2026-08-13 21:07:35 +02:00
|
|
|
extends SceneTree
|
|
|
|
|
|
|
|
|
|
# Forgejo #27: gas giants are deterministic animated gas sources, and the
|
|
|
|
|
# existing transporter route carries their gas without converting it to ore.
|
|
|
|
|
|
|
|
|
|
var game_state: Node
|
|
|
|
|
var stage: int = 0
|
|
|
|
|
var elapsed: float = 0.0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _initialize() -> void:
|
|
|
|
|
game_state = root.get_node("GameState")
|
|
|
|
|
game_state.buildings.clear()
|
|
|
|
|
game_state.extractors.clear()
|
|
|
|
|
game_state.transporters.clear()
|
|
|
|
|
game_state.gas = 0
|
|
|
|
|
game_state.rocks = 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _process(delta: float) -> bool:
|
|
|
|
|
elapsed += delta
|
|
|
|
|
if stage == 0:
|
2026-08-14 12:07:50 +02:00
|
|
|
var nearby_chunk: Vector2i = WorldGen.NEARBY_GAS_GIANT_CHUNK
|
|
|
|
|
var nearby_data: Dictionary = WorldGen.planet_data_at_chunk(nearby_chunk)
|
|
|
|
|
var nearby_position: Vector2 = WorldGen.chunk_origin(nearby_chunk) + nearby_data.local_pos
|
|
|
|
|
if not WorldGen.has_planet_at_chunk(nearby_chunk):
|
|
|
|
|
return _fail("nearby gas giant chunk does not contain a planet")
|
|
|
|
|
if WorldGen.biome_at_chunk(nearby_chunk) != WorldGen.Biome.SPACE:
|
|
|
|
|
return _fail("nearby gas giant is not in the normal space biome")
|
2026-08-14 16:13:24 +02:00
|
|
|
if String(nearby_data.get("definition_id", "")) != "gas_giant":
|
2026-08-14 12:07:50 +02:00
|
|
|
return _fail("nearby guaranteed planet is not a gas source")
|
|
|
|
|
if nearby_position.length() > WorldGen.CHUNK_SIZE * 2.0:
|
|
|
|
|
return _fail("nearby gas giant spawned too far away: %s" % nearby_position)
|
|
|
|
|
|
2026-08-14 13:44:10 +02:00
|
|
|
# Gas surfaces have vents only: no deferred ore pickups, and the vent
|
|
|
|
|
# emission advances continuously so the source visibly looks active.
|
|
|
|
|
game_state.planet_name = "Gas Test"
|
2026-08-14 16:13:24 +02:00
|
|
|
game_state.planet_definition_id = "gas_giant"
|
2026-08-14 13:44:10 +02:00
|
|
|
var surface: Node = load("res://PlanetSurface.tscn").instantiate()
|
|
|
|
|
root.add_child(surface)
|
2026-08-14 16:05:32 +02:00
|
|
|
var gas_field: Node = surface.get_node("SurfaceFeatures/ResourceProvider")
|
|
|
|
|
if gas_field.get_script() != load("res://GasVentField.gd"):
|
2026-08-14 13:44:10 +02:00
|
|
|
surface.free()
|
2026-08-14 16:05:32 +02:00
|
|
|
return _fail("gas surface did not compose the gas feature scene")
|
|
|
|
|
if surface.get_node_or_null("RockField") != null:
|
|
|
|
|
surface.free()
|
|
|
|
|
return _fail("gas surface tree contains an ore producer")
|
2026-08-14 13:44:10 +02:00
|
|
|
gas_field._process(0.5)
|
|
|
|
|
if gas_field.emission_phase <= 0.0:
|
|
|
|
|
surface.free()
|
|
|
|
|
return _fail("gas-source emission animation did not advance")
|
|
|
|
|
surface.free()
|
|
|
|
|
|
2026-08-14 16:13:24 +02:00
|
|
|
game_state.planet_definition_id = "rocky"
|
2026-08-14 16:05:32 +02:00
|
|
|
var rocky_surface: Node = load("res://PlanetSurface.tscn").instantiate()
|
|
|
|
|
root.add_child(rocky_surface)
|
|
|
|
|
var rocky_features: Node = rocky_surface.get_node("SurfaceFeatures/ResourceProvider")
|
|
|
|
|
if rocky_features.get_script() != load("res://RockField.gd"):
|
|
|
|
|
rocky_surface.free()
|
|
|
|
|
return _fail("rocky surface did not compose the ore feature scene")
|
|
|
|
|
if rocky_surface.get_node_or_null("GasVentField") != null:
|
|
|
|
|
rocky_surface.free()
|
|
|
|
|
return _fail("rocky surface tree contains a gas producer")
|
|
|
|
|
rocky_surface.free()
|
|
|
|
|
|
2026-08-13 21:07:35 +02:00
|
|
|
var found_giant: bool = false
|
|
|
|
|
for x in range(-12, 13):
|
|
|
|
|
for y in range(-12, 13):
|
|
|
|
|
var data: Dictionary = WorldGen.planet_data_at_chunk(Vector2i(x, y))
|
2026-08-14 16:13:24 +02:00
|
|
|
if String(data.get("definition_id", "")) == "gas_giant":
|
|
|
|
|
found_giant = true
|
2026-08-13 21:07:35 +02:00
|
|
|
break
|
|
|
|
|
if found_giant:
|
|
|
|
|
break
|
|
|
|
|
if not found_giant:
|
|
|
|
|
return _fail("world generation produced no deterministic gas giant")
|
|
|
|
|
var giant: Node2D = load("res://Planet.tscn").instantiate()
|
2026-08-14 16:13:24 +02:00
|
|
|
giant.definition_id = "gas_giant"
|
|
|
|
|
root.add_child(giant)
|
|
|
|
|
giant.visual._process(0.5)
|
2026-08-13 21:07:35 +02:00
|
|
|
if giant.gas_phase <= 0.0:
|
|
|
|
|
return _fail("gas giant animation did not advance")
|
|
|
|
|
giant.free()
|
|
|
|
|
|
|
|
|
|
game_state.add_building(GameState.BUILDING_MOTHERSHIP, Vector2.ZERO)
|
|
|
|
|
game_state.add_building(GameState.BUILDING_TRANSPORT_HUB, Vector2(100, 0))
|
|
|
|
|
game_state.add_extractor("Aurelia", Vector2(400, 0), "gas")
|
|
|
|
|
game_state.extractors[0].stock = game_state.transporter_load_limit()
|
|
|
|
|
game_state.transporters.append({"hub_id": 2, "state": GameState.TRANSPORTER_TO_EXTRACTOR,
|
|
|
|
|
"target_id": 0, "extractor_index": 0, "carrying": 0, "resource_type": "gas",
|
|
|
|
|
"progress": 1.0, "from": Vector2(100, 0), "to": Vector2(400, 0)})
|
|
|
|
|
game_state._arrive(game_state.transporters[0])
|
|
|
|
|
if game_state.transporters[0].state != GameState.TRANSPORTER_TO_MOTHERSHIP_FROM_EXTRACTOR:
|
|
|
|
|
return _fail("transporter did not collect gas from the extractor")
|
|
|
|
|
game_state._arrive(game_state.transporters[0])
|
|
|
|
|
if game_state.gas != game_state.transporter_load_limit() or game_state.rocks != 0:
|
|
|
|
|
return _fail("gas delivery banked gas=%d ore=%d" % [game_state.gas, game_state.rocks])
|
2026-08-13 22:17:24 +02:00
|
|
|
var mothership_id: int = int(game_state.buildings[0].id)
|
|
|
|
|
if game_state.transfer_gas_to_fleet(mothership_id, 7) != 7 or game_state.fleet_gas_cargo != 7:
|
|
|
|
|
return _fail("could not load banked gas into fleet cargo")
|
|
|
|
|
if game_state.transfer_gas_to_building(2, 7) != 7 or game_state.building_gas_holdings(2) != 7:
|
|
|
|
|
return _fail("could not unload fleet gas into a building")
|
2026-08-13 21:07:35 +02:00
|
|
|
print("gas giant animated; transporter banked %d gas without creating ore" % game_state.gas)
|
|
|
|
|
print("TEST_GAS_SYSTEM: PASS")
|
|
|
|
|
quit(0)
|
|
|
|
|
return true
|
|
|
|
|
return false
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _fail(message: String) -> bool:
|
|
|
|
|
print("TEST_GAS_SYSTEM: FAIL (%s)" % message)
|
|
|
|
|
quit(1)
|
|
|
|
|
return true
|