b451f83174
Captures the pre-Godot-port state of the codebase. This is the rollback anchor for the Godot port (M0 of theriapolis-rpg-implementation-plan-godot-port.md). All Phase 0 through Phase 6.5 work is included; Phase 7 is in flight. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
109 lines
4.1 KiB
C#
109 lines
4.1 KiB
C#
using System.Text.Json.Serialization;
|
||
|
||
namespace Theriapolis.Core.Data;
|
||
|
||
/// <summary>
|
||
/// Phase 6 M0 — definition of a single stampable building (inn, shop, house,
|
||
/// magistrate, etc.). Loaded from <c>Content/Data/building_templates/*.json</c>.
|
||
///
|
||
/// 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 <see cref="Tactical.TacticalSpawn"/>
|
||
/// list as <see cref="Tactical.SpawnKind.Resident"/> (Phase 6 M1).
|
||
/// </summary>
|
||
public sealed record BuildingTemplateDef
|
||
{
|
||
[JsonPropertyName("id")]
|
||
public string Id { get; init; } = "";
|
||
|
||
[JsonPropertyName("name")]
|
||
public string Name { get; init; } = "";
|
||
|
||
/// <summary>Footprint width in tactical tiles. Includes perimeter walls.</summary>
|
||
[JsonPropertyName("footprint_w_tiles")]
|
||
public int FootprintWTiles { get; init; } = 1;
|
||
|
||
/// <summary>Footprint height in tactical tiles. Includes perimeter walls.</summary>
|
||
[JsonPropertyName("footprint_h_tiles")]
|
||
public int FootprintHTiles { get; init; } = 1;
|
||
|
||
/// <summary>Lowest settlement tier this template is eligible for (4 = village+).</summary>
|
||
[JsonPropertyName("min_tier_eligible")]
|
||
public int MinTierEligible { get; init; } = 5;
|
||
|
||
/// <summary>Door positions in template-local coords (0..W-1, 0..H-1).</summary>
|
||
[JsonPropertyName("doors")]
|
||
public BuildingDoor[] Doors { get; init; } = Array.Empty<BuildingDoor>();
|
||
|
||
/// <summary>Decorations in template-local coords.</summary>
|
||
[JsonPropertyName("decos")]
|
||
public BuildingDecoPlacement[] Decos { get; init; } = Array.Empty<BuildingDecoPlacement>();
|
||
|
||
/// <summary>Resident roles (innkeeper, shopkeeper, guard, ...).</summary>
|
||
[JsonPropertyName("roles")]
|
||
public BuildingRole[] Roles { get; init; } = Array.Empty<BuildingRole>();
|
||
|
||
/// <summary>
|
||
/// Optional biome filter. Empty = eligible everywhere. Otherwise the
|
||
/// settlement's home tile must be one of these biome ids.
|
||
/// </summary>
|
||
[JsonPropertyName("biome_filter")]
|
||
public string[] BiomeFilter { get; init; } = Array.Empty<string>();
|
||
|
||
/// <summary>Selection weight in procedural Tier 2–5 layout rolls. Default 1.0.</summary>
|
||
[JsonPropertyName("weight")]
|
||
public float Weight { get; init; } = 1f;
|
||
|
||
/// <summary>"civic" / "shop" / "house" / "inn" / "infrastructure" — used by procedural layout role mix.</summary>
|
||
[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; }
|
||
|
||
/// <summary>Compass facing: "N" / "E" / "S" / "W". Door always sits on a perimeter cell.</summary>
|
||
[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; }
|
||
|
||
/// <summary>Deco kind name: "counter" / "bed" / "hearth" / "sign".</summary>
|
||
[JsonPropertyName("deco")]
|
||
public string Deco { get; init; } = "";
|
||
}
|
||
|
||
public sealed record BuildingRole
|
||
{
|
||
/// <summary>Role tag inside the template (e.g. "innkeeper", "shopkeeper", "guard").</summary>
|
||
[JsonPropertyName("tag")]
|
||
public string Tag { get; init; } = "";
|
||
|
||
/// <summary>Spawn point in template-local coords. Must be an interior cell.</summary>
|
||
[JsonPropertyName("spawn_at")]
|
||
public int[] SpawnAt { get; init; } = new[] { 1, 1 };
|
||
|
||
/// <summary>True if this role may be omitted in a procedural layout (slot left empty).</summary>
|
||
[JsonPropertyName("optional")]
|
||
public bool Optional { get; init; } = false;
|
||
}
|