Updated dialogic

This commit is contained in:
MaddoScientisto 2026-01-05 16:00:41 +01:00
commit cbb82512ee
483 changed files with 5743 additions and 2177 deletions

View file

@ -1 +1 @@
uid://fgk8hal7nugw
uid://qruxugkg6y8w

View file

@ -1 +1 @@
uid://cb4xhtqnifsrf
uid://rfgxn0xtuen3

View file

@ -1 +1 @@
uid://ckqo0ncifb40s
uid://bcs0jdci4mngb

View file

@ -1 +1 @@
uid://cobrccabo638p
uid://fekbbs23rj4m

View file

@ -1 +1 @@
uid://df6ex8wqhaxix
uid://dwnfbyjtc2anb

View file

@ -1 +1 @@
uid://dttqyslijg03r
uid://8ro2ayitmjcp

View file

@ -1 +1 @@
uid://clwy8nsaw1phe
uid://cn4yveni7rdr7

View file

@ -11,7 +11,7 @@ func animate() -> void:
tween.tween_method(bound_multitween, Vector2(), Vector2(-1,0)*strength, time*0.1)
tween.tween_method(bound_multitween, Vector2(), Vector2(1, 0)*strength, time*0.1)
tween.tween_method(bound_multitween, Vector2(), Vector2(-1,0)*strength, time*0.1)
tween.tween_method(bound_multitween, Vector2(), Vector2(1, 0)*strength, time*0.2)
tween.tween_method(bound_multitween, Vector2(), Vector2(0, 0)*strength, time*0.2)
tween.finished.connect(emit_signal.bind('finished_once'))
func _get_named_variations() -> Dictionary:

View file

@ -1 +1 @@
uid://jp8nhoprsqdh
uid://3tqien23j50t

View file

@ -1 +1 @@
uid://j0si5xem8teo
uid://lur75holg34f

View file

@ -4,16 +4,17 @@ func animate() -> void:
var tween := (node.create_tween() as Tween)
tween.set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_BACK)
var target_position := base_position.y
var start_position: float = -node.get_viewport().size.y
var end_position_y: float = base_position.y + node.get_parent().global_position.y
var start_position: float = -get_node_size().y + get_node_origin().y
if is_reversed:
target_position = -node.get_viewport().size.y
tween.set_ease(Tween.EASE_IN)
end_position_y = -get_node_size().y + get_node_origin().y
start_position = base_position.y
node.position.y = start_position
tween.tween_property(node, 'position:y', target_position, time)
tween.tween_property(node, 'global_position:y', end_position_y, time)
await tween.finished
finished_once.emit()

View file

@ -1 +1 @@
uid://b3cvsvayqobsk
uid://d0a5sgbr5imas

View file

@ -5,15 +5,16 @@ func animate() -> void:
var tween := (node.create_tween() as Tween)
tween.set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_BACK)
var end_position_x: float = base_position.x
var end_position_x: float = base_position.x + node.get_parent().global_position.x
if is_reversed:
end_position_x = -node.get_viewport().size.x / 2
end_position_x = - get_node_size().x + get_node_origin().x
tween.set_ease(Tween.EASE_IN)
else:
node.position.x = -node.get_viewport().size.x / 5
node.global_position.x = -get_node_size().x + get_node_origin().x
tween.tween_property(node, 'position:x', end_position_x, time)
tween.tween_property(node, 'global_position:x', end_position_x, time)
await tween.finished
finished_once.emit()
@ -21,6 +22,6 @@ func animate() -> void:
func _get_named_variations() -> Dictionary:
return {
"slide in left": {"reversed": false, "type": AnimationType.IN},
"slide out right": {"reversed": true, "type": AnimationType.OUT},
"slide from left": {"reversed": false, "type": AnimationType.IN},
"slide to left": {"reversed": true, "type": AnimationType.OUT},
}

View file

@ -1 +1 @@
uid://bs763k4612fht
uid://c8il877nw3xqw

View file

@ -4,24 +4,21 @@ func animate() -> void:
var tween := (node.create_tween() as Tween)
tween.set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_BACK)
var viewport_x: float = node.get_viewport().size.x
var start_position_x: float = viewport_x + viewport_x / 5
var end_position_x := base_position.x
var viewport_x: float = get_viewport_size().x
var end_position_x : float = base_position.x + node.get_parent().global_position.x
if is_reversed:
start_position_x = base_position.x
end_position_x = viewport_x + node.get_viewport().size.x / 5
node.position.x = start_position_x
tween.tween_property(node, 'position:x', end_position_x, time)
end_position_x = viewport_x + get_node_origin().x
tween.set_ease(Tween.EASE_IN)
else:
node.global_position.x = viewport_x + get_node_origin().x
tween.tween_property(node, 'global_position:x', end_position_x, time)
tween.finished.connect(emit_signal.bind('finished_once'))
func _get_named_variations() -> Dictionary:
return {
"slide in right": {"reversed": false, "type": AnimationType.IN},
"slide out left": {"reversed": true, "type": AnimationType.OUT},
"slide from right": {"reversed": false, "type": AnimationType.IN},
"slide to right": {"reversed": true, "type": AnimationType.OUT},
}

View file

@ -1 +1 @@
uid://cswjq5jlqrn3g
uid://daj7cqft5hnxg

View file

@ -4,15 +4,16 @@ func animate() -> void:
var tween := (node.create_tween() as Tween)
tween.set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_BACK)
var start_position_y: float = node.get_viewport().size.y * 2
var end_position_y := base_position.y
var start_position_y: float = get_viewport_size().y + get_node_origin().y
var end_position_y: float = base_position.y + node.get_parent().global_position.y
if is_reversed:
start_position_y = base_position.y
end_position_y = node.get_viewport().size.y * 2
tween.set_ease(Tween.EASE_IN)
start_position_y = end_position_y
end_position_y = get_viewport_size().y + get_node_origin().y
node.position.y = start_position_y
tween.tween_property(node, 'position:y', end_position_y, time)
node.global_position.y = start_position_y
tween.tween_property(node, 'global_position:y', end_position_y, time)
await tween.finished
finished_once.emit()

View file

@ -1 +1 @@
uid://b43hklc4t83ic
uid://bj5ak53i7s8ux

View file

@ -1 +1 @@
uid://b4iouoy0lsmg3
uid://crv1pn60clrvx

View file

@ -1 +1 @@
uid://guke2u7jqwkt
uid://cjwdb0jkjrcxe

View file

@ -1 +1 @@
uid://bb2xwtcht84yq
uid://bl5sdpj631mtt

View file

@ -1 +1 @@
uid://b7mq20hi3v6m8
uid://j2k3uogf5715

View file

@ -75,3 +75,28 @@ func get_modulation_property() -> String:
return "self_modulate"
else:
return "modulate"
## Tries to return the size of the node to be animated.
## For portraits this uses the portrait containers size.
## This is useful if your animation depends on the size of the node.
func get_node_size() -> Vector2:
if not node:
return Vector2()
if node.get_parent() is DialogicNode_PortraitContainer:
return node.get_parent().size
if "size" in node:
return node.size * node.scale
return node.get_viewport().size
func get_node_origin() -> Vector2:
if not node:
return Vector2()
if node.get_parent() is DialogicNode_PortraitContainer:
return node.get_parent()._get_origin_position()
return Vector2()
func get_viewport_size() -> Vector2:
return node.get_viewport().get_visible_rect().size

View file

@ -1 +1 @@
uid://blu2it3fdcxr8
uid://0hsjlurlblou

View file

@ -1 +1 @@
uid://c3a0wujs6kev3
uid://cork0heubbx7f

View file

@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://b32paf0ll6um8"]
[ext_resource type="Script" uid="uid://c3a0wujs6kev3" path="res://addons/dialogic/Modules/Character/default_portrait.gd" id="1_wn77n"]
[ext_resource type="Script" uid="uid://cork0heubbx7f" path="res://addons/dialogic/Modules/Character/default_portrait.gd" id="1_wn77n"]
[node name="DefaultPortrait" type="Node2D"]
script = ExtResource("1_wn77n")

View file

@ -1 +1 @@
uid://du4fl3cae5jml
uid://djbg8sc0q67ow

View file

@ -82,14 +82,14 @@ var character_identifier: String:
if character_identifier == '--All--':
return '--All--'
if character:
var identifier := DialogicResourceUtil.get_unique_identifier(character.resource_path)
var identifier := character.get_identifier()
if not identifier.is_empty():
return identifier
return character_identifier
set(value):
character_identifier = value
character = DialogicResourceUtil.get_character_resource(value)
if character and not character.portraits.has(portrait):
if (not character) or (character and not character.portraits.has(portrait)):
portrait = ""
ui_update_needed.emit()
@ -154,10 +154,10 @@ func _execute() -> void:
finish()
return
dialogic.Portraits.change_character_extradata(character, extra_data)
if set_portrait:
dialogic.Portraits.change_character_portrait(character, portrait, fade_animation, fade_length)
await dialogic.Portraits.change_character_portrait(character, portrait, fade_animation, fade_length)
dialogic.Portraits.change_character_extradata(character, extra_data)
if set_mirrored:
dialogic.Portraits.change_character_mirror(character, mirrored)
@ -225,7 +225,7 @@ func to_text() -> String:
if action == Actions.LEAVE and character_identifier == '--All--':
result_string += "--All--"
elif character:
var name := DialogicResourceUtil.get_unique_identifier(character.resource_path)
var name := character.get_character_name()
if name.count(" ") > 0:
name = '"' + name + '"'
@ -302,7 +302,7 @@ func get_shortcode_parameters() -> Dictionary:
{'value':Actions.JOIN},
'Leave':{'value':Actions.LEAVE},
'Update':{'value':Actions.UPDATE}}},
"character" : {"property": "character_identifier", "default": "", "custom_stored":true,},
"character" : {"property": "character_identifier", "default": "", "custom_stored":true, "ext_file":true},
"portrait" : {"property": "portrait", "default": "", "custom_stored":true,},
"transform" : {"property": "transform", "default": "center", "custom_stored":true,},
@ -478,8 +478,8 @@ func get_fade_suggestions(search_text:String='') -> Dictionary:
func _get_code_completion(CodeCompletionHelper:Node, TextNode:TextEdit, line:String, _word:String, symbol:String) -> void:
var line_until_caret: String = CodeCompletionHelper.get_line_untill_caret(line)
if symbol == ' ' and line_until_caret.count(' ') == 1:
CodeCompletionHelper.suggest_characters(TextNode, CodeEdit.KIND_MEMBER)
if symbol == ' ' and line_until_caret.count(" ") == 1:
CodeCompletionHelper.suggest_characters(TextNode, CodeEdit.KIND_MEMBER, self)
if line.begins_with('leave'):
TextNode.add_code_completion_option(CodeEdit.KIND_MEMBER, 'All', '--All-- ', event_color, TextNode.get_theme_icon("GuiEllipsis", "EditorIcons"))
@ -487,10 +487,11 @@ func _get_code_completion(CodeCompletionHelper:Node, TextNode:TextEdit, line:Str
var completion_character := regex.search(line).get_string('name')
CodeCompletionHelper.suggest_portraits(TextNode, completion_character)
elif not '[' in line_until_caret and symbol == ' ':
elif not '[' in line_until_caret and symbol == ' ' and line_until_caret.split(" ", false).size() > 1:
if not line.begins_with("leave"):
for position in get_position_suggestions():
TextNode.add_code_completion_option(CodeEdit.KIND_MEMBER, position, position+' ', TextNode.syntax_highlighter.normal_color)
if not line_until_caret.split(" ", false)[-1] in get_position_suggestions():
for position in get_position_suggestions():
TextNode.add_code_completion_option(CodeEdit.KIND_MEMBER, position, position+' ', TextNode.syntax_highlighter.normal_color)
# Shortcode Part
if '[' in line_until_caret:
@ -504,8 +505,10 @@ func _get_code_completion(CodeCompletionHelper:Node, TextNode:TextEdit, line:Str
if line.begins_with('update'):
suggest_parameter("repeat", line, TextNode)
if line.begins_with("update"):
for param in ["move_time", "move_trans", "move_ease"]:
for param in ["move_time", "move_trans", "move_ease", "fade"]:
suggest_parameter(param, line, TextNode)
if "fade=" in line_until_caret:
suggest_parameter("fade_length", line, TextNode)
if not line.begins_with('leave'):
for param in ["mirrored", "z_index", "extra_data"]:
suggest_parameter(param, line, TextNode)

View file

@ -1 +1 @@
uid://duu0jekiba20n
uid://b88y7tdin2uu5

View file

@ -1 +1 @@
uid://drl3os1svksa2
uid://4tu24b2ex257

View file

@ -1 +1 @@
uid://cfcx0of1aekhk
uid://d0ptqnbudhkyj

View file

@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="DialogicCharacter" load_steps=2 format=3 uid="uid://dykf1j17ct5mo"]
[ext_resource type="Script" uid="uid://w3vtr3asq7b3" path="res://addons/dialogic/Resources/character.gd" id="1_qsljv"]
[ext_resource type="Script" uid="uid://don4ds5f38byo" path="res://addons/dialogic/Resources/character.gd" id="1_qsljv"]
[resource]
script = ExtResource("1_qsljv")

View file

@ -17,11 +17,11 @@ const ANIMATION_CROSSFADE_DEFAULT_LENGTH_KEY:= 'dialogic/animations/cross_fade_d
func _ready():
%JoinDefault.get_suggestions_func = get_join_animation_suggestions
%JoinDefault.suggestions_func = get_join_animation_suggestions
%JoinDefault.mode = 1
%LeaveDefault.get_suggestions_func = get_leave_animation_suggestions
%LeaveDefault.suggestions_func = get_leave_animation_suggestions
%LeaveDefault.mode = 1
%CrossFadeDefault.get_suggestions_func = get_crossfade_animation_suggestions
%CrossFadeDefault.suggestions_func = get_crossfade_animation_suggestions
%CrossFadeDefault.mode = 1
%PositionSuggestions.text_submitted.connect(save_setting.bind(POSITION_SUGGESTION_KEY))

View file

@ -1 +1 @@
uid://0hdug2yw0j7u
uid://c3hdycwp0hrdm

View file

@ -1,6 +1,6 @@
[gd_scene load_steps=5 format=3 uid="uid://cp463rpri5j8a"]
[ext_resource type="Script" uid="uid://0hdug2yw0j7u" path="res://addons/dialogic/Modules/Character/settings_portraits.gd" id="2"]
[ext_resource type="Script" uid="uid://c3hdycwp0hrdm" path="res://addons/dialogic/Modules/Character/settings_portraits.gd" id="2"]
[ext_resource type="PackedScene" uid="uid://dbpkta2tjsqim" path="res://addons/dialogic/Editor/Common/hint_tooltip_icon.tscn" id="2_dce78"]
[ext_resource type="PackedScene" uid="uid://dpwhshre1n4t6" path="res://addons/dialogic/Editor/Events/Fields/field_options_dynamic.tscn" id="3"]
[ext_resource type="PackedScene" uid="uid://7mvxuaulctcq" path="res://addons/dialogic/Editor/Events/Fields/field_file.tscn" id="3_m06d8"]
@ -19,8 +19,7 @@ size_flags_stretch_ratio = 0.5
[node name="Title2" type="Label" parent="PositionsTitle"]
layout_mode = 2
theme_type_variation = &"DialogicSettingsSection"
text = "Position Suggestions
"
text = "Position Suggestions"
[node name="HintTooltip" parent="PositionsTitle" instance=ExtResource("2_dce78")]
layout_mode = 2
@ -40,8 +39,7 @@ size_flags_stretch_ratio = 0.5
[node name="Title2" type="Label" parent="DefaultSceneTitle"]
layout_mode = 2
theme_type_variation = &"DialogicSettingsSection"
text = "Default Portrait Scene
"
text = "Default Portrait Scene"
[node name="HintTooltip" parent="DefaultSceneTitle" instance=ExtResource("2_dce78")]
layout_mode = 2
@ -70,8 +68,7 @@ size_flags_stretch_ratio = 0.5
[node name="Title2" type="Label" parent="Animations2"]
layout_mode = 2
theme_type_variation = &"DialogicSettingsSection"
text = "Default Animations
"
text = "Default Animations"
[node name="HintTooltip" parent="Animations2" instance=ExtResource("2_dce78")]
layout_mode = 2

View file

@ -182,7 +182,8 @@ func resize_container(container: DialogicNode_PortraitContainer, rect_size: Vari
tween.finished.connect(save_position_container.bind(container))
else:
container.position = container.position + relative_position_change
container.size = final_rect_resize
#container.size = final_rect_resize
container.set_deferred("size", final_rect_resize)
save_position_container(container)
position_changed.emit({&'change':'resized', &'container_node':container})

View file

@ -1 +1 @@
uid://c8ug08wx4f1d0
uid://c5dk5rh4vj8rd

View file

@ -19,8 +19,8 @@ var default_portrait_scene: PackedScene = load(get_script().resource_path.get_ba
####################################################################################################
func clear_game_state(_clear_flag:=DialogicGameHandler.ClearFlags.FULL_CLEAR) -> void:
for character in dialogic.current_state_info.get('portraits', {}).keys():
remove_character(load(character))
for character_identifier in dialogic.current_state_info.get('portraits', {}).keys():
remove_character(DialogicResourceUtil.get_character_resource(character_identifier))
dialogic.current_state_info['portraits'] = {}
@ -31,21 +31,24 @@ func load_game_state(_load_flag:=LoadFlags.FULL_LOAD) -> void:
# Load Position Portraits
var portraits_info: Dictionary = dialogic.current_state_info.portraits.duplicate()
dialogic.current_state_info.portraits = {}
for character_path in portraits_info:
var character_info: Dictionary = portraits_info[character_path]
var character: DialogicCharacter = load(character_path)
var container := dialogic.PortraitContainers.load_position_container(character.get_character_name())
add_character(character, container, character_info.portrait, character_info.position_id)
change_character_mirror(character, character_info.get('custom_mirror', false))
change_character_z_index(character, character_info.get('z_index', 0))
change_character_extradata(character, character_info.get('extra_data', ""))
for character_identifier in portraits_info:
var character_info: Dictionary = portraits_info[character_identifier]
var character: DialogicCharacter = DialogicResourceUtil.get_character_resource(character_identifier)
if character:
var container := dialogic.PortraitContainers.load_position_container(character.get_character_name())
add_character(character, container, character_info.portrait, character_info.position_id)
change_character_mirror(character, character_info.get('custom_mirror', false))
change_character_z_index(character, character_info.get('z_index', 0))
change_character_extradata(character, character_info.get('extra_data', ""))
else:
push_error('[Dialogic] Failed to load character "' + str(character_identifier) + '".')
# Load Speaker Portrait
var speaker: Variant = dialogic.current_state_info.get('speaker', "")
var speaker: Variant = dialogic.current_state_info.get("speaker", "")
if speaker:
dialogic.current_state_info['speaker'] = ""
change_speaker(load(speaker))
dialogic.current_state_info['speaker'] = speaker
dialogic.current_state_info["speaker"] = ""
change_speaker(DialogicResourceUtil.get_character_resource(speaker))
dialogic.current_state_info["speaker"] = speaker
func pause() -> void:
@ -117,6 +120,7 @@ func _change_portrait(character_node: Node2D, portrait: String, fade_animation:=
if (not previous_portrait == null and
previous_portrait.get_meta('scene', '') == scene_path and
# Also check if the scene supports changing to the given portrait.
previous_portrait.has_method('_should_do_portrait_update') and
previous_portrait._should_do_portrait_update(character, portrait)):
portrait_node = previous_portrait
info['same_scene'] = true
@ -124,12 +128,21 @@ func _change_portrait(character_node: Node2D, portrait: String, fade_animation:=
else:
if ResourceLoader.exists(scene_path):
var packed_scene: PackedScene = load(scene_path)
ResourceLoader.load_threaded_request(scene_path)
if packed_scene:
portrait_node = packed_scene.instantiate()
var load_status := ResourceLoader.load_threaded_get_status(scene_path)
while load_status == ResourceLoader.THREAD_LOAD_IN_PROGRESS:
await get_tree().process_frame
load_status = ResourceLoader.load_threaded_get_status(scene_path)
if load_status == ResourceLoader.THREAD_LOAD_LOADED:
var packed_scene: PackedScene = ResourceLoader.load_threaded_get(scene_path)
if packed_scene:
portrait_node = packed_scene.instantiate()
else:
push_error('[Dialogic] Portrait node "' + str(scene_path) + '" for character [' + character.display_name + '] could not be loaded. Your portrait might not show up on the screen. Confirm the path is correct.')
else:
push_error('[Dialogic] Portrait node "' + str(scene_path) + '" for character [' + character.display_name + '] could not be loaded. Your portrait might not show up on the screen. Confirm the path is correct.')
push_error('[Dialogic] Failed to load portrait node "' + str(scene_path) + '" for character [' + character.display_name + '].')
if !portrait_node:
portrait_node = default_portrait_scene.instantiate()
@ -167,20 +180,26 @@ func _change_portrait(character_node: Node2D, portrait: String, fade_animation:=
## Unless @force is false, this will take into consideration the character mirror,
## portrait mirror and portrait position mirror settings.
func _change_portrait_mirror(character_node: Node2D, mirrored := false, force := false) -> void:
var latest_portrait := character_node.get_child(-1)
var latest_portrait := character_node.get_child(-1) if character_node.get_child_count() > 0 else null
if latest_portrait.has_method('_set_mirror'):
if latest_portrait and latest_portrait.has_method("_set_mirror"):
var character: DialogicCharacter = character_node.get_meta('character')
var current_portrait_info := character.get_portrait_info(character_node.get_meta('portrait'))
latest_portrait._set_mirror(force or (mirrored != character.mirror != character_node.get_parent().mirrored != current_portrait_info.get('mirror', false)))
func _change_portrait_extradata(character_node: Node2D, extra_data := "") -> void:
var latest_portrait := character_node.get_child(-1)
if not is_instance_valid(character_node):
push_error("[Dialogic] Invalid character node provided.")
return
if latest_portrait.has_method('_set_extra_data'):
latest_portrait._set_extra_data(extra_data)
if character_node.get_child_count() > 0:
var latest_portrait := character_node.get_child(-1)
if latest_portrait and latest_portrait.has_method("_set_extra_data"):
latest_portrait._set_extra_data(extra_data)
else:
push_warning("[Dialogic] No portrait found for character node: " + character_node.name)
func _update_character_transform(character_node:Node, time := 0.0) -> void:
for child in character_node.get_children():
@ -287,7 +306,7 @@ func _change_portrait_z_index(character_node: Node, z_index:int, update_zindex:=
## fully visible yet.
func get_character_portrait(character: DialogicCharacter) -> DialogicPortrait:
if is_character_joined(character):
var portrait_node: DialogicPortrait = dialogic.current_state_info['portraits'][character.resource_path].node.get_child(-1)
var portrait_node: DialogicPortrait = dialogic.current_state_info['portraits'][character.get_identifier()].node.get_child(-1)
return portrait_node
return null
@ -342,7 +361,7 @@ func get_valid_portrait(character:DialogicCharacter, portrait:String) -> String:
if not portrait in character.portraits:
if not portrait.is_empty():
printerr('[Dialogic] Tried to use invalid portrait "', portrait, '" on character "', DialogicResourceUtil.get_unique_identifier(character.resource_path), '". Using default portrait instead.')
printerr('[Dialogic] Tried to use invalid portrait "', portrait, '" on character "', character.get_character_name(), '". Using default portrait instead.')
dialogic.print_debug_moment()
portrait = character.default_portrait
@ -379,18 +398,18 @@ func join_character(character:DialogicCharacter, portrait:String, position_id:S
return
var container := dialogic.PortraitContainers.add_container(character.get_character_name())
var character_node := add_character(character, container, portrait, position_id)
var character_node := await add_character(character, container, portrait, position_id)
if character_node == null:
return null
dialogic.current_state_info['portraits'][character.resource_path] = {'portrait':portrait, 'node':character_node, 'position_id':position_id, 'custom_mirror':mirrored}
dialogic.current_state_info['portraits'][character.get_identifier()] = {'portrait':portrait, 'node':character_node, 'position_id':position_id, 'custom_mirror':mirrored}
_change_portrait_mirror(character_node, mirrored)
_change_portrait_extradata(character_node, extra_data)
_change_portrait_z_index(character_node, z_index)
var info := {'character':character}
info.merge(dialogic.current_state_info['portraits'][character.resource_path])
info.merge(dialogic.current_state_info['portraits'][character.get_identifier()])
character_joined.emit(info)
if animation_name.is_empty():
@ -410,9 +429,9 @@ func join_character(character:DialogicCharacter, portrait:String, position_id:S
return character_node
func add_character(character:DialogicCharacter, container: DialogicNode_PortraitContainer, portrait:String, position_id:String) -> Node:
func add_character(character: DialogicCharacter, container: DialogicNode_PortraitContainer, portrait: String, position_id: String) -> Node:
if is_character_joined(character):
printerr('[DialogicError] Cannot add a already joined character. If this is intended call _create_character_node manually.')
printerr('[DialogicError] Cannot add an already joined character. If this is intended, call _create_character_node manually.')
return null
portrait = get_valid_portrait(character, portrait)
@ -430,36 +449,35 @@ func add_character(character:DialogicCharacter, container: DialogicNode_Portrait
printerr('[Dialogic] Failed to join character to position ', position_id, ". Could not find position container.")
return null
dialogic.current_state_info['portraits'][character.resource_path] = {'portrait':portrait, 'node':character_node, 'position_id':position_id}
dialogic.current_state_info['portraits'][character.get_identifier()] = {'portrait': portrait, 'node': character_node, 'position_id': position_id}
_move_character(character_node, position_id)
_change_portrait(character_node, portrait)
await _change_portrait(character_node, portrait)
return character_node
## Changes the portrait of a character. Only works with joined characters.
func change_character_portrait(character: DialogicCharacter, portrait: String, fade_animation:="DEFAULT", fade_length := -1.0) -> void:
func change_character_portrait(character: DialogicCharacter, portrait: String, fade_animation:="", fade_length := -1.0) -> void:
if not is_character_joined(character):
return
portrait = get_valid_portrait(character, portrait)
if dialogic.current_state_info.portraits[character.resource_path].portrait == portrait:
if dialogic.current_state_info.portraits[character.get_identifier()].portrait == portrait:
return
if fade_animation == "DEFAULT":
if fade_animation == "":
fade_animation = ProjectSettings.get_setting('dialogic/animations/cross_fade_default', "Fade Cross")
fade_length = ProjectSettings.get_setting('dialogic/animations/cross_fade_default_length', 0.5)
fade_animation = DialogicPortraitAnimationUtil.guess_animation(fade_animation, DialogicPortraitAnimationUtil.AnimationType.CROSSFADE)
var info := _change_portrait(dialogic.current_state_info.portraits[character.resource_path].node, portrait, fade_animation, fade_length)
dialogic.current_state_info.portraits[character.resource_path].portrait = info.portrait
var info := await _change_portrait(dialogic.current_state_info.portraits[character.get_identifier()].node, portrait, fade_animation, fade_length)
dialogic.current_state_info.portraits[character.get_identifier()].portrait = info.portrait
_change_portrait_mirror(
dialogic.current_state_info.portraits[character.resource_path].node,
dialogic.current_state_info.portraits[character.resource_path].get('custom_mirror', false)
dialogic.current_state_info.portraits[character.get_identifier()].node,
dialogic.current_state_info.portraits[character.get_identifier()].get('custom_mirror', false)
)
character_portrait_changed.emit(info)
@ -469,8 +487,8 @@ func change_character_mirror(character:DialogicCharacter, mirrored:= false, forc
if !is_character_joined(character):
return
_change_portrait_mirror(dialogic.current_state_info.portraits[character.resource_path].node, mirrored, force)
dialogic.current_state_info.portraits[character.resource_path]['custom_mirror'] = mirrored
_change_portrait_mirror(dialogic.current_state_info.portraits[character.get_identifier()].node, mirrored, force)
dialogic.current_state_info.portraits[character.get_identifier()]['custom_mirror'] = mirrored
## Changes the z_index of a character. Only works with joined characters
@ -478,17 +496,17 @@ func change_character_z_index(character:DialogicCharacter, z_index:int, update_z
if !is_character_joined(character):
return
_change_portrait_z_index(dialogic.current_state_info.portraits[character.resource_path].node, z_index, update_zindex)
_change_portrait_z_index(dialogic.current_state_info.portraits[character.get_identifier()].node, z_index, update_zindex)
if update_zindex:
dialogic.current_state_info.portraits[character.resource_path]['z_index'] = z_index
dialogic.current_state_info.portraits[character.get_identifier()]['z_index'] = z_index
## Changes the extra data on the given character. Only works with joined characters
func change_character_extradata(character:DialogicCharacter, extra_data:="") -> void:
if !is_character_joined(character):
return
_change_portrait_extradata(dialogic.current_state_info.portraits[character.resource_path].node, extra_data)
dialogic.current_state_info.portraits[character.resource_path]['extra_data'] = extra_data
_change_portrait_extradata(dialogic.current_state_info.portraits[character.get_identifier()].node, extra_data)
dialogic.current_state_info.portraits[character.get_identifier()]['extra_data'] = extra_data
## Starts the given animation on the given character. Only works with joined characters
@ -498,7 +516,7 @@ func animate_character(character: DialogicCharacter, animation_path: String, len
animation_path = DialogicPortraitAnimationUtil.guess_animation(animation_path)
var character_node: Node = dialogic.current_state_info.portraits[character.resource_path].node
var character_node: Node = dialogic.current_state_info.portraits[character.get_identifier()].node
return _animate_node(character_node, animation_path, length, repeats, is_reversed)
@ -508,11 +526,11 @@ func move_character(character:DialogicCharacter, position_id:String, time:= 0.0,
if !is_character_joined(character):
return
if dialogic.current_state_info.portraits[character.resource_path].position_id == position_id:
if dialogic.current_state_info.portraits[character.get_identifier()].position_id == position_id:
return
_move_character(dialogic.current_state_info.portraits[character.resource_path].node, position_id, time, easing, trans)
dialogic.current_state_info.portraits[character.resource_path].position_id = position_id
_move_character(dialogic.current_state_info.portraits[character.get_identifier()].node, position_id, time, easing, trans)
dialogic.current_state_info.portraits[character.get_identifier()].position_id = position_id
character_moved.emit({'character':character, 'position_id':position_id, 'time':time})
@ -554,8 +572,8 @@ func leave_all_characters(animation_name:="", animation_length:=0.0, animation_w
## Return `null` if the [param character] is not part of the scene.
func get_character_node(character: DialogicCharacter) -> Node:
if is_character_joined(character):
if is_instance_valid(dialogic.current_state_info['portraits'][character.resource_path].node):
return dialogic.current_state_info['portraits'][character.resource_path].node
if is_instance_valid(dialogic.current_state_info['portraits'][character.get_identifier()].node):
return dialogic.current_state_info['portraits'][character.get_identifier()].node
return null
@ -571,19 +589,12 @@ func remove_character(character: DialogicCharacter) -> void:
character_node.queue_free()
character_left.emit({'character': character})
dialogic.current_state_info['portraits'].erase(character.resource_path)
func get_current_character() -> DialogicCharacter:
if dialogic.current_state_info.get('speaker', null):
return load(dialogic.current_state_info.speaker)
return null
dialogic.current_state_info['portraits'].erase(character.get_identifier())
## Returns true if the given character is currently joined.
func is_character_joined(character: DialogicCharacter) -> bool:
if character == null or not character.resource_path in dialogic.current_state_info['portraits']:
if character == null or not character.get_identifier() in dialogic.current_state_info['portraits']:
return false
return true
@ -593,8 +604,8 @@ func is_character_joined(character: DialogicCharacter) -> bool:
func get_joined_characters() -> Array[DialogicCharacter]:
var chars: Array[DialogicCharacter] = []
for char_path: String in dialogic.current_state_info.get('portraits', {}).keys():
chars.append(load(char_path))
for char_identifier: String in dialogic.current_state_info.get('portraits', {}).keys():
chars.append(DialogicResourceUtil.get_character_resource(char_identifier))
return chars
@ -604,7 +615,7 @@ func get_joined_characters() -> Array[DialogicCharacter]:
## Only joined is included (and false) for not joined characters
func get_character_info(character:DialogicCharacter) -> Dictionary:
if is_character_joined(character):
var info: Dictionary = dialogic.current_state_info['portraits'][character.resource_path]
var info: Dictionary = dialogic.current_state_info['portraits'][character.get_identifier()]
info['joined'] = true
return info
else:
@ -629,7 +640,8 @@ func change_speaker(speaker: DialogicCharacter = null, portrait := "") -> void:
if leave_animation and leave_animation_length:
var animate_out := _animate_node(character_node, leave_animation, leave_animation_length, 1, true)
animate_out.finished.connect(character_node.queue_free)
await animate_out.finished
character_node.queue_free()
else:
character_node.get_parent().remove_child(character_node)
character_node.queue_free()
@ -655,10 +667,10 @@ func change_speaker(speaker: DialogicCharacter = null, portrait := "") -> void:
fade_animation = DialogicPortraitAnimationUtil.guess_animation(fade_animation, DialogicPortraitAnimationUtil.AnimationType.CROSSFADE)
if container.portrait_prefix+portrait in speaker.portraits:
portrait = container.portrait_prefix+portrait
if container.portrait_prefix + portrait in speaker.portraits:
portrait = container.portrait_prefix + portrait
_change_portrait(character_node, portrait, fade_animation, fade_length)
await _change_portrait(character_node, portrait, fade_animation, fade_length)
# if the character has no portraits _change_portrait won't actually add a child node
if character_node.get_child_count() == 0:
@ -671,26 +683,28 @@ func change_speaker(speaker: DialogicCharacter = null, portrait := "") -> void:
character_node.hide()
if not container.is_visible_in_tree():
await get_tree().process_frame
# There is chance that the style changed (due to a speaker style) and thus the character node is gone now.
# In that case, just give up.
if not is_instance_valid(character_node):
return
character_node.show()
var join_animation: String = ProjectSettings.get_setting('dialogic/animations/join_default', "Fade In Up")
join_animation = DialogicPortraitAnimationUtil.guess_animation(join_animation, DialogicPortraitAnimationUtil.AnimationType.IN)
var join_animation_length := _get_join_default_length()
if join_animation and join_animation_length:
_animate_node(character_node, join_animation, join_animation_length)
await _animate_node(character_node, join_animation, join_animation_length).finished
_change_portrait_mirror(character_node)
if speaker:
if speaker.resource_path != dialogic.current_state_info['speaker']:
if dialogic.current_state_info['speaker'] and is_character_joined(load(dialogic.current_state_info['speaker'])):
dialogic.current_state_info['portraits'][dialogic.current_state_info['speaker']].node.get_child(-1)._unhighlight()
var prev_speaker: DialogicCharacter = dialogic.Text.get_current_speaker()
if speaker != prev_speaker:
if is_character_joined(prev_speaker):
dialogic.current_state_info["portraits"][prev_speaker.get_identifier()].node.get_child(-1)._unhighlight()
if speaker and is_character_joined(speaker):
dialogic.current_state_info['portraits'][speaker.resource_path].node.get_child(-1)._highlight()
elif dialogic.current_state_info['speaker'] and is_character_joined(load(dialogic.current_state_info['speaker'])):
dialogic.current_state_info['portraits'][dialogic.current_state_info['speaker']].node.get_child(-1)._unhighlight()
if is_character_joined(speaker):
dialogic.current_state_info["portraits"][speaker.get_identifier()].node.get_child(-1)._highlight()
#endregion
@ -701,14 +715,15 @@ func change_speaker(speaker: DialogicCharacter = null, portrait := "") -> void:
## Called from the [portrait=something] text effect.
func text_effect_portrait(_text_node:Control, _skipped:bool, argument:String) -> void:
if argument:
if dialogic.current_state_info.get('speaker', null):
change_character_portrait(load(dialogic.current_state_info.speaker), argument)
change_speaker(load(dialogic.current_state_info.speaker), argument)
var current_speaker := dialogic.Text.get_current_speaker()
if current_speaker:
change_character_portrait(current_speaker, argument)
change_speaker(current_speaker, argument)
## Called from the [extra_data=something] text effect.
func text_effect_extradata(_text_node:Control, _skipped:bool, argument:String) -> void:
if argument:
if dialogic.current_state_info.get('speaker', null):
change_character_extradata(load(dialogic.current_state_info.speaker), argument)
if dialogic.Text.get_current_speaker():
change_character_extradata(dialogic.Text.get_current_speaker(), argument)
#endregion

View file

@ -1 +1 @@
uid://c1531cn2fwxf6
uid://fyhfur7bpp4v