# title_achievement_system.gd —— Metin2 40250 殿堂级头衔与成就系统 1:1 # 对照 40250 服务端 char.cpp, questmanager.cpp, locale_string.txt class_name TitleAchievementSystem extends RefCounted signal achievement_unlocked(ach_id: String, ach_name: String, title: String) signal title_equipped(title_name: String, bonuses: Dictionary) signal title_unequipped() const ACHIEVEMENTS: Dictionary = { "ACH_DEMON_TOWER": { "name": "恶魔之塔登顶", "desc": "突破恶魔之塔 9 层并斩杀死神", "title": "恶魔征服者", "points": 50, "bonuses": {"max_hp": 500} }, "ACH_SPIDER_BARONESS": { "name": "蛛皇陨落", "desc": "在蜘蛛洞穴三层巢穴击败蜘蛛男爵夫人", "title": "蛛巢克星", "points": 50, "bonuses": {"monster_dmg_pct": 5} }, "ACH_BERAN_SETAOU": { "name": "冰龙之诛", "desc": "击破四大魔石并消灭冰龙贝兰-塞陶", "title": "屠龙勇士", "points": 100, "bonuses": {"boss_dmg_pct": 10} }, "ACH_AZRAEL": { "name": "冥王末日", "desc": "穿过地下墓穴七层击破冥王阿兹瑞尔", "title": "深渊征服者", "points": 100, "bonuses": {"def": 50} }, "ACH_FOUR_WORLD_BOSSES": { "name": "四方平定", "desc": "击杀野外九尾妖狐、沙漠龟、黄虎之魂与烈焰领主", "title": "大陆守护者", "points": 150, "bonuses": {"critical_pct": 5} }, "ACH_SKILL_GRANDMASTER": { "name": "大巧不工", "desc": "将任意核心战斗技能修炼至 P 级完美境界", "title": "武学宗师", "points": 80, "bonuses": {"cast_speed": 10} }, "ACH_EPIC_BLACKSMITH": { "name": "神兵天成", "desc": "成功完成修元平史诗武器或蓝钢神甲升阶转换", "title": "神工锻造师", "points": 80, "bonuses": {"att": 50} } } var unlocked_achievements: Dictionary = {} # ach_id -> bool var unlocked_titles: Array = [] # list of title strings var total_achievement_points: int = 0 var active_title: String = "" # 追踪并达成成就 func complete_achievement(ach_id: String) -> Dictionary: if not ACHIEVEMENTS.has(ach_id): return {"ok": false, "reason": "INVALID_ACH_ID", "msg": "未知的成就标识!"} if unlocked_achievements.get(ach_id, false): return {"ok": false, "reason": "ALREADY_COMPLETED", "msg": "该成就已达成!"} var cfg: Dictionary = ACHIEVEMENTS[ach_id] unlocked_achievements[ach_id] = true total_achievement_points += int(cfg["points"]) var title_name: String = cfg["title"] if not unlocked_titles.has(title_name): unlocked_titles.append(title_name) achievement_unlocked.emit(ach_id, cfg["name"], title_name) return { "ok": true, "ach_id": ach_id, "name": cfg["name"], "title": title_name, "points_awarded": cfg["points"], "total_points": total_achievement_points, "msg": "达成里程碑成就【%s】!解锁荣耀称号【%s】!" % [cfg["name"], title_name] } # 佩戴称号 func equip_title(title_name: String) -> Dictionary: if not unlocked_titles.has(title_name): return {"ok": false, "reason": "TITLE_NOT_UNLOCKED", "msg": "你尚未解锁该头衔称号!"} active_title = title_name var bonuses := get_active_bonuses() title_equipped.emit(title_name, bonuses) return { "ok": true, "active_title": active_title, "bonuses": bonuses, "msg": "已成功佩戴头衔【%s】!战力属性已生效!" % title_name } # 卸下称号 func unequip_title() -> void: active_title = "" title_unequipped.emit() # 获取当前佩戴称号的属性加成 func get_active_bonuses() -> Dictionary: if active_title.is_empty(): return {} for cfg in ACHIEVEMENTS.values(): if cfg["title"] == active_title: return cfg["bonuses"].duplicate() return {} # 查询成就状态 func is_achievement_unlocked(ach_id: String) -> bool: return unlocked_achievements.get(ach_id, false)