Files
mtgodot-poc/project/refine_effect_system.gd
T
shenandshen 66d217b313 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 客户端对拍缺陷发现与修复工程指南
2026-09-19 08:51:25 -07:00

116 lines
4.4 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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