using FFXIVClassic_Lobby_Server.common; 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 = 50; public int minX = -100, minY = -100, maxX = 100, maxY = 100; 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; for (int y = 0; y < numYBlocks; y++) { for (int x = 0; x < numXBlocks; x++ ) { actorBlock[x, y] = new List(); } } } #region Actor Management public void addActorToZone(Actor actor) { int gridX = (int)actor.positionX / boundingGridSize; int gridY = (int)actor.positionZ / 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.positionZ / 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.positionZ / 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.oldPositionZ / 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.positionZ / boundingGridSize; gridX += halfWidth; gridY += halfHeight; List result = new List(); for (int gy = ((gridY - checkDistance) < 0 ? 0 : (gridY - checkDistance)); gy <= ((gridY + checkDistance) >= numYBlocks ? numYBlocks - 1 : (gridY + checkDistance)); gy++) { for (int gx = ((gridX - checkDistance) < 0 ? 0 : (gridX - checkDistance)); gx <= ((gridX + checkDistance) >= numXBlocks ? numXBlocks - 1 : (gridX + checkDistance)); gx++) { result.AddRange(actorBlock[gx, gy]); } } return result; } #endregion } }