diff --git a/.gitignore b/.gitignore
index 25b7d25b..54ac63b5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,3 +13,4 @@
*.DotSettings.user
export_presets.cfg
*.translation
+addons/godotsteam/win64/~libgodotsteam.windows.template_debug.x86_64.dll
diff --git a/Audio/CyberFoxSong.ogg b/Audio/CyberFoxSong.ogg
new file mode 100644
index 00000000..4b8b36e2
Binary files /dev/null and b/Audio/CyberFoxSong.ogg differ
diff --git a/Audio/CyberFoxSong.ogg.import b/Audio/CyberFoxSong.ogg.import
new file mode 100644
index 00000000..3b6a89c0
--- /dev/null
+++ b/Audio/CyberFoxSong.ogg.import
@@ -0,0 +1,19 @@
+[remap]
+
+importer="oggvorbisstr"
+type="AudioStreamOggVorbis"
+uid="uid://cth4pjufelmd6"
+path="res://.godot/imported/CyberFoxSong.ogg-b284af6a3d3aac22904e516894dd5aae.oggvorbisstr"
+
+[deps]
+
+source_file="res://Audio/CyberFoxSong.ogg"
+dest_files=["res://.godot/imported/CyberFoxSong.ogg-b284af6a3d3aac22904e516894dd5aae.oggvorbisstr"]
+
+[params]
+
+loop=true
+loop_offset=0.0
+bpm=0.0
+beat_count=0
+bar_beats=4
diff --git a/Audio/District_Four.ogg b/Audio/District_Four.ogg
new file mode 100644
index 00000000..d6cba76b
Binary files /dev/null and b/Audio/District_Four.ogg differ
diff --git a/Audio/District_Four.ogg.import b/Audio/District_Four.ogg.import
new file mode 100644
index 00000000..a603eea4
--- /dev/null
+++ b/Audio/District_Four.ogg.import
@@ -0,0 +1,19 @@
+[remap]
+
+importer="oggvorbisstr"
+type="AudioStreamOggVorbis"
+uid="uid://bffy1ysxfrte6"
+path="res://.godot/imported/District_Four.ogg-f8fbac641cef73b68aacab4d4b38fbd8.oggvorbisstr"
+
+[deps]
+
+source_file="res://Audio/District_Four.ogg"
+dest_files=["res://.godot/imported/District_Four.ogg-f8fbac641cef73b68aacab4d4b38fbd8.oggvorbisstr"]
+
+[params]
+
+loop=false
+loop_offset=0
+bpm=0
+beat_count=0
+bar_beats=4
diff --git a/Audio/EcholaneSong.ogg b/Audio/EcholaneSong.ogg
new file mode 100644
index 00000000..5b1d5fc1
Binary files /dev/null and b/Audio/EcholaneSong.ogg differ
diff --git a/Audio/EcholaneSong.ogg.import b/Audio/EcholaneSong.ogg.import
new file mode 100644
index 00000000..b73069a4
--- /dev/null
+++ b/Audio/EcholaneSong.ogg.import
@@ -0,0 +1,19 @@
+[remap]
+
+importer="oggvorbisstr"
+type="AudioStreamOggVorbis"
+uid="uid://cotvgtk627cp6"
+path="res://.godot/imported/EcholaneSong.ogg-98376f334d8ef68ec1401c46cae3d881.oggvorbisstr"
+
+[deps]
+
+source_file="res://Audio/EcholaneSong.ogg"
+dest_files=["res://.godot/imported/EcholaneSong.ogg-98376f334d8ef68ec1401c46cae3d881.oggvorbisstr"]
+
+[params]
+
+loop=true
+loop_offset=0.0
+bpm=0.0
+beat_count=0
+bar_beats=4
diff --git a/Audio/FrostWaltz.ogg b/Audio/FrostWaltz.ogg
new file mode 100644
index 00000000..2e4a65b4
Binary files /dev/null and b/Audio/FrostWaltz.ogg differ
diff --git a/Audio/FrostWaltz.ogg.import b/Audio/FrostWaltz.ogg.import
new file mode 100644
index 00000000..fac077e0
--- /dev/null
+++ b/Audio/FrostWaltz.ogg.import
@@ -0,0 +1,19 @@
+[remap]
+
+importer="oggvorbisstr"
+type="AudioStreamOggVorbis"
+uid="uid://cqqek08at2dln"
+path="res://.godot/imported/FrostWaltz.ogg-ac1d837e419d8005c75f8f58778c7de5.oggvorbisstr"
+
+[deps]
+
+source_file="res://Audio/FrostWaltz.ogg"
+dest_files=["res://.godot/imported/FrostWaltz.ogg-ac1d837e419d8005c75f8f58778c7de5.oggvorbisstr"]
+
+[params]
+
+loop=true
+loop_offset=0.0
+bpm=0.0
+beat_count=0
+bar_beats=4
diff --git a/Audio/Gobbler.ogg b/Audio/Gobbler.ogg
new file mode 100644
index 00000000..a239a7a2
Binary files /dev/null and b/Audio/Gobbler.ogg differ
diff --git a/Audio/Gobbler.ogg.import b/Audio/Gobbler.ogg.import
new file mode 100644
index 00000000..bdaca816
--- /dev/null
+++ b/Audio/Gobbler.ogg.import
@@ -0,0 +1,19 @@
+[remap]
+
+importer="oggvorbisstr"
+type="AudioStreamOggVorbis"
+uid="uid://dy1hwvtaqkkq3"
+path="res://.godot/imported/Gobbler.ogg-03b09f5b2bf0ffd7ccfd23009bd2f39b.oggvorbisstr"
+
+[deps]
+
+source_file="res://Audio/Gobbler.ogg"
+dest_files=["res://.godot/imported/Gobbler.ogg-03b09f5b2bf0ffd7ccfd23009bd2f39b.oggvorbisstr"]
+
+[params]
+
+loop=true
+loop_offset=0.0
+bpm=0.0
+beat_count=0
+bar_beats=4
diff --git a/Audio/Holo_ThereItIs.ogg b/Audio/Holo_ThereItIs.ogg
new file mode 100644
index 00000000..55bb2b84
Binary files /dev/null and b/Audio/Holo_ThereItIs.ogg differ
diff --git a/Audio/Holo_ThereItIs.ogg.import b/Audio/Holo_ThereItIs.ogg.import
new file mode 100644
index 00000000..42d0ecd7
--- /dev/null
+++ b/Audio/Holo_ThereItIs.ogg.import
@@ -0,0 +1,19 @@
+[remap]
+
+importer="oggvorbisstr"
+type="AudioStreamOggVorbis"
+uid="uid://bh13g4kvv2ouu"
+path="res://.godot/imported/Holo_ThereItIs.ogg-9a4ef5e03ac86b17b0162d2b30577004.oggvorbisstr"
+
+[deps]
+
+source_file="res://Audio/Holo_ThereItIs.ogg"
+dest_files=["res://.godot/imported/Holo_ThereItIs.ogg-9a4ef5e03ac86b17b0162d2b30577004.oggvorbisstr"]
+
+[params]
+
+loop=true
+loop_offset=0.0
+bpm=0.0
+beat_count=0
+bar_beats=4
diff --git a/Audio/KeythuluSong.ogg b/Audio/KeythuluSong.ogg
new file mode 100644
index 00000000..5b8a7a8e
Binary files /dev/null and b/Audio/KeythuluSong.ogg differ
diff --git a/Audio/KeythuluSong.ogg.import b/Audio/KeythuluSong.ogg.import
new file mode 100644
index 00000000..235d60d4
--- /dev/null
+++ b/Audio/KeythuluSong.ogg.import
@@ -0,0 +1,19 @@
+[remap]
+
+importer="oggvorbisstr"
+type="AudioStreamOggVorbis"
+uid="uid://dsb5qtnub2hb5"
+path="res://.godot/imported/KeythuluSong.ogg-c74318e887a116e4b45c0227012de733.oggvorbisstr"
+
+[deps]
+
+source_file="res://Audio/KeythuluSong.ogg"
+dest_files=["res://.godot/imported/KeythuluSong.ogg-c74318e887a116e4b45c0227012de733.oggvorbisstr"]
+
+[params]
+
+loop=true
+loop_offset=0.0
+bpm=0.0
+beat_count=0
+bar_beats=4
diff --git a/Audio/Mushroom.ogg b/Audio/Mushroom.ogg
new file mode 100644
index 00000000..3e48c166
Binary files /dev/null and b/Audio/Mushroom.ogg differ
diff --git a/Audio/Mushroom.ogg.import b/Audio/Mushroom.ogg.import
new file mode 100644
index 00000000..70ac3b14
--- /dev/null
+++ b/Audio/Mushroom.ogg.import
@@ -0,0 +1,19 @@
+[remap]
+
+importer="oggvorbisstr"
+type="AudioStreamOggVorbis"
+uid="uid://ccsdu3vec8qnm"
+path="res://.godot/imported/Mushroom.ogg-2e906fe7afb72b7bb85b71f5dd19ef51.oggvorbisstr"
+
+[deps]
+
+source_file="res://Audio/Mushroom.ogg"
+dest_files=["res://.godot/imported/Mushroom.ogg-2e906fe7afb72b7bb85b71f5dd19ef51.oggvorbisstr"]
+
+[params]
+
+loop=true
+loop_offset=0.0
+bpm=0.0
+beat_count=0
+bar_beats=4
diff --git a/Audio/Shapes.ogg b/Audio/Shapes.ogg
new file mode 100644
index 00000000..8d6054cd
Binary files /dev/null and b/Audio/Shapes.ogg differ
diff --git a/Audio/Shapes.ogg.import b/Audio/Shapes.ogg.import
new file mode 100644
index 00000000..4bda40c2
--- /dev/null
+++ b/Audio/Shapes.ogg.import
@@ -0,0 +1,19 @@
+[remap]
+
+importer="oggvorbisstr"
+type="AudioStreamOggVorbis"
+uid="uid://dfw74cqw22wbw"
+path="res://.godot/imported/Shapes.ogg-b889800a7203ea0955a099c677ed4dac.oggvorbisstr"
+
+[deps]
+
+source_file="res://Audio/Shapes.ogg"
+dest_files=["res://.godot/imported/Shapes.ogg-b889800a7203ea0955a099c677ed4dac.oggvorbisstr"]
+
+[params]
+
+loop=true
+loop_offset=0.0
+bpm=0.0
+beat_count=0
+bar_beats=4
diff --git a/Audio/Song2.ogg b/Audio/Song2.ogg
index 2301351a..05e34ea4 100644
Binary files a/Audio/Song2.ogg and b/Audio/Song2.ogg differ
diff --git a/Audio/Song2.ogg.import b/Audio/Song2.ogg.import
index 650cf1ff..78fc707e 100644
--- a/Audio/Song2.ogg.import
+++ b/Audio/Song2.ogg.import
@@ -2,7 +2,7 @@
importer="oggvorbisstr"
type="AudioStreamOggVorbis"
-uid="uid://dxp7blovqh1ba"
+uid="uid://bv7lgo2e8wu2j"
path="res://.godot/imported/Song2.ogg-b95c04f3512de6fa42e0f9c35aba831f.oggvorbisstr"
[deps]
diff --git a/Audio/Spider.ogg b/Audio/Spider.ogg
new file mode 100644
index 00000000..8149d9ee
Binary files /dev/null and b/Audio/Spider.ogg differ
diff --git a/Audio/Spider.ogg.import b/Audio/Spider.ogg.import
new file mode 100644
index 00000000..64dddba4
--- /dev/null
+++ b/Audio/Spider.ogg.import
@@ -0,0 +1,19 @@
+[remap]
+
+importer="oggvorbisstr"
+type="AudioStreamOggVorbis"
+uid="uid://dw5w7swc7f3wm"
+path="res://.godot/imported/Spider.ogg-38620b0d976e425d22012e6c4fbbe76d.oggvorbisstr"
+
+[deps]
+
+source_file="res://Audio/Spider.ogg"
+dest_files=["res://.godot/imported/Spider.ogg-38620b0d976e425d22012e6c4fbbe76d.oggvorbisstr"]
+
+[params]
+
+loop=true
+loop_offset=0.0
+bpm=0.0
+beat_count=0
+bar_beats=4
diff --git a/Audio/SquirkelSong.ogg b/Audio/SquirkelSong.ogg
new file mode 100644
index 00000000..ed5a3d1f
Binary files /dev/null and b/Audio/SquirkelSong.ogg differ
diff --git a/Audio/SquirkelSong.ogg.import b/Audio/SquirkelSong.ogg.import
new file mode 100644
index 00000000..6baf4812
--- /dev/null
+++ b/Audio/SquirkelSong.ogg.import
@@ -0,0 +1,19 @@
+[remap]
+
+importer="oggvorbisstr"
+type="AudioStreamOggVorbis"
+uid="uid://p56exjkpdsj6"
+path="res://.godot/imported/SquirkelSong.ogg-63e52521d8bfbd38d4a31f84e995c7b1.oggvorbisstr"
+
+[deps]
+
+source_file="res://Audio/SquirkelSong.ogg"
+dest_files=["res://.godot/imported/SquirkelSong.ogg-63e52521d8bfbd38d4a31f84e995c7b1.oggvorbisstr"]
+
+[params]
+
+loop=true
+loop_offset=0.0
+bpm=0.0
+beat_count=0
+bar_beats=4
diff --git a/Audio/TutorialSong.ogg b/Audio/TutorialSong.ogg
new file mode 100644
index 00000000..f872fab5
Binary files /dev/null and b/Audio/TutorialSong.ogg differ
diff --git a/Audio/TutorialSong.ogg.import b/Audio/TutorialSong.ogg.import
new file mode 100644
index 00000000..a031031e
--- /dev/null
+++ b/Audio/TutorialSong.ogg.import
@@ -0,0 +1,19 @@
+[remap]
+
+importer="oggvorbisstr"
+type="AudioStreamOggVorbis"
+uid="uid://cr3ehxww3eg5o"
+path="res://.godot/imported/TutorialSong.ogg-00527cc92390b837058f07c9a386e555.oggvorbisstr"
+
+[deps]
+
+source_file="res://Audio/TutorialSong.ogg"
+dest_files=["res://.godot/imported/TutorialSong.ogg-00527cc92390b837058f07c9a386e555.oggvorbisstr"]
+
+[params]
+
+loop=true
+loop_offset=0.0
+bpm=0.0
+beat_count=0
+bar_beats=4
diff --git a/Audio/songMaps/CyberFoxSong.tres b/Audio/songMaps/CyberFoxSong.tres
new file mode 100644
index 00000000..27df1cea
--- /dev/null
+++ b/Audio/songMaps/CyberFoxSong.tres
@@ -0,0 +1,121 @@
+[gd_resource type="Resource" load_steps=25 format=3]
+
+[ext_resource type="Script" path="res://Classes/MidiMaestro/NoteInfo.cs" id="1_8ueh4"]
+[ext_resource type="Script" path="res://Classes/MidiMaestro/NoteChart.cs" id="2_s63u8"]
+
+[sub_resource type="Resource" id="Resource_ljr32"]
+script = ExtResource("1_8ueh4")
+Beat = 2.0
+Length = 9.0
+
+[sub_resource type="Resource" id="Resource_bb3yp"]
+script = ExtResource("1_8ueh4")
+Beat = 14.0
+Length = 9.0
+
+[sub_resource type="Resource" id="Resource_852ml"]
+script = ExtResource("1_8ueh4")
+Beat = 30.0
+Length = 9.0
+
+[sub_resource type="Resource" id="Resource_38nu8"]
+script = ExtResource("1_8ueh4")
+Beat = 55.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_ct6sp"]
+script = ExtResource("1_8ueh4")
+Beat = 78.0
+Length = 9.0
+
+[sub_resource type="Resource" id="Resource_8ueh4"]
+script = ExtResource("1_8ueh4")
+Beat = 62.0
+Length = 9.0
+
+[sub_resource type="Resource" id="Resource_7lpnw"]
+script = ExtResource("1_8ueh4")
+Beat = 94.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_yk705"]
+script = ExtResource("1_8ueh4")
+Beat = 14.0
+Length = 9.0
+
+[sub_resource type="Resource" id="Resource_oocdv"]
+script = ExtResource("1_8ueh4")
+Beat = 30.0
+Length = 9.0
+
+[sub_resource type="Resource" id="Resource_uswjw"]
+script = ExtResource("1_8ueh4")
+Beat = 46.0
+Length = 9.0
+
+[sub_resource type="Resource" id="Resource_e1hbr"]
+script = ExtResource("1_8ueh4")
+Beat = 78.0
+Length = 9.0
+
+[sub_resource type="Resource" id="Resource_gryrv"]
+script = ExtResource("1_8ueh4")
+Beat = 2.0
+Length = 9.0
+
+[sub_resource type="Resource" id="Resource_kwtfb"]
+script = ExtResource("1_8ueh4")
+Beat = 30.0
+Length = 9.0
+
+[sub_resource type="Resource" id="Resource_c2bxv"]
+script = ExtResource("1_8ueh4")
+Beat = 46.0
+Length = 9.0
+
+[sub_resource type="Resource" id="Resource_s63u8"]
+script = ExtResource("1_8ueh4")
+Beat = 62.0
+Length = 9.0
+
+[sub_resource type="Resource" id="Resource_lrc4j"]
+script = ExtResource("1_8ueh4")
+Beat = 94.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_50tbs"]
+script = ExtResource("1_8ueh4")
+Beat = 2.0
+Length = 9.0
+
+[sub_resource type="Resource" id="Resource_ttd2q"]
+script = ExtResource("1_8ueh4")
+Beat = 14.0
+Length = 9.0
+
+[sub_resource type="Resource" id="Resource_nnlde"]
+script = ExtResource("1_8ueh4")
+Beat = 46.0
+Length = 9.0
+
+[sub_resource type="Resource" id="Resource_rwedv"]
+script = ExtResource("1_8ueh4")
+Beat = 78.0
+Length = 9.0
+
+[sub_resource type="Resource" id="Resource_3eydr"]
+script = ExtResource("1_8ueh4")
+Beat = 62.0
+Length = 9.0
+
+[sub_resource type="Resource" id="Resource_83big"]
+script = ExtResource("1_8ueh4")
+Beat = 94.0
+Length = 0.0
+
+[resource]
+script = ExtResource("2_s63u8")
+UpLaneData = Array[ExtResource("1_8ueh4")]([SubResource("Resource_50tbs"), SubResource("Resource_ttd2q"), SubResource("Resource_nnlde"), SubResource("Resource_rwedv"), SubResource("Resource_3eydr"), SubResource("Resource_83big")])
+DownLaneData = Array[ExtResource("1_8ueh4")]([SubResource("Resource_ljr32"), SubResource("Resource_bb3yp"), SubResource("Resource_852ml"), SubResource("Resource_38nu8"), SubResource("Resource_ct6sp"), SubResource("Resource_8ueh4"), SubResource("Resource_7lpnw")])
+LeftLaneData = Array[ExtResource("1_8ueh4")]([SubResource("Resource_yk705"), SubResource("Resource_oocdv"), SubResource("Resource_uswjw"), SubResource("Resource_e1hbr")])
+RightLaneData = Array[ExtResource("1_8ueh4")]([SubResource("Resource_gryrv"), SubResource("Resource_kwtfb"), SubResource("Resource_c2bxv"), SubResource("Resource_s63u8"), SubResource("Resource_lrc4j")])
diff --git a/Audio/songMaps/EcholaneSong.tres b/Audio/songMaps/EcholaneSong.tres
new file mode 100644
index 00000000..3713f118
--- /dev/null
+++ b/Audio/songMaps/EcholaneSong.tres
@@ -0,0 +1,226 @@
+[gd_resource type="Resource" load_steps=46 format=3]
+
+[ext_resource type="Script" path="res://Classes/MidiMaestro/NoteInfo.cs" id="1_vkj58"]
+[ext_resource type="Script" path="res://Classes/MidiMaestro/NoteChart.cs" id="2_ulihw"]
+
+[sub_resource type="Resource" id="Resource_vkj58"]
+script = ExtResource("1_vkj58")
+Beat = 3.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_ulihw"]
+script = ExtResource("1_vkj58")
+Beat = 6.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_t8863"]
+script = ExtResource("1_vkj58")
+Beat = 10.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_6g1by"]
+script = ExtResource("1_vkj58")
+Beat = 12.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_m02wy"]
+script = ExtResource("1_vkj58")
+Beat = 14.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_t1nlw"]
+script = ExtResource("1_vkj58")
+Beat = 18.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_iknre"]
+script = ExtResource("1_vkj58")
+Beat = 20.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_icwn4"]
+script = ExtResource("1_vkj58")
+Beat = 23.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_vkj1q"]
+script = ExtResource("1_vkj58")
+Beat = 26.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_g5inb"]
+script = ExtResource("1_vkj58")
+Beat = 29.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_7jmhk"]
+script = ExtResource("1_vkj58")
+Beat = 5.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_plxvd"]
+script = ExtResource("1_vkj58")
+Beat = 11.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_jva8p"]
+script = ExtResource("1_vkj58")
+Beat = 13.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_pref2"]
+script = ExtResource("1_vkj58")
+Beat = 16.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_3tvlw"]
+script = ExtResource("1_vkj58")
+Beat = 18.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_iq4by"]
+script = ExtResource("1_vkj58")
+Beat = 22.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_rekwa"]
+script = ExtResource("1_vkj58")
+Beat = 25.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_xbnbk"]
+script = ExtResource("1_vkj58")
+Beat = 28.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_byp8i"]
+script = ExtResource("1_vkj58")
+Beat = 29.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_dime5"]
+script = ExtResource("1_vkj58")
+Beat = 26.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_dnuvc"]
+script = ExtResource("1_vkj58")
+Beat = 2.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_n5nx3"]
+script = ExtResource("1_vkj58")
+Beat = 4.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_y8tsg"]
+script = ExtResource("1_vkj58")
+Beat = 7.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_msofk"]
+script = ExtResource("1_vkj58")
+Beat = 8.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_8qmnl"]
+script = ExtResource("1_vkj58")
+Beat = 9.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_w7vp2"]
+script = ExtResource("1_vkj58")
+Beat = 11.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_kvr5u"]
+script = ExtResource("1_vkj58")
+Beat = 15.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_6jc5o"]
+script = ExtResource("1_vkj58")
+Beat = 17.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_14q1d"]
+script = ExtResource("1_vkj58")
+Beat = 19.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_vixxy"]
+script = ExtResource("1_vkj58")
+Beat = 21.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_ktvox"]
+script = ExtResource("1_vkj58")
+Beat = 24.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_4vybl"]
+script = ExtResource("1_vkj58")
+Beat = 25.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_hclfl"]
+script = ExtResource("1_vkj58")
+Beat = 29.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_bmq0x"]
+script = ExtResource("1_vkj58")
+Beat = 30.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_6hjh7"]
+script = ExtResource("1_vkj58")
+Beat = 27.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_3lcfd"]
+script = ExtResource("1_vkj58")
+Beat = 1.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_b1quw"]
+script = ExtResource("1_vkj58")
+Beat = 4.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_lq0og"]
+script = ExtResource("1_vkj58")
+Beat = 8.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_56y1a"]
+script = ExtResource("1_vkj58")
+Beat = 11.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_jljr5"]
+script = ExtResource("1_vkj58")
+Beat = 16.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_bxx88"]
+script = ExtResource("1_vkj58")
+Beat = 22.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_bdoqu"]
+script = ExtResource("1_vkj58")
+Beat = 25.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_cr07w"]
+script = ExtResource("1_vkj58")
+Beat = 31.0
+Length = 0.0
+
+[resource]
+script = ExtResource("2_ulihw")
+UpLaneData = Array[ExtResource("1_vkj58")]([SubResource("Resource_3lcfd"), SubResource("Resource_b1quw"), SubResource("Resource_lq0og"), SubResource("Resource_56y1a"), SubResource("Resource_jljr5"), SubResource("Resource_bxx88"), SubResource("Resource_bdoqu"), SubResource("Resource_cr07w")])
+DownLaneData = Array[ExtResource("1_vkj58")]([SubResource("Resource_vkj58"), SubResource("Resource_ulihw"), SubResource("Resource_t8863"), SubResource("Resource_6g1by"), SubResource("Resource_m02wy"), SubResource("Resource_t1nlw"), SubResource("Resource_iknre"), SubResource("Resource_icwn4"), SubResource("Resource_vkj1q"), SubResource("Resource_g5inb")])
+LeftLaneData = Array[ExtResource("1_vkj58")]([SubResource("Resource_7jmhk"), SubResource("Resource_plxvd"), SubResource("Resource_jva8p"), SubResource("Resource_pref2"), SubResource("Resource_3tvlw"), SubResource("Resource_iq4by"), SubResource("Resource_rekwa"), SubResource("Resource_xbnbk"), SubResource("Resource_byp8i"), SubResource("Resource_dime5")])
+RightLaneData = Array[ExtResource("1_vkj58")]([SubResource("Resource_dnuvc"), SubResource("Resource_n5nx3"), SubResource("Resource_y8tsg"), SubResource("Resource_msofk"), SubResource("Resource_8qmnl"), SubResource("Resource_w7vp2"), SubResource("Resource_kvr5u"), SubResource("Resource_6jc5o"), SubResource("Resource_14q1d"), SubResource("Resource_vixxy"), SubResource("Resource_ktvox"), SubResource("Resource_4vybl"), SubResource("Resource_hclfl"), SubResource("Resource_bmq0x"), SubResource("Resource_6hjh7")])
diff --git a/Audio/songMaps/FrostWaltz.tres b/Audio/songMaps/FrostWaltz.tres
new file mode 100644
index 00000000..6562d14b
--- /dev/null
+++ b/Audio/songMaps/FrostWaltz.tres
@@ -0,0 +1,101 @@
+[gd_resource type="Resource" load_steps=21 format=3 uid="uid://cv2l8vevlixlj"]
+
+[ext_resource type="Script" uid="uid://bhbpcmtr6e6pk" path="res://Classes/MidiMaestro/NoteInfo.cs" id="1_8s5n5"]
+[ext_resource type="Script" uid="uid://bnpnavb5lwobj" path="res://Classes/MidiMaestro/NoteChart.cs" id="2_ipsne"]
+
+[sub_resource type="Resource" id="Resource_dwqep"]
+script = ExtResource("1_8s5n5")
+Beat = 7.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_ukqut"]
+script = ExtResource("1_8s5n5")
+Beat = 9.0
+Length = 1.0
+
+[sub_resource type="Resource" id="Resource_x1mw3"]
+script = ExtResource("1_8s5n5")
+Beat = 12.0
+Length = 1.0
+
+[sub_resource type="Resource" id="Resource_54umo"]
+script = ExtResource("1_8s5n5")
+Beat = 15.0
+Length = 1.0
+
+[sub_resource type="Resource" id="Resource_o0hqd"]
+script = ExtResource("1_8s5n5")
+Beat = 18.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_8s5n5"]
+script = ExtResource("1_8s5n5")
+Beat = 3.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_bsuy3"]
+script = ExtResource("1_8s5n5")
+Beat = 6.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_828xi"]
+script = ExtResource("1_8s5n5")
+Beat = 1.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_gfy4r"]
+script = ExtResource("1_8s5n5")
+Beat = 7.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_716y2"]
+script = ExtResource("1_8s5n5")
+Beat = 11.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_6sju3"]
+script = ExtResource("1_8s5n5")
+Beat = 17.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_h8r3u"]
+script = ExtResource("1_8s5n5")
+Beat = 6.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_3skly"]
+script = ExtResource("1_8s5n5")
+Beat = 15.0
+Length = 1.0
+
+[sub_resource type="Resource" id="Resource_fe74b"]
+script = ExtResource("1_8s5n5")
+Beat = 18.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_1d04x"]
+script = ExtResource("1_8s5n5")
+Beat = 3.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_ffi45"]
+script = ExtResource("1_8s5n5")
+Beat = 9.0
+Length = 1.0
+
+[sub_resource type="Resource" id="Resource_3tfr0"]
+script = ExtResource("1_8s5n5")
+Beat = 12.0
+Length = 1.0
+
+[sub_resource type="Resource" id="Resource_ipsne"]
+script = ExtResource("1_8s5n5")
+Beat = 1.0
+Length = 0.0
+
+[resource]
+script = ExtResource("2_ipsne")
+UpLaneData = Array[ExtResource("1_8s5n5")]([SubResource("Resource_ffi45"), SubResource("Resource_3tfr0"), SubResource("Resource_ipsne")])
+DownLaneData = Array[ExtResource("1_8s5n5")]([SubResource("Resource_dwqep"), SubResource("Resource_ukqut"), SubResource("Resource_x1mw3"), SubResource("Resource_54umo"), SubResource("Resource_o0hqd"), SubResource("Resource_8s5n5"), SubResource("Resource_bsuy3")])
+LeftLaneData = Array[ExtResource("1_8s5n5")]([SubResource("Resource_828xi"), SubResource("Resource_gfy4r"), SubResource("Resource_716y2"), SubResource("Resource_6sju3"), SubResource("Resource_h8r3u")])
+RightLaneData = Array[ExtResource("1_8s5n5")]([SubResource("Resource_3skly"), SubResource("Resource_fe74b"), SubResource("Resource_1d04x")])
diff --git a/Audio/songMaps/Gobbler.tres b/Audio/songMaps/Gobbler.tres
new file mode 100644
index 00000000..ec3b18b5
--- /dev/null
+++ b/Audio/songMaps/Gobbler.tres
@@ -0,0 +1,221 @@
+[gd_resource type="Resource" load_steps=45 format=3]
+
+[ext_resource type="Script" path="res://Classes/MidiMaestro/NoteInfo.cs" id="1_tuude"]
+[ext_resource type="Script" path="res://Classes/MidiMaestro/NoteChart.cs" id="2_hfiht"]
+
+[sub_resource type="Resource" id="Resource_i2qfq"]
+script = ExtResource("1_tuude")
+Beat = 4.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_clkmt"]
+script = ExtResource("1_tuude")
+Beat = 7.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_2yhqr"]
+script = ExtResource("1_tuude")
+Beat = 10.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_avloc"]
+script = ExtResource("1_tuude")
+Beat = 13.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_7ipoh"]
+script = ExtResource("1_tuude")
+Beat = 15.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_rc4vs"]
+script = ExtResource("1_tuude")
+Beat = 18.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_hsxfe"]
+script = ExtResource("1_tuude")
+Beat = 24.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_5uul0"]
+script = ExtResource("1_tuude")
+Beat = 27.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_20iwo"]
+script = ExtResource("1_tuude")
+Beat = 25.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_q3mne"]
+script = ExtResource("1_tuude")
+Beat = 2.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_klde2"]
+script = ExtResource("1_tuude")
+Beat = 5.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_6wxhr"]
+script = ExtResource("1_tuude")
+Beat = 7.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_4fyoq"]
+script = ExtResource("1_tuude")
+Beat = 11.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_1hg6d"]
+script = ExtResource("1_tuude")
+Beat = 14.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_6on7t"]
+script = ExtResource("1_tuude")
+Beat = 19.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_eq4ob"]
+script = ExtResource("1_tuude")
+Beat = 22.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_2rtaq"]
+script = ExtResource("1_tuude")
+Beat = 25.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_t5na6"]
+script = ExtResource("1_tuude")
+Beat = 9.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_447id"]
+script = ExtResource("1_tuude")
+Beat = 1.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_5hmpv"]
+script = ExtResource("1_tuude")
+Beat = 3.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_xky58"]
+script = ExtResource("1_tuude")
+Beat = 5.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_sxqb5"]
+script = ExtResource("1_tuude")
+Beat = 8.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_ae4y0"]
+script = ExtResource("1_tuude")
+Beat = 9.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_j7a00"]
+script = ExtResource("1_tuude")
+Beat = 11.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_tbgdx"]
+script = ExtResource("1_tuude")
+Beat = 13.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_55ty7"]
+script = ExtResource("1_tuude")
+Beat = 14.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_meqji"]
+script = ExtResource("1_tuude")
+Beat = 15.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_bc4nj"]
+script = ExtResource("1_tuude")
+Beat = 16.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_i1t8w"]
+script = ExtResource("1_tuude")
+Beat = 20.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_qmi4l"]
+script = ExtResource("1_tuude")
+Beat = 21.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_ebk8g"]
+script = ExtResource("1_tuude")
+Beat = 24.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_cj46n"]
+script = ExtResource("1_tuude")
+Beat = 27.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_8xjpx"]
+script = ExtResource("1_tuude")
+Beat = 1.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_wsgab"]
+script = ExtResource("1_tuude")
+Beat = 6.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_qwdig"]
+script = ExtResource("1_tuude")
+Beat = 9.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_66kxm"]
+script = ExtResource("1_tuude")
+Beat = 12.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_7ilo7"]
+script = ExtResource("1_tuude")
+Beat = 14.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_a20b3"]
+script = ExtResource("1_tuude")
+Beat = 17.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_pqrtt"]
+script = ExtResource("1_tuude")
+Beat = 19.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_pwr5v"]
+script = ExtResource("1_tuude")
+Beat = 23.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_rt0eg"]
+script = ExtResource("1_tuude")
+Beat = 26.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_8g5uo"]
+script = ExtResource("1_tuude")
+Beat = 21.0
+Length = 0.0
+
+[resource]
+script = ExtResource("2_hfiht")
+UpLaneData = Array[ExtResource("1_tuude")]([SubResource("Resource_8xjpx"), SubResource("Resource_wsgab"), SubResource("Resource_qwdig"), SubResource("Resource_66kxm"), SubResource("Resource_7ilo7"), SubResource("Resource_a20b3"), SubResource("Resource_pqrtt"), SubResource("Resource_pwr5v"), SubResource("Resource_rt0eg"), SubResource("Resource_8g5uo")])
+DownLaneData = Array[ExtResource("1_tuude")]([SubResource("Resource_i2qfq"), SubResource("Resource_clkmt"), SubResource("Resource_2yhqr"), SubResource("Resource_avloc"), SubResource("Resource_7ipoh"), SubResource("Resource_rc4vs"), SubResource("Resource_hsxfe"), SubResource("Resource_5uul0"), SubResource("Resource_20iwo")])
+LeftLaneData = Array[ExtResource("1_tuude")]([SubResource("Resource_q3mne"), SubResource("Resource_klde2"), SubResource("Resource_6wxhr"), SubResource("Resource_4fyoq"), SubResource("Resource_1hg6d"), SubResource("Resource_6on7t"), SubResource("Resource_eq4ob"), SubResource("Resource_2rtaq"), SubResource("Resource_t5na6")])
+RightLaneData = Array[ExtResource("1_tuude")]([SubResource("Resource_447id"), SubResource("Resource_5hmpv"), SubResource("Resource_xky58"), SubResource("Resource_sxqb5"), SubResource("Resource_ae4y0"), SubResource("Resource_j7a00"), SubResource("Resource_tbgdx"), SubResource("Resource_55ty7"), SubResource("Resource_meqji"), SubResource("Resource_bc4nj"), SubResource("Resource_i1t8w"), SubResource("Resource_qmi4l"), SubResource("Resource_ebk8g"), SubResource("Resource_cj46n")])
diff --git a/Audio/songMaps/HoloRepeat.tres b/Audio/songMaps/HoloRepeat.tres
new file mode 100644
index 00000000..a51e8538
--- /dev/null
+++ b/Audio/songMaps/HoloRepeat.tres
@@ -0,0 +1,131 @@
+[gd_resource type="Resource" load_steps=27 format=3]
+
+[ext_resource type="Script" path="res://Classes/MidiMaestro/NoteInfo.cs" id="1_y4wy8"]
+[ext_resource type="Script" path="res://Classes/MidiMaestro/NoteChart.cs" id="2_1kkot"]
+
+[sub_resource type="Resource" id="Resource_wxfu7"]
+script = ExtResource("1_y4wy8")
+Beat = 14.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_cjafy"]
+script = ExtResource("1_y4wy8")
+Beat = 24.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_jdotv"]
+script = ExtResource("1_y4wy8")
+Beat = 32.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_per1x"]
+script = ExtResource("1_y4wy8")
+Beat = 40.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_lw4uc"]
+script = ExtResource("1_y4wy8")
+Beat = 50.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_nxcmx"]
+script = ExtResource("1_y4wy8")
+Beat = 57.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_x0uap"]
+script = ExtResource("1_y4wy8")
+Beat = 28.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_1m0i6"]
+script = ExtResource("1_y4wy8")
+Beat = 36.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_1mpgo"]
+script = ExtResource("1_y4wy8")
+Beat = 12.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_iuho0"]
+script = ExtResource("1_y4wy8")
+Beat = 20.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_uj1b6"]
+script = ExtResource("1_y4wy8")
+Beat = 44.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_fi760"]
+script = ExtResource("1_y4wy8")
+Beat = 54.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_1fc0d"]
+script = ExtResource("1_y4wy8")
+Beat = 26.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_0vl64"]
+script = ExtResource("1_y4wy8")
+Beat = 14.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_j64im"]
+script = ExtResource("1_y4wy8")
+Beat = 34.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_t15ay"]
+script = ExtResource("1_y4wy8")
+Beat = 44.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_v3dna"]
+script = ExtResource("1_y4wy8")
+Beat = 52.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_8lcjo"]
+script = ExtResource("1_y4wy8")
+Beat = 57.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_rclq0"]
+script = ExtResource("1_y4wy8")
+Beat = 12.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_d15sy"]
+script = ExtResource("1_y4wy8")
+Beat = 22.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_xylpo"]
+script = ExtResource("1_y4wy8")
+Beat = 28.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_c4e5y"]
+script = ExtResource("1_y4wy8")
+Beat = 38.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_7lbis"]
+script = ExtResource("1_y4wy8")
+Beat = 48.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_8usgo"]
+script = ExtResource("1_y4wy8")
+Beat = 55.0
+Length = 0.0
+
+[resource]
+script = ExtResource("2_1kkot")
+UpLaneData = [SubResource("Resource_rclq0"), SubResource("Resource_d15sy"), SubResource("Resource_xylpo"), SubResource("Resource_c4e5y"), SubResource("Resource_7lbis"), SubResource("Resource_8usgo")]
+DownLaneData = [SubResource("Resource_wxfu7"), SubResource("Resource_cjafy"), SubResource("Resource_jdotv"), SubResource("Resource_per1x"), SubResource("Resource_lw4uc"), SubResource("Resource_nxcmx")]
+LeftLaneData = [SubResource("Resource_x0uap"), SubResource("Resource_1m0i6"), SubResource("Resource_1mpgo"), SubResource("Resource_iuho0"), SubResource("Resource_uj1b6"), SubResource("Resource_fi760")]
+RightLaneData = [SubResource("Resource_1fc0d"), SubResource("Resource_0vl64"), SubResource("Resource_j64im"), SubResource("Resource_t15ay"), SubResource("Resource_v3dna"), SubResource("Resource_8lcjo")]
diff --git a/Audio/songMaps/KeythuluSong.tres b/Audio/songMaps/KeythuluSong.tres
new file mode 100644
index 00000000..3eec9775
--- /dev/null
+++ b/Audio/songMaps/KeythuluSong.tres
@@ -0,0 +1,211 @@
+[gd_resource type="Resource" load_steps=43 format=3]
+
+[ext_resource type="Script" path="res://Classes/MidiMaestro/NoteInfo.cs" id="1_8ueh4"]
+[ext_resource type="Script" path="res://Classes/MidiMaestro/NoteChart.cs" id="2_s63u8"]
+
+[sub_resource type="Resource" id="Resource_ljr32"]
+script = ExtResource("1_8ueh4")
+Beat = 4.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_bb3yp"]
+script = ExtResource("1_8ueh4")
+Beat = 10.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_852ml"]
+script = ExtResource("1_8ueh4")
+Beat = 16.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_38nu8"]
+script = ExtResource("1_8ueh4")
+Beat = 22.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_3eydr"]
+script = ExtResource("1_8ueh4")
+Beat = 28.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_ct6sp"]
+script = ExtResource("1_8ueh4")
+Beat = 36.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_yk705"]
+script = ExtResource("1_8ueh4")
+Beat = 42.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_uswjw"]
+script = ExtResource("1_8ueh4")
+Beat = 54.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_e1hbr"]
+script = ExtResource("1_8ueh4")
+Beat = 60.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_8ueh4"]
+script = ExtResource("1_8ueh4")
+Beat = 48.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_gryrv"]
+script = ExtResource("1_8ueh4")
+Beat = 7.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_kwtfb"]
+script = ExtResource("1_8ueh4")
+Beat = 13.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_c2bxv"]
+script = ExtResource("1_8ueh4")
+Beat = 19.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_7lpnw"]
+script = ExtResource("1_8ueh4")
+Beat = 25.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_50tbs"]
+script = ExtResource("1_8ueh4")
+Beat = 31.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_ttd2q"]
+script = ExtResource("1_8ueh4")
+Beat = 34.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_nnlde"]
+script = ExtResource("1_8ueh4")
+Beat = 39.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_lrc4j"]
+script = ExtResource("1_8ueh4")
+Beat = 45.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_83big"]
+script = ExtResource("1_8ueh4")
+Beat = 57.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_oocdv"]
+script = ExtResource("1_8ueh4")
+Beat = 51.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_lfmd3"]
+script = ExtResource("1_8ueh4")
+Beat = 9.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_x1ijp"]
+script = ExtResource("1_8ueh4")
+Beat = 15.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_6jgy8"]
+script = ExtResource("1_8ueh4")
+Beat = 18.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_oxq2d"]
+script = ExtResource("1_8ueh4")
+Beat = 23.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_3102k"]
+script = ExtResource("1_8ueh4")
+Beat = 29.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_j4fdm"]
+script = ExtResource("1_8ueh4")
+Beat = 35.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_5raac"]
+script = ExtResource("1_8ueh4")
+Beat = 41.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_c27cp"]
+script = ExtResource("1_8ueh4")
+Beat = 47.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_pfqra"]
+script = ExtResource("1_8ueh4")
+Beat = 50.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_2nxl5"]
+script = ExtResource("1_8ueh4")
+Beat = 56.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_67x67"]
+script = ExtResource("1_8ueh4")
+Beat = 61.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_vkfw6"]
+script = ExtResource("1_8ueh4")
+Beat = 6.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_5vawl"]
+script = ExtResource("1_8ueh4")
+Beat = 12.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_wqml3"]
+script = ExtResource("1_8ueh4")
+Beat = 20.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_knus5"]
+script = ExtResource("1_8ueh4")
+Beat = 32.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_iyhat"]
+script = ExtResource("1_8ueh4")
+Beat = 38.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_e231o"]
+script = ExtResource("1_8ueh4")
+Beat = 44.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_u1ybv"]
+script = ExtResource("1_8ueh4")
+Beat = 59.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_s63u8"]
+script = ExtResource("1_8ueh4")
+Beat = 26.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_rwedv"]
+script = ExtResource("1_8ueh4")
+Beat = 53.0
+Length = 0.0
+
+[resource]
+script = ExtResource("2_s63u8")
+UpLaneData = Array[ExtResource("1_8ueh4")]([SubResource("Resource_vkfw6"), SubResource("Resource_5vawl"), SubResource("Resource_wqml3"), SubResource("Resource_knus5"), SubResource("Resource_iyhat"), SubResource("Resource_e231o"), SubResource("Resource_u1ybv"), SubResource("Resource_s63u8"), SubResource("Resource_rwedv")])
+DownLaneData = Array[ExtResource("1_8ueh4")]([SubResource("Resource_ljr32"), SubResource("Resource_bb3yp"), SubResource("Resource_852ml"), SubResource("Resource_38nu8"), SubResource("Resource_3eydr"), SubResource("Resource_ct6sp"), SubResource("Resource_yk705"), SubResource("Resource_uswjw"), SubResource("Resource_e1hbr"), SubResource("Resource_8ueh4")])
+LeftLaneData = Array[ExtResource("1_8ueh4")]([SubResource("Resource_gryrv"), SubResource("Resource_kwtfb"), SubResource("Resource_c2bxv"), SubResource("Resource_7lpnw"), SubResource("Resource_50tbs"), SubResource("Resource_ttd2q"), SubResource("Resource_nnlde"), SubResource("Resource_lrc4j"), SubResource("Resource_83big"), SubResource("Resource_oocdv")])
+RightLaneData = Array[ExtResource("1_8ueh4")]([SubResource("Resource_lfmd3"), SubResource("Resource_x1ijp"), SubResource("Resource_6jgy8"), SubResource("Resource_oxq2d"), SubResource("Resource_3102k"), SubResource("Resource_j4fdm"), SubResource("Resource_5raac"), SubResource("Resource_c27cp"), SubResource("Resource_pfqra"), SubResource("Resource_2nxl5"), SubResource("Resource_67x67")])
diff --git a/Audio/songMaps/Mushroom.tres b/Audio/songMaps/Mushroom.tres
new file mode 100644
index 00000000..76fd946b
--- /dev/null
+++ b/Audio/songMaps/Mushroom.tres
@@ -0,0 +1,81 @@
+[gd_resource type="Resource" load_steps=17 format=3 uid="uid://bowwiy4hgvtiu"]
+
+[ext_resource type="Script" uid="uid://bhbpcmtr6e6pk" path="res://Classes/MidiMaestro/NoteInfo.cs" id="1_n1l5w"]
+[ext_resource type="Script" uid="uid://bnpnavb5lwobj" path="res://Classes/MidiMaestro/NoteChart.cs" id="2_0c8vj"]
+
+[sub_resource type="Resource" id="Resource_pprmk"]
+script = ExtResource("1_n1l5w")
+Beat = 1.0
+Length = 4.0
+
+[sub_resource type="Resource" id="Resource_n1l5w"]
+script = ExtResource("1_n1l5w")
+Beat = 6.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_0c8vj"]
+script = ExtResource("1_n1l5w")
+Beat = 8.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_4gn2h"]
+script = ExtResource("1_n1l5w")
+Beat = 10.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_aa728"]
+script = ExtResource("1_n1l5w")
+Beat = 13.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_olyge"]
+script = ExtResource("1_n1l5w")
+Beat = 16.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_rjl7u"]
+script = ExtResource("1_n1l5w")
+Beat = 15.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_ea4gl"]
+script = ExtResource("1_n1l5w")
+Beat = 4.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_seepc"]
+script = ExtResource("1_n1l5w")
+Beat = 6.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_xdem2"]
+script = ExtResource("1_n1l5w")
+Beat = 13.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_ymucf"]
+script = ExtResource("1_n1l5w")
+Beat = 7.0
+Length = 2.0
+
+[sub_resource type="Resource" id="Resource_bmgju"]
+script = ExtResource("1_n1l5w")
+Beat = 12.0
+Length = 2.0
+
+[sub_resource type="Resource" id="Resource_sosma"]
+script = ExtResource("1_n1l5w")
+Beat = 16.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_3retf"]
+script = ExtResource("1_n1l5w")
+Beat = 15.0
+Length = 0.0
+
+[resource]
+script = ExtResource("2_0c8vj")
+UpLaneData = Array[ExtResource("1_n1l5w")]([SubResource("Resource_ymucf"), SubResource("Resource_bmgju"), SubResource("Resource_sosma"), SubResource("Resource_3retf")])
+DownLaneData = Array[ExtResource("1_n1l5w")]([SubResource("Resource_pprmk"), SubResource("Resource_n1l5w"), SubResource("Resource_0c8vj")])
+LeftLaneData = Array[ExtResource("1_n1l5w")]([SubResource("Resource_4gn2h"), SubResource("Resource_aa728"), SubResource("Resource_olyge"), SubResource("Resource_rjl7u")])
+RightLaneData = Array[ExtResource("1_n1l5w")]([SubResource("Resource_ea4gl"), SubResource("Resource_seepc"), SubResource("Resource_xdem2")])
diff --git a/Audio/songMaps/Shapes.tres b/Audio/songMaps/Shapes.tres
new file mode 100644
index 00000000..5e567069
--- /dev/null
+++ b/Audio/songMaps/Shapes.tres
@@ -0,0 +1,191 @@
+[gd_resource type="Resource" load_steps=39 format=3]
+
+[ext_resource type="Script" path="res://Classes/MidiMaestro/NoteInfo.cs" id="1_egl41"]
+[ext_resource type="Script" path="res://Classes/MidiMaestro/NoteChart.cs" id="2_j6rk8"]
+
+[sub_resource type="Resource" id="Resource_egl41"]
+script = ExtResource("1_egl41")
+Beat = 2.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_j6rk8"]
+script = ExtResource("1_egl41")
+Beat = 5.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_61fe8"]
+script = ExtResource("1_egl41")
+Beat = 6.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_dmlrl"]
+script = ExtResource("1_egl41")
+Beat = 8.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_xny5e"]
+script = ExtResource("1_egl41")
+Beat = 10.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_sybk5"]
+script = ExtResource("1_egl41")
+Beat = 12.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_cs7yi"]
+script = ExtResource("1_egl41")
+Beat = 14.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_xv7yd"]
+script = ExtResource("1_egl41")
+Beat = 18.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_pfidy"]
+script = ExtResource("1_egl41")
+Beat = 21.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_n0y2d"]
+script = ExtResource("1_egl41")
+Beat = 22.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_i5oul"]
+script = ExtResource("1_egl41")
+Beat = 3.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_qnkk3"]
+script = ExtResource("1_egl41")
+Beat = 6.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_oqhlp"]
+script = ExtResource("1_egl41")
+Beat = 11.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_af8di"]
+script = ExtResource("1_egl41")
+Beat = 14.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_p5qx0"]
+script = ExtResource("1_egl41")
+Beat = 16.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_5ddno"]
+script = ExtResource("1_egl41")
+Beat = 19.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_ep11h"]
+script = ExtResource("1_egl41")
+Beat = 23.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_yjewp"]
+script = ExtResource("1_egl41")
+Beat = 1.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_pn3jr"]
+script = ExtResource("1_egl41")
+Beat = 3.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_yxbuu"]
+script = ExtResource("1_egl41")
+Beat = 5.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_5ue8d"]
+script = ExtResource("1_egl41")
+Beat = 7.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_kjeyd"]
+script = ExtResource("1_egl41")
+Beat = 9.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_pljkl"]
+script = ExtResource("1_egl41")
+Beat = 12.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_0h2yl"]
+script = ExtResource("1_egl41")
+Beat = 13.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_ijt06"]
+script = ExtResource("1_egl41")
+Beat = 15.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_61fei"]
+script = ExtResource("1_egl41")
+Beat = 18.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_vxhs1"]
+script = ExtResource("1_egl41")
+Beat = 23.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_20ma1"]
+script = ExtResource("1_egl41")
+Beat = 1.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_t2x17"]
+script = ExtResource("1_egl41")
+Beat = 4.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_hsyk0"]
+script = ExtResource("1_egl41")
+Beat = 7.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_txx7m"]
+script = ExtResource("1_egl41")
+Beat = 9.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_uic3e"]
+script = ExtResource("1_egl41")
+Beat = 11.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_fy78b"]
+script = ExtResource("1_egl41")
+Beat = 13.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_p1dmw"]
+script = ExtResource("1_egl41")
+Beat = 17.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_7k1m6"]
+script = ExtResource("1_egl41")
+Beat = 20.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_e223l"]
+script = ExtResource("1_egl41")
+Beat = 21.0
+Length = 0.0
+
+[resource]
+script = ExtResource("2_j6rk8")
+UpLaneData = Array[ExtResource("1_egl41")]([SubResource("Resource_20ma1"), SubResource("Resource_t2x17"), SubResource("Resource_hsyk0"), SubResource("Resource_txx7m"), SubResource("Resource_uic3e"), SubResource("Resource_fy78b"), SubResource("Resource_p1dmw"), SubResource("Resource_7k1m6"), SubResource("Resource_e223l")])
+DownLaneData = Array[ExtResource("1_egl41")]([SubResource("Resource_egl41"), SubResource("Resource_j6rk8"), SubResource("Resource_61fe8"), SubResource("Resource_dmlrl"), SubResource("Resource_xny5e"), SubResource("Resource_sybk5"), SubResource("Resource_cs7yi"), SubResource("Resource_xv7yd"), SubResource("Resource_pfidy"), SubResource("Resource_n0y2d")])
+LeftLaneData = Array[ExtResource("1_egl41")]([SubResource("Resource_i5oul"), SubResource("Resource_qnkk3"), SubResource("Resource_oqhlp"), SubResource("Resource_af8di"), SubResource("Resource_p5qx0"), SubResource("Resource_5ddno"), SubResource("Resource_ep11h")])
+RightLaneData = Array[ExtResource("1_egl41")]([SubResource("Resource_yjewp"), SubResource("Resource_pn3jr"), SubResource("Resource_yxbuu"), SubResource("Resource_5ue8d"), SubResource("Resource_kjeyd"), SubResource("Resource_pljkl"), SubResource("Resource_0h2yl"), SubResource("Resource_ijt06"), SubResource("Resource_61fei"), SubResource("Resource_vxhs1")])
diff --git a/Audio/songMaps/Song1.tres b/Audio/songMaps/Song1.tres
index bf63d7af..7e95ae2e 100644
--- a/Audio/songMaps/Song1.tres
+++ b/Audio/songMaps/Song1.tres
@@ -1,51 +1,61 @@
-[gd_resource type="Resource" load_steps=44 format=3 uid="uid://djm7g0svpexde"]
+[gd_resource type="Resource" load_steps=51 format=3]
[ext_resource type="Script" path="res://Classes/MidiMaestro/NoteInfo.cs" id="1_5ry1j"]
[ext_resource type="Script" path="res://Classes/MidiMaestro/NoteChart.cs" id="2_gbqfw"]
-[sub_resource type="Resource" id="Resource_sycg1"]
+[sub_resource type="Resource" id="Resource_h1ijp"]
script = ExtResource("1_5ry1j")
-Beat = 16.0
+Beat = 9.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_vh0lg"]
+[sub_resource type="Resource" id="Resource_ysbfa"]
script = ExtResource("1_5ry1j")
-Beat = 24.0
+Beat = 25.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_4fym7"]
+[sub_resource type="Resource" id="Resource_j4c1l"]
script = ExtResource("1_5ry1j")
-Beat = 32.0
+Beat = 49.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_mf3c7"]
+[sub_resource type="Resource" id="Resource_lktv3"]
script = ExtResource("1_5ry1j")
-Beat = 5.0
+Beat = 53.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_5kf2q"]
+[sub_resource type="Resource" id="Resource_b0kfm"]
script = ExtResource("1_5ry1j")
-Beat = 9.0
+Beat = 57.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_f15o4"]
+[sub_resource type="Resource" id="Resource_xbckj"]
script = ExtResource("1_5ry1j")
-Beat = 13.0
+Beat = 34.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_gs0vr"]
+script = ExtResource("1_5ry1j")
+Beat = 43.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_4ygvu"]
+script = ExtResource("1_5ry1j")
+Beat = 44.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_oert5"]
+[sub_resource type="Resource" id="Resource_efsyh"]
script = ExtResource("1_5ry1j")
Beat = 17.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_kytyf"]
+[sub_resource type="Resource" id="Resource_mf3c7"]
script = ExtResource("1_5ry1j")
-Beat = 21.0
+Beat = 5.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_kmfoh"]
+[sub_resource type="Resource" id="Resource_f15o4"]
script = ExtResource("1_5ry1j")
-Beat = 25.0
+Beat = 13.0
Length = 0.0
[sub_resource type="Resource" id="Resource_hsn40"]
@@ -73,19 +83,19 @@ script = ExtResource("1_5ry1j")
Beat = 45.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_n2wrp"]
+[sub_resource type="Resource" id="Resource_2jtmb"]
script = ExtResource("1_5ry1j")
-Beat = 49.0
+Beat = 57.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_gmg26"]
+[sub_resource type="Resource" id="Resource_qx4ac"]
script = ExtResource("1_5ry1j")
-Beat = 53.0
+Beat = 50.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_2jtmb"]
+[sub_resource type="Resource" id="Resource_csfw3"]
script = ExtResource("1_5ry1j")
-Beat = 57.0
+Beat = 59.0
Length = 0.0
[sub_resource type="Resource" id="Resource_l3uo1"]
@@ -93,124 +103,149 @@ script = ExtResource("1_5ry1j")
Beat = 32.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_ayat2"]
+[sub_resource type="Resource" id="Resource_erw8g"]
script = ExtResource("1_5ry1j")
-Beat = 35.0
+Beat = 44.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_5hrj0"]
+[sub_resource type="Resource" id="Resource_alq0l"]
script = ExtResource("1_5ry1j")
-Beat = 38.0
+Beat = 36.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_sbk3e"]
+[sub_resource type="Resource" id="Resource_rkc43"]
script = ExtResource("1_5ry1j")
-Beat = 41.0
+Beat = 4.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_erw8g"]
+[sub_resource type="Resource" id="Resource_tudf6"]
script = ExtResource("1_5ry1j")
-Beat = 44.0
+Beat = 8.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_ohcnr"]
+[sub_resource type="Resource" id="Resource_tlvlu"]
script = ExtResource("1_5ry1j")
-Beat = 47.0
+Beat = 12.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_1xng4"]
+[sub_resource type="Resource" id="Resource_p167p"]
script = ExtResource("1_5ry1j")
-Beat = 50.0
+Beat = 16.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_ullhh"]
+[sub_resource type="Resource" id="Resource_dc6jo"]
script = ExtResource("1_5ry1j")
-Beat = 53.0
+Beat = 20.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_w3cuf"]
+script = ExtResource("1_5ry1j")
+Beat = 24.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_vjysj"]
+script = ExtResource("1_5ry1j")
+Beat = 28.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_aqpy1"]
+script = ExtResource("1_5ry1j")
+Beat = 40.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_ctve7"]
+script = ExtResource("1_5ry1j")
+Beat = 48.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_jf4ph"]
+[sub_resource type="Resource" id="Resource_nl7kj"]
script = ExtResource("1_5ry1j")
Beat = 56.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_l0ykb"]
+[sub_resource type="Resource" id="Resource_ogyoe"]
script = ExtResource("1_5ry1j")
-Beat = 59.0
+Beat = 60.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_o3ga4"]
+[sub_resource type="Resource" id="Resource_q33e3"]
script = ExtResource("1_5ry1j")
-Beat = 4.0
+Beat = 61.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_j4bu6"]
+[sub_resource type="Resource" id="Resource_vqw4k"]
script = ExtResource("1_5ry1j")
-Beat = 8.0
+Beat = 52.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_3pmwc"]
+[sub_resource type="Resource" id="Resource_s8jc0"]
script = ExtResource("1_5ry1j")
-Beat = 12.0
+Beat = 33.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_8a8dw"]
+[sub_resource type="Resource" id="Resource_fjllr"]
script = ExtResource("1_5ry1j")
-Beat = 16.0
+Beat = 36.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_sen1l"]
+[sub_resource type="Resource" id="Resource_y2wfd"]
script = ExtResource("1_5ry1j")
-Beat = 20.0
+Beat = 17.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_i8i3p"]
+[sub_resource type="Resource" id="Resource_cb61k"]
script = ExtResource("1_5ry1j")
-Beat = 24.0
+Beat = 41.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_v6ql4"]
+[sub_resource type="Resource" id="Resource_hbkgo"]
script = ExtResource("1_5ry1j")
-Beat = 28.0
+Beat = 49.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_v3ixx"]
+[sub_resource type="Resource" id="Resource_80wib"]
script = ExtResource("1_5ry1j")
-Beat = 32.0
+Beat = 35.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_fjllr"]
+[sub_resource type="Resource" id="Resource_jsm3m"]
script = ExtResource("1_5ry1j")
-Beat = 36.0
+Beat = 50.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_kfijo"]
+[sub_resource type="Resource" id="Resource_ryg8k"]
script = ExtResource("1_5ry1j")
-Beat = 40.0
+Beat = 51.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_j42ns"]
+[sub_resource type="Resource" id="Resource_gj6xo"]
script = ExtResource("1_5ry1j")
-Beat = 44.0
+Beat = 58.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_c3aa2"]
+[sub_resource type="Resource" id="Resource_112dg"]
script = ExtResource("1_5ry1j")
-Beat = 48.0
+Beat = 59.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_a36fj"]
+[sub_resource type="Resource" id="Resource_eguul"]
script = ExtResource("1_5ry1j")
-Beat = 52.0
+Beat = 42.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_gwuir"]
+[sub_resource type="Resource" id="Resource_tdy7a"]
script = ExtResource("1_5ry1j")
-Beat = 56.0
+Beat = 21.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_d7de0"]
+script = ExtResource("1_5ry1j")
+Beat = 26.0
Length = 0.0
[resource]
script = ExtResource("2_gbqfw")
-UpLaneData = [SubResource("Resource_o3ga4"), SubResource("Resource_j4bu6"), SubResource("Resource_3pmwc"), SubResource("Resource_8a8dw"), SubResource("Resource_sen1l"), SubResource("Resource_i8i3p"), SubResource("Resource_v6ql4"), SubResource("Resource_v3ixx"), SubResource("Resource_fjllr"), SubResource("Resource_kfijo"), SubResource("Resource_j42ns"), SubResource("Resource_c3aa2"), SubResource("Resource_a36fj"), SubResource("Resource_gwuir")]
-DownLaneData = [SubResource("Resource_sycg1"), SubResource("Resource_vh0lg"), SubResource("Resource_4fym7")]
-LeftLaneData = [SubResource("Resource_mf3c7"), SubResource("Resource_5kf2q"), SubResource("Resource_f15o4"), SubResource("Resource_oert5"), SubResource("Resource_kytyf"), SubResource("Resource_kmfoh"), SubResource("Resource_hsn40"), SubResource("Resource_fdk4c"), SubResource("Resource_1aoo3"), SubResource("Resource_wlcjv"), SubResource("Resource_i1n24"), SubResource("Resource_n2wrp"), SubResource("Resource_gmg26"), SubResource("Resource_2jtmb")]
-RightLaneData = [SubResource("Resource_l3uo1"), SubResource("Resource_ayat2"), SubResource("Resource_5hrj0"), SubResource("Resource_sbk3e"), SubResource("Resource_erw8g"), SubResource("Resource_ohcnr"), SubResource("Resource_1xng4"), SubResource("Resource_ullhh"), SubResource("Resource_jf4ph"), SubResource("Resource_l0ykb")]
+UpLaneData = [SubResource("Resource_fjllr"), SubResource("Resource_y2wfd"), SubResource("Resource_cb61k"), SubResource("Resource_hbkgo"), SubResource("Resource_80wib"), SubResource("Resource_jsm3m"), SubResource("Resource_ryg8k"), SubResource("Resource_gj6xo"), SubResource("Resource_112dg"), SubResource("Resource_eguul"), SubResource("Resource_tdy7a"), SubResource("Resource_d7de0")]
+DownLaneData = [SubResource("Resource_h1ijp"), SubResource("Resource_ysbfa"), SubResource("Resource_j4c1l"), SubResource("Resource_lktv3"), SubResource("Resource_b0kfm"), SubResource("Resource_xbckj"), SubResource("Resource_gs0vr"), SubResource("Resource_4ygvu"), SubResource("Resource_efsyh")]
+LeftLaneData = [SubResource("Resource_mf3c7"), SubResource("Resource_f15o4"), SubResource("Resource_hsn40"), SubResource("Resource_fdk4c"), SubResource("Resource_1aoo3"), SubResource("Resource_wlcjv"), SubResource("Resource_i1n24"), SubResource("Resource_2jtmb"), SubResource("Resource_qx4ac"), SubResource("Resource_csfw3")]
+RightLaneData = [SubResource("Resource_l3uo1"), SubResource("Resource_erw8g"), SubResource("Resource_alq0l"), SubResource("Resource_rkc43"), SubResource("Resource_tudf6"), SubResource("Resource_tlvlu"), SubResource("Resource_p167p"), SubResource("Resource_dc6jo"), SubResource("Resource_w3cuf"), SubResource("Resource_vjysj"), SubResource("Resource_aqpy1"), SubResource("Resource_ctve7"), SubResource("Resource_nl7kj"), SubResource("Resource_ogyoe"), SubResource("Resource_q33e3"), SubResource("Resource_vqw4k"), SubResource("Resource_s8jc0")]
diff --git a/Audio/songMaps/Song2.tres b/Audio/songMaps/Song2.tres
index 486b0873..93e6a038 100644
--- a/Audio/songMaps/Song2.tres
+++ b/Audio/songMaps/Song2.tres
@@ -1,156 +1,126 @@
-[gd_resource type="Resource" load_steps=32 format=3]
+[gd_resource type="Resource" load_steps=26 format=3]
-[ext_resource type="Script" path="res://Classes/MidiMaestro/NoteInfo.cs" id="1_7gfc4"]
-[ext_resource type="Script" path="res://Classes/MidiMaestro/NoteChart.cs" id="2_12jpe"]
+[ext_resource type="Script" path="res://Classes/MidiMaestro/NoteInfo.cs" id="1_vo5rw"]
+[ext_resource type="Script" path="res://Classes/MidiMaestro/NoteChart.cs" id="2_hgwt2"]
-[sub_resource type="Resource" id="Resource_rxom0"]
-script = ExtResource("1_7gfc4")
-Beat = 1.0
+[sub_resource type="Resource" id="Resource_svc5u"]
+script = ExtResource("1_vo5rw")
+Beat = 2.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_asj20"]
-script = ExtResource("1_7gfc4")
+[sub_resource type="Resource" id="Resource_ienox"]
+script = ExtResource("1_vo5rw")
Beat = 6.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_hredl"]
-script = ExtResource("1_7gfc4")
+[sub_resource type="Resource" id="Resource_ax4q1"]
+script = ExtResource("1_vo5rw")
Beat = 10.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_iciyj"]
-script = ExtResource("1_7gfc4")
-Beat = 14.0
-Length = 0.0
-
-[sub_resource type="Resource" id="Resource_1w85u"]
-script = ExtResource("1_7gfc4")
-Beat = 17.0
+[sub_resource type="Resource" id="Resource_663rs"]
+script = ExtResource("1_vo5rw")
+Beat = 15.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_daxqs"]
-script = ExtResource("1_7gfc4")
-Beat = 22.0
+[sub_resource type="Resource" id="Resource_86xei"]
+script = ExtResource("1_vo5rw")
+Beat = 20.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_6qbd8"]
-script = ExtResource("1_7gfc4")
-Beat = 25.0
+[sub_resource type="Resource" id="Resource_w3gx2"]
+script = ExtResource("1_vo5rw")
+Beat = 12.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_54mir"]
-script = ExtResource("1_7gfc4")
-Beat = 30.0
+[sub_resource type="Resource" id="Resource_t01kg"]
+script = ExtResource("1_vo5rw")
+Beat = 18.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_ijh26"]
-script = ExtResource("1_7gfc4")
-Beat = 2.0
+[sub_resource type="Resource" id="Resource_rnhdg"]
+script = ExtResource("1_vo5rw")
+Beat = 8.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_sstcx"]
-script = ExtResource("1_7gfc4")
-Beat = 4.0
+[sub_resource type="Resource" id="Resource_of7dy"]
+script = ExtResource("1_vo5rw")
+Beat = 22.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_ldqq5"]
-script = ExtResource("1_7gfc4")
-Beat = 5.0
+[sub_resource type="Resource" id="Resource_xq1dl"]
+script = ExtResource("1_vo5rw")
+Beat = 11.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_eltqr"]
-script = ExtResource("1_7gfc4")
-Beat = 10.0
+[sub_resource type="Resource" id="Resource_ym0tj"]
+script = ExtResource("1_vo5rw")
+Beat = 4.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_fxmce"]
-script = ExtResource("1_7gfc4")
-Beat = 12.0
+[sub_resource type="Resource" id="Resource_1vvgc"]
+script = ExtResource("1_vo5rw")
+Beat = 11.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_l7bpk"]
-script = ExtResource("1_7gfc4")
+[sub_resource type="Resource" id="Resource_wjmqy"]
+script = ExtResource("1_vo5rw")
Beat = 14.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_do8wm"]
-script = ExtResource("1_7gfc4")
-Beat = 15.0
+[sub_resource type="Resource" id="Resource_64q4o"]
+script = ExtResource("1_vo5rw")
+Beat = 16.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_qvcn2"]
-script = ExtResource("1_7gfc4")
-Beat = 18.0
+[sub_resource type="Resource" id="Resource_rubmr"]
+script = ExtResource("1_vo5rw")
+Beat = 19.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_siock"]
-script = ExtResource("1_7gfc4")
+[sub_resource type="Resource" id="Resource_ejow0"]
+script = ExtResource("1_vo5rw")
Beat = 20.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_lec0e"]
-script = ExtResource("1_7gfc4")
-Beat = 22.0
-Length = 0.0
-
-[sub_resource type="Resource" id="Resource_6wstj"]
-script = ExtResource("1_7gfc4")
-Beat = 25.0
-Length = 0.0
-
-[sub_resource type="Resource" id="Resource_uxbx5"]
-script = ExtResource("1_7gfc4")
-Beat = 26.0
-Length = 0.0
-
-[sub_resource type="Resource" id="Resource_chdui"]
-script = ExtResource("1_7gfc4")
-Beat = 28.0
-Length = 1.0
-
-[sub_resource type="Resource" id="Resource_t7pyo"]
-script = ExtResource("1_7gfc4")
+[sub_resource type="Resource" id="Resource_pbett"]
+script = ExtResource("1_vo5rw")
Beat = 8.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_1obgv"]
-script = ExtResource("1_7gfc4")
-Beat = 15.0
-Length = 0.0
-
-[sub_resource type="Resource" id="Resource_3ah33"]
-script = ExtResource("1_7gfc4")
-Beat = 24.0
+[sub_resource type="Resource" id="Resource_gru0r"]
+script = ExtResource("1_vo5rw")
+Beat = 22.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_87dqu"]
-script = ExtResource("1_7gfc4")
-Beat = 1.0
+[sub_resource type="Resource" id="Resource_wljiu"]
+script = ExtResource("1_vo5rw")
+Beat = 10.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_81s21"]
-script = ExtResource("1_7gfc4")
+[sub_resource type="Resource" id="Resource_3viwm"]
+script = ExtResource("1_vo5rw")
Beat = 2.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_pyy5l"]
-script = ExtResource("1_7gfc4")
-Beat = 9.0
+[sub_resource type="Resource" id="Resource_mcgpp"]
+script = ExtResource("1_vo5rw")
+Beat = 4.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_7lmg0"]
-script = ExtResource("1_7gfc4")
-Beat = 17.0
+[sub_resource type="Resource" id="Resource_olklg"]
+script = ExtResource("1_vo5rw")
+Beat = 12.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_hgf3i"]
-script = ExtResource("1_7gfc4")
-Beat = 25.0
+[sub_resource type="Resource" id="Resource_57g2b"]
+script = ExtResource("1_vo5rw")
+Beat = 18.0
Length = 0.0
[resource]
-script = ExtResource("2_12jpe")
-UpLaneData = Array[ExtResource("1_7gfc4")]([SubResource("Resource_87dqu"), SubResource("Resource_81s21"), SubResource("Resource_pyy5l"), SubResource("Resource_7lmg0"), SubResource("Resource_hgf3i")])
-DownLaneData = Array[ExtResource("1_7gfc4")]([SubResource("Resource_rxom0"), SubResource("Resource_asj20"), SubResource("Resource_hredl"), SubResource("Resource_iciyj"), SubResource("Resource_1w85u"), SubResource("Resource_daxqs"), SubResource("Resource_6qbd8"), SubResource("Resource_54mir")])
-LeftLaneData = Array[ExtResource("1_7gfc4")]([SubResource("Resource_ijh26"), SubResource("Resource_sstcx"), SubResource("Resource_ldqq5"), SubResource("Resource_eltqr"), SubResource("Resource_fxmce"), SubResource("Resource_l7bpk"), SubResource("Resource_do8wm"), SubResource("Resource_qvcn2"), SubResource("Resource_siock"), SubResource("Resource_lec0e"), SubResource("Resource_6wstj"), SubResource("Resource_uxbx5"), SubResource("Resource_chdui")])
-RightLaneData = Array[ExtResource("1_7gfc4")]([SubResource("Resource_t7pyo"), SubResource("Resource_1obgv"), SubResource("Resource_3ah33")])
+script = ExtResource("2_hgwt2")
+UpLaneData = Array[ExtResource("1_vo5rw")]([SubResource("Resource_3viwm"), SubResource("Resource_mcgpp"), SubResource("Resource_olklg"), SubResource("Resource_57g2b")])
+DownLaneData = Array[ExtResource("1_vo5rw")]([SubResource("Resource_svc5u"), SubResource("Resource_ienox"), SubResource("Resource_ax4q1"), SubResource("Resource_663rs"), SubResource("Resource_86xei"), SubResource("Resource_w3gx2"), SubResource("Resource_t01kg")])
+LeftLaneData = Array[ExtResource("1_vo5rw")]([SubResource("Resource_rnhdg"), SubResource("Resource_of7dy"), SubResource("Resource_xq1dl")])
+RightLaneData = Array[ExtResource("1_vo5rw")]([SubResource("Resource_ym0tj"), SubResource("Resource_1vvgc"), SubResource("Resource_wjmqy"), SubResource("Resource_64q4o"), SubResource("Resource_rubmr"), SubResource("Resource_ejow0"), SubResource("Resource_pbett"), SubResource("Resource_gru0r"), SubResource("Resource_wljiu")])
diff --git a/Audio/songMaps/Song3.tres b/Audio/songMaps/Song3.tres
index 28d691de..c8e3c520 100644
--- a/Audio/songMaps/Song3.tres
+++ b/Audio/songMaps/Song3.tres
@@ -1,23 +1,8 @@
-[gd_resource type="Resource" load_steps=57 format=3 uid="uid://ekxscjn7ys6v"]
+[gd_resource type="Resource" load_steps=60 format=3]
[ext_resource type="Script" path="res://Classes/MidiMaestro/NoteInfo.cs" id="1_7kndb"]
[ext_resource type="Script" path="res://Classes/MidiMaestro/NoteChart.cs" id="2_xg88o"]
-[sub_resource type="Resource" id="Resource_7kndb"]
-script = ExtResource("1_7kndb")
-Beat = 3.0
-Length = 0.0
-
-[sub_resource type="Resource" id="Resource_xg88o"]
-script = ExtResource("1_7kndb")
-Beat = 6.0
-Length = 0.0
-
-[sub_resource type="Resource" id="Resource_g8421"]
-script = ExtResource("1_7kndb")
-Beat = 7.0
-Length = 0.0
-
[sub_resource type="Resource" id="Resource_11qbm"]
script = ExtResource("1_7kndb")
Beat = 17.0
@@ -38,59 +23,64 @@ script = ExtResource("1_7kndb")
Beat = 25.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_6n6ig"]
+[sub_resource type="Resource" id="Resource_fldsc"]
script = ExtResource("1_7kndb")
-Beat = 27.0
+Beat = 38.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_ci2g3"]
+[sub_resource type="Resource" id="Resource_ntp27"]
script = ExtResource("1_7kndb")
-Beat = 32.0
+Beat = 35.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_2c17a"]
+[sub_resource type="Resource" id="Resource_7nmxt"]
script = ExtResource("1_7kndb")
-Beat = 34.0
+Beat = 49.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_gugsw"]
+[sub_resource type="Resource" id="Resource_47jch"]
script = ExtResource("1_7kndb")
-Beat = 39.0
+Beat = 57.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_j4ixp"]
+[sub_resource type="Resource" id="Resource_kp5f0"]
script = ExtResource("1_7kndb")
-Beat = 44.0
+Beat = 41.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_i2oko"]
+[sub_resource type="Resource" id="Resource_v8s33"]
script = ExtResource("1_7kndb")
-Beat = 48.0
+Beat = 52.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_6oq4l"]
+[sub_resource type="Resource" id="Resource_hrafv"]
script = ExtResource("1_7kndb")
-Beat = 50.0
+Beat = 61.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_s8y6q"]
+[sub_resource type="Resource" id="Resource_d50tw"]
script = ExtResource("1_7kndb")
-Beat = 53.0
+Beat = 4.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_pdfmt"]
+[sub_resource type="Resource" id="Resource_a8amf"]
script = ExtResource("1_7kndb")
-Beat = 59.0
+Beat = 44.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_lkwp6"]
+[sub_resource type="Resource" id="Resource_mbtm7"]
script = ExtResource("1_7kndb")
-Beat = 9.0
+Beat = 12.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_sd1fo"]
+[sub_resource type="Resource" id="Resource_ynh6c"]
script = ExtResource("1_7kndb")
-Beat = 12.0
+Beat = 28.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_marsf"]
+script = ExtResource("1_7kndb")
+Beat = 33.0
Length = 0.0
[sub_resource type="Resource" id="Resource_wkvcn"]
@@ -108,119 +98,134 @@ script = ExtResource("1_7kndb")
Beat = 24.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_8sl4t"]
+[sub_resource type="Resource" id="Resource_1qfq5"]
script = ExtResource("1_7kndb")
-Beat = 29.0
+Beat = 56.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_j8ilf"]
+[sub_resource type="Resource" id="Resource_ywfrj"]
script = ExtResource("1_7kndb")
-Beat = 45.0
+Beat = 60.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_14d3f"]
+[sub_resource type="Resource" id="Resource_rxusk"]
script = ExtResource("1_7kndb")
-Beat = 53.0
+Beat = 8.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_1qfq5"]
+[sub_resource type="Resource" id="Resource_r88cj"]
script = ExtResource("1_7kndb")
-Beat = 56.0
+Beat = 36.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_v0l44"]
+[sub_resource type="Resource" id="Resource_5e2go"]
script = ExtResource("1_7kndb")
-Beat = 59.0
+Beat = 50.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_ywfrj"]
+[sub_resource type="Resource" id="Resource_s083v"]
script = ExtResource("1_7kndb")
-Beat = 60.0
+Beat = 40.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_jc0cy"]
+script = ExtResource("1_7kndb")
+Beat = 52.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_3oete"]
+script = ExtResource("1_7kndb")
+Beat = 61.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_0m2gd"]
+[sub_resource type="Resource" id="Resource_b24fs"]
script = ExtResource("1_7kndb")
Beat = 5.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_yjy3y"]
+[sub_resource type="Resource" id="Resource_45x0b"]
script = ExtResource("1_7kndb")
-Beat = 12.0
+Beat = 33.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_31o0y"]
+[sub_resource type="Resource" id="Resource_x70wl"]
script = ExtResource("1_7kndb")
-Beat = 16.0
+Beat = 45.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_ismkv"]
+[sub_resource type="Resource" id="Resource_6e30o"]
script = ExtResource("1_7kndb")
-Beat = 23.0
+Beat = 29.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_jkqwb"]
+[sub_resource type="Resource" id="Resource_8l6ei"]
script = ExtResource("1_7kndb")
-Beat = 27.0
+Beat = 32.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_k1pbh"]
+[sub_resource type="Resource" id="Resource_31o0y"]
script = ExtResource("1_7kndb")
-Beat = 35.0
+Beat = 16.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_0nv8p"]
+[sub_resource type="Resource" id="Resource_2wwc7"]
script = ExtResource("1_7kndb")
-Beat = 39.0
+Beat = 56.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_bskfl"]
+[sub_resource type="Resource" id="Resource_m5e6q"]
script = ExtResource("1_7kndb")
-Beat = 42.0
+Beat = 24.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_8cd7v"]
+[sub_resource type="Resource" id="Resource_v8sin"]
script = ExtResource("1_7kndb")
-Beat = 47.0
+Beat = 38.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_4giuv"]
+[sub_resource type="Resource" id="Resource_ykqor"]
script = ExtResource("1_7kndb")
-Beat = 52.0
+Beat = 48.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_2wwc7"]
+[sub_resource type="Resource" id="Resource_cbmdd"]
script = ExtResource("1_7kndb")
-Beat = 56.0
+Beat = 34.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_y6l23"]
+[sub_resource type="Resource" id="Resource_ak0tp"]
script = ExtResource("1_7kndb")
-Beat = 62.0
+Beat = 40.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_wc7xs"]
+[sub_resource type="Resource" id="Resource_pd2wi"]
script = ExtResource("1_7kndb")
-Beat = 5.0
+Beat = 53.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_k53ay"]
+[sub_resource type="Resource" id="Resource_11m2d"]
script = ExtResource("1_7kndb")
-Beat = 11.0
+Beat = 3.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_blbm2"]
+[sub_resource type="Resource" id="Resource_7totf"]
script = ExtResource("1_7kndb")
-Beat = 13.0
+Beat = 8.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_3gjtl"]
+[sub_resource type="Resource" id="Resource_ob06q"]
script = ExtResource("1_7kndb")
-Beat = 19.0
+Beat = 45.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_s6r1b"]
+script = ExtResource("1_7kndb")
+Beat = 29.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_mi50b"]
+[sub_resource type="Resource" id="Resource_3gjtl"]
script = ExtResource("1_7kndb")
-Beat = 23.0
+Beat = 19.0
Length = 0.0
[sub_resource type="Resource" id="Resource_vdnsu"]
@@ -228,54 +233,64 @@ script = ExtResource("1_7kndb")
Beat = 25.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_1xwp0"]
+[sub_resource type="Resource" id="Resource_3wyug"]
script = ExtResource("1_7kndb")
-Beat = 32.0
+Beat = 51.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_ybe5s"]
+[sub_resource type="Resource" id="Resource_6kji1"]
script = ExtResource("1_7kndb")
-Beat = 36.0
+Beat = 60.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_wd1lo"]
+[sub_resource type="Resource" id="Resource_w6jqv"]
script = ExtResource("1_7kndb")
-Beat = 40.0
+Beat = 54.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_eotyn"]
+[sub_resource type="Resource" id="Resource_083mg"]
script = ExtResource("1_7kndb")
-Beat = 44.0
+Beat = 37.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_3wyug"]
+[sub_resource type="Resource" id="Resource_dsf4k"]
script = ExtResource("1_7kndb")
-Beat = 51.0
+Beat = 57.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_77c6u"]
+[sub_resource type="Resource" id="Resource_2woca"]
script = ExtResource("1_7kndb")
-Beat = 55.0
+Beat = 41.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_811fa"]
+[sub_resource type="Resource" id="Resource_jsj5h"]
script = ExtResource("1_7kndb")
-Beat = 57.0
+Beat = 6.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_6kji1"]
+[sub_resource type="Resource" id="Resource_qoqm3"]
script = ExtResource("1_7kndb")
-Beat = 60.0
+Beat = 32.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_nob8r"]
+script = ExtResource("1_7kndb")
+Beat = 44.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_a6epf"]
+script = ExtResource("1_7kndb")
+Beat = 12.0
Length = 0.0
-[sub_resource type="Resource" id="Resource_tdwrl"]
+[sub_resource type="Resource" id="Resource_ekjhc"]
script = ExtResource("1_7kndb")
-Beat = 63.0
+Beat = 28.0
Length = 0.0
[resource]
script = ExtResource("2_xg88o")
-UpLaneData = [SubResource("Resource_wc7xs"), SubResource("Resource_k53ay"), SubResource("Resource_blbm2"), SubResource("Resource_3gjtl"), SubResource("Resource_mi50b"), SubResource("Resource_vdnsu"), SubResource("Resource_1xwp0"), SubResource("Resource_ybe5s"), SubResource("Resource_wd1lo"), SubResource("Resource_eotyn"), SubResource("Resource_3wyug"), SubResource("Resource_77c6u"), SubResource("Resource_811fa"), SubResource("Resource_6kji1"), SubResource("Resource_tdwrl")]
-DownLaneData = [SubResource("Resource_7kndb"), SubResource("Resource_xg88o"), SubResource("Resource_g8421"), SubResource("Resource_11qbm"), SubResource("Resource_hrrtc"), SubResource("Resource_rmog3"), SubResource("Resource_tnqsp"), SubResource("Resource_6n6ig"), SubResource("Resource_ci2g3"), SubResource("Resource_2c17a"), SubResource("Resource_gugsw"), SubResource("Resource_j4ixp"), SubResource("Resource_i2oko"), SubResource("Resource_6oq4l"), SubResource("Resource_s8y6q"), SubResource("Resource_pdfmt")]
-LeftLaneData = [SubResource("Resource_lkwp6"), SubResource("Resource_sd1fo"), SubResource("Resource_wkvcn"), SubResource("Resource_woki6"), SubResource("Resource_gm3ao"), SubResource("Resource_8sl4t"), SubResource("Resource_j8ilf"), SubResource("Resource_14d3f"), SubResource("Resource_1qfq5"), SubResource("Resource_v0l44"), SubResource("Resource_ywfrj")]
-RightLaneData = [SubResource("Resource_0m2gd"), SubResource("Resource_yjy3y"), SubResource("Resource_31o0y"), SubResource("Resource_ismkv"), SubResource("Resource_jkqwb"), SubResource("Resource_k1pbh"), SubResource("Resource_0nv8p"), SubResource("Resource_bskfl"), SubResource("Resource_8cd7v"), SubResource("Resource_4giuv"), SubResource("Resource_2wwc7"), SubResource("Resource_y6l23")]
+UpLaneData = [SubResource("Resource_3gjtl"), SubResource("Resource_vdnsu"), SubResource("Resource_3wyug"), SubResource("Resource_6kji1"), SubResource("Resource_w6jqv"), SubResource("Resource_083mg"), SubResource("Resource_dsf4k"), SubResource("Resource_2woca"), SubResource("Resource_jsj5h"), SubResource("Resource_qoqm3"), SubResource("Resource_nob8r"), SubResource("Resource_a6epf"), SubResource("Resource_ekjhc")]
+DownLaneData = [SubResource("Resource_11qbm"), SubResource("Resource_hrrtc"), SubResource("Resource_rmog3"), SubResource("Resource_tnqsp"), SubResource("Resource_fldsc"), SubResource("Resource_ntp27"), SubResource("Resource_7nmxt"), SubResource("Resource_47jch"), SubResource("Resource_kp5f0"), SubResource("Resource_v8s33"), SubResource("Resource_hrafv"), SubResource("Resource_d50tw"), SubResource("Resource_a8amf"), SubResource("Resource_mbtm7"), SubResource("Resource_ynh6c"), SubResource("Resource_marsf")]
+LeftLaneData = [SubResource("Resource_wkvcn"), SubResource("Resource_woki6"), SubResource("Resource_gm3ao"), SubResource("Resource_1qfq5"), SubResource("Resource_ywfrj"), SubResource("Resource_rxusk"), SubResource("Resource_r88cj"), SubResource("Resource_5e2go"), SubResource("Resource_s083v"), SubResource("Resource_jc0cy"), SubResource("Resource_3oete"), SubResource("Resource_b24fs"), SubResource("Resource_45x0b"), SubResource("Resource_x70wl"), SubResource("Resource_6e30o"), SubResource("Resource_8l6ei")]
+RightLaneData = [SubResource("Resource_31o0y"), SubResource("Resource_2wwc7"), SubResource("Resource_m5e6q"), SubResource("Resource_v8sin"), SubResource("Resource_ykqor"), SubResource("Resource_cbmdd"), SubResource("Resource_ak0tp"), SubResource("Resource_pd2wi"), SubResource("Resource_11m2d"), SubResource("Resource_7totf"), SubResource("Resource_ob06q"), SubResource("Resource_s6r1b")]
diff --git a/Audio/songMaps/Spider.tres b/Audio/songMaps/Spider.tres
new file mode 100644
index 00000000..7e666dc5
--- /dev/null
+++ b/Audio/songMaps/Spider.tres
@@ -0,0 +1,141 @@
+[gd_resource type="Resource" load_steps=29 format=3]
+
+[ext_resource type="Script" path="res://Classes/MidiMaestro/NoteInfo.cs" id="1_kilos"]
+[ext_resource type="Script" path="res://Classes/MidiMaestro/NoteChart.cs" id="2_ojgcg"]
+
+[sub_resource type="Resource" id="Resource_kilos"]
+script = ExtResource("1_kilos")
+Beat = 6.0
+Length = 3.0
+
+[sub_resource type="Resource" id="Resource_ojgcg"]
+script = ExtResource("1_kilos")
+Beat = 19.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_e2i3v"]
+script = ExtResource("1_kilos")
+Beat = 32.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_bxgte"]
+script = ExtResource("1_kilos")
+Beat = 38.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_7c41j"]
+script = ExtResource("1_kilos")
+Beat = 56.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_ibasm"]
+script = ExtResource("1_kilos")
+Beat = 57.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_57q1g"]
+script = ExtResource("1_kilos")
+Beat = 58.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_5kf2q"]
+script = ExtResource("1_kilos")
+Beat = 9.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_klick"]
+script = ExtResource("1_kilos")
+Beat = 3.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_ncgpb"]
+script = ExtResource("1_kilos")
+Beat = 70.0
+Length = 2.0
+
+[sub_resource type="Resource" id="Resource_58gsr"]
+script = ExtResource("1_kilos")
+Beat = 17.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_cuxey"]
+script = ExtResource("1_kilos")
+Beat = 27.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_uqtyg"]
+script = ExtResource("1_kilos")
+Beat = 47.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_8wxpt"]
+script = ExtResource("1_kilos")
+Beat = 64.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_7xcdg"]
+script = ExtResource("1_kilos")
+Beat = 65.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_erw8g"]
+script = ExtResource("1_kilos")
+Beat = 44.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_ka8yr"]
+script = ExtResource("1_kilos")
+Beat = 12.0
+Length = 3.0
+
+[sub_resource type="Resource" id="Resource_8jxfc"]
+script = ExtResource("1_kilos")
+Beat = 22.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_al1ha"]
+script = ExtResource("1_kilos")
+Beat = 27.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_heg8m"]
+script = ExtResource("1_kilos")
+Beat = 38.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_j42ns"]
+script = ExtResource("1_kilos")
+Beat = 44.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_kihon"]
+script = ExtResource("1_kilos")
+Beat = 3.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_j43rp"]
+script = ExtResource("1_kilos")
+Beat = 31.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_3j8yo"]
+script = ExtResource("1_kilos")
+Beat = 17.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_vk213"]
+script = ExtResource("1_kilos")
+Beat = 47.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_dsydf"]
+script = ExtResource("1_kilos")
+Beat = 54.0
+Length = 0.0
+
+[resource]
+script = ExtResource("2_ojgcg")
+UpLaneData = Array[ExtResource("1_kilos")]([SubResource("Resource_j42ns"), SubResource("Resource_kihon"), SubResource("Resource_j43rp"), SubResource("Resource_3j8yo"), SubResource("Resource_vk213"), SubResource("Resource_dsydf")])
+DownLaneData = Array[ExtResource("1_kilos")]([SubResource("Resource_kilos"), SubResource("Resource_ojgcg"), SubResource("Resource_e2i3v"), SubResource("Resource_bxgte"), SubResource("Resource_7c41j"), SubResource("Resource_ibasm"), SubResource("Resource_57q1g")])
+LeftLaneData = Array[ExtResource("1_kilos")]([SubResource("Resource_5kf2q"), SubResource("Resource_klick"), SubResource("Resource_ncgpb"), SubResource("Resource_58gsr"), SubResource("Resource_cuxey"), SubResource("Resource_uqtyg"), SubResource("Resource_8wxpt"), SubResource("Resource_7xcdg")])
+RightLaneData = Array[ExtResource("1_kilos")]([SubResource("Resource_erw8g"), SubResource("Resource_ka8yr"), SubResource("Resource_8jxfc"), SubResource("Resource_al1ha"), SubResource("Resource_heg8m")])
diff --git a/Audio/songMaps/SquirkelSong.tres b/Audio/songMaps/SquirkelSong.tres
new file mode 100644
index 00000000..ff14f0c3
--- /dev/null
+++ b/Audio/songMaps/SquirkelSong.tres
@@ -0,0 +1,91 @@
+[gd_resource type="Resource" load_steps=19 format=3]
+
+[ext_resource type="Script" path="res://Classes/MidiMaestro/NoteInfo.cs" id="1_8ueh4"]
+[ext_resource type="Script" path="res://Classes/MidiMaestro/NoteChart.cs" id="2_s63u8"]
+
+[sub_resource type="Resource" id="Resource_ljr32"]
+script = ExtResource("1_8ueh4")
+Beat = 2.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_bb3yp"]
+script = ExtResource("1_8ueh4")
+Beat = 5.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_852ml"]
+script = ExtResource("1_8ueh4")
+Beat = 10.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_38nu8"]
+script = ExtResource("1_8ueh4")
+Beat = 15.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_3eydr"]
+script = ExtResource("1_8ueh4")
+Beat = 21.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_ct6sp"]
+script = ExtResource("1_8ueh4")
+Beat = 24.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_yk705"]
+script = ExtResource("1_8ueh4")
+Beat = 29.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_oocdv"]
+script = ExtResource("1_8ueh4")
+Beat = 34.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_uswjw"]
+script = ExtResource("1_8ueh4")
+Beat = 6.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_e1hbr"]
+script = ExtResource("1_8ueh4")
+Beat = 11.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_gryrv"]
+script = ExtResource("1_8ueh4")
+Beat = 25.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_kwtfb"]
+script = ExtResource("1_8ueh4")
+Beat = 30.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_c2bxv"]
+script = ExtResource("1_8ueh4")
+Beat = 16.0
+Length = 2.0
+
+[sub_resource type="Resource" id="Resource_7lpnw"]
+script = ExtResource("1_8ueh4")
+Beat = 35.0
+Length = 2.0
+
+[sub_resource type="Resource" id="Resource_50tbs"]
+script = ExtResource("1_8ueh4")
+Beat = 2.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_ttd2q"]
+script = ExtResource("1_8ueh4")
+Beat = 21.0
+Length = 0.0
+
+[resource]
+script = ExtResource("2_s63u8")
+UpLaneData = Array[ExtResource("1_8ueh4")]([SubResource("Resource_50tbs"), SubResource("Resource_ttd2q")])
+DownLaneData = Array[ExtResource("1_8ueh4")]([SubResource("Resource_ljr32"), SubResource("Resource_bb3yp"), SubResource("Resource_852ml"), SubResource("Resource_38nu8"), SubResource("Resource_3eydr"), SubResource("Resource_ct6sp"), SubResource("Resource_yk705"), SubResource("Resource_oocdv")])
+LeftLaneData = Array[ExtResource("1_8ueh4")]([])
+RightLaneData = Array[ExtResource("1_8ueh4")]([SubResource("Resource_uswjw"), SubResource("Resource_e1hbr"), SubResource("Resource_gryrv"), SubResource("Resource_kwtfb"), SubResource("Resource_c2bxv"), SubResource("Resource_7lpnw")])
diff --git a/Audio/songMaps/TutorialBoss176_7.tres b/Audio/songMaps/TutorialBoss176_7.tres
new file mode 100644
index 00000000..b90c3588
--- /dev/null
+++ b/Audio/songMaps/TutorialBoss176_7.tres
@@ -0,0 +1,296 @@
+[gd_resource type="Resource" load_steps=60 format=3]
+
+[ext_resource type="Script" path="res://Classes/MidiMaestro/NoteInfo.cs" id="1_w1u0b"]
+[ext_resource type="Script" path="res://Classes/MidiMaestro/NoteChart.cs" id="2_gbai3"]
+
+[sub_resource type="Resource" id="Resource_sxt82"]
+script = ExtResource("1_w1u0b")
+Beat = 64.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_j5ca6"]
+script = ExtResource("1_w1u0b")
+Beat = 72.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_cfyig"]
+script = ExtResource("1_w1u0b")
+Beat = 48.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_oq2fs"]
+script = ExtResource("1_w1u0b")
+Beat = 16.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_bv13m"]
+script = ExtResource("1_w1u0b")
+Beat = 17.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_lg6ov"]
+script = ExtResource("1_w1u0b")
+Beat = 40.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_eg7rs"]
+script = ExtResource("1_w1u0b")
+Beat = 33.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_x3k65"]
+script = ExtResource("1_w1u0b")
+Beat = 41.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_d5g7d"]
+script = ExtResource("1_w1u0b")
+Beat = 56.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_1cpsm"]
+script = ExtResource("1_w1u0b")
+Beat = 28.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_giltv"]
+script = ExtResource("1_w1u0b")
+Beat = 86.0
+Length = 2.0
+
+[sub_resource type="Resource" id="Resource_oqa5e"]
+script = ExtResource("1_w1u0b")
+Beat = 32.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_kk6vq"]
+script = ExtResource("1_w1u0b")
+Beat = 48.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_3scxn"]
+script = ExtResource("1_w1u0b")
+Beat = 33.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_p5ohh"]
+script = ExtResource("1_w1u0b")
+Beat = 41.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_dxorp"]
+script = ExtResource("1_w1u0b")
+Beat = 57.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_pm5wf"]
+script = ExtResource("1_w1u0b")
+Beat = 80.0
+Length = 2.0
+
+[sub_resource type="Resource" id="Resource_biar7"]
+script = ExtResource("1_w1u0b")
+Beat = 28.0
+Length = 2.0
+
+[sub_resource type="Resource" id="Resource_bnjg0"]
+script = ExtResource("1_w1u0b")
+Beat = 87.0
+Length = 2.0
+
+[sub_resource type="Resource" id="Resource_7gvq1"]
+script = ExtResource("1_w1u0b")
+Beat = 49.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_pgga6"]
+script = ExtResource("1_w1u0b")
+Beat = 63.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_gr1jk"]
+script = ExtResource("1_w1u0b")
+Beat = 40.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_w2pru"]
+script = ExtResource("1_w1u0b")
+Beat = 70.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_wgekv"]
+script = ExtResource("1_w1u0b")
+Beat = 71.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_qsagv"]
+script = ExtResource("1_w1u0b")
+Beat = 32.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_gmjq8"]
+script = ExtResource("1_w1u0b")
+Beat = 33.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_35mcn"]
+script = ExtResource("1_w1u0b")
+Beat = 49.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_pwkkg"]
+script = ExtResource("1_w1u0b")
+Beat = 56.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_gks01"]
+script = ExtResource("1_w1u0b")
+Beat = 57.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_vp8wv"]
+script = ExtResource("1_w1u0b")
+Beat = 79.0
+Length = 3.0
+
+[sub_resource type="Resource" id="Resource_ur61o"]
+script = ExtResource("1_w1u0b")
+Beat = 18.0
+Length = 2.0
+
+[sub_resource type="Resource" id="Resource_71lt2"]
+script = ExtResource("1_w1u0b")
+Beat = 26.0
+Length = 2.0
+
+[sub_resource type="Resource" id="Resource_w1u0b"]
+script = ExtResource("1_w1u0b")
+Beat = 8.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_gbai3"]
+script = ExtResource("1_w1u0b")
+Beat = 9.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_bcwc6"]
+script = ExtResource("1_w1u0b")
+Beat = 16.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_0k2f6"]
+script = ExtResource("1_w1u0b")
+Beat = 17.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_tgoco"]
+script = ExtResource("1_w1u0b")
+Beat = 24.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_x1j4d"]
+script = ExtResource("1_w1u0b")
+Beat = 25.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_e76xg"]
+script = ExtResource("1_w1u0b")
+Beat = 32.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_vhygb"]
+script = ExtResource("1_w1u0b")
+Beat = 40.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_unq76"]
+script = ExtResource("1_w1u0b")
+Beat = 41.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_cn75w"]
+script = ExtResource("1_w1u0b")
+Beat = 48.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_3pobr"]
+script = ExtResource("1_w1u0b")
+Beat = 49.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_43v1q"]
+script = ExtResource("1_w1u0b")
+Beat = 56.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_2i0ix"]
+script = ExtResource("1_w1u0b")
+Beat = 57.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_eo1b6"]
+script = ExtResource("1_w1u0b")
+Beat = 64.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_ehfsr"]
+script = ExtResource("1_w1u0b")
+Beat = 65.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_05gdy"]
+script = ExtResource("1_w1u0b")
+Beat = 72.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_b164v"]
+script = ExtResource("1_w1u0b")
+Beat = 73.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_86j1n"]
+script = ExtResource("1_w1u0b")
+Beat = 80.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_p6bp3"]
+script = ExtResource("1_w1u0b")
+Beat = 81.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_7erhr"]
+script = ExtResource("1_w1u0b")
+Beat = 88.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_n6xrx"]
+script = ExtResource("1_w1u0b")
+Beat = 89.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_75ujr"]
+script = ExtResource("1_w1u0b")
+Beat = 96.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_mlxr3"]
+script = ExtResource("1_w1u0b")
+Beat = 97.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_5vw1o"]
+script = ExtResource("1_w1u0b")
+Beat = 29.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_suuru"]
+script = ExtResource("1_w1u0b")
+Beat = 30.0
+Length = 0.0
+
+[resource]
+script = ExtResource("2_gbai3")
+UpLaneData = Array[ExtResource("1_w1u0b")]([SubResource("Resource_w1u0b"), SubResource("Resource_gbai3"), SubResource("Resource_bcwc6"), SubResource("Resource_0k2f6"), SubResource("Resource_tgoco"), SubResource("Resource_x1j4d"), SubResource("Resource_e76xg"), SubResource("Resource_vhygb"), SubResource("Resource_unq76"), SubResource("Resource_cn75w"), SubResource("Resource_3pobr"), SubResource("Resource_43v1q"), SubResource("Resource_2i0ix"), SubResource("Resource_eo1b6"), SubResource("Resource_ehfsr"), SubResource("Resource_05gdy"), SubResource("Resource_b164v"), SubResource("Resource_86j1n"), SubResource("Resource_p6bp3"), SubResource("Resource_7erhr"), SubResource("Resource_n6xrx"), SubResource("Resource_75ujr"), SubResource("Resource_mlxr3"), SubResource("Resource_5vw1o"), SubResource("Resource_suuru")])
+DownLaneData = Array[ExtResource("1_w1u0b")]([SubResource("Resource_sxt82"), SubResource("Resource_j5ca6"), SubResource("Resource_cfyig"), SubResource("Resource_oq2fs"), SubResource("Resource_bv13m"), SubResource("Resource_lg6ov"), SubResource("Resource_eg7rs"), SubResource("Resource_x3k65"), SubResource("Resource_d5g7d"), SubResource("Resource_1cpsm"), SubResource("Resource_giltv")])
+LeftLaneData = Array[ExtResource("1_w1u0b")]([SubResource("Resource_oqa5e"), SubResource("Resource_kk6vq"), SubResource("Resource_3scxn"), SubResource("Resource_p5ohh"), SubResource("Resource_dxorp"), SubResource("Resource_pm5wf"), SubResource("Resource_biar7"), SubResource("Resource_bnjg0"), SubResource("Resource_7gvq1")])
+RightLaneData = Array[ExtResource("1_w1u0b")]([SubResource("Resource_pgga6"), SubResource("Resource_gr1jk"), SubResource("Resource_w2pru"), SubResource("Resource_wgekv"), SubResource("Resource_qsagv"), SubResource("Resource_gmjq8"), SubResource("Resource_35mcn"), SubResource("Resource_pwkkg"), SubResource("Resource_gks01"), SubResource("Resource_vp8wv"), SubResource("Resource_ur61o"), SubResource("Resource_71lt2")])
diff --git a/Audio/songMaps/TutorialSong.tres b/Audio/songMaps/TutorialSong.tres
new file mode 100644
index 00000000..a24d6ee3
--- /dev/null
+++ b/Audio/songMaps/TutorialSong.tres
@@ -0,0 +1,111 @@
+[gd_resource type="Resource" load_steps=23 format=3 uid="uid://1ag6pnhqf2v1"]
+
+[ext_resource type="Script" uid="uid://bhbpcmtr6e6pk" path="res://Classes/MidiMaestro/NoteInfo.cs" id="1_roxhp"]
+[ext_resource type="Script" uid="uid://bnpnavb5lwobj" path="res://Classes/MidiMaestro/NoteChart.cs" id="2_bsw0b"]
+
+[sub_resource type="Resource" id="Resource_a0ovt"]
+script = ExtResource("1_roxhp")
+Beat = 3.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_ahash"]
+script = ExtResource("1_roxhp")
+Beat = 7.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_6gc2p"]
+script = ExtResource("1_roxhp")
+Beat = 11.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_tjsh3"]
+script = ExtResource("1_roxhp")
+Beat = 15.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_s18ys"]
+script = ExtResource("1_roxhp")
+Beat = 17.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_wcsgu"]
+script = ExtResource("1_roxhp")
+Beat = 21.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_r81qg"]
+script = ExtResource("1_roxhp")
+Beat = 25.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_roxhp"]
+script = ExtResource("1_roxhp")
+Beat = 29.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_ifw8a"]
+script = ExtResource("1_roxhp")
+Beat = 18.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_d0m6p"]
+script = ExtResource("1_roxhp")
+Beat = 22.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_owwlp"]
+script = ExtResource("1_roxhp")
+Beat = 26.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_bnbk2"]
+script = ExtResource("1_roxhp")
+Beat = 2.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_t2mc0"]
+script = ExtResource("1_roxhp")
+Beat = 6.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_xl4h8"]
+script = ExtResource("1_roxhp")
+Beat = 10.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_7i220"]
+script = ExtResource("1_roxhp")
+Beat = 14.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_txc3y"]
+script = ExtResource("1_roxhp")
+Beat = 16.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_iixj3"]
+script = ExtResource("1_roxhp")
+Beat = 20.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_5o1tj"]
+script = ExtResource("1_roxhp")
+Beat = 24.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_l3ivu"]
+script = ExtResource("1_roxhp")
+Beat = 28.0
+Length = 0.0
+
+[sub_resource type="Resource" id="Resource_d6d5y"]
+script = ExtResource("1_roxhp")
+Beat = 30.0
+Length = 0.0
+
+[resource]
+script = ExtResource("2_bsw0b")
+UpLaneData = Array[ExtResource("1_roxhp")]([SubResource("Resource_bnbk2"), SubResource("Resource_t2mc0"), SubResource("Resource_xl4h8"), SubResource("Resource_7i220"), SubResource("Resource_txc3y"), SubResource("Resource_iixj3"), SubResource("Resource_5o1tj"), SubResource("Resource_l3ivu"), SubResource("Resource_d6d5y")])
+DownLaneData = Array[ExtResource("1_roxhp")]([SubResource("Resource_a0ovt"), SubResource("Resource_ahash"), SubResource("Resource_6gc2p"), SubResource("Resource_tjsh3"), SubResource("Resource_s18ys"), SubResource("Resource_wcsgu"), SubResource("Resource_r81qg"), SubResource("Resource_roxhp")])
+LeftLaneData = Array[ExtResource("1_roxhp")]([SubResource("Resource_ifw8a"), SubResource("Resource_d0m6p"), SubResource("Resource_owwlp")])
+RightLaneData = Array[ExtResource("1_roxhp")]([])
diff --git a/Classes/Events/Assets/Bandit_Event.png b/Classes/Events/Assets/Bandit_Event.png
new file mode 100644
index 00000000..05a8b1d8
Binary files /dev/null and b/Classes/Events/Assets/Bandit_Event.png differ
diff --git a/Classes/Events/Assets/Bandit_Event.png.import b/Classes/Events/Assets/Bandit_Event.png.import
new file mode 100644
index 00000000..6d60eea8
--- /dev/null
+++ b/Classes/Events/Assets/Bandit_Event.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://b5q4cwqf7rc4n"
+path="res://.godot/imported/Bandit_Event.png-6288df62bc6a82f737688f5cf0ebba45.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Classes/Events/Assets/Bandit_Event.png"
+dest_files=["res://.godot/imported/Bandit_Event.png-6288df62bc6a82f737688f5cf0ebba45.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/Classes/Events/Assets/Event2.png b/Classes/Events/Assets/Event2.png
new file mode 100644
index 00000000..9d3bc2e9
Binary files /dev/null and b/Classes/Events/Assets/Event2.png differ
diff --git a/Classes/Events/Assets/Event2.png.import b/Classes/Events/Assets/Event2.png.import
new file mode 100644
index 00000000..ddda9671
--- /dev/null
+++ b/Classes/Events/Assets/Event2.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cex5vg2ycajdi"
+path="res://.godot/imported/Event2.png-a647bc6675ac54fecafbb5f9d56de04d.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Classes/Events/Assets/Event2.png"
+dest_files=["res://.godot/imported/Event2.png-a647bc6675ac54fecafbb5f9d56de04d.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/Classes/Events/Assets/Medic_Event.png b/Classes/Events/Assets/Medic_Event.png
new file mode 100644
index 00000000..8612ce9d
Binary files /dev/null and b/Classes/Events/Assets/Medic_Event.png differ
diff --git a/Classes/Events/Assets/Medic_Event.png.import b/Classes/Events/Assets/Medic_Event.png.import
new file mode 100644
index 00000000..689ed8e6
--- /dev/null
+++ b/Classes/Events/Assets/Medic_Event.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cmyd7qy1l7pol"
+path="res://.godot/imported/Medic_Event.png-a54756901f127625c3d51a1841c6c64e.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Classes/Events/Assets/Medic_Event.png"
+dest_files=["res://.godot/imported/Medic_Event.png-a54756901f127625c3d51a1841c6c64e.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/Classes/Events/EventDatabase.cs b/Classes/Events/EventDatabase.cs
new file mode 100644
index 00000000..5a869ebd
--- /dev/null
+++ b/Classes/Events/EventDatabase.cs
@@ -0,0 +1,155 @@
+using System;
+using Godot;
+
+///
+/// Holds all game events and their associated logic.
+///
+public class EventDatabase
+{
+ public const int EventDatabaseSize = 3;
+
+ public static readonly EventTemplate[] EventDictionary = new[]
+ {
+ new EventTemplate(
+ 0,
+ "EVENT_EVENT1_DESC",
+ ["EVENT_EVENT1_OPTION1", "EVENT_EVENT1_OPTION2", "EVENT_EVENT1_OPTION3"],
+ ["EVENT_EVENT1_OUTCOME1", "EVENT_EVENT1_OUTCOME2", "EVENT_EVENT1_OUTCOME3"],
+ [
+ (self, node) =>
+ {
+ int randIndex = StageProducer.GlobalRng.RandiRange(
+ 0,
+ StageProducer.PlayerStats.CurNotes.Length - 1
+ );
+ StageProducer.PlayerStats.RemoveNote(randIndex);
+ },
+ (self, node) =>
+ {
+ int randIndex = StageProducer.GlobalRng.RandiRange(
+ 0,
+ StageProducer.PlayerStats.CurRelics.Length - 1
+ );
+ StageProducer.PlayerStats.RemoveRelic(randIndex);
+ },
+ (self, node) =>
+ {
+ StageProducer.PlayerStats.Money /= 2;
+ },
+ ],
+ GD.Load("res://Classes/Events/Assets/Bandit_Event.png"),
+ [
+ () => StageProducer.PlayerStats.CurNotes.Length > 0,
+ () => StageProducer.PlayerStats.CurRelics.Length > 0,
+ () => StageProducer.PlayerStats.Money > 0,
+ ]
+ ),
+ new EventTemplate(
+ 1,
+ "EVENT_EVENT2_DESC",
+ ["EVENT_EVENT2_OPTION1", "EVENT_EVENT2_OPTION2"],
+ ["", "EVENT_EVENT2_OUTCOME1"],
+ [
+ (self, node) =>
+ {
+ var spinner = node.EventSprite;
+ int spinOutcome = StageProducer.GlobalRng.RandiRange(0, 5);
+
+ int outcomeCount = 6;
+ float sectorAngle = 360f / outcomeCount;
+ float targetAngle = spinOutcome * sectorAngle;
+ float fullSpins = 6 * 360f;
+ float finalRotation = spinner.RotationDegrees % 360f + fullSpins + targetAngle;
+
+ var tween = node.CreateTween();
+ tween
+ .TweenProperty(spinner, "rotation_degrees", finalRotation, 2.5f)
+ .SetTrans(Tween.TransitionType.Cubic)
+ .SetEase(Tween.EaseType.Out);
+
+ // Defer execution of the outcome until the tween finishes
+ tween.TweenCallback(
+ Callable.From(() =>
+ {
+ switch (spinOutcome)
+ {
+ case 0:
+ StageProducer.PlayerStats.Money /= 2;
+ self.OutcomeDescriptions[0] = "EVENT_EVENT2_OUTCOME2";
+ break;
+ case 1:
+ self.OutcomeDescriptions[0] = "EVENT_EVENT2_OUTCOME3";
+ StageProducer.PlayerStats.CurrentHealth = Math.Max(
+ 1,
+ StageProducer.PlayerStats.CurrentHealth - 10
+ );
+ break;
+ case 2:
+ self.OutcomeDescriptions[0] = "EVENT_EVENT2_OUTCOME4";
+ StageProducer.PlayerStats.Money += 50;
+ break;
+ case 3:
+ self.OutcomeDescriptions[0] = "EVENT_EVENT2_OUTCOME5";
+ StageProducer.PlayerStats.AddNote(
+ Scribe.GetRandomRewardNotes(1, StageProducer.CurRoom + 10)[
+ 0
+ ]
+ );
+ break;
+ case 4:
+ self.OutcomeDescriptions[0] = "EVENT_EVENT2_OUTCOME6";
+ StageProducer.PlayerStats.AddRelic(
+ Scribe.GetRandomRelics(
+ 1,
+ StageProducer.CurRoom + 10,
+ StageProducer.PlayerStats.RarityOdds
+ )[0]
+ );
+ break;
+ case 5:
+ self.OutcomeDescriptions[0] = "EVENT_EVENT2_OUTCOME7";
+ StageProducer.PlayerStats.CurrentHealth = Math.Min(
+ StageProducer.PlayerStats.CurrentHealth + 20,
+ StageProducer.PlayerStats.MaxHealth
+ );
+ break;
+ }
+ node.AnyButtonPressed(0);
+ self.OutcomeDescriptions[0] = ""; //Will need to fix later, currently changes the primary reference
+ })
+ );
+ },
+ null,
+ ],
+ GD.Load("res://Classes/Events/Assets/Event2.png"),
+ [null, null]
+ ),
+ new EventTemplate(
+ 2,
+ "EVENT_EVENT3_DESC",
+ ["EVENT_EVENT3_OPTION1", "EVENT_EVENT3_OPTION2", "EVENT_EVENT3_OPTION3"],
+ ["EVENT_EVENT3_OUTCOME1", "EVENT_EVENT3_OUTCOME2", "EVENT_EVENT3_OUTCOME3"],
+ [
+ (self, node) =>
+ {
+ StageProducer.PlayerStats.CurrentHealth = Math.Min(
+ StageProducer.PlayerStats.CurrentHealth + 10,
+ StageProducer.PlayerStats.MaxHealth
+ );
+ },
+ (self, node) =>
+ {
+ StageProducer.PlayerStats.MaxComboBar -= 5;
+ },
+ (self, node) =>
+ {
+ StageProducer.PlayerStats.Money -= 30;
+ StageProducer.PlayerStats.AddNote(Scribe.NoteDictionary[3]);
+ StageProducer.PlayerStats.AddNote(Scribe.NoteDictionary[3]);
+ },
+ ],
+ GD.Load("res://Classes/Events/Assets/Medic_Event.png"),
+ [null, null, () => StageProducer.PlayerStats.Money >= 30]
+ ),
+ };
+}
diff --git a/Classes/Events/EventDatabase.cs.uid b/Classes/Events/EventDatabase.cs.uid
new file mode 100644
index 00000000..df77bf1c
--- /dev/null
+++ b/Classes/Events/EventDatabase.cs.uid
@@ -0,0 +1 @@
+uid://c7pukvtaeda8h
diff --git a/Classes/Events/EventTemplate.cs b/Classes/Events/EventTemplate.cs
new file mode 100644
index 00000000..104afb86
--- /dev/null
+++ b/Classes/Events/EventTemplate.cs
@@ -0,0 +1,39 @@
+using System;
+using Godot;
+
+public delegate void EventAction(EventTemplate self, EventScene contextNode);
+public delegate bool EventCondition();
+
+//TODO: Consider making event option struct for better parallelizing of option parameters
+
+public class EventTemplate
+{
+ public int Id;
+ public string EventDescription;
+ public string[] ButtonDescriptions;
+ public string[] OutcomeDescriptions;
+ public Texture2D Texture;
+ public EventAction[] OptionActions;
+ public EventCondition[] OptionEnabledConditions;
+
+ public EventTemplate() { }
+
+ public EventTemplate(
+ int id,
+ string eventDescription,
+ string[] buttonDescriptions,
+ string[] outcomeDescriptions,
+ EventAction[] optionActions,
+ Texture2D texture,
+ EventCondition[] optionEnabledConditions = null
+ )
+ {
+ Id = id;
+ EventDescription = eventDescription;
+ ButtonDescriptions = buttonDescriptions;
+ OutcomeDescriptions = outcomeDescriptions;
+ OptionActions = optionActions;
+ Texture = texture;
+ OptionEnabledConditions = optionEnabledConditions;
+ }
+}
diff --git a/Classes/Events/EventTemplate.cs.uid b/Classes/Events/EventTemplate.cs.uid
new file mode 100644
index 00000000..197ac53a
--- /dev/null
+++ b/Classes/Events/EventTemplate.cs.uid
@@ -0,0 +1 @@
+uid://4ro8fwi5f8uk
diff --git a/Classes/MapAreas/MapArea.cs.uid b/Classes/MapAreas/MapArea.cs.uid
new file mode 100644
index 00000000..cc07f4c9
--- /dev/null
+++ b/Classes/MapAreas/MapArea.cs.uid
@@ -0,0 +1 @@
+uid://dwi3hewlws25r
diff --git a/Classes/MapAreas/MapLevels.cs b/Classes/MapAreas/MapLevels.cs
new file mode 100644
index 00000000..6166090c
--- /dev/null
+++ b/Classes/MapAreas/MapLevels.cs
@@ -0,0 +1,168 @@
+using System;
+using System.Collections.Generic;
+using FunkEngine;
+using Godot;
+
+public class MapLevels
+{
+ public struct MapConfig
+ {
+ public int Width { get; private set; }
+ public int Height { get; private set; }
+ public int Paths { get; private set; }
+
+ ///
+ /// Rooms that exist at set levels, only one room can be set per y-level.
+ ///
+ public Dictionary SetRooms { get; private set; } =
+ new()
+ {
+ { 0, Stages.Battle }, //The first, e.g. y = 0 room, should always be a battle.
+ };
+
+ ///
+ /// Adds a set room type to be generated guaranteed. Additional entries in the same y-level are ignored.
+ /// This ignores minimum y-heights.
+ ///
+ /// The y-level of the rooms
+ /// The room type to be set.
+ public MapConfig AddSetRoom(int height, Stages roomType)
+ {
+ SetRooms.TryAdd(height, roomType);
+ return this;
+ }
+
+ public static readonly Stages[] StagesToRoll = new[]
+ {
+ Stages.Battle,
+ Stages.Chest,
+ Stages.Elite,
+ Stages.Event,
+ Stages.Shop,
+ };
+
+ ///
+ /// The odds for each stage to appear in a non-set room position.
+ ///
+ public float[] StageOdds = new float[5];
+
+ ///
+ /// The config to generate a map from.
+ ///
+ /// The maximum width of a map. Generally a max of ~12 is reasonable.
+ /// The maximum height of a map.
+ /// The number of paths to draw through the mpa, this effects how many onnections there are.
+ /// The odds for each room type.
+ public MapConfig(int width, int height, int paths, float[] odds)
+ {
+ Width = width;
+ Height = height;
+ Paths = paths;
+ for (int i = 0; i < StagesToRoll.Length; i++)
+ {
+ StageOdds[i] = odds[i];
+ }
+ }
+
+ ///
+ /// Rooms that exist at set levels, only one room can be set per y-level.
+ ///
+ public Dictionary MinHeights { get; private set; } = new();
+
+ ///
+ /// Adds a minimum y-height for a room type. Can only have one set per room type
+ ///
+ /// The y-level of the room type
+ /// The room type to be set.
+ public MapConfig AddMinHeight(Stages roomType, int height)
+ {
+ MinHeights.TryAdd(roomType, height);
+ return this;
+ }
+ }
+
+ private MapLevels(
+ int id,
+ MapConfig config,
+ int[] battleSongs,
+ int[] eliteSongs,
+ int[] bossSongs,
+ int[] eventIds,
+ int nextLevelId = -1,
+ string backgroundPath = "res://SharedAssets/BackGround_Full.png"
+ )
+ {
+ Id = id;
+ CurMapConfig = config;
+ NormalBattles = battleSongs;
+ EliteBattles = eliteSongs;
+ BossBattles = bossSongs;
+ EventIds = eventIds;
+ NextLevel = nextLevelId;
+ BackgroundPath = backgroundPath;
+ }
+
+ public int Id { get; private set; }
+ public string BackgroundPath { get; private set; }
+ private MapConfig CurMapConfig;
+ private int NextLevel;
+
+ //These tie into the Scribe SongDictionary
+ public int[] NormalBattles { get; private set; }
+ public int[] EliteBattles { get; private set; }
+ public int[] BossBattles { get; private set; }
+ public int[] EventIds { get; private set; }
+
+ #region Preset Levels
+ private static readonly MapConfig FirstMapConfig = new MapConfig(7, 7, 3, [10, 2, 5, 6, 5])
+ .AddSetRoom(3, Stages.Chest)
+ .AddMinHeight(Stages.Chest, 2)
+ .AddMinHeight(Stages.Shop, 3)
+ .AddMinHeight(Stages.Elite, 3);
+
+ private static readonly MapConfig CityMapConfig = new MapConfig(9, 10, 5, [12, 1, 5, 5, 4])
+ .AddSetRoom(2, Stages.Chest)
+ .AddSetRoom(4, Stages.Shop)
+ .AddMinHeight(Stages.Chest, 1)
+ .AddMinHeight(Stages.Shop, 3)
+ .AddMinHeight(Stages.Elite, 2);
+
+ private static readonly MapConfig TutorialMapConfig = new MapConfig(1, 2, 1, [10, 0, 0, 0, 0]);
+
+ private static readonly MapLevels[] PresetLevels = new[]
+ {
+ new MapLevels(0, TutorialMapConfig, [4], [0], [5], [], 1),
+ new MapLevels(1, FirstMapConfig, [1, 2, 11, 12, 15], [3, 13], [0], [], 2),
+ new MapLevels(
+ 2,
+ CityMapConfig,
+ [7, 8, 10],
+ [6, 9],
+ [14],
+ [],
+ -1,
+ "res://SharedAssets/BackGround_City.png"
+ ),
+ };
+ #endregion
+
+ public MapConfig GetCurrentConfig()
+ {
+ return CurMapConfig;
+ }
+
+ public bool HasMoreMaps()
+ {
+ return NextLevel != -1;
+ }
+
+ public MapLevels GetNextLevel()
+ {
+ return !HasMoreMaps() ? null : PresetLevels[NextLevel];
+ }
+
+ public static MapLevels GetLevelFromId(int id)
+ {
+ return PresetLevels[id];
+ }
+}
diff --git a/Classes/MapAreas/MapLevels.cs.uid b/Classes/MapAreas/MapLevels.cs.uid
new file mode 100644
index 00000000..7e949af2
--- /dev/null
+++ b/Classes/MapAreas/MapLevels.cs.uid
@@ -0,0 +1 @@
+uid://dhcmdrux47fx5
diff --git a/Classes/Notes/Assets/Note_BossBlood.png b/Classes/Notes/Assets/Note_BossBlood.png
new file mode 100644
index 00000000..4c9fef7f
Binary files /dev/null and b/Classes/Notes/Assets/Note_BossBlood.png differ
diff --git a/Classes/Notes/Assets/Note_BossBlood.png.import b/Classes/Notes/Assets/Note_BossBlood.png.import
new file mode 100644
index 00000000..e2d09d8d
--- /dev/null
+++ b/Classes/Notes/Assets/Note_BossBlood.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://c6gaprxxf71mm"
+path="res://.godot/imported/Note_BossBlood.png-867ef730738d75280fbaf251b1d84cde.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Classes/Notes/Assets/Note_BossBlood.png"
+dest_files=["res://.godot/imported/Note_BossBlood.png-867ef730738d75280fbaf251b1d84cde.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/Classes/Notes/Assets/Note_GWS.png b/Classes/Notes/Assets/Note_GWS.png
new file mode 100644
index 00000000..204ecab9
Binary files /dev/null and b/Classes/Notes/Assets/Note_GWS.png differ
diff --git a/Classes/Notes/Assets/Note_GWS.png.import b/Classes/Notes/Assets/Note_GWS.png.import
new file mode 100644
index 00000000..a91093be
--- /dev/null
+++ b/Classes/Notes/Assets/Note_GWS.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bqng2uofbio1x"
+path="res://.godot/imported/Note_GWS.png-374fb66d7b5ccdab1c51d6ad3d49769c.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Classes/Notes/Assets/Note_GWS.png"
+dest_files=["res://.godot/imported/Note_GWS.png-374fb66d7b5ccdab1c51d6ad3d49769c.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/Classes/Notes/Assets/Note_LWS.png b/Classes/Notes/Assets/Note_LWS.png
new file mode 100644
index 00000000..66de061d
Binary files /dev/null and b/Classes/Notes/Assets/Note_LWS.png differ
diff --git a/Classes/Notes/Assets/Note_LWS.png.import b/Classes/Notes/Assets/Note_LWS.png.import
new file mode 100644
index 00000000..65ac0259
--- /dev/null
+++ b/Classes/Notes/Assets/Note_LWS.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://8f1e7sld42dm"
+path="res://.godot/imported/Note_LWS.png-99644fe1956962c91597c9de6bb97929.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Classes/Notes/Assets/Note_LWS.png"
+dest_files=["res://.godot/imported/Note_LWS.png-99644fe1956962c91597c9de6bb97929.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/Classes/Notes/Assets/Note_Mushroom.png b/Classes/Notes/Assets/Note_Mushroom.png
new file mode 100644
index 00000000..09b74925
Binary files /dev/null and b/Classes/Notes/Assets/Note_Mushroom.png differ
diff --git a/Classes/Notes/Assets/Note_Mushroom.png.import b/Classes/Notes/Assets/Note_Mushroom.png.import
new file mode 100644
index 00000000..9de26ce7
--- /dev/null
+++ b/Classes/Notes/Assets/Note_Mushroom.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://d1epchjdmxfxs"
+path="res://.godot/imported/Note_Mushroom.png-d7047f8deb762437256829b5c1281cb5.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Classes/Notes/Assets/Note_Mushroom.png"
+dest_files=["res://.godot/imported/Note_Mushroom.png-d7047f8deb762437256829b5c1281cb5.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/Classes/Notes/Assets/Note_Parasifly.png b/Classes/Notes/Assets/Note_Parasifly.png
new file mode 100644
index 00000000..67599c7d
Binary files /dev/null and b/Classes/Notes/Assets/Note_Parasifly.png differ
diff --git a/Classes/Notes/Assets/Note_Parasifly.png.import b/Classes/Notes/Assets/Note_Parasifly.png.import
new file mode 100644
index 00000000..79bcc03b
--- /dev/null
+++ b/Classes/Notes/Assets/Note_Parasifly.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://b5rpamdpcjrbj"
+path="res://.godot/imported/Note_Parasifly.png-3e72dc1cfeaf988046fea33e3d40a914.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Classes/Notes/Assets/Note_Parasifly.png"
+dest_files=["res://.godot/imported/Note_Parasifly.png-3e72dc1cfeaf988046fea33e3d40a914.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/Classes/Notes/Assets/Note_PlayerCombo.png b/Classes/Notes/Assets/Note_PlayerCombo.png
new file mode 100644
index 00000000..f86a2a79
Binary files /dev/null and b/Classes/Notes/Assets/Note_PlayerCombo.png differ
diff --git a/Classes/Notes/Assets/Note_PlayerCombo.png.import b/Classes/Notes/Assets/Note_PlayerCombo.png.import
new file mode 100644
index 00000000..996b4f44
--- /dev/null
+++ b/Classes/Notes/Assets/Note_PlayerCombo.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cvqo88fkuu8hs"
+path="res://.godot/imported/Note_PlayerCombo.png-a24d525105b1bc80383245debb99deb4.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Classes/Notes/Assets/Note_PlayerCombo.png"
+dest_files=["res://.godot/imported/Note_PlayerCombo.png-a24d525105b1bc80383245debb99deb4.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/Classes/Notes/Assets/Note_PlayerMoney.png b/Classes/Notes/Assets/Note_PlayerMoney.png
new file mode 100644
index 00000000..5d620f57
Binary files /dev/null and b/Classes/Notes/Assets/Note_PlayerMoney.png differ
diff --git a/Classes/Notes/Assets/Note_PlayerMoney.png.import b/Classes/Notes/Assets/Note_PlayerMoney.png.import
new file mode 100644
index 00000000..27997267
--- /dev/null
+++ b/Classes/Notes/Assets/Note_PlayerMoney.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cje3p520pprt4"
+path="res://.godot/imported/Note_PlayerMoney.png-f14210a70c94f89c7ea76606add2bdf2.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Classes/Notes/Assets/Note_PlayerMoney.png"
+dest_files=["res://.godot/imported/Note_PlayerMoney.png-f14210a70c94f89c7ea76606add2bdf2.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/Classes/Notes/Assets/Note_Spider.png b/Classes/Notes/Assets/Note_Spider.png
new file mode 100644
index 00000000..e507766c
Binary files /dev/null and b/Classes/Notes/Assets/Note_Spider.png differ
diff --git a/Classes/Notes/Assets/Note_Spider.png.import b/Classes/Notes/Assets/Note_Spider.png.import
new file mode 100644
index 00000000..7818b10a
--- /dev/null
+++ b/Classes/Notes/Assets/Note_Spider.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bhelwwuva2kvp"
+path="res://.godot/imported/Note_Spider.png-821a99c0e9d394f8bbe59ba0844306c2.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Classes/Notes/Assets/Note_Spider.png"
+dest_files=["res://.godot/imported/Note_Spider.png-821a99c0e9d394f8bbe59ba0844306c2.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/Classes/Notes/Note.cs b/Classes/Notes/Note.cs
index f6b47e3d..3dc196e3 100644
--- a/Classes/Notes/Note.cs
+++ b/Classes/Notes/Note.cs
@@ -16,16 +16,12 @@ public partial class Note : Resource, IDisplayable
private Action NoteEffect;
public const double TimingMax = 0.5d; //The max range for a note to be timed is its beat +/- this const
-
- public string Tooltip { get; set; }
public Texture2D Texture { get; set; }
public Note(
int id,
string name,
- string tooltip,
Texture2D texture = null,
- PuppetTemplate owner = null,
int baseVal = 1,
Action noteEffect = null,
float costModifier = 1.0f,
@@ -34,11 +30,9 @@ public Note(
{
Id = id;
Name = name;
- Owner = owner;
NoteEffect = noteEffect;
_baseVal = baseVal;
Texture = texture;
- Tooltip = tooltip;
CostModifier = costModifier;
TargetType = targetType;
}
@@ -48,21 +42,17 @@ public void OnHit(BattleDirector BD, Timing timing)
NoteEffect(BD, this, timing);
}
+ public Note SetOwner(PuppetTemplate owner)
+ {
+ Owner = owner;
+ return this;
+ }
+
public Note Clone()
{
//Eventually could look into something more robust, but for now shallow copy is preferable.
//We only would want val and name to be copied by value
- Note newNote = new Note(
- Id,
- Name,
- Tooltip,
- Texture,
- Owner,
- _baseVal,
- NoteEffect,
- CostModifier,
- TargetType
- );
+ Note newNote = new Note(Id, Name, Texture, _baseVal, NoteEffect, CostModifier, TargetType);
return newNote;
}
diff --git a/Classes/Relics/Assets/Relic_BloodMoney.png b/Classes/Relics/Assets/Relic_BloodMoney.png
new file mode 100644
index 00000000..2a30e5cf
Binary files /dev/null and b/Classes/Relics/Assets/Relic_BloodMoney.png differ
diff --git a/Classes/Relics/Assets/Relic_BloodMoney.png.import b/Classes/Relics/Assets/Relic_BloodMoney.png.import
new file mode 100644
index 00000000..eccc589b
--- /dev/null
+++ b/Classes/Relics/Assets/Relic_BloodMoney.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dvuhv286d0trp"
+path="res://.godot/imported/Relic_BloodMoney.png-d130382b6c03f59c21d5962c3d5f6e5a.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Classes/Relics/Assets/Relic_BloodMoney.png"
+dest_files=["res://.godot/imported/Relic_BloodMoney.png-d130382b6c03f59c21d5962c3d5f6e5a.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/Classes/Relics/Assets/Relic_BrokenDrumstick.png b/Classes/Relics/Assets/Relic_BrokenDrumstick.png
new file mode 100644
index 00000000..ab3c77b1
Binary files /dev/null and b/Classes/Relics/Assets/Relic_BrokenDrumstick.png differ
diff --git a/Classes/Relics/Assets/Relic_BrokenDrumstick.png.import b/Classes/Relics/Assets/Relic_BrokenDrumstick.png.import
new file mode 100644
index 00000000..8d74d665
--- /dev/null
+++ b/Classes/Relics/Assets/Relic_BrokenDrumstick.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cu26dy5itkd4m"
+path="res://.godot/imported/Relic_BrokenDrumstick.png-94c905ef353da245ad24e71cbd686e66.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Classes/Relics/Assets/Relic_BrokenDrumstick.png"
+dest_files=["res://.godot/imported/Relic_BrokenDrumstick.png-94c905ef353da245ad24e71cbd686e66.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/Classes/Relics/Assets/Relic_Coupon.png b/Classes/Relics/Assets/Relic_Coupon.png
new file mode 100644
index 00000000..3ea084b7
Binary files /dev/null and b/Classes/Relics/Assets/Relic_Coupon.png differ
diff --git a/Classes/Relics/Assets/Relic_Coupon.png.import b/Classes/Relics/Assets/Relic_Coupon.png.import
new file mode 100644
index 00000000..33d0e0fb
--- /dev/null
+++ b/Classes/Relics/Assets/Relic_Coupon.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://c7kegse3tt25t"
+path="res://.godot/imported/Relic_Coupon.png-fbc4593b2a2e278d51828d9813481a77.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Classes/Relics/Assets/Relic_Coupon.png"
+dest_files=["res://.godot/imported/Relic_Coupon.png-fbc4593b2a2e278d51828d9813481a77.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/Classes/Relics/Assets/Relic_LooseChange.png b/Classes/Relics/Assets/Relic_LooseChange.png
new file mode 100644
index 00000000..abe8418b
Binary files /dev/null and b/Classes/Relics/Assets/Relic_LooseChange.png differ
diff --git a/Classes/Relics/Assets/Relic_LooseChange.png.import b/Classes/Relics/Assets/Relic_LooseChange.png.import
new file mode 100644
index 00000000..e978c8b1
--- /dev/null
+++ b/Classes/Relics/Assets/Relic_LooseChange.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://xicfogph25bj"
+path="res://.godot/imported/Relic_LooseChange.png-496af612042666a7f384e1eb8d4167ce.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Classes/Relics/Assets/Relic_LooseChange.png"
+dest_files=["res://.godot/imported/Relic_LooseChange.png-496af612042666a7f384e1eb8d4167ce.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/Classes/Relics/Assets/Relic_LuckyDice.png b/Classes/Relics/Assets/Relic_LuckyDice.png
new file mode 100644
index 00000000..07f0cd9a
Binary files /dev/null and b/Classes/Relics/Assets/Relic_LuckyDice.png differ
diff --git a/Classes/Relics/Assets/Relic_LuckyDice.png.import b/Classes/Relics/Assets/Relic_LuckyDice.png.import
new file mode 100644
index 00000000..8733a36b
--- /dev/null
+++ b/Classes/Relics/Assets/Relic_LuckyDice.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://c4sx72edrmarc"
+path="res://.godot/imported/Relic_LuckyDice.png-88ca6d67d74b2a5f34af4000f643b3a7.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Classes/Relics/Assets/Relic_LuckyDice.png"
+dest_files=["res://.godot/imported/Relic_LuckyDice.png-88ca6d67d74b2a5f34af4000f643b3a7.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/Classes/Relics/Assets/Relic_SecondPick.png b/Classes/Relics/Assets/Relic_SecondPick.png
new file mode 100644
index 00000000..c004b4ac
Binary files /dev/null and b/Classes/Relics/Assets/Relic_SecondPick.png differ
diff --git a/Classes/Relics/Assets/Relic_SecondPick.png.import b/Classes/Relics/Assets/Relic_SecondPick.png.import
new file mode 100644
index 00000000..ffb5f043
--- /dev/null
+++ b/Classes/Relics/Assets/Relic_SecondPick.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bjw3cyofjjxv6"
+path="res://.godot/imported/Relic_SecondPick.png-0361bd1bad087f4d81be27c9c5b3fe2b.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Classes/Relics/Assets/Relic_SecondPick.png"
+dest_files=["res://.godot/imported/Relic_SecondPick.png-0361bd1bad087f4d81be27c9c5b3fe2b.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/Classes/Relics/Assets/Relic_Shortcut.png b/Classes/Relics/Assets/Relic_Shortcut.png
new file mode 100644
index 00000000..4650ecd5
Binary files /dev/null and b/Classes/Relics/Assets/Relic_Shortcut.png differ
diff --git a/Classes/Relics/Assets/Relic_Shortcut.png.import b/Classes/Relics/Assets/Relic_Shortcut.png.import
new file mode 100644
index 00000000..95311cde
--- /dev/null
+++ b/Classes/Relics/Assets/Relic_Shortcut.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cyonk7kn213ik"
+path="res://.godot/imported/Relic_Shortcut.png-d03004b4d7d0b125c8da23d3a2ca0db2.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Classes/Relics/Assets/Relic_Shortcut.png"
+dest_files=["res://.godot/imported/Relic_Shortcut.png-d03004b4d7d0b125c8da23d3a2ca0db2.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/Classes/Relics/Assets/Relic_SpikedShield.png b/Classes/Relics/Assets/Relic_SpikedShield.png
new file mode 100644
index 00000000..46f10a8e
Binary files /dev/null and b/Classes/Relics/Assets/Relic_SpikedShield.png differ
diff --git a/Classes/Relics/Assets/Relic_SpikedShield.png.import b/Classes/Relics/Assets/Relic_SpikedShield.png.import
new file mode 100644
index 00000000..b1ad3927
--- /dev/null
+++ b/Classes/Relics/Assets/Relic_SpikedShield.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dlivs0hony8p8"
+path="res://.godot/imported/Relic_SpikedShield.png-59642dbb734140b3422c00600f46526b.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Classes/Relics/Assets/Relic_SpikedShield.png"
+dest_files=["res://.godot/imported/Relic_SpikedShield.png-59642dbb734140b3422c00600f46526b.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/Classes/Relics/Assets/Relic_VinylRecord.png b/Classes/Relics/Assets/Relic_VinylRecord.png
index b72ab653..f850c30a 100644
Binary files a/Classes/Relics/Assets/Relic_VinylRecord.png and b/Classes/Relics/Assets/Relic_VinylRecord.png differ
diff --git a/Classes/Relics/RelicTemplate.cs b/Classes/Relics/RelicTemplate.cs
index 5ae354ab..803563f2 100644
--- a/Classes/Relics/RelicTemplate.cs
+++ b/Classes/Relics/RelicTemplate.cs
@@ -11,14 +11,12 @@ public partial class RelicTemplate : Resource, IDisplayable
public string Name { get; set; }
public Texture2D Texture { get; set; }
- public string Tooltip { get; set; }
public Rarity Rarity { get; set; }
public RelicTemplate(
int id,
string name = "",
- string tooltip = "",
Rarity rarity = Rarity.Common,
Texture2D texture = null,
RelicEffect[] effectTags = null
@@ -27,14 +25,13 @@ public RelicTemplate(
Id = id;
Effects = effectTags;
Name = name;
- Tooltip = tooltip;
Texture = texture;
Rarity = rarity;
}
public RelicTemplate Clone()
{
- RelicTemplate newRelic = new RelicTemplate(Id, Name, Tooltip, Rarity, Texture, Effects);
+ RelicTemplate newRelic = new RelicTemplate(Id, Name, Rarity, Texture, Effects);
return newRelic;
}
}
diff --git a/Classes/StatusEffects/Assets/Status_Disable.png b/Classes/StatusEffects/Assets/Status_Disable.png
new file mode 100644
index 00000000..227ea99f
Binary files /dev/null and b/Classes/StatusEffects/Assets/Status_Disable.png differ
diff --git a/Classes/StatusEffects/Assets/Status_Disable.png.import b/Classes/StatusEffects/Assets/Status_Disable.png.import
new file mode 100644
index 00000000..75677fd9
--- /dev/null
+++ b/Classes/StatusEffects/Assets/Status_Disable.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dwu28wijmonwh"
+path="res://.godot/imported/Status_Disable.png-42e34df55e73312bef8eb3b735e96fac.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Classes/StatusEffects/Assets/Status_Disable.png"
+dest_files=["res://.godot/imported/Status_Disable.png-42e34df55e73312bef8eb3b735e96fac.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/Classes/StatusEffects/Assets/Status_Dodge.png b/Classes/StatusEffects/Assets/Status_Dodge.png
new file mode 100644
index 00000000..8b3d093b
Binary files /dev/null and b/Classes/StatusEffects/Assets/Status_Dodge.png differ
diff --git a/Classes/StatusEffects/Assets/Status_Dodge.png.import b/Classes/StatusEffects/Assets/Status_Dodge.png.import
new file mode 100644
index 00000000..58c021b9
--- /dev/null
+++ b/Classes/StatusEffects/Assets/Status_Dodge.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://li36jtg8c5ao"
+path="res://.godot/imported/Status_Dodge.png-2abb54401cc55e9c1d845790ee310613.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Classes/StatusEffects/Assets/Status_Dodge.png"
+dest_files=["res://.godot/imported/Status_Dodge.png-2abb54401cc55e9c1d845790ee310613.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/Classes/StatusEffects/Assets/Status_MindCrush.png b/Classes/StatusEffects/Assets/Status_MindCrush.png
new file mode 100644
index 00000000..f6aec566
Binary files /dev/null and b/Classes/StatusEffects/Assets/Status_MindCrush.png differ
diff --git a/Classes/StatusEffects/Assets/Status_MindCrush.png.import b/Classes/StatusEffects/Assets/Status_MindCrush.png.import
new file mode 100644
index 00000000..fa3cbe71
--- /dev/null
+++ b/Classes/StatusEffects/Assets/Status_MindCrush.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cno6d4imgtep0"
+path="res://.godot/imported/Status_MindCrush.png-3cdfb511c512cb7a1639af39055a6426.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Classes/StatusEffects/Assets/Status_MindCrush.png"
+dest_files=["res://.godot/imported/Status_MindCrush.png-3cdfb511c512cb7a1639af39055a6426.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/Classes/StatusEffects/StatusEffect.cs b/Classes/StatusEffects/StatusEffect.cs
index 5229e49f..6e040316 100644
--- a/Classes/StatusEffects/StatusEffect.cs
+++ b/Classes/StatusEffects/StatusEffect.cs
@@ -87,6 +87,70 @@ public partial class StatusEffect : TextureRect, IBattleEvent
GD.Load("res://Classes/StatusEffects/Assets/Status_Poison.png")
)
.SetTags(true);
+
+ private static readonly Action MindCrushEffect = (e, self) =>
+ {
+ if (e is not BattleDirector.Harbinger.LoopEventArgs)
+ return;
+ if (self.Sufferer == null)
+ return;
+ self.DecCount();
+ if (self.Count < 1)
+ {
+ self.Sufferer.TakeDamage(new DamageInstance(1000, null, null));
+ }
+ };
+
+ public static readonly StatusEffect MindCrush = new StatusEffect()
+ .InitStatus(
+ "MindCrush",
+ MindCrushEffect,
+ BattleEffectTrigger.OnLoop,
+ GD.Load("res://Classes/StatusEffects/Assets/Status_MindCrush.png")
+ )
+ .SetTags(true);
+
+ private static readonly Action DodgeEffect = (e, self) =>
+ {
+ if (e is BattleDirector.Harbinger.OnDamageInstanceArgs dmgArgs)
+ {
+ if (dmgArgs.Dmg.Target != self.Sufferer || dmgArgs.Dmg.Damage <= 0)
+ return;
+ if (StageProducer.GlobalRng.RandiRange(0, 1) == 0)
+ return;
+
+ dmgArgs.Dmg.ModifyDamage(0, 0);
+ self.DecCount();
+ }
+ };
+
+ public static readonly StatusEffect Dodge = new StatusEffect()
+ .InitStatus(
+ "Dodge",
+ DodgeEffect,
+ BattleEffectTrigger.OnDamageInstance,
+ GD.Load("res://Classes/StatusEffects/Assets/Status_Dodge.png")
+ )
+ .SetTags(true);
+
+ public static readonly Action DisableEffect = (_, self) =>
+ {
+ self.DecCount();
+ if (self.Count < 1)
+ BattleDirector.PlayerDisabled = false;
+ };
+
+ ///
+ /// Doesn't actually successfully disable input, should be disabled manually, and generally paired with autoplay.
+ ///
+ public static readonly StatusEffect Disable = new StatusEffect()
+ .InitStatus(
+ "Disable",
+ DisableEffect,
+ BattleEffectTrigger.OnLoop,
+ GD.Load("res://Classes/StatusEffects/Assets/Status_Disable.png")
+ )
+ .SetTags(false, true);
#endregion
private BattleEffectTrigger _trigger;
@@ -116,11 +180,11 @@ public StatusEffect InitStatus(
return this;
}
- public StatusEffect GetInstance(int count = 1)
+ public StatusEffect CreateInstance(int count = 1)
{
StatusEffect result = GD.Load(LoadPath).Instantiate();
result.SetCount(count);
- result.InitStatus(Name, _effect, _trigger, Texture);
+ result.InitStatus(StatusName, _effect, _trigger, Texture);
result.SetTags(_stackable, _refreshes);
return result;
}
diff --git a/Globals/BgAudioPlayer/BgAudioPlayer.cs b/Globals/BgAudioPlayer/BgAudioPlayer.cs
index 13c791f2..26f08907 100644
--- a/Globals/BgAudioPlayer/BgAudioPlayer.cs
+++ b/Globals/BgAudioPlayer/BgAudioPlayer.cs
@@ -9,6 +9,8 @@ public partial class BgAudioPlayer : AudioStreamPlayer
"res://Scenes/UI/TitleScreen/Assets/TitleSong.ogg"
);
+ private float _checkpoint;
+
public static BgAudioPlayer LiveInstance { get; private set; }
public override void _EnterTree()
@@ -16,26 +18,42 @@ public override void _EnterTree()
LiveInstance = this;
}
- private void PlayMusic(AudioStream music, float volume)
+ private void PlayMusic(AudioStream music, float volume, bool resume = false)
{
ProcessMode = ProcessModeEnum.Always;
- if (Playing && music.Equals(Stream))
+
+ if (!Playing || !music.Equals(Stream))
{
- return;
+ Stream = music;
+ VolumeDb = volume;
+ Play(resume ? _checkpoint : 0);
}
-
- Stream = music;
- VolumeDb = volume;
- Play();
}
+ ///
+ /// Starts playing main menu music from the start if the track if it is not already playing.
+ /// Does nothing if the track is already playing.
+ ///
+ /// The volume to play the track at
public void PlayLevelMusic(float volume = -10f)
{
PlayMusic(_levelMusic, volume);
}
+ ///
+ /// Starts playing main menu music from the last checkpoint if the track if it is not already playing.
+ /// Does nothing if the track is already playing.
+ ///
+ ///
+ public void ResumeLevelMusic(float volume = -10f)
+ {
+ PlayMusic(_levelMusic, volume, true);
+ }
+
public void StopMusic()
{
+ _checkpoint = GetPlaybackPosition();
+
Stop();
Stream = null;
}
diff --git a/Globals/FunkEngineNameSpace.cs b/Globals/FunkEngineNameSpace.cs
index c73800f6..78b98bd0 100644
--- a/Globals/FunkEngineNameSpace.cs
+++ b/Globals/FunkEngineNameSpace.cs
@@ -55,10 +55,10 @@ public ArrowData(ArrowType type, Beat beat, Note note, double length = 0)
public Beat Beat;
public readonly double Length; //in beats, should never be >= loop
public readonly ArrowType Type;
- public readonly Note NoteRef = null;
+ public Note NoteRef { get; private set; } = null;
public static ArrowData Placeholder { get; private set; } =
- new(default, default, new Note(-1, "", ""));
+ new(default, default, new Note(-1, ""));
public ArrowData BeatFromLength()
{
@@ -66,6 +66,18 @@ public ArrowData BeatFromLength()
return this;
}
+ public static ArrowData SetNote(ArrowData arrowData, Note note)
+ {
+ arrowData.NoteRef = note;
+ return arrowData;
+ }
+
+ public ArrowData IncDecLoop(int amount)
+ {
+ Beat.IncDecLoop(amount);
+ return this;
+ }
+
public bool Equals(ArrowData other)
{
return Beat.Equals(other.Beat) && Type == other.Type;
@@ -130,7 +142,7 @@ public Beat(double beat, int loop)
public double GetBeatInSong()
{
- return BeatPos + Loop * TimeKeeper.BeatsPerLoop % TimeKeeper.BeatsPerSong;
+ return (BeatPos + Loop * TimeKeeper.BeatsPerLoop) % TimeKeeper.BeatsPerSong;
}
public Beat IncDecLoop(int amount)
@@ -245,20 +257,17 @@ public enum BattleEffectTrigger
public enum Stages
{
- Title,
- Battle,
- Chest,
+ Battle = 0,
+ Chest = 1,
+ Elite = 2,
+ Event = 3,
+ Shop = 4,
Boss,
Quit,
Map,
Load,
Continue,
-}
-
-public enum Area
-{
- Forest = 0,
- City = 1,
+ Title,
}
public enum Rarity
@@ -282,6 +291,7 @@ public class MapGrid
private int[,] _map;
private Room[] _rooms;
private int _curIdx;
+ public int Width { get; private set; }
public Room[] GetRooms()
{
@@ -316,59 +326,12 @@ public void AddChild(int newIdx)
}
}
- //TODO: Make odds for rooms based on y-level, e.g. elites only spawn on y > 3
- public struct MapConfig
- {
- public int Width { get; private set; }
- public int Height { get; private set; }
- public int Paths { get; private set; }
-
- ///
- /// Rooms that exist at set levels, only one room can be set per y-level.
- ///
- public Dictionary SetRooms { get; private set; } =
- new()
- {
- { 0, Stages.Battle }, //The first, e.g. y = 0 room, should always be a battle.
- };
-
- public const int NumStages = 2;
-
- public static readonly Stages[] StagsToRoll = new[] { Stages.Battle, Stages.Chest };
-
- ///
- /// The odds for each stage to appear in a non-set room position.
- ///
- public float[] StageOdds = new float[2];
-
- public MapConfig(int width, int height, int paths, float[] odds)
- {
- Width = width;
- Height = height;
- Paths = paths;
- for (int i = 0; i < NumStages; i++)
- {
- StageOdds[i] = odds[i];
- }
- }
-
- ///
- /// Adds a set room type to be generated guaranteed. Additional entries in the same y-level are ignored.
- ///
- /// The y-level of the rooms
- /// The room type to be set.
- public MapConfig AddSetRoom(int height, Stages roomType)
- {
- SetRooms.TryAdd(height, roomType);
- return this;
- }
- }
-
/**
* Initializes the map with max width, max height, and with number of paths.
*/
- public void InitMapGrid(MapConfig curConfig)
+ public void InitMapGrid(MapLevels.MapConfig curConfig)
{
+ Width = curConfig.Width;
_curIdx = 0;
_rooms = [];
_map = new int[curConfig.Width, curConfig.Height]; //x,y
@@ -387,7 +350,7 @@ public void InitMapGrid(MapConfig curConfig)
}
/**Start at x, y, assume prev room exists. Picks new x pos within +/- 1, attaches recursively*/
- private void GeneratePath_r(int x, int y, MapConfig curConfig)
+ private void GeneratePath_r(int x, int y, MapLevels.MapConfig curConfig)
{
int nextX = StageProducer.GlobalRng.RandiRange(
Math.Max(x - 1, 0),
@@ -410,7 +373,7 @@ private void GeneratePath_r(int x, int y, MapConfig curConfig)
}
}
- private Stages PickRoomType(int x, int y, MapConfig curConfig)
+ private Stages PickRoomType(int x, int y, MapLevels.MapConfig curConfig)
{
//If the y has a set room return it.
if (curConfig.SetRooms.TryGetValue(y, out Stages result))
@@ -419,8 +382,17 @@ private Stages PickRoomType(int x, int y, MapConfig curConfig)
}
//Random roll for the room type.
- int idx = (int)StageProducer.GlobalRng.RandWeighted(curConfig.StageOdds);
- return MapConfig.StagsToRoll[idx];
+ float[] validRooms = new float[curConfig.StageOdds.Length];
+ curConfig.StageOdds.CopyTo(validRooms, 0);
+ foreach ((Stages stage, int height) in curConfig.MinHeights)
+ {
+ if (y < height)
+ {
+ validRooms[(int)stage] = 0;
+ }
+ }
+ int idx = (int)StageProducer.GlobalRng.RandWeighted(validRooms);
+ return MapLevels.MapConfig.StagesToRoll[idx];
}
//Asserts that if there is a room at the same x, but y+1 they are connected
@@ -471,7 +443,6 @@ public interface IBattleEvent
public interface IDisplayable
{
string Name { get; set; }
- string Tooltip { get; set; }
Texture2D Texture { get; set; }
}
diff --git a/Globals/SaveSystem.cs b/Globals/SaveSystem.cs
index cb522c32..071e0255 100644
--- a/Globals/SaveSystem.cs
+++ b/Globals/SaveSystem.cs
@@ -14,7 +14,7 @@ public static class SaveSystem
private static ConfigFile _curConfigData;
private const float DefaultVolume = 1f;
- private const string DefaultInputType = "WASD";
+ private const string DefaultInputType = "WASD"; //WASD or CONTROLLER
private const int DefaultInputKeyboardUp = 87; //W
private const int DefaultInputKeyboardLeft = 65; //A
private const int DefaultInputKeyboardDown = 83; //S
@@ -29,6 +29,7 @@ public static class SaveSystem
private const int DefaultInputControllerInventory = 4; //back button
private const string DefaultLanguage = "en";
private const bool DefaultHighCon = false;
+ private const bool DefaultFirstTime = true;
public enum ConfigSettings
{
@@ -48,6 +49,7 @@ public enum ConfigSettings
InputControllerInventory,
LanguageKey,
HighContrast,
+ FirstTime,
}
/**
@@ -72,6 +74,7 @@ private static void InitConfig()
UpdateConfig(ConfigSettings.InputControllerInventory, DefaultInputControllerInventory);
UpdateConfig(ConfigSettings.LanguageKey, DefaultLanguage);
UpdateConfig(ConfigSettings.HighContrast, DefaultHighCon);
+ UpdateConfig(ConfigSettings.FirstTime, DefaultFirstTime);
}
private static void SaveConfig()
@@ -133,6 +136,9 @@ public static void UpdateConfig(ConfigSettings setting, Variant value)
case ConfigSettings.HighContrast:
_curConfigData.SetValue("Options", "HighContrast", value);
break;
+ case ConfigSettings.FirstTime:
+ _curConfigData.SetValue("Game", "FirstTime", value);
+ break;
default:
GD.PushError("SaveSystem.UpdateConfig: Invalid config setting passed. " + setting);
break;
@@ -270,6 +276,8 @@ public static Variant GetConfigValue(ConfigSettings setting)
return _curConfigData.GetValue("Options", "LanguageKey", DefaultLanguage);
case ConfigSettings.HighContrast:
return _curConfigData.GetValue("Options", "HighContrast", DefaultHighCon);
+ case ConfigSettings.FirstTime:
+ return _curConfigData.GetValue("Game", "FirstTime", DefaultFirstTime);
default:
GD.PushError("Invalid config setting passed. " + setting);
return float.MinValue;
@@ -360,6 +368,12 @@ private static void AddJoypadBinding(string action, string buttonString)
GD.PushWarning($"Could not parse joypad button: {buttonString}");
}
}
+
+ public static void ClearConfig()
+ {
+ DirAccess.RemoveAbsolute(UserConfigPath);
+ InitConfig();
+ }
#endregion
#region Save
@@ -373,9 +387,14 @@ public class SaveFile
public int LastRoomIdx { get; init; }
public int Area { get; init; }
+ public int Money { get; init; }
public int[] NoteIds { get; init; }
public int[] RelicIds { get; init; }
+ public int[] BattlePool { get; init; }
+ public int[] EventPool { get; init; }
public int PlayerHealth { get; init; }
+ public int Shortcuts { get; init; }
+ public int PlayerMaxCombo { get; init; }
public SaveFile(
ulong rngSeed,
@@ -383,8 +402,13 @@ public SaveFile(
int lastRoomIdx,
int[] noteIds,
int[] relicIds,
+ int[] battlePool,
+ int[] eventPool,
int playerHealth,
- int area
+ int area,
+ int money,
+ int shortcuts,
+ int playerMaxCombo
)
{
RngSeed = rngSeed;
@@ -392,8 +416,13 @@ int area
LastRoomIdx = lastRoomIdx;
NoteIds = noteIds;
RelicIds = relicIds;
+ BattlePool = battlePool ?? [];
+ EventPool = eventPool ?? [];
PlayerHealth = playerHealth;
Area = area;
+ Money = money;
+ Shortcuts = shortcuts;
+ PlayerMaxCombo = playerMaxCombo;
}
}
@@ -407,8 +436,13 @@ public static void SaveGame()
StageProducer.CurRoom,
noteIds,
relicIds,
+ StageProducer.BattlePool?.ToArray(),
+ EventScene.EventPool?.ToArray(),
StageProducer.PlayerStats.CurrentHealth,
- (int)StageProducer.CurArea
+ StageProducer.CurLevel.Id,
+ StageProducer.PlayerStats.Money,
+ StageProducer.PlayerStats.Shortcuts,
+ StageProducer.PlayerStats.MaxComboBar
);
string json = JsonSerializer.Serialize(sv);
diff --git a/Globals/Scribe.cs b/Globals/Scribe.cs
index e15a8b97..8835dc97 100644
--- a/Globals/Scribe.cs
+++ b/Globals/Scribe.cs
@@ -1,3 +1,4 @@
+using System;
using System.Collections.Generic;
using System.Linq;
using FunkEngine;
@@ -16,8 +17,6 @@ public partial class Scribe : Node
new Note(
0,
"EnemyBase",
- "Basic enemy note, deals damage to player.",
- null,
null,
1,
(director, note, timing) =>
@@ -29,10 +28,8 @@ public partial class Scribe : Node
new Note(
1,
"PlayerBase",
- "Basic player note, deals damage to enemy.",
GD.Load("res://Classes/Notes/Assets/Note_PlayerBasic.png"),
- null,
- 1,
+ 4,
(director, note, timing) =>
{
if (timing == Timing.Miss)
@@ -43,10 +40,8 @@ public partial class Scribe : Node
new Note(
2,
"PlayerDouble",
- "Basic player note, deals double damage to enemy.",
GD.Load("res://Classes/Notes/Assets/Note_PlayerDouble.png"),
- null,
- 2,
+ 8,
(director, note, timing) =>
{
if (timing == Timing.Miss)
@@ -57,9 +52,7 @@ public partial class Scribe : Node
new Note(
3,
"PlayerHeal",
- "Basic player note, heals player.",
GD.Load("res://Classes/Notes/Assets/Note_PlayerHeal.png"),
- null,
1,
(director, note, timing) =>
{
@@ -71,26 +64,22 @@ public partial class Scribe : Node
new Note(
4,
"PlayerVampire",
- "Steals health from enemy.",
GD.Load("res://Classes/Notes/Assets/Note_PlayerVampire.png"),
- null,
- 1,
+ 3,
(director, note, timing) =>
{
if (timing == Timing.Miss)
return;
- int dmg = (int)timing * note.GetBaseVal();
+ int dmg = (int)timing;
director.Player.Heal(dmg);
- director.DealDamage(note, dmg, director.Player);
+ director.DealDamage(note, dmg * note.GetBaseVal(), director.Player);
}
),
new Note(
5,
"PlayerQuarter",
- "Basic note at a quarter of the cost.",
GD.Load("res://Classes/Notes/Assets/Note_PlayerQuarter.png"),
- null,
- 1,
+ 3,
(director, note, timing) =>
{
if (timing == Timing.Miss)
@@ -102,24 +91,20 @@ public partial class Scribe : Node
new Note(
6,
"PlayerBlock",
- "Gives player one charge of block.",
GD.Load("res://Classes/Notes/Assets/Note_PlayerBlock.png"),
- null,
1,
(director, note, timing) =>
{
if (timing == Timing.Miss)
return;
- director.AddStatus(Targetting.Player, StatusEffect.Block.GetInstance()); //todo: should scale with timing????
+ director.AddStatus(Targetting.Player, StatusEffect.Block.CreateInstance()); //todo: should scale with timing????
}
),
new Note(
7,
"PlayerExplosive",
- "Deals damage to all enemies.",
GD.Load("res://Classes/Notes/Assets/Note_PlayerExplosive.png"),
- null,
- 1,
+ 4,
(director, note, timing) =>
{
if (timing == Timing.Miss)
@@ -132,30 +117,131 @@ public partial class Scribe : Node
new Note(
8,
"PlayerEcho",
- "Deals more damage with each loop.",
GD.Load("res://Classes/Notes/Assets/Note_PlayerEcho.png"),
- null,
- 1,
+ 4,
(director, note, timing) =>
{
if (timing == Timing.Miss)
return;
director.DealDamage(note, (int)timing * note.GetBaseVal(), director.Player);
- note.SetBaseVal(note.GetBaseVal() + 1);
+ note.SetBaseVal(note.GetBaseVal() + 2);
}
),
new Note(
9,
"PlayerPoison",
- "Applies stacks of poison based on timing.",
GD.Load("res://Classes/Notes/Assets/Note_PlayerPoison.png"),
- null,
1,
(director, note, timing) =>
{
if (timing == Timing.Miss)
return;
- director.AddStatus(Targetting.First, StatusEffect.Poison.GetInstance((int)timing));
+ director.AddStatus(Targetting.First, StatusEffect.Poison, (int)timing);
+ }
+ ),
+ new Note(
+ 10,
+ "GWS",
+ GD.Load("res://Classes/Notes/Assets/Note_GWS.png"),
+ 1,
+ (director, note, timing) =>
+ {
+ int dmg = 2 * (3 - (int)timing) * note.GetBaseVal() + TimeKeeper.LastBeat.Loop; //Double an enemy base plus the loop num, unless perfect
+ if (timing == Timing.Perfect)
+ dmg = 0;
+ director.DealDamage(Targetting.Player, dmg, note.Owner);
+ }
+ ),
+ new Note(
+ 11,
+ "PlayerMoney",
+ GD.Load("res://Classes/Notes/Assets/Note_PlayerMoney.png"),
+ 1,
+ (director, note, timing) =>
+ {
+ if (timing == Timing.Miss)
+ return;
+ StageProducer.PlayerStats.Money += note.GetBaseVal() * (int)timing;
+ }
+ ),
+ new Note(
+ 12,
+ "PlayerCombo",
+ GD.Load("res://Classes/Notes/Assets/Note_PlayerCombo.png"),
+ 1,
+ (director, note, timing) =>
+ {
+ if (timing == Timing.Miss)
+ return;
+ director.NPB.HandleTiming(
+ timing,
+ (ArrowType)StageProducer.GlobalRng.RandiRange(0, 3)
+ );
+ }
+ ),
+ new Note(
+ 13,
+ "Parasifly",
+ GD.Load("res://Classes/Notes/Assets/Note_Parasifly.png"),
+ 1,
+ (director, note, timing) =>
+ {
+ int amt = Math.Max((3 - (int)timing) * note.GetBaseVal(), 0);
+ director.AddStatus(Targetting.All, StatusEffect.Block, amt);
+ }
+ ),
+ new Note(
+ 14,
+ "BossBlood",
+ GD.Load("res://Classes/Notes/Assets/Note_BossBlood.png"),
+ 2,
+ (director, note, timing) =>
+ {
+ int dmg = (3 - (int)timing) * note.GetBaseVal();
+ director.DealDamage(note, dmg, note.Owner);
+ if (dmg > 0)
+ note.Owner.Heal((3 - (int)timing));
+ },
+ default,
+ Targetting.Player
+ ),
+ new Note(
+ 15,
+ "Spider",
+ GD.Load("res://Classes/Notes/Assets/Note_Spider.png"),
+ 1,
+ (director, note, timing) =>
+ {
+ if (timing == Timing.Perfect)
+ return;
+ int amt = Math.Max((3 - (int)timing) * note.GetBaseVal(), 1);
+ director.AddStatus(Targetting.Player, StatusEffect.Poison, amt);
+ }
+ ),
+ new Note(
+ 16,
+ "LWS",
+ GD.Load("res://Classes/Notes/Assets/Note_LWS.png"),
+ 1,
+ (director, note, timing) =>
+ {
+ int dmg = (3 - (int)timing) * note.GetBaseVal() + (TimeKeeper.LastBeat.Loop / 2);
+ if (timing == Timing.Perfect)
+ dmg = 0;
+ director.DealDamage(Targetting.Player, dmg, note.Owner);
+ }
+ ),
+ new Note(
+ 17,
+ "Mushroom",
+ GD.Load("res://Classes/Notes/Assets/Note_Mushroom.png"),
+ 2,
+ (director, note, timing) =>
+ {
+ if (timing == Timing.Perfect)
+ return;
+ int amt = Math.Max((3 - (int)timing) * note.GetBaseVal(), 1);
+ director.AddStatus(Targetting.Player, StatusEffect.Poison, amt);
}
),
};
@@ -165,14 +251,13 @@ public partial class Scribe : Node
new RelicTemplate(
0,
"Breakfast", //Reference ha ha, Item to give when relic pool is empty.
- "Increases max hp.", //TODO: Description can include the relics values?
Rarity.Breakfast,
GD.Load("res://Classes/Relics/Assets/Relic_Breakfast.png"),
new RelicEffect[]
{
new RelicEffect(
BattleEffectTrigger.OnPickup,
- 10,
+ 15,
(e, self, val) =>
{
StageProducer.PlayerStats.MaxHealth += val;
@@ -184,7 +269,6 @@ public partial class Scribe : Node
new RelicTemplate(
1,
"Good Vibes",
- "Heals the player whenever they place a note.",
Rarity.Common,
GD.Load("res://Classes/Relics/Assets/Relic_GoodVibes.png"),
new RelicEffect[]
@@ -202,7 +286,6 @@ public partial class Scribe : Node
new RelicTemplate(
2,
"Auroboros",
- "Bigger number, better person. Increases combo multiplier every riff.",
Rarity.Common,
GD.Load("res://Classes/Relics/Assets/Relic_Auroboros.png"),
new RelicEffect[]
@@ -221,7 +304,6 @@ public partial class Scribe : Node
new RelicTemplate(
3,
"Colorboros",
- "Taste the rainbow. Charges the freestyle bar every riff.",
Rarity.Common,
GD.Load("res://Classes/Relics/Assets/Relic_Colorboros.png"),
new RelicEffect[]
@@ -240,7 +322,6 @@ public partial class Scribe : Node
new RelicTemplate(
4,
"Chips",
- "Hitting a note deals a bit of damage.",
Rarity.Rare, //This thing is really good imo.
GD.Load("res://Classes/Relics/Assets/Relic_Chips.png"),
new RelicEffect[]
@@ -261,14 +342,13 @@ public partial class Scribe : Node
new RelicTemplate(
5,
"Paper Cut",
- "Deals damage each loop.",
Rarity.Common,
GD.Load("res://Classes/Relics/Assets/Relic_PaperCut.png"),
new RelicEffect[]
{
new RelicEffect(
BattleEffectTrigger.OnLoop,
- 5,
+ 15,
(e, self, val) =>
{
e.BD.DealDamage(Targetting.First, val, null);
@@ -279,7 +359,6 @@ public partial class Scribe : Node
new RelicTemplate(
6,
"Energy Drink",
- "Take a chance to cool down and sip an energy drink to increase your max energy bar.",
Rarity.Common,
GD.Load("res://Classes/Relics/Assets/Relic_EnergyDrink.png"),
new RelicEffect[]
@@ -297,17 +376,16 @@ public partial class Scribe : Node
new RelicTemplate(
7,
"Bandage",
- "A clean strip of cloth. Use it after a fight to patch up and feel better.",
Rarity.Common,
GD.Load("res://Classes/Relics/Assets/Relic_Bandage.png"),
new RelicEffect[]
{
new RelicEffect(
BattleEffectTrigger.OnBattleEnd,
- 10,
+ 20,
(e, self, val) =>
{
- StageProducer.PlayerStats.CurrentHealth += val;
+ e.BD.Player.Heal(val);
}
),
}
@@ -315,7 +393,6 @@ public partial class Scribe : Node
new RelicTemplate(
8,
"Medkit",
- "A small kit with medical supplies. Heals you a bit after each loop.",
Rarity.Common,
GD.Load("res://Classes/Relics/Assets/Relic_Medkit.png"),
new RelicEffect[]
@@ -333,8 +410,7 @@ public partial class Scribe : Node
new RelicTemplate(
9,
"Vinyl Record",
- "Right round, right round. All loop effects trigger twice.",
- Rarity.Legendary,
+ Rarity.Epic,
GD.Load("res://Classes/Relics/Assets/Relic_VinylRecord.png"),
new RelicEffect[]
{
@@ -352,6 +428,158 @@ public partial class Scribe : Node
),
}
),
+ new RelicTemplate(
+ 10,
+ "Loose Change",
+ Rarity.Common,
+ GD.Load("res://Classes/Relics/Assets/Relic_LooseChange.png"),
+ new RelicEffect[]
+ {
+ new RelicEffect(
+ BattleEffectTrigger.OnBattleEnd,
+ 10,
+ (e, self, val) =>
+ {
+ e.BD.BattleScore.IncRelicBonus(val);
+ }
+ ),
+ }
+ ),
+ new RelicTemplate(
+ 11,
+ "Spiked Shield",
+ Rarity.Rare,
+ GD.Load("res://Classes/Relics/Assets/Relic_SpikedShield.png"),
+ new RelicEffect[]
+ {
+ new RelicEffect(
+ BattleEffectTrigger.OnDamageInstance,
+ 5,
+ (e, self, val) =>
+ {
+ if (
+ e is BattleDirector.Harbinger.OnDamageInstanceArgs dmgArgs
+ && dmgArgs.Dmg.Target == e.BD.Player
+ && dmgArgs.Dmg.Damage > 0
+ && e.BD.Player.HasStatus(StatusEffect.Block.CreateInstance())
+ )
+ {
+ e.BD.DealDamage(Targetting.First, val, null);
+ }
+ }
+ ),
+ }
+ ),
+ new RelicTemplate(
+ 12,
+ "Lucky Dice",
+ Rarity.Uncommon,
+ GD.Load("res://Classes/Relics/Assets/Relic_LuckyDice.png"),
+ new RelicEffect[]
+ {
+ new RelicEffect(
+ BattleEffectTrigger.OnPickup,
+ 1,
+ (e, self, val) =>
+ {
+ StageProducer.PlayerStats.Rerolls = 1;
+ }
+ ),
+ }
+ ),
+ new RelicTemplate(
+ 13,
+ "Shortcut",
+ Rarity.Uncommon,
+ GD.Load("res://Classes/Relics/Assets/Relic_Shortcut.png"),
+ new RelicEffect[]
+ {
+ new RelicEffect(
+ BattleEffectTrigger.OnPickup,
+ 1,
+ (e, self, val) =>
+ {
+ StageProducer.PlayerStats.Shortcuts += 1;
+ }
+ ),
+ }
+ ),
+ new RelicTemplate(
+ 14,
+ "Second Pick",
+ Rarity.Uncommon,
+ GD.Load("res://Classes/Relics/Assets/Relic_SecondPick.png"),
+ new RelicEffect[]
+ {
+ new RelicEffect(
+ BattleEffectTrigger.NotePlaced,
+ 20,
+ (e, self, val) =>
+ {
+ if (StageProducer.GlobalRng.RandiRange(1, 100) <= val)
+ e.BD.NPB.IncreaseCharge(StageProducer.PlayerStats.MaxComboBar);
+ }
+ ),
+ }
+ ),
+ new RelicTemplate(
+ 15,
+ "Broken Drumstick",
+ Rarity.Uncommon,
+ GD.Load("res://Classes/Relics/Assets/Relic_BrokenDrumstick.png"),
+ new RelicEffect[]
+ {
+ new RelicEffect(
+ BattleEffectTrigger.OnBattleStart,
+ 10,
+ (e, self, val) =>
+ {
+ //TODO: make damage scale with current act
+ e.BD.DealDamage(Targetting.All, val, e.BD.Player);
+ }
+ ),
+ }
+ ),
+ new RelicTemplate(
+ 16,
+ "Blood Money",
+ Rarity.Epic,
+ GD.Load("res://Classes/Relics/Assets/Relic_BloodMoney.png"),
+ new RelicEffect[]
+ {
+ new RelicEffect(
+ BattleEffectTrigger.OnDamageInstance,
+ 10,
+ (e, self, val) =>
+ {
+ if (
+ e is BattleDirector.Harbinger.OnDamageInstanceArgs dmgArgs
+ && dmgArgs.Dmg.Target == e.BD.Player
+ && e.BD.Player.GetCurrentHealth()
+ < StageProducer.PlayerStats.MaxHealth / 2
+ )
+ StageProducer.PlayerStats.Money += val;
+ }
+ ),
+ }
+ ),
+ new RelicTemplate(
+ 17,
+ "Coupon",
+ Rarity.Common,
+ GD.Load("res://Classes/Relics/Assets/Relic_Coupon.png"),
+ new RelicEffect[]
+ {
+ new RelicEffect(
+ BattleEffectTrigger.OnPickup,
+ 10,
+ (e, self, val) =>
+ {
+ StageProducer.PlayerStats.DiscountPercent += val;
+ }
+ ),
+ }
+ ),
};
public static readonly SongTemplate[] SongDictionary = new[] //Generalize and make pools for areas/room types
@@ -383,9 +611,9 @@ public partial class Scribe : Node
new SongTemplate(
new SongData
{
- Bpm = 60,
+ Bpm = 120,
SongLength = -1,
- NumLoops = 1,
+ NumLoops = 2,
},
"Song2",
"Audio/Song2.ogg",
@@ -404,6 +632,150 @@ public partial class Scribe : Node
"Audio/songMaps/Song3.tres",
[P_TheGWS.LoadPath]
),
+ new SongTemplate(
+ new SongData
+ {
+ Bpm = 90,
+ SongLength = -1,
+ NumLoops = 1,
+ },
+ "TutorialSong",
+ "Audio/TutorialSong.ogg",
+ "Audio/songMaps/TutorialSong.tres",
+ [P_Strawman.LoadPath]
+ ),
+ new SongTemplate(
+ new SongData
+ {
+ Bpm = 176,
+ SongLength = -1,
+ NumLoops = 7,
+ },
+ "YouWillDie:)",
+ "Audio/District_Four.ogg",
+ "Audio/songMaps/TutorialBoss176_7.tres",
+ [P_Effigy.LoadPath]
+ ),
+ new SongTemplate(
+ new SongData
+ {
+ Bpm = 120,
+ SongLength = -1,
+ NumLoops = 4,
+ },
+ "EcholaneSong",
+ "Audio/EcholaneSong.ogg",
+ "Audio/songMaps/EcholaneSong.tres",
+ [P_Turtle.LoadPath]
+ ),
+ new SongTemplate(
+ new SongData
+ {
+ Bpm = 180,
+ SongLength = -1,
+ NumLoops = 1,
+ },
+ "CyberFoxSong",
+ "Audio/CyberFoxSong.ogg",
+ "Audio/songMaps/CyberFoxSong.tres",
+ [P_CyberFox.LoadPath]
+ ),
+ new SongTemplate(
+ new SongData
+ {
+ Bpm = 120,
+ SongLength = -1,
+ NumLoops = 6,
+ },
+ "GobblerSong",
+ "Audio/Gobbler.ogg",
+ "Audio/songMaps/Gobbler.tres",
+ [P_Gobbler.LoadPath]
+ ),
+ new SongTemplate( //9
+ new SongData
+ {
+ Bpm = 130,
+ SongLength = -1,
+ NumLoops = 1,
+ },
+ "Holograeme",
+ "Audio/Holo_ThereItIs.ogg",
+ "Audio/songMaps/HoloRepeat.tres",
+ [P_Holograeme.LoadPath]
+ ),
+ new SongTemplate( //10
+ new SongData
+ {
+ Bpm = 107,
+ SongLength = -1,
+ NumLoops = 7,
+ },
+ "Shapes",
+ "Audio/Shapes.ogg",
+ "Audio/songMaps/Shapes.tres",
+ [P_Shapes.LoadPath]
+ ),
+ new SongTemplate( //11
+ new SongData
+ {
+ Bpm = 130,
+ SongLength = -1,
+ NumLoops = 3,
+ },
+ "Spideer",
+ "Audio/Spider.ogg",
+ "Audio/songMaps/Spider.tres",
+ [P_Spider.LoadPath, P_Spider.LoadPath]
+ ),
+ new SongTemplate( //12
+ new SongData
+ {
+ Bpm = 180,
+ SongLength = -1,
+ NumLoops = 5,
+ },
+ "Squirkel",
+ "Audio/SquirkelSong.ogg",
+ "Audio/songMaps/SquirkelSong.tres",
+ [P_Squirkel.LoadPath]
+ ),
+ new SongTemplate( //13
+ new SongData
+ {
+ Bpm = 100,
+ SongLength = -1,
+ NumLoops = 4,
+ },
+ "Mushroom",
+ "Audio/Mushroom.ogg",
+ "Audio/songMaps/Mushroom.tres",
+ [P_Mushroom.LoadPath]
+ ),
+ new SongTemplate(
+ new SongData
+ {
+ Bpm = 170,
+ SongLength = -1,
+ NumLoops = 9,
+ },
+ "Keythulu",
+ "Audio/KeythuluSong.ogg",
+ "Audio/songMaps/KeythuluSong.tres",
+ [P_Keythulu.LoadPath]
+ ),
+ new SongTemplate( // 15
+ new SongData
+ {
+ Bpm = 99,
+ SongLength = -1,
+ NumLoops = 5,
+ },
+ name: "LWS",
+ audioLocation: "Audio/FrostWaltz.ogg",
+ songMapLocation: "Audio/songMaps/FrostWaltz.tres",
+ enemyScenePath: [P_LWS.LoadPath]
+ ),
};
//Needs to be strictly maintained based on what the player has obtained.
diff --git a/Globals/StageProducer.cs b/Globals/StageProducer.cs
index 3c435ee2..f9606d0a 100644
--- a/Globals/StageProducer.cs
+++ b/Globals/StageProducer.cs
@@ -1,4 +1,5 @@
-using System;
+using System.Collections.Generic;
+using System.Linq;
using System.Threading.Tasks;
using FunkEngine;
using Godot;
@@ -13,28 +14,12 @@ public partial class StageProducer : Node
public static readonly RandomNumberGenerator GlobalRng = new();
- private static readonly MapGrid.MapConfig FirstMapConfig = new MapGrid.MapConfig(
- 7,
- 6,
- 3,
- [10, 1]
- ).AddSetRoom(3, Stages.Chest);
-
- private static readonly MapGrid.MapConfig TestMapConfig = new MapGrid.MapConfig(
- 10,
- 10,
- 5,
- [10, 2]
- )
- .AddSetRoom(3, Stages.Chest)
- .AddSetRoom(6, Stages.Chest);
-
- private static readonly MapGrid.MapConfig[] MapConfigs = new[] { FirstMapConfig };
+ public static MapLevels CurLevel { get; private set; }
+ public static List BattlePool { get; private set; }
public static MapGrid Map { get; private set; } = new();
private Stages _curStage = Stages.Title;
public static int CurRoom { get; private set; }
- public static Area CurArea { get; private set; } = Area.Forest;
private Node _curScene;
private Node _preloadStage;
@@ -52,7 +37,7 @@ public override void _EnterTree()
LiveInstance = this;
}
- private void InitFromCfg()
+ public void InitFromCfg()
{
OptionsMenu.ChangeVolume(
SaveSystem.GetConfigValue(SaveSystem.ConfigSettings.Volume).As()
@@ -70,19 +55,25 @@ private void InitFromCfg()
private void GenerateMapConsistent()
{
- GlobalRng.State = GlobalRng.Seed << 5 / 2; //Fudge seed state, to get consistent maps across new/loaded games
- Map.InitMapGrid(MapConfigs[(int)CurArea]);
+ //Fudge seed state, to get consistent maps across new/loaded games, might be bad practice
+ GlobalRng.State = GlobalRng.Seed << 5 / 2;
+ Map.InitMapGrid(CurLevel.GetCurrentConfig());
}
private void StartNewGame()
{
GlobalRng.Randomize();
- CurArea = Area.Forest;
+ if ((bool)SaveSystem.GetConfigValue(SaveSystem.ConfigSettings.FirstTime))
+ CurLevel = MapLevels.GetLevelFromId(0);
+ else
+ CurLevel = MapLevels.GetLevelFromId(1);
GenerateMapConsistent();
PlayerStats = new PlayerStats();
CurRoom = Map.GetRooms()[0].Idx;
+ BattlePool = null;
+ EventScene.EventPool = null;
Scribe.InitRelicPools();
IsInitialized = true;
}
@@ -96,7 +87,9 @@ private bool LoadGame()
return false;
}
GlobalRng.Seed = sv.RngSeed;
- CurArea = (Area)sv.Area;
+ CurLevel = MapLevels.GetLevelFromId(sv.Area);
+ BattlePool = sv.BattlePool.ToList();
+ EventScene.EventPool = sv.EventPool.ToList();
GenerateMapConsistent();
GlobalRng.State = sv.RngState;
CurRoom = sv.LastRoomIdx;
@@ -114,6 +107,9 @@ private bool LoadGame()
PlayerStats.AddRelic(Scribe.RelicDictionary[relicId]);
}
PlayerStats.CurrentHealth = sv.PlayerHealth;
+ PlayerStats.Money = sv.Money;
+ PlayerStats.Shortcuts = sv.Shortcuts;
+ PlayerStats.MaxComboBar = sv.PlayerMaxCombo;
IsInitialized = true;
return true;
}
@@ -142,6 +138,7 @@ public void PreloadScene(int nextRoomIdx)
Config = MakeBattleConfig(nextStage, nextRoomIdx);
switch (nextStage)
{
+ case Stages.Elite:
case Stages.Battle:
case Stages.Boss:
_loadTask = Task.Run(() =>
@@ -150,6 +147,18 @@ public void PreloadScene(int nextRoomIdx)
.Instantiate();
});
break;
+ case Stages.Event:
+ _loadTask = Task.Run(() =>
+ {
+ _preloadStage = GD.Load(EventScene.LoadPath).Instantiate();
+ });
+ break;
+ case Stages.Shop:
+ _loadTask = Task.Run(() =>
+ {
+ _preloadStage = GD.Load(ShopScene.LoadPath).Instantiate();
+ });
+ break;
case Stages.Chest:
_loadTask = Task.Run(() =>
{
@@ -173,6 +182,9 @@ public void TransitionStage(Stages nextStage, int nextRoomIdx = -1)
break;
case Stages.Battle: //Currently these are only ever entered from map. Be aware if we change
case Stages.Boss: //this, scenes either need to be preloaded first, or a different setup is needed.
+ case Stages.Event:
+ case Stages.Elite:
+ case Stages.Shop:
case Stages.Chest:
_loadTask.Wait(); //Should always finish by the time it gets here, this guarantees it.
GetTree().GetCurrentScene().Free();
@@ -195,7 +207,7 @@ public void TransitionStage(Stages nextStage, int nextRoomIdx = -1)
GetTree().Quit();
return;
case Stages.Continue:
- ProgressAreas();
+ ProgressLevels();
GetTree().ChangeSceneToFile("res://Scenes/Maps/InBetween.tscn");
break;
default:
@@ -210,6 +222,16 @@ public void TransitionStage(Stages nextStage, int nextRoomIdx = -1)
}
#endregion
+ private void RefreshBattlePool()
+ {
+ BattlePool = new List(CurLevel.NormalBattles);
+ for (int i = 0; i < BattlePool.Count - 2; i++)
+ {
+ int randIdx = GlobalRng.RandiRange(0, CurLevel.NormalBattles.Length - 1);
+ (BattlePool[i], BattlePool[randIdx]) = (BattlePool[randIdx], BattlePool[i]); //rad
+ }
+ }
+
private BattleConfig MakeBattleConfig(Stages nextRoom, int nextRoomIdx)
{
BattleConfig result = new BattleConfig
@@ -222,14 +244,29 @@ private BattleConfig MakeBattleConfig(Stages nextRoom, int nextRoomIdx)
switch (nextRoom)
{
case Stages.Battle:
- int songIdx = stageRng.RandiRange(1, 3);
- result.CurSong = Scribe.SongDictionary[songIdx];
- result.EnemyScenePath = Scribe.SongDictionary[songIdx].EnemyScenePath;
+ if (BattlePool == null || BattlePool.Count == 0)
+ RefreshBattlePool();
+ int songIdx = stageRng.RandiRange(0, BattlePool.Count - 1);
+ result.CurSong = Scribe.SongDictionary[BattlePool[songIdx]];
+ result.EnemyScenePath = Scribe.SongDictionary[BattlePool[songIdx]].EnemyScenePath;
+ BattlePool.RemoveAt(songIdx);
+ break;
+ case Stages.Elite:
+ int elitIdx = stageRng.RandiRange(0, CurLevel.EliteBattles.Length - 1);
+ result.CurSong = Scribe.SongDictionary[CurLevel.EliteBattles[elitIdx]];
+ result.EnemyScenePath = Scribe
+ .SongDictionary[CurLevel.EliteBattles[elitIdx]]
+ .EnemyScenePath;
break;
case Stages.Boss:
- result.EnemyScenePath = Scribe.SongDictionary[0].EnemyScenePath;
- result.CurSong = Scribe.SongDictionary[0];
+ int bossIdx = stageRng.RandiRange(0, CurLevel.BossBattles.Length - 1);
+ result.CurSong = Scribe.SongDictionary[CurLevel.BossBattles[bossIdx]];
+ result.EnemyScenePath = Scribe
+ .SongDictionary[CurLevel.BossBattles[bossIdx]]
+ .EnemyScenePath;
break;
+ case Stages.Event:
+ case Stages.Shop:
case Stages.Chest:
break;
default:
@@ -245,11 +282,25 @@ public override void _Input(InputEvent @event)
{
//Consume controller input, if window out of focus.
//This handles ui_input, other scenes need to consume their own.
- if (!GetWindow().HasFocus())
+ if (ControlSettings.IsOutOfFocus(this))
{
GetViewport().SetInputAsHandled();
return;
}
+ if (@event is InputEventKey eventKey && eventKey.Pressed && !eventKey.Echo)
+ {
+ if (eventKey.Keycode == Key.F9)
+ {
+ Image screen = GetViewport().GetTexture().GetImage();
+ if (!DirAccess.DirExistsAbsolute("user://Screenshots"))
+ DirAccess.MakeDirAbsolute("user://Screenshots");
+ screen.SavePng(
+ "user://Screenshots/"
+ + Time.GetDatetimeStringFromSystem().Replace(":", "_")
+ + ".png"
+ );
+ }
+ }
}
#region Area Management
@@ -258,18 +309,20 @@ public override void _Input(InputEvent @event)
/// There should always be a mapconfig for each area. It's preferable to crash later if there isn't even a placeholder config.
///
/// True if there is another area.
- public static bool IsMoreAreas()
+ public static bool IsMoreLevels()
{
- return (int)CurArea + 1 < MapConfigs.Length;
+ return CurLevel.HasMoreMaps();
}
- public void ProgressAreas()
+ public void ProgressLevels()
{
- CurArea += 1;
+ GD.Print(CurLevel.Id);
+ CurLevel = CurLevel.GetNextLevel();
Map = new();
GenerateMapConsistent();
CurRoom = Map.GetRooms()[0].Idx;
+ BattlePool = null;
}
#endregion
diff --git a/Globals/SteamWhisperer.cs b/Globals/SteamWhisperer.cs
new file mode 100644
index 00000000..79c6c078
--- /dev/null
+++ b/Globals/SteamWhisperer.cs
@@ -0,0 +1,99 @@
+using Godot;
+using GodotSteam;
+
+public partial class SteamWhisperer : Node
+{
+ private const uint AppId = 3647600;
+
+ public static bool IsOverlayActive = false;
+
+ private static int placedNotes = 0;
+
+ public override void _EnterTree()
+ {
+ OS.SetEnvironment("SteamAppId", AppId.ToString());
+ OS.SetEnvironment("SteamGameId", AppId.ToString());
+ }
+
+ public override void _ExitTree()
+ {
+ if (!Steam.IsSteamRunning())
+ return;
+ Steam.StoreStats();
+ GD.Print("SW: Steam shut down.");
+ }
+
+ public override void _Ready()
+ {
+ if (!Steam.SteamInit(AppId, true))
+ {
+ GD.PrintErr(
+ "SW: here was an error initializing Steam. No Steam features will be available."
+ );
+ return;
+ }
+
+ GD.Print("SW: Steam initialized successfully.");
+ Steam.OverlayToggled += (active, _, _) =>
+ {
+ IsOverlayActive = active;
+ };
+
+ //Pull in stats
+ placedNotes = Steam.GetStatInt("NotesPlaced");
+ GD.Print($"SW: Placed notes: {placedNotes}");
+
+ //Uncomment this to reset your achievements/stats. There's no confirmation so...
+ //ResetAll();
+ }
+
+ //TODO: This might fail sometimes? IDK, need to look into it
+ public static bool PopAchievement(string id)
+ {
+ if (!Steam.IsSteamRunning())
+ {
+ return false;
+ }
+
+ if (Steam.SetAchievement(id) && Steam.StoreStats())
+ {
+ GD.Print($"SW: Unlocked {id}.");
+ return true;
+ }
+
+ GD.PrintErr($"SW: Failed to set achievement {id}.");
+ return false;
+ }
+
+ //Should make this more generic, but we only have one stat
+ public static bool IncrementNoteCount()
+ {
+ if (!Steam.IsSteamRunning())
+ {
+ return false;
+ }
+
+ placedNotes++;
+
+ if (Steam.SetStatInt("NotesPlaced", placedNotes) && Steam.StoreStats())
+ {
+ GD.Print($"SW: Incremented placed notes to {placedNotes}.");
+ return true;
+ }
+ GD.PrintErr($"SW: Failed to increment placed notes to {placedNotes}.");
+ return false;
+ }
+
+ //For Debugging purposes. Resets all stats/ achievements
+ public static void ResetAll()
+ {
+ if (!Steam.IsSteamRunning())
+ {
+ return;
+ }
+
+ Steam.ResetAllStats(true);
+ Steam.StoreStats();
+ GD.Print("SW: All stats reset.");
+ }
+}
diff --git a/Globals/SteamWhisperer.cs.uid b/Globals/SteamWhisperer.cs.uid
new file mode 100644
index 00000000..529be054
--- /dev/null
+++ b/Globals/SteamWhisperer.cs.uid
@@ -0,0 +1 @@
+uid://bt4f7m5qx106a
diff --git a/Globals/Translations/Translations.csv b/Globals/Translations/Translations.csv
index 6f9346d4..a0b7cb2b 100644
--- a/Globals/Translations/Translations.csv
+++ b/Globals/Translations/Translations.csv
@@ -1,7 +1,7 @@
keys,en,cn
-TITLE,Midnight Riff,中夜现场
+TITLE,Midnzght Riff,中夜现场
TITLE_START,New Game,新游戏
-TITLE_CONTINUE,Load Game,加载游戏
+TITLE_CONTINUE,Load Game,读取存档
TITLE_QUIT,Quit Game,退出游戏
TITLE_OPTIONS,Options,选项
TITLE_CONTROLS,Change Controls,更改操控
@@ -10,76 +10,156 @@ CONTROLS_TITLE_TYPE_QWER,QWERT,QWERT
CONTROLS_TITLE_TYPE_ARROW,Arrow,箭头键
CONTROLS_TITLE_SELECTED,Selected,已选择
CONTROLS_WASD_BUTTON,WASD,WASD
-CONTROLS_CONTROLLER,Controller,控制杆
+CONTROLS_CONTROLLER,Controller,手柄
CONTROLS_KEYBOARD,Keyboard,键盘
CONTROLS_QWER_BUTTON,QWER,QWER
CONTROLS_ARROW_BUTTON,Arrow Keys,箭头键
CONTROLS_RETURN_BUTTON,Return,返回
-CONTROLS_CHOOSE_SCHEME,Choose Control Scheme,选择控制方式
-CONTROLS_CHOOSE_BUTTON,Choose new button,选择输入按钮
+CONTROLS_TUTORIAL_BUTTON,Tutorial,教程
+CONTROLS_CHOOSE_SCHEME,Choose Control Scheme,选择操控方案
+CONTROLS_CHOOSE_BUTTON,Choose new button,选择新按键
+CONTROLS_CHOOSE_TEXT_KEYBOARD,Press Escape to close,按下 Esc 键关闭
+CONTROLS_CHOOSE_TEXT_CONTROLLER,Press Start to close,按下 Start 键关闭
+CONTROLS_CHOOSE_INVALID,"System input, can't be used!",预留输入,无法重定向!
+CONTROLS_CHOOSE_DUPLICATE,"Input already set, can't be used again!",按键已设置,无法重复使用!
ESCAPE_MENU_RESUME,Resume,继续
-ESCAPE_MENU_QUIT,Quit,退出
+ESCAPE_MENU_QUIT,Quit Game,退出游戏
ESCAPE_MENU_TITLE,Quit to Title,返回标题
INBETWEEN_CONTINUE,Continue,继续
-CHEST_ROOM_REWARDS,Reward Selection!,奖励!
+CHEST_ROOM_REWARDS,Reward Selection!,奖励选择!
CHEST_ROOM_SKIP,Skip,跳过
-CHEST_ROOM_ACCEPT,Accept,接受
-CHEST_ROOM_REROLL,Rerolls: ,重刷:
-BATTLE_ROOM_BEGIN_BUTTON,"Begin Battle [Enter]","开始战斗 [Enter]"
-BATTLE_ROOM_PERFECT,Perfect,精准
+CHEST_ROOM_ACCEPT,Accept,确定
+CHEST_ROOM_REROLL,Rerolls: ,重抽:
+SHOP_REMOVAL,Remove A Note,移除音符
+SHOP_CONFIRM,Confirm Purchase,购买已确认
+SHOP_CANCEL,Cancel,取消操作
+REMOVAL_COST,Removal Fee,删除费用
+BATTLE_ROOM_BEGIN_BUTTON,Begin Battle [Enter],开始战斗 [Enter]
+BATTLE_ROOM_PERFECT,Perfect,Perfect
BATTLE_ROOM_GOOD,Good,良好
BATTLE_ROOM_OKAY,Okay,可以
BATTLE_ROOM_MISS,Miss,错误
-BATTLE_ROOM_WIN,"You win!","你获胜了!"
-BATTLE_ROOM_LOSE,"Game Over!","游戏结束!"
+BATTLE_ROOM_WIN,You win!,你赢了!
+BATTLE_ROOM_LOSE,Game Over!,游戏结束!
END_SCREEN_RESTART,Restart,重新开始
BATTLE_ROOM_SKIP_BUTTON,Skip,跳过
BATTLE_ROOM_ACCEPT_BUTTON,Accept,接受
+SCORING_SCENE_TITLE,Scoring,计分
+SCORING_STYLE,Base Style Points,技巧分
+SCORING_PERFECTS,Perfect Multiplier:,"Perfect 倍数:"
+SCORING_PLACED,Placed Multiplier:,已放置倍数:
+SCORING_RELICS,Relic income:,遗物收入:
+SCORING_TOTAL,Coins Earned:,获得硬币:
NOTE_ENEMYBASE_NAME,EnemyBase,敌人基地
-NOTE_ENEMYBASE_TOOLTIP,"Basic enemy note, deals damage to player.","基础敌人音符,对玩家造成伤害"
-NOTE_PLAYERBASE_NAME,PlayerBase,玩家基地
-NOTE_PLAYERBASE_TOOLTIP,"Basic player note, deals damage to enemy.","基础玩家音符,对敌人造成伤害"
-NOTE_PLAYERDOUBLE_NAME,PlayerDouble,玩家双击
-NOTE_PLAYERDOUBLE_TOOLTIP,"Basic player note, deals double damage to enemy.","基础玩家音符,对敌人造成双倍伤害"
-NOTE_PLAYERHEAL_NAME,PlayerHeal,玩家治愈
-NOTE_PLAYERHEAL_TOOLTIP,"Basic player note, heals player.","基础玩家音符,治愈玩家"
-NOTE_PLAYERVAMPIRE_NAME,PlayerVampire,玩家吸血
-NOTE_PLAYERVAMPIRE_TOOLTIP,"Steals health from enemy.","从敌人吸取生命值"
-NOTE_PLAYERQUARTER_NAME,PlayerQuarter,玩家一分之一
-NOTE_PLAYERQUARTER_TOOLTIP,"Basic note at a quarter of the cost.","以四分之一的耗费时间量发出基础音符"
-NOTE_PLAYERBLOCK_NAME,PlayerBlock,玩家格挡
-NOTE_PLAYERBLOCK_TOOLTIP,"Gives player one charge of block.","给予玩家一层格挡充能。"
-NOTE_PLAYEREXPLOSIVE_NAME,PlayerExplosive,玩家炸药
-NOTE_PLAYEREXPLOSIVE_TOOLTIP,"Deals damage to all enemies.","对所有敌人造成伤害"
-NOTE_PLAYERECHO_NAME,PlayerEcho,玩家回声
-NOTE_PLAYERECHO_TOOLTIP,"Deals more damage with each loop.","每次循环造成更多伤害"
-NOTE_PLAYERPOISON_NAME,PlayerPoison,玩家中毒
-NOTE_PLAYERPOISON_TOOLTIP,"Applies stacks of poison based on timing.","根据时机施加中毒层数"
+NOTE_ENEMYBASE_TOOLTIP,"Basic enemy note, deals damage to player.",基础敌人音符,对玩家造成伤害。
+NOTE_PLAYERBASE_NAME,Basic Note,基本音符
+NOTE_PLAYERBASE_TOOLTIP,"Basic player note, deals damage to enemy.",基础玩家音符,对敌人造成伤害。
+NOTE_PLAYERDOUBLE_NAME,Double Note,双重音符
+NOTE_PLAYERDOUBLE_TOOLTIP,"Basic player note, deals double damage to enemy.",基础玩家音符,对敌人造成双倍伤害。
+NOTE_PLAYERHEAL_NAME,Heal Note,治疗音符
+NOTE_PLAYERHEAL_TOOLTIP,"Basic player note, heals player.",基础玩家音符,治愈玩家。
+NOTE_PLAYERVAMPIRE_NAME,Vampire Note,吸血鬼音符
+NOTE_PLAYERVAMPIRE_TOOLTIP,Steals health from enemy.,从敌人吸取生命值。
+NOTE_PLAYERQUARTER_NAME,Quarter Note,四分音符
+NOTE_PLAYERQUARTER_TOOLTIP,Basic note at a quarter of the cost.,以四分之一的耗费时间量发出基础音符。
+NOTE_PLAYERBLOCK_NAME,Block Note,块音符
+NOTE_PLAYERBLOCK_TOOLTIP,Gives player one charge of block.,给予玩家一层格挡充能。
+NOTE_PLAYEREXPLOSIVE_NAME,Explosive Note,爆炸音符
+NOTE_PLAYEREXPLOSIVE_TOOLTIP,Deals damage to all enemies.,对所有敌人造成伤害。
+NOTE_PLAYERECHO_NAME,Echo Note,回音符
+NOTE_PLAYERECHO_TOOLTIP,Deals more damage with each loop.,每次循环造成更多伤害。
+NOTE_PLAYERPOISON_NAME,Poison Note,毒药音符
+NOTE_PLAYERPOISON_TOOLTIP,Applies stacks of poison based on timing.,根据时机施加中毒层数。
+NOTE_PLAYERMONEY_NAME,Money Note,钱的便条
+NOTE_PLAYERMONEY_TOOLTIP,"Deals no damage, but gives you money when hit.",不会造成伤害,但命中时会获得金钱。
+NOTE_PLAYERCOMBO_NAME,Combo Note,连击音符
+NOTE_PLAYERCOMBO_TOOLTIP,"Deals no damage, but gives you double the combo bar charge when hit.",不会造成伤害,但命中时会获得双倍连击槽充能。
RELIC_BREAKFAST_NAME,Breakfast,早餐
-RELIC_BREAKFAST_TOOLTIP,"Increases max hp.",提高最大生命值
+RELIC_BREAKFAST_TOOLTIP,Increases max hp.,提高最大生命值
RELIC_GOODVIBES_NAME,Good Vibes,良好消息
-RELIC_GOODVIBES_TOOLTIP,"Heals the player whenever they place a note.","每开始一个音符时治愈玩家"
+RELIC_GOODVIBES_TOOLTIP,Heals the player whenever they place a note.,每开始一个音符时治愈玩家
RELIC_AUROBOROS_NAME,Auroboros,无尾蛇
-RELIC_AUROBOROS_TOOLTIP,"Bigger number, better person. Increases combo multiplier every riff.","进一步增加综合倍数,每次现场提升"
+RELIC_AUROBOROS_TOOLTIP,"Bigger number, better person. Increases combo multiplier every loop.",更大的数字,更棒的人。每轮循环增加连击倍数。
RELIC_COLORBOROS_NAME,Colorboros,彩蛇轮回
-RELIC_COLORBOROS_TOOLTIP,"Taste the rainbow. Charges the freestyle bar every riff.","品尝临岛,每次现场充值自由格条"
-RELIC_CHIPS_NAME,"Chips",薯片
-RELIC_CHIPS_TOOLTIP,"Hitting a note deals a bit of damage.","击中音符会造成少量伤害。"
+RELIC_COLORBOROS_TOOLTIP,Taste the rainbow. Charges the freestyle bar every loop.,品尝彩虹。每轮循环为风格条充能。
+RELIC_CHIPS_NAME,Chips,薯片
+RELIC_CHIPS_TOOLTIP,Hitting a note deals a bit of damage.,击中音符会造成少量伤害。
RELIC_PAPERCUT_NAME,Paper Cut,纸割伤
-RELIC_PAPERCUT_TOOLTIP,"Deals damage each riff.","每轮造成伤害"
-RELIC_ENERGYDRINK_NAME,Energy Drink,"能量饮料"
-RELIC_ENERGYDRINK_TOOLTIP,"Take a chance to cool down and sip an energy drink to increase your max energy bar.","碰碰运气,喝一口能量饮料来冷静下来并增加你的最大能量条。"
-RELIC_BANDAGE_NAME,Bandage,"绷带"
-RELIC_BANDAGE_TOOLTIP,"A clean strip of cloth. Use it after a fight to patch up and feel better.","一块干净的布条,战斗后使用来包扎并恢复一些健康。"
-RELIC_MEDKIT_NAME,Medkit,"急救包"
-RELIC_MEDKIT_TOOLTIP,"A small kit with medical supplies. Heals you a bit after each riff.","包含一些医疗用品的小包,每次循环后恢复少量生命。"
-RELIC_VINYLRECORD_NAME,Vinyl Record,"黑胶唱片"
-RELIC_VINYLRECORD_TOOLTIP,"Right round, right round. All riff effects trigger twice.","把我转起来,把我转起来。所有循环效果触发两次。"
+RELIC_PAPERCUT_TOOLTIP,Deals damage each loop.,每轮造成伤害。
+RELIC_ENERGYDRINK_NAME,Energy Drink,能量饮料
+RELIC_ENERGYDRINK_TOOLTIP,Take a chance to cool down and sip an energy drink to make your freestyle bar charge faster.,休息一下,补充能量,自由风格能量恢复得更快。
+RELIC_BANDAGE_NAME,Bandage,绷带
+RELIC_BANDAGE_TOOLTIP,A clean strip of cloth. Used after every fight to patch up and feel better.,一块干净的布条,战斗后使用来包扎并恢复一些健康。
+RELIC_MEDKIT_NAME,Medkit,急救包
+RELIC_MEDKIT_TOOLTIP,A small kit with medical supplies. Heals you a bit after each loop.,包含一些医疗用品的小包,每次循环后恢复少量生命。
+RELIC_VINYLRECORD_NAME,Vinyl Record,黑胶唱片
+RELIC_VINYLRECORD_TOOLTIP,"Right round, right round. All loop effects trigger twice.",把我转起来,把我转起来。所有循环效果触发两次。
+RELIC_LOOSECHANGE_NAME,Loose Change,零钱
+RELIC_LOOSECHANGE_TOOLTIP,Gain extra money after battles.,战斗后获得额外金钱。
+RELIC_SPIKEDSHIELD_NAME,Spiked Shield,尖刺之盾
+RELIC_SPIKEDSHIELD_TOOLTIP,Deal damage when you lose a charge of block.,失去格挡层数时造成伤害。
+RELIC_LUCKYDICE_NAME,Lucky Dice,幸运骰子
+RELIC_LUCKYDICE_TOOLTIP,Gain one reroll for reward selections.,获得一次奖励重选。
+RELIC_SHORTCUT_NAME,Shortcut,捷径
+RELIC_SHORTCUT_TOOLTIP,"Can choose any path regardless of connections, but only once.",可无视路径连接选择任意路线,但仅限一次。
+RELIC_SECONDPICK_NAME,Second Pick,备用拨片
+RELIC_SECONDPICK_TOOLTIP,Placing a note has a 20% chance to instantly refill the combo bar.,每次演奏音符时,有20%的几率立即填满连击槽。
+RELIC_BROKENDRUMSTICK_NAME,Broken Drumstick,破碎的鼓棒
+RELIC_BROKENDRUMSTICK_TOOLTIP,Enemies start combat damaged.,敌人在战斗开始时受到伤害。
+RELIC_BLOODMONEY_NAME,Blood Money,血腥钱袋
+RELIC_BLOODMONEY_TOOLTIP,Gain money when taking damage below half health.,在生命值低于一半时受到伤害可获得金钱。
+RELIC_COUPON_NAME,Coupon,优惠券
+RELIC_COUPON_TOOLTIP,Get a 10% discount on notes and relics in the shop.,在商店购买音符和遗物时可享受9折优惠。
INVENTORY_TAB_NOTES,Notes,乐谱
INVENTORY_TAB_RELICS,Relics,遗物
OPTIONS_VOLUME_LABEL,Master Volume,最终音量设置
OPTIONS_CONTRAST_LABEL,High Contrast,高对比度模式
HOW_TO_PLAY,How to Play,如何游玩
-HOW_TO_PLAY_BLOCK1,"Hit notes to\nbuild combo","点击音符\n以建立连击"
-HOW_TO_PLAY_BLOCK2,"Place notes when\ncombo is full","当连击满\n时放置音符"
-HOW_TO_PLAY_BLOCK3,"Only placed notes\nhave effects","只有已放置\n的音符才有效"
\ No newline at end of file
+HOW_TO_PLAY_BLOCK1,Hit notes to\nbuild combo,点击音符\n以建立连击
+HOW_TO_PLAY_BLOCK2,Place notes when\ncombo is full,当连击满\n时放置音符
+HOW_TO_PLAY_BLOCK3,Only placed notes\nhave effects,只有已放置\n的音符才有效
+TUTORIAL_NODYING,No dying during a tutorial!,教程中不会死亡!
+TUTORIAL_DIALOGUE_1,"Hello, welcome to Midnight Riff!",你好!欢迎来到午夜即兴!
+TUTORIAL_DIALOGUE_2,This is a rhythm game where notes move right to left.,这是一款节奏游戏,音符从右向左移动。
+TUTORIAL_DIALOGUE_3,"Press the correct button as the notes line up to hit the note. Try to time it as well as you can!",音符对齐时按下正确的按键,尽量精准地进行点击!
+TUTORIAL_DIALOGUE_4,"What are the correct buttons? I'll help you out and show you. These can be changed from the meu. Once you press continue we can get started!",正确的按键是什么?我会帮你指出来。这些可以在菜单中更改。按下继续后,我们就可以开始了!
+TUTORIAL_LOOP_1,At set intervals the chart loops! This means all notes on the chart repeat. You know a loop is coming up when this symbol scrolls by.,在固定的时间间隔内,乐谱会循环!这意味着乐谱上的所有音符都会重复出现。当这个符号滚动经过时,你就知道循环即将开始。
+TUTORIAL_LOOP_2,"In case you haven't noticed, I'll explain these things on the left side. This is your note queue.",如果你还没注意到,我会在左侧解释这些内容。这是你的音符队列。
+TUTORIAL_LOOP_3,"This is the combo multiplier, as you hit notes successfully your multiplier will rise. If you miss a note, your multiplier gets reset.",这是连击倍数,成功点击音符后,你的倍数将会上升。如果你错过了一个音符,你的倍数将会重置。
+TUTORIAL_LOOP_4,"This is the freestyle bar, as you hit notes successfully, the freestyle bar fills. The higher your multiplier the more this fills.",这是风格条,成功点击音符后,风格条将会填充。你的倍数越高,填充速度越快。
+TUTORIAL_LOOP_5,"By now you've probably taken damage. These aren't just cozy songs, these are battles! You take damage when you miss or have bad timing, or from enemy effects. How do you deal damage to enemies? Fill up the bar and I'll tell you.",到目前为止,你可能已经受到伤害了。这些不仅仅是轻松的歌曲,它们是战斗!你错过音符或时机不好,或者受到敌人的效果影响时,都会受到伤害。你如何对敌人造成伤害?填满能量条,我会告诉你。
+TUTORIAL_PLACE_1,"Okay, now that the bar is full, you can press a lane button to place your own note. Your notes have special effects. Placing notes consumes the freestyle bar.",好的,现在能量条已满,你可以按下轨道按键放置你自己的音符。你的音符具有特殊效果。放置音符会消耗风格条。
+TUTORIAL_PLACE_2,These note effects range from dealing damage to applying status effects!,这些音符效果从造成伤害到施加状态效果不等!
+TUTORIAL_PLACE_3,"Your notes can be placed anywhere a note doesn't already exist, and that isn't over the loop marker. But be careful, if you try to place a note while the bar isn't full you may miss a note!",你的音符可以放置在任何没有音符存在且不在循环标记上的位置。但是要小心,如果你试图在能量条未满时放置音符,你可能会错过音符!
+TUTORIAL_PLACE_4,"The note you'll place is indicated in the top of the note queue.",你将要放置的音符显示在音符队列顶部。
+TUTORIAL_PLACE_5,"Notes are automatically hit when you place them, how helpful, but they come back around when the chart loops, and you need to time hitting them then.",放置音符时会自动击中,这非常方便,但当乐谱循环时它们会再次出现,你需要掌握时机才能击中它们。
+TUTORIAL_PLACE_6,"Now go ahead, place a note in the bottom lane!",现在,在最下方的轨道上放置一个音符吧!
+TUTORIAL_FINAL_1,"Good job, you placed a note! You either healed yourself, or dealt damage. I can't tell I'm just a Strawman.",干得好,你放置了一个音符!你或者治愈了自己,或者造成了伤害。我无法判断,我只是个稻草人。
+TUTORIAL_FINAL_2,"As a refresher: Hit notes to fill the bar. When the bar is full, press one of your lane buttons that doesn't have a note under it. Notes in the chart will loop around. Keep it up to win.",回顾一下:点击音符以填充能量条。当能量条已满时,按下没有音符的轨道按键。乐谱中的音符会循环出现。坚持下去就能获胜!
+TUTORIAL_FINAL_3,Good luck! I believe in you.,祝你好运!我相信你!
+TUTORIAL_BOSS,"This may take some getting used to, but death is ok in the grand scheme of things. Just have some patience with yourself, you'll learn in the end.",这可能需要一些时间来适应,但在全局来看,死亡是可以接受的。只要对自己有耐心,你最终会学会的。
+EVENT_CONTINUE_BUTTON,Continue,继续
+EVENT_EVENT1_DESC,A bandit approaches you.,一个强盗拦住了你。
+EVENT_EVENT1_OPTION1,Give them a random note,给他一个随机音符
+EVENT_EVENT1_OPTION2,Give them a random relic,给他一件随机遗物
+EVENT_EVENT1_OPTION3,Give them half your gold,给他你一半的金币
+EVENT_EVENT1_OUTCOME1,You got robbed of a random note.,你被抢走了一个随机音符
+EVENT_EVENT1_OUTCOME2,You got robbed of a random relic.,你被抢走了一件随机遗物
+EVENT_EVENT1_OUTCOME3,You got robbed of half your gold.,你被抢走了一半金币
+EVENT_EVENT2_DESC,There is a wheel with different outcomes.,这里有一个转盘,结果各不相同。
+EVENT_EVENT2_OPTION1,Spin the wheel,转动转盘
+EVENT_EVENT2_OPTION2,Ignore the cool wheel,忽略这个酷炫的转盘
+EVENT_EVENT2_OUTCOME1,You decided not to spin the wheel.,你决定不转动转盘。
+EVENT_EVENT2_OUTCOME2,You lost half your money.,你损失了一半的金币。
+EVENT_EVENT2_OUTCOME3,You took some damage.,你受到了一些伤害。
+EVENT_EVENT2_OUTCOME4,You won a lot of money!,你赢得了很多金币!
+EVENT_EVENT2_OUTCOME5,You gained a random note!,你获得了一个随机音符!
+EVENT_EVENT2_OUTCOME6,You gained a random relic!,你获得了一件随机遗物!
+EVENT_EVENT2_OUTCOME7,You gained some health!,你恢复了一些生命值!
+EVENT_EVENT3_DESC,There is a field medic on the side of the road.,路边有一名战地医生。
+EVENT_EVENT3_OPTION1,Receive a bit of healing,接受一些治疗
+EVENT_EVENT3_OPTION2,Increase bar charge rate.,提高能量条充能速度
+EVENT_EVENT3_OPTION3,Purchase 2 heal notes (30g),购买2个治疗音符 (30硬币)
+EVENT_EVENT3_OUTCOME1,The medic patched you up.\nYou restored 10 Health.,医生为你包扎了伤口。\n你恢复了10点生命值。
+EVENT_EVENT3_OUTCOME2,The medic gave you a shot of adrenaline.\nFreestyle bar fills 8% faster!,医生给你注射了一针肾上腺素。\n风格条充能速度提升8%!
+EVENT_EVENT3_OUTCOME3,The medic sold you some healing supplies.\nAdded 2 heal notes to your inventory.,医生卖给你一些治疗用品。\n你的背包中增加了2个治疗音符。
\ No newline at end of file
diff --git a/README.md b/README.md
index 1f0f4ecc..b7f77ed8 100644
--- a/README.md
+++ b/README.md
@@ -10,11 +10,11 @@ We now have a Steam page!
## Team Members
### Programmers
-- **Jarod Spanger** – Project Lead
+- **Jarod Spanger** – Producer / Lead Developer
- Connor Lowe - Combat Designer
-- Raul Mojarro
-- Michael Quinn
- Thomas Wessel - Tools / Engine Lead
+- Raul Mojarro - Programming Support
+- Michael Quinn - Design Support
### Artists
- **Evelyn Fu** - Art Lead
@@ -30,9 +30,27 @@ We now have a Steam page!
### Music
- **Title Screen**: [Crystal Cave – Cynicmusic](https://opengameart.org/content/crystal-cave-song18)
-- **Boss Song 1**: [gameMusic – Magntron](https://freesound.org/people/Magntron/sounds/335571/)
-- **Battle Song 1**: [Piano loops 181 – josefpres](https://freesound.org/people/josefpres/sounds/789998/)
-- **Battle Song 2**: [Dark loops 220 – josefpres](https://freesound.org/people/josefpres/sounds/620230/)
+- **Tutorial Song**: [Mute bass 002 – josefpres](https://freesound.org/people/josefpres/sounds/792389/)
+- **Parasifly Song**: [Piano loops 181 – josefpres](https://freesound.org/people/josefpres/sounds/789998/)
+- **Squirkel Song:** [Bass Stories](https://pixabay.com/music/happy-childrens-tunes-bass-stories-15656/)
+- **Weaver Song:** [Jungle-ish beat for video games](https://pixabay.com/music/video-games-jungle-ish-beat-for-video-games-314073/)
+- **GWS Song**: [Dark loops 220 – josefpres](https://freesound.org/people/josefpres/sounds/620230/)
+- **Elite Mushroom Song:** [Mysterious Ambience](https://opengameart.org/content/mysterious-ambience-song21)
+- **Boss Blood Song**: [gameMusic – Magntron](https://freesound.org/people/Magntron/sounds/335571/)
+- **Shape Dudes Song:** [Data - Karl Casey](https://karlcasey.bandcamp.com/track/data)
+- **Gobbler Song:** [Punk - Mere Notilde](https://notilde.bandcamp.com/track/punk)
+- **BoomFox Song:** [We're Finally Landing - HOME](https://soundcloud.com/home-2001/home-before-the-night-01-were)
+- **Mafioso Turtle Song**: [Echolane](https://echoln.bandcamp.com/)
+- **Keythulu Song:** [Resonance - HOME](https://open.spotify.com/track/1TuopWDIuDi1553081zvuU)
+- **LWS Song**: "Frost Waltz" Kevin MacLeod ([incompetech.com](https://incompetech.com/))
+ Licensed under Creative Commons: By Attribution 4.0 License
+ [http://creativecommons.org/licenses/by/4.0/](http://creativecommons.org/licenses/by/4.0/)
+- **Holograeme Song**: "There It Is" Kevin MacLeod ([incompetech.com](https://incompetech.com/))
+Licensed under Creative Commons: By Attribution 4.0 License
+[http://creativecommons.org/licenses/by/4.0/](http://creativecommons.org/licenses/by/4.0/)
+- **Effigy Song**: "District Four" Kevin MacLeod ([incompetech.com](https://incompetech.com/))
+ Licensed under Creative Commons: By Attribution 4.0 License
+ [http://creativecommons.org/licenses/by/4.0/](http://creativecommons.org/licenses/by/4.0/)
### Images
- **Input Buttons**: [inputKeys – Nicolae (Xelu) Berbece](https://thoseawesomeguys.com/prompts/)
@@ -40,6 +58,7 @@ We now have a Steam page!
- **Title Screen Font**: [04B-30 – Yuji Oshimoto](http://04.jp.org/)
- **Main System Font**: [Fibberish - nathan scott](https://caffinate.itch.io/fibberish/)
+
---
## Licensing Notice
@@ -47,4 +66,3 @@ We now have a Steam page!
The repository license **does not** apply to any music or image files in this repository, including but not limited to `.wav`, `.mp3`, `.ogg`, `.png`, `.jpg`, and other media formats. These assets are **not licensed** for use, private or public, without prior written consent from the team.
All source code and documentation files are licensed under the **GNU Affero General Public License v3.0 (AGPL-3.0)**.
-
diff --git a/Scenes/AreaBasedBackground.cs b/Scenes/AreaBasedBackground.cs
index 8a5275a2..5dc2a560 100644
--- a/Scenes/AreaBasedBackground.cs
+++ b/Scenes/AreaBasedBackground.cs
@@ -6,11 +6,9 @@ public partial class AreaBasedBackground : TextureRect
{
public override void _Ready()
{
- Texture = StageProducer.CurArea switch
- {
- Area.Forest => GD.Load("res://SharedAssets/BackGround_Full.png"),
- Area.City => GD.Load("res://icon.svg"),
- _ => null,
- };
+ if (StageProducer.CurLevel == null)
+ Texture = GD.Load("res://SharedAssets/BackGround_Full.png");
+ else
+ Texture = GD.Load(StageProducer.CurLevel.BackgroundPath);
}
}
diff --git a/Scenes/BattleDirector/Assets/PlacementBar_Over.png b/Scenes/BattleDirector/Assets/PlacementBar_Over.png
new file mode 100644
index 00000000..0eb4c832
Binary files /dev/null and b/Scenes/BattleDirector/Assets/PlacementBar_Over.png differ
diff --git a/Scenes/BattleDirector/Assets/PlacementBar_Over.png.import b/Scenes/BattleDirector/Assets/PlacementBar_Over.png.import
new file mode 100644
index 00000000..a3c475cd
--- /dev/null
+++ b/Scenes/BattleDirector/Assets/PlacementBar_Over.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bi4tbiovlm2g1"
+path="res://.godot/imported/PlacementBar_Over.png-722f7fd710d92c69b5dce0436cfc0371.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Scenes/BattleDirector/Assets/PlacementBar_Over.png"
+dest_files=["res://.godot/imported/PlacementBar_Over.png-722f7fd710d92c69b5dce0436cfc0371.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/Scenes/BattleDirector/Assets/PlacementBar_Under.png b/Scenes/BattleDirector/Assets/PlacementBar_Under.png
new file mode 100644
index 00000000..c368a7ea
Binary files /dev/null and b/Scenes/BattleDirector/Assets/PlacementBar_Under.png differ
diff --git a/Scenes/BattleDirector/Assets/PlacementBar_Under.png.import b/Scenes/BattleDirector/Assets/PlacementBar_Under.png.import
new file mode 100644
index 00000000..005fb224
--- /dev/null
+++ b/Scenes/BattleDirector/Assets/PlacementBar_Under.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://gcst7q2acsqm"
+path="res://.godot/imported/PlacementBar_Under.png-84ec66c19986e47bfef867136a8b52d0.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Scenes/BattleDirector/Assets/PlacementBar_Under.png"
+dest_files=["res://.godot/imported/PlacementBar_Under.png-84ec66c19986e47bfef867136a8b52d0.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/Scenes/BattleDirector/Assets/wave.gdshader b/Scenes/BattleDirector/Assets/wave.gdshader
new file mode 100644
index 00000000..244f8927
--- /dev/null
+++ b/Scenes/BattleDirector/Assets/wave.gdshader
@@ -0,0 +1,72 @@
+shader_type canvas_item;
+
+uniform float fillLevel : hint_range(0.0, 1.0) = 0.5;
+uniform float waveIntensity : hint_range(0.0, 3.0) = 1.0;
+uniform sampler2D waveGradient;
+uniform vec4 backWaveTint : source_color = vec4(0.7, 0.7, 0.8, 1.0);
+
+void fragment() {
+ vec2 centeredUV = UV * 2.0 - 1.0;
+
+ vec4 outputColor = vec4(0.0, 0.0, 0.0, 1.0);
+
+ //Only do stuff if the bar is filled
+ if (fillLevel > 0.0) {
+
+ ////**** Gradient Texture Sampling ****////
+
+ //Gets the centered pos of the fillLevel
+ float centeredFillLevel = mix(1.0, -1.0, fillLevel);
+
+ //Calculate where we should sample the gradient for this section of the water
+ float gradientPosition = fillLevel - (centeredUV.y - centeredFillLevel) / 2.0;
+
+ //Finally get the color from the gradient
+ vec4 sampledColorFromGradient = texture(waveGradient, vec2(gradientPosition, 0.5));
+
+ ////**** Wave Sim ****////
+
+ float waveBase = smoothstep(0.1, 0.9, sin(centeredUV.x * 2.0 + PI * 0.5) - 0.3);
+
+ float centerWaveAmp = 0.05 * waveIntensity; //How much larger the center wave should be
+ float mainWaveAmp = 0.04 * waveIntensity; //Overall sin amplitude
+ float surfaceRippleAmp = 0.03 * waveIntensity; //How much the two waves should vary
+ float verticalMovement = 0.03 * waveIntensity; //How much it moves vertically
+
+ //Flatten stuff out if the bar is full
+ if (fillLevel > 0.9999) {
+ centerWaveAmp = 0.0;
+ mainWaveAmp = 0.0;
+ surfaceRippleAmp = 0.0;
+ verticalMovement = 0.0;
+ }
+
+ //How far from the the bottom the waves should appear
+ float waveHeight = mix(1.0, -1.0, fillLevel) + sin(TIME * PI * 0.5) * verticalMovement;
+
+ //Offset wave position and change direction
+ float frontWaveYOffset = sin((TIME * 2.0 + centeredUV.x * 3.0) * 2.0) * mainWaveAmp;
+ float backWaveYOffset = sin((TIME * -2.0 + centeredUV.x * 3.0 + PI) * 2.0) * mainWaveAmp;
+
+ //Calc surface ripples
+ float surfaceAmplitudes = sin(TIME * 3.0) * surfaceRippleAmp * waveBase;
+
+ //Final Y positions of the waves
+ float frontWaveY = waveHeight - (surfaceAmplitudes + frontWaveYOffset);
+ float backWaveY = waveHeight - (-surfaceAmplitudes + backWaveYOffset);
+
+ //Determine which wave is in front for this fragment
+ float isBelowFrontWave = step(frontWaveY, centeredUV.y);
+ float isBelowBackWave = step(backWaveY, centeredUV.y);
+
+ float backOnlyVisibility = clamp(isBelowBackWave - isBelowFrontWave, 0.0, 1.0);
+
+ if (isBelowFrontWave > 0.5) {
+ outputColor = sampledColorFromGradient; //Just assign the color
+ } else if (backOnlyVisibility > 0.5) {
+ outputColor = vec4(sampledColorFromGradient.rgb * backWaveTint.rgb,sampledColorFromGradient.a * backWaveTint.a);
+ }
+ }
+
+ COLOR = outputColor;
+}
\ No newline at end of file
diff --git a/Scenes/BattleDirector/Assets/wave.gdshader.uid b/Scenes/BattleDirector/Assets/wave.gdshader.uid
new file mode 100644
index 00000000..587fff4e
--- /dev/null
+++ b/Scenes/BattleDirector/Assets/wave.gdshader.uid
@@ -0,0 +1 @@
+uid://difiiwiddwutp
diff --git a/Scenes/BattleDirector/BattleScene.tscn b/Scenes/BattleDirector/BattleScene.tscn
index 647e287b..c135a47e 100644
--- a/Scenes/BattleDirector/BattleScene.tscn
+++ b/Scenes/BattleDirector/BattleScene.tscn
@@ -19,15 +19,16 @@ gradient = SubResource("Gradient_8uy3a")
fill_from = Vector2(1, 0)
fill_to = Vector2(0.738532, 1)
-[node name="ProtoBattleDirector" type="Node2D" node_paths=PackedStringArray("PuppetMarkers", "CD", "CM", "NPB", "Audio", "_focusedButton")]
+[node name="ProtoBattleDirector" type="Node2D" node_paths=PackedStringArray("PuppetMarkers", "_countdownLabel", "CD", "CM", "NPB", "Audio", "FocusedButton")]
process_mode = 1
script = ExtResource("1_jmdo1")
PuppetMarkers = [NodePath("PlayerMarker"), NodePath("Enemy1Marker"), NodePath("Enemy2Marker"), NodePath("Enemy3Marker")]
+_countdownLabel = NodePath("CountInControl/Countdown")
CD = NodePath("Conductor")
CM = NodePath("SubViewport")
NPB = NodePath("NotePlacementBar")
Audio = NodePath("AudioStreamPlayer")
-_focusedButton = NodePath("StartButton")
+FocusedButton = NodePath("StartButton")
metadata/_edit_lock_ = true
[node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."]
@@ -90,3 +91,39 @@ offset_right = 443.0
offset_bottom = 267.0
theme = ExtResource("8_62qim")
text = "BATTLE_ROOM_BEGIN_BUTTON"
+
+[node name="CountInControl" type="Control" parent="."]
+z_index = 1
+layout_mode = 3
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+offset_right = 640.0
+offset_bottom = 360.0
+grow_horizontal = 2
+grow_vertical = 2
+size_flags_horizontal = 3
+size_flags_vertical = 3
+size_flags_stretch_ratio = 0.0
+mouse_filter = 2
+
+[node name="Countdown" type="Label" parent="CountInControl"]
+visible = false
+layout_mode = 1
+anchors_preset = 8
+anchor_left = 0.5
+anchor_top = 0.5
+anchor_right = 0.5
+anchor_bottom = 0.5
+offset_left = -0.5
+offset_top = -6.0
+offset_right = 0.5
+offset_bottom = 6.0
+grow_horizontal = 2
+grow_vertical = 2
+theme_override_colors/font_shadow_color = Color(0, 0, 0, 1)
+theme_override_constants/shadow_offset_x = 3
+theme_override_constants/shadow_offset_y = 3
+theme_override_constants/shadow_outline_size = 3
+theme_override_font_sizes/font_size = 64
+text = "5"
diff --git a/Scenes/BattleDirector/NotePlacementBar.tscn b/Scenes/BattleDirector/NotePlacementBar.tscn
index 492ee90b..1fc0ddd2 100644
--- a/Scenes/BattleDirector/NotePlacementBar.tscn
+++ b/Scenes/BattleDirector/NotePlacementBar.tscn
@@ -1,22 +1,27 @@
-[gd_scene load_steps=12 format=3 uid="uid://duhiilcv4tat3"]
+[gd_scene load_steps=15 format=3 uid="uid://duhiilcv4tat3"]
[ext_resource type="Script" uid="uid://gj666xe815py" path="res://Scenes/BattleDirector/Scripts/NotePlacementBar.cs" id="1_456es"]
[ext_resource type="Texture2D" uid="uid://cnyr5usjdv0ni" path="res://Scenes/BattleDirector/Assets/NoteQueue_Frame.png" id="2_3tw16"]
+[ext_resource type="Texture2D" uid="uid://gcst7q2acsqm" path="res://Scenes/BattleDirector/Assets/PlacementBar_Under.png" id="2_5a8x5"]
+[ext_resource type="Shader" uid="uid://difiiwiddwutp" path="res://Scenes/BattleDirector/Assets/wave.gdshader" id="2_kb2co"]
[ext_resource type="Texture2D" uid="uid://c3chrsxrulapd" path="res://Classes/Notes/Assets/Note_PlayerBasic.png" id="3_6ylx6"]
+[ext_resource type="Texture2D" uid="uid://bi4tbiovlm2g1" path="res://Scenes/BattleDirector/Assets/PlacementBar_Over.png" id="3_kb2co"]
[ext_resource type="Texture2D" uid="uid://caw70lr5e1yiq" path="res://Classes/Notes/Assets/Note_PlayerDouble.png" id="4_6w8ha"]
-[sub_resource type="Gradient" id="Gradient_0u6yv"]
-colors = PackedColorArray(0, 0, 0, 1, 0, 0, 0, 1)
-
-[sub_resource type="GradientTexture2D" id="GradientTexture2D_hhds4"]
-gradient = SubResource("Gradient_0u6yv")
-width = 34
-height = 100
-
[sub_resource type="Gradient" id="Gradient_xvck1"]
offsets = PackedFloat32Array(0)
colors = PackedColorArray(0, 0, 0, 1)
+[sub_resource type="GradientTexture2D" id="GradientTexture2D_kb2co"]
+gradient = SubResource("Gradient_xvck1")
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_e2fap"]
+shader = ExtResource("2_kb2co")
+shader_parameter/fillLevel = 0.0
+shader_parameter/waveIntensity = 1.0
+shader_parameter/waveGradient = SubResource("GradientTexture2D_kb2co")
+shader_parameter/backWaveTint = Color(0.7, 0.7, 0.8, 1)
+
[sub_resource type="GradientTexture2D" id="GradientTexture2D_0bqho"]
gradient = SubResource("Gradient_xvck1")
width = 32
@@ -58,6 +63,7 @@ anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_456es")
+_waveMaterial = SubResource("ShaderMaterial_e2fap")
_notePlacementBar = NodePath("PlacementBar")
_particles = NodePath("PlacementBar/Rock")
_fullBarParticles = NodePath("PlacementBar/FullBarParticles")
@@ -65,14 +71,33 @@ _currentComboMultText = NodePath("CurrentCombo")
_currentNote = NodePath("NoteQueueSprite/CurrentNote")
_nextNote = NodePath("NoteQueueSprite/NextNote")
+[node name="CurrentCombo" type="TextEdit" parent="."]
+z_as_relative = false
+custom_minimum_size = Vector2(80, 35)
+layout_mode = 0
+offset_right = 80.0
+offset_bottom = 35.0
+mouse_filter = 2
+theme_override_font_sizes/font_size = 32
+text = " x1"
+context_menu_enabled = false
+shortcut_keys_enabled = false
+selecting_enabled = false
+deselect_on_focus_loss_enabled = false
+drag_and_drop_selection_enabled = false
+virtual_keyboard_enabled = false
+middle_mouse_paste_enabled = false
+
[node name="PlacementBar" type="TextureProgressBar" parent="."]
+material = SubResource("ShaderMaterial_e2fap")
layout_mode = 0
offset_left = 41.0
offset_top = 33.0
offset_right = 75.0
offset_bottom = 133.0
fill_mode = 3
-texture_under = SubResource("GradientTexture2D_hhds4")
+texture_under = ExtResource("2_5a8x5")
+texture_over = ExtResource("3_kb2co")
texture_progress = SubResource("GradientTexture2D_0bqho")
texture_progress_offset = Vector2(1, 1)
@@ -101,23 +126,6 @@ initial_velocity_max = 50.0
scale_amount_max = 2.0
color = Color(1, 1, 0.0745098, 1)
-[node name="CurrentCombo" type="TextEdit" parent="."]
-z_as_relative = false
-custom_minimum_size = Vector2(80, 35)
-layout_mode = 0
-offset_right = 80.0
-offset_bottom = 35.0
-mouse_filter = 2
-theme_override_font_sizes/font_size = 32
-text = " x1"
-context_menu_enabled = false
-shortcut_keys_enabled = false
-selecting_enabled = false
-deselect_on_focus_loss_enabled = false
-drag_and_drop_selection_enabled = false
-virtual_keyboard_enabled = false
-middle_mouse_paste_enabled = false
-
[node name="NoteQueueSprite" type="Sprite2D" parent="."]
position = Vector2(23, 66)
rotation = -1.5708
diff --git a/Scenes/BattleDirector/Scripts/BattleDirector.cs b/Scenes/BattleDirector/Scripts/BattleDirector.cs
index b776ca33..5f927148 100644
--- a/Scenes/BattleDirector/Scripts/BattleDirector.cs
+++ b/Scenes/BattleDirector/Scripts/BattleDirector.cs
@@ -8,7 +8,6 @@
public partial class BattleDirector : Node2D
{
#region Declarations
-
public static readonly string LoadPath = "res://Scenes/BattleDirector/BattleScene.tscn";
public PlayerPuppet Player;
@@ -17,6 +16,9 @@ public partial class BattleDirector : Node2D
[Export]
public Marker2D[] PuppetMarkers = new Marker2D[4]; //[0] is always player
+ [Export]
+ private Label _countdownLabel;
+
[Export]
private Conductor CD;
@@ -30,27 +32,56 @@ public partial class BattleDirector : Node2D
private AudioStreamPlayer Audio;
[Export]
- private Button _focusedButton; //Initial start button
+ public Button FocusedButton; //Initial start button
private double _timingInterval = .1; //in beats, maybe make note/bpm dependent
private bool _initializedPlaying;
+ public static bool AutoPlay = false;
+ public static bool PlayerDisabled = false;
+
#endregion
#region Initialization
+ Timer _countdownTimer; //TODO: Make in time with bpm
+ public bool HasPlayed; //TODO: Disable input during countdown
+
+ public void StartCountdown()
+ {
+ CM.ArrowTween?.Pause();
+ Audio.SetStreamPaused(true);
+ if (_countdownTimer == null)
+ {
+ _countdownTimer = new Timer();
+ AddChild(_countdownTimer);
+ _countdownTimer.Timeout += SyncStartWithMix;
+ }
+ _countdownTimer.Start(3);
+ _countdownLabel.Visible = true;
+ }
+
private void SyncStartWithMix()
{
+ _countdownTimer.Stop();
var timer = GetTree().CreateTimer(AudioServer.GetTimeToNextMix());
timer.Timeout += BeginPlayback;
- _focusedButton.QueueFree();
- _focusedButton = null;
}
private void BeginPlayback()
{
- CM.BeginTweens();
- Audio.Play();
+ _countdownLabel.Visible = false;
+ if (HasPlayed)
+ {
+ Audio.SetStreamPaused(false);
+ CM.ArrowTween?.Play();
+ }
+ else
+ {
+ CM.BeginTweens();
+ Audio.Play();
+ }
+ HasPlayed = true;
_initializedPlaying = true;
}
@@ -67,11 +98,45 @@ public override void _Ready()
Harbinger.Init(this);
InitPlayer();
InitEnemies();
- CD.Initialize(curSong);
+ InitScoringGuide();
+ CD.Initialize(curSong, _enemies);
CD.NoteInputEvent += OnTimedInput;
- _focusedButton.GrabFocus();
- _focusedButton.Pressed += SyncStartWithMix;
+ FocusedButton.GrabFocus();
+ FocusedButton.Pressed += () =>
+ {
+ FocusedButton.QueueFree();
+ FocusedButton = null;
+ StartCountdown();
+ };
+
+ Harbinger.Instance.InvokeBattleStarted();
+ }
+
+ public ScoringScreen.ScoreGuide BattleScore;
+
+ private void InitScoringGuide()
+ {
+ int baseMoney = 0;
+ foreach (EnemyPuppet enem in _enemies)
+ {
+ baseMoney += enem.BaseMoney;
+ }
+ BattleScore = new ScoringScreen.ScoreGuide(baseMoney, Player.GetCurrentHealth());
+ Harbinger.Instance.NotePlaced += (_) =>
+ {
+ BattleScore.IncPlaced();
+ };
+ Harbinger.Instance.NoteHit += (_) =>
+ {
+ BattleScore.IncHits();
+ };
+ Harbinger.Instance.NoteHit += (e) =>
+ {
+ if (e is Harbinger.NoteHitArgs { Timing: Timing.Perfect })
+ BattleScore.IncPerfects();
+ BattleScore.IncHits();
+ };
}
private void InitPlayer()
@@ -103,6 +168,10 @@ private void InitEnemies()
public override void _Process(double delta)
{
+ if (FocusedButton != null && GetViewport().GuiGetFocusOwner() == null)
+ FocusedButton.GrabFocus();
+ if (_countdownTimer != null)
+ _countdownLabel.Text = ((int)_countdownTimer.TimeLeft + 1).ToString();
TimeKeeper.CurrentTime = Audio.GetPlaybackPosition();
Beat realBeat = TimeKeeper.GetBeatFromTime(Audio.GetPlaybackPosition());
UpdateBeat(realBeat);
@@ -117,6 +186,8 @@ private void UpdateBeat(Beat beat)
}
if (beat.Loop > TimeKeeper.LastBeat.Loop)
{
+ if (beat.Loop % TimeKeeper.LoopsPerSong == 0)
+ CM.BeginTweens(); //current hack to improve sync arrow tween
Harbinger.Instance.InvokeChartLoop(beat.Loop, false);
}
TimeKeeper.LastBeat = beat;
@@ -140,7 +211,7 @@ public override void _UnhandledInput(InputEvent @event)
}
}
- private bool PlayerAddNote(ArrowType type, Beat beat)
+ public bool PlayerAddNote(ArrowType type, Beat beat)
{
if (!NPB.CanPlaceNote())
return false;
@@ -148,12 +219,26 @@ private bool PlayerAddNote(ArrowType type, Beat beat)
Note noteToPlace = NPB.NotePlaced();
noteToPlace.OnHit(this, Timing.Okay);
- CD.AddPlayerNote(noteToPlace, type, beat);
+ CD.AddPlayerNote(noteToPlace.SetOwner(Player), type, beat);
Harbinger.Instance.InvokeNotePlaced(new ArrowData(type, beat, noteToPlace));
- Harbinger.Instance.InvokeNoteHit(noteToPlace, Timing.Okay); //TODO: test how this feels? maybe take it out later
+ Harbinger.Instance.InvokeNoteHit(noteToPlace, Timing.Okay, type); //TODO: test how this feels? maybe take it out later
return true;
}
+ public bool EnemyAddNote(ArrowType type, Beat beat, Note noteRef, float len, EnemyPuppet enemy)
+ {
+ noteRef.SetOwner(enemy);
+ Beat realBeat = TimeKeeper.GetBeatFromTime(Audio.GetPlaybackPosition());
+ return CD.AddConcurrentNote(realBeat, noteRef, type, beat.IncDecLoop(realBeat.Loop), len);
+ }
+
+ public void RandApplyNote(PuppetTemplate owner, int noteId, int amount)
+ {
+ if (owner == null || noteId > Scribe.NoteDictionary.Length || amount < 1)
+ return;
+ CD.SetRandBaseNoteToType(owner, (noteId, amount));
+ }
+
//Only called from CD signal when a note is processed
private void OnTimedInput(ArrowData data, double beatDif)
{
@@ -161,7 +246,10 @@ private void OnTimedInput(ArrowData data, double beatDif)
return; //An inactive note was passed, for now do nothing, could force miss.
if (data.NoteRef == null) //An empty beat
{
- if ((int)data.Beat.BeatPos % (int)TimeKeeper.BeatsPerLoop == 0)
+ if (
+ (int)data.Beat.BeatPos % (int)TimeKeeper.BeatsPerLoop == 0
+ || (int)data.Beat.BeatPos > TimeKeeper.BeatsPerLoop
+ )
return; //We never ever try to place at 0
if (PlayerAddNote(data.Type, data.Beat))
return; //Exit handling for a placed note
@@ -172,7 +260,7 @@ private void OnTimedInput(ArrowData data, double beatDif)
Timing timed = CheckTiming(beatDif);
data.NoteRef.OnHit(this, timed);
- Harbinger.Instance.InvokeNoteHit(data.NoteRef, timed);
+ Harbinger.Instance.InvokeNoteHit(data.NoteRef, timed, data.Type);
NPB.HandleTiming(timed, data.Type);
CM.ComboText(timed, data.Type, NPB.GetCurrentCombo());
}
@@ -208,13 +296,22 @@ private Timing CheckTiming(double beatDif)
#region Battle End
private void CheckBattleStatus(PuppetTemplate puppet) //Called when a puppet dies
{
+ var tween = CreateTween();
+ tween.TweenProperty(puppet, "modulate:a", 0, 2f);
if (puppet == Player)
{
- OnBattleLost();
+ CM.ProcessMode = ProcessModeEnum.Disabled;
+ tween.TweenCallback(Callable.From(OnBattleLost));
return;
}
- if (puppet is EnemyPuppet && IsBattleWon())
- OnBattleWon(); //will have to adjust this to account for when we have multiple enemies at once
+
+ if (puppet is EnemyPuppet)
+ {
+ if (!IsBattleWon())
+ return;
+ CM.ProcessMode = ProcessModeEnum.Disabled;
+ tween.TweenCallback(Callable.From(OnBattleWon));
+ }
}
private bool IsBattleWon()
@@ -224,9 +321,14 @@ private bool IsBattleWon()
private void OnBattleWon()
{
- Audio.StreamPaused = true;
+ Harbinger.Instance.InvokeBattleEnded();
CleanUpRelics();
- ShowRewardSelection(3);
+ BattleScore.SetEndHp(Player.GetCurrentHealth());
+ Audio.ProcessMode = ProcessModeEnum.Always;
+ ScoringScreen.CreateScore(this, BattleScore).Finished += () =>
+ {
+ ShowRewardSelection(3);
+ };
}
private void OnBattleLost()
@@ -265,12 +367,7 @@ public void DealDamage(Note note, int damage, PuppetTemplate source)
}
}
- public void DealDamage(
- Targetting targetting,
- int damage,
- PuppetTemplate source,
- bool targetPlayer = false
- )
+ public void DealDamage(Targetting targetting, int damage, PuppetTemplate source)
{
PuppetTemplate[] targets = GetTargets(targetting);
foreach (PuppetTemplate target in targets)
@@ -279,16 +376,28 @@ public void DealDamage(
}
}
- public void AddStatus(Targetting targetting, StatusEffect status)
+ /*public void ReduceMeter(Note note, int amountLost, PuppetTemplate source)
{
- PuppetTemplate[] targets = GetTargets(targetting);
+ PuppetTemplate[] targets = GetTargets(note.TargetType);
foreach (PuppetTemplate target in targets)
{
- target.AddStatusEffect(status);
+ target.
}
+ }*/
- status.StatusEnd += RemoveStatus;
- AddEvent(status);
+ public void AddStatus(Targetting targetting, StatusEffect status, int amount = 1)
+ {
+ if (amount == 0)
+ return;
+ PuppetTemplate[] targets = GetTargets(targetting);
+ foreach (PuppetTemplate target in targets)
+ {
+ StatusEffect eff = status.CreateInstance(amount);
+ if (!target.AddStatusEffect(eff))
+ continue;
+ eff.StatusEnd += RemoveStatus; //If new status, add effect events
+ AddEvent(eff);
+ }
}
public void RemoveStatus(StatusEffect status)
@@ -347,6 +456,9 @@ private void AddEvent(IBattleEvent bEvent)
case BattleEffectTrigger.OnDamageInstance:
Harbinger.Instance.OnDamageInstance += bEvent.OnTrigger;
break;
+ case BattleEffectTrigger.OnBattleStart:
+ Harbinger.Instance.BattleStarted += bEvent.OnTrigger;
+ break;
}
}
@@ -369,6 +481,9 @@ private void RemoveEvent(IBattleEvent bEvent)
case BattleEffectTrigger.OnDamageInstance:
Harbinger.Instance.OnDamageInstance -= bEvent.OnTrigger;
break;
+ case BattleEffectTrigger.OnBattleStart:
+ Harbinger.Instance.BattleStarted -= bEvent.OnTrigger;
+ break;
}
}
@@ -449,10 +564,12 @@ public class LoopEventArgs(BattleDirector bd, int incomingLoop, bool artificialL
///
/// The BattleDirector calling the event.
/// The Note being hit.
- public class NoteHitArgs(BattleDirector bd, Note note, Timing timing) : BattleEventArgs(bd)
+ public class NoteHitArgs(BattleDirector bd, Note note, Timing timing, ArrowType type)
+ : BattleEventArgs(bd)
{
- public Note Note = note;
- public Timing Timing = timing;
+ public readonly Note Note = note;
+ public readonly Timing Timing = timing;
+ public readonly ArrowType Type = type;
}
internal delegate void NotePlacedHandler(BattleEventArgs e);
@@ -460,6 +577,7 @@ public class NoteHitArgs(BattleDirector bd, Note note, Timing timing) : BattleEv
public void InvokeNotePlaced(ArrowData data)
{
+ SteamWhisperer.IncrementNoteCount();
NotePlaced?.Invoke(new NoteEventArgs(_curDirector, data));
}
@@ -474,9 +592,9 @@ public void InvokeChartLoop(int incLoop, bool artificialLoop = true)
internal delegate void NoteHitHandler(BattleEventArgs e);
internal event NoteHitHandler NoteHit;
- public void InvokeNoteHit(Note note, Timing timing)
+ public void InvokeNoteHit(Note note, Timing timing, ArrowType type)
{
- NoteHit?.Invoke(new NoteHitArgs(_curDirector, note, timing));
+ NoteHit?.Invoke(new NoteHitArgs(_curDirector, note, timing, type));
}
internal delegate void BattleEndedHandler(BattleEventArgs e);
@@ -487,6 +605,14 @@ public void InvokeBattleEnded()
BattleEnded?.Invoke(new BattleEventArgs(_curDirector));
}
+ internal delegate void BattleStartedHandler(BattleEventArgs e);
+ internal event BattleStartedHandler BattleStarted;
+
+ public void InvokeBattleStarted()
+ {
+ BattleStarted?.Invoke(new BattleEventArgs(_curDirector));
+ }
+
///
/// Event Args to handle a damage instance being dealt. Happens before taking damage.
/// This allows damage to be intercepted, to be reduced/increased, to counter, or heal based on incoming damage.
@@ -512,7 +638,7 @@ private void DebugKillEnemy()
{
foreach (EnemyPuppet enemy in _enemies)
{
- enemy.TakeDamage(new DamageInstance(1000, null, enemy));
+ enemy.TakeDamage(new DamageInstance(1000, null, null));
}
}
diff --git a/Scenes/BattleDirector/Scripts/Conductor.cs b/Scenes/BattleDirector/Scripts/Conductor.cs
index 146bba7a..55f37f62 100644
--- a/Scenes/BattleDirector/Scripts/Conductor.cs
+++ b/Scenes/BattleDirector/Scripts/Conductor.cs
@@ -14,11 +14,12 @@ public partial class Conductor : Node
private readonly List _noteData = new List();
private double _beatSpawnOffset;
+ public static int BeatSpawnOffsetModifier; //I'm gonna be mad at myself later for this.
private bool _initialized;
#region Initialization
- public void Initialize(SongData curSong)
+ public void Initialize(SongData curSong, EnemyPuppet[] enemies = null)
{
if (_initialized)
return;
@@ -29,10 +30,12 @@ public void Initialize(SongData curSong)
CM.Initialize(curSong);
//Approximately the first note offscreen
- _beatSpawnOffset = Math.Ceiling(
- CM.Size.X / TimeKeeper.ChartWidth * TimeKeeper.BeatsPerLoop
- );
+ _beatSpawnOffset =
+ Math.Ceiling(CM.Size.X / TimeKeeper.ChartWidth * TimeKeeper.BeatsPerLoop)
+ - BeatSpawnOffsetModifier;
AddInitialNotes();
+ AddInitialEnemyNotes(enemies);
+ SpawnInitialNotes();
_initialized = true;
}
@@ -46,11 +49,22 @@ private void AddInitialNotes()
AddNoteData(Scribe.NoteDictionary[0], type, new Beat((int)Note.Beat), Note.Length);
}
}
- SpawnInitialNotes();
+ }
+
+ private void AddInitialEnemyNotes(EnemyPuppet[] enemies)
+ {
+ if (enemies == null)
+ return;
+ foreach (EnemyPuppet enemy in enemies)
+ {
+ if (enemy.InitialNote.Amount > 0)
+ SetRandBaseNoteToType(enemy, enemy.InitialNote);
+ }
}
private void SpawnInitialNotes()
{
+ _noteData.Sort(); //Isn't inherently necessary, but sort for safety
for (int i = 1; i <= _beatSpawnOffset; i++)
{
SpawnNotesAtBeat(new Beat(i));
@@ -66,55 +80,180 @@ private void ReceiveNoteInput(ArrowData data)
}
#endregion
+ //Ignores sorting, use sparingly
+ private void AddNoteData(ArrowData data, int index)
+ {
+ if (index == -1)
+ {
+ GD.PushWarning(
+ "Specific invalid index attempted to be passed (is -1): "
+ + data.Type
+ + " "
+ + data.Beat
+ );
+ return;
+ }
+
+ if (index < -1 || index > _noteData.Count)
+ {
+ GD.PushWarning(
+ "Invalid index passed is: " + index + " data: " + data.Type + " " + data.Beat
+ );
+ return;
+ }
+ _noteData.Insert(index, data);
+ }
+
private int AddNoteData(Note noteRef, ArrowType type, Beat beat, double length = 0)
{
ArrowData result = new ArrowData(type, beat, noteRef, length);
+ return AddNoteData(result);
+ }
+
+ private int AddNoteData(ArrowData data)
+ {
if (_noteData.Count == 0)
{
- _noteData.Add(result);
+ _noteData.Add(data);
return 0;
}
- int index = _noteData.BinarySearch(result); //TODO: This sorts correctly, but we don't take advantage yet.
+ int index = GetIndexOfData(data);
+ if (index == -1)
+ {
+ GD.PushWarning(
+ "Attempted to add duplicate note! Current note: " + data.Type + " " + data.Beat
+ );
+ return -1;
+ }
+
+ _noteData.Insert(index, data);
+ return index;
+ }
+
+ private int GetIndexOfData(ArrowData data)
+ {
+ int index = _noteData.BinarySearch(data);
if (index > 0)
{
- GD.PushWarning("Duplicate note attempted add " + type + " " + beat);
+ GD.PushWarning(index + " Invalid index for: " + data.Type + " " + data.Beat);
return -1;
}
- _noteData.Insert(~index, result);
+
return ~index;
}
- //TODO: Beat spawn redundancy checking, efficiency
+ //Assumes beat has beatPos floor'd
private void SpawnNotesAtBeat(Beat beat)
{
- for (int i = 0; i < _noteData.Count; i++)
+ int startIdx = _noteData.BinarySearch(new ArrowData(ArrowType.Up, beat, null)); //first arrow of beat
+ if (startIdx < 0)
+ startIdx = ~startIdx;
+ for (int i = 0; i <= 40 && (int)_noteData[startIdx].Beat.BeatPos == (int)beat.BeatPos; i++)
{
- if (
- _noteData[i].Beat.Loop != beat.Loop
- || (int)_noteData[i].Beat.BeatPos != (int)beat.BeatPos
- )
- continue;
- SpawnNote(i);
- }
+ SpawnNote(startIdx); //Spawn pops notes, so stay in same idx
+ } //A tiny bit of defensive programming. I don't like this much more than the old way of looping and checking everything.
+ //Could be a while loop, but just in case have a safety counter, iterations per beat should max at 40, 4 directions * 10 increments per beat (0.1 accuracy for beatPos tracking)
}
private void SpawnNote(int index, bool newPlayerNote = false)
{
CM.AddNoteArrow(_noteData[index], newPlayerNote);
- _noteData[index] = new ArrowData(
- _noteData[index].Type,
- _noteData[index].Beat.IncDecLoop(1),
- _noteData[index].NoteRef,
- _noteData[index].Length
- ); //Structs make me sad sometimes
+ if (newPlayerNote) //Player notes are presorted
+ {
+ _noteData[index] = _noteData[index].IncDecLoop(1);
+ return;
+ }
+ _noteData.Add(_noteData[index].IncDecLoop(1));
+ _noteData.RemoveAt(index);
+ }
+
+ public void SetRandBaseNoteToType(PuppetTemplate owner, (int noteid, int amount) noteOfAmount)
+ {
+ RandomNumberGenerator noteRng = new RandomNumberGenerator();
+ noteRng.Seed = StageProducer.GlobalRng.Seed;
+ noteRng.State = StageProducer.GlobalRng.State;
+
+ for (int i = noteOfAmount.amount; i > 0; i--)
+ {
+ int iterationsLeft = 5;
+ while (iterationsLeft > 0)
+ {
+ int idx = noteRng.RandiRange(0, _noteData.Count - 1);
+ if (_noteData[idx].NoteRef.Id == 0)
+ {
+ Note newNoteRef = Scribe
+ .NoteDictionary[noteOfAmount.noteid]
+ .Clone()
+ .SetOwner(owner);
+ _noteData[idx] = ArrowData.SetNote(_noteData[idx], newNoteRef);
+ iterationsLeft = -1;
+ }
+ iterationsLeft--;
+ }
+ }
+ }
+
+ ///
+ /// Attempts to add the new specified beat to current chart.
+ /// Should only be used from On Loop effects
+ /// EXPERIMENTAL - Currently does not check for: Hold note overlap whether placing or preexisting.
+ /// Notes that are far past when they should have been placed. And notes that will come around far in the future.
+ ///
+ /// Current time, should be the beat of the about to happen new loop.
+ /// What type of note
+ /// The lane
+ /// Beat to spawn new note at. Should be within a loop, but outside _beatSpawnOffset buffer.
+ /// Length of note, may get removed.
+ /// Whether placement was successful
+ public bool AddConcurrentNote(
+ Beat currentTime,
+ Note noteRef,
+ ArrowType type,
+ Beat beat,
+ float length = 0
+ )
+ {
+ if (beat < currentTime + _beatSpawnOffset)
+ {
+ GD.PushWarning(
+ "Attempted note far in past. Current beat: "
+ + currentTime
+ + " notedata: "
+ + type
+ + " "
+ + beat
+ );
+ return false;
+ }
+ if (beat > currentTime.IncDecLoop(1) + _beatSpawnOffset)
+ {
+ GD.PushWarning(
+ "Attempted note too far in future. Current beat: "
+ + currentTime
+ + " notedata: "
+ + type
+ + " "
+ + beat
+ );
+ return false;
+ }
+ //Beat should now be guaranteed to be coming up, at some point, from ProgressiveSpawnNote, does NOT need manual spawn
+ int index = AddNoteData(noteRef, type, beat, length);
+ if (index == -1)
+ return false; //Assumption: Dupe note.
+ return true;
}
public void AddPlayerNote(Note noteRef, ArrowType type, Beat beat)
{
- int index = AddNoteData(noteRef, type, beat); //Currently player notes aren't sorted correctly
+ Beat compBeat = new Beat(beat.BeatPos, beat.Loop + 1);
+ int index = GetIndexOfData(new ArrowData(type, compBeat, null)); //Player notes should sorted based on immediately incrementing loop
if (index != -1)
+ {
+ AddNoteData(new ArrowData(type, beat, noteRef), index);
SpawnNote(index, true);
+ }
else
GD.PushError("Duplicate player note was attempted. (This should be stopped by CM)");
}
diff --git a/Scenes/BattleDirector/Scripts/NotePlacementBar.cs b/Scenes/BattleDirector/Scripts/NotePlacementBar.cs
index 00d2952a..ad0f7cf7 100644
--- a/Scenes/BattleDirector/Scripts/NotePlacementBar.cs
+++ b/Scenes/BattleDirector/Scripts/NotePlacementBar.cs
@@ -23,9 +23,13 @@ private double CurrentBarValue
{
_notePlacementBar.Value = value;
_particles.Emitting = CurrentBarValue >= MaxValue; //This is so goated
+ _waveMaterial.SetShaderParameter("fillLevel", _notePlacementBar.Value / MaxValue);
}
}
+ [Export]
+ private ShaderMaterial _waveMaterial; //Sort of breaks the pixel art style, but its cool
+
[Export]
private TextureProgressBar _notePlacementBar;
private Gradient _gradTex;
@@ -65,6 +69,8 @@ public override void _Ready()
if (_notePlacementBar.TextureProgress is GradientTexture2D gradientTexture)
_gradTex = gradientTexture.Gradient;
+
+ _waveMaterial.SetShaderParameter("fillLevel", 0.0);
}
public override void _Process(double delta)
@@ -190,6 +196,11 @@ public int GetCurrentCombo()
return _currentCombo;
}
+ public double GetCurrentBarValue()
+ {
+ return CurrentBarValue;
+ }
+
public void ResetCurrentCombo()
{
_currentCombo = 0;
@@ -230,6 +241,8 @@ public Note NotePlaced()
public void HandleTiming(Timing timed, ArrowType type)
{
+ if (BattleDirector.PlayerDisabled)
+ return;
if (timed == Timing.Miss)
{
MissNote();
diff --git a/Scenes/BattleDirector/Tutorial/Toriel.cs b/Scenes/BattleDirector/Tutorial/Toriel.cs
new file mode 100644
index 00000000..93ad1c14
--- /dev/null
+++ b/Scenes/BattleDirector/Tutorial/Toriel.cs
@@ -0,0 +1,357 @@
+using System;
+using FunkEngine;
+using Godot;
+
+public partial class Toriel : CanvasLayer
+{
+ public static string LoadPath { get; private set; } =
+ "res://Scenes/BattleDirector/Tutorial/Toriel.tscn";
+ private BattleDirector _currentDirector;
+
+ [Export]
+ private Label _dialogueLabel;
+
+ [Export]
+ private Control _dialogueBox;
+
+ [Export]
+ private Button _nextButton;
+
+ [Export]
+ private Sprite2D[] _inputSprites = new Sprite2D[4]; //In enum order
+
+ [Export]
+ private Marker2D _noteQueueMarker;
+
+ [Export]
+ private Marker2D _comboMarker;
+
+ [Export]
+ private Marker2D _barMarker;
+
+ [Export]
+ private Marker2D _noteMarker;
+
+ [Export]
+ private Marker2D _loopMarker;
+
+ [Export]
+ private NinePatchRect _selector;
+
+ public static Toriel AttachNewToriel(BattleDirector director)
+ {
+ Toriel result = GD.Load(LoadPath).Instantiate();
+ result._currentDirector = director;
+ director.AddChild(result);
+ return result;
+ }
+
+ public override void _EnterTree()
+ {
+ UpdateInputSprites();
+ }
+
+ public override void _Process(double delta)
+ {
+ if (GetViewport().GuiGetFocusOwner() == null)
+ {
+ _nextButton?.GrabFocus();
+ }
+ UpdateInputSprites();
+ string scheme = SaveSystem.GetConfigValue(SaveSystem.ConfigSettings.InputType).As();
+ if (_waitingForPlace && Input.IsActionPressed(scheme + "_arrowRight"))
+ {
+ GetViewport().SetInputAsHandled();
+ FirstNotePlaced();
+ }
+ }
+
+ private void UpdateInputSprites()
+ {
+ string prefix = SaveSystem.GetConfigValue(SaveSystem.ConfigSettings.InputType).ToString();
+ _inputSprites[0].Texture = GD.Load(
+ ControlSettings.GetTextureForInput(prefix + "_arrowUp")
+ );
+ _inputSprites[1].Texture = GD.Load(
+ ControlSettings.GetTextureForInput(prefix + "_arrowDown")
+ );
+ _inputSprites[2].Texture = GD.Load(
+ ControlSettings.GetTextureForInput(prefix + "_arrowLeft")
+ );
+ _inputSprites[3].Texture = GD.Load(
+ ControlSettings.GetTextureForInput(prefix + "_arrowRight")
+ );
+ }
+
+ private SceneTreeTimer _timer;
+
+ public void NoDying()
+ {
+ _dialogueBox.Visible = true;
+ _nextButton.Visible = false;
+ _dialogueLabel.Text = Tr("TUTORIAL_NODYING");
+ _timer = GetTree().CreateTimer(3);
+ _timer.Timeout += () =>
+ {
+ _dialogueBox.Visible = false;
+ _nextButton.Visible = true;
+ };
+ }
+
+ #region IntroDialogues
+ public void IntroDialogue()
+ {
+ _dialogueBox.Visible = true;
+ GetTree().SetPause(true);
+ _currentDirector.FocusedButton.Visible = false;
+ _dialogueLabel.Text = Tr("TUTORIAL_DIALOGUE_1");
+ _nextButton.GrabFocus();
+ _nextButton.Pressed += Dialogue2;
+ }
+
+ public void Dialogue2()
+ {
+ _nextButton.Pressed -= Dialogue2;
+ _dialogueLabel.Text = Tr("TUTORIAL_DIALOGUE_2");
+ _selector.Visible = true;
+ _selector.Position = _noteMarker.Position - _selector.Size / 2;
+ _nextButton.Pressed += Dialogue3;
+ }
+
+ public void Dialogue3()
+ {
+ _nextButton.Pressed -= Dialogue3;
+ _dialogueLabel.Text = Tr("TUTORIAL_DIALOGUE_3");
+ _selector.Position = _inputSprites[(int)ArrowType.Down].Position - _selector.Size / 2;
+ _nextButton.Pressed += Dialogue4;
+ }
+
+ public void Dialogue4()
+ {
+ _nextButton.Pressed -= Dialogue4;
+ _dialogueLabel.Text = Tr("TUTORIAL_DIALOGUE_4");
+ _selector.Visible = false;
+ _inputSprites[0].Visible = true;
+ _inputSprites[1].Visible = true;
+ _inputSprites[2].Visible = true;
+ _inputSprites[3].Visible = true;
+ _nextButton.Pressed += Dialogue5;
+ }
+
+ public void Dialogue5()
+ {
+ _nextButton.Pressed -= Dialogue5;
+ _dialogueBox.Visible = false;
+ GetTree().SetPause(false);
+ _currentDirector.FocusedButton.Visible = true;
+ _currentDirector.FocusedButton.GrabFocus();
+ }
+ #endregion
+
+ #region Loop Dialogue
+ public void LoopDialogue()
+ {
+ _timer?.SetTimeLeft(0);
+ _dialogueBox.Visible = true;
+ _nextButton.Visible = true;
+
+ _inputSprites[0].Visible = false;
+ _inputSprites[1].Visible = false;
+ _inputSprites[2].Visible = false;
+ _inputSprites[3].Visible = false;
+
+ _selector.Visible = true;
+ _selector.Position = _loopMarker.Position - _selector.Size / 2;
+
+ _dialogueLabel.Text = Tr("TUTORIAL_LOOP_1");
+ GetTree().SetPause(true);
+ _nextButton.GrabFocus();
+ _nextButton.Pressed += LoopDialogue2;
+ }
+
+ public void LoopDialogue2()
+ {
+ _nextButton.Pressed -= LoopDialogue2;
+ _inputSprites[0].Visible = true;
+ _inputSprites[1].Visible = true;
+ _inputSprites[2].Visible = true;
+ _inputSprites[3].Visible = true;
+
+ _dialogueLabel.Text = Tr("TUTORIAL_LOOP_2");
+ _selector.Position = _noteQueueMarker.Position - _selector.Size / 2;
+ _nextButton.Pressed += LoopDialogue3;
+ }
+
+ public void LoopDialogue3()
+ {
+ _nextButton.Pressed -= LoopDialogue3;
+ _dialogueLabel.Text = Tr("TUTORIAL_LOOP_3");
+ _selector.Position = _comboMarker.Position - _selector.Size / 2;
+ _nextButton.Pressed += LoopDialogue4;
+ }
+
+ public void LoopDialogue4()
+ {
+ _nextButton.Pressed -= LoopDialogue4;
+ _dialogueLabel.Text = Tr("TUTORIAL_LOOP_4");
+ _selector.Position = _barMarker.Position - _selector.Size / 2;
+ _nextButton.Pressed += LoopDialogue5;
+ }
+
+ public void LoopDialogue5()
+ {
+ _nextButton.Pressed -= LoopDialogue5;
+ _dialogueLabel.Text = Tr("TUTORIAL_LOOP_5");
+ _selector.Visible = false;
+ _nextButton.Pressed += LoopDialogue6;
+ }
+
+ public void LoopDialogue6()
+ {
+ _nextButton.Pressed -= LoopDialogue6;
+ _dialogueBox.Visible = false;
+ GetTree().SetPause(false);
+ }
+ #endregion
+
+ #region Placed Dialogue
+ public void PlaceDialogue1()
+ {
+ _dialogueBox.Visible = true;
+ GetTree().SetPause(true);
+ _dialogueLabel.Text = Tr("TUTORIAL_PLACE_1");
+ _nextButton.GrabFocus();
+ _selector.Visible = true;
+ _selector.Position = _inputSprites[(int)ArrowType.Right].Position - _selector.Size / 2;
+ _nextButton.Pressed += PlaceDialogue2;
+ }
+
+ public void PlaceDialogue2()
+ {
+ _nextButton.Pressed -= PlaceDialogue2;
+ _dialogueLabel.Text = Tr("TUTORIAL_PLACE_2");
+ _selector.Position = _noteQueueMarker.Position - _selector.Size / 2;
+ _nextButton.Pressed += PlaceDialogue3;
+ }
+
+ public void PlaceDialogue3()
+ {
+ _nextButton.Pressed -= PlaceDialogue3;
+ _dialogueLabel.Text = Tr("TUTORIAL_PLACE_3");
+ _selector.Position = _inputSprites[(int)ArrowType.Right].Position - _selector.Size / 2;
+ _nextButton.Pressed += PlaceDialogue4;
+ }
+
+ public void PlaceDialogue4()
+ {
+ _nextButton.Pressed -= PlaceDialogue4;
+ _dialogueLabel.Text = Tr("TUTORIAL_PLACE_4");
+ _selector.Position = _noteQueueMarker.Position - _selector.Size / 2;
+ _nextButton.Pressed += PlaceDialogue5;
+ }
+
+ public void PlaceDialogue5()
+ {
+ _nextButton.Pressed -= PlaceDialogue5;
+ _dialogueLabel.Text = Tr("TUTORIAL_PLACE_5");
+ _nextButton.Pressed += PlaceDialogue6;
+ }
+
+ public void PlaceDialogue6()
+ {
+ _nextButton.Pressed -= PlaceDialogue6;
+ _dialogueLabel.Text = Tr("TUTORIAL_PLACE_6");
+ _selector.Position = _inputSprites[(int)ArrowType.Right].Position - _selector.Size / 2;
+ _waitingForPlace = true;
+ _nextButton.Visible = false;
+ }
+
+ private bool _waitingForPlace = false;
+
+ public void FirstNotePlaced()
+ {
+ _waitingForPlace = false;
+ _dialogueBox.Visible = false;
+ _selector.Visible = false;
+ GetTree().SetPause(false);
+ _currentDirector.PlayerAddNote(ArrowType.Right, TimeKeeper.LastBeat.RoundBeat());
+ _finalDialogue = true;
+ }
+ #endregion
+
+ #region OnPlace Dialogue
+ bool _finalDialogue = false;
+
+ public void OnPlaceDialogue1()
+ {
+ if (!_finalDialogue)
+ return;
+ _finalDialogue = false;
+
+ _dialogueBox.Visible = true;
+ _nextButton.Visible = true;
+
+ _dialogueLabel.Text = Tr("TUTORIAL_FINAL_1");
+ GetTree().SetPause(true);
+ _nextButton.GrabFocus();
+ _nextButton.Pressed += OnPlaceDialogue2;
+ }
+
+ public void OnPlaceDialogue2()
+ {
+ _nextButton.Pressed -= OnPlaceDialogue2;
+ _dialogueLabel.Text = Tr("TUTORIAL_FINAL_2");
+ _selector.Visible = true;
+ _selector.Position = _barMarker.Position - _selector.Size / 2;
+ _nextButton.Pressed += OnPlaceDialogue3;
+ }
+
+ public bool FromBoss;
+
+ public void OnPlaceDialogue3()
+ {
+ if (FromBoss)
+ {
+ _dialogueBox.Visible = true;
+ _nextButton.Visible = true;
+ GetTree().SetPause(true);
+ _nextButton.GrabFocus();
+ }
+ else
+ {
+ _nextButton.Pressed -= OnPlaceDialogue3;
+ _selector.Visible = false;
+ }
+ _dialogueLabel.Text = Tr("TUTORIAL_FINAL_3");
+ _nextButton.Pressed += OnPlaceDialogue4;
+ }
+
+ public void OnPlaceDialogue4()
+ {
+ _nextButton.Pressed -= OnPlaceDialogue4;
+ _dialogueBox.Visible = false;
+ GetTree().SetPause(false);
+ }
+ #endregion
+
+ #region Boss Dialogue
+ public void BossDialogue()
+ {
+ _dialogueBox.Visible = true;
+ GetTree().SetPause(true);
+ _currentDirector.FocusedButton.Visible = false;
+ _dialogueLabel.Text = Tr("TUTORIAL_BOSS");
+ _nextButton.GrabFocus();
+ _nextButton.Pressed += BossDialogueReady;
+ }
+
+ public void BossDialogueReady()
+ {
+ _nextButton.Pressed -= BossDialogueReady;
+ _dialogueBox.Visible = false;
+ GetTree().SetPause(false);
+ _currentDirector.FocusedButton.Visible = true;
+ _currentDirector.FocusedButton.GrabFocus();
+ }
+ #endregion
+}
diff --git a/Scenes/BattleDirector/Tutorial/Toriel.cs.uid b/Scenes/BattleDirector/Tutorial/Toriel.cs.uid
new file mode 100644
index 00000000..8c66f452
--- /dev/null
+++ b/Scenes/BattleDirector/Tutorial/Toriel.cs.uid
@@ -0,0 +1 @@
+uid://bwj1pl3srf8q3
diff --git a/Scenes/BattleDirector/Tutorial/Toriel.tscn b/Scenes/BattleDirector/Tutorial/Toriel.tscn
new file mode 100644
index 00000000..cfb1a582
--- /dev/null
+++ b/Scenes/BattleDirector/Tutorial/Toriel.tscn
@@ -0,0 +1,149 @@
+[gd_scene load_steps=6 format=3 uid="uid://dv36qdfq1oqna"]
+
+[ext_resource type="Script" uid="uid://bwj1pl3srf8q3" path="res://Scenes/BattleDirector/Tutorial/Toriel.cs" id="1_mf0nq"]
+[ext_resource type="Texture2D" uid="uid://djd6iw2g84bba" path="res://Scenes/UI/Assets/UI_CenterFrame.png" id="2_3a4m1"]
+[ext_resource type="Theme" uid="uid://d37e3tpsbxwak" path="res://Scenes/UI/Assets/GeneralTheme.tres" id="3_3a4m1"]
+[ext_resource type="Texture2D" uid="uid://cegasble5d7uw" path="res://Scenes/UI/Assets/UI_Selection.png" id="3_oxyw8"]
+[ext_resource type="Texture2D" uid="uid://6jqhilmyy163" path="res://Scenes/UI/Remapping/Assets/1.png" id="4_d6o7n"]
+
+[node name="Toriel" type="CanvasLayer" node_paths=PackedStringArray("_dialogueLabel", "_dialogueBox", "_nextButton", "_inputSprites", "_noteQueueMarker", "_comboMarker", "_barMarker", "_noteMarker", "_loopMarker", "_selector")]
+process_mode = 3
+layer = 0
+script = ExtResource("1_mf0nq")
+_dialogueLabel = NodePath("Control/CenterContainer/VBoxContainer/NinePatchRect/MarginContainer/TextLabel")
+_dialogueBox = NodePath("Control")
+_nextButton = NodePath("Control/CenterContainer/VBoxContainer/MarginContainer2/NextButton")
+_inputSprites = [NodePath("Up"), NodePath("Down"), NodePath("Left"), NodePath("Right")]
+_noteQueueMarker = NodePath("NoteQueueMarker")
+_comboMarker = NodePath("ComboMarker")
+_barMarker = NodePath("BarMarker")
+_noteMarker = NodePath("NoteMarker")
+_loopMarker = NodePath("LoopMarker")
+_selector = NodePath("Selector")
+
+[node name="Control" type="Control" parent="."]
+layout_mode = 3
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+mouse_filter = 2
+
+[node name="CenterContainer" type="CenterContainer" parent="Control"]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+mouse_filter = 2
+
+[node name="VBoxContainer" type="VBoxContainer" parent="Control/CenterContainer"]
+layout_mode = 2
+
+[node name="NinePatchRect" type="NinePatchRect" parent="Control/CenterContainer/VBoxContainer"]
+custom_minimum_size = Vector2(250, 150)
+layout_mode = 2
+texture = ExtResource("2_3a4m1")
+patch_margin_left = 8
+patch_margin_top = 8
+patch_margin_right = 8
+patch_margin_bottom = 8
+
+[node name="MarginContainer" type="MarginContainer" parent="Control/CenterContainer/VBoxContainer/NinePatchRect"]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+size_flags_vertical = 3
+mouse_filter = 2
+theme_override_constants/margin_left = 6
+theme_override_constants/margin_top = 6
+theme_override_constants/margin_right = 6
+theme_override_constants/margin_bottom = 6
+
+[node name="TextLabel" type="Label" parent="Control/CenterContainer/VBoxContainer/NinePatchRect/MarginContainer"]
+layout_mode = 2
+size_flags_vertical = 1
+autowrap_mode = 2
+clip_text = true
+text_overrun_behavior = 4
+
+[node name="MarginContainer2" type="MarginContainer" parent="Control/CenterContainer/VBoxContainer"]
+process_mode = 3
+layout_mode = 2
+theme_override_constants/margin_left = 35
+theme_override_constants/margin_top = -3
+theme_override_constants/margin_right = 35
+theme_override_constants/margin_bottom = 6
+
+[node name="NextButton" type="Button" parent="Control/CenterContainer/VBoxContainer/MarginContainer2"]
+layout_mode = 2
+theme = ExtResource("3_3a4m1")
+text = "INBETWEEN_CONTINUE"
+
+[node name="Selector" type="NinePatchRect" parent="."]
+visible = false
+anchors_preset = 8
+anchor_left = 0.5
+anchor_top = 0.5
+anchor_right = 0.5
+anchor_bottom = 0.5
+offset_left = -368.0
+offset_top = -228.0
+offset_right = -324.0
+offset_bottom = -184.0
+grow_horizontal = 2
+grow_vertical = 2
+pivot_offset = Vector2(22, 22)
+texture = ExtResource("3_oxyw8")
+patch_margin_left = 22
+patch_margin_top = 22
+patch_margin_right = 22
+patch_margin_bottom = 22
+
+[node name="NoteQueueMarker" type="Marker2D" parent="."]
+position = Vector2(22, 249)
+
+[node name="ComboMarker" type="Marker2D" parent="."]
+position = Vector2(35, 202)
+
+[node name="BarMarker" type="Marker2D" parent="."]
+position = Vector2(59, 266)
+
+[node name="NoteMarker" type="Marker2D" parent="."]
+position = Vector2(364, 294)
+
+[node name="LoopMarker" type="Marker2D" parent="."]
+position = Vector2(129, 270)
+
+[node name="Up" type="Sprite2D" parent="."]
+visible = false
+self_modulate = Color(1, 1, 1, 0.45)
+position = Vector2(129, 248)
+scale = Vector2(0.5, 0.5)
+texture = ExtResource("4_d6o7n")
+
+[node name="Down" type="Sprite2D" parent="."]
+visible = false
+self_modulate = Color(1, 1, 1, 0.45)
+position = Vector2(129, 292)
+scale = Vector2(0.5, 0.5)
+texture = ExtResource("4_d6o7n")
+
+[node name="Left" type="Sprite2D" parent="."]
+visible = false
+self_modulate = Color(1, 1, 1, 0.45)
+position = Vector2(129, 210)
+scale = Vector2(0.5, 0.5)
+texture = ExtResource("4_d6o7n")
+
+[node name="Right" type="Sprite2D" parent="."]
+visible = false
+self_modulate = Color(1, 1, 1, 0.45)
+position = Vector2(129, 330)
+scale = Vector2(0.5, 0.5)
+texture = ExtResource("4_d6o7n")
diff --git a/Scenes/ChartViewport/Scripts/ChartManager.cs b/Scenes/ChartViewport/Scripts/ChartManager.cs
index d53165c7..396718ec 100644
--- a/Scenes/ChartViewport/Scripts/ChartManager.cs
+++ b/Scenes/ChartViewport/Scripts/ChartManager.cs
@@ -33,6 +33,45 @@ public override void _Ready()
IH.Connect(nameof(InputHandler.NoteReleased), new Callable(this, nameof(OnNoteReleased)));
}
+ public override void _Process(double delta)
+ {
+ if (!BattleDirector.AutoPlay)
+ return;
+
+ for (int dir = 0; dir < 4; dir++)
+ {
+ if (
+ _currentHolds[dir] != null
+ && _currentHolds[dir].EndBeat - TimeKeeper.LastBeat < new Beat(0.1)
+ )
+ {
+ OnNoteReleased((ArrowType)dir);
+ IH.Arrows[dir].Node.SetPressed(false);
+ continue;
+ }
+
+ foreach (NoteArrow note in _queuedArrows[dir])
+ {
+ if (!note.IsHit && note.Beat - TimeKeeper.LastBeat < new Beat(0.1))
+ {
+ OnNotePressed((ArrowType)dir);
+ IH.Arrows[dir].Node.SetPressed(true);
+ if (note is not HoldArrow)
+ {
+ int capDir = dir;
+ Callable
+ .From(() =>
+ {
+ OnNoteReleased((ArrowType)capDir);
+ IH.Arrows[capDir].Node.SetPressed(false);
+ })
+ .CallDeferred();
+ }
+ }
+ }
+ }
+ }
+
private bool _initialized;
public void Initialize(SongData songData)
@@ -58,11 +97,15 @@ public void Initialize(SongData songData)
_initialized = true;
}
+ public Tween ArrowTween;
+
public void BeginTweens()
{
+ if (ArrowTween != null)
+ this.ArrowTween.Kill();
//This could be good as a function to call on something, to have many things animated to the beat.
- var tween = CreateTween();
- tween
+ ArrowTween = CreateTween();
+ ArrowTween
.TweenMethod(
Callable.From((Vector2 scale) => TweenArrows(scale)),
Vector2.One * .8f,
@@ -71,13 +114,13 @@ public void BeginTweens()
)
.SetEase(Tween.EaseType.Out)
.SetTrans(Tween.TransitionType.Elastic);
- tween.TweenMethod(
+ ArrowTween.TweenMethod(
Callable.From((Vector2 scale) => TweenArrows(scale)),
Vector2.One,
Vector2.One * .8f,
60f / TimeKeeper.Bpm / 2
);
- tween.SetLoops().Play();
+ ArrowTween.SetLoops().Play();
}
private void TweenArrows(Vector2 scale)
diff --git a/Scenes/ChestScene/ChestScene.tscn b/Scenes/ChestScene/ChestScene.tscn
index 4ce4a918..bd88dc49 100644
--- a/Scenes/ChestScene/ChestScene.tscn
+++ b/Scenes/ChestScene/ChestScene.tscn
@@ -23,7 +23,8 @@ script = ExtResource("1_ardd2")
ChestButton = NodePath("CenterContainer/VBoxContainer/ChestButton")
PlayerMarker = NodePath("PlayerMarker")
-[node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."]
+[node name="Audio" type="AudioStreamPlayer" parent="."]
+process_mode = 3
stream = ExtResource("2_x78jo")
autoplay = true
diff --git a/Scenes/EventScene/EventScene.cs b/Scenes/EventScene/EventScene.cs
new file mode 100644
index 00000000..287995c2
--- /dev/null
+++ b/Scenes/EventScene/EventScene.cs
@@ -0,0 +1,140 @@
+using System;
+using System.Collections.Generic;
+using FunkEngine;
+using Godot;
+
+public partial class EventScene : Node
+{
+ public static readonly string LoadPath = "res://Scenes/EventScene/EventScene.tscn";
+ private PlayerPuppet _player;
+
+ [Export]
+ public Marker2D PlayerMarker;
+
+ [Export]
+ public Sprite2D EventSprite;
+
+ [Export]
+ private Label _eventDescription;
+
+ [Export]
+ private VBoxContainer _buttonContainer;
+
+ [Export]
+ private Button _continueButton;
+
+ [Export]
+ private MarginContainer _continueContainer;
+
+ public static List EventPool;
+
+ private static readonly Theme ButtonTheme = GD.Load(
+ "res://Scenes/UI/Assets/GeneralTheme.tres"
+ ); // Store the theme
+
+ private EventTemplate _eventReference;
+ private int _updateOutputIndex;
+
+ public override void _Ready()
+ {
+ _player = GD.Load(PlayerPuppet.LoadPath).Instantiate();
+ PlayerMarker.AddChild(_player);
+
+ if (EventPool == null || EventPool.Count == 0)
+ RefreshPool();
+
+ RandomNumberGenerator stageRng = new RandomNumberGenerator();
+ stageRng.SetSeed(StageProducer.GlobalRng.Seed + (ulong)StageProducer.Config.BattleRoom.Idx);
+ int eventIndex = stageRng.RandiRange(0, EventPool.Count - 1);
+ _eventReference = EventDatabase.EventDictionary[EventPool[eventIndex]];
+
+ EventPool.RemoveAt(eventIndex);
+ DisplayEvent();
+ }
+
+ public override void _Process(double delta)
+ {
+ if (GetViewport().GuiGetFocusOwner() == null)
+ {
+ if (_continueContainer.Visible)
+ _continueButton.GrabFocus();
+ else
+ _buttonContainer.GetChild(0).GrabFocus();
+ }
+ }
+
+ private void RefreshPool()
+ {
+ EventPool = new List();
+ for (int i = 0; i < EventDatabase.EventDatabaseSize; i++)
+ {
+ EventPool.Add(i);
+ }
+ for (int i = 0; i < EventPool.Count - 2; i++)
+ {
+ int randIdx = StageProducer.GlobalRng.RandiRange(0, EventPool.Count - 1);
+ (EventPool[i], EventPool[randIdx]) = (EventPool[randIdx], EventPool[i]); //rad
+ }
+ }
+
+ ///
+ /// Displays the set event.
+ ///
+ public void DisplayEvent()
+ {
+ _eventDescription.Text = _eventReference.EventDescription;
+ EventSprite.Texture = _eventReference.Texture;
+
+ for (int i = 0; i < _eventReference.ButtonDescriptions.Length; i++)
+ {
+ var button = new Button
+ {
+ Text = _eventReference.ButtonDescriptions[i],
+ Theme = ButtonTheme,
+ SizeFlagsVertical = Control.SizeFlags.Expand | Control.SizeFlags.Fill,
+ };
+
+ bool isEnabled;
+ if (
+ _eventReference.OptionEnabledConditions == null
+ || _eventReference.OptionEnabledConditions.Length <= i
+ )
+ {
+ GD.PushWarning("Event Conditions are invalid for event: " + _eventReference.Id);
+ isEnabled = true;
+ }
+ else
+ { // Check if the button should be enabled
+ isEnabled =
+ _eventReference.OptionEnabledConditions[i] == null
+ || _eventReference.OptionEnabledConditions[i].Invoke();
+ }
+
+ button.Disabled = !isEnabled;
+
+ int capturedIndex = i;
+ button.Pressed += () =>
+ {
+ _eventReference.OptionActions[capturedIndex]?.Invoke(_eventReference, this);
+ AnyButtonPressed(capturedIndex);
+ };
+
+ // Automatically focus the first *enabled* button
+ if (capturedIndex == 0 && isEnabled)
+ {
+ button.CallDeferred("grab_focus");
+ }
+
+ _buttonContainer.AddChild(button);
+ }
+ }
+
+ public void AnyButtonPressed(int capturedIndex)
+ {
+ _updateOutputIndex = capturedIndex;
+ _buttonContainer.GetParent().Visible = false;
+ _continueContainer.Visible = _eventReference.OutcomeDescriptions[capturedIndex] != "";
+ _eventDescription.Text = _eventReference.OutcomeDescriptions[capturedIndex];
+ _continueButton.GrabFocus();
+ }
+}
diff --git a/Scenes/EventScene/EventScene.cs.uid b/Scenes/EventScene/EventScene.cs.uid
new file mode 100644
index 00000000..cb060cd4
--- /dev/null
+++ b/Scenes/EventScene/EventScene.cs.uid
@@ -0,0 +1 @@
+uid://md1vhln8ji5h
diff --git a/Scenes/EventScene/EventScene.tscn b/Scenes/EventScene/EventScene.tscn
new file mode 100644
index 00000000..92dbbd0d
--- /dev/null
+++ b/Scenes/EventScene/EventScene.tscn
@@ -0,0 +1,147 @@
+[gd_scene load_steps=10 format=3 uid="uid://u7oppwtmvmci"]
+
+[ext_resource type="Script" uid="uid://md1vhln8ji5h" path="res://Scenes/EventScene/EventScene.cs" id="1_x82kl"]
+[ext_resource type="AudioStream" uid="uid://be5ial13ynf3o" path="res://Audio/Song1.ogg" id="2_vywvm"]
+[ext_resource type="Script" uid="uid://pl57giqyhckb" path="res://Scenes/UI/Scripts/MenuModule.cs" id="2_x82kl"]
+[ext_resource type="Texture2D" uid="uid://qhwve7fik4do" path="res://SharedAssets/BackGround_Full.png" id="4_l56en"]
+[ext_resource type="Texture2D" uid="uid://8u3xvcma81d" path="res://Scenes/UI/Assets/UI_CrystalFrame.png" id="5_erk58"]
+[ext_resource type="Script" uid="uid://cp6t6haqyef7o" path="res://Scenes/AreaBasedBackground.cs" id="5_v3lan"]
+[ext_resource type="Texture2D" uid="uid://burj10os057fx" path="res://Scenes/UI/Assets/UI_CrystalFrameInset.png" id="6_4prsq"]
+[ext_resource type="Theme" uid="uid://d37e3tpsbxwak" path="res://Scenes/UI/Assets/GeneralTheme.tres" id="8_4prsq"]
+[ext_resource type="Script" uid="uid://cahjluc6v7ked" path="res://Scenes/UI/TitleScreen/Scripts/SceneChange.cs" id="9_lw2xf"]
+
+[node name="EventScene" type="Node2D" node_paths=PackedStringArray("PlayerMarker", "EventSprite", "_eventDescription", "_buttonContainer", "_continueButton", "_continueContainer")]
+process_mode = 1
+script = ExtResource("1_x82kl")
+PlayerMarker = NodePath("PlayerMarker")
+EventSprite = NodePath("EventSprite")
+_eventDescription = NodePath("Control/MarginContainer/PanelContainer/HBoxContainer/DescBox/DescMargin/Description")
+_buttonContainer = NodePath("Control/MarginContainer/PanelContainer/HBoxContainer/ButtonContainer/VBoxContainer")
+_continueButton = NodePath("Control/MarginContainer/PanelContainer/HBoxContainer/ContinueContainer/ContinueButton")
+_continueContainer = NodePath("Control/MarginContainer/PanelContainer/HBoxContainer/ContinueContainer")
+
+[node name="UILayer" type="CanvasLayer" parent="." node_paths=PackedStringArray("CurSceneNode")]
+script = ExtResource("2_x82kl")
+CurSceneNode = NodePath("..")
+
+[node name="Audio" type="AudioStreamPlayer" parent="."]
+unique_name_in_owner = true
+stream = ExtResource("2_vywvm")
+autoplay = true
+
+[node name="PlayerMarker" type="Marker2D" parent="."]
+position = Vector2(158, 125)
+
+[node name="EventSprite" type="Sprite2D" parent="."]
+position = Vector2(385, 125)
+
+[node name="BackGround" type="TextureRect" parent="."]
+z_index = -1
+offset_right = 640.0
+offset_bottom = 178.0
+texture = ExtResource("4_l56en")
+script = ExtResource("5_v3lan")
+
+[node name="Control" type="Control" parent="."]
+layout_mode = 3
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+offset_right = 640.0
+offset_bottom = 360.0
+grow_horizontal = 2
+grow_vertical = 2
+size_flags_horizontal = 3
+size_flags_vertical = 3
+
+[node name="MarginContainer" type="MarginContainer" parent="Control"]
+custom_minimum_size = Vector2(0, 180)
+layout_mode = 1
+anchors_preset = 12
+anchor_top = 1.0
+anchor_right = 1.0
+anchor_bottom = 1.0
+offset_top = -105.0
+grow_horizontal = 2
+grow_vertical = 0
+size_flags_horizontal = 3
+size_flags_vertical = 3
+
+[node name="PanelContainer" type="PanelContainer" parent="Control/MarginContainer"]
+layout_mode = 2
+
+[node name="SelectionBG" type="NinePatchRect" parent="Control/MarginContainer/PanelContainer"]
+self_modulate = Color(1, 1, 1, 0.75)
+custom_minimum_size = Vector2(540, 105)
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_vertical = 3
+texture = ExtResource("5_erk58")
+patch_margin_left = 30
+patch_margin_top = 10
+patch_margin_right = 20
+patch_margin_bottom = 27
+
+[node name="HBoxContainer" type="HBoxContainer" parent="Control/MarginContainer/PanelContainer"]
+layout_mode = 2
+
+[node name="DescBox" type="MarginContainer" parent="Control/MarginContainer/PanelContainer/HBoxContainer"]
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_vertical = 3
+theme_override_constants/margin_left = 5
+theme_override_constants/margin_top = 5
+theme_override_constants/margin_right = 5
+theme_override_constants/margin_bottom = 5
+
+[node name="DescBackground" type="NinePatchRect" parent="Control/MarginContainer/PanelContainer/HBoxContainer/DescBox"]
+layout_mode = 2
+texture = ExtResource("6_4prsq")
+patch_margin_left = 7
+patch_margin_top = 7
+patch_margin_right = 7
+patch_margin_bottom = 7
+
+[node name="DescMargin" type="MarginContainer" parent="Control/MarginContainer/PanelContainer/HBoxContainer/DescBox"]
+layout_mode = 2
+size_flags_stretch_ratio = 0.0
+theme_override_constants/margin_left = 0
+theme_override_constants/margin_top = 0
+theme_override_constants/margin_right = 0
+theme_override_constants/margin_bottom = 0
+
+[node name="Description" type="Label" parent="Control/MarginContainer/PanelContainer/HBoxContainer/DescBox/DescMargin"]
+layout_mode = 2
+size_flags_vertical = 1
+text = ":HeathCliff:"
+horizontal_alignment = 1
+vertical_alignment = 1
+autowrap_mode = 2
+clip_text = true
+text_overrun_behavior = 1
+
+[node name="ButtonContainer" type="MarginContainer" parent="Control/MarginContainer/PanelContainer/HBoxContainer"]
+layout_mode = 2
+theme_override_constants/margin_left = -5
+theme_override_constants/margin_top = 7
+theme_override_constants/margin_right = 10
+theme_override_constants/margin_bottom = 7
+
+[node name="VBoxContainer" type="VBoxContainer" parent="Control/MarginContainer/PanelContainer/HBoxContainer/ButtonContainer"]
+layout_mode = 2
+
+[node name="ContinueContainer" type="MarginContainer" parent="Control/MarginContainer/PanelContainer/HBoxContainer"]
+visible = false
+layout_mode = 2
+theme_override_constants/margin_left = -5
+theme_override_constants/margin_top = 7
+theme_override_constants/margin_right = 10
+theme_override_constants/margin_bottom = 7
+
+[node name="ContinueButton" type="Button" parent="Control/MarginContainer/PanelContainer/HBoxContainer/ContinueContainer"]
+layout_mode = 2
+size_flags_vertical = 8
+theme = ExtResource("8_4prsq")
+text = "EVENT_CONTINUE_BUTTON"
+script = ExtResource("9_lw2xf")
+ScenePath = 7
diff --git a/Scenes/Maps/Assets/EliteIcon.png b/Scenes/Maps/Assets/EliteIcon.png
new file mode 100644
index 00000000..05374404
Binary files /dev/null and b/Scenes/Maps/Assets/EliteIcon.png differ
diff --git a/Scenes/Maps/Assets/EliteIcon.png.import b/Scenes/Maps/Assets/EliteIcon.png.import
new file mode 100644
index 00000000..4b35faab
--- /dev/null
+++ b/Scenes/Maps/Assets/EliteIcon.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bo6pprsk2p8fn"
+path="res://.godot/imported/EliteIcon.png-3fb4b7e324eb40bf5441f47b2b3a396b.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Scenes/Maps/Assets/EliteIcon.png"
+dest_files=["res://.godot/imported/EliteIcon.png-3fb4b7e324eb40bf5441f47b2b3a396b.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/Scenes/Maps/Assets/EventIcon.png b/Scenes/Maps/Assets/EventIcon.png
new file mode 100644
index 00000000..07ae24cf
Binary files /dev/null and b/Scenes/Maps/Assets/EventIcon.png differ
diff --git a/Scenes/Maps/Assets/EventIcon.png.import b/Scenes/Maps/Assets/EventIcon.png.import
new file mode 100644
index 00000000..3aa726f8
--- /dev/null
+++ b/Scenes/Maps/Assets/EventIcon.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bi08ruf8ld4mn"
+path="res://.godot/imported/EventIcon.png-59b4b2ec31a8401aaa31d4b2033bc7ef.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Scenes/Maps/Assets/EventIcon.png"
+dest_files=["res://.godot/imported/EventIcon.png-59b4b2ec31a8401aaa31d4b2033bc7ef.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/Scenes/Maps/Assets/FirstIcon.png b/Scenes/Maps/Assets/FirstIcon.png
new file mode 100644
index 00000000..0c25138c
Binary files /dev/null and b/Scenes/Maps/Assets/FirstIcon.png differ
diff --git a/Scenes/Maps/Assets/FirstIcon.png.import b/Scenes/Maps/Assets/FirstIcon.png.import
new file mode 100644
index 00000000..e0dac93f
--- /dev/null
+++ b/Scenes/Maps/Assets/FirstIcon.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dxiceak20m0l7"
+path="res://.godot/imported/FirstIcon.png-51362bbefd81dee000fc3aedbade09ac.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Scenes/Maps/Assets/FirstIcon.png"
+dest_files=["res://.godot/imported/FirstIcon.png-51362bbefd81dee000fc3aedbade09ac.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/Scenes/Maps/Assets/ShopIcon.png b/Scenes/Maps/Assets/ShopIcon.png
new file mode 100644
index 00000000..47c478cc
Binary files /dev/null and b/Scenes/Maps/Assets/ShopIcon.png differ
diff --git a/Scenes/Maps/Assets/ShopIcon.png.import b/Scenes/Maps/Assets/ShopIcon.png.import
new file mode 100644
index 00000000..70de0b02
--- /dev/null
+++ b/Scenes/Maps/Assets/ShopIcon.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://thmkt407eqbo"
+path="res://.godot/imported/ShopIcon.png-db80b24a389b2b47bc99151013ec8cd6.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Scenes/Maps/Assets/ShopIcon.png"
+dest_files=["res://.godot/imported/ShopIcon.png-db80b24a389b2b47bc99151013ec8cd6.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/Scenes/Maps/Assets/StartIcon.png b/Scenes/Maps/Assets/StartIcon.png
new file mode 100644
index 00000000..3b5e9135
Binary files /dev/null and b/Scenes/Maps/Assets/StartIcon.png differ
diff --git a/Scenes/Maps/Assets/StartIcon.png.import b/Scenes/Maps/Assets/StartIcon.png.import
new file mode 100644
index 00000000..3bbd35d8
--- /dev/null
+++ b/Scenes/Maps/Assets/StartIcon.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cyip3p5s5pav5"
+path="res://.godot/imported/StartIcon.png-7b0cc3340e736d4b2b89804cd6171f26.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Scenes/Maps/Assets/StartIcon.png"
+dest_files=["res://.godot/imported/StartIcon.png-7b0cc3340e736d4b2b89804cd6171f26.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/Scenes/Maps/Cartographer.tscn b/Scenes/Maps/Cartographer.tscn
index 157ca73d..77d92b06 100644
--- a/Scenes/Maps/Cartographer.tscn
+++ b/Scenes/Maps/Cartographer.tscn
@@ -18,6 +18,7 @@ Camera = NodePath("TheView")
top_level = true
anchor_mode = 0
limit_top = -10
+limit_bottom = 530
[node name="UI" type="CanvasLayer" parent="." node_paths=PackedStringArray("CurSceneNode")]
script = ExtResource("2_cl7v0")
@@ -25,10 +26,15 @@ CurSceneNode = NodePath("..")
[node name="BG" type="TextureRect" parent="."]
modulate = Color(0.462, 0.462, 0.66, 1)
-offset_left = -557.0
-offset_top = -84.0
-offset_right = 83.0
-offset_bottom = 96.0
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+offset_left = -320.0
+offset_top = -10.0
+offset_right = 320.0
+offset_bottom = 170.0
+grow_horizontal = 2
+grow_vertical = 2
scale = Vector2(3, 3)
texture = ExtResource("2_5g6at")
script = ExtResource("5_taedj")
diff --git a/Scenes/Maps/InBetween.tscn b/Scenes/Maps/InBetween.tscn
index d425f862..9718aa1a 100644
--- a/Scenes/Maps/InBetween.tscn
+++ b/Scenes/Maps/InBetween.tscn
@@ -1,15 +1,14 @@
[gd_scene load_steps=4 format=3 uid="uid://djlperv5n75y1"]
-[ext_resource type="Texture2D" uid="uid://qhwve7fik4do" path="res://SharedAssets/BackGround_Full.png" id="1_74aj5"]
+[ext_resource type="Texture2D" uid="uid://b7xhtf8tgyxuq" path="res://SharedAssets/BG_Forest_To_City.png" id="1_74aj5"]
[ext_resource type="Theme" uid="uid://d37e3tpsbxwak" path="res://Scenes/UI/Assets/GeneralTheme.tres" id="2_dapxv"]
[ext_resource type="Script" uid="uid://cahjluc6v7ked" path="res://Scenes/UI/TitleScreen/Scripts/SceneChange.cs" id="3_35xdc"]
[node name="Inbetween" type="Node2D"]
[node name="Sprite2D" type="Sprite2D" parent="."]
-position = Vector2(197, 86)
-rotation = 3.72628
-scale = Vector2(3.81, 3.81)
+position = Vector2(320, 180)
+scale = Vector2(2, 2)
texture = ExtResource("1_74aj5")
[node name="Button" type="Button" parent="."]
@@ -20,5 +19,5 @@ offset_bottom = 284.0
theme = ExtResource("2_dapxv")
text = "INBETWEEN_CONTINUE"
script = ExtResource("3_35xdc")
-ScenePath = 5
+ScenePath = 7
_startFocused = true
diff --git a/Scenes/Maps/Scripts/Cartographer.cs b/Scenes/Maps/Scripts/Cartographer.cs
index ebd07533..def841d0 100644
--- a/Scenes/Maps/Scripts/Cartographer.cs
+++ b/Scenes/Maps/Scripts/Cartographer.cs
@@ -24,14 +24,15 @@ public partial class Cartographer : Node2D
private Button _focusedButton;
- private static readonly Dictionary StageIcons = new Dictionary<
- Stages,
- Texture2D
- >
+ private static readonly Dictionary StageIcons = new()
{
{ Stages.Battle, GD.Load("res://Scenes/Maps/Assets/BattleIcon.png") },
+ { Stages.Elite, GD.Load("res://Scenes/Maps/Assets/EliteIcon.png") },
{ Stages.Boss, GD.Load("res://Scenes/Maps/Assets/BossIcon.png") },
{ Stages.Chest, GD.Load("res://Scenes/Maps/Assets/ChestIcon.png") },
+ { Stages.Shop, GD.Load("res://Scenes/Maps/Assets/ShopIcon.png") },
+ { Stages.Event, GD.Load("res://Scenes/Maps/Assets/EventIcon.png") },
+ { Stages.Map, GD.Load("res://Scenes/Maps/Assets/FirstIcon.png") },
};
public override void _Ready()
@@ -47,6 +48,29 @@ public override void _Ready()
}
}
+ const float CameraSpeed = 120f;
+
+ public override void _Process(double delta)
+ {
+ if (Camera.Position.Y > Camera.LimitTop && Input.IsActionPressed("ui_up"))
+ {
+ Camera.Position = Camera.Position with
+ {
+ Y = (float)(Camera.Position.Y - CameraSpeed * delta),
+ };
+ }
+ else if (
+ Camera.Position.Y < Camera.LimitBottom - GetViewportRect().Size.Y
+ && Input.IsActionPressed("ui_down")
+ )
+ {
+ Camera.Position = Camera.Position with
+ {
+ Y = (float)(Camera.Position.Y + CameraSpeed * delta),
+ };
+ }
+ }
+
public override void _EnterTree()
{
BgAudioPlayer.LiveInstance.PlayLevelMusic();
@@ -54,7 +78,7 @@ public override void _EnterTree()
private Vector2 GetPosition(int x, int y)
{
- return new Vector2((float)x * 640 / 8 + 32, y * 48 + 16);
+ return new Vector2((float)(x + 1) * 640 / (StageProducer.Map.Width + 1), y * 48 + 16);
}
private void DrawMap()
@@ -85,35 +109,48 @@ private void DrawMapSprite(MapGrid.Room room)
newButton.CustomMinimumSize = MapIconSize;
newButton.IconAlignment = HorizontalAlignment.Center;
AddChild(newButton);
+ bool isChild = StageProducer.GetCurRoom().Children.Contains(room.Idx);
+
+ // checks if the next room is one below current room, player has shortcuts
+ bool isLaneChangeAllowed =
+ room.Y == StageProducer.GetCurRoom().Y + 1 && StageProducer.PlayerStats.Shortcuts > 0;
+
//button is disabled if it is not a child of current room.
- if (!StageProducer.GetCurRoom().Children.Contains(room.Idx))
+ //unless player has charges of lane changing
+ if (!isChild && !isLaneChangeAllowed)
{
newButton.Disabled = true;
newButton.FocusMode = Control.FocusModeEnum.None;
}
else
{
- newButton.GrabFocus();
- _focusedButton = newButton;
+ //grab focus on children paths, to really make sure user wants to use a charge of maplanechanges
+ if (isChild)
+ {
+ newButton.GrabFocus();
+ _focusedButton = newButton;
+ }
newButton.Pressed += () =>
{
+ if (!isChild)
+ StageProducer.PlayerStats.Shortcuts--;
+
EnterStage(room.Idx, newButton);
};
_validButtons = _validButtons.Append(newButton).ToArray();
}
newButton.Icon = StageIcons[room.Type];
+ if (room.Y == 0)
+ newButton.Icon = StageIcons[Stages.Map];
newButton.ZIndex = 1;
newButton.Position = GetPosition(room.X, room.Y) - newButton.Size / 2;
- if (room == StageProducer.GetCurRoom())
- {
- PlayerSprite.Position = newButton.Position + newButton.Size * .5f;
- Camera.Position -= //TODO: Better camera matching for areas.
- (
- (GetViewportRect().Size / 2) - (newButton.Position + newButton.Size * .5f)
- ).Normalized() * 20;
- }
+ if (room != StageProducer.GetCurRoom())
+ return;
+
+ PlayerSprite.Position = newButton.Position + newButton.Size * .5f;
+ Camera.Position = new Vector2(0, PlayerSprite.Position.Y - MapIconSize.Y / 2);
}
private void AddFocusNeighbors()
@@ -150,7 +187,7 @@ private void EnterStage(int roomIdx, Button button)
private void WinArea()
{
- if (StageProducer.IsMoreAreas())
+ if (StageProducer.IsMoreLevels())
{
GetTree().Paused = false;
//What the living fuck? Can't do this during ready?
@@ -160,6 +197,12 @@ private void WinArea()
return;
}
+ //Achievement code for emptyPockets
+ if (StageProducer.PlayerStats.CurRelics.Length == 0)
+ {
+ SteamWhisperer.PopAchievement("emptyPockets");
+ }
+
EndScreen es = GD.Load(EndScreen.LoadPath).Instantiate();
AddChild(es);
es.TopLabel.Text = Tr("BATTLE_ROOM_WIN");
diff --git a/Scenes/NoteManager/Assets/Arrow_Trail.png b/Scenes/NoteManager/Assets/Arrow_Trail.png
index 671b8f18..0475190e 100644
Binary files a/Scenes/NoteManager/Assets/Arrow_Trail.png and b/Scenes/NoteManager/Assets/Arrow_Trail.png differ
diff --git a/Scenes/NoteManager/Scripts/InputHandler.cs b/Scenes/NoteManager/Scripts/InputHandler.cs
index 6f953767..bb6f21a9 100644
--- a/Scenes/NoteManager/Scripts/InputHandler.cs
+++ b/Scenes/NoteManager/Scripts/InputHandler.cs
@@ -64,6 +64,8 @@ public override void _Process(double delta)
SaveSystem.UpdateConfig(SaveSystem.ConfigSettings.InputType, "WASD");
}
+ if (BattleDirector.PlayerDisabled)
+ return;
foreach (var arrow in Arrows)
{
if (Input.IsActionJustPressed(scheme + "_" + arrow.Key))
diff --git a/Scenes/Puppets/Enemies/BossBlood/Boss1.tscn b/Scenes/Puppets/Enemies/BossBlood/Boss1.tscn
index fd5648c8..02923247 100644
--- a/Scenes/Puppets/Enemies/BossBlood/Boss1.tscn
+++ b/Scenes/Puppets/Enemies/BossBlood/Boss1.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=9 format=3 uid="uid://bi5iqbwpsd381"]
+[gd_scene load_steps=11 format=3 uid="uid://bi5iqbwpsd381"]
[ext_resource type="Script" uid="uid://bpyrrnhvisxgv" path="res://Scenes/Puppets/Enemies/BossBlood/P_BossBlood.cs" id="1_qj2oj"]
[ext_resource type="PackedScene" uid="uid://cdoguwlxehbpg" path="res://Scenes/Puppets/StatusContainer.tscn" id="2_b8x7h"]
@@ -23,6 +23,16 @@ scale_min = 4.0
scale_max = 4.0
turbulence_noise_strength = 14.2
+[sub_resource type="Gradient" id="Gradient_b8x7h"]
+offsets = PackedFloat32Array(0.0227273, 1)
+colors = PackedColorArray(0, 1, 0.0999999, 1, 1, 1, 1, 1)
+
+[sub_resource type="GradientTexture2D" id="GradientTexture2D_i20fw"]
+resource_local_to_scene = true
+gradient = SubResource("Gradient_b8x7h")
+width = 100
+height = 18
+
[node name="EnemPuppet" type="Node2D" node_paths=PackedStringArray("HealthBar", "Sprite", "_statusContainer")]
script = ExtResource("1_qj2oj")
HealthBar = NodePath("ProgressBar")
@@ -52,3 +62,4 @@ offset_left = -50.0
offset_top = 32.0
offset_right = 50.0
offset_bottom = 52.0
+texture_progress = SubResource("GradientTexture2D_i20fw")
diff --git a/Scenes/Puppets/Enemies/BossBlood/P_BossBlood.cs b/Scenes/Puppets/Enemies/BossBlood/P_BossBlood.cs
index b37a8ecb..90d2f495 100644
--- a/Scenes/Puppets/Enemies/BossBlood/P_BossBlood.cs
+++ b/Scenes/Puppets/Enemies/BossBlood/P_BossBlood.cs
@@ -8,8 +8,10 @@ public partial class P_BossBlood : EnemyPuppet
public override void _Ready()
{
- CurrentHealth = 100;
- MaxHealth = 100;
+ MaxHealth = 225;
+ CurrentHealth = MaxHealth;
+ BaseMoney = 15;
+ InitialNote = (14, 3);
base._Ready();
var enemTween = CreateTween();
enemTween.TweenProperty(Sprite, "position", Vector2.Down * 5, 1f).AsRelative();
@@ -24,10 +26,28 @@ public override void _Ready()
new EnemyEffect(
this,
BattleEffectTrigger.OnLoop,
- 5,
+ 20,
(e, eff, val) =>
{
eff.Owner.Heal(val);
+ e.BD.RandApplyNote(eff.Owner, 14, 1);
+ }
+ ),
+ new EnemyEffect(
+ this,
+ BattleEffectTrigger.OnDamageInstance,
+ 1,
+ (e, eff, val) =>
+ {
+ if (e is not BattleDirector.Harbinger.OnDamageInstanceArgs dArgs)
+ return;
+ if (
+ dArgs.Dmg.Target == this
+ && dArgs.Dmg.Target.GetCurrentHealth() <= dArgs.Dmg.Damage
+ )
+ {
+ SteamWhisperer.PopAchievement("actOneComp");
+ }
}
),
};
diff --git a/Scenes/Puppets/Enemies/CyberFox/Assets/CyberFox.png b/Scenes/Puppets/Enemies/CyberFox/Assets/CyberFox.png
new file mode 100644
index 00000000..7e89fe11
Binary files /dev/null and b/Scenes/Puppets/Enemies/CyberFox/Assets/CyberFox.png differ
diff --git a/Scenes/Puppets/Enemies/CyberFox/Assets/CyberFox.png.import b/Scenes/Puppets/Enemies/CyberFox/Assets/CyberFox.png.import
new file mode 100644
index 00000000..5649b40a
--- /dev/null
+++ b/Scenes/Puppets/Enemies/CyberFox/Assets/CyberFox.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dy61pskhqgjoo"
+path="res://.godot/imported/CyberFox.png-6ae173f8097de4ea0ff4026765a58ce8.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Scenes/Puppets/Enemies/CyberFox/Assets/CyberFox.png"
+dest_files=["res://.godot/imported/CyberFox.png-6ae173f8097de4ea0ff4026765a58ce8.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/Scenes/Puppets/Enemies/CyberFox/Assets/GlitchEffect.gdshader b/Scenes/Puppets/Enemies/CyberFox/Assets/GlitchEffect.gdshader
new file mode 100644
index 00000000..e31b6a06
--- /dev/null
+++ b/Scenes/Puppets/Enemies/CyberFox/Assets/GlitchEffect.gdshader
@@ -0,0 +1,54 @@
+/*
+ Glitch Effect Shader by Yui Kinomoto @arlez80
+
+ MIT License
+*/
+
+shader_type canvas_item;
+
+uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_linear_mipmap;
+
+// 振動の強さ
+uniform float shake_power = 0.03;
+// 振動率
+uniform float shake_rate : hint_range( 0.0, 1.0 ) = 0.2;
+// 振動速度
+uniform float shake_speed = 5.0;
+// 振動ブロックサイズ
+uniform float shake_block_size = 30.5;
+// 色の分離率
+uniform float shake_color_rate : hint_range( 0.0, 1.0 ) = 0.01;
+
+float random( float seed )
+{
+ return fract( 543.2543 * sin( dot( vec2( seed, seed ), vec2( 3525.46, -54.3415 ) ) ) );
+}
+
+void fragment( )
+{
+ float enable_shift = float(
+ random( trunc( TIME * shake_speed ) )
+ < shake_rate
+ );
+
+ vec2 fixed_uv = SCREEN_UV;
+ fixed_uv.x += (
+ random(
+ ( trunc( SCREEN_UV.y * shake_block_size ) / shake_block_size )
+ + TIME
+ ) - 0.5
+ ) * shake_power * enable_shift;
+
+ vec4 pixel_color = textureLod( SCREEN_TEXTURE, fixed_uv, 0.0 );
+ pixel_color.r = mix(
+ pixel_color.r
+ , textureLod( SCREEN_TEXTURE, fixed_uv + vec2( shake_color_rate, 0.0 ), 0.0 ).r
+ , enable_shift
+ );
+ pixel_color.b = mix(
+ pixel_color.b
+ , textureLod( SCREEN_TEXTURE, fixed_uv + vec2( -shake_color_rate, 0.0 ), 0.0 ).b
+ , enable_shift
+ );
+ COLOR = pixel_color;
+}
diff --git a/Scenes/Puppets/Enemies/CyberFox/Assets/GlitchEffect.gdshader.uid b/Scenes/Puppets/Enemies/CyberFox/Assets/GlitchEffect.gdshader.uid
new file mode 100644
index 00000000..5c549d47
--- /dev/null
+++ b/Scenes/Puppets/Enemies/CyberFox/Assets/GlitchEffect.gdshader.uid
@@ -0,0 +1 @@
+uid://df5rjsuxn4o70
diff --git a/Scenes/Puppets/Enemies/CyberFox/Assets/GlitchScript.cs b/Scenes/Puppets/Enemies/CyberFox/Assets/GlitchScript.cs
new file mode 100644
index 00000000..97d2013e
--- /dev/null
+++ b/Scenes/Puppets/Enemies/CyberFox/Assets/GlitchScript.cs
@@ -0,0 +1,47 @@
+using System;
+using Godot;
+
+public partial class GlitchScript : Node
+{
+ private ShaderMaterial _glitchMaterial;
+ private Timer _glitchTimer;
+
+ [Export]
+ public Sprite2D Sprite;
+
+ public override void _Ready()
+ {
+ var shader = GD.Load(
+ "res://Scenes/Puppets/Enemies/CyberFox/Assets/GlitchEffect.gdshader"
+ );
+ _glitchMaterial = new ShaderMaterial { Shader = shader };
+ Sprite.Material = _glitchMaterial;
+
+ DisableGlitch();
+ _glitchTimer = new Timer { OneShot = true, Autostart = false };
+ AddChild(_glitchTimer);
+ _glitchTimer.Timeout += OnGlitchTimerTimeout;
+ }
+
+ public void TriggerGlitch(float duration)
+ {
+ EnableGlitch();
+ _glitchTimer.WaitTime = duration;
+ _glitchTimer.Start();
+ }
+
+ private void OnGlitchTimerTimeout()
+ {
+ DisableGlitch();
+ }
+
+ private void EnableGlitch()
+ {
+ _glitchMaterial.SetShaderParameter("shake_rate", 0.8f);
+ }
+
+ private void DisableGlitch()
+ {
+ _glitchMaterial.SetShaderParameter("shake_rate", 0.0f);
+ }
+}
diff --git a/Scenes/Puppets/Enemies/CyberFox/Assets/GlitchScript.cs.uid b/Scenes/Puppets/Enemies/CyberFox/Assets/GlitchScript.cs.uid
new file mode 100644
index 00000000..ec5951d6
--- /dev/null
+++ b/Scenes/Puppets/Enemies/CyberFox/Assets/GlitchScript.cs.uid
@@ -0,0 +1 @@
+uid://3yclsl4kckx4
diff --git a/Scenes/Puppets/Enemies/CyberFox/CyberFox.tscn b/Scenes/Puppets/Enemies/CyberFox/CyberFox.tscn
new file mode 100644
index 00000000..9d48dfcf
--- /dev/null
+++ b/Scenes/Puppets/Enemies/CyberFox/CyberFox.tscn
@@ -0,0 +1,48 @@
+[gd_scene load_steps=8 format=3 uid="uid://2iq6mp0o5eri"]
+
+[ext_resource type="Script" uid="uid://dnkjrr1f5up7x" path="res://Scenes/Puppets/Enemies/CyberFox/P_CyberFox.cs" id="1_e1x4p"]
+[ext_resource type="PackedScene" uid="uid://cdoguwlxehbpg" path="res://Scenes/Puppets/StatusContainer.tscn" id="2_t5538"]
+[ext_resource type="Texture2D" uid="uid://dy61pskhqgjoo" path="res://Scenes/Puppets/Enemies/CyberFox/Assets/CyberFox.png" id="3_e1x4p"]
+[ext_resource type="PackedScene" uid="uid://bgomxovxs7sr8" path="res://Scenes/Puppets/HealthBar.tscn" id="4_lmj2w"]
+[ext_resource type="Script" uid="uid://3yclsl4kckx4" path="res://Scenes/Puppets/Enemies/CyberFox/Assets/GlitchScript.cs" id="5_a0uir"]
+
+[sub_resource type="Gradient" id="Gradient_c7cx1"]
+offsets = PackedFloat32Array(0.0227273, 1)
+colors = PackedColorArray(0, 1, 0.0999999, 1, 1, 1, 1, 1)
+
+[sub_resource type="GradientTexture2D" id="GradientTexture2D_c0jk6"]
+resource_local_to_scene = true
+gradient = SubResource("Gradient_c7cx1")
+width = 100
+height = 18
+
+[node name="EnemPuppet" type="Node2D" node_paths=PackedStringArray("_effectNode", "HealthBar", "Sprite", "_statusContainer")]
+script = ExtResource("1_e1x4p")
+_effectNode = NodePath("GlitchNode")
+HealthBar = NodePath("ProgressBar")
+Sprite = NodePath("Sprite")
+_statusContainer = NodePath("StatusContainer")
+
+[node name="StatusContainer" parent="." instance=ExtResource("2_t5538")]
+offset_top = -95.0
+offset_bottom = -59.0
+
+[node name="Sprite" type="Sprite2D" parent="."]
+position = Vector2(10, -12)
+texture = ExtResource("3_e1x4p")
+
+[node name="ProgressBar" parent="." instance=ExtResource("4_lmj2w")]
+offset_left = -50.0
+offset_top = 32.0
+offset_right = 50.0
+offset_bottom = 52.0
+texture_progress = SubResource("GradientTexture2D_c0jk6")
+
+[node name="GlitchNode" type="Node2D" parent="." node_paths=PackedStringArray("Sprite")]
+position = Vector2(10, 0)
+script = ExtResource("5_a0uir")
+Sprite = NodePath("Sprite2D")
+
+[node name="Sprite2D" type="Sprite2D" parent="GlitchNode"]
+position = Vector2(0, -12)
+texture = ExtResource("3_e1x4p")
diff --git a/Scenes/Puppets/Enemies/CyberFox/P_CyberFox.cs b/Scenes/Puppets/Enemies/CyberFox/P_CyberFox.cs
new file mode 100644
index 00000000..7e381731
--- /dev/null
+++ b/Scenes/Puppets/Enemies/CyberFox/P_CyberFox.cs
@@ -0,0 +1,47 @@
+using System;
+using FunkEngine;
+using Godot;
+
+public partial class P_CyberFox : EnemyPuppet
+{
+ public static new readonly string LoadPath =
+ "res://Scenes/Puppets/Enemies/CyberFox/CyberFox.tscn";
+
+ [Export]
+ private GlitchScript _effectNode;
+
+ public override void _Ready()
+ {
+ MaxHealth = 130;
+ CurrentHealth = MaxHealth;
+ BaseMoney = 5;
+ base._Ready();
+ var enemTween = CreateTween();
+ enemTween.TweenProperty(Sprite, "position", Vector2.Right * 10, 0.5f).AsRelative();
+ enemTween.TweenProperty(Sprite, "position", Vector2.Up * 5, 0.25f).AsRelative();
+ enemTween.TweenProperty(Sprite, "position", Vector2.Down * 5, 0.25f).AsRelative();
+ enemTween.TweenProperty(Sprite, "position", Vector2.Left * 10, 0.5f).AsRelative();
+ enemTween.TweenProperty(Sprite, "position", Vector2.Up * 5, 0.25f).AsRelative();
+ enemTween.TweenProperty(Sprite, "position", Vector2.Down * 5, 0.25f).AsRelative();
+ enemTween.TweenProperty(Sprite, "position", Vector2.Up * 5, 0.25f).AsRelative();
+ enemTween.TweenProperty(Sprite, "position", Vector2.Down * 5, 0.25f).AsRelative();
+ enemTween.SetTrans(Tween.TransitionType.Bounce);
+ enemTween.SetEase(Tween.EaseType.InOut);
+ enemTween.SetLoops();
+ enemTween.Play();
+
+ BattleEvents = new EnemyEffect[]
+ {
+ new EnemyEffect(
+ this,
+ BattleEffectTrigger.OnLoop,
+ 1,
+ (e, eff, val) =>
+ {
+ e.BD.AddStatus(Targetting.First, StatusEffect.Dodge, 1);
+ _effectNode.TriggerGlitch(1f);
+ }
+ ),
+ };
+ }
+}
diff --git a/Scenes/Puppets/Enemies/CyberFox/P_CyberFox.cs.uid b/Scenes/Puppets/Enemies/CyberFox/P_CyberFox.cs.uid
new file mode 100644
index 00000000..f2306bb6
--- /dev/null
+++ b/Scenes/Puppets/Enemies/CyberFox/P_CyberFox.cs.uid
@@ -0,0 +1 @@
+uid://dnkjrr1f5up7x
diff --git a/Scenes/Puppets/Enemies/Effigy/Effigy.tscn b/Scenes/Puppets/Enemies/Effigy/Effigy.tscn
new file mode 100644
index 00000000..9b32a36c
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Effigy/Effigy.tscn
@@ -0,0 +1,24 @@
+[gd_scene load_steps=5 format=3 uid="uid://djob0b8d65u44"]
+
+[ext_resource type="Script" uid="uid://bopwk08hbiuej" path="res://Scenes/Puppets/Enemies/Effigy/P_Effigy.cs" id="1_80cpv"]
+[ext_resource type="Texture2D" uid="uid://1uwfu07p38c6" path="res://Scenes/Puppets/Enemies/Strawman/Strawman.png" id="2_5xvmn"]
+[ext_resource type="PackedScene" uid="uid://bgomxovxs7sr8" path="res://Scenes/Puppets/HealthBar.tscn" id="3_j2tnq"]
+[ext_resource type="PackedScene" uid="uid://cdoguwlxehbpg" path="res://Scenes/Puppets/StatusContainer.tscn" id="4_akap3"]
+
+[node name="Strawman" type="Node2D" node_paths=PackedStringArray("HealthBar", "Sprite", "_statusContainer")]
+script = ExtResource("1_80cpv")
+HealthBar = NodePath("ProgressBar")
+Sprite = NodePath("Sprite")
+_statusContainer = NodePath("StatusContainer")
+
+[node name="Sprite" type="Sprite2D" parent="."]
+self_modulate = Color(0.190283, 0.000433802, 0.432638, 1)
+texture = ExtResource("2_5xvmn")
+
+[node name="ProgressBar" parent="." instance=ExtResource("3_j2tnq")]
+offset_left = -50.0
+offset_top = 32.0
+offset_right = 50.0
+offset_bottom = 52.0
+
+[node name="StatusContainer" parent="." instance=ExtResource("4_akap3")]
diff --git a/Scenes/Puppets/Enemies/Effigy/P_Effigy.cs b/Scenes/Puppets/Enemies/Effigy/P_Effigy.cs
new file mode 100644
index 00000000..6373e338
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Effigy/P_Effigy.cs
@@ -0,0 +1,74 @@
+using System;
+using FunkEngine;
+using Godot;
+
+public partial class P_Effigy : EnemyPuppet
+{
+ public static new readonly string LoadPath = "res://Scenes/Puppets/Enemies/Effigy/Effigy.tscn";
+ private static Toriel _tutorialInstance;
+
+ public override void _Ready()
+ {
+ MaxHealth = 124;
+ BaseMoney = 99;
+ CurrentHealth = MaxHealth;
+ base._Ready();
+
+ BattleEvents = new EnemyEffect[]
+ {
+ new EnemyEffect(
+ this,
+ BattleEffectTrigger.OnDamageInstance,
+ 1,
+ (e, eff, val) =>
+ {
+ if (e is not BattleDirector.Harbinger.OnDamageInstanceArgs dArgs)
+ return;
+ if (dArgs.Dmg.Target != this)
+ return;
+ dArgs.Dmg.ModifyDamage(-dArgs.Dmg.Damage + 1);
+ if (dArgs.Dmg.Source != null)
+ dArgs.Dmg.Source.TakeDamage(new DamageInstance(1, null, dArgs.Dmg.Source));
+ }
+ ),
+ new EnemyEffect(
+ this,
+ BattleEffectTrigger.OnBattleEnd,
+ 1,
+ (e, eff, val) =>
+ {
+ e.BD.DealDamage(Targetting.Player, e.BD.Player.GetCurrentHealth() - 1, null);
+ }
+ ),
+ new EnemyEffect(
+ this,
+ BattleEffectTrigger.OnBattleStart,
+ 1,
+ (e, eff, val) =>
+ {
+ _tutorialInstance = Toriel.AttachNewToriel(e.BD);
+ _tutorialInstance.BossDialogue();
+ }
+ ),
+ new EnemyEffect(
+ this,
+ BattleEffectTrigger.OnDamageInstance,
+ 2,
+ (e, eff, val) =>
+ {
+ if (e is not BattleDirector.Harbinger.OnDamageInstanceArgs dArgs || val != 2)
+ return;
+ if (
+ dArgs.Dmg.Target == dArgs.BD.Player
+ && dArgs.Dmg.Target.GetCurrentHealth() <= dArgs.Dmg.Damage
+ )
+ {
+ eff.Value = -1;
+ _tutorialInstance.FromBoss = true;
+ _tutorialInstance.OnPlaceDialogue3();
+ }
+ }
+ ),
+ };
+ }
+}
diff --git a/Scenes/Puppets/Enemies/Effigy/P_Effigy.cs.uid b/Scenes/Puppets/Enemies/Effigy/P_Effigy.cs.uid
new file mode 100644
index 00000000..dcc907db
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Effigy/P_Effigy.cs.uid
@@ -0,0 +1 @@
+uid://bopwk08hbiuej
diff --git a/Scenes/Puppets/Enemies/EnemyPuppet.cs b/Scenes/Puppets/Enemies/EnemyPuppet.cs
index c8b5b7d5..4a9d245d 100644
--- a/Scenes/Puppets/Enemies/EnemyPuppet.cs
+++ b/Scenes/Puppets/Enemies/EnemyPuppet.cs
@@ -3,6 +3,8 @@
public partial class EnemyPuppet : PuppetTemplate
{
protected EnemyEffect[] BattleEvents = Array.Empty();
+ public int BaseMoney { get; protected set; } = 0;
+ public (int NoteId, int Amount) InitialNote = (0, 0);
public virtual EnemyEffect[] GetBattleEvents()
{
diff --git a/Scenes/Puppets/Enemies/EnemyPuppet.tscn b/Scenes/Puppets/Enemies/EnemyPuppet.tscn
index fe97e6ba..24bea1af 100644
--- a/Scenes/Puppets/Enemies/EnemyPuppet.tscn
+++ b/Scenes/Puppets/Enemies/EnemyPuppet.tscn
@@ -1,9 +1,19 @@
-[gd_scene load_steps=4 format=3 uid="uid://cwm0n2wu851nx"]
+[gd_scene load_steps=6 format=3 uid="uid://cwm0n2wu851nx"]
[ext_resource type="Script" uid="uid://bnfo57c070cll" path="res://Scenes/Puppets/Scripts/PuppetTemplate.cs" id="1_kgmh0"]
[ext_resource type="PackedScene" uid="uid://bgomxovxs7sr8" path="res://Scenes/Puppets/HealthBar.tscn" id="1_sxlrs"]
[ext_resource type="PackedScene" uid="uid://cdoguwlxehbpg" path="res://Scenes/Puppets/StatusContainer.tscn" id="3_hguc7"]
+[sub_resource type="Gradient" id="Gradient_hguc7"]
+offsets = PackedFloat32Array(0.0227273, 1)
+colors = PackedColorArray(0, 1, 0.0999999, 1, 1, 1, 1, 1)
+
+[sub_resource type="GradientTexture2D" id="GradientTexture2D_545vi"]
+resource_local_to_scene = true
+gradient = SubResource("Gradient_hguc7")
+width = 100
+height = 18
+
[node name="EnemPuppet" type="Node2D" node_paths=PackedStringArray("HealthBar", "Sprite", "_statusContainer")]
script = ExtResource("1_kgmh0")
HealthBar = NodePath("ProgressBar")
@@ -15,7 +25,8 @@ _statusContainer = NodePath("StatusContainer")
[node name="ProgressBar" parent="." instance=ExtResource("1_sxlrs")]
offset_left = -50.0
offset_top = 32.0
-offset_right = 50.0
+offset_right = 52.0
offset_bottom = 52.0
+texture_progress = SubResource("GradientTexture2D_545vi")
[node name="StatusContainer" parent="." instance=ExtResource("3_hguc7")]
diff --git a/Scenes/Puppets/Enemies/Holograeme/HoloHand1.png b/Scenes/Puppets/Enemies/Holograeme/HoloHand1.png
new file mode 100644
index 00000000..1c0c9162
Binary files /dev/null and b/Scenes/Puppets/Enemies/Holograeme/HoloHand1.png differ
diff --git a/Scenes/Puppets/Enemies/Holograeme/HoloHand1.png.import b/Scenes/Puppets/Enemies/Holograeme/HoloHand1.png.import
new file mode 100644
index 00000000..db7c1a3e
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Holograeme/HoloHand1.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dwa70i6l80ic5"
+path="res://.godot/imported/HoloHand1.png-df061f591b9c17e526005a49442db885.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Scenes/Puppets/Enemies/Holograeme/HoloHand1.png"
+dest_files=["res://.godot/imported/HoloHand1.png-df061f591b9c17e526005a49442db885.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/Scenes/Puppets/Enemies/Holograeme/HoloHand2.png b/Scenes/Puppets/Enemies/Holograeme/HoloHand2.png
new file mode 100644
index 00000000..70e76798
Binary files /dev/null and b/Scenes/Puppets/Enemies/Holograeme/HoloHand2.png differ
diff --git a/Scenes/Puppets/Enemies/Holograeme/HoloHand2.png.import b/Scenes/Puppets/Enemies/Holograeme/HoloHand2.png.import
new file mode 100644
index 00000000..475e4d42
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Holograeme/HoloHand2.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://byr53yh51cxgo"
+path="res://.godot/imported/HoloHand2.png-cff4de3ca0da43eca9d3d1c17c93a5c9.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Scenes/Puppets/Enemies/Holograeme/HoloHand2.png"
+dest_files=["res://.godot/imported/HoloHand2.png-cff4de3ca0da43eca9d3d1c17c93a5c9.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/Scenes/Puppets/Enemies/Holograeme/Holo_HP_Over.png b/Scenes/Puppets/Enemies/Holograeme/Holo_HP_Over.png
new file mode 100644
index 00000000..d280aed3
Binary files /dev/null and b/Scenes/Puppets/Enemies/Holograeme/Holo_HP_Over.png differ
diff --git a/Scenes/Puppets/Enemies/Holograeme/Holo_HP_Over.png.import b/Scenes/Puppets/Enemies/Holograeme/Holo_HP_Over.png.import
new file mode 100644
index 00000000..d3b2e9d1
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Holograeme/Holo_HP_Over.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://d1khaeq3p5d1w"
+path="res://.godot/imported/Holo_HP_Over.png-6243a83bd7e71ff8f7c02fe8f96d9ede.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Scenes/Puppets/Enemies/Holograeme/Holo_HP_Over.png"
+dest_files=["res://.godot/imported/Holo_HP_Over.png-6243a83bd7e71ff8f7c02fe8f96d9ede.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/Scenes/Puppets/Enemies/Holograeme/Holo_HP_Under.png b/Scenes/Puppets/Enemies/Holograeme/Holo_HP_Under.png
new file mode 100644
index 00000000..763882c5
Binary files /dev/null and b/Scenes/Puppets/Enemies/Holograeme/Holo_HP_Under.png differ
diff --git a/Scenes/Puppets/Enemies/Holograeme/Holo_HP_Under.png.import b/Scenes/Puppets/Enemies/Holograeme/Holo_HP_Under.png.import
new file mode 100644
index 00000000..3ea8cdc9
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Holograeme/Holo_HP_Under.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bpi5ytgbhtkk1"
+path="res://.godot/imported/Holo_HP_Under.png-ccb1b65a43db73eefd44ca8673d7f46d.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Scenes/Puppets/Enemies/Holograeme/Holo_HP_Under.png"
+dest_files=["res://.godot/imported/Holo_HP_Under.png-ccb1b65a43db73eefd44ca8673d7f46d.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/Scenes/Puppets/Enemies/Holograeme/Holograeme.png b/Scenes/Puppets/Enemies/Holograeme/Holograeme.png
new file mode 100644
index 00000000..65da713d
Binary files /dev/null and b/Scenes/Puppets/Enemies/Holograeme/Holograeme.png differ
diff --git a/Scenes/Puppets/Enemies/Holograeme/Holograeme.png.import b/Scenes/Puppets/Enemies/Holograeme/Holograeme.png.import
new file mode 100644
index 00000000..937486a1
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Holograeme/Holograeme.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cjoky2yal24e3"
+path="res://.godot/imported/Holograeme.png-840f054774fe413c4cc449073ffdad1f.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Scenes/Puppets/Enemies/Holograeme/Holograeme.png"
+dest_files=["res://.godot/imported/Holograeme.png-840f054774fe413c4cc449073ffdad1f.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/Scenes/Puppets/Enemies/Holograeme/Holograeme.tscn b/Scenes/Puppets/Enemies/Holograeme/Holograeme.tscn
new file mode 100644
index 00000000..fb57ec00
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Holograeme/Holograeme.tscn
@@ -0,0 +1,57 @@
+[gd_scene load_steps=11 format=3 uid="uid://dfke16a27sgop"]
+
+[ext_resource type="Script" uid="uid://cbqev0wucp5gx" path="res://Scenes/Puppets/Enemies/Holograeme/P_Holograeme.cs" id="1_qkr3f"]
+[ext_resource type="Texture2D" uid="uid://cjoky2yal24e3" path="res://Scenes/Puppets/Enemies/Holograeme/Holograeme.png" id="2_dj5fa"]
+[ext_resource type="PackedScene" uid="uid://bgomxovxs7sr8" path="res://Scenes/Puppets/HealthBar.tscn" id="3_qkr3f"]
+[ext_resource type="PackedScene" uid="uid://cdoguwlxehbpg" path="res://Scenes/Puppets/StatusContainer.tscn" id="4_73js3"]
+[ext_resource type="Texture2D" uid="uid://bpi5ytgbhtkk1" path="res://Scenes/Puppets/Enemies/Holograeme/Holo_HP_Under.png" id="4_nx3as"]
+[ext_resource type="Texture2D" uid="uid://d1khaeq3p5d1w" path="res://Scenes/Puppets/Enemies/Holograeme/Holo_HP_Over.png" id="5_3wrsd"]
+[ext_resource type="Texture2D" uid="uid://dwa70i6l80ic5" path="res://Scenes/Puppets/Enemies/Holograeme/HoloHand1.png" id="5_qkr3f"]
+[ext_resource type="Texture2D" uid="uid://byr53yh51cxgo" path="res://Scenes/Puppets/Enemies/Holograeme/HoloHand2.png" id="6_73js3"]
+
+[sub_resource type="Gradient" id="Gradient_hguc7"]
+offsets = PackedFloat32Array(0.0227273, 1)
+colors = PackedColorArray(0, 1, 0.0999999, 1, 1, 1, 1, 1)
+
+[sub_resource type="GradientTexture2D" id="GradientTexture2D_545vi"]
+resource_local_to_scene = true
+gradient = SubResource("Gradient_hguc7")
+width = 22
+height = 18
+
+[node name="Holograeme" type="Node2D" node_paths=PackedStringArray("_whiteHand", "_redHand", "HealthBar", "Sprite", "_statusContainer")]
+script = ExtResource("1_qkr3f")
+_whiteHand = NodePath("Hand2Center")
+_redHand = NodePath("Hand1Center")
+HealthBar = NodePath("ProgressBar")
+Sprite = NodePath("Sprite")
+_statusContainer = NodePath("StatusContainer")
+
+[node name="Sprite" type="Sprite2D" parent="."]
+position = Vector2(0, -4)
+texture = ExtResource("2_dj5fa")
+
+[node name="ProgressBar" parent="." instance=ExtResource("3_qkr3f")]
+offset_left = -12.0
+offset_top = 32.0
+offset_right = 12.0
+offset_bottom = 52.0
+texture_under = ExtResource("4_nx3as")
+texture_over = ExtResource("5_3wrsd")
+texture_progress = SubResource("GradientTexture2D_545vi")
+
+[node name="StatusContainer" parent="." instance=ExtResource("4_73js3")]
+
+[node name="Hand1Center" type="Node2D" parent="."]
+rotation = 4.71239
+
+[node name="Hand1" type="Sprite2D" parent="Hand1Center"]
+position = Vector2(15, -1)
+texture = ExtResource("5_qkr3f")
+
+[node name="Hand2Center" type="Node2D" parent="."]
+rotation = 4.71239
+
+[node name="Hand2" type="Sprite2D" parent="Hand2Center"]
+position = Vector2(15, 1)
+texture = ExtResource("6_73js3")
diff --git a/Scenes/Puppets/Enemies/Holograeme/NoteCover.png b/Scenes/Puppets/Enemies/Holograeme/NoteCover.png
new file mode 100644
index 00000000..0554cd9c
Binary files /dev/null and b/Scenes/Puppets/Enemies/Holograeme/NoteCover.png differ
diff --git a/Scenes/Puppets/Enemies/Holograeme/NoteCover.png.import b/Scenes/Puppets/Enemies/Holograeme/NoteCover.png.import
new file mode 100644
index 00000000..b522056c
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Holograeme/NoteCover.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://crsy2cjimapi3"
+path="res://.godot/imported/NoteCover.png-dcbd3ca668ed3c02f0e46e8703b48bb6.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Scenes/Puppets/Enemies/Holograeme/NoteCover.png"
+dest_files=["res://.godot/imported/NoteCover.png-dcbd3ca668ed3c02f0e46e8703b48bb6.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/Scenes/Puppets/Enemies/Holograeme/P_Holograeme.cs b/Scenes/Puppets/Enemies/Holograeme/P_Holograeme.cs
new file mode 100644
index 00000000..7edc344d
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Holograeme/P_Holograeme.cs
@@ -0,0 +1,154 @@
+using FunkEngine;
+using Godot;
+
+public partial class P_Holograeme : EnemyPuppet
+{
+ public static new readonly string LoadPath =
+ "res://Scenes/Puppets/Enemies/Holograeme/Holograeme.tscn";
+
+ private readonly string NoteCoverPath = "res://Scenes/Puppets/Enemies/Holograeme/NoteCover.png";
+
+ [Export]
+ private Node2D _whiteHand;
+
+ [Export]
+ private Node2D _redHand;
+
+ public override void _ExitTree()
+ {
+ Scribe.NoteDictionary[0].Texture = null;
+ BattleDirector.AutoPlay = false;
+ BattleDirector.PlayerDisabled = false;
+ Conductor.BeatSpawnOffsetModifier = 0;
+ }
+
+ public override void _Ready()
+ {
+ Conductor.BeatSpawnOffsetModifier = 1;
+ MaxHealth = 3;
+ CurrentHealth = MaxHealth;
+ BaseMoney = 20;
+ base._Ready();
+
+ _hands[0] = _redHand;
+ _hands[1] = _whiteHand;
+
+ BattleEvents = new EnemyEffect[]
+ {
+ new EnemyEffect(
+ this,
+ BattleEffectTrigger.OnBattleStart,
+ -1,
+ (e, _, _) =>
+ {
+ BattleDirector.AutoPlay = true;
+ BattleDirector.PlayerDisabled = true;
+ e.BD.AddStatus(Targetting.Player, StatusEffect.Disable);
+ }
+ ),
+ new EnemyEffect(
+ this,
+ BattleEffectTrigger.OnLoop,
+ 1,
+ (e, _, _) =>
+ {
+ TweenLoop();
+ if (e is not BattleDirector.Harbinger.LoopEventArgs lArgs)
+ return;
+ if (lArgs.Loop % 2 == 0)
+ {
+ BattleDirector.AutoPlay = true;
+ BattleDirector.PlayerDisabled = true;
+ e.BD.AddStatus(Targetting.Player, StatusEffect.Disable);
+ Scribe.NoteDictionary[0].Texture = null;
+ }
+ else if (lArgs.Loop % 2 == 1)
+ {
+ BattleDirector.AutoPlay = false;
+ Scribe.NoteDictionary[0].Texture = GD.Load(NoteCoverPath);
+ }
+ }
+ ),
+ new EnemyEffect(
+ this,
+ BattleEffectTrigger.NoteHit,
+ 1,
+ (e, _, _) =>
+ {
+ if (e is BattleDirector.Harbinger.NoteHitArgs nArgs)
+ {
+ TweenDir(nArgs.Type);
+ }
+ }
+ ),
+ new EnemyEffect(
+ this,
+ BattleEffectTrigger.OnDamageInstance,
+ 3,
+ (e, eff, val) =>
+ {
+ if (
+ e is not BattleDirector.Harbinger.OnDamageInstanceArgs dArgs
+ || dArgs.Dmg.Target != eff.Owner
+ || dArgs.Dmg.Source != dArgs.BD.Player
+ )
+ return;
+ if (dArgs.Dmg.Damage < val)
+ {
+ dArgs.Dmg.ModifyDamage(0, 0);
+ }
+ }
+ ),
+ };
+ }
+
+ private Tween _curTween;
+
+ private void TweenLoop()
+ {
+ _curTween?.Stop();
+ _curTween = CreateTween();
+
+ _curTween.TweenProperty(_whiteHand, "rotation", _redHand.Rotation, .1f);
+ _curTween.TweenProperty(_whiteHand, "rotation", Mathf.DegToRad(-450) - 2 * Mathf.Pi, .4f);
+ _curTween
+ .Parallel()
+ .TweenProperty(_redHand, "rotation", Mathf.DegToRad(-450) - 2 * Mathf.Pi, .4f);
+ _curTween.TweenCallback(
+ Callable.From(() =>
+ {
+ _whiteHand.RotationDegrees = 270;
+ _redHand.RotationDegrees = 270;
+ })
+ );
+ }
+
+ private Node2D[] _hands = new Node2D[2];
+
+ private int[] _dirToAngle = [270, 450, 180, 360]; //ArrowType to angle in deg
+
+ private void TweenDir(ArrowType dir)
+ {
+ int handIdx = 0;
+ if (dir == ArrowType.Down || dir == ArrowType.Up)
+ handIdx = 1;
+
+ _curTween = CreateTween();
+
+ _curTween.TweenProperty(
+ _hands[handIdx],
+ "rotation",
+ Mathf.DegToRad(_dirToAngle[(int)dir]),
+ .1f
+ );
+ _curTween.TweenCallback(
+ Callable.From(() =>
+ {
+ int offset = 0;
+ if (_dirToAngle[(int)dir] >= 360)
+ offset = 360;
+ _hands[handIdx].RotationDegrees = _dirToAngle[(int)dir] - offset;
+ })
+ );
+ }
+}
diff --git a/Scenes/Puppets/Enemies/Holograeme/P_Holograeme.cs.uid b/Scenes/Puppets/Enemies/Holograeme/P_Holograeme.cs.uid
new file mode 100644
index 00000000..9d98e9de
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Holograeme/P_Holograeme.cs.uid
@@ -0,0 +1 @@
+uid://cbqev0wucp5gx
diff --git a/Scenes/Puppets/Enemies/Keythulu/Assets/Keythulu.png b/Scenes/Puppets/Enemies/Keythulu/Assets/Keythulu.png
new file mode 100644
index 00000000..56cde20b
Binary files /dev/null and b/Scenes/Puppets/Enemies/Keythulu/Assets/Keythulu.png differ
diff --git a/Scenes/Puppets/Enemies/Keythulu/Assets/Keythulu.png.import b/Scenes/Puppets/Enemies/Keythulu/Assets/Keythulu.png.import
new file mode 100644
index 00000000..079ffa63
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Keythulu/Assets/Keythulu.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://d4ix53yl5i18u"
+path="res://.godot/imported/Keythulu.png-91ef15a3e1500c3863fcd7a1fd3f9882.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Scenes/Puppets/Enemies/Keythulu/Assets/Keythulu.png"
+dest_files=["res://.godot/imported/Keythulu.png-91ef15a3e1500c3863fcd7a1fd3f9882.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/Scenes/Puppets/Enemies/Keythulu/Assets/KeythuluEffect.png b/Scenes/Puppets/Enemies/Keythulu/Assets/KeythuluEffect.png
new file mode 100644
index 00000000..0a0c8bd1
Binary files /dev/null and b/Scenes/Puppets/Enemies/Keythulu/Assets/KeythuluEffect.png differ
diff --git a/Scenes/Puppets/Enemies/Keythulu/Assets/KeythuluEffect.png.import b/Scenes/Puppets/Enemies/Keythulu/Assets/KeythuluEffect.png.import
new file mode 100644
index 00000000..0d435cc9
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Keythulu/Assets/KeythuluEffect.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bq27q7x2kslfx"
+path="res://.godot/imported/KeythuluEffect.png-cf4aa34c1555336ae11c131ad88c30c4.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Scenes/Puppets/Enemies/Keythulu/Assets/KeythuluEffect.png"
+dest_files=["res://.godot/imported/KeythuluEffect.png-cf4aa34c1555336ae11c131ad88c30c4.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/Scenes/Puppets/Enemies/Keythulu/Keythulu.tscn b/Scenes/Puppets/Enemies/Keythulu/Keythulu.tscn
new file mode 100644
index 00000000..768d800a
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Keythulu/Keythulu.tscn
@@ -0,0 +1,56 @@
+[gd_scene load_steps=8 format=3 uid="uid://fpivuc37bqvd"]
+
+[ext_resource type="Script" uid="uid://c3rur4tyhrbyq" path="res://Scenes/Puppets/Enemies/Keythulu/P_Keythulu.cs" id="1_ip2b3"]
+[ext_resource type="PackedScene" uid="uid://cdoguwlxehbpg" path="res://Scenes/Puppets/StatusContainer.tscn" id="2_vy4eo"]
+[ext_resource type="Texture2D" uid="uid://d4ix53yl5i18u" path="res://Scenes/Puppets/Enemies/Keythulu/Assets/Keythulu.png" id="3_ps44m"]
+[ext_resource type="PackedScene" uid="uid://bgomxovxs7sr8" path="res://Scenes/Puppets/HealthBar.tscn" id="4_8outj"]
+[ext_resource type="Texture2D" uid="uid://bq27q7x2kslfx" path="res://Scenes/Puppets/Enemies/Keythulu/Assets/KeythuluEffect.png" id="5_ps44m"]
+
+[sub_resource type="Gradient" id="Gradient_c7cx1"]
+offsets = PackedFloat32Array(0.0227273, 1)
+colors = PackedColorArray(0, 1, 0.0999999, 1, 1, 1, 1, 1)
+
+[sub_resource type="GradientTexture2D" id="GradientTexture2D_c0jk6"]
+resource_local_to_scene = true
+gradient = SubResource("Gradient_c7cx1")
+width = 100
+height = 18
+
+[node name="EnemPuppet" type="Node2D" node_paths=PackedStringArray("_effectSprite", "HealthBar", "Sprite", "_statusContainer")]
+script = ExtResource("1_ip2b3")
+_effectSprite = NodePath("NodeGroup")
+HealthBar = NodePath("ProgressBar")
+Sprite = NodePath("Sprite")
+_statusContainer = NodePath("StatusContainer")
+
+[node name="StatusContainer" parent="." instance=ExtResource("2_vy4eo")]
+offset_top = -126.0
+offset_bottom = -90.0
+
+[node name="Sprite" type="Sprite2D" parent="."]
+position = Vector2(0, -37)
+texture = ExtResource("3_ps44m")
+
+[node name="ProgressBar" parent="." instance=ExtResource("4_8outj")]
+offset_left = -50.0
+offset_top = 32.0
+offset_right = 50.0
+offset_bottom = 52.0
+texture_progress = SubResource("GradientTexture2D_c0jk6")
+
+[node name="NodeGroup" type="Node2D" parent="."]
+visible = false
+position = Vector2(-45, -22)
+
+[node name="Sprite2D" type="Sprite2D" parent="NodeGroup"]
+texture = ExtResource("5_ps44m")
+
+[node name="Sprite2D2" type="Sprite2D" parent="NodeGroup"]
+position = Vector2(15, 0)
+scale = Vector2(0.8, 0.8)
+texture = ExtResource("5_ps44m")
+
+[node name="Sprite2D3" type="Sprite2D" parent="NodeGroup"]
+position = Vector2(30, 0)
+scale = Vector2(0.6, 0.6)
+texture = ExtResource("5_ps44m")
diff --git a/Scenes/Puppets/Enemies/Keythulu/P_Keythulu.cs b/Scenes/Puppets/Enemies/Keythulu/P_Keythulu.cs
new file mode 100644
index 00000000..587c878d
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Keythulu/P_Keythulu.cs
@@ -0,0 +1,81 @@
+using System;
+using FunkEngine;
+using Godot;
+
+public partial class P_Keythulu : EnemyPuppet
+{
+ [Export]
+ private Node2D _effectSprite;
+
+ public static new readonly string LoadPath =
+ "res://Scenes/Puppets/Enemies/Keythulu/Keythulu.tscn";
+
+ public override void _Ready()
+ {
+ MaxHealth = 500;
+ CurrentHealth = MaxHealth;
+ BaseMoney = 50;
+ base._Ready();
+
+ _effectSprite.Visible = false;
+
+ var enemTween = CreateTween();
+ enemTween.TweenProperty(Sprite, "position", Vector2.Left * 10, 1f).AsRelative();
+ enemTween.TweenProperty(Sprite, "position", Vector2.Right * 10, 1f).AsRelative();
+ enemTween.SetTrans(Tween.TransitionType.Bounce);
+ enemTween.SetEase(Tween.EaseType.InOut);
+ enemTween.SetLoops();
+ enemTween.Play();
+
+ BattleEvents = new EnemyEffect[]
+ {
+ new EnemyEffect(
+ this,
+ BattleEffectTrigger.OnBattleStart,
+ 7,
+ (e, eff, val) =>
+ {
+ e.BD.AddStatus(Targetting.Player, StatusEffect.MindCrush, val);
+ }
+ ),
+ new EnemyEffect(
+ this,
+ BattleEffectTrigger.OnLoop,
+ 3,
+ (e, eff, val) =>
+ {
+ _effectSprite.Position = Vector2.Zero;
+ _effectSprite.Visible = true;
+ var effectTween = CreateTween();
+ effectTween
+ .TweenProperty(_effectSprite, "position", Vector2.Left * 2000, 6f)
+ .AsRelative();
+ effectTween.TweenCallback(
+ Callable.From(() =>
+ {
+ _effectSprite.Position = Vector2.Zero;
+ _effectSprite.Visible = false;
+ })
+ );
+ }
+ ),
+ new EnemyEffect(
+ this,
+ BattleEffectTrigger.OnDamageInstance,
+ 1,
+ (e, eff, val) =>
+ {
+ if (e is not BattleDirector.Harbinger.OnDamageInstanceArgs dArgs)
+ return;
+ if (
+ dArgs.Dmg.Target == this
+ && dArgs.Dmg.Target.GetCurrentHealth() <= dArgs.Dmg.Damage
+ )
+ {
+ SteamWhisperer.PopAchievement("actTwoComp");
+ }
+ }
+ ),
+ };
+ }
+}
diff --git a/Scenes/Puppets/Enemies/Keythulu/P_Keythulu.cs.uid b/Scenes/Puppets/Enemies/Keythulu/P_Keythulu.cs.uid
new file mode 100644
index 00000000..418a806e
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Keythulu/P_Keythulu.cs.uid
@@ -0,0 +1 @@
+uid://c3rur4tyhrbyq
diff --git a/Scenes/Puppets/Enemies/LWS/Assets/LWS.png b/Scenes/Puppets/Enemies/LWS/Assets/LWS.png
new file mode 100644
index 00000000..97670a48
Binary files /dev/null and b/Scenes/Puppets/Enemies/LWS/Assets/LWS.png differ
diff --git a/Scenes/Puppets/Enemies/LWS/Assets/LWS.png.import b/Scenes/Puppets/Enemies/LWS/Assets/LWS.png.import
new file mode 100644
index 00000000..e4507e5f
--- /dev/null
+++ b/Scenes/Puppets/Enemies/LWS/Assets/LWS.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://b1k6m2uj4o76x"
+path="res://.godot/imported/LWS.png-c3a231112640f9be6d6ffbac9146a500.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Scenes/Puppets/Enemies/LWS/Assets/LWS.png"
+dest_files=["res://.godot/imported/LWS.png-c3a231112640f9be6d6ffbac9146a500.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/Scenes/Puppets/Enemies/LWS/P_LWS.cs b/Scenes/Puppets/Enemies/LWS/P_LWS.cs
new file mode 100644
index 00000000..e02e0bd6
--- /dev/null
+++ b/Scenes/Puppets/Enemies/LWS/P_LWS.cs
@@ -0,0 +1,37 @@
+using System;
+using FunkEngine;
+using Godot;
+
+public partial class P_LWS : EnemyPuppet
+{
+ public static new readonly string LoadPath = "res://Scenes/Puppets/Enemies/LWS/P_LWS.tscn";
+
+ public override void _Ready()
+ {
+ MaxHealth = 80;
+ CurrentHealth = MaxHealth;
+ BaseMoney = 8;
+ InitialNote = (16, 3);
+ base._Ready();
+ var enemyTween = CreateTween();
+ enemyTween.TweenProperty(Sprite, "position", Vector2.Up * 5, 1f).AsRelative();
+ enemyTween.TweenProperty(Sprite, "position", Vector2.Down * 5, 1f).AsRelative();
+ enemyTween.SetTrans(Tween.TransitionType.Quad);
+ enemyTween.SetEase(Tween.EaseType.InOut);
+ enemyTween.SetLoops();
+ enemyTween.Play();
+
+ BattleEvents = new EnemyEffect[]
+ {
+ new EnemyEffect(
+ this,
+ BattleEffectTrigger.OnLoop,
+ 1,
+ (e, eff, val) =>
+ {
+ e.BD.RandApplyNote(eff.Owner, InitialNote.NoteId, val);
+ }
+ ),
+ };
+ }
+}
diff --git a/Scenes/Puppets/Enemies/LWS/P_LWS.cs.uid b/Scenes/Puppets/Enemies/LWS/P_LWS.cs.uid
new file mode 100644
index 00000000..6544e3b0
--- /dev/null
+++ b/Scenes/Puppets/Enemies/LWS/P_LWS.cs.uid
@@ -0,0 +1 @@
+uid://baudb5v4ai8br
diff --git a/Scenes/Puppets/Enemies/LWS/P_LWS.tscn b/Scenes/Puppets/Enemies/LWS/P_LWS.tscn
new file mode 100644
index 00000000..54667c7b
--- /dev/null
+++ b/Scenes/Puppets/Enemies/LWS/P_LWS.tscn
@@ -0,0 +1,34 @@
+[gd_scene load_steps=7 format=3 uid="uid://beww544cthrsj"]
+
+[ext_resource type="Script" uid="uid://baudb5v4ai8br" path="res://Scenes/Puppets/Enemies/LWS/P_LWS.cs" id="1_slsco"]
+[ext_resource type="Texture2D" uid="uid://b1k6m2uj4o76x" path="res://Scenes/Puppets/Enemies/LWS/Assets/LWS.png" id="2_iipdd"]
+[ext_resource type="PackedScene" uid="uid://bgomxovxs7sr8" path="res://Scenes/Puppets/HealthBar.tscn" id="3_3fwan"]
+[ext_resource type="PackedScene" uid="uid://cdoguwlxehbpg" path="res://Scenes/Puppets/StatusContainer.tscn" id="4_dslq0"]
+
+[sub_resource type="Gradient" id="Gradient_hguc7"]
+offsets = PackedFloat32Array(0.0227273, 1)
+colors = PackedColorArray(0, 1, 0.0999999, 1, 1, 1, 1, 1)
+
+[sub_resource type="GradientTexture2D" id="GradientTexture2D_545vi"]
+resource_local_to_scene = true
+gradient = SubResource("Gradient_hguc7")
+width = 100
+height = 18
+
+[node name="EnemPuppet" type="Node2D" node_paths=PackedStringArray("HealthBar", "Sprite", "_statusContainer")]
+script = ExtResource("1_slsco")
+HealthBar = NodePath("ProgressBar")
+Sprite = NodePath("Sprite")
+_statusContainer = NodePath("StatusContainer")
+
+[node name="Sprite" type="Sprite2D" parent="."]
+texture = ExtResource("2_iipdd")
+
+[node name="ProgressBar" parent="." instance=ExtResource("3_3fwan")]
+offset_left = -50.0
+offset_top = 32.0
+offset_right = 52.0
+offset_bottom = 52.0
+texture_progress = SubResource("GradientTexture2D_545vi")
+
+[node name="StatusContainer" parent="." instance=ExtResource("4_dslq0")]
diff --git a/Scenes/Puppets/Enemies/Mushroom/EliteMushroom.png b/Scenes/Puppets/Enemies/Mushroom/EliteMushroom.png
new file mode 100644
index 00000000..532ef4f9
Binary files /dev/null and b/Scenes/Puppets/Enemies/Mushroom/EliteMushroom.png differ
diff --git a/Scenes/Puppets/Enemies/Mushroom/EliteMushroom.png.import b/Scenes/Puppets/Enemies/Mushroom/EliteMushroom.png.import
new file mode 100644
index 00000000..8b08d23b
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Mushroom/EliteMushroom.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dnjo4sim07auo"
+path="res://.godot/imported/EliteMushroom.png-d9b17cc112a1ebeaf650b39d5d4e2d14.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Scenes/Puppets/Enemies/Mushroom/EliteMushroom.png"
+dest_files=["res://.godot/imported/EliteMushroom.png-d9b17cc112a1ebeaf650b39d5d4e2d14.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/Scenes/Puppets/Enemies/Mushroom/Mushroom.tscn b/Scenes/Puppets/Enemies/Mushroom/Mushroom.tscn
new file mode 100644
index 00000000..c0701fc9
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Mushroom/Mushroom.tscn
@@ -0,0 +1,40 @@
+[gd_scene load_steps=7 format=3 uid="uid://bmjhyq3se5hq5"]
+
+[ext_resource type="Script" uid="uid://qoaceev66ieq" path="res://Scenes/Puppets/Enemies/Mushroom/P_Mushroom.cs" id="1_mtres"]
+[ext_resource type="PackedScene" uid="uid://cdoguwlxehbpg" path="res://Scenes/Puppets/StatusContainer.tscn" id="2_ui84p"]
+[ext_resource type="Texture2D" uid="uid://dnjo4sim07auo" path="res://Scenes/Puppets/Enemies/Mushroom/EliteMushroom.png" id="3_mtres"]
+[ext_resource type="PackedScene" uid="uid://bgomxovxs7sr8" path="res://Scenes/Puppets/HealthBar.tscn" id="4_af0yh"]
+
+[sub_resource type="Gradient" id="Gradient_yw3bu"]
+resource_local_to_scene = true
+offsets = PackedFloat32Array(0.0227273, 1)
+colors = PackedColorArray(0, 1, 0.0999999, 1, 1, 1, 1, 1)
+
+[sub_resource type="GradientTexture2D" id="GradientTexture2D_ypp0w"]
+resource_local_to_scene = true
+gradient = SubResource("Gradient_yw3bu")
+width = 100
+height = 18
+
+[node name="EnemPuppet" type="Node2D" node_paths=PackedStringArray("HealthBar", "Sprite", "_statusContainer")]
+script = ExtResource("1_mtres")
+HealthBar = NodePath("ProgressBar")
+Sprite = NodePath("Sprite2D")
+_statusContainer = NodePath("StatusContainer")
+
+[node name="StatusContainer" parent="." instance=ExtResource("2_ui84p")]
+offset_left = -33.0
+offset_top = -118.0
+offset_right = 43.0
+offset_bottom = -82.0
+
+[node name="Sprite2D" type="Sprite2D" parent="."]
+position = Vector2(4, -22)
+texture = ExtResource("3_mtres")
+
+[node name="ProgressBar" parent="." instance=ExtResource("4_af0yh")]
+offset_left = -48.0
+offset_top = 31.0
+offset_right = 54.0
+offset_bottom = 51.0
+texture_progress = SubResource("GradientTexture2D_ypp0w")
diff --git a/Scenes/Puppets/Enemies/Mushroom/P_Mushroom.cs b/Scenes/Puppets/Enemies/Mushroom/P_Mushroom.cs
new file mode 100644
index 00000000..b8b3283a
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Mushroom/P_Mushroom.cs
@@ -0,0 +1,30 @@
+using System;
+using FunkEngine;
+using Godot;
+
+public partial class P_Mushroom : EnemyPuppet
+{
+ public static new readonly string LoadPath =
+ "res://Scenes/Puppets/Enemies/Mushroom/Mushroom.tscn";
+
+ public override void _Ready()
+ {
+ MaxHealth = 200;
+ CurrentHealth = MaxHealth;
+ BaseMoney = 10;
+ InitialNote = (17, 1);
+ base._Ready();
+ BattleEvents = new EnemyEffect[]
+ {
+ new EnemyEffect(
+ this,
+ BattleEffectTrigger.OnBattleStart,
+ 1,
+ (e, eff, _) =>
+ {
+ e.BD.RandApplyNote(eff.Owner, 17, 1);
+ }
+ ),
+ };
+ }
+}
diff --git a/Scenes/Puppets/Enemies/Mushroom/P_Mushroom.cs.uid b/Scenes/Puppets/Enemies/Mushroom/P_Mushroom.cs.uid
new file mode 100644
index 00000000..3089fa8e
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Mushroom/P_Mushroom.cs.uid
@@ -0,0 +1 @@
+uid://qoaceev66ieq
diff --git a/Scenes/Puppets/Enemies/Parasifly/P_Parasifly.cs b/Scenes/Puppets/Enemies/Parasifly/P_Parasifly.cs
index bd755093..cd26339a 100644
--- a/Scenes/Puppets/Enemies/Parasifly/P_Parasifly.cs
+++ b/Scenes/Puppets/Enemies/Parasifly/P_Parasifly.cs
@@ -1,4 +1,4 @@
-using System;
+using FunkEngine;
using Godot;
public partial class P_Parasifly : EnemyPuppet
@@ -8,8 +8,10 @@ public partial class P_Parasifly : EnemyPuppet
public override void _Ready()
{
- CurrentHealth = 50;
- MaxHealth = 50;
+ MaxHealth = 100;
+ CurrentHealth = MaxHealth;
+ BaseMoney = 5;
+ InitialNote = (13, 2);
base._Ready();
var enemTween = CreateTween();
enemTween.TweenProperty(Sprite, "position", Vector2.Down * 2, 2f).AsRelative();
@@ -18,5 +20,35 @@ public override void _Ready()
enemTween.SetEase(Tween.EaseType.In);
enemTween.SetLoops();
enemTween.Play();
+
+ BattleEvents = new EnemyEffect[]
+ {
+ new EnemyEffect(
+ this,
+ BattleEffectTrigger.OnBattleStart,
+ 1,
+ (e, eff, _) =>
+ {
+ e.BD.RandApplyNote(eff.Owner, 13, 1);
+ }
+ ),
+ new EnemyEffect(
+ this,
+ BattleEffectTrigger.OnDamageInstance,
+ 3,
+ (e, eff, val) =>
+ {
+ if (
+ val <= 0
+ || e is not BattleDirector.Harbinger.OnDamageInstanceArgs dArgs
+ || dArgs.Dmg.Target != eff.Owner
+ || dArgs.Dmg.Damage < dArgs.Dmg.Target.GetCurrentHealth()
+ )
+ return;
+ e.BD.AddStatus(Targetting.All, StatusEffect.Block, val);
+ eff.Value = 0;
+ }
+ ),
+ };
}
}
diff --git a/Scenes/Puppets/Enemies/Parasifly/Parasifly.tscn b/Scenes/Puppets/Enemies/Parasifly/Parasifly.tscn
index 7b2b873f..3d78fa39 100644
--- a/Scenes/Puppets/Enemies/Parasifly/Parasifly.tscn
+++ b/Scenes/Puppets/Enemies/Parasifly/Parasifly.tscn
@@ -1,10 +1,21 @@
-[gd_scene load_steps=5 format=3 uid="uid://uvlux4t6h5de"]
+[gd_scene load_steps=7 format=3 uid="uid://uvlux4t6h5de"]
[ext_resource type="Script" uid="uid://btaqgieybx0ep" path="res://Scenes/Puppets/Enemies/Parasifly/P_Parasifly.cs" id="1_ci2ca"]
[ext_resource type="PackedScene" uid="uid://cdoguwlxehbpg" path="res://Scenes/Puppets/StatusContainer.tscn" id="2_dq3sr"]
[ext_resource type="Texture2D" uid="uid://pngu3pw1pu4o" path="res://Scenes/Puppets/Enemies/Parasifly/Assets/Parasifly.png" id="2_g4o48"]
[ext_resource type="PackedScene" uid="uid://bgomxovxs7sr8" path="res://Scenes/Puppets/HealthBar.tscn" id="3_f74ri"]
+[sub_resource type="Gradient" id="Gradient_dq3sr"]
+resource_local_to_scene = true
+offsets = PackedFloat32Array(0.0227273, 1)
+colors = PackedColorArray(0, 1, 0.0999999, 1, 1, 1, 1, 1)
+
+[sub_resource type="GradientTexture2D" id="GradientTexture2D_eectw"]
+resource_local_to_scene = true
+gradient = SubResource("Gradient_dq3sr")
+width = 100
+height = 18
+
[node name="EnemPuppet" type="Node2D" node_paths=PackedStringArray("HealthBar", "Sprite", "_statusContainer")]
script = ExtResource("1_ci2ca")
HealthBar = NodePath("ProgressBar")
@@ -22,3 +33,4 @@ offset_left = -50.0
offset_top = 32.0
offset_right = 50.0
offset_bottom = 52.0
+texture_progress = SubResource("GradientTexture2D_eectw")
diff --git a/Scenes/Puppets/Enemies/Shapes/Assets/MidnightRiffShapeUpGuys.png b/Scenes/Puppets/Enemies/Shapes/Assets/MidnightRiffShapeUpGuys.png
new file mode 100644
index 00000000..07ebdd80
Binary files /dev/null and b/Scenes/Puppets/Enemies/Shapes/Assets/MidnightRiffShapeUpGuys.png differ
diff --git a/Scenes/Puppets/Enemies/Shapes/Assets/MidnightRiffShapeUpGuys.png.import b/Scenes/Puppets/Enemies/Shapes/Assets/MidnightRiffShapeUpGuys.png.import
new file mode 100644
index 00000000..6e918634
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Shapes/Assets/MidnightRiffShapeUpGuys.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bkxjkg3stb1e1"
+path="res://.godot/imported/MidnightRiffShapeUpGuys.png-a144f52eba4928b22f6cfb41082f7b4d.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Scenes/Puppets/Enemies/Shapes/Assets/MidnightRiffShapeUpGuys.png"
+dest_files=["res://.godot/imported/MidnightRiffShapeUpGuys.png-a144f52eba4928b22f6cfb41082f7b4d.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/Scenes/Puppets/Enemies/Shapes/P_Shapes.cs b/Scenes/Puppets/Enemies/Shapes/P_Shapes.cs
new file mode 100644
index 00000000..c3e75288
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Shapes/P_Shapes.cs
@@ -0,0 +1,23 @@
+using System;
+using FunkEngine;
+using Godot;
+
+public partial class P_Shapes : EnemyPuppet
+{
+ public static new readonly string LoadPath = "res://Scenes/Puppets/Enemies/Shapes/Shapes.tscn";
+
+ public override void _Ready()
+ {
+ MaxHealth = 150;
+ CurrentHealth = MaxHealth;
+ BaseMoney = 10;
+ base._Ready();
+ var enemTween = CreateTween();
+ enemTween.TweenProperty(Sprite, "position", Vector2.Right * 10, 3f).AsRelative();
+ enemTween.TweenProperty(Sprite, "position", Vector2.Left * 10, 3f).AsRelative();
+ enemTween.SetTrans(Tween.TransitionType.Quad);
+ enemTween.SetEase(Tween.EaseType.InOut);
+ enemTween.SetLoops();
+ enemTween.Play();
+ }
+}
diff --git a/Scenes/Puppets/Enemies/Shapes/P_Shapes.cs.uid b/Scenes/Puppets/Enemies/Shapes/P_Shapes.cs.uid
new file mode 100644
index 00000000..32a8cb35
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Shapes/P_Shapes.cs.uid
@@ -0,0 +1 @@
+uid://bcugmb2irxdvn
diff --git a/Scenes/Puppets/Enemies/Shapes/Shapes.tscn b/Scenes/Puppets/Enemies/Shapes/Shapes.tscn
new file mode 100644
index 00000000..9f72a28c
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Shapes/Shapes.tscn
@@ -0,0 +1,37 @@
+[gd_scene load_steps=7 format=3 uid="uid://dvdx2ijm3i2tl"]
+
+[ext_resource type="Script" uid="uid://bcugmb2irxdvn" path="res://Scenes/Puppets/Enemies/Shapes/P_Shapes.cs" id="1_82kly"]
+[ext_resource type="PackedScene" uid="uid://cdoguwlxehbpg" path="res://Scenes/Puppets/StatusContainer.tscn" id="2_sldik"]
+[ext_resource type="Texture2D" uid="uid://bkxjkg3stb1e1" path="res://Scenes/Puppets/Enemies/Shapes/Assets/MidnightRiffShapeUpGuys.png" id="3_82kly"]
+[ext_resource type="PackedScene" uid="uid://bgomxovxs7sr8" path="res://Scenes/Puppets/HealthBar.tscn" id="4_xblx4"]
+
+[sub_resource type="Gradient" id="Gradient_c7cx1"]
+offsets = PackedFloat32Array(0.0227273, 1)
+colors = PackedColorArray(0, 1, 0.0999999, 1, 1, 1, 1, 1)
+
+[sub_resource type="GradientTexture2D" id="GradientTexture2D_c0jk6"]
+resource_local_to_scene = true
+gradient = SubResource("Gradient_c7cx1")
+width = 100
+height = 18
+
+[node name="EnemPuppet" type="Node2D" node_paths=PackedStringArray("HealthBar", "Sprite", "_statusContainer")]
+script = ExtResource("1_82kly")
+HealthBar = NodePath("ProgressBar")
+Sprite = NodePath("Sprite")
+_statusContainer = NodePath("StatusContainer")
+
+[node name="StatusContainer" parent="." instance=ExtResource("2_sldik")]
+offset_top = -92.0
+offset_bottom = -56.0
+
+[node name="Sprite" type="Sprite2D" parent="."]
+position = Vector2(0, -11)
+texture = ExtResource("3_82kly")
+
+[node name="ProgressBar" parent="." instance=ExtResource("4_xblx4")]
+offset_left = -50.0
+offset_top = 32.0
+offset_right = 50.0
+offset_bottom = 52.0
+texture_progress = SubResource("GradientTexture2D_c0jk6")
diff --git a/Scenes/Puppets/Enemies/Spider/P_Spider.cs b/Scenes/Puppets/Enemies/Spider/P_Spider.cs
new file mode 100644
index 00000000..256684ad
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Spider/P_Spider.cs
@@ -0,0 +1,30 @@
+using System;
+using FunkEngine;
+using Godot;
+
+public partial class P_Spider : EnemyPuppet
+{
+ public static new readonly string LoadPath = "res://Scenes/Puppets/Enemies/Spider/Spider.tscn";
+
+ public override void _Ready()
+ {
+ MaxHealth = 100;
+ CurrentHealth = MaxHealth;
+ BaseMoney = 5;
+ InitialNote = (15, 2);
+ base._Ready();
+
+ BattleEvents = new EnemyEffect[]
+ {
+ new EnemyEffect(
+ this,
+ BattleEffectTrigger.OnBattleStart,
+ 1,
+ (e, eff, _) =>
+ {
+ e.BD.RandApplyNote(eff.Owner, 15, 1);
+ }
+ ),
+ };
+ }
+}
diff --git a/Scenes/Puppets/Enemies/Spider/P_Spider.cs.uid b/Scenes/Puppets/Enemies/Spider/P_Spider.cs.uid
new file mode 100644
index 00000000..5637c8d7
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Spider/P_Spider.cs.uid
@@ -0,0 +1 @@
+uid://0o44m0e5yxiy
diff --git a/Scenes/Puppets/Enemies/Spider/Spider.png b/Scenes/Puppets/Enemies/Spider/Spider.png
new file mode 100644
index 00000000..477f3d27
Binary files /dev/null and b/Scenes/Puppets/Enemies/Spider/Spider.png differ
diff --git a/Scenes/Puppets/Enemies/Spider/Spider.png.import b/Scenes/Puppets/Enemies/Spider/Spider.png.import
new file mode 100644
index 00000000..65433933
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Spider/Spider.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dvux16psycv0x"
+path="res://.godot/imported/Spider.png-451052b836bdeb9355c3d644c49f8d15.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Scenes/Puppets/Enemies/Spider/Spider.png"
+dest_files=["res://.godot/imported/Spider.png-451052b836bdeb9355c3d644c49f8d15.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/Scenes/Puppets/Enemies/Spider/Spider.tscn b/Scenes/Puppets/Enemies/Spider/Spider.tscn
new file mode 100644
index 00000000..29c347a5
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Spider/Spider.tscn
@@ -0,0 +1,40 @@
+[gd_scene load_steps=7 format=3 uid="uid://dpc74fpkkivg0"]
+
+[ext_resource type="Script" uid="uid://0o44m0e5yxiy" path="res://Scenes/Puppets/Enemies/Spider/P_Spider.cs" id="1_gyxko"]
+[ext_resource type="PackedScene" uid="uid://cdoguwlxehbpg" path="res://Scenes/Puppets/StatusContainer.tscn" id="2_xxbs3"]
+[ext_resource type="Texture2D" uid="uid://dvux16psycv0x" path="res://Scenes/Puppets/Enemies/Spider/Spider.png" id="3_jf83a"]
+[ext_resource type="PackedScene" uid="uid://bgomxovxs7sr8" path="res://Scenes/Puppets/HealthBar.tscn" id="4_vp5wi"]
+
+[sub_resource type="Gradient" id="Gradient_olxmf"]
+resource_local_to_scene = true
+offsets = PackedFloat32Array(0.0227273, 1)
+colors = PackedColorArray(0, 1, 0.0999999, 1, 1, 1, 1, 1)
+
+[sub_resource type="GradientTexture2D" id="GradientTexture2D_r5ep7"]
+resource_local_to_scene = true
+gradient = SubResource("Gradient_olxmf")
+width = 100
+height = 18
+
+[node name="EnemPuppet" type="Node2D" node_paths=PackedStringArray("HealthBar", "Sprite", "_statusContainer")]
+script = ExtResource("1_gyxko")
+HealthBar = NodePath("ProgressBar")
+Sprite = NodePath("Sprite2D")
+_statusContainer = NodePath("StatusContainer")
+
+[node name="StatusContainer" parent="." instance=ExtResource("2_xxbs3")]
+offset_left = -35.0
+offset_top = -56.0
+offset_right = 41.0
+offset_bottom = -20.0
+
+[node name="Sprite2D" type="Sprite2D" parent="."]
+position = Vector2(0, 6)
+texture = ExtResource("3_jf83a")
+
+[node name="ProgressBar" parent="." instance=ExtResource("4_vp5wi")]
+offset_left = -47.0
+offset_top = 31.0
+offset_right = 55.0
+offset_bottom = 51.0
+texture_progress = SubResource("GradientTexture2D_r5ep7")
diff --git a/Scenes/Puppets/Enemies/Squirkel/Assets/Squirkel.png b/Scenes/Puppets/Enemies/Squirkel/Assets/Squirkel.png
new file mode 100644
index 00000000..39909469
Binary files /dev/null and b/Scenes/Puppets/Enemies/Squirkel/Assets/Squirkel.png differ
diff --git a/Scenes/Puppets/Enemies/Squirkel/Assets/Squirkel.png.import b/Scenes/Puppets/Enemies/Squirkel/Assets/Squirkel.png.import
new file mode 100644
index 00000000..2b023366
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Squirkel/Assets/Squirkel.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://ccl36crr31ari"
+path="res://.godot/imported/Squirkel.png-702e3b5803efe3ad3f673217a9fb2a61.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Scenes/Puppets/Enemies/Squirkel/Assets/Squirkel.png"
+dest_files=["res://.godot/imported/Squirkel.png-702e3b5803efe3ad3f673217a9fb2a61.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/Scenes/Puppets/Enemies/Squirkel/P_Squirkel.cs b/Scenes/Puppets/Enemies/Squirkel/P_Squirkel.cs
new file mode 100644
index 00000000..8c6dbab7
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Squirkel/P_Squirkel.cs
@@ -0,0 +1,32 @@
+using System;
+using FunkEngine;
+using Godot;
+
+public partial class P_Squirkel : EnemyPuppet
+{
+ public static new readonly string LoadPath =
+ "res://Scenes/Puppets/Enemies/Squirkel/Squirkel.tscn";
+
+ public override void _Ready()
+ {
+ MaxHealth = 90;
+ CurrentHealth = MaxHealth;
+ BaseMoney = 5;
+ base._Ready();
+
+ var tween = CreateTween();
+ tween.TweenCallback(Callable.From(() => Sprite.FlipH = true));
+ tween.TweenProperty(Sprite, "position", Vector2.Right * 50, 0.5f).AsRelative();
+ tween.TweenCallback(Callable.From(() => Sprite.RotationDegrees = -90));
+ tween.TweenProperty(Sprite, "position", Vector2.Up * 50, 1f).AsRelative();
+ tween.TweenCallback(Callable.From(() => Sprite.FlipH = false));
+ tween.TweenCallback(Callable.From(() => Sprite.RotationDegrees = -90));
+ tween.TweenProperty(Sprite, "position", Vector2.Down * 50, 0.5f).AsRelative();
+ tween.TweenCallback(Callable.From(() => Sprite.RotationDegrees = 0));
+ tween.TweenProperty(Sprite, "position", Vector2.Left * 50, 0.5f).AsRelative();
+ tween.SetTrans(Tween.TransitionType.Bounce);
+ tween.SetEase(Tween.EaseType.InOut);
+ tween.SetLoops();
+ tween.Play();
+ }
+}
diff --git a/Scenes/Puppets/Enemies/Squirkel/P_Squirkel.cs.uid b/Scenes/Puppets/Enemies/Squirkel/P_Squirkel.cs.uid
new file mode 100644
index 00000000..d2701f50
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Squirkel/P_Squirkel.cs.uid
@@ -0,0 +1 @@
+uid://cykdlrr15ltna
diff --git a/Scenes/Puppets/Enemies/Squirkel/Squirkel.tscn b/Scenes/Puppets/Enemies/Squirkel/Squirkel.tscn
new file mode 100644
index 00000000..73995c80
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Squirkel/Squirkel.tscn
@@ -0,0 +1,36 @@
+[gd_scene load_steps=7 format=3 uid="uid://b5aw4qcsd24nq"]
+
+[ext_resource type="Script" uid="uid://cykdlrr15ltna" path="res://Scenes/Puppets/Enemies/Squirkel/P_Squirkel.cs" id="1_73ufr"]
+[ext_resource type="PackedScene" uid="uid://cdoguwlxehbpg" path="res://Scenes/Puppets/StatusContainer.tscn" id="2_ag8ic"]
+[ext_resource type="Texture2D" uid="uid://ccl36crr31ari" path="res://Scenes/Puppets/Enemies/Squirkel/Assets/Squirkel.png" id="3_73ufr"]
+[ext_resource type="PackedScene" uid="uid://bgomxovxs7sr8" path="res://Scenes/Puppets/HealthBar.tscn" id="4_w3fy1"]
+
+[sub_resource type="Gradient" id="Gradient_c7cx1"]
+offsets = PackedFloat32Array(0.0227273, 1)
+colors = PackedColorArray(0, 1, 0.0999999, 1, 1, 1, 1, 1)
+
+[sub_resource type="GradientTexture2D" id="GradientTexture2D_c0jk6"]
+resource_local_to_scene = true
+gradient = SubResource("Gradient_c7cx1")
+width = 100
+height = 18
+
+[node name="EnemPuppet" type="Node2D" node_paths=PackedStringArray("HealthBar", "Sprite", "_statusContainer")]
+script = ExtResource("1_73ufr")
+HealthBar = NodePath("ProgressBar")
+Sprite = NodePath("Sprite")
+_statusContainer = NodePath("StatusContainer")
+
+[node name="StatusContainer" parent="." instance=ExtResource("2_ag8ic")]
+offset_top = -62.0
+offset_bottom = -26.0
+
+[node name="Sprite" type="Sprite2D" parent="."]
+texture = ExtResource("3_73ufr")
+
+[node name="ProgressBar" parent="." instance=ExtResource("4_w3fy1")]
+offset_left = -50.0
+offset_top = 32.0
+offset_right = 50.0
+offset_bottom = 52.0
+texture_progress = SubResource("GradientTexture2D_c0jk6")
diff --git a/Scenes/Puppets/Enemies/Strawman/P_Strawman.cs b/Scenes/Puppets/Enemies/Strawman/P_Strawman.cs
new file mode 100644
index 00000000..564f9a08
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Strawman/P_Strawman.cs
@@ -0,0 +1,111 @@
+using System;
+using FunkEngine;
+using Godot;
+
+public partial class P_Strawman : EnemyPuppet
+{
+ public static new readonly string LoadPath =
+ "res://Scenes/Puppets/Enemies/Strawman/Strawman.tscn";
+
+ private static Toriel _tutorialInstance;
+
+ public override void _Ready()
+ {
+ CurrentHealth = 40;
+ MaxHealth = 40;
+ BaseMoney = 1;
+ base._Ready();
+
+ BattleEvents = new EnemyEffect[]
+ {
+ new EnemyEffect(
+ this,
+ BattleEffectTrigger.OnBattleStart,
+ 1,
+ (e, eff, val) =>
+ {
+ _tutorialInstance = Toriel.AttachNewToriel(e.BD);
+ _tutorialInstance.IntroDialogue();
+ }
+ ),
+ new EnemyEffect(
+ this,
+ BattleEffectTrigger.OnDamageInstance,
+ 2,
+ (e, eff, val) =>
+ {
+ if (e is not BattleDirector.Harbinger.OnDamageInstanceArgs dArgs)
+ return;
+ if (
+ dArgs.Dmg.Target == dArgs.BD.Player
+ && dArgs.Dmg.Target.GetCurrentHealth() <= dArgs.Dmg.Damage + 1
+ )
+ {
+ dArgs.Dmg.Target.Heal(999);
+ if (eff.Value == 0)
+ return;
+ _tutorialInstance.NoDying();
+ eff.Value--;
+ }
+ }
+ ),
+ new EnemyEffect(
+ this,
+ BattleEffectTrigger.OnLoop,
+ 1,
+ (e, eff, val) =>
+ {
+ if (e is not BattleDirector.Harbinger.LoopEventArgs lArgs)
+ return;
+ if (lArgs.Loop == 1)
+ {
+ _tutorialInstance.LoopDialogue();
+ }
+ }
+ ),
+ new EnemyEffect(
+ this,
+ BattleEffectTrigger.NoteHit,
+ 1,
+ (e, eff, val) =>
+ {
+ if (eff.Value == 0)
+ return;
+ if (e is not BattleDirector.Harbinger.NoteHitArgs nArgs)
+ return;
+ if (!nArgs.BD.NPB.CanPlaceNote() || TimeKeeper.LastBeat.Loop < 1)
+ return;
+ eff.Value = 0;
+ _tutorialInstance.PlaceDialogue1();
+ }
+ ),
+ new EnemyEffect(
+ this,
+ BattleEffectTrigger.NotePlaced,
+ 1,
+ (e, eff, val) =>
+ {
+ _tutorialInstance.CallDeferred(nameof(_tutorialInstance.OnPlaceDialogue1));
+ }
+ ),
+ new EnemyEffect(
+ this,
+ BattleEffectTrigger.OnDamageInstance,
+ 1,
+ (e, eff, val) =>
+ {
+ if (e is not BattleDirector.Harbinger.OnDamageInstanceArgs dArgs)
+ return;
+ if (
+ dArgs.Dmg.Target == this
+ && dArgs.Dmg.Target.GetCurrentHealth() <= dArgs.Dmg.Damage
+ )
+ {
+ SaveSystem.UpdateConfig(SaveSystem.ConfigSettings.FirstTime, false);
+ SteamWhisperer.PopAchievement("tutorial");
+ }
+ }
+ ),
+ };
+ }
+}
diff --git a/Scenes/Puppets/Enemies/Strawman/P_Strawman.cs.uid b/Scenes/Puppets/Enemies/Strawman/P_Strawman.cs.uid
new file mode 100644
index 00000000..c0db8633
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Strawman/P_Strawman.cs.uid
@@ -0,0 +1 @@
+uid://cd3rrwk2hhkux
diff --git a/Scenes/Puppets/Enemies/Strawman/Strawman.png b/Scenes/Puppets/Enemies/Strawman/Strawman.png
new file mode 100644
index 00000000..4fa29a06
Binary files /dev/null and b/Scenes/Puppets/Enemies/Strawman/Strawman.png differ
diff --git a/Scenes/Puppets/Enemies/Strawman/Strawman.png.import b/Scenes/Puppets/Enemies/Strawman/Strawman.png.import
new file mode 100644
index 00000000..86b5e995
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Strawman/Strawman.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://1uwfu07p38c6"
+path="res://.godot/imported/Strawman.png-45d47585ab4c69863f411f8c0ec14e04.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Scenes/Puppets/Enemies/Strawman/Strawman.png"
+dest_files=["res://.godot/imported/Strawman.png-45d47585ab4c69863f411f8c0ec14e04.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/Scenes/Puppets/Enemies/Strawman/Strawman.tscn b/Scenes/Puppets/Enemies/Strawman/Strawman.tscn
new file mode 100644
index 00000000..dbbd0579
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Strawman/Strawman.tscn
@@ -0,0 +1,35 @@
+[gd_scene load_steps=7 format=3 uid="uid://dh3a7hyhlukgx"]
+
+[ext_resource type="Script" uid="uid://cd3rrwk2hhkux" path="res://Scenes/Puppets/Enemies/Strawman/P_Strawman.cs" id="1_8sxmx"]
+[ext_resource type="Texture2D" uid="uid://1uwfu07p38c6" path="res://Scenes/Puppets/Enemies/Strawman/Strawman.png" id="2_451oy"]
+[ext_resource type="PackedScene" uid="uid://bgomxovxs7sr8" path="res://Scenes/Puppets/HealthBar.tscn" id="3_a3xgy"]
+[ext_resource type="PackedScene" uid="uid://cdoguwlxehbpg" path="res://Scenes/Puppets/StatusContainer.tscn" id="4_bktfx"]
+
+[sub_resource type="Gradient" id="Gradient_8sxmx"]
+resource_local_to_scene = true
+offsets = PackedFloat32Array(0.0227273, 1)
+colors = PackedColorArray(0, 1, 0.0999999, 1, 1, 1, 1, 1)
+
+[sub_resource type="GradientTexture2D" id="GradientTexture2D_451oy"]
+resource_local_to_scene = true
+gradient = SubResource("Gradient_8sxmx")
+width = 100
+height = 18
+
+[node name="Strawman" type="Node2D" node_paths=PackedStringArray("HealthBar", "Sprite", "_statusContainer")]
+script = ExtResource("1_8sxmx")
+HealthBar = NodePath("ProgressBar")
+Sprite = NodePath("Sprite")
+_statusContainer = NodePath("StatusContainer")
+
+[node name="Sprite" type="Sprite2D" parent="."]
+texture = ExtResource("2_451oy")
+
+[node name="ProgressBar" parent="." instance=ExtResource("3_a3xgy")]
+offset_left = -50.0
+offset_top = 32.0
+offset_right = 50.0
+offset_bottom = 52.0
+texture_progress = SubResource("GradientTexture2D_451oy")
+
+[node name="StatusContainer" parent="." instance=ExtResource("4_bktfx")]
diff --git a/Scenes/Puppets/Enemies/TheGWS/GWS.tscn b/Scenes/Puppets/Enemies/TheGWS/GWS.tscn
index c77cac57..b71d0a0d 100644
--- a/Scenes/Puppets/Enemies/TheGWS/GWS.tscn
+++ b/Scenes/Puppets/Enemies/TheGWS/GWS.tscn
@@ -1,10 +1,20 @@
-[gd_scene load_steps=5 format=3 uid="uid://d1puw6fvmkrb5"]
+[gd_scene load_steps=7 format=3 uid="uid://d1puw6fvmkrb5"]
[ext_resource type="Script" uid="uid://3axgcdtdevtx" path="res://Scenes/Puppets/Enemies/TheGWS/P_TheGWS.cs" id="1_dlike"]
[ext_resource type="Texture2D" uid="uid://ci0a2h2eatjht" path="res://Scenes/Puppets/Enemies/TheGWS/Assets/GhostWolfSnake.png" id="2_77v4w"]
[ext_resource type="PackedScene" uid="uid://cdoguwlxehbpg" path="res://Scenes/Puppets/StatusContainer.tscn" id="2_c7cx1"]
[ext_resource type="PackedScene" uid="uid://bgomxovxs7sr8" path="res://Scenes/Puppets/HealthBar.tscn" id="3_mr0it"]
+[sub_resource type="Gradient" id="Gradient_c7cx1"]
+offsets = PackedFloat32Array(0.0227273, 1)
+colors = PackedColorArray(0, 1, 0.0999999, 1, 1, 1, 1, 1)
+
+[sub_resource type="GradientTexture2D" id="GradientTexture2D_c0jk6"]
+resource_local_to_scene = true
+gradient = SubResource("Gradient_c7cx1")
+width = 100
+height = 18
+
[node name="EnemPuppet" type="Node2D" node_paths=PackedStringArray("HealthBar", "Sprite", "_statusContainer")]
script = ExtResource("1_dlike")
HealthBar = NodePath("ProgressBar")
@@ -24,3 +34,4 @@ offset_left = -50.0
offset_top = 32.0
offset_right = 50.0
offset_bottom = 52.0
+texture_progress = SubResource("GradientTexture2D_c0jk6")
diff --git a/Scenes/Puppets/Enemies/TheGWS/P_TheGWS.cs b/Scenes/Puppets/Enemies/TheGWS/P_TheGWS.cs
index f720ce0c..ebd3d242 100644
--- a/Scenes/Puppets/Enemies/TheGWS/P_TheGWS.cs
+++ b/Scenes/Puppets/Enemies/TheGWS/P_TheGWS.cs
@@ -1,4 +1,5 @@
using System;
+using FunkEngine;
using Godot;
public partial class P_TheGWS : EnemyPuppet
@@ -7,8 +8,10 @@ public partial class P_TheGWS : EnemyPuppet
public override void _Ready()
{
- CurrentHealth = 75;
- MaxHealth = 75;
+ MaxHealth = 150;
+ CurrentHealth = MaxHealth;
+ BaseMoney = 10;
+ InitialNote = (10, 7);
base._Ready();
var enemTween = CreateTween();
enemTween.TweenProperty(Sprite, "position", Vector2.Down * 10, 3f).AsRelative();
@@ -17,5 +20,42 @@ public override void _Ready()
enemTween.SetEase(Tween.EaseType.InOut);
enemTween.SetLoops();
enemTween.Play();
+
+ BattleEvents = new EnemyEffect[]
+ {
+ new EnemyEffect(
+ this,
+ BattleEffectTrigger.OnLoop,
+ 1,
+ (e, eff, val) =>
+ {
+ e.BD.RandApplyNote(eff.Owner, 10, 2);
+ if (val == 0)
+ return;
+ e.BD.EnemyAddNote(
+ ArrowType.Down,
+ new Beat(37),
+ Scribe.NoteDictionary[10].Clone(),
+ 0,
+ eff.Owner
+ );
+ e.BD.EnemyAddNote(
+ ArrowType.Left,
+ new Beat(51),
+ Scribe.NoteDictionary[10].Clone(),
+ 0,
+ eff.Owner
+ );
+ e.BD.EnemyAddNote(
+ ArrowType.Right,
+ new Beat(59),
+ Scribe.NoteDictionary[10].Clone(),
+ 0,
+ eff.Owner
+ );
+ eff.Value = 0;
+ }
+ ),
+ };
}
}
diff --git a/Scenes/Puppets/Enemies/TheGobbler/Assets/MR_Goblin_Sprite_Shades.png b/Scenes/Puppets/Enemies/TheGobbler/Assets/MR_Goblin_Sprite_Shades.png
new file mode 100644
index 00000000..7bd0cbed
Binary files /dev/null and b/Scenes/Puppets/Enemies/TheGobbler/Assets/MR_Goblin_Sprite_Shades.png differ
diff --git a/Scenes/Puppets/Enemies/TheGobbler/Assets/MR_Goblin_Sprite_Shades.png.import b/Scenes/Puppets/Enemies/TheGobbler/Assets/MR_Goblin_Sprite_Shades.png.import
new file mode 100644
index 00000000..f60a5ae6
--- /dev/null
+++ b/Scenes/Puppets/Enemies/TheGobbler/Assets/MR_Goblin_Sprite_Shades.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dfkn3p2tau82f"
+path="res://.godot/imported/MR_Goblin_Sprite_Shades.png-b9682b7cf0e2e69441e78c7d8a1d5a37.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Scenes/Puppets/Enemies/TheGobbler/Assets/MR_Goblin_Sprite_Shades.png"
+dest_files=["res://.godot/imported/MR_Goblin_Sprite_Shades.png-b9682b7cf0e2e69441e78c7d8a1d5a37.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/Scenes/Puppets/Enemies/TheGobbler/P_Gobbler.cs b/Scenes/Puppets/Enemies/TheGobbler/P_Gobbler.cs
new file mode 100644
index 00000000..a0fa417d
--- /dev/null
+++ b/Scenes/Puppets/Enemies/TheGobbler/P_Gobbler.cs
@@ -0,0 +1,24 @@
+using System;
+using FunkEngine;
+using Godot;
+
+public partial class P_Gobbler : EnemyPuppet
+{
+ public static new readonly string LoadPath =
+ "res://Scenes/Puppets/Enemies/TheGobbler/TheGobbler.tscn";
+
+ public override void _Ready()
+ {
+ MaxHealth = 150;
+ CurrentHealth = MaxHealth;
+ BaseMoney = 10;
+ base._Ready();
+ var enemTween = CreateTween();
+ enemTween.TweenProperty(Sprite, "position", Vector2.Right * 10, 3f).AsRelative();
+ enemTween.TweenProperty(Sprite, "position", Vector2.Left * 10, 3f).AsRelative();
+ enemTween.SetTrans(Tween.TransitionType.Quad);
+ enemTween.SetEase(Tween.EaseType.InOut);
+ enemTween.SetLoops();
+ enemTween.Play();
+ }
+}
diff --git a/Scenes/Puppets/Enemies/TheGobbler/P_Gobbler.cs.uid b/Scenes/Puppets/Enemies/TheGobbler/P_Gobbler.cs.uid
new file mode 100644
index 00000000..7bcfc433
--- /dev/null
+++ b/Scenes/Puppets/Enemies/TheGobbler/P_Gobbler.cs.uid
@@ -0,0 +1 @@
+uid://do0pm6uirfocn
diff --git a/Scenes/Puppets/Enemies/TheGobbler/TheGobbler.tscn b/Scenes/Puppets/Enemies/TheGobbler/TheGobbler.tscn
new file mode 100644
index 00000000..a498e3f9
--- /dev/null
+++ b/Scenes/Puppets/Enemies/TheGobbler/TheGobbler.tscn
@@ -0,0 +1,37 @@
+[gd_scene load_steps=7 format=3 uid="uid://dmogwhwtt0xpv"]
+
+[ext_resource type="Script" uid="uid://do0pm6uirfocn" path="res://Scenes/Puppets/Enemies/TheGobbler/P_Gobbler.cs" id="1_1p2br"]
+[ext_resource type="PackedScene" uid="uid://cdoguwlxehbpg" path="res://Scenes/Puppets/StatusContainer.tscn" id="2_ba2r6"]
+[ext_resource type="Texture2D" uid="uid://dfkn3p2tau82f" path="res://Scenes/Puppets/Enemies/TheGobbler/Assets/MR_Goblin_Sprite_Shades.png" id="3_1p2br"]
+[ext_resource type="PackedScene" uid="uid://bgomxovxs7sr8" path="res://Scenes/Puppets/HealthBar.tscn" id="4_sbehl"]
+
+[sub_resource type="Gradient" id="Gradient_c7cx1"]
+offsets = PackedFloat32Array(0.0227273, 1)
+colors = PackedColorArray(0, 1, 0.0999999, 1, 1, 1, 1, 1)
+
+[sub_resource type="GradientTexture2D" id="GradientTexture2D_c0jk6"]
+resource_local_to_scene = true
+gradient = SubResource("Gradient_c7cx1")
+width = 100
+height = 18
+
+[node name="EnemPuppet" type="Node2D" node_paths=PackedStringArray("HealthBar", "Sprite", "_statusContainer")]
+script = ExtResource("1_1p2br")
+HealthBar = NodePath("ProgressBar")
+Sprite = NodePath("Sprite")
+_statusContainer = NodePath("StatusContainer")
+
+[node name="StatusContainer" parent="." instance=ExtResource("2_ba2r6")]
+offset_top = -67.0
+offset_bottom = -31.0
+
+[node name="Sprite" type="Sprite2D" parent="."]
+position = Vector2(0, -2)
+texture = ExtResource("3_1p2br")
+
+[node name="ProgressBar" parent="." instance=ExtResource("4_sbehl")]
+offset_left = -50.0
+offset_top = 32.0
+offset_right = 50.0
+offset_bottom = 52.0
+texture_progress = SubResource("GradientTexture2D_c0jk6")
diff --git a/Scenes/Puppets/Enemies/Turtle/Assets/Turtle.png b/Scenes/Puppets/Enemies/Turtle/Assets/Turtle.png
new file mode 100644
index 00000000..c7727f6a
Binary files /dev/null and b/Scenes/Puppets/Enemies/Turtle/Assets/Turtle.png differ
diff --git a/Scenes/Puppets/Enemies/Turtle/Assets/Turtle.png.import b/Scenes/Puppets/Enemies/Turtle/Assets/Turtle.png.import
new file mode 100644
index 00000000..d758aaa3
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Turtle/Assets/Turtle.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://2fp64bbbn4qg"
+path="res://.godot/imported/Turtle.png-6a9a5eac0ecfd652d2b5c36de6cf7cf3.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Scenes/Puppets/Enemies/Turtle/Assets/Turtle.png"
+dest_files=["res://.godot/imported/Turtle.png-6a9a5eac0ecfd652d2b5c36de6cf7cf3.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/Scenes/Puppets/Enemies/Turtle/P_Turtle.cs b/Scenes/Puppets/Enemies/Turtle/P_Turtle.cs
new file mode 100644
index 00000000..5b25cc85
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Turtle/P_Turtle.cs
@@ -0,0 +1,42 @@
+using System;
+using FunkEngine;
+using Godot;
+
+public partial class P_Turtle : EnemyPuppet
+{
+ public static new readonly string LoadPath = "res://Scenes/Puppets/Enemies/Turtle/Turtle.tscn";
+
+ public override void _Ready()
+ {
+ MaxHealth = 150;
+ CurrentHealth = MaxHealth;
+ BaseMoney = 10;
+ base._Ready();
+ var enemTween = CreateTween();
+ enemTween.TweenProperty(Sprite, "position", Vector2.Right * 10, 3f).AsRelative();
+ enemTween.TweenProperty(Sprite, "position", Vector2.Left * 10, 3f).AsRelative();
+ enemTween.SetTrans(Tween.TransitionType.Quad);
+ enemTween.SetEase(Tween.EaseType.InOut);
+ enemTween.SetLoops();
+ enemTween.Play();
+
+ BattleEvents = new EnemyEffect[]
+ {
+ new EnemyEffect(
+ this,
+ BattleEffectTrigger.OnLoop,
+ 1,
+ (e, eff, val) =>
+ {
+ // take 1/4th of player's energy, and heal that amount
+ int quarterEnergy = (int)e.BD.NPB.GetCurrentBarValue() / 4;
+ e.BD.NPB.IncreaseCharge(-quarterEnergy);
+ this.Heal(quarterEnergy);
+
+ //gain block based on val
+ e.BD.AddStatus(Targetting.First, StatusEffect.Block, val);
+ }
+ ),
+ };
+ }
+}
diff --git a/Scenes/Puppets/Enemies/Turtle/P_Turtle.cs.uid b/Scenes/Puppets/Enemies/Turtle/P_Turtle.cs.uid
new file mode 100644
index 00000000..06b09283
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Turtle/P_Turtle.cs.uid
@@ -0,0 +1 @@
+uid://ki3c7ra3rco5
diff --git a/Scenes/Puppets/Enemies/Turtle/Turtle.tscn b/Scenes/Puppets/Enemies/Turtle/Turtle.tscn
new file mode 100644
index 00000000..2eaf7199
--- /dev/null
+++ b/Scenes/Puppets/Enemies/Turtle/Turtle.tscn
@@ -0,0 +1,37 @@
+[gd_scene load_steps=7 format=3 uid="uid://dcouc8w63l4tu"]
+
+[ext_resource type="Script" uid="uid://ki3c7ra3rco5" path="res://Scenes/Puppets/Enemies/Turtle/P_Turtle.cs" id="1_8ghls"]
+[ext_resource type="PackedScene" uid="uid://cdoguwlxehbpg" path="res://Scenes/Puppets/StatusContainer.tscn" id="2_12ph0"]
+[ext_resource type="Texture2D" uid="uid://2fp64bbbn4qg" path="res://Scenes/Puppets/Enemies/Turtle/Assets/Turtle.png" id="3_sjk2o"]
+[ext_resource type="PackedScene" uid="uid://bgomxovxs7sr8" path="res://Scenes/Puppets/HealthBar.tscn" id="4_tpaud"]
+
+[sub_resource type="Gradient" id="Gradient_c7cx1"]
+offsets = PackedFloat32Array(0.0227273, 1)
+colors = PackedColorArray(0, 1, 0.0999999, 1, 1, 1, 1, 1)
+
+[sub_resource type="GradientTexture2D" id="GradientTexture2D_c0jk6"]
+resource_local_to_scene = true
+gradient = SubResource("Gradient_c7cx1")
+width = 100
+height = 18
+
+[node name="EnemPuppet" type="Node2D" node_paths=PackedStringArray("HealthBar", "Sprite", "_statusContainer")]
+script = ExtResource("1_8ghls")
+HealthBar = NodePath("ProgressBar")
+Sprite = NodePath("Sprite")
+_statusContainer = NodePath("StatusContainer")
+
+[node name="StatusContainer" parent="." instance=ExtResource("2_12ph0")]
+offset_top = -80.0
+offset_bottom = -44.0
+
+[node name="Sprite" type="Sprite2D" parent="."]
+position = Vector2(0, -4)
+texture = ExtResource("3_sjk2o")
+
+[node name="ProgressBar" parent="." instance=ExtResource("4_tpaud")]
+offset_left = -50.0
+offset_top = 32.0
+offset_right = 50.0
+offset_bottom = 52.0
+texture_progress = SubResource("GradientTexture2D_c0jk6")
diff --git a/Scenes/Puppets/HealthBar.tscn b/Scenes/Puppets/HealthBar.tscn
index aafee228..3e1ea3cb 100644
--- a/Scenes/Puppets/HealthBar.tscn
+++ b/Scenes/Puppets/HealthBar.tscn
@@ -1,27 +1,26 @@
[gd_scene load_steps=6 format=3 uid="uid://bgomxovxs7sr8"]
[ext_resource type="Script" uid="uid://d24uqauywe5j5" path="res://Scenes/Puppets/Scripts/HealthBar.cs" id="1_b1t4i"]
+[ext_resource type="Texture2D" uid="uid://0whvo6xa10it" path="res://Scenes/Puppets/HealthBar_Under.png" id="1_qp5i6"]
+[ext_resource type="Texture2D" uid="uid://btia5s3c7owi1" path="res://Scenes/Puppets/HealthBar_Over.png" id="2_r2mkj"]
-[sub_resource type="Gradient" id="Gradient_ve5ki"]
-colors = PackedColorArray(0, 0, 0, 1, 0, 0, 0, 1)
-
-[sub_resource type="GradientTexture2D" id="GradientTexture2D_ti0cv"]
-gradient = SubResource("Gradient_ve5ki")
-width = 100
-height = 20
-
-[sub_resource type="Gradient" id="Gradient_soqhm"]
+[sub_resource type="Gradient" id="Gradient_qp5i6"]
+resource_local_to_scene = true
+offsets = PackedFloat32Array(0.0227273, 1)
colors = PackedColorArray(0, 1, 0.0999999, 1, 1, 1, 1, 1)
-[sub_resource type="GradientTexture2D" id="GradientTexture2D_r4hau"]
-gradient = SubResource("Gradient_soqhm")
-width = 96
-height = 16
+[sub_resource type="GradientTexture2D" id="GradientTexture2D_r2mkj"]
+resource_local_to_scene = true
+gradient = SubResource("Gradient_qp5i6")
+width = 100
+height = 18
[node name="ProgressBar" type="TextureProgressBar"]
offset_right = 100.0
offset_bottom = 20.0
-texture_under = SubResource("GradientTexture2D_ti0cv")
-texture_progress = SubResource("GradientTexture2D_r4hau")
-texture_progress_offset = Vector2(2, 2)
+value = 100.0
+texture_under = ExtResource("1_qp5i6")
+texture_over = ExtResource("2_r2mkj")
+texture_progress = SubResource("GradientTexture2D_r2mkj")
+texture_progress_offset = Vector2(1, 1)
script = ExtResource("1_b1t4i")
diff --git a/Scenes/Puppets/HealthBar_Over.png b/Scenes/Puppets/HealthBar_Over.png
new file mode 100644
index 00000000..0c045894
Binary files /dev/null and b/Scenes/Puppets/HealthBar_Over.png differ
diff --git a/Scenes/Puppets/HealthBar_Over.png.import b/Scenes/Puppets/HealthBar_Over.png.import
new file mode 100644
index 00000000..8fb9a856
--- /dev/null
+++ b/Scenes/Puppets/HealthBar_Over.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://btia5s3c7owi1"
+path="res://.godot/imported/HealthBar_Over.png-68c473e56f80b77e078701bf34e42946.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Scenes/Puppets/HealthBar_Over.png"
+dest_files=["res://.godot/imported/HealthBar_Over.png-68c473e56f80b77e078701bf34e42946.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/Scenes/Puppets/HealthBar_Under.png b/Scenes/Puppets/HealthBar_Under.png
new file mode 100644
index 00000000..cf48ede0
Binary files /dev/null and b/Scenes/Puppets/HealthBar_Under.png differ
diff --git a/Scenes/Puppets/HealthBar_Under.png.import b/Scenes/Puppets/HealthBar_Under.png.import
new file mode 100644
index 00000000..0b5a7e71
--- /dev/null
+++ b/Scenes/Puppets/HealthBar_Under.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://0whvo6xa10it"
+path="res://.godot/imported/HealthBar_Under.png-b388076b20e97f6e5aae6f1b3073ee1e.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Scenes/Puppets/HealthBar_Under.png"
+dest_files=["res://.godot/imported/HealthBar_Under.png-b388076b20e97f6e5aae6f1b3073ee1e.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/Scenes/Puppets/PlayerPuppet.tscn b/Scenes/Puppets/PlayerPuppet.tscn
index e0caec7c..45cbd954 100644
--- a/Scenes/Puppets/PlayerPuppet.tscn
+++ b/Scenes/Puppets/PlayerPuppet.tscn
@@ -1,10 +1,20 @@
-[gd_scene load_steps=5 format=3 uid="uid://eus17omen6yk"]
+[gd_scene load_steps=7 format=3 uid="uid://eus17omen6yk"]
[ext_resource type="Script" uid="uid://kkb4qp3s86n3" path="res://Scenes/Puppets/Scripts/PlayerPuppet.cs" id="1_f4rea"]
[ext_resource type="Texture2D" uid="uid://b6fkei0i83vte" path="res://SharedAssets/Character1.png" id="2_affso"]
[ext_resource type="PackedScene" uid="uid://bgomxovxs7sr8" path="res://Scenes/Puppets/HealthBar.tscn" id="3_rechw"]
[ext_resource type="PackedScene" uid="uid://cdoguwlxehbpg" path="res://Scenes/Puppets/StatusContainer.tscn" id="4_o8yrn"]
+[sub_resource type="Gradient" id="Gradient_o8yrn"]
+offsets = PackedFloat32Array(0.0227273, 1)
+colors = PackedColorArray(0, 1, 0.0999999, 1, 1, 1, 1, 1)
+
+[sub_resource type="GradientTexture2D" id="GradientTexture2D_iysol"]
+resource_local_to_scene = true
+gradient = SubResource("Gradient_o8yrn")
+width = 100
+height = 18
+
[node name="PlayerPuppet" type="Node2D" node_paths=PackedStringArray("HealthBar", "Sprite", "_statusContainer")]
script = ExtResource("1_f4rea")
HealthBar = NodePath("ProgressBar")
@@ -19,5 +29,6 @@ offset_left = -50.0
offset_top = 32.0
offset_right = 50.0
offset_bottom = 52.0
+texture_progress = SubResource("GradientTexture2D_iysol")
[node name="StatusContainer" parent="." instance=ExtResource("4_o8yrn")]
diff --git a/Scenes/Puppets/Scripts/HealthBar.cs b/Scenes/Puppets/Scripts/HealthBar.cs
index 90e4370d..f8b2eac8 100644
--- a/Scenes/Puppets/Scripts/HealthBar.cs
+++ b/Scenes/Puppets/Scripts/HealthBar.cs
@@ -1,3 +1,5 @@
+using System;
+using System.Linq;
using Godot;
/**
@@ -8,6 +10,7 @@ public partial class HealthBar : TextureProgressBar
public override void _Ready()
{
Value = MaxValue;
+ UpdateBarColor();
}
//initializes health
@@ -15,6 +18,7 @@ public void SetHealth(int max, int current)
{
MaxValue = max;
Value = current;
+ UpdateBarColor();
}
//For effects changes max hp, and changes hp by a similar amount
@@ -22,12 +26,30 @@ public void ChangeMax(int change)
{
MaxValue += change;
Value += change;
+ UpdateBarColor();
}
//Changes hp value, for damage or heal, returns resulting hp.
public int ChangeHP(int amount)
{
Value += amount;
+ UpdateBarColor();
return (int)Value;
}
+
+ private void UpdateBarColor()
+ {
+ if (MaxValue == 0)
+ return;
+ float healthRatio = Mathf.Clamp((float)Value / (float)MaxValue, 0f, 1f);
+ float nearestStep = (healthRatio - healthRatio % 0.20f);
+ if (
+ TextureProgress is GradientTexture2D gradientTexture
+ && gradientTexture.Gradient.GetPointCount() > 0
+ )
+ {
+ Color lerpColor = Colors.Red.Lerp(Colors.Green, nearestStep);
+ gradientTexture.Gradient.SetColor(0, lerpColor);
+ }
+ }
}
diff --git a/Scenes/Puppets/Scripts/PlayerStats.cs b/Scenes/Puppets/Scripts/PlayerStats.cs
index 8c3735ef..3d3581f7 100644
--- a/Scenes/Puppets/Scripts/PlayerStats.cs
+++ b/Scenes/Puppets/Scripts/PlayerStats.cs
@@ -5,6 +5,8 @@
public partial class PlayerStats : Resource
{
+ public int Money = 0;
+
public int MaxHealth = 100;
public int CurrentHealth = 100;
public int MaxComboBar = 60;
@@ -12,6 +14,8 @@ public partial class PlayerStats : Resource
public int NotesToIncreaseCombo = 4;
public int RewardAmountModifier = 0;
public int Rerolls = 0;
+ public int Shortcuts = 0;
+ public int DiscountPercent = 0;
//Array in order of descending rarities, Legendary -> ... Common. Int odds out of 100.
public int[] RarityOdds = [1, 5, 10, 20, 100];
@@ -39,8 +43,44 @@ public void AddRelic(RelicTemplate relic)
Scribe.RemoveRelicFromPool(relic);
}
+ public void RemoveRelic(int index)
+ {
+ if (index < 0 || index >= CurRelics.Length)
+ {
+ GD.Print("index out of range");
+ return;
+ }
+
+ CurRelics = CurRelics.Where((_, i) => i != index).ToArray();
+ }
+
public void AddNote(Note nSelection)
{
+ //If the note is vampire, check to see if we already have 2 of them
+ if (
+ nSelection.Name == "PlayerVampire"
+ && CurNotes.Count(note => note.Name == "PlayerVampire") >= 2
+ )
+ {
+ SteamWhisperer.PopAchievement("vampire");
+ }
+
CurNotes = CurNotes.Append(nSelection).ToArray();
}
+
+ public void RemoveNote(int index)
+ {
+ if (index < 0 || index >= CurNotes.Length)
+ {
+ GD.Print("index out of range");
+ return;
+ }
+
+ CurNotes = CurNotes.Where((_, i) => i != index).ToArray();
+ }
+
+ public void RemoveNote(Note nSelection)
+ {
+ CurNotes = CurNotes.Where(n => n != nSelection).ToArray();
+ }
}
diff --git a/Scenes/Puppets/Scripts/PuppetTemplate.cs b/Scenes/Puppets/Scripts/PuppetTemplate.cs
index 5257d67f..09b7caec 100644
--- a/Scenes/Puppets/Scripts/PuppetTemplate.cs
+++ b/Scenes/Puppets/Scripts/PuppetTemplate.cs
@@ -111,7 +111,6 @@ protected virtual Tween DamageAnimate(int amount)
protected virtual void Kill()
{
Defeated?.Invoke(this);
- Visible = false;
}
#endregion
@@ -127,7 +126,7 @@ public virtual void TakeDamage(DamageInstance dmg)
Tween deathTween = DamageAnimate(amount);
if (CurrentHealth <= 0)
{
- deathTween.TweenCallback(Callable.From(Kill));
+ deathTween.Finished += Kill;
}
TextParticle newText = new TextParticle();
@@ -171,6 +170,8 @@ public int GetCurrentHealth()
///
public bool AddStatusEffect(StatusEffect effect)
{
+ if (CurrentHealth <= 0)
+ return false;
int index = StatusEffects.FindIndex(sEff => sEff.StatusName == effect.StatusName);
if (index != -1) //If status of same name -> stack -> return false
{
@@ -193,5 +194,13 @@ public void RemoveStatusEffect(StatusEffect effect)
StatusEffects.Remove(effect);
effect.QueueFree();
}
+
+ public bool HasStatus(StatusEffect effect)
+ {
+ int index = StatusEffects.FindIndex(sEff => sEff.StatusName == effect.StatusName);
+ if (index != -1)
+ return true;
+ return false;
+ }
#endregion
}
diff --git a/Scenes/ShopScene/Scripts/ShopItem.cs b/Scenes/ShopScene/Scripts/ShopItem.cs
new file mode 100644
index 00000000..c4acd6e3
--- /dev/null
+++ b/Scenes/ShopScene/Scripts/ShopItem.cs
@@ -0,0 +1,35 @@
+using System;
+using Godot;
+
+public partial class ShopItem : VBoxContainer
+{
+ public static readonly string LoadPath = "res://Scenes/ShopScene/ShopItem.tscn";
+
+ [Export]
+ public DisplayButton DisplayButton;
+
+ [Export]
+ public Label Cost;
+ public int Price;
+ public int BaseCost;
+
+ public void Display(
+ int baseCost,
+ int cost,
+ Texture2D texture,
+ string name,
+ bool focusHandling = false
+ )
+ {
+ DisplayButton.Display(texture, name, focusHandling);
+ BaseCost = baseCost;
+ Price = cost;
+ Cost.Text = cost.ToString();
+ }
+
+ public void UpdateCost(int cost)
+ {
+ Price = cost;
+ Cost.Text = cost.ToString();
+ }
+}
diff --git a/Scenes/ShopScene/Scripts/ShopItem.cs.uid b/Scenes/ShopScene/Scripts/ShopItem.cs.uid
new file mode 100644
index 00000000..ad3cf9c5
--- /dev/null
+++ b/Scenes/ShopScene/Scripts/ShopItem.cs.uid
@@ -0,0 +1 @@
+uid://doajq3v7wwje5
diff --git a/Scenes/ShopScene/Scripts/ShopScene.cs b/Scenes/ShopScene/Scripts/ShopScene.cs
new file mode 100644
index 00000000..7709e7a3
--- /dev/null
+++ b/Scenes/ShopScene/Scripts/ShopScene.cs
@@ -0,0 +1,325 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using FunkEngine;
+using Godot;
+
+public partial class ShopScene : Control
+{
+ public static readonly string LoadPath = "res://Scenes/ShopScene/ShopScene.tscn";
+
+ [Export]
+ private Label _moneyLabel;
+
+ [Export]
+ private Button _exitButton;
+
+ [Export]
+ private Button _removalButton;
+
+ [Export]
+ private GridContainer _noteGrid;
+
+ [Export]
+ private GridContainer _relicGrid;
+
+ [Export]
+ private CenterContainer _confirmationPopup;
+
+ [Export]
+ private Button _confirmationButton;
+
+ [Export]
+ private Button _denyButton;
+
+ [Export]
+ private Label _descriptionLabel;
+
+ [Export]
+ private Control _removalPanel;
+
+ [Export]
+ private GridContainer _possessionGrid;
+
+ [Export]
+ private Button _removalAcceptButton;
+
+ [Export]
+ private Button _cancelRemoveButton;
+
+ [Export]
+ private Label _removalCostLabel;
+
+ private ButtonGroup _bGroup;
+
+ private readonly int[] _priceByRarity = [100, 90, 80, 70, 60, 50, 9];
+ const int NoteCost = 45;
+
+ private List _shopItems = new List();
+
+ public override void _Ready()
+ {
+ _bGroup = new ButtonGroup();
+ Initialize();
+ _confirmationButton.Pressed += TryPurchase;
+ _denyButton.Pressed += CloseConfirmationPopup;
+ _removalButton.Pressed += OpenRemovalPane;
+ _removalAcceptButton.Pressed += RemoveNote;
+ _cancelRemoveButton.Pressed += CloseRemovalPane;
+ }
+
+ public override void _EnterTree()
+ {
+ BgAudioPlayer.LiveInstance.ResumeLevelMusic();
+ }
+
+ private void Initialize()
+ {
+ UpdateMoneyLabel();
+ GenerateShopItems();
+ PopulatePossessedNotes();
+ }
+
+ public override void _Input(InputEvent @event)
+ {
+ if (GetViewport().GuiGetFocusOwner() == null)
+ {
+ _exitButton.GrabFocus();
+ }
+ if (@event.IsActionPressed("ui_cancel"))
+ {
+ if (_confirmationPopup.Visible)
+ {
+ CloseConfirmationPopup();
+ GetViewport().SetInputAsHandled();
+ }
+ else if (_removalPanel.Visible)
+ {
+ CloseRemovalPane();
+ GetViewport().SetInputAsHandled();
+ }
+ }
+ }
+
+ private void UpdateMoneyLabel()
+ {
+ _moneyLabel.Text = StageProducer.PlayerStats.Money.ToString();
+ }
+
+ private const int RelicOptions = 3;
+ private const int NoteOptions = 5;
+
+ private void GenerateShopItems()
+ {
+ List _shopRelics = Scribe
+ .GetRandomRelics(
+ RelicOptions,
+ StageProducer.CurRoom + 10,
+ StageProducer.PlayerStats.RarityOdds
+ )
+ .ToList();
+
+ List _shopNotes = Scribe
+ .GetRandomRewardNotes(NoteOptions, StageProducer.CurRoom + 10)
+ .ToList();
+
+ foreach (var relic in _shopRelics)
+ {
+ int price = _priceByRarity[(int)relic.Rarity];
+ AddShopItem(_relicGrid, relic, price);
+ }
+
+ foreach (var note in _shopNotes)
+ {
+ int price = NoteCost;
+ AddShopItem(_noteGrid, note, price);
+ }
+ }
+
+ private void RefreshShopPrices()
+ {
+ foreach (ShopItem sItem in _shopItems)
+ {
+ sItem.UpdateCost(GetPrice(sItem.BaseCost));
+ }
+ }
+
+ private void AddShopItem(GridContainer container, IDisplayable item, int basePrice)
+ {
+ if (container == null || item == null)
+ {
+ GD.PushError("AddShopItem called with null!");
+ return;
+ }
+ int price = GetPrice(basePrice);
+ ShopItem newItem = GD.Load(ShopItem.LoadPath).Instantiate();
+ newItem.Display(basePrice, price, item.Texture, item.Name);
+ newItem.DisplayButton.Pressed += () => SetPurchasable(item, newItem);
+ newItem.DisplayButton.SetButtonGroup(_bGroup);
+ newItem.DisplayButton.ToggleMode = true;
+ newItem.DisplayButton.FocusEntered += () => ChangeDescription(item);
+ _shopItems.Add(newItem);
+ container.AddChild(newItem);
+ }
+
+ private int GetPrice(int basePrice)
+ {
+ return Math.Max(basePrice * (1 - StageProducer.PlayerStats.DiscountPercent / 100), 0); //Price can't go negative
+ }
+
+ private IDisplayable _currentItem;
+ private ShopItem _currentUItem;
+
+ private void SetPurchasable(IDisplayable item, ShopItem uItem)
+ {
+ if (item == null || uItem == null)
+ return;
+ _currentItem = item;
+ _currentUItem = uItem;
+ _confirmationButton.Disabled = StageProducer.PlayerStats.Money < _currentUItem.Price;
+ OpenConfirmationPopup();
+ }
+
+ private void TryPurchase()
+ {
+ if (StageProducer.PlayerStats.Money < _currentUItem.Price)
+ return;
+
+ StageProducer.PlayerStats.Money -= _currentUItem.Price;
+ switch (_currentItem)
+ {
+ case Note note:
+ StageProducer.PlayerStats.AddNote(note);
+ AddNoteToPossessions(note);
+ break;
+ case RelicTemplate relic:
+ StageProducer.PlayerStats.AddRelic(relic);
+ break;
+ }
+
+ _shopItems.Remove(_currentUItem);
+ CloseConfirmationPopup();
+
+ GetViewport().GuiGetFocusOwner().FindNextValidFocus().GrabFocus(); //slightly hacky
+ _currentUItem.Visible = false;
+ _currentUItem.QueueFree();
+ UpdateMoneyLabel();
+
+ _currentItem = null;
+ _currentUItem = null;
+
+ RefreshShopPrices();
+ }
+
+ private Control _lastFocused;
+
+ private void OpenConfirmationPopup()
+ {
+ _confirmationPopup.Visible = true;
+ _lastFocused = GetViewport().GuiGetFocusOwner();
+ _denyButton.GrabFocus();
+ }
+
+ private void CloseConfirmationPopup()
+ {
+ _confirmationPopup.Visible = false;
+ _lastFocused.GrabFocus();
+ _lastFocused = null;
+ _bGroup.GetPressedButton().SetPressed(false);
+ }
+
+ private void ChangeDescription(IDisplayable displayable)
+ {
+ if (displayable == null)
+ {
+ _descriptionLabel.Text = "";
+ return;
+ }
+ string name = displayable.Name.ToUpper();
+ name = name.Replace(" ", "");
+ string type = displayable switch
+ {
+ Note => "NOTE_",
+ RelicTemplate => "RELIC_",
+ _ => "UNKNOWN_",
+ };
+ _descriptionLabel.Text = Tr(type + name + "_NAME") + ": " + Tr(type + name + "_TOOLTIP");
+ }
+
+ private const int RemovalCost = 50;
+ private bool _hasRemoved;
+
+ private void OpenRemovalPane()
+ {
+ if (_hasRemoved)
+ return;
+ _removalCostLabel.Text = RemovalCost.ToString();
+ _removalButton.Disabled = true;
+ _exitButton.Disabled = true;
+ _removalPanel.Visible = true;
+ _removalAcceptButton.Visible = false;
+ _removalAcceptButton.Disabled = StageProducer.PlayerStats.Money < RemovalCost;
+ _bGroup.GetPressedButton()?.SetPressed(false);
+ _noteGrid.Visible = false;
+ _relicGrid.Visible = false;
+ _cancelRemoveButton.GrabFocus();
+ }
+
+ private void CloseRemovalPane()
+ {
+ _removalButton.Disabled = _hasRemoved;
+ _exitButton.Disabled = false;
+ _removalPanel.Visible = false;
+ _removalButton.GrabFocus();
+ _toRemove = null;
+ _selectedRemoveButton = null;
+ _noteGrid.Visible = true;
+ _relicGrid.Visible = true;
+ ChangeDescription(null);
+ }
+
+ private void PopulatePossessedNotes()
+ {
+ foreach (var note in StageProducer.PlayerStats.CurNotes)
+ {
+ AddNoteToPossessions(note);
+ }
+ }
+
+ private void AddNoteToPossessions(Note note)
+ {
+ if (note == null)
+ return;
+ DisplayButton disButton = GD.Load(DisplayButton.LoadPath)
+ .Instantiate();
+ disButton.Display(note.Texture, note.Name);
+ disButton.ToggleMode = true;
+ disButton.FocusEntered += () => ChangeDescription(note);
+ disButton.Pressed += () => RemovalSelection(note, disButton);
+ disButton.ButtonGroup = _bGroup;
+ _possessionGrid.AddChild(disButton);
+ }
+
+ private Note _toRemove;
+ private Button _selectedRemoveButton;
+
+ private void RemovalSelection(Note note, Button button)
+ {
+ _toRemove = note;
+ _selectedRemoveButton = button;
+ _removalAcceptButton.Visible = true;
+ button.SetPressed(true);
+ }
+
+ private void RemoveNote()
+ {
+ if (_toRemove == null || _selectedRemoveButton == null)
+ return;
+ StageProducer.PlayerStats.Money -= RemovalCost;
+ _removalButton.Disabled = true;
+ _hasRemoved = true;
+ StageProducer.PlayerStats.RemoveNote(_toRemove);
+ _selectedRemoveButton.QueueFree();
+ CloseRemovalPane();
+ }
+}
diff --git a/Scenes/ShopScene/Scripts/ShopScene.cs.uid b/Scenes/ShopScene/Scripts/ShopScene.cs.uid
new file mode 100644
index 00000000..f81ceae9
--- /dev/null
+++ b/Scenes/ShopScene/Scripts/ShopScene.cs.uid
@@ -0,0 +1 @@
+uid://dg0xaieus84ns
diff --git a/Scenes/ShopScene/ShopItem.tscn b/Scenes/ShopScene/ShopItem.tscn
new file mode 100644
index 00000000..9bbfb294
--- /dev/null
+++ b/Scenes/ShopScene/ShopItem.tscn
@@ -0,0 +1,47 @@
+[gd_scene load_steps=4 format=3 uid="uid://cln1jkrh6sq35"]
+
+[ext_resource type="PackedScene" uid="uid://cymo26khpw4m1" path="res://Scenes/UI/DisplayButton.tscn" id="1_f0nq7"]
+[ext_resource type="Script" uid="uid://doajq3v7wwje5" path="res://Scenes/ShopScene/Scripts/ShopItem.cs" id="1_ncg4o"]
+[ext_resource type="Texture2D" uid="uid://dyt1cvag13aik" path="res://SharedAssets/Money.png" id="3_qkmob"]
+
+[node name="ShopItem" type="VBoxContainer" node_paths=PackedStringArray("DisplayButton", "Cost")]
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+offset_right = -596.0
+offset_bottom = -300.0
+grow_horizontal = 2
+grow_vertical = 2
+size_flags_horizontal = 4
+size_flags_vertical = 4
+script = ExtResource("1_ncg4o")
+DisplayButton = NodePath("DisplayButton")
+Cost = NodePath("MarginContainer/HBoxContainer/MoneyLabel")
+
+[node name="DisplayButton" parent="." instance=ExtResource("1_f0nq7")]
+layout_mode = 2
+
+[node name="MarginContainer" type="MarginContainer" parent="."]
+layout_mode = 2
+theme_override_constants/margin_right = 2
+
+[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer"]
+layout_mode = 2
+
+[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/HBoxContainer"]
+layout_mode = 2
+theme_override_constants/margin_left = 2
+
+[node name="TextureRect" type="TextureRect" parent="MarginContainer/HBoxContainer/MarginContainer"]
+layout_mode = 2
+size_flags_vertical = 4
+texture = ExtResource("3_qkmob")
+
+[node name="MoneyLabel" type="Label" parent="MarginContainer/HBoxContainer"]
+custom_minimum_size = Vector2(21, 0)
+layout_mode = 2
+size_flags_horizontal = 10
+size_flags_vertical = 1
+horizontal_alignment = 2
+vertical_alignment = 1
+clip_text = true
diff --git a/Scenes/ShopScene/ShopScene.tscn b/Scenes/ShopScene/ShopScene.tscn
new file mode 100644
index 00000000..c6d905f7
--- /dev/null
+++ b/Scenes/ShopScene/ShopScene.tscn
@@ -0,0 +1,60 @@
+[gd_scene load_steps=8 format=3 uid="uid://b35sk5syi24et"]
+
+[ext_resource type="Script" uid="uid://pl57giqyhckb" path="res://Scenes/UI/Scripts/MenuModule.cs" id="2_723s6"]
+[ext_resource type="Texture2D" uid="uid://qhwve7fik4do" path="res://SharedAssets/BackGround_Full.png" id="2_dt33i"]
+[ext_resource type="Script" uid="uid://cp6t6haqyef7o" path="res://Scenes/AreaBasedBackground.cs" id="3_n34g6"]
+[ext_resource type="PackedScene" uid="uid://eus17omen6yk" path="res://Scenes/Puppets/PlayerPuppet.tscn" id="4_jpqhk"]
+[ext_resource type="PackedScene" uid="uid://bk0js6ji42xrt" path="res://Scenes/ShopScene/ShopUI.tscn" id="8_2xatg"]
+[ext_resource type="Shader" uid="uid://dp36iuuy414k1" path="res://SharedAssets/StarryNight.gdshader" id="11_0afww"]
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_jpqhk"]
+shader = ExtResource("11_0afww")
+shader_parameter/bg_top_color = Vector4(0.18, 0.08, 0.12, 0)
+shader_parameter/bg_bottom_color = Vector4(0.028, 0.008, 0.184, 0)
+shader_parameter/gradient_ratio = 1.0
+shader_parameter/time_scale = 1.0
+
+[node name="ShopScene" type="Node2D"]
+
+[node name="UILayer" type="CanvasLayer" parent="." node_paths=PackedStringArray("CurSceneNode")]
+script = ExtResource("2_723s6")
+CurSceneNode = NodePath("..")
+
+[node name="SubViewportContainer" type="SubViewportContainer" parent="."]
+z_index = -2
+offset_top = 178.0
+offset_right = 640.0
+offset_bottom = 358.0
+mouse_filter = 2
+
+[node name="SubViewport" type="SubViewport" parent="SubViewportContainer"]
+handle_input_locally = false
+size = Vector2i(640, 180)
+render_target_update_mode = 4
+
+[node name="StarShader" type="ColorRect" parent="SubViewportContainer/SubViewport"]
+z_index = -1
+material = SubResource("ShaderMaterial_jpqhk")
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+mouse_filter = 2
+color = Color(0, 0, 0, 1)
+
+[node name="PlayerMarker" type="Marker2D" parent="."]
+position = Vector2(579, 126)
+
+[node name="PlayerPuppet" parent="PlayerMarker" instance=ExtResource("4_jpqhk")]
+
+[node name="BackGround" type="TextureRect" parent="."]
+z_index = -1
+offset_right = 640.0
+offset_bottom = 180.0
+texture = ExtResource("2_dt33i")
+script = ExtResource("3_n34g6")
+
+[node name="ShopUI" parent="." instance=ExtResource("8_2xatg")]
+offset_right = 640.0
+offset_bottom = 360.0
diff --git a/Scenes/ShopScene/ShopUI.tscn b/Scenes/ShopScene/ShopUI.tscn
new file mode 100644
index 00000000..6a999efe
--- /dev/null
+++ b/Scenes/ShopScene/ShopUI.tscn
@@ -0,0 +1,530 @@
+[gd_scene load_steps=8 format=3 uid="uid://bk0js6ji42xrt"]
+
+[ext_resource type="Texture2D" uid="uid://djd6iw2g84bba" path="res://Scenes/UI/Assets/UI_CenterFrame.png" id="1_67his"]
+[ext_resource type="Script" uid="uid://dg0xaieus84ns" path="res://Scenes/ShopScene/Scripts/ShopScene.cs" id="1_bmt43"]
+[ext_resource type="Texture2D" uid="uid://8u3xvcma81d" path="res://Scenes/UI/Assets/UI_CrystalFrame.png" id="2_bmt43"]
+[ext_resource type="Texture2D" uid="uid://burj10os057fx" path="res://Scenes/UI/Assets/UI_CrystalFrameInset.png" id="3_r34tc"]
+[ext_resource type="Theme" uid="uid://d37e3tpsbxwak" path="res://Scenes/UI/Assets/GeneralTheme.tres" id="4_3vktw"]
+[ext_resource type="Script" uid="uid://cahjluc6v7ked" path="res://Scenes/UI/TitleScreen/Scripts/SceneChange.cs" id="5_w0f8r"]
+[ext_resource type="Texture2D" uid="uid://dyt1cvag13aik" path="res://SharedAssets/Money.png" id="6_tf865"]
+
+[node name="ShopUI" type="Control" node_paths=PackedStringArray("_moneyLabel", "_exitButton", "_removalButton", "_noteGrid", "_relicGrid", "_confirmationPopup", "_confirmationButton", "_denyButton", "_descriptionLabel", "_removalPanel", "_possessionGrid", "_removalAcceptButton", "_cancelRemoveButton", "_removalCostLabel")]
+z_index = 2
+layout_mode = 3
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+script = ExtResource("1_bmt43")
+_moneyLabel = NodePath("MoneyContainer/MoneyFrame/MarginContainer/HBoxContainer/MoneyLabel")
+_exitButton = NodePath("BottomPanel/DescBox/HBoxContainer/OptionsBG/OptionsMargin/OptionsBG/MarginContainer/VBoxContainer/Continue")
+_removalButton = NodePath("BottomPanel/DescBox/HBoxContainer/OptionsBG/OptionsMargin/OptionsBG/MarginContainer/VBoxContainer/Removal")
+_noteGrid = NodePath("TopPanel/MarginContainer/VBoxContainer/NoteSelection/MarginContainer/NotesBox/CenterContainer/NotesGrid")
+_relicGrid = NodePath("TopPanel/MarginContainer/VBoxContainer/RelicSelection/MarginContainer/RelicsBox/CenterContainer/RelicsGrid")
+_confirmationPopup = NodePath("ConfirmPurchase")
+_confirmationButton = NodePath("ConfirmPurchase/HBoxContainer/Confirm")
+_denyButton = NodePath("ConfirmPurchase/HBoxContainer/Deny")
+_descriptionLabel = NodePath("BottomPanel/DescBox/HBoxContainer/DescBG/DescMargin/DescBackground/MarginContainer/Description")
+_removalPanel = NodePath("Removal")
+_possessionGrid = NodePath("Removal/Panel/MarginContainer/VBoxContainer/NoteSelection/MarginContainer/NotesBox/CenterContainer/PossesionGrid")
+_removalAcceptButton = NodePath("Removal/Panel/MarginContainer/VBoxContainer/Options/MarginContainer/HBoxContainer/Accept")
+_cancelRemoveButton = NodePath("Removal/Panel/MarginContainer/VBoxContainer/Options/MarginContainer/HBoxContainer/Cancel")
+_removalCostLabel = NodePath("Removal/Panel/MarginContainer/VBoxContainer/Options/MarginContainer/HBoxContainer/CostPanel/HBoxContainer/MoneyLabel")
+
+[node name="TopPanel" type="NinePatchRect" parent="."]
+layout_mode = 0
+offset_right = 508.0
+offset_bottom = 211.0
+texture = ExtResource("1_67his")
+patch_margin_left = 12
+patch_margin_top = 12
+patch_margin_right = 12
+patch_margin_bottom = 12
+
+[node name="MarginContainer" type="MarginContainer" parent="TopPanel"]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+theme_override_constants/margin_left = 10
+theme_override_constants/margin_top = 10
+theme_override_constants/margin_right = 10
+theme_override_constants/margin_bottom = 10
+
+[node name="VBoxContainer" type="VBoxContainer" parent="TopPanel/MarginContainer"]
+layout_mode = 2
+theme_override_constants/separation = 5
+
+[node name="NoteSelection" type="NinePatchRect" parent="TopPanel/MarginContainer/VBoxContainer"]
+self_modulate = Color(1, 1, 1, 0.75)
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_vertical = 3
+texture = ExtResource("2_bmt43")
+patch_margin_left = 6
+patch_margin_top = 6
+patch_margin_right = 6
+patch_margin_bottom = 7
+
+[node name="MarginContainer" type="MarginContainer" parent="TopPanel/MarginContainer/VBoxContainer/NoteSelection"]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+theme_override_constants/margin_left = 10
+theme_override_constants/margin_top = 10
+theme_override_constants/margin_right = 10
+theme_override_constants/margin_bottom = 10
+
+[node name="NotesBox" type="ScrollContainer" parent="TopPanel/MarginContainer/VBoxContainer/NoteSelection/MarginContainer"]
+layout_mode = 2
+follow_focus = true
+
+[node name="CenterContainer" type="CenterContainer" parent="TopPanel/MarginContainer/VBoxContainer/NoteSelection/MarginContainer/NotesBox"]
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_vertical = 3
+
+[node name="NotesGrid" type="GridContainer" parent="TopPanel/MarginContainer/VBoxContainer/NoteSelection/MarginContainer/NotesBox/CenterContainer"]
+layout_mode = 2
+size_flags_vertical = 4
+theme_override_constants/h_separation = 30
+columns = 6
+
+[node name="RelicSelection" type="NinePatchRect" parent="TopPanel/MarginContainer/VBoxContainer"]
+self_modulate = Color(1, 1, 1, 0.75)
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_vertical = 3
+texture = ExtResource("2_bmt43")
+patch_margin_left = 6
+patch_margin_top = 6
+patch_margin_right = 6
+patch_margin_bottom = 7
+
+[node name="MarginContainer" type="MarginContainer" parent="TopPanel/MarginContainer/VBoxContainer/RelicSelection"]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+theme_override_constants/margin_left = 10
+theme_override_constants/margin_top = 10
+theme_override_constants/margin_right = 10
+theme_override_constants/margin_bottom = 10
+
+[node name="RelicsBox" type="ScrollContainer" parent="TopPanel/MarginContainer/VBoxContainer/RelicSelection/MarginContainer"]
+layout_mode = 2
+follow_focus = true
+
+[node name="CenterContainer" type="CenterContainer" parent="TopPanel/MarginContainer/VBoxContainer/RelicSelection/MarginContainer/RelicsBox"]
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_vertical = 3
+
+[node name="RelicsGrid" type="GridContainer" parent="TopPanel/MarginContainer/VBoxContainer/RelicSelection/MarginContainer/RelicsBox/CenterContainer"]
+layout_mode = 2
+size_flags_vertical = 4
+theme_override_constants/h_separation = 30
+columns = 6
+
+[node name="BottomPanel" type="NinePatchRect" parent="."]
+layout_mode = 0
+offset_top = 211.0
+offset_right = 640.0
+offset_bottom = 360.0
+texture = ExtResource("1_67his")
+patch_margin_left = 12
+patch_margin_top = 12
+patch_margin_right = 12
+patch_margin_bottom = 12
+
+[node name="DescBox" type="MarginContainer" parent="BottomPanel"]
+layout_mode = 2
+offset_right = 640.0
+offset_bottom = 149.0
+grow_vertical = 0
+size_flags_vertical = 3
+size_flags_stretch_ratio = 0.4
+theme_override_constants/margin_left = 10
+theme_override_constants/margin_top = 10
+theme_override_constants/margin_right = 10
+theme_override_constants/margin_bottom = 10
+
+[node name="HBoxContainer" type="HBoxContainer" parent="BottomPanel/DescBox"]
+layout_mode = 2
+
+[node name="DescBG" type="NinePatchRect" parent="BottomPanel/DescBox/HBoxContainer"]
+self_modulate = Color(1, 1, 1, 0.75)
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_vertical = 3
+texture = ExtResource("2_bmt43")
+patch_margin_left = 6
+patch_margin_top = 6
+patch_margin_right = 6
+patch_margin_bottom = 7
+
+[node name="DescMargin" type="MarginContainer" parent="BottomPanel/DescBox/HBoxContainer/DescBG"]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+size_flags_horizontal = 3
+theme_override_constants/margin_left = 4
+theme_override_constants/margin_top = 4
+theme_override_constants/margin_right = 4
+theme_override_constants/margin_bottom = 4
+
+[node name="DescBackground" type="NinePatchRect" parent="BottomPanel/DescBox/HBoxContainer/DescBG/DescMargin"]
+layout_mode = 2
+texture = ExtResource("3_r34tc")
+patch_margin_left = 7
+patch_margin_top = 7
+patch_margin_right = 7
+patch_margin_bottom = 7
+
+[node name="MarginContainer" type="MarginContainer" parent="BottomPanel/DescBox/HBoxContainer/DescBG/DescMargin/DescBackground"]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+theme_override_constants/margin_left = 7
+theme_override_constants/margin_top = 7
+theme_override_constants/margin_right = 7
+
+[node name="Description" type="Label" parent="BottomPanel/DescBox/HBoxContainer/DescBG/DescMargin/DescBackground/MarginContainer"]
+layout_mode = 2
+size_flags_vertical = 1
+autowrap_mode = 2
+clip_text = true
+text_overrun_behavior = 1
+
+[node name="OptionsBG" type="NinePatchRect" parent="BottomPanel/DescBox/HBoxContainer"]
+self_modulate = Color(1, 1, 1, 0.75)
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_vertical = 3
+size_flags_stretch_ratio = 0.39
+texture = ExtResource("2_bmt43")
+patch_margin_left = 6
+patch_margin_top = 6
+patch_margin_right = 6
+patch_margin_bottom = 7
+
+[node name="OptionsMargin" type="MarginContainer" parent="BottomPanel/DescBox/HBoxContainer/OptionsBG"]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+size_flags_horizontal = 3
+theme_override_constants/margin_left = 4
+theme_override_constants/margin_top = 4
+theme_override_constants/margin_right = 4
+theme_override_constants/margin_bottom = 4
+
+[node name="OptionsBG" type="NinePatchRect" parent="BottomPanel/DescBox/HBoxContainer/OptionsBG/OptionsMargin"]
+layout_mode = 2
+texture = ExtResource("3_r34tc")
+patch_margin_left = 7
+patch_margin_top = 7
+patch_margin_right = 7
+patch_margin_bottom = 7
+
+[node name="MarginContainer" type="MarginContainer" parent="BottomPanel/DescBox/HBoxContainer/OptionsBG/OptionsMargin/OptionsBG"]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+theme_override_constants/margin_left = 7
+theme_override_constants/margin_top = 7
+theme_override_constants/margin_right = 7
+
+[node name="VBoxContainer" type="VBoxContainer" parent="BottomPanel/DescBox/HBoxContainer/OptionsBG/OptionsMargin/OptionsBG/MarginContainer"]
+layout_mode = 2
+alignment = 1
+
+[node name="Removal" type="Button" parent="BottomPanel/DescBox/HBoxContainer/OptionsBG/OptionsMargin/OptionsBG/MarginContainer/VBoxContainer"]
+layout_mode = 2
+size_flags_horizontal = 4
+size_flags_vertical = 4
+theme = ExtResource("4_3vktw")
+text = "SHOP_REMOVAL"
+
+[node name="Continue" type="Button" parent="BottomPanel/DescBox/HBoxContainer/OptionsBG/OptionsMargin/OptionsBG/MarginContainer/VBoxContainer"]
+layout_mode = 2
+size_flags_horizontal = 4
+size_flags_vertical = 4
+theme = ExtResource("4_3vktw")
+text = "INBETWEEN_CONTINUE"
+script = ExtResource("5_w0f8r")
+ScenePath = 7
+_startFocused = true
+
+[node name="MoneyContainer" type="MarginContainer" parent="."]
+layout_mode = 1
+anchors_preset = 1
+anchor_left = 1.0
+anchor_right = 1.0
+offset_left = -125.0
+offset_bottom = 29.0
+grow_horizontal = 0
+theme_override_constants/margin_left = -1
+theme_override_constants/margin_top = 5
+theme_override_constants/margin_right = 5
+theme_override_constants/margin_bottom = 0
+
+[node name="MoneyFrame" type="NinePatchRect" parent="MoneyContainer"]
+layout_mode = 2
+texture = ExtResource("2_bmt43")
+patch_margin_left = 7
+patch_margin_top = 7
+patch_margin_right = 7
+patch_margin_bottom = 7
+
+[node name="MarginContainer" type="MarginContainer" parent="MoneyContainer/MoneyFrame"]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+theme_override_constants/margin_right = 8
+
+[node name="HBoxContainer" type="HBoxContainer" parent="MoneyContainer/MoneyFrame/MarginContainer"]
+layout_mode = 2
+
+[node name="MarginContainer" type="MarginContainer" parent="MoneyContainer/MoneyFrame/MarginContainer/HBoxContainer"]
+layout_mode = 2
+theme_override_constants/margin_left = 6
+
+[node name="TextureRect" type="TextureRect" parent="MoneyContainer/MoneyFrame/MarginContainer/HBoxContainer/MarginContainer"]
+layout_mode = 2
+size_flags_vertical = 4
+texture = ExtResource("6_tf865")
+
+[node name="MoneyLabel" type="Label" parent="MoneyContainer/MoneyFrame/MarginContainer/HBoxContainer"]
+custom_minimum_size = Vector2(91, 0)
+layout_mode = 2
+size_flags_horizontal = 10
+size_flags_vertical = 1
+text = "0"
+horizontal_alignment = 2
+vertical_alignment = 1
+clip_text = true
+
+[node name="ConfirmPurchase" type="CenterContainer" parent="."]
+visible = false
+z_index = 3
+layout_mode = 1
+anchors_preset = 8
+anchor_left = 0.5
+anchor_top = 0.5
+anchor_right = 0.5
+anchor_bottom = 0.5
+offset_left = -105.0
+offset_top = -20.0
+offset_right = 105.0
+offset_bottom = 20.0
+grow_horizontal = 2
+grow_vertical = 2
+
+[node name="MouseFilter" type="Control" parent="ConfirmPurchase"]
+custom_minimum_size = Vector2(640, 360)
+layout_mode = 2
+
+[node name="Confirmation" type="NinePatchRect" parent="ConfirmPurchase"]
+custom_minimum_size = Vector2(230, 62)
+layout_mode = 2
+texture = ExtResource("1_67his")
+patch_margin_left = 7
+patch_margin_top = 7
+patch_margin_right = 7
+patch_margin_bottom = 7
+
+[node name="HBoxContainer" type="HBoxContainer" parent="ConfirmPurchase"]
+layout_mode = 2
+alignment = 1
+
+[node name="Confirm" type="Button" parent="ConfirmPurchase/HBoxContainer"]
+layout_mode = 2
+focus_neighbor_left = NodePath("../Deny")
+focus_neighbor_top = NodePath("../Deny")
+focus_neighbor_right = NodePath("../Deny")
+focus_neighbor_bottom = NodePath("../Deny")
+focus_next = NodePath("../Deny")
+focus_previous = NodePath("../Deny")
+theme = ExtResource("4_3vktw")
+text = "SHOP_CONFIRM"
+
+[node name="Deny" type="Button" parent="ConfirmPurchase/HBoxContainer"]
+layout_mode = 2
+focus_neighbor_left = NodePath("../Confirm")
+focus_neighbor_top = NodePath("../Confirm")
+focus_neighbor_right = NodePath("../Confirm")
+focus_neighbor_bottom = NodePath("../Confirm")
+focus_next = NodePath("../Confirm")
+focus_previous = NodePath("../Confirm")
+theme = ExtResource("4_3vktw")
+text = "SHOP_CANCEL"
+
+[node name="Removal" type="Control" parent="."]
+visible = false
+layout_mode = 3
+anchors_preset = 0
+offset_right = 640.0
+offset_bottom = 360.0
+
+[node name="Panel" type="NinePatchRect" parent="Removal"]
+layout_mode = 0
+offset_right = 508.0
+offset_bottom = 211.0
+texture = ExtResource("1_67his")
+patch_margin_left = 12
+patch_margin_top = 12
+patch_margin_right = 12
+patch_margin_bottom = 12
+
+[node name="MarginContainer" type="MarginContainer" parent="Removal/Panel"]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+theme_override_constants/margin_left = 10
+theme_override_constants/margin_top = 10
+theme_override_constants/margin_right = 10
+theme_override_constants/margin_bottom = 10
+
+[node name="VBoxContainer" type="VBoxContainer" parent="Removal/Panel/MarginContainer"]
+layout_mode = 2
+theme_override_constants/separation = 5
+
+[node name="NoteSelection" type="NinePatchRect" parent="Removal/Panel/MarginContainer/VBoxContainer"]
+self_modulate = Color(1, 1, 1, 0.75)
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_vertical = 3
+texture = ExtResource("2_bmt43")
+patch_margin_left = 6
+patch_margin_top = 6
+patch_margin_right = 6
+patch_margin_bottom = 7
+
+[node name="MarginContainer" type="MarginContainer" parent="Removal/Panel/MarginContainer/VBoxContainer/NoteSelection"]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+theme_override_constants/margin_left = 10
+theme_override_constants/margin_top = 10
+theme_override_constants/margin_right = 10
+theme_override_constants/margin_bottom = 10
+
+[node name="NotesBox" type="ScrollContainer" parent="Removal/Panel/MarginContainer/VBoxContainer/NoteSelection/MarginContainer"]
+layout_mode = 2
+follow_focus = true
+
+[node name="CenterContainer" type="CenterContainer" parent="Removal/Panel/MarginContainer/VBoxContainer/NoteSelection/MarginContainer/NotesBox"]
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_vertical = 3
+
+[node name="PossesionGrid" type="GridContainer" parent="Removal/Panel/MarginContainer/VBoxContainer/NoteSelection/MarginContainer/NotesBox/CenterContainer"]
+layout_mode = 2
+size_flags_vertical = 4
+theme_override_constants/h_separation = 30
+columns = 6
+
+[node name="Options" type="NinePatchRect" parent="Removal/Panel/MarginContainer/VBoxContainer"]
+self_modulate = Color(1, 1, 1, 0.75)
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_vertical = 3
+size_flags_stretch_ratio = 0.5
+texture = ExtResource("2_bmt43")
+patch_margin_left = 6
+patch_margin_top = 6
+patch_margin_right = 6
+patch_margin_bottom = 7
+
+[node name="MarginContainer" type="MarginContainer" parent="Removal/Panel/MarginContainer/VBoxContainer/Options"]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+theme_override_constants/margin_left = 10
+theme_override_constants/margin_top = 10
+theme_override_constants/margin_right = 10
+theme_override_constants/margin_bottom = 10
+
+[node name="HBoxContainer" type="HBoxContainer" parent="Removal/Panel/MarginContainer/VBoxContainer/Options/MarginContainer"]
+layout_mode = 2
+theme_override_constants/separation = 20
+alignment = 1
+
+[node name="CostPanel" type="VBoxContainer" parent="Removal/Panel/MarginContainer/VBoxContainer/Options/MarginContainer/HBoxContainer"]
+layout_mode = 2
+alignment = 1
+
+[node name="Label" type="Label" parent="Removal/Panel/MarginContainer/VBoxContainer/Options/MarginContainer/HBoxContainer/CostPanel"]
+layout_mode = 2
+text = "REMOVAL_COST"
+
+[node name="HBoxContainer" type="HBoxContainer" parent="Removal/Panel/MarginContainer/VBoxContainer/Options/MarginContainer/HBoxContainer/CostPanel"]
+layout_mode = 2
+
+[node name="MarginContainer" type="MarginContainer" parent="Removal/Panel/MarginContainer/VBoxContainer/Options/MarginContainer/HBoxContainer/CostPanel/HBoxContainer"]
+layout_mode = 2
+theme_override_constants/margin_left = 2
+
+[node name="TextureRect" type="TextureRect" parent="Removal/Panel/MarginContainer/VBoxContainer/Options/MarginContainer/HBoxContainer/CostPanel/HBoxContainer/MarginContainer"]
+layout_mode = 2
+size_flags_vertical = 4
+texture = ExtResource("6_tf865")
+
+[node name="MoneyLabel" type="Label" parent="Removal/Panel/MarginContainer/VBoxContainer/Options/MarginContainer/HBoxContainer/CostPanel/HBoxContainer"]
+custom_minimum_size = Vector2(21, 0)
+layout_mode = 2
+size_flags_horizontal = 10
+size_flags_vertical = 1
+text = "999"
+horizontal_alignment = 2
+vertical_alignment = 1
+clip_text = true
+
+[node name="Accept" type="Button" parent="Removal/Panel/MarginContainer/VBoxContainer/Options/MarginContainer/HBoxContainer"]
+layout_mode = 2
+size_flags_horizontal = 4
+size_flags_vertical = 4
+focus_neighbor_bottom = NodePath("../Cancel")
+theme = ExtResource("4_3vktw")
+text = "CHEST_ROOM_ACCEPT"
+
+[node name="Cancel" type="Button" parent="Removal/Panel/MarginContainer/VBoxContainer/Options/MarginContainer/HBoxContainer"]
+layout_mode = 2
+size_flags_horizontal = 4
+size_flags_vertical = 4
+focus_neighbor_bottom = NodePath("../Accept")
+focus_next = NodePath(".")
+theme = ExtResource("4_3vktw")
+text = "SHOP_CANCEL"
diff --git a/Scenes/UI/DisplayButton.tscn b/Scenes/UI/DisplayButton.tscn
index a6c1d0fa..01b83737 100644
--- a/Scenes/UI/DisplayButton.tscn
+++ b/Scenes/UI/DisplayButton.tscn
@@ -10,4 +10,5 @@ anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme = ExtResource("1_26ea7")
+icon_alignment = 1
script = ExtResource("1_7lpm6")
diff --git a/Scenes/UI/Inventory.tscn b/Scenes/UI/Inventory.tscn
index 963cbad3..7fa6e6ab 100644
--- a/Scenes/UI/Inventory.tscn
+++ b/Scenes/UI/Inventory.tscn
@@ -1,11 +1,12 @@
-[gd_scene load_steps=5 format=3 uid="uid://be6fb2sr5i515"]
+[gd_scene load_steps=6 format=3 uid="uid://be6fb2sr5i515"]
[ext_resource type="Script" uid="uid://kqa0ovjph1hd" path="res://Scenes/UI/Scripts/Inventory.cs" id="1_8rcwd"]
[ext_resource type="Texture2D" uid="uid://ck16vyh1q68ri" path="res://Scenes/UI/Assets/UI_ForestBackground.png" id="2_s6pj7"]
[ext_resource type="Texture2D" uid="uid://8u3xvcma81d" path="res://Scenes/UI/Assets/UI_CrystalFrame.png" id="3_s6pj7"]
[ext_resource type="Texture2D" uid="uid://burj10os057fx" path="res://Scenes/UI/Assets/UI_CrystalFrameInset.png" id="4_b6trj"]
+[ext_resource type="Texture2D" uid="uid://dyt1cvag13aik" path="res://SharedAssets/Money.png" id="5_si1x5"]
-[node name="Inventory" type="Control" node_paths=PackedStringArray("_relics", "_notes", "_description", "_tabs")]
+[node name="Inventory" type="Control" node_paths=PackedStringArray("_relics", "_notes", "_description", "_tabs", "_moneyLabel")]
process_mode = 1
layout_mode = 3
anchors_preset = 15
@@ -15,9 +16,10 @@ grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_8rcwd")
_relics = NodePath("MarginContainer/InvenVBox/Tabs/INVENTORY_TAB_RELICS/MarginContainer/RelicBox/RelicGrid")
-_notes = NodePath("MarginContainer/InvenVBox/Tabs/INVENTORY_TAB_NOTES/MarginContainer/NotesBox/NotesGrid")
+_notes = NodePath("MarginContainer/InvenVBox/Tabs/INVENTORY_TAB_NOTES/SelectionBG/MarginContainer/NotesBox/NotesGrid")
_description = NodePath("MarginContainer/InvenVBox/DescBox/DescMargin/MarginContainer/Description")
_tabs = NodePath("MarginContainer/InvenVBox/Tabs")
+_moneyLabel = NodePath("MoneyContainer/MoneyFrame/MarginContainer/HBoxContainer/MoneyLabel")
[node name="Background" type="NinePatchRect" parent="."]
self_modulate = Color(1, 1, 1, 0.75)
@@ -71,21 +73,23 @@ patch_margin_top = 6
patch_margin_right = 6
patch_margin_bottom = 7
-[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/InvenVBox/Tabs/INVENTORY_TAB_NOTES"]
+[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/InvenVBox/Tabs/INVENTORY_TAB_NOTES/SelectionBG"]
layout_mode = 2
+offset_right = 620.0
+offset_bottom = 197.0
theme_override_constants/margin_left = 10
theme_override_constants/margin_top = 10
theme_override_constants/margin_right = 10
theme_override_constants/margin_bottom = 10
-[node name="NotesBox" type="ScrollContainer" parent="MarginContainer/InvenVBox/Tabs/INVENTORY_TAB_NOTES/MarginContainer"]
+[node name="NotesBox" type="ScrollContainer" parent="MarginContainer/InvenVBox/Tabs/INVENTORY_TAB_NOTES/SelectionBG/MarginContainer"]
layout_mode = 2
follow_focus = true
-[node name="NotesGrid" type="GridContainer" parent="MarginContainer/InvenVBox/Tabs/INVENTORY_TAB_NOTES/MarginContainer/NotesBox"]
+[node name="NotesGrid" type="GridContainer" parent="MarginContainer/InvenVBox/Tabs/INVENTORY_TAB_NOTES/SelectionBG/MarginContainer/NotesBox"]
layout_mode = 2
size_flags_vertical = 4
-columns = 5
+columns = 10
[node name="INVENTORY_TAB_RELICS" type="MarginContainer" parent="MarginContainer/InvenVBox/Tabs"]
visible = false
@@ -118,7 +122,7 @@ follow_focus = true
[node name="RelicGrid" type="GridContainer" parent="MarginContainer/InvenVBox/Tabs/INVENTORY_TAB_RELICS/MarginContainer/RelicBox"]
layout_mode = 2
size_flags_vertical = 4
-columns = 5
+columns = 10
[node name="DescBox" type="MarginContainer" parent="MarginContainer/InvenVBox"]
layout_mode = 2
@@ -168,3 +172,54 @@ size_flags_vertical = 1
autowrap_mode = 2
clip_text = true
text_overrun_behavior = 1
+
+[node name="MoneyContainer" type="MarginContainer" parent="."]
+layout_mode = 1
+anchors_preset = 1
+anchor_left = 1.0
+anchor_right = 1.0
+offset_left = -130.0
+offset_bottom = 34.0
+grow_horizontal = 0
+theme_override_constants/margin_top = 5
+theme_override_constants/margin_right = 10
+theme_override_constants/margin_bottom = 5
+
+[node name="MoneyFrame" type="NinePatchRect" parent="MoneyContainer"]
+layout_mode = 2
+texture = ExtResource("3_s6pj7")
+patch_margin_left = 7
+patch_margin_top = 7
+patch_margin_right = 7
+patch_margin_bottom = 7
+
+[node name="MarginContainer" type="MarginContainer" parent="MoneyContainer/MoneyFrame"]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+theme_override_constants/margin_right = 8
+
+[node name="HBoxContainer" type="HBoxContainer" parent="MoneyContainer/MoneyFrame/MarginContainer"]
+layout_mode = 2
+
+[node name="MarginContainer" type="MarginContainer" parent="MoneyContainer/MoneyFrame/MarginContainer/HBoxContainer"]
+layout_mode = 2
+theme_override_constants/margin_left = 6
+
+[node name="TextureRect" type="TextureRect" parent="MoneyContainer/MoneyFrame/MarginContainer/HBoxContainer/MarginContainer"]
+layout_mode = 2
+size_flags_vertical = 4
+texture = ExtResource("5_si1x5")
+
+[node name="MoneyLabel" type="Label" parent="MoneyContainer/MoneyFrame/MarginContainer/HBoxContainer"]
+custom_minimum_size = Vector2(91, 0)
+layout_mode = 2
+size_flags_horizontal = 10
+size_flags_vertical = 1
+text = "0"
+horizontal_alignment = 2
+vertical_alignment = 1
+clip_text = true
diff --git a/Scenes/UI/Options/Credits.tscn b/Scenes/UI/Options/Credits.tscn
new file mode 100644
index 00000000..53deb38c
--- /dev/null
+++ b/Scenes/UI/Options/Credits.tscn
@@ -0,0 +1,64 @@
+[gd_scene load_steps=4 format=3 uid="uid://dgjmb0wllsj41"]
+
+[ext_resource type="Script" uid="uid://drt21hext7pm2" path="res://Scenes/UI/Options/Scripts/CreditsMenu.cs" id="1_n36fd"]
+[ext_resource type="Theme" uid="uid://d37e3tpsbxwak" path="res://Scenes/UI/Assets/GeneralTheme.tres" id="3_agb8c"]
+[ext_resource type="PackedScene" uid="uid://dfevfib11kou1" path="res://Scenes/ChartViewport/ChartViewport.tscn" id="3_ch0mg"]
+
+[node name="Credits" type="Control" node_paths=PackedStringArray("CreditsText", "_returnButton")]
+process_mode = 3
+layout_mode = 3
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+script = ExtResource("1_n36fd")
+CreditsText = NodePath("Node2D/Label")
+ScrollSpeed = 24.0
+RestartPositionY = 400.0
+_returnButton = NodePath("Return Button")
+
+[node name="Node2D2" type="Node2D" parent="."]
+position = Vector2(80, -12.26)
+scale = Vector2(2.255, 2.01)
+
+[node name="SubViewport" parent="Node2D2" instance=ExtResource("3_ch0mg")]
+offset_left = -57.1486
+offset_top = 5.0
+offset_right = 422.851
+offset_bottom = 185.0
+
+[node name="Node2D" type="Node2D" parent="."]
+
+[node name="Label" type="Label" parent="Node2D"]
+offset_left = 217.0
+offset_top = -3.0
+offset_right = 467.0
+offset_bottom = 410.0
+text = "Credits
+
+Programmers
+ Jarod Spanger: Project Lead
+Connor Lowe
+Raul Mojarro
+Thomas Wessel
+Michael Quinn
+
+Artists
+Ares Atlas
+Evelyn Fu
+Emily Wen
+
+Sound
+Sam Meyer: Composer"
+horizontal_alignment = 1
+
+[node name="Return Button" type="Button" parent="."]
+layout_mode = 2
+offset_left = 570.0
+offset_top = 314.0
+offset_right = 631.0
+offset_bottom = 351.0
+theme = ExtResource("3_agb8c")
+text = "Return"
+icon_alignment = 1
diff --git a/Scenes/UI/Options/HowToPlay.tscn b/Scenes/UI/Options/HowToPlay.tscn
index a67584e8..1883ffcf 100644
--- a/Scenes/UI/Options/HowToPlay.tscn
+++ b/Scenes/UI/Options/HowToPlay.tscn
@@ -11,10 +11,11 @@
[ext_resource type="Texture2D" uid="uid://c3chrsxrulapd" path="res://Classes/Notes/Assets/Note_PlayerBasic.png" id="6_uonw3"]
[ext_resource type="Texture2D" uid="uid://dg0lmu0pip4lr" path="res://Classes/Notes/Assets/Note_PlayerVampire.png" id="7_rbdrm"]
-[node name="CanvasLayer" type="Node2D" node_paths=PackedStringArray("_returnButton")]
+[node name="CanvasLayer" type="Node2D" node_paths=PackedStringArray("_returnButton", "_tutorialButton")]
process_mode = 3
script = ExtResource("1_kqayr")
-_returnButton = NodePath("Control/ReturnButton")
+_returnButton = NodePath("Control/HBoxContainer/ReturnButton")
+_tutorialButton = NodePath("Control/HBoxContainer/TutorialButton")
[node name="Background" type="NinePatchRect" parent="."]
offset_right = 640.0
@@ -41,15 +42,23 @@ theme_override_font_sizes/font_size = 32
text = "HOW_TO_PLAY"
horizontal_alignment = 1
-[node name="ReturnButton" type="Button" parent="Control"]
+[node name="HBoxContainer" type="HBoxContainer" parent="Control"]
layout_mode = 0
-offset_left = 202.5
offset_top = 314.0
-offset_right = 437.5
-offset_bottom = 345.0
+offset_right = 640.0
+offset_bottom = 354.0
+alignment = 1
+
+[node name="ReturnButton" type="Button" parent="Control/HBoxContainer"]
+layout_mode = 2
theme = ExtResource("3_xqve7")
text = "CONTROLS_RETURN_BUTTON"
+[node name="TutorialButton" type="Button" parent="Control/HBoxContainer"]
+layout_mode = 2
+theme = ExtResource("3_xqve7")
+text = "CONTROLS_TUTORIAL_BUTTON"
+
[node name="MarginContainer" type="Control" parent="Control"]
anchors_preset = 0
offset_left = 10.0
diff --git a/Scenes/UI/Options/Scripts/CreditsMenu.cs b/Scenes/UI/Options/Scripts/CreditsMenu.cs
new file mode 100644
index 00000000..a634515d
--- /dev/null
+++ b/Scenes/UI/Options/Scripts/CreditsMenu.cs
@@ -0,0 +1,89 @@
+using System;
+using FunkEngine;
+using Godot;
+
+public partial class CreditsMenu : Control, IFocusableMenu
+{
+ public static readonly string LoadPath = "res://Scenes/UI/Options/Credits.tscn";
+
+ [Export]
+ public Label CreditsText;
+
+ [Export]
+ public float ScrollSpeed = 50f;
+
+ public float FadeStartY = 0;
+ public float FadeEndY = -400f;
+
+ [Export]
+ public float RestartPositionY = 800f;
+
+ [Export]
+ private Button _returnButton;
+
+ public IFocusableMenu Prev { get; set; }
+
+ public override void _Ready()
+ {
+ if (CreditsText != null)
+ {
+ CreditsText.Position = new Vector2(CreditsText.Position.X, RestartPositionY);
+ FadeEndY = -CreditsText.Size.Y;
+ }
+ _returnButton.Pressed += ReturnToPrev;
+ _returnButton.GrabFocus();
+ }
+
+ public void ResumeFocus()
+ {
+ ProcessMode = ProcessModeEnum.Inherit;
+ _returnButton.GrabFocus();
+ }
+
+ public void PauseFocus()
+ {
+ ProcessMode = ProcessModeEnum.Disabled;
+ }
+
+ public void OpenMenu(IFocusableMenu prev)
+ {
+ Prev = prev;
+ Prev.PauseFocus();
+ _returnButton.GrabFocus();
+ }
+
+ public void ReturnToPrev()
+ {
+ Prev.ResumeFocus();
+ QueueFree();
+ }
+
+ public override void _Input(InputEvent @event)
+ {
+ if (@event.IsActionPressed("ui_cancel"))
+ {
+ ReturnToPrev();
+ GetViewport().SetInputAsHandled();
+ }
+ }
+
+ public override void _Process(double delta)
+ {
+ if (CreditsText == null)
+ return;
+
+ CreditsText.Position += Vector2.Up * (float)(ScrollSpeed * delta);
+
+ float alpha = Mathf.Clamp(
+ 1 - (CreditsText.GlobalPosition.Y - FadeStartY) / (FadeEndY - FadeStartY),
+ 0,
+ 1
+ );
+ CreditsText.Modulate = new Color(1, 1, 1, alpha);
+
+ if (CreditsText.GlobalPosition.Y < -CreditsText.Size.Y)
+ {
+ CreditsText.Position = new Vector2(CreditsText.Position.X, RestartPositionY);
+ }
+ }
+}
diff --git a/Scenes/UI/Options/Scripts/CreditsMenu.cs.uid b/Scenes/UI/Options/Scripts/CreditsMenu.cs.uid
new file mode 100644
index 00000000..af14f6ae
--- /dev/null
+++ b/Scenes/UI/Options/Scripts/CreditsMenu.cs.uid
@@ -0,0 +1 @@
+uid://drt21hext7pm2
diff --git a/Scenes/UI/Options/Scripts/HowToPlay.cs b/Scenes/UI/Options/Scripts/HowToPlay.cs
index cc49e553..9fae60c5 100644
--- a/Scenes/UI/Options/Scripts/HowToPlay.cs
+++ b/Scenes/UI/Options/Scripts/HowToPlay.cs
@@ -8,11 +8,16 @@ public partial class HowToPlay : Node2D, IFocusableMenu
[Export]
private Button _returnButton;
+ [Export]
+ private Button _tutorialButton;
+
public IFocusableMenu Prev { get; set; }
public override void _Ready()
{
_returnButton.Pressed += ReturnToPrev;
+ _tutorialButton.Pressed += DoTutorial;
+ _tutorialButton.Visible = !StageProducer.IsInitialized;
}
public void ResumeFocus()
@@ -39,9 +44,15 @@ public void ReturnToPrev()
QueueFree();
}
+ private void DoTutorial()
+ {
+ SaveSystem.UpdateConfig(SaveSystem.ConfigSettings.FirstTime, true);
+ StageProducer.LiveInstance.TransitionStage(Stages.Map);
+ }
+
public override void _Input(InputEvent @event)
{
- if (!GetWindow().HasFocus())
+ if (ControlSettings.IsOutOfFocus(this))
{
GetViewport().SetInputAsHandled();
return;
diff --git a/Scenes/UI/Options/Scripts/OptionsMenu.cs b/Scenes/UI/Options/Scripts/OptionsMenu.cs
index 22eeb316..b709adc5 100644
--- a/Scenes/UI/Options/Scripts/OptionsMenu.cs
+++ b/Scenes/UI/Options/Scripts/OptionsMenu.cs
@@ -50,7 +50,7 @@ public override void _Ready()
public override void _Input(InputEvent @event)
{
- if (!GetWindow().HasFocus())
+ if (ControlSettings.IsOutOfFocus(this))
{
GetViewport().SetInputAsHandled();
return;
@@ -124,4 +124,12 @@ private void OpenHowToPlay()
AddChild(howtoPlay);
howtoPlay.OpenMenu(this);
}
+
+ private void OpenCredits()
+ {
+ CreditsMenu creditsMenu = GD.Load(CreditsMenu.LoadPath)
+ .Instantiate();
+ AddChild(creditsMenu);
+ creditsMenu.OpenMenu(this);
+ }
}
diff --git a/Scenes/UI/Pause.tscn b/Scenes/UI/Pause.tscn
index aafcd686..2ca7b9aa 100644
--- a/Scenes/UI/Pause.tscn
+++ b/Scenes/UI/Pause.tscn
@@ -6,7 +6,7 @@
[ext_resource type="Theme" uid="uid://d37e3tpsbxwak" path="res://Scenes/UI/Assets/GeneralTheme.tres" id="4_lw4m2"]
[node name="PauseMenu" type="Control" node_paths=PackedStringArray("PauseButtons")]
-process_mode = 1
+process_mode = 3
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
@@ -14,7 +14,7 @@ anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_6jc8n")
-PauseButtons = [NodePath("MarginContainer/VBoxContainer/MarginContainer/ResumeButton"), NodePath("MarginContainer/VBoxContainer/MarginContainer4/OptionsButton"), NodePath("MarginContainer/VBoxContainer/MarginContainer2/QuitButton"), NodePath("MarginContainer/VBoxContainer/MarginContainer3/PlaceHolderButton")]
+PauseButtons = [NodePath("MarginContainer/VBoxContainer/MarginContainer/ResumeButton"), NodePath("MarginContainer/VBoxContainer/MarginContainer4/OptionsButton"), NodePath("MarginContainer/VBoxContainer/MarginContainer3/QuitButton"), NodePath("MarginContainer/VBoxContainer/MarginContainer2/PlaceHolderButton")]
[node name="Background" type="NinePatchRect" parent="."]
self_modulate = Color(1, 1, 1, 0.75)
@@ -62,7 +62,7 @@ theme_override_constants/margin_bottom = 20
[node name="ResumeButton" type="Button" parent="MarginContainer/VBoxContainer/MarginContainer"]
layout_mode = 2
-focus_neighbor_top = NodePath("../../MarginContainer3/PlaceHolderButton")
+focus_neighbor_top = NodePath("../../MarginContainer3/QuitButton")
focus_neighbor_bottom = NodePath("../../MarginContainer4/OptionsButton")
theme = ExtResource("4_lw4m2")
text = "ESCAPE_MENU_RESUME"
@@ -78,7 +78,7 @@ theme_override_constants/margin_bottom = 20
[node name="OptionsButton" type="Button" parent="MarginContainer/VBoxContainer/MarginContainer4"]
layout_mode = 2
focus_neighbor_top = NodePath("../../MarginContainer/ResumeButton")
-focus_neighbor_bottom = NodePath("../../MarginContainer2/QuitButton")
+focus_neighbor_bottom = NodePath("../../MarginContainer2/PlaceHolderButton")
theme = ExtResource("4_lw4m2")
text = "TITLE_OPTIONS"
@@ -90,12 +90,12 @@ theme_override_constants/margin_top = 20
theme_override_constants/margin_right = 20
theme_override_constants/margin_bottom = 20
-[node name="QuitButton" type="Button" parent="MarginContainer/VBoxContainer/MarginContainer2"]
+[node name="PlaceHolderButton" type="Button" parent="MarginContainer/VBoxContainer/MarginContainer2"]
layout_mode = 2
focus_neighbor_top = NodePath("../../MarginContainer4/OptionsButton")
-focus_neighbor_bottom = NodePath("../../MarginContainer3/PlaceHolderButton")
+focus_neighbor_bottom = NodePath("../../MarginContainer3/QuitButton")
theme = ExtResource("4_lw4m2")
-text = "ESCAPE_MENU_QUIT"
+text = "ESCAPE_MENU_TITLE"
[node name="MarginContainer3" type="MarginContainer" parent="MarginContainer/VBoxContainer"]
layout_mode = 2
@@ -105,9 +105,9 @@ theme_override_constants/margin_top = 20
theme_override_constants/margin_right = 20
theme_override_constants/margin_bottom = 20
-[node name="PlaceHolderButton" type="Button" parent="MarginContainer/VBoxContainer/MarginContainer3"]
+[node name="QuitButton" type="Button" parent="MarginContainer/VBoxContainer/MarginContainer3"]
layout_mode = 2
-focus_neighbor_top = NodePath("../../MarginContainer2/QuitButton")
+focus_neighbor_top = NodePath("../../MarginContainer2/PlaceHolderButton")
focus_neighbor_bottom = NodePath("../../MarginContainer/ResumeButton")
theme = ExtResource("4_lw4m2")
-text = "ESCAPE_MENU_TITLE"
+text = "ESCAPE_MENU_QUIT"
diff --git a/Scenes/UI/Remapping/ControlSettings.cs b/Scenes/UI/Remapping/ControlSettings.cs
index 279ebba4..b5714900 100644
--- a/Scenes/UI/Remapping/ControlSettings.cs
+++ b/Scenes/UI/Remapping/ControlSettings.cs
@@ -3,6 +3,7 @@
using System.Globalization;
using FunkEngine;
using Godot;
+using GodotSteam;
public partial class ControlSettings : Node2D, IFocusableMenu
{ //TODO: Add messages when an invalid key is attempted to be set.
@@ -19,6 +20,13 @@ public partial class ControlSettings : Node2D, IFocusableMenu
[Export]
private Label _remapLabel;
+ private string _keyboardRemap = "CONTROLS_CHOOSE_TEXT_KEYBOARD";
+ private string _controllerRemap = "CONTROLS_CHOOSE_TEXT_CONTROLLER";
+ private string _invalidMessage = "CONTROLS_CHOOSE_INVALID";
+ private string _duplicateInput = "CONTROLS_CHOOSE_DUPLICATE";
+
+ [Export]
+ private Label _remapDescription;
[Export]
private Timer _remapTimer;
@@ -122,6 +130,8 @@ public override void _Ready()
? 0
: 1;
+ _remapDescription.Text = Tr(_remapTabs.CurrentTab == 0 ? _keyboardRemap : _controllerRemap);
+
_remapTimer.Timeout += OnTimerEnd;
_remapTabs.TabChanged += (_) => ChangeInputType();
_closeButton.Pressed += ReturnToPrev;
@@ -197,6 +207,7 @@ private void ChangeInputType()
SaveSystem.ConfigSettings.InputType,
_remapTabs.CurrentTab == 0 ? KeyboardPrefix : JoyPrefix
);
+ _remapDescription.Text = Tr(_remapTabs.CurrentTab == 0 ? _keyboardRemap : _controllerRemap);
}
///
@@ -255,7 +266,7 @@ public override void _Input(InputEvent @event)
{
if (_remapPopup.Visible)
{
- if (@event.IsActionPressed("ui_cancel"))
+ if (@event.IsActionPressed("Pause"))
{
_remapTimer.Stop();
OnTimerEnd();
@@ -295,8 +306,14 @@ private void HandleRemapInput(InputEvent @event)
{
case true when @event is InputEventKey keyEvent:
{
- if (_invalidKeys.Contains(keyEvent.Keycode))
+ if (
+ _invalidKeys.Contains(keyEvent.Keycode)
+ || !ResourceLoader.Exists($"{IconPath}{CleanKeyboardText(@event.AsText())}.png")
+ )
+ {
+ _remapDescription.Text = Tr(_invalidMessage);
return;
+ }
string action = KeyboardPrefix + _chosenKey;
InputMap.ActionEraseEvents(action);
@@ -371,6 +388,22 @@ private static readonly Dictionary<
},
};
+ public static string GetTextureForInput(string inputMapName)
+ {
+ var events = InputMap.ActionGetEvents(inputMapName);
+ if (events.Count <= 0)
+ return null;
+ string textureName = events[0].AsText();
+
+ // Clean up the texture name
+ if (inputMapName.StartsWith(KeyboardPrefix))
+ textureName = CleanKeyboardText(textureName);
+ else
+ textureName = textureName.Replace("/", "");
+
+ return $"{IconPath}{textureName}.png";
+ }
+
///
/// Saves the key to the input based on its input name into the correct config setting.
///
@@ -425,9 +458,17 @@ evt is InputEventKey keyEvent
&& CleanKeyboardText(keyEvent.AsText()) == keyText
) || (evt is InputEventJoypadButton padEvent && padEvent.AsText() == keyText)
)
+ {
+ _remapDescription.Text = Tr(_duplicateInput);
return false;
+ }
}
}
return true;
}
+
+ public static bool IsOutOfFocus(Node asker)
+ {
+ return !asker.GetWindow().HasFocus() || SteamWhisperer.IsOverlayActive;
+ }
}
diff --git a/Scenes/UI/Remapping/Remap.tscn b/Scenes/UI/Remapping/Remap.tscn
index 81e3b860..adbf744d 100644
--- a/Scenes/UI/Remapping/Remap.tscn
+++ b/Scenes/UI/Remapping/Remap.tscn
@@ -19,12 +19,13 @@
[ext_resource type="Texture2D" uid="uid://cpxcg12lovxu5" path="res://Scenes/UI/Remapping/Assets/Joypad Button 4 (Back, Sony Select, Xbox Back, Nintendo -).png" id="16_s0mtp"]
[ext_resource type="Texture2D" uid="uid://djd6iw2g84bba" path="res://Scenes/UI/Assets/UI_CenterFrame.png" id="18_8iace"]
-[node name="Remap" type="Node2D" node_paths=PackedStringArray("_closeButton", "_remapPopup", "_remapLabel", "_remapTimer", "_remapTabs")]
+[node name="Remap" type="Node2D" node_paths=PackedStringArray("_closeButton", "_remapPopup", "_remapLabel", "_remapDescription", "_remapTimer", "_remapTabs")]
process_mode = 3
script = ExtResource("1_ir12b")
_closeButton = NodePath("Panel/TitleButton")
_remapPopup = NodePath("RemapPopup")
_remapLabel = NodePath("RemapPopup/Label2")
+_remapDescription = NodePath("RemapPopup/Label3")
_remapTimer = NodePath("RemapPopup/Timer")
_remapTabs = NodePath("Panel/TabContainer")
@@ -580,6 +581,14 @@ offset_bottom = 59.0
text = "CONTROLS_CHOOSE_BUTTON"
horizontal_alignment = 1
+[node name="Label3" type="Label" parent="RemapPopup"]
+layout_mode = 0
+offset_top = 75.0
+offset_right = 372.0
+offset_bottom = 98.0
+text = "CONTROLS_CHOOSE_TEXT_KEYBOARD"
+horizontal_alignment = 1
+
[node name="Label2" type="Label" parent="RemapPopup"]
layout_mode = 0
offset_top = 111.0
diff --git a/Scenes/UI/ScoreScreen.tscn b/Scenes/UI/ScoreScreen.tscn
new file mode 100644
index 00000000..5fa20eb6
--- /dev/null
+++ b/Scenes/UI/ScoreScreen.tscn
@@ -0,0 +1,224 @@
+[gd_scene load_steps=7 format=3 uid="uid://d3ulgssit1dcv"]
+
+[ext_resource type="Script" uid="uid://b5bw86d25uwdd" path="res://Scenes/UI/Scripts/ScoringScreen.cs" id="1_ma4hf"]
+[ext_resource type="Texture2D" uid="uid://ck16vyh1q68ri" path="res://Scenes/UI/Assets/UI_ForestBackground.png" id="1_ws5ov"]
+[ext_resource type="Texture2D" uid="uid://8u3xvcma81d" path="res://Scenes/UI/Assets/UI_CrystalFrame.png" id="2_usavq"]
+[ext_resource type="Texture2D" uid="uid://burj10os057fx" path="res://Scenes/UI/Assets/UI_CrystalFrameInset.png" id="3_usavq"]
+[ext_resource type="Theme" uid="uid://d37e3tpsbxwak" path="res://Scenes/UI/Assets/GeneralTheme.tres" id="4_1rsqt"]
+[ext_resource type="Texture2D" uid="uid://dyt1cvag13aik" path="res://SharedAssets/Money.png" id="5_0mn6u"]
+
+[node name="ScoreScreen" type="CanvasLayer" node_paths=PackedStringArray("_styleLabel", "_styleAmount", "_perfectsLabel", "_perfectsAmount", "_placedLabel", "_placedAmount", "_totalLabel", "_totalAmount", "_relicLabel", "_relicAmount", "_acceptButton")]
+process_mode = 3
+script = ExtResource("1_ma4hf")
+_styleLabel = NodePath("Bg/WindowMargin/PanelBg/VBoxContainer/MarginContainer/BottomPanelBg/HBoxContainer/LabelMargin/LabelVbox/StyleLabel")
+_styleAmount = NodePath("Bg/WindowMargin/PanelBg/VBoxContainer/MarginContainer/BottomPanelBg/HBoxContainer/ScoreMargin/LabelVbox/StyleLabel")
+_perfectsLabel = NodePath("Bg/WindowMargin/PanelBg/VBoxContainer/MarginContainer/BottomPanelBg/HBoxContainer/LabelMargin/LabelVbox/PerfectLabel")
+_perfectsAmount = NodePath("Bg/WindowMargin/PanelBg/VBoxContainer/MarginContainer/BottomPanelBg/HBoxContainer/ScoreMargin/LabelVbox/PerfectLabel")
+_placedLabel = NodePath("Bg/WindowMargin/PanelBg/VBoxContainer/MarginContainer/BottomPanelBg/HBoxContainer/LabelMargin/LabelVbox/PlacedLabel")
+_placedAmount = NodePath("Bg/WindowMargin/PanelBg/VBoxContainer/MarginContainer/BottomPanelBg/HBoxContainer/ScoreMargin/LabelVbox/PlacedLabel")
+_totalLabel = NodePath("Bg/WindowMargin/PanelBg/VBoxContainer/MarginContainer/BottomPanelBg/HBoxContainer/LabelMargin/LabelVbox/TotalLabel")
+_totalAmount = NodePath("Bg/WindowMargin/PanelBg/VBoxContainer/MarginContainer/BottomPanelBg/HBoxContainer/ScoreMargin/LabelVbox/HBoxContainer/TotalLabel")
+_relicLabel = NodePath("Bg/WindowMargin/PanelBg/VBoxContainer/MarginContainer/BottomPanelBg/HBoxContainer/LabelMargin/LabelVbox/RelicLabel")
+_relicAmount = NodePath("Bg/WindowMargin/PanelBg/VBoxContainer/MarginContainer/BottomPanelBg/HBoxContainer/ScoreMargin/LabelVbox/RelicLabel")
+_acceptButton = NodePath("Bg/WindowMargin/PanelBg/VBoxContainer/ButtonMargin/AcceptButton")
+
+[node name="Bg" type="NinePatchRect" parent="."]
+self_modulate = Color(1, 1, 1, 0.75)
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+texture = ExtResource("1_ws5ov")
+patch_margin_left = 100
+patch_margin_top = 100
+patch_margin_right = 102
+patch_margin_bottom = 100
+
+[node name="WindowMargin" type="MarginContainer" parent="Bg"]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+theme_override_constants/margin_left = 175
+theme_override_constants/margin_top = 50
+theme_override_constants/margin_right = 175
+theme_override_constants/margin_bottom = 50
+
+[node name="PanelBg" type="NinePatchRect" parent="Bg/WindowMargin"]
+self_modulate = Color(1, 1, 1, 0.75)
+layout_mode = 2
+texture = ExtResource("2_usavq")
+patch_margin_left = 30
+patch_margin_top = 10
+patch_margin_right = 20
+patch_margin_bottom = 27
+
+[node name="VBoxContainer" type="VBoxContainer" parent="Bg/WindowMargin/PanelBg"]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+
+[node name="TopPanelBg" type="NinePatchRect" parent="Bg/WindowMargin/PanelBg/VBoxContainer"]
+self_modulate = Color(1, 1, 1, 0.5)
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_vertical = 3
+size_flags_stretch_ratio = 0.25
+texture = ExtResource("2_usavq")
+patch_margin_left = 30
+patch_margin_top = 10
+patch_margin_right = 20
+patch_margin_bottom = 27
+
+[node name="Title" type="CenterContainer" parent="Bg/WindowMargin/PanelBg/VBoxContainer/TopPanelBg"]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+
+[node name="TitleText" type="RichTextLabel" parent="Bg/WindowMargin/PanelBg/VBoxContainer/TopPanelBg/Title"]
+custom_minimum_size = Vector2(400, 47)
+layout_mode = 2
+theme_override_font_sizes/normal_font_size = 32
+bbcode_enabled = true
+text = "SCORING_SCENE_TITLE"
+horizontal_alignment = 1
+vertical_alignment = 1
+
+[node name="MarginContainer" type="MarginContainer" parent="Bg/WindowMargin/PanelBg/VBoxContainer"]
+layout_mode = 2
+size_flags_vertical = 3
+theme_override_constants/margin_left = 4
+theme_override_constants/margin_top = 0
+theme_override_constants/margin_right = 4
+theme_override_constants/margin_bottom = 4
+
+[node name="BottomPanelBg" type="NinePatchRect" parent="Bg/WindowMargin/PanelBg/VBoxContainer/MarginContainer"]
+self_modulate = Color(1, 1, 1, 0.5)
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_vertical = 3
+texture = ExtResource("3_usavq")
+patch_margin_left = 30
+patch_margin_top = 10
+patch_margin_right = 20
+patch_margin_bottom = 27
+
+[node name="HBoxContainer" type="HBoxContainer" parent="Bg/WindowMargin/PanelBg/VBoxContainer/MarginContainer/BottomPanelBg"]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+size_flags_vertical = 3
+
+[node name="LabelMargin" type="MarginContainer" parent="Bg/WindowMargin/PanelBg/VBoxContainer/MarginContainer/BottomPanelBg/HBoxContainer"]
+layout_mode = 2
+size_flags_horizontal = 3
+theme_override_constants/margin_left = 8
+theme_override_constants/margin_top = 8
+theme_override_constants/margin_right = 8
+theme_override_constants/margin_bottom = 8
+
+[node name="LabelVbox" type="VBoxContainer" parent="Bg/WindowMargin/PanelBg/VBoxContainer/MarginContainer/BottomPanelBg/HBoxContainer/LabelMargin"]
+layout_mode = 2
+size_flags_horizontal = 3
+theme_override_constants/separation = 11
+alignment = 1
+
+[node name="StyleLabel" type="Label" parent="Bg/WindowMargin/PanelBg/VBoxContainer/MarginContainer/BottomPanelBg/HBoxContainer/LabelMargin/LabelVbox"]
+layout_mode = 2
+text = "SCORING_STYLE"
+
+[node name="PerfectLabel" type="Label" parent="Bg/WindowMargin/PanelBg/VBoxContainer/MarginContainer/BottomPanelBg/HBoxContainer/LabelMargin/LabelVbox"]
+layout_mode = 2
+text = "SCORING_PERFECTS"
+
+[node name="PlacedLabel" type="Label" parent="Bg/WindowMargin/PanelBg/VBoxContainer/MarginContainer/BottomPanelBg/HBoxContainer/LabelMargin/LabelVbox"]
+layout_mode = 2
+text = "SCORING_PLACED"
+
+[node name="RelicLabel" type="Label" parent="Bg/WindowMargin/PanelBg/VBoxContainer/MarginContainer/BottomPanelBg/HBoxContainer/LabelMargin/LabelVbox"]
+layout_mode = 2
+text = "SCORING_RELICS"
+
+[node name="Placeholder" type="Label" parent="Bg/WindowMargin/PanelBg/VBoxContainer/MarginContainer/BottomPanelBg/HBoxContainer/LabelMargin/LabelVbox"]
+layout_mode = 2
+
+[node name="TotalLabel" type="Label" parent="Bg/WindowMargin/PanelBg/VBoxContainer/MarginContainer/BottomPanelBg/HBoxContainer/LabelMargin/LabelVbox"]
+layout_mode = 2
+text = "SCORING_TOTAL"
+
+[node name="ScoreMargin" type="MarginContainer" parent="Bg/WindowMargin/PanelBg/VBoxContainer/MarginContainer/BottomPanelBg/HBoxContainer"]
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_stretch_ratio = 0.25
+theme_override_constants/margin_left = 8
+theme_override_constants/margin_top = 8
+theme_override_constants/margin_right = 8
+theme_override_constants/margin_bottom = 8
+
+[node name="LabelVbox" type="VBoxContainer" parent="Bg/WindowMargin/PanelBg/VBoxContainer/MarginContainer/BottomPanelBg/HBoxContainer/ScoreMargin"]
+layout_mode = 2
+size_flags_horizontal = 3
+theme_override_constants/separation = 11
+alignment = 1
+
+[node name="StyleLabel" type="Label" parent="Bg/WindowMargin/PanelBg/VBoxContainer/MarginContainer/BottomPanelBg/HBoxContainer/ScoreMargin/LabelVbox"]
+layout_mode = 2
+text = "999"
+horizontal_alignment = 2
+
+[node name="PerfectLabel" type="Label" parent="Bg/WindowMargin/PanelBg/VBoxContainer/MarginContainer/BottomPanelBg/HBoxContainer/ScoreMargin/LabelVbox"]
+layout_mode = 2
+text = "999"
+horizontal_alignment = 2
+
+[node name="PlacedLabel" type="Label" parent="Bg/WindowMargin/PanelBg/VBoxContainer/MarginContainer/BottomPanelBg/HBoxContainer/ScoreMargin/LabelVbox"]
+layout_mode = 2
+text = "999"
+horizontal_alignment = 2
+
+[node name="RelicLabel" type="Label" parent="Bg/WindowMargin/PanelBg/VBoxContainer/MarginContainer/BottomPanelBg/HBoxContainer/ScoreMargin/LabelVbox"]
+layout_mode = 2
+text = "999"
+horizontal_alignment = 2
+
+[node name="Placeholder" type="Label" parent="Bg/WindowMargin/PanelBg/VBoxContainer/MarginContainer/BottomPanelBg/HBoxContainer/ScoreMargin/LabelVbox"]
+layout_mode = 2
+horizontal_alignment = 2
+
+[node name="HBoxContainer" type="HBoxContainer" parent="Bg/WindowMargin/PanelBg/VBoxContainer/MarginContainer/BottomPanelBg/HBoxContainer/ScoreMargin/LabelVbox"]
+layout_mode = 2
+
+[node name="MoneyIcon" type="TextureRect" parent="Bg/WindowMargin/PanelBg/VBoxContainer/MarginContainer/BottomPanelBg/HBoxContainer/ScoreMargin/LabelVbox/HBoxContainer"]
+layout_mode = 2
+size_flags_horizontal = 0
+size_flags_vertical = 4
+texture = ExtResource("5_0mn6u")
+
+[node name="TotalLabel" type="Label" parent="Bg/WindowMargin/PanelBg/VBoxContainer/MarginContainer/BottomPanelBg/HBoxContainer/ScoreMargin/LabelVbox/HBoxContainer"]
+layout_mode = 2
+size_flags_horizontal = 10
+text = "999"
+horizontal_alignment = 2
+
+[node name="ButtonMargin" type="MarginContainer" parent="Bg/WindowMargin/PanelBg/VBoxContainer"]
+layout_mode = 2
+theme_override_constants/margin_top = -3
+theme_override_constants/margin_bottom = 9
+
+[node name="AcceptButton" type="Button" parent="Bg/WindowMargin/PanelBg/VBoxContainer/ButtonMargin"]
+layout_mode = 2
+size_flags_horizontal = 6
+theme = ExtResource("4_1rsqt")
+text = "CHEST_ROOM_ACCEPT"
diff --git a/Scenes/UI/Scripts/DisplayButton.cs b/Scenes/UI/Scripts/DisplayButton.cs
index 54936e61..a07c1496 100644
--- a/Scenes/UI/Scripts/DisplayButton.cs
+++ b/Scenes/UI/Scripts/DisplayButton.cs
@@ -5,27 +5,17 @@
*/
public partial class DisplayButton : Button
{
- //TODO: Make various menus change descriptions when focus changes, instead of on click.
public static readonly string LoadPath = "res://Scenes/UI/DisplayButton.tscn";
[Export]
public Texture2D Texture;
- [Export]
- public string Description;
-
[Export]
public string DisplayName;
- public void Display(
- Texture2D texture,
- string description,
- string name,
- bool focusHandling = false
- )
+ public void Display(Texture2D texture, string name, bool focusHandling = false)
{
Texture = texture;
- Description = description;
DisplayName = name;
Icon = Texture;
diff --git a/Scenes/UI/Scripts/Inventory.cs b/Scenes/UI/Scripts/Inventory.cs
index 2c2bb84c..71dd4d93 100644
--- a/Scenes/UI/Scripts/Inventory.cs
+++ b/Scenes/UI/Scripts/Inventory.cs
@@ -17,6 +17,9 @@ public partial class Inventory : Control, IFocusableMenu
[Export]
private TabContainer _tabs;
+ [Export]
+ private Label _moneyLabel;
+
public IFocusableMenu Prev { get; set; }
private static readonly string[] TabNames = new[] { "NOTE", "RELIC" };
@@ -25,6 +28,8 @@ private void Display(PlayerStats playerStats)
AddDisplayButtons(playerStats.CurRelics, _relics);
AddDisplayButtons(playerStats.CurNotes, _notes);
+ _moneyLabel.Text = playerStats.Money.ToString();
+
_tabs.TabChanged += ClearDescription;
}
@@ -34,7 +39,7 @@ private void AddDisplayButtons(IDisplayable[] displayables, Node parentNode)
{
var newButton = GD.Load(DisplayButton.LoadPath)
.Instantiate();
- newButton.Display(item.Texture, item.Tooltip, item.Name, true);
+ newButton.Display(item.Texture, item.Name, true);
newButton.Pressed += () =>
{
DoDescription(newButton);
@@ -50,7 +55,7 @@ public override void _Process(double delta)
public override void _Input(InputEvent @event)
{
- if (!GetWindow().HasFocus())
+ if (ControlSettings.IsOutOfFocus(this))
{
GetViewport().SetInputAsHandled();
return;
diff --git a/Scenes/UI/Scripts/MenuModule.cs b/Scenes/UI/Scripts/MenuModule.cs
index 9e39b307..f0b9ef8c 100644
--- a/Scenes/UI/Scripts/MenuModule.cs
+++ b/Scenes/UI/Scripts/MenuModule.cs
@@ -1,5 +1,6 @@
using FunkEngine;
using Godot;
+using GodotSteam;
/**
* Simple system for any scene which should display pause and inventory screen.
@@ -11,6 +12,9 @@ public partial class MenuModule : CanvasLayer, IFocusableMenu
private Control _lastFocused { get; set; }
+ [Export]
+ bool _ignorePause = false;
+
public override void _Ready()
{
Input.JoyConnectionChanged += (device, connected) =>
@@ -19,11 +23,19 @@ public override void _Ready()
OpenPauseMenu(); //Pause on disconnection
};
GetTree().GetRoot().FocusExited += OpenPauseMenu;
+ Steam.OverlayToggled += OpenPauseMenu;
+ }
+
+ public override void _ExitTree()
+ {
+ Steam.OverlayToggled -= OpenPauseMenu;
}
public void ResumeFocus()
{
CurSceneNode.ProcessMode = ProcessModeEnum.Inherit;
+ if (CurSceneNode is BattleDirector { HasPlayed: true } bd && !GetTree().IsPaused())
+ bd.StartCountdown();
_lastFocused?.GrabFocus();
}
@@ -47,7 +59,7 @@ public void ReturnToPrev()
public override void _Input(InputEvent @event)
{
- if (!GetWindow().HasFocus())
+ if (ControlSettings.IsOutOfFocus(this))
{
GetViewport().SetInputAsHandled();
return;
@@ -67,8 +79,16 @@ public override void _Input(InputEvent @event)
}
}
+ private void OpenPauseMenu(bool active, bool initiated = false, uint id = 0)
+ {
+ if (active)
+ OpenPauseMenu();
+ }
+
private void OpenPauseMenu()
{
+ if (_ignorePause)
+ return;
if (CurSceneNode.ProcessMode == ProcessModeEnum.Disabled)
return;
var pauseMenu = GD.Load(PauseMenu.LoadPath).Instantiate();
diff --git a/Scenes/UI/Scripts/PauseMenu.cs b/Scenes/UI/Scripts/PauseMenu.cs
index afe5b95f..6fe23493 100644
--- a/Scenes/UI/Scripts/PauseMenu.cs
+++ b/Scenes/UI/Scripts/PauseMenu.cs
@@ -29,7 +29,7 @@ private void OpenOptions()
public override void _Input(InputEvent @event)
{
- if (!GetWindow().HasFocus())
+ if (ControlSettings.IsOutOfFocus(this))
{
GetViewport().SetInputAsHandled();
return;
diff --git a/Scenes/UI/Scripts/RewardSelect.cs b/Scenes/UI/Scripts/RewardSelect.cs
index f06fcb13..01ee7007 100644
--- a/Scenes/UI/Scripts/RewardSelect.cs
+++ b/Scenes/UI/Scripts/RewardSelect.cs
@@ -55,7 +55,11 @@ private void Initialize(PlayerStats player, int amount, Stages type)
public override void _Process(double delta)
{
- _acceptButton.Visible = (_selection != null);
+ _acceptButton.Disabled = (_selection == null);
+ if (GetViewport().GuiGetFocusOwner() == null)
+ {
+ _skipButton.GrabFocus();
+ }
}
private void AddButton(IDisplayable displayable)
@@ -63,7 +67,7 @@ private void AddButton(IDisplayable displayable)
var button = GD.Load(DisplayButton.LoadPath).Instantiate();
button.SetButtonGroup(_rewardGroup);
button.ToggleMode = true;
- button.Display(displayable.Texture, displayable.Tooltip, displayable.Name);
+ button.Display(displayable.Texture, displayable.Name);
button.Pressed += () => SetSelection(displayable);
button.FocusEntered += () => ChangeDescription(displayable);
ButtonContainer.AddChild(button);
@@ -71,20 +75,32 @@ private void AddButton(IDisplayable displayable)
private void GenerateSelection()
{
- if (_roomType == Stages.Battle)
+ switch (_roomType)
{
- GenerateNoteChoices(_amount);
- }
- else
- {
- GenerateRelicChoices(_amount);
+ case Stages.Battle:
+ GenerateNoteChoices(_amount);
+ break;
+ case Stages.Boss:
+ GenerateRelicChoices(_amount, [1, 5, 5, 5, 0]);
+ break;
+ default:
+ GenerateRelicChoices(_amount);
+ break;
}
}
- private void GenerateRelicChoices(int amount = 1)
+ private void GenerateRelicChoices(int amount = 1, int[] addedOdds = null)
{
if (amount < 1)
GD.PushError("Error: In RewardSelect: amount < 1");
+ int[] fullOdds = new int[_player.RarityOdds.Length];
+ bool extraOdds = addedOdds != null && addedOdds.Length == _player.RarityOdds.Length;
+ for (int i = 0; i < _player.RarityOdds.Length; i++)
+ {
+ fullOdds[i] = _player.RarityOdds[i];
+ if (extraOdds)
+ fullOdds[i] += addedOdds[i];
+ }
_rChoices = Scribe.GetRandomRelics(
amount,
StageProducer.CurRoom + 10 * _curRerolls,
diff --git a/Scenes/UI/Scripts/ScoringScreen.cs b/Scenes/UI/Scripts/ScoringScreen.cs
new file mode 100644
index 00000000..a37d24e2
--- /dev/null
+++ b/Scenes/UI/Scripts/ScoringScreen.cs
@@ -0,0 +1,167 @@
+using System;
+using System.Linq;
+using Godot;
+
+public partial class ScoringScreen : CanvasLayer
+{
+ public static readonly string LoadPath = "res://Scenes/UI/ScoreScreen.tscn";
+
+ public struct ScoreGuide
+ {
+ public int BaseMoney = 0;
+ public int TotalHits = 0;
+ public int TotalPerfects = 0;
+ public int TotalPlaced = 0;
+ public int RelicBonus = 0;
+ public float StartingHealth = 0;
+ public float EndingHealth = 0;
+
+ public ScoreGuide(int baseMoney, float startingHealth)
+ {
+ BaseMoney = baseMoney;
+ StartingHealth = startingHealth;
+ }
+
+ public void IncreaseBase(int amount)
+ {
+ BaseMoney += amount;
+ }
+
+ public void IncHits()
+ {
+ TotalHits++;
+ }
+
+ public void IncPerfects()
+ {
+ TotalPerfects++;
+ }
+
+ public void IncPlaced()
+ {
+ TotalPlaced++;
+ }
+
+ public void IncRelicBonus(int amount)
+ {
+ RelicBonus += amount;
+ }
+
+ public void SetEndHp(float amount)
+ {
+ EndingHealth = amount;
+ }
+ }
+
+ [Export]
+ private Label _styleLabel;
+
+ [Export]
+ private Label _styleAmount;
+
+ [Export]
+ private Label _perfectsLabel;
+
+ [Export]
+ private Label _perfectsAmount;
+
+ [Export]
+ private Label _placedLabel;
+
+ [Export]
+ private Label _placedAmount;
+
+ [Export]
+ private Label _totalLabel;
+
+ [Export]
+ private Label _totalAmount;
+
+ [Export]
+ private Label _relicLabel;
+
+ [Export]
+ private Label _relicAmount;
+
+ [Export]
+ private Button _acceptButton;
+
+ private int _totalBaseMoney;
+ private float _perfectMulti;
+ private float _placedMulti;
+ private int _relicBonus;
+ private int FinalMoney => (int)(_totalBaseMoney * _perfectMulti * _placedMulti) + _relicBonus;
+
+ public delegate void FinishedHandler();
+ public event FinishedHandler Finished;
+
+ public override void _Ready()
+ {
+ _acceptButton.Pressed += FinishScoring;
+ }
+
+ public override void _Process(double delta)
+ {
+ _acceptButton.GrabFocus();
+ }
+
+ public static ScoringScreen CreateScore(Node2D parent, ScoreGuide info)
+ {
+ ScoringScreen result = GD.Load(LoadPath).Instantiate();
+ parent.AddChild(result);
+ result.GenerateScore(info);
+ parent.ProcessMode = ProcessModeEnum.Disabled;
+
+ return result;
+ }
+
+ private void GenerateScore(ScoreGuide info)
+ {
+ //Arbitrarily deciding on money calcs
+ _totalBaseMoney = CalcTotalBase(info);
+
+ //Multis
+ _perfectMulti = 1 + (float)info.TotalPerfects / (info.TotalHits - info.TotalPlaced);
+ if (float.IsNaN(_perfectMulti))
+ _perfectMulti = 1;
+ _placedMulti = Math.Max(2 - (float)Math.Abs(info.TotalPlaced - info.BaseMoney) / 10, 1);
+ _relicBonus = info.RelicBonus;
+ DrawScoreLabels();
+ }
+
+ private int CalcTotalBase(ScoreGuide info)
+ {
+ int result = info.BaseMoney;
+ result += (int)((info.EndingHealth / info.StartingHealth) * 10);
+ result += StageProducer.GlobalRng.RandiRange(0, 3);
+ return result;
+ }
+
+ private void DrawScoreLabels()
+ {
+ if (_relicBonus <= 0)
+ {
+ _relicLabel.Visible = false;
+ _relicAmount.Visible = false;
+ }
+ _styleAmount.Text = $"{_totalBaseMoney}";
+ _perfectsAmount.Text = $"X{_perfectMulti:0.00}";
+ _placedAmount.Text = $"X{_placedMulti:0.00}";
+ _relicAmount.Text = $"+{_relicBonus}";
+ _totalAmount.Text = $"{FinalMoney}";
+ }
+
+ private void FinishScoring()
+ {
+ StageProducer.PlayerStats.Money += FinalMoney;
+
+ //Achievement check for 1k money
+ if (StageProducer.PlayerStats.Money >= 1000)
+ {
+ SteamWhisperer.PopAchievement("money");
+ }
+
+ Finished?.Invoke();
+ QueueFree();
+ }
+}
diff --git a/Scenes/UI/Scripts/ScoringScreen.cs.uid b/Scenes/UI/Scripts/ScoringScreen.cs.uid
new file mode 100644
index 00000000..e121e48f
--- /dev/null
+++ b/Scenes/UI/Scripts/ScoringScreen.cs.uid
@@ -0,0 +1 @@
+uid://b5bw86d25uwdd
diff --git a/Scenes/UI/TitleScreen/Assets/TitleScreenFont.TTF b/Scenes/UI/TitleScreen/Assets/TitleScreenFont.TTF
index 4b93740c..43b1c950 100644
Binary files a/Scenes/UI/TitleScreen/Assets/TitleScreenFont.TTF and b/Scenes/UI/TitleScreen/Assets/TitleScreenFont.TTF differ
diff --git a/Scenes/UI/TitleScreen/SceneChange.tscn b/Scenes/UI/TitleScreen/SceneChange.tscn
deleted file mode 100644
index b1d179da..00000000
--- a/Scenes/UI/TitleScreen/SceneChange.tscn
+++ /dev/null
@@ -1,31 +0,0 @@
-[gd_scene load_steps=2 format=3 uid="uid://dbeplni2du158"]
-
-[ext_resource type="Script" uid="uid://cahjluc6v7ked" path="res://Scenes/UI/TitleScreen/Scripts/SceneChange.cs" id="1_n6d5u"]
-
-[node name="Control" type="Control"]
-layout_mode = 3
-anchors_preset = 0
-offset_right = 40.0
-offset_bottom = 40.0
-
-[node name="Node2D" type="Node2D" parent="."]
-
-[node name="StartButton" type="Button" parent="."]
-layout_mode = 0
-offset_left = 120.0
-offset_top = 56.0
-offset_right = 128.0
-offset_bottom = 64.0
-scale = Vector2(2.48, 2.48)
-text = "start battle"
-script = ExtResource("1_n6d5u")
-
-[node name="ExitButton" type="Button" parent="."]
-layout_mode = 0
-offset_left = 471.0
-offset_top = 95.0
-offset_right = 508.0
-offset_bottom = 126.0
-scale = Vector2(2.56, 2.56)
-text = "exit"
-script = ExtResource("1_n6d5u")
diff --git a/Scenes/UI/TitleScreen/Scripts/TitleScreen.cs b/Scenes/UI/TitleScreen/Scripts/TitleScreen.cs
index 4f1647b7..3019809a 100644
--- a/Scenes/UI/TitleScreen/Scripts/TitleScreen.cs
+++ b/Scenes/UI/TitleScreen/Scripts/TitleScreen.cs
@@ -4,8 +4,12 @@
public partial class TitleScreen : Control, IFocusableMenu
{
public static readonly string LoadPath = "res://Scenes/UI/TitleScreen/TitleScreen.tscn";
+ private static readonly string EffectsLoadPath =
+ "res://Scenes/UI/TitleScreen/TitleScreenEffects.tscn";
[Export]
+ private Node _effectsPlaceholder;
+ private Node _effectsRoot;
public PointLight2D TextLight;
[Export]
@@ -14,6 +18,20 @@ public partial class TitleScreen : Control, IFocusableMenu
private Control _focused;
public IFocusableMenu Prev { get; set; }
+ public override void _UnhandledInput(InputEvent @event)
+ {
+ if (@event is InputEventKey eventKey && eventKey.Pressed && !eventKey.Echo)
+ {
+ if (eventKey.Keycode == Key.Key0)
+ {
+ SteamWhisperer.ResetAll();
+ SaveSystem.ClearSave();
+ SaveSystem.ClearConfig();
+ StageProducer.LiveInstance.InitFromCfg();
+ }
+ }
+ }
+
public override void _EnterTree()
{
BgAudioPlayer.LiveInstance.PlayLevelMusic();
@@ -21,10 +39,15 @@ public override void _EnterTree()
public override void _Ready()
{
- TweenLight();
Options.Pressed += OpenOptions;
}
+ public override void _Process(double delta)
+ {
+ if (TextLight == null)
+ InitEffects();
+ }
+
public void ResumeFocus()
{
ProcessMode = ProcessModeEnum.Inherit;
@@ -55,6 +78,15 @@ private void OpenOptions()
optionsMenu.OpenMenu(this);
}
+ private void InitEffects()
+ {
+ if (_effectsPlaceholder is not InstancePlaceholder placeholder)
+ return;
+ _effectsRoot = placeholder.CreateInstance(true, GD.Load(EffectsLoadPath));
+ TextLight = _effectsRoot.GetNode("TextLight");
+ TweenLight();
+ }
+
private void TweenLight()
{
var tween = CreateTween();
diff --git a/Scenes/UI/TitleScreen/TitleScreen.tscn b/Scenes/UI/TitleScreen/TitleScreen.tscn
index 1bd9f8c2..96a32b3a 100644
--- a/Scenes/UI/TitleScreen/TitleScreen.tscn
+++ b/Scenes/UI/TitleScreen/TitleScreen.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=22 format=3 uid="uid://bm41yti6ij2j"]
+[gd_scene load_steps=17 format=3 uid="uid://bm41yti6ij2j"]
[ext_resource type="Texture2D" uid="uid://b0tvsewgnf2x7" path="res://icon.svg" id="1_r5xy8"]
[ext_resource type="Script" uid="uid://ce7anmo6cerw3" path="res://Scenes/UI/TitleScreen/Scripts/TitleScreen.cs" id="1_r22ha"]
@@ -6,16 +6,12 @@
[ext_resource type="Texture2D" uid="uid://de2j543j83hmh" path="res://Scenes/UI/TitleScreen/Assets/Background_BackTree.png" id="2_4luva"]
[ext_resource type="Script" uid="uid://cahjluc6v7ked" path="res://Scenes/UI/TitleScreen/Scripts/SceneChange.cs" id="2_7f3m6"]
[ext_resource type="Texture2D" uid="uid://b6fkei0i83vte" path="res://SharedAssets/Character1.png" id="2_cf582"]
-[ext_resource type="Texture2D" uid="uid://iqbqsiyjd3uq" path="res://Scenes/UI/TitleScreen/Assets/2D_Shadow_Map.webp" id="2_kw6qk"]
[ext_resource type="Texture2D" uid="uid://dat1eoyl3do4e" path="res://Scenes/UI/TitleScreen/Assets/Background_FrontTree.png" id="3_hvvt6"]
[ext_resource type="Texture2D" uid="uid://d3rxic3mi8jwb" path="res://Scenes/UI/TitleScreen/Assets/Background_MidTree.png" id="4_ui8kj"]
[ext_resource type="Texture2D" uid="uid://bj8dxrlwuwrv4" path="res://Scenes/UI/TitleScreen/Assets/Background_Moon.png" id="5_squvs"]
[ext_resource type="Shader" uid="uid://carejaurqw2we" path="res://Scenes/UI/TitleScreen/Assets/TransparentStars.gdshader" id="5_x5dhk"]
[ext_resource type="FontFile" uid="uid://dlwfb7kb7pd76" path="res://Scenes/UI/TitleScreen/Assets/TitleScreenFont.TTF" id="8_gkfev"]
-[ext_resource type="Texture2D" uid="uid://hfxynr5jdgsp" path="res://Scenes/NoteManager/Assets/New_Arrow.png" id="10_4hnj8"]
[ext_resource type="Shader" uid="uid://bxvlpwylcbfvm" path="res://Scenes/UI/TitleScreen/Assets/TitleFont.gdshader" id="11_ht0dv"]
-[ext_resource type="PackedScene" uid="uid://bi5iqbwpsd381" path="res://Scenes/Puppets/Enemies/BossBlood/Boss1.tscn" id="12_lng3a"]
-[ext_resource type="PackedScene" uid="uid://uvlux4t6h5de" path="res://Scenes/Puppets/Enemies/Parasifly/Parasifly.tscn" id="13_j3xa4"]
[ext_resource type="Theme" uid="uid://d37e3tpsbxwak" path="res://Scenes/UI/Assets/GeneralTheme.tres" id="13_v0au1"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_xhbhh"]
@@ -30,16 +26,7 @@ shader_parameter/height = 10.0
shader_parameter/speed = 2.0
shader_parameter/freq = 10.0
-[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_4croe"]
-particle_flag_disable_z = true
-emission_shape = 3
-emission_box_extents = Vector3(2.4, 5, 1)
-gravity = Vector3(-180, 0, 0)
-hue_variation_min = -1.0
-hue_variation_max = 1.0
-turbulence_enabled = true
-
-[node name="Title" type="Control" node_paths=PackedStringArray("TextLight", "Options")]
+[node name="Title" type="Control" node_paths=PackedStringArray("_effectsPlaceholder", "Options")]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
@@ -49,23 +36,10 @@ grow_vertical = 2
size_flags_horizontal = 3
size_flags_vertical = 3
script = ExtResource("1_r22ha")
-TextLight = NodePath("TextLight")
+_effectsPlaceholder = NodePath("Effects")
Options = NodePath("VBoxContainer/OptionsMargin/Options")
-[node name="MoonLight" type="PointLight2D" parent="."]
-position = Vector2(363, 37)
-energy = 2.0
-texture = ExtResource("2_kw6qk")
-texture_scale = 3.0
-
-[node name="TextLight" type="PointLight2D" parent="."]
-position = Vector2(320, 100)
-scale = Vector2(6, 2)
-color = Color(0.560784, 0, 1, 1)
-energy = 2.0
-range_item_cull_mask = 3
-texture = ExtResource("2_kw6qk")
-texture_scale = 0.5
+[node name="Effects" parent="." instance_placeholder="res://Scenes/UI/TitleScreen/TitleScreenEffects.tscn"]
[node name="Background" type="Node2D" parent="."]
modulate = Color(0.355314, 0.355314, 0.355314, 1)
@@ -183,7 +157,7 @@ theme = ExtResource("13_v0au1")
theme_override_font_sizes/font_size = 24
text = "TITLE_START"
script = ExtResource("2_7f3m6")
-ScenePath = 5
+ScenePath = 7
_startFocused = true
[node name="MarginContainer3" type="MarginContainer" parent="VBoxContainer/HBoxContainer"]
@@ -206,7 +180,7 @@ theme = ExtResource("13_v0au1")
theme_override_font_sizes/font_size = 24
text = "TITLE_CONTINUE"
script = ExtResource("2_7f3m6")
-ScenePath = 6
+ScenePath = 8
[node name="MarginContainer2" type="MarginContainer" parent="VBoxContainer/HBoxContainer"]
layout_mode = 2
@@ -227,7 +201,7 @@ theme = ExtResource("13_v0au1")
theme_override_font_sizes/font_size = 24
text = "TITLE_QUIT"
script = ExtResource("2_7f3m6")
-ScenePath = 4
+ScenePath = 6
[node name="OptionsMargin" type="MarginContainer" parent="VBoxContainer"]
layout_mode = 2
@@ -247,21 +221,3 @@ focus_neighbor_right = NodePath("../../HBoxContainer/MarginContainer2/Quit")
theme = ExtResource("13_v0au1")
theme_override_font_sizes/font_size = 24
text = "TITLE_OPTIONS"
-
-[node name="EnemPuppet" parent="." instance=ExtResource("12_lng3a")]
-visible = false
-position = Vector2(37, 186)
-
-[node name="EnemPuppet2" parent="." instance=ExtResource("13_j3xa4")]
-visible = false
-position = Vector2(572, 167)
-
-[node name="GPUParticles2D" type="GPUParticles2D" parent="."]
-light_mask = 0
-z_index = -1
-z_as_relative = false
-position = Vector2(643, 154)
-texture = ExtResource("10_4hnj8")
-lifetime = 15.0
-randomness = 1.0
-process_material = SubResource("ParticleProcessMaterial_4croe")
diff --git a/Scenes/UI/TitleScreen/TitleScreenEffects.tscn b/Scenes/UI/TitleScreen/TitleScreenEffects.tscn
new file mode 100644
index 00000000..c1398f02
--- /dev/null
+++ b/Scenes/UI/TitleScreen/TitleScreenEffects.tscn
@@ -0,0 +1,40 @@
+[gd_scene load_steps=4 format=3 uid="uid://dkaxidh7xlvfc"]
+
+[ext_resource type="Texture2D" uid="uid://iqbqsiyjd3uq" path="res://Scenes/UI/TitleScreen/Assets/2D_Shadow_Map.webp" id="1_07rxh"]
+[ext_resource type="Texture2D" uid="uid://hfxynr5jdgsp" path="res://Scenes/NoteManager/Assets/New_Arrow.png" id="2_ty17s"]
+
+[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_4croe"]
+particle_flag_disable_z = true
+emission_shape = 3
+emission_box_extents = Vector3(2.4, 5, 1)
+gravity = Vector3(-180, 0, 0)
+hue_variation_min = -1.0
+hue_variation_max = 1.0
+turbulence_enabled = true
+
+[node name="Effects" type="Node"]
+
+[node name="MoonLight" type="PointLight2D" parent="."]
+position = Vector2(363, 37)
+energy = 2.0
+texture = ExtResource("1_07rxh")
+texture_scale = 3.0
+
+[node name="TextLight" type="PointLight2D" parent="."]
+position = Vector2(320, 100)
+scale = Vector2(6, 2)
+color = Color(0.560784, 0, 1, 1)
+energy = 2.0
+range_item_cull_mask = 3
+texture = ExtResource("1_07rxh")
+texture_scale = 0.5
+
+[node name="GPUParticles2D" type="GPUParticles2D" parent="."]
+light_mask = 0
+z_index = -1
+z_as_relative = false
+position = Vector2(643, 154)
+texture = ExtResource("2_ty17s")
+lifetime = 15.0
+randomness = 1.0
+process_material = SubResource("ParticleProcessMaterial_4croe")
diff --git a/SharedAssets/BG_Forest_To_City.png b/SharedAssets/BG_Forest_To_City.png
new file mode 100644
index 00000000..b67eb045
Binary files /dev/null and b/SharedAssets/BG_Forest_To_City.png differ
diff --git a/SharedAssets/BG_Forest_To_City.png.import b/SharedAssets/BG_Forest_To_City.png.import
new file mode 100644
index 00000000..9c8ccf2e
--- /dev/null
+++ b/SharedAssets/BG_Forest_To_City.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://b7xhtf8tgyxuq"
+path="res://.godot/imported/BG_Forest_To_City.png-0e79a51c5554f10e16c6fd65efb40dd9.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://SharedAssets/BG_Forest_To_City.png"
+dest_files=["res://.godot/imported/BG_Forest_To_City.png-0e79a51c5554f10e16c6fd65efb40dd9.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/SharedAssets/BackGround_City.png b/SharedAssets/BackGround_City.png
new file mode 100644
index 00000000..4c50d749
Binary files /dev/null and b/SharedAssets/BackGround_City.png differ
diff --git a/SharedAssets/BackGround_City.png.import b/SharedAssets/BackGround_City.png.import
new file mode 100644
index 00000000..cdb64a4b
--- /dev/null
+++ b/SharedAssets/BackGround_City.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bct14w72jt3gv"
+path="res://.godot/imported/BackGround_City.png-d23ac72f201ffb7936eaec08855f457c.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://SharedAssets/BackGround_City.png"
+dest_files=["res://.godot/imported/BackGround_City.png-d23ac72f201ffb7936eaec08855f457c.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/SharedAssets/Money.png b/SharedAssets/Money.png
new file mode 100644
index 00000000..c49cef32
Binary files /dev/null and b/SharedAssets/Money.png differ
diff --git a/SharedAssets/Money.png.import b/SharedAssets/Money.png.import
new file mode 100644
index 00000000..14bf2de1
--- /dev/null
+++ b/SharedAssets/Money.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dyt1cvag13aik"
+path="res://.godot/imported/Money.png-067f5c3b789c8217e2c81c86c031e2f0.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://SharedAssets/Money.png"
+dest_files=["res://.godot/imported/Money.png-067f5c3b789c8217e2c81c86c031e2f0.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/godotsteam/godotsteam.gdextension b/addons/godotsteam/godotsteam.gdextension
new file mode 100644
index 00000000..5917bede
--- /dev/null
+++ b/addons/godotsteam/godotsteam.gdextension
@@ -0,0 +1,22 @@
+[configuration]
+entry_symbol = "godotsteam_init"
+compatibility_minimum = "4.4"
+
+[libraries]
+macos.debug = "res://addons/godotsteam/osx/libgodotsteam.macos.template_debug.framework"
+macos.release = "res://addons/godotsteam/osx/libgodotsteam.macos.template_release.framework"
+windows.debug.x86_64 = "res://addons/godotsteam/win64/libgodotsteam.windows.template_debug.x86_64.dll"
+windows.debug.x86_32 = "res://addons/godotsteam/win32/libgodotsteam.windows.template_debug.x86_32.dll"
+windows.release.x86_64 = "res://addons/godotsteam/win64/libgodotsteam.windows.template_release.x86_64.dll"
+windows.release.x86_32 = "res://addons/godotsteam/win32/libgodotsteam.windows.template_release.x86_32.dll"
+linux.debug.x86_64 = "res://addons/godotsteam/linux64/libgodotsteam.linux.template_debug.x86_64.so"
+linux.debug.x86_32 = "res://addons/godotsteam/linux32/libgodotsteam.linux.template_debug.x86_32.so"
+linux.release.x86_64 = "res://addons/godotsteam/linux64/libgodotsteam.linux.template_release.x86_64.so"
+linux.release.x86_32 = "res://addons/godotsteam/linux32/libgodotsteam.linux.template_release.x86_32.so"
+
+[dependencies]
+macos.universal = { "res://addons/godotsteam/osx/libsteam_api.dylib": "" }
+windows.x86_64 = { "res://addons/godotsteam/win64/steam_api64.dll": "" }
+windows.x86_32 = { "res://addons/godotsteam/win32/steam_api.dll": "" }
+linux.x86_64 = { "res://addons/godotsteam/linux64/libsteam_api.so": "" }
+linux.x86_32 = { "res://addons/godotsteam/linux32/libsteam_api.so": "" }
diff --git a/addons/godotsteam/godotsteam.gdextension.uid b/addons/godotsteam/godotsteam.gdextension.uid
new file mode 100644
index 00000000..17b1dc04
--- /dev/null
+++ b/addons/godotsteam/godotsteam.gdextension.uid
@@ -0,0 +1 @@
+uid://ue83e761t35n
diff --git a/addons/godotsteam/linux32/libgodotsteam.linux.template_debug.x86_32.so b/addons/godotsteam/linux32/libgodotsteam.linux.template_debug.x86_32.so
new file mode 100644
index 00000000..00be7c5f
Binary files /dev/null and b/addons/godotsteam/linux32/libgodotsteam.linux.template_debug.x86_32.so differ
diff --git a/addons/godotsteam/linux32/libgodotsteam.linux.template_release.x86_32.so b/addons/godotsteam/linux32/libgodotsteam.linux.template_release.x86_32.so
new file mode 100644
index 00000000..658694b1
Binary files /dev/null and b/addons/godotsteam/linux32/libgodotsteam.linux.template_release.x86_32.so differ
diff --git a/addons/godotsteam/linux32/libsteam_api.so b/addons/godotsteam/linux32/libsteam_api.so
new file mode 100644
index 00000000..2d9e8a72
Binary files /dev/null and b/addons/godotsteam/linux32/libsteam_api.so differ
diff --git a/addons/godotsteam/linux64/libgodotsteam.linux.template_debug.x86_64.so b/addons/godotsteam/linux64/libgodotsteam.linux.template_debug.x86_64.so
new file mode 100644
index 00000000..045b00d6
Binary files /dev/null and b/addons/godotsteam/linux64/libgodotsteam.linux.template_debug.x86_64.so differ
diff --git a/addons/godotsteam/linux64/libgodotsteam.linux.template_release.x86_64.so b/addons/godotsteam/linux64/libgodotsteam.linux.template_release.x86_64.so
new file mode 100644
index 00000000..b273ec79
Binary files /dev/null and b/addons/godotsteam/linux64/libgodotsteam.linux.template_release.x86_64.so differ
diff --git a/addons/godotsteam/linux64/libsteam_api.so b/addons/godotsteam/linux64/libsteam_api.so
new file mode 100644
index 00000000..8783570d
Binary files /dev/null and b/addons/godotsteam/linux64/libsteam_api.so differ
diff --git a/addons/godotsteam/osx/libgodotsteam.macos.template_debug.framework/Resources/Info.plist b/addons/godotsteam/osx/libgodotsteam.macos.template_debug.framework/Resources/Info.plist
new file mode 100644
index 00000000..68caf2bb
--- /dev/null
+++ b/addons/godotsteam/osx/libgodotsteam.macos.template_debug.framework/Resources/Info.plist
@@ -0,0 +1,26 @@
+
+
+
+
+ CFBundleExecutable
+ libgodotsteam.debug
+ CFBundleIdentifier
+ org.godotsteam.godotsteam
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ libgodotsteam.debug
+ CFBundlePackageType
+ FMWK
+ CFBundleShortVersionString
+ 4.15
+ CFBundleSupportedPlatforms
+
+ MacOSX
+
+ CFBundleVersion
+ 4.15
+ LSMinimumSystemVersion
+ 10.12
+
+
\ No newline at end of file
diff --git a/addons/godotsteam/osx/libgodotsteam.macos.template_debug.framework/libgodotsteam.macos.template_debug b/addons/godotsteam/osx/libgodotsteam.macos.template_debug.framework/libgodotsteam.macos.template_debug
new file mode 100644
index 00000000..8a8b2b7b
Binary files /dev/null and b/addons/godotsteam/osx/libgodotsteam.macos.template_debug.framework/libgodotsteam.macos.template_debug differ
diff --git a/addons/godotsteam/osx/libgodotsteam.macos.template_debug.framework/libsteam_api.dylib b/addons/godotsteam/osx/libgodotsteam.macos.template_debug.framework/libsteam_api.dylib
new file mode 100644
index 00000000..c493b2b5
Binary files /dev/null and b/addons/godotsteam/osx/libgodotsteam.macos.template_debug.framework/libsteam_api.dylib differ
diff --git a/addons/godotsteam/osx/libgodotsteam.macos.template_release.framework/Resources/Info.plist b/addons/godotsteam/osx/libgodotsteam.macos.template_release.framework/Resources/Info.plist
new file mode 100644
index 00000000..e3e8dac1
--- /dev/null
+++ b/addons/godotsteam/osx/libgodotsteam.macos.template_release.framework/Resources/Info.plist
@@ -0,0 +1,26 @@
+
+
+
+
+ CFBundleExecutable
+ libgodotsteam
+ CFBundleIdentifier
+ org.godotsteam.godotsteam
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ libgodotsteam
+ CFBundlePackageType
+ FMWK
+ CFBundleShortVersionString
+ 4.15
+ CFBundleSupportedPlatforms
+
+ MacOSX
+
+ CFBundleVersion
+ 4.15
+ LSMinimumSystemVersion
+ 10.12
+
+
\ No newline at end of file
diff --git a/addons/godotsteam/osx/libgodotsteam.macos.template_release.framework/libgodotsteam.macos.template_release b/addons/godotsteam/osx/libgodotsteam.macos.template_release.framework/libgodotsteam.macos.template_release
new file mode 100644
index 00000000..ce91b3e3
Binary files /dev/null and b/addons/godotsteam/osx/libgodotsteam.macos.template_release.framework/libgodotsteam.macos.template_release differ
diff --git a/addons/godotsteam/osx/libgodotsteam.macos.template_release.framework/libsteam_api.dylib b/addons/godotsteam/osx/libgodotsteam.macos.template_release.framework/libsteam_api.dylib
new file mode 100644
index 00000000..c493b2b5
Binary files /dev/null and b/addons/godotsteam/osx/libgodotsteam.macos.template_release.framework/libsteam_api.dylib differ
diff --git a/addons/godotsteam/osx/libsteam_api.dylib b/addons/godotsteam/osx/libsteam_api.dylib
new file mode 100644
index 00000000..c493b2b5
Binary files /dev/null and b/addons/godotsteam/osx/libsteam_api.dylib differ
diff --git a/addons/godotsteam/win32/libgodotsteam.windows.template_debug.x86_32.dll b/addons/godotsteam/win32/libgodotsteam.windows.template_debug.x86_32.dll
new file mode 100644
index 00000000..cebcc9bd
Binary files /dev/null and b/addons/godotsteam/win32/libgodotsteam.windows.template_debug.x86_32.dll differ
diff --git a/addons/godotsteam/win32/libgodotsteam.windows.template_release.x86_32.dll b/addons/godotsteam/win32/libgodotsteam.windows.template_release.x86_32.dll
new file mode 100644
index 00000000..21c3a1ef
Binary files /dev/null and b/addons/godotsteam/win32/libgodotsteam.windows.template_release.x86_32.dll differ
diff --git a/addons/godotsteam/win32/steam_api.dll b/addons/godotsteam/win32/steam_api.dll
new file mode 100644
index 00000000..2372ab1f
Binary files /dev/null and b/addons/godotsteam/win32/steam_api.dll differ
diff --git a/addons/godotsteam/win64/libgodotsteam.windows.template_debug.x86_64.dll b/addons/godotsteam/win64/libgodotsteam.windows.template_debug.x86_64.dll
new file mode 100644
index 00000000..3d028484
Binary files /dev/null and b/addons/godotsteam/win64/libgodotsteam.windows.template_debug.x86_64.dll differ
diff --git a/addons/godotsteam/win64/libgodotsteam.windows.template_release.x86_64.dll b/addons/godotsteam/win64/libgodotsteam.windows.template_release.x86_64.dll
new file mode 100644
index 00000000..6bb49b3c
Binary files /dev/null and b/addons/godotsteam/win64/libgodotsteam.windows.template_release.x86_64.dll differ
diff --git a/addons/godotsteam/win64/steam_api64.dll b/addons/godotsteam/win64/steam_api64.dll
new file mode 100644
index 00000000..6d118254
Binary files /dev/null and b/addons/godotsteam/win64/steam_api64.dll differ
diff --git a/addons/godotsteam_csharpbindings/Apps/Dlc.cs b/addons/godotsteam_csharpbindings/Apps/Dlc.cs
new file mode 100644
index 00000000..4b8ff667
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Apps/Dlc.cs
@@ -0,0 +1,8 @@
+namespace GodotSteam;
+
+public class Dlc
+{
+ public uint AppId { get; set; }
+ public bool Available { get; set; }
+ public string Name { get; set; }
+}
diff --git a/addons/godotsteam_csharpbindings/Apps/Dlc.cs.uid b/addons/godotsteam_csharpbindings/Apps/Dlc.cs.uid
new file mode 100644
index 00000000..938503fc
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Apps/Dlc.cs.uid
@@ -0,0 +1 @@
+uid://ck0g3t7wpau3w
diff --git a/addons/godotsteam_csharpbindings/Apps/DlcDownloadProgress.cs b/addons/godotsteam_csharpbindings/Apps/DlcDownloadProgress.cs
new file mode 100644
index 00000000..2d288d2c
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Apps/DlcDownloadProgress.cs
@@ -0,0 +1,8 @@
+namespace GodotSteam;
+
+public class DlcDownloadProgress
+{
+ public bool Ret { get; set; }
+ public ulong Downloaded { get; set; }
+ public ulong Total { get; set; }
+}
diff --git a/addons/godotsteam_csharpbindings/Apps/DlcDownloadProgress.cs.uid b/addons/godotsteam_csharpbindings/Apps/DlcDownloadProgress.cs.uid
new file mode 100644
index 00000000..37eb740a
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Apps/DlcDownloadProgress.cs.uid
@@ -0,0 +1 @@
+uid://5rddlaexp6hq
diff --git a/addons/godotsteam_csharpbindings/Apps/InstalledApps.cs b/addons/godotsteam_csharpbindings/Apps/InstalledApps.cs
new file mode 100644
index 00000000..b2951745
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Apps/InstalledApps.cs
@@ -0,0 +1,7 @@
+namespace GodotSteam;
+
+public class InstalledApps
+{
+ public string Directory { get; set; }
+ public uint InstallSize { get; set; }
+}
diff --git a/addons/godotsteam_csharpbindings/Apps/InstalledApps.cs.uid b/addons/godotsteam_csharpbindings/Apps/InstalledApps.cs.uid
new file mode 100644
index 00000000..e3864e67
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Apps/InstalledApps.cs.uid
@@ -0,0 +1 @@
+uid://bljidrnl07rcs
diff --git a/addons/godotsteam_csharpbindings/Apps/TimedTrial.cs b/addons/godotsteam_csharpbindings/Apps/TimedTrial.cs
new file mode 100644
index 00000000..879092bf
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Apps/TimedTrial.cs
@@ -0,0 +1,7 @@
+namespace GodotSteam;
+
+public class TimedTrial
+{
+ public uint SecondsAllowed { get; set; }
+ public uint SecondsPlayed { get; set; }
+}
diff --git a/addons/godotsteam_csharpbindings/Apps/TimedTrial.cs.uid b/addons/godotsteam_csharpbindings/Apps/TimedTrial.cs.uid
new file mode 100644
index 00000000..99d1023d
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Apps/TimedTrial.cs.uid
@@ -0,0 +1 @@
+uid://b7c4do2nj0fsk
diff --git a/addons/godotsteam_csharpbindings/Friends/AvatarSize.cs b/addons/godotsteam_csharpbindings/Friends/AvatarSize.cs
new file mode 100644
index 00000000..3ac505d4
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/AvatarSize.cs
@@ -0,0 +1,8 @@
+namespace GodotSteam;
+
+public enum AvatarSize
+{
+ Small = 1,
+ Medium = 2,
+ Large = 3,
+}
diff --git a/addons/godotsteam_csharpbindings/Friends/AvatarSize.cs.uid b/addons/godotsteam_csharpbindings/Friends/AvatarSize.cs.uid
new file mode 100644
index 00000000..b0494b62
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/AvatarSize.cs.uid
@@ -0,0 +1 @@
+uid://bj8pu5fcyh1p4
diff --git a/addons/godotsteam_csharpbindings/Friends/ChatRoomEnterResponse.cs b/addons/godotsteam_csharpbindings/Friends/ChatRoomEnterResponse.cs
new file mode 100644
index 00000000..dd689958
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/ChatRoomEnterResponse.cs
@@ -0,0 +1,17 @@
+namespace GodotSteam;
+
+public enum ChatRoomEnterResponse
+{
+ Success = 1,
+ DoesntExist = 2,
+ NotAllowed = 3,
+ Full = 4,
+ Error = 5,
+ Banned = 6,
+ Limited = 7,
+ ClanDisabled = 8,
+ CommunityBan = 9,
+ MemberBlockedYou = 10,
+ YouBlockedMember = 11,
+ RateLimitExceeded = 15,
+}
diff --git a/addons/godotsteam_csharpbindings/Friends/ChatRoomEnterResponse.cs.uid b/addons/godotsteam_csharpbindings/Friends/ChatRoomEnterResponse.cs.uid
new file mode 100644
index 00000000..e5539d9f
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/ChatRoomEnterResponse.cs.uid
@@ -0,0 +1 @@
+uid://brocvjixqno6o
diff --git a/addons/godotsteam_csharpbindings/Friends/ClanActivityCounts.cs b/addons/godotsteam_csharpbindings/Friends/ClanActivityCounts.cs
new file mode 100644
index 00000000..2d04d72b
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/ClanActivityCounts.cs
@@ -0,0 +1,9 @@
+namespace GodotSteam;
+
+public class ClanActivityCounts
+{
+ public ulong Clan { get; set; }
+ public int Online { get; set; }
+ public int Ingame { get; set; }
+ public int Chatting { get; set; }
+}
diff --git a/addons/godotsteam_csharpbindings/Friends/ClanActivityCounts.cs.uid b/addons/godotsteam_csharpbindings/Friends/ClanActivityCounts.cs.uid
new file mode 100644
index 00000000..af3259f4
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/ClanActivityCounts.cs.uid
@@ -0,0 +1 @@
+uid://cweigqo0cyi0k
diff --git a/addons/godotsteam_csharpbindings/Friends/ClanChatMessage.cs b/addons/godotsteam_csharpbindings/Friends/ClanChatMessage.cs
new file mode 100644
index 00000000..2acd941b
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/ClanChatMessage.cs
@@ -0,0 +1,9 @@
+namespace GodotSteam;
+
+public class ClanChatMessage
+{
+ public bool Ret { get; set; }
+ public string Text { get; set; }
+ public ClanChatMessageType Type { get; set; }
+ public ulong Chatter { get; set; }
+}
diff --git a/addons/godotsteam_csharpbindings/Friends/ClanChatMessage.cs.uid b/addons/godotsteam_csharpbindings/Friends/ClanChatMessage.cs.uid
new file mode 100644
index 00000000..409f76f2
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/ClanChatMessage.cs.uid
@@ -0,0 +1 @@
+uid://v7tlrri6l22c
diff --git a/addons/godotsteam_csharpbindings/Friends/ClanChatMessageType.cs b/addons/godotsteam_csharpbindings/Friends/ClanChatMessageType.cs
new file mode 100644
index 00000000..e0ab923b
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/ClanChatMessageType.cs
@@ -0,0 +1,17 @@
+namespace GodotSteam;
+
+public enum ClanChatMessageType
+{
+ Invalid = 0,
+ ChatMessage = 1,
+ Typing = 2,
+ InviteGame = 3,
+ Emote = 4,
+ LeftConversation = 6,
+ Entered = 7,
+ WasKicked = 8,
+ WasBanned = 9,
+ Disconnected = 10,
+ HistoricalChat = 11,
+ LinkBlocked = 14,
+}
diff --git a/addons/godotsteam_csharpbindings/Friends/ClanChatMessageType.cs.uid b/addons/godotsteam_csharpbindings/Friends/ClanChatMessageType.cs.uid
new file mode 100644
index 00000000..59dbacee
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/ClanChatMessageType.cs.uid
@@ -0,0 +1 @@
+uid://cwbj36arl2ifh
diff --git a/addons/godotsteam_csharpbindings/Friends/ClanOfficer.cs b/addons/godotsteam_csharpbindings/Friends/ClanOfficer.cs
new file mode 100644
index 00000000..c311e4aa
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/ClanOfficer.cs
@@ -0,0 +1,7 @@
+namespace GodotSteam;
+
+public class ClanOfficer
+{
+ public ulong Id { get; set; }
+ public string Name { get; set; }
+}
diff --git a/addons/godotsteam_csharpbindings/Friends/ClanOfficer.cs.uid b/addons/godotsteam_csharpbindings/Friends/ClanOfficer.cs.uid
new file mode 100644
index 00000000..edd4f0b7
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/ClanOfficer.cs.uid
@@ -0,0 +1 @@
+uid://wr36i3odho8q
diff --git a/addons/godotsteam_csharpbindings/Friends/CommunityProfileItemProperty.cs b/addons/godotsteam_csharpbindings/Friends/CommunityProfileItemProperty.cs
new file mode 100644
index 00000000..e73713c8
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/CommunityProfileItemProperty.cs
@@ -0,0 +1,17 @@
+namespace GodotSteam;
+
+public enum CommunityProfileItemProperty
+{
+ ImageSmall = 0,
+ ImageLarge = 1,
+ InternalName = 2,
+ Title = 3,
+ Description = 4,
+ AppId = 5,
+ TypeId = 6,
+ Class = 7,
+ MovieWebm = 8,
+ MovieMp4 = 9,
+ MovieWebmSmall = 10,
+ MovieMp4Small = 11,
+}
diff --git a/addons/godotsteam_csharpbindings/Friends/CommunityProfileItemProperty.cs.uid b/addons/godotsteam_csharpbindings/Friends/CommunityProfileItemProperty.cs.uid
new file mode 100644
index 00000000..13a72b2a
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/CommunityProfileItemProperty.cs.uid
@@ -0,0 +1 @@
+uid://ddk3sfcg0hewu
diff --git a/addons/godotsteam_csharpbindings/Friends/CommunityProfileItemType.cs b/addons/godotsteam_csharpbindings/Friends/CommunityProfileItemType.cs
new file mode 100644
index 00000000..3882fd90
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/CommunityProfileItemType.cs
@@ -0,0 +1,10 @@
+namespace GodotSteam;
+
+public enum CommunityProfileItemType
+{
+ AnimatedAvatar = 0,
+ AvatarFrame = 1,
+ ProfileModifier = 2,
+ ProfileBackground = 3,
+ MiniProfileBackground = 4,
+}
diff --git a/addons/godotsteam_csharpbindings/Friends/CommunityProfileItemType.cs.uid b/addons/godotsteam_csharpbindings/Friends/CommunityProfileItemType.cs.uid
new file mode 100644
index 00000000..5773636d
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/CommunityProfileItemType.cs.uid
@@ -0,0 +1 @@
+uid://ceej0eif4homl
diff --git a/addons/godotsteam_csharpbindings/Friends/Follow.cs b/addons/godotsteam_csharpbindings/Friends/Follow.cs
new file mode 100644
index 00000000..14ff9185
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/Follow.cs
@@ -0,0 +1,7 @@
+namespace GodotSteam;
+
+public class Follow
+{
+ public int Num { get; set; }
+ public ulong Id { get; set; }
+}
diff --git a/addons/godotsteam_csharpbindings/Friends/Follow.cs.uid b/addons/godotsteam_csharpbindings/Friends/Follow.cs.uid
new file mode 100644
index 00000000..af7c2a7f
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/Follow.cs.uid
@@ -0,0 +1 @@
+uid://eii8sbrpa1se
diff --git a/addons/godotsteam_csharpbindings/Friends/Friend.cs b/addons/godotsteam_csharpbindings/Friends/Friend.cs
new file mode 100644
index 00000000..37623ab7
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/Friend.cs
@@ -0,0 +1,8 @@
+namespace GodotSteam;
+
+public class Friend
+{
+ public ulong Id { get; set; }
+ public string Name { get; set; }
+ public PersonaState Status { get; set; }
+}
diff --git a/addons/godotsteam_csharpbindings/Friends/Friend.cs.uid b/addons/godotsteam_csharpbindings/Friends/Friend.cs.uid
new file mode 100644
index 00000000..1751ce91
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/Friend.cs.uid
@@ -0,0 +1 @@
+uid://bsuq1hrqmfdm2
diff --git a/addons/godotsteam_csharpbindings/Friends/FriendFlag.cs b/addons/godotsteam_csharpbindings/Friends/FriendFlag.cs
new file mode 100644
index 00000000..1f5e4fbb
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/FriendFlag.cs
@@ -0,0 +1,18 @@
+namespace GodotSteam;
+
+[System.Flags]
+public enum FriendFlag
+{
+ None = 0x00,
+ Blocked = 0x01,
+ FriendshipRequested = 0x02,
+ Immediate = 0x04,
+ ClanMember = 0x08,
+ OnGameServer = 0x10,
+ RequestingFriendship = 0x80,
+ RequestingInfo = 0x100,
+ Ignored = 0x200,
+ IgnoredFriend = 0x400,
+ ChatMember = 0x0000,
+ All = 0xFFFF,
+}
diff --git a/addons/godotsteam_csharpbindings/Friends/FriendFlag.cs.uid b/addons/godotsteam_csharpbindings/Friends/FriendFlag.cs.uid
new file mode 100644
index 00000000..300c36ea
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/FriendFlag.cs.uid
@@ -0,0 +1 @@
+uid://dtcarpwof1t4c
diff --git a/addons/godotsteam_csharpbindings/Friends/FriendGroup.cs b/addons/godotsteam_csharpbindings/Friends/FriendGroup.cs
new file mode 100644
index 00000000..92d87249
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/FriendGroup.cs
@@ -0,0 +1,8 @@
+namespace GodotSteam;
+
+public class FriendGroup
+{
+ public short Id { get; set; }
+ public string Name { get; set; }
+ public int Members { get; set; }
+}
diff --git a/addons/godotsteam_csharpbindings/Friends/FriendGroup.cs.uid b/addons/godotsteam_csharpbindings/Friends/FriendGroup.cs.uid
new file mode 100644
index 00000000..69599e2e
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/FriendGroup.cs.uid
@@ -0,0 +1 @@
+uid://ovo8uaggl5sv
diff --git a/addons/godotsteam_csharpbindings/Friends/FriendRelationship.cs b/addons/godotsteam_csharpbindings/Friends/FriendRelationship.cs
new file mode 100644
index 00000000..2f65ba71
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/FriendRelationship.cs
@@ -0,0 +1,14 @@
+namespace GodotSteam;
+
+public enum FriendRelationship
+{
+ None = 0,
+ Blocked = 1,
+ RequestRecipient = 2,
+ Friend = 3,
+ RequestInitiator = 4,
+ Ignored = 5,
+ IgnoredFriend = 6,
+ Suggested = 7,
+ Max = 8,
+}
diff --git a/addons/godotsteam_csharpbindings/Friends/FriendRelationship.cs.uid b/addons/godotsteam_csharpbindings/Friends/FriendRelationship.cs.uid
new file mode 100644
index 00000000..915dcdbe
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/FriendRelationship.cs.uid
@@ -0,0 +1 @@
+uid://byfft28eek76g
diff --git a/addons/godotsteam_csharpbindings/Friends/GameOverlayType.cs b/addons/godotsteam_csharpbindings/Friends/GameOverlayType.cs
new file mode 100644
index 00000000..d32de4dc
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/GameOverlayType.cs
@@ -0,0 +1,36 @@
+using System;
+
+namespace GodotSteam;
+
+public enum GameOverlayType
+{
+ Default,
+ Friends,
+ Community,
+ Players,
+ Settings,
+ OfficalGameGroup,
+ Stats,
+ Achievements,
+ LobbyInvite,
+}
+
+public static class GameOverlayTypeExtensions
+{
+ public static string ToGodotSteam(this GameOverlayType type)
+ {
+ return type switch
+ {
+ GameOverlayType.Default => "",
+ GameOverlayType.Friends => "Friends",
+ GameOverlayType.Community => "Community",
+ GameOverlayType.Players => "Players",
+ GameOverlayType.Settings => "Settings",
+ GameOverlayType.OfficalGameGroup => "OfficalGameGroup",
+ GameOverlayType.Stats => "Stats",
+ GameOverlayType.Achievements => "Achievements",
+ GameOverlayType.LobbyInvite => "LobbyInvite",
+ _ => throw new ArgumentException("Invalid GameOverlayType"),
+ };
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Friends/GameOverlayType.cs.uid b/addons/godotsteam_csharpbindings/Friends/GameOverlayType.cs.uid
new file mode 100644
index 00000000..53769a74
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/GameOverlayType.cs.uid
@@ -0,0 +1 @@
+uid://diaxsml10ay8k
diff --git a/addons/godotsteam_csharpbindings/Friends/GameOverlayUserType.cs b/addons/godotsteam_csharpbindings/Friends/GameOverlayUserType.cs
new file mode 100644
index 00000000..074d1de5
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/GameOverlayUserType.cs
@@ -0,0 +1,36 @@
+using System;
+
+namespace GodotSteam;
+
+public enum GameOverlayUserType
+{
+ SteamId,
+ Chat,
+ JoinTrade,
+ Stats,
+ Achievements,
+ FriendAdd,
+ FriendRemove,
+ FriendRequestAccept,
+ FriendRequestIgnore,
+}
+
+public static class GameOverlayUserTypeExtensions
+{
+ public static string ToGodotSteam(this GameOverlayUserType type)
+ {
+ return type switch
+ {
+ GameOverlayUserType.SteamId => "steamid",
+ GameOverlayUserType.Chat => "chat",
+ GameOverlayUserType.JoinTrade => "jointrade",
+ GameOverlayUserType.Stats => "stats",
+ GameOverlayUserType.Achievements => "achievements",
+ GameOverlayUserType.FriendAdd => "friendadd",
+ GameOverlayUserType.FriendRemove => "friendremove",
+ GameOverlayUserType.FriendRequestAccept => "friendrequestaccept",
+ GameOverlayUserType.FriendRequestIgnore => "friendrequestignore",
+ _ => throw new ArgumentException("Invalid GameOverlayUserType"),
+ };
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Friends/GameOverlayUserType.cs.uid b/addons/godotsteam_csharpbindings/Friends/GameOverlayUserType.cs.uid
new file mode 100644
index 00000000..722cdb9b
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/GameOverlayUserType.cs.uid
@@ -0,0 +1 @@
+uid://h1ymuuuyq5th
diff --git a/addons/godotsteam_csharpbindings/Friends/PersonaChange.cs b/addons/godotsteam_csharpbindings/Friends/PersonaChange.cs
new file mode 100644
index 00000000..6a5b586c
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/PersonaChange.cs
@@ -0,0 +1,21 @@
+namespace GodotSteam;
+
+[System.Flags]
+public enum PersonaChange
+{
+ Name = 0x0001,
+ Status = 0x0002,
+ ComeOnline = 0x0004,
+ GoneOffline = 0x0008,
+ GamePlayed = 0x0010,
+ GameServer = 0x0020,
+ Avatar = 0x0040,
+ JoinedSource = 0x0080,
+ LeftSource = 0x0100,
+ RelationshipChanged = 0x0200,
+ NameFirstSet = 0x0400,
+ FacebookInfo = 0x0800,
+ Nickname = 0x1000,
+ SteamLevel = 0x2000,
+ RichPresence = 0x4000,
+}
diff --git a/addons/godotsteam_csharpbindings/Friends/PersonaChange.cs.uid b/addons/godotsteam_csharpbindings/Friends/PersonaChange.cs.uid
new file mode 100644
index 00000000..a0d008b2
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/PersonaChange.cs.uid
@@ -0,0 +1 @@
+uid://ccn0erf17jpb3
diff --git a/addons/godotsteam_csharpbindings/Friends/PersonaState.cs b/addons/godotsteam_csharpbindings/Friends/PersonaState.cs
new file mode 100644
index 00000000..50421b86
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/PersonaState.cs
@@ -0,0 +1,14 @@
+namespace GodotSteam;
+
+public enum PersonaState
+{
+ Offline = 0,
+ Online = 1,
+ Busy = 2,
+ Away = 3,
+ Snooze = 4,
+ LookingToTrade = 5,
+ LookingToPlay = 6,
+ Invisible = 7,
+ Max = 8,
+}
diff --git a/addons/godotsteam_csharpbindings/Friends/PersonaState.cs.uid b/addons/godotsteam_csharpbindings/Friends/PersonaState.cs.uid
new file mode 100644
index 00000000..fa3af002
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/PersonaState.cs.uid
@@ -0,0 +1 @@
+uid://ccesradiwpwcj
diff --git a/addons/godotsteam_csharpbindings/Friends/ProfileData.cs b/addons/godotsteam_csharpbindings/Friends/ProfileData.cs
new file mode 100644
index 00000000..0b21a6fc
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/ProfileData.cs
@@ -0,0 +1,10 @@
+namespace GodotSteam;
+
+public class ProfileData
+{
+ public bool AvatarAnimated { get; set; }
+ public bool AvatarFrame { get; set; }
+ public bool ProfileModifier { get; set; }
+ public bool ProfileBackground { get; set; }
+ public bool ProfileMiniBackground { get; set; }
+}
diff --git a/addons/godotsteam_csharpbindings/Friends/ProfileData.cs.uid b/addons/godotsteam_csharpbindings/Friends/ProfileData.cs.uid
new file mode 100644
index 00000000..af642f1c
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/ProfileData.cs.uid
@@ -0,0 +1 @@
+uid://bpeckwjb4oxq7
diff --git a/addons/godotsteam_csharpbindings/Friends/RecentPlayer.cs b/addons/godotsteam_csharpbindings/Friends/RecentPlayer.cs
new file mode 100644
index 00000000..c7b7caa6
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/RecentPlayer.cs
@@ -0,0 +1,9 @@
+namespace GodotSteam;
+
+public class RecentPlayer
+{
+ public ulong Id { get; set; }
+ public string Name { get; set; }
+ public int Time { get; set; }
+ public PersonaState Status { get; set; }
+}
diff --git a/addons/godotsteam_csharpbindings/Friends/RecentPlayer.cs.uid b/addons/godotsteam_csharpbindings/Friends/RecentPlayer.cs.uid
new file mode 100644
index 00000000..84f31800
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/RecentPlayer.cs.uid
@@ -0,0 +1 @@
+uid://blcypic65via3
diff --git a/addons/godotsteam_csharpbindings/Friends/RichPresenceKeys.cs b/addons/godotsteam_csharpbindings/Friends/RichPresenceKeys.cs
new file mode 100644
index 00000000..de565ea1
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/RichPresenceKeys.cs
@@ -0,0 +1,13 @@
+using System;
+using Godot;
+
+namespace GodotSteam;
+
+public static class RichPresenceKeys
+{
+ public static readonly StringName Status = "status";
+ public static readonly StringName Connect = "connect";
+ public static readonly StringName SteamDisplay = "steam_display";
+ public static readonly StringName SteamPlayerGroup = "steam_player_group";
+ public static readonly StringName SteamPlayerGroupSize = "steam_player_group_size";
+}
diff --git a/addons/godotsteam_csharpbindings/Friends/RichPresenceKeys.cs.uid b/addons/godotsteam_csharpbindings/Friends/RichPresenceKeys.cs.uid
new file mode 100644
index 00000000..63acabf9
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/RichPresenceKeys.cs.uid
@@ -0,0 +1 @@
+uid://yh3dss1lib5x
diff --git a/addons/godotsteam_csharpbindings/Friends/SteamGroup.cs b/addons/godotsteam_csharpbindings/Friends/SteamGroup.cs
new file mode 100644
index 00000000..e990ae0d
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/SteamGroup.cs
@@ -0,0 +1,8 @@
+namespace GodotSteam;
+
+public class SteamGroup
+{
+ public ulong Id { get; set; }
+ public string Name { get; set; }
+ public string Tag { get; set; }
+}
diff --git a/addons/godotsteam_csharpbindings/Friends/SteamGroup.cs.uid b/addons/godotsteam_csharpbindings/Friends/SteamGroup.cs.uid
new file mode 100644
index 00000000..5210690f
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/SteamGroup.cs.uid
@@ -0,0 +1 @@
+uid://c3umkk5p6exq4
diff --git a/addons/godotsteam_csharpbindings/Friends/UserRestriction.cs b/addons/godotsteam_csharpbindings/Friends/UserRestriction.cs
new file mode 100644
index 00000000..1afa77c8
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/UserRestriction.cs
@@ -0,0 +1,14 @@
+namespace GodotSteam;
+
+[System.Flags]
+public enum UserRestriction
+{
+ None = 0,
+ Unknown = 1,
+ AnyChat = 2,
+ VoiceChat = 4,
+ GroupChat = 8,
+ Rating = 16,
+ GameInvites = 32,
+ Trading = 64,
+}
diff --git a/addons/godotsteam_csharpbindings/Friends/UserRestriction.cs.uid b/addons/godotsteam_csharpbindings/Friends/UserRestriction.cs.uid
new file mode 100644
index 00000000..e7e7a136
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Friends/UserRestriction.cs.uid
@@ -0,0 +1 @@
+uid://fs4inqa3xfqy
diff --git a/addons/godotsteam_csharpbindings/GameSearch/PlayerData.cs b/addons/godotsteam_csharpbindings/GameSearch/PlayerData.cs
new file mode 100644
index 00000000..f1eddf4d
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/GameSearch/PlayerData.cs
@@ -0,0 +1,13 @@
+namespace GodotSteam;
+
+public class PlayerData
+{
+ public ulong PlayerId { get; set; }
+ public ulong LobbyId { get; set; }
+ public int PlayerAcceptState { get; set; } // TODO: Check if Enum
+ public int PlayerIndex { get; set; }
+ public int TotalPlayers { get; set; }
+ public int TotalPlayersAcceptedGame { get; set; }
+ public int SuggestedTeamIndex { get; set; }
+ public ulong UniqueGameId { get; set; }
+}
diff --git a/addons/godotsteam_csharpbindings/GameSearch/PlayerData.cs.uid b/addons/godotsteam_csharpbindings/GameSearch/PlayerData.cs.uid
new file mode 100644
index 00000000..60e8f18c
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/GameSearch/PlayerData.cs.uid
@@ -0,0 +1 @@
+uid://d0b0vguyn6gw2
diff --git a/addons/godotsteam_csharpbindings/GameSearch/PlayerResult.cs b/addons/godotsteam_csharpbindings/GameSearch/PlayerResult.cs
new file mode 100644
index 00000000..ee21bbf3
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/GameSearch/PlayerResult.cs
@@ -0,0 +1,10 @@
+namespace GodotSteam;
+
+public enum PlayerResult
+{
+ FailedToConnect = 1,
+ Abandoned = 2,
+ Kicked = 3,
+ Incomplete = 4,
+ Completed = 5,
+}
diff --git a/addons/godotsteam_csharpbindings/GameSearch/PlayerResult.cs.uid b/addons/godotsteam_csharpbindings/GameSearch/PlayerResult.cs.uid
new file mode 100644
index 00000000..b14a0a89
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/GameSearch/PlayerResult.cs.uid
@@ -0,0 +1 @@
+uid://b0vs3a2usr84q
diff --git a/addons/godotsteam_csharpbindings/GameSearch/SearchProgress.cs b/addons/godotsteam_csharpbindings/GameSearch/SearchProgress.cs
new file mode 100644
index 00000000..fd0f6ab5
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/GameSearch/SearchProgress.cs
@@ -0,0 +1,9 @@
+namespace GodotSteam;
+
+public class SearchProgress
+{
+ public ulong LobbyId { get; set; }
+ public ulong EndedSearchId { get; set; }
+ public int SecondsRemainingEstimate { get; set; }
+ public int PlayersSearching { get; set; }
+}
diff --git a/addons/godotsteam_csharpbindings/GameSearch/SearchProgress.cs.uid b/addons/godotsteam_csharpbindings/GameSearch/SearchProgress.cs.uid
new file mode 100644
index 00000000..68862a79
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/GameSearch/SearchProgress.cs.uid
@@ -0,0 +1 @@
+uid://hkdoknh0hg16
diff --git a/addons/godotsteam_csharpbindings/GameSearch/SearchResult.cs b/addons/godotsteam_csharpbindings/GameSearch/SearchResult.cs
new file mode 100644
index 00000000..ae334b0e
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/GameSearch/SearchResult.cs
@@ -0,0 +1,9 @@
+namespace GodotSteam;
+
+public class SearchResult
+{
+ public int CountPlayersIngame { get; set; }
+ public int CountAcceptedGame { get; set; }
+ public ulong HostId { get; set; }
+ public bool FinalCallback { get; set; }
+}
diff --git a/addons/godotsteam_csharpbindings/GameSearch/SearchResult.cs.uid b/addons/godotsteam_csharpbindings/GameSearch/SearchResult.cs.uid
new file mode 100644
index 00000000..29e20fac
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/GameSearch/SearchResult.cs.uid
@@ -0,0 +1 @@
+uid://b6xdm8m3j8g1j
diff --git a/addons/godotsteam_csharpbindings/HTMLSurface/HtmlKeyModifiers.cs b/addons/godotsteam_csharpbindings/HTMLSurface/HtmlKeyModifiers.cs
new file mode 100644
index 00000000..61559517
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/HTMLSurface/HtmlKeyModifiers.cs
@@ -0,0 +1,10 @@
+namespace GodotSteam;
+
+[System.Flags]
+public enum HtmlKeyModifiers
+{
+ None = 0,
+ AltDown = 1,
+ CtrlDown = 2,
+ ShiftDown = 4,
+}
diff --git a/addons/godotsteam_csharpbindings/HTMLSurface/HtmlKeyModifiers.cs.uid b/addons/godotsteam_csharpbindings/HTMLSurface/HtmlKeyModifiers.cs.uid
new file mode 100644
index 00000000..0d0899e9
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/HTMLSurface/HtmlKeyModifiers.cs.uid
@@ -0,0 +1 @@
+uid://df61g7jsh3ups
diff --git a/addons/godotsteam_csharpbindings/HTMLSurface/HtmlLinkData.cs b/addons/godotsteam_csharpbindings/HTMLSurface/HtmlLinkData.cs
new file mode 100644
index 00000000..ce676ae4
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/HTMLSurface/HtmlLinkData.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace GodotSteam;
+
+public class HtmlLinkData
+{
+ public uint X { get; set; }
+ public uint Y { get; set; }
+ public Uri Url { get; set; }
+ public bool Input { get; set; }
+ public bool LiveLink { get; set; }
+}
diff --git a/addons/godotsteam_csharpbindings/HTMLSurface/HtmlLinkData.cs.uid b/addons/godotsteam_csharpbindings/HTMLSurface/HtmlLinkData.cs.uid
new file mode 100644
index 00000000..014fa01e
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/HTMLSurface/HtmlLinkData.cs.uid
@@ -0,0 +1 @@
+uid://bi0eri2eobb2
diff --git a/addons/godotsteam_csharpbindings/HTMLSurface/HtmlMouseButton.cs b/addons/godotsteam_csharpbindings/HTMLSurface/HtmlMouseButton.cs
new file mode 100644
index 00000000..7b3e6a34
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/HTMLSurface/HtmlMouseButton.cs
@@ -0,0 +1,8 @@
+namespace GodotSteam;
+
+public enum HtmlMouseButton
+{
+ Left = 0,
+ Right = 1,
+ Middle = 2,
+}
diff --git a/addons/godotsteam_csharpbindings/HTMLSurface/HtmlMouseButton.cs.uid b/addons/godotsteam_csharpbindings/HTMLSurface/HtmlMouseButton.cs.uid
new file mode 100644
index 00000000..a808c4dc
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/HTMLSurface/HtmlMouseButton.cs.uid
@@ -0,0 +1 @@
+uid://ds0jvl5uotr6q
diff --git a/addons/godotsteam_csharpbindings/HTMLSurface/HtmlMouseCursor.cs b/addons/godotsteam_csharpbindings/HTMLSurface/HtmlMouseCursor.cs
new file mode 100644
index 00000000..d8ae08cb
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/HTMLSurface/HtmlMouseCursor.cs
@@ -0,0 +1,47 @@
+namespace GodotSteam;
+
+public enum HtmlMouseCursor
+{
+ User = 0,
+ None = 1,
+ Arrow = 2,
+ Ibeam = 3,
+ HourGlass = 4,
+ WaitArrow = 5,
+ Crosshair = 6,
+ Up = 7,
+ SizeNw = 8,
+ SizeSe = 9,
+ SizeNe = 10,
+ SizeSw = 11,
+ SizeW = 12,
+ SizeE = 13,
+ SizeN = 14,
+ SizeS = 15,
+ SizeWe = 16,
+ SizeNs = 17,
+ SizeAll = 18,
+ No = 19,
+ Hand = 20,
+ Blank = 21,
+ MiddlePan = 22,
+ NorthPan = 23,
+ NorthEastPan = 24,
+ EastPan = 25,
+ SouthEastPan = 26,
+ SouthPan = 27,
+ SouthWestPan = 28,
+ WestPan = 29,
+ NorthWestPan = 30,
+ Alias = 31,
+ Cell = 32,
+ ColResize = 33,
+ CopyCur = 34,
+ VerticalText = 35,
+ RowResize = 36,
+ ZoomIn = 37,
+ ZoomOut = 38,
+ Help = 39,
+ Custom = 40,
+ Last = 41,
+}
diff --git a/addons/godotsteam_csharpbindings/HTMLSurface/HtmlMouseCursor.cs.uid b/addons/godotsteam_csharpbindings/HTMLSurface/HtmlMouseCursor.cs.uid
new file mode 100644
index 00000000..a67799be
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/HTMLSurface/HtmlMouseCursor.cs.uid
@@ -0,0 +1 @@
+uid://3kjwru52okfs
diff --git a/addons/godotsteam_csharpbindings/HTMLSurface/HtmlPageData.cs b/addons/godotsteam_csharpbindings/HTMLSurface/HtmlPageData.cs
new file mode 100644
index 00000000..1e247bfe
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/HTMLSurface/HtmlPageData.cs
@@ -0,0 +1,16 @@
+namespace GodotSteam;
+
+public class HtmlPageData
+{
+ public string Bgra { get; set; }
+ public uint Wide { get; set; }
+ public uint Tall { get; set; }
+ public uint UpdateX { get; set; }
+ public uint UpdateY { get; set; }
+ public uint UpdateWide { get; set; }
+ public uint UpdateTall { get; set; }
+ public uint ScrollX { get; set; }
+ public uint ScrollY { get; set; }
+ public float PageScale { get; set; }
+ public uint PageSerial { get; set; }
+}
diff --git a/addons/godotsteam_csharpbindings/HTMLSurface/HtmlPageData.cs.uid b/addons/godotsteam_csharpbindings/HTMLSurface/HtmlPageData.cs.uid
new file mode 100644
index 00000000..bcfc4871
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/HTMLSurface/HtmlPageData.cs.uid
@@ -0,0 +1 @@
+uid://2hwis0agec34
diff --git a/addons/godotsteam_csharpbindings/HTMLSurface/HtmlScrollData.cs b/addons/godotsteam_csharpbindings/HTMLSurface/HtmlScrollData.cs
new file mode 100644
index 00000000..8945e3c4
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/HTMLSurface/HtmlScrollData.cs
@@ -0,0 +1,10 @@
+namespace GodotSteam;
+
+public class HtmlScrollData
+{
+ public uint ScrollMax { get; set; }
+ public uint ScrollCurrent { get; set; }
+ public float PageScale { get; set; }
+ public bool Visible { get; set; }
+ public uint PageSize { get; set; }
+}
diff --git a/addons/godotsteam_csharpbindings/HTMLSurface/HtmlScrollData.cs.uid b/addons/godotsteam_csharpbindings/HTMLSurface/HtmlScrollData.cs.uid
new file mode 100644
index 00000000..c5edb45c
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/HTMLSurface/HtmlScrollData.cs.uid
@@ -0,0 +1 @@
+uid://q26dio7sxrhn
diff --git a/addons/godotsteam_csharpbindings/HTMLSurface/HtmlUrlData.cs b/addons/godotsteam_csharpbindings/HTMLSurface/HtmlUrlData.cs
new file mode 100644
index 00000000..e84d4591
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/HTMLSurface/HtmlUrlData.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace GodotSteam;
+
+public class HtmlUrlData
+{
+ public Uri Url { get; set; }
+ public string PostData { get; set; }
+ public bool Redirect { get; set; }
+ public string Title { get; set; }
+ public bool NewNavigation { get; set; }
+}
diff --git a/addons/godotsteam_csharpbindings/HTMLSurface/HtmlUrlData.cs.uid b/addons/godotsteam_csharpbindings/HTMLSurface/HtmlUrlData.cs.uid
new file mode 100644
index 00000000..e9a7eb41
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/HTMLSurface/HtmlUrlData.cs.uid
@@ -0,0 +1 @@
+uid://csy1ygrcmmbex
diff --git a/addons/godotsteam_csharpbindings/HTMLSurface/HtmlWindowData.cs b/addons/godotsteam_csharpbindings/HTMLSurface/HtmlWindowData.cs
new file mode 100644
index 00000000..6dc05660
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/HTMLSurface/HtmlWindowData.cs
@@ -0,0 +1,13 @@
+using System;
+
+namespace GodotSteam;
+
+public class HtmlWindowData
+{
+ public Uri Url { get; set; }
+ public uint X { get; set; }
+ public uint Y { get; set; }
+ public uint Wide { get; set; }
+ public uint Tall { get; set; }
+ public uint NewHandle { get; set; }
+}
diff --git a/addons/godotsteam_csharpbindings/HTMLSurface/HtmlWindowData.cs.uid b/addons/godotsteam_csharpbindings/HTMLSurface/HtmlWindowData.cs.uid
new file mode 100644
index 00000000..8f8081fe
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/HTMLSurface/HtmlWindowData.cs.uid
@@ -0,0 +1 @@
+uid://bwsbr20488yhh
diff --git a/addons/godotsteam_csharpbindings/Methods.cs b/addons/godotsteam_csharpbindings/Methods.cs
new file mode 100644
index 00000000..6252715b
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Methods.cs
@@ -0,0 +1,794 @@
+using Godot;
+
+namespace GodotSteam;
+
+public static class Methods
+{
+ public static readonly StringName IsSteamRunning = "isSteamRunning";
+ public static readonly StringName RunCallbacks = "run_callbacks";
+ public static readonly StringName RestartAppIfNecessary = "restartAppIfNecessary";
+ public static readonly StringName SteamInit = "steamInit";
+ public static readonly StringName SteamInitEx = "steamInitEx";
+ public static readonly StringName SteamShutdown = "steamShutdown";
+ public static readonly StringName GetDLCDataByIndex = "getDLCDataByIndex";
+ public static readonly StringName IsAppInstalled = "isAppInstalled";
+ public static readonly StringName IsCybercafe = "isCybercafe";
+ public static readonly StringName IsDLCInstalled = "isDLCInstalled";
+ public static readonly StringName IsLowViolence = "isLowViolence";
+ public static readonly StringName IsSubscribed = "isSubscribed";
+ public static readonly StringName IsSubscribedApp = "isSubscribedApp";
+ public static readonly StringName IsSubscribedFromFamilySharing =
+ "isSubscribedFromFamilySharing";
+ public static readonly StringName IsSubscribedFromFreeWeekend = "isSubscribedFromFreeWeekend";
+ public static readonly StringName IsTimedTrial = "isTimedTrial";
+ public static readonly StringName IsVACBanned = "isVACBanned";
+ public static readonly StringName GetAppBuildId = "getAppBuildId";
+ public static readonly StringName GetAppInstallDir = "getAppInstallDir";
+ public static readonly StringName GetAppOwner = "getAppOwner";
+ public static readonly StringName GetAvailableGameLanguages = "getAvailableGameLanguages";
+ public static readonly StringName GetCurrentBetaName = "getCurrentBetaName";
+ public static readonly StringName GetCurrentGameLanguage = "getCurrentGameLanguage";
+ public static readonly StringName GetDLCCount = "getDLCCount";
+ public static readonly StringName GetDLCDownloadProgress = "getDLCDownloadProgress";
+ public static readonly StringName GetEarliestPurchaseUnixTime = "getEarliestPurchaseUnixTime";
+ public static readonly StringName GetFileDetails = "getFileDetails";
+ public static readonly StringName GetInstalledDepots = "getInstalledDepots";
+ public static readonly StringName GetLaunchCommandLine = "getLaunchCommandLine";
+ public static readonly StringName GetLaunchQueryParam = "getLaunchQueryParam";
+ public static readonly StringName InstallDLC = "installDLC";
+ public static readonly StringName MarkContentCorrupt = "markContentCorrupt";
+ public static readonly StringName SetDLCContext = "setDLCContext";
+ public static readonly StringName UninstallDLC = "uninstallDLC";
+ public static readonly StringName GetNumInstalledApps = "getNumInstalledApps";
+ public static readonly StringName GetInstalledApps = "getInstalledApps";
+ public static readonly StringName GetAppName = "getAppName";
+ public static readonly StringName GetAppListInstallDir = "getAppListInstallDir";
+ public static readonly StringName GetAppListBuildId = "getAppListBuildId";
+ public static readonly StringName ActivateGameOverlay = "activateGameOverlay";
+ public static readonly StringName ActivateGameOverlayInviteDialog =
+ "activateGameOverlayInviteDialog";
+ public static readonly StringName ActivateGameOverlayInviteDialogConnectString =
+ "activateGameOverlayInviteDialogConnectString";
+ public static readonly StringName ActivateGameOverlayToStore = "activateGameOverlayToStore";
+ public static readonly StringName ActivateGameOverlayToUser = "activateGameOverlayToUser";
+ public static readonly StringName ActivateGameOverlayToWebPage = "activateGameOverlayToWebPage";
+ public static readonly StringName ClearRichPresence = "clearRichPresence";
+ public static readonly StringName CloseClanChatWindowInSteam = "closeClanChatWindowInSteam";
+ public static readonly StringName DownloadClanActivityCounts = "downloadClanActivityCounts";
+ public static readonly StringName EnumerateFollowingList = "enumerateFollowingList";
+ public static readonly StringName GetChatMemberByIndex = "getChatMemberByIndex";
+ public static readonly StringName GetClanActivityCounts = "getClanActivityCounts";
+ public static readonly StringName GetClanByIndex = "getClanByIndex";
+ public static readonly StringName GetClanChatMemberCount = "getClanChatMemberCount";
+ public static readonly StringName GetClanChatMessage = "getClanChatMessage";
+ public static readonly StringName GetClanCount = "getClanCount";
+ public static readonly StringName GetClanName = "getClanName";
+ public static readonly StringName GetClanOfficerByIndex = "getClanOfficerByIndex";
+ public static readonly StringName GetClanOfficerCount = "getClanOfficerCount";
+ public static readonly StringName GetClanOwner = "getClanOwner";
+ public static readonly StringName GetClanTag = "getClanTag";
+ public static readonly StringName GetCoplayFriend = "getCoplayFriend";
+ public static readonly StringName GetCoplayFriendCount = "getCoplayFriendCount";
+ public static readonly StringName GetFollowerCount = "getFollowerCount";
+ public static readonly StringName GetFriendByIndex = "getFriendByIndex";
+ public static readonly StringName GetFriendCoplayGame = "getFriendCoplayGame";
+ public static readonly StringName GetFriendCoplayTime = "getFriendCoplayTime";
+ public static readonly StringName GetFriendCount = "getFriendCount";
+ public static readonly StringName GetFriendCountFromSource = "getFriendCountFromSource";
+ public static readonly StringName GetFriendFromSourceByIndex = "getFriendFromSourceByIndex";
+ public static readonly StringName GetFriendGamePlayed = "getFriendGamePlayed";
+ public static readonly StringName GetFriendMessage = "getFriendMessage";
+ public static readonly StringName GetFriendPersonaName = "getFriendPersonaName";
+ public static readonly StringName GetFriendPersonaNameHistory = "getFriendPersonaNameHistory";
+ public static readonly StringName GetFriendPersonaState = "getFriendPersonaState";
+ public static readonly StringName GetFriendRelationship = "getFriendRelationship";
+ public static readonly StringName GetFriendRichPresence = "getFriendRichPresence";
+ public static readonly StringName GetFriendRichPresenceKeyCount =
+ "getFriendRichPresenceKeyCount";
+ public static readonly StringName GetFriendRichPresenceKeyByIndex =
+ "getFriendRichPresenceKeyByIndex";
+ public static readonly StringName GetFriendsGroupCount = "getFriendsGroupCount";
+ public static readonly StringName GetFriendsGroupIDByIndex = "getFriendsGroupIDByIndex";
+ public static readonly StringName GetFriendsGroupMembersCount = "getFriendsGroupMembersCount";
+ public static readonly StringName GetFriendsGroupMembersList = "getFriendsGroupMembersList";
+ public static readonly StringName GetFriendsGroupName = "getFriendsGroupName";
+ public static readonly StringName GetFriendSteamLevel = "getFriendSteamLevel";
+ public static readonly StringName GetLargeFriendAvatar = "getLargeFriendAvatar";
+ public static readonly StringName GetMediumFriendAvatar = "getMediumFriendAvatar";
+ public static readonly StringName GetPersonaName = "getPersonaName";
+ public static readonly StringName GetPersonaState = "getPersonaState";
+ public static readonly StringName GetPlayerAvatar = "getPlayerAvatar";
+ public static readonly StringName GetPlayerNickname = "getPlayerNickname";
+ public static readonly StringName GetProfileItemPropertyString = "getProfileItemPropertyString";
+ public static readonly StringName GetProfileItemPropertyInt = "getProfileItemPropertyInt";
+ public static readonly StringName GetRecentPlayers = "getRecentPlayers";
+ public static readonly StringName GetSmallFriendAvatar = "getSmallFriendAvatar";
+ public static readonly StringName GetUserFriendsGroups = "getUserFriendsGroups";
+ public static readonly StringName GetUserRestrictions = "getUserRestrictions";
+ public static readonly StringName GetUserSteamFriends = "getUserSteamFriends";
+ public static readonly StringName GetUserSteamGroups = "getUserSteamGroups";
+ public static readonly StringName HasEquippedProfileItem = "hasEquippedProfileItem";
+ public static readonly StringName HasFriend = "hasFriend";
+ public static readonly StringName InviteUserToGame = "inviteUserToGame";
+ public static readonly StringName IsClanChatAdmin = "isClanChatAdmin";
+ public static readonly StringName IsClanPublic = "isClanPublic";
+ public static readonly StringName IsClanOfficialGameGroup = "isClanOfficialGameGroup";
+ public static readonly StringName IsClanChatWindowOpenInSteam = "isClanChatWindowOpenInSteam";
+ public static readonly StringName IsFollowing = "isFollowing";
+ public static readonly StringName IsUserInSource = "isUserInSource";
+ public static readonly StringName JoinClanChatRoom = "joinClanChatRoom";
+ public static readonly StringName LeaveClanChatRoom = "leaveClanChatRoom";
+ public static readonly StringName OpenClanChatWindowInSteam = "openClanChatWindowInSteam";
+ public static readonly StringName RegisterProtocolInOverlayBrowser =
+ "registerProtocolInOverlayBrowser";
+ public static readonly StringName ReplyToFriendMessage = "replyToFriendMessage";
+ public static readonly StringName RequestClanOfficerList = "requestClanOfficerList";
+ public static readonly StringName RequestEquippedProfileItems = "requestEquippedProfileItems";
+ public static readonly StringName RequestFriendRichPresence = "requestFriendRichPresence";
+ public static readonly StringName RequestUserInformation = "requestUserInformation";
+ public static readonly StringName SendClanChatMessage = "sendClanChatMessage";
+ public static readonly StringName SetInGameVoiceSpeaking = "setInGameVoiceSpeaking";
+ public static readonly StringName SetListenForFriendsMessages = "setListenForFriendsMessages";
+ public static readonly StringName SetPersonaName = "setPersonaName";
+ public static readonly StringName SetPlayedWith = "setPlayedWith";
+ public static readonly StringName SetRichPresence = "setRichPresence";
+ public static readonly StringName AddGameSearchParams = "addGameSearchParams";
+ public static readonly StringName SearchForGameWithLobby = "searchForGameWithLobby";
+ public static readonly StringName SearchForGameSolo = "searchForGameSolo";
+ public static readonly StringName AcceptGame = "acceptGame";
+ public static readonly StringName DeclineGame = "declineGame";
+ public static readonly StringName RetrieveConnectionDetails = "retrieveConnectionDetails";
+ public static readonly StringName EndGameSearch = "endGameSearch";
+ public static readonly StringName SetGameHostParams = "setGameHostParams";
+ public static readonly StringName SetConnectionDetails = "setConnectionDetails";
+ public static readonly StringName RequestPlayersForGame = "requestPlayersForGame";
+ public static readonly StringName HostConfirmGameStart = "hostConfirmGameStart";
+ public static readonly StringName CancelRequestPlayersForGame = "cancelRequestPlayersForGame";
+ public static readonly StringName SubmitPlayerResult = "submitPlayerResult";
+ public static readonly StringName EndGame = "endGame";
+ public static readonly StringName AddHeader = "addHeader";
+ public static readonly StringName AllowStartRequest = "allowStartRequest";
+ public static readonly StringName CopyToClipboard = "copyToClipboard";
+ public static readonly StringName CreateBrowser = "createBrowser";
+ public static readonly StringName ExecuteJavascript = "executeJavascript";
+ public static readonly StringName Find = "find";
+ public static readonly StringName GetLinkAtPosition = "getLinkAtPosition";
+ public static readonly StringName GoBack = "goBack";
+ public static readonly StringName GoForward = "goForward";
+ public static readonly StringName HtmlInit = "htmlInit";
+ public static readonly StringName JsDialogResponse = "jsDialogResponse";
+ public static readonly StringName KeyChar = "keyChar";
+ public static readonly StringName KeyDown = "keyDown";
+ public static readonly StringName KeyUp = "keyUp";
+ public static readonly StringName LoadURL = "loadURL";
+ public static readonly StringName MouseDoubleClick = "mouseDoubleClick";
+ public static readonly StringName MouseDown = "mouseDown";
+ public static readonly StringName MouseMove = "mouseMove";
+ public static readonly StringName MouseUp = "mouseUp";
+ public static readonly StringName MouseWheel = "mouseWheel";
+ public static readonly StringName PasteFromClipboard = "pasteFromClipboard";
+ public static readonly StringName Reload = "reload";
+ public static readonly StringName RemoveBrowser = "removeBrowser";
+ public static readonly StringName SetBackgroundMode = "setBackgroundMode";
+ public static readonly StringName SetCookie = "setCookie";
+ public static readonly StringName SetHorizontalScroll = "setHorizontalScroll";
+ public static readonly StringName SetKeyFocus = "setKeyFocus";
+ public static readonly StringName SetPageScaleFactor = "setPageScaleFactor";
+ public static readonly StringName SetSize = "setSize";
+ public static readonly StringName SetVerticalScroll = "setVerticalScroll";
+ public static readonly StringName HtmlShutdown = "htmlShutdown";
+ public static readonly StringName StopFind = "stopFind";
+ public static readonly StringName StopLoad = "stopLoad";
+ public static readonly StringName ViewSource = "viewSource";
+ public static readonly StringName CreateCookieContainer = "createCookieContainer";
+ public static readonly StringName CreateHTTPRequest = "createHTTPRequest";
+ public static readonly StringName DeferHTTPRequest = "deferHTTPRequest";
+ public static readonly StringName GetHTTPDownloadProgressPct = "getHTTPDownloadProgressPct";
+ public static readonly StringName GetHTTPRequestWasTimedOut = "getHTTPRequestWasTimedOut";
+ public static readonly StringName GetHTTPResponseBodyData = "getHTTPResponseBodyData";
+ public static readonly StringName GetHTTPResponseBodySize = "getHTTPResponseBodySize";
+ public static readonly StringName GetHTTPResponseHeaderSize = "getHTTPResponseHeaderSize";
+ public static readonly StringName GetHTTPResponseHeaderValue = "getHTTPResponseHeaderValue";
+ public static readonly StringName GetHTTPStreamingResponseBodyData =
+ "getHTTPStreamingResponseBodyData";
+ public static readonly StringName PrioritizeHTTPRequest = "prioritizeHTTPRequest";
+ public static readonly StringName ReleaseCookieContainer = "releaseCookieContainer";
+ public static readonly StringName ReleaseHTTPRequest = "releaseHTTPRequest";
+ public static readonly StringName SendHTTPRequest = "sendHTTPRequest";
+ public static readonly StringName SendHTTPRequestAndStreamResponse =
+ "sendHTTPRequestAndStreamResponse";
+ public static readonly StringName SetHTTPCookie = "setHTTPCookie";
+ public static readonly StringName SetHTTPRequestAbsoluteTimeoutMS =
+ "setHTTPRequestAbsoluteTimeoutMS";
+ public static readonly StringName SetHTTPRequestContextValue = "setHTTPRequestContextValue";
+ public static readonly StringName SetHTTPRequestCookieContainer =
+ "setHTTPRequestCookieContainer";
+ public static readonly StringName SetHTTPRequestGetOrPostParameter =
+ "setHTTPRequestGetOrPostParameter";
+ public static readonly StringName SetHTTPRequestHeaderValue = "setHTTPRequestHeaderValue";
+ public static readonly StringName SetHTTPRequestNetworkActivityTimeout =
+ "setHTTPRequestNetworkActivityTimeout";
+ public static readonly StringName SetHTTPRequestRawPostBody = "setHTTPRequestRawPostBody";
+ public static readonly StringName SetHTTPRequestRequiresVerifiedCertificate =
+ "setHTTPRequestRequiresVerifiedCertificate";
+ public static readonly StringName SetHTTPRequestUserAgentInfo = "setHTTPRequestUserAgentInfo";
+ public static readonly StringName ActivateActionSet = "activateActionSet";
+ public static readonly StringName ActivateActionSetLayer = "activateActionSetLayer";
+ public static readonly StringName DeactivateActionSetLayer = "deactivateActionSetLayer";
+ public static readonly StringName DeactivateAllActionSetLayers = "deactivateAllActionSetLayers";
+ public static readonly StringName GetActionSetHandle = "getActionSetHandle";
+ public static readonly StringName GetActionOriginFromXboxOrigin =
+ "getActionOriginFromXboxOrigin";
+ public static readonly StringName GetActiveActionSetLayers = "getActiveActionSetLayers";
+ public static readonly StringName GetAnalogActionData = "getAnalogActionData";
+ public static readonly StringName GetAnalogActionHandle = "getAnalogActionHandle";
+ public static readonly StringName GetAnalogActionOrigins = "getAnalogActionOrigins";
+ public static readonly StringName GetConnectedControllers = "getConnectedControllers";
+ public static readonly StringName GetControllerForGamepadIndex = "getControllerForGamepadIndex";
+ public static readonly StringName GetCurrentActionSet = "getCurrentActionSet";
+ public static readonly StringName GetDeviceBindingRevision = "getDeviceBindingRevision";
+ public static readonly StringName GetDigitalActionData = "getDigitalActionData";
+ public static readonly StringName GetDigitalActionHandle = "getDigitalActionHandle";
+ public static readonly StringName GetDigitalActionOrigins = "getDigitalActionOrigins";
+ public static readonly StringName GetGamepadIndexForController = "getGamepadIndexForController";
+ public static readonly StringName GetGlyphForActionOrigin = "getGlyphForActionOrigin";
+ public static readonly StringName GetInputTypeForHandle = "getInputTypeForHandle";
+ public static readonly StringName GetMotionData = "getMotionData";
+ public static readonly StringName GetRemotePlaySessionID = "getRemotePlaySessionID";
+ public static readonly StringName GetStringForActionOrigin = "getStringForActionOrigin";
+ public static readonly StringName InputInit = "inputInit";
+ public static readonly StringName InputShutdown = "inputShutdown";
+ public static readonly StringName RunFrame = "runFrame";
+ public static readonly StringName SetLEDColor = "setLEDColor";
+ public static readonly StringName ShowBindingPanel = "showBindingPanel";
+ public static readonly StringName StopAnalogActionMomentum = "stopAnalogActionMomentum";
+ public static readonly StringName TranslateActionOrigin = "translateActionOrigin";
+ public static readonly StringName TriggerHapticPulse = "triggerHapticPulse";
+ public static readonly StringName TriggerRepeatedHapticPulse = "triggerRepeatedHapticPulse";
+ public static readonly StringName TriggerVibration = "triggerVibration";
+ public static readonly StringName SetInputActionManifestFilePath =
+ "setInputActionManifestFilePath";
+ public static readonly StringName SetDualSenseTriggerEffect = "setDualSenseTriggerEffect";
+ public static readonly StringName WaitForData = "waitForData";
+ public static readonly StringName NewDataAvailable = "newDataAvailable";
+ public static readonly StringName EnableDeviceCallbacks = "enableDeviceCallbacks";
+ public static readonly StringName GetGlyphPNGForActionOrigin = "getGlyphPNGForActionOrigin";
+ public static readonly StringName GetGlyphSVGForActionOrigin = "getGlyphSVGForActionOrigin";
+ public static readonly StringName TriggerVibrationExtended = "triggerVibrationExtended";
+ public static readonly StringName TriggerSimpleHapticEvent = "triggerSimpleHapticEvent";
+ public static readonly StringName GetStringForXboxOrigin = "getStringForXboxOrigin";
+ public static readonly StringName GetGlyphForXboxOrigin = "getGlyphForXboxOrigin";
+ public static readonly StringName GetSessionInputConfigurationSettings =
+ "getSessionInputConfigurationSettings";
+ public static readonly StringName GetStringForDigitalActionName =
+ "getStringForDigitalActionName";
+ public static readonly StringName GetStringForAnalogActionName = "getStringForAnalogActionName";
+ public static readonly StringName AddPromoItem = "addPromoItem";
+ public static readonly StringName AddPromoItems = "addPromoItems";
+ public static readonly StringName CheckResultSteamID = "checkResultSteamID";
+ public static readonly StringName ConsumeItem = "consumeItem";
+ public static readonly StringName DeserializeResult = "deserializeResult";
+ public static readonly StringName DestroyResult = "destroyResult";
+ public static readonly StringName ExchangeItems = "exchangeItems";
+ public static readonly StringName GenerateItems = "generateItems";
+ public static readonly StringName GetAllItems = "getAllItems";
+ public static readonly StringName GetItemDefinitionProperty = "getItemDefinitionProperty";
+ public static readonly StringName GetItemsByID = "getItemsByID";
+ public static readonly StringName GetItemPrice = "getItemPrice";
+ public static readonly StringName GetItemsWithPrices = "getItemsWithPrices";
+ public static readonly StringName GetNumItemsWithPrices = "getNumItemsWithPrices";
+ public static readonly StringName GetResultItemProperty = "getResultItemProperty";
+ public static readonly StringName GetResultItems = "getResultItems";
+ public static readonly StringName GetResultStatus = "getResultStatus";
+ public static readonly StringName GetResultTimestamp = "getResultTimestamp";
+ public static readonly StringName GrantPromoItems = "grantPromoItems";
+ public static readonly StringName LoadItemDefinitions = "loadItemDefinitions";
+ public static readonly StringName RequestEligiblePromoItemDefinitionsIDs =
+ "requestEligiblePromoItemDefinitionsIDs";
+ public static readonly StringName RequestPrices = "requestPrices";
+ public static readonly StringName SerializeResult = "serializeResult";
+ public static readonly StringName StartPurchase = "startPurchase";
+ public static readonly StringName TransferItemQuantity = "transferItemQuantity";
+ public static readonly StringName TriggerItemDrop = "triggerItemDrop";
+ public static readonly StringName StartUpdateProperties = "startUpdateProperties";
+ public static readonly StringName SubmitUpdateProperties = "submitUpdateProperties";
+ public static readonly StringName RemoveProperty = "removeProperty";
+ public static readonly StringName SetPropertyString = "setPropertyString";
+ public static readonly StringName SetPropertyBool = "setPropertyBool";
+ public static readonly StringName SetPropertyInt = "setPropertyInt";
+ public static readonly StringName SetPropertyFloat = "setPropertyFloat";
+ public static readonly StringName GetFavoriteGames = "getFavoriteGames";
+ public static readonly StringName AddFavoriteGame = "addFavoriteGame";
+ public static readonly StringName RemoveFavoriteGame = "removeFavoriteGame";
+ public static readonly StringName RequestLobbyList = "requestLobbyList";
+ public static readonly StringName AddRequestLobbyListStringFilter =
+ "addRequestLobbyListStringFilter";
+ public static readonly StringName AddRequestLobbyListNumericalFilter =
+ "addRequestLobbyListNumericalFilter";
+ public static readonly StringName AddRequestLobbyListNearValueFilter =
+ "addRequestLobbyListNearValueFilter";
+ public static readonly StringName AddRequestLobbyListFilterSlotsAvailable =
+ "addRequestLobbyListFilterSlotsAvailable";
+ public static readonly StringName AddRequestLobbyListDistanceFilter =
+ "addRequestLobbyListDistanceFilter";
+ public static readonly StringName AddRequestLobbyListResultCountFilter =
+ "addRequestLobbyListResultCountFilter";
+ public static readonly StringName CreateLobby = "createLobby";
+ public static readonly StringName JoinLobby = "joinLobby";
+ public static readonly StringName LeaveLobby = "leaveLobby";
+ public static readonly StringName InviteUserToLobby = "inviteUserToLobby";
+ public static readonly StringName GetNumLobbyMembers = "getNumLobbyMembers";
+ public static readonly StringName GetLobbyMemberByIndex = "getLobbyMemberByIndex";
+ public static readonly StringName GetLobbyData = "getLobbyData";
+ public static readonly StringName SetLobbyData = "setLobbyData";
+ public static readonly StringName GetAllLobbyData = "getAllLobbyData";
+ public static readonly StringName DeleteLobbyData = "deleteLobbyData";
+ public static readonly StringName GetLobbyMemberData = "getLobbyMemberData";
+ public static readonly StringName SetLobbyMemberData = "setLobbyMemberData";
+ public static readonly StringName SendLobbyChatMsg = "sendLobbyChatMsg";
+ public static readonly StringName RequestLobbyData = "requestLobbyData";
+ public static readonly StringName SetLobbyGameServer = "setLobbyGameServer";
+ public static readonly StringName GetLobbyGameServer = "getLobbyGameServer";
+ public static readonly StringName SetLobbyMemberLimit = "setLobbyMemberLimit";
+ public static readonly StringName GetLobbyMemberLimit = "getLobbyMemberLimit";
+ public static readonly StringName SetLobbyType = "setLobbyType";
+ public static readonly StringName SetLobbyJoinable = "setLobbyJoinable";
+ public static readonly StringName GetLobbyOwner = "getLobbyOwner";
+ public static readonly StringName SetLobbyOwner = "setLobbyOwner";
+ public static readonly StringName CancelQuery = "cancelQuery";
+ public static readonly StringName CancelServerQuery = "cancelServerQuery";
+ public static readonly StringName GetServerCount = "getServerCount";
+ public static readonly StringName GetServerDetails = "getServerDetails";
+ public static readonly StringName IsRefreshing = "isRefreshing";
+ public static readonly StringName PingServer = "pingServer";
+ public static readonly StringName PlayerDetails = "playerDetails";
+ public static readonly StringName RefreshQuery = "refreshQuery";
+ public static readonly StringName RefreshServer = "refreshServer";
+ public static readonly StringName ReleaseRequest = "releaseRequest";
+ public static readonly StringName RequestFavoritesServerList = "requestFavoritesServerList";
+ public static readonly StringName RequestFriendsServerList = "requestFriendsServerList";
+ public static readonly StringName RequestHistoryServerList = "requestHistoryServerList";
+ public static readonly StringName RequestInternetServerList = "requestInternetServerList";
+ public static readonly StringName RequestLANServerList = "requestLANServerList";
+ public static readonly StringName RequestSpectatorServerList = "requestSpectatorServerList";
+ public static readonly StringName ServerRules = "serverRules";
+ public static readonly StringName MusicIsEnabled = "musicIsEnabled";
+ public static readonly StringName MusicIsPlaying = "musicIsPlaying";
+ public static readonly StringName GetPlaybackStatus = "getPlaybackStatus";
+ public static readonly StringName MusicGetVolume = "musicGetVolume";
+ public static readonly StringName MusicPause = "musicPause";
+ public static readonly StringName MusicPlay = "musicPlay";
+ public static readonly StringName MusicPlayNext = "musicPlayNext";
+ public static readonly StringName MusicPlayPrev = "musicPlayPrev";
+ public static readonly StringName MusicSetVolume = "musicSetVolume";
+ public static readonly StringName ActivationSuccess = "activationSuccess";
+ public static readonly StringName IsCurrentMusicRemote = "isCurrentMusicRemote";
+ public static readonly StringName CurrentEntryDidChange = "currentEntryDidChange";
+ public static readonly StringName CurrentEntryIsAvailable = "currentEntryIsAvailable";
+ public static readonly StringName CurrentEntryWillChange = "currentEntryWillChange";
+ public static readonly StringName DeregisterSteamMusicRemote = "deregisterSteamMusicRemote";
+ public static readonly StringName EnableLooped = "enableLooped";
+ public static readonly StringName EnablePlaylists = "enablePlaylists";
+ public static readonly StringName EnablePlayNext = "enablePlayNext";
+ public static readonly StringName EnablePlayPrevious = "enablePlayPrevious";
+ public static readonly StringName EnableQueue = "enableQueue";
+ public static readonly StringName EnableShuffled = "enableShuffled";
+ public static readonly StringName PlaylistDidChange = "playlistDidChange";
+ public static readonly StringName PlaylistWillChange = "playlistWillChange";
+ public static readonly StringName QueueDidChange = "queueDidChange";
+ public static readonly StringName QueueWillChange = "queueWillChange";
+ public static readonly StringName RegisterSteamMusicRemote = "registerSteamMusicRemote";
+ public static readonly StringName ResetPlaylistEntries = "resetPlaylistEntries";
+ public static readonly StringName ResetQueueEntries = "resetQueueEntries";
+ public static readonly StringName SetCurrentPlaylistEntry = "setCurrentPlaylistEntry";
+ public static readonly StringName SetCurrentQueueEntry = "setCurrentQueueEntry";
+ public static readonly StringName SetDisplayName = "setDisplayName";
+ public static readonly StringName SetPlaylistEntry = "setPlaylistEntry";
+ public static readonly StringName SetPNGIcon64X64 = "setPNGIcon64x64";
+ public static readonly StringName SetQueueEntry = "setQueueEntry";
+ public static readonly StringName UpdateCurrentEntryCoverArt = "updateCurrentEntryCoverArt";
+ public static readonly StringName UpdateCurrentEntryElapsedSeconds =
+ "updateCurrentEntryElapsedSeconds";
+ public static readonly StringName UpdateCurrentEntryText = "updateCurrentEntryText";
+ public static readonly StringName UpdateLooped = "updateLooped";
+ public static readonly StringName UpdatePlaybackStatus = "updatePlaybackStatus";
+ public static readonly StringName UpdateShuffled = "updateShuffled";
+ public static readonly StringName UpdateVolume = "updateVolume";
+ public static readonly StringName AcceptP2PSessionWithUser = "acceptP2PSessionWithUser";
+ public static readonly StringName AllowP2PPacketRelay = "allowP2PPacketRelay";
+ public static readonly StringName CloseP2PChannelWithUser = "closeP2PChannelWithUser";
+ public static readonly StringName CloseP2PSessionWithUser = "closeP2PSessionWithUser";
+ public static readonly StringName GetP2PSessionState = "getP2PSessionState";
+ public static readonly StringName GetAvailableP2PPacketSize = "getAvailableP2PPacketSize";
+ public static readonly StringName ReadP2PPacket = "readP2PPacket";
+ public static readonly StringName SendP2PPacket = "sendP2PPacket";
+ public static readonly StringName AcceptSessionWithUser = "acceptSessionWithUser";
+ public static readonly StringName CloseChannelWithUser = "closeChannelWithUser";
+ public static readonly StringName CloseSessionWithUser = "closeSessionWithUser";
+ public static readonly StringName GetSessionConnectionInfo = "getSessionConnectionInfo";
+ public static readonly StringName ReceiveMessagesOnChannel = "receiveMessagesOnChannel";
+ public static readonly StringName SendMessageToUser = "sendMessageToUser";
+ public static readonly StringName AcceptConnection = "acceptConnection";
+ public static readonly StringName BeginAsyncRequestFakeIP = "beginAsyncRequestFakeIP";
+ public static readonly StringName CloseConnection = "closeConnection";
+ public static readonly StringName CloseListenSocket = "closeListenSocket";
+ public static readonly StringName ConfigureConnectionLanes = "configureConnectionLanes";
+ public static readonly StringName ConnectP2P = "connectP2P";
+ public static readonly StringName ConnectByIPAddress = "connectByIPAddress";
+ public static readonly StringName ConnectToHostedDedicatedServer =
+ "connectToHostedDedicatedServer";
+ public static readonly StringName CreateFakeUDPPort = "createFakeUDPPort";
+ public static readonly StringName CreateHostedDedicatedServerListenSocket =
+ "createHostedDedicatedServerListenSocket";
+ public static readonly StringName CreateListenSocketIP = "createListenSocketIP";
+ public static readonly StringName CreateListenSocketP2P = "createListenSocketP2P";
+ public static readonly StringName CreateListenSocketP2PFakeIP = "createListenSocketP2PFakeIP";
+ public static readonly StringName CreatePollGroup = "createPollGroup";
+ public static readonly StringName CreateSocketPair = "createSocketPair";
+ public static readonly StringName DestroyPollGroup = "destroyPollGroup";
+ public static readonly StringName FlushMessagesOnConnection = "flushMessagesOnConnection";
+ public static readonly StringName GetAuthenticationStatus = "getAuthenticationStatus";
+ public static readonly StringName GetCertificateRequest = "getCertificateRequest";
+ public static readonly StringName GetConnectionInfo = "getConnectionInfo";
+ public static readonly StringName GetConnectionName = "getConnectionName";
+ public static readonly StringName GetConnectionRealTimeStatus = "getConnectionRealTimeStatus";
+ public static readonly StringName GetConnectionUserData = "getConnectionUserData";
+ public static readonly StringName GetDetailedConnectionStatus = "getDetailedConnectionStatus";
+ public static readonly StringName GetFakeIP = "getFakeIP";
+ public static readonly StringName GetHostedDedicatedServerPOPId =
+ "getHostedDedicatedServerPOPId";
+ public static readonly StringName GetHostedDedicatedServerPort = "getHostedDedicatedServerPort";
+ public static readonly StringName GetListenSocketAddress = "getListenSocketAddress";
+ public static readonly StringName GetIdentity = "getIdentity";
+ public static readonly StringName GetRemoteFakeIPForConnection = "getRemoteFakeIPForConnection";
+ public static readonly StringName InitAuthentication = "initAuthentication";
+ public static readonly StringName ReceiveMessagesOnConnection = "receiveMessagesOnConnection";
+ public static readonly StringName ReceiveMessagesOnPollGroup = "receiveMessagesOnPollGroup";
+ public static readonly StringName ResetIdentity = "resetIdentity";
+ public static readonly StringName RunNetworkingCallbacks = "runNetworkingCallbacks";
+ public static readonly StringName SendMessages = "sendMessages";
+ public static readonly StringName SendMessageToConnection = "sendMessageToConnection";
+ public static readonly StringName SetCertificate = "setCertificate";
+ public static readonly StringName SetConnectionPollGroup = "setConnectionPollGroup";
+ public static readonly StringName SetConnectionName = "setConnectionName";
+ public static readonly StringName AddIdentity = "addIdentity";
+ public static readonly StringName AddIPAddress = "addIPAddress";
+ public static readonly StringName ClearIdentity = "clearIdentity";
+ public static readonly StringName ClearIPAddress = "clearIPAddress";
+ public static readonly StringName GetGenericBytes = "getGenericBytes";
+ public static readonly StringName GetGenericString = "getGenericString";
+ public static readonly StringName GetIdentities = "getIdentities";
+ public static readonly StringName GetIdentityIPAddr = "getIdentityIPAddr";
+ public static readonly StringName GetIdentitySteamID = "getIdentitySteamID";
+ public static readonly StringName GetIdentitySteamID64 = "getIdentitySteamID64";
+ public static readonly StringName GetIPAddresses = "getIPAddresses";
+ public static readonly StringName GetIPv4 = "getIPv4";
+ public static readonly StringName GetPSNID = "getPSNID";
+ public static readonly StringName GetStadiaID = "getStadiaID";
+ public static readonly StringName GetXboxPairwiseID = "getXboxPairwiseID";
+ public static readonly StringName IsAddressLocalHost = "isAddressLocalHost";
+ public static readonly StringName IsIdentityInvalid = "isIdentityInvalid";
+ public static readonly StringName IsIdentityLocalHost = "isIdentityLocalHost";
+ public static readonly StringName IsIPv4 = "isIPv4";
+ public static readonly StringName IsIPv6AllZeros = "isIPv6AllZeros";
+ public static readonly StringName ParseIdentityString = "parseIdentityString";
+ public static readonly StringName ParseIPAddressString = "parseIPAddressString";
+ public static readonly StringName SetGenericBytes = "setGenericBytes";
+ public static readonly StringName SetGenericString = "setGenericString";
+ public static readonly StringName SetIdentityIPAddr = "setIdentityIPAddr";
+ public static readonly StringName SetIdentityLocalHost = "setIdentityLocalHost";
+ public static readonly StringName SetIdentitySteamID = "setIdentitySteamID";
+ public static readonly StringName SetIdentitySteamID64 = "setIdentitySteamID64";
+ public static readonly StringName SetIPv4 = "setIPv4";
+ public static readonly StringName SetIPv6 = "setIPv6";
+ public static readonly StringName SetIPv6LocalHost = "setIPv6LocalHost";
+ public static readonly StringName SetPSNID = "setPSNID";
+ public static readonly StringName SetStadiaID = "setStadiaID";
+ public static readonly StringName SetXboxPairwiseID = "setXboxPairwiseID";
+ public static readonly StringName ToIdentityString = "toIdentityString";
+ public static readonly StringName ToIPAddressString = "toIPAddressString";
+ public static readonly StringName CheckPingDataUpToDate = "checkPingDataUpToDate";
+ public static readonly StringName ConvertPingLocationToString = "convertPingLocationToString";
+ public static readonly StringName EstimatePingTimeBetweenTwoLocations =
+ "estimatePingTimeBetweenTwoLocations";
+ public static readonly StringName EstimatePingTimeFromLocalHost =
+ "estimatePingTimeFromLocalHost";
+ public static readonly StringName GetConfigValue = "getConfigValue";
+ public static readonly StringName GetConfigValueInfo = "getConfigValueInfo";
+ public static readonly StringName GetDirectPingToPOP = "getDirectPingToPOP";
+ public static readonly StringName GetLocalPingLocation = "getLocalPingLocation";
+ public static readonly StringName GetLocalTimestamp = "getLocalTimestamp";
+ public static readonly StringName GetPingToDataCenter = "getPingToDataCenter";
+ public static readonly StringName GetPOPCount = "getPOPCount";
+ public static readonly StringName GetPOPList = "getPOPList";
+ public static readonly StringName GetRelayNetworkStatus = "getRelayNetworkStatus";
+ public static readonly StringName InitRelayNetworkAccess = "initRelayNetworkAccess";
+ public static readonly StringName ParsePingLocationString = "parsePingLocationString";
+ public static readonly StringName SetConnectionConfigValueFloat =
+ "setConnectionConfigValueFloat";
+ public static readonly StringName SetConnectionConfigValueInt32 =
+ "setConnectionConfigValueInt32";
+ public static readonly StringName SetConnectionConfigValueString =
+ "setConnectionConfigValueString";
+ public static readonly StringName SetGlobalConfigValueFloat = "setGlobalConfigValueFloat";
+ public static readonly StringName SetGlobalConfigValueInt32 = "setGlobalConfigValueInt32";
+ public static readonly StringName SetGlobalConfigValueString = "setGlobalConfigValueString";
+ public static readonly StringName IsParentalLockEnabled = "isParentalLockEnabled";
+ public static readonly StringName IsParentalLockLocked = "isParentalLockLocked";
+ public static readonly StringName IsAppBlocked = "isAppBlocked";
+ public static readonly StringName IsAppInBlockList = "isAppInBlockList";
+ public static readonly StringName IsFeatureBlocked = "isFeatureBlocked";
+ public static readonly StringName IsFeatureInBlockList = "isFeatureInBlockList";
+ public static readonly StringName CancelReservation = "cancelReservation";
+ public static readonly StringName ChangeNumOpenSlots = "changeNumOpenSlots";
+ public static readonly StringName CreateBeacon = "createBeacon";
+ public static readonly StringName DestroyBeacon = "destroyBeacon";
+ public static readonly StringName GetAvailableBeaconLocations = "getAvailableBeaconLocations";
+ public static readonly StringName GetBeaconByIndex = "getBeaconByIndex";
+ public static readonly StringName GetBeaconDetails = "getBeaconDetails";
+ public static readonly StringName GetBeaconLocationData = "getBeaconLocationData";
+ public static readonly StringName GetNumActiveBeacons = "getNumActiveBeacons";
+ public static readonly StringName JoinParty = "joinParty";
+ public static readonly StringName OnReservationCompleted = "onReservationCompleted";
+ public static readonly StringName GetSessionCount = "getSessionCount";
+ public static readonly StringName GetSessionID = "getSessionID";
+ public static readonly StringName GetSessionSteamID = "getSessionSteamID";
+ public static readonly StringName GetSessionClientName = "getSessionClientName";
+ public static readonly StringName GetSessionClientFormFactor = "getSessionClientFormFactor";
+ public static readonly StringName GetSessionClientResolution = "getSessionClientResolution";
+ public static readonly StringName SendRemotePlayTogetherInvite = "sendRemotePlayTogetherInvite";
+ public static readonly StringName StartRemotePlayTogether = "startRemotePlayTogether";
+ public static readonly StringName BeginFileWriteBatch = "beginFileWriteBatch";
+ public static readonly StringName EndFileWriteBatch = "endFileWriteBatch";
+ public static readonly StringName FileDelete = "fileDelete";
+ public static readonly StringName FileExists = "fileExists";
+ public static readonly StringName FileForget = "fileForget";
+ public static readonly StringName FilePersisted = "filePersisted";
+ public static readonly StringName FileRead = "fileRead";
+ public static readonly StringName FileReadAsync = "fileReadAsync";
+ public static readonly StringName FileShare = "fileShare";
+ public static readonly StringName FileWrite = "fileWrite";
+ public static readonly StringName FileWriteAsync = "fileWriteAsync";
+ public static readonly StringName FileWriteStreamCancel = "fileWriteStreamCancel";
+ public static readonly StringName FileWriteStreamClose = "fileWriteStreamClose";
+ public static readonly StringName FileWriteStreamOpen = "fileWriteStreamOpen";
+ public static readonly StringName FileWriteStreamWriteChunk = "fileWriteStreamWriteChunk";
+ public static readonly StringName GetCachedUGCCount = "getCachedUGCCount";
+ public static readonly StringName GetCachedUGCHandle = "getCachedUGCHandle";
+ public static readonly StringName GetFileCount = "getFileCount";
+ public static readonly StringName GetFileNameAndSize = "getFileNameAndSize";
+ public static readonly StringName GetFileSize = "getFileSize";
+ public static readonly StringName GetFileTimestamp = "getFileTimestamp";
+ public static readonly StringName GetLocalFileChange = "getLocalFileChange";
+ public static readonly StringName GetLocalFileChangeCount = "getLocalFileChangeCount";
+ public static readonly StringName GetQuota = "getQuota";
+ public static readonly StringName GetSyncPlatforms = "getSyncPlatforms";
+ public static readonly StringName GetUGCDetails = "getUGCDetails";
+ public static readonly StringName GetUGCDownloadProgress = "getUGCDownloadProgress";
+ public static readonly StringName IsCloudEnabledForAccount = "isCloudEnabledForAccount";
+ public static readonly StringName IsCloudEnabledForApp = "isCloudEnabledForApp";
+ public static readonly StringName SetCloudEnabledForApp = "setCloudEnabledForApp";
+ public static readonly StringName SetSyncPlatforms = "setSyncPlatforms";
+ public static readonly StringName UgcDownload = "ugcDownload";
+ public static readonly StringName UgcDownloadToLocation = "ugcDownloadToLocation";
+ public static readonly StringName UgcRead = "ugcRead";
+ public static readonly StringName AddScreenshotToLibrary = "addScreenshotToLibrary";
+ public static readonly StringName AddVRScreenshotToLibrary = "addVRScreenshotToLibrary";
+ public static readonly StringName HookScreenshots = "hookScreenshots";
+ public static readonly StringName IsScreenshotsHooked = "isScreenshotsHooked";
+ public static readonly StringName SetLocation = "setLocation";
+ public static readonly StringName TagPublishedFile = "tagPublishedFile";
+ public static readonly StringName TagUser = "tagUser";
+ public static readonly StringName TriggerScreenshot = "triggerScreenshot";
+ public static readonly StringName WriteScreenshot = "writeScreenshot";
+ public static readonly StringName AddAppDependency = "addAppDependency";
+ public static readonly StringName AddContentDescriptor = "addContentDescriptor";
+ public static readonly StringName AddDependency = "addDependency";
+ public static readonly StringName AddExcludedTag = "addExcludedTag";
+ public static readonly StringName AddItemKeyValueTag = "addItemKeyValueTag";
+ public static readonly StringName AddItemPreviewFile = "addItemPreviewFile";
+ public static readonly StringName AddItemPreviewVideo = "addItemPreviewVideo";
+ public static readonly StringName AddItemToFavorites = "addItemToFavorites";
+ public static readonly StringName AddRequiredKeyValueTag = "addRequiredKeyValueTag";
+ public static readonly StringName AddRequiredTag = "addRequiredTag";
+ public static readonly StringName AddRequiredTagGroup = "addRequiredTagGroup";
+ public static readonly StringName InitWorkshopForGameServer = "initWorkshopForGameServer";
+ public static readonly StringName CreateItem = "createItem";
+ public static readonly StringName CreateQueryAllUGCRequest = "createQueryAllUGCRequest";
+ public static readonly StringName CreateQueryUGCDetailsRequest = "createQueryUGCDetailsRequest";
+ public static readonly StringName CreateQueryUserUGCRequest = "createQueryUserUGCRequest";
+ public static readonly StringName DeleteItem = "deleteItem";
+ public static readonly StringName DownloadItem = "downloadItem";
+ public static readonly StringName GetItemDownloadInfo = "getItemDownloadInfo";
+ public static readonly StringName GetItemInstallInfo = "getItemInstallInfo";
+ public static readonly StringName GetItemState = "getItemState";
+ public static readonly StringName GetItemUpdateProgress = "getItemUpdateProgress";
+ public static readonly StringName GetNumSubscribedItems = "getNumSubscribedItems";
+ public static readonly StringName GetQueryUGCAdditionalPreview = "getQueryUGCAdditionalPreview";
+ public static readonly StringName GetQueryUGCChildren = "getQueryUGCChildren";
+ public static readonly StringName GetQueryUGCContentDescriptors =
+ "getQueryUGCContentDescriptors";
+ public static readonly StringName GetQueryUGCKeyValueTag = "getQueryUGCKeyValueTag";
+ public static readonly StringName GetQueryUGCMetadata = "getQueryUGCMetadata";
+ public static readonly StringName GetQueryUGCNumAdditionalPreviews =
+ "getQueryUGCNumAdditionalPreviews";
+ public static readonly StringName GetQueryUGCNumKeyValueTags = "getQueryUGCNumKeyValueTags";
+ public static readonly StringName GetQueryUGCNumTags = "getQueryUGCNumTags";
+ public static readonly StringName GetQueryUGCPreviewURL = "getQueryUGCPreviewURL";
+ public static readonly StringName GetQueryUGCResult = "getQueryUGCResult";
+ public static readonly StringName GetQueryUGCStatistic = "getQueryUGCStatistic";
+ public static readonly StringName GetQueryUGCTag = "getQueryUGCTag";
+ public static readonly StringName GetQueryUGCTagDisplayName = "getQueryUGCTagDisplayName";
+ public static readonly StringName GetSubscribedItems = "getSubscribedItems";
+ public static readonly StringName GetUserContentDescriptorPreferences =
+ "getUserContentDescriptorPreferences";
+ public static readonly StringName GetUserItemVote = "getUserItemVote";
+ public static readonly StringName ReleaseQueryUGCRequest = "releaseQueryUGCRequest";
+ public static readonly StringName RemoveAppDependency = "removeAppDependency";
+ public static readonly StringName RemoveContentDescriptor = "removeContentDescriptor";
+ public static readonly StringName RemoveDependency = "removeDependency";
+ public static readonly StringName RemoveItemFromFavorites = "removeItemFromFavorites";
+ public static readonly StringName RemoveItemKeyValueTags = "removeItemKeyValueTags";
+ public static readonly StringName RemoveItemPreview = "removeItemPreview";
+ public static readonly StringName SendQueryUGCRequest = "sendQueryUGCRequest";
+ public static readonly StringName SetAllowCachedResponse = "setAllowCachedResponse";
+ public static readonly StringName SetCloudFileNameFilter = "setCloudFileNameFilter";
+ public static readonly StringName SetItemContent = "setItemContent";
+ public static readonly StringName SetItemDescription = "setItemDescription";
+ public static readonly StringName SetItemMetadata = "setItemMetadata";
+ public static readonly StringName SetItemPreview = "setItemPreview";
+ public static readonly StringName SetItemTags = "setItemTags";
+ public static readonly StringName SetItemTitle = "setItemTitle";
+ public static readonly StringName SetItemUpdateLanguage = "setItemUpdateLanguage";
+ public static readonly StringName SetItemVisibility = "setItemVisibility";
+ public static readonly StringName SetLanguage = "setLanguage";
+ public static readonly StringName SetMatchAnyTag = "setMatchAnyTag";
+ public static readonly StringName SetRankedByTrendDays = "setRankedByTrendDays";
+ public static readonly StringName SetReturnAdditionalPreviews = "setReturnAdditionalPreviews";
+ public static readonly StringName SetReturnChildren = "setReturnChildren";
+ public static readonly StringName SetReturnKeyValueTags = "setReturnKeyValueTags";
+ public static readonly StringName SetReturnLongDescription = "setReturnLongDescription";
+ public static readonly StringName SetReturnMetadata = "setReturnMetadata";
+ public static readonly StringName SetReturnOnlyIDs = "setReturnOnlyIDs";
+ public static readonly StringName SetReturnPlaytimeStats = "setReturnPlaytimeStats";
+ public static readonly StringName SetReturnTotalOnly = "setReturnTotalOnly";
+ public static readonly StringName SetSearchText = "setSearchText";
+ public static readonly StringName SetUserItemVote = "setUserItemVote";
+ public static readonly StringName StartItemUpdate = "startItemUpdate";
+ public static readonly StringName StartPlaytimeTracking = "startPlaytimeTracking";
+ public static readonly StringName StopPlaytimeTracking = "stopPlaytimeTracking";
+ public static readonly StringName StopPlaytimeTrackingForAllItems =
+ "stopPlaytimeTrackingForAllItems";
+ public static readonly StringName GetAppDependencies = "getAppDependencies";
+ public static readonly StringName SubmitItemUpdate = "submitItemUpdate";
+ public static readonly StringName SubscribeItem = "subscribeItem";
+ public static readonly StringName SuspendDownloads = "suspendDownloads";
+ public static readonly StringName UnsubscribeItem = "unsubscribeItem";
+ public static readonly StringName UpdateItemPreviewFile = "updateItemPreviewFile";
+ public static readonly StringName UpdateItemPreviewVideo = "updateItemPreviewVideo";
+ public static readonly StringName ShowWorkshopEULA = "showWorkshopEULA";
+ public static readonly StringName GetWorkshopEULAStatus = "getWorkshopEULAStatus";
+ public static readonly StringName SetTimeCreatedDateRange = "setTimeCreatedDateRange";
+ public static readonly StringName SetTimeUpdatedDateRange = "setTimeUpdatedDateRange";
+ public static readonly StringName AdvertiseGame = "advertiseGame";
+ public static readonly StringName BeginAuthSession = "beginAuthSession";
+ public static readonly StringName CancelAuthTicket = "cancelAuthTicket";
+ public static readonly StringName DecompressVoice = "decompressVoice";
+ public static readonly StringName EndAuthSession = "endAuthSession";
+ public static readonly StringName GetAuthSessionTicket = "getAuthSessionTicket";
+ public static readonly StringName GetAuthTicketForWebApi = "getAuthTicketForWebApi";
+ public static readonly StringName GetAvailableVoice = "getAvailableVoice";
+ public static readonly StringName GetDurationControl = "getDurationControl";
+ public static readonly StringName GetEncryptedAppTicket = "getEncryptedAppTicket";
+ public static readonly StringName GetGameBadgeLevel = "getGameBadgeLevel";
+ public static readonly StringName GetPlayerSteamLevel = "getPlayerSteamLevel";
+ public static readonly StringName GetSteamID = "getSteamID";
+ public static readonly StringName GetVoice = "getVoice";
+ public static readonly StringName GetVoiceOptimalSampleRate = "getVoiceOptimalSampleRate";
+ public static readonly StringName InitiateGameConnection = "initiateGameConnection";
+ public static readonly StringName IsBehindNAT = "isBehindNAT";
+ public static readonly StringName IsPhoneIdentifying = "isPhoneIdentifying";
+ public static readonly StringName IsPhoneRequiringVerification = "isPhoneRequiringVerification";
+ public static readonly StringName IsPhoneVerified = "isPhoneVerified";
+ public static readonly StringName IsTwoFactorEnabled = "isTwoFactorEnabled";
+ public static readonly StringName LoggedOn = "loggedOn";
+ public static readonly StringName RequestEncryptedAppTicket = "requestEncryptedAppTicket";
+ public static readonly StringName RequestStoreAuthURL = "requestStoreAuthURL";
+ public static readonly StringName StartVoiceRecording = "startVoiceRecording";
+ public static readonly StringName SetDurationControlOnlineState =
+ "setDurationControlOnlineState";
+ public static readonly StringName StopVoiceRecording = "stopVoiceRecording";
+ public static readonly StringName TerminateGameConnection = "terminateGameConnection";
+ public static readonly StringName UserHasLicenseForApp = "userHasLicenseForApp";
+ public static readonly StringName AttachLeaderboardUGC = "attachLeaderboardUGC";
+ public static readonly StringName ClearAchievement = "clearAchievement";
+ public static readonly StringName DownloadLeaderboardEntries = "downloadLeaderboardEntries";
+ public static readonly StringName DownloadLeaderboardEntriesForUsers =
+ "downloadLeaderboardEntriesForUsers";
+ public static readonly StringName FindLeaderboard = "findLeaderboard";
+ public static readonly StringName FindOrCreateLeaderboard = "findOrCreateLeaderboard";
+ public static readonly StringName GetAchievement = "getAchievement";
+ public static readonly StringName GetAchievementAchievedPercent =
+ "getAchievementAchievedPercent";
+ public static readonly StringName GetAchievementAndUnlockTime = "getAchievementAndUnlockTime";
+ public static readonly StringName GetAchievementDisplayAttribute =
+ "getAchievementDisplayAttribute";
+ public static readonly StringName GetAchievementIcon = "getAchievementIcon";
+ public static readonly StringName GetAchievementName = "getAchievementName";
+ public static readonly StringName GetAchievementProgressLimitsInt =
+ "getAchievementProgressLimitsInt";
+ public static readonly StringName GetAchievementProgressLimitsFloat =
+ "getAchievementProgressLimitsFloat";
+ public static readonly StringName GetGlobalStatInt = "getGlobalStatInt";
+ public static readonly StringName GetGlobalStatFloat = "getGlobalStatFloat";
+ public static readonly StringName GetGlobalStatIntHistory = "getGlobalStatIntHistory";
+ public static readonly StringName GetGlobalStatFloatHistory = "getGlobalStatFloatHistory";
+ public static readonly StringName GetLeaderboardDisplayType = "getLeaderboardDisplayType";
+ public static readonly StringName GetLeaderboardEntryCount = "getLeaderboardEntryCount";
+ public static readonly StringName GetLeaderboardName = "getLeaderboardName";
+ public static readonly StringName GetLeaderboardSortMethod = "getLeaderboardSortMethod";
+ public static readonly StringName GetMostAchievedAchievementInfo =
+ "getMostAchievedAchievementInfo";
+ public static readonly StringName GetNextMostAchievedAchievementInfo =
+ "getNextMostAchievedAchievementInfo";
+ public static readonly StringName GetNumAchievements = "getNumAchievements";
+ public static readonly StringName GetNumberOfCurrentPlayers = "getNumberOfCurrentPlayers";
+ public static readonly StringName GetStatFloat = "getStatFloat";
+ public static readonly StringName GetStatInt = "getStatInt";
+ public static readonly StringName GetUserAchievement = "getUserAchievement";
+ public static readonly StringName GetUserAchievementAndUnlockTime =
+ "getUserAchievementAndUnlockTime";
+ public static readonly StringName GetUserStatFloat = "getUserStatFloat";
+ public static readonly StringName GetUserStatInt = "getUserStatInt";
+ public static readonly StringName IndicateAchievementProgress = "indicateAchievementProgress";
+ public static readonly StringName RequestCurrentStats = "requestCurrentStats";
+ public static readonly StringName RequestGlobalAchievementPercentages =
+ "requestGlobalAchievementPercentages";
+ public static readonly StringName RequestGlobalStats = "requestGlobalStats";
+ public static readonly StringName RequestUserStats = "requestUserStats";
+ public static readonly StringName ResetAllStats = "resetAllStats";
+ public static readonly StringName SetAchievement = "setAchievement";
+ public static readonly StringName SetLeaderboardDetailsMax = "setLeaderboardDetailsMax";
+ public static readonly StringName SetStatFloat = "setStatFloat";
+ public static readonly StringName SetStatInt = "setStatInt";
+ public static readonly StringName StoreStats = "storeStats";
+ public static readonly StringName UpdateAvgRateStat = "updateAvgRateStat";
+ public static readonly StringName UploadLeaderboardScore = "uploadLeaderboardScore";
+ public static readonly StringName GetLeaderboardEntries = "getLeaderboardEntries";
+ public static readonly StringName FilterText = "filterText";
+ public static readonly StringName GetAPICallFailureReason = "getAPICallFailureReason";
+ public static readonly StringName GetAppID = "getAppID";
+ public static readonly StringName GetCurrentBatteryPower = "getCurrentBatteryPower";
+ public static readonly StringName GetImageRGBA = "getImageRGBA";
+ public static readonly StringName GetImageSize = "getImageSize";
+ public static readonly StringName GetIPCCallCount = "getIPCCallCount";
+ public static readonly StringName GetIPCountry = "getIPCountry";
+ public static readonly StringName GetSecondsSinceAppActive = "getSecondsSinceAppActive";
+ public static readonly StringName GetSecondsSinceComputerActive =
+ "getSecondsSinceComputerActive";
+ public static readonly StringName GetServerRealTime = "getServerRealTime";
+ public static readonly StringName GetSteamUILanguage = "getSteamUILanguage";
+ public static readonly StringName InitFilterText = "initFilterText";
+ public static readonly StringName IsAPICallCompleted = "isAPICallCompleted";
+ public static readonly StringName IsOverlayEnabled = "isOverlayEnabled";
+ public static readonly StringName IsSteamChinaLauncher = "isSteamChinaLauncher";
+ public static readonly StringName IsSteamInBigPictureMode = "isSteamInBigPictureMode";
+ public static readonly StringName IsSteamRunningInVR = "isSteamRunningInVR";
+ public static readonly StringName IsVRHeadsetStreamingEnabled = "isVRHeadsetStreamingEnabled";
+ public static readonly StringName OverlayNeedsPresent = "overlayNeedsPresent";
+ public static readonly StringName SetOverlayNotificationInset = "setOverlayNotificationInset";
+ public static readonly StringName SetOverlayNotificationPosition =
+ "setOverlayNotificationPosition";
+ public static readonly StringName SetVRHeadsetStreamingEnabled = "setVRHeadsetStreamingEnabled";
+ public static readonly StringName ShowGamepadTextInput = "showGamepadTextInput";
+ public static readonly StringName ShowFloatingGamepadTextInput = "showFloatingGamepadTextInput";
+ public static readonly StringName SetGameLauncherMode = "setGameLauncherMode";
+ public static readonly StringName StartVRDashboard = "startVRDashboard";
+ public static readonly StringName IsSteamRunningOnSteamDeck = "isSteamRunningOnSteamDeck";
+ public static readonly StringName DismissFloatingGamepadTextInput =
+ "dismissFloatingGamepadTextInput";
+ public static readonly StringName GetOPFSettings = "getOPFSettings";
+ public static readonly StringName GetOPFStringForApp = "getOPFStringForApp";
+ public static readonly StringName GetVideoURL = "getVideoURL";
+ public static readonly StringName IsBroadcasting = "isBroadcasting";
+}
diff --git a/addons/godotsteam_csharpbindings/Methods.cs.uid b/addons/godotsteam_csharpbindings/Methods.cs.uid
new file mode 100644
index 00000000..42c0c6aa
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Methods.cs.uid
@@ -0,0 +1 @@
+uid://ct6pjscay5oub
diff --git a/addons/godotsteam_csharpbindings/Screenshots/VRScreenshotType.cs b/addons/godotsteam_csharpbindings/Screenshots/VRScreenshotType.cs
new file mode 100644
index 00000000..4b9172e4
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Screenshots/VRScreenshotType.cs
@@ -0,0 +1,11 @@
+namespace GodotSteam;
+
+public enum VRScreenshotType
+{
+ None = 0,
+ Mono = 1,
+ Stereo = 2,
+ MonoCubeMap = 3,
+ MonoPanorama = 4,
+ StereoPanorama = 5,
+}
diff --git a/addons/godotsteam_csharpbindings/Screenshots/VRScreenshotType.cs.uid b/addons/godotsteam_csharpbindings/Screenshots/VRScreenshotType.cs.uid
new file mode 100644
index 00000000..b68f1ce2
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Screenshots/VRScreenshotType.cs.uid
@@ -0,0 +1 @@
+uid://dqqlllkead4ol
diff --git a/addons/godotsteam_csharpbindings/Signals.cs b/addons/godotsteam_csharpbindings/Signals.cs
new file mode 100644
index 00000000..062b1428
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Signals.cs
@@ -0,0 +1,213 @@
+using Godot;
+
+namespace GodotSteam;
+
+public static class Signals
+{
+ public static readonly StringName SteamworksError = "steamworks_error";
+ public static readonly StringName FileDetailsResult = "file_details_result";
+ public static readonly StringName DlcInstalled = "dlc_installed";
+ public static readonly StringName NewLaunchUrlParameters = "new_launch_url_parameters";
+ public static readonly StringName TimedTrialStatus = "timed_trial_status";
+ public static readonly StringName AppInstalled = "app_installed";
+ public static readonly StringName AppUninstalled = "app_uninstalled";
+ public static readonly StringName AvatarLoaded = "avatar_loaded";
+ public static readonly StringName AvatarImageLoaded = "avatar_image_loaded";
+ public static readonly StringName RequestClanOfficerListSignal = "request_clan_officer_list";
+ public static readonly StringName ClanActivityDownloaded = "clan_activity_downloaded";
+ public static readonly StringName FriendRichPresenceUpdate = "friend_rich_presence_update";
+ public static readonly StringName EnumerateFollowingListSignal = "enumerate_following_list";
+ public static readonly StringName GetFollowerCountSignal = "get_follower_count";
+ public static readonly StringName IsFollowingSignal = "is_following";
+ public static readonly StringName ConnectedChatJoin = "connected_chat_join";
+ public static readonly StringName ConnectedChatLeave = "connected_chat_leave";
+ public static readonly StringName ConnectedClanChatMessage = "connected_clan_chat_message";
+ public static readonly StringName ConnectedFriendChatMessage = "connected_friend_chat_message";
+ public static readonly StringName JoinRequested = "join_requested";
+ public static readonly StringName OverlayToggled = "overlay_toggled";
+ public static readonly StringName JoinGameRequested = "join_game_requested";
+ public static readonly StringName ChangeServerRequested = "change_server_requested";
+ public static readonly StringName JoinClanChatComplete = "join_clan_chat_complete";
+ public static readonly StringName PersonaStateChange = "persona_state_change";
+ public static readonly StringName NameChanged = "name_changed";
+ public static readonly StringName OverlayBrowserProtocol = "overlay_browser_protocol";
+ public static readonly StringName UnreadChatMessagesChanged = "unread_chat_messages_changed";
+ public static readonly StringName EquippedProfileItemsChanged =
+ "equipped_profile_items_changed";
+ public static readonly StringName EquippedProfileItems = "equipped_profile_items";
+ public static readonly StringName SearchForGameProgress = "search_for_game_progress";
+ public static readonly StringName SearchForGameResult = "search_for_game_result";
+ public static readonly StringName RequestPlayersForGameProgress =
+ "request_players_for_game_progress";
+ public static readonly StringName RequestPlayersForGameResult =
+ "request_players_for_game_result";
+ public static readonly StringName RequestPlayersForGameFinalResult =
+ "request_players_for_game_final_result";
+ public static readonly StringName SubmitPlayerResultSignal = "submit_player_result";
+ public static readonly StringName EndGameResult = "end_game_result";
+ public static readonly StringName HtmlBrowserReady = "html_browser_ready";
+ public static readonly StringName HtmlCanGoBackandforward = "html_can_go_backandforward";
+ public static readonly StringName HtmlChangedTitle = "html_changed_title";
+ public static readonly StringName HtmlCloseBrowser = "html_close_browser";
+ public static readonly StringName HtmlFileOpenDialog = "html_file_open_dialog";
+ public static readonly StringName HtmlFinishedRequest = "html_finished_request";
+ public static readonly StringName HtmlHideTooltip = "html_hide_tooltip";
+ public static readonly StringName HtmlHorizontalScroll = "html_horizontal_scroll";
+ public static readonly StringName HtmlJsAlert = "html_js_alert";
+ public static readonly StringName HtmlJsConfirm = "html_js_confirm";
+ public static readonly StringName HtmlLinkAtPosition = "html_link_at_position";
+ public static readonly StringName HtmlNeedsPaint = "html_needs_paint";
+ public static readonly StringName HtmlNewWindow = "html_new_window";
+ public static readonly StringName HtmlOpenLinkInNewTab = "html_open_link_in_new_tab";
+ public static readonly StringName HtmlSearchResults = "html_search_results";
+ public static readonly StringName HtmlSetCursor = "html_set_cursor";
+ public static readonly StringName HtmlShowTooltip = "html_show_tooltip";
+ public static readonly StringName HtmlStartRequest = "html_start_request";
+ public static readonly StringName HtmlStatusText = "html_status_text";
+ public static readonly StringName HtmlUpdateTooltip = "html_update_tooltip";
+ public static readonly StringName HtmlUrlChanged = "html_url_changed";
+ public static readonly StringName HtmlVerticalScroll = "html_vertical_scroll";
+ public static readonly StringName HttpRequestCompleted = "http_request_completed";
+ public static readonly StringName HttpRequestDataReceived = "http_request_data_received";
+ public static readonly StringName HttpRequestHeadersReceived = "http_request_headers_received";
+ public static readonly StringName InputActionEvent = "input_action_event";
+ public static readonly StringName InputDeviceConnected = "input_device_connected";
+ public static readonly StringName InputDeviceDisconnected = "input_device_disconnected";
+ public static readonly StringName InputConfigurationLoaded = "input_configuration_loaded";
+ public static readonly StringName InputGamepadSlotChange = "input_gamepad_slot_change";
+ public static readonly StringName InventoryDefinitionUpdate = "inventory_definition_update";
+ public static readonly StringName InventoryEligiblePromoItem = "inventory_eligible_promo_item";
+ public static readonly StringName InventoryFullUpdate = "inventory_full_update";
+ public static readonly StringName InventoryResultReady = "inventory_result_ready";
+ public static readonly StringName InventoryStartPurchaseResult =
+ "inventory_start_purchase_result";
+ public static readonly StringName InventoryRequestPricesResult =
+ "inventory_request_prices_result";
+ public static readonly StringName FavoritesListAccountsUpdated =
+ "favorites_list_accounts_updated";
+ public static readonly StringName FavoritesListChanged = "favorites_list_changed";
+ public static readonly StringName LobbyMessage = "lobby_message";
+ public static readonly StringName LobbyChatUpdate = "lobby_chat_update";
+ public static readonly StringName LobbyCreated = "lobby_created";
+ public static readonly StringName LobbyDataUpdate = "lobby_data_update";
+ public static readonly StringName LobbyJoined = "lobby_joined";
+ public static readonly StringName LobbyGameCreated = "lobby_game_created";
+ public static readonly StringName LobbyInvite = "lobby_invite";
+ public static readonly StringName LobbyMatchList = "lobby_match_list";
+ public static readonly StringName LobbyKicked = "lobby_kicked";
+ public static readonly StringName ServerResponded = "server_responded";
+ public static readonly StringName ServerFailedToRespond = "server_failed_to_respond";
+ public static readonly StringName MusicPlayerRemoteToFront = "music_player_remote_to_front";
+ public static readonly StringName MusicPlayerRemoteWillActivate =
+ "music_player_remote_will_activate";
+ public static readonly StringName MusicPlayerRemoteWillDeactivate =
+ "music_player_remote_will_deactivate";
+ public static readonly StringName MusicPlayerSelectsPlaylistEntry =
+ "music_player_selects_playlist_entry";
+ public static readonly StringName MusicPlayerSelectsQueueEntry =
+ "music_player_selects_queue_entry";
+ public static readonly StringName MusicPlayerWantsLooped = "music_player_wants_looped";
+ public static readonly StringName MusicPlayerWantsPause = "music_player_wants_pause";
+ public static readonly StringName MusicPlayerWantsPlayingRepeatStatus =
+ "music_player_wants_playing_repeat_status";
+ public static readonly StringName MusicPlayerWantsPlayNext = "music_player_wants_play_next";
+ public static readonly StringName MusicPlayerWantsPlayPrevious =
+ "music_player_wants_play_previous";
+ public static readonly StringName MusicPlayerWantsPlay = "music_player_wants_play";
+ public static readonly StringName MusicPlayerWantsShuffled = "music_player_wants_shuffled";
+ public static readonly StringName MusicPlayerWantsVolume = "music_player_wants_volume";
+ public static readonly StringName MusicPlayerWillQuit = "music_player_will_quit";
+ public static readonly StringName P2PSessionRequest = "p2p_session_request";
+ public static readonly StringName P2PSessionConnectFail = "p2p_session_connect_fail";
+ public static readonly StringName NetworkMessagesSessionRequest =
+ "network_messages_session_request";
+ public static readonly StringName NetworkMessagesSessionFailed =
+ "network_messages_session_failed";
+ public static readonly StringName NetworkConnectionStatusChanged =
+ "network_connection_status_changed";
+ public static readonly StringName NetworkAuthenticationStatus = "network_authentication_status";
+ public static readonly StringName FakeIPResult = "fake_ip_result";
+ public static readonly StringName RelayNetworkStatus = "relay_network_status";
+ public static readonly StringName ParentalSettingChanged = "parental_setting_changed";
+ public static readonly StringName JoinPartySignal = "join_party";
+ public static readonly StringName CreateBeaconSignal = "create_beacon";
+ public static readonly StringName ReservationNotification = "reservation_notification";
+ public static readonly StringName ChangeNumOpenSlotsSignal = "change_num_open_slots";
+ public static readonly StringName AvailableBeaconLocationsUpdated =
+ "available_beacon_locations_updated";
+ public static readonly StringName ActiveBeaconsUpdated = "active_beacons_updated";
+ public static readonly StringName RemotePlaySessionConnected = "remote_play_session_connected";
+ public static readonly StringName RemotePlaySessionDisconnected =
+ "remote_play_session_disconnected";
+ public static readonly StringName FileReadAsyncComplete = "file_read_async_complete";
+ public static readonly StringName FileShareResult = "file_share_result";
+ public static readonly StringName FileWriteAsyncComplete = "file_write_async_complete";
+ public static readonly StringName DownloadUgcResult = "download_ugc_result";
+ public static readonly StringName UnsubscribeItemSignal = "unsubscribe_item";
+ public static readonly StringName SubscribeItemSignal = "subscribe_item";
+ public static readonly StringName LocalFileChanged = "local_file_changed";
+ public static readonly StringName ScreenshotReady = "screenshot_ready";
+ public static readonly StringName ScreenshotRequested = "screenshot_requested";
+ public static readonly StringName AddAppDependencyResult = "add_app_dependency_result";
+ public static readonly StringName AddUgcDependencyResult = "add_ugc_dependency_result";
+ public static readonly StringName ItemCreated = "item_created";
+ public static readonly StringName ItemDownloaded = "item_downloaded";
+ public static readonly StringName GetAppDependenciesResult = "get_app_dependencies_result";
+ public static readonly StringName ItemDeleted = "item_deleted";
+ public static readonly StringName GetItemVoteResult = "get_item_vote_result";
+ public static readonly StringName ItemInstalled = "item_installed";
+ public static readonly StringName RemoveAppDependencyResult = "remove_app_dependency_result";
+ public static readonly StringName RemoveUgcDependencyResult = "remove_ugc_dependency_result";
+ public static readonly StringName SetUserItemVoteSignal = "set_user_item_vote";
+ public static readonly StringName StartPlaytimeTrackingSignal = "start_playtime_tracking";
+ public static readonly StringName UgcQueryCompleted = "ugc_query_completed";
+ public static readonly StringName StopPlaytimeTrackingSignal = "stop_playtime_tracking";
+ public static readonly StringName ItemUpdated = "item_updated";
+ public static readonly StringName UserFavoriteItemsListChanged =
+ "user_favorite_items_list_changed";
+ public static readonly StringName WorkshopEulaStatus = "workshop_eula_status";
+ public static readonly StringName UserSubscribedItemsListChanged =
+ "user_subscribed_items_list_changed";
+ public static readonly StringName ClientGameServerDeny = "client_game_server_deny";
+ public static readonly StringName DurationControl = "duration_control";
+ public static readonly StringName EncryptedAppTicketResponse = "encrypted_app_ticket_response";
+ public static readonly StringName GameWebCallback = "game_web_callback";
+ public static readonly StringName GetAuthSessionTicketResponse =
+ "get_auth_session_ticket_response";
+ public static readonly StringName GetTicketForWebApi = "get_ticket_for_web_api";
+ public static readonly StringName IpcFailure = "ipc_failure";
+ public static readonly StringName LicensesUpdated = "licenses_updated";
+ public static readonly StringName MicrotransactionAuthResponse =
+ "microtransaction_auth_response";
+ public static readonly StringName SteamServerConnectFailed = "steam_server_connect_failed";
+ public static readonly StringName SteamServerConnected = "steam_server_connected";
+ public static readonly StringName SteamServerDisconnected = "steam_server_disconnected";
+ public static readonly StringName StoreAuthUrlResponse = "store_auth_url_response";
+ public static readonly StringName ValidateAuthTicketResponse = "validate_auth_ticket_response";
+ public static readonly StringName GlobalAchievementPercentagesReady =
+ "global_achievement_percentages_ready";
+ public static readonly StringName GlobalStatsReceived = "global_stats_received";
+ public static readonly StringName LeaderboardFindResult = "leaderboard_find_result";
+ public static readonly StringName LeaderboardScoresDownloaded = "leaderboard_scores_downloaded";
+ public static readonly StringName LeaderboardScoreUploaded = "leaderboard_score_uploaded";
+ public static readonly StringName LeaderboardUgcSet = "leaderboard_ugc_set";
+ public static readonly StringName NumberOfCurrentPlayers = "number_of_current_players";
+ public static readonly StringName UserAchievementStored = "user_achievement_stored";
+ public static readonly StringName CurrentStatsReceived = "current_stats_received";
+ public static readonly StringName UserStatsReceived = "user_stats_received";
+ public static readonly StringName UserStatsStored = "user_stats_stored";
+ public static readonly StringName UserStatsUnloaded = "user_stats_unloaded";
+ public static readonly StringName CheckFileSignature = "check_file_signature";
+ public static readonly StringName GamepadTextInputDismissed = "gamepad_text_input_dismissed";
+ public static readonly StringName IPCountry = "ip_country";
+ public static readonly StringName LowPower = "low_power";
+ public static readonly StringName SteamApiCallCompleted = "steam_api_call_completed";
+ public static readonly StringName SteamShutdownSignal = "steam_shutdown";
+ public static readonly StringName AppResumingFromSuspend = "app_resuming_from_suspend";
+ public static readonly StringName FloatingGamepadTextInputDismissed =
+ "floating_gamepad_text_input_dismissed";
+ public static readonly StringName FilterTextDictionaryChanged =
+ "filter_text_dictionary_changed";
+ public static readonly StringName GetOpfSettingsResult = "get_opf_settings_result";
+ public static readonly StringName GetVideoResult = "get_video_result";
+}
diff --git a/addons/godotsteam_csharpbindings/Signals.cs.uid b/addons/godotsteam_csharpbindings/Signals.cs.uid
new file mode 100644
index 00000000..6ecbb614
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Signals.cs.uid
@@ -0,0 +1 @@
+uid://dy812x34p1upx
diff --git a/addons/godotsteam_csharpbindings/Steam.AppLists.Signals.cs b/addons/godotsteam_csharpbindings/Steam.AppLists.Signals.cs
new file mode 100644
index 00000000..53d2e70e
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.AppLists.Signals.cs
@@ -0,0 +1,60 @@
+using System;
+using Godot;
+
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public delegate void AppInstalledEventHandler(uint appId, uint installFolderIndex);
+ private static event AppInstalledEventHandler AppInstalledEvent;
+ static Action _appInstalledAction = (appId, installFolderIndex) =>
+ {
+ AppInstalledEvent?.Invoke(appId, installFolderIndex);
+ };
+ public static event AppInstalledEventHandler AppInstalled
+ {
+ add
+ {
+ if (AppInstalledEvent == null)
+ {
+ GetInstance().Connect(Signals.AppInstalled, Callable.From(_appInstalledAction));
+ }
+ AppInstalledEvent += value;
+ }
+ remove
+ {
+ AppInstalledEvent -= value;
+ if (AppInstalledEvent == null)
+ {
+ GetInstance().Disconnect(Signals.AppInstalled, Callable.From(_appInstalledAction));
+ }
+ }
+ }
+
+ public delegate void AppUninstalledEventHandler(uint appId, uint installFolderIndex);
+ private static event AppUninstalledEventHandler AppUninstalledEvent;
+ static Action _appUninstalledAction = (appId, installFolderIndex) =>
+ {
+ AppUninstalledEvent?.Invoke(appId, installFolderIndex);
+ };
+ public static event AppUninstalledEventHandler AppUninstalled
+ {
+ add
+ {
+ if (AppUninstalledEvent == null)
+ {
+ GetInstance().Connect(Signals.AppUninstalled, Callable.From(_appUninstalledAction));
+ }
+ AppUninstalledEvent += value;
+ }
+ remove
+ {
+ AppUninstalledEvent -= value;
+ if (AppUninstalledEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.AppUninstalled, Callable.From(_appUninstalledAction));
+ }
+ }
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.AppLists.Signals.cs.uid b/addons/godotsteam_csharpbindings/Steam.AppLists.Signals.cs.uid
new file mode 100644
index 00000000..8d95a4f5
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.AppLists.Signals.cs.uid
@@ -0,0 +1 @@
+uid://bvregkp0xpd6w
diff --git a/addons/godotsteam_csharpbindings/Steam.AppLists.cs b/addons/godotsteam_csharpbindings/Steam.AppLists.cs
new file mode 100644
index 00000000..09adcb09
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.AppLists.cs
@@ -0,0 +1,35 @@
+using System.Collections.Generic;
+using System.Linq;
+using Godot.Collections;
+
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public static List GetInstalledApps(uint maxAppIds)
+ {
+ var raw = GetInstance().Call(Methods.GetInstalledApps, maxAppIds).AsGodotArray();
+
+ return raw.Select(x => x.AsUInt32()).ToList();
+ }
+
+ public static string GetAppName(uint appId, int nameMax)
+ {
+ return GetInstance().Call(Methods.GetAppName, appId, nameMax).AsString();
+ }
+
+ public static string GetAppListInstallDir(uint appId, int nameMax)
+ {
+ return GetInstance().Call(Methods.GetAppListInstallDir, appId, nameMax).AsString();
+ }
+
+ public static int GetAppListBuildId(uint appId)
+ {
+ return GetInstance().Call(Methods.GetAppListBuildId, appId).AsInt32();
+ }
+
+ public static long GetNumInstalledApps()
+ {
+ return GetInstance().Call(Methods.GetNumInstalledApps).AsInt64();
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.AppLists.cs.uid b/addons/godotsteam_csharpbindings/Steam.AppLists.cs.uid
new file mode 100644
index 00000000..9dfb0c2f
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.AppLists.cs.uid
@@ -0,0 +1 @@
+uid://cv1pfcxcfe8qs
diff --git a/addons/godotsteam_csharpbindings/Steam.Apps.Signals.cs b/addons/godotsteam_csharpbindings/Steam.Apps.Signals.cs
new file mode 100644
index 00000000..9798cdcf
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Apps.Signals.cs
@@ -0,0 +1,142 @@
+using System;
+using Godot;
+
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public delegate void DlcInstalledEventHandler(uint appId);
+ private static event DlcInstalledEventHandler DlcInstalledEvent;
+ static Action _dlcInstalledAction = (appId) =>
+ {
+ DlcInstalledEvent?.Invoke(appId);
+ };
+ public static event DlcInstalledEventHandler DlcInstalled
+ {
+ add
+ {
+ if (DlcInstalledEvent == null)
+ {
+ GetInstance().Connect(Signals.DlcInstalled, Callable.From(_dlcInstalledAction));
+ }
+ DlcInstalledEvent += value;
+ }
+ remove
+ {
+ DlcInstalledEvent -= value;
+ if (DlcInstalledEvent == null)
+ {
+ GetInstance().Disconnect(Signals.DlcInstalled, Callable.From(_dlcInstalledAction));
+ }
+ }
+ }
+
+ public delegate void FileDetailsResultEventHandler(
+ ErrorResult result,
+ ulong fileSize,
+ sbyte fileHash,
+ uint flags
+ );
+ private static event FileDetailsResultEventHandler FileDetailsResultEvent;
+ static Action _fileDetailsResultAction = (
+ result,
+ fileSize,
+ fileHash,
+ flags
+ ) =>
+ {
+ FileDetailsResultEvent?.Invoke((ErrorResult)result, fileSize, fileHash, flags);
+ };
+ public static event FileDetailsResultEventHandler FileDetailsResult
+ {
+ add
+ {
+ if (FileDetailsResultEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.FileDetailsResult, Callable.From(_fileDetailsResultAction));
+ }
+ FileDetailsResultEvent += value;
+ }
+ remove
+ {
+ FileDetailsResultEvent -= value;
+ if (FileDetailsResultEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.FileDetailsResult, Callable.From(_fileDetailsResultAction));
+ }
+ }
+ }
+
+ private static event Action NewLaunchUrlParametersEvent;
+ static Action _newLaunchUrlParametersAction = () =>
+ {
+ NewLaunchUrlParametersEvent?.Invoke();
+ };
+ public static event Action NewLaunchUrlParameters
+ {
+ add
+ {
+ if (NewLaunchUrlParametersEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.NewLaunchUrlParameters,
+ Callable.From(_newLaunchUrlParametersAction)
+ );
+ }
+ NewLaunchUrlParametersEvent += value;
+ }
+ remove
+ {
+ NewLaunchUrlParametersEvent -= value;
+ if (NewLaunchUrlParametersEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.NewLaunchUrlParameters,
+ Callable.From(_newLaunchUrlParametersAction)
+ );
+ }
+ }
+ }
+
+ public delegate void TimedTrialStatusEventHandler(
+ uint appId,
+ bool isOffline,
+ uint secondsAllowed,
+ uint secondsPlayed
+ );
+ private static event TimedTrialStatusEventHandler TimedTrialStatusEvent;
+ static Action _timeTrialStatusAction = (
+ appId,
+ isOffline,
+ secondsAllowed,
+ secondsPlayed
+ ) =>
+ {
+ TimedTrialStatusEvent?.Invoke(appId, isOffline, secondsAllowed, secondsPlayed);
+ };
+ public static event TimedTrialStatusEventHandler TimedTrialStatus
+ {
+ add
+ {
+ if (TimedTrialStatusEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.TimedTrialStatus, Callable.From(_timeTrialStatusAction));
+ }
+ TimedTrialStatusEvent += value;
+ }
+ remove
+ {
+ TimedTrialStatusEvent -= value;
+ if (TimedTrialStatusEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.TimedTrialStatus, Callable.From(_timeTrialStatusAction));
+ }
+ }
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.Apps.Signals.cs.uid b/addons/godotsteam_csharpbindings/Steam.Apps.Signals.cs.uid
new file mode 100644
index 00000000..08108d34
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Apps.Signals.cs.uid
@@ -0,0 +1 @@
+uid://22n4u8d7g7hx
diff --git a/addons/godotsteam_csharpbindings/Steam.Apps.cs b/addons/godotsteam_csharpbindings/Steam.Apps.cs
new file mode 100644
index 00000000..74fcb324
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Apps.cs
@@ -0,0 +1,184 @@
+using System.Collections.Generic;
+using System.Linq;
+using Godot;
+using Godot.Collections;
+
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public static bool IsAppInstalled(uint appId)
+ {
+ return GetInstance().Call(Methods.IsAppInstalled, appId).AsBool();
+ }
+
+ public static int GetAppBuildId()
+ {
+ return GetInstance().Call(Methods.GetAppBuildId).AsInt32();
+ }
+
+ public static InstalledApps GetAppInstallDir(uint appId)
+ {
+ var raw = GetInstance().Call(Methods.GetAppInstallDir, appId).AsGodotDictionary();
+
+ return new InstalledApps
+ {
+ Directory = raw["directory"].AsString(),
+ InstallSize = raw["install_size"].AsUInt32(),
+ };
+ }
+
+ public static ulong GetAppOwner()
+ {
+ return GetInstance().Call(Methods.GetAppOwner).AsUInt64();
+ }
+
+ public static string GetAvailableGameLanguages()
+ {
+ return GetInstance().Call(Methods.GetAvailableGameLanguages).AsString();
+ }
+
+ public static string GetCurrentBetaName()
+ {
+ return GetInstance().Call(Methods.GetCurrentBetaName).AsString();
+ }
+
+ public static string GetCurrentGameLanguage()
+ {
+ return GetInstance().Call(Methods.GetCurrentGameLanguage).AsString();
+ }
+
+ public static uint GetEarliestPurchaseUnixTime(uint appId)
+ {
+ return GetInstance().Call(Methods.GetEarliestPurchaseUnixTime, appId).AsUInt32();
+ }
+
+ public static void GetFileDetails(string fileName)
+ {
+ GetInstance().Call(Methods.GetFileDetails, fileName);
+ }
+
+ public static List GetInstalledDepots(uint appId)
+ {
+ var raw = GetInstance().Call(Methods.GetInstalledDepots, appId).AsGodotArray();
+
+ return raw.Select(x => x.AsUInt32()).ToList();
+ }
+
+ public static string GetLaunchCommandLine()
+ {
+ return GetInstance().Call(Methods.GetLaunchCommandLine).AsString();
+ }
+
+ public static string GetLaunchQueryParam(string key)
+ {
+ return GetInstance().Call(Methods.GetLaunchQueryParam, key).AsString();
+ }
+
+ public static List GetDLCDataByIndex()
+ {
+ var raw = GetInstance().Call(Methods.GetDLCDataByIndex).AsGodotArray();
+
+ return raw.Select(rawDlc => rawDlc.AsGodotDictionary())
+ .Select(dlcDictionary => new Dlc
+ {
+ AppId = dlcDictionary["app_id"].AsUInt32(),
+ Available = dlcDictionary["available"].AsBool(),
+ Name = dlcDictionary["name"].AsString(),
+ })
+ .ToList();
+ }
+
+ public static bool IsDLCInstalled(uint dlcId)
+ {
+ return GetInstance().Call(Methods.IsDLCInstalled, dlcId).AsBool();
+ }
+
+ public static int GetDLCCount()
+ {
+ return GetInstance().Call(Methods.GetDLCCount).AsInt32();
+ }
+
+ public static DlcDownloadProgress GetDLCDownloadProgress(uint dlcId)
+ {
+ var raw = GetInstance().Call(Methods.GetDLCDownloadProgress, dlcId).AsGodotDictionary();
+
+ if (!raw.ContainsKey("ret") || !raw.ContainsKey("downloaded") || !raw.ContainsKey("total"))
+ {
+ return null;
+ }
+
+ return new DlcDownloadProgress
+ {
+ Ret = raw["ret"].AsBool(),
+ Downloaded = raw["downloaded"].AsUInt64(),
+ Total = raw["total"].AsUInt64(),
+ };
+ }
+
+ public static void InstallDLC(uint dlcId)
+ {
+ GetInstance().Call(Methods.InstallDLC, dlcId);
+ }
+
+ public static bool MarkContentCorrupt(bool missingFilesOnly)
+ {
+ return GetInstance().Call(Methods.MarkContentCorrupt, missingFilesOnly).AsBool();
+ }
+
+ public static bool SetDLCContext(uint appId)
+ {
+ return GetInstance().Call(Methods.SetDLCContext, appId).AsBool();
+ }
+
+ public static void UninstallDLC(uint dlcId)
+ {
+ GetInstance().Call(Methods.UninstallDLC, dlcId);
+ }
+
+ public static bool IsLowViolence()
+ {
+ return GetInstance().Call(Methods.IsLowViolence).AsBool();
+ }
+
+ public static bool IsSubscribed()
+ {
+ return GetInstance().Call(Methods.IsSubscribed).AsBool();
+ }
+
+ public static bool IsSubscribedApp(uint appId)
+ {
+ return GetInstance().Call(Methods.IsSubscribedApp, appId).AsBool();
+ }
+
+ public static bool IsSubscribedFromFamilySharing()
+ {
+ return GetInstance().Call(Methods.IsSubscribedFromFamilySharing).AsBool();
+ }
+
+ public static bool IsSubscribedFromFreeWeekend()
+ {
+ return GetInstance().Call(Methods.IsSubscribedFromFreeWeekend).AsBool();
+ }
+
+ public static TimedTrial IsTimedTrial()
+ {
+ var raw = GetInstance().Call(Methods.IsTimedTrial).AsGodotDictionary();
+
+ if (!raw.ContainsKey("seconds_allowed") || !raw.ContainsKey("seconds_played"))
+ {
+ return null;
+ }
+
+ return new TimedTrial
+ {
+ SecondsAllowed = raw["seconds_allowed"].AsUInt32(),
+ SecondsPlayed = raw["seconds_played"].AsUInt32(),
+ };
+ }
+
+ public static bool IsVACBanned()
+ {
+ return GetInstance().Call(Methods.IsVACBanned).AsBool();
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.Apps.cs.uid b/addons/godotsteam_csharpbindings/Steam.Apps.cs.uid
new file mode 100644
index 00000000..5526ef12
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Apps.cs.uid
@@ -0,0 +1 @@
+uid://dnmvwnkk5w3va
diff --git a/addons/godotsteam_csharpbindings/Steam.Friends.Signals.cs b/addons/godotsteam_csharpbindings/Steam.Friends.Signals.cs
new file mode 100644
index 00000000..e05e2f95
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Friends.Signals.cs
@@ -0,0 +1,826 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Godot;
+
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public delegate void AvatarLoadedEventHandler(ulong avatarId, int width, byte[] data);
+ private static event AvatarLoadedEventHandler AvatarLoadedEvent;
+ static Action _avatarLoadedAction = (avatarId, width, data) =>
+ {
+ AvatarLoadedEvent?.Invoke(avatarId, width, data);
+ };
+ public static event AvatarLoadedEventHandler AvatarLoaded
+ {
+ add
+ {
+ if (AvatarLoadedEvent == null)
+ {
+ GetInstance().Connect(Signals.AvatarLoaded, Callable.From(_avatarLoadedAction));
+ }
+ AvatarLoadedEvent += value;
+ }
+ remove
+ {
+ AvatarLoadedEvent -= value;
+ if (AvatarLoadedEvent == null)
+ {
+ GetInstance().Disconnect(Signals.AvatarLoaded, Callable.From(_avatarLoadedAction));
+ }
+ }
+ }
+
+ public delegate void AvatarImageLoadedEventHandler(
+ ulong avatarId,
+ uint avatarIndex,
+ uint width,
+ uint height
+ );
+ private static event AvatarImageLoadedEventHandler AvatarImageLoadedEvent;
+ static Action _avatarImageLoadedAction = (
+ avatarId,
+ avatarIndex,
+ width,
+ height
+ ) =>
+ {
+ AvatarImageLoadedEvent?.Invoke(avatarId, avatarIndex, width, height);
+ };
+ public static event AvatarImageLoadedEventHandler AvatarImageLoaded
+ {
+ add
+ {
+ if (AvatarImageLoadedEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.AvatarImageLoaded, Callable.From(_avatarImageLoadedAction));
+ }
+ AvatarImageLoadedEvent += value;
+ }
+ remove
+ {
+ AvatarImageLoadedEvent -= value;
+ if (AvatarImageLoadedEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.AvatarImageLoaded, Callable.From(_avatarImageLoadedAction));
+ }
+ }
+ }
+
+ public delegate void ChangeServerRequestedEventHandler(string server, string password);
+ private static event ChangeServerRequestedEventHandler ChangeServerRequestedEvent;
+ static Action _changeServerRequestedAction = (server, password) =>
+ {
+ ChangeServerRequestedEvent?.Invoke(server, password);
+ };
+ public static event ChangeServerRequestedEventHandler ChangeServerRequested
+ {
+ add
+ {
+ if (ChangeServerRequestedEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.ChangeServerRequested,
+ Callable.From(_changeServerRequestedAction)
+ );
+ }
+ ChangeServerRequestedEvent += value;
+ }
+ remove
+ {
+ ChangeServerRequestedEvent -= value;
+ if (ChangeServerRequestedEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.ChangeServerRequested,
+ Callable.From(_changeServerRequestedAction)
+ );
+ }
+ }
+ }
+
+ public delegate void ClanActivityDownloadedEventHandler(int online, int ingame, int chatting);
+ private static event ClanActivityDownloadedEventHandler ClanActivityDownloadedEvent;
+ static Action _clanActivityDownloadedAction = (online, ingame, chatting) =>
+ {
+ ClanActivityDownloadedEvent?.Invoke(online, ingame, chatting);
+ };
+ public static event ClanActivityDownloadedEventHandler ClanActivityDownloaded
+ {
+ add
+ {
+ if (ClanActivityDownloadedEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.ClanActivityDownloaded,
+ Callable.From(_clanActivityDownloadedAction)
+ );
+ }
+ ClanActivityDownloadedEvent += value;
+ }
+ remove
+ {
+ ClanActivityDownloadedEvent -= value;
+ if (ClanActivityDownloadedEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.ClanActivityDownloaded,
+ Callable.From(_clanActivityDownloadedAction)
+ );
+ }
+ }
+ }
+
+ public delegate void ConnectedChatJoinEventHandler(ulong chatId, ulong steamId);
+ private static event ConnectedChatJoinEventHandler ConnectedChatJoinEvent;
+ static Action _connectedChatJoinAction = (chatId, steamId) =>
+ {
+ ConnectedChatJoinEvent?.Invoke(chatId, steamId);
+ };
+ public static event ConnectedChatJoinEventHandler ConnectedChatJoin
+ {
+ add
+ {
+ if (ConnectedChatJoinEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.ConnectedChatJoin, Callable.From(_connectedChatJoinAction));
+ }
+ ConnectedChatJoinEvent += value;
+ }
+ remove
+ {
+ ConnectedChatJoinEvent -= value;
+ if (ConnectedChatJoinEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.ConnectedChatJoin, Callable.From(_connectedChatJoinAction));
+ }
+ }
+ }
+
+ public delegate void ConnectedChatLeaveEventHandler(
+ ulong chatId,
+ ulong steamId,
+ bool kicked,
+ bool dropped
+ );
+ private static event ConnectedChatLeaveEventHandler ConnectedChatLeaveEvent;
+ static Action _connectedChatLeaveAction = (
+ chatId,
+ steamId,
+ kicked,
+ dropped
+ ) =>
+ {
+ ConnectedChatLeaveEvent?.Invoke(chatId, steamId, kicked, dropped);
+ };
+ public static event ConnectedChatLeaveEventHandler ConnectedChatLeave
+ {
+ add
+ {
+ if (ConnectedChatLeaveEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.ConnectedChatLeave, Callable.From(_connectedChatLeaveAction));
+ }
+ ConnectedChatLeaveEvent += value;
+ }
+ remove
+ {
+ ConnectedChatLeaveEvent -= value;
+ if (ConnectedChatLeaveEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.ConnectedChatLeave,
+ Callable.From(_connectedChatLeaveAction)
+ );
+ }
+ }
+ }
+
+ public delegate void ConnectedClanChatMessageEventHandler(
+ int ret,
+ string text,
+ string type,
+ ulong chatter
+ );
+ private static event ConnectedClanChatMessageEventHandler ConnectedClanChatMessageEvent;
+ static Action _connectedClanChatMessageAction = (raw) =>
+ {
+ ConnectedClanChatMessageEvent?.Invoke(
+ raw["ret"].AsInt32(),
+ raw["text"].AsString(),
+ raw["type"].AsString(),
+ raw["chatter"].AsUInt64()
+ );
+ };
+ public static event ConnectedClanChatMessageEventHandler ConnectedClanChatMessage
+ {
+ add
+ {
+ if (ConnectedClanChatMessageEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.ConnectedClanChatMessage,
+ Callable.From(_connectedClanChatMessageAction)
+ );
+ }
+ ConnectedClanChatMessageEvent += value;
+ }
+ remove
+ {
+ ConnectedClanChatMessageEvent -= value;
+ if (ConnectedClanChatMessageEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.ConnectedClanChatMessage,
+ Callable.From(_connectedClanChatMessageAction)
+ );
+ }
+ }
+ }
+
+ public delegate void ConnectedFriendChatMessageEventHandler(int ret, string text);
+ private static event ConnectedFriendChatMessageEventHandler ConnectedFriendChatMessageEvent;
+ static Action _connectedFriendChatMessageAction = (raw) =>
+ {
+ ConnectedFriendChatMessageEvent?.Invoke(raw["ret"].AsInt32(), raw["text"].AsString());
+ };
+ public static event ConnectedFriendChatMessageEventHandler ConnectedFriendChatMessage
+ {
+ add
+ {
+ if (ConnectedFriendChatMessageEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.ConnectedFriendChatMessage,
+ Callable.From(_connectedFriendChatMessageAction)
+ );
+ }
+ ConnectedFriendChatMessageEvent += value;
+ }
+ remove
+ {
+ ConnectedFriendChatMessageEvent -= value;
+ if (ConnectedFriendChatMessageEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.ConnectedFriendChatMessage,
+ Callable.From(_connectedFriendChatMessageAction)
+ );
+ }
+ }
+ }
+
+ public delegate void EnumerateFollowingListSignalEventHandler(
+ string message,
+ List following
+ );
+ private static event EnumerateFollowingListSignalEventHandler EnumerateFollowingListSignalEvent;
+ static Action _enumerateFollowingListSignalAction = (
+ message,
+ following
+ ) =>
+ {
+ EnumerateFollowingListSignalEvent?.Invoke(
+ message,
+ following
+ .Select(rawFollow => rawFollow.AsGodotDictionary())
+ .Select(followDictionary => new Follow
+ {
+ Num = followDictionary["num"].AsInt32(),
+ Id = followDictionary["id"].AsUInt64(),
+ })
+ .ToList()
+ );
+ };
+ public static event EnumerateFollowingListSignalEventHandler EnumerateFollowingListSignal
+ {
+ add
+ {
+ if (EnumerateFollowingListSignalEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.EnumerateFollowingListSignal,
+ Callable.From(_enumerateFollowingListSignalAction)
+ );
+ }
+ EnumerateFollowingListSignalEvent += value;
+ }
+ remove
+ {
+ EnumerateFollowingListSignalEvent -= value;
+ if (EnumerateFollowingListSignalEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.EnumerateFollowingListSignal,
+ Callable.From(_enumerateFollowingListSignalAction)
+ );
+ }
+ }
+ }
+
+ public delegate void EquippedProfileItemsChangedEventHandler(ulong steamId);
+ private static event EquippedProfileItemsChangedEventHandler EquippedProfileItemsChangedEvent;
+ static Action _equippedProfileItemsChangedAction = (steamId) =>
+ {
+ EquippedProfileItemsChangedEvent?.Invoke(steamId);
+ };
+ public static event EquippedProfileItemsChangedEventHandler EquippedProfileItemsChanged
+ {
+ add
+ {
+ if (EquippedProfileItemsChangedEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.EquippedProfileItemsChanged,
+ Callable.From(_equippedProfileItemsChangedAction)
+ );
+ }
+ EquippedProfileItemsChangedEvent += value;
+ }
+ remove
+ {
+ EquippedProfileItemsChangedEvent -= value;
+ if (EquippedProfileItemsChangedEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.EquippedProfileItemsChanged,
+ Callable.From(_equippedProfileItemsChangedAction)
+ );
+ }
+ }
+ }
+
+ public delegate void EquippedProfileItemsEventHandler(
+ ErrorResult result,
+ ulong steamId,
+ ProfileData profileData
+ );
+ private static event EquippedProfileItemsEventHandler EquippedProfileItemsEvent;
+ static Action _equippedProfileItemsAction = (
+ result,
+ steamId,
+ profileData
+ ) =>
+ {
+ EquippedProfileItemsEvent?.Invoke(
+ (ErrorResult)result,
+ steamId,
+ new ProfileData
+ {
+ AvatarAnimated = profileData["avatar_animated"].AsBool(),
+ AvatarFrame = profileData["avatar_frame"].AsBool(),
+ ProfileModifier = profileData["profile_modifier"].AsBool(),
+ ProfileBackground = profileData["profile_background"].AsBool(),
+ ProfileMiniBackground = profileData["profile_mini_background"].AsBool(),
+ }
+ );
+ };
+ public static event EquippedProfileItemsEventHandler EquippedProfileItems
+ {
+ add
+ {
+ if (EquippedProfileItemsEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.EquippedProfileItems,
+ Callable.From(_equippedProfileItemsAction)
+ );
+ }
+ EquippedProfileItemsEvent += value;
+ }
+ remove
+ {
+ EquippedProfileItemsEvent -= value;
+ if (EquippedProfileItemsEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.EquippedProfileItems,
+ Callable.From(_equippedProfileItemsAction)
+ );
+ }
+ }
+ }
+
+ public delegate void FriendRichPresenceUpdateEventHandler(ulong steamId, uint appId);
+ private static event FriendRichPresenceUpdateEventHandler FriendRichPresenceUpdateEvent;
+ static Action _friendRichPresenceUpdateAction = (steamId, appId) =>
+ {
+ FriendRichPresenceUpdateEvent?.Invoke(steamId, appId);
+ };
+ public static event FriendRichPresenceUpdateEventHandler FriendRichPresenceUpdate
+ {
+ add
+ {
+ if (FriendRichPresenceUpdateEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.FriendRichPresenceUpdate,
+ Callable.From(_friendRichPresenceUpdateAction)
+ );
+ }
+ FriendRichPresenceUpdateEvent += value;
+ }
+ remove
+ {
+ FriendRichPresenceUpdateEvent -= value;
+ if (FriendRichPresenceUpdateEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.FriendRichPresenceUpdate,
+ Callable.From(_friendRichPresenceUpdateAction)
+ );
+ }
+ }
+ }
+
+ public delegate void GetFollowerCountSignalEventHandler(
+ ErrorResult result,
+ ulong steamId,
+ int count
+ );
+ private static event GetFollowerCountSignalEventHandler GetFollowerCountSignalEvent;
+ static Action _getFollowerCountSignalAction = (result, steamId, count) =>
+ {
+ GetFollowerCountSignalEvent?.Invoke((ErrorResult)result, steamId, count);
+ };
+ public static event GetFollowerCountSignalEventHandler GetFollowerCountSignal
+ {
+ add
+ {
+ if (GetFollowerCountSignalEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.GetFollowerCountSignal,
+ Callable.From(_getFollowerCountSignalAction)
+ );
+ }
+ GetFollowerCountSignalEvent += value;
+ }
+ remove
+ {
+ GetFollowerCountSignalEvent -= value;
+ if (GetFollowerCountSignalEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.GetFollowerCountSignal,
+ Callable.From(_getFollowerCountSignalAction)
+ );
+ }
+ }
+ }
+
+ public delegate void IsFollowingSignalEventHandler(
+ ErrorResult result,
+ ulong steamId,
+ bool following
+ );
+ private static event IsFollowingSignalEventHandler IsFollowingSignalEvent;
+ static Action _isFollowingSignalAction = (result, steamId, following) =>
+ {
+ IsFollowingSignalEvent?.Invoke((ErrorResult)result, steamId, following);
+ };
+ public static event IsFollowingSignalEventHandler IsFollowingSignal
+ {
+ add
+ {
+ if (IsFollowingSignalEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.IsFollowingSignal, Callable.From(_isFollowingSignalAction));
+ }
+ IsFollowingSignalEvent += value;
+ }
+ remove
+ {
+ IsFollowingSignalEvent -= value;
+ if (IsFollowingSignalEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.IsFollowingSignal, Callable.From(_isFollowingSignalAction));
+ }
+ }
+ }
+
+ public delegate void JoinClanChatCompleteEventHandler(
+ ulong chatId,
+ ChatRoomEnterResponse response
+ );
+ private static event JoinClanChatCompleteEventHandler JoinClanChatCompleteEvent;
+ static Action _joinClanChatCompleteAction = (chatId, response) =>
+ {
+ JoinClanChatCompleteEvent?.Invoke(chatId, (ChatRoomEnterResponse)response);
+ };
+ public static event JoinClanChatCompleteEventHandler JoinClanChatComplete
+ {
+ add
+ {
+ if (JoinClanChatCompleteEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.JoinClanChatComplete,
+ Callable.From(_joinClanChatCompleteAction)
+ );
+ }
+ JoinClanChatCompleteEvent += value;
+ }
+ remove
+ {
+ JoinClanChatCompleteEvent -= value;
+ if (JoinClanChatCompleteEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.JoinClanChatComplete,
+ Callable.From(_joinClanChatCompleteAction)
+ );
+ }
+ }
+ }
+
+ public delegate void JoinGameRequestedEventHandler(ulong user, string connect);
+ private static event JoinGameRequestedEventHandler JoinGameRequestedEvent;
+ static Action _joinGameRequestedAction = (user, connect) =>
+ {
+ JoinGameRequestedEvent?.Invoke(user, connect);
+ };
+ public static event JoinGameRequestedEventHandler JoinGameRequested
+ {
+ add
+ {
+ if (JoinGameRequestedEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.JoinGameRequested, Callable.From(_joinGameRequestedAction));
+ }
+ JoinGameRequestedEvent += value;
+ }
+ remove
+ {
+ JoinGameRequestedEvent -= value;
+ if (JoinGameRequestedEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.JoinGameRequested, Callable.From(_joinGameRequestedAction));
+ }
+ }
+ }
+
+ public delegate void JoinRequestedEventHandler(ulong lobbyId, ulong steamId);
+ private static event JoinRequestedEventHandler JoinRequestedEvent;
+ static Action _joinRequestedAction = (lobbyId, steamId) =>
+ {
+ JoinRequestedEvent?.Invoke(lobbyId, steamId);
+ };
+ public static event JoinRequestedEventHandler JoinRequested
+ {
+ add
+ {
+ if (JoinRequestedEvent == null)
+ {
+ GetInstance().Connect(Signals.JoinRequested, Callable.From(_joinRequestedAction));
+ }
+ JoinRequestedEvent += value;
+ }
+ remove
+ {
+ JoinRequestedEvent -= value;
+ if (JoinRequestedEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.JoinRequested, Callable.From(_joinRequestedAction));
+ }
+ }
+ }
+
+ public delegate void NameChangedEventHandler(
+ bool success,
+ bool localSuccess,
+ ErrorResult result
+ );
+ private static event NameChangedEventHandler NameChangedEvent;
+ static Action _nameChangedAction = (success, localSuccess, result) =>
+ {
+ NameChangedEvent?.Invoke(success, localSuccess, (ErrorResult)result);
+ };
+ public static event NameChangedEventHandler NameChanged
+ {
+ add
+ {
+ if (NameChangedEvent == null)
+ {
+ GetInstance().Connect(Signals.NameChanged, Callable.From(_nameChangedAction));
+ }
+ NameChangedEvent += value;
+ }
+ remove
+ {
+ NameChangedEvent -= value;
+ if (NameChangedEvent == null)
+ {
+ GetInstance().Disconnect(Signals.NameChanged, Callable.From(_nameChangedAction));
+ }
+ }
+ }
+
+ public delegate void OverlayBrowserProtocolEventHandler(Uri uri);
+ private static event OverlayBrowserProtocolEventHandler OverlayBrowserProtocolEvent;
+ static Action _overlayBrowserProtocolAction = (uri) =>
+ {
+ OverlayBrowserProtocolEvent?.Invoke(new Uri(uri));
+ };
+ public static event OverlayBrowserProtocolEventHandler OverlayBrowserProtocol
+ {
+ add
+ {
+ if (OverlayBrowserProtocolEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.OverlayBrowserProtocol,
+ Callable.From(_overlayBrowserProtocolAction)
+ );
+ }
+ OverlayBrowserProtocolEvent += value;
+ }
+ remove
+ {
+ OverlayBrowserProtocolEvent -= value;
+ if (OverlayBrowserProtocolEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.OverlayBrowserProtocol,
+ Callable.From(_overlayBrowserProtocolAction)
+ );
+ }
+ }
+ }
+
+ public delegate void OverlayToggledEventHandler(bool active, bool userInitiated, uint appId);
+ private static event OverlayToggledEventHandler OverlayToggledEvent;
+ static Action _overlayToggledAction = (active, userInitiated, appId) =>
+ {
+ OverlayToggledEvent?.Invoke(active, userInitiated, appId);
+ };
+ public static event OverlayToggledEventHandler OverlayToggled
+ {
+ add
+ {
+ if (OverlayToggledEvent == null)
+ {
+ GetInstance().Connect(Signals.OverlayToggled, Callable.From(_overlayToggledAction));
+ }
+ OverlayToggledEvent += value;
+ }
+ remove
+ {
+ OverlayToggledEvent -= value;
+ if (OverlayToggledEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.OverlayToggled, Callable.From(_overlayToggledAction));
+ }
+ }
+ }
+
+ public delegate void PersonaStateChangeEventHandler(ulong steamId, PersonaChange flags);
+ private static event PersonaStateChangeEventHandler PersonaStateChangeEvent;
+ static Action _personaStateChangeAction = (steamId, flags) =>
+ {
+ PersonaStateChangeEvent?.Invoke(steamId, (PersonaChange)flags);
+ };
+ public static event PersonaStateChangeEventHandler PersonaStateChange
+ {
+ add
+ {
+ if (PersonaStateChangeEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.PersonaStateChange, Callable.From(_personaStateChangeAction));
+ }
+ PersonaStateChangeEvent += value;
+ }
+ remove
+ {
+ PersonaStateChangeEvent -= value;
+ if (PersonaStateChangeEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.PersonaStateChange,
+ Callable.From(_personaStateChangeAction)
+ );
+ }
+ }
+ }
+
+ public delegate void RequestClanOfficerListSignalEventHandler(
+ string message,
+ List officerList
+ );
+ private static event RequestClanOfficerListSignalEventHandler RequestClanOfficerListSignalEvent;
+ static Action _requestClanOfficerListSignalAction = (
+ message,
+ officerList
+ ) =>
+ {
+ RequestClanOfficerListSignalEvent?.Invoke(
+ message,
+ officerList
+ .Select(rawOfficer => rawOfficer.AsGodotDictionary())
+ .Select(officerDictionary => new ClanOfficer
+ {
+ Id = officerDictionary["id"].AsUInt64(),
+ Name = officerDictionary["name"].AsString(),
+ })
+ .ToList()
+ );
+ };
+ public static event RequestClanOfficerListSignalEventHandler RequestClanOfficerListSignal
+ {
+ add
+ {
+ if (RequestClanOfficerListSignalEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.RequestClanOfficerListSignal,
+ Callable.From(_requestClanOfficerListSignalAction)
+ );
+ }
+ RequestClanOfficerListSignalEvent += value;
+ }
+ remove
+ {
+ RequestClanOfficerListSignalEvent -= value;
+ if (RequestClanOfficerListSignalEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.RequestClanOfficerListSignal,
+ Callable.From(_requestClanOfficerListSignalAction)
+ );
+ }
+ }
+ }
+
+ private static event Action UnreadChatMessagesChangedEvent;
+ static Action _unreadChatMessagesChangedAction = () =>
+ {
+ UnreadChatMessagesChangedEvent?.Invoke();
+ };
+ public static event Action UnreadChatMessagesChanged
+ {
+ add
+ {
+ if (UnreadChatMessagesChangedEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.UnreadChatMessagesChanged,
+ Callable.From(_unreadChatMessagesChangedAction)
+ );
+ }
+ UnreadChatMessagesChangedEvent += value;
+ }
+ remove
+ {
+ UnreadChatMessagesChangedEvent -= value;
+ if (UnreadChatMessagesChangedEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.UnreadChatMessagesChanged,
+ Callable.From(_unreadChatMessagesChangedAction)
+ );
+ }
+ }
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.Friends.Signals.cs.uid b/addons/godotsteam_csharpbindings/Steam.Friends.Signals.cs.uid
new file mode 100644
index 00000000..5de9acc2
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Friends.Signals.cs.uid
@@ -0,0 +1 @@
+uid://b0d4cx08c5cyv
diff --git a/addons/godotsteam_csharpbindings/Steam.Friends.cs b/addons/godotsteam_csharpbindings/Steam.Friends.cs
new file mode 100644
index 00000000..288aed7e
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Friends.cs
@@ -0,0 +1,536 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Godot;
+using Godot.Collections;
+using Godot.NativeInterop;
+
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public static void ActivateGameOverlay(GameOverlayType type)
+ {
+ GetInstance().Call(Methods.ActivateGameOverlay, type.ToGodotSteam());
+ }
+
+ public static void ActivateGameOverlayInviteDialog(ulong steamId)
+ {
+ GetInstance().Call(Methods.ActivateGameOverlayInviteDialog, steamId);
+ }
+
+ public static void ActivateGameOverlayInviteDialogConnectString(string connectString)
+ {
+ GetInstance().Call(Methods.ActivateGameOverlayInviteDialogConnectString, connectString);
+ }
+
+ public static void ActivateGameOverlayToStore(uint appId = 0)
+ {
+ GetInstance().Call(Methods.ActivateGameOverlayToStore, appId);
+ }
+
+ public static void ActivateGameOverlayToUser(GameOverlayUserType type, ulong steamId = 0)
+ {
+ GetInstance().Call(Methods.ActivateGameOverlayToUser, type.ToGodotSteam(), steamId);
+ }
+
+ public static void ActivateGameOverlayToWebPage(string url)
+ {
+ GetInstance().Call(Methods.ActivateGameOverlayToWebPage, url);
+ }
+
+ public static void GetFollowerCount(ulong steamId)
+ {
+ GetInstance().Call(Methods.GetFollowerCount, steamId);
+ }
+
+ public static ulong GetFriendByIndex(int friendNumber, FriendFlag friendFlags)
+ {
+ return GetInstance()
+ .Call(Methods.GetFriendByIndex, friendNumber, (int)friendFlags)
+ .AsUInt64();
+ }
+
+ public static uint GetFriendCoplayGame(ulong friendId)
+ {
+ return GetInstance().Call(Methods.GetFriendCoplayGame, friendId).AsUInt32();
+ }
+
+ public static int GetFriendCoplayTime(ulong friendId)
+ {
+ return GetInstance().Call(Methods.GetFriendCoplayTime, friendId).AsInt32();
+ }
+
+ public static int GetFriendCount(FriendFlag friendFlags = FriendFlag.Immediate)
+ {
+ return GetInstance().Call(Methods.GetFriendCount, (int)friendFlags).AsInt32();
+ }
+
+ public static int GetFriendCountFromSource(long sourceId)
+ {
+ return GetInstance().Call(Methods.GetFriendCountFromSource, sourceId).AsInt32();
+ }
+
+ public static ulong GetFriendFromSourceByIndex(ulong sourceId, long friendNumber)
+ {
+ return GetInstance()
+ .Call(Methods.GetFriendFromSourceByIndex, sourceId, friendNumber)
+ .AsUInt64();
+ }
+
+ public static Godot.Collections.Dictionary GetFriendGamePlayed(ulong steamId)
+ {
+ return GetInstance().Call(Methods.GetFriendGamePlayed, steamId).AsGodotDictionary();
+ }
+
+ public static Godot.Collections.Dictionary GetFriendMessage(ulong friendId, long message)
+ {
+ return GetInstance().Call(Methods.GetFriendMessage, friendId, message).AsGodotDictionary();
+ }
+
+ public static string GetFriendPersonaName(ulong steamId)
+ {
+ return GetInstance().Call(Methods.GetFriendPersonaName, steamId).AsString();
+ }
+
+ public static string GetFriendPersonaNameHistory(ulong steamId, long nameHistory)
+ {
+ return GetInstance()
+ .Call(Methods.GetFriendPersonaNameHistory, steamId, nameHistory)
+ .AsString();
+ }
+
+ public static PersonaState GetFriendPersonaState(ulong steamId)
+ {
+ return (PersonaState)GetInstance().Call(Methods.GetFriendPersonaState, steamId).AsInt64();
+ }
+
+ public static FriendRelationship GetFriendRelationship(ulong steamId)
+ {
+ return (FriendRelationship)
+ GetInstance().Call(Methods.GetFriendRelationship, steamId).AsInt64();
+ }
+
+ public static string GetFriendRichPresence(ulong friendId, string key)
+ {
+ return GetInstance().Call(Methods.GetFriendRichPresence, friendId, key).AsString();
+ }
+
+ public static int GetFriendRichPresenceKeyCount(ulong friendId)
+ {
+ return GetInstance().Call(Methods.GetFriendRichPresenceKeyCount, friendId).AsInt32();
+ }
+
+ public static string GetFriendRichPresenceKeyByIndex(ulong friendId, int key)
+ {
+ return GetInstance()
+ .Call(Methods.GetFriendRichPresenceKeyByIndex, friendId, key)
+ .AsString();
+ }
+
+ public static int GetFriendsGroupCount()
+ {
+ return GetInstance().Call(Methods.GetFriendsGroupCount).AsInt32();
+ }
+
+ public static short GetFriendsGroupIDByIndex(short friendGroup)
+ {
+ return GetInstance().Call(Methods.GetFriendsGroupIDByIndex, friendGroup).AsInt16();
+ }
+
+ public static int GetFriendsGroupMembersCount(short friendGroup)
+ {
+ return GetInstance().Call(Methods.GetFriendsGroupMembersCount, friendGroup).AsInt32();
+ }
+
+ public static List GetFriendsGroupMembersList(short friendGroup, long memberCount)
+ {
+ var raw = GetInstance()
+ .Call(Methods.GetFriendsGroupMembersList, friendGroup, memberCount)
+ .AsGodotArray();
+
+ return raw.Select(x => x.AsUInt64()).ToList();
+ }
+
+ public static string GetFriendsGroupName(short friendGroup)
+ {
+ return GetInstance().Call(Methods.GetFriendsGroupName, friendGroup).AsString();
+ }
+
+ public static int GetFriendSteamLevel(ulong steamId)
+ {
+ return GetInstance().Call(Methods.GetFriendSteamLevel, steamId).AsInt32();
+ }
+
+ public static int GetLargeFriendAvatar(ulong steamId)
+ {
+ return GetInstance().Call(Methods.GetLargeFriendAvatar, steamId).AsInt32();
+ }
+
+ public static int GetMediumFriendAvatar(ulong steamId)
+ {
+ return GetInstance().Call(Methods.GetMediumFriendAvatar, steamId).AsInt32();
+ }
+
+ public static int GetSmallFriendAvatar(ulong steamId)
+ {
+ return GetInstance().Call(Methods.GetSmallFriendAvatar, steamId).AsInt32();
+ }
+
+ public static bool ReplyToFriendMessage(ulong steamId, string message)
+ {
+ return GetInstance().Call(Methods.ReplyToFriendMessage, steamId, message).AsBool();
+ }
+
+ public static void RequestFriendRichPresence(ulong friendId)
+ {
+ GetInstance().Call(Methods.RequestFriendRichPresence, friendId);
+ }
+
+ public static bool SetListenForFriendsMessages(bool intercept)
+ {
+ return GetInstance().Call(Methods.SetListenForFriendsMessages, intercept).AsBool();
+ }
+
+ public static ulong GetCoplayFriend(int friendNumber)
+ {
+ return GetInstance().Call(Methods.GetCoplayFriend, friendNumber).AsUInt64();
+ }
+
+ public static int GetCoplayFriendCount()
+ {
+ return GetInstance().Call(Methods.GetCoplayFriendCount).AsInt32();
+ }
+
+ public static bool CloseClanChatWindowInSteam(ulong chatId)
+ {
+ return GetInstance().Call(Methods.CloseClanChatWindowInSteam, chatId).AsBool();
+ }
+
+ public static void DownloadClanActivityCounts(ulong chatId, int clansToRequest)
+ {
+ GetInstance().Call(Methods.DownloadClanActivityCounts, chatId, clansToRequest);
+ }
+
+ public static void EnumerateFollowingList(uint startIndex)
+ {
+ GetInstance().Call(Methods.EnumerateFollowingList, startIndex);
+ }
+
+ public static ulong GetChatMemberByIndex(ulong clanId, long user)
+ {
+ return GetInstance().Call(Methods.GetChatMemberByIndex, clanId, user).AsUInt64();
+ }
+
+ public static ClanActivityCounts GetClanActivityCounts(ulong clanId)
+ {
+ var raw = GetInstance().Call(Methods.GetClanActivityCounts, clanId).AsGodotDictionary();
+
+ if (
+ !raw.ContainsKey("clan")
+ || !raw.ContainsKey("online")
+ || !raw.ContainsKey("ingame")
+ || !raw.ContainsKey("chatting")
+ )
+ {
+ return null;
+ }
+
+ return new ClanActivityCounts
+ {
+ Clan = raw["clan"].AsUInt64(),
+ Online = raw["online"].AsInt32(),
+ Ingame = raw["ingame"].AsInt32(),
+ Chatting = raw["chatting"].AsInt32(),
+ };
+ }
+
+ public static ulong GetClanByIndex(int clan)
+ {
+ return GetInstance().Call(Methods.GetClanByIndex, clan).AsUInt64();
+ }
+
+ public static int GetClanChatMemberCount(ulong clanId)
+ {
+ return GetInstance().Call(Methods.GetClanChatMemberCount, clanId).AsInt32();
+ }
+
+ public static ClanChatMessage GetClanChatMessage(ulong chatId, long message)
+ {
+ var raw = GetInstance()
+ .Call(Methods.GetClanChatMessage, chatId, message)
+ .AsGodotDictionary();
+
+ if (!raw.ContainsKey("ret"))
+ {
+ return null;
+ }
+
+ return new ClanChatMessage
+ {
+ Ret = raw["ret"].AsBool(),
+ Text = raw["text"].AsString(),
+ Type = (ClanChatMessageType)raw["type"].AsInt32(),
+ Chatter = raw["chatter"].AsUInt64(),
+ };
+ }
+
+ public static int GetClanCount()
+ {
+ return GetInstance().Call(Methods.GetClanCount).AsInt32();
+ }
+
+ public static string GetClanName(ulong clanId)
+ {
+ return GetInstance().Call(Methods.GetClanName, clanId).AsString();
+ }
+
+ public static ulong GetClanOfficerByIndex(ulong clanId, int officer)
+ {
+ return GetInstance().Call(Methods.GetClanOfficerByIndex, clanId, officer).AsUInt64();
+ }
+
+ public static int GetClanOfficerCount(ulong clanId)
+ {
+ return GetInstance().Call(Methods.GetClanOfficerCount, clanId).AsInt32();
+ }
+
+ public static ulong GetClanOwner(ulong clanId)
+ {
+ return GetInstance().Call(Methods.GetClanOwner, clanId).AsUInt64();
+ }
+
+ public static string GetClanTag(ulong clanId)
+ {
+ return GetInstance().Call(Methods.GetClanTag, clanId).AsString();
+ }
+
+ public static bool IsClanChatAdmin(ulong chatId, ulong steamId)
+ {
+ return GetInstance().Call(Methods.IsClanChatAdmin, chatId, steamId).AsBool();
+ }
+
+ public static bool IsClanPublic(ulong clanId)
+ {
+ return GetInstance().Call(Methods.IsClanPublic, clanId).AsBool();
+ }
+
+ public static bool IsClanOfficialGameGroup(ulong clanId)
+ {
+ return GetInstance().Call(Methods.IsClanOfficialGameGroup, clanId).AsBool();
+ }
+
+ public static bool IsClanChatWindowOpenInSteam(ulong chatId)
+ {
+ return GetInstance().Call(Methods.IsClanChatWindowOpenInSteam, chatId).AsBool();
+ }
+
+ public static void JoinClanChatRoom(ulong clanId)
+ {
+ GetInstance().Call(Methods.JoinClanChatRoom, clanId);
+ }
+
+ public static bool LeaveClanChatRoom(ulong clanId)
+ {
+ return GetInstance().Call(Methods.LeaveClanChatRoom, clanId).AsBool();
+ }
+
+ public static bool OpenClanChatWindowInSteam(ulong chatId)
+ {
+ return GetInstance().Call(Methods.OpenClanChatWindowInSteam, chatId).AsBool();
+ }
+
+ public static void RequestClanOfficerList(ulong clanId)
+ {
+ GetInstance().Call(Methods.RequestClanOfficerList, clanId);
+ }
+
+ public static bool SendClanChatMessage(ulong chatId, string text)
+ {
+ return GetInstance().Call(Methods.SendClanChatMessage, chatId, text).AsBool();
+ }
+
+ public static string GetPersonaName()
+ {
+ return GetInstance().Call(Methods.GetPersonaName).AsString();
+ }
+
+ public static PersonaState GetPersonaState()
+ {
+ return (PersonaState)GetInstance().Call(Methods.GetPersonaState).AsInt64();
+ }
+
+ public static void GetPlayerAvatar(AvatarSize size = AvatarSize.Medium, ulong steamId = 0)
+ {
+ GetInstance().Call(Methods.GetPlayerAvatar, (int)size, steamId);
+ }
+
+ public static string GetPlayerNickname(ulong steamId)
+ {
+ return GetInstance().Call(Methods.GetPlayerNickname, steamId).AsString();
+ }
+
+ public static string GetProfileItemPropertyString(
+ ulong steamId,
+ CommunityProfileItemType itemType,
+ CommunityProfileItemProperty itemProperty
+ )
+ {
+ return GetInstance()
+ .Call(Methods.GetProfileItemPropertyString, steamId, (int)itemType, (int)itemProperty)
+ .AsString();
+ }
+
+ public static uint GetProfileItemPropertyInt(
+ ulong steamId,
+ CommunityProfileItemType itemType,
+ CommunityProfileItemProperty itemProperty
+ )
+ {
+ return GetInstance()
+ .Call(Methods.GetProfileItemPropertyInt, steamId, (int)itemType, (int)itemProperty)
+ .AsUInt32();
+ }
+
+ public static List GetRecentPlayers()
+ {
+ var raw = GetInstance().Call(Methods.GetRecentPlayers).AsGodotArray();
+
+ return raw.Select(rawPlayer => rawPlayer.AsGodotDictionary())
+ .Select(playerDictionary => new RecentPlayer
+ {
+ Id = playerDictionary["id"].AsUInt64(),
+ Name = playerDictionary["name"].AsString(),
+ Time = playerDictionary["time"].AsInt32(),
+ Status = (PersonaState)playerDictionary["status"].AsInt32(),
+ })
+ .ToList();
+ }
+
+ public static List GetUserFriendsGroups()
+ {
+ var raw = GetInstance().Call(Methods.GetUserFriendsGroups).AsGodotArray();
+
+ return raw.Select(rawFriendGroup => rawFriendGroup.AsGodotDictionary())
+ .Select(friendGroupDictionary => new FriendGroup
+ {
+ Id = friendGroupDictionary["id"].AsInt16(),
+ Name = friendGroupDictionary["name"].AsString(),
+ Members = friendGroupDictionary["time"].AsInt32(),
+ })
+ .ToList();
+ }
+
+ public static UserRestriction GetUserRestrictions()
+ {
+ return (UserRestriction)GetInstance().Call(Methods.GetUserRestrictions).AsUInt32();
+ }
+
+ public static List GetUserSteamFriends()
+ {
+ var raw = GetInstance().Call(Methods.GetUserSteamFriends).AsGodotArray();
+
+ return raw.Select(rawFriend => rawFriend.AsGodotDictionary())
+ .Select(friendDictionary => new Friend
+ {
+ Id = friendDictionary["id"].AsUInt64(),
+ Name = friendDictionary["name"].AsString(),
+ Status = (PersonaState)friendDictionary["status"].AsInt32(),
+ })
+ .ToList();
+ }
+
+ public static List GetUserSteamGroups()
+ {
+ var raw = GetInstance().Call(Methods.GetUserSteamGroups).AsGodotArray();
+
+ return raw.Select(rawGroups => rawGroups.AsGodotDictionary())
+ .Select(groupDictionary => new SteamGroup
+ {
+ Id = groupDictionary["id"].AsUInt64(),
+ Name = groupDictionary["name"].AsString(),
+ Tag = groupDictionary["tag"].AsString(),
+ })
+ .ToList();
+ }
+
+ public static bool HasEquippedProfileItem(ulong steamId, CommunityProfileItemType itemType)
+ {
+ return GetInstance().Call(Methods.HasEquippedProfileItem, steamId, (long)itemType).AsBool();
+ }
+
+ public static bool HasFriend(ulong steamId, FriendFlag friendFlags)
+ {
+ return GetInstance().Call(Methods.HasFriend, steamId, (int)friendFlags).AsBool();
+ }
+
+ public static bool InviteUserToGame(ulong friendId, string connectString)
+ {
+ return GetInstance().Call(Methods.InviteUserToGame, friendId, connectString).AsBool();
+ }
+
+ public static void IsFollowing(ulong steamId)
+ {
+ GetInstance().Call(Methods.IsFollowing, steamId);
+ }
+
+ public static bool IsUserInSource(ulong steamId, ulong sourceId)
+ {
+ return GetInstance().Call(Methods.IsUserInSource, steamId, sourceId).AsBool();
+ }
+
+ public static void RequestEquippedProfileItems(ulong steamId)
+ {
+ GetInstance().Call(Methods.RequestEquippedProfileItems, steamId);
+ }
+
+ public static bool RequestUserInformation(ulong steamId, bool requireNameOnly)
+ {
+ return GetInstance()
+ .Call(Methods.RequestUserInformation, steamId, requireNameOnly)
+ .AsBool();
+ }
+
+ public static void SetPersonaName(string name)
+ {
+ GetInstance().Call(Methods.SetPersonaName, name);
+ }
+
+ public static void SetPlayedWith(ulong steamId)
+ {
+ GetInstance().Call(Methods.SetPlayedWith, steamId);
+ }
+
+ public static bool SetRichPresence(string richPresenceKey, string value)
+ {
+ return GetInstance().Call(Methods.SetRichPresence, richPresenceKey, value).AsBool();
+ }
+
+ public static void SetInGameVoiceSpeaking(ulong steamId, bool speaking)
+ {
+ GetInstance().Call(Methods.SetInGameVoiceSpeaking, steamId, speaking);
+ }
+
+ public static void ClearRichPresence()
+ {
+ GetInstance().Call(Methods.ClearRichPresence);
+ }
+
+ public static bool RegisterProtocolInOverlayBrowser(string protocol)
+ {
+ return GetInstance().Call(Methods.RegisterProtocolInOverlayBrowser, protocol).AsBool();
+ }
+
+ public enum OverlayToStoreFlag : long
+ {
+ None = 0,
+ AddToCart = 1,
+ AndToCartAndShow = 2,
+ }
+
+ public enum OverlayToWebPageMode : long
+ {
+ Default = 0,
+ Modal = 1,
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.Friends.cs.uid b/addons/godotsteam_csharpbindings/Steam.Friends.cs.uid
new file mode 100644
index 00000000..a7921146
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Friends.cs.uid
@@ -0,0 +1 @@
+uid://4ubxcddlrnq1
diff --git a/addons/godotsteam_csharpbindings/Steam.GameSearch.Signals.cs b/addons/godotsteam_csharpbindings/Steam.GameSearch.Signals.cs
new file mode 100644
index 00000000..80cc1665
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.GameSearch.Signals.cs
@@ -0,0 +1,311 @@
+using System;
+using Godot;
+
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public delegate void EndGameResultEventHandler(ErrorResult result, ulong gameId);
+ private static event EndGameResultEventHandler EndGameResultEvent;
+ static Action _endGameResultAction = (result, gameId) =>
+ {
+ EndGameResultEvent?.Invoke((ErrorResult)result, gameId);
+ };
+ public static event EndGameResultEventHandler EndGameResult
+ {
+ add
+ {
+ if (EndGameResultEvent == null)
+ {
+ GetInstance().Connect(Signals.EndGameResult, Callable.From(_endGameResultAction));
+ }
+ EndGameResultEvent += value;
+ }
+ remove
+ {
+ EndGameResultEvent -= value;
+ if (EndGameResultEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.EndGameResult, Callable.From(_endGameResultAction));
+ }
+ }
+ }
+
+ public delegate void RequestPlayersForGameFinalResultEventHandler(
+ ErrorResult result,
+ ulong searchId,
+ ulong gameId
+ );
+ private static event RequestPlayersForGameFinalResultEventHandler RequestPlayersForGameFinalResultEvent;
+ static Action _requestPlayersForGameFinalResultAction = (
+ result,
+ searchId,
+ gameId
+ ) =>
+ {
+ RequestPlayersForGameFinalResultEvent?.Invoke((ErrorResult)result, searchId, gameId);
+ };
+ public static event RequestPlayersForGameFinalResultEventHandler RequestPlayersForGameFinalResult
+ {
+ add
+ {
+ if (RequestPlayersForGameFinalResultEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.RequestPlayersForGameFinalResult,
+ Callable.From(_requestPlayersForGameFinalResultAction)
+ );
+ }
+ RequestPlayersForGameFinalResultEvent += value;
+ }
+ remove
+ {
+ RequestPlayersForGameFinalResultEvent -= value;
+ if (RequestPlayersForGameFinalResultEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.RequestPlayersForGameFinalResult,
+ Callable.From(_requestPlayersForGameFinalResultAction)
+ );
+ }
+ }
+ }
+
+ public delegate void RequestPlayersForGameProgressEventHandler(
+ ErrorResult result,
+ ulong searchId
+ );
+ private static event RequestPlayersForGameProgressEventHandler RequestPlayersForGameProgressEvent;
+ static Action _requestPlayersForGameProgressAction = (result, searchId) =>
+ {
+ RequestPlayersForGameProgressEvent?.Invoke((ErrorResult)result, searchId);
+ };
+ public static event RequestPlayersForGameProgressEventHandler RequestPlayersForGameProgress
+ {
+ add
+ {
+ if (RequestPlayersForGameProgressEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.RequestPlayersForGameProgress,
+ Callable.From(_requestPlayersForGameProgressAction)
+ );
+ }
+ RequestPlayersForGameProgressEvent += value;
+ }
+ remove
+ {
+ RequestPlayersForGameProgressEvent -= value;
+ if (RequestPlayersForGameProgressEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.RequestPlayersForGameProgress,
+ Callable.From(_requestPlayersForGameProgressAction)
+ );
+ }
+ }
+ }
+
+ public delegate void RequestPlayersForGameResultEventHandler(
+ ErrorResult result,
+ ulong searchId,
+ PlayerData playerData
+ );
+ private static event RequestPlayersForGameResultEventHandler RequestPlayersForGameResultEvent;
+ static Action _requestPlayersForGameResultAction = (
+ result,
+ searchId,
+ playerData
+ ) =>
+ {
+ RequestPlayersForGameResultEvent?.Invoke(
+ (ErrorResult)result,
+ searchId,
+ new PlayerData
+ {
+ PlayerId = playerData["player_id"].AsUInt64(),
+ LobbyId = playerData["lobby_id"].AsUInt64(),
+ PlayerAcceptState = playerData["player_accept_state"].AsInt32(),
+ PlayerIndex = playerData["player_index"].AsInt32(),
+ TotalPlayers = playerData["total_players"].AsInt32(),
+ TotalPlayersAcceptedGame = playerData["total_players_accepted_game"].AsInt32(),
+ SuggestedTeamIndex = playerData["suggested_team_index"].AsInt32(),
+ UniqueGameId = playerData["unique_game_id"].AsUInt64(),
+ }
+ );
+ };
+ public static event RequestPlayersForGameResultEventHandler RequestPlayersForGameResult
+ {
+ add
+ {
+ if (RequestPlayersForGameResultEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.RequestPlayersForGameResult,
+ Callable.From(_requestPlayersForGameResultAction)
+ );
+ }
+ RequestPlayersForGameResultEvent += value;
+ }
+ remove
+ {
+ RequestPlayersForGameResultEvent -= value;
+ if (RequestPlayersForGameResultEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.RequestPlayersForGameResult,
+ Callable.From(_requestPlayersForGameResultAction)
+ );
+ }
+ }
+ }
+
+ public delegate void SearchForGameProgressEventHandler(
+ ErrorResult result,
+ long searchId,
+ SearchProgress searchProgress
+ );
+ private static event SearchForGameProgressEventHandler SearchForGameProgressEvent;
+ static Action _searchForGameProgressAction = (
+ result,
+ searchId,
+ searchProgress
+ ) =>
+ {
+ SearchForGameProgressEvent?.Invoke(
+ (ErrorResult)result,
+ searchId,
+ new SearchProgress
+ {
+ LobbyId = searchProgress["lobby_id"].AsUInt64(),
+ EndedSearchId = searchProgress["lobby_id"].AsUInt64(),
+ SecondsRemainingEstimate = searchProgress["seconds_remaining_estimate"].AsInt32(),
+ PlayersSearching = searchProgress["players_searching"].AsInt32(),
+ }
+ );
+ };
+ public static event SearchForGameProgressEventHandler SearchForGameProgress
+ {
+ add
+ {
+ if (SearchForGameProgressEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.SearchForGameProgress,
+ Callable.From(_searchForGameProgressAction)
+ );
+ }
+ SearchForGameProgressEvent += value;
+ }
+ remove
+ {
+ SearchForGameProgressEvent -= value;
+ if (SearchForGameProgressEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.SearchForGameProgress,
+ Callable.From(_searchForGameProgressAction)
+ );
+ }
+ }
+ }
+
+ public delegate void SearchForGameResultEventHandler(
+ ErrorResult result,
+ ulong searchId,
+ SearchResult searchResult
+ );
+ private static event SearchForGameResultEventHandler SearchForGameResultEvent;
+ static Action _searchForGameResultAction = (
+ result,
+ searchId,
+ searchResult
+ ) =>
+ {
+ SearchForGameResultEvent?.Invoke(
+ (ErrorResult)result,
+ searchId,
+ new SearchResult
+ {
+ CountPlayersIngame = searchResult["count_players_ingame"].AsInt32(),
+ CountAcceptedGame = searchResult["count_accepted_game"].AsInt32(),
+ HostId = searchResult["host_id"].AsUInt64(),
+ FinalCallback = searchResult["final_callback"].AsBool(),
+ }
+ );
+ };
+ public static event SearchForGameResultEventHandler SearchForGameResult
+ {
+ add
+ {
+ if (SearchForGameResultEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.SearchForGameResult,
+ Callable.From(_searchForGameResultAction)
+ );
+ }
+ SearchForGameResultEvent += value;
+ }
+ remove
+ {
+ SearchForGameResultEvent -= value;
+ if (SearchForGameResultEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.SearchForGameResult,
+ Callable.From(_searchForGameResultAction)
+ );
+ }
+ }
+ }
+
+ public delegate void SubmitPlayerResultSignalEventHandler(
+ ErrorResult result,
+ ulong gameId,
+ ulong playerId
+ );
+ private static event SubmitPlayerResultSignalEventHandler SubmitPlayerResultSignalEvent;
+ static Action _submitPlayerResultSignalAction = (result, gameId, playerId) =>
+ {
+ SubmitPlayerResultSignalEvent?.Invoke((ErrorResult)result, gameId, playerId);
+ };
+ public static event SubmitPlayerResultSignalEventHandler SubmitPlayerResultSignal
+ {
+ add
+ {
+ if (SubmitPlayerResultSignalEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.SubmitPlayerResultSignal,
+ Callable.From(_submitPlayerResultSignalAction)
+ );
+ }
+ SubmitPlayerResultSignalEvent += value;
+ }
+ remove
+ {
+ SubmitPlayerResultSignalEvent -= value;
+ if (SubmitPlayerResultSignalEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.SubmitPlayerResultSignal,
+ Callable.From(_submitPlayerResultSignalAction)
+ );
+ }
+ }
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.GameSearch.Signals.cs.uid b/addons/godotsteam_csharpbindings/Steam.GameSearch.Signals.cs.uid
new file mode 100644
index 00000000..aa8dfefa
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.GameSearch.Signals.cs.uid
@@ -0,0 +1 @@
+uid://rsejto4lkgw7
diff --git a/addons/godotsteam_csharpbindings/Steam.GameSearch.cs b/addons/godotsteam_csharpbindings/Steam.GameSearch.cs
new file mode 100644
index 00000000..8175dabe
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.GameSearch.cs
@@ -0,0 +1,87 @@
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public static int AddGameSearchParams(string key, string values)
+ {
+ return GetInstance().Call(Methods.AddGameSearchParams, key, values).AsInt32();
+ }
+
+ public static int SearchForGameWithLobby(ulong lobbyId, int playerMin, int playerMax)
+ {
+ return GetInstance()
+ .Call(Methods.SearchForGameWithLobby, lobbyId, playerMin, playerMax)
+ .AsInt32();
+ }
+
+ public static int SearchForGameSolo(int playerMin, int playerMax)
+ {
+ return GetInstance().Call(Methods.SearchForGameSolo, playerMin, playerMax).AsInt32();
+ }
+
+ public static int AcceptGame()
+ {
+ return GetInstance().Call(Methods.AcceptGame).AsInt32();
+ }
+
+ public static int DeclineGame()
+ {
+ return GetInstance().Call(Methods.DeclineGame).AsInt32();
+ }
+
+ public static string RetrieveConnectionDetails(ulong hostId)
+ {
+ return GetInstance().Call(Methods.RetrieveConnectionDetails, hostId).AsString();
+ }
+
+ public static int EndGameSearch()
+ {
+ return GetInstance().Call(Methods.EndGameSearch).AsInt32();
+ }
+
+ public static int SetGameHostParams(string key, string value)
+ {
+ return GetInstance().Call(Methods.SetGameHostParams, key, value).AsInt32();
+ }
+
+ public static int SetConnectionDetails(string details, int connectionDetails)
+ {
+ return GetInstance()
+ .Call(Methods.SetConnectionDetails, details, connectionDetails)
+ .AsInt32();
+ }
+
+ public static int RequestPlayersForGame(int playerMin, int playerMax, int maxTeamSize)
+ {
+ return GetInstance()
+ .Call(Methods.RequestPlayersForGame, playerMin, playerMax, maxTeamSize)
+ .AsInt32();
+ }
+
+ public static int HostConfirmGameStart(ulong gameId)
+ {
+ return GetInstance().Call(Methods.HostConfirmGameStart, gameId).AsInt32();
+ }
+
+ public static int CancelRequestPlayersForGame()
+ {
+ return GetInstance().Call(Methods.CancelRequestPlayersForGame).AsInt32();
+ }
+
+ public static PlayerResult SubmitPlayerResult(
+ ulong gameId,
+ ulong playerId,
+ PlayerResult playerResult
+ )
+ {
+ return (PlayerResult)
+ GetInstance()
+ .Call(Methods.SubmitPlayerResult, gameId, playerId, (int)playerResult)
+ .AsInt32();
+ }
+
+ public static int EndGame(ulong gameId)
+ {
+ return GetInstance().Call(Methods.EndGame, gameId).AsInt32();
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.GameSearch.cs.uid b/addons/godotsteam_csharpbindings/Steam.GameSearch.cs.uid
new file mode 100644
index 00000000..09a2ca37
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.GameSearch.cs.uid
@@ -0,0 +1 @@
+uid://dhuv7mhp0h6cg
diff --git a/addons/godotsteam_csharpbindings/Steam.Generated.Data.cs b/addons/godotsteam_csharpbindings/Steam.Generated.Data.cs
new file mode 100644
index 00000000..9df0c652
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Generated.Data.cs
@@ -0,0 +1,224 @@
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public const long ApiCallInvalid = 0;
+ public const long AppIdInvalid = 0;
+ public const long AuthTicketInvalid = 0;
+ public const long DepotIdInvalid = 0;
+ public const long GameExtraInfoMax = 64;
+ public const long InvalidBreakpadHandle = 0;
+ public const long SteamAccountIdMask = 4294967295;
+ public const long SteamAccountInstanceMask = 1048575;
+ public const long SteamBufferSize = 255;
+ public const long SteamLargeBufferSize = 8160;
+ public const long SteamMaxErrorMessage = 1024;
+ public const long SteamUserConsoleInstance = 2;
+ public const long SteamUserDesktopInstance = 1;
+ public const long SteamUserWebInstance = 4;
+ public const long QueryPortError = 65534;
+ public const long QueryPortNotInitialized = 65535;
+ public const long ChatMetadataMax = 8192;
+ public const long EnumeratedFollowersMax = 50;
+ public const long FriendsGroupLimit = 100;
+ public const long InvalidFriendGroupId = -1;
+ public const long MaxFriendsGroupName = 64;
+ public const long MaxRichPresenceKeyLength = 64;
+ public const long MaxRichPresenceKeys = 20;
+ public const long MaxRichPresenceValueLenth = 256;
+ public const long PersonaNameMaxUtf8 = 128;
+ public const long PersonaNameMaxUtf16 = 32;
+ public const long InvalidHtmlbrowser = 0;
+ public const long InvalidHttpcookieHandle = 0;
+ public const long InvalidHttprequestHandle = 0;
+ public const long InputMaxAnalogActions = 24;
+ public const long InputMaxAnalogActionData = 1;
+ public const long InputMaxCount = 16;
+ public const long InputMaxDigitalActions = 256;
+ public const long InputMaxOrigins = 8;
+ public const long InputMinAnalogActionData = -1;
+ public const long InventoryResultInvalid = -1;
+ public const long ItemInstanceIdInvalid = 0;
+ public const long ServerQueryInvalid = 4294967295;
+ public const long MaxLobbyKeyLength = 255;
+ public const long FavoriteFlagFavorite = 1;
+ public const long FavoriteFlagHistory = 2;
+ public const long FavoriteFlagNone = 0;
+ public const long MaxGameServerGameData = 2048;
+ public const long MaxGameServerGameDescription = 64;
+ public const long MaxGameServerGameDir = 32;
+ public const long MaxGameServerMapName = 32;
+ public const long MaxGameServerName = 64;
+ public const long MaxGameServerTags = 128;
+ public const long MusicNameMaxLength = 255;
+ public const long MusicPngMaxLength = 65535;
+ public const long NetworkingSendUnreliable = 0;
+ public const long NetworkingSendNoNagle = 1;
+ public const long NetworkingSendNoDelay = 4;
+ public const long NetworkingSendReliable = 8;
+ public const long DeviceFormFactorUnknown = 0;
+ public const long DeviceFormFactorPhone = 1;
+ public const long DeviceFormFactorTablet = 2;
+ public const long DeviceFormFactorComputer = 3;
+ public const long DeviceFormFactorTv = 4;
+ public const long FileNameMax = 1024;
+ public const long PublishedDocumentChangeDescriptionMax = 8000;
+ public const long PublishedDocumentDescriptionMax = 8000;
+ public const long PublishedDocumentTitleMax = 129;
+ public const long PublishedFileUrlMax = 256;
+ public const long TagListMax = 1025;
+ public const long PublishedFileIdInvalid = 0;
+ public const long PublishedFileUpdateHandleInvalid = 0;
+ public const long UgcFileStreamHandleInvalid = 0;
+ public const long UgcHandleInvalid = 0;
+ public const long EnumeratePublishedFilesMaxResults = 50;
+ public const long MaxCloudFileChunkSize = 104857600;
+ public const long InvalidScreenshotHandle = 0;
+ public const long UfsTagTypeMax = 255;
+ public const long UfsTagValueMax = 255;
+ public const long MaxTaggedPublishedFiles = 32;
+ public const long MaxTaggedUsers = 32;
+ public const long ScreenshotThumbWidth = 200;
+ public const long NumUgcResultsPerPage = 50;
+ public const long DeveloperMetadataMax = 5000;
+ public const long UgcQueryHandleInvalid = 0;
+ public const long UgcUpdateHandleInvalid = 0;
+ public const long LeaderboardDetailMax = 64;
+ public const long LeaderboardNameMax = 128;
+ public const long StatNameMax = 128;
+
+ public enum ControllerHapticLocation : long
+ {
+ Left = 1,
+ Right = 2,
+ Both = 3,
+ }
+
+ public enum ControllerHapticType : long
+ {
+ Off = 0,
+ Tick = 1,
+ Click = 2,
+ }
+
+ public enum ControllerPad : long
+ {
+ Left = 0,
+ Right = 1,
+ }
+
+ public enum DeviceFormFactor : long
+ {
+ Unknown = 0,
+ Phone = 1,
+ Tablet = 2,
+ Computer = 3,
+ Tv = 4,
+ }
+
+ public enum DurationControlOnlineState : long
+ {
+ Invalid = 0,
+ Offline = 1,
+ Online = 2,
+ OnlineHighPriority = 3,
+ }
+
+ public enum GameSearchErrorCode : long
+ {
+ Ok = 1,
+ SearchAreadyInProgress = 2,
+ NoSearchInProgress = 3,
+ NotLobbyLeader = 4,
+ NoHostAvailable = 5,
+ SearchParamsInvalid = 6,
+ Offline = 7,
+ NotAuthorized = 8,
+ UnknownError = 9,
+ }
+
+ public enum IPType : long
+ {
+ Ipv4 = 0,
+ Ipv6 = 1,
+ }
+
+ public enum IPv6ConnectivityProtocol : long
+ {
+ Invalid = 0,
+ Http = 1,
+ Udp = 2,
+ }
+
+ public enum IPv6ConnectivityState : long
+ {
+ Unknown = 0,
+ Good = 1,
+ Bad = 2,
+ }
+
+ public enum MarketNotAllowedReasonFlags : long
+ {
+ None = 0,
+ TemporaryFailure = 1,
+ AccountDisabled = 2,
+ AccountLockedDown = 4,
+ AccountLimited = 8,
+ TradeBanned = 16,
+ AccountNotTrusted = 32,
+ SteamGuardNotEnabled = 64,
+ SteamGaurdOnlyRecentlyEnabled = 128,
+ RecentPasswordReset = 256,
+ NewPaymentMethod = 512,
+ InvalidCookie = 1024,
+ UsingNewDevice = 2048,
+ RecentSelfRefund = 4096,
+ NewPaymentMethodCannotBeVerified = 8192,
+ NoRecentPurchases = 16384,
+ AcceptedWalletGift = 32768,
+ }
+
+ public enum ScePadTriggerEffectMode : long
+ {
+ Off = 0,
+ Feedback = 1,
+ Weapon = 2,
+ Vibration = 3,
+ MultiplePositionFeedback = 4,
+ SlopeFeedback = 5,
+ MultiplePositionVibration = 6,
+ }
+
+ public enum XboxOrigin : long
+ {
+ A = 0,
+ B = 1,
+ X = 2,
+ Y = 3,
+ LeftBumper = 4,
+ RightBumper = 5,
+ Menu = 6,
+ View = 7,
+ LeftTriggerPull = 8,
+ LeftTriggerClick = 9,
+ RightTriggerPull = 10,
+ RightTriggerClick = 11,
+ LeftStickMove = 12,
+ LeftStickClick = 13,
+ LeftStickDpadNorth = 14,
+ LeftStickDpadSouth = 15,
+ LeftStickDpadWest = 16,
+ LeftStickDpadEat = 17,
+ RightStickMove = 18,
+ RightStickClick = 19,
+ RightStickDpadNorth = 20,
+ RightStickDpadSouth = 21,
+ RightStickDpadWest = 22,
+ RightStickDpadEast = 23,
+ DpadNorth = 24,
+ DpadSouth = 25,
+ DpadWest = 26,
+ DpadEast = 27,
+ Count = 28,
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.Generated.Data.cs.uid b/addons/godotsteam_csharpbindings/Steam.Generated.Data.cs.uid
new file mode 100644
index 00000000..25594d9e
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Generated.Data.cs.uid
@@ -0,0 +1 @@
+uid://be35e1qokhyiq
diff --git a/addons/godotsteam_csharpbindings/Steam.HTMLSurface.Signals.cs b/addons/godotsteam_csharpbindings/Steam.HTMLSurface.Signals.cs
new file mode 100644
index 00000000..32f8b133
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.HTMLSurface.Signals.cs
@@ -0,0 +1,779 @@
+using System;
+using Godot;
+
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public delegate void HtmlBrowserReadyEventHandler(uint browserHandle);
+ private static event HtmlBrowserReadyEventHandler HtmlBrowserReadyEvent;
+ static Action _htmlBrowserReadyAction = (browserHandle) =>
+ {
+ HtmlBrowserReadyEvent?.Invoke(browserHandle);
+ };
+ public static event HtmlBrowserReadyEventHandler HtmlBrowserReady
+ {
+ add
+ {
+ if (HtmlBrowserReadyEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.HtmlBrowserReady, Callable.From(_htmlBrowserReadyAction));
+ }
+ HtmlBrowserReadyEvent += value;
+ }
+ remove
+ {
+ HtmlBrowserReadyEvent -= value;
+ if (HtmlBrowserReadyEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.HtmlBrowserReady, Callable.From(_htmlBrowserReadyAction));
+ }
+ }
+ }
+
+ public delegate void HtmlCanGoBackandforwardEventHandler(
+ uint browserHandle,
+ bool goBack,
+ bool goForward
+ );
+ private static event HtmlCanGoBackandforwardEventHandler HtmlCanGoBackandforwardEvent;
+ static Action _htmlCanGoBackandforwardAction = (
+ browserHandle,
+ goBack,
+ goForward
+ ) =>
+ {
+ HtmlCanGoBackandforwardEvent?.Invoke(browserHandle, goBack, goForward);
+ };
+ public static event HtmlCanGoBackandforwardEventHandler HtmlCanGoBackandforward
+ {
+ add
+ {
+ if (HtmlCanGoBackandforwardEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.HtmlCanGoBackandforward,
+ Callable.From(_htmlCanGoBackandforwardAction)
+ );
+ }
+ HtmlCanGoBackandforwardEvent += value;
+ }
+ remove
+ {
+ HtmlCanGoBackandforwardEvent -= value;
+ if (HtmlCanGoBackandforwardEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.HtmlCanGoBackandforward,
+ Callable.From(_htmlCanGoBackandforwardAction)
+ );
+ }
+ }
+ }
+
+ public delegate void HtmlChangedTitleEventHandler(uint browserHandle, string title);
+ private static event HtmlChangedTitleEventHandler HtmlChangedTitleEvent;
+ static Action _htmlChangedTitleAction = (browserHandle, title) =>
+ {
+ HtmlChangedTitleEvent?.Invoke(browserHandle, title);
+ };
+ public static event HtmlChangedTitleEventHandler HtmlChangedTitle
+ {
+ add
+ {
+ if (HtmlChangedTitleEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.HtmlChangedTitle, Callable.From(_htmlChangedTitleAction));
+ }
+ HtmlChangedTitleEvent += value;
+ }
+ remove
+ {
+ HtmlChangedTitleEvent -= value;
+ if (HtmlChangedTitleEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.HtmlChangedTitle, Callable.From(_htmlChangedTitleAction));
+ }
+ }
+ }
+
+ public delegate void HtmlCloseBrowserEventHandler(uint browserHandle);
+ private static event HtmlCloseBrowserEventHandler HtmlCloseBrowserEvent;
+ static Action _htmlCloseBrowserAction = (browserHandle) =>
+ {
+ HtmlCloseBrowserEvent?.Invoke(browserHandle);
+ };
+ public static event HtmlCloseBrowserEventHandler HtmlCloseBrowser
+ {
+ add
+ {
+ if (HtmlCloseBrowserEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.HtmlCloseBrowser, Callable.From(_htmlCloseBrowserAction));
+ }
+ HtmlCloseBrowserEvent += value;
+ }
+ remove
+ {
+ HtmlCloseBrowserEvent -= value;
+ if (HtmlCloseBrowserEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.HtmlCloseBrowser, Callable.From(_htmlCloseBrowserAction));
+ }
+ }
+ }
+
+ public delegate void HtmlFileOpenDialogEventHandler(
+ uint browserHandle,
+ string title,
+ string initialFile
+ );
+ private static event HtmlFileOpenDialogEventHandler HtmlFileOpenDialogEvent;
+ static Action _htmlFileOpenDialogAction = (
+ browserHandle,
+ title,
+ initialFile
+ ) =>
+ {
+ HtmlFileOpenDialogEvent?.Invoke(browserHandle, title, initialFile);
+ };
+ public static event HtmlFileOpenDialogEventHandler HtmlFileOpenDialog
+ {
+ add
+ {
+ if (HtmlFileOpenDialogEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.HtmlFileOpenDialog, Callable.From(_htmlFileOpenDialogAction));
+ }
+ HtmlFileOpenDialogEvent += value;
+ }
+ remove
+ {
+ HtmlFileOpenDialogEvent -= value;
+ if (HtmlFileOpenDialogEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.HtmlFileOpenDialog,
+ Callable.From(_htmlFileOpenDialogAction)
+ );
+ }
+ }
+ }
+
+ public delegate void HtmlFinishedRequestEventHandler(
+ uint browserHandle,
+ string url,
+ string title
+ );
+ private static event HtmlFinishedRequestEventHandler HtmlFinishedRequestEvent;
+ static Action _htmlFinishedRequestAction = (browserHandle, url, title) =>
+ {
+ HtmlFinishedRequestEvent?.Invoke(browserHandle, url, title);
+ };
+ public static event HtmlFinishedRequestEventHandler HtmlFinishedRequest
+ {
+ add
+ {
+ if (HtmlFinishedRequestEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.HtmlFinishedRequest,
+ Callable.From(_htmlFinishedRequestAction)
+ );
+ }
+ HtmlFinishedRequestEvent += value;
+ }
+ remove
+ {
+ HtmlFinishedRequestEvent -= value;
+ if (HtmlFinishedRequestEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.HtmlFinishedRequest,
+ Callable.From(_htmlFinishedRequestAction)
+ );
+ }
+ }
+ }
+
+ public delegate void HtmlHideTooltipEventHandler(uint browserHandle);
+ private static event HtmlHideTooltipEventHandler HtmlHideTooltipEvent;
+ static Action _htmlHideTooltipAction = (browserHandle) =>
+ {
+ HtmlHideTooltipEvent?.Invoke(browserHandle);
+ };
+ public static event HtmlHideTooltipEventHandler HtmlHideTooltip
+ {
+ add
+ {
+ if (HtmlHideTooltipEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.HtmlHideTooltip, Callable.From(_htmlHideTooltipAction));
+ }
+ HtmlHideTooltipEvent += value;
+ }
+ remove
+ {
+ HtmlHideTooltipEvent -= value;
+ if (HtmlHideTooltipEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.HtmlHideTooltip, Callable.From(_htmlHideTooltipAction));
+ }
+ }
+ }
+
+ public delegate void HtmlHorizontalScrollEventHandler(
+ uint browserHandle,
+ HtmlScrollData scrollData
+ );
+ private static event HtmlHorizontalScrollEventHandler HtmlHorizontalScrollEvent;
+ static Action _htmlHorizontalScrollAction = (
+ browserHandle,
+ scrollData
+ ) =>
+ {
+ HtmlHorizontalScrollEvent?.Invoke(
+ browserHandle,
+ new HtmlScrollData
+ {
+ ScrollMax = scrollData["scroll_max"].AsUInt32(),
+ ScrollCurrent = scrollData["scroll_current"].AsUInt32(),
+ PageScale = scrollData["page_scale"].AsSingle(),
+ Visible = scrollData["visible"].AsBool(),
+ PageSize = scrollData["page_size"].AsUInt32(),
+ }
+ );
+ };
+ public static event HtmlHorizontalScrollEventHandler HtmlHorizontalScroll
+ {
+ add
+ {
+ if (HtmlHorizontalScrollEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.HtmlHorizontalScroll,
+ Callable.From(_htmlHorizontalScrollAction)
+ );
+ }
+ HtmlHorizontalScrollEvent += value;
+ }
+ remove
+ {
+ HtmlHorizontalScrollEvent -= value;
+ if (HtmlHorizontalScrollEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.HtmlHorizontalScroll,
+ Callable.From(_htmlHorizontalScrollAction)
+ );
+ }
+ }
+ }
+
+ public delegate void HtmlJsAlertEventHandler(uint browserHandle, string message);
+ private static event HtmlJsAlertEventHandler HtmlJsAlertEvent;
+ static Action _htmlJsAlertAction = (browserHandle, message) =>
+ {
+ HtmlJsAlertEvent?.Invoke(browserHandle, message);
+ };
+ public static event HtmlJsAlertEventHandler HtmlJsAlert
+ {
+ add
+ {
+ if (HtmlJsAlertEvent == null)
+ {
+ GetInstance().Connect(Signals.HtmlJsAlert, Callable.From(_htmlJsAlertAction));
+ }
+ HtmlJsAlertEvent += value;
+ }
+ remove
+ {
+ HtmlJsAlertEvent -= value;
+ if (HtmlJsAlertEvent == null)
+ {
+ GetInstance().Disconnect(Signals.HtmlJsAlert, Callable.From(_htmlJsAlertAction));
+ }
+ }
+ }
+
+ public delegate void HtmlJsConfirmEventHandler(uint browserHandle, string message);
+ private static event HtmlJsConfirmEventHandler HtmlJsConfirmEvent;
+ static Action _htmlJsConfirmAction = (browserHandle, message) =>
+ {
+ HtmlJsConfirmEvent?.Invoke(browserHandle, message);
+ };
+ public static event HtmlJsConfirmEventHandler HtmlJsConfirm
+ {
+ add
+ {
+ if (HtmlJsConfirmEvent == null)
+ {
+ GetInstance().Connect(Signals.HtmlJsConfirm, Callable.From(_htmlJsConfirmAction));
+ }
+ HtmlJsConfirmEvent += value;
+ }
+ remove
+ {
+ HtmlJsConfirmEvent -= value;
+ if (HtmlJsConfirmEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.HtmlJsConfirm, Callable.From(_htmlJsConfirmAction));
+ }
+ }
+ }
+
+ public delegate void HtmlLinkAtPositionEventHandler(uint browserHandle, HtmlLinkData linkData);
+ private static event HtmlLinkAtPositionEventHandler HtmlLinkAtPositionEvent;
+ static Action _htmlLinkAtPositionAction = (
+ browserHandle,
+ linkData
+ ) =>
+ {
+ HtmlLinkAtPositionEvent?.Invoke(
+ browserHandle,
+ new HtmlLinkData
+ {
+ X = linkData["x"].AsUInt32(),
+ Y = linkData["y"].AsUInt32(),
+ Url = new Uri(linkData["url"].AsString()),
+ Input = linkData["input"].AsBool(),
+ LiveLink = linkData["live_link"].AsBool(),
+ }
+ );
+ };
+ public static event HtmlLinkAtPositionEventHandler HtmlLinkAtPosition
+ {
+ add
+ {
+ if (HtmlLinkAtPositionEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.HtmlLinkAtPosition, Callable.From(_htmlLinkAtPositionAction));
+ }
+ HtmlLinkAtPositionEvent += value;
+ }
+ remove
+ {
+ HtmlLinkAtPositionEvent -= value;
+ if (HtmlLinkAtPositionEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.HtmlLinkAtPosition,
+ Callable.From(_htmlLinkAtPositionAction)
+ );
+ }
+ }
+ }
+
+ public delegate void HtmlNeedsPaintEventHandler(uint browserHandle, HtmlPageData pageData);
+ private static event HtmlNeedsPaintEventHandler HtmlNeedsPaintEvent;
+ static Action _htmlNeedsPaintAction = (
+ browserHandle,
+ pageData
+ ) =>
+ {
+ HtmlNeedsPaintEvent?.Invoke(
+ browserHandle,
+ new HtmlPageData
+ {
+ Bgra = pageData["bgra"].AsString(),
+ Wide = pageData["wide"].AsUInt32(),
+ Tall = pageData["tall"].AsUInt32(),
+ UpdateX = pageData["update_x"].AsUInt32(),
+ UpdateY = pageData["update_y"].AsUInt32(),
+ UpdateWide = pageData["update_wide"].AsUInt32(),
+ UpdateTall = pageData["update_tall"].AsUInt32(),
+ ScrollX = pageData["scroll_x"].AsUInt32(),
+ ScrollY = pageData["scroll_y"].AsUInt32(),
+ PageScale = pageData["page_scale"].AsSingle(),
+ PageSerial = pageData["page_serial"].AsUInt32(),
+ }
+ );
+ };
+ public static event HtmlNeedsPaintEventHandler HtmlNeedsPaint
+ {
+ add
+ {
+ if (HtmlNeedsPaintEvent == null)
+ {
+ GetInstance().Connect(Signals.HtmlNeedsPaint, Callable.From(_htmlNeedsPaintAction));
+ }
+ HtmlNeedsPaintEvent += value;
+ }
+ remove
+ {
+ HtmlNeedsPaintEvent -= value;
+ if (HtmlNeedsPaintEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.HtmlNeedsPaint, Callable.From(_htmlNeedsPaintAction));
+ }
+ }
+ }
+
+ public delegate void HtmlNewWindowEventHandler(uint browserHandle, HtmlWindowData windowData);
+ private static event HtmlNewWindowEventHandler HtmlNewWindowEvent;
+ static Action _htmlNewWindowAction = (
+ browserHandle,
+ windowData
+ ) =>
+ {
+ HtmlNewWindowEvent?.Invoke(
+ browserHandle,
+ new HtmlWindowData
+ {
+ Url = new Uri(windowData["url"].AsString()),
+ X = windowData["x"].AsUInt32(),
+ Y = windowData["y"].AsUInt32(),
+ Wide = windowData["wide"].AsUInt32(),
+ Tall = windowData["tall"].AsUInt32(),
+ NewHandle = windowData["new_handle"].AsUInt32(),
+ }
+ );
+ };
+ public static event HtmlNewWindowEventHandler HtmlNewWindow
+ {
+ add
+ {
+ if (HtmlNewWindowEvent == null)
+ {
+ GetInstance().Connect(Signals.HtmlNewWindow, Callable.From(_htmlNewWindowAction));
+ }
+ HtmlNewWindowEvent += value;
+ }
+ remove
+ {
+ HtmlNewWindowEvent -= value;
+ if (HtmlNewWindowEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.HtmlNewWindow, Callable.From(_htmlNewWindowAction));
+ }
+ }
+ }
+
+ public delegate void HtmlOpenLinkInNewTabEventHandler(uint browserHandle, string url);
+ private static event HtmlOpenLinkInNewTabEventHandler HtmlOpenLinkInNewTabEvent;
+ static Action _htmlOpenLinkInNewTabAction = (browserHandle, url) =>
+ {
+ HtmlOpenLinkInNewTabEvent?.Invoke(browserHandle, url);
+ };
+ public static event HtmlOpenLinkInNewTabEventHandler HtmlOpenLinkInNewTab
+ {
+ add
+ {
+ if (HtmlOpenLinkInNewTabEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.HtmlOpenLinkInNewTab,
+ Callable.From(_htmlOpenLinkInNewTabAction)
+ );
+ }
+ HtmlOpenLinkInNewTabEvent += value;
+ }
+ remove
+ {
+ HtmlOpenLinkInNewTabEvent -= value;
+ if (HtmlOpenLinkInNewTabEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.HtmlOpenLinkInNewTab,
+ Callable.From(_htmlOpenLinkInNewTabAction)
+ );
+ }
+ }
+ }
+
+ public delegate void HtmlSearchResultsEventHandler(
+ uint browserHandle,
+ uint results,
+ uint currentMatch
+ );
+ private static event HtmlSearchResultsEventHandler HtmlSearchResultsEvent;
+ static Action _htmlSearchResultsAction = (
+ browserHandle,
+ results,
+ currentMatch
+ ) =>
+ {
+ HtmlSearchResultsEvent?.Invoke(browserHandle, results, currentMatch);
+ };
+ public static event HtmlSearchResultsEventHandler HtmlSearchResults
+ {
+ add
+ {
+ if (HtmlSearchResultsEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.HtmlSearchResults, Callable.From(_htmlSearchResultsAction));
+ }
+ HtmlSearchResultsEvent += value;
+ }
+ remove
+ {
+ HtmlSearchResultsEvent -= value;
+ if (HtmlSearchResultsEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.HtmlSearchResults, Callable.From(_htmlSearchResultsAction));
+ }
+ }
+ }
+
+ public delegate void HtmlSetCursorEventHandler(uint browserHandle, HtmlMouseCursor mouseCursor);
+ private static event HtmlSetCursorEventHandler HtmlSetCursorEvent;
+ static Action _htmlSetCursorAction = (browserHandle, mouseCursor) =>
+ {
+ HtmlSetCursorEvent?.Invoke(browserHandle, (HtmlMouseCursor)mouseCursor);
+ };
+ public static event HtmlSetCursorEventHandler HtmlSetCursor
+ {
+ add
+ {
+ if (HtmlSetCursorEvent == null)
+ {
+ GetInstance().Connect(Signals.HtmlSetCursor, Callable.From(_htmlSetCursorAction));
+ }
+ HtmlSetCursorEvent += value;
+ }
+ remove
+ {
+ HtmlSetCursorEvent -= value;
+ if (HtmlSetCursorEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.HtmlSetCursor, Callable.From(_htmlSetCursorAction));
+ }
+ }
+ }
+
+ public delegate void HtmlShowTooltipEventHandler(uint browserHandle, string message);
+ private static event HtmlShowTooltipEventHandler HtmlShowTooltipEvent;
+ static Action _htmlShowTooltipAction = (browserHandle, message) =>
+ {
+ HtmlShowTooltipEvent?.Invoke(browserHandle, message);
+ };
+ public static event HtmlShowTooltipEventHandler HtmlShowTooltip
+ {
+ add
+ {
+ if (HtmlShowTooltipEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.HtmlShowTooltip, Callable.From(_htmlShowTooltipAction));
+ }
+ HtmlShowTooltipEvent += value;
+ }
+ remove
+ {
+ HtmlShowTooltipEvent -= value;
+ if (HtmlShowTooltipEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.HtmlShowTooltip, Callable.From(_htmlShowTooltipAction));
+ }
+ }
+ }
+
+ public delegate void HtmlStartRequestEventHandler(
+ uint browserHandle,
+ string url,
+ string target,
+ string postData,
+ bool redirect
+ );
+ private static event HtmlStartRequestEventHandler HtmlStartRequestEvent;
+ static Action _htmlStartRequestAction = (
+ browserHandle,
+ url,
+ target,
+ postData,
+ redirect
+ ) =>
+ {
+ HtmlStartRequestEvent?.Invoke(browserHandle, url, target, postData, redirect);
+ };
+ public static event HtmlStartRequestEventHandler HtmlStartRequest
+ {
+ add
+ {
+ if (HtmlStartRequestEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.HtmlStartRequest, Callable.From(_htmlStartRequestAction));
+ }
+ HtmlStartRequestEvent += value;
+ }
+ remove
+ {
+ HtmlStartRequestEvent -= value;
+ if (HtmlStartRequestEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.HtmlStartRequest, Callable.From(_htmlStartRequestAction));
+ }
+ }
+ }
+
+ public delegate void HtmlStatusTextEventHandler(uint browserHandle, string message);
+ private static event HtmlStatusTextEventHandler HtmlStatusTextEvent;
+ static Action _htmlStatusTextAction = (browserHandle, message) =>
+ {
+ HtmlStatusTextEvent?.Invoke(browserHandle, message);
+ };
+ public static event HtmlStatusTextEventHandler HtmlStatusText
+ {
+ add
+ {
+ if (HtmlStatusTextEvent == null)
+ {
+ GetInstance().Connect(Signals.HtmlStatusText, Callable.From(_htmlStatusTextAction));
+ }
+ HtmlStatusTextEvent += value;
+ }
+ remove
+ {
+ HtmlStatusTextEvent -= value;
+ if (HtmlStatusTextEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.HtmlStatusText, Callable.From(_htmlStatusTextAction));
+ }
+ }
+ }
+
+ public delegate void HtmlUpdateTooltipEventHandler(uint browserHandle, string message);
+ private static event HtmlUpdateTooltipEventHandler HtmlUpdateTooltipEvent;
+ static Action _htmlUpdateTooltipAction = (browserHandle, message) =>
+ {
+ HtmlUpdateTooltipEvent?.Invoke(browserHandle, message);
+ };
+ public static event HtmlUpdateTooltipEventHandler HtmlUpdateTooltip
+ {
+ add
+ {
+ if (HtmlUpdateTooltipEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.HtmlUpdateTooltip, Callable.From(_htmlUpdateTooltipAction));
+ }
+ HtmlUpdateTooltipEvent += value;
+ }
+ remove
+ {
+ HtmlUpdateTooltipEvent -= value;
+ if (HtmlUpdateTooltipEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.HtmlUpdateTooltip, Callable.From(_htmlUpdateTooltipAction));
+ }
+ }
+ }
+
+ public delegate void HtmlUrlChangedEventHandler(uint browserHandle, HtmlUrlData urlData);
+ private static event HtmlUrlChangedEventHandler HtmlUrlChangedEvent;
+ static Action _htmlUrlChangedAction = (
+ browserHandle,
+ urlData
+ ) =>
+ {
+ HtmlUrlChangedEvent?.Invoke(
+ browserHandle,
+ new HtmlUrlData
+ {
+ Url = new Uri(urlData["url"].AsString()),
+ PostData = urlData["post_data"].AsString(),
+ Redirect = urlData["redirect"].AsBool(),
+ Title = urlData["title"].AsString(),
+ NewNavigation = urlData["new_navigation"].AsBool(),
+ }
+ );
+ };
+ public static event HtmlUrlChangedEventHandler HtmlUrlChanged
+ {
+ add
+ {
+ if (HtmlUrlChangedEvent == null)
+ {
+ GetInstance().Connect(Signals.HtmlUrlChanged, Callable.From(_htmlUrlChangedAction));
+ }
+ HtmlUrlChangedEvent += value;
+ }
+ remove
+ {
+ HtmlUrlChangedEvent -= value;
+ if (HtmlUrlChangedEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.HtmlUrlChanged, Callable.From(_htmlUrlChangedAction));
+ }
+ }
+ }
+
+ public delegate void HtmlVerticalScrollEventHandler(
+ uint browserHandle,
+ HtmlScrollData scrollData
+ );
+ private static event HtmlVerticalScrollEventHandler HtmlVerticalScrollEvent;
+ static Action _htmlVerticalScrollAction = (
+ browserHandle,
+ scrollData
+ ) =>
+ {
+ HtmlVerticalScrollEvent?.Invoke(
+ browserHandle,
+ new HtmlScrollData
+ {
+ ScrollMax = scrollData["scroll_max"].AsUInt32(),
+ ScrollCurrent = scrollData["scroll_current"].AsUInt32(),
+ PageScale = scrollData["page_scale"].AsSingle(),
+ Visible = scrollData["visible"].AsBool(),
+ PageSize = scrollData["page_size"].AsUInt32(),
+ }
+ );
+ };
+ public static event HtmlVerticalScrollEventHandler HtmlVerticalScroll
+ {
+ add
+ {
+ if (HtmlVerticalScrollEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.HtmlVerticalScroll, Callable.From(_htmlVerticalScrollAction));
+ }
+ HtmlVerticalScrollEvent += value;
+ }
+ remove
+ {
+ HtmlVerticalScrollEvent -= value;
+ if (HtmlVerticalScrollEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.HtmlVerticalScroll,
+ Callable.From(_htmlVerticalScrollAction)
+ );
+ }
+ }
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.HTMLSurface.Signals.cs.uid b/addons/godotsteam_csharpbindings/Steam.HTMLSurface.Signals.cs.uid
new file mode 100644
index 00000000..b679dcde
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.HTMLSurface.Signals.cs.uid
@@ -0,0 +1 @@
+uid://cbi5wjopd18ea
diff --git a/addons/godotsteam_csharpbindings/Steam.HTMLSurface.cs b/addons/godotsteam_csharpbindings/Steam.HTMLSurface.cs
new file mode 100644
index 00000000..1ebe1ab4
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.HTMLSurface.cs
@@ -0,0 +1,187 @@
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public static void AddHeader(string key, string value, uint thisHandle = 0)
+ {
+ GetInstance().Call(Methods.AddHeader, key, value, thisHandle);
+ }
+
+ public static void AllowStartRequest(bool allowed, uint thisHandle = 0)
+ {
+ GetInstance().Call(Methods.AllowStartRequest, allowed, thisHandle);
+ }
+
+ public static void CopyToClipboard(uint thisHandle = 0)
+ {
+ GetInstance().Call(Methods.CopyToClipboard, thisHandle);
+ }
+
+ public static void CreateBrowser(string userAgent = "", string userCss = "")
+ {
+ GetInstance().Call(Methods.CreateBrowser, userAgent, userCss);
+ }
+
+ public static void ExecuteJavascript(string script, uint thisHandle = 0)
+ {
+ GetInstance().Call(Methods.ExecuteJavascript, script, thisHandle);
+ }
+
+ public static void Find(string search, bool currentlyInFind, bool reverse, uint thisHandle = 0)
+ {
+ GetInstance().Call(Methods.Find, search, currentlyInFind, reverse, thisHandle);
+ }
+
+ public static void GetLinkAtPosition(int x, int y, uint thisHandle = 0)
+ {
+ GetInstance().Call(Methods.GetLinkAtPosition, x, y, thisHandle);
+ }
+
+ public static void GoBack(uint thisHandle = 0)
+ {
+ GetInstance().Call(Methods.GoBack, thisHandle);
+ }
+
+ public static void GoForward(uint thisHandle = 0)
+ {
+ GetInstance().Call(Methods.GoForward, thisHandle);
+ }
+
+ public static void HtmlInit()
+ {
+ GetInstance().Call(Methods.HtmlInit);
+ }
+
+ public static void JsDialogResponse(bool result, uint thisHandle = 0)
+ {
+ GetInstance().Call(Methods.JsDialogResponse, result, thisHandle);
+ }
+
+ public static void KeyChar(uint unicodeChar, HtmlKeyModifiers keyModifiers, uint thisHandle = 0)
+ {
+ GetInstance().Call(Methods.KeyChar, unicodeChar, (int)keyModifiers, thisHandle);
+ }
+
+ public static void KeyDown(
+ uint nativeKeyCode,
+ HtmlKeyModifiers keyModifiers,
+ uint thisHandle = 0
+ )
+ {
+ GetInstance().Call(Methods.KeyDown, nativeKeyCode, (int)keyModifiers, thisHandle);
+ }
+
+ public static void KeyUp(uint nativeKeyCode, HtmlKeyModifiers keyModifiers, uint thisHandle = 0)
+ {
+ GetInstance().Call(Methods.KeyUp, nativeKeyCode, (int)keyModifiers, thisHandle);
+ }
+
+ public static void LoadURL(string url, string postData, uint thisHandle = 0)
+ {
+ GetInstance().Call(Methods.LoadURL, url, postData, thisHandle);
+ }
+
+ public static void MouseDoubleClick(HtmlMouseButton mouseButton, uint thisHandle = 0)
+ {
+ GetInstance().Call(Methods.MouseDoubleClick, (int)mouseButton, thisHandle);
+ }
+
+ public static void MouseDown(HtmlMouseButton mouseButton, uint thisHandle = 0)
+ {
+ GetInstance().Call(Methods.MouseDown, (int)mouseButton, thisHandle);
+ }
+
+ public static void MouseMove(int x, int y, uint thisHandle = 0)
+ {
+ GetInstance().Call(Methods.MouseMove, x, y, thisHandle);
+ }
+
+ public static void MouseUp(HtmlMouseButton mouseButton, uint thisHandle = 0)
+ {
+ GetInstance().Call(Methods.MouseUp, (int)mouseButton, thisHandle);
+ }
+
+ public static void MouseWheel(int delta, uint thisHandle = 0)
+ {
+ GetInstance().Call(Methods.MouseWheel, delta, thisHandle);
+ }
+
+ public static void PasteFromClipboard(uint thisHandle = 0)
+ {
+ GetInstance().Call(Methods.PasteFromClipboard, thisHandle);
+ }
+
+ public static void Reload(uint thisHandle = 0)
+ {
+ GetInstance().Call(Methods.Reload, thisHandle);
+ }
+
+ public static void RemoveBrowser(uint thisHandle = 0)
+ {
+ GetInstance().Call(Methods.RemoveBrowser, thisHandle);
+ }
+
+ public static void SetBackgroundMode(bool backgroundMode, uint thisHandle = 0)
+ {
+ GetInstance().Call(Methods.SetBackgroundMode, backgroundMode, thisHandle);
+ }
+
+ public static void SetCookie(
+ string hostname,
+ string key,
+ string value,
+ string path,
+ uint expires,
+ bool secure,
+ bool httpOnly
+ )
+ {
+ GetInstance()
+ .Call(Methods.SetCookie, hostname, key, value, path, expires, secure, httpOnly);
+ }
+
+ public static void SetHorizontalScroll(uint absolutePixelScroll, uint thisHandle = 0)
+ {
+ GetInstance().Call(Methods.SetHorizontalScroll, absolutePixelScroll, thisHandle);
+ }
+
+ public static void SetKeyFocus(bool hasKeyFocus, uint thisHandle = 0)
+ {
+ GetInstance().Call(Methods.SetKeyFocus, hasKeyFocus, thisHandle);
+ }
+
+ public static void SetPageScaleFactor(float zoom, int pointX, int pointY, uint thisHandle = 0)
+ {
+ GetInstance().Call(Methods.SetPageScaleFactor, zoom, pointX, pointY, thisHandle);
+ }
+
+ public static void SetSize(uint width, uint height, uint thisHandle = 0)
+ {
+ GetInstance().Call(Methods.SetSize, width, height, thisHandle);
+ }
+
+ public static void SetVerticalScroll(uint absolutePixelScroll, uint thisHandle = 0)
+ {
+ GetInstance().Call(Methods.SetVerticalScroll, absolutePixelScroll, thisHandle);
+ }
+
+ public static bool HtmlShutdown()
+ {
+ return GetInstance().Call(Methods.HtmlShutdown).AsBool();
+ }
+
+ public static void StopFind(uint thisHandle = 0)
+ {
+ GetInstance().Call(Methods.StopFind, thisHandle);
+ }
+
+ public static void StopLoad(uint thisHandle = 0)
+ {
+ GetInstance().Call(Methods.StopLoad, thisHandle);
+ }
+
+ public static void ViewSource(uint thisHandle = 0)
+ {
+ GetInstance().Call(Methods.ViewSource, thisHandle);
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.HTMLSurface.cs.uid b/addons/godotsteam_csharpbindings/Steam.HTMLSurface.cs.uid
new file mode 100644
index 00000000..cb4a435a
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.HTMLSurface.cs.uid
@@ -0,0 +1 @@
+uid://3nir88lvbc4c
diff --git a/addons/godotsteam_csharpbindings/Steam.HTTP.Signals.cs b/addons/godotsteam_csharpbindings/Steam.HTTP.Signals.cs
new file mode 100644
index 00000000..1665db4a
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.HTTP.Signals.cs
@@ -0,0 +1,140 @@
+using System;
+using Godot;
+
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public delegate void HttpRequestCompletedEventHandler(
+ long cookieHandle,
+ long contextValue,
+ bool requestSuccess,
+ long statusCode,
+ long bodySize
+ );
+ private static event HttpRequestCompletedEventHandler HttpRequestCompletedEvent;
+ static Action _httpRequestCompletedAction = (
+ cookieHandle,
+ contextValue,
+ requestSuccess,
+ statusCode,
+ bodySize
+ ) =>
+ {
+ HttpRequestCompletedEvent?.Invoke(
+ cookieHandle,
+ contextValue,
+ requestSuccess,
+ statusCode,
+ bodySize
+ );
+ };
+ public static event HttpRequestCompletedEventHandler HttpRequestCompleted
+ {
+ add
+ {
+ if (HttpRequestCompletedEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.HttpRequestCompleted,
+ Callable.From(_httpRequestCompletedAction)
+ );
+ }
+ HttpRequestCompletedEvent += value;
+ }
+ remove
+ {
+ HttpRequestCompletedEvent -= value;
+ if (HttpRequestCompletedEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.HttpRequestCompleted,
+ Callable.From(_httpRequestCompletedAction)
+ );
+ }
+ }
+ }
+
+ public delegate void HttpRequestDataReceivedEventHandler(
+ long cookieHandle,
+ long contextValue,
+ long offset,
+ long bytesReceived
+ );
+ private static event HttpRequestDataReceivedEventHandler HttpRequestDataReceivedEvent;
+ static Action _httpRequestDataReceivedAction = (
+ cookieHandle,
+ contextValue,
+ offset,
+ bytesReceived
+ ) =>
+ {
+ HttpRequestDataReceivedEvent?.Invoke(cookieHandle, contextValue, offset, bytesReceived);
+ };
+ public static event HttpRequestDataReceivedEventHandler HttpRequestDataReceived
+ {
+ add
+ {
+ if (HttpRequestDataReceivedEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.HttpRequestDataReceived,
+ Callable.From(_httpRequestDataReceivedAction)
+ );
+ }
+ HttpRequestDataReceivedEvent += value;
+ }
+ remove
+ {
+ HttpRequestDataReceivedEvent -= value;
+ if (HttpRequestDataReceivedEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.HttpRequestDataReceived,
+ Callable.From(_httpRequestDataReceivedAction)
+ );
+ }
+ }
+ }
+
+ public delegate void HttpRequestHeadersReceivedEventHandler(
+ long cookieHandle,
+ long contextValue
+ );
+ private static event HttpRequestHeadersReceivedEventHandler HttpRequestHeadersReceivedEvent;
+ static Action _httpRequestHeadersReceivedAction = (cookieHandle, contextValue) =>
+ {
+ HttpRequestHeadersReceivedEvent?.Invoke(cookieHandle, contextValue);
+ };
+ public static event HttpRequestHeadersReceivedEventHandler HttpRequestHeadersReceived
+ {
+ add
+ {
+ if (HttpRequestHeadersReceivedEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.HttpRequestHeadersReceived,
+ Callable.From(_httpRequestHeadersReceivedAction)
+ );
+ }
+ HttpRequestHeadersReceivedEvent += value;
+ }
+ remove
+ {
+ HttpRequestHeadersReceivedEvent -= value;
+ if (HttpRequestHeadersReceivedEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.HttpRequestHeadersReceived,
+ Callable.From(_httpRequestHeadersReceivedAction)
+ );
+ }
+ }
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.HTTP.Signals.cs.uid b/addons/godotsteam_csharpbindings/Steam.HTTP.Signals.cs.uid
new file mode 100644
index 00000000..3857b1bf
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.HTTP.Signals.cs.uid
@@ -0,0 +1 @@
+uid://dp6y0hvvt3qg
diff --git a/addons/godotsteam_csharpbindings/Steam.HTTP.cs b/addons/godotsteam_csharpbindings/Steam.HTTP.cs
new file mode 100644
index 00000000..036a690a
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.HTTP.cs
@@ -0,0 +1,246 @@
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public static uint CreateCookieContainer(bool allowResponseToModify)
+ {
+ return GetInstance().Call(Methods.CreateCookieContainer, allowResponseToModify).AsUInt32();
+ }
+
+ public static uint CreateHTTPRequest(HttpMethod requestMethod, string absoluteUrl)
+ {
+ return GetInstance()
+ .Call(Methods.CreateHTTPRequest, (long)requestMethod, absoluteUrl)
+ .AsUInt32();
+ }
+
+ public static bool DeferHTTPRequest(long requestHandle)
+ {
+ return GetInstance().Call(Methods.DeferHTTPRequest, requestHandle).AsBool();
+ }
+
+ public static float GetHTTPDownloadProgressPct(long requestHandle)
+ {
+ return GetInstance().Call(Methods.GetHTTPDownloadProgressPct, requestHandle).AsSingle();
+ }
+
+ public static bool GetHTTPRequestWasTimedOut(long requestHandle)
+ {
+ return GetInstance().Call(Methods.GetHTTPRequestWasTimedOut, requestHandle).AsBool();
+ }
+
+ public static byte[] GetHTTPResponseBodyData(uint requestHandle, long bufferSize)
+ {
+ return GetInstance()
+ .Call(Methods.GetHTTPResponseBodyData, requestHandle, bufferSize)
+ .AsByteArray();
+ }
+
+ public static uint GetHTTPResponseBodySize(long requestHandle)
+ {
+ return GetInstance().Call(Methods.GetHTTPResponseBodySize, requestHandle).AsUInt32();
+ }
+
+ public static uint GetHTTPResponseHeaderSize(uint requestHandle, string headerName)
+ {
+ return GetInstance()
+ .Call(Methods.GetHTTPResponseHeaderSize, requestHandle, headerName)
+ .AsUInt32();
+ }
+
+ public static byte GetHTTPResponseHeaderValue(
+ uint requestHandle,
+ string headerName,
+ long bufferSize
+ )
+ {
+ return GetInstance()
+ .Call(Methods.GetHTTPResponseHeaderValue, requestHandle, headerName, bufferSize)
+ .AsByte();
+ }
+
+ public static byte GetHTTPStreamingResponseBodyData(
+ uint requestHandle,
+ uint offset,
+ long bufferSize
+ )
+ {
+ return GetInstance()
+ .Call(Methods.GetHTTPStreamingResponseBodyData, requestHandle, offset, bufferSize)
+ .AsByte();
+ }
+
+ public static bool PrioritizeHTTPRequest(long requestHandle)
+ {
+ return GetInstance().Call(Methods.PrioritizeHTTPRequest, requestHandle).AsBool();
+ }
+
+ public static bool ReleaseCookieContainer(long cookieHandle)
+ {
+ return GetInstance().Call(Methods.ReleaseCookieContainer, cookieHandle).AsBool();
+ }
+
+ public static bool ReleaseHTTPRequest(long requestHandle)
+ {
+ return GetInstance().Call(Methods.ReleaseHTTPRequest, requestHandle).AsBool();
+ }
+
+ public static bool SendHTTPRequest(long requestHandle)
+ {
+ return GetInstance().Call(Methods.SendHTTPRequest, requestHandle).AsBool();
+ }
+
+ public static bool SendHTTPRequestAndStreamResponse(long requestHandle)
+ {
+ return GetInstance().Call(Methods.SendHTTPRequestAndStreamResponse, requestHandle).AsBool();
+ }
+
+ public static bool SetHTTPCookie(uint cookieHandle, string host, string url, string cookie)
+ {
+ return GetInstance().Call(Methods.SetHTTPCookie, cookieHandle, host, url, cookie).AsBool();
+ }
+
+ public static bool SetHTTPRequestAbsoluteTimeoutMS(uint requestHandle, long milliseconds)
+ {
+ return GetInstance()
+ .Call(Methods.SetHTTPRequestAbsoluteTimeoutMS, requestHandle, milliseconds)
+ .AsBool();
+ }
+
+ public static bool SetHTTPRequestContextValue(uint requestHandle, long contextValue)
+ {
+ return GetInstance()
+ .Call(Methods.SetHTTPRequestContextValue, requestHandle, contextValue)
+ .AsBool();
+ }
+
+ public static bool SetHTTPRequestCookieContainer(uint requestHandle, long cookieHandle)
+ {
+ return GetInstance()
+ .Call(Methods.SetHTTPRequestCookieContainer, requestHandle, cookieHandle)
+ .AsBool();
+ }
+
+ public static bool SetHTTPRequestGetOrPostParameter(
+ uint requestHandle,
+ string name,
+ string value
+ )
+ {
+ return GetInstance()
+ .Call(Methods.SetHTTPRequestGetOrPostParameter, requestHandle, name, value)
+ .AsBool();
+ }
+
+ public static bool SetHTTPRequestHeaderValue(
+ uint requestHandle,
+ string headerName,
+ string headerValue
+ )
+ {
+ return GetInstance()
+ .Call(Methods.SetHTTPRequestHeaderValue, requestHandle, headerName, headerValue)
+ .AsBool();
+ }
+
+ public static bool SetHTTPRequestNetworkActivityTimeout(uint requestHandle, long timeoutSeconds)
+ {
+ return GetInstance()
+ .Call(Methods.SetHTTPRequestNetworkActivityTimeout, requestHandle, timeoutSeconds)
+ .AsBool();
+ }
+
+ public static byte SetHTTPRequestRawPostBody(
+ uint requestHandle,
+ string contentType,
+ long bodyLength
+ )
+ {
+ return GetInstance()
+ .Call(Methods.SetHTTPRequestRawPostBody, requestHandle, contentType, bodyLength)
+ .AsByte();
+ }
+
+ public static bool SetHTTPRequestRequiresVerifiedCertificate(
+ uint requestHandle,
+ bool requireVerifiedCertificate
+ )
+ {
+ return GetInstance()
+ .Call(
+ Methods.SetHTTPRequestRequiresVerifiedCertificate,
+ requestHandle,
+ requireVerifiedCertificate
+ )
+ .AsBool();
+ }
+
+ public static bool SetHTTPRequestUserAgentInfo(uint requestHandle, string userAgentInfo)
+ {
+ return GetInstance()
+ .Call(Methods.SetHTTPRequestUserAgentInfo, requestHandle, userAgentInfo)
+ .AsBool();
+ }
+
+ public enum HttpMethod : long
+ {
+ Invalid = 0,
+ Get = 1,
+ Head = 2,
+ Post = 3,
+ Put = 4,
+ Delete = 5,
+ Options = 6,
+ Patch = 7,
+ }
+
+ public enum HttpStatusCode : long
+ {
+ Invalid = 0,
+ Code100Continue = 100,
+ Code101SwitchingProtocols = 101,
+ Code200Ok = 200,
+ Code201Created = 201,
+ Code202Accepted = 202,
+ Code203NonAuthoritative = 203,
+ Code204NoContent = 204,
+ Code205ResetContent = 205,
+ Code206PartialContent = 206,
+ Code300MultipleChoices = 300,
+ Code301MovedPermanently = 301,
+ Code302Found = 302,
+ Code303SeeOther = 303,
+ Code304NotModified = 304,
+ Code305UseProxy = 305,
+ Code307TemporaryRedirect = 307,
+ Code308PermanentRedirect = 308,
+ Code400BadRequest = 400,
+ Code401Unauthorized = 401,
+ Code402PaymentRequired = 402,
+ Code403Forbidden = 403,
+ Code404NotFound = 404,
+ Code405MethodNotAllowed = 405,
+ Code406NotAcceptable = 406,
+ Code407ProxyAuthRequired = 407,
+ Code408RequestTimeout = 408,
+ Code409Conflict = 409,
+ Code410Gone = 410,
+ Code411LengthRequired = 411,
+ Code412PreconditionFailed = 412,
+ Code413RequestEntityTooLarge = 413,
+ Code414RequestUriTooLong = 414,
+ Code415UnsupportedMediaType = 415,
+ Code416RequestedRangeNotSatisfiable = 416,
+ Code417ExpectationFailed = 417,
+ Code4XxUnknown = 418,
+ Code429TooManyRequests = 429,
+ Code444ConnectionClosed = 444,
+ Code500InternalServerError = 500,
+ Code501NotImplemented = 501,
+ Code502BadGateway = 502,
+ Code503ServiceUnavailable = 503,
+ Code504GatewayTimeout = 504,
+ Code505HttpVersionNotSupported = 505,
+ Code5XxUnknown = 599,
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.HTTP.cs.uid b/addons/godotsteam_csharpbindings/Steam.HTTP.cs.uid
new file mode 100644
index 00000000..6ee8e2fe
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.HTTP.cs.uid
@@ -0,0 +1 @@
+uid://7cur6lchwvky
diff --git a/addons/godotsteam_csharpbindings/Steam.Input.Signals.cs b/addons/godotsteam_csharpbindings/Steam.Input.Signals.cs
new file mode 100644
index 00000000..cf3db128
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Input.Signals.cs
@@ -0,0 +1,195 @@
+using System;
+using Godot;
+
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ private static event Action InputActionEventDelegate;
+ static Action _inputActionAction = () =>
+ {
+ InputActionEventDelegate?.Invoke();
+ };
+ public static event Action InputActionEvent
+ {
+ add
+ {
+ if (InputActionEventDelegate == null)
+ {
+ GetInstance().Connect(Signals.InputActionEvent, Callable.From(_inputActionAction));
+ }
+ InputActionEventDelegate += value;
+ }
+ remove
+ {
+ InputActionEventDelegate -= value;
+ if (InputActionEventDelegate == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.InputActionEvent, Callable.From(_inputActionAction));
+ }
+ }
+ }
+
+ public delegate void InputDeviceConnectedEventHandler(long inputHandle);
+ private static event InputDeviceConnectedEventHandler InputDeviceConnectedEvent;
+ static Action _inputDeviceConnectedAction = (inputHandle) =>
+ {
+ InputDeviceConnectedEvent?.Invoke(inputHandle);
+ };
+ public static event InputDeviceConnectedEventHandler InputDeviceConnected
+ {
+ add
+ {
+ if (InputDeviceConnectedEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.InputDeviceConnected,
+ Callable.From(_inputDeviceConnectedAction)
+ );
+ }
+ InputDeviceConnectedEvent += value;
+ }
+ remove
+ {
+ InputDeviceConnectedEvent -= value;
+ if (InputDeviceConnectedEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.InputDeviceConnected,
+ Callable.From(_inputDeviceConnectedAction)
+ );
+ }
+ }
+ }
+
+ public delegate void InputDeviceDisconnectedEventHandler(long inputHandle);
+ private static event InputDeviceDisconnectedEventHandler InputDeviceDisconnectedEvent;
+ static Action _inputDeviceDisconnectedAction = (inputHandle) =>
+ {
+ InputDeviceDisconnectedEvent?.Invoke(inputHandle);
+ };
+ public static event InputDeviceDisconnectedEventHandler InputDeviceDisconnected
+ {
+ add
+ {
+ if (InputDeviceDisconnectedEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.InputDeviceDisconnected,
+ Callable.From(_inputDeviceDisconnectedAction)
+ );
+ }
+ InputDeviceDisconnectedEvent += value;
+ }
+ remove
+ {
+ InputDeviceDisconnectedEvent -= value;
+ if (InputDeviceDisconnectedEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.InputDeviceDisconnected,
+ Callable.From(_inputDeviceDisconnectedAction)
+ );
+ }
+ }
+ }
+
+ public delegate void InputConfigurationLoadedEventHandler(
+ uint appId,
+ long deviceHandle,
+ Godot.Collections.Dictionary configData
+ );
+ private static event InputConfigurationLoadedEventHandler InputConfigurationLoadedEvent;
+ static Action _inputConfigurationLoadedAction = (
+ appId,
+ deviceHandle,
+ configData
+ ) =>
+ {
+ InputConfigurationLoadedEvent?.Invoke(appId, deviceHandle, configData);
+ };
+ public static event InputConfigurationLoadedEventHandler InputConfigurationLoaded
+ {
+ add
+ {
+ if (InputConfigurationLoadedEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.InputConfigurationLoaded,
+ Callable.From(_inputConfigurationLoadedAction)
+ );
+ }
+ InputConfigurationLoadedEvent += value;
+ }
+ remove
+ {
+ InputConfigurationLoadedEvent -= value;
+ if (InputConfigurationLoadedEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.InputConfigurationLoaded,
+ Callable.From(_inputConfigurationLoadedAction)
+ );
+ }
+ }
+ }
+
+ public delegate void InputGamepadSlotChangeEventHandler(
+ uint appId,
+ long deviceHandle,
+ long deviceType,
+ long oldGamepadSlot,
+ long newGamepadSlot
+ );
+ private static event InputGamepadSlotChangeEventHandler InputGamepadSlotChangeEvent;
+ static Action _inputGamepadSlotChangeAction = (
+ appId,
+ deviceHandle,
+ deviceType,
+ oldGamepadSlot,
+ newGamepadSlot
+ ) =>
+ {
+ InputGamepadSlotChangeEvent?.Invoke(
+ appId,
+ deviceHandle,
+ deviceType,
+ oldGamepadSlot,
+ newGamepadSlot
+ );
+ };
+ public static event InputGamepadSlotChangeEventHandler InputGamepadSlotChange
+ {
+ add
+ {
+ if (InputGamepadSlotChangeEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.InputGamepadSlotChange,
+ Callable.From(_inputGamepadSlotChangeAction)
+ );
+ }
+ InputGamepadSlotChangeEvent += value;
+ }
+ remove
+ {
+ InputGamepadSlotChangeEvent -= value;
+ if (InputGamepadSlotChangeEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.InputGamepadSlotChange,
+ Callable.From(_inputGamepadSlotChangeAction)
+ );
+ }
+ }
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.Input.Signals.cs.uid b/addons/godotsteam_csharpbindings/Steam.Input.Signals.cs.uid
new file mode 100644
index 00000000..e2e99443
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Input.Signals.cs.uid
@@ -0,0 +1 @@
+uid://dxpge2ru7ddhv
diff --git a/addons/godotsteam_csharpbindings/Steam.Input.cs b/addons/godotsteam_csharpbindings/Steam.Input.cs
new file mode 100644
index 00000000..85d6daa4
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Input.cs
@@ -0,0 +1,846 @@
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public static void ActivateActionSet(ulong inputHandle, long actionSetHandle)
+ {
+ GetInstance().Call(Methods.ActivateActionSet, inputHandle, actionSetHandle);
+ }
+
+ public static void ActivateActionSetLayer(ulong inputHandle, long actionSetLayerHandle)
+ {
+ GetInstance().Call(Methods.ActivateActionSetLayer, inputHandle, actionSetLayerHandle);
+ }
+
+ public static void DeactivateActionSetLayer(ulong inputHandle, long actionSetHandle)
+ {
+ GetInstance().Call(Methods.DeactivateActionSetLayer, inputHandle, actionSetHandle);
+ }
+
+ public static void DeactivateAllActionSetLayers(long inputHandle)
+ {
+ GetInstance().Call(Methods.DeactivateAllActionSetLayers, inputHandle);
+ }
+
+ public static ulong GetActionSetHandle(string actionSetName)
+ {
+ return GetInstance().Call(Methods.GetActionSetHandle, actionSetName).AsUInt64();
+ }
+
+ public static InputActionOrigin GetActionOriginFromXboxOrigin(ulong inputHandle, long origin)
+ {
+ return (InputActionOrigin)
+ GetInstance()
+ .Call(Methods.GetActionOriginFromXboxOrigin, inputHandle, origin)
+ .AsInt64();
+ }
+
+ public static Godot.Collections.Array GetActiveActionSetLayers(long inputHandle)
+ {
+ return GetInstance().Call(Methods.GetActiveActionSetLayers, inputHandle).AsGodotArray();
+ }
+
+ public static Godot.Collections.Dictionary GetAnalogActionData(
+ ulong inputHandle,
+ long analogActionHandle
+ )
+ {
+ return GetInstance()
+ .Call(Methods.GetAnalogActionData, inputHandle, analogActionHandle)
+ .AsGodotDictionary();
+ }
+
+ public static ulong GetAnalogActionHandle(string actionName)
+ {
+ return GetInstance().Call(Methods.GetAnalogActionHandle, actionName).AsUInt16();
+ }
+
+ public static Godot.Collections.Array GetAnalogActionOrigins(
+ ulong inputHandle,
+ ulong actionSetHandle,
+ long analogActionHandle
+ )
+ {
+ return GetInstance()
+ .Call(Methods.GetAnalogActionOrigins, inputHandle, actionSetHandle, analogActionHandle)
+ .AsGodotArray();
+ }
+
+ public static Godot.Collections.Array GetConnectedControllers()
+ {
+ return GetInstance().Call(Methods.GetConnectedControllers).AsGodotArray();
+ }
+
+ public static ulong GetControllerForGamepadIndex(long index)
+ {
+ return GetInstance().Call(Methods.GetControllerForGamepadIndex, index).AsUInt16();
+ }
+
+ public static ulong GetCurrentActionSet(long inputHandle)
+ {
+ return GetInstance().Call(Methods.GetCurrentActionSet, inputHandle).AsUInt16();
+ }
+
+ public static Godot.Collections.Array GetDeviceBindingRevision(long inputHandle)
+ {
+ return GetInstance().Call(Methods.GetDeviceBindingRevision, inputHandle).AsGodotArray();
+ }
+
+ public static Godot.Collections.Dictionary GetDigitalActionData(
+ ulong inputHandle,
+ long digitalActionHandle
+ )
+ {
+ return GetInstance()
+ .Call(Methods.GetDigitalActionData, inputHandle, digitalActionHandle)
+ .AsGodotDictionary();
+ }
+
+ public static ulong GetDigitalActionHandle(string actionName)
+ {
+ return GetInstance().Call(Methods.GetDigitalActionHandle, actionName).AsUInt64();
+ }
+
+ public static Godot.Collections.Array GetDigitalActionOrigins(
+ ulong inputHandle,
+ ulong actionSetHandle,
+ long digitalActionHandle
+ )
+ {
+ return GetInstance()
+ .Call(
+ Methods.GetDigitalActionOrigins,
+ inputHandle,
+ actionSetHandle,
+ digitalActionHandle
+ )
+ .AsGodotArray();
+ }
+
+ public static int GetGamepadIndexForController(long inputHandle)
+ {
+ return GetInstance().Call(Methods.GetGamepadIndexForController, inputHandle).AsInt32();
+ }
+
+ public static string GetGlyphForActionOrigin(InputActionOrigin origin)
+ {
+ return GetInstance().Call(Methods.GetGlyphForActionOrigin, (long)origin).AsString();
+ }
+
+ public static string GetInputTypeForHandle(long inputHandle)
+ {
+ return GetInstance().Call(Methods.GetInputTypeForHandle, inputHandle).AsString();
+ }
+
+ public static Godot.Collections.Dictionary GetMotionData(long inputHandle)
+ {
+ return GetInstance().Call(Methods.GetMotionData, inputHandle).AsGodotDictionary();
+ }
+
+ public static int GetRemotePlaySessionID(long inputHandle)
+ {
+ return GetInstance().Call(Methods.GetRemotePlaySessionID, inputHandle).AsInt32();
+ }
+
+ public static string GetStringForActionOrigin(InputActionOrigin origin)
+ {
+ return GetInstance().Call(Methods.GetStringForActionOrigin, (long)origin).AsString();
+ }
+
+ public static bool InputInit(bool explicitlyCallRunframe = false)
+ {
+ return GetInstance().Call(Methods.InputInit, explicitlyCallRunframe).AsBool();
+ }
+
+ public static bool InputShutdown()
+ {
+ return GetInstance().Call(Methods.InputShutdown).AsBool();
+ }
+
+ public static void RunFrame(bool reservedValue = true)
+ {
+ GetInstance().Call(Methods.RunFrame, reservedValue);
+ }
+
+ public static void SetLEDColor(
+ ulong inputHandle,
+ int colorR,
+ int colorG,
+ int colorB,
+ long flags
+ )
+ {
+ GetInstance().Call(Methods.SetLEDColor, inputHandle, colorR, colorG, colorB, flags);
+ }
+
+ public static bool ShowBindingPanel(long inputHandle)
+ {
+ return GetInstance().Call(Methods.ShowBindingPanel, inputHandle).AsBool();
+ }
+
+ public static void StopAnalogActionMomentum(ulong inputHandle, long action)
+ {
+ GetInstance().Call(Methods.StopAnalogActionMomentum, inputHandle, action);
+ }
+
+ public static int TranslateActionOrigin(
+ InputType destinationInput,
+ InputActionOrigin sourceOrigin
+ )
+ {
+ return GetInstance()
+ .Call(Methods.TranslateActionOrigin, (long)destinationInput, (long)sourceOrigin)
+ .AsInt32();
+ }
+
+ public static void TriggerHapticPulse(ulong inputHandle, int targetPad, long duration)
+ {
+ GetInstance().Call(Methods.TriggerHapticPulse, inputHandle, targetPad, duration);
+ }
+
+ public static void TriggerRepeatedHapticPulse(
+ ulong inputHandle,
+ int targetPad,
+ int duration,
+ int offset,
+ int repeat,
+ long flags
+ )
+ {
+ GetInstance()
+ .Call(
+ Methods.TriggerRepeatedHapticPulse,
+ inputHandle,
+ targetPad,
+ duration,
+ offset,
+ repeat,
+ flags
+ );
+ }
+
+ public static void TriggerVibration(ulong inputHandle, int leftSpeed, long rightSpeed)
+ {
+ GetInstance().Call(Methods.TriggerVibration, inputHandle, leftSpeed, rightSpeed);
+ }
+
+ public static bool SetInputActionManifestFilePath(string manifestPath)
+ {
+ return GetInstance().Call(Methods.SetInputActionManifestFilePath, manifestPath).AsBool();
+ }
+
+ public static void SetDualSenseTriggerEffect(
+ ulong inputHandle,
+ int parameters,
+ int triggerMask,
+ ScePadTriggerEffectMode effectMode,
+ int position,
+ int amplitude,
+ long frequency
+ )
+ {
+ GetInstance()
+ .Call(
+ Methods.SetDualSenseTriggerEffect,
+ inputHandle,
+ parameters,
+ triggerMask,
+ (long)effectMode,
+ position,
+ amplitude,
+ frequency
+ );
+ }
+
+ public static bool WaitForData(bool waitForever, long timeout)
+ {
+ return GetInstance().Call(Methods.WaitForData, waitForever, timeout).AsBool();
+ }
+
+ public static bool NewDataAvailable()
+ {
+ return GetInstance().Call(Methods.NewDataAvailable).AsBool();
+ }
+
+ public static void EnableDeviceCallbacks()
+ {
+ GetInstance().Call(Methods.EnableDeviceCallbacks);
+ }
+
+ public static string GetGlyphPNGForActionOrigin(
+ InputActionOrigin origin,
+ InputGlyphSize size,
+ long flags
+ )
+ {
+ return GetInstance()
+ .Call(Methods.GetGlyphPNGForActionOrigin, (long)origin, (long)size, flags)
+ .AsString();
+ }
+
+ public static string GetGlyphSVGForActionOrigin(InputActionOrigin origin, long flags)
+ {
+ return GetInstance()
+ .Call(Methods.GetGlyphSVGForActionOrigin, (long)origin, flags)
+ .AsString();
+ }
+
+ public static void TriggerVibrationExtended(
+ ulong inputHandle,
+ int leftSpeed,
+ int rightSpeed,
+ int leftTriggerSpeed,
+ long rightTriggerSpeed
+ )
+ {
+ GetInstance()
+ .Call(
+ Methods.TriggerVibrationExtended,
+ inputHandle,
+ leftSpeed,
+ rightSpeed,
+ leftTriggerSpeed,
+ rightTriggerSpeed
+ );
+ }
+
+ public static void TriggerSimpleHapticEvent(
+ ulong inputHandle,
+ int hapticLocation,
+ int intensity,
+ string gainDb,
+ int otherIntensity,
+ string otherGainDb
+ )
+ {
+ GetInstance()
+ .Call(
+ Methods.TriggerSimpleHapticEvent,
+ inputHandle,
+ hapticLocation,
+ intensity,
+ gainDb,
+ otherIntensity,
+ otherGainDb
+ );
+ }
+
+ public static string GetStringForXboxOrigin(long origin)
+ {
+ return GetInstance().Call(Methods.GetStringForXboxOrigin, origin).AsString();
+ }
+
+ public static string GetGlyphForXboxOrigin(long origin)
+ {
+ return GetInstance().Call(Methods.GetGlyphForXboxOrigin, origin).AsString();
+ }
+
+ public static long GetSessionInputConfigurationSettings()
+ {
+ return GetInstance().Call(Methods.GetSessionInputConfigurationSettings).AsInt64();
+ }
+
+ public static string GetStringForDigitalActionName(long actionHandle)
+ {
+ return GetInstance().Call(Methods.GetStringForDigitalActionName, actionHandle).AsString();
+ }
+
+ public static string GetStringForAnalogActionName(long actionHandle)
+ {
+ return GetInstance().Call(Methods.GetStringForAnalogActionName, actionHandle).AsString();
+ }
+
+ public enum InputActionEventType : long
+ {
+ DigitalAction = 0,
+ AnalogAction = 1,
+ }
+
+ public enum InputActionOrigin : long
+ {
+ None = 0,
+ SteamcontrollerA = 1,
+ SteamcontrollerB = 2,
+ SteamcontrollerX = 3,
+ SteamcontrollerY = 4,
+ SteamcontrollerLeftbumper = 5,
+ SteamcontrollerRightbumper = 6,
+ SteamcontrollerLeftgrip = 7,
+ SteamcontrollerRightgrip = 8,
+ SteamcontrollerStart = 9,
+ SteamcontrollerBack = 10,
+ SteamcontrollerLeftpadTouch = 11,
+ SteamcontrollerLeftpadSwipe = 12,
+ SteamcontrollerLeftpadClick = 13,
+ SteamcontrollerLeftpadDpadnorth = 14,
+ SteamcontrollerLeftpadDpadsouth = 15,
+ SteamcontrollerLeftpadDpadwest = 16,
+ SteamcontrollerLeftpadDpadeast = 17,
+ SteamcontrollerRightpadTouch = 18,
+ SteamcontrollerRightpadSwipe = 19,
+ SteamcontrollerRightpadClick = 20,
+ SteamcontrollerRightpadDpadnorth = 21,
+ SteamcontrollerRightpadDpadsouth = 22,
+ SteamcontrollerRightpadDpadwest = 23,
+ SteamcontrollerRightpadDpadeast = 24,
+ SteamcontrollerLefttriggerPull = 25,
+ SteamcontrollerLefttriggerClick = 26,
+ SteamcontrollerRighttriggerPull = 27,
+ SteamcontrollerRighttriggerClick = 28,
+ SteamcontrollerLeftstickMove = 29,
+ SteamcontrollerLeftstickClick = 30,
+ SteamcontrollerLeftstickDpadnorth = 31,
+ SteamcontrollerLeftstickDpadsouth = 32,
+ SteamcontrollerLeftstickDpadwest = 33,
+ SteamcontrollerLeftstickDpadeast = 34,
+ SteamcontrollerGyroMove = 35,
+ SteamcontrollerGyroPitch = 36,
+ SteamcontrollerGyroYaw = 37,
+ SteamcontrollerGyroRoll = 38,
+ SteamcontrollerReserved0 = 39,
+ SteamcontrollerReserved1 = 40,
+ SteamcontrollerReserved2 = 41,
+ SteamcontrollerReserved3 = 42,
+ SteamcontrollerReserved4 = 43,
+ SteamcontrollerReserved5 = 44,
+ SteamcontrollerReserved6 = 45,
+ SteamcontrollerReserved7 = 46,
+ SteamcontrollerReserved8 = 47,
+ SteamcontrollerReserved9 = 48,
+ SteamcontrollerReserved10 = 49,
+ Ps4X = 50,
+ Ps4Circle = 51,
+ Ps4Triangle = 52,
+ Ps4Square = 53,
+ Ps4Leftbumper = 54,
+ Ps4Rightbumper = 55,
+ Ps4Options = 56,
+ Ps4Share = 57,
+ Ps4LeftpadTouch = 58,
+ Ps4LeftpadSwipe = 59,
+ Ps4LeftpadClick = 60,
+ Ps4LeftpadDpadnorth = 61,
+ Ps4LeftpadDpadsouth = 62,
+ Ps4LeftpadDpadwest = 63,
+ Ps4LeftpadDpadeast = 64,
+ Ps4RightpadTouch = 65,
+ Ps4RightpadSwipe = 66,
+ Ps4RightpadClick = 67,
+ Ps4RightpadDpadnorth = 68,
+ Ps4RightpadDpadsouth = 69,
+ Ps4RightpadDpadwest = 70,
+ Ps4RightpadDpadeast = 71,
+ Ps4CenterpadTouch = 72,
+ Ps4CenterpadSwipe = 73,
+ Ps4CenterpadClick = 74,
+ Ps4CenterpadDpadnorth = 75,
+ Ps4CenterpadDpadsouth = 76,
+ Ps4CenterpadDpadwest = 77,
+ Ps4CenterpadDpadeast = 78,
+ Ps4LefttriggerPull = 79,
+ Ps4LefttriggerClick = 80,
+ Ps4RighttriggerPull = 81,
+ Ps4RighttriggerClick = 82,
+ Ps4LeftstickMove = 83,
+ Ps4LeftstickClick = 84,
+ Ps4LeftstickDpadnorth = 85,
+ Ps4LeftstickDpadsouth = 86,
+ Ps4LeftstickDpadwest = 87,
+ Ps4LeftstickDpadeast = 88,
+ Ps4RightstickMove = 89,
+ Ps4RightstickClick = 90,
+ Ps4RightstickDpadnorth = 91,
+ Ps4RightstickDpadsouth = 92,
+ Ps4RightstickDpadwest = 93,
+ Ps4RightstickDpadeast = 94,
+ Ps4DpadNorth = 95,
+ Ps4DpadSouth = 96,
+ Ps4DpadWest = 97,
+ Ps4DpadEast = 98,
+ Ps4GyroMove = 99,
+ Ps4GyroPitch = 100,
+ Ps4GyroYaw = 101,
+ Ps4GyroRoll = 102,
+ Ps4DpadMove = 103,
+ Ps4Reserved1 = 104,
+ Ps4Reserved2 = 105,
+ Ps4Reserved3 = 106,
+ Ps4Reserved4 = 107,
+ Ps4Reserved5 = 108,
+ Ps4Reserved6 = 109,
+ Ps4Reserved7 = 110,
+ Ps4Reserved8 = 111,
+ Ps4Reserved9 = 112,
+ Ps4Reserved10 = 113,
+ XboxoneA = 114,
+ XboxoneB = 115,
+ XboxoneX = 116,
+ XboxoneY = 117,
+ XboxoneLeftbumper = 118,
+ XboxoneRightbumper = 119,
+ XboxoneMenu = 120,
+ XboxoneView = 121,
+ XboxoneLefttriggerPull = 122,
+ XboxoneLefttriggerClick = 123,
+ XboxoneRighttriggerPull = 124,
+ XboxoneRighttriggerClick = 125,
+ XboxoneLeftstickMove = 126,
+ XboxoneLeftstickClick = 127,
+ XboxoneLeftstickDpadnorth = 128,
+ XboxoneLeftstickDpadsouth = 129,
+ XboxoneLeftstickDpadwest = 130,
+ XboxoneLeftstickDpadeast = 131,
+ XboxoneRightstickMove = 132,
+ XboxoneRightstickClick = 133,
+ XboxoneRightstickDpadnorth = 134,
+ XboxoneRightstickDpadsouth = 135,
+ XboxoneRightstickDpadwest = 136,
+ XboxoneRightstickDpadeast = 137,
+ XboxoneDpadNorth = 138,
+ XboxoneDpadSouth = 139,
+ XboxoneDpadWest = 140,
+ XboxoneDpadEast = 141,
+ XboxoneDpadMove = 142,
+ XboxoneLeftgripLower = 143,
+ XboxoneLeftgripUpper = 144,
+ XboxoneRightgripLower = 145,
+ XboxoneRightgripUpper = 146,
+ XboxoneShare = 147,
+ XboxoneReserved6 = 148,
+ XboxoneReserved7 = 149,
+ XboxoneReserved8 = 150,
+ XboxoneReserved9 = 151,
+ XboxoneReserved10 = 152,
+ Xbox360A = 153,
+ Xbox360B = 154,
+ Xbox360X = 155,
+ Xbox360Y = 156,
+ Xbox360Leftbumper = 157,
+ Xbox360Rightbumper = 158,
+ Xbox360Start = 159,
+ Xbox360Back = 160,
+ Xbox360LefttriggerPull = 161,
+ Xbox360LefttriggerClick = 162,
+ Xbox360RighttriggerPull = 163,
+ Xbox360RighttriggerClick = 164,
+ Xbox360LeftstickMove = 165,
+ Xbox360LeftstickClick = 166,
+ Xbox360LeftstickDpadnorth = 167,
+ Xbox360LeftstickDpadsouth = 168,
+ Xbox360LeftstickDpadwest = 169,
+ Xbox360LeftstickDpadeast = 170,
+ Xbox360RightstickMove = 171,
+ Xbox360RightstickClick = 172,
+ Xbox360RightstickDpadnorth = 173,
+ Xbox360RightstickDpadsouth = 174,
+ Xbox360RightstickDpadwest = 175,
+ Xbox360RightstickDpadeast = 176,
+ Xbox360DpadNorth = 177,
+ Xbox360DpadSouth = 178,
+ Xbox360DpadWest = 179,
+ Xbox360DpadEast = 180,
+ Xbox360DpadMove = 181,
+ Xbox360Reserved1 = 182,
+ Xbox360Reserved2 = 183,
+ Xbox360Reserved3 = 184,
+ Xbox360Reserved4 = 185,
+ Xbox360Reserved5 = 186,
+ Xbox360Reserved6 = 187,
+ Xbox360Reserved7 = 188,
+ Xbox360Reserved8 = 189,
+ Xbox360Reserved9 = 190,
+ Xbox360Reserved10 = 191,
+ SwitchA = 192,
+ SwitchB = 193,
+ SwitchX = 194,
+ SwitchY = 195,
+ SwitchLeftbumper = 196,
+ SwitchRightbumper = 197,
+ SwitchPlus = 198,
+ SwitchMinus = 199,
+ SwitchCapture = 200,
+ SwitchLefttriggerPull = 201,
+ SwitchLefttriggerClick = 202,
+ SwitchRighttriggerPull = 203,
+ SwitchRighttriggerClick = 204,
+ SwitchLeftstickMove = 205,
+ SwitchLeftstickClick = 206,
+ SwitchLeftstickDpadnorth = 207,
+ SwitchLeftstickDpadsouth = 208,
+ SwitchLeftstickDpadwest = 209,
+ SwitchLeftstickDpadeast = 210,
+ SwitchRightstickMove = 211,
+ SwitchRightstickClick = 212,
+ SwitchRightstickDpadnorth = 213,
+ SwitchRightstickDpadsouth = 214,
+ SwitchRightstickDpadwest = 215,
+ SwitchRightstickDpadeast = 216,
+ SwitchDpadNorth = 217,
+ SwitchDpadSouth = 218,
+ SwitchDpadWest = 219,
+ SwitchDpadEast = 220,
+ SwitchProgyroMove = 221,
+ SwitchProgyroPitch = 222,
+ SwitchProgyroYaw = 223,
+ SwitchProgyroRoll = 224,
+ SwitchDpadMove = 225,
+ SwitchReserved1 = 226,
+ SwitchReserved2 = 227,
+ SwitchReserved3 = 228,
+ SwitchReserved4 = 229,
+ SwitchReserved5 = 230,
+ SwitchReserved6 = 231,
+ SwitchReserved7 = 232,
+ SwitchReserved8 = 233,
+ SwitchReserved9 = 234,
+ SwitchReserved10 = 235,
+ SwitchRightgyroMove = 236,
+ SwitchRightgyroPitch = 237,
+ SwitchRightgyroYaw = 238,
+ SwitchRightgyroRoll = 239,
+ SwitchLeftgyroMove = 240,
+ SwitchLeftgyroPitch = 241,
+ SwitchLeftgyroYaw = 242,
+ SwitchLeftgyroRoll = 243,
+ SwitchLeftgripLower = 244,
+ SwitchLeftgripUpper = 245,
+ SwitchRightgripLower = 246,
+ SwitchRightgripUpper = 247,
+ SwitchJoyconButtonN = 248,
+ SwitchJoyconButtonE = 249,
+ SwitchJoyconButtonS = 250,
+ SwitchJoyconButtonW = 251,
+ SwitchReserved15 = 252,
+ SwitchReserved16 = 253,
+ SwitchReserved17 = 254,
+ SwitchReserved18 = 255,
+ SwitchReserved19 = 256,
+ SwitchReserved20 = 257,
+ Ps5X = 258,
+ Ps5Circle = 259,
+ Ps5Triangle = 260,
+ Ps5Square = 261,
+ Ps5Leftbumper = 262,
+ Ps5Rightbumper = 263,
+ Ps5Option = 264,
+ Ps5Create = 265,
+ Ps5Mute = 266,
+ Ps5LeftpadTouch = 267,
+ Ps5LeftpadSwipe = 268,
+ Ps5LeftpadClick = 269,
+ Ps5LeftpadDpadnorth = 270,
+ Ps5LeftpadDpadsouth = 271,
+ Ps5LeftpadDpadwest = 272,
+ Ps5LeftpadDpadeast = 273,
+ Ps5RightpadTouch = 274,
+ Ps5RightpadSwipe = 275,
+ Ps5RightpadClick = 276,
+ Ps5RightpadDpadnorth = 277,
+ Ps5RightpadDpadsouth = 278,
+ Ps5RightpadDpadwest = 279,
+ Ps5RightpadDpadeast = 280,
+ Ps5CenterpadTouch = 281,
+ Ps5CenterpadSwipe = 282,
+ Ps5CenterpadClick = 283,
+ Ps5CenterpadDpadnorth = 284,
+ Ps5CenterpadDpadsouth = 285,
+ Ps5CenterpadDpadwest = 286,
+ Ps5CenterpadDpadeast = 287,
+ Ps5LefttriggerPull = 288,
+ Ps5LefttriggerClick = 289,
+ Ps5RighttriggerPull = 290,
+ Ps5RighttriggerClick = 291,
+ Ps5LeftstickMove = 292,
+ Ps5LeftstickClick = 293,
+ Ps5LeftstickDpadnorth = 294,
+ Ps5LeftstickDpadsouth = 295,
+ Ps5LeftstickDpadwest = 296,
+ Ps5LeftstickDpadeast = 297,
+ Ps5RightstickMove = 298,
+ Ps5RightstickClick = 299,
+ Ps5RightstickDpadnorth = 300,
+ Ps5RightstickDpadsouth = 301,
+ Ps5RightstickDpadwest = 302,
+ Ps5RightstickDpadeast = 303,
+ Ps5DpadNorth = 304,
+ Ps5DpadSouth = 305,
+ Ps5DpadWest = 306,
+ Ps5DpadEast = 307,
+ Ps5GyroMove = 308,
+ Ps5GyroPitch = 309,
+ Ps5GyroYaw = 310,
+ Ps5GyroRoll = 311,
+ Ps5DpadMove = 312,
+ Ps5Leftgrip = 313,
+ Ps5Rightgrip = 314,
+ Ps5Leftfn = 315,
+ Ps5Rightfn = 316,
+ Ps5Reserved5 = 317,
+ Ps5Reserved6 = 318,
+ Ps5Reserved7 = 319,
+ Ps5Reserved8 = 320,
+ Ps5Reserved9 = 321,
+ Ps5Reserved10 = 322,
+ Ps5Reserved11 = 323,
+ Ps5Reserved12 = 324,
+ Ps5Reserved13 = 325,
+ Ps5Reserved14 = 326,
+ Ps5Reserved15 = 327,
+ Ps5Reserved16 = 328,
+ Ps5Reserved17 = 329,
+ Ps5Reserved18 = 330,
+ Ps5Reserved19 = 331,
+ Ps5Reserved20 = 332,
+ SteamdeckA = 333,
+ SteamdeckB = 334,
+ SteamdeckX = 335,
+ SteamdeckY = 336,
+ SteamdeckL1 = 337,
+ SteamdeckR1 = 338,
+ SteamdeckMenu = 339,
+ SteamdeckView = 340,
+ SteamdeckLeftpadTouch = 341,
+ SteamdeckLeftpadSwipe = 342,
+ SteamdeckLeftpadClick = 343,
+ SteamdeckLeftpadDpadnorth = 344,
+ SteamdeckLeftpadDpadsouth = 345,
+ SteamdeckLeftpadDpadwest = 346,
+ SteamdeckLeftpadDpadeast = 347,
+ SteamdeckRightpadTouch = 348,
+ SteamdeckRightpadSwipe = 349,
+ SteamdeckRightpadClick = 350,
+ SteamdeckRightpadDpadnorth = 351,
+ SteamdeckRightpadDpadsouth = 352,
+ SteamdeckRightpadDpadwest = 353,
+ SteamdeckRightpadDpadeast = 354,
+ SteamdeckL2Softpull = 355,
+ SteamdeckL2 = 356,
+ SteamdeckR2Softpull = 357,
+ SteamdeckR2 = 358,
+ SteamdeckLeftstickMove = 359,
+ SteamdeckL3 = 360,
+ SteamdeckLeftstickDpadnorth = 361,
+ SteamdeckLeftstickDpadsouth = 362,
+ SteamdeckLeftstickDpadwest = 363,
+ SteamdeckLeftstickDpadeast = 364,
+ SteamdeckLeftstickTouch = 365,
+ SteamdeckRightstickMove = 366,
+ SteamdeckR3 = 367,
+ SteamdeckRightstickDpadnorth = 368,
+ SteamdeckRightstickDpadsouth = 369,
+ SteamdeckRightstickDpadwest = 370,
+ SteamdeckRightstickDpadeast = 371,
+ SteamdeckRightstickTouch = 372,
+ SteamdeckL4 = 373,
+ SteamdeckR4 = 374,
+ SteamdeckL5 = 375,
+ SteamdeckR5 = 376,
+ SteamdeckDpadMove = 377,
+ SteamdeckDpadNorth = 378,
+ SteamdeckDpadSouth = 379,
+ SteamdeckDpadWest = 380,
+ SteamdeckDpadEast = 381,
+ SteamdeckGyroMove = 382,
+ SteamdeckGyroPitch = 383,
+ SteamdeckGyroYaw = 384,
+ SteamdeckGyroRoll = 385,
+ SteamdeckReserved1 = 386,
+ SteamdeckReserved2 = 387,
+ SteamdeckReserved3 = 388,
+ SteamdeckReserved4 = 389,
+ SteamdeckReserved5 = 390,
+ SteamdeckReserved6 = 391,
+ SteamdeckReserved7 = 392,
+ SteamdeckReserved8 = 393,
+ SteamdeckReserved9 = 394,
+ SteamdeckReserved10 = 395,
+ SteamdeckReserved11 = 396,
+ SteamdeckReserved12 = 397,
+ SteamdeckReserved13 = 398,
+ SteamdeckReserved14 = 399,
+ SteamdeckReserved15 = 400,
+ SteamdeckReserved16 = 401,
+ SteamdeckReserved17 = 402,
+ SteamdeckReserved18 = 403,
+ SteamdeckReserved19 = 404,
+ SteamdeckReserved20 = 405,
+ Count = 406,
+ MaximumPossibleValue = 32767,
+ }
+
+ [System.Flags]
+ public enum InputConfigurationEnableType : long
+ {
+ None = 0,
+ Playstation = 1,
+ Xbox = 2,
+ Generic = 4,
+ Switch = 8,
+ }
+
+ public enum InputGlyphSize : long
+ {
+ Small = 0,
+ Medium = 1,
+ Large = 2,
+ Count = 3,
+ }
+
+ [System.Flags]
+ public enum InputGlyphStyle : long
+ {
+ Knockout = 0,
+ Light = 1,
+ Dark = 2,
+ NeutralColorAbxy = 16,
+ SolidAbxy = 32,
+ }
+
+ public enum InputLedFlag : long
+ {
+ SetColor = 0,
+ RestoreUserDefault = 1,
+ }
+
+ public enum InputSourceMode : long
+ {
+ None = 0,
+ Dpad = 1,
+ Buttons = 2,
+ FourButtons = 3,
+ AbsoluteMouse = 4,
+ RelativeMouse = 5,
+ JoystickMove = 6,
+ JoystickMouse = 7,
+ JoystickCamera = 8,
+ ScrollWheel = 9,
+ Trigger = 10,
+ TouchMenu = 11,
+ MouseJoystick = 12,
+ MouseRegion = 13,
+ RadialMenu = 14,
+ SingleButton = 15,
+ Switch = 16,
+ }
+
+ public enum InputType : long
+ {
+ Unknown = 0,
+ SteamController = 1,
+ Xbox360Controller = 2,
+ XboxoneController = 3,
+ GenericXinput = 4,
+ Ps4Controller = 5,
+ AppleMfiController = 6,
+ AndroidController = 7,
+ SwitchJoyconPair = 8,
+ SwitchJoyconSingle = 9,
+ SwitchProController = 10,
+ MobileTouch = 11,
+ Ps3Controller = 12,
+ Ps5Controller = 13,
+ SteamDeckController = 14,
+ Count = 15,
+ MaximumPossibleValue = 255,
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.Input.cs.uid b/addons/godotsteam_csharpbindings/Steam.Input.cs.uid
new file mode 100644
index 00000000..59735a6b
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Input.cs.uid
@@ -0,0 +1 @@
+uid://cdp7kht5j4b6g
diff --git a/addons/godotsteam_csharpbindings/Steam.Inventory.Signals.cs b/addons/godotsteam_csharpbindings/Steam.Inventory.Signals.cs
new file mode 100644
index 00000000..006a7f1e
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Inventory.Signals.cs
@@ -0,0 +1,227 @@
+using System;
+using Godot;
+
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public delegate void InventoryDefinitionUpdateEventHandler(Godot.Collections.Array definitions);
+ private static event InventoryDefinitionUpdateEventHandler InventoryDefinitionUpdateEvent;
+ static Action _inventoryDefinitionUpdateAction = (definitions) =>
+ {
+ InventoryDefinitionUpdateEvent?.Invoke(definitions);
+ };
+ public static event InventoryDefinitionUpdateEventHandler InventoryDefinitionUpdate
+ {
+ add
+ {
+ if (InventoryDefinitionUpdateEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.InventoryDefinitionUpdate,
+ Callable.From(_inventoryDefinitionUpdateAction)
+ );
+ }
+ InventoryDefinitionUpdateEvent += value;
+ }
+ remove
+ {
+ InventoryDefinitionUpdateEvent -= value;
+ if (InventoryDefinitionUpdateEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.InventoryDefinitionUpdate,
+ Callable.From(_inventoryDefinitionUpdateAction)
+ );
+ }
+ }
+ }
+
+ public delegate void InventoryEligiblePromoItemEventHandler(
+ long result,
+ bool cached,
+ Godot.Collections.Array definitions
+ );
+ private static event InventoryEligiblePromoItemEventHandler InventoryEligiblePromoItemEvent;
+ static Action _inventoryEligiblePromoItemAction = (
+ result,
+ cached,
+ definitions
+ ) =>
+ {
+ InventoryEligiblePromoItemEvent?.Invoke(result, cached, definitions);
+ };
+ public static event InventoryEligiblePromoItemEventHandler InventoryEligiblePromoItem
+ {
+ add
+ {
+ if (InventoryEligiblePromoItemEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.InventoryEligiblePromoItem,
+ Callable.From(_inventoryEligiblePromoItemAction)
+ );
+ }
+ InventoryEligiblePromoItemEvent += value;
+ }
+ remove
+ {
+ InventoryEligiblePromoItemEvent -= value;
+ if (InventoryEligiblePromoItemEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.InventoryEligiblePromoItem,
+ Callable.From(_inventoryEligiblePromoItemAction)
+ );
+ }
+ }
+ }
+
+ public delegate void InventoryFullUpdateEventHandler(long inventoryHandle);
+ private static event InventoryFullUpdateEventHandler InventoryFullUpdateEvent;
+ static Action _inventoryFullUpdateAction = (inventoryHandle) =>
+ {
+ InventoryFullUpdateEvent?.Invoke(inventoryHandle);
+ };
+ public static event InventoryFullUpdateEventHandler InventoryFullUpdate
+ {
+ add
+ {
+ if (InventoryFullUpdateEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.InventoryFullUpdate,
+ Callable.From(_inventoryFullUpdateAction)
+ );
+ }
+ InventoryFullUpdateEvent += value;
+ }
+ remove
+ {
+ InventoryFullUpdateEvent -= value;
+ if (InventoryFullUpdateEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.InventoryFullUpdate,
+ Callable.From(_inventoryFullUpdateAction)
+ );
+ }
+ }
+ }
+
+ public delegate void InventoryResultReadyEventHandler(long result, long inventoryHandle);
+ private static event InventoryResultReadyEventHandler InventoryResultReadyEvent;
+ static Action _inventoryResultReadyAction = (result, inventoryHandle) =>
+ {
+ InventoryResultReadyEvent?.Invoke(result, inventoryHandle);
+ };
+ public static event InventoryResultReadyEventHandler InventoryResultReady
+ {
+ add
+ {
+ if (InventoryResultReadyEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.InventoryResultReady,
+ Callable.From(_inventoryResultReadyAction)
+ );
+ }
+ InventoryResultReadyEvent += value;
+ }
+ remove
+ {
+ InventoryResultReadyEvent -= value;
+ if (InventoryResultReadyEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.InventoryResultReady,
+ Callable.From(_inventoryResultReadyAction)
+ );
+ }
+ }
+ }
+
+ public delegate void InventoryStartPurchaseResultEventHandler(
+ string result,
+ long orderId,
+ long transactionId
+ );
+ private static event InventoryStartPurchaseResultEventHandler InventoryStartPurchaseResultEvent;
+ static Action _inventoryStartPurchaseResultAction = (
+ result,
+ orderId,
+ transactionId
+ ) =>
+ {
+ InventoryStartPurchaseResultEvent?.Invoke(result, orderId, transactionId);
+ };
+ public static event InventoryStartPurchaseResultEventHandler InventoryStartPurchaseResult
+ {
+ add
+ {
+ if (InventoryStartPurchaseResultEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.InventoryStartPurchaseResult,
+ Callable.From(_inventoryStartPurchaseResultAction)
+ );
+ }
+ InventoryStartPurchaseResultEvent += value;
+ }
+ remove
+ {
+ InventoryStartPurchaseResultEvent -= value;
+ if (InventoryStartPurchaseResultEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.InventoryStartPurchaseResult,
+ Callable.From(_inventoryStartPurchaseResultAction)
+ );
+ }
+ }
+ }
+
+ public delegate void InventoryRequestPricesResultEventHandler(long result, string currency);
+ private static event InventoryRequestPricesResultEventHandler InventoryRequestPricesResultEvent;
+ static Action _inventoryRequestPricesResultAction = (result, currency) =>
+ {
+ InventoryRequestPricesResultEvent?.Invoke(result, currency);
+ };
+ public static event InventoryRequestPricesResultEventHandler InventoryRequestPricesResult
+ {
+ add
+ {
+ if (InventoryRequestPricesResultEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.InventoryRequestPricesResult,
+ Callable.From(_inventoryRequestPricesResultAction)
+ );
+ }
+ InventoryRequestPricesResultEvent += value;
+ }
+ remove
+ {
+ InventoryRequestPricesResultEvent -= value;
+ if (InventoryRequestPricesResultEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.InventoryRequestPricesResult,
+ Callable.From(_inventoryRequestPricesResultAction)
+ );
+ }
+ }
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.Inventory.Signals.cs.uid b/addons/godotsteam_csharpbindings/Steam.Inventory.Signals.cs.uid
new file mode 100644
index 00000000..4cc9497a
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Inventory.Signals.cs.uid
@@ -0,0 +1 @@
+uid://cost68vwxtyxm
diff --git a/addons/godotsteam_csharpbindings/Steam.Inventory.cs b/addons/godotsteam_csharpbindings/Steam.Inventory.cs
new file mode 100644
index 00000000..df9ae1b0
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Inventory.cs
@@ -0,0 +1,231 @@
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public static int AddPromoItem(long item)
+ {
+ return GetInstance().Call(Methods.AddPromoItem, item).AsInt32();
+ }
+
+ public static int AddPromoItems(long[] items)
+ {
+ return GetInstance().Call(Methods.AddPromoItems, items).AsInt32();
+ }
+
+ public static bool CheckResultSteamID(ulong steamIdExpected, long thisInventoryHandle = 0)
+ {
+ return GetInstance()
+ .Call(Methods.CheckResultSteamID, steamIdExpected, thisInventoryHandle)
+ .AsBool();
+ }
+
+ public static int ConsumeItem(ulong itemConsume, long quantity)
+ {
+ return GetInstance().Call(Methods.ConsumeItem, itemConsume, quantity).AsInt32();
+ }
+
+ public static int DeserializeResult(byte[] buffer)
+ {
+ return GetInstance().Call(Methods.DeserializeResult, buffer).AsInt32();
+ }
+
+ public static void DestroyResult(long thisInventoryHandle = 0)
+ {
+ GetInstance().Call(Methods.DestroyResult, thisInventoryHandle);
+ }
+
+ public static int ExchangeItems(
+ long[] outputItems,
+ uint outputQuantity,
+ ulong inputItems,
+ long inputQuantity
+ )
+ {
+ return GetInstance()
+ .Call(Methods.ExchangeItems, outputItems, outputQuantity, inputItems, inputQuantity)
+ .AsInt32();
+ }
+
+ public static int GenerateItems(long[] items, long quantity)
+ {
+ return GetInstance().Call(Methods.GenerateItems, items, quantity).AsInt32();
+ }
+
+ public static long GetAllItems()
+ {
+ return GetInstance().Call(Methods.GetAllItems).AsInt64();
+ }
+
+ public static string GetItemDefinitionProperty(uint definition, string name)
+ {
+ return GetInstance().Call(Methods.GetItemDefinitionProperty, definition, name).AsString();
+ }
+
+ public static int GetItemsByID(ulong idArray, long count)
+ {
+ return GetInstance().Call(Methods.GetItemsByID, idArray, count).AsInt32();
+ }
+
+ public static ulong GetItemPrice(long definition)
+ {
+ return GetInstance().Call(Methods.GetItemPrice, definition).AsUInt64();
+ }
+
+ public static Godot.Collections.Array GetItemsWithPrices(long length)
+ {
+ return GetInstance().Call(Methods.GetItemsWithPrices, length).AsGodotArray();
+ }
+
+ public static long GetNumItemsWithPrices()
+ {
+ return GetInstance().Call(Methods.GetNumItemsWithPrices).AsInt64();
+ }
+
+ public static string GetResultItemProperty(
+ uint index,
+ string name,
+ long thisInventoryHandle = 0
+ )
+ {
+ return GetInstance()
+ .Call(Methods.GetResultItemProperty, index, name, thisInventoryHandle)
+ .AsString();
+ }
+
+ public static Godot.Collections.Array GetResultItems(long thisInventoryHandle = 0)
+ {
+ return GetInstance().Call(Methods.GetResultItems, thisInventoryHandle).AsGodotArray();
+ }
+
+ public static string GetResultStatus(long thisInventoryHandle = 0)
+ {
+ return GetInstance().Call(Methods.GetResultStatus, thisInventoryHandle).AsString();
+ }
+
+ public static uint GetResultTimestamp(long thisInventoryHandle = 0)
+ {
+ return GetInstance().Call(Methods.GetResultTimestamp, thisInventoryHandle).AsUInt32();
+ }
+
+ public static long GrantPromoItems()
+ {
+ return GetInstance().Call(Methods.GrantPromoItems).AsInt64();
+ }
+
+ public static bool LoadItemDefinitions()
+ {
+ return GetInstance().Call(Methods.LoadItemDefinitions).AsBool();
+ }
+
+ public static void RequestEligiblePromoItemDefinitionsIDs(ulong steamId)
+ {
+ GetInstance().Call(Methods.RequestEligiblePromoItemDefinitionsIDs, steamId);
+ }
+
+ public static void RequestPrices()
+ {
+ GetInstance().Call(Methods.RequestPrices);
+ }
+
+ public static string SerializeResult(long thisInventoryHandle = 0)
+ {
+ return GetInstance().Call(Methods.SerializeResult, thisInventoryHandle).AsString();
+ }
+
+ public static void StartPurchase(long[] items, long quantity)
+ {
+ GetInstance().Call(Methods.StartPurchase, items, quantity);
+ }
+
+ public static int TransferItemQuantity(
+ ulong itemId,
+ uint quantity,
+ ulong itemDestination,
+ bool split
+ )
+ {
+ return GetInstance()
+ .Call(Methods.TransferItemQuantity, itemId, quantity, itemDestination, split)
+ .AsInt32();
+ }
+
+ public static int TriggerItemDrop(long definition)
+ {
+ return GetInstance().Call(Methods.TriggerItemDrop, definition).AsInt32();
+ }
+
+ public static void StartUpdateProperties()
+ {
+ GetInstance().Call(Methods.StartUpdateProperties);
+ }
+
+ public static int SubmitUpdateProperties(long thisInventoryUpdateHandle = 0)
+ {
+ return GetInstance()
+ .Call(Methods.SubmitUpdateProperties, thisInventoryUpdateHandle)
+ .AsInt32();
+ }
+
+ public static bool RemoveProperty(ulong itemId, string name, long thisInventoryUpdateHandle = 0)
+ {
+ return GetInstance()
+ .Call(Methods.RemoveProperty, itemId, name, thisInventoryUpdateHandle)
+ .AsBool();
+ }
+
+ public static bool SetPropertyString(
+ ulong itemId,
+ string name,
+ string value,
+ long thisInventoryUpdateHandle = 0
+ )
+ {
+ return GetInstance()
+ .Call(Methods.SetPropertyString, itemId, name, value, thisInventoryUpdateHandle)
+ .AsBool();
+ }
+
+ public static bool SetPropertyBool(
+ ulong itemId,
+ string name,
+ bool value,
+ long thisInventoryUpdateHandle = 0
+ )
+ {
+ return GetInstance()
+ .Call(Methods.SetPropertyBool, itemId, name, value, thisInventoryUpdateHandle)
+ .AsBool();
+ }
+
+ public static bool SetPropertyInt(
+ ulong itemId,
+ string name,
+ ulong value,
+ long thisInventoryUpdateHandle = 0
+ )
+ {
+ return GetInstance()
+ .Call(Methods.SetPropertyInt, itemId, name, value, thisInventoryUpdateHandle)
+ .AsBool();
+ }
+
+ public static bool SetPropertyFloat(
+ ulong itemId,
+ string name,
+ float value,
+ long thisInventoryUpdateHandle = 0
+ )
+ {
+ return GetInstance()
+ .Call(Methods.SetPropertyFloat, itemId, name, value, thisInventoryUpdateHandle)
+ .AsBool();
+ }
+
+ [System.Flags]
+ public enum ItemFlags : long
+ {
+ NoTrade = 1,
+ Removed = 256,
+ Consumed = 512,
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.Inventory.cs.uid b/addons/godotsteam_csharpbindings/Steam.Inventory.cs.uid
new file mode 100644
index 00000000..a9579ac9
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Inventory.cs.uid
@@ -0,0 +1 @@
+uid://cdpl682enwg7m
diff --git a/addons/godotsteam_csharpbindings/Steam.Matchmaking.Signals.cs b/addons/godotsteam_csharpbindings/Steam.Matchmaking.Signals.cs
new file mode 100644
index 00000000..5d960b73
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Matchmaking.Signals.cs
@@ -0,0 +1,360 @@
+using System;
+using Godot;
+
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public delegate void FavoritesListAccountsUpdatedEventHandler(long result);
+ private static event FavoritesListAccountsUpdatedEventHandler FavoritesListAccountsUpdatedEvent;
+ static Action _favoritesListAccountsUpdatedAction = (result) =>
+ {
+ FavoritesListAccountsUpdatedEvent?.Invoke(result);
+ };
+ public static event FavoritesListAccountsUpdatedEventHandler FavoritesListAccountsUpdated
+ {
+ add
+ {
+ if (FavoritesListAccountsUpdatedEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.FavoritesListAccountsUpdated,
+ Callable.From(_favoritesListAccountsUpdatedAction)
+ );
+ }
+ FavoritesListAccountsUpdatedEvent += value;
+ }
+ remove
+ {
+ FavoritesListAccountsUpdatedEvent -= value;
+ if (FavoritesListAccountsUpdatedEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.FavoritesListAccountsUpdated,
+ Callable.From(_favoritesListAccountsUpdatedAction)
+ );
+ }
+ }
+ }
+
+ public delegate void FavoritesListChangedEventHandler(Godot.Collections.Dictionary favorite);
+ private static event FavoritesListChangedEventHandler FavoritesListChangedEvent;
+ static Action _favoritesListChangedAction = (favorite) =>
+ {
+ FavoritesListChangedEvent?.Invoke(favorite);
+ };
+ public static event FavoritesListChangedEventHandler FavoritesListChanged
+ {
+ add
+ {
+ if (FavoritesListChangedEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.FavoritesListChanged,
+ Callable.From(_favoritesListChangedAction)
+ );
+ }
+ FavoritesListChangedEvent += value;
+ }
+ remove
+ {
+ FavoritesListChangedEvent -= value;
+ if (FavoritesListChangedEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.FavoritesListChanged,
+ Callable.From(_favoritesListChangedAction)
+ );
+ }
+ }
+ }
+
+ public delegate void LobbyMessageEventHandler(
+ ulong lobbyId,
+ long user,
+ string message,
+ long chatType
+ );
+ private static event LobbyMessageEventHandler LobbyMessageEvent;
+ static Action _lobbyMessageAction = (
+ lobbyId,
+ user,
+ message,
+ chatType
+ ) =>
+ {
+ LobbyMessageEvent?.Invoke(lobbyId, user, message, chatType);
+ };
+ public static event LobbyMessageEventHandler LobbyMessage
+ {
+ add
+ {
+ if (LobbyMessageEvent == null)
+ {
+ GetInstance().Connect(Signals.LobbyMessage, Callable.From(_lobbyMessageAction));
+ }
+ LobbyMessageEvent += value;
+ }
+ remove
+ {
+ LobbyMessageEvent -= value;
+ if (LobbyMessageEvent == null)
+ {
+ GetInstance().Disconnect(Signals.LobbyMessage, Callable.From(_lobbyMessageAction));
+ }
+ }
+ }
+
+ public delegate void LobbyChatUpdateEventHandler(
+ ulong lobbyId,
+ long changedId,
+ long makingChangeId,
+ long chatState
+ );
+ private static event LobbyChatUpdateEventHandler LobbyChatUpdateEvent;
+ static Action _lobbyChatUpdateAction = (
+ lobbyId,
+ changedId,
+ makingChangeId,
+ chatState
+ ) =>
+ {
+ LobbyChatUpdateEvent?.Invoke(lobbyId, changedId, makingChangeId, chatState);
+ };
+ public static event LobbyChatUpdateEventHandler LobbyChatUpdate
+ {
+ add
+ {
+ if (LobbyChatUpdateEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.LobbyChatUpdate, Callable.From(_lobbyChatUpdateAction));
+ }
+ LobbyChatUpdateEvent += value;
+ }
+ remove
+ {
+ LobbyChatUpdateEvent -= value;
+ if (LobbyChatUpdateEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.LobbyChatUpdate, Callable.From(_lobbyChatUpdateAction));
+ }
+ }
+ }
+
+ public delegate void LobbyCreatedEventHandler(long connect, ulong lobbyId);
+ private static event LobbyCreatedEventHandler LobbyCreatedEvent;
+ static Action _lobbyCreatedAction = (connect, lobbyId) =>
+ {
+ LobbyCreatedEvent?.Invoke(connect, lobbyId);
+ };
+ public static event LobbyCreatedEventHandler LobbyCreated
+ {
+ add
+ {
+ if (LobbyCreatedEvent == null)
+ {
+ GetInstance().Connect(Signals.LobbyCreated, Callable.From(_lobbyCreatedAction));
+ }
+ LobbyCreatedEvent += value;
+ }
+ remove
+ {
+ LobbyCreatedEvent -= value;
+ if (LobbyCreatedEvent == null)
+ {
+ GetInstance().Disconnect(Signals.LobbyCreated, Callable.From(_lobbyCreatedAction));
+ }
+ }
+ }
+
+ public delegate void LobbyDataUpdateEventHandler(uint success, ulong lobbyID, ulong memberID);
+ public static event LobbyDataUpdateEventHandler LobbyDataUpdateEvent;
+ static Action _lobbyDataUpdateAction = (success, lobbyID, memberID) =>
+ {
+ LobbyDataUpdateEvent?.Invoke(success, lobbyID, memberID);
+ };
+ public static event LobbyDataUpdateEventHandler LobbyDataUpdate
+ {
+ add
+ {
+ if (LobbyDataUpdateEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.LobbyDataUpdate, Callable.From(_lobbyDataUpdateAction));
+ }
+ LobbyDataUpdateEvent += value;
+ }
+ remove
+ {
+ LobbyDataUpdateEvent -= value;
+ if (LobbyDataUpdateEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.LobbyDataUpdate, Callable.From(_lobbyDataUpdateAction));
+ }
+ }
+ }
+
+ public delegate void LobbyJoinedEventHandler(
+ ulong lobby,
+ long permissions,
+ bool locked,
+ long response
+ );
+ private static event LobbyJoinedEventHandler LobbyJoinedEvent;
+ static Action _lobbyJoinedAction = (
+ lobby,
+ permissions,
+ locked,
+ response
+ ) =>
+ {
+ LobbyJoinedEvent?.Invoke(lobby, permissions, locked, response);
+ };
+ public static event LobbyJoinedEventHandler LobbyJoined
+ {
+ add
+ {
+ if (LobbyJoinedEvent == null)
+ {
+ GetInstance().Connect(Signals.LobbyJoined, Callable.From(_lobbyJoinedAction));
+ }
+ LobbyJoinedEvent += value;
+ }
+ remove
+ {
+ LobbyJoinedEvent -= value;
+ if (LobbyJoinedEvent == null)
+ {
+ GetInstance().Disconnect(Signals.LobbyJoined, Callable.From(_lobbyJoinedAction));
+ }
+ }
+ }
+
+ public delegate void LobbyGameCreatedEventHandler(
+ ulong lobbyId,
+ ulong serverId,
+ string serverIP,
+ ushort port
+ );
+ private static event LobbyGameCreatedEventHandler LobbyGameCreatedEvent;
+ static Action _lobbyGameCreatedAction = (
+ lobbyId,
+ serverId,
+ serverIP,
+ port
+ ) =>
+ {
+ LobbyGameCreatedEvent?.Invoke(lobbyId, serverId, serverIP, port);
+ };
+ public static event LobbyGameCreatedEventHandler LobbyGameCreated
+ {
+ add
+ {
+ if (LobbyGameCreatedEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.LobbyGameCreated, Callable.From(_lobbyGameCreatedAction));
+ }
+ LobbyGameCreatedEvent += value;
+ }
+ remove
+ {
+ LobbyGameCreatedEvent -= value;
+ if (LobbyGameCreatedEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.LobbyGameCreated, Callable.From(_lobbyGameCreatedAction));
+ }
+ }
+ }
+
+ public delegate void LobbyInviteEventHandler(ulong inviter, ulong lobby, ulong game);
+ private static event LobbyInviteEventHandler LobbyInviteEvent;
+ static Action _lobbyInviteAction = (inviter, lobby, game) =>
+ {
+ LobbyInviteEvent?.Invoke(inviter, lobby, game);
+ };
+ public static event LobbyInviteEventHandler LobbyInvite
+ {
+ add
+ {
+ if (LobbyInviteEvent == null)
+ {
+ GetInstance().Connect(Signals.LobbyInvite, Callable.From(_lobbyInviteAction));
+ }
+ LobbyInviteEvent += value;
+ }
+ remove
+ {
+ LobbyInviteEvent -= value;
+ if (LobbyInviteEvent == null)
+ {
+ GetInstance().Disconnect(Signals.LobbyInvite, Callable.From(_lobbyInviteAction));
+ }
+ }
+ }
+
+ public delegate void LobbyMatchListEventHandler(Godot.Collections.Array lobbies);
+ private static event LobbyMatchListEventHandler LobbyMatchListEvent;
+ static Action _lobbyMatchListAction = (lobbies) =>
+ {
+ LobbyMatchListEvent?.Invoke(lobbies);
+ };
+ public static event LobbyMatchListEventHandler LobbyMatchList
+ {
+ add
+ {
+ if (LobbyMatchListEvent == null)
+ {
+ GetInstance().Connect(Signals.LobbyMatchList, Callable.From(_lobbyMatchListAction));
+ }
+ LobbyMatchListEvent += value;
+ }
+ remove
+ {
+ LobbyMatchListEvent -= value;
+ if (LobbyMatchListEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.LobbyMatchList, Callable.From(_lobbyMatchListAction));
+ }
+ }
+ }
+
+ public delegate void LobbyKickedEventHandler(
+ ulong lobbyId,
+ ulong adminId,
+ byte dueToDisconnect
+ );
+ private static event LobbyKickedEventHandler LobbyKickedEvent;
+ static Action _lobbyKickedAction = (lobbyId, adminId, dueToDisconnect) =>
+ {
+ LobbyKickedEvent?.Invoke(lobbyId, adminId, dueToDisconnect);
+ };
+ public static event LobbyKickedEventHandler LobbyKicked
+ {
+ add
+ {
+ if (LobbyKickedEvent == null)
+ {
+ GetInstance().Connect(Signals.LobbyKicked, Callable.From(_lobbyKickedAction));
+ }
+ LobbyKickedEvent += value;
+ }
+ remove
+ {
+ LobbyKickedEvent -= value;
+ if (LobbyKickedEvent == null)
+ {
+ GetInstance().Disconnect(Signals.LobbyKicked, Callable.From(_lobbyKickedAction));
+ }
+ }
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.Matchmaking.Signals.cs.uid b/addons/godotsteam_csharpbindings/Steam.Matchmaking.Signals.cs.uid
new file mode 100644
index 00000000..ef142fed
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Matchmaking.Signals.cs.uid
@@ -0,0 +1 @@
+uid://6usy88k3yn23
diff --git a/addons/godotsteam_csharpbindings/Steam.Matchmaking.cs b/addons/godotsteam_csharpbindings/Steam.Matchmaking.cs
new file mode 100644
index 00000000..8ad49845
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Matchmaking.cs
@@ -0,0 +1,240 @@
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public static Godot.Collections.Array GetFavoriteGames()
+ {
+ return GetInstance().Call(Methods.GetFavoriteGames).AsGodotArray();
+ }
+
+ public static int AddFavoriteGame(uint iP, int port, int queryPort, uint flags, long lastPlayed)
+ {
+ return GetInstance()
+ .Call(Methods.AddFavoriteGame, iP, port, queryPort, flags, lastPlayed)
+ .AsInt32();
+ }
+
+ public static bool RemoveFavoriteGame(uint appId, uint iP, int port, int queryPort, long flags)
+ {
+ return GetInstance()
+ .Call(Methods.RemoveFavoriteGame, appId, iP, port, queryPort, flags)
+ .AsBool();
+ }
+
+ public static void RequestLobbyList()
+ {
+ GetInstance().Call(Methods.RequestLobbyList);
+ }
+
+ public static void AddRequestLobbyListStringFilter(
+ string keyToMatch,
+ string valueToMatch,
+ LobbyComparison comparisonType
+ )
+ {
+ GetInstance()
+ .Call(
+ Methods.AddRequestLobbyListStringFilter,
+ keyToMatch,
+ valueToMatch,
+ (long)comparisonType
+ );
+ }
+
+ public static void AddRequestLobbyListNumericalFilter(
+ string keyToMatch,
+ int valueToMatch,
+ LobbyComparison comparisonType
+ )
+ {
+ GetInstance()
+ .Call(
+ Methods.AddRequestLobbyListNumericalFilter,
+ keyToMatch,
+ valueToMatch,
+ (long)comparisonType
+ );
+ }
+
+ public static void AddRequestLobbyListNearValueFilter(string keyToMatch, long valueToBeCloseTo)
+ {
+ GetInstance()
+ .Call(Methods.AddRequestLobbyListNearValueFilter, keyToMatch, valueToBeCloseTo);
+ }
+
+ public static void AddRequestLobbyListFilterSlotsAvailable(long slotsAvailable)
+ {
+ GetInstance().Call(Methods.AddRequestLobbyListFilterSlotsAvailable, slotsAvailable);
+ }
+
+ public static void AddRequestLobbyListDistanceFilter(LobbyDistanceFilter distanceFilter)
+ {
+ GetInstance().Call(Methods.AddRequestLobbyListDistanceFilter, (long)distanceFilter);
+ }
+
+ public static void AddRequestLobbyListResultCountFilter(long maxResults)
+ {
+ GetInstance().Call(Methods.AddRequestLobbyListResultCountFilter, maxResults);
+ }
+
+ public static void CreateLobby(LobbyType lobbyType, long maxMembers = 2)
+ {
+ GetInstance().Call(Methods.CreateLobby, (long)lobbyType, maxMembers);
+ }
+
+ public static void JoinLobby(ulong steamLobbyId)
+ {
+ GetInstance().Call(Methods.JoinLobby, steamLobbyId);
+ }
+
+ public static void LeaveLobby(ulong steamLobbyId)
+ {
+ GetInstance().Call(Methods.LeaveLobby, steamLobbyId);
+ }
+
+ public static bool InviteUserToLobby(ulong steamLobbyId, ulong steamIdInvitee)
+ {
+ return GetInstance().Call(Methods.InviteUserToLobby, steamLobbyId, steamIdInvitee).AsBool();
+ }
+
+ public static int GetNumLobbyMembers(ulong steamLobbyId)
+ {
+ return GetInstance().Call(Methods.GetNumLobbyMembers, steamLobbyId).AsInt32();
+ }
+
+ public static ulong GetLobbyMemberByIndex(ulong steamLobbyId, long member)
+ {
+ return GetInstance().Call(Methods.GetLobbyMemberByIndex, steamLobbyId, member).AsUInt64();
+ }
+
+ public static string GetLobbyData(ulong steamLobbyId, string key)
+ {
+ return GetInstance().Call(Methods.GetLobbyData, steamLobbyId, key).AsString();
+ }
+
+ public static bool SetLobbyData(ulong steamLobbyId, string key, string value)
+ {
+ return GetInstance().Call(Methods.SetLobbyData, steamLobbyId, key, value).AsBool();
+ }
+
+ public static Godot.Collections.Dictionary GetAllLobbyData(ulong steamLobbyId)
+ {
+ return GetInstance().Call(Methods.GetAllLobbyData, steamLobbyId).AsGodotDictionary();
+ }
+
+ public static bool DeleteLobbyData(ulong steamLobbyId, string key)
+ {
+ return GetInstance().Call(Methods.DeleteLobbyData, steamLobbyId, key).AsBool();
+ }
+
+ public static string GetLobbyMemberData(ulong steamLobbyId, ulong steamIdUser, string key)
+ {
+ return GetInstance()
+ .Call(Methods.GetLobbyMemberData, steamLobbyId, steamIdUser, key)
+ .AsString();
+ }
+
+ public static void SetLobbyMemberData(ulong steamLobbyId, string key, string value)
+ {
+ GetInstance().Call(Methods.SetLobbyMemberData, steamLobbyId, key, value);
+ }
+
+ public static bool SendLobbyChatMsg(ulong steamLobbyId, string messageBody)
+ {
+ return GetInstance().Call(Methods.SendLobbyChatMsg, steamLobbyId, messageBody).AsBool();
+ }
+
+ public static bool RequestLobbyData(ulong steamLobbyId)
+ {
+ return GetInstance().Call(Methods.RequestLobbyData, steamLobbyId).AsBool();
+ }
+
+ public static void SetLobbyGameServer(
+ ulong steamLobbyId,
+ string serverIP,
+ int serverPort,
+ ulong steamIdGameServer
+ )
+ {
+ GetInstance()
+ .Call(
+ Methods.SetLobbyGameServer,
+ steamLobbyId,
+ serverIP,
+ serverPort,
+ steamIdGameServer
+ );
+ }
+
+ public static Godot.Collections.Dictionary GetLobbyGameServer(ulong steamLobbyId)
+ {
+ return GetInstance().Call(Methods.GetLobbyGameServer, steamLobbyId).AsGodotDictionary();
+ }
+
+ public static bool SetLobbyMemberLimit(ulong steamLobbyId, long maxMembers)
+ {
+ return GetInstance().Call(Methods.SetLobbyMemberLimit, steamLobbyId, maxMembers).AsBool();
+ }
+
+ public static int GetLobbyMemberLimit(ulong steamLobbyId)
+ {
+ return GetInstance().Call(Methods.GetLobbyMemberLimit, steamLobbyId).AsInt32();
+ }
+
+ public static bool SetLobbyType(ulong steamLobbyId, LobbyType lobbyType)
+ {
+ return GetInstance().Call(Methods.SetLobbyType, steamLobbyId, (long)lobbyType).AsBool();
+ }
+
+ public static bool SetLobbyJoinable(ulong steamLobbyId, bool joinable)
+ {
+ return GetInstance().Call(Methods.SetLobbyJoinable, steamLobbyId, joinable).AsBool();
+ }
+
+ public static ulong GetLobbyOwner(ulong steamLobbyId)
+ {
+ return GetInstance().Call(Methods.GetLobbyOwner, steamLobbyId).AsUInt64();
+ }
+
+ public static bool SetLobbyOwner(ulong steamLobbyId, ulong steamIdNewOwner)
+ {
+ return GetInstance().Call(Methods.SetLobbyOwner, steamLobbyId, steamIdNewOwner).AsBool();
+ }
+
+ [System.Flags]
+ public enum ChatMemberStateChange : long
+ {
+ Entered = 1,
+ Left = 2,
+ Disconnected = 4,
+ Kicked = 8,
+ Banned = 16,
+ }
+
+ public enum LobbyComparison : long
+ {
+ LobbyComparisonEqualToOrLessThan = -2,
+ LobbyComparisonLessThan = -1,
+ LobbyComparisonEqual = 0,
+ LobbyComparisonGreaterThan = 1,
+ LobbyComparisonEqualToGreaterThan = 2,
+ LobbyComparisonNotEqual = 3,
+ }
+
+ public enum LobbyDistanceFilter : long
+ {
+ Close = 0,
+ Default = 1,
+ Far = 2,
+ Worldwide = 3,
+ }
+
+ public enum LobbyType : long
+ {
+ Private = 0,
+ FriendsOnly = 1,
+ Public = 2,
+ Invisible = 3,
+ PrivateUnique = 4,
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.Matchmaking.cs.uid b/addons/godotsteam_csharpbindings/Steam.Matchmaking.cs.uid
new file mode 100644
index 00000000..3180d99c
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Matchmaking.cs.uid
@@ -0,0 +1 @@
+uid://nyyih81w26he
diff --git a/addons/godotsteam_csharpbindings/Steam.MatchmakingServers.Signals.cs b/addons/godotsteam_csharpbindings/Steam.MatchmakingServers.Signals.cs
new file mode 100644
index 00000000..35776ad1
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.MatchmakingServers.Signals.cs
@@ -0,0 +1,67 @@
+using System;
+using Godot;
+
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public static event Action ServerRespondedEvent;
+ static Action _serverRespondedAction = () =>
+ {
+ ServerRespondedEvent?.Invoke();
+ };
+ public static event Action ServerResponded
+ {
+ add
+ {
+ if (ServerRespondedEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.ServerResponded, Callable.From(_serverRespondedAction));
+ }
+ ServerRespondedEvent += value;
+ }
+ remove
+ {
+ ServerRespondedEvent -= value;
+ if (ServerRespondedEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.ServerResponded, Callable.From(_serverRespondedAction));
+ }
+ }
+ }
+
+ public static event Action ServerFailedToRespondEvent;
+ static Action _serverFailedToRespondAction = () =>
+ {
+ ServerFailedToRespondEvent?.Invoke();
+ };
+ public static event Action ServerFailedToRespond
+ {
+ add
+ {
+ if (ServerFailedToRespondEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.ServerFailedToRespond,
+ Callable.From(_serverFailedToRespondAction)
+ );
+ }
+ ServerFailedToRespondEvent += value;
+ }
+ remove
+ {
+ ServerFailedToRespondEvent -= value;
+ if (ServerFailedToRespondEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.ServerFailedToRespond,
+ Callable.From(_serverFailedToRespondAction)
+ );
+ }
+ }
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.MatchmakingServers.Signals.cs.uid b/addons/godotsteam_csharpbindings/Steam.MatchmakingServers.Signals.cs.uid
new file mode 100644
index 00000000..c06ab0dc
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.MatchmakingServers.Signals.cs.uid
@@ -0,0 +1 @@
+uid://bpbnpgg6iriyb
diff --git a/addons/godotsteam_csharpbindings/Steam.MatchmakingServers.cs b/addons/godotsteam_csharpbindings/Steam.MatchmakingServers.cs
new file mode 100644
index 00000000..1669862e
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.MatchmakingServers.cs
@@ -0,0 +1,98 @@
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public static void CancelQuery(long serverListRequest)
+ {
+ GetInstance().Call(Methods.CancelQuery, serverListRequest);
+ }
+
+ public static void CancelServerQuery(long serverQuery)
+ {
+ GetInstance().Call(Methods.CancelServerQuery, serverQuery);
+ }
+
+ public static int GetServerCount(long serverListRequest)
+ {
+ return GetInstance().Call(Methods.GetServerCount, serverListRequest).AsInt32();
+ }
+
+ public static Godot.Collections.Dictionary GetServerDetails(int server, long serverListRequest)
+ {
+ return GetInstance()
+ .Call(Methods.GetServerDetails, server, serverListRequest)
+ .AsGodotDictionary();
+ }
+
+ public static bool IsRefreshing(long serverListRequest)
+ {
+ return GetInstance().Call(Methods.IsRefreshing, serverListRequest).AsBool();
+ }
+
+ public static int PingServer(string iP, long port)
+ {
+ return GetInstance().Call(Methods.PingServer, iP, port).AsInt32();
+ }
+
+ public static int PlayerDetails(string iP, long port)
+ {
+ return GetInstance().Call(Methods.PlayerDetails, iP, port).AsInt32();
+ }
+
+ public static void RefreshQuery(long serverListRequest)
+ {
+ GetInstance().Call(Methods.RefreshQuery, serverListRequest);
+ }
+
+ public static void RefreshServer(int server, long serverListRequest)
+ {
+ GetInstance().Call(Methods.RefreshServer, server, serverListRequest);
+ }
+
+ public static void ReleaseRequest(long serverListRequest)
+ {
+ GetInstance().Call(Methods.ReleaseRequest, serverListRequest);
+ }
+
+ public static ulong RequestFavoritesServerList(uint appId, Godot.Collections.Array filters)
+ {
+ return GetInstance().Call(Methods.RequestFavoritesServerList, appId, filters).AsUInt64();
+ }
+
+ public static ulong RequestFriendsServerList(uint appId, Godot.Collections.Array filters)
+ {
+ return GetInstance().Call(Methods.RequestFriendsServerList, appId, filters).AsUInt64();
+ }
+
+ public static ulong RequestHistoryServerList(uint appId, Godot.Collections.Array filters)
+ {
+ return GetInstance().Call(Methods.RequestHistoryServerList, appId, filters).AsUInt64();
+ }
+
+ public static ulong RequestInternetServerList(uint appId, Godot.Collections.Array filters)
+ {
+ return GetInstance().Call(Methods.RequestInternetServerList, appId, filters).AsUInt64();
+ }
+
+ public static ulong RequestLANServerList(uint appId)
+ {
+ return GetInstance().Call(Methods.RequestLANServerList, appId).AsUInt64();
+ }
+
+ public static ulong RequestSpectatorServerList(uint appId, Godot.Collections.Array filters)
+ {
+ return GetInstance().Call(Methods.RequestSpectatorServerList, appId, filters).AsUInt64();
+ }
+
+ public static int ServerRules(string iP, long port)
+ {
+ return GetInstance().Call(Methods.ServerRules, iP, port).AsInt32();
+ }
+
+ public enum MatchMakingServerResponse : long
+ {
+ ServerResponded = 0,
+ ServerFailedToRespond = 1,
+ NoServersListedOnMasterServer = 2,
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.MatchmakingServers.cs.uid b/addons/godotsteam_csharpbindings/Steam.MatchmakingServers.cs.uid
new file mode 100644
index 00000000..3227b6d3
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.MatchmakingServers.cs.uid
@@ -0,0 +1 @@
+uid://bdhnj5vbbpct8
diff --git a/addons/godotsteam_csharpbindings/Steam.Music.cs b/addons/godotsteam_csharpbindings/Steam.Music.cs
new file mode 100644
index 00000000..36c38dbb
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Music.cs
@@ -0,0 +1,57 @@
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public static bool MusicIsEnabled()
+ {
+ return GetInstance().Call(Methods.MusicIsEnabled).AsBool();
+ }
+
+ public static bool MusicIsPlaying()
+ {
+ return GetInstance().Call(Methods.MusicIsPlaying).AsBool();
+ }
+
+ public static AudioPlaybackStatus GetPlaybackStatus()
+ {
+ return (AudioPlaybackStatus)GetInstance().Call(Methods.GetPlaybackStatus).AsInt64();
+ }
+
+ public static double MusicGetVolume()
+ {
+ return GetInstance().Call(Methods.MusicGetVolume).AsDouble();
+ }
+
+ public static void MusicPause()
+ {
+ GetInstance().Call(Methods.MusicPause);
+ }
+
+ public static void MusicPlay()
+ {
+ GetInstance().Call(Methods.MusicPlay);
+ }
+
+ public static void MusicPlayNext()
+ {
+ GetInstance().Call(Methods.MusicPlayNext);
+ }
+
+ public static void MusicPlayPrev()
+ {
+ GetInstance().Call(Methods.MusicPlayPrev);
+ }
+
+ public static void MusicSetVolume(double volume)
+ {
+ GetInstance().Call(Methods.MusicSetVolume, volume);
+ }
+
+ public enum AudioPlaybackStatus : long
+ {
+ Undefined = 0,
+ Playing = 1,
+ Paused = 2,
+ Idle = 3,
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.Music.cs.uid b/addons/godotsteam_csharpbindings/Steam.Music.cs.uid
new file mode 100644
index 00000000..71536686
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Music.cs.uid
@@ -0,0 +1 @@
+uid://7gsit5fbnxt5
diff --git a/addons/godotsteam_csharpbindings/Steam.MusicRemote.Signals.cs b/addons/godotsteam_csharpbindings/Steam.MusicRemote.Signals.cs
new file mode 100644
index 00000000..18fd08bb
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.MusicRemote.Signals.cs
@@ -0,0 +1,475 @@
+using System;
+using Godot;
+
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public static event Action MusicPlayerRemoteToFrontEvent;
+ static Action _musicPlayerRemoteToFrontAction = () =>
+ {
+ MusicPlayerRemoteToFrontEvent?.Invoke();
+ };
+ public static event Action MusicPlayerRemoteToFront
+ {
+ add
+ {
+ if (MusicPlayerRemoteToFrontEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.MusicPlayerRemoteToFront,
+ Callable.From(_musicPlayerRemoteToFrontAction)
+ );
+ }
+ MusicPlayerRemoteToFrontEvent += value;
+ }
+ remove
+ {
+ MusicPlayerRemoteToFrontEvent -= value;
+ if (MusicPlayerRemoteToFrontEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.MusicPlayerRemoteToFront,
+ Callable.From(_musicPlayerRemoteToFrontAction)
+ );
+ }
+ }
+ }
+
+ public static event Action MusicPlayerRemoteWillActivateEvent;
+ static Action _musicPlayerRemoteWillActivateAction = () =>
+ {
+ MusicPlayerRemoteWillActivateEvent?.Invoke();
+ };
+ public static event Action MusicPlayerRemoteWillActivate
+ {
+ add
+ {
+ if (MusicPlayerRemoteWillActivateEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.MusicPlayerRemoteWillActivate,
+ Callable.From(_musicPlayerRemoteWillActivateAction)
+ );
+ }
+ MusicPlayerRemoteWillActivateEvent += value;
+ }
+ remove
+ {
+ MusicPlayerRemoteWillActivateEvent -= value;
+ if (MusicPlayerRemoteWillActivateEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.MusicPlayerRemoteWillActivate,
+ Callable.From(_musicPlayerRemoteWillActivateAction)
+ );
+ }
+ }
+ }
+
+ public static event Action MusicPlayerRemoteWillDeactivateEvent;
+ static Action _musicPlayerRemoteWillDeactivateAction = () =>
+ {
+ MusicPlayerRemoteWillDeactivateEvent?.Invoke();
+ };
+ public static event Action MusicPlayerRemoteWillDeactivate
+ {
+ add
+ {
+ if (MusicPlayerRemoteWillDeactivateEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.MusicPlayerRemoteWillDeactivate,
+ Callable.From(_musicPlayerRemoteWillDeactivateAction)
+ );
+ }
+ MusicPlayerRemoteWillDeactivateEvent += value;
+ }
+ remove
+ {
+ MusicPlayerRemoteWillDeactivateEvent -= value;
+ if (MusicPlayerRemoteWillDeactivateEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.MusicPlayerRemoteWillDeactivate,
+ Callable.From(_musicPlayerRemoteWillDeactivateAction)
+ );
+ }
+ }
+ }
+
+ public delegate void MusicPlayerSelectsPlaylistEntryEventHandler(long entry);
+ private static event MusicPlayerSelectsPlaylistEntryEventHandler MusicPlayerSelectsPlaylistEntryEvent;
+ static Action _musicPlayerSelectsPlaylistEntryAction = (entry) =>
+ {
+ MusicPlayerSelectsPlaylistEntryEvent?.Invoke(entry);
+ };
+ public static event MusicPlayerSelectsPlaylistEntryEventHandler MusicPlayerSelectsPlaylistEntry
+ {
+ add
+ {
+ if (MusicPlayerSelectsPlaylistEntryEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.MusicPlayerSelectsPlaylistEntry,
+ Callable.From(_musicPlayerSelectsPlaylistEntryAction)
+ );
+ }
+ MusicPlayerSelectsPlaylistEntryEvent += value;
+ }
+ remove
+ {
+ MusicPlayerSelectsPlaylistEntryEvent -= value;
+ if (MusicPlayerSelectsPlaylistEntryEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.MusicPlayerSelectsPlaylistEntry,
+ Callable.From(_musicPlayerSelectsPlaylistEntryAction)
+ );
+ }
+ }
+ }
+
+ public delegate void MusicPlayerSelectsQueueEntryEventHandler(long entry);
+ private static event MusicPlayerSelectsQueueEntryEventHandler MusicPlayerSelectsQueueEntryEvent;
+ static Action _musicPlayerSelectsQueueEntryAction = (entry) =>
+ {
+ MusicPlayerSelectsQueueEntryEvent?.Invoke(entry);
+ };
+ public static event MusicPlayerSelectsQueueEntryEventHandler MusicPlayerSelectsQueueEntry
+ {
+ add
+ {
+ if (MusicPlayerSelectsQueueEntryEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.MusicPlayerSelectsQueueEntry,
+ Callable.From(_musicPlayerSelectsQueueEntryAction)
+ );
+ }
+ MusicPlayerSelectsQueueEntryEvent += value;
+ }
+ remove
+ {
+ MusicPlayerSelectsQueueEntryEvent -= value;
+ if (MusicPlayerSelectsQueueEntryEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.MusicPlayerSelectsQueueEntry,
+ Callable.From(_musicPlayerSelectsQueueEntryAction)
+ );
+ }
+ }
+ }
+
+ public delegate void MusicPlayerWantsLoopedEventHandler(bool looped);
+ private static event MusicPlayerWantsLoopedEventHandler MusicPlayerWantsLoopedEvent;
+ static Action _musicPlayerWantsLoopedAction = (looped) =>
+ {
+ MusicPlayerWantsLoopedEvent?.Invoke(looped);
+ };
+ public static event MusicPlayerWantsLoopedEventHandler MusicPlayerWantsLooped
+ {
+ add
+ {
+ if (MusicPlayerWantsLoopedEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.MusicPlayerWantsLooped,
+ Callable.From(_musicPlayerWantsLoopedAction)
+ );
+ }
+ MusicPlayerWantsLoopedEvent += value;
+ }
+ remove
+ {
+ MusicPlayerWantsLoopedEvent -= value;
+ if (MusicPlayerWantsLoopedEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.MusicPlayerWantsLooped,
+ Callable.From(_musicPlayerWantsLoopedAction)
+ );
+ }
+ }
+ }
+
+ public static event Action MusicPlayerWantsPauseEvent;
+ static Action _musicPlayerWantsPauseAction = () =>
+ {
+ MusicPlayerWantsPauseEvent?.Invoke();
+ };
+ public static event Action MusicPlayerWantsPause
+ {
+ add
+ {
+ if (MusicPlayerWantsPauseEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.MusicPlayerWantsPause,
+ Callable.From(_musicPlayerWantsPauseAction)
+ );
+ }
+ MusicPlayerWantsPauseEvent += value;
+ }
+ remove
+ {
+ MusicPlayerWantsPauseEvent -= value;
+ if (MusicPlayerWantsPauseEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.MusicPlayerWantsPause,
+ Callable.From(_musicPlayerWantsPauseAction)
+ );
+ }
+ }
+ }
+
+ public delegate void MusicPlayerWantsPlayingRepeatStatusEventHandler(long status);
+ private static event MusicPlayerWantsPlayingRepeatStatusEventHandler MusicPlayerWantsPlayingRepeatStatusEvent;
+ static Action _musicPlayerWantsPlayingRepeatStatusAction = (status) =>
+ {
+ MusicPlayerWantsPlayingRepeatStatusEvent?.Invoke(status);
+ };
+ public static event MusicPlayerWantsPlayingRepeatStatusEventHandler MusicPlayerWantsPlayingRepeatStatus
+ {
+ add
+ {
+ if (MusicPlayerWantsPlayingRepeatStatusEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.MusicPlayerWantsPlayingRepeatStatus,
+ Callable.From(_musicPlayerWantsPlayingRepeatStatusAction)
+ );
+ }
+ MusicPlayerWantsPlayingRepeatStatusEvent += value;
+ }
+ remove
+ {
+ MusicPlayerWantsPlayingRepeatStatusEvent -= value;
+ if (MusicPlayerWantsPlayingRepeatStatusEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.MusicPlayerWantsPlayingRepeatStatus,
+ Callable.From(_musicPlayerWantsPlayingRepeatStatusAction)
+ );
+ }
+ }
+ }
+
+ public static event Action MusicPlayerWantsPlayNextEvent;
+ static Action _musicPlayerWantsPlayNextAction = () =>
+ {
+ MusicPlayerWantsPlayNextEvent?.Invoke();
+ };
+ public static event Action MusicPlayerWantsPlayNext
+ {
+ add
+ {
+ if (MusicPlayerWantsPlayNextEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.MusicPlayerWantsPlayNext,
+ Callable.From(_musicPlayerWantsPlayNextAction)
+ );
+ }
+ MusicPlayerWantsPlayNextEvent += value;
+ }
+ remove
+ {
+ MusicPlayerWantsPlayNextEvent -= value;
+ if (MusicPlayerWantsPlayNextEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.MusicPlayerWantsPlayNext,
+ Callable.From(_musicPlayerWantsPlayNextAction)
+ );
+ }
+ }
+ }
+
+ public static event Action MusicPlayerWantsPlayPreviousEvent;
+ static Action _musicPlayerWantsPlayPreviousAction = () =>
+ {
+ MusicPlayerWantsPlayPreviousEvent?.Invoke();
+ };
+ public static event Action MusicPlayerWantsPlayPrevious
+ {
+ add
+ {
+ if (MusicPlayerWantsPlayPreviousEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.MusicPlayerWantsPlayPrevious,
+ Callable.From(_musicPlayerWantsPlayPreviousAction)
+ );
+ }
+ MusicPlayerWantsPlayPreviousEvent += value;
+ }
+ remove
+ {
+ MusicPlayerWantsPlayPreviousEvent -= value;
+ if (MusicPlayerWantsPlayPreviousEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.MusicPlayerWantsPlayPrevious,
+ Callable.From(_musicPlayerWantsPlayPreviousAction)
+ );
+ }
+ }
+ }
+
+ public static event Action MusicPlayerWantsPlayEvent;
+ static Action _musicPlayerWantsPlayAction = () =>
+ {
+ MusicPlayerWantsPlayEvent?.Invoke();
+ };
+ public static event Action MusicPlayerWantsPlay
+ {
+ add
+ {
+ if (MusicPlayerWantsPlayEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.MusicPlayerWantsPlay,
+ Callable.From(_musicPlayerWantsPlayAction)
+ );
+ }
+ MusicPlayerWantsPlayEvent += value;
+ }
+ remove
+ {
+ MusicPlayerWantsPlayEvent -= value;
+ if (MusicPlayerWantsPlayEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.MusicPlayerWantsPlay,
+ Callable.From(_musicPlayerWantsPlayAction)
+ );
+ }
+ }
+ }
+
+ public delegate void MusicPlayerWantsShuffledEventHandler(bool shuffled);
+ private static event MusicPlayerWantsShuffledEventHandler MusicPlayerWantsShuffledEvent;
+ static Action _musicPlayerWantsShuffledAction = (shuffled) =>
+ {
+ MusicPlayerWantsShuffledEvent?.Invoke(shuffled);
+ };
+ public static event MusicPlayerWantsShuffledEventHandler MusicPlayerWantsShuffled
+ {
+ add
+ {
+ if (MusicPlayerWantsShuffledEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.MusicPlayerWantsShuffled,
+ Callable.From(_musicPlayerWantsShuffledAction)
+ );
+ }
+ MusicPlayerWantsShuffledEvent += value;
+ }
+ remove
+ {
+ MusicPlayerWantsShuffledEvent -= value;
+ if (MusicPlayerWantsShuffledEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.MusicPlayerWantsShuffled,
+ Callable.From(_musicPlayerWantsShuffledAction)
+ );
+ }
+ }
+ }
+
+ public delegate void MusicPlayerWantsVolumeEventHandler(double volume);
+ private static event MusicPlayerWantsVolumeEventHandler MusicPlayerWantsVolumeEvent;
+ static Action _musicPlayerWantsVolumeAction = (volume) =>
+ {
+ MusicPlayerWantsVolumeEvent?.Invoke(volume);
+ };
+ public static event MusicPlayerWantsVolumeEventHandler MusicPlayerWantsVolume
+ {
+ add
+ {
+ if (MusicPlayerWantsVolumeEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.MusicPlayerWantsVolume,
+ Callable.From(_musicPlayerWantsVolumeAction)
+ );
+ }
+ MusicPlayerWantsVolumeEvent += value;
+ }
+ remove
+ {
+ MusicPlayerWantsVolumeEvent -= value;
+ if (MusicPlayerWantsVolumeEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.MusicPlayerWantsVolume,
+ Callable.From(_musicPlayerWantsVolumeAction)
+ );
+ }
+ }
+ }
+
+ public static event Action MusicPlayerWillQuitEvent;
+ static Action _musicPlayerWillQuitAction = () =>
+ {
+ MusicPlayerWillQuitEvent?.Invoke();
+ };
+ public static event Action MusicPlayerWillQuit
+ {
+ add
+ {
+ if (MusicPlayerWillQuitEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.MusicPlayerWillQuit,
+ Callable.From(_musicPlayerWillQuitAction)
+ );
+ }
+ MusicPlayerWillQuitEvent += value;
+ }
+ remove
+ {
+ MusicPlayerWillQuitEvent -= value;
+ if (MusicPlayerWillQuitEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.MusicPlayerWillQuit,
+ Callable.From(_musicPlayerWillQuitAction)
+ );
+ }
+ }
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.MusicRemote.Signals.cs.uid b/addons/godotsteam_csharpbindings/Steam.MusicRemote.Signals.cs.uid
new file mode 100644
index 00000000..71d5ac7b
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.MusicRemote.Signals.cs.uid
@@ -0,0 +1 @@
+uid://c52be5fc77rje
diff --git a/addons/godotsteam_csharpbindings/Steam.MusicRemote.cs b/addons/godotsteam_csharpbindings/Steam.MusicRemote.cs
new file mode 100644
index 00000000..6ca1bd84
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.MusicRemote.cs
@@ -0,0 +1,164 @@
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public static bool ActivationSuccess(bool activate)
+ {
+ return GetInstance().Call(Methods.ActivationSuccess, activate).AsBool();
+ }
+
+ public static bool IsCurrentMusicRemote()
+ {
+ return GetInstance().Call(Methods.IsCurrentMusicRemote).AsBool();
+ }
+
+ public static bool CurrentEntryDidChange()
+ {
+ return GetInstance().Call(Methods.CurrentEntryDidChange).AsBool();
+ }
+
+ public static bool CurrentEntryIsAvailable(bool available)
+ {
+ return GetInstance().Call(Methods.CurrentEntryIsAvailable, available).AsBool();
+ }
+
+ public static bool CurrentEntryWillChange()
+ {
+ return GetInstance().Call(Methods.CurrentEntryWillChange).AsBool();
+ }
+
+ public static bool DeregisterSteamMusicRemote()
+ {
+ return GetInstance().Call(Methods.DeregisterSteamMusicRemote).AsBool();
+ }
+
+ public static bool EnableLooped(bool loop)
+ {
+ return GetInstance().Call(Methods.EnableLooped, loop).AsBool();
+ }
+
+ public static bool EnablePlaylists(bool playlists)
+ {
+ return GetInstance().Call(Methods.EnablePlaylists, playlists).AsBool();
+ }
+
+ public static bool EnablePlayNext(bool next)
+ {
+ return GetInstance().Call(Methods.EnablePlayNext, next).AsBool();
+ }
+
+ public static bool EnablePlayPrevious(bool previous)
+ {
+ return GetInstance().Call(Methods.EnablePlayPrevious, previous).AsBool();
+ }
+
+ public static bool EnableQueue(bool queue)
+ {
+ return GetInstance().Call(Methods.EnableQueue, queue).AsBool();
+ }
+
+ public static bool EnableShuffled(bool shuffle)
+ {
+ return GetInstance().Call(Methods.EnableShuffled, shuffle).AsBool();
+ }
+
+ public static bool PlaylistDidChange()
+ {
+ return GetInstance().Call(Methods.PlaylistDidChange).AsBool();
+ }
+
+ public static bool PlaylistWillChange()
+ {
+ return GetInstance().Call(Methods.PlaylistWillChange).AsBool();
+ }
+
+ public static bool QueueDidChange()
+ {
+ return GetInstance().Call(Methods.QueueDidChange).AsBool();
+ }
+
+ public static bool QueueWillChange()
+ {
+ return GetInstance().Call(Methods.QueueWillChange).AsBool();
+ }
+
+ public static bool RegisterSteamMusicRemote(string name)
+ {
+ return GetInstance().Call(Methods.RegisterSteamMusicRemote, name).AsBool();
+ }
+
+ public static bool ResetPlaylistEntries()
+ {
+ return GetInstance().Call(Methods.ResetPlaylistEntries).AsBool();
+ }
+
+ public static bool ResetQueueEntries()
+ {
+ return GetInstance().Call(Methods.ResetQueueEntries).AsBool();
+ }
+
+ public static bool SetCurrentPlaylistEntry(long id)
+ {
+ return GetInstance().Call(Methods.SetCurrentPlaylistEntry, id).AsBool();
+ }
+
+ public static bool SetCurrentQueueEntry(long id)
+ {
+ return GetInstance().Call(Methods.SetCurrentQueueEntry, id).AsBool();
+ }
+
+ public static bool SetDisplayName(string name)
+ {
+ return GetInstance().Call(Methods.SetDisplayName, name).AsBool();
+ }
+
+ public static bool SetPlaylistEntry(int id, int position, string entryText)
+ {
+ return GetInstance().Call(Methods.SetPlaylistEntry, id, position, entryText).AsBool();
+ }
+
+ public static bool SetPNGIcon64X64(byte[] icon)
+ {
+ return GetInstance().Call(Methods.SetPNGIcon64X64, icon).AsBool();
+ }
+
+ public static bool SetQueueEntry(int id, int position, string entryText)
+ {
+ return GetInstance().Call(Methods.SetQueueEntry, id, position, entryText).AsBool();
+ }
+
+ public static bool UpdateCurrentEntryCoverArt(byte[] art)
+ {
+ return GetInstance().Call(Methods.UpdateCurrentEntryCoverArt, art).AsBool();
+ }
+
+ public static bool UpdateCurrentEntryElapsedSeconds(long seconds)
+ {
+ return GetInstance().Call(Methods.UpdateCurrentEntryElapsedSeconds, seconds).AsBool();
+ }
+
+ public static bool UpdateCurrentEntryText(string text)
+ {
+ return GetInstance().Call(Methods.UpdateCurrentEntryText, text).AsBool();
+ }
+
+ public static bool UpdateLooped(bool looped)
+ {
+ return GetInstance().Call(Methods.UpdateLooped, looped).AsBool();
+ }
+
+ public static bool UpdatePlaybackStatus(AudioPlaybackStatus status)
+ {
+ return GetInstance().Call(Methods.UpdatePlaybackStatus, (long)status).AsBool();
+ }
+
+ public static bool UpdateShuffled(bool shuffle)
+ {
+ return GetInstance().Call(Methods.UpdateShuffled, shuffle).AsBool();
+ }
+
+ public static bool UpdateVolume(double volume)
+ {
+ return GetInstance().Call(Methods.UpdateVolume, volume).AsBool();
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.MusicRemote.cs.uid b/addons/godotsteam_csharpbindings/Steam.MusicRemote.cs.uid
new file mode 100644
index 00000000..978c55d0
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.MusicRemote.cs.uid
@@ -0,0 +1 @@
+uid://bm5bvq8mdvp6s
diff --git a/addons/godotsteam_csharpbindings/Steam.Networking.Signals.cs b/addons/godotsteam_csharpbindings/Steam.Networking.Signals.cs
new file mode 100644
index 00000000..8ade7708
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Networking.Signals.cs
@@ -0,0 +1,71 @@
+using System;
+using Godot;
+
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public delegate void P2PSessionRequestEventHandler(ulong steamIdRemote);
+ private static event P2PSessionRequestEventHandler P2PSessionRequestEvent;
+ static Action _p2pSessionRequestAction = (steamIdRemote) =>
+ {
+ P2PSessionRequestEvent?.Invoke(steamIdRemote);
+ };
+ public static event P2PSessionRequestEventHandler P2PSessionRequest
+ {
+ add
+ {
+ if (P2PSessionRequestEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.P2PSessionRequest, Callable.From(_p2pSessionRequestAction));
+ }
+ P2PSessionRequestEvent += value;
+ }
+ remove
+ {
+ P2PSessionRequestEvent -= value;
+ if (P2PSessionRequestEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.P2PSessionRequest, Callable.From(_p2pSessionRequestAction));
+ }
+ }
+ }
+
+ public delegate void P2PSessionConnectFailEventHandler(ulong steamIdRemote, long sessionError);
+ private static event P2PSessionConnectFailEventHandler P2PSessionConnectFailEvent;
+ static Action _p2pSessionConnectFailAction = (steamIdRemote, sessionError) =>
+ {
+ P2PSessionConnectFailEvent?.Invoke(steamIdRemote, sessionError);
+ };
+ public static event P2PSessionConnectFailEventHandler P2PSessionConnectFail
+ {
+ add
+ {
+ if (P2PSessionConnectFailEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.P2PSessionConnectFail,
+ Callable.From(_p2pSessionConnectFailAction)
+ );
+ }
+
+ P2PSessionConnectFailEvent += value;
+ }
+ remove
+ {
+ P2PSessionConnectFailEvent -= value;
+
+ if (P2PSessionConnectFailEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.P2PSessionConnectFail,
+ Callable.From(_p2pSessionConnectFailAction)
+ );
+ }
+ }
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.Networking.Signals.cs.uid b/addons/godotsteam_csharpbindings/Steam.Networking.Signals.cs.uid
new file mode 100644
index 00000000..29fe5698
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Networking.Signals.cs.uid
@@ -0,0 +1 @@
+uid://cejt4l4r6ovwe
diff --git a/addons/godotsteam_csharpbindings/Steam.Networking.cs b/addons/godotsteam_csharpbindings/Steam.Networking.cs
new file mode 100644
index 00000000..e80c5ae1
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Networking.cs
@@ -0,0 +1,91 @@
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public static bool AcceptP2PSessionWithUser(ulong steamIdRemote)
+ {
+ return GetInstance().Call(Methods.AcceptP2PSessionWithUser, steamIdRemote).AsBool();
+ }
+
+ public static bool AllowP2PPacketRelay(bool allow)
+ {
+ return GetInstance().Call(Methods.AllowP2PPacketRelay, allow).AsBool();
+ }
+
+ public static bool CloseP2PChannelWithUser(ulong steamIdRemote, long channel)
+ {
+ return GetInstance().Call(Methods.CloseP2PChannelWithUser, steamIdRemote, channel).AsBool();
+ }
+
+ public static bool CloseP2PSessionWithUser(ulong steamIdRemote)
+ {
+ return GetInstance().Call(Methods.CloseP2PSessionWithUser, steamIdRemote).AsBool();
+ }
+
+ public static Godot.Collections.Dictionary GetP2PSessionState(ulong steamIdRemote)
+ {
+ return GetInstance().Call(Methods.GetP2PSessionState, steamIdRemote).AsGodotDictionary();
+ }
+
+ public static uint GetAvailableP2PPacketSize(long channel = 0)
+ {
+ return GetInstance().Call(Methods.GetAvailableP2PPacketSize, channel).AsUInt32();
+ }
+
+ public static Godot.Collections.Dictionary ReadP2PPacket(uint packet, long channel = 0)
+ {
+ return GetInstance().Call(Methods.ReadP2PPacket, packet, channel).AsGodotDictionary();
+ }
+
+ public static bool SendP2PPacket(
+ ulong steamIdRemote,
+ byte[] data,
+ P2PSend sendType,
+ long channel = 0
+ )
+ {
+ return GetInstance()
+ .Call(Methods.SendP2PPacket, steamIdRemote, data, (long)sendType, channel)
+ .AsBool();
+ }
+
+ public enum P2PSend : long
+ {
+ Unreliable = 0,
+ UnreliableNoDelay = 1,
+ Reliable = 2,
+ ReliableWithBuffering = 3,
+ }
+
+ public enum P2PSessionError : long
+ {
+ None = 0,
+ NotRunningApp = 1,
+ NoRightsToApp = 2,
+ DestinationNotLoggedOn = 3,
+ Timeout = 4,
+ Max = 5,
+ }
+
+ public enum SocketConnectionType : long
+ {
+ NotConnected = 0,
+ Udp = 1,
+ UdpRelay = 2,
+ }
+
+ public enum SocketState : long
+ {
+ Invalid = 0,
+ Connected = 1,
+ Initiated = 10,
+ LocalCandidateFound = 11,
+ ReceivedRemoteCandidates = 12,
+ ChallengeHandshake = 15,
+ Disconnecting = 21,
+ LocalDisconnect = 22,
+ TimeoutDuringConnect = 23,
+ RemoteEndDisconnected = 24,
+ Broken = 25,
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.Networking.cs.uid b/addons/godotsteam_csharpbindings/Steam.Networking.cs.uid
new file mode 100644
index 00000000..c8d8d9a0
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Networking.cs.uid
@@ -0,0 +1 @@
+uid://bax0l1e44v8nc
diff --git a/addons/godotsteam_csharpbindings/Steam.NetworkingMessages.Signals.cs b/addons/godotsteam_csharpbindings/Steam.NetworkingMessages.Signals.cs
new file mode 100644
index 00000000..45b6cc20
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.NetworkingMessages.Signals.cs
@@ -0,0 +1,77 @@
+using System;
+using Godot;
+
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public delegate void NetworkMessagesSessionRequestEventHandler(ulong remoteSteamId);
+ private static event NetworkMessagesSessionRequestEventHandler NetworkMessagesSessionRequestEvent;
+ static Action _networkMessagesSessionRequestAction = (remoteSteamId) =>
+ {
+ NetworkMessagesSessionRequestEvent?.Invoke(remoteSteamId);
+ };
+ public static event NetworkMessagesSessionRequestEventHandler NetworkMessagesSessionRequest
+ {
+ add
+ {
+ if (NetworkMessagesSessionRequestEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.NetworkMessagesSessionRequest,
+ Callable.From(_networkMessagesSessionRequestAction)
+ );
+ }
+
+ NetworkMessagesSessionRequestEvent += value;
+ }
+ remove
+ {
+ NetworkMessagesSessionRequestEvent -= value;
+
+ if (NetworkMessagesSessionRequestEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.NetworkMessagesSessionRequest,
+ Callable.From(_networkMessagesSessionRequestAction)
+ );
+ }
+ }
+ }
+
+ public delegate void NetworkMessagesSessionFailedEventHandler(long reason);
+ private static event NetworkMessagesSessionFailedEventHandler NetworkMessagesSessionFailedEvent;
+ static Action _networkMessagesSessionFailedAction = (reason) =>
+ {
+ NetworkMessagesSessionFailedEvent?.Invoke(reason);
+ };
+ public static event NetworkMessagesSessionFailedEventHandler NetworkMessagesSessionFailed
+ {
+ add
+ {
+ if (NetworkMessagesSessionFailedEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.NetworkMessagesSessionFailed,
+ Callable.From(_networkMessagesSessionFailedAction)
+ );
+ }
+ NetworkMessagesSessionFailedEvent += value;
+ }
+ remove
+ {
+ NetworkMessagesSessionFailedEvent -= value;
+ if (NetworkMessagesSessionFailedEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.NetworkMessagesSessionFailed,
+ Callable.From(_networkMessagesSessionFailedAction)
+ );
+ }
+ }
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.NetworkingMessages.Signals.cs.uid b/addons/godotsteam_csharpbindings/Steam.NetworkingMessages.Signals.cs.uid
new file mode 100644
index 00000000..dab77d05
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.NetworkingMessages.Signals.cs.uid
@@ -0,0 +1 @@
+uid://mgfn4h0cag30
diff --git a/addons/godotsteam_csharpbindings/Steam.NetworkingMessages.cs b/addons/godotsteam_csharpbindings/Steam.NetworkingMessages.cs
new file mode 100644
index 00000000..0bbb30d0
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.NetworkingMessages.cs
@@ -0,0 +1,44 @@
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public static bool AcceptSessionWithUser(ulong remoteSteamId)
+ {
+ return GetInstance().Call(Methods.AcceptSessionWithUser, remoteSteamId).AsBool();
+ }
+
+ public static bool CloseChannelWithUser(ulong remoteSteamId, long channel)
+ {
+ return GetInstance().Call(Methods.CloseChannelWithUser, remoteSteamId, channel).AsBool();
+ }
+
+ public static bool CloseSessionWithUser(ulong remoteSteamId)
+ {
+ return GetInstance().Call(Methods.CloseSessionWithUser, remoteSteamId).AsBool();
+ }
+
+ public static Godot.Collections.Dictionary GetSessionConnectionInfo(
+ ulong remoteSteamId,
+ bool getConnection,
+ bool getStatus
+ )
+ {
+ return GetInstance()
+ .Call(Methods.GetSessionConnectionInfo, remoteSteamId, getConnection, getStatus)
+ .AsGodotDictionary();
+ }
+
+ public static Godot.Collections.Array ReceiveMessagesOnChannel(int channel, long maxMessages)
+ {
+ return GetInstance()
+ .Call(Methods.ReceiveMessagesOnChannel, channel, maxMessages)
+ .AsGodotArray();
+ }
+
+ public static int SendMessageToUser(ulong remoteSteamId, byte[] data, int flags, long channel)
+ {
+ return GetInstance()
+ .Call(Methods.SendMessageToUser, remoteSteamId, data, flags, channel)
+ .AsInt32();
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.NetworkingMessages.cs.uid b/addons/godotsteam_csharpbindings/Steam.NetworkingMessages.cs.uid
new file mode 100644
index 00000000..5ce98eb8
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.NetworkingMessages.cs.uid
@@ -0,0 +1 @@
+uid://cnj17tpleg05p
diff --git a/addons/godotsteam_csharpbindings/Steam.NetworkingSockets.Signals.cs b/addons/godotsteam_csharpbindings/Steam.NetworkingSockets.Signals.cs
new file mode 100644
index 00000000..0634b338
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.NetworkingSockets.Signals.cs
@@ -0,0 +1,125 @@
+using System;
+using Godot;
+
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public delegate void NetworkConnectionStatusChangedEventHandler(
+ long connectHandle,
+ Godot.Collections.Dictionary connection,
+ long oldState
+ );
+ private static event NetworkConnectionStatusChangedEventHandler NetworkConnectionStatusChangedEvent;
+ static Action _networkConnectionStatusChangedAction =
+ (connectHandle, connection, oldState) =>
+ {
+ NetworkConnectionStatusChangedEvent?.Invoke(connectHandle, connection, oldState);
+ };
+ public static event NetworkConnectionStatusChangedEventHandler NetworkConnectionStatusChanged
+ {
+ add
+ {
+ if (NetworkConnectionStatusChangedEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.NetworkConnectionStatusChanged,
+ Callable.From(_networkConnectionStatusChangedAction)
+ );
+ }
+
+ NetworkConnectionStatusChangedEvent += value;
+ }
+ remove
+ {
+ NetworkConnectionStatusChangedEvent -= value;
+
+ if (NetworkConnectionStatusChangedEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.NetworkConnectionStatusChanged,
+ Callable.From(_networkConnectionStatusChangedAction)
+ );
+ }
+ }
+ }
+
+ public delegate void NetworkAuthenticationStatusEventHandler(
+ long available,
+ string debugMessage
+ );
+ private static event NetworkAuthenticationStatusEventHandler NetworkAuthenticationStatusEvent;
+ static Action _networkAuthenticationStatusAction = (available, debugMessage) =>
+ {
+ NetworkAuthenticationStatusEvent?.Invoke(available, debugMessage);
+ };
+ public static event NetworkAuthenticationStatusEventHandler NetworkAuthenticationStatus
+ {
+ add
+ {
+ if (NetworkAuthenticationStatusEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.NetworkAuthenticationStatus,
+ Callable.From(_networkAuthenticationStatusAction)
+ );
+ }
+
+ NetworkAuthenticationStatusEvent += value;
+ }
+ remove
+ {
+ NetworkAuthenticationStatusEvent -= value;
+
+ if (NetworkAuthenticationStatusEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.NetworkAuthenticationStatus,
+ Callable.From(_networkAuthenticationStatusAction)
+ );
+ }
+ }
+ }
+
+ public delegate void FakeIPResultEventHandler(
+ long result,
+ string identity,
+ string fakeIP,
+ Godot.Collections.Array portList
+ );
+ private static event FakeIPResultEventHandler FakeIPResultEvent;
+ static Action _fakeIPResultAction = (
+ result,
+ identity,
+ fakeIP,
+ portList
+ ) =>
+ {
+ FakeIPResultEvent?.Invoke(result, identity, fakeIP, portList);
+ };
+ public static event FakeIPResultEventHandler FakeIPResult
+ {
+ add
+ {
+ if (FakeIPResultEvent == null)
+ {
+ GetInstance().Connect(Signals.FakeIPResult, Callable.From(_fakeIPResultAction));
+ }
+
+ FakeIPResultEvent += value;
+ }
+ remove
+ {
+ FakeIPResultEvent -= value;
+
+ if (FakeIPResultEvent == null)
+ {
+ GetInstance().Disconnect(Signals.FakeIPResult, Callable.From(_fakeIPResultAction));
+ }
+ }
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.NetworkingSockets.Signals.cs.uid b/addons/godotsteam_csharpbindings/Steam.NetworkingSockets.Signals.cs.uid
new file mode 100644
index 00000000..27f545fc
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.NetworkingSockets.Signals.cs.uid
@@ -0,0 +1 @@
+uid://dt42f0ldop5ns
diff --git a/addons/godotsteam_csharpbindings/Steam.NetworkingSockets.cs b/addons/godotsteam_csharpbindings/Steam.NetworkingSockets.cs
new file mode 100644
index 00000000..587c74cc
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.NetworkingSockets.cs
@@ -0,0 +1,436 @@
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public static int AcceptConnection(long connection)
+ {
+ return GetInstance().Call(Methods.AcceptConnection, connection).AsInt32();
+ }
+
+ public static bool BeginAsyncRequestFakeIP(long numPorts)
+ {
+ return GetInstance().Call(Methods.BeginAsyncRequestFakeIP, numPorts).AsBool();
+ }
+
+ public static bool CloseConnection(uint peer, int reason, string debugMessage, bool linger)
+ {
+ return GetInstance()
+ .Call(Methods.CloseConnection, peer, reason, debugMessage, linger)
+ .AsBool();
+ }
+
+ public static bool CloseListenSocket(long socket)
+ {
+ return GetInstance().Call(Methods.CloseListenSocket, socket).AsBool();
+ }
+
+ public static int ConfigureConnectionLanes(
+ uint connection,
+ int lanes,
+ Godot.Collections.Array priorities,
+ Godot.Collections.Array weights
+ )
+ {
+ return GetInstance()
+ .Call(Methods.ConfigureConnectionLanes, connection, lanes, priorities, weights)
+ .AsInt32();
+ }
+
+ public static uint ConnectP2P(
+ string identityReference,
+ int virtualPort,
+ Godot.Collections.Array options
+ )
+ {
+ return GetInstance()
+ .Call(Methods.ConnectP2P, identityReference, virtualPort, options)
+ .AsUInt32();
+ }
+
+ public static uint ConnectByIPAddress(string iPAddressWithPort, Godot.Collections.Array options)
+ {
+ return GetInstance()
+ .Call(Methods.ConnectByIPAddress, iPAddressWithPort, options)
+ .AsUInt32();
+ }
+
+ public static uint ConnectToHostedDedicatedServer(
+ string identityReference,
+ int virtualPort,
+ Godot.Collections.Array options
+ )
+ {
+ return GetInstance()
+ .Call(Methods.ConnectToHostedDedicatedServer, identityReference, virtualPort, options)
+ .AsUInt32();
+ }
+
+ public static void CreateFakeUDPPort(long fakeServerPort)
+ {
+ GetInstance().Call(Methods.CreateFakeUDPPort, fakeServerPort);
+ }
+
+ public static uint CreateHostedDedicatedServerListenSocket(
+ int virtualPort,
+ Godot.Collections.Array options
+ )
+ {
+ return GetInstance()
+ .Call(Methods.CreateHostedDedicatedServerListenSocket, virtualPort, options)
+ .AsUInt32();
+ }
+
+ public static uint CreateListenSocketIP(string iPReference, Godot.Collections.Array options)
+ {
+ return GetInstance().Call(Methods.CreateListenSocketIP, iPReference, options).AsUInt32();
+ }
+
+ public static uint CreateListenSocketP2P(int virtualPort, Godot.Collections.Array options)
+ {
+ return GetInstance().Call(Methods.CreateListenSocketP2P, virtualPort, options).AsUInt32();
+ }
+
+ public static uint CreateListenSocketP2PFakeIP(int fakePort, Godot.Collections.Array options)
+ {
+ return GetInstance()
+ .Call(Methods.CreateListenSocketP2PFakeIP, fakePort, options)
+ .AsUInt32();
+ }
+
+ public static long CreatePollGroup()
+ {
+ return GetInstance().Call(Methods.CreatePollGroup).AsInt64();
+ }
+
+ public static Godot.Collections.Dictionary CreateSocketPair(
+ bool loopback,
+ string identityReference1,
+ string identityReference2
+ )
+ {
+ return GetInstance()
+ .Call(Methods.CreateSocketPair, loopback, identityReference1, identityReference2)
+ .AsGodotDictionary();
+ }
+
+ public static bool DestroyPollGroup(long pollGroup)
+ {
+ return GetInstance().Call(Methods.DestroyPollGroup, pollGroup).AsBool();
+ }
+
+ public static int FlushMessagesOnConnection(long connectionHandle)
+ {
+ return GetInstance().Call(Methods.FlushMessagesOnConnection, connectionHandle).AsInt32();
+ }
+
+ public static NetworkingAvailability GetAuthenticationStatus()
+ {
+ return (NetworkingAvailability)
+ GetInstance().Call(Methods.GetAuthenticationStatus).AsInt64();
+ }
+
+ public static Godot.Collections.Dictionary GetCertificateRequest()
+ {
+ return GetInstance().Call(Methods.GetCertificateRequest).AsGodotDictionary();
+ }
+
+ public static Godot.Collections.Dictionary GetConnectionInfo(long connectionHandle)
+ {
+ return GetInstance().Call(Methods.GetConnectionInfo, connectionHandle).AsGodotDictionary();
+ }
+
+ public static string GetConnectionName(long peer)
+ {
+ return GetInstance().Call(Methods.GetConnectionName, peer).AsString();
+ }
+
+ public static Godot.Collections.Dictionary GetConnectionRealTimeStatus(
+ uint connectionHandle,
+ int lanes,
+ bool getStatus = true
+ )
+ {
+ return GetInstance()
+ .Call(Methods.GetConnectionRealTimeStatus, connectionHandle, lanes, getStatus)
+ .AsGodotDictionary();
+ }
+
+ public static ulong GetConnectionUserData(long peer)
+ {
+ return GetInstance().Call(Methods.GetConnectionUserData, peer).AsUInt64();
+ }
+
+ public static Godot.Collections.Dictionary GetDetailedConnectionStatus(long connectionHandle)
+ {
+ return GetInstance()
+ .Call(Methods.GetDetailedConnectionStatus, connectionHandle)
+ .AsGodotDictionary();
+ }
+
+ public static Godot.Collections.Dictionary GetFakeIP(long firstPort = 0)
+ {
+ return GetInstance().Call(Methods.GetFakeIP, firstPort).AsGodotDictionary();
+ }
+
+ public static long GetHostedDedicatedServerPOPId()
+ {
+ return GetInstance().Call(Methods.GetHostedDedicatedServerPOPId).AsInt64();
+ }
+
+ public static long GetHostedDedicatedServerPort()
+ {
+ return GetInstance().Call(Methods.GetHostedDedicatedServerPort).AsInt64();
+ }
+
+ public static string GetListenSocketAddress(uint socket, bool withPort = true)
+ {
+ return GetInstance().Call(Methods.GetListenSocketAddress, socket, withPort).AsString();
+ }
+
+ public static string GetIdentity()
+ {
+ return GetInstance().Call(Methods.GetIdentity).AsString();
+ }
+
+ public static Godot.Collections.Dictionary GetRemoteFakeIPForConnection(long connection)
+ {
+ return GetInstance()
+ .Call(Methods.GetRemoteFakeIPForConnection, connection)
+ .AsGodotDictionary();
+ }
+
+ public static NetworkingAvailability InitAuthentication()
+ {
+ return (NetworkingAvailability)GetInstance().Call(Methods.InitAuthentication).AsInt64();
+ }
+
+ public static Godot.Collections.Array ReceiveMessagesOnConnection(
+ uint connection,
+ long maxMessages
+ )
+ {
+ return GetInstance()
+ .Call(Methods.ReceiveMessagesOnConnection, connection, maxMessages)
+ .AsGodotArray();
+ }
+
+ public static Godot.Collections.Array ReceiveMessagesOnPollGroup(
+ uint pollGroup,
+ long maxMessages
+ )
+ {
+ return GetInstance()
+ .Call(Methods.ReceiveMessagesOnPollGroup, pollGroup, maxMessages)
+ .AsGodotArray();
+ }
+
+ public static void ResetIdentity(string thisIdentity)
+ {
+ GetInstance().Call(Methods.ResetIdentity, thisIdentity);
+ }
+
+ public static void RunNetworkingCallbacks()
+ {
+ GetInstance().Call(Methods.RunNetworkingCallbacks);
+ }
+
+ public static void SendMessages(int messages, byte[] data, uint connectionHandle, long flags)
+ {
+ GetInstance().Call(Methods.SendMessages, messages, data, connectionHandle, flags);
+ }
+
+ public static Godot.Collections.Dictionary SendMessageToConnection(
+ uint connectionHandle,
+ byte[] data,
+ long flags
+ )
+ {
+ return GetInstance()
+ .Call(Methods.SendMessageToConnection, connectionHandle, data, flags)
+ .AsGodotDictionary();
+ }
+
+ public static Godot.Collections.Dictionary SetCertificate(byte[] certificate)
+ {
+ return GetInstance().Call(Methods.SetCertificate, certificate).AsGodotDictionary();
+ }
+
+ public static bool SetConnectionPollGroup(uint connectionHandle, long pollGroup)
+ {
+ return GetInstance()
+ .Call(Methods.SetConnectionPollGroup, connectionHandle, pollGroup)
+ .AsBool();
+ }
+
+ public static void SetConnectionName(uint peer, string name)
+ {
+ GetInstance().Call(Methods.SetConnectionName, peer, name);
+ }
+
+ public enum NetworkingConfigValue : long
+ {
+ Invalid = 0,
+ FakePacketLossSend = 2,
+ FakePacketLossRecv = 3,
+ FakePacketLagSend = 4,
+ FakePacketLagRecv = 5,
+ FakePacketReorderSend = 6,
+ FakePacketReorderRecv = 7,
+ FakePacketReorderTime = 8,
+ FakePacketDupSend = 26,
+ FakePacketDupRevc = 27,
+ FakePacketDupTimeMax = 28,
+ PacketTraceMaxBytes = 41,
+ FakeRateLimitSendRate = 42,
+ FakeRateLimitSendBurst = 43,
+ FakeRateLimitRecvRate = 44,
+ FakeRateLimitRecvBurst = 45,
+ ConnectionUserData = 40,
+ TimeoutInitial = 24,
+ TimeoutConnected = 25,
+ SendBufferSize = 9,
+ RecvBufferSize = 47,
+ RecvBufferMessages = 48,
+ RecvMaxMessageSize = 49,
+ RecvMaxSegmentsPerPacket = 50,
+ SendRateMin = 10,
+ SendRateMax = 11,
+ NagleTime = 12,
+ IPAllowWithoutAuth = 23,
+ MtuPacketSize = 32,
+ MtuDataSize = 33,
+ Unencrypted = 34,
+ SymmetricConnect = 37,
+ LocalVirtualPort = 38,
+ DualWifiEnable = 39,
+ EnableDiagnosticsUi = 46,
+ SdrClientConsecPingTimeoutFailInitial = 19,
+ SdrClientConsecPingTimeoutFail = 20,
+ SdrClientMinPingsBeforePingAccurate = 21,
+ SdrClientSingleSocket = 22,
+ SdrClientForceRelayCluster = 29,
+ SdrClientDebugTicketAddress = 30,
+ SdrClientForceProxyAddr = 31,
+ SdrClientFakeClusterPing = 36,
+ LogLevelAckRtt = 13,
+ LogLevelPacketDecode = 14,
+ LogLevelMessage = 15,
+ LogLevelPacketGaps = 16,
+ LogLevelP2PRendezvous = 17,
+ LogLevelSrdRelayPings = 18,
+ CallbackConnectionStatusChanged = 201,
+ CallbackAuthStatusChanged = 202,
+ CallbackRelayNetworkStatusChanged = 203,
+ CallbackMessageSessionRequest = 204,
+ CallbackMessagesSessionFailed = 205,
+ CallbackCreateConnectionSignaling = 206,
+ CallbackFakeIPResult = 207,
+ P2PStunServerList = 103,
+ P2PTransportIceEnable = 104,
+ P2PTransportIcePenalty = 105,
+ P2PTransportSdrPenalty = 106,
+ P2PTurnServerList = 107,
+ P2PTurnUserList = 108,
+ P2PTurnPassList = 109,
+ P2PTransportIceImplementation = 110,
+ ValueForce32Bit = 2147483647,
+ }
+
+ public enum NetworkingConnectionEnd : long
+ {
+ Invalid = 0,
+ AppMin = 1000,
+ AppGeneric = 1000,
+ AppMax = 1999,
+ AppExceptionMin = 2000,
+ AppExceptionGeneric = 2000,
+ AppExceptionMax = 2999,
+ LocalMin = 3000,
+ LocalOfflineMode = 3001,
+ LocalManyRelayConnectivity = 3002,
+ LocalHostedServerPrimaryRelay = 3003,
+ LocalNetworkConfig = 3004,
+ LocalRights = 3005,
+ NoPublicAddress = 3006,
+ LocalMax = 3999,
+ RemoveMin = 4000,
+ RemoteTimeout = 4001,
+ RemoteBadCrypt = 4002,
+ RemoteBadCert = 4003,
+ BadProtocolVersion = 4006,
+ RemoteP2PIceNoPublicAddresses = 4007,
+ RemoteMax = 4999,
+ MiscMin = 5000,
+ MiscGeneric = 5001,
+ MiscInternalError = 5002,
+ MiscTimeout = 5003,
+ MiscSteamConnectivity = 5005,
+ MiscNoRelaySessionsToClient = 5006,
+ MiscP2PRendezvous = 5008,
+ MiscP2PNatFirewall = 5009,
+ MiscPeerSentNoConnection = 5010,
+ MiscMax = 5999,
+ Force32Bit = 2147483647,
+ }
+
+ public enum NetworkingConnectionState : long
+ {
+ None = 0,
+ Connecting = 1,
+ FindingRoute = 2,
+ Connected = 3,
+ ClosedByPeer = 4,
+ ProblemDetectedLocally = 5,
+ FinWait = -1,
+ Linger = -2,
+ Dead = -3,
+ Force32Bit = 2147483647,
+ }
+
+ public enum NetworkingFakeIPType : long
+ {
+ Invalid = 0,
+ NotFake = 1,
+ GlobalIpv4 = 2,
+ LocalIpv4 = 3,
+ Force32Bit = 2147483647,
+ }
+
+ public enum NetworkingGetConfigValueResult : long
+ {
+ BadValue = -1,
+ BadScopeObj = -2,
+ BufferTooSmall = -3,
+ Ok = 1,
+ OkInherited = 2,
+ Force32Bit = 2147483647,
+ }
+
+ public enum NetworkingIdentityType : long
+ {
+ Invalid = 0,
+ Steamid = 16,
+ IPAddress = 1,
+ GenericString = 2,
+ GenericBytes = 3,
+ UnknownType = 4,
+ XboxPairwise = 17,
+ SonyPsn = 18,
+ GoogleStadia = 19,
+ Force32Bit = 2147483647,
+ }
+
+ public enum NetworkingSocketsDebugOutputType : long
+ {
+ None = 0,
+ Bug = 1,
+ Error = 2,
+ Important = 3,
+ Warning = 4,
+ Msg = 5,
+ Verbose = 6,
+ Debug = 7,
+ Everything = 8,
+ Force32Bit = 2147483647,
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.NetworkingSockets.cs.uid b/addons/godotsteam_csharpbindings/Steam.NetworkingSockets.cs.uid
new file mode 100644
index 00000000..72c0ba72
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.NetworkingSockets.cs.uid
@@ -0,0 +1 @@
+uid://bq4r0eftdkv0a
diff --git a/addons/godotsteam_csharpbindings/Steam.NetworkingTypes.cs b/addons/godotsteam_csharpbindings/Steam.NetworkingTypes.cs
new file mode 100644
index 00000000..4760f827
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.NetworkingTypes.cs
@@ -0,0 +1,188 @@
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public static bool AddIdentity(string referenceName)
+ {
+ return GetInstance().Call(Methods.AddIdentity, referenceName).AsBool();
+ }
+
+ public static bool AddIPAddress(string referenceName)
+ {
+ return GetInstance().Call(Methods.AddIPAddress, referenceName).AsBool();
+ }
+
+ public static void ClearIdentity(string referenceName)
+ {
+ GetInstance().Call(Methods.ClearIdentity, referenceName);
+ }
+
+ public static void ClearIPAddress(string referenceName)
+ {
+ GetInstance().Call(Methods.ClearIPAddress, referenceName);
+ }
+
+ public static byte GetGenericBytes(string referenceName)
+ {
+ return GetInstance().Call(Methods.GetGenericBytes, referenceName).AsByte();
+ }
+
+ public static string GetGenericString(string referenceName)
+ {
+ return GetInstance().Call(Methods.GetGenericString, referenceName).AsString();
+ }
+
+ public static Godot.Collections.Array GetIdentities()
+ {
+ return GetInstance().Call(Methods.GetIdentities).AsGodotArray();
+ }
+
+ public static uint GetIdentityIPAddr(string referenceName)
+ {
+ return GetInstance().Call(Methods.GetIdentityIPAddr, referenceName).AsUInt32();
+ }
+
+ public static uint GetIdentitySteamID(string referenceName)
+ {
+ return GetInstance().Call(Methods.GetIdentitySteamID, referenceName).AsUInt32();
+ }
+
+ public static ulong GetIdentitySteamID64(string referenceName)
+ {
+ return GetInstance().Call(Methods.GetIdentitySteamID64, referenceName).AsUInt64();
+ }
+
+ public static Godot.Collections.Array GetIPAddresses()
+ {
+ return GetInstance().Call(Methods.GetIPAddresses).AsGodotArray();
+ }
+
+ public static uint GetIPv4(string referenceName)
+ {
+ return GetInstance().Call(Methods.GetIPv4, referenceName).AsUInt32();
+ }
+
+ public static ulong GetPSNID(string referenceName)
+ {
+ return GetInstance().Call(Methods.GetPSNID, referenceName).AsUInt64();
+ }
+
+ public static ulong GetStadiaID(string referenceName)
+ {
+ return GetInstance().Call(Methods.GetStadiaID, referenceName).AsUInt64();
+ }
+
+ public static string GetXboxPairwiseID(string referenceName)
+ {
+ return GetInstance().Call(Methods.GetXboxPairwiseID, referenceName).AsString();
+ }
+
+ public static bool IsAddressLocalHost(string referenceName)
+ {
+ return GetInstance().Call(Methods.IsAddressLocalHost, referenceName).AsBool();
+ }
+
+ public static bool IsIdentityInvalid(string referenceName)
+ {
+ return GetInstance().Call(Methods.IsIdentityInvalid, referenceName).AsBool();
+ }
+
+ public static bool IsIdentityLocalHost(string referenceName)
+ {
+ return GetInstance().Call(Methods.IsIdentityLocalHost, referenceName).AsBool();
+ }
+
+ public static bool IsIPv4(string referenceName)
+ {
+ return GetInstance().Call(Methods.IsIPv4, referenceName).AsBool();
+ }
+
+ public static bool IsIPv6AllZeros(string referenceName)
+ {
+ return GetInstance().Call(Methods.IsIPv6AllZeros, referenceName).AsBool();
+ }
+
+ public static bool ParseIdentityString(string referenceName, string stringToParse)
+ {
+ return GetInstance()
+ .Call(Methods.ParseIdentityString, referenceName, stringToParse)
+ .AsBool();
+ }
+
+ public static bool ParseIPAddressString(string referenceName, string stringToParse)
+ {
+ return GetInstance()
+ .Call(Methods.ParseIPAddressString, referenceName, stringToParse)
+ .AsBool();
+ }
+
+ public static bool SetGenericBytes(string referenceName, long data)
+ {
+ return GetInstance().Call(Methods.SetGenericBytes, referenceName, data).AsBool();
+ }
+
+ public static bool SetGenericString(string referenceName, string thisString)
+ {
+ return GetInstance().Call(Methods.SetGenericString, referenceName, thisString).AsBool();
+ }
+
+ public static bool SetIdentityIPAddr(string referenceName, string iPAddressName)
+ {
+ return GetInstance().Call(Methods.SetIdentityIPAddr, referenceName, iPAddressName).AsBool();
+ }
+
+ public static void SetIdentityLocalHost(string referenceName)
+ {
+ GetInstance().Call(Methods.SetIdentityLocalHost, referenceName);
+ }
+
+ public static void SetIdentitySteamID(string referenceName, ulong steamId)
+ {
+ GetInstance().Call(Methods.SetIdentitySteamID, referenceName, steamId);
+ }
+
+ public static void SetIdentitySteamID64(string referenceName, ulong steamId)
+ {
+ GetInstance().Call(Methods.SetIdentitySteamID64, referenceName, steamId);
+ }
+
+ public static void SetIPv4(string referenceName, uint iP, long port)
+ {
+ GetInstance().Call(Methods.SetIPv4, referenceName, iP, port);
+ }
+
+ public static void SetIPv6(string referenceName, int ipv6, long port)
+ {
+ GetInstance().Call(Methods.SetIPv6, referenceName, ipv6, port);
+ }
+
+ public static void SetIPv6LocalHost(string referenceName, long port = 0)
+ {
+ GetInstance().Call(Methods.SetIPv6LocalHost, referenceName, port);
+ }
+
+ public static void SetPSNID(string referenceName, long psnId)
+ {
+ GetInstance().Call(Methods.SetPSNID, referenceName, psnId);
+ }
+
+ public static void SetStadiaID(string referenceName, long stadiaId)
+ {
+ GetInstance().Call(Methods.SetStadiaID, referenceName, stadiaId);
+ }
+
+ public static bool SetXboxPairwiseID(string referenceName, string xboxId)
+ {
+ return GetInstance().Call(Methods.SetXboxPairwiseID, referenceName, xboxId).AsBool();
+ }
+
+ public static string ToIdentityString(string referenceName)
+ {
+ return GetInstance().Call(Methods.ToIdentityString, referenceName).AsString();
+ }
+
+ public static string ToIPAddressString(string referenceName, bool withPort)
+ {
+ return GetInstance().Call(Methods.ToIPAddressString, referenceName, withPort).AsString();
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.NetworkingTypes.cs.uid b/addons/godotsteam_csharpbindings/Steam.NetworkingTypes.cs.uid
new file mode 100644
index 00000000..5c18e6fd
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.NetworkingTypes.cs.uid
@@ -0,0 +1 @@
+uid://50uq51ln4jmh
diff --git a/addons/godotsteam_csharpbindings/Steam.NetworkingUtils.Signals.cs b/addons/godotsteam_csharpbindings/Steam.NetworkingUtils.Signals.cs
new file mode 100644
index 00000000..17a26151
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.NetworkingUtils.Signals.cs
@@ -0,0 +1,58 @@
+using System;
+using Godot;
+
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public delegate void RelayNetworkStatusEventHandler(
+ long available,
+ long pingMeasurement,
+ long availableConfig,
+ long availableRelay,
+ string debugMessage
+ );
+ private static event RelayNetworkStatusEventHandler RelayNetworkStatusEvent;
+ static Action _relayNetworkStatusAction = (
+ available,
+ pingMeasurement,
+ availableConfig,
+ availableRelay,
+ debugMessage
+ ) =>
+ {
+ RelayNetworkStatusEvent?.Invoke(
+ available,
+ pingMeasurement,
+ availableConfig,
+ availableRelay,
+ debugMessage
+ );
+ };
+ public static event RelayNetworkStatusEventHandler RelayNetworkStatus
+ {
+ add
+ {
+ if (RelayNetworkStatusEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.RelayNetworkStatus, Callable.From(_relayNetworkStatusAction));
+ }
+
+ RelayNetworkStatusEvent += value;
+ }
+ remove
+ {
+ RelayNetworkStatusEvent -= value;
+
+ if (RelayNetworkStatusEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.RelayNetworkStatus,
+ Callable.From(_relayNetworkStatusAction)
+ );
+ }
+ }
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.NetworkingUtils.Signals.cs.uid b/addons/godotsteam_csharpbindings/Steam.NetworkingUtils.Signals.cs.uid
new file mode 100644
index 00000000..19f0a585
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.NetworkingUtils.Signals.cs.uid
@@ -0,0 +1 @@
+uid://b3bca6mtbsmrq
diff --git a/addons/godotsteam_csharpbindings/Steam.NetworkingUtils.cs b/addons/godotsteam_csharpbindings/Steam.NetworkingUtils.cs
new file mode 100644
index 00000000..ab12b209
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.NetworkingUtils.cs
@@ -0,0 +1,170 @@
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public static bool CheckPingDataUpToDate(double maxAgeInSeconds)
+ {
+ return GetInstance().Call(Methods.CheckPingDataUpToDate, maxAgeInSeconds).AsBool();
+ }
+
+ public static string ConvertPingLocationToString(byte[] location)
+ {
+ return GetInstance().Call(Methods.ConvertPingLocationToString, location).AsString();
+ }
+
+ public static int EstimatePingTimeBetweenTwoLocations(byte[] location1, byte[] location2)
+ {
+ return GetInstance()
+ .Call(Methods.EstimatePingTimeBetweenTwoLocations, location1, location2)
+ .AsInt32();
+ }
+
+ public static int EstimatePingTimeFromLocalHost(byte[] location)
+ {
+ return GetInstance().Call(Methods.EstimatePingTimeFromLocalHost, location).AsInt32();
+ }
+
+ public static Godot.Collections.Dictionary GetConfigValue(
+ NetworkingConfigValue configValue,
+ NetworkingConfigScope scopeType,
+ long connectionHandle
+ )
+ {
+ return GetInstance()
+ .Call(Methods.GetConfigValue, (long)configValue, (long)scopeType, connectionHandle)
+ .AsGodotDictionary();
+ }
+
+ public static Godot.Collections.Dictionary GetConfigValueInfo(NetworkingConfigValue configValue)
+ {
+ return GetInstance()
+ .Call(Methods.GetConfigValueInfo, (long)configValue)
+ .AsGodotDictionary();
+ }
+
+ public static int GetDirectPingToPOP(long popId)
+ {
+ return GetInstance().Call(Methods.GetDirectPingToPOP, popId).AsInt32();
+ }
+
+ public static Godot.Collections.Dictionary GetLocalPingLocation()
+ {
+ return GetInstance().Call(Methods.GetLocalPingLocation).AsGodotDictionary();
+ }
+
+ public static long GetLocalTimestamp()
+ {
+ return GetInstance().Call(Methods.GetLocalTimestamp).AsInt64();
+ }
+
+ public static Godot.Collections.Dictionary GetPingToDataCenter(long popId)
+ {
+ return GetInstance().Call(Methods.GetPingToDataCenter, popId).AsGodotDictionary();
+ }
+
+ public static long GetPOPCount()
+ {
+ return GetInstance().Call(Methods.GetPOPCount).AsInt64();
+ }
+
+ public static Godot.Collections.Array GetPOPList()
+ {
+ return GetInstance().Call(Methods.GetPOPList).AsGodotArray();
+ }
+
+ public static NetworkingAvailability GetRelayNetworkStatus()
+ {
+ return (NetworkingAvailability)GetInstance().Call(Methods.GetRelayNetworkStatus).AsInt64();
+ }
+
+ public static void InitRelayNetworkAccess()
+ {
+ GetInstance().Call(Methods.InitRelayNetworkAccess);
+ }
+
+ public static Godot.Collections.Dictionary ParsePingLocationString(string @string)
+ {
+ return GetInstance().Call(Methods.ParsePingLocationString, @string).AsGodotDictionary();
+ }
+
+ public static bool SetConnectionConfigValueFloat(
+ uint connection,
+ NetworkingConfigValue config,
+ double value
+ )
+ {
+ return GetInstance()
+ .Call(Methods.SetConnectionConfigValueFloat, connection, (long)config, value)
+ .AsBool();
+ }
+
+ public static bool SetConnectionConfigValueInt32(
+ uint connection,
+ NetworkingConfigValue config,
+ long value
+ )
+ {
+ return GetInstance()
+ .Call(Methods.SetConnectionConfigValueInt32, connection, (long)config, value)
+ .AsBool();
+ }
+
+ public static bool SetConnectionConfigValueString(
+ uint connection,
+ NetworkingConfigValue config,
+ string value
+ )
+ {
+ return GetInstance()
+ .Call(Methods.SetConnectionConfigValueString, connection, (long)config, value)
+ .AsBool();
+ }
+
+ public static bool SetGlobalConfigValueFloat(NetworkingConfigValue config, double value)
+ {
+ return GetInstance().Call(Methods.SetGlobalConfigValueFloat, (long)config, value).AsBool();
+ }
+
+ public static bool SetGlobalConfigValueInt32(NetworkingConfigValue config, long value)
+ {
+ return GetInstance().Call(Methods.SetGlobalConfigValueInt32, (long)config, value).AsBool();
+ }
+
+ public static bool SetGlobalConfigValueString(NetworkingConfigValue config, string value)
+ {
+ return GetInstance().Call(Methods.SetGlobalConfigValueString, (long)config, value).AsBool();
+ }
+
+ public enum NetworkingAvailability : long
+ {
+ CannotTry = -102,
+ Failed = -101,
+ Previously = -100,
+ Retrying = -10,
+ NeverTried = 1,
+ Waiting = 2,
+ Attempting = 3,
+ Current = 100,
+ Unknown = 0,
+ Force32Bit = 2147483647,
+ }
+
+ public enum NetworkingConfigDataType : long
+ {
+ NetworkingConfigTypeInt32 = 1,
+ NetworkingConfigTypeInt64 = 2,
+ NetworkingConfigTypeFloat = 3,
+ EtworkingConfigTypeString = 4,
+ NetworkingConfigTypeFunctionPtr = 5,
+ NetworkingConfigTypeForce32Bit = 2147483647,
+ }
+
+ public enum NetworkingConfigScope : long
+ {
+ Global = 1,
+ SocketsInterface = 2,
+ ListenSocket = 3,
+ Connection = 4,
+ Force32Bit = 2147483647,
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.NetworkingUtils.cs.uid b/addons/godotsteam_csharpbindings/Steam.NetworkingUtils.cs.uid
new file mode 100644
index 00000000..23762ba7
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.NetworkingUtils.cs.uid
@@ -0,0 +1 @@
+uid://braojp6a3dvb5
diff --git a/addons/godotsteam_csharpbindings/Steam.ParentalSettings.Signals.cs b/addons/godotsteam_csharpbindings/Steam.ParentalSettings.Signals.cs
new file mode 100644
index 00000000..38814803
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.ParentalSettings.Signals.cs
@@ -0,0 +1,42 @@
+using System;
+using Godot;
+
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ private static event Action ParentalSettingChangedEvent;
+ static Action _parentalSettingChangedAction = () =>
+ {
+ ParentalSettingChangedEvent?.Invoke();
+ };
+ public static event Action ParentalSettingChanged
+ {
+ add
+ {
+ if (ParentalSettingChangedEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.ParentalSettingChanged,
+ Callable.From(_parentalSettingChangedAction)
+ );
+ }
+
+ ParentalSettingChangedEvent += value;
+ }
+ remove
+ {
+ ParentalSettingChangedEvent -= value;
+
+ if (ParentalSettingChangedEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.ParentalSettingChanged,
+ Callable.From(_parentalSettingChangedAction)
+ );
+ }
+ }
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.ParentalSettings.Signals.cs.uid b/addons/godotsteam_csharpbindings/Steam.ParentalSettings.Signals.cs.uid
new file mode 100644
index 00000000..f0f188db
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.ParentalSettings.Signals.cs.uid
@@ -0,0 +1 @@
+uid://6ne3oi3ox0uo
diff --git a/addons/godotsteam_csharpbindings/Steam.ParentalSettings.cs b/addons/godotsteam_csharpbindings/Steam.ParentalSettings.cs
new file mode 100644
index 00000000..4afd89a2
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.ParentalSettings.cs
@@ -0,0 +1,54 @@
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public static bool IsParentalLockEnabled()
+ {
+ return GetInstance().Call(Methods.IsParentalLockEnabled).AsBool();
+ }
+
+ public static bool IsParentalLockLocked()
+ {
+ return GetInstance().Call(Methods.IsParentalLockLocked).AsBool();
+ }
+
+ public static bool IsAppBlocked(uint appId)
+ {
+ return GetInstance().Call(Methods.IsAppBlocked, appId).AsBool();
+ }
+
+ public static bool IsAppInBlockList(uint appId)
+ {
+ return GetInstance().Call(Methods.IsAppInBlockList, appId).AsBool();
+ }
+
+ public static bool IsFeatureBlocked(ParentalFeature feature)
+ {
+ return GetInstance().Call(Methods.IsFeatureBlocked, (long)feature).AsBool();
+ }
+
+ public static bool IsFeatureInBlockList(ParentalFeature feature)
+ {
+ return GetInstance().Call(Methods.IsFeatureInBlockList, (long)feature).AsBool();
+ }
+
+ public enum ParentalFeature : long
+ {
+ Invalid = 0,
+ Store = 1,
+ Community = 2,
+ Profile = 3,
+ Friends = 4,
+ News = 5,
+ Trading = 6,
+ Settings = 7,
+ Console = 8,
+ Browser = 9,
+ ParentalSetup = 10,
+ Library = 11,
+ Test = 12,
+ SiteLicense = 13,
+ KioskMode = 14,
+ Max = 15,
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.ParentalSettings.cs.uid b/addons/godotsteam_csharpbindings/Steam.ParentalSettings.cs.uid
new file mode 100644
index 00000000..a8aa9e47
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.ParentalSettings.cs.uid
@@ -0,0 +1 @@
+uid://dyarbc7utwpom
diff --git a/addons/godotsteam_csharpbindings/Steam.Parties.Signals.cs b/addons/godotsteam_csharpbindings/Steam.Parties.Signals.cs
new file mode 100644
index 00000000..0203b117
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Parties.Signals.cs
@@ -0,0 +1,220 @@
+using System;
+using Godot;
+
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public delegate void JoinPartySignalEventHandler(
+ long result,
+ long beaconId,
+ ulong steamId,
+ string connectString
+ );
+ private static event JoinPartySignalEventHandler JoinPartySignalEvent;
+ static Action _joinPartySignalAction = (
+ result,
+ beaconId,
+ steamId,
+ connectString
+ ) =>
+ {
+ JoinPartySignalEvent?.Invoke(result, beaconId, steamId, connectString);
+ };
+ public static event JoinPartySignalEventHandler JoinPartySignal
+ {
+ add
+ {
+ if (JoinPartySignalEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.JoinPartySignal, Callable.From(_joinPartySignalAction));
+ }
+
+ JoinPartySignalEvent += value;
+ }
+ remove
+ {
+ JoinPartySignalEvent -= value;
+
+ if (JoinPartySignalEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.JoinPartySignal, Callable.From(_joinPartySignalAction));
+ }
+ }
+ }
+
+ public delegate void CreateBeaconSignalEventHandler(long result, long beaconId);
+ private static event CreateBeaconSignalEventHandler CreateBeaconSignalEvent;
+ static Action _createBeaconSignalAction = (result, beaconId) =>
+ {
+ CreateBeaconSignalEvent?.Invoke(result, beaconId);
+ };
+ public static event CreateBeaconSignalEventHandler CreateBeaconSignal
+ {
+ add
+ {
+ if (CreateBeaconSignalEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.CreateBeaconSignal, Callable.From(_createBeaconSignalAction));
+ }
+
+ CreateBeaconSignalEvent += value;
+ }
+ remove
+ {
+ CreateBeaconSignalEvent -= value;
+
+ if (CreateBeaconSignalEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.CreateBeaconSignal,
+ Callable.From(_createBeaconSignalAction)
+ );
+ }
+ }
+ }
+
+ public delegate void ReservationNotificationEventHandler(long beaconId, ulong steamId);
+ private static event ReservationNotificationEventHandler ReservationNotificationEvent;
+ static Action _reservationNotificationAction = (beaconId, steamId) =>
+ {
+ ReservationNotificationEvent?.Invoke(beaconId, steamId);
+ };
+ public static event ReservationNotificationEventHandler ReservationNotification
+ {
+ add
+ {
+ if (ReservationNotificationEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.ReservationNotification,
+ Callable.From(_reservationNotificationAction)
+ );
+ }
+
+ ReservationNotificationEvent += value;
+ }
+ remove
+ {
+ ReservationNotificationEvent -= value;
+
+ if (ReservationNotificationEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.ReservationNotification,
+ Callable.From(_reservationNotificationAction)
+ );
+ }
+ }
+ }
+
+ public delegate void ChangeNumOpenSlotsSignalEventHandler(long result);
+ private static event ChangeNumOpenSlotsSignalEventHandler ChangeNumOpenSlotsSignalEvent;
+ static Action _changeNumOpenSlotsSignalAction = (result) =>
+ {
+ ChangeNumOpenSlotsSignalEvent?.Invoke(result);
+ };
+ public static event ChangeNumOpenSlotsSignalEventHandler ChangeNumOpenSlotsSignal
+ {
+ add
+ {
+ if (ChangeNumOpenSlotsSignalEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.ChangeNumOpenSlotsSignal,
+ Callable.From(_changeNumOpenSlotsSignalAction)
+ );
+ }
+
+ ChangeNumOpenSlotsSignalEvent += value;
+ }
+ remove
+ {
+ ChangeNumOpenSlotsSignalEvent -= value;
+
+ if (ChangeNumOpenSlotsSignalEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.ChangeNumOpenSlotsSignal,
+ Callable.From(_changeNumOpenSlotsSignalAction)
+ );
+ }
+ }
+ }
+
+ private static event Action AvailableBeaconLocationsUpdatedEvent;
+ static Action _availableBeaconLocationsUpdatedAction = () =>
+ {
+ AvailableBeaconLocationsUpdatedEvent?.Invoke();
+ };
+ public static event Action AvailableBeaconLocationsUpdated
+ {
+ add
+ {
+ if (AvailableBeaconLocationsUpdatedEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.AvailableBeaconLocationsUpdated,
+ Callable.From(_availableBeaconLocationsUpdatedAction)
+ );
+ }
+ AvailableBeaconLocationsUpdatedEvent += value;
+ }
+ remove
+ {
+ AvailableBeaconLocationsUpdatedEvent -= value;
+ if (AvailableBeaconLocationsUpdatedEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.AvailableBeaconLocationsUpdated,
+ Callable.From(_availableBeaconLocationsUpdatedAction)
+ );
+ }
+ }
+ }
+
+ private static event Action ActiveBeaconsUpdatedEvent;
+ static Action _activeBeaconsUpdatedAction = () =>
+ {
+ ActiveBeaconsUpdatedEvent?.Invoke();
+ };
+ public static event Action ActiveBeaconsUpdated
+ {
+ add
+ {
+ if (ActiveBeaconsUpdatedEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.ActiveBeaconsUpdated,
+ Callable.From(_activeBeaconsUpdatedAction)
+ );
+ }
+
+ ActiveBeaconsUpdatedEvent += value;
+ }
+ remove
+ {
+ ActiveBeaconsUpdatedEvent -= value;
+
+ if (ActiveBeaconsUpdatedEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.ActiveBeaconsUpdated,
+ Callable.From(_activeBeaconsUpdatedAction)
+ );
+ }
+ }
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.Parties.Signals.cs.uid b/addons/godotsteam_csharpbindings/Steam.Parties.Signals.cs.uid
new file mode 100644
index 00000000..d5d8a7e0
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Parties.Signals.cs.uid
@@ -0,0 +1 @@
+uid://xqj1h63jtbny
diff --git a/addons/godotsteam_csharpbindings/Steam.Parties.cs b/addons/godotsteam_csharpbindings/Steam.Parties.cs
new file mode 100644
index 00000000..27a54406
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Parties.cs
@@ -0,0 +1,95 @@
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public static void CancelReservation(ulong beaconId, ulong steamId)
+ {
+ GetInstance().Call(Methods.CancelReservation, beaconId, steamId);
+ }
+
+ public static void ChangeNumOpenSlots(ulong beaconId, long openSlots)
+ {
+ GetInstance().Call(Methods.ChangeNumOpenSlots, beaconId, openSlots);
+ }
+
+ public static void CreateBeacon(
+ uint openSlots,
+ ulong locationId,
+ PartyBeaconLocationType type,
+ string connectString,
+ string beaconMetadata
+ )
+ {
+ GetInstance()
+ .Call(
+ Methods.CreateBeacon,
+ openSlots,
+ locationId,
+ (long)type,
+ connectString,
+ beaconMetadata
+ );
+ }
+
+ public static bool DestroyBeacon(long beaconId)
+ {
+ return GetInstance().Call(Methods.DestroyBeacon, beaconId).AsBool();
+ }
+
+ public static Godot.Collections.Array GetAvailableBeaconLocations(long max)
+ {
+ return GetInstance().Call(Methods.GetAvailableBeaconLocations, max).AsGodotArray();
+ }
+
+ public static ulong GetBeaconByIndex(long index)
+ {
+ return GetInstance().Call(Methods.GetBeaconByIndex, index).AsUInt64();
+ }
+
+ public static Godot.Collections.Dictionary GetBeaconDetails(long beaconId)
+ {
+ return GetInstance().Call(Methods.GetBeaconDetails, beaconId).AsGodotDictionary();
+ }
+
+ public static string GetBeaconLocationData(
+ ulong locationId,
+ PartyBeaconLocationType locationType,
+ PartyBeaconLocationData locationData
+ )
+ {
+ return GetInstance()
+ .Call(Methods.GetBeaconLocationData, locationId, (long)locationType, (long)locationData)
+ .AsString();
+ }
+
+ public static long GetNumActiveBeacons()
+ {
+ return GetInstance().Call(Methods.GetNumActiveBeacons).AsInt64();
+ }
+
+ public static void JoinParty(long beaconId)
+ {
+ GetInstance().Call(Methods.JoinParty, beaconId);
+ }
+
+ public static void OnReservationCompleted(ulong beaconId, ulong steamId)
+ {
+ GetInstance().Call(Methods.OnReservationCompleted, beaconId, steamId);
+ }
+
+ public enum PartyBeaconLocationData : long
+ {
+ Data = 0,
+ DataName = 1,
+ DataUrlSmall = 2,
+ DataUrlMedium = 3,
+ DataUrlLarge = 4,
+ }
+
+ public enum PartyBeaconLocationType : long
+ {
+ LocationtypeInvalid = 0,
+ LocationtypeChatGroup = 1,
+ LocationTypeMax = 2,
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.Parties.cs.uid b/addons/godotsteam_csharpbindings/Steam.Parties.cs.uid
new file mode 100644
index 00000000..f40255ae
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Parties.cs.uid
@@ -0,0 +1 @@
+uid://bgmbcdrfe2wwg
diff --git a/addons/godotsteam_csharpbindings/Steam.RemotePlay.Signals.cs b/addons/godotsteam_csharpbindings/Steam.RemotePlay.Signals.cs
new file mode 100644
index 00000000..2e6d9b0a
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.RemotePlay.Signals.cs
@@ -0,0 +1,75 @@
+using System;
+using Godot;
+
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public delegate void RemotePlaySessionConnectedEventHandler(long sessionId);
+ private static event RemotePlaySessionConnectedEventHandler RemotePlaySessionConnectedEvent;
+ static Action _remotePlaySessionConnectedAction = (sessionId) =>
+ {
+ RemotePlaySessionConnectedEvent?.Invoke(sessionId);
+ };
+ public static event RemotePlaySessionConnectedEventHandler RemotePlaySessionConnected
+ {
+ add
+ {
+ if (RemotePlaySessionConnectedEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.RemotePlaySessionConnected,
+ Callable.From(_remotePlaySessionConnectedAction)
+ );
+ }
+ RemotePlaySessionConnectedEvent += value;
+ }
+ remove
+ {
+ RemotePlaySessionConnectedEvent -= value;
+ if (RemotePlaySessionConnectedEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.RemotePlaySessionConnected,
+ Callable.From(_remotePlaySessionConnectedAction)
+ );
+ }
+ }
+ }
+
+ public delegate void RemotePlaySessionDisconnectedEventHandler(long sessionId);
+ private static event RemotePlaySessionDisconnectedEventHandler RemotePlaySessionDisconnectedEvent;
+ static Action _remotePlaySessionDisconnectedAction = (sessionId) =>
+ {
+ RemotePlaySessionDisconnectedEvent?.Invoke(sessionId);
+ };
+ public static event RemotePlaySessionDisconnectedEventHandler RemotePlaySessionDisconnected
+ {
+ add
+ {
+ if (RemotePlaySessionDisconnectedEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.RemotePlaySessionDisconnected,
+ Callable.From(_remotePlaySessionDisconnectedAction)
+ );
+ }
+ RemotePlaySessionDisconnectedEvent += value;
+ }
+ remove
+ {
+ RemotePlaySessionDisconnectedEvent -= value;
+ if (RemotePlaySessionDisconnectedEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.RemotePlaySessionDisconnected,
+ Callable.From(_remotePlaySessionDisconnectedAction)
+ );
+ }
+ }
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.RemotePlay.Signals.cs.uid b/addons/godotsteam_csharpbindings/Steam.RemotePlay.Signals.cs.uid
new file mode 100644
index 00000000..c8fab373
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.RemotePlay.Signals.cs.uid
@@ -0,0 +1 @@
+uid://du8cue6fgrtgs
diff --git a/addons/godotsteam_csharpbindings/Steam.RemotePlay.cs b/addons/godotsteam_csharpbindings/Steam.RemotePlay.cs
new file mode 100644
index 00000000..af80aaac
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.RemotePlay.cs
@@ -0,0 +1,46 @@
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public static long GetSessionCount()
+ {
+ return GetInstance().Call(Methods.GetSessionCount).AsInt64();
+ }
+
+ public static uint GetSessionID(long index)
+ {
+ return GetInstance().Call(Methods.GetSessionID, index).AsUInt32();
+ }
+
+ public static ulong GetSessionSteamID(long sessionId)
+ {
+ return GetInstance().Call(Methods.GetSessionSteamID, sessionId).AsUInt64();
+ }
+
+ public static string GetSessionClientName(long sessionId)
+ {
+ return GetInstance().Call(Methods.GetSessionClientName, sessionId).AsString();
+ }
+
+ public static int GetSessionClientFormFactor(long sessionId)
+ {
+ return GetInstance().Call(Methods.GetSessionClientFormFactor, sessionId).AsInt32();
+ }
+
+ public static Godot.Collections.Dictionary GetSessionClientResolution(long sessionId)
+ {
+ return GetInstance()
+ .Call(Methods.GetSessionClientResolution, sessionId)
+ .AsGodotDictionary();
+ }
+
+ public static bool SendRemotePlayTogetherInvite(ulong friendId)
+ {
+ return GetInstance().Call(Methods.SendRemotePlayTogetherInvite, friendId).AsBool();
+ }
+
+ public static bool StartRemotePlayTogether(bool showOverlay = true)
+ {
+ return GetInstance().Call(Methods.StartRemotePlayTogether, showOverlay).AsBool();
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.RemotePlay.cs.uid b/addons/godotsteam_csharpbindings/Steam.RemotePlay.cs.uid
new file mode 100644
index 00000000..46516a96
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.RemotePlay.cs.uid
@@ -0,0 +1 @@
+uid://ct722oe7hsrh8
diff --git a/addons/godotsteam_csharpbindings/Steam.RemoteStorage.Signals.cs b/addons/godotsteam_csharpbindings/Steam.RemoteStorage.Signals.cs
new file mode 100644
index 00000000..5c554808
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.RemoteStorage.Signals.cs
@@ -0,0 +1,232 @@
+using System;
+using Godot;
+
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public delegate void FileReadAsyncCompleteEventHandler(Godot.Collections.Dictionary fileRead);
+ private static event FileReadAsyncCompleteEventHandler FileReadAsyncCompleteEvent;
+ static Action _fileReadAsyncCompleteAction = (fileRead) =>
+ {
+ FileReadAsyncCompleteEvent?.Invoke(fileRead);
+ };
+ public static event FileReadAsyncCompleteEventHandler FileReadAsyncComplete
+ {
+ add
+ {
+ if (FileReadAsyncCompleteEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.FileReadAsyncComplete,
+ Callable.From(_fileReadAsyncCompleteAction)
+ );
+ }
+ FileReadAsyncCompleteEvent += value;
+ }
+ remove
+ {
+ FileReadAsyncCompleteEvent -= value;
+ if (FileReadAsyncCompleteEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.FileReadAsyncComplete,
+ Callable.From(_fileReadAsyncCompleteAction)
+ );
+ }
+ }
+ }
+
+ public delegate void FileShareResultEventHandler(long result, long handle, string name);
+ private static event FileShareResultEventHandler FileShareResultEvent;
+ static Action _fileShareResultAction = (result, handle, name) =>
+ {
+ FileShareResultEvent?.Invoke(result, handle, name);
+ };
+ public static event FileShareResultEventHandler FileShareResult
+ {
+ add
+ {
+ if (FileShareResultEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.FileShareResult, Callable.From(_fileShareResultAction));
+ }
+ FileShareResultEvent += value;
+ }
+ remove
+ {
+ FileShareResultEvent -= value;
+ if (FileShareResultEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.FileShareResult, Callable.From(_fileShareResultAction));
+ }
+ }
+ }
+
+ public delegate void FileWriteAsyncCompleteEventHandler(long result);
+ private static event FileWriteAsyncCompleteEventHandler FileWriteAsyncCompleteEvent;
+ static Action _fileWriteAsyncCompleteAction = (result) =>
+ {
+ FileWriteAsyncCompleteEvent?.Invoke(result);
+ };
+ public static event FileWriteAsyncCompleteEventHandler FileWriteAsyncComplete
+ {
+ add
+ {
+ if (FileWriteAsyncCompleteEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.FileWriteAsyncComplete,
+ Callable.From(_fileWriteAsyncCompleteAction)
+ );
+ }
+ FileWriteAsyncCompleteEvent += value;
+ }
+ remove
+ {
+ FileWriteAsyncCompleteEvent -= value;
+ if (FileWriteAsyncCompleteEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.FileWriteAsyncComplete,
+ Callable.From(_fileWriteAsyncCompleteAction)
+ );
+ }
+ }
+ }
+
+ public delegate void DownloadUgcResultEventHandler(
+ long result,
+ Godot.Collections.Dictionary downloadData
+ );
+ private static event DownloadUgcResultEventHandler DownloadUgcResultEvent;
+ static Action _downloadUgcResultAction = (
+ result,
+ downloadData
+ ) =>
+ {
+ DownloadUgcResultEvent?.Invoke(result, downloadData);
+ };
+ public static event DownloadUgcResultEventHandler DownloadUgcResult
+ {
+ add
+ {
+ if (DownloadUgcResultEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.DownloadUgcResult, Callable.From(_downloadUgcResultAction));
+ }
+ DownloadUgcResultEvent += value;
+ }
+ remove
+ {
+ DownloadUgcResultEvent -= value;
+ if (DownloadUgcResultEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.DownloadUgcResult, Callable.From(_downloadUgcResultAction));
+ }
+ }
+ }
+
+ public delegate void UnsubscribeItemSignalEventHandler(long result, long fileId);
+ private static event UnsubscribeItemSignalEventHandler UnsubscribeItemSignalEvent;
+ static Action _unsubscribeItemSignalAction = (result, fileId) =>
+ {
+ UnsubscribeItemSignalEvent?.Invoke(result, fileId);
+ };
+ public static event UnsubscribeItemSignalEventHandler UnsubscribeItemSignal
+ {
+ add
+ {
+ if (UnsubscribeItemSignalEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.UnsubscribeItemSignal,
+ Callable.From(_unsubscribeItemSignalAction)
+ );
+ }
+ UnsubscribeItemSignalEvent += value;
+ }
+ remove
+ {
+ UnsubscribeItemSignalEvent -= value;
+ if (UnsubscribeItemSignalEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.UnsubscribeItemSignal,
+ Callable.From(_unsubscribeItemSignalAction)
+ );
+ }
+ }
+ }
+
+ public delegate void SubscribeItemSignalEventHandler(long result, long fileId);
+ private static event SubscribeItemSignalEventHandler SubscribeItemSignalEvent;
+ static Action _subscribeItemSignalAction = (result, fileId) =>
+ {
+ SubscribeItemSignalEvent?.Invoke(result, fileId);
+ };
+ public static event SubscribeItemSignalEventHandler SubscribeItemSignal
+ {
+ add
+ {
+ if (SubscribeItemSignalEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.SubscribeItemSignal,
+ Callable.From(_subscribeItemSignalAction)
+ );
+ }
+ SubscribeItemSignalEvent += value;
+ }
+ remove
+ {
+ SubscribeItemSignalEvent -= value;
+ if (SubscribeItemSignalEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.SubscribeItemSignal,
+ Callable.From(_subscribeItemSignalAction)
+ );
+ }
+ }
+ }
+
+ private static event Action LocalFileChangedEvent;
+ static Action _localFileChangedAction = () =>
+ {
+ LocalFileChangedEvent?.Invoke();
+ };
+ public static event Action LocalFileChanged
+ {
+ add
+ {
+ if (LocalFileChangedEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.LocalFileChanged, Callable.From(_localFileChangedAction));
+ }
+ LocalFileChangedEvent += value;
+ }
+ remove
+ {
+ LocalFileChangedEvent -= value;
+ if (LocalFileChangedEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.LocalFileChanged, Callable.From(_localFileChangedAction));
+ }
+ }
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.RemoteStorage.Signals.cs.uid b/addons/godotsteam_csharpbindings/Steam.RemoteStorage.Signals.cs.uid
new file mode 100644
index 00000000..b805f7cf
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.RemoteStorage.Signals.cs.uid
@@ -0,0 +1 @@
+uid://d2gw838h5g0fk
diff --git a/addons/godotsteam_csharpbindings/Steam.RemoteStorage.cs b/addons/godotsteam_csharpbindings/Steam.RemoteStorage.cs
new file mode 100644
index 00000000..0eed4121
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.RemoteStorage.cs
@@ -0,0 +1,272 @@
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public static bool BeginFileWriteBatch()
+ {
+ return GetInstance().Call(Methods.BeginFileWriteBatch).AsBool();
+ }
+
+ public static bool EndFileWriteBatch()
+ {
+ return GetInstance().Call(Methods.EndFileWriteBatch).AsBool();
+ }
+
+ public static bool FileDelete(string file)
+ {
+ return GetInstance().Call(Methods.FileDelete, file).AsBool();
+ }
+
+ public static bool FileExists(string file)
+ {
+ return GetInstance().Call(Methods.FileExists, file).AsBool();
+ }
+
+ public static bool FileForget(string file)
+ {
+ return GetInstance().Call(Methods.FileForget, file).AsBool();
+ }
+
+ public static bool FilePersisted(string file)
+ {
+ return GetInstance().Call(Methods.FilePersisted, file).AsBool();
+ }
+
+ public static Godot.Collections.Dictionary FileRead(string file, long dataToRead)
+ {
+ return GetInstance().Call(Methods.FileRead, file, dataToRead).AsGodotDictionary();
+ }
+
+ public static void FileReadAsync(string file, uint offset, long dataToRead)
+ {
+ GetInstance().Call(Methods.FileReadAsync, file, offset, dataToRead);
+ }
+
+ public static void FileShare(string file)
+ {
+ GetInstance().Call(Methods.FileShare, file);
+ }
+
+ public static bool FileWrite(string file, byte[] data, long size = 0)
+ {
+ return GetInstance().Call(Methods.FileWrite, file, data, size).AsBool();
+ }
+
+ public static void FileWriteAsync(string file, byte[] data, long size = 0)
+ {
+ GetInstance().Call(Methods.FileWriteAsync, file, data, size);
+ }
+
+ public static bool FileWriteStreamCancel(long writeHandle)
+ {
+ return GetInstance().Call(Methods.FileWriteStreamCancel, writeHandle).AsBool();
+ }
+
+ public static bool FileWriteStreamClose(long writeHandle)
+ {
+ return GetInstance().Call(Methods.FileWriteStreamClose, writeHandle).AsBool();
+ }
+
+ public static ulong FileWriteStreamOpen(string file)
+ {
+ return GetInstance().Call(Methods.FileWriteStreamOpen, file).AsUInt64();
+ }
+
+ public static bool FileWriteStreamWriteChunk(ulong writeHandle, byte[] data)
+ {
+ return GetInstance().Call(Methods.FileWriteStreamWriteChunk, writeHandle, data).AsBool();
+ }
+
+ public static long GetCachedUGCCount()
+ {
+ return GetInstance().Call(Methods.GetCachedUGCCount).AsInt64();
+ }
+
+ public static ulong GetCachedUGCHandle(long content)
+ {
+ return GetInstance().Call(Methods.GetCachedUGCHandle, content).AsUInt64();
+ }
+
+ public static long GetFileCount()
+ {
+ return GetInstance().Call(Methods.GetFileCount).AsInt64();
+ }
+
+ public static Godot.Collections.Dictionary GetFileNameAndSize(long file)
+ {
+ return GetInstance().Call(Methods.GetFileNameAndSize, file).AsGodotDictionary();
+ }
+
+ public static int GetFileSize(string file)
+ {
+ return GetInstance().Call(Methods.GetFileSize, file).AsInt32();
+ }
+
+ public static long GetFileTimestamp(string file)
+ {
+ return GetInstance().Call(Methods.GetFileTimestamp, file).AsInt64();
+ }
+
+ public static Godot.Collections.Dictionary GetLocalFileChange(long file)
+ {
+ return GetInstance().Call(Methods.GetLocalFileChange, file).AsGodotDictionary();
+ }
+
+ public static long GetLocalFileChangeCount()
+ {
+ return GetInstance().Call(Methods.GetLocalFileChangeCount).AsInt64();
+ }
+
+ public static Godot.Collections.Dictionary GetQuota()
+ {
+ return GetInstance().Call(Methods.GetQuota).AsGodotDictionary();
+ }
+
+ public static Godot.Collections.Dictionary GetSyncPlatforms(string file)
+ {
+ return GetInstance().Call(Methods.GetSyncPlatforms, file).AsGodotDictionary();
+ }
+
+ public static Godot.Collections.Dictionary GetUGCDetails(long content)
+ {
+ return GetInstance().Call(Methods.GetUGCDetails, content).AsGodotDictionary();
+ }
+
+ public static Godot.Collections.Dictionary GetUGCDownloadProgress(long content)
+ {
+ return GetInstance().Call(Methods.GetUGCDownloadProgress, content).AsGodotDictionary();
+ }
+
+ public static bool IsCloudEnabledForAccount()
+ {
+ return GetInstance().Call(Methods.IsCloudEnabledForAccount).AsBool();
+ }
+
+ public static bool IsCloudEnabledForApp()
+ {
+ return GetInstance().Call(Methods.IsCloudEnabledForApp).AsBool();
+ }
+
+ public static void SetCloudEnabledForApp(bool enabled)
+ {
+ GetInstance().Call(Methods.SetCloudEnabledForApp, enabled);
+ }
+
+ public static bool SetSyncPlatforms(string file, long platform)
+ {
+ return GetInstance().Call(Methods.SetSyncPlatforms, file, platform).AsBool();
+ }
+
+ public static void UgcDownload(ulong content, long priority)
+ {
+ GetInstance().Call(Methods.UgcDownload, content, priority);
+ }
+
+ public static void UgcDownloadToLocation(ulong content, string location, long priority)
+ {
+ GetInstance().Call(Methods.UgcDownloadToLocation, content, location, priority);
+ }
+
+ public static byte[] UgcRead(ulong content, int dataSize, uint offset, UgcReadAction action)
+ {
+ return GetInstance()
+ .Call(Methods.UgcRead, content, dataSize, offset, (long)action)
+ .AsByteArray();
+ }
+
+ [System.Flags]
+ public enum RemoteStoragePlatform : long
+ {
+ None = 0,
+ Windows = 1,
+ Osx = 2,
+ Ps3 = 4,
+ Linux = 8,
+ Switch = 16,
+ Android = 32,
+ Ios = 64,
+ All = 4294967295,
+ }
+
+ public enum RemoteStoragePublishedFileVisibility : long
+ {
+ Public = 0,
+ FriendsOnly = 1,
+ Private = 2,
+ Unlisted = 3,
+ }
+
+ public enum UgcReadAction : long
+ {
+ ContinueReadingUntilFinished = 0,
+ ContinueReading = 1,
+ Close = 2,
+ }
+
+ public enum WorkshopEnumerationType : long
+ {
+ RankedByVote = 0,
+ Recent = 1,
+ Trending = 2,
+ FavoritesOfFriends = 3,
+ VotedByFriends = 4,
+ ContentByFriends = 5,
+ RecentFromFollowedUsers = 6,
+ }
+
+ public enum WorkshopFileAction : long
+ {
+ Played = 0,
+ Completed = 1,
+ }
+
+ public enum WorkshopFileType : long
+ {
+ WorkshopFileTypeFirst = 0,
+ WorkshopFileTypeCommunity = 0,
+ WorkshopFileTypeMicrotransaction = 1,
+ WorkshopFileTypeCollection = 2,
+ WorkshopFileTypeArt = 3,
+ WorkshopFileTypeVideo = 4,
+ WorkshopFileTypeScreenshot = 5,
+ WorkshopFileTypeGame = 6,
+ WorkshopFileTypeSoftware = 7,
+ WorkshopFileTypeConcept = 8,
+ WorkshopFileTypeWebGuide = 9,
+ WorkshopFileTypeIntegratedGuide = 10,
+ WorkshopFileTypeMerch = 11,
+ WorkshopFileTypeControllerBinding = 12,
+ WorkshopFileTypeSteamworksAccessInvite = 13,
+ WorkshopFileTypeSteamVideo = 14,
+ WorkshopFileTypeGameManagedItem = 15,
+ WorkshopFileTypeMax = 16,
+ }
+
+ public enum WorkshopVideoProvider : long
+ {
+ None = 0,
+ Youtube = 1,
+ }
+
+ public enum WorkshopVote : long
+ {
+ Unvoted = 0,
+ For = 1,
+ Against = 2,
+ Later = 3,
+ }
+
+ public enum LocalFileChange : long
+ {
+ Invalid = 0,
+ FileUpdated = 1,
+ FileDeleted = 2,
+ }
+
+ public enum FilePathType : long
+ {
+ Invalid = 0,
+ Absolute = 1,
+ ApiFileName = 2,
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.RemoteStorage.cs.uid b/addons/godotsteam_csharpbindings/Steam.RemoteStorage.cs.uid
new file mode 100644
index 00000000..624d1da0
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.RemoteStorage.cs.uid
@@ -0,0 +1 @@
+uid://djeeotxol2suo
diff --git a/addons/godotsteam_csharpbindings/Steam.Screenshots.Signals.cs b/addons/godotsteam_csharpbindings/Steam.Screenshots.Signals.cs
new file mode 100644
index 00000000..176c4ccb
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Screenshots.Signals.cs
@@ -0,0 +1,68 @@
+using System;
+using Godot;
+
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public delegate void ScreenshotReadyEventHandler(uint handle, ErrorResult result);
+ private static event ScreenshotReadyEventHandler ScreenshotReadyEvent;
+ static Action _screenshotReadyAction = (handle, result) =>
+ {
+ ScreenshotReadyEvent?.Invoke(handle, (ErrorResult)result);
+ };
+ public static event ScreenshotReadyEventHandler ScreenshotReady
+ {
+ add
+ {
+ if (ScreenshotReadyEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.ScreenshotReady, Callable.From(_screenshotReadyAction));
+ }
+ ScreenshotReadyEvent += value;
+ }
+ remove
+ {
+ ScreenshotReadyEvent -= value;
+ if (ScreenshotReadyEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.ScreenshotReady, Callable.From(_screenshotReadyAction));
+ }
+ }
+ }
+
+ private static event Action ScreenshotRequestedEvent;
+ static Action _screenshotRequestedAction = () =>
+ {
+ ScreenshotRequestedEvent?.Invoke();
+ };
+ public static event Action ScreenshotRequested
+ {
+ add
+ {
+ if (ScreenshotRequestedEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.ScreenshotRequested,
+ Callable.From(_screenshotRequestedAction)
+ );
+ }
+ ScreenshotRequestedEvent += value;
+ }
+ remove
+ {
+ ScreenshotRequestedEvent -= value;
+ if (ScreenshotRequestedEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.ScreenshotRequested,
+ Callable.From(_screenshotRequestedAction)
+ );
+ }
+ }
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.Screenshots.Signals.cs.uid b/addons/godotsteam_csharpbindings/Steam.Screenshots.Signals.cs.uid
new file mode 100644
index 00000000..e23d7fec
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Screenshots.Signals.cs.uid
@@ -0,0 +1 @@
+uid://i72xtnpthx2v
diff --git a/addons/godotsteam_csharpbindings/Steam.Screenshots.cs b/addons/godotsteam_csharpbindings/Steam.Screenshots.cs
new file mode 100644
index 00000000..dd8bb48c
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Screenshots.cs
@@ -0,0 +1,62 @@
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public static uint AddScreenshotToLibrary(
+ string fileName,
+ string thumbnailFileName,
+ int width,
+ int height
+ )
+ {
+ return GetInstance()
+ .Call(Methods.AddScreenshotToLibrary, fileName, thumbnailFileName, width, height)
+ .AsUInt32();
+ }
+
+ public static uint AddVRScreenshotToLibrary(
+ VRScreenshotType type,
+ string fileName,
+ string vrFileName
+ )
+ {
+ return GetInstance()
+ .Call(Methods.AddVRScreenshotToLibrary, (int)type, fileName, vrFileName)
+ .AsUInt32();
+ }
+
+ public static void HookScreenshots(bool hook)
+ {
+ GetInstance().Call(Methods.HookScreenshots, hook);
+ }
+
+ public static bool IsScreenshotsHooked()
+ {
+ return GetInstance().Call(Methods.IsScreenshotsHooked).AsBool();
+ }
+
+ public static bool SetLocation(uint screenshot, string location)
+ {
+ return GetInstance().Call(Methods.SetLocation, screenshot, location).AsBool();
+ }
+
+ public static bool TagPublishedFile(uint screenshot, ulong fileId)
+ {
+ return GetInstance().Call(Methods.TagPublishedFile, screenshot, fileId).AsBool();
+ }
+
+ public static bool TagUser(uint screenshot, ulong steamId)
+ {
+ return GetInstance().Call(Methods.TagUser, screenshot, steamId).AsBool();
+ }
+
+ public static void TriggerScreenshot()
+ {
+ GetInstance().Call(Methods.TriggerScreenshot);
+ }
+
+ public static uint WriteScreenshot(byte[] rgb, int width, int height)
+ {
+ return GetInstance().Call(Methods.WriteScreenshot, rgb, width, height).AsUInt32();
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.Screenshots.cs.uid b/addons/godotsteam_csharpbindings/Steam.Screenshots.cs.uid
new file mode 100644
index 00000000..39188d5e
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Screenshots.cs.uid
@@ -0,0 +1 @@
+uid://buas4arvbau2m
diff --git a/addons/godotsteam_csharpbindings/Steam.Signals.cs b/addons/godotsteam_csharpbindings/Steam.Signals.cs
new file mode 100644
index 00000000..cc9cd422
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Signals.cs
@@ -0,0 +1,35 @@
+using System;
+using Godot;
+
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public delegate void SteamworksErrorEventHandler(string failedSignal, string iOFailure);
+ private static event SteamworksErrorEventHandler SteamworksErrorEvent;
+ static Action _steamworksErrorAction = (failedSignal, iOFailure) =>
+ {
+ SteamworksErrorEvent?.Invoke(failedSignal, iOFailure);
+ };
+ public static event SteamworksErrorEventHandler SteamworksError
+ {
+ add
+ {
+ if (SteamworksErrorEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.SteamworksError, Callable.From(_steamworksErrorAction));
+ }
+ SteamworksErrorEvent += value;
+ }
+ remove
+ {
+ SteamworksErrorEvent -= value;
+ if (SteamworksErrorEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.SteamworksError, Callable.From(_steamworksErrorAction));
+ }
+ }
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.Signals.cs.uid b/addons/godotsteam_csharpbindings/Steam.Signals.cs.uid
new file mode 100644
index 00000000..0f31baad
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.Signals.cs.uid
@@ -0,0 +1 @@
+uid://b8risj0vfs2x3
diff --git a/addons/godotsteam_csharpbindings/Steam.UGC.Signals.cs b/addons/godotsteam_csharpbindings/Steam.UGC.Signals.cs
new file mode 100644
index 00000000..a7260b3b
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.UGC.Signals.cs
@@ -0,0 +1,629 @@
+using System;
+using Godot;
+
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public delegate void AddAppDependencyResultEventHandler(long result, long fileId, uint appId);
+ private static event AddAppDependencyResultEventHandler AddAppDependencyResultEvent;
+ static Action _addAppDependencyResultAction = (result, fileId, appId) =>
+ {
+ AddAppDependencyResultEvent?.Invoke(result, fileId, appId);
+ };
+ public static event AddAppDependencyResultEventHandler AddAppDependencyResult
+ {
+ add
+ {
+ if (AddAppDependencyResultEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.AddAppDependencyResult,
+ Callable.From(_addAppDependencyResultAction)
+ );
+ }
+ AddAppDependencyResultEvent += value;
+ }
+ remove
+ {
+ AddAppDependencyResultEvent -= value;
+ if (AddAppDependencyResultEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.AddAppDependencyResult,
+ Callable.From(_addAppDependencyResultAction)
+ );
+ }
+ }
+ }
+
+ public delegate void AddUgcDependencyResultEventHandler(long result, long fileId, long childId);
+ private static event AddUgcDependencyResultEventHandler AddUgcDependencyResultEvent;
+ static Action _addUgcDependencyResultAction = (result, fileId, childId) =>
+ {
+ AddUgcDependencyResultEvent?.Invoke(result, fileId, childId);
+ };
+ public static event AddUgcDependencyResultEventHandler AddUgcDependencyResult
+ {
+ add
+ {
+ if (AddUgcDependencyResultEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.AddUgcDependencyResult,
+ Callable.From(_addUgcDependencyResultAction)
+ );
+ }
+ AddUgcDependencyResultEvent += value;
+ }
+ remove
+ {
+ AddUgcDependencyResultEvent -= value;
+ if (AddUgcDependencyResultEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.AddUgcDependencyResult,
+ Callable.From(_addUgcDependencyResultAction)
+ );
+ }
+ }
+ }
+
+ public delegate void ItemCreatedEventHandler(long result, long fileId, bool acceptTos);
+ private static event ItemCreatedEventHandler ItemCreatedEvent;
+ static Action _itemCreatedAction = (result, fileId, acceptTos) =>
+ {
+ ItemCreatedEvent?.Invoke(result, fileId, acceptTos);
+ };
+ public static event ItemCreatedEventHandler ItemCreated
+ {
+ add
+ {
+ if (ItemCreatedEvent == null)
+ {
+ GetInstance().Connect(Signals.ItemCreated, Callable.From(_itemCreatedAction));
+ }
+ ItemCreatedEvent += value;
+ }
+ remove
+ {
+ ItemCreatedEvent -= value;
+ if (ItemCreatedEvent == null)
+ {
+ GetInstance().Disconnect(Signals.ItemCreated, Callable.From(_itemCreatedAction));
+ }
+ }
+ }
+
+ public delegate void ItemDownloadedEventHandler(long result, long fileId, uint appId);
+ private static event ItemDownloadedEventHandler ItemDownloadedEvent;
+ static Action _itemDownloadedAction = (result, fileId, appId) =>
+ {
+ ItemDownloadedEvent?.Invoke(result, fileId, appId);
+ };
+ public static event ItemDownloadedEventHandler ItemDownloaded
+ {
+ add
+ {
+ if (ItemDownloadedEvent == null)
+ {
+ GetInstance().Connect(Signals.ItemDownloaded, Callable.From(_itemDownloadedAction));
+ }
+ ItemDownloadedEvent += value;
+ }
+ remove
+ {
+ ItemDownloadedEvent -= value;
+ if (ItemDownloadedEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.ItemDownloaded, Callable.From(_itemDownloadedAction));
+ }
+ }
+ }
+
+ public delegate void GetAppDependenciesResultEventHandler(
+ long result,
+ long fileId,
+ long appDependencies,
+ long totalAppDependencies
+ );
+ private static event GetAppDependenciesResultEventHandler GetAppDependenciesResultEvent;
+ static Action _getAppDependenciesResultAction = (
+ result,
+ fileId,
+ appDependencies,
+ totalAppDependencies
+ ) =>
+ {
+ GetAppDependenciesResultEvent?.Invoke(
+ result,
+ fileId,
+ appDependencies,
+ totalAppDependencies
+ );
+ };
+ public static event GetAppDependenciesResultEventHandler GetAppDependenciesResult
+ {
+ add
+ {
+ if (GetAppDependenciesResultEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.GetAppDependenciesResult,
+ Callable.From(_getAppDependenciesResultAction)
+ );
+ }
+ GetAppDependenciesResultEvent += value;
+ }
+ remove
+ {
+ GetAppDependenciesResultEvent -= value;
+ if (GetAppDependenciesResultEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.GetAppDependenciesResult,
+ Callable.From(_getAppDependenciesResultAction)
+ );
+ }
+ }
+ }
+
+ public delegate void ItemDeletedEventHandler(long result, long fileId);
+ private static event ItemDeletedEventHandler ItemDeletedEvent;
+ static Action _itemDeletedAction = (result, fileId) =>
+ {
+ ItemDeletedEvent?.Invoke(result, fileId);
+ };
+ public static event ItemDeletedEventHandler ItemDeleted
+ {
+ add
+ {
+ if (ItemDeletedEvent == null)
+ {
+ GetInstance().Connect(Signals.ItemDeleted, Callable.From(_itemDeletedAction));
+ }
+ ItemDeletedEvent += value;
+ }
+ remove
+ {
+ ItemDeletedEvent -= value;
+ if (ItemDeletedEvent == null)
+ {
+ GetInstance().Disconnect(Signals.ItemDeleted, Callable.From(_itemDeletedAction));
+ }
+ }
+ }
+
+ public delegate void GetItemVoteResultEventHandler(
+ long result,
+ long fileId,
+ bool voteUp,
+ bool voteDown,
+ bool voteSkipped
+ );
+ private static event GetItemVoteResultEventHandler GetItemVoteResultEvent;
+ static Action _getItemVoteResultAction = (
+ result,
+ fileId,
+ voteUp,
+ voteDown,
+ voteSkipped
+ ) =>
+ {
+ GetItemVoteResultEvent?.Invoke(result, fileId, voteUp, voteDown, voteSkipped);
+ };
+ public static event GetItemVoteResultEventHandler GetItemVoteResult
+ {
+ add
+ {
+ if (GetItemVoteResultEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.GetItemVoteResult, Callable.From(_getItemVoteResultAction));
+ }
+ GetItemVoteResultEvent += value;
+ }
+ remove
+ {
+ GetItemVoteResultEvent -= value;
+ if (GetItemVoteResultEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.GetItemVoteResult, Callable.From(_getItemVoteResultAction));
+ }
+ }
+ }
+
+ public delegate void ItemInstalledEventHandler(uint appId, long fileId);
+ private static event ItemInstalledEventHandler ItemInstalledEvent;
+ static Action _itemInstalledAction = (appId, fileId) =>
+ {
+ ItemInstalledEvent?.Invoke(appId, fileId);
+ };
+ public static event ItemInstalledEventHandler ItemInstalled
+ {
+ add
+ {
+ if (ItemInstalledEvent == null)
+ {
+ GetInstance().Connect(Signals.ItemInstalled, Callable.From(_itemInstalledAction));
+ }
+ ItemInstalledEvent += value;
+ }
+ remove
+ {
+ ItemInstalledEvent -= value;
+ if (ItemInstalledEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.ItemInstalled, Callable.From(_itemInstalledAction));
+ }
+ }
+ }
+
+ public delegate void RemoveAppDependencyResultEventHandler(
+ long result,
+ long fileId,
+ uint appId
+ );
+ private static event RemoveAppDependencyResultEventHandler RemoveAppDependencyResultEvent;
+ static Action _removeAppDependencyResultAction = (result, fileId, appId) =>
+ {
+ RemoveAppDependencyResultEvent?.Invoke(result, fileId, appId);
+ };
+ public static event RemoveAppDependencyResultEventHandler RemoveAppDependencyResult
+ {
+ add
+ {
+ if (RemoveAppDependencyResultEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.RemoveAppDependencyResult,
+ Callable.From(_removeAppDependencyResultAction)
+ );
+ }
+ RemoveAppDependencyResultEvent += value;
+ }
+ remove
+ {
+ RemoveAppDependencyResultEvent -= value;
+ if (RemoveAppDependencyResultEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.RemoveAppDependencyResult,
+ Callable.From(_removeAppDependencyResultAction)
+ );
+ }
+ }
+ }
+
+ public delegate void RemoveUgcDependencyResultEventHandler(
+ long result,
+ long fileId,
+ long childId
+ );
+ private static event RemoveUgcDependencyResultEventHandler RemoveUgcDependencyResultEvent;
+ static Action _removeUgcDependencyResultAction = (result, fileId, childId) =>
+ {
+ RemoveUgcDependencyResultEvent?.Invoke(result, fileId, childId);
+ };
+ public static event RemoveUgcDependencyResultEventHandler RemoveUgcDependencyResult
+ {
+ add
+ {
+ if (RemoveUgcDependencyResultEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.RemoveUgcDependencyResult,
+ Callable.From(_removeUgcDependencyResultAction)
+ );
+ }
+ RemoveUgcDependencyResultEvent += value;
+ }
+ remove
+ {
+ RemoveUgcDependencyResultEvent -= value;
+ if (RemoveUgcDependencyResultEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.RemoveUgcDependencyResult,
+ Callable.From(_removeUgcDependencyResultAction)
+ );
+ }
+ }
+ }
+
+ public delegate void SetUserItemVoteSignalEventHandler(long result, long fileId, bool voteUp);
+ private static event SetUserItemVoteSignalEventHandler SetUserItemVoteSignalEvent;
+ static Action _setUserItemVoteSignalAction = (result, fileId, voteUp) =>
+ {
+ SetUserItemVoteSignalEvent?.Invoke(result, fileId, voteUp);
+ };
+ public static event SetUserItemVoteSignalEventHandler SetUserItemVoteSignal
+ {
+ add
+ {
+ if (SetUserItemVoteSignalEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.SetUserItemVoteSignal,
+ Callable.From(_setUserItemVoteSignalAction)
+ );
+ }
+ SetUserItemVoteSignalEvent += value;
+ }
+ remove
+ {
+ SetUserItemVoteSignalEvent -= value;
+ if (SetUserItemVoteSignalEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.SetUserItemVoteSignal,
+ Callable.From(_setUserItemVoteSignalAction)
+ );
+ }
+ }
+ }
+
+ public delegate void StartPlaytimeTrackingSignalEventHandler(long result);
+ private static event StartPlaytimeTrackingSignalEventHandler StartPlaytimeTrackingSignalEvent;
+ static Action _startPlaytimeTrackingSignalAction = (result) =>
+ {
+ StartPlaytimeTrackingSignalEvent?.Invoke(result);
+ };
+ public static event StartPlaytimeTrackingSignalEventHandler StartPlaytimeTrackingSignal
+ {
+ add
+ {
+ if (StartPlaytimeTrackingSignalEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.StartPlaytimeTrackingSignal,
+ Callable.From(_startPlaytimeTrackingSignalAction)
+ );
+ }
+ StartPlaytimeTrackingSignalEvent += value;
+ }
+ remove
+ {
+ StartPlaytimeTrackingSignalEvent -= value;
+ if (StartPlaytimeTrackingSignalEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.StartPlaytimeTrackingSignal,
+ Callable.From(_startPlaytimeTrackingSignalAction)
+ );
+ }
+ }
+ }
+
+ public delegate void UgcQueryCompletedEventHandler(
+ long handle,
+ long result,
+ long resultsReturned,
+ long totalMatching,
+ bool cached
+ );
+ private static event UgcQueryCompletedEventHandler UgcQueryCompletedEvent;
+ static Action _ugcQueryCompletedAction = (
+ handle,
+ result,
+ resultsReturned,
+ totalMatching,
+ cached
+ ) =>
+ {
+ UgcQueryCompletedEvent?.Invoke(handle, result, resultsReturned, totalMatching, cached);
+ };
+ public static event UgcQueryCompletedEventHandler UgcQueryCompleted
+ {
+ add
+ {
+ if (UgcQueryCompletedEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.UgcQueryCompleted, Callable.From(_ugcQueryCompletedAction));
+ }
+ UgcQueryCompletedEvent += value;
+ }
+ remove
+ {
+ UgcQueryCompletedEvent -= value;
+ if (UgcQueryCompletedEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.UgcQueryCompleted, Callable.From(_ugcQueryCompletedAction));
+ }
+ }
+ }
+
+ public delegate void StopPlaytimeTrackingSignalEventHandler(long result);
+ private static event StopPlaytimeTrackingSignalEventHandler StopPlaytimeTrackingSignalEvent;
+ static Action _stopPlaytimeTrackingSignalAction = (result) =>
+ {
+ StopPlaytimeTrackingSignalEvent?.Invoke(result);
+ };
+ public static event StopPlaytimeTrackingSignalEventHandler StopPlaytimeTrackingSignal
+ {
+ add
+ {
+ if (StopPlaytimeTrackingSignalEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.StopPlaytimeTrackingSignal,
+ Callable.From(_stopPlaytimeTrackingSignalAction)
+ );
+ }
+ StopPlaytimeTrackingSignalEvent += value;
+ }
+ remove
+ {
+ StopPlaytimeTrackingSignalEvent -= value;
+ if (StopPlaytimeTrackingSignalEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.StopPlaytimeTrackingSignal,
+ Callable.From(_stopPlaytimeTrackingSignalAction)
+ );
+ }
+ }
+ }
+
+ public delegate void ItemUpdatedEventHandler(long result, bool acceptTos);
+ private static event ItemUpdatedEventHandler ItemUpdatedEvent;
+ static Action _itemUpdatedAction = (result, acceptTos) =>
+ {
+ ItemUpdatedEvent?.Invoke(result, acceptTos);
+ };
+ public static event ItemUpdatedEventHandler ItemUpdated
+ {
+ add
+ {
+ if (ItemUpdatedEvent == null)
+ {
+ GetInstance().Connect(Signals.ItemUpdated, Callable.From(_itemUpdatedAction));
+ }
+ ItemUpdatedEvent += value;
+ }
+ remove
+ {
+ ItemUpdatedEvent -= value;
+ if (ItemUpdatedEvent == null)
+ {
+ GetInstance().Disconnect(Signals.ItemUpdated, Callable.From(_itemUpdatedAction));
+ }
+ }
+ }
+
+ public delegate void UserFavoriteItemsListChangedEventHandler(
+ long result,
+ long fileId,
+ bool wasAddRequest
+ );
+ private static event UserFavoriteItemsListChangedEventHandler UserFavoriteItemsListChangedEvent;
+ static Action _userFavoriteItemsListChangedAction = (
+ result,
+ fileId,
+ wasAddRequest
+ ) =>
+ {
+ UserFavoriteItemsListChangedEvent?.Invoke(result, fileId, wasAddRequest);
+ };
+ public static event UserFavoriteItemsListChangedEventHandler UserFavoriteItemsListChanged
+ {
+ add
+ {
+ if (UserFavoriteItemsListChangedEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.UserFavoriteItemsListChanged,
+ Callable.From(_userFavoriteItemsListChangedAction)
+ );
+ }
+ UserFavoriteItemsListChangedEvent += value;
+ }
+ remove
+ {
+ UserFavoriteItemsListChangedEvent -= value;
+ if (UserFavoriteItemsListChangedEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.UserFavoriteItemsListChanged,
+ Callable.From(_userFavoriteItemsListChangedAction)
+ );
+ }
+ }
+ }
+
+ public delegate void WorkshopEulaStatusEventHandler(
+ long result,
+ uint appId,
+ Godot.Collections.Dictionary eulaData
+ );
+ private static event WorkshopEulaStatusEventHandler WorkshopEulaStatusEvent;
+ static Action _workshopEulaStatusAction = (
+ result,
+ appId,
+ eulaData
+ ) =>
+ {
+ WorkshopEulaStatusEvent?.Invoke(result, appId, eulaData);
+ };
+ public static event WorkshopEulaStatusEventHandler WorkshopEulaStatus
+ {
+ add
+ {
+ if (WorkshopEulaStatusEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.WorkshopEulaStatus, Callable.From(_workshopEulaStatusAction));
+ }
+ WorkshopEulaStatusEvent += value;
+ }
+ remove
+ {
+ WorkshopEulaStatusEvent -= value;
+ if (WorkshopEulaStatusEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.WorkshopEulaStatus,
+ Callable.From(_workshopEulaStatusAction)
+ );
+ }
+ }
+ }
+
+ public delegate void UserSubscribedItemsListChangedEventHandler(uint appId);
+ private static event UserSubscribedItemsListChangedEventHandler UserSubscribedItemsListChangedEvent;
+ static Action _userSubscribedItemsListChangedAction = (appId) =>
+ {
+ UserSubscribedItemsListChangedEvent?.Invoke(appId);
+ };
+ public static event UserSubscribedItemsListChangedEventHandler UserSubscribedItemsListChanged
+ {
+ add
+ {
+ if (UserSubscribedItemsListChangedEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.UserSubscribedItemsListChanged,
+ Callable.From(_userSubscribedItemsListChangedAction)
+ );
+ }
+ UserSubscribedItemsListChangedEvent += value;
+ }
+ remove
+ {
+ UserSubscribedItemsListChangedEvent -= value;
+ if (UserSubscribedItemsListChangedEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.UserSubscribedItemsListChanged,
+ Callable.From(_userSubscribedItemsListChangedAction)
+ );
+ }
+ }
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.UGC.Signals.cs.uid b/addons/godotsteam_csharpbindings/Steam.UGC.Signals.cs.uid
new file mode 100644
index 00000000..65214452
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.UGC.Signals.cs.uid
@@ -0,0 +1 @@
+uid://syr4ofgum21r
diff --git a/addons/godotsteam_csharpbindings/Steam.UGC.cs b/addons/godotsteam_csharpbindings/Steam.UGC.cs
new file mode 100644
index 00000000..3b46480c
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.UGC.cs
@@ -0,0 +1,668 @@
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public static void AddAppDependency(ulong publishedFileId, uint appId)
+ {
+ GetInstance().Call(Methods.AddAppDependency, publishedFileId, appId);
+ }
+
+ public static bool AddContentDescriptor(ulong updateHandle, long descriptorId)
+ {
+ return GetInstance()
+ .Call(Methods.AddContentDescriptor, updateHandle, descriptorId)
+ .AsBool();
+ }
+
+ public static void AddDependency(ulong publishedFileId, long childPublishedFileId)
+ {
+ GetInstance().Call(Methods.AddDependency, publishedFileId, childPublishedFileId);
+ }
+
+ public static bool AddExcludedTag(ulong queryHandle, string tagName)
+ {
+ return GetInstance().Call(Methods.AddExcludedTag, queryHandle, tagName).AsBool();
+ }
+
+ public static bool AddItemKeyValueTag(ulong queryHandle, string key, string value)
+ {
+ return GetInstance().Call(Methods.AddItemKeyValueTag, queryHandle, key, value).AsBool();
+ }
+
+ public static bool AddItemPreviewFile(
+ ulong queryHandle,
+ string previewFile,
+ ItemPreviewType type
+ )
+ {
+ return GetInstance()
+ .Call(Methods.AddItemPreviewFile, queryHandle, previewFile, (long)type)
+ .AsBool();
+ }
+
+ public static bool AddItemPreviewVideo(ulong queryHandle, string videoId)
+ {
+ return GetInstance().Call(Methods.AddItemPreviewVideo, queryHandle, videoId).AsBool();
+ }
+
+ public static void AddItemToFavorites(uint appId, long publishedFileId)
+ {
+ GetInstance().Call(Methods.AddItemToFavorites, appId, publishedFileId);
+ }
+
+ public static bool AddRequiredKeyValueTag(ulong queryHandle, string key, string value)
+ {
+ return GetInstance().Call(Methods.AddRequiredKeyValueTag, queryHandle, key, value).AsBool();
+ }
+
+ public static bool AddRequiredTag(ulong queryHandle, string tagName)
+ {
+ return GetInstance().Call(Methods.AddRequiredTag, queryHandle, tagName).AsBool();
+ }
+
+ public static bool AddRequiredTagGroup(ulong queryHandle, Godot.Collections.Array tagArray)
+ {
+ return GetInstance().Call(Methods.AddRequiredTagGroup, queryHandle, tagArray).AsBool();
+ }
+
+ public static bool InitWorkshopForGameServer(long workshopDepotId)
+ {
+ return GetInstance().Call(Methods.InitWorkshopForGameServer, workshopDepotId).AsBool();
+ }
+
+ public static void CreateItem(uint appId, WorkshopFileType fileType)
+ {
+ GetInstance().Call(Methods.CreateItem, appId, (long)fileType);
+ }
+
+ public static ulong CreateQueryAllUGCRequest(
+ UgcQuery queryType,
+ UgcMatchingUgcType matchingType,
+ uint creatorId,
+ uint consumerId,
+ long page
+ )
+ {
+ return GetInstance()
+ .Call(
+ Methods.CreateQueryAllUGCRequest,
+ (long)queryType,
+ (long)matchingType,
+ creatorId,
+ consumerId,
+ page
+ )
+ .AsUInt64();
+ }
+
+ public static ulong CreateQueryUGCDetailsRequest(Godot.Collections.Array publishedFileId)
+ {
+ return GetInstance().Call(Methods.CreateQueryUGCDetailsRequest, publishedFileId).AsUInt64();
+ }
+
+ public static ulong CreateQueryUserUGCRequest(
+ ulong accountId,
+ UserUgcList listType,
+ UgcMatchingUgcType matchingUgcType,
+ UserUgcListSortOrder sortOrder,
+ uint creatorId,
+ uint consumerId,
+ long page
+ )
+ {
+ return GetInstance()
+ .Call(
+ Methods.CreateQueryUserUGCRequest,
+ accountId,
+ (long)listType,
+ (long)matchingUgcType,
+ (long)sortOrder,
+ creatorId,
+ consumerId,
+ page
+ )
+ .AsUInt64();
+ }
+
+ public static void DeleteItem(long publishedFileId)
+ {
+ GetInstance().Call(Methods.DeleteItem, publishedFileId);
+ }
+
+ public static bool DownloadItem(ulong publishedFileId, bool highPriority)
+ {
+ return GetInstance().Call(Methods.DownloadItem, publishedFileId, highPriority).AsBool();
+ }
+
+ public static Godot.Collections.Dictionary GetItemDownloadInfo(long publishedFileId)
+ {
+ return GetInstance().Call(Methods.GetItemDownloadInfo, publishedFileId).AsGodotDictionary();
+ }
+
+ public static Godot.Collections.Dictionary GetItemInstallInfo(long publishedFileId)
+ {
+ return GetInstance().Call(Methods.GetItemInstallInfo, publishedFileId).AsGodotDictionary();
+ }
+
+ public static uint GetItemState(long publishedFileId)
+ {
+ return GetInstance().Call(Methods.GetItemState, publishedFileId).AsUInt32();
+ }
+
+ public static Godot.Collections.Dictionary GetItemUpdateProgress(long updateHandle)
+ {
+ return GetInstance().Call(Methods.GetItemUpdateProgress, updateHandle).AsGodotDictionary();
+ }
+
+ public static long GetNumSubscribedItems()
+ {
+ return GetInstance().Call(Methods.GetNumSubscribedItems).AsInt64();
+ }
+
+ public static Godot.Collections.Dictionary GetQueryUGCAdditionalPreview(
+ ulong queryHandle,
+ uint index,
+ long previewIndex
+ )
+ {
+ return GetInstance()
+ .Call(Methods.GetQueryUGCAdditionalPreview, queryHandle, index, previewIndex)
+ .AsGodotDictionary();
+ }
+
+ public static Godot.Collections.Dictionary GetQueryUGCChildren(
+ ulong queryHandle,
+ uint index,
+ long childCount
+ )
+ {
+ return GetInstance()
+ .Call(Methods.GetQueryUGCChildren, queryHandle, index, childCount)
+ .AsGodotDictionary();
+ }
+
+ public static Godot.Collections.Dictionary GetQueryUGCContentDescriptors(
+ ulong queryHandle,
+ uint index,
+ long maxEntries
+ )
+ {
+ return GetInstance()
+ .Call(Methods.GetQueryUGCContentDescriptors, queryHandle, index, maxEntries)
+ .AsGodotDictionary();
+ }
+
+ public static Godot.Collections.Dictionary GetQueryUGCKeyValueTag(
+ ulong queryHandle,
+ uint index,
+ long keyValueTagIndex
+ )
+ {
+ return GetInstance()
+ .Call(Methods.GetQueryUGCKeyValueTag, queryHandle, index, keyValueTagIndex)
+ .AsGodotDictionary();
+ }
+
+ public static string GetQueryUGCMetadata(ulong queryHandle, long index)
+ {
+ return GetInstance().Call(Methods.GetQueryUGCMetadata, queryHandle, index).AsString();
+ }
+
+ public static uint GetQueryUGCNumAdditionalPreviews(ulong queryHandle, long index)
+ {
+ return GetInstance()
+ .Call(Methods.GetQueryUGCNumAdditionalPreviews, queryHandle, index)
+ .AsUInt32();
+ }
+
+ public static uint GetQueryUGCNumKeyValueTags(ulong queryHandle, long index)
+ {
+ return GetInstance()
+ .Call(Methods.GetQueryUGCNumKeyValueTags, queryHandle, index)
+ .AsUInt32();
+ }
+
+ public static uint GetQueryUGCNumTags(ulong queryHandle, long index)
+ {
+ return GetInstance().Call(Methods.GetQueryUGCNumTags, queryHandle, index).AsUInt32();
+ }
+
+ public static string GetQueryUGCPreviewURL(ulong queryHandle, long index)
+ {
+ return GetInstance().Call(Methods.GetQueryUGCPreviewURL, queryHandle, index).AsString();
+ }
+
+ public static Godot.Collections.Dictionary GetQueryUGCResult(ulong queryHandle, long index)
+ {
+ return GetInstance()
+ .Call(Methods.GetQueryUGCResult, queryHandle, index)
+ .AsGodotDictionary();
+ }
+
+ public static Godot.Collections.Dictionary GetQueryUGCStatistic(
+ ulong queryHandle,
+ uint index,
+ ItemStatistic statType
+ )
+ {
+ return GetInstance()
+ .Call(Methods.GetQueryUGCStatistic, queryHandle, index, (long)statType)
+ .AsGodotDictionary();
+ }
+
+ public static string GetQueryUGCTag(ulong queryHandle, uint index, long tagIndex)
+ {
+ return GetInstance().Call(Methods.GetQueryUGCTag, queryHandle, index, tagIndex).AsString();
+ }
+
+ public static string GetQueryUGCTagDisplayName(ulong queryHandle, uint index, long tagIndex)
+ {
+ return GetInstance()
+ .Call(Methods.GetQueryUGCTagDisplayName, queryHandle, index, tagIndex)
+ .AsString();
+ }
+
+ public static Godot.Collections.Array GetSubscribedItems()
+ {
+ return GetInstance().Call(Methods.GetSubscribedItems).AsGodotArray();
+ }
+
+ public static Godot.Collections.Array GetUserContentDescriptorPreferences(long maxEntries)
+ {
+ return GetInstance()
+ .Call(Methods.GetUserContentDescriptorPreferences, maxEntries)
+ .AsGodotArray();
+ }
+
+ public static void GetUserItemVote(long publishedFileId)
+ {
+ GetInstance().Call(Methods.GetUserItemVote, publishedFileId);
+ }
+
+ public static bool ReleaseQueryUGCRequest(long queryHandle)
+ {
+ return GetInstance().Call(Methods.ReleaseQueryUGCRequest, queryHandle).AsBool();
+ }
+
+ public static void RemoveAppDependency(ulong publishedFileId, uint appId)
+ {
+ GetInstance().Call(Methods.RemoveAppDependency, publishedFileId, appId);
+ }
+
+ public static bool RemoveContentDescriptor(ulong updateHandle, long descriptorId)
+ {
+ return GetInstance()
+ .Call(Methods.RemoveContentDescriptor, updateHandle, descriptorId)
+ .AsBool();
+ }
+
+ public static void RemoveDependency(ulong publishedFileId, long childPublishedFileId)
+ {
+ GetInstance().Call(Methods.RemoveDependency, publishedFileId, childPublishedFileId);
+ }
+
+ public static void RemoveItemFromFavorites(uint appId, long publishedFileId)
+ {
+ GetInstance().Call(Methods.RemoveItemFromFavorites, appId, publishedFileId);
+ }
+
+ public static bool RemoveItemKeyValueTags(ulong updateHandle, string key)
+ {
+ return GetInstance().Call(Methods.RemoveItemKeyValueTags, updateHandle, key).AsBool();
+ }
+
+ public static bool RemoveItemPreview(ulong updateHandle, long index)
+ {
+ return GetInstance().Call(Methods.RemoveItemPreview, updateHandle, index).AsBool();
+ }
+
+ public static void SendQueryUGCRequest(long updateHandle)
+ {
+ GetInstance().Call(Methods.SendQueryUGCRequest, updateHandle);
+ }
+
+ public static bool SetAllowCachedResponse(ulong updateHandle, long maxAgeSeconds)
+ {
+ return GetInstance()
+ .Call(Methods.SetAllowCachedResponse, updateHandle, maxAgeSeconds)
+ .AsBool();
+ }
+
+ public static bool SetCloudFileNameFilter(ulong updateHandle, string matchCloudFileName)
+ {
+ return GetInstance()
+ .Call(Methods.SetCloudFileNameFilter, updateHandle, matchCloudFileName)
+ .AsBool();
+ }
+
+ public static bool SetItemContent(ulong updateHandle, string contentFolder)
+ {
+ return GetInstance().Call(Methods.SetItemContent, updateHandle, contentFolder).AsBool();
+ }
+
+ public static bool SetItemDescription(ulong updateHandle, string description)
+ {
+ return GetInstance().Call(Methods.SetItemDescription, updateHandle, description).AsBool();
+ }
+
+ public static bool SetItemMetadata(ulong updateHandle, string ugcMetadata)
+ {
+ return GetInstance().Call(Methods.SetItemMetadata, updateHandle, ugcMetadata).AsBool();
+ }
+
+ public static bool SetItemPreview(ulong updateHandle, string previewFile)
+ {
+ return GetInstance().Call(Methods.SetItemPreview, updateHandle, previewFile).AsBool();
+ }
+
+ public static bool SetItemTags(
+ ulong updateHandle,
+ Godot.Collections.Array tagArray,
+ bool allowAdminTags = false
+ )
+ {
+ return GetInstance()
+ .Call(Methods.SetItemTags, updateHandle, tagArray, allowAdminTags)
+ .AsBool();
+ }
+
+ public static bool SetItemTitle(ulong updateHandle, string title)
+ {
+ return GetInstance().Call(Methods.SetItemTitle, updateHandle, title).AsBool();
+ }
+
+ public static bool SetItemUpdateLanguage(ulong updateHandle, string language)
+ {
+ return GetInstance().Call(Methods.SetItemUpdateLanguage, updateHandle, language).AsBool();
+ }
+
+ public static bool SetItemVisibility(
+ ulong updateHandle,
+ RemoteStoragePublishedFileVisibility visibility
+ )
+ {
+ return GetInstance()
+ .Call(Methods.SetItemVisibility, updateHandle, (long)visibility)
+ .AsBool();
+ }
+
+ public static bool SetLanguage(ulong queryHandle, string language)
+ {
+ return GetInstance().Call(Methods.SetLanguage, queryHandle, language).AsBool();
+ }
+
+ public static bool SetMatchAnyTag(ulong queryHandle, bool matchAnyTag)
+ {
+ return GetInstance().Call(Methods.SetMatchAnyTag, queryHandle, matchAnyTag).AsBool();
+ }
+
+ public static bool SetRankedByTrendDays(ulong queryHandle, long days)
+ {
+ return GetInstance().Call(Methods.SetRankedByTrendDays, queryHandle, days).AsBool();
+ }
+
+ public static bool SetReturnAdditionalPreviews(ulong queryHandle, bool returnAdditionalPreviews)
+ {
+ return GetInstance()
+ .Call(Methods.SetReturnAdditionalPreviews, queryHandle, returnAdditionalPreviews)
+ .AsBool();
+ }
+
+ public static bool SetReturnChildren(ulong queryHandle, bool returnChildren)
+ {
+ return GetInstance().Call(Methods.SetReturnChildren, queryHandle, returnChildren).AsBool();
+ }
+
+ public static bool SetReturnKeyValueTags(ulong queryHandle, bool returnKeyValueTags)
+ {
+ return GetInstance()
+ .Call(Methods.SetReturnKeyValueTags, queryHandle, returnKeyValueTags)
+ .AsBool();
+ }
+
+ public static bool SetReturnLongDescription(ulong queryHandle, bool returnLongDescription)
+ {
+ return GetInstance()
+ .Call(Methods.SetReturnLongDescription, queryHandle, returnLongDescription)
+ .AsBool();
+ }
+
+ public static bool SetReturnMetadata(ulong queryHandle, bool returnMetadata)
+ {
+ return GetInstance().Call(Methods.SetReturnMetadata, queryHandle, returnMetadata).AsBool();
+ }
+
+ public static bool SetReturnOnlyIDs(ulong queryHandle, bool returnOnlyIds)
+ {
+ return GetInstance().Call(Methods.SetReturnOnlyIDs, queryHandle, returnOnlyIds).AsBool();
+ }
+
+ public static bool SetReturnPlaytimeStats(ulong queryHandle, long days)
+ {
+ return GetInstance().Call(Methods.SetReturnPlaytimeStats, queryHandle, days).AsBool();
+ }
+
+ public static bool SetReturnTotalOnly(ulong queryHandle, bool returnTotalOnly)
+ {
+ return GetInstance()
+ .Call(Methods.SetReturnTotalOnly, queryHandle, returnTotalOnly)
+ .AsBool();
+ }
+
+ public static bool SetSearchText(ulong queryHandle, string searchText)
+ {
+ return GetInstance().Call(Methods.SetSearchText, queryHandle, searchText).AsBool();
+ }
+
+ public static void SetUserItemVote(ulong publishedFileId, bool voteUp)
+ {
+ GetInstance().Call(Methods.SetUserItemVote, publishedFileId, voteUp);
+ }
+
+ public static ulong StartItemUpdate(uint appId, long fileId)
+ {
+ return GetInstance().Call(Methods.StartItemUpdate, appId, fileId).AsUInt64();
+ }
+
+ public static void StartPlaytimeTracking(Godot.Collections.Array publishedFileIds)
+ {
+ GetInstance().Call(Methods.StartPlaytimeTracking, publishedFileIds);
+ }
+
+ public static void StopPlaytimeTracking(Godot.Collections.Array publishedFileIds)
+ {
+ GetInstance().Call(Methods.StopPlaytimeTracking, publishedFileIds);
+ }
+
+ public static void StopPlaytimeTrackingForAllItems()
+ {
+ GetInstance().Call(Methods.StopPlaytimeTrackingForAllItems);
+ }
+
+ public static void GetAppDependencies(long publishedFileId)
+ {
+ GetInstance().Call(Methods.GetAppDependencies, publishedFileId);
+ }
+
+ public static void SubmitItemUpdate(ulong updateHandle, string changeNote)
+ {
+ GetInstance().Call(Methods.SubmitItemUpdate, updateHandle, changeNote);
+ }
+
+ public static void SubscribeItem(long publishedFileId)
+ {
+ GetInstance().Call(Methods.SubscribeItem, publishedFileId);
+ }
+
+ public static void SuspendDownloads(bool suspend)
+ {
+ GetInstance().Call(Methods.SuspendDownloads, suspend);
+ }
+
+ public static void UnsubscribeItem(long publishedFileId)
+ {
+ GetInstance().Call(Methods.UnsubscribeItem, publishedFileId);
+ }
+
+ public static bool UpdateItemPreviewFile(ulong updateHandle, uint index, string previewFile)
+ {
+ return GetInstance()
+ .Call(Methods.UpdateItemPreviewFile, updateHandle, index, previewFile)
+ .AsBool();
+ }
+
+ public static bool UpdateItemPreviewVideo(ulong updateHandle, uint index, string videoId)
+ {
+ return GetInstance()
+ .Call(Methods.UpdateItemPreviewVideo, updateHandle, index, videoId)
+ .AsBool();
+ }
+
+ public static bool ShowWorkshopEULA()
+ {
+ return GetInstance().Call(Methods.ShowWorkshopEULA).AsBool();
+ }
+
+ public static void GetWorkshopEULAStatus()
+ {
+ GetInstance().Call(Methods.GetWorkshopEULAStatus);
+ }
+
+ public static bool SetTimeCreatedDateRange(ulong updateHandle, uint start, long end)
+ {
+ return GetInstance()
+ .Call(Methods.SetTimeCreatedDateRange, updateHandle, start, end)
+ .AsBool();
+ }
+
+ public static bool SetTimeUpdatedDateRange(ulong updateHandle, uint start, long end)
+ {
+ return GetInstance()
+ .Call(Methods.SetTimeUpdatedDateRange, updateHandle, start, end)
+ .AsBool();
+ }
+
+ public enum ItemPreviewType : long
+ {
+ Image = 0,
+ YoutubeVideo = 1,
+ Sketchfab = 2,
+ EnvironmentmapHorizontalCross = 3,
+ EnvironmentmapLatLong = 4,
+ ReservedMax = 255,
+ }
+
+ [System.Flags]
+ public enum ItemState : long
+ {
+ None = 0,
+ Subscribed = 1,
+ LegacyItem = 2,
+ Installed = 4,
+ NeedsUpdate = 8,
+ Downloading = 16,
+ DownloadPending = 32,
+ }
+
+ public enum ItemStatistic : long
+ {
+ NumSubscriptions = 0,
+ NumFavorites = 1,
+ NumFollowers = 2,
+ NumUniqueSubscriptions = 3,
+ NumUniqueFavorites = 4,
+ NumUniqueFollowers = 5,
+ NumUniqueWebsiteViews = 6,
+ ReportScore = 7,
+ NumSecondsPlayed = 8,
+ NumPlaytimeSessions = 9,
+ NumComments = 10,
+ NumSecondsPlayedDuringTimePeriod = 11,
+ NumPlaytimeSessionsDuringTimePeriod = 12,
+ }
+
+ public enum ItemUpdateStatus : long
+ {
+ Invalid = 0,
+ PreparingConfig = 1,
+ PreparingContent = 2,
+ UploadingContent = 3,
+ UploadingPreviewFile = 4,
+ CommittingChanges = 5,
+ }
+
+ public enum UserUgcList : long
+ {
+ Published = 0,
+ VotedOn = 1,
+ VotedUp = 2,
+ VotedDown = 3,
+ WillVoteLater = 4,
+ Favorited = 5,
+ Subscribed = 6,
+ UsedOrPlayed = 7,
+ Followed = 8,
+ }
+
+ public enum UserUgcListSortOrder : long
+ {
+ UserugclistsortorderCreationorderdesc = 0,
+ UserugclistsortorderCreationorderasc = 1,
+ UserugclistsortorderTitleasc = 2,
+ UserugclistsortorderLastupdateddesc = 3,
+ UserugclistsortorderSubscriptiondatedesc = 4,
+ UserugclistsortorderVotescoredesc = 5,
+ SerugclistsortorderFormoderation = 6,
+ }
+
+ public enum UgcQuery : long
+ {
+ RankedByVote = 0,
+ RankedByPublicationDate = 1,
+ AcceptedForGameRankedByAcceptanceDate = 2,
+ RankedByTrend = 3,
+ FavoritedByFriendsRankedByPublicationDate = 4,
+ CreatedByFriendsRankedByPublicationDate = 5,
+ RankedByNumTimesReported = 6,
+ CreatedByFollowedUsersRankedByPublicationDate = 7,
+ NotYetRated = 8,
+ RankedByTotalVotesAsc = 9,
+ RankedByVotesUp = 10,
+ RankedByTextSearch = 11,
+ RankedByTotalUniqueSubscriptions = 12,
+ RankedByPlaytimeTrend = 13,
+ RankedByTotalPlaytime = 14,
+ RankedByAveragePlaytimeTrend = 15,
+ RankedByLifetimeAveragePlaytime = 16,
+ RankedByPlaytimeSessionsTrend = 17,
+ RankedByLifetimePlaytimeSessions = 18,
+ RankedByLastUpdatedDate = 19,
+ }
+
+ public enum UgcContentDescriptorId : long
+ {
+ NudityOrSexualContent = 1,
+ FrequentViolenceOrGore = 2,
+ AdultOnlySexualContent = 3,
+ GratuitousSexualContent = 4,
+ AnyMatureContent = 5,
+ }
+
+ public enum UgcMatchingUgcType : long
+ {
+ MatchingugctypeItems = 0,
+ MatchingUgcTypeItemsMtx = 1,
+ MatchingUgcTypeItemsReadyToUse = 2,
+ MatchingUgcTypeCollections = 3,
+ MatchingUgcTypeArtwork = 4,
+ MatchingUgcTypeVideos = 5,
+ MatchingUgcTypeScreenshots = 6,
+ MatchingUgcTypeAllGuides = 7,
+ MatchingUgcTypeWebGuides = 8,
+ MatchingUgcTypeIntegratedGuides = 9,
+ MatchingUgcTypeUsableInGame = 10,
+ MatchingUgcTypeControllerBindings = 11,
+ MatchingUgcTypeGameManagedItems = 12,
+ MatchingUgcTypeAll = -1,
+ }
+}
diff --git a/addons/godotsteam_csharpbindings/Steam.UGC.cs.uid b/addons/godotsteam_csharpbindings/Steam.UGC.cs.uid
new file mode 100644
index 00000000..48248ebe
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.UGC.cs.uid
@@ -0,0 +1 @@
+uid://bf0suxxpxh6yw
diff --git a/addons/godotsteam_csharpbindings/Steam.User.Signals.cs b/addons/godotsteam_csharpbindings/Steam.User.Signals.cs
new file mode 100644
index 00000000..14570189
--- /dev/null
+++ b/addons/godotsteam_csharpbindings/Steam.User.Signals.cs
@@ -0,0 +1,492 @@
+using System;
+using Godot;
+
+namespace GodotSteam;
+
+public static partial class Steam
+{
+ public delegate void DurationControlEventHandler(
+ long result,
+ Godot.Collections.Dictionary duration
+ );
+ private static event DurationControlEventHandler DurationControlEvent;
+ static Action _durationControlAction = (result, duration) =>
+ {
+ DurationControlEvent?.Invoke(result, duration);
+ };
+ public static event DurationControlEventHandler DurationControl
+ {
+ add
+ {
+ if (DurationControlEvent == null)
+ {
+ GetInstance()
+ .Connect(Signals.DurationControl, Callable.From(_durationControlAction));
+ }
+ DurationControlEvent += value;
+ }
+ remove
+ {
+ DurationControlEvent -= value;
+ if (DurationControlEvent == null)
+ {
+ GetInstance()
+ .Disconnect(Signals.DurationControl, Callable.From(_durationControlAction));
+ }
+ }
+ }
+
+ public delegate void ClientGameServerDenyEventHandler(
+ uint appId,
+ string iP,
+ long serverPort,
+ long secure,
+ long reason
+ );
+ private static event ClientGameServerDenyEventHandler ClientGameServerDenyEvent;
+ static Action _clientGameServerDenyAction = (
+ appId,
+ iP,
+ serverPort,
+ secure,
+ reason
+ ) =>
+ {
+ ClientGameServerDenyEvent?.Invoke(appId, iP, serverPort, secure, reason);
+ };
+ public static event ClientGameServerDenyEventHandler ClientGameServerDeny
+ {
+ add
+ {
+ if (ClientGameServerDenyEvent == null)
+ {
+ GetInstance()
+ .Connect(
+ Signals.ClientGameServerDeny,
+ Callable.From(_clientGameServerDenyAction)
+ );
+ }
+ ClientGameServerDenyEvent += value;
+ }
+ remove
+ {
+ ClientGameServerDenyEvent -= value;
+ if (ClientGameServerDenyEvent == null)
+ {
+ GetInstance()
+ .Disconnect(
+ Signals.ClientGameServerDeny,
+ Callable.From(_clientGameServerDenyAction)
+ );
+ }
+ }
+ }
+
+ public delegate void EncryptedAppTicketResponseEventHandler(string result);
+ private static event EncryptedAppTicketResponseEventHandler EncryptedAppTicketResponseEvent;
+ static Action