This commit is contained in:
131
src/services/storyEngine/companionReactionDirector.test.ts
Normal file
131
src/services/storyEngine/companionReactionDirector.test.ts
Normal file
@@ -0,0 +1,131 @@
|
||||
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,
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user