InstancePlayer.cs 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183
  1. using CommonAI.RTS;
  2. using CommonLang.Vector;
  3. using CommonAI.Zone.Helper;
  4. using CommonAI.Zone.Formula;
  5. using CommonLang;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using System.Text;
  10. using CommonLang.IO;
  11. using CommonAI.Data;
  12. using CommonAI.Zone.ZoneEditor.EventTrigger;
  13. using CommonAI.ZoneClient;
  14. namespace CommonAI.Zone.Instance
  15. {
  16. /// <summary>
  17. /// 可自动战斗的可操作单位
  18. /// </summary>
  19. public class InstancePlayer : InstanceUnit
  20. {
  21. private readonly string mPlayerUUID;
  22. //private HashMap<string, int> mKilledPlayersID = new HashMap<string, int>();
  23. private CommonAI.ZoneClient.SyncMode mCurrentSyncMode;
  24. private bool mIsSkillControlByServer = true;
  25. //自动拾取范围
  26. protected float mAutoPickRange = XmdsConstConfig.AUTOPICK_RANGE;
  27. protected float mAutoPickSearchRange = XmdsConstConfig.AUTOPICK_RANGE * 3;
  28. protected TimeInterval<int> mCheckGuard;
  29. protected HashMap<string, QuestData> mQuests = new HashMap<string, QuestData>();
  30. protected UnitLaunchSkillAction mWaitingSkill;
  31. protected StatePlayerControlMove mControlMove;
  32. protected StatePlayerUpdateMove mUpdateMove;
  33. protected StateFollowAndAttack mFocusTarget;
  34. protected StateFollowAndPickItem mFocusPickItem;
  35. protected StatePlayerAttackTo mAttackTo;
  36. public virtual bool isTeamMemberAndFollow()
  37. {
  38. return false;
  39. }
  40. public override string PlayerUUID
  41. {
  42. get { return mPlayerUUID; }
  43. }
  44. public string ClientID { get; set; }
  45. public bool IsGuard { get; set; }
  46. public bool IsReady { get; private set; }
  47. public override bool IsPlayer { get { return true; } }
  48. public override bool IsPlayerUnit { get { return true; } }
  49. public override bool IntersectObj { get { return (Templates.CFG.PLAYER_NONE_TOUCH) ? false : base.IntersectObj; } }
  50. public override bool IsSkillControllableByServer { get { return mIsSkillControlByServer; } }
  51. public CommonAI.ZoneClient.SyncMode ClientSyncMode { get { return mCurrentSyncMode; } }
  52. public bool IsRobot { get; set; }
  53. public InstancePlayer(InstanceZone zone, UnitInfo info, string name, int force, int level, int alliesForce)
  54. : base(zone, info, name, force, level, false, alliesForce)
  55. {
  56. this.mPlayerUUID = string.IsNullOrEmpty(name) ? "" : name;
  57. this.mSyncInfo.PlayerUUID = mPlayerUUID;
  58. this.mControlMove = new StatePlayerControlMove(this);
  59. this.mUpdateMove = new StatePlayerUpdateMove(this);
  60. this.mCheckGuard = new TimeInterval<int>(Templates.CFG.AI_VIEW_TRIGGER_CHECK_TIME_MS);
  61. }
  62. protected override void Disposing()
  63. {
  64. /*
  65. mControlMove = null;
  66. mUpdateMove = null;
  67. mFocusTarget = null;
  68. mFocusPickItem = null;
  69. mAttackTo = null;
  70. */
  71. base.Disposing();
  72. }
  73. /// <summary>
  74. /// 联网模式,断开连接。
  75. /// </summary>
  76. public virtual void OnDisconnected() { }
  77. /// <summary>
  78. /// 联网模式,重新连接。
  79. /// </summary>
  80. public virtual void OnReconnected(UnitInfo temp, int force, int level, Vector2 enterPos) { }
  81. public virtual LockActorEvent GenLockActorEvent(string displayName, float inRange, float outRange, int updateInterval)
  82. {
  83. // 准备发送当前场景信息 //
  84. var loc = new LockActorEvent();
  85. loc.ServerUpdateInterval = updateInterval;
  86. loc.ClientSyncObjectRange = inRange;
  87. loc.ClientSyncObjectOutRange = outRange;
  88. loc.UnitData = IOUtil.CloneIExternalizable<ZoneClient.SyncUnitInfo>(TemplateManager.MessageCodec, this.GenSyncUnitInfo(true));
  89. loc.UnitData.Name = displayName;
  90. loc.UnitData.x = this.X;
  91. loc.UnitData.y = this.Y;
  92. loc.GameServerProp = CUtils.TryClone(this.Info.Properties);
  93. loc.Skills = this.GetSkillEvent();
  94. loc.UnitData.CurrentBuffStatus = this.GetCurrentBuffStatus();
  95. loc.CurrentSkillStatus = this.GetCurrentSkillStatus();
  96. loc.CurrentItemStatus = this.GetCurrentItemStatus();
  97. loc.CurrentPlayerVars = this.GetCurrentUnitVars();
  98. loc.CurrentZoneVars = Parent.GetCurrentZoneVars();
  99. return loc;
  100. }
  101. protected override void onUpdateRecover()
  102. {
  103. base.onUpdateRecover();
  104. }
  105. override protected void onResetAI()
  106. {
  107. this.cleanFocus();
  108. this.doSomething();
  109. }
  110. protected override void onAdded(bool pointLv)
  111. {
  112. base.onAdded(pointLv);
  113. this.doSomething();
  114. }
  115. // override protected void onDead(InstanceUnit attacker)
  116. // {
  117. // if (attacker is IPlayerUnit)
  118. // {
  119. // var killer = attacker as IPlayerUnit;
  120. // killer.PutKillPlayer(this.PlayerUUID);
  121. // }
  122. // }
  123. override protected void onUpdate(bool slowRefresh)
  124. {
  125. base.onUpdate(slowRefresh);
  126. this.updateGuard();
  127. this.updateCurrentSkill();
  128. this.updateAttackTo();
  129. }
  130. protected virtual void updateCurrentSkill()
  131. {
  132. if (CurrentState is StateSkill)
  133. {
  134. var current = CurrentState as StateSkill;
  135. if (mWaitingSkill != null && current.IsCancelableBySkill)
  136. {
  137. doLaunchSkill(mWaitingSkill);
  138. }
  139. else if (IsGuard)
  140. {
  141. if ((mFocusTarget != null))
  142. {
  143. tryLaunchRandomSkillAndCancelCurrentSkill(mFocusTarget.TargetUnit, true);
  144. }
  145. }
  146. }
  147. }
  148. protected virtual void updateGuard()
  149. {
  150. if (mFocusTarget != null && !mFocusTarget.IsActive)
  151. {
  152. mFocusTarget = null;
  153. }
  154. if (mFocusPickItem != null && !mFocusPickItem.IsActive)
  155. {
  156. mFocusPickItem = null;
  157. }
  158. if (IsGuard)
  159. {
  160. // 旋风斩贴近目标 //
  161. if (mFocusTarget != null && CurrentState is StateSkill)
  162. {
  163. var state = CurrentState as StateSkill;
  164. if (state.IsControlMoveable && !state.unit.IsCannotMove)
  165. {
  166. state.setMoveTo(mFocusTarget.Target.X, mFocusTarget.Target.Y);
  167. }
  168. }
  169. // 没目标定期检测目标 //
  170. if ((mFocusTarget == null) && (mFocusPickItem == null))
  171. {
  172. if (mCheckGuard.Update(Parent.UpdateIntervalMS))
  173. {
  174. var item = findGuardPickItem();
  175. if (item != null)
  176. {
  177. doFocusPickItem(item);
  178. return;
  179. }
  180. var enemy = findGuardTarget(SkillTemplate.CastTarget.Enemy, AttackReason.Look);
  181. if (enemy != null)
  182. {
  183. doFocusAttack(enemy, SkillTemplate.CastTarget.Enemy);
  184. return;
  185. }
  186. var alias = findGuardTarget(SkillTemplate.CastTarget.AlliesIncludeSelf, AttackReason.Look);
  187. if (alias != null)
  188. {
  189. doFocusAttack(alias, SkillTemplate.CastTarget.AlliesIncludeSelf);
  190. return;
  191. }
  192. }
  193. }
  194. }
  195. }
  196. protected virtual void updateAttackTo()
  197. {
  198. if (mAttackTo != null)
  199. {
  200. if (mAttackTo.IsDone)
  201. {
  202. mAttackTo = null;
  203. }
  204. else if (!mAttackTo.IsAttack)
  205. {
  206. cleanFocus();
  207. }
  208. }
  209. }
  210. public override void doSomething()
  211. {
  212. if (mWaitingSkill != null && CurrentState is StateSkill)
  213. {
  214. if (doLaunchSkill(mWaitingSkill))
  215. {
  216. return;
  217. }
  218. }
  219. else if (IsGuard)
  220. {
  221. if (mFocusPickItem != null && mFocusPickItem.IsActive)
  222. {
  223. changeState(mFocusPickItem);
  224. return;
  225. }
  226. else
  227. {
  228. mFocusPickItem = null;
  229. }
  230. if (mFocusTarget != null && mFocusTarget.IsActive)
  231. {
  232. if (Parent.IsAttackable(this, mFocusTarget.TargetUnit, SkillTemplate.CastTarget.AlliesIncludeSelf, AttackReason.Attack, Info))
  233. {
  234. mFocusTarget = null;
  235. }
  236. else
  237. {
  238. changeState(mFocusTarget);
  239. return;
  240. }
  241. }
  242. else
  243. {
  244. mFocusTarget = null;
  245. }
  246. if (mAttackTo != null && !mAttackTo.IsDone)
  247. {
  248. changeState(mAttackTo);
  249. return;
  250. }
  251. }
  252. base.doSomething();
  253. }
  254. public virtual InstanceUnit findGuardTarget(SkillTemplate.CastTarget expect = SkillTemplate.CastTarget.Enemy, AttackReason reason = AttackReason.Look)
  255. {
  256. InstanceUnit min = null;
  257. if (getAvailableSkill(expect) != null)
  258. {
  259. float min_len = float.MaxValue;
  260. Parent.ForEachNearObjects(this.X, this.Y, this.Info.GuardRange, (InstanceUnit u, ref bool cancel) =>
  261. {
  262. if (Parent.IsAttackable(this, u, expect, reason, Info))
  263. {
  264. float len = MathVector.getDistanceSquare(u.X, u.Y, this.X, this.Y);
  265. if (min_len > len)
  266. {
  267. min_len = len;
  268. min = u;
  269. }
  270. }
  271. });
  272. }
  273. return min;
  274. }
  275. public virtual StateFollowAndAttack doFocusAttack(InstanceUnit target, SkillTemplate.CastTarget expect_target = SkillTemplate.CastTarget.Enemy)
  276. {
  277. if ((mAttackTo == null || mAttackTo.IsAttack) && Parent.IsAttackable(this, target, expect_target, AttackReason.Tracing, Info))
  278. {
  279. if (mFocusTarget != null)
  280. {
  281. if (mFocusTarget.TargetUnit != target)
  282. {
  283. mFocusTarget = new StateFollowAndAttack(this, target, expect_target, true);
  284. if (changeState(mFocusTarget))
  285. {
  286. queueEvent(new PlayerFocuseTargetEvent(this.ID, target.ID, expect_target));
  287. }
  288. }
  289. }
  290. else
  291. {
  292. mFocusTarget = new StateFollowAndAttack(this, target, expect_target, true);
  293. if (changeState(mFocusTarget))
  294. {
  295. queueEvent(new PlayerFocuseTargetEvent(this.ID, target.ID, expect_target));
  296. }
  297. }
  298. }
  299. else
  300. {
  301. mFocusTarget = null;
  302. }
  303. return mFocusTarget;
  304. }
  305. //可被自动拾取的,是那种没有进度条的
  306. public virtual InstanceItem findGuardPickItem()
  307. {
  308. InstanceItem min = null;
  309. float min_len = float.MaxValue;
  310. Parent.ForEachNearObjects(this.X, this.Y, this.mAutoPickRange, (InstanceItem u, ref bool cancel) =>
  311. {
  312. if (u.IsPickable(this))
  313. {
  314. float len = MathVector.getDistanceSquare(u.X, u.Y, this.X, this.Y);
  315. if (min_len > len)
  316. {
  317. min_len = len;
  318. min = u;
  319. }
  320. }
  321. });
  322. return min;
  323. }
  324. public virtual StateFollowAndPickItem doFocusPickItem(InstanceItem target, bool doPick = true)
  325. {
  326. if (mAttackTo == null || mAttackTo.IsAttack)
  327. {
  328. if (mFocusPickItem != null)
  329. {
  330. if (mFocusPickItem.Target != target)
  331. {
  332. StateFollowAndPickItem focusPickItem = new StateFollowAndPickItem(this, target, doPick);
  333. if (changeState(focusPickItem))
  334. {
  335. mFocusPickItem = focusPickItem;
  336. queueEvent(new PlayerFocuseTargetEvent(this.ID, target.ID, SkillTemplate.CastTarget.NA));
  337. }
  338. }
  339. }
  340. else
  341. {
  342. StateFollowAndPickItem focusPickItem = new StateFollowAndPickItem(this, target, doPick);
  343. if (changeState(focusPickItem))
  344. {
  345. mFocusPickItem = focusPickItem;
  346. queueEvent(new PlayerFocuseTargetEvent(this.ID, target.ID, SkillTemplate.CastTarget.NA));
  347. }
  348. }
  349. }
  350. else
  351. {
  352. mFocusPickItem = null;
  353. }
  354. return mFocusPickItem;
  355. }
  356. protected virtual void cleanFocus()
  357. {
  358. mFocusPickItem = null;
  359. mFocusTarget = null;
  360. }
  361. // internal void PutKillPlayer(string killed)
  362. // {
  363. // int count = 0;
  364. // if (mKilledPlayersID.TryGetValue(killed, out count))
  365. // {
  366. // mKilledPlayersID.Put(killed, count + 1);
  367. // }
  368. // else
  369. // {
  370. // mKilledPlayersID.Put(killed, 1);
  371. // }
  372. // }
  373. //--------------------------------------------------------------------------------------
  374. public virtual bool doRequest(ActorRequest req)
  375. {
  376. if (req is UnitGetStatisticRequest)
  377. {
  378. doGetStatisticRequest(req as UnitGetStatisticRequest);
  379. return true;
  380. }
  381. return false;
  382. }
  383. //设置自动拾取范围
  384. public override void SetAutoPickRange(int value)
  385. {
  386. this.mAutoPickRange = value;
  387. this.mAutoPickSearchRange = value * 3;
  388. }
  389. protected override void onAction(ObjectAction act)
  390. {
  391. //log.Info("------<onAction: " + act.ToString());
  392. if (!IsDead())
  393. {
  394. if (act is UnitMoveAction)
  395. {
  396. doMove(act as UnitMoveAction);
  397. }
  398. else if (act is UnitAxisAction)
  399. {
  400. doAxis(act as UnitAxisAction);
  401. }
  402. else if (act is UnitFaceToAction)
  403. {
  404. doFaceTo(act as UnitFaceToAction);
  405. }
  406. else if (act is UnitStopMoveAction)
  407. {
  408. doStopMove(act as UnitStopMoveAction);
  409. }
  410. else if (act is UnitLaunchSkillAction)
  411. {
  412. doLaunchSkill(act as UnitLaunchSkillAction);
  413. }
  414. else if (act is UnitUseItemAction)
  415. {
  416. doUseItem(act as UnitUseItemAction);
  417. }
  418. else if (act is UnitPickObjectAction)
  419. {
  420. doPickObject(act as UnitPickObjectAction);
  421. }
  422. else if (act is UnitUpdatePosAction)
  423. {
  424. doUnitUpdatePos(act as UnitUpdatePosAction);
  425. }
  426. else if (act is UnitCancelBuffAction)
  427. {
  428. doCancelBuff(act as UnitCancelBuffAction);
  429. }
  430. else if (act is UnitSetSubStateAction)
  431. {
  432. doUnitSetSubStateAction(act as UnitSetSubStateAction);
  433. }
  434. else if (act is PlayPetTeleportAction)
  435. {
  436. doPetTeleportAction(act as PlayPetTeleportAction);
  437. }
  438. }
  439. if (act is UnitReadAction)
  440. {
  441. doReady(act as UnitReadAction);
  442. }
  443. else if (act is UnitGuardAction)
  444. {
  445. doGuard(act as UnitGuardAction);
  446. }
  447. else if (act is UnitFollowAction)
  448. {
  449. doFollow(act as UnitFollowAction);
  450. }
  451. else if (act is UnitAttackToAction)
  452. {
  453. doAttackTo(act as UnitAttackToAction);
  454. }
  455. else if (act is UnitFocuseTargetAction)
  456. {
  457. doFocusTarget(act as UnitFocuseTargetAction);
  458. }
  459. else if (act is ChatAction)
  460. {
  461. doChat(act as ChatAction);
  462. }
  463. else if (act is UnitSetSyncModeAction)
  464. {
  465. doSetSyncMode(act as UnitSetSyncModeAction);
  466. }
  467. else if (act is UnitGetStatisticRequest)
  468. {
  469. doGetStatisticRequest(act as UnitGetStatisticRequest);
  470. }
  471. }
  472. #region PlayerActions
  473. protected virtual void doReady(UnitReadAction act)
  474. {
  475. if (IsReady == false)
  476. {
  477. IsReady = true;
  478. Parent.cb_playerReady(this);
  479. }
  480. }
  481. protected virtual void doMove(UnitMoveAction ma)
  482. {
  483. if (CurrentState is StateSkill)
  484. {
  485. StateSkill ss = CurrentState as StateSkill;
  486. ss.setMoveTo(new Vector2(ma.x, ma.y));
  487. }
  488. else
  489. {
  490. cleanFocus();
  491. startMoveTo(ma.x, ma.y);
  492. }
  493. }
  494. protected virtual void doAxis(UnitAxisAction ma)
  495. {
  496. if (CurrentState is StateSkill)
  497. {
  498. ma.dx *= 100f;
  499. ma.dy *= 100f;
  500. StateSkill ss = CurrentState as StateSkill;
  501. if (!ma.IsZero)
  502. {
  503. if (ss.IsCancelableByMove)
  504. {
  505. cleanFocus();
  506. if (this.mWaitingSkill != null)
  507. {
  508. doLaunchSkill(this.mWaitingSkill);
  509. }
  510. else if (mCurrentSyncMode != ZoneClient.SyncMode.MoveByClient_PreSkillByClient)
  511. {
  512. this.mControlMove.Action = ma;
  513. ss.block(mControlMove);
  514. }
  515. else
  516. {
  517. ss.block(mUpdateMove);
  518. }
  519. }
  520. else
  521. {
  522. this.mControlMove.Action = ma;
  523. Vector2 moveto = new Vector2(X + ma.dx, Y + ma.dy);
  524. ss.setMoveTo(moveto);
  525. }
  526. }
  527. else
  528. {
  529. ss.setMoveTo(null);
  530. }
  531. }
  532. else if (mCurrentSyncMode != ZoneClient.SyncMode.MoveByClient_PreSkillByClient)
  533. {
  534. cleanFocus();
  535. if (!ma.IsZero)
  536. {
  537. this.mControlMove.Action = ma;
  538. changeState(mControlMove);
  539. }
  540. else
  541. {
  542. doSomething();
  543. }
  544. }
  545. }
  546. protected virtual void doFaceTo(UnitFaceToAction ufa)
  547. {
  548. if (CurrentActionStatus == UnitActionStatus.Idle || CurrentActionStatus == UnitActionStatus.Move)
  549. {
  550. this.faceTo(ufa.Direction);
  551. }
  552. }
  553. protected virtual void doStopMove(UnitStopMoveAction act)
  554. {
  555. cleanFocus();
  556. if (CurrentState is StateSkill)
  557. {
  558. StateSkill ss = CurrentState as StateSkill;
  559. ss.setMoveTo(null);
  560. }
  561. else if (CurrentState is StateMove || CurrentState is StatePlayerControlMove)
  562. {
  563. doSomething();
  564. base.SetActionStatus(UnitActionStatus.Idle);
  565. }
  566. }
  567. protected virtual bool doLaunchSkill(UnitLaunchSkillAction sk)
  568. {
  569. var launched = launchSkill(sk.SkillID, new LaunchSkillParam(
  570. sk.TargetObjID,
  571. sk.SpellTargetPos,
  572. sk.IsAutoFocusNearTarget,
  573. sk.SyncDirection,
  574. sk.Direction));
  575. if (launched == null)
  576. {
  577. //Console.WriteLine("UnitLaunchSkillAction - 1");
  578. if (CurrentState is StateSkill)
  579. {
  580. var state = CurrentState as StateSkill;
  581. if (state.SkillData.ID != sk.SkillID || (state.SkillData.IsSingleAction && state.Skill.GetSkillType() != XmdsSkillType.normalAtk))
  582. {
  583. //缓存释放技能指令//
  584. mWaitingSkill = sk;
  585. }
  586. }
  587. return false;
  588. }
  589. else
  590. {
  591. //一旦释放成功,释放指令//\
  592. //Console.WriteLine("UnitLaunchSkillAction - 2");
  593. mWaitingSkill = null;
  594. return true;
  595. }
  596. }
  597. protected virtual void doGetStatisticRequest(UnitGetStatisticRequest req)
  598. {
  599. UnitGetStatisticResponse resp = new UnitGetStatisticResponse();
  600. //if (req.RequestObjectsID != null)
  601. //{
  602. // for (int i = 0; i < req.RequestObjectsID.Length; i++)
  603. // {
  604. // InstanceUnit u = Parent.getUnit(req.RequestObjectsID[i]);
  605. // if (u != null)
  606. // {
  607. // var data = u.Statistic.ToUnitStatisticData();
  608. // resp.Statistics.Put(req.RequestObjectsID[i], data);
  609. // }
  610. // }
  611. //}
  612. Parent.sendActorResponse(this, req, resp);
  613. }
  614. protected virtual void doFocusTarget(UnitFocuseTargetAction focus)
  615. {
  616. if (IsGuard)
  617. {
  618. mAttackTo = null;
  619. InstanceZoneObject src = Parent.getObject<InstanceZoneObject>(focus.targetUnitID);
  620. if ((src is InstanceUnit))
  621. {
  622. if (!IsNoneSkill && ((src as InstanceUnit).IsActive))
  623. {
  624. doFocusAttack(src as InstanceUnit);
  625. }
  626. }
  627. else if ((src is InstanceItem))
  628. {
  629. if (src.Enable)
  630. {
  631. doFocusPickItem(src as InstanceItem);
  632. }
  633. }
  634. else
  635. {
  636. cleanFocus();
  637. }
  638. }
  639. }
  640. protected virtual void doAttackTo(UnitAttackToAction act)
  641. {
  642. if (!act.attack)
  643. {
  644. cleanFocus();
  645. }
  646. mAttackTo = new StatePlayerAttackTo(this, act.targetX, act.targetY, act.attack);
  647. changeState(mAttackTo);
  648. }
  649. protected virtual void doUseItem(UnitUseItemAction use)
  650. {
  651. UseInventoryItem(use.Index, use.Count);
  652. }
  653. protected virtual void doPickObject(UnitPickObjectAction pick)
  654. {
  655. InstanceZoneObject obj = Parent.getObject<InstanceZoneObject>(pick.PickableObjectID);
  656. if (obj is InstanceItem)
  657. {
  658. InstanceItem item = obj as InstanceItem;
  659. item.PickItem(this);
  660. }
  661. else if (obj is InstanceUnit)
  662. {
  663. InstanceUnit unit = obj as InstanceUnit;
  664. this.PickUnit(unit);
  665. }
  666. }
  667. protected virtual void doChat(ChatAction chat)
  668. {
  669. ChatEvent send = new ChatEvent(chat.To);
  670. send.FromPlayerUUID = this.PlayerUUID;
  671. send.Message = chat.Message;
  672. switch (chat.To)
  673. {
  674. case ChatMessageType.PlayerToPlayer:
  675. InstancePlayer target = Parent.getPlayerByUUID(chat.TargetPlayerUUID);
  676. if (target != null)
  677. {
  678. send.ToPlayerUUID = target.PlayerUUID;
  679. Parent.queueEvent(send);
  680. }
  681. break;
  682. case ChatMessageType.PlayerToForce:
  683. send.Force = this.Force;
  684. Parent.queueEvent(send);
  685. break;
  686. case ChatMessageType.PlayerToAll:
  687. Parent.queueEvent(send);
  688. break;
  689. }
  690. }
  691. protected virtual void doUnitUpdatePos(UnitUpdatePosAction act)
  692. {
  693. //Console.WriteLine("-------------------UnitUpdatePosAction : " + TimeUtil.GetTimestampMS() + ", " + act.x + ", " + act.y + " \t \t" + act.d);
  694. if (mCurrentSyncMode == ZoneClient.SyncMode.MoveByClient_PreSkillByClient && !this.IsCannotMove)
  695. {
  696. //mWaitingSkill = null;
  697. mUpdateMove.SetPos(act);
  698. if (CurrentState is StateSkill)
  699. {
  700. var ss = CurrentState as StateSkill;
  701. ss.doUpdatePosByClient(act);
  702. //服务器判断下,蓄力阶段才同步客户端蓄力状态
  703. if (ss.CurrentActionIndex < ss.SkillData.ActionQueue.Count &&
  704. ss.SkillData.ActionQueue[ss.CurrentActionIndex].SigleActionType == ActionEnum.chargeAtk)
  705. {
  706. if (act.st == UnitActionStatus.ChargeAtkMove)
  707. {
  708. this.RemoveActionSubState(UnitActionSubStatus.ChargeAtkIdle);
  709. this.AddActionSubState(UnitActionSubStatus.ChargeAtkMove);
  710. }
  711. else if (act.st == UnitActionStatus.ChargeAtkIdle)
  712. {
  713. this.RemoveActionSubState(UnitActionSubStatus.ChargeAtkMove);
  714. this.AddActionSubState(UnitActionSubStatus.ChargeAtkIdle);
  715. }
  716. }
  717. }
  718. else if (CurrentState is StatePickObject)
  719. {
  720. if (act.st == UnitActionStatus.Move)
  721. {
  722. this.faceTo(act.d);
  723. this.setPos(act.x, act.y, this.IntersectMap);
  724. changeState(mUpdateMove);
  725. }
  726. }
  727. else if (CurrentState is StateDamage || CurrentState is StateDead || CurrentState is IStateNoneControllable)
  728. {
  729. }
  730. else if (CurrentActionStatus == UnitActionStatus.DaZuo || CurrentActionStatus == UnitActionStatus.DaZuoRecoveryAttr ||
  731. CurrentActionStatus == UnitActionStatus.Idle || CurrentActionStatus == UnitActionStatus.Move)
  732. {
  733. //changestate在帧中切换状态,这里提前判断下一个动作能否转向
  734. bool canChangeDircetion = true;
  735. StateSkill nextSkill = this.NextState as StateSkill;
  736. if (nextSkill != null && nextSkill.Skill != null)
  737. {
  738. UnitActionData action = nextSkill.Skill.GetCurAction();
  739. if(action != null && !action.IsControlFaceable)
  740. {
  741. canChangeDircetion = false;
  742. }
  743. }
  744. if (canChangeDircetion)
  745. {
  746. this.faceTo(act.d);
  747. }
  748. this.setPos(act.x, act.y, this.IntersectMap);
  749. if (act.st == UnitActionStatus.Idle)
  750. {
  751. doSomething();
  752. }
  753. else if (act.st == UnitActionStatus.Move)
  754. {
  755. changeState(mUpdateMove);
  756. }
  757. //Console.WriteLine("st=" + act.d);
  758. }
  759. }
  760. }
  761. protected virtual void doGuard(UnitGuardAction act)
  762. {
  763. if (this.IsGuard != act.guard)
  764. {
  765. var IsInCancelingGuard = this.IsGuard;
  766. this.IsGuard = act.guard;
  767. this.mIsSkillControlByServer = IsGuard || (mCurrentSyncMode != ZoneClient.SyncMode.MoveByClient_PreSkillByClient);
  768. if (IsGuard == false)
  769. {
  770. mAttackTo = null;
  771. cleanFocus();
  772. }
  773. else
  774. {
  775. mCheckGuard.Reset();
  776. }
  777. resetAI();
  778. if (NextState == null && IsInCancelingGuard && CurrentState is StateSkill)
  779. {
  780. TryEnqueueIdleState();
  781. }
  782. //通知待机状态\
  783. //if (act.forceNotify)
  784. {
  785. this.Virtual.doEvent(JSGCustomOpType.UpdateAutoBattleFlag);
  786. }
  787. }
  788. }
  789. public virtual void doEnterAutoFight()
  790. {
  791. this.IsGuard = true;
  792. }
  793. protected virtual void doFollow(UnitFollowAction act)
  794. {
  795. this.mIsSkillControlByServer = act.follow || (mCurrentSyncMode != ZoneClient.SyncMode.MoveByClient_PreSkillByClient);
  796. //this.mIsSkillControlByServer = (mCurrentSyncMode != ZoneClient.SyncMode.MoveByClient_PreSkillByClient);
  797. }
  798. protected virtual void doSetSyncMode(UnitSetSyncModeAction act)
  799. {
  800. this.mCurrentSyncMode = act.Mode;
  801. this.mIsSkillControlByServer = IsGuard || (mCurrentSyncMode != ZoneClient.SyncMode.MoveByClient_PreSkillByClient);
  802. }
  803. protected virtual void doCancelBuff(UnitCancelBuffAction act)
  804. {
  805. BuffState bs = this.GetBuffByID(act.BuffID);
  806. if (bs != null && bs.Data.IsCancelBySelf)
  807. {
  808. this.removeBuff(act.BuffID, BuffState.EndResult_ByClientRemoved);
  809. }
  810. }
  811. protected virtual void doUnitSetSubStateAction(UnitSetSubStateAction act)
  812. {
  813. base.AddActionSubState((UnitActionSubStatus)(act.UnitSubState));
  814. }
  815. protected virtual void doPetTeleportAction(PlayPetTeleportAction act)
  816. {
  817. InstanceUnit petUnit = this.Virtual.GetPetUnit();
  818. if (petUnit != null)
  819. {
  820. if (petUnit.petTeleportTime < CommonLang.CUtils.CurrentTimeMS)
  821. {
  822. petUnit.petTeleportTime = CommonLang.CUtils.CurrentTimeMS+10*1000;
  823. petUnit.lastTeleportTime = CommonLang.CUtils.CurrentTimeMS+3*1000; //3秒之后开始返回
  824. //获取玩家当前坐标
  825. float x = this.get_x();
  826. float y = this.get_y();
  827. petUnit.setPos(this.get_x(), this.get_y(), this.IntersectMap);
  828. petUnit.faceTo(this.get_direction());
  829. State s = new PetLockState(petUnit);
  830. petUnit.changeState(s);
  831. }
  832. else
  833. {
  834. if (petUnit.lastTeleportTime < CommonLang.CUtils.CurrentTimeMS)
  835. {
  836. petUnit.lastTeleportTime = CommonLang.CUtils.CurrentTimeMS+3*1000; //3秒之后开始返回
  837. this.Virtual.SendMsgToClient(CommonAI.XmdsConstConfig.TIPS_CALL_BACK_BTN);
  838. }
  839. }
  840. }
  841. }
  842. #endregion
  843. // --------------------------------------------------------------------------------------
  844. #region PlayerQuests
  845. public virtual void InitQuestData(ICollection<QuestData> datas)
  846. {
  847. foreach (QuestData q in datas)
  848. {
  849. if (q.QuestID != null)
  850. {
  851. mQuests.Put(q.QuestID, q);
  852. }
  853. }
  854. }
  855. internal QuestData doQuestAccepted(string quest)
  856. {
  857. if (!string.IsNullOrEmpty(quest))
  858. {
  859. QuestData qd = new QuestData(quest);
  860. qd.State = QuestState.Accepted;
  861. mQuests.Put(quest, qd);
  862. return qd;
  863. }
  864. return null;
  865. }
  866. internal QuestData doQuestCommitted(string quest)
  867. {
  868. QuestData qd = mQuests.RemoveByKey(quest);
  869. if (qd != null)
  870. {
  871. qd.State = QuestState.Commited;
  872. onQuestCommitted(qd);
  873. }
  874. return qd;
  875. }
  876. /// <summary>
  877. /// 当任务完成时,子类覆盖的方法被调用
  878. /// </summary>
  879. /// <param name="qd"></param>
  880. protected virtual void onQuestCommitted(QuestData qd) { }
  881. internal QuestData doQuestDropped(string quest)
  882. {
  883. QuestData qd = mQuests.RemoveByKey(quest);
  884. if (qd != null)
  885. {
  886. qd.State = QuestState.Uncharted;
  887. }
  888. return qd;
  889. }
  890. internal QuestData doQuestStatusChanged(string quest, string key, string value)
  891. {
  892. QuestData qd = mQuests.Get(quest);
  893. if (qd != null)
  894. {
  895. qd.Attributes.Put(key, value);
  896. }
  897. return qd;
  898. }
  899. public virtual bool IsQuestAccepted(string quest)
  900. {
  901. QuestData qd = mQuests.Get(quest);
  902. if (qd != null)
  903. {
  904. string ret;
  905. if (qd.Attributes.TryGetValue("state", out ret))
  906. {
  907. return ret == "0";
  908. }
  909. return qd.State == QuestState.Accepted;
  910. }
  911. return false;
  912. }
  913. public virtual string GetQuestStatus(string quest, string key)
  914. {
  915. QuestData qd = mQuests.Get(quest);
  916. if (qd != null)
  917. {
  918. string value;
  919. if (qd.Attributes.TryGetValue(key, out value))
  920. {
  921. return value;
  922. }
  923. }
  924. return null;
  925. }
  926. public virtual QuestData GetQuest(string quest)
  927. {
  928. return mQuests.Get(quest);
  929. }
  930. #endregion
  931. //--------------------------------------------------------------------------------------
  932. /// <summary>
  933. /// 更新坐标移动状态
  934. /// </summary>
  935. public class StatePlayerUpdateMove : State
  936. {
  937. private UnitUpdatePosAction act;
  938. public bool IsPosChanged
  939. {
  940. get
  941. {
  942. if (act != null)
  943. {
  944. return act.x != unit.X || act.y != unit.Y;
  945. }
  946. return false;
  947. }
  948. }
  949. public StatePlayerUpdateMove(InstancePlayer unit)
  950. : base(unit)
  951. {
  952. }
  953. public void SetPos(UnitUpdatePosAction act)
  954. {
  955. // TODO 检测作弊
  956. this.act = act;
  957. }
  958. public override bool onBlock(State new_state)
  959. {
  960. return true;
  961. }
  962. protected override void onStart()
  963. {
  964. unit.SetActionStatus(UnitActionStatus.Move);
  965. }
  966. protected override void onUpdate()
  967. {
  968. unit.SetActionStatus(UnitActionStatus.Move);
  969. }
  970. protected override void onStop()
  971. {
  972. }
  973. }
  974. //--------------------------------------------------------------------------------------
  975. /// <summary>
  976. /// 摇杆控制移动状态
  977. /// </summary>
  978. protected class StatePlayerControlMove : State
  979. {
  980. private float mDirection;
  981. private UnitAxisAction mAction;
  982. public UnitAxisAction Action
  983. {
  984. get { return mAction; }
  985. set
  986. {
  987. mAction = value;
  988. mDirection = MathVector.getDegree(value.dx, value.dy);
  989. }
  990. }
  991. public float Direction
  992. {
  993. get { return mDirection; }
  994. }
  995. public StatePlayerControlMove(InstancePlayer unit)
  996. : base(unit)
  997. {
  998. }
  999. public override bool onBlock(State new_state)
  1000. {
  1001. return true;
  1002. }
  1003. protected override void onStart()
  1004. {
  1005. unit.SetActionStatus(UnitActionStatus.Move);
  1006. }
  1007. protected override void onUpdate()
  1008. {
  1009. unit.faceTo(mDirection);
  1010. unit.moveBlockTo(unit.Direction, unit.MoveSpeedSEC, zone.UpdateIntervalMS);
  1011. unit.SetActionStatus(UnitActionStatus.Move);
  1012. }
  1013. protected override void onStop()
  1014. {
  1015. }
  1016. }
  1017. //--------------------------------------------------------------------------------------
  1018. protected class StatePlayerAttackTo : State
  1019. {
  1020. private TargetPos target;
  1021. private MoveAI moveAI;
  1022. private bool is_attack;
  1023. public bool IsAttack { get { return is_attack; } }
  1024. public bool IsDone { get { return target == null; } }
  1025. public StatePlayerAttackTo(InstancePlayer unit, float tx, float ty, bool attack)
  1026. : base(unit)
  1027. {
  1028. this.target = new TargetPos(tx, ty);
  1029. this.is_attack = attack;
  1030. }
  1031. public override bool onBlock(State new_state)
  1032. {
  1033. return true;
  1034. }
  1035. override protected void onStart()
  1036. {
  1037. this.moveAI = new MoveAI(unit, true, 0);
  1038. this.moveAI.IsNoWayAutoFindNear = false; ;
  1039. if (target != null)
  1040. {
  1041. this.moveAI.FindPath(target);
  1042. unit.SetActionStatus(UnitActionStatus.Move);
  1043. }
  1044. else
  1045. {
  1046. unit.SetActionStatus(UnitActionStatus.Idle);
  1047. }
  1048. }
  1049. override protected void onUpdate()
  1050. {
  1051. if (target == null)
  1052. {
  1053. unit.doSomething();
  1054. }
  1055. else
  1056. {
  1057. var result = this.moveAI.Update();
  1058. if (result.HasFlag(MoveResult.MOVE_RESULT_ARRIVED))
  1059. {
  1060. do_stop();
  1061. }
  1062. else if (result.HasFlag(MoveResult.MOVE_RESULT_MIN_STEP) && result.HasFlag(MoveResult.MOVE_RESULT_NO_WAY))
  1063. {
  1064. do_stop();
  1065. }
  1066. else if (result.HasFlag(MoveResult.MOVE_RESULT_BLOCK_OBJ))
  1067. {
  1068. if (CMath.includeRoundPoint(unit.X, unit.Y, unit.BodyBlockSize, target.X, target.Y))
  1069. {
  1070. do_stop();
  1071. }
  1072. else if (result.obj != null && CMath.includeRoundPoint(result.obj.X, result.obj.Y, result.obj.BodyBlockSize, target.X, target.Y))
  1073. {
  1074. do_stop();
  1075. }
  1076. }
  1077. }
  1078. }
  1079. protected override void onStop()
  1080. {
  1081. }
  1082. private void do_stop()
  1083. {
  1084. target = null;
  1085. unit.doSomething();
  1086. }
  1087. class TargetPos : IPositionObject
  1088. {
  1089. public float Direction { get; set; }
  1090. public float RadiusSize { get; set; }
  1091. public float X { get; set; }
  1092. public float Y { get; set; }
  1093. public TargetPos(float tx, float ty)
  1094. {
  1095. this.X = tx;
  1096. this.Y = ty;
  1097. }
  1098. }
  1099. }
  1100. }
  1101. }