123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743 |
- using System;
- using System.Collections.Generic;
- using System.Text;
- using CommonLang;
- using CommonAI.RTS;
- using CommonLang.Vector;
- using CommonAI.RTS.Manhattan;
- using CommonAI.Zone.Helper;
- using CommonAI.Data;
- namespace CommonAI.Zone.Instance
- {
-
- /// <summary>
- /// 生成单位的触发器
- /// </summary>
- public abstract class AbstractSpawnTrigger : Ability
- {
- public string Name { get; private set; }
- private ZoneRegion mAdded = null;
- private int mSpawnTimeIntervalMS;
- private int mDelayTimeMS = 0;
- private int mSpawnOnceCount;
- private LaunchEffect mSpawnEffect;
- private bool mSpawnWithoutAlive = true;
- private bool mResetOnWithoutAlive = false;
- private int mTotalSpawnCount = 0;
- private int mSpawnIndexer = 0;
- private int mLimitedSpawnCount = 0;
- private int mLimitedAliveCount = 0;
- private HashMap<InstanceZoneObject, InstanceZoneObject> mSpawnedUnits = new HashMap<InstanceZoneObject, InstanceZoneObject>();
- private string mUnitTag;
- private TimeTaskMS mTimeTask;
- private float mStartDirection = float.NaN;
- private TeamFormation mTeam;
- private TeamFormationGroup mTeamHelper;
- //绑定事件
- //protected List<String> Events = new List<String>();
- //--------------------------------------------------------------------------------------------------
- public AbstractSpawnTrigger(InstanceZone zone, string name)
- : base(zone)
- {
- this.Name = name;
- }
- public InstanceZone BindingZone { get { return mAdded.Parent; } }
- public ZoneRegion BindingRegion { get { return mAdded; } }
- public int OnceSpawnCount { get { return mSpawnOnceCount; } }
- public int LimitedSpawnCount { get { return mLimitedSpawnCount; } }
- public int LimitedAliveCount { get { return mLimitedAliveCount; } }
- /// <summary>
- /// 当前存活数量
- /// </summary>
- public virtual int AliveCount { get { return mSpawnedUnits.Count; } }
- public int SpawnIndexer { get { return mSpawnIndexer; } }
- public int TotalSpawnCount { get { return mTotalSpawnCount; } }
- public float StartDirection { get { return (!float.IsNaN(mStartDirection)) ? mStartDirection : (float)(Zone.RandomN.NextDouble() * CMath.PI_MUL_2); } }
- /// <summary>
- /// 是否已完成刷新
- /// </summary>
- public bool IsSpawnOver
- {
- get
- {
- if (mLimitedSpawnCount == 0)
- return false;
- return (mTotalSpawnCount >= mLimitedSpawnCount);
- }
- }
- public bool IsWaitAlive
- {
- get
- {
- if (mLimitedAliveCount == 0)
- return false;
- return (mSpawnedUnits.Count >= mLimitedAliveCount);
- }
- }
- /// <summary>
- /// 生产单位间隔时间
- /// </summary>
- /// <param name="interval"></param>
- public void setSpawnInterval(int interval)
- {
- this.mSpawnTimeIntervalMS = interval;
- }
- /// <summary>
- /// 设置每次产生个数
- /// </summary>
- /// <param name="count"></param>
- public void setSpawnCount(int count)
- {
- this.mSpawnOnceCount = count;
- }
- /// <summary>
- /// 设置出生特效
- /// </summary>
- /// <param name="effect"></param>
- public void setSpawnEffect(LaunchEffect effect)
- {
- this.mSpawnEffect = effect;
- }
- /// <summary>
- /// 单位产生绑定的标志
- /// </summary>
- /// <param name="tag"></param>
- public void setUnitTag(string tag)
- {
- this.mUnitTag = tag;
- }
- /// <summary>
- /// 只有当前怪物没有存活时才刷新
- /// </summary>
- /// <param name="without_alive"></param>
- public void setSpawnWithoutAlive(bool without_alive)
- {
- this.mSpawnWithoutAlive = without_alive;
- }
- /// <summary>
- /// 设置怪物存活最大上限
- /// </summary>
- /// <param name="count"></param>
- public void setLimitedAliveCount(int count)
- {
- this.mLimitedAliveCount = count;
- }
- /// <summary>
- /// 设置怪物最大产生数量
- /// </summary>
- /// <param name="count"></param>
- public void setLimitedSpawnCount(int count)
- {
- this.mLimitedSpawnCount = count;
- }
- /// <summary>
- /// 设置当前触发器禁止时间,就是多长时间后才起效。
- /// </summary>
- /// <param name="time"></param>
- public void setDelayTime(int time)
- {
- this.mDelayTimeMS = time;
- }
- public void setStartDirection(float direction)
- {
- if (direction >= 0)
- {
- this.mStartDirection = direction;
- }
- }
- public void setTeamFormation(TeamFormation team)
- {
- this.mTeam = team;
- }
- public void setResetOnWithoutAlive(bool flag)
- {
- this.mResetOnWithoutAlive = flag;
- }
- public void getSpawnedObjects<T>(List<T> list) where T : InstanceZoneObject
- {
- foreach (var o in mSpawnedUnits.Values)
- {
- if (o is T)
- {
- list.Add(o as T);
- }
- }
- }
- /// <summary>
- /// 重置计时器
- /// </summary>
- public void reset()
- {
- mTotalSpawnCount = 0;
- mSpawnedUnits.Clear();
- if (mTimeTask != null)
- {
- mTimeTask.Reset();
- }
- }
- /// <summary>
- /// 绑定到区域
- /// </summary>
- /// <param name="region"></param>
- public void bindToRegion(ZoneRegion region)
- {
- if (mAdded == null)
- {
- InstanceZone zone = region.Parent;
- mAdded = region;
- mTimeTask = zone.AddTimeTask(mSpawnTimeIntervalMS, mDelayTimeMS, 0, onTimeSpawn);
- region.OnFlagDisabled += this.onRegionStop;
- region.OnFlagEnabled += this.onRegionStart;
- region.AddSpawnTrigger(this);
- if (!region.Enable)
- {
- mTimeTask.Pause();
- }
- else
- {
- //一开始就执行一次spawn
- spawnOnce(mAdded);
- }
- }
- else
- {
- throw new Exception("This Trigger already bind a region !!!");
- }
- }
- private void onRegionStart(InstanceFlag region)
- {
- //一开始就执行一次spawn
- spawnOnce(mAdded);
- mTimeTask.Resume();
- }
- private void onRegionStop(InstanceFlag region)
- {
- mTimeTask.Pause();
- }
- private void onTimeSpawn(TimeTaskMS task)
- {
- spawnOnce(mAdded);
- }
- private void spawnOnce(ZoneRegion region)
- {
- if (SpawnTemplateCount <= 0)
- {
- return;
- }
- if (mSpawnWithoutAlive && mSpawnedUnits.Count > 0)
- {
- return;
- }
- InstanceZone zone = region.Parent;
- if (mTeam != null)
- {
- if (mTeamHelper == null || mTeamHelper.Data != mTeam)
- {
- mTeamHelper = new TeamFormationGroup(mTeam, region);
- }
- for (int i = mSpawnOnceCount - 1; i >= 0; --i)
- {
- var pos = region.getRandomPos(zone.RandomN);
- mTeamHelper.AddPos(pos.X, pos.Y, StartDirection);
- }
- mTeamHelper.ResetPos();
- }
- else
- {
- mTeamHelper = null;
- }
-
- for (int i = mSpawnOnceCount - 1; i >= 0; --i)
- {
- if (IsSpawnOver) { break; }
- if (IsWaitAlive) { break; }
- var pos = (mTeamHelper != null) ? mTeamHelper.PopPos() : null;
- var obj = SpawnObject(pos);
- this.mSpawnIndexer++;
- this.mTotalSpawnCount++;
- if (obj != null)
- {
- this.mSpawnedUnits.Put(obj, obj);
- obj.UnitTag = mUnitTag;
- obj.OnObjectRemoved += removeSpawned;
- OnObjectSpawned(obj);
- if (mOnSpawnObject != null)
- {
- mOnSpawnObject.Invoke(region, this, obj);
- }
- if (mSpawnEffect != null)
- {
- zone.queueEvent(new AddEffectEvent(0 ,region.X, region.Y, region.Direction, mSpawnEffect));
- }
- if (IsSpawnOver)
- {
- if (mOnSpawnOver != null)
- {
- mOnSpawnOver.Invoke(region, this);
- }
- }
- }
- }
- if (mTeamHelper != null)
- {
- mTeamHelper.Clear();
- }
- if (mResetOnWithoutAlive)
- {
- this.mTimeTask.Pause();
- }
- }
- private void removeSpawned(InstanceZoneObject obj)
- {
- obj.OnObjectRemoved -= removeSpawned;
- obj = mSpawnedUnits.RemoveByKey(obj);
- if (obj != null)
- {
- OnSpawnedObjectRemoved(obj);
- if (IsSpawnOver && mSpawnedUnits.Count == 0)
- {
- mTimeTask.Pause();
- if (mOnLastObjectRemoved != null)
- {
- mOnLastObjectRemoved.Invoke(mAdded, this, obj);
- }
- }
- }
- if (IsSpawnOver == false && mSpawnedUnits.Count == 0 && mResetOnWithoutAlive)
- {
- this.mTimeTask.Reset();
- }
- }
- //--------------------------------------------------------------------------------------------------
- #region Delegate
- public override void Dispose()
- {
- base.Dispose();
- mOnSpawnOver = null;
- mOnSpawnObject = null;
- mOnLastObjectRemoved = null;
- }
- public delegate void SpawnObjectHandler(ZoneRegion region, AbstractSpawnTrigger trigger, InstanceZoneObject unit);
- public delegate void SpawnOverHandler(ZoneRegion region, AbstractSpawnTrigger trigger);
- public delegate void SpawnLastObjectRemovedHandler(ZoneRegion region, AbstractSpawnTrigger trigger, InstanceZoneObject unit);
- private SpawnOverHandler mOnSpawnOver;
- private SpawnObjectHandler mOnSpawnObject;
- private SpawnLastObjectRemovedHandler mOnLastObjectRemoved;
- public event SpawnOverHandler OnSpawnOver { add { mOnSpawnOver += value; } remove { mOnSpawnOver -= value; } }
- public event SpawnObjectHandler OnSpawnUnit { add { mOnSpawnObject += value; } remove { mOnSpawnObject -= value; } }
- public event SpawnLastObjectRemovedHandler OnLastObjectRemoved { add { mOnLastObjectRemoved += value; } remove { mOnLastObjectRemoved -= value; } }
- #endregion
- //--------------------------------------------------------------------------------------------------
- #region ABSTRACT
- abstract public int SpawnTemplateCount { get; }
- /// <summary>
- /// 创建并生成一个单位
- /// </summary>
- /// <returns></returns>
- abstract protected InstanceZoneObject SpawnObject(IPositionObject pos);
- /// <summary>
- /// 当一个单位被生成
- /// </summary>
- /// <param name="obj"></param>
- abstract protected void OnObjectSpawned(InstanceZoneObject obj);
- /// <summary>
- /// 当被生成的单位被移除场景
- /// </summary>
- /// <param name="obj"></param>
- abstract protected void OnSpawnedObjectRemoved(InstanceZoneObject obj);
- #endregion
- }
- //-------------------------------------------------------------------------------------------
- /// <summary>
- /// 生成单位的触发器
- /// </summary>
- public class SpawnUnitTrigger : AbstractSpawnTrigger
- {
- public struct SpawnUnitInfo
- {
- public UnitInfo Unit;
- public int Level;
- public float Percent;
- public SpawnUnitInfo(UnitInfo unit, int level, float percent)
- {
- this.Unit = unit;
- this.Level = level;
- this.Percent = percent;
- }
- }
- private List<SpawnUnitInfo> mSpawnUnitTemplates = new List<SpawnUnitInfo>();
- private HashMap<uint, InstanceUnit> mAlivedUnits = new HashMap<uint, InstanceUnit>();
- private ZoneWayPoint mStartPath = null;
- private int mStartPathMinHoldTimeMS, mStartPathMaxHoldTimeMS;
- private int mPeaceTime;
- private byte mUnitForceMin;
- private byte mUnitForceMax;
- private string mUnitName;
- public override int SpawnTemplateCount
- {
- get { return mSpawnUnitTemplates.Count; }
- }
- public override int AliveCount
- {
- get {
- if (mAlivedUnits.Count > 0)
- {
- int count = 0;
- foreach(var u in mAlivedUnits.Values)
- {
- if (!u.IsDead())
- {
- count++;
- }
- }
- return count;
- }
- return 0;
- }
- }
- public SpawnUnitTrigger(InstanceZone zone, string name)
- : base(zone, name)
- {
- }
- /// <summary>
- /// 设置产生单位的Force
- /// </summary>
- /// <param name="force"></param>
- public void setUnitForce(byte forceMin, byte forceMax)
- {
- this.mUnitForceMin = forceMin;
- this.mUnitForceMax = forceMax;
- }
- /// <summary>
- /// 设置出生单位名字
- /// </summary>
- /// <param name="name"></param>
- public void setUnitName(string name)
- {
- this.mUnitName = name;
- }
- /// <summary>
- /// 添加单位模板
- /// </summary>
- /// <param name="info">将要产生的单位模板</param>
- /// <param name="level"></param>
- /// <param name="percent"></param>
- public void addUnitInfo(UnitInfo info, int level, float percent)
- {
- this.mSpawnUnitTemplates.Add(new SpawnUnitInfo(info, level, percent));
- }
- /// <summary>
- /// 添加单位模板
- /// </summary>
- /// <param name="templateID">将要产生的单位模板</param>
- /// <param name="level"></param>
- /// <param name="percent"></param>
- public void addUnitInfo(int templateID, int level = 0, float percent = 100f)
- {
- UnitInfo info = Zone.Templates.getUnit(templateID);
- if (info != null)
- {
- info = (UnitInfo)info.Clone();
- this.addUnitInfo(info, level, percent);
- }
- }
- //添加单位事件
- //public void addItemEvent(string eventId)
- //{
- // this.Events.Add(eventId);
- //}
- /// <summary>
- /// 添加多个单位模板
- /// </summary>
- /// <param name="unitsTemplateID"></param>
- /// <param name="level"></param>
- public void addUnits(int[] unitsTemplateID, int level)
- {
- if (unitsTemplateID != null)
- {
- foreach (int id in unitsTemplateID)
- {
- UnitInfo info = Zone.Templates.getUnit(id);
- if (info != null)
- {
- info = (UnitInfo)info.Clone();
- this.addUnitInfo(info, level, 100f);
- }
- }
- }
- }
- /// <summary>
- /// 清除所有怪物模板
- /// </summary>
- public void clearTemplates()
- {
- mSpawnUnitTemplates.Clear();
- }
- /// <summary>
- /// 设置移动路线
- /// </summary>
- /// <param name="zone"></param>
- /// <param name="flagName"></param>
- /// <param name="minHoldTimeMS"></param>
- /// <param name="maxHoldTimeMS"></param>
- public ZoneWayPoint setStartPath(InstanceZone zone, string flagName, int minHoldTimeMS, int maxHoldTimeMS, int PeaceTime)
- {
- this.mStartPath = null;
- if (!string.IsNullOrEmpty(flagName))
- {
- InstanceFlag flag = zone.getFlag(flagName);
- if (flag is ZoneWayPoint)
- {
- mStartPath = flag as ZoneWayPoint;
- mStartPathMinHoldTimeMS = minHoldTimeMS;
- mStartPathMaxHoldTimeMS = maxHoldTimeMS;
- mPeaceTime = PeaceTime;
- }
- }
- return mStartPath;
- }
- protected override InstanceZoneObject SpawnObject(IPositionObject pos)
- {
- InstanceZone zone = this.BindingZone;
- SpawnUnitInfo spawn = mSpawnUnitTemplates[SpawnIndexer % mSpawnUnitTemplates.Count];
- if (CUtils.RandomPercent(zone.RandomN, spawn.Percent))
- {
- IVector2 mpos = pos != null ? new TVector2(pos.X, pos.Y) : BindingRegion.getRandomPos(zone.RandomN);
- float direction = pos != null ? pos.Direction : this.StartDirection;
- UnitInfo info = spawn.Unit;
- int level = spawn.Level;
- InstanceUnit unit = zone.AddUnit(info,
- mUnitName,
- this.GetForce(),
- level,
- mpos.X, mpos.Y, direction);
- if (unit is IGuardUnit)
- {
- IGuardUnit guard = unit as IGuardUnit;
- guard.SetOrginPosition(mpos.X, mpos.Y);
- }
- return unit;
- }
- return null;
- }
-
- private byte GetForce()
- {
- if (this.mUnitForceMax > this.mUnitForceMin && this.mUnitForceMin >= 0)
- {
- return (byte)(GlobalData.gRandom.Next() % (this.mUnitForceMax - this.mUnitForceMin) + this.mUnitForceMin);
- }
- return this.mUnitForceMin;
- }
- protected override void OnObjectSpawned(InstanceZoneObject obj)
- {
- InstanceUnit unit = (obj as InstanceUnit);
- if (unit != null)
- {
- mAlivedUnits.Put(unit.ID, unit);
- unit.OnDead += unit_OnDead;
- if (mStartPath != null && (unit is IGuardUnit))
- {
- unit.OnActivated += unit_OnActivated;
- }
- }
- }
- protected override void OnSpawnedObjectRemoved(InstanceZoneObject obj)
- {
- IGuardUnit guard = (obj as IGuardUnit);
- if (guard != null)
- {
- var unit = guard as InstanceUnit;
- mAlivedUnits.RemoveByKey(unit.ID);
- unit.OnDead -= unit_OnDead;
- unit.OnActivated -= unit_OnActivated;
- }
- }
- private void unit_OnDead(InstanceUnit unit, InstanceUnit attacker)
- {
- mAlivedUnits.RemoveByKey(unit.ID);
- }
- private void unit_OnActivated(InstanceUnit unit)
- {
- unit.OnActivated -= unit_OnActivated;
- if (unit is IGuardUnit)
- {
- IGuardUnit guard = unit as IGuardUnit;
- if (mStartPathMinHoldTimeMS != 0 || mStartPathMaxHoldTimeMS != 0)
- {
- guard.PatrolWith(
- mStartPath,
- mStartPathMinHoldTimeMS,
- mStartPathMaxHoldTimeMS,
- mPeaceTime);
- }
- else
- {
- guard.AttackTo(mStartPath, mPeaceTime);
- }
- }
- }
- }
- //-------------------------------------------------------------------------------------------
- /// <summary>
- /// 生成物品的触发器
- /// </summary>
- public class SpawnItemTrigger : AbstractSpawnTrigger
- {
- public struct SpawnItemInfo
- {
- public ItemTemplate Item;
- public float Percent;
- public SpawnItemInfo(ItemTemplate item, float percent)
- {
- this.Item = item;
- this.Percent = percent;
- }
- }
- private List<SpawnItemInfo> mSpawnUnitTemplates = new List<SpawnItemInfo>();
- private byte mUnitForce;
- private string mUnitName;
- public override int SpawnTemplateCount
- {
- get { return mSpawnUnitTemplates.Count; }
- }
- public SpawnItemTrigger(InstanceZone zone, string name)
- : base(zone, name)
- {
- }
- /// <summary>
- /// 设置产生单位的Force
- /// </summary>
- /// <param name="force"></param>
- public void setUnitForce(byte force)
- {
- this.mUnitForce = force;
- }
- /// <summary>
- /// 设置出生单位名字
- /// </summary>
- /// <param name="name"></param>
- public void setUnitName(string name)
- {
- this.mUnitName = name;
- }
- /// <summary>
- /// 添加单位模板
- /// </summary>
- /// <param name="info">将要产生的单位模板</param>
- public void addItemInfo(int templateID, float percent = 100f)
- {
- ItemTemplate info = Zone.Templates.getItem(templateID);
- if (info != null)
- {
- info = (ItemTemplate)info.Clone();
- mSpawnUnitTemplates.Add(new SpawnItemInfo(info, percent));
- }
- }
- /// <summary>
- /// 清除所有怪物模板
- /// </summary>
- public void clearTemplates()
- {
- mSpawnUnitTemplates.Clear();
- }
- protected override InstanceZoneObject SpawnObject(IPositionObject pos)
- {
- InstanceZone zone = this.BindingZone;
- SpawnItemInfo spawn = mSpawnUnitTemplates[SpawnIndexer % mSpawnUnitTemplates.Count];
- if (CUtils.RandomPercent(zone.RandomN, spawn.Percent))
- {
- IVector2 mpos = pos != null ? new TVector2(pos.X, pos.Y) : BindingRegion.getRandomPos(zone.RandomN);
- float direction = pos != null ? pos.Direction : base.StartDirection;
- ItemTemplate info = spawn.Item;
- info = (ItemTemplate)info.Clone();
- InstanceItem item = zone.AddItem(info, mUnitName, mpos.X, mpos.Y, direction, mUnitForce, mUnitName, null);
- return item;
- }
- return null;
- }
- protected override void OnObjectSpawned(InstanceZoneObject obj)
- {
- }
- protected override void OnSpawnedObjectRemoved(InstanceZoneObject obj)
- {
- }
- }
- }
|