138 lines
5.1 KiB
GDScript
138 lines
5.1 KiB
GDScript
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)
|