Refactor multi-resource UI and transfers

This commit is contained in:
Loïc Wisniewski 2026-08-14 11:54:31 +02:00
commit 8231e165ff
20 changed files with 648 additions and 435 deletions

View file

@ -44,6 +44,22 @@ var gas: int = 0
var fleet_cargo: int = 0
var fleet_gas_cargo: int = 0
# Resource-facing UI and logistics iterate this list instead of growing a
# second set of controls and controller branches every time a material is
# introduced. Keep presentation data here with the state it describes so a
# resource has one name and colour everywhere it appears.
const RESOURCE_ORE: String = "ore"
const RESOURCE_GAS: String = "gas"
const RESOURCE_TYPES: PackedStringArray = [RESOURCE_ORE, RESOURCE_GAS]
const RESOURCE_NAMES: Dictionary = {
RESOURCE_ORE: "Ore",
RESOURCE_GAS: "Gas",
}
const RESOURCE_COLORS: Dictionary = {
RESOURCE_ORE: Color(0.0, 0.72, 0.82),
RESOURCE_GAS: Color(0.85, 0.52, 1.0),
}
func collect_cargo(amount: int = 1) -> void:
fleet_cargo += amount
@ -51,6 +67,83 @@ func collect_gas_cargo(amount: int = 1) -> void:
fleet_gas_cargo += amount
func resource_name(resource_type: String) -> String:
return String(RESOURCE_NAMES.get(resource_type, resource_type.capitalize()))
func resource_color(resource_type: String) -> Color:
return RESOURCE_COLORS.get(resource_type, Color.WHITE)
func banked_resource(resource_type: String) -> int:
match resource_type:
RESOURCE_ORE: return rocks
RESOURCE_GAS: return gas
_: return 0
func fleet_resource(resource_type: String) -> int:
match resource_type:
RESOURCE_ORE: return fleet_cargo
RESOURCE_GAS: return fleet_gas_cargo
_: return 0
func building_resource(id: int, resource_type: String) -> int:
var building: Dictionary = find_building(id)
if building.is_empty():
return 0
if building.type == BUILDING_MOTHERSHIP:
return banked_resource(resource_type)
match resource_type:
RESOURCE_ORE: return int(building.get("stock", 0))
RESOURCE_GAS: return int(building.get("gas_stock", 0))
_: return 0
func transfer_resource_to_building(id: int, resource_type: String, amount: int) -> int:
var building: Dictionary = find_building(id)
if building.is_empty():
return 0
var moved: int = mini(maxi(amount, 0), fleet_resource(resource_type))
if moved <= 0:
return 0
match resource_type:
RESOURCE_ORE: fleet_cargo -= moved
RESOURCE_GAS: fleet_gas_cargo -= moved
_: return 0
if building.type == BUILDING_MOTHERSHIP:
match resource_type:
RESOURCE_ORE: rocks += moved
RESOURCE_GAS: gas += moved
else:
match resource_type:
RESOURCE_ORE: building.stock = int(building.get("stock", 0)) + moved
RESOURCE_GAS: building.gas_stock = int(building.get("gas_stock", 0)) + moved
return moved
func transfer_resource_to_fleet(id: int, resource_type: String, amount: int) -> int:
var building: Dictionary = find_building(id)
if building.is_empty():
return 0
var moved: int = mini(maxi(amount, 0), building_resource(id, resource_type))
if moved <= 0:
return 0
if building.type == BUILDING_MOTHERSHIP:
match resource_type:
RESOURCE_ORE: rocks -= moved
RESOURCE_GAS: gas -= moved
else:
match resource_type:
RESOURCE_ORE: building.stock = int(building.get("stock", 0)) - moved
RESOURCE_GAS: building.gas_stock = int(building.get("gas_stock", 0)) - moved
match resource_type:
RESOURCE_ORE: fleet_cargo += moved
RESOURCE_GAS: fleet_gas_cargo += moved
return moved
# 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
# emptying the bank in one tap would strand research, which spends from it.
@ -70,70 +163,29 @@ const CARGO_LOAD_BATCH: int = 25
func building_holdings(id: int) -> int:
var b: Dictionary = find_building(id)
if b.is_empty():
return 0
if b.type == BUILDING_MOTHERSHIP:
return rocks
return int(b.get("stock", 0))
return building_resource(id, RESOURCE_ORE)
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))
return building_resource(id, RESOURCE_GAS)
func transfer_to_building(id: int, amount: int) -> int:
# Hold -> this building. Returns how much actually moved, which is capped
# by the hold: a caller asking for "all" passes a number too big on
# purpose and reads the result back.
var b: Dictionary = find_building(id)
if b.is_empty():
return 0
var moved: int = mini(amount, fleet_cargo)
if moved <= 0:
return 0
fleet_cargo -= moved
if b.type == BUILDING_MOTHERSHIP:
rocks += moved
else:
b.stock = int(b.get("stock", 0)) + moved
return moved
return transfer_resource_to_building(id, RESOURCE_ORE, amount)
func transfer_to_fleet(id: int, amount: int) -> int:
# This building -> hold. Capped by what the building actually holds, so
# there is no overdraft in either direction.
var b: Dictionary = find_building(id)
if b.is_empty():
return 0
var moved: int = mini(amount, building_holdings(id))
if moved <= 0:
return 0
if b.type == BUILDING_MOTHERSHIP:
rocks -= moved
else:
b.stock = int(b.get("stock", 0)) - moved
fleet_cargo += moved
return moved
return transfer_resource_to_fleet(id, RESOURCE_ORE, amount)
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
return transfer_resource_to_building(id, RESOURCE_GAS, amount)
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
return transfer_resource_to_fleet(id, RESOURCE_GAS, amount)
const MOTHERSHIP_COST: int = 20
const SHIP_CRAFTER_COST: int = 12
@ -348,7 +400,8 @@ func add_building(type: String, at_position: Vector2) -> int:
var id: int = next_building_id
next_building_id += 1
buildings.append({
"id": id, "type": type, "position": at_position, "stock": 0, "orders": [],
"id": id, "type": type, "position": at_position, "stock": 0,
"gas_stock": 0, "orders": [],
})
return id