class_name ResourceBar extends Control # The header every building menu now carries (#24): banked ore, what the # fleet is holding, and what THIS building has. Before this, each panel # improvised its own - the crafter spelled the same three figures into a # run-on StatusLabel string, the research screen printed a bank total inside # a button caption - so the same numbers looked different in every room. # # Three columns rather than a sentence, because the point of the bar is that # a figure stays in the same place as the player moves between menus. # # Reads GameState directly every frame, like ResourceCounter and CargoCounter # do, so it stays correct across the space <-> planet-surface scene swap with # nobody having to push updates into it. Only `building_id` is pushed in, # because "here" is the one thing the bar cannot work out for itself. # Which building the HERE column is reporting. 0 means none, which greys the # column rather than showing a confident zero. var building_id: int = 0 # The caption box has to be a full line tall, not just the font size: a Label # renders its line height, not its point size, and the first version sat the # digits 26px down from the top straight through the middle of the caption. const CAPTION_HEIGHT: float = 34.0 const CAPTION_GAP: float = 4.0 const CAPTION_FONT_SIZE: int = 24 const DIGIT_HEIGHT: float = 34.0 # Bank keeps NeonNumber's own ore-teal, and the hold keeps the amber # CargoCounter established for ore in transit. Only HERE needed a new colour; # it borrows the mothership's green, which already reads as "landed # somewhere and staying there" everywhere else in the game. const BANK_GLOW: Color = Color(0.0, 0.62, 0.7) const BANK_CORE: Color = Color(0.0, 0.12, 0.15) const HOLD_GLOW: Color = Color(1.0, 0.78, 0.25) const HOLD_CORE: Color = Color(0.22, 0.12, 0.0) const HERE_GLOW: Color = Color(0.45, 0.9, 0.55) const HERE_CORE: Color = Color(0.05, 0.16, 0.08) const RULE_COLOR: Color = Color(0.25, 0.55, 0.7) var _numbers: Array[NeonNumber] = [] var _captions: Array[Label] = [] func _ready() -> void: mouse_filter = Control.MOUSE_FILTER_IGNORE var columns: Array = [ ["BANK", BANK_GLOW, BANK_CORE], ["HOLD", HOLD_GLOW, HOLD_CORE], ["HERE", HERE_GLOW, HERE_CORE], ] for column in columns: var caption: Label = Label.new() caption.text = column[0] caption.mouse_filter = Control.MOUSE_FILTER_IGNORE caption.add_theme_font_size_override("font_size", CAPTION_FONT_SIZE) caption.add_theme_color_override("font_color", column[1]) add_child(caption) _captions.append(caption) var number: NeonNumber = NeonNumber.new() number.mouse_filter = Control.MOUSE_FILTER_IGNORE number.glow_color = column[1] number.core_color = column[2] number.digit_height = DIGIT_HEIGHT add_child(number) _numbers.append(number) _layout() resized.connect(_layout) func _layout() -> void: var column_width: float = size.x / float(_numbers.size()) for i in _numbers.size(): var x: float = column_width * float(i) _captions[i].position = Vector2(x, 0.0) _captions[i].size = Vector2(column_width, CAPTION_HEIGHT) # The hexagon and digits are drawn from the node's own origin, so the # number is positioned rather than sized. _numbers[i].position = Vector2(x, CAPTION_HEIGHT + CAPTION_GAP) func _process(_delta: float) -> void: _numbers[0].set_amount(GameState.rocks) _numbers[1].set_amount(GameState.fleet_cargo) # A building with no id is not a building: showing "0" there would claim # the store is empty rather than that there is no store to look at. var known: bool = building_id != 0 _numbers[2].visible = known _captions[2].visible = known if known: _numbers[2].set_amount(GameState.building_holdings(building_id)) # The height the bar needs for a caption line and a row of digits. The scene # sizes the node, so this is what those offsets have to add up to; anything # less and the rule is drawn back through the digits. static func natural_height() -> float: return CAPTION_HEIGHT + CAPTION_GAP + DIGIT_HEIGHT + 8.0 func _draw() -> void: # One rule under the whole bar, so the header reads as a band separating # the standing figures from whatever the panel below them does. var rule_y: float = maxf(size.y, natural_height()) NeonDraw.draw_glowing_line( self, Vector2(0.0, rule_y), Vector2(size.x, rule_y), RULE_COLOR, 0.55, 1.0 )