Triggers.Spawn.cs 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using CommonLang;
  5. using CommonAI.RTS;
  6. using CommonLang.Vector;
  7. using CommonAI.RTS.Manhattan;
  8. using CommonAI.Zone.Helper;
  9. using CommonAI.Data;
  10. namespace CommonAI.Zone.Instance
  11. {
  12. /// <summary>
  13. /// 生成单位的触发器
  14. /// </summary>
  15. public abstract class AbstractSpawnTrigger : Ability
  16. {
  17. public string Name { get; private set; }
  18. private ZoneRegion mAdded = null;
  19. private int mSpawnTimeIntervalMS;
  20. private int mDelayTimeMS = 0;
  21. private int mSpawnOnceCount;
  22. private LaunchEffect mSpawnEffect;
  23. private bool mSpawnWithoutAlive = true;
  24. private bool mResetOnWithoutAlive = false;
  25. private int mTotalSpawnCount = 0;
  26. private int mSpawnIndexer = 0;
  27. private int mLimitedSpawnCount = 0;
  28. private int mLimitedAliveCount = 0;
  29. private HashMap<InstanceZoneObject, InstanceZoneObject> mSpawnedUnits = new HashMap<InstanceZoneObject, InstanceZoneObject>();
  30. private string mUnitTag;
  31. private TimeTaskMS mTimeTask;
  32. private float mStartDirection = float.NaN;
  33. private TeamFormation mTeam;
  34. private TeamFormationGroup mTeamHelper;
  35. //绑定事件
  36. //protected List<String> Events = new List<String>();
  37. //--------------------------------------------------------------------------------------------------
  38. public AbstractSpawnTrigger(InstanceZone zone, string name)
  39. : base(zone)
  40. {
  41. this.Name = name;
  42. }
  43. public InstanceZone BindingZone { get { return mAdded.Parent; } }
  44. public ZoneRegion BindingRegion { get { return mAdded; } }
  45. public int OnceSpawnCount { get { return mSpawnOnceCount; } }
  46. public int LimitedSpawnCount { get { return mLimitedSpawnCount; } }
  47. public int LimitedAliveCount { get { return mLimitedAliveCount; } }
  48. /// <summary>
  49. /// 当前存活数量
  50. /// </summary>
  51. public virtual int AliveCount { get { return mSpawnedUnits.Count; } }
  52. public int SpawnIndexer { get { return mSpawnIndexer; } }
  53. public int TotalSpawnCount { get { return mTotalSpawnCount; } }
  54. public float StartDirection { get { return (!float.IsNaN(mStartDirection)) ? mStartDirection : (float)(Zone.RandomN.NextDouble() * CMath.PI_MUL_2); } }
  55. /// <summary>
  56. /// 是否已完成刷新
  57. /// </summary>
  58. public bool IsSpawnOver
  59. {
  60. get
  61. {
  62. if (mLimitedSpawnCount == 0)
  63. return false;
  64. return (mTotalSpawnCount >= mLimitedSpawnCount);
  65. }
  66. }
  67. public bool IsWaitAlive
  68. {
  69. get
  70. {
  71. if (mLimitedAliveCount == 0)
  72. return false;
  73. return (mSpawnedUnits.Count >= mLimitedAliveCount);
  74. }
  75. }
  76. /// <summary>
  77. /// 生产单位间隔时间
  78. /// </summary>
  79. /// <param name="interval"></param>
  80. public void setSpawnInterval(int interval)
  81. {
  82. this.mSpawnTimeIntervalMS = interval;
  83. }
  84. /// <summary>
  85. /// 设置每次产生个数
  86. /// </summary>
  87. /// <param name="count"></param>
  88. public void setSpawnCount(int count)
  89. {
  90. this.mSpawnOnceCount = count;
  91. }
  92. /// <summary>
  93. /// 设置出生特效
  94. /// </summary>
  95. /// <param name="effect"></param>
  96. public void setSpawnEffect(LaunchEffect effect)
  97. {
  98. this.mSpawnEffect = effect;
  99. }
  100. /// <summary>
  101. /// 单位产生绑定的标志
  102. /// </summary>
  103. /// <param name="tag"></param>
  104. public void setUnitTag(string tag)
  105. {
  106. this.mUnitTag = tag;
  107. }
  108. /// <summary>
  109. /// 只有当前怪物没有存活时才刷新
  110. /// </summary>
  111. /// <param name="without_alive"></param>
  112. public void setSpawnWithoutAlive(bool without_alive)
  113. {
  114. this.mSpawnWithoutAlive = without_alive;
  115. }
  116. /// <summary>
  117. /// 设置怪物存活最大上限
  118. /// </summary>
  119. /// <param name="count"></param>
  120. public void setLimitedAliveCount(int count)
  121. {
  122. this.mLimitedAliveCount = count;
  123. }
  124. /// <summary>
  125. /// 设置怪物最大产生数量
  126. /// </summary>
  127. /// <param name="count"></param>
  128. public void setLimitedSpawnCount(int count)
  129. {
  130. this.mLimitedSpawnCount = count;
  131. }
  132. /// <summary>
  133. /// 设置当前触发器禁止时间,就是多长时间后才起效。
  134. /// </summary>
  135. /// <param name="time"></param>
  136. public void setDelayTime(int time)
  137. {
  138. this.mDelayTimeMS = time;
  139. }
  140. public void setStartDirection(float direction)
  141. {
  142. if (direction >= 0)
  143. {
  144. this.mStartDirection = direction;
  145. }
  146. }
  147. public void setTeamFormation(TeamFormation team)
  148. {
  149. this.mTeam = team;
  150. }
  151. public void setResetOnWithoutAlive(bool flag)
  152. {
  153. this.mResetOnWithoutAlive = flag;
  154. }
  155. public void getSpawnedObjects<T>(List<T> list) where T : InstanceZoneObject
  156. {
  157. foreach (var o in mSpawnedUnits.Values)
  158. {
  159. if (o is T)
  160. {
  161. list.Add(o as T);
  162. }
  163. }
  164. }
  165. /// <summary>
  166. /// 重置计时器
  167. /// </summary>
  168. public void reset()
  169. {
  170. mTotalSpawnCount = 0;
  171. mSpawnedUnits.Clear();
  172. if (mTimeTask != null)
  173. {
  174. mTimeTask.Reset();
  175. }
  176. }
  177. /// <summary>
  178. /// 绑定到区域
  179. /// </summary>
  180. /// <param name="region"></param>
  181. public void bindToRegion(ZoneRegion region)
  182. {
  183. if (mAdded == null)
  184. {
  185. InstanceZone zone = region.Parent;
  186. mAdded = region;
  187. mTimeTask = zone.AddTimeTask(mSpawnTimeIntervalMS, mDelayTimeMS, 0, onTimeSpawn);
  188. region.OnFlagDisabled += this.onRegionStop;
  189. region.OnFlagEnabled += this.onRegionStart;
  190. region.AddSpawnTrigger(this);
  191. if (!region.Enable)
  192. {
  193. mTimeTask.Pause();
  194. }
  195. else
  196. {
  197. //一开始就执行一次spawn
  198. spawnOnce(mAdded);
  199. }
  200. }
  201. else
  202. {
  203. throw new Exception("This Trigger already bind a region !!!");
  204. }
  205. }
  206. private void onRegionStart(InstanceFlag region)
  207. {
  208. //一开始就执行一次spawn
  209. spawnOnce(mAdded);
  210. mTimeTask.Resume();
  211. }
  212. private void onRegionStop(InstanceFlag region)
  213. {
  214. mTimeTask.Pause();
  215. }
  216. private void onTimeSpawn(TimeTaskMS task)
  217. {
  218. spawnOnce(mAdded);
  219. }
  220. private void spawnOnce(ZoneRegion region)
  221. {
  222. if (SpawnTemplateCount <= 0)
  223. {
  224. return;
  225. }
  226. if (mSpawnWithoutAlive && mSpawnedUnits.Count > 0)
  227. {
  228. return;
  229. }
  230. InstanceZone zone = region.Parent;
  231. if (mTeam != null)
  232. {
  233. if (mTeamHelper == null || mTeamHelper.Data != mTeam)
  234. {
  235. mTeamHelper = new TeamFormationGroup(mTeam, region);
  236. }
  237. for (int i = mSpawnOnceCount - 1; i >= 0; --i)
  238. {
  239. var pos = region.getRandomPos(zone.RandomN);
  240. mTeamHelper.AddPos(pos.X, pos.Y, StartDirection);
  241. }
  242. mTeamHelper.ResetPos();
  243. }
  244. else
  245. {
  246. mTeamHelper = null;
  247. }
  248. for (int i = mSpawnOnceCount - 1; i >= 0; --i)
  249. {
  250. if (IsSpawnOver) { break; }
  251. if (IsWaitAlive) { break; }
  252. var pos = (mTeamHelper != null) ? mTeamHelper.PopPos() : null;
  253. var obj = SpawnObject(pos);
  254. this.mSpawnIndexer++;
  255. this.mTotalSpawnCount++;
  256. if (obj != null)
  257. {
  258. this.mSpawnedUnits.Put(obj, obj);
  259. obj.UnitTag = mUnitTag;
  260. obj.OnObjectRemoved += removeSpawned;
  261. OnObjectSpawned(obj);
  262. if (mOnSpawnObject != null)
  263. {
  264. mOnSpawnObject.Invoke(region, this, obj);
  265. }
  266. if (mSpawnEffect != null)
  267. {
  268. zone.queueEvent(new AddEffectEvent(0 ,region.X, region.Y, region.Direction, mSpawnEffect));
  269. }
  270. if (IsSpawnOver)
  271. {
  272. if (mOnSpawnOver != null)
  273. {
  274. mOnSpawnOver.Invoke(region, this);
  275. }
  276. }
  277. }
  278. }
  279. if (mTeamHelper != null)
  280. {
  281. mTeamHelper.Clear();
  282. }
  283. if (mResetOnWithoutAlive)
  284. {
  285. this.mTimeTask.Pause();
  286. }
  287. }
  288. private void removeSpawned(InstanceZoneObject obj)
  289. {
  290. obj.OnObjectRemoved -= removeSpawned;
  291. obj = mSpawnedUnits.RemoveByKey(obj);
  292. if (obj != null)
  293. {
  294. OnSpawnedObjectRemoved(obj);
  295. if (IsSpawnOver && mSpawnedUnits.Count == 0)
  296. {
  297. mTimeTask.Pause();
  298. if (mOnLastObjectRemoved != null)
  299. {
  300. mOnLastObjectRemoved.Invoke(mAdded, this, obj);
  301. }
  302. }
  303. }
  304. if (IsSpawnOver == false && mSpawnedUnits.Count == 0 && mResetOnWithoutAlive)
  305. {
  306. this.mTimeTask.Reset();
  307. }
  308. }
  309. //--------------------------------------------------------------------------------------------------
  310. #region Delegate
  311. public override void Dispose()
  312. {
  313. base.Dispose();
  314. mOnSpawnOver = null;
  315. mOnSpawnObject = null;
  316. mOnLastObjectRemoved = null;
  317. }
  318. public delegate void SpawnObjectHandler(ZoneRegion region, AbstractSpawnTrigger trigger, InstanceZoneObject unit);
  319. public delegate void SpawnOverHandler(ZoneRegion region, AbstractSpawnTrigger trigger);
  320. public delegate void SpawnLastObjectRemovedHandler(ZoneRegion region, AbstractSpawnTrigger trigger, InstanceZoneObject unit);
  321. private SpawnOverHandler mOnSpawnOver;
  322. private SpawnObjectHandler mOnSpawnObject;
  323. private SpawnLastObjectRemovedHandler mOnLastObjectRemoved;
  324. public event SpawnOverHandler OnSpawnOver { add { mOnSpawnOver += value; } remove { mOnSpawnOver -= value; } }
  325. public event SpawnObjectHandler OnSpawnUnit { add { mOnSpawnObject += value; } remove { mOnSpawnObject -= value; } }
  326. public event SpawnLastObjectRemovedHandler OnLastObjectRemoved { add { mOnLastObjectRemoved += value; } remove { mOnLastObjectRemoved -= value; } }
  327. #endregion
  328. //--------------------------------------------------------------------------------------------------
  329. #region ABSTRACT
  330. abstract public int SpawnTemplateCount { get; }
  331. /// <summary>
  332. /// 创建并生成一个单位
  333. /// </summary>
  334. /// <returns></returns>
  335. abstract protected InstanceZoneObject SpawnObject(IPositionObject pos);
  336. /// <summary>
  337. /// 当一个单位被生成
  338. /// </summary>
  339. /// <param name="obj"></param>
  340. abstract protected void OnObjectSpawned(InstanceZoneObject obj);
  341. /// <summary>
  342. /// 当被生成的单位被移除场景
  343. /// </summary>
  344. /// <param name="obj"></param>
  345. abstract protected void OnSpawnedObjectRemoved(InstanceZoneObject obj);
  346. #endregion
  347. }
  348. //-------------------------------------------------------------------------------------------
  349. /// <summary>
  350. /// 生成单位的触发器
  351. /// </summary>
  352. public class SpawnUnitTrigger : AbstractSpawnTrigger
  353. {
  354. public struct SpawnUnitInfo
  355. {
  356. public UnitInfo Unit;
  357. public int Level;
  358. public float Percent;
  359. public SpawnUnitInfo(UnitInfo unit, int level, float percent)
  360. {
  361. this.Unit = unit;
  362. this.Level = level;
  363. this.Percent = percent;
  364. }
  365. }
  366. private List<SpawnUnitInfo> mSpawnUnitTemplates = new List<SpawnUnitInfo>();
  367. private HashMap<uint, InstanceUnit> mAlivedUnits = new HashMap<uint, InstanceUnit>();
  368. private ZoneWayPoint mStartPath = null;
  369. private int mStartPathMinHoldTimeMS, mStartPathMaxHoldTimeMS;
  370. private int mPeaceTime;
  371. private byte mUnitForceMin;
  372. private byte mUnitForceMax;
  373. private string mUnitName;
  374. public override int SpawnTemplateCount
  375. {
  376. get { return mSpawnUnitTemplates.Count; }
  377. }
  378. public override int AliveCount
  379. {
  380. get {
  381. if (mAlivedUnits.Count > 0)
  382. {
  383. int count = 0;
  384. foreach(var u in mAlivedUnits.Values)
  385. {
  386. if (!u.IsDead())
  387. {
  388. count++;
  389. }
  390. }
  391. return count;
  392. }
  393. return 0;
  394. }
  395. }
  396. public SpawnUnitTrigger(InstanceZone zone, string name)
  397. : base(zone, name)
  398. {
  399. }
  400. /// <summary>
  401. /// 设置产生单位的Force
  402. /// </summary>
  403. /// <param name="force"></param>
  404. public void setUnitForce(byte forceMin, byte forceMax)
  405. {
  406. this.mUnitForceMin = forceMin;
  407. this.mUnitForceMax = forceMax;
  408. }
  409. /// <summary>
  410. /// 设置出生单位名字
  411. /// </summary>
  412. /// <param name="name"></param>
  413. public void setUnitName(string name)
  414. {
  415. this.mUnitName = name;
  416. }
  417. /// <summary>
  418. /// 添加单位模板
  419. /// </summary>
  420. /// <param name="info">将要产生的单位模板</param>
  421. /// <param name="level"></param>
  422. /// <param name="percent"></param>
  423. public void addUnitInfo(UnitInfo info, int level, float percent)
  424. {
  425. this.mSpawnUnitTemplates.Add(new SpawnUnitInfo(info, level, percent));
  426. }
  427. /// <summary>
  428. /// 添加单位模板
  429. /// </summary>
  430. /// <param name="templateID">将要产生的单位模板</param>
  431. /// <param name="level"></param>
  432. /// <param name="percent"></param>
  433. public void addUnitInfo(int templateID, int level = 0, float percent = 100f)
  434. {
  435. UnitInfo info = Zone.Templates.getUnit(templateID);
  436. if (info != null)
  437. {
  438. info = (UnitInfo)info.Clone();
  439. this.addUnitInfo(info, level, percent);
  440. }
  441. }
  442. //添加单位事件
  443. //public void addItemEvent(string eventId)
  444. //{
  445. // this.Events.Add(eventId);
  446. //}
  447. /// <summary>
  448. /// 添加多个单位模板
  449. /// </summary>
  450. /// <param name="unitsTemplateID"></param>
  451. /// <param name="level"></param>
  452. public void addUnits(int[] unitsTemplateID, int level)
  453. {
  454. if (unitsTemplateID != null)
  455. {
  456. foreach (int id in unitsTemplateID)
  457. {
  458. UnitInfo info = Zone.Templates.getUnit(id);
  459. if (info != null)
  460. {
  461. info = (UnitInfo)info.Clone();
  462. this.addUnitInfo(info, level, 100f);
  463. }
  464. }
  465. }
  466. }
  467. /// <summary>
  468. /// 清除所有怪物模板
  469. /// </summary>
  470. public void clearTemplates()
  471. {
  472. mSpawnUnitTemplates.Clear();
  473. }
  474. /// <summary>
  475. /// 设置移动路线
  476. /// </summary>
  477. /// <param name="zone"></param>
  478. /// <param name="flagName"></param>
  479. /// <param name="minHoldTimeMS"></param>
  480. /// <param name="maxHoldTimeMS"></param>
  481. public ZoneWayPoint setStartPath(InstanceZone zone, string flagName, int minHoldTimeMS, int maxHoldTimeMS, int PeaceTime)
  482. {
  483. this.mStartPath = null;
  484. if (!string.IsNullOrEmpty(flagName))
  485. {
  486. InstanceFlag flag = zone.getFlag(flagName);
  487. if (flag is ZoneWayPoint)
  488. {
  489. mStartPath = flag as ZoneWayPoint;
  490. mStartPathMinHoldTimeMS = minHoldTimeMS;
  491. mStartPathMaxHoldTimeMS = maxHoldTimeMS;
  492. mPeaceTime = PeaceTime;
  493. }
  494. }
  495. return mStartPath;
  496. }
  497. protected override InstanceZoneObject SpawnObject(IPositionObject pos)
  498. {
  499. InstanceZone zone = this.BindingZone;
  500. SpawnUnitInfo spawn = mSpawnUnitTemplates[SpawnIndexer % mSpawnUnitTemplates.Count];
  501. if (CUtils.RandomPercent(zone.RandomN, spawn.Percent))
  502. {
  503. IVector2 mpos = pos != null ? new TVector2(pos.X, pos.Y) : BindingRegion.getRandomPos(zone.RandomN);
  504. float direction = pos != null ? pos.Direction : this.StartDirection;
  505. UnitInfo info = spawn.Unit;
  506. int level = spawn.Level;
  507. InstanceUnit unit = zone.AddUnit(info,
  508. mUnitName,
  509. this.GetForce(),
  510. level,
  511. mpos.X, mpos.Y, direction);
  512. if (unit is IGuardUnit)
  513. {
  514. IGuardUnit guard = unit as IGuardUnit;
  515. guard.SetOrginPosition(mpos.X, mpos.Y);
  516. }
  517. return unit;
  518. }
  519. return null;
  520. }
  521. private byte GetForce()
  522. {
  523. if (this.mUnitForceMax > this.mUnitForceMin && this.mUnitForceMin >= 0)
  524. {
  525. return (byte)(GlobalData.gRandom.Next() % (this.mUnitForceMax - this.mUnitForceMin) + this.mUnitForceMin);
  526. }
  527. return this.mUnitForceMin;
  528. }
  529. protected override void OnObjectSpawned(InstanceZoneObject obj)
  530. {
  531. InstanceUnit unit = (obj as InstanceUnit);
  532. if (unit != null)
  533. {
  534. mAlivedUnits.Put(unit.ID, unit);
  535. unit.OnDead += unit_OnDead;
  536. if (mStartPath != null && (unit is IGuardUnit))
  537. {
  538. unit.OnActivated += unit_OnActivated;
  539. }
  540. }
  541. }
  542. protected override void OnSpawnedObjectRemoved(InstanceZoneObject obj)
  543. {
  544. IGuardUnit guard = (obj as IGuardUnit);
  545. if (guard != null)
  546. {
  547. var unit = guard as InstanceUnit;
  548. mAlivedUnits.RemoveByKey(unit.ID);
  549. unit.OnDead -= unit_OnDead;
  550. unit.OnActivated -= unit_OnActivated;
  551. }
  552. }
  553. private void unit_OnDead(InstanceUnit unit, InstanceUnit attacker)
  554. {
  555. mAlivedUnits.RemoveByKey(unit.ID);
  556. }
  557. private void unit_OnActivated(InstanceUnit unit)
  558. {
  559. unit.OnActivated -= unit_OnActivated;
  560. if (unit is IGuardUnit)
  561. {
  562. IGuardUnit guard = unit as IGuardUnit;
  563. if (mStartPathMinHoldTimeMS != 0 || mStartPathMaxHoldTimeMS != 0)
  564. {
  565. guard.PatrolWith(
  566. mStartPath,
  567. mStartPathMinHoldTimeMS,
  568. mStartPathMaxHoldTimeMS,
  569. mPeaceTime);
  570. }
  571. else
  572. {
  573. guard.AttackTo(mStartPath, mPeaceTime);
  574. }
  575. }
  576. }
  577. }
  578. //-------------------------------------------------------------------------------------------
  579. /// <summary>
  580. /// 生成物品的触发器
  581. /// </summary>
  582. public class SpawnItemTrigger : AbstractSpawnTrigger
  583. {
  584. public struct SpawnItemInfo
  585. {
  586. public ItemTemplate Item;
  587. public float Percent;
  588. public SpawnItemInfo(ItemTemplate item, float percent)
  589. {
  590. this.Item = item;
  591. this.Percent = percent;
  592. }
  593. }
  594. private List<SpawnItemInfo> mSpawnUnitTemplates = new List<SpawnItemInfo>();
  595. private byte mUnitForce;
  596. private string mUnitName;
  597. public override int SpawnTemplateCount
  598. {
  599. get { return mSpawnUnitTemplates.Count; }
  600. }
  601. public SpawnItemTrigger(InstanceZone zone, string name)
  602. : base(zone, name)
  603. {
  604. }
  605. /// <summary>
  606. /// 设置产生单位的Force
  607. /// </summary>
  608. /// <param name="force"></param>
  609. public void setUnitForce(byte force)
  610. {
  611. this.mUnitForce = force;
  612. }
  613. /// <summary>
  614. /// 设置出生单位名字
  615. /// </summary>
  616. /// <param name="name"></param>
  617. public void setUnitName(string name)
  618. {
  619. this.mUnitName = name;
  620. }
  621. /// <summary>
  622. /// 添加单位模板
  623. /// </summary>
  624. /// <param name="info">将要产生的单位模板</param>
  625. public void addItemInfo(int templateID, float percent = 100f)
  626. {
  627. ItemTemplate info = Zone.Templates.getItem(templateID);
  628. if (info != null)
  629. {
  630. info = (ItemTemplate)info.Clone();
  631. mSpawnUnitTemplates.Add(new SpawnItemInfo(info, percent));
  632. }
  633. }
  634. /// <summary>
  635. /// 清除所有怪物模板
  636. /// </summary>
  637. public void clearTemplates()
  638. {
  639. mSpawnUnitTemplates.Clear();
  640. }
  641. protected override InstanceZoneObject SpawnObject(IPositionObject pos)
  642. {
  643. InstanceZone zone = this.BindingZone;
  644. SpawnItemInfo spawn = mSpawnUnitTemplates[SpawnIndexer % mSpawnUnitTemplates.Count];
  645. if (CUtils.RandomPercent(zone.RandomN, spawn.Percent))
  646. {
  647. IVector2 mpos = pos != null ? new TVector2(pos.X, pos.Y) : BindingRegion.getRandomPos(zone.RandomN);
  648. float direction = pos != null ? pos.Direction : base.StartDirection;
  649. ItemTemplate info = spawn.Item;
  650. info = (ItemTemplate)info.Clone();
  651. InstanceItem item = zone.AddItem(info, mUnitName, mpos.X, mpos.Y, direction, mUnitForce, mUnitName, null);
  652. return item;
  653. }
  654. return null;
  655. }
  656. protected override void OnObjectSpawned(InstanceZoneObject obj)
  657. {
  658. }
  659. protected override void OnSpawnedObjectRemoved(InstanceZoneObject obj)
  660. {
  661. }
  662. }
  663. }