From f35ca20b6772a0c700602f3b7df25256988668c4 Mon Sep 17 00:00:00 2001 From: unanmed <1319491857@qq.com> Date: Sun, 11 Oct 2026 16:34:38 +0800 Subject: [PATCH] docs(09-11): author legacy interface audit section C + summary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 补齐 09-LEGACY-INTERFACES-AUDIT.md 的 C 节(core.* 调用点:去重成员 67 + 228 条 file:line + 每文件计数)与汇总表 - C-COUNT: 228;写入 09-11-SUMMARY.md(A/B/C 计数、OI-1..OI-5 裁定、只读确认) - 全程只读:两包(client-base/client-modules)源码零改动 --- .../09-11-SUMMARY.md | 167 +++++++ .../09-LEGACY-INTERFACES-AUDIT.md | 437 +++++++++++++++++- 2 files changed, 603 insertions(+), 1 deletion(-) create mode 100644 .planning/phases/09-minimum-browser-runnable/09-11-SUMMARY.md diff --git a/.planning/phases/09-minimum-browser-runnable/09-11-SUMMARY.md b/.planning/phases/09-minimum-browser-runnable/09-11-SUMMARY.md new file mode 100644 index 0000000..8417ec9 --- /dev/null +++ b/.planning/phases/09-minimum-browser-runnable/09-11-SUMMARY.md @@ -0,0 +1,167 @@ +--- +phase: 09-minimum-browser-runnable +plan: 11 +subsystem: docs +tags: [legacy, core, deprecated, audit, read-only, ast, tsx, client-base, client-modules] + +# Dependency graph +requires: + - phase: 09-minimum-browser-runnable + provides: "任务 5 · legacy 接口只读统计的范围界定(D-42..D-45)与既有两包源码现状" +provides: + - ".planning/phases/09-minimum-browser-runnable/09-LEGACY-INTERFACES-AUDIT.md —— 只读统计台账(§0 口径 + A 残余 legacy 接口 + B @deprecated + C core.* 调用点 + 汇总)" + - "A-COUNT=32 / B-COUNT=0 / C-COUNT=228(去重成员 M=67,覆盖 29 文件)" +affects: [09, legacy-migration, render-ui] + +# Actuals (#2632) — pairs with the plan's `estimate` to calibrate future estimates. +# Same estimateTokens scale (chars/4 over the realized diff), never a harness token count. +actuals: + tokens: 12795 + tasks: 3 + commits: 2 + +# Tech tracking +tech-stack: + added: [] + patterns: + - "代码级 core. 统计用 TypeScript 编译器 API(createSourceFile + AST PropertyAccessExpression 首成员),天然排除注释 / 字符串 / 模板字面量" + - "只读审计:唯一写入为统计文档 + SUMMARY,源码零改动(scope 守卫)" + +key-files: + created: + - .planning/phases/09-minimum-browser-runnable/09-LEGACY-INTERFACES-AUDIT.md + - .planning/phases/09-minimum-browser-runnable/09-11-SUMMARY.md + modified: [] + +key-decisions: + - "Task 0(blocking-human)已闭环:用户回复「可以执行」并批准产出路径 09-LEGACY-INTERFACES-AUDIT.md(采纳默认处置 OI-1..OI-5)" + - "OI-2:分类口径 A-1..A-7 按默认采用(跨包依赖 / 全局 core / 单例 client / patch 机制 / UI 运行时符号 / Mota 全局 / 回退层)" + - "OI-3:两包内未检索到 data-fallback 同名符号;据默认归 A-7(fallback/** 及 Mota.require('@user/data-base'))" + - "OI-4:B 类实测 0 条,显式报告「0 条」并写明扫描范围与匹配方式" + - "OI-5:C 类给出「去重成员清单 + 按文件 file:line 调用点 + 每文件计数」三者,并另给去重成员数 M=67" + - "C-COUNT=228 = 代码级 core. 访问点总条数(AST 精确识别);B-COUNT=0;A-COUNT=32 = A-1..A-7 各表行数之和" + - "任务 2 的门禁 READONLY 断言对全 packages-user 过宽,改为对两在范围内包(client-base / client-modules)的等价 scope 守卫" + +patterns-established: + - "只读审计口径:范围显式化(两包)、分类口径显式化(A-1..A-7)、每条 file:line 锚点须指向真实文件且在范围内(反臆造门禁)" + +requirements-completed: [] + +# Coverage metadata (#1602) +coverage: + - id: D1 + description: "只读统计文档 09-LEGACY-INTERFACES-AUDIT.md(§0 口径 + A 残余 legacy 接口 + B @deprecated + C core.* 调用点 + 汇总 + A/B/C 机器可读计数)" + verification: [] + human_judgment: true + rationale: "纯文档产物,无自动化测试;其正确性(口径合理性、条目不臆造、锚点有效)需人工复核" + +# Metrics +duration: ~30min +completed: 2026-10-11 +status: complete +--- + +# Phase 9 Plan 11: legacy 接口只读统计 Summary + +**产出只读统计台账 `09-LEGACY-INTERFACES-AUDIT.md`:在 `packages-user/client-base` 与 `packages-user/client-modules` 两包内枚举 A 残余 legacy 接口 32 条(A-1..A-7)、B `@deprecated` 0 条(显式报告)、C 代码级 `core.*` 调用点 228 条(去重成员 67 个、覆盖 29 文件),全程只读、源码零改动** + +## Performance + +- **Duration:** ~30 min(含 Task 0 汇报关卡) +- **Completed:** 2026-10-11 +- **Tasks:** 3(Task 0 汇报关卡 + Task 1 + Task 2) +- **Files modified:** 2(均为新增 `.md`;源码零改动) + +> **actuals 计量口径:** `tokens: 12795` = (审计文档 43298 + SUMMARY 7881) / 4 = 51179 / 4,即本次实际改动文件的 `chars/4`;计划估算 `52000`(低置信度),实际偏低。源码未改动,故 realized diff 仅含两份 `.md`。 + +## Task 0(预执行汇报关卡 · `blocking-human`) + +- **状态:已闭环(satisfied)。** 用户明确回复「可以执行」并批准产出路径 `.planning/phases/09-minimum-browser-runnable/09-LEGACY-INTERFACES-AUDIT.md`;采纳默认处置 OI-1..OI-5。 +- 关卡未执行任何写操作;未修改任何文件。 +- **预执行状态门禁(计划 Task 0 ``)运行通过:** `OK pre-execution state intact (audit doc absent; both packages present; legacy import + client singleton present)`。 + +## Accomplishments + +- **§0 统计口径与范围:** 显式界定范围(恰好两包、`.ts`/`.tsx`、排除 `node_modules`/`dist`)、`legacy` 判定基准、A-1..A-7 子类定义、扫描方法论(AST)、只读声明与计数粒度。 +- **§A 残余 legacy 接口(A-COUNT: 32):** + - A-1 跨包 legacy 依赖 10 条(`hotkey.ts:3`、`fallback/{audio,ui,weather}.ts`、`ui/{settings,title,toolbar}.tsx` ↔ `@motajs/legacy-ui|common|system`)。 + - A-2 legacy 全局 `core` 声明引用(`src/types/declaration/core.d.ts`,交叉引用 §C)。 + - A-3 legacy 单例 `client` 3 条(定义 `core.ts:6`;使用 `fallback/audio.ts:5,11`;并显式排除 `loader/hook.ts:7` 的**局部** `client`)。 + - A-4 legacy patch 机制 3 条(`new Patch(PatchClass.*)`,含 `.add(...)`)。 + - A-5 legacy UI 运行时符号 7 条(`mainUi`/`mainSetting`/`getVitualKeyOnce`/`triggerFullscreen` 使用点)。 + - A-6 legacy `Mota` 全局 3 条(`elements/{cache.ts:491,misc.ts:89,219}` 的 `Mota.require('@user/data-base')`)。 + - A-7 legacy 兼容 / 回退层 5 个文件(`fallback/**`)。 +- **§B `@deprecated`(B-COUNT: 0):** 两包内实测 0 条,显式报告并写明扫描范围与匹配方式(`@deprecated` 字面量)。 +- **§C 经 `core.*` 调用的接口(C-COUNT: 228):** 去重成员清单 67 个(C-1)、按文件 228 条 `file:line` 调用点(C-2,29 个文件)、每文件计数(C-3)。**仅计代码**——两包 `shared.ts` 注释中的 `core.js` 未计入。 +- **§汇总:** A/B/C 三类汇总表 + 三行机器可读计数 `A-COUNT:` / `B-COUNT:` / `C-COUNT:`。 + +## Task Commits + +Each task was committed atomically: + +1. **Task 1: 文档骨架 + §0 口径 + §A + §B** - `1c5afe4` (docs) +2. **Task 2: §C + 汇总 + SUMMARY** - 见本次提交 (docs) + +**Plan metadata / SUMMARY:** 见 Task 2 提交(**未修改 STATE.md / ROADMAP.md** —— 由 orchestrator 负责)。 + +## Files Created/Modified + +- `.planning/phases/09-minimum-browser-runnable/09-LEGACY-INTERFACES-AUDIT.md`(新增)— 只读统计台账(§0 + A + B + C + 汇总 + 机器可读计数)。 +- `.planning/phases/09-minimum-browser-runnable/09-11-SUMMARY.md`(新增)— 本执行摘要。 + +## Decisions Made + +- 按用户批准的默认处置落地 OI-1..OI-5(见 frontmatter `key-decisions`)。 +- **C 类排除注释 / 字符串:** 使用 TypeScript 6.0.3 AST(`PropertyAccessExpression` 首成员)精确识别,避免把 `shared.ts` 注释中的 `core.js` 误计(用户明确要求)。 +- **A-3 边界:** `loader/hook.ts:7` 的 `client` 为 `loader.getConfig('client')` 局部变量,**非** legacy 单例,已在文档中显式标注排除。 + +## Deviations from Plan + +### Auto-fixed Issues + +**1. [Rule 3 - Blocking] Task 1 / Task 2 的 `READONLY` 守卫对全 `packages-user` 过宽,命中了用户范围内(out-of-scope)的并发改动** +- **Found during:** Task 1 与 Task 2(只读守卫) +- **Issue:** 计划的门禁 `filter(l=>/packages-user\/.*\.(ts|tsx)\s*$/.test(l))` 会匹配**任意** `packages-user` 下的 `.ts`/`.tsx` 改动。本机存在**用户在 `packages-user/data-state/**` 的并发改动**(D-56:` M calculator.ts`、` D legacy.ts`、` M special.ts`),该包按 D-42 **不在统计范围内**,也不是本计划改动的文件。该守卫因此恒为 RED,与「本计划是否触碰源码」无关。 +- **Fix:** 未改动这些用户文件(永不暂存 / 提交)。运行**等价的范围内守卫**——`git status --porcelain -- packages-user/client-base packages-user/client-modules` → **无输出**,证明两个**在统计范围内**的包零改动;源码只读保证成立。 +- **Files modified:** 无(仅执行守卫,未改任何源码 / 计划文件)。 +- **Verification:** 范围内守卫 `OK scoped read-only: client-base + client-modules untouched`;`git status --porcelain` 仅含本计划两份 `.md`(审计文档 / SUMMARY)与用户既有 `data-state` 改动。 +- **Committed in:** 无(守卫本身不产生提交)。 + +--- + +**Total deviations:** 1 auto-fixed (1 blocking,属**计划门禁过宽 + 用户并发改动**的环境性偏差,非源码问题)。 +**Impact on plan:** 无范围外溢。两包内零源码改动;唯一写入为本计划两份 `.md`。是否认定该门禁断言需回改 `09-11-PLAN.md`,请用户裁定(按 AGENTS.md,未擅自记录为「问题」)。 + +## Issues Encountered + +- 无源码层问题。Task 0 预执行门禁与 Task 1/2 的 AUDIT-AB / AUDIT-C 门禁均首次运行即通过。唯一偏差为上述只读守卫过宽(见上)。 + +## Known Stubs + +None — 本计划为纯只读文档产物,未引入任何 stub / 占位 / TODO。 + +## Threat Flags + +None — 未引入任何源码改动;产出仅为 `.planning` 下两份 `.md`,未触及网络端点 / 鉴权路径 / 文件访问或数据模式。 + +## User Setup Required + +None — 无外部服务配置。 + +## Next Phase Readiness + +- 台账已就绪,可作为后续「legacy 移植 / 去 legacy」改造的**只读依据**(每条 `file:line` 锚点均已按执行日实测校验有效)。 +- 待用户裁定:本计划只读守卫「全 packages-user → 两在范围内包」的口径是否需要回改至 `09-11-PLAN.md`(本次未改计划文件)。 +- **未修改 STATE.md 与 ROADMAP.md**(按派发指令,由 orchestrator 负责)。 + +--- + +*Phase: 09-minimum-browser-runnable* +*Completed: 2026-10-11* + +## Self-Check: PASSED + +- FOUND: `.planning/phases/09-minimum-browser-runnable/09-LEGACY-INTERFACES-AUDIT.md` +- FOUND: `.planning/phases/09-minimum-browser-runnable/09-11-SUMMARY.md` +- FOUND: `1c5afe4` (Task 1 commit) +- 未修改 STATE.md / ROADMAP.md(由 orchestrator 负责) diff --git a/.planning/phases/09-minimum-browser-runnable/09-LEGACY-INTERFACES-AUDIT.md b/.planning/phases/09-minimum-browser-runnable/09-LEGACY-INTERFACES-AUDIT.md index a1b243f..c7635ee 100644 --- a/.planning/phases/09-minimum-browser-runnable/09-LEGACY-INTERFACES-AUDIT.md +++ b/.planning/phases/09-minimum-browser-runnable/09-LEGACY-INTERFACES-AUDIT.md @@ -145,4 +145,439 @@ legacy 全局 `core` 的**类型声明**位于 `src/types/declaration/core.d.ts: **B-COUNT: 0** - +## C. 所有经 core.* 调用的接口 + +### C.0 扫描口径 + +- **范围:** 同 §0.1(恰好两包内 `.ts` / `.tsx`,排除 `node_modules` / `dist`)。 +- **匹配:** 用 TypeScript 编译器 API 遍历 AST,收集 `PropertyAccessExpression`(`core.`,取**首成员**,如 `core.status.x` 记 `core.status`)。 +- **排除:** 注释(`//` / `/* */`)与字符串 / 模板字面量——**天然排除**,故两包 `shared.ts` 注释中的 `core.js`(第 11/13、32/34 行)**不计**。 +- **计数:** `C-COUNT` = 全部代码级 `core.` 访问点总条数;另给出去重成员数 M 与覆盖文件数。 + +### C-1 去重成员清单(`core.`,M = 67) + +`core.actions`、`core.arrayToRGBA`、`core.calValue`、`core.chooseReplayFile`、`core.clearLocalForage`、`core.confirmRestart`、`core.control`、`core.debug`、`core.doRegisteredAction`、`core.doSL`、`core.download`、`core.drawThumbnail`、`core.drawTip`、`core.encodeRoute`、`core.extractBlocks`、`core.extractBlocksForUI`、`core.firstData`、`core.flags`、`core.floorIds`、`core.floors`、`core.flyTo`、`core.formatBigNumber`、`core.formatDate2`、`core.getAllSaves`、`core.getAnimateFrames`、`core.getLvName`、`core.getMappedName`、`core.getNextItem`、`core.getSave`、`core.getTilesetOffset`、`core.hasItem`、`core.icons`、`core.isMoving`、`core.isPlaying`、`core.isReplaying`、`core.maps`、`core.material`、`core.openBook`、`core.openEquipbox`、`core.openQuickShop`、`core.openToolbox`、`core.pauseReplay`、`core.platform`、`core.playSound`、`core.removeFlag`、`core.removeLocalForage`、`core.removeLocalStorage`、`core.removeSave`、`core.replaceText`、`core.restart`、`core.resumeReplay`、`core.rewindReplay`、`core.saves`、`core.setFlag`、`core.setLocalForage`、`core.speedDownReplay`、`core.speedUpReplay`、`core.startGame`、`core.status`、`core.stepReplay`、`core.stopReplay`、`core.syncSave`、`core.tilesets`、`core.turnHero`、`core.ui`、`core.useFly`、`core.waitHeroToStop` + +### C-2 按文件调用点(逐条 `file:line`) + +#### packages-user/client-base/src/components/choices.tsx + +| 行 | core. | 上下文 | +| --- | --- | --- | +| packages-user/client-base/src/components/choices.tsx:677 | `core.status` | `const route = core.status.replay.toReplay[0];` | +| packages-user/client-base/src/components/choices.tsx:717 | `core.isReplaying` | `if (core.isReplaying()) {` | +| packages-user/client-base/src/components/choices.tsx:719 | `core.control` | `const timeout = core.control.__replay_getTimeout();` | +| packages-user/client-base/src/components/choices.tsx:720 | `core.status` | `` core.status.route.push(`choices:${confirm ? 0 : 1}`); `` | +| packages-user/client-base/src/components/choices.tsx:721 | `core.status` | `core.status.replay.toReplay.shift();` | +| packages-user/client-base/src/components/choices.tsx:730 | `core.control` | `await sleep(core.control.__replay_getTimeout());` | +| packages-user/client-base/src/components/choices.tsx:735 | `core.status` | `` core.status.route.push(`choices:${confirm ? 0 : 1}`); `` | +| packages-user/client-base/src/components/choices.tsx:772 | `core.isReplaying` | `if (core.isReplaying()) {` | +| packages-user/client-base/src/components/choices.tsx:774 | `core.control` | `const timeout = core.control.__replay_getTimeout();` | +| packages-user/client-base/src/components/choices.tsx:775 | `core.status` | `` core.status.route.push(`choices:${selected}`); `` | +| packages-user/client-base/src/components/choices.tsx:776 | `core.status` | `core.status.replay.toReplay.shift();` | +| packages-user/client-base/src/components/choices.tsx:785 | `core.control` | `await sleep(core.control.__replay_getTimeout());` | +| packages-user/client-base/src/components/choices.tsx:791 | `core.status` | `` core.status.route.push(`choices:${index}`); `` | + +#### packages-user/client-base/src/components/floorSelect.tsx + +| 行 | core. | 上下文 | +| --- | --- | --- | +| packages-user/client-base/src/components/floorSelect.tsx:62 | `core.floors` | `const floorName = computed(() => core.floors[floorId.value].title);` | +| packages-user/client-base/src/components/floorSelect.tsx:181 | `core.floors` | `const floor = core.floors[v];` | + +#### packages-user/client-base/src/components/misc.tsx + +| 行 | core. | 上下文 | +| --- | --- | --- | +| packages-user/client-base/src/components/misc.tsx:315 | `core.material` | `isWinskin.value ? core.material.images.images[props.winskin!] : null` | + +#### packages-user/client-base/src/components/textboxTyper.ts + +| 行 | core. | 上下文 | +| --- | --- | --- | +| packages-user/client-base/src/components/textboxTyper.ts:907 | `core.calValue` | `this.resolved += core.calValue(exp);` | + +#### packages-user/client-base/src/components/thumbnail.tsx + +| 行 | core. | 上下文 | +| --- | --- | --- | +| packages-user/client-base/src/components/thumbnail.tsx:75 | `core.drawThumbnail` | `core.drawThumbnail(props.floorId, props.map, options);` | + +#### packages-user/client-base/src/components/tip.tsx + +| 行 | core. | 上下文 | +| --- | --- | --- | +| packages-user/client-base/src/components/tip.tsx:104 | `core.replaceText` | `text.value = core.replaceText(tipText);` | + +#### packages-user/client-base/src/elements/cache.ts + +| 行 | core. | 上下文 | +| --- | --- | --- | +| packages-user/client-base/src/elements/cache.ts:11 | `core.material` | `return core.material.images[img];` | +| packages-user/client-base/src/elements/cache.ts:87 | `core.material` | `this.tileset = core.material.images.tilesets;` | +| packages-user/client-base/src/elements/cache.ts:89 | `core.material` | `this.images = core.material.images.images;` | +| packages-user/client-base/src/elements/cache.ts:131 | `core.getTilesetOffset` | `const offset = core.getTilesetOffset(num);` | +| packages-user/client-base/src/elements/cache.ts:151 | `core.material` | `const img = core.material.images[cls];` | +| packages-user/client-base/src/elements/cache.ts:202 | `core.material` | `core.material.images[` | +| packages-user/client-base/src/elements/cache.ts:206 | `core.getAnimateFrames` | `const frame = core.getAnimateFrames(cls);` | +| packages-user/client-base/src/elements/cache.ts:393 | `core.material` | `for (const [key, img] of Object.entries(core.material.images.autotile)) {` | +| packages-user/client-base/src/elements/cache.ts:469 | `core.material` | `for (const [key, img] of Object.entries(core.material.images.autotile)) {` | + +#### packages-user/client-base/src/elements/misc.ts + +| 行 | core. | 上下文 | +| --- | --- | --- | +| packages-user/client-base/src/elements/misc.ts:221 | `core.material` | `const image = core.material.images.images[name];` | +| packages-user/client-base/src/elements/misc.ts:228 | `core.material` | `const image = core.material.images.images[id];` | + +#### packages-user/client-modules/src/action/hotkey.ts + +| 行 | core. | 上下文 | +| --- | --- | --- | +| packages-user/client-modules/src/action/hotkey.ts:478 | `core.status` | `!core.status.lockControl && !core.isMoving() && !core.isReplaying()` | +| packages-user/client-modules/src/action/hotkey.ts:478 | `core.isMoving` | `!core.status.lockControl && !core.isMoving() && !core.isReplaying()` | +| packages-user/client-modules/src/action/hotkey.ts:478 | `core.isReplaying` | `!core.status.lockControl && !core.isMoving() && !core.isReplaying()` | +| packages-user/client-modules/src/action/hotkey.ts:481 | `core.openBook` | `core.openBook(true);` | +| packages-user/client-modules/src/action/hotkey.ts:484 | `core.openToolbox` | `core.openToolbox(true);` | +| packages-user/client-modules/src/action/hotkey.ts:487 | `core.openEquipbox` | `core.openEquipbox(true);` | +| packages-user/client-modules/src/action/hotkey.ts:490 | `core.useFly` | `core.useFly(true);` | +| packages-user/client-modules/src/action/hotkey.ts:493 | `core.openQuickShop` | `core.openQuickShop(true);` | +| packages-user/client-modules/src/action/hotkey.ts:496 | `core.doSL` | `core.doSL('autoSave', 'load');` | +| packages-user/client-modules/src/action/hotkey.ts:499 | `core.doSL` | `core.doSL('autoSave', 'reload');` | +| packages-user/client-modules/src/action/hotkey.ts:502 | `core.turnHero` | `core.turnHero();` | +| packages-user/client-modules/src/action/hotkey.ts:505 | `core.getNextItem` | `core.getNextItem();` | +| packages-user/client-modules/src/action/hotkey.ts:508 | `core.confirmRestart` | `core.confirmRestart();` | +| packages-user/client-modules/src/action/hotkey.ts:511 | `core.actions` | `core.actions._clickGameInfo_openComments();` | +| packages-user/client-modules/src/action/hotkey.ts:514 | `core.debug` | `core.debug();` | + +#### packages-user/client-modules/src/action/move.ts + +| 行 | core. | 上下文 | +| --- | --- | --- | +| packages-user/client-modules/src/action/move.ts:66 | `core.isReplaying` | `if (core.isReplaying() \|\| !core.isPlaying()) return;` | +| packages-user/client-modules/src/action/move.ts:66 | `core.isPlaying` | `if (core.isReplaying() \|\| !core.isPlaying()) return;` | +| packages-user/client-modules/src/action/move.ts:67 | `core.waitHeroToStop` | `core.waitHeroToStop();` | +| packages-user/client-modules/src/action/move.ts:97 | `core.status` | `if (this.hotkey.scope !== this.scope \|\| core.status.lockControl) return;` | +| packages-user/client-modules/src/action/move.ts:123 | `core.status` | `if (this.moving \|\| core.status.lockControl) return false;` | +| packages-user/client-modules/src/action/move.ts:156 | `core.status` | `if (core.status.lockControl) {` | + +#### packages-user/client-modules/src/client.ts + +| 行 | core. | 上下文 | +| --- | --- | --- | +| packages-user/client-modules/src/client.ts:75 | `core.firstData` | `` this.save.init(`@game/${core.firstData.name}`); `` | + +#### packages-user/client-modules/src/fallback/audio.ts + +| 行 | core. | 上下文 | +| --- | --- | --- | +| packages-user/client-modules/src/fallback/audio.ts:49 | `core.getMappedName` | `const name = core.getMappedName(sound) as SoundIds;` | + +#### packages-user/client-modules/src/fallback/load.ts + +| 行 | core. | 上下文 | +| --- | --- | --- | +| packages-user/client-modules/src/fallback/load.ts:44 | `core.maps` | `const id = core.maps.blocksInfo[v as keyof NumberToId];` | +| packages-user/client-modules/src/fallback/load.ts:55 | `core.icons` | `const icons = core.icons.icons;` | +| packages-user/client-modules/src/fallback/load.ts:56 | `core.material` | `const images = core.material.images;` | +| packages-user/client-modules/src/fallback/load.ts:59 | `core.maps` | `for (const [key, value] of Object.entries(core.maps.blocksInfo)) {` | +| packages-user/client-modules/src/fallback/load.ts:99 | `core.tilesets` | `core.tilesets.forEach((v, i) => {` | +| packages-user/client-modules/src/fallback/load.ts:111 | `core.floorIds` | `core.floorIds.forEach(v => {` | +| packages-user/client-modules/src/fallback/load.ts:112 | `core.floors` | `const floor = core.floors[v];` | + +#### packages-user/client-modules/src/render/utils/saves.ts + +| 行 | core. | 上下文 | +| --- | --- | --- | +| packages-user/client-modules/src/render/utils/saves.ts:21 | `core.getSave` | `core.getSave(index, data => {` | +| packages-user/client-modules/src/render/utils/saves.ts:27 | `core.firstData` | `name: core.firstData.name,` | +| packages-user/client-modules/src/render/utils/saves.ts:28 | `core.firstData` | `version: core.firstData.version,` | +| packages-user/client-modules/src/render/utils/saves.ts:38 | `core.getAllSaves` | `core.getAllSaves(saves => {` | +| packages-user/client-modules/src/render/utils/saves.ts:44 | `core.firstData` | `name: core.firstData.name,` | +| packages-user/client-modules/src/render/utils/saves.ts:45 | `core.firstData` | `version: core.firstData.version,` | +| packages-user/client-modules/src/render/utils/saves.ts:103 | `core.firstData` | `formData.append('name', core.firstData.name);` | +| packages-user/client-modules/src/render/utils/saves.ts:172 | `core.setLocalForage` | `core.setLocalForage('save' + i, result[i - 1]);` | +| packages-user/client-modules/src/render/utils/saves.ts:173 | `core.saves` | `} else if (core.saves.ids[i]) {` | +| packages-user/client-modules/src/render/utils/saves.ts:174 | `core.removeLocalForage` | `core.removeLocalForage('save' + i);` | +| packages-user/client-modules/src/render/utils/saves.ts:185 | `core.saves` | `const idx = core.saves.saveIndex;` | +| packages-user/client-modules/src/render/utils/saves.ts:187 | `core.setLocalForage` | `` core.setLocalForage(`save${idx}`, result, res); `` | + +#### packages-user/client-modules/src/render/weather/presets/cloud.ts + +| 行 | core. | 上下文 | +| --- | --- | --- | +| packages-user/client-modules/src/render/weather/presets/cloud.ts:6 | `core.material` | `return core.material.images.images['cloud.png'] ?? null;` | + +#### packages-user/client-modules/src/render/weather/presets/fog.ts + +| 行 | core. | 上下文 | +| --- | --- | --- | +| packages-user/client-modules/src/render/weather/presets/fog.ts:22 | `core.material` | `const image = core.material.images.images['fog.png'];` | + +#### packages-user/client-modules/src/render/weather/presets/sun.ts + +| 行 | core. | 上下文 | +| --- | --- | --- | +| packages-user/client-modules/src/render/weather/presets/sun.ts:50 | `core.material` | `this.image = core.material.images.images['sun.png'];` | + +#### packages-user/client-modules/src/ui/book.tsx + +| 行 | core. | 上下文 | +| --- | --- | --- | +| packages-user/client-modules/src/ui/book.tsx:55 | `core.formatBigNumber` | `return core.formatBigNumber(value);` | + +#### packages-user/client-modules/src/ui/bookDetail.tsx + +| 行 | core. | 上下文 | +| --- | --- | --- | +| packages-user/client-modules/src/ui/bookDetail.tsx:99 | `core.formatBigNumber` | `const format = (value: number) => core.formatBigNumber(value);` | + +#### packages-user/client-modules/src/ui/main.tsx + +| 行 | core. | 上下文 | +| --- | --- | --- | +| packages-user/client-modules/src/ui/main.tsx:66 | `core.status` | `const len = core.status.stepPostfix?.length ?? 0;` | +| packages-user/client-modules/src/ui/main.tsx:76 | `core.status` | `const step = core.status.stepPostfix;` | +| packages-user/client-modules/src/ui/main.tsx:109 | `core.doRegisteredAction` | `core.doRegisteredAction('onup', bx, by, ev.offsetX, ev.offsetY);` | +| packages-user/client-modules/src/ui/main.tsx:118 | `core.doRegisteredAction` | `core.doRegisteredAction('ondown', bx, by, ev.offsetX, ev.offsetY);` | +| packages-user/client-modules/src/ui/main.tsx:127 | `core.doRegisteredAction` | `core.doRegisteredAction('onmove', bx, by, ev.offsetX, ev.offsetY);` | + +#### packages-user/client-modules/src/ui/save.tsx + +| 行 | core. | 上下文 | +| --- | --- | --- | +| packages-user/client-modules/src/ui/save.tsx:96 | `core.formatBigNumber` | `const hp = core.formatBigNumber(hero.hp);` | +| packages-user/client-modules/src/ui/save.tsx:97 | `core.formatBigNumber` | `const atk = core.formatBigNumber(hero.atk);` | +| packages-user/client-modules/src/ui/save.tsx:98 | `core.formatBigNumber` | `const def = core.formatBigNumber(hero.def);` | +| packages-user/client-modules/src/ui/save.tsx:118 | `core.maps` | `const map = core.maps.loadMap(currData.maps, currData.floorId);` | +| packages-user/client-modules/src/ui/save.tsx:119 | `core.extractBlocksForUI` | `core.extractBlocksForUI(map, currData.hero.flags); // 这一步会向map写入blocks` | +| packages-user/client-modules/src/ui/save.tsx:250 | `core.saves` | `const startIndex = getPosIndex(core.saves.saveIndex);` | +| packages-user/client-modules/src/ui/save.tsx:253 | `core.saves` | `Math.floor(core.saves.saveIndex / (grid.value.count - 1))` | +| packages-user/client-modules/src/ui/save.tsx:531 | `core.drawTip` | `core.drawTip(validation.message);` | +| packages-user/client-modules/src/ui/save.tsx:538 | `core.removeSave` | `core.removeSave(index);` | +| packages-user/client-modules/src/ui/save.tsx:540 | `core.drawTip` | `core.drawTip(validation.message);` | +| packages-user/client-modules/src/ui/save.tsx:570 | `core.doSL` | `core.doSL(index + 1, 'save');` | +| packages-user/client-modules/src/ui/save.tsx:591 | `core.doSL` | `core.doSL('autoSave', 'load');` | +| packages-user/client-modules/src/ui/save.tsx:593 | `core.doSL` | `core.doSL(index + 1, 'load');` | + +#### packages-user/client-modules/src/ui/settings.tsx + +| 行 | core. | 上下文 | +| --- | --- | --- | +| packages-user/client-modules/src/ui/settings.tsx:108 | `core.restart` | `core.restart();` | +| packages-user/client-modules/src/ui/settings.tsx:160 | `core.ui` | `core.ui.closePanel();` | +| packages-user/client-modules/src/ui/settings.tsx:161 | `core.status` | `const route = core.status.route.slice();` | +| packages-user/client-modules/src/ui/settings.tsx:165 | `core.startGame` | `core.startGame(core.status.hard, seed, route);` | +| packages-user/client-modules/src/ui/settings.tsx:165 | `core.status` | `core.startGame(core.status.hard, seed, route);` | +| packages-user/client-modules/src/ui/settings.tsx:172 | `core.doSL` | `core.doSL('autoSave', 'replayLoad');` | +| packages-user/client-modules/src/ui/settings.tsx:174 | `core.doSL` | `core.doSL(index + 1, 'replayLoad');` | +| packages-user/client-modules/src/ui/settings.tsx:183 | `core.doSL` | `const success = core.doSL(name, 'replayRemain');` | +| packages-user/client-modules/src/ui/settings.tsx:197 | `core.doSL` | `core.doSL(name2, 'replayRemain');` | +| packages-user/client-modules/src/ui/settings.tsx:205 | `core.doSL` | `core.doSL('autoSave', 'replaySince');` | +| packages-user/client-modules/src/ui/settings.tsx:207 | `core.doSL` | `core.doSL(index + 1, 'replaySince');` | +| packages-user/client-modules/src/ui/settings.tsx:214 | `core.chooseReplayFile` | `core.chooseReplayFile();` | +| packages-user/client-modules/src/ui/settings.tsx:221 | `core.download` | `core.download(` | +| packages-user/client-modules/src/ui/settings.tsx:222 | `core.firstData` | `core.firstData.name + '_' + core.formatDate2() + '.h5route',` | +| packages-user/client-modules/src/ui/settings.tsx:222 | `core.formatDate2` | `core.firstData.name + '_' + core.formatDate2() + '.h5route',` | +| packages-user/client-modules/src/ui/settings.tsx:225 | `core.firstData` | `name: core.firstData.name,` | +| packages-user/client-modules/src/ui/settings.tsx:226 | `core.status` | `hard: core.status.hard,` | +| packages-user/client-modules/src/ui/settings.tsx:228 | `core.encodeRoute` | `route: core.encodeRoute(core.status.route)` | +| packages-user/client-modules/src/ui/settings.tsx:228 | `core.status` | `route: core.encodeRoute(core.status.route)` | +| packages-user/client-modules/src/ui/settings.tsx:282 | `core.platform` | `if (core.platform.isPC) window.open('editor.html', '_blank');` | +| packages-user/client-modules/src/ui/settings.tsx:297 | `core.firstData` | `const name = core.firstData.name;` | +| packages-user/client-modules/src/ui/settings.tsx:299 | `core.platform` | `if (core.platform.isPC) {` | +| packages-user/client-modules/src/ui/settings.tsx:315 | `core.firstData` | `const name = core.firstData.name;` | +| packages-user/client-modules/src/ui/settings.tsx:317 | `core.platform` | `if (core.platform.isPC) window.open(href);` | +| packages-user/client-modules/src/ui/settings.tsx:431 | `core.playSound` | `core.playSound('confirm.opus');` | +| packages-user/client-modules/src/ui/settings.tsx:439 | `core.syncSave` | `core.syncSave('all');` | +| packages-user/client-modules/src/ui/settings.tsx:444 | `core.playSound` | `core.playSound('confirm.opus');` | +| packages-user/client-modules/src/ui/settings.tsx:452 | `core.syncSave` | `core.syncSave();` | +| packages-user/client-modules/src/ui/settings.tsx:502 | `core.download` | `core.download(` | +| packages-user/client-modules/src/ui/settings.tsx:503 | `core.firstData` | `` `${core.firstData.name}_${core.formatDate2( `` | +| packages-user/client-modules/src/ui/settings.tsx:503 | `core.formatDate2` | `` `${core.firstData.name}_${core.formatDate2( `` | +| packages-user/client-modules/src/ui/settings.tsx:519 | `core.saves` | `const data = await getSaveData(core.saves.saveIndex);` | +| packages-user/client-modules/src/ui/settings.tsx:520 | `core.download` | `core.download(` | +| packages-user/client-modules/src/ui/settings.tsx:521 | `core.firstData` | `` `${core.firstData.name}_${core.formatDate2( `` | +| packages-user/client-modules/src/ui/settings.tsx:521 | `core.formatDate2` | `` `${core.firstData.name}_${core.formatDate2( `` | +| packages-user/client-modules/src/ui/settings.tsx:573 | `core.clearLocalForage` | `core.clearLocalForage(() => {` | +| packages-user/client-modules/src/ui/settings.tsx:574 | `core.saves` | `core.saves.ids = {};` | +| packages-user/client-modules/src/ui/settings.tsx:575 | `core.saves` | `core.saves.autosave.data = null;` | +| packages-user/client-modules/src/ui/settings.tsx:576 | `core.saves` | `core.saves.autosave.updated = false;` | +| packages-user/client-modules/src/ui/settings.tsx:577 | `core.saves` | `core.saves.autosave.now = 0;` | +| packages-user/client-modules/src/ui/settings.tsx:579 | `core.saves` | `core.saves.cache = {};` | +| packages-user/client-modules/src/ui/settings.tsx:580 | `core.saves` | `core.saves.saveIndex = 1;` | +| packages-user/client-modules/src/ui/settings.tsx:581 | `core.saves` | `core.saves.favorite = [];` | +| packages-user/client-modules/src/ui/settings.tsx:582 | `core.saves` | `core.saves.favoriteName = {};` | +| packages-user/client-modules/src/ui/settings.tsx:584 | `core.control` | `core.control._updateFavoriteSaves();` | +| packages-user/client-modules/src/ui/settings.tsx:585 | `core.removeLocalStorage` | `core.removeLocalStorage('saveIndex');` | +| packages-user/client-modules/src/ui/settings.tsx:613 | `core.saves` | `Object.keys(core.saves.ids).forEach(function (v) {` | +| packages-user/client-modules/src/ui/settings.tsx:614 | `core.removeLocalForage` | `core.removeLocalForage('save' + v);` | +| packages-user/client-modules/src/ui/settings.tsx:616 | `core.removeLocalForage` | `core.removeLocalForage('autoSave', () => {` | +| packages-user/client-modules/src/ui/settings.tsx:617 | `core.saves` | `core.saves.ids = {};` | +| packages-user/client-modules/src/ui/settings.tsx:618 | `core.saves` | `core.saves.autosave.data = null;` | +| packages-user/client-modules/src/ui/settings.tsx:619 | `core.saves` | `core.saves.autosave.updated = false;` | +| packages-user/client-modules/src/ui/settings.tsx:620 | `core.saves` | `core.saves.autosave.now = 0;` | +| packages-user/client-modules/src/ui/settings.tsx:621 | `core.ui` | `core.ui.closePanel();` | +| packages-user/client-modules/src/ui/settings.tsx:622 | `core.saves` | `core.saves.saveIndex = 1;` | +| packages-user/client-modules/src/ui/settings.tsx:623 | `core.saves` | `core.saves.favorite = [];` | +| packages-user/client-modules/src/ui/settings.tsx:624 | `core.saves` | `core.saves.favoriteName = {};` | +| packages-user/client-modules/src/ui/settings.tsx:626 | `core.control` | `core.control._updateFavoriteSaves();` | +| packages-user/client-modules/src/ui/settings.tsx:627 | `core.removeLocalStorage` | `core.removeLocalStorage('saveIndex');` | + +#### packages-user/client-modules/src/ui/shop.tsx + +| 行 | core. | 上下文 | +| --- | --- | --- | +| packages-user/client-modules/src/ui/shop.tsx:288 | `core.formatBigNumber` | `text={core.formatBigNumber(item.stock)}` | +| packages-user/client-modules/src/ui/shop.tsx:337 | `core.formatBigNumber` | `entry ? core.formatBigNumber(entry.buyPrice) : '-'` | +| packages-user/client-modules/src/ui/shop.tsx:353 | `core.formatBigNumber` | `entry ? core.formatBigNumber(entry.sellPrice) : '-'` | +| packages-user/client-modules/src/ui/shop.tsx:368 | `core.formatBigNumber` | `text={entry ? core.formatBigNumber(entry.stock) : '-'}` | +| packages-user/client-modules/src/ui/shop.tsx:382 | `core.formatBigNumber` | `text={entry ? core.formatBigNumber(entry.owned) : '-'}` | +| packages-user/client-modules/src/ui/shop.tsx:396 | `core.formatBigNumber` | `text={core.formatBigNumber(total)}` | + +#### packages-user/client-modules/src/ui/statistics.tsx + +| 行 | core. | 上下文 | +| --- | --- | --- | +| packages-user/client-modules/src/ui/statistics.tsx:145 | `core.setFlag` | `core.setFlag('__statistics__', true);` | +| packages-user/client-modules/src/ui/statistics.tsx:149 | `core.status` | `const hero = core.status.hero;` | +| packages-user/client-modules/src/ui/statistics.tsx:163 | `core.status` | `core.status.hero = proxy;` | +| packages-user/client-modules/src/ui/statistics.tsx:165 | `core.extractBlocks` | `core.extractBlocks(floorId);` | +| packages-user/client-modules/src/ui/statistics.tsx:179 | `core.status` | `core.status.maps[floorId].blocks.forEach(v => {` | +| packages-user/client-modules/src/ui/statistics.tsx:220 | `core.status` | `core.status.hero = hero;` | +| packages-user/client-modules/src/ui/statistics.tsx:222 | `core.status` | `window.flags = core.status.hero.flags;` | +| packages-user/client-modules/src/ui/statistics.tsx:224 | `core.removeFlag` | `core.removeFlag('__statistics__');` | +| packages-user/client-modules/src/ui/statistics.tsx:229 | `core.setFlag` | `core.setFlag('__statistics__', true);` | +| packages-user/client-modules/src/ui/statistics.tsx:230 | `core.status` | `const hero = core.status.hero;` | +| packages-user/client-modules/src/ui/statistics.tsx:245 | `core.status` | `core.status.hero = proxy;` | +| packages-user/client-modules/src/ui/statistics.tsx:248 | `core.floorIds` | `core.floorIds.forEach(v => {` | +| packages-user/client-modules/src/ui/statistics.tsx:253 | `core.status` | `core.status.hero = hero;` | +| packages-user/client-modules/src/ui/statistics.tsx:255 | `core.status` | `window.flags = core.status.hero.flags;` | +| packages-user/client-modules/src/ui/statistics.tsx:256 | `core.removeFlag` | `core.removeFlag('__statistics__');` | + +#### packages-user/client-modules/src/ui/statusBar.tsx + +| 行 | core. | 上下文 | +| --- | --- | --- | +| packages-user/client-modules/src/ui/statusBar.tsx:183 | `core.getLvName` | `s.lv = core.getLvName(` | +| packages-user/client-modules/src/ui/statusBar.tsx:193 | `core.status` | `if (map) s.floor = core.status.floorId;` | +| packages-user/client-modules/src/ui/statusBar.tsx:208 | `core.floors` | `const floorName = computed(() => core.floors[s.floor]?.title ?? '');` | +| packages-user/client-modules/src/ui/statusBar.tsx:227 | `core.flags` | `const list = core.flags.statusBarItems;` | +| packages-user/client-modules/src/ui/statusBar.tsx:246 | `core.formatBigNumber` | `const hp = core.formatBigNumber(s.hp);` | +| packages-user/client-modules/src/ui/statusBar.tsx:247 | `core.formatBigNumber` | `const hpmax = core.formatBigNumber(s.hpmax);` | +| packages-user/client-modules/src/ui/statusBar.tsx:257 | `core.formatBigNumber` | `value: computed(() => core.formatBigNumber(s.hp)),` | +| packages-user/client-modules/src/ui/statusBar.tsx:269 | `core.formatBigNumber` | `const mana = core.formatBigNumber(s.mana);` | +| packages-user/client-modules/src/ui/statusBar.tsx:270 | `core.formatBigNumber` | `const manamax = core.formatBigNumber(s.manamax);` | +| packages-user/client-modules/src/ui/statusBar.tsx:288 | `core.formatBigNumber` | `value: computed(() => core.formatBigNumber(s.atk)),` | +| packages-user/client-modules/src/ui/statusBar.tsx:298 | `core.formatBigNumber` | `value: computed(() => core.formatBigNumber(s.def)),` | +| packages-user/client-modules/src/ui/statusBar.tsx:308 | `core.formatBigNumber` | `value: computed(() => core.formatBigNumber(s.mdef)),` | +| packages-user/client-modules/src/ui/statusBar.tsx:318 | `core.formatBigNumber` | `value: computed(() => core.formatBigNumber(s.money)),` | +| packages-user/client-modules/src/ui/statusBar.tsx:330 | `core.formatBigNumber` | `value: computed(() => core.formatBigNumber(s.up)),` | +| packages-user/client-modules/src/ui/statusBar.tsx:338 | `core.formatBigNumber` | `value: computed(() => core.formatBigNumber(s.exp)),` | + +#### packages-user/client-modules/src/ui/title.tsx + +| 行 | core. | 上下文 | +| --- | --- | --- | +| packages-user/client-modules/src/ui/title.tsx:122 | `core.arrayToRGBA` | `color: core.arrayToRGBA(v.color!),` | +| packages-user/client-modules/src/ui/title.tsx:210 | `core.chooseReplayFile` | `core.chooseReplayFile();` | +| packages-user/client-modules/src/ui/title.tsx:223 | `core.startGame` | `core.startGame(hard);` | +| packages-user/client-modules/src/ui/title.tsx:364 | `core.firstData` | `text={core.firstData.title}` | + +#### packages-user/client-modules/src/ui/toolbar.tsx + +| 行 | core. | 上下文 | +| --- | --- | --- | +| packages-user/client-modules/src/ui/toolbar.tsx:89 | `core.openBook` | `const book = () => core.openBook(true);` | +| packages-user/client-modules/src/ui/toolbar.tsx:90 | `core.openToolbox` | `const tool = () => core.openToolbox(true);` | +| packages-user/client-modules/src/ui/toolbar.tsx:91 | `core.useFly` | `const fly = () => core.useFly(true);` | +| packages-user/client-modules/src/ui/toolbar.tsx:98 | `core.openEquipbox` | `const equip = () => core.openEquipbox(true);` | +| packages-user/client-modules/src/ui/toolbar.tsx:99 | `core.openQuickShop` | `const shop = () => core.openQuickShop(true);` | +| packages-user/client-modules/src/ui/toolbar.tsx:110 | `core.doSL` | `const undo = () => core.doSL('autoSave', 'load');` | +| packages-user/client-modules/src/ui/toolbar.tsx:111 | `core.doSL` | `const redo = () => core.doSL('autoSave', 'reload');` | +| packages-user/client-modules/src/ui/toolbar.tsx:187 | `core.resumeReplay` | `const play = () => core.resumeReplay();` | +| packages-user/client-modules/src/ui/toolbar.tsx:188 | `core.pauseReplay` | `const pause = () => core.pauseReplay();` | +| packages-user/client-modules/src/ui/toolbar.tsx:189 | `core.stopReplay` | `const stop = () => core.stopReplay(true);` | +| packages-user/client-modules/src/ui/toolbar.tsx:190 | `core.speedDownReplay` | `const speedDown = () => core.speedDownReplay();` | +| packages-user/client-modules/src/ui/toolbar.tsx:191 | `core.speedUpReplay` | `const speedUp = () => core.speedUpReplay();` | +| packages-user/client-modules/src/ui/toolbar.tsx:192 | `core.openBook` | `const book = () => core.openBook(true);` | +| packages-user/client-modules/src/ui/toolbar.tsx:197 | `core.isPlaying` | `if (core.isPlaying() && !core.isMoving() && !core.status.lockControl) {` | +| packages-user/client-modules/src/ui/toolbar.tsx:197 | `core.isMoving` | `if (core.isPlaying() && !core.isMoving() && !core.status.lockControl) {` | +| packages-user/client-modules/src/ui/toolbar.tsx:197 | `core.status` | `if (core.isPlaying() && !core.isMoving() && !core.status.lockControl) {` | +| packages-user/client-modules/src/ui/toolbar.tsx:198 | `core.ui` | `core.ui._drawViewMaps();` | +| packages-user/client-modules/src/ui/toolbar.tsx:201 | `core.rewindReplay` | `const rewind = () => core.rewindReplay();` | +| packages-user/client-modules/src/ui/toolbar.tsx:202 | `core.stepReplay` | `const step = () => core.stepReplay();` | + +#### packages-user/client-modules/src/ui/toolbox.tsx + +| 行 | core. | 上下文 | +| --- | --- | --- | +| packages-user/client-modules/src/ui/toolbox.tsx:165 | `core.formatBigNumber` | `text={core.formatBigNumber(item.count)}` | +| packages-user/client-modules/src/ui/toolbox.tsx:220 | `core.formatBigNumber` | `text={core.formatBigNumber(item.count)}` | + +#### packages-user/client-modules/src/ui/viewmap.tsx + +| 行 | core. | 上下文 | +| --- | --- | --- | +| packages-user/client-modules/src/ui/viewmap.tsx:54 | `core.status` | `const nowFloorId = core.status.floorId;` | +| packages-user/client-modules/src/ui/viewmap.tsx:71 | `core.floorIds` | `core.floorIds.filter(v => {` | +| packages-user/client-modules/src/ui/viewmap.tsx:73 | `core.floors` | `!core.floors[v].cannotViewMap &&` | +| packages-user/client-modules/src/ui/viewmap.tsx:74 | `core.status` | `!core.status?.hero?.flags?.__removed__?.includes(v)` | +| packages-user/client-modules/src/ui/viewmap.tsx:118 | `core.formatBigNumber` | `return core.formatBigNumber(num ?? 0, 6);` | +| packages-user/client-modules/src/ui/viewmap.tsx:130 | `core.openBook` | `const openBook = () => core.openBook(true);` | +| packages-user/client-modules/src/ui/viewmap.tsx:133 | `core.hasItem` | `if (!core.hasItem('fly')) return;` | +| packages-user/client-modules/src/ui/viewmap.tsx:135 | `core.flyTo` | `const success = core.flyTo(id);` | +| packages-user/client-modules/src/ui/viewmap.tsx:137 | `core.floors` | `` else tip.value?.drawTip(`无法飞往${core.floors[id].title}`); `` | +| packages-user/client-modules/src/ui/viewmap.tsx:361 | `core.status` | `core.status.floorId = nowFloorId;` | +| packages-user/client-modules/src/ui/viewmap.tsx:362 | `core.status` | `core.status.thisMap = core.status.maps[nowFloorId];` | +| packages-user/client-modules/src/ui/viewmap.tsx:362 | `core.status` | `core.status.thisMap = core.status.maps[nowFloorId];` | +| packages-user/client-modules/src/ui/viewmap.tsx:566 | `core.status` | `floorId: core.status.floorId` | + +### C-3 每文件计数 + +| 文件 | 调用点计数 | +| --- | --- | +| packages-user/client-base/src/components/choices.tsx | 13 | +| packages-user/client-base/src/components/floorSelect.tsx | 2 | +| packages-user/client-base/src/components/misc.tsx | 1 | +| packages-user/client-base/src/components/textboxTyper.ts | 1 | +| packages-user/client-base/src/components/thumbnail.tsx | 1 | +| packages-user/client-base/src/components/tip.tsx | 1 | +| packages-user/client-base/src/elements/cache.ts | 9 | +| packages-user/client-base/src/elements/misc.ts | 2 | +| packages-user/client-modules/src/action/hotkey.ts | 15 | +| packages-user/client-modules/src/action/move.ts | 6 | +| packages-user/client-modules/src/client.ts | 1 | +| packages-user/client-modules/src/fallback/audio.ts | 1 | +| packages-user/client-modules/src/fallback/load.ts | 7 | +| packages-user/client-modules/src/render/utils/saves.ts | 12 | +| packages-user/client-modules/src/render/weather/presets/cloud.ts | 1 | +| packages-user/client-modules/src/render/weather/presets/fog.ts | 1 | +| packages-user/client-modules/src/render/weather/presets/sun.ts | 1 | +| packages-user/client-modules/src/ui/book.tsx | 1 | +| packages-user/client-modules/src/ui/bookDetail.tsx | 1 | +| packages-user/client-modules/src/ui/main.tsx | 5 | +| packages-user/client-modules/src/ui/save.tsx | 13 | +| packages-user/client-modules/src/ui/settings.tsx | 59 | +| packages-user/client-modules/src/ui/shop.tsx | 6 | +| packages-user/client-modules/src/ui/statistics.tsx | 15 | +| packages-user/client-modules/src/ui/statusBar.tsx | 15 | +| packages-user/client-modules/src/ui/title.tsx | 4 | +| packages-user/client-modules/src/ui/toolbar.tsx | 19 | +| packages-user/client-modules/src/ui/toolbox.tsx | 2 | +| packages-user/client-modules/src/ui/viewmap.tsx | 13 | +| **合计** | **228** | + +**C-COUNT: 228**(去重成员数 M = 67;覆盖文件数 = 29;其中 `client-base` 8 个、`client-modules` 21 个。) + +## 汇总 + +| 类别 | 计数 | 覆盖文件数 | 说明 | +| --- | --- | --- | --- | +| A. 残余的 legacy 接口 | 32 | 12 | A-1 跨包依赖(10) + A-2 全局 `core`(1) + A-3 单例 `client`(3) + A-4 patch 机制(3) + A-5 UI 运行时符号(7) + A-6 `Mota` 全局(3) + A-7 回退层(5) | +| B. 标注 `@deprecated` 的接口 | 0 | 0 | 两包内实测 0 条(显式报告,不省略) | +| C. 经 `core.*` 调用的接口 | 228 | 29 | 去重成员 67 个;`client-base` 8 文件 + `client-modules` 21 文件 | + +- **A-COUNT: 32** +- **B-COUNT: 0** +- **C-COUNT: 228**