class_name MapLayout extends Resource @export var rooms: Array[Room] ## Openings are stored as a flat array of pairs: [from1, to1, from2, to2, ...]. ## Each consecutive pair of Vector2i values represents a bidirectional doorway ## between two adjacent tiles in different rooms. @export var openings: Array[Vector2i] var _tile_room_map: Dictionary = {} var _opening_set: Dictionary = {} func initialize() -> void: assert(openings.size() % 2 == 0, "Openings must be provided as pairs of Vector2i") _tile_room_map.clear() _opening_set.clear() for room in rooms: for tile in room.tiles: _tile_room_map[tile] = room for i in range(0, openings.size(), 2): var a := openings[i] var b := openings[i + 1] _opening_set[_edge_key(a, b)] = true static func _edge_key(a: Vector2i, b: Vector2i) -> String: if a < b: return "%d,%d-%d,%d" % [a.x, a.y, b.x, b.y] return "%d,%d-%d,%d" % [b.x, b.y, a.x, a.y] func is_tile_valid(tile: Vector2i) -> bool: return _tile_room_map.has(tile) func get_room_at(tile: Vector2i) -> Room: return _tile_room_map.get(tile, null) func is_passable(from: Vector2i, to: Vector2i) -> bool: if not is_tile_valid(from) or not is_tile_valid(to): return false var room_from: Room = _tile_room_map[from] var room_to: Room = _tile_room_map[to] if room_from == room_to: return true return _opening_set.has(_edge_key(from, to)) func get_walls() -> Array: ## Returns an array of [Vector2i, Vector2i] pairs representing wall edges. ## A wall exists where a room tile borders void or a different room (without an opening). var walls: Array = [] var directions := [Vector2i.RIGHT, Vector2i.DOWN, Vector2i.LEFT, Vector2i.UP] var visited_edges: Dictionary = {} for room in rooms: for tile in room.tiles: for dir in directions: var neighbor: Vector2i = tile + dir var key := _edge_key(tile, neighbor) if visited_edges.has(key): continue visited_edges[key] = true var neighbor_room: Room = _tile_room_map.get(neighbor, null) if neighbor_room == room: continue # Neighbor is void or different room — wall unless opening if not _opening_set.has(key): walls.append([tile, neighbor]) return walls