This commit is contained in:
2026-04-28 20:25:37 +08:00
parent f0471a4f8d
commit 0f013b6eee
45 changed files with 1117 additions and 1047 deletions

View File

@@ -5,7 +5,8 @@ import type { FunctionDocumentationEntry } from '../types';
* camp_travel_home_scene
*
* 从营地与同伴对话结束后,正式前往角色主线场景的控制 function。
* 这里除了元信息,也直接收口了它的按钮构造判定 helper
* 中文注释:前端只保留按钮构造判定 helper 和视觉元信息;
* 正式场景迁移、遭遇预览与快照写入统一由后端 resolver 承接。
*/
export const CAMP_TRAVEL_HOME_OPTION_VISUALS: StoryOption['visuals'] = {
playerAnimation: AnimationState.RUN,
@@ -41,10 +42,10 @@ export const CAMP_TRAVEL_HOME_FUNCTION: FunctionDocumentationEntry = {
source: 'src/data/functionCatalog/flow/campTravelHomeScene.ts',
summary: '营地开场后的专用旅行控制项。',
detailedDescription:
'它负责把开局同伴营地流程平稳切到角色真正的起始场景,并清理当前营地 encounter、战斗态和镜头残留状态。',
'它负责把开局同伴营地流程平稳切到角色真正的起始场景;正式目标场景、encounter 清理、战斗态清理和镜头残留状态由后端 resolver 写入。',
trigger: '常见于开局同伴营地对话后的跟进选项。',
execution:
'点击后不会走普通 state function 结算,而是执行一次定制场景迁移和历史写入。',
'点击后作为服务端 runtime function id 提交到 /api/runtime/story/actions/resolve由后端执行定制场景迁移和历史写入。',
result: '玩家会离开营地进入角色主场景,正式开始该角色的冒险线。',
active: true,
runtime: {
@@ -52,11 +53,11 @@ export const CAMP_TRAVEL_HOME_FUNCTION: FunctionDocumentationEntry = {
uiMode: 'none',
visuals: CAMP_TRAVEL_HOME_OPTION_VISUALS,
executor:
'src/hooks/rpg-runtime-story/choiceActions.ts -> handleCampTravelHome',
'server-rs/crates/api-server/src/runtime_story/compat.rs -> resolve_camp_travel_home_scene_action',
animationNote:
'先播放营地离场的 run 演出,再切到正式场景并生成 encounter preview。',
'前端保留 run 视觉元信息;正式状态以服务端 hydrated snapshot 为准。',
storyNote:
'通过 commitGeneratedStateWithEncounterEntry 写入离营结果,并在新场景继续后续剧情。',
'后端写入离营结果、生成 encounter preview,并在新场景继续后续剧情。',
uiNote: '这是专用旅行流程,不会打开 modal。',
},
};

View File

@@ -1,8 +1,9 @@
import { existsSync } from 'node:fs';
import { SERVER_RUNTIME_FUNCTION_IDS } from '../../../packages/shared/src/contracts/rpgRuntimeStoryAction';
import { describe, expect, it } from 'vitest';
import { SERVER_RUNTIME_FUNCTION_IDS } from '../../../packages/shared/src/contracts/rpgRuntimeStoryAction';
import type { Encounter, GameState, InventoryItem } from '../../types';
import {
ALL_FUNCTION_DOCUMENTATION,
buildCampTravelHomeOption,
@@ -11,6 +12,7 @@ import {
buildNpcPreviewTalkOption,
buildNpcRecruitModalState,
buildNpcTradeModalState,
CAMP_TRAVEL_HOME_FUNCTION,
CONTINUE_ADVENTURE_FUNCTION,
getFunctionDocumentationById,
isNpcPreviewTalkOption,
@@ -18,7 +20,6 @@ import {
shouldNpcRecruitOpenModal,
} from './index';
import { RPG_FUNCTION_RUNTIME_OVERVIEW } from './runtimeIndex';
import type { Encounter, GameState, InventoryItem } from '../../types';
function createEncounter(overrides: Partial<Encounter> = {}): Encounter {
return {
@@ -103,6 +104,12 @@ describe('functionCatalog', () => {
expect(campTravelOption.functionId).toBe('camp_travel_home_scene');
expect(campTravelOption.actionText).toBe('前往 竹林古道');
expect(campTravelOption.detailText).toBe('离开营地,前往 竹林古道。');
expect(CAMP_TRAVEL_HOME_FUNCTION.runtime?.executor).toContain(
'server-rs/crates/api-server/src/runtime_story/compat.rs',
);
expect(CAMP_TRAVEL_HOME_FUNCTION.detailedDescription).toContain(
'后端 resolver',
);
});
it('builds npc preview talk options from the current encounter', () => {