prototype vibe
This commit is contained in:
88
systems/invasion_system.gd
Normal file
88
systems/invasion_system.gd
Normal file
@@ -0,0 +1,88 @@
|
||||
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()
|
||||
Reference in New Issue
Block a user