2026-08-12 13:07:52 +02:00
|
|
|
class_name ResourceBar
|
|
|
|
|
extends Control
|
|
|
|
|
|
2026-08-14 11:54:31 +02:00
|
|
|
# Compact resource table shared by crafting, research and the ship lab.
|
|
|
|
|
# Rows are resources; columns are locations. Adding another material to
|
2026-08-14 20:32:58 +02:00
|
|
|
# The resource-definition catalog automatically gives each material a row.
|
2026-08-14 11:54:31 +02:00
|
|
|
|
2026-08-12 13:07:52 +02:00
|
|
|
var building_id: int = 0
|
|
|
|
|
|
2026-08-14 11:54:31 +02:00
|
|
|
const HEADER_HEIGHT: float = 22.0
|
2026-08-12 13:07:52 +02:00
|
|
|
const RULE_COLOR: Color = Color(0.25, 0.55, 0.7)
|
2026-08-14 11:54:31 +02:00
|
|
|
const FLEET_COLOR: Color = Color(1.0, 0.78, 0.25)
|
|
|
|
|
const LOCAL_COLOR: Color = Color(0.45, 0.9, 0.55)
|
2026-08-12 13:07:52 +02:00
|
|
|
|
2026-08-14 11:54:31 +02:00
|
|
|
var _header_labels: Array[Label] = []
|
|
|
|
|
var _rows: Dictionary = {}
|
2026-08-12 13:07:52 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
func _ready() -> void:
|
|
|
|
|
mouse_filter = Control.MOUSE_FILTER_IGNORE
|
2026-08-14 11:54:31 +02:00
|
|
|
for heading in ["", "BANKED", "FLEET", "LOCAL"]:
|
|
|
|
|
var label := _make_label(heading, 16, Color(0.62, 0.78, 0.86))
|
|
|
|
|
label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
|
|
|
|
add_child(label)
|
|
|
|
|
_header_labels.append(label)
|
|
|
|
|
|
2026-08-14 20:32:58 +02:00
|
|
|
for resource_type in GameState.resource_types():
|
2026-08-14 11:54:31 +02:00
|
|
|
var glyph := ResourceGlyph.new()
|
|
|
|
|
glyph.resource_type = resource_type
|
|
|
|
|
add_child(glyph)
|
|
|
|
|
var name_label := _make_label(GameState.resource_name(resource_type).to_upper(), 18,
|
|
|
|
|
GameState.resource_color(resource_type))
|
|
|
|
|
add_child(name_label)
|
|
|
|
|
var bank_label := _make_value_label(GameState.resource_color(resource_type))
|
|
|
|
|
var fleet_label := _make_value_label(FLEET_COLOR)
|
|
|
|
|
var local_label := _make_value_label(LOCAL_COLOR)
|
|
|
|
|
for label in [bank_label, fleet_label, local_label]:
|
|
|
|
|
add_child(label)
|
|
|
|
|
_rows[resource_type] = {
|
|
|
|
|
"glyph": glyph, "name": name_label, "bank": bank_label,
|
|
|
|
|
"fleet": fleet_label, "local": local_label,
|
|
|
|
|
}
|
2026-08-12 13:07:52 +02:00
|
|
|
|
|
|
|
|
resized.connect(_layout)
|
2026-08-14 11:54:31 +02:00
|
|
|
_layout()
|
|
|
|
|
queue_redraw()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _make_label(text_value: String, font_size: int, colour: Color) -> Label:
|
|
|
|
|
var label := Label.new()
|
|
|
|
|
label.text = text_value
|
|
|
|
|
label.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
|
|
|
label.add_theme_font_size_override("font_size", font_size)
|
|
|
|
|
label.add_theme_color_override("font_color", colour)
|
|
|
|
|
label.add_theme_color_override("font_outline_color", Color(0.01, 0.01, 0.035, 0.95))
|
|
|
|
|
label.add_theme_constant_override("outline_size", 2)
|
|
|
|
|
label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
|
|
|
|
return label
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _make_value_label(colour: Color) -> Label:
|
|
|
|
|
var label := _make_label("0", 19, colour)
|
|
|
|
|
label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
|
|
|
|
return label
|
2026-08-12 13:07:52 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
func _layout() -> void:
|
2026-08-14 11:54:31 +02:00
|
|
|
if _header_labels.is_empty():
|
|
|
|
|
return
|
|
|
|
|
var resource_width: float = size.x * 0.25
|
|
|
|
|
var value_width: float = (size.x - resource_width) / 3.0
|
|
|
|
|
var columns: Array = [0.0, resource_width, resource_width + value_width,
|
|
|
|
|
resource_width + value_width * 2.0]
|
|
|
|
|
var widths: Array = [resource_width, value_width, value_width, value_width]
|
|
|
|
|
for i in range(_header_labels.size()):
|
|
|
|
|
_header_labels[i].position = Vector2(columns[i], 0.0)
|
|
|
|
|
_header_labels[i].size = Vector2(widths[i], HEADER_HEIGHT)
|
|
|
|
|
|
|
|
|
|
var row_height: float = (size.y - HEADER_HEIGHT - 4.0) / maxf(1.0, float(_rows.size()))
|
|
|
|
|
var row_index: int = 0
|
2026-08-14 20:32:58 +02:00
|
|
|
for resource_type in GameState.resource_types():
|
2026-08-14 11:54:31 +02:00
|
|
|
var row: Dictionary = _rows[resource_type]
|
|
|
|
|
var y: float = HEADER_HEIGHT + float(row_index) * row_height
|
|
|
|
|
row.glyph.position = Vector2(2.0, y + 2.0)
|
|
|
|
|
row.glyph.size = Vector2(row_height - 4.0, row_height - 4.0)
|
|
|
|
|
row.name.position = Vector2(row_height, y)
|
|
|
|
|
row.name.size = Vector2(resource_width - row_height, row_height)
|
|
|
|
|
for i in range(3):
|
|
|
|
|
var label: Label = row[["bank", "fleet", "local"][i]]
|
|
|
|
|
label.position = Vector2(columns[i + 1], y)
|
|
|
|
|
label.size = Vector2(widths[i + 1], row_height)
|
|
|
|
|
row_index += 1
|
|
|
|
|
queue_redraw()
|
2026-08-12 13:07:52 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
func _process(_delta: float) -> void:
|
2026-08-14 20:32:58 +02:00
|
|
|
for resource_type in GameState.resource_types():
|
2026-08-14 11:54:31 +02:00
|
|
|
var row: Dictionary = _rows.get(resource_type, {})
|
|
|
|
|
if row.is_empty():
|
|
|
|
|
continue
|
|
|
|
|
row.bank.text = str(GameState.banked_resource(resource_type))
|
|
|
|
|
row.fleet.text = str(GameState.fleet_resource(resource_type))
|
|
|
|
|
row.local.text = str(GameState.building_resource(building_id, resource_type)) \
|
|
|
|
|
if building_id != 0 else "—"
|
|
|
|
|
|
|
|
|
|
|
2026-08-12 13:07:52 +02:00
|
|
|
static func natural_height() -> float:
|
2026-08-14 11:54:31 +02:00
|
|
|
return 84.0
|
2026-08-12 13:07:52 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
func _draw() -> void:
|
2026-08-14 11:54:31 +02:00
|
|
|
NeonDraw.draw_glowing_line(self, Vector2(0.0, size.y), Vector2(size.x, size.y),
|
|
|
|
|
RULE_COLOR, 0.55, 1.0)
|