class_name QuestJournalHud extends Control const ENTER_OFFSET := 8.0 const THANKS_SECONDS := 3.4 @export var simulation_manager: Node @onready var accent: ColorRect = $Accent @onready var copy: VBoxContainer = $Copy @onready var standing_label: Label = $Copy/Standing @onready var quest_label: Label = $Copy/Quest @onready var quest_kicker: Label = $Copy/QuestKicker @onready var thanks_label: Label = $Copy/Thanks var resting_position: Vector2 var feedback_version := 0 var feedback_tween: Tween var journal_tween: Tween func _ready() -> void: resting_position = position visible = false modulate.a = 0.0 if simulation_manager == null: push_error("QuestJournalHud: simulation_manager missing") return if simulation_manager.has_signal("player_quest_opened"): simulation_manager.player_quest_opened.connect(_on_quest_opened) if simulation_manager.has_signal("player_quest_completed"): simulation_manager.player_quest_completed.connect(_on_quest_completed) if simulation_manager.has_signal("player_quest_expired"): simulation_manager.player_quest_expired.connect(_on_quest_expired) if simulation_manager.has_signal("player_standing_changed"): simulation_manager.player_standing_changed.connect(_on_standing_changed) if simulation_manager.has_signal("opportunity_resolved"): simulation_manager.opportunity_resolved.connect(_on_opportunity_resolved) if simulation_manager.has_signal("state_restored"): simulation_manager.state_restored.connect(_on_state_restored) _refresh() func _on_quest_opened(_quest: PlayerQuestRecord) -> void: _refresh() func _on_quest_expired(_quest: PlayerQuestRecord) -> void: _refresh() func _on_standing_changed(_standing: PlayerStandingRecord) -> void: _refresh() func _on_opportunity_resolved( _opportunity: OpportunityStateRecord, _cause_event: EconomicEventRecord ) -> void: _refresh() func _on_state_restored() -> void: _refresh() func _refresh() -> void: if simulation_manager == null: return var standing: PlayerStandingRecord = simulation_manager.get_player_standing() if standing == null: return var standing_text := ( "Standing · %s · %.0f/100" % [standing.get_tier_name(), standing.get_standing()] ) standing_label.text = standing_text var quest: PlayerQuestRecord = simulation_manager.get_active_player_quest() if quest == null: quest_kicker.text = "" quest_label.text = "" else: var requester_name := _get_npc_name(quest.get_requester_npc_id()) quest_kicker.text = "ACTIVE QUEST" quest_label.text = ( "%s · bring %.0f %s to the %s" % [ requester_name, quest.get_target_amount(), String(quest.get_resource_id()).replace("_", " "), String(quest.get_target_id()).replace("_", " "), ] ) var has_content := not quest_kicker.text.is_empty() or not standing_text.is_empty() if not has_content: return if not visible: visible = true modulate.a = 0.0 position = resting_position + Vector2(0.0, ENTER_OFFSET) if journal_tween != null and journal_tween.is_valid(): journal_tween.kill() journal_tween = create_tween().set_parallel(true) journal_tween.set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_OUT) journal_tween.tween_property(self, "position", resting_position, 0.3) journal_tween.tween_property(self, "modulate:a", 1.0, 0.22) func _on_quest_completed(quest: PlayerQuestRecord) -> void: _refresh() var requester_name := _get_npc_name(quest.get_requester_npc_id()) _show_thanks( "Gratitude", ( "%s thanks you for your help. +%.0f Standing" % [requester_name, quest.get_standing_reward()] ) ) func _show_thanks(heading: String, message: String) -> void: feedback_version += 1 var version := feedback_version if feedback_tween != null and feedback_tween.is_valid(): feedback_tween.kill() thanks_label.text = "%s\n%s" % [heading, message] thanks_label.visible = true thanks_label.modulate.a = 0.0 feedback_tween = create_tween().set_parallel(true) feedback_tween.set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_OUT) feedback_tween.tween_property(thanks_label, "modulate:a", 1.0, 0.3) feedback_tween.chain().tween_interval(THANKS_SECONDS) feedback_tween.chain().tween_property(thanks_label, "modulate:a", 0.0, 0.5) feedback_tween.chain().tween_callback( func() -> void: if version == feedback_version: thanks_label.visible = false ) func _get_npc_name(npc_id: int) -> String: for npc in simulation_manager.npcs: if npc.id == npc_id: return npc.npc_name return "Someone"