Support gas cargo transfers

This commit is contained in:
Loïc Wisniewski 2026-08-13 22:17:24 +02:00
commit 4c82155cf3
7 changed files with 91 additions and 2 deletions

View file

@ -133,6 +133,8 @@ var lab_building_id: int = 0
@onready var to_fleet_batch_button: IconButton = get_node("../UI/TransferMenu/ToFleetBatchButton") @onready var to_fleet_batch_button: IconButton = get_node("../UI/TransferMenu/ToFleetBatchButton")
@onready var to_fleet_batch_label: Label = get_node("../UI/TransferMenu/ToFleetBatchLabel") @onready var to_fleet_batch_label: Label = get_node("../UI/TransferMenu/ToFleetBatchLabel")
@onready var to_fleet_all_button: IconButton = get_node("../UI/TransferMenu/ToFleetAllButton") @onready var to_fleet_all_button: IconButton = get_node("../UI/TransferMenu/ToFleetAllButton")
@onready var gas_to_building_button: IconButton = get_node("../UI/TransferMenu/GasToBuildingButton")
@onready var gas_to_fleet_button: IconButton = get_node("../UI/TransferMenu/GasToFleetButton")
# Every building menu carries the same header (#24). Held as a list because # Every building menu carries the same header (#24). Held as a list because
# the only thing any of them needs is to be told which building it is # the only thing any of them needs is to be told which building it is
@ -253,6 +255,8 @@ func _ready() -> void:
to_building_all_button.pressed.connect(_on_transfer.bind(true, ALL)) to_building_all_button.pressed.connect(_on_transfer.bind(true, ALL))
to_fleet_batch_button.pressed.connect(_on_transfer.bind(false, GameState.CARGO_LOAD_BATCH)) to_fleet_batch_button.pressed.connect(_on_transfer.bind(false, GameState.CARGO_LOAD_BATCH))
to_fleet_all_button.pressed.connect(_on_transfer.bind(false, ALL)) to_fleet_all_button.pressed.connect(_on_transfer.bind(false, ALL))
gas_to_building_button.pressed.connect(_on_gas_transfer.bind(true))
gas_to_fleet_button.pressed.connect(_on_gas_transfer.bind(false))
formation_close_button.pressed.connect(func(): formation_menu.visible = false) formation_close_button.pressed.connect(func(): formation_menu.visible = false)
formation_reset_button.pressed.connect(_on_reset_formation) formation_reset_button.pressed.connect(_on_reset_formation)
@ -1002,6 +1006,11 @@ func _on_transfer(to_building: bool, amount: int) -> void:
transfer_status.text = "Loaded %d ore into the fleet" % moved transfer_status.text = "Loaded %d ore into the fleet" % moved
_refresh_transfer() _refresh_transfer()
func _on_gas_transfer(to_building: bool) -> void:
var moved: int = GameState.transfer_gas_to_building(transfer_building_id, ALL) if to_building else GameState.transfer_gas_to_fleet(transfer_building_id, ALL)
transfer_status.text = "Moved %d gas" % moved if moved > 0 else "No gas available on that side"
_refresh_transfer()
func _transfer_place_name() -> String: func _transfer_place_name() -> String:
var b: Dictionary = GameState.find_building(transfer_building_id) var b: Dictionary = GameState.find_building(transfer_building_id)
@ -1037,6 +1046,10 @@ func _refresh_transfer() -> void:
for button in [to_building_batch_button, to_building_all_button, for button in [to_building_batch_button, to_building_all_button,
to_fleet_batch_button, to_fleet_all_button]: to_fleet_batch_button, to_fleet_all_button]:
button.queue_redraw() button.queue_redraw()
gas_to_building_button.enabled = GameState.fleet_gas_cargo > 0
gas_to_fleet_button.enabled = GameState.building_gas_holdings(transfer_building_id) > 0
gas_to_building_button.queue_redraw()
gas_to_fleet_button.queue_redraw()
func _refresh_queue() -> void: func _refresh_queue() -> void:

View file

@ -42,10 +42,14 @@ var gas: int = 0
# down and rebuilt on every trip to a planet's surface - and cargo mined ON a # down and rebuilt on every trip to a planet's surface - and cargo mined ON a
# surface would otherwise be dropped the moment the player took off. # surface would otherwise be dropped the moment the player took off.
var fleet_cargo: int = 0 var fleet_cargo: int = 0
var fleet_gas_cargo: int = 0
func collect_cargo(amount: int = 1) -> void: func collect_cargo(amount: int = 1) -> void:
fleet_cargo += amount fleet_cargo += amount
func collect_gas_cargo(amount: int = 1) -> void:
fleet_gas_cargo += amount
# The batch size the transfer menu offers, next to "All". A batch rather # The batch size the transfer menu offers, next to "All". A batch rather
# than only all-or-nothing: the hold is the part that can be lost, and # than only all-or-nothing: the hold is the part that can be lost, and
@ -73,6 +77,11 @@ func building_holdings(id: int) -> int:
return rocks return rocks
return int(b.get("stock", 0)) return int(b.get("stock", 0))
func building_gas_holdings(id: int) -> int:
var b: Dictionary = find_building(id)
if b.is_empty(): return 0
return gas if b.type == BUILDING_MOTHERSHIP else int(b.get("gas_stock", 0))
func transfer_to_building(id: int, amount: int) -> int: func transfer_to_building(id: int, amount: int) -> int:
# Hold -> this building. Returns how much actually moved, which is capped # Hold -> this building. Returns how much actually moved, which is capped
@ -108,6 +117,24 @@ func transfer_to_fleet(id: int, amount: int) -> int:
fleet_cargo += moved fleet_cargo += moved
return moved return moved
func transfer_gas_to_building(id: int, amount: int) -> int:
var b: Dictionary = find_building(id)
if b.is_empty(): return 0
var moved := mini(amount, fleet_gas_cargo)
fleet_gas_cargo -= moved
if b.type == BUILDING_MOTHERSHIP: gas += moved
else: b.gas_stock = int(b.get("gas_stock", 0)) + moved
return moved
func transfer_gas_to_fleet(id: int, amount: int) -> int:
var b: Dictionary = find_building(id)
if b.is_empty(): return 0
var moved := mini(amount, building_gas_holdings(id))
if b.type == BUILDING_MOTHERSHIP: gas -= moved
else: b.gas_stock = int(b.get("gas_stock", 0)) - moved
fleet_gas_cargo += moved
return moved
const MOTHERSHIP_COST: int = 20 const MOTHERSHIP_COST: int = 20
const SHIP_CRAFTER_COST: int = 12 const SHIP_CRAFTER_COST: int = 12
const SHIP_COST: int = 6 const SHIP_COST: int = 6

View file

@ -12,7 +12,7 @@ func _process(delta: float) -> void:
if fleet.get_centroid().distance_to(vent) < 90.0: if fleet.get_centroid().distance_to(vent) < 90.0:
progress += delta progress += delta
if progress >= 1.0: if progress >= 1.0:
GameState.gas += int(progress) GameState.collect_gas_cargo(int(progress))
progress = fmod(progress, 1.0) progress = fmod(progress, 1.0)
return return
progress = 0.0 progress = 0.0

View file

@ -26,6 +26,7 @@ enum Icon {
UPGRADE_SHIELD_HITS, UPGRADE_SHIELD_RECHARGE, UPGRADE_CARGO, UPGRADE_SHIELD_HITS, UPGRADE_SHIELD_RECHARGE, UPGRADE_CARGO,
UPGRADE_ENGINES, UPGRADE_UNLOCK_SHIELD, UPGRADE_ENGINES, UPGRADE_UNLOCK_SHIELD,
ACTION_MENU, ACTION_MENU,
GAS,
} }
# Size the glyphs were originally drawn against. Every glyph dimension is # Size the glyphs were originally drawn against. Every glyph dimension is
@ -200,6 +201,8 @@ func _draw() -> void:
_draw_upgrade_unlock_shield(center, pulse, s) _draw_upgrade_unlock_shield(center, pulse, s)
Icon.ACTION_MENU: Icon.ACTION_MENU:
_draw_action_menu(center, pulse, s) _draw_action_menu(center, pulse, s)
Icon.GAS:
_draw_gas(center, pulse, s)
func _draw_close(center: Vector2, pulse: float, s: float) -> void: func _draw_close(center: Vector2, pulse: float, s: float) -> void:
@ -334,6 +337,15 @@ func _draw_action_menu(center: Vector2, pulse: float, s: float) -> void:
center + Vector2(-15, y + 2) * s, center + Vector2(-15, y + 2) * s,
]), _active_color(), pulse, core_color) ]), _active_color(), pulse, core_color)
func _draw_gas(center: Vector2, pulse: float, s: float) -> void:
# Three drifting bubbles: the visual language for gaseous resources.
for data in [[Vector2(-6,-3), 6.0], [Vector2(6,4), 8.0], [Vector2(4,-9), 4.0]]:
var ring := PackedVector2Array()
for i in range(10):
var a := TAU * float(i) / 10.0
ring.append(center + (data[0] + Vector2(cos(a), sin(a)) * data[1]) * s)
NeonDraw.draw_glowing_polygon(self, ring, _active_color(), pulse, core_color)
func _draw_build(center: Vector2, pulse: float, s: float) -> void: func _draw_build(center: Vector2, pulse: float, s: float) -> void:
# A plus inside a frame - "add a structure". # A plus inside a frame - "add a structure".

View file

@ -1615,6 +1615,38 @@ script = ExtResource("10")
icon = 1 icon = 1
glow_color = Color(1, 0.78, 0.25, 1) glow_color = Color(1, 0.78, 0.25, 1)
[node name="GasToBuildingButton" type="Control" parent="UI/TransferMenu"]
anchor_left = 0.5
anchor_right = 0.5
offset_left = -180
offset_right = -32
offset_top = 1020
offset_bottom = 1168
script = ExtResource("10")
icon = 25
glow_color = Color(0.85, 0.52, 1, 1)
[node name="GasToFleetButton" type="Control" parent="UI/TransferMenu"]
anchor_left = 0.5
anchor_right = 0.5
offset_left = 32
offset_right = 180
offset_top = 1020
offset_bottom = 1168
script = ExtResource("10")
icon = 25
glow_color = Color(0.85, 0.52, 1, 1)
[node name="GasTransferLabel" type="Label" parent="UI/TransferMenu"]
mouse_filter = 2
anchor_right = 1.0
offset_top = 1172
offset_bottom = 1222
text = "GAS: unload all load all"
horizontal_alignment = 1
theme_override_colors/font_color = Color(0.85, 0.52, 1, 1)
theme_override_font_sizes/font_size = 22
[node name="FormationMenu" type="Control" parent="UI" groups=["modal_menus"]] [node name="FormationMenu" type="Control" parent="UI" groups=["modal_menus"]]
visible = false visible = false
mouse_filter = 2 mouse_filter = 2

View file

@ -93,7 +93,7 @@ func _layout() -> void:
func _process(_delta: float) -> void: func _process(_delta: float) -> void:
_gas_caption.text = "GAS %d" % GameState.gas _gas_caption.text = "GAS %d / %d / %d" % [GameState.gas, GameState.fleet_gas_cargo, GameState.building_gas_holdings(building_id)]
_numbers[0].set_amount(GameState.rocks) _numbers[0].set_amount(GameState.rocks)
_numbers[1].set_amount(GameState.fleet_cargo) _numbers[1].set_amount(GameState.fleet_cargo)

View file

@ -51,6 +51,11 @@ func _process(delta: float) -> bool:
game_state._arrive(game_state.transporters[0]) game_state._arrive(game_state.transporters[0])
if game_state.gas != game_state.transporter_load_limit() or game_state.rocks != 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]) return _fail("gas delivery banked gas=%d ore=%d" % [game_state.gas, game_state.rocks])
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")
print("gas giant animated; transporter banked %d gas without creating ore" % game_state.gas) print("gas giant animated; transporter banked %d gas without creating ore" % game_state.gas)
print("TEST_GAS_SYSTEM: PASS") print("TEST_GAS_SYSTEM: PASS")
quit(0) quit(0)