- item_tooltip_view.gd: 新增 avoid_rect 属性,tooltip 与装备窗口重叠时自动推到左侧 - inventory_ui.gd: 悬停装备时传入窗口矩形作为避让区域 - 包含其他累积的功能开发和测试文件
11 KiB
11 KiB
world.fishing_mining
Scope
审计 40250 Windows 客户端的钓鱼输入门控、GetFishingRot 水面扫描、CG_FISHING/GC_FISHING 状态与角色动作、GC_DIG_MOTION 采矿动作、地图水面/水高和当前端扩展的钓鱼、开鱼、烹饪、营火、采矿、熔炼脚本。判断标准是当前端是否统一复现 40250 客户端的输入条件、坐标/单位、协议、角色动画、事件顺序和资源副作用;服务端概率、掉落、库存、熔炼与增益规则不能因被写入 Godot helper 就当成 Windows 客户端 parity。
Reference call chain
UserInterface/PythonPlayerInput.cppNEW_Fishing:无主角色则返回;已在钓鱼时发送CG_FISHING(0);否则要求CanFishing(),调用GetFishingRot,水面无效时只触发OnFishingWrongPlace,有效时发送角度。NEW_CancelFishing只在IsFishing()时发送取消包,并有 500ms 节流。
UserInterface/InstanceBaseMotion.cpp/InstanceBase.cppGetFishingRot以角色当前位置、朝向和 600cm 距离,按左右 0..180 度、每 10 度扫描ATTRIBUTE_WATER,优先返回右侧,再返回左侧;钓鱼/持镐状态参与动作门控。StartFishing、StopFishing、ReactFishing、CatchSuccess、CatchFail只切换角色动作/表情,不在客户端结算鱼或库存。
UserInterface/PythonNetworkStreamPhaseGame.cpp/Packet.hSendFishingPacket发送角度/5 的 byte 并追加 sequence;RecvFishing对 START/STOP/REACT/SUCCESS/FAIL 按info查角色并切换动作,FISH 按 item vnum 走OnFishingNotify/OnFishingSuccess;未知角色包直接忽略,未知物品也不凭空入包。RecvDigMotionPacket查主角色和目标,朝目标转身,再按count重复NAME_DIG动作。
GameLib/AreaTerrain.cpp/MapOutdoorWater.cpp- 地形通过水属性图和水高表提供
ATTRIBUTE_WATER/water height;水面渲染使用地图 water 数据和循环纹理,不负责钓鱼收益。
- 地形通过水属性图和水高表提供
Current call chain
- native
M2Client::fishing、ClassicSession::send_fishing、GameClient::send_fishing已能在游戏阶段发送角度/5;classic stream 会为已登记的 CG 包追加 sequence。 EntityStore/classic parser 已保存GC_FISHING和GC_DIG_MOTION,M2Client::poll发出fishing_event/dig_motion;NetWorld会更新实体方向/动作,NetPlay会更新本地主角钓鱼状态,ChatUI展示 FISH/FAIL 文本。Metin2World::get_fishing_rotation已按 600cm、左右 10 度扫描ATTRIBUTE_WATER,fishing_water_test.gd已在 A1 地图验证样本;water builder/animation 已存在。project/fishing_mining_system.gd、fishing_rod_reel_system.gd、fishing_cooking_camp_system.gd、mining_refinery_smelt_system.gd直接实现概率、物品消耗、烤鱼 buff、矿石熔炼、宝石孔和库存写入。这些是本端 custom/server-like authority,40250 Windows 客户端本身不做这些结算。
Branch matrix
| 场景 | 40250 | 当前端 | 结论 |
|---|---|---|---|
| 开始钓鱼 | NEW_Fishing→CanFishing→GetFishingRot→有效才发送;无水只提示 |
activate_fishing 有状态/死亡/技能门控并调用 get_fishing_rotation,再调用 native fishing |
PARTIAL:主路径接近,但真实装备动作模式、CanFishing 和服务端拒绝回滚未端到端证明 |
| 钓鱼角度 | 角色前方 600cm,左右 0..180、10 度,右侧优先,返回服务端角度 | native world 用 6m、同样步长并做 MapCoord 转换 | PARTIAL:算法接近;轴向、地图基准和 heading 转换需实机/固定样本对照,provider 缺失时当前端允许协议 fallback |
| 取消钓鱼 | 只在 IsFishing 时发 0,500ms 内不重复发送 |
cancel_fishing 使用 _fishing_active 和 500ms 节流 |
PARTIAL:状态来源是本地事件 flag,不是 actor IsFishing 的完整动作状态;断线/旧包/取消失败清理未覆盖 |
GC_FISHING START/STOP |
按 fisher VID 查角色,调用 Start/Stop;找不到角色直接忽略 | NetWorld 写 metadata、设置 fishing/wait,NetPlay 对本地主角维护 _fishing_active |
PARTIAL:状态/动作骨架存在;metadata/placeholder 与真实角色 motion 资源、重复/乱序包语义仍需验证 |
REACT |
仅在角色仍钓鱼时加 fish emoticon 并 ReactFishing | 当前端显示 emoticon 并切 fishing_react,未严格以 actor 状态确认 |
PARTIAL:缺少同等 IsFishing 条件和清理时序证据 |
SUCCESS/FAIL |
切 catch/fail 动作;FAIL 对主角色触发失败 UI | 当前端切动作并在 ChatUI 展示失败文本 | PARTIAL:动作/文本入口有,资源、音效、重复结果和主角色判断未完整覆盖 |
FISH 结果 |
info=0 显示 unknown;有 item 且能查 item data 才通知;按角色仍钓鱼决定 notify/success | ChatUI 用 proto 查询并展示;NetWorld/NetPlay 将 FISH 作为 UI-only | PARTIAL:未知物品忽略接近参考,但 item type、主角色状态和 live inventory 回包未闭合 |
| 采矿动作 | GC_DIG_MOTION 查 VID/目标、朝目标转身、按 count 重复 dig motion |
native parser→NetWorld 转身并只设置一次 dig 状态、保存 count |
PARTIAL:count 仅 metadata,未证明按 count 排队多个 NAME_DIG 动作;目标缺失/动作结束清理未覆盖 |
| 矿镐/攻击门控 | IsHoldingPickAxe 影响 CanAttack/CanUseSkill/动作模式 |
当前 FishingMiningSystem 能识别矿镐,但未作为 live NetPlay 的统一攻击/技能门控证据 |
PARTIAL/GAP:识别 helper 存在,网络动作门控未闭合 |
| 水属性/水高/水面 | ATTRIBUTE_WATER、水高和 water.wtr 由地图资源读取与渲染 | native world 读取 attr、水高并构造 water mesh/动画 | PARTIAL:结构已存在,尚未证明所有 map chunk 边界、water height 单位和纹理帧与 40250 像素级一致 |
| 钓鱼/采矿收益 | 客户端只展示服务端 item/状态,不计算概率和库存 authority | 本地脚本直接 roll、扣 bait、写 inventory、发 fish/ore、烹饪 buff 和熔炼宝石 | GAP(custom authority):不能与 40250 Windows 客户端实现宣称统一 |
Implementation-equivalence matrix
| 项目 | 状态 | 证据/限制 |
|---|---|---|
| Preconditions | PARTIAL | 游戏阶段、网络状态、水面扫描和部分本地动作门控存在;真实 CanFishing/装备形态、持镐对攻击/技能的统一门控、服务端拒绝未完整接入 |
| Branch structure | PARTIAL | START/STOP/REACT/SUCCESS/FAIL/FISH、DIG_MOTION、water attribute 主分支存在;REACT 的 actor 状态条件、DIG count 队列和未知/乱序清理不等价 |
| Algorithms/formulas | PARTIAL | 600cm/10度扫描、右优先和 5 度网络量化接近参考;收益概率、开鱼、采矿、熔炼和 buff 是自定义本地算法,不是 40250 client 算法 |
| State transition order | PARTIAL | 回包→parser→NetWorld/NetPlay/UI 大体存在;真实角色动作完成、FISH 与 IsFishing 判断、拒绝/重连和 inventory 回包顺序未闭合 |
| Constants/units | PARTIAL | 600cm、10度、180度、500ms、角度/5、ATTRIBUTE_WATER 和 packet layout 有证据;MapCoord 轴向/水高单位和本地 VNUM/概率表缺 reference client 证据 |
| Timing/event sources | PARTIAL | 取消节流和网络事件队列存在;服务端 fishing reaction 时序、动作结束、重复/延迟 GC 包、矿动作 count 时序未覆盖 |
| Resource/data sources | PARTIAL | A1 attr/water mesh、fish emoticon 和角色状态入口存在;全部地图 water.wtr、实际 fishing motion/effect/sound 和 item proto 对应关系未完整验证 |
| Protocol side effects | PARTIAL | CG/GC fishing、GC dig parser 和 sequence/frame 存在;缺 live wrong-place、CanFishing、server result、item inventory/音效端到端证据 |
| Interruption/failure/cleanup | GAP | 断线、换图、角色消失、错误 item、重复 FISH/FAIL、采矿 count 中断及本地 helper 的 optimistic inventory/buff 回滚没有完整证明 |
Regression evidence
project/test_fishing_mining_parity.gd:26/26 通过;验证本地装备识别、概率 helper、开鱼/蚌壳和矿脉表,不是 40250 live client 回包证据。project/test_fishing_rod_reel_parity.gd:33/33 通过;验证本端抛竿/拉杆/鱼竿精炼 helper,40250 Windows client 不在本地执行这些收益和持久化规则。project/test_fishing_cooking_camp_parity.gd:23/23 通过;验证本地营火、烤鱼和 buff 写入,属于 custom authority。project/test_mining_refinery_smelt_parity.gd:21/21 通过;验证本地熔炼、开孔和镶嵌,不能证明 Windows client parity。project/fishing_water_test.gd、project/water_reference_test.gd:通过;分别验证 A1 水属性/600cm heading 查询和当前 water geometry/material,不是 40250 像素级渲染证明。project/netplay_test.gd、project/netbridge_test.gd、project/combat_fx_test.gd、project/chat_test.gd、build/extension/net_entity_test、build/extension/net_classic_session_test、build/extension/net_classic_wire_test:覆盖 fishing/dig event 的部分状态、动作和 wire;未覆盖 actor motion 资源、REACTIsFishing、DIG count 多动作、服务端拒绝、乱序、断线/切图和 live inventory。
Status
Deep audit round 2026-09-21
Fresh regression results
test_fishing_mining_parity.gd26/26、test_fishing_rod_reel_parity.gd33/33、test_fishing_cooking_camp_parity.gd23/23、test_mining_refinery_smelt_parity.gd21/21 均通过。fishing_water_test.gd、water_reference_test.gd、netplay_test.gd、combat_fx_test.gd、chat_test.gd通过;native entity/session/wire 三项通过。netbridge_test.gd仍失败 3 项(实体节点、mount 子节点和主实体可见性),并有 5 个 ObjectDB 泄漏;这说明 fishing/dig 事件与通用实体桥接尚未闭合。
Static parity conclusion
- 600cm 水面扫描、10 度步长、右侧优先、500ms 取消节流和 fishing/dig 包骨架存在,但
CanFishing/持竿动作状态、REACT 的IsFishing条件和服务端拒绝回滚不等价。 GC_DIG_MOTION的count目前只保存为 metadata/一次状态,未证明按参考实现重复排队NAME_DIG动作。- 本端钓鱼收益、烹饪、营火、采矿、熔炼、开孔和库存写入仍由本地脚本直接结算;40250 Windows 客户端只消费服务端结果,属于职责差异。
- 水属性和水面几何有局部样本通过,但地图边界、单位、资源帧、动作/音效和断线/换图清理没有完整 live 证据。
Status update
本轮仍为 PARTIAL;完成钓鱼/采矿方向的合同审计并登记,未修改实现。
PARTIAL。当前端已经具备 40250 钓鱼/采矿协议骨架、角色动作入口、水属性扫描和水面构造;但持竿/持镐 live 门控、角色状态条件、采矿 count 动作队列和真实资源副作用证据不足,且钓鱼收益、烹饪、营火、熔炼、宝石与库存脚本承担了 40250 客户端没有承担的本地 authority。本轮完成审计并记录,未修改实现。