feat: Tektonischer Schlag implementiert (Krieger Level 5)

- AoE um Spieler (Radius 4.0), kostet 30 Wut
- Schaden: 5-10 + 30% Stärke an alle Gegner im Radius
- Slow-Effekt: 60% langsamer für 3s
- enemy.gd: apply_slow() + _slow_factor in _move_toward()
- Skill erscheint ab Level 5 in der Skillliste

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Andre 2026-03-19 21:27:52 +01:00
parent 6b9fc3f0d6
commit 217ce63a28
2 changed files with 64 additions and 5 deletions

View file

@ -50,6 +50,10 @@ var state: State = State.IDLE
var attack_cooldown: float = 0.0
var is_dead: bool = false
# Debuffs
var _slow_timer: float = 0.0
var _slow_factor: float = 1.0 # 1.0 = normal, 0.5 = 50% langsamer
# Patrol
@export var patrol_radius: float = 8.0
@export var patrol_speed: float = 1.5 # Laufgeschwindigkeit beim Patrouillieren
@ -219,6 +223,12 @@ func _physics_process(delta):
if attack_cooldown > 0:
attack_cooldown -= delta
# Slow-Debuff herunterzählen
if _slow_timer > 0.0:
_slow_timer -= delta
if _slow_timer <= 0.0:
_slow_factor = 1.0
# Kein Ziel → Spieler suchen
if target == null or not is_instance_valid(target):
target = null
@ -306,8 +316,8 @@ func _move_toward(goal: Vector3, speed: float):
if direction.length() < 0.1:
return
direction = direction.normalized()
velocity.x = direction.x * speed
velocity.z = direction.z * speed
velocity.x = direction.x * speed * _slow_factor
velocity.z = direction.z * speed * _slow_factor
_face_direction(direction)
@ -406,6 +416,10 @@ func _perform_attack():
_play_anim("autoattack")
print(name + " greift an: " + str(damage) + " Schaden")
func apply_slow(factor: float, duration: float):
_slow_factor = clamp(factor, 0.1, 1.0)
_slow_timer = duration
func take_damage(amount: int):
if is_dead:
return

View file

@ -127,8 +127,11 @@ const GLOBAL_COOLDOWN_TIME: float = 1.5
# Autoattack
var autoattack_active: bool = false
const HEAVY_STRIKE_COOLDOWN: float = 3.0
const HEAVY_STRIKE_RANGE: float = 2.0
const HEAVY_STRIKE_COOLDOWN: float = 3.0
const HEAVY_STRIKE_RANGE: float = 2.0
const TEKTONISCHER_SCHLAG_COOLDOWN: float = 8.0
const TEKTONISCHER_SCHLAG_RADIUS: float = 4.0
const TEKTONISCHER_SCHLAG_RAGE: int = 30
# Cast System
var is_casting: bool = false
@ -256,11 +259,20 @@ func _init_class_skills():
available_skills.append({
"id": "heavy_strike",
"name": "Mächtiger Schlag",
"description": "Schlägt den Gegner mit voller Kraft (10-15 Schaden, 3s CD).",
"description": "Schlägt den Gegner mit voller Kraft. Generiert Wut.",
"icon": "res://icons/heavy_strike_icon.svg",
"cooldown": HEAVY_STRIKE_COOLDOWN,
"cast_time": 0.0,
})
if level >= 5:
available_skills.append({
"id": "tektonischer_schlag",
"name": "Tektonischer Schlag",
"description": "Erschüttert den Boden um dich herum. Schlägt alle Gegner in der Nähe und verlangsamt sie.",
"icon": "res://icons/tektonischer_schlag_icon.svg",
"cooldown": TEKTONISCHER_SCHLAG_COOLDOWN,
"cast_time": 0.0,
})
CharacterClass.MainStat.INTELLIGENCE: # Magier
available_skills.append({
@ -596,6 +608,11 @@ func execute_skill(skill_id: String):
if target == null or not is_instance_valid(target):
print("Kein Ziel!")
return
# Wut-Check für Krieger-Skills
if skill_id in ["tektonischer_schlag"]:
if current_resource < TEKTONISCHER_SCHLAG_RAGE:
print("Zu wenig Wut!")
return
# Cast-Zeit?
if skill["cast_time"] > 0:
@ -628,6 +645,8 @@ func _apply_skill(skill_id: String):
_do_quick_strike()
"frostbolt":
_do_frostbolt()
"tektonischer_schlag":
_do_tektonischer_schlag()
# ─── Autoattack ───────────────────────────────────────────────
@ -670,6 +689,32 @@ func _do_heavy_strike():
print("Heavy Strike! " + str(damage) + " Schaden")
_play_anim_once("heavy_strike")
# ─── Tektonischer Schlag ──────────────────────────────────────
func _do_tektonischer_schlag():
if not _spend_rage(TEKTONISCHER_SCHLAG_RAGE):
return
var space_state = get_world_3d().direct_space_state
var shape = SphereShape3D.new()
shape.radius = TEKTONISCHER_SCHLAG_RADIUS
var query = PhysicsShapeQueryParameters3D.new()
query.shape = shape
query.transform = global_transform
query.exclude = [self]
var hits = space_state.intersect_shape(query)
var hit_count = 0
for hit in hits:
var body = hit.collider
if body.has_method("take_damage"):
var damage = randi_range(5, 10) + int(strength * 0.3)
body.take_damage(damage)
if body.has_method("apply_slow"):
body.apply_slow(0.4, 3.0) # 60% langsamer für 3s
hit_count += 1
skill_cooldowns["tektonischer_schlag"] = TEKTONISCHER_SCHLAG_COOLDOWN
trigger_global_cooldown()
print("Tektonischer Schlag! %d Gegner getroffen" % hit_count)
# ─── Quick Strike (Schurke) ───────────────────────────────────
func _do_quick_strike():