- 桥梁与静态物体高度采样修复: - 严格对齐 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 客户端对拍缺陷发现与修复工程指南
116 lines
4.4 KiB
GDScript
116 lines
4.4 KiB
GDScript
# 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
|