## Single-goal tile showing the current (first uncompleted) goal from GoalCatalogue. ## Mirrors a single row from goals_debug_ui: goal name, requirements text, and a resolve button. extends PanelContainer @onready var _game_state: LevelGameState = find_parent("LevelGameState") @onready var _goal_label: Label = $VBoxContainer/GoalLabel @onready var _requirements_label: Label = $VBoxContainer/RequirementsLabel @onready var _resolve_button: Button = $VBoxContainer/ResolveButton var _current_goal: GoalData func _ready() -> void: _resolve_button.pressed.connect(_on_resolve_pressed) if _game_state: _game_state.currency_changed.connect(_on_currency_changed) _game_state.generator_state_changed.connect(_on_generator_state_changed) _game_state.goal_completed.connect(_on_goal_completed) if not _game_state.goal_catalogue or _game_state.goal_catalogue.goals.is_empty(): _game_state.ready.connect(_on_level_state_ready) _refresh_current_goal() _refresh_ui() _refresh_ui.call_deferred() func _get_current_goal() -> GoalData: if _game_state == null: return null var catalogue: GoalCatalogue = _game_state.goal_catalogue if catalogue == null: return null for goal in catalogue.goals: if goal == null: continue if not goal.has_id(): continue if _game_state.is_goal_completed(goal.id): continue return goal return null func _refresh_current_goal() -> void: _current_goal = _get_current_goal() func _refresh_ui() -> void: if _current_goal == null: _goal_label.text = "All goals complete!" _requirements_label.text = "" _resolve_button.disabled = true _resolve_button.text = "Done" return _goal_label.text = String(_current_goal.id) if _game_state == null: return var already_completed: bool = _game_state.is_goal_completed(_current_goal.id) _requirements_label.text = _get_requirements_text(_current_goal) var met: bool = _game_state.is_goal_met(_current_goal) var can_click: bool = met and not already_completed _resolve_button.disabled = not can_click _resolve_button.text = "Done" if already_completed else "Resolve" func _get_requirements_text(goal: GoalData) -> String: if goal == null or _game_state == null: return "" var parts: Array[String] = [] for req in goal.get_requirements(): if req == null: continue var currency: Currency = req.get_currency() if currency == null: continue var currency_id: StringName = _game_state.get_currency_id(currency) var total_amount: BigNumber = _game_state.get_total_currency_acquired_by_id(currency_id) var required_amount: BigNumber = req.get_amount() var currency_name: String = _game_state.get_currency_name(currency_id) parts.append( "%s %s / %s" % [ currency_name, total_amount.to_string_suffix(2), required_amount.to_string_suffix(2), ] ) if parts.is_empty(): return "No requirements" return " | ".join(parts) func _on_resolve_pressed() -> void: if _current_goal == null: return if _game_state == null: return if _game_state.is_goal_completed(_current_goal.id): return if not _game_state.is_goal_met(_current_goal): return if _current_goal.unlock_behavior == GoalData.UnlockBehavior.MANUAL: _game_state._complete_goal_manually(_current_goal.id) _refresh_current_goal() _refresh_ui() func _on_currency_changed(_currency_id: StringName, _new_amount: BigNumber) -> void: _refresh_current_goal() _refresh_ui() func _on_generator_state_changed(_generator_id: StringName, _state: Dictionary) -> void: _refresh_current_goal() _refresh_ui() func _on_goal_completed(_goal_id: StringName) -> void: _refresh_current_goal() _refresh_ui() func _on_level_state_ready() -> void: if _game_state: _game_state.ready.disconnect(_on_level_state_ready) _refresh_current_goal() _refresh_ui() func _exit_tree() -> void: if _game_state: if _game_state.currency_changed.is_connected(_on_currency_changed): _game_state.currency_changed.disconnect(_on_currency_changed) if _game_state.generator_state_changed.is_connected(_on_generator_state_changed): _game_state.generator_state_changed.disconnect(_on_generator_state_changed) if _game_state.goal_completed.is_connected(_on_goal_completed): _game_state.goal_completed.disconnect(_on_goal_completed) if _game_state.ready.is_connected(_on_level_state_ready): _game_state.ready.disconnect(_on_level_state_ready)