地图回合实现进度(台账)
本文档记录代码已落地内容与待接线任务,便于在对话上下文变长时单独查阅。规则、伪代码与冻结优先级以 map-turn-spec.md 为唯一口径;本文不写新规则,只写状态与文件指针。patch / rebuild / performEnemyAction 等与实现对齐的契约说明见规范 §6.2、§6.3、§6.7。
1. 已完成(截至当前仓库)
1.1 数据表(timeCost 默认 null)
| 区域 |
说明 |
| project/items.js |
每条道具在 "cls" 下一行含 "timeCost": null;需消耗地图时间时改为正整数。 |
| project/enemys.js |
每条怪物在 point 与 special 之间含 "timeCost": null。 |
enemy48 |
与 enemys 共用 core.material.enemys 数值,无独立 libs/enemys48.js 数据表。 |
1.2 引擎初始化缺省补全
| 文件 |
行为 |
libs/items.js items.prototype._init |
若道具 timeCost === undefined,补 timeCost: null(含编辑器新注册道具漏字段)。 |
libs/enemys.js enemys.prototype._init |
若怪物 timeCost === undefined,补 timeCost: null。 |
1.3 使用道具推进地图时间
| 文件 |
行为 |
libs/items.js items.prototype.useItem |
在 _useItemEffect 之后:若 typeof timeCost === "number" 且 > 0,且存在 core.plugin.mapTurn.consumeTime,则调用 consumeTime(_tc, "item:" + itemId)。null 或非正数不推进。 |
1.4 插件:core.plugin.mapTurn
| 文件 |
说明 |
project/plugins.js 插件键 "mapTurn" |
挂载 this.mapTurn = { ... },对外即 core.plugin.mapTurn.*。 |
已实现的 API(名称与 map-turn-spec.md §3.4 / §6 对齐):
isEnabled / setEnabled(v):总开关读写 flags.mapTurnEnabled(随存档);为真时 consumeTime / advanceMapTurnOne 才会推进状态。setEnabled(true) 或 bootstrapPersistedState() 在开关为真时会补齐 mapTurnState / skillState 缺省结构。
consumeTime(deltaTime, reason):clock += floor(delta),再循环 deltaTime 次 advanceMapTurnOne(§2.1)。
advanceMapTurnOne(reason):mapTurn += 1,调用 resolveEnemyActionsForSingleTick。
resolveEnemyActionsForSingleTick(reason):已按 §6.2 遍历 activeEnemiesByFloor[currentFloor],维护 enemyActionGauge[floorId][runtimeId],达阈调用 performEnemyAction;本函数路径内不调用 extractBlocks。
performEnemyAction(enemyRef, def, floorId, reason):已挂载;初版 actType === idle 无操作;chase/patrol/skill 占位(同步改图块会经引擎 removeBlock 触发全表扫描,故不在此 tick 内实现)。
rebuildActiveEnemies(floorId):对该层 extractBlocks 一次 后遍历 map.blocks,收录 cls 以 enemy 开头 且 enemys[id].timeCost 为正数 的实例(runtimeId / x / y / enemyId / def),写回 activeEnemiesByFloor[floorId],activeEnemiesVersion++,并修剪 enemyActionGauge[floorId]。换层由 project/plugins.js 对 afterChangeFloor 的包装调用。
patchActiveEnemiesForBlockChange(floorId, hint):hint.op 为 removeCell / syncCell / migratePoint / rebuild(默认全量 rebuildActiveEnemies)。已在 maps.removeBlock / setBlock / hideBlock / showBlock / removeBlockByIndexes 与 events.moveEnemyOnPoint 挂钩;moveBlock / jumpBlock 用深度计数抑制中途 removeBlock/setBlock 的重复同步,keep===false 结束时补 removeCell 起点格;migratePoint 在 moveEnemyOnPoint 后迁移 runtimeId 与 enemyActionGauge。
settleBattleTimeCost:已实现 max(1, 状态技能 battleTimeCost 最大值)(§6.4)。
applyStatusAfterBattle / clearOnDeath:已按规范 §6.5–6.6 操作 flags.skillState(经 core.getFlag / core.setFlag 维护的 mapTurnState / skillState 结构)。
1.5 编辑器 / 新素材注册
1.6 当前接线口径补充(2026-04)
- 总开关开启时机:已在 project/data.js 的
startText 前两条:setValue 写入 flag:mapTurnEnabled 为真,再 bootstrapPersistedState() 补齐结构。开关存于存档,读档后随存档恢复。
- 首次触发路径约束:新开局统一经过
startText 写入总开关;读档后由 project/functions.js loadData 调用 bootstrapPersistedState() 与存档中的 mapTurnEnabled 对齐。
- 演出移动与地图回合:事件编辑器「地图处理」中在「无视地形移动勇士」下增加图块 「移动勇者」(JSON
type: moveHeroMapTurn)。运行时由 libs/events.js _action_moveHeroMapTurn 将路径拆成每格一次 eventMoveHero,每格落点后 consumeTime(1, "event:moveHeroMapTurn")(speed: 与 :0 段不扣时)。语法见 _server/MotaAction.g4 moveHeroMapTurn_s。
- 分层相对回合约定:
mapTurn 以楼层相对值使用;普通切层后当前层回合计数按 0 起算。读档导致的换层(__fromLoad__ 为真)不归零,以保持与存档一致。clock 可继续作为全局累计观测值。
2. 待完成(接线清单,对齐 map-turn-spec §4 / §6 / §8)
已完成接线见 §1(含 §1.4、§1.6)。以下为尚未实现的步骤说明;完成后在 §3 验收表对应行打勾。
2.1 后续扩展接线备忘
对应 map-turn-spec.md 中已有字段或流程、尚未在工程中专项接线时的操作指向:
- 四类技能与
items:在 project/items.js 为道具补 skillType / timeCost 等后,在道具使用效果与 flags.skillState 写入处接线;状态技能保持 timeCost === 0 且不调用 consumeTime;战斗耗时仍走 settleBattleTimeCost 与战后 applyStatusAfterBattle 调用链。
contactBattleOnly 与多怪捕捉:在战斗触发逻辑(如 beforeBattle 或等价入口)读取怪物字段分支;多怪连续战斗时每场成功后调用 applyStatusAfterBattle("success")。
actType / actArgs:在 performEnemyAction(或由 resolveEnemyActionsForSingleTick 内联)按怪物表字段分支执行移动/技能等行为。
3. 验收清单映射(对应 map-turn-spec §10)
| §10 条目 |
依赖的待办小节 |
状态技能不立即推进时间;战后层数 -1 |
战斗胜利接线 + skillState 数据与 applyStatusAfterBattle 调用时机 |
| 远程/恢复立即推进;怪物按时间响应 |
道具 timeCost(已有 useItem 钩子)+ resolveEnemyActions / activeEnemies 实装 |
战斗耗时 max |
settleBattleTimeCost 已在插件中;需战斗路径实际调用 |
| 多怪捕捉逐场扣层 |
afterBattle 多场链路与每场成功分支 |
Boss contactBattleOnly |
战斗触发层逻辑 + 怪物字段 |
| 死亡清理 |
clearOnDeath 接入 lose / 失败 |
| 存档读档连续 |
flags 持久化已有方向;读档后 rebuildActiveEnemies |
timeCost=0 不参与调度 |
rebuildActiveEnemies 过滤 + resolveEnemyActions 只扫缓存 |
consumeTime(3) 恰好 3 tick |
consumeTime 已实现循环;需集成测试断言 |
activeEnemies 路径无每 tick 全图扫描 |
rebuild / patch 实装 |
4. 相关路径速查