统一 Rust 与 TypeScript 格式化门禁
纳入 AGC Cargo workspace 的统一 rustfmt 检查与格式化入口 完成项目 TypeScript/Prettier 与 Rust 全量格式化 修复 Pingora expected executable 门禁的空白敏感误报 同步开发运维文档与 AGC skill pack 格式化忽略规则
This commit is contained in:
@@ -72,7 +72,9 @@ function createModalState(overrides: Partial<GameState> = {}): GameState {
|
||||
|
||||
describe('functionCatalog', () => {
|
||||
it('keeps function documentation ids unique and source files resolvable', () => {
|
||||
const documentationIds = ALL_FUNCTION_DOCUMENTATION.map((entry) => entry.id);
|
||||
const documentationIds = ALL_FUNCTION_DOCUMENTATION.map(
|
||||
(entry) => entry.id,
|
||||
);
|
||||
|
||||
expect(new Set(documentationIds).size).toBe(documentationIds.length);
|
||||
ALL_FUNCTION_DOCUMENTATION.forEach((entry) => {
|
||||
|
||||
@@ -37,9 +37,9 @@ export const NPC_GIFT_FUNCTION: FunctionDocumentationEntry = {
|
||||
detailedDescription:
|
||||
'它会把当前互动引到礼物选择 modal,礼物列表、好感增益和不可选原因都读取后端 runtimeNpcInteraction view。',
|
||||
trigger: '后端判断当前 NPC 可接收礼物时出现在 NPC 交互菜单里。',
|
||||
execution:
|
||||
'首次点击只打开 gift modal,确认礼物后只提交 itemId 给后端结算。',
|
||||
result: '玩家可立即看到后端结算后的好感变化与送礼反馈,并影响后续交易、聊天和招募阈值。',
|
||||
execution: '首次点击只打开 gift modal,确认礼物后只提交 itemId 给后端结算。',
|
||||
result:
|
||||
'玩家可立即看到后端结算后的好感变化与送礼反馈,并影响后续交易、聊天和招募阈值。',
|
||||
active: true,
|
||||
runtime: {
|
||||
storyMode: 'modal_then_generate',
|
||||
|
||||
@@ -60,7 +60,7 @@ export const NPC_PREVIEW_TALK_FUNCTION: FunctionDocumentationEntry = {
|
||||
uiMode: 'npc_interaction_entry',
|
||||
visuals: NPC_PREVIEW_TALK_OPTION_VISUALS,
|
||||
executor:
|
||||
'src/hooks/rpg-runtime-story/choiceActions.ts + src/hooks/rpg-runtime-story/useRpgRuntimeNpcInteraction.ts',
|
||||
'src/hooks/rpg-runtime-story/choiceActions.ts + src/hooks/rpg-runtime-story/useRpgRuntimeNpcInteraction.ts',
|
||||
animationNote:
|
||||
'保持轻量 idle 站场,不做额外位移,重点是把交互焦点切到 NPC 身上。',
|
||||
storyNote:
|
||||
|
||||
@@ -54,7 +54,8 @@ export const NPC_TRADE_FUNCTION: FunctionDocumentationEntry = {
|
||||
animationNote: '第一次点击不播额外战斗或位移动画,重点是切到交易窗口。',
|
||||
storyNote:
|
||||
'真正的剧情推进发生在 confirmTrade 之后,而不是打开 modal 的瞬间。',
|
||||
uiNote: '会先打开交易 modal,并预选后端 view 中第一件可提交的买入 / 卖出物品。',
|
||||
uiNote:
|
||||
'会先打开交易 modal,并预选后端 view 中第一件可提交的买入 / 卖出物品。',
|
||||
compactDetailText: '查看库存与价格',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -75,4 +75,3 @@ export const BATTLE_ALL_IN_CRUSH_FUNCTION_SOURCE: StateFunctionRuntimeSource = {
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -17,7 +17,8 @@ export const BATTLE_ATTACK_BASIC_FUNCTION: FunctionDocumentationEntry = {
|
||||
trigger: '仅在 battle 状态且场上仍有存活敌人时,由后端战斗 option 池下发。',
|
||||
execution:
|
||||
'前端透传 functionId,Rust 后端经 story battle facade 调用 module-combat 按普通攻击规则结算本回合。',
|
||||
result: '刷新 HP、战斗日志和下一轮战斗 options;若敌人被击败,再进入脱战剧情推理。',
|
||||
result:
|
||||
'刷新 HP、战斗日志和下一轮战斗 options;若敌人被击败,再进入脱战剧情推理。',
|
||||
state: 'battle',
|
||||
category: 'battle',
|
||||
active: true,
|
||||
@@ -27,8 +28,7 @@ export const BATTLE_ATTACK_BASIC_FUNCTION: FunctionDocumentationEntry = {
|
||||
executor:
|
||||
'server-rs/crates/module-combat/src/lib.rs -> resolve_combat_action',
|
||||
animationNote: '播放一次基础攻击和受击反馈,不扩展成连续多段连击。',
|
||||
storyNote:
|
||||
'战斗未结束时只展示本次结算文本;战斗结束后才请求脱战剧情。',
|
||||
storyNote: '战斗未结束时只展示本次结算文本;战斗结束后才请求脱战剧情。',
|
||||
uiNote: '由后端战斗 option 池生成,不进入前端本地 state function 候选。',
|
||||
compactDetailText: '直接攻击眼前敌人',
|
||||
},
|
||||
|
||||
@@ -7,64 +7,64 @@ import type { StateFunctionRuntimeSource } from '../types';
|
||||
* 战斗中的脱离动作。它不是继续换血,而是明确让主角放弃当前缠斗,
|
||||
* 把叙事重心切到“拉开距离、甩开追击、离开战场”。
|
||||
*/
|
||||
export const BATTLE_ESCAPE_BREAKOUT_FUNCTION_SOURCE: StateFunctionRuntimeSource = {
|
||||
definition: {
|
||||
id: 'battle_escape_breakout',
|
||||
state: 'battle',
|
||||
category: 'escape',
|
||||
text: '逃跑:转身甩开',
|
||||
description: '立刻放弃缠斗,转身拉开距离,冲向下一片区域。',
|
||||
visual: {
|
||||
playerAnimation: AnimationState.RUN,
|
||||
playerMoveMeters: -0.6,
|
||||
playerOffsetY: 0,
|
||||
playerFacing: 'left',
|
||||
scrollWorld: true,
|
||||
monsterActionTemplate: '{monster}在后方死死咬住不放',
|
||||
monsterAnimation: 'idle',
|
||||
monsterMoveMeters: 0,
|
||||
export const BATTLE_ESCAPE_BREAKOUT_FUNCTION_SOURCE: StateFunctionRuntimeSource =
|
||||
{
|
||||
definition: {
|
||||
id: 'battle_escape_breakout',
|
||||
state: 'battle',
|
||||
category: 'escape',
|
||||
text: '逃跑:转身甩开',
|
||||
description: '立刻放弃缠斗,转身拉开距离,冲向下一片区域。',
|
||||
visual: {
|
||||
playerAnimation: AnimationState.RUN,
|
||||
playerMoveMeters: -0.6,
|
||||
playerOffsetY: 0,
|
||||
playerFacing: 'left',
|
||||
scrollWorld: true,
|
||||
monsterActionTemplate: '{monster}在后方死死咬住不放',
|
||||
monsterAnimation: 'idle',
|
||||
monsterMoveMeters: 0,
|
||||
},
|
||||
effect: {
|
||||
escapeDurationMs: 5000,
|
||||
escapeDistance: 5,
|
||||
monsterLagStart: 0.52,
|
||||
monsterLagEnd: 0.34,
|
||||
sceneShift: 0,
|
||||
enterBattle: false,
|
||||
},
|
||||
},
|
||||
effect: {
|
||||
escapeDurationMs: 5000,
|
||||
escapeDistance: 5,
|
||||
monsterLagStart: 0.52,
|
||||
monsterLagEnd: 0.34,
|
||||
sceneShift: 0,
|
||||
enterBattle: false,
|
||||
promptDescription:
|
||||
'从当前战斗中脱身、拉开距离或撤离,文案可以自然改写,但仍要保持这是逃脱而不是继续交战。',
|
||||
documentation: {
|
||||
id: 'battle_escape_breakout',
|
||||
domain: 'state',
|
||||
title: '逃跑:转身甩开',
|
||||
source: 'src/data/functionCatalog/state/battleEscapeBreakout.ts',
|
||||
summary: '用于脱战、逃离和切离镜头压力的战斗 function。',
|
||||
detailedDescription:
|
||||
'它让回合从“继续打”切换到“先活下来”,并带出逃跑镜头、距离拉开和怪物追击落后的演出逻辑。',
|
||||
trigger: '仅在 battle 状态下参与候选,并会在低血时提升优先级。',
|
||||
execution:
|
||||
'不追求伤害,而是提供 escapeDurationMs、escapeDistance 与 monsterLag 参数,驱动逃跑流程与镜头表现。',
|
||||
result: '适合生命见底、资源不够,或玩家主动决定放弃当前战斗时使用。',
|
||||
state: 'battle',
|
||||
category: 'escape',
|
||||
active: true,
|
||||
},
|
||||
},
|
||||
promptDescription:
|
||||
'从当前战斗中脱身、拉开距离或撤离,文案可以自然改写,但仍要保持这是逃脱而不是继续交战。',
|
||||
documentation: {
|
||||
id: 'battle_escape_breakout',
|
||||
domain: 'state',
|
||||
title: '逃跑:转身甩开',
|
||||
source: 'src/data/functionCatalog/state/battleEscapeBreakout.ts',
|
||||
summary: '用于脱战、逃离和切离镜头压力的战斗 function。',
|
||||
detailedDescription:
|
||||
'它让回合从“继续打”切换到“先活下来”,并带出逃跑镜头、距离拉开和怪物追击落后的演出逻辑。',
|
||||
trigger: '仅在 battle 状态下参与候选,并会在低血时提升优先级。',
|
||||
execution:
|
||||
'不追求伤害,而是提供 escapeDurationMs、escapeDistance 与 monsterLag 参数,驱动逃跑流程与镜头表现。',
|
||||
result: '适合生命见底、资源不够,或玩家主动决定放弃当前战斗时使用。',
|
||||
state: 'battle',
|
||||
category: 'escape',
|
||||
active: true,
|
||||
},
|
||||
runtime: {
|
||||
buildSuggestedActionText({ metrics, environment }) {
|
||||
if (metrics.playerHpRatio <= 0.35) {
|
||||
return `撑着伤势先脱离${environment.monsterName}的追杀`;
|
||||
}
|
||||
return `转身拉开距离,甩开${environment.monsterName}`;
|
||||
runtime: {
|
||||
buildSuggestedActionText({ metrics, environment }) {
|
||||
if (metrics.playerHpRatio <= 0.35) {
|
||||
return `撑着伤势先脱离${environment.monsterName}的追杀`;
|
||||
}
|
||||
return `转身拉开距离,甩开${environment.monsterName}`;
|
||||
},
|
||||
getPriority({ metrics }) {
|
||||
return metrics.playerHpRatio <= 0.2
|
||||
? 9
|
||||
: metrics.playerHpRatio <= 0.35
|
||||
? 5
|
||||
: 1;
|
||||
},
|
||||
},
|
||||
getPriority({ metrics }) {
|
||||
return metrics.playerHpRatio <= 0.2
|
||||
? 9
|
||||
: metrics.playerHpRatio <= 0.35
|
||||
? 5
|
||||
: 1;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@@ -68,4 +68,3 @@ export const BATTLE_FEINT_STEP_FUNCTION_SOURCE: StateFunctionRuntimeSource = {
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -7,71 +7,71 @@ import type { StateFunctionRuntimeSource } from '../types';
|
||||
* 战斗中的终结窗口动作。它要求系统把这一回合理解为“敌人已经露出空档”,
|
||||
* 因而优先演出收割、补刀和终结技。
|
||||
*/
|
||||
export const BATTLE_FINISHER_WINDOW_FUNCTION_SOURCE: StateFunctionRuntimeSource = {
|
||||
definition: {
|
||||
id: 'battle_finisher_window',
|
||||
state: 'battle',
|
||||
category: 'battle',
|
||||
text: '战斗:抓住破绽',
|
||||
description: '专门针对敌人露出的空档压上终结技,节奏更短、更猛。',
|
||||
visual: {
|
||||
playerAnimation: AnimationState.SKILL3,
|
||||
playerMoveMeters: 0,
|
||||
playerOffsetY: 0,
|
||||
playerFacing: 'right',
|
||||
scrollWorld: false,
|
||||
monsterActionTemplate: '{monster}来不及调整姿态,只能仓促迎击',
|
||||
monsterAnimation: 'attack',
|
||||
monsterMoveMeters: 0,
|
||||
},
|
||||
effect: {
|
||||
damageMultiplier: 1.4,
|
||||
incomingDamageMultiplier: 1.05,
|
||||
turnTimeMultiplier: 0.92,
|
||||
skillWeights: {
|
||||
finisher: 6,
|
||||
burst: 3.5,
|
||||
mobility: 1.5,
|
||||
steady: 0.8,
|
||||
projectile: 0.6,
|
||||
export const BATTLE_FINISHER_WINDOW_FUNCTION_SOURCE: StateFunctionRuntimeSource =
|
||||
{
|
||||
definition: {
|
||||
id: 'battle_finisher_window',
|
||||
state: 'battle',
|
||||
category: 'battle',
|
||||
text: '战斗:抓住破绽',
|
||||
description: '专门针对敌人露出的空档压上终结技,节奏更短、更猛。',
|
||||
visual: {
|
||||
playerAnimation: AnimationState.SKILL3,
|
||||
playerMoveMeters: 0,
|
||||
playerOffsetY: 0,
|
||||
playerFacing: 'right',
|
||||
scrollWorld: false,
|
||||
monsterActionTemplate: '{monster}来不及调整姿态,只能仓促迎击',
|
||||
monsterAnimation: 'attack',
|
||||
monsterMoveMeters: 0,
|
||||
},
|
||||
effect: {
|
||||
damageMultiplier: 1.4,
|
||||
incomingDamageMultiplier: 1.05,
|
||||
turnTimeMultiplier: 0.92,
|
||||
skillWeights: {
|
||||
finisher: 6,
|
||||
burst: 3.5,
|
||||
mobility: 1.5,
|
||||
steady: 0.8,
|
||||
projectile: 0.6,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
promptDescription:
|
||||
'抓住面前敌人的破绽收割或终结,文案可以自然改写,但仍要保持这是终结窗口。',
|
||||
documentation: {
|
||||
id: 'battle_finisher_window',
|
||||
domain: 'state',
|
||||
title: '战斗:抓住破绽',
|
||||
source: 'src/data/functionCatalog/state/battleFinisherWindow.ts',
|
||||
summary: '围绕残局补刀与爆发终结的战斗 function。',
|
||||
detailedDescription:
|
||||
'它会强烈推动“敌人已经失衡、主角准备收口”的叙事判断,让 actionText 与技能选择都更像最后一击。',
|
||||
trigger: '仅在 battle 状态下参与候选,并会在敌方血量偏低时明显升优先级。',
|
||||
execution:
|
||||
'提供最高档位之一的 damageMultiplier,缩短 turnTimeMultiplier,并极度偏向 finisher / burst 技能。',
|
||||
result: '适合在敌方残血、明显露出空档,或需要一口气结束战斗时使用。',
|
||||
state: 'battle',
|
||||
category: 'battle',
|
||||
active: true,
|
||||
},
|
||||
runtime: {
|
||||
buildSuggestedActionText({ metrics, environment }) {
|
||||
if (metrics.monsterHpRatio <= 0.25) {
|
||||
return `完成对${environment.monsterName}的残血收割`;
|
||||
}
|
||||
if (metrics.monsterHpRatio <= 0.45) {
|
||||
return `抓住${environment.monsterName}露出的破绽补上重击`;
|
||||
}
|
||||
return `盯住${environment.monsterName}的空当准备终结一击`;
|
||||
promptDescription:
|
||||
'抓住面前敌人的破绽收割或终结,文案可以自然改写,但仍要保持这是终结窗口。',
|
||||
documentation: {
|
||||
id: 'battle_finisher_window',
|
||||
domain: 'state',
|
||||
title: '战斗:抓住破绽',
|
||||
source: 'src/data/functionCatalog/state/battleFinisherWindow.ts',
|
||||
summary: '围绕残局补刀与爆发终结的战斗 function。',
|
||||
detailedDescription:
|
||||
'它会强烈推动“敌人已经失衡、主角准备收口”的叙事判断,让 actionText 与技能选择都更像最后一击。',
|
||||
trigger: '仅在 battle 状态下参与候选,并会在敌方血量偏低时明显升优先级。',
|
||||
execution:
|
||||
'提供最高档位之一的 damageMultiplier,缩短 turnTimeMultiplier,并极度偏向 finisher / burst 技能。',
|
||||
result: '适合在敌方残血、明显露出空档,或需要一口气结束战斗时使用。',
|
||||
state: 'battle',
|
||||
category: 'battle',
|
||||
active: true,
|
||||
},
|
||||
getPriority({ metrics }) {
|
||||
return metrics.monsterHpRatio <= 0.25
|
||||
? 10
|
||||
: metrics.monsterHpRatio <= 0.45
|
||||
? 6
|
||||
: 1;
|
||||
runtime: {
|
||||
buildSuggestedActionText({ metrics, environment }) {
|
||||
if (metrics.monsterHpRatio <= 0.25) {
|
||||
return `完成对${environment.monsterName}的残血收割`;
|
||||
}
|
||||
if (metrics.monsterHpRatio <= 0.45) {
|
||||
return `抓住${environment.monsterName}露出的破绽补上重击`;
|
||||
}
|
||||
return `盯住${environment.monsterName}的空当准备终结一击`;
|
||||
},
|
||||
getPriority({ metrics }) {
|
||||
return metrics.monsterHpRatio <= 0.25
|
||||
? 10
|
||||
: metrics.monsterHpRatio <= 0.45
|
||||
? 6
|
||||
: 1;
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@@ -66,4 +66,3 @@ export const BATTLE_GUARD_BREAK_FUNCTION_SOURCE: StateFunctionRuntimeSource = {
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -7,66 +7,66 @@ import type { StateFunctionRuntimeSource } from '../types';
|
||||
* 战斗中的稳扎试探动作。适合在局势未明、资源需要保留时,
|
||||
* 先用安全且持续的压制把信息和节奏摸出来。
|
||||
*/
|
||||
export const BATTLE_PROBE_PRESSURE_FUNCTION_SOURCE: StateFunctionRuntimeSource = {
|
||||
definition: {
|
||||
id: 'battle_probe_pressure',
|
||||
state: 'battle',
|
||||
category: 'battle',
|
||||
text: '战斗:稳扎试探',
|
||||
description: '以持续压制和稳健试探为主,更容易发动常规连段和中段技能。',
|
||||
visual: {
|
||||
playerAnimation: AnimationState.SKILL1,
|
||||
playerMoveMeters: 0,
|
||||
playerOffsetY: 0,
|
||||
playerFacing: 'right',
|
||||
scrollWorld: false,
|
||||
monsterActionTemplate: '{monster}一边招架一边寻找反扑的缝隙',
|
||||
monsterAnimation: 'attack',
|
||||
monsterMoveMeters: 0,
|
||||
},
|
||||
effect: {
|
||||
damageMultiplier: 1,
|
||||
incomingDamageMultiplier: 0.95,
|
||||
skillWeights: {
|
||||
steady: 5,
|
||||
burst: 2.2,
|
||||
mobility: 2,
|
||||
projectile: 2,
|
||||
finisher: 1.2,
|
||||
export const BATTLE_PROBE_PRESSURE_FUNCTION_SOURCE: StateFunctionRuntimeSource =
|
||||
{
|
||||
definition: {
|
||||
id: 'battle_probe_pressure',
|
||||
state: 'battle',
|
||||
category: 'battle',
|
||||
text: '战斗:稳扎试探',
|
||||
description: '以持续压制和稳健试探为主,更容易发动常规连段和中段技能。',
|
||||
visual: {
|
||||
playerAnimation: AnimationState.SKILL1,
|
||||
playerMoveMeters: 0,
|
||||
playerOffsetY: 0,
|
||||
playerFacing: 'right',
|
||||
scrollWorld: false,
|
||||
monsterActionTemplate: '{monster}一边招架一边寻找反扑的缝隙',
|
||||
monsterAnimation: 'attack',
|
||||
monsterMoveMeters: 0,
|
||||
},
|
||||
effect: {
|
||||
damageMultiplier: 1,
|
||||
incomingDamageMultiplier: 0.95,
|
||||
skillWeights: {
|
||||
steady: 5,
|
||||
burst: 2.2,
|
||||
mobility: 2,
|
||||
projectile: 2,
|
||||
finisher: 1.2,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
promptDescription:
|
||||
'对面前敌人稳扎稳打地试探施压,文案可以自然改写,但仍要保持这是试探压制。',
|
||||
documentation: {
|
||||
id: 'battle_probe_pressure',
|
||||
domain: 'state',
|
||||
title: '战斗:稳扎试探',
|
||||
source: 'src/data/functionCatalog/state/battleProbePressure.ts',
|
||||
summary: '强调观察、压迫和中段连段的稳健战斗 function。',
|
||||
detailedDescription:
|
||||
'这个 function 让战斗回合更像“边压边看”,适合在想控制资源消耗、等待更好机会,或需要防止自己出手过重时使用。',
|
||||
trigger: '仅在 battle 状态下参与候选。',
|
||||
execution:
|
||||
'保持标准 damageMultiplier,轻微降低 incomingDamageMultiplier,并把 skillWeights 明显偏向 steady,兼顾少量 mobility / projectile。',
|
||||
result: '适合拉平节奏、压住敌人反扑窗口,或在低蓝时维持安全输出。',
|
||||
state: 'battle',
|
||||
category: 'battle',
|
||||
active: true,
|
||||
},
|
||||
runtime: {
|
||||
buildSuggestedActionText({ metrics, environment }) {
|
||||
if (metrics.playerManaRatio <= 0.3) {
|
||||
return `稳住节奏试探${environment.monsterName},先省下灵力`;
|
||||
}
|
||||
if (metrics.monsterHpRatio <= 0.3) {
|
||||
return `稳步逼近,补掉${environment.monsterName}残余血量`;
|
||||
}
|
||||
return `稳扎稳打继续试探${environment.monsterName}`;
|
||||
promptDescription:
|
||||
'对面前敌人稳扎稳打地试探施压,文案可以自然改写,但仍要保持这是试探压制。',
|
||||
documentation: {
|
||||
id: 'battle_probe_pressure',
|
||||
domain: 'state',
|
||||
title: '战斗:稳扎试探',
|
||||
source: 'src/data/functionCatalog/state/battleProbePressure.ts',
|
||||
summary: '强调观察、压迫和中段连段的稳健战斗 function。',
|
||||
detailedDescription:
|
||||
'这个 function 让战斗回合更像“边压边看”,适合在想控制资源消耗、等待更好机会,或需要防止自己出手过重时使用。',
|
||||
trigger: '仅在 battle 状态下参与候选。',
|
||||
execution:
|
||||
'保持标准 damageMultiplier,轻微降低 incomingDamageMultiplier,并把 skillWeights 明显偏向 steady,兼顾少量 mobility / projectile。',
|
||||
result: '适合拉平节奏、压住敌人反扑窗口,或在低蓝时维持安全输出。',
|
||||
state: 'battle',
|
||||
category: 'battle',
|
||||
active: true,
|
||||
},
|
||||
getPriority({ metrics }) {
|
||||
return metrics.playerManaRatio <= 0.3 ? 8 : 4;
|
||||
runtime: {
|
||||
buildSuggestedActionText({ metrics, environment }) {
|
||||
if (metrics.playerManaRatio <= 0.3) {
|
||||
return `稳住节奏试探${environment.monsterName},先省下灵力`;
|
||||
}
|
||||
if (metrics.monsterHpRatio <= 0.3) {
|
||||
return `稳步逼近,补掉${environment.monsterName}残余血量`;
|
||||
}
|
||||
return `稳扎稳打继续试探${environment.monsterName}`;
|
||||
},
|
||||
getPriority({ metrics }) {
|
||||
return metrics.playerManaRatio <= 0.3 ? 8 : 4;
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@@ -7,72 +7,72 @@ import type { StateFunctionRuntimeSource } from '../types';
|
||||
* 战斗中的恢复动作。它会把当前回合塑造成“先稳住伤势与灵力”,
|
||||
* 让数值、冷却和叙事都朝回气与整顿节奏的方向靠拢。
|
||||
*/
|
||||
export const BATTLE_RECOVER_BREATH_FUNCTION_SOURCE: StateFunctionRuntimeSource = {
|
||||
definition: {
|
||||
id: 'battle_recover_breath',
|
||||
state: 'battle',
|
||||
category: 'recovery',
|
||||
text: '战斗:收势调息',
|
||||
description: '边守边调息,恢复少量生命和灵力,并让技能冷却更快转动。',
|
||||
visual: {
|
||||
playerAnimation: AnimationState.IDLE,
|
||||
playerMoveMeters: 0,
|
||||
playerOffsetY: 0,
|
||||
playerFacing: 'right',
|
||||
scrollWorld: false,
|
||||
monsterActionTemplate: '{monster}仍在逼近,不给你轻松喘息的空当',
|
||||
monsterAnimation: 'move',
|
||||
monsterMoveMeters: -0.1,
|
||||
},
|
||||
effect: {
|
||||
damageMultiplier: 0.72,
|
||||
incomingDamageMultiplier: 0.7,
|
||||
healAmount: 12,
|
||||
manaRestore: 18,
|
||||
cooldownTickBonus: 1,
|
||||
skillWeights: {
|
||||
steady: 3,
|
||||
mobility: 2,
|
||||
projectile: 1.8,
|
||||
burst: 1,
|
||||
finisher: 0.4,
|
||||
export const BATTLE_RECOVER_BREATH_FUNCTION_SOURCE: StateFunctionRuntimeSource =
|
||||
{
|
||||
definition: {
|
||||
id: 'battle_recover_breath',
|
||||
state: 'battle',
|
||||
category: 'recovery',
|
||||
text: '战斗:收势调息',
|
||||
description: '边守边调息,恢复少量生命和灵力,并让技能冷却更快转动。',
|
||||
visual: {
|
||||
playerAnimation: AnimationState.IDLE,
|
||||
playerMoveMeters: 0,
|
||||
playerOffsetY: 0,
|
||||
playerFacing: 'right',
|
||||
scrollWorld: false,
|
||||
monsterActionTemplate: '{monster}仍在逼近,不给你轻松喘息的空当',
|
||||
monsterAnimation: 'move',
|
||||
monsterMoveMeters: -0.1,
|
||||
},
|
||||
effect: {
|
||||
damageMultiplier: 0.72,
|
||||
incomingDamageMultiplier: 0.7,
|
||||
healAmount: 12,
|
||||
manaRestore: 18,
|
||||
cooldownTickBonus: 1,
|
||||
skillWeights: {
|
||||
steady: 3,
|
||||
mobility: 2,
|
||||
projectile: 1.8,
|
||||
burst: 1,
|
||||
finisher: 0.4,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
promptDescription:
|
||||
'在战斗中收势调息、稳住伤势或回气,文案可以自然改写,但仍要保持这是恢复而不是继续猛攻。',
|
||||
documentation: {
|
||||
id: 'battle_recover_breath',
|
||||
domain: 'state',
|
||||
title: '战斗:收势调息',
|
||||
source: 'src/data/functionCatalog/state/battleRecoverBreath.ts',
|
||||
summary: '战斗中的保命与回气 function。',
|
||||
detailedDescription:
|
||||
'这个 function 专门为低血、低蓝或技能轮转吃紧时准备,让一回合承担“止血、回蓝、缓冷却”的综合恢复职责。',
|
||||
trigger: '仅在 battle 状态下参与候选,且通常会在低血或低蓝时被提权。',
|
||||
execution:
|
||||
'显著降低 damageMultiplier 和 incomingDamageMultiplier,同时提供 healAmount、manaRestore 与 cooldownTickBonus。',
|
||||
result: '适合临时止损、等关键技能转好,或把高压战斗拉回可控节奏。',
|
||||
state: 'battle',
|
||||
category: 'recovery',
|
||||
active: true,
|
||||
},
|
||||
runtime: {
|
||||
buildSuggestedActionText({ metrics }) {
|
||||
if (metrics.playerHpRatio <= 0.35) {
|
||||
return '原地打坐恢复血量';
|
||||
}
|
||||
if (metrics.playerManaRatio <= 0.3) {
|
||||
return '收势调息回一口灵力';
|
||||
}
|
||||
return '边守边调息稳住节奏';
|
||||
promptDescription:
|
||||
'在战斗中收势调息、稳住伤势或回气,文案可以自然改写,但仍要保持这是恢复而不是继续猛攻。',
|
||||
documentation: {
|
||||
id: 'battle_recover_breath',
|
||||
domain: 'state',
|
||||
title: '战斗:收势调息',
|
||||
source: 'src/data/functionCatalog/state/battleRecoverBreath.ts',
|
||||
summary: '战斗中的保命与回气 function。',
|
||||
detailedDescription:
|
||||
'这个 function 专门为低血、低蓝或技能轮转吃紧时准备,让一回合承担“止血、回蓝、缓冷却”的综合恢复职责。',
|
||||
trigger: '仅在 battle 状态下参与候选,且通常会在低血或低蓝时被提权。',
|
||||
execution:
|
||||
'显著降低 damageMultiplier 和 incomingDamageMultiplier,同时提供 healAmount、manaRestore 与 cooldownTickBonus。',
|
||||
result: '适合临时止损、等关键技能转好,或把高压战斗拉回可控节奏。',
|
||||
state: 'battle',
|
||||
category: 'recovery',
|
||||
active: true,
|
||||
},
|
||||
getPriority({ metrics }) {
|
||||
return (
|
||||
(metrics.playerHpRatio <= 0.35 ? 10 : 0) +
|
||||
(metrics.playerManaRatio <= 0.3 ? 6 : 0)
|
||||
);
|
||||
runtime: {
|
||||
buildSuggestedActionText({ metrics }) {
|
||||
if (metrics.playerHpRatio <= 0.35) {
|
||||
return '原地打坐恢复血量';
|
||||
}
|
||||
if (metrics.playerManaRatio <= 0.3) {
|
||||
return '收势调息回一口灵力';
|
||||
}
|
||||
return '边守边调息稳住节奏';
|
||||
},
|
||||
getPriority({ metrics }) {
|
||||
return (
|
||||
(metrics.playerHpRatio <= 0.35 ? 10 : 0) +
|
||||
(metrics.playerManaRatio <= 0.3 ? 6 : 0)
|
||||
);
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@@ -14,7 +14,8 @@ export const BATTLE_USE_SKILL_FUNCTION: FunctionDocumentationEntry = {
|
||||
summary: '后端单行为战斗模型中的指定技能释放 function。',
|
||||
detailedDescription:
|
||||
'这个 functionId 可以对应多个技能 option 实例。前端只展示技能名和不可用原因,后端根据 runtimePayload.skillId 校验蓝量、冷却并结算本次技能效果。',
|
||||
trigger: '仅在 battle 状态下由后端按角色技能列表生成,可能携带 disabled 状态。',
|
||||
trigger:
|
||||
'仅在 battle 状态下由后端按角色技能列表生成,可能携带 disabled 状态。',
|
||||
execution:
|
||||
'前端透传 runtimePayload.skillId,Rust 后端经 story battle facade 调用 module-combat 校验技能并完成一次技能动作结算。',
|
||||
result:
|
||||
@@ -27,9 +28,9 @@ export const BATTLE_USE_SKILL_FUNCTION: FunctionDocumentationEntry = {
|
||||
uiMode: 'none',
|
||||
executor:
|
||||
'server-rs/crates/module-combat/src/lib.rs -> resolve_combat_action',
|
||||
animationNote: '根据技能 option 播放一次技能演出,不在本 function 内追加多回合动作。',
|
||||
storyNote:
|
||||
'战斗未结束时使用本次技能结算文本;只有战斗结束才请求新剧情。',
|
||||
animationNote:
|
||||
'根据技能 option 播放一次技能演出,不在本 function 内追加多回合动作。',
|
||||
storyNote: '战斗未结束时使用本次技能结算文本;只有战斗结束才请求新剧情。',
|
||||
uiNote: '每个技能是一个后端下发的独立 option,必须携带 skillId。',
|
||||
compactDetailText: '释放一个指定技能',
|
||||
},
|
||||
|
||||
@@ -64,4 +64,3 @@ export const IDLE_CALL_OUT_FUNCTION_SOURCE: StateFunctionRuntimeSource = {
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -7,69 +7,69 @@ import type { StateFunctionRuntimeSource } from '../types';
|
||||
* 空闲状态下最核心的推进动作。它负责把“继续往前探”从一句泛化文案,
|
||||
* 落成真正会引出下一幕遭遇的运行时 function。
|
||||
*/
|
||||
export const IDLE_EXPLORE_FORWARD_FUNCTION_SOURCE: StateFunctionRuntimeSource = {
|
||||
definition: {
|
||||
id: 'idle_explore_forward',
|
||||
state: 'idle',
|
||||
category: 'idle',
|
||||
text: '继续向前探索',
|
||||
description: '沿当前场景继续深入,很可能立刻撞上新的敌人或危险。',
|
||||
visual: {
|
||||
playerAnimation: AnimationState.RUN,
|
||||
playerMoveMeters: 0.9,
|
||||
playerOffsetY: 0,
|
||||
playerFacing: 'right',
|
||||
scrollWorld: false,
|
||||
export const IDLE_EXPLORE_FORWARD_FUNCTION_SOURCE: StateFunctionRuntimeSource =
|
||||
{
|
||||
definition: {
|
||||
id: 'idle_explore_forward',
|
||||
state: 'idle',
|
||||
category: 'idle',
|
||||
text: '继续向前探索',
|
||||
description: '沿当前场景继续深入,很可能立刻撞上新的敌人或危险。',
|
||||
visual: {
|
||||
playerAnimation: AnimationState.RUN,
|
||||
playerMoveMeters: 0.9,
|
||||
playerOffsetY: 0,
|
||||
playerFacing: 'right',
|
||||
scrollWorld: false,
|
||||
},
|
||||
effect: {
|
||||
sceneShift: 0,
|
||||
enterBattle: true,
|
||||
},
|
||||
},
|
||||
effect: {
|
||||
sceneShift: 0,
|
||||
enterBattle: true,
|
||||
promptDescription:
|
||||
'继续向前推进当前场景,文案可以自然改写,但仍要保持这是往前探索。',
|
||||
documentation: {
|
||||
id: 'idle_explore_forward',
|
||||
domain: 'state',
|
||||
title: '继续向前探索',
|
||||
source: 'src/data/functionCatalog/state/idleExploreForward.ts',
|
||||
summary: '空闲阶段默认的主推进 function。',
|
||||
detailedDescription:
|
||||
'它负责把玩家继续深入当前场景的意图交给运行时,让场景实体池、前探预览和下一幕遭遇有机会真正落地。',
|
||||
trigger: '仅在 idle 状态下参与候选;营地场景会在运行时被额外过滤。',
|
||||
execution:
|
||||
'保持空闲探索态,视觉上推动角色向前,effect 中通过 enterBattle / sceneShift 让下一步遭遇有机会进入前探或战斗链路。',
|
||||
result: '适合在当前场景继续摸深、主动触发新的角色、怪物、宝藏或危险。',
|
||||
state: 'idle',
|
||||
category: 'idle',
|
||||
active: true,
|
||||
},
|
||||
},
|
||||
promptDescription:
|
||||
'继续向前推进当前场景,文案可以自然改写,但仍要保持这是往前探索。',
|
||||
documentation: {
|
||||
id: 'idle_explore_forward',
|
||||
domain: 'state',
|
||||
title: '继续向前探索',
|
||||
source: 'src/data/functionCatalog/state/idleExploreForward.ts',
|
||||
summary: '空闲阶段默认的主推进 function。',
|
||||
detailedDescription:
|
||||
'它负责把玩家继续深入当前场景的意图交给运行时,让场景实体池、前探预览和下一幕遭遇有机会真正落地。',
|
||||
trigger: '仅在 idle 状态下参与候选;营地场景会在运行时被额外过滤。',
|
||||
execution:
|
||||
'保持空闲探索态,视觉上推动角色向前,effect 中通过 enterBattle / sceneShift 让下一步遭遇有机会进入前探或战斗链路。',
|
||||
result: '适合在当前场景继续摸深、主动触发新的角色、怪物、宝藏或危险。',
|
||||
state: 'idle',
|
||||
category: 'idle',
|
||||
active: true,
|
||||
},
|
||||
runtime: {
|
||||
applyDefinitionAdjustments(definition) {
|
||||
return {
|
||||
...definition,
|
||||
text: '继续向前探索',
|
||||
description:
|
||||
'沿着当前场景继续深入,把前路真正探出来,下一刻就可能撞上新的危险或际遇。',
|
||||
};
|
||||
runtime: {
|
||||
applyDefinitionAdjustments(definition) {
|
||||
return {
|
||||
...definition,
|
||||
text: '继续向前探索',
|
||||
description:
|
||||
'沿着当前场景继续深入,把前路真正探出来,下一刻就可能撞上新的危险或际遇。',
|
||||
};
|
||||
},
|
||||
buildSuggestedActionText({ metrics, environment }) {
|
||||
if (metrics.playerHpRatio <= 0.35) {
|
||||
return `按着伤口,沿着${environment.sceneName}继续往深处摸去`;
|
||||
}
|
||||
if (environment.hasForwardScene) {
|
||||
return `顺着${environment.sceneName}的路势,继续朝前方深处探去`;
|
||||
}
|
||||
return `拨开${environment.sceneName}前的遮挡,继续朝更深处探去`;
|
||||
},
|
||||
buildDetailText({ environment }) {
|
||||
return environment.hasForwardScene
|
||||
? `沿着${environment.sceneName}继续往前压过去,真正把前方会遇到的人影、怪物或宝藏探出来。`
|
||||
: `继续深入${environment.sceneName}前方未探明的地带,下一刻就可能撞见新的动静。`;
|
||||
},
|
||||
getPriority({ metrics }) {
|
||||
return metrics.playerHpRatio > 0.45 ? 6 : 2;
|
||||
},
|
||||
},
|
||||
buildSuggestedActionText({ metrics, environment }) {
|
||||
if (metrics.playerHpRatio <= 0.35) {
|
||||
return `按着伤口,沿着${environment.sceneName}继续往深处摸去`;
|
||||
}
|
||||
if (environment.hasForwardScene) {
|
||||
return `顺着${environment.sceneName}的路势,继续朝前方深处探去`;
|
||||
}
|
||||
return `拨开${environment.sceneName}前的遮挡,继续朝更深处探去`;
|
||||
},
|
||||
buildDetailText({ environment }) {
|
||||
return environment.hasForwardScene
|
||||
? `沿着${environment.sceneName}继续往前压过去,真正把前方会遇到的人影、怪物或宝藏探出来。`
|
||||
: `继续深入${environment.sceneName}前方未探明的地带,下一刻就可能撞见新的动静。`;
|
||||
},
|
||||
getPriority({ metrics }) {
|
||||
return metrics.playerHpRatio > 0.45 ? 6 : 2;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@@ -56,4 +56,3 @@ export const IDLE_FOLLOW_CLUE_FUNCTION_SOURCE: StateFunctionRuntimeSource = {
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -56,4 +56,3 @@ export const IDLE_OBSERVE_SIGNS_FUNCTION_SOURCE: StateFunctionRuntimeSource = {
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -63,4 +63,3 @@ export const IDLE_REST_FOCUS_FUNCTION_SOURCE: StateFunctionRuntimeSource = {
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -7,58 +7,58 @@ import type { StateFunctionRuntimeSource } from '../types';
|
||||
* 空闲状态下的切场景动作。它代表玩家主动离开当前地点,
|
||||
* 进入相邻场景重新开启新的遭遇周期。
|
||||
*/
|
||||
export const IDLE_TRAVEL_NEXT_SCENE_FUNCTION_SOURCE: StateFunctionRuntimeSource = {
|
||||
definition: {
|
||||
id: 'idle_travel_next_scene',
|
||||
state: 'idle',
|
||||
category: 'idle',
|
||||
text: '前往其他场景',
|
||||
description: '离开当前场景,进入下一处地点,并在那里重新遭遇新的威胁。',
|
||||
visual: {
|
||||
playerAnimation: AnimationState.RUN,
|
||||
playerMoveMeters: 1.1,
|
||||
playerOffsetY: 0,
|
||||
playerFacing: 'right',
|
||||
scrollWorld: false,
|
||||
export const IDLE_TRAVEL_NEXT_SCENE_FUNCTION_SOURCE: StateFunctionRuntimeSource =
|
||||
{
|
||||
definition: {
|
||||
id: 'idle_travel_next_scene',
|
||||
state: 'idle',
|
||||
category: 'idle',
|
||||
text: '前往其他场景',
|
||||
description: '离开当前场景,进入下一处地点,并在那里重新遭遇新的威胁。',
|
||||
visual: {
|
||||
playerAnimation: AnimationState.RUN,
|
||||
playerMoveMeters: 1.1,
|
||||
playerOffsetY: 0,
|
||||
playerFacing: 'right',
|
||||
scrollWorld: false,
|
||||
},
|
||||
effect: {
|
||||
sceneShift: 1,
|
||||
enterBattle: true,
|
||||
},
|
||||
},
|
||||
effect: {
|
||||
sceneShift: 1,
|
||||
enterBattle: true,
|
||||
promptDescription:
|
||||
'离开当前场景并前往下一个场景,文案可以自然改写,但仍要保持这是切换场景。',
|
||||
documentation: {
|
||||
id: 'idle_travel_next_scene',
|
||||
domain: 'state',
|
||||
title: '前往其他场景',
|
||||
source: 'src/data/functionCatalog/state/idleTravelNextScene.ts',
|
||||
summary: '空闲阶段的地图流转 function。',
|
||||
detailedDescription:
|
||||
'当玩家不再想在当前场景深挖,而是希望切换地形、敌人池和环境压力时,这个 function 负责驱动合法的场景迁移。',
|
||||
trigger: '仅在 idle 状态下参与候选。',
|
||||
execution:
|
||||
'视觉上继续向前奔跑,effect 里通过 sceneShift: 1 把结果导向相邻场景,并允许新的遭遇在新场景刷新。',
|
||||
result: '适合主动换图、回避当前区域、或推进地图探索节奏时使用。',
|
||||
state: 'idle',
|
||||
category: 'idle',
|
||||
active: true,
|
||||
},
|
||||
},
|
||||
promptDescription:
|
||||
'离开当前场景并前往下一个场景,文案可以自然改写,但仍要保持这是切换场景。',
|
||||
documentation: {
|
||||
id: 'idle_travel_next_scene',
|
||||
domain: 'state',
|
||||
title: '前往其他场景',
|
||||
source: 'src/data/functionCatalog/state/idleTravelNextScene.ts',
|
||||
summary: '空闲阶段的地图流转 function。',
|
||||
detailedDescription:
|
||||
'当玩家不再想在当前场景深挖,而是希望切换地形、敌人池和环境压力时,这个 function 负责驱动合法的场景迁移。',
|
||||
trigger: '仅在 idle 状态下参与候选。',
|
||||
execution:
|
||||
'视觉上继续向前奔跑,effect 里通过 sceneShift: 1 把结果导向相邻场景,并允许新的遭遇在新场景刷新。',
|
||||
result: '适合主动换图、回避当前区域、或推进地图探索节奏时使用。',
|
||||
state: 'idle',
|
||||
category: 'idle',
|
||||
active: true,
|
||||
},
|
||||
runtime: {
|
||||
buildSuggestedActionText({ environment }) {
|
||||
return environment.travelSceneName
|
||||
? `前往${environment.travelSceneName}`
|
||||
: '前往其他场景';
|
||||
runtime: {
|
||||
buildSuggestedActionText({ environment }) {
|
||||
return environment.travelSceneName
|
||||
? `前往${environment.travelSceneName}`
|
||||
: '前往其他场景';
|
||||
},
|
||||
buildDetailText({ environment }) {
|
||||
return (
|
||||
environment.travelSceneDescription ??
|
||||
'离开当前区域,前往相邻场景继续冒险。'
|
||||
);
|
||||
},
|
||||
getPriority({ metrics }) {
|
||||
return metrics.playerHpRatio > 0.45 ? 5 : 3;
|
||||
},
|
||||
},
|
||||
buildDetailText({ environment }) {
|
||||
return (
|
||||
environment.travelSceneDescription ??
|
||||
'离开当前区域,前往相邻场景继续冒险。'
|
||||
);
|
||||
},
|
||||
getPriority({ metrics }) {
|
||||
return metrics.playerHpRatio > 0.45 ? 5 : 3;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user