Simplify custom world result editing controls
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { AnimationState, type GameState } from '../../types';
|
||||
import { buildChapterQuestForScene } from '../../data/questFlow';
|
||||
import { AnimationState, type GameState, WorldType } from '../../types';
|
||||
import { advanceChapterState, resolveCurrentChapterState } from './chapterDirector';
|
||||
|
||||
function createState(signalCount: number): GameState {
|
||||
@@ -73,6 +74,54 @@ function createState(signalCount: number): GameState {
|
||||
};
|
||||
}
|
||||
|
||||
function createSceneChapterState() {
|
||||
const quest = buildChapterQuestForScene({
|
||||
scene: {
|
||||
id: 'scene-court',
|
||||
name: '宫苑内庭',
|
||||
description: '回廊深处静得过分。',
|
||||
npcs: [
|
||||
{
|
||||
id: 'npc-maid',
|
||||
name: '旧宫侍女',
|
||||
description: '她总知道哪条回廊最近不该过去。',
|
||||
avatar: '侍',
|
||||
role: '宫人',
|
||||
hostile: false,
|
||||
},
|
||||
{
|
||||
id: 'hostile-shadow',
|
||||
name: '旧宫戍影',
|
||||
description: '巡行在回廊里的敌影。',
|
||||
avatar: '戍',
|
||||
role: '敌对角色',
|
||||
monsterPresetId: 'monster-11',
|
||||
hostile: true,
|
||||
},
|
||||
],
|
||||
treasureHints: ['回廊暗格里的香囊'],
|
||||
},
|
||||
worldType: WorldType.WUXIA,
|
||||
});
|
||||
|
||||
if (!quest) {
|
||||
throw new Error('Expected chapter quest');
|
||||
}
|
||||
|
||||
return {
|
||||
...createState(0),
|
||||
currentScenePreset: {
|
||||
id: 'scene-court',
|
||||
name: '宫苑内庭',
|
||||
description: '回廊深处静得过分。',
|
||||
imageSrc: '/scene.png',
|
||||
treasureHints: ['回廊暗格里的香囊'],
|
||||
npcs: [],
|
||||
},
|
||||
quests: [quest],
|
||||
} satisfies GameState;
|
||||
}
|
||||
|
||||
describe('chapterDirector', () => {
|
||||
it('resolves chapter stages from signal intensity', () => {
|
||||
expect(resolveCurrentChapterState({ state: createState(1) }).stage).toBe('opening');
|
||||
@@ -89,4 +138,58 @@ describe('chapterDirector', () => {
|
||||
|
||||
expect(next.id).toBe(previous.id);
|
||||
});
|
||||
|
||||
it('binds the current chapter to the current scene chapter quest', () => {
|
||||
const openingState = createSceneChapterState();
|
||||
const openingChapter = resolveCurrentChapterState({ state: openingState });
|
||||
expect(openingChapter.id).toBe('chapter:scene:scene-court');
|
||||
expect(openingChapter.sceneId).toBe('scene-court');
|
||||
expect(openingChapter.chapterQuestId).toBe('quest:chapter:scene-court');
|
||||
expect(openingChapter.stage).toBe('opening');
|
||||
|
||||
const turningState: GameState = {
|
||||
...openingState,
|
||||
quests: [
|
||||
{
|
||||
...openingState.quests[0]!,
|
||||
steps: openingState.quests[0]!.steps?.map((step) =>
|
||||
step.id === 'step_scene_opening'
|
||||
? { ...step, progress: step.requiredCount }
|
||||
: step.id === 'step_scene_pressure'
|
||||
? { ...step, progress: step.requiredCount }
|
||||
: step,
|
||||
),
|
||||
activeStepId: 'step_scene_turning',
|
||||
},
|
||||
],
|
||||
};
|
||||
expect(resolveCurrentChapterState({ state: turningState }).stage).toBe('turning_point');
|
||||
|
||||
const climaxState: GameState = {
|
||||
...turningState,
|
||||
quests: [
|
||||
{
|
||||
...turningState.quests[0]!,
|
||||
steps: turningState.quests[0]!.steps?.map((step) => ({
|
||||
...step,
|
||||
progress: step.requiredCount,
|
||||
})),
|
||||
activeStepId: null,
|
||||
status: 'ready_to_turn_in',
|
||||
},
|
||||
],
|
||||
};
|
||||
expect(resolveCurrentChapterState({ state: climaxState }).stage).toBe('climax');
|
||||
|
||||
const aftermathState: GameState = {
|
||||
...climaxState,
|
||||
quests: [
|
||||
{
|
||||
...climaxState.quests[0]!,
|
||||
status: 'turned_in',
|
||||
},
|
||||
],
|
||||
};
|
||||
expect(resolveCurrentChapterState({ state: aftermathState }).stage).toBe('aftermath');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user