Refactor gameplay menus into owned scenes
This commit is contained in:
parent
46196a1adb
commit
a17fe88197
50 changed files with 3449 additions and 3619 deletions
138
ui/menus/HangarMenu.gd
Normal file
138
ui/menus/HangarMenu.gd
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
extends "res://ui/menus/ModalMenu.gd"
|
||||
|
||||
signal crew_requested(vessel_type: String)
|
||||
signal store_requested(vessel_type: String)
|
||||
|
||||
const VESSEL_DEFINITIONS = preload("res://vessels/VesselDefinitions.gd")
|
||||
const RULE_COLOR := Color(0.45, 0.9, 0.55)
|
||||
const COLUMNS := 3
|
||||
const LABEL_GAP := 2.0
|
||||
const DIVIDER_GAP := 10.0
|
||||
const CAPTION_LINES := 3.0
|
||||
const CAPTION_MIN := 13
|
||||
const CAPTION_MAX := 22
|
||||
const LINE_RATIO := 1.25
|
||||
|
||||
@onready var status: Label = $StatusLabel
|
||||
@onready var available_title: Label = $AvailableTitle
|
||||
@onready var fleet_title: Label = $FleetTitle
|
||||
@onready var available_slots: Array = [$AvailableInterceptor, $AvailableShield,
|
||||
$AvailableGasBomber, $AvailableCarrier, $AvailableLaser, $AvailableDistorder]
|
||||
@onready var available_labels: Array = [$AvailableInterceptorLabel, $AvailableShieldLabel,
|
||||
$AvailableGasBomberLabel, $AvailableCarrierLabel, $AvailableLaserLabel,
|
||||
$AvailableDistorderLabel]
|
||||
@onready var fleet_slots: Array = [$FleetInterceptor, $FleetShield, $FleetGasBomber,
|
||||
$FleetCarrier, $FleetLaser, $FleetDistorder]
|
||||
@onready var fleet_labels: Array = [$FleetInterceptorLabel, $FleetShieldLabel,
|
||||
$FleetGasBomberLabel, $FleetCarrierLabel, $FleetLaserLabel, $FleetDistorderLabel]
|
||||
|
||||
var divider_y: float = 0.0
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
super._ready()
|
||||
for i in range(available_slots.size()):
|
||||
available_slots[i].pressed.connect(
|
||||
func(): crew_requested.emit(_vessel_types()[i]))
|
||||
fleet_slots[i].pressed.connect(
|
||||
func(): store_requested.emit(_vessel_types()[i]))
|
||||
_layout_sections()
|
||||
|
||||
|
||||
func open_for(fleet: Node) -> void:
|
||||
status.text = ""
|
||||
open_menu()
|
||||
refresh(fleet)
|
||||
|
||||
|
||||
func set_status(message: String) -> void:
|
||||
status.text = message
|
||||
|
||||
|
||||
func refresh(fleet: Node) -> void:
|
||||
var types: Array = _vessel_types()
|
||||
for i in range(mini(types.size(), available_slots.size())):
|
||||
var vessel_type: String = types[i]
|
||||
var definition: Resource = VESSEL_DEFINITIONS.get_definition(vessel_type)
|
||||
var available: int = GameState.stored_vessels.count(vessel_type)
|
||||
var deployed: int = 0
|
||||
for ship in fleet.ships:
|
||||
if is_instance_valid(ship) and String(ship.vessel_type) == vessel_type:
|
||||
deployed += 1
|
||||
available_labels[i].text = "%s\n%d available" % [definition.display_name, available]
|
||||
fleet_labels[i].text = "%s\n%d in fleet" % [definition.display_name, deployed]
|
||||
for slot in [available_slots[i], fleet_slots[i]]:
|
||||
slot.icon = definition.icon
|
||||
slot.glow_color = definition.glow_color
|
||||
available_slots[i].enabled = available > 0 \
|
||||
and fleet.ships.size() < GameState.max_fleet_size()
|
||||
fleet_slots[i].enabled = deployed > 0 and fleet.ships.size() > 1
|
||||
available_slots[i].queue_redraw()
|
||||
fleet_slots[i].queue_redraw()
|
||||
|
||||
|
||||
func _vessel_types() -> Array:
|
||||
var types: Array = []
|
||||
for definition in VESSEL_DEFINITIONS.fleet():
|
||||
types.append(String(definition.definition_id))
|
||||
return types
|
||||
|
||||
|
||||
func _layout_sections() -> void:
|
||||
var count: int = available_slots.size()
|
||||
if count == 0:
|
||||
return
|
||||
var columns: int = mini(COLUMNS, count)
|
||||
var rows: int = int(ceil(float(count) / float(columns)))
|
||||
var top: float = available_title.position.y + available_title.size.y + 8.0
|
||||
var bottom: float = status.position.y - 12.0
|
||||
var title_height: float = fleet_title.size.y
|
||||
var section_height: float = (bottom - top - title_height - 16.0) * 0.5
|
||||
if section_height <= 0.0:
|
||||
return
|
||||
var cell_width: float = size.x / float(columns)
|
||||
var cell_height: float = section_height / float(rows)
|
||||
var slot_size: float = minf(cell_height * 0.46, cell_width * 0.40)
|
||||
var label_height: float = maxf(cell_height - slot_size - LABEL_GAP * 2.0, 1.0)
|
||||
_layout_section(available_slots, available_labels, top, columns, cell_width,
|
||||
cell_height, slot_size, label_height)
|
||||
var available_bottom: float = top + section_height
|
||||
divider_y = available_bottom + DIVIDER_GAP
|
||||
fleet_title.position.y = divider_y + DIVIDER_GAP
|
||||
var fleet_top: float = fleet_title.position.y + title_height + 8.0
|
||||
_layout_section(fleet_slots, fleet_labels, fleet_top, columns, cell_width,
|
||||
cell_height, slot_size, label_height)
|
||||
queue_redraw()
|
||||
|
||||
|
||||
func _layout_section(slots: Array, labels: Array, top: float, columns: int,
|
||||
cell_width: float, cell_height: float, slot_size: float,
|
||||
label_height: float) -> void:
|
||||
if columns <= 0:
|
||||
return
|
||||
for i in range(slots.size()):
|
||||
var column: int = i % columns
|
||||
var row: int = i / columns
|
||||
var cell_x: float = float(column) * cell_width
|
||||
var cell_y: float = top + float(row) * cell_height
|
||||
slots[i].position = Vector2(cell_x + (cell_width - slot_size) * 0.5, cell_y)
|
||||
slots[i].size = Vector2(slot_size, slot_size)
|
||||
labels[i].position = Vector2(cell_x, cell_y + slot_size + LABEL_GAP)
|
||||
labels[i].size = Vector2(cell_width, label_height)
|
||||
labels[i].horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
labels[i].vertical_alignment = VERTICAL_ALIGNMENT_TOP
|
||||
labels[i].autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
labels[i].add_theme_font_size_override("font_size", caption_size(label_height))
|
||||
labels[i].clip_text = true
|
||||
|
||||
|
||||
func caption_size(label_height: float) -> int:
|
||||
return clampi(int(label_height / (CAPTION_LINES * LINE_RATIO)),
|
||||
CAPTION_MIN, CAPTION_MAX)
|
||||
|
||||
|
||||
func _draw() -> void:
|
||||
if divider_y <= 0.0:
|
||||
return
|
||||
NeonDraw.draw_glowing_line(self, Vector2(24.0, divider_y),
|
||||
Vector2(size.x - 24.0, divider_y), RULE_COLOR, 0.5, 0.4)
|
||||
Loading…
Reference in a new issue