using System.Text.Json.Serialization; namespace Theriapolis.Core.Data; /// /// Phase 6 M0 — definition of a single stampable building (inn, shop, house, /// magistrate, etc.). Loaded from Content/Data/building_templates/*.json. /// /// A template describes: /// - The building's footprint in tactical tiles. /// - Where doors sit on the perimeter. /// - Which interior cells get specific furniture (counter, bed, hearth, sign). /// - Which "roles" the building offers (innkeeper, shopkeeper, guard) and /// where each role's resident NPC stands when the player walks in. /// /// Stamping draws walls along the perimeter, floors inside, doors at the /// declared door cells, and decorations at the declared deco cells. Spawn /// records for roles are emitted into the chunk's /// list as (Phase 6 M1). /// public sealed record BuildingTemplateDef { [JsonPropertyName("id")] public string Id { get; init; } = ""; [JsonPropertyName("name")] public string Name { get; init; } = ""; /// Footprint width in tactical tiles. Includes perimeter walls. [JsonPropertyName("footprint_w_tiles")] public int FootprintWTiles { get; init; } = 1; /// Footprint height in tactical tiles. Includes perimeter walls. [JsonPropertyName("footprint_h_tiles")] public int FootprintHTiles { get; init; } = 1; /// Lowest settlement tier this template is eligible for (4 = village+). [JsonPropertyName("min_tier_eligible")] public int MinTierEligible { get; init; } = 5; /// Door positions in template-local coords (0..W-1, 0..H-1). [JsonPropertyName("doors")] public BuildingDoor[] Doors { get; init; } = Array.Empty(); /// Decorations in template-local coords. [JsonPropertyName("decos")] public BuildingDecoPlacement[] Decos { get; init; } = Array.Empty(); /// Resident roles (innkeeper, shopkeeper, guard, ...). [JsonPropertyName("roles")] public BuildingRole[] Roles { get; init; } = Array.Empty(); /// /// Optional biome filter. Empty = eligible everywhere. Otherwise the /// settlement's home tile must be one of these biome ids. /// [JsonPropertyName("biome_filter")] public string[] BiomeFilter { get; init; } = Array.Empty(); /// Selection weight in procedural Tier 2–5 layout rolls. Default 1.0. [JsonPropertyName("weight")] public float Weight { get; init; } = 1f; /// "civic" / "shop" / "house" / "inn" / "infrastructure" — used by procedural layout role mix. [JsonPropertyName("category")] public string Category { get; init; } = "house"; } public sealed record BuildingDoor { [JsonPropertyName("x")] public int X { get; init; } [JsonPropertyName("y")] public int Y { get; init; } /// Compass facing: "N" / "E" / "S" / "W". Door always sits on a perimeter cell. [JsonPropertyName("facing")] public string Facing { get; init; } = "S"; } public sealed record BuildingDecoPlacement { [JsonPropertyName("x")] public int X { get; init; } [JsonPropertyName("y")] public int Y { get; init; } /// Deco kind name: "counter" / "bed" / "hearth" / "sign". [JsonPropertyName("deco")] public string Deco { get; init; } = ""; } public sealed record BuildingRole { /// Role tag inside the template (e.g. "innkeeper", "shopkeeper", "guard"). [JsonPropertyName("tag")] public string Tag { get; init; } = ""; /// Spawn point in template-local coords. Must be an interior cell. [JsonPropertyName("spawn_at")] public int[] SpawnAt { get; init; } = new[] { 1, 1 }; /// True if this role may be omitted in a procedural layout (slot left empty). [JsonPropertyName("optional")] public bool Optional { get; init; } = false; }