TowerDefense/Levels/Scripts/WorldManager.gd
2025-09-04 13:19:46 +02:00

111 lines
2.6 KiB
GDScript

extends Node3D
class_name WorldManager
const PACK_DELAY : float = .15
var level : Level
var paths : Array[Node]
var wave : int = 0
var currentTroopIdx : int = 0
var currentTroop : Troop :
get():
return level.waves[wave - 1].troops[currentTroopIdx]
var enemiesAlive : int = 0
@onready var troopTimer : Timer = $TroopTimer
func _ready() -> void:
EventBus.projectile_shooted.connect(onProjectileShooted)
EventBus.player_defeated.connect(queue_free)
func onProjectileShooted(projectile: Projectile, startPosition: Vector3) -> void:
add_child(projectile)
projectile.global_position = startPosition
func _process(_delta: float) -> void:
if wave > 0 || level && level.auto_start:
spawnManager()
func spawnNextWave() -> void:
if wave == level.waves.size() && currentTroopIdx == level.waves[wave - 1].troops.size():
EventBus.player_has_won.emit()
queue_free.call_deferred()
return
currentTroopIdx = 0
wave += 1
EventBus.waveHasChange.emit(wave)
func spawnTroop() -> void:
var enemyScene : PackedScene = load(currentTroop.enemy)
var totalDelay : float = 0
for n in currentTroop.number_to_spawn:
spawnEnemy(enemyScene, currentTroop.lane_to_spawn, totalDelay)
totalDelay += PACK_DELAY
currentTroopIdx += 1
func spawnEnemy(enemyScene: PackedScene, laneToSpawn: int, delay: float) -> void:
var enemy : PathFollow3D = createEnemy(enemyScene)
if delay > 0:
var enemyTimer : Timer = createTimer(delay)
enemyTimer.timeout.connect(
func():
paths[laneToSpawn].add_child(enemy)
enemyTimer.queue_free()
)
add_child(enemyTimer)
else:
paths[laneToSpawn].add_child(enemy)
enemiesAlive += 1
func createEnemy(enemyScene: PackedScene) -> PathFollow3D :
var PF3D : PathFollow3D = enemyScene.instantiate()
var enemy : Enemy = PF3D.find_children("*", "Enemy")[0]
enemy.died.connect(func(): enemiesAlive -= 1)
return PF3D
func spawnManager() -> void:
if not troopTimer.is_stopped():
return
var current_wave : Wave = level.waves[wave - 1]
if current_wave.troops.size() < currentTroopIdx + 1:
if enemiesAlive == 0:
spawnNextWave()
return
if currentTroop.spawn_delay == 0:
spawnTroop()
else:
troopTimer.start(currentTroop.spawn_delay)
func createTimer(delay: float) -> Timer :
var timer : Timer = Timer.new()
timer.wait_time = delay
timer.one_shot = true
timer.autostart = true
return timer
func addMap(mapScene : PackedScene) -> void:
var map : Map = mapScene.instantiate()
add_child(map)
level = map.level
paths = map.paths.get_children()
TheCube.money = level.startingMoney
EventBus.allowedTowerHasChange.emit(level.allowedTowers)
spawnNextWave()