# guild_skill_system.gd —— Metin2 40250 公会等级与 7 大神龙技能树系统 1:1 # 对照 40250 服务端 guild.cpp, guild_manager.cpp, PythonGuild.cpp, skilldesc.txt:23-29 class_name GuildSkillSystem extends RefCounted signal guild_level_up(new_level: int, skill_points: int) signal guild_skill_cast(skill_id: int, duration: float) const MAX_GUILD_LEVEL := 20 const MAX_SKILL_LEVEL := 7 # 7 官方公会技能 (skilldesc.txt:23-29) const SKILL_DRAGON_EYES := 151 # 龙神之眼: 被动增加最大神龙精力 const SKILL_DRAGON_BLOOD := 152 # 龙神之血: 最大 HP 提升 const SKILL_DRAGON_BLESSING := 153# 龙神庇护: 最大 SP 提升 const SKILL_HOLY_ARMOR := 154 # 圣灵之甲: 防御力百分比提升 const SKILL_ACCELERATE := 155 # 疾风步: 攻击与移动速度提升 const SKILL_DRAGON_RAGE := 156 # 龙神之怒: 致命一击几率提升 const SKILL_CASTING_AID := 157 # 咏唱神助: 施法提速 / 技能冷却缩减 const GUILD_SKILLS: Dictionary = { SKILL_DRAGON_EYES: { "name": "龙神之眼", "is_passive": true, "spirit_cost": 0, "cooldown": 0.0, "duration": 0.0 }, SKILL_DRAGON_BLOOD: { "name": "龙神之血", "is_passive": false, "spirit_cost": 20, "cooldown": 60.0, "duration": 300.0 # 5 分钟 }, SKILL_DRAGON_BLESSING: { "name": "龙神庇护", "is_passive": false, "spirit_cost": 20, "cooldown": 60.0, "duration": 300.0 }, SKILL_HOLY_ARMOR: { "name": "圣灵之甲", "is_passive": false, "spirit_cost": 25, "cooldown": 60.0, "duration": 300.0 }, SKILL_ACCELERATE: { "name": "疾风步", "is_passive": false, "spirit_cost": 25, "cooldown": 60.0, "duration": 300.0 }, SKILL_DRAGON_RAGE: { "name": "龙神之怒", "is_passive": false, "spirit_cost": 30, "cooldown": 60.0, "duration": 300.0 }, SKILL_CASTING_AID: { "name": "咏唱神助", "is_passive": false, "spirit_cost": 30, "cooldown": 60.0, "duration": 300.0 } } # 公会基础属性 var guild_level: int = 1 var guild_exp: int = 0 var skill_points: int = 0 var max_spirit: int = 100 var current_spirit: int = 100 # 技能加点等级: skill_id -> level (0~7) var skill_levels: Dictionary = { SKILL_DRAGON_EYES: 0, SKILL_DRAGON_BLOOD: 0, SKILL_DRAGON_BLESSING: 0, SKILL_HOLY_ARMOR: 0, SKILL_ACCELERATE: 0, SKILL_DRAGON_RAGE: 0, SKILL_CASTING_AID: 0 } # 技能冷却与生效增益 var skill_cooldowns: Dictionary = {} var active_buffs: Dictionary = {} # skill_id -> { duration, value } # 计算升级所需经验 (guild.cpp) static func get_exp_needed_for_level(lvl: int) -> int: return lvl * 50000 # 捐献公会经验 func donate_exp(amount: int) -> Dictionary: if guild_level >= MAX_GUILD_LEVEL: return {"ok": false, "reason": "MAX_LEVEL", "msg": "公会已达到最高 20 级!"} guild_exp += amount var leveled_up := false var levels_gained := 0 while guild_level < MAX_GUILD_LEVEL: var needed = get_exp_needed_for_level(guild_level) if guild_exp >= needed: guild_exp -= needed guild_level += 1 skill_points += 1 levels_gained += 1 leveled_up = true else: break if leveled_up: _recalculate_spirit() guild_level_up.emit(guild_level, skill_points) return { "ok": true, "guild_level": guild_level, "guild_exp": guild_exp, "needed_exp": get_exp_needed_for_level(guild_level), "skill_points": skill_points, "leveled_up": leveled_up } # 升级公会技能 func level_up_skill(skill_id: int) -> Dictionary: if not GUILD_SKILLS.has(skill_id): return {"ok": false, "reason": "INVALID_SKILL"} if skill_points <= 0: return {"ok": false, "reason": "NO_SKILL_POINTS", "msg": "可用公会技能点不足!"} var cur_lvl: int = int(skill_levels.get(skill_id, 0)) if cur_lvl >= MAX_SKILL_LEVEL: return {"ok": false, "reason": "MAX_SKILL_LEVEL", "msg": "该公会技能已满级!"} skill_levels[skill_id] = cur_lvl + 1 skill_points -= 1 _recalculate_spirit() return { "ok": true, "skill_id": skill_id, "new_level": skill_levels[skill_id], "remaining_points": skill_points } func _recalculate_spirit() -> void: # 151 龙神之眼扩充神龙精力 var eyes_lvl: int = int(skill_levels.get(SKILL_DRAGON_EYES, 0)) var bonus_sp: int = int(round(float(eyes_lvl) / float(MAX_SKILL_LEVEL) * 100.0)) max_spirit = 100 + bonus_sp current_spirit = mini(current_spirit, max_spirit) # 施放公会技能 func cast_guild_skill(skill_id: int) -> Dictionary: if not GUILD_SKILLS.has(skill_id): return {"ok": false, "reason": "INVALID_SKILL"} var cfg: Dictionary = GUILD_SKILLS[skill_id] if bool(cfg["is_passive"]): return {"ok": false, "reason": "PASSIVE_SKILL", "msg": "被动技能无需主动施放!"} var lvl: int = int(skill_levels.get(skill_id, 0)) if lvl <= 0: return {"ok": false, "reason": "NOT_LEARNED", "msg": "尚未学习该公会技能!"} # 检查冷却 if float(skill_cooldowns.get(skill_id, 0.0)) > 0.0: return {"ok": false, "reason": "COOLDOWN_ACTIVE", "remaining": skill_cooldowns[skill_id]} # 检查精力消耗 var cost: int = int(cfg["spirit_cost"]) if current_spirit < cost: return {"ok": false, "reason": "NOT_ENOUGH_SPIRIT", "msg": "公会神龙精力不足!"} # 扣除精力并进入冷却 current_spirit -= cost skill_cooldowns[skill_id] = float(cfg["cooldown"]) # 计算技能数值 (对齐 skilldesc.txt: k = lvl / 7.0) var k: float = float(lvl) / float(MAX_SKILL_LEVEL) var dur: float = float(cfg["duration"]) var val: float = 0.0 match skill_id: SKILL_DRAGON_BLOOD: val = k * 20.0 # Max HP +20% SKILL_DRAGON_BLESSING: val = k * 20.0 # Max SP +20% SKILL_HOLY_ARMOR: val = k * 10.0 # DEF +10% SKILL_ACCELERATE: val = k * 30.0 # Atk & Motion Speed +30 SKILL_DRAGON_RAGE: val = k * 50.0 # Crit +50% SKILL_CASTING_AID: val = k * 50.0 # Cooldown reduction +50% active_buffs[skill_id] = { "name": cfg["name"], "value": val, "duration": dur, "total_duration": dur } guild_skill_cast.emit(skill_id, dur) return { "ok": true, "skill_id": skill_id, "name": cfg["name"], "value": val, "duration": dur, "current_spirit": current_spirit } # 逐帧更新冷却与生效增益 func update(dt: float) -> void: # 更新技能冷却 for sid in skill_cooldowns.keys(): skill_cooldowns[sid] = maxf(0.0, float(skill_cooldowns[sid]) - dt) if float(skill_cooldowns[sid]) <= 0.0: skill_cooldowns.erase(sid) # 更新增益持续时间 var expired: Array[int] = [] for sid in active_buffs.keys(): var b: Dictionary = active_buffs[sid] b["duration"] = maxf(0.0, float(b["duration"]) - dt) if float(b["duration"]) <= 0.0: expired.append(sid) for sid in expired: active_buffs.erase(sid) # 恢复精力 (每秒恢复 0.5) current_spirit = mini(max_spirit, current_spirit + int(round(0.5 * dt))) # 查询当前激活的所有公会增益 func get_active_bonuses() -> Dictionary: var res: Dictionary = { "max_hp_pct": 0.0, "max_sp_pct": 0.0, "def_pct": 0.0, "speed_bonus": 0.0, "critical_pct": 0.0, "casting_aid_pct": 0.0 } if active_buffs.has(SKILL_DRAGON_BLOOD): res["max_hp_pct"] = float(active_buffs[SKILL_DRAGON_BLOOD]["value"]) if active_buffs.has(SKILL_DRAGON_BLESSING): res["max_sp_pct"] = float(active_buffs[SKILL_DRAGON_BLESSING]["value"]) if active_buffs.has(SKILL_HOLY_ARMOR): res["def_pct"] = float(active_buffs[SKILL_HOLY_ARMOR]["value"]) if active_buffs.has(SKILL_ACCELERATE): res["speed_bonus"] = float(active_buffs[SKILL_ACCELERATE]["value"]) if active_buffs.has(SKILL_DRAGON_RAGE): res["critical_pct"] = float(active_buffs[SKILL_DRAGON_RAGE]["value"]) if active_buffs.has(SKILL_CASTING_AID): res["casting_aid_pct"] = float(active_buffs[SKILL_CASTING_AID]["value"]) return res