using System.Text.Json.Serialization; namespace NeonSprawl.Server.Game.AbilityInput; /// Canonical hotbar loadout payload returned by loadout APIs (NEO-29). public sealed class HotbarLoadoutResponse { public const int CurrentSchemaVersion = 1; public const int SlotCountV1 = 8; [JsonPropertyName("schemaVersion")] public int SchemaVersion { get; init; } = CurrentSchemaVersion; [JsonPropertyName("playerId")] public required string PlayerId { get; init; } [JsonPropertyName("slotCount")] public int SlotCount { get; init; } = SlotCountV1; /// Always includes v1 slots 0..7 in ascending order. [JsonPropertyName("slots")] public required IReadOnlyList Slots { get; init; } } /// POST body for hotbar loadout updates. public sealed class HotbarLoadoutUpdateRequest { public const int CurrentSchemaVersion = 1; [JsonPropertyName("schemaVersion")] public int SchemaVersion { get; init; } /// /// Requested slot bindings to apply. Slot entries are upserts; unspecified slots keep previous values. /// [JsonPropertyName("slots")] public IReadOnlyList? Slots { get; init; } } /// POST response for hotbar updates (applied or denied). public sealed class HotbarLoadoutUpdateResponse { public const int CurrentSchemaVersion = 1; [JsonPropertyName("schemaVersion")] public int SchemaVersion { get; init; } = CurrentSchemaVersion; [JsonPropertyName("updated")] public bool Updated { get; init; } [JsonPropertyName("loadout")] public required HotbarLoadoutResponse Loadout { get; init; } /// Required on deny responses; omitted when is true. [JsonPropertyName("reasonCode")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? ReasonCode { get; init; } } /// Wire shape for an individual slot state in GET/POST responses. public sealed class HotbarSlotStateJson { [JsonPropertyName("slotIndex")] public required int SlotIndex { get; init; } /// Canonical lowercase ability id or null when the slot is unbound. [JsonPropertyName("abilityId")] [JsonIgnore(Condition = JsonIgnoreCondition.Never)] public string? AbilityId { get; init; } } /// Wire shape for an individual slot update in POST requests. public sealed class HotbarSlotBindingJson { [JsonPropertyName("slotIndex")] public int SlotIndex { get; init; } [JsonPropertyName("abilityId")] public string? AbilityId { get; init; } }