InstanceManual.cs 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  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. namespace CommonAI.Zone.Instance
  10. {
  11. /// <summary>
  12. /// 纯手动控制AI,完全没有自动成分
  13. /// </summary>
  14. public class InstanceManual : InstanceUnit
  15. {
  16. private StateFollowAndAttack mAttackTargget;
  17. private TimeExpire<WaitTimeHandler> mWaitCommand;
  18. public InstanceManual(InstanceZone zone, UnitInfo info, string name, int force, int level)
  19. : base(zone, info, name, force, level)
  20. {
  21. }
  22. public void queueDoAction(float timeSEC, string actionName, State.StateStopHandler over = null)
  23. {
  24. mAttackTargget = null;
  25. QueueStateActionTime state = new QueueStateActionTime(this, timeSEC, actionName);
  26. if (over != null)
  27. {
  28. state.AddStopOnce(over);
  29. }
  30. queueState(state);
  31. }
  32. public void queueIdle(float timeSEC, State.StateStopHandler over = null)
  33. {
  34. mAttackTargget = null;
  35. QueueStateIdleTime state = new QueueStateIdleTime(this, timeSEC);
  36. if (over != null)
  37. {
  38. state.AddStopOnce(over);
  39. }
  40. queueState(state);
  41. }
  42. public void queueMoveTo(float x, float y, State.StateStopHandler over = null)
  43. {
  44. mAttackTargget = null;
  45. QueueStateMoveTo state = new QueueStateMoveTo(this, x, y);
  46. if (over != null)
  47. {
  48. state.AddStopOnce(over);
  49. }
  50. queueState(state);
  51. }
  52. public void queueLaunchSkill(int skillID, bool random, State.StateStopHandler over = null)
  53. {
  54. mAttackTargget = null;
  55. QueueStateLaunchSkill state = new QueueStateLaunchSkill(this, skillID, random, over);
  56. queueState(state);
  57. }
  58. public void focuseAttack(InstanceUnit targget)
  59. {
  60. mAttackTargget = new StateFollowAndAttack(this, targget);
  61. changeState(mAttackTargget);
  62. }
  63. public void wait(float timeSEC, WaitTimeHandler over)
  64. {
  65. // 强制中断前一个等待指令
  66. if (mWaitCommand != null)
  67. {
  68. mWaitCommand.Tag.Invoke();
  69. }
  70. mWaitCommand = new TimeExpire<WaitTimeHandler>(over, (int)(timeSEC * 1000));
  71. }
  72. protected override void onUpdate(bool slowRefresh)
  73. {
  74. base.onUpdate(slowRefresh);
  75. if (mWaitCommand != null && mWaitCommand.Update(Parent.UpdateIntervalMS))
  76. {
  77. mWaitCommand.Tag.Invoke();
  78. mWaitCommand = null;
  79. }
  80. }
  81. protected override void onAction(ObjectAction act)
  82. {
  83. if (IsDead())
  84. {
  85. return;
  86. }
  87. if (act is UnitStopMoveAction)
  88. {
  89. doSomething();
  90. }
  91. else if (act is UnitMoveAction)
  92. {
  93. UnitMoveAction move = act as UnitMoveAction;
  94. startMoveTo(move.x, move.y);
  95. }
  96. else if (act is UnitAxisAction)
  97. {
  98. }
  99. else if (act is UnitLaunchSkillAction)
  100. {
  101. UnitLaunchSkillAction sk = act as UnitLaunchSkillAction;
  102. launchSkill(sk.SkillID, new InstanceUnit.LaunchSkillParam(sk.TargetObjID, sk.SpellTargetPos, sk.IsAutoFocusNearTarget));
  103. }
  104. else if (act is UnitFaceToAction)
  105. {
  106. UnitFaceToAction ufa = act as UnitFaceToAction;
  107. this.faceTo(ufa.Direction);
  108. }
  109. else if (act is UnitSlipAction)
  110. {
  111. // do nothing
  112. }
  113. else if (act is UnitGuardAction)
  114. {
  115. // do nothing
  116. }
  117. else if (act is UnitFocuseTargetAction)
  118. {
  119. // do nothing
  120. }
  121. }
  122. public delegate void WaitTimeHandler();
  123. class QueueStateMoveTo : State
  124. {
  125. private readonly float targetX;
  126. private readonly float targetY;
  127. private bool isEnd = false;
  128. private MoveAI moveAI;
  129. public QueueStateMoveTo(InstanceUnit unit, float x, float y)
  130. : base(unit)
  131. {
  132. this.targetX = x;
  133. this.targetY = y;
  134. }
  135. override public bool onBlock(State new_state)
  136. {
  137. if (unit.IsDead()) return true;
  138. return isEnd;
  139. }
  140. override protected void onStart()
  141. {
  142. unit.SetActionStatus(UnitActionStatus.Move);
  143. this.moveAI = new MoveAI(unit);
  144. this.moveAI.FindPath(targetX, targetY);
  145. }
  146. override protected void onUpdate()
  147. {
  148. if (!isEnd)
  149. {
  150. unit.faceTo(targetX, targetY);
  151. MoveBlockResult result = moveAI.Update();
  152. if ((result.result & MoveResult.MOVE_RESULT_NO_WAY) != 0)
  153. {
  154. isEnd = true;
  155. unit.doSomething();
  156. }
  157. else if ((result.result & MoveResult.RESULTS_MOVE_END) != 0)
  158. {
  159. float r = Math.Max(zone.MinStep, unit.BodyBlockSize);
  160. if (CMath.includeRoundPoint(unit.X, unit.Y, r, targetX, targetY))
  161. {
  162. isEnd = true;
  163. unit.doSomething();
  164. }
  165. }
  166. else
  167. {
  168. float r = Math.Max(zone.MinStep, unit.BodyBlockSize);
  169. if (CMath.includeRoundPoint(unit.X, unit.Y, r, targetX, targetY))
  170. {
  171. isEnd = true;
  172. unit.doSomething();
  173. }
  174. }
  175. }
  176. }
  177. override protected void onStop()
  178. {
  179. }
  180. }
  181. class QueueStateLaunchSkill : State
  182. {
  183. private readonly int SkillID;
  184. private readonly bool IsRandom;
  185. private readonly StateStopHandler SkillOver;
  186. private StateSkill mSkillState;
  187. public QueueStateLaunchSkill(InstanceUnit unit, int skillID, bool random, StateStopHandler over)
  188. : base(unit)
  189. {
  190. this.SkillID = skillID;
  191. this.IsRandom = random;
  192. this.SkillOver = over;
  193. }
  194. public override bool onBlock(State new_state)
  195. {
  196. if (unit.IsDead()) return true;
  197. if (new_state is StateSkill)
  198. {
  199. return true;
  200. }
  201. return mSkillState != null;
  202. }
  203. protected override void onStart()
  204. {
  205. }
  206. protected override void onUpdate()
  207. {
  208. if (IsRandom)
  209. {
  210. mSkillState = unit.launchRandomSkillForAll(new InstanceUnit.LaunchSkillParam());
  211. }
  212. else
  213. {
  214. mSkillState = unit.launchSkill(SkillID, new InstanceUnit.LaunchSkillParam());
  215. }
  216. if (mSkillState != null && SkillOver != null)
  217. {
  218. mSkillState.AddStopOnce(SkillOver);
  219. }
  220. }
  221. protected override void onStop()
  222. {
  223. if (mSkillState == null && SkillOver != null)
  224. {
  225. SkillOver.Invoke(unit, this);
  226. }
  227. }
  228. }
  229. class QueueStateIdleTime : State
  230. {
  231. private readonly TimeExpire<int> mIdleTime;
  232. public QueueStateIdleTime(InstanceUnit unit, float timeSEC)
  233. : base(unit)
  234. {
  235. mIdleTime = new TimeExpire<int>((int)(timeSEC * 1000));
  236. }
  237. override public bool onBlock(State new_state)
  238. {
  239. if (unit.IsDead()) return true;
  240. return mIdleTime.IsEnd;
  241. }
  242. override protected void onStart()
  243. {
  244. unit.SetActionStatus(UnitActionStatus.Idle);
  245. }
  246. override protected void onUpdate()
  247. {
  248. if (mIdleTime.Update(zone.UpdateIntervalMS))
  249. {
  250. unit.doSomething();
  251. }
  252. }
  253. override protected void onStop() { }
  254. }
  255. class QueueStateActionTime : QueueStateIdleTime
  256. {
  257. private readonly string ActionName;
  258. public QueueStateActionTime(InstanceUnit unit, float timeSEC, string actionName)
  259. : base(unit, timeSEC)
  260. {
  261. this.ActionName = actionName;
  262. }
  263. override protected void onStart()
  264. {
  265. unit.queueEvent(new UnitDoActionEvent(unit.ID, ActionName));
  266. }
  267. }
  268. }
  269. }