Files
MaidEngine/scripts/battle/map/combat_map.gd
2026-04-09 08:07:25 -04:00

121 lines
3.0 KiB
GDScript

class_name CombatMap
extends Node2D
@export var tile_set: DLTileset
@export var map_layout: MapLayout
@onready var tile_map: TileMapLayer = %TerrainLayer
@onready var highlight_map: GridOverlay = %OverlayLayer
@onready var wall_renderer: WallRenderer = %WallRenderer
@onready var fog_renderer: FogRenderer = %FogRenderer
const DEPLOYED_UNIT_SCENE = preload("res://prefabs/deployed_unit.tscn")
const SOURCE_ID: int = 0
var _pending_layout: String
var _pending_units: Array[Dictionary] = []
func _ready() -> void:
if _pending_layout:
_apply_layout(_pending_layout)
for entry in _pending_units:
_apply_deploy(entry.deployed, entry.coords)
_pending_units.clear()
if map_layout:
apply_layout(map_layout)
func draw_wall(coords: Vector2i) -> void:
draw_custom(coords, tile_set.wall_tile_coords)
func draw_floor(coords: Vector2i) -> void:
draw_custom(coords, tile_set.floor_tile_coords)
func draw_custom(coords: Vector2i, tile_coords: Vector2i) -> void:
tile_map.set_cell(coords, SOURCE_ID, tile_coords)
func load_map(layout: String) -> void:
if is_node_ready():
_apply_layout(layout)
else:
_pending_layout = layout
func deploy_unit(unit: Unit, coords: Vector2i) -> void:
var deployed: DeployedUnit = DEPLOYED_UNIT_SCENE.instantiate()
deployed.unit = unit
if is_node_ready():
_apply_deploy(deployed, coords)
else:
_pending_units.append({deployed = deployed, coords = coords})
func _apply_layout(layout: String) -> void:
var rows := layout.split("\n")
for y in rows.size():
for x in rows[y].length():
var coords := Vector2i(x, y)
match rows[y][x]:
"#":
draw_wall(coords)
".":
draw_floor(coords)
func _apply_deploy(deployed: DeployedUnit, coords: Vector2i) -> void:
deployed.position = BattleMapHelper.coords_to_world(coords)
add_child(deployed)
func remove_unit(deployed: DeployedUnit) -> void:
if deployed.get_parent() == self:
remove_child(deployed)
func target_tile(coords: Vector2i) -> void:
highlight_map.target_tile(coords)
func apply_layout(layout: MapLayout) -> void:
map_layout = layout
map_layout.initialize()
load_from_layout()
draw_room_walls()
draw_fog()
func is_tile_passable(from: Vector2i, to: Vector2i) -> bool:
assert(map_layout != null, "CombatMap.is_tile_passable called before map_layout was set")
return map_layout.is_passable(from, to)
func is_tile_valid(coords: Vector2i) -> bool:
assert(map_layout != null, "CombatMap.is_tile_valid called before map_layout was set")
return map_layout.is_tile_valid(coords)
func draw_room_walls() -> void:
if not map_layout:
return
wall_renderer.draw_walls_for_layout(map_layout)
func draw_fog() -> void:
if not map_layout:
return
fog_renderer.draw_fog_for_layout(map_layout)
func get_map_rect() -> Rect2:
if not map_layout:
return Rect2()
return Rect2(Vector2.ZERO, Vector2(map_layout.size) * BattleMapHelper.TILE_SIZE)
func load_from_layout() -> void:
if not map_layout:
return
for room in map_layout.rooms:
for tile in room.tiles:
draw_floor(tile)