## Individual tile in the prestige buff graph UI. ## Visually represents a single PrestigeBuffNode with locked/available/unlocked states. ## The PrestigeBuffNode resource is assigned directly via the editor export. class_name PrestigeBuffGraphTile extends PanelContainer ## The prestige buff node this tile represents. Set in the scene editor. @export var prestige_buff: PrestigeBuffNode @onready var _button: Button = $Button @onready var _icon: TextureRect = $Button/HBoxContainer/Icon @onready var _name_label: Label = $Button/HBoxContainer/VBoxContainer/NameLabel @onready var _effect_label: Label = $Button/HBoxContainer/VBoxContainer/EffectLabel @onready var _cost_label: Label = $Button/HBoxContainer/VBoxContainer/CostLabel @onready var _state_label: Label = $Button/HBoxContainer/StateLabel var _game_state: LevelGameState func _ready() -> void: _game_state = find_parent("LevelGameState") _button.pressed.connect(_on_button_pressed) if _game_state: _game_state.prestige_buff_unlocked.connect(_on_prestige_buff_unlocked) _game_state.currency_changed.connect(_on_currency_changed) if prestige_buff == null: push_warning("PrestigeBuffGraphTile: prestige_buff is not set") return _refresh_visuals() _refresh_state() func get_node_id() -> StringName: if prestige_buff: return prestige_buff.id return &"" func _refresh_visuals() -> void: if prestige_buff == null: return _name_label.text = prestige_buff.display_name _cost_label.text = "Cost: %s" % prestige_buff.get_cost().to_string_suffix(2) if prestige_buff.icon: _icon.texture = prestige_buff.icon var effect_text: String = _format_effect_description() _effect_label.text = effect_text _effect_label.visible = not effect_text.is_empty() func _refresh_state() -> void: if prestige_buff == null or _game_state == null: return var unlocked: bool = _game_state.is_prestige_buff_unlocked(prestige_buff.id) var available: bool = _game_state.can_purchase_prestige_buff(prestige_buff.id) if unlocked: _state_label.text = "✓ Unlocked" _button.disabled = true modulate = Color.GREEN elif available: _state_label.text = "Available" _button.disabled = false modulate = Color.WHITE else: _state_label.text = "Locked" _button.disabled = true modulate = Color(0.5, 0.5, 0.5, 1.0) func _format_effect_description() -> String: if prestige_buff == null: return "" match prestige_buff.effect_type: PrestigeBuffNode.EffectType.CURRENCY_PRODUCTION_MULTIPLIER: if prestige_buff.target_id != &"": return "+%.0f%% %s production" % [((prestige_buff.effect_value - 1.0) * 100.0), prestige_buff.target_id] return "+%.0f%% all production" % ((prestige_buff.effect_value - 1.0) * 100.0) PrestigeBuffNode.EffectType.BUILDING_CREATION_BONUS: return "+%.0f%% gain on build" % ((prestige_buff.effect_value - 1.0) * 100.0) PrestigeBuffNode.EffectType.WORKER_THRESHOLD_MULTIPLIER: return "+%.0f%% with 10+ workers" % ((prestige_buff.effect_value - 1.0) * 100.0) PrestigeBuffNode.EffectType.CARRYOVER_BUILDINGS: return "Keep %d buildings on prestige" % int(prestige_buff.effect_value) PrestigeBuffNode.EffectType.UNLOCK_AUTO_BUY_WORKER: return "Unlock auto-buy worker" PrestigeBuffNode.EffectType.HOVER_SPEED_BOOST: return "Hover to speed up workers" PrestigeBuffNode.EffectType.UNLOCK_BUILDING: return "Unlock %s building" % prestige_buff.target_id PrestigeBuffNode.EffectType.WORKER_PRODUCTIVITY: return "+%.0f%% worker productivity" % ((prestige_buff.effect_value - 1.0) * 100.0) PrestigeBuffNode.EffectType.RESEARCH_XP_MULTIPLIER: return "+%.0f%% research XP" % ((prestige_buff.effect_value - 1.0) * 100.0) _: return "" func _on_button_pressed() -> void: if _game_state and prestige_buff: _game_state.purchase_prestige_buff(prestige_buff.id) func _on_prestige_buff_unlocked(buff_id: StringName) -> void: if prestige_buff and buff_id == prestige_buff.id: _refresh_state() func _on_currency_changed(currency_id: StringName, _new_amount: BigNumber) -> void: if _game_state == null or prestige_buff == null: return var asc_id: StringName = _game_state.get_prestige_currency_id() if currency_id == asc_id: _refresh_state()