using System; using System.Collections.Generic; using System.Text; using CommonAI.Zone.Instance; using CommonAI.Zone.Formula; using CommonLang; using CommonLang.Vector; namespace CommonAI.Zone.Helper { public abstract class HateSystem : IComparer { public class HateInfo { public InstanceUnit Unit; public long HateValue; public int hitNums; //连击数 public HateInfo(InstanceUnit unit) { this.Unit = unit; this.HateValue = 0; this.hitNums = 0; } } private InstanceUnit owner; private TimeInterval m_Timer; private int m_Capacity; protected readonly HashMap unitMap = new HashMap(); protected readonly List unitList = new List(); // 第一个是仇恨值最高的 public int Count { get { return unitList.Count; } } public int Capacity { get { return m_Capacity; } } public InstanceUnit Owner { get { return owner; } } public HateSystem(InstanceUnit owner) : this(owner, owner.Templates.CFG.AI_HATE_SYSTEM_CAPACITY_MS, owner.Templates.CFG.AI_NPC_CHECK_IN_GUARD_LIMIT_TIME_MS) { } public HateSystem(InstanceUnit owner, int capacity, int updateIntervalMS) { this.owner = owner; this.m_Capacity = capacity; this.m_Timer = new TimeInterval(updateIntervalMS); } protected virtual void onTargetAdded(HateInfo target) { } protected virtual void onTargetRemoved(HateInfo target) { } protected virtual void onOwnerHitted(HateInfo attacker, AttackSource attack, int reduceHP) { attacker.HateValue += reduceHP; } public void OnHitted(InstanceUnit attacker, AttackSource attack, int reduceHP) { HateInfo ret = Add(attacker); onOwnerHitted(ret, attack, reduceHP); Sort(); } public HateInfo Add(InstanceUnit target) { HateInfo ret; if (!unitMap.TryGetValue(target.ID, out ret)) { ret = new HateInfo(target); unitMap.Add(target.ID, ret); unitList.Add(ret); onTargetAdded(ret); } return ret; } public void Remove(InstanceUnit unit) { HateInfo u = unitMap.RemoveByKey(unit.ID); if (u != null) { unitList.Remove(u); onTargetRemoved(u); } } public bool Contains(InstanceUnit unit) { return unitMap.ContainsKey(unit.ID); } public bool ContainsID(uint unitID) { return unitMap.ContainsKey(unitID); } public HateInfo getHateInfo(uint unitId) { return this.unitMap.Get(unitId); } public virtual void Reset() { for (int i = 0; i < unitList.Count; ++i) { HateInfo u = unitList[i]; u.HateValue = 0; } this.Sort(); } public virtual void Update(int intervalMS) { if (unitList.Count > 0 && m_Timer.Update(intervalMS)) { this.Sort(); while (unitList.Count > m_Capacity) { int i = unitList.Count - 1; HateInfo u = unitList[i]; unitList.RemoveAt(i); unitMap.Remove(u.Unit.ID); onTargetRemoved(u); } for (int i = 0; i < unitList.Count; ++i) { HateInfo u = unitList[i]; if (u.Unit.Enable && u.Unit.IsActive) { } else { unitList.RemoveAt(i); unitMap.Remove(u.Unit.ID); onTargetRemoved(u); i--; } } } } public virtual void Sort() { unitList.Sort(this); } public virtual void Clear() { for (int i = 0; i < unitList.Count; ++i) { HateInfo u = unitList[i]; onTargetRemoved(u); } unitMap.Clear(); unitList.Clear(); } /// /// 当前首要目标 /// public virtual InstanceUnit GetHated(bool onlyMonster = false) { for (int i = 0; i < unitList.Count; ++i) { HateInfo u = unitList[i]; if (u.Unit.Enable && u.Unit.IsActive) { // 现在宠物也能拉仇恨,死亡了 //if(u.Unit is InstancePet) //{ // return (u.Unit as InstancePet).Master; //} //Console.WriteLine(" ------ getHated -- " + u.Unit.Name + ", " + unitList.Count + ", index = " + i); if(!onlyMonster || (onlyMonster && u.Unit.IsMonster)) { return u.Unit; } } else { unitList.RemoveAt(i); unitMap.Remove(u.Unit.ID); onTargetRemoved(u); i--; } } return null; } /// /// 强制删除buff追击目标 /// public virtual void forceRemoveAtkTraget() {} public virtual int updateHateList(float guargRangeLimit, Vector2 orginPosition) { for (int i = 0; i < unitList.Count; ++i) { HateInfo u = unitList[i]; if (!u.Unit.Enable || !u.Unit.IsActive || !CMath.intersectRound(u.Unit.X, u.Unit.Y, u.Unit.BodyBlockSize, orginPosition.X, orginPosition.Y, guargRangeLimit)) { unitList.RemoveAt(i); unitMap.Remove(u.Unit.ID); onTargetRemoved(u); //Console.WriteLine(" - - - - updateHateList : " + u.Unit.Name); i--; } } return unitMap.Count; } public void print() { for (int i = 0; i < unitList.Count; ++i) { HateInfo u = unitList[i]; Console.WriteLine(" - - - - print hate : " + u.Unit.Name); } } public virtual int GetHateList(List ret) { int count = 0; for (int i = 0; i < unitList.Count; ++i) { HateInfo u = unitList[i]; if (u.Unit.Enable && u.Unit.IsActive) { ret.Add(u); count++; } else { unitList.RemoveAt(i); unitMap.Remove(u.Unit.ID); onTargetRemoved(u); i--; } } return count; } public string GetHatePlayerInfo() { string hateInfo = ""; for (int i = 0; i < unitList.Count; ++i) { if (unitList[i].Unit.IsPlayer) { hateInfo = hateInfo + "_" + unitList[i].Unit.PlayerUUID; } else { hateInfo = hateInfo + "#" + unitList[i].Unit.Info.ID; } } return hateInfo; } public int getHateSize() { return unitMap.Count; } public virtual int Compare(HateSystem.HateInfo x, HateSystem.HateInfo y) { //Console.WriteLine(" - - - - x:" + x.HateValue + ", y:" + y.HateValue); long value = y.HateValue - x.HateValue; if(value != 0) { return value > 0 ? 1 : -1; } return 0; } } }