using System; using UnityEngine; using System.Collections; using System.Collections.Generic; namespace PvpGame { public class GridValue { public enum EntityType { None, Tree, Rock } public string id; public Vector3 position; public EntityType entityType; public GameObject go; } public class Grid { public static Dictionary grids = new Dictionary (); private Dictionary> cells = new Dictionary> (); private Dictionary objectIndex = new Dictionary (); private Dictionary cellsIndex = new Dictionary (); public static float coordOffset = 5000f; private int max; private int cellSize = 0; private float convFactor; private int width; private int cellCount; public Grid (int max, int cellSize) { this.max = max; this.cellSize = cellSize; this.convFactor = 1.0f / this.cellSize; this.width = (int)(this.max / this.cellSize); this.cellCount = this.width * this.width; } public int Count () { return objectIndex.Count; } public static Grid FindOrCreate (string id, int max, int cellSize) { if (!grids.ContainsKey (id)) { grids [id] = new Grid (max, cellSize); } return grids [id]; } public HashSet CellsWithinBounds (float x, float z) { x += coordOffset; z += coordOffset; HashSet mcells = new HashSet (); int offset = this.cellSize; int startX = (int)(x - offset); int startZ = (int)(z - offset); int endX = (int)(x + offset); int endZ = (int)(z + offset); for (int rowNum = startX; rowNum <= endX; rowNum += offset) { for (int colNum = startZ; colNum <= endZ; colNum += offset) { if (rowNum >= 0 && colNum >= 0) { mcells.Add (Hash (rowNum, colNum)); } } } return mcells; } public List Neighbors (float x, float z, GridValue.EntityType entityType) { List result = new List (); ICollection gridValues; HashSet cells = CellsWithinBounds (x, z); foreach (int cell in cells) { gridValues = GridValuesInCell (cell); if (gridValues == null) { continue; } foreach (GridValue gridValue in gridValues) { if (gridValue != null) { if (entityType == GridValue.EntityType.None) { result.Add (gridValue); } else if (gridValue.entityType == entityType) { result.Add (gridValue); } } } } return result; } public ICollection GridValuesInCell (int cell) { if (cells.ContainsKey (cell)) { return cells [cell].Values; } else { return null; } } public void Set (GridValue gridValue) { bool hasExisting = false; int oldCellValue = -1; string id = gridValue.id; if (objectIndex.ContainsKey (id)) { hasExisting = true; oldCellValue = cellsIndex [id]; } int cell = Hash (gridValue.position.x + coordOffset, gridValue.position.z + coordOffset); Dictionary cellGridValues; if (hasExisting && oldCellValue != cell) { if (cells.ContainsKey (oldCellValue)) { cellGridValues = cells [oldCellValue]; if (cellGridValues.ContainsKey (id)) { cellGridValues.Remove (id); } if (cellGridValues.Count == 0) { cells.Remove (oldCellValue); } } } cellsIndex [id] = cell; objectIndex [id] = gridValue; if (cells.ContainsKey (cell)) { cellGridValues = cells [cell]; cellGridValues [id] = gridValue; } else { cellGridValues = new Dictionary (); cellGridValues [id] = gridValue; cells [cell] = cellGridValues; } } public int Hash (float x, float z) { return (int)((x * this.convFactor)) + (int)((z * this.convFactor)) * this.width; } } }