namespace Theriapolis.Core.World.Settlements; /// /// Phase 6 M0 — runtime record of a single stamped building inside a /// settlement. Created by at chunk-gen time /// and attached to the parent . /// /// Buildings can straddle chunk boundaries; the footprint is in /// world-pixel (= tactical-tile) coordinates so cross-chunk lookups /// (e.g. "is the player inside the Millhaven inn?") work without per-chunk /// reconstruction. /// public sealed class BuildingFootprint { /// Unique id within the parent settlement (sequential, 0-based). public int Id { get; init; } /// Building template id (e.g. "inn_small"). public string TemplateId { get; init; } = ""; /// Inclusive minimum X in world-pixel space. public int MinX { get; init; } /// Inclusive minimum Y in world-pixel space. public int MinY { get; init; } /// Inclusive maximum X in world-pixel space. public int MaxX { get; init; } /// Inclusive maximum Y in world-pixel space. public int MaxY { get; init; } /// Door positions in world-pixel space (one entry per door). public (int X, int Y)[] Doors { get; init; } = Array.Empty<(int, int)>(); /// Resident slots: role tag (possibly anchor-prefixed) → spawn position in world-pixel space. public BuildingResidentSlot[] Residents { get; init; } = Array.Empty(); public bool ContainsTile(int worldPxX, int worldPxY) => worldPxX >= MinX && worldPxX <= MaxX && worldPxY >= MinY && worldPxY <= MaxY; } /// One resident slot inside a building. public readonly struct BuildingResidentSlot { /// Role tag — either generic ("innkeeper") or anchor-qualified ("millhaven.innkeeper"). public readonly string RoleTag; /// Spawn point in world-pixel (tactical-tile) coordinates. public readonly int SpawnX; public readonly int SpawnY; /// Optional category match for procedural residents — passed through from BuildingTemplateDef.Category. public readonly string Category; public BuildingResidentSlot(string roleTag, int spawnX, int spawnY, string category) { RoleTag = roleTag; SpawnX = spawnX; SpawnY = spawnY; Category = category; } }