extends "res://addons/escoria-dialog-simple/patterns/state_machine/state.gd" # A regular expression that separates the translation key from the text const KEYTEXT_REGEX = "^((?[^:]+):)?\"(?.+)\"" # Reference to the currently playing dialog manager var _dialog_manager: ESCDialogManager = null # Character that is talking var _character: String # UI to use for the dialog var _type: String # Text to say var _text: String # Regular expression object for the separation of key and text var _keytext_regex: RegEx = RegEx.new() var _ready_to_say: bool var _stop_talking_animation_on_option: String # Constructor func _init() -> void: _keytext_regex.compile(KEYTEXT_REGEX) func initialize(dialog_manager: ESCDialogManager, character: String, text: String, type: String) -> void: _dialog_manager = dialog_manager _character = character _text = text _type = type _stop_talking_animation_on_option = \ ESCProjectSettingsManager.get_setting(SimpleDialogSettings.STOP_TALKING_ANIMATION_ON) func handle_input(_event): if _event is InputEventMouseButton and _event.pressed: if escoria.inputs_manager.input_mode != \ escoria.inputs_manager.INPUT_NONE and \ _dialog_manager != null: var left_click_action = ESCProjectSettingsManager.get_setting(SimpleDialogSettings.LEFT_CLICK_ACTION) _handle_left_click_action(left_click_action) func _handle_left_click_action(left_click_action: String) -> void: match left_click_action: SimpleDialogSettings.LEFT_CLICK_ACTION_SPEED_UP: if _dialog_manager.is_connected("say_visible", self, "_on_say_visible"): _dialog_manager.disconnect("say_visible", self, "_on_say_visible") escoria.logger.trace(self, "Dialog State Machine: 'say' -> 'say_fast'") emit_signal("finished", "say_fast") SimpleDialogSettings.LEFT_CLICK_ACTION_INSTANT_FINISH: if _dialog_manager.is_connected("say_visible", self, "_on_say_visible"): _dialog_manager.disconnect("say_visible", self, "_on_say_visible") escoria.logger.trace(self, "Dialog State Machine: 'say' -> 'say_finish'") emit_signal("finished", "say_finish") get_tree().set_input_as_handled() func enter(): escoria.logger.trace(self, "Dialog State Machine: Entered 'say'.") if not _dialog_manager.is_connected("say_visible", self, "_on_say_visible"): _dialog_manager.connect("say_visible", self, "_on_say_visible") var matches = _keytext_regex.search(_text) if not matches: escoria.logger.error( self, "Unexpected text encountered: %s." % _text ) var key = matches.get_string("key") if matches.get_string("key") != "": var _speech_resource = _get_voice_file( matches.get_string("key") ) if _speech_resource == "": escoria.logger.warn( self, "Unable to find voice file with key '%s'." % matches.get_string("key") ) else: ( escoria.object_manager.get_object(escoria.object_manager.SPEECH).node\ as ESCSpeechPlayer ).set_state(_speech_resource) if _stop_talking_animation_on_option == SimpleDialogSettings.STOP_TALKING_ANIMATION_ON_END_OF_AUDIO: if not ( escoria.object_manager.get_object(escoria.object_manager.SPEECH).node\ as ESCSpeechPlayer ).stream.is_connected("finished", self, "_on_audio_finished"): ( escoria.object_manager.get_object(escoria.object_manager.SPEECH).node\ as ESCSpeechPlayer ).stream.connect("finished", self, "_on_audio_finished") var translated_text: String = tr(matches.get_string("key")) # Only update the text if the translated text was found; otherwise, raise # a warning and use the original, untranslated text. if translated_text == matches.get_string("key"): escoria.logger.warn( self, "Unable to find translation key '%s'. Using untranslated text." % matches.get_string("key") ) _text = matches.get_string("text") else: _text = translated_text else: _text = matches.get_string("text") _ready_to_say = true func update(_delta): if _ready_to_say: _dialog_manager.do_say(_character, _text) _ready_to_say = false # Find the matching voice output file for the given key # # #### Parameters # # - key: Text key provided # - start: Starting folder to search for voices # # *Returns* The path to the matching voice file func _get_voice_file(key: String, start: String = "") -> String: if start == "": start = ESCProjectSettingsManager.get_setting( ESCProjectSettingsManager.SPEECH_FOLDER ) var _dir = Directory.new() if _dir.open(start) == OK: _dir.list_dir_begin(true, true) var file_name = _dir.get_next() while file_name != "": if _dir.current_is_dir(): var _voice_file = _get_voice_file( key, start.plus_file(file_name) ) if _voice_file != "": return _voice_file else: if file_name == "%s.%s.import" % [ key, ESCProjectSettingsManager.get_setting( ESCProjectSettingsManager.SPEECH_EXTENSION ) ]: return start.plus_file(file_name.trim_suffix(".import")) file_name = _dir.get_next() return "" 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()