Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019AJMdB7iuHuLFZM1aBu3GD
157 lines
5.6 KiB
GDScript
157 lines
5.6 KiB
GDScript
extends "res://ui/menus/ModalMenu.gd"
|
|
|
|
signal fleet_add_requested(vessel_type: String)
|
|
signal fleet_remove_requested(vessel_type: String)
|
|
signal unlock_skills_requested
|
|
signal unlimited_resources_requested(enabled: bool)
|
|
signal free_costs_requested(enabled: bool)
|
|
signal wave_requested
|
|
|
|
const ICON_BUTTON = preload("res://ui/IconButton.gd")
|
|
const VESSEL_DEFINITIONS = preload("res://vessels/VesselDefinitions.gd")
|
|
const ROW_HEIGHT: float = 86.0
|
|
const DESIGN_SIZE := Vector2(720.0, 1280.0)
|
|
|
|
@onready var content: Control = $Content
|
|
@onready var fleet_summary: Label = $Content/FleetSummary
|
|
@onready var fleet_rows: VBoxContainer = $Content/FleetRows
|
|
@onready var unlock_button: IconButton = $Content/ToolButtons/UnlockSkills
|
|
@onready var unlimited_button: IconButton = $Content/ToolButtons/UnlimitedResources
|
|
@onready var free_costs_button: IconButton = $Content/ToolButtons/FreeCosts
|
|
@onready var wave_button: IconButton = $Content/ToolButtons/StartWave
|
|
@onready var unlimited_label: Label = $Content/ToolLabels/UnlimitedLabel
|
|
@onready var free_costs_label: Label = $Content/ToolLabels/FreeCostsLabel
|
|
@onready var status: Label = $Content/StatusLabel
|
|
|
|
var fleet: Node = null
|
|
var row_controls: Dictionary = {}
|
|
|
|
|
|
func _ready() -> void:
|
|
super._ready()
|
|
$Content/CloseButton.pressed.connect(close_menu)
|
|
_build_fleet_rows()
|
|
unlock_button.pressed.connect(func(): unlock_skills_requested.emit())
|
|
unlimited_button.pressed.connect(func():
|
|
unlimited_resources_requested.emit(not GameState.dev_unlimited_resources))
|
|
free_costs_button.pressed.connect(func():
|
|
free_costs_requested.emit(not GameState.dev_free_costs))
|
|
wave_button.pressed.connect(func(): wave_requested.emit())
|
|
_layout_content()
|
|
|
|
|
|
func _notification(what: int) -> void:
|
|
if what == NOTIFICATION_RESIZED and is_node_ready():
|
|
_layout_content()
|
|
|
|
|
|
func _layout_content() -> void:
|
|
# The project has a landscape reference viewport but is played in portrait
|
|
# too. A fixed design canvas keeps touch targets at their authored size and
|
|
# scales the complete composition uniformly into either shape.
|
|
var factor: float = minf(size.x / DESIGN_SIZE.x, size.y / DESIGN_SIZE.y)
|
|
content.scale = Vector2(factor, factor)
|
|
content.position = (size - DESIGN_SIZE * factor) * 0.5
|
|
|
|
|
|
func open_for(fleet_node: Node) -> void:
|
|
fleet = fleet_node
|
|
status.text = ""
|
|
open_menu()
|
|
refresh()
|
|
|
|
|
|
func set_status(message: String) -> void:
|
|
status.text = message
|
|
refresh()
|
|
|
|
|
|
func refresh() -> void:
|
|
if fleet == null or not is_instance_valid(fleet):
|
|
return
|
|
var total: int = fleet.ships.size()
|
|
fleet_summary.text = "CURRENT FLEET %d / %d" % [total, GameState.max_fleet_size()]
|
|
for definition in VESSEL_DEFINITIONS.fleet():
|
|
var vessel_type: String = String(definition.definition_id)
|
|
var count: int = 0
|
|
for ship in fleet.ships:
|
|
if is_instance_valid(ship) and String(ship.vessel_type) == vessel_type:
|
|
count += 1
|
|
var controls: Dictionary = row_controls.get(vessel_type, {})
|
|
if controls.is_empty():
|
|
continue
|
|
(controls.count as Label).text = str(count)
|
|
(controls.add as IconButton).enabled = total < GameState.max_fleet_size()
|
|
(controls.remove as IconButton).enabled = count > 0 and total > 1
|
|
unlock_button.highlighted = _all_skills_unlocked()
|
|
unlimited_button.highlighted = GameState.dev_unlimited_resources
|
|
unlimited_label.text = "UNLIMITED\nRESOURCES\n%s" \
|
|
% ("ON" if GameState.dev_unlimited_resources else "OFF")
|
|
free_costs_button.highlighted = GameState.dev_free_costs
|
|
free_costs_label.text = "FREE\nCOSTS\n%s" \
|
|
% ("ON" if GameState.dev_free_costs else "OFF")
|
|
|
|
|
|
func _all_skills_unlocked() -> bool:
|
|
for node in GameState.SKILL_TREE:
|
|
if not GameState.is_unlocked(String(node.id)):
|
|
return false
|
|
return true
|
|
|
|
|
|
func _build_fleet_rows() -> void:
|
|
for definition in VESSEL_DEFINITIONS.fleet():
|
|
var vessel_type: String = String(definition.definition_id)
|
|
var row := HBoxContainer.new()
|
|
row.custom_minimum_size = Vector2(0.0, ROW_HEIGHT)
|
|
row.add_theme_constant_override("separation", 12)
|
|
fleet_rows.add_child(row)
|
|
|
|
var vessel_icon := ICON_BUTTON.new()
|
|
vessel_icon.custom_minimum_size = Vector2(76.0, 76.0)
|
|
vessel_icon.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
vessel_icon.icon = int(definition.icon)
|
|
vessel_icon.glow_color = definition.glow_color
|
|
row.add_child(vessel_icon)
|
|
|
|
var name_label := Label.new()
|
|
name_label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
|
name_label.text = String(definition.display_name)
|
|
name_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
|
name_label.add_theme_font_size_override("font_size", 25)
|
|
row.add_child(name_label)
|
|
|
|
var remove_button := ICON_BUTTON.new()
|
|
remove_button.custom_minimum_size = Vector2(70.0, 70.0)
|
|
remove_button.icon = IconButton.Icon.MINUS
|
|
remove_button.glow_color = definition.glow_color
|
|
remove_button.pressed.connect(_request_remove.bind(vessel_type))
|
|
row.add_child(remove_button)
|
|
|
|
var count_label := Label.new()
|
|
count_label.custom_minimum_size = Vector2(48.0, 0.0)
|
|
count_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
|
count_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
|
count_label.add_theme_font_size_override("font_size", 31)
|
|
row.add_child(count_label)
|
|
|
|
var add_button := ICON_BUTTON.new()
|
|
add_button.custom_minimum_size = Vector2(70.0, 70.0)
|
|
add_button.icon = IconButton.Icon.PLUS
|
|
add_button.glow_color = definition.glow_color
|
|
add_button.pressed.connect(_request_add.bind(vessel_type))
|
|
row.add_child(add_button)
|
|
|
|
row_controls[vessel_type] = {
|
|
"count": count_label,
|
|
"add": add_button,
|
|
"remove": remove_button,
|
|
}
|
|
|
|
|
|
func _request_add(vessel_type: String) -> void:
|
|
fleet_add_requested.emit(vessel_type)
|
|
|
|
|
|
func _request_remove(vessel_type: String) -> void:
|
|
fleet_remove_requested.emit(vessel_type)
|