Refactor multi-resource UI and transfers
This commit is contained in:
parent
af5e08e5a1
commit
8231e165ff
20 changed files with 648 additions and 435 deletions
|
|
@ -125,25 +125,14 @@ var lab_building_id: int = 0
|
|||
@onready var transfer_menu: Control = get_node("../UI/TransferMenu")
|
||||
@onready var transfer_status: Label = get_node("../UI/TransferMenu/StatusLabel")
|
||||
@onready var transfer_close_button: IconButton = get_node("../UI/TransferMenu/CloseButton")
|
||||
@onready var to_building_label: Label = get_node("../UI/TransferMenu/ToBuildingLabel")
|
||||
@onready var to_building_batch_button: IconButton = get_node("../UI/TransferMenu/ToBuildingBatchButton")
|
||||
@onready var to_building_batch_label: Label = get_node("../UI/TransferMenu/ToBuildingBatchLabel")
|
||||
@onready var to_building_all_label: Label = get_node("../UI/TransferMenu/ToBuildingAllLabel")
|
||||
@onready var to_building_all_button: IconButton = get_node("../UI/TransferMenu/ToBuildingAllButton")
|
||||
@onready var to_fleet_label: Label = get_node("../UI/TransferMenu/ToFleetLabel")
|
||||
@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_all_label: Label = get_node("../UI/TransferMenu/ToFleetAllLabel")
|
||||
@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")
|
||||
@onready var transfer_list: ResourceTransferList = get_node("../UI/TransferMenu/ResourceList")
|
||||
|
||||
# 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
|
||||
# reporting on when its panel opens.
|
||||
@onready var resource_bars: Array = [
|
||||
get_node("../UI/CraftMenu/Bar"), get_node("../UI/SkillMenu/Bar"),
|
||||
get_node("../UI/LabMenu/Bar"), get_node("../UI/TransferMenu/Bar"),
|
||||
get_node("../UI/LabMenu/Bar"),
|
||||
]
|
||||
|
||||
@onready var skill_menu: Control = get_node("../UI/SkillMenu")
|
||||
|
|
@ -253,12 +242,7 @@ func _ready() -> void:
|
|||
for i in range(queue_slots.size()):
|
||||
queue_slots[i].pressed.connect(_on_queue_slot.bind(i))
|
||||
transfer_close_button.pressed.connect(func(): transfer_menu.visible = false)
|
||||
to_building_batch_button.pressed.connect(_on_transfer.bind(true, GameState.CARGO_LOAD_BATCH))
|
||||
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_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))
|
||||
transfer_list.transfer_requested.connect(_on_resource_transfer)
|
||||
|
||||
formation_close_button.pressed.connect(func(): formation_menu.visible = false)
|
||||
formation_reset_button.pressed.connect(_on_reset_formation)
|
||||
|
|
@ -978,40 +962,45 @@ func _on_transfer_pressed() -> void:
|
|||
if current_building == null:
|
||||
return
|
||||
transfer_building_id = current_building.building_id
|
||||
for bar in resource_bars:
|
||||
bar.building_id = transfer_building_id
|
||||
transfer_menu.visible = true
|
||||
transfer_status.text = ""
|
||||
_refresh_transfer()
|
||||
|
||||
|
||||
func _on_transfer(to_building: bool, amount: int) -> void:
|
||||
_on_resource_transfer(GameState.RESOURCE_ORE, to_building, amount)
|
||||
|
||||
|
||||
func _on_resource_transfer(resource_type: String, to_building: bool, amount: int = ALL) -> void:
|
||||
if transfer_building_id == 0:
|
||||
transfer_status.text = "No building selected - reopen this panel from the building"
|
||||
return
|
||||
|
||||
var moved: int = 0
|
||||
if to_building:
|
||||
moved = GameState.transfer_to_building(transfer_building_id, amount)
|
||||
else:
|
||||
moved = GameState.transfer_to_fleet(transfer_building_id, amount)
|
||||
var moved: int = GameState.transfer_resource_to_building(
|
||||
transfer_building_id, resource_type, amount
|
||||
) if to_building else GameState.transfer_resource_to_fleet(
|
||||
transfer_building_id, resource_type, amount
|
||||
)
|
||||
var resource_name: String = GameState.resource_name(resource_type).to_lower()
|
||||
|
||||
# Nothing moving is the common case at an empty end, and a silent no-op
|
||||
# is the dead-button problem this panel exists to remove. Say which side
|
||||
# was empty rather than just refusing.
|
||||
if moved <= 0:
|
||||
if to_building:
|
||||
transfer_status.text = "The fleet is carrying nothing to unload"
|
||||
transfer_status.text = "The fleet is carrying nothing to unload (no %s)" % resource_name
|
||||
else:
|
||||
transfer_status.text = "%s has no ore to load" % _transfer_place_name()
|
||||
transfer_status.text = "%s has no %s to load" % [_transfer_place_name().capitalize(), resource_name]
|
||||
elif to_building:
|
||||
transfer_status.text = "Moved %d ore into %s" % [moved, _transfer_place_name()]
|
||||
transfer_status.text = "Moved %d %s into %s" % [moved, resource_name, _transfer_place_name()]
|
||||
else:
|
||||
transfer_status.text = "Loaded %d ore into the fleet" % moved
|
||||
transfer_status.text = "Loaded %d %s into the fleet" % [moved, resource_name]
|
||||
_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()
|
||||
_on_resource_transfer(GameState.RESOURCE_GAS, to_building)
|
||||
|
||||
|
||||
func _transfer_place_name() -> String:
|
||||
|
|
@ -1026,38 +1015,11 @@ func _transfer_place_name() -> String:
|
|||
|
||||
|
||||
func _refresh_transfer() -> void:
|
||||
for bar in resource_bars:
|
||||
bar.building_id = transfer_building_id
|
||||
|
||||
var hold: int = GameState.fleet_cargo
|
||||
var here: int = GameState.building_holdings(transfer_building_id)
|
||||
var batch: int = GameState.CARGO_LOAD_BATCH
|
||||
|
||||
to_building_label.text = "ORE"
|
||||
to_fleet_label.text = "GAS"
|
||||
to_building_batch_button.visible = false
|
||||
to_building_batch_label.visible = false
|
||||
to_fleet_batch_button.visible = false
|
||||
to_fleet_batch_label.visible = false
|
||||
to_building_all_label.text = "Unload all"
|
||||
to_fleet_all_label.text = "Load all"
|
||||
# The batch buttons say what they would actually move, not the nominal
|
||||
# batch size: offering "25" when the hold has 4 in it is a promise the
|
||||
# press cannot keep.
|
||||
to_building_batch_label.text = "%d" % mini(batch, hold)
|
||||
to_fleet_batch_label.text = "%d" % mini(batch, here)
|
||||
|
||||
to_building_batch_button.enabled = hold > 0
|
||||
to_building_all_button.enabled = hold > 0
|
||||
to_fleet_batch_button.enabled = here > 0
|
||||
to_fleet_all_button.enabled = here > 0
|
||||
for button in [to_building_batch_button, to_building_all_button,
|
||||
to_fleet_batch_button, to_fleet_all_button]:
|
||||
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()
|
||||
var building: Dictionary = GameState.find_building(transfer_building_id)
|
||||
var heading: String = "This building"
|
||||
if not building.is_empty() and building.type == GameState.BUILDING_MOTHERSHIP:
|
||||
heading = "Mothership bank"
|
||||
transfer_list.set_destination(transfer_building_id, heading)
|
||||
|
||||
|
||||
func _refresh_queue() -> void:
|
||||
|
|
|
|||
149
GameState.gd
149
GameState.gd
|
|
@ -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
|
||||
|
||||
|
|
|
|||
10
GasCargoCounter.gd
Normal file
10
GasCargoCounter.gd
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
extends "res://GasCounter.gd"
|
||||
|
||||
# Fleet-side companion to GasCounter. It keeps the gas bubble glyph instead
|
||||
# of recolouring ore, and occupies the same row as banked gas in the HUD.
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
visible = GameState.fleet_gas_cargo > 0
|
||||
if visible:
|
||||
set_amount(GameState.fleet_gas_cargo)
|
||||
|
|
@ -18,4 +18,20 @@ func _process(delta: float) -> void:
|
|||
progress = 0.0
|
||||
func _draw() -> void:
|
||||
for vent in vents:
|
||||
NeonDraw.draw_glowing_polygon(self, PackedVector2Array([vent+Vector2(0,-44),vent+Vector2(38,-22),vent+Vector2(38,22),vent+Vector2(0,44),vent+Vector2(-38,22),vent+Vector2(-38,-22)]), Color(0.85,0.52,1),0.8,Color(0.15,0.03,0.22),0.5)
|
||||
_draw_gas_source(vent)
|
||||
|
||||
|
||||
func _draw_gas_source(centre: Vector2) -> void:
|
||||
var colour := Color(0.85, 0.52, 1.0)
|
||||
var core := Color(0.15, 0.03, 0.22)
|
||||
var bubbles: Array = [
|
||||
[centre + Vector2(-20.0, 8.0), 20.0],
|
||||
[centre + Vector2(18.0, 14.0), 27.0],
|
||||
[centre + Vector2(17.0, -22.0), 15.0],
|
||||
]
|
||||
for bubble in bubbles:
|
||||
var ring := PackedVector2Array()
|
||||
for i in range(12):
|
||||
var angle: float = TAU * float(i) / 12.0
|
||||
ring.append(bubble[0] + Vector2(cos(angle), sin(angle)) * float(bubble[1]))
|
||||
NeonDraw.draw_glowing_polygon(self, ring, colour, 0.9, core, 0.6)
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ enum Icon {
|
|||
UPGRADE_ENGINES, UPGRADE_UNLOCK_SHIELD,
|
||||
ACTION_MENU,
|
||||
GAS,
|
||||
LEFT_ARROW, RIGHT_ARROW,
|
||||
}
|
||||
|
||||
# Size the glyphs were originally drawn against. Every glyph dimension is
|
||||
|
|
@ -203,6 +204,10 @@ func _draw() -> void:
|
|||
_draw_action_menu(center, pulse, s)
|
||||
Icon.GAS:
|
||||
_draw_gas(center, pulse, s)
|
||||
Icon.LEFT_ARROW:
|
||||
_draw_horizontal_arrow(center, pulse, -1.0, s)
|
||||
Icon.RIGHT_ARROW:
|
||||
_draw_horizontal_arrow(center, pulse, 1.0, s)
|
||||
|
||||
|
||||
func _draw_close(center: Vector2, pulse: float, s: float) -> void:
|
||||
|
|
@ -228,6 +233,15 @@ func _draw_arrow(center: Vector2, pulse: float, direction: float, s: float) -> v
|
|||
NeonDraw.draw_glowing_line(self, tip, tip + Vector2(r * 0.7, -r * 0.8 * direction), _active_color(), pulse, 0.5 * s, core_color)
|
||||
|
||||
|
||||
func _draw_horizontal_arrow(center: Vector2, pulse: float, direction: float, s: float) -> void:
|
||||
var r: float = 10.0 * s
|
||||
var tip: Vector2 = center + Vector2(r * direction, 0.0)
|
||||
var tail: Vector2 = center + Vector2(-r * direction, 0.0)
|
||||
NeonDraw.draw_glowing_line(self, tail, tip, _active_color(), pulse, 0.5 * s, core_color)
|
||||
NeonDraw.draw_glowing_line(self, tip, tip + Vector2(-r * 0.8 * direction, -r * 0.7), _active_color(), pulse, 0.5 * s, core_color)
|
||||
NeonDraw.draw_glowing_line(self, tip, tip + Vector2(-r * 0.8 * direction, r * 0.7), _active_color(), pulse, 0.5 * s, core_color)
|
||||
|
||||
|
||||
func _draw_transfer_icon(center: Vector2, pulse: float, s: float) -> void:
|
||||
# Two shafts side by side pointing opposite ways. Drawn as a pair rather
|
||||
# than as one double-headed arrow because the button's whole job is that
|
||||
|
|
|
|||
249
Main.tscn
249
Main.tscn
|
|
@ -1,4 +1,4 @@
|
|||
[gd_scene load_steps=23 format=3]
|
||||
[gd_scene load_steps=29 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://Starfield.gd" id="1"]
|
||||
[ext_resource type="Script" path="res://Fleet.gd" id="2"]
|
||||
|
|
@ -25,6 +25,8 @@
|
|||
[ext_resource type="Script" path="res://ResourceBar.gd" id="24"]
|
||||
[ext_resource type="Script" path="res://GasCounter.gd" id="25"]
|
||||
[ext_resource type="Script" path="res://VesselDeliveryField.gd" id="26"]
|
||||
[ext_resource type="Script" path="res://ResourceTransferList.gd" id="27"]
|
||||
[ext_resource type="Script" path="res://GasCargoCounter.gd" id="28"]
|
||||
|
||||
[sub_resource type="ShaderMaterial" id="1"]
|
||||
shader = ExtResource("5")
|
||||
|
|
@ -90,48 +92,58 @@ layer = 1
|
|||
[node name="ResourceCounter" type="Control" parent="UI"]
|
||||
mouse_filter = 2
|
||||
offset_left = 28
|
||||
offset_top = 24
|
||||
offset_top = 38
|
||||
offset_right = 320
|
||||
offset_bottom = 92
|
||||
offset_bottom = 82
|
||||
script = ExtResource("16")
|
||||
digit_height = 60.0
|
||||
digit_height = 38.0
|
||||
|
||||
[node name="OreCaption" type="Label" parent="UI"]
|
||||
mouse_filter = 2
|
||||
offset_left = 28
|
||||
offset_top = 22
|
||||
offset_right = 120
|
||||
offset_bottom = 48
|
||||
offset_top = 6
|
||||
offset_right = 220
|
||||
offset_bottom = 34
|
||||
theme_override_font_sizes/font_size = 18
|
||||
text = "ORE"
|
||||
theme_override_colors/font_color = Color(0.55, 0.78, 0.86, 1)
|
||||
text = "BANKED"
|
||||
|
||||
[node name="GasCounter" type="Control" parent="UI"]
|
||||
mouse_filter = 2
|
||||
offset_left = 294
|
||||
offset_top = 24
|
||||
offset_right = 468
|
||||
offset_bottom = 92
|
||||
script = ExtResource("25")
|
||||
digit_height = 60.0
|
||||
|
||||
[node name="GasCaption" type="Label" parent="UI"]
|
||||
mouse_filter = 2
|
||||
offset_left = 294
|
||||
offset_top = 22
|
||||
offset_right = 380
|
||||
offset_bottom = 48
|
||||
theme_override_font_sizes/font_size = 18
|
||||
theme_override_colors/font_color = Color(0.85, 0.52, 1, 1)
|
||||
text = "GAS"
|
||||
|
||||
[node name="CargoCounter" type="Control" parent="UI"]
|
||||
mouse_filter = 2
|
||||
offset_left = 28
|
||||
offset_top = 96
|
||||
offset_right = 320
|
||||
offset_bottom = 146
|
||||
offset_bottom = 140
|
||||
script = ExtResource("25")
|
||||
digit_height = 38.0
|
||||
|
||||
[node name="GasCaption" type="Label" parent="UI"]
|
||||
mouse_filter = 2
|
||||
offset_left = 356
|
||||
offset_top = 6
|
||||
offset_right = 620
|
||||
offset_bottom = 34
|
||||
theme_override_font_sizes/font_size = 18
|
||||
theme_override_colors/font_color = Color(1, 0.78, 0.25, 1)
|
||||
text = "FLEET HOLD"
|
||||
|
||||
[node name="CargoCounter" type="Control" parent="UI"]
|
||||
mouse_filter = 2
|
||||
offset_left = 356
|
||||
offset_top = 38
|
||||
offset_right = 696
|
||||
offset_bottom = 82
|
||||
script = ExtResource("22")
|
||||
digit_height = 42.0
|
||||
digit_height = 38.0
|
||||
|
||||
[node name="GasCargoCounter" type="Control" parent="UI"]
|
||||
mouse_filter = 2
|
||||
offset_left = 356
|
||||
offset_top = 96
|
||||
offset_right = 696
|
||||
offset_bottom = 140
|
||||
script = ExtResource("28")
|
||||
digit_height = 38.0
|
||||
|
||||
[node name="PlanetNameLabel" type="Label" parent="UI"]
|
||||
visible = false
|
||||
|
|
@ -947,10 +959,11 @@ horizontal_alignment = 1
|
|||
|
||||
[node name="Bar" type="Control" parent="UI/LabMenu"]
|
||||
mouse_filter = 2
|
||||
anchor_right = 1.0
|
||||
offset_left = 24
|
||||
offset_top = 180
|
||||
offset_right = 520
|
||||
offset_bottom = 260
|
||||
offset_right = -24
|
||||
offset_bottom = 264
|
||||
script = ExtResource("24")
|
||||
|
||||
[node name="VesselA" type="Control" parent="UI/LabMenu"]
|
||||
|
|
@ -1004,7 +1017,7 @@ anchor_left = 0.5
|
|||
anchor_right = 0.5
|
||||
offset_left = -330
|
||||
offset_right = -130
|
||||
offset_top = 376
|
||||
offset_top = 400
|
||||
offset_bottom = 460
|
||||
theme_override_font_sizes/font_size = 22
|
||||
horizontal_alignment = 1
|
||||
|
|
@ -1258,7 +1271,7 @@ mouse_filter = 2
|
|||
offset_left = 24
|
||||
offset_top = 180
|
||||
offset_right = 520
|
||||
offset_bottom = 260
|
||||
offset_bottom = 264
|
||||
script = ExtResource("24")
|
||||
|
||||
[node name="StatusLabel" type="Label" parent="UI/CraftMenu"]
|
||||
|
|
@ -1467,142 +1480,29 @@ offset_left = 24
|
|||
offset_top = 36
|
||||
offset_right = -200
|
||||
offset_bottom = 166
|
||||
text = "Move ore"
|
||||
text = "Transfer cargo"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="Bar" type="Control" parent="UI/TransferMenu"]
|
||||
mouse_filter = 2
|
||||
offset_left = 24
|
||||
offset_top = 180
|
||||
offset_right = 520
|
||||
offset_bottom = 260
|
||||
script = ExtResource("24")
|
||||
|
||||
[node name="StatusLabel" type="Label" parent="UI/TransferMenu"]
|
||||
mouse_filter = 2
|
||||
anchor_right = 1.0
|
||||
offset_left = 24
|
||||
offset_top = 274
|
||||
offset_top = 184
|
||||
offset_right = -24
|
||||
offset_bottom = 396
|
||||
theme_override_font_sizes/font_size = 34
|
||||
offset_bottom = 284
|
||||
theme_override_font_sizes/font_size = 30
|
||||
autowrap_mode = 2
|
||||
text = ""
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="ToBuildingLabel" type="Label" parent="UI/TransferMenu"]
|
||||
[node name="ResourceList" type="Control" parent="UI/TransferMenu"]
|
||||
mouse_filter = 2
|
||||
anchor_right = 1.0
|
||||
offset_left = 24
|
||||
offset_top = 376
|
||||
offset_top = 294
|
||||
offset_right = -24
|
||||
offset_bottom = 426
|
||||
theme_override_font_sizes/font_size = 28
|
||||
text = ""
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="ToBuildingBatchButton" type="Control" parent="UI/TransferMenu"]
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -184
|
||||
offset_right = -36
|
||||
offset_top = 438
|
||||
offset_bottom = 586
|
||||
script = ExtResource("10")
|
||||
icon = 3
|
||||
glow_color = Color(0.45, 0.9, 0.55, 1)
|
||||
|
||||
[node name="ToBuildingBatchLabel" type="Label" parent="UI/TransferMenu"]
|
||||
mouse_filter = 2
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -230
|
||||
offset_right = 10
|
||||
offset_top = 592
|
||||
offset_bottom = 638
|
||||
theme_override_font_sizes/font_size = 24
|
||||
text = ""
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="ToBuildingAllButton" type="Control" parent="UI/TransferMenu"]
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -180
|
||||
offset_right = -32
|
||||
offset_top = 438
|
||||
offset_bottom = 586
|
||||
script = ExtResource("10")
|
||||
icon = 3
|
||||
glow_color = Color(0.45, 0.9, 0.55, 1)
|
||||
|
||||
[node name="ToBuildingAllLabel" type="Label" parent="UI/TransferMenu"]
|
||||
mouse_filter = 2
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -230
|
||||
offset_right = 10
|
||||
offset_top = 592
|
||||
offset_bottom = 638
|
||||
theme_override_font_sizes/font_size = 24
|
||||
text = "Unload all"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="ToFleetLabel" type="Label" parent="UI/TransferMenu"]
|
||||
mouse_filter = 2
|
||||
anchor_right = 1.0
|
||||
offset_left = 24
|
||||
offset_top = 680
|
||||
offset_right = -24
|
||||
offset_bottom = 730
|
||||
theme_override_font_sizes/font_size = 28
|
||||
text = ""
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="ToFleetBatchButton" type="Control" parent="UI/TransferMenu"]
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -184
|
||||
offset_right = -36
|
||||
offset_top = 756
|
||||
offset_bottom = 904
|
||||
script = ExtResource("10")
|
||||
icon = 4
|
||||
glow_color = Color(1, 0.78, 0.25, 1)
|
||||
|
||||
[node name="ToFleetBatchLabel" type="Label" parent="UI/TransferMenu"]
|
||||
mouse_filter = 2
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -230
|
||||
offset_right = 10
|
||||
offset_top = 910
|
||||
offset_bottom = 962
|
||||
theme_override_font_sizes/font_size = 30
|
||||
text = ""
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="ToFleetAllButton" type="Control" parent="UI/TransferMenu"]
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = 32
|
||||
offset_right = 180
|
||||
offset_top = 438
|
||||
offset_bottom = 586
|
||||
script = ExtResource("10")
|
||||
icon = 4
|
||||
glow_color = Color(1, 0.78, 0.25, 1)
|
||||
|
||||
[node name="ToFleetAllLabel" type="Label" parent="UI/TransferMenu"]
|
||||
mouse_filter = 2
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = 10
|
||||
offset_right = 230
|
||||
offset_top = 592
|
||||
offset_bottom = 638
|
||||
theme_override_font_sizes/font_size = 24
|
||||
text = "Load all"
|
||||
horizontal_alignment = 1
|
||||
offset_bottom = 1080
|
||||
script = ExtResource("27")
|
||||
|
||||
[node name="CloseButton" type="Control" parent="UI/TransferMenu"]
|
||||
anchor_left = 1.0
|
||||
|
|
@ -1615,37 +1515,17 @@ script = ExtResource("10")
|
|||
icon = 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 = 742
|
||||
offset_bottom = 890
|
||||
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 = 742
|
||||
offset_bottom = 890
|
||||
script = ExtResource("10")
|
||||
icon = 25
|
||||
glow_color = Color(0.85, 0.52, 1, 1)
|
||||
|
||||
[node name="GasTransferLabel" type="Label" parent="UI/TransferMenu"]
|
||||
[node name="HintLabel" type="Label" parent="UI/TransferMenu"]
|
||||
mouse_filter = 2
|
||||
anchor_right = 1.0
|
||||
offset_top = 896
|
||||
offset_bottom = 942
|
||||
text = "Unload all Load all"
|
||||
offset_left = 24
|
||||
offset_top = 1092
|
||||
offset_right = -24
|
||||
offset_bottom = 1150
|
||||
text = "Arrows move everything available on that side"
|
||||
horizontal_alignment = 1
|
||||
theme_override_colors/font_color = Color(0.85, 0.52, 1, 1)
|
||||
theme_override_font_sizes/font_size = 22
|
||||
theme_override_colors/font_color = Color(0.55, 0.7, 0.78, 1)
|
||||
theme_override_font_sizes/font_size = 20
|
||||
|
||||
[node name="FormationMenu" type="Control" parent="UI" groups=["modal_menus"]]
|
||||
visible = false
|
||||
|
|
@ -1755,10 +1635,11 @@ horizontal_alignment = 1
|
|||
|
||||
[node name="Bar" type="Control" parent="UI/SkillMenu"]
|
||||
mouse_filter = 2
|
||||
anchor_right = 1.0
|
||||
offset_left = 24.0
|
||||
offset_top = 180.0
|
||||
offset_right = 520.0
|
||||
offset_bottom = 260.0
|
||||
offset_right = -24.0
|
||||
offset_bottom = 264.0
|
||||
script = ExtResource("24")
|
||||
|
||||
[node name="Tree" type="Control" parent="UI/SkillMenu"]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
[gd_scene load_steps=12 format=3]
|
||||
[gd_scene load_steps=15 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://GameController.gd" id="1"]
|
||||
[ext_resource type="Script" path="res://LunarBackground.gd" id="2"]
|
||||
|
|
@ -10,6 +10,9 @@
|
|||
[ext_resource type="Script" path="res://RockField.gd" id="8"]
|
||||
[ext_resource type="Script" path="res://ResourceCounter.gd" id="9"]
|
||||
[ext_resource type="Script" path="res://GasVentField.gd" id="10"]
|
||||
[ext_resource type="Script" path="res://GasCounter.gd" id="11"]
|
||||
[ext_resource type="Script" path="res://CargoCounter.gd" id="12"]
|
||||
[ext_resource type="Script" path="res://GasCargoCounter.gd" id="13"]
|
||||
|
||||
[sub_resource type="ShaderMaterial" id="1"]
|
||||
shader = ExtResource("3")
|
||||
|
|
@ -62,14 +65,65 @@ layer = 1
|
|||
[node name="ResourceCounter" type="Control" parent="UI"]
|
||||
mouse_filter = 2
|
||||
offset_left = 28
|
||||
offset_top = 24
|
||||
offset_top = 38
|
||||
offset_right = 320
|
||||
offset_bottom = 92
|
||||
offset_bottom = 82
|
||||
script = ExtResource("9")
|
||||
digit_height = 60.0
|
||||
digit_height = 38.0
|
||||
glow_color = Color(0, 0.42, 0.48, 1)
|
||||
core_color = Color(0, 0.08, 0.1, 1)
|
||||
|
||||
[node name="BankCaption" type="Label" parent="UI"]
|
||||
mouse_filter = 2
|
||||
offset_left = 28
|
||||
offset_top = 6
|
||||
offset_right = 220
|
||||
offset_bottom = 34
|
||||
theme_override_font_sizes/font_size = 18
|
||||
theme_override_colors/font_color = Color(0.08, 0.16, 0.2, 1)
|
||||
theme_override_colors/font_outline_color = Color(0.9, 0.95, 0.96, 0.8)
|
||||
theme_override_constants/outline_size = 4
|
||||
text = "BANKED"
|
||||
|
||||
[node name="GasCounter" type="Control" parent="UI"]
|
||||
mouse_filter = 2
|
||||
offset_left = 28
|
||||
offset_top = 96
|
||||
offset_right = 320
|
||||
offset_bottom = 140
|
||||
script = ExtResource("11")
|
||||
digit_height = 38.0
|
||||
|
||||
[node name="FleetCaption" type="Label" parent="UI"]
|
||||
mouse_filter = 2
|
||||
offset_left = 356
|
||||
offset_top = 6
|
||||
offset_right = 620
|
||||
offset_bottom = 34
|
||||
theme_override_font_sizes/font_size = 18
|
||||
theme_override_colors/font_color = Color(0.24, 0.14, 0.02, 1)
|
||||
theme_override_colors/font_outline_color = Color(0.96, 0.93, 0.82, 0.85)
|
||||
theme_override_constants/outline_size = 4
|
||||
text = "FLEET HOLD"
|
||||
|
||||
[node name="CargoCounter" type="Control" parent="UI"]
|
||||
mouse_filter = 2
|
||||
offset_left = 356
|
||||
offset_top = 38
|
||||
offset_right = 696
|
||||
offset_bottom = 82
|
||||
script = ExtResource("12")
|
||||
digit_height = 38.0
|
||||
|
||||
[node name="GasCargoCounter" type="Control" parent="UI"]
|
||||
mouse_filter = 2
|
||||
offset_left = 356
|
||||
offset_top = 96
|
||||
offset_right = 696
|
||||
offset_bottom = 140
|
||||
script = ExtResource("13")
|
||||
digit_height = 38.0
|
||||
|
||||
[node name="PlanetNameLabel" type="Label" parent="UI"]
|
||||
offset_left = 24
|
||||
offset_top = 156
|
||||
|
|
|
|||
|
|
@ -20,10 +20,22 @@ var transitioning: bool = false
|
|||
func _ready() -> void:
|
||||
if GameState.planet_type == "gas_giant":
|
||||
# A gas giant is not lunar terrain: its surface view uses a deep,
|
||||
# coloured atmosphere instead of the rocky field.
|
||||
# coloured atmosphere instead of the rocky field. The background is
|
||||
# shader-driven, so changing ColorRect.color does not tint it; update
|
||||
# the actual palette uniforms.
|
||||
get_node("../RockField").visible = false
|
||||
get_node("../GasVentField").visible = true
|
||||
get_node("../BackgroundLayer/LunarBackground").color = Color(0.16, 0.035, 0.26, 1.0)
|
||||
var background: ColorRect = get_node("../BackgroundLayer/LunarBackground")
|
||||
var atmosphere: ShaderMaterial = background.material
|
||||
atmosphere.set_shader_parameter("base_color", Color(0.13, 0.025, 0.22, 1.0))
|
||||
atmosphere.set_shader_parameter("crater_color", Color(0.055, 0.008, 0.11, 1.0))
|
||||
atmosphere.set_shader_parameter("highlight_color", Color(0.52, 0.17, 0.7, 1.0))
|
||||
# The lunar surface uses dark captions on a bright ground. Flip only
|
||||
# those captions for the night-dark gas atmosphere.
|
||||
for caption_path in ["../UI/BankCaption", "../UI/FleetCaption"]:
|
||||
var caption: Label = get_node(caption_path)
|
||||
caption.add_theme_color_override("font_color", Color(0.78, 0.88, 0.94))
|
||||
caption.add_theme_color_override("font_outline_color", Color(0.02, 0.01, 0.05, 0.9))
|
||||
fleet.spawn_ships(GameState.surviving_ship_count, Vector2.ZERO)
|
||||
camera.position = Vector2.ZERO
|
||||
camera.zoom = Vector2(GameState.return_camera_zoom, GameState.return_camera_zoom)
|
||||
|
|
|
|||
205
ResourceBar.gd
205
ResourceBar.gd
|
|
@ -1,146 +1,113 @@
|
|||
class_name ResourceBar
|
||||
extends Control
|
||||
|
||||
# The header every building menu now carries (#24): banked ore, what the
|
||||
# fleet is holding, and what THIS building has. Before this, each panel
|
||||
# improvised its own - the crafter spelled the same three figures into a
|
||||
# run-on StatusLabel string, the research screen printed a bank total inside
|
||||
# a button caption - so the same numbers looked different in every room.
|
||||
#
|
||||
# Three columns rather than a sentence, because the point of the bar is that
|
||||
# a figure stays in the same place as the player moves between menus.
|
||||
#
|
||||
# Reads GameState directly every frame, like ResourceCounter and CargoCounter
|
||||
# do, so it stays correct across the space <-> planet-surface scene swap with
|
||||
# nobody having to push updates into it. Only `building_id` is pushed in,
|
||||
# because "here" is the one thing the bar cannot work out for itself.
|
||||
# Compact resource table shared by crafting, research and the ship lab.
|
||||
# Rows are resources; columns are locations. Adding another material to
|
||||
# GameState.RESOURCE_TYPES automatically gives it a row here.
|
||||
|
||||
# Which building the HERE column is reporting. 0 means none, which greys the
|
||||
# column rather than showing a confident zero.
|
||||
var building_id: int = 0
|
||||
|
||||
# The caption box has to be a full line tall, not just the font size: a Label
|
||||
# renders its line height, not its point size, and the first version sat the
|
||||
# digits 26px down from the top straight through the middle of the caption.
|
||||
const CAPTION_HEIGHT: float = 34.0
|
||||
const CAPTION_GAP: float = 4.0
|
||||
const CAPTION_FONT_SIZE: int = 24
|
||||
const DIGIT_HEIGHT: float = 34.0
|
||||
|
||||
# Bank keeps NeonNumber's own ore-teal, and the hold keeps the amber
|
||||
# CargoCounter established for ore in transit. Only HERE needed a new colour;
|
||||
# it borrows the mothership's green, which already reads as "landed
|
||||
# somewhere and staying there" everywhere else in the game.
|
||||
const BANK_GLOW: Color = Color(0.0, 0.62, 0.7)
|
||||
const BANK_CORE: Color = Color(0.0, 0.12, 0.15)
|
||||
const HOLD_GLOW: Color = Color(1.0, 0.78, 0.25)
|
||||
const HOLD_CORE: Color = Color(0.22, 0.12, 0.0)
|
||||
const HERE_GLOW: Color = Color(0.45, 0.9, 0.55)
|
||||
const HERE_CORE: Color = Color(0.05, 0.16, 0.08)
|
||||
const HEADER_HEIGHT: float = 22.0
|
||||
const RULE_COLOR: Color = Color(0.25, 0.55, 0.7)
|
||||
const FLEET_COLOR: Color = Color(1.0, 0.78, 0.25)
|
||||
const LOCAL_COLOR: Color = Color(0.45, 0.9, 0.55)
|
||||
|
||||
var _numbers: Array[NeonNumber] = []
|
||||
var _captions: Array[Label] = []
|
||||
var _gas_caption: Label
|
||||
var _gas_icon: IconButton
|
||||
var _summary: Label
|
||||
var _header_labels: Array[Label] = []
|
||||
var _rows: Dictionary = {}
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
var columns: Array = [
|
||||
["BANK", BANK_GLOW, BANK_CORE],
|
||||
["HOLD", HOLD_GLOW, HOLD_CORE],
|
||||
["HERE", HERE_GLOW, HERE_CORE],
|
||||
]
|
||||
for column in columns:
|
||||
var caption: Label = Label.new()
|
||||
caption.text = column[0]
|
||||
caption.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
caption.add_theme_font_size_override("font_size", CAPTION_FONT_SIZE)
|
||||
caption.add_theme_color_override("font_color", column[1])
|
||||
add_child(caption)
|
||||
_captions.append(caption)
|
||||
for heading in ["", "BANKED", "FLEET", "LOCAL"]:
|
||||
var label := _make_label(heading, 16, Color(0.62, 0.78, 0.86))
|
||||
label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
add_child(label)
|
||||
_header_labels.append(label)
|
||||
|
||||
var number: NeonNumber = NeonNumber.new()
|
||||
number.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
number.glow_color = column[1]
|
||||
number.core_color = column[2]
|
||||
number.digit_height = DIGIT_HEIGHT
|
||||
add_child(number)
|
||||
_numbers.append(number)
|
||||
for resource_type in GameState.RESOURCE_TYPES:
|
||||
var glyph := ResourceGlyph.new()
|
||||
glyph.resource_type = resource_type
|
||||
add_child(glyph)
|
||||
var name_label := _make_label(GameState.resource_name(resource_type).to_upper(), 18,
|
||||
GameState.resource_color(resource_type))
|
||||
add_child(name_label)
|
||||
var bank_label := _make_value_label(GameState.resource_color(resource_type))
|
||||
var fleet_label := _make_value_label(FLEET_COLOR)
|
||||
var local_label := _make_value_label(LOCAL_COLOR)
|
||||
for label in [bank_label, fleet_label, local_label]:
|
||||
add_child(label)
|
||||
_rows[resource_type] = {
|
||||
"glyph": glyph, "name": name_label, "bank": bank_label,
|
||||
"fleet": fleet_label, "local": local_label,
|
||||
}
|
||||
|
||||
_layout()
|
||||
resized.connect(_layout)
|
||||
_gas_caption = Label.new()
|
||||
_gas_caption.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
_gas_caption.add_theme_font_size_override("font_size", 20)
|
||||
_gas_caption.add_theme_color_override("font_color", Color(0.85, 0.52, 1.0))
|
||||
add_child(_gas_caption)
|
||||
_gas_icon = IconButton.new()
|
||||
_gas_icon.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
_gas_icon.icon = IconButton.Icon.GAS
|
||||
_gas_icon.glow_color = Color(0.85, 0.52, 1.0)
|
||||
add_child(_gas_icon)
|
||||
_summary = Label.new()
|
||||
_summary.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
_summary.add_theme_font_size_override("font_size", 18)
|
||||
_summary.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
_summary.size = size
|
||||
add_child(_summary)
|
||||
_layout()
|
||||
queue_redraw()
|
||||
|
||||
|
||||
func _make_label(text_value: String, font_size: int, colour: Color) -> Label:
|
||||
var label := Label.new()
|
||||
label.text = text_value
|
||||
label.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
label.add_theme_font_size_override("font_size", font_size)
|
||||
label.add_theme_color_override("font_color", colour)
|
||||
label.add_theme_color_override("font_outline_color", Color(0.01, 0.01, 0.035, 0.95))
|
||||
label.add_theme_constant_override("outline_size", 2)
|
||||
label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
||||
return label
|
||||
|
||||
|
||||
func _make_value_label(colour: Color) -> Label:
|
||||
var label := _make_label("0", 19, colour)
|
||||
label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
return label
|
||||
|
||||
|
||||
func _layout() -> void:
|
||||
var column_width: float = size.x / float(_numbers.size())
|
||||
for i in _numbers.size():
|
||||
var x: float = column_width * float(i)
|
||||
_captions[i].position = Vector2(x, 0.0)
|
||||
_captions[i].size = Vector2(column_width, CAPTION_HEIGHT)
|
||||
# The hexagon and digits are drawn from the node's own origin, so the
|
||||
# number is positioned rather than sized.
|
||||
_numbers[i].position = Vector2(x, CAPTION_HEIGHT + CAPTION_GAP)
|
||||
if _gas_caption != null:
|
||||
_gas_caption.position = Vector2(size.x - 110.0, 2.0)
|
||||
_gas_caption.size = Vector2(106.0, CAPTION_HEIGHT)
|
||||
_gas_caption.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT
|
||||
if _gas_icon != null:
|
||||
_gas_icon.position = Vector2(size.x - 34.0, 0.0)
|
||||
_gas_icon.size = Vector2(32.0, 32.0)
|
||||
_gas_caption.size.x = maxf(0.0, _gas_caption.size.x - 36.0)
|
||||
if _header_labels.is_empty():
|
||||
return
|
||||
var resource_width: float = size.x * 0.25
|
||||
var value_width: float = (size.x - resource_width) / 3.0
|
||||
var columns: Array = [0.0, resource_width, resource_width + value_width,
|
||||
resource_width + value_width * 2.0]
|
||||
var widths: Array = [resource_width, value_width, value_width, value_width]
|
||||
for i in range(_header_labels.size()):
|
||||
_header_labels[i].position = Vector2(columns[i], 0.0)
|
||||
_header_labels[i].size = Vector2(widths[i], HEADER_HEIGHT)
|
||||
|
||||
var row_height: float = (size.y - HEADER_HEIGHT - 4.0) / maxf(1.0, float(_rows.size()))
|
||||
var row_index: int = 0
|
||||
for resource_type in GameState.RESOURCE_TYPES:
|
||||
var row: Dictionary = _rows[resource_type]
|
||||
var y: float = HEADER_HEIGHT + float(row_index) * row_height
|
||||
row.glyph.position = Vector2(2.0, y + 2.0)
|
||||
row.glyph.size = Vector2(row_height - 4.0, row_height - 4.0)
|
||||
row.name.position = Vector2(row_height, y)
|
||||
row.name.size = Vector2(resource_width - row_height, row_height)
|
||||
for i in range(3):
|
||||
var label: Label = row[["bank", "fleet", "local"][i]]
|
||||
label.position = Vector2(columns[i + 1], y)
|
||||
label.size = Vector2(widths[i + 1], row_height)
|
||||
row_index += 1
|
||||
queue_redraw()
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
# Resource rows scale without inventing a new menu per resource. The old
|
||||
# ore-only columns remain behind this concise, explicit summary.
|
||||
_summary.text = "ORE Bank %d Fleet %d Local %d\nGAS Bank %d Fleet %d Local %d" % [GameState.rocks, GameState.fleet_cargo, GameState.building_holdings(building_id), GameState.gas, GameState.fleet_gas_cargo, GameState.building_gas_holdings(building_id)]
|
||||
for number in _numbers: number.visible = false
|
||||
for caption in _captions: caption.visible = false
|
||||
_gas_caption.visible = false
|
||||
_gas_icon.visible = false
|
||||
_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[1].set_amount(GameState.fleet_cargo)
|
||||
|
||||
# A building with no id is not a building: showing "0" there would claim
|
||||
# the store is empty rather than that there is no store to look at.
|
||||
var known: bool = building_id != 0
|
||||
_numbers[2].visible = known
|
||||
_captions[2].visible = known
|
||||
if known:
|
||||
_numbers[2].set_amount(GameState.building_holdings(building_id))
|
||||
for resource_type in GameState.RESOURCE_TYPES:
|
||||
var row: Dictionary = _rows.get(resource_type, {})
|
||||
if row.is_empty():
|
||||
continue
|
||||
row.bank.text = str(GameState.banked_resource(resource_type))
|
||||
row.fleet.text = str(GameState.fleet_resource(resource_type))
|
||||
row.local.text = str(GameState.building_resource(building_id, resource_type)) \
|
||||
if building_id != 0 else "—"
|
||||
|
||||
|
||||
# The height the bar needs for a caption line and a row of digits. The scene
|
||||
# sizes the node, so this is what those offsets have to add up to; anything
|
||||
# less and the rule is drawn back through the digits.
|
||||
static func natural_height() -> float:
|
||||
return CAPTION_HEIGHT + CAPTION_GAP + DIGIT_HEIGHT + 8.0
|
||||
return 84.0
|
||||
|
||||
|
||||
func _draw() -> void:
|
||||
# One rule under the whole bar, so the header reads as a band separating
|
||||
# the standing figures from whatever the panel below them does.
|
||||
var rule_y: float = maxf(size.y, natural_height())
|
||||
NeonDraw.draw_glowing_line(
|
||||
self, Vector2(0.0, rule_y), Vector2(size.x, rule_y), RULE_COLOR, 0.55, 1.0
|
||||
)
|
||||
NeonDraw.draw_glowing_line(self, Vector2(0.0, size.y), Vector2(size.x, size.y),
|
||||
RULE_COLOR, 0.55, 1.0)
|
||||
|
|
|
|||
54
ResourceGlyph.gd
Normal file
54
ResourceGlyph.gd
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
class_name ResourceGlyph
|
||||
extends Control
|
||||
|
||||
# A small, non-interactive resource mark shared by tables and transfer rows.
|
||||
# Resource buttons used to borrow IconButton, which made decorative icons
|
||||
# look tappable and encouraged each screen to invent its own version.
|
||||
|
||||
@export var resource_type: String = GameState.RESOURCE_ORE: set = set_resource_type
|
||||
|
||||
|
||||
func set_resource_type(value: String) -> void:
|
||||
if resource_type == value:
|
||||
return
|
||||
resource_type = value
|
||||
queue_redraw()
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
queue_redraw()
|
||||
|
||||
|
||||
func _draw() -> void:
|
||||
var colour: Color = GameState.resource_color(resource_type)
|
||||
var centre: Vector2 = size * 0.5
|
||||
var radius: float = minf(size.x, size.y) * 0.34
|
||||
match resource_type:
|
||||
GameState.RESOURCE_GAS:
|
||||
_draw_gas(centre, radius, colour)
|
||||
_:
|
||||
_draw_ore(centre, radius, colour)
|
||||
|
||||
|
||||
func _draw_ore(centre: Vector2, radius: float, colour: Color) -> void:
|
||||
var points := PackedVector2Array()
|
||||
for i in range(6):
|
||||
var angle: float = TAU * float(i) / 6.0 - PI * 0.5
|
||||
points.append(centre + Vector2(cos(angle), sin(angle)) * radius)
|
||||
NeonDraw.draw_glowing_polygon(self, points, colour, 1.0, colour.darkened(0.78), maxf(0.5, radius * 0.035))
|
||||
NeonDraw.draw_glowing_line(self, points[5], points[2], colour, 0.55, maxf(0.4, radius * 0.025), colour.darkened(0.78))
|
||||
|
||||
|
||||
func _draw_gas(centre: Vector2, radius: float, colour: Color) -> void:
|
||||
var bubbles: Array = [
|
||||
[centre + Vector2(-radius * 0.38, radius * 0.12), radius * 0.46],
|
||||
[centre + Vector2(radius * 0.34, radius * 0.26), radius * 0.58],
|
||||
[centre + Vector2(radius * 0.38, -radius * 0.48), radius * 0.32],
|
||||
]
|
||||
for bubble in bubbles:
|
||||
var ring := PackedVector2Array()
|
||||
for i in range(12):
|
||||
var angle: float = TAU * float(i) / 12.0
|
||||
ring.append(bubble[0] + Vector2(cos(angle), sin(angle)) * float(bubble[1]))
|
||||
NeonDraw.draw_glowing_polygon(self, ring, colour, 1.0, colour.darkened(0.78), maxf(0.5, radius * 0.035))
|
||||
161
ResourceTransferList.gd
Normal file
161
ResourceTransferList.gd
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
class_name ResourceTransferList
|
||||
extends Control
|
||||
|
||||
# Two-sided cargo control. Resources are rows and locations stay fixed:
|
||||
# fleet on the left, the current building on the right. Horizontal arrows
|
||||
# make the result of a press visible before the player commits to it.
|
||||
|
||||
signal transfer_requested(resource_type: String, to_building: bool)
|
||||
|
||||
const HEADER_HEIGHT: float = 58.0
|
||||
const FLEET_COLOR: Color = Color(1.0, 0.78, 0.25)
|
||||
const LOCAL_COLOR: Color = Color(0.45, 0.9, 0.55)
|
||||
const RULE_COLOR: Color = Color(0.18, 0.38, 0.52)
|
||||
|
||||
var building_id: int = 0
|
||||
var _destination_heading: Label
|
||||
var _rows: Dictionary = {}
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
var fleet_heading := _make_label("FLEET HOLD", 22, FLEET_COLOR)
|
||||
fleet_heading.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
add_child(fleet_heading)
|
||||
_destination_heading = _make_label("THIS BUILDING", 22, LOCAL_COLOR)
|
||||
_destination_heading.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
add_child(_destination_heading)
|
||||
|
||||
for resource_type in GameState.RESOURCE_TYPES:
|
||||
var colour: Color = GameState.resource_color(resource_type)
|
||||
var glyph := ResourceGlyph.new()
|
||||
glyph.resource_type = resource_type
|
||||
add_child(glyph)
|
||||
var name_label := _make_label(GameState.resource_name(resource_type).to_upper(), 25, colour)
|
||||
name_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
add_child(name_label)
|
||||
var fleet_amount := _make_label("0", 42, FLEET_COLOR)
|
||||
fleet_amount.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
add_child(fleet_amount)
|
||||
var local_amount := _make_label("0", 42, LOCAL_COLOR)
|
||||
local_amount.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
add_child(local_amount)
|
||||
|
||||
var unload := IconButton.new()
|
||||
unload.name = "%sToBuildingButton" % GameState.resource_name(resource_type)
|
||||
unload.icon = IconButton.Icon.RIGHT_ARROW
|
||||
unload.glow_color = colour
|
||||
unload.pressed.connect(_request_transfer.bind(resource_type, true))
|
||||
add_child(unload)
|
||||
var unload_label := _make_label("UNLOAD ALL →", 20, colour)
|
||||
unload_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
add_child(unload_label)
|
||||
|
||||
var load := IconButton.new()
|
||||
load.name = "%sToFleetButton" % GameState.resource_name(resource_type)
|
||||
load.icon = IconButton.Icon.LEFT_ARROW
|
||||
load.glow_color = colour
|
||||
load.pressed.connect(_request_transfer.bind(resource_type, false))
|
||||
add_child(load)
|
||||
var load_label := _make_label("← LOAD ALL", 20, colour)
|
||||
load_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
add_child(load_label)
|
||||
|
||||
_rows[resource_type] = {
|
||||
"glyph": glyph, "name": name_label,
|
||||
"fleet_amount": fleet_amount, "local_amount": local_amount,
|
||||
"unload": unload, "unload_label": unload_label,
|
||||
"load": load, "load_label": load_label,
|
||||
}
|
||||
|
||||
resized.connect(_layout)
|
||||
_layout()
|
||||
refresh()
|
||||
|
||||
|
||||
func _make_label(text_value: String, font_size: int, colour: Color) -> Label:
|
||||
var label := Label.new()
|
||||
label.text = text_value
|
||||
label.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
label.add_theme_font_size_override("font_size", font_size)
|
||||
label.add_theme_color_override("font_color", colour)
|
||||
label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
||||
return label
|
||||
|
||||
|
||||
func _request_transfer(resource_type: String, to_building: bool) -> void:
|
||||
transfer_requested.emit(resource_type, to_building)
|
||||
|
||||
|
||||
func set_destination(id: int, heading: String) -> void:
|
||||
building_id = id
|
||||
if _destination_heading != null:
|
||||
_destination_heading.text = heading.to_upper()
|
||||
refresh()
|
||||
|
||||
|
||||
func refresh() -> void:
|
||||
for resource_type in GameState.RESOURCE_TYPES:
|
||||
var row: Dictionary = _rows.get(resource_type, {})
|
||||
if row.is_empty():
|
||||
continue
|
||||
var fleet_amount: int = GameState.fleet_resource(resource_type)
|
||||
var local_amount: int = GameState.building_resource(building_id, resource_type)
|
||||
row.fleet_amount.text = str(fleet_amount)
|
||||
row.local_amount.text = str(local_amount)
|
||||
row.unload.enabled = fleet_amount > 0
|
||||
row.load.enabled = local_amount > 0
|
||||
row.unload.queue_redraw()
|
||||
row.load.queue_redraw()
|
||||
|
||||
|
||||
func _layout() -> void:
|
||||
if _destination_heading == null:
|
||||
return
|
||||
var side_width: float = size.x * 0.36
|
||||
var centre_width: float = size.x - side_width * 2.0
|
||||
var right_x: float = side_width + centre_width
|
||||
var fleet_heading: Label = get_child(0)
|
||||
fleet_heading.position = Vector2(0.0, 0.0)
|
||||
fleet_heading.size = Vector2(side_width, HEADER_HEIGHT)
|
||||
_destination_heading.position = Vector2(right_x, 0.0)
|
||||
_destination_heading.size = Vector2(side_width, HEADER_HEIGHT)
|
||||
|
||||
var row_height: float = (size.y - HEADER_HEIGHT) / maxf(1.0, float(_rows.size()))
|
||||
var row_index: int = 0
|
||||
for resource_type in GameState.RESOURCE_TYPES:
|
||||
var row: Dictionary = _rows[resource_type]
|
||||
var y: float = HEADER_HEIGHT + float(row_index) * row_height
|
||||
var glyph_size: float = minf(58.0, row_height * 0.22)
|
||||
row.glyph.position = Vector2(size.x * 0.5 - glyph_size * 0.5, y + 12.0)
|
||||
row.glyph.size = Vector2(glyph_size, glyph_size)
|
||||
row.name.position = Vector2(side_width, y + 12.0 + glyph_size)
|
||||
row.name.size = Vector2(centre_width, 38.0)
|
||||
|
||||
row.fleet_amount.position = Vector2(0.0, y + 12.0)
|
||||
row.fleet_amount.size = Vector2(side_width, 62.0)
|
||||
row.local_amount.position = Vector2(right_x, y + 12.0)
|
||||
row.local_amount.size = Vector2(side_width, 62.0)
|
||||
|
||||
var button_size: float = minf(118.0, row_height * 0.42)
|
||||
var button_y: float = y + 78.0
|
||||
row.unload.position = Vector2(side_width * 0.5 - button_size * 0.5, button_y)
|
||||
row.unload.size = Vector2(button_size, button_size)
|
||||
row.load.position = Vector2(right_x + side_width * 0.5 - button_size * 0.5, button_y)
|
||||
row.load.size = Vector2(button_size, button_size)
|
||||
var caption_y: float = button_y + button_size + 2.0
|
||||
row.unload_label.position = Vector2(0.0, caption_y)
|
||||
row.unload_label.size = Vector2(side_width, 36.0)
|
||||
row.load_label.position = Vector2(right_x, caption_y)
|
||||
row.load_label.size = Vector2(side_width, 36.0)
|
||||
row_index += 1
|
||||
queue_redraw()
|
||||
|
||||
|
||||
func _draw() -> void:
|
||||
var row_height: float = (size.y - HEADER_HEIGHT) / maxf(1.0, float(_rows.size()))
|
||||
NeonDraw.draw_glowing_line(self, Vector2(0.0, HEADER_HEIGHT), Vector2(size.x, HEADER_HEIGHT),
|
||||
RULE_COLOR, 0.5, 0.7)
|
||||
for i in range(1, _rows.size()):
|
||||
var y: float = HEADER_HEIGHT + float(i) * row_height
|
||||
NeonDraw.draw_glowing_line(self, Vector2(0.0, y), Vector2(size.x, y),
|
||||
RULE_COLOR, 0.4, 0.6)
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
extends Node2D
|
||||
|
||||
# Preview, not a test. The resource readouts with the fleet carrying ore, so
|
||||
# the #15 banked-vs-carried split can actually be looked at - headless draws
|
||||
# no pixels and cannot say whether two numbers read as two different things.
|
||||
# Preview, not a test. Both banked resources and both fleet-held resources
|
||||
# are populated so the complete two-column HUD can be inspected.
|
||||
#
|
||||
# bash tests/screenshot.sh res://tests/_cargo_readout_preview.tscn /tmp/hud.png 20 720x1280
|
||||
|
||||
|
|
@ -11,5 +10,7 @@ func _ready() -> void:
|
|||
GameState.buildings.clear()
|
||||
GameState.extractors.clear()
|
||||
GameState.rocks = 128
|
||||
GameState.gas = 46
|
||||
GameState.fleet_cargo = 34
|
||||
GameState.fleet_gas_cargo = 17
|
||||
add_child(load("res://Main.tscn").instantiate())
|
||||
|
|
|
|||
|
|
@ -13,13 +13,16 @@ func _ready() -> void:
|
|||
GameState.extractors.clear()
|
||||
GameState.transporters.clear()
|
||||
GameState.rocks = 180
|
||||
GameState.gas = 36
|
||||
GameState.fleet_cargo = 24
|
||||
GameState.fleet_gas_cargo = 12
|
||||
GameState.unlocked = ["shipyards", "logistics", "freight"]
|
||||
var main: Node = load("res://Main.tscn").instantiate()
|
||||
add_child(main)
|
||||
main.get_node("BuildingField").place(GameState.BUILDING_SHIP_CRAFTER, Vector2(400.0, 0.0))
|
||||
var crafter_id: int = int(GameState.buildings[-1].id)
|
||||
GameState.deposit_to_building(crafter_id, 42)
|
||||
GameState.find_building(crafter_id).gas_stock = 18
|
||||
var bc: Node = main.get_node("BuildController")
|
||||
bc.craft_building_id = crafter_id
|
||||
# The shared header (#24) is the thing worth eyeballing here, so give it
|
||||
|
|
|
|||
14
tests/_gas_surface_preview.gd
Normal file
14
tests/_gas_surface_preview.gd
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
extends Node2D
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
GameState.planet_name = "Violet Tempest"
|
||||
GameState.planet_type = "gas_giant"
|
||||
GameState.surviving_ship_count = 3
|
||||
GameState.rocks = 128
|
||||
GameState.gas = 46
|
||||
GameState.fleet_cargo = 34
|
||||
GameState.fleet_gas_cargo = 17
|
||||
var surface: Node = load("res://PlanetSurface.tscn").instantiate()
|
||||
surface.get_node("SurfaceController").fade_duration = 0.0
|
||||
add_child(surface)
|
||||
6
tests/_gas_surface_preview.tscn
Normal file
6
tests/_gas_surface_preview.tscn
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[gd_scene load_steps=2 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://tests/_gas_surface_preview.gd" id="1"]
|
||||
|
||||
[node name="GasSurfacePreview" type="Node2D"]
|
||||
script = ExtResource("1")
|
||||
|
|
@ -13,7 +13,9 @@ func _ready() -> void:
|
|||
GameState.extractors.clear()
|
||||
GameState.transporters.clear()
|
||||
GameState.rocks = 180
|
||||
GameState.gas = 36
|
||||
GameState.fleet_cargo = 24
|
||||
GameState.fleet_gas_cargo = 12
|
||||
GameState.unlocked = ["shipyards", "logistics", "freight"]
|
||||
var main: Node = load("res://Main.tscn").instantiate()
|
||||
add_child(main)
|
||||
|
|
|
|||
|
|
@ -28,18 +28,15 @@ WAIT_FRAMES="${3:-60}"
|
|||
RESOLUTION="${4:-1280x720}"
|
||||
|
||||
proot-distro login ubuntu -- bash -c "
|
||||
# A killed run (or a session that ended mid-screenshot) leaves /tmp/.X99-lock
|
||||
# behind, and Xvfb then refuses to claim :99 - which surfaces much later and
|
||||
# far less obviously as Godot's 'X11 Display is not available'. Nothing else
|
||||
# uses :99 here, so a lock with no live Xvfb behind it is always stale.
|
||||
if ! pgrep -x Xvfb >/dev/null; then
|
||||
rm -f /tmp/.X99-lock /tmp/.X11-unix/X99
|
||||
fi
|
||||
# Display :99 is dedicated to this helper. Clear both a live process left by
|
||||
# an interrupted capture and its lock/socket before claiming it again.
|
||||
pkill -x Xvfb >/dev/null 2>&1 || true
|
||||
rm -f /tmp/.X99-lock /tmp/.X11-unix/X99
|
||||
Xvfb :99 -screen 0 ${RESOLUTION}x24 &
|
||||
XVFB_PID=\$!
|
||||
trap 'kill \$XVFB_PID >/dev/null 2>&1 || true' EXIT
|
||||
sleep 2
|
||||
mkdir -p /tmp/xdgrt && chmod 700 /tmp/xdgrt
|
||||
cd '$PROJECT_DIR'
|
||||
DISPLAY=:99 XDG_RUNTIME_DIR=/tmp/xdgrt GALLIUM_DRIVER=softpipe '$GODOT_BIN' --rendering-driver opengl3 --rendering-method gl_compatibility --resolution '$RESOLUTION' -s res://tests/_screenshot_tool.gd -- '$SCENE_PATH' '$OUTPUT_PATH' '$WAIT_FRAMES'
|
||||
kill \$XVFB_PID
|
||||
DISPLAY=:99 XDG_RUNTIME_DIR=/tmp/xdgrt GALLIUM_DRIVER=softpipe '$GODOT_BIN' --audio-driver Dummy --rendering-driver opengl3 --rendering-method gl_compatibility --resolution '$RESOLUTION' -s res://tests/_screenshot_tool.gd -- '$SCENE_PATH' '$OUTPUT_PATH' '$WAIT_FRAMES'
|
||||
"
|
||||
|
|
|
|||
|
|
@ -96,7 +96,10 @@ func _process(delta: float) -> bool:
|
|||
print("TEST_CRAFTER_FEEDBACK: FAIL (fleet parked on the crafter never registered)")
|
||||
quit(1)
|
||||
return true
|
||||
# A crafter now has both Craft and Transfer, so the shared action
|
||||
# button unfolds those choices before the craft action is selected.
|
||||
_tap(controller.action_button)
|
||||
_tap(controller.building_action_button)
|
||||
if not controller.craft_menu.visible:
|
||||
print("TEST_CRAFTER_FEEDBACK: FAIL (the action button did not open the crafter panel)")
|
||||
quit(1)
|
||||
|
|
|
|||
|
|
@ -162,8 +162,11 @@ func _process(delta: float) -> bool:
|
|||
stage = 6
|
||||
return false
|
||||
6:
|
||||
# Long enough for the build itself, which #23 made take time.
|
||||
if elapsed < game_state.build_time(GameState.PRODUCT_SHIP) * 3.0:
|
||||
# Long enough for both construction and the physical delivery trip
|
||||
# from this remote crafter to the mothership hangar.
|
||||
var delivery_time: float = CRAFTER_AT.distance_to(MOTHERSHIP_AT) \
|
||||
/ GameState.VESSEL_DELIVERY_SPEED
|
||||
if elapsed < game_state.build_time(GameState.PRODUCT_SHIP) * 3.0 + delivery_time + 0.5:
|
||||
return false
|
||||
# --- 5. the queued order completed off the fleet's own ore ---
|
||||
if game_state.pending_orders(crafter_id) != 0:
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ func _process(delta: float) -> bool:
|
|||
# The handler working while the BUTTON is inert is the exact bug
|
||||
# class this project keeps hitting, so one press goes the long way.
|
||||
var bank_at_tap: int = game_state.rocks
|
||||
_tap(scene.get_node("UI/TransferMenu/ToFleetAllButton"))
|
||||
_tap(scene.get_node("UI/TransferMenu/ResourceList/OreToFleetButton"))
|
||||
_expect(game_state.fleet_cargo == bank_at_tap,
|
||||
"a real tap did not load all banked ore")
|
||||
_expect(game_state.rocks == 0,
|
||||
|
|
|
|||
Loading…
Reference in a new issue