extends Node var attack_timers: Dictionary = {} func _physics_process(delta: float) -> void: for enemy in get_tree().get_nodes_in_group("enemies"): if not is_instance_valid(enemy) or not Stats.is_alive(enemy): continue if enemy.state != enemy.State.ATTACK: continue _handle_attack(enemy, delta) func _handle_attack(enemy: Node, delta: float) -> void: if enemy not in attack_timers: attack_timers[enemy] = 0.0 attack_timers[enemy] -= delta if not is_instance_valid(enemy.target): enemy.state = enemy.State.RETURN return var base: BaseStats = Stats.get_base(enemy) var attack_range: float = base.attack_range if base is EnemyStats else 2.0 var dist: float = enemy.global_position.distance_to(enemy.target.global_position) if dist > attack_range: enemy.state = enemy.State.CHASE return if attack_timers[enemy] <= 0: var attack_cooldown: float = base.attack_cooldown if base is EnemyStats else 1.5 var attack_damage: float = base.attack_damage if base is EnemyStats else 5.0 attack_timers[enemy] = attack_cooldown EventBus.damage_requested.emit(enemy, enemy.target, attack_damage) enemy.velocity.x = 0 enemy.velocity.z = 0