extends StaticBody3D class_name Tower var bullet : PackedScene = preload("res://Bullets/bullet.tscn") @export var tower_name : String = "Pierre" @export var price : int = 100 @export_group("Attack") @export var bullet_damage : int = 1 @export var action_cooldown : float = 1.5: set(value): action_cooldown = clamp(value, 0.3, 999) $Cooldown.wait_time = action_cooldown @export_group("Energy") @export var max_energy : float = 100.0: set(value): max_energy = value energy_bar.set_max_value(max_energy) @export var energy_regen : float = 10.0 @export var energy_cost : float = 50.0 @onready var energy_bar : EnergyBar3D = $EnergyBar3D var tower_button : TowerButton = null var energy : float = max_energy: set(value): energy = clampf(value, 0.0, max_energy) energy_bar.update(value) if energy < energy_cost: is_exhausted = true else: is_exhausted = false var current_targets : Array = [] var current : CharacterBody3D var can_shoot : bool = true var is_exhausted : bool = false var is_rest : bool = false: set(value): is_rest = value if value: resting() else: in_action() var tower_upgrades : Array[TowerUpgrade] func _ready() -> void: EventBus.tower_upgraded.connect(_on_EventBus_tower_upgraded) energy_bar.set_up(energy, max_energy) $Cooldown.wait_time = action_cooldown func _process(delta: float) -> void: if is_rest: return if is_instance_valid(current): if can_shoot && not is_exhausted: shoot() can_shoot = false $Cooldown.start() else: for i in $BulletContainer.get_child_count(): $BulletContainer.get_child(i).queue_free() func shoot() -> void: energy -= energy_cost var temp_bullet : Bullet = bullet.instantiate() temp_bullet.target = current temp_bullet.bullet_damage = bullet_damage temp_bullet.start_position = $Aim.global_position EventBus.bullet_shooted.emit(temp_bullet) func resting() -> void: energy += energy_regen visible = false set_collision_layer_value(3,false) set_collision_mask_value(3, false) $EnergyCooldown.start() func in_action() -> void: visible = true set_collision_layer_value(3, true) set_collision_mask_value(3, true) $EnergyCooldown.stop() func choose_target(_current_targets : Array) -> void: var temp_array : Array = _current_targets var current_target : CharacterBody3D = null for i in temp_array: if current_target == null : current_target = i else: if i.get_parent().get_progress() > current_target.get_parent().get_progress(): current_target = i current = current_target func _on_range_body_entered(body: Node3D) -> void: if body is Enemy: current_targets.append(body) choose_target(current_targets) func _on_range_body_exited(body: Node3D) -> void: if body is Enemy: current_targets.erase(body) choose_target(current_targets) func _on_cooldown_timeout() -> void: can_shoot = true func _on_energy_cooldown_timeout() -> void: resting() func _on_EventBus_tower_upgraded(tower_to_upgrade : String, upgrade : TowerUpgrade) -> void: if tower_to_upgrade == tower_name: upgrade.apply_upgrade(self) tower_upgrades.append(upgrade)