Files
mtgodot-poc/project/marriage_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

112 lines
3.8 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.
# marriage_system.gd —— Metin2 40250 结婚戒指与伴侣瞬移传送系统 1:1
# 对照 40250 服务端 wedding.cpp, char_item.cpp (Wedding Ring 70301, NPC 20017 Musician)
class_name MarriageSystem
extends RefCounted
signal couple_warped(target_map: String, target_pos: Vector3)
const NPC_MUSICIAN := 20017 # 月下老人 / 乐师
const ITEM_WEDDING_RING := 70301 # 结婚戒指
const WARP_SP_COST := 50 # 每次传送消耗 50 SP
const WARP_COOLDOWN := 180.0 # 3 分钟传送冷却
# 禁止传送进入的特殊副本/区域
const FORBIDDEN_MAPS := ["deviltower_f7", "deviltower_f8", "deviltower_f9", "oxevent"]
var is_married: bool = false
var spouse_name: String = ""
var love_points: int = 0 # 0 ~ 100%
var warp_cooldown: float = 0.0
# 在月下老人处登记结婚 (wedding.cpp)
func marry(player_name: String, partner_name: String, ring_item: Dictionary, player_level: int) -> Dictionary:
if is_married:
return {"ok": false, "reason": "ALREADY_MARRIED", "msg": "你已经结过婚了!"}
if player_level < 25:
return {"ok": false, "reason": "LEVEL_TOO_LOW", "msg": "角色等级未满 25 级,无法缔结婚约!"}
var vnum: int = int(ring_item.get("vnum", 0))
if vnum != ITEM_WEDDING_RING:
return {"ok": false, "reason": "NO_WEDDING_RING", "msg": "缔结婚约必须携带结婚戒指!"}
is_married = true
spouse_name = partner_name
love_points = 50 # 初始爱意值 50%
warp_cooldown = 0.0
# 戒指上刻录伴侣名字
ring_item["inscribed_name"] = partner_name
ring_item["is_bound"] = true
return {
"ok": true,
"spouse_name": spouse_name,
"love_points": love_points,
"msg": "恭喜!你与【%s】在月下老人的见证下正式结为夫妻!" % spouse_name
}
# 离婚解除婚约
func divorce() -> Dictionary:
if not is_married:
return {"ok": false, "reason": "NOT_MARRIED"}
var old_spouse = spouse_name
is_married = false
spouse_name = ""
love_points = 0
warp_cooldown = 0.0
return {"ok": true, "msg": "已与【%s】解除婚姻关系。" % old_spouse}
# 增加爱意值
func add_love_points(amount: int) -> int:
if is_married:
love_points = clampi(love_points + amount, 0, 100)
return love_points
# 夫妻瞬移传送 (char_item.cpp:UseItemEx 70301)
func warp_to_spouse(current_sp: int, spouse_location: Dictionary, is_dead: bool) -> Dictionary:
if not is_married:
return {"ok": false, "reason": "NOT_MARRIED", "msg": "你尚未结婚,无法使用夫妻传送!"}
if is_dead:
return {"ok": false, "reason": "PLAYER_DEAD", "msg": "死亡状态下无法进行传送!"}
if warp_cooldown > 0.0:
return {"ok": false, "reason": "COOLDOWN_ACTIVE", "remaining": warp_cooldown, "msg": "结婚戒指传送冷却中!"}
if current_sp < WARP_SP_COST:
return {"ok": false, "reason": "NOT_ENOUGH_SP", "msg": "传送所需内力值不足 (需要 %d SP)" % WARP_SP_COST}
if spouse_location.is_empty() or not bool(spouse_location.get("is_online", false)):
return {"ok": false, "reason": "SPOUSE_OFFLINE", "msg": "伴侣当前不在线!"}
var map_id: String = String(spouse_location.get("map", ""))
if map_id in FORBIDDEN_MAPS:
return {"ok": false, "reason": "FORBIDDEN_ZONE", "msg": "伴侣当前处于特殊封闭区域,无法瞬移传送到其身边!"}
var pos: Vector3 = spouse_location.get("pos", Vector3.ZERO)
# 扣除 SP 并进入冷却
warp_cooldown = WARP_COOLDOWN
couple_warped.emit(map_id, pos)
return {
"ok": true,
"target_map": map_id,
"target_pos": pos,
"sp_cost": WARP_SP_COST,
"cooldown": WARP_COOLDOWN,
"msg": "心有灵犀!正在瞬间传送到伴侣身边..."
}
# 逐帧更新冷却
func update(dt: float) -> void:
if warp_cooldown > 0.0:
warp_cooldown = maxf(0.0, warp_cooldown - dt)
func get_info() -> Dictionary:
return {
"is_married": is_married,
"spouse_name": spouse_name,
"love_points": love_points,
"warp_cooldown": warp_cooldown
}