using System.Collections.Generic; using System.Linq; using UnityEngine; namespace Gley.UrbanSystem.Internal { public class GridDataHandler { private readonly GridData _gridData; public GridDataHandler(GridData data) { _gridData = data; } public int GetCellSize() { return _gridData.GridCellSize; } private RowData[] GetGrid() { return _gridData.Grid; } /// /// Get all specified neighbors for the specified depth /// /// current row /// current column /// how far the cells should be /// ignore middle cells /// Returns the neighbors of the given cells internal List GetCellNeighbors(int row, int column, int depth, bool justEdgeCells) { List result = new List(); int rowMinimum = row - depth; if (rowMinimum < 0) { rowMinimum = 0; } int rowMaximum = row + depth; if (rowMaximum >= GetGridLength()) { rowMaximum = GetGridLength() - 1; } int columnMinimum = column - depth; if (columnMinimum < 0) { columnMinimum = 0; } int columnMaximum = column + depth; if (columnMaximum >= GetRowLength(row)) { columnMaximum = GetRowLength(row) - 1; } for (int i = rowMinimum; i <= rowMaximum; i++) { for (int j = columnMinimum; j <= columnMaximum; j++) { if (justEdgeCells) { if (i == row + depth || i == row - depth || j == column + depth || j == column - depth) { result.Add(new Vector2Int(i, j)); } } else { result.Add(new Vector2Int(i, j)); } } } return result; } /// /// Convert position to Grid cell. /// public CellData GetCell(Vector3 position) { return GetCell(position.x, position.z); } /// /// Convert indexes to Grid cell. /// public CellData GetCell(float xPoz, float zPoz) { int rowIndex = Mathf.FloorToInt(Mathf.Abs((GetGridCorner().z - zPoz) / GetCellSize())); int columnIndex = Mathf.FloorToInt(Mathf.Abs((GetGridCorner().x - xPoz) / GetCellSize())); return GetGrid()[rowIndex].Row[columnIndex]; } public Vector3 GetGridCorner() { return _gridData.GridCorner; } public CellData GetCell(Vector2Int cellIndex) { return GetGrid()[cellIndex.x].Row[cellIndex.y]; } public int GetGridLength() { return GetGrid().Length; } public int GetRowLength(int row) { return GetGrid()[row].Row.Length; } public Vector2Int GetCellIndex(Vector3 position) { int rowIndex = Mathf.FloorToInt(Mathf.Abs((GetGridCorner().z - position.z) / GetCellSize())); int columnIndex = Mathf.FloorToInt(Mathf.Abs((GetGridCorner().x - position.x) / GetCellSize())); return new Vector2Int(GetGrid()[rowIndex].Row[columnIndex].CellProperties.Row, GetGrid()[rowIndex].Row[columnIndex].CellProperties.Column); } public List GetPedestrianSpawnWaypointsForCell(Vector2Int cellIndex, int agentType) { return GetGrid()[cellIndex.x].Row[cellIndex.y].PedestrianWaypointsData.SpawnWaypoints.Where(cond1 => cond1.AllowedAgents.Contains(agentType)).ToList(); } internal List GetPedestrianWaypointsAroundPosition(Vector3 position) { List possibleWaypoints = GetCell(position.x, position.z).PedestrianWaypointsData.Waypoints; if (possibleWaypoints.Count == 0) { var gridCell = GetCell(position.x, position.z); List cells = GetCellNeighbors(gridCell.CellProperties.Row, gridCell.CellProperties.Column, 1, true); foreach (Vector2Int cell in cells) { possibleWaypoints.AddRange(GetCell(cell).PedestrianWaypointsData.Waypoints); } } return possibleWaypoints; } internal List GetPedestrianSpawnWaypoipointsAroundPosition(Vector3 position, int agentType) { var possibleWaypoints = GetCell(position.x, position.z).PedestrianWaypointsData.SpawnWaypoints.Where(cond1 => cond1.AllowedAgents.Contains(agentType)).ToList(); if(possibleWaypoints.Count==0) { var gridCell = GetCell(position.x, position.z); List cells = GetCellNeighbors(gridCell.CellProperties.Row, gridCell.CellProperties.Column, 1, true); foreach (Vector2Int cell in cells) { possibleWaypoints.AddRange(GetCell(cell).PedestrianWaypointsData.SpawnWaypoints.Where(cond1 => cond1.AllowedAgents.Contains(agentType)).ToList()); } } return possibleWaypoints; } public List GetAllPedestrianSpawnWaypoints() { var result = new List(); for (int i = 0; i < GetGrid().Length; i++) { for (int j = 0; j < GetGrid()[i].Row.Length; j++) { result.AddRange(GetGrid()[i].Row[j].PedestrianWaypointsData.SpawnWaypoints); } } return result; } public List GetAllTrafficSpawnWaypoints() { var result = new List(); for (int i = 0; i < GetGrid().Length; i++) { for (int j = 0; j < GetGrid()[i].Row.Length; j++) { result.AddRange(GetGrid()[i].Row[j].TrafficWaypointsData.SpawnWaypoints); } } return result; } public List GetAllPedestrianPlayModeWaypoints() { var result = new List(); for (int i = 0; i < GetGrid().Length; i++) { for (int j = 0; j < GetGrid()[i].Row.Length; j++) { result.AddRange(GetGrid()[i].Row[j].PedestrianWaypointsData.Waypoints); } } return result; } public List GetAllTrafficPlayModeWaypoints() { var result = new List(); for (int i = 0; i < GetGrid().Length; i++) { for (int j = 0; j < GetGrid()[i].Row.Length; j++) { result.AddRange(GetGrid()[i].Row[j].TrafficWaypointsData.Waypoints); } } return result; } public List GetTrafficSpawnWaypointsForCell(Vector2Int cellIndex, int agentType) { List spawnWaypoints = GetGrid()[cellIndex.x].Row[cellIndex.y].TrafficWaypointsData.SpawnWaypoints; return GetGrid()[cellIndex.x].Row[cellIndex.y].TrafficWaypointsData.SpawnWaypoints.Where(cond1 => cond1.AllowedAgents.Contains(agentType)).ToList(); } internal List GetTrafficSpawnWaypoipointsAroundPosition(Vector3 position, int agentType) { var possibleWaypoints = GetCell(position.x, position.z).TrafficWaypointsData.SpawnWaypoints.Where(cond1 => cond1.AllowedAgents.Contains(agentType)).ToList(); if (possibleWaypoints.Count == 0) { var gridCell = GetCell(position.x, position.z); List cells = GetCellNeighbors(gridCell.CellProperties.Row, gridCell.CellProperties.Column, 1, true); foreach (Vector2Int cell in cells) { possibleWaypoints.AddRange(GetCell(cell).TrafficWaypointsData.SpawnWaypoints.Where(cond1 => cond1.AllowedAgents.Contains(agentType)).ToList()); } } return possibleWaypoints; } public List GetAllWaypoints(Vector2Int cellIndex) { return GetGrid()[cellIndex.x].Row[cellIndex.y].TrafficWaypointsData.Waypoints; } public bool HasPedestrianSpawnWaypoints(Vector2Int cellIndex) { return GetGrid()[cellIndex.x].Row[cellIndex.y].PedestrianWaypointsData.HasSpawnWaypoints; } public bool HasTrafficSpawnWaypoints(Vector2Int cellIndex) { return GetGrid()[cellIndex.x].Row[cellIndex.y].TrafficWaypointsData.HasSpawnWaypoints; } internal CellData[] GetCells(List activeCells) { CellData[] cellDatas = new CellData[activeCells.Count]; for (int i = 0; i < activeCells.Count; i++) { cellDatas[i] = GetCell(activeCells[i]); } return cellDatas; } internal Vector3 GetCellPosition(Vector2Int vector2Int) { return GetCell(vector2Int).CellProperties.Center; } internal List GetPedestrianWaypointsInArea(Area area) { List result = new List(); CellData cell = GetCell(area.Center); List neighbors = GetCellNeighbors(cell.CellProperties.Row, cell.CellProperties.Column, Mathf.CeilToInt(area.Radius * 2 / GetCellSize()), false); for (int i = neighbors.Count - 1; i >= 0; i--) { cell = GetCell(neighbors[i]); result.AddRange(cell.PedestrianWaypointsData.Waypoints); } return result; } internal List GetTrafficWaypointsAroundPosition(Vector3 position) { List possibleWaypoints = GetCell(position.x, position.z).TrafficWaypointsData.Waypoints; if (possibleWaypoints.Count == 0) { var gridCell = GetCell(position.x, position.z); List cells = GetCellNeighbors(gridCell.CellProperties.Row, gridCell.CellProperties.Column, 1, true); foreach (Vector2Int cell in cells) { possibleWaypoints.AddRange(GetCell(cell).TrafficWaypointsData.Waypoints); } } return possibleWaypoints; } public void AddTrafficWaypoint(CellData cellData, int waypointIndex) { cellData.TrafficWaypointsData.Waypoints.Add(waypointIndex); cellData.TrafficWaypointsData.HasWaypoints = true; } public void AddTrafficSpawnWaypoint(CellData cellData, int waypointIndex, int[] allowedVehicles, int priority) { cellData.TrafficWaypointsData.SpawnWaypoints.Add(new SpawnWaypoint(waypointIndex, allowedVehicles, priority)); cellData.TrafficWaypointsData.HasSpawnWaypoints = true; } public void AddPedestrianWaypoint(CellData cellData, int waypointIndex) { cellData.PedestrianWaypointsData.Waypoints.Add(waypointIndex); cellData.PedestrianWaypointsData.HasWaypoints = true; } public void AddPedestrianSpawnWaypoint(CellData cellData, int waypointIndex, int[] allowedPedestrians, int priority) { cellData.PedestrianWaypointsData.SpawnWaypoints.Add(new SpawnWaypoint(waypointIndex, allowedPedestrians, priority)); cellData.PedestrianWaypointsData.HasSpawnWaypoints = true; } public void AddIntersection(CellData cellData, int intersectionIndex) { cellData.IntersectionsInCell.Add(intersectionIndex); } } }