using Godot; using System; using System.Collections.Generic; using System.Linq; public partial class Map : TileMapLayer { public int _minX, _maxX, _minY, _maxY, _mainSource = 0; public string _isSolidString = "is_solid"; public Vector2 _cellSize, _sizeInPixels, _sizeInCells; public Vector2I _pathTakenAtlasCoordinates = new Vector2I(4, 0); public List _cells = new(), _leftmostColumn = new(), _rightmostColumn = new(), _topRow = new(), _bottomRow = new(); public AStarGrid2D _astar = new(); public Dictionary _addressOccupants = new(); public override void _Ready() { base._Ready(); _cellSize = TileSet.TileSize; _cells = [.. GetUsedCells()]; _cells.ForEach(c => _addressOccupants[c] = null); _minX = _cells.Min(c => c.X); _maxX = _cells.Max(c => c.X); _minY = _cells.Min(c => c.Y); _maxY = _cells.Max(c => c.Y); _leftmostColumn = [.. _cells.Where(c => c.X == _minX)]; _rightmostColumn = [.. _cells.Where(c => c.X == _maxX)]; _topRow = [.. _cells.Where(c => c.Y == _minY)]; _bottomRow = [.. _cells.Where(c => c.Y == _maxY)]; _sizeInCells = new Vector2(_topRow.Count, _leftmostColumn.Count); _sizeInPixels = _sizeInCells * _cellSize; SetupAstar(); } public Vector2 GetCellPositionFromAddress(Vector2I CELL_ADDRESS) { return GlobalPosition + CELL_ADDRESS * _cellSize + _cellSize / 2; } public Enemy GetOccupant(Vector2I CELL_TO_CHECK) { return _addressOccupants[CELL_TO_CHECK]; } public bool IsCellSolid(Vector2I CELL_TO_CHECK) { bool hasOccupant = GetOccupant(CELL_TO_CHECK) != null; if (hasOccupant) { // GD.Print(CELL_TO_CHECK, " has occupant"); } bool isSolid = (bool)GetCellTileData(CELL_TO_CHECK).GetCustomData(_isSolidString); if (isSolid) { // GD.Print(CELL_TO_CHECK, " is solid"); } return hasOccupant || isSolid; } public bool IsRowFull(int ROW_TO_CHECK) { List rowCells = [.. _cells.Where(c => c.Y == ROW_TO_CHECK)]; return rowCells.All(c => GetOccupant(c) != null); } public void SetCellEnemy(Vector2I ADDRESS, Enemy ENEMY) { if (ENEMY != null) { if (ENEMY._address != -(Vector2I)Vector2.Inf) { _addressOccupants[ENEMY._address] = null; } ENEMY._address = ADDRESS; } _addressOccupants[ADDRESS] = ENEMY; SetCellSolid(ADDRESS); } public void SetCellSolid(Vector2I ADDRESS) { _astar.SetPointSolid(ADDRESS, IsCellSolid(ADDRESS)); } public void SetupAstar() { _astar.Region = new Rect2I(_minX, _minY, _topRow.Count, _leftmostColumn.Count); _astar.CellSize = _cellSize; _astar.DefaultComputeHeuristic = AStarGrid2D.Heuristic.Euclidean; _astar.DiagonalMode = AStarGrid2D.DiagonalModeEnum.Never; _astar.Update(); EvaluateSolidCells(); } public List GetPath(Vector2I FROM, Vector2I TO, bool INCLUDE_FROM = false, bool SHOW_PATH = false) { _astar.SetPointSolid(FROM, false); List pathTaken = [.. _astar.GetIdPath(FROM, TO, true)]; // if (SHOW_PATH) // { // for (int i = 0; i < pathTaken.Count; i++) // { // Vector2I cell = pathTaken[i]; // SetCell(cell, _mainSource, _pathTakenAtlasCoordinates); // } // } if (!INCLUDE_FROM) { pathTaken.Remove(FROM); } return pathTaken; } public void EvaluateSolidCells() { for (int i = 0; i < _cells.Count; i++) { SetCellSolid(_cells[i]); } } }