On a gas planet the vents were drawn on top of the player. SurfaceFeatures is added after Fleet in PlanetSurface.tscn, so at the default z_index of 0 the vent field won the tie purely by being the later sibling, and the fleet flew under its own gas source. Same one-line fix, for the same reason, as #50's capture rings and the rocks on a rocky surface. It goes on the field rather than on children because this one draws in its own _draw(). The test checks the rule instead of the node that was wrong: every drawing feature, on every surface profile that has features, must end up behind the fleet - 22 of them today, and any added later without editing the test. Enemies are excluded and the test says why; they are combatants and share the fleet's plane on purpose. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
84 lines
3.4 KiB
GDScript
84 lines
3.4 KiB
GDScript
extends Node2D
|
|
|
|
# By path, not by its `ResourcePickupVFX` global name: a bare class-name
|
|
# reference needs the global class cache already warm, which it is not when
|
|
# this script is reached indirectly - loading Main.tscn from inside a preview
|
|
# scene made it a hard parse error. Same workaround PlanetSetups and
|
|
# PlanetSetupEditor already use.
|
|
const RESOURCE_PICKUP_VFX = preload("res://vfx/ResourcePickupVFX.gd")
|
|
|
|
@export var fleet_path: NodePath = NodePath("../Fleet")
|
|
@onready var fleet: Node2D = get_node(fleet_path)
|
|
var vents: Array[Vector2] = []
|
|
var progress: float = 0.0
|
|
var emission_phase: float = 0.0
|
|
func _ready() -> void:
|
|
# #91: the vents are ground features and must never cover the fleet.
|
|
# SurfaceFeatures is added AFTER Fleet in PlanetSurface.tscn, so at the
|
|
# default z_index of 0 the later sibling simply wins and the player flies
|
|
# UNDER their own gas source. Same fix, and the same reason, as #50's
|
|
# capture rings and the rocks on a rocky surface (Rock.gd) - the
|
|
# difference is that this field draws in its own _draw() rather than
|
|
# spawning child nodes, so the depth belongs on the field itself.
|
|
z_index = -1
|
|
var rng := RandomNumberGenerator.new()
|
|
rng.seed = hash(GameState.planet_id if GameState.planet_id != "" else GameState.planet_name)
|
|
for i in range(6): vents.append(Vector2(rng.randf_range(-800,800), rng.randf_range(-650,650)))
|
|
queue_redraw()
|
|
func _process(delta: float) -> void:
|
|
emission_phase = fmod(emission_phase + delta * 0.55, 1.0)
|
|
queue_redraw()
|
|
for vent in vents:
|
|
if fleet.get_centroid().distance_to(vent) < 90.0:
|
|
progress += delta
|
|
if progress >= 1.0:
|
|
# #56: a full fleet hold rejects the deposit - keep the
|
|
# undelivered whole units in progress rather than discarding
|
|
# them, so gas is only ever lost by not gathering it.
|
|
var whole: int = int(progress)
|
|
var taken: int = GameState.collect_gas_cargo(whole)
|
|
progress -= float(taken)
|
|
RESOURCE_PICKUP_VFX.spawn(get_tree().root,
|
|
to_global(vent), GameState.RESOURCE_GAS, taken)
|
|
return
|
|
progress = 0.0
|
|
func _draw() -> void:
|
|
for vent in vents:
|
|
_draw_gas_source(vent)
|
|
_draw_emission(vent)
|
|
|
|
|
|
func _draw_gas_source(centre: Vector2) -> void:
|
|
var colour := Color(0.85, 0.52, 1.0)
|
|
var core := Color(0.15, 0.03, 0.22)
|
|
var bubbles: Array = [
|
|
[centre + Vector2(-20.0, 8.0), 20.0],
|
|
[centre + Vector2(18.0, 14.0), 27.0],
|
|
[centre + Vector2(17.0, -22.0), 15.0],
|
|
]
|
|
for bubble in bubbles:
|
|
var ring := PackedVector2Array()
|
|
for i in range(12):
|
|
var angle: float = TAU * float(i) / 12.0
|
|
ring.append(bubble[0] + Vector2(cos(angle), sin(angle)) * float(bubble[1]))
|
|
NeonDraw.draw_glowing_polygon(self, ring, colour, 0.9, core, 0.6)
|
|
|
|
|
|
func _draw_emission(centre: Vector2) -> void:
|
|
# Small bubbles continuously rise out of every source. This remains
|
|
# animated even when the fleet is not collecting, so the vent reads as
|
|
# an active gas generator rather than a static decoration.
|
|
var core := Color(0.15, 0.03, 0.22)
|
|
for i in range(4):
|
|
var travel: float = fmod(emission_phase + float(i) * 0.25, 1.0)
|
|
var bubble_centre := centre + Vector2(
|
|
sin((travel + float(i)) * TAU) * 11.0,
|
|
-48.0 - travel * 92.0
|
|
)
|
|
var radius: float = lerpf(5.0, 14.0, travel)
|
|
var colour := Color(0.92, 0.68, 1.0, 1.0 - travel * 0.72)
|
|
var ring := PackedVector2Array()
|
|
for point in range(10):
|
|
var angle: float = TAU * float(point) / 10.0
|
|
ring.append(bubble_centre + Vector2(cos(angle), sin(angle)) * radius)
|
|
NeonDraw.draw_glowing_polygon(self, ring, colour, 0.75, core, 0.45)
|