ZoneObject.Spell.cs 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869
  1. using CommonAI.RTS;
  2. using CommonLang.Vector;
  3. using CommonAI.Zone;
  4. using CommonAI.Zone.Helper;
  5. using CommonLang;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using System.Text;
  10. using CommonLang.Log;
  11. namespace CommonAI.ZoneClient
  12. {
  13. public class ZoneSpell : ZoneObject
  14. {
  15. public readonly SpellTemplate Info;
  16. public override string Name { get { return null; } }
  17. public override string DisplayName { get { return Info.Name; } }
  18. public override float X { get { return mLocalPos.X; } }
  19. public override float Y { get { return mLocalPos.Y; } }
  20. public override float Z { get { return mLocal_Z; } }
  21. public override float RadiusSize { get { return mDisplaySize; } }
  22. public ZoneObject Sender { get; internal set; }
  23. public ZoneUnit Launcher { get; internal set; }
  24. public ZoneUnit Target { get; internal set; }
  25. public Vector2 TargetPos { get; internal set; }
  26. public Vector2 StartPos { get { return mStartPos; } }
  27. public float LaunchHeight { get { return mStartHeight; } set { this.mStartHeight = value; this.mLocal_Z = value; } }
  28. public float BodySize { get { return mDisplaySize; } }
  29. public float Distance { get { return mDisplayDistance; } }
  30. public int PassTimeMS { get { return mPassTimeMS; } }
  31. private Vector2 mLocalPos = new Vector2();
  32. private float mLocal_Z = 0;
  33. private float mSizeLimit, mDisplaySize;
  34. private float mDistanceLimit, mDisplayDistance;
  35. private Vector2 mStartPos = new Vector2();
  36. private float mStartDirection;
  37. private float mStartHeight;
  38. private int mPassTimeMS;
  39. private float mSpeed;
  40. private float mMoveDistance;
  41. private int mCurveMissileIndex = -1;
  42. private PopupKeyFrames<SpellTemplate.KeyFrame> mKeyFrames;
  43. private TimeInterval<SpellTemplate.KeyFrame> mHitIntervalTicker;
  44. private AddSpellEvent mAddEvent;
  45. public System.Action OnTargetChanged = null;
  46. private static HashMap<string, int> hashCurveMissileCnt = new HashMap<string, int>();
  47. private string strCurveMissileIndexKey;
  48. public ZoneSpell(SpellTemplate info, SyncSpellInfo syn, ZoneLayer parent, AddSpellEvent add)
  49. : base(syn.ObjectID, parent)
  50. {
  51. this.Info = info;
  52. this.mStartPos.SetX(syn.x);
  53. this.mStartPos.SetY(syn.y);
  54. this.mPos.SetX(syn.x);
  55. this.mPos.SetY(syn.y);
  56. this.mLocalPos.SetX(syn.x);
  57. this.mLocalPos.SetY(syn.y);
  58. this.mDirection = this.mStartDirection = syn.direction;
  59. this.mDistanceLimit = this.mDisplayDistance = info.Distance;
  60. this.mSizeLimit = this.mDisplaySize = info.BodySize;
  61. this.mPassTimeMS = 0;
  62. this.mAddEvent = add;
  63. if (add != null && add.IsHeight)
  64. {
  65. this.mLocal_Z = add.height;
  66. }
  67. this.mKeyFrames = new PopupKeyFrames<SpellTemplate.KeyFrame>();
  68. this.mKeyFrames.AddRange(info.KeyFrames);
  69. this.mHitIntervalTicker = new TimeInterval<SpellTemplate.KeyFrame>(info.HitIntervalMS);
  70. this.mHitIntervalTicker.Tag = info.HitIntervalKeyFrame;
  71. this.mSpeed = info.MSpeedSEC;
  72. this.mMoveDistance = 0;
  73. if (syn.HasSpeed)
  74. {
  75. this.mSpeed = syn.CurSpeed;
  76. }
  77. if(info.MType == SpellTemplate.MotionType.CurveMissile)
  78. {
  79. int cnt;
  80. strCurveMissileIndexKey = add.sender_unit_id.ToString() + ":" + info.TemplateID.ToString();
  81. if (hashCurveMissileCnt.TryGetValue(strCurveMissileIndexKey, out cnt))
  82. {
  83. hashCurveMissileCnt[strCurveMissileIndexKey] = ++cnt;
  84. }
  85. else
  86. {
  87. hashCurveMissileCnt.Add(strCurveMissileIndexKey, 1);
  88. cnt = 1;
  89. }
  90. mCurveMissileIndex = cnt-1;
  91. }
  92. }
  93. protected override void Disposing()
  94. {
  95. if (!string.IsNullOrEmpty(strCurveMissileIndexKey))
  96. {
  97. int cnt;
  98. if (hashCurveMissileCnt.TryGetValue(strCurveMissileIndexKey, out cnt))
  99. {
  100. if (cnt <= 1)
  101. {
  102. hashCurveMissileCnt.Remove(strCurveMissileIndexKey);
  103. }
  104. else
  105. {
  106. hashCurveMissileCnt[strCurveMissileIndexKey] = cnt - 1;
  107. }
  108. }
  109. }
  110. base.Disposing();
  111. }
  112. protected internal override void OnAdded()
  113. {
  114. base.OnAdded();
  115. float radius = 0;
  116. if (mAddEvent != null)
  117. {
  118. if (mAddEvent.LaunchData.FromUnitBody && Sender != null && (Sender is ZoneUnit))
  119. {
  120. radius = (Sender as ZoneUnit).Info.LaunchSpellRadius;
  121. }
  122. else
  123. {
  124. radius = mAddEvent.LaunchData.LaunchSpellRadius;
  125. }
  126. }
  127. if (!Info.IsLaunchSpellEventSyncPos)
  128. {
  129. switch (Info.MType)
  130. {
  131. case SpellTemplate.MotionType.SelectTarget:
  132. if (Target != null)
  133. {
  134. mStartPos.SetX(Target.X);
  135. mStartPos.SetY(Target.Y);
  136. mLocal_Z = Target.Z;
  137. mStartDirection = Target.ServerDirection;
  138. }
  139. MathVector.movePolar(mStartPos, mStartDirection, radius);
  140. break;
  141. case SpellTemplate.MotionType.SelectLauncher:
  142. if (Launcher != null)
  143. {
  144. mStartPos.SetX(Launcher.X);
  145. mStartPos.SetY(Launcher.Y);
  146. mLocal_Z = Launcher.Z;
  147. mStartDirection = Launcher.ServerDirection;
  148. }
  149. MathVector.movePolar(mStartPos, mStartDirection, radius);
  150. break;
  151. case SpellTemplate.MotionType.Chain:
  152. if (Sender != null)
  153. {
  154. mStartPos.SetX(Sender.X);
  155. mStartPos.SetY(Sender.Y);
  156. mLocal_Z = Sender.Z;
  157. }
  158. break;
  159. case SpellTemplate.MotionType.AOE_Binding:
  160. case SpellTemplate.MotionType.Binding:
  161. if (Sender != null)
  162. {
  163. mStartPos.SetX(Sender.X);
  164. mStartPos.SetY(Sender.Y);
  165. mLocal_Z = Sender.Z;
  166. }
  167. break;
  168. case SpellTemplate.MotionType.AOE_BindingTarget:
  169. case SpellTemplate.MotionType.BindingTarget:
  170. if (Target != null)
  171. {
  172. mStartPos.SetX(Target.X);
  173. mStartPos.SetY(Target.Y);
  174. mLocal_Z = Target.Z;
  175. }
  176. break;
  177. }
  178. this.mPos.SetX(this.mStartPos.X);
  179. this.mPos.SetY(this.mStartPos.Y);
  180. this.mLocalPos.SetX(this.mStartPos.X);
  181. this.mLocalPos.SetY(this.mStartPos.Y);
  182. this.mDirection = this.mStartDirection;
  183. }
  184. if (Info.TargetEffect != null)
  185. {
  186. if (Target != null)
  187. {
  188. Parent.PreQueueEvent(new UnitEffectEvent(Target.ObjectID, Info.TargetEffect));
  189. }
  190. else if (TargetPos != null)
  191. {
  192. Parent.PreQueueEvent(new AddEffectEvent(0,TargetPos.X, TargetPos.Y, mDirection, Info.TargetEffect));
  193. }
  194. }
  195. }
  196. public override void ForceSyncPos(float x, float y)
  197. {
  198. this.mPos.SetX(x);
  199. this.mPos.SetY(y);
  200. this.mLocalPos.SetX(x);
  201. this.mLocalPos.SetY(y);
  202. }
  203. internal protected override void DoEvent(ObjectEvent e)
  204. {
  205. if (e is SpellLockTargetEvent)
  206. {
  207. doSpellLockTargetEvent(e as SpellLockTargetEvent);
  208. }
  209. else if (e is ObjectForceSyncPosEvent)
  210. {
  211. var oe = e as ObjectForceSyncPosEvent;
  212. this.ForceSyncPos(oe.X, oe.Y);
  213. this.Direction = oe.Direction;
  214. }
  215. }
  216. private void doSpellLockTargetEvent(SpellLockTargetEvent e)
  217. {
  218. if (Parent == null)
  219. {
  220. log.Error("doSpellLockTargetEvent -> Parent == null");
  221. }
  222. if (Info == null)
  223. {
  224. log.Error("doSpellLockTargetEvent -> Info == null");
  225. }
  226. if (e == null)
  227. {
  228. log.Error("doSpellLockTargetEvent -> e == null");
  229. }
  230. this.Target = Parent.GetUnit(e.target_obj_id);
  231. if(OnTargetChanged != null)
  232. {
  233. OnTargetChanged();
  234. }
  235. switch (Info.MType)
  236. {
  237. case SpellTemplate.MotionType.SeekerSelectTarget:
  238. if (Target != null)
  239. {
  240. this.mLocalPos.SetX(Target.X);
  241. this.mLocalPos.SetY(Target.Y);
  242. this.mLocal_Z = Target.Z;
  243. }
  244. break;
  245. }
  246. }
  247. protected internal override void UpdateAI()
  248. {
  249. }
  250. internal protected override void Update()
  251. {
  252. int intervalMS = Parent.CurrentIntervalMS;
  253. mPassTimeMS += intervalMS;
  254. //法术位置更新交给战斗服
  255. /*if (Parent.ActorSyncMode != SyncMode.ForceByServer && (Info.MaxMoveDistance == 0 || mMoveDistance < Info.MaxMoveDistance))
  256. {
  257. updateMotion(intervalMS);
  258. }*/
  259. updateZPos();
  260. switch (Info.MType)
  261. {
  262. case SpellTemplate.MotionType.AOE:
  263. case SpellTemplate.MotionType.AOE_Binding:
  264. case SpellTemplate.MotionType.AOE_BindingTarget:
  265. updateAOE(intervalMS);
  266. break;
  267. }
  268. switch (Info.BodyShape)
  269. {
  270. case SpellTemplate.Shape.StripRayTouchEnd:
  271. updateRayTouchEnd();
  272. break;
  273. case SpellTemplate.Shape.LineToStart:
  274. case SpellTemplate.Shape.LineToTarget:
  275. updateLineToTarget();
  276. break;
  277. }
  278. if (Info.IsMoveable && (Info.MaxMoveDistance == 0 || mMoveDistance < Info.MaxMoveDistance))
  279. {
  280. MoveHelper.UpdateSpeed(intervalMS, ref mSpeed, Info.MSpeedAdd, Info.MSpeedAcc);
  281. MoveHelper.UpdateMoveDistance(intervalMS, ref mMoveDistance, mSpeed);
  282. }
  283. updateKeyFrames();
  284. }
  285. public override void SyncPos(ref SyncPosEvent.UnitPos pos)
  286. {
  287. base.SyncPos(ref pos);
  288. if (Parent.ActorSyncMode == SyncMode.ForceByServer)
  289. {
  290. mLocalPos.SetX(pos.X);
  291. mLocalPos.SetY(pos.Y);
  292. if (Parent.IsSyncZ) { this.Z = pos.Z; }
  293. }
  294. }
  295. //-----------------------------------------------------------------------
  296. #region _UpdateMotions_
  297. float foxfireRoundAngle = 0f;
  298. float foxfireSeekWait = 0f;
  299. private Logger log = LoggerFactory.GetLogger("ZoneClient");
  300. /// <summary>
  301. /// 更新移动行为
  302. /// </summary>
  303. private void updateMotion(int intervalMS)
  304. {
  305. float speed_distance = MoveHelper.GetDistance(intervalMS, mSpeed);
  306. try
  307. {
  308. switch (Info.MType)
  309. {
  310. case SpellTemplate.MotionType.SelectLauncher:
  311. case SpellTemplate.MotionType.SelectTarget:
  312. break;
  313. case SpellTemplate.MotionType.Cannon:
  314. case SpellTemplate.MotionType.Straight:
  315. MathVector.movePolar(mLocalPos, mStartDirection, speed_distance);
  316. break;
  317. case SpellTemplate.MotionType.StraightAndStop:
  318. if (PassTimeMS < Info.BoomerangFlyTime)
  319. {
  320. MathVector.movePolar(mLocalPos, mStartDirection, speed_distance);
  321. }
  322. //else if (PassTimeMS > Info.BoomerangFlyTime + Info.BoomerangHangtime)
  323. //{
  324. // PreFlyTo(Sender.X, Sender.Y, mSpeed * 1.8f, intervalMS);
  325. //}
  326. break;
  327. case SpellTemplate.MotionType.Boomerang1:
  328. if (PassTimeMS < Info.BoomerangFlyTime)
  329. {
  330. MathVector.movePolar(mLocalPos, mStartDirection, speed_distance);
  331. }
  332. else if (Sender != null && PassTimeMS > Info.BoomerangFlyTime + Info.BoomerangHangtime)
  333. {
  334. PreFlyTo(Sender.X, Sender.Y, mSpeed * 1.4f, intervalMS);
  335. }
  336. break;
  337. case SpellTemplate.MotionType.Boomerang2:
  338. if (PassTimeMS < Info.BoomerangFlyTime)
  339. {
  340. MathVector.movePolar(mLocalPos, mStartDirection, speed_distance);
  341. }
  342. else if (PassTimeMS > Info.BoomerangFlyTime + Info.BoomerangHangtime)
  343. {
  344. PreFlyTo(mStartPos.X, mStartPos.Y, mSpeed * 1.4f, intervalMS);
  345. }
  346. break;
  347. case SpellTemplate.MotionType.Immovability:
  348. case SpellTemplate.MotionType.AOE:
  349. mLocalPos.SetX(mPos.X);
  350. mLocalPos.SetY(mPos.Y);
  351. break;
  352. case SpellTemplate.MotionType.AOE_Binding:
  353. case SpellTemplate.MotionType.Binding:
  354. if (Sender != null)
  355. {
  356. updateBinding(Sender.X, Sender.Y, Sender.Direction, intervalMS);
  357. }
  358. else
  359. {
  360. adjustPos(speed_distance);
  361. }
  362. break;
  363. case SpellTemplate.MotionType.AOE_BindingTarget:
  364. case SpellTemplate.MotionType.BindingTarget:
  365. if (Target != null)
  366. {
  367. updateBinding(Target.X, Target.Y, Target.Direction, intervalMS);
  368. }
  369. else
  370. {
  371. adjustPos(speed_distance);
  372. }
  373. break;
  374. case SpellTemplate.MotionType.Missile:
  375. case SpellTemplate.MotionType.MissileAttackRoute:
  376. if (Target != null)
  377. {
  378. if (Info.RotateSpeedSEC == 0)
  379. {
  380. PreFaceTo(Target.X, Target.Y);
  381. }
  382. PreFlyTo(Target.X, Target.Y, mSpeed, intervalMS);
  383. }
  384. else
  385. {
  386. MathVector.movePolar(mLocalPos, mStartDirection, speed_distance);
  387. }
  388. break;
  389. case SpellTemplate.MotionType.SeekerMissile:
  390. if (Target != null)
  391. {
  392. if (Info.SeekingTurningAngleSEC != 0)
  393. {
  394. FlyToTargetTunning(Target.X, Target.Y, mSpeed, Info.SeekingTurningAngleSEC, intervalMS);
  395. }
  396. else
  397. {
  398. PreFaceTo(Target.X, Target.Y);
  399. PreFlyTo(Target.X, Target.Y, mSpeed, intervalMS);
  400. }
  401. }
  402. else
  403. {
  404. MathVector.movePolar(mLocalPos, mStartDirection, speed_distance);
  405. }
  406. break;
  407. case SpellTemplate.MotionType.SeekerSelectTarget:
  408. break;
  409. case SpellTemplate.MotionType.Chain:
  410. if (Sender != null && Sender.IsEnable && Target != null && Target.IsActive)
  411. {
  412. mLocalPos.SetX(Sender.X);
  413. mLocalPos.SetY(Sender.Y);
  414. PreFaceTo(Target.X, Target.Y);
  415. }
  416. break;
  417. case SpellTemplate.MotionType.CurveMissile:
  418. IPosBase targetPos = Target == null ? (IPosBase)TargetPos : (IPosBase)Target;
  419. if(targetPos == null)
  420. {
  421. PreFlyTo(mStartDirection, mSpeed, intervalMS);
  422. }
  423. else if (Info.SeekingTurningAngleSEC != 0)
  424. {
  425. FlyToTargetTunning(targetPos.X, targetPos.Y, mSpeed, Info.SeekingTurningAngleSEC, intervalMS);
  426. }
  427. else
  428. {
  429. PreFaceTo(targetPos.X, targetPos.Y);
  430. PreFlyTo(targetPos.X, targetPos.Y, mSpeed, intervalMS);
  431. }
  432. break;
  433. case SpellTemplate.MotionType.Foxfire:
  434. if (Target == null)
  435. {
  436. var mLaunchData = mAddEvent.LaunchData;
  437. foxfireRoundAngle = mStartDirection + PassTimeMS * 0.001f * 3;
  438. var x = (float)(Math.Cos(foxfireRoundAngle + 0.3f) * mLaunchData.LaunchSpellRadius);
  439. var y = (float)(Math.Sin(foxfireRoundAngle + 0.3f) * mLaunchData.LaunchSpellRadius);
  440. if (Sender != null)
  441. {
  442. x = Sender.X + x;
  443. y = Sender.Y + y;
  444. }
  445. else
  446. {
  447. x = mStartPos.X + x;
  448. y = mStartPos.Y + y;
  449. }
  450. PreFlyTo(x, y, mSpeed, intervalMS);
  451. if (Info.RotateSpeedSEC == 0)
  452. {
  453. PreFaceTo(foxfireRoundAngle + (float)Math.PI * 0.25f);
  454. }
  455. foxfireSeekWait += intervalMS;
  456. }
  457. else
  458. {
  459. if (Info.SeekingTurningAngleSEC != 0)
  460. {
  461. FlyToTargetTunning(Target.X, Target.Y, mSpeed, Info.SeekingTurningAngleSEC, intervalMS);
  462. }
  463. else
  464. {
  465. PreFaceTo(Target.X, Target.Y);
  466. PreFlyTo(Target.X, Target.Y, mSpeed, intervalMS);
  467. }
  468. }
  469. break;
  470. }
  471. if (Info.BodyShape == SpellTemplate.Shape.LineToTarget)
  472. {
  473. if (Target != null)
  474. {
  475. PreFaceTo(Target.X, Target.Y);
  476. }
  477. }
  478. else if (Info.BodyShape == SpellTemplate.Shape.LineToStart)
  479. {
  480. PreFaceTo(StartPos.X, StartPos.Y);
  481. }
  482. else if (Info.RotateSpeedSEC != 0 && Info.MType != SpellTemplate.MotionType.SeekerMissile)
  483. {
  484. this.mDirection += MoveHelper.GetDistance(intervalMS, Info.RotateSpeedSEC);
  485. }
  486. }
  487. catch (Exception e) {
  488. log.Error(e.Message + "\n" + "Info.MType = " + Info.MType + " Info.BodyShape = " + Info.BodyShape);
  489. }
  490. }
  491. private void updateZPos()
  492. {
  493. switch (Info.MType)
  494. {
  495. case SpellTemplate.MotionType.Immovability:
  496. case SpellTemplate.MotionType.SelectTarget:
  497. case SpellTemplate.MotionType.SelectLauncher:
  498. case SpellTemplate.MotionType.AOE:
  499. updateFloatingZ(mStartHeight);
  500. break;
  501. case SpellTemplate.MotionType.Straight:
  502. case SpellTemplate.MotionType.Boomerang1:
  503. case SpellTemplate.MotionType.Boomerang2:
  504. case SpellTemplate.MotionType.StraightAndStop:
  505. updateFloatingZ(mStartHeight);
  506. break;
  507. case SpellTemplate.MotionType.AOE_Binding:
  508. case SpellTemplate.MotionType.Binding:
  509. if (Sender != null)
  510. {
  511. this.mLocal_Z = Sender.Z;
  512. }
  513. break;
  514. case SpellTemplate.MotionType.AOE_BindingTarget:
  515. case SpellTemplate.MotionType.BindingTarget:
  516. if (Target != null)
  517. {
  518. this.mLocal_Z = Target.Z;
  519. }
  520. break;
  521. case SpellTemplate.MotionType.Cannon:
  522. if (TargetPos != null)
  523. {
  524. updateTargetZ(TargetPos, 0);
  525. }
  526. break;
  527. case SpellTemplate.MotionType.Missile:
  528. case SpellTemplate.MotionType.SeekerMissile:
  529. case SpellTemplate.MotionType.MissileAttackRoute:
  530. if (Target != null)
  531. {
  532. updateTargetZ(new TVector2(Target.X, Target.Y), Target.Z + Target.Info.BodyHeight * 0.6f);
  533. }
  534. break;
  535. case SpellTemplate.MotionType.CurveMissile:
  536. if (Target != null)
  537. {
  538. updata3DParabola(new TVector2(Target.X, Target.Y));
  539. }
  540. break;
  541. }
  542. }
  543. private void updata3DParabola(IVector2 targetPos)
  544. {
  545. TVector2 nowPos = new TVector2(mLocalPos.X, mLocalPos.Y);
  546. TVector2 vcStart = new TVector2(mStartPos.X, mStartPos.Y);
  547. TVector2 vcEnd = new TVector2(targetPos.X, targetPos.Y);
  548. TVector2 v1 = nowPos - vcStart;
  549. TVector2 v2 = vcEnd - vcStart;
  550. float a = (float)Math.Atan2(v1.Y, v1.X);
  551. float b = (float)Math.Atan2(v2.Y, v2.X);
  552. if (float.Equals(a, b) || float.Equals(Math.PI, Math.Abs(a - b)))
  553. {
  554. mLocal_Z = Target.Z;
  555. }
  556. else
  557. {
  558. float dis = nowPos.DistanceTo(vcStart) * (float)Math.Abs(Math.Sin(a - b));
  559. mLocal_Z = this.mStartHeight + dis *1.6f* (float)Math.Sin(Math.PI / 6 * mCurveMissileIndex);
  560. //ClientLog.LogWarning(">z:{0}, index:{1}, ({2},{3})->({4},{5})->({6},{7})", mLocal_Z, mCurveMissileIndex, mStartPos.X, mStartPos.Y, TargetPos.X, targetPos.Y, nowPos.X, nowPos.Y);
  561. }
  562. }
  563. /// <summary>
  564. /// 计算有固定目标Z坐标
  565. /// </summary>
  566. /// <param name="targetPos"></param>
  567. /// <param name="targetZ"></param>
  568. private void updateTargetZ(IVector2 targetPos, float targetZ)
  569. {
  570. float fdis = MathVector.getDistance(mStartPos, targetPos);
  571. float odis = MathVector.getDistance(mStartPos, mLocalPos);
  572. float pct = CMath.getInRange((fdis == 0 ? 0 : (odis / fdis)), 0, 1);//生命周期百分比//
  573. float dz = CMath.getMiddleValue(pct, mStartHeight, targetZ);//和目标高度差//
  574. float ph = 0;//抛物线相对高度//
  575. if (Info.ParabolaHeight != 0)
  576. {
  577. //计算抛物线//
  578. ph = (float)Math.Sin(pct * CMath.PI_F) * Info.ParabolaHeight;
  579. }
  580. this.mLocal_Z = dz + ph;
  581. }
  582. private void updateFloatingZ(float targetZ)
  583. {
  584. float pct = (float)mPassTimeMS / (float)Info.LifeTimeMS;//生命周期百分比//
  585. float dz = CMath.getMiddleValue(pct, mStartHeight, targetZ);//和目标高度差//
  586. float ph = 0;//抛物线相对高度//
  587. if (Info.ParabolaHeight != 0)
  588. {
  589. //计算抛物线//
  590. ph = (float)Math.Sin(pct * CMath.PI_F) * Info.ParabolaHeight;
  591. }
  592. this.mLocal_Z = dz + ph;
  593. }
  594. private void updateBinding(float x, float y, float direction, int intervalMS)
  595. {
  596. if (Info.IsBindingDirection)
  597. {
  598. mDirection = direction;
  599. }
  600. if (Info.IsBindingOrbit)
  601. {
  602. float dadd = Info.OrbitDistance;
  603. float ox = (float)Math.Cos(Direction) * dadd;
  604. float oy = (float)Math.Sin(Direction) * dadd;
  605. mLocalPos.SetX(x + ox);
  606. mLocalPos.SetY(y + oy);
  607. }
  608. else
  609. {
  610. mLocalPos.SetX(x);
  611. mLocalPos.SetY(y);
  612. }
  613. }
  614. #endregion
  615. //---------------------------------------------------------------------------------------------------
  616. #region _UpdateShape_
  617. private void updateAOE(int intervalMS)
  618. {
  619. switch (Info.BodyShape)
  620. {
  621. case SpellTemplate.Shape.LineToTarget:
  622. case SpellTemplate.Shape.LineToStart:
  623. case SpellTemplate.Shape.Strip:
  624. case SpellTemplate.Shape.StripRay:
  625. case SpellTemplate.Shape.StripRayTouchEnd:
  626. case SpellTemplate.Shape.RectStrip:
  627. case SpellTemplate.Shape.RectStripRay:
  628. updateAoeMotion(intervalMS, Info.Distance, ref mDistanceLimit);
  629. mDisplayDistance = mDistanceLimit;
  630. break;
  631. default:
  632. updateAoeMotion(intervalMS, Info.BodySize, ref mSizeLimit);
  633. mDisplaySize = mSizeLimit;
  634. break;
  635. }
  636. }
  637. private void updateAoeMotion(int intervalMS, float base_value, ref float value)
  638. {
  639. switch (Info.AOEMType)
  640. {
  641. case SpellTemplate.AoeMotionType.Sine:
  642. value = (float)Math.Sin(CMath.PI_F * mPassTimeMS / (float)Info.LifeTimeMS) * base_value;
  643. break;
  644. case SpellTemplate.AoeMotionType.Linear:
  645. default:
  646. value += MoveHelper.GetDistance(intervalMS, mSpeed);
  647. break;
  648. }
  649. }
  650. private void updateRayTouchEnd()
  651. {
  652. if (Launcher != null)
  653. {
  654. float d_width = Info.RectWide / 2f;
  655. Vector2 p1 = new Vector2(X, Y);
  656. MathVector.movePolar(p1, this.Direction, this.mDistanceLimit);
  657. using (var list = ListObjectPool<ZoneUnit>.AllocAutoRelease())
  658. {
  659. Parent.ForEachNearObjectsRect(this.X, this.Y, p1.X, p1.Y, (ZoneObject u, ref bool cancel) =>
  660. {
  661. if ((u is ZoneUnit))
  662. {
  663. ZoneUnit zu = u as ZoneUnit;
  664. if (Parent.IsAttackable(Launcher, zu, Info.ExpectTarget))
  665. {
  666. if ((CMath.intersectLineRound(this.X, this.Y, p1.X, p1.Y, zu.X, zu.Y, d_width + zu.BodyHitSize)))
  667. {
  668. list.Add(u as ZoneUnit);
  669. }
  670. }
  671. }
  672. });
  673. if (list.Count > 0)
  674. {
  675. list.Sort(new ObjectBodySorterNearest<ZoneUnit>(this.X, this.Y, 0));
  676. this.mDisplayDistance = CMath.getDistance(this.X, this.Y, list[0].X, list[0].Y);
  677. this.mDisplayDistance = Math.Min(mDisplayDistance, this.mDistanceLimit);
  678. }
  679. else
  680. {
  681. this.mDisplayDistance = this.mDistanceLimit;
  682. }
  683. }
  684. }
  685. }
  686. private void updateLineToTarget()
  687. {
  688. if (Info.BodyShape == SpellTemplate.Shape.LineToTarget)
  689. {
  690. if (Target != null)
  691. {
  692. this.mDisplayDistance = CMath.getDistance(this.X, this.Y, Target.X, Target.Y);
  693. this.mDisplayDistance = Math.Min(mDisplayDistance, this.mDistanceLimit);
  694. PreFaceTo(Target.X, Target.Y);
  695. }
  696. else
  697. {
  698. this.mDisplayDistance = 0;
  699. }
  700. }
  701. else if (Info.BodyShape == SpellTemplate.Shape.LineToStart)
  702. {
  703. this.mDisplayDistance = CMath.getDistance(this.X, this.Y, mStartPos.X, mStartPos.Y);
  704. this.mDisplayDistance = Math.Min(mDisplayDistance, this.mDistanceLimit);
  705. PreFaceTo(mStartPos.X, mStartPos.Y);
  706. }
  707. else
  708. {
  709. this.mDisplayDistance = 0;
  710. }
  711. }
  712. #endregion
  713. //---------------------------------------------------------------------------------------------------
  714. #region _UpdateKeyFrames_
  715. /// <summary>
  716. /// 更新范围检测以及关键帧
  717. /// </summary>
  718. private void updateKeyFrames()
  719. {
  720. switch (Info.MType)
  721. {
  722. case SpellTemplate.MotionType.Missile:
  723. case SpellTemplate.MotionType.SeekerMissile:
  724. case SpellTemplate.MotionType.Cannon:
  725. case SpellTemplate.MotionType.Chain:
  726. case SpellTemplate.MotionType.CurveMissile:
  727. break;
  728. default:
  729. if (Info.BodyShape == SpellTemplate.Shape.LineToTarget || Info.BodyShape == SpellTemplate.Shape.LineToStart)
  730. {
  731. }
  732. else
  733. {
  734. updateKeyFramesRanged();
  735. }
  736. break;
  737. }
  738. }
  739. private void updateKeyFramesRanged()
  740. {
  741. using (var kfs = ListObjectPool<SpellTemplate.KeyFrame>.AllocAutoRelease())
  742. {
  743. // int kfs_count = mKeyFrames.PopKeyFrames(PassTimeMS, kfs);
  744. bool is_interval_test = mHitIntervalTicker.Update(Parent.CurrentIntervalMS);
  745. //if (kfs_count > 0)
  746. //{
  747. // for (int i = 0; i < kfs.Count; i++)
  748. // {
  749. // if (kfs[i].Effect != null)
  750. // {
  751. // Parent.PreQueueEvent(new UnitEffectEvent(ObjectID, kfs[i].Effect));
  752. // }
  753. // }
  754. //}
  755. if (Info.HitOnExplosion)
  756. {
  757. }
  758. else if (Info.HitIntervalMS == 0)
  759. {
  760. }
  761. else if (is_interval_test)
  762. {
  763. if (Info.HitIntervalKeyFrame != null && Info.HitIntervalKeyFrame.Effect != null)
  764. {
  765. Parent.PreQueueEvent(new UnitEffectEvent(ObjectID, Info.HitIntervalKeyFrame.Effect));
  766. }
  767. }
  768. }
  769. }
  770. #endregion
  771. //---------------------------------------------------------------------------------------------------
  772. private void adjustPos(float min_distance)
  773. {
  774. float fdistance = MathVector.getDistance(mLocalPos, mPos);
  775. if (fdistance < min_distance)
  776. {
  777. MathVector.moveTo(mLocalPos, mPos.X, mPos.Y, min_distance);
  778. }
  779. else
  780. {
  781. MathVector.moveTo(mLocalPos, mPos.X, mPos.Y, fdistance / 2f);
  782. }
  783. }
  784. private void PreFaceTo(float angle)
  785. {
  786. this.mDirection = angle;
  787. }
  788. private void PreFaceTo(float x, float y)
  789. {
  790. if (this.X == x && this.Y == y)
  791. {
  792. return;
  793. }
  794. this.mDirection = (float)(Math.Atan2(y - this.Y, x - this.X));
  795. }
  796. private void PreTurnTo(float add)
  797. {
  798. this.mDirection += add;
  799. }
  800. private void PreFlyTo(float x, float y, float speedSEC, int intervalMS)
  801. {
  802. float distance = MoveHelper.GetDistance(intervalMS, speedSEC);
  803. MathVector.moveTo(mLocalPos, x, y, distance);
  804. }
  805. private void PreFlyTo(float direction, float speedSEC, int intervalMS)
  806. {
  807. float distance = MoveHelper.GetDistance(intervalMS, speedSEC);
  808. float dx = (float)(Math.Cos(direction) * distance);
  809. float dy = (float)(Math.Sin(direction) * distance);
  810. mLocalPos.AddX(dx);
  811. mLocalPos.AddY(dy);
  812. }
  813. public void FlyToTargetTunning(float x, float y, float speedSEC, float tunningSpeedSEC, int intervalMS)
  814. {
  815. MoveHelper.MoveToTargetTunning(ref mLocalPos, ref mDirection, x, y, speedSEC, tunningSpeedSEC, intervalMS);
  816. }
  817. }
  818. }