# 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 }