From 844d4a53864b2415671f69342ed005ebed8ce14a Mon Sep 17 00:00:00 2001 From: MateoP Date: Tue, 25 Aug 2026 19:03:24 -0500 Subject: [PATCH 01/16] implemented uisfx_player --- assets/third_party/sounds/ui/Click.wav | 3 + assets/third_party/sounds/ui/Click.wav.import | 24 +++++++ assets/third_party/sounds/ui/Click_single.wav | 3 + .../sounds/ui/Click_single.wav.import | 24 +++++++ project.godot | 1 + scenes/globals/uisfx_player/menu_ui_player.gd | 70 +++++++++++++++++++ .../uisfx_player/menu_ui_player.gd.uid | 1 + .../globals/uisfx_player/menu_ui_player.tscn | 10 +++ 8 files changed, 136 insertions(+) create mode 100644 assets/third_party/sounds/ui/Click.wav create mode 100644 assets/third_party/sounds/ui/Click.wav.import create mode 100644 assets/third_party/sounds/ui/Click_single.wav create mode 100644 assets/third_party/sounds/ui/Click_single.wav.import create mode 100644 scenes/globals/uisfx_player/menu_ui_player.gd create mode 100644 scenes/globals/uisfx_player/menu_ui_player.gd.uid create mode 100644 scenes/globals/uisfx_player/menu_ui_player.tscn diff --git a/assets/third_party/sounds/ui/Click.wav b/assets/third_party/sounds/ui/Click.wav new file mode 100644 index 0000000000..8fb189f0b6 --- /dev/null +++ b/assets/third_party/sounds/ui/Click.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e0928b532609d7572052c151cb70a0ea33dcdc30a71d3152c232faeec8c8fbea +size 18480 diff --git a/assets/third_party/sounds/ui/Click.wav.import b/assets/third_party/sounds/ui/Click.wav.import new file mode 100644 index 0000000000..4a8df8f1eb --- /dev/null +++ b/assets/third_party/sounds/ui/Click.wav.import @@ -0,0 +1,24 @@ +[remap] + +importer="wav" +type="AudioStreamWAV" +uid="uid://cba2ckeb3gxu1" +path="res://.godot/imported/Click.wav-e119b1599ed3552187fc9ad9f52c4f8f.sample" + +[deps] + +source_file="res://assets/third_party/sounds/ui/Click.wav" +dest_files=["res://.godot/imported/Click.wav-e119b1599ed3552187fc9ad9f52c4f8f.sample"] + +[params] + +force/8_bit=false +force/mono=false +force/max_rate=false +force/max_rate_hz=44100 +edit/trim=false +edit/normalize=false +edit/loop_mode=0 +edit/loop_begin=0 +edit/loop_end=-1 +compress/mode=2 diff --git a/assets/third_party/sounds/ui/Click_single.wav b/assets/third_party/sounds/ui/Click_single.wav new file mode 100644 index 0000000000..c2defab029 --- /dev/null +++ b/assets/third_party/sounds/ui/Click_single.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:433167c51ef67ed8c2b7ad44b157413e420bf2ac6448b2c313fc3ced38452c69 +size 8860 diff --git a/assets/third_party/sounds/ui/Click_single.wav.import b/assets/third_party/sounds/ui/Click_single.wav.import new file mode 100644 index 0000000000..3be9242625 --- /dev/null +++ b/assets/third_party/sounds/ui/Click_single.wav.import @@ -0,0 +1,24 @@ +[remap] + +importer="wav" +type="AudioStreamWAV" +uid="uid://pk4mvg05n0uo" +path="res://.godot/imported/Click_single.wav-8d682f41512d147806f7f717b940d4c4.sample" + +[deps] + +source_file="res://assets/third_party/sounds/ui/Click_single.wav" +dest_files=["res://.godot/imported/Click_single.wav-8d682f41512d147806f7f717b940d4c4.sample"] + +[params] + +force/8_bit=false +force/mono=false +force/max_rate=false +force/max_rate_hz=44100 +edit/trim=false +edit/normalize=false +edit/loop_mode=0 +edit/loop_begin=0 +edit/loop_end=-1 +compress/mode=2 diff --git a/project.godot b/project.godot index a0ebb146b7..fd43623a60 100644 --- a/project.godot +++ b/project.godot @@ -32,6 +32,7 @@ SceneSwitcher="*res://scenes/globals/scene_switcher/scene_switcher.gd" Transitions="*res://scenes/globals/scene_switcher/transitions/transitions.tscn" Settings="*res://scenes/globals/settings/settings.gd" MusicPlayer="*res://scenes/globals/music_player/music_player.tscn" +MenuUiPlayer="*uid://q3dc07xy31ty" CameraShake="*res://scenes/globals/camera_shaker/camera_shake.tscn" InputHelper="*res://addons/input_helper/input_helper.gd" PauseOverlay="*res://scenes/globals/pause/pause_overlay.tscn" diff --git a/scenes/globals/uisfx_player/menu_ui_player.gd b/scenes/globals/uisfx_player/menu_ui_player.gd new file mode 100644 index 0000000000..c2f3169c85 --- /dev/null +++ b/scenes/globals/uisfx_player/menu_ui_player.gd @@ -0,0 +1,70 @@ +# SPDX-FileCopyrightText: The Threadbare Authors +# SPDX-License-Identifier: MPL-2.0 +extends Node +## Global Menu UI player +## +## This singleton node handles playing UI SFX when interacting with any button +## in game. It runs once when entering the tree and connects the respective +## "pressed" signal with a function that reproduces a sound +## +## The sound reproduced depends on the type of interactable clicked + + +# Press and release click sound used for buttons +const CLICK = preload("uid://cba2ckeb3gxu1") + +# Press click sound used for sliders +const CLICK_SINGLE = preload("uid://pk4mvg05n0uo") + +@onready var menu_sfx_player: AudioStreamPlayer = %MenuSFXPlayer + + + +func _enter_tree() -> void: + get_tree().node_added.connect(_on_node_added) + + + + +func _on_node_added(node : Node) -> void: + + if node is CheckButton and !node.is_connected("toggled", _on_toggle_pressed): + node.toggled.connect(_on_toggle_pressed) + + elif node is Button and !node.is_connected("pressed", _on_button_pressed): + node.pressed.connect(_on_button_pressed) + + elif node is Slider and !node.is_connected("value_changed" ,_on_slider_value_changed): + node.value_changed.connect(_on_slider_value_changed) + + elif node is TabBar and !node.is_connected("tab_clicked" ,_on_slider_value_changed): + node.tab_clicked.connect(_on_button_pressed) + + +func _on_toggle_pressed(toggled_on: bool) -> void: + _set_player_sound(CLICK) + + if toggled_on: + menu_sfx_player.pitch_scale = 1.2 + else: + menu_sfx_player.pitch_scale = 0.7 + + menu_sfx_player.play() + + +func _on_button_pressed() -> void: + _set_player_sound(CLICK) + menu_sfx_player.pitch_scale = randf_range(0.95, 1.1) + menu_sfx_player.play() + + +func _on_slider_value_changed(_value : float) -> void: + _set_player_sound(CLICK_SINGLE) + menu_sfx_player.pitch_scale = randf_range(0.95, 1.1) + menu_sfx_player.play() + + +func _set_player_sound(sound: AudioStream) -> void: + if menu_sfx_player.stream != sound: + menu_sfx_player.stream = sound + diff --git a/scenes/globals/uisfx_player/menu_ui_player.gd.uid b/scenes/globals/uisfx_player/menu_ui_player.gd.uid new file mode 100644 index 0000000000..233a973224 --- /dev/null +++ b/scenes/globals/uisfx_player/menu_ui_player.gd.uid @@ -0,0 +1 @@ +uid://bpti2tbv1ufco diff --git a/scenes/globals/uisfx_player/menu_ui_player.tscn b/scenes/globals/uisfx_player/menu_ui_player.tscn new file mode 100644 index 0000000000..70d097b419 --- /dev/null +++ b/scenes/globals/uisfx_player/menu_ui_player.tscn @@ -0,0 +1,10 @@ +[gd_scene format=3 uid="uid://q3dc07xy31ty"] + +[ext_resource type="Script" uid="uid://bpti2tbv1ufco" path="res://scenes/globals/uisfx_player/menu_ui_player.gd" id="1_08877"] + +[node name="MenuSFXPlayer" type="Node" unique_id=1818340025] +script = ExtResource("1_08877") + +[node name="MenuSFXPlayer" type="AudioStreamPlayer" parent="." unique_id=818033647] +unique_name_in_owner = true +bus = &"SFX" From 79bf0dc5bb2190afe278652a8ef37680fbbec6f0 Mon Sep 17 00:00:00 2001 From: MateoP Date: Wed, 26 Aug 2026 12:52:24 -0500 Subject: [PATCH 02/16] Moved sound files to first_party --- assets/{third_party => first_party}/sounds/ui/Click.wav | 0 .../{third_party => first_party}/sounds/ui/Click.wav.import | 6 +++--- .../{third_party => first_party}/sounds/ui/Click_single.wav | 0 .../sounds/ui/Click_single.wav.import | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) rename assets/{third_party => first_party}/sounds/ui/Click.wav (100%) rename assets/{third_party => first_party}/sounds/ui/Click.wav.import (55%) rename assets/{third_party => first_party}/sounds/ui/Click_single.wav (100%) rename assets/{third_party => first_party}/sounds/ui/Click_single.wav.import (53%) diff --git a/assets/third_party/sounds/ui/Click.wav b/assets/first_party/sounds/ui/Click.wav similarity index 100% rename from assets/third_party/sounds/ui/Click.wav rename to assets/first_party/sounds/ui/Click.wav diff --git a/assets/third_party/sounds/ui/Click.wav.import b/assets/first_party/sounds/ui/Click.wav.import similarity index 55% rename from assets/third_party/sounds/ui/Click.wav.import rename to assets/first_party/sounds/ui/Click.wav.import index 4a8df8f1eb..e6764a8753 100644 --- a/assets/third_party/sounds/ui/Click.wav.import +++ b/assets/first_party/sounds/ui/Click.wav.import @@ -3,12 +3,12 @@ importer="wav" type="AudioStreamWAV" uid="uid://cba2ckeb3gxu1" -path="res://.godot/imported/Click.wav-e119b1599ed3552187fc9ad9f52c4f8f.sample" +path="res://.godot/imported/Click.wav-b391aa7af385e7297d353406bc92db11.sample" [deps] -source_file="res://assets/third_party/sounds/ui/Click.wav" -dest_files=["res://.godot/imported/Click.wav-e119b1599ed3552187fc9ad9f52c4f8f.sample"] +source_file="res://assets/first_party/sounds/ui/Click.wav" +dest_files=["res://.godot/imported/Click.wav-b391aa7af385e7297d353406bc92db11.sample"] [params] diff --git a/assets/third_party/sounds/ui/Click_single.wav b/assets/first_party/sounds/ui/Click_single.wav similarity index 100% rename from assets/third_party/sounds/ui/Click_single.wav rename to assets/first_party/sounds/ui/Click_single.wav diff --git a/assets/third_party/sounds/ui/Click_single.wav.import b/assets/first_party/sounds/ui/Click_single.wav.import similarity index 53% rename from assets/third_party/sounds/ui/Click_single.wav.import rename to assets/first_party/sounds/ui/Click_single.wav.import index 3be9242625..9ccc548583 100644 --- a/assets/third_party/sounds/ui/Click_single.wav.import +++ b/assets/first_party/sounds/ui/Click_single.wav.import @@ -3,12 +3,12 @@ importer="wav" type="AudioStreamWAV" uid="uid://pk4mvg05n0uo" -path="res://.godot/imported/Click_single.wav-8d682f41512d147806f7f717b940d4c4.sample" +path="res://.godot/imported/Click_single.wav-38b6465c402d8756cbd27c2c22f0e502.sample" [deps] -source_file="res://assets/third_party/sounds/ui/Click_single.wav" -dest_files=["res://.godot/imported/Click_single.wav-8d682f41512d147806f7f717b940d4c4.sample"] +source_file="res://assets/first_party/sounds/ui/Click_single.wav" +dest_files=["res://.godot/imported/Click_single.wav-38b6465c402d8756cbd27c2c22f0e502.sample"] [params] From dff43b45f73504593d8370dc02d1785ac6666c19 Mon Sep 17 00:00:00 2001 From: MateoP Date: Wed, 26 Aug 2026 13:01:30 -0500 Subject: [PATCH 03/16] created multiple players --- scenes/globals/uisfx_player/menu_ui_player.tscn | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/scenes/globals/uisfx_player/menu_ui_player.tscn b/scenes/globals/uisfx_player/menu_ui_player.tscn index 70d097b419..4a2a2461f9 100644 --- a/scenes/globals/uisfx_player/menu_ui_player.tscn +++ b/scenes/globals/uisfx_player/menu_ui_player.tscn @@ -1,10 +1,23 @@ [gd_scene format=3 uid="uid://q3dc07xy31ty"] [ext_resource type="Script" uid="uid://bpti2tbv1ufco" path="res://scenes/globals/uisfx_player/menu_ui_player.gd" id="1_08877"] +[ext_resource type="AudioStream" uid="uid://pk4mvg05n0uo" path="res://assets/first_party/sounds/ui/Click_single.wav" id="2_a0vny"] + +[sub_resource type="AudioStreamRandomizer" id="AudioStreamRandomizer_7me2p"] +random_pitch = 1.005793 +streams_count = 1 +stream_0/stream = ExtResource("2_a0vny") [node name="MenuSFXPlayer" type="Node" unique_id=1818340025] script = ExtResource("1_08877") -[node name="MenuSFXPlayer" type="AudioStreamPlayer" parent="." unique_id=818033647] +[node name="SliderSFX" type="AudioStreamPlayer" parent="." unique_id=818033647] unique_name_in_owner = true +stream = SubResource("AudioStreamRandomizer_7me2p") bus = &"SFX" + +[node name="ButtonSFX" type="AudioStreamPlayer" parent="." unique_id=1487510413] + +[node name="ToggleONSFX" type="AudioStreamPlayer" parent="." unique_id=1221647971] + +[node name="ToggleOFFSFX" type="AudioStreamPlayer" parent="." unique_id=179480757] From 9a21a527d92b621c740dc1b4ccf9a97df8707f36 Mon Sep 17 00:00:00 2001 From: MateoP Date: Wed, 26 Aug 2026 13:13:28 -0500 Subject: [PATCH 04/16] updated code to fit new players --- scenes/globals/uisfx_player/menu_ui_player.gd | 60 +++++++------------ .../globals/uisfx_player/menu_ui_player.tscn | 19 ++++-- 2 files changed, 36 insertions(+), 43 deletions(-) diff --git a/scenes/globals/uisfx_player/menu_ui_player.gd b/scenes/globals/uisfx_player/menu_ui_player.gd index c2f3169c85..2403502f39 100644 --- a/scenes/globals/uisfx_player/menu_ui_player.gd +++ b/scenes/globals/uisfx_player/menu_ui_player.gd @@ -3,68 +3,50 @@ extends Node ## Global Menu UI player ## -## This singleton node handles playing UI SFX when interacting with any button -## in game. It runs once when entering the tree and connects the respective +## This singleton node handles playing UI SFX when interacting with any button +## in game. It runs once when entering the tree and connects the respective ## "pressed" signal with a function that reproduces a sound ## ## The sound reproduced depends on the type of interactable clicked - -# Press and release click sound used for buttons -const CLICK = preload("uid://cba2ckeb3gxu1") - -# Press click sound used for sliders -const CLICK_SINGLE = preload("uid://pk4mvg05n0uo") - -@onready var menu_sfx_player: AudioStreamPlayer = %MenuSFXPlayer - +@onready var slider_sfx_player: AudioStreamPlayer = %SliderSFXPlayer +@onready var button_sfx_player: AudioStreamPlayer = $ButtonSFXPlayer +@onready var toggle_on_sfx_player: AudioStreamPlayer = $ToggleOnSFXPlayer +@onready var toggle_off_sfx_player: AudioStreamPlayer = $ToggleOffSFXPlayer func _enter_tree() -> void: get_tree().node_added.connect(_on_node_added) - - -func _on_node_added(node : Node) -> void: - +func _on_node_added(node: Node) -> void: if node is CheckButton and !node.is_connected("toggled", _on_toggle_pressed): node.toggled.connect(_on_toggle_pressed) - + elif node is Button and !node.is_connected("pressed", _on_button_pressed): node.pressed.connect(_on_button_pressed) - - elif node is Slider and !node.is_connected("value_changed" ,_on_slider_value_changed): + + elif node is Slider and !node.is_connected("value_changed", _on_slider_value_changed): node.value_changed.connect(_on_slider_value_changed) - - elif node is TabBar and !node.is_connected("tab_clicked" ,_on_slider_value_changed): - node.tab_clicked.connect(_on_button_pressed) - + + elif node is TabBar and !node.is_connected("tab_clicked", _on_slider_value_changed): + node.tab_clicked.connect(_on_tab_clicked) + func _on_toggle_pressed(toggled_on: bool) -> void: - _set_player_sound(CLICK) - if toggled_on: - menu_sfx_player.pitch_scale = 1.2 + toggle_on_sfx_player.play() else: - menu_sfx_player.pitch_scale = 0.7 - - menu_sfx_player.play() + toggle_off_sfx_player.play() func _on_button_pressed() -> void: - _set_player_sound(CLICK) - menu_sfx_player.pitch_scale = randf_range(0.95, 1.1) - menu_sfx_player.play() + button_sfx_player.play() -func _on_slider_value_changed(_value : float) -> void: - _set_player_sound(CLICK_SINGLE) - menu_sfx_player.pitch_scale = randf_range(0.95, 1.1) - menu_sfx_player.play() +func _on_slider_value_changed(_value: float) -> void: + slider_sfx_player.play() -func _set_player_sound(sound: AudioStream) -> void: - if menu_sfx_player.stream != sound: - menu_sfx_player.stream = sound - +func _on_tab_clicked(_tab: int) -> void: + button_sfx_player.play() diff --git a/scenes/globals/uisfx_player/menu_ui_player.tscn b/scenes/globals/uisfx_player/menu_ui_player.tscn index 4a2a2461f9..074e8c63c9 100644 --- a/scenes/globals/uisfx_player/menu_ui_player.tscn +++ b/scenes/globals/uisfx_player/menu_ui_player.tscn @@ -2,22 +2,33 @@ [ext_resource type="Script" uid="uid://bpti2tbv1ufco" path="res://scenes/globals/uisfx_player/menu_ui_player.gd" id="1_08877"] [ext_resource type="AudioStream" uid="uid://pk4mvg05n0uo" path="res://assets/first_party/sounds/ui/Click_single.wav" id="2_a0vny"] +[ext_resource type="AudioStream" uid="uid://cba2ckeb3gxu1" path="res://assets/first_party/sounds/ui/Click.wav" id="3_73s60"] [sub_resource type="AudioStreamRandomizer" id="AudioStreamRandomizer_7me2p"] random_pitch = 1.005793 streams_count = 1 stream_0/stream = ExtResource("2_a0vny") +[sub_resource type="AudioStreamRandomizer" id="AudioStreamRandomizer_a0vny"] +random_pitch = 1.0116194 +streams_count = 1 +stream_0/stream = ExtResource("3_73s60") + [node name="MenuSFXPlayer" type="Node" unique_id=1818340025] script = ExtResource("1_08877") -[node name="SliderSFX" type="AudioStreamPlayer" parent="." unique_id=818033647] +[node name="SliderSFXPlayer" type="AudioStreamPlayer" parent="." unique_id=818033647] unique_name_in_owner = true stream = SubResource("AudioStreamRandomizer_7me2p") bus = &"SFX" -[node name="ButtonSFX" type="AudioStreamPlayer" parent="." unique_id=1487510413] +[node name="ButtonSFXPlayer" type="AudioStreamPlayer" parent="." unique_id=1487510413] +stream = SubResource("AudioStreamRandomizer_a0vny") -[node name="ToggleONSFX" type="AudioStreamPlayer" parent="." unique_id=1221647971] +[node name="ToggleOnSFXPlayer" type="AudioStreamPlayer" parent="." unique_id=1221647971] +stream = ExtResource("3_73s60") +pitch_scale = 1.2 -[node name="ToggleOFFSFX" type="AudioStreamPlayer" parent="." unique_id=179480757] +[node name="ToggleOffSFXPlayer" type="AudioStreamPlayer" parent="." unique_id=179480757] +stream = ExtResource("3_73s60") +pitch_scale = 0.8 From de4f0a4274599acd7ffbc00b87dd5533a34d2c42 Mon Sep 17 00:00:00 2001 From: MateoP Date: Wed, 26 Aug 2026 13:29:36 -0500 Subject: [PATCH 05/16] random pitch for sliders and buttons --- scenes/globals/uisfx_player/menu_ui_player.tscn | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/scenes/globals/uisfx_player/menu_ui_player.tscn b/scenes/globals/uisfx_player/menu_ui_player.tscn index 074e8c63c9..6404665354 100644 --- a/scenes/globals/uisfx_player/menu_ui_player.tscn +++ b/scenes/globals/uisfx_player/menu_ui_player.tscn @@ -5,12 +5,12 @@ [ext_resource type="AudioStream" uid="uid://cba2ckeb3gxu1" path="res://assets/first_party/sounds/ui/Click.wav" id="3_73s60"] [sub_resource type="AudioStreamRandomizer" id="AudioStreamRandomizer_7me2p"] -random_pitch = 1.005793 +random_pitch = 1.122462 streams_count = 1 stream_0/stream = ExtResource("2_a0vny") [sub_resource type="AudioStreamRandomizer" id="AudioStreamRandomizer_a0vny"] -random_pitch = 1.0116194 +random_pitch = 1.122462 streams_count = 1 stream_0/stream = ExtResource("3_73s60") @@ -24,11 +24,14 @@ bus = &"SFX" [node name="ButtonSFXPlayer" type="AudioStreamPlayer" parent="." unique_id=1487510413] stream = SubResource("AudioStreamRandomizer_a0vny") +bus = &"SFX" [node name="ToggleOnSFXPlayer" type="AudioStreamPlayer" parent="." unique_id=1221647971] stream = ExtResource("3_73s60") pitch_scale = 1.2 +bus = &"SFX" [node name="ToggleOffSFXPlayer" type="AudioStreamPlayer" parent="." unique_id=179480757] stream = ExtResource("3_73s60") pitch_scale = 0.8 +bus = &"SFX" From d4b1c33bdb4c037e169bdbb086093e50fef7431a Mon Sep 17 00:00:00 2001 From: MateoP Date: Thu, 27 Aug 2026 12:50:27 -0500 Subject: [PATCH 06/16] audiostreams accessed by their unique names --- scenes/globals/uisfx_player/menu_ui_player.gd | 6 +++--- scenes/globals/uisfx_player/menu_ui_player.tscn | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/scenes/globals/uisfx_player/menu_ui_player.gd b/scenes/globals/uisfx_player/menu_ui_player.gd index 2403502f39..b92381cd42 100644 --- a/scenes/globals/uisfx_player/menu_ui_player.gd +++ b/scenes/globals/uisfx_player/menu_ui_player.gd @@ -10,9 +10,9 @@ extends Node ## The sound reproduced depends on the type of interactable clicked @onready var slider_sfx_player: AudioStreamPlayer = %SliderSFXPlayer -@onready var button_sfx_player: AudioStreamPlayer = $ButtonSFXPlayer -@onready var toggle_on_sfx_player: AudioStreamPlayer = $ToggleOnSFXPlayer -@onready var toggle_off_sfx_player: AudioStreamPlayer = $ToggleOffSFXPlayer +@onready var button_sfx_player: AudioStreamPlayer = %ButtonSFXPlayer +@onready var toggle_on_sfx_player: AudioStreamPlayer = %ToggleOnSFXPlayer +@onready var toggle_off_sfx_player: AudioStreamPlayer = %ToggleOffSFXPlayer func _enter_tree() -> void: diff --git a/scenes/globals/uisfx_player/menu_ui_player.tscn b/scenes/globals/uisfx_player/menu_ui_player.tscn index 6404665354..4370887681 100644 --- a/scenes/globals/uisfx_player/menu_ui_player.tscn +++ b/scenes/globals/uisfx_player/menu_ui_player.tscn @@ -23,15 +23,18 @@ stream = SubResource("AudioStreamRandomizer_7me2p") bus = &"SFX" [node name="ButtonSFXPlayer" type="AudioStreamPlayer" parent="." unique_id=1487510413] +unique_name_in_owner = true stream = SubResource("AudioStreamRandomizer_a0vny") bus = &"SFX" [node name="ToggleOnSFXPlayer" type="AudioStreamPlayer" parent="." unique_id=1221647971] +unique_name_in_owner = true stream = ExtResource("3_73s60") pitch_scale = 1.2 bus = &"SFX" [node name="ToggleOffSFXPlayer" type="AudioStreamPlayer" parent="." unique_id=179480757] +unique_name_in_owner = true stream = ExtResource("3_73s60") pitch_scale = 0.8 bus = &"SFX" From 3409e380ca237d6557bd950c715bbc48f8d43c77 Mon Sep 17 00:00:00 2001 From: MateoP Date: Tue, 8 Sep 2026 18:55:09 -0500 Subject: [PATCH 07/16] Eternal Loom new animation --- .../eternal_loom/components/eternal_loom.gd | 7 +- .../components/loom_offering_animation.gd | 96 ++++ .../components/loom_offering_animation.gd.uid | 1 + .../props/eternal_loom/eternal_loom.tscn | 411 +----------------- 4 files changed, 120 insertions(+), 395 deletions(-) create mode 100644 scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd create mode 100644 scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd.uid diff --git a/scenes/game_elements/props/eternal_loom/components/eternal_loom.gd b/scenes/game_elements/props/eternal_loom/components/eternal_loom.gd index b0d76d8768..0f9ae82b41 100644 --- a/scenes/game_elements/props/eternal_loom/components/eternal_loom.gd +++ b/scenes/game_elements/props/eternal_loom/components/eternal_loom.gd @@ -18,7 +18,8 @@ var elders: Array[Elder] @onready var interact_area: InteractArea = %InteractArea @onready var talk_behavior: TalkBehavior = %TalkBehavior -@onready var loom_offering_animation_player: AnimationPlayer = %LoomOfferingAnimationPlayer +@onready var loom_offering_animation: LoomOfferingAnimation = %LoomOfferingAnimation + func _find_elder(quest: Quest) -> Elder: @@ -90,8 +91,8 @@ func on_offering_succeeded() -> void: if load_error != OK: push_error("Failed to start loading %s: %s" % [cutscene_path, error_string(load_error)]) - loom_offering_animation_player.play(&"loom_offering") - await loom_offering_animation_player.animation_finished + loom_offering_animation.play_loom_animation() + await loom_offering_animation.animation_finished GameState.quest.inventory.clear_inventory() if load_error != OK: diff --git a/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd b/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd new file mode 100644 index 0000000000..e2d16f68de --- /dev/null +++ b/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd @@ -0,0 +1,96 @@ +@tool +extends Node2D +class_name LoomOfferingAnimation + +@onready var animation_path: Path2D = %AnimationPath +@onready var loom_offering_sound: AudioStreamPlayer2D = $LoomOfferingSound + + +@export var _play_animation: bool = false: + set(value): + play_loom_animation_debug() + +@export var animation_time : float = 5.0 +@export var debug_thread_count : int = 6 + + +signal animation_finished + +const WORLD_IMAGINATION = preload("uid://6bf8rum68wq3") +const WORLD_MEMORY = preload("uid://5wscjc8yqqts") +const WORLD_SPIRIT = preload("uid://cepg1o3ihp055") + + +func play_loom_animation() -> void: + _loom_animation_play(GameState.quest.inventory.items) + + +func play_loom_animation_debug() -> void: + var arr : Array[InventoryItem] + for i in range(debug_thread_count): + var _temp_item := InventoryItem.new() + _temp_item.type = InventoryItem.ItemType.MEMORY + arr.append(_temp_item) + _loom_animation_play(arr) + + +func _loom_animation_play(thread_list : Array[InventoryItem]) -> void: + + var animation_points := animation_path.curve.get_baked_points() + + loom_offering_sound.play() + + + var timer : float = animation_time / (animation_points.size() * 2.8) + var modifier : int = animation_points.size() / floor(thread_list.size()) + + var counter : int = 0 + for thread in thread_list: + + + var sprite := Sprite2D.new() + + match (thread.type): + InventoryItem.ItemType.MEMORY: + sprite.texture = WORLD_MEMORY + InventoryItem.ItemType.IMAGINATION: + sprite.texture = WORLD_IMAGINATION + InventoryItem.ItemType.SPIRIT: + sprite.texture = WORLD_SPIRIT + _ : + sprite.texture = WORLD_SPIRIT + + + sprite.position = animation_points[counter * modifier] + add_child(sprite) + + var tween := sprite.create_tween() + + if (counter == 0): + tween.finished.connect(_on_animation_finished) + + # Animation Start + tween.tween_property(sprite, "scale", Vector2(0,0), 0) + + tween.tween_property(sprite, "scale", Vector2(1,1), timer) + tween.parallel().tween_property(sprite, "position", animation_points[(counter * modifier + 1) % animation_points.size()], timer) + + # Thread Roundabout + for j in range(animation_points.size() - 1 + (thread_list.size() - counter) * modifier) : + var position_index : int = (counter * modifier + j + 2 ) % animation_points.size() + tween.tween_property(sprite, "position", animation_points[position_index], timer) + + # Final animation + tween.tween_property(sprite, "position", Vector2(0, 0), timer*2) + tween.tween_property(sprite, "modulate", Color(0,0,0,0), 0.5) + tween.parallel().tween_property(sprite, "scale", Vector2(3,3), 0.5) + + + counter = counter + 1 + + thread_list.back() + + +func _on_animation_finished() -> void: + print("finished!") + animation_finished.emit() diff --git a/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd.uid b/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd.uid new file mode 100644 index 0000000000..13e76f3e02 --- /dev/null +++ b/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd.uid @@ -0,0 +1 @@ +uid://byu17bpk0v5n7 diff --git a/scenes/game_elements/props/eternal_loom/eternal_loom.tscn b/scenes/game_elements/props/eternal_loom/eternal_loom.tscn index f0dba9095e..86593f01de 100644 --- a/scenes/game_elements/props/eternal_loom/eternal_loom.tscn +++ b/scenes/game_elements/props/eternal_loom/eternal_loom.tscn @@ -3,11 +3,9 @@ [ext_resource type="Script" uid="uid://dj5shb75ckk2a" path="res://scenes/game_elements/props/eternal_loom/components/eternal_loom.gd" id="1_0f752"] [ext_resource type="Texture2D" uid="uid://cj62bpasgf643" path="res://scenes/game_elements/props/eternal_loom/components/eternal_loom_blue.png" id="2_dj2yp"] [ext_resource type="Script" uid="uid://du8wfijr35r35" path="res://scenes/game_elements/props/interact_area/interact_area.gd" id="3_mjlja"] -[ext_resource type="Texture2D" uid="uid://5wscjc8yqqts" path="res://assets/first_party/collectibles/world_memory.png" id="4_12bvc"] [ext_resource type="Script" uid="uid://edcifob4jc4s" path="res://scenes/game_logic/talk_behavior.gd" id="4_eq7jh"] -[ext_resource type="Texture2D" uid="uid://6bf8rum68wq3" path="res://assets/first_party/collectibles/world_imagination.png" id="5_eq7jh"] [ext_resource type="Resource" uid="uid://yafw7bf362gh" path="res://scenes/game_elements/props/eternal_loom/components/eternal_loom_interaction.dialogue" id="5_k2bt4"] -[ext_resource type="Texture2D" uid="uid://cepg1o3ihp055" path="res://assets/first_party/collectibles/world_spirit.png" id="6_hfqem"] +[ext_resource type="Script" uid="uid://byu17bpk0v5n7" path="res://scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd" id="6_rle0d"] [ext_resource type="AudioStream" uid="uid://bg8u4en3hlo6w" path="res://assets/third_party/sounds/eternal_loom/EternalLoomShort.ogg" id="7_12bvc"] [ext_resource type="Texture2D" uid="uid://b5ooaiyxdrp6a" path="res://scenes/game_elements/components/light_texture_256x256.tres" id="9_mjlja"] [ext_resource type="Script" uid="uid://bk52qjv58locq" path="res://scenes/game_logic/light2d_behaviors/artificial_light_behavior.gd" id="10_k2bt4"] @@ -148,378 +146,15 @@ size = Vector2(393, 260) [sub_resource type="RectangleShape2D" id="RectangleShape2D_uhynt"] size = Vector2(50, 50) -[sub_resource type="Animation" id="Animation_x4prg"] -length = 0.001 -tracks/0/type = "value" -tracks/0/imported = false -tracks/0/enabled = true -tracks/0/path = NodePath("LoomOfferingAnimation/Imagination:scale") -tracks/0/interp = 1 -tracks/0/loop_wrap = true -tracks/0/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 0, -"values": [Vector2(1, 1)] -} -tracks/1/type = "value" -tracks/1/imported = false -tracks/1/enabled = true -tracks/1/path = NodePath("LoomOfferingAnimation/Spirit:scale") -tracks/1/interp = 1 -tracks/1/loop_wrap = true -tracks/1/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 0, -"values": [Vector2(1, 1)] -} -tracks/2/type = "value" -tracks/2/imported = false -tracks/2/enabled = true -tracks/2/path = NodePath("LoomOfferingAnimation/Memory:scale") -tracks/2/interp = 1 -tracks/2/loop_wrap = true -tracks/2/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 0, -"values": [Vector2(1, 1)] -} -tracks/3/type = "value" -tracks/3/imported = false -tracks/3/enabled = true -tracks/3/path = NodePath("LoomOfferingAnimation/Imagination:visible") -tracks/3/interp = 1 -tracks/3/loop_wrap = true -tracks/3/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 1, -"values": [false] -} -tracks/4/type = "value" -tracks/4/imported = false -tracks/4/enabled = true -tracks/4/path = NodePath("LoomOfferingAnimation/Spirit:visible") -tracks/4/interp = 1 -tracks/4/loop_wrap = true -tracks/4/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 1, -"values": [false] -} -tracks/5/type = "value" -tracks/5/imported = false -tracks/5/enabled = true -tracks/5/path = NodePath("LoomOfferingAnimation/Memory:visible") -tracks/5/interp = 1 -tracks/5/loop_wrap = true -tracks/5/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 1, -"values": [false] -} -tracks/6/type = "value" -tracks/6/imported = false -tracks/6/enabled = true -tracks/6/path = NodePath("LoomOfferingAnimation/Spirit:position") -tracks/6/interp = 1 -tracks/6/loop_wrap = true -tracks/6/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 0, -"values": [Vector2(-48, 33)] -} -tracks/7/type = "value" -tracks/7/imported = false -tracks/7/enabled = true -tracks/7/path = NodePath("LoomOfferingAnimation/Memory:position") -tracks/7/interp = 1 -tracks/7/loop_wrap = true -tracks/7/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 0, -"values": [Vector2(1, -34)] -} -tracks/8/type = "value" -tracks/8/imported = false -tracks/8/enabled = true -tracks/8/path = NodePath("LoomOfferingAnimation/Imagination:position") -tracks/8/interp = 1 -tracks/8/loop_wrap = true -tracks/8/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 0, -"values": [Vector2(50, 33)] -} -tracks/9/type = "value" -tracks/9/imported = false -tracks/9/enabled = true -tracks/9/path = NodePath("LoomOfferingAnimation/Spirit:modulate") -tracks/9/interp = 1 -tracks/9/loop_wrap = true -tracks/9/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 0, -"values": [Color(1, 1, 1, 1)] -} -tracks/10/type = "value" -tracks/10/imported = false -tracks/10/enabled = true -tracks/10/path = NodePath("LoomOfferingAnimation/Memory:modulate") -tracks/10/interp = 1 -tracks/10/loop_wrap = true -tracks/10/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 0, -"values": [Color(1, 1, 1, 1)] -} -tracks/11/type = "value" -tracks/11/imported = false -tracks/11/enabled = true -tracks/11/path = NodePath("LoomOfferingAnimation/Imagination:modulate") -tracks/11/interp = 1 -tracks/11/loop_wrap = true -tracks/11/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 0, -"values": [Color(1, 1, 1, 1)] -} -tracks/12/type = "value" -tracks/12/imported = false -tracks/12/enabled = true -tracks/12/path = NodePath("AnimatedSprite2D:modulate") -tracks/12/interp = 1 -tracks/12/loop_wrap = true -tracks/12/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 0, -"values": [Color(1, 1, 1, 1)] -} -tracks/13/type = "value" -tracks/13/imported = false -tracks/13/enabled = true -tracks/13/path = NodePath("LoomOfferingAnimation/LoomOfferingSound:playing") -tracks/13/interp = 1 -tracks/13/loop_wrap = true -tracks/13/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 1, -"values": [false] -} -tracks/14/type = "value" -tracks/14/imported = false -tracks/14/enabled = true -tracks/14/path = NodePath("LoomOfferingAnimation/LoomOfferingSound:volume_db") -tracks/14/interp = 1 -tracks/14/loop_wrap = true -tracks/14/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 0, -"values": [0.0] -} - -[sub_resource type="Animation" id="Animation_ytadt"] -resource_name = "loom_offering" -length = 5.0 -tracks/0/type = "value" -tracks/0/imported = false -tracks/0/enabled = true -tracks/0/path = NodePath("LoomOfferingAnimation/Imagination:scale") -tracks/0/interp = 1 -tracks/0/loop_wrap = true -tracks/0/keys = { -"times": PackedFloat32Array(0, 0.8, 3.16667, 3.6), -"transitions": PackedFloat32Array(1, 1, 1, 1), -"update": 0, -"values": [Vector2(0.001, 0.001), Vector2(1, 1), Vector2(1, 1), Vector2(3, 3)] -} -tracks/1/type = "value" -tracks/1/imported = false -tracks/1/enabled = true -tracks/1/path = NodePath("LoomOfferingAnimation/Spirit:scale") -tracks/1/interp = 1 -tracks/1/loop_wrap = true -tracks/1/keys = { -"times": PackedFloat32Array(0, 0.766667, 4.16667, 4.6), -"transitions": PackedFloat32Array(1, 1, 1, 1), -"update": 0, -"values": [Vector2(0.001, 0.001), Vector2(1, 1), Vector2(1, 1), Vector2(3, 3)] -} -tracks/2/type = "value" -tracks/2/imported = false -tracks/2/enabled = true -tracks/2/path = NodePath("LoomOfferingAnimation/Memory:scale") -tracks/2/interp = 1 -tracks/2/loop_wrap = true -tracks/2/keys = { -"times": PackedFloat32Array(0, 0.766667, 2.33333, 2.8), -"transitions": PackedFloat32Array(1, 1, 1, 1), -"update": 0, -"values": [Vector2(0.001, 0.001), Vector2(1, 1), Vector2(1, 1), Vector2(3, 3)] -} -tracks/3/type = "value" -tracks/3/imported = false -tracks/3/enabled = true -tracks/3/path = NodePath("LoomOfferingAnimation/Imagination:visible") -tracks/3/interp = 1 -tracks/3/loop_wrap = true -tracks/3/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 1, -"values": [true] -} -tracks/4/type = "value" -tracks/4/imported = false -tracks/4/enabled = true -tracks/4/path = NodePath("LoomOfferingAnimation/Spirit:visible") -tracks/4/interp = 1 -tracks/4/loop_wrap = true -tracks/4/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 1, -"values": [true] -} -tracks/5/type = "value" -tracks/5/imported = false -tracks/5/enabled = true -tracks/5/path = NodePath("LoomOfferingAnimation/Memory:visible") -tracks/5/interp = 1 -tracks/5/loop_wrap = true -tracks/5/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 1, -"values": [true] -} -tracks/6/type = "value" -tracks/6/imported = false -tracks/6/enabled = true -tracks/6/path = NodePath("LoomOfferingAnimation/Spirit:position") -tracks/6/interp = 2 -tracks/6/loop_wrap = true -tracks/6/keys = { -"times": PackedFloat32Array(0, 0.77, 1.5, 2.35, 3.18333, 4.15), -"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1), -"update": 0, -"values": [Vector2(-48, 33), Vector2(50, 33), Vector2(1, -34), Vector2(-48, 33), Vector2(50, 33), Vector2(1, -34)] -} -tracks/7/type = "value" -tracks/7/imported = false -tracks/7/enabled = true -tracks/7/path = NodePath("LoomOfferingAnimation/Memory:position") -tracks/7/interp = 2 -tracks/7/loop_wrap = true -tracks/7/keys = { -"times": PackedFloat32Array(0, 0.77, 1.49, 2.35), -"transitions": PackedFloat32Array(1, 1, 1, 1), -"update": 0, -"values": [Vector2(1, -34), Vector2(-48, 33), Vector2(50, 33), Vector2(1, -34)] -} -tracks/8/type = "value" -tracks/8/imported = false -tracks/8/enabled = true -tracks/8/path = NodePath("LoomOfferingAnimation/Imagination:position") -tracks/8/interp = 2 -tracks/8/loop_wrap = true -tracks/8/keys = { -"times": PackedFloat32Array(0, 0.77, 1.5, 2.33333, 3.16667), -"transitions": PackedFloat32Array(1, 1, 1, 1, 1), -"update": 0, -"values": [Vector2(50, 33), Vector2(1, -34), Vector2(-48, 33), Vector2(50, 33), Vector2(1, -34)] -} -tracks/9/type = "value" -tracks/9/imported = false -tracks/9/enabled = true -tracks/9/path = NodePath("LoomOfferingAnimation/Spirit:modulate") -tracks/9/interp = 1 -tracks/9/loop_wrap = true -tracks/9/keys = { -"times": PackedFloat32Array(0, 4.16667, 4.60667), -"transitions": PackedFloat32Array(1, 1, 1), -"update": 0, -"values": [Color(1, 1, 1, 1), Color(1, 1, 1, 1), Color(1, 1, 1, 0)] -} -tracks/10/type = "value" -tracks/10/imported = false -tracks/10/enabled = true -tracks/10/path = NodePath("LoomOfferingAnimation/Memory:modulate") -tracks/10/interp = 1 -tracks/10/loop_wrap = true -tracks/10/keys = { -"times": PackedFloat32Array(0, 2.34333, 2.78333), -"transitions": PackedFloat32Array(1, 1, 1), -"update": 0, -"values": [Color(1, 1, 1, 1), Color(1, 1, 1, 1), Color(1, 1, 1, 0)] -} -tracks/11/type = "value" -tracks/11/imported = false -tracks/11/enabled = true -tracks/11/path = NodePath("LoomOfferingAnimation/Imagination:modulate") -tracks/11/interp = 1 -tracks/11/loop_wrap = true -tracks/11/keys = { -"times": PackedFloat32Array(0, 3.16667, 3.63333), -"transitions": PackedFloat32Array(1, 1, 1), -"update": 0, -"values": [Color(1, 1, 1, 1), Color(1, 1, 1, 1), Color(1, 1, 1, 0)] -} -tracks/12/type = "value" -tracks/12/imported = false -tracks/12/enabled = true -tracks/12/path = NodePath("AnimatedSprite2D:modulate") -tracks/12/interp = 1 -tracks/12/loop_wrap = true -tracks/12/keys = { -"times": PackedFloat32Array(0, 1.7, 2.46667, 3.03333, 3.33333, 3.66667, 4.03333, 4.46667, 4.86667), -"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1), -"update": 0, -"values": [Color(1, 1, 1, 1), Color(1, 1, 1, 1), Color(1, 1, 1, 1), Color(0, 0.972549, 0, 1), Color(0, 0.972549, 0, 1), Color(1, 1, 0, 1), Color(1, 1, 0, 1), Color(1, 0, 0, 1), Color(1, 1, 1, 1)] -} -tracks/13/type = "value" -tracks/13/imported = false -tracks/13/enabled = true -tracks/13/path = NodePath("LoomOfferingAnimation/LoomOfferingSound:playing") -tracks/13/interp = 1 -tracks/13/loop_wrap = true -tracks/13/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 1, -"values": [true] -} -tracks/14/type = "value" -tracks/14/imported = false -tracks/14/enabled = true -tracks/14/path = NodePath("LoomOfferingAnimation/LoomOfferingSound:volume_db") -tracks/14/interp = 1 -tracks/14/loop_wrap = true -tracks/14/keys = { -"times": PackedFloat32Array(0, 4.33333, 5), -"transitions": PackedFloat32Array(1, 1, 1), -"update": 0, -"values": [0.0, 0.0, -60.0] -} - -[sub_resource type="AnimationLibrary" id="AnimationLibrary_x4prg"] +[sub_resource type="Curve2D" id="Curve2D_f3ofd"] +bake_interval = 512.0 _data = { -&"RESET": SubResource("Animation_x4prg"), -&"loom_offering": SubResource("Animation_ytadt") +"points": PackedVector2Array(0, 0, 0, 0, -1, -79, 0, 0, 0, 0, -40, -69, 0, 0, 0, 0, -69, -41, 0, 0, 0, 0, -80, -1, 0, 0, 0, 0, -70, 38, 0, 0, 0, 0, -40, 67, 0, 0, 0, 0, -2, 76, 0, 0, 0, 0, 38, 67, 0, 0, 0, 0, 67, 38, 0, 0, 0, 0, 78, -1, 0, 0, 0, 0, 67, -40, 0, 0, 0, 0, 38, -69) } +point_count = 12 + +[sub_resource type="CircleShape2D" id="CircleShape2D_7me2p"] +radius = 78.42 [node name="EternalLoom" type="Node2D" unique_id=630179356] script = ExtResource("1_0f752") @@ -556,7 +191,7 @@ metadata/_custom_type_script = "uid://du8wfijr35r35" [node name="CollisionShape2D" type="CollisionShape2D" parent="InteractArea" unique_id=1537085446] position = Vector2(0, 120) shape = SubResource("RectangleShape2D_uhynt") -debug_color = Color(0.600391, 0.54335, 0, 0.42) +debug_color = Color(0.6, 0.545, 0, 0.42) [node name="Marker" type="Marker2D" parent="InteractArea" unique_id=556753843] position = Vector2(0, -152) @@ -569,33 +204,25 @@ interact_area = NodePath("../InteractArea") metadata/_custom_type_script = "uid://edcifob4jc4s" [node name="LoomOfferingAnimation" type="Node2D" parent="." unique_id=515569025] +unique_name_in_owner = true z_index = 1 position = Vector2(0, 135) +script = ExtResource("6_rle0d") +_play_animation = null +debug_thread_count = 2 -[node name="LoomOfferingAnimationPlayer" type="AnimationPlayer" parent="LoomOfferingAnimation" unique_id=1836718462] +[node name="AnimationPath" type="Path2D" parent="LoomOfferingAnimation" unique_id=1718786189] unique_name_in_owner = true -root_node = NodePath("../..") -libraries/ = SubResource("AnimationLibrary_x4prg") - -[node name="Memory" type="Sprite2D" parent="LoomOfferingAnimation" unique_id=480436827] -visible = false -position = Vector2(1, -34) -texture = ExtResource("4_12bvc") - -[node name="Imagination" type="Sprite2D" parent="LoomOfferingAnimation" unique_id=1315423320] -visible = false -position = Vector2(50, 33) -texture = ExtResource("5_eq7jh") - -[node name="Spirit" type="Sprite2D" parent="LoomOfferingAnimation" unique_id=1417706099] -visible = false -position = Vector2(-48, 33) -texture = ExtResource("6_hfqem") +curve = SubResource("Curve2D_f3ofd") [node name="LoomOfferingSound" type="AudioStreamPlayer2D" parent="LoomOfferingAnimation" unique_id=1851096463] stream = ExtResource("7_12bvc") bus = &"SFX" +[node name="CollisionShape2D" type="CollisionShape2D" parent="LoomOfferingAnimation" unique_id=1229920001] +visible = false +shape = SubResource("CircleShape2D_7me2p") + [node name="PointLight2D" type="PointLight2D" parent="." unique_id=853151346 groups=["night-lights"]] visibility_layer = 2 position = Vector2(0, 39) From 6998727ee22cda66ee128f785cd56dc00cfec99b Mon Sep 17 00:00:00 2001 From: MateoP Date: Tue, 8 Sep 2026 19:07:53 -0500 Subject: [PATCH 08/16] small update --- .../eternal_loom/components/loom_offering_animation.gd | 2 ++ .../game_elements/props/eternal_loom/eternal_loom.tscn | 10 +--------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd b/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd index e2d16f68de..2b4161475c 100644 --- a/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd +++ b/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd @@ -1,3 +1,5 @@ +# SPDX-FileCopyrightText: The Threadbare Authors +# SPDX-License-Identifier: MPL-2.0 @tool extends Node2D class_name LoomOfferingAnimation diff --git a/scenes/game_elements/props/eternal_loom/eternal_loom.tscn b/scenes/game_elements/props/eternal_loom/eternal_loom.tscn index 86593f01de..cb02f37558 100644 --- a/scenes/game_elements/props/eternal_loom/eternal_loom.tscn +++ b/scenes/game_elements/props/eternal_loom/eternal_loom.tscn @@ -153,9 +153,6 @@ _data = { } point_count = 12 -[sub_resource type="CircleShape2D" id="CircleShape2D_7me2p"] -radius = 78.42 - [node name="EternalLoom" type="Node2D" unique_id=630179356] script = ExtResource("1_0f752") @@ -208,8 +205,7 @@ unique_name_in_owner = true z_index = 1 position = Vector2(0, 135) script = ExtResource("6_rle0d") -_play_animation = null -debug_thread_count = 2 +debug_thread_count = 12 [node name="AnimationPath" type="Path2D" parent="LoomOfferingAnimation" unique_id=1718786189] unique_name_in_owner = true @@ -219,10 +215,6 @@ curve = SubResource("Curve2D_f3ofd") stream = ExtResource("7_12bvc") bus = &"SFX" -[node name="CollisionShape2D" type="CollisionShape2D" parent="LoomOfferingAnimation" unique_id=1229920001] -visible = false -shape = SubResource("CircleShape2D_7me2p") - [node name="PointLight2D" type="PointLight2D" parent="." unique_id=853151346 groups=["night-lights"]] visibility_layer = 2 position = Vector2(0, 39) From d36306785e7909ff1634308b005e4e360fd665b1 Mon Sep 17 00:00:00 2001 From: MateoP Date: Tue, 8 Sep 2026 21:59:55 -0500 Subject: [PATCH 09/16] formatting --- .../components/loom_offering_animation.gd | 104 +++++++++--------- .../props/eternal_loom/eternal_loom.tscn | 1 - 2 files changed, 51 insertions(+), 54 deletions(-) diff --git a/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd b/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd index 2b4161475c..a4c596039e 100644 --- a/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd +++ b/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd @@ -1,98 +1,96 @@ # SPDX-FileCopyrightText: The Threadbare Authors # SPDX-License-Identifier: MPL-2.0 @tool -extends Node2D class_name LoomOfferingAnimation +extends Node2D -@onready var animation_path: Path2D = %AnimationPath -@onready var loom_offering_sound: AudioStreamPlayer2D = $LoomOfferingSound +signal animation_finished +const WORLD_IMAGINATION = preload("uid://6bf8rum68wq3") +const WORLD_MEMORY = preload("uid://5wscjc8yqqts") +const WORLD_SPIRIT = preload("uid://cepg1o3ihp055") @export var _play_animation: bool = false: set(value): play_loom_animation_debug() -@export var animation_time : float = 5.0 -@export var debug_thread_count : int = 6 - - -signal animation_finished +@export var animation_time: float = 5.0 +@export var debug_thread_count: int = 6 -const WORLD_IMAGINATION = preload("uid://6bf8rum68wq3") -const WORLD_MEMORY = preload("uid://5wscjc8yqqts") -const WORLD_SPIRIT = preload("uid://cepg1o3ihp055") +@onready var animation_path: Path2D = %AnimationPath +@onready var loom_offering_sound: AudioStreamPlayer2D = $LoomOfferingSound func play_loom_animation() -> void: _loom_animation_play(GameState.quest.inventory.items) +## Only used for the in-editor preview func play_loom_animation_debug() -> void: - var arr : Array[InventoryItem] + var arr: Array[InventoryItem] for i in range(debug_thread_count): - var _temp_item := InventoryItem.new() - _temp_item.type = InventoryItem.ItemType.MEMORY - arr.append(_temp_item) + var temp_item := InventoryItem.new() + temp_item.type = InventoryItem.ItemType.MEMORY + arr.append(temp_item) _loom_animation_play(arr) -func _loom_animation_play(thread_list : Array[InventoryItem]) -> void: - +func _loom_animation_play(thread_list: Array[InventoryItem]) -> void: var animation_points := animation_path.curve.get_baked_points() - + loom_offering_sound.play() - - - var timer : float = animation_time / (animation_points.size() * 2.8) - var modifier : int = animation_points.size() / floor(thread_list.size()) - - var counter : int = 0 + + # Time between each animation_point + var timer: float = animation_time / (animation_points.size() * 2.8) + # Separation between threads + var separator: int = animation_points.size() / floor(thread_list.size()) + + var counter: int = 0 for thread in thread_list: - - var sprite := Sprite2D.new() - - match (thread.type): + + match thread.type: InventoryItem.ItemType.MEMORY: sprite.texture = WORLD_MEMORY InventoryItem.ItemType.IMAGINATION: sprite.texture = WORLD_IMAGINATION InventoryItem.ItemType.SPIRIT: sprite.texture = WORLD_SPIRIT - _ : + _: sprite.texture = WORLD_SPIRIT - - - sprite.position = animation_points[counter * modifier] + + sprite.position = animation_points[counter * separator] add_child(sprite) - + var tween := sprite.create_tween() - - if (counter == 0): + + ## The first thread is the last to enter the loom + if counter == 0: tween.finished.connect(_on_animation_finished) - + # Animation Start - tween.tween_property(sprite, "scale", Vector2(0,0), 0) - - tween.tween_property(sprite, "scale", Vector2(1,1), timer) - tween.parallel().tween_property(sprite, "position", animation_points[(counter * modifier + 1) % animation_points.size()], timer) - - # Thread Roundabout - for j in range(animation_points.size() - 1 + (thread_list.size() - counter) * modifier) : - var position_index : int = (counter * modifier + j + 2 ) % animation_points.size() + tween.tween_property(sprite, "scale", Vector2(0, 0), 0) + + tween.tween_property(sprite, "scale", Vector2(1, 1), timer) + tween.parallel().tween_property( + sprite, + "position", + animation_points[(counter * separator + 1) % animation_points.size()], + timer + ) + + # Thread Cycle + for i in range(animation_points.size() - 1 + (thread_list.size() - counter) * separator): + var position_index: int = (counter * separator + i + 2) % animation_points.size() tween.tween_property(sprite, "position", animation_points[position_index], timer) - + # Final animation - tween.tween_property(sprite, "position", Vector2(0, 0), timer*2) - tween.tween_property(sprite, "modulate", Color(0,0,0,0), 0.5) - tween.parallel().tween_property(sprite, "scale", Vector2(3,3), 0.5) - - + tween.tween_property(sprite, "position", Vector2(0, 0), timer * 2) + tween.tween_property(sprite, "modulate", Color(0, 0, 0, 0), 0.5) + tween.parallel().tween_property(sprite, "scale", Vector2(3, 3), 0.5) + counter = counter + 1 - - thread_list.back() func _on_animation_finished() -> void: - print("finished!") animation_finished.emit() diff --git a/scenes/game_elements/props/eternal_loom/eternal_loom.tscn b/scenes/game_elements/props/eternal_loom/eternal_loom.tscn index cb02f37558..61865df272 100644 --- a/scenes/game_elements/props/eternal_loom/eternal_loom.tscn +++ b/scenes/game_elements/props/eternal_loom/eternal_loom.tscn @@ -205,7 +205,6 @@ unique_name_in_owner = true z_index = 1 position = Vector2(0, 135) script = ExtResource("6_rle0d") -debug_thread_count = 12 [node name="AnimationPath" type="Path2D" parent="LoomOfferingAnimation" unique_id=1718786189] unique_name_in_owner = true From 507448b9a3646fa0ed2897a518c87015c4c417fa Mon Sep 17 00:00:00 2001 From: MateoP Date: Tue, 8 Sep 2026 22:08:53 -0500 Subject: [PATCH 10/16] formatting --- .../game_elements/props/eternal_loom/components/eternal_loom.gd | 1 - 1 file changed, 1 deletion(-) diff --git a/scenes/game_elements/props/eternal_loom/components/eternal_loom.gd b/scenes/game_elements/props/eternal_loom/components/eternal_loom.gd index 0f9ae82b41..e65ebb9d60 100644 --- a/scenes/game_elements/props/eternal_loom/components/eternal_loom.gd +++ b/scenes/game_elements/props/eternal_loom/components/eternal_loom.gd @@ -21,7 +21,6 @@ var elders: Array[Elder] @onready var loom_offering_animation: LoomOfferingAnimation = %LoomOfferingAnimation - func _find_elder(quest: Quest) -> Elder: for elder in elders: if quest.resource_path.begins_with(elder.quest_directory): From e622078a1fbeab7769c9c827b574e2d5d8dd9427 Mon Sep 17 00:00:00 2001 From: MateoP Date: Wed, 9 Sep 2026 21:54:08 -0500 Subject: [PATCH 11/16] small improvements --- .../components/loom_offering_animation.gd | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd b/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd index a4c596039e..f8c807a767 100644 --- a/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd +++ b/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd @@ -10,13 +10,13 @@ const WORLD_IMAGINATION = preload("uid://6bf8rum68wq3") const WORLD_MEMORY = preload("uid://5wscjc8yqqts") const WORLD_SPIRIT = preload("uid://cepg1o3ihp055") -@export var _play_animation: bool = false: - set(value): - play_loom_animation_debug() - +## The time in seconds it takes for the animation to finish, determines the speed of threads @export var animation_time: float = 5.0 +## Number of threads in the animation for the in-editor preview @export var debug_thread_count: int = 6 +@export_tool_button("Play") var play_animation: Callable = play_loom_animation_debug + @onready var animation_path: Path2D = %AnimationPath @onready var loom_offering_sound: AudioStreamPlayer2D = $LoomOfferingSound @@ -48,16 +48,7 @@ func _loom_animation_play(thread_list: Array[InventoryItem]) -> void: var counter: int = 0 for thread in thread_list: var sprite := Sprite2D.new() - - match thread.type: - InventoryItem.ItemType.MEMORY: - sprite.texture = WORLD_MEMORY - InventoryItem.ItemType.IMAGINATION: - sprite.texture = WORLD_IMAGINATION - InventoryItem.ItemType.SPIRIT: - sprite.texture = WORLD_SPIRIT - _: - sprite.texture = WORLD_SPIRIT + sprite.texture = thread.get_world_texture() sprite.position = animation_points[counter * separator] add_child(sprite) From afc0e1b2092132a4d161693bb1392dcc73269193 Mon Sep 17 00:00:00 2001 From: MateoP Date: Wed, 9 Sep 2026 21:58:03 -0500 Subject: [PATCH 12/16] small improvements --- .../eternal_loom/components/loom_offering_animation.gd | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd b/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd index f8c807a767..bbb5eba01f 100644 --- a/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd +++ b/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd @@ -30,12 +30,16 @@ func play_loom_animation_debug() -> void: var arr: Array[InventoryItem] for i in range(debug_thread_count): var temp_item := InventoryItem.new() - temp_item.type = InventoryItem.ItemType.MEMORY + temp_item.type = InventoryItem.ItemType.values().pick_random() arr.append(temp_item) _loom_animation_play(arr) func _loom_animation_play(thread_list: Array[InventoryItem]) -> void: + if thread_list.is_empty(): + animation_finished.emit() + return + var animation_points := animation_path.curve.get_baked_points() loom_offering_sound.play() From d961f2495fe4be9e4a5554c14a2f1be0aa06a174 Mon Sep 17 00:00:00 2001 From: MateoP Date: Thu, 10 Sep 2026 17:47:36 -0500 Subject: [PATCH 13/16] randomness and curve length --- .../components/loom_offering_animation.gd | 15 +++++++++++++-- .../props/eternal_loom/eternal_loom.tscn | 5 +++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd b/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd index bbb5eba01f..dca346e838 100644 --- a/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd +++ b/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd @@ -30,7 +30,9 @@ func play_loom_animation_debug() -> void: var arr: Array[InventoryItem] for i in range(debug_thread_count): var temp_item := InventoryItem.new() - temp_item.type = InventoryItem.ItemType.values().pick_random() + var item_types := InventoryItem.ItemType.values() + item_types.remove_at(3) ## Remove the 'None' Item Type + temp_item.type = item_types.pick_random() arr.append(temp_item) _loom_animation_play(arr) @@ -40,7 +42,15 @@ func _loom_animation_play(thread_list: Array[InventoryItem]) -> void: animation_finished.emit() return - var animation_points := animation_path.curve.get_baked_points() + ## Calculating the animation points + var animation_points: Array[Vector2] + + var curve_length := animation_path.curve.get_baked_length() + var separation := curve_length / thread_list.size() + for i in thread_list.size(): + var offset := separation * i + var point := animation_path.curve.sample_baked(offset) + animation_points.append(point) loom_offering_sound.play() @@ -52,6 +62,7 @@ func _loom_animation_play(thread_list: Array[InventoryItem]) -> void: var counter: int = 0 for thread in thread_list: var sprite := Sprite2D.new() + sprite.texture = thread.get_world_texture() sprite.position = animation_points[counter * separator] diff --git a/scenes/game_elements/props/eternal_loom/eternal_loom.tscn b/scenes/game_elements/props/eternal_loom/eternal_loom.tscn index 61865df272..4cda4b8f41 100644 --- a/scenes/game_elements/props/eternal_loom/eternal_loom.tscn +++ b/scenes/game_elements/props/eternal_loom/eternal_loom.tscn @@ -149,9 +149,9 @@ size = Vector2(50, 50) [sub_resource type="Curve2D" id="Curve2D_f3ofd"] bake_interval = 512.0 _data = { -"points": PackedVector2Array(0, 0, 0, 0, -1, -79, 0, 0, 0, 0, -40, -69, 0, 0, 0, 0, -69, -41, 0, 0, 0, 0, -80, -1, 0, 0, 0, 0, -70, 38, 0, 0, 0, 0, -40, 67, 0, 0, 0, 0, -2, 76, 0, 0, 0, 0, 38, 67, 0, 0, 0, 0, 67, 38, 0, 0, 0, 0, 78, -1, 0, 0, 0, 0, 67, -40, 0, 0, 0, 0, 38, -69) +"points": PackedVector2Array(0, 0, 0, 0, -1, -79, 0, 0, 0, 0, -40, -69, 0, 0, 0, 0, -69, -41, 0, 0, 0, 0, -80, -1, 0, 0, 0, 0, -70, 38, 0, 0, 0, 0, -40, 67, 0, 0, 0, 0, -2, 76, 0, 0, 0, 0, 38, 67, 0, 0, 0, 0, 67, 38, 0, 0, 0, 0, 78, -1, 0, 0, 0, 0, 67, -40, 0, 0, 0, 0, 38, -69, 0, 0, 0, 0, -1, -79) } -point_count = 12 +point_count = 13 [node name="EternalLoom" type="Node2D" unique_id=630179356] script = ExtResource("1_0f752") @@ -205,6 +205,7 @@ unique_name_in_owner = true z_index = 1 position = Vector2(0, 135) script = ExtResource("6_rle0d") +debug_thread_count = 100 [node name="AnimationPath" type="Path2D" parent="LoomOfferingAnimation" unique_id=1718786189] unique_name_in_owner = true From b549616489b15e736d4be795b1f0513e792604ad Mon Sep 17 00:00:00 2001 From: MateoP Date: Sat, 12 Sep 2026 15:40:08 -0500 Subject: [PATCH 14/16] new animation PathFollow2D --- .../components/loom_offering_animation.gd | 64 ++++++++----------- .../props/eternal_loom/eternal_loom.tscn | 11 ++-- 2 files changed, 32 insertions(+), 43 deletions(-) diff --git a/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd b/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd index dca346e838..1d1c919cea 100644 --- a/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd +++ b/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd @@ -42,61 +42,51 @@ func _loom_animation_play(thread_list: Array[InventoryItem]) -> void: animation_finished.emit() return - ## Calculating the animation points - var animation_points: Array[Vector2] - - var curve_length := animation_path.curve.get_baked_length() - var separation := curve_length / thread_list.size() - for i in thread_list.size(): - var offset := separation * i - var point := animation_path.curve.sample_baked(offset) - animation_points.append(point) + var separation := 1.0 / thread_list.size() loom_offering_sound.play() - # Time between each animation_point - var timer: float = animation_time / (animation_points.size() * 2.8) - # Separation between threads - var separator: int = animation_points.size() / floor(thread_list.size()) - var counter: int = 0 for thread in thread_list: + var path_follow := PathFollow2D.new() + path_follow.rotates = false var sprite := Sprite2D.new() sprite.texture = thread.get_world_texture() + path_follow.add_child(sprite) - sprite.position = animation_points[counter * separator] - add_child(sprite) + animation_path.add_child(path_follow) + ## Starting point + path_follow.progress_ratio = counter * separation - var tween := sprite.create_tween() + var thign := 3.5 / (2.0 * thread_list.size()) - ## The first thread is the last to enter the loom - if counter == 0: - tween.finished.connect(_on_animation_finished) + var tween := path_follow.create_tween() - # Animation Start + ## Animation Start tween.tween_property(sprite, "scale", Vector2(0, 0), 0) - tween.tween_property(sprite, "scale", Vector2(1, 1), timer) - tween.parallel().tween_property( - sprite, - "position", - animation_points[(counter * separator + 1) % animation_points.size()], - timer - ) - - # Thread Cycle - for i in range(animation_points.size() - 1 + (thread_list.size() - counter) * separator): - var position_index: int = (counter * separator + i + 2) % animation_points.size() - tween.tween_property(sprite, "position", animation_points[position_index], timer) + tween.tween_property(sprite, "scale", Vector2(1, 1), 0.5) + ## Loop around + tween.parallel().tween_property(path_follow, "progress_ratio", 2.0, 3.5 - thign * counter) - # Final animation - tween.tween_property(sprite, "position", Vector2(0, 0), timer * 2) - tween.tween_property(sprite, "modulate", Color(0, 0, 0, 0), 0.5) + ## Animation end + ( + tween + . tween_property(sprite, "global_position", animation_path.global_position, 3) + . set_trans(Tween.TRANS_ELASTIC) + . set_ease(Tween.EASE_OUT) + ) + tween.parallel().tween_property(sprite, "modulate", Color(0, 0, 0, 0), 0.5) tween.parallel().tween_property(sprite, "scale", Vector2(3, 3), 0.5) - + tween.tween_callback(_thread_free.bind(sprite)) counter = counter + 1 +## Remove thread once animation finishes +func _thread_free(thread: Sprite2D) -> void: + thread.queue_free() + + func _on_animation_finished() -> void: animation_finished.emit() diff --git a/scenes/game_elements/props/eternal_loom/eternal_loom.tscn b/scenes/game_elements/props/eternal_loom/eternal_loom.tscn index 4cda4b8f41..02bfaf9b0e 100644 --- a/scenes/game_elements/props/eternal_loom/eternal_loom.tscn +++ b/scenes/game_elements/props/eternal_loom/eternal_loom.tscn @@ -147,11 +147,10 @@ size = Vector2(393, 260) size = Vector2(50, 50) [sub_resource type="Curve2D" id="Curve2D_f3ofd"] -bake_interval = 512.0 _data = { -"points": PackedVector2Array(0, 0, 0, 0, -1, -79, 0, 0, 0, 0, -40, -69, 0, 0, 0, 0, -69, -41, 0, 0, 0, 0, -80, -1, 0, 0, 0, 0, -70, 38, 0, 0, 0, 0, -40, 67, 0, 0, 0, 0, -2, 76, 0, 0, 0, 0, 38, 67, 0, 0, 0, 0, 67, 38, 0, 0, 0, 0, 78, -1, 0, 0, 0, 0, 67, -40, 0, 0, 0, 0, 38, -69, 0, 0, 0, 0, -1, -79) +"points": PackedVector2Array(0, 0, 0, 0, 0, -80, 0, -80, 0, 80, -80, 0, 0, 0, 0, 0, 0, 80, 0, 80, 0, -80, 80, 0, 0, 0, 0, 0, 0, -80) } -point_count = 13 +point_count = 5 [node name="EternalLoom" type="Node2D" unique_id=630179356] script = ExtResource("1_0f752") @@ -203,9 +202,9 @@ metadata/_custom_type_script = "uid://edcifob4jc4s" [node name="LoomOfferingAnimation" type="Node2D" parent="." unique_id=515569025] unique_name_in_owner = true z_index = 1 -position = Vector2(0, 135) +position = Vector2(0, 85) script = ExtResource("6_rle0d") -debug_thread_count = 100 +debug_thread_count = 20 [node name="AnimationPath" type="Path2D" parent="LoomOfferingAnimation" unique_id=1718786189] unique_name_in_owner = true @@ -217,7 +216,7 @@ bus = &"SFX" [node name="PointLight2D" type="PointLight2D" parent="." unique_id=853151346 groups=["night-lights"]] visibility_layer = 2 -position = Vector2(0, 39) +position = Vector2(-1, 39) scale = Vector2(2.9765627, 1.765625) enabled = false color = Color(1, 1, 0, 1) From ab60cc7ee1b6615469031416770aedc9117bd91b Mon Sep 17 00:00:00 2001 From: MateoP Date: Sat, 12 Sep 2026 15:54:53 -0500 Subject: [PATCH 15/16] small fix --- .../components/loom_offering_animation.gd | 20 ++++++++++++++----- .../props/eternal_loom/eternal_loom.tscn | 2 +- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd b/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd index 1d1c919cea..d49c244a82 100644 --- a/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd +++ b/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd @@ -44,6 +44,9 @@ func _loom_animation_play(thread_list: Array[InventoryItem]) -> void: var separation := 1.0 / thread_list.size() + # time it takes for all threads to loop + var loop_time := animation_time * 0.7 + loom_offering_sound.play() var counter: int = 0 @@ -56,25 +59,32 @@ func _loom_animation_play(thread_list: Array[InventoryItem]) -> void: path_follow.add_child(sprite) animation_path.add_child(path_follow) - ## Starting point + + ## Starting point for each thread path_follow.progress_ratio = counter * separation - var thign := 3.5 / (2.0 * thread_list.size()) + ## Time variation between threads + var time_variation := loop_time / (2.0 * thread_list.size()) var tween := path_follow.create_tween() + ## The first thread is the last to end + if counter == 0: + tween.finished.connect(_on_animation_finished) + ## Animation Start tween.tween_property(sprite, "scale", Vector2(0, 0), 0) tween.tween_property(sprite, "scale", Vector2(1, 1), 0.5) ## Loop around - tween.parallel().tween_property(path_follow, "progress_ratio", 2.0, 3.5 - thign * counter) + tween.parallel().tween_property( + path_follow, "progress_ratio", 2.0, loop_time - time_variation * counter + ) ## Animation end ( tween - . tween_property(sprite, "global_position", animation_path.global_position, 3) - . set_trans(Tween.TRANS_ELASTIC) + . tween_property(sprite, "global_position", animation_path.global_position, 0.25) . set_ease(Tween.EASE_OUT) ) tween.parallel().tween_property(sprite, "modulate", Color(0, 0, 0, 0), 0.5) diff --git a/scenes/game_elements/props/eternal_loom/eternal_loom.tscn b/scenes/game_elements/props/eternal_loom/eternal_loom.tscn index 02bfaf9b0e..d8bc910f86 100644 --- a/scenes/game_elements/props/eternal_loom/eternal_loom.tscn +++ b/scenes/game_elements/props/eternal_loom/eternal_loom.tscn @@ -204,7 +204,7 @@ unique_name_in_owner = true z_index = 1 position = Vector2(0, 85) script = ExtResource("6_rle0d") -debug_thread_count = 20 +debug_thread_count = 7 [node name="AnimationPath" type="Path2D" parent="LoomOfferingAnimation" unique_id=1718786189] unique_name_in_owner = true From fd9f674bf25b7418a22e6b016e25c9b80bf6890e Mon Sep 17 00:00:00 2001 From: MateoP Date: Mon, 14 Sep 2026 15:07:01 -0500 Subject: [PATCH 16/16] Suggestions and small improvements --- .../components/loom_offering_animation.gd | 32 +++++++++---------- .../props/eternal_loom/eternal_loom.tscn | 5 ++- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd b/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd index d49c244a82..ce8ab183d2 100644 --- a/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd +++ b/scenes/game_elements/props/eternal_loom/components/loom_offering_animation.gd @@ -27,14 +27,14 @@ func play_loom_animation() -> void: ## Only used for the in-editor preview func play_loom_animation_debug() -> void: - var arr: Array[InventoryItem] + var debug_items: Array[InventoryItem] + # TODO: InventoryItem needs a utility function to obtain all types except NONE. + var item_types := InventoryItem.COLORS_PER_TYPE.keys() for i in range(debug_thread_count): - var temp_item := InventoryItem.new() - var item_types := InventoryItem.ItemType.values() - item_types.remove_at(3) ## Remove the 'None' Item Type - temp_item.type = item_types.pick_random() - arr.append(temp_item) - _loom_animation_play(arr) + var item := InventoryItem.new() + item.type = item_types.pick_random() + debug_items.append(item) + _loom_animation_play(debug_items) func _loom_animation_play(thread_list: Array[InventoryItem]) -> void: @@ -44,7 +44,7 @@ func _loom_animation_play(thread_list: Array[InventoryItem]) -> void: var separation := 1.0 / thread_list.size() - # time it takes for all threads to loop + # Time it takes for all threads to loop var loop_time := animation_time * 0.7 loom_offering_sound.play() @@ -60,28 +60,28 @@ func _loom_animation_play(thread_list: Array[InventoryItem]) -> void: animation_path.add_child(path_follow) - ## Starting point for each thread + # Starting point for each thread path_follow.progress_ratio = counter * separation - ## Time variation between threads + # Time variation between threads var time_variation := loop_time / (2.0 * thread_list.size()) var tween := path_follow.create_tween() - ## The first thread is the last to end + # The first thread is the last to end if counter == 0: tween.finished.connect(_on_animation_finished) - ## Animation Start + # Animation Start tween.tween_property(sprite, "scale", Vector2(0, 0), 0) tween.tween_property(sprite, "scale", Vector2(1, 1), 0.5) - ## Loop around + # Loop around tween.parallel().tween_property( path_follow, "progress_ratio", 2.0, loop_time - time_variation * counter ) - ## Animation end + # Animation end ( tween . tween_property(sprite, "global_position", animation_path.global_position, 0.25) @@ -90,10 +90,10 @@ func _loom_animation_play(thread_list: Array[InventoryItem]) -> void: tween.parallel().tween_property(sprite, "modulate", Color(0, 0, 0, 0), 0.5) tween.parallel().tween_property(sprite, "scale", Vector2(3, 3), 0.5) tween.tween_callback(_thread_free.bind(sprite)) - counter = counter + 1 + counter += 1 -## Remove thread once animation finishes +# Remove thread once animation finishes func _thread_free(thread: Sprite2D) -> void: thread.queue_free() diff --git a/scenes/game_elements/props/eternal_loom/eternal_loom.tscn b/scenes/game_elements/props/eternal_loom/eternal_loom.tscn index d8bc910f86..41c5107c37 100644 --- a/scenes/game_elements/props/eternal_loom/eternal_loom.tscn +++ b/scenes/game_elements/props/eternal_loom/eternal_loom.tscn @@ -202,9 +202,8 @@ metadata/_custom_type_script = "uid://edcifob4jc4s" [node name="LoomOfferingAnimation" type="Node2D" parent="." unique_id=515569025] unique_name_in_owner = true z_index = 1 -position = Vector2(0, 85) +position = Vector2(0, 135) script = ExtResource("6_rle0d") -debug_thread_count = 7 [node name="AnimationPath" type="Path2D" parent="LoomOfferingAnimation" unique_id=1718786189] unique_name_in_owner = true @@ -216,7 +215,7 @@ bus = &"SFX" [node name="PointLight2D" type="PointLight2D" parent="." unique_id=853151346 groups=["night-lights"]] visibility_layer = 2 -position = Vector2(-1, 39) +position = Vector2(0, 39) scale = Vector2(2.9765627, 1.765625) enabled = false color = Color(1, 1, 0, 1)