- item_tooltip_view.gd: 新增 avoid_rect 属性,tooltip 与装备窗口重叠时自动推到左侧 - inventory_ui.gd: 悬停装备时传入窗口矩形作为避让区域 - 包含其他累积的功能开发和测试文件
89 lines
10 KiB
Markdown
89 lines
10 KiB
Markdown
# world.dungeon_activity
|
||
|
||
## Scope
|
||
|
||
审计 `GC_DUNGEON` 目标点、地下城事件/计时、`DUNGEON_RESULT` 结果窗口、地图导航提示、镜头/屏幕效果,以及当前端额外提供的 Boss、排行和具体副本 helper。判断标准是当前端是否复现 40250 Windows 客户端的协议字段、目标点状态、到达/重复提示、结果展示和中断清理;服务端才拥有副本奖励、Boss 血量、排行和副本规则,当前端本地计算这些内容不能作为 40250 客户端 parity 证明。
|
||
|
||
## Reference call chain
|
||
|
||
- `UserInterface/PythonNetworkStreamPhaseGame.cpp`
|
||
- `RecvDungeon` 读取 `TPacketGCDungeon`;`TIME_ATTACK_START` 分支在 40250 中不启动本地计时,`DESTINATION_POSITION` 读取两个坐标并调用 `CPythonPlayer::SetDungeonDestinationPosition`。
|
||
- `PythonEventManager.cpp` 的 `DUNGEON_RESULT` 分支把九个整数交给 `interface.ShowDungeonResult`;客户端展示结果,不在此处结算奖励。
|
||
- `UserInterface/PythonPlayer.cpp` / `PythonPlayer.h`
|
||
- `SetDungeonDestinationPosition` 保存全局像素/厘米目标,立即调用 `AlarmHaveToGo`;更新时用整数 Manhattan 距离判断 `< 10000` 到达,未到达且超过 20 秒再次提示,并在到达时清空目标。
|
||
- `AlarmHaveToGo` 创建 `effect/etc/compass/appear_middle.mse`,朝目标方向旋转罗盘提示。
|
||
- `UserInterface/PythonEventManager.cpp` / `GameLib/GameEventManager.cpp`
|
||
- 事件窗口负责结果 UI、等待和清理;`GameEventManager` 的相关路径是屏幕波动/运动效果,不是 Boss 或排行 authority。
|
||
- `GameLib/MapManager.cpp` / `Packet.h` / `PythonNetworkStreamPhaseGame.h`
|
||
- 提供地图/副本协议常量和包布局;副本目标与结果由服务端包驱动,客户端没有本地奖励、Boss HP 或排行榜结算。
|
||
|
||
## Current call chain
|
||
|
||
- native `EntityStore::apply` 已解析 `GC_DUNGEON` 的 subheader 和目标坐标;`M2Client::poll` 发出 `dungeon_event`,`M2Client::request_dungeon`/`ClassicSession::send_dungeon` 能发送请求。
|
||
- `project/dungeon_state.gd` 已实现 `TIME_ATTACK_START` 不启动本地计时、目标坐标转换、立即提示、10,000 cm Manhattan 到达阈值、20 秒重复 alarm、到达清理和 `world_reset` 清理。
|
||
- `project/ui/dungeon_result_ui.gd` 已接收九个字段并呈现击杀、隐藏目标、药水、复活、完成、时间和经验等结果;`game_scene.gd` 已连接 `dungeon_result_requested`。
|
||
- `project/world_boss_system.gd`、`project/dungeon_ranking_system.gd`、`project/spider_dungeon_system.gd`、`project/flame_dungeon_razador_system.gd`、`project/endless_spire_dungeon_system.gd` 是当前端额外的本地规则/authority helper。40250 Windows 客户端没有对应的本地 Boss HP、掉落、排行或副本奖励实现,不能把这些 helper 的单元测试当成 parity PASS。
|
||
|
||
## Branch matrix
|
||
|
||
| 场景 | 40250 | 当前端 | 结论 |
|
||
|---|---|---|---|
|
||
| 地下城请求 | `__CanActMainInstance`/游戏阶段检查后发送对应请求;结果由服务端包驱动 | native 只做 `is_in_game` 和 session send;没有完整动作门控、请求去重和拒绝回滚证据 | PARTIAL |
|
||
| `TIME_ATTACK_START` | `RecvDungeon` 消费包但分支为空,不凭客户端包启动计时 | `DungeonState` 记录 subheader 但不启动本地计时 | PASS(已覆盖的分支) |
|
||
| 目标点回包 | 读取 x/y→`SetDungeonDestinationPosition`→立即 compass alarm | `GC_DUNGEON`→`dungeon_event`→坐标转换→`destination_changed` 和 `alarm_requested` | PARTIAL:协议/状态接近,但 alarm 没有在 `game_scene.gd` 接到实际 compass/effect 消费者 |
|
||
| 目标点重复提示 | 未到达时每 20 秒 `AlarmHaveToGo`,使用参考 `.mse` 资源并按目标方向旋转 | `DungeonState` 每 20 秒发 `alarm_requested`,但当前没有实际资源效果调用 | GAP:信号存在,视觉副作用缺失 |
|
||
| 目标到达 | Manhattan `< 10000` 后清除目标并停止提示 | 同阈值和清理信号已实现 | PASS(状态算法) |
|
||
| 地图切换/断线 | 玩家状态重置并清理目标提示 | `world_reset` 清理目标;实际断线、重连、旧包乱序未完整验证 | PARTIAL |
|
||
| 副本结果 | `DUNGEON_RESULT` 九个整数交给 `ShowDungeonResult`,仅展示服务端结果 | `QuestDialog` 发 `dungeon_result_requested`,`DungeonResultUI` 展示九字段 | PARTIAL:展示链存在,但真实 `DUNGEON_RESULT`→UI 回包和关闭/重复/中断未端到端覆盖 |
|
||
| 奖励、Boss、排行 | 客户端不计算副本奖励、Boss HP、掉落或排行榜权威 | 本地 helper 直接推进 Boss 阶段/掉落/库存奖励和排行统计 | GAP(custom authority):与 40250 客户端职责不一致 |
|
||
| 屏幕波动/地图事件 | `GameEventManager` 处理屏幕波动和运动事件 | 当前副本合同没有证明该引用链的实际资源/中断效果 | PARTIAL:不能用 Boss/排行 helper 代替原版事件效果 |
|
||
|
||
## Implementation-equivalence matrix
|
||
|
||
| 项目 | 状态 | 证据/限制 |
|
||
|---|---|---|
|
||
| Preconditions | PARTIAL | native 游戏阶段、包长度和目标字段检查存在;请求动作门控、重复请求、服务器拒绝和活动阶段限制未与 40250 等价证明 |
|
||
| Branch structure | PARTIAL | dungeon subheader、目标、到达、结果主分支存在;alarm 没有实际 compass 消费者,结果回包和中断分支证据不足 |
|
||
| Algorithms/formulas | PARTIAL | 目标坐标转换、10,000 cm Manhattan 阈值、20 秒间隔与参考一致;实际 `.mse` 方向/资源效果缺失,本地 Boss/排行公式属于额外 authority |
|
||
| State transition order | PARTIAL | 包→native event→目标状态→HUD 的顺序接近;alarm 只到 signal,world reset/重连/旧包清理和结果窗口生命周期未闭合 |
|
||
| Constants/units | PARTIAL | subheader 0/1、10,000 cm、20 秒和九字段结果存在;server cm→Godot world 的轴/地图基准需实机验证,Boss/排行常量不能视为 40250 客户端常量 |
|
||
| Timing/event sources | PARTIAL | 目标初次与 20 秒 alarm、到达检测存在;实际 compass effect、结果重复包、断线/切图/重连和计时事件未覆盖 |
|
||
| Resource/data sources | PARTIAL | 结果字段来自服务端包,目标坐标来自 `GC_DUNGEON`;参考 `appear_middle.mse` 没有实际接入,Boss/排行使用本地硬编码表 |
|
||
| Protocol side effects | PARTIAL | `GC_DUNGEON` parser、请求和结果 UI 入口存在;未证明请求被正确门控,alarm/结果的完整 UI/音效/资源副作用不完整 |
|
||
| Interruption/failure/cleanup | GAP | 目标 alarm、结果 UI、Boss/排行 helper 在拒绝、断线、乱序、地图切换、重复结果和重连时的恢复没有完整回归;本地 helper 可绕开服务器 authority |
|
||
|
||
## Regression evidence
|
||
|
||
- `project/dungeon_state_test.gd`:通过,覆盖目标状态、坐标、到达阈值和 alarm 计数;没有证明实际 compass `.mse` 消费者已连接。
|
||
- `project/dungeon_result_test.gd`:通过,覆盖九字段结果窗口的本地展示;没有真实 `DUNGEON_RESULT` native 回包、重复结果、断线和关闭时序。
|
||
- `project/test_dungeon_ranking_parity.gd`、`project/test_spider_dungeon_parity.gd`、`project/test_spider_dungeon_key_parity.gd`、`project/test_flame_dungeon_razador_parity.gd`、`project/test_endless_spire_dungeon_parity.gd`:通过,验证当前端自定义 helper;40250 客户端没有同等本地 authority,因此不能证明 Windows 客户端 parity。
|
||
- `build/extension/net_entity_test`、`build/extension/net_classic_session_test`、`build/extension/net_classic_wire_test`:通过基础 parser/session/wire 检查;未覆盖 alarm 视觉副作用、目标乱序/旧包、结果 live UI、断线重连和 server rejection。
|
||
|
||
### Active GameLib dungeon-block review
|
||
|
||
- `GameLib/DungeonBlock.cpp`/`.h` 以资源 `CGraphicThing` 建立多个 `CDungeonModelInstance`,维护 deformable vertex buffer、bounding sphere、model intersection、static collision data、height instance、Update/Render/Shadow 和 Destroy;它是地图对象碰撞/渲染生命周期的一部分。
|
||
- 当前副本 helper 与 dungeon HUD 主要实现目标、结果和本地状态,没有 40250 `DungeonBlock` 的多模型/碰撞/高度/阴影对象链;`DUNGEON_RESULT` 测试通过不能覆盖该地图对象资源语义。
|
||
- 本轮完成 `DungeonBlock` 活跃源码静态核对,地下城合同继续为 `PARTIAL`。
|
||
|
||
## Status
|
||
|
||
## Deep audit round 2026-09-21
|
||
|
||
### Fresh regression results
|
||
|
||
- `dungeon_state_test.gd`、`dungeon_result_test.gd`、`test_dungeon_ranking_parity.gd`、`test_spider_dungeon_parity.gd`、`test_spider_dungeon_key_parity.gd`、`test_flame_dungeon_razador_parity.gd`、`test_endless_spire_dungeon_parity.gd` 均退出码 0;对应本地断言为 30/30、32/32、34/34、31/31、22/22。
|
||
- `net_entity_test`、`net_classic_session_test`、`net_classic_wire_test` 均退出码 0。
|
||
|
||
### Static parity conclusion
|
||
|
||
- `TIME_ATTACK_START`、目标坐标转换、10,000 cm Manhattan 到达阈值和 20 秒 alarm 状态算法已接近参考实现;但 `alarm_requested` 没有实际消费 `appear_middle.mse`、方向旋转和音效的生产链。
|
||
- `DUNGEON_RESULT` 九字段展示窗口只有本地 UI/假回包证据,尚未证明真实 native 回包到窗口的重复、关闭、断线和重连时序。
|
||
- Boss、排行、蜘蛛/火焰/无限塔 helper 在本端直接维护阶段、掉落、奖励或统计;这些不是 40250 Windows 客户端 authority,不能把其单元测试计为 parity 通过。
|
||
- 请求门控、拒绝回滚、旧包/乱序、地图切换和重连清理仍缺 live 证据。
|
||
|
||
### Status update
|
||
|
||
本轮仍为 `PARTIAL`;完成三个地下城/活动方向的合同审计并登记,未修改实现。
|
||
|
||
`PARTIAL`。当前端已经具备 `GC_DUNGEON` 目标点的主要 parser、坐标状态和与 40250 一致的 Manhattan/20 秒算法,也有结果窗口骨架;但 40250 的 compass `.mse` alarm 没有实际消费者,结果链缺少 live 回包时序证据,且 Boss、排行和具体副本 helper 是当前端本地 authority,不是 40250 Windows 客户端实现。本轮完成审计并记录,未修改实现。
|