using Theriapolis.Core.Tactical;
using Theriapolis.Core.World;
namespace Theriapolis.Core.Dungeons;
///
/// Phase 7 M1 — runtime view of an interior dungeon. Generated lazily on
/// the player's first entry to a PoI; persisted modifications live on
/// and
/// re-apply on reload.
///
/// The dungeon owns its own bounded tactical-tile array (the scene-swap
/// model from Phase 7 plan §4.2): movement, combat, dialogue, and save/load
/// all work the same as the surface, but the renderer reads tiles from
/// instead of the chunk streamer.
///
/// Coordinate space: Tiles[x, y] where x ∈ [0, W) and
/// y ∈ [0, H). Every 's AABB falls within these
/// bounds; corridor tiles between rooms are also in this array.
///
public sealed class Dungeon
{
/// Source PoI id. Identity for save lookups.
public int PoiId { get; }
/// Dungeon type — drives art family, default loot tier, etc.
public PoiType Type { get; }
/// The tactical-tile grid in dungeon-local coordinates.
public TacticalTile[,] Tiles { get; }
/// Every room in layout order. Rooms[i].Id == i.
public Room[] Rooms { get; }
///
/// Door-anchored connections between rooms. Authoritative for
/// reachability — the graph is undirected (a connection from A→B is
/// implicit B→A; do not double-store).
///
public RoomConnection[] Connections { get; }
///
/// Dungeon-local tile coords of the entrance. The player spawns here
/// on enter and exits when they cross this tile inbound from inside.
///
public (int X, int Y) EntranceTile { get; }
/// Width of the tile array (dungeon-local tiles).
public int W => Tiles.GetLength(0);
/// Height of the tile array (dungeon-local tiles).
public int H => Tiles.GetLength(1);
public Dungeon(
int poiId,
PoiType type,
TacticalTile[,] tiles,
Room[] rooms,
RoomConnection[] connections,
(int X, int Y) entranceTile)
{
PoiId = poiId;
Type = type;
Tiles = tiles;
Rooms = rooms;
Connections = connections;
EntranceTile = entranceTile;
}
}