Files
Genarrative/src/services/storyEngine/companionReactionDirector.test.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

132 lines
3.2 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { AnimationState, type GameState } from '../../types';
import {
applyCompanionReactionToStance,
buildCompanionReactionBatch,
} from './companionReactionDirector';
function createState(): GameState {
return {
worldType: null,
customWorldProfile: null,
playerCharacter: null,
runtimeStats: {
playTimeMs: 0,
lastPlayTickAt: null,
hostileNpcsDefeated: 0,
questsAccepted: 0,
itemsUsed: 0,
scenesTraveled: 0,
},
currentScene: 'Story',
storyHistory: [],
storyEngineMemory: {
discoveredFactIds: [],
inferredFactIds: [],
activeThreadIds: ['thread-1'],
resolvedScarIds: [],
recentCarrierIds: [],
recentSignalIds: [],
recentCompanionReactions: [],
},
characterChats: {},
animationState: AnimationState.IDLE,
currentEncounter: null,
npcInteractionActive: false,
currentScenePreset: null,
sceneHostileNpcs: [],
playerX: 0,
playerOffsetY: 0,
playerFacing: 'right',
playerActionMode: 'idle',
scrollWorld: false,
inBattle: false,
playerHp: 0,
playerMaxHp: 0,
playerMana: 0,
playerMaxMana: 0,
playerSkillCooldowns: {},
activeBuildBuffs: [],
activeCombatEffects: [],
playerCurrency: 0,
playerInventory: [],
playerEquipment: {
weapon: null,
armor: null,
relic: null,
},
npcStates: {
'npc-companion': {
affinity: 30,
helpUsed: false,
chattedCount: 0,
giftsGiven: 0,
inventory: [],
recruited: true,
revealedFacts: [],
knownAttributeRumors: [],
firstMeaningfulContactResolved: true,
seenBackstoryChapterIds: [],
stanceProfile: {
trust: 52,
warmth: 48,
ideologicalFit: 50,
fearOrGuard: 30,
loyalty: 40,
currentConflictTag: null,
recentApprovals: [],
recentDisapprovals: [],
},
},
},
quests: [],
roster: [],
companions: [
{
npcId: 'npc-companion',
characterId: 'archer-hero',
joinedAtAffinity: 30,
hp: 10,
maxHp: 10,
mana: 10,
maxMana: 10,
skillCooldowns: {},
},
],
currentBattleNpcId: null,
currentNpcBattleMode: null,
currentNpcBattleOutcome: null,
sparReturnEncounter: null,
sparPlayerHpBefore: null,
sparPlayerMaxHpBefore: null,
sparStoryHistoryBefore: null,
};
}
describe('companionReactionDirector', () => {
it('builds reactions and writes them back to stance', () => {
const state = createState();
const reactions = buildCompanionReactionBatch({
state,
signals: [
{
id: 'signal-1',
signalType: 'accept_contract',
threadIds: ['thread-1'],
},
],
actionText: '接下调查断桥旧案的委托',
});
const nextState = applyCompanionReactionToStance({
state,
reactions,
});
expect(reactions[0]?.reactionType).toBe('approve');
expect(nextState.npcStates['npc-companion']?.stanceProfile?.trust).toBeGreaterThan(
state.npcStates['npc-companion']?.stanceProfile?.trust ?? 0,
);
});
});