XmdsHateSystem.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  1. 
  2. using CommonAI.Zone.Formula;
  3. using CommonAI.Zone.Helper;
  4. using CommonAI.Zone.Instance;
  5. using CommonLang;
  6. using System.Collections.Generic;
  7. using XmdsCommon.Plugin;
  8. using CommonLang.Log;
  9. namespace XmdsCommonServer.Plugin
  10. {
  11. public class XmdsHateSystem : HateSystem
  12. {
  13. //private readonly Logger log = LoggerFactory.GetLogger("XmdsHateSystem");
  14. public readonly XmdsVirtual Virtual;
  15. /// <summary>
  16. /// 继承者.
  17. /// </summary>
  18. private XmdsVirtual mHeirs;
  19. //是否寻找继承人.
  20. private bool mFindHeirs = false;
  21. //分享列表.
  22. private List<string> mSharedList = null;
  23. //hatesystem添加单位通知.
  24. public delegate void OnTargetAddEvent(HateInfo target);
  25. public event OnTargetAddEvent OnHandleTargetAddEvent;
  26. /// <summary>
  27. /// 击杀助攻列表.
  28. /// </summary>
  29. private List<string> mAtkAssistantList = null;
  30. protected TimeExpire<int> mSwithHeirsExpire;//切换归属者
  31. public XmdsHateSystem(XmdsVirtual owner)
  32. : base(owner.mUnit)
  33. {
  34. Virtual = owner;
  35. this.mSwithHeirsExpire = new TimeExpire<int>(10000);// 6秒切归属者
  36. }
  37. /// <summary>
  38. /// 设置是否计算归属权.
  39. /// </summary>
  40. /// <param name="flag"></param>
  41. public void SetFindHeirs(bool flag)
  42. {
  43. if (flag == false && mFindHeirs != flag)
  44. {
  45. RemoveHeirs();
  46. }
  47. mFindHeirs = flag;
  48. }
  49. public override void Update(int intervalMS)
  50. {
  51. base.Update(intervalMS);
  52. if (mHeirs != null)
  53. {
  54. if (this.mSwithHeirsExpire.Update(intervalMS))
  55. {
  56. RemoveHeirs();
  57. }
  58. }
  59. }
  60. public override void Sort()
  61. {
  62. base.Sort();
  63. }
  64. public override int Compare(HateSystem.HateInfo x, HateSystem.HateInfo y)
  65. {
  66. //先根据仇恨值排序.
  67. int v = base.Compare(x, y);
  68. //仇恨值相同时,就近原则.
  69. if (v == 0)
  70. {
  71. //重载后根据距离判断,距离近的在前.
  72. float d1 = CMath.getDistance(Virtual.mUnit.X, Virtual.mUnit.Y, x.Unit.X, x.Unit.Y);
  73. float d2 = CMath.getDistance(Virtual.mUnit.X, Virtual.mUnit.Y, y.Unit.X, y.Unit.Y);
  74. v = (int)(d1 - d2);
  75. }
  76. return v;
  77. }
  78. //获取攻击对象.
  79. public override InstanceUnit GetHated(bool onlyMonster = false)
  80. {
  81. InstanceUnit ret = base.GetHated(onlyMonster);
  82. if (ret != null)
  83. {
  84. ret = Virtual.GetAtkTarget(ret);
  85. }
  86. return ret;
  87. }
  88. /// <summary>
  89. /// 强制删除buff追击目标,只能怪物调用(怪物有攻击圈)
  90. /// </summary>
  91. public override void forceRemoveAtkTraget() {
  92. Virtual.forceRemoveAtkTarget();
  93. }
  94. protected override void onTargetAdded(HateInfo target)
  95. {
  96. if (this.Owner.IsDead() == false)
  97. {
  98. if (OnHandleTargetAddEvent != null)
  99. {
  100. OnHandleTargetAddEvent.Invoke(target);
  101. }
  102. base.onTargetAdded(target);
  103. }
  104. }
  105. public void MockingInheritHatred(XmdsVirtual attacker)
  106. {
  107. if(unitList.Count > 1)
  108. {
  109. HateInfo info = unitList[0];
  110. XmdsVirtual hateVirtual = (XmdsVirtual)info.Unit.Virtual;
  111. long hateValue = System.Math.Min((long)(info.HateValue * 1.3), info.HateValue + hateVirtual.MirrorProp.GetFinalAttack(true) * 100);
  112. this.SetHateInfo(attacker, hateValue);
  113. }
  114. else
  115. {
  116. this.SetHateInfo(attacker, CUtils.CastInt(attacker.MirrorProp.MaxHP));
  117. }
  118. }
  119. protected override void onTargetRemoved(HateInfo target)
  120. {
  121. base.onTargetRemoved(target);
  122. if (mHeirs != null)
  123. {
  124. if (mHeirs.mUnit.ID == target.Unit.ID)
  125. {
  126. if (Virtual.mUnit.IsDead() == false)
  127. {
  128. //移除归属者.
  129. RemoveHeirs();
  130. }
  131. else
  132. {
  133. //移除归属者监听.
  134. RemoveHeirsListener();
  135. }
  136. }
  137. }
  138. }
  139. protected override void onOwnerHitted(HateInfo attacker, AttackSource attack, int reduceHP)
  140. {
  141. //不使用底层仇恨机制.
  142. base.onOwnerHitted(attacker, attack, reduceHP);
  143. }
  144. /// <summary>
  145. /// 设置归属者,同时设置监听.
  146. /// </summary>
  147. /// <param name="zv"></param>
  148. private void AddHeirs(XmdsVirtual zv)
  149. {
  150. if (zv is XmdsVirtual_Player)
  151. {
  152. if ((zv.mUnit.Info.Properties as XmdsUnitProperties).BotTestTemplate == false)
  153. {
  154. //log.Error("AddHeirs - " + System.DateTime.Now);
  155. mHeirs = zv;
  156. if (mHeirs != null)
  157. {
  158. int hpPercent = mHeirs.mUnit.get_current_hp()*10000/ mHeirs.mProp.ServerData.Prop.MaxHP;
  159. Virtual.SyncHeirsInfo(mHeirs.mProp.ServerData.BaseInfo.name, hpPercent,mHeirs.mProp.ServerData.BaseInfo.ProType);
  160. //加血监听.
  161. mHeirs.OnHealEventHandle += MHeres_OnHealEventHandle;
  162. //脱战监听.
  163. mHeirs.OnCombatStateChangeHandle += MHeres_OnCombatStateChangeHandle;
  164. }
  165. this.mSwithHeirsExpire.Reset();
  166. }
  167. }
  168. }
  169. /// <summary>
  170. /// 移除归属者以及对应的监听.
  171. /// </summary>
  172. private void RemoveHeirs()
  173. {
  174. if (mHeirs != null)
  175. {
  176. //log.Error("RemoveHeirs - " + System.DateTime.Now);
  177. mHeirs.OnHealEventHandle -= MHeres_OnHealEventHandle;
  178. mHeirs.OnCombatStateChangeHandle -= MHeres_OnCombatStateChangeHandle;
  179. Virtual.SyncHeirsInfo(null, 0,mHeirs.mProp.ServerData.BaseInfo.ProType);
  180. mHeirs = null;
  181. }
  182. }
  183. private void RemoveHeirsListener()
  184. {
  185. if (mHeirs != null)
  186. {
  187. mHeirs.OnHealEventHandle -= MHeres_OnHealEventHandle;
  188. mHeirs.OnCombatStateChangeHandle -= MHeres_OnCombatStateChangeHandle;
  189. }
  190. }
  191. /// <summary>
  192. /// 脱战监听.
  193. /// </summary>
  194. /// <param name="unit"></param>
  195. /// <param name="status"></param>
  196. private void MHeres_OnCombatStateChangeHandle(XmdsVirtual unit, bool status)
  197. {
  198. if (status == false)
  199. {
  200. RemoveHeirs();
  201. }
  202. }
  203. /// <summary>
  204. /// 监听仇恨对象受治愈效果.
  205. /// </summary>
  206. /// <param name="attacker"></param>
  207. /// <param name="hitter"></param>
  208. /// <param name="value"></param>
  209. /// <param name="result"></param>
  210. private void MHeres_OnHealEventHandle(XmdsVirtual attacker, XmdsVirtual hitter, int value, ref XmdsVirtual.AtkResult result)
  211. {
  212. if (value > 0 && result.ThreatValue > 0)
  213. {
  214. int ret = CalThreatValue(value, result.ThreatValue, result.ThreatValueChangePer, result.ThreatValueChangeModify);
  215. addTarget(attacker, ret);
  216. }
  217. }
  218. /// <summary>
  219. /// 添加仇恨对象,设置仇恨值.
  220. /// </summary>
  221. /// <param name="target"></param>
  222. /// <param name="threatValue"></param>
  223. private void addTarget(XmdsVirtual target, int threatValue)
  224. {
  225. HateInfo ret = null;
  226. if (this.unitMap.TryGetValue(target.mUnit.ID, out ret))
  227. {
  228. //donothing.
  229. }
  230. else
  231. {
  232. //加入仇恨列表.
  233. ret = Add(target.mUnit);
  234. }
  235. //增加对应仇恨.
  236. ret.HateValue += threatValue;
  237. }
  238. /// <summary>
  239. /// 被攻击时调用.
  240. /// </summary>
  241. /// <param name="attacker"></param>
  242. /// <param name="hitter"></param>
  243. /// <param name="value"></param>
  244. /// <param name="result"></param>
  245. public void OnHitted(XmdsVirtual attacker, XmdsVirtual hitter, int value, ref XmdsVirtual.AtkResult result)
  246. {
  247. int threat = value;
  248. if (value > 0 && result.ThreatValue > 0)
  249. {
  250. threat = CalThreatValue(value, result.ThreatValue, result.ThreatValueChangePer, result.ThreatValueChangeModify);
  251. }
  252. //归属人设置.
  253. if (mFindHeirs)
  254. {
  255. if(mHeirs == null)
  256. {
  257. //设置继承人.
  258. XmdsVirtual temp = null;
  259. if (attacker is XmdsVirtual_Player)
  260. {
  261. AddHeirs(attacker);
  262. }
  263. else if (attacker is XmdsVirtual_Pet)//是宠物找主人.
  264. {
  265. temp = (attacker as XmdsVirtual_Pet).GetMaster();
  266. if (temp != null)
  267. {
  268. AddHeirs(temp);
  269. }
  270. }
  271. else if (attacker is XmdsVirtual_SummonUnit)//是召唤物,找宿主.
  272. {
  273. temp = (attacker as XmdsVirtual_SummonUnit).GetPlayerUnit();
  274. if (temp != null && temp is XmdsVirtual_Player)
  275. {
  276. AddHeirs(temp);
  277. }
  278. }
  279. }
  280. else
  281. {
  282. bool isFinded = mHeirs.GetPlayerUUID() == attacker.GetPlayerUUID();
  283. if(!isFinded)
  284. {
  285. if (mHeirs is XmdsVirtual_Player && attacker is XmdsVirtual_Player)
  286. {
  287. List<string> lt = mHeirs.TeamList as List<string>;
  288. if(lt != null)
  289. {
  290. for (int i = 0; i < lt.Count; i++)
  291. {
  292. if (attacker.GetPlayerUUID() == lt[i])
  293. {
  294. isFinded = true;
  295. break;
  296. }
  297. }
  298. }
  299. }
  300. }
  301. if(isFinded)
  302. {
  303. this.mSwithHeirsExpire.Reset();
  304. }
  305. }
  306. }
  307. addTarget(attacker, threat);
  308. }
  309. public void AddTarget(XmdsVirtual zv)
  310. {
  311. addTarget(zv, 0);
  312. }
  313. /// <summary>
  314. /// 计算仇恨值.
  315. /// </summary>
  316. /// <param name="damage"></param>
  317. /// <param name="threatValue"></param>
  318. /// <returns></returns>
  319. private int CalThreatValue(int damage, int threatValue, int threatValuePer, int threatValueModify)
  320. {
  321. threatValue = threatValue + threatValuePer;
  322. int ret = 0;
  323. if (threatValue != 0)
  324. {
  325. ret = (int)(damage * (threatValue / XmdsSkillTemplate.DamageCalculator.XmdsDamageCalculator.PERER));
  326. }
  327. return ret;
  328. }
  329. /// <summary>
  330. /// 销毁仇恨系统.
  331. /// </summary>
  332. public void Dispose()
  333. {
  334. if (mAtkAssistantList != null)
  335. {
  336. mAtkAssistantList.Clear();
  337. }
  338. OnHandleTargetAddEvent = null;
  339. Clear();
  340. ClearSharedList();
  341. RemoveHeirs();
  342. }
  343. /// <summary>
  344. /// 取得继承人.
  345. /// </summary>
  346. /// <returns></returns>
  347. public InstanceUnit GetHeirs()
  348. {
  349. if (mHeirs != null)
  350. {
  351. return mHeirs.mUnit;
  352. }
  353. return null;
  354. }
  355. public void AddSharedList(string uuid)
  356. {
  357. if (mSharedList == null) { mSharedList = new List<string>(); }
  358. mSharedList.Add(uuid);
  359. }
  360. public List<string> GetSharedList()
  361. {
  362. return mSharedList;
  363. }
  364. public void ClearSharedList()
  365. {
  366. if (mSharedList != null)
  367. {
  368. mSharedList.Clear();
  369. }
  370. }
  371. public void CalAtkAssistantList(bool isShare)
  372. {
  373. if (mAtkAssistantList != null)
  374. {
  375. mAtkAssistantList.Clear();
  376. }
  377. else
  378. {
  379. mAtkAssistantList = new List<string>();
  380. }
  381. string uuid = null;
  382. //仇恨值大于0的单位.
  383. foreach (var info in unitMap)
  384. {
  385. if (info.Value.HateValue > 0)
  386. {
  387. float dist = CMath.getDistance(Owner.X, Owner.Y, info.Value.Unit.X, info.Value.Unit.Y);
  388. //单位在范围内.
  389. if (dist <= XmdsConfig.Instance.SHARED_AWARD_MAX_RANGE)
  390. {
  391. uuid = ((info.Value.Unit.Virtual) as XmdsVirtual).GetPlayerUUID();
  392. //过滤宠物、召唤单位宿主相同情况.
  393. if (string.IsNullOrEmpty(uuid) == false && !mAtkAssistantList.Contains(uuid))
  394. {
  395. mAtkAssistantList.Add(uuid);
  396. }
  397. }
  398. }
  399. }
  400. //if(isShare)
  401. //{
  402. // foreach (InstancePlayer info in this.Owner.Parent.AllPlayers)
  403. // {
  404. // float dist = CMath.getDistance(Owner.X, Owner.Y, info.X, info.Y);
  405. // if (dist <= XmdsConfig.Instance.SHARED_AWARD_MAX_RANGE)
  406. // {
  407. // uuid = info.PlayerUUID;
  408. // if (string.IsNullOrEmpty(uuid) == false && !mAtkAssistantList.Contains(uuid))
  409. // {
  410. // mAtkAssistantList.Add(uuid);
  411. // }
  412. // }
  413. // }
  414. //}
  415. }
  416. public List<string> GetAtkAssistantList()
  417. {
  418. return mAtkAssistantList;
  419. }
  420. /// <summary>
  421. /// 设置指定单位仇恨值.
  422. /// </summary>
  423. /// <param name="id"></param>
  424. /// <param name="threatValue"></param>
  425. public void SetHateInfo(uint id, long threatValue)
  426. {
  427. HateInfo ret = null;
  428. if (this.unitMap.TryGetValue(id, out ret))
  429. {
  430. ret.HateValue = threatValue;
  431. }
  432. }
  433. /// <summary>
  434. /// 添加仇恨对象,设置仇恨值.
  435. /// </summary>
  436. /// <param name="target"></param>
  437. /// <param name="threatValue"></param>
  438. private void SetHateInfo(XmdsVirtual target, long threatValue)
  439. {
  440. HateInfo ret = null;
  441. if (this.unitMap.TryGetValue(target.mUnit.ID, out ret))
  442. {
  443. //donothing.
  444. }
  445. else
  446. {
  447. //加入仇恨列表.
  448. ret = Add(target.mUnit);
  449. }
  450. //增加对应仇恨.
  451. ret.HateValue = threatValue;
  452. }
  453. public void ClearAllThreatValue()
  454. {
  455. if (unitMap != null)
  456. {
  457. foreach (var kvp in unitMap)
  458. {
  459. kvp.Value.HateValue = 0;
  460. }
  461. }
  462. }
  463. }
  464. }