TowerDefense/Towers/Tower.gd

161 lines
3.8 KiB
GDScript3
Raw Normal View History

@tool
2025-03-26 18:55:43 +01:00
extends StaticBody3D
class_name Tower
2025-08-29 12:11:51 +02:00
# DANGER "NONE" Should always be first
enum TYPE { NONE, PIERRE, ALINE, MAXENCE, VICTORIA, EVAN, ALEX, GERALDINE }
var projectileScene : PackedScene = preload("res://Towers/Projectiles/projectile.tscn")
2025-08-31 23:07:55 +02:00
@export var tower_name : String = "None"
@export var tower_type : TYPE
@export_group("Base data")
2025-08-25 23:42:09 +02:00
@export var icone : Texture2D
@export var bio : String
@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
@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)
@export_group("Energy")
2025-08-31 23:07:55 +02:00
@export var max_energy : float = 100.0
@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
@onready var energy_bar : ProgressBar = $EnergyBar3D/SubViewport/EnergyBar2D
2025-08-27 13:27:32 +02:00
@onready var sprite : Sprite3D = $Sprite3D
var energy : float = 0:
set(value):
energy_bar.value = value
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-03-26 18:55:43 +01:00
var current_targets : Array = []
var current : CharacterBody3D
var can_shoot : bool = false
var is_exhausted : bool = false
2025-08-29 12:11:51 +02:00
var builded : bool = false
2025-08-29 12:11:51 +02:00
var is_rest : bool = true:
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
func _ready() -> void:
2025-09-03 18:39:58 +02:00
EventBus.tower_upgraded.connect(apply_upgrade)
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
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()
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:
energy -= energy_cost
2025-08-31 23:07:55 +02:00
var projectile : Projectile = projectileScene.instantiate()
projectile.loadProjectile(projectileRessource, current)
EventBus.projectile_shooted.emit(projectile, $Aim.global_position)
2025-03-26 18:55:43 +01: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)
$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)
$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-03-26 18:55:43 +01:00
current = current_target
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
func _on_energy_cooldown_timeout() -> void:
resting()