Improve ship crafter and hangar controls
This commit is contained in:
parent
82552464d2
commit
06081c41b0
4 changed files with 348 additions and 56 deletions
|
|
@ -49,14 +49,28 @@ extends Node2D
|
|||
@onready var queue_detail: Label = get_node("../UI/CraftMenu/QueueDetail")
|
||||
@onready var hangar_button: IconButton = get_node("../UI/HangarButton")
|
||||
@onready var hangar_menu: Control = get_node("../UI/HangarMenu")
|
||||
@onready var hangar_list: Label = get_node("../UI/HangarMenu/ListLabel")
|
||||
@onready var hangar_status: Label = get_node("../UI/HangarMenu/StatusLabel")
|
||||
@onready var hangar_next_button: IconButton = get_node("../UI/HangarMenu/NextButton")
|
||||
@onready var hangar_crew_button: IconButton = get_node("../UI/HangarMenu/CrewButton")
|
||||
@onready var hangar_close_button: IconButton = get_node("../UI/HangarMenu/CloseButton")
|
||||
|
||||
# Which stored vessel the hangar is offering to crew.
|
||||
var hangar_choice: int = 0
|
||||
@onready var hangar_available_slots: Array = [
|
||||
get_node("../UI/HangarMenu/AvailableInterceptor"),
|
||||
get_node("../UI/HangarMenu/AvailableShield"),
|
||||
get_node("../UI/HangarMenu/AvailableTransporter"),
|
||||
]
|
||||
@onready var hangar_available_labels: Array = [
|
||||
get_node("../UI/HangarMenu/AvailableInterceptorLabel"),
|
||||
get_node("../UI/HangarMenu/AvailableShieldLabel"),
|
||||
get_node("../UI/HangarMenu/AvailableTransporterLabel"),
|
||||
]
|
||||
@onready var hangar_fleet_slots: Array = [
|
||||
get_node("../UI/HangarMenu/FleetInterceptor"),
|
||||
get_node("../UI/HangarMenu/FleetShield"),
|
||||
get_node("../UI/HangarMenu/FleetTransporter"),
|
||||
]
|
||||
@onready var hangar_fleet_labels: Array = [
|
||||
get_node("../UI/HangarMenu/FleetInterceptorLabel"),
|
||||
get_node("../UI/HangarMenu/FleetShieldLabel"),
|
||||
get_node("../UI/HangarMenu/FleetTransporterLabel"),
|
||||
]
|
||||
@onready var build_menu_entries: Array = [
|
||||
[GameState.BUILDING_MOTHERSHIP, build_mothership_button,
|
||||
get_node("../UI/BuildMenu/MothershipLabel"), get_node("../UI/BuildMenu/MothershipCost")],
|
||||
|
|
@ -91,6 +105,9 @@ var lab_choice: int = 0
|
|||
@onready var craft_transporter_button: IconButton = get_node("../UI/CraftMenu/TransporterButton")
|
||||
@onready var craft_close_button: IconButton = get_node("../UI/CraftMenu/CloseButton")
|
||||
@onready var craft_status: Label = get_node("../UI/CraftMenu/StatusLabel")
|
||||
@onready var craft_interceptor_label: Label = get_node("../UI/CraftMenu/InterceptorLabel")
|
||||
@onready var craft_transporter_label: Label = get_node("../UI/CraftMenu/TransporterLabel")
|
||||
@onready var craft_shield_label: Label = get_node("../UI/CraftMenu/ShieldLabel")
|
||||
|
||||
# --- the transfer panel (#24) ---------------------------------------------
|
||||
# Ore used to be moved from inside whichever panel happened to be open: "load
|
||||
|
|
@ -216,8 +233,9 @@ func _ready() -> void:
|
|||
transfer_button.pressed.connect(_on_transfer_pressed)
|
||||
hangar_button.pressed.connect(_on_hangar_pressed)
|
||||
hangar_close_button.pressed.connect(func(): hangar_menu.visible = false)
|
||||
hangar_next_button.pressed.connect(_on_hangar_next)
|
||||
hangar_crew_button.pressed.connect(_on_hangar_crew)
|
||||
for i in range(hangar_available_slots.size()):
|
||||
hangar_available_slots[i].pressed.connect(_on_hangar_crew_type.bind(i))
|
||||
hangar_fleet_slots[i].pressed.connect(_on_hangar_store_type.bind(i))
|
||||
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)
|
||||
|
|
@ -245,6 +263,7 @@ func _ready() -> void:
|
|||
transfer_button.visible = false
|
||||
hangar_button.visible = false
|
||||
hangar_menu.visible = false
|
||||
_layout_context_buttons()
|
||||
|
||||
|
||||
# True while a building prompt or panel owns the shared action slot, so the
|
||||
|
|
@ -340,6 +359,20 @@ func _process(delta: float) -> void:
|
|||
if current_building != null:
|
||||
action_button.icon = _action_icon_for(current_building.building_type)
|
||||
action_button.queue_redraw()
|
||||
_layout_context_buttons()
|
||||
|
||||
|
||||
func _layout_context_buttons() -> void:
|
||||
# Every contextual action uses a distinct, fixed berth above Build. This
|
||||
# replaces the old hand-picked offsets where Hangar overlapped Action at a
|
||||
# mothership (#25).
|
||||
var buttons: Array = [action_button, transfer_button]
|
||||
if hangar_button.visible:
|
||||
buttons.append(hangar_button)
|
||||
for i in range(buttons.size()):
|
||||
var button: Control = buttons[i]
|
||||
button.offset_top = -720 + i * 164
|
||||
button.offset_bottom = button.offset_top + 148
|
||||
|
||||
|
||||
func _action_icon_for(type: String) -> int:
|
||||
|
|
@ -672,16 +705,13 @@ func _say(message: String) -> void:
|
|||
|
||||
|
||||
func _refresh_craft_status() -> void:
|
||||
# The bank/hold/here figures moved out to the shared header (#24), so this
|
||||
# line is now only what is specific to a crafter: prices, the queue, and
|
||||
# berth pressure. It used to restate "Here %d" itself, which is exactly
|
||||
# the per-panel improvisation the header replaces.
|
||||
var queued: int = GameState.pending_orders(craft_building_id)
|
||||
var queue_text: String = "" if queued == 0 else " Queued %d" % queued
|
||||
craft_status.text = "Interceptor %d Transporter %d%s Transporters %d/%d" % [
|
||||
GameState.SHIP_COST, GameState.TRANSPORTER_COST, queue_text,
|
||||
GameState.transporters_claimed(), GameState.transport_capacity()
|
||||
]
|
||||
# Prices live with the buttons they describe. The top of the screen is
|
||||
# intentionally reserved for the shared resource bar and a short action
|
||||
# message; repeating fleet, queue and transport counts here buried the UI.
|
||||
craft_interceptor_label.text = "Interceptor\n%d ore" % GameState.SHIP_COST
|
||||
craft_transporter_label.text = "Transporter\n%d ore" % GameState.TRANSPORTER_COST
|
||||
craft_shield_label.text = "Shield Vessel\n%d ore" % GameState.SHIELD_COST
|
||||
craft_status.text = ""
|
||||
# Nowhere to station one means the order would be refused, so say so
|
||||
# rather than letting the button look available and do nothing.
|
||||
craft_transporter_button.enabled = GameState.has_transport_hub() \
|
||||
|
|
@ -698,11 +728,6 @@ func _refresh_craft_status() -> void:
|
|||
# where the fleet starts at exactly its cap.
|
||||
craft_interceptor_button.enabled = true
|
||||
craft_interceptor_button.queue_redraw()
|
||||
craft_status.text += " Fleet %d/%d Ready %d" % [
|
||||
fleet.ships.size(), GameState.max_fleet_size(), GameState.stored_vessels.size()
|
||||
]
|
||||
# LAST, so a message about what just happened is the first line the
|
||||
# player reads rather than being buried under the standing state.
|
||||
_refresh_queue()
|
||||
if craft_message != "":
|
||||
if Time.get_ticks_msec() < craft_message_until:
|
||||
|
|
@ -995,55 +1020,67 @@ func _on_queue_slot(index: int) -> void:
|
|||
# --- hangar (#23) ---------------------------------------------------------
|
||||
|
||||
func _on_hangar_pressed() -> void:
|
||||
hangar_choice = 0
|
||||
hangar_status.text = ""
|
||||
hangar_menu.visible = true
|
||||
_refresh_hangar()
|
||||
|
||||
|
||||
func _on_hangar_next() -> void:
|
||||
if GameState.stored_vessels.is_empty():
|
||||
return
|
||||
hangar_choice = (hangar_choice + 1) % GameState.stored_vessels.size()
|
||||
_refresh_hangar()
|
||||
|
||||
|
||||
func _on_hangar_crew() -> void:
|
||||
if GameState.stored_vessels.is_empty():
|
||||
hangar_status.text = "Nothing built yet - order vessels at a ship crafter"
|
||||
return
|
||||
func _on_hangar_crew_type(index: int) -> void:
|
||||
var type: String = _hangar_types()[index]
|
||||
if fleet.ships.size() >= GameState.max_fleet_size():
|
||||
hangar_status.text = "Fleet is full (%d/%d) - research capacity at the mothership" % [
|
||||
fleet.ships.size(), GameState.max_fleet_size()
|
||||
]
|
||||
return
|
||||
var product: String = GameState.claim_stored_vessel(hangar_choice)
|
||||
if product == "" or not fleet.add_ship(product):
|
||||
var stored_index: int = GameState.stored_vessels.find(type)
|
||||
if stored_index < 0:
|
||||
hangar_status.text = "No %s available" % GameState.VESSEL_NAMES.get(type, type)
|
||||
return
|
||||
if not fleet.add_ship(GameState.take_stored_vessel(stored_index)):
|
||||
hangar_status.text = "Could not crew that vessel"
|
||||
return
|
||||
GameState.take_stored_vessel(hangar_choice)
|
||||
hangar_status.text = "%s joined the fleet" % GameState.VESSEL_NAMES.get(product, product)
|
||||
hangar_choice = 0
|
||||
hangar_status.text = "%s joined the fleet" % GameState.VESSEL_NAMES.get(type, type)
|
||||
_refresh_hangar()
|
||||
|
||||
|
||||
func _on_hangar_store_type(index: int) -> void:
|
||||
var type: String = _hangar_types()[index]
|
||||
var ship_index: int = -1
|
||||
for i in range(fleet.ships.size()):
|
||||
if String(fleet.ships[i].vessel_type) == type:
|
||||
ship_index = i
|
||||
break
|
||||
if ship_index < 0:
|
||||
hangar_status.text = "No %s in the fleet" % GameState.VESSEL_NAMES.get(type, type)
|
||||
return
|
||||
var stored: String = fleet.store_ship(ship_index)
|
||||
if stored == "":
|
||||
hangar_status.text = "Keep one ship deployed"
|
||||
return
|
||||
GameState.stored_vessels.append(stored)
|
||||
hangar_status.text = "%s stored in the hangar" % GameState.VESSEL_NAMES.get(stored, stored)
|
||||
_refresh_hangar()
|
||||
|
||||
|
||||
func _hangar_types() -> Array:
|
||||
return [GameState.VESSEL_INTERCEPTOR, GameState.VESSEL_SHIELD, GameState.VESSEL_TRANSPORTER]
|
||||
|
||||
|
||||
func _refresh_hangar() -> void:
|
||||
var stored: Array = GameState.stored_vessels
|
||||
if stored.is_empty():
|
||||
hangar_list.text = "No vessels waiting.\n\nOrder them at a ship crafter - finished vessels are delivered here."
|
||||
hangar_crew_button.enabled = false
|
||||
hangar_next_button.enabled = false
|
||||
else:
|
||||
hangar_choice = clampi(hangar_choice, 0, stored.size() - 1)
|
||||
var lines: Array = []
|
||||
for i in range(stored.size()):
|
||||
var marker: String = ">" if i == hangar_choice else " "
|
||||
lines.append("%s %s" % [marker, GameState.VESSEL_NAMES.get(stored[i], stored[i])])
|
||||
hangar_list.text = "\n".join(lines)
|
||||
hangar_crew_button.enabled = fleet.ships.size() < GameState.max_fleet_size()
|
||||
hangar_next_button.enabled = stored.size() > 1
|
||||
hangar_crew_button.queue_redraw()
|
||||
hangar_next_button.queue_redraw()
|
||||
var types: Array = _hangar_types()
|
||||
for i in range(types.size()):
|
||||
var type: String = types[i]
|
||||
var available: int = GameState.stored_vessels.count(type)
|
||||
var deployed: int = 0
|
||||
for ship in fleet.ships:
|
||||
if is_instance_valid(ship) and String(ship.vessel_type) == type:
|
||||
deployed += 1
|
||||
hangar_available_labels[i].text = "%s\n%d available" % [GameState.VESSEL_NAMES.get(type, type), available]
|
||||
hangar_fleet_labels[i].text = "%s\n%d in fleet" % [GameState.VESSEL_NAMES.get(type, type), deployed]
|
||||
hangar_available_slots[i].enabled = available > 0 and fleet.ships.size() < GameState.max_fleet_size()
|
||||
hangar_fleet_slots[i].enabled = deployed > 0 and fleet.ships.size() > 1
|
||||
hangar_available_slots[i].queue_redraw()
|
||||
hangar_fleet_slots[i].queue_redraw()
|
||||
|
||||
|
||||
func _on_formation_changed() -> void:
|
||||
|
|
|
|||
17
Fleet.gd
17
Fleet.gd
|
|
@ -92,6 +92,23 @@ func add_ship(vessel_type: String = GameState.VESSEL_INTERCEPTOR) -> bool:
|
|||
return true
|
||||
|
||||
|
||||
func store_ship(index: int) -> String:
|
||||
# A fleet always keeps one ship deployed. Removing the last one would trip
|
||||
# the wiped-out-fleet safety net on the next frame and immediately spawn a
|
||||
# replacement, which is the opposite of storing it at the mothership.
|
||||
if ships.size() <= 1 or index < 0 or index >= ships.size():
|
||||
return ""
|
||||
var ship: Node = ships[index]
|
||||
if not is_instance_valid(ship):
|
||||
return ""
|
||||
var vessel_type: String = String(ship.vessel_type)
|
||||
ships.remove_at(index)
|
||||
formation_offsets.remove_at(index)
|
||||
ship.queue_free()
|
||||
apply_formation()
|
||||
return vessel_type
|
||||
|
||||
|
||||
func apply_formation() -> void:
|
||||
# Re-seats the EXISTING ships into the current GameState.formation.
|
||||
# Without this, editing the layout at a command centre (or pivoting it)
|
||||
|
|
|
|||
152
Main.tscn
152
Main.tscn
|
|
@ -665,6 +665,7 @@ text = "Hangar"
|
|||
horizontal_alignment = 1
|
||||
|
||||
[node name="ListLabel" type="Label" parent="UI/HangarMenu"]
|
||||
visible = false
|
||||
mouse_filter = 2
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
|
|
@ -692,6 +693,7 @@ horizontal_alignment = 1
|
|||
text = ""
|
||||
|
||||
[node name="NextButton" type="Control" parent="UI/HangarMenu"]
|
||||
visible = false
|
||||
anchor_left = 0.5
|
||||
anchor_top = 1.0
|
||||
anchor_right = 0.5
|
||||
|
|
@ -705,6 +707,7 @@ icon = 6
|
|||
glow_color = Color(0.55, 0.95, 0.9, 1)
|
||||
|
||||
[node name="CrewButton" type="Control" parent="UI/HangarMenu"]
|
||||
visible = false
|
||||
anchor_left = 0.5
|
||||
anchor_top = 1.0
|
||||
anchor_right = 0.5
|
||||
|
|
@ -718,6 +721,7 @@ icon = 2
|
|||
glow_color = Color(0.45, 0.9, 0.55, 1)
|
||||
|
||||
[node name="HintLabel" type="Label" parent="UI/HangarMenu"]
|
||||
visible = false
|
||||
mouse_filter = 2
|
||||
anchor_right = 1.0
|
||||
anchor_top = 1.0
|
||||
|
|
@ -731,6 +735,154 @@ autowrap_mode = 2
|
|||
horizontal_alignment = 1
|
||||
text = "Next Crew"
|
||||
|
||||
[node name="AvailableTitle" type="Label" parent="UI/HangarMenu"]
|
||||
mouse_filter = 2
|
||||
anchor_right = 1.0
|
||||
offset_top = 190
|
||||
offset_bottom = 240
|
||||
theme_override_font_sizes/font_size = 28
|
||||
text = "AVAILABLE — TAP TO CREW"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="AvailableInterceptor" type="Control" parent="UI/HangarMenu"]
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -250
|
||||
offset_right = -130
|
||||
offset_top = 255
|
||||
offset_bottom = 375
|
||||
script = ExtResource("10")
|
||||
icon = 2
|
||||
|
||||
[node name="AvailableInterceptorLabel" type="Label" parent="UI/HangarMenu"]
|
||||
mouse_filter = 2
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -300
|
||||
offset_right = -80
|
||||
offset_top = 380
|
||||
offset_bottom = 460
|
||||
theme_override_font_sizes/font_size = 22
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="AvailableShield" type="Control" parent="UI/HangarMenu"]
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -60
|
||||
offset_right = 60
|
||||
offset_top = 255
|
||||
offset_bottom = 375
|
||||
script = ExtResource("10")
|
||||
icon = 2
|
||||
glow_color = Color(0.45, 0.8, 1, 1)
|
||||
|
||||
[node name="AvailableShieldLabel" type="Label" parent="UI/HangarMenu"]
|
||||
mouse_filter = 2
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -110
|
||||
offset_right = 110
|
||||
offset_top = 380
|
||||
offset_bottom = 460
|
||||
theme_override_font_sizes/font_size = 22
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="AvailableTransporter" type="Control" parent="UI/HangarMenu"]
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = 130
|
||||
offset_right = 250
|
||||
offset_top = 255
|
||||
offset_bottom = 375
|
||||
script = ExtResource("10")
|
||||
icon = 12
|
||||
glow_color = Color(0.95, 0.55, 0.85, 1)
|
||||
|
||||
[node name="AvailableTransporterLabel" type="Label" parent="UI/HangarMenu"]
|
||||
mouse_filter = 2
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = 80
|
||||
offset_right = 300
|
||||
offset_top = 380
|
||||
offset_bottom = 460
|
||||
theme_override_font_sizes/font_size = 22
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="FleetTitle" type="Label" parent="UI/HangarMenu"]
|
||||
mouse_filter = 2
|
||||
anchor_right = 1.0
|
||||
offset_top = 500
|
||||
offset_bottom = 550
|
||||
theme_override_font_sizes/font_size = 28
|
||||
text = "FLEET — TAP TO STORE"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="FleetInterceptor" type="Control" parent="UI/HangarMenu"]
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -250
|
||||
offset_right = -130
|
||||
offset_top = 565
|
||||
offset_bottom = 685
|
||||
script = ExtResource("10")
|
||||
icon = 2
|
||||
|
||||
[node name="FleetInterceptorLabel" type="Label" parent="UI/HangarMenu"]
|
||||
mouse_filter = 2
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -300
|
||||
offset_right = -80
|
||||
offset_top = 690
|
||||
offset_bottom = 770
|
||||
theme_override_font_sizes/font_size = 22
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="FleetShield" type="Control" parent="UI/HangarMenu"]
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -60
|
||||
offset_right = 60
|
||||
offset_top = 565
|
||||
offset_bottom = 685
|
||||
script = ExtResource("10")
|
||||
icon = 2
|
||||
glow_color = Color(0.45, 0.8, 1, 1)
|
||||
|
||||
[node name="FleetShieldLabel" type="Label" parent="UI/HangarMenu"]
|
||||
mouse_filter = 2
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -110
|
||||
offset_right = 110
|
||||
offset_top = 690
|
||||
offset_bottom = 770
|
||||
theme_override_font_sizes/font_size = 22
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="FleetTransporter" type="Control" parent="UI/HangarMenu"]
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = 130
|
||||
offset_right = 250
|
||||
offset_top = 565
|
||||
offset_bottom = 685
|
||||
script = ExtResource("10")
|
||||
icon = 12
|
||||
glow_color = Color(0.95, 0.55, 0.85, 1)
|
||||
|
||||
[node name="FleetTransporterLabel" type="Label" parent="UI/HangarMenu"]
|
||||
mouse_filter = 2
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = 80
|
||||
offset_right = 300
|
||||
offset_top = 690
|
||||
offset_bottom = 770
|
||||
theme_override_font_sizes/font_size = 22
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="CloseButton" type="Control" parent="UI/HangarMenu"]
|
||||
anchor_left = 1.0
|
||||
anchor_right = 1.0
|
||||
|
|
|
|||
86
tests/test_hangar_management.gd
Normal file
86
tests/test_hangar_management.gd
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
extends SceneTree
|
||||
|
||||
# Forgejo #23 + #25: the mothership hangar presents vessels by type, tapping
|
||||
# an available type crews one, tapping a fleet type stores one, and contextual
|
||||
# world buttons each get their own touch berth.
|
||||
|
||||
var game_state: Node
|
||||
var scene: Node
|
||||
var fleet: Node
|
||||
var controller: 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.stored_vessels.clear()
|
||||
game_state.rocks = 100
|
||||
scene = load("res://Main.tscn").instantiate()
|
||||
root.add_child(scene)
|
||||
fleet = scene.get_node("Fleet")
|
||||
controller = scene.get_node("BuildController")
|
||||
|
||||
|
||||
func _process(delta: float) -> bool:
|
||||
elapsed += delta
|
||||
if stage == 0:
|
||||
scene.get_node("AsteroidField").set_process(false)
|
||||
scene.get_node("EnemySpawner").set_process(false)
|
||||
for a in get_nodes_in_group("asteroids"):
|
||||
if is_instance_valid(a):
|
||||
a.queue_free()
|
||||
fleet.spawn_ships(1, Vector2.ZERO)
|
||||
fleet.add_ship(GameState.VESSEL_SHIELD)
|
||||
game_state.stored_vessels = [GameState.VESSEL_INTERCEPTOR, GameState.VESSEL_SHIELD]
|
||||
controller._on_hangar_pressed()
|
||||
elapsed = 0.0
|
||||
stage = 1
|
||||
return false
|
||||
if stage == 1:
|
||||
if elapsed < 0.2:
|
||||
return false
|
||||
# Available cards name the vessel and count what can be crewed.
|
||||
var available_label: Label = controller.hangar_available_labels[0]
|
||||
if "Interceptor" not in available_label.text or "1 available" not in available_label.text:
|
||||
_fail("available interceptor card says '%s'" % available_label.text)
|
||||
return true
|
||||
controller._on_hangar_crew_type(0)
|
||||
if fleet.ships.size() != 3 or game_state.stored_vessels.has(GameState.VESSEL_INTERCEPTOR):
|
||||
_fail("tapping an available interceptor did not crew it")
|
||||
return true
|
||||
controller._on_hangar_store_type(1)
|
||||
if fleet.ships.size() != 2 or not game_state.stored_vessels.has(GameState.VESSEL_SHIELD):
|
||||
_fail("tapping the shield fleet card did not store it")
|
||||
return true
|
||||
# The safety rule prevents an empty deployed fleet.
|
||||
controller._on_hangar_store_type(0)
|
||||
controller._on_hangar_store_type(0)
|
||||
if fleet.ships.size() != 1:
|
||||
_fail("hangar allowed the last deployed ship to be stored")
|
||||
return true
|
||||
|
||||
# #25: all three contextual controls have non-overlapping vertical
|
||||
# rectangles when the mothership exposes Action, Transfer and Hangar.
|
||||
controller.action_button.visible = true
|
||||
controller.transfer_button.visible = true
|
||||
controller.hangar_button.visible = true
|
||||
controller._layout_context_buttons()
|
||||
var buttons: Array = [controller.action_button, controller.transfer_button, controller.hangar_button]
|
||||
for i in range(buttons.size() - 1):
|
||||
if buttons[i].offset_bottom > buttons[i + 1].offset_top:
|
||||
_fail("context buttons %d and %d overlap" % [i, i + 1])
|
||||
return true
|
||||
print("hangar crews and stores typed vessels; contextual buttons have separate berths")
|
||||
print("TEST_HANGAR_MANAGEMENT: PASS")
|
||||
quit(0)
|
||||
return true
|
||||
return false
|
||||
|
||||
|
||||
func _fail(message: String) -> void:
|
||||
print("TEST_HANGAR_MANAGEMENT: FAIL (%s)" % message)
|
||||
quit(1)
|
||||
Loading…
Reference in a new issue