Files
EVEngine/docs/usr/modules/combat.md
T

62 lines
4.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Combat
Combat 模块提供不依赖具体角色类的伤害、韧性、战斗属性、标准 Ability 原型与移动适配。游戏仍负责角色
实体、动画和输入映射;模块不会创建通用 Actor 根类。
脚本入口 `eve.Combat()` 提供 `getName`,并可通过 `newRuntime()` 创建一个 Squirrel-owned
`CombatRuntime`。`registerFighter`、
`setMoveIntent`、`navigateTo`、`stop`、`advance`、`applyDamage`、`applyTimelineDamage` 和 `state`
全部返回统一 Result 投影;`applyTimelineDamage` 直接消费 Montage runtime event 的 payload JSON,并复用
`ActionDamageBinding` 校验,不会在示例脚本中复制伤害字段解析规则。
runtime 内部复用下述 C++ 权威实现,不在脚本层复制生命值或移动状态。runtime 随脚本对象 GC 销毁,
`ownership()` 返回 `owned`。
同一个 runtime 还内建并注册 `standardCombatAbilities()` 的 20 个定义。`grantAbility`、
`activateAbility`、`advanceAbilities`、`cancelAbility`、`abilityGrant` 和 `matchingAbilities` 直接投影
`AbilityRuntime`;冷却与 Action phase 只使用调用者注入的 tick/delta,不读取墙钟。`advanceAbilities`
推进所有活跃 execution、递减冷却并同步终态链接,脚本不应另外保存 active/cooldown 状态。
`registerTimelineAbility` 接收 `ActionTimelineEditor.snapshotJson()` 的规范 schema,将 timeline 的 actionId、
总时长和 physical split 映射为同一个 `ActionDefinition` 的 phase timing;同时显式设置 cooldown、
instancing、activation group 和可选 gameplay-event trigger。注册失败不会留下部分 definition。
`replaceTimelineAbility` 使用相同参数事务式热替换已有定义:grant、per-owner instance 与剩余冷却保持不变;
已激活 execution 继续持有提交时的旧快照,下一次激活才读取新的 timeline 与 actionId。
已有 grant 时不能热切换 instancing policy,避免悄悄改变 instance 身份语义。
## 角色移动与导航
`CombatLocomotionRuntime` 以 `SubjectRef` 注册角色,并唯一拥有水平位置、速度、朝向、移动意图和导航目标:
```cpp
DirectCombatNavigationProvider navigation;
CombatLocomotionRuntime locomotion(navigation);
locomotion.registerSubject({fighter, "fighter:player", {0.0, 0.0}, 5.0, 18.0});
locomotion.setMoveIntent(fighter, {1.0, 0.0}, 1.0);
locomotion.advance({tick, fixedDelta});
```
方向不要求预先归一化,速度比例必须位于 `[0,1]`。玩家或 AI 的直接移动会清除该角色旧导航目标;
`navigateTo` 则要求安装 `ICombatNavigationProvider`。内置 `DirectCombatNavigationProvider` 适合无障碍 arena。
启用 2D/3D profile 时,可选 `combat_navigation` 卫星提供 `PathfinderCombatNavigationProvider`:
```cpp
map::Pathfinder pathfinder(width, height);
auto navigation = combat::navigation::PathfinderCombatNavigationProvider::create(
pathfinder, {{worldOriginX, worldOriginZ}, cellSize});
CombatLocomotionRuntime locomotion(*navigation.value());
```
它把世界 X/Z 投影到地图格,每步调用 canonical `Pathfinder` 取得下一 waypoint;不会缓存 Path,因此地图阻挡、
TileLayer revision 或代价改变会在下一步重新规划。不可达目标返回 `NotFound`,并由 locomotion 的整帧事务语义保证
所有角色都不发生部分移动。`Pathfinder` 必须比 provider 活得更久。
整帧更新具有原子语义:运行时先复制全部状态,再依次取得导航 steering、限制加速度并积分,全部成功后才
发布。Provider 失败、返回非有限值或非法比例时,没有任何角色移动。Provider 是借用对象,必须比运行时活得
更久,或者在销毁前调用 `clearNavigationProvider`;若清除时仍有活动目标,后续 `advance` 会明确失败,目标不会
被悄悄丢弃。到达目标会返回 owning `CombatLocomotionEventKind::Arrived` 事件。
## 组合边界
移动状态应由表现层投射到 Scene/Physics,由 Ability Active 阶段决定冲刺、闪避等动作何时写入移动意图。
Ability 生命周期仍由 `AbilityRuntime`/`ActionRuntime` 唯一拥有,伤害仍通过 `DamageRuntime` 或
`CombatActionDamageSink` 提交;不要在角色 Controller 中复制冷却、动作阶段或生命值。