#216: transport hubs and spacial workshops no longer conjure their crews. Transporters and repair drones are ordered at a ship crafter, assigned per building through a new Station menu, flown out from the mothership hangar, and spent by the work they do - 20 runs, 12 repairs, counted where the run ENDS so nothing retires with cargo in the air or a building half repaired. A spent vessel is gone, so the structure is short again and the player has to build another. The menu shows what each one has left, worst first. Craftability needed its own flag: "the crafter can make it" and "it can take a berth in the fleet" stopped being the same question. #217: transporters crawl at 120 rather than 150, and a Burn Drive lets them carry energy and spend it to travel far faster. Fetching it is a leg of its own, to the nearest store that has any - so a refuelling transporter cannot be dispatched mid-errand - and the leg flown to COLLECT fuel is not charged for it. Unresearched, nothing detours and nothing changes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019AJMdB7iuHuLFZM1aBu3GD
109 lines
3.9 KiB
GDScript
109 lines
3.9 KiB
GDScript
extends SceneTree
|
|
|
|
# Extractors now mine into local stock. A hub-stationed transporter is the
|
|
# only route to the bank, and it waits for a full researched-size load.
|
|
|
|
var game_state: Node
|
|
var stage: int = 0
|
|
var elapsed: float = 0.0
|
|
var extractor_index: int = 0
|
|
var base_load: int = 0
|
|
var upgraded_load: int = 0
|
|
const MOTHERSHIP_AT := Vector2.ZERO
|
|
const HUB_AT := Vector2(100.0, 0.0)
|
|
const EXTRACTOR_AT := Vector2(300.0, 0.0)
|
|
|
|
|
|
func _initialize() -> void:
|
|
game_state = root.get_node("GameState")
|
|
game_state.rocks = 0
|
|
game_state.buildings.clear()
|
|
game_state.extractors.clear()
|
|
game_state.transporters.clear()
|
|
game_state.reset_progression()
|
|
game_state.research_points = 1
|
|
game_state.add_extractor("Test Planet", EXTRACTOR_AT)
|
|
extractor_index = 0
|
|
|
|
|
|
func _process(delta: float) -> bool:
|
|
elapsed += delta
|
|
match stage:
|
|
0:
|
|
# Mining is local even without a mothership or transporter.
|
|
# The wait is DERIVED from the rate, not a fixed 1.2s: that was
|
|
# long enough only while an extractor produced 2 ore per second,
|
|
# so halving the rate made this fail while the extractor was
|
|
# working perfectly. What is being tested is where the ore goes,
|
|
# not how fast it arrives.
|
|
if elapsed < 2.0 / GameState.EXTRACTOR_RATE + 0.4:
|
|
return false
|
|
if game_state.extractor_stock(extractor_index) < 2 or game_state.rocks != 0:
|
|
_fail("extractor did not hold locally: stock=%d bank=%d" % [
|
|
game_state.extractor_stock(extractor_index), game_state.rocks])
|
|
return true
|
|
print("extractor mined locally: stock=%d bank=%d" % [
|
|
game_state.extractor_stock(extractor_index), game_state.rocks])
|
|
game_state.add_building(GameState.BUILDING_MOTHERSHIP, MOTHERSHIP_AT)
|
|
game_state.add_building(GameState.BUILDING_TRANSPORT_HUB, HUB_AT)
|
|
# #216: crews are built and flown in now, not provisioned with the
|
|
# structure. This test is about what a crew DOES, so it is put
|
|
# straight at its post - test_transporter_supply.gd owns the journey.
|
|
load("res://tests/_staff.gd").staff_all(game_state)
|
|
if game_state.transporters.size() != game_state.hub_capacity():
|
|
_fail("hub did not provision its transporters")
|
|
return true
|
|
base_load = game_state.transporter_load_limit()
|
|
game_state.extractors[extractor_index].stock = base_load - 1
|
|
elapsed = 0.0
|
|
stage = 1
|
|
return false
|
|
1:
|
|
# No partial pickup: it stays local until it can fill the hold.
|
|
if elapsed < 0.2:
|
|
return false
|
|
if game_state.transporters[0].state != GameState.TRANSPORTER_IDLE or game_state.rocks != 0:
|
|
_fail("transporter left for a partial load")
|
|
return true
|
|
game_state.extractors[extractor_index].stock = base_load
|
|
elapsed = 0.0
|
|
stage = 2
|
|
return false
|
|
2:
|
|
# It must lift exactly the capacity amount, then bank it only when
|
|
# it reaches the mothership.
|
|
if game_state.rocks >= base_load:
|
|
print("full transporter load banked: %d ore" % base_load)
|
|
# Fund the lab purchase independently of the delivery assertion.
|
|
game_state.rocks = 100
|
|
game_state.add_building(GameState.BUILDING_SHIP_LAB, Vector2(-100.0, 0.0))
|
|
if not game_state.buy_upgrade("trn_capacity"):
|
|
_fail("could not research Expanded Hold at a ship lab")
|
|
return true
|
|
upgraded_load = game_state.transporter_load_limit()
|
|
if upgraded_load <= base_load:
|
|
_fail("Expanded Hold did not raise capacity")
|
|
return true
|
|
game_state.extractors[extractor_index].stock = upgraded_load
|
|
elapsed = 0.0
|
|
stage = 3
|
|
return false
|
|
if elapsed > 10.0:
|
|
_fail("full extractor load was never collected")
|
|
return true
|
|
return false
|
|
3:
|
|
if game_state.rocks >= 100 - 30 + upgraded_load:
|
|
print("Expanded Hold %d -> %d, upgraded load banked" % [base_load, upgraded_load])
|
|
print("TEST_EXTRACTOR_INCOME: PASS")
|
|
quit(0)
|
|
return true
|
|
if elapsed > 10.0:
|
|
_fail("upgraded load was not transported")
|
|
return true
|
|
return false
|
|
|
|
|
|
func _fail(message: String) -> void:
|
|
print("TEST_EXTRACTOR_INCOME: FAIL (%s)" % message)
|
|
quit(1)
|