Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 32 additions & 7 deletions scenes/world_map/components/retelling_manager.gd
Original file line number Diff line number Diff line change
Expand Up @@ -9,38 +9,63 @@ 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] = []

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())

# 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]

_start_townie_after_delay(townie, delay)


func _start_townie_after_delay(townie: RetellingTownie, delay: float) -> void:
townie.loom_reached.connect(_on_loom_reached, CONNECT_ONE_SHOT | CONNECT_APPEND_SOURCE_OBJECT)

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()

Expand Down
29 changes: 25 additions & 4 deletions scenes/world_map/components/retelling_townie.gd
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,18 @@ 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))

reversed_path.curve = curve
return reversed_path


func _ready() -> void:
if Engine.is_editor_hint():
return

hide_townie()


Expand All @@ -48,18 +51,29 @@ 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

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()
Expand All @@ -72,16 +86,21 @@ 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

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

Expand All @@ -98,5 +117,7 @@ func leave_the_loom() -> void:

path_walk_behavior.walking_path = leave_path
path_walk_behavior.process_mode = Node.PROCESS_MODE_INHERIT

await path_walk_behavior.ending_reached

hide_townie()