- item_tooltip_view.gd: 新增 avoid_rect 属性,tooltip 与装备窗口重叠时自动推到左侧 - inventory_ui.gd: 悬停装备时传入窗口矩形作为避让区域 - 包含其他累积的功能开发和测试文件
10 KiB
10 KiB
world.mount_pet_polymorph
Scope
审计 40250 Windows 客户端的角色 mount_vnum 接收、GC_MOUNT 上下马状态、骑乘/步行 motion mode、旋转速度、骑乘攻击/技能限制、变身 affect/装备遮挡,以及当前端的马匹、宠物、变身和马上技能脚本。判断标准是客户端是否与 40250 的实体字段、动作模式、门控和回包顺序统一;服务端拥有马匹等级、宠物属性、变身持续和技能伤害 authority,当前端本地 helper 能独立推进规则不能作为 parity 证明。
Reference call chain
UserInterface/PythonNetworkStreamPhaseGameActor.cpp- Character add/additional/update packet 携带
dwMountVnum,交给CInstanceBase;角色创建时非零 mount vnum 会进入MountHorse。
- Character add/additional/update packet 携带
UserInterface/PythonNetworkStreamPhaseGame.cpp/Packet.hRecvMountPacket读取vid/mount_vid/pos/x/y,按角色存在性处理上下马;该版本的Ride/Unride/SetRidingVehicleIndex调用被注释,不能凭空扩大为客户端结算。
UserInterface/InstanceBase.cpp/InstanceBaseMotion.cppMountHorse/DismountHorse更新 horse actor、动作模式和 rotation speed;持镐、钓竿、变身、婚纱、坐骑会影响 motion mode、CanAttack、CanUseSkill和武器/发型遮挡。CanAttackHorseLevel通过 horse actor 等级限制普通攻击;新的坐骑/马术技能可由PythonPlayer的 can-use 门控决定。
UserInterface/PythonPlayer.cpp/PythonPlayerSkill.cpp/InstanceBase.h- 客户端消费
NEW_AFFECT_POLYMORPH/NEW_AFFECT_MOUNT等状态和 skill level,阻止不允许的动作;不在客户端本地计算宠物战力、掉落、马匹成长或服务端技能伤害。
- 客户端消费
- 40250 ClientVS22 全树搜索未找到独立宠物 follow/combat authority 实现;
ITEM_TYPE_POLYMORPH和 polymorph skill/affect 常量存在,但其客户端职责是展示/门控/动作。
Current call chain
- native classic parser 已将角色 add/update、additional info 和
GC_MOUNT的mount_vnum写入EntityStore;M2Client::poll发出mount_changed,实体 getter 能提供该字段。 project/net_world.gd保存mount_vnummetadata、根据 mount 选择旋转速度并更新实体字段;project/net_play.gd根据 mount/poly/weapon 刷新 local motion mode、骑乘攻击等级门和技能上下文;EquipModel只用 mount 状态处理武器双手规则。project/horse_system.gd、horse_combat_system.gd、horse_level_growth_system.gd、mounted_combat_skill_system.gd、pet_companion_system.gd、classic_pet_system.gd、polymorph_system.gd、polymorph_marble_system.gd在本地维护召唤、骑乘、耐力、宠物跟随/增益、变身时限和技能伤害。- 当前代码搜索未发现
mount_vnum被用于创建/挂接实际坐骑模型或 saddle actor 的实现;大多数 live 网络路径只保留 metadata/motion mode,宠物和变身 helper 也没有对应的 native server affect/entity 回包闭环。
Branch matrix
| 场景 | 40250 | 当前端 | 结论 |
|---|---|---|---|
| 角色创建带 mount | add packet 的 dwMountVnum→MountHorse→动作/挂点;服务器字段权威 |
parser/store 保存 mount,NetWorld 只写 metadata,未发现 mount actor/model attach | GAP:状态字段有,视觉实体链缺失 |
GC_MOUNT 上马 |
读取包,角色存在时进入 Ride 分支(本版本 Ride 调用被注释),主角色 vehicle index 也被注释 | parser 更新实体 mount_vnum,发 mount_changed,NetPlay 刷 motion mode |
PARTIAL:字段/动作门有,需保持与该版本注释语义一致,不能自行增加本地 ride authority |
GC_MOUNT 下马 |
mount_vid==0,服务端位置字段交给 Unride(本版本调用被注释) |
mount 字段置零并刷新 motion;没有验证 x/y 下马位置和模型清理 | PARTIAL |
| 骑乘旋转/移动 | MountHorse 使用约 300°/s rotation,步行约 1200°/s,horse motion mode 参与根运动 | NetPlay/NetWorld 有 horse rotation speed 和 mounted mode;NetWorld 对有 mount 的真模型不推送 motion speeds | PARTIAL:常量入口接近,但实际 horse motion/模型不存在,远端骑乘 root motion 不完整 |
| 普通攻击 | CanAttack 受 horse level、婚纱、持镐和 actor lock 限制;等级 1 坐骑不能攻击 |
NetPlay 有 _can_attack_horse_level 和部分新坐骑 skill gate |
PARTIAL:部分映射存在,真实 horse actor 等级、服务器拒绝、动作/包副作用未完整证明 |
| 技能/武器模式 | CanUseSkill、SetMotionMode 受变身、婚纱、持镐、坐骑、武器类型影响 |
local motion mode/skill context 有 mount/poly 字段,但 poly 字段未由 native entity 回包提供 | PARTIAL/GAP |
| 变身 | NEW_AFFECT_POLYMORPH/shape/parts 影响模型、装备遮挡、技能/动作门;状态来自服务器 affect/character data |
polymorph_system.gd 直接启动、加攻防、计时、死亡取消;EquipModel 明确 _is_poly() 恒 false |
GAP:本地 helper 有规则,live 视觉和 native affect 闭环缺失 |
| 宠物 | 40250 ClientVS22 未发现独立宠物 follow/combat authority | pet_companion_system.gd/classic_pet_system.gd 本地召唤、跟随和属性加成 |
GAP(custom feature/authority):不能标记为 40250 parity |
| 马匹成长/耐力/喂养/马上技能 | 服务端/脚本权威;客户端只消费字段和动作 | 本地 helper 直接计算成长、耐力、技能 CD、伤害、库存消耗 | GAP(custom authority) |
Implementation-equivalence matrix
| 项目 | 状态 | 证据/限制 |
|---|---|---|
| Preconditions | PARTIAL | native stage/VID/mount 字段、部分死亡/技能/新坐骑门存在;角色存在、horse actor、变身 affect 和 server rejection 的完整门控未闭合 |
| Branch structure | PARTIAL | add/update/mount parser、动作模式、攻击范围/等级入口存在;ride/unride 位置、实际 mount attach、poly entity field 和 pet 分支不等价 |
| Algorithms/formulas | PARTIAL | motion mode/旋转速度和部分 mount level 表有映射;马匹成长、耐力、宠物加成、变身加攻防、马上技能伤害是本地 custom 算法 |
| State transition order | PARTIAL | server actor data→EntityStore→mount_changed→motion mode 顺序大体存在;模型 attach/detach、poly affect→装备遮挡、断线/重连和死亡清理未闭合 |
| Constants/units | PARTIAL | mount_vnum、马等级表、300/1200°/s、技能/affect 常量有证据;本地宠物/成长/耐力/伤害常量没有 40250 client authority 依据 |
| Timing/event sources | PARTIAL | mount signal、motion refresh、死亡/技能上下文存在;实际 ride animation、poly affect duration、server updates、重复/乱序包未覆盖 |
| Resource/data sources | GAP | 当前搜索未找到 mount_vnum→horse model/saddle actor 挂接;真实 horse/poly motion 资源存在与否、路径和绑定关系没有端到端证明 |
| Protocol side effects | PARTIAL | actor/mount packet parser 和 getter 存在;没有客户端等价的宠物/马战本地结算,也缺 live 上下马/变身/拒绝/重连 packet sequence |
| Interruption/failure/cleanup | GAP | 下马、角色消失、地图切换、死亡、变身过期、宠物过期、断线重连和 mount/poly model 清理未完整回归;本地 helper 可绕开服务器 authority |
Regression evidence
project/test_mount_horse_parity.gd:24/24 通过,覆盖本地马匹命令/范围 helper;不证明GC_MOUNTlive actor/model attach。project/test_horse_combat_parity.gd:32/32、test_horse_level_growth_parity.gd:42/42、test_mounted_combat_skill_parity.gd:25/25 通过;这些测试验证本地骑乘战斗、成长、耐力和技能 helper,不能作为 40250 Windows client parity。project/test_pet_companion_parity.gd:40/40、test_classic_pet_parity.gd:31/31 通过;验证本地宠物状态/序列化,40250 ClientVS22 未发现同等宠物 authority。project/test_polymorph_parity.gd:25/25、test_polymorph_marble_parity.gd:32/32 通过;验证本地变身 helper,但未覆盖 native affect/entity、模型 shape、装备遮挡和 server lifetime。project/netplay_test.gd、project/netbridge_test.gd、build/extension/net_entity_test、build/extension/net_classic_session_test:覆盖部分 mount 字段、motion mode 和 parser 信号;未覆盖模型挂接、GC_MOUNT 位置、poly/pet live chain、骑乘根运动、拒绝、乱序和重连清理。
Status
Deep audit round 2026-09-21
Fresh regression results
test_mount_horse_parity.gd24/24、test_horse_combat_parity.gd32/32、test_horse_level_growth_parity.gd42/42、test_mounted_combat_skill_parity.gd25/25、test_pet_companion_parity.gd40/40、test_classic_pet_parity.gd31/31、test_polymorph_parity.gd25/25、test_polymorph_marble_parity.gd32/32 均通过。equip_rules_test.gd、test_battle_arena_duel_parity.gd、player_move_test.gd、netplay_test.gd和 native entity/session 测试退出码 0;通用netbridge_test.gd仍有 3 项实体桥接失败和 5 个 ObjectDB 泄漏。
Static parity conclusion
mount_vnum的 parser/store/signal、部分动作模式、旋转速度和攻击等级门存在;但没有找到mount_vnum到实际 horse/saddle model attach/detach 的生产链。GC_MOUNT的位置、下马清理、重复/乱序、断线重连和角色死亡后的模型生命周期没有闭合;本版本参考代码中 Ride/Unride 调用被注释,不能用本地 helper 自行扩大 authority。- 变身字段没有形成 native affect→shape→装备遮挡/动作资源的完整链,
EquipModel的_is_poly()仍是恒 false;宠物、马匹成长/耐力/马上技能/变身加攻防由本地脚本直接结算,而 40250 Windows 客户端没有对应本地 authority。 - 所有 helper 测试通过只证明当前端自定义规则内部一致,不证明与参考客户端实现统一。
Status update
本轮仍为 PARTIAL;完成坐骑、宠物和变身方向的合同审计并登记,未修改实现。
PARTIAL。当前端已具备 mount_vnum 的网络存储、mount_changed 信号、部分动作模式/旋转速度/攻击门控,并有本地马匹、宠物和变身 helper;但没有发现实际坐骑模型挂接链,变身状态尚未进入 native entity,宠物与马战/成长/耐力/伤害脚本承担了 40250 客户端没有承担的本地 authority。基础测试全部通过仍不足以证明与 40250 Windows 客户端实现统一。本轮完成审计并记录,未修改实现。