class_name StandardRoom extends TileMap const TILEMAP_LAYER = 0 @export_category("Room Openings") @export var left: bool = false @export var right: bool = false @export var top: bool = false @export var bottom: bool = false var room_size: Vector2i var cell_size: Vector2i func _init() -> void: self.room_size = self.get_used_rect().size self.cell_size = self.tile_set.tile_size func is_block() -> bool: if self.left or self.right or self.top or self.bottom: return false return true func get_exits() -> Array[Vector2i]: var exits: Array[Vector2i] = [] if self.left: exits.append(Vector2i.LEFT) if self.right: exits.append(Vector2i.RIGHT) if self.top: exits.append(Vector2i.UP) if self.bottom: exits.append(Vector2i.DOWN) return exits func get_exit_pos(exit: Vector2i) -> Vector2i: var pos: Vector2i = Vector2i.ZERO if exit == Vector2i.LEFT: pos = Vector2i(0, self.room_size.y / 2) elif exit == Vector2i.RIGHT: pos = Vector2i(self.room_size.x - 1, self.room_size.y / 2) elif exit == Vector2i.UP: pos = Vector2i(self.room_size.x / 2, 0) elif exit == Vector2i.DOWN: pos = Vector2i(self.room_size.x / 2, self.room_size.y - 1) return pos func get_exit_pos_offset(edge_pos: Vector2i, exit: Vector2i) -> Vector2i: match exit: Vector2i.UP: return edge_pos + Vector2i(self.room_size.x/-2, self.room_size.y * -1) Vector2i.DOWN: return edge_pos + Vector2i(self.room_size.x/-2, 1) Vector2i.LEFT: return edge_pos + Vector2i(-self.room_size.x, -self.room_size.y/2) Vector2i.RIGHT: return edge_pos + Vector2i(1, -self.room_size.y/2) _: return Vector2i.ZERO func copy_to_map(map: TileMap) -> void: for x in range(0, self.room_size.x): for y in range(0, self.room_size.y): var tile = self.get_cell_source_id(TILEMAP_LAYER, Vector2i(x, y)) var alt = self.get_cell_alternative_tile(TILEMAP_LAYER, Vector2i(x, y)) if tile != -1: map.set_cell(TILEMAP_LAYER, Vector2i(position.x + x, position.y + y), tile, Vector2i(0, 0), alt) else: map.set_cell(TILEMAP_LAYER, Vector2i(position.x + x, position.y + y), -1, Vector2i(0, 0)) func seal_exit(map: TileMap, pos: Vector2i, exit: Vector2i) -> void: var exit_pos = get_exit_pos(exit) var seal_tile_id = 0 match exit: Vector2i.UP: map.set_cell(TILEMAP_LAYER, exit_pos + Vector2i(pos.x - 1, pos.y), seal_tile_id, Vector2i(0, 0)) map.set_cell(TILEMAP_LAYER, exit_pos + Vector2i(pos.x, pos.y), seal_tile_id, Vector2i(0, 0)) map.set_cell(TILEMAP_LAYER, exit_pos + Vector2i(pos.x + 1, pos.y), seal_tile_id, Vector2i(0, 0)) Vector2i.DOWN: map.set_cell(TILEMAP_LAYER, exit_pos + Vector2i(pos.x - 1, pos.y), seal_tile_id, Vector2i(0, 0)) map.set_cell(TILEMAP_LAYER, exit_pos + Vector2i(pos.x, pos.y), seal_tile_id, Vector2i(0, 0)) map.set_cell(TILEMAP_LAYER, exit_pos + Vector2i(pos.x + 1, pos.y), seal_tile_id, Vector2i(0, 0)) Vector2i.RIGHT: map.set_cell(TILEMAP_LAYER, exit_pos + Vector2i(pos.x, pos.y - 1), seal_tile_id, Vector2i(0, 0)) map.set_cell(TILEMAP_LAYER, exit_pos + Vector2i(pos.x, pos.y), seal_tile_id, Vector2i(0, 0)) map.set_cell(TILEMAP_LAYER, exit_pos + Vector2i(pos.x, pos.y + 1), seal_tile_id, Vector2i(0, 0)) Vector2i.LEFT: map.set_cell(TILEMAP_LAYER, exit_pos + Vector2i(pos.x, pos.y - 1), seal_tile_id, Vector2i(0, 0)) map.set_cell(TILEMAP_LAYER, exit_pos + Vector2i(pos.x, pos.y), seal_tile_id, Vector2i(0, 0)) map.set_cell(TILEMAP_LAYER, exit_pos + Vector2i(pos.x, pos.y + 1), seal_tile_id, Vector2i(0, 0)) func is_overlapping(map: TileMap) -> bool: for x in range(0, self.room_size.x): for y in range(0, self.room_size.y): var tile = map.get_cell_source_id(TILEMAP_LAYER, Vector2i(self.position.x + x, self.position.y + y)) if tile != -1: return true return false # Validate room by checking that the top left tile is at 0, 0 and all exits are valid func _validate() -> bool: # Check for tiles where x is negative pass # Check for tiles where y is negative pass # If exit on left, check that the middle tile on the left is empty if self.left and self.get_cell_source_id(TILEMAP_LAYER, Vector2i(0, self.room_size.y / 2)) != -1: push_error("Room with exit on left must have empty middle tile on left") return false # If exit on right, check that the middle tile on the right is empty if self.right and self.get_cell_source_id(TILEMAP_LAYER, Vector2i(self.room_size.x - 1, self.room_size.y / 2)) != -1: push_error("Room with exit on right must have empty middle tile on right") return false # If exit on top, check that the middle tile on the top is empty if self.top and self.get_cell_source_id(TILEMAP_LAYER, Vector2i(self.room_size.x / 2, 0)) != -1: push_error("Room with exit on top must have empty middle tile on top") return false # If exit on bottom, check that the middle tile on the bottom is empty if self.bottom and self.get_cell_source_id(TILEMAP_LAYER, Vector2i(self.room_size.x / 2, self.room_size.y - 1)) != -1: push_error("Room with exit on bottom must have empty middle tile on bottom") return false return true func flip_vector(vector: Vector2i) -> Vector2i: return Vector2i(vector.x * -1, vector.y * -1) func disable_room_exit_opposite(exit: Vector2i) -> void: self.disable_room_exit(self.flip_vector(exit)) func disable_room_exit(exit: Vector2i) -> void: if exit == Vector2i.LEFT: self.left = false elif exit == Vector2i.RIGHT: self.right = false elif exit == Vector2i.UP: self.top = false elif exit == Vector2i.DOWN: self.bottom = false