# party_management_system.gd —— 40250 8人组队面板、经验分配与领导力光环系统 1:1 # 严格对照: # metin2/src/server/game/src/party.h, party.cpp, char_party.cpp # Client/Eternexus/root/uiparty.py # ClientVS22/source/UserInterface/PythonPlayer.h (PARTY_AFFECT_*) extends RefCounted const PARTY_MAX_MEMBER := 8 # 官方最大 8 人队伍 # 经验分配模式 (char_party.cpp) const EXP_MODE_LEVEL := 0 # 按等级比例分配 (NON_PARITY) const EXP_MODE_PARITY := 1 # 均分模式 (PARITY) # 队长战术领导力职权角色分配 (uiparty.py / PythonPlayer.h) const ROLE_NORMAL := 0 # 普通队员 const ROLE_ATTACKER := 1 # 攻击者 (增加物理攻击力) const ROLE_TANKER := 2 # 肉盾 (增加生命值上限) const ROLE_BUFFER := 3 # 增益者 (增加法术/技能攻击力) const ROLE_SKILL_MASTER := 4 # 技能大师 (减少技能冷却时间) const ROLE_DEFENDER := 5 # 防御者 (增加防御力) const ROLE_BERSERKER := 6 # 狂战士 (增加攻击速度) # 角色光环属性加成表 const ROLE_BUFF_BONUSES := { ROLE_ATTACKER: { "stat": "att_grade", "val": 30 }, ROLE_TANKER: { "stat": "max_hp", "val": 2500 }, ROLE_BUFFER: { "stat": "magic_att", "val": 25 }, ROLE_SKILL_MASTER: { "stat": "cooldown_reduction", "val": 15 }, ROLE_DEFENDER: { "stat": "def_grade", "val": 40 }, ROLE_BERSERKER: { "stat": "att_speed", "val": 15 } } class PartyMember: var pid: int var name: String var level: int var is_leader: bool = false var role: int = ROLE_NORMAL var cur_hp: int = 1000 var max_hp: int = 1000 func _init(p_pid: int, p_name: String, p_lvl: int, p_leader: bool = false) -> void: pid = p_pid name = p_name level = p_lvl is_leader = p_leader role = ROLE_NORMAL cur_hp = 1000 max_hp = 1000 func get_hp_percent() -> float: if max_hp <= 0: return 0.0 return clamp(float(cur_hp) / float(max_hp), 0.0, 1.0) var members: Dictionary = {} # pid -> PartyMember var leader_pid: int = -1 var exp_distribution_mode: int = EXP_MODE_PARITY func _init(p_leader_pid: int = -1, p_leader_name: String = "", p_leader_lvl: int = 1) -> void: members.clear() leader_pid = -1 exp_distribution_mode = EXP_MODE_PARITY if p_leader_pid > 0: create_party(p_leader_pid, p_leader_name, p_leader_lvl) # 1. 创建队伍 func create_party(p_pid: int, p_name: String, p_lvl: int) -> bool: members.clear() leader_pid = p_pid var leader = PartyMember.new(p_pid, p_name, p_lvl, true) members[p_pid] = leader return true # 2. 邀请/加入队员 (CParty::Join) func add_member(p_pid: int, p_name: String, p_lvl: int) -> Dictionary: var res := { "success": false, "error_code": "OK", "message": "" } if members.size() >= PARTY_MAX_MEMBER: res["error_code"] = "PARTY_FULL" res["message"] = "队伍人数已达到 8 人上限。" return res if members.has(p_pid): res["error_code"] = "ALREADY_IN_PARTY" res["message"] = "该玩家已在队伍中。" return res var m = PartyMember.new(p_pid, p_name, p_lvl, false) members[p_pid] = m res["success"] = true res["message"] = "%s 加入了队伍。" % p_name return res # 3. 踢出队员 (CParty::Quit / Expel) func expel_member(caller_pid: int, target_pid: int) -> Dictionary: var res := { "success": false, "error_code": "OK", "message": "" } if caller_pid != leader_pid: res["error_code"] = "NOT_LEADER" res["message"] = "只有队长才能踢出队员。" return res if not members.has(target_pid): res["error_code"] = "MEMBER_NOT_FOUND" return res if target_pid == leader_pid: res["error_code"] = "CANNOT_EXPEL_LEADER" res["message"] = "队长不能踢出自己。" return res var target_name: String = members[target_pid].name members.erase(target_pid) res["success"] = true res["message"] = "%s 已被移出队伍。" % target_name return res # 4. 离队与队长顺延/解散 (CParty::Quit) func leave_party(p_pid: int) -> Dictionary: var res := { "success": false, "dissolved": false, "new_leader": -1 } if not members.has(p_pid): return res var was_leader: bool = (p_pid == leader_pid) members.erase(p_pid) if members.is_empty(): leader_pid = -1 res["dissolved"] = true res["success"] = true return res # 若队长离队,移交给第一位队员 if was_leader: var new_lead_key: int = members.keys()[0] leader_pid = new_lead_key members[new_lead_key].is_leader = true res["new_leader"] = new_lead_key res["success"] = true return res # 5. 队长战术领导力角色光环配置 (CParty::SetRole) func set_member_role(caller_pid: int, target_pid: int, role: int) -> Dictionary: var res := { "success": false, "error_code": "OK", "message": "" } if caller_pid != leader_pid: res["error_code"] = "NOT_LEADER" res["message"] = "只有队长有权分配战术光环。" return res if not members.has(target_pid): res["error_code"] = "MEMBER_NOT_FOUND" return res # 检查角色是否已被队伍中其他成员占用 (非 ROLE_NORMAL) if role != ROLE_NORMAL: for k in members: if k != target_pid and members[k].role == role: res["error_code"] = "ROLE_ALREADY_ASSIGNED" res["message"] = "该战术光环已被其他队员占用。" return res members[target_pid].role = role res["success"] = true res["role"] = role res["buff"] = ROLE_BUFF_BONUSES.get(role, {}) res["message"] = "成功为队员分配战术角色。" return res # 6. 获取队员当前享有的领导力光环加成 func get_member_buff(p_pid: int) -> Dictionary: if not members.has(p_pid): return {} var r: int = members[p_pid].role return ROLE_BUFF_BONUSES.get(r, {}) # 7. 切换经验分配模式 func set_exp_distribution_mode(caller_pid: int, mode: int) -> bool: if caller_pid != leader_pid: return false if mode == EXP_MODE_PARITY or mode == EXP_MODE_LEVEL: exp_distribution_mode = mode return true return false # 8. 队伍击杀经验结算与分发 (1:1 CParty::DistributeExp) func distribute_exp(total_exp: int) -> Dictionary: var distribution := {} if members.is_empty() or total_exp <= 0: return distribution var count := members.size() if exp_distribution_mode == EXP_MODE_PARITY: # 均分模式: 每个队员获得 total_exp / count var per_member: int = total_exp / count for k in members: distribution[k] = per_member else: # 等级权重模式: 按队员等级比例分配 var sum_levels: int = 0 for k in members: sum_levels += members[k].level for k in members: var share: int = int(float(total_exp) * float(members[k].level) / float(sum_levels)) distribution[k] = share return distribution # 9. 同步队员生命值百分比 func sync_member_hp(p_pid: int, cur: int, max_h: int) -> void: if members.has(p_pid): members[p_pid].cur_hp = cur members[p_pid].max_hp = max_h