class_name DialogueAction const _TextboxGd = preload("res://ui/component/DialogueTextbox.gd") const _ChoiceBoxGd = preload("res://ui/component/DialogueChoiceBox.gd") enum DialogueMode { CONVERSATION, # blocks movement, player advances NARRATION, # non-blocking, player advances AMBIENT, # non-blocking, timed auto-advance } static func dialogueCallable(params:Dictionary) -> int: assert(params.has('basePath')) var basePath:String = params['basePath'] var title:String = params.get('title', 'start') var extraStates:Array = params.get('extraStates', []) var mode:DialogueMode = params.get('mode', DialogueMode.CONVERSATION) var resource:DialogueResource = _loadLocaleResource(basePath) assert(resource != null, "DialogueAction: could not load resource for path: " + basePath) if mode == DialogueMode.CONVERSATION: UI.activeConversation = true var advancementMode:int = ( _TextboxGd.AdvancementMode.TIMED if mode == DialogueMode.AMBIENT else _TextboxGd.AdvancementMode.PLAYER ) DialogueManager.dialogue_started.emit(resource) var line:DialogueLine = await DialogueManager.get_next_dialogue_line(resource, title, extraStates) while line != null: var entity:Entity = OVERWORLD.getEntityByDialogueName(line.character) var textbox = _TextboxGd.SCENE.instantiate() UI.chatBoxContainer.add_child(textbox) textbox.setup(line, entity, advancementMode) await textbox.dismissed var allowedResponses:Array = line.responses.filter(func(r): return r.is_allowed) if allowedResponses.size() > 0: var playerEntity:Entity = OVERWORLD.getPlayerEntity() var choiceBox = _ChoiceBoxGd.SCENE.instantiate() UI.chatBoxContainer.add_child(choiceBox) choiceBox.setup(line.responses, playerEntity) var chosen:DialogueResponse = await choiceBox.chosen line = await DialogueManager.get_next_dialogue_line(resource, chosen.next_id, extraStates) else: line = await DialogueManager.get_next_dialogue_line(resource, line.next_id, extraStates) DialogueManager.dialogue_ended.emit(resource) if mode == DialogueMode.CONVERSATION: UI.activeConversation = false return Cutscene.CUTSCENE_CONTINUE static func _loadLocaleResource(basePath:String) -> DialogueResource: var lang:String = TranslationServer.get_locale().left(2) var localePath:String = basePath + "." + lang + ".dialogue" if ResourceLoader.exists(localePath): return load(localePath) var fallback:String = basePath + ".en.dialogue" if ResourceLoader.exists(fallback): return load(fallback) return null static func getDialogueCallable(basePath:String, title:String = "start", extraStates:Array = [], mode:DialogueMode = DialogueMode.CONVERSATION) -> Dictionary: return { "function": dialogueCallable, "basePath": basePath, "title": title, "extraStates": extraStates, "mode": mode, }