89 lines
2.7 KiB
GDScript
89 lines
2.7 KiB
GDScript
extends Node
|
|
|
|
const ENEMY_SCENE: PackedScene = preload("res://scenes/enemy/enemy.tscn")
|
|
const BOSS_STATS: Resource = preload("res://scenes/enemy/boss_stats.tres")
|
|
const INVASION_COUNT := 16
|
|
const SPAWN_RADIUS := 45.0
|
|
|
|
var active: bool = false
|
|
var invasion_enemies: Array[Node] = []
|
|
|
|
func _ready() -> void:
|
|
EventBus.wave_timer_tick.connect(_on_wave_timer_tick)
|
|
EventBus.entity_died.connect(_on_entity_died)
|
|
EventBus.tavern_destroyed.connect(_on_tavern_destroyed)
|
|
|
|
func _on_wave_timer_tick(seconds_remaining: float) -> void:
|
|
if active:
|
|
return
|
|
if seconds_remaining > 0:
|
|
return
|
|
var has_alive_red := false
|
|
for p in get_tree().get_nodes_in_group("red_portal"):
|
|
if is_instance_valid(p) and PortalData.is_alive(p):
|
|
has_alive_red = true
|
|
break
|
|
if not has_alive_red:
|
|
return
|
|
trigger()
|
|
|
|
func trigger() -> void:
|
|
active = true
|
|
invasion_enemies.clear()
|
|
var tavern: Node = get_tree().get_first_node_in_group("tavern")
|
|
if not tavern:
|
|
active = false
|
|
return
|
|
var world: Node = get_tree().current_scene
|
|
var scale: float = PlayerData.level_scale * 10.0
|
|
for enemy in get_tree().get_nodes_in_group("red_enemies"):
|
|
if is_instance_valid(enemy):
|
|
_convert_to_invasion(enemy, tavern)
|
|
for i in range(INVASION_COUNT):
|
|
var angle: float = randf() * TAU
|
|
var pos := Vector3(cos(angle) * SPAWN_RADIUS, 0, sin(angle) * SPAWN_RADIUS)
|
|
var enemy: Node = ENEMY_SCENE.instantiate()
|
|
enemy.spawn_scale = scale
|
|
world.add_child(enemy)
|
|
enemy.global_position = pos
|
|
_convert_to_invasion(enemy, tavern)
|
|
var boss_angle: float = randf() * TAU
|
|
var boss_pos := Vector3(cos(boss_angle) * SPAWN_RADIUS, 0, sin(boss_angle) * SPAWN_RADIUS)
|
|
var boss: Node = ENEMY_SCENE.instantiate()
|
|
boss.add_to_group("boss")
|
|
boss.stats = BOSS_STATS
|
|
boss.spawn_scale = scale
|
|
world.add_child(boss)
|
|
boss.global_position = boss_pos
|
|
_convert_to_invasion(boss, tavern)
|
|
EventBus.invasion_started.emit(invasion_enemies)
|
|
|
|
func _convert_to_invasion(enemy: Node, tavern: Node) -> void:
|
|
enemy.add_to_group("invasion")
|
|
var data_source: Node = BossData if enemy.is_in_group("boss") else EnemyData
|
|
data_source.set_stat(enemy, "target", tavern)
|
|
data_source.set_stat(enemy, "state", 1)
|
|
invasion_enemies.append(enemy)
|
|
|
|
func _on_entity_died(entity: Node) -> void:
|
|
if not active:
|
|
return
|
|
if entity not in invasion_enemies:
|
|
return
|
|
invasion_enemies.erase(entity)
|
|
var alive_count := 0
|
|
for e in invasion_enemies:
|
|
if is_instance_valid(e):
|
|
alive_count += 1
|
|
if alive_count == 0:
|
|
_end_invasion(true)
|
|
|
|
func _end_invasion(success: bool) -> void:
|
|
active = false
|
|
invasion_enemies.clear()
|
|
EventBus.invasion_ended.emit(success)
|
|
|
|
func _on_tavern_destroyed() -> void:
|
|
active = false
|
|
EventBus.game_over.emit()
|