using CommonAI.Zone.Formula; using CommonAI.Zone.Helper; using CommonAI.Zone.Instance; using CommonLang; using System.Collections.Generic; using XmdsCommon.Plugin; using CommonLang.Log; namespace XmdsCommonServer.Plugin { public class XmdsHateSystem : HateSystem { //private readonly Logger log = LoggerFactory.GetLogger("XmdsHateSystem"); public readonly XmdsVirtual Virtual; /// /// 继承者. /// private XmdsVirtual mHeirs; //是否寻找继承人. private bool mFindHeirs = false; //分享列表. private List mSharedList = null; //hatesystem添加单位通知. public delegate void OnTargetAddEvent(HateInfo target); public event OnTargetAddEvent OnHandleTargetAddEvent; /// /// 击杀助攻列表. /// private List mAtkAssistantList = null; protected TimeExpire mSwithHeirsExpire;//切换归属者 public XmdsHateSystem(XmdsVirtual owner) : base(owner.mUnit) { Virtual = owner; this.mSwithHeirsExpire = new TimeExpire(10000);// 6秒切归属者 } /// /// 设置是否计算归属权. /// /// public void SetFindHeirs(bool flag) { if (flag == false && mFindHeirs != flag) { RemoveHeirs(); } mFindHeirs = flag; } public override void Update(int intervalMS) { base.Update(intervalMS); if (mHeirs != null) { if (this.mSwithHeirsExpire.Update(intervalMS)) { RemoveHeirs(); } } } public override void Sort() { base.Sort(); } public override int Compare(HateSystem.HateInfo x, HateSystem.HateInfo y) { //先根据仇恨值排序. int v = base.Compare(x, y); //仇恨值相同时,就近原则. if (v == 0) { //重载后根据距离判断,距离近的在前. float d1 = CMath.getDistance(Virtual.mUnit.X, Virtual.mUnit.Y, x.Unit.X, x.Unit.Y); float d2 = CMath.getDistance(Virtual.mUnit.X, Virtual.mUnit.Y, y.Unit.X, y.Unit.Y); v = (int)(d1 - d2); } return v; } //获取攻击对象. public override InstanceUnit GetHated(bool onlyMonster = false) { InstanceUnit ret = base.GetHated(onlyMonster); if (ret != null) { ret = Virtual.GetAtkTarget(ret); } return ret; } /// /// 强制删除buff追击目标,只能怪物调用(怪物有攻击圈) /// public override void forceRemoveAtkTraget() { Virtual.forceRemoveAtkTarget(); } protected override void onTargetAdded(HateInfo target) { if (this.Owner.IsDead() == false) { if (OnHandleTargetAddEvent != null) { OnHandleTargetAddEvent.Invoke(target); } base.onTargetAdded(target); } } public void MockingInheritHatred(XmdsVirtual attacker) { if(unitList.Count > 1) { HateInfo info = unitList[0]; XmdsVirtual hateVirtual = (XmdsVirtual)info.Unit.Virtual; long hateValue = System.Math.Min((long)(info.HateValue * 1.3), info.HateValue + hateVirtual.MirrorProp.GetFinalAttack(true) * 100); this.SetHateInfo(attacker, hateValue); } else { this.SetHateInfo(attacker, CUtils.CastInt(attacker.MirrorProp.MaxHP)); } } protected override void onTargetRemoved(HateInfo target) { base.onTargetRemoved(target); if (mHeirs != null) { if (mHeirs.mUnit.ID == target.Unit.ID) { if (Virtual.mUnit.IsDead() == false) { //移除归属者. RemoveHeirs(); } else { //移除归属者监听. RemoveHeirsListener(); } } } } protected override void onOwnerHitted(HateInfo attacker, AttackSource attack, int reduceHP) { //不使用底层仇恨机制. base.onOwnerHitted(attacker, attack, reduceHP); } /// /// 设置归属者,同时设置监听. /// /// private void AddHeirs(XmdsVirtual zv) { if (zv is XmdsVirtual_Player) { if ((zv.mUnit.Info.Properties as XmdsUnitProperties).BotTestTemplate == false) { //log.Error("AddHeirs - " + System.DateTime.Now); mHeirs = zv; if (mHeirs != null) { int hpPercent = mHeirs.mUnit.get_current_hp()*10000/ mHeirs.mProp.ServerData.Prop.MaxHP; Virtual.SyncHeirsInfo(mHeirs.mProp.ServerData.BaseInfo.name, hpPercent,mHeirs.mProp.ServerData.BaseInfo.ProType); //加血监听. mHeirs.OnHealEventHandle += MHeres_OnHealEventHandle; //脱战监听. mHeirs.OnCombatStateChangeHandle += MHeres_OnCombatStateChangeHandle; } this.mSwithHeirsExpire.Reset(); } } } /// /// 移除归属者以及对应的监听. /// private void RemoveHeirs() { if (mHeirs != null) { //log.Error("RemoveHeirs - " + System.DateTime.Now); mHeirs.OnHealEventHandle -= MHeres_OnHealEventHandle; mHeirs.OnCombatStateChangeHandle -= MHeres_OnCombatStateChangeHandle; Virtual.SyncHeirsInfo(null, 0,mHeirs.mProp.ServerData.BaseInfo.ProType); mHeirs = null; } } private void RemoveHeirsListener() { if (mHeirs != null) { mHeirs.OnHealEventHandle -= MHeres_OnHealEventHandle; mHeirs.OnCombatStateChangeHandle -= MHeres_OnCombatStateChangeHandle; } } /// /// 脱战监听. /// /// /// private void MHeres_OnCombatStateChangeHandle(XmdsVirtual unit, bool status) { if (status == false) { RemoveHeirs(); } } /// /// 监听仇恨对象受治愈效果. /// /// /// /// /// private void MHeres_OnHealEventHandle(XmdsVirtual attacker, XmdsVirtual hitter, int value, ref XmdsVirtual.AtkResult result) { if (value > 0 && result.ThreatValue > 0) { int ret = CalThreatValue(value, result.ThreatValue, result.ThreatValueChangePer, result.ThreatValueChangeModify); addTarget(attacker, ret); } } /// /// 添加仇恨对象,设置仇恨值. /// /// /// private void addTarget(XmdsVirtual target, int threatValue) { HateInfo ret = null; if (this.unitMap.TryGetValue(target.mUnit.ID, out ret)) { //donothing. } else { //加入仇恨列表. ret = Add(target.mUnit); } //增加对应仇恨. ret.HateValue += threatValue; } /// /// 被攻击时调用. /// /// /// /// /// public void OnHitted(XmdsVirtual attacker, XmdsVirtual hitter, int value, ref XmdsVirtual.AtkResult result) { int threat = value; if (value > 0 && result.ThreatValue > 0) { threat = CalThreatValue(value, result.ThreatValue, result.ThreatValueChangePer, result.ThreatValueChangeModify); } //归属人设置. if (mFindHeirs) { if(mHeirs == null) { //设置继承人. XmdsVirtual temp = null; if (attacker is XmdsVirtual_Player) { AddHeirs(attacker); } else if (attacker is XmdsVirtual_Pet)//是宠物找主人. { temp = (attacker as XmdsVirtual_Pet).GetMaster(); if (temp != null) { AddHeirs(temp); } } else if (attacker is XmdsVirtual_SummonUnit)//是召唤物,找宿主. { temp = (attacker as XmdsVirtual_SummonUnit).GetPlayerUnit(); if (temp != null && temp is XmdsVirtual_Player) { AddHeirs(temp); } } } else { bool isFinded = mHeirs.GetPlayerUUID() == attacker.GetPlayerUUID(); if(!isFinded) { if (mHeirs is XmdsVirtual_Player && attacker is XmdsVirtual_Player) { List lt = mHeirs.TeamList as List; if(lt != null) { for (int i = 0; i < lt.Count; i++) { if (attacker.GetPlayerUUID() == lt[i]) { isFinded = true; break; } } } } } if(isFinded) { this.mSwithHeirsExpire.Reset(); } } } addTarget(attacker, threat); } public void AddTarget(XmdsVirtual zv) { addTarget(zv, 0); } /// /// 计算仇恨值. /// /// /// /// private int CalThreatValue(int damage, int threatValue, int threatValuePer, int threatValueModify) { threatValue = threatValue + threatValuePer; int ret = 0; if (threatValue != 0) { ret = (int)(damage * (threatValue / XmdsSkillTemplate.DamageCalculator.XmdsDamageCalculator.PERER)); } return ret; } /// /// 销毁仇恨系统. /// public void Dispose() { if (mAtkAssistantList != null) { mAtkAssistantList.Clear(); } OnHandleTargetAddEvent = null; Clear(); ClearSharedList(); RemoveHeirs(); } /// /// 取得继承人. /// /// public InstanceUnit GetHeirs() { if (mHeirs != null) { return mHeirs.mUnit; } return null; } public void AddSharedList(string uuid) { if (mSharedList == null) { mSharedList = new List(); } mSharedList.Add(uuid); } public List GetSharedList() { return mSharedList; } public void ClearSharedList() { if (mSharedList != null) { mSharedList.Clear(); } } public void CalAtkAssistantList(bool isShare) { if (mAtkAssistantList != null) { mAtkAssistantList.Clear(); } else { mAtkAssistantList = new List(); } string uuid = null; //仇恨值大于0的单位. foreach (var info in unitMap) { if (info.Value.HateValue > 0) { float dist = CMath.getDistance(Owner.X, Owner.Y, info.Value.Unit.X, info.Value.Unit.Y); //单位在范围内. if (dist <= XmdsConfig.Instance.SHARED_AWARD_MAX_RANGE) { uuid = ((info.Value.Unit.Virtual) as XmdsVirtual).GetPlayerUUID(); //过滤宠物、召唤单位宿主相同情况. if (string.IsNullOrEmpty(uuid) == false && !mAtkAssistantList.Contains(uuid)) { mAtkAssistantList.Add(uuid); } } } } //if(isShare) //{ // foreach (InstancePlayer info in this.Owner.Parent.AllPlayers) // { // float dist = CMath.getDistance(Owner.X, Owner.Y, info.X, info.Y); // if (dist <= XmdsConfig.Instance.SHARED_AWARD_MAX_RANGE) // { // uuid = info.PlayerUUID; // if (string.IsNullOrEmpty(uuid) == false && !mAtkAssistantList.Contains(uuid)) // { // mAtkAssistantList.Add(uuid); // } // } // } //} } public List GetAtkAssistantList() { return mAtkAssistantList; } /// /// 设置指定单位仇恨值. /// /// /// public void SetHateInfo(uint id, long threatValue) { HateInfo ret = null; if (this.unitMap.TryGetValue(id, out ret)) { ret.HateValue = threatValue; } } /// /// 添加仇恨对象,设置仇恨值. /// /// /// private void SetHateInfo(XmdsVirtual target, long threatValue) { HateInfo ret = null; if (this.unitMap.TryGetValue(target.mUnit.ID, out ret)) { //donothing. } else { //加入仇恨列表. ret = Add(target.mUnit); } //增加对应仇恨. ret.HateValue = threatValue; } public void ClearAllThreatValue() { if (unitMap != null) { foreach (var kvp in unitMap) { kvp.Value.HateValue = 0; } } } } }