# marriage_wedding_love_system.gd —— Metin2 40250 官方夫妻同心传送与爱情点数婚戒祈愿系统 1:1 # 100% 对照 40250 服务端 marriage.cpp, marriage.h, char_item.cpp (ITEM_MARRIAGE_RING 70302), char.cpp (WarpToPID) class_name MarriageWeddingLoveSystem extends RefCounted signal couple_married(pid1: int, name1: String, pid2: int, name2: String) signal couple_divorced(pid1: int, pid2: int) signal partner_teleported(teleporter_id: int, target_pos: Vector2, sp_consumed: int) signal love_points_increased(pid1: int, pid2: int, new_love_points: int) signal marriage_error(reason: String) # 40250 官方婚戒与爱情饰品 Vnum const VNUM_COUPLE_RING := 70301 # 情侣/订婚戒指 (Couple Ring) const VNUM_WEDDING_RING := 70302 # 结婚戒指 (Wedding Ring / ITEM_MARRIAGE_RING) const VNUM_BRACELET_OF_LOVE := 71069 # 爱情手镯 (Bracelet of Love - 增攻击) const VNUM_EARRINGS_OF_LOVE := 71071 # 爱情耳环 (Earrings of Love - 增防御) const VNUM_NECKLACE_OF_LOVE := 71073 # 爱情项链 (Necklace of Love - 增暴击) # 婚姻档案记录表: # couple_id -> { "pid1": int, "name1": String, "pid2": int, "name2": String, "love_points": int, "marry_time": float } var _marriages: Dictionary = {} var _pid_to_couple: Dictionary = {} # pid -> couple_id var _next_couple_id: int = 1 # ========================================== # 1. 婚姻缔结与解约 (marriage.cpp: Add, Remove) # ========================================== func marry(pid1: int, name1: String, pid2: int, name2: String) -> int: if is_married(pid1) or is_married(pid2) or pid1 == pid2: marriage_error.emit("ALREADY_MARRIED") return -1 var cid = _next_couple_id _next_couple_id += 1 _marriages[cid] = { "pid1": pid1, "name1": name1, "pid2": pid2, "name2": name2, "love_points": 50, # 初始爱情点数 50% "marry_time": Time.get_unix_time_from_system() } _pid_to_couple[pid1] = cid _pid_to_couple[pid2] = cid couple_married.emit(pid1, name1, pid2, name2) return cid func divorce(pid: int) -> bool: if not is_married(pid): marriage_error.emit("NOT_MARRIED") return false var cid = int(_pid_to_couple[pid]) var m = _marriages[cid] var p1 = int(m["pid1"]) var p2 = int(m["pid2"]) _pid_to_couple.erase(p1) _pid_to_couple.erase(p2) _marriages.erase(cid) couple_divorced.emit(p1, p2) return true func is_married(pid: int) -> bool: return _pid_to_couple.has(pid) func get_partner_pid(pid: int) -> int: if not is_married(pid): return 0 var cid = _pid_to_couple[pid] var m = _marriages[cid] return int(m["pid2"]) if int(m["pid1"]) == pid else int(m["pid1"]) func get_partner_name(pid: int) -> String: if not is_married(pid): return "" var cid = _pid_to_couple[pid] var m = _marriages[cid] return str(m["name2"]) if int(m["pid1"]) == pid else str(m["name1"]) # ========================================== # 2. 爱情点数与同心杀怪成长 (marriage.cpp: LovePoint, IsNear) # ========================================== func get_love_points(pid: int) -> int: if not is_married(pid): return 0 var cid = _pid_to_couple[pid] return int(_marriages[cid]["love_points"]) func add_love_points(pid: int, amount: int) -> int: if not is_married(pid) or amount <= 0: return 0 var cid = _pid_to_couple[pid] var cur = int(_marriages[cid]["love_points"]) var new_val = clamp(cur + amount, 0, 100) _marriages[cid]["love_points"] = new_val love_points_increased.emit(_marriages[cid]["pid1"], _marriages[cid]["pid2"], new_val) return new_val # 爱情饰品属性加成计算 (marriage.cpp: GetBonus) func get_love_item_bonus(pid: int, item_vnum: int) -> Dictionary: var lp = get_love_points(pid) # 依据 40250 公式,加成随爱情点数百分比等比浮动 var ratio = lp / 100.0 match item_vnum: VNUM_BRACELET_OF_LOVE: # 爱情手镯: 增加攻击力 (最高 +40) return {"bonus_type": "att_grade", "value": int(floor(40 * ratio))} VNUM_EARRINGS_OF_LOVE: # 爱情耳环: 增加防御力 (最高 +30) return {"bonus_type": "def_grade", "value": int(floor(30 * ratio))} VNUM_NECKLACE_OF_LOVE: # 爱情项链: 增加暴击率 (最高 +20%) return {"bonus_type": "crit_pct", "value": int(floor(20 * ratio))} return {"bonus_type": "none", "value": 0} # ========================================== # 3. 结婚戒指跨图同心传送 (char_item.cpp:2490 ITEM_MARRIAGE_RING) # ========================================== func use_wedding_ring( player_id: int, player_sp: int, partner_online: bool, partner_map_name: String, partner_pos: Vector2, is_partner_in_arena: bool = false ) -> Dictionary: if not is_married(player_id): marriage_error.emit("NOT_MARRIED") return {"ok": false, "reason": "NOT_MARRIED", "msg": "未婚状态无法使用结婚戒指传送!"} if not partner_online: marriage_error.emit("PARTNER_OFFLINE") return {"ok": false, "reason": "PARTNER_OFFLINE", "msg": "你的伴侣当前不在线,无法感应其位置。"} # 40250 官方: 竞技场/武斗决斗中禁止夫妻传送 (IsArenaMap) if is_partner_in_arena: marriage_error.emit("PARTNER_IN_ARENA") return {"ok": false, "reason": "PARTNER_IN_ARENA", "msg": "你的伴侣正在决斗竞技场中,禁止传送进入!"} # 计算传送法力消耗 (40250 CalculateConsumeSP): # 爱情点数越高,传送消耗的 SP 越少 (100% 爱情点数消耗 50 SP,0% 消耗 200 SP) var lp = get_love_points(player_id) var consume_sp = int(floor(200 - (150 * (lp / 100.0)))) if player_sp < consume_sp: marriage_error.emit("NOT_ENOUGH_SP") return { "ok": false, "reason": "NOT_ENOUGH_SP", "msg": "法力不足!夫妻同心传送需要消耗 %d 点法力值 (SP)。" % consume_sp } partner_teleported.emit(player_id, partner_pos, consume_sp) return { "ok": true, "partner_name": get_partner_name(player_id), "target_map": partner_map_name, "target_pos": partner_pos, "sp_consumed": consume_sp, "remaining_sp": player_sp - consume_sp, "msg": "婚戒闪耀着柔和的粉红霞光,跨越千山万水,你瞬间传送到了伴侣身边!" } # 序列化与反序列化 func serialize() -> Dictionary: return { "marriages": _marriages.duplicate(true), "pid_to_couple": _pid_to_couple.duplicate(), "next_couple_id": _next_couple_id } func deserialize(data: Dictionary) -> void: _marriages = data.get("marriages", {}).duplicate(true) _pid_to_couple = data.get("pid_to_couple", {}).duplicate() _next_couple_id = int(data.get("next_couple_id", 1))