56 lines
2.4 KiB
GDScript
56 lines
2.4 KiB
GDScript
class_name DialogueAction
|
|
|
|
# Runs a .dialogue file through the VNTextbox and returns CUTSCENE_CONTINUE when
|
|
# the last line is dismissed. Mutations in the .dialogue file are executed
|
|
# automatically by DialogueManager before the line is returned.
|
|
#
|
|
# extra_game_states: additional objects/dicts whose properties and methods are
|
|
# accessible inside the .dialogue file (alongside all autoloads).
|
|
static func dialogueCallable(params:Dictionary) -> int:
|
|
assert(params.has('resource'))
|
|
var resource:DialogueResource = params['resource']
|
|
var title:String = params.get('title', 'start')
|
|
var extraStates:Array = params.get('extraStates', [])
|
|
var characterTargets:Dictionary = params.get('characterTargets', {})
|
|
|
|
UI.dialogueActive = true
|
|
var line:DialogueLine = await DialogueManager.get_next_dialogue_line(resource, title, extraStates)
|
|
while line != null:
|
|
var target:Node3D = _getLineTarget(line.character, characterTargets)
|
|
var text:String = line.text
|
|
|
|
if line.responses.size() > 0:
|
|
# Show text then auto-pick the first allowed response.
|
|
# Replace this block with a real response UI when branching dialogue is needed.
|
|
await UI.MAIN_CHATBOX.setTextAndWait(text, target)
|
|
var nextId:String = ""
|
|
for response:DialogueResponse in line.responses:
|
|
if response.is_allowed:
|
|
nextId = response.next_id
|
|
break
|
|
line = await DialogueManager.get_next_dialogue_line(resource, nextId, extraStates)
|
|
else:
|
|
await UI.MAIN_CHATBOX.setTextAndWait(text, target)
|
|
line = await DialogueManager.get_next_dialogue_line(resource, line.next_id, extraStates)
|
|
|
|
UI.dialogueActive = false
|
|
return Cutscene.CUTSCENE_CONTINUE
|
|
|
|
# "player" (case-insensitive) maps to the player entity; any other named
|
|
# character maps to the npc entity; empty character (narrator) uses no target.
|
|
static func _getLineTarget(character:String, characterTargets:Dictionary) -> Node3D:
|
|
if characterTargets.is_empty() or character == "":
|
|
return null
|
|
if character.to_lower() == "player":
|
|
return characterTargets.get("player", null)
|
|
return characterTargets.get("npc", null)
|
|
|
|
static func getDialogueCallable(resource:DialogueResource, title:String = 'start', extraStates:Array = [], characterTargets:Dictionary = {}) -> Dictionary:
|
|
return {
|
|
'function': dialogueCallable,
|
|
'resource': resource,
|
|
'title': title,
|
|
'extraStates': extraStates,
|
|
'characterTargets': characterTargets,
|
|
}
|