# monarch_election_ui_system.gd —— 40250 帝国君主大选投票公示系统 1:1 # 严格对照: # metin2/src/server/game/src/monarch.h, monarch.cpp (CMonarch) # metin2/src/server/share/locale/english/quest/xxx_monarch.quest # 40250/Server Client TMP4/mysql/player/monarch_candidacy.MYD, monarch_election.MYD extends RefCounted const EMPIRE_SHINSOO := 1 # 赤蛇国 (进国) const EMPIRE_CHUNJO := 2 # 白虎国 (顺天) const EMPIRE_JINNO := 3 # 苍龙国 (忍国) const STATUS_CLOSED := 0 # 选举未开放 const STATUS_CANDIDACY := 1 # 候选人报名登记期 const STATUS_VOTING := 2 # 全民大选投票期 const STATUS_CONCLUDED := 3 # 大选揭晓,君主即位 const MIN_CANDIDATE_LEVEL := 50 const MIN_VOTER_LEVEL := 50 const CANDIDACY_FEE := 1000000 # 报名保证金 1,000,000 金币 const MAX_CANDIDATES_PER_EMPIRE := 8 # 每国最多 8 名候选人 class CandidateInfo: var pid: int var name: String var empire: int var level: int var votes: int = 0 var manifesto: String = "" func _init(p_pid: int, p_name: String, p_emp: int, p_lvl: int, p_manifesto: String) -> void: pid = p_pid name = p_name empire = p_emp level = p_lvl votes = 0 manifesto = p_manifesto # 选举状态字典: empire_id -> status var election_states: Dictionary = { EMPIRE_SHINSOO: STATUS_CLOSED, EMPIRE_CHUNJO: STATUS_CLOSED, EMPIRE_JINNO: STATUS_CLOSED } # 候选人名册: empire_id -> Array of CandidateInfo var candidates: Dictionary = { EMPIRE_SHINSOO: [], EMPIRE_CHUNJO: [], EMPIRE_JINNO: [] } # 选民投票记录: empire_id -> { voter_pid: candidate_pid } var voter_records: Dictionary = { EMPIRE_SHINSOO: {}, EMPIRE_CHUNJO: {}, EMPIRE_JINNO: {} } # 现任君主数据: empire_id -> { "pid": int, "name": String, "treasury": int, "tax_rate": int } var current_monarchs: Dictionary = { EMPIRE_SHINSOO: { "pid": 0, "name": "", "treasury": 10000000, "tax_rate": 3 }, EMPIRE_CHUNJO: { "pid": 0, "name": "", "treasury": 10000000, "tax_rate": 3 }, EMPIRE_JINNO: { "pid": 0, "name": "", "treasury": 10000000, "tax_rate": 3 }, } func _init() -> void: reset_all_elections() func reset_all_elections() -> void: for emp in [EMPIRE_SHINSOO, EMPIRE_CHUNJO, EMPIRE_JINNO]: election_states[emp] = STATUS_CLOSED candidates[emp] = [] voter_records[emp] = {} # 1. 管理员开启大选阶段 (GM: Kaiser Wahl Einstellung) func set_election_stage(empire: int, new_status: int) -> bool: if not election_states.has(empire): return false election_states[empire] = new_status return true # 2. 候选人报名参选 (monarch_candidacy) func register_candidacy( pid: int, name: String, empire: int, level: int, player_gold: int, manifesto: String ) -> Dictionary: var res := { "success": false, "gold_cost": 0, "error_code": "OK", "message": "" } if election_states.get(empire) != STATUS_CANDIDACY: res["error_code"] = "CANDIDACY_NOT_OPEN" res["message"] = "当前未处于君主参选登记期。" return res if level < MIN_CANDIDATE_LEVEL: res["error_code"] = "LEVEL_TOO_LOW" res["message"] = "参选君主等级必须达到 Lv 50。" return res if player_gold < CANDIDACY_FEE: res["error_code"] = "INSUFFICIENT_GOLD" res["message"] = "报名参选需缴纳 1,000,000 金币保证金。" return res var emp_candidates: Array = candidates[empire] if emp_candidates.size() >= MAX_CANDIDATES_PER_EMPIRE: res["error_code"] = "CANDIDATES_FULL" res["message"] = "本届君主候选人名额已满 (最多 8 人)。" return res for c in emp_candidates: if c.pid == pid: res["error_code"] = "ALREADY_REGISTERED" res["message"] = "您已成功报名,无需重复登记。" return res var cand = CandidateInfo.new(pid, name, empire, level, manifesto) emp_candidates.append(cand) res["success"] = true res["gold_cost"] = CANDIDACY_FEE res["message"] = "恭喜!您已成功登记为第 %d 帝国君主候选人。" % empire return res # 3. 选民投票 (monarch_election) func cast_vote(voter_pid: int, voter_empire: int, voter_level: int, target_candidate_pid: int) -> Dictionary: var res := { "success": false, "error_code": "OK", "message": "" } if election_states.get(voter_empire) != STATUS_VOTING: res["error_code"] = "VOTING_NOT_OPEN" res["message"] = "当前未处于全民投票大选阶段。" return res if voter_level < MIN_VOTER_LEVEL: res["error_code"] = "VOTER_LEVEL_TOO_LOW" res["message"] = "等级未达到 Lv 50,尚无大选投票权。" return res var records: Dictionary = voter_records[voter_empire] if records.has(voter_pid): res["error_code"] = "ALREADY_VOTED" res["message"] = "您在本届选举中已经投过神圣的一票,不可重复投票。" return res # 查找目标候选人 var target_cand: CandidateInfo = null for c in candidates[voter_empire]: if c.pid == target_candidate_pid: target_cand = c break if target_cand == null: res["error_code"] = "CANDIDATE_NOT_FOUND" res["message"] = "未找到该候选人。" return res # 计票 target_cand.votes += 1 records[voter_pid] = target_candidate_pid res["success"] = true res["message"] = "投票成功!感谢您支持候选人 %s。" % target_cand.name return res # 4. 统计揭晓并任命新君主 func conclude_election(empire: int) -> Dictionary: var res := { "success": false, "winner_pid": 0, "winner_name": "", "votes": 0 } if not election_states.has(empire): return res var emp_candidates: Array = candidates[empire] if emp_candidates.is_empty(): election_states[empire] = STATUS_CLOSED return res # 选出最高票者 var top_cand: CandidateInfo = emp_candidates[0] for c in emp_candidates: if c.votes > top_cand.votes: top_cand = c # 就任君主 current_monarchs[empire]["pid"] = top_cand.pid current_monarchs[empire]["name"] = top_cand.name election_states[empire] = STATUS_CONCLUDED res["success"] = true res["winner_pid"] = top_cand.pid res["winner_name"] = top_cand.name res["votes"] = top_cand.votes return res # 5. 君主行使特权:调整帝国商业税率 (1% ~ 10%) func set_tax_rate(caller_pid: int, empire: int, new_tax: int) -> Dictionary: var res := { "success": false, "error_code": "OK", "message": "" } var monarch = current_monarchs[empire] if caller_pid != monarch["pid"]: res["error_code"] = "NOT_MONARCH" res["message"] = "只有现任帝国君主有权调整商业税率。" return res var clamped_tax: int = clamp(new_tax, 1, 10) monarch["tax_rate"] = clamped_tax res["success"] = true res["tax_rate"] = clamped_tax res["message"] = "帝国商业税率已调整为 %d%%。" % clamped_tax return res # 6. 君主行使特权:释放全帝国神佑祝福 func activate_monarch_blessing(caller_pid: int, empire: int) -> Dictionary: var res := { "success": false, "error_code": "OK", "blessing_buff": {}, "message": "" } var monarch = current_monarchs[empire] if caller_pid != monarch["pid"]: res["error_code"] = "NOT_MONARCH" return res res["success"] = true res["blessing_buff"] = { "exp_bonus": 10, "att_bonus": 10, "duration_sec": 7200 } res["message"] = "君主神佑降临!帝国全体子民获得 +10% 经验与 +10% 攻击力加成 (持续2小时)。" return res