- 桥梁与静态物体高度采样修复: - 严格对齐 40250 CMapOutdoor::GetHeight 与 CAttributeInstance::GetHeight - 解析 .mdatr 中的 AttributeHeight 网格,使用 is_in_triangle_2d 准确计算桥面多边形平面方程 - sample_height 查询邻近区块并返回 fMAX(fObjectHeight, fTerrainHeight),彻底解决走上桥面穿透掉入水底/河床的问题 - 新增 test_bridge_height_parity.gd 自动化对拍测试 - 40250 怪物击杀经验动效: - 1:1 实现 FLY_EXP(0) / FLY_HP / FLY_SP 粒子轨迹与爆炸吸附 - 40250 客户端全系统功能对齐(Batches 1-31): - 包含公会、交易、骑乘、变身、钓鱼、采矿、商城、信件、结婚、地牢等 134 套对拍系统与自动化回归测试 - 文档沉淀: - 新增 docs/CLIENT-PARITY-AUDIT-AND-FIX-GUIDE.md 客户端对拍缺陷发现与修复工程指南
55 lines
2.1 KiB
GDScript
55 lines
2.1 KiB
GDScript
# 40250 stores SLOT_TYPE_SKILL quickslots as CPythonPlayer skill-slot numbers,
|
|
# not raw skill vnums. playersettingmodule.RegisterSkill() maps those slots to
|
|
# a job + skill-group specific skill id before the taskbar asks for its icon.
|
|
extends RefCounted
|
|
|
|
const ACTIVE := {
|
|
0: {0: [0, 0, 0, 0, 0, 0, 0, 0, 137, 0, 138, 0, 139, 0],
|
|
1: [1, 2, 3, 4, 5, 0, 0, 0, 137, 0, 138, 0, 139, 0],
|
|
2: [16, 17, 18, 19, 20, 0, 0, 0, 137, 0, 138, 0, 139, 0]},
|
|
1: {0: [0, 0, 0, 0, 0, 0, 0, 0, 137, 0, 138, 0, 139, 0, 140],
|
|
1: [31, 32, 33, 34, 35, 0, 0, 0, 137, 0, 138, 0, 139, 0, 140],
|
|
2: [46, 47, 48, 49, 50, 0, 0, 0, 137, 0, 138, 0, 139, 0, 140]},
|
|
2: {0: [0, 0, 0, 0, 0, 0, 0, 0, 137, 0, 138, 0, 139, 0],
|
|
1: [61, 62, 63, 64, 65, 66, 0, 0, 137, 0, 138, 0, 139, 0],
|
|
2: [76, 77, 78, 79, 80, 81, 0, 0, 137, 0, 138, 0, 139, 0]},
|
|
3: {0: [0, 0, 0, 0, 0, 0, 0, 0, 137, 0, 138, 0, 139, 0],
|
|
1: [91, 92, 93, 94, 95, 96, 0, 0, 137, 0, 138, 0, 139, 0],
|
|
2: [106, 107, 108, 109, 110, 111, 0, 0, 137, 0, 138, 0, 139, 0]},
|
|
}
|
|
const SUPPORT := [122, 123, 121, 124, 125, 129, 0, 0, 130, 131]
|
|
const PASSIVE_GUILD := [151]
|
|
const ACTIVE_GUILD := [152, 153, 154, 155, 156, 157]
|
|
|
|
static func skill_id_for_slot(race: int, group: int, slot: int) -> int:
|
|
var job := race & 3
|
|
if slot >= 1 and slot <= 14:
|
|
var by_group: Dictionary = ACTIVE.get(job, {})
|
|
var ids: Array = by_group.get(group, [])
|
|
return int(ids[slot - 1]) if slot <= ids.size() else 0
|
|
if slot >= 101 and slot < 101 + SUPPORT.size():
|
|
return int(SUPPORT[slot - 101])
|
|
if slot >= 200 and slot < 200 + PASSIVE_GUILD.size():
|
|
return int(PASSIVE_GUILD[slot - 200])
|
|
if slot >= 210 and slot < 210 + ACTIVE_GUILD.size():
|
|
return int(ACTIVE_GUILD[slot - 210])
|
|
return 0
|
|
|
|
static func skill_slot_for_id(race: int, group: int, skill_id: int) -> int:
|
|
var job := race & 3
|
|
var by_group: Dictionary = ACTIVE.get(job, {})
|
|
var ids: Array = by_group.get(group, [])
|
|
var at := ids.find(skill_id)
|
|
if at >= 0:
|
|
return at + 1
|
|
at = SUPPORT.find(skill_id)
|
|
if at >= 0:
|
|
return at + 101
|
|
at = PASSIVE_GUILD.find(skill_id)
|
|
if at >= 0:
|
|
return at + 200
|
|
at = ACTIVE_GUILD.find(skill_id)
|
|
if at >= 0:
|
|
return at + 210
|
|
return 0
|