import type { RoleActionDefinition, RoleAttributeProfile, RoleRelationState, } from './attributes'; import type { Character, CharacterBackstoryRevealConfig, } from './characters'; import { AnimationState, type CharacterGender, type CombatActionMode, type CombatDelivery, type FacingDirection, type HostileNpcRenderAnimation, type NpcFunctionType, } from './core'; import type { CustomWorldNpcVisual, CustomWorldRoleInitialItem, CustomWorldRoleSkill, CustomWorldSceneRelativePosition, } from './customWorld'; import type {InventoryItem} from './items'; import type { ActorNarrativeProfile, CompanionStanceProfile, SceneNarrativeResidue, } from './storyEngine'; export interface NpcPersistentState { affinity: number; relationState?: RoleRelationState; helpUsed: boolean; chattedCount: number; giftsGiven: number; inventory: InventoryItem[]; tradeStockSignature?: string | null; recruited: boolean; revealedFacts?: string[]; knownAttributeRumors?: string[]; firstMeaningfulContactResolved?: boolean; seenBackstoryChapterIds?: string[]; stanceProfile?: CompanionStanceProfile; } export interface CompanionState { npcId: string; characterId: string; joinedAtAffinity: number; hp: number; maxHp: number; mana: number; maxMana: number; skillCooldowns: Record; animationState?: AnimationState; actionMode?: CombatActionMode; offsetX?: number; offsetY?: number; transitionMs?: number; } export interface CompanionRenderState { npcId: string; character: Character; hp: number; maxHp: number; mana: number; maxMana: number; skillCooldowns: Record; animationState: AnimationState; actionMode?: CombatActionMode; slot: 'upper' | 'lower'; facing?: FacingDirection; entryOffsetX?: number; entryOffsetY?: number; transitionMs?: number; recruitToken?: number; } export interface Encounter { id?: string; kind?: 'npc' | 'treasure'; npcName: string; npcDescription: string; npcAvatar: string; context: string; gender?: CharacterGender; specialBehavior?: 'initial_companion' | 'camp_companion'; xMeters?: number; characterId?: string; monsterPresetId?: string; initialAffinity?: number; hostile?: boolean; attributeProfile?: RoleAttributeProfile; title?: string; backstory?: string; personality?: string; motivation?: string; combatStyle?: string; relationshipHooks?: string[]; tags?: string[]; backstoryReveal?: CharacterBackstoryRevealConfig; skills?: CustomWorldRoleSkill[]; initialItems?: CustomWorldRoleInitialItem[]; imageSrc?: string; visual?: CustomWorldNpcVisual; narrativeProfile?: ActorNarrativeProfile | null; levelProfile?: EntityLevelProfile; experienceReward?: number; } export type ProgressionRole = | 'guide' | 'ambient' | 'support' | 'hostile_standard' | 'hostile_elite' | 'hostile_boss' | 'rival'; export interface EntityLevelProfile { level: number; referenceStrength: number; chapterId?: string | null; chapterIndex?: number | null; progressionRole: ProgressionRole; source: 'chapter_auto' | 'preset_override' | 'manual'; } export interface SceneHostileNpc { id: string; name: string; action: string; description: string; animation: HostileNpcRenderAnimation; xMeters: number; yOffset: number; facing: FacingDirection; attackRange: number; speed: number; hp: number; maxHp: number; renderKind?: 'npc'; encounter?: Encounter; characterAnimation?: AnimationState; combatMode?: CombatDelivery; combatTags?: string[]; attributeProfile?: RoleAttributeProfile; behaviorVectors?: RoleActionDefinition[]; levelProfile?: EntityLevelProfile; experienceReward?: number; } export interface SceneNpc { id: string; name: string; description: string; avatar: string; role: string; title?: string; gender?: CharacterGender; characterId?: string; monsterPresetId?: string; initialAffinity?: number; hostile?: boolean; functions?: NpcFunctionType[]; recruitable?: boolean; attributeProfile?: RoleAttributeProfile; backstory?: string; personality?: string; motivation?: string; combatStyle?: string; relationshipHooks?: string[]; tags?: string[]; backstoryReveal?: CharacterBackstoryRevealConfig; skills?: CustomWorldRoleSkill[]; initialItems?: CustomWorldRoleInitialItem[]; imageSrc?: string; visual?: CustomWorldNpcVisual; narrativeProfile?: ActorNarrativeProfile | null; levelProfile?: EntityLevelProfile; } export type SceneEncounterKind = 'npc' | 'treasure' | 'none'; export interface SceneEncounterResult { kind: SceneEncounterKind; npcId?: string; treasureText?: string; } export interface CombatVisualEffect { id: string; frames: string[]; fps: number; startX: number; endX?: number; startOrigin: 'player' | 'hostile_npc' | 'monster'; endOrigin?: 'player' | 'hostile_npc' | 'monster'; startMonsterId?: string; endMonsterId?: string; startHostileNpcId?: string; endHostileNpcId?: string; startAnchorOffsetY?: number; endAnchorOffsetY?: number; startOffsetX?: number; endOffsetX?: number; startYOffset: number; endYOffset?: number; durationMs: number; sizePx: number; scale?: number; facing: FacingDirection; zIndex?: number; traveling?: boolean; } export interface SceneHostileNpcChange { id: string; action: string; animation: HostileNpcRenderAnimation; moveMeters?: number; yOffset?: number; } export type SceneMonsterChange = SceneHostileNpcChange; export interface SceneDirective { playerAnimation: AnimationState; playerMoveMeters: number; playerOffsetY: number; playerFacing: FacingDirection; scrollWorld: boolean; monsterChanges: SceneMonsterChange[]; hostileNpcChanges?: SceneHostileNpcChange[]; } export interface ScenePresetInfo { id: string; name: string; description: string; imageSrc: string; forwardSceneId?: string; connectedSceneIds?: string[]; npcs?: SceneNpc[]; treasureHints?: string[]; connections?: SceneConnectionInfo[]; narrativeResidues?: SceneNarrativeResidue[]; mutationStateText?: string | null; currentPressureLevel?: 'low' | 'medium' | 'high' | 'extreme'; } export interface SceneConnectionInfo { sceneId: string; relativePosition: CustomWorldSceneRelativePosition; summary: string; }