74 lines
2.7 KiB
GDScript
74 lines
2.7 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
|
|
)
|
|
|
|
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)
|
|
|
|
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,
|
|
}
|