namespace HSchool.Content; public enum DefKind { Action, Thing, Position, Work, Room, Building, Floor, Territory, Skill, Trait, BodyAttribute, Need, Country, ClimatePreset, Subject, Staffing, DayFrame, Holiday, Behavior, Color, Topic, Orientation, AffinityRules, Event, Disease, } /// Shared JSONC fields. Kind comes from the folder under defs/, not from the file. public abstract class Def { public required string DefName { get; init; } public string? Parent { get; init; } public bool Abstract { get; init; } } public sealed class ActionDef : Def { /// RoomDef or TerritoryDef where this is done. Required on concrete actions. public string? Room { get; init; } /// Thing occupied for the duration. Null means the room itself is enough. public string? Thing { get; init; } /// Game minutes the action takes. Applied in full when it completes. public float Minutes { get; init; } /// NeedDef refilled on completion. Null for walks and other leisure with no refill. public string? Need { get; init; } /// Added to the need in one shot when the action finishes, then clamped to min–max. public float NeedGain { get; init; } /// Empty means every role. Values are ids. public IReadOnlyList Roles { get; init; } = []; /// Leisure weight. Zero means phase 21 will not pick this for fun — only for a need. public float Weight { get; init; } /// /// A sitting rather than something done whenever the need bites: only offered during the /// eater's own lunch break (). Without it a hungry class /// would walk out of a lesson to the canteen, and the whole school would arrive at once. /// public bool Lunch { get; init; } } public sealed class ThingDef : Def { public IReadOnlyList Actions { get; init; } = []; /// /// How many pupils this thing hosts for lessons. Zero for teacher's furniture — a chair /// must not inflate class size just because someone sits in it. /// public int PupilSlots { get; init; } /// Layers this occupies when worn. Empty — not apparel, so it can sit on the map. public IReadOnlyList Layers { get; init; } = []; /// /// Worn layers fully hidden beneath this piece while condition stays above torn. /// Example: pants list . /// public IReadOnlyList FullyCoversLayers { get; init; } = []; /// Can live in a bag, locker or at home. Furniture stays false. public bool Portable { get; init; } /// Kilograms. Carried mass sums; worn mass does not in this slice. public float Mass { get; init; } /// How much it warms — and how much it steams in heat. public float Insulation { get; init; } /// 0–100. Dress-code formality, not a fashion score. public int Formality { get; init; } /// Allowed age window. Omit for any age. public IntRange? Age { get; init; } /// male, female, or omit for any. public string? Sex { get; init; } /// ColorDef ids this thing may be. Empty — the instance has no colour. public IReadOnlyList Colors { get; init; } = []; /// id, or omit when there is no hem to measure. public string? SkirtLength { get; init; } /// PE kit. Worn for that lesson; not a second wardrobe of everyday clothes. public bool Pe { get; init; } /// /// Chance the dress generator issues this portable non-apparel item. 0 — not rolled (textbooks /// are granted per subject instead). Apparel ignores this and fills layers. /// public float CarryChance { get; init; } /// Portrait fragment when this thing is in the person's frame. Null or empty — silent. public PromptContribution? Prompt { get; init; } } public sealed class PositionDef : Def; public sealed class WorkDef : Def; public sealed class RoomSlot { public required string Key { get; init; } public required string Thing { get; init; } public int Count { get; init; } = 1; } public sealed class RoomDef : Def { public IReadOnlyList Slots { get; init; } = []; public IReadOnlyList Positions { get; init; } = []; public IReadOnlyList Works { get; init; } = []; /// /// When true, a map room of this def with pupil slots becomes a roster class. /// Labs keep for lessons without forming a homeroom. /// Homerooms are a seat count of , not a table of named slots. /// public bool Homeroom { get; init; } /// Thing whose × map seats is class capacity. public string? SeatThing { get; init; } /// Editor default when placing a new homeroom. Vanilla classrooms are 16. public int DefaultSeats { get; init; } /// Game minutes spent occupying this room when walking through it. public float TravelMinutes { get; init; } /// /// Outdoor like the yard: porch, crossing between buildings. Indoor rooms stay warmer than /// the street by the climate preset's wall offset. /// public bool Outdoor { get; init; } /// /// When set, pupil lockers in this room go to students of that sex (male / female). /// public string? LockerSex { get; init; } /// Portrait fragment when the person is in a room of this def. Null or empty — silent. public PromptContribution? Prompt { get; init; } } public sealed class BuildingDef : Def; public sealed class FloorDef : Def; public sealed class TerritoryDef : Def { /// Game minutes spent occupying the yard when walking through it. public float TravelMinutes { get; init; } /// Portrait fragment when the person is in this yard. Null or empty — silent. public PromptContribution? Prompt { get; init; } }