extends VBoxContainer const GENERATOR_BUFF_TILE_SCENE: PackedScene = preload("res://generator_buff_tile.tscn") class BuffRow extends RefCounted: var buff: GeneratorBuffData var tile: GeneratorBuffTile func _init(row_buff: GeneratorBuffData, row_tile: GeneratorBuffTile) -> void: buff = row_buff tile = row_tile @export var _generator: CurrencyGenerator @onready var _buy_button: Button = $HBoxContainerGenerators/BuyOneButton @onready var _buy_max_button: Button = $HBoxContainerGenerators/BuyMaxButton @onready var _name_label: Label = $Label @onready var _owned_value: Label = $GeneratorStatsGrid/OwnedValue @onready var _next_cost_value: Label = $GeneratorStatsGrid/NextCostValue @onready var _production_value: Label = $GeneratorStatsGrid/ProductionValue @onready var _buffs_section: VBoxContainer = $BuffsSection @onready var _buffs_list: VBoxContainer = $BuffsSection/BuffsList var _buff_rows: Array[BuffRow] = [] func _ready() -> void: if _generator == null: push_warning("GeneratorContainer '%s' has no generator assigned." % String(name)) return _generator.purchase_completed.connect(_on_generator_updated) _generator.production_tick.connect(_on_generator_updated) _generator.purchase_failed.connect(_on_generator_updated) _generator.buff_purchased.connect(_on_generator_updated) _generator.buff_purchase_failed.connect(_on_generator_updated) GameState.currency_changed.connect(_on_currency_changed) GameState.generator_state_changed.connect(_on_generator_state_changed) GameState.generator_buff_level_changed.connect(_on_generator_buff_level_changed) _name_label.text = _generator.data.name if _generator.data != null else "Generator" _build_buff_rows() _refresh_generator_ui() func _on_buy_pressed() -> void: _generator.buy(1) _refresh_generator_ui() func _on_buy_max_pressed() -> void: _generator.buy_max() _refresh_generator_ui() func _on_debug_income_pressed() -> void: _generator.grant_currency(BigNumber.from_float(100.0)) _refresh_generator_ui() func _on_currency_changed(_changed_currency_id: StringName, _new_value: BigNumber) -> void: _refresh_generator_ui() func _on_generator_updated(_a = null, _b = null, _c = null, _d = null) -> void: _refresh_generator_ui() func _on_generator_state_changed(generator_id: StringName, _state: Dictionary) -> void: if generator_id == _generator.get_generator_id(): visible = true _refresh_generator_ui() func _on_generator_buff_level_changed(generator_id: StringName, _buff_id: StringName, _new_level: int) -> void: if generator_id != _generator.get_generator_id(): return _refresh_generator_ui() func _on_buy_buff_pressed(buff_id: StringName) -> void: _generator.buy_buff(buff_id) _refresh_generator_ui() func _build_buff_rows() -> void: _buff_rows.clear() for child in _buffs_list.get_children(): child.queue_free() for buff in _generator.get_buffs(): if buff == null: continue var buff_id_text: String = String(buff.id).strip_edges() if buff_id_text.is_empty(): continue var tile: GeneratorBuffTile = GENERATOR_BUFF_TILE_SCENE.instantiate() as GeneratorBuffTile if tile == null: push_warning("Failed to instantiate GeneratorBuffTile for buff '%s'." % buff_id_text) continue _buffs_list.add_child(tile) tile.set_buff(buff) tile.buy_pressed.connect(_on_buy_buff_pressed) _buff_rows.append(BuffRow.new(buff, tile)) func _refresh_buff_rows(can_interact: bool) -> void: _buffs_section.visible = not _buff_rows.is_empty() if _buff_rows.is_empty(): return for row in _buff_rows: if row == null or row.buff == null or row.tile == null: continue var buff: GeneratorBuffData = row.buff var level: int = _generator.get_buff_level(buff.id) var effect_text: String = buff.get_effect_description(level) if _generator.is_buff_maxed(buff.id): row.tile.set_runtime(level, effect_text, "", false, true) continue var cost: BigNumber = _generator.get_buff_cost(buff.id) var cost_currency_id: StringName = _generator.get_buff_cost_currency_id(buff.id) var currency_label: String = GameState.get_currency_name(cost_currency_id) var cost_text: String = "%s %s" % [cost.to_string_suffix(2), currency_label] var can_buy: bool = can_interact and _generator.can_buy_buff(buff.id) row.tile.set_runtime(level, effect_text, cost_text, can_buy, false) func _refresh_generator_ui() -> void: var can_interact: bool = _generator.is_available_to_player() _buy_button.disabled = not can_interact _buy_max_button.disabled = not can_interact _owned_value.text = str(_generator.owned) _next_cost_value.text = _generator.get_next_cost().to_string_suffix(2) if can_interact else "-" var production_per_second: float = 0.0 if _generator.data != null and can_interact: production_per_second = _generator.data.production_per_second( _generator.owned, _generator.run_multiplier * _generator.get_automatic_production_multiplier(), _generator.purchased_count ) _production_value.text = BigNumber.from_float(production_per_second).to_string_suffix(2) _refresh_buff_rows(can_interact)