40250 classic: G1 integrate W3 (§8.3 in-game help window)
Doc conflicts resolved by W0: kept all four 增量 50 change-log bullets and appended the W3 C.5 batch record. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014yvAPqPivoY7vmBbzgqK4W
This commit is contained in:
+74
-9
@@ -2545,18 +2545,53 @@ BOOL bMainFlareEnable; std::string strMainFlareTextureFileName; float fMainFla
|
|||||||
|
|
||||||
### 8.3 帮助窗口未实现
|
### 8.3 帮助窗口未实现
|
||||||
|
|
||||||
**参考**:`POC/assets/root/uihelp.py`(136 行)+ uiscript `helpwindow.py`。
|
**状态**:🟡 开发中(首版落地,真服 / 视觉未验收)—— 批次 2026-09-02 / W3。
|
||||||
入口:`game.py:459 __PressHKey()` —— 非 Ctrl 时 `self.interface.OpenHelpWindow()`
|
|
||||||
|
**参考**:`assets/root/uihelp.py`(`HelpWindow`,单页版 `ENABLE_HELP_MULTIPAGE = 0` →
|
||||||
|
`LoadDialogSinglePage()` 装 `UIScript/HelpWindow.py`)+ uiscript
|
||||||
|
`assets/uiscript/uiscript/helpwindow.py`(19 条 `help_XX` 浮动文本 + `taskbar_help_*`
|
||||||
|
贴纸标签 + `close_button`,文本取自 `uiScriptLocale.HELP_*`)。
|
||||||
|
入口:`game.py __PressHKey()` —— 非 Ctrl 时 `self.interface.OpenHelpWindow()`
|
||||||
(Ctrl+H 是 `/user_horse_ride`)。
|
(Ctrl+H 是 `/user_horse_ride`)。
|
||||||
|
|
||||||
**当前**:`POC/project/ui/system_menu_ui.gd:91` 只显示占位提示。
|
> 注:本仓 `uihelp.py` 并非“136 行含键位/说明行”的版本;帮助行文本实际在
|
||||||
|
> `helpwindow.py` uiscript 里以 `uiScriptLocale.HELP_*` 引用,逐字值在
|
||||||
|
> `locale/locale/<lang>/locale_interface.txt`。故“逐字对齐 `uihelp.py`”按“逐字对齐
|
||||||
|
> `helpwindow.py` + `uiScriptLocale.HELP_*`(英文表)”落实。
|
||||||
|
|
||||||
**修改**
|
**当前**:`system_menu_ui.gd` 的 `help_button` 已由占位提示改为打开 `help_ui.gd`。
|
||||||
|
|
||||||
1. 新建 `POC/project/ui/help_ui.gd`,按样板装 `helpwindow.py` uiscript,
|
**改动**
|
||||||
内容绑定逐字对齐 `uihelp.py`。
|
|
||||||
2. 挂 `H` 键(非 Ctrl)与 ESC 菜单的 `help_button`,替换 `system_menu_ui.gd:91` 的占位。
|
- 新增 `project/ui/help_ui.gd`:`ui.open_script("helpwindow.py")`(UiScript → UiBuild)
|
||||||
3. 配 `help_ui_test.gd`。
|
非模态开窗;`_relabel()` 把 `helpwindow.py` 解析出的 `<HELP_*>` / `<CLOSE>` 占位
|
||||||
|
(`UiManager` 未接 locale 回调时产生)用本工程 `Locale`(`en`)表 + 逐字英文兜底补回,
|
||||||
|
覆盖原脚本重名的两个 `help_02`(右键 / 中键相机说明);`open/close/toggle/is_open`、
|
||||||
|
`close_button` → `close`、ESC 由 `UiManager` 窗口栈统一关顶层。
|
||||||
|
- `project/ui/system_menu_ui.gd`:`help_button` → `close()` + `open_help()`;新增
|
||||||
|
`const HelpUI`、可注入的 `help_ui` 成员、`_ensure_help()`(懒建,复用菜单的
|
||||||
|
`ui/client/assets_root`)、`open_help()`、`toggle_help()`;`setup()` 追加可选第 6 参
|
||||||
|
`help_win`(旧 5 参调用不受影响)。
|
||||||
|
- `project/game_scene.gd`:`_unhandled_input` 加**单条** `elif` —— `KEY_H` 且
|
||||||
|
`not ctrl_pressed and not meta_pressed` → `system_menu_ui.toggle_help()`;`Ctrl+H`
|
||||||
|
未占用,仍留给 `/user_horse_ride`。
|
||||||
|
- 接口 / 数据结构变化:仅 `SystemMenuUI.setup()` 追加可选尾参;无网络 / EntityStore 改动。
|
||||||
|
|
||||||
|
**测试**
|
||||||
|
|
||||||
|
- 新增 `project/help_ui_test.gd`(headless SceneTree):helpwindow.py 装载、19 条帮助行
|
||||||
|
逐字绑定且非 `<KEY>` 占位、任务栏标签、`close_button` 文本 = `Close`、`rows()` 便捷器、
|
||||||
|
`close_button` 关窗、`open/toggle`、ESC 栈顶、`SystemMenuUI.open_help()` 懒建并打开。
|
||||||
|
- `godot --headless --path project --script res://help_ui_test.gd` → `PASS`(exit 0)。
|
||||||
|
- 回归:`system_menu_ui_test`、`gamescene_test`、`ui_test` 全 `PASS`;附加
|
||||||
|
`system_option_ui_test`、`char_status_ui_test` 亦 `PASS`。
|
||||||
|
- skip:本 worktree 无 `build/`,未跑 C++ `ctest`(本条无 C++ 改动)。
|
||||||
|
|
||||||
|
**验收**
|
||||||
|
|
||||||
|
- 真服 / 双账号 / Mac App:未验证(§8.3 为纯本地 UI,无服务端依赖)。
|
||||||
|
- 视觉:`helpwindow.py` 的 `.sub` / `help_stick.tga` 贴图未逐像素比对;字体描边
|
||||||
|
(`"outline": 1`)按 `ui.py` 默认,未单独标定。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -3076,7 +3111,7 @@ var _pw := "123456789"
|
|||||||
| W0 公共基础 / 集成 | 🟡 开发中 | DirectEnter、Classic Warp endpoint、`world_reset`、场景重建首版;增量 49 接口冻结批次(`Entity` 字段 + `mut_spawn_full/mut_ownership/mut_map_bgm/drain_dirty` + `bgm_changed` 信号 + `bgm_director.gd` + §8.6 键位入口)已提交,C++ `ctest` 16/16 + 9 项 GDScript 回归通过 | 接收 Phase 1 W1/W2/W3/W4 批次并执行 G1 |
|
| W0 公共基础 / 集成 | 🟡 开发中 | DirectEnter、Classic Warp endpoint、`world_reset`、场景重建首版;增量 49 接口冻结批次(`Entity` 字段 + `mut_spawn_full/mut_ownership/mut_map_bgm/drain_dirty` + `bgm_changed` 信号 + `bgm_director.gd` + §8.6 键位入口)已提交,C++ `ctest` 16/16 + 9 项 GDScript 回归通过 | 接收 Phase 1 W1/W2/W3/W4 批次并执行 G1 |
|
||||||
| W1 协议 / 账号会话 | 🟡 开发中(增量 50:§1.5 / §1.10 / §2.2 已落地,待真实验收) | 角色槽地址透传、发送结果、unknown / unhandled 错误链路、断线回 LOGIN;§1.5 locale 分支 + `CGClientVersion2`(0xf1);§1.10 `text_codec.h` + `to_wire` 路由 + `net_text_codec_test`(套件 16→17);§2.2 `GC_CHARACTER_ADD` 隐身丢弃 / PC·NPC 暂存 / 其余按 `npclist.txt` 命名立即 spawn,`GC_CHAR_ADDITIONAL_INFO` 无 pending 丢弃、命中则 `mut_spawn_full` 合并;G1 已接线 `set_executable_name` / `set_npclist_path` / `mut_affect_flags` | locale 代码页转码(CP949/CP1252)、真实双连接、进场延迟 |
|
| W1 协议 / 账号会话 | 🟡 开发中(增量 50:§1.5 / §1.10 / §2.2 已落地,待真实验收) | 角色槽地址透传、发送结果、unknown / unhandled 错误链路、断线回 LOGIN;§1.5 locale 分支 + `CGClientVersion2`(0xf1);§1.10 `text_codec.h` + `to_wire` 路由 + `net_text_codec_test`(套件 16→17);§2.2 `GC_CHARACTER_ADD` 隐身丢弃 / PC·NPC 暂存 / 其余按 `npclist.txt` 命名立即 spawn,`GC_CHAR_ADDITIONAL_INFO` 无 pending 丢弃、命中则 `mut_spawn_full` 合并;G1 已接线 `set_executable_name` / `set_npclist_path` / `mut_affect_flags` | locale 代码页转码(CP949/CP1252)、真实双连接、进场延迟 |
|
||||||
| W2 实体 / 世界 / 战斗 | 🟡 开发中(Phase 1 批次已交) | 增量 50:§2.1 两层模型(`EntityStore` 纯数据层 + `net_world._update_visibility()` 按 `CHAR_STAGE_VIEW_BOUND` / `AFFECT_SHOW_ALWAYS` / `IsWall` 建 / 淡出节点)、§2.3(`mut_spawn`→`mut_spawn_full` 整行替换 + 节点重建 + 上下马保坐标)、§2.4(点数快照清尾 / 单索引边界)、§2.5(`mut_affect_flags` 两段拼装 + 参考调用序刷新)已落地;`ctest` 16/16 + 7 项 GDScript 回归 + 新增 `net_world_vis_test` 全绿 | 远服端到端可见性 / VID 复用 / affect 表现验收;`state_flags` 表现层枚举 |
|
| W2 实体 / 世界 / 战斗 | 🟡 开发中(Phase 1 批次已交) | 增量 50:§2.1 两层模型(`EntityStore` 纯数据层 + `net_world._update_visibility()` 按 `CHAR_STAGE_VIEW_BOUND` / `AFFECT_SHOW_ALWAYS` / `IsWall` 建 / 淡出节点)、§2.3(`mut_spawn`→`mut_spawn_full` 整行替换 + 节点重建 + 上下马保坐标)、§2.4(点数快照清尾 / 单索引边界)、§2.5(`mut_affect_flags` 两段拼装 + 参考调用序刷新)已落地;`ctest` 16/16 + 7 项 GDScript 回归 + 新增 `net_world_vis_test` 全绿 | 远服端到端可见性 / VID 复用 / affect 表现验收;`state_flags` 表现层枚举 |
|
||||||
| W3 玩法 UI / 输入 | 🟡 已有首版 | 多数窗口、背包 / 任务 / 社交、键位和输入已有回归;§8.6 数字键 / F1–F4 / Ctrl+数字入口已收敛 | §8.3 帮助窗;§8.6 剩余逐行键位、LSHIFT 翻页、表情包 |
|
| W3 玩法 UI / 输入 | 🟡 已有首版 | 多数窗口、背包 / 任务 / 社交、键位和输入已有回归;§8.6 数字键 / F1–F4 / Ctrl+数字入口已收敛;§8.3 帮助窗(`help_ui.gd` = `helpwindow.py` + `uiScriptLocale.HELP_*` 逐字,`H` / ESC 菜单 `help_button` 入口,`help_ui_test` 绿)已落地 | §8.6 剩余逐行键位、LSHIFT 翻页、表情包;帮助窗视觉 / `.sub` 贴图与真服未验收 |
|
||||||
| W4 渲染 / 资产 / 音频 | 🟡 已有首版 | GR2 / `.msa` / `.mse`、地图 / 水体 / 天气 / BGM 部分链路已有;`bgm_director.gd` 消费点就位 | §9.1 地图 BGM 曲目解析 + 音量、§9.2 后台恢复曲目、§9.3 生命周期单一属主 |
|
| W4 渲染 / 资产 / 音频 | 🟡 已有首版 | GR2 / `.msa` / `.mse`、地图 / 水体 / 天气 / BGM 部分链路已有;`bgm_director.gd` 消费点就位 | §9.1 地图 BGM 曲目解析 + 音量、§9.2 后台恢复曲目、§9.3 生命周期单一属主 |
|
||||||
| W5 打包 / 发布 / 验收 | ⬜ 未开始 | 已有 Godot 导出配置和构建入口 | 自包含资源包、Intel / Apple Silicon、签名和 Mac App 验收 |
|
| W5 打包 / 发布 / 验收 | ⬜ 未开始 | 已有 Godot 导出配置和构建入口 | 自包含资源包、Intel / Apple Silicon、签名和 Mac App 验收 |
|
||||||
|
|
||||||
@@ -3216,3 +3251,33 @@ var _pw := "123456789"
|
|||||||
- m2dev apply() 内联 touch() 路径(GC_CHARACTER_ADD 等旧协议分支)不在 §2.2 范围,未改
|
- m2dev apply() 内联 touch() 路径(GC_CHARACTER_ADD 等旧协议分支)不在 §2.2 范围,未改
|
||||||
下一批次:W1 接线 mut_affect_flags + §2.2 两包合并;Phase 2 由 W0 执行 G1 集成
|
下一批次:W1 接线 mut_affect_flags + §2.2 两包合并;Phase 2 由 W0 执行 G1 集成
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```text
|
||||||
|
批次:2026-09-02 / W3 / §8.3(帮助窗)
|
||||||
|
状态:🟡 开发中(首版落地;真服 / 视觉未验收)
|
||||||
|
参考:assets/root/uihelp.py(HelpWindow.LoadDialogSinglePage);
|
||||||
|
assets/uiscript/uiscript/helpwindow.py(help_01..help_19 + taskbar_help_* + close_button);
|
||||||
|
assets/locale/locale/en/locale_interface.txt(HELP_* / CLOSE 逐字);
|
||||||
|
game.py __PressHKey(H 非 Ctrl → interface.OpenHelpWindow(),Ctrl+H = /user_horse_ride)
|
||||||
|
改动:
|
||||||
|
project/ui/help_ui.gd(新)—— ui.open_script("helpwindow.py") 非模态;_relabel() 用
|
||||||
|
Locale(en) + 英文兜底把 <HELP_*>/<CLOSE> 占位补回(含重名的两个 help_02);
|
||||||
|
open/close/toggle/is_open、close_button→close、ESC 走 UiManager 窗口栈、rows() 便捷器
|
||||||
|
project/ui/system_menu_ui.gd —— help_button 由占位提示改为 close()+open_help();
|
||||||
|
+const HelpUI、+help_ui 成员、+_ensure_help()/open_help()/toggle_help();
|
||||||
|
setup() 追加可选第 6 参 help_win(旧 5 参调用不受影响)
|
||||||
|
project/game_scene.gd —— _unhandled_input 加单条 elif:KEY_H 且非 ctrl/meta →
|
||||||
|
system_menu_ui.toggle_help()(Ctrl+H 未占用)
|
||||||
|
接口变化:仅 SystemMenuUI.setup() 追加可选尾参;无 net / EntityStore 改动
|
||||||
|
测试:godot --headless --path project --script res://help_ui_test.gd → PASS(exit 0);
|
||||||
|
system_menu_ui_test / gamescene_test / ui_test 全 PASS;附加 system_option_ui_test /
|
||||||
|
char_status_ui_test 亦 PASS
|
||||||
|
skip:本 worktree 无 build/,未跑 C++ ctest(本批次无 C++ 改动)
|
||||||
|
验收:真服 / 双账号 / Mac App 未验证(§8.3 纯本地 UI,无服务端依赖);
|
||||||
|
helpwindow.py 的 .sub / help_stick.tga 贴图与字体描边未逐像素比对
|
||||||
|
风险与依赖:依赖 W0 冻结的 UiManager/UiScript/UiBuild 与 Locale;未改共享文件,
|
||||||
|
game_scene.gd 仅加 1 条 elif(W3 许可范围)。1:1 偏差:本仓 uihelp.py 非“136 行含
|
||||||
|
键位行”版本,逐字源实际为 helpwindow.py + uiScriptLocale.HELP_*(已在 §8.3 注明);
|
||||||
|
帮助窗按非模态实现(原版 Lock()),ESC/关闭行为等价
|
||||||
|
下一批次:Phase 2 由 W0 执行 G1 集成;§8.6 剩余逐行键位与表情包仍在 W3 范围
|
||||||
|
```
|
||||||
|
|||||||
+17
-1
@@ -58,7 +58,7 @@
|
|||||||
| W0 公共基础 / 集成 | 🟡 | DirectEnter、Classic Warp endpoint、`world_reset`、场景重建首版已落地;增量 49 接口冻结批次(`Entity` 补字段 + `mut_spawn_full/mut_ownership/mut_map_bgm/drain_dirty`、`bgm_changed` 信号、`bgm_director.gd`、§8.6 键位收敛)已提交 | Phase 1 4 工作流并行完成后执行 G1 集成 |
|
| W0 公共基础 / 集成 | 🟡 | DirectEnter、Classic Warp endpoint、`world_reset`、场景重建首版已落地;增量 49 接口冻结批次(`Entity` 补字段 + `mut_spawn_full/mut_ownership/mut_map_bgm/drain_dirty`、`bgm_changed` 信号、`bgm_director.gd`、§8.6 键位收敛)已提交 | Phase 1 4 工作流并行完成后执行 G1 集成 |
|
||||||
| W1 协议 / 账号会话 | 🟡 | 增量 50:§1.5 版本包按 locale 分支(EUROPE 发 `CG_CLIENT_VERSION2` 0xf1 + `"1215955205"`,其余发 0xfd + `MT_BUILD_TIMESTAMP`)、可执行名 setter;§1.10 `text_codec.h` UTF-8 安全定长文本裁剪 + `net_text_codec_test`,会话侧所有定长 name/sign/comment 填充改走 `to_wire()`;§2.2 `GC_CHARACTER_ADD` 按 invisible-race 丢弃 / PC·NPC 暂存 `m_pending_actor` / 其余即时 `mut_spawn`(名字取自 npclist.txt),`GC_CHAR_ADDITIONAL_INFO` 无暂存则记录并丢弃、命中则合并 9 字段 `mut_spawn_full` 后清表 | 真实 locale codepage 转码、真实双连接、enter delay;GDScript 名称长度校验统一(G1 已收) |
|
| W1 协议 / 账号会话 | 🟡 | 增量 50:§1.5 版本包按 locale 分支(EUROPE 发 `CG_CLIENT_VERSION2` 0xf1 + `"1215955205"`,其余发 0xfd + `MT_BUILD_TIMESTAMP`)、可执行名 setter;§1.10 `text_codec.h` UTF-8 安全定长文本裁剪 + `net_text_codec_test`,会话侧所有定长 name/sign/comment 填充改走 `to_wire()`;§2.2 `GC_CHARACTER_ADD` 按 invisible-race 丢弃 / PC·NPC 暂存 `m_pending_actor` / 其余即时 `mut_spawn`(名字取自 npclist.txt),`GC_CHAR_ADDITIONAL_INFO` 无暂存则记录并丢弃、命中则合并 9 字段 `mut_spawn_full` 后清表 | 真实 locale codepage 转码、真实双连接、enter delay;GDScript 名称长度校验统一(G1 已收) |
|
||||||
| W2 实体 / 世界 / 战斗 | 🟡 | §2.1 两层模型(`EntityStore` 纯数据层 + `net_world.gd` 每帧 `_update_visibility()` 按 `CHAR_STAGE_VIEW_BOUND` / `AFFECT_SHOW_ALWAYS` / `IsWall` 建 / 淡出节点)、§2.3(`mut_spawn`→`mut_spawn_full` 整行替换 + 节点销毁重建 + 上下坐骑保坐标)、§2.4(点数快照截断 / 尾部清零 + 单索引边界)、§2.5(`mut_affect_flags` 两段拼装 + 参考调用序节点刷新)已落地并回归(增量 50) | 远服 40250 端到端可见性 / VID 复用 / affect 表现验收;`state_flags` 表现层枚举与眩晕 / 隐身等表现 |
|
| W2 实体 / 世界 / 战斗 | 🟡 | §2.1 两层模型(`EntityStore` 纯数据层 + `net_world.gd` 每帧 `_update_visibility()` 按 `CHAR_STAGE_VIEW_BOUND` / `AFFECT_SHOW_ALWAYS` / `IsWall` 建 / 淡出节点)、§2.3(`mut_spawn`→`mut_spawn_full` 整行替换 + 节点销毁重建 + 上下坐骑保坐标)、§2.4(点数快照截断 / 尾部清零 + 单索引边界)、§2.5(`mut_affect_flags` 两段拼装 + 参考调用序节点刷新)已落地并回归(增量 50) | 远服 40250 端到端可见性 / VID 复用 / affect 表现验收;`state_flags` 表现层枚举与眩晕 / 隐身等表现 |
|
||||||
| W3 玩法 UI / 输入 | 🟡 | 多数窗口、背包 / 任务 / 社交、键位和输入已有首版;§8.6 数字键 / F1–F4 / Ctrl+数字入口已收敛 | §8.3 帮助窗;§8.6 剩余逐行键位与表情包 |
|
| W3 玩法 UI / 输入 | 🟡 | 多数窗口、背包 / 任务 / 社交、键位和输入已有首版;§8.6 数字键 / F1–F4 / Ctrl+数字入口已收敛;**§8.3 帮助窗(`help_ui.gd` = `helpwindow.py` uiscript + `uiScriptLocale.HELP_*` 逐字,`H` 键 / ESC 菜单 `help_button` 入口,`help_ui_test` 绿)已落地** | §8.6 剩余逐行键位与表情包;帮助窗视觉 / `.sub` 贴图与真服未验证 |
|
||||||
| W4 渲染 / 资产 / 音频 | 🟡 | GR2 / `.msa` / `.mse`、地图 / 水体 / 天气 / BGM 部分链路已有;`bgm_director.gd` 消费点已就位 | §9.1 地图 BGM 曲目解析 + 音量、§9.2 后台恢复曲目、§9.3 生命周期单一属主 |
|
| W4 渲染 / 资产 / 音频 | 🟡 | GR2 / `.msa` / `.mse`、地图 / 水体 / 天气 / BGM 部分链路已有;`bgm_director.gd` 消费点已就位 | §9.1 地图 BGM 曲目解析 + 音量、§9.2 后台恢复曲目、§9.3 生命周期单一属主 |
|
||||||
| W5 打包 / 发布 / 验收 | ⬜ | 已有 Godot 导出配置和构建入口 | 自包含资源包、Intel / Apple Silicon、签名和 Mac App 验收 |
|
| W5 打包 / 发布 / 验收 | ⬜ | 已有 Godot 导出配置和构建入口 | 自包含资源包、Intel / Apple Silicon、签名和 Mac App 验收 |
|
||||||
|
|
||||||
@@ -162,6 +162,22 @@
|
|||||||
> `wire_classic.h` 的 `GCPoints` 已有 `static_assert(sizeof == 1 + 255*4)`;`ClassicParser`
|
> `wire_classic.h` 的 `GCPoints` 已有 `static_assert(sizeof == 1 + 255*4)`;`ClassicParser`
|
||||||
> 需在 `GC_CHARACTER_ADD[2]` / `GC_CHARACTER_UPDATE` 后调用 `mut_affect_flags()` 把
|
> 需在 `GC_CHARACTER_ADD[2]` / `GC_CHARACTER_UPDATE` 后调用 `mut_affect_flags()` 把
|
||||||
> `affect_flag[2]` 送进实体(`mut_char_update` 无 affect 形参,未接线)。G1 集成已接线(见下)。
|
> `affect_flag[2]` 送进实体(`mut_char_update` 无 affect 形参,未接线)。G1 集成已接线(见下)。
|
||||||
|
> - **2026-09-02 增量 50(Phase 1 W3 / §8.3 帮助窗)**:新增 `project/ui/help_ui.gd` —— 1:1
|
||||||
|
> 迁移 `assets/root/uihelp.py` 的 `HelpWindow`(单页版 `ENABLE_HELP_MULTIPAGE = 0` →
|
||||||
|
> `LoadDialogSinglePage`),布局走真 `assets/uiscript/uiscript/helpwindow.py`(UiScript →
|
||||||
|
> UiBuild),19 条浮动帮助行 + 10 个任务栏贴纸标签 + `close_button` 的文本逐字对齐
|
||||||
|
> `uiScriptLocale.HELP_*`(`locale/locale/en/locale_interface.txt`);`UiManager` 未接 locale
|
||||||
|
> 回调时 `helpwindow.py` 里的 `uiScriptLocale.X` 被解析成 `<X>` 占位,`_relabel()` 用本工程
|
||||||
|
> `Locale` 表 + 英文兜底补回(含原脚本重名的两个 `help_02`)。入口:`game_scene.gd`
|
||||||
|
> `_unhandled_input` 加单条 `elif`(`H` 且非 Ctrl / 非 Meta → `system_menu_ui.toggle_help()`;
|
||||||
|
> `Ctrl+H` 仍留给 `/user_horse_ride`);`system_menu_ui.gd` 的 `help_button` 由占位提示改为
|
||||||
|
> `close()` + `open_help()`,新增 `_ensure_help()` 懒建 / `open_help()` / `toggle_help()` 与
|
||||||
|
> 可注入的 `help_ui` 成员(`setup()` 追加可选第 6 参,旧 5 参调用不受影响)。新增
|
||||||
|
> `project/help_ui_test.gd`(helpwindow.py 装载 + 19 行逐字绑定 + 任务栏标签 + close_button +
|
||||||
|
> open/close/toggle + ESC 栈顶 + `SystemMenuUI.open_help()` 懒建)。`help_ui_test` /
|
||||||
|
> `system_menu_ui_test` / `gamescene_test` / `ui_test`(附加 `system_option_ui_test` /
|
||||||
|
> `char_status_ui_test`)全绿;本 worktree 无 `build/`,未跑 C++ `ctest`。视觉 / `.sub` 贴图
|
||||||
|
> 与真服未验证。
|
||||||
> - **2026-09-02 增量 49(W0 接口冻结批次)**:为 Phase 1 的 4 个并行工作流一次性落地跨工作流
|
> - **2026-09-02 增量 49(W0 接口冻结批次)**:为 Phase 1 的 4 个并行工作流一次性落地跨工作流
|
||||||
> 共享文件的骨架,冻结接口后再拆分。`EntityStore`:`Entity` 补 `empire / affect_flags /
|
> 共享文件的骨架,冻结接口后再拆分。`EntityStore`:`Entity` 补 `empire / affect_flags /
|
||||||
> owner_vid / state_flags` 字段;新增 `mut_spawn_full()`(§2.3 两包合并的单次落地入口)、
|
> owner_vid / state_flags` 字段;新增 `mut_spawn_full()`(§2.3 两包合并的单次落地入口)、
|
||||||
|
|||||||
@@ -603,6 +603,9 @@ func _unhandled_input(e: InputEvent) -> void:
|
|||||||
skills.toggle()
|
skills.toggle()
|
||||||
elif e.keycode in [KEY_V, KEY_C] and char_status_ui:
|
elif e.keycode in [KEY_V, KEY_C] and char_status_ui:
|
||||||
char_status_ui.toggle()
|
char_status_ui.toggle()
|
||||||
|
elif e.keycode == KEY_H and not e.ctrl_pressed and not e.meta_pressed and system_menu_ui:
|
||||||
|
# 参考端 game.py __PressHKey:非 Ctrl → interface.OpenHelpWindow()(Ctrl+H 是 /user_horse_ride)
|
||||||
|
system_menu_ui.toggle_help()
|
||||||
elif e.keycode == KEY_J and quest_log:
|
elif e.keycode == KEY_J and quest_log:
|
||||||
quest_log.toggle()
|
quest_log.toggle()
|
||||||
elif e.keycode == KEY_O and friend_ui:
|
elif e.keycode == KEY_O and friend_ui:
|
||||||
|
|||||||
@@ -0,0 +1,115 @@
|
|||||||
|
# help_ui_test —— §8.3 帮助窗 headless 自检(真 `helpwindow.py` uiscript + 假 client)。
|
||||||
|
# godot --headless --path project --script help_ui_test.gd
|
||||||
|
# 校验:helpwindow.py 装载、19 条帮助行 + 任务栏标签逐字绑定(对齐
|
||||||
|
# `locale/locale/en/locale_interface.txt` 的 `HELP_*`)、close_button、open/close/toggle、
|
||||||
|
# 以及 SystemMenuUI.open_help() 懒建并打开本窗。缺 uiscript 资产时优雅跳过。
|
||||||
|
extends SceneTree
|
||||||
|
|
||||||
|
const UiManager = preload("res://ui/ui_manager.gd")
|
||||||
|
const HelpUI = preload("res://ui/help_ui.gd")
|
||||||
|
const SystemMenuUI = preload("res://ui/system_menu_ui.gd")
|
||||||
|
|
||||||
|
class FakeClient extends Node:
|
||||||
|
func say(_type: int, _text: String) -> bool:
|
||||||
|
return true
|
||||||
|
|
||||||
|
var _fail := 0
|
||||||
|
func _ck(c: bool, m: String) -> void:
|
||||||
|
if not c:
|
||||||
|
_fail += 1
|
||||||
|
printerr("FAIL: " + m)
|
||||||
|
|
||||||
|
func _init() -> void:
|
||||||
|
_run()
|
||||||
|
if _fail == 0:
|
||||||
|
print("PASS: help_ui_test (helpwindow.py + HELP_* rows + close/open/toggle + SystemMenu.open_help)")
|
||||||
|
quit(0)
|
||||||
|
else:
|
||||||
|
printerr("%d check(s) failed" % _fail)
|
||||||
|
quit(1)
|
||||||
|
|
||||||
|
func _txt(hw: Node, nm: String) -> String:
|
||||||
|
var n: Control = hw._node(nm)
|
||||||
|
return String(n.text) if n and ("text" in n) else "<missing:%s>" % nm
|
||||||
|
|
||||||
|
func _run() -> void:
|
||||||
|
var assets := AssetRoot.path()
|
||||||
|
if not FileAccess.file_exists(assets.path_join("uiscript/uiscript/helpwindow.py")):
|
||||||
|
print(" (skip: no helpwindow.py — assets checkout missing)")
|
||||||
|
return
|
||||||
|
|
||||||
|
var ui: CanvasLayer = UiManager.new()
|
||||||
|
get_root().add_child(ui)
|
||||||
|
ui._ready()
|
||||||
|
var fc := FakeClient.new()
|
||||||
|
get_root().add_child(fc)
|
||||||
|
|
||||||
|
var hw: Node = HelpUI.new()
|
||||||
|
get_root().add_child(hw)
|
||||||
|
hw.setup(ui, fc, assets)
|
||||||
|
hw.open()
|
||||||
|
_ck(hw.is_open(), "help window opened")
|
||||||
|
if not hw.is_open():
|
||||||
|
return
|
||||||
|
|
||||||
|
# --- 19 条浮动帮助行都绑定且非占位 ---
|
||||||
|
var bound := 0
|
||||||
|
for i in range(1, 20):
|
||||||
|
var nm := "help_%02d" % i
|
||||||
|
var s := _txt(hw, nm)
|
||||||
|
_ck(not s.begins_with("<missing"), "%s node exists" % nm)
|
||||||
|
_ck(s.strip_edges() != "", "%s non-empty" % nm)
|
||||||
|
_ck(not (s.begins_with("<") and s.ends_with(">")), "%s not a <KEY> placeholder (got %s)" % [nm, s])
|
||||||
|
if not s.strip_edges().is_empty() and not (s.begins_with("<") and s.ends_with(">")):
|
||||||
|
bound += 1
|
||||||
|
_ck(bound == 19, "all 19 help rows bound (got %d)" % bound)
|
||||||
|
|
||||||
|
# --- 逐字对照 locale/locale/en/locale_interface.txt ---
|
||||||
|
_ck(_txt(hw, "help_01") == "Panel: W, A, S, D or arrow keys",
|
||||||
|
"help_01 = HELP_MOVE_KEY (got %s)" % _txt(hw, "help_01"))
|
||||||
|
_ck(_txt(hw, "help_06") == "Attack: left mouse button or space bar",
|
||||||
|
"help_06 = HELP_ATTACK_KEY (got %s)" % _txt(hw, "help_06"))
|
||||||
|
_ck(_txt(hw, "help_02") == "Camera View: middle or right mouse button",
|
||||||
|
"help_02 = HELP_CONTROL_CAMERA_BY_MIDDLEBUTTON (2nd dup wins) (got %s)" % _txt(hw, "help_02"))
|
||||||
|
_ck(_txt(hw, "help_19") == "Display help: H",
|
||||||
|
"help_19 = HELP_HELP (got %s)" % _txt(hw, "help_19"))
|
||||||
|
|
||||||
|
# --- 任务栏贴纸标签 ---
|
||||||
|
_ck(_txt(hw, "taskbar_help_02") == "Hit Points (HP)",
|
||||||
|
"taskbar_help_02 = HELP_HP (got %s)" % _txt(hw, "taskbar_help_02"))
|
||||||
|
_ck(_txt(hw, "taskbar_help_08b") == "(Character Window, Inventory Window,",
|
||||||
|
"taskbar_help_08b = HELP_CHARACTER_BUTTON1 (got %s)" % _txt(hw, "taskbar_help_08b"))
|
||||||
|
|
||||||
|
# --- close_button ---
|
||||||
|
var close_btn: Control = hw._node("close_button")
|
||||||
|
_ck(close_btn is BaseButton, "close_button is a button")
|
||||||
|
_ck(_txt(hw, "close_button") == "Close", "close_button text = Close (got %s)" % _txt(hw, "close_button"))
|
||||||
|
|
||||||
|
# --- rows() 便捷器 ---
|
||||||
|
var rows: Array = hw.rows()
|
||||||
|
_ck(rows.size() == 19, "rows() returns 19 entries (got %d)" % rows.size())
|
||||||
|
var all_nonempty := true
|
||||||
|
for r in rows:
|
||||||
|
if String(r).strip_edges().is_empty():
|
||||||
|
all_nonempty = false
|
||||||
|
_ck(all_nonempty, "rows() all non-empty")
|
||||||
|
|
||||||
|
# --- close_button 关窗 ---
|
||||||
|
close_btn.pressed.emit()
|
||||||
|
_ck(not hw.is_open(), "close_button closes help window")
|
||||||
|
|
||||||
|
# --- open / toggle / ESC 栈 ---
|
||||||
|
hw.toggle()
|
||||||
|
_ck(hw.is_open(), "toggle() re-opens help window")
|
||||||
|
_ck(ui.top() == hw._win.get("root"), "help window is top of UiManager stack (ESC closes it)")
|
||||||
|
hw.toggle()
|
||||||
|
_ck(not hw.is_open(), "toggle() closes help window")
|
||||||
|
|
||||||
|
# --- SystemMenuUI.open_help() 懒建并打开 ---
|
||||||
|
var sm: Node = SystemMenuUI.new()
|
||||||
|
get_root().add_child(sm)
|
||||||
|
sm.setup(ui, fc, assets)
|
||||||
|
sm.open_help()
|
||||||
|
_ck(is_instance_valid(sm.help_ui), "SystemMenuUI.open_help() lazily builds help_ui")
|
||||||
|
_ck(sm.help_ui.is_open(), "SystemMenuUI.open_help() opens the help window")
|
||||||
|
sm.help_ui.close()
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://c0k8knok8mik5
|
||||||
@@ -0,0 +1,197 @@
|
|||||||
|
# HelpUI (P11 / §8.3) —— 游戏内帮助窗(1:1 迁移 `assets/root/uihelp.py` 的
|
||||||
|
# `HelpWindow`,单页版:`ENABLE_HELP_MULTIPAGE = 0` → `LoadDialogSinglePage()`)。
|
||||||
|
#
|
||||||
|
# var hw := preload("res://ui/help_ui.gd").new()
|
||||||
|
# add_child(hw)
|
||||||
|
# hw.setup(ui_manager, m2client, assets_root)
|
||||||
|
# hw.toggle() # H 键(非 Ctrl)
|
||||||
|
# hw.open() # ESC 系统菜单 help_button
|
||||||
|
#
|
||||||
|
# 布局走真 `assets/uiscript/uiscript/helpwindow.py`(UiScript → UiBuild)。
|
||||||
|
# 文本逐字对齐 `uiScriptLocale.HELP_*`(`locale/locale/<lang>/locale_interface.txt`);
|
||||||
|
# `ui_manager` 没接 locale 回调时,`helpwindow.py` 里的 `uiScriptLocale.X` 会被
|
||||||
|
# UiScript 解析成 `<X>` 占位,`_relabel()` 再用本工程的 `Locale` 表 + 英文兜底补回。
|
||||||
|
#
|
||||||
|
# 入口逐字对照 `game.py:459 __PressHKey()`:非 Ctrl → `interface.OpenHelpWindow()`
|
||||||
|
# (Ctrl+H 是 `net.SendChatPacket("/user_horse_ride")`,不在本窗职责内)。
|
||||||
|
# 关闭对照 `helpwindow.py` 的 `HelpWindow`:`close_button` / `OnPressEscapeKey` /
|
||||||
|
# `OnPressExitKey` / `OnKeyDown(DIK_H)` 都调用 `eventClose`。ESC 由 `UiManager`
|
||||||
|
# 的窗口栈统一处理(关最顶层);H 键复用 `toggle()`。
|
||||||
|
extends Node
|
||||||
|
|
||||||
|
# helpwindow.py 的 name → uiScriptLocale key(逐字,含原脚本里重名的两个 `help_02`)。
|
||||||
|
const FLOAT_ROWS := {
|
||||||
|
"help_01": "HELP_MOVE_KEY",
|
||||||
|
"help_02": "HELP_CONTROL_CAMERA_BY_MIDDLEBUTTON", # 原脚本第二个 help_02(后者覆盖)
|
||||||
|
"help_03": "HELP_SHOW_ALL_NAME",
|
||||||
|
"help_04": "HELP_OPEN_CHAT",
|
||||||
|
"help_05": "HELP_OPEN_WHISPER",
|
||||||
|
"help_06": "HELP_ATTACK_KEY",
|
||||||
|
"help_07": "HELP_OPEN_CHARACTER",
|
||||||
|
"help_08": "HELP_OPEN_SKILL",
|
||||||
|
"help_09": "HELP_OPEN_QUEST",
|
||||||
|
"help_10": "HELP_OPEN_INVENTORY",
|
||||||
|
"help_11": "HELP_OPEN_LOG",
|
||||||
|
"help_12": "HELP_OPEN_ZONEMAP",
|
||||||
|
"help_13": "HELP_OPEN_MINIMAP",
|
||||||
|
"help_14": "HELP_CHANGE_PK_MODE",
|
||||||
|
"help_15": "HELP_PICK_ITEM",
|
||||||
|
"help_16": "HELP_SCREEN_CAPTURE",
|
||||||
|
"help_17": "HELP_GUILD_WINDOW",
|
||||||
|
"help_18": "HELP_MESSENGER_WINDOW",
|
||||||
|
"help_19": "HELP_HELP",
|
||||||
|
}
|
||||||
|
|
||||||
|
# 任务栏贴纸标签(helpwindow.py 的 `taskbar_help_*` 文本)。
|
||||||
|
const TASKBAR_ROWS := {
|
||||||
|
"taskbar_help_01": "HELP_FURY",
|
||||||
|
"taskbar_help_02": "HELP_HP",
|
||||||
|
"taskbar_help_03": "HELP_SP",
|
||||||
|
"taskbar_help_04": "HELP_EXP",
|
||||||
|
"taskbar_help_05": "HELP_MOUSE_LEFT",
|
||||||
|
"taskbar_help_06": "HELP_MOUSE_RIGHT",
|
||||||
|
"taskbar_help_07": "HELP_QUICKSLOT",
|
||||||
|
"taskbar_help_08a": "HELP_SYSTEM_BUTTON",
|
||||||
|
"taskbar_help_08b": "HELP_CHARACTER_BUTTON1",
|
||||||
|
"taskbar_help_08c": "HELP_CHARACTER_BUTTON2",
|
||||||
|
}
|
||||||
|
|
||||||
|
# uiScriptLocale 兜底(逐字取自 `locale/locale/en/locale_interface.txt`)——
|
||||||
|
# 资产缺 locale 表或 UiManager 没接 locale 回调时用这份。
|
||||||
|
const FALLBACK := {
|
||||||
|
"HELP_MOVE_KEY": "Panel: W, A, S, D or arrow keys",
|
||||||
|
"HELP_CONTROL_CAMERA_BY_RIGHTBUTTON": "Camera View: right or middle mouse button",
|
||||||
|
"HELP_CONTROL_CAMERA_BY_MIDDLEBUTTON": "Camera View: middle or right mouse button",
|
||||||
|
"HELP_SHOW_ALL_NAME": "Display Names: Alt",
|
||||||
|
"HELP_OPEN_CHAT": "Open chat window: Enter",
|
||||||
|
"HELP_OPEN_WHISPER": "Open Whisper Window: Shift + Enter",
|
||||||
|
"HELP_ATTACK_KEY": "Attack: left mouse button or space bar",
|
||||||
|
"HELP_OPEN_CHARACTER": "Open character window: C",
|
||||||
|
"HELP_OPEN_SKILL": "Open Skill Window: V",
|
||||||
|
"HELP_OPEN_QUEST": "Open Task Window: N",
|
||||||
|
"HELP_OPEN_INVENTORY": "Open inventory window: I",
|
||||||
|
"HELP_OPEN_LOG": "Open Chatlog: L",
|
||||||
|
"HELP_OPEN_ZONEMAP": "Open Large Map: M",
|
||||||
|
"HELP_OPEN_MINIMAP": "Open mini map: Shift + M",
|
||||||
|
"HELP_CHANGE_PK_MODE": "Change attack mode: change setting of left mouse button",
|
||||||
|
"HELP_PICK_ITEM": "Collect Items: ^ or Y or left mouse button",
|
||||||
|
"HELP_SCREEN_CAPTURE": "Save Screenshot: Print (will be saved in file \"Metin2\\screenshot\")",
|
||||||
|
"HELP_GUILD_WINDOW": "Open Guild Window: Alt + G",
|
||||||
|
"HELP_MESSENGER_WINDOW": "Open Friends List: Alt + M",
|
||||||
|
"HELP_HELP": "Display help: H",
|
||||||
|
"HELP_FURY": "Ingame Item Shop",
|
||||||
|
"HELP_HP": "Hit Points (HP)",
|
||||||
|
"HELP_SP": "Spell Points (SP)",
|
||||||
|
"HELP_EXP": "Experience",
|
||||||
|
"HELP_MOUSE_LEFT": "Function of the Left Mouse button",
|
||||||
|
"HELP_MOUSE_RIGHT": "Function of the Right Mouse button",
|
||||||
|
"HELP_QUICKSLOT": "Fast Access Fields",
|
||||||
|
"HELP_SYSTEM_BUTTON": "System buttons",
|
||||||
|
"HELP_CHARACTER_BUTTON1": "(Character Window, Inventory Window,",
|
||||||
|
"HELP_CHARACTER_BUTTON2": "List of Friends and Options)",
|
||||||
|
"CLOSE": "Close",
|
||||||
|
}
|
||||||
|
|
||||||
|
var ui: CanvasLayer
|
||||||
|
var client: Node
|
||||||
|
var assets_root := ""
|
||||||
|
var uiscript_dir := ""
|
||||||
|
|
||||||
|
var _win: Dictionary = {}
|
||||||
|
var _loc # Locale(res://locale.gd)
|
||||||
|
|
||||||
|
func setup(ui_manager: CanvasLayer, m2client: Node = null, assets := "") -> void:
|
||||||
|
ui = ui_manager
|
||||||
|
client = m2client
|
||||||
|
assets_root = assets
|
||||||
|
if assets_root == "" and ui and "assets_root" in ui:
|
||||||
|
assets_root = ui.assets_root
|
||||||
|
uiscript_dir = assets_root.path_join("uiscript/uiscript")
|
||||||
|
if not DirAccess.dir_exists_absolute(uiscript_dir):
|
||||||
|
uiscript_dir = assets_root.path_join("uiscript")
|
||||||
|
var LocaleScript = load("res://locale.gd")
|
||||||
|
if LocaleScript:
|
||||||
|
_loc = LocaleScript.new()
|
||||||
|
_loc.setup(assets_root, "en")
|
||||||
|
|
||||||
|
# --- open / close ---------------------------------------------------
|
||||||
|
|
||||||
|
func is_open() -> bool:
|
||||||
|
return not _win.is_empty() and is_instance_valid(_win.get("root"))
|
||||||
|
|
||||||
|
func toggle() -> void:
|
||||||
|
if is_open(): close()
|
||||||
|
else: open()
|
||||||
|
|
||||||
|
func close() -> void:
|
||||||
|
if is_open():
|
||||||
|
ui.close(_win["root"])
|
||||||
|
_win = {}
|
||||||
|
|
||||||
|
func open() -> void:
|
||||||
|
if is_open():
|
||||||
|
return
|
||||||
|
var path := uiscript_dir.path_join("helpwindow.py")
|
||||||
|
if not FileAccess.file_exists(path):
|
||||||
|
push_warning("HelpUI: no helpwindow.py at " + path)
|
||||||
|
return
|
||||||
|
_win = ui.open_script(path, assets_root)
|
||||||
|
if not is_open():
|
||||||
|
return
|
||||||
|
_relabel()
|
||||||
|
_wire()
|
||||||
|
|
||||||
|
func _node(nm: String) -> Control:
|
||||||
|
if _win.is_empty():
|
||||||
|
return null
|
||||||
|
var n = _win.get("nodes", {}).get(nm, null)
|
||||||
|
return n if n is Control else null
|
||||||
|
|
||||||
|
# --- content (uihelp.py.LoadDialogSinglePage + helpwindow.py 文本) ---------
|
||||||
|
|
||||||
|
# 解析 `<KEY>` 占位 / 应用 name→key 映射:先扫所有 Label(覆盖原脚本重名的两个
|
||||||
|
# `help_02`),再按映射兜一遍(nodes dict 只留最后一个同名)。
|
||||||
|
func _relabel() -> void:
|
||||||
|
var root: Control = _win.get("root")
|
||||||
|
if root:
|
||||||
|
for lbl in root.find_children("*", "Label", true, false):
|
||||||
|
var t := String(lbl.text)
|
||||||
|
if t.length() >= 2 and t.begins_with("<") and t.ends_with(">"):
|
||||||
|
lbl.text = _text(t.substr(1, t.length() - 2))
|
||||||
|
for nm in FLOAT_ROWS:
|
||||||
|
_set_text(nm, _text(FLOAT_ROWS[nm]))
|
||||||
|
for nm in TASKBAR_ROWS:
|
||||||
|
_set_text(nm, _text(TASKBAR_ROWS[nm]))
|
||||||
|
_set_text("close_button", _text("CLOSE"))
|
||||||
|
|
||||||
|
func _set_text(nm: String, s: String) -> void:
|
||||||
|
var n := _node(nm)
|
||||||
|
if n == null:
|
||||||
|
return
|
||||||
|
if n.has_method("set_text"):
|
||||||
|
n.set_text(s)
|
||||||
|
elif "text" in n:
|
||||||
|
n.text = s
|
||||||
|
|
||||||
|
# uiScriptLocale.<key> 的取值:优先本工程 Locale 表,否则英文兜底,否则原样 key。
|
||||||
|
func _text(key: String) -> String:
|
||||||
|
if _loc != null and _loc.has(key):
|
||||||
|
return _loc.t(key)
|
||||||
|
return FALLBACK.get(key, key)
|
||||||
|
|
||||||
|
# 已绑定的帮助行文本(供自检 / 调试)。
|
||||||
|
func rows() -> Array:
|
||||||
|
var out: Array = []
|
||||||
|
for nm in FLOAT_ROWS:
|
||||||
|
var n := _node(nm)
|
||||||
|
if n and "text" in n:
|
||||||
|
out.append(String(n.text))
|
||||||
|
return out
|
||||||
|
|
||||||
|
# --- wiring (uihelp.py.HelpWindow.SetCloseEvent) ------------------------
|
||||||
|
|
||||||
|
func _wire() -> void:
|
||||||
|
var btn := _node("close_button")
|
||||||
|
if btn is BaseButton:
|
||||||
|
btn.pressed.connect(close)
|
||||||
|
# helpwindow.py2 的多页按钮在单页版不存在;此处不绑。
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://dfoy732rqh7hd
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
# sm.toggle() # ESC(无其它窗打开时)
|
# sm.toggle() # ESC(无其它窗打开时)
|
||||||
#
|
#
|
||||||
# 按钮绑定逐字对照 uisystem.py:
|
# 按钮绑定逐字对照 uisystem.py:
|
||||||
# help_button → OpenHelpWindow(暂无帮助窗 → 提示)
|
# help_button → interface.OpenHelpWindow(help_ui.gd,§8.3)
|
||||||
# mall_button → net.SendChatPacket("/in_game_mall")
|
# mall_button → net.SendChatPacket("/in_game_mall")
|
||||||
# system_option_button → uiSystemOption.OptionDialog(system_option_ui)
|
# system_option_button → uiSystemOption.OptionDialog(system_option_ui)
|
||||||
# game_option_button → uiGameOption.OptionDialog(game_option_ui)
|
# game_option_button → uiGameOption.OptionDialog(game_option_ui)
|
||||||
@@ -17,6 +17,8 @@
|
|||||||
# cancel_button / 标题栏 → 关闭
|
# cancel_button / 标题栏 → 关闭
|
||||||
extends Node
|
extends Node
|
||||||
|
|
||||||
|
const HelpUI = preload("res://ui/help_ui.gd")
|
||||||
|
|
||||||
const LABELS := {
|
const LABELS := {
|
||||||
"help_button": "帮助", "mall_button": "商城", "system_option_button": "系统设置",
|
"help_button": "帮助", "mall_button": "商城", "system_option_button": "系统设置",
|
||||||
"game_option_button": "游戏设置", "change_button": "选择角色", "logout_button": "登出",
|
"game_option_button": "游戏设置", "change_button": "选择角色", "logout_button": "登出",
|
||||||
@@ -29,16 +31,18 @@ var assets_root := ""
|
|||||||
var uiscript_dir := ""
|
var uiscript_dir := ""
|
||||||
var system_option_ui: Node
|
var system_option_ui: Node
|
||||||
var game_option_ui: Node
|
var game_option_ui: Node
|
||||||
|
var help_ui: Node # HelpUI(§8.3)—— 未注入时 _ensure_help() 懒建
|
||||||
var toast: Callable = Callable() # 可选:func(msg: String) 显示提示
|
var toast: Callable = Callable() # 可选:func(msg: String) 显示提示
|
||||||
|
|
||||||
var _win: Dictionary = {}
|
var _win: Dictionary = {}
|
||||||
|
|
||||||
func setup(ui_manager: CanvasLayer, m2client: Node, assets := "",
|
func setup(ui_manager: CanvasLayer, m2client: Node, assets := "",
|
||||||
sys_opt: Node = null, game_opt: Node = null) -> void:
|
sys_opt: Node = null, game_opt: Node = null, help_win: Node = null) -> void:
|
||||||
ui = ui_manager
|
ui = ui_manager
|
||||||
client = m2client
|
client = m2client
|
||||||
system_option_ui = sys_opt
|
system_option_ui = sys_opt
|
||||||
game_option_ui = game_opt
|
game_option_ui = game_opt
|
||||||
|
help_ui = help_win
|
||||||
assets_root = assets
|
assets_root = assets
|
||||||
if assets_root == "" and ui and "assets_root" in ui:
|
if assets_root == "" and ui and "assets_root" in ui:
|
||||||
assets_root = ui.assets_root
|
assets_root = ui.assets_root
|
||||||
@@ -88,11 +92,25 @@ func _btn(nm: String, cb: Callable) -> void:
|
|||||||
if b is BaseButton:
|
if b is BaseButton:
|
||||||
b.pressed.connect(cb)
|
b.pressed.connect(cb)
|
||||||
|
|
||||||
|
# uisystem.py: self.interface.OpenHelpWindow()。未注入 help_ui 时懒建一个,
|
||||||
|
# 复用本菜单的 ui / client / assets_root。
|
||||||
|
func _ensure_help() -> Node:
|
||||||
|
if not is_instance_valid(help_ui):
|
||||||
|
help_ui = HelpUI.new()
|
||||||
|
add_child(help_ui)
|
||||||
|
help_ui.setup(ui, client, assets_root)
|
||||||
|
return help_ui
|
||||||
|
|
||||||
|
func open_help() -> void:
|
||||||
|
_ensure_help().open()
|
||||||
|
|
||||||
|
func toggle_help() -> void:
|
||||||
|
_ensure_help().toggle()
|
||||||
|
|
||||||
func _wire() -> void:
|
func _wire() -> void:
|
||||||
_btn("help_button", func():
|
_btn("help_button", func():
|
||||||
if toast.is_valid():
|
close()
|
||||||
toast.call("帮助窗暂未实现")
|
open_help())
|
||||||
)
|
|
||||||
_btn("mall_button", func():
|
_btn("mall_button", func():
|
||||||
if client and client.has_method("say"):
|
if client and client.has_method("say"):
|
||||||
client.say(0, "/in_game_mall") # net.SendChatPacket("/in_game_mall")
|
client.say(0, "/in_game_mall") # net.SendChatPacket("/in_game_mall")
|
||||||
|
|||||||
Reference in New Issue
Block a user