From f3e583ac777ee8473949e9e35e1bcdab0ee53b2d Mon Sep 17 00:00:00 2001 From: Jowan-Spooner Date: Tue, 25 Jun 2024 09:24:41 +0200 Subject: [PATCH 1/7] Code cleanup --- addons/dialogic/Core/DialogicResourceUtil.gd | 4 +-- addons/dialogic/Editor/editor_main.gd | 4 +-- .../Layer_VN_Textbox/animations.gd | 26 +++++++++---------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/addons/dialogic/Core/DialogicResourceUtil.gd b/addons/dialogic/Core/DialogicResourceUtil.gd index d8e978fa0..6bb6b17b4 100644 --- a/addons/dialogic/Core/DialogicResourceUtil.gd +++ b/addons/dialogic/Core/DialogicResourceUtil.gd @@ -218,8 +218,6 @@ static func guess_special_resource(type: String, string: String, default := {}, printerr("[Dialogic] No ", type, "s found, but attempted to use one.") return default - string = string.to_lower() - if string.begins_with('res://'): for i in resources.values(): if i.path == string: @@ -227,6 +225,8 @@ static func guess_special_resource(type: String, string: String, default := {}, printerr("[Dialogic] Unable to find ", type, " at path '", string, "'.") return default + string = string.to_lower() + if string in resources: return resources[string] diff --git a/addons/dialogic/Editor/editor_main.gd b/addons/dialogic/Editor/editor_main.gd index f5c60d6e1..5d7aa96e3 100644 --- a/addons/dialogic/Editor/editor_main.gd +++ b/addons/dialogic/Editor/editor_main.gd @@ -15,7 +15,7 @@ func _ready() -> void: ## REFERENCES editors_manager = $EditorsManager - var button :Button = editors_manager.add_icon_button(get_theme_icon("MakeFloating", "EditorIcons"), 'Make floating') + var button: Button = editors_manager.add_icon_button(get_theme_icon("MakeFloating", "EditorIcons"), 'Make floating') button.pressed.connect(toggle_floating_window) # File dialog @@ -86,7 +86,7 @@ func update_theme_additions() -> void: # panel used for example for portrait previews in character editor theme.set_type_variation('DialogicPanelB', 'PanelContainer') - var side_panel :StyleBoxFlat= panel_style.duplicate() + var side_panel: StyleBoxFlat = panel_style.duplicate() side_panel.corner_radius_top_left = 0 side_panel.corner_radius_bottom_left = 0 side_panel.expand_margin_left = 8 diff --git a/addons/dialogic/Modules/DefaultLayoutParts/Layer_VN_Textbox/animations.gd b/addons/dialogic/Modules/DefaultLayoutParts/Layer_VN_Textbox/animations.gd index 43eca1f7d..ed3f9a017 100644 --- a/addons/dialogic/Modules/DefaultLayoutParts/Layer_VN_Textbox/animations.gd +++ b/addons/dialogic/Modules/DefaultLayoutParts/Layer_VN_Textbox/animations.gd @@ -7,11 +7,12 @@ enum AnimationsIn {NONE, POP_IN, FADE_UP} enum AnimationsOut {NONE, POP_OUT, FADE_DOWN} enum AnimationsNewText {NONE, WIGGLE} -var animation_in : AnimationsIn -var animation_out : AnimationsOut -var animation_new_text : AnimationsNewText +var animation_in: AnimationsIn +var animation_out: AnimationsOut +var animation_new_text: AnimationsNewText + +var full_clear := true -var full_clear : bool = true func get_text_panel() -> PanelContainer: return %DialogTextPanel @@ -23,18 +24,17 @@ func get_dialog() -> DialogicNode_DialogText: func _ready() -> void: var text_system : Node = DialogicUtil.autoload().get(&'Text') - var _error : int = 0 - _error = text_system.connect(&'animation_textbox_hide', _on_textbox_hide) - _error = text_system.connect(&'animation_textbox_show', _on_textbox_show) - _error = text_system.connect(&'animation_textbox_new_text', _on_textbox_new_text) - _error = text_system.connect(&'about_to_show_text', _on_about_to_show_text) + text_system.connect(&'animation_textbox_hide', _on_textbox_hide) + text_system.connect(&'animation_textbox_show', _on_textbox_show) + text_system.connect(&'animation_textbox_new_text', _on_textbox_new_text) + text_system.connect(&'about_to_show_text', _on_about_to_show_text) func _on_textbox_show() -> void: if animation_in == AnimationsIn.NONE: return play('RESET') - var animation_system : Node = DialogicUtil.autoload().get(&'Animations') + var animation_system: Node = DialogicUtil.autoload().get(&'Animations') animation_system.call(&'start_animating') get_text_panel().get_parent().get_parent().set(&'modulate', Color.TRANSPARENT) get_dialog().text = "" @@ -74,7 +74,7 @@ func _on_textbox_new_text() -> void: if animation_new_text == AnimationsNewText.NONE: return - var animation_system : Node = DialogicUtil.autoload().get(&'Animation') + var animation_system: Node = DialogicUtil.autoload().get(&'Animations') animation_system.call(&'start_animating') if full_clear: get_dialog().text = "" @@ -82,5 +82,5 @@ func _on_textbox_new_text() -> void: AnimationsNewText.WIGGLE: play("new_text") - if not is_connected(&'animation_finished', Callable(animation_system, &'animation_finished')): - var _error : int = connect(&'animation_finished', Callable(animation_system, &'animation_finished'), CONNECT_ONE_SHOT) + if not animation_finished.is_connected(Callable(animation_system, &'animation_finished')): + animation_finished.connect(Callable(animation_system, &'animation_finished'), CONNECT_ONE_SHOT) From 3264a38c64b3ed424b5f82655750f35c153be421 Mon Sep 17 00:00:00 2001 From: Jowan-Spooner Date: Tue, 25 Jun 2024 09:34:09 +0200 Subject: [PATCH 2/7] Avoid errors --- addons/dialogic/Modules/Character/subsystem_containers.gd | 2 +- addons/dialogic/Modules/Character/subsystem_portraits.gd | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/dialogic/Modules/Character/subsystem_containers.gd b/addons/dialogic/Modules/Character/subsystem_containers.gd index a129d52ae..cf89c3476 100644 --- a/addons/dialogic/Modules/Character/subsystem_containers.gd +++ b/addons/dialogic/Modules/Character/subsystem_containers.gd @@ -181,7 +181,7 @@ 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.set_deferred("size", final_rect_resize) save_position_container(container) position_changed.emit({&'change':'resized', &'container_node':container}) diff --git a/addons/dialogic/Modules/Character/subsystem_portraits.gd b/addons/dialogic/Modules/Character/subsystem_portraits.gd index b7377be89..e09025417 100644 --- a/addons/dialogic/Modules/Character/subsystem_portraits.gd +++ b/addons/dialogic/Modules/Character/subsystem_portraits.gd @@ -255,6 +255,7 @@ func _animate_node(node: Node, animation_path: String, length: float, repeats := func _move_character(character_node: Node2D, transform:="", time := 0.0, easing:= Tween.EASE_IN_OUT, trans:= Tween.TRANS_SINE) -> void: var tween := character_node.create_tween().set_ease(easing).set_trans(trans).set_parallel() if time == 0: + tween.kill() tween = null var container: DialogicNode_PortraitContainer = character_node.get_parent() dialogic.PortraitContainers.move_container(container, transform, tween, time) From 830ff8d4afc0163a8d247423d7b06a1285e6ce16 Mon Sep 17 00:00:00 2001 From: Jowan-Spooner Date: Tue, 25 Jun 2024 09:48:00 +0200 Subject: [PATCH 3/7] Make sure all animations are considered finished on clear() Some methods where awaiting Animations.finished and that could carry into the next session. - fixes #2273 --- addons/dialogic/Modules/Core/subsystem_animation.gd | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/addons/dialogic/Modules/Core/subsystem_animation.gd b/addons/dialogic/Modules/Core/subsystem_animation.gd index cffba65a5..410bac4bd 100644 --- a/addons/dialogic/Modules/Core/subsystem_animation.gd +++ b/addons/dialogic/Modules/Core/subsystem_animation.gd @@ -10,6 +10,10 @@ var prev_state: int = 0 #region MAIN METHODS #################################################################################################### +func clear_game_state(_clear_flag := DialogicGameHandler.ClearFlags.FULL_CLEAR) -> void: + animation_finished() + + func is_animating() -> bool: return dialogic.current_state == dialogic.States.ANIMATING From de2b918702e0454bc2fc9c9711cd1e9de971358a Mon Sep 17 00:00:00 2001 From: Jowan-Spooner Date: Tue, 25 Jun 2024 10:22:03 +0200 Subject: [PATCH 4/7] Properly interrupt animations to fix #2163 --- .../Modules/Core/subsystem_animation.gd | 18 +++++++++++++++--- .../Layer_VN_Textbox/animations.gd | 19 +++++++++++++------ .../dialogic/Modules/Text/subsystem_text.gd | 3 +-- addons/dialogic/Modules/Wait/event_wait.gd | 10 +++++++--- 4 files changed, 36 insertions(+), 14 deletions(-) diff --git a/addons/dialogic/Modules/Core/subsystem_animation.gd b/addons/dialogic/Modules/Core/subsystem_animation.gd index 410bac4bd..476913442 100644 --- a/addons/dialogic/Modules/Core/subsystem_animation.gd +++ b/addons/dialogic/Modules/Core/subsystem_animation.gd @@ -3,28 +3,40 @@ extends DialogicSubsystem ## Subsystem that allows entering and leaving an animation state. signal finished +signal animation_interrupted -var prev_state: int = 0 +var prev_state: DialogicGameHandler.States = DialogicGameHandler.States.IDLE +var _is_animating := false #region MAIN METHODS #################################################################################################### func clear_game_state(_clear_flag := DialogicGameHandler.ClearFlags.FULL_CLEAR) -> void: - animation_finished() + stop_animation() func is_animating() -> bool: - return dialogic.current_state == dialogic.States.ANIMATING + return _is_animating func start_animating() -> void: prev_state = dialogic.current_state dialogic.current_state = dialogic.States.ANIMATING + _is_animating = true func animation_finished(_arg := "") -> void: + # It can happen that the animation state has already been stopped + if not is_animating(): + return + _is_animating = false dialogic.current_state = prev_state as DialogicGameHandler.States finished.emit() + +func stop_animation() -> void: + animation_finished() + animation_interrupted.emit() + #endregion diff --git a/addons/dialogic/Modules/DefaultLayoutParts/Layer_VN_Textbox/animations.gd b/addons/dialogic/Modules/DefaultLayoutParts/Layer_VN_Textbox/animations.gd index ed3f9a017..c03b3ee0d 100644 --- a/addons/dialogic/Modules/DefaultLayoutParts/Layer_VN_Textbox/animations.gd +++ b/addons/dialogic/Modules/DefaultLayoutParts/Layer_VN_Textbox/animations.gd @@ -23,11 +23,13 @@ func get_dialog() -> DialogicNode_DialogText: func _ready() -> void: - var text_system : Node = DialogicUtil.autoload().get(&'Text') + var text_system: Node = DialogicUtil.autoload().get(&'Text') text_system.connect(&'animation_textbox_hide', _on_textbox_hide) text_system.connect(&'animation_textbox_show', _on_textbox_show) text_system.connect(&'animation_textbox_new_text', _on_textbox_new_text) text_system.connect(&'about_to_show_text', _on_about_to_show_text) + var animation_system: Node = DialogicUtil.autoload().get(&'Animations') + animation_system.connect(&'animation_interrupted', _on_animation_interrupted) func _on_textbox_show() -> void: @@ -43,15 +45,15 @@ func _on_textbox_show() -> void: play("textbox_pop") AnimationsIn.FADE_UP: play("textbox_fade_up") - if not is_connected(&'animation_finished', Callable(animation_system, &'animation_finished')): - var _error : int = connect(&'animation_finished', Callable(animation_system, &'animation_finished'), CONNECT_ONE_SHOT) + if not animation_finished.is_connected(Callable(animation_system, &'animation_finished')): + animation_finished.connect(Callable(animation_system, &'animation_finished'), CONNECT_ONE_SHOT) func _on_textbox_hide() -> void: if animation_out == AnimationsOut.NONE: return play('RESET') - var animation_system : Node = DialogicUtil.autoload().get(&'Animations') + var animation_system: Node = DialogicUtil.autoload().get(&'Animations') animation_system.call(&'start_animating') match animation_out: AnimationsOut.POP_OUT: @@ -59,8 +61,8 @@ func _on_textbox_hide() -> void: AnimationsOut.FADE_DOWN: play_backwards("textbox_fade_up") - if not is_connected(&'animation_finished', Callable(animation_system, &'animation_finished')): - var _error : int = connect(&'animation_finished', Callable(animation_system, &'animation_finished'), CONNECT_ONE_SHOT) + if not animation_finished.is_connected(Callable(animation_system, &'animation_finished')): + animation_finished.connect(Callable(animation_system, &'animation_finished'), CONNECT_ONE_SHOT) func _on_about_to_show_text(info:Dictionary) -> void: @@ -84,3 +86,8 @@ func _on_textbox_new_text() -> void: if not animation_finished.is_connected(Callable(animation_system, &'animation_finished')): animation_finished.connect(Callable(animation_system, &'animation_finished'), CONNECT_ONE_SHOT) + + +func _on_animation_interrupted() -> void: + if is_playing(): + stop() diff --git a/addons/dialogic/Modules/Text/subsystem_text.gd b/addons/dialogic/Modules/Text/subsystem_text.gd index 8a7e4d475..1c8adbe75 100644 --- a/addons/dialogic/Modules/Text/subsystem_text.gd +++ b/addons/dialogic/Modules/Text/subsystem_text.gd @@ -123,7 +123,6 @@ func update_textbox(text: String, instant := false) -> void: func update_dialog_text(text: String, instant := false, additional := false) -> String: update_text_speed() - if !instant: dialogic.current_state = dialogic.States.REVEALING_TEXT if additional: @@ -195,7 +194,7 @@ func show_textbox(instant:=false) -> void: for text_node in get_tree().get_nodes_in_group('dialogic_dialog_text'): if not text_node.enabled: continue - if !text_node.textbox_root.visible and !emitted: + if not text_node.textbox_root.visible and not emitted: animation_textbox_show.emit() text_node.textbox_root.show() if dialogic.Animations.is_animating(): diff --git a/addons/dialogic/Modules/Wait/event_wait.gd b/addons/dialogic/Modules/Wait/event_wait.gd index b37cc3cd5..699e69c17 100644 --- a/addons/dialogic/Modules/Wait/event_wait.gd +++ b/addons/dialogic/Modules/Wait/event_wait.gd @@ -24,11 +24,15 @@ func _execute() -> void: var time_per_event: float = dialogic.Inputs.auto_skip.time_per_event final_wait_time = min(time, time_per_event) + dialogic.current_state = dialogic.States.WAITING + if hide_text and dialogic.has_subsystem("Text"): - dialogic.Text.update_dialog_text('') + dialogic.Text.update_dialog_text('', true) dialogic.Text.hide_textbox() - dialogic.current_state = dialogic.States.WAITING - await dialogic.get_tree().create_timer(time, false, DialogicUtil.is_physics_timer()).timeout + + await dialogic.get_tree().create_timer(final_wait_time, false, DialogicUtil.is_physics_timer()).timeout + if dialogic.Animations.is_animating(): + dialogic.Animations.stop_animation() dialogic.current_state = dialogic.States.IDLE finish() From 51a40d66e709ad03092f956907fd54556f6460fb Mon Sep 17 00:00:00 2001 From: Jowan-Spooner Date: Tue, 25 Jun 2024 10:39:08 +0200 Subject: [PATCH 5/7] Improve input detection to fix #1976 --- addons/dialogic/Modules/Core/subsystem_input.gd | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/addons/dialogic/Modules/Core/subsystem_input.gd b/addons/dialogic/Modules/Core/subsystem_input.gd index 59d29d6cc..6c9164b96 100644 --- a/addons/dialogic/Modules/Core/subsystem_input.gd +++ b/addons/dialogic/Modules/Core/subsystem_input.gd @@ -92,7 +92,7 @@ func handle_input() -> void: ## Unhandled Input is used for all NON-Mouse based inputs. func _unhandled_input(event:InputEvent) -> void: - if Input.is_action_just_pressed(ProjectSettings.get_setting(_SETTING_INPUT_ACTION, _SETTING_INPUT_ACTION_DEFAULT), true): + if is_input_pressed(event, true): if event is InputEventMouse: return handle_input() @@ -101,14 +101,18 @@ func _unhandled_input(event:InputEvent) -> void: ## Input is used for all mouse based inputs. ## If any DialogicInputNode is present this won't do anything (because that node handles MouseInput then). func _input(event:InputEvent) -> void: - if Input.is_action_just_pressed(ProjectSettings.get_setting(_SETTING_INPUT_ACTION, _SETTING_INPUT_ACTION_DEFAULT)): - + if is_input_pressed(event): if not event is InputEventMouse or get_tree().get_nodes_in_group('dialogic_input').any(func(node):return node.is_visible_in_tree()): return handle_input() +func is_input_pressed(event: InputEvent, exact := false) -> bool: + var action := ProjectSettings.get_setting(_SETTING_INPUT_ACTION, _SETTING_INPUT_ACTION_DEFAULT) + return (event is InputEventAction and event.action == action) or Input.is_action_just_pressed(action, exact) + + ## This is called from the gui_input of the InputCatcher and DialogText nodes func handle_node_gui_input(event:InputEvent) -> void: if Input.is_action_just_pressed(ProjectSettings.get_setting(_SETTING_INPUT_ACTION, _SETTING_INPUT_ACTION_DEFAULT)): From be2908bfddc7037f9f8615b0308984a50e9c96bd Mon Sep 17 00:00:00 2001 From: Jowan-Spooner Date: Tue, 25 Jun 2024 10:47:30 +0200 Subject: [PATCH 6/7] Fix possible errors on autoskip _init _init is called again later, because we can't be certain of the order the subsystems are added in, but that could lead to it already being connected, so this is to avoid error messages. --- addons/dialogic/Modules/Text/auto_advance.gd | 2 +- addons/dialogic/Modules/Text/auto_skip.gd | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/dialogic/Modules/Text/auto_advance.gd b/addons/dialogic/Modules/Text/auto_advance.gd index baa566b7a..c48d1a791 100644 --- a/addons/dialogic/Modules/Text/auto_advance.gd +++ b/addons/dialogic/Modules/Text/auto_advance.gd @@ -1,5 +1,5 @@ -extends RefCounted class_name DialogicAutoAdvance +extends RefCounted ## This class holds the settings for the Auto-Advance feature. ## Changing the variables will alter the behaviour of Auto-Advance. ## diff --git a/addons/dialogic/Modules/Text/auto_skip.gd b/addons/dialogic/Modules/Text/auto_skip.gd index 84f42f8e3..2a614f257 100644 --- a/addons/dialogic/Modules/Text/auto_skip.gd +++ b/addons/dialogic/Modules/Text/auto_skip.gd @@ -1,5 +1,5 @@ -extends RefCounted class_name DialogicAutoSkip +extends RefCounted ## This class holds the settings for the Auto-Skip feature. ## Changing the variables will alter the behaviour of Auto-Skip. ## @@ -40,7 +40,7 @@ var time_per_event: float = 0.1 func _init() -> void: time_per_event = ProjectSettings.get_setting('dialogic/text/autoskip_time_per_event', time_per_event) - if DialogicUtil.autoload().has_subsystem('History'): + if DialogicUtil.autoload().has_subsystem("History") and not DialogicUtil.autoload().History.visited_event.is_connected(_handle_seen_event): DialogicUtil.autoload().History.visited_event.connect(_handle_seen_event) DialogicUtil.autoload().History.unvisited_event.connect(_handle_unseen_event) From 431edebf4186add6dbc40084c701e4861acc4f9a Mon Sep 17 00:00:00 2001 From: Jowan-Spooner Date: Tue, 25 Jun 2024 10:49:59 +0200 Subject: [PATCH 7/7] Fix potential error in textbubble script --- .../Modules/DefaultLayoutParts/Layer_Textbubble/text_bubble.gd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/dialogic/Modules/DefaultLayoutParts/Layer_Textbubble/text_bubble.gd b/addons/dialogic/Modules/DefaultLayoutParts/Layer_Textbubble/text_bubble.gd index ce69740cb..6e2e0e403 100644 --- a/addons/dialogic/Modules/DefaultLayoutParts/Layer_Textbubble/text_bubble.gd +++ b/addons/dialogic/Modules/DefaultLayoutParts/Layer_Textbubble/text_bubble.gd @@ -193,7 +193,7 @@ func add_choice_container(node:Container, alignment:=FlowContainer.ALIGNMENT_BEG func get_speaker_canvas_position() -> Vector2: - if node_to_point_at: + if is_instance_valid(node_to_point_at): if node_to_point_at is Node3D: base_position = get_viewport().get_camera_3d().unproject_position( (node_to_point_at as Node3D).global_position)