feat: Zornfesseln implementiert (Krieger Level 28)
- Zieht Gegner in Reichweite 12m heran (Pull-Effekt 0.6s) - Nach dem Pull: automatischer Schlag 20-30 + 80% Stärke - enemy.gd: apply_pull() + Pull überschreibt KI-Bewegung - Kostet 35 Wut, Cooldown 14s Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
c81ba9760b
commit
63d0f3e64d
2 changed files with 78 additions and 0 deletions
27
enemy.gd
27
enemy.gd
|
|
@ -54,6 +54,11 @@ var is_dead: bool = false
|
||||||
var _slow_timer: float = 0.0
|
var _slow_timer: float = 0.0
|
||||||
var _slow_factor: float = 1.0 # 1.0 = normal, 0.5 = 50% langsamer
|
var _slow_factor: float = 1.0 # 1.0 = normal, 0.5 = 50% langsamer
|
||||||
|
|
||||||
|
# Pull (Zornfesseln)
|
||||||
|
var _pull_target: Node3D = null
|
||||||
|
var _pull_timer: float = 0.0
|
||||||
|
const PULL_SPEED: float = 18.0
|
||||||
|
|
||||||
# Patrol
|
# Patrol
|
||||||
@export var patrol_radius: float = 8.0
|
@export var patrol_radius: float = 8.0
|
||||||
@export var patrol_speed: float = 1.5 # Laufgeschwindigkeit beim Patrouillieren
|
@export var patrol_speed: float = 1.5 # Laufgeschwindigkeit beim Patrouillieren
|
||||||
|
|
@ -229,6 +234,23 @@ func _physics_process(delta):
|
||||||
if _slow_timer <= 0.0:
|
if _slow_timer <= 0.0:
|
||||||
_slow_factor = 1.0
|
_slow_factor = 1.0
|
||||||
|
|
||||||
|
# Pull-Effekt (Zornfesseln)
|
||||||
|
if _pull_timer > 0.0 and _pull_target != null and is_instance_valid(_pull_target):
|
||||||
|
_pull_timer -= delta
|
||||||
|
var dir = (_pull_target.global_position - global_position)
|
||||||
|
dir.y = 0
|
||||||
|
if dir.length() > 1.0:
|
||||||
|
dir = dir.normalized()
|
||||||
|
velocity.x = dir.x * PULL_SPEED
|
||||||
|
velocity.z = dir.z * PULL_SPEED
|
||||||
|
else:
|
||||||
|
_pull_timer = 0.0 # Nah genug — Pull beendet
|
||||||
|
|
||||||
|
# Pull aktiv → normale KI überspringen
|
||||||
|
if _pull_timer > 0.0:
|
||||||
|
move_and_slide()
|
||||||
|
return
|
||||||
|
|
||||||
# Kein Ziel → Spieler suchen
|
# Kein Ziel → Spieler suchen
|
||||||
if target == null or not is_instance_valid(target):
|
if target == null or not is_instance_valid(target):
|
||||||
target = null
|
target = null
|
||||||
|
|
@ -416,6 +438,11 @@ func _perform_attack():
|
||||||
_play_anim("autoattack")
|
_play_anim("autoattack")
|
||||||
print(name + " greift an: " + str(damage) + " Schaden")
|
print(name + " greift an: " + str(damage) + " Schaden")
|
||||||
|
|
||||||
|
func apply_pull(source: Node3D, duration: float):
|
||||||
|
_pull_target = source
|
||||||
|
_pull_timer = duration
|
||||||
|
state = State.CHASING # Aggro auslösen
|
||||||
|
|
||||||
func apply_slow(factor: float, duration: float):
|
func apply_slow(factor: float, duration: float):
|
||||||
_slow_factor = clamp(factor, 0.1, 1.0)
|
_slow_factor = clamp(factor, 0.1, 1.0)
|
||||||
_slow_timer = duration
|
_slow_timer = duration
|
||||||
|
|
|
||||||
51
player.gd
51
player.gd
|
|
@ -97,6 +97,10 @@ var is_defending: bool = false
|
||||||
var _defend_timer: float = 0.0
|
var _defend_timer: float = 0.0
|
||||||
var _defend_mode: String = "" # "schildwall" oder "trotz"
|
var _defend_mode: String = "" # "schildwall" oder "trotz"
|
||||||
|
|
||||||
|
# Zornfesseln — verzögerter Schlag nach Pull
|
||||||
|
var _zornfesseln_target = null
|
||||||
|
var _zornfesseln_strike_timer: float = 0.0
|
||||||
|
|
||||||
# Blutrausch — Blutungs-DOT
|
# Blutrausch — Blutungs-DOT
|
||||||
var _bleed_target = null
|
var _bleed_target = null
|
||||||
var _bleed_timer: float = 0.0 # verbleibende Dauer
|
var _bleed_timer: float = 0.0 # verbleibende Dauer
|
||||||
|
|
@ -155,6 +159,10 @@ const BLUTRAUSCH_DOT_DAMAGE: int = 4 # Schaden pro Tick
|
||||||
const WIRBELWIND_COOLDOWN: float = 6.0
|
const WIRBELWIND_COOLDOWN: float = 6.0
|
||||||
const WIRBELWIND_RADIUS: float = 3.5
|
const WIRBELWIND_RADIUS: float = 3.5
|
||||||
const WIRBELWIND_RAGE: int = 40
|
const WIRBELWIND_RAGE: int = 40
|
||||||
|
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
|
||||||
|
|
||||||
# Cast System
|
# Cast System
|
||||||
var is_casting: bool = false
|
var is_casting: bool = false
|
||||||
|
|
@ -296,6 +304,15 @@ func _init_class_skills():
|
||||||
"cooldown": TEKTONISCHER_SCHLAG_COOLDOWN,
|
"cooldown": TEKTONISCHER_SCHLAG_COOLDOWN,
|
||||||
"cast_time": 0.0,
|
"cast_time": 0.0,
|
||||||
})
|
})
|
||||||
|
if level >= 28:
|
||||||
|
available_skills.append({
|
||||||
|
"id": "zornfesseln",
|
||||||
|
"name": "Zornfesseln",
|
||||||
|
"description": "Reißt einen Gegner heran und schlägt ihn mit voller Wucht.",
|
||||||
|
"icon": "res://icons/zornfesseln_icon.svg",
|
||||||
|
"cooldown": ZORNFESSELN_COOLDOWN,
|
||||||
|
"cast_time": 0.0,
|
||||||
|
})
|
||||||
if level >= 20:
|
if level >= 20:
|
||||||
available_skills.append({
|
available_skills.append({
|
||||||
"id": "wirbelwind",
|
"id": "wirbelwind",
|
||||||
|
|
@ -680,6 +697,10 @@ func execute_skill(skill_id: String):
|
||||||
if current_resource < WIRBELWIND_RAGE:
|
if current_resource < WIRBELWIND_RAGE:
|
||||||
print("Zu wenig Wut!")
|
print("Zu wenig Wut!")
|
||||||
return
|
return
|
||||||
|
if skill_id == "zornfesseln":
|
||||||
|
if current_resource < ZORNFESSELN_RAGE:
|
||||||
|
print("Zu wenig Wut!")
|
||||||
|
return
|
||||||
|
|
||||||
# Cast-Zeit?
|
# Cast-Zeit?
|
||||||
if skill["cast_time"] > 0:
|
if skill["cast_time"] > 0:
|
||||||
|
|
@ -720,6 +741,8 @@ func _apply_skill(skill_id: String):
|
||||||
_do_blutrausch()
|
_do_blutrausch()
|
||||||
"wirbelwind":
|
"wirbelwind":
|
||||||
_do_wirbelwind()
|
_do_wirbelwind()
|
||||||
|
"zornfesseln":
|
||||||
|
_do_zornfesseln()
|
||||||
|
|
||||||
# ─── Autoattack ───────────────────────────────────────────────
|
# ─── Autoattack ───────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
@ -812,6 +835,24 @@ func _do_wirbelwind():
|
||||||
trigger_global_cooldown()
|
trigger_global_cooldown()
|
||||||
print("Wirbelwind! %d Gegner getroffen" % hit_count)
|
print("Wirbelwind! %d Gegner getroffen" % hit_count)
|
||||||
|
|
||||||
|
# ─── Zornfesseln ──────────────────────────────────────────────
|
||||||
|
|
||||||
|
func _do_zornfesseln():
|
||||||
|
if target == null or not is_instance_valid(target):
|
||||||
|
return
|
||||||
|
var dist = global_position.distance_to(target.global_position)
|
||||||
|
if dist > ZORNFESSELN_RANGE:
|
||||||
|
print("Ziel zu weit für Zornfesseln!")
|
||||||
|
return
|
||||||
|
if not _spend_rage(ZORNFESSELN_RAGE):
|
||||||
|
return
|
||||||
|
target.apply_pull(self, ZORNFESSELN_PULL_DURATION)
|
||||||
|
_zornfesseln_target = target
|
||||||
|
_zornfesseln_strike_timer = ZORNFESSELN_PULL_DURATION
|
||||||
|
skill_cooldowns["zornfesseln"] = ZORNFESSELN_COOLDOWN
|
||||||
|
trigger_global_cooldown()
|
||||||
|
print("Zornfesseln! Gegner wird herangezogen...")
|
||||||
|
|
||||||
# ─── Durchbeißen / Schildwall / Trotz ────────────────────────
|
# ─── Durchbeißen / Schildwall / Trotz ────────────────────────
|
||||||
|
|
||||||
# ─── Blutrausch ───────────────────────────────────────────────
|
# ─── Blutrausch ───────────────────────────────────────────────
|
||||||
|
|
@ -1168,6 +1209,16 @@ func _physics_process(delta):
|
||||||
# ── Wut-Verfall ───────────────────────────────────────────
|
# ── Wut-Verfall ───────────────────────────────────────────
|
||||||
_update_rage_decay(delta)
|
_update_rage_decay(delta)
|
||||||
|
|
||||||
|
# ── Zornfesseln Schlag ────────────────────────────────────
|
||||||
|
if _zornfesseln_strike_timer > 0.0:
|
||||||
|
_zornfesseln_strike_timer -= delta
|
||||||
|
if _zornfesseln_strike_timer <= 0.0:
|
||||||
|
if _zornfesseln_target != null and is_instance_valid(_zornfesseln_target):
|
||||||
|
var damage = randi_range(20, 30) + int(strength * 0.8)
|
||||||
|
_zornfesseln_target.take_damage(damage)
|
||||||
|
print("Zornfesseln Schlag! %d Schaden" % damage)
|
||||||
|
_zornfesseln_target = null
|
||||||
|
|
||||||
# ── Blutungs-DOT ──────────────────────────────────────────
|
# ── Blutungs-DOT ──────────────────────────────────────────
|
||||||
if _bleed_timer > 0.0:
|
if _bleed_timer > 0.0:
|
||||||
_bleed_timer -= delta
|
_bleed_timer -= delta
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue