if/docs/map-turn-implementation-status.md

14 KiB
Raw Blame History

地图回合实现进度(台账)

本文档记录代码已落地内容待接线任务,便于在对话上下文变长时单独查阅。规则、伪代码与冻结优先级以 map-turn-spec.md 为唯一口径;本文不写新规则,只写状态与文件指针。patch / rebuild / performEnemyAction 等与实现对齐的契约说明见规范 §6.2、§6.3、§6.7


1. 已完成(截至当前仓库)

1.1 数据表(timeCost 默认 null

区域 说明
project/items.js 每条道具在 "cls" 下一行含 "timeCost": null;需消耗地图时间时改为正整数。样例(已接)bigKeytoolstimeCost: 3,见 §1.3。
project/enemys.js 每条怪物在 pointspecial 之间"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(含 eval useItemEffect、并入队 useItemEvent之后立即结算:若 typeof timeCost === "number"> 0,且存在 core.plugin.mapTurn.consumeTime,则 consumeTime(_tc, "item:" + itemId)(如 item:bigKey → 3 tick例外clsskillbattle / skillupdate,或 mapTurnSkillRolebattle / update走本条即时扣时(与规范 §3.1 对齐;工程上可用 cls:"tools" + mapTurnSkillRole 代替未注册的 skill cls地图时间语义见 §1.4 / map-turn-spec.md §3.1。null 或非正数不推进;与异步开门动画无关(规范 §4 tools。总开关关则 consumeTime 内早退。

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):已挂载;特殊 29【庇护】测试hasSpecial(..., 29) 时本层所有怪 enemyOnPoint.hp += 1,不经改图块;否则初版 actType === idle 无操作;chase/patrol/skill 占位(同步改图块会经引擎 removeBlock 触发全表扫描,故不在此 tick 内实现)。
  • rebuildActiveEnemies(floorId):对该层 extractBlocks 一次 后遍历 map.blocks,收录 clsenemy 开头enemys[id].timeCost 为正数 的实例(runtimeId / x / y / enemyId / def),写回 activeEnemiesByFloor[floorId]activeEnemiesVersion++,并修剪 enemyActionGauge[floorId]。换层由 project/plugins.jsafterChangeFloor 的包装调用。
  • patchActiveEnemiesForBlockChange(floorId, hint)hint.opremoveCell / syncCell / migratePoint / rebuild(默认全量 rebuildActiveEnemies)。已在 maps.removeBlock / setBlock / hideBlock / showBlock / removeBlockByIndexesevents.moveEnemyOnPoint 挂钩;moveBlock / jumpBlock 用深度计数抑制中途 removeBlock/setBlock 的重复同步,keep===false 结束时补 removeCell 起点格;migratePointmoveEnemyOnPoint 后迁移 runtimeIdenemyActionGauge
  • 战后成功路径(同文件内 「序章追击」 等对 events.prototype.afterBattle 的包装):先调用原 afterBattle;若勇士仍存活且存在 mapTurn,则 consumeTime(settleBattleTimeCost(), "battle"),再 applyStatusAfterBattle("success")
  • settleBattleTimeCost:返回 max(1, M)§6.4)。M = activeStatusSkills 各条 battleTimeCost 中的最大值,与 activeBattleSkillId 对应道具在 cls === "skillbattle"mapTurnSkillRole === "battle" 时的 timeCost 取较大(二者仅取一层 max再与基础 1 取 max
  • syncBattleSkillItemState / resyncBattleSkillItemStates:战斗技能道具与 flag:skillactiveBattleSkillId 对齐(约定 skillN 型 iduseItem 末尾与读档 bootstrapPersistedStateresync 调用。migrateSkillItemBuckets:读档开头将 constants 或旧 skillbattle/skillremote/skillrecover/skillupdate 桶中、但 material 已改为 cls:"tools" 且带 mapTurnSkillRole 的条目迁入 tools;仍保留从 constants 迁往 skill* 桶的旧逻辑以兼容旧表。
  • applyStatusAfterBattle§6.5,按 remainBattles 等扣减 activeStatusSkills战后成功路径已调用)。
  • clearOnDeath§6.6 清理 skillState 等逻辑已实现;调用侧仍缺:需在 lose / 战斗失败 出口调用(当前仓库未接,见 §3
  • 道具栏libs/ui.js getToolboxItems("tools")getToolboxPermanentItemsconstants + 四类技能 cls)分两行;地图回合技能线若暂用 cls:"tools",走 消耗道具行 显示(与 bigKey 同区)。

1.5 编辑器 / 新素材注册

文件 说明
_server/table/comment.js 道具表、怪物表 timeCost 列说明;items_template / enemys_templatetimeCost: null。道具 cls 可选 skillbattle / skillremote / skillrecover / skillupdate(与 map-turn-spec.md §3.1 一致)。工程临时:未在编辑器注册 skill cls 时,可用 cls:"tools" + mapTurnSkillRolebattle/remote/recover/update+ mapTurnKeepAfterUse: true(使用后不占消耗、addItem 上限 1),与 libs/items.js useItem / _afterUseItem 对齐。

1.6 当前接线口径补充2026-04

  • 总开关开启时机:已在 project/data.jsstartText 前两条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)。下表 §2 为大块任务勾选;细项与「仍缺」见 §2.1§3

  • resolveEnemyActionsForSingleTick:已在 project/plugins.js mapTurn 中实现 §2 该条所列 14 步(含 performEnemyActionidle 已实现,其余 actType 占位)。

  • rebuildActiveEnemies:已在 mapTurn.rebuildActiveEnemies 实现 §2 该条 14 步;afterChangeFloor 中已调用 rebuildActiveEnemies(core.status.floorId || floorId)

  • patchActiveEnemiesForBlockChange:已在 mapTurn.patchActiveEnemiesForBlockChange 实现 removeCell / syncCell / migratePoint / rebuildproject/plugins.jsmapTurn 插件末尾对 core.maps / core.events 安装挂钩(含 moveBlock/jumpBlockkeep===false 补清)。

2.1 后续扩展接线备忘

对应 map-turn-spec.md 中已有字段或流程的操作指向;已接与仍缺分列如下

已接(当前仓库)

  • 战斗技能(skillbattlemapTurnSkillRole:"battle":样例 skill1project/items.js,当前 cls:"tools" + mapTurnSkillRole:"battle" + mapTurnKeepAfterUsetimeCost: 3id skill1flag:skill === 1libs/items.js useItembattle/update 角色跳过即时 consumeTime;战后 settleBattleTimeCostsyncBattleSkillItemState / resyncBattleSkillItemStatesmigrateSkillItemBuckets§1.4道具栏tools§1.4)。
  • bigKey tools + timeCost: 3§1.3 即时 consumeTime(已验证)。

仍待扩展

  • skillremote / skillrecover / skillupdate(规范 cls:编辑器注册与 activeStatusSkills 战后路径仍可按规范扩展;仓库内示例 I347/I348/I350 已用 tools + mapTurnSkillRole 实现拾取/使用时轴与道具栏(I350 仍为 mapTestAtkLayers + tick 衰减,非 activeStatusSkills)。
  • contactBattleOnly 与多怪捕捉:在战斗触发逻辑(如 beforeBattle 或等价入口)读取怪物字段分支;多怪连续战斗时每场成功需调用 applyStatusAfterBattle("success")(普通单场已接,见 §1.4 战后路径)。
  • actType / actArgs:在 performEnemyAction(或由 resolveEnemyActionsForSingleTick 内联)按怪物表字段分支执行移动/技能等行为(chase/patrol/skill 等仍占位§1.4)。

3. 验收清单映射(对应 map-turn-spec §10

§10 条目 依赖 / 当前状态(台账口径)
状态技能不立即推进时间;战后层数 -1 applyStatusAfterBattle 已在单场战后成功路径调用§1.4)。规范路径仍缺cls:"skillupdate" 写入 activeStatusSkills(含 remainBattles / battleTimeCost)的配置与开关脚本。I350 为测试向 mapTestAtkLayers + tick 衰减,不覆盖 activeStatusSkills 验收。
远程/恢复立即推进;怪物按时间响应 useItemremote/recover 角色(或规范 skillremote/skillrecover)与普通 tools 一样按正数 timeCost consumeTime§1.3)。示例 I347/I348§2.1)。敌调度resolveEnemyActionsForSingleTick + activeEnemies 已实装§1.4)。
战斗耗时 max afterBattle 成功路径已 consumeTime(settleBattleTimeCost(), "battle")§1.4);含 skill1battle 角色)与 activeStatusSkills。回归:全场战斗均走该 afterBattle 包装即可确认。
多怪捕捉逐场扣层 单场 afterBattle 已链 applyStatusAfterBattle仍缺:多怪连战的 afterBattle 触发次数 / 事件链是否每场独立成功分支(见 §2.1)。
Boss contactBattleOnly 仍缺:战斗触发层读取 contactBattleOnly 与单场结算分支§2.1)。
死亡清理 clearOnDeath 已实现;仍缺:在 events.lose 或等价失败出口调用§1.4)。
存档读档连续 flags.mapTurnState / skillState 等随档;读档后 bootstrapPersistedState + afterChangeFloorrebuildActiveEnemies§1.6)。
timeCost=0 不参与调度 rebuildActiveEnemies 仅收录 timeCost > 0resolveEnemyActionsForSingleTick 只扫缓存列表§1.4)。
consumeTime(3) 恰好 3 tick consumeTime 内循环 advanceMapTurnOne 已实现;建议:对 bigKey 或脚本 consumeTime(3) 做日志/计数断言回归§1.3)。
activeEnemies 路径无每 tick 全图扫描 resolveEnemyActionsForSingleTickextractBlocks;地图变更走 patch/rebuild§1.4)。例外庇护 29 每次行动 extractBlocks 一次测试专用§1.4)。

4. 相关路径速查

用途 路径
规范全文 docs/map-turn-spec.md
样板 API _docs/api.md
地图回合插件 project/plugins.js 搜索 "mapTurn"