diff --git a/addons/escoria-core/game/scenes/dialogs/esc_dialog_manager.gd b/addons/escoria-core/game/scenes/dialogs/esc_dialog_manager.gd index f4720633..15307c20 100644 --- a/addons/escoria-core/game/scenes/dialogs/esc_dialog_manager.gd +++ b/addons/escoria-core/game/scenes/dialogs/esc_dialog_manager.gd @@ -69,3 +69,8 @@ func finish(): # The say command has been interrupted, cancel the dialog display func interrupt(): pass + + +# To be called if voice audio has finished. +func voice_audio_finished(): + pass diff --git a/addons/escoria-core/game/scenes/dialogs/state_machine/dialog_say.gd b/addons/escoria-core/game/scenes/dialogs/state_machine/dialog_say.gd index 1a156c9f..da0ff720 100644 --- a/addons/escoria-core/game/scenes/dialogs/state_machine/dialog_say.gd +++ b/addons/escoria-core/game/scenes/dialogs/state_machine/dialog_say.gd @@ -26,6 +26,8 @@ var _keytext_regex: RegEx = RegEx.new() var _ready_to_say: bool +var _stop_talking_animation_on_option: String + # Constructor func _init() -> void: @@ -36,6 +38,8 @@ func initialize(character: String, type: String, text: String) -> void: _character = character _type = type _text = text + _stop_talking_animation_on_option = \ + ESCProjectSettingsManager.get_setting(SimpleDialogPlugin.STOP_TALKING_ANIMATION_ON) func handle_input(_event): @@ -125,6 +129,12 @@ func enter(): as ESCSpeechPlayer ).set_state(_speech_resource) + if _stop_talking_animation_on_option == SimpleDialogPlugin.STOP_TALKING_ANIMATION_ON_END_OF_AUDIO: + ( + escoria.object_manager.get_object(escoria.object_manager.SPEECH).node\ + as ESCSpeechPlayer + ).stream.connect("finished", self, "_on_audio_finished", [], CONNECT_ONESHOT) + var translated_text: String = tr(matches.get_string("key")) # Only update the text if the translated text was found; otherwise, raise @@ -189,3 +199,7 @@ func _get_voice_file(key: String, start: String = "") -> String: func _on_say_visible() -> void: escoria.logger.trace(self, "Dialog State Machine: 'say' -> 'visible'") emit_signal("finished", "visible") + + +func _on_audio_finished() -> void: + _dialog_manager.voice_audio_finished() diff --git a/addons/escoria-dialog-simple/esc_dialog_simple.gd b/addons/escoria-dialog-simple/esc_dialog_simple.gd index b06b50fc..912bb5fa 100644 --- a/addons/escoria-dialog-simple/esc_dialog_simple.gd +++ b/addons/escoria-dialog-simple/esc_dialog_simple.gd @@ -112,3 +112,9 @@ func interrupt(): _dialog_player.remove_child(_type_player) emit_signal("say_finished") + + +# To be called if voice audio has finished. +func voice_audio_finished(): + if _type_player != null: + _type_player.voice_audio_finished() diff --git a/addons/escoria-dialog-simple/plugin.gd b/addons/escoria-dialog-simple/plugin.gd index e9fcbb31..389c8407 100644 --- a/addons/escoria-dialog-simple/plugin.gd +++ b/addons/escoria-dialog-simple/plugin.gd @@ -13,11 +13,15 @@ const TEXT_TIME_PER_LETTER_MS_FAST = "%s/text_time_per_fast_letter_ms" % SETTING const READING_SPEED_IN_WPM = "%s/reading_speed_in_wpm" % SETTINGS_ROOT const CLEAR_TEXT_BY_CLICK_ONLY = "%s/clear_text_by_click_only" % SETTINGS_ROOT const LEFT_CLICK_ACTION = "%s/left_click_action" % SETTINGS_ROOT +const STOP_TALKING_ANIMATION_ON = "%s/stop_talking_animation_on" % SETTINGS_ROOT const LEFT_CLICK_ACTION_SPEED_UP = "Speed up" const LEFT_CLICK_ACTION_INSTANT_FINISH = "Instant finish" const LEFT_CLICK_ACTION_NOTHING = "None" +const STOP_TALKING_ANIMATION_ON_END_OF_TEXT = "End of text" +const STOP_TALKING_ANIMATION_ON_END_OF_AUDIO = "End of audio" + const READING_SPEED_IN_WPM_DEFAULT_VALUE = 200 const TEXT_TIME_PER_LETTER_MS_DEFAULT_VALUE = 100 const TEXT_TIME_PER_LETTER_MS_FAST_DEFAULT_VALUE = 25 @@ -29,6 +33,11 @@ var leftClickActions: Array = [ LEFT_CLICK_ACTION_NOTHING ] +var stopTalkingAnimationOnOptions: Array = [ + STOP_TALKING_ANIMATION_ON_END_OF_TEXT, + STOP_TALKING_ANIMATION_ON_END_OF_AUDIO +] + # Override function to return the plugin name. func get_plugin_name(): @@ -65,6 +74,10 @@ func disable_plugin(): ESCProjectSettingsManager.remove_setting( LEFT_CLICK_ACTION ) + + ESCProjectSettingsManager.remove_setting( + STOP_TALKING_ANIMATION_ON + ) EscoriaPlugin.deregister_dialog_manager(MANAGER_CLASS) @@ -127,7 +140,7 @@ func enable_plugin(): ESCProjectSettingsManager.register_setting( LEFT_CLICK_ACTION, - "Speed up", + LEFT_CLICK_ACTION_SPEED_UP, { "type": TYPE_STRING, "hint": PROPERTY_HINT_ENUM, @@ -135,6 +148,18 @@ func enable_plugin(): } ) + var stopTalkingAnimationOnOptionsString: String = ",".join(stopTalkingAnimationOnOptions) + + ESCProjectSettingsManager.register_setting( + STOP_TALKING_ANIMATION_ON, + STOP_TALKING_ANIMATION_ON_END_OF_AUDIO, + { + "type": TYPE_STRING, + "hint": PROPERTY_HINT_ENUM, + "hint_string": stopTalkingAnimationOnOptionsString + } + ) + else: get_editor_interface().set_plugin_enabled( get_plugin_name(), diff --git a/addons/escoria-dialog-simple/types/avatar.gd b/addons/escoria-dialog-simple/types/avatar.gd index 383dd9be..e4e11578 100644 --- a/addons/escoria-dialog-simple/types/avatar.gd +++ b/addons/escoria-dialog-simple/types/avatar.gd @@ -174,9 +174,20 @@ func finish(): tween.start() +# To be called if voice audio has finished. +func voice_audio_finished(): + if avatar_node and avatar_node.texture: + avatar_node.texture.current_frame = 0 + avatar_node.texture.pause = true + + # The dialog line was printed, start the waiting time and then finish # the dialog func _on_dialog_line_typed(object, key): + if avatar_node.texture is AnimatedTexture: + avatar_node.texture.current_frame = 0 + avatar_node.texture.pause = true + text_node.visible_characters = -1 var time_to_disappear: float = _calculate_time_to_disappear() @@ -196,10 +207,6 @@ func _get_number_of_words() -> int: # Ending the dialog func _on_dialog_finished(): - if avatar_node.texture is AnimatedTexture: - avatar_node.texture.current_frame = 0 - avatar_node.texture.pause = true - # Only trigger to clear the text if we aren't limiting the clearing trigger to a click. if not ESCProjectSettingsManager.get_setting(SimpleDialogPlugin.CLEAR_TEXT_BY_CLICK_ONLY): emit_signal("say_finished") @@ -218,3 +225,5 @@ func _on_resumed(): if not tween.is_active(): is_paused = false tween.resume_all() + + diff --git a/addons/escoria-dialog-simple/types/floating.gd b/addons/escoria-dialog-simple/types/floating.gd index dff2ca4b..c1adf6bf 100644 --- a/addons/escoria-dialog-simple/types/floating.gd +++ b/addons/escoria-dialog-simple/types/floating.gd @@ -198,9 +198,15 @@ func finish(): tween.start() +# To be called if voice audio has finished. +func voice_audio_finished(): + _stop_character_talking() + + # The dialog line was printed, start the waiting time and then finish # the dialog func _on_dialog_line_typed(object, key): + _stop_character_talking() text_node.visible_characters = -1 var time_to_disappear: float = _calculate_time_to_disappear() @@ -220,8 +226,6 @@ func _get_number_of_words() -> int: # Ending the dialog func _on_dialog_finished(): - _stop_character_talking() - # Only trigger to clear the text if we aren't limiting the clearing trigger to a click. if not ESCProjectSettingsManager.get_setting(SimpleDialogPlugin.CLEAR_TEXT_BY_CLICK_ONLY): emit_signal("say_finished")