XmdsInstanceMonster.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. using CommonAI.Zone;
  2. using CommonAI.Zone.Helper;
  3. using CommonAI.Zone.Instance;
  4. using CommonLang;
  5. using XmdsCommon.Plugin;
  6. using CommonLang.Vector;
  7. using XmdsCommonServer.Plugin.Scene;
  8. using System.Collections.Generic;
  9. using System;
  10. using CommonAI.Zone.Formula;
  11. using static XmdsCommonServer.Plugin.XmdsVirtual;
  12. using static CommonAI.Zone.AttackProp;
  13. using XmdsCommon.Message;
  14. using CommonAI.Data;
  15. using CommonAI;
  16. namespace XmdsCommonServer.Plugin.Units
  17. {
  18. public class XmdsInstanceMonster : InstanceGuard
  19. {
  20. /// <summary>
  21. /// 储存真正的单位ID.
  22. /// </summary>
  23. private int mMonsterID = 0;
  24. /// <summary>
  25. /// 获取怪物真正的ID.
  26. /// </summary>
  27. /// <returns></returns>
  28. public int MonsterID
  29. {
  30. set { mMonsterID = value; }
  31. get { return mMonsterID; }
  32. }
  33. private float mGuardRangeLimit;
  34. private float mGuardRange;
  35. private TimeExpire<int> mIdleMoveHoldTime;
  36. private WanderConfig mWanderConfig = null;
  37. public XmdsInstanceMonster(InstanceZone zone, UnitInfo info, string name, int force, int level)
  38. : base(zone, info, name, force, level)
  39. {
  40. mGuardRangeLimit = info.GuardRangeLimit;
  41. mGuardRange = info.GuardRange;
  42. if (((zone as XmdsServerScene).Data != null))
  43. {
  44. XmdsServerSceneData data = ((zone as XmdsServerScene).Data.Properties as XmdsSceneProperties).ServerSceneData;
  45. //只有野外地图生效.
  46. if (data.SceneHard == XmdsServerSceneData.NORMAL_MAP)
  47. {
  48. mWanderConfig = (info.Properties as XmdsUnitProperties).WanderConfigData;
  49. if (mWanderConfig == null)
  50. {
  51. //编辑器未配置时走默认.
  52. mWanderConfig = new WanderConfig();
  53. mWanderConfig.MaxHoldTimeMS = XmdsConfig.Instance.MAX_HOLD_TIMEMS;
  54. mWanderConfig.MinHoldTimeMS = XmdsConfig.Instance.MIN_HOLD_TIMEMS;
  55. mWanderConfig.MaxMoveTimeMS = XmdsConfig.Instance.MAX_MOVE_TIMEMS;
  56. mWanderConfig.MinMoveTimeMS = XmdsConfig.Instance.MIN_MOVE_TIMEMS;
  57. mWanderConfig.WanderRange = XmdsConfig.Instance.WANDE_RRANGE;
  58. }
  59. if (mWanderConfig.MaxHoldTimeMS > 0)
  60. {
  61. mIdleMoveHoldTime =
  62. new TimeExpire<int>(Parent.RandomN.Next(mWanderConfig.MinHoldTimeMS, mWanderConfig.MaxHoldTimeMS));
  63. }
  64. }
  65. }
  66. }
  67. protected override void onUpdate(bool slowRefresh)
  68. {
  69. base.onUpdate(slowRefresh);
  70. this.updateIdle();
  71. }
  72. public HateSystem getHateSystem()
  73. {
  74. return this.mHateSystem;
  75. }
  76. protected override void OnBackToOrgin()
  77. {
  78. //DoUnitStateReset();
  79. base.OnBackToOrgin();
  80. }
  81. public void AddEnemy(InstanceUnit target)
  82. {
  83. base.onAddEnemy(target, false, AttackReason.Look);
  84. }
  85. public override void doSomething()
  86. {
  87. base.doSomething();
  88. }
  89. public override bool IsMonster { get { return true; } }
  90. protected override void updateBackToOrgin()
  91. {
  92. if (mBackToPosition != null)
  93. {
  94. if (mBackToPosition.IsDone)
  95. {
  96. mBackToPosition = null;
  97. }
  98. }
  99. if (mGuardRangeLimit > mGuardRange)
  100. {
  101. //if (mCheckInGuardLimit.Update(Parent.UpdateIntervalMS))
  102. if (mNextCheckGuardLimit != null && mNextCheckGuardLimit.IsTrigger())
  103. {
  104. //怪物会原地警戒
  105. float mGuardRangeLimitTemp = mGuardRangeLimit + 1.5f;
  106. if (!CMath.includeRoundPoint(X, Y, mGuardRangeLimitTemp, mOrginPosition.X, mOrginPosition.Y))
  107. {
  108. mHateSystem.forceRemoveAtkTraget();
  109. //Console.WriteLine(" - - backToOrgin - 1 " + this.Info.Name);
  110. //在自己的攻击范围内,找仇恨,目标
  111. if(mHateSystem.updateHateList(mGuardRangeLimit, mOrginPosition) <= 0)
  112. {
  113. backToOrgin();
  114. }
  115. else
  116. {
  117. //boss寻找下一个攻击目标
  118. mTracingTarget = null;
  119. InstanceUnit unit = mHateSystem.GetHated();
  120. if (unit is InstancePlayer)
  121. {
  122. }
  123. followAndAttack(mHateSystem.GetHated(), AttackReason.Look);
  124. }
  125. //mHateSystem.print();
  126. }
  127. else if (mTracingTarget != null)
  128. {
  129. if (!mTracingTarget.IsActive || !CMath.intersectRound(
  130. X, Y, mGuardRangeLimit,
  131. mTracingTarget.TargetUnit.X,
  132. mTracingTarget.TargetUnit.Y,
  133. mTracingTarget.TargetUnit.BodyHitSize))
  134. {
  135. //Console.WriteLine(" - - backToOrgin - 2 " + this.Info.Name);
  136. mHateSystem.Remove(mTracingTarget.TargetUnit);
  137. if(mHateSystem.getHateSize() <= 0)
  138. {
  139. backToOrgin();
  140. }else
  141. {
  142. //boss寻找下一个攻击目标
  143. mTracingTarget = null;
  144. followAndAttack(mHateSystem.GetHated(), AttackReason.Look);
  145. }
  146. return;
  147. }
  148. }
  149. }
  150. }
  151. }
  152. protected virtual void updateIdle()
  153. {
  154. //不能移动单位,也不游荡
  155. if (CurrentActionStatus == UnitActionStatus.Idle && this.Moveable &&
  156. (this.Virtual as XmdsVirtual).CombatState == BattleStatus.None)
  157. {
  158. if (mIdleMoveHoldTime != null && mIdleMoveHoldTime.Update(Parent.UpdateIntervalMS))
  159. {
  160. //发呆时间.
  161. mIdleMoveHoldTime.Reset(Parent.RandomN.Next(mWanderConfig.MinHoldTimeMS, mWanderConfig.MaxHoldTimeMS));
  162. //游荡时间、游荡范围.
  163. idleMove(Parent.RandomN.Next(mWanderConfig.MinMoveTimeMS, mWanderConfig.MaxMoveTimeMS), mWanderConfig.WanderRange);
  164. }
  165. }
  166. }
  167. public override void guardInPosition(Vector2 pos)
  168. {
  169. if (this.IsDead() == false)
  170. {
  171. DoUnitStateReset();
  172. }
  173. if (CurrentState is StateIdleMove && pos == mOrginPosition)
  174. {
  175. // 浪切换到发呆,别回原点 //
  176. base.guardInPosition(new Vector2(X, Y));
  177. }
  178. else
  179. {
  180. base.guardInPosition(pos);
  181. }
  182. }
  183. //怪物返回原点时,状态重置.
  184. private void DoUnitStateReset()
  185. {
  186. var v = this.Virtual as XmdsVirtual_Monster;
  187. if (v != null)
  188. {
  189. v.DoUnitStateReset();
  190. }
  191. }
  192. public void SetGuardRange(float r)
  193. {
  194. if (mViewTrigger is ViewTriggerRoundBody)
  195. {
  196. mGuardRange = r;
  197. (mViewTrigger as ViewTriggerRoundBody).SetLookRange(r);
  198. }
  199. }
  200. protected override void onNewStateBeginChange(State old_state, ref State new_state)
  201. {
  202. if (new_state is StateBackToPosition)
  203. {
  204. if(this.Info.Attributes != null && this.Info.Attributes.Length > 0)
  205. {
  206. //特殊的怪物不回血, 如要特殊处理,初始化就弄
  207. // String par = this.Info.Attributes[0];
  208. // if (par.Equals("noRecover"))
  209. {
  210. this.clearBuffs();
  211. }
  212. }
  213. else
  214. {
  215. //回血.
  216. this.AddHP(this.MaxHP, null);
  217. this.AddMP(this.MaxMP, null);
  218. this.Virtual.StartRecoverMP(true);
  219. //去BUFF.
  220. this.clearBuffs();
  221. }
  222. }
  223. base.onNewStateBeginChange(old_state, ref new_state);
  224. }
  225. public override BuffState AddBuff(BuffTemplate buff, InstanceUnit sender, int pointMaxOverLayer = 0, bool forever = false, bool bMaxOverlayer = false,
  226. int buffExt = 0, bool isControlBuf = false, bool bMaxRest = false, int addLayers = 0)
  227. {
  228. if (!buff.forceAdd && this.Virtual.IsBoss() && XmdsInstanceUtils.IsControlBuff_Monster(buff))//BOSS不吃控制
  229. {
  230. return null;
  231. }
  232. return base.AddBuff(buff, sender, pointMaxOverLayer, forever, bMaxOverlayer, buffExt, isControlBuf, bMaxRest, addLayers);
  233. }
  234. public override void InitSkills(LaunchSkill baseSkill, params LaunchSkill[] skills)
  235. {
  236. if (this.Virtual == null ||
  237. (this.Virtual as XmdsVirtual).IsFinishSkillInit() == false)
  238. {
  239. return;
  240. }
  241. base.InitSkills(baseSkill, skills);
  242. }
  243. protected SkillState GetAvailableSkillExceptDefaultSkill()
  244. {
  245. SkillState ret = null;
  246. List<SkillState> list = SkillStatus as List<SkillState>;
  247. for (int si = list.Count - 1; si >= 0; --si)
  248. {
  249. SkillState sst = list[si];
  250. if (DefaultSkill != null && sst.Data.ID != DefaultSkill.ID)
  251. {
  252. if (!sst.IsCD && sst.IsActive && sst.IsDone)
  253. {
  254. ret = sst;
  255. break;
  256. }
  257. }
  258. }
  259. return ret;
  260. }
  261. public override void guard()
  262. {
  263. if (IsNoneSkill)
  264. {
  265. mTracingTarget = null;
  266. base.startIdle();
  267. return;
  268. }
  269. if (this.Info.GuardRange > 0)
  270. {
  271. InstanceUnit min = null;
  272. float min_len = float.MaxValue;
  273. bool isSpecial = false;
  274. bool iamSpecial = Info.Properties is XmdsUnitProperties myprop && myprop.GameStatusType > XmdsUnitProperties.StatusType.Normal;
  275. float guardRangSqua = mGuardRange * mGuardRange;
  276. Parent.ForEachNearObjects(this.X, this.Y, this.Info.GuardRange, (InstanceUnit u, ref bool cancel) =>
  277. {
  278. float len = MathVector.getDistanceSquare(u.X, u.Y, this.X, this.Y);
  279. if (len > guardRangSqua)
  280. {
  281. return;
  282. }
  283. if (!Parent.IsAttackable(this, u, SkillTemplate.CastTarget.Enemy, AttackReason.Look, Info))
  284. {
  285. return;
  286. }
  287. if (iamSpecial && u.Info.Properties is XmdsUnitProperties prop && prop.GameStatusType > XmdsUnitProperties.StatusType.Normal)
  288. {
  289. if (isSpecial)
  290. {
  291. if (len < min_len)
  292. {
  293. min = u;
  294. min_len = len;
  295. }
  296. }
  297. else
  298. {
  299. min = u;
  300. min_len = len;
  301. isSpecial = true;
  302. }
  303. }
  304. else if (!isSpecial && min_len > len)
  305. {
  306. min_len = len;
  307. min = u;
  308. }
  309. });
  310. if (min != null)
  311. {
  312. changeState(new StateFollowAndAttack(this, min, SkillTemplate.CastTarget.Enemy));
  313. return;
  314. }
  315. }
  316. base.guard();
  317. }
  318. public override bool tryLaunchRandomSkillAndCancelCurrentSkill(InstanceUnit target, bool autoFocusNearTarget = false)
  319. {
  320. //自动战斗不允许中断当前技能施放.
  321. return false;
  322. }
  323. protected override void onResetAI()
  324. {
  325. mTracingTarget = null;
  326. doSomething();
  327. }
  328. protected override void Disposing()
  329. {
  330. mIdleMoveHoldTime = null;
  331. mWanderConfig = null;
  332. base.Disposing();
  333. }
  334. protected override void doHitAttack(InstanceUnit attacker, AttackSource source)
  335. {
  336. base.doHitAttack(attacker, source);
  337. if (IsDead() && source.OutClientState == (int)UnitHitEventState.Crit && this.Weight < XmdsConstConfig.DEFAULT_WEIGHT
  338. && source.Attack.killHitMove!=null && source.Attack.killHitMove.enable)
  339. {
  340. HitMoveType moveType = source.Attack.killHitMove.moveType;
  341. changeState(new StateDeadFuckFuck(this, source, attacker, moveType), true);
  342. }
  343. }
  344. protected override void onBack2PositionStart()
  345. {
  346. (this.Virtual as XmdsVirtual_Monster).changeRunSpeed4back();
  347. }
  348. protected override void onBack2PositionEnd()
  349. {
  350. (this.Virtual as XmdsVirtual_Monster).onBack2PositionEnd();
  351. }
  352. protected override void onAddEnemy(InstanceUnit target, bool group, AttackReason reason)
  353. {
  354. var state = CurrentState;
  355. InstanceUnit nowTarget = null;
  356. if (state is StateFollowAndAttack attackstate)
  357. {
  358. nowTarget = attackstate.TargetUnit;
  359. }
  360. else if(state is StateSkill skillstate)
  361. {
  362. nowTarget = skillstate.TargetUnit;
  363. }
  364. //当前正在追踪/攻击一个价值更高的目标时,不理会小啰啰的攻击
  365. if (nowTarget != null && nowTarget.Info.Properties is XmdsUnitProperties prop && prop.GameStatusType > XmdsUnitProperties.StatusType.Normal)
  366. {
  367. if(target.Info.Properties is XmdsUnitProperties propnew && propnew.GameStatusType > prop.GameStatusType)
  368. {
  369. }
  370. else
  371. {
  372. return;
  373. }
  374. }
  375. base.onAddEnemy(target, group, reason);
  376. }
  377. }
  378. }