XmdsInstancePlayer.cs 54 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089
  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. var state = CurrentState as StateSkill;
  550. if (state != null)
  551. {
  552. Vector2 movePos = (mXmdsFocusTarget == null) ? state.GetMoveToPos() : new Vector2(mXmdsFocusTarget.Target.X, mXmdsFocusTarget.Target.Y);
  553. if (movePos != null && state.IsControlMoveable && !state.unit.IsCannotMove && state.SkillData.AutoFightFollower)
  554. {
  555. if(state.setMoveTo(movePos.X, movePos.Y))
  556. {
  557. // 移动结束
  558. if((this.CurrentActionSubstate & (byte)UnitActionSubStatus.ChargeAtkMove) > 0)
  559. {
  560. this.RemoveActionSubState(UnitActionSubStatus.ChargeAtkMove);
  561. this.AddActionSubState(UnitActionSubStatus.ChargeAtkIdle);
  562. }
  563. }
  564. else
  565. {
  566. // 移动
  567. if ((this.CurrentActionSubstate & (byte)UnitActionSubStatus.ChargeAtkIdle) > 0)
  568. {
  569. this.RemoveActionSubState(UnitActionSubStatus.ChargeAtkIdle);
  570. this.AddActionSubState(UnitActionSubStatus.ChargeAtkMove);
  571. }
  572. }
  573. return;
  574. }
  575. }
  576. // 没目标定期检测目标 //
  577. if ((mXmdsFocusTarget == null) && (mFocusPickItem == null))
  578. {
  579. if (mCheckGuard.Update(Parent.UpdateIntervalMS))
  580. {
  581. var enemy = findGuardTarget(SkillTemplate.CastTarget.Enemy, AttackReason.Look);
  582. if (enemy != null)
  583. {
  584. doXmdsFocusAttack(enemy, SkillTemplate.CastTarget.Enemy);
  585. return;
  586. }
  587. var alias = findGuardTarget(SkillTemplate.CastTarget.AlliesIncludeSelf, AttackReason.Look);
  588. if (alias != null)
  589. {
  590. doXmdsFocusAttack(alias, SkillTemplate.CastTarget.AlliesIncludeSelf);
  591. return;
  592. }
  593. //if (CommonLang.CUtils.localTimeMS - this.mLastAutoAttackTime > 3000/* && this.X == this.mLastAutoFightPos.X && this.Y == this.mLastAutoFightPos.Y*/)
  594. //{
  595. // this.mLastAutoAttackTime = CommonLang.CUtils.localTimeMS;
  596. // this.mGuardPos.SetX(this.X);
  597. // this.mGuardPos.SetY(this.Y);
  598. //}
  599. }
  600. }
  601. }
  602. }
  603. //是否可以自动拾取
  604. public override bool DoAutoPick(bool ignoreInterval = false)
  605. {
  606. //非自动战斗或者非跟随,退出
  607. if (!this.IsGuard && (this.leadingMan == null || (this.leadingMan != null && !this.canFollowTeam)))
  608. {
  609. return false;
  610. }
  611. if(this.VirtualPlayer.VirtualInventorySize <= 0)
  612. {
  613. //只要自动战斗就提示这个,不合理,客户端自己加
  614. //if(mNextNotifyBagFullTime < CommonLang.CUtils.localTimeMS)
  615. //{
  616. // mNextNotifyBagFullTime = CommonLang.CUtils.localTimeMS + 6000;
  617. // this.Virtual.SendMsgToClient(CommonAI.XmdsConstConfig.TIPS_BAG_FULL);
  618. //}
  619. return false;
  620. }
  621. if (!this.Parent.CheckAutoDropItem() || !IsBattleCanPick())
  622. {
  623. return false;
  624. }
  625. if (mFocusPickItem == null || !mFocusPickItem.IsActive || mFocusPickItem.IsBlock())
  626. {
  627. bool leaderInView = false;
  628. if (this.mTeamVirtual != null && this.canFollowTeam && this.leadingMan != null && this.leadingMan.Enable)
  629. {
  630. // 如果正在跟随图中,取消拾取
  631. if(this.CurrentState is StateFollowLeader)
  632. {
  633. StateFollowLeader folloLeader = this.CurrentState as StateFollowLeader;
  634. if(folloLeader != null && folloLeader.FollowState == StateFollow.MoveState.Move)
  635. {
  636. return false;
  637. }
  638. }
  639. if (!CMath.includeRoundPoint(X, Y, this.mAutoPickRange, leadingMan.X, leadingMan.Y))
  640. {
  641. return false;
  642. }
  643. else
  644. {
  645. leaderInView = true;
  646. }
  647. }
  648. bool canAutoPick = IsGuard || this.CurrentState is StateFollowAndPickItem || leaderInView;
  649. if (canAutoPick && (ignoreInterval || mNextAutoFindPickItemTime < CommonLang.CUtils.localTimeMS))
  650. {
  651. var item = findAutoGuardPickItem();
  652. if (item != null)
  653. {
  654. mNextAutoFindPickItemTime = CommonLang.CUtils.localTimeMS + XmdsConfig.Instance.GUARD_FIND_ITEM_CYCLE_TIME;
  655. doFocusPickItem(item, false);
  656. return true;
  657. }
  658. }
  659. }
  660. else
  661. {
  662. return true;
  663. }
  664. return false;
  665. }
  666. //是否跟随队长
  667. public override bool IsFollowMaster()
  668. {
  669. if(this.leadingMan != null && this.canFollowTeam)
  670. {
  671. return true;
  672. }
  673. return false;
  674. }
  675. private bool IsBattleCanPick()
  676. {
  677. if(this.Virtual.GetBattleStatus() != BattleStatus.None)
  678. {
  679. // 不主动开战
  680. if(this.mXmdsFocusTarget != null && this.mXmdsFocusTarget.TargetUnit.IsActive && !this.mXmdsFocusTarget.TargetUnit.IsFullHP())
  681. {
  682. return false;
  683. }
  684. }
  685. return true;
  686. }
  687. //通知拾取消息
  688. public override void NotifyRemoveDropItemB2C(InstanceItem item)
  689. {
  690. RemoveDropItemB2C rd = new RemoveDropItemB2C(item.ID, this.ID);
  691. this.queueEvent(rd);
  692. }
  693. private void DoMockingAttack()
  694. {
  695. //doXmdsFocusAttack(mMockTarget.GetTargetUnit(), SkillTemplate.CastTarget.Enemy, false, this.DefaultSkillStatus());
  696. if (!(this.CurrentState is XmdsInstanceUnitStateMock) || !(this.CurrentState is StateSkill))
  697. {
  698. changeState(mMockTarget);
  699. queueEvent(new PlayerFocuseTargetEvent(this.ID, mMockTarget.GetTargetUnit().ID, SkillTemplate.CastTarget.Enemy)); ;
  700. }
  701. }
  702. public override BuffState AddBuff(BuffTemplate buff, InstanceUnit sender, int pointMaxOverLayer = 0, bool forever = false, bool bMaxOverlayer = false,
  703. int buffExt = 0, bool isControlBuf = false, bool maxReset = false, int addLayers = 0)
  704. {
  705. XmdsBuffProperties prop = buff.Properties as XmdsBuffProperties;
  706. if (prop.BuffAbilityList != null)
  707. {
  708. int count = prop.BuffAbilityList.Count;
  709. for (int i = 0; i < count; i++)
  710. {
  711. if (XmdsInstanceUtils.IsDebuff(prop.BuffAbilityList[i].ability))
  712. {
  713. isControlBuf = true;
  714. break;
  715. }
  716. }
  717. }
  718. return base.AddBuff(buff, sender, pointMaxOverLayer, forever, bMaxOverlayer, buffExt, isControlBuf, maxReset, addLayers);
  719. }
  720. protected override void doHitAttack(InstanceUnit attacker, AttackSource source)
  721. {
  722. if (this.IsDead())
  723. {
  724. //XmdsAttackProperties zap = (source.Attack.Properties as XmdsAttackProperties);
  725. if (attacker.CurrentState is StateSkill)
  726. {
  727. var skilltemplate = (attacker.CurrentState as StateSkill).SkillData;
  728. if ((skilltemplate.Properties as XmdsSkillProperties).TargetType
  729. == XmdsSkillProperties.XmdsSkillTargetType.AllianceDead)
  730. {
  731. TemplateManager.Formula.OnHit(attacker, source, this);
  732. }
  733. }
  734. }
  735. base.doHitAttack(attacker, source);
  736. }
  737. /// <summary>
  738. /// 更改遗言.
  739. /// </summary>
  740. /// <param name="testamentID"></param>
  741. private void ChangeTestament(byte testamentID)
  742. {
  743. (this.Virtual as XmdsVirtual_Player).SyncTestament(testamentID);
  744. }
  745. public override void InitSkills(LaunchSkill baseSkill, params LaunchSkill[] skills)
  746. {
  747. if (this.Virtual == null ||
  748. (this.Virtual as XmdsVirtual).IsFinishSkillInit() == false)
  749. {
  750. return;
  751. }
  752. base.InitSkills(baseSkill, skills);
  753. }
  754. public override bool tryLaunchRandomSkillAndCancelCurrentSkill(InstanceUnit target, bool autoFocusNearTarget = false)
  755. {
  756. //自动战斗不允许中断当前技能施放.
  757. return false;
  758. }
  759. private void UpdateDoStopSkill()
  760. {
  761. if (this.CurrentState is StateSkill)
  762. {
  763. if (mDoStopSkill)
  764. {
  765. var ss = (this.CurrentState as StateSkill);
  766. if (ss.IsCancelableByMove || ss.IsCancelableBySkill)
  767. {
  768. ss.block();
  769. mDoStopSkill = false;
  770. }
  771. }
  772. }
  773. else
  774. {
  775. mDoStopSkill = false;
  776. }
  777. }
  778. protected override void doGuard(UnitGuardAction act)
  779. {
  780. //没有通关不能自动战斗.
  781. if (act.guard == true && this.Virtual != null && (this.Virtual as XmdsVirtual_Player).AllowUseAutoGuard() == false)
  782. {
  783. // 机器人除外.
  784. if (IsRobot)
  785. {
  786. return;
  787. }
  788. }
  789. cleanFocus();
  790. lastAttackUnit = null;
  791. //XmdsVirtual.FormatLog(CommonLang.Log.LoggerLevel.DEBUG, "act.reason:" + act.reason);
  792. if (act.guard == false)
  793. {
  794. // mAutoGuardTargetList.Clear();
  795. }
  796. else
  797. {
  798. try
  799. {
  800. ParseGuardActionReason(act.reason);
  801. }
  802. catch (Exception error)
  803. {
  804. XmdsVirtual.FormatLog(CommonLang.Log.LoggerLevel.ERROR, "ParseGuardActionReason Error : " + act.reason + " error : " + error.ToString());
  805. }
  806. }
  807. base.doGuard(act);
  808. }
  809. //private static List<int> s_RobotScenID = new List<int>() { 21202, 11001, 11002, 11004,11006, 21202,11021,11022,11047,11048,11049,
  810. // 11050,11052,11053,11056,11061,11064, 11019,11065,11068,11071, 11072,11074,12116,12119, 11012,11015,11019,11024,11029,11045};
  811. /// <summary>
  812. /// 解析挂机指令,新增指令头,告知是定点挂机还是全图游走.
  813. /// 第0位 map/point:
  814. /// 第1位 怪物模板ID:
  815. /// EG: map:怪物模板ID:怪物模板ID
  816. /// </summary>
  817. /// <param name="reason"></param>
  818. private void ParseGuardActionReason(string reason)
  819. {
  820. if (mCurGuardMode == GuardMode.Mode_Point)
  821. {
  822. mGuardPos.SetX(this.X);
  823. mGuardPos.SetY(this.Y);
  824. }
  825. # if OPNE_JSG_AI_TOOLS
  826. if (this.IsRobot)
  827. {
  828. this.mGuardSearchRange = 50;
  829. reason = CommonAI.XmdsConstConfig.AUTO_GUARD_MODE_MAP;
  830. }
  831. #endif
  832. if (string.IsNullOrEmpty(reason))
  833. {
  834. return;
  835. }
  836. string[] array = reason.Split(SPLIT);
  837. if (array != null && array.Length > 0)
  838. {
  839. string head = array[0];
  840. if (head == CommonAI.XmdsConstConfig.AUTO_GUARD_MODE_MAP) //全图模式.
  841. {
  842. mCurGuardMode = GuardMode.Mode_Map;
  843. }
  844. else if (head == CommonAI.XmdsConstConfig.AUTO_GUARD_MODE_POINT)//定点模式.
  845. {
  846. mCurGuardMode = GuardMode.Mode_Point;
  847. mGuardPos.SetX(this.X);
  848. mGuardPos.SetY(this.Y);
  849. }
  850. //array可能是point: point:0 point:taskId:targetId
  851. if (array.Length >= 3)
  852. {
  853. clearAutoGuardTargetList();
  854. if (!string.IsNullOrEmpty(array[1]))
  855. {
  856. int taskId = int.Parse(array[1]);
  857. for (int i = 2; i < array.Length; i++)
  858. {
  859. if (!string.IsNullOrEmpty(array[i]))
  860. {
  861. int targetId = int.Parse(array[i]);
  862. if (targetId > 0)
  863. {
  864. mAutoGuardTargetList.Add(targetId);
  865. //log.Debug("--------------addTarget id: " + targetId);
  866. }
  867. }
  868. }
  869. }
  870. }
  871. }
  872. }
  873. private float GetGuardPosX()
  874. {
  875. switch (mCurGuardMode)
  876. {
  877. case GuardMode.Mode_Map:
  878. return this.X;
  879. case GuardMode.Mode_Point:
  880. return mGuardPos.X;
  881. default:
  882. return this.X;
  883. }
  884. }
  885. private float GetGuardPosY()
  886. {
  887. switch (mCurGuardMode)
  888. {
  889. case GuardMode.Mode_Map:
  890. return this.Y;
  891. case GuardMode.Mode_Point:
  892. return mGuardPos.Y;
  893. default:
  894. return this.Y;
  895. }
  896. }
  897. //查找自动攻击单位.
  898. public override InstanceUnit findGuardTarget(SkillTemplate.CastTarget expect = SkillTemplate.CastTarget.Enemy, AttackReason reason = AttackReason.Look)
  899. {
  900. InstanceUnit min = null;
  901. if (getAvailableAutoLaunchSkill(expect) != null)
  902. {
  903. //有优先目标取优先目标攻击.
  904. if (mAutoGuardTargetList.Count > 0)
  905. {
  906. //using (var list = ListObjectPool<InstanceUnit>.AllocAutoRelease())
  907. List<InstanceUnit> list = new List<InstanceUnit>();
  908. {
  909. Parent.ForEachNearObjects(GetGuardPosX(), GetGuardPosY(), mGuardSearchRange, (InstanceUnit u, ref bool cancel) =>
  910. {
  911. if (mCurGuardMode == GuardMode.Mode_Point && (MathVector.getDistanceSquare(u.X, u.Y, this.X, this.Y) > mGuardSearchRangeExt))
  912. {
  913. return;
  914. }
  915. if (Parent.IsAttackable(this, u, expect, reason, Info))
  916. {
  917. XmdsVirtual zv = u.Virtual as XmdsVirtual;
  918. if (zv != null)
  919. {
  920. if (mAutoGuardTargetList.Contains(zv.GetVirtualTemplateID()))
  921. {
  922. list.Add(u);
  923. }
  924. }
  925. }
  926. });
  927. if (list.Count > 0)
  928. {
  929. list.Sort((a, b) =>
  930. {
  931. float da = CMath.getDistanceSquare(a.X, a.Y, this.X, this.Y);
  932. float db = CMath.getDistanceSquare(b.X, b.Y, this.X, this.Y);
  933. return (int)(da - db);
  934. });
  935. min = list[0];
  936. if (min != null)
  937. {
  938. mAutoGuardTargetTimes = 0;
  939. }
  940. }
  941. //log.Debug("findGuardTarget times: " + mAutoGuardTargetTimes + " count:" + mAutoGuardTargetList.Count + " min:" + (min == null ? "null" : "finded"));
  942. //找不到目标怪就直接返回null等下一次查找,直到等待MAX_AUTO_GUARD_TARGET_TIMES次数
  943. if (mAutoGuardTargetList.Count > 0 && min == null)
  944. {
  945. mAutoGuardTargetTimes += 1;
  946. if (mAutoGuardTargetTimes >= MAX_AUTO_GUARD_TARGET_TIMES)
  947. {
  948. clearAutoGuardTargetList();
  949. }
  950. else
  951. {
  952. return null;
  953. }
  954. }
  955. }
  956. }
  957. //没有优先目标,按照默认逻辑走.
  958. //原本是走父类逻辑,但是现在要分挂机模式,要分索敌范围.
  959. //base.findGuardTarget(expect, reason);
  960. if (min == null)
  961. {
  962. if (getAvailableSkill(expect) != null)
  963. {
  964. bool isMeSteah = this.IsHasSubState(UnitActionSubStatus.Stealth);
  965. float min_len = float.MaxValue;
  966. Parent.ForEachNearObjects(GetGuardPosX(), GetGuardPosY(), mGuardSearchRange, (InstanceUnit u, ref bool cancel) =>
  967. {
  968. // 别人隐身了,自己没有隐身,自动攻击不到
  969. if(u.Virtual.GetBattleStatus() == BattleStatus.None && u.IsHasSubState(UnitActionSubStatus.Stealth) && !isMeSteah)
  970. {
  971. return;
  972. }
  973. float len = MathVector.getDistanceSquare(u.X, u.Y, this.X, this.Y);
  974. if (mCurGuardMode == GuardMode.Mode_Point && len > mGuardSearchRangeExt)
  975. {
  976. return;
  977. }
  978. if (Parent.IsAttackable(this, u, expect, reason, Info))
  979. {
  980. #if OPNE_JSG_AI_TOOLS
  981. //降低机器人之间的互相PK概率
  982. //if (this.IsRobot && u.IsPlayer)
  983. //{
  984. // XmdsInstancePlayer uPlayer = u as XmdsInstancePlayer;
  985. // if (uPlayer.IsRobot && this.RandomN.Next() % 100 < 95)
  986. // {
  987. // return;
  988. // }
  989. //}
  990. //AI随机攻击目标
  991. if (this.IsRobot && this.RandomN.Next() % 100 < 15)
  992. {
  993. min = u;
  994. cancel = true;
  995. return;
  996. }
  997. #endif
  998. if (min_len > len)
  999. {
  1000. min_len = len;
  1001. min = u;
  1002. }
  1003. }
  1004. });
  1005. }
  1006. return min;
  1007. }
  1008. }
  1009. return min;
  1010. }
  1011. /// <summary>
  1012. /// 当任务完成时
  1013. /// </summary>
  1014. /// <param name="qd"></param>
  1015. protected override void onQuestCommitted(QuestData qd)
  1016. {
  1017. int targetId = XmdsQuestData.GetTargetID(qd);
  1018. if (this.mAutoGuardTargetList.Contains(targetId))
  1019. {
  1020. clearAutoGuardTargetList();
  1021. }
  1022. }
  1023. public override void OnReconnected(UnitInfo temp, int force, int level, Vector2 enterPos)
  1024. {
  1025. (this.Virtual as XmdsVirtual_Player).OnUnitReEnter(temp, force, level, enterPos);
  1026. base.OnReconnected(temp, force, level, enterPos);
  1027. }
  1028. public override void OnDisconnected()
  1029. {
  1030. base.OnDisconnected();
  1031. var act = new UnitGuardAction();
  1032. act.guard = false;
  1033. doGuard(act);
  1034. var actFollow = new UnitFollowAction();
  1035. actFollow.follow = false;
  1036. doFollow(actFollow);
  1037. }
  1038. protected override void doFollow(UnitFollowAction act)
  1039. {
  1040. base.doFollow(act);
  1041. if (act.follow == true)
  1042. {
  1043. if (this.TeamVirtual != null && this.stateFollow != null)
  1044. {
  1045. if (this.TeamVirtual.TeamLeader != null && this.TeamVirtual.TeamLeader.Enable)
  1046. {
  1047. if (this.TeamVirtual.acceptAutoFollow(this))
  1048. {
  1049. this.TeamVirtual.changeMemberAutoFollow();
  1050. this.stateFollow.Distance = this.TeamVirtual.TeamLeader.RadiusSize + (this.BodyBlockSize * (this.FollowIndex + 1)) * 2;
  1051. //this.changeState(this.stateFollow);
  1052. }
  1053. else
  1054. {
  1055. this.TeamVirtual.cancelAutoFollow(this);
  1056. this.TeamVirtual.changeMemberAutoFollow();
  1057. }
  1058. }
  1059. else if (this.TeamVirtual.TeamLeader == null)
  1060. {
  1061. this.TeamVirtual.cancelAutoFollow(this);
  1062. this.TeamVirtual.changeMemberAutoFollow();
  1063. }
  1064. }
  1065. }
  1066. else
  1067. {
  1068. if (this.TeamVirtual != null)
  1069. {
  1070. this.TeamVirtual.cancelAutoFollow(this);
  1071. this.TeamVirtual.changeMemberAutoFollow();
  1072. }
  1073. }
  1074. }
  1075. public void SendBotTestAutoFight()
  1076. {
  1077. if (mBotTestAutoFight == true)
  1078. {
  1079. var act = new UnitGuardAction();
  1080. act.guard = true;
  1081. doGuard(act);
  1082. }
  1083. }
  1084. #region 自动释放技能.
  1085. /// <summary>
  1086. /// 获得当前能够使用的技能.
  1087. /// </summary>
  1088. /// <returns></returns>
  1089. protected SkillState GetAvailableAutoLaunchSkill(ref InstanceUnit enemy)
  1090. {
  1091. SkillState ret = null;
  1092. do
  1093. {
  1094. //没蓝直接转普攻.
  1095. if (mXmdsFocusTarget == null) { break; }
  1096. List<SkillState> list = SkillStatus as List<SkillState>;
  1097. XmdsStateFollowAndAttack current = CurrentState as XmdsStateFollowAndAttack;
  1098. //优先多段攻击技能
  1099. if (current != null)
  1100. {
  1101. for (int si = list.Count - 1; si >= 0; --si)
  1102. {
  1103. SkillState sst = list[si];
  1104. if (sst == null || (DefaultSkill != null && DefaultSkill.ID == sst.Data.ID))
  1105. {
  1106. continue;
  1107. }
  1108. if (sst.LaunchSkill.AutoLaunch && sst.IsActive && sst.IsMutilAction() && sst.IsHasNext()
  1109. && sst.IsCD && sst.IsDone && this.VirtualPlayer.SkillAutoLaunchTest(sst))
  1110. {
  1111. //System.Console.WriteLine(" - GetAvailableAutoLaunchSkill - " + sst.ID + ", " + sst.ActionIndex);
  1112. return sst;
  1113. }
  1114. }
  1115. }
  1116. for (int si = list.Count - 1; si >= 0; --si)
  1117. {
  1118. SkillState sst = list[si];
  1119. //非PVP, PVE状态下不允许释放技能
  1120. if (DefaultSkill != null && sst.Data.ID != DefaultSkill.ID &&
  1121. sst.LaunchSkill.AutoLaunch && (Virtual.IsInPVP() || Virtual.IsInPVE()))
  1122. {
  1123. if (!sst.IsCD && sst.IsActive && sst.IsDone && sst.LaunchSkill.AutoLaunch && sst.CanAutoLaunch() &&
  1124. this.VirtualPlayer.SkillAutoLaunchTest(sst))
  1125. {
  1126. //判断需要能量值
  1127. if (!this.Virtual.LaunchSkillCheckTalentInfo(sst))
  1128. {
  1129. continue;
  1130. }
  1131. //切换作用不同的技能,这时需要切换技能目标,会导致丢失原目标.
  1132. if (mXmdsFocusTarget.ExpectTarget != sst.Data.ExpectTarget)
  1133. {
  1134. enemy = findGuardTarget(sst.Data.ExpectTarget, AttackReason.Look);
  1135. }
  1136. if (enemy != null)
  1137. {
  1138. ret = sst;
  1139. }
  1140. break;
  1141. }
  1142. }
  1143. }
  1144. } while (false);
  1145. //没有技能时施放普攻.
  1146. if (ret == null && DefaultSkill != null)
  1147. {
  1148. if (enemy != null)
  1149. {
  1150. ret = getSkillState(DefaultSkill.ID);
  1151. }
  1152. }
  1153. return ret;
  1154. }
  1155. /// <summary>
  1156. /// 判断目标技能是否可以自动释放.
  1157. /// </summary>
  1158. /// <param name="skillid"></param>
  1159. /// <returns></returns>
  1160. //private bool CanAutoLaunchSkill(int skillid)
  1161. //{
  1162. // bool ret = false;
  1163. // var v = (this.Virtual as XmdsVirtual);
  1164. // if (v != null)
  1165. // {
  1166. // ret = v.AllowAutoLaunch(skillid);
  1167. // }
  1168. // return ret;
  1169. //}
  1170. public override SkillState getRandomLaunchableExpectSkill(InstanceUnit target, SkillTemplate.CastTarget expectTarget, AttackReason reason = AttackReason.Tracing, bool checkRange = false)
  1171. {
  1172. var ss = GetAvailableAutoLaunchSkill(ref target);
  1173. if (mXmdsFocusTarget != null && target != null && ss != null)
  1174. {
  1175. //mXmdsFocusTarget.TargetUnit = target;
  1176. //mXmdsFocusTarget.ExpectSkillState = ss;
  1177. //mXmdsFocusTarget.ChangeMoveTarget(target);
  1178. mXmdsFocusTarget.ChangeAttackTarget(ss, target);
  1179. }
  1180. return ss;
  1181. }
  1182. private InstanceUnit lastAttackUnit = null;
  1183. public override SkillState getRandomLaunchableExpectSkill(SkillTemplate.CastTarget expectTarget)
  1184. {
  1185. InstanceUnit unit = null;
  1186. if (mXmdsFocusTarget != null)
  1187. {
  1188. unit = mXmdsFocusTarget.TargetUnit;
  1189. }
  1190. var ss = GetAvailableAutoLaunchSkill(ref unit);
  1191. if (mXmdsFocusTarget != null && unit != null && ss != null)
  1192. {
  1193. //mXmdsFocusTarget.TargetUnit = unit;
  1194. //mXmdsFocusTarget.ExpectSkillState = ss;
  1195. //mXmdsFocusTarget.ChangeMoveTarget(unit);
  1196. if (ss.Data.ExpectTarget != mXmdsFocusTarget.ExpectTarget)
  1197. {
  1198. if (mXmdsFocusTarget.ExpectTarget == SkillTemplate.CastTarget.Enemy)
  1199. {
  1200. lastAttackUnit = mXmdsFocusTarget.TargetUnit;
  1201. }
  1202. }
  1203. mXmdsFocusTarget.ChangeAttackTarget(ss, unit);
  1204. }
  1205. return ss;
  1206. }
  1207. public void OnReceiveGetMonsterSufferDamageInfoC2B(GetMonsterSufferDamageInfoC2B evt)
  1208. {
  1209. var ret = evt as GetMonsterSufferDamageInfoC2B;
  1210. //找到指定的怪物单位,获取伤害信息并排序.
  1211. InstanceUnit iu = this.Parent.getUnit(ret.MonsterID);
  1212. if (iu != null && iu is XmdsInstanceMonster)
  1213. {
  1214. XmdsVirtual_Monster zvm = (iu as XmdsInstanceMonster).Virtual as XmdsVirtual_Monster;
  1215. if (zvm != null)
  1216. {
  1217. HashMap<string, PlayerDamageInfo> map = zvm.GetSufferDamage();
  1218. if (map != null)
  1219. {
  1220. MonsterSufferDamageInfoB2C msg = new MonsterSufferDamageInfoB2C();
  1221. List<PlayerDamageInfo> infoList = new List<PlayerDamageInfo>();
  1222. int playerRank = 0;
  1223. int playerDamage = 0;
  1224. //获取数据并排序.
  1225. foreach (var kvp in map)
  1226. {
  1227. infoList.Add(kvp.Value);
  1228. }
  1229. //伤害从大到小排序.
  1230. infoList.Sort((a, b) =>
  1231. {
  1232. return b.Damage - a.Damage;
  1233. });
  1234. //找到自己的排名和伤害.
  1235. for (int i = 0; i < infoList.Count; i++)
  1236. {
  1237. var temp = infoList[i];
  1238. if (this.PlayerUUID == temp.PlayerUUID)
  1239. {
  1240. playerRank = i + 1;
  1241. playerDamage = temp.Damage;
  1242. break;
  1243. }
  1244. }
  1245. //只取10条详细信息发送.
  1246. if (infoList.Count > 10)
  1247. {
  1248. infoList.RemoveRange(10, infoList.Count - 10);
  1249. }
  1250. msg.PlayerDamage = playerDamage;
  1251. msg.PlayerRank = playerRank;
  1252. msg.InfoList = infoList;
  1253. this.queueEvent(msg);
  1254. }
  1255. }
  1256. }
  1257. }
  1258. #endregion
  1259. #region 绕开底层重新实现自动战斗AI.
  1260. private XmdsInstanceUnitStateMachine.XmdsStateFollowAndAttack doXmdsFocusAttack(InstanceUnit target,
  1261. SkillTemplate.CastTarget expect_target = SkillTemplate.CastTarget.Enemy,
  1262. bool autoFocusNearTarget = true, InstanceUnit.SkillState lanuchSkill = null)
  1263. {
  1264. if ((mAttackTo == null || mAttackTo.IsAttack) && Parent.IsAttackable(this, target, expect_target, AttackReason.Tracing, Info))
  1265. {
  1266. this.mLastAutoAttackTime = CommonLang.CUtils.localTimeMS;
  1267. if (mXmdsFocusTarget != null)
  1268. {
  1269. if (mXmdsFocusTarget.TargetUnit != target)
  1270. {
  1271. mXmdsFocusTarget = new XmdsInstanceUnitStateMachine.XmdsStateFollowAndAttack(this, target, expect_target, autoFocusNearTarget, lanuchSkill);
  1272. if (changeState(mXmdsFocusTarget))
  1273. {
  1274. queueEvent(new PlayerFocuseTargetEvent(this.ID, target.ID, expect_target));
  1275. }
  1276. }
  1277. }
  1278. else
  1279. {
  1280. mXmdsFocusTarget = new XmdsInstanceUnitStateMachine.XmdsStateFollowAndAttack(this, target, expect_target, autoFocusNearTarget, lanuchSkill);
  1281. if (changeState(mXmdsFocusTarget))
  1282. {
  1283. queueEvent(new PlayerFocuseTargetEvent(this.ID, target.ID, expect_target));
  1284. }
  1285. }
  1286. }
  1287. else
  1288. {
  1289. mXmdsFocusTarget = null;
  1290. }
  1291. return mXmdsFocusTarget;
  1292. }
  1293. private void doXmdsFocusAttack(InstanceUnit target, SkillState state)
  1294. {
  1295. SkillTemplate.CastTarget expect_target = state.Data.ExpectTarget;
  1296. if ((mAttackTo == null || mAttackTo.IsAttack) && Parent.IsAttackable(this, target, expect_target, AttackReason.Tracing, Info))
  1297. {
  1298. if (mXmdsFocusTarget != null)
  1299. {
  1300. if (mXmdsFocusTarget.TargetUnit != target)
  1301. {
  1302. mXmdsFocusTarget = new XmdsInstanceUnitStateMachine.XmdsStateFollowAndAttack(this, target, expect_target, true);
  1303. mXmdsFocusTarget.ExpectSkillState = state;
  1304. if (changeState(mXmdsFocusTarget))
  1305. {
  1306. queueEvent(new PlayerFocuseTargetEvent(this.ID, target.ID, expect_target));
  1307. }
  1308. }
  1309. }
  1310. else
  1311. {
  1312. mXmdsFocusTarget = new XmdsInstanceUnitStateMachine.XmdsStateFollowAndAttack(this, target, expect_target, true);
  1313. mXmdsFocusTarget.ExpectSkillState = state;
  1314. if (changeState(mXmdsFocusTarget))
  1315. {
  1316. queueEvent(new PlayerFocuseTargetEvent(this.ID, target.ID, expect_target));
  1317. }
  1318. }
  1319. }
  1320. else
  1321. {
  1322. mXmdsFocusTarget = null;
  1323. }
  1324. }
  1325. protected override void cleanFocus()
  1326. {
  1327. mFocusTarget = null;
  1328. mXmdsFocusTarget = null;
  1329. base.cleanFocus();
  1330. }
  1331. protected override void doFocusTarget(UnitFocuseTargetAction focus)
  1332. {
  1333. if (IsGuard)
  1334. {
  1335. mAttackTo = null;
  1336. InstanceZoneObject src = Parent.getObject<InstanceZoneObject>(focus.targetUnitID);
  1337. //目标不能是宠物
  1338. if ((src is InstanceUnit) && !(src is InstancePet))
  1339. {
  1340. if (!IsNoneSkill && ((src as InstanceUnit).IsActive))
  1341. {
  1342. doXmdsFocusAttack(src as InstanceUnit);
  1343. }
  1344. }
  1345. else if ((src is InstanceItem))
  1346. {
  1347. if (src.Enable)
  1348. {
  1349. doFocusPickItem(src as InstanceItem);
  1350. }
  1351. }
  1352. else
  1353. {
  1354. cleanFocus();
  1355. }
  1356. }
  1357. }
  1358. public override void OnUnitDead()
  1359. {
  1360. this.cleanFocus();
  1361. // 死亡取消自动战斗
  1362. if (this.IsGuard)
  1363. {
  1364. this.IsGuard = false;
  1365. this.Virtual.doEvent(JSGCustomOpType.UpdateAutoBattleFlag);
  1366. }
  1367. }
  1368. public override void doSomething()
  1369. {
  1370. if (mWaitingSkill != null && CurrentState is StateSkill)
  1371. {
  1372. if (doLaunchSkill(mWaitingSkill))
  1373. {
  1374. return;
  1375. }
  1376. }
  1377. else if(this.DoAutoPick())
  1378. {
  1379. return;
  1380. }
  1381. else if (IsGuard)
  1382. {
  1383. if (this.canFollowTeam && leadingMan != null)
  1384. {
  1385. if (leadingMan.AoiStatus != null)
  1386. {
  1387. //若队长进入位面
  1388. UnitGuardAction action = new UnitGuardAction();
  1389. action.guard = false;
  1390. action.reason = "guard to follow";
  1391. doGuard(action);
  1392. startIdle();
  1393. return;
  1394. }
  1395. else if (leadingMan.Virtual.GetBattleStatus() == BattleStatus.None)
  1396. {
  1397. UnitGuardAction action = new UnitGuardAction();
  1398. action.guard = false;
  1399. action.reason = "guard to follow";
  1400. doGuard(action);
  1401. updateStateToFollowTeam();
  1402. mXmdsFocusTarget = null;
  1403. return;
  1404. }
  1405. this.stateFollow.Distance = this.leadingMan.RadiusSize + (this.BodyBlockSize * (this.FollowIndex + 1)) * 2;
  1406. //var distance = leadingMan.RadiusSize + this.BodyBlockSize * 2;
  1407. if (!CMath.includeRoundPoint(X, Y, this.GetFollowDistance(true), leadingMan.X, leadingMan.Y))
  1408. {
  1409. UnitGuardAction action = new UnitGuardAction();
  1410. action.guard = false;
  1411. action.reason = "guard to follow";
  1412. doGuard(action);
  1413. updateStateToFollowTeam();
  1414. mXmdsFocusTarget = null;
  1415. return;
  1416. }
  1417. }
  1418. if (mFocusPickItem != null && mFocusPickItem.IsActive)
  1419. {
  1420. changeState(mFocusPickItem);
  1421. return;
  1422. }
  1423. else
  1424. {
  1425. mFocusPickItem = null;
  1426. }
  1427. if (mXmdsFocusTarget != null && mXmdsFocusTarget.IsActive)
  1428. {
  1429. if (Parent.IsAttackable(this, mXmdsFocusTarget.TargetUnit, SkillTemplate.CastTarget.AlliesIncludeSelf, AttackReason.Attack, Info))
  1430. {
  1431. mXmdsFocusTarget = null;
  1432. }
  1433. else
  1434. {
  1435. changeState(mXmdsFocusTarget);
  1436. return;
  1437. }
  1438. }
  1439. else
  1440. {
  1441. mXmdsFocusTarget = null;
  1442. }
  1443. if (mAttackTo != null && !mAttackTo.IsDone)
  1444. {
  1445. changeState(mAttackTo);
  1446. return;
  1447. }
  1448. }
  1449. else if (this.canFollowTeam && leadingMan != null)
  1450. {
  1451. if (leadingMan.Enable)
  1452. {
  1453. if (this.CurrentState != this.stateFollow)
  1454. {
  1455. if (leadingMan.AoiStatus != null)
  1456. {
  1457. //若队长进入位面
  1458. return;
  1459. }
  1460. this.stateFollow.Distance = this.leadingMan.RadiusSize + (this.BodyBlockSize * (this.FollowIndex + 1)) * 2;
  1461. if (!CMath.includeRoundPoint(X, Y, this.GetFollowDistance(false), leadingMan.X, leadingMan.Y))
  1462. {
  1463. this.updateStateToFollowTeam();
  1464. mXmdsFocusTarget = null;
  1465. }
  1466. else
  1467. {//组队切场景后,如果队长不移动,队员状态不改变
  1468. this.updateStateToFollowTeam();
  1469. mXmdsFocusTarget = null;
  1470. }
  1471. }
  1472. else
  1473. {
  1474. //发生寻路卡死
  1475. //transportToTeamLeader();
  1476. }
  1477. //var distance = leadingMan.RadiusSize + this.BodyBlockSize * 2;
  1478. //if (!CMath.includeRoundPoint(X, Y, distance, leadingMan.X, leadingMan.Y))
  1479. //{
  1480. // this.updateStateToFollowTeam();
  1481. // mXmdsFocusTarget = null;
  1482. // return;
  1483. //}
  1484. return;
  1485. }
  1486. else
  1487. {
  1488. //leadingMan忙,切换leadingMan
  1489. //mTeamVirtual.changeMemberAutoFollow();
  1490. }
  1491. }
  1492. else if (CurrentState is StateChuanGongA || CurrentState is StateChuanGongB || CurrentState is StateClearYaoQi)
  1493. {
  1494. if (CommonLang.CUtils.localTimeMS < chuangongTime)
  1495. {
  1496. return;
  1497. }
  1498. }
  1499. else if(CurrentState is StateDaZuo)
  1500. {
  1501. return;
  1502. }
  1503. else if (CurrentState is StateDaZuoRecoveryAttr)
  1504. {
  1505. return;
  1506. }
  1507. startIdle();
  1508. }
  1509. #endregion
  1510. private float GetFollowDistance(bool isGuard)
  1511. {
  1512. if (isGuard)
  1513. {
  1514. return Templates.CFG.PET_FOLLOW_DISTANCE_MAX;
  1515. }
  1516. return this.stateFollow.Distance;
  1517. }
  1518. private void OnPlayerCreate()
  1519. {
  1520. lock (CreateInfoMap)
  1521. {
  1522. AtomicInteger c = null;
  1523. zoneID = (this.Parent as EditorScene).Data.ID;
  1524. if (CreateInfoMap.TryGetValue(zoneID, out c))
  1525. {
  1526. c++;
  1527. }
  1528. else
  1529. {
  1530. c = new AtomicInteger(1);
  1531. CreateInfoMap.Add(zoneID, c);
  1532. }
  1533. }
  1534. }
  1535. ~XmdsInstancePlayer()
  1536. {
  1537. lock (CreateInfoMap)
  1538. {
  1539. AtomicInteger c = null;
  1540. if (CreateInfoMap.TryGetValue(zoneID, out c))
  1541. {
  1542. c--;
  1543. }
  1544. }
  1545. }
  1546. //组队跟随
  1547. private XmdsTeamVirtual mTeamVirtual;
  1548. public XmdsTeamVirtual TeamVirtual
  1549. {
  1550. set
  1551. {
  1552. mTeamVirtual = value;
  1553. }
  1554. get
  1555. {
  1556. return mTeamVirtual;
  1557. }
  1558. }
  1559. private byte mFollowIndex;
  1560. public byte FollowIndex
  1561. {
  1562. set
  1563. {
  1564. mFollowIndex = value;
  1565. }
  1566. get
  1567. {
  1568. return mFollowIndex;
  1569. }
  1570. }
  1571. protected XmdsInstancePlayer leadingMan;
  1572. public XmdsInstancePlayer Leader
  1573. {
  1574. get
  1575. {
  1576. return leadingMan;
  1577. }
  1578. set
  1579. {
  1580. if (leadingMan != value)
  1581. {
  1582. leadingMan = value;
  1583. if (leadingMan == null)
  1584. {
  1585. this.stateFollow = null;
  1586. }
  1587. else
  1588. {
  1589. if (this.stateFollow == null)
  1590. {
  1591. this.stateFollow = new StateFollowLeader(this, leadingMan, 300);
  1592. }
  1593. else
  1594. {
  1595. this.stateFollow.Follower = leadingMan;
  1596. }
  1597. //this.stateFollow = StateFollowTeam.createStateFollowTeam(this, leadingMan);
  1598. }
  1599. }
  1600. }
  1601. }
  1602. public bool canFollowTeam = false;
  1603. public StateFollowLeader stateFollow;
  1604. override public bool isTeamMemberAndFollow()
  1605. {
  1606. return canFollowTeam;
  1607. }
  1608. //切换至跟随状态
  1609. public void updateStateToFollowTeam()
  1610. {
  1611. if (this.mIsReady)
  1612. {
  1613. if (this.canFollowTeam)
  1614. {
  1615. if (this.stateFollow != null && this.CurrentState != this.stateFollow)
  1616. {
  1617. this.changeState(this.stateFollow);
  1618. }
  1619. else if (this.stateFollow == null)
  1620. {
  1621. mTeamVirtual.changeMemberAutoFollow();
  1622. }
  1623. }
  1624. }
  1625. }
  1626. public void cancelGuard()
  1627. {
  1628. if (IsGuard)
  1629. {
  1630. //log.Debug("------guardCanceled: " + this.Name);
  1631. UnitGuardAction action = new UnitGuardAction();
  1632. action.guard = false;
  1633. action.reason = "sdfsdfsdfs";
  1634. doGuard(action);
  1635. SetAutoBattleB2C evt = new SetAutoBattleB2C();
  1636. evt.isAutoBattle = 0;
  1637. this.queueEvent(evt);
  1638. }
  1639. }
  1640. /// <summary>
  1641. ///
  1642. /// </summary>
  1643. private void updateFollowTeam()
  1644. {
  1645. if (this.CurrentState == this.stateFollow && this.mTeamVirtual != null && this.canFollowTeam && this.leadingMan != null && this.leadingMan.Enable)
  1646. {
  1647. // 当前如果正在拾取状态,先捡完再说
  1648. if(this.CurrentState is StateFollowAndPickItem)
  1649. {
  1650. return;
  1651. }
  1652. if (CMath.includeRoundPoint(X, Y, this.GetFollowDistance(true), leadingMan.X, leadingMan.Y))
  1653. {
  1654. //在范围内
  1655. var leader = this.leadingMan;
  1656. if (leader.AoiStatus != null)
  1657. {
  1658. //队长在位面中
  1659. UnitGuardAction action = new UnitGuardAction();
  1660. action.guard = false;
  1661. action.reason = "sdfsdfsdfs";
  1662. doGuard(action);
  1663. startIdle();
  1664. //updateStateToFollowTeam();
  1665. return;
  1666. }
  1667. var vir = leader.Virtual as XmdsVirtual;
  1668. if (vir.CombatState == BattleStatus.PVE)
  1669. {
  1670. if (IsGuard == false)
  1671. {
  1672. //队长在PVE状态
  1673. UnitGuardAction action = new UnitGuardAction();
  1674. action.guard = true;
  1675. action.reason = CommonAI.XmdsConstConfig.AUTO_GUARD_MODE_POINT;
  1676. doGuard(action);
  1677. }
  1678. }
  1679. else if (vir.CombatState == BattleStatus.PVP)
  1680. {
  1681. //队长在PVP状态
  1682. //检查玩家Pk状态在“自由”,“队伍”攻击模式下,则跟随队长攻击目标,否则无视
  1683. var myVir = this.Virtual as XmdsVirtual;
  1684. if (IsGuard == false/* &&( myVir.GetCurPKMode() == PKInfo.PKMode.Team
  1685. || myVir.GetCurPKMode() == PKInfo.PKMode.All)*/)
  1686. {
  1687. UnitGuardAction action = new UnitGuardAction();
  1688. action.guard = true;
  1689. action.reason = CommonAI.XmdsConstConfig.AUTO_GUARD_MODE_POINT;
  1690. doGuard(action);
  1691. }
  1692. }
  1693. }
  1694. else
  1695. {
  1696. UnitGuardAction action = new UnitGuardAction();
  1697. action.guard = false;
  1698. action.reason = "sdfsdfsdfs";
  1699. doGuard(action);
  1700. updateStateToFollowTeam();
  1701. }
  1702. }
  1703. }
  1704. //检测修正部分异常数据
  1705. private void UpdateAndModifyErrorData()
  1706. {
  1707. if(this.CurrentActionStatus == UnitActionStatus.Move)
  1708. {
  1709. if(this.mNotMoveTimes == 0)
  1710. {
  1711. this.mNotMoveTimes = 1;
  1712. this.mLastMovePos.SetX(this.X);
  1713. this.mLastMovePos.SetY(this.Y);
  1714. }
  1715. else if(this.mLastMovePos.X == this.X && this.mLastMovePos.Y == this.Y)
  1716. {
  1717. this.mNotMoveTimes++;
  1718. }
  1719. else
  1720. {
  1721. this.mNotMoveTimes = 0;
  1722. }
  1723. if(this.mNotMoveTimes > 10)
  1724. {
  1725. this.mNotMoveTimes = 0;
  1726. this.doSomething();
  1727. }
  1728. }
  1729. else
  1730. {
  1731. this.mNotMoveTimes = 0;
  1732. }
  1733. }
  1734. //移动到队长旁
  1735. public void moveToLeader()
  1736. {
  1737. if (!this.mIsReady)
  1738. {
  1739. this.readyAction = moveToLeader;
  1740. return;
  1741. }
  1742. if (this.leadingMan != null)
  1743. {
  1744. if (this.CurrentState != this.stateFollow)
  1745. {
  1746. this.changeState(this.stateFollow);
  1747. var virt = this.Virtual as XmdsVirtual;
  1748. if (!virt.IsMounted && !virt.IsInDebuffStatus() && !CMath.includeRoundPoint(this.X, this.Y, this.Templates.CFG.TEAMER_FOLLOW_DISTANCE_LIMIT, this.leadingMan.X, this.leadingMan.Y))
  1749. {
  1750. PlayerSummonMountEventR2B r2b = new PlayerSummonMountEventR2B();
  1751. r2b.TimeMS = 0;
  1752. r2b.IsSummonMount = true;
  1753. (this.Virtual as XmdsVirtual).ReceiveMsgR2B(r2b);
  1754. }
  1755. }
  1756. //float dx, dy;
  1757. //var distance = this.leadingMan.RadiusSize + (this.BodyBlockSize * (this.FollowIndex + 1)) * 2;
  1758. //CMath.RandomPosInRound(Parent.RandomN, this.leadingMan.X, this.leadingMan.Y,
  1759. // distance, out dx, out dy);
  1760. //if (CMath.includeRoundPoint(
  1761. // this.X, this.Y,
  1762. // distance,
  1763. // dx, dy))
  1764. //{
  1765. // this.changeState(this.stateFollow);
  1766. // return;
  1767. //}
  1768. //this.changeState(new StateIdle(this));
  1769. ////StateFollowTeam stateMove = StateFollowTeam.createStateFollowTeam(this, leadingMan);
  1770. //StateMove stateMove = new StateMove(this, dx, dy);
  1771. //stateMove.EndMoveAction = (m) =>
  1772. //{
  1773. // this.changeState(this.stateFollow);
  1774. // return false;
  1775. //};
  1776. //var virt = this.Virtual as XmdsVirtual;
  1777. //if (!virt.IsMounted && !CMath.includeRoundPoint(this.X, this.Y, this.Templates.CFG.TEAMER_FOLLOW_DISTANCE_LIMIT, this.leadingMan.X, this.leadingMan.Y))
  1778. //{
  1779. // PlayerSummonMountEventR2B r2b = new PlayerSummonMountEventR2B();
  1780. // r2b.TimeMS = 0;
  1781. // r2b.IsSummonMount = true;
  1782. // (this.Virtual as XmdsVirtual).ReceiveMsgR2B(r2b);
  1783. //}
  1784. //this.changeState(stateMove);
  1785. }
  1786. }
  1787. protected override void onAdded(bool pointLv)
  1788. {
  1789. base.onAdded(pointLv);
  1790. //吴永辉:进入PVP地图清除技能CD bugId:2797
  1791. XmdsServerScene scene = this.Parent as XmdsServerScene;
  1792. SceneType sceneType = this.VirtualPlayer.mUnit.GetSceneType();
  1793. if (sceneType == SceneType.DanTiao || sceneType == SceneType.JJC || sceneType == SceneType.CrossServer || sceneType == SceneType.MengZhan
  1794. || sceneType == SceneType.FiveVFive || sceneType == SceneType.SourceDungeon
  1795. || sceneType == SceneType.GuildBoss || sceneType == SceneType.SecretDungeon)
  1796. {
  1797. this.ClearAllSkillCD();
  1798. }
  1799. }
  1800. }
  1801. //队伍跟随
  1802. public class StateFollowLeader : VStateFollowLeader
  1803. {
  1804. private InstanceZoneObject follower;
  1805. public InstanceZoneObject Follower
  1806. {
  1807. get
  1808. {
  1809. return follower;
  1810. }
  1811. set
  1812. {
  1813. follower = value;
  1814. this.target = follower;
  1815. }
  1816. }
  1817. public StateFollowLeader(InstanceUnit unit, InstanceZoneObject target, int holdTime = 0) : base(unit, target, holdTime)
  1818. {
  1819. follower = target;
  1820. }
  1821. protected override void onStart()
  1822. {
  1823. if (follower != null)
  1824. {
  1825. unit.SetActionStatus(UnitActionStatus.Move);
  1826. MoveAI.FindPath(follower);
  1827. }
  1828. }
  1829. protected override void onUpdate()
  1830. {
  1831. base.onUpdate();
  1832. switch (FollowState)
  1833. {
  1834. case MoveState.Move:
  1835. var virt = unit.Virtual as XmdsVirtual;
  1836. if (!virt.IsMounted && !virt.IsInDebuffStatus() && !CMath.includeRoundPoint(unit.X, unit.Y, unit.Templates.CFG.TEAMER_FOLLOW_DISTANCE_LIMIT, follower.X, follower.Y))
  1837. {
  1838. //Console.WriteLine("请求上马");
  1839. PlayerSummonMountEventR2B r2b = new PlayerSummonMountEventR2B();
  1840. r2b.TimeMS = 0;
  1841. r2b.IsSummonMount = true;
  1842. (unit.Virtual as XmdsVirtual).ReceiveMsgR2B(r2b);
  1843. }
  1844. break;
  1845. }
  1846. }
  1847. protected override void onUpdateFollowed(IPositionObject target)
  1848. {
  1849. unit.doSomething();
  1850. }
  1851. protected override void onChangedToMove(IPositionObject target)
  1852. {
  1853. var virt = unit.Virtual as XmdsVirtual;
  1854. if (!virt.IsMounted && !virt.IsInDebuffStatus() && !CMath.includeRoundPoint(unit.X, unit.Y, unit.Templates.CFG.TEAMER_FOLLOW_DISTANCE_LIMIT, follower.X, follower.Y))
  1855. {
  1856. PlayerSummonMountEventR2B r2b = new PlayerSummonMountEventR2B();
  1857. r2b.TimeMS = 0;
  1858. r2b.IsSummonMount = true;
  1859. (unit.Virtual as XmdsVirtual).ReceiveMsgR2B(r2b);
  1860. }
  1861. }
  1862. }
  1863. }