feat: Berserker Ultimate implementiert (Krieger Level 35)

- Verbraucht gesamte Wut (Minimum 50)
- 10s aktiv: 2x Autoattack-Speed, 25% weniger Schaden, Wut verfällt nicht
- 2.5s Crash danach: 50% mehr Schaden nehmen, 50% langsamer, Skills gesperrt
- Cooldown 90s

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Andre 2026-03-19 21:39:51 +01:00
parent 63d0f3e64d
commit 7ccc0ef8e7

View file

@ -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