2025-09-01 13:52:14 +02:00
|
|
|
extends Node3D
|
|
|
|
|
class_name WorldManager
|
2025-08-27 01:40:22 +02:00
|
|
|
|
2025-08-30 15:46:36 +02:00
|
|
|
const PACK_DELAY : float = .15
|
|
|
|
|
|
2025-09-01 13:52:14 +02:00
|
|
|
var level : Level
|
|
|
|
|
var paths : Array[Node]
|
2025-08-27 01:40:22 +02:00
|
|
|
|
2025-08-30 15:46:36 +02:00
|
|
|
var wave : int = 0
|
2025-09-03 03:44:44 +02:00
|
|
|
var currentTroopIdx : int = 0
|
|
|
|
|
var currentTroop : Troop :
|
|
|
|
|
get():
|
|
|
|
|
return level.waves[wave - 1].troops[currentTroopIdx]
|
|
|
|
|
var enemiesAlive : int = 0
|
|
|
|
|
@onready var troopTimer : Timer = $TroopTimer
|
2025-08-29 12:11:51 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
func _ready() -> void:
|
2025-09-01 13:52:14 +02:00
|
|
|
EventBus.projectile_shooted.connect(onProjectileShooted)
|
|
|
|
|
EventBus.player_defeated.connect(queue_free)
|
|
|
|
|
|
|
|
|
|
|
2025-09-03 03:44:44 +02:00
|
|
|
func onProjectileShooted(projectile: Projectile, startPosition: Vector3) -> void:
|
2025-09-01 13:52:14 +02:00
|
|
|
add_child(projectile)
|
2025-09-03 03:44:44 +02:00
|
|
|
projectile.global_position = startPosition
|
2025-08-27 01:40:22 +02:00
|
|
|
|
|
|
|
|
|
2025-09-03 03:44:44 +02:00
|
|
|
func _process(_delta: float) -> void:
|
2025-09-01 13:52:14 +02:00
|
|
|
if wave > 0 || level && level.auto_start:
|
2025-09-03 03:44:44 +02:00
|
|
|
spawnManager()
|
2025-08-27 01:40:22 +02:00
|
|
|
|
|
|
|
|
|
2025-09-03 03:44:44 +02:00
|
|
|
func spawnNextWave() -> void:
|
|
|
|
|
if wave == level.waves.size() && currentTroopIdx == level.waves[wave - 1].troops.size():
|
2025-08-27 01:40:22 +02:00
|
|
|
EventBus.player_has_won.emit()
|
2025-09-01 13:52:14 +02:00
|
|
|
queue_free.call_deferred()
|
2025-08-27 01:40:22 +02:00
|
|
|
return
|
|
|
|
|
|
2025-09-03 03:44:44 +02:00
|
|
|
currentTroopIdx = 0
|
2025-08-30 15:46:36 +02:00
|
|
|
wave += 1
|
|
|
|
|
EventBus.waveHasChange.emit(wave)
|
2025-08-27 01:40:22 +02:00
|
|
|
|
|
|
|
|
|
2025-09-03 03:44:44 +02:00
|
|
|
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
|
2025-08-30 15:46:36 +02:00
|
|
|
|
|
|
|
|
|
2025-09-03 03:44:44 +02:00
|
|
|
func spawnEnemy(enemyScene: PackedScene, laneToSpawn: int, delay: float) -> void:
|
2025-09-02 19:49:40 +02:00
|
|
|
var enemy : PathFollow3D = createEnemy(enemyScene)
|
2025-08-30 15:46:36 +02:00
|
|
|
|
|
|
|
|
if delay > 0:
|
2025-08-31 23:07:55 +02:00
|
|
|
var enemyTimer : Timer = createTimer(delay)
|
2025-08-30 15:46:36 +02:00
|
|
|
enemyTimer.timeout.connect(
|
|
|
|
|
func():
|
2025-09-02 19:49:40 +02:00
|
|
|
paths[laneToSpawn].add_child(enemy)
|
2025-08-30 15:46:36 +02:00
|
|
|
enemyTimer.queue_free()
|
|
|
|
|
)
|
2025-09-02 19:49:40 +02:00
|
|
|
add_child(enemyTimer)
|
2025-08-30 15:46:36 +02:00
|
|
|
else:
|
2025-09-02 19:49:40 +02:00
|
|
|
paths[laneToSpawn].add_child(enemy)
|
2025-08-30 15:46:36 +02:00
|
|
|
|
2025-09-03 03:44:44 +02:00
|
|
|
enemiesAlive += 1
|
2025-08-30 15:46:36 +02:00
|
|
|
|
|
|
|
|
|
2025-09-03 03:44:44 +02:00
|
|
|
func createEnemy(enemyScene: PackedScene) -> PathFollow3D :
|
2025-09-02 19:49:40 +02:00
|
|
|
var PF3D : PathFollow3D = enemyScene.instantiate()
|
2025-08-30 20:08:12 +02:00
|
|
|
var enemy : Enemy = PF3D.find_children("*", "Enemy")[0]
|
2025-09-03 03:44:44 +02:00
|
|
|
enemy.died.connect(func(): enemiesAlive -= 1)
|
2025-08-30 15:46:36 +02:00
|
|
|
|
2025-08-30 20:08:12 +02:00
|
|
|
return PF3D
|
2025-08-27 01:40:22 +02:00
|
|
|
|
|
|
|
|
|
2025-09-03 03:44:44 +02:00
|
|
|
func spawnManager() -> void:
|
2025-08-30 20:08:12 +02:00
|
|
|
if not troopTimer.is_stopped():
|
2025-08-29 12:11:51 +02:00
|
|
|
return
|
|
|
|
|
|
2025-09-03 03:44:44 +02:00
|
|
|
var current_wave : Wave = level.waves[wave - 1]
|
|
|
|
|
if current_wave.troops.size() < currentTroopIdx + 1:
|
|
|
|
|
if enemiesAlive == 0:
|
|
|
|
|
spawnNextWave()
|
2025-08-30 20:08:12 +02:00
|
|
|
return
|
|
|
|
|
|
2025-09-03 03:44:44 +02:00
|
|
|
if currentTroop.spawn_delay == 0:
|
|
|
|
|
spawnTroop()
|
2025-08-30 20:08:12 +02:00
|
|
|
else:
|
2025-09-03 03:44:44 +02:00
|
|
|
troopTimer.start(currentTroop.spawn_delay)
|
2025-08-27 01:40:22 +02:00
|
|
|
|
|
|
|
|
|
2025-09-03 03:44:44 +02:00
|
|
|
func createTimer(delay: float) -> Timer :
|
2025-08-31 23:07:55 +02:00
|
|
|
var timer : Timer = Timer.new()
|
2025-08-30 15:46:36 +02:00
|
|
|
timer.wait_time = delay
|
2025-09-03 03:44:44 +02:00
|
|
|
timer.one_shot = true
|
|
|
|
|
timer.autostart = true
|
2025-08-30 15:46:36 +02:00
|
|
|
|
|
|
|
|
return timer
|
2025-09-01 13:52:14 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
func addMap(mapScene : PackedScene) -> void:
|
|
|
|
|
var map : Map = mapScene.instantiate()
|
|
|
|
|
add_child(map)
|
|
|
|
|
level = map.level
|
|
|
|
|
paths = map.paths.get_children()
|
2025-09-03 03:44:44 +02:00
|
|
|
EventBus.allowedTowerHasChange.emit(level.allowedTowers)
|
|
|
|
|
spawnNextWave()
|