## PathfindingHandler.gd # Handles A* pathfinding for the map using Godot's AStar2D. # Builds a navigation graph from walkable tiles and provides path queries. class_name PathfindingHandler extends RefCounted # All 8 possible neighbor offsets (cardinal and diagonal directions). const NEIGHBORS: Array[Vector2i] = [ Vector2i.RIGHT, Vector2i.LEFT, Vector2i.DOWN, Vector2i.UP, Vector2i(1, 1), Vector2i(1, -1), Vector2i(-1, 1), Vector2i(-1, -1), ] # The underlying AStar2D instance for pathfinding. var _astar: AStar2D = AStar2D.new() # Maps grid coordinates (Vector2i) to AStar2D point IDs. var _coord_to_id: Dictionary = {} # Builds the AStar2D graph from all walkable tiles in MapData. # Safe to call again for a new level — clears all previous state first. func build(data: MapData) -> void: _astar.clear() _coord_to_id.clear() # Register a point for every walkable tile (FLOOR). for coords: Vector2i in data.grid.keys(): if data.grid[coords] == MapData.TileType.FLOOR: var id: int = _astar.get_available_point_id() _astar.add_point(id, Vector2(coords.x, coords.y)) _coord_to_id[coords] = id # Connect each point to its walkable neighbors (cardinal and diagonal). for coords: Vector2i in _coord_to_id.keys(): for offset: Vector2i in NEIGHBORS: var neighbor: Vector2i = coords + offset if _coord_to_id.has(neighbor): _astar.connect_points(_coord_to_id[coords], _coord_to_id[neighbor], false) # Returns the path as grid coordinates, or an empty array if no path exists. # Used by LevelManager and Player for navigation. func find_path(from: Vector2i, to: Vector2i) -> Array[Vector2i]: if not _coord_to_id.has(from) or not _coord_to_id.has(to): return [] var raw: PackedVector2Array = _astar.get_point_path(_coord_to_id[from], _coord_to_id[to]) var result: Array[Vector2i] = [] for point in raw: result.append(Vector2i(point)) return result