using FFXIVClassic_Map_Server.dataobjects; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FFXIVClassic_Map_Server { class Zone { public uint mapId; public ushort weatherNormal, weatherCommon, weatherRare; public ushort bgmDay, bgmNight, bgmBattle; public int boundingGridSize = 200; public int minX = -1000, minY = -1000, maxX = 1000, maxY = 1000; private int numXBlocks, numYBlocks; private int halfWidth, halfHeight; private List[,] actorBlock; public Zone() { numXBlocks = (maxX - minX) / boundingGridSize; numYBlocks = (maxY - minY) / boundingGridSize; actorBlock = new List[numXBlocks, numYBlocks]; halfWidth = numXBlocks / 2; halfHeight = numYBlocks / 2; } #region Actor Management public void addActorToZone(Actor actor) { int gridX = (int)actor.positionX / boundingGridSize; int gridY = (int)actor.positionY / boundingGridSize; gridX += halfWidth; gridY += halfHeight; //Boundries if (gridX < 0) gridX = 0; if (gridX >= numXBlocks) gridX = numXBlocks - 1; if (gridY < 0) gridY = 0; if (gridY >= numYBlocks) gridY = numYBlocks - 1; lock (actorBlock) actorBlock[gridX, gridY].Add(actor); } public void removeActorToZone(Actor actor) { int gridX = (int)actor.positionX / boundingGridSize; int gridY = (int)actor.positionY / boundingGridSize; gridX += halfWidth; gridY += halfHeight; //Boundries if (gridX < 0) gridX = 0; if (gridX >= numXBlocks) gridX = numXBlocks - 1; if (gridY < 0) gridY = 0; if (gridY >= numYBlocks) gridY = numYBlocks - 1; lock (actorBlock) actorBlock[gridX, gridY].Remove(actor); } public void updateActorPosition(Actor actor) { int gridX = (int)actor.positionX / boundingGridSize; int gridY = (int)actor.positionY / boundingGridSize; gridX += halfWidth; gridY += halfHeight; //Boundries if (gridX < 0) gridX = 0; if (gridX >= numXBlocks) gridX = numXBlocks - 1; if (gridY < 0) gridY = 0; if (gridY >= numYBlocks) gridY = numYBlocks - 1; int gridOldX = (int)actor.oldPositionX / boundingGridSize; int gridOldY = (int)actor.oldPositionY / boundingGridSize; gridOldX += halfWidth; gridOldY += halfHeight; //Boundries if (gridOldX < 0) gridOldX = 0; if (gridOldX >= numXBlocks) gridOldX = numXBlocks - 1; if (gridOldY < 0) gridOldY = 0; if (gridOldY >= numYBlocks) gridOldY = numYBlocks - 1; //Still in same block if (gridX == gridOldX && gridY == gridOldY) return; lock (actorBlock) actorBlock[gridOldX, gridOldY].Remove(actor); lock (actorBlock) actorBlock[gridX, gridY].Add(actor); } public List getActorsAroundPoint(float x, float y, int checkDistance) { int gridX = (int)x/boundingGridSize; int gridY = (int)y/boundingGridSize; gridX += halfWidth; gridY += halfHeight; //Boundries if (gridX < 0) gridX = 0; if (gridX >= numXBlocks) gridX = numXBlocks - 1; if (gridY < 0) gridY = 0; if (gridY >= numYBlocks) gridY = numYBlocks - 1; List result = new List(); for (int gx = gridX - checkDistance; gx <= gridX + checkDistance; gx++) { for (int gy = gridY - checkDistance; gy <= gridY + checkDistance; gy++) { result.AddRange(actorBlock[gx, gy]); } } return result; } public List getActorsAroundActor(Actor actor, int checkDistance) { int gridX = (int)actor.positionX / boundingGridSize; int gridY = (int)actor.positionY / boundingGridSize; gridX += halfWidth; gridY += halfHeight; //Boundries if (gridX < 0) gridX = 0; if (gridX >= numXBlocks) gridX = numXBlocks - 1; if (gridY < 0) gridY = 0; if (gridY >= numYBlocks) gridY = numYBlocks - 1; List result = new List(); for (int gx = gridX - checkDistance; gx <= gridX + checkDistance; gx++) { for (int gy = gridY - checkDistance; gy <= gridY + checkDistance; gy++) { result.AddRange(actorBlock[gx, gy]); } } return result; } #endregion } }