extends CharacterBody3D class_name Enemy signal died const DEATH_PARTICLE : PackedScene = preload("uid://ddm57pv5ox171") const SAD_PARTICLE : PackedScene = preload("uid://m0vj2ac5oesx") @export var speed : float = 1 @export var base_attack_damage : int = 1 @export var max_life : int = 5 @export var money : int = 5 var health : int = 0 : set(value): health = value if health >= max_life and is_alive: death() @onready var path : PathFollow3D = get_parent() @onready var healthBar : ProgressBar = $HealthBar3D/SubViewport/HealthBar2D var targets : Array[Node3D] var is_alive : bool = true func _ready() -> void: healthBar.max_value = max_life func _physics_process(delta: float) -> void: if !is_alive: return if not attack(): path.progress += speed * delta func take_damage(damage: int) -> void: health += damage healthBar.value = health func attack() -> bool: if targets.is_empty(): return false var cubeTarget : Array[Node3D] = targets.filter(func(b): return b is TheCube) if $AttackCooldown.is_stopped() && not cubeTarget.is_empty(): cubeTarget[0].take_damage(base_attack_damage) $AttackCooldown.start() path.progress = 0 return true return false func death() -> void: is_alive = false died.emit() Game.money += money $Sprite3D.visible = false var death_vfx : CPUParticles3D = DEATH_PARTICLE.instantiate() get_tree().current_scene.add_child(death_vfx) death_vfx.global_position = global_position path.queue_free() func onAttackRangeBodyEntered(body: Node3D) -> void: if (body is TheCube || body is Tower) && not targets.has(body): targets.append(body) func onAttackRangeBodyExited(body: Node3D) -> void: targets.erase(body)