diff --git a/scenes/world_map/components/retelling_manager.gd b/scenes/world_map/components/retelling_manager.gd index 524ff96c3..5fab68b39 100644 --- a/scenes/world_map/components/retelling_manager.gd +++ b/scenes/world_map/components/retelling_manager.gd @@ -9,10 +9,10 @@ extends Node2D ## ## Coordinate an array of townies to join the StoryWeaver at the Eternal Loom ## for listening the retelling. -## Call [member RetellingTownie.go_to_the_loom()] on each townie so they join. -## Call [member EternalLoom.show_retelling_dialogue()] when all townies have joined. -## May call [member RetellingTownie.become_helper()] on one townie (at random). -## Call [member RetellingTownie.leave_the_loom()] on each townie so they leave. +## Call [method RetellingTownie.go_to_the_loom]on each townie so they join. +## Call [method EternalLoom.show_retelling_dialogue] when all townies have joined. +## May call [method RetellingTownie.become_helper] on one townie (at random). +## Call [method RetellingTownie.leave_the_loom] on each townie so they leave. ## The array of retelling townies in Fray's End. @export var townies: Array[RetellingTownie] = [] @@ -20,27 +20,68 @@ extends Node2D var _waiting_for_townies: Array[RetellingTownie] = [] ## The Eternal Loom, for listening to signals and calling -## [member EternalLoom.show_retelling_dialogue()]. +## [method EternalLoom.show_retelling_dialogue]. @onready var eternal_loom: EternalLoom = %EternalLoom func _ready() -> void: if Engine.is_editor_hint(): return + eternal_loom.retelling_started.connect(_on_eternal_loom_retelling_started) eternal_loom.retelling_finished.connect(_on_eternal_loom_retelling_finished) eternal_loom.give_retelling_upgrade.connect(_on_eternal_loom_give_retelling_upgrade) - - + func _on_eternal_loom_retelling_started() -> void: _waiting_for_townies = townies.duplicate() + + var travel_times: Array[float] = [] + + # Prepare each townie and calculate its travel time. for t: RetellingTownie in townies: - t.go_to_the_loom() - t.loom_reached.connect(_on_loom_reached.bind(t)) + var travel_time: float = t.prepare_walk() + travel_times.append(travel_time) + + # The slowest townie determines the target arrival time. + var target_time: float = float(travel_times.max()) + + print("================================") + print("Tiempo objetivo: ", target_time, " s") + print("================================") + + # Start each townie with a delay so they arrive together. + for i in range(townies.size()): + var townie: RetellingTownie = townies[i] + var delay: float = target_time - travel_times[i] + + print( + "Townie: ", + townie.name, + " | Retraso: ", + delay, + " s" + ) + + _start_townie_after_delay(townie, delay) + + +func _start_townie_after_delay( + townie: RetellingTownie, + delay: float +) -> void: + # Connect before starting the townie so the arrival signal is captured. + if not townie.loom_reached.is_connected(_on_loom_reached.bind(townie)): + townie.loom_reached.connect(_on_loom_reached.bind(townie)) + + if delay > 0.0: + await get_tree().create_timer(delay).timeout + + townie.go_to_the_loom() func _on_loom_reached(townie: RetellingTownie) -> void: _waiting_for_townies.erase(townie) + if _waiting_for_townies.size() == 0: eternal_loom.show_retelling_dialogue() @@ -50,6 +91,8 @@ func _on_eternal_loom_retelling_finished() -> void: t.leave_the_loom() -func _on_eternal_loom_give_retelling_upgrade(type: InventoryItem.ItemType) -> void: +func _on_eternal_loom_give_retelling_upgrade( + type: InventoryItem.ItemType +) -> void: var t: RetellingTownie = townies.pick_random() t.become_helper(type) diff --git a/scenes/world_map/components/retelling_townie.gd b/scenes/world_map/components/retelling_townie.gd index 0a87231f0..1fe2cdf8f 100644 --- a/scenes/world_map/components/retelling_townie.gd +++ b/scenes/world_map/components/retelling_townie.gd @@ -30,8 +30,14 @@ static func reverse_path(path: Path2D) -> Path2D: var reversed_path := Path2D.new() var curve := Curve2D.new() var src := path.curve + for i in range(src.point_count - 1, -1, -1): - curve.add_point(src.get_point_position(i), src.get_point_out(i), src.get_point_in(i)) + curve.add_point( + src.get_point_position(i), + src.get_point_out(i), + src.get_point_in(i) + ) + reversed_path.curve = curve return reversed_path @@ -39,6 +45,7 @@ static func reverse_path(path: Path2D) -> Path2D: func _ready() -> void: if Engine.is_editor_hint(): return + hide_townie() @@ -48,18 +55,34 @@ func hide_townie() -> void: townie.process_mode = Node.PROCESS_MODE_DISABLED -## Walk the path to the loom and then emit [member loom_reached]. -func go_to_the_loom() -> void: +## Prepare the townie's walking speed and calculate its travel time. +func prepare_walk() -> float: path_walk_behavior.walking_path = enter_path - # Randomize the speed of each townie, for variation: + # Randomize the speed of each townie. path_walk_behavior.speeds = CharacterSpeeds.new() - path_walk_behavior.speeds.walk_speed = randf_range(100, 200) + path_walk_behavior.speeds.walk_speed = randf_range(175, 264) + + var path_distance: float = enter_path.curve.get_baked_length() + var walk_speed: float = path_walk_behavior.speeds.walk_speed + var travel_time: float = path_distance / walk_speed + print("Townie: ", name) + print("Distancia: ", path_distance, " px") + print("Velocidad: ", walk_speed, " px/s") + print("Tiempo estimado: ", travel_time, " s") + + return travel_time + + +## Walk the path to the loom and then emit loom_reached. +func go_to_the_loom() -> void: townie.randomize_character() townie.visible = true townie.process_mode = Node.PROCESS_MODE_INHERIT + await path_walk_behavior.ending_reached + path_walk_behavior.process_mode = Node.PROCESS_MODE_DISABLED townie.velocity = Vector2.ZERO loom_reached.emit() @@ -72,16 +95,23 @@ func become_helper(type: InventoryItem.ItemType) -> void: var closer_path := Path2D.new() enter_path.add_sibling(closer_path) closer_path.global_position = enter_path.global_position + var curve := Curve2D.new() curve.add_point(Vector2.ZERO) + var player := get_tree().get_first_node_in_group("player") as Node2D - _closer_to_player_position = townie.global_position.direction_to(player.global_position) * 100.0 + _closer_to_player_position = townie.global_position.direction_to( + player.global_position + ) * 100.0 + curve.add_point(_closer_to_player_position) closer_path.curve = curve path_walk_behavior.walking_path = closer_path path_walk_behavior.process_mode = Node.PROCESS_MODE_INHERIT + await path_walk_behavior.ending_reached + path_walk_behavior.process_mode = Node.PROCESS_MODE_DISABLED townie.velocity = Vector2.ZERO @@ -94,9 +124,16 @@ func leave_the_loom() -> void: leave_path.global_position = enter_path.global_position if _closer_to_player_position: - leave_path.curve.add_point(_closer_to_player_position, Vector2.ZERO, Vector2.ZERO, 0) + leave_path.curve.add_point( + _closer_to_player_position, + Vector2.ZERO, + Vector2.ZERO, + 0 + ) path_walk_behavior.walking_path = leave_path path_walk_behavior.process_mode = Node.PROCESS_MODE_INHERIT + await path_walk_behavior.ending_reached + hide_townie()