LogicFighterOpr.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  1. using UnityEngine;
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. namespace YLBattle
  6. {
  7. /// <summary>
  8. /// 逻辑管理(操作)
  9. /// </summary>
  10. public partial class LogicFighterManager : ILogicFighterOper
  11. {
  12. /// <summary>
  13. /// 寻求朋友帮助
  14. /// </summary>
  15. /// <param name="seat"></param>
  16. /// <param name="whodead"></param>
  17. public void SetFriendHelp(int seat, bool isShowTip = false)
  18. {
  19. HeroAdapter friend = this.Env().friend as HeroAdapter;
  20. friend.Seat = seat; //占位设置
  21. LogicFighter fighter = new LogicFighter();
  22. ///索引设定为当前己方最大人数+1
  23. int maxindex = this.Env().mLogicFighterOper.FindTeamAllFighter(EBattleTeam.BLUETEAM).Count;
  24. string id = (maxindex + 1).ToString();
  25. ///占位为死亡占位
  26. fighter.SetData(id, this.Env(), friend, EBattleTeam.BLUETEAM, seat);
  27. this.Env().ShowAdapter().CreatLogicFighter(id, EBattleTeam.BLUETEAM, this.Env().levelMode, friend, true);
  28. this.mFighters.Add(fighter.ID(), fighter);
  29. this.mFriendFighters.Add(seat, fighter);
  30. this.Env().friend = null; //清空好友支援数据
  31. if (isShowTip)
  32. {
  33. this.Env().ShowAdapter().OnFriendSupportTip(friend.TID());
  34. }
  35. //LogHelper.Log("GetFriendHelp...............seat=" + seat + " name=" + friend.FName());
  36. }
  37. /// <summary>
  38. /// 查找指定战斗对象
  39. /// </summary>
  40. /// <param name="id">对象唯一编号</param>
  41. /// <returns>目标</returns>
  42. public LogicFighter FindFighter(string id)
  43. {
  44. if (mFighters.ContainsKey(id))
  45. {
  46. return mFighters[id];
  47. }
  48. return null;
  49. }
  50. /// <summary>
  51. /// 获取指定队伍目前存活人员
  52. /// </summary>
  53. /// <param name="team">队伍描述</param>
  54. /// <returns>人员列表</returns>
  55. public List<LogicFighter> FindFighter()
  56. {
  57. List<LogicFighter> all = new List<LogicFighter>();
  58. foreach (KeyValuePair<string, LogicFighter> kv in this.mFighters)
  59. {
  60. all.Add(kv.Value);
  61. }
  62. return all;
  63. }
  64. /// <summary>
  65. /// 获取指定队伍目前存活人员
  66. /// </summary>
  67. /// <param name="team">队伍描述</param>
  68. /// <returns>人员列表</returns>
  69. public List<LogicFighter> FindAliveFighter()
  70. {
  71. List<LogicFighter> all = new List<LogicFighter>();
  72. foreach (KeyValuePair<string, LogicFighter> kv in this.mFighters)
  73. {
  74. if (kv.Value.IsDead() == true)
  75. {
  76. continue;
  77. }
  78. all.Add(kv.Value);
  79. }
  80. return all;
  81. }
  82. /// <summary>
  83. /// 获取指定队伍目前存活人员
  84. /// </summary>
  85. /// <param name="team">队伍描述</param>
  86. /// <returns>人员列表</returns>
  87. public List<LogicFighter> FindTeamAliveFighter(EBattleTeam team)
  88. {
  89. List<LogicFighter> all = new List<LogicFighter>();
  90. foreach (KeyValuePair<string, LogicFighter> kv in this.mFighters)
  91. {
  92. if (kv.Value.Team() != team)
  93. {
  94. continue;
  95. }
  96. if (kv.Value.IsDead() == true)
  97. {
  98. continue;
  99. }
  100. all.Add(kv.Value);
  101. }
  102. return all;
  103. }
  104. /// <summary>
  105. /// 获取指定角色的敌人队伍存活列表
  106. /// </summary>
  107. /// <param name="id">参照对象编号</param>
  108. /// <returns>敌方存活角色列表</returns>
  109. public List<LogicFighter> FindEnemyTeam(string id)
  110. {
  111. LogicFighter who = this.FindFighter(id);
  112. EBattleTeam team = who.Team();
  113. return this.FindTeamAliveFighter(team);
  114. }
  115. /// <summary>
  116. /// 获取指定角色的友方队伍存活列表
  117. /// </summary>
  118. /// <param name="id">参照对象编号</param>
  119. /// <returns>友方存活角色列表,包含自己</returns>
  120. public List<LogicFighter> FindFriendTeam(string id)
  121. {
  122. LogicFighter who = this.FindFighter(id);
  123. EBattleTeam team = who.Team();
  124. return this.FindTeamAliveFighter(team);
  125. }
  126. /// <summary>
  127. /// 根据站位查找fighter
  128. /// </summary>
  129. /// <param name="_seat">指定占位</param>
  130. /// <param name="team">所属队列</param>
  131. /// <returns></returns>
  132. public LogicFighter FindFighterBySeat(int _seat, EBattleTeam team)
  133. {
  134. LogicFighter target = null;
  135. List<LogicFighter> parter = this.FindTeamAliveFighter(team);
  136. foreach (LogicFighter fighter in parter)
  137. {
  138. if (fighter.Seat() == _seat)
  139. {
  140. target = fighter;
  141. break;
  142. }
  143. }
  144. return target;
  145. }
  146. /// <summary>
  147. /// 查找与目标指定关系的对象列表
  148. /// </summary>
  149. /// <param name="id">参照对象编号</param>
  150. /// <param name="relation">关系过滤</param>
  151. /// <returns>对象列表</returns>
  152. public List<LogicFighter> FindRelationAliveFighters(string id, EBattleRelation relation)
  153. {
  154. List<LogicFighter> result = new List<LogicFighter>();
  155. LogicFighter who = this.FindFighter(id);
  156. if (null == who)
  157. {
  158. return null;
  159. }
  160. foreach (KeyValuePair<string, LogicFighter> kv in this.mFighters)
  161. {
  162. if (kv.Value.ID() == id)
  163. {
  164. continue;
  165. }
  166. if (kv.Value.IsDead())
  167. {
  168. continue;
  169. }
  170. switch (relation)
  171. {
  172. case EBattleRelation.EBATTLE_RELATION_NONE:
  173. result.Add(kv.Value);
  174. break;
  175. case EBattleRelation.EBATTLE_RELATION_ENEMY:
  176. {
  177. if (EBattleRelation.EBATTLE_RELATION_ENEMY == who.Relation(kv.Value))
  178. {
  179. result.Add(kv.Value);
  180. }
  181. }
  182. break;
  183. case EBattleRelation.EBATTLE_RELATION_FRIEND:
  184. {
  185. if (EBattleRelation.EBATTLE_RELATION_FRIEND == who.Relation(kv.Value))
  186. {
  187. result.Add(kv.Value);
  188. }
  189. }
  190. break;
  191. }
  192. }
  193. return result;
  194. }
  195. /// <summary>
  196. /// 获得当前存活的按攻击速度排序的所有人员
  197. /// </summary>
  198. /// <returns></returns>
  199. public List<LogicFighter> FindAliveSortFighter(EBattleTeam _team)
  200. {
  201. List<LogicFighter> all = new List<LogicFighter>();
  202. foreach (KeyValuePair<string, LogicFighter> kv in this.mFighters)
  203. {
  204. if (kv.Value.IsDead() == true)
  205. {
  206. continue;
  207. }
  208. if (kv.Value.Team() != _team)
  209. {
  210. continue;
  211. }
  212. all.Add(kv.Value);
  213. }
  214. Reverser<LogicFighter> reverser = new Reverser<LogicFighter>(Type.GetType("LogicFighter"), "AttackSpeed", ReverserInfo.Direction.ASC);
  215. all.Sort(reverser);
  216. return all;
  217. }
  218. //public List<LogicFighter> FindAliveFighterByLastAttackTime()
  219. //{
  220. // List<LogicFighter> trgLst = this.FindAliveFighter();
  221. // if (trgLst.Count > 0)
  222. // {
  223. // foreach (LogicFighter fighter in trgLst)
  224. // {
  225. // if (sombody == null)
  226. // {
  227. // sombody = fighter;
  228. // continue;
  229. // }
  230. // int restTime1 = (int)(sombody.AttackSpeed - (this.Env().TimeCenter().Now() - sombody.LastAttackTime));
  231. // int restTime2 = (int)(fighter.AttackSpeed - (this.Env().TimeCenter().Now() - fighter.LastAttackTime));
  232. // if (restTime2 < restTime1)
  233. // {
  234. // sombody = fighter;
  235. // }
  236. // }
  237. // if (sombody != null && sombody.Team() == EBattleTeam.REDTEAM)
  238. // {
  239. // sombody.GetState().ChangeState(BaseState.EFighterState.ROTATE, null);
  240. // }
  241. // }
  242. // return trgLst;
  243. //}
  244. /// <summary>
  245. /// 获取指定队伍所有人员,不论生死
  246. /// </summary>
  247. /// <param name="team">目标队伍</param>
  248. /// <returns>对象列表</returns>
  249. public List<LogicFighter> FindTeamAllFighter(EBattleTeam team)
  250. {
  251. List<LogicFighter> all = new List<LogicFighter>();
  252. foreach (KeyValuePair<string, LogicFighter> kv in this.mFighters)
  253. {
  254. if (kv.Value.Team() == team)
  255. {
  256. all.Add(kv.Value);
  257. }
  258. }
  259. return all;
  260. }
  261. /// <summary>
  262. /// 查找当前地图中间的人
  263. /// </summary>
  264. /// <param name="fighter">己方</param>
  265. /// <returns>敌方角色</returns>
  266. public LogicFighter FindCenterEnemy(string whoId, EBattleTeam _team)
  267. {
  268. #region ---------------------------2017-09-08 修正
  269. //EBattleTeam targetTeam = _team == EBattleTeam.BLUETEAM ? EBattleTeam.REDTEAM : EBattleTeam.BLUETEAM;
  270. //int seat = FightingMap.Instance.GetCenterSeat();
  271. //sombody = this.FindFighterBySeat(seat, targetTeam);
  272. //if (sombody == null)
  273. //{
  274. // List<LogicFighter> trgLst = FindTeamAliveFighter(targetTeam);
  275. // Reverser<LogicFighter> reverser = new Reverser<LogicFighter>(System.Type.GetType("LogicFighter"), "AttackSpeed", ReverserInfo.Direction.ASC);
  276. // trgLst.Sort(reverser);
  277. // if (trgLst.Count > 0)
  278. // {
  279. // sombody = trgLst[0];
  280. // sombody.GetState().ChangeState(BaseState.EFighterState.ROTATE, null);
  281. // }
  282. //}
  283. #endregion
  284. /**
  285. * 选取规则 (选择地图中间的人,己方假象也是地图圆盘)
  286. * 如果 Blue(Red)CurrentCenterAttacker 为空,则是第一次出手,则攻击占位索引依次为0->4的人(以此类推)
  287. * 如果 Blue(Red)CurrentCenterAttacker 不为空,则为上一次出手的角色(当前应该在地图中间位置)如果不为死亡,则选定为目标
  288. * 如果 Blue(Red)CurrentCenterAttacker 不为空,如果死亡,则对敌方队伍按“攻击速度”排序(下一个出手的应该是剩余时间最少的一个人)迭代选择
  289. */
  290. //----是否背叛。。。。。
  291. LogicFighter who = this.FindFighter(whoId);
  292. string targetId = _team == EBattleTeam.BLUETEAM ? this.Env().mRedCurrentCenterAttacker : this.Env().mBlueCurrentCenterAttacker;
  293. if (targetId != string.Empty)
  294. {
  295. LogicFighter f = this.FindFighter(targetId);
  296. if (f != null && !f.IsDead())
  297. {
  298. //Debug.LogError(_team.ToString() + ":[" + who + "] 获取中线目标:" + targetId);
  299. return f;
  300. }
  301. }
  302. if (targetId == string.Empty)
  303. {
  304. LogicFighter sombody = FindFighterBySeat(0, _team == EBattleTeam.BLUETEAM ? EBattleTeam.REDTEAM : EBattleTeam.BLUETEAM);
  305. if (sombody != null)
  306. {
  307. return sombody;
  308. }
  309. }
  310. return this.OnUpdateMapCenterFighter(_team == EBattleTeam.BLUETEAM ? EBattleTeam.REDTEAM : EBattleTeam.BLUETEAM);
  311. }
  312. /// <summary>
  313. /// 刷新当前地图中间位置的角色
  314. /// </summary>
  315. /// <param name="_team">己方队伍</param>
  316. /// <returns>敌方角色</returns>
  317. public LogicFighter OnUpdateMapCenterFighter(EBattleTeam _team)
  318. {
  319. LogicFighter sombody = null;
  320. /**
  321. * 当前中心位置无角色,已死亡,按攻击速度找到下一个出手的角色,置为中心位置,并地图转向
  322. */
  323. List<LogicFighter> trgLst = FindTeamAliveFighter(_team);
  324. if (trgLst.Count > 0)
  325. {
  326. foreach (LogicFighter fighter in trgLst)
  327. {
  328. if (sombody == null)
  329. {
  330. sombody = fighter;
  331. continue;
  332. }
  333. int restTime1 = (int)(sombody.AttackSpeed - (this.Env().TimeCenter().Now() - sombody.LastAttackTime));
  334. int restTime2 = (int)(fighter.AttackSpeed - (this.Env().TimeCenter().Now() - fighter.LastAttackTime));
  335. if (restTime2 < restTime1)
  336. {
  337. sombody = fighter;
  338. }
  339. }
  340. if (sombody != null && sombody.Team() == EBattleTeam.REDTEAM)
  341. {
  342. sombody.GetState().ChangeState(BaseState.EFighterState.ROTATE, null);
  343. }
  344. }
  345. return sombody;
  346. }
  347. /// <summary>
  348. /// 禁用指定战斗对象
  349. /// </summary>
  350. /// <param name="id">角色编号</param>
  351. public void MarkDeathFighter(string id)
  352. {
  353. LogicFighter fighter = this.FindFighter(id);
  354. if (null == fighter)
  355. {
  356. return;
  357. }
  358. this.mDeathFighterss.Add(fighter);
  359. }
  360. /// <summary>
  361. /// 从死亡列表中移除指定对象
  362. /// </summary>
  363. /// <param name="id">对象id</param>
  364. public void RemoveFighterFromDeath(string id)
  365. {
  366. LogicFighter fighter = null;
  367. for (int i = 0; i < this.mDeathFighterss.Count; ++i)
  368. {
  369. if (this.mDeathFighterss[i].ID() == id)
  370. {
  371. fighter = this.mDeathFighterss[i];
  372. break;
  373. }
  374. }
  375. if (null != fighter)
  376. {
  377. this.mDeathFighterss.Remove(fighter);
  378. }
  379. }
  380. /// <summary>
  381. /// 英雄受到治疗效果
  382. /// </summary>
  383. /// <param name="who">目标对象</param>
  384. /// <param name="cure">治疗值</param>
  385. public void OnCureLogicFighter(string who, float cure, float tipdelayTime = 0)
  386. {
  387. LogicFighter target = this.FindFighter(who);
  388. if (null == target)
  389. {
  390. return;
  391. }
  392. float cureAdd = 0f;
  393. //if (target.GetBuffEffectProperty(EBuffEffect.EBUFF_EFFECT_Cure) > 0)
  394. //{
  395. // cureAdd = cure * target.GetBuffEffectProperty(EBuffEffect.EBUFF_EFFECT_Cure) / 100;
  396. //}
  397. cure = cure + cureAdd;
  398. //Debug.Log(who + " cure:" + cure);
  399. target.ModifyProperty(EBattleProperty.HP, cure);
  400. this.Env().ShowAdapter().BattleTipShowing(who, EBattleTips.EDAMAGE_TIPS_CURE, ((int)cure).ToString());
  401. }
  402. /// <summary>
  403. /// 英雄能量恢复
  404. /// </summary>
  405. /// <param name="who">目标对象id</param>
  406. /// <param name="power">能量值</param>
  407. /// <param name="isTip">是否需要提示信息</param>
  408. public void OnCurePower(string who, float power, bool isTip = false)
  409. {
  410. LogicFighter target = this.FindFighter(who);
  411. if (null == target)
  412. {
  413. return;
  414. }
  415. target.ModifyProperty(EBattleProperty.NPOWER, power);
  416. if (isTip)
  417. {
  418. this.Env().ShowAdapter().BattleTipShowing(who, EBattleTips.EDAMAGE_TIPS_POWERRECOVER, power.ToString());
  419. }
  420. }
  421. /// <summary>
  422. /// 英雄受到魔法伤害
  423. /// </summary>
  424. /// <param name="casterID">施法对象ID</param>
  425. /// <param name="targetID">目标对象id</param>
  426. /// <param name="damage">伤害数值</param>
  427. /// <param name="isCritical">是否暴击</param>
  428. /// <param name="delay">延迟显示</param>
  429. public void OnMagicDamageToBattleFighter(string casterID, string targetID, float damage,
  430. bool isCritical = false, float tipdelayTime = 0)
  431. {
  432. LogicFighter target = this.FindFighter(targetID);
  433. LogicFighter caster = this.FindFighter(casterID);
  434. if (null == target || true == target.IsDead())
  435. {
  436. //LogHelper.LogError("目标死亡 id:" + target.ID());
  437. return;
  438. }
  439. ///护盾检测【被攻击方】
  440. damage = OnMagicDamageByBuffHandle(caster, target, damage, EBuffEffect.EBUFF_EFFECT_Shield);
  441. if (damage == 0)
  442. {
  443. //Debug.LogError("攻击伤害为零无效");
  444. return;
  445. }
  446. damage = damage * this.Env().BattleGlobalOper().GetLianJiDamageRate() * 1.0f / 100;
  447. //Debug.LogError(targetID + " 伤害 " + damage);
  448. target.ModifyProperty(EBattleProperty.HP, damage);
  449. #region UI显示信息/动作表现
  450. if (target.GetState().GetCurrentState().Type() == BaseState.EFighterState.IDLE)
  451. {
  452. target.GetState().ChangeState(BaseState.EFighterState.ONHIT, null);
  453. }
  454. else
  455. {
  456. this.Env().ShowAdapter().EnterHitState(target.ID());
  457. }
  458. //刷新界面数据
  459. this.Env().ShowAdapter().OnRefreshWindowData();
  460. //伤害提示
  461. if (isCritical)
  462. {
  463. this.Env().ShowAdapter().BattleTipShowing(targetID, EBattleTips.EDAMAGE_TIPS_CRIT, (Mathf.Abs((int)damage)).ToString(), tipdelayTime);
  464. }
  465. else
  466. {
  467. this.Env().ShowAdapter().BattleTipShowing(targetID, EBattleTips.EDAMAGE_TIPS_DAMAGE, (Mathf.Abs((int)damage)).ToString(), tipdelayTime);
  468. }
  469. // 目标角色处理
  470. if (target.IsDead())
  471. {
  472. this.Env().mBattleGlobalOper.OnTriggerPassiveSkill((int)ESkillTrigger.ESkill_TRIGGER_DEAD, string.Empty, casterID, targetID);
  473. // 目标对象处理
  474. target.GetState().ChangeState(BaseState.EFighterState.DEAD, null);
  475. return;
  476. }
  477. #endregion
  478. }
  479. /// <summary>
  480. /// 攻击行为被(buff)过滤
  481. /// </summary>
  482. /// <param name="caster"></param>
  483. /// <param name="target"></param>
  484. /// <param name="damage"></param>
  485. /// <returns></returns>
  486. private float OnMagicDamageByBuffHandle(LogicFighter caster, LogicFighter target, float damage, EBuffEffect effecttype)
  487. {
  488. float result = damage;
  489. switch (effecttype)
  490. {
  491. case EBuffEffect.EBUFF_EFFECT_Shield:
  492. ///提示用,可抵御的伤害数字
  493. int shieldDefence = target.GetBuffEffectProperty(EBuffEffect.EBUFF_EFFECT_Shield);
  494. ///剩余护盾值
  495. int lastShieldDefence = 0;
  496. // 伤害百分比加成效果
  497. if (shieldDefence > 0)
  498. {
  499. int tipDefence = 0;
  500. lastShieldDefence = shieldDefence + (int)result;
  501. if (lastShieldDefence > 0)
  502. {
  503. tipDefence = (int)Mathf.Abs(result);
  504. result = 0;
  505. }
  506. else
  507. {
  508. result = lastShieldDefence;
  509. tipDefence = shieldDefence;
  510. lastShieldDefence = 0;
  511. }
  512. LogHelper.LogError(target.ID() + ":护盾效果:抵御" + tipDefence + "点伤害,剩余" + lastShieldDefence);
  513. target.SetBuffEffectProperty(EBuffEffect.EBUFF_EFFECT_Shield, lastShieldDefence);
  514. this.Env().ShowAdapter().BattleTipShowing(target.ID(), EBattleTips.EDAMAGE_IMMO, tipDefence.ToString());
  515. }
  516. if (result == 0)
  517. {
  518. //LogHelper.LogError(caster.ID() + "-------------" + damage + "---------------------------护盾值剩余" + shieldDefence);
  519. }
  520. break;
  521. }
  522. return result;
  523. }
  524. }
  525. }