import type { CharacterAppearance, ClassId, GenderId, RaceId, RomClassId } from "./characterCatalog"; import type { ContentCategoryId } from "./contentCategories"; import type { InventoryItem } from "../game/lootTypes"; import type { EquipmentAssignments } from "../game/equipment"; import type { GameplaySettings } from "../game/combatStore"; import type { ManastormProgress } from "../game/manastormProgress"; import type { DungeonRunCheckpoint } from "../game/dungeonRunCheckpoint"; import type { BossCardCollection } from "../game/bossCards"; import type { Wow335HunterPetFamily } from "../game/wow335HunterPetFamilySelection"; import type { CharacterStatRuleset } from "../game/characterStatRuleset"; export type ShellPhase = "login" | "characters" | "create-character" | "main-menu" | "class-hall" | "dungeons" | "manastorms" | "arenas" | "arena-game" | "gm-admin" | "bite-sized-editor" | "game"; export type SessionKind = "account" | "offline"; export type AccountRole = "gm"; export interface PlayerSession { kind: SessionKind; ownerId: string; displayName: string; roles?: readonly AccountRole[]; /** Present for server-backed accounts; kept in session storage only. */ accessToken?: string; } export type GearRecoveryReason = "missing-category" | "foreign-category" | "invalid-native-payload"; /** Original rejected gear data kept with its character so migrations never erase it. */ export interface GearRecoveryItem { readonly item: unknown; readonly reason: GearRecoveryReason; } /** A former loadout reference for an item that is quarantined from active gear. */ export interface GearRecoveryEquipmentReference { readonly ownerId: string; readonly slot: string; readonly instanceId: string; readonly reason: GearRecoveryReason; } /** Character-scoped recovery for legacy or foreign-namespace gear. */ export interface CharacterGearRecovery { readonly items: readonly GearRecoveryItem[]; readonly equipment: readonly GearRecoveryEquipmentReference[]; } export interface CharacterProfile { id: string; ownerId: string; name: string; raceId: RaceId; classId: ClassId; /** Stable specialization registry ID. Normalized profiles always include it; optional for legacy callers. */ specializationId?: string | null; /** Always present after repository normalization; optional for v1 callers. */ categoryId?: ContentCategoryId; /** RoM's inactive class. The active primary remains `classId`. */ secondaryClassId?: RomClassId | null; /** Optional for legacy profile inputs; repository-normalized profiles always include a value. */ statRuleset?: CharacterStatRuleset; /** Persisted choice for a Hunter's current pet family; legacy profiles default to Wolf. */ hunterPetFamily?: Wow335HunterPetFamily; gender: GenderId; appearance: CharacterAppearance; level: number; experience: number; talentRanks: Record; /** Active WoW glyph IDs in the character's saved build; normalized legacy profiles may omit this field. */ glyphIds?: readonly string[]; actionBindings: Record; /** Bindings keyed by ordered `primary:secondary` class pair. */ actionLoadouts?: Record>; inventory: InventoryItem[]; equipment: EquipmentAssignments; /** Rejected gear remains recoverable here and is excluded from active inventory/loadouts. */ gearRecovery?: CharacterGearRecovery; /** Legacy character log, read only during migration to the account collection. */ bossCards?: BossCardCollection; /** Present on normalized and newly created profiles; optional for legacy callers. */ manastormProgress?: ManastormProgress; /** Safe resume point only; active combat, timers, and temporary waves are never persisted. */ dungeonRunCheckpoint?: DungeonRunCheckpoint | null; settings?: Partial; location: string; createdAt: number; lastPlayedAt: number; } export interface CharacterDraft { name: string; categoryId: ContentCategoryId; raceId: RaceId; classId: ClassId; specializationId: string | null; gender: GenderId; appearance: CharacterAppearance; rotation: number; step: "identity" | "appearance"; }