extends Node2D # A bounded ambient threat attached to the OCTOPUS biome. Like AsteroidField, # this node owns only the nearby presentation: the biome itself and its one # boss planet remain deterministic WorldGen data. @export var spawn_interval: float = 2.4 @export var max_octopuses: int = 7 @export var spawn_margin: float = 180.0 @export var retire_distance: float = 2600.0 @onready var fleet: Node2D = get_node("../Fleet") var octopus_scene: PackedScene = preload("res://boss/BossMinion.tscn") var active: Array = [] var spawn_left: float = 0.0 var spawn_count: int = 0 func _process(delta: float) -> void: active = active.filter(func(o): return is_instance_valid(o)) var in_biome: bool = WorldGen.biome_at_chunk( WorldGen.chunk_coords(fleet.get_centroid())) == WorldGen.Biome.OCTOPUS if not in_biome or GameState.intro_active: retire_all() spawn_left = 0.0 return for octopus in active.duplicate(): if octopus.global_position.distance_to(fleet.get_centroid()) > retire_distance: octopus.retire() active.erase(octopus) spawn_left -= delta if spawn_left <= 0.0 and active.size() < max_octopuses: spawn_one() spawn_left = spawn_interval func spawn_one() -> Node2D: if fleet == null or fleet.ships.is_empty(): return null var visible_rect: Rect2 = ViewUtils.get_visible_world_rect(self) var radius: float = maxf(visible_rect.size.length() * 0.5 + spawn_margin, 620.0) var angle: float = randf() * TAU var octopus: Node2D = octopus_scene.instantiate() # Ambient hatchlings are sturdy enough to harass a travelling fleet, but # never marked: only the boss encounter's golden hatchlings open eyes. octopus.max_hp = 7 octopus.position = fleet.get_centroid() + Vector2.from_angle(angle) * radius get_parent().add_child(octopus) octopus.uses_dash_pattern = spawn_count % 3 == 2 octopus.add_to_group("roaming_octopuses") active.append(octopus) spawn_count += 1 return octopus func retire_all() -> void: for octopus in active: if is_instance_valid(octopus): octopus.retire() active.clear()