Skip to content

Implement proper timeline ending logic #2536

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 16, 2025
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
36 changes: 23 additions & 13 deletions addons/dialogic/Core/DialogicGameHandler.gd
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ var paused := false:

dialogic_resumed.emit()

## A timeline that will be played when dialog ends.
## By default this timeline only contains a clear event.
var dialog_ending_timeline: DialogicTimeline

## Emitted when [member paused] changes to `true`.
signal dialogic_paused
## Emitted when [member paused] changes to `false`.
Expand Down Expand Up @@ -158,6 +162,9 @@ func _ready() -> void:

clear()

dialog_ending_timeline = DialogicTimeline.new()
dialog_ending_timeline.from_text("[clear]")


#region TIMELINE & EVENT HANDLING
################################################################################
Expand Down Expand Up @@ -242,9 +249,22 @@ func preload_timeline(timeline_resource:Variant) -> Variant:


## Clears and stops the current timeline.
func end_timeline() -> void:
## If [param skip_ending] is `true`, the dialog_ending_timeline is not getting played
func end_timeline(skip_ending := false) -> void:
if not skip_ending and dialog_ending_timeline and current_timeline != dialog_ending_timeline:
start(dialog_ending_timeline)
return

await clear(ClearFlags.TIMELINE_INFO_ONLY)
_on_timeline_ended()

if Styles.has_active_layout_node() and Styles.get_layout_node().is_inside_tree():
match ProjectSettings.get_setting('dialogic/layout/end_behaviour', 0):
0:
Styles.get_layout_node().get_parent().remove_child(Styles.get_layout_node())
Styles.get_layout_node().queue_free()
1:
Styles.get_layout_node().hide()

timeline_ended.emit()


Expand Down Expand Up @@ -368,7 +388,7 @@ func load_full_state(state_info:Dictionary) -> void:
if current_state_info.get('current_timeline', null):
start_timeline(current_state_info.current_timeline, current_state_info.get('current_event_idx', 0))
else:
end_timeline.call_deferred()
end_timeline.call_deferred(true)
#endregion


Expand Down Expand Up @@ -413,16 +433,6 @@ func add_subsystem(subsystem_name:String, script_path:String) -> DialogicSubsyst
#region HELPERS
################################################################################

## This handles the `Layout End Behaviour` setting that can be changed in the Dialogic settings.
func _on_timeline_ended() -> void:
if self.Styles.has_active_layout_node() and self.Styles.get_layout_node().is_inside_tree():
match ProjectSettings.get_setting('dialogic/layout/end_behaviour', 0):
0:
self.Styles.get_layout_node().get_parent().remove_child(self.Styles.get_layout_node())
self.Styles.get_layout_node().queue_free()
1:
@warning_ignore("unsafe_method_access")
self.Styles.get_layout_node().hide()


func print_debug_moment() -> void:
Expand Down
10 changes: 9 additions & 1 deletion addons/dialogic/Modules/Audio/subsystem_audio.gd
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ func update_audio(channel_name:= "", path := "", settings_overrides := {}) -> vo
current_audio_channels[channel_name] = new_player


## Returns true if any audio is playing on the given [param channel_name].
## Returns `true` if any audio is playing on the given [param channel_name].
func is_channel_playing(channel_name: String) -> bool:
return (current_audio_channels.has(channel_name)
and is_instance_valid(current_audio_channels[channel_name])
Expand Down Expand Up @@ -226,6 +226,14 @@ func is_channel_playing_file(file_path: String, channel_name: String) -> bool:
and current_audio_channels[channel_name].stream.resource_path == file_path)


## Returns `true` if any channel is playing.
func is_any_channel_playing() -> bool:
for channel in current_audio_channels:
if is_channel_playing(channel):
return true
return false


func _on_audio_finished(player: AudioStreamPlayer, channel_name: String, path: String) -> void:
if current_audio_channels.has(channel_name) and current_audio_channels[channel_name] == player:
current_audio_channels.erase(channel_name)
Expand Down
9 changes: 5 additions & 4 deletions addons/dialogic/Modules/Clear/event_clear.gd
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ func _execute() -> void:
var time_per_event: float = dialogic.Inputs.auto_skip.time_per_event
final_time = min(time, time_per_event)

if clear_textbox and dialogic.has_subsystem("Text"):
if clear_textbox and dialogic.has_subsystem("Text") and dialogic.Text.is_textbox_visible():
dialogic.Text.update_dialog_text('')
dialogic.Text.hide_textbox()
dialogic.Text.hide_textbox(final_time == 0)
dialogic.current_state = dialogic.States.IDLE
if step_by_step: await dialogic.get_tree().create_timer(final_time).timeout

Expand All @@ -44,9 +44,10 @@ func _execute() -> void:
if step_by_step: await dialogic.get_tree().create_timer(final_time).timeout

if clear_music and dialogic.has_subsystem('Audio'):
dialogic.Audio.stop_all_channels(final_time)
dialogic.Audio.stop_all_one_shot_sounds()
if step_by_step: await dialogic.get_tree().create_timer(final_time).timeout
if dialogic.Audio.is_any_channel_playing():
dialogic.Audio.stop_all_channels(final_time)
if step_by_step: await dialogic.get_tree().create_timer(final_time).timeout

if clear_style and dialogic.has_subsystem('Styles'):
dialogic.Styles.change_style()
Expand Down
2 changes: 1 addition & 1 deletion addons/dialogic/Modules/Jump/event_return.gd
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ extends DialogicEvent
################################################################################

func _execute() -> void:
if !dialogic.Jump.is_jump_stack_empty():
if not dialogic.Jump.is_jump_stack_empty():
dialogic.Jump.resume_from_last_jump()
else:
dialogic.end_timeline()
Expand Down