Forgejo #14, part 1 of #12. Rock.gd credited GameState.rocks on pickup, so ore was banked instantly from anywhere on the map and a mining run had nothing at stake. Ore now goes into GameState.fleet_cargo and only becomes spendable when the fleet reaches the mothership. Delivery lives in BuildingField because that node already knows where the buildings are and already answers "is the fleet standing on one?", using the fleet CENTROID - the same stable single-number test Planet and Building use, rather than per-ship collision that flickers as ships jostle in formation. Cargo lives in the GameState autoload so it survives Main.tscn being torn down on every trip to a planet's surface - cargo mined ON a surface would otherwise be dropped the moment the player took off. test_resources_and_buildings asserted the old behaviour (gathering a rock raises `rocks`) and now asserts the new one. That is a spec change, not a weakened test - the gathering assertion itself is intact. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
63 lines
2 KiB
GDScript
63 lines
2 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 = []
|
|
|
|
|
|
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.
|
|
if GameState.fleet_cargo <= 0:
|
|
return
|
|
var under: Node2D = get_building_fleet_is_on()
|
|
if under != null and under.building_type == GameState.BUILDING_MOTHERSHIP:
|
|
GameState.deliver_cargo()
|
|
|
|
|
|
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
|
|
# 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)
|