diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..fccac25
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018 Robert Morse
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/addons/guide/debugger/guide_debugger.gd.uid b/addons/guide/debugger/guide_debugger.gd.uid
new file mode 100644
index 0000000..e9b088a
--- /dev/null
+++ b/addons/guide/debugger/guide_debugger.gd.uid
@@ -0,0 +1 @@
+uid://cvb8o2louvxsw
diff --git a/addons/guide/debugger/guide_debugger.tscn b/addons/guide/debugger/guide_debugger.tscn
index 0e7caf4..5767419 100644
--- a/addons/guide/debugger/guide_debugger.tscn
+++ b/addons/guide/debugger/guide_debugger.tscn
@@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://dkr80d2pi0d41"]
-[ext_resource type="Script" path="res://addons/guide/debugger/guide_debugger.gd" id="1_ckdvj"]
+[ext_resource type="Script" uid="uid://cvb8o2louvxsw" path="res://addons/guide/debugger/guide_debugger.gd" id="1_ckdvj"]
[node name="GuideDebugger" type="MarginContainer"]
anchors_preset = 15
diff --git a/addons/guide/editor/action_mapping_editor/action_mapping_editor.gd.uid b/addons/guide/editor/action_mapping_editor/action_mapping_editor.gd.uid
new file mode 100644
index 0000000..e216155
--- /dev/null
+++ b/addons/guide/editor/action_mapping_editor/action_mapping_editor.gd.uid
@@ -0,0 +1 @@
+uid://dib57ucg64xa0
diff --git a/addons/guide/editor/action_mapping_editor/action_mapping_editor.tscn b/addons/guide/editor/action_mapping_editor/action_mapping_editor.tscn
index 3730f92..a1f5faa 100644
--- a/addons/guide/editor/action_mapping_editor/action_mapping_editor.tscn
+++ b/addons/guide/editor/action_mapping_editor/action_mapping_editor.tscn
@@ -1,6 +1,6 @@
[gd_scene load_steps=5 format=3 uid="uid://361aipcef24h"]
-[ext_resource type="Script" path="res://addons/guide/editor/action_mapping_editor/action_mapping_editor.gd" id="1_2k0pi"]
+[ext_resource type="Script" uid="uid://dib57ucg64xa0" path="res://addons/guide/editor/action_mapping_editor/action_mapping_editor.gd" id="1_2k0pi"]
[ext_resource type="PackedScene" uid="uid://du4x7ng6ntuk4" path="res://addons/guide/editor/action_slot/action_slot.tscn" id="1_hguf2"]
[ext_resource type="PackedScene" uid="uid://c323mdijdhktg" path="res://addons/guide/editor/input_mapping_editor/input_mapping_editor.tscn" id="2_a8nbp"]
[ext_resource type="PackedScene" uid="uid://cly0ff32fvpb2" path="res://addons/guide/editor/array_edit/array_edit.tscn" id="4_ehr5j"]
diff --git a/addons/guide/editor/action_slot/action_slot.gd.uid b/addons/guide/editor/action_slot/action_slot.gd.uid
new file mode 100644
index 0000000..fb2b464
--- /dev/null
+++ b/addons/guide/editor/action_slot/action_slot.gd.uid
@@ -0,0 +1 @@
+uid://dvwfhry6u83db
diff --git a/addons/guide/editor/action_slot/action_slot.tscn b/addons/guide/editor/action_slot/action_slot.tscn
index 956be79..91a540d 100644
--- a/addons/guide/editor/action_slot/action_slot.tscn
+++ b/addons/guide/editor/action_slot/action_slot.tscn
@@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://du4x7ng6ntuk4"]
-[ext_resource type="Script" path="res://addons/guide/editor/action_slot/action_slot.gd" id="1_w5nxd"]
+[ext_resource type="Script" uid="uid://dvwfhry6u83db" path="res://addons/guide/editor/action_slot/action_slot.gd" id="1_w5nxd"]
[node name="ActionSlot" type="LineEdit"]
anchors_preset = 15
diff --git a/addons/guide/editor/array_edit/array_edit.gd.uid b/addons/guide/editor/array_edit/array_edit.gd.uid
new file mode 100644
index 0000000..05264dd
--- /dev/null
+++ b/addons/guide/editor/array_edit/array_edit.gd.uid
@@ -0,0 +1 @@
+uid://dklq5gtpunho2
diff --git a/addons/guide/editor/array_edit/array_edit.tscn b/addons/guide/editor/array_edit/array_edit.tscn
index c6c7408..dd861cd 100644
--- a/addons/guide/editor/array_edit/array_edit.tscn
+++ b/addons/guide/editor/array_edit/array_edit.tscn
@@ -1,9 +1,9 @@
[gd_scene load_steps=5 format=3 uid="uid://cly0ff32fvpb2"]
-[ext_resource type="Script" path="res://addons/guide/editor/array_edit/array_edit.gd" id="1_y3qyt"]
+[ext_resource type="Script" uid="uid://dklq5gtpunho2" path="res://addons/guide/editor/array_edit/array_edit.gd" id="1_y3qyt"]
[ext_resource type="PackedScene" uid="uid://cjabwsa4gmlpp" path="res://addons/guide/editor/array_edit/array_edit_item.tscn" id="2_n3ncl"]
-[sub_resource type="Image" id="Image_efj5n"]
+[sub_resource type="Image" id="Image_2nfri"]
data = {
"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 93, 93, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0),
"format": "RGBA8",
@@ -13,7 +13,7 @@ data = {
}
[sub_resource type="ImageTexture" id="ImageTexture_uapko"]
-image = SubResource("Image_efj5n")
+image = SubResource("Image_2nfri")
[node name="Array" type="MarginContainer"]
anchors_preset = 15
diff --git a/addons/guide/editor/array_edit/array_edit_item.gd.uid b/addons/guide/editor/array_edit/array_edit_item.gd.uid
new file mode 100644
index 0000000..f01b535
--- /dev/null
+++ b/addons/guide/editor/array_edit/array_edit_item.gd.uid
@@ -0,0 +1 @@
+uid://86p0b71yit85
diff --git a/addons/guide/editor/array_edit/array_edit_item.tscn b/addons/guide/editor/array_edit/array_edit_item.tscn
index be3b43b..65763a4 100644
--- a/addons/guide/editor/array_edit/array_edit_item.tscn
+++ b/addons/guide/editor/array_edit/array_edit_item.tscn
@@ -1,9 +1,9 @@
[gd_scene load_steps=5 format=3 uid="uid://cjabwsa4gmlpp"]
-[ext_resource type="Script" path="res://addons/guide/editor/array_edit/array_edit_item.gd" id="1_ujx05"]
-[ext_resource type="Script" path="res://addons/guide/editor/array_edit/dragger.gd" id="2_53e2r"]
+[ext_resource type="Script" uid="uid://86p0b71yit85" path="res://addons/guide/editor/array_edit/array_edit_item.gd" id="1_ujx05"]
+[ext_resource type="Script" uid="uid://bobwrqyqm5lax" path="res://addons/guide/editor/array_edit/dragger.gd" id="2_53e2r"]
-[sub_resource type="Image" id="Image_efj5n"]
+[sub_resource type="Image" id="Image_p1tee"]
data = {
"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 93, 93, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0),
"format": "RGBA8",
@@ -13,7 +13,7 @@ data = {
}
[sub_resource type="ImageTexture" id="ImageTexture_uapko"]
-image = SubResource("Image_efj5n")
+image = SubResource("Image_p1tee")
[node name="ArrayEditItem" type="MarginContainer"]
anchors_preset = 10
diff --git a/addons/guide/editor/array_edit/dragger.gd.uid b/addons/guide/editor/array_edit/dragger.gd.uid
new file mode 100644
index 0000000..58e140a
--- /dev/null
+++ b/addons/guide/editor/array_edit/dragger.gd.uid
@@ -0,0 +1 @@
+uid://bobwrqyqm5lax
diff --git a/addons/guide/editor/binding_dialog/binding_dialog.gd.uid b/addons/guide/editor/binding_dialog/binding_dialog.gd.uid
new file mode 100644
index 0000000..02e0ed3
--- /dev/null
+++ b/addons/guide/editor/binding_dialog/binding_dialog.gd.uid
@@ -0,0 +1 @@
+uid://clwmpekkvd0gq
diff --git a/addons/guide/editor/binding_dialog/binding_dialog.tscn b/addons/guide/editor/binding_dialog/binding_dialog.tscn
index 056fdac..7a478ef 100644
--- a/addons/guide/editor/binding_dialog/binding_dialog.tscn
+++ b/addons/guide/editor/binding_dialog/binding_dialog.tscn
@@ -1,8 +1,8 @@
[gd_scene load_steps=5 format=3 uid="uid://dic27bm4pfw3q"]
-[ext_resource type="Script" path="res://addons/guide/editor/binding_dialog/binding_dialog.gd" id="1_tknjd"]
+[ext_resource type="Script" uid="uid://clwmpekkvd0gq" path="res://addons/guide/editor/binding_dialog/binding_dialog.gd" id="1_tknjd"]
[ext_resource type="PackedScene" uid="uid://dsv7s6tfmnsrs" path="res://addons/guide/editor/input_display/input_display.tscn" id="2_83ieu"]
-[ext_resource type="Script" path="res://addons/guide/remapping/guide_input_detector.gd" id="3_c6q6r"]
+[ext_resource type="Script" uid="uid://c5823o2wpiamt" path="res://addons/guide/remapping/guide_input_detector.gd" id="3_c6q6r"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_3e874"]
content_margin_left = 4.0
diff --git a/addons/guide/editor/class_scanner.gd.uid b/addons/guide/editor/class_scanner.gd.uid
new file mode 100644
index 0000000..d4a4d2f
--- /dev/null
+++ b/addons/guide/editor/class_scanner.gd.uid
@@ -0,0 +1 @@
+uid://x1bami7hx7qc
diff --git a/addons/guide/editor/input_display/input_display.gd.uid b/addons/guide/editor/input_display/input_display.gd.uid
new file mode 100644
index 0000000..7d03ed3
--- /dev/null
+++ b/addons/guide/editor/input_display/input_display.gd.uid
@@ -0,0 +1 @@
+uid://opxaniicinft
diff --git a/addons/guide/editor/input_display/input_display.tscn b/addons/guide/editor/input_display/input_display.tscn
index 4cd79a3..d15e0f0 100644
--- a/addons/guide/editor/input_display/input_display.tscn
+++ b/addons/guide/editor/input_display/input_display.tscn
@@ -1,6 +1,6 @@
[gd_scene load_steps=3 format=3 uid="uid://dsv7s6tfmnsrs"]
-[ext_resource type="Script" path="res://addons/guide/editor/input_display/input_display.gd" id="1_ne6sd"]
+[ext_resource type="Script" uid="uid://opxaniicinft" path="res://addons/guide/editor/input_display/input_display.gd" id="1_ne6sd"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_0bp65"]
diff --git a/addons/guide/editor/input_mapping_editor/input_mapping_editor.gd.uid b/addons/guide/editor/input_mapping_editor/input_mapping_editor.gd.uid
new file mode 100644
index 0000000..615391d
--- /dev/null
+++ b/addons/guide/editor/input_mapping_editor/input_mapping_editor.gd.uid
@@ -0,0 +1 @@
+uid://bw0ejqqmxnh46
diff --git a/addons/guide/editor/input_mapping_editor/input_mapping_editor.tscn b/addons/guide/editor/input_mapping_editor/input_mapping_editor.tscn
index a70f142..f787576 100644
--- a/addons/guide/editor/input_mapping_editor/input_mapping_editor.tscn
+++ b/addons/guide/editor/input_mapping_editor/input_mapping_editor.tscn
@@ -1,13 +1,13 @@
[gd_scene load_steps=9 format=3 uid="uid://c323mdijdhktg"]
[ext_resource type="PackedScene" uid="uid://dsv7s6tfmnsrs" path="res://addons/guide/editor/input_display/input_display.tscn" id="1_pg8n3"]
-[ext_resource type="Script" path="res://addons/guide/editor/input_mapping_editor/input_mapping_editor.gd" id="1_xsluc"]
+[ext_resource type="Script" uid="uid://bw0ejqqmxnh46" path="res://addons/guide/editor/input_mapping_editor/input_mapping_editor.gd" id="1_xsluc"]
[ext_resource type="PackedScene" uid="uid://ck5a30syo6bpo" path="res://addons/guide/editor/modifier_slot/modifier_slot.tscn" id="2_uhbrq"]
[ext_resource type="PackedScene" uid="uid://tk30wnstb0ku" path="res://addons/guide/editor/trigger_slot/trigger_slot.tscn" id="3_e0jys"]
[ext_resource type="PackedScene" uid="uid://dic27bm4pfw3q" path="res://addons/guide/editor/binding_dialog/binding_dialog.tscn" id="4_oepf3"]
[ext_resource type="PackedScene" uid="uid://cly0ff32fvpb2" path="res://addons/guide/editor/array_edit/array_edit.tscn" id="6_jekhk"]
-[sub_resource type="Image" id="Image_m1w1j"]
+[sub_resource type="Image" id="Image_uu37q"]
data = {
"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 93, 93, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0),
"format": "RGBA8",
@@ -17,7 +17,7 @@ data = {
}
[sub_resource type="ImageTexture" id="ImageTexture_y0eyy"]
-image = SubResource("Image_m1w1j")
+image = SubResource("Image_uu37q")
[node name="InputMappingEditor" type="MarginContainer"]
anchors_preset = 15
diff --git a/addons/guide/editor/mapping_context_editor/mapping_context_editor.gd.uid b/addons/guide/editor/mapping_context_editor/mapping_context_editor.gd.uid
new file mode 100644
index 0000000..8c80101
--- /dev/null
+++ b/addons/guide/editor/mapping_context_editor/mapping_context_editor.gd.uid
@@ -0,0 +1 @@
+uid://28b86h1tj4ne
diff --git a/addons/guide/editor/mapping_context_editor/mapping_context_editor.tscn b/addons/guide/editor/mapping_context_editor/mapping_context_editor.tscn
index f28a17f..2fbf257 100644
--- a/addons/guide/editor/mapping_context_editor/mapping_context_editor.tscn
+++ b/addons/guide/editor/mapping_context_editor/mapping_context_editor.tscn
@@ -1,6 +1,6 @@
[gd_scene load_steps=4 format=3 uid="uid://dm3hott3tfvwe"]
-[ext_resource type="Script" path="res://addons/guide/editor/mapping_context_editor/mapping_context_editor.gd" id="1_vytdu"]
+[ext_resource type="Script" uid="uid://28b86h1tj4ne" path="res://addons/guide/editor/mapping_context_editor/mapping_context_editor.gd" id="1_vytdu"]
[ext_resource type="PackedScene" uid="uid://361aipcef24h" path="res://addons/guide/editor/action_mapping_editor/action_mapping_editor.tscn" id="2_qb3p8"]
[ext_resource type="PackedScene" uid="uid://cly0ff32fvpb2" path="res://addons/guide/editor/array_edit/array_edit.tscn" id="3_x7h5x"]
diff --git a/addons/guide/editor/modifier_slot/modifier_slot.gd.uid b/addons/guide/editor/modifier_slot/modifier_slot.gd.uid
new file mode 100644
index 0000000..eef3c4a
--- /dev/null
+++ b/addons/guide/editor/modifier_slot/modifier_slot.gd.uid
@@ -0,0 +1 @@
+uid://s2eppvhqc6wn
diff --git a/addons/guide/editor/modifier_slot/modifier_slot.tscn b/addons/guide/editor/modifier_slot/modifier_slot.tscn
index 6b2f91e..c6b5636 100644
--- a/addons/guide/editor/modifier_slot/modifier_slot.tscn
+++ b/addons/guide/editor/modifier_slot/modifier_slot.tscn
@@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://ck5a30syo6bpo"]
-[ext_resource type="Script" path="res://addons/guide/editor/modifier_slot/modifier_slot.gd" id="1_273m5"]
+[ext_resource type="Script" uid="uid://s2eppvhqc6wn" path="res://addons/guide/editor/modifier_slot/modifier_slot.gd" id="1_273m5"]
[node name="LineEdit" type="LineEdit"]
offset_right = 1920.0
diff --git a/addons/guide/editor/resource_slot/resource_slot.gd.uid b/addons/guide/editor/resource_slot/resource_slot.gd.uid
new file mode 100644
index 0000000..545ac0d
--- /dev/null
+++ b/addons/guide/editor/resource_slot/resource_slot.gd.uid
@@ -0,0 +1 @@
+uid://b8d5q5qpelshd
diff --git a/addons/guide/editor/trigger_slot/trigger_slot.gd.uid b/addons/guide/editor/trigger_slot/trigger_slot.gd.uid
new file mode 100644
index 0000000..81f42e1
--- /dev/null
+++ b/addons/guide/editor/trigger_slot/trigger_slot.gd.uid
@@ -0,0 +1 @@
+uid://doajsqn833r5e
diff --git a/addons/guide/editor/trigger_slot/trigger_slot.tscn b/addons/guide/editor/trigger_slot/trigger_slot.tscn
index 3d5e6d8..35d77e0 100644
--- a/addons/guide/editor/trigger_slot/trigger_slot.tscn
+++ b/addons/guide/editor/trigger_slot/trigger_slot.tscn
@@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://tk30wnstb0ku"]
-[ext_resource type="Script" path="res://addons/guide/editor/trigger_slot/trigger_slot.gd" id="1_wxafc"]
+[ext_resource type="Script" uid="uid://doajsqn833r5e" path="res://addons/guide/editor/trigger_slot/trigger_slot.gd" id="1_wxafc"]
[node name="LineEdit" type="LineEdit"]
unique_name_in_owner = true
diff --git a/addons/guide/editor/utils.gd.uid b/addons/guide/editor/utils.gd.uid
new file mode 100644
index 0000000..b1542cf
--- /dev/null
+++ b/addons/guide/editor/utils.gd.uid
@@ -0,0 +1 @@
+uid://d02ft0qt2ilsr
diff --git a/addons/guide/guide.gd.uid b/addons/guide/guide.gd.uid
new file mode 100644
index 0000000..24fc575
--- /dev/null
+++ b/addons/guide/guide.gd.uid
@@ -0,0 +1 @@
+uid://vi2w3bhxo3u6
diff --git a/addons/guide/guide_action.gd.uid b/addons/guide/guide_action.gd.uid
new file mode 100644
index 0000000..e47fdb6
--- /dev/null
+++ b/addons/guide/guide_action.gd.uid
@@ -0,0 +1 @@
+uid://5yg21xllntrk
diff --git a/addons/guide/guide_action_mapping.gd.uid b/addons/guide/guide_action_mapping.gd.uid
new file mode 100644
index 0000000..6051422
--- /dev/null
+++ b/addons/guide/guide_action_mapping.gd.uid
@@ -0,0 +1 @@
+uid://5huk51k6eqa8
diff --git a/addons/guide/guide_input_mapping.gd.uid b/addons/guide/guide_input_mapping.gd.uid
new file mode 100644
index 0000000..ac5bd67
--- /dev/null
+++ b/addons/guide/guide_input_mapping.gd.uid
@@ -0,0 +1 @@
+uid://c5pstcepgwkmy
diff --git a/addons/guide/guide_input_tracker.gd.uid b/addons/guide/guide_input_tracker.gd.uid
new file mode 100644
index 0000000..ee72812
--- /dev/null
+++ b/addons/guide/guide_input_tracker.gd.uid
@@ -0,0 +1 @@
+uid://cf4x5dukw63wg
diff --git a/addons/guide/guide_mapping_context.gd.uid b/addons/guide/guide_mapping_context.gd.uid
new file mode 100644
index 0000000..3e1a8f1
--- /dev/null
+++ b/addons/guide/guide_mapping_context.gd.uid
@@ -0,0 +1 @@
+uid://ddr05cbbemxru
diff --git a/addons/guide/guide_reset.gd.uid b/addons/guide/guide_reset.gd.uid
new file mode 100644
index 0000000..d609534
--- /dev/null
+++ b/addons/guide/guide_reset.gd.uid
@@ -0,0 +1 @@
+uid://cmsafc4hu0qay
diff --git a/addons/guide/guide_set.gd.uid b/addons/guide/guide_set.gd.uid
new file mode 100644
index 0000000..7e49fd6
--- /dev/null
+++ b/addons/guide/guide_set.gd.uid
@@ -0,0 +1 @@
+uid://gyx7afc0uhnc
diff --git a/addons/guide/inputs/guide_input.gd.uid b/addons/guide/inputs/guide_input.gd.uid
new file mode 100644
index 0000000..aa82289
--- /dev/null
+++ b/addons/guide/inputs/guide_input.gd.uid
@@ -0,0 +1 @@
+uid://cc26qctfgfohf
diff --git a/addons/guide/inputs/guide_input_action.gd.uid b/addons/guide/inputs/guide_input_action.gd.uid
new file mode 100644
index 0000000..3b1843b
--- /dev/null
+++ b/addons/guide/inputs/guide_input_action.gd.uid
@@ -0,0 +1 @@
+uid://d0pj4nsxevy2q
diff --git a/addons/guide/inputs/guide_input_any.gd.uid b/addons/guide/inputs/guide_input_any.gd.uid
new file mode 100644
index 0000000..2d7f4e1
--- /dev/null
+++ b/addons/guide/inputs/guide_input_any.gd.uid
@@ -0,0 +1 @@
+uid://bpnm06nodv3y8
diff --git a/addons/guide/inputs/guide_input_joy_axis_1d.gd.uid b/addons/guide/inputs/guide_input_joy_axis_1d.gd.uid
new file mode 100644
index 0000000..2035548
--- /dev/null
+++ b/addons/guide/inputs/guide_input_joy_axis_1d.gd.uid
@@ -0,0 +1 @@
+uid://ca5ylmpi6a6fm
diff --git a/addons/guide/inputs/guide_input_joy_axis_2d.gd.uid b/addons/guide/inputs/guide_input_joy_axis_2d.gd.uid
new file mode 100644
index 0000000..c326c4d
--- /dev/null
+++ b/addons/guide/inputs/guide_input_joy_axis_2d.gd.uid
@@ -0,0 +1 @@
+uid://c0scrj0tgjhba
diff --git a/addons/guide/inputs/guide_input_joy_base.gd.uid b/addons/guide/inputs/guide_input_joy_base.gd.uid
new file mode 100644
index 0000000..ad7e1b7
--- /dev/null
+++ b/addons/guide/inputs/guide_input_joy_base.gd.uid
@@ -0,0 +1 @@
+uid://cmkk3acwkqnam
diff --git a/addons/guide/inputs/guide_input_joy_button.gd.uid b/addons/guide/inputs/guide_input_joy_button.gd.uid
new file mode 100644
index 0000000..37f3ed2
--- /dev/null
+++ b/addons/guide/inputs/guide_input_joy_button.gd.uid
@@ -0,0 +1 @@
+uid://cqpxl8nxcex4m
diff --git a/addons/guide/inputs/guide_input_key.gd.uid b/addons/guide/inputs/guide_input_key.gd.uid
new file mode 100644
index 0000000..14a3398
--- /dev/null
+++ b/addons/guide/inputs/guide_input_key.gd.uid
@@ -0,0 +1 @@
+uid://coygbn3kos0l6
diff --git a/addons/guide/inputs/guide_input_mouse_axis_1d.gd.uid b/addons/guide/inputs/guide_input_mouse_axis_1d.gd.uid
new file mode 100644
index 0000000..01ad281
--- /dev/null
+++ b/addons/guide/inputs/guide_input_mouse_axis_1d.gd.uid
@@ -0,0 +1 @@
+uid://bplyuyag4727p
diff --git a/addons/guide/inputs/guide_input_mouse_axis_2d.gd.uid b/addons/guide/inputs/guide_input_mouse_axis_2d.gd.uid
new file mode 100644
index 0000000..044a489
--- /dev/null
+++ b/addons/guide/inputs/guide_input_mouse_axis_2d.gd.uid
@@ -0,0 +1 @@
+uid://7a503o6hblhk
diff --git a/addons/guide/inputs/guide_input_mouse_button.gd.uid b/addons/guide/inputs/guide_input_mouse_button.gd.uid
new file mode 100644
index 0000000..f80f0fa
--- /dev/null
+++ b/addons/guide/inputs/guide_input_mouse_button.gd.uid
@@ -0,0 +1 @@
+uid://bjsqx0ldaanm0
diff --git a/addons/guide/inputs/guide_input_mouse_position.gd.uid b/addons/guide/inputs/guide_input_mouse_position.gd.uid
new file mode 100644
index 0000000..f4a437a
--- /dev/null
+++ b/addons/guide/inputs/guide_input_mouse_position.gd.uid
@@ -0,0 +1 @@
+uid://d2qonq7dcfqc1
diff --git a/addons/guide/inputs/guide_input_touch_angle.gd.uid b/addons/guide/inputs/guide_input_touch_angle.gd.uid
new file mode 100644
index 0000000..e6e78fa
--- /dev/null
+++ b/addons/guide/inputs/guide_input_touch_angle.gd.uid
@@ -0,0 +1 @@
+uid://d15fohvathk0t
diff --git a/addons/guide/inputs/guide_input_touch_axis_1d.gd.uid b/addons/guide/inputs/guide_input_touch_axis_1d.gd.uid
new file mode 100644
index 0000000..f62efb6
--- /dev/null
+++ b/addons/guide/inputs/guide_input_touch_axis_1d.gd.uid
@@ -0,0 +1 @@
+uid://ducu74n37r83t
diff --git a/addons/guide/inputs/guide_input_touch_axis_2d.gd.uid b/addons/guide/inputs/guide_input_touch_axis_2d.gd.uid
new file mode 100644
index 0000000..648aee5
--- /dev/null
+++ b/addons/guide/inputs/guide_input_touch_axis_2d.gd.uid
@@ -0,0 +1 @@
+uid://eai5rm24dsmq
diff --git a/addons/guide/inputs/guide_input_touch_axis_base.gd.uid b/addons/guide/inputs/guide_input_touch_axis_base.gd.uid
new file mode 100644
index 0000000..02e26f1
--- /dev/null
+++ b/addons/guide/inputs/guide_input_touch_axis_base.gd.uid
@@ -0,0 +1 @@
+uid://cvdj3th7gnnae
diff --git a/addons/guide/inputs/guide_input_touch_base.gd.uid b/addons/guide/inputs/guide_input_touch_base.gd.uid
new file mode 100644
index 0000000..46d07a3
--- /dev/null
+++ b/addons/guide/inputs/guide_input_touch_base.gd.uid
@@ -0,0 +1 @@
+uid://cub7x2ywiba1s
diff --git a/addons/guide/inputs/guide_input_touch_distance.gd.uid b/addons/guide/inputs/guide_input_touch_distance.gd.uid
new file mode 100644
index 0000000..591e93a
--- /dev/null
+++ b/addons/guide/inputs/guide_input_touch_distance.gd.uid
@@ -0,0 +1 @@
+uid://dcoinm0y1mrow
diff --git a/addons/guide/inputs/guide_input_touch_position.gd.uid b/addons/guide/inputs/guide_input_touch_position.gd.uid
new file mode 100644
index 0000000..563d7b5
--- /dev/null
+++ b/addons/guide/inputs/guide_input_touch_position.gd.uid
@@ -0,0 +1 @@
+uid://d1p3u6rttnlfp
diff --git a/addons/guide/inputs/guide_touch_state.gd.uid b/addons/guide/inputs/guide_touch_state.gd.uid
new file mode 100644
index 0000000..e92311c
--- /dev/null
+++ b/addons/guide/inputs/guide_touch_state.gd.uid
@@ -0,0 +1 @@
+uid://c7sumc65pe5ba
diff --git a/addons/guide/modifiers/guide_modifier.gd.uid b/addons/guide/modifiers/guide_modifier.gd.uid
new file mode 100644
index 0000000..767390b
--- /dev/null
+++ b/addons/guide/modifiers/guide_modifier.gd.uid
@@ -0,0 +1 @@
+uid://dokohnxlptadc
diff --git a/addons/guide/modifiers/guide_modifier_3d_coordinates.gd.uid b/addons/guide/modifiers/guide_modifier_3d_coordinates.gd.uid
new file mode 100644
index 0000000..a0499da
--- /dev/null
+++ b/addons/guide/modifiers/guide_modifier_3d_coordinates.gd.uid
@@ -0,0 +1 @@
+uid://bytclrko2xc4j
diff --git a/addons/guide/modifiers/guide_modifier_8_way_direction.gd.uid b/addons/guide/modifiers/guide_modifier_8_way_direction.gd.uid
new file mode 100644
index 0000000..8c564e0
--- /dev/null
+++ b/addons/guide/modifiers/guide_modifier_8_way_direction.gd.uid
@@ -0,0 +1 @@
+uid://c23dvin8kx35m
diff --git a/addons/guide/modifiers/guide_modifier_canvas_coordinates.gd.uid b/addons/guide/modifiers/guide_modifier_canvas_coordinates.gd.uid
new file mode 100644
index 0000000..97fdc28
--- /dev/null
+++ b/addons/guide/modifiers/guide_modifier_canvas_coordinates.gd.uid
@@ -0,0 +1 @@
+uid://c7276omec30hi
diff --git a/addons/guide/modifiers/guide_modifier_curve.gd.uid b/addons/guide/modifiers/guide_modifier_curve.gd.uid
new file mode 100644
index 0000000..15914d6
--- /dev/null
+++ b/addons/guide/modifiers/guide_modifier_curve.gd.uid
@@ -0,0 +1 @@
+uid://bj2jogowcg505
diff --git a/addons/guide/modifiers/guide_modifier_deadzone.gd.uid b/addons/guide/modifiers/guide_modifier_deadzone.gd.uid
new file mode 100644
index 0000000..e1a98ab
--- /dev/null
+++ b/addons/guide/modifiers/guide_modifier_deadzone.gd.uid
@@ -0,0 +1 @@
+uid://dxbj570e2ki2p
diff --git a/addons/guide/modifiers/guide_modifier_input_swizzle.gd.uid b/addons/guide/modifiers/guide_modifier_input_swizzle.gd.uid
new file mode 100644
index 0000000..fab4a41
--- /dev/null
+++ b/addons/guide/modifiers/guide_modifier_input_swizzle.gd.uid
@@ -0,0 +1 @@
+uid://bpk8r5v7hvw32
diff --git a/addons/guide/modifiers/guide_modifier_map_range.gd.uid b/addons/guide/modifiers/guide_modifier_map_range.gd.uid
new file mode 100644
index 0000000..30950ef
--- /dev/null
+++ b/addons/guide/modifiers/guide_modifier_map_range.gd.uid
@@ -0,0 +1 @@
+uid://clqbj0xevb64q
diff --git a/addons/guide/modifiers/guide_modifier_negate.gd.uid b/addons/guide/modifiers/guide_modifier_negate.gd.uid
new file mode 100644
index 0000000..e03b9e3
--- /dev/null
+++ b/addons/guide/modifiers/guide_modifier_negate.gd.uid
@@ -0,0 +1 @@
+uid://b58e004vuk1hd
diff --git a/addons/guide/modifiers/guide_modifier_normalize.gd.uid b/addons/guide/modifiers/guide_modifier_normalize.gd.uid
new file mode 100644
index 0000000..62d6f99
--- /dev/null
+++ b/addons/guide/modifiers/guide_modifier_normalize.gd.uid
@@ -0,0 +1 @@
+uid://bu0gmehf5nomv
diff --git a/addons/guide/modifiers/guide_modifier_positive_negative.gd.uid b/addons/guide/modifiers/guide_modifier_positive_negative.gd.uid
new file mode 100644
index 0000000..7b73978
--- /dev/null
+++ b/addons/guide/modifiers/guide_modifier_positive_negative.gd.uid
@@ -0,0 +1 @@
+uid://u7w48jae3w24
diff --git a/addons/guide/modifiers/guide_modifier_scale.gd.uid b/addons/guide/modifiers/guide_modifier_scale.gd.uid
new file mode 100644
index 0000000..3ef24d8
--- /dev/null
+++ b/addons/guide/modifiers/guide_modifier_scale.gd.uid
@@ -0,0 +1 @@
+uid://dpl2ij36k6sfp
diff --git a/addons/guide/modifiers/guide_modifier_virtual_cursor.gd.uid b/addons/guide/modifiers/guide_modifier_virtual_cursor.gd.uid
new file mode 100644
index 0000000..33b3f18
--- /dev/null
+++ b/addons/guide/modifiers/guide_modifier_virtual_cursor.gd.uid
@@ -0,0 +1 @@
+uid://ce4p4fmma1jkd
diff --git a/addons/guide/modifiers/guide_modifier_window_relative.gd.uid b/addons/guide/modifiers/guide_modifier_window_relative.gd.uid
new file mode 100644
index 0000000..763f219
--- /dev/null
+++ b/addons/guide/modifiers/guide_modifier_window_relative.gd.uid
@@ -0,0 +1 @@
+uid://baxa8ht35rrdo
diff --git a/addons/guide/plugin.gd.uid b/addons/guide/plugin.gd.uid
new file mode 100644
index 0000000..05871a6
--- /dev/null
+++ b/addons/guide/plugin.gd.uid
@@ -0,0 +1 @@
+uid://dv2jpc2lupuwk
diff --git a/addons/guide/remapping/guide_input_detector.gd.uid b/addons/guide/remapping/guide_input_detector.gd.uid
new file mode 100644
index 0000000..9b996f5
--- /dev/null
+++ b/addons/guide/remapping/guide_input_detector.gd.uid
@@ -0,0 +1 @@
+uid://c5823o2wpiamt
diff --git a/addons/guide/remapping/guide_remapper.gd.uid b/addons/guide/remapping/guide_remapper.gd.uid
new file mode 100644
index 0000000..de89420
--- /dev/null
+++ b/addons/guide/remapping/guide_remapper.gd.uid
@@ -0,0 +1 @@
+uid://ct55sgurb867e
diff --git a/addons/guide/remapping/guide_remapping_config.gd.uid b/addons/guide/remapping/guide_remapping_config.gd.uid
new file mode 100644
index 0000000..9dd78aa
--- /dev/null
+++ b/addons/guide/remapping/guide_remapping_config.gd.uid
@@ -0,0 +1 @@
+uid://bphtynwtc4l1s
diff --git a/addons/guide/triggers/guide_trigger.gd.uid b/addons/guide/triggers/guide_trigger.gd.uid
new file mode 100644
index 0000000..547c597
--- /dev/null
+++ b/addons/guide/triggers/guide_trigger.gd.uid
@@ -0,0 +1 @@
+uid://bf0t8choiiqnb
diff --git a/addons/guide/triggers/guide_trigger_chorded_action.gd.uid b/addons/guide/triggers/guide_trigger_chorded_action.gd.uid
new file mode 100644
index 0000000..d29f656
--- /dev/null
+++ b/addons/guide/triggers/guide_trigger_chorded_action.gd.uid
@@ -0,0 +1 @@
+uid://bm6y7ircbddfs
diff --git a/addons/guide/triggers/guide_trigger_combo.gd.uid b/addons/guide/triggers/guide_trigger_combo.gd.uid
new file mode 100644
index 0000000..fac3366
--- /dev/null
+++ b/addons/guide/triggers/guide_trigger_combo.gd.uid
@@ -0,0 +1 @@
+uid://cec060pvt0o3p
diff --git a/addons/guide/triggers/guide_trigger_combo_cancel_action.gd.uid b/addons/guide/triggers/guide_trigger_combo_cancel_action.gd.uid
new file mode 100644
index 0000000..7212f97
--- /dev/null
+++ b/addons/guide/triggers/guide_trigger_combo_cancel_action.gd.uid
@@ -0,0 +1 @@
+uid://c8rjdy4hx2y2m
diff --git a/addons/guide/triggers/guide_trigger_combo_step.gd.uid b/addons/guide/triggers/guide_trigger_combo_step.gd.uid
new file mode 100644
index 0000000..02b0562
--- /dev/null
+++ b/addons/guide/triggers/guide_trigger_combo_step.gd.uid
@@ -0,0 +1 @@
+uid://baiohjdhsurxq
diff --git a/addons/guide/triggers/guide_trigger_down.gd.uid b/addons/guide/triggers/guide_trigger_down.gd.uid
new file mode 100644
index 0000000..0017b64
--- /dev/null
+++ b/addons/guide/triggers/guide_trigger_down.gd.uid
@@ -0,0 +1 @@
+uid://cxky2hmhu8t3x
diff --git a/addons/guide/triggers/guide_trigger_hold.gd.uid b/addons/guide/triggers/guide_trigger_hold.gd.uid
new file mode 100644
index 0000000..0df2e45
--- /dev/null
+++ b/addons/guide/triggers/guide_trigger_hold.gd.uid
@@ -0,0 +1 @@
+uid://brcxarmh6ithc
diff --git a/addons/guide/triggers/guide_trigger_pressed.gd.uid b/addons/guide/triggers/guide_trigger_pressed.gd.uid
new file mode 100644
index 0000000..a2c2acc
--- /dev/null
+++ b/addons/guide/triggers/guide_trigger_pressed.gd.uid
@@ -0,0 +1 @@
+uid://ccm1vfltgmbe
diff --git a/addons/guide/triggers/guide_trigger_pulse.gd.uid b/addons/guide/triggers/guide_trigger_pulse.gd.uid
new file mode 100644
index 0000000..ad6f30b
--- /dev/null
+++ b/addons/guide/triggers/guide_trigger_pulse.gd.uid
@@ -0,0 +1 @@
+uid://3pfpsiy0kbh4
diff --git a/addons/guide/triggers/guide_trigger_released.gd.uid b/addons/guide/triggers/guide_trigger_released.gd.uid
new file mode 100644
index 0000000..40cb93f
--- /dev/null
+++ b/addons/guide/triggers/guide_trigger_released.gd.uid
@@ -0,0 +1 @@
+uid://dcei3rp27hbso
diff --git a/addons/guide/triggers/guide_trigger_stability.gd.uid b/addons/guide/triggers/guide_trigger_stability.gd.uid
new file mode 100644
index 0000000..af522af
--- /dev/null
+++ b/addons/guide/triggers/guide_trigger_stability.gd.uid
@@ -0,0 +1 @@
+uid://cqn05ohpgxhfe
diff --git a/addons/guide/triggers/guide_trigger_tap.gd.uid b/addons/guide/triggers/guide_trigger_tap.gd.uid
new file mode 100644
index 0000000..b8596ff
--- /dev/null
+++ b/addons/guide/triggers/guide_trigger_tap.gd.uid
@@ -0,0 +1 @@
+uid://b8a1e02wrhnlj
diff --git a/addons/guide/ui/guide_icon_renderer.gd.uid b/addons/guide/ui/guide_icon_renderer.gd.uid
new file mode 100644
index 0000000..972c0d1
--- /dev/null
+++ b/addons/guide/ui/guide_icon_renderer.gd.uid
@@ -0,0 +1 @@
+uid://dqbm5cgnglupd
diff --git a/addons/guide/ui/guide_input_formatter.gd.uid b/addons/guide/ui/guide_input_formatter.gd.uid
new file mode 100644
index 0000000..15481aa
--- /dev/null
+++ b/addons/guide/ui/guide_input_formatter.gd.uid
@@ -0,0 +1 @@
+uid://cro3lh2xuhjat
diff --git a/addons/guide/ui/guide_text_provider.gd.uid b/addons/guide/ui/guide_text_provider.gd.uid
new file mode 100644
index 0000000..e6e3aa7
--- /dev/null
+++ b/addons/guide/ui/guide_text_provider.gd.uid
@@ -0,0 +1 @@
+uid://baj7ycjany6t5
diff --git a/addons/guide/ui/icon_maker/icon_maker.gd.uid b/addons/guide/ui/icon_maker/icon_maker.gd.uid
new file mode 100644
index 0000000..8d409c9
--- /dev/null
+++ b/addons/guide/ui/icon_maker/icon_maker.gd.uid
@@ -0,0 +1 @@
+uid://bcuebbdpuxper
diff --git a/addons/guide/ui/icon_maker/icon_maker.tscn b/addons/guide/ui/icon_maker/icon_maker.tscn
index 662d2ce..6e97fcc 100644
--- a/addons/guide/ui/icon_maker/icon_maker.tscn
+++ b/addons/guide/ui/icon_maker/icon_maker.tscn
@@ -1,6 +1,6 @@
[gd_scene load_steps=3 format=3 uid="uid://8thurteeibtu"]
-[ext_resource type="Script" path="res://addons/guide/ui/icon_maker/icon_maker.gd" id="1_hdbjk"]
+[ext_resource type="Script" uid="uid://bcuebbdpuxper" path="res://addons/guide/ui/icon_maker/icon_maker.gd" id="1_hdbjk"]
[sub_resource type="ViewportTexture" id="ViewportTexture_kra7t"]
viewport_path = NodePath("SubViewport")
diff --git a/addons/guide/ui/renderers/controllers/controller_renderer.gd.uid b/addons/guide/ui/renderers/controllers/controller_renderer.gd.uid
new file mode 100644
index 0000000..3d43398
--- /dev/null
+++ b/addons/guide/ui/renderers/controllers/controller_renderer.gd.uid
@@ -0,0 +1 @@
+uid://umdl0q4is1u
diff --git a/addons/guide/ui/renderers/controllers/controller_renderer.tscn b/addons/guide/ui/renderers/controllers/controller_renderer.tscn
index 9ab0538..c61a52e 100644
--- a/addons/guide/ui/renderers/controllers/controller_renderer.tscn
+++ b/addons/guide/ui/renderers/controllers/controller_renderer.tscn
@@ -1,6 +1,6 @@
[gd_scene load_steps=4 format=3 uid="uid://bsaylcb5ixjxk"]
-[ext_resource type="Script" path="res://addons/guide/ui/renderers/controllers/controller_renderer.gd" id="1_yt13e"]
+[ext_resource type="Script" uid="uid://umdl0q4is1u" path="res://addons/guide/ui/renderers/controllers/controller_renderer.gd" id="1_yt13e"]
[ext_resource type="Texture2D" uid="uid://bmgxqbypegjxh" path="res://addons/guide/ui/renderers/textures/arrow_horizontal.svg" id="2_nv2ob"]
[ext_resource type="Texture2D" uid="uid://bu5nlug6uf03w" path="res://addons/guide/ui/renderers/textures/arrow_vertical.svg" id="3_ejti1"]
diff --git a/addons/guide/ui/renderers/joy/joy_renderer.gd.uid b/addons/guide/ui/renderers/joy/joy_renderer.gd.uid
new file mode 100644
index 0000000..bf107be
--- /dev/null
+++ b/addons/guide/ui/renderers/joy/joy_renderer.gd.uid
@@ -0,0 +1 @@
+uid://cr5s0o6i0mlcp
diff --git a/addons/guide/ui/renderers/joy/joy_renderer.tscn b/addons/guide/ui/renderers/joy/joy_renderer.tscn
index a1dd98e..e58ac90 100644
--- a/addons/guide/ui/renderers/joy/joy_renderer.tscn
+++ b/addons/guide/ui/renderers/joy/joy_renderer.tscn
@@ -1,6 +1,6 @@
[gd_scene load_steps=7 format=3 uid="uid://c6sqf8rur1wss"]
-[ext_resource type="Script" path="res://addons/guide/ui/renderers/joy/joy_renderer.gd" id="1_u7brn"]
+[ext_resource type="Script" uid="uid://cr5s0o6i0mlcp" path="res://addons/guide/ui/renderers/joy/joy_renderer.gd" id="1_u7brn"]
[ext_resource type="Texture2D" uid="uid://do001o6aysaxo" path="res://addons/guide/ui/renderers/joy/icons/stick_empty.png" id="2_23u2k"]
[ext_resource type="Texture2D" uid="uid://veqjcwokdukw" path="res://addons/guide/ui/renderers/joy/icons/button_empty.png" id="3_7qfbp"]
[ext_resource type="FontFile" uid="uid://cu8bvod6tnnwr" path="res://addons/guide/ui/renderers/keyboard/Lato-Black.ttf" id="4_otp86"]
diff --git a/addons/guide/ui/renderers/keyboard/Lato-Black.ttf.import b/addons/guide/ui/renderers/keyboard/Lato-Black.ttf.import
index f2b96dd..c7bb2da 100644
--- a/addons/guide/ui/renderers/keyboard/Lato-Black.ttf.import
+++ b/addons/guide/ui/renderers/keyboard/Lato-Black.ttf.import
@@ -23,6 +23,7 @@ allow_system_fallback=true
force_autohinter=false
hinting=1
subpixel_positioning=1
+keep_rounding_remainders=true
oversampling=0.0
Fallbacks=null
fallbacks=[]
diff --git a/addons/guide/ui/renderers/keyboard/key_renderer.gd.uid b/addons/guide/ui/renderers/keyboard/key_renderer.gd.uid
new file mode 100644
index 0000000..d0c42ed
--- /dev/null
+++ b/addons/guide/ui/renderers/keyboard/key_renderer.gd.uid
@@ -0,0 +1 @@
+uid://bp7usjfkvypy0
diff --git a/addons/guide/ui/renderers/keyboard/key_renderer.tscn b/addons/guide/ui/renderers/keyboard/key_renderer.tscn
index eacb5b9..0506765 100644
--- a/addons/guide/ui/renderers/keyboard/key_renderer.tscn
+++ b/addons/guide/ui/renderers/keyboard/key_renderer.tscn
@@ -1,6 +1,6 @@
[gd_scene load_steps=4 format=3 uid="uid://toty2e3yx26l"]
-[ext_resource type="Script" path="res://addons/guide/ui/renderers/keyboard/key_renderer.gd" id="1_tm2sd"]
+[ext_resource type="Script" uid="uid://bp7usjfkvypy0" path="res://addons/guide/ui/renderers/keyboard/key_renderer.gd" id="1_tm2sd"]
[ext_resource type="Texture2D" uid="uid://b3x586os8uuwb" path="res://addons/guide/ui/renderers/keyboard/icons/Blank_White_Normal.png" id="2_myc15"]
[ext_resource type="FontFile" uid="uid://cu8bvod6tnnwr" path="res://addons/guide/ui/renderers/keyboard/Lato-Black.ttf" id="3_d3uds"]
diff --git a/addons/guide/ui/renderers/misc/action_renderer.gd.uid b/addons/guide/ui/renderers/misc/action_renderer.gd.uid
new file mode 100644
index 0000000..7304433
--- /dev/null
+++ b/addons/guide/ui/renderers/misc/action_renderer.gd.uid
@@ -0,0 +1 @@
+uid://dcpbinyawmrim
diff --git a/addons/guide/ui/renderers/misc/action_renderer.tscn b/addons/guide/ui/renderers/misc/action_renderer.tscn
index 88cb452..d9abeea 100644
--- a/addons/guide/ui/renderers/misc/action_renderer.tscn
+++ b/addons/guide/ui/renderers/misc/action_renderer.tscn
@@ -1,6 +1,6 @@
[gd_scene load_steps=3 format=3 uid="uid://ortn6jb3wljf"]
-[ext_resource type="Script" path="res://addons/guide/ui/renderers/misc/action_renderer.gd" id="1_140q4"]
+[ext_resource type="Script" uid="uid://dcpbinyawmrim" path="res://addons/guide/ui/renderers/misc/action_renderer.gd" id="1_140q4"]
[ext_resource type="Texture2D" uid="uid://diwkvjkss2ie" path="res://addons/guide/ui/renderers/textures/action.svg" id="2_uqvia"]
[node name="ActionRenderer" type="MarginContainer"]
diff --git a/addons/guide/ui/renderers/misc/fallback_renderer.gd.uid b/addons/guide/ui/renderers/misc/fallback_renderer.gd.uid
new file mode 100644
index 0000000..7c80e5e
--- /dev/null
+++ b/addons/guide/ui/renderers/misc/fallback_renderer.gd.uid
@@ -0,0 +1 @@
+uid://btt4yt4yu28yp
diff --git a/addons/guide/ui/renderers/misc/fallback_renderer.tscn b/addons/guide/ui/renderers/misc/fallback_renderer.tscn
index 106c8d8..743af0c 100644
--- a/addons/guide/ui/renderers/misc/fallback_renderer.tscn
+++ b/addons/guide/ui/renderers/misc/fallback_renderer.tscn
@@ -1,6 +1,6 @@
[gd_scene load_steps=3 format=3 uid="uid://bqf4yoind3a82"]
-[ext_resource type="Script" path="res://addons/guide/ui/renderers/misc/fallback_renderer.gd" id="1_mgm3k"]
+[ext_resource type="Script" uid="uid://btt4yt4yu28yp" path="res://addons/guide/ui/renderers/misc/fallback_renderer.gd" id="1_mgm3k"]
[ext_resource type="FontFile" uid="uid://cu8bvod6tnnwr" path="res://addons/guide/ui/renderers/keyboard/Lato-Black.ttf" id="2_5hk8u"]
[node name="FallbackRenderer" type="MarginContainer"]
diff --git a/addons/guide/ui/renderers/mouse/mouse_renderer.gd.uid b/addons/guide/ui/renderers/mouse/mouse_renderer.gd.uid
new file mode 100644
index 0000000..c5fa578
--- /dev/null
+++ b/addons/guide/ui/renderers/mouse/mouse_renderer.gd.uid
@@ -0,0 +1 @@
+uid://cffeshu6gqsgx
diff --git a/addons/guide/ui/renderers/mouse/mouse_renderer.tscn b/addons/guide/ui/renderers/mouse/mouse_renderer.tscn
index 7e51e7d..68c3879 100644
--- a/addons/guide/ui/renderers/mouse/mouse_renderer.tscn
+++ b/addons/guide/ui/renderers/mouse/mouse_renderer.tscn
@@ -1,6 +1,6 @@
[gd_scene load_steps=15 format=3 uid="uid://bfl6dbw21xqs1"]
-[ext_resource type="Script" path="res://addons/guide/ui/renderers/mouse/mouse_renderer.gd" id="1_amutf"]
+[ext_resource type="Script" uid="uid://cffeshu6gqsgx" path="res://addons/guide/ui/renderers/mouse/mouse_renderer.gd" id="1_amutf"]
[ext_resource type="Texture2D" uid="uid://vvgpheda22ew" path="res://addons/guide/ui/renderers/mouse/icons/Mouse_Left_Key_Light.png" id="2_6vk7n"]
[ext_resource type="Texture2D" uid="uid://b8bsyguf4qw6f" path="res://addons/guide/ui/renderers/mouse/icons/Mouse_Right_Key_Light.png" id="3_aaqrj"]
[ext_resource type="Texture2D" uid="uid://bmj244x0jn7v2" path="res://addons/guide/ui/renderers/mouse/icons/Mouse_Middle_Key_Light.png" id="4_gprek"]
diff --git a/addons/guide/ui/renderers/touch/touch_renderer.gd.uid b/addons/guide/ui/renderers/touch/touch_renderer.gd.uid
new file mode 100644
index 0000000..2e24c24
--- /dev/null
+++ b/addons/guide/ui/renderers/touch/touch_renderer.gd.uid
@@ -0,0 +1 @@
+uid://ifnst4gxj4q7
diff --git a/addons/guide/ui/renderers/touch/touch_renderer.tscn b/addons/guide/ui/renderers/touch/touch_renderer.tscn
index b54a0e8..3bbb5e0 100644
--- a/addons/guide/ui/renderers/touch/touch_renderer.tscn
+++ b/addons/guide/ui/renderers/touch/touch_renderer.tscn
@@ -1,6 +1,6 @@
[gd_scene load_steps=11 format=3 uid="uid://ykuou1deo5ub"]
-[ext_resource type="Script" path="res://addons/guide/ui/renderers/touch/touch_renderer.gd" id="1_heixj"]
+[ext_resource type="Script" uid="uid://ifnst4gxj4q7" path="res://addons/guide/ui/renderers/touch/touch_renderer.gd" id="1_heixj"]
[ext_resource type="Texture2D" uid="uid://c5nwnp5cjny7m" path="res://addons/guide/ui/renderers/touch/icons/touch_1_finger.png" id="2_4mplc"]
[ext_resource type="Texture2D" uid="uid://bllhe78a1yo6" path="res://addons/guide/ui/renderers/touch/icons/touch_2_fingers.png" id="3_0dcqu"]
[ext_resource type="Texture2D" uid="uid://bwhqf2nmm5q1w" path="res://addons/guide/ui/renderers/touch/icons/touch_3_fingers.png" id="4_mgq0v"]
diff --git a/addons/guide/ui/text_providers/controllers/controller_text_provider.gd.uid b/addons/guide/ui/text_providers/controllers/controller_text_provider.gd.uid
new file mode 100644
index 0000000..3fa96fc
--- /dev/null
+++ b/addons/guide/ui/text_providers/controllers/controller_text_provider.gd.uid
@@ -0,0 +1 @@
+uid://cx2cfjsh68i1q
diff --git a/addons/guide/ui/text_providers/controllers/playstation/playstation_controller_text_provider.gd.uid b/addons/guide/ui/text_providers/controllers/playstation/playstation_controller_text_provider.gd.uid
new file mode 100644
index 0000000..951227e
--- /dev/null
+++ b/addons/guide/ui/text_providers/controllers/playstation/playstation_controller_text_provider.gd.uid
@@ -0,0 +1 @@
+uid://0llhrxb0bat2
diff --git a/addons/guide/ui/text_providers/controllers/switch/switch_controller_text_provider.gd.uid b/addons/guide/ui/text_providers/controllers/switch/switch_controller_text_provider.gd.uid
new file mode 100644
index 0000000..e6206da
--- /dev/null
+++ b/addons/guide/ui/text_providers/controllers/switch/switch_controller_text_provider.gd.uid
@@ -0,0 +1 @@
+uid://c6j7crlp6ou50
diff --git a/addons/guide/ui/text_providers/controllers/xbox/xbox_controller_text_provider.gd.uid b/addons/guide/ui/text_providers/controllers/xbox/xbox_controller_text_provider.gd.uid
new file mode 100644
index 0000000..33a81c2
--- /dev/null
+++ b/addons/guide/ui/text_providers/controllers/xbox/xbox_controller_text_provider.gd.uid
@@ -0,0 +1 @@
+uid://dle2rbb4i13en
diff --git a/addons/guide/ui/text_providers/default_text_provider.gd.uid b/addons/guide/ui/text_providers/default_text_provider.gd.uid
new file mode 100644
index 0000000..2dc55c6
--- /dev/null
+++ b/addons/guide/ui/text_providers/default_text_provider.gd.uid
@@ -0,0 +1 @@
+uid://brekmfywuc503
diff --git a/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_example_scene.tscn
index e1119a8..d221194 100644
--- a/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_example_scene.tscn
@@ -4,11 +4,11 @@
[ext_resource type="PackedScene" uid="uid://dg7rhrymsrrrm" path="res://addons/phantom_camera/examples/ui/ui_inventory.tscn" id="2_kmt5y"]
[ext_resource type="PackedScene" uid="uid://iq5xd1ob1res" path="res://addons/phantom_camera/examples/ui/ui_sign.tscn" id="3_1cmgi"]
[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="4_4dx73"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="5_gcww2"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="6_i3g4f"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="5_gcww2"]
+[ext_resource type="Script" uid="uid://d23haq52m7ulv" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="6_i3g4f"]
[ext_resource type="Resource" uid="uid://euybd2w0bax" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_2d_tween.tres" id="7_j2i8l"]
[ext_resource type="PackedScene" uid="uid://7kh0xydx0b1o" path="res://addons/phantom_camera/examples/example_scenes/2D/sub_scenes/playable_character_2d.tscn" id="8_ytjsp"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/2D/player_character_body_2d_4.3.gd" id="9_o4c4h"]
+[ext_resource type="Script" uid="uid://ci7lfaa7jvsu7" path="res://addons/phantom_camera/examples/scripts/2D/player_character_body_2d_4.3.gd" id="9_o4c4h"]
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_yx3lp"]
texture = ExtResource("1_foq54")
diff --git a/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_follow_framed_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_follow_framed_example_scene.tscn
index 48f31c7..2f49a7c 100644
--- a/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_follow_framed_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_follow_framed_example_scene.tscn
@@ -3,12 +3,12 @@
[ext_resource type="Texture2D" uid="uid://c77npili4pel4" path="res://addons/phantom_camera/examples/textures/2D/level_spritesheet.png" id="1_nf5bo"]
[ext_resource type="PackedScene" uid="uid://dg7rhrymsrrrm" path="res://addons/phantom_camera/examples/ui/ui_inventory.tscn" id="2_5oggv"]
[ext_resource type="PackedScene" uid="uid://iq5xd1ob1res" path="res://addons/phantom_camera/examples/ui/ui_sign.tscn" id="3_aku7q"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="4_j3ux0"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="5_uwr6r"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="4_j3ux0"]
+[ext_resource type="Script" uid="uid://d23haq52m7ulv" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="5_uwr6r"]
[ext_resource type="Resource" uid="uid://euybd2w0bax" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_2d_tween.tres" id="6_4l0c3"]
[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="7_briql"]
[ext_resource type="PackedScene" uid="uid://7kh0xydx0b1o" path="res://addons/phantom_camera/examples/example_scenes/2D/sub_scenes/playable_character_2d.tscn" id="8_i4m1d"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/2D/player_character_body_2d_4.3.gd" id="9_m3lnd"]
+[ext_resource type="Script" uid="uid://ci7lfaa7jvsu7" path="res://addons/phantom_camera/examples/scripts/2D/player_character_body_2d_4.3.gd" id="9_m3lnd"]
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_dpuou"]
texture = ExtResource("1_nf5bo")
diff --git a/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_follow_group_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_follow_group_example_scene.tscn
index 6519323..7760390 100644
--- a/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_follow_group_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_follow_group_example_scene.tscn
@@ -3,13 +3,13 @@
[ext_resource type="Texture2D" uid="uid://c77npili4pel4" path="res://addons/phantom_camera/examples/textures/2D/level_spritesheet.png" id="1_8rflf"]
[ext_resource type="PackedScene" uid="uid://dg7rhrymsrrrm" path="res://addons/phantom_camera/examples/ui/ui_inventory.tscn" id="2_tafwr"]
[ext_resource type="PackedScene" uid="uid://iq5xd1ob1res" path="res://addons/phantom_camera/examples/ui/ui_sign.tscn" id="3_37c7w"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="4_dxiro"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="4_dxiro"]
[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="5_gaaip"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="6_ojk83"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="7_awenl"]
+[ext_resource type="Script" uid="uid://d23haq52m7ulv" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="6_ojk83"]
+[ext_resource type="Script" uid="uid://ccfft4b8rwgbo" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="7_awenl"]
[ext_resource type="Texture2D" uid="uid://cwep0on2tthn7" path="res://addons/phantom_camera/examples/textures/2D/phantom_camera_2d_sprite.png" id="8_ys0m4"]
[ext_resource type="PackedScene" uid="uid://7kh0xydx0b1o" path="res://addons/phantom_camera/examples/example_scenes/2D/sub_scenes/playable_character_2d.tscn" id="9_witv0"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/2D/player_character_body_2d_4.3.gd" id="10_aivri"]
+[ext_resource type="Script" uid="uid://ci7lfaa7jvsu7" path="res://addons/phantom_camera/examples/scripts/2D/player_character_body_2d_4.3.gd" id="10_aivri"]
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_3qxnm"]
texture = ExtResource("1_8rflf")
diff --git a/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_follow_path_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_follow_path_example_scene.tscn
index b5d2775..194e1c4 100644
--- a/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_follow_path_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_follow_path_example_scene.tscn
@@ -3,12 +3,12 @@
[ext_resource type="Texture2D" uid="uid://c77npili4pel4" path="res://addons/phantom_camera/examples/textures/2D/level_spritesheet.png" id="1_t003o"]
[ext_resource type="PackedScene" uid="uid://dg7rhrymsrrrm" path="res://addons/phantom_camera/examples/ui/ui_inventory.tscn" id="2_4ncqd"]
[ext_resource type="PackedScene" uid="uid://iq5xd1ob1res" path="res://addons/phantom_camera/examples/ui/ui_sign.tscn" id="3_tpji3"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="4_w0rat"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="4_w0rat"]
[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="5_q77r4"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="6_y6hoa"]
+[ext_resource type="Script" uid="uid://d23haq52m7ulv" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="6_y6hoa"]
[ext_resource type="Resource" uid="uid://euybd2w0bax" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_2d_tween.tres" id="7_wd55r"]
[ext_resource type="PackedScene" uid="uid://7kh0xydx0b1o" path="res://addons/phantom_camera/examples/example_scenes/2D/sub_scenes/playable_character_2d.tscn" id="8_fy81j"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/2D/player_character_body_2d_4.3.gd" id="9_u6ygl"]
+[ext_resource type="Script" uid="uid://ci7lfaa7jvsu7" path="res://addons/phantom_camera/examples/scripts/2D/player_character_body_2d_4.3.gd" id="9_u6ygl"]
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_nivvc"]
texture = ExtResource("1_t003o")
diff --git a/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_limit_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_limit_example_scene.tscn
index 9eb1d61..1613303 100644
--- a/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_limit_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_limit_example_scene.tscn
@@ -1,14 +1,14 @@
[gd_scene load_steps=17 format=4 uid="uid://0ox7hgdpwpqp"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/2D/2d_room_limit_tween_4.3.gd" id="1_bwr3f"]
+[ext_resource type="Script" uid="uid://b7wnot35mku6h" path="res://addons/phantom_camera/examples/scripts/2D/2d_room_limit_tween_4.3.gd" id="1_bwr3f"]
[ext_resource type="Texture2D" uid="uid://c77npili4pel4" path="res://addons/phantom_camera/examples/textures/2D/level_spritesheet.png" id="2_f03of"]
[ext_resource type="PackedScene" uid="uid://dg7rhrymsrrrm" path="res://addons/phantom_camera/examples/ui/ui_inventory.tscn" id="3_cysy4"]
[ext_resource type="PackedScene" uid="uid://iq5xd1ob1res" path="res://addons/phantom_camera/examples/ui/ui_sign.tscn" id="4_qqut6"]
[ext_resource type="PackedScene" uid="uid://7kh0xydx0b1o" path="res://addons/phantom_camera/examples/example_scenes/2D/sub_scenes/playable_character_2d.tscn" id="5_yv8tn"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="6_2n5r1"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/2D/player_character_body_2d_4.3.gd" id="6_68ewj"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="7_ne05h"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="8_hulu3"]
+[ext_resource type="Script" uid="uid://d23haq52m7ulv" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="6_2n5r1"]
+[ext_resource type="Script" uid="uid://ci7lfaa7jvsu7" path="res://addons/phantom_camera/examples/scripts/2D/player_character_body_2d_4.3.gd" id="6_68ewj"]
+[ext_resource type="Script" uid="uid://ccfft4b8rwgbo" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="7_ne05h"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="8_hulu3"]
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_easgx"]
texture = ExtResource("2_f03of")
diff --git a/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_noise_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_noise_example_scene.tscn
index 029444b..9250e31 100644
--- a/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_noise_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_noise_example_scene.tscn
@@ -4,13 +4,13 @@
[ext_resource type="PackedScene" uid="uid://dg7rhrymsrrrm" path="res://addons/phantom_camera/examples/ui/ui_inventory.tscn" id="2_4bfy0"]
[ext_resource type="PackedScene" uid="uid://iq5xd1ob1res" path="res://addons/phantom_camera/examples/ui/ui_sign.tscn" id="3_vdqsb"]
[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="4_w2gh7"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="5_d6fcf"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="6_bdmii"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="5_d6fcf"]
+[ext_resource type="Script" uid="uid://d23haq52m7ulv" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="6_bdmii"]
[ext_resource type="Resource" uid="uid://euybd2w0bax" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_2d_tween.tres" id="7_dpnkg"]
[ext_resource type="PackedScene" uid="uid://7kh0xydx0b1o" path="res://addons/phantom_camera/examples/example_scenes/2D/sub_scenes/playable_character_2d.tscn" id="8_u5o87"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/2D/player_character_body_2d_4.3.gd" id="9_suxld"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_noise_emitter_2d.gd" id="10_p43w0"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/phantom_camera_noise_2d.gd" id="11_d6abr"]
+[ext_resource type="Script" uid="uid://ci7lfaa7jvsu7" path="res://addons/phantom_camera/examples/scripts/2D/player_character_body_2d_4.3.gd" id="9_suxld"]
+[ext_resource type="Script" uid="uid://bskijkg6twd3h" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_noise_emitter_2d.gd" id="10_p43w0"]
+[ext_resource type="Script" uid="uid://daroioflx7bt1" path="res://addons/phantom_camera/scripts/resources/phantom_camera_noise_2d.gd" id="11_d6abr"]
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_lvmak"]
texture = ExtResource("1_2m0x8")
diff --git a/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_tweening_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_tweening_example_scene.tscn
index 74db5c1..b0f945a 100644
--- a/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_tweening_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_tweening_example_scene.tscn
@@ -3,14 +3,14 @@
[ext_resource type="Texture2D" uid="uid://c77npili4pel4" path="res://addons/phantom_camera/examples/textures/2D/level_spritesheet.png" id="1_h1rbo"]
[ext_resource type="PackedScene" uid="uid://dg7rhrymsrrrm" path="res://addons/phantom_camera/examples/ui/ui_inventory.tscn" id="2_1f2t2"]
[ext_resource type="PackedScene" uid="uid://iq5xd1ob1res" path="res://addons/phantom_camera/examples/ui/ui_sign.tscn" id="3_o6nri"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="4_j7670"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="5_gvv7r"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="4_j7670"]
+[ext_resource type="Script" uid="uid://d23haq52m7ulv" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="5_gvv7r"]
[ext_resource type="Resource" uid="uid://euybd2w0bax" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_2d_tween.tres" id="6_rwobr"]
[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="7_ylx0h"]
[ext_resource type="PackedScene" uid="uid://7kh0xydx0b1o" path="res://addons/phantom_camera/examples/example_scenes/2D/sub_scenes/playable_character_2d.tscn" id="8_ytsgf"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/2D/2d_trigger_area.gd" id="9_3r1pw"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/2D/player_character_body_2d_4.3.gd" id="9_5jy5e"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="10_guf2v"]
+[ext_resource type="Script" uid="uid://cjparvte7lvi4" path="res://addons/phantom_camera/examples/scripts/2D/2d_trigger_area.gd" id="9_3r1pw"]
+[ext_resource type="Script" uid="uid://ci7lfaa7jvsu7" path="res://addons/phantom_camera/examples/scripts/2D/player_character_body_2d_4.3.gd" id="9_5jy5e"]
+[ext_resource type="Script" uid="uid://ccfft4b8rwgbo" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="10_guf2v"]
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_cvmao"]
texture = ExtResource("1_h1rbo")
diff --git a/addons/phantom_camera/examples/example_scenes/2D/2d_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/2D/2d_example_scene.tscn
index 40aa4aa..c87f274 100644
--- a/addons/phantom_camera/examples/example_scenes/2D/2d_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/2D/2d_example_scene.tscn
@@ -1,8 +1,8 @@
[gd_scene load_steps=11 format=3 uid="uid://drvexsp2t0nfy"]
[ext_resource type="Texture2D" uid="uid://c77npili4pel4" path="res://addons/phantom_camera/examples/textures/2D/level_spritesheet.png" id="1_1utlo"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="2_mgsut"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="4_54fc4"]
+[ext_resource type="Script" uid="uid://d23haq52m7ulv" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="2_mgsut"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="4_54fc4"]
[ext_resource type="PackedScene" uid="uid://iq5xd1ob1res" path="res://addons/phantom_camera/examples/ui/ui_sign.tscn" id="6_kqt1v"]
[ext_resource type="Resource" uid="uid://euybd2w0bax" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_2d_tween.tres" id="6_pxbym"]
[ext_resource type="PackedScene" uid="uid://7kh0xydx0b1o" path="res://addons/phantom_camera/examples/example_scenes/2D/sub_scenes/playable_character_2d.tscn" id="7_62i3t"]
diff --git a/addons/phantom_camera/examples/example_scenes/2D/2d_follow_framed_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/2D/2d_follow_framed_example_scene.tscn
index 74cac59..203c2f3 100644
--- a/addons/phantom_camera/examples/example_scenes/2D/2d_follow_framed_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/2D/2d_follow_framed_example_scene.tscn
@@ -3,8 +3,8 @@
[ext_resource type="Texture2D" uid="uid://c77npili4pel4" path="res://addons/phantom_camera/examples/textures/2D/level_spritesheet.png" id="1_27o77"]
[ext_resource type="PackedScene" uid="uid://dg7rhrymsrrrm" path="res://addons/phantom_camera/examples/ui/ui_inventory.tscn" id="2_1tbys"]
[ext_resource type="PackedScene" uid="uid://iq5xd1ob1res" path="res://addons/phantom_camera/examples/ui/ui_sign.tscn" id="3_1kfnp"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="4_mylkx"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="5_lwx5e"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="4_mylkx"]
+[ext_resource type="Script" uid="uid://d23haq52m7ulv" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="5_lwx5e"]
[ext_resource type="Resource" uid="uid://euybd2w0bax" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_2d_tween.tres" id="6_tju6r"]
[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="8_bo8m7"]
[ext_resource type="PackedScene" uid="uid://7kh0xydx0b1o" path="res://addons/phantom_camera/examples/example_scenes/2D/sub_scenes/playable_character_2d.tscn" id="8_wlikg"]
diff --git a/addons/phantom_camera/examples/example_scenes/2D/2d_follow_group_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/2D/2d_follow_group_example_scene.tscn
index 103729b..7257ff0 100644
--- a/addons/phantom_camera/examples/example_scenes/2D/2d_follow_group_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/2D/2d_follow_group_example_scene.tscn
@@ -3,11 +3,11 @@
[ext_resource type="Texture2D" uid="uid://c77npili4pel4" path="res://addons/phantom_camera/examples/textures/2D/level_spritesheet.png" id="1_5kqbp"]
[ext_resource type="PackedScene" uid="uid://dg7rhrymsrrrm" path="res://addons/phantom_camera/examples/ui/ui_inventory.tscn" id="2_xmntp"]
[ext_resource type="PackedScene" uid="uid://iq5xd1ob1res" path="res://addons/phantom_camera/examples/ui/ui_sign.tscn" id="3_8dojy"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="4_2efwt"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="4_2efwt"]
[ext_resource type="Texture2D" uid="uid://cwep0on2tthn7" path="res://addons/phantom_camera/examples/textures/2D/phantom_camera_2d_sprite.png" id="5_0v2cd"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="6_diuy4"]
+[ext_resource type="Script" uid="uid://d23haq52m7ulv" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="6_diuy4"]
[ext_resource type="PackedScene" uid="uid://7kh0xydx0b1o" path="res://addons/phantom_camera/examples/example_scenes/2D/sub_scenes/playable_character_2d.tscn" id="7_ybwrw"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="9_wk0p3"]
+[ext_resource type="Script" uid="uid://ccfft4b8rwgbo" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="9_wk0p3"]
[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="12_uvcwb"]
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_easgx"]
diff --git a/addons/phantom_camera/examples/example_scenes/2D/2d_follow_path_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/2D/2d_follow_path_example_scene.tscn
index 247a15b..9f7c877 100644
--- a/addons/phantom_camera/examples/example_scenes/2D/2d_follow_path_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/2D/2d_follow_path_example_scene.tscn
@@ -3,8 +3,8 @@
[ext_resource type="Texture2D" uid="uid://c77npili4pel4" path="res://addons/phantom_camera/examples/textures/2D/level_spritesheet.png" id="1_17ngo"]
[ext_resource type="PackedScene" uid="uid://dg7rhrymsrrrm" path="res://addons/phantom_camera/examples/ui/ui_inventory.tscn" id="2_whpvu"]
[ext_resource type="PackedScene" uid="uid://iq5xd1ob1res" path="res://addons/phantom_camera/examples/ui/ui_sign.tscn" id="3_rbo5b"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="4_yddet"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="5_x25dj"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="4_yddet"]
+[ext_resource type="Script" uid="uid://d23haq52m7ulv" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="5_x25dj"]
[ext_resource type="Resource" uid="uid://euybd2w0bax" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_2d_tween.tres" id="6_4vtmp"]
[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="8_6pcaf"]
[ext_resource type="PackedScene" uid="uid://7kh0xydx0b1o" path="res://addons/phantom_camera/examples/example_scenes/2D/sub_scenes/playable_character_2d.tscn" id="8_a2pel"]
diff --git a/addons/phantom_camera/examples/example_scenes/2D/2d_limit_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/2D/2d_limit_example_scene.tscn
index f1f7e7f..56508a7 100644
--- a/addons/phantom_camera/examples/example_scenes/2D/2d_limit_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/2D/2d_limit_example_scene.tscn
@@ -1,13 +1,13 @@
[gd_scene load_steps=16 format=3 uid="uid://w20wokw3ohsq"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/2D/2d_room_limit_tween.gd" id="1_ijqyv"]
+[ext_resource type="Script" uid="uid://cpxh0wtbnb3lg" path="res://addons/phantom_camera/examples/scripts/2D/2d_room_limit_tween.gd" id="1_ijqyv"]
[ext_resource type="Texture2D" uid="uid://c77npili4pel4" path="res://addons/phantom_camera/examples/textures/2D/level_spritesheet.png" id="1_wmhqb"]
[ext_resource type="PackedScene" uid="uid://dg7rhrymsrrrm" path="res://addons/phantom_camera/examples/ui/ui_inventory.tscn" id="2_v5qg2"]
[ext_resource type="PackedScene" uid="uid://iq5xd1ob1res" path="res://addons/phantom_camera/examples/ui/ui_sign.tscn" id="3_oqmwp"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="4_4b648"]
+[ext_resource type="Script" uid="uid://d23haq52m7ulv" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="4_4b648"]
[ext_resource type="PackedScene" uid="uid://7kh0xydx0b1o" path="res://addons/phantom_camera/examples/example_scenes/2D/sub_scenes/playable_character_2d.tscn" id="5_pr2x5"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="9_twplb"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="9_w5e16"]
+[ext_resource type="Script" uid="uid://ccfft4b8rwgbo" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="9_twplb"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="9_w5e16"]
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_easgx"]
texture = ExtResource("1_wmhqb")
diff --git a/addons/phantom_camera/examples/example_scenes/2D/2d_tweening_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/2D/2d_tweening_example_scene.tscn
index 4a72e81..57bafe8 100644
--- a/addons/phantom_camera/examples/example_scenes/2D/2d_tweening_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/2D/2d_tweening_example_scene.tscn
@@ -3,12 +3,12 @@
[ext_resource type="Texture2D" uid="uid://c77npili4pel4" path="res://addons/phantom_camera/examples/textures/2D/level_spritesheet.png" id="1_oo2bo"]
[ext_resource type="PackedScene" uid="uid://dg7rhrymsrrrm" path="res://addons/phantom_camera/examples/ui/ui_inventory.tscn" id="2_as4e6"]
[ext_resource type="PackedScene" uid="uid://iq5xd1ob1res" path="res://addons/phantom_camera/examples/ui/ui_sign.tscn" id="3_6yi7w"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="4_bb7en"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="5_kikl5"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="6_8u8cj"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="4_bb7en"]
+[ext_resource type="Script" uid="uid://d23haq52m7ulv" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="5_kikl5"]
+[ext_resource type="Script" uid="uid://ccfft4b8rwgbo" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="6_8u8cj"]
[ext_resource type="Resource" uid="uid://euybd2w0bax" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_2d_tween.tres" id="6_gu0o0"]
[ext_resource type="PackedScene" uid="uid://7kh0xydx0b1o" path="res://addons/phantom_camera/examples/example_scenes/2D/sub_scenes/playable_character_2d.tscn" id="8_g1syc"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/2D/2d_trigger_area.gd" id="9_184pu"]
+[ext_resource type="Script" uid="uid://cjparvte7lvi4" path="res://addons/phantom_camera/examples/scripts/2D/2d_trigger_area.gd" id="9_184pu"]
[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="11_myq47"]
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_easgx"]
diff --git a/addons/phantom_camera/examples/example_scenes/2D/sub_scenes/playable_character_2d.tscn b/addons/phantom_camera/examples/example_scenes/2D/sub_scenes/playable_character_2d.tscn
index 2ff6075..b583388 100644
--- a/addons/phantom_camera/examples/example_scenes/2D/sub_scenes/playable_character_2d.tscn
+++ b/addons/phantom_camera/examples/example_scenes/2D/sub_scenes/playable_character_2d.tscn
@@ -1,9 +1,9 @@
[gd_scene load_steps=10 format=3 uid="uid://7kh0xydx0b1o"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/2D/player_character_body_2d.gd" id="1_jnc14"]
+[ext_resource type="Script" uid="uid://bxii6lssrm0pp" path="res://addons/phantom_camera/examples/scripts/2D/player_character_body_2d.gd" id="1_jnc14"]
[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="2_62b2n"]
[ext_resource type="Texture2D" uid="uid://cscjjt55iw2cu" path="res://addons/phantom_camera/examples/textures/2D/player_sprite.svg" id="2_yr8cm"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="4_rloon"]
+[ext_resource type="Script" uid="uid://d23haq52m7ulv" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="4_rloon"]
[ext_resource type="Resource" uid="uid://cecrnq0wnkexh" path="res://addons/phantom_camera/examples/resources/tween/item_focus_phantom_camera_2d_tween.tres" id="5_4iyk1"]
[ext_resource type="Resource" uid="uid://cllveybboaqk5" path="res://addons/phantom_camera/examples/resources/tween/inventory_phantom_camera_2d_tween.tres" id="6_2h6fv"]
diff --git a/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_example_scene.tscn
index c3c90f4..9ef93b8 100644
--- a/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_example_scene.tscn
@@ -1,15 +1,15 @@
[gd_scene load_steps=41 format=3 uid="uid://cypbptekk8etg"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_u86qq"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_u86qq"]
[ext_resource type="PackedScene" uid="uid://bulsh7s0ibmao" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn" id="2_jl1he"]
[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="3_an0dt"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_4.4.gd" id="3_yfuq5"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="4_iy6qn"]
+[ext_resource type="Script" uid="uid://dw1obe248t83j" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_4.4.gd" id="3_yfuq5"]
+[ext_resource type="Script" uid="uid://bu76fr7072fv0" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="4_iy6qn"]
[ext_resource type="Resource" uid="uid://cptfoggk2ok67" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_3d_tween.tres" id="5_0ku52"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="6_prr6u"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/3D/npc.gd" id="7_nl3ax"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="8_xvqcg"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/3D/3d_trigger_area.gd" id="9_hqgwi"]
+[ext_resource type="Script" uid="uid://dscwf24xavqcu" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="6_prr6u"]
+[ext_resource type="Script" uid="uid://b7kjbvamap1u8" path="res://addons/phantom_camera/examples/scripts/3D/npc.gd" id="7_nl3ax"]
+[ext_resource type="Script" uid="uid://ccfft4b8rwgbo" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="8_xvqcg"]
+[ext_resource type="Script" uid="uid://c3ghgg2gdidnj" path="res://addons/phantom_camera/examples/scripts/3D/3d_trigger_area.gd" id="9_hqgwi"]
[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="10_cd0kn"]
[sub_resource type="Resource" id="Resource_jtk1d"]
diff --git a/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_framed_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_framed_example_scene.tscn
index 427c6cc..7327e4d 100644
--- a/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_framed_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_framed_example_scene.tscn
@@ -1,11 +1,11 @@
[gd_scene load_steps=11 format=3 uid="uid://cx7x48cpi8gcd"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_6uslv"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_5cpe8"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_6uslv"]
+[ext_resource type="Script" uid="uid://bu76fr7072fv0" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_5cpe8"]
[ext_resource type="Resource" uid="uid://cptfoggk2ok67" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_3d_tween.tres" id="3_422w7"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_4qurp"]
+[ext_resource type="Script" uid="uid://dscwf24xavqcu" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_4qurp"]
[ext_resource type="PackedScene" uid="uid://bulsh7s0ibmao" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn" id="5_uw36d"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_4.4.gd" id="6_fcomr"]
+[ext_resource type="Script" uid="uid://dw1obe248t83j" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_4.4.gd" id="6_fcomr"]
[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="6_i060b"]
[ext_resource type="Texture2D" uid="uid://c7ja4woxol8yc" path="res://addons/phantom_camera/examples/textures/3D/checker_pattern_dark.png" id="7_iyghi"]
diff --git a/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_glued_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_glued_example_scene.tscn
index 302db04..ddce898 100644
--- a/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_glued_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_glued_example_scene.tscn
@@ -1,11 +1,11 @@
[gd_scene load_steps=15 format=3 uid="uid://d2lx45noxq685"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_7a3wq"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_158c0"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="3_ganw1"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_kig2n"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_7a3wq"]
+[ext_resource type="Script" uid="uid://bu76fr7072fv0" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_158c0"]
+[ext_resource type="Script" uid="uid://ccfft4b8rwgbo" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="3_ganw1"]
+[ext_resource type="Script" uid="uid://dscwf24xavqcu" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_kig2n"]
[ext_resource type="PackedScene" uid="uid://bulsh7s0ibmao" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn" id="5_caky3"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_4.4.gd" id="6_b6ic4"]
+[ext_resource type="Script" uid="uid://dw1obe248t83j" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_4.4.gd" id="6_b6ic4"]
[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="6_kkbaa"]
[ext_resource type="Texture2D" uid="uid://c7ja4woxol8yc" path="res://addons/phantom_camera/examples/textures/3D/checker_pattern_dark.png" id="7_i1dbs"]
diff --git a/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_group_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_group_example_scene.tscn
index 01be18f..2804652 100644
--- a/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_group_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_group_example_scene.tscn
@@ -1,11 +1,11 @@
[gd_scene load_steps=14 format=3 uid="uid://cqy81q5p0tsda"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_3iw7y"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_3iw7y"]
[ext_resource type="PackedScene" uid="uid://bulsh7s0ibmao" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn" id="2_vcfky"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_4.4.gd" id="3_2idlr"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="3_65wck"]
+[ext_resource type="Script" uid="uid://dw1obe248t83j" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_4.4.gd" id="3_2idlr"]
+[ext_resource type="Script" uid="uid://bu76fr7072fv0" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="3_65wck"]
[ext_resource type="Resource" uid="uid://cptfoggk2ok67" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_3d_tween.tres" id="4_b0eay"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="5_i3ale"]
+[ext_resource type="Script" uid="uid://dscwf24xavqcu" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="5_i3ale"]
[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="6_5hq8j"]
[ext_resource type="Texture2D" uid="uid://c7ja4woxol8yc" path="res://addons/phantom_camera/examples/textures/3D/checker_pattern_dark.png" id="7_7lab4"]
diff --git a/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_path_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_path_example_scene.tscn
index fb8d086..3e67469 100644
--- a/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_path_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_path_example_scene.tscn
@@ -1,13 +1,13 @@
[gd_scene load_steps=25 format=3 uid="uid://oo1y1sjdmr6k"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_p8ccw"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_8itog"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_p8ccw"]
+[ext_resource type="Script" uid="uid://bu76fr7072fv0" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_8itog"]
[ext_resource type="Resource" uid="uid://cptfoggk2ok67" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_3d_tween.tres" id="3_xqpq0"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_akuuo"]
+[ext_resource type="Script" uid="uid://dscwf24xavqcu" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_akuuo"]
[ext_resource type="PackedScene" uid="uid://bulsh7s0ibmao" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn" id="5_0nadx"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_4.4.gd" id="6_7h7mx"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="6_mkxip"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/3D/path_follow.gd" id="7_g1m51"]
+[ext_resource type="Script" uid="uid://dw1obe248t83j" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_4.4.gd" id="6_7h7mx"]
+[ext_resource type="Script" uid="uid://ccfft4b8rwgbo" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="6_mkxip"]
+[ext_resource type="Script" uid="uid://dtpqxkvuimvfg" path="res://addons/phantom_camera/examples/scripts/3D/path_follow.gd" id="7_g1m51"]
[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="8_a1h2k"]
[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="9_rk5lh"]
diff --git a/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_simple_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_simple_example_scene.tscn
index 49ab893..ece1ce4 100644
--- a/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_simple_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_simple_example_scene.tscn
@@ -1,11 +1,11 @@
[gd_scene load_steps=12 format=3 uid="uid://c7uyfhhnrmkbx"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_gt67h"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_4ltlo"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="3_hldrt"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_pqibl"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_gt67h"]
+[ext_resource type="Script" uid="uid://bu76fr7072fv0" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_4ltlo"]
+[ext_resource type="Script" uid="uid://ccfft4b8rwgbo" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="3_hldrt"]
+[ext_resource type="Script" uid="uid://dscwf24xavqcu" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_pqibl"]
[ext_resource type="PackedScene" uid="uid://bulsh7s0ibmao" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn" id="5_o4k7v"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_4.4.gd" id="6_8yuc5"]
+[ext_resource type="Script" uid="uid://dw1obe248t83j" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_4.4.gd" id="6_8yuc5"]
[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="6_m6ich"]
[ext_resource type="Texture2D" uid="uid://c7ja4woxol8yc" path="res://addons/phantom_camera/examples/textures/3D/checker_pattern_dark.png" id="7_pagh0"]
diff --git a/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_third_person_attribtues_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_third_person_attribtues_example_scene.tscn
index 1a86f2e..91620f3 100644
--- a/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_third_person_attribtues_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_third_person_attribtues_example_scene.tscn
@@ -1,11 +1,11 @@
[gd_scene load_steps=22 format=3 uid="uid://bklrp02eywxsx"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="1_s26cy"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="2_m2d6w"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="3_l7kg8"]
+[ext_resource type="Script" uid="uid://bu76fr7072fv0" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="1_s26cy"]
+[ext_resource type="Script" uid="uid://ccfft4b8rwgbo" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="2_m2d6w"]
+[ext_resource type="Script" uid="uid://dscwf24xavqcu" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="3_l7kg8"]
[ext_resource type="PackedScene" uid="uid://mskcwn1a1v6d" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_third_person_3d.tscn" id="4_qcyfd"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="5_8von1"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_third_person_4.4.gd" id="5_tarnu"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="5_8von1"]
+[ext_resource type="Script" uid="uid://cd4an05w0gyce" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_third_person_4.4.gd" id="5_tarnu"]
[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="6_o1fj6"]
[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="7_amcmx"]
[ext_resource type="Texture2D" uid="uid://c3mskbmvnpwux" path="res://addons/phantom_camera/examples/textures/3D/target.png" id="8_rjcgw"]
diff --git a/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_third_person_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_third_person_example_scene.tscn
index 2df24a9..2717042 100644
--- a/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_third_person_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_third_person_example_scene.tscn
@@ -1,11 +1,11 @@
[gd_scene load_steps=17 format=3 uid="uid://ceelq6qrb41uf"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="2_47xf2"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_third_person_4.4.gd" id="2_uhq7m"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_whx47"]
+[ext_resource type="Script" uid="uid://ccfft4b8rwgbo" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="2_47xf2"]
+[ext_resource type="Script" uid="uid://cd4an05w0gyce" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_third_person_4.4.gd" id="2_uhq7m"]
+[ext_resource type="Script" uid="uid://bu76fr7072fv0" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_whx47"]
[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="4_lii5s"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="5_jt2lp"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="5_oc4q1"]
+[ext_resource type="Script" uid="uid://dscwf24xavqcu" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="5_jt2lp"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="5_oc4q1"]
[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="7_kg7u1"]
[ext_resource type="PackedScene" uid="uid://mskcwn1a1v6d" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_third_person_3d.tscn" id="7_kut0u"]
diff --git a/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_look_at_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_look_at_example_scene.tscn
index c85deb1..5aad419 100644
--- a/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_look_at_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_look_at_example_scene.tscn
@@ -1,11 +1,11 @@
[gd_scene load_steps=15 format=3 uid="uid://dsfixtpa5xwqt"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_jbmnd"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_t3gk2"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="3_b2lea"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_mqo2b"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_jbmnd"]
+[ext_resource type="Script" uid="uid://bu76fr7072fv0" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_t3gk2"]
+[ext_resource type="Script" uid="uid://ccfft4b8rwgbo" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="3_b2lea"]
+[ext_resource type="Script" uid="uid://dscwf24xavqcu" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_mqo2b"]
[ext_resource type="PackedScene" uid="uid://bulsh7s0ibmao" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn" id="5_pxkua"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_4.4.gd" id="6_3rtu0"]
+[ext_resource type="Script" uid="uid://dw1obe248t83j" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_4.4.gd" id="6_3rtu0"]
[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="6_uuxs3"]
[ext_resource type="Texture2D" uid="uid://c7ja4woxol8yc" path="res://addons/phantom_camera/examples/textures/3D/checker_pattern_dark.png" id="7_0dyt0"]
diff --git a/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_noise_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_noise_example_scene.tscn
index 1c7a8b7..b86c45c 100644
--- a/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_noise_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_noise_example_scene.tscn
@@ -1,12 +1,12 @@
[gd_scene load_steps=21 format=3 uid="uid://d0fyuvesb472p"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_25rmy"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_first_person_4.4.gd" id="2_7nd2u"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/phantom_camera_noise_3d.gd" id="3_t4fhv"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="4_tnm2f"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="5_4webr"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="6_dmm4a"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_noise_emitter_3d.gd" id="7_2vtho"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_25rmy"]
+[ext_resource type="Script" uid="uid://0tyckg8fqwn" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_first_person_4.4.gd" id="2_7nd2u"]
+[ext_resource type="Script" uid="uid://bbbhlv5mlpshy" path="res://addons/phantom_camera/scripts/resources/phantom_camera_noise_3d.gd" id="3_t4fhv"]
+[ext_resource type="Script" uid="uid://bu76fr7072fv0" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="4_tnm2f"]
+[ext_resource type="Script" uid="uid://ccfft4b8rwgbo" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="5_4webr"]
+[ext_resource type="Script" uid="uid://dscwf24xavqcu" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="6_dmm4a"]
+[ext_resource type="Script" uid="uid://dh4470fws0h8p" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_noise_emitter_3d.gd" id="7_2vtho"]
[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="8_bw5oq"]
[ext_resource type="Texture2D" uid="uid://c7ja4woxol8yc" path="res://addons/phantom_camera/examples/textures/3D/checker_pattern_dark.png" id="9_jpkpr"]
[ext_resource type="FontFile" uid="uid://dve7mgsjik4dg" path="res://addons/phantom_camera/fonts/Nunito-Regular.ttf" id="10_8pr3k"]
diff --git a/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_tweening_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_tweening_example_scene.tscn
index 76ee9a4..e91bfda 100644
--- a/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_tweening_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_tweening_example_scene.tscn
@@ -1,14 +1,14 @@
[gd_scene load_steps=23 format=3 uid="uid://cvnbgtbaxwj5p"]
[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="1_d55xf"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="2_d1opf"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="3_4whss"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="2_d1opf"]
+[ext_resource type="Script" uid="uid://bu76fr7072fv0" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="3_4whss"]
[ext_resource type="Resource" uid="uid://cptfoggk2ok67" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_3d_tween.tres" id="4_8ap1e"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="5_1sgnu"]
+[ext_resource type="Script" uid="uid://dscwf24xavqcu" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="5_1sgnu"]
[ext_resource type="PackedScene" uid="uid://bulsh7s0ibmao" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn" id="6_lr46m"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/3D/3d_trigger_area.gd" id="7_istoq"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_4.4.gd" id="7_x1jex"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="8_qepee"]
+[ext_resource type="Script" uid="uid://c3ghgg2gdidnj" path="res://addons/phantom_camera/examples/scripts/3D/3d_trigger_area.gd" id="7_istoq"]
+[ext_resource type="Script" uid="uid://dw1obe248t83j" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_4.4.gd" id="7_x1jex"]
+[ext_resource type="Script" uid="uid://ccfft4b8rwgbo" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="8_qepee"]
[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="9_ptb3h"]
[sub_resource type="Resource" id="Resource_0dtvs"]
diff --git a/addons/phantom_camera/examples/example_scenes/3D-4.4/sub_scenes/playable_character_3d.tscn b/addons/phantom_camera/examples/example_scenes/3D-4.4/sub_scenes/playable_character_3d.tscn
index 03bfcae..b0a9814 100644
--- a/addons/phantom_camera/examples/example_scenes/3D-4.4/sub_scenes/playable_character_3d.tscn
+++ b/addons/phantom_camera/examples/example_scenes/3D-4.4/sub_scenes/playable_character_3d.tscn
@@ -1,6 +1,6 @@
[gd_scene load_steps=5 format=3 uid="uid://cb83in8f0tbb1"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/3D/player_controller.gd" id="1_tm04f"]
+[ext_resource type="Script" uid="uid://c7wyr45opu0fp" path="res://addons/phantom_camera/examples/scripts/3D/player_controller.gd" id="1_tm04f"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_8efyg"]
diff --git a/addons/phantom_camera/examples/example_scenes/3D-4.4/sub_scenes/playable_character_third_person_3d.tscn b/addons/phantom_camera/examples/example_scenes/3D-4.4/sub_scenes/playable_character_third_person_3d.tscn
index 17bb808..7349671 100644
--- a/addons/phantom_camera/examples/example_scenes/3D-4.4/sub_scenes/playable_character_third_person_3d.tscn
+++ b/addons/phantom_camera/examples/example_scenes/3D-4.4/sub_scenes/playable_character_third_person_3d.tscn
@@ -1,6 +1,6 @@
[gd_scene load_steps=6 format=3 uid="uid://bhd1kwv2fwj1y"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_third_person.gd" id="1_5s24o"]
+[ext_resource type="Script" uid="uid://did833y3pchlm" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_third_person.gd" id="1_5s24o"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_s61dn"]
diff --git a/addons/phantom_camera/examples/example_scenes/3D/3d_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D/3d_example_scene.tscn
index 19c1c13..bd38cbf 100644
--- a/addons/phantom_camera/examples/example_scenes/3D/3d_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/3D/3d_example_scene.tscn
@@ -1,15 +1,15 @@
[gd_scene load_steps=40 format=3 uid="uid://ci12ytew5vwty"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_wn7ww"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/3D/npc.gd" id="2_2n1da"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_wn7ww"]
+[ext_resource type="Script" uid="uid://b7kjbvamap1u8" path="res://addons/phantom_camera/examples/scripts/3D/npc.gd" id="2_2n1da"]
[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="2_e7gxt"]
[ext_resource type="PackedScene" uid="uid://bulsh7s0ibmao" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn" id="2_tvx5n"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_y3dy8"]
+[ext_resource type="Script" uid="uid://bu76fr7072fv0" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_y3dy8"]
[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="3_f5qrw"]
[ext_resource type="Resource" uid="uid://cptfoggk2ok67" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_3d_tween.tres" id="4_a27nb"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_m2vbn"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/3D/3d_trigger_area.gd" id="4_moad5"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="7_jitt8"]
+[ext_resource type="Script" uid="uid://dscwf24xavqcu" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_m2vbn"]
+[ext_resource type="Script" uid="uid://c3ghgg2gdidnj" path="res://addons/phantom_camera/examples/scripts/3D/3d_trigger_area.gd" id="4_moad5"]
+[ext_resource type="Script" uid="uid://ccfft4b8rwgbo" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="7_jitt8"]
[sub_resource type="Resource" id="Resource_jtk1d"]
script = ExtResource("4_m2vbn")
diff --git a/addons/phantom_camera/examples/example_scenes/3D/3d_follow_framed_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D/3d_follow_framed_example_scene.tscn
index a14363a..442d911 100644
--- a/addons/phantom_camera/examples/example_scenes/3D/3d_follow_framed_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/3D/3d_follow_framed_example_scene.tscn
@@ -1,9 +1,9 @@
[gd_scene load_steps=10 format=3 uid="uid://c4llb3gsbfv1a"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_7824u"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_g1bv4"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_7824u"]
+[ext_resource type="Script" uid="uid://bu76fr7072fv0" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_g1bv4"]
[ext_resource type="Resource" uid="uid://cptfoggk2ok67" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_3d_tween.tres" id="3_420vh"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_oqbub"]
+[ext_resource type="Script" uid="uid://dscwf24xavqcu" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_oqbub"]
[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="4_t4fso"]
[ext_resource type="Texture2D" uid="uid://c7ja4woxol8yc" path="res://addons/phantom_camera/examples/textures/3D/checker_pattern_dark.png" id="5_c0upu"]
[ext_resource type="PackedScene" uid="uid://bulsh7s0ibmao" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn" id="5_f2w3x"]
diff --git a/addons/phantom_camera/examples/example_scenes/3D/3d_follow_glued_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D/3d_follow_glued_example_scene.tscn
index 10acd87..d617a36 100644
--- a/addons/phantom_camera/examples/example_scenes/3D/3d_follow_glued_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/3D/3d_follow_glued_example_scene.tscn
@@ -1,10 +1,10 @@
[gd_scene load_steps=14 format=3 uid="uid://dw2yflu7up2rr"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_pmeux"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_q1ygp"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="3_hpix1"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_pmeux"]
+[ext_resource type="Script" uid="uid://bu76fr7072fv0" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_q1ygp"]
+[ext_resource type="Script" uid="uid://ccfft4b8rwgbo" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="3_hpix1"]
[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="4_8qqha"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_evdoo"]
+[ext_resource type="Script" uid="uid://dscwf24xavqcu" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_evdoo"]
[ext_resource type="PackedScene" uid="uid://bulsh7s0ibmao" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn" id="5_vqgn5"]
[ext_resource type="Texture2D" uid="uid://c7ja4woxol8yc" path="res://addons/phantom_camera/examples/textures/3D/checker_pattern_dark.png" id="5_wr3bq"]
diff --git a/addons/phantom_camera/examples/example_scenes/3D/3d_follow_group_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D/3d_follow_group_example_scene.tscn
index 2c927d4..032e4f4 100644
--- a/addons/phantom_camera/examples/example_scenes/3D/3d_follow_group_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/3D/3d_follow_group_example_scene.tscn
@@ -1,12 +1,12 @@
[gd_scene load_steps=13 format=3 uid="uid://dbfiy6svpcqap"]
[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="1_r00ve"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_pi7mp"]
+[ext_resource type="Script" uid="uid://bu76fr7072fv0" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_pi7mp"]
[ext_resource type="PackedScene" uid="uid://bulsh7s0ibmao" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn" id="2_wnlkq"]
[ext_resource type="Resource" uid="uid://cptfoggk2ok67" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_3d_tween.tres" id="3_1eb12"]
[ext_resource type="Texture2D" uid="uid://c7ja4woxol8yc" path="res://addons/phantom_camera/examples/textures/3D/checker_pattern_dark.png" id="3_a5igg"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="3_wr1tj"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="5_70gws"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="3_wr1tj"]
+[ext_resource type="Script" uid="uid://dscwf24xavqcu" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="5_70gws"]
[sub_resource type="Resource" id="Resource_1iman"]
script = ExtResource("5_70gws")
diff --git a/addons/phantom_camera/examples/example_scenes/3D/3d_follow_path_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D/3d_follow_path_example_scene.tscn
index 9de651d..33a7383 100644
--- a/addons/phantom_camera/examples/example_scenes/3D/3d_follow_path_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/3D/3d_follow_path_example_scene.tscn
@@ -1,12 +1,12 @@
[gd_scene load_steps=24 format=3 uid="uid://dxx7ngi0emt8h"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_lm5n8"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="3_bd7x3"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_lm5n8"]
+[ext_resource type="Script" uid="uid://bu76fr7072fv0" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="3_bd7x3"]
[ext_resource type="Resource" uid="uid://cptfoggk2ok67" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_3d_tween.tres" id="3_od2r4"]
[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="4_dfdlo"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_hni7n"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="4_lfwkm"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/3D/path_follow.gd" id="5_vdqkm"]
+[ext_resource type="Script" uid="uid://dscwf24xavqcu" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_hni7n"]
+[ext_resource type="Script" uid="uid://ccfft4b8rwgbo" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="4_lfwkm"]
+[ext_resource type="Script" uid="uid://dtpqxkvuimvfg" path="res://addons/phantom_camera/examples/scripts/3D/path_follow.gd" id="5_vdqkm"]
[ext_resource type="PackedScene" uid="uid://bulsh7s0ibmao" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn" id="5_vms5c"]
[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="6_obo83"]
diff --git a/addons/phantom_camera/examples/example_scenes/3D/3d_follow_simple_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D/3d_follow_simple_example_scene.tscn
index 59247c9..cf52456 100644
--- a/addons/phantom_camera/examples/example_scenes/3D/3d_follow_simple_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/3D/3d_follow_simple_example_scene.tscn
@@ -1,10 +1,10 @@
[gd_scene load_steps=11 format=3 uid="uid://buglvjwpn85ny"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_3tok8"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_grjck"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="3_j3f4l"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_3tok8"]
+[ext_resource type="Script" uid="uid://bu76fr7072fv0" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_grjck"]
+[ext_resource type="Script" uid="uid://ccfft4b8rwgbo" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="3_j3f4l"]
[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="4_4u2y6"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_sielv"]
+[ext_resource type="Script" uid="uid://dscwf24xavqcu" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_sielv"]
[ext_resource type="Texture2D" uid="uid://c7ja4woxol8yc" path="res://addons/phantom_camera/examples/textures/3D/checker_pattern_dark.png" id="5_1tybo"]
[ext_resource type="PackedScene" uid="uid://bulsh7s0ibmao" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn" id="5_7ywxt"]
diff --git a/addons/phantom_camera/examples/example_scenes/3D/3d_follow_third_person_attribtues_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D/3d_follow_third_person_attribtues_example_scene.tscn
index 019328f..4298998 100644
--- a/addons/phantom_camera/examples/example_scenes/3D/3d_follow_third_person_attribtues_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/3D/3d_follow_third_person_attribtues_example_scene.tscn
@@ -1,10 +1,10 @@
[gd_scene load_steps=21 format=3 uid="uid://5pjtxclcnx4f"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="1_s26cy"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="2_m2d6w"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="3_l7kg8"]
+[ext_resource type="Script" uid="uid://bu76fr7072fv0" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="1_s26cy"]
+[ext_resource type="Script" uid="uid://ccfft4b8rwgbo" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="2_m2d6w"]
+[ext_resource type="Script" uid="uid://dscwf24xavqcu" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="3_l7kg8"]
[ext_resource type="PackedScene" uid="uid://mskcwn1a1v6d" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_third_person_3d.tscn" id="4_qcyfd"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="5_8von1"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="5_8von1"]
[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="6_o1fj6"]
[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="7_amcmx"]
[ext_resource type="Texture2D" uid="uid://c3mskbmvnpwux" path="res://addons/phantom_camera/examples/textures/3D/target.png" id="8_rjcgw"]
diff --git a/addons/phantom_camera/examples/example_scenes/3D/3d_follow_third_person_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D/3d_follow_third_person_example_scene.tscn
index d7fae5e..04baa66 100644
--- a/addons/phantom_camera/examples/example_scenes/3D/3d_follow_third_person_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/3D/3d_follow_third_person_example_scene.tscn
@@ -1,10 +1,10 @@
[gd_scene load_steps=16 format=3 uid="uid://4i5csj0s34nb"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="2_47xf2"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_whx47"]
+[ext_resource type="Script" uid="uid://ccfft4b8rwgbo" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="2_47xf2"]
+[ext_resource type="Script" uid="uid://bu76fr7072fv0" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_whx47"]
[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="4_lii5s"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="5_jt2lp"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="5_oc4q1"]
+[ext_resource type="Script" uid="uid://dscwf24xavqcu" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="5_jt2lp"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="5_oc4q1"]
[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="7_kg7u1"]
[ext_resource type="PackedScene" uid="uid://mskcwn1a1v6d" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_third_person_3d.tscn" id="7_kut0u"]
diff --git a/addons/phantom_camera/examples/example_scenes/3D/3d_look_at_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D/3d_look_at_example_scene.tscn
index cc5c045..bf9569a 100644
--- a/addons/phantom_camera/examples/example_scenes/3D/3d_look_at_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/3D/3d_look_at_example_scene.tscn
@@ -1,11 +1,11 @@
[gd_scene load_steps=14 format=3 uid="uid://bdhrdhbux7sjg"]
[ext_resource type="PackedScene" uid="uid://bulsh7s0ibmao" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn" id="1_i2pjc"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_lldvu"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_8md3q"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="3_dqss1"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_lldvu"]
+[ext_resource type="Script" uid="uid://bu76fr7072fv0" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_8md3q"]
+[ext_resource type="Script" uid="uid://ccfft4b8rwgbo" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="3_dqss1"]
[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="4_2i811"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_m3qpq"]
+[ext_resource type="Script" uid="uid://dscwf24xavqcu" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_m3qpq"]
[ext_resource type="Texture2D" uid="uid://c7ja4woxol8yc" path="res://addons/phantom_camera/examples/textures/3D/checker_pattern_dark.png" id="5_u5qhp"]
[sub_resource type="Resource" id="Resource_pwcgo"]
diff --git a/addons/phantom_camera/examples/example_scenes/3D/3d_noise_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D/3d_noise_example_scene.tscn
index 8a76989..5bb1b66 100644
--- a/addons/phantom_camera/examples/example_scenes/3D/3d_noise_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/3D/3d_noise_example_scene.tscn
@@ -1,13 +1,13 @@
[gd_scene load_steps=22 format=3 uid="uid://p7s5t3tthmo"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_ggfbg"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_dreow"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="3_f8fcw"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_mjtut"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/phantom_camera_noise_3d.gd" id="4_poyyk"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_ggfbg"]
+[ext_resource type="Script" uid="uid://bu76fr7072fv0" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_dreow"]
+[ext_resource type="Script" uid="uid://ccfft4b8rwgbo" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="3_f8fcw"]
+[ext_resource type="Script" uid="uid://dscwf24xavqcu" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_mjtut"]
+[ext_resource type="Script" uid="uid://bbbhlv5mlpshy" path="res://addons/phantom_camera/scripts/resources/phantom_camera_noise_3d.gd" id="4_poyyk"]
[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="5_d6uqs"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_first_person.gd" id="6_fbad7"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_noise_emitter_3d.gd" id="6_n8u0x"]
+[ext_resource type="Script" uid="uid://bcsse7njcempc" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_first_person.gd" id="6_fbad7"]
+[ext_resource type="Script" uid="uid://dh4470fws0h8p" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_noise_emitter_3d.gd" id="6_n8u0x"]
[ext_resource type="Texture2D" uid="uid://c7ja4woxol8yc" path="res://addons/phantom_camera/examples/textures/3D/checker_pattern_dark.png" id="6_vpla5"]
[ext_resource type="FontFile" uid="uid://dve7mgsjik4dg" path="res://addons/phantom_camera/fonts/Nunito-Regular.ttf" id="10_0thai"]
[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="11_i8r8q"]
diff --git a/addons/phantom_camera/examples/example_scenes/3D/3d_tweening_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D/3d_tweening_example_scene.tscn
index 44ac8b8..c147ebe 100644
--- a/addons/phantom_camera/examples/example_scenes/3D/3d_tweening_example_scene.tscn
+++ b/addons/phantom_camera/examples/example_scenes/3D/3d_tweening_example_scene.tscn
@@ -1,13 +1,13 @@
[gd_scene load_steps=22 format=3 uid="uid://5xtssqdfilal"]
[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="1_ydeog"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="2_b2yrt"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="3_m2w30"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="2_b2yrt"]
+[ext_resource type="Script" uid="uid://bu76fr7072fv0" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="3_m2w30"]
[ext_resource type="Resource" uid="uid://cptfoggk2ok67" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_3d_tween.tres" id="4_425ma"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="5_cn3g7"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/3D/3d_trigger_area.gd" id="5_h0ouh"]
+[ext_resource type="Script" uid="uid://dscwf24xavqcu" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="5_cn3g7"]
+[ext_resource type="Script" uid="uid://c3ghgg2gdidnj" path="res://addons/phantom_camera/examples/scripts/3D/3d_trigger_area.gd" id="5_h0ouh"]
[ext_resource type="PackedScene" uid="uid://bulsh7s0ibmao" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn" id="6_gcjyn"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="6_wup4d"]
+[ext_resource type="Script" uid="uid://ccfft4b8rwgbo" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="6_wup4d"]
[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="8_60rny"]
[sub_resource type="Resource" id="Resource_0dtvs"]
diff --git a/addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn b/addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn
index 2198ced..3fa6a2b 100644
--- a/addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn
+++ b/addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn
@@ -1,6 +1,6 @@
[gd_scene load_steps=5 format=3 uid="uid://bulsh7s0ibmao"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/3D/player_controller.gd" id="1_6hh6c"]
+[ext_resource type="Script" uid="uid://c7wyr45opu0fp" path="res://addons/phantom_camera/examples/scripts/3D/player_controller.gd" id="1_6hh6c"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_8efyg"]
diff --git a/addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_third_person_3d.tscn b/addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_third_person_3d.tscn
index ecfd6f9..ef09099 100644
--- a/addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_third_person_3d.tscn
+++ b/addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_third_person_3d.tscn
@@ -1,6 +1,6 @@
[gd_scene load_steps=6 format=3 uid="uid://mskcwn1a1v6d"]
-[ext_resource type="Script" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_third_person.gd" id="1_0dnfe"]
+[ext_resource type="Script" uid="uid://did833y3pchlm" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_third_person.gd" id="1_0dnfe"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_s61dn"]
diff --git a/addons/phantom_camera/examples/resources/tween/fixed_camera_tween.tres b/addons/phantom_camera/examples/resources/tween/fixed_camera_tween.tres
index 640b6ae..fc8caaa 100644
--- a/addons/phantom_camera/examples/resources/tween/fixed_camera_tween.tres
+++ b/addons/phantom_camera/examples/resources/tween/fixed_camera_tween.tres
@@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="PhantomCameraTween" load_steps=2 format=3 uid="uid://c1v786g5agaw5"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="1_ptlie"]
+[ext_resource type="Script" uid="uid://ccfft4b8rwgbo" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="1_ptlie"]
[resource]
script = ExtResource("1_ptlie")
diff --git a/addons/phantom_camera/examples/resources/tween/inventory_phantom_camera_2d_tween.tres b/addons/phantom_camera/examples/resources/tween/inventory_phantom_camera_2d_tween.tres
index 38d9879..4ab91b3 100644
--- a/addons/phantom_camera/examples/resources/tween/inventory_phantom_camera_2d_tween.tres
+++ b/addons/phantom_camera/examples/resources/tween/inventory_phantom_camera_2d_tween.tres
@@ -1,6 +1,6 @@
-[gd_resource type="Resource" script_class="PhantomCameraTweenResource" load_steps=2 format=3 uid="uid://cllveybboaqk5"]
+[gd_resource type="Resource" script_class="PhantomCameraTween" load_steps=2 format=3 uid="uid://cllveybboaqk5"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="1_7yoy0"]
+[ext_resource type="Script" uid="uid://ccfft4b8rwgbo" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="1_7yoy0"]
[resource]
script = ExtResource("1_7yoy0")
diff --git a/addons/phantom_camera/examples/resources/tween/item_focus_phantom_camera_2d_tween.tres b/addons/phantom_camera/examples/resources/tween/item_focus_phantom_camera_2d_tween.tres
index 3a09b1e..6d9e65d 100644
--- a/addons/phantom_camera/examples/resources/tween/item_focus_phantom_camera_2d_tween.tres
+++ b/addons/phantom_camera/examples/resources/tween/item_focus_phantom_camera_2d_tween.tres
@@ -1,6 +1,6 @@
-[gd_resource type="Resource" script_class="PhantomCameraTweenResource" load_steps=2 format=3 uid="uid://cecrnq0wnkexh"]
+[gd_resource type="Resource" script_class="PhantomCameraTween" load_steps=2 format=3 uid="uid://cecrnq0wnkexh"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="1_sq5ls"]
+[ext_resource type="Script" uid="uid://ccfft4b8rwgbo" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="1_sq5ls"]
[resource]
script = ExtResource("1_sq5ls")
diff --git a/addons/phantom_camera/examples/resources/tween/player_phantom_camera_2d_tween.tres b/addons/phantom_camera/examples/resources/tween/player_phantom_camera_2d_tween.tres
index e23bdbe..327af64 100644
--- a/addons/phantom_camera/examples/resources/tween/player_phantom_camera_2d_tween.tres
+++ b/addons/phantom_camera/examples/resources/tween/player_phantom_camera_2d_tween.tres
@@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="PhantomCameraTween" load_steps=2 format=3 uid="uid://euybd2w0bax"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="1_by4ei"]
+[ext_resource type="Script" uid="uid://ccfft4b8rwgbo" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="1_by4ei"]
[resource]
script = ExtResource("1_by4ei")
diff --git a/addons/phantom_camera/examples/resources/tween/player_phantom_camera_3d_tween.tres b/addons/phantom_camera/examples/resources/tween/player_phantom_camera_3d_tween.tres
index 7edea42..3c76909 100644
--- a/addons/phantom_camera/examples/resources/tween/player_phantom_camera_3d_tween.tres
+++ b/addons/phantom_camera/examples/resources/tween/player_phantom_camera_3d_tween.tres
@@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="PhantomCameraTween" load_steps=2 format=3 uid="uid://cptfoggk2ok67"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="1_q5tix"]
+[ext_resource type="Script" uid="uid://ccfft4b8rwgbo" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="1_q5tix"]
[resource]
script = ExtResource("1_q5tix")
diff --git a/addons/phantom_camera/examples/scripts/2D/2d_room_limit_tween.gd.uid b/addons/phantom_camera/examples/scripts/2D/2d_room_limit_tween.gd.uid
new file mode 100644
index 0000000..99cf3b5
--- /dev/null
+++ b/addons/phantom_camera/examples/scripts/2D/2d_room_limit_tween.gd.uid
@@ -0,0 +1 @@
+uid://cpxh0wtbnb3lg
diff --git a/addons/phantom_camera/examples/scripts/2D/2d_room_limit_tween_4.3.gd.uid b/addons/phantom_camera/examples/scripts/2D/2d_room_limit_tween_4.3.gd.uid
new file mode 100644
index 0000000..f02d5f0
--- /dev/null
+++ b/addons/phantom_camera/examples/scripts/2D/2d_room_limit_tween_4.3.gd.uid
@@ -0,0 +1 @@
+uid://b7wnot35mku6h
diff --git a/addons/phantom_camera/examples/scripts/2D/2d_trigger_area.gd.uid b/addons/phantom_camera/examples/scripts/2D/2d_trigger_area.gd.uid
new file mode 100644
index 0000000..b30c4e6
--- /dev/null
+++ b/addons/phantom_camera/examples/scripts/2D/2d_trigger_area.gd.uid
@@ -0,0 +1 @@
+uid://cjparvte7lvi4
diff --git a/addons/phantom_camera/examples/scripts/2D/player_character_body_2d.gd.uid b/addons/phantom_camera/examples/scripts/2D/player_character_body_2d.gd.uid
new file mode 100644
index 0000000..7e8dc1b
--- /dev/null
+++ b/addons/phantom_camera/examples/scripts/2D/player_character_body_2d.gd.uid
@@ -0,0 +1 @@
+uid://bxii6lssrm0pp
diff --git a/addons/phantom_camera/examples/scripts/2D/player_character_body_2d_4.3.gd.uid b/addons/phantom_camera/examples/scripts/2D/player_character_body_2d_4.3.gd.uid
new file mode 100644
index 0000000..1e8d40b
--- /dev/null
+++ b/addons/phantom_camera/examples/scripts/2D/player_character_body_2d_4.3.gd.uid
@@ -0,0 +1 @@
+uid://ci7lfaa7jvsu7
diff --git a/addons/phantom_camera/examples/scripts/3D/3d_trigger_area.gd.uid b/addons/phantom_camera/examples/scripts/3D/3d_trigger_area.gd.uid
new file mode 100644
index 0000000..ebab34f
--- /dev/null
+++ b/addons/phantom_camera/examples/scripts/3D/3d_trigger_area.gd.uid
@@ -0,0 +1 @@
+uid://c3ghgg2gdidnj
diff --git a/addons/phantom_camera/examples/scripts/3D/npc.gd.uid b/addons/phantom_camera/examples/scripts/3D/npc.gd.uid
new file mode 100644
index 0000000..6468275
--- /dev/null
+++ b/addons/phantom_camera/examples/scripts/3D/npc.gd.uid
@@ -0,0 +1 @@
+uid://b7kjbvamap1u8
diff --git a/addons/phantom_camera/examples/scripts/3D/path_follow.gd.uid b/addons/phantom_camera/examples/scripts/3D/path_follow.gd.uid
new file mode 100644
index 0000000..35c74b5
--- /dev/null
+++ b/addons/phantom_camera/examples/scripts/3D/path_follow.gd.uid
@@ -0,0 +1 @@
+uid://dtpqxkvuimvfg
diff --git a/addons/phantom_camera/examples/scripts/3D/player_controller.gd.uid b/addons/phantom_camera/examples/scripts/3D/player_controller.gd.uid
new file mode 100644
index 0000000..8f7e48d
--- /dev/null
+++ b/addons/phantom_camera/examples/scripts/3D/player_controller.gd.uid
@@ -0,0 +1 @@
+uid://c7wyr45opu0fp
diff --git a/addons/phantom_camera/examples/scripts/3D/player_controller_4.4.gd.uid b/addons/phantom_camera/examples/scripts/3D/player_controller_4.4.gd.uid
new file mode 100644
index 0000000..32b243d
--- /dev/null
+++ b/addons/phantom_camera/examples/scripts/3D/player_controller_4.4.gd.uid
@@ -0,0 +1 @@
+uid://dw1obe248t83j
diff --git a/addons/phantom_camera/examples/scripts/3D/player_controller_first_person.gd.uid b/addons/phantom_camera/examples/scripts/3D/player_controller_first_person.gd.uid
new file mode 100644
index 0000000..489945d
--- /dev/null
+++ b/addons/phantom_camera/examples/scripts/3D/player_controller_first_person.gd.uid
@@ -0,0 +1 @@
+uid://bcsse7njcempc
diff --git a/addons/phantom_camera/examples/scripts/3D/player_controller_first_person_4.4.gd.uid b/addons/phantom_camera/examples/scripts/3D/player_controller_first_person_4.4.gd.uid
new file mode 100644
index 0000000..a53b0a9
--- /dev/null
+++ b/addons/phantom_camera/examples/scripts/3D/player_controller_first_person_4.4.gd.uid
@@ -0,0 +1 @@
+uid://0tyckg8fqwn
diff --git a/addons/phantom_camera/examples/scripts/3D/player_controller_third_person.gd.uid b/addons/phantom_camera/examples/scripts/3D/player_controller_third_person.gd.uid
new file mode 100644
index 0000000..8a7be3b
--- /dev/null
+++ b/addons/phantom_camera/examples/scripts/3D/player_controller_third_person.gd.uid
@@ -0,0 +1 @@
+uid://did833y3pchlm
diff --git a/addons/phantom_camera/examples/scripts/3D/player_controller_third_person_4.4.gd.uid b/addons/phantom_camera/examples/scripts/3D/player_controller_third_person_4.4.gd.uid
new file mode 100644
index 0000000..0646b2d
--- /dev/null
+++ b/addons/phantom_camera/examples/scripts/3D/player_controller_third_person_4.4.gd.uid
@@ -0,0 +1 @@
+uid://cd4an05w0gyce
diff --git a/addons/phantom_camera/fonts/Nunito-Black.ttf.import b/addons/phantom_camera/fonts/Nunito-Black.ttf.import
index ac96a49..8e68c5f 100644
--- a/addons/phantom_camera/fonts/Nunito-Black.ttf.import
+++ b/addons/phantom_camera/fonts/Nunito-Black.ttf.import
@@ -23,6 +23,7 @@ allow_system_fallback=true
force_autohinter=false
hinting=1
subpixel_positioning=1
+keep_rounding_remainders=true
oversampling=0.0
Fallbacks=null
fallbacks=[]
diff --git a/addons/phantom_camera/fonts/Nunito-Regular.ttf.import b/addons/phantom_camera/fonts/Nunito-Regular.ttf.import
index 393153f..11c0c62 100644
--- a/addons/phantom_camera/fonts/Nunito-Regular.ttf.import
+++ b/addons/phantom_camera/fonts/Nunito-Regular.ttf.import
@@ -23,6 +23,7 @@ allow_system_fallback=true
force_autohinter=false
hinting=1
subpixel_positioning=1
+keep_rounding_remainders=true
oversampling=0.0
Fallbacks=null
fallbacks=[]
diff --git a/addons/phantom_camera/gizmos/custom_gizmo.gd.uid b/addons/phantom_camera/gizmos/custom_gizmo.gd.uid
new file mode 100644
index 0000000..178242c
--- /dev/null
+++ b/addons/phantom_camera/gizmos/custom_gizmo.gd.uid
@@ -0,0 +1 @@
+uid://c3psnjq6uaui6
diff --git a/addons/phantom_camera/gizmos/phantom_camera_gizmo_plugin_3d.gd.uid b/addons/phantom_camera/gizmos/phantom_camera_gizmo_plugin_3d.gd.uid
new file mode 100644
index 0000000..3c6b287
--- /dev/null
+++ b/addons/phantom_camera/gizmos/phantom_camera_gizmo_plugin_3d.gd.uid
@@ -0,0 +1 @@
+uid://5ixfa2ouhy1u
diff --git a/addons/phantom_camera/gizmos/phantom_camera_noise_emitter_gizmo_plugin_3d.gd.uid b/addons/phantom_camera/gizmos/phantom_camera_noise_emitter_gizmo_plugin_3d.gd.uid
new file mode 100644
index 0000000..f5534b5
--- /dev/null
+++ b/addons/phantom_camera/gizmos/phantom_camera_noise_emitter_gizmo_plugin_3d.gd.uid
@@ -0,0 +1 @@
+uid://bjtgfeb5gv2am
diff --git a/addons/phantom_camera/inspector/phantom_camera_inspector_plugin.gd.uid b/addons/phantom_camera/inspector/phantom_camera_inspector_plugin.gd.uid
new file mode 100644
index 0000000..daa9762
--- /dev/null
+++ b/addons/phantom_camera/inspector/phantom_camera_inspector_plugin.gd.uid
@@ -0,0 +1 @@
+uid://feyqmc38mhq0
diff --git a/addons/phantom_camera/panel/editor.gd.uid b/addons/phantom_camera/panel/editor.gd.uid
new file mode 100644
index 0000000..e64183e
--- /dev/null
+++ b/addons/phantom_camera/panel/editor.gd.uid
@@ -0,0 +1 @@
+uid://bvcvl44yjbm58
diff --git a/addons/phantom_camera/panel/editor.tscn b/addons/phantom_camera/panel/editor.tscn
index da1574c..7f90937 100644
--- a/addons/phantom_camera/panel/editor.tscn
+++ b/addons/phantom_camera/panel/editor.tscn
@@ -1,6 +1,6 @@
[gd_scene load_steps=4 format=3 uid="uid://cfdoaceoosi1w"]
-[ext_resource type="Script" path="res://addons/phantom_camera/panel/editor.gd" id="1_86hp7"]
+[ext_resource type="Script" uid="uid://bvcvl44yjbm58" path="res://addons/phantom_camera/panel/editor.gd" id="1_86hp7"]
[ext_resource type="PackedScene" uid="uid://cuqkqsp3ikv5u" path="res://addons/phantom_camera/panel/updater/update_button.tscn" id="1_oowcd"]
[ext_resource type="PackedScene" uid="uid://dbkr3d716wtx0" path="res://addons/phantom_camera/panel/viewfinder/viewfinder_panel.tscn" id="2_xecnk"]
diff --git a/addons/phantom_camera/panel/updater/download_update_panel.tscn b/addons/phantom_camera/panel/updater/download_update_panel.tscn
index 240ed5f..b0342d0 100644
--- a/addons/phantom_camera/panel/updater/download_update_panel.tscn
+++ b/addons/phantom_camera/panel/updater/download_update_panel.tscn
@@ -1,6 +1,6 @@
[gd_scene load_steps=15 format=3 uid="uid://b25fl4usw0nlp"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/panel/updater/download_update_panel.gd" id="1_sx5xq"]
+[ext_resource type="Script" uid="uid://2lrk72t3ej7b" path="res://addons/phantom_camera/scripts/panel/updater/download_update_panel.gd" id="1_sx5xq"]
[ext_resource type="Texture2D" uid="uid://cc0wmici0eic8" path="res://addons/phantom_camera/icons/phantom_camera_logo.png" id="2_f3yo7"]
[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="3_h8uk3"]
[ext_resource type="FontFile" uid="uid://dve7mgsjik4dg" path="res://addons/phantom_camera/fonts/Nunito-Regular.ttf" id="4_gwh4i"]
diff --git a/addons/phantom_camera/panel/updater/update_button.tscn b/addons/phantom_camera/panel/updater/update_button.tscn
index 00c80de..a732c7e 100644
--- a/addons/phantom_camera/panel/updater/update_button.tscn
+++ b/addons/phantom_camera/panel/updater/update_button.tscn
@@ -1,7 +1,7 @@
[gd_scene load_steps=10 format=3 uid="uid://cuqkqsp3ikv5u"]
[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="1_5e5k4"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/panel/updater/update_button.gd" id="1_xtaw5"]
+[ext_resource type="Script" uid="uid://dfjiugcxau5lh" path="res://addons/phantom_camera/scripts/panel/updater/update_button.gd" id="1_xtaw5"]
[ext_resource type="Texture2D" uid="uid://d4j4hrb7yusyq" path="res://addons/phantom_camera/icons/phantom_camera_updater_panel_icon.svg" id="2_c4d83"]
[ext_resource type="PackedScene" uid="uid://b25fl4usw0nlp" path="res://addons/phantom_camera/panel/updater/download_update_panel.tscn" id="2_vtgcx"]
diff --git a/addons/phantom_camera/panel/viewfinder/viewfinder_panel.tscn b/addons/phantom_camera/panel/viewfinder/viewfinder_panel.tscn
index c4769e6..4493f5a 100644
--- a/addons/phantom_camera/panel/viewfinder/viewfinder_panel.tscn
+++ b/addons/phantom_camera/panel/viewfinder/viewfinder_panel.tscn
@@ -1,6 +1,6 @@
[gd_scene load_steps=22 format=3 uid="uid://dbkr3d716wtx0"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/panel/viewfinder/viewfinder.gd" id="1_utvi8"]
+[ext_resource type="Script" uid="uid://c0kcljp4dn1r8" path="res://addons/phantom_camera/scripts/panel/viewfinder/viewfinder.gd" id="1_utvi8"]
[ext_resource type="StyleBox" uid="uid://dpa7yvxlq043a" path="res://addons/phantom_camera/panel/viewfinder/deadzone_style_box.tres" id="2_uabt4"]
[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="3_li3i3"]
[ext_resource type="Texture2D" uid="uid://5fatldiu7dd5" path="res://addons/phantom_camera/icons/phantom_camera_host.svg" id="4_lcg1p"]
diff --git a/addons/phantom_camera/plugin.gd.uid b/addons/phantom_camera/plugin.gd.uid
new file mode 100644
index 0000000..50766ee
--- /dev/null
+++ b/addons/phantom_camera/plugin.gd.uid
@@ -0,0 +1 @@
+uid://d0d8dkrojlljk
diff --git a/addons/phantom_camera/scripts/managers/phantom_camera_manager.gd.uid b/addons/phantom_camera/scripts/managers/phantom_camera_manager.gd.uid
new file mode 100644
index 0000000..108d774
--- /dev/null
+++ b/addons/phantom_camera/scripts/managers/phantom_camera_manager.gd.uid
@@ -0,0 +1 @@
+uid://chalnjy12ql1q
diff --git a/addons/phantom_camera/scripts/panel/updater/download_update_panel.gd.uid b/addons/phantom_camera/scripts/panel/updater/download_update_panel.gd.uid
new file mode 100644
index 0000000..ad0fac8
--- /dev/null
+++ b/addons/phantom_camera/scripts/panel/updater/download_update_panel.gd.uid
@@ -0,0 +1 @@
+uid://2lrk72t3ej7b
diff --git a/addons/phantom_camera/scripts/panel/updater/update_button.gd.uid b/addons/phantom_camera/scripts/panel/updater/update_button.gd.uid
new file mode 100644
index 0000000..df7e090
--- /dev/null
+++ b/addons/phantom_camera/scripts/panel/updater/update_button.gd.uid
@@ -0,0 +1 @@
+uid://dfjiugcxau5lh
diff --git a/addons/phantom_camera/scripts/panel/updater/updater_constants.gd.uid b/addons/phantom_camera/scripts/panel/updater/updater_constants.gd.uid
new file mode 100644
index 0000000..3e6b43f
--- /dev/null
+++ b/addons/phantom_camera/scripts/panel/updater/updater_constants.gd.uid
@@ -0,0 +1 @@
+uid://mksojbjyv7t5
diff --git a/addons/phantom_camera/scripts/panel/viewfinder/viewfinder.gd.uid b/addons/phantom_camera/scripts/panel/viewfinder/viewfinder.gd.uid
new file mode 100644
index 0000000..5cc2e3a
--- /dev/null
+++ b/addons/phantom_camera/scripts/panel/viewfinder/viewfinder.gd.uid
@@ -0,0 +1 @@
+uid://c0kcljp4dn1r8
diff --git a/addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd.uid b/addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd.uid
new file mode 100644
index 0000000..4438672
--- /dev/null
+++ b/addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd.uid
@@ -0,0 +1 @@
+uid://d23haq52m7ulv
diff --git a/addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd.uid b/addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd.uid
new file mode 100644
index 0000000..8eca1d7
--- /dev/null
+++ b/addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd.uid
@@ -0,0 +1 @@
+uid://bu76fr7072fv0
diff --git a/addons/phantom_camera/scripts/phantom_camera/phantom_camera_constants.gd.uid b/addons/phantom_camera/scripts/phantom_camera/phantom_camera_constants.gd.uid
new file mode 100644
index 0000000..591a9ae
--- /dev/null
+++ b/addons/phantom_camera/scripts/phantom_camera/phantom_camera_constants.gd.uid
@@ -0,0 +1 @@
+uid://cxrfvpik1807h
diff --git a/addons/phantom_camera/scripts/phantom_camera/phantom_camera_noise_emitter_2d.gd.uid b/addons/phantom_camera/scripts/phantom_camera/phantom_camera_noise_emitter_2d.gd.uid
new file mode 100644
index 0000000..1b4105d
--- /dev/null
+++ b/addons/phantom_camera/scripts/phantom_camera/phantom_camera_noise_emitter_2d.gd.uid
@@ -0,0 +1 @@
+uid://bskijkg6twd3h
diff --git a/addons/phantom_camera/scripts/phantom_camera/phantom_camera_noise_emitter_3d.gd.uid b/addons/phantom_camera/scripts/phantom_camera/phantom_camera_noise_emitter_3d.gd.uid
new file mode 100644
index 0000000..4df4a15
--- /dev/null
+++ b/addons/phantom_camera/scripts/phantom_camera/phantom_camera_noise_emitter_3d.gd.uid
@@ -0,0 +1 @@
+uid://dh4470fws0h8p
diff --git a/addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd.uid b/addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd.uid
new file mode 100644
index 0000000..f6ab6cd
--- /dev/null
+++ b/addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd.uid
@@ -0,0 +1 @@
+uid://cie33tct7ehf0
diff --git a/addons/phantom_camera/scripts/resources/camera_3d_resource.gd.uid b/addons/phantom_camera/scripts/resources/camera_3d_resource.gd.uid
new file mode 100644
index 0000000..0f0336e
--- /dev/null
+++ b/addons/phantom_camera/scripts/resources/camera_3d_resource.gd.uid
@@ -0,0 +1 @@
+uid://dscwf24xavqcu
diff --git a/addons/phantom_camera/scripts/resources/phantom_camera_noise_2d.gd.uid b/addons/phantom_camera/scripts/resources/phantom_camera_noise_2d.gd.uid
new file mode 100644
index 0000000..050b82e
--- /dev/null
+++ b/addons/phantom_camera/scripts/resources/phantom_camera_noise_2d.gd.uid
@@ -0,0 +1 @@
+uid://daroioflx7bt1
diff --git a/addons/phantom_camera/scripts/resources/phantom_camera_noise_3d.gd.uid b/addons/phantom_camera/scripts/resources/phantom_camera_noise_3d.gd.uid
new file mode 100644
index 0000000..406b13a
--- /dev/null
+++ b/addons/phantom_camera/scripts/resources/phantom_camera_noise_3d.gd.uid
@@ -0,0 +1 @@
+uid://bbbhlv5mlpshy
diff --git a/addons/phantom_camera/scripts/resources/tween_resource.gd.uid b/addons/phantom_camera/scripts/resources/tween_resource.gd.uid
new file mode 100644
index 0000000..944b97e
--- /dev/null
+++ b/addons/phantom_camera/scripts/resources/tween_resource.gd.uid
@@ -0,0 +1 @@
+uid://ccfft4b8rwgbo
diff --git a/addons/rmsmartshape/actions/action.gd b/addons/rmsmartshape/actions/action.gd
deleted file mode 100644
index 5125edc..0000000
--- a/addons/rmsmartshape/actions/action.gd
+++ /dev/null
@@ -1,23 +0,0 @@
-class_name SS2D_Action
-extends RefCounted
-
-## Base class for all plugin actions.
-##
-## UndoRedo system will call [method do] and [method undo].
-
-# @virtual
-## Returns string to be used as a name in editor History tab.
-func get_name() -> String:
- return "UntitledAction"
-
-
-# @virtual
-## Do action here.
-func do() -> void:
- pass
-
-
-# @virtual
-## Undo action here.
-func undo() -> void:
- pass
diff --git a/addons/rmsmartshape/actions/action_add_collision_nodes.gd b/addons/rmsmartshape/actions/action_add_collision_nodes.gd
deleted file mode 100644
index 648f67d..0000000
--- a/addons/rmsmartshape/actions/action_add_collision_nodes.gd
+++ /dev/null
@@ -1,56 +0,0 @@
-extends SS2D_Action
-
-## ActionAddCollisionNodes
-
-var _shape: SS2D_Shape
-
-var _saved_index: int
-var _saved_pos: Vector2
-
-
-func _init(shape: SS2D_Shape) -> void:
- _shape = shape
-
-
-func get_name() -> String:
- return "Add Collision Nodes"
-
-
-func do() -> void:
- _saved_index = _shape.get_index()
- _saved_pos = _shape.position
-
- var owner := _shape.owner
- var static_body := StaticBody2D.new()
- static_body.position = _shape.position
- _shape.position = Vector2.ZERO
-
- _shape.get_parent().add_child(static_body, true)
- static_body.owner = owner
-
- _shape.get_parent().remove_child(_shape)
- static_body.add_child(_shape, true)
- _shape.owner = owner
-
- var poly: CollisionPolygon2D = CollisionPolygon2D.new()
- static_body.add_child(poly, true)
- poly.owner = owner
- # TODO: Make this a option at some point
- poly.modulate.a = 0.3
- poly.visible = false
- _shape.collision_polygon_node_path = _shape.get_path_to(poly)
-
-
-func undo() -> void:
- var owner := _shape.owner
- var parent := _shape.get_parent()
- var grandparent := _shape.get_parent().get_parent()
- parent.remove_child(_shape)
- grandparent.remove_child(parent)
- parent.free()
-
- grandparent.add_child(_shape)
- _shape.owner = owner
- grandparent.move_child(_shape, _saved_index)
- _shape.position = _saved_pos
-
diff --git a/addons/rmsmartshape/actions/action_add_point.gd b/addons/rmsmartshape/actions/action_add_point.gd
deleted file mode 100644
index 017eadc..0000000
--- a/addons/rmsmartshape/actions/action_add_point.gd
+++ /dev/null
@@ -1,44 +0,0 @@
-extends SS2D_Action
-
-## ActionAddPoint
-
-const ActionInvertOrientation := preload("res://addons/rmsmartshape/actions/action_invert_orientation.gd")
-var _invert_orientation: ActionInvertOrientation
-
-var _commit_update: bool
-var _shape: SS2D_Shape
-var _key: int
-var _position: Vector2
-var _idx: int
-
-
-func _init(shape: SS2D_Shape, position: Vector2, idx: int = -1, commit_update: bool = true) -> void:
- _shape = shape
- _position = position
- _commit_update = commit_update
- _idx = _shape.adjust_add_point_index(idx)
- _key = _shape.reserve_key()
- _invert_orientation = ActionInvertOrientation.new(shape)
-
-
-func get_name() -> String:
- return "Add Point at (%d, %d)" % [_position.x, _position.y]
-
-
-func do() -> void:
- _shape.begin_update()
- _key = _shape.add_point(_position, _idx, _key)
- _invert_orientation.do()
- if _commit_update:
- _shape.end_update()
-
-
-func undo() -> void:
- _shape.begin_update()
- _invert_orientation.undo()
- _shape.remove_point(_key)
- _shape.end_update()
-
-
-func get_key() -> int:
- return _key
diff --git a/addons/rmsmartshape/actions/action_close_shape.gd b/addons/rmsmartshape/actions/action_close_shape.gd
deleted file mode 100644
index d935209..0000000
--- a/addons/rmsmartshape/actions/action_close_shape.gd
+++ /dev/null
@@ -1,40 +0,0 @@
-extends SS2D_Action
-
-## ActionCloseShape
-
-const ActionInvertOrientation := preload("res://addons/rmsmartshape/actions/action_invert_orientation.gd")
-var _invert_orientation: ActionInvertOrientation
-
-var _shape: SS2D_Shape
-var _key: int
-var _performed: bool
-
-
-func _init(shape: SS2D_Shape) -> void:
- _shape = shape
- _invert_orientation = ActionInvertOrientation.new(shape)
-
-
-func get_name() -> String:
- return "Close Shape"
-
-
-func do() -> void:
- _performed = _shape.can_close()
- if _performed:
- _shape.begin_update()
- _key = _shape.close_shape(_key)
- _invert_orientation.do()
- _shape.end_update()
-
-
-func undo() -> void:
- if _performed:
- _shape.begin_update()
- _invert_orientation.undo()
- _shape.remove_point(_key)
- _shape.end_update()
-
-
-func get_key() -> int:
- return _key
diff --git a/addons/rmsmartshape/actions/action_cut_edge.gd b/addons/rmsmartshape/actions/action_cut_edge.gd
deleted file mode 100644
index 5fc3f65..0000000
--- a/addons/rmsmartshape/actions/action_cut_edge.gd
+++ /dev/null
@@ -1,41 +0,0 @@
-extends SS2D_Action
-
-## ActionCutEdge
-##
-## A delegate action that selects an action to perform based on the edge
-## location and shape state.
-
-var ActionOpenShape := preload("res://addons/rmsmartshape/actions/action_open_shape.gd")
-var ActionDeletePoint := preload("res://addons/rmsmartshape/actions/action_delete_point.gd")
-var ActionSplitShape := preload("res://addons/rmsmartshape/actions/action_split_shape.gd")
-
-var _shape: SS2D_Shape
-var _action: SS2D_Action
-
-
-func _init(shape: SS2D_Shape, key_edge_start: int, key_edge_end: int) -> void:
- _shape = shape
-
- var key_first: int = shape.get_point_key_at_index(0)
- var key_last: int = shape.get_point_key_at_index(shape.get_point_count()-1)
- if _shape.is_shape_closed():
- _action = ActionOpenShape.new(shape, key_edge_start)
- elif key_edge_start == key_first:
- _action = ActionDeletePoint.new(shape, key_edge_start)
- elif key_edge_end == key_last:
- _action = ActionDeletePoint.new(shape, key_edge_end)
- else:
- _action = ActionSplitShape.new(shape, key_edge_start)
-
-
-func get_name() -> String:
- return _action.get_name()
-
-
-func do() -> void:
- _action.do()
-
-
-func undo() -> void:
- _action.undo()
-
diff --git a/addons/rmsmartshape/actions/action_delete_control_point.gd b/addons/rmsmartshape/actions/action_delete_control_point.gd
deleted file mode 100644
index 56a2bdc..0000000
--- a/addons/rmsmartshape/actions/action_delete_control_point.gd
+++ /dev/null
@@ -1,45 +0,0 @@
-extends SS2D_Action
-
-## ActionDeleteControlPoint
-
-enum PointType {POINT_IN, POINT_OUT}
-
-const ActionInvertOrientation := preload("res://addons/rmsmartshape/actions/action_invert_orientation.gd")
-var _invert_orientation: ActionInvertOrientation
-
-var _shape: SS2D_Shape
-var _key: int
-var _point_type: PointType
-var _old_value: Vector2
-
-
-func _init(shape: SS2D_Shape, key: int, point_type: PointType) -> void:
- _shape = shape
- _key = key
- _point_type = point_type
- _old_value = shape.get_point_in(key) if _point_type == PointType.POINT_IN else shape.get_point_out(key)
- _invert_orientation = ActionInvertOrientation.new(shape)
-
-
-func get_name() -> String:
- return "Delete Control Point " + ("In" if _point_type == PointType.POINT_IN else "Out")
-
-
-func do() -> void:
- _shape.begin_update()
- if _point_type == PointType.POINT_IN:
- _shape.set_point_in(_key, Vector2.ZERO)
- else:
- _shape.set_point_out(_key, Vector2.ZERO)
- _invert_orientation.do()
- _shape.end_update()
-
-
-func undo() -> void:
- _shape.begin_update()
- _invert_orientation.undo()
- if _point_type == PointType.POINT_IN:
- _shape.set_point_in(_key, _old_value)
- else:
- _shape.set_point_out(_key, _old_value)
- _shape.end_update()
diff --git a/addons/rmsmartshape/actions/action_delete_point.gd b/addons/rmsmartshape/actions/action_delete_point.gd
deleted file mode 100644
index ad63e85..0000000
--- a/addons/rmsmartshape/actions/action_delete_point.gd
+++ /dev/null
@@ -1,13 +0,0 @@
-extends "res://addons/rmsmartshape/actions/action_delete_points.gd"
-
-## ActionDeletePoint
-
-
-func _init(shape: SS2D_Shape, key: int, commit_update: bool = true) -> void:
- var keys: PackedInt32Array = [key]
- super(shape, keys, commit_update)
-
-
-func get_name() -> String:
- var pos := _shape.get_point_position(_keys[0])
- return "Delete Point at (%d, %d)" % [pos.x, pos.y]
diff --git a/addons/rmsmartshape/actions/action_delete_points.gd b/addons/rmsmartshape/actions/action_delete_points.gd
deleted file mode 100644
index 60ec5ba..0000000
--- a/addons/rmsmartshape/actions/action_delete_points.gd
+++ /dev/null
@@ -1,88 +0,0 @@
-extends SS2D_Action
-
-## ActionDeletePoints
-
-const TUP := preload("res://addons/rmsmartshape/lib/tuple.gd")
-
-const ActionInvertOrientation := preload("res://addons/rmsmartshape/actions/action_invert_orientation.gd")
-var _invert_orientation: ActionInvertOrientation
-
-const ActionCloseShape := preload("res://addons/rmsmartshape/actions/action_close_shape.gd")
-var _close_shape: ActionCloseShape
-
-var _shape: SS2D_Shape
-var _keys: PackedInt32Array
-var _indicies: PackedInt32Array
-var _positions: PackedVector2Array
-var _points_in: PackedVector2Array
-var _points_out: PackedVector2Array
-var _properties: Array[SS2D_VertexProperties]
-var _constraints: Array[Dictionary]
-var _was_closed: bool
-var _commit_update: bool
-
-
-func _init(shape: SS2D_Shape, keys: PackedInt32Array, commit_update: bool = true) -> void:
- _shape = shape
- _invert_orientation = ActionInvertOrientation.new(shape)
- _close_shape = ActionCloseShape.new(shape)
- _commit_update = commit_update
-
- for k in keys:
- add_point_to_delete(k)
-
-
-func get_name() -> String:
- return "Delete Points %s" % [_keys]
-
-
-func do() -> void:
- _shape.begin_update()
- _was_closed = _shape.is_shape_closed()
- var first_run := _positions.size() == 0
- for k in _keys:
- if first_run:
- _indicies.append(_shape.get_point_index(k))
- _positions.append(_shape.get_point_position(k))
- _points_in.append(_shape.get_point_in(k))
- _points_out.append(_shape.get_point_out(k))
- _properties.append(_shape.get_point_properties(k))
- _shape.remove_point(k)
- if _was_closed:
- _close_shape.do()
- _invert_orientation.do()
- if _commit_update:
- _shape.end_update()
-
-
-func undo() -> void:
- _shape.begin_update()
- _invert_orientation.undo()
- if _was_closed:
- _close_shape.undo()
- for i in range(_keys.size()-1, -1, -1):
- _shape.add_point(_positions[i], _indicies[i], _keys[i])
- _shape.set_point_in(_keys[i], _points_in[i])
- _shape.set_point_out(_keys[i], _points_out[i])
- _shape.set_point_properties(_keys[i], _properties[i])
- # Restore point constraints.
- for i in range(_keys.size()-1, -1, -1):
- for tuple: Vector2i in _constraints[i]:
- _shape.set_constraint(tuple[0], tuple[1], _constraints[i][tuple])
- _shape.end_update()
-
-
-func add_point_to_delete(key: int) -> void:
- _keys.push_back(key)
- var constraints := _shape.get_point_array().get_point_constraints(key)
- # Save point constraints.
- _constraints.append(constraints)
-
- for tuple: Vector2i in constraints:
- var constraint: SS2D_Point_Array.CONSTRAINT = constraints[tuple]
- if constraint == SS2D_Point_Array.CONSTRAINT.NONE:
- continue
- var key_other := SS2D_IndexTuple.get_other_value(tuple, key)
- if constraint & SS2D_Point_Array.CONSTRAINT.ALL:
- if not _keys.has(key_other):
- add_point_to_delete(key_other)
diff --git a/addons/rmsmartshape/actions/action_invert_orientation.gd b/addons/rmsmartshape/actions/action_invert_orientation.gd
deleted file mode 100644
index 0f41504..0000000
--- a/addons/rmsmartshape/actions/action_invert_orientation.gd
+++ /dev/null
@@ -1,33 +0,0 @@
-extends SS2D_Action
-
-## ActionInvertOrientation
-
-var _shape: SS2D_Shape
-var _performed: bool
-
-
-func _init(shape: SS2D_Shape) -> void:
- _shape = shape
-
-
-func get_name() -> String:
- return "Invert Orientation"
-
-
-func do() -> void:
- _performed = should_invert_orientation(_shape)
- if _performed:
- _shape.invert_point_order()
-
-
-func undo() -> void:
- if _performed:
- _shape.invert_point_order()
-
-
-func should_invert_orientation(s: SS2D_Shape) -> bool:
- if s == null:
- return false
- if not s.is_shape_closed():
- return false
- return not s.are_points_clockwise() and s.get_point_count() >= 3
diff --git a/addons/rmsmartshape/actions/action_make_shape_unique.gd b/addons/rmsmartshape/actions/action_make_shape_unique.gd
deleted file mode 100644
index 28a064a..0000000
--- a/addons/rmsmartshape/actions/action_make_shape_unique.gd
+++ /dev/null
@@ -1,26 +0,0 @@
-extends SS2D_Action
-
-## ActionMakeShapeUnique
-
-var _shape: SS2D_Shape
-var _old_array: SS2D_Point_Array
-var _new_array: SS2D_Point_Array
-
-
-func _init(shape: SS2D_Shape) -> void:
- _shape = shape
- _old_array = shape.get_point_array()
- _new_array = _shape.get_point_array().clone(true)
-
-
-func get_name() -> String:
- return "Make Shape Unique"
-
-
-func do() -> void:
- _shape.set_point_array(_new_array)
-
-
-func undo() -> void:
- _shape.set_point_array(_old_array)
-
diff --git a/addons/rmsmartshape/actions/action_move_control_points.gd b/addons/rmsmartshape/actions/action_move_control_points.gd
deleted file mode 100644
index 5af9e67..0000000
--- a/addons/rmsmartshape/actions/action_move_control_points.gd
+++ /dev/null
@@ -1,43 +0,0 @@
-extends SS2D_Action
-
-## ActionMoveControlPoints
-
-var _shape: SS2D_Shape
-var _keys: PackedInt32Array
-var _old_points_in: PackedVector2Array
-var _old_points_out: PackedVector2Array
-var _new_points_in: PackedVector2Array
-var _new_points_out: PackedVector2Array
-
-
-func _init(s: SS2D_Shape, keys: PackedInt32Array,
- old_points_in: PackedVector2Array, old_points_out: PackedVector2Array) -> void:
- _shape = s
- _keys = keys
- _old_points_in = old_points_in
- _old_points_out = old_points_out
- for key in _keys:
- _new_points_in.append(_shape.get_point_in(key))
- _new_points_out.append(_shape.get_point_out(key))
-
-
-func get_name() -> String:
- return "Move Control Point"
-
-
-func do() -> void:
- _assign_points_in_out(_keys, _new_points_in, _new_points_out)
-
-
-func undo() -> void:
- _assign_points_in_out(_keys, _old_points_in, _old_points_out)
-
-
-func _assign_points_in_out(keys: PackedInt32Array, in_positions: PackedVector2Array, out_positions: PackedVector2Array) -> void:
- _shape.begin_update()
- for i in keys.size():
- if _shape.get_point_in(keys[i]) != in_positions[i]:
- _shape.set_point_in(keys[i], in_positions[i])
- if _shape.get_point_out(keys[i]) != out_positions[i]:
- _shape.set_point_out(keys[i], out_positions[i])
- _shape.end_update()
diff --git a/addons/rmsmartshape/actions/action_move_verticies.gd b/addons/rmsmartshape/actions/action_move_verticies.gd
deleted file mode 100644
index f8d4a47..0000000
--- a/addons/rmsmartshape/actions/action_move_verticies.gd
+++ /dev/null
@@ -1,44 +0,0 @@
-extends SS2D_Action
-
-## ActionMoveVerticies
-
-const ActionInvertOrientation := preload("res://addons/rmsmartshape/actions/action_invert_orientation.gd")
-var _invert_orientation: ActionInvertOrientation
-
-var _shape: SS2D_Shape
-var _keys: PackedInt32Array
-var _old_positions: PackedVector2Array
-var _new_positions: PackedVector2Array
-
-
-func _init(s: SS2D_Shape, keys: PackedInt32Array, old_positions: PackedVector2Array) -> void:
- _shape = s
- _keys = keys.duplicate()
- _old_positions = old_positions.duplicate()
- _new_positions = PackedVector2Array()
- for k in _keys:
- _new_positions.append(_shape.get_point_position(k))
- _invert_orientation = ActionInvertOrientation.new(_shape)
-
-
-func get_name() -> String:
- if _keys.size() == 1:
- return "Move Vertex to (%d, %d)" % [_new_positions[0].x, _new_positions[0].y]
- else:
- return "Move Verticies"
-
-
-func do() -> void:
- _shape.begin_update()
- for i in _keys.size():
- _shape.set_point_position(_keys[i], _new_positions[i])
- _invert_orientation.do()
- _shape.end_update()
-
-
-func undo() -> void:
- _shape.begin_update()
- _invert_orientation.undo()
- for i in range(_keys.size() - 1, -1, -1):
- _shape.set_point_position(_keys[i], _old_positions[i])
- _shape.end_update()
diff --git a/addons/rmsmartshape/actions/action_open_shape.gd b/addons/rmsmartshape/actions/action_open_shape.gd
deleted file mode 100644
index adbbb1f..0000000
--- a/addons/rmsmartshape/actions/action_open_shape.gd
+++ /dev/null
@@ -1,31 +0,0 @@
-extends SS2D_Action
-
-## ActionOpenShape
-
-var _shape: SS2D_Shape
-var _cut_idx: int
-var _closing_key: int
-
-
-func _init(shape: SS2D_Shape, edge_start_key: int) -> void:
- _shape = shape
- _cut_idx = shape.get_point_index(edge_start_key)
-
-
-func get_name() -> String:
- return "Open Shape"
-
-
-func do() -> void:
- _shape.begin_update()
- var last_idx: int = _shape.get_point_count() - 1
- _closing_key = _shape.get_point_key_at_index(last_idx)
- _shape.open_shape_at_edge(_cut_idx)
- _shape.end_update()
-
-
-func undo() -> void:
- _shape.begin_update()
- _shape.undo_open_shape_at_edge(_cut_idx, _closing_key)
- _shape.end_update()
-
diff --git a/addons/rmsmartshape/actions/action_set_pivot.gd b/addons/rmsmartshape/actions/action_set_pivot.gd
deleted file mode 100644
index 6157337..0000000
--- a/addons/rmsmartshape/actions/action_set_pivot.gd
+++ /dev/null
@@ -1,44 +0,0 @@
-extends SS2D_Action
-
-## ActionSetPivot
-
-var _shape: SS2D_Shape
-
-var _new_pos: Vector2
-var _old_pos: Vector2
-
-
-func _init(s: SS2D_Shape, pos: Vector2) -> void:
- _shape = s
- _new_pos = pos
- _old_pos = _shape.global_position
-
-
-func get_name() -> String:
- return "Set Pivot"
-
-
-func do() -> void:
- _set_pivot(_new_pos)
-
-
-func undo() -> void:
- _set_pivot(_old_pos)
-
-
-func _set_pivot(shape_position: Vector2) -> void:
- var shape_gt: Transform2D = _shape.get_global_transform()
-
- _shape.global_position = shape_position
-
- _shape.begin_update()
- _shape.disable_constraints()
-
- for i in _shape.get_point_count():
- var key: int = _shape.get_point_key_at_index(i)
- var point: Vector2 = _shape.get_point_position(key)
- _shape.set_point_position(key, _shape.to_local(shape_gt * point))
-
- _shape.enable_constraints()
- _shape.end_update()
-
diff --git a/addons/rmsmartshape/actions/action_split_curve.gd b/addons/rmsmartshape/actions/action_split_curve.gd
deleted file mode 100644
index a4ca489..0000000
--- a/addons/rmsmartshape/actions/action_split_curve.gd
+++ /dev/null
@@ -1,10 +0,0 @@
-extends "res://addons/rmsmartshape/actions/action_add_point.gd"
-
-## ActionSplitCurve
-
-func _init(shape: SS2D_Shape, idx: int, gpoint: Vector2, xform: Transform2D, commit_update: bool = true) -> void:
- super._init(shape, xform.affine_inverse() * gpoint, idx, commit_update)
-
-
-func get_name() -> String:
- return "Split Curve at (%d, %d)" % [_position.x, _position.y]
diff --git a/addons/rmsmartshape/actions/action_split_shape.gd b/addons/rmsmartshape/actions/action_split_shape.gd
deleted file mode 100644
index 8fb2a28..0000000
--- a/addons/rmsmartshape/actions/action_split_shape.gd
+++ /dev/null
@@ -1,74 +0,0 @@
-extends SS2D_Action
-
-## ActionSplitShape
-##
-## How it's done:
-## 1. First, the shape is copied and added to the scene tree.
-## 2. Then, points of the splitted shape are deleted from first point to split point.
-## 3. Finally, points of the original shape are deleted from the point after split point to last point.
-
-const ActionDeletePoints := preload("res://addons/rmsmartshape/actions/action_delete_points.gd")
-var _delete_points_from_original: ActionDeletePoints
-
-var _shape: SS2D_Shape
-var _splitted: SS2D_Shape
-var _splitted_collision: CollisionPolygon2D
-var _split_idx: int
-
-
-func _init(shape: SS2D_Shape, split_point_key: int) -> void:
- assert(shape.is_shape_closed() == false)
- _shape = shape
- _split_idx = shape.get_point_index(split_point_key)
- _splitted = null
- _splitted_collision = null
- _delete_points_from_original = null
-
-
-func get_name() -> String:
- return "Split Shape"
-
-
-func do() -> void:
- if not is_instance_valid(_splitted):
- _splitted = _shape.clone()
- _splitted.begin_update()
- for i in range(0, _split_idx + 1):
- _splitted.remove_point_at_index(0)
- _splitted.end_update()
- _shape.get_parent().add_child(_splitted, true)
- _splitted.set_owner(_shape.get_tree().get_edited_scene_root())
- # Add a collision shape node if the original shape has one.
- if (not _shape.collision_polygon_node_path.is_empty() and _shape.has_node(_shape.collision_polygon_node_path)):
- var collision_polygon_original := _shape.get_node(_shape.collision_polygon_node_path) as CollisionPolygon2D
- if not is_instance_valid(_splitted_collision):
- _splitted_collision = CollisionPolygon2D.new()
- _splitted_collision.visible = collision_polygon_original.visible
- _splitted_collision.modulate = collision_polygon_original.modulate
- collision_polygon_original.get_parent().add_child(_splitted_collision, true)
- _splitted_collision.set_owner(collision_polygon_original.get_tree().get_edited_scene_root())
- _splitted.collision_polygon_node_path = _splitted.get_path_to(_splitted_collision)
-
- if _delete_points_from_original == null:
- var delete_keys := PackedInt32Array()
- for i in range(_shape.get_point_count() - 1, _split_idx, -1):
- delete_keys.append(_shape.get_point_key_at_index(i))
- _delete_points_from_original = ActionDeletePoints.new(_shape, delete_keys)
- _delete_points_from_original.do()
-
-
-func undo() -> void:
- _splitted.set_owner(null)
- _splitted.get_parent().remove_child(_splitted)
- if is_instance_valid(_splitted_collision):
- _splitted_collision.set_owner(null)
- _splitted_collision.get_parent().remove_child(_splitted_collision)
- _delete_points_from_original.undo()
-
-
-func _notification(what: int) -> void:
- if what == NOTIFICATION_PREDELETE:
- if is_instance_valid(_splitted) and _splitted.get_parent() == null:
- _splitted.queue_free()
- if is_instance_valid(_splitted_collision) and _splitted_collision.get_parent() == null:
- _splitted_collision.queue_free()
diff --git a/addons/rmsmartshape/asset_library_icon-new.png b/addons/rmsmartshape/asset_library_icon-new.png
deleted file mode 100644
index 44db166..0000000
Binary files a/addons/rmsmartshape/asset_library_icon-new.png and /dev/null differ
diff --git a/addons/rmsmartshape/asset_library_icon-new.png.import b/addons/rmsmartshape/asset_library_icon-new.png.import
deleted file mode 100644
index 554070c..0000000
--- a/addons/rmsmartshape/asset_library_icon-new.png.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://5wllxq74p8kq"
-path="res://.godot/imported/asset_library_icon-new.png-60877ecd9837f02c48423d4ec08e9284.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://addons/rmsmartshape/asset_library_icon-new.png"
-dest_files=["res://.godot/imported/asset_library_icon-new.png-60877ecd9837f02c48423d4ec08e9284.ctex"]
-
-[params]
-
-compress/mode=0
-compress/high_quality=false
-compress/lossy_quality=0.7
-compress/hdr_compression=1
-compress/normal_map=0
-compress/channel_pack=0
-mipmaps/generate=false
-mipmaps/limit=-1
-roughness/mode=0
-roughness/src_normal=""
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/normal_map_invert_y=false
-process/hdr_as_srgb=false
-process/hdr_clamp_exposure=false
-process/size_limit=0
-detect_3d/compress_to=1
diff --git a/addons/rmsmartshape/asset_library_icon.png b/addons/rmsmartshape/asset_library_icon.png
deleted file mode 100644
index 1ff18e6..0000000
Binary files a/addons/rmsmartshape/asset_library_icon.png and /dev/null differ
diff --git a/addons/rmsmartshape/asset_library_icon.png.import b/addons/rmsmartshape/asset_library_icon.png.import
deleted file mode 100644
index 6d146eb..0000000
--- a/addons/rmsmartshape/asset_library_icon.png.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://cbde02owb6iuu"
-path="res://.godot/imported/asset_library_icon.png-57d4f9e357cb3293fe7f718c0ef3633c.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://addons/rmsmartshape/asset_library_icon.png"
-dest_files=["res://.godot/imported/asset_library_icon.png-57d4f9e357cb3293fe7f718c0ef3633c.ctex"]
-
-[params]
-
-compress/mode=0
-compress/high_quality=false
-compress/lossy_quality=0.7
-compress/hdr_compression=1
-compress/normal_map=0
-compress/channel_pack=0
-mipmaps/generate=false
-mipmaps/limit=-1
-roughness/mode=0
-roughness/src_normal=""
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/normal_map_invert_y=false
-process/hdr_as_srgb=false
-process/hdr_clamp_exposure=false
-process/size_limit=0
-detect_3d/compress_to=1
diff --git a/addons/rmsmartshape/assets/Anchor.svg b/addons/rmsmartshape/assets/Anchor.svg
deleted file mode 100644
index a9caae0..0000000
--- a/addons/rmsmartshape/assets/Anchor.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-
diff --git a/addons/rmsmartshape/assets/Anchor.svg.import b/addons/rmsmartshape/assets/Anchor.svg.import
deleted file mode 100644
index 57a43f2..0000000
--- a/addons/rmsmartshape/assets/Anchor.svg.import
+++ /dev/null
@@ -1,37 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://b2h8c634u1120"
-path="res://.godot/imported/Anchor.svg-1c23ca67e353b480fc5d8186bb0064b9.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://addons/rmsmartshape/assets/Anchor.svg"
-dest_files=["res://.godot/imported/Anchor.svg-1c23ca67e353b480fc5d8186bb0064b9.ctex"]
-
-[params]
-
-compress/mode=0
-compress/high_quality=false
-compress/lossy_quality=0.7
-compress/hdr_compression=1
-compress/normal_map=0
-compress/channel_pack=0
-mipmaps/generate=false
-mipmaps/limit=-1
-roughness/mode=0
-roughness/src_normal=""
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/normal_map_invert_y=false
-process/hdr_as_srgb=false
-process/hdr_clamp_exposure=false
-process/size_limit=0
-detect_3d/compress_to=1
-svg/scale=1.0
-editor/scale_with_editor_scale=false
-editor/convert_colors_with_editor_theme=false
diff --git a/addons/rmsmartshape/assets/CenterView.svg b/addons/rmsmartshape/assets/CenterView.svg
deleted file mode 100644
index dc4052f..0000000
--- a/addons/rmsmartshape/assets/CenterView.svg
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/addons/rmsmartshape/assets/CenterView.svg.import b/addons/rmsmartshape/assets/CenterView.svg.import
deleted file mode 100644
index 41a9077..0000000
--- a/addons/rmsmartshape/assets/CenterView.svg.import
+++ /dev/null
@@ -1,37 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://byx10wt6pl1vo"
-path="res://.godot/imported/CenterView.svg-f5e9c7178a59ab586ba9d8fac61799bc.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://addons/rmsmartshape/assets/CenterView.svg"
-dest_files=["res://.godot/imported/CenterView.svg-f5e9c7178a59ab586ba9d8fac61799bc.ctex"]
-
-[params]
-
-compress/mode=0
-compress/high_quality=false
-compress/lossy_quality=0.7
-compress/hdr_compression=1
-compress/normal_map=0
-compress/channel_pack=0
-mipmaps/generate=false
-mipmaps/limit=-1
-roughness/mode=0
-roughness/src_normal=""
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/normal_map_invert_y=false
-process/hdr_as_srgb=false
-process/hdr_clamp_exposure=false
-process/size_limit=0
-detect_3d/compress_to=1
-svg/scale=1.0
-editor/scale_with_editor_scale=false
-editor/convert_colors_with_editor_theme=false
diff --git a/addons/rmsmartshape/assets/InterpLinear.svg b/addons/rmsmartshape/assets/InterpLinear.svg
deleted file mode 100644
index 241a82f..0000000
--- a/addons/rmsmartshape/assets/InterpLinear.svg
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/addons/rmsmartshape/assets/InterpLinear.svg.import b/addons/rmsmartshape/assets/InterpLinear.svg.import
deleted file mode 100644
index c2dc335..0000000
--- a/addons/rmsmartshape/assets/InterpLinear.svg.import
+++ /dev/null
@@ -1,37 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://umo7sgb6w70s"
-path="res://.godot/imported/InterpLinear.svg-c9d61ab817f2809471482a31f06cda10.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://addons/rmsmartshape/assets/InterpLinear.svg"
-dest_files=["res://.godot/imported/InterpLinear.svg-c9d61ab817f2809471482a31f06cda10.ctex"]
-
-[params]
-
-compress/mode=0
-compress/high_quality=false
-compress/lossy_quality=0.7
-compress/hdr_compression=1
-compress/normal_map=0
-compress/channel_pack=0
-mipmaps/generate=false
-mipmaps/limit=-1
-roughness/mode=0
-roughness/src_normal=""
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/normal_map_invert_y=false
-process/hdr_as_srgb=false
-process/hdr_clamp_exposure=false
-process/size_limit=0
-detect_3d/compress_to=1
-svg/scale=1.0
-editor/scale_with_editor_scale=false
-editor/convert_colors_with_editor_theme=false
diff --git a/addons/rmsmartshape/assets/SourceCodeVariable-Roman.ttf b/addons/rmsmartshape/assets/SourceCodeVariable-Roman.ttf
deleted file mode 100644
index 42e619f..0000000
Binary files a/addons/rmsmartshape/assets/SourceCodeVariable-Roman.ttf and /dev/null differ
diff --git a/addons/rmsmartshape/assets/SourceCodeVariable-Roman.ttf.import b/addons/rmsmartshape/assets/SourceCodeVariable-Roman.ttf.import
deleted file mode 100644
index 0b511de..0000000
--- a/addons/rmsmartshape/assets/SourceCodeVariable-Roman.ttf.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="font_data_dynamic"
-type="FontFile"
-uid="uid://cjgo8gf0cp441"
-path="res://.godot/imported/SourceCodeVariable-Roman.ttf-cb1e4f55679e973e90075716efcdf601.fontdata"
-
-[deps]
-
-source_file="res://addons/rmsmartshape/assets/SourceCodeVariable-Roman.ttf"
-dest_files=["res://.godot/imported/SourceCodeVariable-Roman.ttf-cb1e4f55679e973e90075716efcdf601.fontdata"]
-
-[params]
-
-Rendering=null
-antialiasing=1
-generate_mipmaps=false
-disable_embedded_bitmaps=true
-multichannel_signed_distance_field=false
-msdf_pixel_range=8
-msdf_size=48
-allow_system_fallback=true
-force_autohinter=false
-hinting=1
-subpixel_positioning=1
-oversampling=0.0
-Fallbacks=null
-fallbacks=[]
-Compress=null
-compress=true
-preload=[]
-language_support={}
-script_support={}
-opentype_features={}
diff --git a/addons/rmsmartshape/assets/closed_shape.png b/addons/rmsmartshape/assets/closed_shape.png
deleted file mode 100644
index e2834e3..0000000
Binary files a/addons/rmsmartshape/assets/closed_shape.png and /dev/null differ
diff --git a/addons/rmsmartshape/assets/closed_shape.png.import b/addons/rmsmartshape/assets/closed_shape.png.import
deleted file mode 100644
index dbc0499..0000000
--- a/addons/rmsmartshape/assets/closed_shape.png.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://8r4xp6j0ro3y"
-path="res://.godot/imported/closed_shape.png-c1d349f5c2caecc40ec65e52f86a8145.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://addons/rmsmartshape/assets/closed_shape.png"
-dest_files=["res://.godot/imported/closed_shape.png-c1d349f5c2caecc40ec65e52f86a8145.ctex"]
-
-[params]
-
-compress/mode=0
-compress/high_quality=false
-compress/lossy_quality=0.7
-compress/hdr_compression=1
-compress/normal_map=0
-compress/channel_pack=0
-mipmaps/generate=false
-mipmaps/limit=-1
-roughness/mode=0
-roughness/src_normal=""
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/normal_map_invert_y=false
-process/hdr_as_srgb=false
-process/hdr_clamp_exposure=false
-process/size_limit=0
-detect_3d/compress_to=1
diff --git a/addons/rmsmartshape/assets/freehand.png b/addons/rmsmartshape/assets/freehand.png
deleted file mode 100644
index ee1125a..0000000
Binary files a/addons/rmsmartshape/assets/freehand.png and /dev/null differ
diff --git a/addons/rmsmartshape/assets/freehand.png.import b/addons/rmsmartshape/assets/freehand.png.import
deleted file mode 100644
index 85093e0..0000000
--- a/addons/rmsmartshape/assets/freehand.png.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://bjbq000i2n7qd"
-path="res://.godot/imported/freehand.png-de4c7fa877a42fa4776ee9cd166cdabd.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://addons/rmsmartshape/assets/freehand.png"
-dest_files=["res://.godot/imported/freehand.png-de4c7fa877a42fa4776ee9cd166cdabd.ctex"]
-
-[params]
-
-compress/mode=0
-compress/high_quality=false
-compress/lossy_quality=0.7
-compress/hdr_compression=1
-compress/normal_map=0
-compress/channel_pack=0
-mipmaps/generate=false
-mipmaps/limit=-1
-roughness/mode=0
-roughness/src_normal=""
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/normal_map_invert_y=false
-process/hdr_as_srgb=false
-process/hdr_clamp_exposure=false
-process/size_limit=0
-detect_3d/compress_to=1
diff --git a/addons/rmsmartshape/assets/gui_theme.res b/addons/rmsmartshape/assets/gui_theme.res
deleted file mode 100644
index 55d0270..0000000
Binary files a/addons/rmsmartshape/assets/gui_theme.res and /dev/null differ
diff --git a/addons/rmsmartshape/assets/icon.png b/addons/rmsmartshape/assets/icon.png
deleted file mode 100644
index a9d3337..0000000
Binary files a/addons/rmsmartshape/assets/icon.png and /dev/null differ
diff --git a/addons/rmsmartshape/assets/icon.png.import b/addons/rmsmartshape/assets/icon.png.import
deleted file mode 100644
index 2f57b16..0000000
--- a/addons/rmsmartshape/assets/icon.png.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://h0jpajdrldwm"
-path="res://.godot/imported/icon.png-cf4ff9c0f4595c1f390bb463008250b4.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://addons/rmsmartshape/assets/icon.png"
-dest_files=["res://.godot/imported/icon.png-cf4ff9c0f4595c1f390bb463008250b4.ctex"]
-
-[params]
-
-compress/mode=0
-compress/high_quality=false
-compress/lossy_quality=0.7
-compress/hdr_compression=1
-compress/normal_map=0
-compress/channel_pack=0
-mipmaps/generate=false
-mipmaps/limit=-1
-roughness/mode=0
-roughness/src_normal=""
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/normal_map_invert_y=false
-process/hdr_as_srgb=false
-process/hdr_clamp_exposure=false
-process/size_limit=0
-detect_3d/compress_to=1
diff --git a/addons/rmsmartshape/assets/icon_collision_polygon_2d.svg b/addons/rmsmartshape/assets/icon_collision_polygon_2d.svg
deleted file mode 100644
index 9d90a66..0000000
--- a/addons/rmsmartshape/assets/icon_collision_polygon_2d.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-
diff --git a/addons/rmsmartshape/assets/icon_collision_polygon_2d.svg.import b/addons/rmsmartshape/assets/icon_collision_polygon_2d.svg.import
deleted file mode 100644
index 25f570c..0000000
--- a/addons/rmsmartshape/assets/icon_collision_polygon_2d.svg.import
+++ /dev/null
@@ -1,37 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://c3n1j5ybtgjit"
-path="res://.godot/imported/icon_collision_polygon_2d.svg-d52c533e615c0baed724848cec175fe6.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://addons/rmsmartshape/assets/icon_collision_polygon_2d.svg"
-dest_files=["res://.godot/imported/icon_collision_polygon_2d.svg-d52c533e615c0baed724848cec175fe6.ctex"]
-
-[params]
-
-compress/mode=0
-compress/high_quality=false
-compress/lossy_quality=0.7
-compress/hdr_compression=1
-compress/normal_map=0
-compress/channel_pack=0
-mipmaps/generate=false
-mipmaps/limit=-1
-roughness/mode=0
-roughness/src_normal=""
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/normal_map_invert_y=false
-process/hdr_as_srgb=false
-process/hdr_clamp_exposure=false
-process/size_limit=0
-detect_3d/compress_to=1
-svg/scale=1.0
-editor/scale_with_editor_scale=false
-editor/convert_colors_with_editor_theme=false
diff --git a/addons/rmsmartshape/assets/icon_curve_create.svg b/addons/rmsmartshape/assets/icon_curve_create.svg
deleted file mode 100644
index 1181111..0000000
--- a/addons/rmsmartshape/assets/icon_curve_create.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-
diff --git a/addons/rmsmartshape/assets/icon_curve_create.svg.import b/addons/rmsmartshape/assets/icon_curve_create.svg.import
deleted file mode 100644
index eb6db2b..0000000
--- a/addons/rmsmartshape/assets/icon_curve_create.svg.import
+++ /dev/null
@@ -1,37 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://qf0hmmvirgbn"
-path="res://.godot/imported/icon_curve_create.svg-24c8317cfb8ced81d4c832ca7b3310d5.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://addons/rmsmartshape/assets/icon_curve_create.svg"
-dest_files=["res://.godot/imported/icon_curve_create.svg-24c8317cfb8ced81d4c832ca7b3310d5.ctex"]
-
-[params]
-
-compress/mode=0
-compress/high_quality=false
-compress/lossy_quality=0.7
-compress/hdr_compression=1
-compress/normal_map=0
-compress/channel_pack=0
-mipmaps/generate=false
-mipmaps/limit=-1
-roughness/mode=0
-roughness/src_normal=""
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/normal_map_invert_y=false
-process/hdr_as_srgb=false
-process/hdr_clamp_exposure=false
-process/size_limit=0
-detect_3d/compress_to=1
-svg/scale=1.0
-editor/scale_with_editor_scale=false
-editor/convert_colors_with_editor_theme=false
diff --git a/addons/rmsmartshape/assets/icon_curve_delete.svg b/addons/rmsmartshape/assets/icon_curve_delete.svg
deleted file mode 100644
index 901a08e..0000000
--- a/addons/rmsmartshape/assets/icon_curve_delete.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-
diff --git a/addons/rmsmartshape/assets/icon_curve_delete.svg.import b/addons/rmsmartshape/assets/icon_curve_delete.svg.import
deleted file mode 100644
index 9577201..0000000
--- a/addons/rmsmartshape/assets/icon_curve_delete.svg.import
+++ /dev/null
@@ -1,37 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://ce2cbowctirhc"
-path="res://.godot/imported/icon_curve_delete.svg-9121c11be9a22040b2d567743d44ead0.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://addons/rmsmartshape/assets/icon_curve_delete.svg"
-dest_files=["res://.godot/imported/icon_curve_delete.svg-9121c11be9a22040b2d567743d44ead0.ctex"]
-
-[params]
-
-compress/mode=0
-compress/high_quality=false
-compress/lossy_quality=0.7
-compress/hdr_compression=1
-compress/normal_map=0
-compress/channel_pack=0
-mipmaps/generate=false
-mipmaps/limit=-1
-roughness/mode=0
-roughness/src_normal=""
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/normal_map_invert_y=false
-process/hdr_as_srgb=false
-process/hdr_clamp_exposure=false
-process/size_limit=0
-detect_3d/compress_to=1
-svg/scale=1.0
-editor/scale_with_editor_scale=false
-editor/convert_colors_with_editor_theme=false
diff --git a/addons/rmsmartshape/assets/icon_curve_edit.svg b/addons/rmsmartshape/assets/icon_curve_edit.svg
deleted file mode 100644
index 8f09ca6..0000000
--- a/addons/rmsmartshape/assets/icon_curve_edit.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-
diff --git a/addons/rmsmartshape/assets/icon_curve_edit.svg.import b/addons/rmsmartshape/assets/icon_curve_edit.svg.import
deleted file mode 100644
index 639cb49..0000000
--- a/addons/rmsmartshape/assets/icon_curve_edit.svg.import
+++ /dev/null
@@ -1,37 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://crjuwuq4vp15w"
-path="res://.godot/imported/icon_curve_edit.svg-bd7d5e1af7c72f4525dff1d79ad0af94.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://addons/rmsmartshape/assets/icon_curve_edit.svg"
-dest_files=["res://.godot/imported/icon_curve_edit.svg-bd7d5e1af7c72f4525dff1d79ad0af94.ctex"]
-
-[params]
-
-compress/mode=0
-compress/high_quality=false
-compress/lossy_quality=0.7
-compress/hdr_compression=1
-compress/normal_map=0
-compress/channel_pack=0
-mipmaps/generate=false
-mipmaps/limit=-1
-roughness/mode=0
-roughness/src_normal=""
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/normal_map_invert_y=false
-process/hdr_as_srgb=false
-process/hdr_clamp_exposure=false
-process/size_limit=0
-detect_3d/compress_to=1
-svg/scale=1.0
-editor/scale_with_editor_scale=false
-editor/convert_colors_with_editor_theme=false
diff --git a/addons/rmsmartshape/assets/icon_editor_freehand.svg b/addons/rmsmartshape/assets/icon_editor_freehand.svg
deleted file mode 100644
index d354946..0000000
--- a/addons/rmsmartshape/assets/icon_editor_freehand.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
diff --git a/addons/rmsmartshape/assets/icon_editor_freehand.svg.import b/addons/rmsmartshape/assets/icon_editor_freehand.svg.import
deleted file mode 100644
index eda11a4..0000000
--- a/addons/rmsmartshape/assets/icon_editor_freehand.svg.import
+++ /dev/null
@@ -1,37 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://da64iqyjipw4f"
-path="res://.godot/imported/icon_editor_freehand.svg-4eb5cac550480a5ffb50b9c62fba3af1.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://addons/rmsmartshape/assets/icon_editor_freehand.svg"
-dest_files=["res://.godot/imported/icon_editor_freehand.svg-4eb5cac550480a5ffb50b9c62fba3af1.ctex"]
-
-[params]
-
-compress/mode=0
-compress/high_quality=false
-compress/lossy_quality=0.7
-compress/hdr_compression=1
-compress/normal_map=0
-compress/channel_pack=0
-mipmaps/generate=false
-mipmaps/limit=-1
-roughness/mode=0
-roughness/src_normal=""
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/normal_map_invert_y=false
-process/hdr_as_srgb=false
-process/hdr_clamp_exposure=false
-process/size_limit=0
-detect_3d/compress_to=1
-svg/scale=1.0
-editor/scale_with_editor_scale=false
-editor/convert_colors_with_editor_theme=false
diff --git a/addons/rmsmartshape/assets/icon_editor_handle.svg b/addons/rmsmartshape/assets/icon_editor_handle.svg
deleted file mode 100644
index 328dc04..0000000
--- a/addons/rmsmartshape/assets/icon_editor_handle.svg
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/addons/rmsmartshape/assets/icon_editor_handle.svg.import b/addons/rmsmartshape/assets/icon_editor_handle.svg.import
deleted file mode 100644
index 5b6c811..0000000
--- a/addons/rmsmartshape/assets/icon_editor_handle.svg.import
+++ /dev/null
@@ -1,37 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://ccnyogs0qbq8b"
-path="res://.godot/imported/icon_editor_handle.svg-ace1b9f89612a442855e8ad0888fdf3e.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://addons/rmsmartshape/assets/icon_editor_handle.svg"
-dest_files=["res://.godot/imported/icon_editor_handle.svg-ace1b9f89612a442855e8ad0888fdf3e.ctex"]
-
-[params]
-
-compress/mode=0
-compress/high_quality=false
-compress/lossy_quality=0.7
-compress/hdr_compression=1
-compress/normal_map=0
-compress/channel_pack=0
-mipmaps/generate=false
-mipmaps/limit=-1
-roughness/mode=0
-roughness/src_normal=""
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/normal_map_invert_y=false
-process/hdr_as_srgb=false
-process/hdr_clamp_exposure=false
-process/size_limit=0
-detect_3d/compress_to=1
-svg/scale=1.5
-editor/scale_with_editor_scale=false
-editor/convert_colors_with_editor_theme=false
diff --git a/addons/rmsmartshape/assets/icon_editor_handle_add.svg b/addons/rmsmartshape/assets/icon_editor_handle_add.svg
deleted file mode 100644
index a8bc1fd..0000000
--- a/addons/rmsmartshape/assets/icon_editor_handle_add.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-
diff --git a/addons/rmsmartshape/assets/icon_editor_handle_add.svg.import b/addons/rmsmartshape/assets/icon_editor_handle_add.svg.import
deleted file mode 100644
index d8998c0..0000000
--- a/addons/rmsmartshape/assets/icon_editor_handle_add.svg.import
+++ /dev/null
@@ -1,37 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://ci73r1ncmyrrw"
-path="res://.godot/imported/icon_editor_handle_add.svg-7258971e5edcfe4396b7b9c27c0ba1cc.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://addons/rmsmartshape/assets/icon_editor_handle_add.svg"
-dest_files=["res://.godot/imported/icon_editor_handle_add.svg-7258971e5edcfe4396b7b9c27c0ba1cc.ctex"]
-
-[params]
-
-compress/mode=0
-compress/high_quality=false
-compress/lossy_quality=0.7
-compress/hdr_compression=1
-compress/normal_map=0
-compress/channel_pack=0
-mipmaps/generate=false
-mipmaps/limit=-1
-roughness/mode=0
-roughness/src_normal=""
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/normal_map_invert_y=false
-process/hdr_as_srgb=false
-process/hdr_clamp_exposure=false
-process/size_limit=0
-detect_3d/compress_to=1
-svg/scale=1.5
-editor/scale_with_editor_scale=false
-editor/convert_colors_with_editor_theme=false
diff --git a/addons/rmsmartshape/assets/icon_editor_handle_bezier.svg b/addons/rmsmartshape/assets/icon_editor_handle_bezier.svg
deleted file mode 100644
index b498345..0000000
--- a/addons/rmsmartshape/assets/icon_editor_handle_bezier.svg
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/addons/rmsmartshape/assets/icon_editor_handle_bezier.svg.import b/addons/rmsmartshape/assets/icon_editor_handle_bezier.svg.import
deleted file mode 100644
index c6cf95a..0000000
--- a/addons/rmsmartshape/assets/icon_editor_handle_bezier.svg.import
+++ /dev/null
@@ -1,37 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://cycko7tpd5xk5"
-path="res://.godot/imported/icon_editor_handle_bezier.svg-b0150f05772e8974a66bc735765e0aeb.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://addons/rmsmartshape/assets/icon_editor_handle_bezier.svg"
-dest_files=["res://.godot/imported/icon_editor_handle_bezier.svg-b0150f05772e8974a66bc735765e0aeb.ctex"]
-
-[params]
-
-compress/mode=0
-compress/high_quality=false
-compress/lossy_quality=0.7
-compress/hdr_compression=1
-compress/normal_map=0
-compress/channel_pack=0
-mipmaps/generate=false
-mipmaps/limit=-1
-roughness/mode=0
-roughness/src_normal=""
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/normal_map_invert_y=false
-process/hdr_as_srgb=false
-process/hdr_clamp_exposure=false
-process/size_limit=0
-detect_3d/compress_to=1
-svg/scale=1.5
-editor/scale_with_editor_scale=false
-editor/convert_colors_with_editor_theme=false
diff --git a/addons/rmsmartshape/assets/icon_editor_handle_control.svg b/addons/rmsmartshape/assets/icon_editor_handle_control.svg
deleted file mode 100644
index ea69f4e..0000000
--- a/addons/rmsmartshape/assets/icon_editor_handle_control.svg
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/addons/rmsmartshape/assets/icon_editor_handle_control.svg.import b/addons/rmsmartshape/assets/icon_editor_handle_control.svg.import
deleted file mode 100644
index 9208cb7..0000000
--- a/addons/rmsmartshape/assets/icon_editor_handle_control.svg.import
+++ /dev/null
@@ -1,37 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://dgcshah05p0bm"
-path="res://.godot/imported/icon_editor_handle_control.svg-8383942d01a7ee5e839992ed99e53aaf.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://addons/rmsmartshape/assets/icon_editor_handle_control.svg"
-dest_files=["res://.godot/imported/icon_editor_handle_control.svg-8383942d01a7ee5e839992ed99e53aaf.ctex"]
-
-[params]
-
-compress/mode=0
-compress/high_quality=false
-compress/lossy_quality=0.7
-compress/hdr_compression=1
-compress/normal_map=0
-compress/channel_pack=0
-mipmaps/generate=false
-mipmaps/limit=-1
-roughness/mode=0
-roughness/src_normal=""
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/normal_map_invert_y=false
-process/hdr_as_srgb=false
-process/hdr_clamp_exposure=false
-process/size_limit=0
-detect_3d/compress_to=1
-svg/scale=1.5
-editor/scale_with_editor_scale=false
-editor/convert_colors_with_editor_theme=false
diff --git a/addons/rmsmartshape/assets/icon_editor_handle_selected.svg b/addons/rmsmartshape/assets/icon_editor_handle_selected.svg
deleted file mode 100644
index ac96ca6..0000000
--- a/addons/rmsmartshape/assets/icon_editor_handle_selected.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/addons/rmsmartshape/assets/icon_editor_handle_selected.svg.import b/addons/rmsmartshape/assets/icon_editor_handle_selected.svg.import
deleted file mode 100644
index 4b670dd..0000000
--- a/addons/rmsmartshape/assets/icon_editor_handle_selected.svg.import
+++ /dev/null
@@ -1,37 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://dh3vdfbsl5o65"
-path="res://.godot/imported/icon_editor_handle_selected.svg-356ef806610ee2a60b5838a989f58598.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://addons/rmsmartshape/assets/icon_editor_handle_selected.svg"
-dest_files=["res://.godot/imported/icon_editor_handle_selected.svg-356ef806610ee2a60b5838a989f58598.ctex"]
-
-[params]
-
-compress/mode=0
-compress/high_quality=false
-compress/lossy_quality=0.7
-compress/hdr_compression=1
-compress/normal_map=0
-compress/channel_pack=0
-mipmaps/generate=false
-mipmaps/limit=-1
-roughness/mode=0
-roughness/src_normal=""
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/normal_map_invert_y=false
-process/hdr_as_srgb=false
-process/hdr_clamp_exposure=false
-process/size_limit=0
-detect_3d/compress_to=1
-svg/scale=1.25
-editor/scale_with_editor_scale=false
-editor/convert_colors_with_editor_theme=false
diff --git a/addons/rmsmartshape/assets/icon_editor_position.svg b/addons/rmsmartshape/assets/icon_editor_position.svg
deleted file mode 100644
index 7657eb5..0000000
--- a/addons/rmsmartshape/assets/icon_editor_position.svg
+++ /dev/null
@@ -1,4 +0,0 @@
-
diff --git a/addons/rmsmartshape/assets/icon_editor_position.svg.import b/addons/rmsmartshape/assets/icon_editor_position.svg.import
deleted file mode 100644
index fb6f20f..0000000
--- a/addons/rmsmartshape/assets/icon_editor_position.svg.import
+++ /dev/null
@@ -1,37 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://c18veogqnx5ht"
-path="res://.godot/imported/icon_editor_position.svg-1f6e1977293add549ed436510f8834c1.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://addons/rmsmartshape/assets/icon_editor_position.svg"
-dest_files=["res://.godot/imported/icon_editor_position.svg-1f6e1977293add549ed436510f8834c1.ctex"]
-
-[params]
-
-compress/mode=0
-compress/high_quality=false
-compress/lossy_quality=0.7
-compress/hdr_compression=1
-compress/normal_map=0
-compress/channel_pack=0
-mipmaps/generate=false
-mipmaps/limit=-1
-roughness/mode=0
-roughness/src_normal=""
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/normal_map_invert_y=false
-process/hdr_as_srgb=false
-process/hdr_clamp_exposure=false
-process/size_limit=0
-detect_3d/compress_to=1
-svg/scale=1.0
-editor/scale_with_editor_scale=false
-editor/convert_colors_with_editor_theme=false
diff --git a/addons/rmsmartshape/assets/icon_editor_snap.svg b/addons/rmsmartshape/assets/icon_editor_snap.svg
deleted file mode 100644
index a4a1f33..0000000
--- a/addons/rmsmartshape/assets/icon_editor_snap.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/addons/rmsmartshape/assets/icon_editor_snap.svg.import b/addons/rmsmartshape/assets/icon_editor_snap.svg.import
deleted file mode 100644
index e2de758..0000000
--- a/addons/rmsmartshape/assets/icon_editor_snap.svg.import
+++ /dev/null
@@ -1,37 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://bojrgd0r131xh"
-path="res://.godot/imported/icon_editor_snap.svg-f0374ecd8cb313d78a2acb46b093a7f1.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://addons/rmsmartshape/assets/icon_editor_snap.svg"
-dest_files=["res://.godot/imported/icon_editor_snap.svg-f0374ecd8cb313d78a2acb46b093a7f1.ctex"]
-
-[params]
-
-compress/mode=0
-compress/high_quality=false
-compress/lossy_quality=0.7
-compress/hdr_compression=1
-compress/normal_map=0
-compress/channel_pack=0
-mipmaps/generate=false
-mipmaps/limit=-1
-roughness/mode=0
-roughness/src_normal=""
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/normal_map_invert_y=false
-process/hdr_as_srgb=false
-process/hdr_clamp_exposure=false
-process/size_limit=0
-detect_3d/compress_to=1
-svg/scale=1.0
-editor/scale_with_editor_scale=false
-editor/convert_colors_with_editor_theme=false
diff --git a/addons/rmsmartshape/assets/icon_width_handle.svg.import b/addons/rmsmartshape/assets/icon_width_handle.svg.import
deleted file mode 100644
index a1e995e..0000000
--- a/addons/rmsmartshape/assets/icon_width_handle.svg.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="StreamTexture"
-path="res://.import/icon_width_handle.svg-55d6fdc3b3c08e53dc0bed806d2f0a8f.stex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://addons/rmsmartshape/assets/icon_width_handle.svg"
-dest_files=[ "res://.import/icon_width_handle.svg-55d6fdc3b3c08e53dc0bed806d2f0a8f.stex" ]
-
-[params]
-
-compress/mode=0
-compress/lossy_quality=0.7
-compress/hdr_mode=0
-compress/bptc_ldr=0
-compress/normal_map=0
-flags/repeat=0
-flags/filter=true
-flags/mipmaps=false
-flags/anisotropic=false
-flags/srgb=2
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/HDR_as_SRGB=false
-process/invert_color=false
-stream=false
-size_limit=0
-detect_3d=true
-svg/scale=1.0
diff --git a/addons/rmsmartshape/assets/icon_width_handle0.svg.import b/addons/rmsmartshape/assets/icon_width_handle0.svg.import
deleted file mode 100644
index 3d70ef9..0000000
--- a/addons/rmsmartshape/assets/icon_width_handle0.svg.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="StreamTexture"
-path="res://.import/icon_width_handle0.svg-9a486a252970ecb72608cabecc20a9f6.stex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://addons/rmsmartshape/assets/icon_width_handle0.svg"
-dest_files=[ "res://.import/icon_width_handle0.svg-9a486a252970ecb72608cabecc20a9f6.stex" ]
-
-[params]
-
-compress/mode=0
-compress/lossy_quality=0.7
-compress/hdr_mode=0
-compress/bptc_ldr=0
-compress/normal_map=0
-flags/repeat=0
-flags/filter=true
-flags/mipmaps=false
-flags/anisotropic=false
-flags/srgb=2
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/HDR_as_SRGB=false
-process/invert_color=false
-stream=false
-size_limit=0
-detect_3d=false
-svg/scale=1.0
diff --git a/addons/rmsmartshape/assets/icon_width_handle1.svg.import b/addons/rmsmartshape/assets/icon_width_handle1.svg.import
deleted file mode 100644
index c4edbdc..0000000
--- a/addons/rmsmartshape/assets/icon_width_handle1.svg.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="StreamTexture"
-path="res://.import/icon_width_handle1.svg-a1da7c369cb74b89d2283c3679312805.stex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://addons/rmsmartshape/assets/icon_width_handle1.svg"
-dest_files=[ "res://.import/icon_width_handle1.svg-a1da7c369cb74b89d2283c3679312805.stex" ]
-
-[params]
-
-compress/mode=0
-compress/lossy_quality=0.7
-compress/hdr_mode=0
-compress/bptc_ldr=0
-compress/normal_map=0
-flags/repeat=0
-flags/filter=true
-flags/mipmaps=false
-flags/anisotropic=false
-flags/srgb=2
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/HDR_as_SRGB=false
-process/invert_color=false
-stream=false
-size_limit=0
-detect_3d=false
-svg/scale=1.0
diff --git a/addons/rmsmartshape/assets/icon_width_handle2.svg.import b/addons/rmsmartshape/assets/icon_width_handle2.svg.import
deleted file mode 100644
index fd84d56..0000000
--- a/addons/rmsmartshape/assets/icon_width_handle2.svg.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="StreamTexture"
-path="res://.import/icon_width_handle2.svg-b02ee2da69342d687c1fd9680123e834.stex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://addons/rmsmartshape/assets/icon_width_handle2.svg"
-dest_files=[ "res://.import/icon_width_handle2.svg-b02ee2da69342d687c1fd9680123e834.stex" ]
-
-[params]
-
-compress/mode=0
-compress/lossy_quality=0.7
-compress/hdr_mode=0
-compress/bptc_ldr=0
-compress/normal_map=0
-flags/repeat=0
-flags/filter=true
-flags/mipmaps=false
-flags/anisotropic=false
-flags/srgb=2
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/HDR_as_SRGB=false
-process/invert_color=false
-stream=false
-size_limit=0
-detect_3d=false
-svg/scale=1.0
diff --git a/addons/rmsmartshape/assets/icon_width_handle3.svg.import b/addons/rmsmartshape/assets/icon_width_handle3.svg.import
deleted file mode 100644
index 751beb8..0000000
--- a/addons/rmsmartshape/assets/icon_width_handle3.svg.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="StreamTexture"
-path="res://.import/icon_width_handle3.svg-3dcf9d2b715a3978009539d7a6640342.stex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://addons/rmsmartshape/assets/icon_width_handle3.svg"
-dest_files=[ "res://.import/icon_width_handle3.svg-3dcf9d2b715a3978009539d7a6640342.stex" ]
-
-[params]
-
-compress/mode=0
-compress/lossy_quality=0.7
-compress/hdr_mode=0
-compress/bptc_ldr=0
-compress/normal_map=0
-flags/repeat=0
-flags/filter=true
-flags/mipmaps=false
-flags/anisotropic=false
-flags/srgb=2
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/HDR_as_SRGB=false
-process/invert_color=false
-stream=false
-size_limit=0
-detect_3d=false
-svg/scale=1.0
diff --git a/addons/rmsmartshape/assets/icon_width_handle4.svg.import b/addons/rmsmartshape/assets/icon_width_handle4.svg.import
deleted file mode 100644
index 957a8ee..0000000
--- a/addons/rmsmartshape/assets/icon_width_handle4.svg.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="StreamTexture"
-path="res://.import/icon_width_handle4.svg-47fd86c3a89419c03da7bc2def15fbfa.stex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://addons/rmsmartshape/assets/icon_width_handle4.svg"
-dest_files=[ "res://.import/icon_width_handle4.svg-47fd86c3a89419c03da7bc2def15fbfa.stex" ]
-
-[params]
-
-compress/mode=0
-compress/lossy_quality=0.7
-compress/hdr_mode=0
-compress/bptc_ldr=0
-compress/normal_map=0
-flags/repeat=0
-flags/filter=true
-flags/mipmaps=false
-flags/anisotropic=false
-flags/srgb=2
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/HDR_as_SRGB=false
-process/invert_color=false
-stream=false
-size_limit=0
-detect_3d=true
-svg/scale=1.0
diff --git a/addons/rmsmartshape/assets/light1-1.png b/addons/rmsmartshape/assets/light1-1.png
deleted file mode 100644
index 4523497..0000000
Binary files a/addons/rmsmartshape/assets/light1-1.png and /dev/null differ
diff --git a/addons/rmsmartshape/assets/light1-1.png.import b/addons/rmsmartshape/assets/light1-1.png.import
deleted file mode 100644
index 30774a7..0000000
--- a/addons/rmsmartshape/assets/light1-1.png.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://b350jwt2tgchl"
-path="res://.godot/imported/light1-1.png-433fe7882cc83fa28e02c4948a40f886.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://addons/rmsmartshape/assets/light1-1.png"
-dest_files=["res://.godot/imported/light1-1.png-433fe7882cc83fa28e02c4948a40f886.ctex"]
-
-[params]
-
-compress/mode=0
-compress/high_quality=false
-compress/lossy_quality=0.7
-compress/hdr_compression=1
-compress/normal_map=0
-compress/channel_pack=0
-mipmaps/generate=false
-mipmaps/limit=-1
-roughness/mode=0
-roughness/src_normal=""
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/normal_map_invert_y=false
-process/hdr_as_srgb=false
-process/hdr_clamp_exposure=false
-process/size_limit=0
-detect_3d/compress_to=1
diff --git a/addons/rmsmartshape/assets/meta_shape.png b/addons/rmsmartshape/assets/meta_shape.png
deleted file mode 100644
index 2e8259d..0000000
Binary files a/addons/rmsmartshape/assets/meta_shape.png and /dev/null differ
diff --git a/addons/rmsmartshape/assets/meta_shape.png.import b/addons/rmsmartshape/assets/meta_shape.png.import
deleted file mode 100644
index 424753a..0000000
--- a/addons/rmsmartshape/assets/meta_shape.png.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://olmio6gxe5d6"
-path="res://.godot/imported/meta_shape.png-462cb0c943fa311edd3a47aeb27824d9.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://addons/rmsmartshape/assets/meta_shape.png"
-dest_files=["res://.godot/imported/meta_shape.png-462cb0c943fa311edd3a47aeb27824d9.ctex"]
-
-[params]
-
-compress/mode=0
-compress/high_quality=false
-compress/lossy_quality=0.7
-compress/hdr_compression=1
-compress/normal_map=0
-compress/channel_pack=0
-mipmaps/generate=false
-mipmaps/limit=-1
-roughness/mode=0
-roughness/src_normal=""
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/normal_map_invert_y=false
-process/hdr_as_srgb=false
-process/hdr_clamp_exposure=false
-process/size_limit=0
-detect_3d/compress_to=1
diff --git a/addons/rmsmartshape/assets/open_shape.png b/addons/rmsmartshape/assets/open_shape.png
deleted file mode 100644
index 8e1978d..0000000
Binary files a/addons/rmsmartshape/assets/open_shape.png and /dev/null differ
diff --git a/addons/rmsmartshape/assets/open_shape.png.import b/addons/rmsmartshape/assets/open_shape.png.import
deleted file mode 100644
index 9ac56fa..0000000
--- a/addons/rmsmartshape/assets/open_shape.png.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://cpg65u2v4mthq"
-path="res://.godot/imported/open_shape.png-f18727d78226e221aef881edda953bbd.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://addons/rmsmartshape/assets/open_shape.png"
-dest_files=["res://.godot/imported/open_shape.png-f18727d78226e221aef881edda953bbd.ctex"]
-
-[params]
-
-compress/mode=0
-compress/high_quality=false
-compress/lossy_quality=0.7
-compress/hdr_compression=1
-compress/normal_map=0
-compress/channel_pack=0
-mipmaps/generate=false
-mipmaps/limit=-1
-roughness/mode=0
-roughness/src_normal=""
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/normal_map_invert_y=false
-process/hdr_as_srgb=false
-process/hdr_clamp_exposure=false
-process/size_limit=0
-detect_3d/compress_to=1
diff --git a/addons/rmsmartshape/assets/shape.png.import b/addons/rmsmartshape/assets/shape.png.import
deleted file mode 100644
index 7af62f8..0000000
--- a/addons/rmsmartshape/assets/shape.png.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="StreamTexture"
-path="res://.import/shape.png-00d53041e0aeffe00cc49849dfbcc65f.stex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://addons/rmsmartshape/shape.png"
-dest_files=[ "res://.import/shape.png-00d53041e0aeffe00cc49849dfbcc65f.stex" ]
-
-[params]
-
-compress/mode=0
-compress/lossy_quality=0.7
-compress/hdr_mode=0
-compress/bptc_ldr=0
-compress/normal_map=0
-flags/repeat=0
-flags/filter=false
-flags/mipmaps=false
-flags/anisotropic=false
-flags/srgb=2
-process/fix_alpha_border=false
-process/premult_alpha=false
-process/HDR_as_SRGB=false
-process/invert_color=false
-stream=false
-size_limit=0
-detect_3d=true
-svg/scale=1.0
diff --git a/addons/rmsmartshape/assets/shape_anchor.png.import b/addons/rmsmartshape/assets/shape_anchor.png.import
deleted file mode 100644
index 86c89d7..0000000
--- a/addons/rmsmartshape/assets/shape_anchor.png.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="StreamTexture"
-path="res://.import/shape_anchor.png-c4527dad8f7093abc2088dd0157f0c72.stex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://addons/rmsmartshape/shape_anchor.png"
-dest_files=[ "res://.import/shape_anchor.png-c4527dad8f7093abc2088dd0157f0c72.stex" ]
-
-[params]
-
-compress/mode=0
-compress/lossy_quality=0.7
-compress/hdr_mode=0
-compress/bptc_ldr=0
-compress/normal_map=0
-flags/repeat=0
-flags/filter=true
-flags/mipmaps=false
-flags/anisotropic=false
-flags/srgb=2
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/HDR_as_SRGB=false
-process/invert_color=false
-stream=false
-size_limit=0
-detect_3d=true
-svg/scale=1.0
diff --git a/addons/rmsmartshape/common_functions.gd b/addons/rmsmartshape/common_functions.gd
deleted file mode 100644
index 3fa40af..0000000
--- a/addons/rmsmartshape/common_functions.gd
+++ /dev/null
@@ -1,33 +0,0 @@
-@tool
-extends Node
-class_name SS2D_Common_Functions
-
-
-static func sort_z(a, b) -> bool:
- if a.z_index < b.z_index:
- return true
- return false
-
-
-static func sort_int_ascending(a: int, b: int) -> bool:
- if a < b:
- return true
- return false
-
-
-static func sort_int_descending(a: int, b: int) -> bool:
- if a < b:
- return false
- return true
-
-
-static func to_vector3(vector: Vector2) -> Vector3:
- return Vector3(vector.x, vector.y, 0)
-
-
-static func merge_arrays(arrays: Array) -> Array:
- var new_array := []
- for array: Array in arrays:
- for v: Variant in array:
- new_array.push_back(v)
- return new_array
diff --git a/addons/rmsmartshape/documentation/.gdignore b/addons/rmsmartshape/documentation/.gdignore
deleted file mode 100644
index e69de29..0000000
diff --git a/addons/rmsmartshape/documentation/Controls.md b/addons/rmsmartshape/documentation/Controls.md
deleted file mode 100644
index 424b2d8..0000000
--- a/addons/rmsmartshape/documentation/Controls.md
+++ /dev/null
@@ -1,47 +0,0 @@
-# SmartShape2D - Controls and Hotkeys
-
-
-
-## Controls - Point Create
-
-- Add Point
- - Left Click Anywhere in the viewport
-
-- Leave Point Create Mode
- - ESCAPE
-
-## Controls - Point Edit
-
-- Add Point
- - Either:
- - Hold ALT and Left Click Anywhere in the viewport
- - Click on an edge between two points
-
-- Grab closest point
- - Hold CTRL
-
-- Cycle through texture indices of a point
- - Mouseover a point and MOUSEWHEEL up or down to increment / decrement the texture index
-
-- Flip texture
- - Mouseover a point and press SPACE
-
-- Change texture width property
- - Mouseover a point, hold SHIFT, then MOUSEWHEEL up or down to increment / decrement the texture width
-
-- Add Bezier curve
- - Mouseover a point, hold SHIFT, then click and drag to create control points on the point
-
-- Create New Shape
- - Hold SHFT + ALT and click
- - The location of the click will be the the first point of a newly created Shape Node
-
-### Overlap
-
-When multiple points and edges overlap, it can be ambiguous what clicking will do.
-SmartShape adheres the following rules:
-- If a control point overlaps a vertex, the control point takes priority
-- If a control point or vertex overlaps an edge:
- - Clicking will move the control point or vert
- - Clicking while holding ALT will create new point on the edge
-
diff --git a/addons/rmsmartshape/documentation/FAQ.md b/addons/rmsmartshape/documentation/FAQ.md
deleted file mode 100644
index ca83607..0000000
--- a/addons/rmsmartshape/documentation/FAQ.md
+++ /dev/null
@@ -1,47 +0,0 @@
-# SmartShape2D - FAQ
-
-
-
-## Why aren't my textures repeating?
-
-If your textures aren't repeating and look something like this:
-
-
-
-The issue is most likely that you need to set the texture's import options in Godot:
-
-
-
-## Why isn't my shape updaing when I change the Light Mask?
-
-Each shape is currently rendered by multiple-subnodes (Children Node2Ds).
-Their owner isn't set, making them invisible in the editor (unless you have debug mode on).
-
-Unfortunately, there is no accessible signal when changing the Light Mask setting in editor.
-That means changing the Light Mask setting in editor won't trigger the children nodes to change THIER Light Mask
-
-The Shape nodes CAN update their children's light mask, they just need to be triggered to do it manually.
-If you update the shape in any way, the shape will update its children's light mask.
-
-When playing the game, the render Node children are regenerated, ensuring that the light mask will be set
-correctly.
-
-The actual shape has set\_light\_mask overloaded, so changing the light\_mask in code should work without issue
-
-If you need to manually tell the shape to update its rendering, call the set\_as\_dirty() method
-
-If anyone has any insights on this issue, please feel free to open an issue on this subject
-and let us know how we might be able to fix it
-
-## Why does changing the width look so ugly?
-
-Changing the width of the quads generally looks best with welding turned off.
-
-If welding is on, you can still change the width of the quads, but you may need to play with it a bit.
-It's best that you change the width gradually in small increments instead of sharply.
-Sharply changing the width will result in odd looking shapes.
-
-[Non-perspective rendering to a non-parallelogram is kinda tough](http://reedbeta.com/blog/quadrilateral-interpolation-part-1/)
-
-If anyone has any insights on this issue, please feel free to open an issue on this subject
-and let us know how we might be able to fix it
diff --git a/addons/rmsmartshape/documentation/Godot4.md b/addons/rmsmartshape/documentation/Godot4.md
deleted file mode 100644
index 93423a3..0000000
--- a/addons/rmsmartshape/documentation/Godot4.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# Using SmartShape2D with Godot 4
-
-Godot 4 moved `repeat` for textures as an import option to a per-node option. On how to make textures repeat and
-set normal maps see [section below.](#repeating-textures-and-normal-textures-with-canvastexture)
-
-By default, **shape resources are shared** when the shape is copy-pasted. Editing points will edit every copy of that shape.
-To make point geometry unique, press **"Make Unique"** property button in Geometry property group in the inspector:
-
-
-
-## Repeating Textures and Normal Textures with CanvasTexture
-
-CanvasItem, the base class of Node2D has a Texture section with `repeat`. If you aren't using a normal, you can set it here.
-By default, this setting is inherited by children nodes so you could set it on a parent node (assuming all the children need
-repeating textures or it's easier to disable for a few specific nodes than turn it on for most).
-
-
-
-Normal textures are no longer set in a material resource.
-
-To set normal textures, you can create a `CanvasTexture` resource in the inspector on any property, that allows setting a `Texture2D`.
-
-
-
-`CanvasTexture` allows you to assign diffuse texture and normal map texture, as well as set textures to `repeat`:
-
-
-
-## Converting Projects from Godot 3.x
-
-Scene files with shapes saved in Godot 3.x should load in Godot 4 project. However, you may encounter some issues. Here is a list of expected problems:
-1. Textures are looking weird, not repeated.
-2. Normal textures are not used.
-
-Please read the section on [how to set repeat and use normal textures in Godot 4](#repeating-textures-and-normal-textures-with-canvastexture).
-
-## Removed Features
-
-- The Godot 4 version of this addon does not support 1.x RMSmartShape2D nodes anymore.
-- SS2D_Shape_Meta node was removed, since its functionality is available copy-pasted shapes by default.
diff --git a/addons/rmsmartshape/documentation/Install.md b/addons/rmsmartshape/documentation/Install.md
deleted file mode 100644
index 3a3d0ca..0000000
--- a/addons/rmsmartshape/documentation/Install.md
+++ /dev/null
@@ -1,20 +0,0 @@
-# SmartShape2D - Install
-
-## Asset Library
-
-- After installing the plugin, you may encounter an error, this is normal.
-- You need to restart Godot before using the plugin.
-
-## Manual Install
-
-- Clone the repository at https://github.com/SirRamEsq/SmartShape2D.
-- Move the "addons/rmsmartshape" folder to your project's "addons" folder.
-- Open your project in Godot to have the addon install.
-- After installing the plugin, you may encounter an error, this is normal.
-- Restart Godot.
-
-## Activate Plugin
-
-- After Installing the plugin, activate the plugin by navigating to `Project -> Project Settings... -> Plugins`
-
-
diff --git a/addons/rmsmartshape/documentation/Normals.md b/addons/rmsmartshape/documentation/Normals.md
deleted file mode 100644
index 91c3e7b..0000000
--- a/addons/rmsmartshape/documentation/Normals.md
+++ /dev/null
@@ -1,60 +0,0 @@
-# Normals
-
-## Default Normals
-
-Even if you assign normal textures to your Edge Material, the normals will look wrong.
-
-For example, consider the following image:
-
-
-
-The normals in the image clearly don't line up with where the light is actually coming from.
-
-## Encoding Normal data in the canvas_item Vertex Shader Color Parameter
-
-As SmartShape renders the edges, the textures and their normal textures are also rotated.
-This will result in incorrect normals.
-To solve this, we can use a shader to correctly calculate the normals.
-
-The tricky part lies in how few ways there are to pass data to a canvasItem shader on a per-vertex basis.
-See here for the full list:
-https://docs.godotengine.org/en/stable/tutorials/shading/shading_reference/canvas_item_shader.html#doc-canvas-item-shader
-
-Fortunately, the COLOR parameter can be used for this purpose.
-The COLOR ENCODING paramter of an Edge Material can be used to choose what data is encoded in the
-Vertex Shader's Color Parameter.
-
-If we set the COLOR ENCODING value to "Normals", we get this:
-
-
-
-Ok, so now the normals still look wrong, but the colors look wrong too. Great.
-
-There is one final step before our normals will be correct. We need to decode the normal data in a shader.
-
-
-## Writing a Shader
-
-You'll want to assign a new shader to the Edge Material's material property.
-This shader will determine how each edge is rendered.
-
-Here's a sample shader to decode our normal data and set our actual color to that of our diffuse texture:
-
-```glsl
-shader_type canvas_item;
-
-varying mat2 NORMAL_MATRIX;
-
-void vertex() {
- NORMAL_MATRIX = mat2(COLOR.rg, COLOR.ba)*2.0 - mat2(vec2(1.0), vec2(1.0));
-}
-
-void fragment() {
- NORMAL.xy = NORMAL_MATRIX*NORMAL.xy;
- COLOR = texture(TEXTURE, UV);
-}
-```
-
-After assigning this shader the the Edge Material's material property, our normals finally look right:
-
-
diff --git a/addons/rmsmartshape/documentation/Quickstart.md b/addons/rmsmartshape/documentation/Quickstart.md
deleted file mode 100644
index 14554b0..0000000
--- a/addons/rmsmartshape/documentation/Quickstart.md
+++ /dev/null
@@ -1,136 +0,0 @@
-# SmartShape2D - QuickStart
----
-
-
-If you feel like your workflow with SmartShape2D is a little bit slow, try reading [Controls and Hotkeys](./Controls.md). The hotkeys may help you work with the tool more effectively.
-
-## Basic understanding
-SmartShapes work similarly to [tilesets](https://docs.godotengine.org/en/latest/tutorials/2d/using_tilesets.html) but are not bound to a grid. They can be used to create polygons and even organic shapes. This allows for level design akin to [Rayman Legends](https://youtu.be/WFu1utKAZ18?si=_33TaErpHSh-r732&t=916) (based on the UbiArt Framework).
-
-Each SmartShape is made up of multiple textures that are responsible for rendering different aspects like corners or edges:
-
-
-
-## Creating a Shape
-
-
-
-- First, instance a node of either:
- - SS2D_Shape_Open
- - **SS2D_Shape_Closed**
- - **We'll use a closed shape for this Quickstart demo**
-- SS2D_Shape_Base cannot be instanced directly
-- SS2D_Shape_Anchor is a node that attaches to a shape
-- The following Nodes are legacy nodes and are deprecated:
- - RMSmartShape2D
- - RMSmartShape2DAnchor
-
-
-
-## Editing the Shape
-
-- After creating the shape node, make sure it's selected and the toolbar appears and is in Point Edit mode
- - 
-- Hold ALT and Left Click on the viewport to add points
- - If this is a closed shape, the polygon will close after adding the 3rd point
-- You should now have a shape consisting of a few points and lines:
-
-
-
-## Setting the Fill Texture of the Shape (Closed Shape only)
-
-- To give it some life, we'll want to edit the "Shape Material" in the Inspector
-- Under "Shape Material" Expand "Fill Textures" and you'll see an empty array
-- Set the Array's size to '1'
-- Assign a texture to the newly created slot in the array
-- After assigning the shape should now have a valid texture
- - If nothing happens after setting the texture, try to force the shape to update by adjusting one of the points
-- **Note that "Fill Textures" does not affect open shapes at all**
-- If you want to add a normal_texture, you would add it using the "Fill Texture Normals" property
-
-
-
-## Texturing the Edges
-
-- This where the rubber hits the road, the real meat of the tool
-- Under "Shape Material" add an element to the "Edge Meta Materials" property
- - Shape Material -> Edge Meta Materials
-- Set the resource of the newly created element to "SS2D_Material_Edge_Metadata"
- - Unfortunately, due to Godot limitations, every avaiable resource will offered to you instead of the one you want
- - The options are alphabetized though, which helps in finding the resource you want
-- Expand the first element of the "Edge Meta Materials" that you just set
- - Shape Material -> Edge Meta Materials -> element 1
-- Set the value of the "Edge Material" property to a new resource of type "SS2D_Material_Edge"
- - Shape Material -> Edge Meta Materials -> element 1 -> Edge Material
-- Expand "Edge Material" that you just set
-- Add an element to "Textures" and assign the texture to one that you want to use as an edge
-- The shape's edges should now update using the texture you set
- - If nothing happens after setting the texture, try to force the shape to update by adjusting one of the points
-- If you want to add a normal_texture, you would add it using the "Texture Normals" property
-- Godot should now look something like this:
-
-
-
-### Corners
-
-- If your shape has sharp 90-degree corners, the texture can look a bit warped in those places
-- You can specify a unique texture to use for inner and outer corners for each Edge Material
-- The following Edge Material properties are used for corners
- - Textures Corner Inner
- - Texture Normals Corner Inner
- - Textures Corner Outer
- - Texture Normals Corner Outer
-- See how the addition of outer corner textures improves the square created earlier
-
-
-
-### Multiple Edge Materials in One Edge
-
-- You can add as many Edge Meta Materials as you want to a Shape Material, each with their own Edge Material
-- For instance, you can add an additional egde with a rock texture (and its own set of corner textures) and have it render behind the grass
- - To have it render behind the grass, Set the Z index of the meta material
-
-
-
-### Normal Range
-
-- Each Meta material has a Normal Range
-- The Normal Range indicates when a texture should be rendered
- - If the normal range is 0 - 360 or 0 - 0, then any angle is considered in range and the edge will always render
- - Angle "0" is Facing directly Right
- - Angle "90" is Facing directly Up
- - Angle "180" is Facing directly Left
- - Angle "270" is Facing directly Down
-
-- If you wanted to, for example:
- - Have rocks display on the bottom part of the shape only
- - Have grass display on the sides and top of the shape only
-- You could:
- - Set the grass Normal Range to 0 - 180
- - Set the rock Normal Range to 181 - 359
-
-
-
-### Material Overrides
-
-- Using Material Overrides will allow you to change how specific edges are rendered
-- For Example, to prevent the left edge from rendering, we'll do the following:
- - Select the edge edit button from the toolbar 
- - Right Click the left edge of the shape
- - Press the "Material Override" Button
- - Uncheck the "Render" Checkbox
-
-
-
-- You can use material overrrides to also specify a specific material for a single edge
-- For example, Checking Render and choosing the "Rock" Edge Material will cause the edge to render as rocks, even though the NormalRange configuration would otherwise have it render as grass
-
-### Multiple Textures
-
-- If more than one texture is specified for an Edge Material, you can specify which texture should be used
-- Enter Point Edit mode, mouseover a point, and scroll up or down to change the texture index
-
-## Anchoring Nodes to the Shape
-
-- To anchor nodes directly to the SmartShape2D node, use SmartSahpeAnchor2D
-- You can then make nodes children to the anchor
diff --git a/addons/rmsmartshape/documentation/Resources.md b/addons/rmsmartshape/documentation/Resources.md
deleted file mode 100644
index 92c5678..0000000
--- a/addons/rmsmartshape/documentation/Resources.md
+++ /dev/null
@@ -1,115 +0,0 @@
-# SmartShape2D - Resources
-
-
-
-## Shape Materials
-
-Shape materials provide all the texture and collision information needed by the SmartShape nodes.
-Once a shape material is defined, it can be easily reused by any number of SmartShape2D nodes.
-
-- Edge Meta Materials
- - An array of resources of type SS2D_Material_Edge_Metadata
-- Fill Textures
- - Used as the texture for the inside of the polygon for Closed Shapes
- - Currently, only the first texture can be used, multiple textures may be supported at a later date
-- Normal Textures
- - In Godot 4, you can set normal textures with `CanvasTexture` resource.
-- Fill Texture Z Index
- - Each Edge Meta Material has a ZIndex indicating which edges are drawn first
- - This sets the ZIndex for the fill texture
- - This allows the user to draw the fill texture in front of some edges or behind others
-- Fill Mesh Offset
- - The Offset of the Fill Mesh
- - Can be used to grow / shrink the fill mesh
-- Render Offset
- - Every edge in the shape will be offset by this amount
-- Weld
- - Whether or not to weld the last quad of an edge with the first quad of the next edge
-
-## Edge Meta Material
-
-An Edge Meta Material doesn't contain the actual textures used to render an edge like **Edge Material** does.
-Instead, this resource contains a single **Edge Material** and describes how and when to render the edge.
-
-- Normal Range
- - The angles at which an edge is allowed to be rendered
-- Weld
- - Whether or not to weld the quads in this edge
-- Taper Sharp Corners
- - Edge vertices sharper than 90° that aren't rendered as corners, will be tapered and not welded
- - Will not work properly on shapes with curves
-- Render
- - Whether or not this edge is visible
-- Z Index
- - Dictates the order in which edges are drawn
-- Offset
- - Offset of the edge
- - Can use a positive or negative value to draw the edges closer or further from the shape
-
-## Normal Range
-
-The Normal Range indicates when a texture should be rendered.
-Each shape will compare the Surface Normal of an edge to the Normal Range in each Edge Meta Material.
-If the edge's Normal is inside a Meta Material's Normal Range, the Meta Material's Edge Material is rendered.
-
-
-
-- A Normal Range is specified in Degrees
- - If the normal range is 0 - 360 or 0 - 0, any angle is considered in range and the edge will always render
- - Angle "0" is Facing directly Right
- - Angle "90" is Facing directly Up
- - Angle "180" is Facing directly Left
- - Angle "270" is Facing directly Down
-
-## Edge Material
-
-The actual textures used to define an edge
-
-### Textures
-
-- The primary textures used for the edge
-- At least one texture must be defined
-- Example: 
-
-### Taper Textures
-
-These textures will be used as the first or last quad in an edge.
-They're named "Taper Textures" because the purpose is to show the edge "tapering off"
-- Textures_Taper_Left is the first quad in an edge
- - Example: 
-- Textures_Taper_Right is the final quad in an edge
- - Example: 
-
-### Corner Textures
-
-These textures will be used when the edge forms a sharp corner (80 degrees - 100 degrees)
-These are used because corners can look warped when using only regular textures
-- Texture_Corner_Inner is used when the corner forms an inner corner
- - Example: 
-- Texture_Corner_Outer is used when the corner forms an outer angle
- - Example: 
-
-### Normal Texture and Repeat
-
-To use normal textures, you can create a `CanvasTexture` resource in the inspector on any property,
-that allows to set a texture. There you can assign your texture and your normal texture, as well as set
-those to `repeat`.
-
-### Repeat Textures
-
-See previous section.
-
-### Fit Mode
-
-Most likely, the textures you use will not *perfectly* fit the polygon.
-This setting allows you to determine how SmartShape will rectify this.
-
-Differt options may look better or worse depending on the art-style.
-
-- Sqush and Stretch
- - Texture will be mutated
- - Either slightly squished or stretched to fit the polygon
-- Crop
- - Texture will not be mutated
- - Texture will simply be cropped when changing from one texture to the next
-
diff --git a/addons/rmsmartshape/documentation/Shapes.md b/addons/rmsmartshape/documentation/Shapes.md
deleted file mode 100644
index 70afa84..0000000
--- a/addons/rmsmartshape/documentation/Shapes.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# SmartShape2D - Shapes
-
-Each shape consists of a set of points. You can directly edit either the points or the edges between the points in the viewport.
-
-Shapes are configured to use a [Shape Material](./Resources.md#ShapeMaterial) which determines how the shape is rendered.
-
-A shape can be open or closed. Each new shape starts open. To close a shape, simply add a point on top of the first one.
-
-
-## Properties
-
-> 🛈 Most properties now have documentation comments.
-
-
-
-### Editor Debug
-
-- Will show the bounding box for each quad in the mesh of edges.
-- Can be helpful to illustrate why a shape doesn't look the way you expect.
-
-### Flip Edges
-
-- Will flip the edges of the shape (invert y).
-
-### Render Edges
-
-- Whether or not the edges of the shape should be rendered.
-
-### Collision Size
-
-- Size of the collision shape.
-
-### Collision Offset
-
-- Offset of where the collision shape starts and ends.
-- A **positive** value offsets the collision shape **outwards**.
-- A **negative** value offsets the collision shape **inwards**.
-
-### Tessellation Stages
-
-- Number of stages in the curve tessellation process (Uses Curve2D Internally).
-- First Param in Curve2D.tessellate.
-- See [Curve2D Documentation](https://docs.godotengine.org/en/3.2/classes/class_curve2d.html#class-curve2d-method-tessellate).
-
-### Tessellation Tolerence
-
-- Tolerence Degrees in the curve tessellation process (Uses Curve2D Internally).
-- Second Param in Curve2D.tessellate.
-- See [Curve2D Documentation](https://docs.godotengine.org/en/3.2/classes/class_curve2d.html#class-curve2d-method-tessellate).
-
-### Collision Generation Method
-
-- Controls which method should be used to generate the collision shape.
-- See also in-engine documentation.
-
-### Collision Update Mode
-
-- Controls when to update collisions.
-- See also in-engine documentation.
-
-### Curve Bake Interval
-
-- Bake interval value for Curve2D.
-- See [Curve2D Documentation](https://docs.godotengine.org/en/3.2/classes/class_curve2d.html#class-curve2d-property-bake-interval).
-
-### Collision Polygon Node Path
-
-- The path to the CollisionShape that the SmartShape will use for collision.
-- Is Autoset when pressing the generate collision button.
-
-### Shape Material
-
-- The material that this shape will use to render itself.
-- For backwards compatibility `fill_texture_z_index` defaults to `-10`. Set this to `0` and enable `fill_texture_show_behind_parent` in order to preserve Godot's normal z-sorting when layering with other nodes.
-
-### Points
-
-- **There is no need to edit this property by hand, but you can if you'd like.**
-- Contains all of the points and meta-data for the points contained in this shape.
-- This data structure is updated as you manipulate the shape.
-
-### Material Overrides
-
-- **There is no need to edit this property by hand, but you can if you'd like.**
-- When an edge is given a "Material Override" the data for that edge is stored here.
-- This data structure is updated as you manipulate the shape.
-
-
diff --git a/addons/rmsmartshape/documentation/Toolbar.md b/addons/rmsmartshape/documentation/Toolbar.md
deleted file mode 100644
index ffd31b8..0000000
--- a/addons/rmsmartshape/documentation/Toolbar.md
+++ /dev/null
@@ -1,53 +0,0 @@
-# SmartShape2D - Toolbar
-
-
-
-
-
-## Create Mode
-
-- In this mode you can start creating a new shape.
-- Left-Click anywhere to add a new point.
-- Press ESCAPE to exit create mode.
-- Hold down ALT and Left-Click to create a point between the two points closest to your mouse.
-
-## Point Mode
-
-- In this mode you can add, delete, and move all of the points that make up a shape
-- To **Add** a new point to the shape:
- - Hold down ALT and Left-Click anywhere on the viewport to add a point between the two points closest to your mouse.
- - Left-Click on an edge between two points.
-- To **Move** a point, Left-Click on any point and drag
-- To **Delete** a point, Right-Click on any point
-- To set the **Control Points** of a point (for curves), hold **Shift**, Left Click on any point and drag
- - After the Control Points have been set, you can edit them individually by Left-Clicking and dragging
- - You can delete control points by right clicking them
- - To make an empty clone SmartShape2D, hold down ALT + SHIFT and Left-Click anywhere in the viewport.
-
-## Edge Mode
-
-- In this mode you can Move Eges and choose how specific edges are rendered
-- To **Move** an Edge, Left Click and Drag the Edge
-- To **Change an Edges Rendering**, right click the edge and press "**Material Override**"
-
-
-- This popup allows you to **change how edges are rendered**
- - **Render** will toggle whether or not this edge will be drawn with Edge Materials
- - **Set Material** allows you to choose a specific Edge Material to use to render this edge
-
-## Origin Set
-
-- This tool allows you to set the origin of any SmartShape
-- To **Set the Origin** Left Click anywhere on the viewport
-
-## Generate Collision
-
-- If you want your shape to have collision, press this button to autogenerate the collision nodes
-- The shape will be made a child of a newly created **StaticBody2D**
-- A sibling node, **CollisionPolygon2D** will also be created and added to the SceneTree
- - The "Collision Polygon" parameter of the Shape will be set to this sibling **CollisionPolygon2D**
-
-## Snapping
-
-When Moving / Adding points, snapping will cause the positions of the points to snap to the grid. This works the same as Godot's built-in snapping.
-You can have snapping either use Global Space, or space relative to the shape's origin.
diff --git a/addons/rmsmartshape/documentation/VersionHistory.md b/addons/rmsmartshape/documentation/VersionHistory.md
deleted file mode 100644
index e924a95..0000000
--- a/addons/rmsmartshape/documentation/VersionHistory.md
+++ /dev/null
@@ -1,117 +0,0 @@
-# Version History
-
-## 2.x
-### 2.2
-January 4th 2021
-### Fix
-- Fix for crash that would occur when points were aligned *just* right
-- See issue 66
- + https://github.com/SirRamEsq/SmartShape2D/issues/66
-### Features
-- Each Edge Material can now have a Material (Shader)
-- Each Edge Material Meta can have a z-index and z-as-relative set
-- See issue 64
- + https://github.com/SirRamEsq/SmartShape2D/issues/64
-
-### 2.1
-December 14th 2020
-#### Significant Changes from 2.0
-- Improved Width handling
-- Improved Welding
-- Rendering is now achieved by having multiple child-nodes each render a piece of the shape
- + Previously, all the rendering was done by the shape node
- + Improves performance
- + Fixes lighting bugs
-- Point Creation mode reimplemented
- + Mode active by default
- + Can be exited by pressing ESC
-- Several usability additions
- + Hotkey for grabbing closest point
- + Hotkey for creating new shape at point
- + Width Grabber for closest point
- + Preview for adding points
-- Several Bug fixes and issues closed
-#### New Features
-- Meta Shapes Introduced
-- "Fit mode" added to edge material
- + Can either squash and stretch the texture or crop it
-#### Minor Changes
-- Changes to GUI Theme
- + More in line with standard Godot
-- Add windows scripts for running unit tests
-- Changed default snap settings to 8x8 pixels
-
-### 2.0
-September 7th 2020
-#### Significant Changes from 1.0
-- Edge Textures are no longer determined by a cardinal direction (UP, DOWN, LEFT, RIGHT)
- - Instead, a starting and ending normal angle is specified for each edge
-- Textures are now defined per-edge instead of per-shape
-#### New Features
-- Taper textures
- - Instead of simply ending, the user can have an edge "taper-off"
-- Editing by Edges
-- Material Overrides
-#### Internal Changes
-- Completely overhauled everything
-- A rudimentary constraint system is in place
- - Closed shapes will add a point when closing, then constrain the added point's position to the first point
-- Points are no longer refered to by index, they are refered to by keys
- - This enables points to have relationships that aren't affected when:
- - Adding/Removing a point
- - Changing orientation of the poly
-- Many Unit and Integration tests
- - Refactored original working code to better support testing
-- Kept original scripts and classes from version 1.0 to ease importing
-
-## 1.x
-### Changes in 1.3
-This update primarily fixes bugs and improves existing features to be more usable.
-#### Changes
-- Merged top/left/right/bottom offset into one variable. render offset
-#### Fixes
-- Input bugs
-- Edge Flipping
-- Polygon orientation bugs
-- Quad Welding
-- Corer quad generation and welding
-- Collision variables in the RMSmartShapeMaterial working as intended
-
-### Changes in 1.2
-#### Tweaks
-- Refactoring
-- Toolbar takes less space
-- Minor bug fixes
-
-#### New Features
-- Bezier Curves!
- - Hold shift on a control point to create a curve
-- Corner Quads!
- - Both inner and outer corner quads are now generated
- - Textures can be speciied for each direction of both inner and outer quads
-- Edge Moving!
- - Can move an edge (two points) by pressing SHIFT in move mode and dragging the edge
-
-### Changes in 1.1
-- Refactoring
-- Fixed Errors Occuring when Texture Arrays are size '0' but not null
-- Fixed sync between texture, flip, and width indicies
- - Would sometimes share a single array between the 3 vars
- - Are all unique now
-
-- Snapping
-- More informative toolbar
-
-### Changes in 1.0
-- Fixed many debug errors reported related to indexing beyond array sizes
-- Fixed control point wrapping of RMSmartShapeAnchor2D nodes anchored to RMSmartShape2D nodes.
-- Tested on newly released 3.2 Godot.
-
-### Changes in 0.91
-- Edges are calculated in relationship to object space instead of screen space
-- Added option to allow user to let the object recalculate edges based on screen space.
-- Fixed uv calculations for flipped textures.
-- Fixed uv bug for edge sections less than half the size of texture width
-- Added option to allow for a RMSmartShapeAnchor to mimic scale of monitored node
-- Removed sections of code related to clockwise versus clockwise checks, very specifically regarding the direction of texture edges.
-- Corrected normal texture bug for fill and edge rendering
diff --git a/addons/rmsmartshape/documentation/imgs/AngleExplaination.png b/addons/rmsmartshape/documentation/imgs/AngleExplaination.png
deleted file mode 100644
index 5b74564..0000000
Binary files a/addons/rmsmartshape/documentation/imgs/AngleExplaination.png and /dev/null differ
diff --git a/addons/rmsmartshape/documentation/imgs/EdgeEdit-MaterialOverride.png b/addons/rmsmartshape/documentation/imgs/EdgeEdit-MaterialOverride.png
deleted file mode 100644
index 56c0070..0000000
Binary files a/addons/rmsmartshape/documentation/imgs/EdgeEdit-MaterialOverride.png and /dev/null differ
diff --git a/addons/rmsmartshape/documentation/imgs/EdgeEdit-NoRender.png b/addons/rmsmartshape/documentation/imgs/EdgeEdit-NoRender.png
deleted file mode 100644
index 789ac59..0000000
Binary files a/addons/rmsmartshape/documentation/imgs/EdgeEdit-NoRender.png and /dev/null differ
diff --git a/addons/rmsmartshape/documentation/imgs/Inpsector-EdgeMaterial.png b/addons/rmsmartshape/documentation/imgs/Inpsector-EdgeMaterial.png
deleted file mode 100644
index e031a52..0000000
Binary files a/addons/rmsmartshape/documentation/imgs/Inpsector-EdgeMaterial.png and /dev/null differ
diff --git a/addons/rmsmartshape/documentation/imgs/Inpsector-EdgeMaterialCornerOuter.png b/addons/rmsmartshape/documentation/imgs/Inpsector-EdgeMaterialCornerOuter.png
deleted file mode 100644
index 42bb12b..0000000
Binary files a/addons/rmsmartshape/documentation/imgs/Inpsector-EdgeMaterialCornerOuter.png and /dev/null differ
diff --git a/addons/rmsmartshape/documentation/imgs/Inpsector-EdgeMaterials2.png b/addons/rmsmartshape/documentation/imgs/Inpsector-EdgeMaterials2.png
deleted file mode 100644
index f03a474..0000000
Binary files a/addons/rmsmartshape/documentation/imgs/Inpsector-EdgeMaterials2.png and /dev/null differ
diff --git a/addons/rmsmartshape/documentation/imgs/Inpsector-EdgeMaterialsNormalRange.png b/addons/rmsmartshape/documentation/imgs/Inpsector-EdgeMaterialsNormalRange.png
deleted file mode 100644
index cfc3a68..0000000
Binary files a/addons/rmsmartshape/documentation/imgs/Inpsector-EdgeMaterialsNormalRange.png and /dev/null differ
diff --git a/addons/rmsmartshape/documentation/imgs/NewNode-SS2D_Nodes.png b/addons/rmsmartshape/documentation/imgs/NewNode-SS2D_Nodes.png
deleted file mode 100644
index df063e4..0000000
Binary files a/addons/rmsmartshape/documentation/imgs/NewNode-SS2D_Nodes.png and /dev/null differ
diff --git a/addons/rmsmartshape/documentation/imgs/NormalColors.png b/addons/rmsmartshape/documentation/imgs/NormalColors.png
deleted file mode 100644
index 904f83a..0000000
Binary files a/addons/rmsmartshape/documentation/imgs/NormalColors.png and /dev/null differ
diff --git a/addons/rmsmartshape/documentation/imgs/NormalCorrect.png b/addons/rmsmartshape/documentation/imgs/NormalCorrect.png
deleted file mode 100644
index 2c899e2..0000000
Binary files a/addons/rmsmartshape/documentation/imgs/NormalCorrect.png and /dev/null differ
diff --git a/addons/rmsmartshape/documentation/imgs/NormalWrong.png b/addons/rmsmartshape/documentation/imgs/NormalWrong.png
deleted file mode 100644
index 79c188e..0000000
Binary files a/addons/rmsmartshape/documentation/imgs/NormalWrong.png and /dev/null differ
diff --git a/addons/rmsmartshape/documentation/imgs/PluginActivate.png b/addons/rmsmartshape/documentation/imgs/PluginActivate.png
deleted file mode 100644
index 1a96705..0000000
Binary files a/addons/rmsmartshape/documentation/imgs/PluginActivate.png and /dev/null differ
diff --git a/addons/rmsmartshape/documentation/imgs/ShapeClosed-FillTextured.png b/addons/rmsmartshape/documentation/imgs/ShapeClosed-FillTextured.png
deleted file mode 100644
index d768f8e..0000000
Binary files a/addons/rmsmartshape/documentation/imgs/ShapeClosed-FillTextured.png and /dev/null differ
diff --git a/addons/rmsmartshape/documentation/imgs/ShapeClosed-Untextured.png b/addons/rmsmartshape/documentation/imgs/ShapeClosed-Untextured.png
deleted file mode 100644
index 275b25c..0000000
Binary files a/addons/rmsmartshape/documentation/imgs/ShapeClosed-Untextured.png and /dev/null differ
diff --git a/addons/rmsmartshape/documentation/imgs/Toolbar-PointEdit.png b/addons/rmsmartshape/documentation/imgs/Toolbar-PointEdit.png
deleted file mode 100644
index 8bc8b56..0000000
Binary files a/addons/rmsmartshape/documentation/imgs/Toolbar-PointEdit.png and /dev/null differ
diff --git a/addons/rmsmartshape/documentation/imgs/canvas-item-repeat.png b/addons/rmsmartshape/documentation/imgs/canvas-item-repeat.png
deleted file mode 100644
index 1045c52..0000000
Binary files a/addons/rmsmartshape/documentation/imgs/canvas-item-repeat.png and /dev/null differ
diff --git a/addons/rmsmartshape/documentation/imgs/faq-texture-repeat-import.png b/addons/rmsmartshape/documentation/imgs/faq-texture-repeat-import.png
deleted file mode 100644
index f5963d7..0000000
Binary files a/addons/rmsmartshape/documentation/imgs/faq-texture-repeat-import.png and /dev/null differ
diff --git a/addons/rmsmartshape/documentation/imgs/faq-texture-repeat.png b/addons/rmsmartshape/documentation/imgs/faq-texture-repeat.png
deleted file mode 100644
index 1ceedbf..0000000
Binary files a/addons/rmsmartshape/documentation/imgs/faq-texture-repeat.png and /dev/null differ
diff --git a/addons/rmsmartshape/documentation/imgs/godot4-assign-normal-tex.png b/addons/rmsmartshape/documentation/imgs/godot4-assign-normal-tex.png
deleted file mode 100644
index cc64e74..0000000
Binary files a/addons/rmsmartshape/documentation/imgs/godot4-assign-normal-tex.png and /dev/null differ
diff --git a/addons/rmsmartshape/documentation/imgs/godot4-create-texture-res.png b/addons/rmsmartshape/documentation/imgs/godot4-create-texture-res.png
deleted file mode 100644
index 4a0e417..0000000
Binary files a/addons/rmsmartshape/documentation/imgs/godot4-create-texture-res.png and /dev/null differ
diff --git a/addons/rmsmartshape/documentation/imgs/godot4-make-points-unique.png b/addons/rmsmartshape/documentation/imgs/godot4-make-points-unique.png
deleted file mode 100644
index 9b1e49d..0000000
Binary files a/addons/rmsmartshape/documentation/imgs/godot4-make-points-unique.png and /dev/null differ
diff --git a/addons/rmsmartshape/documentation/imgs/grass-corner-inner.png b/addons/rmsmartshape/documentation/imgs/grass-corner-inner.png
deleted file mode 100644
index 59c4705..0000000
Binary files a/addons/rmsmartshape/documentation/imgs/grass-corner-inner.png and /dev/null differ
diff --git a/addons/rmsmartshape/documentation/imgs/grass-corner-outer.png b/addons/rmsmartshape/documentation/imgs/grass-corner-outer.png
deleted file mode 100644
index 5aa5b59..0000000
Binary files a/addons/rmsmartshape/documentation/imgs/grass-corner-outer.png and /dev/null differ
diff --git a/addons/rmsmartshape/documentation/imgs/grass-taper-left.png b/addons/rmsmartshape/documentation/imgs/grass-taper-left.png
deleted file mode 100644
index c28f026..0000000
Binary files a/addons/rmsmartshape/documentation/imgs/grass-taper-left.png and /dev/null differ
diff --git a/addons/rmsmartshape/documentation/imgs/grass-taper-right.png b/addons/rmsmartshape/documentation/imgs/grass-taper-right.png
deleted file mode 100644
index c3803fc..0000000
Binary files a/addons/rmsmartshape/documentation/imgs/grass-taper-right.png and /dev/null differ
diff --git a/addons/rmsmartshape/documentation/imgs/grass.png b/addons/rmsmartshape/documentation/imgs/grass.png
deleted file mode 100644
index caa0420..0000000
Binary files a/addons/rmsmartshape/documentation/imgs/grass.png and /dev/null differ
diff --git a/addons/rmsmartshape/documentation/imgs/icon_edge.png b/addons/rmsmartshape/documentation/imgs/icon_edge.png
deleted file mode 100644
index e2e08d6..0000000
Binary files a/addons/rmsmartshape/documentation/imgs/icon_edge.png and /dev/null differ
diff --git a/addons/rmsmartshape/documentation/imgs/sample.gif b/addons/rmsmartshape/documentation/imgs/sample.gif
deleted file mode 100644
index 0e9064e..0000000
Binary files a/addons/rmsmartshape/documentation/imgs/sample.gif and /dev/null differ
diff --git a/addons/rmsmartshape/documentation/imgs/sample.png b/addons/rmsmartshape/documentation/imgs/sample.png
deleted file mode 100644
index bf47a3e..0000000
Binary files a/addons/rmsmartshape/documentation/imgs/sample.png and /dev/null differ
diff --git a/addons/rmsmartshape/documentation/imgs/smartshape_textures_breakdown.png b/addons/rmsmartshape/documentation/imgs/smartshape_textures_breakdown.png
deleted file mode 100644
index 36a7886..0000000
Binary files a/addons/rmsmartshape/documentation/imgs/smartshape_textures_breakdown.png and /dev/null differ
diff --git a/addons/rmsmartshape/editors/NormalRangeEditor/NormalRangeEditor.gd b/addons/rmsmartshape/editors/NormalRangeEditor/NormalRangeEditor.gd
deleted file mode 100644
index 89ef973..0000000
--- a/addons/rmsmartshape/editors/NormalRangeEditor/NormalRangeEditor.gd
+++ /dev/null
@@ -1,64 +0,0 @@
-@tool
-extends VBoxContainer
-class_name SS2D_NormalRangeEditor
-
-signal value_changed
-
-var start: float: get = _get_start, set = _set_start
-var end: float: get = _get_end, set = _set_end
-var zero_equals_full_circle := true
-
-var _progress_bar: TextureProgressBar:
- get:
- if _progress_bar == null:
- _progress_bar = get_node_or_null("%TextureProgressBar")
- return _progress_bar
-
-
-func _ready() -> void:
- _set_initial_angles()
-
-
-func _enter_tree() -> void:
- _set_initial_angles()
-
-
-func _set_initial_angles() -> void:
- _set_start(_progress_bar.radial_initial_angle)
- _set_end(_progress_bar.radial_fill_degrees)
-
-
-func _on_startSlider_value_changed(value: float) -> void:
- _set_start(value)
-
-
-func _on_endSlider_value_changed(value: float) -> void:
- _set_end(value)
-
-
-func _set_start(value: float) -> void:
- var fill: float = _progress_bar.radial_fill_degrees
- var init_angle: float = 360.0 - fill - value + 90.0
- _progress_bar.radial_initial_angle = _mutate_angle_deg(init_angle)
-
-
-func _get_start() -> float:
- return _progress_bar.radial_initial_angle
-
-
-func _set_end(value: float) -> void:
- _progress_bar.radial_fill_degrees = _mutate_angle_deg(value)
-
-
-func _get_end() -> float:
- return _progress_bar.radial_fill_degrees
-
-
-func _on_SS2D_StartEditorSpinSlider_value_changed(value: float) -> void:
- _set_start(value)
-
-
-func _mutate_angle_deg(v: float) -> float:
- if zero_equals_full_circle and v == 0.0:
- return 360.0
- return v
diff --git a/addons/rmsmartshape/editors/NormalRangeEditor/NormalRangeEditor.tscn b/addons/rmsmartshape/editors/NormalRangeEditor/NormalRangeEditor.tscn
deleted file mode 100644
index 37f4d4b..0000000
--- a/addons/rmsmartshape/editors/NormalRangeEditor/NormalRangeEditor.tscn
+++ /dev/null
@@ -1,32 +0,0 @@
-[gd_scene load_steps=5 format=3 uid="uid://cg1vy768oxwxr"]
-
-[ext_resource type="Texture2D" uid="uid://dajqljvjm2d2q" path="res://addons/rmsmartshape/editors/NormalRangeEditor/progress_texture.png" id="1"]
-[ext_resource type="Script" path="res://addons/rmsmartshape/editors/NormalRangeEditor/NormalRangeEditor.gd" id="2"]
-[ext_resource type="Texture2D" uid="uid://dgd4sbhsw1no3" path="res://addons/rmsmartshape/editors/NormalRangeEditor/over_texture.png" id="3"]
-[ext_resource type="Texture2D" uid="uid://cax163h05b60j" path="res://addons/rmsmartshape/editors/NormalRangeEditor/under_texture.png" id="4"]
-
-[node name="NormalRangeEditor" type="VBoxContainer"]
-anchors_preset = -1
-anchor_right = 0.087
-anchor_bottom = 0.027
-offset_right = 38.912
-offset_bottom = 203.8
-size_flags_horizontal = 3
-size_flags_vertical = 9
-script = ExtResource("2")
-
-[node name="CenterContainer" type="CenterContainer" parent="."]
-layout_mode = 2
-
-[node name="TextureProgressBar" type="TextureProgressBar" parent="CenterContainer"]
-unique_name_in_owner = true
-layout_mode = 2
-max_value = 1.0
-step = 0.0
-value = 1.0
-fill_mode = 4
-texture_under = ExtResource("4")
-texture_over = ExtResource("3")
-texture_progress = ExtResource("1")
-radial_initial_angle = 79.3
-radial_fill_degrees = 93.8
diff --git a/addons/rmsmartshape/editors/NormalRangeEditor/NormalRangeEditorProperty.gd b/addons/rmsmartshape/editors/NormalRangeEditor/NormalRangeEditorProperty.gd
deleted file mode 100644
index 6e28eac..0000000
--- a/addons/rmsmartshape/editors/NormalRangeEditor/NormalRangeEditorProperty.gd
+++ /dev/null
@@ -1,26 +0,0 @@
-extends EditorProperty
-class_name SS2D_NormalRangeEditorProperty
-
-var control: SS2D_NormalRangeEditor = preload(
- "res://addons/rmsmartshape/editors/NormalRangeEditor/NormalRangeEditor.tscn"
- ).instantiate()
-
-
-func _init() -> void:
- add_child(control)
- add_focusable(control)
-
-
-func _enter_tree() -> void:
- control.connect("value_changed", self._value_changed)
- _value_changed()
-
-
-func _exit_tree() -> void:
- control.disconnect("value_changed", self._value_changed)
-
-
-func _value_changed() -> void:
- var obj: SS2D_NormalRange = get_edited_object()
- control.end = obj.distance
- control.start = obj.begin
diff --git a/addons/rmsmartshape/editors/NormalRangeEditor/over_texture.png b/addons/rmsmartshape/editors/NormalRangeEditor/over_texture.png
deleted file mode 100644
index 7b47da6..0000000
Binary files a/addons/rmsmartshape/editors/NormalRangeEditor/over_texture.png and /dev/null differ
diff --git a/addons/rmsmartshape/editors/NormalRangeEditor/over_texture.png.import b/addons/rmsmartshape/editors/NormalRangeEditor/over_texture.png.import
deleted file mode 100644
index b8afe45..0000000
--- a/addons/rmsmartshape/editors/NormalRangeEditor/over_texture.png.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://dgd4sbhsw1no3"
-path="res://.godot/imported/over_texture.png-8aa46a605c51c9642f0609a4a8bbd43d.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://addons/rmsmartshape/editors/NormalRangeEditor/over_texture.png"
-dest_files=["res://.godot/imported/over_texture.png-8aa46a605c51c9642f0609a4a8bbd43d.ctex"]
-
-[params]
-
-compress/mode=0
-compress/high_quality=false
-compress/lossy_quality=0.7
-compress/hdr_compression=1
-compress/normal_map=0
-compress/channel_pack=0
-mipmaps/generate=false
-mipmaps/limit=-1
-roughness/mode=0
-roughness/src_normal=""
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/normal_map_invert_y=false
-process/hdr_as_srgb=false
-process/hdr_clamp_exposure=false
-process/size_limit=0
-detect_3d/compress_to=1
diff --git a/addons/rmsmartshape/editors/NormalRangeEditor/progress_texture.png b/addons/rmsmartshape/editors/NormalRangeEditor/progress_texture.png
deleted file mode 100644
index 1911c99..0000000
Binary files a/addons/rmsmartshape/editors/NormalRangeEditor/progress_texture.png and /dev/null differ
diff --git a/addons/rmsmartshape/editors/NormalRangeEditor/progress_texture.png.import b/addons/rmsmartshape/editors/NormalRangeEditor/progress_texture.png.import
deleted file mode 100644
index 6407be1..0000000
--- a/addons/rmsmartshape/editors/NormalRangeEditor/progress_texture.png.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://dajqljvjm2d2q"
-path="res://.godot/imported/progress_texture.png-5c3ce00c522dd3c8b7a6f676bd7a3382.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://addons/rmsmartshape/editors/NormalRangeEditor/progress_texture.png"
-dest_files=["res://.godot/imported/progress_texture.png-5c3ce00c522dd3c8b7a6f676bd7a3382.ctex"]
-
-[params]
-
-compress/mode=0
-compress/high_quality=false
-compress/lossy_quality=0.7
-compress/hdr_compression=1
-compress/normal_map=0
-compress/channel_pack=0
-mipmaps/generate=false
-mipmaps/limit=-1
-roughness/mode=0
-roughness/src_normal=""
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/normal_map_invert_y=false
-process/hdr_as_srgb=false
-process/hdr_clamp_exposure=false
-process/size_limit=0
-detect_3d/compress_to=1
diff --git a/addons/rmsmartshape/editors/NormalRangeEditor/under_texture.png b/addons/rmsmartshape/editors/NormalRangeEditor/under_texture.png
deleted file mode 100644
index b838714..0000000
Binary files a/addons/rmsmartshape/editors/NormalRangeEditor/under_texture.png and /dev/null differ
diff --git a/addons/rmsmartshape/editors/NormalRangeEditor/under_texture.png.import b/addons/rmsmartshape/editors/NormalRangeEditor/under_texture.png.import
deleted file mode 100644
index 9914330..0000000
--- a/addons/rmsmartshape/editors/NormalRangeEditor/under_texture.png.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://cax163h05b60j"
-path="res://.godot/imported/under_texture.png-87a243e17179ba2b162ef41ea65a8e51.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://addons/rmsmartshape/editors/NormalRangeEditor/under_texture.png"
-dest_files=["res://.godot/imported/under_texture.png-87a243e17179ba2b162ef41ea65a8e51.ctex"]
-
-[params]
-
-compress/mode=0
-compress/high_quality=false
-compress/lossy_quality=0.7
-compress/hdr_compression=1
-compress/normal_map=0
-compress/channel_pack=0
-mipmaps/generate=false
-mipmaps/limit=-1
-roughness/mode=0
-roughness/src_normal=""
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/normal_map_invert_y=false
-process/hdr_as_srgb=false
-process/hdr_clamp_exposure=false
-process/size_limit=0
-detect_3d/compress_to=1
diff --git a/addons/rmsmartshape/editors/action_property_inspector_plugin.gd b/addons/rmsmartshape/editors/action_property_inspector_plugin.gd
deleted file mode 100644
index cbb97b3..0000000
--- a/addons/rmsmartshape/editors/action_property_inspector_plugin.gd
+++ /dev/null
@@ -1,60 +0,0 @@
-extends EditorInspectorPlugin
-
-## This inspector plugin will show an Execute button for action properties in
-## SS2D_Shape.
-##
-## To add an action property export it with:
-##
-## @export_placeholder("ActionProperty") var ...
-##
-## Then, when an action is executed by user (by pressing an Execute button in inspector),
-## setter will be called with non-empty string:
-##
-## func _action_property_setter(value: String) -> void:
-## if value.size() > 0:
-## ## Action is executed
-##
-
-class ActionPropertyEditor:
- extends EditorProperty
-
- signal action_pressed
-
- var button: Button
-
- func _init() -> void:
- button = Button.new()
- button.text = "Execute"
- add_child(button)
- button.connect("pressed", func() -> void: emit_signal("action_pressed"))
-
- func _ready() -> void:
- button.icon = get_theme_icon("TextEditorPlay", "EditorIcons")
-
-
-func _can_handle(object: Object) -> bool:
- if object is SS2D_Shape:
- return true
- return false
-
-
-func _parse_property(
- object: Object,
- _type: Variant.Type,
- name: String,
- _hint_type: PropertyHint,
- hint_string: String,
- _usage_flags,
- _wide: bool
-) -> bool:
- if hint_string == "ActionProperty":
- var prop_editor := ActionPropertyEditor.new()
- add_property_editor(name, prop_editor)
- prop_editor.connect("action_pressed", self._on_action_pressed.bind(object, name))
- return true
- return false
-
-
-func _on_action_pressed(object: Object, prop_name: String) -> void:
- prints("Action executed:", prop_name.capitalize())
- object.set(prop_name, "executed")
diff --git a/addons/rmsmartshape/editors/normal_range_inspector_plugin.gd b/addons/rmsmartshape/editors/normal_range_inspector_plugin.gd
deleted file mode 100644
index 8678296..0000000
--- a/addons/rmsmartshape/editors/normal_range_inspector_plugin.gd
+++ /dev/null
@@ -1,45 +0,0 @@
-extends EditorInspectorPlugin
-
-var control: SS2D_NormalRangeEditorProperty = null
-
-
-func _can_handle(object: Object) -> bool:
- #if object is SS2D_NormalRange:
- # return true
- if object is SS2D_NormalRange:
- #Connect
- if not object.is_connected("changed", self._changed):
- object.connect("changed", self._changed.bind(object))
- return true
- else:
- #Disconnect
- if control != null:
- control = null
-
- if object.has_signal("changed"):
- if object.is_connected("changed", self._changed):
- object.disconnect("changed", self._changed)
- pass
-
- return false
-
-
-func _changed(_object: Object) -> void:
- control._value_changed()
-
-
-func _parse_property(
- _object: Object,
- _type: Variant.Type,
- name: String,
- _hint_type: PropertyHint,
- _hint_string: String,
- _usage_flags: int,
- _wide: bool
-) -> bool:
- if name == "edgeRendering":
- control = SS2D_NormalRangeEditorProperty.new()
- add_property_editor(" ", control)
- return true
- return false
-
diff --git a/addons/rmsmartshape/lib/tesselation_vertex_mapping.gd b/addons/rmsmartshape/lib/tesselation_vertex_mapping.gd
deleted file mode 100644
index 8336b02..0000000
--- a/addons/rmsmartshape/lib/tesselation_vertex_mapping.gd
+++ /dev/null
@@ -1,35 +0,0 @@
-extends RefCounted
-class_name SS2D_TesselationVertexMapping
-
-## Provides mappings from tesselated point indices to their corresponding vertex indices and vice-versa.
-
-var _t_point_idx_to_point_idx := PackedInt32Array()
-var _point_idx_to_t_points_idx: Array[PackedInt32Array] = []
-
-
-## Rebuild the mapping using the given tesselated points and vertices.
-func build(tesselated_points: PackedVector2Array, vertices: PackedVector2Array) -> void:
- _t_point_idx_to_point_idx.clear()
- _point_idx_to_t_points_idx.clear()
-
- var point_idx := -1
-
- for t_point_idx in tesselated_points.size():
- var next_point_idx := SS2D_PluginFunctionality.get_next_point_index_wrap_around(point_idx, vertices)
-
- if tesselated_points[t_point_idx] == vertices[next_point_idx]:
- point_idx = next_point_idx
- _point_idx_to_t_points_idx.push_back(PackedInt32Array())
-
- _t_point_idx_to_point_idx.push_back(point_idx)
- _point_idx_to_t_points_idx[point_idx].push_back(t_point_idx)
-
-
-## Returns the vertex index corresponding to the given tesselated point index
-func tess_to_vertex_index(tesselated_idx: int) -> int:
- return _t_point_idx_to_point_idx[tesselated_idx]
-
-
-## Returns a list of tesselated point indices corresponding to the given vertex index
-func vertex_to_tess_indices(vertex_idx: int) -> PackedInt32Array:
- return _point_idx_to_t_points_idx[vertex_idx]
diff --git a/addons/rmsmartshape/lib/tuple.gd b/addons/rmsmartshape/lib/tuple.gd
deleted file mode 100644
index aea5e3c..0000000
--- a/addons/rmsmartshape/lib/tuple.gd
+++ /dev/null
@@ -1,142 +0,0 @@
-@tool
-extends RefCounted
-class_name SS2D_IndexTuple
-
-## Provides utility functions for handling and storing indices of two related points using Vector2i.
-##
-## Index tuples are considered equal if their elements are equal, regardless of their order:
-## T(X, Y) <=> T(Y, X).
-##
-## For effectively working with containers, helper functions for arrays and dictionaries are
-## provided that implement the above behavior.
-
-## Returns the second tuple element that does not equal the given value.
-## Returns -1 if neither element matches.
-static func get_other_value(t: Vector2i, value: int) -> int:
- if t.x == value:
- return t.y
- elif t.y == value:
- return t.x
- return -1
-
-
-## Returns whether two tuples are equal. Two tuples are considered equal when both contain the same values regardless of order.
-static func are_equal(t1: Vector2i, t2: Vector2i) -> bool:
- return t1 == t2 or t1 == flip_elements(t2)
-
-
-## Returns true when the tuple contains the given value.
-static func has(t: Vector2i, value: int) -> bool:
- return t.x == value or t.y == value
-
-
-## Searches for an equal tuple in the given array and returns the index or -1 if not found.
-## Incorporates the equality behavior.
-static func array_find(tuple_array: Array[Vector2i], t: Vector2i) -> int:
- for i in tuple_array.size():
- if are_equal(tuple_array[i], t):
- return i
- return -1
-
-
-## Returns whether the given tuple exists in the given array.
-## Incorporates the equality behavior.
-static func array_has(tuple_array: Array[Vector2i], t: Vector2i) -> bool:
- return array_find(tuple_array, t) != -1
-
-
-## Returns a list indices to tuples that contain the given value.
-static func array_find_partial(tuple_array: Array[Vector2i], value: int) -> PackedInt32Array:
- var out := PackedInt32Array()
-
- for i in tuple_array.size():
- if tuple_array[i].x == value or tuple_array[i].y == value:
- out.push_back(i)
-
- return out
-
-
-## Transform the tuple into a normalized representation (elements in ascending order).
-## Same as sort_ascending() at the moment.
-## Useful in more optimized use-cases where certain assumptions can be made if all tuples share a
-## normalized representation.
-static func normalize_tuple(tuple: Vector2i) -> Vector2i:
- return sort_ascending(tuple)
-
-
-## Returns a tuple with elements in ascending order.
-static func sort_ascending(tuple: Vector2i) -> Vector2i:
- if tuple.x <= tuple.y:
- return tuple
- return flip_elements(tuple)
-
-
-
-## Returns a tuple with x and y components switched.
-static func flip_elements(tuple: Vector2i) -> Vector2i:
- return Vector2i(tuple.y, tuple.x)
-
-
-## Validates the keys of a dictionary to be correct tuple values and converts all Arrays to
-## corresponding Vector2i values.
-## Optionally also validates that values are of the given type.
-## Exists mostly for backwards compatibility to allow a seamless transition from Array to Vector2i tuples.
-static func dict_validate(dict: Dictionary, value_type: Variant = null) -> void:
- # TODO: Maybe don't use asserts but push_warning and return true if successful
- for key: Variant in dict.keys():
- var value: Variant = dict[key]
-
- if value_type != null:
- assert(is_instance_of(value, value_type), "Incorrect value type in dictionary: " + var_to_str(value))
-
- if key is Array or key is PackedInt32Array or key is PackedInt64Array:
- var converted := Vector2i(int(key[0]), int(key[1]))
- dict.erase(key)
- dict[converted] = value
- else:
- assert(key is Vector2i, "Invalid tuple representation: %s. Should be Vector2i." % var_to_str(key))
-
-
-## Get the value in a dictionary with the given tuple as key or a default value if it does not exist.
-## Incorporates the equality behavior.
-static func dict_get(dict: Dictionary, tuple: Vector2i, default: Variant = null) -> Variant:
- if dict.has(tuple):
- return dict[tuple]
- return dict.get(flip_elements(tuple), default)
-
-
-static func dict_has(dict: Dictionary, tuple: Vector2i) -> bool:
- return dict.has(tuple) or dict.has(flip_elements(tuple))
-
-
-static func dict_set(dict: Dictionary, tuple: Vector2i, value: Variant) -> void:
- dict[dict_get_key(dict, tuple)] = value
-
-
-## Removes the given entry from the dictionary. Returns true if a corresponding key existed, otherwise false.
-static func dict_erase(dict: Dictionary, tuple: Vector2i) -> bool:
- return dict.erase(dict_get_key(dict, tuple))
-
-
-## Checks if there is an existing key for the given tuple or its flipped variant and returns it.
-## If a key does not exist, returns the tuple as it is.
-## Usually this function does not need to be invoked manually, as helpers for dictionary and array access exist.
-static func dict_get_key(dict: Dictionary, tuple: Vector2i) -> Vector2i:
- if not dict.has(tuple):
- var flipped := flip_elements(tuple)
-
- if dict.has(flipped):
- return flipped
-
- return tuple
-
-
-## Returns a list of all dictionary keys (tuples) that contain the given value.
-static func dict_find_partial(dict: Dictionary, value: int) -> Array[Vector2i]:
- var out: Array[Vector2i] = []
-
- for t: Vector2i in dict.keys():
- if t.x == value or t.y == value:
- out.push_back(t)
-
- return out
diff --git a/addons/rmsmartshape/materials/edge_material.gd b/addons/rmsmartshape/materials/edge_material.gd
deleted file mode 100644
index 81f5fc7..0000000
--- a/addons/rmsmartshape/materials/edge_material.gd
+++ /dev/null
@@ -1,156 +0,0 @@
-@tool
-extends Resource
-class_name SS2D_Material_Edge
-
-## This material represents the set of textures used for a single edge.
-##
-## This consists of: [br]
-## - textures [br]
-## - corner_textures [br]
-## - taper_textures [br]
-
-## All variations of the main edge texture.[br]
-## _textures[0] is considered the "main" texture for the EdgeMaterial.[br][br]
-## [b]Note:[/b] Will be used to generate an icon representing an edge texture.[br]
-@export var textures: Array[Texture2D] = [] : set = _set_textures
-
-# Textures for the final left and right quad of the edge when the angle is steep
-@export var textures_corner_outer: Array[Texture2D] = [] : set = _set_textures_corner_outer
-@export var textures_corner_inner: Array[Texture2D] = [] : set = _set_textures_corner_inner
-
-# Textures for the final left and right quad of the edge when the angle is shallow
-# Named as such because the desired look is that the texture "tapers-off"
-@export var textures_taper_left: Array[Texture2D] = [] : set = _set_textures_taper_left
-@export var textures_taper_right: Array[Texture2D] = [] : set = _set_textures_taper_right
-
-## Textures that will be used for the sharp_corner_tapering feature
-@export var textures_taper_corner_left: Array[Texture2D] = [] : set = _set_textures_taper_corner_left
-@export var textures_taper_corner_right: Array[Texture2D] = [] : set = _set_textures_taper_corner_right
-
-## If the texture choice should be randomized instead of the choice by point setup
-@export var randomize_texture: bool = false : set = _set_randomize_texture
-## If corner textures should be used
-@export var use_corner_texture: bool = true : set = _set_use_corner
-## If taper textures should be used
-@export var use_taper_texture: bool = true : set = _set_use_taper
-
-## Whether squishing can occur when texture doesn't fit nicely into total length.
-enum FITMODE {SQUISH_AND_STRETCH, CROP}
-@export var fit_mode: FITMODE = FITMODE.SQUISH_AND_STRETCH : set = _set_fit_texture
-
-@export var material: Material = null : set = _set_material
-
-
-###########
-# SETTERS #
-###########
-func _set_textures(ta: Array[Texture2D]) -> void:
- textures = ta
- emit_changed()
-
-
-func _set_textures_corner_outer(a: Array[Texture2D]) -> void:
- textures_corner_outer = a
- emit_changed()
-
-
-func _set_textures_corner_inner(a: Array[Texture2D]) -> void:
- textures_corner_inner = a
- emit_changed()
-
-
-func _set_textures_taper_left(a: Array[Texture2D]) -> void:
- textures_taper_left = a
- emit_changed()
-
-
-func _set_textures_taper_right(a: Array[Texture2D]) -> void:
- textures_taper_right = a
- emit_changed()
-
-func _set_textures_taper_corner_left(a: Array[Texture2D]) -> void:
- textures_taper_corner_left = a
- emit_changed()
-
-func _set_textures_taper_corner_right(a: Array[Texture2D]) -> void:
- textures_taper_corner_right = a
- emit_changed()
-
-func _set_randomize_texture(b: bool) -> void:
- randomize_texture = b
- emit_changed()
-
-
-func _set_use_corner(b: bool) -> void:
- use_corner_texture = b
- emit_changed()
-
-
-func _set_use_taper(b: bool) -> void:
- use_taper_texture = b
- emit_changed()
-
-
-func _set_fit_texture(fitmode: FITMODE) -> void:
- fit_mode = fitmode
- emit_changed()
-
-
-func _set_material(m: Material) -> void:
- material = m
- emit_changed()
-
-
-###########
-# GETTERS #
-###########
-func get_texture(idx: int) -> Texture2D:
- return _get_element(idx, textures)
-
-
-func get_texture_corner_inner(idx: int) -> Texture2D:
- return _get_element(idx, textures_corner_inner)
-
-
-func get_texture_corner_outer(idx: int) -> Texture2D:
- return _get_element(idx, textures_corner_outer)
-
-
-func get_texture_taper_left(idx: int) -> Texture2D:
- return _get_element(idx, textures_taper_left)
-
-
-func get_texture_taper_right(idx: int) -> Texture2D:
- return _get_element(idx, textures_taper_right)
-
-
-func get_texture_taper_corner_left(idx: int) -> Texture2D:
- return _get_element(idx, textures_taper_corner_left)
-
-
-func get_texture_taper_corner_right(idx: int) -> Texture2D:
- return _get_element(idx, textures_taper_corner_right)
-
-
-#########
-# USAGE #
-#########
-
-## Returns main texture used to visually identify this edge material
-func get_icon_texture() -> Texture2D:
- if not textures.is_empty():
- return textures[0]
- return null
-
-
-############
-# INTERNAL #
-############
-func _get_element(idx: int, a: Array) -> Variant:
- if a.is_empty():
- return null
- return a[_adjust_idx(idx, a)]
-
-
-func _adjust_idx(idx: int, a: Array) -> int:
- return idx % a.size()
diff --git a/addons/rmsmartshape/materials/edge_material_metadata.gd b/addons/rmsmartshape/materials/edge_material_metadata.gd
deleted file mode 100644
index 2573188..0000000
--- a/addons/rmsmartshape/materials/edge_material_metadata.gd
+++ /dev/null
@@ -1,81 +0,0 @@
-@tool
-extends Resource
-class_name SS2D_Material_Edge_Metadata
-
-## Represents the metadata for an edge material.
-##
-## Used by Shape Material.
-
-@export var edge_material: SS2D_Material_Edge = null : set = set_edge_material
-## What range of normals can this edge be used on.
-@export var normal_range := SS2D_NormalRange.new(0, 360) : set = set_normal_range
-## If edge should be welded to the edges surrounding it.
-@export var weld: bool = true : set = set_weld
-## Whether or not the edges should use the taper corner textures and not be welded, if they are
-## too sharp to be welded without significant distortion. NOTE this will not work properly
-## in curved shapes
-@export var taper_sharp_corners: bool = false : set = set_taper_sharp_corners
-## If this edge should be visible.
-@export var render: bool = true : set = set_render
-## z index for an edge.
-@export var z_index: int = 0 : set = set_z_index
-## z index for an edge.
-@export var z_as_relative: bool = true : set = set_z_as_relative
-## Distance from center.
-@export_range (-1.5, 1.5, 0.1) var offset: float = 0.0 : set = set_offset
-
-
-func _to_string() -> String:
- return "%s | %s" % [str(edge_material), normal_range]
-
-
-func set_render(b: bool) -> void:
- render = b
- emit_changed()
-
-
-func set_edge_material(m: SS2D_Material_Edge) -> void:
- if edge_material != null:
- if edge_material.is_connected("changed", self._on_edge_changed):
- edge_material.disconnect("changed", self._on_edge_changed)
- edge_material = m
- if edge_material != null:
- edge_material.connect("changed", self._on_edge_changed)
- emit_changed()
-
-
-func set_normal_range(nr: SS2D_NormalRange) -> void:
- if nr == null:
- return
- if normal_range.is_connected("changed", self._on_edge_changed):
- normal_range.disconnect("changed", self._on_edge_changed)
- normal_range = nr
- normal_range.connect("changed", self._on_edge_changed)
- emit_changed()
-
-
-func set_weld(b: bool) -> void:
- weld = b
- emit_changed()
-
-func set_taper_sharp_corners(val: bool) -> void:
- taper_sharp_corners = val
- emit_changed()
-
-func set_z_index(z: int) -> void:
- z_index = z
- emit_changed()
-
-
-func set_z_as_relative(b: bool) -> void:
- z_as_relative = b
- emit_changed()
-
-
-func set_offset(f: float) -> void:
- offset = f
- emit_changed()
-
-
-func _on_edge_changed() -> void:
- emit_changed()
diff --git a/addons/rmsmartshape/materials/shape_material.gd b/addons/rmsmartshape/materials/shape_material.gd
deleted file mode 100644
index e77955c..0000000
--- a/addons/rmsmartshape/materials/shape_material.gd
+++ /dev/null
@@ -1,139 +0,0 @@
-@tool
-extends Resource
-class_name SS2D_Material_Shape
-
-## This material represents the set of edge materials used for a smart shape.
-##
-## Each edge represents a set of textures used to render an edge.
-
-## List of materials this shape can use.
-@export var _edge_meta_materials: Array[SS2D_Material_Edge_Metadata] = [] : set = set_edge_meta_materials
-@export var fill_textures: Array[Texture2D] = [] : set = set_fill_textures
-@export var fill_texture_z_index: int = -10 : set = set_fill_texture_z_index
-@export var fill_texture_show_behind_parent: bool = false : set = set_fill_texture_show_behind_parent
-
-## Scale the fill texture
-@export_range(0.1, 4, 0.01, "or_greater") var fill_texture_scale: float = 1.0 : set = set_fill_texture_scale
-
-## Whether the fill texture should start at the global 0/0 instead of the node's 0/0
-@export var fill_texture_absolute_position: bool = false : set = set_fill_texture_absolute_position
-
-## Whether the fill texture should ignore the node's rotation
-@export var fill_texture_absolute_rotation: bool = false : set = set_fill_texture_absolute_rotation
-
-## How many pixels the fill texture should be shifted in x and y direction
-@export var fill_texture_offset: Vector2 = Vector2.ZERO : set = set_fill_texture_offset
-
-## Added rotation of the texture in degrees
-@export_range(-180, 180, 0.1) var fill_texture_angle_offset: float = 0.0 : set = set_fill_texture_angle_offset
-
-@export var fill_mesh_offset: float = 0.0 : set = set_fill_mesh_offset
-@export var fill_mesh_material: Material = null : set = set_fill_mesh_material
-
-## How much to offset all edges
-@export_range (-1.5, 1.5, 0.1) var render_offset: float = 0.0 : set = set_render_offset
-
-
-func set_fill_mesh_material(m: Material) -> void:
- fill_mesh_material = m
- emit_changed()
-
-
-func set_fill_mesh_offset(f: float) -> void:
- fill_mesh_offset = f
- emit_changed()
-
-
-func set_render_offset(f: float) -> void:
- render_offset = f
- emit_changed()
-
-
-## Get all valid edge materials for this normal.
-func get_edge_meta_materials(normal: Vector2) -> Array[SS2D_Material_Edge_Metadata]:
- var materials: Array[SS2D_Material_Edge_Metadata] = []
- for e in _edge_meta_materials:
- if e == null:
- continue
- if e.normal_range.is_in_range(normal):
- materials.push_back(e)
- return materials
-
-
-func get_all_edge_meta_materials() -> Array[SS2D_Material_Edge_Metadata]:
- return _edge_meta_materials
-
-
-func get_all_edge_materials() -> Array[SS2D_Material_Edge]:
- var materials: Array[SS2D_Material_Edge] = []
- for meta in _edge_meta_materials:
- if meta.edge_material != null:
- materials.push_back(meta.edge_material)
- return materials
-
-
-func add_edge_material(e: SS2D_Material_Edge_Metadata) -> void:
- var new_array := _edge_meta_materials.duplicate()
- new_array.push_back(e)
- set_edge_meta_materials(new_array)
-
-
-func _on_edge_material_changed() -> void:
- emit_changed()
-
-
-func set_fill_textures(a: Array[Texture2D]) -> void:
- fill_textures = a
- emit_changed()
-
-
-func set_fill_texture_z_index(i: int) -> void:
- fill_texture_z_index = i
- emit_changed()
-
-
-func set_fill_texture_show_behind_parent(value: bool) -> void:
- fill_texture_show_behind_parent = value
- emit_changed()
-
-
-func set_edge_meta_materials(a: Array[SS2D_Material_Edge_Metadata]) -> void:
- for e in _edge_meta_materials:
- if e == null:
- continue
- if not a.has(e):
- e.disconnect("changed", self._on_edge_material_changed)
-
- for e in a:
- if e == null:
- continue
- if not e.is_connected("changed", self._on_edge_material_changed):
- e.connect("changed", self._on_edge_material_changed)
-
- _edge_meta_materials = a
- emit_changed()
-
-
-func set_fill_texture_offset(value: Vector2) -> void:
- fill_texture_offset = value
- emit_changed()
-
-
-func set_fill_texture_scale(value:float) -> void:
- fill_texture_scale = value
- emit_changed()
-
-
-func set_fill_texture_absolute_rotation(value: bool) -> void:
- fill_texture_absolute_rotation = value
- emit_changed()
-
-
-func set_fill_texture_angle_offset(value: float) -> void:
- fill_texture_angle_offset = value
- emit_changed()
-
-
-func set_fill_texture_absolute_position(value: bool) -> void:
- fill_texture_absolute_position = value
- emit_changed()
\ No newline at end of file
diff --git a/addons/rmsmartshape/normal_range.gd b/addons/rmsmartshape/normal_range.gd
deleted file mode 100644
index 195d2f3..0000000
--- a/addons/rmsmartshape/normal_range.gd
+++ /dev/null
@@ -1,99 +0,0 @@
-@tool
-extends Resource
-class_name SS2D_NormalRange
-
-## This class will determine if the normal of a vector falls within the specifed angle ranges.
-##
-## - if begin and end are equal, any angle is considered to be within range [br]
-## - 360.0 and 0.0 degrees are considered equivilent [br]
-
-@export_range (0, 360, 1) var begin: float = 0.0 : set = set_begin
-@export_range (0, 360, 1) var distance: float = 0.0 : set = set_distance
-
-# This is a hack to support the custom editor, needed a property
-# to exist to lock the TextureProgressBar to. Makes it flow better
-# in the Inspector.
-@export var edgeRendering: Vector2
-
-
-func set_distance(f: float) -> void:
- distance = f
- emit_changed()
-
-
-func set_begin(f: float) -> void:
- begin = f
- emit_changed()
-
-
-func _to_string() -> String:
- return "NormalRange: %s - %s" % [begin, begin + distance]
-
-
-static func get_angle_from_vector(vec: Vector2) -> float:
- var normal: Vector2 = vec.normalized()
- # With respect to the X-axis
- # This is how Vector2.angle() is calculated, best to keep it consistent
- var comparison_vector := Vector2(1, 0)
-
- var ab: Vector2 = normal
- var bc: Vector2 = comparison_vector
- var dot_prod: float = ab.dot(bc)
- var determinant: float = (ab.x * bc.y) - (ab.y * bc.x)
- var angle: float = atan2(determinant, dot_prod)
-
- # This angle has a range of 360 degrees
- # Is between 180 and - 180
- var deg: float = rad_to_deg(angle)
-
- # Get range between 0.0 and 360.0
- if deg < 0:
- deg = 360.0 + deg
- return deg
-
-
-# Get in range between 0.0 and 360.0.
-static func _get_positive_angle_deg(degrees: float) -> float:
- while degrees < 0:
- degrees += 360
- return fmod(degrees, 360.0)
-
-# Get in range between -360.0 and 360.0
-static func _get_signed_angle_deg(degrees: float) -> float:
- var new_degrees: float = degrees
- while absf(new_degrees) > 360.0:
- new_degrees += (360.0 * signf(degrees) * -1.0)
- return new_degrees
-
-
-# Saving a scene with this resource requires a parameter-less init method
-func _init(_begin: float = 0.0, _distance: float = 0.0) -> void:
- _begin = SS2D_NormalRange._get_signed_angle_deg(_begin)
- _distance = SS2D_NormalRange._get_signed_angle_deg(_distance)
-
- begin = _begin
- distance = _distance
-
-
-func is_in_range(vec: Vector2) -> bool:
- # A Distance of 0 or 360 is the entire circle
- if distance == 0 or SS2D_NormalRange._get_positive_angle_deg(distance) == 360.0:
- return true
-
- var begin_positive: float = SS2D_NormalRange._get_positive_angle_deg(begin)
- var end_positive: float = SS2D_NormalRange._get_positive_angle_deg(begin + distance)
- # If positive, counter clockwise direction
- # If negative, clockwise direction
- var direction: float = signf(distance)
- var angle: float = SS2D_NormalRange.get_angle_from_vector(vec)
-
- # Swap begin and end if direction is negative
- if direction == -1:
- var t: float = begin_positive
- begin_positive = end_positive
- end_positive = t
-
- if begin_positive < end_positive:
- return ((angle >= begin_positive) and (angle <= end_positive))
- else:
- return ((angle >= begin_positive) or (angle <= end_positive))
diff --git a/addons/rmsmartshape/plugin.cfg b/addons/rmsmartshape/plugin.cfg
deleted file mode 100644
index 92088d1..0000000
--- a/addons/rmsmartshape/plugin.cfg
+++ /dev/null
@@ -1,7 +0,0 @@
-[plugin]
-
-name="SmartShape2D"
-description="Tool to design nicely textured 2D polygons"
-author="Ryan Lloyd, Robert Morse, Guy Unger, Serhii Snitsaruk, Marvin Ewald"
-version="3.2.0"
-script="plugin.gd"
diff --git a/addons/rmsmartshape/plugin.gd b/addons/rmsmartshape/plugin.gd
deleted file mode 100644
index 69208e1..0000000
--- a/addons/rmsmartshape/plugin.gd
+++ /dev/null
@@ -1,1639 +0,0 @@
-@tool
-extends EditorPlugin
-
-
-## Common Abbreviations
-## et = editor transform (viewport's canvas transform)
-##
-## - Snapping using the build in functionality isn't going to happen
-## - https://github.com/godotengine/godot/issues/11180
-## - https://godotengine.org/qa/18051/tool-script-in-3-0
-
-# Icons
-# TODO: Change to const and preload when this is resolved:
-# https://github.com/godotengine/godot/issues/17483
-var ICON_HANDLE: Texture2D = load("res://addons/rmsmartshape/assets/icon_editor_handle.svg")
-var ICON_HANDLE_SELECTED: Texture2D = load("res://addons/rmsmartshape/assets/icon_editor_handle_selected.svg")
-var ICON_HANDLE_BEZIER: Texture2D = load("res://addons/rmsmartshape/assets/icon_editor_handle_bezier.svg")
-var ICON_HANDLE_CONTROL: Texture2D = load("res://addons/rmsmartshape/assets/icon_editor_handle_control.svg")
-var ICON_FREEHAND_MODE: Texture2D = load("res://addons/rmsmartshape/assets/freehand.png")
-var ICON_CIRCLE_ERASE: Texture2D = load("res://addons/rmsmartshape/assets/icon_editor_snap.svg")
-var ICON_ADD_HANDLE: Texture2D = load("res://addons/rmsmartshape/assets/icon_editor_handle_add.svg")
-var ICON_CURVE_EDIT: Texture2D = load("res://addons/rmsmartshape/assets/icon_curve_edit.svg")
-var ICON_CURVE_CREATE: Texture2D = load("res://addons/rmsmartshape/assets/icon_curve_create.svg")
-var ICON_CURVE_DELETE: Texture2D = load("res://addons/rmsmartshape/assets/icon_curve_delete.svg")
-var ICON_PIVOT_POINT: Texture2D = load("res://addons/rmsmartshape/assets/icon_editor_position.svg")
-var ICON_CENTER_PIVOT: Texture2D = load("res://addons/rmsmartshape/assets/CenterView.svg")
-var ICON_COLLISION: Texture2D = load("res://addons/rmsmartshape/assets/icon_collision_polygon_2d.svg")
-var ICON_INTERP_LINEAR: Texture2D = load("res://addons/rmsmartshape/assets/InterpLinear.svg")
-var ICON_SNAP: Texture2D = load("res://addons/rmsmartshape/assets/icon_editor_snap.svg")
-var ICON_IMPORT_CLOSED: Texture2D = load("res://addons/rmsmartshape/assets/closed_shape.png")
-var ICON_IMPORT_OPEN: Texture2D = load("res://addons/rmsmartshape/assets/open_shape.png")
-
-const FUNC = preload("plugin_functionality.gd")
-const ActionAddCollisionNodes := preload("res://addons/rmsmartshape/actions/action_add_collision_nodes.gd")
-const ActionMoveVerticies := preload("res://addons/rmsmartshape/actions/action_move_verticies.gd")
-const ActionSetPivot := preload("res://addons/rmsmartshape/actions/action_set_pivot.gd")
-const ActionMoveControlPoints := preload("res://addons/rmsmartshape/actions/action_move_control_points.gd")
-const ActionDeleteControlPoint := preload("res://addons/rmsmartshape/actions/action_delete_control_point.gd")
-const ActionDeletePoint := preload("res://addons/rmsmartshape/actions/action_delete_point.gd")
-const ActionAddPoint := preload("res://addons/rmsmartshape/actions/action_add_point.gd")
-const ActionSplitCurve := preload("res://addons/rmsmartshape/actions/action_split_curve.gd")
-const ActionMakeShapeUnique := preload("res://addons/rmsmartshape/actions/action_make_shape_unique.gd")
-const ActionCutEdge := preload("res://addons/rmsmartshape/actions/action_cut_edge.gd")
-const ActionCloseShape := preload("res://addons/rmsmartshape/actions/action_close_shape.gd")
-const ActionSplitShape := preload("res://addons/rmsmartshape/actions/action_split_shape.gd")
-
-enum MODE { EDIT_VERT, EDIT_EDGE, CUT_EDGE, SET_PIVOT, CREATE_VERT, FREEHAND }
-
-enum SNAP_MENU { ID_USE_GRID_SNAP, ID_SNAP_RELATIVE, ID_CONFIGURE_SNAP }
-enum OPTIONS_MENU { ID_DEFER_MESH_UPDATES }
-
-enum ACTION_VERT {
- NONE = 0,
- MOVE_VERT = 1,
- MOVE_CONTROL = 2,
- MOVE_CONTROL_IN = 3,
- MOVE_CONTROL_OUT = 4,
- MOVE_WIDTH_HANDLE = 5
-}
-
-
-# Data related to an action being taken on points
-class ActionDataVert:
- #Type of Action from the ACTION_VERT enum
- var type: ACTION_VERT = ACTION_VERT.NONE
- # The affected Verticies and their initial positions
- var keys: PackedInt32Array
- var starting_width: PackedFloat32Array
- var starting_positions: PackedVector2Array = []
- var starting_positions_control_in: PackedVector2Array = []
- var starting_positions_control_out: PackedVector2Array = []
-
- func _init(
- _keys: PackedInt32Array,
- positions: PackedVector2Array,
- positions_in: PackedVector2Array,
- positions_out: PackedVector2Array,
- width: PackedFloat32Array,
- t: ACTION_VERT
- ) -> void:
- type = t
- keys = _keys
- starting_positions = positions
- starting_positions_control_in = positions_in
- starting_positions_control_out = positions_out
- starting_width = width
-
- func are_verts_selected() -> bool:
- return keys.size() > 0
-
- func _to_string() -> String:
- return "%s: %s = %s" % [type, keys, starting_positions]
-
- func is_single_vert_selected() -> bool:
- return keys.size() == 1
-
- func current_point_key() -> int:
- if not is_single_vert_selected():
- return -1
- return keys[0]
-
- func current_point_index(s: SS2D_Shape) -> int:
- if not is_single_vert_selected():
- return -1
- return s.get_point_index(keys[0])
-
-
-# PRELOADS
-var GUI_SNAP_POPUP := preload("scenes/SnapPopup.tscn")
-var GUI_POINT_INFO_PANEL := preload("scenes/GUI_InfoPanel.tscn")
-var GUI_EDGE_INFO_PANEL := preload("scenes/GUI_Edge_InfoPanel.tscn")
-var gui_point_info_panel: SS2D_PointInfoPanel = GUI_POINT_INFO_PANEL.instantiate()
-var gui_edge_info_panel: SS2D_EdgeInfoPanel = GUI_EDGE_INFO_PANEL.instantiate()
-var gui_snap_settings: SS2D_SnapPopup = GUI_SNAP_POPUP.instantiate()
-
-const GUI_POINT_INFO_PANEL_OFFSET := Vector2(256, 130)
-
-# This is the shape node being edited
-var shape: SS2D_Shape = null
-
-# Toolbar Stuff
-var tb_hb: HBoxContainer = null
-var tb_vert_create: Button = null
-var tb_vert_edit: Button = null
-var tb_edge_edit: Button = null
-var tb_edge_cut: Button = null
-var tb_pivot: Button = null
-var tb_center_pivot: Button = null
-var tb_collision: Button = null
-var tb_freehand: Button = null
-var tb_button_group: ButtonGroup = null
-
-var tb_snap: MenuButton = null
-# The PopupMenu that belongs to tb_snap
-var tb_snap_popup: PopupMenu = null
-
-var tb_options: MenuButton = null
-var tb_options_popup: PopupMenu = null
-
-var make_unique_dialog: AcceptDialog
-
-# Edge Stuff
-var on_edge: bool = false
-var edge_point: Vector2
-var edge_data: SS2D_Edge = null
-
-# Width Handle Stuff
-var on_width_handle: bool = false
-const WIDTH_HANDLE_OFFSET: float = 60.0
-var closest_key: int
-var closest_edge_keys := Vector2i(-1, -1)
-var width_scaling: float
-
-# Vertex paint mode stuff
-var last_point_position: Vector2
-var _mouse_lmb_pressed := false
-var _mouse_rmb_pressed := false
-var freehand_paint_size := 20.0
-var freehand_erase_size := 40.0
-
-# Track our mode of operation
-var current_mode: int = MODE.CREATE_VERT
-var previous_mode: int = MODE.CREATE_VERT
-
-var current_action := ActionDataVert.new([], [], [], [], [], ACTION_VERT.NONE)
-var cached_shape_global_transform: Transform2D
-
-# Action Move Variables
-var _mouse_motion_delta_starting_pos := Vector2(0, 0)
-
-# Defining the viewport to get the current zoom/scale
-var target_viewport: Viewport
-var current_zoom_level : float = 1.0
-
-# Track the property plugin
-var plugin: EditorInspectorPlugin
-
-var is_2d_screen_active := false
-
-var _defer_mesh_updates := false
-
-#######
-# GUI #
-#######
-
-
-func gui_display_snap_settings() -> void:
- var pos := tb_snap.get_screen_position() + tb_snap.size
- pos.x -= (gui_snap_settings.size.x + tb_snap.size.x) / 2.0
- gui_snap_settings.position = pos
- gui_snap_settings.popup()
-
-
-func _snapping_item_selected(id: int) -> void:
- if id == SNAP_MENU.ID_USE_GRID_SNAP:
- tb_snap_popup.set_item_checked(id, not tb_snap_popup.is_item_checked(id))
- if id == SNAP_MENU.ID_SNAP_RELATIVE:
- tb_snap_popup.set_item_checked(id, not tb_snap_popup.is_item_checked(id))
- elif id == SNAP_MENU.ID_CONFIGURE_SNAP:
- gui_display_snap_settings()
-
-
-func _options_item_selected(id: int) -> void:
- if id == OPTIONS_MENU.ID_DEFER_MESH_UPDATES:
- tb_options_popup.set_item_checked(id, not tb_options_popup.is_item_checked(id))
- _defer_mesh_updates = tb_options_popup.is_item_checked(id)
-
-
-func _gui_build_toolbar() -> void:
- tb_hb = HBoxContainer.new()
- add_control_to_container(EditorPlugin.CONTAINER_CANVAS_EDITOR_MENU, tb_hb)
-
- var sep := VSeparator.new()
- tb_hb.add_child(sep)
-
- tb_button_group = ButtonGroup.new()
-
- tb_vert_create = create_tool_button(ICON_CURVE_CREATE, SS2D_Strings.EN_TOOLTIP_CREATE_VERT)
- tb_vert_create.connect(&"pressed", self._enter_mode.bind(MODE.CREATE_VERT))
- tb_vert_create.button_pressed = true
-
- tb_vert_edit = create_tool_button(ICON_CURVE_EDIT, SS2D_Strings.EN_TOOLTIP_EDIT_VERT)
- tb_vert_edit.connect(&"pressed", self._enter_mode.bind(MODE.EDIT_VERT))
-
- tb_edge_edit = create_tool_button(ICON_INTERP_LINEAR, SS2D_Strings.EN_TOOLTIP_EDIT_EDGE)
- tb_edge_edit.connect(&"pressed", self._enter_mode.bind(MODE.EDIT_EDGE))
-
- var edge_cut_icon: Texture2D = EditorInterface.get_base_control().get_theme_icon(&"ActionCut", &"EditorIcons")
- tb_edge_cut = create_tool_button(edge_cut_icon, SS2D_Strings.EN_TOOLTIP_CUT_EDGE)
- tb_edge_cut.connect(&"pressed", _enter_mode.bind(MODE.CUT_EDGE))
-
- tb_pivot = create_tool_button(ICON_PIVOT_POINT, SS2D_Strings.EN_TOOLTIP_PIVOT)
- tb_pivot.connect(&"pressed", self._enter_mode.bind(MODE.SET_PIVOT))
-
- tb_center_pivot = create_tool_button(ICON_CENTER_PIVOT, SS2D_Strings.EN_TOOLTIP_CENTER_PIVOT, false)
- tb_center_pivot.connect(&"pressed", self._center_pivot)
-
- tb_freehand = create_tool_button(ICON_FREEHAND_MODE, SS2D_Strings.EN_TOOLTIP_FREEHAND)
- tb_freehand.connect(&"pressed", self._enter_mode.bind(MODE.FREEHAND))
-
- tb_collision = create_tool_button(ICON_COLLISION, SS2D_Strings.EN_TOOLTIP_COLLISION, false)
- tb_collision.connect(&"pressed", self._add_collision)
-
- tb_snap = MenuButton.new()
- tb_snap.tooltip_text = SS2D_Strings.EN_TOOLTIP_SNAP
- tb_snap_popup = tb_snap.get_popup()
- tb_snap.icon = ICON_SNAP
- tb_snap_popup.add_check_item("Use Grid Snap", SNAP_MENU.ID_USE_GRID_SNAP)
- tb_snap_popup.add_check_item("Snap Relative", SNAP_MENU.ID_SNAP_RELATIVE)
- tb_snap_popup.add_separator()
- tb_snap_popup.add_item("Configure Snap...", SNAP_MENU.ID_CONFIGURE_SNAP)
- tb_snap_popup.hide_on_checkable_item_selection = false
- tb_hb.add_child(tb_snap)
- tb_snap_popup.connect("id_pressed", self._snapping_item_selected)
-
- tb_options = MenuButton.new()
- tb_options.tooltip_text = SS2D_Strings.EN_TOOLTIP_MORE_OPTIONS
- tb_options.icon = EditorInterface.get_base_control().get_theme_icon("GuiTabMenuHl", "EditorIcons")
- tb_options_popup = tb_options.get_popup()
- tb_options_popup.add_check_item(SS2D_Strings.EN_OPTIONS_DEFER_MESH_UPDATES, OPTIONS_MENU.ID_DEFER_MESH_UPDATES)
- tb_options_popup.hide_on_checkable_item_selection = false
- tb_hb.add_child(tb_options)
- tb_options_popup.connect("id_pressed", self._options_item_selected)
-
-
-func create_tool_button(icon: Texture2D, tooltip: String, toggle: bool = true) -> Button:
- var tb := Button.new()
- tb.toggle_mode = toggle
- tb.button_group = tb_button_group
- tb.theme_type_variation = "FlatButton"
- tb.focus_mode = Control.FocusMode.FOCUS_NONE
- tb.icon = icon
- tb.tooltip_text = tooltip
- tb_hb.add_child(tb)
- return tb
-
-
-func _gui_update_vert_info_panel() -> void:
- var idx: int = current_action.current_point_index(shape)
- var key: int = current_action.current_point_key()
- if not is_key_valid(key):
- gui_point_info_panel.visible = false
- return
- gui_point_info_panel.visible = true
- # Shrink panel
- gui_point_info_panel.size = Vector2(1, 1)
-
- var properties := shape.get_point_properties(key)
- gui_point_info_panel.set_idx(idx)
- gui_point_info_panel.set_texture_idx(properties.texture_idx)
- gui_point_info_panel.set_width(properties.width)
- gui_point_info_panel.set_flip(properties.flip)
-
-
-func _load_config() -> void:
- var conf := ConfigFile.new()
- conf.load(EditorInterface.get_editor_paths().get_project_settings_dir().path_join("ss2d.cfg"))
- _defer_mesh_updates = conf.get_value("options", "defer_mesh_updates", false)
- tb_options_popup.set_item_checked(OPTIONS_MENU.ID_DEFER_MESH_UPDATES, _defer_mesh_updates)
- tb_snap_popup.set_item_checked(SNAP_MENU.ID_USE_GRID_SNAP, conf.get_value("options", "use_grid_snap", false))
- tb_snap_popup.set_item_checked(SNAP_MENU.ID_SNAP_RELATIVE, conf.get_value("options", "snap_relative", false))
-
-
-func _save_config() -> void:
- var conf := ConfigFile.new()
- conf.set_value("options", "defer_mesh_updates", _defer_mesh_updates)
- conf.set_value("options", "use_grid_snap", tb_snap_popup.is_item_checked(SNAP_MENU.ID_USE_GRID_SNAP))
- conf.set_value("options", "snap_relative", tb_snap_popup.is_item_checked(SNAP_MENU.ID_SNAP_RELATIVE))
- conf.save(EditorInterface.get_editor_paths().get_project_settings_dir().path_join("ss2d.cfg"))
-
-
-func _process(_delta: float) -> void:
- if current_mode == MODE.FREEHAND:
- current_zoom_level = get_canvas_scale()
-
-
-func get_canvas_scale() -> float:
- get_current_viewport()
- if target_viewport:
- return target_viewport.global_canvas_transform.x.x
- else:
- return 1.0
-
-
-func get_current_viewport() -> void:
- if !get_tree().get_edited_scene_root():
- return
- var editor_viewport: Node = get_tree().get_edited_scene_root().get_parent()
-
- if editor_viewport is SubViewport:
- target_viewport = editor_viewport
- elif editor_viewport is SubViewportContainer:
- target_viewport = get_tree().get_edited_scene_root()
- else:
- target_viewport = editor_viewport.get_parent()
-
-
-func _gui_update_edge_info_panel() -> void:
- # Don't update if already visible
- if gui_edge_info_panel.visible:
- return
- var indicies := Vector2i(-1, -1)
- var override: SS2D_Material_Edge_Metadata = null
- if on_edge:
- var t: Transform2D = get_et() * shape.get_global_transform()
- var offset: float = shape.get_closest_offset_straight_edge(t.affine_inverse() * edge_point)
- var keys: Vector2i = _get_edge_point_keys_from_offset(offset, true)
- indicies = Vector2i(shape.get_point_index(keys.x), shape.get_point_index(keys.y))
- if shape.get_point_array().has_material_override(keys):
- override = shape.get_point_array().get_material_override(keys)
- gui_edge_info_panel.set_indicies(indicies)
- if override != null:
- gui_edge_info_panel.set_material_override(true)
- gui_edge_info_panel.load_values_from_meta_material(override)
- else:
- gui_edge_info_panel.set_material_override(false)
-
- # Shrink panel to minimum size
- gui_edge_info_panel.size = Vector2(1, 1)
-
-
-func _gui_update_info_panels() -> void:
- if not is_2d_screen_active:
- _gui_hide_info_panels()
- return
- match current_mode:
- MODE.EDIT_VERT:
- _gui_update_vert_info_panel()
- gui_edge_info_panel.visible = false
- MODE.EDIT_EDGE:
- _gui_update_edge_info_panel()
- gui_point_info_panel.visible = false
- _:
- gui_point_info_panel.visible = false
- gui_edge_info_panel.visible = false
-
-
-func _gui_hide_info_panels() -> void:
- gui_edge_info_panel.visible = false
- gui_point_info_panel.visible = false
-
-#########
-# GODOT #
-#########
-
-
-# Called when saving
-# https://docs.godotengine.org/en/3.2/classes/class_editorplugin.html?highlight=switch%20scene%20tab
-func _apply_changes() -> void:
- gui_point_info_panel.visible = false
- gui_edge_info_panel.visible = false
-
-
-func _init() -> void:
- pass
-
-
-func _ready() -> void:
- # Support the undo-redo actions
- _gui_build_toolbar()
- _load_config()
- add_child(gui_point_info_panel)
- gui_point_info_panel.visible = false
- add_child(gui_edge_info_panel)
- gui_edge_info_panel.visible = false
- gui_edge_info_panel.connect("material_override_toggled", self._on_edge_material_override_toggled)
- gui_edge_info_panel.connect("render_toggled", self._on_edge_material_override_render_toggled)
- gui_edge_info_panel.connect("weld_toggled", self._on_edge_material_override_weld_toggled)
- gui_edge_info_panel.connect("z_index_changed", self._on_edge_material_override_z_index_changed)
- gui_edge_info_panel.connect("edge_material_changed", self._on_edge_material_changed)
- add_child(gui_snap_settings)
- gui_snap_settings.hide()
-
- make_unique_dialog = AcceptDialog.new()
- make_unique_dialog.title = "Make Shape Unique"
- make_unique_dialog.get_label().text = "Make shape point geometry unique (not materials). Proceed?"
- make_unique_dialog.get_ok_button().text = "Proceed"
- make_unique_dialog.add_cancel_button("Cancel")
- make_unique_dialog.theme = EditorInterface.get_base_control().theme
- make_unique_dialog.connect("confirmed", self._shape_make_unique)
- add_child(make_unique_dialog)
-
- connect("main_screen_changed", self._on_main_screen_changed)
-
-
-func _enter_tree() -> void:
- @warning_ignore("unsafe_method_access")
- plugin = load("res://addons/rmsmartshape/editors/normal_range_inspector_plugin.gd").new()
- if plugin != null:
- add_inspector_plugin(plugin)
-
- @warning_ignore("unsafe_method_access")
- var action_plugin: EditorInspectorPlugin = load("res://addons/rmsmartshape/editors/action_property_inspector_plugin.gd").new()
- if action_plugin != null:
- add_inspector_plugin(action_plugin)
-
-
-func _exit_tree() -> void:
- if (plugin != null):
- remove_inspector_plugin(plugin)
-
- _save_config()
-
- gui_point_info_panel.visible = false
- gui_edge_info_panel.visible = false
- remove_control_from_container(EditorPlugin.CONTAINER_CANVAS_EDITOR_MENU, tb_hb)
- tb_hb.queue_free()
-
-
-func _forward_canvas_gui_input(event: InputEvent) -> bool:
- if not is_shape_valid():
- return false
-
- # Force update if global transforma has been changed
- if cached_shape_global_transform != shape.get_global_transform():
- shape.set_as_dirty()
- cached_shape_global_transform = shape.get_global_transform()
-
- var et: Transform2D = get_et()
- var grab_threshold: float = EditorInterface.get_editor_settings().get(
- "editors/polygon_editor/point_grab_radius"
- )
-
- var key_return_value := false
- if event is InputEventKey:
- key_return_value = _input_handle_keyboard_event(event)
-
- var mb_return_value := false
- if event is InputEventMouseButton:
- mb_return_value = _input_handle_mouse_button_event(event, et, grab_threshold)
-
- var mm_return_value := false
- if event is InputEventMouseMotion:
- mb_return_value = _input_handle_mouse_motion_event(event, et, grab_threshold)
-
- var return_value := key_return_value == true or mb_return_value == true or mm_return_value == true
- _gui_update_info_panels()
- return return_value
-
-
-func _handles(object: Object) -> bool:
- var hideToolbar: bool = true
-
- update_overlays()
- gui_point_info_panel.visible = false
- gui_edge_info_panel.visible = false
-
- var selection: EditorSelection = EditorInterface.get_selection()
- if selection != null:
- if selection.get_selected_nodes().size() == 1:
- if selection.get_selected_nodes()[0] is SS2D_Shape:
- hideToolbar = false
-
- if hideToolbar == true:
- tb_hb.hide()
-
- if object is Resource:
- return false
-
- return object is SS2D_Shape
-
-
-func _edit(object: Object) -> void:
- on_edge = false
- deselect_verts()
- if is_shape_valid():
- disconnect_shape(shape)
-
- shape = object
-
- if not is_shape_valid():
- gui_point_info_panel.visible = false
- gui_edge_info_panel.visible = false
- shape = null
- else:
- connect_shape(shape)
-
- if shape.get_point_array().get_point_count() == 0:
- _enter_mode(MODE.CREATE_VERT)
- elif current_mode == MODE.CREATE_VERT:
- _enter_mode(MODE.EDIT_VERT)
-
- update_overlays()
-
-
-func _make_visible(visible: bool) -> void:
- if visible:
- tb_hb.show()
- else:
- tb_hb.hide()
-
-
-
-func _on_main_screen_changed(screen_name: String) -> void:
- is_2d_screen_active = screen_name == "2D"
- if not is_2d_screen_active:
- _gui_hide_info_panels()
-
-
-############
-# SNAPPING #
-############
-func use_global_snap() -> bool:
- return not tb_snap_popup.is_item_checked(SNAP_MENU.ID_SNAP_RELATIVE)
-
-
-func use_snap() -> bool:
- return tb_snap_popup.is_item_checked(SNAP_MENU.ID_USE_GRID_SNAP)
-
-
-func get_snap_offset() -> Vector2:
- return gui_snap_settings.get_snap_offset()
-
-
-func get_snap_step() -> Vector2:
- return gui_snap_settings.get_snap_step()
-
-
-func snap(v: Vector2, force: bool = false) -> Vector2:
- if not use_snap() and not force:
- return v
- var step: Vector2 = get_snap_step()
- var offset: Vector2 = get_snap_offset()
- var t := Transform2D.IDENTITY
- if use_global_snap():
- t = shape.get_global_transform()
- return SS2D_PluginFunctionality.snap_position(v, offset, step, t)
-
-
-##########
-# PLUGIN #
-##########
-
-func disconnect_shape(s: SS2D_Shape) -> void:
- if s.is_connected("make_unique_pressed", self._on_shape_make_unique):
- s.disconnect("make_unique_pressed", self._on_shape_make_unique)
-
-
-func connect_shape(s: SS2D_Shape) -> void:
- if not s.is_connected("make_unique_pressed", self._on_shape_make_unique):
- s.connect("make_unique_pressed", self._on_shape_make_unique)
-
-
-func get_material_override_from_indicies() -> SS2D_Material_Edge_Metadata:
- var keys := shape.get_point_array().get_edge_keys_for_indices(gui_edge_info_panel.indicies)
- return shape.get_point_array().get_material_override(keys)
-
-
-func _on_edge_material_override_render_toggled(enabled: bool) -> void:
- var override := get_material_override_from_indicies()
- if override != null:
- override.render = enabled
-
-
-func _on_edge_material_override_weld_toggled(enabled: bool) -> void:
- var override := get_material_override_from_indicies()
- if override != null:
- override.weld = enabled
-
-
-func _on_edge_material_override_z_index_changed(z: int) -> void:
- var override := get_material_override_from_indicies()
- if override != null:
- override.z_index = z
-
-
-func _on_edge_material_changed(m: SS2D_Material_Edge) -> void:
- var override := get_material_override_from_indicies()
- if override != null:
- override.edge_material = m
-
-
-func _on_edge_material_override_toggled(enabled: bool) -> void:
- var indices := gui_edge_info_panel.indicies
-
- if SS2D_IndexTuple.has(indices, -1):
- return
-
- var keys := shape.get_point_array().get_edge_keys_for_indices(indices)
-
- # Get the relevant Override data if any exists
- var override: SS2D_Material_Edge_Metadata = shape.get_point_array().get_material_override(keys)
-
- if enabled:
- if override == null:
- override = SS2D_Material_Edge_Metadata.new()
- override.edge_material = null
- shape.get_point_array().set_material_override(keys, override)
-
- # Load override data into the info panel
- gui_edge_info_panel.load_values_from_meta_material(override)
- else:
- if override != null:
- shape.get_point_array().remove_material_override(keys)
-
-
-func is_shape_valid() -> bool:
- if shape == null:
- return false
- if not is_instance_valid(shape):
- return false
- if not shape.is_inside_tree():
- return false
- return true
-
-
-func _on_shape_make_unique(_shape: SS2D_Shape) -> void:
- make_unique_dialog.popup_centered()
-
-
-func _shape_make_unique() -> void:
- perform_action(ActionMakeShapeUnique.new(shape))
-
-
-func get_et() -> Transform2D:
- return EditorInterface.get_edited_scene_root().get_viewport().global_canvas_transform
-
-
-func is_key_valid(key: int) -> bool:
- if not is_shape_valid():
- return false
- return shape.has_point(key)
-
-
-func _enter_mode(mode: int) -> void:
- if current_mode == mode:
- return
-
- for tb: Button in [tb_vert_edit, tb_edge_edit, tb_pivot, tb_center_pivot, tb_vert_create, tb_freehand]:
- tb.button_pressed = false
-
- previous_mode = current_mode
- current_mode = mode
- match mode:
- MODE.CREATE_VERT:
- tb_vert_create.button_pressed = true
- MODE.EDIT_VERT:
- tb_vert_edit.button_pressed = true
- MODE.EDIT_EDGE:
- tb_edge_edit.button_pressed = true
- MODE.CUT_EDGE:
- tb_edge_cut.button_pressed = true
- MODE.SET_PIVOT:
- tb_pivot.button_pressed = true
- MODE.FREEHAND:
- tb_freehand.button_pressed = true
- _:
- tb_vert_edit.button_pressed = true
-
- update_overlays()
-
-
-func _add_collision() -> void:
- call_deferred("_add_deferred_collision")
-
-
-func _add_deferred_collision() -> void:
- if shape and not shape.get_parent() is PhysicsBody2D:
- perform_action(ActionAddCollisionNodes.new(shape))
-
-
-func _center_pivot() -> void:
- if shape and shape.is_shape_closed():
- # Calculate centroid
- var points: PackedVector2Array = shape.get_tessellated_points()
- var point_count: int = points.size()
- var total_area: float = 0.0
- var center: Vector2 = Vector2.ZERO
- for i in range(point_count):
- var pt1: Vector2 = points[i]
- var pt2: Vector2
- if i == point_count - 1:
- pt2 = points[0]
- else:
- pt2 = points[i + 1]
-
- var triangle_area: float = pt1.cross(pt2)
- total_area += triangle_area
- center += (pt1 + pt2) * triangle_area
-
- if total_area != 0.0:
- center /= 3 * total_area
-
- perform_action(ActionSetPivot.new(shape, shape.to_global(center)))
-
-#############
-# RENDERING #
-#############
-
-func _forward_canvas_draw_over_viewport(overlay: Control) -> void:
- # Something might force a draw which we had no control over,
- # in this case do some updating to be sure
- if not is_shape_valid() or not is_inside_tree():
- return
-
- match current_mode:
- MODE.CREATE_VERT:
- draw_mode_edit_vert(overlay)
- if Input.is_key_pressed(KEY_ALT) and Input.is_key_pressed(KEY_SHIFT):
- draw_new_shape_preview(overlay)
- elif Input.is_key_pressed(KEY_ALT):
- draw_new_point_close_preview(overlay)
- else:
- draw_new_point_preview(overlay)
- MODE.EDIT_VERT:
- draw_mode_edit_vert(overlay)
- if Input.is_key_pressed(KEY_ALT):
- if Input.is_key_pressed(KEY_SHIFT):
- draw_new_shape_preview(overlay)
- elif not on_edge:
- draw_new_point_close_preview(overlay)
- MODE.EDIT_EDGE:
- draw_mode_edit_edge(overlay, Color.WHITE, Color.YELLOW)
- MODE.CUT_EDGE:
- draw_mode_cut_edge(overlay)
- MODE.FREEHAND:
- if not _mouse_lmb_pressed:
- draw_new_point_close_preview(overlay)
- draw_freehand_circle(overlay)
- draw_mode_edit_vert(overlay, false)
-
-
-func draw_freehand_circle(overlay: Control) -> void:
- var mouse: Vector2 = overlay.get_local_mouse_position()
- var size: float = freehand_paint_size
- var color := Color.WHITE
- if Input.is_key_pressed(KEY_CTRL):
- color = Color.RED
- size = freehand_erase_size
- color.a = 0.5
- overlay.draw_arc(mouse, size * 2 * current_zoom_level, 0, TAU, 64, color, 1, true)
- color.a = 0.05
- overlay.draw_circle(mouse, size * 2 * current_zoom_level, color)
-
-
-func draw_mode_edit_edge(overlay: Control, color_normal: Color, color_highlight: Color) -> void:
- var t: Transform2D = get_et() * shape.get_global_transform()
- var verts: PackedVector2Array = shape.get_vertices()
-
- draw_shape_outline(overlay, t, verts, color_normal)
- draw_vert_handles(overlay, t, verts, false)
-
- if current_action.type == ACTION_VERT.MOVE_VERT:
- var edge_point_keys := current_action.keys
- var p1: Vector2 = shape.get_point_position(edge_point_keys[0])
- var p2: Vector2 = shape.get_point_position(edge_point_keys[1])
- overlay.draw_line(t * p1, t * p2, Color.BLACK, 8.0, true)
- overlay.draw_line(t * p1, t * p2, color_highlight, 4.0, true)
- elif on_edge:
- var offset: float = shape.get_closest_offset_straight_edge(t.affine_inverse() * edge_point)
- var edge_point_keys := _get_edge_point_keys_from_offset(offset, true)
- var p1: Vector2 = shape.get_point_position(edge_point_keys.x)
- var p2: Vector2 = shape.get_point_position(edge_point_keys.y)
- overlay.draw_line(t * p1, t * p2, Color.BLACK, 8.0, true)
- overlay.draw_line(t * p1, t * p2, color_highlight, 4.0, true)
-
-
-func draw_mode_cut_edge(overlay: Control) -> void:
- draw_mode_edit_edge(overlay, Color(1.0, 0.25, 0.25, 0.8), Color(1.0, 0.75, 0.75, 1.0))
-
- if on_edge:
- # Draw "X" marks along the edge that is selected
- var t: Transform2D = get_et() * shape.get_global_transform()
- var offset: float = shape.get_closest_offset_straight_edge(t.affine_inverse() * edge_point)
- var edge_point_keys := _get_edge_point_keys_from_offset(offset, true)
- var from: Vector2 = t * shape.get_point_position(edge_point_keys.x)
- var to: Vector2 = t * shape.get_point_position(edge_point_keys.y)
- var dir: Vector2 = (to - from).normalized()
- var angle: float = dir.angle()
- var length: float = (to - from).length()
- var num_crosses := remap(length, 0.0, 2000.0, 0.0, 10.0)
- @warning_ignore("narrowing_conversion")
- num_crosses = snappedi(num_crosses, 2.0) + 1
- var fraction := 1.0 / (num_crosses + 1)
- for i in num_crosses:
- var pos: Vector2 = from + dir * length * fraction * (i + 1)
- overlay.draw_line(Vector2(8.0, 8.0).rotated(angle) + pos,
- Vector2(-8.0, -8.0).rotated(angle) + pos, Color.RED, 3.0, true)
- overlay.draw_line(Vector2(-8.0, 8.0).rotated(angle) + pos,
- Vector2(8.0, -8.0).rotated(angle) + pos, Color.RED, 3.0, true)
-
-
-func draw_mode_edit_vert(overlay: Control, show_vert_handles: bool = true) -> void:
- var t: Transform2D = get_et() * shape.get_global_transform()
- var verts: PackedVector2Array = shape.get_vertices()
- var points: PackedVector2Array = shape.get_tessellated_points()
- draw_shape_outline(overlay, t, points, shape.modulate)
- if show_vert_handles:
- draw_vert_handles(overlay, t, verts, true)
- if on_edge:
- overlay.draw_texture(ICON_ADD_HANDLE, edge_point - ICON_ADD_HANDLE.get_size() * 0.5)
-
- # Draw Highlighted Handle
- if current_action.is_single_vert_selected():
- var tex: Texture2D = ICON_HANDLE_SELECTED
- overlay.draw_texture(
- tex, t * verts[current_action.current_point_index(shape)] - tex.get_size() * 0.5
- )
-
-
-func draw_shape_outline(
- overlay: Control, t: Transform2D, points: PackedVector2Array, color: Color, width: float = 2.0
-) -> void:
- if points.size() >= 2:
- overlay.draw_polyline(t * points, Color.BLACK, width * 1.5, true)
- overlay.draw_polyline(t * points, color, width, true)
-
-
-func draw_vert_handles(
- overlay: Control, t: Transform2D, verts: PackedVector2Array, control_points: bool
-) -> void:
- var transformed_verts := t * verts
- for i in verts.size():
- # Draw Vert handles
- var hp: Vector2 = transformed_verts[i]
- var icon: Texture2D = ICON_HANDLE_BEZIER if (Input.is_key_pressed(KEY_SHIFT) and not current_mode == MODE.FREEHAND) else ICON_HANDLE
- overlay.draw_texture(icon, hp - icon.get_size() * 0.5)
-
- # Draw Width handle
- var offset: float = WIDTH_HANDLE_OFFSET
- var width_handle_key: int = closest_key
- if (
- Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT)
- and current_action.type == ACTION_VERT.MOVE_WIDTH_HANDLE
- ):
- offset *= width_scaling
- width_handle_key = current_action.keys[0]
-
- var point_index: int = shape.get_point_index(width_handle_key)
- if point_index == -1:
- return
-
- var width_handle_normal: Vector2 = _get_vert_normal(t, verts, point_index)
- var vertex_position: Vector2 = t * shape.get_point_position(width_handle_key)
- var icon_position: Vector2 = vertex_position + width_handle_normal * offset
- var size: Vector2 = Vector2.ONE * 10.0
- var width_handle_color := Color("f53351")
- overlay.draw_line(vertex_position, icon_position, width_handle_color, 1.0)
- overlay.draw_set_transform(icon_position, width_handle_normal.angle(), Vector2.ONE)
- overlay.draw_rect(Rect2(-size / 2.0, size), width_handle_color, true)
- overlay.draw_set_transform(Vector2.ZERO, 0, Vector2.ONE)
-
- # Draw Control point handles
- if control_points:
- for i in verts.size():
- var key: int = shape.get_point_key_at_index(i)
- var hp: Vector2 = transformed_verts[i]
-
- # Drawing the point-out for the last point makes no sense, as there's no point ahead of it
- if i < verts.size() - 1:
- var pointout: Vector2 = t * (verts[i] + shape.get_point_out(key))
- if hp != pointout:
- _draw_control_point_line(overlay, hp, pointout, ICON_HANDLE_CONTROL)
- # Drawing the point-in for point 0 makes no sense, as there's no point behind it
- if i > 0:
- var pointin: Vector2 = t * (verts[i] + shape.get_point_in(key))
- if hp != pointin:
- _draw_control_point_line(overlay, hp, pointin, ICON_HANDLE_CONTROL)
-
-
-func _draw_control_point_line(c: Control, vert: Vector2, cp: Vector2, tex: Texture2D) -> void:
- # Draw the line with a dark and light color to be visible on all backgrounds
- var color_dark := Color(0, 0, 0, 0.3)
- var color_light := Color(1, 1, 1, .5)
- var width := 2.0
- var normal := (cp - vert).normalized()
- c.draw_line(vert + normal * 4 + Vector2.DOWN, cp + Vector2.DOWN, color_dark, width)
- c.draw_line(vert + normal * 4, cp, color_light, width)
- c.draw_texture(tex, cp - tex.get_size() * 0.5)
-
-
-func draw_new_point_preview(overlay: Control) -> void:
- # Draw lines to where a new point will be added
- var verts: PackedVector2Array = shape.get_vertices()
- var t: Transform2D = get_et() * shape.get_global_transform()
- var color := Color(1, 1, 1, .5)
- var width := 2.0
- var mouse: Vector2 = overlay.get_local_mouse_position()
-
- if verts.size() > 0:
- var a: Vector2
- if shape.is_shape_closed() and verts.size() > 1:
- a = t * verts[verts.size() - 2]
- overlay.draw_line(mouse, t * verts[0], color,width * .5)
- else:
- a = t * verts[verts.size() - 1]
- overlay.draw_line(mouse, a, color, width)
-
- overlay.draw_texture(ICON_ADD_HANDLE, mouse - ICON_ADD_HANDLE.get_size() * 0.5)
-
-
-func draw_new_point_close_preview(overlay: Control) -> void:
- # Draw lines to where a new point will be added
- var t: Transform2D = get_et() * shape.get_global_transform()
- var color := Color(1, 1, 1, .5)
- var width := 2.0
-
- var mouse: Vector2 = overlay.get_local_mouse_position()
- var a: Vector2 = t * shape.get_point_position(closest_edge_keys[0])
- var b: Vector2 = t * shape.get_point_position(closest_edge_keys[1])
- overlay.draw_line(mouse, a, color, width)
- color.a = 0.1
- overlay.draw_line(mouse, b, color, width)
- overlay.draw_texture(ICON_ADD_HANDLE, mouse - ICON_ADD_HANDLE.get_size() * 0.5)
-
-
-func draw_new_shape_preview(overlay: Control) -> void:
- # Draw a plus where a new shape will be added
- var mouse: Vector2 = overlay.get_local_mouse_position()
- overlay.draw_texture(ICON_ADD_HANDLE, mouse - ICON_ADD_HANDLE.get_size() * 0.5)
-
-
-##########
-# PLUGIN #
-##########
-func deselect_verts() -> void:
- current_action = ActionDataVert.new([], [], [], [], [], ACTION_VERT.NONE)
-
-
-func select_verticies(keys: PackedInt32Array, action: ACTION_VERT) -> ActionDataVert:
- var from_positions := PackedVector2Array()
- var from_positions_c_in := PackedVector2Array()
- var from_positions_c_out := PackedVector2Array()
- var from_widths := PackedFloat32Array()
- for key in keys:
- from_positions.push_back(shape.get_point_position(key))
- from_positions_c_in.push_back(shape.get_point_in(key))
- from_positions_c_out.push_back(shape.get_point_out(key))
- from_widths.push_back(shape.get_point_width(key))
- return ActionDataVert.new(
- keys, from_positions, from_positions_c_in, from_positions_c_out, from_widths, action
- )
-
-
-func select_vertices_to_move(keys: PackedInt32Array, _mouse_starting_pos_viewport: Vector2) -> void:
- _mouse_motion_delta_starting_pos = _mouse_starting_pos_viewport
- current_action = select_verticies(keys, ACTION_VERT.MOVE_VERT)
-
-
-func select_control_points_to_move(
- keys: PackedInt32Array, _mouse_starting_pos_viewport: Vector2, action: ACTION_VERT = ACTION_VERT.MOVE_CONTROL
-) -> void:
- current_action = select_verticies(keys, action)
- _mouse_motion_delta_starting_pos = _mouse_starting_pos_viewport
-
-
-func select_width_handle_to_move(keys: PackedInt32Array, _mouse_starting_pos_viewport: Vector2) -> void:
- _mouse_motion_delta_starting_pos = _mouse_starting_pos_viewport
- current_action = select_verticies(keys, ACTION_VERT.MOVE_WIDTH_HANDLE)
-
-
-func perform_action(action: SS2D_Action) -> void:
- var undo := get_undo_redo()
- undo.create_action(action.get_name(), UndoRedo.MERGE_DISABLE, shape.get_point_array())
- undo.add_do_method(action, "do")
- undo.add_do_method(self, "update_overlays")
- undo.add_undo_method(action, "undo")
- undo.add_undo_method(self, "update_overlays")
- undo.commit_action()
-
-
-#########
-# INPUT #
-#########
-func _input_handle_right_click_press(mb_position: Vector2, grab_threshold: float) -> bool:
- if not shape.can_edit:
- return false
- if current_mode == MODE.EDIT_VERT or current_mode == MODE.CREATE_VERT:
- # Mouse over a single vertex?
- if current_action.is_single_vert_selected():
- perform_action(ActionDeletePoint.new(shape, current_action.keys[0]))
- deselect_verts()
- return true
- else:
- # Mouse over a control point?
- var et: Transform2D = get_et()
- var points_in: Array = FUNC.get_intersecting_control_point_in(
- shape, et, mb_position, grab_threshold
- )
- var points_out: Array = FUNC.get_intersecting_control_point_out(
- shape, et, mb_position, grab_threshold
- )
- if not points_in.is_empty():
- perform_action(ActionDeleteControlPoint.new(shape, points_in[0],
- ActionDeleteControlPoint.PointType.POINT_IN))
- return true
- elif not points_out.is_empty():
- perform_action(ActionDeleteControlPoint.new(shape, points_out[0],
- ActionDeleteControlPoint.PointType.POINT_OUT))
- return true
- elif current_mode == MODE.EDIT_EDGE:
- if on_edge:
- gui_edge_info_panel.visible = not gui_edge_info_panel.visible
- gui_edge_info_panel.position = get_window().get_mouse_position()
- return true
- return false
-
-
-func _input_handle_left_click(
- mb: InputEventMouseButton,
- vp_m_pos: Vector2,
- t: Transform2D,
- et: Transform2D,
- grab_threshold: float
-) -> bool:
- # Set Pivot?
- if current_mode == MODE.SET_PIVOT:
- var local_position: Vector2 = et.affine_inverse() * mb.position
- if use_snap():
- local_position = snap(local_position)
- perform_action(ActionSetPivot.new(shape, local_position))
- return true
-
- if current_mode == MODE.EDIT_VERT or current_mode == MODE.CREATE_VERT:
- gui_edge_info_panel.visible = false
- var can_add_point: bool = Input.is_key_pressed(KEY_ALT) or current_mode == MODE.CREATE_VERT
- var is_first_selected: bool = current_action.is_single_vert_selected() and current_action.current_point_key() == shape.get_point_key_at_index(0)
-
- if _defer_mesh_updates:
- shape.begin_update()
-
- # Close the shape if the first point is clicked
- if can_add_point and is_first_selected and shape.can_close():
- var close_action := ActionCloseShape.new(shape)
- perform_action(close_action)
- if Input.is_key_pressed(KEY_SHIFT):
- select_control_points_to_move([close_action.get_key()], vp_m_pos)
- else:
- select_vertices_to_move([close_action.get_key()], vp_m_pos)
- return true
-
- # Any nearby control points to move?
- if not Input.is_key_pressed(KEY_ALT):
- if _input_move_control_points(mb, vp_m_pos, grab_threshold):
- return true
-
- # Highlighting a vert to move or add control points to
- if current_action.is_single_vert_selected():
- if on_width_handle:
- select_width_handle_to_move([current_action.current_point_key()], vp_m_pos)
- elif Input.is_key_pressed(KEY_SHIFT):
- select_control_points_to_move([current_action.current_point_key()], vp_m_pos)
- return true
- else:
- select_vertices_to_move([current_action.current_point_key()], vp_m_pos)
- return true
-
- # Split the Edge?
- if _input_split_edge(mb, vp_m_pos, t):
- return true
-
- if not on_edge and can_add_point:
- # Create new point
- var local_position: Vector2 = t.affine_inverse() * mb.position
- if use_snap():
- local_position = snap(local_position)
-
- var idx: int = -1
- if Input.is_key_pressed(KEY_SHIFT) and Input.is_key_pressed(KEY_ALT):
- # Copy shape with a new single point
- var copy: SS2D_Shape = copy_shape(shape)
- copy.set_point_array(SS2D_Point_Array.new())
- _enter_mode(MODE.CREATE_VERT)
- var selection := EditorInterface.get_selection()
- selection.clear()
- selection.add_node(copy)
- shape = copy
- elif Input.is_key_pressed(KEY_ALT):
- # Add point between start and end points of the closest edge
- idx = shape.get_point_index(closest_edge_keys[1])
- var add_point := ActionAddPoint.new(shape, local_position, idx, not _defer_mesh_updates)
- perform_action(add_point)
- if Input.is_key_pressed(KEY_SHIFT) and not Input.is_key_pressed(KEY_ALT):
- select_control_points_to_move([add_point.get_key()], vp_m_pos)
- else:
- select_vertices_to_move([add_point.get_key()], vp_m_pos)
- return true
- elif current_mode == MODE.EDIT_EDGE:
- if gui_edge_info_panel.visible:
- gui_edge_info_panel.visible = false
- return true
- if on_edge:
- # Grab Edge (2 points)
- var offset: float = shape.get_closest_offset_straight_edge(
- t.affine_inverse() * edge_point
- )
- var edge_point_keys := _get_edge_point_keys_from_offset(offset, true)
- select_vertices_to_move([edge_point_keys.x, edge_point_keys.y], vp_m_pos)
- if _defer_mesh_updates:
- shape.begin_update()
- return true
- elif current_mode == MODE.CUT_EDGE:
- if not on_edge:
- return true
- var offset: float = shape.get_closest_offset_straight_edge(t.affine_inverse() * edge_point)
- var edge_keys := _get_edge_point_keys_from_offset(offset, true)
- perform_action(ActionCutEdge.new(shape, edge_keys.x, edge_keys.y))
- on_edge = false
- return true
- elif current_mode == MODE.FREEHAND:
- return true
- return false
-
-
-func _input_handle_mouse_wheel(btn: int) -> bool:
- if current_mode == MODE.FREEHAND:
- if Input.is_key_pressed(KEY_CTRL) and Input.is_key_pressed(KEY_SHIFT):
- var step_multiplier := 1.2 if btn == MOUSE_BUTTON_WHEEL_UP else 0.8
- freehand_erase_size = roundf(clampf(freehand_erase_size * step_multiplier, 5, 400))
- update_overlays()
- return true
- elif Input.is_key_pressed(KEY_SHIFT):
- var step_multiplier := 1.2 if btn == MOUSE_BUTTON_WHEEL_UP else 0.8
- freehand_paint_size = roundf(clampf(freehand_paint_size * step_multiplier, 5, 400))
- update_overlays()
- return true
- elif current_action.is_single_vert_selected():
- if not shape.can_edit:
- return false
- var key: int = current_action.current_point_key()
- if Input.is_key_pressed(KEY_SHIFT):
- var width: float = shape.get_point_width(key)
- var width_step := 0.1
- if btn == MOUSE_BUTTON_WHEEL_DOWN:
- width_step *= -1
- var new_width: float = width + width_step
- shape.set_point_width(key, new_width)
-
- else:
- var texture_idx_step := 1
- if btn == MOUSE_BUTTON_WHEEL_DOWN:
- texture_idx_step *= -1
-
- var tex_idx: int = shape.get_point_texture_index(key) + texture_idx_step
- shape.set_point_texture_index(key, tex_idx)
-
- update_overlays()
- _gui_update_info_panels()
- return true
-
- return false
-
-
-func _input_handle_keyboard_event(event: InputEventKey) -> bool:
- if not shape.can_edit:
- return false
- var kb: InputEventKey = event
- if _is_valid_keyboard_scancode(kb):
- if current_action.is_single_vert_selected():
- if kb.pressed and kb.keycode == KEY_SPACE:
- var key: int = current_action.current_point_key()
- shape.set_point_texture_flip(key, not shape.get_point_texture_flip(key))
- _gui_update_info_panels()
-
- if kb.pressed and kb.keycode == KEY_ESCAPE:
- # Hide edge_info_panel
- if gui_edge_info_panel.visible:
- gui_edge_info_panel.visible = false
-
- if current_mode == MODE.CREATE_VERT:
- _enter_mode(MODE.EDIT_VERT)
-
- if kb.keycode == KEY_CTRL:
- if kb.pressed and not kb.echo:
- on_edge = false
- if closest_key != -1:
- current_action = select_verticies([closest_key], ACTION_VERT.NONE)
- else:
- deselect_verts()
- update_overlays()
-
- if kb.keycode == KEY_ALT:
- update_overlays()
-
- return true
- return false
-
-
-func _is_valid_keyboard_scancode(kb: InputEventKey) -> bool:
- match kb.keycode:
- KEY_ESCAPE:
- return true
- KEY_ENTER:
- return true
- KEY_SPACE:
- return true
- KEY_SHIFT:
- return true
- KEY_ALT:
- return true
- KEY_CTRL:
- return true
- return false
-
-
-func _input_handle_mouse_button_event(
- event: InputEventMouseButton, et: Transform2D, grab_threshold: float
-) -> bool:
- if not shape.can_edit:
- return false
- var t: Transform2D = et * shape.get_global_transform()
- var mb: InputEventMouseButton = event
- var viewport_mouse_position: Vector2 = et.affine_inverse() * mb.position
- var mouse_wheel_spun: bool = (
- mb.pressed
- and (mb.button_index == MOUSE_BUTTON_WHEEL_DOWN or mb.button_index == MOUSE_BUTTON_WHEEL_UP)
- )
-
- #######################################
- # Left Mouse Button released
- if not mb.pressed and mb.button_index == MOUSE_BUTTON_LEFT:
- _mouse_lmb_pressed = false
- var rslt: bool = false
- var type: ACTION_VERT = current_action.type
- var _in := type == ACTION_VERT.MOVE_CONTROL or type == ACTION_VERT.MOVE_CONTROL_IN
- var _out := type == ACTION_VERT.MOVE_CONTROL or type == ACTION_VERT.MOVE_CONTROL_OUT
- if type == ACTION_VERT.MOVE_VERT:
- perform_action(ActionMoveVerticies.new(shape, current_action.keys,
- current_action.starting_positions))
- rslt = true
- elif _in or _out:
- perform_action(ActionMoveControlPoints.new(
- shape,
- current_action.keys,
- current_action.starting_positions_control_in,
- current_action.starting_positions_control_out
- ))
- rslt = true
- elif current_mode == MODE.FREEHAND:
- if _defer_mesh_updates:
- shape.end_update()
- deselect_verts()
- return rslt
-
- #######################################
- # Right Mouse Button released
- if not mb.pressed and mb.button_index == MOUSE_BUTTON_RIGHT:
- _mouse_rmb_pressed = false
-
- #########################################
- # Mouse Wheel on valid point
- elif mouse_wheel_spun:
- return _input_handle_mouse_wheel(mb.button_index)
-
- #########################################
- # Mouse left click
- elif mb.pressed and mb.button_index == MOUSE_BUTTON_LEFT:
- _mouse_lmb_pressed = true
- return _input_handle_left_click(mb, viewport_mouse_position, t, et, grab_threshold)
-
- #########################################
- # Mouse right click
- elif mb.pressed and mb.button_index == MOUSE_BUTTON_RIGHT:
- _mouse_rmb_pressed = true
- return _input_handle_right_click_press(mb.position, grab_threshold)
-
- return false
-
-
-func _input_split_edge(mb: InputEventMouseButton, vp_m_pos: Vector2, t: Transform2D) -> bool:
- if not on_edge:
- return false
- var gpoint: Vector2 = mb.position
- var insertion_point: int = -1
- var mb_offset: float = shape.get_closest_offset(t.affine_inverse() * gpoint)
-
- insertion_point = shape.get_point_index(_get_edge_point_keys_from_offset(mb_offset)[1])
-
- if insertion_point == -1:
- insertion_point = shape.get_point_count() - 1
-
- var split_curve := ActionSplitCurve.new(shape, insertion_point, gpoint, t, not _defer_mesh_updates)
- perform_action(split_curve)
- select_vertices_to_move([split_curve.get_key()], vp_m_pos)
- on_edge = false
-
- if _defer_mesh_updates:
- shape.begin_update()
-
- return true
-
-
-func _input_move_control_points(mb: InputEventMouseButton, vp_m_pos: Vector2, grab_threshold: float) -> bool:
- var points_in := SS2D_PluginFunctionality.get_intersecting_control_point_in(
- shape, get_et(), mb.position, grab_threshold
- )
- var points_out := SS2D_PluginFunctionality.get_intersecting_control_point_out(
- shape, get_et(), mb.position, grab_threshold
- )
- if not points_in.is_empty():
- select_control_points_to_move([points_in[0]], vp_m_pos, ACTION_VERT.MOVE_CONTROL_IN)
- return true
- elif not points_out.is_empty():
- select_control_points_to_move([points_out[0]], vp_m_pos, ACTION_VERT.MOVE_CONTROL_OUT)
- return true
- return false
-
-
-func _get_edge_point_keys_from_offset(
- offset: float, straight: bool = false, _position := Vector2(0, 0)
-) -> Vector2i:
- for i in range(0, shape.get_point_count() - 1, 1):
- var key: int = shape.get_point_key_at_index(i)
- var key_next: int = shape.get_point_key_at_index(i + 1)
- var this_offset := 0.0
- var next_offset := 0.0
- if straight:
- this_offset = shape.get_closest_offset_straight_edge(shape.get_point_position(key))
- next_offset = shape.get_closest_offset_straight_edge(shape.get_point_position(key_next))
- else:
- this_offset = shape.get_closest_offset(shape.get_point_position(key))
- next_offset = shape.get_closest_offset(shape.get_point_position(key_next))
-
- if offset >= this_offset and offset <= next_offset:
- return Vector2i(key, key_next)
- # for when the shape is closed and the final point has an offset of 0
- if next_offset == 0 and offset >= this_offset:
- return Vector2i(key, key_next)
- return Vector2i(-1, -1)
-
-
-func _input_motion_is_on_edge(mm: InputEventMouseMotion, grab_threshold: float) -> bool:
- var xform: Transform2D = get_et() * shape.get_global_transform()
- if shape.get_point_count() < 2:
- return false
-
- # Find edge
- var closest_point: Vector2
- if current_mode == MODE.EDIT_EDGE or current_mode == MODE.CUT_EDGE:
- closest_point = shape.get_closest_point_straight_edge(
- xform.affine_inverse() * mm.position
- )
- else:
- closest_point = shape.get_closest_point(xform.affine_inverse() * mm.position)
- edge_point = xform * closest_point
- if edge_point.distance_to(mm.position) <= grab_threshold:
- return true
- return false
-
-
-func _input_find_closest_edge_keys(mm: InputEventMouseMotion) -> void:
- if shape.get_point_count() < 2:
- return
-
- # Find edge
- var xform: Transform2D = get_et() * shape.get_global_transform()
- var closest_point: Vector2 = shape.get_closest_point_straight_edge(xform.affine_inverse() * mm.position)
- var edge_p: Vector2 = xform * closest_point
- var offset: float = shape.get_closest_offset_straight_edge(xform.affine_inverse() * edge_p)
- closest_edge_keys = _get_edge_point_keys_from_offset(offset, true, xform.affine_inverse() * mm.position)
-
-
-func get_mouse_over_vert_key(mm: InputEventMouseMotion, grab_threshold: float) -> int:
- var xform: Transform2D = get_et() * shape.get_global_transform()
- # However, if near a control point or one of its handles then we are not on the edge
- for k in shape.get_all_point_keys():
- var pp: Vector2 = shape.get_point_position(k)
- var p: Vector2 = xform * pp
- if p.distance_to(mm.position) <= grab_threshold:
- return k
- return -1
-
-
-func get_mouse_over_width_handle(mm: InputEventMouseMotion, grab_threshold: float) -> int:
- var xform: Transform2D = get_et() * shape.get_global_transform()
- for k in shape.get_all_point_keys():
- var pp: Vector2 = shape.get_point_position(k)
- var normal: Vector2 = _get_vert_normal(
- xform, shape.get_vertices(), shape.get_point_index(k)
- )
- var p: Vector2 = xform * pp + normal * WIDTH_HANDLE_OFFSET
- if p.distance_to(mm.position) <= grab_threshold:
- return k
- return -1
-
-
-func _input_motion_move_control_points(delta: Vector2, _in: bool, _out: bool) -> bool:
- var rslt := false
- for i in range(0, current_action.keys.size(), 1):
- var key: int = current_action.keys[i]
- var out_multiplier := 1
- # Invert the delta for position_out if moving both at once
- if _out and _in:
- out_multiplier = -1
-
- var from_in: Vector2 = shape.to_global(current_action.starting_positions_control_in[i])
- var new_position_in: Vector2 = shape.global_transform.affine_inverse() * (
- delta + from_in
- )
-
- var from_out: Vector2 = shape.to_global(current_action.starting_positions_control_out[i])
- var new_position_out: Vector2 = shape.global_transform.affine_inverse() * (
- (delta * out_multiplier)
- + from_out
- )
-
- if use_snap():
- new_position_in = snap(new_position_in)
- new_position_out = snap(new_position_out)
- if _in:
- shape.set_point_in(key, new_position_in)
- rslt = true
- if _out:
- shape.set_point_out(key, new_position_out)
- rslt = true
- update_overlays()
-
- return rslt
-
-
-func _input_motion_move_verts(delta: Vector2) -> bool:
- for i in range(0, current_action.keys.size(), 1):
- var key: int = current_action.keys[i]
- var from: Vector2 = shape.to_global(current_action.starting_positions[i])
- var new_position: Vector2 = shape.global_transform.affine_inverse() * (from + delta)
- if use_snap():
- new_position = snap(new_position)
- shape.set_point_position(key, new_position)
- update_overlays()
- return true
-
-
-func _input_motion_move_width_handle(mouse_position: Vector2, scale: Vector2) -> bool:
- for i in range(0, current_action.keys.size(), 1):
- var key: int = current_action.keys[i]
- var from_width: float = current_action.starting_width[i]
- var from_position: Vector2 = current_action.starting_positions[i]
- width_scaling = from_position.distance_to(mouse_position) / WIDTH_HANDLE_OFFSET * scale.x
- shape.set_point_width(key, roundf(from_width * width_scaling * 10.0) / 10.0)
- update_overlays()
- return true
-
-
-## Will return index of closest vert to point.
-func get_closest_vert_to_point(s: SS2D_Shape, p: Vector2) -> int:
- var gt: Transform2D = shape.get_global_transform()
- var verts: PackedVector2Array = s.get_vertices()
- var transformed_point: Vector2 = gt.affine_inverse() * p
- var idx: int = -1
- var closest_distance: float = -1.0
- for i in verts.size():
- var distance: float = verts[i].distance_to(transformed_point)
- if distance < closest_distance or closest_distance == -1.0:
- idx = s.get_point_key_at_index(i)
- closest_distance = distance
- return idx
-
-
-func _input_handle_mouse_motion_event(
- event: InputEventMouseMotion, et: Transform2D, grab_threshold: float
-) -> bool:
- var t: Transform2D = et * shape.get_global_transform()
- var mm: InputEventMouseMotion = event
- var delta_current_pos: Vector2 = et.affine_inverse() * mm.position
- gui_point_info_panel.position = mm.position + GUI_POINT_INFO_PANEL_OFFSET
- var delta: Vector2 = delta_current_pos - _mouse_motion_delta_starting_pos
-
- closest_key = get_closest_vert_to_point(shape, delta_current_pos)
-
- if current_mode == MODE.EDIT_VERT or current_mode == MODE.CREATE_VERT:
- var type: ACTION_VERT = current_action.type
- var _in := type == ACTION_VERT.MOVE_CONTROL or type == ACTION_VERT.MOVE_CONTROL_IN
- var _out := type == ACTION_VERT.MOVE_CONTROL or type == ACTION_VERT.MOVE_CONTROL_OUT
-
- if type == ACTION_VERT.MOVE_VERT:
- return _input_motion_move_verts(delta)
- elif _in or _out:
- return _input_motion_move_control_points(delta, _in, _out)
- elif type == ACTION_VERT.MOVE_WIDTH_HANDLE:
- return _input_motion_move_width_handle(
- et.affine_inverse() * mm.position, et.get_scale()
- )
- var mouse_over_key: int = get_mouse_over_vert_key(event, grab_threshold)
- var mouse_over_width_handle: int = get_mouse_over_width_handle(event, grab_threshold)
-
- # Make the closest key grabable while holding down Control
- if (
- Input.is_key_pressed(KEY_CTRL)
- and not Input.is_key_pressed(KEY_ALT)
- and mouse_over_width_handle == -1
- and mouse_over_key == -1
- ):
- mouse_over_key = closest_key
-
- on_width_handle = false
- if mouse_over_key != -1:
- on_edge = false
- current_action = select_verticies([mouse_over_key], ACTION_VERT.NONE)
- elif mouse_over_width_handle != -1:
- on_edge = false
- on_width_handle = true
- current_action = select_verticies([mouse_over_width_handle], ACTION_VERT.NONE)
- elif Input.is_key_pressed(KEY_ALT):
- _input_find_closest_edge_keys(mm)
- else:
- deselect_verts()
- on_edge = _input_motion_is_on_edge(mm, grab_threshold)
-
- elif current_mode == MODE.EDIT_EDGE or current_mode == MODE.CUT_EDGE:
- # Don't update if edge panel is visible
- if gui_edge_info_panel.visible:
- return false
- var type: ACTION_VERT = current_action.type
- if type == ACTION_VERT.MOVE_VERT:
- return _input_motion_move_verts(delta)
- else:
- deselect_verts()
- on_edge = _input_motion_is_on_edge(mm, grab_threshold)
-
- elif current_mode == MODE.FREEHAND:
- if _mouse_lmb_pressed:
- if not Input.is_key_pressed(KEY_CTRL):
- var local_position: Vector2 = t.affine_inverse() * mm.position
- if last_point_position.distance_to(local_position) >= freehand_paint_size * 2:
- last_point_position = local_position
- if use_snap():
- local_position = snap(local_position)
- var idx: int = shape.get_point_index(closest_edge_keys[1]) if shape.is_shape_closed() else -1
- perform_action(ActionAddPoint.new(shape, local_position, idx, not _defer_mesh_updates))
- update_overlays()
- return true
- else:
- var xform: Transform2D = get_et() * shape.get_global_transform()
- var closest_ss2d_point: SS2D_Point = (shape as SS2D_Shape).get_point(closest_key)
- if closest_ss2d_point != null:
- var closest_point: Vector2 = closest_ss2d_point.position
- closest_point = xform * closest_point
- if closest_point.distance_to(mm.position) / current_zoom_level <= freehand_erase_size * 2:
- var delete_point: int = get_mouse_over_vert_key(event, grab_threshold)
- delete_point = closest_key
- on_width_handle = false
- if delete_point != -1:
- perform_action(ActionDeletePoint.new(shape, delete_point, not _defer_mesh_updates))
- last_point_position = Vector2.ZERO
- update_overlays()
- return true
- else:
- _input_find_closest_edge_keys(mm)
-
- update_overlays()
- return false
-
-
-func _get_vert_normal(t: Transform2D, verts: PackedVector2Array, i: int) -> Vector2:
- var point: Vector2 = t * verts[i]
- var prev_point: Vector2 = t * (verts[(i - 1) % verts.size()])
- var next_point: Vector2 = t * (verts[(i + 1) % verts.size()])
- return ((prev_point - point).normalized().rotated(PI / 2) + (point - next_point).normalized().rotated(PI / 2)).normalized()
-
-
-func copy_shape(s: SS2D_Shape) -> SS2D_Shape:
- var copy: SS2D_Shape = s.clone(false)
-
- var undo := get_undo_redo()
- undo.create_action("Add Shape Node")
-
- undo.add_do_method(s.get_parent(), "add_child", copy, true)
- undo.add_do_method(copy, "set_owner", get_tree().get_edited_scene_root())
- undo.add_do_reference(copy)
- undo.add_undo_method(copy, "set_owner", null)
- undo.add_undo_method(s.get_parent(), "remove_child", copy)
-
- var collision_polygon_original := s.get_collision_polygon_node()
-
- if collision_polygon_original:
- var collision_polygon_new := CollisionPolygon2D.new()
- collision_polygon_new.visible = collision_polygon_original.visible
-
- undo.add_do_method(collision_polygon_original.get_parent(), "add_child", collision_polygon_new, true)
- undo.add_do_method(collision_polygon_new, "set_owner", get_tree().get_edited_scene_root())
- undo.add_do_reference(collision_polygon_new)
-
- undo.add_undo_method(collision_polygon_original.get_parent(), "remove_child", collision_polygon_new)
-
- undo.commit_action()
-
- copy.collision_polygon_node_path = copy.get_path_to(collision_polygon_new)
- else:
- undo.commit_action()
-
- return copy
-
-
-#########
-# DEBUG #
-#########
-func _debug_mouse_positions(mm: InputEventMouseMotion, t: Transform2D) -> void:
- print("========================================")
- print("MouseDelta:%s" % str(_mouse_motion_delta_starting_pos))
- print("= MousePositions =")
- print("Position: %s" % str(mm.position))
- print("Relative: %s" % str(mm.relative))
- print("= Transforms =")
- print("Transform3D: %s" % str(t))
- print("Inverse: %s" % str(t.affine_inverse()))
- print("= Transformed Mouse positions =")
- print("Position: %s" % str(t.affine_inverse() * mm.position))
- print("Relative: %s" % str(t.affine_inverse() * mm.relative))
- print("MouseDelta:%s" % str(t.affine_inverse() * _mouse_motion_delta_starting_pos))
diff --git a/addons/rmsmartshape/plugin_functionality.gd b/addons/rmsmartshape/plugin_functionality.gd
deleted file mode 100644
index 3d12e53..0000000
--- a/addons/rmsmartshape/plugin_functionality.gd
+++ /dev/null
@@ -1,132 +0,0 @@
-@tool
-class_name SS2D_PluginFunctionality
-extends RefCounted
-
-## - Everything in this script should be static
-## - There is one reason to have code in this script
-## 1. To separate out code from the main plugin script to ease testing
-##
-## Common Abbreviations
-## et = editor transform (viewport's canvas transform)
-
-# --- VERTS
-
-static func get_intersecting_control_point_in(
- s: SS2D_Shape, et: Transform2D, mouse_pos: Vector2, grab_threshold: float
-) -> PackedInt32Array:
- return _get_intersecting_control_point(s, et, mouse_pos, grab_threshold, true)
-
-
-static func get_intersecting_control_point_out(
- s: SS2D_Shape, et: Transform2D, mouse_pos: Vector2, grab_threshold: float
-) -> PackedInt32Array:
- return _get_intersecting_control_point(s, et, mouse_pos, grab_threshold, false)
-
-
-static func _get_intersecting_control_point(
- s: SS2D_Shape, et: Transform2D, mouse_pos: Vector2, grab_threshold: float, _in: bool
-) -> PackedInt32Array:
- var points := PackedInt32Array()
- var xform: Transform2D = et * s.get_global_transform()
- for i in s.get_point_count():
- var key: int = s.get_point_key_at_index(i)
- var vec_pos: Vector2 = s.get_point_position(key)
- var c_pos := Vector2.ZERO
- if _in:
- c_pos = s.get_point_in(key)
- else:
- c_pos = s.get_point_out(key)
- if c_pos == Vector2.ZERO:
- continue
- var final_pos := vec_pos + c_pos
- final_pos = xform * final_pos
- if final_pos.distance_to(mouse_pos) <= grab_threshold:
- points.push_back(key)
-
- return points
-
-
-static func get_next_point_index(idx: int, points: PackedVector2Array, wrap_around: bool = false) -> int:
- if wrap_around:
- return get_next_point_index_wrap_around(idx, points)
- return get_next_point_index_no_wrap_around(idx, points)
-
-
-static func get_previous_point_index(idx: int, points: PackedVector2Array, wrap_around: bool = false) -> int:
- if wrap_around:
- return get_previous_point_index_wrap_around(idx, points)
- return get_previous_point_index_no_wrap_around(idx, points)
-
-
-static func get_next_point_index_no_wrap_around(idx: int, points: PackedVector2Array) -> int:
- return mini(idx + 1, points.size() - 1)
-
-
-static func get_previous_point_index_no_wrap_around(idx: int, _points_: PackedVector2Array) -> int:
- return maxi(idx - 1, 0)
-
-
-static func get_next_point_index_wrap_around(idx: int, points: PackedVector2Array) -> int:
- return (idx + 1) % points.size()
-
-
-static func get_previous_point_index_wrap_around(idx: int, points: PackedVector2Array) -> int:
- return posmod(idx - 1, points.size())
-
-
-## Get the next point that doesn't share the same position with the current point.[br]
-## In other words, get the next point in the array with a unique position.[br]
-static func get_next_unique_point_idx(idx: int, pts: PackedVector2Array, wrap_around: bool) -> int:
- var next_idx: int = get_next_point_index(idx, pts, wrap_around)
- if next_idx == idx:
- return idx
- var pt1: Vector2 = pts[idx]
- var pt2: Vector2 = pts[next_idx]
- if pt1 == pt2:
- return get_next_unique_point_idx(next_idx, pts, wrap_around)
- return next_idx
-
-
-static func get_previous_unique_point_idx(idx: int, pts: PackedVector2Array, wrap_around: bool) -> int:
- var previous_idx: int = get_previous_point_index(idx, pts, wrap_around)
- if previous_idx == idx:
- return idx
- var pt1: Vector2 = pts[idx]
- var pt2: Vector2 = pts[previous_idx]
- if pt1 == pt2:
- return get_previous_unique_point_idx(previous_idx, pts, wrap_around)
- return previous_idx
-
-
-static func snap_position(
- pos_global: Vector2, snap_offset: Vector2, snap_step: Vector2, local_t: Transform2D
-) -> Vector2:
- # Move global position to local position to snap in local space
- var pos_local: Vector2 = local_t * pos_global
-
- # Snap in local space
- var x: float = pos_local.x
- if snap_step.x != 0:
- var delta: float = fmod(pos_local.x, snap_step.x)
- # Round up
- if delta >= (snap_step.x / 2.0):
- x = pos_local.x + (snap_step.x - delta)
- # Round down
- else:
- x = pos_local.x - delta
- var y: float = pos_local.y
- if snap_step.y != 0:
- var delta: float = fmod(pos_local.y, snap_step.y)
- # Round up
- if delta >= (snap_step.y / 2.0):
- y = pos_local.y + (snap_step.y - delta)
- # Round down
- else:
- y = pos_local.y - delta
-
- # Transform3D local position to global position
- var pos_global_snapped := (local_t.affine_inverse() * Vector2(x, y)) + snap_offset
- #print ("%s | %s | %s | %s" % [pos_global, pos_local, Vector2(x,y), pos_global_snapped])
- return pos_global_snapped
-
-
diff --git a/addons/rmsmartshape/scenes/GUI_Edge_InfoPanel.gd b/addons/rmsmartshape/scenes/GUI_Edge_InfoPanel.gd
deleted file mode 100644
index f748341..0000000
--- a/addons/rmsmartshape/scenes/GUI_Edge_InfoPanel.gd
+++ /dev/null
@@ -1,146 +0,0 @@
-@tool
-extends PanelContainer
-class_name SS2D_EdgeInfoPanel
-
-signal material_override_toggled(enabled: bool)
-signal render_toggled(enabled: bool)
-signal weld_toggled(enabled: bool)
-signal z_index_changed(value: int)
-signal edge_material_changed(value: SS2D_Material_Edge)
-
-var indicies := Vector2i(-1, -1) : set = set_indicies
-var edge_material: SS2D_Material_Edge = null
-var edge_material_selector := FileDialog.new()
-
-@onready var idx_label: Label = %IDX
-@onready var material_override_button: Button = %MaterialOverride
-@onready var override_container: Container = %OverrideContainer
-@onready var render_checkbox: CheckBox = %Render
-@onready var weld_checkbox: CheckBox = %Weld
-@onready var z_index_spinbox: SpinBox = %ZIndex
-@onready var set_material_button: Button = %SetMaterial
-@onready var clear_material_button: Button = %ClearMaterial
-@onready var material_status: Label = %MaterialStatus
-
-
-func _ready() -> void:
- material_override_button.connect("toggled", self._on_toggle_material_override)
- render_checkbox.connect("toggled", self._on_toggle_render)
- weld_checkbox.connect("toggled", self._on_toggle_weld)
- z_index_spinbox.connect("value_changed", self._on_set_z_index)
- set_material_button.connect("pressed", self._on_set_edge_material_pressed)
- clear_material_button.connect("pressed", self._on_set_edge_material_clear_pressed)
-
- override_container.hide()
- clear_material_button.hide()
-
- edge_material_selector.file_mode = FileDialog.FILE_MODE_OPEN_FILE
- edge_material_selector.dialog_hide_on_ok = true
- edge_material_selector.show_hidden_files = true
- edge_material_selector.mode_overrides_title = false
- edge_material_selector.title = "Select Edge Material"
- edge_material_selector.filters = PackedStringArray(["*.tres"])
- edge_material_selector.connect("file_selected", self._on_set_edge_material_file_selected)
- add_child(edge_material_selector)
-
-
-func _on_set_edge_material_clear_pressed() -> void:
- set_edge_material(null)
-
-
-func _on_set_edge_material_pressed() -> void:
- # Update file list
- edge_material_selector.invalidate()
- edge_material_selector.popup_centered_ratio(0.8)
-
-
-func _on_set_edge_material_file_selected(f: String) -> void:
- var rsc := load(f)
- if not rsc is SS2D_Material_Edge:
- push_error("Selected resource is not an Edge Material! (SS2D_Material_Edge)")
- return
- set_edge_material(rsc)
-
-
-func set_indicies(t: Vector2i) -> void:
- indicies = t
- idx_label.text = "IDX: %s" % indicies
-
-
-func set_material_override(enabled: bool) -> void:
- material_override_button.button_pressed = enabled
- _on_toggle_material_override(enabled)
-
-
-func set_render(enabled: bool, emit: bool = true) -> void:
- render_checkbox.button_pressed = enabled
- if emit:
- _on_toggle_render(enabled)
-
-
-func set_weld(enabled: bool, emit: bool = true) -> void:
- weld_checkbox.button_pressed = enabled
- if emit:
- _on_toggle_weld(enabled)
-
-
-func set_edge_material(v: SS2D_Material_Edge, emit: bool = true) -> void:
- edge_material = v
- if v == null:
- material_status.text = "[No Material]"
- clear_material_button.visible = false
- else:
- # Call string function 'get_file()' to get the filepath
- material_status.text = "[%s]" % (v.resource_path).get_file()
- clear_material_button.visible = true
- if emit:
- emit_signal("edge_material_changed", v)
-
-
-func set_edge_z_index(v: int, emit: bool = true) -> void:
- z_index_spinbox.value = float(v)
- if emit:
- _on_set_z_index(float(v))
-
-
-func get_render() -> bool:
- return render_checkbox.button_pressed
-
-
-func get_weld() -> bool:
- return weld_checkbox.button_pressed
-
-
-func get_edge_z_index() -> int:
- return int(z_index_spinbox.value)
-
-
-func _on_toggle_material_override(pressed: bool) -> void:
- override_container.visible = pressed
- emit_signal("material_override_toggled", pressed)
-
-
-func _on_toggle_render(pressed: bool) -> void:
- emit_signal("render_toggled", pressed)
-
-
-func _on_toggle_weld(pressed: bool) -> void:
- emit_signal("weld_toggled", pressed)
-
-
-func _on_set_z_index(v: float) -> void:
- emit_signal("z_index_changed", int(v))
-
-
-func load_values_from_meta_material(meta_mat: SS2D_Material_Edge_Metadata) -> void:
- set_render(meta_mat.render)
- set_weld(meta_mat.weld)
- set_z_index(meta_mat.z_index)
- set_edge_material(meta_mat.edge_material)
-
-
-func save_values_to_meta_material(meta_mat: SS2D_Material_Edge_Metadata) -> void:
- meta_mat.render = get_render()
- meta_mat.weld = get_weld()
- meta_mat.z_index = get_z_index()
- meta_mat.edge_material = edge_material
diff --git a/addons/rmsmartshape/scenes/GUI_Edge_InfoPanel.tscn b/addons/rmsmartshape/scenes/GUI_Edge_InfoPanel.tscn
deleted file mode 100644
index 6ddae7e..0000000
--- a/addons/rmsmartshape/scenes/GUI_Edge_InfoPanel.tscn
+++ /dev/null
@@ -1,100 +0,0 @@
-[gd_scene load_steps=3 format=3 uid="uid://cy1l6tyadc4s3"]
-
-[ext_resource type="Theme" uid="uid://dud4fe6fsicvm" path="res://addons/rmsmartshape/assets/gui_theme.res" id="1_pwu3l"]
-[ext_resource type="Script" path="res://addons/rmsmartshape/scenes/GUI_Edge_InfoPanel.gd" id="2"]
-
-[node name="GUI_Edge_InfoPanel" type="PanelContainer"]
-anchors_preset = -1
-anchor_right = 0.203125
-anchor_bottom = 0.345679
-offset_bottom = -62.0
-size_flags_horizontal = 4
-size_flags_vertical = 4
-mouse_filter = 2
-theme = ExtResource("1_pwu3l")
-script = ExtResource("2")
-metadata/_edit_use_anchors_ = true
-
-[node name="Panel" type="Panel" parent="."]
-layout_mode = 2
-mouse_filter = 2
-
-[node name="Container" type="VBoxContainer" parent="."]
-layout_mode = 2
-
-[node name="Properties" type="VBoxContainer" parent="Container"]
-layout_mode = 2
-mouse_filter = 2
-
-[node name="IDX" type="Label" parent="Container/Properties"]
-unique_name_in_owner = true
-layout_mode = 2
-text = "IDX: [1,2]"
-
-[node name="Functions" type="VBoxContainer" parent="Container"]
-layout_mode = 2
-mouse_filter = 2
-
-[node name="Make Inner Curve" type="Button" parent="Container/Functions"]
-visible = false
-layout_mode = 2
-text = "Make Inner Curve"
-
-[node name="Make Outer Curve" type="Button" parent="Container/Functions"]
-visible = false
-layout_mode = 2
-text = "Make Outer Curve"
-
-[node name="MaterialOverride" type="Button" parent="Container/Functions"]
-unique_name_in_owner = true
-layout_mode = 2
-toggle_mode = true
-text = "Material Override"
-
-[node name="OverrideContainer" type="VBoxContainer" parent="Container"]
-unique_name_in_owner = true
-visible = false
-layout_mode = 2
-
-[node name="HSeparator" type="HSeparator" parent="Container/OverrideContainer"]
-layout_mode = 2
-
-[node name="Render" type="CheckBox" parent="Container/OverrideContainer"]
-unique_name_in_owner = true
-layout_mode = 2
-text = "Render"
-
-[node name="Weld" type="CheckBox" parent="Container/OverrideContainer"]
-unique_name_in_owner = true
-visible = false
-layout_mode = 2
-text = "Weld"
-
-[node name="ZIndexSection" type="HBoxContainer" parent="Container/OverrideContainer"]
-visible = false
-layout_mode = 2
-
-[node name="lbl" type="Label" parent="Container/OverrideContainer/ZIndexSection"]
-layout_mode = 2
-text = "Z:"
-
-[node name="ZIndex" type="SpinBox" parent="Container/OverrideContainer/ZIndexSection"]
-unique_name_in_owner = true
-layout_mode = 2
-min_value = -100.0
-
-[node name="SetMaterial" type="Button" parent="Container/OverrideContainer"]
-unique_name_in_owner = true
-layout_mode = 2
-text = "Set Material"
-
-[node name="ClearMaterial" type="Button" parent="Container/OverrideContainer"]
-unique_name_in_owner = true
-visible = false
-layout_mode = 2
-text = "Clear Material"
-
-[node name="MaterialStatus" type="Label" parent="Container/OverrideContainer"]
-unique_name_in_owner = true
-layout_mode = 2
-text = "[No Material]"
diff --git a/addons/rmsmartshape/scenes/GUI_InfoPanel.gd b/addons/rmsmartshape/scenes/GUI_InfoPanel.gd
deleted file mode 100644
index 1ff15f2..0000000
--- a/addons/rmsmartshape/scenes/GUI_InfoPanel.gd
+++ /dev/null
@@ -1,25 +0,0 @@
-@tool
-extends PanelContainer
-class_name SS2D_PointInfoPanel
-
-
-@onready var idx_label: Label = %IDX
-@onready var tex_label: Label = %Tex
-@onready var width_label: Label = %Width
-@onready var flip_label: Label = %Flip
-
-
-func set_idx(i: int) -> void:
- idx_label.text = "IDX: %s" % i
-
-
-func set_texture_idx(i: int) -> void:
- tex_label.text = "Texture2D: %s" % i
-
-
-func set_width(f: float) -> void:
- width_label.text = "Width: %s" % f
-
-
-func set_flip(b: bool) -> void:
- flip_label.text = "Flip: %s" % b
diff --git a/addons/rmsmartshape/scenes/GUI_InfoPanel.tscn b/addons/rmsmartshape/scenes/GUI_InfoPanel.tscn
deleted file mode 100644
index 9bb1c70..0000000
--- a/addons/rmsmartshape/scenes/GUI_InfoPanel.tscn
+++ /dev/null
@@ -1,44 +0,0 @@
-[gd_scene load_steps=3 format=3 uid="uid://cxu6258urdtf1"]
-
-[ext_resource type="Theme" uid="uid://dud4fe6fsicvm" path="res://addons/rmsmartshape/assets/gui_theme.res" id="1_byls6"]
-[ext_resource type="Script" path="res://addons/rmsmartshape/scenes/GUI_InfoPanel.gd" id="2"]
-
-[node name="GUI_InfoPanel" type="PanelContainer"]
-anchors_preset = 15
-anchor_right = 1.0
-anchor_bottom = 1.0
-offset_right = -918.0
-offset_bottom = -486.0
-size_flags_horizontal = 4
-size_flags_vertical = 4
-mouse_filter = 2
-theme = ExtResource("1_byls6")
-script = ExtResource("2")
-
-[node name="Panel" type="Panel" parent="."]
-layout_mode = 2
-mouse_filter = 2
-
-[node name="Properties" type="VBoxContainer" parent="."]
-layout_mode = 2
-mouse_filter = 2
-
-[node name="IDX" type="Label" parent="Properties"]
-unique_name_in_owner = true
-layout_mode = 2
-text = "IDX: 13"
-
-[node name="Tex" type="Label" parent="Properties"]
-unique_name_in_owner = true
-layout_mode = 2
-text = "Tex: 1"
-
-[node name="Width" type="Label" parent="Properties"]
-unique_name_in_owner = true
-layout_mode = 2
-text = "Width: 1.0"
-
-[node name="Flip" type="Label" parent="Properties"]
-unique_name_in_owner = true
-layout_mode = 2
-text = "Flip: N"
diff --git a/addons/rmsmartshape/scenes/SnapPopup.gd b/addons/rmsmartshape/scenes/SnapPopup.gd
deleted file mode 100644
index cb87ea0..0000000
--- a/addons/rmsmartshape/scenes/SnapPopup.gd
+++ /dev/null
@@ -1,16 +0,0 @@
-@tool
-extends Popup
-class_name SS2D_SnapPopup
-
-@onready var snap_offset_x: SpinBox = %SnapOffsetX
-@onready var snap_offset_y: SpinBox = %SnapOffsetY
-@onready var snap_step_x: SpinBox = %SnapStepX
-@onready var snap_step_y: SpinBox = %SnapStepY
-
-
-func get_snap_offset() -> Vector2:
- return Vector2(snap_offset_x.value, snap_offset_y.value)
-
-
-func get_snap_step() -> Vector2:
- return Vector2(snap_step_x.value, snap_step_y.value)
diff --git a/addons/rmsmartshape/scenes/SnapPopup.tscn b/addons/rmsmartshape/scenes/SnapPopup.tscn
deleted file mode 100644
index 12af8f3..0000000
--- a/addons/rmsmartshape/scenes/SnapPopup.tscn
+++ /dev/null
@@ -1,58 +0,0 @@
-[gd_scene load_steps=3 format=3 uid="uid://d1acvw8yuubxo"]
-
-[ext_resource type="Script" path="res://addons/rmsmartshape/scenes/SnapPopup.gd" id="1"]
-[ext_resource type="Theme" uid="uid://dud4fe6fsicvm" path="res://addons/rmsmartshape/assets/gui_theme.res" id="1_6ft7o"]
-
-[node name="SnapPopup" type="PopupPanel"]
-size = Vector2i(301, 128)
-visible = true
-theme = ExtResource("1_6ft7o")
-script = ExtResource("1")
-
-[node name="VBoxContainer" type="VBoxContainer" parent="."]
-offset_left = 12.0
-offset_top = 12.0
-offset_right = 289.0
-offset_bottom = 116.0
-
-[node name="Label" type="Label" parent="VBoxContainer"]
-layout_mode = 2
-text = "Configure Snap"
-
-[node name="SnapOffset" type="HBoxContainer" parent="VBoxContainer"]
-layout_mode = 2
-alignment = 2
-
-[node name="Label" type="Label" parent="VBoxContainer/SnapOffset"]
-layout_mode = 2
-text = "Grid Offset:"
-
-[node name="SnapOffsetX" type="SpinBox" parent="VBoxContainer/SnapOffset"]
-unique_name_in_owner = true
-layout_mode = 2
-suffix = "px"
-
-[node name="SnapOffsetY" type="SpinBox" parent="VBoxContainer/SnapOffset"]
-unique_name_in_owner = true
-layout_mode = 2
-suffix = "px"
-
-[node name="SnapStep" type="HBoxContainer" parent="VBoxContainer"]
-layout_mode = 2
-alignment = 2
-
-[node name="Label" type="Label" parent="VBoxContainer/SnapStep"]
-layout_mode = 2
-text = "Grid Step: "
-
-[node name="SnapStepX" type="SpinBox" parent="VBoxContainer/SnapStep"]
-unique_name_in_owner = true
-layout_mode = 2
-value = 8.0
-suffix = "px"
-
-[node name="SnapStepY" type="SpinBox" parent="VBoxContainer/SnapStep"]
-unique_name_in_owner = true
-layout_mode = 2
-value = 8.0
-suffix = "px"
diff --git a/addons/rmsmartshape/shapes/edge.gd b/addons/rmsmartshape/shapes/edge.gd
deleted file mode 100644
index 35ee62b..0000000
--- a/addons/rmsmartshape/shapes/edge.gd
+++ /dev/null
@@ -1,337 +0,0 @@
-@tool
-extends RefCounted
-class_name SS2D_Edge
-
-## An SS2D_Edge represents an edge that will be rendered.
-##
-## It contains: [br]
-## - A list of quads that should be rendered [br]
-## - A [Material] that dictates how the edge should be rendered [br]
-
-## What to encode in the color data (for use by shaders).
-enum COLOR_ENCODING {
- COLOR, ## Encode a diffuse value to offset the quads color by (currently only ever white).
- NORMALS, ## Encode normal data in the colors to be unpacked by a shader later.
-}
-
-var quads: Array[SS2D_Quad] = []
-var first_point_key: int = -1
-var last_point_key: int = -1
-var z_index: int = 0
-var z_as_relative: bool = false
-## If final point is connected to first point.
-var wrap_around: bool = false
-var material: Material = null
-
-
-## Will return true if the 2 quads must be drawn in two calls.
-static func different_render(q1: SS2D_Quad, q2: SS2D_Quad) -> bool:
- if q1.matches_quad(q2):
- return false
- return true
-
-
-static func get_consecutive_quads_for_mesh(_quads: Array[SS2D_Quad]) -> Array[Array]:
- var quad_ranges: Array[Array] = []
-
- if _quads.is_empty():
- return quad_ranges
-
- var quad_range: Array[SS2D_Quad] = []
- quad_range.push_back(_quads[0])
- for i in range(1, _quads.size(), 1):
- var quad_prev: SS2D_Quad = _quads[i - 1]
- var quad: SS2D_Quad = _quads[i]
- if different_render(quad, quad_prev):
- quad_ranges.push_back(quad_range)
- quad_range = [quad]
- else:
- quad_range.push_back(quad)
-
- quad_ranges.push_back(quad_range)
- return quad_ranges
-
-
-## Will generate normals for a given quad
-## and interpolate with previous and next quads.
-static func generate_normals_for_quad_interpolated(qp: SS2D_Quad, q: SS2D_Quad, qn: SS2D_Quad) -> Array[Color]:
- # Interpolation and normalization
- #First, consider everything to be a non corner
- var tg_a: Vector2 = (q.tg_a + qp.tg_d)
- var bn_a: Vector2 = (q.bn_a + qp.bn_d)
-
- var tg_b: Vector2 = (q.tg_b + qp.tg_c)
- var bn_b: Vector2 = (q.bn_b + qp.bn_c)
-
- var tg_c: Vector2 = (q.tg_c + qn.tg_b)
- var bn_c: Vector2 = (q.bn_c + qn.bn_b)
-
- var tg_d: Vector2 = (q.tg_d + qn.tg_a)
- var bn_d: Vector2 = (q.bn_d + qn.bn_a)
-
- #then, fix values for corner cases (and edge ends)
- if q.corner == q.CORNER.NONE:
- if qp.corner == q.CORNER.NONE:
- #check validity
- if (not q.pt_a.is_equal_approx(qp.pt_d)) or (not q.pt_b.is_equal_approx(qp.pt_c)):
- tg_a = q.tg_a
- tg_b = q.tg_b
- bn_a = q.bn_a
- bn_b = q.bn_b
- elif qp.corner == q.CORNER.INNER:
- tg_a = (-qp.bn_d)
- bn_a = (-qp.tg_d)
- tg_b = (q.tg_b - qp.bn_a)
- bn_b = (q.bn_b - qp.tg_a)
- #check validity
- if (not q.pt_a.is_equal_approx(qp.pt_d)) or (not q.pt_b.is_equal_approx(qp.pt_a)):
- tg_a = q.tg_a
- tg_b = q.tg_b
- bn_a = q.bn_a
- bn_b = q.bn_b
- elif qp.corner == q.CORNER.OUTER:
- tg_a = (q.tg_a + qp.bn_c)
- bn_a = (q.bn_a - qp.tg_c)
- tg_b = (qp.bn_b)
- bn_b = (-qp.tg_b)
- #check validity
- if (not q.pt_a.is_equal_approx(qp.pt_c)) or (not q.pt_b.is_equal_approx(qp.pt_b)):
- tg_a = q.tg_a
- tg_b = q.tg_b
- bn_a = q.bn_a
- bn_b = q.bn_b
- if qn.corner == q.CORNER.NONE:
- #check validity
- if (not q.pt_c.is_equal_approx(qn.pt_b)) or (not q.pt_d.is_equal_approx(qn.pt_a)):
- tg_c = q.tg_c
- tg_d = q.tg_d
- bn_c = q.bn_c
- bn_d = q.bn_d
- elif qn.corner == q.CORNER.INNER:
- tg_d = (-qn.tg_d)
- bn_d = (qn.bn_d)
- tg_c = (q.tg_c - qn.tg_c)
- bn_c = (q.bn_c + qn.bn_c)
- #check validity
- if (not q.pt_c.is_equal_approx(qn.pt_c)) or (not q.pt_d.is_equal_approx(qn.pt_d)):
- tg_c = q.tg_c
- tg_d = q.tg_d
- bn_c = q.bn_c
- bn_d = q.bn_d
- elif qn.corner == q.CORNER.OUTER:
- tg_c = (qn.tg_b)
- bn_c = (qn.bn_b)
- #check validity
- if (not q.pt_c.is_equal_approx(qn.pt_b)) or (not q.pt_d.is_equal_approx(qn.pt_a)):
- tg_c = q.tg_c
- tg_d = q.tg_d
- bn_c = q.bn_c
- bn_d = q.bn_d
-
- elif q.corner == q.CORNER.INNER:
- #common
- tg_d = q.tg_d
- bn_d = q.bn_d
- tg_b = (q.tg_b)
- bn_b = (q.bn_b)
- #previous
- tg_c = (q.tg_c - qp.tg_c)
- bn_c = (q.bn_c + qp.bn_c)
- #next
- tg_a = (q.tg_a - qn.bn_b)
- bn_a = (q.bn_a - qn.tg_b)
- #check validity
- if qp.corner != qp.CORNER.NONE or (not q.pt_c.is_equal_approx(qp.pt_c)) or (not q.pt_d.is_equal_approx(qp.pt_d)):
- tg_c = q.tg_c
- bn_c = q.bn_c
- if qn.corner != qp.CORNER.NONE or (not q.pt_a.is_equal_approx(qn.pt_b)) or (not q.pt_d.is_equal_approx(qn.pt_a)):
- tg_a = q.tg_a
- bn_a = q.bn_a
-
- elif q.corner == q.CORNER.OUTER:
- tg_d = q.tg_d
- bn_d = q.bn_d
- tg_b = (q.tg_b)
- bn_b = (q.bn_b)
- #previous
- tg_a = (q.tg_a + qp.tg_d)
- bn_a = (q.bn_a + qp.bn_d)
- #qn
- tg_c = (q.tg_c - qn.bn_a)
- bn_c = (q.bn_c + qn.tg_a)
- #check validity
- if qp.corner != qp.CORNER.NONE or (not q.pt_a.is_equal_approx(qp.pt_d)) or (not q.pt_b.is_equal_approx(qp.pt_c)):
- tg_a = q.tg_a
- bn_a = q.bn_a
- if qn.corner != qp.CORNER.NONE or (not q.pt_b.is_equal_approx(qn.pt_b)) or (not q.pt_c.is_equal_approx(qn.pt_a)):
- tg_c = q.tg_c
- bn_c = q.bn_c
-
- if q.flip_texture:
- bn_a = -bn_a;
- bn_b = -bn_b;
- bn_c = -bn_c;
- bn_d = -bn_d;
-
- #Normalize the values
- var half_vector: Vector2 = Vector2.ONE * 0.5
- tg_a = tg_a.normalized()*0.5 + half_vector
- tg_b = tg_b.normalized()*0.5 + half_vector
- tg_c = tg_c.normalized()*0.5 + half_vector
- tg_d = tg_d.normalized()*0.5 + half_vector
-
- bn_a = bn_a.normalized()*0.5 + half_vector
- bn_b = bn_b.normalized()*0.5 + half_vector
- bn_c = bn_c.normalized()*0.5 + half_vector
- bn_d = bn_d.normalized()*0.5 + half_vector
-
- var normal_pt_a := Color(tg_a.x, tg_a.y, bn_a.x, bn_a.y)
- var normal_pt_b := Color(tg_b.x, tg_b.y, bn_b.x, bn_b.y)
- var normal_pt_c := Color(tg_c.x, tg_c.y, bn_c.x, bn_c.y)
- var normal_pt_d := Color(tg_d.x, tg_d.y, bn_d.x, bn_d.y)
-
- return [normal_pt_a, normal_pt_b, normal_pt_c, normal_pt_d]
-
-
-## Assumes each quad in the sequence is of the same render type (same textures, values, etc...).[br]
-## [param _quads] should have been generated by [method get_consecutive_quads_for_mesh].
-static func generate_array_mesh_from_quad_sequence(_quads: Array[SS2D_Quad], _wrap_around: bool, color_encoding: int) -> ArrayMesh:
- # FIXME: _wrap_around is unused.
- if _quads.is_empty():
- return ArrayMesh.new()
-
- var total_length: float = 0.0
- for q in _quads:
- total_length += q.get_length_average()
- if total_length == 0.0:
- return ArrayMesh.new()
-
- var first_quad: SS2D_Quad = _quads[0]
- var tex: Texture2D = first_quad.texture
- # The change in length required to apply to each quad
- # to make the textures begin and end at the start and end of each texture
- var change_in_length: float = -1.0
- if tex != null:
- # How many times the texture is repeated
- var texture_reps: float = roundf(total_length / tex.get_size().x)
- # Length required to display all the reps with the texture's full width
- var texture_full_length: float = texture_reps * tex.get_size().x
- # How much each quad's texture must be offset to make up the difference in full length vs total length
- change_in_length = (texture_full_length / total_length)
-
- if first_quad.fit_texture == SS2D_Material_Edge.FITMODE.CROP:
- change_in_length = 1.0
-
- var length_elapsed: float = 0.0
- var st := SurfaceTool.new()
- st.begin(Mesh.PRIMITIVE_TRIANGLES)
- for q in _quads:
- q.update_tangents()
- for i in _quads.size():
- var q: SS2D_Quad = _quads[i]
- var section_length: float = q.get_length_average() * change_in_length
-# var highest_value: float = max(q.get_height_left(), q.get_height_right())
- # When welding and using different widths, quads can look a little weird
- # This is because they are no longer parallelograms
- # This is a tough problem to solve
- # See http://reedbeta.com/blog/quadrilateral-interpolation-part-1/
- var uv_a := Vector2(0, 0)
- var uv_b := Vector2(0, 1)
- var uv_c := Vector2(1, 1)
- var uv_d := Vector2(1, 0)
- # If we have a valid texture and this quad isn't a corner
- if tex != null and q.corner == q.CORNER.NONE:
- var x_left: float = (length_elapsed) / tex.get_size().x
- var x_right: float = (length_elapsed + section_length) / tex.get_size().x
- uv_a.x = x_left
- uv_b.x = x_left
- uv_c.x = x_right
- uv_d.x = x_right
- if q.flip_texture:
- var t: Vector2 = uv_a
- uv_a = uv_b
- uv_b = t
- t = uv_c
- uv_c = uv_d
- uv_d = t
-
- var color_a := q.color
- var color_b := q.color
- var color_c := q.color
- var color_d := q.color
-
- if color_encoding == COLOR_ENCODING.NORMALS:
- var next := _quads[wrapi(i + 1, 0, _quads.size())]
- var prev := _quads[wrapi(i - 1, 0, _quads.size())]
-
- var normals: Array[Color] = generate_normals_for_quad_interpolated(next, q, prev)
- color_a = normals[0]
- color_b = normals[1]
- color_c = normals[2]
- color_d = normals[3]
-
- # A
- _add_uv_to_surface_tool(st, uv_a)
- st.set_color(color_a)
- st.add_vertex(SS2D_Common_Functions.to_vector3(q.pt_a))
-
- # B
- _add_uv_to_surface_tool(st, uv_b)
- st.set_color(color_b)
- st.add_vertex(SS2D_Common_Functions.to_vector3(q.pt_b))
-
- # C
- _add_uv_to_surface_tool(st, uv_c)
- st.set_color(color_c)
- st.add_vertex(SS2D_Common_Functions.to_vector3(q.pt_c))
-
- # A
- _add_uv_to_surface_tool(st, uv_a)
- st.set_color(color_a)
- st.add_vertex(SS2D_Common_Functions.to_vector3(q.pt_a))
-
- # C
- _add_uv_to_surface_tool(st, uv_c)
- st.set_color(color_c)
- st.add_vertex(SS2D_Common_Functions.to_vector3(q.pt_c))
-
- # D
- _add_uv_to_surface_tool(st, uv_d)
- st.set_color(color_d)
- st.add_vertex(SS2D_Common_Functions.to_vector3(q.pt_d))
-
- length_elapsed += section_length
-
- st.index()
- st.generate_normals()
- return st.commit()
-
-
-func get_meshes(color_encoding: SS2D_Edge.COLOR_ENCODING) -> Array[SS2D_Mesh]:
- # Get Arrays of consecutive quads with the same mesh data.
- # For each array, generate Mesh Data from the quad.
-
- var consecutive_quad_arrays := SS2D_Edge.get_consecutive_quads_for_mesh(quads)
- #print("Arrays: %s" % consecutive_quad_arrays.size())
- var meshes: Array[SS2D_Mesh] = []
- for consecutive_quads in consecutive_quad_arrays:
- if consecutive_quads.is_empty():
- continue
- var array_mesh: ArrayMesh = SS2D_Edge.generate_array_mesh_from_quad_sequence(
- consecutive_quads, wrap_around, color_encoding
- )
- var quad: SS2D_Quad = consecutive_quads[0]
- var tex: Texture2D = quad.texture
- var flip: bool = quad.flip_texture
- var mesh_data := SS2D_Mesh.new(tex, flip, Transform2D(), [array_mesh], material)
- mesh_data.force_no_tiling = quad.is_tapered or quad.corner != SS2D_Quad.CORNER.NONE
- mesh_data.z_index = z_index
- mesh_data.z_as_relative = z_as_relative
- meshes.push_back(mesh_data)
-
- return meshes
-
-
-static func _add_uv_to_surface_tool(surface_tool: SurfaceTool, uv: Vector2) -> void:
- surface_tool.set_uv(uv)
- surface_tool.set_uv2(uv)
diff --git a/addons/rmsmartshape/shapes/index_map.gd b/addons/rmsmartshape/shapes/index_map.gd
deleted file mode 100644
index 31f7eda..0000000
--- a/addons/rmsmartshape/shapes/index_map.gd
+++ /dev/null
@@ -1,264 +0,0 @@
-@tool
-extends RefCounted
-class_name SS2D_IndexMap
-
-## Maps a set of indicies to an object.
-
-var object: Variant = null
-var indicies: PackedInt32Array
-
-
-## Parameter [param subresources] has no effect, no subresources to duplicate.
-func duplicate(_subresources: bool = false) -> SS2D_IndexMap:
- return SS2D_IndexMap.new(indicies.duplicate(), object)
-
-
-func _init(i: PackedInt32Array, o: Variant) -> void:
- indicies = i
- object = o
-
-
-func _to_string() -> String:
- return "[M_2_IDX] (%s) | %s" % [str(object), indicies]
-
-
-static func is_index_array_valid(idx_array: PackedInt32Array) -> bool:
- return idx_array.size() >= 2
-
-
-func is_valid() -> bool:
- return SS2D_IndexMap.is_index_array_valid(indicies)
-
-
-# FIXME: Unused. Remove eventually
-# func get_contiguous_segments() -> Array:
-# if is_contiguous():
-# return [indicies.duplicate()]
-# var segments: Array = []
-# var break_idx: int = find_break()
-# var remainder: Array[int] = indicies.duplicate()
-# while break_idx != -1:
-# var new_slice: Array[int] = []
-# for i in range(0, break_idx):
-# new_slice.push_back(remainder[i])
-# segments.push_back(new_slice)
-# remainder = remainder.slice(break_idx, remainder.size())
-# break_idx = SS2D_IndexMap.find_break_in_array(remainder)
-# if not remainder.is_empty():
-# segments.push_back(remainder)
-# return segments
-
-
-## Will join together segments that share the same idx,
-## ex. [1,2], [4,5], and [2,3,4] become [1,2,3,4,5]
-static func join_segments(segments: Array[PackedInt32Array]) -> Array[PackedInt32Array]:
- var final_segments: Array[PackedInt32Array] = []
- final_segments.assign(segments.duplicate())
-
- var to_join_tuple: Vector2i
- var join_performed := true
- while join_performed:
- join_performed = false
- for i in range(0, final_segments.size()):
- if join_performed:
- break
- for ii in range(i + 1, final_segments.size()):
- var a := final_segments[i]
- var b := final_segments[ii]
- if a[-1] == b[0]:
- to_join_tuple = Vector2i(i, ii)
- join_performed = true
- if b[-1] == a[0]:
- to_join_tuple = Vector2i(ii, i)
- join_performed = true
- if join_performed:
- break
- if join_performed:
- var idx_lowest: int = to_join_tuple[0]
- var idx_highest: int = to_join_tuple[1]
- var lowest: PackedInt32Array = final_segments[idx_lowest]
- var highest: PackedInt32Array = final_segments[idx_highest]
- final_segments.erase(lowest)
- final_segments.erase(highest)
- # pop the shared idx from lowest
- lowest.remove_at(lowest.size() - 1)
- var new_segment := lowest + highest
- final_segments.push_back(new_segment)
-
- return final_segments
-
-
-## Does each index increment by 1 without any breaks.
-func is_contiguous() -> bool:
- return SS2D_IndexMap.is_array_contiguous(indicies)
-
-
-static func is_array_contiguous(a: PackedInt32Array) -> bool:
- return find_break_in_array(a) == -1
-
-
-## Find a break in the indexes where they aren't contiguous.[br]
-## Will return -1 if there's no break.[br]
-func find_break() -> int:
- return SS2D_IndexMap.find_break_in_array(indicies)
-
-
-static func find_break_in_array(a: PackedInt32Array, offset: int = 0) -> int:
- for i in range(offset, a.size() - 1, 1):
- if is_break_at_index_in_array(a, i):
- return i + 1
- return -1
-
-
-## Whether there is a break at the given index.[br]
-## Will return -1 if there's no break.[br]
-func is_break_at_index(i: int) -> bool:
- return SS2D_IndexMap.is_break_at_index_in_array(indicies, i)
-
-
-static func is_break_at_index_in_array(a: PackedInt32Array, i: int) -> bool:
- var difference: int = absi((a[i]) - (a[i + 1]))
- return difference != 1
-
-
-func has_index(idx: int) -> bool:
- return indicies.has(idx)
-
-
-# FIXME: Unused, remove eventually.
-# func lowest_index() -> int:
-# return indicies.min()
-#
-#
-# func highest_index() -> int:
-# return indicies.max()
-
-
-# FIXME: Unused, remove eventually
-func _split_indicies_into_multiple_mappings(new_indicies: PackedInt32Array) -> Array[SS2D_IndexMap]:
- var maps: Array[SS2D_IndexMap] = []
- var break_idx := SS2D_IndexMap.find_break_in_array(new_indicies)
- var offset := 0
- var sub_indicies: PackedInt32Array
-
- while break_idx != -1:
- sub_indicies = new_indicies.slice(offset, break_idx)
-
- if SS2D_IndexMap.is_index_array_valid(sub_indicies):
- maps.push_back(SS2D_IndexMap.new(sub_indicies, object))
-
- offset = break_idx
- break_idx = SS2D_IndexMap.find_break_in_array(new_indicies, offset)
-
- sub_indicies = new_indicies.slice(offset)
-
- if SS2D_IndexMap.is_index_array_valid(sub_indicies):
- maps.push_back(SS2D_IndexMap.new(sub_indicies, object))
-
- return maps
-
-
-## FIXME: Unused, remove eventually
-## Will create a new set of SS2D_IndexMaps. [br][br]
-##
-## The new set will contain all of the indicies of the current set,
-## minus the ones specified in the indicies parameter. [br][br]
-##
-## Example: [br]
-## indicies = [0,1,2,3,4,5,6] [br]
-## to_remove = [3,4] [br]
-## new_sets = [0,1,2] [5,6] [br][br]
-##
-## This may split the IndexMap or make it invalid entirely.
-## As a result, the returned array could have 0 or several IndexMaps.
-func remove_indicies(to_remove: PackedInt32Array) -> Array[SS2D_IndexMap]:
- var out: Array[SS2D_IndexMap] = []
- var new_indicies := indicies.duplicate()
-
- for r in to_remove:
- var idx := new_indicies.find(r)
- if idx >= 0:
- new_indicies.remove_at(idx)
-
- if not SS2D_IndexMap.is_index_array_valid(new_indicies):
- return out
-
- if SS2D_IndexMap.is_array_contiguous(new_indicies):
- out.push_back(SS2D_IndexMap.new(new_indicies, object))
- return out
-
- return _split_indicies_into_multiple_mappings(new_indicies)
-
-
-## Will create a new set of SS2D_IndexMaps. [br][br]
-##
-## The new set will contain all of the edges of the current set,
-## minus the ones specified in the indicies parameter. [br][br]
-##
-## Example: [br]
-## indicies = [0,1,2,3,4,5,6] [br]
-## to_remove = [4,5] [br]
-## new_sets = [0,1,2,3,4] [4,5,6] [br][br]
-##
-## This may split the IndexMap or make it invalid entirely.
-## As a result, the returned array could have 0 or several IndexMaps.
-func remove_edges(to_remove: PackedInt32Array) -> Array[SS2D_IndexMap]:
- # Corner case
- if to_remove.size() == 2:
- var idx: int = indicies.find(to_remove[0])
- if idx != indicies.size()-1:
- if indicies[idx+1] == to_remove[1]:
- # Need one split
- var set_1 := indicies.slice(0, idx+1)
- var set_2 := indicies.slice(idx+1, indicies.size())
- var new_maps: Array[SS2D_IndexMap] = []
- if SS2D_IndexMap.is_index_array_valid(set_1):
- new_maps.push_back(SS2D_IndexMap.new(set_1, object))
- if SS2D_IndexMap.is_index_array_valid(set_2):
- new_maps.push_back(SS2D_IndexMap.new(set_2, object))
- return new_maps
- return [SS2D_IndexMap.new(indicies, object)]
-
- # General case
- var new_edges := SS2D_IndexMap.indicies_to_edges(indicies)
- for i in range(0, to_remove.size() - 1, 1):
- var idx1: int = to_remove[i]
- var idx2: int = to_remove[i + 1]
- var edges_to_remove := PackedInt32Array()
- for ii in new_edges.size():
- var edge := new_edges[ii]
- if (edge[0] == idx1 or edge[0] == idx2) and (edge[1] == idx1 or edge[1] == idx2):
- edges_to_remove.push_back(ii)
- # Reverse iterate
- for ii in range(edges_to_remove.size()-1, -1, -1):
- new_edges.remove_at(edges_to_remove[ii])
-
- new_edges = SS2D_IndexMap.join_segments(new_edges)
- var new_index_mappings: Array[SS2D_IndexMap] = []
- for e in new_edges:
- new_index_mappings.push_back(SS2D_IndexMap.new(e, object))
- return new_index_mappings
-
-
-# NOTE: Even though it makes more sense to return an Array[Vector2i], we return PackedInt32Arrays
-# instead because it makes things easier in the context where this function output is needed.
-static func indicies_to_edges(p_indicies: PackedInt32Array) -> Array[PackedInt32Array]:
- var edges: Array[PackedInt32Array] = []
- for i in p_indicies.size() - 1:
- var edge := PackedInt32Array([ i, i+1 ])
- if absi(edge[0] - edge[1]) == 1:
- edges.push_back(edge)
- return edges
-
-
-## Returns a Dict[Variant, Array[SS2D_IndexMap]]
-static func index_map_array_sort_by_object(imaps: Array) -> Dictionary:
- var dict := {}
- for imap: SS2D_IndexMap in imaps:
- if not dict.has(imap.object):
- var arr: Array[SS2D_IndexMap] = [ imap ]
- dict[imap.object] = arr
- else:
- var arr: Array[SS2D_IndexMap] = dict[imap.object]
- arr.push_back(imap)
- return dict
diff --git a/addons/rmsmartshape/shapes/mesh.gd b/addons/rmsmartshape/shapes/mesh.gd
deleted file mode 100644
index 0c26f9b..0000000
--- a/addons/rmsmartshape/shapes/mesh.gd
+++ /dev/null
@@ -1,80 +0,0 @@
-@tool
-extends RefCounted
-class_name SS2D_Mesh
-
-## Used to organize all requested meshes to be rendered by their textures.
-
-var texture: Texture2D = null
-var flip_texture: bool = false
-var meshes: Array[ArrayMesh] = []
-var mesh_transform: Transform2D = Transform2D()
-var material: Material = null
-var z_index: int = 0
-var z_as_relative: bool = true
-var show_behind_parent: bool = false
-var force_no_tiling: bool = false
-
-
-func _init(
- t: Texture2D = null,
- f: bool = false,
- xform: Transform2D = Transform2D(),
- m: Array[ArrayMesh] = [],
- mat: Material = null
-) -> void:
- texture = t
- flip_texture = f
- meshes = m
- mesh_transform = xform
- material = mat
-
-
-# Note: Not an override.
-func duplicate(subresources: bool = false) -> SS2D_Mesh:
- var copy := SS2D_Mesh.new()
- copy.texture = texture
- copy.flip_texture = flip_texture
- copy.mesh_transform = mesh_transform
- copy.material = material
- copy.z_index = z_index
- copy.z_as_relative = z_as_relative
- copy.show_behind_parent = show_behind_parent
- copy.force_no_tiling = force_no_tiling
- copy.meshes = []
- if subresources:
- for m in meshes:
- copy.meshes.push_back(m.duplicate(true))
- return copy
-
-
-func matches(tex: Texture2D, f: bool, t: Transform2D, m: Material, zi: int, zb: bool) -> bool:
- return (
- tex == texture
- and f == flip_texture
- and t == mesh_transform
- and m == material
- and zi == z_index
- and zb == z_as_relative
- )
-
-
-func mesh_matches(m: SS2D_Mesh) -> bool:
- return matches(
- m.texture,
- m.flip_texture,
- m.mesh_transform,
- m.material,
- m.z_index,
- m.z_as_relative
- )
-
-
-func debug_print_array_mesh(am: ArrayMesh) -> String:
- var s := "Faces:%s | Surfs:%s | " % [am.get_faces(), am.get_surface_count()]
- return s
-
-
-func render(ci: CanvasItem) -> void:
- #print("mesh count %s" % meshes.size())
- for mesh in meshes:
- ci.draw_mesh(mesh, texture)
diff --git a/addons/rmsmartshape/shapes/point.gd b/addons/rmsmartshape/shapes/point.gd
deleted file mode 100644
index a7b58e4..0000000
--- a/addons/rmsmartshape/shapes/point.gd
+++ /dev/null
@@ -1,72 +0,0 @@
-@tool
-extends Resource
-class_name SS2D_Point
-
-@export var position: Vector2 : set = _set_position
-@export var point_in: Vector2 : set = _set_point_in
-@export var point_out: Vector2 : set = _set_point_out
-@export var properties: SS2D_VertexProperties : set = _set_properties
-
-# If class members are written to, the 'changed' signal may not be emitted
-# Signal is only emitted when data is actually changed
-# If assigned data is the same as the existing data, no signal is emitted
-
-
-func _init(pos: Vector2 = Vector2(0, 0)) -> void:
- position = pos
- point_in = Vector2(0, 0)
- point_out = Vector2(0, 0)
- properties = SS2D_VertexProperties.new()
-
-
-func equals(other: SS2D_Point) -> bool:
- if position != other.position:
- return false
- if point_in != other.point_in:
- return false
- if point_out != other.point_out:
- return false
- print ("E! %s" % properties.equals(other.properties))
- if not properties.equals(other.properties):
- return false
- return true
-
-
-func _set_position(v: Vector2) -> void:
- if position != v:
- position = v
- emit_changed()
-
-
-func _set_point_in(v: Vector2) -> void:
- if point_in != v:
- point_in = v
- emit_changed()
-
-
-func _set_point_out(v: Vector2) -> void:
- if point_out != v:
- point_out = v
- emit_changed()
-
-
-func _set_properties(other: SS2D_VertexProperties) -> void:
- # FIXME: What if other is null?
- if properties == null or not properties.equals(other):
- if properties:
- properties.changed.disconnect(_on_properties_changed)
-
- properties = other
-
- if properties:
- properties.changed.connect(_on_properties_changed)
-
- emit_changed()
-
-
-func _to_string() -> String:
- return "" % [position]
-
-
-func _on_properties_changed() -> void:
- emit_changed()
diff --git a/addons/rmsmartshape/shapes/point_array.gd b/addons/rmsmartshape/shapes/point_array.gd
deleted file mode 100644
index 0d74011..0000000
--- a/addons/rmsmartshape/shapes/point_array.gd
+++ /dev/null
@@ -1,675 +0,0 @@
-@tool
-extends Resource
-class_name SS2D_Point_Array
-
-enum CONSTRAINT { NONE = 0, AXIS_X = 1, AXIS_Y = 2, CONTROL_POINTS = 4, PROPERTIES = 8, ALL = 15 }
-
-# Maps a key to each point: Dict[int, SS2D_Point]
-@export var _points: Dictionary = {} : set = _set_points
-# Contains all keys; the order of the keys determines the order of the points
-@export var _point_order := PackedInt32Array() : set = set_point_order
-
-## Dict[Vector2i, CONSTRAINT]
-## Key is tuple of point_keys; Value is the CONSTRAINT enum.
-@export var _constraints: Dictionary = {} : set = _set_constraints
-# Next key value to generate
-@export var _next_key: int = 0 : set = set_next_key
-
-## Dict[Vector2i, SS2D_Material_Edge_Metadata]
-## Dictionary of specific materials to use for specific tuples of points.
-## Key is tuple of two point keys, value is material.
-@export var _material_overrides: Dictionary = {} : set = set_material_overrides
-
-## Controls how many subdivisions a curve segment may face before it is considered
-## approximate enough.
-@export_range(0, 8, 1)
-var tessellation_stages: int = 3 : set = set_tessellation_stages
-
-## Controls how many degrees the midpoint of a segment may deviate from the real
-## curve, before the segment has to be subdivided.
-@export_range(0.1, 16.0, 0.1, "or_greater", "or_lesser")
-var tessellation_tolerance: float = 6.0 : set = set_tessellation_tolerance
-
-@export_range(1, 512) var curve_bake_interval: float = 20.0 : set = set_curve_bake_interval
-
-var _constraints_enabled: bool = true
-var _updating_constraints := false
-var _keys_to_update_constraints := PackedInt32Array()
-
-var _changed_during_update := false
-var _updating := false
-
-# Point caches
-var _point_cache_dirty := true
-var _vertex_cache := PackedVector2Array()
-var _curve := Curve2D.new()
-var _curve_no_control_points := Curve2D.new()
-var _tesselation_cache := PackedVector2Array()
-var _tess_vertex_mapping := SS2D_TesselationVertexMapping.new()
-
-## Gets called when points were modified.
-## In comparison to the "changed" signal, "update_finished" will only be called once after
-## begin/end_update() blocks, while "changed" will be called for every singular change.
-## Hence, this signal is usually better suited to react to point updates.
-signal update_finished()
-
-signal constraint_removed(key1: int, key2: int)
-signal material_override_changed(tuple: Vector2i)
-
-###################
-# HANDLING POINTS #
-###################
-
-
-func _init() -> void:
- # Required by Godot to correctly make unique instances of this resource
- _points = {}
- _constraints = {}
- _next_key = 0
- # Assigning an empty dict to _material_overrides this way
- # instead of assigning in the declaration appears to bypass
- # a weird Godot bug where _material_overrides of one shape
- # interfere with another
- if _material_overrides == null:
- _material_overrides = {}
-
-
-func clone(deep: bool = false) -> SS2D_Point_Array:
- var copy := SS2D_Point_Array.new()
- copy._next_key = _next_key
- copy.tessellation_stages = tessellation_stages
- copy.tessellation_tolerance = tessellation_tolerance
- copy.curve_bake_interval = curve_bake_interval
-
- if deep:
- var new_point_dict := {}
- for k: int in _points:
- new_point_dict[k] = get_point(k).duplicate(true)
- copy._points = new_point_dict
- copy._point_order = _point_order.duplicate()
- copy._constraints = _constraints.duplicate()
- copy._material_overrides = _material_overrides.duplicate()
- else:
- copy._points = _points
- copy._point_order = _point_order
- copy._constraints = _constraints
- copy._material_overrides = _material_overrides
-
- return copy
-
-
-## Called by Godot when loading from a saved scene
-func _set_points(ps: Dictionary) -> void:
- _points = ps
- for k: int in _points:
- _hook_point(k)
- _changed()
-
-
-func set_point_order(po: PackedInt32Array) -> void:
- _point_order = po
- _changed()
-
-
-func _set_constraints(cs: Dictionary) -> void:
- _constraints = cs
-
- # For backwards compatibility (Array to Vector2i transition)
- # FIXME: Maybe remove during the next breaking release
- SS2D_IndexTuple.dict_validate(_constraints, TYPE_INT)
-
-
-func set_next_key(i: int) -> void:
- _next_key = i
-
-
-func __generate_key(next: int) -> int:
- if not is_key_valid(next):
- return __generate_key(maxi(next + 1, 0))
- return next
-
-
-## Reserve a key. It will not be generated again.
-func reserve_key() -> int:
- var next: int = __generate_key(_next_key)
- _next_key = next + 1
- return next
-
-
-## Returns next key that would be generated when adding a new point, e.g. when [method add_point] is called.
-func get_next_key() -> int:
- return __generate_key(_next_key)
-
-
-func is_key_valid(k: int) -> bool:
- return k >= 0 and not _points.has(k)
-
-
-## Add a point and insert it at the given index or at the end by default.
-## Returns the key of the added point.
-func add_point(point: Vector2, idx: int = -1, use_key: int = -1) -> int:
-# print("Add Point :: ", point, " | idx: ", idx, " | key: ", use_key, " |")
- if use_key == -1 or not is_key_valid(use_key):
- use_key = reserve_key()
- if use_key == _next_key:
- _next_key += 1
- _points[use_key] = SS2D_Point.new(point)
- _hook_point(use_key)
- _point_order.push_back(use_key)
- if idx != -1:
- set_point_index(use_key, idx)
- _changed()
- return use_key
-
-
-## Deprecated. There is no reason to use this function, points can be modified directly.
-## @deprecated
-func set_point(key: int, value: SS2D_Point) -> void:
- if has_point(key):
- # FIXME: Should there be a call to remove_constraints() like in remove_point()? Because
- # we're technically deleting a point and replacing it with another.
- _unhook_point(get_point(key))
- _points[key] = value
- _hook_point(key)
- _changed()
-
-
-## Connects the changed signal of the given point. Requires that the point exists in _points.
-func _hook_point(key: int) -> void:
- var p := get_point(key)
- if not p.changed.is_connected(_on_point_changed):
- p.changed.connect(_on_point_changed.bind(key))
-
-
-## Disconnects the changed signal of the given point. See also _hook_point().
-func _unhook_point(p: SS2D_Point) -> void:
- if not p.changed.is_connected(_on_point_changed):
- p.changed.disconnect(_on_point_changed)
-
-
-func is_index_in_range(idx: int) -> bool:
- return idx >= 0 and idx < _point_order.size()
-
-
-func get_point_key_at_index(idx: int) -> int:
- return _point_order[idx]
-
-
-func get_edge_keys_for_indices(indices: Vector2i) -> Vector2i:
- return Vector2i(
- get_point_key_at_index(indices.x),
- get_point_key_at_index(indices.y)
- )
-
-
-func get_point_at_index(idx: int) -> SS2D_Point:
- return _points[_point_order[idx]]
-
-
-## Returns the point with the given key as reference or null if it does not exist.
-func get_point(key: int) -> SS2D_Point:
- return _points.get(key)
-
-
-func get_point_count() -> int:
- return _point_order.size()
-
-
-func get_point_index(key: int) -> int:
- if has_point(key):
- var idx := 0
- for k in _point_order:
- if key == k:
- return idx
- idx += 1
- return -1
-
-
-## Reverse order of points in point array.[br]
-## I.e. [1, 2, 3, 4] will become [4, 3, 2, 1].[br]
-func invert_point_order() -> void:
- # Postpone `changed` and disable constraints.
- var was_updating: bool = _updating
- _updating = true
- disable_constraints()
-
- _point_order.reverse()
- # Swap Bezier points.
- for p: SS2D_Point in _points.values():
- if p.point_out != p.point_in:
- var tmp: Vector2 = p.point_out
- p.point_out = p.point_in
- p.point_in = tmp
-
- # Re-enable contraits and emit `changed`.
- enable_constraints()
- _updating = was_updating
- _changed()
-
-
-func set_point_index(key: int, idx: int) -> void:
- if not has_point(key):
- return
- var old_idx: int = get_point_index(key)
- if idx < 0 or idx >= _points.size():
- idx = _points.size() - 1
- if idx == old_idx:
- return
- _point_order.remove_at(old_idx)
- _point_order.insert(idx, key)
- _changed()
-
-
-func has_point(key: int) -> bool:
- return _points.has(key)
-
-
-func get_all_point_keys() -> PackedInt32Array:
- # _point_order should contain every single point ONLY ONCE
- return _point_order
-
-
-func remove_point(key: int) -> bool:
- if has_point(key):
-# print("Remove Point :: ", get_point_position(key), " | idx: ", get_point_index(key), " | key: ", key, " |")
- remove_constraints(key)
- _unhook_point(get_point(key))
- _point_order.remove_at(get_point_index(key))
- _points.erase(key)
- _changed()
- return true
- return false
-
-
-func remove_point_at_index(idx: int) -> void:
- remove_point(get_point_key_at_index(idx))
-
-
-## Remove all points from point array.
-func clear() -> void:
- _points.clear()
- _point_order.clear()
- _constraints.clear()
- _next_key = 0
- _changed()
-
-
-## point_in controls the edge leading from the previous vertex to this one
-func set_point_in(key: int, value: Vector2) -> void:
- if has_point(key):
- _points[key].point_in = value
- _changed()
-
-
-func get_point_in(key: int) -> Vector2:
- if has_point(key):
- return _points[key].point_in
- return Vector2(0, 0)
-
-
-## point_out controls the edge leading from this vertex to the next
-func set_point_out(key: int, value: Vector2) -> void:
- if has_point(key):
- _points[key].point_out = value
- _changed()
-
-
-func get_point_out(key: int) -> Vector2:
- if has_point(key):
- return _points[key].point_out
- return Vector2(0, 0)
-
-
-func set_point_position(key: int, value: Vector2) -> void:
- if has_point(key):
- _points[key].position = value
- _changed()
-
-
-func get_point_position(key: int) -> Vector2:
- if has_point(key):
- return _points[key].position
- return Vector2(0, 0)
-
-
-func set_point_properties(key: int, value: SS2D_VertexProperties) -> void:
- if has_point(key):
- _points[key].properties = value
- _changed()
-
-
-func get_point_properties(key: int) -> SS2D_VertexProperties:
- var p := get_point(key)
- return p.properties if p else null
-
-
-## Returns the corresponding key for a given point or -1 if it does not exist.
-func get_key_from_point(p: SS2D_Point) -> int:
- for k: int in _points:
- if p == _points[k]:
- return k
- return -1
-
-
-func _on_point_changed(key: int) -> void:
- if _updating_constraints:
- _keys_to_update_constraints.push_back(key)
- else:
- update_constraints(key)
-
-
-## Begin updating the shape.[br]
-## Shape mesh and curve will only be updated after [method end_update] is called.
-func begin_update() -> void:
- _updating = true
-
-
-## End updating the shape.[br]
-## Mesh and curve will be updated, if changes were made to points array after
-## [method begin_update] was called.
-func end_update() -> bool:
- var was_dirty := _changed_during_update
- _updating = false
- _changed_during_update = false
- if was_dirty:
- update_finished.emit()
- return was_dirty
-
-
-## Is shape in the middle of being updated.
-## Returns [code]true[/code] after [method begin_update] and before [method end_update].
-func is_updating() -> bool:
- return _updating
-
-
-func _changed() -> void:
- _point_cache_dirty = true
-
- emit_changed()
-
- if _updating:
- _changed_during_update = true
- else:
- update_finished.emit()
-
-###############
-# CONSTRAINTS #
-###############
-
-
-func disable_constraints() -> void:
- _constraints_enabled = false
-
-
-func enable_constraints() -> void:
- _constraints_enabled = true
-
-
-func _update_constraints(src: int) -> void:
- if not _constraints_enabled:
- return
-
- var constraints := get_point_constraints_tuples(src)
-
- for tuple in constraints:
- var constraint: CONSTRAINT = SS2D_IndexTuple.dict_get(_constraints, tuple)
-
- if constraint == CONSTRAINT.NONE:
- continue
-
- var dst: int = SS2D_IndexTuple.get_other_value(tuple, src)
-
- if constraint & CONSTRAINT.AXIS_X:
- set_point_position(dst, Vector2(get_point_position(src).x, get_point_position(dst).y))
- if constraint & CONSTRAINT.AXIS_Y:
- set_point_position(dst, Vector2(get_point_position(dst).x, get_point_position(src).y))
- if constraint & CONSTRAINT.CONTROL_POINTS:
- set_point_in(dst, get_point_in(src))
- set_point_out(dst, get_point_out(src))
- if constraint & CONSTRAINT.PROPERTIES:
- set_point_properties(dst, get_point_properties(src))
-
-
-## Will mutate points based on constraints.[br]
-## Values from Passed key will be used to update constrained points.[br]
-func update_constraints(src: int) -> void:
- if not has_point(src) or _updating_constraints:
- return
-
- _updating_constraints = true
- # Initial pass of updating constraints
- _update_constraints(src)
-
- # Subsequent required passes of updating constraints
- while not _keys_to_update_constraints.is_empty():
- var key_set := _keys_to_update_constraints
- _keys_to_update_constraints = PackedInt32Array()
- for k in key_set:
- _update_constraints(k)
-
- _updating_constraints = false
- _changed()
-
-
-## Returns all point constraint that include the given point key.
-## Returns a Dictionary[Vector2i, CONSTRAINT].
-func get_point_constraints(key1: int) -> Dictionary:
- var constraints := {}
- var tuples := get_point_constraints_tuples(key1)
-
- for t in tuples:
- constraints[t] = get_point_constraint(t.x, t.y)
-
- return constraints
-
-
-## Returns all point constraint tuples that include the given point key.
-func get_point_constraints_tuples(key1: int) -> Array[Vector2i]:
- return SS2D_IndexTuple.dict_find_partial(_constraints, key1)
-
-
-## Returns the constraint for a pair of keys or CONSTRAINT.NONE if no constraint exists.
-func get_point_constraint(key1: int, key2: int) -> CONSTRAINT:
- return SS2D_IndexTuple.dict_get(_constraints, Vector2i(key1, key2), CONSTRAINT.NONE)
-
-
-## Set a constraint between two points. If the constraint is NONE, remove_constraint() is called instead.
-func set_constraint(key1: int, key2: int, constraint: CONSTRAINT) -> void:
- var t := Vector2i(key1, key2)
-
- if constraint == CONSTRAINT.NONE:
- remove_constraint(t)
- return
-
- SS2D_IndexTuple.dict_set(_constraints, t, constraint)
- update_constraints(key1)
- _changed()
-
-
-## Remove all constraints involving the given point key.
-func remove_constraints(key1: int) -> void:
- for tuple in get_point_constraints_tuples(key1):
- remove_constraint(tuple)
-
-
-## Remove the constraint between the two point indices of the given tuple.
-func remove_constraint(point_index_tuple: Vector2i) -> void:
- if SS2D_IndexTuple.dict_erase(_constraints, point_index_tuple):
- emit_signal("constraint_removed", point_index_tuple.x, point_index_tuple.y)
-
-
-########
-# MISC #
-########
-func debug_print() -> void:
- for k in get_all_point_keys():
- var pos: Vector2 = get_point_position(k)
- var _in: Vector2 = get_point_in(k)
- var out: Vector2 = get_point_out(k)
- print("%s = P:%s | I:%s | O:%s" % [k, pos, _in, out])
-
-
-######################
-# MATERIAL OVERRIDES #
-######################
-## dict: Dict[Vector2i, SS2D_Material_Edge_Metadata]
-func set_material_overrides(dict: Dictionary) -> void:
- # For backwards compatibility (Array to Vector2i transition)
- # FIXME: Maybe remove during the next breaking release
- SS2D_IndexTuple.dict_validate(dict, SS2D_Material_Edge_Metadata)
-
- if _material_overrides != null:
- for old: SS2D_Material_Edge_Metadata in _material_overrides.values():
- _unhook_mat(old)
-
- _material_overrides = dict
-
- for tuple: Vector2i in _material_overrides:
- _hook_mat(tuple, _material_overrides[tuple])
-
-
-func has_material_override(tuple: Vector2i) -> bool:
- return SS2D_IndexTuple.dict_has(_material_overrides, tuple)
-
-
-func remove_material_override(tuple: Vector2i) -> void:
- var old := get_material_override(tuple)
-
- if old != null:
- _unhook_mat(old)
- SS2D_IndexTuple.dict_erase(_material_overrides, tuple)
- _on_material_override_changed(tuple)
-
-
-func set_material_override(tuple: Vector2i, mat: SS2D_Material_Edge_Metadata) -> void:
- var old := get_material_override(tuple)
-
- if old != null:
- if old == mat:
- return
- else:
- _unhook_mat(old)
-
- _hook_mat(tuple, mat)
- SS2D_IndexTuple.dict_set(_material_overrides, tuple, mat)
- _on_material_override_changed(tuple)
-
-
-## Returns the material override for the edge defined by the given point index tuple, or null if
-## there is no override.
-func get_material_override(tuple: Vector2i) -> SS2D_Material_Edge_Metadata:
- return SS2D_IndexTuple.dict_get(_material_overrides, tuple)
-
-
-func _hook_mat(tuple: Vector2i, mat: SS2D_Material_Edge_Metadata) -> void:
- if not mat.changed.is_connected(_on_material_override_changed):
- mat.changed.connect(_on_material_override_changed.bind(tuple))
-
-
-func _unhook_mat(mat: SS2D_Material_Edge_Metadata) -> void:
- if mat.changed.is_connected(_on_material_override_changed):
- mat.changed.disconnect(_on_material_override_changed)
-
-
-## Returns a list of index tuples for wich material overrides exist.
-func get_material_overrides() -> Array[Vector2i]:
- var keys: Array[Vector2i] = []
- keys.assign(_material_overrides.keys())
- return keys
-
-
-func clear_all_material_overrides() -> void:
- _material_overrides = {}
-
-
-
-## Returns a PackedVector2Array with all points of the shape.
-func get_vertices() -> PackedVector2Array:
- _update_cache()
- return _vertex_cache
-
-
-## Returns a Curve2D representing the shape including bezier handles.
-func get_curve() -> Curve2D:
- _update_cache()
- return _curve
-
-
-## Returns a Curve2D representing the shape, disregarding bezier handles.
-func get_curve_no_control_points() -> Curve2D:
- _update_cache()
- return _curve_no_control_points
-
-
-## Returns a PackedVector2Array with all points
-func get_tessellated_points() -> PackedVector2Array:
- _update_cache()
- return _tesselation_cache
-
-
-func set_tessellation_stages(value: int) -> void:
- tessellation_stages = value
- _changed()
-
-
-func set_tessellation_tolerance(value: float) -> void:
- tessellation_tolerance = value
- _changed()
-
-
-func set_curve_bake_interval(f: float) -> void:
- curve_bake_interval = f
- _curve.bake_interval = f
- _changed()
-
-
-func get_tesselation_vertex_mapping() -> SS2D_TesselationVertexMapping:
- _update_cache()
- return _tess_vertex_mapping
-
-
-func _update_cache() -> void:
- # NOTE: Theoretically one could differentiate between vertex list dirty, curve dirty and
- # tesselation dirty to never waste any computation time.
- # However, 99% of the time, the cache will be dirty due to vertex updates, so we don't bother.
-
- if not _point_cache_dirty:
- return
-
- var keys := get_all_point_keys()
-
- _vertex_cache.resize(keys.size())
- _curve.clear_points()
- _curve_no_control_points.clear_points()
-
- for i in keys.size():
- var key := keys[i]
- var pos := get_point_position(keys[i])
-
- # Vertex cache
- _vertex_cache[i] = pos
-
- # Curves
- _curve.add_point(pos, get_point_in(key), get_point_out(key))
- _curve_no_control_points.add_point(pos)
-
- # Tesselation
- # Point 0 will be the same on both the curve points and the vertices
- # Point size - 1 will be the same on both the curve points and the vertices
- _tesselation_cache = _curve.tessellate(tessellation_stages, tessellation_tolerance)
-
- if _tesselation_cache.size() >= 2:
- _tesselation_cache[0] = _curve.get_point_position(0)
- _tesselation_cache[-1] = _curve.get_point_position(_curve.get_point_count() - 1)
-
- _tess_vertex_mapping.build(_tesselation_cache, _vertex_cache)
-
- _point_cache_dirty = false
-
-
-func _to_string() -> String:
- return "" % [_points.keys(), _point_order]
-
-
-func _on_material_override_changed(tuple: Vector2i) -> void:
- material_override_changed.emit(tuple)
diff --git a/addons/rmsmartshape/shapes/quad.gd b/addons/rmsmartshape/shapes/quad.gd
deleted file mode 100644
index a5d3375..0000000
--- a/addons/rmsmartshape/shapes/quad.gd
+++ /dev/null
@@ -1,210 +0,0 @@
-@tool
-extends RefCounted
-class_name SS2D_Quad
-
-enum ORIENTATION { COLINEAR = 0, CCW, CW }
-enum CORNER { NONE = 0, OUTER, INNER }
-
-var pt_a: Vector2
-var pt_b: Vector2
-var pt_c: Vector2
-var pt_d: Vector2
-
-var tg_a : Vector2
-var tg_b : Vector2
-var tg_c : Vector2
-var tg_d : Vector2
-
-var bn_a : Vector2
-var bn_b : Vector2
-var bn_c : Vector2
-var bn_d : Vector2
-
-var texture: Texture2D = null
-var color: Color = Color(1.0, 1.0, 1.0, 1.0)
-
-var is_tapered: bool = false
-var ignore_weld_next: bool = false
-var flip_texture: bool = false
-# Deprecated, should remove control_point_index
-var control_point_index: int
-var fit_texture := SS2D_Material_Edge.FITMODE.SQUISH_AND_STRETCH
-
-# Contains value from CORNER enum
-var corner: int = 0
-
-
-# Will return two quads split down the middle of this one
-func bisect() -> Array[SS2D_Quad]:
- var delta: Vector2 = pt_d - pt_a
- var delta_normal := delta.normalized()
- var quad_left: SS2D_Quad = duplicate()
- var quad_right: SS2D_Quad = duplicate()
- var mid_point := Vector2(get_length_average(), 0.0) * delta_normal
- quad_left.pt_d = pt_a + mid_point
- quad_left.pt_c = pt_b + mid_point
- quad_right.pt_a = pt_d - mid_point
- quad_right.pt_b = pt_c - mid_point
- return [quad_left, quad_right]
-
-
-func _to_string() -> String:
- return "[Quad] A:%s B:%s C:%s D:%s | Corner: %s" % [pt_a, pt_b, pt_c, pt_d, corner]
-
-
-func matches_quad(q: SS2D_Quad) -> bool:
- return (
- texture == q.texture
- and color == q.color
- and flip_texture == q.flip_texture
- and fit_texture == q.fit_texture
- )
-
-
-func duplicate() -> SS2D_Quad:
- var q := SS2D_Quad.new()
- q.pt_a = pt_a
- q.pt_b = pt_b
- q.pt_c = pt_c
- q.pt_d = pt_d
-
- q.texture = texture
- q.color = color
-
- q.flip_texture = flip_texture
- q.control_point_index = control_point_index
-
- q.corner = corner
- return q
-
-
-func update_tangents() -> void:
- tg_a = (pt_d-pt_a).normalized()
- tg_b = (pt_c-pt_b).normalized()
- tg_c = tg_b
- tg_d = tg_a
-
- bn_a = (pt_b - pt_a).normalized()
- bn_b = bn_a
- bn_c = (pt_c - pt_d).normalized()
- bn_d = bn_c
-
-
-func _init(
- a: Vector2 = Vector2.ZERO,
- b: Vector2 = Vector2.ZERO,
- c: Vector2 = Vector2.ZERO,
- d: Vector2 = Vector2.ZERO,
- t: Texture2D = null,
- f: bool = false
-) -> void:
- pt_a = a
- pt_b = b
- pt_c = c
- pt_d = d
-
- texture = t
- flip_texture = f
-
-
-func get_rotation() -> float:
- return SS2D_NormalRange.get_angle_from_vector(pt_c - pt_a)
-
-
-## Given three colinear points p, q, r, the function checks if
-## point q lies on line segment 'pr'.
-func on_segment(p: Vector2, q: Vector2, r: Vector2) -> bool:
- return (
- (q.x <= maxf(p.x, r.x))
- and (q.x >= minf(p.x, r.x))
- and (q.y <= maxf(p.y, r.y))
- and (q.y >= minf(p.y, r.y))
- )
-
-
-## Returns CCW, CW, or colinear.[br]
-## see https://www.geeksforgeeks.org/check-if-two-given-line-segments-intersect/
-func get_orientation(a: Vector2, b: Vector2, c: Vector2) -> ORIENTATION:
- var val := (float(b.y - a.y) * (c.x - b.x)) - (float(b.x - a.x) * (c.y - b.y))
- if val > 0:
- return ORIENTATION.CW
- elif val < 0:
- return ORIENTATION.CCW
- return ORIENTATION.COLINEAR
-
-
-## Return true if line segments p1q1 and p2q2 intersect.
-func edges_intersect(p1: Vector2, q1: Vector2, p2: Vector2, q2: Vector2) -> bool:
- var o1 := get_orientation(p1, q1, p2)
- var o2 := get_orientation(p1, q1, q2)
- var o3 := get_orientation(p2, q2, p1)
- var o4 := get_orientation(p2, q2, q1)
- # General case
- if (o1 != o2) and (o3 != o4):
- return true
-
- # Special Cases
- # p1 , q1 and p2 are colinear and p2 lies on segment p1q1
- if (o1 == 0) and on_segment(p1, p2, q1):
- return true
-
- # p1 , q1 and q2 are colinear and q2 lies on segment p1q1
- if (o2 == 0) and on_segment(p1, q2, q1):
- return true
-
- # p2 , q2 and p1 are colinear and p1 lies on segment p2q2
- if (o3 == 0) and on_segment(p2, p1, q2):
- return true
-
- # p2 , q2 and q1 are colinear and q1 lies on segment p2q2
- if (o4 == 0) and on_segment(p2, q1, q2):
- return true
-
- return false
-
-
-func self_intersects() -> bool:
- return edges_intersect(pt_a, pt_d, pt_b, pt_c) or edges_intersect(pt_a, pt_b, pt_d, pt_c)
-
-
-func render_lines(ci: CanvasItem) -> void:
- ci.draw_line(pt_a, pt_b, color)
- ci.draw_line(pt_b, pt_c, color)
- ci.draw_line(pt_c, pt_d, color)
- ci.draw_line(pt_d, pt_a, color)
-
-
-func render_points(rad: float, intensity: float, ci: CanvasItem) -> void:
- ci.draw_circle(pt_a, rad, Color(intensity, 0, 0))
- ci.draw_circle(pt_b, rad, Color(0, 0, intensity))
- ci.draw_circle(pt_c, rad, Color(0, intensity, 0))
- ci.draw_circle(pt_d, rad, Color(intensity, 0, intensity))
-
-
-func get_height_average() -> float:
- return (get_height_left() + get_height_right()) / 2.0
-
-
-func get_height_left() -> float:
- return pt_a.distance_to(pt_b)
-
-
-func get_height_right() -> float:
- return pt_d.distance_to(pt_c)
-
-
-## Returns the difference in height between the left and right sides.
-func get_height_difference() -> float:
- return get_height_left() - get_height_right()
-
-
-func get_length_average() -> float:
- return (get_length_top() + get_length_bottom()) / 2.0
-
-
-func get_length_top() -> float:
- return pt_d.distance_to(pt_a)
-
-
-func get_length_bottom() -> float:
- return pt_c.distance_to(pt_b)
diff --git a/addons/rmsmartshape/shapes/shape.gd b/addons/rmsmartshape/shapes/shape.gd
deleted file mode 100644
index 8dacecf..0000000
--- a/addons/rmsmartshape/shapes/shape.gd
+++ /dev/null
@@ -1,1894 +0,0 @@
-@tool
-@icon("../assets/closed_shape.png")
-extends Node2D
-class_name SS2D_Shape
-
-## Represents the base functionality for all smart shapes.
-
-# Functions consist of the following categories:[br]
-# - Setters / Getters
-# - Curve
-# - Curve Wrapper
-# - Godot
-# - Misc
-#
-# To use search to jump between categories, use the regex: # .+ #
-
-################
-#-DECLARATIONS-#
-################
-
-var _dirty: bool = false
-var _edges: Array[SS2D_Edge] = []
-var _meshes: Array[SS2D_Mesh] = []
-var _collision_polygon_node: CollisionPolygon2D
-# Whether or not the plugin should allow editing this shape
-var can_edit: bool = true
-
-signal points_modified
-signal on_dirty_update
-signal make_unique_pressed(shape: SS2D_Shape)
-
-enum ORIENTATION { COLINEAR, CLOCKWISE, C_CLOCKWISE }
-
-enum CollisionGenerationMethod {
- ## Uses the shape curve to generate a collision polygon. Usually this method is accurate enough.
- ## For open shapes, a precise method will be used instead, as the fast method is not suitable.
- Fast,
- ## Uses the edge generation algorithm to create an accurate collision representation that
- ## exactly matches the shape's visuals.
- ## Depending on the shape's complexity, this method is very expensive.
- Precise,
-}
-
-enum CollisionUpdateMode {
- ## Only update collisions in editor. If the corresponding CollisionPolygon2D is part of the same
- ## scene, it will be saved automatically by Godot, hence no additional regeneration at runtime
- ## is necessary, which reduces the loading times.
- ## Does not work if the CollisionPolygon2D is part of an instanced scene, as only the scene root
- ## node will be saved by Godot.
- Editor,
- ## Only update collisions during runtime. Improves the shape-editing performance in editor but
- ## increases loading times as collision generation is deferred to runtime.
- Runtime,
- ## Update collisions both in editor and during runtime. This is the default behavior in older
- ## SS2D versions.
- EditorAndRuntime,
-}
-
-###########
-#-EXPORTS-#
-###########
-
-# Execute to refresh shape rendered geometry and textures.
-@warning_ignore("unused_private_class_variable")
-@export_placeholder("ActionProperty") var _refresh: String = "" : set = _refresh_action
-# ActionProperty will add a button to inspector to execute this action.
-# When non-empty string is passed into setter, action is considerd executed.
-
-## Visualize generated quads and edges.
-@export var editor_debug: bool = false : set = _set_editor_debug
-
-## @deprecated
-@export_range(1, 512) var curve_bake_interval: float = 20.0 :
- set(value): _points.curve_bake_interval = value
- get: return _points.curve_bake_interval
-
-## How to treat color data. See [enum SS2D_Edge.COLOR_ENCODING].
-@export var color_encoding: SS2D_Edge.COLOR_ENCODING = SS2D_Edge.COLOR_ENCODING.COLOR : set = set_color_encoding
-
-@export_group("Geometry")
-
-# Execute to make shape point geometry unique (not materials).
-@warning_ignore("unused_private_class_variable")
-@export_placeholder("ActionProperty") var _make_unique: String = "" : set = _make_unique_action
-# ActionProperty will add a button to inspector to execute this action.
-# When non-empty string is passed into setter, action is considerd executed.
-
-## Resource that holds shape point geometry (aka point array).
-@export var _points: SS2D_Point_Array : set = set_point_array
-
-@export_group("Edges")
-
-@export var flip_edges: bool = false : set = set_flip_edges
-
-## Enable/disable rendering of the edges.
-@export var render_edges: bool = true : set = set_render_edges
-
-@export_group("Materials")
-
-## Contains textures and data on how to visualize the shape.
-@export var shape_material := SS2D_Material_Shape.new() : set = _set_material
-
-## Dictionary of (Array of 2 keys) to (SS2D_Material_Edge_Metadata)
-## Deprecated, exists for Support of older versions
-## @deprecated
-@export var material_overrides: Dictionary = {} : set = set_material_overrides
-
-@export_group("Tesselation")
-
-## Controls how many subdivisions a curve segment may face before it is considered
-## approximate enough.
-## @deprecated
-@export_range(0, 8, 1)
-var tessellation_stages: int = 3 :
- set(value): _points.tessellation_stages = value
- get: return _points.tessellation_stages
-
-## Controls how many degrees the midpoint of a segment may deviate from the real
-## curve, before the segment has to be subdivided.
-## @deprecated
-@export_range(0.1, 16.0, 0.1, "or_greater", "or_lesser")
-var tessellation_tolerence: float = 6.0 :
- set(value): _points.tessellation_tolerance = value
- get: return _points.tessellation_tolerance
-
-@export_group("Collision")
-
-## Controls which method should be used to generate the collision shape.
-@export var collision_generation_method := CollisionGenerationMethod.Fast : set = set_collision_generation_method
-
-## Controls when to update collisions.
-@export var collision_update_mode := CollisionUpdateMode.Editor : set = set_collision_update_mode
-
-## Controls size of generated polygon for CollisionPolygon2D.
-@export_range(0.0, 64.0, 1.0, "or_greater")
-var collision_size: float = 32 : set = set_collision_size
-
-## Controls offset of generated polygon for CollisionPolygon2D.
-@export_range(-64.0, 64.0, 1.0, "or_greater", "or_lesser")
-var collision_offset: float = 0.0 : set = set_collision_offset
-
-## NodePath to CollisionPolygon2D node for which polygon data will be generated.
-@export_node_path("CollisionPolygon2D") var collision_polygon_node_path: NodePath : set = set_collision_polygon_node_path
-
-#####################
-#-SETTERS / GETTERS-#
-#####################
-
-func set_collision_polygon_node_path(value: NodePath) -> void:
- collision_polygon_node_path = value
- set_as_dirty()
-
- if not is_inside_tree():
- return
-
- if collision_polygon_node_path.is_empty():
- _collision_polygon_node = null
- return
-
- _collision_polygon_node = get_node(collision_polygon_node_path) as CollisionPolygon2D
-
- if not _collision_polygon_node:
- push_error("collision_polygon_node_path should point to proper CollisionPolygon2D node.")
-
-
-func get_collision_polygon_node() -> CollisionPolygon2D:
- return _collision_polygon_node
-
-
-func get_point_array() -> SS2D_Point_Array:
- return _points
-
-
-func set_point_array(a: SS2D_Point_Array) -> void:
- if _points != null:
- if _points.is_connected("update_finished", self._points_modified):
- _points.disconnect("update_finished", self._points_modified)
- if _points.material_override_changed.is_connected(_handle_material_override_change):
- _points.material_override_changed.disconnect(_handle_material_override_change)
- if a == null:
- a = SS2D_Point_Array.new()
- _points = a
- _points.connect("update_finished", self._points_modified)
- _points.material_override_changed.connect(_handle_material_override_change)
- clear_cached_data()
- set_as_dirty()
- notify_property_list_changed()
-
-
-func _refresh_action(value: String) -> void:
- if value.length() > 0:
- _points_modified()
-
-
-func _make_unique_action(value: String) -> void:
- if value.length() > 0:
- emit_signal("make_unique_pressed", self)
-
-
-func set_flip_edges(b: bool) -> void:
- flip_edges = b
- set_as_dirty()
- notify_property_list_changed()
-
-
-func set_render_edges(b: bool) -> void:
- render_edges = b
- set_as_dirty()
- notify_property_list_changed()
-
-
-func set_collision_generation_method(value: CollisionGenerationMethod) -> void:
- collision_generation_method = value
- set_as_dirty()
-
-
-func set_collision_update_mode(value: CollisionUpdateMode) -> void:
- collision_update_mode = value
- set_as_dirty()
-
-
-func set_collision_size(s: float) -> void:
- collision_size = s
- set_as_dirty()
- notify_property_list_changed()
-
-
-func set_collision_offset(s: float) -> void:
- collision_offset = s
- set_as_dirty()
- notify_property_list_changed()
-
-
-# FIXME: Only used by unit test.
-func set_curve(curve: Curve2D) -> void:
- _points.begin_update()
- _points.clear()
-
- for i in curve.get_point_count():
- _points.add_point(curve.get_point_position(i))
-
- _points.end_update()
-
-
-## Deprecated. Use get_point_array().get_curve() instead.
-## @deprecated
-func get_curve() -> Curve2D:
- return _points.get_curve()
-
-
-func _set_editor_debug(value: bool) -> void:
- editor_debug = value
- set_as_dirty()
- notify_property_list_changed()
-
-
-func set_render_node_light_masks(value: int) -> void:
- # TODO: This method should be called when user changes mask in the inspector.
- var render_parent: SS2D_Shape_Render = _get_rendering_nodes_parent()
- for c: CanvasItem in render_parent.get_children():
- c.light_mask = value
- render_parent.light_mask = value
-
-
-func set_render_node_owners(v: bool) -> void:
- if Engine.is_editor_hint():
- # Force scene tree update
- var render_parent: SS2D_Shape_Render = _get_rendering_nodes_parent()
- var new_owner: Node = null
- if v:
- new_owner = get_tree().edited_scene_root
- render_parent.set_owner(new_owner)
-
- # Set owner recurisvely
- for c in render_parent.get_children():
- c.set_owner(new_owner)
-
- # Force update
- var dummy_name := "__DUMMY__"
- if has_node(dummy_name):
- var n: Node = get_node(dummy_name)
- remove_child(n)
- n.queue_free()
-
- var dummy := Node2D.new()
- dummy.name = dummy_name
- add_child(dummy)
- dummy.set_owner(new_owner)
-
-
-func update_render_nodes() -> void:
-# set_render_node_owners(editor_debug)
- set_render_node_light_masks(light_mask)
-
-
-## Deprecated. Use get_point_array().tessellation_stages instead.
-## @deprecated
-func set_tessellation_stages(value: int) -> void:
- _points.tessellation_stages = value
-
-
-## Deprecated. Use get_point_array().tessellation_tolerance instead.
-## @deprecated
-func set_tessellation_tolerence(value: float) -> void:
- _points.tessellation_tolerance = value
-
-
-## Deprecated. Use get_point_array().curve_bake_interval instead.
-## @deprecated
-func set_curve_bake_interval(f: float) -> void:
- _points.curve_bake_interval = f
-
-
-func set_color_encoding(i: SS2D_Edge.COLOR_ENCODING) -> void:
- color_encoding = i
- notify_property_list_changed()
- set_as_dirty()
-
-
-func _set_material(value: SS2D_Material_Shape) -> void:
- if (
- shape_material != null
- and shape_material.is_connected("changed", self._handle_material_change)
- ):
- shape_material.disconnect("changed", self._handle_material_change)
-
- shape_material = value
- if shape_material != null:
- shape_material.connect("changed", self._handle_material_change)
- set_as_dirty()
- notify_property_list_changed()
-
-
-func set_material_overrides(dict: Dictionary) -> void:
- material_overrides = {}
- if dict == null:
- return
- _points.set_material_overrides(dict)
-
-
-#########
-#-CURVE-#
-#########
-
-## Deprecated. Use get_point_array().get_vertices() instead.
-## @deprecated
-func get_vertices() -> PackedVector2Array:
- return _points.get_vertices()
-
-
-## Deprecated. Use get_point_array().get_tessellated_points() instead.
-## @deprecated
-func get_tessellated_points() -> PackedVector2Array:
- return _points.get_tessellated_points()
-
-
-## Deprecated. Use get_point_array().invert_point_order() instead.
-## @deprecated
-func invert_point_order() -> void:
- _points.invert_point_order()
-
-
-## Deprecated. Use get_point_array().clear() instead.
-## @deprecated
-func clear_points() -> void:
- _points.clear()
-
-
-func adjust_add_point_index(index: int) -> int:
- # Don't allow a point to be added after the last point of the closed shape or before the first
- if _has_closing_point():
- if index < 0 or (index > get_point_count() - 1):
- index = maxi(get_point_count() - 1, 0)
- if index < 1:
- index = 1
- return index
-
-
-# FIXME: Only unit tests use this.
-func add_points(verts: PackedVector2Array, starting_index: int = -1, key: int = -1) -> PackedInt32Array:
- starting_index = adjust_add_point_index(starting_index)
- var keys := PackedInt32Array()
- _points.begin_update()
- for i in range(0, verts.size(), 1):
- var v: Vector2 = verts[i]
- if starting_index != -1:
- keys.push_back(_points.add_point(v, starting_index + i, key))
- else:
- keys.push_back(_points.add_point(v, starting_index, key))
- _points.end_update()
- return keys
-
-
-## Deprecated. Use get_point_array().add_point() instead.
-## @deprecated
-func add_point(pos: Vector2, index: int = -1, key: int = -1) -> int:
- return _points.add_point(pos, adjust_add_point_index(index), key)
-
-
-## Is this shape closed, i.e. last point is constrained to the first point.
-func is_shape_closed() -> bool:
- if _points.get_point_count() < 4:
- return false
- return _has_closing_point()
-
-
-## Is this shape not yet closed but should be.[br]
-## Returns [code]false[/code] for open shapes.[br]
-func can_close() -> bool:
- return _points.get_point_count() > 2 and _has_closing_point() == false
-
-
-## Will mutate the _points to ensure this is a closed_shape.[br]
-## Last point will be constrained to first point.[br]
-## Returns key of a point used to close the shape.[br]
-## [param key] suggests which key to use instead of auto-generated.[br]
-func close_shape(key: int = -1) -> int:
- if not can_close():
- return -1
-
- var key_first: int = _points.get_point_key_at_index(0)
- var key_last: int = _points.get_point_key_at_index(_points.get_point_count() - 1)
-
- if get_point_position(key_first) != get_point_position(key_last):
- key_last = _points.add_point(_points.get_point_position(key_first), -1, key)
- _points.set_constraint(key_first, key_last, SS2D_Point_Array.CONSTRAINT.ALL)
-
- return key_last
-
-
-## Open shape by removing edge that starts at specified point index.
-func open_shape_at_edge(edge_start_idx: int) -> void:
- var last_idx: int = get_point_count() - 1
- if is_shape_closed():
- remove_point(get_point_key_at_index(last_idx))
- if edge_start_idx < last_idx:
- for i in range(edge_start_idx + 1):
- _points.set_point_index(_points.get_point_key_at_index(0), last_idx)
- else:
- push_warning("Can't open a shape that is not a closed shape.")
-
-
-## Undo shape opening done by [method open_shape_at_edge].
-func undo_open_shape_at_edge(edge_start_idx: int, closing_index: int) -> void:
- var last_idx := get_point_count() - 1
- if edge_start_idx < last_idx:
- for i in range(edge_start_idx + 1):
- _points.set_point_index(_points.get_point_key_at_index(last_idx), 0)
- if can_close():
- close_shape(closing_index)
-
-
-func _has_closing_point() -> bool:
- if _points.get_point_count() < 2:
- return false
- var key1: int = _points.get_point_key_at_index(0)
- var key2: int = _points.get_point_key_at_index(_points.get_point_count() - 1)
- return _points.get_point_constraint(key1, key2) == SS2D_Point_Array.CONSTRAINT.ALL
-
-
-## Deprecated. Use get_point_array().begin_update() instead.
-## @deprecated
-func begin_update() -> void:
- _points.begin_update()
-
-
-## Deprecated. Use get_point_array().end_update() instead.
-## @deprecated
-func end_update() -> void:
- _points.end_update()
-
-
-## Deprecated. Use get_point_array().is_updating() instead.
-## @deprecated
-func is_updating() -> bool:
- return _points.is_updating()
-
-
-## Deprecated. Use get_point_array().get_next_key() instead.
-## @deprecated
-func get_next_key() -> int:
- return _points.get_next_key()
-
-
-## Deprecated. Use get_point_array().reserve_key() instead.
-## @deprecated
-func reserve_key() -> int:
- return _points.reserve_key()
-
-
-func _points_modified() -> void:
- set_as_dirty()
- points_modified.emit()
-
-
-func _is_array_index_in_range(a: Array, i: int) -> bool:
- return a.size() > i and i >= 0;
-
-
-## Deprecated. Use respective function in get_point_array() instead.
-## @deprecated
-func is_index_in_range(idx: int) -> bool:
- return _points.is_index_in_range(idx)
-
-
-## Deprecated. Use respective function in get_point_array() instead.
-## @deprecated
-func set_point_position(key: int, pos: Vector2) -> void:
- _points.set_point_position(key, pos)
-
-
-## Deprecated. Use respective function in get_point_array() instead.
-## @deprecated
-func remove_point(key: int) -> void:
- _points.remove_point(key)
-
-
-## Deprecated. Use respective function in get_point_array() instead.
-## @deprecated
-func remove_point_at_index(idx: int) -> void:
- _points.remove_point_at_index(idx)
-
-
-func clone(clone_point_array: bool = true) -> SS2D_Shape:
- var copy := SS2D_Shape.new()
- copy.transform = transform
- copy.modulate = modulate
- copy.shape_material = shape_material
- copy.editor_debug = editor_debug
- copy.flip_edges = flip_edges
- copy.editor_debug = editor_debug
- copy.collision_size = collision_size
- copy.collision_offset = collision_offset
- #copy.material_overrides = s.material_overrides
- copy.name = get_name().rstrip("0123456789")
- if clone_point_array:
- copy.set_point_array(_points.clone(true))
- return copy
-
-
-#######################
-#-POINT ARRAY WRAPPER-#
-#######################
-
-## Deprecated. Use respective function in get_point_array() instead.
-## @deprecated
-func has_point(key: int) -> bool:
- return _points.has_point(key)
-
-
-## Deprecated. Use respective function in get_point_array() instead.
-## @deprecated
-func get_all_point_keys() -> PackedInt32Array:
- return _points.get_all_point_keys()
-
-
-## Deprecated. Use respective function in get_point_array() instead.
-## @deprecated
-func get_point_key_at_index(idx: int) -> int:
- return _points.get_point_key_at_index(idx)
-
-
-## Deprecated. Use respective function in get_point_array() instead.
-## @deprecated
-func get_point_at_index(idx: int) -> SS2D_Point:
- return _points.get_point_at_index(idx)
-
-
-## Deprecated. Use respective function in get_point_array() instead.
-## @deprecated
-func get_point_index(key: int) -> int:
- return _points.get_point_index(key)
-
-
-## Deprecated. Use respective function in get_point_array() instead.
-## @deprecated
-func set_point_in(key: int, v: Vector2) -> void:
- _points.set_point_in(key, v)
-
-
-## Deprecated. Use respective function in get_point_array() instead.
-## @deprecated
-func set_point_out(key: int, v: Vector2) -> void:
- _points.set_point_out(key, v)
-
-
-## Deprecated. Use respective function in get_point_array() instead.
-## @deprecated
-func get_point_in(key: int) -> Vector2:
- return _points.get_point_in(key)
-
-
-## Deprecated. Use respective function in get_point_array() instead.
-## @deprecated
-func get_point_out(key: int) -> Vector2:
- return _points.get_point_out(key)
-
-
-func get_closest_point(to_point: Vector2) -> Vector2:
- return _points.get_curve().get_closest_point(to_point)
-
-
-func get_closest_point_straight_edge(to_point: Vector2) -> Vector2:
- return _points.get_curve_no_control_points().get_closest_point(to_point)
-
-
-func get_closest_offset_straight_edge(to_point: Vector2) -> float:
- return _points.get_curve_no_control_points().get_closest_offset(to_point)
-
-
-func get_closest_offset(to_point: Vector2) -> float:
- return _points.get_curve().get_closest_offset(to_point)
-
-
-## Deprecated. Use respective function in get_point_array() instead.
-## @deprecated
-func disable_constraints() -> void:
- _points.disable_constraints()
-
-
-## Deprecated. Use respective function in get_point_array() instead.
-## @deprecated
-func enable_constraints() -> void:
- _points.enable_constraints()
-
-
-## Deprecated. Use respective function in get_point_array() instead.
-## @deprecated
-func get_point_count() -> int:
- return _points.get_point_count()
-
-
-func get_edges() -> Array[SS2D_Edge]:
- return _edges
-
-
-## Deprecated. Use respective function in get_point_array() instead.
-## @deprecated
-func get_point_position(key: int) -> Vector2:
- return _points.get_point_position(key)
-
-
-## Deprecated. Use respective function in get_point_array() instead.
-## @deprecated
-func get_point(key: int) -> SS2D_Point:
- return _points.get_point(key)
-
-
-## Deprecated. Use respective function in get_point_array() instead.
-## @deprecated
-func get_point_constraints(key: int) -> Dictionary:
- return _points.get_point_constraints(key)
-
-
-## Deprecated. Use respective function in get_point_array() instead.
-## @deprecated
-func get_point_constraint(key1: int, key2: int) -> SS2D_Point_Array.CONSTRAINT:
- return _points.get_point_constraint(key1, key2)
-
-
-## Deprecated. Use respective function in get_point_array() instead.
-## @deprecated
-func set_constraint(key1: int, key2: int, c: SS2D_Point_Array.CONSTRAINT) -> void:
- _points.set_constraint(key1, key2, c)
-
-
-## Deprecated. Use respective function in get_point_array() instead.
-## @deprecated
-func set_point(key: int, value: SS2D_Point) -> void:
- _points.set_point(key, value)
-
-
-## Deprecated. Use respective property in get_point_array().get_point_properties() instead.
-## @deprecated
-func set_point_width(key: int, w: float) -> void:
- _points.get_point_properties(key).width = w
-
-
-## Deprecated. Use respective property in get_point_array().get_point_properties() instead.
-## @deprecated
-func get_point_width(key: int) -> float:
- return _points.get_point_properties(key).width
-
-
-## Deprecated. Use respective property in get_point_array().get_point_properties() instead.
-## @deprecated
-func set_point_texture_index(key: int, tex_idx: int) -> void:
- _points.get_point_properties(key).texture_idx = tex_idx
-
-
-## Deprecated. Use respective property in get_point_array().get_point_properties() instead.
-## @deprecated
-func get_point_texture_index(key: int) -> int:
- return _points.get_point_properties(key).texture_idx
-
-
-## Deprecated. Use respective property in get_point_array().get_point_properties() instead.
-## @deprecated
-func set_point_texture_flip(key: int, flip: bool) -> void:
- _points.get_point_properties(key).flip = flip
-
-
-## Deprecated. Use respective property in get_point_array().get_point_properties() instead.
-## @deprecated
-func get_point_texture_flip(key: int) -> bool:
- return _points.get_point_properties(key).flip
-
-
-## Deprecated. Use respective function in get_point_array() instead.
-## @deprecated
-func get_point_properties(key: int) -> SS2D_VertexProperties:
- return _points.get_point_properties(key)
-
-
-## Deprecated. Use respective function in get_point_array() instead.
-## @deprecated
-func set_point_properties(key: int, properties: SS2D_VertexProperties) -> void:
- _points.set_point_properties(key, properties)
-
-
-#########
-#-GODOT-#
-#########
-
-func _init() -> void:
- set_point_array(SS2D_Point_Array.new())
-
-
-func _enter_tree() -> void:
- # Call this again because get_node() only works when the node is inside the tree
- set_collision_polygon_node_path(collision_polygon_node_path)
-
- # Handle material changes if scene is (re-)entered (e.g. after switching to another)
- if shape_material != null:
- if not shape_material.is_connected("changed", self._handle_material_change):
- shape_material.connect("changed", self._handle_material_change)
-
-
-func _get_rendering_nodes_parent() -> SS2D_Shape_Render:
- var render_parent_name := "_SS2D_RENDER"
- var render_parent: SS2D_Shape_Render = null
- if not has_node(render_parent_name):
- render_parent = SS2D_Shape_Render.new()
- render_parent.name = render_parent_name
- render_parent.light_mask = light_mask
- add_child(render_parent)
- if editor_debug and Engine.is_editor_hint():
- render_parent.set_owner(get_tree().edited_scene_root)
- else:
- render_parent = get_node(render_parent_name)
- return render_parent
-
-
-# Returns true if the children have changed.
-func _create_rendering_nodes(size: int) -> bool:
- var render_parent: SS2D_Shape_Render = _get_rendering_nodes_parent()
- var child_count := render_parent.get_child_count()
- var delta := size - child_count
- #print ("%s | %s | %s" % [child_count, size, delta])
- # Size and child_count match
- if delta == 0:
- return false
-
- # More children than needed
- elif delta < 0:
- var children := render_parent.get_children()
- for i in range(0, abs(delta), 1):
- var child: SS2D_Shape_Render = children[child_count - 1 - i]
- render_parent.remove_child(child)
- child.set_mesh(null)
- child.queue_free()
-
- # Fewer children than needed
- elif delta > 0:
- for i in range(0, delta, 1):
- var child := SS2D_Shape_Render.new()
- child.light_mask = light_mask
- render_parent.add_child(child)
- if editor_debug and Engine.is_editor_hint():
- child.set_owner(get_tree().edited_scene_root)
- return true
-
-
-# Takes an array of SS2D_Meshes and returns a flat array of SS2D_Meshes.
-# If a SS2D_Mesh has n meshes, will return an array contain n SS2D_Mesh.
-# The returned array will consist of SS2D_Meshes each with a SS2D_Mesh::meshes array of size 1.
-func _draw_flatten_meshes_array(meshes: Array[SS2D_Mesh]) -> Array[SS2D_Mesh]:
- var flat_meshes: Array[SS2D_Mesh] = []
- for ss2d_mesh in meshes:
- for godot_mesh in ss2d_mesh.meshes:
- var new_mesh: SS2D_Mesh = ss2d_mesh.duplicate(false)
- var arr: Array[ArrayMesh] = [godot_mesh]
- new_mesh.meshes = arr
- flat_meshes.push_back(new_mesh)
- return flat_meshes
-
-
-func _draw() -> void:
- var flat_meshes: Array[SS2D_Mesh] = _draw_flatten_meshes_array(_meshes)
- _create_rendering_nodes(flat_meshes.size())
- var render_parent: SS2D_Shape_Render = _get_rendering_nodes_parent()
- var render_nodes := render_parent.get_children()
- #print ("RENDER | %s" % [render_nodes])
- #print ("MESHES | %s" % [flat_meshes])
- for i in range(0, flat_meshes.size(), 1):
- var m: SS2D_Mesh = flat_meshes[i]
- var render_node: SS2D_Shape_Render = render_nodes[i]
- render_node.set_mesh(m)
-
- if editor_debug and Engine.is_editor_hint():
- _draw_debug(SS2D_Shape.sort_by_z_index(_edges))
-
-
-func _draw_debug(edges: Array[SS2D_Edge]) -> void:
- for e in edges:
- for q in e.quads:
- q.render_lines(self)
-
- var _range := range(0, e.quads.size(), 1)
- for i: int in _range:
- var q := e.quads[i]
- if not (i % 3 == 0):
- continue
- q.render_points(3, 0.5, self)
-
- for i: int in _range:
- var q := e.quads[i]
- if not ((i + 1) % 3 == 0):
- continue
- q.render_points(2, 0.75, self)
-
- for i: int in _range:
- var q := e.quads[i]
- if not ((i + 2) % 3 == 0):
- continue
- q.render_points(1, 1.0, self)
-
-
-func _exit_tree() -> void:
- if shape_material != null:
- if shape_material.is_connected("changed", self._handle_material_change):
- shape_material.disconnect("changed", self._handle_material_change)
-
-
-############
-#-GEOMETRY-#
-############
-
-
-func should_flip_edges() -> bool:
- if is_shape_closed():
- return (are_points_clockwise() == flip_edges)
- else:
- return flip_edges
-
-
-func _generate_collision_points_precise() -> PackedVector2Array:
- var points := PackedVector2Array()
- var num_points: int = _points.get_point_count()
- if num_points < 2:
- return points
-
- var csize: float = 1.0 if is_shape_closed() else collision_size
- var indices := PackedInt32Array(range(num_points))
- var edge_data := SS2D_IndexMap.new(indices, null)
- var edge: SS2D_Edge = _build_edge_with_material(edge_data, collision_offset - 1.0, csize)
- _weld_quad_array(edge.quads, false)
-
- if is_shape_closed():
- var first_quad: SS2D_Quad = edge.quads[0]
- var last_quad: SS2D_Quad = edge.quads.back()
- SS2D_Shape.weld_quads(last_quad, first_quad)
-
- if not edge.quads.is_empty():
- # Top edge (typically point A unless corner quad)
- for quad in edge.quads:
- if quad.corner == SS2D_Quad.CORNER.NONE:
- points.push_back(quad.pt_a)
- elif quad.corner == SS2D_Quad.CORNER.OUTER:
- points.push_back(quad.pt_d)
- elif quad.corner == SS2D_Quad.CORNER.INNER:
- pass
-
- if not is_shape_closed():
- # Right Edge (point d, the first or final quad will never be a corner)
- points.push_back(edge.quads[edge.quads.size() - 1].pt_d)
-
- # Bottom Edge (typically point c)
- for quad_index in edge.quads.size():
- var quad: SS2D_Quad = edge.quads[edge.quads.size() - 1 - quad_index]
- if quad.corner == SS2D_Quad.CORNER.NONE:
- points.push_back(quad.pt_c)
- elif quad.corner == SS2D_Quad.CORNER.OUTER:
- pass
- elif quad.corner == SS2D_Quad.CORNER.INNER:
- points.push_back(quad.pt_b)
-
- # Left Edge (point b)
- points.push_back(edge.quads[0].pt_b)
- return points
-
-
-func _generate_collision_points_fast() -> PackedVector2Array:
- return _points.get_tessellated_points()
-
-
-func bake_collision() -> void:
- if not _collision_polygon_node:
- return
-
- if collision_update_mode == CollisionUpdateMode.Editor and not Engine.is_editor_hint() \
- or collision_update_mode == CollisionUpdateMode.Runtime and Engine.is_editor_hint():
- return
-
- var generated_points: PackedVector2Array
-
- if collision_generation_method == CollisionGenerationMethod.Fast and is_shape_closed():
- generated_points = _generate_collision_points_fast()
- else:
- generated_points = _generate_collision_points_precise()
-
- var xform := _collision_polygon_node.get_global_transform().affine_inverse() * get_global_transform()
- _collision_polygon_node.polygon = xform * generated_points
-
-
-func cache_edges() -> void:
- if shape_material != null and render_edges:
- _edges = _build_edges(shape_material, _points.get_vertices())
- else:
- _edges = []
-
-
-func cache_meshes() -> void:
- if shape_material != null:
- _meshes = _build_meshes(SS2D_Shape.sort_by_z_index(_edges))
-
-
-func _build_meshes(edges: Array[SS2D_Edge]) -> Array[SS2D_Mesh]:
- var meshes: Array[SS2D_Mesh] = []
- if _points == null or _points.get_point_count() < 2:
- return meshes
-
- var produced_fill_mesh := false
- for e in edges:
- if not produced_fill_mesh and is_shape_closed():
- if e.z_index > shape_material.fill_texture_z_index:
- # Produce Fill Meshes
- for m in _build_fill_mesh(_points.get_tessellated_points(), shape_material):
- meshes.push_back(m)
- produced_fill_mesh = true
-
- # Produce edge Meshes
- for m in e.get_meshes(color_encoding):
- meshes.push_back(m)
- if not produced_fill_mesh and is_shape_closed():
- for m in _build_fill_mesh(_points.get_tessellated_points(), shape_material):
- meshes.push_back(m)
- produced_fill_mesh = true
- return meshes
-
-
-func _build_fill_mesh(points: PackedVector2Array, s_mat: SS2D_Material_Shape) -> Array[SS2D_Mesh]:
- var meshes: Array[SS2D_Mesh] = []
- if s_mat == null:
- return meshes
- if s_mat.fill_textures.is_empty():
- return meshes
- if points.size() < 3:
- return meshes
-
- var tex: Texture2D = null
- if s_mat.fill_textures.is_empty():
- return meshes
- tex = s_mat.fill_textures[0]
- var tex_size: Vector2 = tex.get_size()
-
- # Points to produce the fill mesh
- var fill_points: PackedVector2Array = PackedVector2Array()
- var polygons: Array[PackedVector2Array] = Geometry2D.offset_polygon(
- PackedVector2Array(points), tex_size.x * s_mat.fill_mesh_offset
- )
- points = polygons[0]
- fill_points.resize(points.size())
- for i in range(points.size()):
- fill_points[i] = points[i]
-
- # Produce the fill mesh
- var fill_tris: PackedInt32Array = Geometry2D.triangulate_polygon(fill_points)
- if fill_tris.is_empty():
- push_error("'%s': Couldn't Triangulate shape" % name)
- return []
-
- var st: SurfaceTool
- st = SurfaceTool.new()
- st.begin(Mesh.PRIMITIVE_TRIANGLES)
-
- var uv_points := _get_uv_points(points, s_mat, tex_size)
-
- for i in range(0, fill_tris.size() - 1, 3):
- st.set_color(Color.WHITE)
- _add_uv_to_surface_tool(st, uv_points[fill_tris[i]])
- st.add_vertex(Vector3(points[fill_tris[i]].x, points[fill_tris[i]].y, 0))
- st.set_color(Color.WHITE)
- _add_uv_to_surface_tool(st, uv_points[fill_tris[i + 1]])
- st.add_vertex(Vector3(points[fill_tris[i + 1]].x, points[fill_tris[i + 1]].y, 0))
- st.set_color(Color.WHITE)
- _add_uv_to_surface_tool(st, uv_points[fill_tris[i + 2]])
- st.add_vertex(Vector3(points[fill_tris[i + 2]].x, points[fill_tris[i + 2]].y, 0))
- st.index()
- st.generate_normals()
- st.generate_tangents()
- var array_mesh := st.commit()
- var flip := false
- var trans := Transform2D()
- var mesh_data := SS2D_Mesh.new(tex, flip, trans, [array_mesh])
- mesh_data.material = s_mat.fill_mesh_material
- mesh_data.z_index = s_mat.fill_texture_z_index
- mesh_data.z_as_relative = true
- mesh_data.show_behind_parent = s_mat.fill_texture_show_behind_parent
- meshes.push_back(mesh_data)
-
- return meshes
-
-
-func _get_uv_points(
- points: PackedVector2Array,
- s_material: SS2D_Material_Shape,
- tex_size: Vector2
-) -> PackedVector2Array:
- var transformation: Transform2D = global_transform
-
- # If relative position ... undo translation from global_transform
- if not s_material.fill_texture_absolute_position:
- transformation = transformation.translated(-global_position)
-
- # Scale
- var tex_scale := 1.0 / s_material.fill_texture_scale
- transformation = transformation.scaled(Vector2(tex_scale, tex_scale))
-
- # If relative rotation ... undo rotation from global_transform
- if not s_material.fill_texture_absolute_rotation:
- transformation = transformation.rotated(-global_rotation)
-
- # Rotate the desired extra amount
- transformation = transformation.rotated(-deg_to_rad(s_material.fill_texture_angle_offset))
-
- # Shift the desired amount (adjusted so it's scale independent)
- transformation = transformation.translated(-s_material.fill_texture_offset / s_material.fill_texture_scale)
-
- # Convert local space to UV
- transformation = transformation.scaled(Vector2(1 / tex_size.x, 1 / tex_size.y))
-
- return transformation * points
-
-
-## Given three colinear points p, q, r, the function checks if point q lies on line segment 'pr'.[br]
-## See: https://www.geeksforgeeks.org/check-if-two-given-line-segments-intersect/
-static func on_segment(p: Vector2, q: Vector2, r: Vector2) -> bool:
- return (
- q.x <= maxf(p.x, r.x)
- and q.x >= minf(p.x, r.x)
- and q.y <= maxf(p.y, r.y)
- and q.y >= minf(p.y, r.y)
- )
-
-
-static func get_points_orientation(points: PackedVector2Array) -> ORIENTATION:
- var point_count: int = points.size()
- if point_count < 3:
- return ORIENTATION.COLINEAR
-
- var sum := 0.0
- for i in point_count:
- var pt := points[i]
- var pt2 := points[(i + 1) % point_count]
- sum += pt.cross(pt2)
-
- # Colinear
- if sum == 0.0:
- return ORIENTATION.COLINEAR
-
- # Clockwise
- if sum > 0.0:
- return ORIENTATION.CLOCKWISE
- return ORIENTATION.C_CLOCKWISE
-
-
-func are_points_clockwise() -> bool:
- var points: PackedVector2Array = _points.get_tessellated_points()
- var orient: ORIENTATION = SS2D_Shape.get_points_orientation(points)
- return orient == ORIENTATION.CLOCKWISE
-
-
-func _add_uv_to_surface_tool(surface_tool: SurfaceTool, uv: Vector2) -> void:
- surface_tool.set_uv(uv)
- surface_tool.set_uv2(uv)
-
-
-static func build_quad_from_two_points(
- pt: Vector2,
- pt_next: Vector2,
- tex: Texture2D,
- width: float,
- flip_x: bool,
- flip_y: bool,
- first_point: bool,
- last_point: bool,
- custom_offset: float,
- custom_extends: float,
- fit_texture: SS2D_Material_Edge.FITMODE
-) -> SS2D_Quad:
- # Create new quad
- var quad := SS2D_Quad.new()
- quad.texture = tex
- quad.color = Color(1.0, 1.0, 1.0, 1.0)
- quad.flip_texture = flip_x
- quad.fit_texture = fit_texture
-
- # Calculate the normal
- var delta: Vector2 = pt_next - pt
- var delta_normal := delta.normalized()
- var normal_direction := Vector2(delta.y, -delta.x).normalized()
- var normal_length: float = width
- var normal_with_magnitude: Vector2 = normal_direction * (normal_length * 0.5)
- if flip_y:
- normal_with_magnitude *= -1
- var offset: Vector2 = normal_with_magnitude * custom_offset
-
- # If is first or last point, extend past the normal boundary by 'custom_extends' pixels
- if first_point:
- pt -= (delta_normal * custom_extends)
- if last_point:
- pt_next += (delta_normal * custom_extends)
-
- ##############################################
- # QUAD POINT ILLUSTRATION # #
- ##############################################
- # LENGTH #
- # <--------------> #
- # pt_a -> O--------O <- pt_d â–² #
- # | | | #
- # | pt | | WIDTH #
- # | | | #
- # pt_b -> O--------O <- pt_c â–¼ #
- ##############################################
- ##############################################
-
- quad.pt_a = pt + normal_with_magnitude + offset
- quad.pt_b = pt - normal_with_magnitude + offset
- quad.pt_c = pt_next - normal_with_magnitude + offset
- quad.pt_d = pt_next + normal_with_magnitude + offset
-
- return quad
-
-
-## Builds a corner quad. [br]
-## - [param pt] is the center of this corner quad. [br]
-## - [param width] will scale the quad in line with the next point (one dimension). [br]
-## - [param prev_width] will scale the quad in line with the prev point (hte other dimension). [br]
-## - [param custom_scale] will scale the quad in both dimensions. [br]
-static func build_quad_corner(
- pt_next: Vector2,
- pt: Vector2,
- pt_prev: Vector2,
- pt_width: float,
- pt_prev_width: float,
- flip_edges_: bool,
- corner_status: int,
- texture: Texture2D,
- size: Vector2,
- custom_scale: float,
- custom_offset: float
-) -> SS2D_Quad:
- var new_quad := SS2D_Quad.new()
-
- # :BUILD PLAN:
- # OUTER CORNER INNER CORNER
- #
- # 0------A-----D 0-----0
- # | 1 : 2 | | 3 :
- # 0......B.....C | :
- # : | 0-------D-----A
- # : 3 | | 1 | 2 :
- # 0-----0 0.......C.....B
- #
- # 1-previous, 2-current, 3-next (points)
-
- var quad_size: Vector2 = size * 0.5
- var dir_12: Vector2 = (pt - pt_prev).normalized()
- var dir_23: Vector2 = (pt_next - pt).normalized()
- var offset_12: Vector2 = dir_12 * custom_scale * pt_width * quad_size
- var offset_23: Vector2 = dir_23 * custom_scale * pt_prev_width * quad_size
- var custom_offset_13: Vector2 = (dir_12 - dir_23) * custom_offset * quad_size
-
- if flip_edges_:
- offset_12 *= -1
- offset_23 *= -1
- custom_offset_13 *= -1
-
- # Should we mirror internal ABCD vertices relative to quad center.
- # - Historically, quad internal vertices are flipped for inner corner quads (see illustration).
- # - Value: 1.0 for outer, -1.0 for inner (mirrored).
- var mirror: float = -1.0 if corner_status == SS2D_Quad.CORNER.INNER else 1.0
-
- new_quad.pt_a = pt + (-offset_12 - offset_23 + custom_offset_13) * mirror
- new_quad.pt_b = pt + (-offset_12 + offset_23 + custom_offset_13) * mirror
- new_quad.pt_c = pt + (offset_12 + offset_23 + custom_offset_13) * mirror
- new_quad.pt_d = pt + (offset_12 - offset_23 + custom_offset_13) * mirror
-
- new_quad.corner = corner_status
- new_quad.texture = texture
-
- return new_quad
-
-
-func _get_width_for_tessellated_point(
- points: PackedVector2Array,
- t_idx: int
-) -> float:
- var v_idx := _points.get_tesselation_vertex_mapping().tess_to_vertex_index(t_idx)
- var v_idx_next := SS2D_PluginFunctionality.get_next_point_index(v_idx, points)
- var w1: float = _points.get_point_properties(_points.get_point_key_at_index(v_idx)).width
- var w2: float = _points.get_point_properties(_points.get_point_key_at_index(v_idx_next)).width
- var ratio: float = get_ratio_from_tessellated_point_to_vertex(t_idx)
- return lerp(w1, w2, ratio)
-
-
-## Mutates two quads to be welded.[br]
-## Returns the midpoint of the weld.[br]
-static func weld_quads(a: SS2D_Quad, b: SS2D_Quad, custom_scale: float = 1.0) -> Vector2:
- var midpoint := Vector2(0, 0)
- # If both quads are not a corner
- if a.corner == SS2D_Quad.CORNER.NONE and b.corner == SS2D_Quad.CORNER.NONE:
- var needed_height: float = (a.get_height_average() + b.get_height_average()) / 2.0
-
- var pt1: Vector2 = (a.pt_d + b.pt_a) * 0.5
- var pt2: Vector2 = (a.pt_c + b.pt_b) * 0.5
-
- midpoint = Vector2(pt1 + pt2) / 2.0
- var half_line: Vector2 = (pt2 - midpoint).normalized() * needed_height * custom_scale / 2.0
-
- if half_line != Vector2.ZERO:
- pt2 = midpoint + half_line
- pt1 = midpoint - half_line
-
- a.pt_d = pt1
- a.pt_c = pt2
- b.pt_a = pt1
- b.pt_b = pt2
-
- # If either quad is a corner
- else:
- if a.corner == SS2D_Quad.CORNER.OUTER:
- b.pt_a = a.pt_c
- b.pt_b = a.pt_b
- midpoint = (b.pt_a + b.pt_b) / 2.0
-
- elif a.corner == SS2D_Quad.CORNER.INNER:
- b.pt_a = a.pt_d
- b.pt_b = a.pt_a
- midpoint = (b.pt_a + b.pt_b) / 2.0
-
- elif b.corner == SS2D_Quad.CORNER.OUTER:
- a.pt_d = b.pt_a
- a.pt_c = b.pt_b
- midpoint = (a.pt_d + a.pt_c) / 2.0
-
- elif b.corner == SS2D_Quad.CORNER.INNER:
- a.pt_d = b.pt_d
- a.pt_c = b.pt_c
- midpoint = (a.pt_d + a.pt_c) / 2.0
-
- return midpoint
-
-
-func _weld_quad_array(
- quads: Array[SS2D_Quad], weld_first_and_last: bool, start_idx: int = 0
-) -> void:
- if quads.is_empty():
- return
-
- for index in range(start_idx, quads.size() - 1, 1):
- var this_quad: SS2D_Quad = quads[index]
- var next_quad: SS2D_Quad = quads[index + 1]
- if not this_quad.ignore_weld_next:
- SS2D_Shape.weld_quads(this_quad, next_quad)
- # If this quad self_intersects after welding, it's likely very small and can be removed
- # Usually happens when welding a very large and very small quad together
- # Generally looks better when simply being removed
- #
- # When welding and using different widths, quads can look a little weird
- # This is because they are no longer parallelograms
- # This is a tough problem to solve
- # See http://reedbeta.com/blog/quadrilateral-interpolation-part-1/
- if this_quad.self_intersects():
- quads.remove_at(index)
- if index < quads.size():
- var new_index: int = maxi(index - 1, 0)
- _weld_quad_array(quads, weld_first_and_last, new_index)
- return
-
- if weld_first_and_last:
- if not quads[-1].ignore_weld_next:
- SS2D_Shape.weld_quads(quads[-1], quads[0])
-
-
-func _merge_index_maps(imaps: Array[SS2D_IndexMap], verts: PackedVector2Array) -> Array[SS2D_IndexMap]:
- if not is_shape_closed():
- return imaps
- # See if any edges have both the first (0) and last idx (size)
- # Merge them into one if so
- var final_edges: Array[SS2D_IndexMap] = imaps.duplicate()
- var edges_by_material: Dictionary = SS2D_IndexMap.index_map_array_sort_by_object(final_edges)
- # Erase any with null material
- edges_by_material.erase(null)
- for mat: Variant in edges_by_material:
- var edge_first_idx: SS2D_IndexMap = null
- var edge_last_idx: SS2D_IndexMap = null
- for e: SS2D_IndexMap in edges_by_material[mat]:
- if e.indicies.has(0):
- edge_first_idx = e
- if e.indicies.has(verts.size()-1):
- edge_last_idx = e
- if edge_first_idx != null and edge_last_idx != null:
- break
- if edge_first_idx != null and edge_last_idx != null:
- if edge_first_idx == edge_last_idx:
- pass
- else:
- final_edges.erase(edge_last_idx)
- final_edges.erase(edge_first_idx)
- var indicies := edge_last_idx.indicies + edge_first_idx.indicies
- var merged_edge := SS2D_IndexMap.new(indicies, mat)
- final_edges.push_back(merged_edge)
- return final_edges
-
-
-func _build_edges(s_mat: SS2D_Material_Shape, verts: PackedVector2Array) -> Array[SS2D_Edge]:
- var edges: Array[SS2D_Edge] = []
- if s_mat == null:
- return edges
-
- var index_maps: Array[SS2D_IndexMap] = _get_meta_material_index_mapping(s_mat, verts)
- var overrides: Array[SS2D_IndexMap] = SS2D_Shape.get_meta_material_index_mapping_for_overrides(s_mat, _points)
-
- # Remove the override indicies from the default index_maps
- for override in overrides:
- var old_to_new_imaps := {}
- for index_map in index_maps:
- var new_imaps: Array[SS2D_IndexMap] = index_map.remove_edges(override.indicies)
- old_to_new_imaps[index_map] = new_imaps
- for k: SS2D_IndexMap in old_to_new_imaps:
- index_maps.erase(k)
- for new_imap: SS2D_IndexMap in old_to_new_imaps[k]:
- index_maps.push_back(new_imap)
-
- # Merge index maps
- index_maps = _merge_index_maps(index_maps, verts)
-
- # Add the overrides to the mappings to be rendered
- for override in overrides:
- index_maps.push_back(override)
-
- # Edge case for web so it doesn't use thread
- if OS.get_name() != "Web":
- var threads: Array[Thread] = []
- for index_map in index_maps:
- var thread := Thread.new()
- var args := [index_map, s_mat.render_offset, 0.0]
- var priority := 2
- thread.start(self._build_edge_with_material_thread_wrapper.bind(args), priority)
- threads.push_back(thread)
- for thread in threads:
- var new_edge: SS2D_Edge = thread.wait_to_finish()
- edges.push_back(new_edge)
-
- else:
- # Process index_maps sequentially for web exports (probably slower than thread)
- for index_map in index_maps:
- var args = [index_map, s_mat.render_offset, 0.0]
- var new_edge: SS2D_Edge = _build_edge_with_material_thread_wrapper(args)
- edges.push_back(new_edge)
-
- return edges
-
-
-## Will return an array of SS2D_IndexMaps.[br]
-## Each index map will map a set of indicies to a meta_material.[br]
-static func get_meta_material_index_mapping_for_overrides(
- _s_material: SS2D_Material_Shape, pa: SS2D_Point_Array
-) -> Array[SS2D_IndexMap]:
- var mappings: Array[SS2D_IndexMap] = []
- for key_tuple in pa.get_material_overrides():
- var indices := SS2D_IndexTuple.sort_ascending(Vector2i(pa.get_point_index(key_tuple.x), pa.get_point_index(key_tuple.y)))
- var m: SS2D_Material_Edge_Metadata = pa.get_material_override(key_tuple)
- var new_mapping := SS2D_IndexMap.new(PackedInt32Array([ indices.x, indices.y ]), m)
- mappings.push_back(new_mapping)
-
- return mappings
-
-
-## Will return a dictionary containing array of SS2D_IndexMap.[br]
-## Each element in the array is a contiguous sequence of indicies that fit inside
-## the meta_material's normalrange.[br]
-func _get_meta_material_index_mapping(
- s_material: SS2D_Material_Shape, verts: PackedVector2Array
-) -> Array[SS2D_IndexMap]:
- return SS2D_Shape.get_meta_material_index_mapping(s_material, verts, is_shape_closed())
-
-
-static func get_meta_material_index_mapping(
- s_material: SS2D_Material_Shape, verts: PackedVector2Array, wrap_around: bool
-) -> Array[SS2D_IndexMap]:
- var final_edges: Array[SS2D_IndexMap] = []
- var edge_building: Dictionary = {} # Dict[SS2D_Material_Edge_Metadata, SS2D_IndexMap]
- for idx in range(0, verts.size() - 1, 1):
- var idx_next: int = SS2D_PluginFunctionality.get_next_point_index(idx, verts, wrap_around)
- var pt: Vector2 = verts[idx]
- var pt_next: Vector2 = verts[idx_next]
- var delta: Vector2 = pt_next - pt
- var normal := Vector2(delta.y, -delta.x).normalized()
-
- # Get all valid edge_meta_materials for this normal value
- var edge_meta_materials := s_material.get_edge_meta_materials(normal)
-
- # Append to existing edges being built. Add new ones if needed
- for e in edge_meta_materials:
- var imap: SS2D_IndexMap = edge_building.get(e)
-
- # Is exsiting, append
- if imap:
- if not idx_next in imap.indicies:
- imap.indicies.push_back(idx_next)
- # Isn't existing, make a new mapping
- else:
- edge_building[e] = SS2D_IndexMap.new([idx, idx_next], e)
-
- # Closeout and stop building edges that are no longer viable
- for e: SS2D_Material_Edge_Metadata in edge_building.keys():
- if not edge_meta_materials.has(e):
- final_edges.push_back(edge_building[e])
- edge_building.erase(e)
-
- # Closeout all edge building
- for e: SS2D_Material_Edge_Metadata in edge_building.keys():
- final_edges.push_back(edge_building[e])
-
- return final_edges
-
-########
-#-MISC-#
-########
-func _handle_material_change() -> void:
- set_as_dirty()
-
-
-func _handle_material_override_change(_tuple: Vector2i) -> void:
- set_as_dirty()
-
-
-func set_as_dirty() -> void:
- if not _dirty:
- call_deferred("_on_dirty_update")
- _dirty = true
-
-
-static func sort_by_z_index(a: Array) -> Array:
- a.sort_custom(Callable(SS2D_Common_Functions, "sort_z"))
- return a
-
-
-static func sort_by_int_ascending(a: Array) -> Array:
- a.sort_custom(Callable(SS2D_Common_Functions, "sort_int_ascending"))
- return a
-
-
-func clear_cached_data() -> void:
- _edges = []
- _meshes = []
-
-
-func _on_dirty_update() -> void:
- if _dirty:
- force_update()
-
-
-func force_update() -> void:
- update_render_nodes()
- clear_cached_data()
-
- bake_collision()
- if get_point_count() >= 2:
- cache_edges()
- cache_meshes()
- queue_redraw()
- _dirty = false
-
-
-## Returns a float between 0.0 and 1.0.[br]
-## 0.0 means that this tessellated point is at the same position as the vertex.[br]
-## 0.5 means that this tessellated point is half-way between this vertex and the next.[br]
-## 0.999 means that this tessellated point is basically at the next vertex.[br]
-## 1.0 isn't going to happen; If a tess point is at the same position as a vert, it gets a ratio of 0.0.[br]
-func get_ratio_from_tessellated_point_to_vertex(t_point_idx: int) -> float:
- # Index of the starting vertex
- var point_idx := _points.get_tesselation_vertex_mapping().tess_to_vertex_index(t_point_idx)
- # Index of the first tesselated point with the same vertex
- var tess_point_first_idx: int = _points.get_tesselation_vertex_mapping().vertex_to_tess_indices(point_idx)[0]
- # The total tessellated points with the same vertex
- var tess_point_count := _points.get_tesselation_vertex_mapping().vertex_to_tess_indices(point_idx).size()
- # The index of the passed t_point_idx relative to the starting vert
- var tess_index_count := t_point_idx - tess_point_first_idx
- return tess_index_count / float(tess_point_count)
-
-
-func debug_print_points() -> void:
- _points.debug_print()
-
-
-###################
-#-EDGE GENERATION-#
-###################
-
-## Get Number of TessPoints from the start and end indicies of the index_map parameter.
-func _edge_data_get_tess_point_count(index_map: SS2D_IndexMap) -> int:
- ## TODO Test this function
- var count: int = 0
- for i in range(index_map.indicies.size() - 1):
- var this_idx := index_map.indicies[i]
- var next_idx := index_map.indicies[i + 1]
- if this_idx > next_idx:
- count += 1
- continue
- var this_t_idx: int = _points.get_tesselation_vertex_mapping().vertex_to_tess_indices(this_idx)[0]
- var next_t_idx: int = _points.get_tesselation_vertex_mapping().vertex_to_tess_indices(next_idx)[0]
- var delta: int = next_t_idx - this_t_idx
- count += delta
- return count
-
-
-## This function determines if a corner quad should be generated.[br]
-## if so, OUTER or INNER? [br]
-## - The conditions deg < 0 and flip_edges are used to determine this.[br]
-## - These conditions works correctly so long as the points are in Clockwise order.[br]
-static func edge_should_generate_corner(pt_prev: Vector2, pt: Vector2, pt_next: Vector2, flip_edges_: bool) -> SS2D_Quad.CORNER:
- var generate_corner := SS2D_Quad.CORNER.NONE
- var ab: Vector2 = pt - pt_prev
- var bc: Vector2 = pt_next - pt
- var dot_prod: float = ab.dot(bc)
- var determinant: float = (ab.x * bc.y) - (ab.y * bc.x)
- var angle := atan2(determinant, dot_prod)
- # This angle has a range of 360 degrees
- # Is between 180 and - 180
- var deg := rad_to_deg(angle)
- var corner_range := 10.0
- var corner_angle := 90.0
- if absf(deg) >= corner_angle - corner_range and absf(deg) <= corner_angle + corner_range:
- var inner := false
- if deg < 0:
- inner = true
- if flip_edges_:
- inner = not inner
- if inner:
- generate_corner = SS2D_Quad.CORNER.INNER
- else:
- generate_corner = SS2D_Quad.CORNER.OUTER
- return generate_corner
-
-
-func _edge_generate_corner(
- pt_prev: Vector2,
- pt: Vector2,
- pt_next: Vector2,
- width_prev: float,
- width: float,
- size: float,
- edge_material: SS2D_Material_Edge,
- texture_idx: int,
- c_scale: float,
- c_offset: float
-) -> SS2D_Quad:
- var generate_corner := SS2D_Shape.edge_should_generate_corner(pt_prev, pt, pt_next, flip_edges)
- if generate_corner == SS2D_Quad.CORNER.NONE:
- return null
- var corner_texture: Texture2D = null
- if edge_material != null:
- if generate_corner == SS2D_Quad.CORNER.OUTER:
- corner_texture = edge_material.get_texture_corner_outer(texture_idx)
- elif generate_corner == SS2D_Quad.CORNER.INNER:
- corner_texture = edge_material.get_texture_corner_inner(texture_idx)
- var corner_quad: SS2D_Quad = SS2D_Shape.build_quad_corner(
- pt_next,
- pt,
- pt_prev,
- width,
- width_prev,
- flip_edges,
- generate_corner,
- corner_texture,
- Vector2(size, size),
- c_scale,
- c_offset
- )
- return corner_quad
-
-
-func _imap_contains_all_points(imap: SS2D_IndexMap, verts: PackedVector2Array) -> bool:
- return imap.indicies[0] == 0 and imap.indicies[-1] == verts.size()-1
-
-
-func _is_edge_contiguous(imap: SS2D_IndexMap, verts: PackedVector2Array) -> bool:
- if not is_shape_closed():
- return false
- return _imap_contains_all_points(imap, verts)
-
-
-# Will construct an SS2D_Edge from the passed parameters.
-# index_map must be a SS2D_IndexMap with a SS2D_Material_Edge_Metadata for an object
-# the indicies used by index_map should match up with the get_verticies() indicies
-#
-# default_quad_width is the quad width used if a texture isn't available
-#
-# c_offset is the magnitude to offset all of the points
-# the direction of the offset is the surface_normal
-func _build_edge_with_material(
- index_map: SS2D_IndexMap, c_offset: float, default_quad_width: float
-) -> SS2D_Edge:
- var verts_t: PackedVector2Array = _points.get_tessellated_points()
- var verts: PackedVector2Array = _points.get_vertices()
- var edge := SS2D_Edge.new()
- var is_edge_contiguous: bool = _is_edge_contiguous(index_map, verts)
- edge.wrap_around = is_edge_contiguous
- if not index_map.is_valid():
- return edge
- var c_scale := 1.0
- var c_extends := 0.0
-
- var edge_material_meta: SS2D_Material_Edge_Metadata = null
- var edge_material: SS2D_Material_Edge = null
- if index_map.object != null:
- edge_material_meta = index_map.object
- if edge_material_meta == null:
- return edge
- if not edge_material_meta.render:
- return edge
- edge_material = edge_material_meta.edge_material
- if edge_material == null:
- return edge
- c_offset += edge_material_meta.offset
-
- edge.z_index = edge_material_meta.z_index
- edge.z_as_relative = edge_material_meta.z_as_relative
- edge.material = edge_material_meta.edge_material.material
-
- var first_idx: int = index_map.indicies[0]
- var last_idx: int = index_map.indicies[-1]
- var first_idx_t: int = _points.get_tesselation_vertex_mapping().vertex_to_tess_indices(first_idx)[0]
- var last_idx_t: int = _points.get_tesselation_vertex_mapping().vertex_to_tess_indices(last_idx)[-1]
- edge.first_point_key = _points.get_point_key_at_index(first_idx)
- edge.last_point_key = _points.get_point_key_at_index(last_idx)
-
- var should_flip := should_flip_edges()
-
- # How many tessellated points are contained within this index map?
- var tess_point_count: int = _edge_data_get_tess_point_count(index_map)
-
- var i := 0
- var texture_idx := 0
- var sharp_taper_next: SS2D_Quad = null
- var is_not_corner: bool = true
- var taper_sharp: bool = edge_material_meta != null and edge_material_meta.taper_sharp_corners
- while i < tess_point_count:
- var tess_idx: int = (first_idx_t + i) % verts_t.size()
- var tess_idx_next: int = SS2D_PluginFunctionality.get_next_unique_point_idx(tess_idx, verts_t, true)
- var tess_idx_prev: int = SS2D_PluginFunctionality.get_previous_unique_point_idx(tess_idx, verts_t, true)
-
- # set next_point_delta
- # next_point_delta is the number of tess_pts from
- # the current tess_pt to the next unique tess_pt
- # unique meaning it has a different position from the current tess_pt
- var next_point_delta := 0
- for j in range(verts_t.size()):
- if ((tess_idx + j) % verts_t.size()) == tess_idx_next:
- next_point_delta = j
- break
-
- var vert_idx: int = _points.get_tesselation_vertex_mapping().tess_to_vertex_index(tess_idx)
- var vert_key: int = get_point_key_at_index(vert_idx)
- var pt: Vector2 = verts_t[tess_idx]
- var pt_next: Vector2 = verts_t[tess_idx_next]
- var pt_prev: Vector2 = verts_t[tess_idx_prev]
- var flip_x: bool = get_point_texture_flip(vert_key)
-
- var width_scale: float = _get_width_for_tessellated_point(verts, tess_idx)
- var is_first_point: bool = (vert_idx == first_idx) and not is_edge_contiguous
- var is_last_point: bool = (vert_idx == last_idx - 1) and not is_edge_contiguous
- var is_first_tess_point: bool = (tess_idx == first_idx_t) and not is_edge_contiguous
- var is_last_tess_point: bool = (tess_idx == last_idx_t - 1) and not is_edge_contiguous
-
- var tex: Texture2D = null
- var tex_size := Vector2(default_quad_width, default_quad_width)
- var fitmode := SS2D_Material_Edge.FITMODE.SQUISH_AND_STRETCH
- if edge_material != null:
- if edge_material.randomize_texture:
- texture_idx = randi() % edge_material.textures.size()
- else :
- texture_idx = get_point_texture_index(vert_key)
- tex = edge_material.get_texture(texture_idx)
- tex_size = tex.get_size()
- fitmode = edge_material.fit_mode
- # Exit if we have an edge material defined but no texture to render
- if tex == null:
- i += next_point_delta
- continue
-
- var new_quad: SS2D_Quad = SS2D_Shape.build_quad_from_two_points(
- pt,
- pt_next,
- tex,
- width_scale * c_scale * tex_size.y,
- flip_x,
- should_flip,
- is_first_point,
- is_last_point,
- c_offset,
- c_extends,
- fitmode
- )
- var new_quads: Array[SS2D_Quad] = []
- new_quads.push_back(new_quad)
-
- # Corner Quad
- if edge_material != null and edge_material.use_corner_texture:
- if tess_idx != first_idx_t or is_edge_contiguous:
- var prev_width: float = _get_width_for_tessellated_point(verts, tess_idx_prev)
- var q: SS2D_Quad = _edge_generate_corner(
- pt_prev,
- pt,
- pt_next,
- prev_width,
- width_scale,
- tex_size.y,
- edge_material,
- texture_idx,
- c_scale,
- c_offset
- )
- if q != null:
- new_quads.push_front(q)
- is_not_corner = false
- else:
- is_not_corner = true
-
- # Taper Quad
- # Bear in mind, a point can be both first AND last
- # Consider an edge that consists of two points (one edge)
- # This first point is used to generate the quad; it is both first and last
- var did_taper_left: bool = false
- var did_taper_right: bool = false
- if is_first_tess_point and edge_material != null and edge_material.use_taper_texture:
- did_taper_left = true
- var taper_quad := _taper_quad(new_quad, edge_material, texture_idx, false, false)
- if taper_quad != null:
- new_quads.push_front(taper_quad)
- if is_last_tess_point and edge_material != null and edge_material.use_taper_texture:
- did_taper_right = true
- var taper_quad := _taper_quad(new_quad, edge_material, texture_idx, true, false)
- if taper_quad != null:
- new_quads.push_back(taper_quad)
-
- # Taper sharp corners
- if taper_sharp:
- var ang_threshold := PI * 0.5
- if sharp_taper_next != null and is_not_corner:
- var taper := _taper_quad(sharp_taper_next, edge_material, texture_idx, true, true)
- if taper != null:
- taper.ignore_weld_next = true
- edge.quads.push_back(taper)
- else:
- sharp_taper_next.ignore_weld_next = true
- sharp_taper_next = null
- var vert := verts[vert_idx]
- var prev_vert := verts[wrapi(vert_idx - 1, 0, verts.size() - 1)]
- var next_vert := verts[wrapi(vert_idx + 1, 0, verts.size() - 1)]
- if not did_taper_left and is_not_corner:
- var ang_from := prev_vert.angle_to_point(vert)
- var ang_to := vert.angle_to_point(next_vert)
- var ang_dif := angle_difference(ang_from, ang_to)
- if absf(ang_dif) > ang_threshold:
- var taper := _taper_quad(new_quad, edge_material, texture_idx, false, true)
- if taper != null:
- new_quads.push_front(taper)
- if not did_taper_right:
- var next_next_vert := verts[wrapi(vert_idx + 2, 0, verts.size() - 1)]
- var ang_from := vert.angle_to_point(next_vert)
- var ang_to := next_vert.angle_to_point(next_next_vert)
- var ang_dif := angle_difference(ang_from, ang_to)
- if absf(ang_dif) > ang_threshold:
- sharp_taper_next = new_quad
-
- # Final point for closed shapes fix
- # Corner quads aren't always correctly when the corner is between final and first pt
- if is_last_point and is_edge_contiguous:
- var idx_mid: int = verts_t.size() - 1
- var idx_next: int = SS2D_PluginFunctionality.get_next_unique_point_idx(idx_mid, verts_t, true)
- var idx_prev: int = SS2D_PluginFunctionality.get_previous_unique_point_idx(idx_mid, verts_t, true)
- var p_p: Vector2 = verts_t[idx_prev]
- var p_m: Vector2 = verts_t[idx_mid]
- var p_n: Vector2 = verts_t[idx_next]
- var w_p: float = _get_width_for_tessellated_point(verts, idx_prev)
- var w_m: float = _get_width_for_tessellated_point(verts, idx_mid)
- var q: SS2D_Quad = _edge_generate_corner(
- p_p, p_m, p_n, w_p, w_m, tex_size.y, edge_material, texture_idx, c_scale, c_offset
- )
- if q != null:
- new_quads.push_back(q)
-
- # Add new quads to edge
- for q in new_quads:
- edge.quads.push_back(q)
- i += next_point_delta
-
- # leftover final taper for the last sharp corner if required
- if taper_sharp:
- if sharp_taper_next != null and edge.quads[0].corner == SS2D_Quad.CORNER.NONE:
- var taper := _taper_quad(sharp_taper_next, edge_material, texture_idx, true, true)
- if taper != null:
- taper.ignore_weld_next = true
- edge.quads.push_back(taper)
- else:
- sharp_taper_next.ignore_weld_next = true
- sharp_taper_next = null
-
- if edge_material_meta != null:
- if edge_material_meta.weld:
- _weld_quad_array(edge.quads, edge.wrap_around)
-
- return edge
-
-
-# get the appropriate tapering texture based on direction and whether the current taper is a sharp
-# corner taper or normal material edge taper
-func get_taper_tex(edge_mat: SS2D_Material_Edge, tex_idx: int, facing_right: bool, corner_taper: bool) -> Texture2D:
- if facing_right:
- if corner_taper:
- return edge_mat.get_texture_taper_corner_right(tex_idx)
- else:
- return edge_mat.get_texture_taper_right(tex_idx)
- else:
- if corner_taper:
- return edge_mat.get_texture_taper_corner_left(tex_idx)
- else:
- return edge_mat.get_texture_taper_left(tex_idx)
-
-
-func _taper_quad(
- quad: SS2D_Quad,
- edge_mat: SS2D_Material_Edge,
- tex_idx: int,
- facing_right: bool,
- corner_taper: bool
-) -> SS2D_Quad:
- var taper_texture: Texture2D = get_taper_tex(edge_mat, tex_idx, facing_right, corner_taper)
- if taper_texture != null:
- var taper_size: Vector2 = taper_texture.get_size()
- var fit: bool = absf(taper_size.x) <= quad.get_length_average()
- if fit:
- var taper_quad := quad.duplicate()
- taper_quad.corner = SS2D_Quad.CORNER.NONE
- taper_quad.texture = taper_texture
- var delta_normal: Vector2 = (taper_quad.pt_d - taper_quad.pt_a).normalized()
- var offset: Vector2 = delta_normal * taper_size
- if facing_right:
- taper_quad.pt_a = taper_quad.pt_d - offset
- taper_quad.pt_b = taper_quad.pt_c - offset
- quad.pt_d = taper_quad.pt_a
- quad.pt_c = taper_quad.pt_b
- else:
- taper_quad.pt_d = taper_quad.pt_a + offset
- taper_quad.pt_c = taper_quad.pt_b + offset
- quad.pt_a = taper_quad.pt_d
- quad.pt_b = taper_quad.pt_c
-
- taper_quad.is_tapered = true
- return taper_quad
- # If a new taper quad doesn't fit, re-texture the new_quad
- else:
- quad.is_tapered = true
- quad.texture = taper_texture
- return null
-
-
-func _build_edge_with_material_thread_wrapper(args: Array) -> SS2D_Edge:
- return _build_edge_with_material(args[0], args[1], args[2])
diff --git a/addons/rmsmartshape/shapes/shape_anchor.gd b/addons/rmsmartshape/shapes/shape_anchor.gd
deleted file mode 100644
index f6492b8..0000000
--- a/addons/rmsmartshape/shapes/shape_anchor.gd
+++ /dev/null
@@ -1,208 +0,0 @@
-@tool
-@icon("../assets/Anchor.svg")
-extends Node2D
-class_name SS2D_Shape_Anchor
-
-const DEBUG_DRAW_LINE_LENGTH := 128.0
-
-@export var shape_path: NodePath : set = set_shape_path
-@export var shape_point_index: int = 0 : set = set_shape_point_index
-@export_range (0.0, 1.0) var shape_point_offset: float = 0.0 : set = set_shape_point_offset
-@export_range (0, 3.14) var child_rotation: float = 3.14 : set = set_child_rotation
-@export var use_shape_scale: bool = false : set = set_use_shape_scale
-
-@export var debug_draw: bool = false : set = set_debug_draw
-
-var cached_shape_transform: Transform2D = Transform2D.IDENTITY
-var shape: SS2D_Shape = null
-
-
-###########
-#-SETTERS-#
-###########
-
-func set_shape_path(value: NodePath) -> void:
- # Assign path value
- shape_path = value
- set_shape()
-
- notify_property_list_changed()
- refresh()
-
-
-func set_shape() -> void:
- # Disconnect old shape
- if shape != null:
- disconnect_shape(shape)
-
- # Set shape if path is valid and connect
- shape = null
- if has_node(shape_path):
- var new_node: Node = get_node(shape_path)
- if not new_node is SS2D_Shape:
- push_error("Shape Path isn't a valid subtype of SS2D_Shape! Aborting...")
- return
- shape = new_node
- connect_shape(shape)
- shape_point_index = get_shape_index_range(shape, shape_point_index)
-
-
-func get_shape_index_range(s: SS2D_Shape, idx: int) -> int:
- var point_count: int = s.get_point_count()
- # Subtract 2;
- # 'point_count' is out of bounds; subtract 1
- # cannot use final idx as starting point_index; subtract another 1
- var final_idx: int = point_count - 2
- if idx < 0:
- idx = final_idx
- idx = idx % (final_idx + 1)
- return idx
-
-
-func set_shape_point_index(value: int) -> void:
- if value == shape_point_index:
- return
-
- if shape == null:
- shape_point_index = value
- return
-
- shape_point_index = get_shape_index_range(shape, value)
- #notify_property_list_changed()
- refresh()
-
-
-func set_shape_point_offset(value: float) -> void:
- shape_point_offset = value
- #notify_property_list_changed()
- refresh()
-
-
-func set_use_shape_scale(value: bool) -> void:
- use_shape_scale = value
- #notify_property_list_changed()
- refresh()
-
-
-func set_child_rotation(value: float) -> void:
- child_rotation = value
- #notify_property_list_changed()
- refresh()
-
-
-func set_debug_draw(v: bool) -> void:
- debug_draw = v
- #notify_property_list_changed()
- refresh()
-
-
-##########
-#-EVENTS-#
-##########
-func _process(_delta: float) -> void:
- if shape == null:
- set_shape()
- return
- if shape.is_queued_for_deletion():
- return
- if shape.get_global_transform() != cached_shape_transform:
- cached_shape_transform = shape.get_global_transform()
- refresh()
-
-
-func _monitored_node_leaving() -> void:
- pass
-
-
-func _handle_point_change() -> void:
- refresh()
-
-
-#########
-#LOGIC-#
-#########
-func _cubic_bezier(p0: Vector2, p1: Vector2, p2: Vector2, p3: Vector2, t: float) -> Vector2:
- var q0 := p0.lerp(p1, t)
- var q1 := p1.lerp(p2, t)
- var q2 := p2.lerp(p3, t)
-
- var r0 := q0.lerp(q1, t)
- var r1 := q1.lerp(q2, t)
-
- var s := r0.lerp(r1, t)
- return s
-
-
-func disconnect_shape(s: SS2D_Shape) -> void:
- s.disconnect("points_modified", self._handle_point_change)
- s.disconnect("tree_exiting", self._monitored_node_leaving)
-
-
-func connect_shape(s: SS2D_Shape) -> void:
- s.connect("points_modified", self._handle_point_change)
- s.connect("tree_exiting", self._monitored_node_leaving)
-
-
-func refresh() -> void:
- if shape == null:
- return
- if not is_instance_valid(shape):
- return
- if shape.is_queued_for_deletion():
- disconnect_shape(shape)
- shape = null
- return
-
- # Subtract one, cannot use final point as starting index
-# var point_count: int = shape.get_point_count() - 1
-
- var pt_a_index: int = shape_point_index
- var pt_b_index: int = shape_point_index + 1
- var pt_a_key: int = shape.get_point_key_at_index(pt_a_index)
- var pt_b_key: int = shape.get_point_key_at_index(pt_b_index)
-
- var pt_a: Vector2 = shape.global_transform * shape.get_point_position(pt_a_key)
- var pt_b: Vector2 = shape.global_transform * shape.get_point_position(pt_b_key)
-
- var pt_a_handle: Vector2
- var pt_b_handle: Vector2
-
- var n_pt: Vector2
- var n_pt_a: Vector2
- var n_pt_b: Vector2
-
- var angle := 0.0
-
- pt_a_handle = shape.global_transform * (
- shape.get_point_position(pt_a_key) + shape.get_point_out(pt_a_key)
- )
- pt_b_handle = shape.global_transform * (
- shape.get_point_position(pt_b_key) + shape.get_point_in(pt_b_key)
- )
-
- # If this segment uses no bezier curve, use linear interpolation instead
- if pt_a_handle != pt_a or pt_b_handle != pt_b:
- n_pt = _cubic_bezier(pt_a, pt_a_handle, pt_b_handle, pt_b, shape_point_offset)
- else:
- n_pt = pt_a.lerp(pt_b, shape_point_offset)
-
- n_pt_a = _cubic_bezier(
- pt_a, pt_a_handle, pt_b_handle, pt_b, clampf(shape_point_offset - 0.1, 0.0, 1.0)
- )
- n_pt_b = _cubic_bezier(
- pt_a, pt_a_handle, pt_b_handle, pt_b, clampf(shape_point_offset + 0.1, 0.0, 1.0)
- )
-
- angle = atan2(n_pt_a.y - n_pt_b.y, n_pt_a.x - n_pt_b.x)
-
- self.global_transform = Transform2D(angle + child_rotation, n_pt)
-
- if use_shape_scale:
- self.scale = shape.scale
-
- queue_redraw()
-
-
-func _draw() -> void:
- if Engine.is_editor_hint() and debug_draw:
- draw_line(Vector2.ZERO, Vector2(0, -DEBUG_DRAW_LINE_LENGTH), self.modulate)
diff --git a/addons/rmsmartshape/shapes/shape_closed.gd b/addons/rmsmartshape/shapes/shape_closed.gd
deleted file mode 100644
index 1fa3ae7..0000000
--- a/addons/rmsmartshape/shapes/shape_closed.gd
+++ /dev/null
@@ -1,58 +0,0 @@
-@tool
-@icon("../assets/closed_shape.png")
-extends SS2D_Shape
-class_name SS2D_Shape_Closed
-## DEPRECATED: Use [SS2D_Shape] instead.
-## @deprecated
-
-# UNUSED FUNCTIONS:
-
-## Returns true if line segment 'a1a2' and 'b1b2' intersect.[br]
-## Find the four orientations needed for general and special cases.[br]
-#func do_edges_intersect(a1: Vector2, a2: Vector2, b1: Vector2, b2: Vector2) -> bool:
-# var o1: int = get_points_orientation([a1, a2, b1])
-# var o2: int = get_points_orientation([a1, a2, b2])
-# var o3: int = get_points_orientation([b1, b2, a1])
-# var o4: int = get_points_orientation([b1, b2, a2])
-#
-# # General case
-# if o1 != o2 and o3 != o4:
-# return true
-#
-# # Special Cases
-# # a1, a2 and b1 are colinear and b1 lies on segment p1q1
-# if o1 == ORIENTATION.COLINEAR and on_segment(a1, b1, a2):
-# return true
-#
-# # a1, a2 and b2 are colinear and b2 lies on segment p1q1
-# if o2 == ORIENTATION.COLINEAR and on_segment(a1, b2, a2):
-# return true
-#
-# # b1, b2 and a1 are colinear and a1 lies on segment p2q2
-# if o3 == ORIENTATION.COLINEAR and on_segment(b1, a1, b2):
-# return true
-#
-# # b1, b2 and a2 are colinear and a2 lies on segment p2q2
-# if o4 == ORIENTATION.COLINEAR and on_segment(b1, a2, b2):
-# return true
-#
-# # Doesn't fall in any of the above cases
-# return false
-
-
-#static func get_edge_intersection(a1: Vector2, a2: Vector2, b1: Vector2, b2: Vector2) -> Variant:
-# var den: float = (b2.y - b1.y) * (a2.x - a1.x) - (b2.x - b1.x) * (a2.y - a1.y)
-#
-# # Check if lines are parallel or coincident
-# if den == 0:
-# return null
-#
-# var ua: float = ((b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x)) / den
-# var ub: float = ((a2.x - a1.x) * (a1.y - b1.y) - (a2.y - a1.y) * (a1.x - b1.x)) / den
-#
-# if ua < 0 or ub < 0 or ua > 1 or ub > 1:
-# return null
-#
-# return Vector2(a1.x + ua * (a2.x - a1.x), a1.y + ua * (a2.y - a1.y))
-
-
diff --git a/addons/rmsmartshape/shapes/shape_open.gd b/addons/rmsmartshape/shapes/shape_open.gd
deleted file mode 100644
index 76d11d3..0000000
--- a/addons/rmsmartshape/shapes/shape_open.gd
+++ /dev/null
@@ -1,7 +0,0 @@
-@tool
-@icon("../assets/open_shape.png")
-extends SS2D_Shape
-class_name SS2D_Shape_Open
-
-## DEPRECATED: Use [SS2D_Shape] instead.
-## @deprecated
diff --git a/addons/rmsmartshape/shapes/shape_render.gd b/addons/rmsmartshape/shapes/shape_render.gd
deleted file mode 100644
index dfa43b7..0000000
--- a/addons/rmsmartshape/shapes/shape_render.gd
+++ /dev/null
@@ -1,31 +0,0 @@
-@tool
-extends Node2D
-class_name SS2D_Shape_Render
-
-## Node is used to render shape geometry.
-
-var mesh: SS2D_Mesh = null : set = set_mesh
-
-
-func set_mesh(m: SS2D_Mesh) -> void:
- mesh = m
- if m != null:
- if m.force_no_tiling:
- texture_repeat = CanvasItem.TEXTURE_REPEAT_DISABLED
- else:
- texture_repeat = CanvasItem.TEXTURE_REPEAT_PARENT_NODE
- material = mesh.material
- z_index = mesh.z_index
- z_as_relative = mesh.z_as_relative
- show_behind_parent = mesh.show_behind_parent
- else:
- material = null
- z_index = 0
- z_as_relative = true
- show_behind_parent = false
- queue_redraw()
-
-
-func _draw() -> void:
- if mesh != null:
- mesh.render(self)
diff --git a/addons/rmsmartshape/strings.gd b/addons/rmsmartshape/strings.gd
deleted file mode 100644
index 9195b79..0000000
--- a/addons/rmsmartshape/strings.gd
+++ /dev/null
@@ -1,16 +0,0 @@
-@tool
-extends Resource
-class_name SS2D_Strings
-
-const EN_TOOLTIP_CREATE_VERT := "Create Vertices Tool\nLMB: Add vertex\nShift+LMB: Create Bezier curve using Control Points\nControl+LMB: Set Pivot Point\nLMB+Drag: Move Point\nLMB: Click on edge to split\nRMB: Delete Point"
-const EN_TOOLTIP_EDIT_VERT := "Edit Vertices Tool\nShift+LMB: Create Bezier curve using Control Points\nAlt+LMB: Add vertex\nControl+LMB: Set Pivot Point\nLMB+Drag: Move Point\nLMB: Click on edge to split\nRMB: Delete Point"
-const EN_TOOLTIP_EDIT_EDGE := "Edit Edge Tool\nSelect each edge's properties"
-const EN_TOOLTIP_CUT_EDGE := "Cut Edge Tool\nRemoves the edge between vertices, opening the shape.\nCan be used to split the shape into two separate shapes."
-const EN_TOOLTIP_FREEHAND := "Freehand Tool\nHold LMB: Add vertices along the drag line.\nControl+LMB: remove vertices inside the circle while dragging.\nShift+Mousewheel: Change circle size for drawing.\nShift+Control+Mousewheel: Change circle size for eraser."
-const EN_TOOLTIP_PIVOT := "Set Pivot Tool\nSets the origin of the shape"
-const EN_TOOLTIP_CENTER_PIVOT := "Center Pivot\nSets the origin to the centroid of the shape"
-const EN_TOOLTIP_COLLISION := "Collision Tool\nAdds a static body parent and collision polygon sibling\nUse this to auto-generate collision nodes"
-const EN_TOOLTIP_SNAP := "Snapping Options"
-const EN_TOOLTIP_MORE_OPTIONS := "More Options"
-
-const EN_OPTIONS_DEFER_MESH_UPDATES := "Defer Mesh Updates"
diff --git a/addons/rmsmartshape/vertex_properties.gd b/addons/rmsmartshape/vertex_properties.gd
deleted file mode 100644
index ab53688..0000000
--- a/addons/rmsmartshape/vertex_properties.gd
+++ /dev/null
@@ -1,38 +0,0 @@
-@tool
-extends Resource
-class_name SS2D_VertexProperties
-
-@export var texture_idx: int : set = set_texture_idx
-@export var flip: bool : set = set_flip
-@export var width: float : set = set_width
-
-
-func set_texture_idx(i: int) -> void:
- texture_idx = i
- emit_changed()
-
-
-func set_flip(b: bool) -> void:
- flip = b
- emit_changed()
-
-
-func set_width(w: float) -> void:
- width = w
- emit_changed()
-
-
-func _init() -> void:
- texture_idx = 0
- flip = false
- width = 1.0
-
-
-func equals(other: SS2D_VertexProperties) -> bool:
- if other.flip != flip:
- return false
- if other.texture_idx != texture_idx:
- return false
- if other.width != width:
- return false
- return true
diff --git a/fonts/Inter.ttc.import b/fonts/Inter.ttc.import
index 0655c7e..7a50e7f 100644
--- a/fonts/Inter.ttc.import
+++ b/fonts/Inter.ttc.import
@@ -23,6 +23,7 @@ allow_system_fallback=true
force_autohinter=false
hinting=1
subpixel_positioning=1
+keep_rounding_remainders=true
oversampling=0.0
Fallbacks=null
fallbacks=[]
diff --git a/fonts/InterVariable-Italic.ttf.import b/fonts/InterVariable-Italic.ttf.import
index 70a0a39..79e9751 100644
--- a/fonts/InterVariable-Italic.ttf.import
+++ b/fonts/InterVariable-Italic.ttf.import
@@ -23,6 +23,7 @@ allow_system_fallback=true
force_autohinter=false
hinting=1
subpixel_positioning=1
+keep_rounding_remainders=true
oversampling=0.0
Fallbacks=null
fallbacks=[]
diff --git a/fonts/InterVariable.ttf.import b/fonts/InterVariable.ttf.import
index 587da4d..4fe53d4 100644
--- a/fonts/InterVariable.ttf.import
+++ b/fonts/InterVariable.ttf.import
@@ -23,6 +23,7 @@ allow_system_fallback=true
force_autohinter=false
hinting=1
subpixel_positioning=1
+keep_rounding_remainders=true
oversampling=0.0
Fallbacks=null
fallbacks=[]
diff --git a/fonts/PressStart2P-Regular.ttf.import b/fonts/PressStart2P-Regular.ttf.import
index b1ca4c1..7a03015 100644
--- a/fonts/PressStart2P-Regular.ttf.import
+++ b/fonts/PressStart2P-Regular.ttf.import
@@ -23,6 +23,7 @@ allow_system_fallback=true
force_autohinter=false
hinting=1
subpixel_positioning=1
+keep_rounding_remainders=true
oversampling=0.0
Fallbacks=null
fallbacks=[]
diff --git a/objects/big_coin.tscn b/objects/big_coin.tscn
index 87b1eb7..85debe1 100644
--- a/objects/big_coin.tscn
+++ b/objects/big_coin.tscn
@@ -1,9 +1,9 @@
[gd_scene load_steps=7 format=3 uid="uid://bargnp4twtmxg"]
[ext_resource type="Texture2D" uid="uid://djifxc5x0dyrw" path="res://sprites/ppc_tileset.png" id="1_aya2w"]
-[ext_resource type="Script" path="res://scripts/components/collectable.gd" id="2_7cph7"]
+[ext_resource type="Script" uid="uid://pa1bwc4no08q" path="res://scripts/components/collectable.gd" id="2_7cph7"]
[ext_resource type="Resource" uid="uid://bsnr5v2b2mfsl" path="res://resources/collectables/big_coin.tres" id="3_lk3av"]
-[ext_resource type="Script" path="res://scripts/components/fade_away.gd" id="4_wkrj0"]
+[ext_resource type="Script" uid="uid://bg75hnr3q6grk" path="res://scripts/components/fade_away.gd" id="4_wkrj0"]
[ext_resource type="AudioStream" uid="uid://bceic1csr8rq3" path="res://sfx/pickup_coin_2.wav" id="5_dbffd"]
[sub_resource type="CircleShape2D" id="CircleShape2D_3ask2"]
diff --git a/objects/big_treasure.tscn b/objects/big_treasure.tscn
index 8185d56..e12c630 100644
--- a/objects/big_treasure.tscn
+++ b/objects/big_treasure.tscn
@@ -1,9 +1,9 @@
[gd_scene load_steps=7 format=3 uid="uid://d08dfqmirnd66"]
[ext_resource type="Texture2D" uid="uid://djifxc5x0dyrw" path="res://sprites/ppc_tileset.png" id="1_1co1x"]
-[ext_resource type="Script" path="res://scripts/components/collectable.gd" id="2_cujcq"]
+[ext_resource type="Script" uid="uid://pa1bwc4no08q" path="res://scripts/components/collectable.gd" id="2_cujcq"]
[ext_resource type="Resource" uid="uid://b6xqotmke54x" path="res://resources/collectables/big_treasure.tres" id="3_k64cr"]
-[ext_resource type="Script" path="res://scripts/components/fade_away.gd" id="4_nw7tw"]
+[ext_resource type="Script" uid="uid://bg75hnr3q6grk" path="res://scripts/components/fade_away.gd" id="4_nw7tw"]
[ext_resource type="AudioStream" uid="uid://wr7n5ivv06ux" path="res://sfx/pickup_coin_4.wav" id="5_fxf8v"]
[sub_resource type="CircleShape2D" id="CircleShape2D_3ask2"]
diff --git a/objects/brick.tscn b/objects/brick.tscn
index d2d8140..5b46066 100644
--- a/objects/brick.tscn
+++ b/objects/brick.tscn
@@ -1,8 +1,8 @@
[gd_scene load_steps=5 format=3 uid="uid://bymro4t7angv5"]
[ext_resource type="Texture2D" uid="uid://djifxc5x0dyrw" path="res://sprites/ppc_tileset.png" id="1_1c3jb"]
-[ext_resource type="Script" path="res://scripts/components/bullet.gd" id="2_i6t5k"]
-[ext_resource type="Script" path="res://scripts/components/damage_component.gd" id="3_8xipx"]
+[ext_resource type="Script" uid="uid://bh2vrkdbrtpin" path="res://scripts/components/bullet.gd" id="2_i6t5k"]
+[ext_resource type="Script" uid="uid://dkmxhjtmu5xlb" path="res://scripts/components/damage_component.gd" id="3_8xipx"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_ar0xf"]
size = Vector2(16, 10)
diff --git a/objects/brick_player.tscn b/objects/brick_player.tscn
index bca173e..13080ae 100644
--- a/objects/brick_player.tscn
+++ b/objects/brick_player.tscn
@@ -1,30 +1,30 @@
[gd_scene load_steps=29 format=3 uid="uid://bqi5s710xb1ju"]
-[ext_resource type="Script" path="res://scripts/player.gd" id="1_8j4h4"]
+[ext_resource type="Script" uid="uid://ccuddyoakg04u" path="res://scripts/player.gd" id="1_8j4h4"]
[ext_resource type="Texture2D" uid="uid://b7gp0gqvkv8j4" path="res://sprites/MrBrick_base.png" id="2_bc55y"]
[ext_resource type="Texture2D" uid="uid://jl1gwqchhpdc" path="res://sprites/left_eye.png" id="3_2srrh"]
[ext_resource type="Texture2D" uid="uid://iiawtnwmeny3" path="res://sprites/right_eye.png" id="4_ccn81"]
-[ext_resource type="Script" path="res://scripts/components/flip_player.gd" id="5_geu10"]
-[ext_resource type="Script" path="res://scripts/components/score.gd" id="6_fowa2"]
-[ext_resource type="Script" path="res://scripts/components/health.gd" id="7_tqjk8"]
-[ext_resource type="Script" path="res://scripts/components/player_death.gd" id="8_1v23d"]
-[ext_resource type="Script" path="res://scripts/components/knockback.gd" id="9_rjyu4"]
-[ext_resource type="Script" path="res://scripts/components/stomp_damage_component.gd" id="12_payr4"]
-[ext_resource type="Script" path="res://scripts/components/flashing_component.gd" id="13_hrtyn"]
-[ext_resource type="Script" path="res://scripts/components/invulnerability_component.gd" id="14_jopig"]
-[ext_resource type="Script" path="res://scripts/components/can_be_launched_component.gd" id="16_kemlv"]
+[ext_resource type="Script" uid="uid://oxeqvxkgj87j" path="res://scripts/components/flip_player.gd" id="5_geu10"]
+[ext_resource type="Script" uid="uid://qeu80jy4vmuf" path="res://scripts/components/score.gd" id="6_fowa2"]
+[ext_resource type="Script" uid="uid://btfsq0bvtrx3t" path="res://scripts/components/health.gd" id="7_tqjk8"]
+[ext_resource type="Script" uid="uid://dkpu3121y88oo" path="res://scripts/components/player_death.gd" id="8_1v23d"]
+[ext_resource type="Script" uid="uid://nogmyshjrv57" path="res://scripts/components/knockback.gd" id="9_rjyu4"]
+[ext_resource type="Script" uid="uid://ulhswh4jjlc6" path="res://scripts/components/stomp_damage_component.gd" id="12_payr4"]
+[ext_resource type="Script" uid="uid://dqmbvuutd5c3c" path="res://scripts/components/flashing_component.gd" id="13_hrtyn"]
+[ext_resource type="Script" uid="uid://ijrli0x8ij8v" path="res://scripts/components/invulnerability_component.gd" id="14_jopig"]
+[ext_resource type="Script" uid="uid://6ffxsx3gknhr" path="res://scripts/components/can_be_launched_component.gd" id="16_kemlv"]
[ext_resource type="Resource" uid="uid://dw5ee2lpeypnb" path="res://resources/skills/brick_throw.tres" id="16_smbir"]
[ext_resource type="Resource" uid="uid://2glvryih82t1" path="res://resources/skills/fire_brick.tres" id="17_6y5qu"]
-[ext_resource type="Script" path="res://scripts/components/trigger_lever_component.gd" id="17_hglfj"]
+[ext_resource type="Script" uid="uid://bpy6xtfm8l3hy" path="res://scripts/components/trigger_lever_component.gd" id="17_hglfj"]
[ext_resource type="AudioStream" uid="uid://duj2q0rqytaxg" path="res://sfx/jump.wav" id="18_pysae"]
[ext_resource type="Resource" uid="uid://cx5fsbexblp60" path="res://resources/skills/ice_brick.tres" id="18_umfbf"]
[ext_resource type="Resource" uid="uid://cdp8sex36vdq2" path="res://resources/skills/explosive_brick.tres" id="19_5wjb7"]
[ext_resource type="AudioStream" uid="uid://bmfn6p88gy575" path="res://sfx/player_hurt.wav" id="19_7anly"]
[ext_resource type="AudioStream" uid="uid://ycgtf6wj7mto" path="res://sfx/heal.wav" id="20_bptj5"]
-[ext_resource type="Script" path="res://scripts/skill_manager.gd" id="20_ppfy7"]
-[ext_resource type="Script" path="res://scripts/resources/skill_data.gd" id="21_d0oiv"]
+[ext_resource type="Script" uid="uid://cjqe428jwip6b" path="res://scripts/skill_manager.gd" id="20_ppfy7"]
+[ext_resource type="Script" uid="uid://bya240e627ti6" path="res://scripts/resources/skill_data.gd" id="21_d0oiv"]
[ext_resource type="Resource" uid="uid://d3bjre2etov1n" path="res://resources/skills/magnetic.tres" id="22_vnsgd"]
-[ext_resource type="Script" path="res://scripts/components/skill_unlocker_component.gd" id="23_qsv2c"]
+[ext_resource type="Script" uid="uid://bjsyeo1n7bsri" path="res://scripts/components/skill_unlocker_component.gd" id="23_qsv2c"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_hdsg1"]
size = Vector2(16, 31)
diff --git a/objects/bullet.tscn b/objects/bullet.tscn
index 77f3f56..fa3d308 100644
--- a/objects/bullet.tscn
+++ b/objects/bullet.tscn
@@ -1,8 +1,8 @@
[gd_scene load_steps=5 format=3 uid="uid://bhc7y4xugu4q7"]
[ext_resource type="Texture2D" uid="uid://djifxc5x0dyrw" path="res://sprites/ppc_tileset.png" id="1_w543f"]
-[ext_resource type="Script" path="res://scripts/components/damage_component.gd" id="2_ll0xw"]
-[ext_resource type="Script" path="res://scripts/components/bullet.gd" id="3_keogl"]
+[ext_resource type="Script" uid="uid://dkmxhjtmu5xlb" path="res://scripts/components/damage_component.gd" id="2_ll0xw"]
+[ext_resource type="Script" uid="uid://bh2vrkdbrtpin" path="res://scripts/components/bullet.gd" id="3_keogl"]
[sub_resource type="CircleShape2D" id="CircleShape2D_txsw8"]
radius = 4.0
diff --git a/objects/cage.tscn b/objects/cage.tscn
index 640b766..df08133 100644
--- a/objects/cage.tscn
+++ b/objects/cage.tscn
@@ -1,7 +1,7 @@
[gd_scene load_steps=5 format=3 uid="uid://to2xnqev0pu1"]
[ext_resource type="Texture2D" uid="uid://djifxc5x0dyrw" path="res://sprites/ppc_tileset.png" id="1_5poh3"]
-[ext_resource type="Script" path="res://scripts/components/cage_component.gd" id="2_unomj"]
+[ext_resource type="Script" uid="uid://ddplvyjqguxtl" path="res://scripts/components/cage_component.gd" id="2_unomj"]
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_aivtb"]
texture = ExtResource("1_5poh3")
diff --git a/objects/cannon.tscn b/objects/cannon.tscn
index 6674b3b..1dbda6f 100644
--- a/objects/cannon.tscn
+++ b/objects/cannon.tscn
@@ -1,8 +1,8 @@
[gd_scene load_steps=5 format=3 uid="uid://dstko446qydsc"]
[ext_resource type="Texture2D" uid="uid://djifxc5x0dyrw" path="res://sprites/ppc_tileset.png" id="1_6gptm"]
-[ext_resource type="Script" path="res://scripts/components/destroyable_component.gd" id="2_2tib2"]
-[ext_resource type="Script" path="res://scripts/components/health.gd" id="3_vevhj"]
+[ext_resource type="Script" uid="uid://d01dmoafptl2p" path="res://scripts/components/destroyable_component.gd" id="2_2tib2"]
+[ext_resource type="Script" uid="uid://btfsq0bvtrx3t" path="res://scripts/components/health.gd" id="3_vevhj"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_j5sus"]
size = Vector2(16, 16)
diff --git a/objects/cannon_ray_down.tscn b/objects/cannon_ray_down.tscn
index 0cd351a..0055434 100644
--- a/objects/cannon_ray_down.tscn
+++ b/objects/cannon_ray_down.tscn
@@ -1,8 +1,8 @@
[gd_scene load_steps=5 format=3 uid="uid://dfwpha0d18dmn"]
[ext_resource type="Texture2D" uid="uid://djifxc5x0dyrw" path="res://sprites/ppc_tileset.png" id="1_rwgpm"]
-[ext_resource type="Script" path="res://scripts/components/damage_component.gd" id="2_cprue"]
-[ext_resource type="Script" path="res://scripts/components/beam_component.gd" id="3_jlh0s"]
+[ext_resource type="Script" uid="uid://dkmxhjtmu5xlb" path="res://scripts/components/damage_component.gd" id="2_cprue"]
+[ext_resource type="Script" uid="uid://bejv75mi8npj0" path="res://scripts/components/beam_component.gd" id="3_jlh0s"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_ptfn7"]
size = Vector2(8, 16)
diff --git a/objects/cannon_ray_left.tscn b/objects/cannon_ray_left.tscn
index 1602248..3ab4acb 100644
--- a/objects/cannon_ray_left.tscn
+++ b/objects/cannon_ray_left.tscn
@@ -1,8 +1,8 @@
[gd_scene load_steps=5 format=3 uid="uid://d3lt4rhxduv44"]
[ext_resource type="Texture2D" uid="uid://djifxc5x0dyrw" path="res://sprites/ppc_tileset.png" id="1_l5x2w"]
-[ext_resource type="Script" path="res://scripts/components/damage_component.gd" id="2_mxy0q"]
-[ext_resource type="Script" path="res://scripts/components/beam_component.gd" id="3_mcbof"]
+[ext_resource type="Script" uid="uid://dkmxhjtmu5xlb" path="res://scripts/components/damage_component.gd" id="2_mxy0q"]
+[ext_resource type="Script" uid="uid://bejv75mi8npj0" path="res://scripts/components/beam_component.gd" id="3_mcbof"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_ptfn7"]
size = Vector2(16, 8)
diff --git a/objects/child.tscn b/objects/child.tscn
index 3c16ec7..5049150 100644
--- a/objects/child.tscn
+++ b/objects/child.tscn
@@ -5,7 +5,7 @@
[ext_resource type="Texture2D" uid="uid://iiawtnwmeny3" path="res://sprites/right_eye.png" id="3_k41y7"]
[ext_resource type="Texture2D" uid="uid://8h05rd26t66q" path="res://sprites/lollipop.png" id="4_vq1oq"]
[ext_resource type="Texture2D" uid="uid://dpbpjffbdbovp" path="res://sprites/cap.png" id="5_m7x6t"]
-[ext_resource type="Script" path="res://scripts/components/collectable.gd" id="5_wc3ym"]
+[ext_resource type="Script" uid="uid://pa1bwc4no08q" path="res://scripts/components/collectable.gd" id="5_wc3ym"]
[ext_resource type="Resource" uid="uid://b6apusc0jmi3x" path="res://resources/collectables/child.tres" id="6_vmvuo"]
[ext_resource type="AudioStream" uid="uid://drfr0wlgkhkdq" path="res://sfx/child_pickup.wav" id="7_j8eyh"]
diff --git a/objects/coin.tscn b/objects/coin.tscn
index 57a0721..2aa8c97 100644
--- a/objects/coin.tscn
+++ b/objects/coin.tscn
@@ -1,9 +1,9 @@
[gd_scene load_steps=7 format=3 uid="uid://54w4wisfj8v8"]
[ext_resource type="Texture2D" uid="uid://djifxc5x0dyrw" path="res://sprites/ppc_tileset.png" id="1_epuj5"]
-[ext_resource type="Script" path="res://scripts/components/collectable.gd" id="2_y0k47"]
+[ext_resource type="Script" uid="uid://pa1bwc4no08q" path="res://scripts/components/collectable.gd" id="2_y0k47"]
[ext_resource type="Resource" uid="uid://vql535ckoeqm" path="res://resources/collectables/coin.tres" id="3_fm2fq"]
-[ext_resource type="Script" path="res://scripts/components/fade_away.gd" id="4_fx1h2"]
+[ext_resource type="Script" uid="uid://bg75hnr3q6grk" path="res://scripts/components/fade_away.gd" id="4_fx1h2"]
[ext_resource type="AudioStream" uid="uid://dpyr80hk4kebc" path="res://sfx/pickup_coin_1.wav" id="5_4jc2c"]
[sub_resource type="CircleShape2D" id="CircleShape2D_3ask2"]
diff --git a/objects/collapsing_bridge.tscn b/objects/collapsing_bridge.tscn
index 5a9607e..7f345a5 100644
--- a/objects/collapsing_bridge.tscn
+++ b/objects/collapsing_bridge.tscn
@@ -1,7 +1,7 @@
[gd_scene load_steps=5 format=3 uid="uid://ct8fim6mduyl3"]
[ext_resource type="Texture2D" uid="uid://djifxc5x0dyrw" path="res://sprites/ppc_tileset.png" id="1_rka1x"]
-[ext_resource type="Script" path="res://scripts/components/collapsable.gd" id="2_3vvum"]
+[ext_resource type="Script" uid="uid://r0a6xjicrh74" path="res://scripts/components/collapsable.gd" id="2_3vvum"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_l44jt"]
size = Vector2(16, 4)
diff --git a/objects/damage_test.tscn b/objects/damage_test.tscn
index 6ee89d7..6e63b43 100644
--- a/objects/damage_test.tscn
+++ b/objects/damage_test.tscn
@@ -1,11 +1,13 @@
[gd_scene load_steps=4 format=3 uid="uid://dmvipsoauefs3"]
-[ext_resource type="Script" path="res://scripts/components/damage.gd" id="1_qhm3r"]
[ext_resource type="Texture2D" uid="uid://djifxc5x0dyrw" path="res://sprites/ppc_tileset.png" id="1_yevdj"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_pn1xh"]
size = Vector2(8, 16)
+[sub_resource type="Resource" id="Resource_dv860"]
+metadata/__load_path__ = "res://scripts/components/damage.gd"
+
[node name="Damage" type="Area2D"]
collision_mask = 5
@@ -19,5 +21,5 @@ vframes = 12
frame = 59
[node name="DamageComponent" type="Node" parent="." node_paths=PackedStringArray("area2d")]
-script = ExtResource("1_qhm3r")
+script = SubResource("Resource_dv860")
area2d = NodePath("..")
diff --git a/objects/enemy.tscn b/objects/enemy.tscn
index e76aff7..1ffa24e 100644
--- a/objects/enemy.tscn
+++ b/objects/enemy.tscn
@@ -2,16 +2,16 @@
[ext_resource type="Shader" uid="uid://bs4xvm4qkurpr" path="res://shaders/hit_flash.tres" id="1_ep4yr"]
[ext_resource type="Texture2D" uid="uid://cu72810eyk4dx" path="res://sprites/enemy-robot.png" id="2_hjtwe"]
-[ext_resource type="Script" path="res://scripts/components/health.gd" id="2_o170m"]
-[ext_resource type="Script" path="res://scripts/components/damage_component.gd" id="4_4eajk"]
-[ext_resource type="Script" path="res://scripts/components/side_to_side_movement.gd" id="4_gbsq8"]
-[ext_resource type="Script" path="res://scripts/components/periodic_shooting.gd" id="5_m03v0"]
-[ext_resource type="Script" path="res://scripts/components/enemy_death.gd" id="6_6p3gr"]
-[ext_resource type="Script" path="res://scripts/components/flashing_component.gd" id="7_xsaiy"]
-[ext_resource type="Script" path="res://scripts/components/hit_component.gd" id="9_0qjr4"]
-[ext_resource type="Script" path="res://scripts/components/status_effect_component.gd" id="10_5i27q"]
-[ext_resource type="Script" path="res://scripts/components/fire_effect_component.gd" id="10_ej8vg"]
-[ext_resource type="Script" path="res://scripts/components/ice_effect_component.gd" id="11_pq0k7"]
+[ext_resource type="Script" uid="uid://btfsq0bvtrx3t" path="res://scripts/components/health.gd" id="2_o170m"]
+[ext_resource type="Script" uid="uid://dkmxhjtmu5xlb" path="res://scripts/components/damage_component.gd" id="4_4eajk"]
+[ext_resource type="Script" uid="uid://dmqpif5qhvri3" path="res://scripts/components/side_to_side_movement.gd" id="4_gbsq8"]
+[ext_resource type="Script" uid="uid://b37gqnycj6rtk" path="res://scripts/components/periodic_shooting.gd" id="5_m03v0"]
+[ext_resource type="Script" uid="uid://dqm371fysuk7i" path="res://scripts/components/enemy_death.gd" id="6_6p3gr"]
+[ext_resource type="Script" uid="uid://dqmbvuutd5c3c" path="res://scripts/components/flashing_component.gd" id="7_xsaiy"]
+[ext_resource type="Script" uid="uid://ceq8n7yw7qxpi" path="res://scripts/components/hit_component.gd" id="9_0qjr4"]
+[ext_resource type="Script" uid="uid://c07d50s20rl8s" path="res://scripts/components/status_effect_component.gd" id="10_5i27q"]
+[ext_resource type="Script" uid="uid://qi2irprbqru2" path="res://scripts/components/fire_effect_component.gd" id="10_ej8vg"]
+[ext_resource type="Script" uid="uid://dhj4qtwcqmqkj" path="res://scripts/components/ice_effect_component.gd" id="11_pq0k7"]
[ext_resource type="AudioStream" uid="uid://b3tsqhr06pbrs" path="res://sfx/enemy_hurt.wav" id="13_u4k3d"]
[ext_resource type="AudioStream" uid="uid://dyev46uqusimi" path="res://sfx/shoot.wav" id="14_tdjks"]
[ext_resource type="PackedScene" uid="uid://dx80ivlvuuew4" path="res://objects/fire_fx.tscn" id="15_mc6rj"]
diff --git a/objects/exploding_brick.tscn b/objects/exploding_brick.tscn
index 38ee7e0..12925b2 100644
--- a/objects/exploding_brick.tscn
+++ b/objects/exploding_brick.tscn
@@ -1,9 +1,9 @@
[gd_scene load_steps=8 format=3 uid="uid://5surx230gfw3"]
[ext_resource type="Texture2D" uid="uid://djifxc5x0dyrw" path="res://sprites/ppc_tileset.png" id="1_rcgxf"]
-[ext_resource type="Script" path="res://scripts/components/bullet.gd" id="2_1i2y5"]
-[ext_resource type="Script" path="res://scripts/components/damage_component.gd" id="3_y0uai"]
-[ext_resource type="Script" path="res://scripts/components/explosive_component.gd" id="4_8lw0n"]
+[ext_resource type="Script" uid="uid://bh2vrkdbrtpin" path="res://scripts/components/bullet.gd" id="2_1i2y5"]
+[ext_resource type="Script" uid="uid://dkmxhjtmu5xlb" path="res://scripts/components/damage_component.gd" id="3_y0uai"]
+[ext_resource type="Script" uid="uid://beg4dk7d5pvhp" path="res://scripts/components/explosive_component.gd" id="4_8lw0n"]
[ext_resource type="PackedScene" uid="uid://dyp4i4ru2j2jh" path="res://objects/explosion_fx.tscn" id="5_6oopj"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_ar0xf"]
diff --git a/objects/explosion_fx.tscn b/objects/explosion_fx.tscn
index 6103db1..3b045fa 100644
--- a/objects/explosion_fx.tscn
+++ b/objects/explosion_fx.tscn
@@ -1,6 +1,6 @@
[gd_scene load_steps=9 format=3 uid="uid://dyp4i4ru2j2jh"]
-[ext_resource type="Script" path="res://scripts/components/cleanup_component.gd" id="1_8uvxg"]
+[ext_resource type="Script" uid="uid://f74xpfg7624d" path="res://scripts/components/cleanup_component.gd" id="1_8uvxg"]
[sub_resource type="Curve" id="Curve_8umf8"]
_data = [Vector2(0, 1), 0.0, 0.0, 0, 0, Vector2(1, 0.4), 0.0, 0.0, 0, 0]
@@ -39,11 +39,11 @@ alpha_curve = SubResource("CurveTexture_w18ti")
[node name="ExplosionFX" type="GPUParticles2D"]
emitting = false
amount = 2048
-process_material = SubResource("ParticleProcessMaterial_1ujje")
lifetime = 0.5
one_shot = true
explosiveness = 1.0
fixed_fps = 24
+process_material = SubResource("ParticleProcessMaterial_1ujje")
[node name="CleanUpComponent" type="Node" parent="." node_paths=PackedStringArray("root")]
script = ExtResource("1_8uvxg")
diff --git a/objects/fire_brick.tscn b/objects/fire_brick.tscn
index 520d957..2d174b0 100644
--- a/objects/fire_brick.tscn
+++ b/objects/fire_brick.tscn
@@ -1,10 +1,10 @@
[gd_scene load_steps=7 format=3 uid="uid://daau4j5hbklk0"]
[ext_resource type="Texture2D" uid="uid://djifxc5x0dyrw" path="res://sprites/ppc_tileset.png" id="1_52l28"]
-[ext_resource type="Script" path="res://scripts/components/bullet.gd" id="2_hjcob"]
-[ext_resource type="Script" path="res://scripts/components/damage_component.gd" id="3_sog2h"]
+[ext_resource type="Script" uid="uid://bh2vrkdbrtpin" path="res://scripts/components/bullet.gd" id="2_hjcob"]
+[ext_resource type="Script" uid="uid://dkmxhjtmu5xlb" path="res://scripts/components/damage_component.gd" id="3_sog2h"]
[ext_resource type="Resource" uid="uid://obodgnkhxuhe" path="res://resources/status_effect/fire.tres" id="4_xx5l4"]
-[ext_resource type="Script" path="res://scripts/components/effect_inflictor_component.gd" id="5_ofrqk"]
+[ext_resource type="Script" uid="uid://d3brcje121krs" path="res://scripts/components/effect_inflictor_component.gd" id="5_ofrqk"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_ar0xf"]
size = Vector2(16, 10)
diff --git a/objects/fire_fx.tscn b/objects/fire_fx.tscn
index ecedb95..fbcead8 100644
--- a/objects/fire_fx.tscn
+++ b/objects/fire_fx.tscn
@@ -28,6 +28,6 @@ color_ramp = SubResource("GradientTexture1D_mar4t")
[node name="FireFX" type="GPUParticles2D"]
amount = 512
-process_material = SubResource("ParticleProcessMaterial_dq33o")
lifetime = 0.5
fixed_fps = 24
+process_material = SubResource("ParticleProcessMaterial_dq33o")
diff --git a/objects/game_manager.tscn b/objects/game_manager.tscn
index 53496ab..6fc2c40 100644
--- a/objects/game_manager.tscn
+++ b/objects/game_manager.tscn
@@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://b4eifkc31jsun"]
-[ext_resource type="Script" path="res://scripts/game_manager.gd" id="1_58t7u"]
+[ext_resource type="Script" uid="uid://dd30bgqiagi25" path="res://scripts/game_manager.gd" id="1_58t7u"]
[node name="GameManager" type="Node"]
script = ExtResource("1_58t7u")
diff --git a/objects/hud.tscn b/objects/hud.tscn
index 202aa01..0dd3c19 100644
--- a/objects/hud.tscn
+++ b/objects/hud.tscn
@@ -1,7 +1,7 @@
[gd_scene load_steps=8 format=3 uid="uid://byxf45ukq82pe"]
[ext_resource type="LabelSettings" uid="uid://rvn5ivivfvv6" path="res://resources/ui/hud_label_settings.tres" id="1_4dsh5"]
-[ext_resource type="Script" path="res://scripts/hud.gd" id="1_ueofj"]
+[ext_resource type="Script" uid="uid://c3pde84b3kdco" path="res://scripts/hud.gd" id="1_ueofj"]
[ext_resource type="FontFile" uid="uid://xm0vbusjr7b7" path="res://fonts/PressStart2P-Regular.ttf" id="1_ygmwt"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_aa3sf"]
diff --git a/objects/ice_brick.tscn b/objects/ice_brick.tscn
index 8ac73bb..1410237 100644
--- a/objects/ice_brick.tscn
+++ b/objects/ice_brick.tscn
@@ -1,10 +1,10 @@
[gd_scene load_steps=7 format=3 uid="uid://bcmx07k12gcsc"]
[ext_resource type="Texture2D" uid="uid://djifxc5x0dyrw" path="res://sprites/ppc_tileset.png" id="1_xusxl"]
-[ext_resource type="Script" path="res://scripts/components/bullet.gd" id="2_ilnf5"]
-[ext_resource type="Script" path="res://scripts/components/damage_component.gd" id="3_3yf4g"]
+[ext_resource type="Script" uid="uid://bh2vrkdbrtpin" path="res://scripts/components/bullet.gd" id="2_ilnf5"]
+[ext_resource type="Script" uid="uid://dkmxhjtmu5xlb" path="res://scripts/components/damage_component.gd" id="3_3yf4g"]
[ext_resource type="Resource" uid="uid://02l4nbnf2aft" path="res://resources/status_effect/ice.tres" id="4_da7hn"]
-[ext_resource type="Script" path="res://scripts/components/effect_inflictor_component.gd" id="5_x7vqb"]
+[ext_resource type="Script" uid="uid://d3brcje121krs" path="res://scripts/components/effect_inflictor_component.gd" id="5_x7vqb"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_ar0xf"]
size = Vector2(16, 10)
diff --git a/objects/jump_pad.tscn b/objects/jump_pad.tscn
index 2a9bab8..c458bad 100644
--- a/objects/jump_pad.tscn
+++ b/objects/jump_pad.tscn
@@ -1,7 +1,7 @@
[gd_scene load_steps=4 format=3 uid="uid://cm3rixnnev1pg"]
[ext_resource type="Texture2D" uid="uid://djifxc5x0dyrw" path="res://sprites/ppc_tileset.png" id="1_ctugi"]
-[ext_resource type="Script" path="res://scripts/components/jump_pad_component.gd" id="2_2ypfs"]
+[ext_resource type="Script" uid="uid://dwok2qx4wpkey" path="res://scripts/components/jump_pad_component.gd" id="2_2ypfs"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_ci3ij"]
size = Vector2(16, 6)
diff --git a/objects/killzone.tscn b/objects/killzone.tscn
index e260582..1f7b37c 100644
--- a/objects/killzone.tscn
+++ b/objects/killzone.tscn
@@ -1,6 +1,6 @@
[gd_scene load_steps=3 format=3 uid="uid://bqom4cm7r18db"]
-[ext_resource type="Script" path="res://scripts/components/damage_component.gd" id="1_un3fl"]
+[ext_resource type="Script" uid="uid://dkmxhjtmu5xlb" path="res://scripts/components/damage_component.gd" id="1_un3fl"]
[sub_resource type="WorldBoundaryShape2D" id="WorldBoundaryShape2D_cr00c"]
diff --git a/objects/laser_beam.tscn b/objects/laser_beam.tscn
index e8562c1..7287291 100644
--- a/objects/laser_beam.tscn
+++ b/objects/laser_beam.tscn
@@ -1,8 +1,8 @@
[gd_scene load_steps=5 format=3 uid="uid://c7ku0k8n55hjv"]
[ext_resource type="Texture2D" uid="uid://djifxc5x0dyrw" path="res://sprites/ppc_tileset.png" id="1_brnkm"]
-[ext_resource type="Script" path="res://scripts/components/damage_component.gd" id="2_x12f0"]
-[ext_resource type="Script" path="res://scripts/components/beam_component.gd" id="3_6pj0h"]
+[ext_resource type="Script" uid="uid://dkmxhjtmu5xlb" path="res://scripts/components/damage_component.gd" id="2_x12f0"]
+[ext_resource type="Script" uid="uid://bejv75mi8npj0" path="res://scripts/components/beam_component.gd" id="3_6pj0h"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_ptfn7"]
size = Vector2(8, 16)
diff --git a/objects/lever.tscn b/objects/lever.tscn
index bcf7104..01b5ee9 100644
--- a/objects/lever.tscn
+++ b/objects/lever.tscn
@@ -1,7 +1,7 @@
[gd_scene load_steps=5 format=3 uid="uid://bd51frym6mm7v"]
[ext_resource type="Texture2D" uid="uid://djifxc5x0dyrw" path="res://sprites/ppc_tileset.png" id="1_psg62"]
-[ext_resource type="Script" path="res://scripts/components/lever_component.gd" id="2_0p0wb"]
+[ext_resource type="Script" uid="uid://hyuwsp1b336a" path="res://scripts/components/lever_component.gd" id="2_0p0wb"]
[ext_resource type="AudioStream" uid="uid://beq14we7v3iw4" path="res://sfx/activate_lever.wav" id="3_gipby"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_ke5tv"]
diff --git a/objects/marketplace.tscn b/objects/marketplace.tscn
index 8a2683b..93794f5 100644
--- a/objects/marketplace.tscn
+++ b/objects/marketplace.tscn
@@ -1,9 +1,9 @@
[gd_scene load_steps=11 format=3 uid="uid://dlm2ri562fynd"]
[ext_resource type="LabelSettings" uid="uid://rvn5ivivfvv6" path="res://resources/ui/hud_label_settings.tres" id="1_7r0u8"]
-[ext_resource type="Script" path="res://scripts/marketplace.gd" id="1_ncpyg"]
+[ext_resource type="Script" uid="uid://duifmqjarjpuv" path="res://scripts/marketplace.gd" id="1_ncpyg"]
[ext_resource type="FontFile" uid="uid://xm0vbusjr7b7" path="res://fonts/PressStart2P-Regular.ttf" id="2_ho1tm"]
-[ext_resource type="Script" path="res://scripts/resources/skill_data.gd" id="2_pg4mc"]
+[ext_resource type="Script" uid="uid://bya240e627ti6" path="res://scripts/resources/skill_data.gd" id="2_pg4mc"]
[ext_resource type="Resource" uid="uid://dw5ee2lpeypnb" path="res://resources/skills/brick_throw.tres" id="3_bk5yi"]
[ext_resource type="Resource" uid="uid://cdp8sex36vdq2" path="res://resources/skills/explosive_brick.tres" id="4_tx0n3"]
[ext_resource type="Resource" uid="uid://2glvryih82t1" path="res://resources/skills/fire_brick.tres" id="5_fqx8e"]
diff --git a/objects/player_skills/brick_throw_skill.tscn b/objects/player_skills/brick_throw_skill.tscn
index 99d851e..44137a8 100644
--- a/objects/player_skills/brick_throw_skill.tscn
+++ b/objects/player_skills/brick_throw_skill.tscn
@@ -1,6 +1,6 @@
[gd_scene load_steps=3 format=3 uid="uid://coayig4dxelo2"]
-[ext_resource type="Script" path="res://scripts/components/brick_throw.gd" id="1_hniwk"]
+[ext_resource type="Script" uid="uid://cm06xg1l3xtw5" path="res://scripts/components/brick_throw.gd" id="1_hniwk"]
[ext_resource type="PackedScene" uid="uid://bymro4t7angv5" path="res://objects/brick.tscn" id="2_4txoq"]
[node name="BrickThrowComponent" type="Node"]
diff --git a/objects/player_skills/magnetic_skill.tscn b/objects/player_skills/magnetic_skill.tscn
index 7db1dcb..296a9a0 100644
--- a/objects/player_skills/magnetic_skill.tscn
+++ b/objects/player_skills/magnetic_skill.tscn
@@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://cunyndudjh2he"]
-[ext_resource type="Script" path="res://scripts/components/magnetic_skill.gd" id="1_lwbas"]
+[ext_resource type="Script" uid="uid://ce8w71vgv37pt" path="res://scripts/components/magnetic_skill.gd" id="1_lwbas"]
[node name="MagneticSkill" type="Node"]
script = ExtResource("1_lwbas")
diff --git a/objects/tooltip.tscn b/objects/tooltip.tscn
index 71d9cfb..c64f825 100644
--- a/objects/tooltip.tscn
+++ b/objects/tooltip.tscn
@@ -1,6 +1,6 @@
[gd_scene load_steps=5 format=3 uid="uid://b4pdt1gv2ymyi"]
-[ext_resource type="Script" path="res://scripts/components/tooltip_component.gd" id="1_kkpqq"]
+[ext_resource type="Script" uid="uid://bsq5pplxqbssh" path="res://scripts/components/tooltip_component.gd" id="1_kkpqq"]
[ext_resource type="Texture2D" uid="uid://djifxc5x0dyrw" path="res://sprites/ppc_tileset.png" id="1_yy7uq"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_hkd8b"]
diff --git a/objects/treasure.tscn b/objects/treasure.tscn
index d901864..0547b06 100644
--- a/objects/treasure.tscn
+++ b/objects/treasure.tscn
@@ -1,9 +1,9 @@
[gd_scene load_steps=7 format=3 uid="uid://073ts5cxtwbl"]
[ext_resource type="Texture2D" uid="uid://djifxc5x0dyrw" path="res://sprites/ppc_tileset.png" id="1_uh3ex"]
-[ext_resource type="Script" path="res://scripts/components/collectable.gd" id="2_i1ssp"]
+[ext_resource type="Script" uid="uid://pa1bwc4no08q" path="res://scripts/components/collectable.gd" id="2_i1ssp"]
[ext_resource type="Resource" uid="uid://bws2xldndlre1" path="res://resources/collectables/treasure.tres" id="3_uknsr"]
-[ext_resource type="Script" path="res://scripts/components/fade_away.gd" id="4_ccbcr"]
+[ext_resource type="Script" uid="uid://bg75hnr3q6grk" path="res://scripts/components/fade_away.gd" id="4_ccbcr"]
[ext_resource type="AudioStream" uid="uid://d2rj7uy5f0kwm" path="res://sfx/pickup_coin_3.wav" id="5_xt2rk"]
[sub_resource type="CircleShape2D" id="CircleShape2D_3ask2"]
diff --git a/project.godot b/project.godot
index 531814e..6b63678 100644
--- a/project.godot
+++ b/project.godot
@@ -17,7 +17,7 @@ config/name_localized={
}
config/version="in-dev"
run/main_scene="res://scenes/test.tscn"
-config/features=PackedStringArray("4.3", "GL Compatibility")
+config/features=PackedStringArray("4.4", "GL Compatibility")
run/max_fps=144
boot_splash/show_image=false
boot_splash/fullsize=false
@@ -31,10 +31,6 @@ PhantomCameraManager="*res://addons/phantom_camera/scripts/managers/phantom_came
GUIDE="*res://addons/guide/guide.gd"
AudioController="*res://objects/audio_controller.tscn"
-[debug]
-
-file_logging/enable_file_logging=true
-
[display]
window/size/viewport_width=640
diff --git a/resources/collectables/big_coin.tres b/resources/collectables/big_coin.tres
index e7549c4..e51329e 100644
--- a/resources/collectables/big_coin.tres
+++ b/resources/collectables/big_coin.tres
@@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="CollectableResource" load_steps=2 format=3 uid="uid://bsnr5v2b2mfsl"]
-[ext_resource type="Script" path="res://scripts/resources/collectable_resource.gd" id="1_fudbo"]
+[ext_resource type="Script" uid="uid://cb5f0mx0hrt3b" path="res://scripts/resources/collectable_resource.gd" id="1_fudbo"]
[resource]
script = ExtResource("1_fudbo")
diff --git a/resources/collectables/big_treasure.tres b/resources/collectables/big_treasure.tres
index a6f9604..abe6fa0 100644
--- a/resources/collectables/big_treasure.tres
+++ b/resources/collectables/big_treasure.tres
@@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="CollectableResource" load_steps=2 format=3 uid="uid://b6xqotmke54x"]
-[ext_resource type="Script" path="res://scripts/resources/collectable_resource.gd" id="1_037vi"]
+[ext_resource type="Script" uid="uid://cb5f0mx0hrt3b" path="res://scripts/resources/collectable_resource.gd" id="1_037vi"]
[resource]
script = ExtResource("1_037vi")
diff --git a/resources/collectables/child.tres b/resources/collectables/child.tres
index 3fe5be4..9dcb529 100644
--- a/resources/collectables/child.tres
+++ b/resources/collectables/child.tres
@@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="CollectableResource" load_steps=2 format=3 uid="uid://b6apusc0jmi3x"]
-[ext_resource type="Script" path="res://scripts/resources/collectable_resource.gd" id="1_2d5tb"]
+[ext_resource type="Script" uid="uid://cb5f0mx0hrt3b" path="res://scripts/resources/collectable_resource.gd" id="1_2d5tb"]
[resource]
script = ExtResource("1_2d5tb")
diff --git a/resources/collectables/coin.tres b/resources/collectables/coin.tres
index 01659ea..1d16f8b 100644
--- a/resources/collectables/coin.tres
+++ b/resources/collectables/coin.tres
@@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="CollectableResource" load_steps=2 format=3 uid="uid://vql535ckoeqm"]
-[ext_resource type="Script" path="res://scripts/resources/collectable_resource.gd" id="1_veemo"]
+[ext_resource type="Script" uid="uid://cb5f0mx0hrt3b" path="res://scripts/resources/collectable_resource.gd" id="1_veemo"]
[resource]
script = ExtResource("1_veemo")
diff --git a/resources/collectables/treasure.tres b/resources/collectables/treasure.tres
index c423854..15e44d0 100644
--- a/resources/collectables/treasure.tres
+++ b/resources/collectables/treasure.tres
@@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="CollectableResource" load_steps=2 format=3 uid="uid://bws2xldndlre1"]
-[ext_resource type="Script" path="res://scripts/resources/collectable_resource.gd" id="1_w50p5"]
+[ext_resource type="Script" uid="uid://cb5f0mx0hrt3b" path="res://scripts/resources/collectable_resource.gd" id="1_w50p5"]
[resource]
script = ExtResource("1_w50p5")
diff --git a/resources/input/move.tres b/resources/input/move.tres
index 2f4fc2e..7b5e0f8 100644
--- a/resources/input/move.tres
+++ b/resources/input/move.tres
@@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://c7h4sh2ilslsv"]
-[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_abssq"]
+[ext_resource type="Script" uid="uid://5yg21xllntrk" path="res://addons/guide/guide_action.gd" id="1_abssq"]
[resource]
script = ExtResource("1_abssq")
diff --git a/resources/input/walk_mode.tres b/resources/input/walk_mode.tres
index 15a6e2a..467a357 100644
--- a/resources/input/walk_mode.tres
+++ b/resources/input/walk_mode.tres
@@ -1,12 +1,12 @@
[gd_resource type="Resource" script_class="GUIDEMappingContext" load_steps=18 format=3 uid="uid://cb5pheu58dpqi"]
-[ext_resource type="Script" path="res://addons/guide/guide_action_mapping.gd" id="1_20ds1"]
-[ext_resource type="Script" path="res://addons/guide/guide_mapping_context.gd" id="2_tdx85"]
+[ext_resource type="Script" uid="uid://5huk51k6eqa8" path="res://addons/guide/guide_action_mapping.gd" id="1_20ds1"]
+[ext_resource type="Script" uid="uid://ddr05cbbemxru" path="res://addons/guide/guide_mapping_context.gd" id="2_tdx85"]
[ext_resource type="Resource" uid="uid://c7h4sh2ilslsv" path="res://resources/input/move.tres" id="2_wp2di"]
-[ext_resource type="Script" path="res://addons/guide/guide_input_mapping.gd" id="3_lq4l6"]
-[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_key.gd" id="4_rtw28"]
-[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier.gd" id="5_gbdho"]
-[ext_resource type="Script" path="res://addons/guide/triggers/guide_trigger.gd" id="6_3igdd"]
+[ext_resource type="Script" uid="uid://c5pstcepgwkmy" path="res://addons/guide/guide_input_mapping.gd" id="3_lq4l6"]
+[ext_resource type="Script" uid="uid://coygbn3kos0l6" path="res://addons/guide/inputs/guide_input_key.gd" id="4_rtw28"]
+[ext_resource type="Script" uid="uid://dokohnxlptadc" path="res://addons/guide/modifiers/guide_modifier.gd" id="5_gbdho"]
+[ext_resource type="Script" uid="uid://bf0t8choiiqnb" path="res://addons/guide/triggers/guide_trigger.gd" id="6_3igdd"]
[sub_resource type="Resource" id="Resource_10hm2"]
script = ExtResource("4_rtw28")
diff --git a/resources/skills/brick_throw.tres b/resources/skills/brick_throw.tres
index 7f0ac85..d99ccef 100644
--- a/resources/skills/brick_throw.tres
+++ b/resources/skills/brick_throw.tres
@@ -1,7 +1,7 @@
[gd_resource type="Resource" script_class="SkillData" load_steps=3 format=3 uid="uid://dw5ee2lpeypnb"]
[ext_resource type="PackedScene" uid="uid://coayig4dxelo2" path="res://objects/player_skills/brick_throw_skill.tscn" id="1_5gnea"]
-[ext_resource type="Script" path="res://scripts/resources/skill_data.gd" id="1_etxe2"]
+[ext_resource type="Script" uid="uid://bya240e627ti6" path="res://scripts/resources/skill_data.gd" id="1_etxe2"]
[resource]
script = ExtResource("1_etxe2")
diff --git a/resources/skills/explosive_brick.tres b/resources/skills/explosive_brick.tres
index 1bdba41..d04ba5d 100644
--- a/resources/skills/explosive_brick.tres
+++ b/resources/skills/explosive_brick.tres
@@ -2,7 +2,7 @@
[ext_resource type="PackedScene" uid="uid://5surx230gfw3" path="res://objects/exploding_brick.tscn" id="1_6pfoa"]
[ext_resource type="PackedScene" uid="uid://coayig4dxelo2" path="res://objects/player_skills/brick_throw_skill.tscn" id="2_e0o8w"]
-[ext_resource type="Script" path="res://scripts/resources/skill_data.gd" id="3_cgsq1"]
+[ext_resource type="Script" uid="uid://bya240e627ti6" path="res://scripts/resources/skill_data.gd" id="3_cgsq1"]
[resource]
script = ExtResource("3_cgsq1")
diff --git a/resources/skills/fire_brick.tres b/resources/skills/fire_brick.tres
index 68639d6..a883c87 100644
--- a/resources/skills/fire_brick.tres
+++ b/resources/skills/fire_brick.tres
@@ -1,7 +1,7 @@
[gd_resource type="Resource" script_class="SkillData" load_steps=4 format=3 uid="uid://2glvryih82t1"]
[ext_resource type="PackedScene" uid="uid://daau4j5hbklk0" path="res://objects/fire_brick.tscn" id="1_2g43l"]
-[ext_resource type="Script" path="res://scripts/resources/skill_data.gd" id="1_2j5ko"]
+[ext_resource type="Script" uid="uid://bya240e627ti6" path="res://scripts/resources/skill_data.gd" id="1_2j5ko"]
[ext_resource type="PackedScene" uid="uid://coayig4dxelo2" path="res://objects/player_skills/brick_throw_skill.tscn" id="1_g53fp"]
[resource]
diff --git a/resources/skills/ice_brick.tres b/resources/skills/ice_brick.tres
index 84bd9d6..0272f8d 100644
--- a/resources/skills/ice_brick.tres
+++ b/resources/skills/ice_brick.tres
@@ -2,7 +2,7 @@
[ext_resource type="PackedScene" uid="uid://bcmx07k12gcsc" path="res://objects/ice_brick.tscn" id="1_ci3d1"]
[ext_resource type="PackedScene" uid="uid://coayig4dxelo2" path="res://objects/player_skills/brick_throw_skill.tscn" id="1_rflri"]
-[ext_resource type="Script" path="res://scripts/resources/skill_data.gd" id="2_pspkt"]
+[ext_resource type="Script" uid="uid://bya240e627ti6" path="res://scripts/resources/skill_data.gd" id="2_pspkt"]
[resource]
script = ExtResource("2_pspkt")
diff --git a/resources/skills/magnetic.tres b/resources/skills/magnetic.tres
index cb58e75..2d47bf0 100644
--- a/resources/skills/magnetic.tres
+++ b/resources/skills/magnetic.tres
@@ -2,7 +2,7 @@
[ext_resource type="Texture2D" uid="uid://cvhoq7aubxlmq" path="res://sprites/ui/magnetic_skill_icon.png" id="1_16qcg"]
[ext_resource type="PackedScene" uid="uid://cunyndudjh2he" path="res://objects/player_skills/magnetic_skill.tscn" id="1_er41s"]
-[ext_resource type="Script" path="res://scripts/resources/skill_data.gd" id="1_r01oq"]
+[ext_resource type="Script" uid="uid://bya240e627ti6" path="res://scripts/resources/skill_data.gd" id="1_r01oq"]
[resource]
script = ExtResource("1_r01oq")
diff --git a/resources/status_effect/fire.tres b/resources/status_effect/fire.tres
index d659e24..ba8ce8a 100644
--- a/resources/status_effect/fire.tres
+++ b/resources/status_effect/fire.tres
@@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="StatusEffectDataResource" load_steps=2 format=3 uid="uid://obodgnkhxuhe"]
-[ext_resource type="Script" path="res://scripts/resources/status_effect_data_resource.gd" id="1_r8ycx"]
+[ext_resource type="Script" uid="uid://cqq2stnfs1doo" path="res://scripts/resources/status_effect_data_resource.gd" id="1_r8ycx"]
[resource]
script = ExtResource("1_r8ycx")
diff --git a/resources/status_effect/ice.tres b/resources/status_effect/ice.tres
index a1284be..8bb963e 100644
--- a/resources/status_effect/ice.tres
+++ b/resources/status_effect/ice.tres
@@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="StatusEffectDataResource" load_steps=2 format=3 uid="uid://02l4nbnf2aft"]
-[ext_resource type="Script" path="res://scripts/resources/status_effect_data_resource.gd" id="1_kqthd"]
+[ext_resource type="Script" uid="uid://cqq2stnfs1doo" path="res://scripts/resources/status_effect_data_resource.gd" id="1_kqthd"]
[resource]
script = ExtResource("1_kqthd")
diff --git a/scenes/test.tscn b/scenes/test.tscn
index 1ba7871..dc0eef9 100644
--- a/scenes/test.tscn
+++ b/scenes/test.tscn
@@ -11,15 +11,15 @@
[ext_resource type="PackedScene" uid="uid://ct8fim6mduyl3" path="res://objects/collapsing_bridge.tscn" id="6_84ckv"]
[ext_resource type="PackedScene" uid="uid://d08dfqmirnd66" path="res://objects/big_treasure.tscn" id="6_a3vrq"]
[ext_resource type="PackedScene" uid="uid://073ts5cxtwbl" path="res://objects/treasure.tscn" id="7_4mhb5"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="7_jgh7o"]
+[ext_resource type="Script" uid="uid://cie33tct7ehf0" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="7_jgh7o"]
[ext_resource type="PackedScene" uid="uid://bwdlmualj6xbw" path="res://objects/enemy.tscn" id="7_qgddg"]
[ext_resource type="PackedScene" uid="uid://cm3rixnnev1pg" path="res://objects/jump_pad.tscn" id="8_dt3jb"]
[ext_resource type="PackedScene" uid="uid://to2xnqev0pu1" path="res://objects/cage.tscn" id="9_oiafb"]
[ext_resource type="PackedScene" uid="uid://bd51frym6mm7v" path="res://objects/lever.tscn" id="10_gxrpi"]
[ext_resource type="Texture2D" uid="uid://cw42lvnqxubq2" path="res://sprites/PS_Tileset_10_nes.png" id="11_cyldw"]
[ext_resource type="Texture2D" uid="uid://dxvevrm15uus1" path="res://sprites/flowers_tileset.png" id="12_hk3do"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="13_rsy5s"]
-[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="14_mjvn7"]
+[ext_resource type="Script" uid="uid://d23haq52m7ulv" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="13_rsy5s"]
+[ext_resource type="Script" uid="uid://ccfft4b8rwgbo" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="14_mjvn7"]
[ext_resource type="PackedScene" uid="uid://dtjrpkhssq32a" path="res://objects/bg.tscn" id="14_ws5fk"]
[ext_resource type="PackedScene" uid="uid://bqom4cm7r18db" path="res://objects/killzone.tscn" id="20_8a4vc"]
[ext_resource type="PackedScene" uid="uid://dlm2ri562fynd" path="res://objects/marketplace.tscn" id="20_ss8k0"]
diff --git a/scripts/components/beam_component.gd.uid b/scripts/components/beam_component.gd.uid
new file mode 100644
index 0000000..da83346
--- /dev/null
+++ b/scripts/components/beam_component.gd.uid
@@ -0,0 +1 @@
+uid://bejv75mi8npj0
diff --git a/scripts/components/brick_throw.gd.uid b/scripts/components/brick_throw.gd.uid
new file mode 100644
index 0000000..0ea24ad
--- /dev/null
+++ b/scripts/components/brick_throw.gd.uid
@@ -0,0 +1 @@
+uid://cm06xg1l3xtw5
diff --git a/scripts/components/bullet.gd.uid b/scripts/components/bullet.gd.uid
new file mode 100644
index 0000000..824c57e
--- /dev/null
+++ b/scripts/components/bullet.gd.uid
@@ -0,0 +1 @@
+uid://bh2vrkdbrtpin
diff --git a/scripts/components/cage_component.gd.uid b/scripts/components/cage_component.gd.uid
new file mode 100644
index 0000000..a82f5d9
--- /dev/null
+++ b/scripts/components/cage_component.gd.uid
@@ -0,0 +1 @@
+uid://ddplvyjqguxtl
diff --git a/scripts/components/can_be_launched_component.gd.uid b/scripts/components/can_be_launched_component.gd.uid
new file mode 100644
index 0000000..6db28a6
--- /dev/null
+++ b/scripts/components/can_be_launched_component.gd.uid
@@ -0,0 +1 @@
+uid://6ffxsx3gknhr
diff --git a/scripts/components/can_pickup.gd.uid b/scripts/components/can_pickup.gd.uid
new file mode 100644
index 0000000..63c7228
--- /dev/null
+++ b/scripts/components/can_pickup.gd.uid
@@ -0,0 +1 @@
+uid://dcvjvjy2nhf8s
diff --git a/scripts/components/cannot_stomp_component.gd.uid b/scripts/components/cannot_stomp_component.gd.uid
new file mode 100644
index 0000000..730f9e4
--- /dev/null
+++ b/scripts/components/cannot_stomp_component.gd.uid
@@ -0,0 +1 @@
+uid://ct7lsuwjvmwxu
diff --git a/scripts/components/cleanup_component.gd.uid b/scripts/components/cleanup_component.gd.uid
new file mode 100644
index 0000000..dae9724
--- /dev/null
+++ b/scripts/components/cleanup_component.gd.uid
@@ -0,0 +1 @@
+uid://f74xpfg7624d
diff --git a/scripts/components/collapsable.gd.uid b/scripts/components/collapsable.gd.uid
new file mode 100644
index 0000000..1ce1c00
--- /dev/null
+++ b/scripts/components/collapsable.gd.uid
@@ -0,0 +1 @@
+uid://r0a6xjicrh74
diff --git a/scripts/components/collectable.gd.uid b/scripts/components/collectable.gd.uid
new file mode 100644
index 0000000..6ce4f73
--- /dev/null
+++ b/scripts/components/collectable.gd.uid
@@ -0,0 +1 @@
+uid://pa1bwc4no08q
diff --git a/scripts/components/damage_component.gd.uid b/scripts/components/damage_component.gd.uid
new file mode 100644
index 0000000..c1a208c
--- /dev/null
+++ b/scripts/components/damage_component.gd.uid
@@ -0,0 +1 @@
+uid://dkmxhjtmu5xlb
diff --git a/scripts/components/destroyable_component.gd.uid b/scripts/components/destroyable_component.gd.uid
new file mode 100644
index 0000000..7258442
--- /dev/null
+++ b/scripts/components/destroyable_component.gd.uid
@@ -0,0 +1 @@
+uid://d01dmoafptl2p
diff --git a/scripts/components/effect_inflictor_component.gd.uid b/scripts/components/effect_inflictor_component.gd.uid
new file mode 100644
index 0000000..463982b
--- /dev/null
+++ b/scripts/components/effect_inflictor_component.gd.uid
@@ -0,0 +1 @@
+uid://d3brcje121krs
diff --git a/scripts/components/enemy_death.gd.uid b/scripts/components/enemy_death.gd.uid
new file mode 100644
index 0000000..ec5a612
--- /dev/null
+++ b/scripts/components/enemy_death.gd.uid
@@ -0,0 +1 @@
+uid://dqm371fysuk7i
diff --git a/scripts/components/explosive_component.gd.uid b/scripts/components/explosive_component.gd.uid
new file mode 100644
index 0000000..8b7fd0a
--- /dev/null
+++ b/scripts/components/explosive_component.gd.uid
@@ -0,0 +1 @@
+uid://beg4dk7d5pvhp
diff --git a/scripts/components/fade_away.gd.uid b/scripts/components/fade_away.gd.uid
new file mode 100644
index 0000000..501bf25
--- /dev/null
+++ b/scripts/components/fade_away.gd.uid
@@ -0,0 +1 @@
+uid://bg75hnr3q6grk
diff --git a/scripts/components/fire_effect_component.gd.uid b/scripts/components/fire_effect_component.gd.uid
new file mode 100644
index 0000000..25e50ec
--- /dev/null
+++ b/scripts/components/fire_effect_component.gd.uid
@@ -0,0 +1 @@
+uid://qi2irprbqru2
diff --git a/scripts/components/flashing_component.gd.uid b/scripts/components/flashing_component.gd.uid
new file mode 100644
index 0000000..5875465
--- /dev/null
+++ b/scripts/components/flashing_component.gd.uid
@@ -0,0 +1 @@
+uid://dqmbvuutd5c3c
diff --git a/scripts/components/flip_player.gd.uid b/scripts/components/flip_player.gd.uid
new file mode 100644
index 0000000..d81faa3
--- /dev/null
+++ b/scripts/components/flip_player.gd.uid
@@ -0,0 +1 @@
+uid://oxeqvxkgj87j
diff --git a/scripts/components/health.gd.uid b/scripts/components/health.gd.uid
new file mode 100644
index 0000000..eb93c41
--- /dev/null
+++ b/scripts/components/health.gd.uid
@@ -0,0 +1 @@
+uid://btfsq0bvtrx3t
diff --git a/scripts/components/hit_component.gd.uid b/scripts/components/hit_component.gd.uid
new file mode 100644
index 0000000..f78e883
--- /dev/null
+++ b/scripts/components/hit_component.gd.uid
@@ -0,0 +1 @@
+uid://ceq8n7yw7qxpi
diff --git a/scripts/components/ice_effect_component.gd.uid b/scripts/components/ice_effect_component.gd.uid
new file mode 100644
index 0000000..38ba092
--- /dev/null
+++ b/scripts/components/ice_effect_component.gd.uid
@@ -0,0 +1 @@
+uid://dhj4qtwcqmqkj
diff --git a/scripts/components/invulnerability_component.gd.uid b/scripts/components/invulnerability_component.gd.uid
new file mode 100644
index 0000000..51a9343
--- /dev/null
+++ b/scripts/components/invulnerability_component.gd.uid
@@ -0,0 +1 @@
+uid://ijrli0x8ij8v
diff --git a/scripts/components/jump_pad_component.gd.uid b/scripts/components/jump_pad_component.gd.uid
new file mode 100644
index 0000000..3a14c81
--- /dev/null
+++ b/scripts/components/jump_pad_component.gd.uid
@@ -0,0 +1 @@
+uid://dwok2qx4wpkey
diff --git a/scripts/components/knockback.gd.uid b/scripts/components/knockback.gd.uid
new file mode 100644
index 0000000..23683ae
--- /dev/null
+++ b/scripts/components/knockback.gd.uid
@@ -0,0 +1 @@
+uid://nogmyshjrv57
diff --git a/scripts/components/lever_component.gd.uid b/scripts/components/lever_component.gd.uid
new file mode 100644
index 0000000..0d5a733
--- /dev/null
+++ b/scripts/components/lever_component.gd.uid
@@ -0,0 +1 @@
+uid://hyuwsp1b336a
diff --git a/scripts/components/magnetic_skill.gd.uid b/scripts/components/magnetic_skill.gd.uid
new file mode 100644
index 0000000..2832e58
--- /dev/null
+++ b/scripts/components/magnetic_skill.gd.uid
@@ -0,0 +1 @@
+uid://ce8w71vgv37pt
diff --git a/scripts/components/periodic_shooting.gd.uid b/scripts/components/periodic_shooting.gd.uid
new file mode 100644
index 0000000..9560a8a
--- /dev/null
+++ b/scripts/components/periodic_shooting.gd.uid
@@ -0,0 +1 @@
+uid://b37gqnycj6rtk
diff --git a/scripts/components/player_death.gd.uid b/scripts/components/player_death.gd.uid
new file mode 100644
index 0000000..0425315
--- /dev/null
+++ b/scripts/components/player_death.gd.uid
@@ -0,0 +1 @@
+uid://dkpu3121y88oo
diff --git a/scripts/components/score.gd.uid b/scripts/components/score.gd.uid
new file mode 100644
index 0000000..423413f
--- /dev/null
+++ b/scripts/components/score.gd.uid
@@ -0,0 +1 @@
+uid://qeu80jy4vmuf
diff --git a/scripts/components/side_to_side_movement.gd.uid b/scripts/components/side_to_side_movement.gd.uid
new file mode 100644
index 0000000..a653dab
--- /dev/null
+++ b/scripts/components/side_to_side_movement.gd.uid
@@ -0,0 +1 @@
+uid://dmqpif5qhvri3
diff --git a/scripts/components/skill_unlocker_component.gd.uid b/scripts/components/skill_unlocker_component.gd.uid
new file mode 100644
index 0000000..1aa9e46
--- /dev/null
+++ b/scripts/components/skill_unlocker_component.gd.uid
@@ -0,0 +1 @@
+uid://bjsyeo1n7bsri
diff --git a/scripts/components/status_effect_component.gd.uid b/scripts/components/status_effect_component.gd.uid
new file mode 100644
index 0000000..efbeec9
--- /dev/null
+++ b/scripts/components/status_effect_component.gd.uid
@@ -0,0 +1 @@
+uid://c07d50s20rl8s
diff --git a/scripts/components/stomp_damage_component.gd.uid b/scripts/components/stomp_damage_component.gd.uid
new file mode 100644
index 0000000..8557532
--- /dev/null
+++ b/scripts/components/stomp_damage_component.gd.uid
@@ -0,0 +1 @@
+uid://ulhswh4jjlc6
diff --git a/scripts/components/tooltip_component.gd.uid b/scripts/components/tooltip_component.gd.uid
new file mode 100644
index 0000000..fece85c
--- /dev/null
+++ b/scripts/components/tooltip_component.gd.uid
@@ -0,0 +1 @@
+uid://bsq5pplxqbssh
diff --git a/scripts/components/trigger_lever_component.gd.uid b/scripts/components/trigger_lever_component.gd.uid
new file mode 100644
index 0000000..95ad8b8
--- /dev/null
+++ b/scripts/components/trigger_lever_component.gd.uid
@@ -0,0 +1 @@
+uid://bpy6xtfm8l3hy
diff --git a/scripts/game_manager.gd.uid b/scripts/game_manager.gd.uid
new file mode 100644
index 0000000..013ca68
--- /dev/null
+++ b/scripts/game_manager.gd.uid
@@ -0,0 +1 @@
+uid://dd30bgqiagi25
diff --git a/scripts/hud.gd.uid b/scripts/hud.gd.uid
new file mode 100644
index 0000000..c710616
--- /dev/null
+++ b/scripts/hud.gd.uid
@@ -0,0 +1 @@
+uid://c3pde84b3kdco
diff --git a/scripts/marketplace.gd.uid b/scripts/marketplace.gd.uid
new file mode 100644
index 0000000..594cb5f
--- /dev/null
+++ b/scripts/marketplace.gd.uid
@@ -0,0 +1 @@
+uid://duifmqjarjpuv
diff --git a/scripts/player.gd.uid b/scripts/player.gd.uid
new file mode 100644
index 0000000..b0e8a29
--- /dev/null
+++ b/scripts/player.gd.uid
@@ -0,0 +1 @@
+uid://ccuddyoakg04u
diff --git a/scripts/resources/collectable_resource.gd.uid b/scripts/resources/collectable_resource.gd.uid
new file mode 100644
index 0000000..01a4825
--- /dev/null
+++ b/scripts/resources/collectable_resource.gd.uid
@@ -0,0 +1 @@
+uid://cb5f0mx0hrt3b
diff --git a/scripts/resources/skill_data.gd.uid b/scripts/resources/skill_data.gd.uid
new file mode 100644
index 0000000..58a05be
--- /dev/null
+++ b/scripts/resources/skill_data.gd.uid
@@ -0,0 +1 @@
+uid://bya240e627ti6
diff --git a/scripts/resources/status_effect_data_resource.gd.uid b/scripts/resources/status_effect_data_resource.gd.uid
new file mode 100644
index 0000000..37fbeb3
--- /dev/null
+++ b/scripts/resources/status_effect_data_resource.gd.uid
@@ -0,0 +1 @@
+uid://cqq2stnfs1doo
diff --git a/scripts/save_system.gd.uid b/scripts/save_system.gd.uid
new file mode 100644
index 0000000..394c1f9
--- /dev/null
+++ b/scripts/save_system.gd.uid
@@ -0,0 +1 @@
+uid://d3tgf7fyr6xek
diff --git a/scripts/skill_manager.gd.uid b/scripts/skill_manager.gd.uid
new file mode 100644
index 0000000..83ee3c4
--- /dev/null
+++ b/scripts/skill_manager.gd.uid
@@ -0,0 +1 @@
+uid://cjqe428jwip6b
diff --git a/scripts/steam_integration.gd.uid b/scripts/steam_integration.gd.uid
new file mode 100644
index 0000000..34543de
--- /dev/null
+++ b/scripts/steam_integration.gd.uid
@@ -0,0 +1 @@
+uid://f4y8evisxgnc
diff --git a/shaders/shine_shader.gdshader.uid b/shaders/shine_shader.gdshader.uid
new file mode 100644
index 0000000..dce5b65
--- /dev/null
+++ b/shaders/shine_shader.gdshader.uid
@@ -0,0 +1 @@
+uid://ykn0lvcpdkp6
diff --git a/shaders/shine_shader.tres b/shaders/shine_shader.tres
index 243f80b..3bdb8e2 100644
--- a/shaders/shine_shader.tres
+++ b/shaders/shine_shader.tres
@@ -1,6 +1,6 @@
[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://d1m2qrclercr"]
-[ext_resource type="Shader" path="res://shaders/shine_shader.gdshader" id="1_a47lf"]
+[ext_resource type="Shader" uid="uid://ykn0lvcpdkp6" path="res://shaders/shine_shader.gdshader" id="1_a47lf"]
[resource]
shader = ExtResource("1_a47lf")