diff --git a/player.gd b/player.gd index e90ce16..b0cba4b 100644 --- a/player.gd +++ b/player.gd @@ -101,6 +101,12 @@ var _defend_mode: String = "" # "schildwall" oder "trotz" var _zornfesseln_target = null var _zornfesseln_strike_timer: float = 0.0 +# Berserker +var is_berserker: bool = false +var _berserker_timer: float = 0.0 +var is_berserker_crash: bool = false +var _crash_timer: float = 0.0 + # Blutrausch — Blutungs-DOT var _bleed_target = null var _bleed_timer: float = 0.0 # verbleibende Dauer @@ -163,6 +169,14 @@ const ZORNFESSELN_COOLDOWN: float = 14.0 const ZORNFESSELN_RANGE: float = 12.0 # Max Zielreichweite const ZORNFESSELN_RAGE: int = 35 const ZORNFESSELN_PULL_DURATION: float = 0.6 # Sekunden bis Gegner da ist +const BERSERKER_COOLDOWN: float = 90.0 +const BERSERKER_MIN_RAGE: int = 50 +const BERSERKER_DURATION: float = 10.0 +const BERSERKER_CRASH_DURATION: float = 2.5 +const BERSERKER_GCD_MULT: float = 0.5 # Autoattack 2x schneller +const BERSERKER_DMG_REDUCTION: float = 0.25 # 25% weniger Schaden nehmen +const BERSERKER_CRASH_DMG_MULT: float = 1.5 # 50% mehr Schaden im Crash +const BERSERKER_CRASH_SPEED_MULT: float = 0.5 # 50% langsamer im Crash # Cast System var is_casting: bool = false @@ -304,6 +318,15 @@ func _init_class_skills(): "cooldown": TEKTONISCHER_SCHLAG_COOLDOWN, "cast_time": 0.0, }) + if level >= 35: + available_skills.append({ + "id": "berserker", + "name": "Berserker", + "description": "Entfesselt die gesamte Wut. 10s: schneller, stärker, unaufhaltsamer. Danach 2.5s Erschöpfung.", + "icon": "res://icons/berserker_icon.svg", + "cooldown": BERSERKER_COOLDOWN, + "cast_time": 0.0, + }) if level >= 28: available_skills.append({ "id": "zornfesseln", @@ -503,6 +526,10 @@ func take_damage(amount: int): var missing_hp = 1.0 - (float(current_hp) / float(max_hp)) var reduction = missing_hp * TROTZ_MAX_REDUCTION effective = int(effective * (1.0 - reduction)) + if is_berserker: + effective = int(effective * (1.0 - BERSERKER_DMG_REDUCTION)) + if is_berserker_crash: + effective = int(effective * BERSERKER_CRASH_DMG_MULT) effective = max(1, effective) current_hp = clamp(current_hp - effective, 0, max_hp) hud.update_health(current_hp, max_hp) @@ -537,6 +564,8 @@ func _update_rage_decay(delta: float): return if current_resource <= 0: return + if is_berserker: + return # Wut verfällt nicht während Berserker if _rage_decay_timer > 0.0: _rage_decay_timer -= delta return @@ -662,7 +691,7 @@ func _on_slot_clicked(slot_index: int): _use_consumable_slot(slot_index, slot_content) func execute_skill(skill_id: String): - if is_dead or is_casting or is_drinking: + if is_dead or is_casting or is_drinking or is_berserker_crash: return var skill = _find_skill(skill_id) if skill.is_empty(): @@ -743,6 +772,8 @@ func _apply_skill(skill_id: String): _do_wirbelwind() "zornfesseln": _do_zornfesseln() + "berserker": + _do_berserker() # ─── Autoattack ─────────────────────────────────────────────── @@ -853,6 +884,20 @@ func _do_zornfesseln(): trigger_global_cooldown() print("Zornfesseln! Gegner wird herangezogen...") +# ─── Berserker (Ultimate) ───────────────────────────────────── + +func _do_berserker(): + if current_resource < BERSERKER_MIN_RAGE: + print("Zu wenig Wut für Berserker! (Minimum %d)" % BERSERKER_MIN_RAGE) + return + current_resource = 0 + hud.update_resource(current_resource, max_resource, get_resource_name()) + is_berserker = true + _berserker_timer = BERSERKER_DURATION + is_berserker_crash = false + skill_cooldowns["berserker"] = BERSERKER_COOLDOWN + print("BERSERKER! 10 Sekunden Wahnsinn...") + # ─── Durchbeißen / Schildwall / Trotz ──────────────────────── # ─── Blutrausch ─────────────────────────────────────────────── @@ -944,7 +989,10 @@ func _use_consumable_slot(slot_index: int, item: Consumable): # ─── GCD ────────────────────────────────────────────────────── func trigger_global_cooldown(): - global_cooldown = get_attack_cooldown() + var gcd = get_attack_cooldown() + if is_berserker: + gcd *= BERSERKER_GCD_MULT + global_cooldown = gcd # ═══════════════════════════════════════════════════════════════ # ZIELAUSWAHL @@ -1209,6 +1257,18 @@ func _physics_process(delta): # ── Wut-Verfall ─────────────────────────────────────────── _update_rage_decay(delta) + # ── Berserker / Crash Timer ─────────────────────────────── + if is_berserker: + _berserker_timer -= delta + if _berserker_timer <= 0.0: + is_berserker = false + is_berserker_crash = true + _crash_timer = BERSERKER_CRASH_DURATION + if is_berserker_crash: + _crash_timer -= delta + if _crash_timer <= 0.0: + is_berserker_crash = false + # ── Zornfesseln Schlag ──────────────────────────────────── if _zornfesseln_strike_timer > 0.0: _zornfesseln_strike_timer -= delta @@ -1365,6 +1425,8 @@ func _physics_process(delta): # ── Velocity ───────────────────────────────────────────── var current_speed = SPEED if is_walking else SPRINT_SPEED + if is_berserker_crash: + current_speed *= BERSERKER_CRASH_SPEED_MULT if is_rolling: velocity.x = roll_direction.x * SPRINT_SPEED velocity.z = roll_direction.z * SPRINT_SPEED