XmdsInstancePlayer.cs 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088
  1. #define OPNE_JSG_AI_TOOLS
  2. using CommonAI.Zone;
  3. using CommonAI.Zone.Helper;
  4. using CommonAI.Zone.Instance;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Linq;
  8. using System.Text;
  9. using XmdsCommon.Plugin;
  10. using CommonAI.Zone.Formula;
  11. using XmdsCommon.Message;
  12. using CommonLang;
  13. using XmdsCommonServer.Message;
  14. using CommonLang.Vector;
  15. using XmdsCommon.EditorData;
  16. using CommonAI.Zone.ZoneEditor;
  17. using CommonLang.Concurrent;
  18. using static CommonAI.Zone.Instance.InstanceUnit;
  19. using XmdsCommon.ZoneClient.XmdsClientVirtual;
  20. using XmdsCommonServer.Plugin.Scene;
  21. using static CommonAI.XmdsConstConfig;
  22. using System.Collections;
  23. using CommonLang.Log;
  24. using CommonAI.Data;
  25. using static XmdsCommonServer.Plugin.Units.XmdsInstanceUnitStateMachine;
  26. using CommonAI;
  27. namespace XmdsCommonServer.Plugin.Units
  28. {
  29. public class XmdsInstancePlayer : InstancePlayer
  30. {
  31. public enum GuardMode
  32. {
  33. Mode_Point,
  34. Mode_Map,
  35. }
  36. private static HashMap<int, AtomicInteger> CreateInfoMap = new HashMap<int, AtomicInteger>();
  37. //嘲讽状态
  38. protected XmdsInstanceUnitStateMock mMockTarget;
  39. //private TimeInterval<int> mFindItemTimeInterval;
  40. private long mNextAutoFindPickItemTime;
  41. private GuardMode mCurGuardMode = GuardMode.Mode_Point;
  42. private Vector2 mGuardPos = new Vector2();
  43. private bool mDoStopSkill = false;
  44. private static int DEFAULT_CROSS_SERVER_ID = -999;
  45. private const char SPLIT = ':';
  46. private List<int> mAutoGuardTargetList = new List<int>();
  47. private int mAutoGuardTargetTimes = 0;
  48. private const int MAX_AUTO_GUARD_TARGET_TIMES = 500;
  49. private bool mIsReady = false;
  50. private XmdsInstanceUnitStateMachine.XmdsStateFollowAndAttack mXmdsFocusTarget;
  51. private bool mBotTestAutoFight = false;
  52. private int zoneID;
  53. //解决部分情况下未上发(或者上发时机不对)idle,导致别人看到自己在move,唯独自己看到自己是正常的
  54. private int mNotMoveTimes;
  55. private Vector2 mLastMovePos = new Vector2();
  56. //定点自动战斗情况下,玩家不能像怪物一样回原地,所以需要定时检测一下,重置定点的位置
  57. private long mLastAutoAttackTime = 0;
  58. //private Vector2 mLastAutoFightPos = new Vector2();
  59. //下一次通知背包已满时间
  60. //private long mNextNotifyBagFullTime = 0;
  61. public XmdsInstancePlayer(InstanceZone zone, UnitInfo info, string name, int force, int alliesForce, int level)
  62. : base(zone, info, name, force, level, alliesForce)
  63. {
  64. //mFindItemTimeInterval = new TimeInterval<int>(XmdsConfig.Instance.GUARD_FIND_ITEM_CYCLE_TIME);
  65. mCheckGuard.FirstTimeEnable = true;
  66. if (TemplateManager.IsEditor)
  67. {
  68. mIsReady = true;
  69. mBotTestAutoFight = true;
  70. }
  71. else if ((Info.Properties as XmdsUnitProperties).BotTestTemplate)
  72. {
  73. mIsReady = true;
  74. }
  75. OnPlayerCreate();
  76. this.OnHandleAction += OnActionHandle;
  77. }
  78. public override void doEnterAutoFight()
  79. {
  80. base.doEnterAutoFight();
  81. this.IsGuard = true;
  82. this.mGuardPos.SetX(this.X);
  83. this.mGuardPos.SetY(this.Y);
  84. }
  85. static void OnActionHandle(InstanceUnit unit, ObjectAction act)
  86. {
  87. if (act is PlayerDramaEndAction && unit.AoiStatus != null)
  88. {
  89. var dramaId = (act as PlayerDramaEndAction).dramaId;
  90. if (unit.AoiStatus is XmdsPlayerAOI)
  91. {
  92. if ((unit.AoiStatus as XmdsPlayerAOI).QuestId == dramaId)
  93. {
  94. unit.setAoiStatus(null);
  95. }
  96. return;
  97. }
  98. if (unit.AoiStatus is DarmaAOI)
  99. {
  100. if ((unit.AoiStatus as DarmaAOI).darmaId == dramaId)
  101. {
  102. unit.setAoiStatus(null);
  103. }
  104. return;
  105. }
  106. }
  107. }
  108. private void clearAutoGuardTargetList()
  109. {
  110. if (mAutoGuardTargetList != null)
  111. {
  112. mAutoGuardTargetList.Clear();
  113. }
  114. mAutoGuardTargetTimes = 0;
  115. }
  116. protected override void Disposing()
  117. {
  118. foreach (var item in mQuestScript)
  119. {
  120. item.Value.Dispose();
  121. }
  122. clearAutoGuardTargetList();
  123. mXmdsFocusTarget = null;
  124. lastAttackUnit = null;
  125. base.Disposing();
  126. }
  127. private System.Action readyAction;
  128. public void PlayerReady()
  129. {
  130. mIsReady = true;
  131. if (readyAction != null)
  132. {
  133. readyAction.Invoke();
  134. }
  135. }
  136. public bool IsPlayerReady()
  137. {
  138. return mIsReady;
  139. }
  140. //--------------------------------------------------------------------------------------
  141. public override bool IsVisible
  142. {
  143. get { return base.IsVisible && mIsReady; }
  144. }
  145. public override bool IsInvincible
  146. {
  147. get { return (!mIsReady || base.IsInvincible); }
  148. }
  149. public XmdsVirtual_Player VirtualPlayer
  150. {
  151. get { return base.Virtual as XmdsVirtual_Player; }
  152. }
  153. public bool CanPickDropableItem
  154. {
  155. get { return VirtualPlayer.VirtualInventorySize >= 1; }
  156. }
  157. /// <summary>
  158. /// 是否是机器人
  159. /// </summary>
  160. //public bool IsBotTest { get; private set; }
  161. //--------------------------------------------------------------------------------------
  162. #region 任务相关
  163. private HashMap<string, Quest.QuestScript> mQuestScript = new HashMap<string, Quest.QuestScript>();
  164. public Quest.QuestScript GetQuestScript(string quest_id)
  165. {
  166. return mQuestScript.Get(quest_id);
  167. }
  168. public IList<Quest.QuestScript> GetAllQuestScript()
  169. {
  170. return new List<Quest.QuestScript>(mQuestScript.Values);
  171. }
  172. public void SetQuestScript(string quest_id, int questType, Quest.QuestScript script)
  173. {
  174. if (mQuestScript.ContainsKey(quest_id))
  175. {
  176. XmdsVirtual.FormatLog(CommonLang.Log.LoggerLevel.ERROR, "SetQuestScript Error : ContainsKey" + quest_id);
  177. RemoveQuestScript(quest_id);
  178. }
  179. mQuestScript.Add(quest_id, script);
  180. script.Init(quest_id, questType, this);
  181. script.Start();
  182. }
  183. public void RemoveQuestScript(string quest_id)
  184. {
  185. Quest.QuestScript qs = mQuestScript.Get(quest_id);
  186. if (qs != null)
  187. {
  188. qs.Dispose();
  189. mQuestScript.Remove(quest_id);
  190. }
  191. }
  192. public List<CommonAI.Zone.Helper.QuestData> GetQuests()
  193. {
  194. return new List<CommonAI.Zone.Helper.QuestData>(mQuests.Values);
  195. }
  196. #endregion
  197. //--------------------------------------------------------------------------------------
  198. #region 作弊惩罚
  199. private TimeExpire<int> mLockTime;
  200. public bool IsLock { get { return mLockTime != null; } }
  201. //索敌范围.
  202. private int mGuardSearchRange = XmdsConfig.Instance.NORMALSCENE_AUTO_GUARD_RANGE;
  203. private int mGuardSearchRangeExt = XmdsConfig.Instance.NORMALSCENE_AUTO_GUARD_RANGE * XmdsConfig.Instance.NORMALSCENE_AUTO_GUARD_RANGE;
  204. /// <summary>
  205. /// 设置自动战斗索敌范围.
  206. /// </summary>
  207. /// <param name="v"></param>
  208. public void SetGuardSearchRange(int v)
  209. {
  210. mGuardSearchRange = v;
  211. mGuardSearchRangeExt = mGuardSearchRange * mGuardSearchRange;
  212. }
  213. /// <summary>
  214. /// 检测到作弊,禁止一切操作一段时间
  215. /// </summary>
  216. /// <param name="timeMS"></param>
  217. public void Lock(int timeMS)
  218. {
  219. this.startIdle();
  220. if (mLockTime != null && mLockTime.ExpireTimeMS >= timeMS)
  221. {
  222. return;
  223. }
  224. else
  225. {
  226. mLockTime = new TimeExpire<int>(timeMS);
  227. }
  228. }
  229. private void upateLock()
  230. {
  231. if (mLockTime != null && mLockTime.Update(Parent.UpdateIntervalMS))
  232. {
  233. mLockTime = null;
  234. }
  235. }
  236. #endregion
  237. //--------------------------------------------------------------------------------------
  238. #region BUFF特殊状态锁定移动.
  239. private TimeExpire<int> mBuffLockMoveTime;
  240. public bool IsBuffLockMove { get { return mBuffLockMoveTime != null; } }
  241. public void BuffMoveLock(int timeMS)
  242. {
  243. this.startIdle();
  244. if (mBuffLockMoveTime != null && mBuffLockMoveTime.ExpireTimeMS >= timeMS)
  245. {
  246. return;
  247. }
  248. else
  249. {
  250. mBuffLockMoveTime = new TimeExpire<int>(timeMS);
  251. }
  252. }
  253. private void UpdateBuffMoveLock()
  254. {
  255. if (mBuffLockMoveTime != null && mBuffLockMoveTime.Update(Parent.UpdateIntervalMS))
  256. {
  257. mBuffLockMoveTime = null;
  258. }
  259. }
  260. #endregion
  261. //--------------------------------------------------------------------------------------
  262. protected override void onUpdate(bool slowRefresh)
  263. {
  264. base.onUpdate(slowRefresh);
  265. this.upateLock();
  266. this.UpdateBuffMoveLock();
  267. this.UpdateDoStopSkill();
  268. this.updateFollowTeam();
  269. this.UpdateAndModifyErrorData();
  270. }
  271. //--------------------------------------------------------------------------------------
  272. protected override void onAction(ObjectAction act)
  273. {
  274. if (IsLock) return;
  275. if (act is UnitAxisAction || act is UnitMoveAction)
  276. {
  277. //BUFF锁定客户端移动.
  278. if (IsBuffLockMove == true)
  279. {
  280. return;
  281. }
  282. }
  283. base.onAction(act);
  284. if (this.IsDead() == true)
  285. {
  286. //单位遗言更改.
  287. if (act is PlayerTestamentChangeEventAction)
  288. {
  289. PlayerTestamentChangeEventAction evt = act as PlayerTestamentChangeEventAction;
  290. ChangeTestament(evt.TestamentID);
  291. }
  292. }
  293. //自动战斗状态变更通知.
  294. if (act is PlayerAutoGuardEventC2B)
  295. {
  296. var evt = act as PlayerAutoGuardEventC2B;
  297. if (evt.Flag == false)
  298. {
  299. if (this.CurrentState is StateSkill)
  300. {
  301. mDoStopSkill = true;
  302. }
  303. }
  304. return;
  305. }
  306. else if (act is PlayerEnterCrossServerRequestC2B)
  307. {
  308. //战斗服判断单位是否在PVPV状态,如果不是发送切换场景请求.
  309. if ((this.Virtual as XmdsVirtual).CombatState != BattleStatus.PVP)
  310. {
  311. //发送协议.
  312. TransUnitEventB2R evt = new TransUnitEventB2R();
  313. //约定跨服场景ID.
  314. evt.SceneID = DEFAULT_CROSS_SERVER_ID;
  315. evt.playerId = this.PlayerUUID;
  316. evt.TargetX = 0;
  317. evt.TargetY = 0;
  318. this.queueEvent(evt);
  319. }
  320. else
  321. {
  322. (this.Virtual as XmdsVirtual).SendMsgToClient(CommonAI.XmdsConstConfig.TIPS_CAN_NOT_ENTER_SCENE);
  323. }
  324. }
  325. else if (act is GetMonsterSufferDamageInfoC2B)
  326. {
  327. var ret = act as GetMonsterSufferDamageInfoC2B;
  328. OnReceiveGetMonsterSufferDamageInfoC2B(ret);
  329. }
  330. foreach (var q in mQuestScript)
  331. {
  332. if (q.Value.TryDoAction(act))
  333. {
  334. break;
  335. }
  336. }
  337. }
  338. protected override bool doLaunchSkill(UnitLaunchSkillAction sk)
  339. {
  340. //Console.WriteLine(" ------------------------------doLaunchSkill - " + sk.SkillID + ", " + this.ID + ", targetID: " +
  341. // sk.TargetObjID + ", XY:" + this.X + ", " + this.Y + ", direction : " + this.Direction + ", " + this.Parent.UUID);
  342. //if(sk.SkillID == 110160)
  343. // sk.SkillID = 110360;
  344. //如果在采集中,不让放技能,并通知客户端.
  345. if (CurrentActionStatus == UnitActionStatus.Pick)
  346. {
  347. this.VirtualPlayer.SendMsgToClient(CommonAI.XmdsConstConfig.TIPS_BE_BUSY);
  348. return false;
  349. }
  350. var skill = this.getSkillState(sk.SkillID);
  351. if (skill == null)
  352. {
  353. return false;
  354. }
  355. return base.doLaunchSkill(sk);
  356. }
  357. public bool PlayerChangeSkill(int oldSkillID, int newSkillID, SkillLevelData levelData)
  358. {
  359. return this.Virtual.ChangeSkill(oldSkillID, newSkillID, levelData);
  360. }
  361. // 获取队伍的天命属性加成
  362. public override int GetTeamFateValue(UnitFateType fateType)
  363. {
  364. if(this.TeamVirtual == null)
  365. {
  366. return this.Virtual.GetPetTalentAddition(fateType);
  367. }
  368. return this.TeamVirtual.GetTeamFateValue(fateType);
  369. }
  370. //查找自动拾取的物品
  371. public override InstanceItem findGuardPickItem()
  372. {
  373. if (CanPickDropableItem)
  374. {
  375. return base.findGuardPickItem();
  376. }
  377. return null;
  378. }
  379. //查找自动战斗等一切情况下的物品拾取
  380. public InstanceItem findAutoGuardPickItem()
  381. {
  382. if (CanPickDropableItem)
  383. {
  384. InstanceItem min = null;
  385. //float min_len = float.MaxValue;
  386. Parent.ForEachNearObjects(this.X, this.Y, this.mAutoPickRange, (InstanceItem u, ref bool cancel) =>
  387. {
  388. if (!u.Info.Pickable && u.IsPickable(this))
  389. {
  390. //float len = MathVector.getDistanceSquare(u.X, u.Y, this.X, this.Y);
  391. //if (min_len > len && len <= searchValue)
  392. //{
  393. // min_len = len;
  394. // min = u;
  395. //}
  396. min = u;
  397. cancel = true;
  398. }
  399. });
  400. return min;
  401. }
  402. return null;
  403. }
  404. protected override void doPickObject(UnitPickObjectAction pick)
  405. {
  406. InstanceZoneObject obj = Parent.getObject<InstanceZoneObject>(pick.PickableObjectID);
  407. if (obj is InstanceItem)
  408. {
  409. InstanceItem item = obj as InstanceItem;
  410. var zip = (item.Info.Properties as XmdsItemProperties);
  411. switch (zip.ItemType)
  412. {
  413. case XmdsItemProperties.XmdsItemType.Equip:
  414. //if (CanPickDropableItem) XmdsDropableInstanceItem.IsPickable已经检查
  415. {
  416. item.DirectPickItem(this, () =>
  417. {
  418. RemoveDropItemB2C rd = new RemoveDropItemB2C(item.ID, this.ID);
  419. this.queueEvent(rd);
  420. });
  421. }
  422. break;
  423. default:
  424. {
  425. if (item.PickItem(this) && item.mFrom == 1)
  426. {
  427. RemoveDropItemB2C rd = new RemoveDropItemB2C(item.ID, this.ID);
  428. this.queueEvent(rd);
  429. }
  430. }
  431. break;
  432. }
  433. }
  434. else if (obj is InstanceUnit)
  435. {
  436. InstanceUnit unit = obj as InstanceUnit;
  437. this.PickUnit(unit);
  438. }
  439. }
  440. protected void TryDirectPickNearItems()
  441. {
  442. int size = this.VirtualPlayer.VirtualInventorySize;
  443. if (size == 0) { return; }
  444. Parent.ForEachNearObjects(this.X, this.Y, this.mAutoPickRange, (InstanceItem u, ref bool cancel) =>
  445. {
  446. if (size > 0)
  447. {
  448. var itemProp = u.Info.Properties as XmdsItemProperties;
  449. if (itemProp.AllowAutoGuardPick == true && u.PassTimeMS > 1000)
  450. {
  451. //自己可以捡的装备再扣除背包数量.
  452. if (u.DirectPickItem(this, () =>
  453. {
  454. RemoveDropItemB2C rd = new RemoveDropItemB2C(u.ID, this.ID);
  455. this.queueEvent(rd);
  456. }))
  457. {
  458. size--;
  459. }
  460. }
  461. }
  462. else
  463. {
  464. cancel = true;
  465. }
  466. });
  467. //this.VirtualPlayer.VirtualInventorySize = size;
  468. }
  469. public void setMocking(InstanceUnit unit)
  470. {
  471. if(unit == null)
  472. {
  473. if(mMockTarget != null)
  474. {
  475. mMockTarget.mMarkRemove = true;
  476. }
  477. mMockTarget = null;
  478. }
  479. else
  480. {
  481. mMockTarget = new XmdsInstanceUnitStateMock(this, unit);
  482. DoMockingAttack();
  483. }
  484. }
  485. protected override void updateGuard()
  486. {
  487. if (mMockTarget != null)
  488. {
  489. DoMockingAttack();
  490. }
  491. else if(this.mFocusPickItem != null && this.mFocusPickItem.IsActive)
  492. {
  493. if (this.mFocusPickItem.IsBlock())
  494. {
  495. this.mFocusPickItem = null;
  496. }
  497. else
  498. {
  499. return;
  500. }
  501. }
  502. else if (IsGuard == true && (mXmdsFocusTarget == null || (mXmdsFocusTarget != null && !mXmdsFocusTarget.IsActive)))
  503. {
  504. mXmdsFocusTarget = null;
  505. InstanceUnit enemy = null;
  506. if (lastAttackUnit != null && lastAttackUnit.IsActive == true)//上一次攻击的单位如果没死且能攻击,继续攻击他.
  507. {
  508. //上次攻击的单位如果超过了一屏范围,取消攻击.
  509. //if (CMath.getDistance(this.X, this.Y, lastAttackUnit.X, lastAttackUnit.Y) > this.mGuardSearchRange)
  510. //{
  511. // lastAttackUnit = null;
  512. //}
  513. //else
  514. {
  515. enemy = lastAttackUnit;
  516. }
  517. }
  518. else
  519. {
  520. lastAttackUnit = null;
  521. }
  522. if (enemy == null)//如果无效再找一次.
  523. {
  524. enemy = findGuardTarget(SkillTemplate.CastTarget.Enemy, AttackReason.Look);
  525. }
  526. if (enemy != null)
  527. {
  528. doXmdsFocusAttack(enemy, SkillTemplate.CastTarget.Enemy);
  529. return;
  530. }
  531. //UpdateXmdsGuard();
  532. }
  533. //自动拾取检测
  534. if(this.DoAutoPick())
  535. {
  536. return;
  537. }
  538. if (mFocusPickItem != null && !mFocusPickItem.IsActive)
  539. {
  540. mFocusPickItem = null;
  541. }
  542. //if (mFindItemTimeInterval.Update(Parent.UpdateIntervalMS))
  543. // {
  544. // TryDirectPickNearItems();
  545. //}
  546. if (IsGuard)
  547. {
  548. // 旋风斩贴近目标 //
  549. if (CurrentState is StateSkill state)
  550. {
  551. Vector2 movePos = (mXmdsFocusTarget == null) ? state.GetMoveToPos() : new Vector2(mXmdsFocusTarget.Target.X, mXmdsFocusTarget.Target.Y);
  552. if (movePos != null && state.IsControlMoveable && !state.unit.IsCannotMove && state.SkillData.AutoFightFollower)
  553. {
  554. if(state.setMoveTo(movePos.X, movePos.Y))
  555. {
  556. // 移动结束
  557. if((this.CurrentActionSubstate & (byte)UnitActionSubStatus.ChargeAtkMove) > 0)
  558. {
  559. this.RemoveActionSubState(UnitActionSubStatus.ChargeAtkMove);
  560. this.AddActionSubState(UnitActionSubStatus.ChargeAtkIdle);
  561. }
  562. }
  563. else
  564. {
  565. // 移动
  566. if ((this.CurrentActionSubstate & (byte)UnitActionSubStatus.ChargeAtkIdle) > 0)
  567. {
  568. this.RemoveActionSubState(UnitActionSubStatus.ChargeAtkIdle);
  569. this.AddActionSubState(UnitActionSubStatus.ChargeAtkMove);
  570. }
  571. }
  572. return;
  573. }
  574. }
  575. // 没目标定期检测目标 //
  576. if ((mXmdsFocusTarget == null) && (mFocusPickItem == null))
  577. {
  578. if (mCheckGuard.Update(Parent.UpdateIntervalMS))
  579. {
  580. var enemy = findGuardTarget(SkillTemplate.CastTarget.Enemy, AttackReason.Look);
  581. if (enemy != null)
  582. {
  583. doXmdsFocusAttack(enemy, SkillTemplate.CastTarget.Enemy);
  584. return;
  585. }
  586. var alias = findGuardTarget(SkillTemplate.CastTarget.AlliesIncludeSelf, AttackReason.Look);
  587. if (alias != null)
  588. {
  589. doXmdsFocusAttack(alias, SkillTemplate.CastTarget.AlliesIncludeSelf);
  590. return;
  591. }
  592. //if (CommonLang.CUtils.localTimeMS - this.mLastAutoAttackTime > 3000/* && this.X == this.mLastAutoFightPos.X && this.Y == this.mLastAutoFightPos.Y*/)
  593. //{
  594. // this.mLastAutoAttackTime = CommonLang.CUtils.localTimeMS;
  595. // this.mGuardPos.SetX(this.X);
  596. // this.mGuardPos.SetY(this.Y);
  597. //}
  598. }
  599. }
  600. }
  601. }
  602. //是否可以自动拾取
  603. public override bool DoAutoPick(bool ignoreInterval = false)
  604. {
  605. //非自动战斗或者非跟随,退出
  606. if (!this.IsGuard && (this.leadingMan == null || (this.leadingMan != null && !this.canFollowTeam)))
  607. {
  608. return false;
  609. }
  610. if(this.VirtualPlayer.VirtualInventorySize <= 0)
  611. {
  612. //只要自动战斗就提示这个,不合理,客户端自己加
  613. //if(mNextNotifyBagFullTime < CommonLang.CUtils.localTimeMS)
  614. //{
  615. // mNextNotifyBagFullTime = CommonLang.CUtils.localTimeMS + 6000;
  616. // this.Virtual.SendMsgToClient(CommonAI.XmdsConstConfig.TIPS_BAG_FULL);
  617. //}
  618. return false;
  619. }
  620. if (!this.Parent.CheckAutoDropItem() || !IsBattleCanPick())
  621. {
  622. return false;
  623. }
  624. if (mFocusPickItem == null || !mFocusPickItem.IsActive || mFocusPickItem.IsBlock())
  625. {
  626. bool leaderInView = false;
  627. if (this.mTeamVirtual != null && this.canFollowTeam && this.leadingMan != null && this.leadingMan.Enable)
  628. {
  629. // 如果正在跟随图中,取消拾取
  630. if(this.CurrentState is StateFollowLeader)
  631. {
  632. StateFollowLeader folloLeader = this.CurrentState as StateFollowLeader;
  633. if(folloLeader != null && folloLeader.FollowState == StateFollow.MoveState.Move)
  634. {
  635. return false;
  636. }
  637. }
  638. if (!CMath.includeRoundPoint(X, Y, this.mAutoPickRange, leadingMan.X, leadingMan.Y))
  639. {
  640. return false;
  641. }
  642. else
  643. {
  644. leaderInView = true;
  645. }
  646. }
  647. bool canAutoPick = IsGuard || this.CurrentState is StateFollowAndPickItem || leaderInView;
  648. if (canAutoPick && (ignoreInterval || mNextAutoFindPickItemTime < CommonLang.CUtils.localTimeMS))
  649. {
  650. var item = findAutoGuardPickItem();
  651. if (item != null)
  652. {
  653. mNextAutoFindPickItemTime = CommonLang.CUtils.localTimeMS + XmdsConfig.Instance.GUARD_FIND_ITEM_CYCLE_TIME;
  654. doFocusPickItem(item, false);
  655. return true;
  656. }
  657. }
  658. }
  659. else
  660. {
  661. return true;
  662. }
  663. return false;
  664. }
  665. //是否跟随队长
  666. public override bool IsFollowMaster()
  667. {
  668. if(this.leadingMan != null && this.canFollowTeam)
  669. {
  670. return true;
  671. }
  672. return false;
  673. }
  674. private bool IsBattleCanPick()
  675. {
  676. if(this.Virtual.GetBattleStatus() != BattleStatus.None)
  677. {
  678. // 不主动开战
  679. if(this.mXmdsFocusTarget != null && this.mXmdsFocusTarget.TargetUnit.IsActive && !this.mXmdsFocusTarget.TargetUnit.IsFullHP())
  680. {
  681. return false;
  682. }
  683. }
  684. return true;
  685. }
  686. //通知拾取消息
  687. public override void NotifyRemoveDropItemB2C(InstanceItem item)
  688. {
  689. RemoveDropItemB2C rd = new RemoveDropItemB2C(item.ID, this.ID);
  690. this.queueEvent(rd);
  691. }
  692. private void DoMockingAttack()
  693. {
  694. //doXmdsFocusAttack(mMockTarget.GetTargetUnit(), SkillTemplate.CastTarget.Enemy, false, this.DefaultSkillStatus());
  695. if (!(this.CurrentState is XmdsInstanceUnitStateMock) || !(this.CurrentState is StateSkill))
  696. {
  697. changeState(mMockTarget);
  698. queueEvent(new PlayerFocuseTargetEvent(this.ID, mMockTarget.GetTargetUnit().ID, SkillTemplate.CastTarget.Enemy)); ;
  699. }
  700. }
  701. public override BuffState AddBuff(BuffTemplate buff, InstanceUnit sender, int pointMaxOverLayer = 0, bool forever = false, bool bMaxOverlayer = false,
  702. int buffExt = 0, bool isControlBuf = false, bool maxReset = false, int addLayers = 0)
  703. {
  704. XmdsBuffProperties prop = buff.Properties as XmdsBuffProperties;
  705. if (prop.BuffAbilityList != null)
  706. {
  707. int count = prop.BuffAbilityList.Count;
  708. for (int i = 0; i < count; i++)
  709. {
  710. if (XmdsInstanceUtils.IsDebuff(prop.BuffAbilityList[i].ability))
  711. {
  712. isControlBuf = true;
  713. break;
  714. }
  715. }
  716. }
  717. return base.AddBuff(buff, sender, pointMaxOverLayer, forever, bMaxOverlayer, buffExt, isControlBuf, maxReset, addLayers);
  718. }
  719. protected override void doHitAttack(InstanceUnit attacker, AttackSource source)
  720. {
  721. if (this.IsDead())
  722. {
  723. //XmdsAttackProperties zap = (source.Attack.Properties as XmdsAttackProperties);
  724. if (attacker.CurrentState is StateSkill)
  725. {
  726. var skilltemplate = (attacker.CurrentState as StateSkill).SkillData;
  727. if ((skilltemplate.Properties as XmdsSkillProperties).TargetType
  728. == XmdsSkillProperties.XmdsSkillTargetType.AllianceDead)
  729. {
  730. TemplateManager.Formula.OnHit(attacker, source, this);
  731. }
  732. }
  733. }
  734. base.doHitAttack(attacker, source);
  735. }
  736. /// <summary>
  737. /// 更改遗言.
  738. /// </summary>
  739. /// <param name="testamentID"></param>
  740. private void ChangeTestament(byte testamentID)
  741. {
  742. (this.Virtual as XmdsVirtual_Player).SyncTestament(testamentID);
  743. }
  744. public override void InitSkills(LaunchSkill baseSkill, params LaunchSkill[] skills)
  745. {
  746. if (this.Virtual == null ||
  747. (this.Virtual as XmdsVirtual).IsFinishSkillInit() == false)
  748. {
  749. return;
  750. }
  751. base.InitSkills(baseSkill, skills);
  752. }
  753. public override bool tryLaunchRandomSkillAndCancelCurrentSkill(InstanceUnit target, bool autoFocusNearTarget = false)
  754. {
  755. //自动战斗不允许中断当前技能施放.
  756. return false;
  757. }
  758. private void UpdateDoStopSkill()
  759. {
  760. if (this.CurrentState is StateSkill)
  761. {
  762. if (mDoStopSkill)
  763. {
  764. var ss = (this.CurrentState as StateSkill);
  765. if (ss.IsCancelableByMove || ss.IsCancelableBySkill)
  766. {
  767. ss.block();
  768. mDoStopSkill = false;
  769. }
  770. }
  771. }
  772. else
  773. {
  774. mDoStopSkill = false;
  775. }
  776. }
  777. protected override void doGuard(UnitGuardAction act)
  778. {
  779. //没有通关不能自动战斗.
  780. if (act.guard == true && this.Virtual != null && (this.Virtual as XmdsVirtual_Player).AllowUseAutoGuard() == false)
  781. {
  782. // 机器人除外.
  783. if (IsRobot)
  784. {
  785. return;
  786. }
  787. }
  788. cleanFocus();
  789. lastAttackUnit = null;
  790. //XmdsVirtual.FormatLog(CommonLang.Log.LoggerLevel.DEBUG, "act.reason:" + act.reason);
  791. if (act.guard == false)
  792. {
  793. // mAutoGuardTargetList.Clear();
  794. }
  795. else
  796. {
  797. try
  798. {
  799. ParseGuardActionReason(act.reason);
  800. }
  801. catch (Exception error)
  802. {
  803. XmdsVirtual.FormatLog(CommonLang.Log.LoggerLevel.ERROR, "ParseGuardActionReason Error : " + act.reason + " error : " + error.ToString());
  804. }
  805. }
  806. base.doGuard(act);
  807. }
  808. //private static List<int> s_RobotScenID = new List<int>() { 21202, 11001, 11002, 11004,11006, 21202,11021,11022,11047,11048,11049,
  809. // 11050,11052,11053,11056,11061,11064, 11019,11065,11068,11071, 11072,11074,12116,12119, 11012,11015,11019,11024,11029,11045};
  810. /// <summary>
  811. /// 解析挂机指令,新增指令头,告知是定点挂机还是全图游走.
  812. /// 第0位 map/point:
  813. /// 第1位 怪物模板ID:
  814. /// EG: map:怪物模板ID:怪物模板ID
  815. /// </summary>
  816. /// <param name="reason"></param>
  817. private void ParseGuardActionReason(string reason)
  818. {
  819. if (mCurGuardMode == GuardMode.Mode_Point)
  820. {
  821. mGuardPos.SetX(this.X);
  822. mGuardPos.SetY(this.Y);
  823. }
  824. # if OPNE_JSG_AI_TOOLS
  825. if (this.IsRobot)
  826. {
  827. this.mGuardSearchRange = 50;
  828. reason = CommonAI.XmdsConstConfig.AUTO_GUARD_MODE_MAP;
  829. }
  830. #endif
  831. if (string.IsNullOrEmpty(reason))
  832. {
  833. return;
  834. }
  835. string[] array = reason.Split(SPLIT);
  836. if (array != null && array.Length > 0)
  837. {
  838. string head = array[0];
  839. if (head == CommonAI.XmdsConstConfig.AUTO_GUARD_MODE_MAP) //全图模式.
  840. {
  841. mCurGuardMode = GuardMode.Mode_Map;
  842. }
  843. else if (head == CommonAI.XmdsConstConfig.AUTO_GUARD_MODE_POINT)//定点模式.
  844. {
  845. mCurGuardMode = GuardMode.Mode_Point;
  846. mGuardPos.SetX(this.X);
  847. mGuardPos.SetY(this.Y);
  848. }
  849. //array可能是point: point:0 point:taskId:targetId
  850. if (array.Length >= 3)
  851. {
  852. clearAutoGuardTargetList();
  853. if (!string.IsNullOrEmpty(array[1]))
  854. {
  855. int taskId = int.Parse(array[1]);
  856. for (int i = 2; i < array.Length; i++)
  857. {
  858. if (!string.IsNullOrEmpty(array[i]))
  859. {
  860. int targetId = int.Parse(array[i]);
  861. if (targetId > 0)
  862. {
  863. mAutoGuardTargetList.Add(targetId);
  864. //log.Debug("--------------addTarget id: " + targetId);
  865. }
  866. }
  867. }
  868. }
  869. }
  870. }
  871. }
  872. private float GetGuardPosX()
  873. {
  874. switch (mCurGuardMode)
  875. {
  876. case GuardMode.Mode_Map:
  877. return this.X;
  878. case GuardMode.Mode_Point:
  879. return mGuardPos.X;
  880. default:
  881. return this.X;
  882. }
  883. }
  884. private float GetGuardPosY()
  885. {
  886. switch (mCurGuardMode)
  887. {
  888. case GuardMode.Mode_Map:
  889. return this.Y;
  890. case GuardMode.Mode_Point:
  891. return mGuardPos.Y;
  892. default:
  893. return this.Y;
  894. }
  895. }
  896. //查找自动攻击单位.
  897. public override InstanceUnit findGuardTarget(SkillTemplate.CastTarget expect = SkillTemplate.CastTarget.Enemy, AttackReason reason = AttackReason.Look)
  898. {
  899. InstanceUnit min = null;
  900. if (getAvailableAutoLaunchSkill(expect) != null)
  901. {
  902. //有优先目标取优先目标攻击.
  903. if (mAutoGuardTargetList.Count > 0)
  904. {
  905. //using (var list = ListObjectPool<InstanceUnit>.AllocAutoRelease())
  906. List<InstanceUnit> list = new List<InstanceUnit>();
  907. {
  908. Parent.ForEachNearObjects(GetGuardPosX(), GetGuardPosY(), mGuardSearchRange, (InstanceUnit u, ref bool cancel) =>
  909. {
  910. if (mCurGuardMode == GuardMode.Mode_Point && (MathVector.getDistanceSquare(u.X, u.Y, this.X, this.Y) > mGuardSearchRangeExt))
  911. {
  912. return;
  913. }
  914. if (Parent.IsAttackable(this, u, expect, reason, Info))
  915. {
  916. XmdsVirtual zv = u.Virtual as XmdsVirtual;
  917. if (zv != null)
  918. {
  919. if (mAutoGuardTargetList.Contains(zv.GetVirtualTemplateID()))
  920. {
  921. list.Add(u);
  922. }
  923. }
  924. }
  925. });
  926. if (list.Count > 0)
  927. {
  928. list.Sort((a, b) =>
  929. {
  930. float da = CMath.getDistanceSquare(a.X, a.Y, this.X, this.Y);
  931. float db = CMath.getDistanceSquare(b.X, b.Y, this.X, this.Y);
  932. return (int)(da - db);
  933. });
  934. min = list[0];
  935. if (min != null)
  936. {
  937. mAutoGuardTargetTimes = 0;
  938. }
  939. }
  940. //log.Debug("findGuardTarget times: " + mAutoGuardTargetTimes + " count:" + mAutoGuardTargetList.Count + " min:" + (min == null ? "null" : "finded"));
  941. //找不到目标怪就直接返回null等下一次查找,直到等待MAX_AUTO_GUARD_TARGET_TIMES次数
  942. if (mAutoGuardTargetList.Count > 0 && min == null)
  943. {
  944. mAutoGuardTargetTimes += 1;
  945. if (mAutoGuardTargetTimes >= MAX_AUTO_GUARD_TARGET_TIMES)
  946. {
  947. clearAutoGuardTargetList();
  948. }
  949. else
  950. {
  951. return null;
  952. }
  953. }
  954. }
  955. }
  956. //没有优先目标,按照默认逻辑走.
  957. //原本是走父类逻辑,但是现在要分挂机模式,要分索敌范围.
  958. //base.findGuardTarget(expect, reason);
  959. if (min == null)
  960. {
  961. if (getAvailableSkill(expect) != null)
  962. {
  963. bool isMeSteah = this.IsHasSubState(UnitActionSubStatus.Stealth);
  964. float min_len = float.MaxValue;
  965. Parent.ForEachNearObjects(GetGuardPosX(), GetGuardPosY(), mGuardSearchRange, (InstanceUnit u, ref bool cancel) =>
  966. {
  967. // 别人隐身了,自己没有隐身,自动攻击不到
  968. if(u.Virtual.GetBattleStatus() == BattleStatus.None && u.IsHasSubState(UnitActionSubStatus.Stealth) && !isMeSteah)
  969. {
  970. return;
  971. }
  972. float len = MathVector.getDistanceSquare(u.X, u.Y, this.X, this.Y);
  973. if (mCurGuardMode == GuardMode.Mode_Point && len > mGuardSearchRangeExt)
  974. {
  975. return;
  976. }
  977. if (Parent.IsAttackable(this, u, expect, reason, Info))
  978. {
  979. #if OPNE_JSG_AI_TOOLS
  980. //降低机器人之间的互相PK概率
  981. //if (this.IsRobot && u.IsPlayer)
  982. //{
  983. // XmdsInstancePlayer uPlayer = u as XmdsInstancePlayer;
  984. // if (uPlayer.IsRobot && this.RandomN.Next() % 100 < 95)
  985. // {
  986. // return;
  987. // }
  988. //}
  989. //AI随机攻击目标
  990. if (this.IsRobot && this.RandomN.Next() % 100 < 15)
  991. {
  992. min = u;
  993. cancel = true;
  994. return;
  995. }
  996. #endif
  997. if (min_len > len)
  998. {
  999. min_len = len;
  1000. min = u;
  1001. }
  1002. }
  1003. });
  1004. }
  1005. return min;
  1006. }
  1007. }
  1008. return min;
  1009. }
  1010. /// <summary>
  1011. /// 当任务完成时
  1012. /// </summary>
  1013. /// <param name="qd"></param>
  1014. protected override void onQuestCommitted(QuestData qd)
  1015. {
  1016. int targetId = XmdsQuestData.GetTargetID(qd);
  1017. if (this.mAutoGuardTargetList.Contains(targetId))
  1018. {
  1019. clearAutoGuardTargetList();
  1020. }
  1021. }
  1022. public override void OnReconnected(UnitInfo temp, int force, int level, Vector2 enterPos)
  1023. {
  1024. (this.Virtual as XmdsVirtual_Player).OnUnitReEnter(temp, force, level, enterPos);
  1025. base.OnReconnected(temp, force, level, enterPos);
  1026. }
  1027. public override void OnDisconnected()
  1028. {
  1029. base.OnDisconnected();
  1030. var act = new UnitGuardAction();
  1031. act.guard = false;
  1032. doGuard(act);
  1033. var actFollow = new UnitFollowAction();
  1034. actFollow.follow = false;
  1035. doFollow(actFollow);
  1036. }
  1037. protected override void doFollow(UnitFollowAction act)
  1038. {
  1039. base.doFollow(act);
  1040. if (act.follow == true)
  1041. {
  1042. if (this.TeamVirtual != null && this.stateFollow != null)
  1043. {
  1044. if (this.TeamVirtual.TeamLeader != null && this.TeamVirtual.TeamLeader.Enable)
  1045. {
  1046. if (this.TeamVirtual.acceptAutoFollow(this))
  1047. {
  1048. this.TeamVirtual.changeMemberAutoFollow();
  1049. this.stateFollow.Distance = this.TeamVirtual.TeamLeader.RadiusSize + (this.BodyBlockSize * (this.FollowIndex + 1)) * 2;
  1050. //this.changeState(this.stateFollow);
  1051. }
  1052. else
  1053. {
  1054. this.TeamVirtual.cancelAutoFollow(this);
  1055. this.TeamVirtual.changeMemberAutoFollow();
  1056. }
  1057. }
  1058. else if (this.TeamVirtual.TeamLeader == null)
  1059. {
  1060. this.TeamVirtual.cancelAutoFollow(this);
  1061. this.TeamVirtual.changeMemberAutoFollow();
  1062. }
  1063. }
  1064. }
  1065. else
  1066. {
  1067. if (this.TeamVirtual != null)
  1068. {
  1069. this.TeamVirtual.cancelAutoFollow(this);
  1070. this.TeamVirtual.changeMemberAutoFollow();
  1071. }
  1072. }
  1073. }
  1074. public void SendBotTestAutoFight()
  1075. {
  1076. if (mBotTestAutoFight == true)
  1077. {
  1078. var act = new UnitGuardAction();
  1079. act.guard = true;
  1080. doGuard(act);
  1081. }
  1082. }
  1083. #region 自动释放技能.
  1084. /// <summary>
  1085. /// 获得当前能够使用的技能.
  1086. /// </summary>
  1087. /// <returns></returns>
  1088. protected SkillState GetAvailableAutoLaunchSkill(ref InstanceUnit enemy)
  1089. {
  1090. SkillState ret = null;
  1091. do
  1092. {
  1093. //没蓝直接转普攻.
  1094. if (mXmdsFocusTarget == null) { break; }
  1095. List<SkillState> list = SkillStatus as List<SkillState>;
  1096. XmdsStateFollowAndAttack current = CurrentState as XmdsStateFollowAndAttack;
  1097. //优先多段攻击技能
  1098. if (current != null)
  1099. {
  1100. for (int si = list.Count - 1; si >= 0; --si)
  1101. {
  1102. SkillState sst = list[si];
  1103. if (sst == null || (DefaultSkill != null && DefaultSkill.ID == sst.Data.ID))
  1104. {
  1105. continue;
  1106. }
  1107. if (sst.LaunchSkill.AutoLaunch && sst.IsActive && sst.IsMutilAction() && sst.IsHasNext()
  1108. && sst.IsCD && sst.IsDone && this.VirtualPlayer.SkillAutoLaunchTest(sst))
  1109. {
  1110. //System.Console.WriteLine(" - GetAvailableAutoLaunchSkill - " + sst.ID + ", " + sst.ActionIndex);
  1111. return sst;
  1112. }
  1113. }
  1114. }
  1115. for (int si = list.Count - 1; si >= 0; --si)
  1116. {
  1117. SkillState sst = list[si];
  1118. //非PVP, PVE状态下不允许释放技能
  1119. if (DefaultSkill != null && sst.Data.ID != DefaultSkill.ID &&
  1120. sst.LaunchSkill.AutoLaunch && (Virtual.IsInPVP() || Virtual.IsInPVE()))
  1121. {
  1122. if (!sst.IsCD && sst.IsActive && sst.IsDone && sst.LaunchSkill.AutoLaunch && sst.CanAutoLaunch() &&
  1123. this.VirtualPlayer.SkillAutoLaunchTest(sst))
  1124. {
  1125. //判断需要能量值
  1126. if (!this.Virtual.LaunchSkillCheckTalentInfo(sst))
  1127. {
  1128. continue;
  1129. }
  1130. //切换作用不同的技能,这时需要切换技能目标,会导致丢失原目标.
  1131. if (mXmdsFocusTarget.ExpectTarget != sst.Data.ExpectTarget)
  1132. {
  1133. enemy = findGuardTarget(sst.Data.ExpectTarget, AttackReason.Look);
  1134. }
  1135. if (enemy != null)
  1136. {
  1137. ret = sst;
  1138. }
  1139. break;
  1140. }
  1141. }
  1142. }
  1143. } while (false);
  1144. //没有技能时施放普攻.
  1145. if (ret == null && DefaultSkill != null)
  1146. {
  1147. if (enemy != null)
  1148. {
  1149. ret = getSkillState(DefaultSkill.ID);
  1150. }
  1151. }
  1152. return ret;
  1153. }
  1154. /// <summary>
  1155. /// 判断目标技能是否可以自动释放.
  1156. /// </summary>
  1157. /// <param name="skillid"></param>
  1158. /// <returns></returns>
  1159. //private bool CanAutoLaunchSkill(int skillid)
  1160. //{
  1161. // bool ret = false;
  1162. // var v = (this.Virtual as XmdsVirtual);
  1163. // if (v != null)
  1164. // {
  1165. // ret = v.AllowAutoLaunch(skillid);
  1166. // }
  1167. // return ret;
  1168. //}
  1169. public override SkillState getRandomLaunchableExpectSkill(InstanceUnit target, SkillTemplate.CastTarget expectTarget, AttackReason reason = AttackReason.Tracing, bool checkRange = false)
  1170. {
  1171. var ss = GetAvailableAutoLaunchSkill(ref target);
  1172. if (mXmdsFocusTarget != null && target != null && ss != null)
  1173. {
  1174. //mXmdsFocusTarget.TargetUnit = target;
  1175. //mXmdsFocusTarget.ExpectSkillState = ss;
  1176. //mXmdsFocusTarget.ChangeMoveTarget(target);
  1177. mXmdsFocusTarget.ChangeAttackTarget(ss, target);
  1178. }
  1179. return ss;
  1180. }
  1181. private InstanceUnit lastAttackUnit = null;
  1182. public override SkillState getRandomLaunchableExpectSkill(SkillTemplate.CastTarget expectTarget)
  1183. {
  1184. InstanceUnit unit = null;
  1185. if (mXmdsFocusTarget != null)
  1186. {
  1187. unit = mXmdsFocusTarget.TargetUnit;
  1188. }
  1189. var ss = GetAvailableAutoLaunchSkill(ref unit);
  1190. if (mXmdsFocusTarget != null && unit != null && ss != null)
  1191. {
  1192. //mXmdsFocusTarget.TargetUnit = unit;
  1193. //mXmdsFocusTarget.ExpectSkillState = ss;
  1194. //mXmdsFocusTarget.ChangeMoveTarget(unit);
  1195. if (ss.Data.ExpectTarget != mXmdsFocusTarget.ExpectTarget)
  1196. {
  1197. if (mXmdsFocusTarget.ExpectTarget == SkillTemplate.CastTarget.Enemy)
  1198. {
  1199. lastAttackUnit = mXmdsFocusTarget.TargetUnit;
  1200. }
  1201. }
  1202. mXmdsFocusTarget.ChangeAttackTarget(ss, unit);
  1203. }
  1204. return ss;
  1205. }
  1206. public void OnReceiveGetMonsterSufferDamageInfoC2B(GetMonsterSufferDamageInfoC2B evt)
  1207. {
  1208. var ret = evt as GetMonsterSufferDamageInfoC2B;
  1209. //找到指定的怪物单位,获取伤害信息并排序.
  1210. InstanceUnit iu = this.Parent.getUnit(ret.MonsterID);
  1211. if (iu != null && iu is XmdsInstanceMonster)
  1212. {
  1213. XmdsVirtual_Monster zvm = (iu as XmdsInstanceMonster).Virtual as XmdsVirtual_Monster;
  1214. if (zvm != null)
  1215. {
  1216. HashMap<string, PlayerDamageInfo> map = zvm.GetSufferDamage();
  1217. if (map != null)
  1218. {
  1219. MonsterSufferDamageInfoB2C msg = new MonsterSufferDamageInfoB2C();
  1220. List<PlayerDamageInfo> infoList = new List<PlayerDamageInfo>();
  1221. int playerRank = 0;
  1222. int playerDamage = 0;
  1223. //获取数据并排序.
  1224. foreach (var kvp in map)
  1225. {
  1226. infoList.Add(kvp.Value);
  1227. }
  1228. //伤害从大到小排序.
  1229. infoList.Sort((a, b) =>
  1230. {
  1231. return b.Damage - a.Damage;
  1232. });
  1233. //找到自己的排名和伤害.
  1234. for (int i = 0; i < infoList.Count; i++)
  1235. {
  1236. var temp = infoList[i];
  1237. if (this.PlayerUUID == temp.PlayerUUID)
  1238. {
  1239. playerRank = i + 1;
  1240. playerDamage = temp.Damage;
  1241. break;
  1242. }
  1243. }
  1244. //只取10条详细信息发送.
  1245. if (infoList.Count > 10)
  1246. {
  1247. infoList.RemoveRange(10, infoList.Count - 10);
  1248. }
  1249. msg.PlayerDamage = playerDamage;
  1250. msg.PlayerRank = playerRank;
  1251. msg.InfoList = infoList;
  1252. this.queueEvent(msg);
  1253. }
  1254. }
  1255. }
  1256. }
  1257. #endregion
  1258. #region 绕开底层重新实现自动战斗AI.
  1259. private XmdsInstanceUnitStateMachine.XmdsStateFollowAndAttack doXmdsFocusAttack(InstanceUnit target,
  1260. SkillTemplate.CastTarget expect_target = SkillTemplate.CastTarget.Enemy,
  1261. bool autoFocusNearTarget = true, InstanceUnit.SkillState lanuchSkill = null)
  1262. {
  1263. if ((mAttackTo == null || mAttackTo.IsAttack) && Parent.IsAttackable(this, target, expect_target, AttackReason.Tracing, Info))
  1264. {
  1265. this.mLastAutoAttackTime = CommonLang.CUtils.localTimeMS;
  1266. if (mXmdsFocusTarget != null)
  1267. {
  1268. if (mXmdsFocusTarget.TargetUnit != target)
  1269. {
  1270. mXmdsFocusTarget = new XmdsInstanceUnitStateMachine.XmdsStateFollowAndAttack(this, target, expect_target, autoFocusNearTarget, lanuchSkill);
  1271. if (changeState(mXmdsFocusTarget))
  1272. {
  1273. queueEvent(new PlayerFocuseTargetEvent(this.ID, target.ID, expect_target));
  1274. }
  1275. }
  1276. }
  1277. else
  1278. {
  1279. mXmdsFocusTarget = new XmdsInstanceUnitStateMachine.XmdsStateFollowAndAttack(this, target, expect_target, autoFocusNearTarget, lanuchSkill);
  1280. if (changeState(mXmdsFocusTarget))
  1281. {
  1282. queueEvent(new PlayerFocuseTargetEvent(this.ID, target.ID, expect_target));
  1283. }
  1284. }
  1285. }
  1286. else
  1287. {
  1288. mXmdsFocusTarget = null;
  1289. }
  1290. return mXmdsFocusTarget;
  1291. }
  1292. private void doXmdsFocusAttack(InstanceUnit target, SkillState state)
  1293. {
  1294. SkillTemplate.CastTarget expect_target = state.Data.ExpectTarget;
  1295. if ((mAttackTo == null || mAttackTo.IsAttack) && Parent.IsAttackable(this, target, expect_target, AttackReason.Tracing, Info))
  1296. {
  1297. if (mXmdsFocusTarget != null)
  1298. {
  1299. if (mXmdsFocusTarget.TargetUnit != target)
  1300. {
  1301. mXmdsFocusTarget = new XmdsInstanceUnitStateMachine.XmdsStateFollowAndAttack(this, target, expect_target, true);
  1302. mXmdsFocusTarget.ExpectSkillState = state;
  1303. if (changeState(mXmdsFocusTarget))
  1304. {
  1305. queueEvent(new PlayerFocuseTargetEvent(this.ID, target.ID, expect_target));
  1306. }
  1307. }
  1308. }
  1309. else
  1310. {
  1311. mXmdsFocusTarget = new XmdsInstanceUnitStateMachine.XmdsStateFollowAndAttack(this, target, expect_target, true);
  1312. mXmdsFocusTarget.ExpectSkillState = state;
  1313. if (changeState(mXmdsFocusTarget))
  1314. {
  1315. queueEvent(new PlayerFocuseTargetEvent(this.ID, target.ID, expect_target));
  1316. }
  1317. }
  1318. }
  1319. else
  1320. {
  1321. mXmdsFocusTarget = null;
  1322. }
  1323. }
  1324. protected override void cleanFocus()
  1325. {
  1326. mFocusTarget = null;
  1327. mXmdsFocusTarget = null;
  1328. base.cleanFocus();
  1329. }
  1330. protected override void doFocusTarget(UnitFocuseTargetAction focus)
  1331. {
  1332. if (IsGuard)
  1333. {
  1334. mAttackTo = null;
  1335. InstanceZoneObject src = Parent.getObject<InstanceZoneObject>(focus.targetUnitID);
  1336. //目标不能是宠物
  1337. if ((src is InstanceUnit) && !(src is InstancePet))
  1338. {
  1339. if (!IsNoneSkill && ((src as InstanceUnit).IsActive))
  1340. {
  1341. doXmdsFocusAttack(src as InstanceUnit);
  1342. }
  1343. }
  1344. else if ((src is InstanceItem))
  1345. {
  1346. if (src.Enable)
  1347. {
  1348. doFocusPickItem(src as InstanceItem);
  1349. }
  1350. }
  1351. else
  1352. {
  1353. cleanFocus();
  1354. }
  1355. }
  1356. }
  1357. public override void OnUnitDead()
  1358. {
  1359. this.cleanFocus();
  1360. // 死亡取消自动战斗
  1361. if (this.IsGuard)
  1362. {
  1363. this.IsGuard = false;
  1364. this.Virtual.doEvent(JSGCustomOpType.UpdateAutoBattleFlag);
  1365. }
  1366. }
  1367. public override void doSomething()
  1368. {
  1369. if (mWaitingSkill != null && CurrentState is StateSkill)
  1370. {
  1371. if (doLaunchSkill(mWaitingSkill))
  1372. {
  1373. return;
  1374. }
  1375. }
  1376. else if(this.DoAutoPick())
  1377. {
  1378. return;
  1379. }
  1380. else if (IsGuard)
  1381. {
  1382. if (this.canFollowTeam && leadingMan != null)
  1383. {
  1384. if (leadingMan.AoiStatus != null)
  1385. {
  1386. //若队长进入位面
  1387. UnitGuardAction action = new UnitGuardAction();
  1388. action.guard = false;
  1389. action.reason = "guard to follow";
  1390. doGuard(action);
  1391. startIdle();
  1392. return;
  1393. }
  1394. else if (leadingMan.Virtual.GetBattleStatus() == BattleStatus.None)
  1395. {
  1396. UnitGuardAction action = new UnitGuardAction();
  1397. action.guard = false;
  1398. action.reason = "guard to follow";
  1399. doGuard(action);
  1400. updateStateToFollowTeam();
  1401. mXmdsFocusTarget = null;
  1402. return;
  1403. }
  1404. this.stateFollow.Distance = this.leadingMan.RadiusSize + (this.BodyBlockSize * (this.FollowIndex + 1)) * 2;
  1405. //var distance = leadingMan.RadiusSize + this.BodyBlockSize * 2;
  1406. if (!CMath.includeRoundPoint(X, Y, this.GetFollowDistance(true), leadingMan.X, leadingMan.Y))
  1407. {
  1408. UnitGuardAction action = new UnitGuardAction();
  1409. action.guard = false;
  1410. action.reason = "guard to follow";
  1411. doGuard(action);
  1412. updateStateToFollowTeam();
  1413. mXmdsFocusTarget = null;
  1414. return;
  1415. }
  1416. }
  1417. if (mFocusPickItem != null && mFocusPickItem.IsActive)
  1418. {
  1419. changeState(mFocusPickItem);
  1420. return;
  1421. }
  1422. else
  1423. {
  1424. mFocusPickItem = null;
  1425. }
  1426. if (mXmdsFocusTarget != null && mXmdsFocusTarget.IsActive)
  1427. {
  1428. if (Parent.IsAttackable(this, mXmdsFocusTarget.TargetUnit, SkillTemplate.CastTarget.AlliesIncludeSelf, AttackReason.Attack, Info))
  1429. {
  1430. mXmdsFocusTarget = null;
  1431. }
  1432. else
  1433. {
  1434. changeState(mXmdsFocusTarget);
  1435. return;
  1436. }
  1437. }
  1438. else
  1439. {
  1440. mXmdsFocusTarget = null;
  1441. }
  1442. if (mAttackTo != null && !mAttackTo.IsDone)
  1443. {
  1444. changeState(mAttackTo);
  1445. return;
  1446. }
  1447. }
  1448. else if (this.canFollowTeam && leadingMan != null)
  1449. {
  1450. if (leadingMan.Enable)
  1451. {
  1452. if (this.CurrentState != this.stateFollow)
  1453. {
  1454. if (leadingMan.AoiStatus != null)
  1455. {
  1456. //若队长进入位面
  1457. return;
  1458. }
  1459. this.stateFollow.Distance = this.leadingMan.RadiusSize + (this.BodyBlockSize * (this.FollowIndex + 1)) * 2;
  1460. if (!CMath.includeRoundPoint(X, Y, this.GetFollowDistance(false), leadingMan.X, leadingMan.Y))
  1461. {
  1462. this.updateStateToFollowTeam();
  1463. mXmdsFocusTarget = null;
  1464. }
  1465. else
  1466. {//组队切场景后,如果队长不移动,队员状态不改变
  1467. this.updateStateToFollowTeam();
  1468. mXmdsFocusTarget = null;
  1469. }
  1470. }
  1471. else
  1472. {
  1473. //发生寻路卡死
  1474. //transportToTeamLeader();
  1475. }
  1476. //var distance = leadingMan.RadiusSize + this.BodyBlockSize * 2;
  1477. //if (!CMath.includeRoundPoint(X, Y, distance, leadingMan.X, leadingMan.Y))
  1478. //{
  1479. // this.updateStateToFollowTeam();
  1480. // mXmdsFocusTarget = null;
  1481. // return;
  1482. //}
  1483. return;
  1484. }
  1485. else
  1486. {
  1487. //leadingMan忙,切换leadingMan
  1488. //mTeamVirtual.changeMemberAutoFollow();
  1489. }
  1490. }
  1491. else if (CurrentState is StateChuanGongA || CurrentState is StateChuanGongB || CurrentState is StateClearYaoQi)
  1492. {
  1493. if (CommonLang.CUtils.localTimeMS < chuangongTime)
  1494. {
  1495. return;
  1496. }
  1497. }
  1498. else if(CurrentState is StateDaZuo)
  1499. {
  1500. return;
  1501. }
  1502. else if (CurrentState is StateDaZuoRecoveryAttr)
  1503. {
  1504. return;
  1505. }
  1506. startIdle();
  1507. }
  1508. #endregion
  1509. private float GetFollowDistance(bool isGuard)
  1510. {
  1511. if (isGuard)
  1512. {
  1513. return Templates.CFG.PET_FOLLOW_DISTANCE_MAX;
  1514. }
  1515. return this.stateFollow.Distance;
  1516. }
  1517. private void OnPlayerCreate()
  1518. {
  1519. lock (CreateInfoMap)
  1520. {
  1521. AtomicInteger c = null;
  1522. zoneID = (this.Parent as EditorScene).Data.ID;
  1523. if (CreateInfoMap.TryGetValue(zoneID, out c))
  1524. {
  1525. c++;
  1526. }
  1527. else
  1528. {
  1529. c = new AtomicInteger(1);
  1530. CreateInfoMap.Add(zoneID, c);
  1531. }
  1532. }
  1533. }
  1534. ~XmdsInstancePlayer()
  1535. {
  1536. lock (CreateInfoMap)
  1537. {
  1538. AtomicInteger c = null;
  1539. if (CreateInfoMap.TryGetValue(zoneID, out c))
  1540. {
  1541. c--;
  1542. }
  1543. }
  1544. }
  1545. //组队跟随
  1546. private XmdsTeamVirtual mTeamVirtual;
  1547. public XmdsTeamVirtual TeamVirtual
  1548. {
  1549. set
  1550. {
  1551. mTeamVirtual = value;
  1552. }
  1553. get
  1554. {
  1555. return mTeamVirtual;
  1556. }
  1557. }
  1558. private byte mFollowIndex;
  1559. public byte FollowIndex
  1560. {
  1561. set
  1562. {
  1563. mFollowIndex = value;
  1564. }
  1565. get
  1566. {
  1567. return mFollowIndex;
  1568. }
  1569. }
  1570. protected XmdsInstancePlayer leadingMan;
  1571. public XmdsInstancePlayer Leader
  1572. {
  1573. get
  1574. {
  1575. return leadingMan;
  1576. }
  1577. set
  1578. {
  1579. if (leadingMan != value)
  1580. {
  1581. leadingMan = value;
  1582. if (leadingMan == null)
  1583. {
  1584. this.stateFollow = null;
  1585. }
  1586. else
  1587. {
  1588. if (this.stateFollow == null)
  1589. {
  1590. this.stateFollow = new StateFollowLeader(this, leadingMan, 300);
  1591. }
  1592. else
  1593. {
  1594. this.stateFollow.Follower = leadingMan;
  1595. }
  1596. //this.stateFollow = StateFollowTeam.createStateFollowTeam(this, leadingMan);
  1597. }
  1598. }
  1599. }
  1600. }
  1601. public bool canFollowTeam = false;
  1602. public StateFollowLeader stateFollow;
  1603. override public bool isTeamMemberAndFollow()
  1604. {
  1605. return canFollowTeam;
  1606. }
  1607. //切换至跟随状态
  1608. public void updateStateToFollowTeam()
  1609. {
  1610. if (this.mIsReady)
  1611. {
  1612. if (this.canFollowTeam)
  1613. {
  1614. if (this.stateFollow != null && this.CurrentState != this.stateFollow)
  1615. {
  1616. this.changeState(this.stateFollow);
  1617. }
  1618. else if (this.stateFollow == null)
  1619. {
  1620. mTeamVirtual.changeMemberAutoFollow();
  1621. }
  1622. }
  1623. }
  1624. }
  1625. public void cancelGuard()
  1626. {
  1627. if (IsGuard)
  1628. {
  1629. //log.Debug("------guardCanceled: " + this.Name);
  1630. UnitGuardAction action = new UnitGuardAction();
  1631. action.guard = false;
  1632. action.reason = "sdfsdfsdfs";
  1633. doGuard(action);
  1634. SetAutoBattleB2C evt = new SetAutoBattleB2C();
  1635. evt.isAutoBattle = 0;
  1636. this.queueEvent(evt);
  1637. }
  1638. }
  1639. /// <summary>
  1640. ///
  1641. /// </summary>
  1642. private void updateFollowTeam()
  1643. {
  1644. if (this.CurrentState == this.stateFollow && this.mTeamVirtual != null && this.canFollowTeam && this.leadingMan != null && this.leadingMan.Enable)
  1645. {
  1646. // 当前如果正在拾取状态,先捡完再说
  1647. if(this.CurrentState is StateFollowAndPickItem)
  1648. {
  1649. return;
  1650. }
  1651. if (CMath.includeRoundPoint(X, Y, this.GetFollowDistance(true), leadingMan.X, leadingMan.Y))
  1652. {
  1653. //在范围内
  1654. var leader = this.leadingMan;
  1655. if (leader.AoiStatus != null)
  1656. {
  1657. //队长在位面中
  1658. UnitGuardAction action = new UnitGuardAction();
  1659. action.guard = false;
  1660. action.reason = "sdfsdfsdfs";
  1661. doGuard(action);
  1662. startIdle();
  1663. //updateStateToFollowTeam();
  1664. return;
  1665. }
  1666. var vir = leader.Virtual as XmdsVirtual;
  1667. if (vir.CombatState == BattleStatus.PVE)
  1668. {
  1669. if (IsGuard == false)
  1670. {
  1671. //队长在PVE状态
  1672. UnitGuardAction action = new UnitGuardAction();
  1673. action.guard = true;
  1674. action.reason = CommonAI.XmdsConstConfig.AUTO_GUARD_MODE_POINT;
  1675. doGuard(action);
  1676. }
  1677. }
  1678. else if (vir.CombatState == BattleStatus.PVP)
  1679. {
  1680. //队长在PVP状态
  1681. //检查玩家Pk状态在“自由”,“队伍”攻击模式下,则跟随队长攻击目标,否则无视
  1682. var myVir = this.Virtual as XmdsVirtual;
  1683. if (IsGuard == false/* &&( myVir.GetCurPKMode() == PKInfo.PKMode.Team
  1684. || myVir.GetCurPKMode() == PKInfo.PKMode.All)*/)
  1685. {
  1686. UnitGuardAction action = new UnitGuardAction();
  1687. action.guard = true;
  1688. action.reason = CommonAI.XmdsConstConfig.AUTO_GUARD_MODE_POINT;
  1689. doGuard(action);
  1690. }
  1691. }
  1692. }
  1693. else
  1694. {
  1695. UnitGuardAction action = new UnitGuardAction();
  1696. action.guard = false;
  1697. action.reason = "sdfsdfsdfs";
  1698. doGuard(action);
  1699. updateStateToFollowTeam();
  1700. }
  1701. }
  1702. }
  1703. //检测修正部分异常数据
  1704. private void UpdateAndModifyErrorData()
  1705. {
  1706. if(this.CurrentActionStatus == UnitActionStatus.Move)
  1707. {
  1708. if(this.mNotMoveTimes == 0)
  1709. {
  1710. this.mNotMoveTimes = 1;
  1711. this.mLastMovePos.SetX(this.X);
  1712. this.mLastMovePos.SetY(this.Y);
  1713. }
  1714. else if(this.mLastMovePos.X == this.X && this.mLastMovePos.Y == this.Y)
  1715. {
  1716. this.mNotMoveTimes++;
  1717. }
  1718. else
  1719. {
  1720. this.mNotMoveTimes = 0;
  1721. }
  1722. if(this.mNotMoveTimes > 10)
  1723. {
  1724. this.mNotMoveTimes = 0;
  1725. this.doSomething();
  1726. }
  1727. }
  1728. else
  1729. {
  1730. this.mNotMoveTimes = 0;
  1731. }
  1732. }
  1733. //移动到队长旁
  1734. public void moveToLeader()
  1735. {
  1736. if (!this.mIsReady)
  1737. {
  1738. this.readyAction = moveToLeader;
  1739. return;
  1740. }
  1741. if (this.leadingMan != null)
  1742. {
  1743. if (this.CurrentState != this.stateFollow)
  1744. {
  1745. this.changeState(this.stateFollow);
  1746. var virt = this.Virtual as XmdsVirtual;
  1747. if (!virt.IsMounted && !virt.IsInDebuffStatus() && !CMath.includeRoundPoint(this.X, this.Y, this.Templates.CFG.TEAMER_FOLLOW_DISTANCE_LIMIT, this.leadingMan.X, this.leadingMan.Y))
  1748. {
  1749. PlayerSummonMountEventR2B r2b = new PlayerSummonMountEventR2B();
  1750. r2b.TimeMS = 0;
  1751. r2b.IsSummonMount = true;
  1752. (this.Virtual as XmdsVirtual).ReceiveMsgR2B(r2b);
  1753. }
  1754. }
  1755. //float dx, dy;
  1756. //var distance = this.leadingMan.RadiusSize + (this.BodyBlockSize * (this.FollowIndex + 1)) * 2;
  1757. //CMath.RandomPosInRound(Parent.RandomN, this.leadingMan.X, this.leadingMan.Y,
  1758. // distance, out dx, out dy);
  1759. //if (CMath.includeRoundPoint(
  1760. // this.X, this.Y,
  1761. // distance,
  1762. // dx, dy))
  1763. //{
  1764. // this.changeState(this.stateFollow);
  1765. // return;
  1766. //}
  1767. //this.changeState(new StateIdle(this));
  1768. ////StateFollowTeam stateMove = StateFollowTeam.createStateFollowTeam(this, leadingMan);
  1769. //StateMove stateMove = new StateMove(this, dx, dy);
  1770. //stateMove.EndMoveAction = (m) =>
  1771. //{
  1772. // this.changeState(this.stateFollow);
  1773. // return false;
  1774. //};
  1775. //var virt = this.Virtual as XmdsVirtual;
  1776. //if (!virt.IsMounted && !CMath.includeRoundPoint(this.X, this.Y, this.Templates.CFG.TEAMER_FOLLOW_DISTANCE_LIMIT, this.leadingMan.X, this.leadingMan.Y))
  1777. //{
  1778. // PlayerSummonMountEventR2B r2b = new PlayerSummonMountEventR2B();
  1779. // r2b.TimeMS = 0;
  1780. // r2b.IsSummonMount = true;
  1781. // (this.Virtual as XmdsVirtual).ReceiveMsgR2B(r2b);
  1782. //}
  1783. //this.changeState(stateMove);
  1784. }
  1785. }
  1786. protected override void onAdded(bool pointLv)
  1787. {
  1788. base.onAdded(pointLv);
  1789. //吴永辉:进入PVP地图清除技能CD bugId:2797
  1790. XmdsServerScene scene = this.Parent as XmdsServerScene;
  1791. SceneType sceneType = this.VirtualPlayer.mUnit.GetSceneType();
  1792. if (sceneType == SceneType.DanTiao || sceneType == SceneType.JJC || sceneType == SceneType.CrossServer || sceneType == SceneType.MengZhan
  1793. || sceneType == SceneType.FiveVFive || sceneType == SceneType.SourceDungeon
  1794. || sceneType == SceneType.GuildBoss || sceneType == SceneType.SecretDungeon)
  1795. {
  1796. this.ClearAllSkillCD();
  1797. }
  1798. }
  1799. }
  1800. //队伍跟随
  1801. public class StateFollowLeader : VStateFollowLeader
  1802. {
  1803. private InstanceZoneObject follower;
  1804. public InstanceZoneObject Follower
  1805. {
  1806. get
  1807. {
  1808. return follower;
  1809. }
  1810. set
  1811. {
  1812. follower = value;
  1813. this.target = follower;
  1814. }
  1815. }
  1816. public StateFollowLeader(InstanceUnit unit, InstanceZoneObject target, int holdTime = 0) : base(unit, target, holdTime)
  1817. {
  1818. follower = target;
  1819. }
  1820. protected override void onStart()
  1821. {
  1822. if (follower != null)
  1823. {
  1824. unit.SetActionStatus(UnitActionStatus.Move);
  1825. MoveAI.FindPath(follower);
  1826. }
  1827. }
  1828. protected override void onUpdate()
  1829. {
  1830. base.onUpdate();
  1831. switch (FollowState)
  1832. {
  1833. case MoveState.Move:
  1834. var virt = unit.Virtual as XmdsVirtual;
  1835. if (!virt.IsMounted && !virt.IsInDebuffStatus() && !CMath.includeRoundPoint(unit.X, unit.Y, unit.Templates.CFG.TEAMER_FOLLOW_DISTANCE_LIMIT, follower.X, follower.Y))
  1836. {
  1837. //Console.WriteLine("请求上马");
  1838. PlayerSummonMountEventR2B r2b = new PlayerSummonMountEventR2B();
  1839. r2b.TimeMS = 0;
  1840. r2b.IsSummonMount = true;
  1841. (unit.Virtual as XmdsVirtual).ReceiveMsgR2B(r2b);
  1842. }
  1843. break;
  1844. }
  1845. }
  1846. protected override void onUpdateFollowed(IPositionObject target)
  1847. {
  1848. unit.doSomething();
  1849. }
  1850. protected override void onChangedToMove(IPositionObject target)
  1851. {
  1852. var virt = unit.Virtual as XmdsVirtual;
  1853. if (!virt.IsMounted && !virt.IsInDebuffStatus() && !CMath.includeRoundPoint(unit.X, unit.Y, unit.Templates.CFG.TEAMER_FOLLOW_DISTANCE_LIMIT, follower.X, follower.Y))
  1854. {
  1855. PlayerSummonMountEventR2B r2b = new PlayerSummonMountEventR2B();
  1856. r2b.TimeMS = 0;
  1857. r2b.IsSummonMount = true;
  1858. (unit.Virtual as XmdsVirtual).ReceiveMsgR2B(r2b);
  1859. }
  1860. }
  1861. }
  1862. }