update dialogic

This commit is contained in:
Arnaud Vergnet 2021-04-12 10:59:12 +02:00
parent c47ca10569
commit c1a1e9aadf
7 changed files with 143 additions and 69 deletions

View file

@ -8,14 +8,59 @@ var editorPopup
# This is the information of this event and it will get parsed and saved to the JSON file.
var event_data = {
'question': '',
'options': []
'options': [],
'character': '',
'portrait': '',
}
onready var portrait_picker = $PanelContainer/VBoxContainer/Header/PortraitPicker
func _ready():
$PanelContainer/VBoxContainer/Header/CharacterPicker.connect('character_selected', self , '_on_character_selected')
portrait_picker.get_popup().connect("index_pressed", self, '_on_portrait_selected')
var c_list = DialogicUtil.get_sorted_character_list()
if c_list.size() == 0:
$PanelContainer/VBoxContainer/Header/CharacterPicker.visible = false
else:
# Default Speaker
for c in c_list:
if c['default_speaker']:
event_data['character'] = c['file']
func load_data(data):
event_data = data
if not event_data.has('character'):
event_data['character'] = ''
if not event_data.has('portrait'):
event_data['portrait'] = ''
$PanelContainer/VBoxContainer/Header/LineEdit.text = event_data['question']
update_preview()
func _on_LineEdit_text_changed(new_text):
event_data['question'] = new_text
func _on_character_selected(data):
event_data['character'] = data['file']
update_preview()
func _on_portrait_selected(index):
var text = portrait_picker.get_popup().get_item_text(index)
if text == "[Don't change]":
text = ''
portrait_picker.text = ''
event_data['portrait'] = text
update_preview()
func update_preview():
portrait_picker.set_character(event_data['character'], event_data['portrait'])
for c in DialogicUtil.get_character_list():
if c['file'] == event_data['character']:
$PanelContainer/VBoxContainer/Header/CharacterPicker.set_data_by_file(event_data['character'])

View file

@ -1,12 +1,11 @@
[gd_scene load_steps=6 format=2]
[gd_scene load_steps=8 format=2]
[ext_resource path="res://addons/dialogic/Images/Event Icons/Main Icons/question.svg" type="Texture" id=1]
[ext_resource path="res://addons/dialogic/Editor/Events/Question.gd" type="Script" id=2]
[ext_resource path="res://addons/dialogic/Editor/Events/Common/Spacer.tscn" type="PackedScene" id=3]
[ext_resource path="res://addons/dialogic/Editor/Events/Common/PieceExtraSettings.tscn" type="PackedScene" id=4]
[ext_resource path="res://addons/dialogic/Editor/Events/Common/CharacterPicker.tscn" type="PackedScene" id=5]
[ext_resource path="res://addons/dialogic/Editor/Events/Common/PortraitPicker.tscn" type="PackedScene" id=6]
[sub_resource type="StyleBoxFlat" id=1]
content_margin_left = 16.0
@ -67,15 +66,34 @@ texture = ExtResource( 1 )
stretch_mode = 6
[node name="Title" type="Label" parent="PanelContainer/VBoxContainer/Header"]
visible = false
margin_left = 26.0
margin_top = 7.0
margin_right = 97.0
margin_bottom = 21.0
text = " Question "
[node name="VSeparator" type="VSeparator" parent="PanelContainer/VBoxContainer/Header"]
margin_left = 26.0
margin_right = 30.0
margin_bottom = 28.0
[node name="CharacterPicker" parent="PanelContainer/VBoxContainer/Header" instance=ExtResource( 5 )]
margin_left = 34.0
margin_right = 140.0
margin_bottom = 28.0
[node name="PortraitPicker" parent="PanelContainer/VBoxContainer/Header" instance=ExtResource( 6 )]
visible = false
[node name="VSeparator2" type="VSeparator" parent="PanelContainer/VBoxContainer/Header"]
margin_left = 144.0
margin_right = 148.0
margin_bottom = 28.0
[node name="LineEdit" type="LineEdit" parent="PanelContainer/VBoxContainer/Header"]
margin_left = 101.0
margin_right = 301.0
margin_left = 152.0
margin_right = 352.0
margin_bottom = 28.0
rect_min_size = Vector2( 200, 0 )
expand_to_text_length = true
@ -84,14 +102,14 @@ caret_blink = true
caret_blink_speed = 0.5
[node name="Preview" type="Label" parent="PanelContainer/VBoxContainer/Header"]
margin_left = 305.0
margin_left = 356.0
margin_top = 7.0
margin_right = 305.0
margin_right = 356.0
margin_bottom = 21.0
custom_colors/font_color = Color( 1, 1, 1, 0.513726 )
[node name="Spacer" parent="PanelContainer/VBoxContainer/Header" instance=ExtResource( 3 )]
margin_left = 309.0
margin_left = 360.0
margin_right = 941.0
margin_bottom = 28.0

View file

@ -377,7 +377,7 @@ func load_timeline(filename: String):
create_event("AudioBlock", i)
{'background-music', 'file'}:
create_event("BackgroundMusic", i)
{'question', 'options'}:
{'question', 'options', ..}:
create_event("Question", i)
{'choice'}:
create_event("Choice", i)

View file

@ -62,9 +62,9 @@ func _ready():
if Engine.is_editor_hint():
if preview:
load_dialog()
_init_dialog()
else:
load_dialog()
_init_dialog()
func load_config_files():
@ -269,7 +269,7 @@ func _input(event: InputEvent) -> void:
$TextBubble.skip()
else:
if waiting_for_answer == false and waiting_for_input == false:
load_dialog()
_load_next_event()
if settings.has_section_key('dialog', 'propagate_input'):
var propagate_input: bool = settings.get_value('dialog', 'propagate_input')
if not propagate_input:
@ -319,34 +319,54 @@ func on_timeline_end():
emit_signal("event_end", "timeline")
func load_dialog(skip_add = false):
# Emitting signals
if dialog_script.has('events'):
if dialog_index == 0:
on_timeline_start()
elif dialog_index == dialog_script['events'].size():
on_timeline_end()
func _init_dialog():
dialog_index = 0
_load_event()
# Hiding definitions popup
definition_visible = false
$DefinitionInfo.visible = definition_visible
# This will load the next entry in the dialog_script array.
func _load_event_at_index(index: int):
dialog_index = index
_load_event()
func _load_next_event():
dialog_index += 1
_load_event()
func _is_dialog_starting():
return dialog_index == 0
func _is_dialog_finished():
return dialog_index >= dialog_script['events'].size()
func _load_event():
_emit_timeline_signals()
_hide_definition_popup()
if dialog_script.has('events'):
if dialog_index < dialog_script['events'].size():
if not _is_dialog_finished():
var func_state = event_handler(dialog_script['events'][dialog_index])
if (func_state is GDScriptFunctionState):
yield(func_state, "completed")
else:
if Engine.is_editor_hint() == false:
queue_free()
if skip_add == false:
dialog_index += 1
elif not Engine.is_editor_hint():
# Do not free the dialog if we are in the preview
queue_free()
func reset_dialog_extras():
$TextBubble/NameLabel.text = ''
$TextBubble/NameLabel.visible = false
func _emit_timeline_signals():
if dialog_script.has('events'):
if _is_dialog_starting():
on_timeline_start()
elif _is_dialog_finished():
on_timeline_end()
func _hide_definition_popup():
definition_visible = false
$DefinitionInfo.visible = definition_visible
func get_character(character_id):
@ -378,6 +398,10 @@ func event_handler(event: Dictionary):
waiting_for_answer = true
if event.has('name'):
update_name(event['name'])
elif event.has('character'):
var character_data = get_character(event['character'])
update_name(character_data)
grab_portrait_focus(character_data, event)
update_text(event['question'])
if event.has('options'):
for o in event['options']:
@ -388,8 +412,7 @@ func event_handler(event: Dictionary):
if q['question_id'] == event['question_id']:
if q['answered']:
# If the option is for an answered question, skip to the end of it.
dialog_index = q['end_id']
load_dialog(true)
_load_event_at_index(q['end_id'])
{'action', ..}:
emit_signal("event_start", "action", event)
if event['action'] == 'leaveall':
@ -399,11 +422,10 @@ func event_handler(event: Dictionary):
for p in $Portraits.get_children():
if p.character_data['file'] == event['character']:
p.fade_out()
go_to_next_event()
_load_next_event()
elif event['action'] == 'join':
if event['character'] == '':
go_to_next_event()
_load_next_event()
else:
var character_data = get_character(event['character'])
var exists = grab_portrait_focus(character_data)
@ -416,7 +438,7 @@ func event_handler(event: Dictionary):
p.init(char_portrait, get_character_position(event['position']))
$Portraits.add_child(p)
p.fade_in()
go_to_next_event()
_load_next_event()
{'scene'}:
get_tree().change_scene(event['scene'])
{'background'}:
@ -446,7 +468,7 @@ func event_handler(event: Dictionary):
background.add_child(bg_scene)
elif (event['background'] != ''):
background.texture = load(event['background'])
go_to_next_event()
_load_next_event()
{'audio'}, {'audio', 'file'}:
emit_signal("event_start", "audio", event)
if event['audio'] == 'play' and 'file' in event.keys() and not event['file'].empty():
@ -463,23 +485,23 @@ func event_handler(event: Dictionary):
if audio != null:
audio.stop()
audio.queue_free()
go_to_next_event()
_load_next_event()
{'background-music'}, {'background-music', 'file'}:
emit_signal("event_start", "background-music", event)
if event['background-music'] == 'play' and 'file' in event.keys() and not event['file'].empty():
$FX/BackgroundMusic.crossfade_to(event['file'])
else:
$FX/BackgroundMusic.fade_out()
go_to_next_event()
_load_next_event()
{'endbranch', ..}:
emit_signal("event_start", "endbranch", event)
go_to_next_event()
_load_next_event()
{'change_scene'}:
get_tree().change_scene(event['change_scene'])
{'emit_signal', ..}:
dprint('[!] Emitting signal: dialogic_signal(', event['emit_signal'], ')')
emit_signal("dialogic_signal", event['emit_signal'])
go_to_next_event()
_load_next_event()
{'close_dialog'}:
emit_signal("event_start", "close_dialog", event)
close_dialog_event()
@ -487,15 +509,14 @@ func event_handler(event: Dictionary):
emit_signal("event_start", "set_theme", event)
if event['set_theme'] != '':
current_theme = load_theme(event['set_theme'])
go_to_next_event()
_load_next_event()
{'wait_seconds'}:
emit_signal("event_start", "wait", event)
wait_seconds(event['wait_seconds'])
waiting = true
{'change_timeline'}:
dialog_script = set_current_dialog(event['change_timeline'])
dialog_index = -1
go_to_next_event()
_init_dialog()
{'condition', 'definition', 'value', 'question_id', ..}:
# Treating this conditional as an option on a regular question event
var def_value = null
@ -510,18 +531,17 @@ func event_handler(event: Dictionary):
current_question['answered'] = !condition_met
if !condition_met:
# condition not met, skipping branch
dialog_index = current_question['end_id']
load_dialog(true)
_load_event_at_index(current_question['end_id'])
else:
# condition met, entering branch
go_to_next_event()
_load_next_event()
{'set_value', 'definition', ..}:
emit_signal("event_start", "set_value", event)
var operation = '='
if 'operation' in event and not event['operation'].empty():
operation = event["operation"]
DialogicSingleton.set_variable_from_id(event['definition'], event['set_value'], operation)
go_to_next_event()
_load_next_event()
{'call_node', ..}:
dprint('[!] Call Node signal: dialogic_signal(call_node) ', var2str(event['call_node']))
emit_signal("event_start", "call_node", event)
@ -546,7 +566,7 @@ func event_handler(event: Dictionary):
waiting = false
$TextBubble.visible = true
go_to_next_event()
_load_next_event()
_:
visible = false
dprint('Other event. ', event)
@ -620,13 +640,10 @@ func add_choice_button(option):
func answer_question(i, event_id, question_id):
dprint('[!] Going to ', event_id + 1, i, 'question_id:', question_id)
dprint('')
waiting_for_answer = false
dialog_index = event_id + 1
questions[question_id]['answered'] = true
dprint(' dialog_index = ', dialog_index)
reset_options()
load_dialog()
_load_event_at_index(event_id + 1)
if last_mouse_mode != null:
Input.set_mouse_mode(last_mouse_mode) # Revert to last mouse mode when selection is done
last_mouse_mode = null
@ -636,16 +653,10 @@ func _on_option_selected(option, variable, value):
dialog_resource.custom_variables[variable] = value
waiting_for_answer = false
reset_options()
load_dialog()
_load_next_event()
dprint('[!] Option selected: ', option.text, ' value= ' , value)
func go_to_next_event():
# The entire event reading system should be refactored... but not today!
dialog_index += 1
load_dialog(true)
func grab_portrait_focus(character_data, event: Dictionary = {}) -> bool:
var exists = false
var visually_focus = true
@ -754,7 +765,7 @@ func _on_WaitSeconds_timeout():
$WaitSeconds.stop()
$WaitSeconds.queue_free()
$TextBubble.visible = true
load_dialog()
_load_next_event()
func dprint(string, arg1='', arg2='', arg3='', arg4='' ):

View file

@ -76,12 +76,12 @@ static func get_definitions() -> Dictionary:
## Definitions are automatically saved on timeline start/end
##
## @returns Error status, OK if all went well
func save_definitions():
static func save_definitions():
return DialogicSingleton.save_definitions()
## Resets data to default values. This is the same as calling start with reset_saves to true
func reset_saves():
static func reset_saves():
DialogicSingleton.init(true)

View file

@ -1 +1 @@
{"events":[{"background":"res://backgrounds/meetingRoom.jpg"},{"action":"join","character":"character-1616658403.json","portrait":"","position":{"0":false,"1":true,"2":false,"3":false,"4":false}},{"character":"","portrait":"","text":"Test"},{"character":"character-1616658403.json","portrait":"","text":"On peut discuter une minute ?"},{"character":"character-1616658355.json","portrait":"","text":"Euh oui pas de soucis quest ce quil se passe ?"},{"character":"character-1616658403.json","portrait":"","text":"Je viens dapprendre que ton projet vient dêtre validé mais que cest le projet de développer un téléphone que lutilisateur peut ouvrir !\nTu as une idée des répercussions sur lentreprise que cela va avoir ?\nLentreprise va perdre beaucoup dargent à laisser la possibilité aux gens de réparer leurs téléphones en leur laissant laccès aux composants !\nEt toutes les idées dont je tavais parlé de technologies innovantes et de designs incroyables sont réduits à néant !\nFranchement je ne sais pas ce qui tes passé par la tête mais ça me laisse sans voix …\nSur ce je nai plus rien à dire au revoir."},{"background":""},{"action":"join","character":"character-1616658373.json","portrait":"","position":{"0":false,"1":false,"2":false,"3":true,"4":false}},{"character":"character-1616658373.json","portrait":"","text":"Re-bonjour ! Quelle belle journée aujourdhui !\nJai appris que tu avais repris mon idée de pouvoir ouvrir le téléphone dans ton projet de développement.\nCest une sage décision qui va engendrer tellement de choses positives pour lentreprise.\nCest le début dune nouvelle ère technologique responsable, crois moi !\nOui au recyclage et oui à la seconde vie des appareils !"},{"character":"character-1616658355.json","portrait":"","text":"Je suis content que ce projet provoque un tel enthousiasme en toi !"},{"action":"join","character":"character-1616658435.json","portrait":"","position":{"0":true,"1":false,"2":false,"3":false,"4":false}},{"character":"character-1616658435.json","portrait":"","text":"Il se passe quoi ici ?"},{"character":"character-1616658355.json","portrait":"","text":"Tu n'as pas vu mon mail ?"},{"character":"character-1616658435.json","portrait":"","text":"Ah non.."},{"wait_seconds":1},{"character":"character-1616658435.json","portrait":"","text":"J'ai perdu mon mot de passe\n...\n..."},{"wait_seconds":1},{"action":"leaveall","character":"character-1616658435.json"},{"character":"character-1616658373.json","portrait":"","text":"...\nBon\nEn tout cas je suis ravie de ton choix !\nJe te laisse jai une réunion dans 10 min à bientôt !"},{"action":"leaveall","character":"[All]"},{"change_timeline":"timeline-1616662258.json"}],"metadata":{"dialogic-version":"1.1","file":"timeline-1616661658.json","name":"conseq-tel-ouvert-1"}}
{"events":[{"background":"res://backgrounds/meetingRoom.jpg"},{"action":"join","character":"character-1616658403.json","portrait":"","position":{"0":false,"1":true,"2":false,"3":false,"4":false}},{"character":"","portrait":"","text":"Test"},{"character":"character-1616658403.json","portrait":"","text":"On peut discuter une minute ?"},{"character":"character-1616658355.json","portrait":"","text":"Euh oui pas de soucis quest ce quil se passe ?"},{"character":"character-1616658403.json","portrait":"","text":"Je viens dapprendre que ton projet vient dêtre validé mais que cest le projet de développer un téléphone que lutilisateur peut ouvrir !\nTu as une idée des répercussions sur lentreprise que cela va avoir ?\nLentreprise va perdre beaucoup dargent à laisser la possibilité aux gens de réparer leurs téléphones en leur laissant laccès aux composants !\nEt toutes les idées dont je tavais parlé de technologies innovantes et de designs incroyables sont réduits à néant !\nFranchement je ne sais pas ce qui tes passé par la tête mais ça me laisse sans voix …\nSur ce je nai plus rien à dire au revoir."},{"action":"join","character":"character-1616658373.json","portrait":"","position":{"0":false,"1":false,"2":false,"3":true,"4":false}},{"character":"character-1616658373.json","portrait":"","text":"Re-bonjour ! Quelle belle journée aujourdhui !\nJai appris que tu avais repris mon idée de pouvoir ouvrir le téléphone dans ton projet de développement.\nCest une sage décision qui va engendrer tellement de choses positives pour lentreprise.\nCest le début dune nouvelle ère technologique responsable, crois moi !\nOui au recyclage et oui à la seconde vie des appareils !"},{"character":"character-1616658355.json","portrait":"","text":"Je suis content que ce projet provoque un tel enthousiasme en toi !"},{"action":"join","character":"character-1616658435.json","portrait":"","position":{"0":true,"1":false,"2":false,"3":false,"4":false}},{"character":"character-1616658435.json","portrait":"","text":"Il se passe quoi ici ?"},{"character":"character-1616658355.json","portrait":"","text":"Tu n'as pas vu mon mail ?"},{"character":"character-1616658435.json","portrait":"","text":"Ah non.."},{"wait_seconds":1},{"character":"character-1616658435.json","portrait":"","text":"J'ai perdu mon mot de passe\n...\n..."},{"wait_seconds":1},{"action":"leaveall","character":"character-1616658435.json"},{"character":"character-1616658373.json","portrait":"","text":"...\nBon\nEn tout cas je suis ravie de ton choix !\nJe te laisse jai une réunion dans 10 min à bientôt !"},{"action":"leaveall","character":"[All]"},{"change_timeline":"timeline-1616662258.json"}],"metadata":{"dialogic-version":"1.1","file":"timeline-1616661658.json","name":"conseq-tel-ouvert-1"}}

View file

@ -1 +1 @@
{"events":[{"action":"join","character":"character-1616658373.json","portrait":"","position":{"0":false,"1":false,"2":false,"3":true,"4":false}},{"character":"character-1616658373.json","portrait":"","text":"you lost"},{"options":[],"question":"Tu veux réessayer?"},{"choice":"Oui !"},{"emit_signal":"setup_minigame score _test_minigame_end _test_minigame_end2"},{"background":""},{"emit_signal":"start_minigame"},{"choice":"Non"},{"change_timeline":"timeline-1616661658.json"},{"endbranch":""}],"metadata":{"dialogic-version":"1.1","file":"timeline-1617874348.json","name":"_test_minigame_end"}}
{"events":[{"action":"join","character":"character-1616658373.json","portrait":"","position":{"0":false,"1":false,"2":false,"3":true,"4":false}},{"character":"character-1616658373.json","portrait":"","text":"you lost"},{"character":"character-1616658373.json","options":[],"portrait":"","question":"Tu veux réessayer?"},{"choice":"Oui !"},{"emit_signal":"setup_minigame score _test_minigame_end _test_minigame_end2"},{"background":""},{"emit_signal":"start_minigame"},{"choice":"Non"},{"change_timeline":"timeline-1616661658.json"},{"endbranch":""}],"metadata":{"dialogic-version":"1.1","file":"timeline-1617874348.json","name":"_test_minigame_end"}}