Files
Dawn-Godot/cutscene/dialogue/DialogueAction.gd
T

77 lines
2.8 KiB
GDScript

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,
}