- item_tooltip_view.gd: 新增 avoid_rect 属性,tooltip 与装备窗口重叠时自动推到左侧 - inventory_ui.gd: 悬停装备时传入窗口矩形作为避让区域 - 包含其他累积的功能开发和测试文件
99 lines
11 KiB
Markdown
99 lines
11 KiB
Markdown
# ui.hud_target_minimap_status —— 角色状态、目标框、小地图、文本尾标和快捷栏
|
||
|
||
状态:`PARTIAL`
|
||
|
||
本合同检查 HUD 的数据源、UI 实例注册、刷新顺序、目标类型分派、HP/EXP/等级、名字尾标、聊天气泡、小地图标记/缩放、快捷栏和死亡/删除/换图清理。静态模块测试通过,只能证明局部 helper;正式 `GameScene` 中实际创建了哪些控件、信号是否接通、旧控件是否重复显示,必须单独核对。
|
||
|
||
## 40250 参考调用链
|
||
|
||
- `UserInterface/PythonApplication.cpp` / `PythonApplication.h`
|
||
- 每帧按应用渲染顺序更新 PythonPlayer、TextTail、Effect 和 UI;TextTail 先刷新全部尾标,再显示目标/拾取/全显尾标,最后更新显示和排布。
|
||
- `UserInterface/PythonPlayer.cpp` / `PythonPlayer.h`
|
||
- `SetStatus` 写入带保护的点数组;等级变化同步 `CInstanceBase::SetLevel` 和等级尾标,战斗点变化触发派生战斗状态重算。
|
||
- `SetQuickPage` 按 `QUICKSLOT_MAX_LINE` 环绕,快捷栏按全局槽位保存,使用时区分 inventory/skill/emotion 并经网络发送。
|
||
- 目标死亡、删除和不可选中时清理目标;`UpdatePartyMemberInfo/Affect` 更新队伍状态和头像/尾标数据。
|
||
- `UserInterface/PythonTextTail.cpp` / `.h`
|
||
- 维护角色、聊天、信息、掉落尾标的 map/list/pool;角色尾标由 `RegisterCharacterTextTail` 建立,按 guild/title/level 资源更新;聊天尾标 5000ms 到期,`bNameFlag` 会强显名字并把名字上移 17px;物品尾标按屏幕 AABB 互相下推。
|
||
- `DeleteCharacterTextTail`、死亡分支和地图清理必须同时删除角色名、公会/称号/等级、聊天和物品 owner 子实例。
|
||
- `UserInterface/PythonMiniMap.cpp` / `.h`
|
||
- 默认 `m_fScale=2.0`,`SetScale` 范围 `[0.5,4.0]`,ScaleUp/Down 分别乘 2/0.5;以 terrain cell/cm 坐标计算玩家、PC、怪物、NPC/warp、observer、guild area、waypoint/target mark 和玩家朝向。
|
||
- `__SetPosition`、`Render`、地图中心及点击拾取都使用同一 scale/terrain-cell 单位,并按边缘半径处理超出地图的 waypoint。
|
||
- `UserInterface/PythonPlayer.cpp`、`PythonApplication.cpp`、`uitaskbar.py` / `uicharacter.py` / `uitarget.py`
|
||
- TaskBar/CharacterWindow/TargetBoard 由统一 UI 入口创建并接收 points、target、quickslot、party 和 entity 删除事件,不允许只保留“存在但未注入”的独立控件。
|
||
|
||
## 当前端实现映射
|
||
|
||
- `project/net_play.gd` / `project/hud.gd` / `project/ui/quickbar.gd`
|
||
- native `points_changed`/`vitals_changed`/`target_info` 已接入 NetPlay;NetPlay 将 HP/SP/ST/EXP/等级写入 HUD,Quickbar 自己也订阅 `points_changed` 并绘制 4 段经验珠、HP/SP/ST 和 36 槽服务端快捷栏。
|
||
- `hud.gd::_build_status()` 已经是空实现,旧 HUD 的 setters 只有在 Quickbar 存在时才产生可见效果;这是一次“数据链存在但显示 owner 分散”的适配层。
|
||
- `project/ui/target_board.gd` / `project/ui/target_ui.gd`
|
||
- `target_board.gd` 已镜像 `RecvTargetPacket` 的 CLOSE/CLOSE_IF_DIFFERENT/SET_HP/NONE 判定,`target_ui.gd` 已实现宽度、等级/阶级前缀、HP、PC 操作按钮和关闭回调。
|
||
- 但正式 `project/game_scene.gd` 只把 `target_changed` 连接到 `net_world.set_target_vid`,没有创建 `target_ui.gd` 实例,也没有设置 `net_play.target_ui`;实际运行的目标面板退回 `hud.gd` 的简化 200×40 面板,缺少 40250 TargetBoard 的运行链。
|
||
- `project/net_world.gd` / `project/text_tail.gd` / `project/text_tail_arrange.gd` / `project/chat_tail.gd`
|
||
- 已实现角色名字、guild/title/level、guild mark、聊天/信息尾标、5000ms 生命周期、目标/悬停强显和掉落名条 AABB 排布;测试覆盖了静态颜色、标题、聊天和物品尾标 helper。
|
||
- 当前 `CanPickInstance` 仍用存活/墙体近似,尾标强制显示和名字可见性整表刷新约 2Hz,而 40250 在渲染帧内按实例资格和 list 重建;真实字体/Label3D 像素度量也有 fallback 近似。
|
||
- `project/ui/minimap.gd` / `project/hud.gd` / `project/game_scene.gd`
|
||
- `minimap.gd` 已绘制实体、NPC/warp、observer、guild area、quest signal、target marker、坐标和玩家箭头,并连接 channel/world reset;`hud.gd` 另有一套基于 `minimap.dds` 的旧地图贴图与玩家点。
|
||
- 正式 `GameScene` 同时调用 `hud.setup()`(创建旧 minimap)和 `minimap.setup()`(创建新雷达),没有销毁/隐藏其中一套,存在重复小地图;新雷达 scale 默认 0.25、范围 0.10–1.25、按钮步进 ±0.05/滚轮 1.15,与 40250 默认 2.0、范围 0.5–4.0、按钮 ×2/×0.5 的行为和单位不一致。
|
||
- `project/ui/char_status_ui.gd`
|
||
- 已支持状态/技能/表情/任务页、points 读取、装备/技能资源、加点命令和移动端页;`char_status_ui_test.gd` 证明基础布局/刷新/Tab/加点路径。
|
||
|
||
## 分支等价矩阵
|
||
|
||
| 40250 判据/副作用 | 当前实现 | 结论 |
|
||
|---|---|---|
|
||
| points/status → TaskBar HP/SP/ST/EXP/等级刷新 | NetPlay 和 Quickbar 都可接收 points,Quickbar 绘制主要仪表 | 部分等价;HUD 状态 owner 分散,`_build_status()` 空实现,等级/旧 setter 的可见链没有统一快照 |
|
||
| QuickSlot 全局槽位、页切换、inventory/skill/emotion 分派 | `_state` 36 槽、4×8 页、服务端恢复和激活分支存在 | 基础路径通过;最后 4 个服务端槽、物品引用失效、死亡/变身门控和资源图标完整时序仍需 live packet 证据 |
|
||
| `RecvTargetPacket` 按 PC/building/stone/enemy/NPC/死亡分派 | `target_board.gd` 和 `net_play._on_target_info` 静态/单测通过 | 判定 helper 基本等价;生产 `target_ui` 未实例化注入,实际 UI 运行链不等价 |
|
||
| TargetBoard 宽度、等级/阶级、HP、PC 私聊/交易/装备按钮 | `ui/target_ui.gd` 单测通过 | 代码存在但正式场景未挂载;当前可见 HUD 面板是简化实现 |
|
||
| 角色 guild/title/level、聊天/信息尾标、5000ms 回收 | `net_world` + TextTail/ChatTail + 2Hz 可见性刷新 | 部分等价;`CanPickInstance`、逐帧 list 生命周期、字体真实度量和死亡/删除全链仍有近似 |
|
||
| 掉落物 owner 名、AABB 去重叠和拾取 | `ground_items` + `text_tail_arrange` | helper 通过;实际投影、字体、删除和鼠标拾取尚未与 native 渲染逐像素对照 |
|
||
| 小地图 scale、地形单位、玩家/实体/observer/waypoint/target/guild mark | 新 `minimap.gd` 覆盖大部分标记和 observer 插值 | 不等价;scale 常量/步进/单位不同,且 HUD 与新 Minimap 同时显示两套地图 |
|
||
| 场景创建、目标/小地图/尾标的统一 owner | GameScene 分散创建 HUD、Minimap、NetWorld、NetPlay | 不等价;TargetUI 漏接入,MiniMap 重复创建,跨图/退出时 UI 节点清理未形成统一证据 |
|
||
| 角色死亡、实体删除、换图清理 | NetWorld 清理 HP bars、尾标、target、实体;NetPlay 清理 target | 部分等价;需补生产场景级删除/换图后无重复 UI、无悬挂 signal 的测试 |
|
||
|
||
## 已执行测试
|
||
|
||
- `project/test_target_board_parity.gd`:13 passed、0 failed;覆盖 TargetBoard 尺寸、HP、关闭回调和手工注入 `target_ui` 的 NetPlay 分派。
|
||
- `project/target_board_test.gd`:通过;覆盖目标分类、死亡、异阵营和 LCONTROL 私聊分支。
|
||
- `project/test_minimap_radar_parity.gd`:6 passed、0 failed;`project/p9_test.gd` 通过;只证明新雷达坐标、按钮、Atlas 信号和基础 world/observer 路径,不检测 GameScene 同时存在两套 minimap,也没有校验 40250 scale 常量。
|
||
- `project/text_tail_test.gd`、`project/text_tail_arrange_test.gd`、`project/chat_tail_test.gd`、`project/chat_test.gd`、`project/name_show_test.gd`:均通过;这些是 helper/路由测试,未证明完整 native 渲染帧顺序和 `CanPickInstance` 等价。
|
||
- `project/char_status_ui_test.gd`:通过;覆盖布局、状态刷新、加点和分页。
|
||
- `project/test_taskbar_quickslot_parity.gd`:34 passed、0 failed;Quickbar/TaskBar 断言通过,但进程报告 221 个 ObjectDB、91 个 CanvasItem RID、3 个资源仍在使用,不能作为稳定清理证据。
|
||
- `project/taskbar_dock_test.gd`:通过;覆盖任务栏按钮、角色窗 Tab 和安全箱窗口。
|
||
|
||
## Deep audit round 2026-09-21
|
||
|
||
### Fresh regression results
|
||
|
||
- `test_target_board_parity.gd` 13/13、`target_board_test.gd`、`test_minimap_radar_parity.gd` 6/6、`p9_test.gd`、`text_tail_test.gd`、`text_tail_arrange_test.gd`、`chat_tail_test.gd`、`chat_test.gd`、`name_show_test.gd`、`char_status_ui_test.gd`、`taskbar_dock_test.gd` 均退出码 0。
|
||
- `test_taskbar_quickslot_parity.gd` 34/34,但退出时仍有 221 个 ObjectDB、91 个 CanvasItem RID、3 个资源、56 个 shaped-text RID 和 1 个 font RID 泄漏。
|
||
|
||
### Static parity conclusion
|
||
|
||
- TargetBoard 单测和手工注入的 `target_ui` 分派通过,但正式 `GameScene` 仍未实例化/注入唯一 TargetUI,实际显示路径仍可能回落到 HUD 简化目标条。
|
||
- HUD 与新 minimap 仍是两套生产 owner;新雷达的 scale 默认/范围/步进与 40250 的 2.0、0.5–4.0、×2/×0.5 不一致。
|
||
- TextTail、血条、快捷栏和角色状态 helper 可用,但逐帧显示顺序、真实字体度量、删除/死亡/换图清理和统一 points/target/quickslot owner 仍未闭合。
|
||
|
||
本轮仍为 `PARTIAL`,完成 HUD/目标框/小地图/尾标第二轮证据登记,未修改实现。
|
||
|
||
## 已确认差异和未验证项
|
||
|
||
1. 在正式 GameScene 创建并注入唯一的 `TargetUI`,将 `NetPlay.target_ui` 的 open/set_hp/close 与 TargetBoard 分派接通;再移除/隐藏 HUD 简化目标条,避免两个目标面板 owner。
|
||
2. 只保留一套生产小地图,统一参考端的 scale/terrain-cell 单位、默认值、上下限、按钮倍率、滚轮和地图/雷达切换行为。
|
||
3. 将 points、quickslot、target、party、entity delete、world reset 的 UI 更新集中到可观测 owner,补生产场景级重复创建、换图、死亡、重连和退出清理测试。
|
||
4. 逐帧对照 TextTail 的 `UpdateAllTextTail → Show* → UpdateShowingTextTail → ArrangeTextTail`,消除 `CanPickInstance` 近似、2Hz 可见性延迟和 Label3D 字体度量 fallback。
|
||
5. 补真实资源/网络包驱动的 HP/EXP/等级/快捷栏/小地图 marker 测试;修复 Quickbar 测试的 ObjectDB/RID/resource cleanup。
|
||
|
||
## 下一轮验证入口
|
||
|
||
- 先修复/验证 GameScene 的 TargetUI 单例注入和旧 HUD 目标条去重。
|
||
- 再以一个地图、一个远端 PC、一个敌对怪、一个 NPC/warp、一个 observer 和一条 quest waypoint 采集新旧客户端同帧 UI 快照。
|
||
- 最后验证 mini-map scale 边界、实体删除/死亡/换图/重连后的尾标、血条、目标框和小地图无残留。
|
||
|
||
## Active UserInterface minimap and text-tail bridge review
|
||
|
||
- `PythonMiniMapModule.cpp` 暴露小地图 scale/center/size、创建/销毁/更新/拾取、atlas、waypoint、guild area 和地图 marker;这些状态依赖地图坐标、地形/atlas 资源和实体删除顺序。
|
||
- `PythonTextTailModule.cpp` 暴露角色/聊天/信息尾标注册、标题颜色、投影位置、显示/隐藏、排列和 pick;生产更新必须先更新全部尾标,再更新可见集合和排列,不能由单个 Label3D 的定时器替代。
|
||
- 当前端 minimap/text-tail 有 helper 和局部布局测试,但生产 owner、marker/waypoint 删除、实体重置、投影失败和资源字体度量未闭合;本轮纳入 active source 证据,合同继续 `PARTIAL`。
|