2026-03-16 16:24:32 +11:00
## LevelManager.gd
# Manages the current level's data, visual representation, and navigation graph.
# Responsible for generating, painting, and initializing the level, as well as providing pathfinding and coordinate helpers.
extends Node
2026-03-20 20:40:12 +11:00
const ENEMY_SCENE_PATH : String = "res://scenes/actors/enemy.tscn"
2026-03-16 16:24:32 +11:00
# The source of truth for the current level's layout (MapData resource).
var _data : MapData
# The TileMapLayer node where the map is visually rendered.
var _layer : TileMapLayer
# Service objects for map generation, painting, and pathfinding.
# MapGenerator and MapPainter are stateless; PathfindingHandler manages the navigation graph.
var _generator : MapGenerator = MapGenerator . new ()
var _painter : MapPainter = MapPainter . new ()
var _pathfinding : PathfindingHandler = PathfindingHandler . new ()
# Orchestrates the creation of a new level.
# 1. Generates the map data.
# 2. Paints the map visually.
# 3. Builds the navigation graph for AI/pathfinding.
2026-03-20 20:40:12 +11:00
# 4. Spawns the player at the correct location.
func initialize ( settings : MapSettings , layer : TileMapLayer , player : Player ) -> void :
2026-03-16 16:24:32 +11:00
_layer = layer
# 1. Generate the abstract map data (rooms, corridors, etc.).
# This avoids side effects on the settings resource.
_data = _generator . generate ( settings )
# 2. Paint the visual layer for the player to see.
# This does not modify the underlying map data.
_painter . paint ( _data , _layer )
# 3. Build the AStar graph for AI and navigation.
# Reads directly from the grid stored in _data.
_pathfinding . build ( _data )
# 4. Finalize world state by spawning the player at the spawn point.
# Uses the TileMapLayer to convert grid coordinates to world pixel positions.
player . position = _layer . map_to_local ( _data . spawn_point )
2026-03-20 20:40:12 +11:00
# 5. Spawn one enemy per room, skipping the player's spawn room (index 0).
var enemy_scene := load ( ENEMY_SCENE_PATH ) as PackedScene
var world_node := player . get_parent ()
for i in range ( 1 , _data . rooms . size ()):
var enemy_instance = enemy_scene . instantiate ()
var enemy = enemy_instance as Enemy
if enemy == null :
push_error ( "Failed to cast enemy instance to Enemy at room index %d " % i )
continue
enemy . _player = player
world_node . add_child ( enemy )
enemy . position = _layer . map_to_local ( _data . rooms [ i ] . get_center ())
2026-03-16 16:24:32 +11:00
# Public API for other systems (like AI) to query the navigation grid.
# Encapsulates the PathfindingHandler so callers don't need to know about it directly.
func find_path ( from : Vector2i , to : Vector2i ) -> Array [ Vector2i ]:
return _pathfinding . find_path ( from , to )
# Coordinate conversion helpers — lets the player and other systems convert between world and tile coordinates without touching the TileMapLayer directly.
func world_to_tile ( world_pos : Vector2 ) -> Vector2i :
return _layer . local_to_map ( world_pos )
func tile_to_world ( tile : Vector2i ) -> Vector2 :
return _layer . map_to_local ( tile )