class_name Room
## Phase 13 — enclosed-space data class.
##
## A Room is a set of contiguous tiles enclosed by walls (and/or doors), discovered
## by RoomDetector's BFS. Once discovered, the room may be auto-roofed (if
## `tile_count() <= ROOM_AUTOROOF_CAP`) and its tiles count as "indoor" for
## purposes of weather shelter, beauty aggregation, dirtiness, and room thoughts.
##
## A room with tile_count() > ROOM_AUTOROOF_CAP is detected but NOT roofed; it
## triggers EventBus.room_too_large so UI can surface the "split with an interior
## wall" banner.  The cap is 16 per the 2026-05-11 decision (memory.md).
##
## Construction is owned by RoomDetector; entities should NEVER instantiate
## Rooms directly — query World.room_at_tile() instead.

const ROOM_AUTOROOF_CAP: int = 16

## Stable identity, assigned by RoomDetector on creation.  Used as the value
## carried by EventBus.room_changed(room_id).  Invalidated on destroy.
var id: int = -1

## Every floor/door tile inside this room.  Walls themselves are NOT included —
## walls are the boundary, not the interior.
var tiles: Array[Vector2i] = []

## Cached AABB of `tiles`.  Useful for cheap point-in-room rejection before the
## full tiles-array sweep.
var bounds: Rect2i = Rect2i()

## True when RoomDetector applied auto-roof — i.e. tile_count() <= ROOM_AUTOROOF_CAP
## AND the room is fully enclosed.  Drives shelter / indoor-tint checks.
var is_under_roof: bool = false


## Returns the number of interior tiles (NOT including bounding walls).
func tile_count() -> int:
	return tiles.size()


## True if `tile` is one of this room's interior tiles.  Uses bounds first
## as a cheap reject before falling back to a linear search.
func contains_tile(tile: Vector2i) -> bool:
	if not bounds.has_point(tile):
		return false
	return tile in tiles


## Recompute the bounds Rect2i from the current tiles array.  Called by
## RoomDetector after populating tiles.
func recompute_bounds() -> void:
	if tiles.is_empty():
		bounds = Rect2i()
		return
	var min_x: int = tiles[0].x
	var min_y: int = tiles[0].y
	var max_x: int = tiles[0].x
	var max_y: int = tiles[0].y
	for t in tiles:
		if t.x < min_x: min_x = t.x
		if t.y < min_y: min_y = t.y
		if t.x > max_x: max_x = t.x
		if t.y > max_y: max_y = t.y
	bounds = Rect2i(min_x, min_y, max_x - min_x + 1, max_y - min_y + 1)
