extends Node const PORTAL_SCENE: PackedScene = preload("res://scenes/portal/portal.tscn") const GATE_SCENE: PackedScene = preload("res://scenes/portal/gate.tscn") const RED_PORTAL_STATS: Resource = preload("res://scenes/portal/red_portal_stats.tres") const MAX_NORMAL_PORTALS := 3 const MIN_DISTANCE := 20.0 const MAX_DISTANCE := 40.0 const RESPAWN_DELAY := 1.0 var portals: Array[Node] = [] func _ready() -> void: EventBus.portal_defeated.connect(_on_portal_defeated) EventBus.wave_started.connect(_on_wave_started) if PlayerData.portal_position != Vector3.ZERO and not PlayerData.dungeon_cleared: call_deferred("_restore_gate") else: if PlayerData.dungeon_cleared: PlayerData.clear_cache() call_deferred("_ensure_portals") func _restore_gate() -> void: var gate: Node3D = GATE_SCENE.instantiate() get_parent().add_child(gate) gate.global_position = PlayerData.portal_position func _ensure_portals() -> void: _cleanup_dead() while portals.size() < MAX_NORMAL_PORTALS: _spawn_portal() func _on_portal_defeated(portal: Node) -> void: if portal.is_in_group("red_portal"): return portals.erase(portal) await get_tree().create_timer(RESPAWN_DELAY).timeout _ensure_portals() func _on_wave_started(_wave_number: int) -> void: _spawn_red_portal() func _spawn_red_portal() -> void: for p in get_tree().get_nodes_in_group("red_portal"): if is_instance_valid(p): return var angle: float = randf() * TAU var distance: float = randf_range(MIN_DISTANCE, MAX_DISTANCE) var pos := Vector3(cos(angle) * distance, 0, sin(angle) * distance) var portal: Node3D = PORTAL_SCENE.instantiate() portal.stats = RED_PORTAL_STATS get_parent().add_child(portal) portal.global_position = pos func _spawn_portal() -> void: var angle: float = randf() * TAU var distance: float = randf_range(MIN_DISTANCE, MAX_DISTANCE) var pos := Vector3(cos(angle) * distance, 0, sin(angle) * distance) var portal: Node3D = PORTAL_SCENE.instantiate() get_parent().add_child(portal) portal.global_position = pos portals.append(portal) func _cleanup_dead() -> void: var valid: Array[Node] = [] for p in portals: if is_instance_valid(p): valid.append(p) portals = valid