feat(client): 完成40250客户端核心功能1:1对齐与桥梁高度采样修复
- 桥梁与静态物体高度采样修复: - 严格对齐 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 客户端对拍缺陷发现与修复工程指南
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
# refine_effect_system.gd —— +7/+8/+9 装备强化专属发光特效(40250 官方 1:1 对齐)
|
||||
# 对齐源码:
|
||||
# - 40250 ClientVS22/source/UserInterface/InstanceBase.cpp:2698-2740 (AttachEffect, EFFECT_REFINED)
|
||||
# - 40250 ClientVS22/source/UserInterface/InstanceBase.h:268-297 (EFFECT_REFINED_NUM)
|
||||
# - 40250 root/playersettingmodule.py:391-416 (RegisterEffect, sword_7..9.mse, armor_7..9.mse)
|
||||
class_name RefineEffectSystem
|
||||
extends RefCounted
|
||||
|
||||
# 40250 官方发光分级常量
|
||||
const REFINE_SHINE_START_LEVEL := 7 # 从 +7 开始出现发光特效
|
||||
|
||||
const SHINE_TIER_7 := 7
|
||||
const SHINE_TIER_8 := 8
|
||||
const SHINE_TIER_9 := 9
|
||||
|
||||
# 官方发光特效配置文件映射表 (40250 playersettingmodule.py:391-416)
|
||||
const WEAPON_SHINE_EFFECTS := {
|
||||
SHINE_TIER_7: "d:/ymir work/pc/common/effect/sword/sword_7.mse",
|
||||
SHINE_TIER_8: "d:/ymir work/pc/common/effect/sword/sword_8.mse",
|
||||
SHINE_TIER_9: "d:/ymir work/pc/common/effect/sword/sword_9.mse",
|
||||
}
|
||||
|
||||
const ARMOR_SHINE_EFFECTS := {
|
||||
SHINE_TIER_7: "d:/ymir work/pc/common/effect/armor/armor_7.mse",
|
||||
SHINE_TIER_8: "d:/ymir work/pc/common/effect/armor/armor_8.mse",
|
||||
SHINE_TIER_9: "d:/ymir work/pc/common/effect/armor/armor_9.mse",
|
||||
}
|
||||
|
||||
# 66~70 级高级黑钢战甲特效 (armor-4-2-1.mse, armor-4-2-2.mse)
|
||||
const SPECIAL_ARMOR_EFFECTS := {
|
||||
SHINE_TIER_7: "d:/ymir work/pc/common/effect/armor/armor-4-2-1.mse",
|
||||
SHINE_TIER_8: "d:/ymir work/pc/common/effect/armor/armor-4-2-2.mse",
|
||||
SHINE_TIER_9: "d:/ymir work/pc/common/effect/armor/armor-4-2.mse",
|
||||
}
|
||||
|
||||
# 骨骼挂载点定义 (InstanceBase.cpp:2698)
|
||||
const ATTACH_BONE_WEAPON_RIGHT := "PART_WEAPON" # 右手武器
|
||||
const ATTACH_BONE_WEAPON_LEFT := "PART_WEAPON_LEFT" # 左手武器(如双持匕首)
|
||||
const ATTACH_BONE_ARMOR := "Bip01" # 盔甲躯干
|
||||
|
||||
# 发光色调配置(用于 Godot 动态粒子与材质 Emission)
|
||||
const SHINE_COLORS := {
|
||||
SHINE_TIER_7: Color(0.9, 0.95, 1.0, 0.7), # +7: 浅白清冷光晕
|
||||
SHINE_TIER_8: Color(0.3, 0.7, 1.0, 0.85), # +8: 亮蓝闪烁流光
|
||||
SHINE_TIER_9: Color(1.0, 0.85, 0.2, 1.0), # +9: 强烈金黄/电光辉光
|
||||
}
|
||||
|
||||
## 从物品 Vnum 解析强化等级 (Metin2 官方惯例:vnum % 10 为强化等级)
|
||||
static func get_refine_level_from_vnum(vnum: int) -> int:
|
||||
if vnum <= 0:
|
||||
return 0
|
||||
return vnum % 10
|
||||
|
||||
## 检查该物品是否具备 +7/+8/+9 专属发光
|
||||
static func is_shining_item(vnum: int, item_type: int) -> bool:
|
||||
if item_type not in [1, 2]: # 1: WEAPON, 2: ARMOR
|
||||
return false
|
||||
var lvl := get_refine_level_from_vnum(vnum)
|
||||
return lvl >= REFINE_SHINE_START_LEVEL
|
||||
|
||||
## 获取发光特效数据配置
|
||||
static func get_shine_spec(vnum: int, item_type: int, is_left_hand := false) -> Dictionary:
|
||||
var lvl := get_refine_level_from_vnum(vnum)
|
||||
if lvl < REFINE_SHINE_START_LEVEL:
|
||||
return {"shining": false, "level": lvl}
|
||||
|
||||
var attach_bone := ""
|
||||
var effect_path := ""
|
||||
var color: Color = SHINE_COLORS.get(lvl, Color.WHITE)
|
||||
|
||||
if item_type == 1: # WEAPON
|
||||
attach_bone = ATTACH_BONE_WEAPON_LEFT if is_left_hand else ATTACH_BONE_WEAPON_RIGHT
|
||||
effect_path = WEAPON_SHINE_EFFECTS.get(lvl, "")
|
||||
elif item_type == 2: # ARMOR
|
||||
attach_bone = ATTACH_BONE_ARMOR
|
||||
# 判断是否为 66 级以上黑钢特种战甲 (如 11290..11299)
|
||||
if vnum >= 11290 and vnum <= 11899:
|
||||
effect_path = SPECIAL_ARMOR_EFFECTS.get(lvl, "")
|
||||
else:
|
||||
effect_path = ARMOR_SHINE_EFFECTS.get(lvl, "")
|
||||
|
||||
return {
|
||||
"shining": true,
|
||||
"level": lvl,
|
||||
"attach_bone": attach_bone,
|
||||
"effect_path": effect_path,
|
||||
"color": color,
|
||||
"particle_rate": 15 if lvl == 7 else (30 if lvl == 8 else 60),
|
||||
"light_energy": 0.8 if lvl == 7 else (1.5 if lvl == 8 else 3.0),
|
||||
}
|
||||
|
||||
## 创建发光粒子节点(可在挂载模型时直接附加到 Skeleton3D)
|
||||
static func create_shine_particles(spec: Dictionary) -> GPUParticles3D:
|
||||
if not bool(spec.get("shining", false)):
|
||||
return null
|
||||
var particles := GPUParticles3D.new()
|
||||
particles.name = "RefineShineParticles_L%d" % int(spec.get("level", 7))
|
||||
particles.amount = int(spec.get("particle_rate", 20))
|
||||
particles.lifetime = 0.6
|
||||
particles.explosiveness = 0.05
|
||||
particles.randomness = 0.2
|
||||
|
||||
# 创建材质
|
||||
var mat := StandardMaterial3D.new()
|
||||
mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
|
||||
mat.albedo_color = spec.get("color", Color.WHITE)
|
||||
mat.emission_enabled = true
|
||||
mat.emission = spec.get("color", Color.WHITE)
|
||||
mat.emission_energy_multiplier = float(spec.get("light_energy", 1.0))
|
||||
|
||||
var quad := QuadMesh.new()
|
||||
quad.size = Vector2(0.12, 0.12)
|
||||
quad.material = mat
|
||||
particles.draw_pass_1 = quad
|
||||
return particles
|
||||
Reference in New Issue
Block a user