Files

4.2 KiB
Raw Permalink Blame History

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 注册角色,并唯一拥有水平位置、速度、朝向、移动意图和导航目标:

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:

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 中复制冷却、动作阶段或生命值。