spaceship/world/OctopusField.gd

62 lines
2 KiB
GDScript3
Raw Normal View History

2026-09-04 15:56:07 +02:00
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()