110 lines
4 KiB
GDScript3
110 lines
4 KiB
GDScript3
|
|
extends "res://ui/menus/ModalMenu.gd"
|
||
|
|
|
||
|
|
# Forgejo #216: transport hubs and spacial workshops used to conjure their own
|
||
|
|
# crews, free and permanent. The player orders them at a ship crafter now, and
|
||
|
|
# this is where they say how many they want standing HERE.
|
||
|
|
#
|
||
|
|
# The menu edits the ORDER, not the crew - the same split GarrisonPanel makes
|
||
|
|
# for outposts, and for the same reason: a hub that has asked for three and
|
||
|
|
# been sent one is waiting, not broken, and has to read that way.
|
||
|
|
#
|
||
|
|
# It also answers "how long will these last". Each vessel is spent by the work
|
||
|
|
# it does, so the bar row below shows what each of them has left, worst first,
|
||
|
|
# which is the number that decides whether another needs building.
|
||
|
|
|
||
|
|
const BAR_WIDTH: float = 54.0
|
||
|
|
const BAR_HEIGHT: float = 18.0
|
||
|
|
const BAR_GAP: float = 10.0
|
||
|
|
const BAR_TOP: float = 470.0
|
||
|
|
const WORN_COLOR: Color = Color(1.0, 0.35, 0.25)
|
||
|
|
const FRESH_COLOR: Color = Color(0.5, 1.0, 0.55)
|
||
|
|
const PLATE_COLOR: Color = Color(0.02, 0.02, 0.06, 0.9)
|
||
|
|
const FRAME_COLOR: Color = Color(0.85, 0.96, 1.0, 0.85)
|
||
|
|
|
||
|
|
@onready var title: Label = $TitleLabel
|
||
|
|
@onready var assigned_label: Label = $AssignedLabel
|
||
|
|
@onready var status: Label = $StatusLabel
|
||
|
|
@onready var condition_label: Label = $ConditionLabel
|
||
|
|
@onready var less_button: IconButton = $LessButton
|
||
|
|
@onready var more_button: IconButton = $MoreButton
|
||
|
|
|
||
|
|
var building_id: int = 0
|
||
|
|
|
||
|
|
|
||
|
|
func _ready() -> void:
|
||
|
|
super._ready()
|
||
|
|
# ModalMenu already owns $CloseButton and wires it.
|
||
|
|
less_button.pressed.connect(func(): _step(-1))
|
||
|
|
more_button.pressed.connect(func(): _step(1))
|
||
|
|
|
||
|
|
|
||
|
|
func open_for(next_building_id: int) -> void:
|
||
|
|
building_id = next_building_id
|
||
|
|
open_menu()
|
||
|
|
refresh()
|
||
|
|
|
||
|
|
|
||
|
|
func close_menu() -> void:
|
||
|
|
super.close_menu()
|
||
|
|
building_id = 0
|
||
|
|
|
||
|
|
|
||
|
|
func _step(delta: int) -> void:
|
||
|
|
if building_id == 0:
|
||
|
|
return
|
||
|
|
GameState.set_station_desired(building_id,
|
||
|
|
GameState.station_desired(building_id) + delta)
|
||
|
|
refresh()
|
||
|
|
|
||
|
|
|
||
|
|
func refresh() -> void:
|
||
|
|
if building_id == 0:
|
||
|
|
return
|
||
|
|
var building: Dictionary = GameState.find_building(building_id)
|
||
|
|
if building.is_empty():
|
||
|
|
close_menu()
|
||
|
|
return
|
||
|
|
var vessel_type: String = GameState.station_vessel_type(building)
|
||
|
|
var wanted: int = GameState.station_desired(building_id)
|
||
|
|
var here: int = GameState.station_crew(building_id)
|
||
|
|
var capacity: int = GameState.station_capacity(building)
|
||
|
|
|
||
|
|
title.text = String(building.get("type", "")).to_upper().replace("_", " ")
|
||
|
|
assigned_label.text = "%d / %d ASSIGNED (room for %d)" % [here, wanted, capacity]
|
||
|
|
less_button.enabled = wanted > 0
|
||
|
|
more_button.enabled = wanted < capacity
|
||
|
|
|
||
|
|
var name: String = GameState.vessel_name(vessel_type)
|
||
|
|
if wanted == 0:
|
||
|
|
status.text = "None assigned. Build %s at a ship crafter, then ask for them here." % name.to_lower()
|
||
|
|
elif here >= wanted:
|
||
|
|
status.text = "Fully crewed. Each one wears out with use and is not replaced by itself."
|
||
|
|
else:
|
||
|
|
status.text = "%d on order - sent from the mothership hangar as they are built." % (wanted - here)
|
||
|
|
|
||
|
|
var left: Array = GameState.station_condition(building_id)
|
||
|
|
condition_label.text = "CONDITION" if not left.is_empty() else ""
|
||
|
|
queue_redraw()
|
||
|
|
|
||
|
|
|
||
|
|
func _draw() -> void:
|
||
|
|
if building_id == 0:
|
||
|
|
return
|
||
|
|
# One bar per vessel standing here, worst first: what is left of the work
|
||
|
|
# it was built to do. Drawn rather than built from nodes because the count
|
||
|
|
# changes as vessels arrive and wear out, and a row of bars is cheaper to
|
||
|
|
# draw than to keep a pool of Controls in step with.
|
||
|
|
var left: Array = GameState.station_condition(building_id)
|
||
|
|
if left.is_empty():
|
||
|
|
return
|
||
|
|
var full: int = maxi(GameState.station_work_capacity(building_id), 1)
|
||
|
|
var total: float = float(left.size()) * BAR_WIDTH + float(left.size() - 1) * BAR_GAP
|
||
|
|
var x: float = (size.x - total) * 0.5
|
||
|
|
for remaining in left:
|
||
|
|
var fraction: float = clampf(float(remaining) / float(full), 0.0, 1.0)
|
||
|
|
draw_rect(Rect2(x - 2.0, BAR_TOP - 2.0, BAR_WIDTH + 4.0, BAR_HEIGHT + 4.0),
|
||
|
|
PLATE_COLOR)
|
||
|
|
draw_rect(Rect2(x, BAR_TOP, BAR_WIDTH * fraction, BAR_HEIGHT),
|
||
|
|
WORN_COLOR.lerp(FRESH_COLOR, fraction))
|
||
|
|
draw_rect(Rect2(x, BAR_TOP, BAR_WIDTH, BAR_HEIGHT), FRAME_COLOR, false, 1.5)
|
||
|
|
x += BAR_WIDTH + BAR_GAP
|