Files
Genarrative/src/types/scene.ts
kdletters cbc27bad4a
Some checks failed
CI / verify (push) Has been cancelled
init with react+axum+spacetimedb
2026-04-26 18:06:23 +08:00

260 lines
6.2 KiB
TypeScript

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<string, number>;
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<string, number>;
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;
}