InstancePet.cs 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. using CommonAI.RTS;
  2. using CommonLang.Vector;
  3. using CommonAI.Zone.Helper;
  4. using CommonLang;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Linq;
  8. using System.Text;
  9. using CommonAI.Zone.Instance.Helper;
  10. using CommonAI.Data;
  11. namespace CommonAI.Zone.Instance
  12. {
  13. public class InstancePet : InstanceUnit, ISummonedUnit
  14. {
  15. protected InstanceUnit mMaster;
  16. protected StateFollowMaster mFollowMaster;
  17. public InstanceUnit Owner { get { return this; } }
  18. public InstancePet(InstanceZone zone, UnitInfo info, string name, int force, int level)
  19. : base(zone, info, name, force, level)
  20. {
  21. s_mFollowDistance = Templates.CFG.PET_FOLLOW_DISTANCE_MIN + (Templates.CFG.PET_FOLLOW_DISTANCE_MAX - Templates.CFG.PET_FOLLOW_DISTANCE_MIN) / 2;
  22. }
  23. public override bool IntersectMap { get { return Info.BodySize > 0; } }
  24. public override bool IntersectObj { get { return false; } }
  25. public override bool IsActive { get { return false; } }
  26. public override bool IsAttackable { get { return false; } }
  27. /// <summary>
  28. /// 获取主人
  29. /// </summary>
  30. public virtual InstanceUnit Master
  31. {
  32. get { return mMaster; }
  33. set { this.mMaster = value; this.mFollowMaster = new StateFollowMaster(this, mMaster); }
  34. }
  35. public virtual InstanceUnit SummonerUnit
  36. {
  37. get { return Master; }
  38. set { Master = value; }
  39. }
  40. /// <summary>
  41. /// IAO标记
  42. /// </summary>
  43. public override ObjectAoiStatus AoiStatus { get { return this.Master == null ? base.AoiStatus : this.Master.AoiStatus; } }
  44. // 跟随最大最小距离的中间值
  45. public static float s_mFollowDistance = 0;
  46. protected override void onUpdate(bool slowRefresh)
  47. {
  48. base.onUpdate(slowRefresh);
  49. OnPetUpdate();
  50. }
  51. protected virtual void OnPetUpdate()
  52. {
  53. if (mMaster != null)
  54. {
  55. if (mMaster.IsDead() || !mMaster.Enable)
  56. {
  57. this.kill(this);
  58. }
  59. else if (!CMath.includeRoundPoint(X, Y, Templates.CFG.PET_FOLLOW_DISTANCE_LIMIT, mMaster.X, mMaster.Y))
  60. {
  61. this.transportToMaster();
  62. }
  63. else if (!CMath.includeRoundPoint(X, Y, Templates.CFG.PET_FOLLOW_DISTANCE_MAX, mMaster.X, mMaster.Y))
  64. {
  65. this.followMaster();
  66. }
  67. }
  68. if (CurrentState is StateIdle)
  69. {
  70. doSomething2();
  71. }
  72. }
  73. protected void transportToMaster()
  74. {
  75. float dx, dy;
  76. CMath.RandomPosInRound(Parent.RandomN, mMaster.X, mMaster.Y, Templates.CFG.PET_FOLLOW_DISTANCE_MAX, out dx, out dy);
  77. if (IntersectMap && Parent.TryTouchMap(this, dx, dy))
  78. {
  79. dx = Master.X;
  80. dy = Master.Y;
  81. }
  82. this.Virtual.SetCombatState(BattleStatus.None);
  83. this.transport(dx, dy);
  84. this.followMaster();
  85. }
  86. protected void followMaster()
  87. {
  88. StateSkill skillState = this.CurrentState as StateSkill;
  89. if (skillState != null && skillState.Skill != null && !skillState.IsCancelableByMove)
  90. {
  91. return;
  92. }
  93. else if(CurrentState == mFollowMaster)
  94. {
  95. return;
  96. }
  97. //float distanceTemp = MathVector.getDistance(this.X, this.Y, this.Master.X, this.Master.Y);
  98. float speedChag = 1.01f;// (distanceTemp < s_mFollowDistance) ? 1.01f : 1.1f;
  99. this.followMasterChangeSpeed(speedChag);
  100. changeState(mFollowMaster);
  101. //System.Console.WriteLine("---followMaster: " + TimeUtil.GetTimestampMS() + speedChag);
  102. }
  103. protected virtual void followMasterChangeSpeed(float speedChag)
  104. {
  105. // 随从使用主人的速度
  106. if (this.Master != null)
  107. {
  108. this.SetMoveSpeed(this.Master.MoveSpeedSEC * speedChag);
  109. }
  110. }
  111. protected void doSomething2()
  112. {
  113. if (!IsNoneSkill)
  114. {
  115. using (var list = ListObjectPool<InstanceUnit>.AllocAutoRelease())
  116. {
  117. //随机找个目标施法//
  118. Parent.getObjectsRoundRange<InstanceUnit>(Collider.Object_Pos_IncludeInRound, X, Y, Info.GuardRange, list, this.AoiStatus);
  119. DoAndRemoveCollection.UpdateAndRemove<InstanceUnit>(list, (InstanceUnit u) =>
  120. {
  121. return !u.IsActive;
  122. });
  123. CUtils.RandomList(Parent.RandomN, list);
  124. foreach (SkillState skill in SkillStatus)
  125. {
  126. if (skill.LaunchSkill.AutoLaunch && skill.TryLaunch())
  127. {
  128. foreach (InstanceUnit u in list)
  129. {
  130. if (Parent.IsAttackable(this, u, skill.Data.ExpectTarget, AttackReason.Look, skill.Data))
  131. {
  132. //检测是否有可释放技能//
  133. if (tryAutoLaunch(skill, u))
  134. {
  135. return;
  136. }
  137. }
  138. }
  139. }
  140. }
  141. }
  142. }
  143. }
  144. protected virtual bool tryAutoLaunch(SkillState st, InstanceUnit target)
  145. {
  146. if (st != null && st.LaunchSkill.AutoLaunch)
  147. {
  148. changeState(new StateFollowAndAttack(this, target, st.Data.ExpectTarget));
  149. return true;
  150. }
  151. return false;
  152. }
  153. protected override void Disposing()
  154. {
  155. mMaster = null;
  156. mFollowMaster = null;
  157. base.Disposing();
  158. }
  159. //----------------------------------------------------------------------------------------------------------
  160. protected override IUnitStatistic CreateUnitStatistic()
  161. {
  162. return new PetUnitStatistic(this);
  163. //return base.CreateUnitStatistic();
  164. }
  165. public class PetUnitStatistic : UnitStatistic
  166. {
  167. private InstancePet owner;
  168. public PetUnitStatistic(InstancePet owner) : base(owner)
  169. {
  170. this.owner = owner;
  171. }
  172. public override void onAttack(InstanceUnit target, int reduceHP)
  173. {
  174. //伤害统计重定向到主人//
  175. if (owner.Master != null)
  176. {
  177. owner.Master.Statistic.onAttack(target, reduceHP);
  178. }
  179. else
  180. {
  181. base.onAttack(target, reduceHP);
  182. }
  183. }
  184. public override void onKill(InstanceUnit target)
  185. {
  186. //击杀统计重定向到主人//
  187. if (owner.Master != null)
  188. {
  189. owner.Master.Statistic.onKill(target);
  190. }
  191. else
  192. {
  193. base.onKill(target);
  194. }
  195. }
  196. }
  197. //----------------------------------------------------------------------------------------------------------
  198. /// <summary>
  199. /// 移动状态
  200. /// </summary>
  201. public class StateFollowMaster : State
  202. {
  203. // 被追目标
  204. readonly private InstanceZoneObject master;
  205. private MoveAI move;
  206. public StateFollowMaster(InstancePet unit, InstanceZoneObject target)
  207. : base(unit)
  208. {
  209. this.master = target;
  210. this.move = new MoveAI(unit);
  211. }
  212. override public bool onBlock(State new_state)
  213. {
  214. if (new_state is StateDead)
  215. {
  216. return true;
  217. }
  218. if (new_state is StateFollowMaster)
  219. {
  220. return true;
  221. }
  222. float r = Math.Max(zone.Templates.CFG.PET_FOLLOW_DISTANCE_MIN, master.BodyBlockSize + unit.BodyBlockSize);
  223. if (CMath.includeRoundPoint(unit.X, unit.Y, r, master.X, master.Y))
  224. {
  225. unit.SetActionStatus(UnitActionStatus.Idle);
  226. return true;
  227. }
  228. StateSkill stateSkill = new_state as StateSkill;
  229. if(stateSkill != null && !stateSkill.IsCancelableByMove)
  230. {
  231. return true;
  232. }
  233. return false;
  234. }
  235. override protected void onStart()
  236. {
  237. unit.SetActionStatus(UnitActionStatus.Move);
  238. this.move.FindPath(master);
  239. }
  240. override protected void onUpdate()
  241. {
  242. float r = Math.Max(zone.Templates.CFG.PET_FOLLOW_DISTANCE_MIN, master.BodyBlockSize + unit.BodyBlockSize);
  243. if (CMath.includeRoundPoint(unit.X, unit.Y, r, master.X, master.Y))
  244. {
  245. unit.SetActionStatus(UnitActionStatus.Idle);
  246. unit.doSomething();
  247. }
  248. else
  249. {
  250. move.Update();
  251. if (move.IsNoWay)
  252. {
  253. (unit as InstancePet).transportToMaster();
  254. }
  255. }
  256. }
  257. override protected void onStop()
  258. {
  259. unit.SetActionStatus(UnitActionStatus.Idle);
  260. }
  261. }
  262. }
  263. }