107 lines
9.2 KiB
Markdown
107 lines
9.2 KiB
Markdown
# 地图回合实现进度(台账)
|
||
|
||
本文档记录**代码已落地内容**与**待接线任务**,便于在对话上下文变长时单独查阅。规则、伪代码与冻结优先级以 [map-turn-spec.md](map-turn-spec.md) 为唯一口径;本文不写新规则,只写状态与文件指针。**`patch` / `rebuild` / `performEnemyAction` 等与实现对齐的契约说明**见规范 **§6.2、§6.3、§6.7**。
|
||
|
||
---
|
||
|
||
## 1. 已完成(截至当前仓库)
|
||
|
||
### 1.1 数据表(`timeCost` 默认 `null`)
|
||
|
||
| 区域 | 说明 |
|
||
|------|------|
|
||
| [project/items.js](../project/items.js) | 每条道具在 `"cls"` 下一行含 **`"timeCost": null`**;需消耗地图时间时改为正整数。 |
|
||
| [project/enemys.js](../project/enemys.js) | 每条怪物在 **`point` 与 `special` 之间**含 **`"timeCost": null`**。 |
|
||
| `enemy48` | 与 `enemys` 共用 **`core.material.enemys`** 数值,**无**独立 `libs/enemys48.js` 数据表。 |
|
||
|
||
### 1.2 引擎初始化缺省补全
|
||
|
||
| 文件 | 行为 |
|
||
|------|------|
|
||
| [libs/items.js](../libs/items.js) `items.prototype._init` | 若道具 **`timeCost === undefined`**,补 **`timeCost: null`**(含编辑器新注册道具漏字段)。 |
|
||
| [libs/enemys.js](../libs/enemys.js) `enemys.prototype._init` | 若怪物 **`timeCost === undefined`**,补 **`timeCost: null`**。 |
|
||
|
||
### 1.3 使用道具推进地图时间
|
||
|
||
| 文件 | 行为 |
|
||
|------|------|
|
||
| [libs/items.js](../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](../project/plugins.js) 插件键 **`"mapTurn"`** | 挂载 **`this.mapTurn = { ... }`**,对外即 **`core.plugin.mapTurn.*`**。 |
|
||
|
||
已实现的 API(名称与 [map-turn-spec.md](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](../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 编辑器 / 新素材注册
|
||
|
||
| 文件 | 说明 |
|
||
|------|------|
|
||
| [_server/table/comment.js](../_server/table/comment.js) | 道具表、怪物表增加 **`timeCost`** 列说明;**`items_template`** / **`enemys_template`** 含 **`timeCost: null`**,新建行时带该字段。 |
|
||
|
||
### 1.6 当前接线口径补充(2026-04)
|
||
|
||
- **总开关开启时机**:已在 [project/data.js](../project/data.js) 的 **`startText` 前两条**:**`setValue`** 写入 **`flag:mapTurnEnabled`** 为真,再 **`bootstrapPersistedState()`** 补齐结构。开关存于存档,读档后随存档恢复。
|
||
- **首次触发路径约束**:新开局统一经过 `startText` 写入总开关;读档后由 [project/functions.js](../project/functions.js) **`loadData`** 调用 **`bootstrapPersistedState()`** 与存档中的 **`mapTurnEnabled`** 对齐。
|
||
- **演出移动与地图回合**:事件编辑器「地图处理」中在「无视地形移动勇士」下增加图块 **「移动勇者」**(JSON `type`: **`moveHeroMapTurn`**)。运行时由 [libs/events.js](../libs/events.js) **`_action_moveHeroMapTurn`** 将路径拆成每格一次 `eventMoveHero`,每格落点后 **`consumeTime(1, "event:moveHeroMapTurn")`**(`speed:` 与 `:0` 段不扣时)。语法见 [_server/MotaAction.g4](../_server/MotaAction.g4) `moveHeroMapTurn_s`。
|
||
- **分层相对回合约定**:`mapTurn` 以楼层相对值使用;**普通切层**后当前层回合计数按 `0` 起算。**读档**导致的换层(`__fromLoad__` 为真)不归零,以保持与存档一致。`clock` 可继续作为全局累计观测值。
|
||
|
||
---
|
||
|
||
## 2. 待完成(接线清单,对齐 map-turn-spec §4 / §6 / §8)
|
||
|
||
已完成接线见 **§1**(含 §1.4、§1.6)。以下为尚未实现的步骤说明;完成后在 §3 验收表对应行打勾。
|
||
|
||
- [x] **`resolveEnemyActionsForSingleTick`**:已在 [project/plugins.js](../project/plugins.js) **`mapTurn`** 中实现 §2 该条所列 1–4 步(含 **`performEnemyAction`**,`idle` 已实现,其余 `actType` 占位)。
|
||
|
||
- [x] **`rebuildActiveEnemies`**:已在 **`mapTurn.rebuildActiveEnemies`** 实现 §2 该条 1–4 步;**`afterChangeFloor`** 中已调用 **`rebuildActiveEnemies(core.status.floorId || floorId)`**。
|
||
|
||
- [x] **`patchActiveEnemiesForBlockChange`**:已在 **`mapTurn.patchActiveEnemiesForBlockChange`** 实现 **`removeCell` / `syncCell` / `migratePoint` / `rebuild`**;[project/plugins.js](../project/plugins.js) 在 **`mapTurn`** 插件末尾对 **`core.maps`** / **`core.events`** 安装挂钩(含 **`moveBlock`/`jumpBlock`** 与 **`keep===false`** 补清)。
|
||
|
||
### 2.1 后续扩展接线备忘
|
||
|
||
对应 [map-turn-spec.md](map-turn-spec.md) 中已有字段或流程、尚未在工程中专项接线时的操作指向:
|
||
|
||
- **四类技能与 `items`**:在 [project/items.js](../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. 相关路径速查
|
||
|
||
| 用途 | 路径 |
|
||
|------|------|
|
||
| 规范全文 | [docs/map-turn-spec.md](map-turn-spec.md) |
|
||
| 样板 API | [_docs/api.md](../_docs/api.md) |
|
||
| 地图回合插件 | [project/plugins.js](../project/plugins.js) 搜索 **`"mapTurn"`** |
|