Forgejo #17, part 4 of #12. #16 lets an order queue waiting for ore, so something has to be able to fulfil one. Until transporters exist (#19) this is the only route, which is why it lands before them rather than after: otherwise a player with a queued order and no Transport Hub is stuck forever. A "Load ore" button at the mothership moves a batch from the bank into the fleet's hold, and opening a building hands it whatever the fleet is carrying. Delivery at the mothership is now EDGE triggered on arrival rather than running every frame the fleet is parked there. Continuous delivery made withdrawing impossible - ore loaded into the hold was banked again on the very next frame, so the button would have looked broken. A batch rather than the whole bank, because the hold is the part that can be lost and emptying the bank in one tap would also strand research, which still spends from it. Both new logistics tests now clear existing asteroids: disabling AsteroidField only stops new chunks spawning, and a drifting rock destroying a parked ship changed the fleet size the tests assert on. That was a real intermittent failure, seen once in a full run. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
72 lines
2.6 KiB
GDScript
72 lines
2.6 KiB
GDScript
extends Node2D
|
|
|
|
# Rebuilds every player-placed structure from GameState when the space
|
|
# scene loads, and answers "is the fleet standing on one?".
|
|
#
|
|
# Buildings live in GameState rather than in the scene because Main.tscn is
|
|
# torn down and recreated on every trip to a planet's surface - anything
|
|
# kept only as a node would be lost on the first landing.
|
|
|
|
@onready var fleet: Node2D = get_node("../Fleet")
|
|
|
|
var building_scene: PackedScene = preload("res://Building.tscn")
|
|
var spawned: Array = []
|
|
# Whether the fleet was already standing on the mothership last frame - see
|
|
# the edge-triggered delivery in _process().
|
|
var _was_on_mothership: bool = false
|
|
|
|
|
|
func _ready() -> void:
|
|
rebuild_all()
|
|
|
|
|
|
func _process(_delta: float) -> void:
|
|
# Unloading the fleet's hold (#14). Done here because this is the node
|
|
# that already knows where the buildings are and already answers "is the
|
|
# fleet standing on one?" - and it uses the fleet CENTROID, the same
|
|
# stable single-number test Planet and Building already use, rather than
|
|
# per-ship collision that flickers as ships jostle in formation.
|
|
# EDGE-triggered on arrival, not continuous. Delivering every frame the
|
|
# fleet is parked on the mothership would make withdrawing impossible:
|
|
# ore loaded into the hold at the mothership (#17) would be banked again
|
|
# the very next frame, and the button would look broken.
|
|
var under: Node2D = get_building_fleet_is_on()
|
|
var on_mothership: bool = under != null \
|
|
and under.building_type == GameState.BUILDING_MOTHERSHIP
|
|
if on_mothership and not _was_on_mothership and GameState.fleet_cargo > 0:
|
|
GameState.deliver_cargo()
|
|
_was_on_mothership = on_mothership
|
|
|
|
|
|
func rebuild_all() -> void:
|
|
for b in spawned:
|
|
if is_instance_valid(b):
|
|
b.queue_free()
|
|
spawned.clear()
|
|
for record in GameState.buildings:
|
|
_spawn(record)
|
|
|
|
|
|
func place(type: String, at_position: Vector2) -> void:
|
|
GameState.add_building(type, at_position)
|
|
_spawn(GameState.buildings[-1])
|
|
|
|
|
|
func get_building_fleet_is_on() -> Node2D:
|
|
var centre: Vector2 = fleet.get_centroid()
|
|
for b in spawned:
|
|
if is_instance_valid(b) and b.position.distance_to(centre) <= b.interact_radius:
|
|
return b
|
|
return null
|
|
|
|
|
|
func _spawn(record: Dictionary) -> void:
|
|
var b: Node2D = building_scene.instantiate()
|
|
b.position = record.position
|
|
b.building_type = record.type
|
|
b.building_id = int(record.get("id", 0))
|
|
# Deferred for the same reason as the other field spawners: this can run
|
|
# from inside a parent's _ready() chain, where a direct add_child() is
|
|
# rejected while the tree is still setting up children.
|
|
get_parent().add_child.call_deferred(b)
|
|
spawned.append(b)
|