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);
}
}
}