This commit is contained in:
Marek Le
2026-03-30 09:03:29 +02:00
parent 80a65fa555
commit 4fddc74df1
31 changed files with 295 additions and 153 deletions

View File

@@ -1,19 +1,23 @@
extends Node
const GCD_TIME := 0.5
const AA_DAMAGE := 10.0
const AA_COOLDOWN := 1.0
const AA_RANGE := 20.0
@onready var player: CharacterBody3D = get_parent()
@onready var targeting: Node = get_parent().get_node("Targeting")
@onready var player_class: Node = get_parent().get_node("PlayerClass")
@onready var role: Node = get_parent().get_node("Role")
var abilities: Array = []
var cooldowns: Array[float] = [0.0, 0.0, 0.0, 0.0, 0.0]
var max_cooldowns: Array[float] = [0.0, 0.0, 0.0, 0.0, 0.0]
var gcd_timer := 0.0
var aa_timer := 0.0
func _ready() -> void:
_load_abilities()
EventBus.class_changed.connect(_on_class_changed)
EventBus.role_changed.connect(_on_role_changed)
func _process(delta: float) -> void:
if gcd_timer > 0:
@@ -22,9 +26,26 @@ func _process(delta: float) -> void:
if cooldowns[i] > 0:
cooldowns[i] -= delta
EventBus.cooldown_tick.emit(cooldowns, max_cooldowns, gcd_timer)
_auto_attack(delta)
func _auto_attack(delta: float) -> void:
aa_timer -= delta
if aa_timer > 0:
return
if not targeting.in_combat or not targeting.current_target:
return
if not is_instance_valid(targeting.current_target):
return
var dist := player.global_position.distance_to(targeting.current_target.global_position)
if dist > AA_RANGE:
return
var dmg := apply_passive(AA_DAMAGE)
EventBus.damage_requested.emit(player, targeting.current_target, dmg)
print("AA: %s Schaden an %s" % [dmg, targeting.current_target.name])
aa_timer = AA_COOLDOWN
func _load_abilities() -> void:
var ability_set: AbilitySet = player_class.get_ability_set()
var ability_set: AbilitySet = role.get_ability_set()
if ability_set:
abilities = ability_set.abilities
else:
@@ -59,5 +80,5 @@ func apply_passive(base_damage: float) -> float:
return base_damage * (1.0 + ability.damage / 100.0)
return base_damage
func _on_class_changed(_player: Node, _class_type: int) -> void:
func _on_role_changed(_player: Node, _role_type: int) -> void:
_load_abilities()

View File

@@ -22,7 +22,7 @@ func _ready() -> void:
EventBus.shield_changed.connect(_on_shield_changed)
EventBus.entity_died.connect(_on_entity_died)
EventBus.player_respawned.connect(_on_player_respawned)
EventBus.class_changed.connect(_on_class_changed)
EventBus.role_changed.connect(_on_role_changed)
EventBus.respawn_tick.connect(_on_respawn_tick)
EventBus.cooldown_tick.connect(_on_cooldown_tick)
@@ -46,8 +46,8 @@ func _on_player_respawned(_player: Node) -> void:
func _on_respawn_tick(timer: float) -> void:
respawn_label.text = str(ceil(timer))
func _on_class_changed(_player: Node, class_type: int) -> void:
match class_type:
func _on_role_changed(_player: Node, role_type: int) -> void:
match role_type:
0: class_icon.text = "T"
1: class_icon.text = "D"
2: class_icon.text = "H"

View File

@@ -1,37 +0,0 @@
extends Node
enum PlayerClass { TANK, DAMAGE, HEALER }
var current_class: int = PlayerClass.DAMAGE
@export var tank_set: AbilitySet
@export var damage_set: AbilitySet
@export var healer_set: AbilitySet
@onready var player: CharacterBody3D = get_parent()
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("class_tank"):
set_class(PlayerClass.TANK)
elif event.is_action_pressed("class_damage"):
set_class(PlayerClass.DAMAGE)
elif event.is_action_pressed("class_healer"):
set_class(PlayerClass.HEALER)
func set_class(new_class: int) -> void:
current_class = new_class
EventBus.class_changed.emit(player, current_class)
func get_class_icon() -> String:
match current_class:
PlayerClass.TANK: return "T"
PlayerClass.DAMAGE: return "D"
PlayerClass.HEALER: return "H"
return ""
func get_ability_set() -> AbilitySet:
match current_class:
PlayerClass.TANK: return tank_set
PlayerClass.DAMAGE: return damage_set
PlayerClass.HEALER: return healer_set
return damage_set

View File

@@ -1 +0,0 @@
uid://rus4umqvvqq4

37
scripts/player/role.gd Normal file
View File

@@ -0,0 +1,37 @@
extends Node
enum Role { TANK, DAMAGE, HEALER }
var current_role: int = Role.DAMAGE
@export var tank_set: AbilitySet
@export var damage_set: AbilitySet
@export var healer_set: AbilitySet
@onready var player: CharacterBody3D = get_parent()
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("class_tank"):
set_role(Role.TANK)
elif event.is_action_pressed("class_damage"):
set_role(Role.DAMAGE)
elif event.is_action_pressed("class_healer"):
set_role(Role.HEALER)
func set_role(new_role: int) -> void:
current_role = new_role
EventBus.role_changed.emit(player, current_role)
func get_role_icon() -> String:
match current_role:
Role.TANK: return "T"
Role.DAMAGE: return "D"
Role.HEALER: return "H"
return ""
func get_ability_set() -> AbilitySet:
match current_role:
Role.TANK: return tank_set
Role.DAMAGE: return damage_set
Role.HEALER: return healer_set
return damage_set

View File

@@ -0,0 +1 @@
uid://dhomrampxola4

View File

@@ -49,7 +49,7 @@ func _try_target_under_mouse(mouse_pos: Vector2) -> void:
set_target(null)
func _cycle_target() -> void:
var targets := get_tree().get_nodes_in_group("targetable")
var targets := get_tree().get_nodes_in_group("enemies") + get_tree().get_nodes_in_group("portals")
if targets.is_empty():
set_target(null)
return
@@ -70,23 +70,26 @@ func _on_enemy_engaged(_enemy: Node, target: Node) -> void:
if not in_combat:
in_combat = true
if current_target == null:
_target_nearest()
_auto_target()
func _on_damage_dealt(_attacker: Node, target: Node, _amount: float) -> void:
func _on_damage_dealt(attacker: Node, target: Node, _amount: float) -> void:
if target == player:
combat_timer = COMBAT_TIMEOUT
if not in_combat:
in_combat = true
if current_target == null:
_target_nearest()
_auto_target()
elif attacker == player and in_combat:
combat_timer = COMBAT_TIMEOUT
func _on_entity_died(entity: Node) -> void:
if entity == current_target:
set_target(null)
if in_combat:
_target_nearest_except(entity)
_auto_target(entity)
func _target_nearest_except(exclude: Node = null) -> void:
func _auto_target(exclude: Node = null) -> void:
# Priorität 1: Nächster Gegner
var enemies := get_tree().get_nodes_in_group("enemies")
var nearest: Node3D = null
var nearest_dist: float = INF
@@ -98,16 +101,14 @@ func _target_nearest_except(exclude: Node = null) -> void:
nearest = enemy
if nearest:
set_target(nearest)
func _target_nearest() -> void:
var enemies := get_tree().get_nodes_in_group("enemies")
var nearest: Node3D = null
var nearest_dist: float = INF
for enemy in enemies:
if is_instance_valid(enemy):
var dist: float = player.global_position.distance_to(enemy.global_position)
return
# Priorität 2: Nächstes Portal
var portals := get_tree().get_nodes_in_group("portals")
for p in portals:
if is_instance_valid(p) and p != exclude:
var dist: float = player.global_position.distance_to(p.global_position)
if dist < nearest_dist:
nearest_dist = dist
nearest = enemy
nearest = p
if nearest:
set_target(nearest)