2025-09-02 19:49:40 +02:00
|
|
|
@tool
|
2025-03-26 18:55:43 +01:00
|
|
|
extends StaticBody3D
|
|
|
|
|
class_name Tower
|
|
|
|
|
|
2025-08-29 12:11:51 +02:00
|
|
|
|
2025-08-31 21:26:02 +02:00
|
|
|
# DANGER "NONE" Should always be first
|
|
|
|
|
enum TYPE { NONE, PIERRE, ALINE, MAXENCE, VICTORIA, EVAN, ALEX, GERALDINE }
|
|
|
|
|
|
2025-09-02 19:49:40 +02:00
|
|
|
var projectileScene : PackedScene = preload("res://Towers/Projectiles/projectile.tscn")
|
2025-08-31 23:07:55 +02:00
|
|
|
|
2025-08-31 21:26:02 +02:00
|
|
|
@export var tower_name : String = "None"
|
|
|
|
|
@export var tower_type : TYPE
|
2025-09-02 19:49:40 +02:00
|
|
|
@export_group("Base data")
|
2025-08-25 23:42:09 +02:00
|
|
|
@export var icone : Texture2D
|
|
|
|
|
@export var bio : String
|
2025-06-05 15:35:19 +02:00
|
|
|
@export var price : int = 100
|
|
|
|
|
|
2025-06-18 12:19:43 +02:00
|
|
|
@export_group("Attack")
|
2025-08-31 23:07:55 +02:00
|
|
|
@export var projectileRessource : ProjectileResource
|
2025-09-02 19:49:40 +02:00
|
|
|
@export var towerRange : Shape3D
|
2025-06-18 12:19:43 +02:00
|
|
|
@export var action_cooldown : float = 1.5:
|
|
|
|
|
set(value):
|
|
|
|
|
action_cooldown = clamp(value, 0.3, 999)
|
|
|
|
|
|
2025-06-05 15:35:19 +02:00
|
|
|
@export_group("Energy")
|
2025-08-31 23:07:55 +02:00
|
|
|
@export var max_energy : float = 100.0
|
2025-06-05 15:35:19 +02:00
|
|
|
@export var energy_regen : float = 10.0
|
|
|
|
|
@export var energy_cost : float = 50.0
|
2025-08-29 20:07:36 +02:00
|
|
|
|
|
|
|
|
@export_group("Button")
|
|
|
|
|
@export var buttonTooltip : String
|
|
|
|
|
|
|
|
|
|
|
2025-09-02 19:49:40 +02:00
|
|
|
@onready var energy_bar : ProgressBar = $EnergyBar3D/SubViewport/EnergyBar2D
|
2025-08-27 13:27:32 +02:00
|
|
|
@onready var sprite : Sprite3D = $Sprite3D
|
2025-06-05 15:35:19 +02:00
|
|
|
|
2025-09-02 19:49:40 +02:00
|
|
|
var energy : float = 0:
|
2025-06-05 15:35:19 +02:00
|
|
|
set(value):
|
2025-09-02 19:49:40 +02:00
|
|
|
energy_bar.value = value
|
2025-06-05 15:35:19 +02:00
|
|
|
energy = clampf(value, 0.0, max_energy)
|
2025-08-30 15:46:36 +02:00
|
|
|
is_exhausted = energy < energy_cost
|
2025-08-27 14:37:26 +02:00
|
|
|
EventBus.energy_has_changed.emit(self)
|
2025-06-05 15:35:19 +02:00
|
|
|
|
2025-03-26 18:55:43 +01:00
|
|
|
var current_targets : Array = []
|
|
|
|
|
var current : CharacterBody3D
|
2025-09-02 19:49:40 +02:00
|
|
|
var can_shoot : bool = false
|
2025-06-05 15:35:19 +02:00
|
|
|
var is_exhausted : bool = false
|
2025-08-29 12:11:51 +02:00
|
|
|
var builded : bool = false
|
2025-06-05 15:35:19 +02:00
|
|
|
|
2025-08-29 12:11:51 +02:00
|
|
|
var is_rest : bool = true:
|
2025-06-05 15:35:19 +02:00
|
|
|
set(value):
|
|
|
|
|
is_rest = value
|
|
|
|
|
if value:
|
|
|
|
|
resting()
|
|
|
|
|
else:
|
|
|
|
|
in_action()
|
|
|
|
|
|
2025-09-03 18:39:58 +02:00
|
|
|
|
2025-08-25 23:23:03 +02:00
|
|
|
@export_category("Upgrades")
|
2025-09-03 18:39:58 +02:00
|
|
|
@export var upgrades : Array[TowerUpgrade]
|
2025-08-25 23:23:03 +02:00
|
|
|
|
2025-06-18 12:19:43 +02:00
|
|
|
|
2025-09-02 19:49:40 +02:00
|
|
|
func _ready() -> void:
|
2025-09-03 18:39:58 +02:00
|
|
|
EventBus.tower_upgraded.connect(apply_upgrade)
|
2025-09-02 19:49:40 +02:00
|
|
|
EventBus.energy_has_changed.emit(self)
|
|
|
|
|
# WARNING : Prevent .tscn file to be modified by the load of the scene in editor
|
|
|
|
|
if not Engine.is_editor_hint():
|
|
|
|
|
$PriceTag.text = str(price) +" €"
|
|
|
|
|
energy = max_energy
|
|
|
|
|
$Range/Range.shape = towerRange
|
|
|
|
|
energy_bar.value = energy
|
|
|
|
|
energy_bar.max_value = max_energy
|
|
|
|
|
$Cooldown.wait_time = action_cooldown
|
|
|
|
|
|
|
|
|
|
|
2025-09-03 03:44:44 +02:00
|
|
|
func _process(_delta: float) -> void:
|
2025-09-02 19:49:40 +02:00
|
|
|
if is_rest:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if is_instance_valid(current):
|
|
|
|
|
if can_shoot && not is_exhausted:
|
|
|
|
|
shoot()
|
|
|
|
|
can_shoot = false
|
|
|
|
|
$Cooldown.start()
|
|
|
|
|
|
|
|
|
|
|
2025-08-25 23:23:03 +02:00
|
|
|
func get_available_upgrades() -> Array[TowerUpgrade]:
|
2025-09-03 18:39:58 +02:00
|
|
|
return upgrades.filter(func(u: TowerUpgrade): u.isLevelMax)
|
|
|
|
|
|
2025-08-25 23:23:03 +02:00
|
|
|
|
2025-09-03 18:39:58 +02:00
|
|
|
func apply_upgrade(towerType : Tower.TYPE, upgrade : TowerUpgrade):
|
|
|
|
|
## TODO DANGER connect cube money
|
|
|
|
|
if towerType == tower_type && upgrade.canUpgrade(100):
|
|
|
|
|
upgrade.upgrade(self)
|
2025-06-18 12:19:43 +02:00
|
|
|
|
2025-03-26 18:55:43 +01:00
|
|
|
|
|
|
|
|
func shoot() -> void:
|
2025-06-05 15:35:19 +02:00
|
|
|
energy -= energy_cost
|
2025-08-26 13:03:22 +02:00
|
|
|
|
2025-08-31 23:07:55 +02:00
|
|
|
var projectile : Projectile = projectileScene.instantiate()
|
2025-09-03 03:44:44 +02:00
|
|
|
projectile.loadProjectile(projectileRessource, current)
|
|
|
|
|
EventBus.projectile_shooted.emit(projectile, $Aim.global_position)
|
2025-03-26 18:55:43 +01:00
|
|
|
|
|
|
|
|
|
2025-06-05 15:35:19 +02:00
|
|
|
func resting() -> void:
|
|
|
|
|
energy += energy_regen
|
|
|
|
|
visible = false
|
2025-06-18 12:19:43 +02:00
|
|
|
set_collision_layer_value(3,false)
|
|
|
|
|
set_collision_mask_value(3, false)
|
2025-06-05 15:35:19 +02:00
|
|
|
$EnergyCooldown.start()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func in_action() -> void:
|
|
|
|
|
visible = true
|
2025-06-18 12:19:43 +02:00
|
|
|
set_collision_layer_value(3, true)
|
|
|
|
|
set_collision_mask_value(3, true)
|
2025-06-05 15:35:19 +02:00
|
|
|
$EnergyCooldown.stop()
|
|
|
|
|
|
|
|
|
|
|
2025-03-26 18:55:43 +01:00
|
|
|
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
|
2025-08-26 13:03:22 +02:00
|
|
|
|
2025-03-26 18:55:43 +01:00
|
|
|
current = current_target
|
|
|
|
|
|
2025-06-05 15:35:19 +02:00
|
|
|
|
2025-09-02 19:49:40 +02:00
|
|
|
func build() -> void:
|
|
|
|
|
EventBus.money_spent.emit(price)
|
|
|
|
|
can_shoot = true
|
|
|
|
|
collision_layer = 3
|
|
|
|
|
sprite.modulate = "ffffffff"
|
|
|
|
|
builded = true
|
|
|
|
|
$PriceTag.visible = false
|
|
|
|
|
EventBus.tower_builded.emit(self)
|
2025-08-27 13:27:32 +02:00
|
|
|
|
|
|
|
|
|
2025-03-26 18:55:43 +01:00
|
|
|
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
|
2025-06-05 15:35:19 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
func _on_energy_cooldown_timeout() -> void:
|
|
|
|
|
resting()
|