spaceship/ui/menus/LabMenu.gd

168 lines
5.3 KiB
GDScript3
Raw Normal View History

extends "res://ui/menus/ModalMenu.gd"
signal vessel_selected(index: int)
signal upgrade_selected(index: int)
const PRICE_TAG = preload("res://ui/PriceTag.gd")
const TAG_HEIGHT := 38.0
const LABEL_HEIGHT := 40.0
const TAG_PADDING := 8.0
const ROW_GAP := 18.0
const VESSEL_HALF := 30.0
const VESSEL_SPACING := 90.0
const VESSEL_MARGIN := 24.0
@onready var vessel_buttons: Array = [$VesselA, $VesselB, $VesselC, $VesselD,
$VesselE, $VesselF, $VesselG, $VesselH]
@onready var vessel_labels: Array = [$VesselALabel, $VesselBLabel, $VesselCLabel,
$VesselDLabel, $VesselELabel, $VesselFLabel, $VesselGLabel, $VesselHLabel]
@onready var upgrade_buttons: Array = [$Upgrade0, $Upgrade1, $Upgrade2, $Upgrade3]
@onready var upgrade_labels: Array = [$Upgrade0Label, $Upgrade1Label,
$Upgrade2Label, $Upgrade3Label]
@onready var vessel_heading: Label = $VesselLabel
@onready var detail: Label = $DetailLabel
@onready var status: Label = $StatusLabel
@onready var research_progress: ProgressBar = $ResearchProgress
@onready var resource_bar: Control = $Bar
var building_id: int = 0
var price_tags: Array = []
func _ready() -> void:
super._ready()
_build_price_tags()
for i in range(vessel_buttons.size()):
vessel_buttons[i].pressed.connect(func(): vessel_selected.emit(i))
for i in range(upgrade_buttons.size()):
upgrade_buttons[i].pressed.connect(func(): upgrade_selected.emit(i))
func open_for(next_building_id: int) -> void:
building_id = next_building_id
resource_bar.building_id = building_id
open_menu()
func close_menu() -> void:
super.close_menu()
building_id = 0
func render_vessels(definitions: Array, selected_type: String) -> void:
for i in range(mini(vessel_buttons.size(), definitions.size())):
var definition: Resource = definitions[i]
vessel_buttons[i].enabled = true
vessel_buttons[i].icon = definition.icon
vessel_buttons[i].glow_color = definition.glow_color
vessel_buttons[i].highlighted = String(definition.definition_id) == selected_type
vessel_labels[i].text = definition.display_name
vessel_buttons[i].queue_redraw()
_layout_vessels()
func render_options(options: Array, selected: int, vessel_colour: Color) -> void:
for i in range(upgrade_buttons.size()):
var shown: bool = i < options.size()
upgrade_buttons[i].visible = shown
upgrade_labels[i].visible = shown
price_tags[i].visible = shown
if not shown:
continue
var option: Dictionary = options[i]
var maxed: bool = bool(option.get("maxed", false))
upgrade_labels[i].text = String(option.label)
price_tags[i].visible = not maxed
price_tags[i].show_price({} if maxed else option.costs,
0 if maxed else int(option.points))
upgrade_buttons[i].icon = int(option.icon)
upgrade_buttons[i].glow_color = vessel_colour
upgrade_buttons[i].highlighted = i == selected
upgrade_buttons[i].enabled = true
upgrade_buttons[i].queue_redraw()
_resize_price_tags()
func show_detail(heading: String, description: String, points: int) -> void:
detail.text = "%s\n%s" % [heading, description]
if points > 0:
detail.text += "\nResearch points: %d/%d" % [GameState.research_points, points]
func clear_detail() -> void:
detail.text = ""
func set_status(message: String) -> void:
status.text = message
func show_research_progress(message: String, ratio: float) -> void:
status.text = message
research_progress.value = clampf(ratio, 0.0, 1.0)
research_progress.visible = true
func hide_research_progress() -> void:
research_progress.visible = false
func _build_price_tags() -> void:
for i in range(upgrade_labels.size()):
var label: Control = upgrade_labels[i]
var tag: Control = PRICE_TAG.new()
tag.name = "LabPrice%d" % i
tag.anchor_left = label.anchor_left
tag.anchor_right = label.anchor_right
tag.anchor_top = label.anchor_top
tag.anchor_bottom = label.anchor_bottom
tag.offset_left = label.offset_left
tag.offset_right = label.offset_right
label.offset_bottom = label.offset_top + LABEL_HEIGHT
tag.offset_top = label.offset_bottom + 2.0
tag.offset_bottom = tag.offset_top + tag_height()
add_child(tag)
price_tags.append(tag)
func tag_height() -> float:
var tallest: float = TAG_HEIGHT
for tag in price_tags:
if tag != null and tag.has_method("wanted_height"):
tallest = maxf(tallest, float(tag.wanted_height()) + TAG_PADDING)
return tallest
func _layout_vessels() -> void:
var shown: Array = []
for i in range(vessel_buttons.size()):
if vessel_buttons[i].visible:
shown.append(i)
if shown.is_empty():
return
var room: float = size.x - VESSEL_MARGIN * 2.0
if room <= 0.0:
room = 672.0
var spacing: float = minf(VESSEL_SPACING, room / float(shown.size()))
for slot in range(shown.size()):
var i: int = shown[slot]
var cx: float = (float(slot) - (float(shown.size()) - 1.0) * 0.5) * spacing
vessel_buttons[i].offset_left = cx - VESSEL_HALF
vessel_buttons[i].offset_right = cx + VESSEL_HALF
vessel_labels[i].offset_left = cx - spacing * 0.5
vessel_labels[i].offset_right = cx + spacing * 0.5
func _resize_price_tags() -> void:
var height: float = tag_height()
for tag in price_tags:
tag.offset_bottom = tag.offset_top + height
if price_tags.size() < 3:
return
var shift: float = price_tags[0].offset_bottom + ROW_GAP - upgrade_buttons[2].offset_top
if absf(shift) < 0.5:
return
for i in range(2, upgrade_buttons.size()):
for node in [upgrade_buttons[i], upgrade_labels[i], price_tags[i]]:
node.offset_top += shift
node.offset_bottom += shift