class_name QuestProgressBar extends Control const waypoint_template = preload("res://templates/waypoint.tscn") var length : float var waypoints : Array[Waypoint] = [] @onready var hero_offset : Vector2 = %Hero.position @onready var hero : HeroIcon = %Hero @onready var heroLabel : Label = %HeroLabel @onready var startpoint : Endpoint = %Start @onready var endpoint : Endpoint = %End @onready var bar : TextureProgressBar = $ProgressBar @onready var path : Control = %Path @onready var speech_bubble = %SpeechBubble var quest : Quest = null var current_event : Quest.Event = null var time_elapsed : float = 0 var next_waypoint = 0 var failed : bool = false #signal value_changed(value : float) #var min_value #var max_value #var step #var page #var value #var exp_edit #var rounded #var allow_greater func _ready() -> void: length = path.size.x hero.position = hero_offset + Vector2(length * bar.value / bar.max_value, 0) func _process(delta: float) -> void: if failed: return if time_elapsed < quest.length: if current_event != null: current_event.process(delta) else: time_elapsed += delta progress_quest() func generate_waypoints(): if len(waypoints) > 0: for wp in waypoints: wp.queue_free() waypoints = [] #Include the "end" in the count var num = quest.num_events() #add_waypoint(0, Quest.Event.new()) #waypoints[0]. for evt : Quest.Event in quest.events: add_waypoint( evt.progress_point, evt) #add_waypoint(1, Quest.Event.new()) func add_waypoint(pct : float, event : Quest.Event): var wp = waypoint_template.instantiate() waypoints.append(wp) wp.percent = pct #TODO: Make events matter wp.event = event %Waypoints.add_child(wp) if event.hidden: wp.visible = false wp.global_position = %Waypoints.global_position + Vector2(pct * length - 16, -9) if bar.value / bar.max_value >= pct: wp.fill = true func update_waypoints(value : float) -> void: startpoint.fill = (bar.value / bar.max_value >= startpoint.percent) for wp : Waypoint in waypoints: wp.fill = (bar.value / bar.max_value >= wp.percent) endpoint.fill = (bar.value / bar.max_value >= endpoint.percent) func start_event(event : Quest.Event, offset : float) -> void: current_event = event current_event.completed.connect(_on_event_complete) current_event.failed.connect(_on_event_failed) current_event.start(quest) event.time_elapsed = offset func setup(quest : Quest) -> void: self.quest = quest heroLabel.text = quest.questor.full_name() time_elapsed = 0 #Generate the waypoints generate_waypoints() #TODO: Change the hero's portrait bar.value = quest.progress func progress_quest() -> void: var pct = time_elapsed / quest.length quest.progress = pct if next_waypoint < len(waypoints) and pct >= waypoints[next_waypoint].percent: if waypoints[next_waypoint].visible == false: waypoints[next_waypoint].visible = true start_event(waypoints[next_waypoint].event, (pct - waypoints[next_waypoint].percent) * quest.length) pct = waypoints[next_waypoint].percent waypoints[next_waypoint].blink(true) bar.value = clampf(pct, 0, bar.max_value) hero.position = hero_offset + Vector2(length * bar.value / bar.max_value, 0) if time_elapsed >= quest.length: quest.complete() update_waypoints(bar.value) func set_fill_color(color : Color) -> void: %Start/Fill.self_modulate = color %End/Fill.self_modulate = color $ProgressBar.tint_progress = color for wp : Waypoint in waypoints: wp.fill_color = color func _on_event_complete() -> void: #TODO: Show event message! speech_bubble.show_message("Event complete!") if current_event.type == Quest.Event.Type.COMBAT: quest.questview.unpause_setting() for p : QuestorSprite in current_event.participants: p.set_animation("running") waypoints[next_waypoint].blink(false) next_waypoint += 1 current_event = null func _on_event_failed() -> void: failed = true set_fill_color(Color.RED) quest.fail()