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