123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using CommonLang;
- using CommonAI.RTS.Manhattan;
- using CommonAI.Zone.Helper;
- using CommonAI.RTS;
- using CommonLang.Vector;
- using CommonAI.Zone.Interface;
- using static CommonAI.ZoneServer.JSGModule.MSpaceNodeCache;
- using CommonAI.ZoneServer.JSGModule;
- namespace CommonAI.Zone.Instance
- {
- partial class InstanceZone
- {
- #region COLLIDE
- /// <summary>
- /// 2个单位是否碰撞
- /// </summary>
- /// <param name="s"></param>
- /// <param name="d"></param>
- /// <returns></returns>
- public virtual bool TouchObject2(InstanceZoneObject s, InstanceZoneObject d)
- {
- if (s == d) return false;
- float w = s.X - d.X;
- float h = s.Y - d.Y;
- float r = s.BodyBlockSize + d.BodyBlockSize;
- if (w * w + h * h <= r * r)
- {
- return true;
- }
- return false;
- }
- /// <summary>
- /// 单位和地图碰撞检测
- /// </summary>
- /// <param name="o"></param>
- /// <returns></returns>
- public virtual bool TouchMap(InstanceZoneObject o)
- {
- return path_finder.TouchMapBlock(
- (int)((o.X) / m_TerrainSrc.GridCellW),
- (int)((o.Y) / m_TerrainSrc.GridCellH));
- }
- /// <summary>
- /// 单位尝试用心的坐标和地图碰撞
- /// </summary>
- /// <param name="o"></param>
- /// <param name="x"></param>
- /// <param name="y"></param>
- /// <returns></returns>
- public virtual bool TryTouchMap(InstanceZoneObject o, float x, float y)
- {
- return path_finder.TouchMapBlock(
- (int)((x) / m_TerrainSrc.GridCellW),
- (int)((y) / m_TerrainSrc.GridCellH));
- }
- /// <summary>
- /// 单位尝试移动,并自动对齐到地图边界
- /// </summary>
- /// <param name="o"></param>
- /// <param name="x"></param>
- /// <param name="y"></param>
- /// <param name="dx"></param>
- /// <param name="dy"></param>
- /// <returns></returns>
- public virtual CommonAI.RTS.Manhattan.AstarManhattan.TryMoveToMapBorderResult TryMoveToMapBorder(InstanceZoneObject o, ref float x, ref float y, float dx, float dy)
- {
- return path_finder.TryMoveToMapBorder(ref x, ref y, dx, dy);
- }
- public virtual CommonAI.RTS.Manhattan.AstarManhattan.TryMoveToMapBorderResult TryMoveToMapBorder(InstanceZoneObject o, ref Vector2 pos, float dx, float dy)
- {
- float x = pos.X;
- float y = pos.Y;
- var result = path_finder.TryMoveToMapBorder(ref x, ref y, dx, dy);
- pos.SetX(x);
- pos.SetY(y);
- return result;
- }
- /// <summary>
- /// 单位视线是否和地图相交
- /// </summary>
- /// <param name="src"></param>
- /// <param name="sx"></param>
- /// <param name="sy"></param>
- /// <param name="dx"></param>
- /// <param name="dy"></param>
- /// <returns></returns>
- public virtual bool RaycastMap(InstanceUnit src, float sx, float sy, float dx, float dy)
- {
- if (CMath.includeRectPoint(0, 0, m_TerrainSrc.TotalWidth, m_TerrainSrc.TotalHeight, sx, sy) &&
- CMath.includeRectPoint(0, 0, m_TerrainSrc.TotalWidth, m_TerrainSrc.TotalHeight, dx, dy))
- {
- return path_finder.TouchMapLine(sx, sy, dx, dy);
- }
- return false;
- }
- public bool intersectMapByBlock(int bx, int by)
- {
- return path_finder.TouchMapBlock(bx, by);
- }
- public bool intersectMapByPos(float x, float y)
- {
- return path_finder.TouchMapBlock(
- (int)((x) / m_TerrainSrc.GridCellW),
- (int)((y) / m_TerrainSrc.GridCellH));
- }
- /// <summary>
- /// 当前单位是否和建筑碰撞
- /// </summary>
- /// <param name="a"></param>
- /// <returns></returns>
- public InstanceZoneObject intersectNearStaticBlockable(InstanceZoneObject a)
- {
- InstanceZoneObject ret = null;
- ForEachNearObjects(a.X, a.Y, (InstanceZoneObject o, ref bool cancel) =>
- {
- if (o.IsStaticBlockable && o.IntersectObj && TouchObject2(a, o))
- {
- ret = o;
- cancel = true;
- }
- });
- return ret;
- }
- /// <summary>
- /// 包含身体高度和建筑碰撞
- /// </summary>
- /// <param name="a"></param>
- /// <returns></returns>
- public InstanceZoneObject intersectNearStaticBlockableZ(InstanceZoneObject a)
- {
- InstanceZoneObject ret = null;
- ForEachNearObjects(a.X, a.Y, (InstanceZoneObject o, ref bool cancel) =>
- {
- if (o.IsStaticBlockable && o.IntersectObj)
- {
- if (CMath.IsIntersect2(a.Z, a.BodyHeight, o.Z, o.BodyHeight) && TouchObject2(a, o))
- {
- ret = o;
- cancel = true;
- }
- }
- });
- return ret;
- }
- /// <summary>
- /// 当前单位是否和单位碰撞
- /// </summary>
- /// <param name="a"></param>
- /// <returns></returns>
- public InstanceZoneObject intersectNearUnit(InstanceZoneObject a)
- {
- InstanceZoneObject ret = null;
- ForEachNearObjects(a.X, a.Y, (InstanceZoneObject o, ref bool cancel) =>
- {
- if ((o.IntersectObj) && TouchObject2(a, o))
- {
- ret = o;
- cancel = true;
- }
- });
- return ret;
- }
- #endregion
- //-------------------------------------------------------------------------------------------------------//
- #region MANHATTAN_MAP
- private ZoneManhattanMap path_terrain_data;
- private AstarManhattan path_finder;
- private ManhattanMapAreaGenerator path_terrain_area_gen;
-
- protected virtual void InitTerrain(ZoneEditor.SceneData data, int spaceDiv, out ZoneManhattanMap terrain_data, out AstarManhattan path_finder, out ManhattanMapAreaGenerator area_gen)
- {
- terrain_data = new ZoneManhattanMap(m_TerrainSrc.Clone() as ZoneInfo, Templates.TerrainDefinition);
- path_finder = new AstarManhattan(data.TemplateID, terrain_data, true, spaceDiv);
- area_gen = new ManhattanMapAreaGenerator(terrain_data.Data);
- }
- protected virtual void DisposeTerrain()
- {
- this.path_finder.Dispose();
- this.path_terrain_data.Dispose();
- this.path_finder = null;
- this.path_terrain_data = null;
- this.path_terrain_area_gen = null;
- this.sync_pos_list.Clear();
- }
- public AstarManhattan PathFinder
- {
- get { return path_finder; }
- }
- public ZoneManhattanMap PathFinderTerrain
- {
- get { return path_terrain_data; }
- }
- public ManhattanMapAreaGenerator TerrainAreaGenerator
- {
- get { return path_terrain_area_gen; }
- }
- public AstarManhattan.MWayPoint findPath(float sx, float sy, float dx, float dy)
- {
- AstarManhattan.MWayPoint ret;
- var result = path_finder.findPath(sx, sy, dx, dy, out ret);
- switch (result)
- {
- case AstarManhattan.FindPathResult.Cross:
- case AstarManhattan.FindPathResult.Destination:
- return ret;
- default:
- return null;
- }
- }
-
- public ZoneArea GetArea(float x, float y)
- {
- var node = PathFinder.GetMapNodeByPos(x, y) as ZoneMapNode;
- if (node != null)
- {
- return node.ServerArea;
- }
- return null;
- }
- public ZoneArea GetAreaByBlock(int bx, int by)
- {
- var node = PathFinder.GetMapNode(bx, by) as ZoneMapNode;
- if (node != null)
- {
- return node.ServerArea;
- }
- return null;
- }
- #endregion
- //-------------------------------------------------------------------------------------------------------//
- #region SPACE_DIVISION
- public int SpaceXCount { get { return mSpaceDiv.SpaceXCount; } }
- public int SpaceYCount { get { return mSpaceDiv.SpaceYCount; } }
- /// <summary>
- /// 按坐标取分割块
- /// </summary>
- /// <param name="x"></param>
- /// <param name="y"></param>
- /// <returns></returns>
- public SpaceDivision.SpaceCellNode GetSpaceCellNode(float x, float y)
- {
- return mSpaceDiv.GetSpaceCellNode(x, y);
- }
- /// <summary>
- /// 按格取分割块
- /// </summary>
- /// <param name="bx"></param>
- /// <param name="by"></param>
- /// <returns></returns>
- public SpaceDivision.SpaceCellNode GetSpaceCellNodeByBlock(int bx, int by)
- {
- return mSpaceDiv.GetSpaceCellNodeByBlock(bx, by);
- }
- public List<SpaceDivision.SpaceCellNode> ListSpaceCellNodes()
- {
- return mSpaceDiv.ListSpaceCellNodes();
- }
- /// <summary>
- /// 刷新空间分割位置为有改变
- /// </summary>
- /// <param name="obj"></param>
- internal void nearChange(InstanceZoneObject obj)
- {
- mSpaceDiv.NearChange(obj.mCurCellNode);
- }
- /// <summary>
- /// 清除空间位置
- /// </summary>
- /// <param name="obj"></param>
- internal void clearSpace(InstanceZoneObject obj)
- {
- mSpaceDiv.ClearSpace(obj.mCurCellNode);
- }
-
- internal bool swapSpace(InstanceZoneObject obj, bool nearchange)
- {
- SpaceDivision.SpaceCellNode old_cell = obj.CurrentSpaceCellNode;
- if (mSpaceDiv.SwapSpace(obj.mCurCellNode, obj.X, obj.Y, nearchange))
- {
- if (mOnObjectSpaceChanged != null)
- {
- SpaceDivision.SpaceCellNode new_cell = obj.CurrentSpaceCellNode;
- mOnObjectSpaceChanged.Invoke(this, obj, old_cell, new_cell);
- }
- return true;
- }
- return false;
- }
- internal void swapArea(InstanceZoneObject obj, ZoneArea o, ZoneArea n)
- {
- if (o != null && o.Enable) { o.do_onUnitLeave(obj); }
- if (n != null && n.Enable) { n.do_onUnitEnter(obj); }
- if (mOnObjectAreaChanged != null)
- {
- mOnObjectAreaChanged.Invoke(this, obj, o, n);
- }
- }
- /// <summary>
- /// 判断是否附近有位置变化
- /// </summary>
- /// <param name="x"></param>
- /// <param name="y"></param>
- /// <returns></returns>
- public bool IsNearChanged(float x, float y)
- {
- return mSpaceDiv.IsNearChanged(x, y);
- }
- public bool IsNearChanged(float x, float y, float r)
- {
- return mSpaceDiv.IsNearChanged(x, y, r);
- }
- public bool IsNearChanged(float x1, float y1, float x2, float y2)
- {
- return mSpaceDiv.IsNearChanged(x1, y1, x2, y2);
- }
- /// <summary>
- /// 获取当前坐标附近的所有单位容量
- /// </summary>
- /// <param name="x"></param>
- /// <param name="y"></param>
- /// <returns></returns>
- public int getNearObjectsCapacity(float x, float y)
- {
- return mSpaceDiv.GetNearObjectsCapacity(x, y);
- }
- /**
- * 以目标点为中心,circle为半径,找可行走区域。找到了返回true;找不到返回false;
- * sx, sy 起始位置
- * dstx, dsty 目标位置
- * circle 搜寻半径
- * outx, outy修改后的目标点
- */
- public bool GetNearWay(float sx, float sy, float dstx, float dsty, float circle, ref float outx, ref float outy)
- {
- //以目标点为中心,一圈一圈向外查找可行走的块
- //起始点与终点连线方向上的点优先
- int W = Terrain.GridCellW;
- int H = Terrain.GridCellH;
- float squCircle = circle * circle;
- int dr = ((int)circle) / W;
- float vx = sx > dstx ? 1 : -1;
- float vy = sy > dsty ? 1 : -1;
- bool f = true;
- for (int r = 1; r <= dr; r++)
- {
- for (int v = 1; v <= 4; v++)
- {
- float xx = dstx + W * r * vx;
- float yy = dsty + H * r * vy;
- for (int dx = f ? 0 : 1; f ? dx <= r : dx < r; dx++)
- {
- float x = dstx + dx * W * vx;
- if (MathVector.getDistanceSquare(x, yy, dstx, dsty) < squCircle)
- {
- if (!path_finder.TouchMapBlock(((int)x) / W, ((int)yy) / H) && findPath(sx, sy, x, yy) != null)
- {
- outx = x;
- outy = yy;
- return true;
- }
- }
- }
- for (int dy = f ? 1 : 0; f ? dy < r : dy <= r; dy++)
- {
- float y = dsty + dy * H * vy;
- if (MathVector.getDistanceSquare(xx, y, dstx, dsty) < squCircle)
- {
- if (!path_finder.TouchMapBlock(((int)xx) / W, ((int)y) / H) && findPath(sx, sy, xx, y) != null)
- {
- outx = xx;
- outy = y;
- return true;
- }
- }
- }
- if (f) vy *= -1;
- else vx *= -1;
- f = !f;
- }
- }
- outx = -1;
- outy = -1;
- return false;
- }
- //---------------------------------------------------------------------------------------------------------------
- #region _Deprecated_
- /// <summary>
- /// 获取当前坐标附近的所有单位
- /// </summary>
- /// <param name="x"></param>
- /// <param name="y"></param>
- /// <returns></returns>
- [Obsolete("use {@link #ForEachNearObjects} for best performance!")]
- public List<InstanceZoneObject> getNearObjects(float x, float y)
- {
- List<InstanceZoneObject> list = new List<InstanceZoneObject>(getNearObjectsCapacity(x, y));
- getNearObjects(x, y, list);
- return list;
- }
- /// <summary>
- /// 获取当前圆形坐标附近所有单位
- /// </summary>
- /// <param name="x"></param>
- /// <param name="y"></param>
- /// <param name="r"></param>
- /// <returns></returns>
- [Obsolete("use {@link #ForEachNearObjects} for best performance!")]
- public List<InstanceZoneObject> getNearObjects(float x, float y, float r)
- {
- List<InstanceZoneObject> list = new List<InstanceZoneObject>(getNearObjectsCapacity(x, y));
- getNearObjects(x, y, r, list);
- return list;
- }
- /// <summary>
- /// 获取当前矩形附近所有单位
- /// </summary>
- /// <param name="x1"></param>
- /// <param name="y1"></param>
- /// <param name="x2"></param>
- /// <param name="y2"></param>
- /// <returns></returns>
- [Obsolete("use {@link #ForEachNearObjectsRect} for best performance!")]
- public List<InstanceZoneObject> getNearObjectsRect(float x1, float y1, float x2, float y2)
- {
- List<InstanceZoneObject> list = new List<InstanceZoneObject>();
- getNearObjectsRect(x1, y1, x2, y2, list);
- return list;
- }
-
- //----------------------------------------------------------------------------------------------------------------------------
-
- /// <summary>
- /// 获取当前坐标附近的所有单位
- /// </summary>
- /// <param name="x"></param>
- /// <param name="y"></param>
- /// <param name="list"></param>
- [Obsolete]
- private void getNearObjects(float x, float y, List<InstanceZoneObject> list)
- {
- SpaceDivision.SpaceCellNode node = mSpaceDiv.GetSpaceCellNode(x, y);
- if (node != null)
- {
- list.AddRange(node.AsChildList<InstanceZoneObject>());
- for (int i = node.nears.Count - 1; i >= 0; --i)
- {
- list.AddRange(node.nears[i].AsChildList<InstanceZoneObject>());
- }
- }
- }
- /// <summary>
- /// 获取当前坐标附近的所有单位
- /// </summary>
- /// <param name="x"></param>
- /// <param name="y"></param>
- /// <param name="r"></param>
- /// <param name="list"></param>
- [Obsolete]
- private void getNearObjects(float x, float y, float r, List<InstanceZoneObject> list)
- {
- if (r < mSpaceDiv.SpaceCellW && r < mSpaceDiv.SpaceCellH)
- {
- SpaceDivision.SpaceCellNode node = mSpaceDiv.GetSpaceCellNode(x, y);
- if (node != null)
- {
- list.AddRange(node.AsChildList<InstanceZoneObject>());
- for (int i = node.nears.Count - 1; i >= 0; --i)
- {
- list.AddRange(node.nears[i].AsChildList<InstanceZoneObject>());
- }
- }
- }
- else
- {
- int cx1 = ((int)((x - r) / mSpaceDiv.SpaceCellW)) - 1;
- int cy1 = ((int)((y - r) / mSpaceDiv.SpaceCellH)) - 1;
- int cx2 = ((int)((x + r) / mSpaceDiv.SpaceCellW)) + 1;
- int cy2 = ((int)((y + r) / mSpaceDiv.SpaceCellH)) + 1;
- cx1 = Math.Max(cx1, 0);
- cy1 = Math.Max(cy1, 0);
- cx2 = Math.Min(cx2, mSpaceDiv.SpaceXCount - 1);
- cy2 = Math.Min(cy2, mSpaceDiv.SpaceYCount - 1);
- for (int cx = cx1; cx <= cx2; ++cx)
- {
- for (int cy = cy1; cy <= cy2; ++cy)
- {
- SpaceDivision.SpaceCellNode cn = mSpaceDiv.GetSpaceCellNodeByBlock(cx, cy);
- list.AddRange(cn.AsChildList<InstanceZoneObject>());
- }
- }
- }
- }
- /// <summary>
- /// 获取当前坐标附近的所有单位
- /// </summary>
- /// <param name="x1"></param>
- /// <param name="y1"></param>
- /// <param name="x2"></param>
- /// <param name="y2"></param>
- /// <param name="list"></param>
- [Obsolete]
- private void getNearObjectsRect(float x1, float y1, float x2, float y2, List<InstanceZoneObject> list)
- {
- int cx1 = ((int)((Math.Min(x1, x2)) / mSpaceDiv.SpaceCellW)) - 1;
- int cy1 = ((int)((Math.Min(y1, y2)) / mSpaceDiv.SpaceCellH)) - 1;
- int cx2 = ((int)((Math.Max(x1, x2)) / mSpaceDiv.SpaceCellW)) + 1;
- int cy2 = ((int)((Math.Max(y1, y2)) / mSpaceDiv.SpaceCellH)) + 1;
- cx1 = Math.Max(cx1, 0);
- cy1 = Math.Max(cy1, 0);
- cx2 = Math.Min(cx2, mSpaceDiv.SpaceXCount - 1);
- cy2 = Math.Min(cy2, mSpaceDiv.SpaceYCount - 1);
- for (int cx = cx1; cx <= cx2; ++cx)
- {
- for (int cy = cy1; cy <= cy2; ++cy)
- {
- SpaceDivision.SpaceCellNode cn = mSpaceDiv.GetSpaceCellNodeByBlock(cx, cy);
- list.AddRange(cn.AsChildList<InstanceZoneObject>());
- }
- }
- }
- #endregion
- //----------------------------------------------------------------------------------------------------------------------------
- /// <summary>
- /// 获取当前坐标附近的所有单位
- /// </summary>
- /// <param name="x"></param>
- /// <param name="y"></param>
- /// <param name="indexer"></param>
- /// <returns>is cancel</returns>
- public bool ForEachNearObjects<T>(float x, float y, SpaceDivision.ObjectForEachAction<T> indexer) where T : InstanceZoneObject
- {
- return mSpaceDiv.ForEachNearObjects(x, y, indexer);
- }
- /// <summary>
- /// 获取当前坐标附近的所有单位
- /// </summary>
- /// <param name="x"></param>
- /// <param name="y"></param>
- /// <param name="r"></param>
- /// <param name="indexer"></param>
- /// <returns>is cancel</returns>
- public bool ForEachNearObjects<T>(float x, float y, float r, SpaceDivision.ObjectForEachAction<T> indexer) where T : InstanceZoneObject
- {
- return mSpaceDiv.ForEachNearObjects(x, y, r, indexer);
- }
- /// <summary>
- /// 获取当前坐标附近的所有单位
- /// </summary>
- /// <param name="x1"></param>
- /// <param name="y1"></param>
- /// <param name="x2"></param>
- /// <param name="y2"></param>
- /// <param name="indexer"></param>
- /// <returns>is cancel</returns>
- public bool ForEachNearObjectsRect<T>(float x1, float y1, float x2, float y2, SpaceDivision.ObjectForEachAction<T> indexer) where T : InstanceZoneObject
- {
- return mSpaceDiv.ForEachNearObjectsRect(x1, y1, x2, y2, indexer);
- }
- //----------------------------------------------------------------------------------------------------------------------------
- /// <summary>
- /// 获取【矩形】范围内的所有单位
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="func"></param>
- /// <param name="x1"></param>
- /// <param name="y1"></param>
- /// <param name="x2"></param>
- /// <param name="y2"></param>
- /// <param name="list"></param>
- /// <param name="aoi"></param>
- /// <returns></returns>
- public int getObjectsRectRange<T>(
- Collider.ObjectBodyTouchRect func,
- float x1, float y1,
- float x2, float y2,
- List<T> list, ObjectAoiStatus aoi) where T : InstanceZoneObject
- {
- int count = 0;
- ForEachNearObjectsRect<T>(x1, y1, x2, y2, (T o, ref bool cancel) =>
- {
- if (o.AoiStatus == aoi && func(o, x1, y1, x2, y2))
- {
- if (list != null) list.Add(o as T);
- count++;
- }
- });
- return count;
- }
- [Obsolete]
- public List<T> getObjectsRectRange<T>(
- Collider.ObjectBodyTouchRect func,
- float x1, float y1,
- float x2, float y2, ObjectAoiStatus aoi) where T : InstanceZoneObject
- {
- List<T> ret = new List<T>(getNearObjectsCapacity(x1, y1));
- getObjectsRectRange<T>(func, x1, y1, x2, y2, ret, aoi);
- return ret;
- }
- public int getObjectsCountRectRange<T>(
- Collider.ObjectBodyTouchRect func,
- float x1, float y1,
- float x2, float y2, ObjectAoiStatus aoi) where T : InstanceZoneObject
- {
- return getObjectsRectRange<T>(func, x1, y1, x2, y2, null, aoi);
- }
- /// <summary>
- /// 获取【圆形】范围内的所有单位
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="func"></param>
- /// <param name="x"></param>
- /// <param name="y"></param>
- /// <param name="r"></param>
- /// <param name="list"></param>
- /// <param name="aoi"></param>
- /// <returns></returns>
- public int getObjectsRoundRange<T>(
- Collider.ObjectBodyTouchRound func,
- float x, float y, float r,
- List<T> list, ObjectAoiStatus aoi) where T : InstanceZoneObject
- {
- int count = 0;
- ForEachNearObjects(x, y, r, (T o, ref bool cancel) =>
- {
- if (o.AoiStatus == aoi && func(o, x, y, r))
- {
- if (list != null) list.Add(o as T);
- count++;
- }
- });
- return count;
- }
- //单位是否在范围内
- public InstanceUnit isUnitInRoundRange<T>(int unitID, float x, float y, float r, ObjectAoiStatus aoi) where T : InstanceUnit
- {
- InstanceUnit unit = null;
- ForEachNearObjects(x, y, r, (T o, ref bool cancel) =>
- {
- if (o.AoiStatus == aoi && o.Info.TemplateID == unitID)
- {
- cancel = true;
- unit = o;
- }
- });
- return unit;
- }
- [Obsolete]
- public List<T> getObjectsRoundRange<T>(
- Collider.ObjectBodyTouchRound func,
- float x, float y, float r, ObjectAoiStatus aoi) where T : InstanceZoneObject
- {
- List<T> ret = new List<T>(getNearObjectsCapacity(x, y));
- getObjectsRoundRange<T>(func, x, y, r, ret, aoi);
- return ret;
- }
- public int getObjectsCountRoundRange<T>(
- Collider.ObjectBodyTouchRound func,
- float x, float y, float r, ObjectAoiStatus aoi) where T : InstanceZoneObject
- {
- return getObjectsRoundRange<T>(func, x, y, r, null, aoi);
- }
- /// <summary>
- /// 获取【扇形】范围内的所有单位,扇形范围为【弧度】
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="func"></param>
- /// <param name="x"></param>
- /// <param name="y"></param>
- /// <param name="distance"></param>
- /// <param name="startAngle"></param>
- /// <param name="endAngle"></param>
- /// <param name="list"></param>
- /// <param name="aoi"></param>
- /// <returns></returns>
- public int getObjectsFanRange<T>(
- Collider.ObjectBodyTouchFan func,
- float x, float y, float distance,
- float startAngle, float endAngle,
- List<T> list, ObjectAoiStatus aoi) where T : InstanceZoneObject
- {
- int count = 0;
- ForEachNearObjects(x, y, distance, (T o, ref bool cancel) =>
- {
- if (o.AoiStatus == aoi && func(o, x, y, distance, startAngle, endAngle))
- {
- if (list != null) list.Add(o as T);
- count++;
- }
- });
- return count;
- }
- [Obsolete]
- public List<T> getObjectsFanRange<T>(
- Collider.ObjectBodyTouchFan func,
- float x, float y, float distance,
- float startAngle, float endAngle, ObjectAoiStatus aoi) where T : InstanceZoneObject
- {
- List<T> ret = new List<T>(getNearObjectsCapacity(x, y));
- getObjectsFanRange<T>(func, x, y, distance, startAngle, endAngle, ret, aoi);
- return ret;
- }
- /// <summary>
- /// 获取【直线】穿过范围内的所有单位(粗线段)
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="func"></param>
- /// <param name="x1"></param>
- /// <param name="y1"></param>
- /// <param name="x2"></param>
- /// <param name="y2"></param>
- /// <param name="line_r"></param>
- /// <param name="list"></param>
- /// <param name="aoi"></param>
- /// <returns></returns>
- public int getObjectsRectLineRange<T>(
- Collider.ObjectBodyTouchRectLine func,
- float x1, float y1, float x2, float y2, float line_r,
- List<T> list, ObjectAoiStatus aoi) where T : InstanceZoneObject
- {
- int count = 0;
- ForEachNearObjectsRect(x1, y1, x2, y2, (T o, ref bool cancel) =>
- {
- if (o.AoiStatus == aoi && func(o, x1, y1, x2, y2, line_r))
- {
- if (list != null) list.Add(o as T);
- count++;
- }
- });
- return count;
- }
- [Obsolete]
- public List<T> getObjectsRectLineRange<T>(
- Collider.ObjectBodyTouchRectLine func,
- float x1, float y1, float x2, float y2, float line_r, ObjectAoiStatus aoi) where T : InstanceZoneObject
- {
- List<T> ret = new List<T>(getNearObjectsCapacity(x1, y1));
- getObjectsRectLineRange(func, x1, y1, x2, y2, line_r, ret, aoi);
- return ret;
- }
- /// <summary>
- /// 单位【运动轨迹】从A点移动到B点经过的碰撞
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="func"></param>
- /// <param name="sx"></param>
- /// <param name="sy"></param>
- /// <param name="dx"></param>
- /// <param name="dy"></param>
- /// <param name="line_r"></param>
- /// <param name="list"></param>
- /// <param name="aoi"></param>
- /// <returns></returns>
- public int getObjectsRoundLineRange<T>(
- Collider.ObjectBodyTouchRoundLine func,
- float sx, float sy, float dx, float dy, float line_r,
- List<T> list , ObjectAoiStatus aoi) where T : InstanceZoneObject
- {
- int count = 0;
- ForEachNearObjectsRect(sx, sy, dx, dy, (T o, ref bool cancel) =>
- {
- if (aoi == o.AoiStatus && func(o, sx, sy, dx, dy, line_r))
- {
- if (list != null) list.Add(o as T);
- count++;
- }
- });
- return count;
- }
- [Obsolete]
- public List<T> getObjectsRoundLineRange<T>(
- Collider.ObjectBodyTouchRoundLine func,
- float sx, float sy, float dx, float dy, float line_r, ObjectAoiStatus aoi) where T : InstanceZoneObject
- {
- List<T> ret = new List<T>(getNearObjectsCapacity(sx, sy));
- getObjectsRoundLineRange<T>(func, sx, sy, dx, dy, line_r, ret , aoi);
- return ret;
- }
- #endregion
- //-------------------------------------------------------------------------------------------------------//
- protected List<SyncPosEvent.UnitPos> m_UnitsPos = new List<SyncPosEvent.UnitPos>();
- protected List<SyncPosEvent.UnitState> m_UnitsStates = new List<SyncPosEvent.UnitState>();
- #region SYNC_POS
- /// <summary>
- /// 获得场景当前所有装饰物状态
- /// </summary>
- /// <returns></returns>
- public ZoneClient.SyncFlagsEvent GetSyncFlagsEvent()
- {
- var ret = new ZoneClient.SyncFlagsEvent();
- foreach (InstanceFlag flag in mFlags.Values)
- {
- if (flag is ZoneDecoration)
- {
- ZoneDecoration d = flag as ZoneDecoration;
- if (!d.Enable)
- {
- ret.ClosedDecorations.Add(d.Name);
- }
- }
- if (flag.Tag != flag.SrcTag)
- {
- ret.ChangedTags.Add(flag.Name, flag.Tag);
- }
- }
- return ret;
- }
- /// <summary>
- /// 获得所有单位同步信息,一般在进入场景时同步
- /// </summary>
- /// <param name="exclude"></param>
- /// <returns></returns>
- public ZoneClient.SyncObjectsEvent GetSyncUnitsEvent(InstanceUnit exclude = null)
- {
- var objs = mObjects.Objects;
- ZoneClient.SyncObjectsEvent ret = new ZoneClient.SyncObjectsEvent(mObjects.ObjectsCount);
- foreach (InstanceZoneObject o in objs)
- {
- if ((exclude == null || o != exclude) && o.ClientVisible)
- {
- var sync = o.GenSyncInfo(true);
- ret.Objects.Add(sync);
- }
- }
- return ret;
- }
- /// <summary>
- /// 获得半径内所有单位同步信息
- /// </summary>
- /// <param name="x"></param>
- /// <param name="y"></param>
- /// <param name="r"></param>
- /// <param name="exclude"></param>
- /// <returns></returns>
- public ZoneClient.SyncObjectsEvent GetSyncUnitsEventInRange(float x, float y, float r, InstanceUnit exclude = null)
- {
- ZoneClient.SyncObjectsEvent ret = new ZoneClient.SyncObjectsEvent(getNearObjectsCapacity(x, y));
- ForEachNearObjects(x, y, r, (InstanceZoneObject o, ref bool cancel) =>
- {
- if ((exclude == null || o != exclude) && o.ClientVisible)
- {
- if (Collider.Object_Pos_IncludeInRound(o, x, y, r))
- {
- var sync = o.GenSyncInfo(true);
- ret.Objects.Add(sync);
- }
- }
- });
- return ret;
- }
- /// <summary>
- /// 获得空间分割块所有单位同步信息
- /// </summary>
- /// <param name="bx"></param>
- /// <param name="by"></param>
- /// <param name="exclude"></param>
- /// <returns></returns>
- public ZoneClient.SyncObjectsEvent GetSyncUnitsEventBySpace(int bx, int by, InstanceUnit exclude = null)
- {
- SpaceDivision.SpaceCellNode space = GetSpaceCellNodeByBlock(bx, by);
- if (space != null)
- {
- ZoneClient.SyncObjectsEvent ret = new ZoneClient.SyncObjectsEvent(space.Count);
- space.ForEach((InstanceZoneObject o, ref bool cancel) =>
- {
- if ((exclude == null || o != exclude) && o.ClientVisible)
- {
- var sync = o.GenSyncInfo(true);
- ret.Objects.Add(sync);
- }
- });
- return ret;
- }
- return null;
- }
- public ZoneClient.SyncObjectsEvent GetSyncObjectsEvent(ICollection<InstanceZoneObject> objs)
- {
- ZoneClient.SyncObjectsEvent ret = new ZoneClient.SyncObjectsEvent(objs.Count);
- foreach (InstanceZoneObject o in objs)
- {
- if (o.ClientVisible)
- {
- var sync = o.GenSyncInfo(true);
- ret.Objects.Add(sync);
- }
- }
- return ret;
- }
- /// <summary>
- /// 得到半径范围内的所有移动信息
- /// </summary>
- /// <param name="x"></param>
- /// <param name="y"></param>
- /// <param name="range"></param>
- /// <returns></returns>
- public SyncPosEvent GetSyncPosEventInRange(float x, float y, float range)
- {
- using (var units = ListObjectPool<SyncPosEvent.UnitPos>.AllocAutoRelease())
- using (var units_st = ListObjectPool<SyncPosEvent.UnitState>.AllocAutoRelease())
- {
- SyncPosEvent.UnitPos pos = new SyncPosEvent.UnitPos();
- SyncPosEvent.UnitState st = new SyncPosEvent.UnitState();
- ForEachNearObjects(x, y, range, (InstanceZoneObject u, ref bool cancel) =>
- {
- if (u.ClientVisible && u.SyncPos && u.mCurCellNode.PosDirty())
- {
- if (Collider.Object_Pos_IncludeInRound(u, x, y, range))
- {
- if (u.GenSyncPos(ref pos))
- {
- units.Add(pos);
- }
- if (u is InstanceUnit)
- {
- InstanceUnit unit = u as InstanceUnit;
- if (unit.GenSyncState(ref st))
- {
- units_st.Add(st);
- }
- }
- }
- }
- });
- if (units.Count > 0 || units_st.Count > 0)
- {
- SyncPosEvent ret = new SyncPosEvent(IsHalfSync, IsSyncZ, (uint)PassTimeMS);
- ret.units_pos = units.ToArray();
- ret.units_st = units_st.ToArray();
- return ret;
- }
- }
- return null;
- }
- /// <summary>
- /// 得到空间分割块范围内的所有移动信息
- /// </summary>
- /// <param name="bx"></param>
- /// <param name="by"></param>
- /// <returns></returns>
- public SyncPosEvent GetSyncPosEventBySpace(int bx, int by)
- {
- SpaceDivision.SpaceCellNode space = GetSpaceCellNodeByBlock(bx, by);
- if (space != null)
- {
- List<SyncPosEvent.UnitPos> units = new List<SyncPosEvent.UnitPos>(space.Count);
- List<SyncPosEvent.UnitState> units_st = new List<SyncPosEvent.UnitState>(space.Count);
- SyncPosEvent.UnitPos pos = new SyncPosEvent.UnitPos();
- SyncPosEvent.UnitState st = new SyncPosEvent.UnitState();
- space.ForEach((InstanceZoneObject u, ref bool cancel) =>
- {
- if (u.mCurCellNode.PosDirty() && u.ClientVisible && u.SyncPos)
- {
- if (u.GenSyncPos(ref pos))
- {
- units.Add(pos);
- }
- if (u is InstanceUnit)
- {
- InstanceUnit unit = u as InstanceUnit;
- if (unit.GenSyncState(ref st))
- {
- units_st.Add(st);
- }
- }
- }
- });
- if (units.Count > 0 || units_st.Count > 0)
- {
- SyncPosEvent ret = new SyncPosEvent(IsHalfSync, IsSyncZ, (uint)PassTimeMS);
- ret.units_pos = units.ToArray();
- ret.units_st = units_st.ToArray();
- return ret;
- }
- }
- return null;
- }
- public SyncPosEvent GetSyncPosEvent(ICollection<InstanceZoneObject> objs, InstancePlayer Actor, PlayerClientObject playerClient)
- {
- if (objs.Count > 0)
- {
- //using (var units = ListObjectPool<SyncPosEvent.UnitPos>.AllocAutoRelease())
- //using (var units_st = ListObjectPool<SyncPosEvent.UnitState>.AllocAutoRelease())
- m_UnitsPos.Clear();
- m_UnitsStates.Clear();
- {
- SyncPosEvent.UnitPos pos = new SyncPosEvent.UnitPos();
- SyncPosEvent.UnitState st = new SyncPosEvent.UnitState();
- foreach (InstanceZoneObject u in objs)
- {
- if (u.mCurCellNode.PosDirty() && u.ClientVisible && u.SyncPos)
- {
- InstanceUnit unitTemp = u as InstanceUnit;
- if(unitTemp != null && unitTemp.CurrentActionSubstate != 0 && Actor.CurrentActionSubstate != unitTemp.CurrentActionSubstate)
- {
- if (playerClient.RemoveInRange(u))
- {
- continue;
- }
- }
-
- if (u.GenSyncPos(ref pos))
- {
- m_UnitsPos.Add(pos);
- }
- if (u is InstanceUnit)
- {
- InstanceUnit unit = u as InstanceUnit;
- if (unit.GenSyncState(ref st))
- {
- m_UnitsStates.Add(st);
- }
- }
- }
- }
- if (m_UnitsPos.Count > 0 || m_UnitsStates.Count > 0)
- {
- SyncPosEvent ret = new SyncPosEvent(IsHalfSync, IsSyncZ, PassTimeMS);
- ret.units_pos = m_UnitsPos.ToArray();
- ret.units_st = m_UnitsStates.ToArray();
- return ret;
- }
- }
- }
- return null;
- }
- readonly private PositionList sync_pos_list = new PositionList();
- internal class PositionList
- {
- public bool Enable = true;
- private List<InstanceZoneObject> units = new List<InstanceZoneObject>();
- public void Add(InstanceZoneObject u)
- {
- if (Enable)
- {
- units.Add(u);
- }
- }
- public void Clear()
- {
- units.Clear();
- }
- public SyncPosEvent AsEvent(InstanceZone zone)
- {
- if (Enable)
- {
- using (var units_pos = ListObjectPool<SyncPosEvent.UnitPos>.AllocAutoRelease())
- using (var units_st = ListObjectPool<SyncPosEvent.UnitState>.AllocAutoRelease())
- {
- SyncPosEvent.UnitPos pos = new SyncPosEvent.UnitPos();
- SyncPosEvent.UnitState st = new SyncPosEvent.UnitState();
- for (int i = units.Count - 1; i >= 0; --i)
- {
- InstanceZoneObject obj = units[i];
- if (obj.GenSyncPos(ref pos))
- {
- units_pos.Add(pos);
- }
- if (obj is InstanceUnit)
- {
- InstanceUnit unit = obj as InstanceUnit;
- if (unit.GenSyncState(ref st))
- {
- units_st.Add(st);
- }
- }
- }
- SyncPosEvent ret = new SyncPosEvent(zone.IsHalfSync, zone.IsSyncZ, (uint)zone.PassTimeMS);
- ret.units_pos = units_pos.ToArray();
- ret.units_st = units_st.ToArray();
- return ret;
- }
- }
- return null;
- }
- public int Count { get { return units.Count; } }
- }
- #endregion
- }
- }
|