123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580 |
- 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;
- namespace CommonAI.Zone.Instance
- {
-
- /// <summary>
- /// 观察一定范围的触发器
- /// </summary>
- abstract public class ViewTrigger : Ability
- {
- /// <summary>
- /// 监听单位进出观察范围
- /// </summary>
- public interface ViewTriggerListener
- {
- /// <summary>
- /// 当一个单位进入观察范围后触发
- /// </summary>
- /// <param name="src">观察者</param>
- /// <param name="obj">进入视野的单位</param>
- void onObjectEnterView(ViewTrigger src, InstanceZoneObject obj);
- /// <summary>
- /// 当一个单位离开观察范围后触发
- /// </summary>
- /// <param name="src">观察者</param>
- /// <param name="obj">离开视野范围的单位</param>
- void onObjectLeaveView(ViewTrigger src, InstanceZoneObject obj);
- /// <summary>
- /// 是否可见
- /// </summary>
- /// <param name="src"></param>
- /// <param name="obj"></param>
- /// <returns></returns>
- bool select(ViewTrigger src, InstanceZoneObject obj);
- }
- private bool mEnable = true;
- private int mMaxViewd = int.MaxValue;
- private ViewTriggerListener mViewListener;
- private List<InstanceZoneObject> mViewd = new List<InstanceZoneObject>();
- /// <summary>
- /// 检测频率
- /// </summary>
- private readonly TimeInterval<int> mCheckRate;
- public bool Enable
- {
- get { return mEnable; }
- set { mEnable = value; }
- }
- public IEnumerable<InstanceZoneObject> InViewed
- {
- get { return mViewd; }
- }
- public ViewTrigger(InstanceZone zone)
- : base(zone)
- {
- mCheckRate = new TimeInterval<int>(Zone.Templates.CFG.AI_VIEW_TRIGGER_CHECK_TIME_MS);
- }
- public override void Dispose()
- {
- mEnable = false;
- base.Dispose();
- mViewd.Clear();
- }
- public void addViewed(InstanceZoneObject obj)
- {
- mViewd.Add(obj);
- }
- public InstanceZoneObject getRandomViewed(Random random)
- {
- return CUtils.GetRandomInArray<InstanceZoneObject>(mViewd, random);
- }
- [Obsolete]
- public List<InstanceZoneObject> getRandomViewedList(Random random)
- {
- List<InstanceZoneObject> ret = new List<InstanceZoneObject>(mViewd);
- CUtils.RandomList<InstanceZoneObject>(random, ret);
- return ret;
- }
- public void getRandomViewedList(Random random, List<InstanceZoneObject> ret)
- {
- ret.AddRange(mViewd);
- CUtils.RandomList<InstanceZoneObject>(random, ret);
- }
- /// <summary>
- /// 设置最大观察单位数量
- /// </summary>
- /// <param name="m"></param>
- public void setMaxViewd(int m)
- {
- this.mMaxViewd = m;
- }
- /// <summary>
- /// 增加观察者监听器
- /// </summary>
- /// <param name="listener"></param>
- public void setListener(ViewTriggerListener listener)
- {
- mViewListener = listener;
- }
- public virtual void onLookUpdate(float x, float y)
- {
- if (mEnable)
- {
- bool is_check = mCheckRate.Update(Zone.UpdateIntervalMS);
- this.check(x, y, is_check);
- }
- else if (mViewd.Count > 0)
- {
- for (int i = mViewd.Count - 1; i >= 0; --i)
- {
- onObjectLeaveView(mViewd[i]);
- }
- mViewd.Clear();
- }
- }
- protected void onObjectEnterView(InstanceZoneObject o)
- {
- if (mViewListener != null)
- {
- mViewListener.onObjectEnterView(this, o);
- }
- }
- protected void onObjectLeaveView(InstanceZoneObject o)
- {
- if (mViewListener != null)
- {
- mViewListener.onObjectLeaveView(this, o);
- }
- }
- protected virtual void check(float x, float y, bool check)
- {
- if (check || this.IsNearChanged(x, y))
- {
- // 检索已看到的消失
- for (int i = mViewd.Count - 1; i >= 0; --i)
- {
- InstanceZoneObject o = mViewd[i];
- if (!o.Enable || !mViewListener.select(this, o) || !TestInView(o, x, y))
- {
- mViewd.RemoveAt(i);
- onObjectLeaveView(o);
- }
- }
- this.ForEachNearObjects(x, y, (InstanceZoneObject o) =>
- {
- if (o.Enable && mViewListener.select(this, o) && !mViewd.Contains(o) && TestInView(o, x, y))
- {
- mViewd.Add(o);
- onObjectEnterView(o);
- }
- });
- }
- }
- abstract protected bool IsNearChanged(float x, float y);
- abstract protected bool TestInView(InstanceZoneObject o, float x, float y);
- abstract protected void ForEachNearObjects(float x, float y, Action<InstanceZoneObject> indexer);
- }
- /// <summary>
- /// 瞎子
- /// </summary>
- public class ViewTriggerBlind : ViewTrigger
- {
- public ViewTriggerBlind(InstanceZone zone) : base(zone)
- {
- }
- public override void onLookUpdate(float x, float y)
- {
- }
- protected override void ForEachNearObjects(float x, float y, Action<InstanceZoneObject> indexer)
- {
- }
- protected override bool IsNearChanged(float x, float y)
- {
- return false;
- }
- protected override bool TestInView(InstanceZoneObject o, float x, float y)
- {
- return false;
- }
- }
- /// <summary>
- /// 观察目标坐标是否在圆形范围内
- /// </summary>
- public class ViewTriggerRoundCenter : ViewTrigger
- {
- private float mLookRange;
- public ViewTriggerRoundCenter(InstanceZone zone, float r)
- : base(zone)
- {
- this.mLookRange = r;
- }
- protected override bool IsNearChanged(float x, float y)
- {
- return Zone.IsNearChanged(x, y, mLookRange);
- }
- protected override bool TestInView(InstanceZoneObject o, float x, float y)
- {
- return Collider.Object_Pos_IncludeInRound(o, x, y, mLookRange);
- }
- protected override void ForEachNearObjects(float x, float y, Action<InstanceZoneObject> indexer)
- {
- Zone.ForEachNearObjects(x, y, mLookRange, (InstanceZoneObject o, ref bool cancel) =>
- {
- indexer(o);
- });
- }
- /*
- public override void Check(InstanceZone zone, float x, float y, bool check)
- {
- if (check || zone.IsNearChanged(x, y, mLookRange))
- {
- // 检索已看到的消失
- for (int i = mViewd.Count - 1; i >= 0; --i)
- {
- InstanceZoneObject o = mViewd[i];
- if (!o.Enable || !mViewListener.select(this, o) || !Collider.Object_Pos_IncludeInRound(o, x, y, mLookRange))
- {
- mViewd.RemoveAt(i);
- onObjectLeaveView(o);
- }
- }
- zone.ForEachNearObjects(x, y, mLookRange, (InstanceZoneObject o, ref bool cancel) =>
- {
- if (o.Enable && mViewListener.select(this, o) && !mViewd.Contains(o) && Collider.Object_Pos_IncludeInRound(o, x, y, mLookRange))
- {
- mViewd.Add(o);
- onObjectEnterView(o);
- }
- });
- }
- }
- */
- }
- /// <summary>
- /// 观察目标BlockBody是否在圆形范围内
- /// </summary>
- public class ViewTriggerRoundBody : ViewTrigger
- {
- private float mLookRange;
- public ViewTriggerRoundBody(InstanceZone zone, float r)
- : base(zone)
- {
- this.mLookRange = r;
- }
- public void SetLookRange(float r)
- {
- this.mLookRange = r;
- }
- protected override bool IsNearChanged(float x, float y)
- {
- return Zone.IsNearChanged(x, y, mLookRange);
- }
- protected override bool TestInView(InstanceZoneObject o, float x, float y)
- {
- return Collider.Object_BlockBody_TouchRound(o, x, y, mLookRange);
- }
- protected override void ForEachNearObjects(float x, float y, Action<InstanceZoneObject> indexer)
- {
- Zone.ForEachNearObjects(x, y, mLookRange, (InstanceZoneObject o, ref bool cancel) =>
- {
- indexer(o);
- });
- }
- /*
- public override void Check(InstanceZone zone, float x, float y, bool check)
- {
- if (check || zone.IsNearChanged(x, y, mLookRange))
- {
- // 检索已看到的消失
- for (int i = mViewd.Count - 1; i >= 0; --i)
- {
- InstanceZoneObject o = mViewd[i];
- if (!o.Enable || !mViewListener.select(this, o) || !Collider.Object_BlockBody_TouchRound(o, x, y, mLookRange))
- {
- mViewd.RemoveAt(i);
- onObjectLeaveView(o);
- }
- }
- zone.ForEachNearObjects(x, y, mLookRange, (InstanceZoneObject o, ref bool cancel) =>
- {
- if (o.Enable && mViewListener.select(this, o) && !mViewd.Contains(o) && Collider.Object_BlockBody_TouchRound(o, x, y, mLookRange))
- {
- mViewd.Add(o);
- onObjectEnterView(o);
- }
- });
- }
- }
- */
- }
- /// <summary>
- /// 观察目标坐标是否在矩形范围内
- /// </summary>
- public class ViewTriggerRectCenter : ViewTrigger
- {
- private float mSizeW;
- private float mSizeH;
- private float sx, sy, dx, dy;
- public ViewTriggerRectCenter(InstanceZone zone, float w, float h)
- : base(zone)
- {
- this.mSizeW = w;
- this.mSizeH = h;
- }
- protected override void check(float x, float y, bool check)
- {
- this.sx = x - mSizeW / 2;
- this.sy = y - mSizeH / 2;
- this.dx = sx + mSizeW;
- this.dy = sy + mSizeH;
- base.check(x, y, check);
- }
- protected override bool IsNearChanged(float x, float y)
- {
- return Zone.IsNearChanged(sx, sy, dx, dy);
- }
- protected override bool TestInView(InstanceZoneObject o, float x, float y)
- {
- return Collider.Object_Pos_IncludeInRect(o, sx, sy, dx, dy);
- }
- protected override void ForEachNearObjects(float x, float y, Action<InstanceZoneObject> indexer)
- {
- Zone.ForEachNearObjectsRect(sx, sy, dx, dy, (InstanceZoneObject o, ref bool cancel) =>
- {
- indexer(o);
- });
- }
- /*
- public override void Check(InstanceZone zone, float x, float y, bool check)
- {
- if (check || zone.IsNearChanged(x, y, x + mSizeW, y + mSizeH))
- {
- float sx = x - mSizeW / 2;
- float sy = y - mSizeH / 2;
- float dx = sx + mSizeW;
- float dy = sy + mSizeH;
- // 检索已看到的消失
- for (int i = mViewd.Count - 1; i >= 0; --i)
- {
- InstanceZoneObject o = mViewd[i];
- if (!o.Enable || !mViewListener.select(this, o) || !Collider.Object_Pos_IncludeInRect(o, sx, sy, dx, dy))
- {
- mViewd.RemoveAt(i);
- onObjectLeaveView(o);
- }
- }
- zone.ForEachNearObjectsRect(sx, sy, dx, dy, (InstanceZoneObject o, ref bool cancel) =>
- {
- if (o.Enable && mViewListener.select(this, o) && !mViewd.Contains(o) && Collider.Object_Pos_IncludeInRect(o, sx, sy, dx, dy))
- {
- mViewd.Add(o);
- onObjectEnterView(o);
- }
- });
- }
- }*/
- }
- /// <summary>
- /// 观察目标坐标是否在矩形范围内
- /// </summary>
- public class ViewTriggerStripCenter : ViewTrigger
- {
- private float mWidth;
- private float mHigh;
- private float mRange;
- private float mDirection;
- public ViewTriggerStripCenter(InstanceZone zone, float w, float h, float direction)
- : base(zone)
- {
- this.mWidth = w;
- this.mHigh = h;
- this.mRange = Math.Max(this.mWidth, this.mHigh);
- this.mDirection = direction;
- }
- protected override void check(float x, float y, bool check)
- {
- base.check(x, y, check);
-
- }
- protected override bool IsNearChanged(float x, float y)
- {
- return Zone.IsNearChanged(x, y, this.mRange);
- }
- protected override bool TestInView(InstanceZoneObject o, float x, float y)
- {
- Vector2 p0 = new Vector2(x, y);
- Vector2 p1 = new Vector2(x, y);
- MathVector.movePolar(p0, this.mDirection, -this.mHigh/2);
- MathVector.movePolar(p1, this.mDirection, +this.mHigh/2);
- return CMath.includeStripWidthPoint(p0.X, p0.Y, p1.X, p1.Y, this.mWidth, o.X, o.Y);
- //return Collider.Object_Pos_IncludeInRect(o, p0.x, p0.y, p1.x, p1.y);
- }
- protected override void ForEachNearObjects(float x, float y, Action<InstanceZoneObject> indexer)
- {
- Zone.ForEachNearObjects(x, y, this.mRange, (InstanceZoneObject o, ref bool cancel) =>
- {
- indexer(o);
- });
- }
- }
- /// <summary>
- /// 观察目标坐标是否在扇形范围内
- /// </summary>
- public class ViewTriggerFanCenter : ViewTrigger
- {
- private float mLookRange;
- private float mAngleRange;
- private float startAngle, endAngle;
- public float Direction { get; set; }
- public ViewTriggerFanCenter(InstanceZone zone, float range, float angle)
- : base(zone)
- {
- this.mLookRange = range;
- this.mAngleRange = angle;
- }
- public void SetLookRange(float r)
- {
- this.mLookRange = r;
- }
- protected override void check(float x, float y, bool check)
- {
- this.startAngle = Direction - mAngleRange;
- this.endAngle = Direction + mAngleRange;
- base.check(x, y, check);
- }
- protected override bool IsNearChanged(float x, float y)
- {
- return Zone.IsNearChanged(x, y, mLookRange);
- }
- protected override bool TestInView(InstanceZoneObject o, float x, float y)
- {
- return Collider.Object_Pos_IncludeInFan(o, x, y, mLookRange, startAngle, endAngle);
- }
- protected override void ForEachNearObjects(float x, float y, Action<InstanceZoneObject> indexer)
- {
- Zone.ForEachNearObjects(x, y, mLookRange, (InstanceZoneObject o, ref bool cancel) =>
- {
- indexer(o);
- });
- }
- /*
- public override void Check(InstanceZone zone, float x, float y, bool check)
- {
- float startAngle = Direction - mAngleRange;
- float endAngle = Direction + mAngleRange;
- for (int i = mViewd.Count - 1; i >= 0; --i)
- {
- InstanceZoneObject o = mViewd[i];
- if (!o.Enable || !mViewListener.select(this, o) || !Collider.Object_Pos_IncludeInFan(o, x, y, mLookRange, startAngle, endAngle))
- {
- mViewd.RemoveAt(i);
- onObjectLeaveView(o);
- }
- }
- zone.ForEachNearObjects(x, y, mLookRange, (InstanceZoneObject o, ref bool cancel) =>
- {
- if (o.Enable && mViewListener.select(this, o) && !mViewd.Contains(o) && Collider.Object_Pos_IncludeInFan(o, x, y, mLookRange, startAngle, endAngle))
- {
- mViewd.Add(o);
- onObjectEnterView(o);
- }
- });
- }*/
- }
- /// <summary>
- /// 观察目标身体是否在扇形范围内
- /// </summary>
- public class ViewTriggerFanBody : ViewTrigger
- {
- private float mLookRange;
- private float mAngleRange;
- private float startAngle, endAngle;
- public float Direction { get; set; }
- public ViewTriggerFanBody(InstanceZone zone, float range, float angle)
- : base(zone)
- {
- this.mLookRange = range;
- this.mAngleRange = angle;
- }
- public void SetLookRange(float r)
- {
- this.mLookRange = r;
- }
- protected override void check(float x, float y, bool check)
- {
- this.startAngle = Direction - mAngleRange / 2;
- this.endAngle = Direction + mAngleRange / 2;
- base.check(x, y, check);
- }
- protected override bool IsNearChanged(float x, float y)
- {
- return Zone.IsNearChanged(x, y, mLookRange);
- }
- protected override bool TestInView(InstanceZoneObject o, float x, float y)
- {
- return Collider.Object_BlockBody_TouchFan(o, x, y, mLookRange, startAngle, endAngle);
- }
- protected override void ForEachNearObjects(float x, float y, Action<InstanceZoneObject> indexer)
- {
- Zone.ForEachNearObjects(x, y, mLookRange, (InstanceZoneObject o, ref bool cancel) =>
- {
- indexer(o);
- });
- }
- /*
- public override void Check(InstanceZone zone, float x, float y, bool check)
- {
- float startAngle = Direction - mAngleRange;
- float endAngle = Direction + mAngleRange;
- for (int i = mViewd.Count - 1; i >= 0; --i)
- {
- InstanceZoneObject o = mViewd[i];
- if (!o.Enable || !mViewListener.select(this, o) || !Collider.Object_Pos_IncludeInFan(o, x, y, mLookRange, startAngle, endAngle))
- {
- mViewd.RemoveAt(i);
- onObjectLeaveView(o);
- }
- }
- zone.ForEachNearObjects(x, y, mLookRange, (InstanceZoneObject o, ref bool cancel) =>
- {
- if (o.Enable && mViewListener.select(this, o) && !mViewd.Contains(o) && Collider.Object_Pos_IncludeInFan(o, x, y, mLookRange, startAngle, endAngle))
- {
- mViewd.Add(o);
- onObjectEnterView(o);
- }
- });
- }*/
- }
- //-------------------------------------------------------------------------------------------
- }
|