From ef8447c873d61e38686989388647af7f207f564d Mon Sep 17 00:00:00 2001 From: Andus Date: Sun, 17 Mar 2024 18:36:33 +0100 Subject: [PATCH] Glass of water, Furniture, Points, Timer --- ...s.png-3b2015c0dd629c60d3c1b09d9013c59c.md5 | 3 + ....png-3b2015c0dd629c60d3c1b09d9013c59c.stex | Bin 0 -> 116 bytes ...s.png-8678c0300c4ceb28841173a60adcbab3.md5 | 3 + ....png-8678c0300c4ceb28841173a60adcbab3.stex | Bin 0 -> 150 bytes ...4.png-dc833624655055ecbac60caa1ff8c787.md5 | 3 + ....png-dc833624655055ecbac60caa1ff8c787.stex | Bin 0 -> 176 bytes ...5.png-5996b0b5e4a48ab5d0c5454fa98a17bd.md5 | 3 + ....png-5996b0b5e4a48ab5d0c5454fa98a17bd.stex | Bin 0 -> 168 bytes ...6.png-f5c5c36d0c8e2c99b2c8998b12e2dca2.md5 | 3 + ....png-f5c5c36d0c8e2c99b2c8998b12e2dca2.stex | Bin 0 -> 162 bytes ...7.png-e5599ba2a6360063be55af65767b9beb.md5 | 3 + ....png-e5599ba2a6360063be55af65767b9beb.stex | Bin 0 -> 174 bytes ...8.png-058c48e4cc637de37413544fee2a9a2b.md5 | 3 + ....png-058c48e4cc637de37413544fee2a9a2b.stex | Bin 0 -> 132 bytes ...9.png-50a7db6b6a1fee5a30051fa84f0c1a0b.md5 | 3 + ....png-50a7db6b6a1fee5a30051fa84f0c1a0b.stex | Bin 0 -> 132 bytes ...g.png-5046840dce817dc9e1d61a818df550fc.md5 | 3 + ....png-5046840dce817dc9e1d61a818df550fc.stex | Bin 0 -> 66 bytes ....sfxr-c1c1594a22628fd278421b7f8a79a149.md5 | 3 + ...xr-c1c1594a22628fd278421b7f8a79a149.sample | Bin 0 -> 17773 bytes ...r.png-bad02a3061f4734a68e01c2ddec9b22e.md5 | 4 +- ....png-bad02a3061f4734a68e01c2ddec9b22e.stex | Bin 82 -> 92 bytes ...n.png-487276ed1e3a0c39cad0279d744ee560.md5 | 4 +- ....png-487276ed1e3a0c39cad0279d744ee560.stex | Bin 1496 -> 270 bytes ...w.PNG-3372de55fcb4add320565bad41f71587.md5 | 3 + ...s.png-1546df883425497bf4494dd92b12d7b4.md5 | 3 + ....png-1546df883425497bf4494dd92b12d7b4.stex | Bin 0 -> 70 bytes ....sfxr-ce24cf25ac6de08473bbda5685c58ae5.md5 | 3 + ...xr-ce24cf25ac6de08473bbda5685c58ae5.sample | Bin 0 -> 8273 bytes ...e.png-6287c5224e3a2223ad79685cc0bf8f85.md5 | 3 + ....png-6287c5224e3a2223ad79685cc0bf8f85.stex | Bin 0 -> 120 bytes ...r.png-d21cca1445c6a2663bc52f4f2384a623.md5 | 3 + ....png-d21cca1445c6a2663bc52f4f2384a623.stex | Bin 0 -> 70 bytes ...e.png-67445500d100c0d821e09597f4b6463a.md5 | 3 + ....png-67445500d100c0d821e09597f4b6463a.stex | Bin 0 -> 134 bytes Scenes/End.tscn | 44 ++ Scenes/Game.tscn | 75 ++- Scenes/Player.tscn | 20 +- Scenes/Start.tscn | 86 +++ Scenes/WaterThings/Glass.tscn | 28 + Scenes/WaterThings/Jug.tscn | 14 +- Scripts/End.gd | 4 + Scripts/Game.gd | 7 + Scripts/Player.gd | 4 +- Scripts/Start.gd | 4 + Scripts/Utils.gd | 3 + Scripts/WaterThing.gd | 20 +- Sounds/Sfxr/break.sfxr | Bin 0 -> 105 bytes Sounds/Sfxr/break.sfxr.import | 16 + Sounds/Sfxr/punch.sfxr | Bin 0 -> 105 bytes Sounds/Sfxr/punch.sfxr.import | 16 + Sprites/Water/Broken/Glass.png | Bin 0 -> 142 bytes Sprites/Water/Broken/Glass.png.import | 35 ++ Sprites/Water/Glass.png | Bin 0 -> 171 bytes Sprites/Water/Glass.png.import | 35 ++ Sprites/bg.png | Bin 0 -> 70 bytes Sprites/bg.png.import | 35 ++ Sprites/floor.png | Bin 115 -> 115 bytes Sprites/furniture.tres | 68 +++ Sprites/table.png | Bin 0 -> 132 bytes Sprites/table.png.import | 35 ++ Sprites/wardrobe.png | Bin 0 -> 159 bytes Sprites/wardrobe.png.import | 35 ++ addons/gdfxr/Base58.gd | 38 ++ addons/gdfxr/LICENSE | 7 + addons/gdfxr/SFXRConfig.gd | 511 ++++++++++++++++++ addons/gdfxr/SFXRGenerator.gd | 274 ++++++++++ addons/gdfxr/editor/EditSlider.gd | 203 +++++++ addons/gdfxr/editor/Editor.gd | 387 +++++++++++++ addons/gdfxr/editor/Editor.tscn | 394 ++++++++++++++ addons/gdfxr/editor/EditorIconButton.gd | 16 + addons/gdfxr/editor/ParamOption.gd | 43 ++ addons/gdfxr/editor/ParamOption.tscn | 43 ++ addons/gdfxr/editor/ParamSlider.gd | 43 ++ addons/gdfxr/editor/ParamSlider.tscn | 42 ++ addons/gdfxr/editor/PluginTranslator.gd | 56 ++ addons/gdfxr/editor/PluginTranslator.tscn | 6 + addons/gdfxr/editor/VersionButton.gd | 25 + addons/gdfxr/editor/VersionButton.tscn | 19 + addons/gdfxr/editor/translations/zh_CN.po | 265 +++++++++ addons/gdfxr/import_plugin.gd | 76 +++ addons/gdfxr/plugin.cfg | 7 + addons/gdfxr/plugin.gd | 39 ++ fonts/dotty.ttf | Bin 0 -> 51848 bytes fonts/game over.ttf | Bin 0 -> 8416 bytes icon.png | Bin 3305 -> 660 bytes project.godot | 9 + 87 files changed, 3115 insertions(+), 28 deletions(-) create mode 100644 .import/Glass.png-3b2015c0dd629c60d3c1b09d9013c59c.md5 create mode 100644 .import/Glass.png-3b2015c0dd629c60d3c1b09d9013c59c.stex create mode 100644 .import/Glass.png-8678c0300c4ceb28841173a60adcbab3.md5 create mode 100644 .import/Glass.png-8678c0300c4ceb28841173a60adcbab3.stex create mode 100644 .import/Icon_4.png-dc833624655055ecbac60caa1ff8c787.md5 create mode 100644 .import/Icon_4.png-dc833624655055ecbac60caa1ff8c787.stex create mode 100644 .import/Icon_5.png-5996b0b5e4a48ab5d0c5454fa98a17bd.md5 create mode 100644 .import/Icon_5.png-5996b0b5e4a48ab5d0c5454fa98a17bd.stex create mode 100644 .import/Icon_6.png-f5c5c36d0c8e2c99b2c8998b12e2dca2.md5 create mode 100644 .import/Icon_6.png-f5c5c36d0c8e2c99b2c8998b12e2dca2.stex create mode 100644 .import/Icon_7.png-e5599ba2a6360063be55af65767b9beb.md5 create mode 100644 .import/Icon_7.png-e5599ba2a6360063be55af65767b9beb.stex create mode 100644 .import/Icon_8.png-058c48e4cc637de37413544fee2a9a2b.md5 create mode 100644 .import/Icon_8.png-058c48e4cc637de37413544fee2a9a2b.stex create mode 100644 .import/Icon_9.png-50a7db6b6a1fee5a30051fa84f0c1a0b.md5 create mode 100644 .import/Icon_9.png-50a7db6b6a1fee5a30051fa84f0c1a0b.stex create mode 100644 .import/bg.png-5046840dce817dc9e1d61a818df550fc.md5 create mode 100644 .import/bg.png-5046840dce817dc9e1d61a818df550fc.stex create mode 100644 .import/break.sfxr-c1c1594a22628fd278421b7f8a79a149.md5 create mode 100644 .import/break.sfxr-c1c1594a22628fd278421b7f8a79a149.sample create mode 100644 .import/overview.PNG-3372de55fcb4add320565bad41f71587.md5 create mode 100644 .import/progress.png-1546df883425497bf4494dd92b12d7b4.md5 create mode 100644 .import/progress.png-1546df883425497bf4494dd92b12d7b4.stex create mode 100644 .import/punch.sfxr-ce24cf25ac6de08473bbda5685c58ae5.md5 create mode 100644 .import/punch.sfxr-ce24cf25ac6de08473bbda5685c58ae5.sample create mode 100644 .import/table.png-6287c5224e3a2223ad79685cc0bf8f85.md5 create mode 100644 .import/table.png-6287c5224e3a2223ad79685cc0bf8f85.stex create mode 100644 .import/under.png-d21cca1445c6a2663bc52f4f2384a623.md5 create mode 100644 .import/under.png-d21cca1445c6a2663bc52f4f2384a623.stex create mode 100644 .import/wardrobe.png-67445500d100c0d821e09597f4b6463a.md5 create mode 100644 .import/wardrobe.png-67445500d100c0d821e09597f4b6463a.stex create mode 100644 Scenes/End.tscn create mode 100644 Scenes/Start.tscn create mode 100644 Scenes/WaterThings/Glass.tscn create mode 100644 Scripts/End.gd create mode 100644 Scripts/Game.gd create mode 100644 Scripts/Start.gd create mode 100644 Scripts/Utils.gd create mode 100644 Sounds/Sfxr/break.sfxr create mode 100644 Sounds/Sfxr/break.sfxr.import create mode 100644 Sounds/Sfxr/punch.sfxr create mode 100644 Sounds/Sfxr/punch.sfxr.import create mode 100644 Sprites/Water/Broken/Glass.png create mode 100644 Sprites/Water/Broken/Glass.png.import create mode 100644 Sprites/Water/Glass.png create mode 100644 Sprites/Water/Glass.png.import create mode 100644 Sprites/bg.png create mode 100644 Sprites/bg.png.import create mode 100644 Sprites/furniture.tres create mode 100644 Sprites/table.png create mode 100644 Sprites/table.png.import create mode 100644 Sprites/wardrobe.png create mode 100644 Sprites/wardrobe.png.import create mode 100644 addons/gdfxr/Base58.gd create mode 100644 addons/gdfxr/LICENSE create mode 100644 addons/gdfxr/SFXRConfig.gd create mode 100644 addons/gdfxr/SFXRGenerator.gd create mode 100644 addons/gdfxr/editor/EditSlider.gd create mode 100644 addons/gdfxr/editor/Editor.gd create mode 100644 addons/gdfxr/editor/Editor.tscn create mode 100644 addons/gdfxr/editor/EditorIconButton.gd create mode 100644 addons/gdfxr/editor/ParamOption.gd create mode 100644 addons/gdfxr/editor/ParamOption.tscn create mode 100644 addons/gdfxr/editor/ParamSlider.gd create mode 100644 addons/gdfxr/editor/ParamSlider.tscn create mode 100644 addons/gdfxr/editor/PluginTranslator.gd create mode 100644 addons/gdfxr/editor/PluginTranslator.tscn create mode 100644 addons/gdfxr/editor/VersionButton.gd create mode 100644 addons/gdfxr/editor/VersionButton.tscn create mode 100644 addons/gdfxr/editor/translations/zh_CN.po create mode 100644 addons/gdfxr/import_plugin.gd create mode 100644 addons/gdfxr/plugin.cfg create mode 100644 addons/gdfxr/plugin.gd create mode 100644 fonts/dotty.ttf create mode 100644 fonts/game over.ttf diff --git a/.import/Glass.png-3b2015c0dd629c60d3c1b09d9013c59c.md5 b/.import/Glass.png-3b2015c0dd629c60d3c1b09d9013c59c.md5 new file mode 100644 index 0000000..df63c5b --- /dev/null +++ b/.import/Glass.png-3b2015c0dd629c60d3c1b09d9013c59c.md5 @@ -0,0 +1,3 @@ +source_md5="e48338fdf043e69d0c0549bc35a336d3" +dest_md5="80b05a4161e3e44efe54c5f703abc6a1" + diff --git a/.import/Glass.png-3b2015c0dd629c60d3c1b09d9013c59c.stex b/.import/Glass.png-3b2015c0dd629c60d3c1b09d9013c59c.stex new file mode 100644 index 0000000000000000000000000000000000000000..d566acb2f5e840bf08876f062be3c3c5f4c6b001 GIT binary patch literal 116 zcmZ>F2@VlpU|;}Y2vA^S1TrFkINa4KAjs3r%?HX33$XC92eS3~4=@X;8=N_8bB2lW zP`miVE@qh?1qqi)BJ7-NTILoXuspDT_533aF8|dR{MnYZZ&#+Ln^Bt776}Doo<->l F3;=W{ALal6 literal 0 HcmV?d00001 diff --git a/.import/Glass.png-8678c0300c4ceb28841173a60adcbab3.md5 b/.import/Glass.png-8678c0300c4ceb28841173a60adcbab3.md5 new file mode 100644 index 0000000..e17e61d --- /dev/null +++ b/.import/Glass.png-8678c0300c4ceb28841173a60adcbab3.md5 @@ -0,0 +1,3 @@ +source_md5="ae48a5a22aa6a99422a8318ffed1feaa" +dest_md5="d181a180dfaeadaadbdfd93dc388012c" + diff --git a/.import/Glass.png-8678c0300c4ceb28841173a60adcbab3.stex b/.import/Glass.png-8678c0300c4ceb28841173a60adcbab3.stex new file mode 100644 index 0000000000000000000000000000000000000000..0313439e100518c338ba6124a8d058f594d0e4cc GIT binary patch literal 150 zcmZ>F2@VlpU|;}Y2vA^S1Tw0CINa4KAjs3rEf2~L3$XA>1hVz{4=@YpJIu&6so&Ij z=0Tmh(~?}{|A*8Pjr#bPM>+&N`Jb_{vEGbJAi{N$X!^;I=RXT@`ZM-4#GKzhgFU0; p#eWu$u7G{Yex9bHE16X0Ur;|&F2@VlpU|;}Y2vA^W1Tv-oak#5fK#-@KTL+XK7GU914P@){A7BTZ!F~>F*Paucjx}WpWmz{u`cO$nN$?Zo<$3|7St}!VSi}HDDq!v zM@7er|12g9$7YzH`FBt%xxpezmn}PiFOes#bGyVbiB;RUKSwV6ApY!a)OW2vW;<7L P*gvsb9J|PN9|Hpb9D+Tj literal 0 HcmV?d00001 diff --git a/.import/Icon_5.png-5996b0b5e4a48ab5d0c5454fa98a17bd.md5 b/.import/Icon_5.png-5996b0b5e4a48ab5d0c5454fa98a17bd.md5 new file mode 100644 index 0000000..5e613a0 --- /dev/null +++ b/.import/Icon_5.png-5996b0b5e4a48ab5d0c5454fa98a17bd.md5 @@ -0,0 +1,3 @@ +source_md5="9fd4edb2bc0911b9a18417c61fe8cdd1" +dest_md5="911caff935a9e06a4c65b7d79a85fbc8" + diff --git a/.import/Icon_5.png-5996b0b5e4a48ab5d0c5454fa98a17bd.stex b/.import/Icon_5.png-5996b0b5e4a48ab5d0c5454fa98a17bd.stex new file mode 100644 index 0000000000000000000000000000000000000000..24cf3aac79748561ca5d9f545cc796cbfa346de8 GIT binary patch literal 168 zcmZ>F2@VlpU|;}Y2vA^W1TuPnINa4KAjs3rtpUmo3$XAh2D0_}4=@XuJBaZZ)wiCo zQub_ixOD6v>%6x%XGFK=GPnL;ud%*yM#F*=|1UnO|4_EznmSWspvul(7RROsKf)Fy zaAh;>J0S0pCUEgTr-D+@)dWFLP0PoZPV?TM^8eFP{{)@~7S-o0*Bh%b$OJyQF2@VlpU|;}Y2vA^W1TxxyINa4KAjs3rtqRHx3$XCX1G4q`4=@XuJBaZZ)wiCo zQub_ixOD6v>%6x%XGFK=GPnL;ud%*yM#F*=|1UnO|4_EznmSWspi1Q0d!5E&ix{sR za&|DA@Ta>$p4a6|JyQn*Q-Nca{?_(@DDAb?x6jHSd6iVUnN_dxbk3f+YxAC4F#!OH CR5|(p literal 0 HcmV?d00001 diff --git a/.import/Icon_7.png-e5599ba2a6360063be55af65767b9beb.md5 b/.import/Icon_7.png-e5599ba2a6360063be55af65767b9beb.md5 new file mode 100644 index 0000000..d37d405 --- /dev/null +++ b/.import/Icon_7.png-e5599ba2a6360063be55af65767b9beb.md5 @@ -0,0 +1,3 @@ +source_md5="42cdc1e1592e52083e73e551f21c2fa9" +dest_md5="45d459381756e367f5d750e422e98474" + diff --git a/.import/Icon_7.png-e5599ba2a6360063be55af65767b9beb.stex b/.import/Icon_7.png-e5599ba2a6360063be55af65767b9beb.stex new file mode 100644 index 0000000000000000000000000000000000000000..200f2649e452acb390cb1bd43a0e1744b98061cb GIT binary patch literal 174 zcmZ>F2@VlpU|;}Y2vA^W1TrQ8ak#5fK#-@KTN{)e7GU911!U{U@gkRalE2G^x`5xPX&+?pGp3Cblc>8}bD+}Aiw?{fz^_agHe9(Rv zeZXlspAdWRdj=_`U-~K@8?0MY7$-`$oMV46_nq-?UiW~lt##ac)APMME_-l()=acp OYBxVfDs#S$IwJtm@jC$k literal 0 HcmV?d00001 diff --git a/.import/Icon_8.png-058c48e4cc637de37413544fee2a9a2b.md5 b/.import/Icon_8.png-058c48e4cc637de37413544fee2a9a2b.md5 new file mode 100644 index 0000000..4e2aba8 --- /dev/null +++ b/.import/Icon_8.png-058c48e4cc637de37413544fee2a9a2b.md5 @@ -0,0 +1,3 @@ +source_md5="7e380c1c224c308f607885c419a9cf73" +dest_md5="3c31581c74d855625078446a4795fe21" + diff --git a/.import/Icon_8.png-058c48e4cc637de37413544fee2a9a2b.stex b/.import/Icon_8.png-058c48e4cc637de37413544fee2a9a2b.stex new file mode 100644 index 0000000000000000000000000000000000000000..ae00135bb34ca0f401429d1b752c73e15895bf50 GIT binary patch literal 132 zcmZ>F2@VlpU|;}Y2vA^W1Tr#!INa4KAjs3rEe6UC3$XAB0J8P@4=@X;E2t>^*`F{o zZJI;F2m1xRQl`1m1`q$Urm}M}I!^q*_^5nAD;LKqrN~?lL5IQymZSx?|5rWGXHxoQ W&lqwpr+Mi{lLIzq9=mJ1@&W*_Y9{3X literal 0 HcmV?d00001 diff --git a/.import/Icon_9.png-50a7db6b6a1fee5a30051fa84f0c1a0b.md5 b/.import/Icon_9.png-50a7db6b6a1fee5a30051fa84f0c1a0b.md5 new file mode 100644 index 0000000..99e7c4c --- /dev/null +++ b/.import/Icon_9.png-50a7db6b6a1fee5a30051fa84f0c1a0b.md5 @@ -0,0 +1,3 @@ +source_md5="71bc1217289de16605b99e80fd1fae32" +dest_md5="84842298ad49aff82aaae5f911bfa156" + diff --git a/.import/Icon_9.png-50a7db6b6a1fee5a30051fa84f0c1a0b.stex b/.import/Icon_9.png-50a7db6b6a1fee5a30051fa84f0c1a0b.stex new file mode 100644 index 0000000000000000000000000000000000000000..878951927943f83f021a3bb867920d45eaf39e9f GIT binary patch literal 132 zcmZ>F2@VlpU|;}Y2vA^W1Tr#!INa4KAjs3rEe6UC3$XAB0J8P@4=@X;E2t>^*`F{o zZJI;F2m1xRQl`1m1`q$Urm}M}I!^q*_^5nAD;Ecs(oL@o4DnKbI06pT{SUEV>3H#< WWk%wQR8|+4)u)t{KB})={TcwfxF}Ts literal 0 HcmV?d00001 diff --git a/.import/bg.png-5046840dce817dc9e1d61a818df550fc.md5 b/.import/bg.png-5046840dce817dc9e1d61a818df550fc.md5 new file mode 100644 index 0000000..0b64965 --- /dev/null +++ b/.import/bg.png-5046840dce817dc9e1d61a818df550fc.md5 @@ -0,0 +1,3 @@ +source_md5="d607510048c43b15d9f908666abc10ce" +dest_md5="f56c36e2e2d12453433c9dfc95b37c0f" + diff --git a/.import/bg.png-5046840dce817dc9e1d61a818df550fc.stex b/.import/bg.png-5046840dce817dc9e1d61a818df550fc.stex new file mode 100644 index 0000000000000000000000000000000000000000..3f47cea9151aae37dd390b8cdbe9c2d46291ffe6 GIT binary patch literal 66 zcmZ>F2@YXoU|;}Y2vA@HvDJV$+|?-{$kWYD3d#-(u<+pnvh{(Ofn7lGFTab+e`Wyk CuL(o| literal 0 HcmV?d00001 diff --git a/.import/break.sfxr-c1c1594a22628fd278421b7f8a79a149.md5 b/.import/break.sfxr-c1c1594a22628fd278421b7f8a79a149.md5 new file mode 100644 index 0000000..25d52ba --- /dev/null +++ b/.import/break.sfxr-c1c1594a22628fd278421b7f8a79a149.md5 @@ -0,0 +1,3 @@ +source_md5="24213acfa75e1afe51371161b047d97d" +dest_md5="403bc96e74c0979fac5728f0848ea056" + diff --git a/.import/break.sfxr-c1c1594a22628fd278421b7f8a79a149.sample b/.import/break.sfxr-c1c1594a22628fd278421b7f8a79a149.sample new file mode 100644 index 0000000000000000000000000000000000000000..dcfcef8fbd64e5efd26906d0e04d90136db386c2 GIT binary patch literal 17773 zcmeI4TWnNC7=TX~umbi1f?PxwEESX@LJ+W^1;n%h8Y~wPsdZ^rQ`7C%?UMMY4?d|e zkq7m`Ck+}CB37dW5%DfkEhq-%RuHsYx@~DoTefJObDuf$&zw1XW=li(lC$&AKW9(R z&gGwf{uwA;UHX7xFa)K;(50rM(Y0iAWmR-_JQfZ`R)-?B)nTOb#|ZTG@#u<$>!O=u z72)#gXho>HJRU8ts|eSGm2AAMCKL&4?^79yhm=fI^mH^93B?ulDb>+vZFwYG8CFJ` zxlQ3`s%n(sW;R??sbwNn&zHwS@v!!Ux_CGij_P7Xtg1GS?pBlxbm- z^4XIX8k!7R{~bW?HYuyLsF2MjokjBuCXYxPv(3M;RNzM#@5N87ZdSHIE{{uK&PbCs zexJol)6#uKANrMVj$53)eDyKYX1&$*dGx6P#~TESyEkAjIb-6=ZU z6Yr!ceU?WRgEbFpti-wBjB$#kvovM^OrPeN@xuX}Ce1y6azDWCPrT9ywa-YX_i=SI zRfl?^gXKmTpPM{}Gaqe~P@MPdKkRCUxW_YKP^#sKN1Brmx#PVt0UX|w^E}ZHzWO$v zWp$Rl@hQa4KgEHA70Y;L2QQ;GpjN4@Ro!M+mKH(GrDt+VGZdubgbPi_K#mZh0cWO% z8UmUkUt=mnkaGMqMd$AB8#$NC1w{Ky-`Pviv|A7I_E=$#Z2E{QG=p_tFa=P1EjNz@#JphXy_Hx0&&rR8rb4!!&z-ggMBl29Iid$(V2~W6f+^ zr$@SYoM&*(=Q8TF#RV4qQh@w4&2uZnLKxn~H9D(S;+7wimoN3l5=0U5=V&KW)dX+U zF}MGz^ahsU7yy0ZD2qKG3bEZEexrx=KKWRL&l(#6_gGUMclWKO-jTSHbg=0bre}}> zIr)Yzft&KdA=?YBHcou15BB{AQVThlrf#7fi!Sj?u>cP))_}bBqN0Th_{^7p`NN@f z%BZxFo6GIA--AbHJbB5`&4=06qNAhN8NlKO1Vjs`a^oj@;KkqPT@?IX4m-NZkUWPG zj4u>A!XresuxN?i)qQ=!;{<8>9ku)KbaRelt5MM)Cv6~^Ic*5q}WwKVap$GUeez!0+NCZl>TU8T|osj8(0r?zoOi?gSU|f!$amIzJr_FWTDd zOALskEl}nrJYqY}#B~|n0*9kg(-J3Sz)X`Kmf?I_yXS%e9N*(<_cge|2{f8TV9#<< z9wf#DlxeaeBjN&YNPulXD9^$JG6iij<3;SQbo!(etbxiDS~+VN(W0U5(UP0NT@Nox zfmzIDnqo~~mOcYA77pDg+W-kk*o>x%z@%oYj7@ieUy9vAp6XCsf|_a!v&k|2h-Z%j z2S%I$&StBtd5XUD2zZGBa37DW3<#jOT7LY7fXLB^NmH1RtFNHT1gRAZoeR!{w~k0{ z!Yz<4WXyOC+o?7O*C{}SBbc>gjYXbt#{BnGSbE}=KnF@Dvy6x^mI(BaK%ft;sPUo2 zTVONFdNV}G!VJcLB3!bXtdqAvVU?L3f>*(I*$^G_fGjJg{SC1wsXDQ?v7STd`%#4m zHBlhh)rB{aPq~%X%dN8W_LR+#5@=a0untOcz4~6U7;h)%4~ex4JKmbG&O&iR0G*6C z4cH4Jo&=0fG*olMc0GrS^%KWk`l#&dgX{+tFz>Qzp$)4BfxaSG{q$`YAaerr?VjHB zkTgtyYa%i)dc7yx;e9c)!$fTBwR@}@P@vv!>o8*kbTuKBIvEg#oR?8tdlz|wHiYe2 z%9h|66Z<))n1q4{r~h90Qa>LbpQYW diff --git a/.import/icon.png-487276ed1e3a0c39cad0279d744ee560.md5 b/.import/icon.png-487276ed1e3a0c39cad0279d744ee560.md5 index 5328bc7..bd2e7d9 100644 --- a/.import/icon.png-487276ed1e3a0c39cad0279d744ee560.md5 +++ b/.import/icon.png-487276ed1e3a0c39cad0279d744ee560.md5 @@ -1,3 +1,3 @@ -source_md5="47313fa4c47a9963fddd764e1ec6e4a8" -dest_md5="26ea799ea0a3da9e753b3ebe822e0570" +source_md5="bc69b7f51a5c3e10bbb3a38f62ff6284" +dest_md5="253c7a0063b8268d86be8cb737ff1111" diff --git a/.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex b/.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex index 71f69131f1bad5ac84f9f5fb77b8014d6f855868..8b3d7dfb1694b14d8909fcd09c339e2d2b7a6d4e 100644 GIT binary patch literal 270 zcmZ>F2@XkMU|;}Y79eI|P+(^SlAnM$+|?-{$kWa38I&CsVBvEU$kvZPAkN^wKw}&4 zt3=m^{Iatl8>YGXs%ZLrSB>N{GU!>Iav_&4~_OQJ@uZkZU`W=n4l`?SSt^@4nW4F<$h)=gziXmDnq}YVS4Vl^xzU z*>naqL_NHwaA2}WYtGp}|O>d-->Jz7r=T9L##X+PGzAItV{cV%dD@@Jf%~rNS~{ny(d23)QAQ_2^U$G~4|z N*zZ{1<|Ba&3;=K~Y=i&+ literal 1496 zcmV;}1t8#jQIRc$f~c)tQiw!~w%QUQ6exqX5cknk z0+d35DiDbTDuoE4>Lo>6B7>ey@m$S@5kjOuv{fWhh-@ho&(;2WkwS$K6`&Ldl|Us> zi4+J0k-+z7D#fx5bCy(4v8-W?7^7rF3d=UlIm}g3kr8v2*TVsYG0L(HsaUol6{$#J zzu%jyB(dI3x&O7SY0hEJfqi2jQf;@JF@lOwkr88**UM&PLd-R!kcy0;loU$Knm#_B zpssT<`uctM`T6EPm%A7K9*tSP|39fzMMT%Jh>GrWxv%zI|5WGxr!+(rs;IWI7+u$| ztA8kAM1hddg9IT6zY$?4T#831gq|cT869IJntT)|=01mwu*fe$Smy`ebi^HL+s-xg7chk284pq%~oy)o1W?`nc*zBC=zRt+_#M70<6PFG z6}tee5v>KVd&MI&-P+`h3e5&K^|-6M0EkEyjlf*9+`s@4^=sduefxeS9)KHW zxry#hT9*zlA+*bJIQpy4c0ZhsA-z^ z>#WBV&J`yU4D>m2?bqM)mFeH8@`b;@t{w3iXa*Wm8VHI_5p)5%2vTB$fYL+A6hukG z$!S`fHfaJP8lFT>jWhoL$`1ibnR*S{w;v;KO#Alr>y=RgAjwy$tV9ApAt(LXJMHJB z5CB9fl}q_biX|eNFsP!BlcI21)QL~UK@*6GVkMnytRt$6Bte>2l|jNPUTK0P)Fok~ z<8pRY5;Z~3$-3c)Ct*B>>n8U^6H%qzayG_@T0>t#DTYp>PAI07fWEaTdcB-^=q5<& z*tTB18j2DbF@k^@@+ev1QMg zL5#haz6F3%uU@HhjobH`e9qrvh%#pS={PAR-X0k%SWDWbr)+o y|M)fYRW9dto5g$WGgZ~$_?(~f&V283@;^HqstN$fY}?!b diff --git a/.import/overview.PNG-3372de55fcb4add320565bad41f71587.md5 b/.import/overview.PNG-3372de55fcb4add320565bad41f71587.md5 new file mode 100644 index 0000000..8d11c02 --- /dev/null +++ b/.import/overview.PNG-3372de55fcb4add320565bad41f71587.md5 @@ -0,0 +1,3 @@ +source_md5="ad923036df9b2572bacd6749ae2024f0" +dest_md5="245c6fd0f699a6ee53e6c878da599b50" + diff --git a/.import/progress.png-1546df883425497bf4494dd92b12d7b4.md5 b/.import/progress.png-1546df883425497bf4494dd92b12d7b4.md5 new file mode 100644 index 0000000..9195a29 --- /dev/null +++ b/.import/progress.png-1546df883425497bf4494dd92b12d7b4.md5 @@ -0,0 +1,3 @@ +source_md5="653c99928be1524b21d2add32ae8d13f" +dest_md5="892389819376be6bfe0deb52ff6fed11" + diff --git a/.import/progress.png-1546df883425497bf4494dd92b12d7b4.stex b/.import/progress.png-1546df883425497bf4494dd92b12d7b4.stex new file mode 100644 index 0000000000000000000000000000000000000000..2e6be0a03e5f4fb0350df5d2caa042dc58d040c6 GIT binary patch literal 70 zcmZ>F2@XkQWMB|vU|?VYVg?2Ub|9BQ3y8yAodSY9-Q47$?63d}ACNlz1V$DH_6zsz Ow(a`g*zuyCfdK$p$__sO literal 0 HcmV?d00001 diff --git a/.import/punch.sfxr-ce24cf25ac6de08473bbda5685c58ae5.md5 b/.import/punch.sfxr-ce24cf25ac6de08473bbda5685c58ae5.md5 new file mode 100644 index 0000000..64ef855 --- /dev/null +++ b/.import/punch.sfxr-ce24cf25ac6de08473bbda5685c58ae5.md5 @@ -0,0 +1,3 @@ +source_md5="85a9cb49e771d72d839a8409b3f9b9ce" +dest_md5="c3251c8663f0f35e65cb0f58382bc6b0" + diff --git a/.import/punch.sfxr-ce24cf25ac6de08473bbda5685c58ae5.sample b/.import/punch.sfxr-ce24cf25ac6de08473bbda5685c58ae5.sample new file mode 100644 index 0000000000000000000000000000000000000000..1f02d62bfb3c46dc4180635e3aaad190289981fd GIT binary patch literal 8273 zcmdU#2~bo=8i1eUaE=2Lzyk!lIYmN=9I}Y(L8Kx{fW#acaL~yXyBscJxk+}Hr3{G) zWo1JWc8d~S4F*lLl(4c&JQl+lL{WkUhI0_X0bzg{hC`hF`*rtY7)C_|w*0DI|NY)P z`t|$!zxoxSVWI08!c33`a3E;`$8Y!SjEW0Oh?j_C!o)GVq9t(c*)WAap9e?0WOv-2 z_#Kjn=(ru?=!k^4h}}CRu@c5i`?pwejD(%fPH}>mF@m4oi;IsDCopJ~=(xCD5ixN) zC5(WcMM{1b70Z~=Q%USj_9Q0iPZ9Cr1PMFB?gUA^Bo23X#7FH)fV&xH1{`=$n9XW; zcMoO(x&-J~1NxB%#{xJEpcxz-95OI47|c3;{G5w}!~B~1`nvSJdz0n|2M2$%Z{NOI zCMG6UZftJP{FJ3Bj@KA;f@iWH0YBqb&Je3O}ZHYh0Q<&=X54|e9{ zE7}DL{eMKgd8Gn$PnphAU8~ZPq$W0@m@WGcFjb@N% zXlPd^kPb!ovNdk5f|I`p)j&U3WkDlTQvD5O1}qxt5sNXgxmss;aX5 z)PV!{mzfE81vei&sJnP9E$wfA$;~b368QNonLXUu>EIx(=(JmL^yo()?ApHF)O1j8 z8WZ!6%zvh&yeHngc6~(n=V_mLdkckjo5TL_`|SZvGTFdF@9^;Oh*v#5`MI}Ls_uLD zyNZ(R?pboB<7 ziWbANE%!2pDM=L!n(4Bcwb!p-H;aha3i{{s`9f!BS10s$h&jvA>mi(5dntZ1DG%XK zFwQch9+p#wC>ej}IN!j6oYf1wnh>y%qv8hTrUDk8@FuH9Xf|x{@JFl3^4cHQ`B5DE z^7F3{l9N8Ae3o_zf(s!k5-ktrE>dJcL1AIx)jJ#kZ%`uq@#{kS0)!-j;Z=@94>=@T zLMi_1=qm+peRT#!m7ez1S6^dNKfm%bMfI?TIX;Dc@(7@F)&q zu?U4dmTyy1WL=bykWE6$Fgyy@5+eYsG?7!jPfI&^nsUChw6uf+tgiTKIpP}d3s4Io z5Yqv(WFY2Z{9bt_IG7J{n?><0@Evj^mLD%8E^%B0F3=~QJ`S<-=+Pg3BwVPfsw$%t z<>z1iH|1nj))_PpmUg954Osv)$KKvv2mzOc4~8y)Fob~^zRjH)l_~OJ4b_|oxf99( zEFRw8US15H!q#n~tm(Xw)%K){-iVK)K_Xr|9kd?p`W6Tf(J4 zfyP*@P+UOBD=AGV=pp!cD$tsaepmFu48BL9xKqthi`*H}LZ8#x+NOYHiBO>+P8h^W zQLB|ShJe&8CIp6tLXHRtK@kukP+^9s|I&HMaS&;!%qBEGz?cORHn6c98p!(yUtbX$ z8~gj)AkAayh$jrwAY*HRB00btnce+%OlvboE%Dh~G*I2R(M4vq_$5kUpbfFhyA>mp zgPS4eFaAl3W@2ncv&df{u>=ec5wK1RXLF327!MY$WJQK(xWRImKvhm;!);6+RRflV z!~;wrhmXR3J_hFjtyYdLwc(sDWyD}-%^QOmF+*3DC>^;u z`v;Eypa6gIVlf!`SV)%b=CbDK&MZ{^&7QaX5jf#=V`26v92^^u02Jwh(jf=?W=jqx5jMBuhjCO^ZLo}Lhh?^^Bf1u zQL(wyhOG#n+!(Mv*an67__%}0S6LH|_v379SRX0T)hiU?kEMoH;$mkCRIJm6H44If z&h?(UL*fLRKI9`=@yR`s4D^fkPMAnfpH4`hjMH8e;o51fF_jX%St}~Yo|z{rQ|}!L z^)SOTpFJiyP3*$l>EH#3)_aPJj-j(wNO?Z1dzO{KPwigM+=Js=j(s z13$B9=}`@HyOOEu@YHI#p8WF6Awcf{*y}sGdq{Eje-#6Ly<=*|DY`)F!-)vx07G|= zQ)L3vH7?z<>PSPT8<#F@{i3(wc6bx&(2e^9r5^8inoD{e;VCZa&6H1bQGdbm6j$}t z9P;*#&Mx{P;c<4|Gd<7^*HlZgp_>MwwOO3%F8$IqEpntLR;l1)Q_tg!r+c!DXR^#< z($;;_mUI%=Y-DAgy+^+3O^O(QwK literal 0 HcmV?d00001 diff --git a/.import/table.png-6287c5224e3a2223ad79685cc0bf8f85.md5 b/.import/table.png-6287c5224e3a2223ad79685cc0bf8f85.md5 new file mode 100644 index 0000000..fe18a51 --- /dev/null +++ b/.import/table.png-6287c5224e3a2223ad79685cc0bf8f85.md5 @@ -0,0 +1,3 @@ +source_md5="9dd651cc55c5cf69f617ef98c9759a3a" +dest_md5="2da991840fabf6730dc8918b7e936144" + diff --git a/.import/table.png-6287c5224e3a2223ad79685cc0bf8f85.stex b/.import/table.png-6287c5224e3a2223ad79685cc0bf8f85.stex new file mode 100644 index 0000000000000000000000000000000000000000..96627c34f668fc1b928514d33287dff622b5babe GIT binary patch literal 120 zcmZ>F2@c_5U|;}Y2vA^S1TtcPINa4KAjs3rEda_63$XBU2D0_J4=@SHD+qWLvTW7? zl49PvDjtSs*EK9S@&DqZc5RL>CC{vmd>uu_btkRUzaMgB;}!gS{$r}pt{Eu_EMGY0 IK44@30Jj7oivR!s literal 0 HcmV?d00001 diff --git a/.import/under.png-d21cca1445c6a2663bc52f4f2384a623.md5 b/.import/under.png-d21cca1445c6a2663bc52f4f2384a623.md5 new file mode 100644 index 0000000..f51e6e4 --- /dev/null +++ b/.import/under.png-d21cca1445c6a2663bc52f4f2384a623.md5 @@ -0,0 +1,3 @@ +source_md5="31cd1f8a917c5075e663ae258d562cd7" +dest_md5="65f32199154fd5ec5e092e0d77471819" + diff --git a/.import/under.png-d21cca1445c6a2663bc52f4f2384a623.stex b/.import/under.png-d21cca1445c6a2663bc52f4f2384a623.stex new file mode 100644 index 0000000000000000000000000000000000000000..bbf0b130e4fefbabfa1d7ad2cd58dde7d8de9570 GIT binary patch literal 70 zcmZ>F2@XkQWMB|vU|?VYVg?2Ub|9BQ3y8yAodSY9-Q47$?63d}ACNlz1V$DH_6w7m OOqTs`?08YnzyJVM@eQB= literal 0 HcmV?d00001 diff --git a/.import/wardrobe.png-67445500d100c0d821e09597f4b6463a.md5 b/.import/wardrobe.png-67445500d100c0d821e09597f4b6463a.md5 new file mode 100644 index 0000000..6c71d25 --- /dev/null +++ b/.import/wardrobe.png-67445500d100c0d821e09597f4b6463a.md5 @@ -0,0 +1,3 @@ +source_md5="f3ddc145ab52891047b639168d925bc9" +dest_md5="3afb1cf0f019a3c071a05c5995aec7d8" + diff --git a/.import/wardrobe.png-67445500d100c0d821e09597f4b6463a.stex b/.import/wardrobe.png-67445500d100c0d821e09597f4b6463a.stex new file mode 100644 index 0000000000000000000000000000000000000000..e2899c1eb9555ae1275d78a15cd5ad0a739379c2 GIT binary patch literal 134 zcmZ>F2@VlpU|;}Y2vA^S1TwOKINa4KAjs3rEe^^K3$XAB0+00kT;#Q*>R literal 0 HcmV?d00001 diff --git a/Scenes/End.tscn b/Scenes/End.tscn new file mode 100644 index 0000000..34da616 --- /dev/null +++ b/Scenes/End.tscn @@ -0,0 +1,44 @@ +[gd_scene load_steps=5 format=2] + +[ext_resource path="res://fonts/dotty.ttf" type="DynamicFontData" id=2] +[ext_resource path="res://Scripts/End.gd" type="Script" id=3] + +[sub_resource type="DynamicFont" id=1] +size = 128 +font_data = ExtResource( 2 ) + +[sub_resource type="DynamicFont" id=2] +size = 64 +font_data = ExtResource( 2 ) + +[node name="Control" type="Control"] +anchor_right = 1.0 +anchor_bottom = 1.0 +script = ExtResource( 3 ) + +[node name="Label" type="Label" parent="."] +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +margin_left = -288.0 +margin_top = -76.0 +margin_right = 288.0 +margin_bottom = 4.0 +custom_fonts/font = SubResource( 1 ) +text = "Game Over!" +align = 1 +valign = 1 + +[node name="Points" type="Label" parent="."] +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +margin_left = -128.0 +margin_top = 4.0 +margin_right = 128.0 +margin_bottom = 52.0 +custom_fonts/font = SubResource( 2 ) +text = "Points:" +align = 1 diff --git a/Scenes/Game.tscn b/Scenes/Game.tscn index ce58015..dc9d675 100644 --- a/Scenes/Game.tscn +++ b/Scenes/Game.tscn @@ -1,34 +1,66 @@ -[gd_scene load_steps=4 format=2] +[gd_scene load_steps=9 format=2] [ext_resource path="res://Sprites/tileset.tres" type="TileSet" id=1] [ext_resource path="res://Scenes/Player.tscn" type="PackedScene" id=2] [ext_resource path="res://Scenes/WaterThings/Jug.tscn" type="PackedScene" id=3] +[ext_resource path="res://fonts/dotty.ttf" type="DynamicFontData" id=4] +[ext_resource path="res://Sprites/furniture.tres" type="TileSet" id=5] +[ext_resource path="res://Scripts/Game.gd" type="Script" id=6] +[ext_resource path="res://Scenes/WaterThings/Glass.tscn" type="PackedScene" id=7] + +[sub_resource type="DynamicFont" id=1] +font_data = ExtResource( 4 ) [node name="Game" type="Node2D"] +script = ExtResource( 6 ) [node name="TileMap" type="TileMap" parent="."] tile_set = ExtResource( 1 ) cell_size = Vector2( 8, 8 ) +cell_custom_transform = Transform2D( 16, 0, 0, 16, 0, 0 ) +format = 1 +tile_data = PoolIntArray( 0, 1, 0, 1, 1, 0, 2, 1, 0, 3, 1, 0, 4, 1, 0, 5, 1, 0, 6, 1, 0, 7, 1, 0, 8, 1, 0, 9, 1, 0, 10, 1, 0, 11, 1, 0, 12, 1, 0, 13, 1, 0, 14, 1, 0, 15, 1, 0, 16, 1, 0, 17, 1, 0, 18, 1, 0, 19, 1, 0, 20, 1, 0, 21, 1, 0, 22, 1, 0, 23, 1, 0, 24, 1, 0, 25, 1, 0, 26, 1, 0, 27, 1, 0, 28, 1, 0, 29, 1, 0, 30, 1, 0, 31, 1, 0, 32, 1, 0, 33, 1, 0, 65536, 1, 0, 65537, 3, 0, 65538, 3, 0, 65539, 3, 0, 65540, 3, 0, 65541, 3, 0, 65542, 3, 0, 65543, 3, 0, 65544, 3, 0, 65545, 3, 0, 65546, 3, 0, 65547, 3, 0, 65548, 3, 0, 65549, 3, 0, 65550, 3, 0, 65551, 3, 0, 65552, 3, 0, 65553, 3, 0, 65554, 3, 0, 65555, 3, 0, 65556, 3, 0, 65557, 3, 0, 65558, 1, 0, 65559, 3, 0, 65560, 3, 0, 65561, 3, 0, 65562, 3, 0, 65563, 3, 0, 65564, 3, 0, 65565, 3, 0, 65566, 3, 0, 65567, 3, 0, 65568, 3, 0, 65569, 1, 0, 131072, 1, 0, 131073, 0, 0, 131074, 0, 0, 131075, 0, 0, 131076, 0, 0, 131077, 0, 0, 131078, 0, 0, 131079, 0, 0, 131080, 0, 0, 131081, 0, 0, 131082, 0, 0, 131083, 0, 0, 131084, 0, 0, 131085, 0, 0, 131086, 0, 0, 131087, 0, 0, 131088, 0, 0, 131089, 0, 0, 131090, 0, 0, 131091, 0, 0, 131092, 0, 0, 131093, 0, 0, 131094, 1, 0, 131095, 2, 0, 131096, 2, 0, 131097, 2, 0, 131098, 2, 0, 131099, 2, 0, 131100, 2, 0, 131101, 2, 0, 131102, 2, 0, 131103, 2, 0, 131104, 2, 0, 131105, 1, 0, 196608, 1, 0, 196609, 0, 0, 196610, 0, 0, 196611, 0, 0, 196612, 0, 0, 196613, 0, 0, 196614, 0, 0, 196615, 0, 0, 196616, 0, 0, 196617, 0, 0, 196618, 0, 0, 196619, 0, 0, 196620, 0, 0, 196621, 0, 0, 196622, 0, 0, 196623, 0, 0, 196624, 0, 0, 196625, 0, 0, 196626, 0, 0, 196627, 0, 0, 196628, 0, 0, 196629, 0, 0, 196630, 1, 0, 196631, 2, 0, 196632, 2, 0, 196633, 2, 0, 196634, 2, 0, 196635, 2, 0, 196636, 2, 0, 196637, 2, 0, 196638, 2, 0, 196639, 2, 0, 196640, 2, 0, 196641, 1, 0, 262144, 1, 0, 262145, 0, 0, 262146, 0, 0, 262147, 0, 0, 262148, 0, 0, 262149, 0, 0, 262150, 0, 0, 262151, 0, 0, 262152, 0, 0, 262153, 0, 0, 262154, 0, 0, 262155, 0, 0, 262156, 0, 0, 262157, 0, 0, 262158, 0, 0, 262159, 0, 0, 262160, 0, 0, 262161, 0, 0, 262162, 0, 0, 262163, 0, 0, 262164, 0, 0, 262165, 0, 0, 262166, 1, 0, 262167, 2, 0, 262168, 2, 0, 262169, 2, 0, 262170, 2, 0, 262171, 2, 0, 262172, 2, 0, 262173, 2, 0, 262174, 2, 0, 262175, 2, 0, 262176, 2, 0, 262177, 1, 0, 327680, 1, 0, 327681, 0, 0, 327682, 0, 0, 327683, 0, 0, 327684, 0, 0, 327685, 0, 0, 327686, 0, 0, 327687, 0, 0, 327688, 0, 0, 327689, 0, 0, 327690, 0, 0, 327691, 0, 0, 327692, 0, 0, 327693, 0, 0, 327694, 0, 0, 327695, 0, 0, 327696, 0, 0, 327697, 0, 0, 327698, 0, 0, 327699, 0, 0, 327700, 0, 0, 327701, 0, 0, 327702, 1, 0, 327703, 2, 0, 327704, 2, 0, 327705, 2, 0, 327706, 2, 0, 327707, 2, 0, 327708, 2, 0, 327709, 2, 0, 327710, 2, 0, 327711, 2, 0, 327712, 2, 0, 327713, 1, 0, 393216, 1, 0, 393217, 0, 0, 393218, 0, 0, 393219, 0, 0, 393220, 0, 0, 393221, 0, 0, 393222, 0, 0, 393223, 0, 0, 393224, 0, 0, 393225, 0, 0, 393226, 0, 0, 393227, 0, 0, 393228, 0, 0, 393229, 0, 0, 393230, 0, 0, 393231, 0, 0, 393232, 0, 0, 393233, 0, 0, 393234, 0, 0, 393235, 0, 0, 393236, 0, 0, 393237, 0, 0, 393238, 1, 0, 393239, 2, 0, 393240, 2, 0, 393241, 2, 0, 393242, 2, 0, 393243, 2, 0, 393244, 2, 0, 393245, 2, 0, 393246, 2, 0, 393247, 2, 0, 393248, 2, 0, 393249, 1, 0, 458752, 1, 0, 458753, 0, 0, 458754, 0, 0, 458755, 0, 0, 458756, 0, 0, 458757, 0, 0, 458758, 0, 0, 458759, 0, 0, 458760, 0, 0, 458761, 0, 0, 458762, 0, 0, 458763, 0, 0, 458764, 0, 0, 458765, 0, 0, 458766, 0, 0, 458767, 0, 0, 458768, 0, 0, 458769, 0, 0, 458770, 0, 0, 458771, 0, 0, 458772, 0, 0, 458773, 0, 0, 458774, 1, 0, 458775, 2, 0, 458776, 2, 0, 458777, 2, 0, 458778, 2, 0, 458779, 2, 0, 458780, 2, 0, 458781, 2, 0, 458782, 2, 0, 458783, 2, 0, 458784, 2, 0, 458785, 1, 0, 524288, 1, 0, 524289, 0, 0, 524290, 0, 0, 524291, 0, 0, 524292, 0, 0, 524293, 0, 0, 524294, 0, 0, 524295, 0, 0, 524296, 0, 0, 524297, 0, 0, 524298, 0, 0, 524299, 0, 0, 524300, 0, 0, 524301, 0, 0, 524302, 0, 0, 524303, 0, 0, 524304, 0, 0, 524305, 0, 0, 524306, 0, 0, 524307, 0, 0, 524308, 0, 0, 524309, 0, 0, 524310, 1, 0, 524311, 2, 0, 524312, 2, 0, 524313, 2, 0, 524314, 2, 0, 524315, 2, 0, 524316, 2, 0, 524317, 2, 0, 524318, 2, 0, 524319, 2, 0, 524320, 2, 0, 524321, 1, 0, 589824, 1, 0, 589825, 0, 0, 589826, 0, 0, 589827, 0, 0, 589828, 0, 0, 589829, 0, 0, 589830, 0, 0, 589831, 0, 0, 589832, 0, 0, 589833, 0, 0, 589834, 0, 0, 589835, 0, 0, 589836, 0, 0, 589837, 0, 0, 589838, 0, 0, 589839, 0, 0, 589840, 0, 0, 589841, 0, 0, 589842, 0, 0, 589843, 0, 0, 589844, 0, 0, 589845, 0, 0, 589846, 1, 0, 589847, 1, 0, 589848, 1, 0, 589849, 1, 0, 589850, 1, 0, 589851, 1, 0, 589852, 1, 0, 589853, 1, 0, 589854, 2, 0, 589855, 2, 0, 589856, 1, 0, 589857, 1, 0, 655360, 1, 0, 655361, 0, 0, 655362, 0, 0, 655363, 0, 0, 655364, 0, 0, 655365, 0, 0, 655366, 0, 0, 655367, 0, 0, 655368, 0, 0, 655369, 0, 0, 655370, 0, 0, 655371, 0, 0, 655372, 0, 0, 655373, 0, 0, 655374, 0, 0, 655375, 0, 0, 655376, 0, 0, 655377, 0, 0, 655378, 0, 0, 655379, 0, 0, 655380, 0, 0, 655381, 0, 0, 655382, 3, 0, 655383, 3, 0, 655384, 3, 0, 655385, 3, 0, 655386, 3, 0, 655387, 3, 0, 655388, 3, 0, 655389, 3, 0, 655390, 2, 0, 655391, 2, 0, 655392, 3, 0, 655393, 1, 0, 720896, 1, 0, 720897, 0, 0, 720898, 0, 0, 720899, 0, 0, 720900, 0, 0, 720901, 0, 0, 720902, 0, 0, 720903, 0, 0, 720904, 0, 0, 720905, 0, 0, 720906, 0, 0, 720907, 0, 0, 720908, 0, 0, 720909, 0, 0, 720910, 0, 0, 720911, 0, 0, 720912, 0, 0, 720913, 0, 0, 720914, 0, 0, 720915, 0, 0, 720916, 0, 0, 720917, 0, 0, 720918, 3, 0, 720919, 3, 0, 720920, 3, 0, 720921, 3, 0, 720922, 3, 0, 720923, 3, 0, 720924, 3, 0, 720925, 3, 0, 720926, 0, 0, 720927, 0, 0, 720928, 3, 0, 720929, 1, 0, 786432, 1, 0, 786433, 1, 0, 786434, 1, 0, 786435, 1, 0, 786436, 1, 0, 786437, 1, 0, 786438, 0, 0, 786439, 0, 0, 786440, 1, 0, 786441, 1, 0, 786442, 1, 0, 786443, 0, 0, 786444, 0, 0, 786445, 0, 0, 786446, 0, 0, 786447, 0, 0, 786448, 0, 0, 786449, 0, 0, 786450, 0, 0, 786451, 0, 0, 786452, 0, 0, 786453, 0, 0, 786454, 0, 0, 786455, 0, 0, 786456, 0, 0, 786457, 0, 0, 786458, 0, 0, 786459, 0, 0, 786460, 0, 0, 786461, 0, 0, 786462, 0, 0, 786463, 0, 0, 786464, 0, 0, 786465, 1, 0, 851968, 1, 0, 851969, 3, 0, 851970, 3, 0, 851971, 3, 0, 851972, 3, 0, 851973, 3, 0, 851974, 0, 0, 851975, 0, 0, 851976, 3, 0, 851977, 3, 0, 851978, 1, 0, 851979, 0, 0, 851980, 0, 0, 851981, 0, 0, 851982, 0, 0, 851983, 0, 0, 851984, 0, 0, 851985, 0, 0, 851986, 0, 0, 851987, 0, 0, 851988, 0, 0, 851989, 0, 0, 851990, 0, 0, 851991, 0, 0, 851992, 0, 0, 851993, 0, 0, 851994, 0, 0, 851995, 0, 0, 851996, 0, 0, 851997, 0, 0, 851998, 0, 0, 851999, 0, 0, 852000, 0, 0, 852001, 1, 0, 917504, 1, 0, 917505, 3, 0, 917506, 3, 0, 917507, 3, 0, 917508, 3, 0, 917509, 3, 0, 917510, 0, 0, 917511, 0, 0, 917512, 3, 0, 917513, 3, 0, 917514, 1, 0, 917515, 0, 0, 917516, 0, 0, 917517, 0, 0, 917518, 0, 0, 917519, 0, 0, 917520, 0, 0, 917521, 0, 0, 917522, 0, 0, 917523, 0, 0, 917524, 0, 0, 917525, 0, 0, 917526, 0, 0, 917527, 0, 0, 917528, 0, 0, 917529, 0, 0, 917530, 0, 0, 917531, 0, 0, 917532, 0, 0, 917533, 0, 0, 917534, 0, 0, 917535, 0, 0, 917536, 0, 0, 917537, 1, 0, 983040, 1, 0, 983041, 0, 0, 983042, 0, 0, 983043, 0, 0, 983044, 0, 0, 983045, 0, 0, 983046, 0, 0, 983047, 0, 0, 983048, 0, 0, 983049, 0, 0, 983050, 1, 0, 983051, 0, 0, 983052, 0, 0, 983053, 0, 0, 983054, 0, 0, 983055, 0, 0, 983056, 0, 0, 983057, 0, 0, 983058, 0, 0, 983059, 0, 0, 983060, 0, 0, 983061, 0, 0, 983062, 0, 0, 983063, 0, 0, 983064, 0, 0, 983065, 0, 0, 983066, 0, 0, 983067, 0, 0, 983068, 0, 0, 983069, 0, 0, 983070, 0, 0, 983071, 0, 0, 983072, 0, 0, 983073, 1, 0, 1048576, 1, 0, 1048577, 0, 0, 1048578, 0, 0, 1048579, 0, 0, 1048580, 0, 0, 1048581, 0, 0, 1048582, 0, 0, 1048583, 0, 0, 1048584, 0, 0, 1048585, 0, 0, 1048586, 1, 0, 1048587, 0, 0, 1048588, 0, 0, 1048589, 0, 0, 1048590, 0, 0, 1048591, 0, 0, 1048592, 0, 0, 1048593, 0, 0, 1048594, 0, 0, 1048595, 0, 0, 1048596, 0, 0, 1048597, 0, 0, 1048598, 0, 0, 1048599, 0, 0, 1048600, 0, 0, 1048601, 0, 0, 1048602, 0, 0, 1048603, 0, 0, 1048604, 0, 0, 1048605, 0, 0, 1048606, 0, 0, 1048607, 0, 0, 1048608, 0, 0, 1048609, 1, 0, 1114112, 1, 0, 1114113, 0, 0, 1114114, 0, 0, 1114115, 0, 0, 1114116, 0, 0, 1114117, 0, 0, 1114118, 0, 0, 1114119, 0, 0, 1114120, 0, 0, 1114121, 0, 0, 1114122, 1, 0, 1114123, 0, 0, 1114124, 0, 0, 1114125, 0, 0, 1114126, 0, 0, 1114127, 0, 0, 1114128, 0, 0, 1114129, 0, 0, 1114130, 0, 0, 1114131, 0, 0, 1114132, 0, 0, 1114133, 0, 0, 1114134, 0, 0, 1114135, 0, 0, 1114136, 0, 0, 1114137, 0, 0, 1114138, 0, 0, 1114139, 0, 0, 1114140, 0, 0, 1114141, 0, 0, 1114142, 0, 0, 1114143, 0, 0, 1114144, 0, 0, 1114145, 1, 0, 1179648, 1, 0, 1179649, 0, 0, 1179650, 0, 0, 1179651, 0, 0, 1179652, 0, 0, 1179653, 0, 0, 1179654, 0, 0, 1179655, 0, 0, 1179656, 0, 0, 1179657, 0, 0, 1179658, 1, 0, 1179659, 0, 0, 1179660, 0, 0, 1179661, 0, 0, 1179662, 0, 0, 1179663, 0, 0, 1179664, 0, 0, 1179665, 0, 0, 1179666, 0, 0, 1179667, 0, 0, 1179668, 0, 0, 1179669, 0, 0, 1179670, 0, 0, 1179671, 0, 0, 1179672, 0, 0, 1179673, 0, 0, 1179674, 0, 0, 1179675, 0, 0, 1179676, 0, 0, 1179677, 0, 0, 1179678, 0, 0, 1179679, 0, 0, 1179680, 0, 0, 1179681, 1, 0, 1245184, 1, 0, 1245185, 1, 0, 1245186, 1, 0, 1245187, 1, 0, 1245188, 1, 0, 1245189, 1, 0, 1245190, 1, 0, 1245191, 1, 0, 1245192, 1, 0, 1245193, 1, 0, 1245194, 1, 0, 1245195, 1, 0, 1245196, 1, 0, 1245197, 1, 0, 1245198, 1, 0, 1245199, 1, 0, 1245200, 1, 0, 1245201, 1, 0, 1245202, 1, 0, 1245203, 1, 0, 1245204, 1, 0, 1245205, 1, 0, 1245206, 1, 0, 1245207, 1, 0, 1245208, 1, 0, 1245209, 1, 0, 1245210, 1, 0, 1245211, 1, 0, 1245212, 1, 0, 1245213, 1, 0, 1245214, 1, 0, 1245215, 1, 0, 1245216, 1, 0, 1245217, 1, 0 ) + +[node name="Furniture" type="TileMap" parent="."] +tile_set = ExtResource( 5 ) +cell_size = Vector2( 8, 8 ) +cell_quadrant_size = 8 cell_custom_transform = Transform2D( 8, 0, 0, 8, 0, 0 ) show_collision = true format = 1 -tile_data = PoolIntArray( 0, 1, 0, 1, 1, 0, 2, 1, 0, 3, 1, 0, 4, 1, 0, 5, 1, 0, 6, 1, 0, 7, 1, 0, 8, 1, 0, 9, 1, 0, 10, 1, 0, 11, 1, 0, 12, 1, 0, 13, 1, 0, 14, 1, 0, 15, 1, 0, 16, 1, 0, 17, 1, 0, 18, 1, 0, 19, 1, 0, 20, 1, 0, 21, 1, 0, 22, 1, 0, 23, 1, 0, 24, 1, 0, 25, 1, 0, 26, 1, 0, 27, 1, 0, 28, 1, 0, 29, 1, 0, 30, 1, 0, 31, 1, 0, 32, 1, 0, 33, 1, 0, 65536, 1, 0, 65537, 3, 0, 65538, 3, 0, 65539, 3, 0, 65540, 3, 0, 65541, 3, 0, 65542, 3, 0, 65543, 3, 0, 65544, 3, 0, 65545, 3, 0, 65546, 3, 0, 65547, 3, 0, 65548, 3, 0, 65549, 3, 0, 65550, 3, 0, 65551, 3, 0, 65552, 3, 0, 65553, 3, 0, 65554, 3, 0, 65555, 3, 0, 65556, 3, 0, 65557, 3, 0, 65558, 1, 0, 65559, 3, 0, 65560, 3, 0, 65561, 3, 0, 65562, 3, 0, 65563, 3, 0, 65564, 3, 0, 65565, 3, 0, 65566, 3, 0, 65567, 3, 0, 65568, 3, 0, 65569, 1, 0, 131072, 1, 0, 131073, 0, 0, 131074, 0, 0, 131075, 0, 0, 131076, 0, 0, 131077, 0, 0, 131078, 0, 0, 131079, 0, 0, 131080, 0, 0, 131081, 0, 0, 131082, 0, 0, 131083, 0, 0, 131084, 0, 0, 131085, 0, 0, 131086, 0, 0, 131087, 0, 0, 131088, 0, 0, 131089, 0, 0, 131090, 0, 0, 131091, 0, 0, 131092, 0, 0, 131093, 0, 0, 131094, 1, 0, 131095, 2, 0, 131096, 2, 0, 131097, 2, 0, 131098, 2, 0, 131099, 2, 0, 131100, 2, 0, 131101, 2, 0, 131102, 2, 0, 131103, 2, 0, 131104, 2, 0, 131105, 1, 0, 196608, 1, 0, 196609, 0, 0, 196610, 0, 0, 196611, 0, 0, 196612, 0, 0, 196613, 0, 0, 196614, 0, 0, 196615, 0, 0, 196616, 0, 0, 196617, 0, 0, 196618, 0, 0, 196619, 0, 0, 196620, 0, 0, 196621, 0, 0, 196622, 0, 0, 196623, 0, 0, 196624, 0, 0, 196625, 0, 0, 196626, 0, 0, 196627, 0, 0, 196628, 0, 0, 196629, 0, 0, 196630, 1, 0, 196631, 2, 0, 196632, 2, 0, 196633, 2, 0, 196634, 2, 0, 196635, 2, 0, 196636, 2, 0, 196637, 2, 0, 196638, 2, 0, 196639, 2, 0, 196640, 2, 0, 196641, 1, 0, 262144, 1, 0, 262145, 0, 0, 262146, 0, 0, 262147, 0, 0, 262148, 0, 0, 262149, 0, 0, 262150, 0, 0, 262151, 0, 0, 262152, 0, 0, 262153, 0, 0, 262154, 0, 0, 262155, 0, 0, 262156, 0, 0, 262157, 0, 0, 262158, 0, 0, 262159, 0, 0, 262160, 0, 0, 262161, 0, 0, 262162, 0, 0, 262163, 0, 0, 262164, 0, 0, 262165, 0, 0, 262166, 1, 0, 262167, 2, 0, 262168, 2, 0, 262169, 2, 0, 262170, 2, 0, 262171, 2, 0, 262172, 2, 0, 262173, 2, 0, 262174, 2, 0, 262175, 2, 0, 262176, 2, 0, 262177, 1, 0, 327680, 1, 0, 327681, 0, 0, 327682, 0, 0, 327683, 0, 0, 327684, 0, 0, 327685, 0, 0, 327686, 0, 0, 327687, 0, 0, 327688, 0, 0, 327689, 0, 0, 327690, 0, 0, 327691, 0, 0, 327692, 0, 0, 327693, 0, 0, 327694, 0, 0, 327695, 0, 0, 327696, 0, 0, 327697, 0, 0, 327698, 0, 0, 327699, 0, 0, 327700, 0, 0, 327701, 0, 0, 327702, 1, 0, 327703, 2, 0, 327704, 2, 0, 327705, 2, 0, 327706, 2, 0, 327707, 2, 0, 327708, 2, 0, 327709, 2, 0, 327710, 2, 0, 327711, 2, 0, 327712, 2, 0, 327713, 1, 0, 393216, 1, 0, 393217, 0, 0, 393218, 0, 0, 393219, 0, 0, 393220, 0, 0, 393221, 0, 0, 393222, 0, 0, 393223, 0, 0, 393224, 0, 0, 393225, 0, 0, 393226, 0, 0, 393227, 0, 0, 393228, 0, 0, 393229, 0, 0, 393230, 0, 0, 393231, 0, 0, 393232, 0, 0, 393233, 0, 0, 393234, 0, 0, 393235, 0, 0, 393236, 0, 0, 393237, 0, 0, 393238, 1, 0, 393239, 2, 0, 393240, 2, 0, 393241, 2, 0, 393242, 2, 0, 393243, 2, 0, 393244, 2, 0, 393245, 2, 0, 393246, 2, 0, 393247, 2, 0, 393248, 2, 0, 393249, 1, 0, 458752, 1, 0, 458753, 0, 0, 458754, 0, 0, 458755, 0, 0, 458756, 0, 0, 458757, 0, 0, 458758, 0, 0, 458759, 0, 0, 458760, 0, 0, 458761, 0, 0, 458762, 0, 0, 458763, 0, 0, 458764, 0, 0, 458765, 0, 0, 458766, 0, 0, 458767, 0, 0, 458768, 0, 0, 458769, 0, 0, 458770, 0, 0, 458771, 0, 0, 458772, 0, 0, 458773, 0, 0, 458774, 1, 0, 458775, 2, 0, 458776, 2, 0, 458777, 2, 0, 458778, 2, 0, 458779, 2, 0, 458780, 2, 0, 458781, 2, 0, 458782, 2, 0, 458783, 2, 0, 458784, 2, 0, 458785, 1, 0, 524288, 1, 0, 524289, 0, 0, 524290, 0, 0, 524291, 0, 0, 524292, 0, 0, 524293, 0, 0, 524294, 0, 0, 524295, 0, 0, 524296, 0, 0, 524297, 0, 0, 524298, 0, 0, 524299, 0, 0, 524300, 0, 0, 524301, 0, 0, 524302, 0, 0, 524303, 0, 0, 524304, 0, 0, 524305, 0, 0, 524306, 0, 0, 524307, 0, 0, 524308, 0, 0, 524309, 0, 0, 524310, 1, 0, 524311, 2, 0, 524312, 2, 0, 524313, 2, 0, 524314, 2, 0, 524315, 2, 0, 524316, 2, 0, 524317, 2, 0, 524318, 2, 0, 524319, 2, 0, 524320, 2, 0, 524321, 1, 0, 589824, 1, 0, 589825, 0, 0, 589826, 0, 0, 589827, 0, 0, 589828, 0, 0, 589829, 0, 0, 589830, 0, 0, 589831, 0, 0, 589832, 0, 0, 589833, 0, 0, 589834, 0, 0, 589835, 0, 0, 589836, 0, 0, 589837, 0, 0, 589838, 0, 0, 589839, 0, 0, 589840, 0, 0, 589841, 0, 0, 589842, 0, 0, 589843, 0, 0, 589844, 0, 0, 589845, 0, 0, 589846, 1, 0, 589847, 1, 0, 589848, 1, 0, 589849, 1, 0, 589850, 1, 0, 589851, 1, 0, 589852, 1, 0, 589853, 1, 0, 589854, 2, 0, 589855, 2, 0, 589856, 1, 0, 589857, 1, 0, 655360, 1, 0, 655361, 0, 0, 655362, 0, 0, 655363, 0, 0, 655364, 0, 0, 655365, 0, 0, 655366, 0, 0, 655367, 0, 0, 655368, 0, 0, 655369, 0, 0, 655370, 0, 0, 655371, 0, 0, 655372, 0, 0, 655373, 0, 0, 655374, 0, 0, 655375, 0, 0, 655376, 0, 0, 655377, 0, 0, 655378, 0, 0, 655379, 0, 0, 655380, 0, 0, 655381, 0, 0, 655382, 3, 0, 655383, 3, 0, 655384, 3, 0, 655385, 3, 0, 655386, 3, 0, 655387, 3, 0, 655388, 3, 0, 655389, 3, 0, 655390, 0, 0, 655391, 0, 0, 655392, 3, 0, 655393, 1, 0, 720896, 1, 0, 720897, 0, 0, 720898, 0, 0, 720899, 0, 0, 720900, 0, 0, 720901, 0, 0, 720902, 0, 0, 720903, 0, 0, 720904, 0, 0, 720905, 0, 0, 720906, 0, 0, 720907, 0, 0, 720908, 0, 0, 720909, 0, 0, 720910, 0, 0, 720911, 0, 0, 720912, 0, 0, 720913, 0, 0, 720914, 0, 0, 720915, 0, 0, 720916, 0, 0, 720917, 0, 0, 720918, 0, 0, 720919, 0, 0, 720920, 0, 0, 720921, 0, 0, 720922, 0, 0, 720923, 0, 0, 720924, 0, 0, 720925, 0, 0, 720926, 0, 0, 720927, 0, 0, 720928, 0, 0, 720929, 1, 0, 786432, 1, 0, 786433, 0, 0, 786434, 0, 0, 786435, 0, 0, 786436, 0, 0, 786437, 0, 0, 786438, 0, 0, 786439, 0, 0, 786440, 0, 0, 786441, 0, 0, 786442, 0, 0, 786443, 0, 0, 786444, 0, 0, 786445, 0, 0, 786446, 0, 0, 786447, 0, 0, 786448, 0, 0, 786449, 0, 0, 786450, 0, 0, 786451, 0, 0, 786452, 0, 0, 786453, 0, 0, 786454, 0, 0, 786455, 0, 0, 786456, 0, 0, 786457, 0, 0, 786458, 0, 0, 786459, 0, 0, 786460, 0, 0, 786461, 0, 0, 786462, 0, 0, 786463, 0, 0, 786464, 0, 0, 786465, 1, 0, 851968, 1, 0, 851969, 0, 0, 851970, 0, 0, 851971, 0, 0, 851972, 0, 0, 851973, 0, 0, 851974, 0, 0, 851975, 0, 0, 851976, 0, 0, 851977, 0, 0, 851978, 0, 0, 851979, 0, 0, 851980, 0, 0, 851981, 0, 0, 851982, 0, 0, 851983, 0, 0, 851984, 0, 0, 851985, 0, 0, 851986, 0, 0, 851987, 0, 0, 851988, 0, 0, 851989, 0, 0, 851990, 0, 0, 851991, 0, 0, 851992, 0, 0, 851993, 0, 0, 851994, 0, 0, 851995, 0, 0, 851996, 0, 0, 851997, 0, 0, 851998, 0, 0, 851999, 0, 0, 852000, 0, 0, 852001, 1, 0, 917504, 1, 0, 917505, 0, 0, 917506, 0, 0, 917507, 0, 0, 917508, 0, 0, 917509, 0, 0, 917510, 0, 0, 917511, 0, 0, 917512, 0, 0, 917513, 0, 0, 917514, 0, 0, 917515, 0, 0, 917516, 0, 0, 917517, 0, 0, 917518, 0, 0, 917519, 0, 0, 917520, 0, 0, 917521, 0, 0, 917522, 0, 0, 917523, 0, 0, 917524, 0, 0, 917525, 0, 0, 917526, 0, 0, 917527, 0, 0, 917528, 0, 0, 917529, 0, 0, 917530, 0, 0, 917531, 0, 0, 917532, 0, 0, 917533, 0, 0, 917534, 0, 0, 917535, 0, 0, 917536, 0, 0, 917537, 1, 0, 983040, 1, 0, 983041, 0, 0, 983042, 0, 0, 983043, 0, 0, 983044, 0, 0, 983045, 0, 0, 983046, 0, 0, 983047, 0, 0, 983048, 0, 0, 983049, 0, 0, 983050, 0, 0, 983051, 0, 0, 983052, 0, 0, 983053, 0, 0, 983054, 0, 0, 983055, 0, 0, 983056, 0, 0, 983057, 0, 0, 983058, 0, 0, 983059, 0, 0, 983060, 0, 0, 983061, 0, 0, 983062, 0, 0, 983063, 0, 0, 983064, 0, 0, 983065, 0, 0, 983066, 0, 0, 983067, 0, 0, 983068, 0, 0, 983069, 0, 0, 983070, 0, 0, 983071, 0, 0, 983072, 0, 0, 983073, 1, 0, 1048576, 1, 0, 1048577, 0, 0, 1048578, 0, 0, 1048579, 0, 0, 1048580, 0, 0, 1048581, 0, 0, 1048582, 0, 0, 1048583, 0, 0, 1048584, 0, 0, 1048585, 0, 0, 1048586, 0, 0, 1048587, 0, 0, 1048588, 0, 0, 1048589, 0, 0, 1048590, 0, 0, 1048591, 0, 0, 1048592, 0, 0, 1048593, 0, 0, 1048594, 0, 0, 1048595, 0, 0, 1048596, 0, 0, 1048597, 0, 0, 1048598, 0, 0, 1048599, 0, 0, 1048600, 0, 0, 1048601, 0, 0, 1048602, 0, 0, 1048603, 0, 0, 1048604, 0, 0, 1048605, 0, 0, 1048606, 0, 0, 1048607, 0, 0, 1048608, 0, 0, 1048609, 1, 0, 1114112, 1, 0, 1114113, 0, 0, 1114114, 0, 0, 1114115, 0, 0, 1114116, 0, 0, 1114117, 0, 0, 1114118, 0, 0, 1114119, 0, 0, 1114120, 0, 0, 1114121, 0, 0, 1114122, 0, 0, 1114123, 0, 0, 1114124, 0, 0, 1114125, 0, 0, 1114126, 0, 0, 1114127, 0, 0, 1114128, 0, 0, 1114129, 0, 0, 1114130, 0, 0, 1114131, 0, 0, 1114132, 0, 0, 1114133, 0, 0, 1114134, 0, 0, 1114135, 0, 0, 1114136, 0, 0, 1114137, 0, 0, 1114138, 0, 0, 1114139, 0, 0, 1114140, 0, 0, 1114141, 0, 0, 1114142, 0, 0, 1114143, 0, 0, 1114144, 0, 0, 1114145, 1, 0, 1179648, 1, 0, 1179649, 0, 0, 1179650, 0, 0, 1179651, 0, 0, 1179652, 0, 0, 1179653, 0, 0, 1179654, 0, 0, 1179655, 0, 0, 1179656, 0, 0, 1179657, 0, 0, 1179658, 0, 0, 1179659, 0, 0, 1179660, 0, 0, 1179661, 0, 0, 1179662, 0, 0, 1179663, 0, 0, 1179664, 0, 0, 1179665, 0, 0, 1179666, 0, 0, 1179667, 0, 0, 1179668, 0, 0, 1179669, 0, 0, 1179670, 0, 0, 1179671, 0, 0, 1179672, 0, 0, 1179673, 0, 0, 1179674, 0, 0, 1179675, 0, 0, 1179676, 0, 0, 1179677, 0, 0, 1179678, 0, 0, 1179679, 0, 0, 1179680, 0, 0, 1179681, 1, 0, 1245184, 1, 0, 1245185, 1, 0, 1245186, 1, 0, 1245187, 1, 0, 1245188, 1, 0, 1245189, 1, 0, 1245190, 1, 0, 1245191, 1, 0, 1245192, 1, 0, 1245193, 1, 0, 1245194, 1, 0, 1245195, 1, 0, 1245196, 1, 0, 1245197, 1, 0, 1245198, 1, 0, 1245199, 1, 0, 1245200, 1, 0, 1245201, 1, 0, 1245202, 1, 0, 1245203, 1, 0, 1245204, 1, 0, 1245205, 1, 0, 1245206, 1, 0, 1245207, 1, 0, 1245208, 1, 0, 1245209, 1, 0, 1245210, 1, 0, 1245211, 1, 0, 1245212, 1, 0, 1245213, 1, 0, 1245214, 1, 0, 1245215, 1, 0, 1245216, 1, 0, 1245217, 1, 0 ) +tile_data = PoolIntArray( 524300, 3, 0, 917505, 0, 0 ) [node name="WaterThings" type="Node2D" parent="."] [node name="Jug" parent="WaterThings" instance=ExtResource( 3 )] -position = Vector2( 125, 24 ) +position = Vector2( 237, 20 ) [node name="Jug2" parent="WaterThings" instance=ExtResource( 3 )] +position = Vector2( 15, 109 ) -[node name="Jug3" parent="WaterThings" instance=ExtResource( 3 )] -position = Vector2( 77, 84 ) +[node name="Glass" parent="WaterThings" instance=ExtResource( 7 )] +position = Vector2( 102, 68 ) -[node name="Jug4" parent="WaterThings" instance=ExtResource( 3 )] -position = Vector2( 36, 42 ) +[node name="Glass2" parent="WaterThings" instance=ExtResource( 7 )] +position = Vector2( 144, 52 ) -[node name="Jug5" parent="WaterThings" instance=ExtResource( 3 )] -position = Vector2( 160, 56 ) +[node name="Glass3" parent="WaterThings" instance=ExtResource( 7 )] +position = Vector2( 116, 78 ) + +[node name="Glass4" parent="WaterThings" instance=ExtResource( 7 )] +position = Vector2( 158, 63 ) + +[node name="Glass5" parent="WaterThings" instance=ExtResource( 7 )] +position = Vector2( 73, 45 ) + +[node name="Glass6" parent="WaterThings" instance=ExtResource( 7 )] +position = Vector2( 115, 29 ) + +[node name="Glass7" parent="WaterThings" instance=ExtResource( 7 )] +position = Vector2( 87, 55 ) + +[node name="Glass8" parent="WaterThings" instance=ExtResource( 7 )] +position = Vector2( 129, 40 ) [node name="Player" parent="." instance=ExtResource( 2 )] position = Vector2( 136, 80 ) @@ -37,3 +69,28 @@ position = Vector2( 136, 80 ) position = Vector2( 136, 80 ) current = true zoom = Vector2( 0.265, 0.265 ) + +[node name="UI" type="Control" parent="."] +margin_right = 272.0 +margin_bottom = 160.0 +__meta__ = { +"_edit_lock_": true +} + +[node name="TimeLeft" type="Label" parent="UI"] +margin_right = 73.0 +margin_bottom = 14.0 +custom_fonts/font = SubResource( 1 ) +text = "Time Left: " + +[node name="Points" type="Label" parent="UI"] +margin_top = 8.0 +margin_right = 73.0 +margin_bottom = 22.0 +custom_fonts/font = SubResource( 1 ) +text = "Points:" + +[node name="Timer" type="Timer" parent="."] +wait_time = 30.0 +one_shot = true +autostart = true diff --git a/Scenes/Player.tscn b/Scenes/Player.tscn index 8143faa..70cda4c 100644 --- a/Scenes/Player.tscn +++ b/Scenes/Player.tscn @@ -1,10 +1,13 @@ -[gd_scene load_steps=6 format=2] +[gd_scene load_steps=7 format=2] [ext_resource path="res://Sprites/player.png" type="Texture" id=1] [ext_resource path="res://Scripts/Player.gd" type="Script" id=2] -[sub_resource type="RectangleShape2D" id=1] -extents = Vector2( 5, 10.2143 ) +[sub_resource type="CircleShape2D" id=5] +radius = 6.0 + +[sub_resource type="RectangleShape2D" id=4] +extents = Vector2( 5.71429, 11.4286 ) [sub_resource type="Animation" id=2] length = 0.001 @@ -46,9 +49,16 @@ script = ExtResource( 2 ) texture = ExtResource( 1 ) [node name="CollisionShape2D" type="CollisionShape2D" parent="."] -position = Vector2( 0, 1.64286 ) +position = Vector2( 0, 5.92858 ) scale = Vector2( 1, 1 ) -shape = SubResource( 1 ) +shape = SubResource( 5 ) + +[node name="PlayerArea" type="Area2D" parent="."] +scale = Vector2( 1, 1 ) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="PlayerArea"] +position = Vector2( -1.70299e-07, -3.40598e-07 ) +shape = SubResource( 4 ) [node name="AnimationPlayer" type="AnimationPlayer" parent="."] anims/RESET = SubResource( 2 ) diff --git a/Scenes/Start.tscn b/Scenes/Start.tscn new file mode 100644 index 0000000..fa41939 --- /dev/null +++ b/Scenes/Start.tscn @@ -0,0 +1,86 @@ +[gd_scene load_steps=13 format=2] + +[ext_resource path="res://fonts/game over.ttf" type="DynamicFontData" id=1] +[ext_resource path="res://Sprites/bg.png" type="Texture" id=2] +[ext_resource path="res://fonts/dotty.ttf" type="DynamicFontData" id=3] +[ext_resource path="res://Scripts/Start.gd" type="Script" id=4] + +[sub_resource type="DynamicFont" id=1] +size = 64 +font_data = ExtResource( 1 ) + +[sub_resource type="StyleBoxEmpty" id=2] + +[sub_resource type="StyleBoxEmpty" id=3] + +[sub_resource type="StyleBoxEmpty" id=4] + +[sub_resource type="StyleBoxEmpty" id=5] + +[sub_resource type="StyleBoxEmpty" id=6] + +[sub_resource type="DynamicFont" id=7] +size = 128 +font_data = ExtResource( 1 ) + +[sub_resource type="DynamicFont" id=8] +size = 64 +font_data = ExtResource( 3 ) + +[node name="Control" type="Control"] +anchor_right = 1.0 +anchor_bottom = 1.0 +script = ExtResource( 4 ) + +[node name="Background" type="TextureRect" parent="."] +anchor_right = 1.0 +anchor_bottom = 1.0 +texture = ExtResource( 2 ) +expand = true + +[node name="Button" type="Button" parent="."] +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +margin_left = -80.0 +margin_top = 84.0 +margin_right = 80.0 +margin_bottom = 130.0 +custom_colors/font_color_hover = Color( 0.290196, 0.517647, 1, 1 ) +custom_fonts/font = SubResource( 1 ) +custom_styles/hover = SubResource( 2 ) +custom_styles/pressed = SubResource( 3 ) +custom_styles/focus = SubResource( 4 ) +custom_styles/disabled = SubResource( 5 ) +custom_styles/normal = SubResource( 6 ) +text = "Start" + +[node name="Label" type="Label" parent="."] +anchor_left = 0.5 +anchor_right = 0.5 +margin_left = -200.0 +margin_top = 64.0 +margin_right = 200.0 +margin_bottom = 144.0 +custom_fonts/font = SubResource( 7 ) +text = "H2Grow" + +[node name="Label2" type="Label" parent="."] +anchor_left = 0.5 +anchor_top = 1.0 +anchor_right = 0.5 +anchor_bottom = 1.0 +margin_left = -512.0 +margin_top = -64.0 +margin_right = 512.0 +custom_colors/font_color = Color( 1, 0.262745, 0.262745, 1 ) +custom_colors/font_outline_modulate = Color( 1, 1, 1, 1 ) +custom_fonts/font = SubResource( 8 ) +text = "Read instructions on itch.io before playing the game!" +align = 1 +valign = 1 +autowrap = true +clip_text = true + +[connection signal="pressed" from="Button" to="." method="_on_Button_pressed"] diff --git a/Scenes/WaterThings/Glass.tscn b/Scenes/WaterThings/Glass.tscn new file mode 100644 index 0000000..b5c6198 --- /dev/null +++ b/Scenes/WaterThings/Glass.tscn @@ -0,0 +1,28 @@ +[gd_scene load_steps=6 format=2] + +[ext_resource path="res://Scripts/WaterThing.gd" type="Script" id=1] +[ext_resource path="res://Sprites/Water/Glass.png" type="Texture" id=2] +[ext_resource path="res://Sounds/Sfxr/break.sfxr" type="AudioStream" id=3] +[ext_resource path="res://Sounds/Sfxr/punch.sfxr" type="AudioStream" id=4] + +[sub_resource type="RectangleShape2D" id=1] +extents = Vector2( 5, 6 ) + +[node name="Glass" type="Area2D"] +scale = Vector2( 0.5, 0.5 ) +script = ExtResource( 1 ) + +[node name="Sprite" type="Sprite" parent="."] +texture = ExtResource( 2 ) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource( 1 ) + +[node name="PunchPlayer" type="AudioStreamPlayer" parent="."] +stream = ExtResource( 4 ) + +[node name="BreakPlayer" type="AudioStreamPlayer" parent="."] +stream = ExtResource( 3 ) + +[connection signal="area_entered" from="." to="." method="_on_body_entered"] +[connection signal="area_exited" from="." to="." method="_on_body_exited"] diff --git a/Scenes/WaterThings/Jug.tscn b/Scenes/WaterThings/Jug.tscn index 2c19b7f..0e9e5c3 100644 --- a/Scenes/WaterThings/Jug.tscn +++ b/Scenes/WaterThings/Jug.tscn @@ -1,7 +1,9 @@ -[gd_scene load_steps=4 format=2] +[gd_scene load_steps=6 format=2] [ext_resource path="res://Sprites/Water/Jug.png" type="Texture" id=1] [ext_resource path="res://Scripts/WaterThing.gd" type="Script" id=2] +[ext_resource path="res://Sounds/Sfxr/punch.sfxr" type="AudioStream" id=3] +[ext_resource path="res://Sounds/Sfxr/break.sfxr" type="AudioStream" id=4] [sub_resource type="RectangleShape2D" id=1] extents = Vector2( 5, 6 ) @@ -17,5 +19,11 @@ texture = ExtResource( 1 ) position = Vector2( 1, 0 ) shape = SubResource( 1 ) -[connection signal="body_entered" from="." to="." method="_on_body_entered"] -[connection signal="body_exited" from="." to="." method="_on_body_exited"] +[node name="PunchPlayer" type="AudioStreamPlayer" parent="."] +stream = ExtResource( 3 ) + +[node name="BreakPlayer" type="AudioStreamPlayer" parent="."] +stream = ExtResource( 4 ) + +[connection signal="area_entered" from="." to="." method="_on_body_entered"] +[connection signal="area_exited" from="." to="." method="_on_body_exited"] diff --git a/Scripts/End.gd b/Scripts/End.gd new file mode 100644 index 0000000..e6cc109 --- /dev/null +++ b/Scripts/End.gd @@ -0,0 +1,4 @@ +extends Control + +func _ready(): + $Points.text += " " + str(Utils.points) diff --git a/Scripts/Game.gd b/Scripts/Game.gd new file mode 100644 index 0000000..5ffe693 --- /dev/null +++ b/Scripts/Game.gd @@ -0,0 +1,7 @@ +extends Node2D + +func _process(delta): + $UI/TimeLeft.text = "Time left: " + str($Timer.time_left) + $UI/Points.text = "Points: " + str(Utils.points) + if ($Timer.time_left == 0): + get_tree().change_scene("res://Scenes/End.tscn") diff --git a/Scripts/Player.gd b/Scripts/Player.gd index c1452bd..cd6a6e8 100644 --- a/Scripts/Player.gd +++ b/Scripts/Player.gd @@ -9,6 +9,7 @@ func _ready(): func _physics_process(delta): velocity = Vector2() + # Input if Input.is_action_pressed("down"): velocity.y += speed if Input.is_action_pressed("up"): @@ -17,7 +18,8 @@ func _physics_process(delta): velocity.x -= speed if Input.is_action_pressed("right"): velocity.x += speed - + + # Animation if Input.is_action_pressed("right") || Input.is_action_pressed("left") \ || Input.is_action_pressed("up") || Input.is_action_pressed("down"): $AnimationPlayer.play("Walk") diff --git a/Scripts/Start.gd b/Scripts/Start.gd new file mode 100644 index 0000000..9dd1915 --- /dev/null +++ b/Scripts/Start.gd @@ -0,0 +1,4 @@ +extends Control + +func _on_Button_pressed(): + get_tree().change_scene("res://Scenes/Game.tscn") diff --git a/Scripts/Utils.gd b/Scripts/Utils.gd new file mode 100644 index 0000000..b210d13 --- /dev/null +++ b/Scripts/Utils.gd @@ -0,0 +1,3 @@ +extends Node + +var points = 0 diff --git a/Scripts/WaterThing.gd b/Scripts/WaterThing.gd index 9e9d1ec..3842412 100644 --- a/Scripts/WaterThing.gd +++ b/Scripts/WaterThing.gd @@ -1,7 +1,7 @@ extends Area2D var broken = false -var hits_left = 2 +var hits_left = 3 var player = false var player_body = null @@ -13,12 +13,12 @@ func replace_numbers(name: String) -> String: return new_name func _on_body_entered(body): - if body.name == "Player" and !broken: + if body.get_parent().name == "Player": player = true - player_body = body + player_body = body.get_parent() func _on_body_exited(body): - if body.name == "Player" and !broken: + if body.get_parent().name == "Player": player = false player_body = null @@ -26,8 +26,16 @@ func _process(delta): if player && player_body != null: if Input.is_action_just_pressed("punch"): if hits_left > 0: + $PunchPlayer.play() hits_left -= 1 - if hits_left == 0 && broken == false: + if hits_left == 0 && !broken: + # Mod Thing + $BreakPlayer.play() $Sprite.texture = load("res://Sprites/Water/Broken/" + replace_numbers(name) + ".png") - player_body.scale += Vector2(0.05, 0.05) broken = true + # Mod Player + player_body.scale += Vector2(0.05, 0.05) + player_body.get_node("CollisionShape2D").scale -= Vector2(0.05, 0.05) + player_body.speed -= 0.5 + # Add points + Utils.points += 1 diff --git a/Sounds/Sfxr/break.sfxr b/Sounds/Sfxr/break.sfxr new file mode 100644 index 0000000000000000000000000000000000000000..737ead2934dbe506d5ffdae59c6a997efaaf63c4 GIT binary patch literal 105 zcmYdeU|?VdVj!^JvRB>~#88<%-3~;|Ar`%F`w#LSP~c%+zviOp zpEQ-WM3sATtMpY|IRA$KczR>w)B^_(>KCkaxg8qR>9p;2y5sXnr!4mC-IyVn!QC6^ rANX1AP9>Yi#r2a;Ju!VS@4MUzYl*~-kyB-X7BG0a`njxgN@xNA9Pl<0 literal 0 HcmV?d00001 diff --git a/Sprites/Water/Broken/Glass.png.import b/Sprites/Water/Broken/Glass.png.import new file mode 100644 index 0000000..9896134 --- /dev/null +++ b/Sprites/Water/Broken/Glass.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/Glass.png-3b2015c0dd629c60d3c1b09d9013c59c.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Sprites/Water/Broken/Glass.png" +dest_files=[ "res://.import/Glass.png-3b2015c0dd629c60d3c1b09d9013c59c.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=false +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=false +svg/scale=1.0 diff --git a/Sprites/Water/Glass.png b/Sprites/Water/Glass.png new file mode 100644 index 0000000000000000000000000000000000000000..e8e3fe9002c28dada8ed39e20c0f06a6179130cf GIT binary patch literal 171 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`MV>B>Ar`&K2@)X>Zgg(`?-_cy zY2AWMzC`BjB>doKU}RxrsNHnp QK2U+9sk-rl*5An^41`uQ(D6}a*MfsVn{6T2obc5&YDNj|u&`&=Fa!+SZk UG!^CjJPbhK>FVdQ&MBb@0B$85+W-In diff --git a/Sprites/furniture.tres b/Sprites/furniture.tres new file mode 100644 index 0000000..190d3e1 --- /dev/null +++ b/Sprites/furniture.tres @@ -0,0 +1,68 @@ +[gd_resource type="TileSet" load_steps=5 format=2] + +[ext_resource path="res://Sprites/wardrobe.png" type="Texture" id=1] +[ext_resource path="res://Sprites/table.png" type="Texture" id=2] + +[sub_resource type="ConvexPolygonShape2D" id=1] +points = PoolVector2Array( 16, 11.2241, 0, 11.3539, 0, 0, 16, 0 ) + +[sub_resource type="ConvexPolygonShape2D" id=2] +points = PoolVector2Array( 12, 12, 0, 12, 0, 0, 12, 0 ) + +[resource] +0/name = "wardrobe.png 0" +0/texture = ExtResource( 1 ) +0/tex_offset = Vector2( 0, 0 ) +0/modulate = Color( 1, 1, 1, 1 ) +0/region = Rect2( 0, 0, 16, 16 ) +0/tile_mode = 0 +0/occluder_offset = Vector2( 0, 0 ) +0/navigation_offset = Vector2( 0, 0 ) +0/shape_offset = Vector2( 0, 0 ) +0/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) +0/shape = SubResource( 1 ) +0/shape_one_way = false +0/shape_one_way_margin = 1.0 +0/shapes = [ { +"autotile_coord": Vector2( 0, 0 ), +"one_way": false, +"one_way_margin": 1.0, +"shape": SubResource( 1 ), +"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) +} ] +0/z_index = 0 +2/name = "table.png 2" +2/texture = ExtResource( 2 ) +2/tex_offset = Vector2( 0, 0 ) +2/modulate = Color( 1, 1, 1, 1 ) +2/region = Rect2( 3, 1, 0, 0 ) +2/tile_mode = 0 +2/occluder_offset = Vector2( 0, 0 ) +2/navigation_offset = Vector2( 0, 0 ) +2/shape_offset = Vector2( 0, 0 ) +2/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) +2/shape_one_way = false +2/shape_one_way_margin = 0.0 +2/shapes = [ ] +2/z_index = 0 +3/name = "table.png 3" +3/texture = ExtResource( 2 ) +3/tex_offset = Vector2( 0, 0 ) +3/modulate = Color( 1, 1, 1, 1 ) +3/region = Rect2( 0, 0, 12, 12 ) +3/tile_mode = 0 +3/occluder_offset = Vector2( 0, 0 ) +3/navigation_offset = Vector2( 0, 0 ) +3/shape_offset = Vector2( 0, 0 ) +3/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) +3/shape = SubResource( 2 ) +3/shape_one_way = false +3/shape_one_way_margin = 1.0 +3/shapes = [ { +"autotile_coord": Vector2( 0, 0 ), +"one_way": false, +"one_way_margin": 1.0, +"shape": SubResource( 2 ), +"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) +} ] +3/z_index = 0 diff --git a/Sprites/table.png b/Sprites/table.png new file mode 100644 index 0000000000000000000000000000000000000000..03f94a597d2d5fd9406634fbb9d647cd34d3519a GIT binary patch literal 132 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$1|-8uW1a&kZ%-G;5RHk+2@<~=3~%~PYHVzL zXut8*Opkyw2M!$gFuyZI-O$j$z+lpXd4jGR`x^zAnU@JmZjY&GPh$3D$YbWaY?$M? fjWIss;8TXrLA=LS_MJWpG?u~B)z4*}Q$iB}4!tZh literal 0 HcmV?d00001 diff --git a/Sprites/table.png.import b/Sprites/table.png.import new file mode 100644 index 0000000..4fa83b3 --- /dev/null +++ b/Sprites/table.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/table.png-6287c5224e3a2223ad79685cc0bf8f85.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Sprites/table.png" +dest_files=[ "res://.import/table.png-6287c5224e3a2223ad79685cc0bf8f85.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=false +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=false +svg/scale=1.0 diff --git a/Sprites/wardrobe.png b/Sprites/wardrobe.png new file mode 100644 index 0000000000000000000000000000000000000000..13ee3b694d0a561fd0f1bb3d605b83720d86cfdc GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`X`U{QAr`&KDG3P)9cEAepLbx3 zsQRU>%-wVN;K|m75ANK(&I1B&rxr;R+3%}Q2C7R)P&%HLVvxnKmgk4^nxh}wBe>P& zB{w99)>QNA&tJgp!MK=B;V6?%xgxW!X5O440|tiQr4k#PoKBnt+Q{JP>gTe~DWM4f DLBTYC literal 0 HcmV?d00001 diff --git a/Sprites/wardrobe.png.import b/Sprites/wardrobe.png.import new file mode 100644 index 0000000..7183ec7 --- /dev/null +++ b/Sprites/wardrobe.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/wardrobe.png-67445500d100c0d821e09597f4b6463a.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Sprites/wardrobe.png" +dest_files=[ "res://.import/wardrobe.png-67445500d100c0d821e09597f4b6463a.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=false +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=false +svg/scale=1.0 diff --git a/addons/gdfxr/Base58.gd b/addons/gdfxr/Base58.gd new file mode 100644 index 0000000..6f484bd --- /dev/null +++ b/addons/gdfxr/Base58.gd @@ -0,0 +1,38 @@ +extends Object + +const BASE_58_ALPHABET := "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" + + +static func b58decode(v: String) -> StreamPeerBuffer: + # Base 58 is a number expressed in the base-58 numeral system. + # When encoding data, big-endian is used and leading zeros are encoded as leading `1`s. + + var original_length := v.length() + v = v.lstrip(BASE_58_ALPHABET[0]) + var zeros := original_length - v.length() + + var buffer := PoolByteArray() + buffer.resize(v.length()) # Won't be as long as base 58 string since the buffer is 256-based. + buffer.fill(0) + + var length := 0 + for c in v: + var carry := BASE_58_ALPHABET.find(c) + if carry == -1: + return null + var i := 0 + while carry != 0 or i < length: + var pos := buffer.size() - 1 - i + carry += 58 * buffer[pos] + buffer[pos] = carry % 256 + carry /= 256 + i += 1 + length = i + + var result := StreamPeerBuffer.new() + for _i in zeros: + result.put_8(0) + result.put_data(buffer.subarray(buffer.size() - length, -1)) + result.seek(0) + + return result diff --git a/addons/gdfxr/LICENSE b/addons/gdfxr/LICENSE new file mode 100644 index 0000000..4544320 --- /dev/null +++ b/addons/gdfxr/LICENSE @@ -0,0 +1,7 @@ +Copyright 2022 Haoyu Qiu + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/addons/gdfxr/SFXRConfig.gd b/addons/gdfxr/SFXRConfig.gd new file mode 100644 index 0000000..a290ff1 --- /dev/null +++ b/addons/gdfxr/SFXRConfig.gd @@ -0,0 +1,511 @@ +# GDScript port of the original SFXR +# https://www.drpetter.se/project_sfxr.html + +enum WaveType { + SQUARE_WAVE, + SAWTOOTH, + SINE_WAVE, + NOISE, +} + +enum Category { + PICKUP_COIN, + LASER_SHOOT, + EXPLOSION, + POWERUP, + HIT_HURT, + JUMP, + BLIP_SELECT, +} + +const Base58 := preload("res://addons/gdfxr/Base58.gd") + +var wave_type: int = WaveType.SQUARE_WAVE + +var p_env_attack := 0.0 # Attack Time +var p_env_sustain := 0.3 # Sustain Time +var p_env_punch := 0.0 # Sustain Punch +var p_env_decay := 0.4 # Decay Time + +var p_base_freq := 0.3 # Start Frequency +var p_freq_limit := 0.0 # Min Frequency +var p_freq_ramp := 0.0 # Slide +var p_freq_dramp := 0.0 # Delta Slide +var p_vib_strength := 0.0 # Vibrato Depth +var p_vib_speed := 0.0 # Vibrato Speed + +var p_duty := 0.0 # Square Duty +var p_duty_ramp := 0.0 # Duty Sweep + +var p_arp_mod := 0.0 # Change Amount +var p_arp_speed := 0.0 # Change Speed + +var p_repeat_speed := 0.0 # Repeat Speed + +var p_pha_offset := 0.0 # Phaser Offset +var p_pha_ramp := 0.0 # Phaser Weep + +var p_lpf_freq := 1.0 # Lp Filter Cutoff +var p_lpf_ramp := 0.0 # Lp Filter Cutoff Sweep +var p_lpf_resonance := 0.0 # Lp Filter Resonance +var p_hpf_freq := 0.0 # Hp Filter Cutoff +var p_hpf_ramp := 0.0 # Hp Filter Cutoff Sweep + +var sound_vol := 0.5 + + +func load(path: String) -> int: # Error + var f := File.new() + var err := f.open(path, File.READ) + if err != OK: + return err + + var version := f.get_32() + if not [100, 101, 102].has(version): + return ERR_FILE_UNRECOGNIZED + + wave_type = f.get_32() + sound_vol = 0.5 + if version == 102: + sound_vol = f.get_float() + + p_base_freq = f.get_float() + p_freq_limit = f.get_float() + p_freq_ramp = f.get_float() + if version >= 101: + p_freq_dramp = f.get_float() + p_duty = f.get_float() + p_duty_ramp = f.get_float() + + p_vib_strength = f.get_float() + p_vib_speed = f.get_float() + f.get_float() # p_vib_delay + + p_env_attack = f.get_float() + p_env_sustain = f.get_float() + p_env_decay = f.get_float() + p_env_punch = f.get_float() + + f.get_8() # filter_on + p_lpf_resonance = f.get_float() + p_lpf_freq = f.get_float() + p_lpf_ramp = f.get_float() + p_hpf_freq = f.get_float() + p_hpf_ramp = f.get_float() + + p_pha_offset = f.get_float() + p_pha_ramp = f.get_float() + + p_repeat_speed = f.get_float() + + if version >= 101: + p_arp_speed = f.get_float() + p_arp_mod = f.get_float() + + return OK + + +func save(path: String) -> int: # Error + var f := File.new() + var err := f.open(path, File.WRITE) + if err != OK: + return err + + f.store_32(102) + f.store_32(wave_type) + f.store_float(sound_vol) + + f.store_float(p_base_freq) + f.store_float(p_freq_limit) + f.store_float(p_freq_ramp) + f.store_float(p_freq_dramp) + f.store_float(p_duty) + f.store_float(p_duty_ramp) + + f.store_float(p_vib_strength) + f.store_float(p_vib_speed) + f.store_float(0) # p_vib_delay + + f.store_float(p_env_attack) + f.store_float(p_env_sustain) + f.store_float(p_env_decay) + f.store_float(p_env_punch) + + f.store_8(true) # filter_on + f.store_float(p_lpf_resonance) + f.store_float(p_lpf_freq) + f.store_float(p_lpf_ramp) + f.store_float(p_hpf_freq) + f.store_float(p_hpf_ramp) + + f.store_float(p_pha_offset) + f.store_float(p_pha_ramp) + + f.store_float(p_repeat_speed) + + f.store_float(p_arp_speed) + f.store_float(p_arp_mod) + + return OK + + +func randomize_in_category(category: int) -> void: + reset() + + match category: + Category.PICKUP_COIN: + p_base_freq = rand_range(0.4, 0.9) + p_env_attack = 0.0 + p_env_sustain = rand_range(0.0, 0.1) + p_env_decay = rand_range(0.1, 0.5) + p_env_punch = rand_range(0.3, 0.6) + if randi() % 2: + p_arp_speed = rand_range(0.5, 0.7) + p_arp_mod = rand_range(0.2, 0.6) + + Category.LASER_SHOOT: + wave_type = randi() % 3 + if wave_type == 2 and randi() % 2: + wave_type = randi() % 2 + p_base_freq = rand_range(0.5, 1.0) + p_freq_limit = max(0.2, p_base_freq - rand_range(0.2, 0.8)) + p_freq_ramp = rand_range(-0.35, -0.15) + if randi() % 3 == 0: + p_base_freq = rand_range(0.3, 0.9) + p_freq_limit = rand_range(0, 0.1) + p_freq_ramp = rand_range(-0.65, -0.35) + if randi() % 2: + p_duty = rand_range(0, 0.5) + p_duty_ramp = rand_range(0, 0.2) + else: + p_duty = rand_range(0.4, 0.9) + p_duty_ramp = rand_range(-0.7, 0) + p_env_attack = 0.0 + p_env_sustain = rand_range(0.1, 0.3) + p_env_decay = rand_range(0.0, 0.4) + if randi() % 2: + p_env_punch = rand_range(0, 0.3) + if randi() % 3 == 0: + p_pha_offset = rand_range(0, 0.2) + p_pha_ramp = rand_range(0, 0.2) + if randi() % 2: + p_hpf_freq = rand_range(0, 0.3) + + Category.EXPLOSION: + wave_type = WaveType.NOISE + if randi() % 2: + p_base_freq = rand_range(0.1, 0.4) + p_freq_ramp = rand_range(-0.1, 0.3) + else: + p_base_freq = rand_range(0.2, 0.9) + p_freq_ramp = rand_range(-0.4, -0.2) + p_base_freq *= p_base_freq + if randi() % 5 == 0: + p_freq_ramp = 0.0 + if randi() % 3 == 0: + p_repeat_speed = rand_range(0.3, 0.8) + p_env_attack = 0.0 + p_env_sustain = rand_range(0.1, 0.4) + p_env_decay = rand_range(0, 0.5) + if randi() % 2: + p_pha_offset = rand_range(-0.3, 0.6) + p_pha_ramp = rand_range(-0.3, 0) + p_env_punch = rand_range(0.2, 0.8) + if randi() % 2: + p_vib_strength = rand_range(0, 0.7) + p_vib_speed = rand_range(0, 0.6) + if randi() % 3: + p_arp_speed = rand_range(0.6, 0.9) + p_arp_mod = rand_range(-0.8, 0.8) + + Category.POWERUP: + if randi() % 2: + wave_type = WaveType.SAWTOOTH + else: + p_duty = rand_range(0, 0.6) + if randi() % 2: + p_base_freq = rand_range(0.2, 0.5) + p_freq_ramp = rand_range(0.1, 0.5) + p_repeat_speed = rand_range(0.4, 0.8) + else: + p_base_freq = rand_range(0.2, 0.5) + p_freq_ramp = rand_range(0.05, 0.25) + if randi() % 2: + p_vib_strength = rand_range(0, 0.7) + p_vib_speed = rand_range(0, 0.6) + p_env_attack = 0.0 + p_env_sustain = rand_range(0, 0.4) + p_env_decay = rand_range(0.1, 0.5) + + Category.HIT_HURT: + wave_type = randi() % 3 + match wave_type: + WaveType.SINE_WAVE: + wave_type = WaveType.NOISE + WaveType.SQUARE_WAVE: + p_duty = rand_range(0, 0.6) + p_base_freq = rand_range(0.2, 0.8) + p_freq_ramp = rand_range(-0.7, -0.3) + p_env_attack = 0.0 + p_env_sustain = rand_range(0, 0.1) + p_env_decay = rand_range(0.1, 0.3) + if randi() % 2: + p_hpf_freq = rand_range(0, 0.3) + + Category.JUMP: + wave_type = WaveType.SQUARE_WAVE + p_duty = rand_range(0, 0.6) + p_base_freq = rand_range(0.3, 0.6) + p_freq_ramp = rand_range(0.1, 0.3) + p_env_attack = 0.0 + p_env_sustain = rand_range(0.1, 0.4) + p_env_decay = rand_range(0.1, 0.3) + if randi() % 2: + p_hpf_freq = rand_range(0, 0.3) + if randi() % 2: + p_lpf_freq = rand_range(0.4, 1.0) + + Category.BLIP_SELECT: + wave_type = randi() % 2 + if wave_type == WaveType.SQUARE_WAVE: + p_duty = rand_range(0, 0.6) + p_base_freq = rand_range(0.2, 0.6) + p_env_attack = 0.0 + p_env_sustain = rand_range(0.1, 0.2) + p_env_decay = rand_range(0, 0.2) + p_hpf_freq = 0.1 + + +func randomize() -> void: + p_base_freq = pow(rand_range(-1.0, +1.0), 2.0) + if randi() % 2: + p_base_freq = pow(rand_range(-1.0, +1.0), 3.0) + 0.5 + p_freq_limit = 0.0 + p_freq_ramp = pow(rand_range(-1.0, +1.0), 5.0) + if p_base_freq > 0.7 and p_freq_ramp > 0.2: + p_freq_ramp = -p_freq_ramp + if p_base_freq < 0.2 and p_freq_ramp < -0.05: + p_freq_ramp = -p_freq_ramp + p_freq_dramp = pow(rand_range(-1.0, +1.0), 3.0) + p_duty = rand_range(-1.0, +1.0) + p_duty_ramp = pow(rand_range(-1.0, +1.0), 3.0) + p_vib_strength = pow(rand_range(-1.0, +1.0), 3.0) + p_vib_speed = rand_range(-1.0, +1.0) + # p_vib_delay = rand_range(-1.0, +1.0) + p_env_attack = pow(rand_range(-1.0, +1.0), 3.0) + p_env_sustain = pow(rand_range(-1.0, +1.0), 2.0) + p_env_decay = rand_range(-1.0, +1.0) + p_env_punch = pow(rand_range(0, 0.8), 2.0) + if p_env_attack + p_env_sustain + p_env_decay < 0.2: + p_env_sustain += rand_range(0.2, 0.5) + p_env_decay += rand_range(0.2, 0.5) + p_lpf_resonance = rand_range(-1.0, +1.0) + p_lpf_freq = 1.0 - pow(randf(), 3.0) + p_lpf_ramp = pow(rand_range(-1.0, +1.0), 3.0) + if p_lpf_freq < 0.1 and p_lpf_ramp < -0.05: + p_lpf_ramp = -p_lpf_ramp + p_hpf_freq = pow(randf(), 5.0) + p_hpf_ramp = pow(rand_range(-1.0, +1.0), 5.0) + p_pha_offset = pow(rand_range(-1.0, +1.0), 3.0) + p_pha_ramp = pow(rand_range(-1.0, +1.0), 3.0) + p_repeat_speed = rand_range(-1.0, +1.0) + p_arp_speed = rand_range(-1.0, +1.0) + p_arp_mod = rand_range(-1.0, +1.0) + + +func mutate() -> void: + if randi() % 2: + p_base_freq += rand_range(-0.05, +0.05) + if randi() % 2: + p_freq_limit += rand_range(-0.05, +0.05) + if randi() % 2: + p_freq_ramp += rand_range(-0.05, +0.05) + if randi() % 2: + p_freq_dramp += rand_range(-0.05, +0.05) + if randi() % 2: + p_duty += rand_range(-0.05, +0.05) + if randi() % 2: + p_duty_ramp += rand_range(-0.05, +0.05) + if randi() % 2: + p_vib_strength += rand_range(-0.05, +0.05) + if randi() % 2: + p_vib_speed += rand_range(-0.05, +0.05) +# if randi() % 2: +# p_vib_delay += rand_range(-0.05, +0.05) + if randi() % 2: + p_env_attack += rand_range(-0.05, +0.05) + if randi() % 2: + p_env_sustain += rand_range(-0.05, +0.05) + if randi() % 2: + p_env_decay += rand_range(-0.05, +0.05) + if randi() % 2: + p_env_punch += rand_range(-0.05, +0.05) + if randi() % 2: + p_lpf_resonance += rand_range(-0.05, +0.05) + if randi() % 2: + p_lpf_freq += rand_range(-0.05, +0.05) + if randi() % 2: + p_lpf_ramp += rand_range(-0.05, +0.05) + if randi() % 2: + p_hpf_freq += rand_range(-0.05, +0.05) + if randi() % 2: + p_hpf_ramp += rand_range(-0.05, +0.05) + if randi() % 2: + p_pha_offset += rand_range(-0.05, +0.05) + if randi() % 2: + p_pha_ramp += rand_range(-0.05, +0.05) + if randi() % 2: + p_repeat_speed += rand_range(-0.05, +0.05) + if randi() % 2: + p_arp_speed += rand_range(-0.05, +0.05) + if randi() % 2: + p_arp_mod += rand_range(-0.05, +0.05) + + +func reset(): + wave_type = WaveType.SQUARE_WAVE + + p_base_freq = 0.3 + p_freq_limit = 0.0 + p_freq_ramp = 0.0 + p_freq_dramp = 0.0 + p_duty = 0.0 + p_duty_ramp = 0.0 + + p_vib_strength = 0.0 + p_vib_speed = 0.0 + # p_vib_delay = 0.0 + + p_env_attack = 0.0 + p_env_sustain = 0.3 + p_env_decay = 0.4 + p_env_punch = 0.0 + + # filter_on = false + p_lpf_resonance = 0.0 + p_lpf_freq = 1.0 + p_lpf_ramp = 0.0 + p_hpf_freq = 0.0 + p_hpf_ramp = 0.0 + + p_pha_offset = 0.0 + p_pha_ramp = 0.0 + + p_repeat_speed = 0.0 + + p_arp_speed = 0.0 + p_arp_mod = 0.0 + + +func copy_from(other: Reference) -> void: # SFXRConfig + wave_type = other.wave_type + + p_env_attack = other.p_env_attack + p_env_sustain = other.p_env_sustain + p_env_punch = other.p_env_punch + p_env_decay = other.p_env_decay + + p_base_freq = other.p_base_freq + p_freq_limit = other.p_freq_limit + p_freq_ramp = other.p_freq_ramp + p_freq_dramp = other.p_freq_dramp + p_vib_strength = other.p_vib_strength + p_vib_speed = other.p_vib_speed + + p_duty = other.p_duty + p_duty_ramp = other.p_duty_ramp + + p_arp_mod = other.p_arp_mod + p_arp_speed = other.p_arp_speed + + p_repeat_speed = other.p_repeat_speed + + p_pha_offset = other.p_pha_offset + p_pha_ramp = other.p_pha_ramp + + p_lpf_freq = other.p_lpf_freq + p_lpf_ramp = other.p_lpf_ramp + p_lpf_resonance = other.p_lpf_resonance + p_hpf_freq = other.p_hpf_freq + p_hpf_ramp = other.p_hpf_ramp + + sound_vol = other.sound_vol + + +func is_equal(other: Reference) -> bool: # SFXRConfig + return ( + wave_type == other.wave_type + + and p_env_attack == other.p_env_attack + and p_env_sustain == other.p_env_sustain + and p_env_punch == other.p_env_punch + and p_env_decay == other.p_env_decay + + and p_base_freq == other.p_base_freq + and p_freq_limit == other.p_freq_limit + and p_freq_ramp == other.p_freq_ramp + and p_freq_dramp == other.p_freq_dramp + and p_vib_strength == other.p_vib_strength + and p_vib_speed == other.p_vib_speed + + and p_duty == other.p_duty + and p_duty_ramp == other.p_duty_ramp + + and p_arp_mod == other.p_arp_mod + and p_arp_speed == other.p_arp_speed + + and p_repeat_speed == other.p_repeat_speed + + and p_pha_offset == other.p_pha_offset + and p_pha_ramp == other.p_pha_ramp + + and p_lpf_freq == other.p_lpf_freq + and p_lpf_ramp == other.p_lpf_ramp + and p_lpf_resonance == other.p_lpf_resonance + and p_hpf_freq == other.p_hpf_freq + and p_hpf_ramp == other.p_hpf_ramp + + and sound_vol == other.sound_vol + ) + + +# Load base58 string copied from jsfxr +# See https://github.com/chr15m/jsfxr/blob/a708164e6ce200008d88202e1aaf2b9171a17ec2/sfxr.js#L132-L175 +func load_from_base58(v: String) -> int: # Error + var buffer := Base58.b58decode(v) + if not buffer: + return ERR_INVALID_DATA + if buffer.get_size() != 89: + return ERR_INVALID_DATA + + var params_order = [ + "p_env_attack", + "p_env_sustain", + "p_env_punch", + "p_env_decay", + "p_base_freq", + "p_freq_limit", + "p_freq_ramp", + "p_freq_dramp", + "p_vib_strength", + "p_vib_speed", + "p_arp_mod", + "p_arp_speed", + "p_duty", + "p_duty_ramp", + "p_repeat_speed", + "p_pha_offset", + "p_pha_ramp", + "p_lpf_freq", + "p_lpf_ramp", + "p_lpf_resonance", + "p_hpf_freq", + "p_hpf_ramp", + ] + + wave_type = buffer.get_8() + + for param in params_order: + set(param, buffer.get_float()) + + return OK diff --git a/addons/gdfxr/SFXRGenerator.gd b/addons/gdfxr/SFXRGenerator.gd new file mode 100644 index 0000000..111edc0 --- /dev/null +++ b/addons/gdfxr/SFXRGenerator.gd @@ -0,0 +1,274 @@ +# GDScript port of the original SFXR +# https://www.drpetter.se/project_sfxr.html + +const SFXRConfig := preload("SFXRConfig.gd") + +const master_vol := 0.05 + +enum WavBits { + WAV_BITS_8, + WAV_BITS_16, +} +enum WavFreq { + WAV_FREQ_44100, + WAV_FREQ_22050, +} + +var _config: SFXRConfig + +var rep_time: int +var rep_limit: int +var arp_time: int +var arp_limit: int +var arp_mod: float +var period: int +var fperiod: float +var fmaxperiod: float +var fslide: float +var fdslide: float +var vib_amp: float +var vib_phase: float +var vib_speed: float +var square_duty: float +var square_slide: float +var env_vol: float +var env_length := PoolIntArray([0, 0, 0]) +var phase: int +var fphase: float +var fdphase: float +var iphase: int +var flthp: float +var flthp_d: float +var noise_buffer := PoolRealArray([]) +var phaser_buffer := PoolRealArray([]) +var ipp: int +var fltp: float +var fltdp: float +var fltw: float +var fltw_d: float +var fltdmp: float +var fltphp: float + + +func generate_audio_stream( + config: SFXRConfig, + wav_bits: int = WavBits.WAV_BITS_8, + wav_freq: int = WavFreq.WAV_FREQ_44100 +) -> AudioStreamSample: + var stream := AudioStreamSample.new() + stream.format = AudioStreamSample.FORMAT_8_BITS if wav_bits == WavBits.WAV_BITS_8 else AudioStreamSample.FORMAT_16_BITS + stream.mix_rate = 44100 if wav_freq == WavFreq.WAV_FREQ_44100 else 22050 + + _config = config + stream.data = _generate_samples(wav_bits, wav_freq).data_array + _config = null + + return stream + + +func generate_samples( + config: SFXRConfig, + wav_bits: int = WavBits.WAV_BITS_8, + wav_freq: int = WavFreq.WAV_FREQ_44100 +) -> PoolByteArray: + _config = config + var data := _generate_samples(wav_bits, wav_freq).data_array + _config = null + return data + + +func _generate_samples(wav_bits: int, wav_freq: int) -> StreamPeerBuffer: + _reset_sample(true) + + var playing_sample := true + var env_stage := 0 + var env_time := 0 + var filesample: float = 0 + var fileacc := 0 + var buffer := StreamPeerBuffer.new() + + # SynthSample + while playing_sample: + rep_time += 1 + if rep_limit != 0 and rep_time >= rep_limit: + rep_time = 0 + _reset_sample(false) + + # frequency envelopes/arpeggios + arp_time += 1 + if arp_limit != 0 and arp_time >= arp_limit: + arp_limit = 0 + fperiod *= arp_mod + fslide += fdslide + fperiod *= fslide + if fperiod > fmaxperiod: + fperiod = fmaxperiod + if _config.p_freq_limit > 0: + playing_sample = false + var rfperiod := fperiod + if vib_amp > 0.0: + vib_phase += vib_speed + rfperiod = fperiod * (1.0 + sin(vib_phase) * vib_amp) + period = int(max(8, rfperiod)) + square_duty = clamp(square_duty + square_slide, 0.0, 0.5) + + # volume envelope + env_time += 1 # Note: this skips 0 of env_stage 0. Seems problematic. + if env_time > env_length[env_stage]: + env_time = 0 + + while true: + env_stage += 1 + if env_stage == 3: + playing_sample = false + break + if env_length[env_stage] != 0: + break + + match env_stage: + 0: + env_vol = float(env_time) / env_length[0] + 1: + env_vol = 1.0 + pow(1.0 - float(env_time) / env_length[1], 1.0) * 2.0 * _config.p_env_punch + 2: + env_vol = 1.0 - float(env_time) / env_length[2] + + # phaser step + fphase += fdphase + iphase = int(min(abs(fphase), 1023)) + + if flthp_d != 0.0: + flthp = clamp(flthp * flthp_d, 0.00001, 0.1) + + var ssample := 0.0 + for si in 8: # 8x supersampling + var sample := 0.0 + phase += 1 + if phase >= period: + phase %= period + if _config.wave_type == SFXRConfig.WaveType.NOISE: + for j in 32: + noise_buffer[j] = rand_range(-1.0, +1.0) + + # base waveform + var fp := float(phase) / period + match _config.wave_type: + SFXRConfig.WaveType.SQUARE_WAVE: + sample = 0.5 if fp < square_duty else -0.5 + SFXRConfig.WaveType.SAWTOOTH: + sample = 1.0 - fp * 2 + SFXRConfig.WaveType.SINE_WAVE: + sample = sin(fp * 2 * PI) + SFXRConfig.WaveType.NOISE: + sample = noise_buffer[phase * 32 / period] + + # lp filter + var pp := fltp + fltw = clamp(fltw * fltw_d, 0.0, 0.1) + if _config.p_lpf_freq == 1.0: + fltp = sample + fltdp = 0.0 + else: + fltdp += (sample - fltp) * fltw + fltdp -= fltdp * fltdmp + fltp += fltdp + + # hp filter + fltphp += fltp - pp + fltphp -= fltphp * flthp + sample = fltphp + + # phaser + phaser_buffer[ipp & 1023] = sample + sample += phaser_buffer[(ipp - iphase + 1024) & 1023] + ipp = (ipp + 1) & 1023 + + # final accumulation and envelope application + ssample += sample * env_vol + + ssample = ssample / 8 * master_vol + + ssample *= 2.0 * _config.sound_vol + + ssample *= 4.0 # arbitrary gain to get reasonable output volume... + ssample = clamp(ssample, -1.0, +1.0) + + filesample += ssample + fileacc += 1 + + if wav_freq == WavFreq.WAV_FREQ_44100 or fileacc == 2: + filesample /= fileacc + fileacc = 0 + + if wav_bits == WavBits.WAV_BITS_8: + buffer.put_8(filesample * 255) + else: + buffer.put_16(filesample * 32000) + + filesample = 0 + + return buffer + + +func _reset_sample(restart: bool) -> void: + fperiod = 100.0 / (_config.p_base_freq * _config.p_base_freq + 0.001) + period = int(fperiod) + fmaxperiod = 100.0 / (_config.p_freq_limit * _config.p_freq_limit + 0.001) + fslide = 1.0 - pow(_config.p_freq_ramp, 3.0) * 0.01 + fdslide = -pow(_config.p_freq_dramp, 3.0) * 0.000001 + square_duty = 0.5 - _config.p_duty * 0.5 + square_slide = -_config.p_duty_ramp * 0.00005 + if _config.p_arp_mod >= 0.0: + arp_mod = 1.0 - pow(_config.p_arp_mod, 2.0) * 0.9 + else: + arp_mod = 1.0 + pow(_config.p_arp_mod, 2.0) * 10.0 + arp_time = 0 + arp_limit = int(pow(1.0 - _config.p_arp_speed, 2.0) * 20000 + 32) + if _config.p_arp_speed == 1.0: + arp_limit = 0 + + if restart: + phase = 0 + + # Reset filter. + fltp = 0.0 + fltdp = 0.0 + fltw = pow(_config.p_lpf_freq, 3.0) * 0.1 + fltw_d = 1.0 + _config.p_lpf_ramp * 0.0001 + fltdmp = min(5.0 / (1.0 + pow(_config.p_lpf_resonance, 2.0) * 20.0) * (0.01 + fltw), 0.8) + fltphp = 0.0 + flthp = pow(_config.p_hpf_freq, 2.0) * 0.1 + flthp_d = 1.0 + _config.p_hpf_ramp * 0.0003 + + # Reset vibrato + vib_phase = 0.0 + vib_speed = pow(_config.p_vib_speed, 2.0) * 0.01 + vib_amp = _config.p_vib_strength * 0.5 + + # Reset envelope + env_vol = 0.0 + env_length[0] = int(_config.p_env_attack * _config.p_env_attack * 100000.0) + env_length[1] = int(_config.p_env_sustain * _config.p_env_sustain * 100000.0) + env_length[2] = int(_config.p_env_decay * _config.p_env_decay * 100000.0) + + fphase = pow(_config.p_pha_offset, 2.0) * 1020.0 + if _config.p_pha_offset < 0.0: + fphase = -fphase + fdphase = pow(_config.p_pha_ramp, 2.0) * 1.0 + if _config.p_pha_ramp < 0.0: + fdphase = -fdphase + iphase = int(abs(fphase)) + ipp = 0 + + phaser_buffer.resize(1024) + for i in phaser_buffer.size(): + phaser_buffer[i] = 0.0 + + noise_buffer.resize(32) + for i in noise_buffer.size(): + noise_buffer[i] = rand_range(-1.0, +1.0) + + rep_time = 0 + rep_limit = int(pow(1.0 - _config.p_repeat_speed, 2.0) * 20000 + 32) + if _config.p_repeat_speed == 0.0: + rep_limit = 0 diff --git a/addons/gdfxr/editor/EditSlider.gd b/addons/gdfxr/editor/EditSlider.gd new file mode 100644 index 0000000..217a900 --- /dev/null +++ b/addons/gdfxr/editor/EditSlider.gd @@ -0,0 +1,203 @@ +tool +extends Control + +signal value_changed(value) + +export var value: float = 0.0 setget set_value +export var min_value: float = 0.0 +export var max_value: float = 1.0 + +var _line_edit: LineEdit + +var _stylebox_normal: StyleBox +var _stylebox_hover: StyleBox +var _stylebox_editing: StyleBox +var _stylebox_value: StyleBox + +var _line_edit_just_closed := false +var _mouse_hovering := false +var _is_editing := false + +var _drag_start_position: Vector2 +var _drag_cancelled := true +var _drag_dist := 0.0 +var _drag_start_factor: float + + +func _init() -> void: + mouse_default_cursor_shape = Control.CURSOR_HSIZE + rect_clip_content = true + focus_mode = Control.FOCUS_ALL + + var style := StyleBoxEmpty.new() + style.content_margin_left = 8 + style.content_margin_right = 8 + + _line_edit = LineEdit.new() + _line_edit.set_as_toplevel(true) + _line_edit.visible = false + _line_edit.add_stylebox_override("normal", style) + _line_edit.add_stylebox_override("focus", StyleBoxEmpty.new()) + + var _ret: int + _ret = _line_edit.connect("focus_exited", self, "_on_line_edit_focus_exited") + _ret = _line_edit.connect("text_entered", self, "_on_line_edit_text_entered") + _ret = _line_edit.connect("visibility_changed", self, "_on_line_edit_visibility_changed") + + add_child(_line_edit) + + +func _draw() -> void: + var font := get_font("font", "LineEdit") + var color := get_color("highlighted_font_color" if _mouse_hovering else "font_color", "Editor") + var number_string := "%.3f" % value + var number_size := font.get_string_size(number_string) + var pos := Vector2( + (rect_size.x - number_size.x) / 2, + (rect_size.y - number_size.y) / 2 + font.get_ascent() + ) + + var stylebox := _stylebox_editing if _is_editing else _stylebox_hover if _mouse_hovering else _stylebox_normal + + if _line_edit.visible: + draw_style_box(stylebox, Rect2(Vector2.ZERO, rect_size)) + else: + var value_width := rect_size.x * ((value - min_value) / (max_value - min_value)) + draw_style_box(stylebox, Rect2(value_width, 0, rect_size.x - value_width, rect_size.y)) + draw_style_box(_stylebox_value, Rect2(0, 0, value_width, rect_size.y)) + draw_string(font, pos, number_string, color) + + +func _get_minimum_size() -> Vector2: + var ms := _stylebox_normal.get_minimum_size() + ms.y += get_font("font", "LineEdit").get_height() + return ms + + +func _gui_input(event: InputEvent) -> void: + var mb := event as InputEventMouseButton + if mb and mb.button_index == BUTTON_LEFT: + if mb.pressed: + _drag_prepare(mb) + else: + _drag_done() + if _drag_cancelled: + _show_text_edit() + _drag_cancelled = true + _is_editing = mb.pressed + update() + + var mm := event as InputEventMouseMotion + if mm and mm.button_mask & BUTTON_MASK_LEFT: + _drag_motion(mm) + _drag_cancelled = false + + +func _notification(what: int) -> void: + match what: + NOTIFICATION_ENTER_TREE, NOTIFICATION_THEME_CHANGED: + _update_stylebox() + + NOTIFICATION_MOUSE_ENTER: + _mouse_hovering = true + update() + + NOTIFICATION_MOUSE_EXIT: + _mouse_hovering = false + update() + + NOTIFICATION_FOCUS_ENTER: + if (Input.is_action_pressed("ui_focus_next") or Input.is_action_pressed("ui_focus_prev")) and not _line_edit_just_closed: + _show_text_edit() + _line_edit_just_closed = false + + +func set_value(v: float) -> void: + if is_equal_approx(v, value): + return + value = v + emit_signal("value_changed", value) + update() + + +func _update_stylebox() -> void: + _stylebox_normal = get_stylebox("normal", "LineEdit") + _stylebox_hover = StyleBoxFlat.new() + _stylebox_hover.bg_color = get_color("highlight_color", "Editor") + _stylebox_editing = StyleBoxFlat.new() + _stylebox_editing.bg_color = get_color("dark_color_2", "Editor") + _stylebox_value = StyleBoxFlat.new() + _stylebox_value.bg_color = get_color("accent_color", "Editor") * Color(1, 1, 1, 0.4) + + +func _drag_prepare(mouse: InputEventMouse) -> void: + _drag_dist = 0.0 + _drag_start_factor = (value - min_value) / (max_value - min_value) + _drag_start_position = mouse.global_position + Input.mouse_mode = Input.MOUSE_MODE_CAPTURED + + +func _drag_done() -> void: + Input.mouse_mode = Input.MOUSE_MODE_VISIBLE + + if _drag_cancelled: + Input.warp_mouse_position(_drag_start_position) + else: + Input.warp_mouse_position(rect_global_position + rect_size * Vector2( + (value - min_value) / (max_value - min_value), + 0.5 + )) + + +func _drag_motion(motion: InputEventMouseMotion) -> void: + _drag_dist += motion.relative.x + + var factor := _drag_start_factor + _drag_dist / rect_size.x + if factor < 0 or 1 < factor: + factor = clamp(factor, 0, 1) + _drag_dist = (factor - _drag_start_factor) * rect_size.x + + var v := factor * (max_value - min_value) + min_value + var snap := motion.command or motion.shift + if snap and not (is_equal_approx(v, min_value) or is_equal_approx(v, max_value)): + if motion.shift and motion.command: + v = round(v * 1000.0) * 0.001 + elif motion.shift: + v = round(v * 100.0) * 0.01 + else: + v = round(v * 10.0) * 0.1 + + set_value(clamp(v, min_value, max_value)) + + update() + + +func _show_text_edit() -> void: + var gr := get_global_rect() + _line_edit.text = str(value) + _line_edit.set_position(gr.position) + _line_edit.set_size(gr.size) + _line_edit.show_modal() + _line_edit.select_all() + _line_edit.grab_focus() + _line_edit.focus_next = find_next_valid_focus().get_path() + _line_edit.focus_previous = find_prev_valid_focus().get_path() + + +func _on_line_edit_focus_exited(): + if _line_edit.get_menu().visible: + return + if _line_edit.text.is_valid_float(): + set_value(clamp(_line_edit.text.to_float(), min_value, max_value)) + if not _line_edit_just_closed: + _line_edit.hide() + update() + + +func _on_line_edit_text_entered(_text: String): + _line_edit.hide() + + +func _on_line_edit_visibility_changed(): + if not _line_edit.visible: + _line_edit_just_closed = true diff --git a/addons/gdfxr/editor/Editor.gd b/addons/gdfxr/editor/Editor.gd new file mode 100644 index 0000000..b6028d3 --- /dev/null +++ b/addons/gdfxr/editor/Editor.gd @@ -0,0 +1,387 @@ +tool +extends Container + +enum ExtraOption { SAVE_AS, COPY, PASTE, PASTE_JSFXR, RECENT } +enum DefaultFilename { EMPTY, GUESS_FOR_SAVE } + +const SFXRConfig := preload("../SFXRConfig.gd") +const SFXRGenerator := preload("../SFXRGenerator.gd") +const Base58 := preload("../Base58.gd") +const NUM_RECENTS := 4 + +class RecentEntry: + var title: String + var config := SFXRConfig.new() + +var plugin: EditorPlugin + +var _config := SFXRConfig.new() +var _config_defaults := SFXRConfig.new() +var _config_clipboard: SFXRConfig +var _config_recents: Array +var _recents_id := 0 +var _generator := SFXRGenerator.new() +var _path: String +var _modified := false +var _param_map := {} +var _syncing_ui := false # a hack since Range set_value emits value_changed +var _category_names := {} + +onready var audio_player := $AudioStreamPlayer as AudioStreamPlayer +onready var filename_label := find_node("Filename") as Label +onready var save_button := find_node("Save") as Button +onready var restore_button := find_node("Restore") as Button +onready var extra_button := find_node("Extra") as MenuButton +onready var version_button := find_node("VersionButton") +onready var translator := $PluginTranslator + + +func _ready(): + if not plugin: + return # Running in the edited scene instead of from Plugin + + for child in get_children(): + _hook_plugin(child) + + var popup := extra_button.get_popup() + popup.add_item(translator.tr("Save As..."), ExtraOption.SAVE_AS) + popup.add_separator() + popup.add_item(translator.tr("Copy"), ExtraOption.COPY) + popup.add_item(translator.tr("Paste"), ExtraOption.PASTE) + popup.add_item(translator.tr("Paste from jsfxr"), ExtraOption.PASTE_JSFXR) + popup.add_separator(translator.tr("Recently Generated")) + popup.connect("id_pressed", self, "_on_Extra_id_pressed") + + _category_names = { + SFXRConfig.Category.PICKUP_COIN: translator.tr("Pickup/Coin"), + SFXRConfig.Category.LASER_SHOOT: translator.tr("Laser/Shoot"), + SFXRConfig.Category.EXPLOSION: translator.tr("Explosion"), + SFXRConfig.Category.POWERUP: translator.tr("Powerup"), + SFXRConfig.Category.HIT_HURT: translator.tr("Hit/Hurt"), + SFXRConfig.Category.JUMP: translator.tr("Jump"), + SFXRConfig.Category.BLIP_SELECT: translator.tr("Blip/Select"), + } + + var params := find_node("Params") as Container + for category in params.get_children(): + for control in category.get_children(): + _param_map[control.parameter] = control + control.connect("param_changed", self, "_on_param_changed") + control.connect("param_reset", self, "_on_param_reset") + + _set_editing_file("") + + +func _notification(what: int): + if not plugin: + return # Running in the edited scene instead of from Plugin + + match what: + NOTIFICATION_ENTER_TREE, NOTIFICATION_THEME_CHANGED: + find_node("ScrollContainer").add_stylebox_override("bg", get_stylebox("bg", "Tree")) + + if extra_button: + var popup = extra_button.get_popup() + popup.set_item_icon(popup.get_item_index(ExtraOption.COPY), get_icon("ActionCopy", "EditorIcons")) + popup.set_item_icon(popup.get_item_index(ExtraOption.PASTE), get_icon("ActionPaste", "EditorIcons")) + + +func edit(path: String) -> void: + if _modified: + _popup_confirm( + translator.tr("There are unsaved changes.\nOpen '%s' anyway?") % path, + "_set_editing_file", [path] + ) + else: + _set_editing_file(path) + + +func _hook_plugin(node: Node) -> void: + if "plugin" in node: + node.plugin = plugin + for child in node.get_children(): + _hook_plugin(child) + + +func _push_recent(title: String) -> void: + var recent: RecentEntry + if _config_recents.size() < NUM_RECENTS: + recent = RecentEntry.new() + else: + recent = _config_recents.pop_back() + + _recents_id += 1 + recent.title = "#%d %s" % [_recents_id, title] + recent.config.copy_from(_config) + + _config_recents.push_front(recent) + + +func _popup_confirm(content: String, callback: String, binds := []) -> void: + var dialog := ConfirmationDialog.new() + add_child(dialog) + dialog.dialog_text = content + dialog.window_title = translator.tr("SFXR Editor") + dialog.connect("confirmed", self, callback, binds) + dialog.connect("popup_hide", dialog, "queue_free") + dialog.popup_centered() + + +func _popup_message(content: String) -> void: + var dialog := AcceptDialog.new() + add_child(dialog) + dialog.dialog_text = content + dialog.window_title = translator.tr("SFXR Editor") + dialog.connect("popup_hide", dialog, "queue_free") + dialog.popup_centered() + + +func _popup_file_dialog(mode: int, callback: String, default_filename: int = DefaultFilename.EMPTY) -> void: + var dialog := EditorFileDialog.new() + add_child(dialog) + dialog.access = EditorFileDialog.ACCESS_RESOURCES + dialog.mode = mode + + match default_filename: + DefaultFilename.EMPTY: + pass + + DefaultFilename.GUESS_FOR_SAVE: + if _path: + dialog.current_path = _generate_serial_path(_path) + + dialog.add_filter("*.sfxr; %s" % translator.tr("SFXR Audio")) + dialog.connect("popup_hide", dialog, "queue_free") + dialog.connect("file_selected", self, callback) + dialog.popup_centered_ratio() + + +func _reset_defaults() -> void: + _config_defaults.copy_from(_config) + _set_modified(false) + _sync_ui() + + +func _restore_from_config(config: SFXRConfig) -> void: + _config.copy_from(config) + _sync_ui() + _set_modified(not config.is_equal(_config_defaults)) + audio_player.stream = null + + +func _set_editing_file(path: String) -> int: # Error + if path.empty(): + _config.reset() + audio_player.stream = null + else: + var err := _config.load(path) + if err != OK: + _popup_message(translator.tr("'%s' is not a valid SFXR file.") % path) + return err + audio_player.stream = load(path) + + _path = path + _reset_defaults() + return OK + + +func _set_modified(value: bool) -> void: + _modified = value + + var has_file := not _path.empty() + var base = _path if has_file else translator.tr("Unsaved sound") + if _modified: + base += "(*)" + filename_label.text = base + restore_button.disabled = not _modified + save_button.disabled = has_file and not _modified + + +func _sync_ui() -> void: + _syncing_ui = true + for name in _param_map: + var control = _param_map[name] + var value = _config.get(name) + control.set_value(value) + control.set_resetable(value != _config_defaults.get(name)) + _syncing_ui = false + + +func _generate_serial_path(path: String) -> String: + var directory := Directory.new() + if directory.open(path.get_base_dir()) != OK: + return path + + if not directory.file_exists(path.get_file()): + return path + + var basename := path.get_basename() + var extension := path.get_extension() + + # Extract trailing number. + var num_string: String + for i in range(basename.length() - 1, -1, -1): + var c: String = basename[i] + if "0" <= c and c <= "9": + num_string = c + num_string + else: + break + var number := num_string.to_int() if num_string else 0 + var name_string: String = basename.substr(0, basename.length() - num_string.length()) + + while true: + number += 1 + var attemp := "%s%d.%s" % [name_string, number, extension] + if not directory.file_exists(attemp): + return attemp + + return path # Unreachable + + +func _on_param_changed(name, value): + if _syncing_ui: + return + + _config.set(name, value) + + _param_map[name].set_resetable(value != _config_defaults.get(name)) + + _set_modified(not _config.is_equal(_config_defaults)) + audio_player.stream = null + + +func _on_param_reset(name): + var value = _config_defaults.get(name) + _config.set(name, value) + + _syncing_ui = true + var control = _param_map[name] + control.set_value(value) + control.set_resetable(false) + _syncing_ui = false + + _set_modified(not _config.is_equal(_config_defaults)) + audio_player.stream = null + + +func _on_Play_pressed(force_regenerate := false): + if force_regenerate or audio_player.stream == null: + audio_player.stream = _generator.generate_audio_stream(_config) + audio_player.play() + + +func _on_Randomize_pressed(category: int): + if category == -1: + _config.randomize() + _push_recent(translator.tr("Randomize")) + else: + _config.randomize_in_category(category) + _push_recent(_category_names.get(category, "Unknown")) + + _set_modified(true) + _sync_ui() + _on_Play_pressed(true) + + +func _on_Mutate_pressed(): + _config.mutate() + + _push_recent(translator.tr("Mutate")) + _set_modified(true) + _sync_ui() + _on_Play_pressed(true) + + +func _on_Restore_pressed(): + _set_editing_file(_path) + + +func _on_New_pressed(): + if _modified: + _popup_confirm( + translator.tr("There are unsaved changes.\nCreate a new one anyway?"), + "_on_New_confirmed" + ) + else: + _on_New_confirmed() + + +func _on_New_confirmed() -> void: + _set_editing_file("") + + +func _on_Save_pressed(): + if _path.empty(): + _popup_file_dialog(EditorFileDialog.MODE_SAVE_FILE, "_on_SaveAsDialog_confirmed") + else: + _config.save(_path) + plugin.get_editor_interface().get_resource_filesystem().scan_sources() + _reset_defaults() + + +func _on_SaveAsDialog_confirmed(path: String): + _path = path + _config.save(path) + plugin.get_editor_interface().get_resource_filesystem().scan() + _reset_defaults() + + +func _on_Load_pressed(): + if _modified: + _popup_confirm( + translator.tr("There are unsaved changes.\nLoad anyway?"), + "_popup_file_dialog", [EditorFileDialog.MODE_OPEN_FILE, "_set_editing_file"] + ) + else: + _popup_file_dialog(EditorFileDialog.MODE_OPEN_FILE, "_set_editing_file") + + +func _on_Extra_about_to_show(): + var popup := extra_button.get_popup() + popup.set_item_disabled(popup.get_item_index(ExtraOption.PASTE), _config_clipboard == null) + popup.set_item_disabled(popup.get_item_index(ExtraOption.PASTE_JSFXR), not OS.has_clipboard()) + + # Rebuild recents menu everytime :) + var first_recent_index := popup.get_item_index(ExtraOption.RECENT) + if first_recent_index != -1: + var count := popup.get_item_count() + for i in count - first_recent_index: + popup.remove_item(count - 1 - i) + + if _config_recents.empty(): + popup.add_item(translator.tr("None"), ExtraOption.RECENT) + popup.set_item_disabled(popup.get_item_index(ExtraOption.RECENT), true) + else: + for i in _config_recents.size(): + popup.add_item(_config_recents[i].title, ExtraOption.RECENT + i) + + +func _on_Extra_id_pressed(id: int) -> void: + match id: + ExtraOption.SAVE_AS: + _popup_file_dialog(EditorFileDialog.MODE_SAVE_FILE, "_on_SaveAsDialog_confirmed", DefaultFilename.GUESS_FOR_SAVE) + + ExtraOption.COPY: + if not _config_clipboard: + _config_clipboard = SFXRConfig.new() + _config_clipboard.copy_from(_config) + + ExtraOption.PASTE: + _restore_from_config(_config_clipboard) + + ExtraOption.PASTE_JSFXR: + var pasted := SFXRConfig.new() + if pasted.load_from_base58(OS.clipboard) == OK: + _restore_from_config(pasted) + else: + _popup_message(translator.tr("Clipboard does not contain code copied from jsfxr.")) + + _: + var i := id - ExtraOption.RECENT as int + if i < 0 or _config_recents.size() <= i: + printerr("Bad index %d (%d in total)" % [i, _config_recents.size()]) + return + var recent: RecentEntry = _config_recents[i] + _restore_from_config(recent.config) + _on_Play_pressed() + diff --git a/addons/gdfxr/editor/Editor.tscn b/addons/gdfxr/editor/Editor.tscn new file mode 100644 index 0000000..3641981 --- /dev/null +++ b/addons/gdfxr/editor/Editor.tscn @@ -0,0 +1,394 @@ +[gd_scene load_steps=7 format=2] + +[ext_resource path="res://addons/gdfxr/editor/EditorIconButton.gd" type="Script" id=1] +[ext_resource path="res://addons/gdfxr/editor/Editor.gd" type="Script" id=2] +[ext_resource path="res://addons/gdfxr/editor/ParamSlider.tscn" type="PackedScene" id=3] +[ext_resource path="res://addons/gdfxr/editor/ParamOption.tscn" type="PackedScene" id=4] +[ext_resource path="res://addons/gdfxr/editor/PluginTranslator.tscn" type="PackedScene" id=5] +[ext_resource path="res://addons/gdfxr/editor/VersionButton.tscn" type="PackedScene" id=6] + +[node name="Editor" type="VBoxContainer"] +anchor_right = 1.0 +anchor_bottom = 1.0 +script = ExtResource( 2 ) + +[node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."] + +[node name="Toolbar" type="HBoxContainer" parent="."] +margin_right = 1024.0 +margin_bottom = 22.0 + +[node name="New" type="ToolButton" parent="Toolbar"] +margin_right = 12.0 +margin_bottom = 22.0 +hint_tooltip = "New" +script = ExtResource( 1 ) +icon_name = "New" + +[node name="Load" type="ToolButton" parent="Toolbar"] +margin_left = 16.0 +margin_right = 28.0 +margin_bottom = 22.0 +hint_tooltip = "Load" +script = ExtResource( 1 ) +icon_name = "Load" + +[node name="Save" type="ToolButton" parent="Toolbar"] +margin_left = 32.0 +margin_right = 44.0 +margin_bottom = 22.0 +hint_tooltip = "Save" +script = ExtResource( 1 ) +icon_name = "Save" + +[node name="Extra" type="MenuButton" parent="Toolbar"] +margin_left = 48.0 +margin_right = 60.0 +margin_bottom = 22.0 +hint_tooltip = "Extra Options" +script = ExtResource( 1 ) +icon_name = "GuiTabMenuHl" + +[node name="VSeparator" type="VSeparator" parent="Toolbar"] +margin_left = 64.0 +margin_right = 68.0 +margin_bottom = 22.0 + +[node name="Play" type="Button" parent="Toolbar"] +margin_left = 72.0 +margin_right = 152.0 +margin_bottom = 22.0 +rect_min_size = Vector2( 80, 0 ) +size_flags_horizontal = 0 +text = "Play" +script = ExtResource( 1 ) +icon_name = "Play" + +[node name="Restore" type="Button" parent="Toolbar"] +margin_left = 156.0 +margin_right = 236.0 +margin_bottom = 22.0 +rect_min_size = Vector2( 80, 0 ) +hint_tooltip = "Restore" +disabled = true +text = "Restore" +script = ExtResource( 1 ) +icon_name = "Reload" + +[node name="VSeparator2" type="VSeparator" parent="Toolbar"] +margin_left = 240.0 +margin_right = 244.0 +margin_bottom = 22.0 + +[node name="Filename" type="Label" parent="Toolbar"] +margin_left = 248.0 +margin_top = 4.0 +margin_right = 1020.0 +margin_bottom = 18.0 +size_flags_horizontal = 3 +text = "Unsaved sound" +clip_text = true + +[node name="VersionButton" parent="Toolbar" instance=ExtResource( 6 )] +margin_top = 4.0 +margin_bottom = 18.0 +website = "https://github.com/timothyqiu/gdfxr" + +[node name="HSeparator" type="HSeparator" parent="."] +margin_top = 26.0 +margin_right = 1024.0 +margin_bottom = 30.0 + +[node name="Editor" type="HBoxContainer" parent="."] +margin_top = 34.0 +margin_right = 1024.0 +margin_bottom = 600.0 +size_flags_vertical = 3 + +[node name="Generators" type="VBoxContainer" parent="Editor"] +margin_right = 128.0 +margin_bottom = 566.0 +rect_min_size = Vector2( 128, 0 ) + +[node name="Button" type="Button" parent="Editor/Generators"] +margin_right = 128.0 +margin_bottom = 20.0 +text = "Pickup/Coin" + +[node name="Button2" type="Button" parent="Editor/Generators"] +margin_top = 24.0 +margin_right = 128.0 +margin_bottom = 44.0 +text = "Laser/Shoot" + +[node name="Button3" type="Button" parent="Editor/Generators"] +margin_top = 48.0 +margin_right = 128.0 +margin_bottom = 68.0 +text = "Explosion" + +[node name="Button4" type="Button" parent="Editor/Generators"] +margin_top = 72.0 +margin_right = 128.0 +margin_bottom = 92.0 +text = "Powerup" + +[node name="Button5" type="Button" parent="Editor/Generators"] +margin_top = 96.0 +margin_right = 128.0 +margin_bottom = 116.0 +text = "Hit/Hurt" + +[node name="Button6" type="Button" parent="Editor/Generators"] +margin_top = 120.0 +margin_right = 128.0 +margin_bottom = 140.0 +text = "Jump" + +[node name="Button7" type="Button" parent="Editor/Generators"] +margin_top = 144.0 +margin_right = 128.0 +margin_bottom = 164.0 +text = "Blip/Select" + +[node name="HSeparator" type="HSeparator" parent="Editor/Generators"] +margin_top = 168.0 +margin_right = 128.0 +margin_bottom = 172.0 + +[node name="Button8" type="Button" parent="Editor/Generators"] +margin_top = 176.0 +margin_right = 128.0 +margin_bottom = 196.0 +size_flags_horizontal = 3 +text = "Mutate" + +[node name="Button9" type="Button" parent="Editor/Generators"] +margin_top = 200.0 +margin_right = 128.0 +margin_bottom = 220.0 +size_flags_horizontal = 3 +text = "Randomize" + +[node name="ScrollContainer" type="ScrollContainer" parent="Editor"] +margin_left = 132.0 +margin_right = 1024.0 +margin_bottom = 566.0 +size_flags_horizontal = 3 +scroll_vertical_enabled = false + +[node name="Params" type="HBoxContainer" parent="Editor/ScrollContainer"] +margin_top = 188.0 +margin_right = 895.0 +margin_bottom = 366.0 +size_flags_horizontal = 6 +size_flags_vertical = 6 + +[node name="Envolope" type="VBoxContainer" parent="Editor/ScrollContainer/Params"] +margin_right = 211.0 +margin_bottom = 178.0 + +[node name="ParamSlider" parent="Editor/ScrollContainer/Params/Envolope" instance=ExtResource( 3 )] +margin_right = 211.0 +margin_bottom = 22.0 +label = "Attack Time" +parameter = "p_env_attack" + +[node name="ParamSlider2" parent="Editor/ScrollContainer/Params/Envolope" instance=ExtResource( 3 )] +margin_top = 26.0 +margin_right = 211.0 +margin_bottom = 48.0 +label = "Sustain Time" +parameter = "p_env_sustain" + +[node name="ParamSlider3" parent="Editor/ScrollContainer/Params/Envolope" instance=ExtResource( 3 )] +margin_top = 52.0 +margin_right = 211.0 +margin_bottom = 74.0 +label = "Sustain Punch" +parameter = "p_env_punch" + +[node name="ParamSlider4" parent="Editor/ScrollContainer/Params/Envolope" instance=ExtResource( 3 )] +margin_top = 78.0 +margin_right = 211.0 +margin_bottom = 100.0 +label = "Decay Time" +parameter = "p_env_decay" + +[node name="ParamSlider5" parent="Editor/ScrollContainer/Params/Envolope" instance=ExtResource( 3 )] +margin_top = 104.0 +margin_right = 211.0 +margin_bottom = 126.0 +label = "Change Amount" +parameter = "p_arp_mod" +bipolar = true + +[node name="ParamSlider6" parent="Editor/ScrollContainer/Params/Envolope" instance=ExtResource( 3 )] +margin_top = 130.0 +margin_right = 211.0 +margin_bottom = 152.0 +label = "Change Speed" +parameter = "p_arp_speed" + +[node name="ParamSlider7" parent="Editor/ScrollContainer/Params/Envolope" instance=ExtResource( 3 )] +margin_top = 156.0 +margin_right = 211.0 +margin_bottom = 178.0 +label = "Volume" +parameter = "sound_vol" + +[node name="Frequency" type="VBoxContainer" parent="Editor/ScrollContainer/Params"] +margin_left = 215.0 +margin_right = 425.0 +margin_bottom = 178.0 + +[node name="ParamSlider" parent="Editor/ScrollContainer/Params/Frequency" instance=ExtResource( 3 )] +margin_right = 210.0 +margin_bottom = 22.0 +label = "Start Frequency" +parameter = "p_base_freq" + +[node name="ParamSlider2" parent="Editor/ScrollContainer/Params/Frequency" instance=ExtResource( 3 )] +margin_top = 26.0 +margin_right = 210.0 +margin_bottom = 48.0 +label = "Min Frequency" +parameter = "p_freq_limit" + +[node name="ParamSlider3" parent="Editor/ScrollContainer/Params/Frequency" instance=ExtResource( 3 )] +margin_top = 52.0 +margin_right = 210.0 +margin_bottom = 74.0 +label = "Slide" +parameter = "p_freq_ramp" +bipolar = true + +[node name="ParamSlider4" parent="Editor/ScrollContainer/Params/Frequency" instance=ExtResource( 3 )] +margin_top = 78.0 +margin_right = 210.0 +margin_bottom = 100.0 +label = "Delta Slide" +parameter = "p_freq_dramp" +bipolar = true + +[node name="ParamSlider5" parent="Editor/ScrollContainer/Params/Frequency" instance=ExtResource( 3 )] +margin_top = 104.0 +margin_right = 210.0 +margin_bottom = 126.0 +label = "Vibrato Depth" +parameter = "p_vib_strength" + +[node name="ParamSlider6" parent="Editor/ScrollContainer/Params/Frequency" instance=ExtResource( 3 )] +margin_top = 130.0 +margin_right = 210.0 +margin_bottom = 152.0 +label = "Vibrato Speed" +parameter = "p_vib_speed" + +[node name="ParamSlider7" parent="Editor/ScrollContainer/Params/Frequency" instance=ExtResource( 3 )] +margin_top = 156.0 +margin_right = 210.0 +margin_bottom = 178.0 +label = "Repeat Speed" +parameter = "p_repeat_speed" + +[node name="Waveform" type="VBoxContainer" parent="Editor/ScrollContainer/Params"] +margin_left = 429.0 +margin_right = 649.0 +margin_bottom = 178.0 + +[node name="WaveformOption" parent="Editor/ScrollContainer/Params/Waveform" instance=ExtResource( 4 )] +margin_right = 220.0 +margin_bottom = 22.0 +options = [ "Square", "Sawtooth", "Sine", "Noise" ] +parameter = "wave_type" + +[node name="ParamSlider" parent="Editor/ScrollContainer/Params/Waveform" instance=ExtResource( 3 )] +margin_top = 26.0 +margin_right = 220.0 +margin_bottom = 48.0 +label = "Square Duty" +parameter = "p_duty" + +[node name="ParamSlider2" parent="Editor/ScrollContainer/Params/Waveform" instance=ExtResource( 3 )] +margin_top = 52.0 +margin_right = 220.0 +margin_bottom = 74.0 +label = "Duty Sweep" +parameter = "p_duty_ramp" +bipolar = true + +[node name="ParamSlider5" parent="Editor/ScrollContainer/Params/Waveform" instance=ExtResource( 3 )] +margin_top = 78.0 +margin_right = 220.0 +margin_bottom = 100.0 +label = "Phaser Offset" +parameter = "p_pha_offset" +bipolar = true + +[node name="ParamSlider3" parent="Editor/ScrollContainer/Params/Waveform" instance=ExtResource( 3 )] +margin_top = 104.0 +margin_right = 220.0 +margin_bottom = 126.0 +label = "Phaser Sweep" +parameter = "p_pha_ramp" +bipolar = true + +[node name="Filter" type="VBoxContainer" parent="Editor/ScrollContainer/Params"] +margin_left = 653.0 +margin_right = 895.0 +margin_bottom = 178.0 + +[node name="ParamSlider" parent="Editor/ScrollContainer/Params/Filter" instance=ExtResource( 3 )] +margin_right = 242.0 +margin_bottom = 22.0 +label = "Low-pass Cutoff" +parameter = "p_lpf_freq" + +[node name="ParamSlider2" parent="Editor/ScrollContainer/Params/Filter" instance=ExtResource( 3 )] +margin_top = 26.0 +margin_right = 242.0 +margin_bottom = 48.0 +label = "Low-pass Sweep" +parameter = "p_lpf_ramp" +bipolar = true + +[node name="ParamSlider5" parent="Editor/ScrollContainer/Params/Filter" instance=ExtResource( 3 )] +margin_top = 52.0 +margin_right = 242.0 +margin_bottom = 74.0 +label = "Low-pass Resonance" +parameter = "p_lpf_resonance" + +[node name="ParamSlider3" parent="Editor/ScrollContainer/Params/Filter" instance=ExtResource( 3 )] +margin_top = 78.0 +margin_right = 242.0 +margin_bottom = 100.0 +label = "High-pass Cutoff" +parameter = "p_hpf_freq" + +[node name="ParamSlider4" parent="Editor/ScrollContainer/Params/Filter" instance=ExtResource( 3 )] +margin_top = 104.0 +margin_right = 242.0 +margin_bottom = 126.0 +label = "High-pass Sweep" +parameter = "p_hpf_ramp" +bipolar = true + +[node name="PluginTranslator" parent="." instance=ExtResource( 5 )] + +[connection signal="pressed" from="Toolbar/New" to="." method="_on_New_pressed"] +[connection signal="pressed" from="Toolbar/Load" to="." method="_on_Load_pressed"] +[connection signal="pressed" from="Toolbar/Save" to="." method="_on_Save_pressed"] +[connection signal="about_to_show" from="Toolbar/Extra" to="." method="_on_Extra_about_to_show"] +[connection signal="pressed" from="Toolbar/Play" to="." method="_on_Play_pressed"] +[connection signal="pressed" from="Toolbar/Restore" to="." method="_on_Restore_pressed"] +[connection signal="pressed" from="Editor/Generators/Button" to="." method="_on_Randomize_pressed" binds= [ 0 ]] +[connection signal="pressed" from="Editor/Generators/Button2" to="." method="_on_Randomize_pressed" binds= [ 1 ]] +[connection signal="pressed" from="Editor/Generators/Button3" to="." method="_on_Randomize_pressed" binds= [ 2 ]] +[connection signal="pressed" from="Editor/Generators/Button4" to="." method="_on_Randomize_pressed" binds= [ 3 ]] +[connection signal="pressed" from="Editor/Generators/Button5" to="." method="_on_Randomize_pressed" binds= [ 4 ]] +[connection signal="pressed" from="Editor/Generators/Button6" to="." method="_on_Randomize_pressed" binds= [ 5 ]] +[connection signal="pressed" from="Editor/Generators/Button7" to="." method="_on_Randomize_pressed" binds= [ 6 ]] +[connection signal="pressed" from="Editor/Generators/Button8" to="." method="_on_Mutate_pressed"] +[connection signal="pressed" from="Editor/Generators/Button9" to="." method="_on_Randomize_pressed" binds= [ -1 ]] diff --git a/addons/gdfxr/editor/EditorIconButton.gd b/addons/gdfxr/editor/EditorIconButton.gd new file mode 100644 index 0000000..9a16ad0 --- /dev/null +++ b/addons/gdfxr/editor/EditorIconButton.gd @@ -0,0 +1,16 @@ +tool +extends Button + +export var icon_name: String + +var plugin: EditorPlugin # a hack to know if this is executing as plugin + + +func _notification(what: int): + if not plugin: + return + + match what: + NOTIFICATION_ENTER_TREE, NOTIFICATION_THEME_CHANGED: + if icon_name: + icon = get_icon(icon_name, "EditorIcons") diff --git a/addons/gdfxr/editor/ParamOption.gd b/addons/gdfxr/editor/ParamOption.gd new file mode 100644 index 0000000..29402ff --- /dev/null +++ b/addons/gdfxr/editor/ParamOption.gd @@ -0,0 +1,43 @@ +tool +extends HBoxContainer + +signal param_changed(name, value) +signal param_reset(name) + +export var options: Array setget set_options +export var parameter: String # Could be PoolStringArray, but pybabel won't catch that + +onready var option_button := $OptionButton as OptionButton + + +func _ready(): + set_options(options) + + +func set_options(v: Array) -> void: + options = v + + if is_inside_tree(): + option_button.clear() + for item in options: + option_button.add_item(item) + + +func set_value(v: int) -> void: + option_button.select(v) + + +func get_value() -> int: + return option_button.selected + + +func set_resetable(v: bool) -> void: + $Reset.disabled = not v + + +func _on_OptionButton_item_selected(index: int): + emit_signal("param_changed", parameter, index) + + +func _on_Reset_pressed(): + emit_signal("param_reset", parameter) diff --git a/addons/gdfxr/editor/ParamOption.tscn b/addons/gdfxr/editor/ParamOption.tscn new file mode 100644 index 0000000..41452da --- /dev/null +++ b/addons/gdfxr/editor/ParamOption.tscn @@ -0,0 +1,43 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://addons/gdfxr/editor/ParamOption.gd" type="Script" id=1] +[ext_resource path="res://addons/gdfxr/editor/EditorIconButton.gd" type="Script" id=2] + +[node name="WaveformOption" type="HBoxContainer"] +margin_right = 253.0 +margin_bottom = 40.0 +rect_pivot_offset = Vector2( 41, -65 ) +size_flags_horizontal = 3 +script = ExtResource( 1 ) + +[node name="Label" type="Label" parent="."] +margin_top = 13.0 +margin_right = 128.0 +margin_bottom = 27.0 +rect_min_size = Vector2( 100, 0 ) +size_flags_horizontal = 3 +text = "Waveform" +align = 2 + +[node name="OptionButton" type="OptionButton" parent="."] +margin_left = 132.0 +margin_top = 10.0 +margin_right = 237.0 +margin_bottom = 30.0 +rect_min_size = Vector2( 105, 0 ) +size_flags_vertical = 4 +clip_text = true + +[node name="Reset" type="ToolButton" parent="."] +margin_left = 241.0 +margin_top = 9.0 +margin_right = 253.0 +margin_bottom = 31.0 +focus_mode = 0 +size_flags_vertical = 4 +enabled_focus_mode = 0 +script = ExtResource( 2 ) +icon_name = "ReloadSmall" + +[connection signal="item_selected" from="OptionButton" to="." method="_on_OptionButton_item_selected"] +[connection signal="pressed" from="Reset" to="." method="_on_Reset_pressed"] diff --git a/addons/gdfxr/editor/ParamSlider.gd b/addons/gdfxr/editor/ParamSlider.gd new file mode 100644 index 0000000..c88a258 --- /dev/null +++ b/addons/gdfxr/editor/ParamSlider.gd @@ -0,0 +1,43 @@ +tool +extends HBoxContainer + +signal param_changed(name, value) +signal param_reset(name) + +export var label: String setget set_label +export var parameter: String +export var bipolar := false setget set_bipolar + + +func set_label(v: String) -> void: + label = v + $Label.text = v + + +func set_bipolar(v: bool) -> void: + bipolar = v + if bipolar: + $HSlider.min_value = -1.0 + else: + $HSlider.min_value = 0.0 + + +func set_value(v: float) -> void: + $HSlider.value = v + + +func get_value() -> float: + return $HSlider.value + + +func set_resetable(v: bool) -> void: + $Reset.disabled = not v + + +func _on_HSlider_value_changed(value: float): + emit_signal("param_changed", parameter, value) + + +func _on_Reset_pressed(): + emit_signal("param_reset", parameter) + diff --git a/addons/gdfxr/editor/ParamSlider.tscn b/addons/gdfxr/editor/ParamSlider.tscn new file mode 100644 index 0000000..33ba555 --- /dev/null +++ b/addons/gdfxr/editor/ParamSlider.tscn @@ -0,0 +1,42 @@ +[gd_scene load_steps=4 format=2] + +[ext_resource path="res://addons/gdfxr/editor/ParamSlider.gd" type="Script" id=1] +[ext_resource path="res://addons/gdfxr/editor/EditorIconButton.gd" type="Script" id=2] +[ext_resource path="res://addons/gdfxr/editor/EditSlider.gd" type="Script" id=3] + +[node name="ParamSlider" type="HBoxContainer"] +margin_right = 253.0 +margin_bottom = 40.0 +size_flags_horizontal = 3 +script = ExtResource( 1 ) + +[node name="Label" type="Label" parent="."] +margin_top = 13.0 +margin_right = 128.0 +margin_bottom = 27.0 +rect_min_size = Vector2( 100, 0 ) +size_flags_horizontal = 3 +align = 2 + +[node name="HSlider" type="Control" parent="."] +margin_left = 132.0 +margin_right = 237.0 +margin_bottom = 40.0 +rect_min_size = Vector2( 105, 0 ) +rect_clip_content = true +focus_mode = 2 +mouse_default_cursor_shape = 10 +script = ExtResource( 3 ) + +[node name="Reset" type="ToolButton" parent="."] +margin_left = 241.0 +margin_top = 9.0 +margin_right = 253.0 +margin_bottom = 31.0 +focus_mode = 0 +size_flags_vertical = 4 +script = ExtResource( 2 ) +icon_name = "ReloadSmall" + +[connection signal="value_changed" from="HSlider" to="." method="_on_HSlider_value_changed"] +[connection signal="pressed" from="Reset" to="." method="_on_Reset_pressed"] diff --git a/addons/gdfxr/editor/PluginTranslator.gd b/addons/gdfxr/editor/PluginTranslator.gd new file mode 100644 index 0000000..c4f9017 --- /dev/null +++ b/addons/gdfxr/editor/PluginTranslator.gd @@ -0,0 +1,56 @@ +tool +extends Node + +var plugin: EditorPlugin setget set_plugin + +var _translation: Translation + + +func set_plugin(v: EditorPlugin) -> void: + if plugin == v: + return + if not v: + plugin = null + _translation = null + return + + plugin = v + var locale: String = plugin.get_editor_interface().get_editor_settings().get('interface/editor/editor_language') + var script := get_script() as Script + var path := script.resource_path.get_base_dir().plus_file("translations/%s.po" % locale) + if ResourceLoader.exists(path): + _translation = ResourceLoader.load(path) + + if _translation: + _translate_node(get_parent()) + + +func tr(message: String) -> String: + if _translation: + var translated := _translation.get_message(message) + if not translated.empty(): + return translated + return message + + +func _translate_node(node: Node): + if node is Control: + node.hint_tooltip = tr(node.hint_tooltip) + + if node is HBoxContainer and node.has_method("set_options"): + var options = [] + for item in node.options: + options.append(tr(item)) + node.options = options + + if node is Button and not node is OptionButton: + node.text = tr(node.text) + + if node is Label: + node.text = tr(node.text) + + if node is Slider: + node.hint_tooltip = tr(node.hint_tooltip) + + for child in node.get_children(): + _translate_node(child) diff --git a/addons/gdfxr/editor/PluginTranslator.tscn b/addons/gdfxr/editor/PluginTranslator.tscn new file mode 100644 index 0000000..1868f2a --- /dev/null +++ b/addons/gdfxr/editor/PluginTranslator.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://addons/gdfxr/editor/PluginTranslator.gd" type="Script" id=1] + +[node name="PluginTranslator" type="Node"] +script = ExtResource( 1 ) diff --git a/addons/gdfxr/editor/VersionButton.gd b/addons/gdfxr/editor/VersionButton.gd new file mode 100644 index 0000000..3baa0dd --- /dev/null +++ b/addons/gdfxr/editor/VersionButton.gd @@ -0,0 +1,25 @@ +tool +extends LinkButton + +export var website: String + +var plugin: EditorPlugin setget set_plugin + + +func set_plugin(v: EditorPlugin) -> void: + plugin = v + + var script := get_script() as Script + var path := script.resource_path.get_base_dir().plus_file("../plugin.cfg") + + var cfg := ConfigFile.new() + var err := cfg.load(path) + text = "%s v%s" % [ + cfg.get_value("plugin", "name", "plugin"), + cfg.get_value("plugin", "version", "1.0"), + ] + + +func _on_VersionButton_pressed(): + if website: + OS.shell_open(website) diff --git a/addons/gdfxr/editor/VersionButton.tscn b/addons/gdfxr/editor/VersionButton.tscn new file mode 100644 index 0000000..c0161b4 --- /dev/null +++ b/addons/gdfxr/editor/VersionButton.tscn @@ -0,0 +1,19 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://addons/gdfxr/editor/VersionButton.gd" type="Script" id=1] + +[node name="VersionButton" type="LinkButton"] +self_modulate = Color( 1, 1, 1, 0.65 ) +margin_left = 1024.0 +margin_top = 5.0 +margin_right = 1024.0 +margin_bottom = 19.0 +focus_mode = 2 +size_flags_vertical = 4 +underline = 1 +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[connection signal="pressed" from="." to="." method="_on_VersionButton_pressed"] diff --git a/addons/gdfxr/editor/translations/zh_CN.po b/addons/gdfxr/editor/translations/zh_CN.po new file mode 100644 index 0000000..9ca15d9 --- /dev/null +++ b/addons/gdfxr/editor/translations/zh_CN.po @@ -0,0 +1,265 @@ +# Translations template for gdfxr. +# Copyright (C) 2022 Haoyu Qiu +# This file is distributed under the same license as the gdfxr project. +# Haoyu Qiu , 2022. +# +msgid "" +msgstr "" +"Project-Id-Version: gdfxr 1.0\n" +"Report-Msgid-Bugs-To: timothyqiu32@gmail.com\n" +"POT-Creation-Date: 2022-12-04 13:45+0800\n" +"PO-Revision-Date: 2022-12-04 13:45+0800\n" +"Last-Translator: Haoyu Qiu \n" +"Language-Team: \n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"Generated-By: Babel 2.9.1\n" +"X-Generator: Poedit 3.2.1\n" + +#: addons/gdfxr/editor/Editor.gd +msgid "Save As..." +msgstr "另存为..." + +#: addons/gdfxr/editor/Editor.gd +msgid "Copy" +msgstr "复制" + +#: addons/gdfxr/editor/Editor.gd +msgid "Paste" +msgstr "粘贴" + +#: addons/gdfxr/editor/Editor.gd +msgid "Paste from jsfxr" +msgstr "从 jsfxr 粘贴" + +#: addons/gdfxr/editor/Editor.gd +msgid "Recently Generated" +msgstr "最近生成" + +#: addons/gdfxr/editor/Editor.gd addons/gdfxr/editor/Editor.tscn +msgid "Pickup/Coin" +msgstr "拾取/金币" + +#: addons/gdfxr/editor/Editor.gd addons/gdfxr/editor/Editor.tscn +msgid "Laser/Shoot" +msgstr "激光/射击" + +#: addons/gdfxr/editor/Editor.gd addons/gdfxr/editor/Editor.tscn +msgid "Explosion" +msgstr "爆炸" + +#: addons/gdfxr/editor/Editor.gd addons/gdfxr/editor/Editor.tscn +msgid "Powerup" +msgstr "升级" + +#: addons/gdfxr/editor/Editor.gd addons/gdfxr/editor/Editor.tscn +msgid "Hit/Hurt" +msgstr "击中/受伤" + +#: addons/gdfxr/editor/Editor.gd addons/gdfxr/editor/Editor.tscn +msgid "Jump" +msgstr "跳跃" + +#: addons/gdfxr/editor/Editor.gd addons/gdfxr/editor/Editor.tscn +msgid "Blip/Select" +msgstr "短滴/选择" + +#: addons/gdfxr/editor/Editor.gd +#, python-format +msgid "" +"There are unsaved changes.\n" +"Open '%s' anyway?" +msgstr "" +"存在未保存的修改。\n" +"仍然要打开“%s”吗?" + +#: addons/gdfxr/editor/Editor.gd +msgid "SFXR Editor" +msgstr "SFXR 编辑器" + +#: addons/gdfxr/editor/Editor.gd +msgid "SFXR Audio" +msgstr "SFXR 音频" + +#: addons/gdfxr/editor/Editor.gd +#, python-format +msgid "'%s' is not a valid SFXR file." +msgstr "“%s”不是有效的 SFXR 文件。" + +#: addons/gdfxr/editor/Editor.gd addons/gdfxr/editor/Editor.tscn +msgid "Unsaved sound" +msgstr "未保存音效" + +#: addons/gdfxr/editor/Editor.gd addons/gdfxr/editor/Editor.tscn +msgid "Randomize" +msgstr "随机" + +#: addons/gdfxr/editor/Editor.gd addons/gdfxr/editor/Editor.tscn +msgid "Mutate" +msgstr "演化" + +#: addons/gdfxr/editor/Editor.gd +msgid "" +"There are unsaved changes.\n" +"Create a new one anyway?" +msgstr "" +"存在未保存的修改。\n" +"仍然要新建吗?" + +#: addons/gdfxr/editor/Editor.gd +msgid "" +"There are unsaved changes.\n" +"Load anyway?" +msgstr "" +"存在未保存的修改。\n" +"仍然要加载吗?" + +#: addons/gdfxr/editor/Editor.gd +msgid "None" +msgstr "无" + +#: addons/gdfxr/editor/Editor.gd +msgid "Clipboard does not contain code copied from jsfxr." +msgstr "剪贴板中没有从 jsfxr 复制的代码。" + +#: addons/gdfxr/editor/Editor.tscn +msgid "New" +msgstr "新建" + +#: addons/gdfxr/editor/Editor.tscn +msgid "Load" +msgstr "加载" + +#: addons/gdfxr/editor/Editor.tscn +msgid "Save" +msgstr "保存" + +#: addons/gdfxr/editor/Editor.tscn +msgid "Extra Options" +msgstr "更多选项" + +#: addons/gdfxr/editor/Editor.tscn +msgid "Play" +msgstr "播放" + +#: addons/gdfxr/editor/Editor.tscn +msgid "Restore" +msgstr "恢复" + +#: addons/gdfxr/editor/Editor.tscn +msgid "Attack Time" +msgstr "起音时间" + +#: addons/gdfxr/editor/Editor.tscn +msgid "Sustain Time" +msgstr "延音时间" + +#: addons/gdfxr/editor/Editor.tscn +msgid "Sustain Punch" +msgstr "延音冲击" + +#: addons/gdfxr/editor/Editor.tscn +msgid "Decay Time" +msgstr "释音时间" + +#: addons/gdfxr/editor/Editor.tscn +msgid "Change Amount" +msgstr "改变强度" + +#: addons/gdfxr/editor/Editor.tscn +msgid "Change Speed" +msgstr "改变速度" + +#: addons/gdfxr/editor/Editor.tscn +msgid "Volume" +msgstr "音量" + +#: addons/gdfxr/editor/Editor.tscn +msgid "Start Frequency" +msgstr "起始频率" + +#: addons/gdfxr/editor/Editor.tscn +msgid "Min Frequency" +msgstr "最低频率" + +#: addons/gdfxr/editor/Editor.tscn +msgid "Slide" +msgstr "滑音" + +#: addons/gdfxr/editor/Editor.tscn +msgid "Delta Slide" +msgstr "滑音增量" + +#: addons/gdfxr/editor/Editor.tscn +msgid "Vibrato Depth" +msgstr "颤音深度" + +#: addons/gdfxr/editor/Editor.tscn +msgid "Vibrato Speed" +msgstr "颤音速度" + +#: addons/gdfxr/editor/Editor.tscn +msgid "Repeat Speed" +msgstr "重复速度" + +#: addons/gdfxr/editor/Editor.tscn +msgid "Square" +msgstr "方波" + +#: addons/gdfxr/editor/Editor.tscn +msgid "Sawtooth" +msgstr "锯齿波" + +#: addons/gdfxr/editor/Editor.tscn +msgid "Sine" +msgstr "正弦波" + +#: addons/gdfxr/editor/Editor.tscn +msgid "Noise" +msgstr "噪波" + +#: addons/gdfxr/editor/Editor.tscn +msgid "Square Duty" +msgstr "方波工作" + +#: addons/gdfxr/editor/Editor.tscn +msgid "Duty Sweep" +msgstr "工作变频" + +#: addons/gdfxr/editor/Editor.tscn +msgid "Phaser Offset" +msgstr "相位偏移" + +#: addons/gdfxr/editor/Editor.tscn +msgid "Phaser Sweep" +msgstr "相位变频" + +#: addons/gdfxr/editor/Editor.tscn +msgid "Low-pass Cutoff" +msgstr "低通截频" + +#: addons/gdfxr/editor/Editor.tscn +msgid "Low-pass Sweep" +msgstr "低通变频" + +#: addons/gdfxr/editor/Editor.tscn +msgid "Low-pass Resonance" +msgstr "低通共振" + +#: addons/gdfxr/editor/Editor.tscn +msgid "High-pass Cutoff" +msgstr "高通截频" + +#: addons/gdfxr/editor/Editor.tscn +msgid "High-pass Sweep" +msgstr "高通变频" + +#: addons/gdfxr/editor/ParamOption.tscn +msgid "Waveform" +msgstr "波形" + +#~ msgid "Hold Ctrl to snap to 0.01 increments." +#~ msgstr "按住 Ctrl 吸附到 0.01 增量。" diff --git a/addons/gdfxr/import_plugin.gd b/addons/gdfxr/import_plugin.gd new file mode 100644 index 0000000..5dce8ff --- /dev/null +++ b/addons/gdfxr/import_plugin.gd @@ -0,0 +1,76 @@ +tool +extends EditorImportPlugin + +const SFXRConfig = preload("SFXRConfig.gd") +const SFXRGenerator = preload("SFXRGenerator.gd") + + +func get_importer_name(): + return "com.timothyqiu.gdfxr.importer" + + +func get_visible_name(): + return "SFXR Audio" + + +func get_recognized_extensions(): + return ["sfxr"] + + +func get_save_extension(): + return "sample" + + +func get_resource_type(): + return "AudioStreamSample" + + +func get_preset_count(): + return 1 + + +func get_preset_name(preset): + return "Default" + + +func get_import_options(preset): + return [ + { + name="loop", + default_value=false, + }, + { + name="bit_depth", + property_hint=PROPERTY_HINT_ENUM, + hint_string="8 Bits,16 Bits", + default_value=SFXRGenerator.WavBits.WAV_BITS_8, + }, + { + name="sample_rate", + property_hint=PROPERTY_HINT_ENUM, + hint_string="44100 Hz,22050 Hz", + default_value=SFXRGenerator.WavFreq.WAV_FREQ_44100, + }, + ] + + +func get_option_visibility(option, options): + return true + + +func import(source_file, save_path, options, platform_variants, gen_files): + var config := SFXRConfig.new() + var err := config.load(source_file) + if err != OK: + printerr("Failed to open %s: %d" % [source_file, err]) + return err + + var stream := SFXRGenerator.new().generate_audio_stream( + config, options.bit_depth, options.sample_rate + ) + if options.loop: + stream.loop_mode = AudioStreamSample.LOOP_FORWARD + stream.loop_end = stream.data.size() + + var filename = save_path + "." + get_save_extension() + return ResourceSaver.save(filename, stream) diff --git a/addons/gdfxr/plugin.cfg b/addons/gdfxr/plugin.cfg new file mode 100644 index 0000000..253bebe --- /dev/null +++ b/addons/gdfxr/plugin.cfg @@ -0,0 +1,7 @@ +[plugin] + +name="gdfxr" +description="A Godot plugin that ports sfxr, the popular program of choice to make retro sound effects for games." +author="Haoyu Qiu" +version="1.3" +script="plugin.gd" diff --git a/addons/gdfxr/plugin.gd b/addons/gdfxr/plugin.gd new file mode 100644 index 0000000..25bb1e9 --- /dev/null +++ b/addons/gdfxr/plugin.gd @@ -0,0 +1,39 @@ +tool +extends EditorPlugin + + +var import_plugin: EditorImportPlugin +var sfxr_editor: Control + + +func _enter_tree(): + import_plugin = preload("import_plugin.gd").new() + add_import_plugin(import_plugin) + + sfxr_editor = preload("editor/Editor.tscn").instance() + sfxr_editor.plugin = self + add_control_to_bottom_panel(sfxr_editor, "gdfxr") + + +func _exit_tree(): + remove_control_from_bottom_panel(sfxr_editor) + sfxr_editor.queue_free() + sfxr_editor = null + + remove_import_plugin(import_plugin) + import_plugin = null + + +func handles(object: Object) -> bool: + return object is AudioStreamSample and object.resource_path.ends_with(".sfxr") + + +func edit(object: Object): + sfxr_editor.edit(object.resource_path) # Should already passed `handles()` checks + + +func make_visible(visible: bool): + if visible: + make_bottom_panel_item_visible(sfxr_editor) + elif sfxr_editor.is_visible_in_tree(): + hide_bottom_panel() diff --git a/fonts/dotty.ttf b/fonts/dotty.ttf new file mode 100644 index 0000000000000000000000000000000000000000..4ce2814cf7fbf593ad923ea52f162c408315dc42 GIT binary patch literal 51848 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 RyWZu$2JD4SLM`a}e*kIWutfj> literal 0 HcmV?d00001 diff --git a/icon.png b/icon.png index c98fbb601c83c81ec8c22b1dba7d1d57c62b323c..bbe1ec2a2c44ddd785d1f3a89620b9eedfc4dc47 100644 GIT binary patch literal 660 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7Ro>V2bv1aSW-L^Y)IT9*d($`$tI^ zrzVb#5@urO4)ErziD?#&h_qz9zM-7?TtZ^=S_R3IEgRmczw}!9@>klK@3*(UeEIUE z{rY*Y-mU!i?Aoz%{~4CQSkmS)9^hfv7Vw)ne0sU`?fk>-YyK8Lm9yXae@7&v0ds>S z!ddcl$o!UymMZj)qY*E^K-|Q8TH>T$$Z|cZj%hs zz2Vj8hIQ3WT(-~L!x+vmB(O2O{JI1je&>U>_?d*`CL7j1j3e!XY5 zCdep>I^7o;7v6Aozx8(Pi3J9PmN~}yFmDvvE(powUwM`b;(CyF paFn&Jm-V$bcUiBU1&M+U@?m^)wutQt*94|E22WQ%mvv4FO#osRCzSvI literal 3305 zcmVNc=P)Px>qe(&U$es`gSqKCHF-lq>v1vga#%UF>TTrLR zW%{UNJKZi|Pj@Rc9GyPBD1CamMMf6SL~V^ag9~Vzut^L^0!Tv0LK0FTdnJ`x->EF(MZIP5kY*1-@^egP~7mH>({qi7{6 zQF;bN-XMq~+RzA8lI9AtJuz@PY*+{SP-Gbd@mZ(r*eE&`XO5!C>w#-pcmS28K^qzY zfTGCjor*I@ltgKb03nh#Fh$KpDL=o}gj-g4v6{}ZR1*mvXv?|gEA&Yr#r;Zw*d zUabIx8iHf+WoIO_c11Ba&!34XihSMF&C#YFDjU0)mmbXz3ex!D&t9UYp>;&R%(O(_ z*z^;&A84SWzKiQpqsdQ+Vs?rFS(f?R;c8xg_ft;Roec_~1KsVww}wzq5D}*5x6k|& zf~2A3@L4|ix|Q=L>rnmKE;B3UB=OMQxAK$Ce;LvDp?hwn-{Rn}Uo~U4IXTs4V%MQY zCWULcZFU0R%gbU;_Ef(A#76r1%|YWis0t`9$R{cyjFnsV(POrI)SGQi-l{mu{e?5R zepcp?AQ54D3g_mswd@RLn{z~;^Cl}>%j@}TWixL+audY``MmSV{-E(3R0Ws^U9%mk zmAond;N8k*{(f!}e^~d(i1Hq@jdv@XN2MLAl}3yaECf{nz5N3KMCjDCFzB_7)gkjj z>2Z={^e74l7u>P4oo1{Kc~sgFI`xP#f`uR}z_p~qLwws5)h)eLxAX=?+fB2_6kG)a zeE3U}YSi;Qc}gq*;kw|Tu5Oy{F)l`0;$$RA6)@d^I9>n9N^W1g0D!WJYJT&d@6p`W zfmWmD=^x$2@|)+=&@n(wn<-#M#zIY-iH42=UU>XI3i7l0^?#ILwb@CU63f5b_jeS| zn+d@CpB>^?Ti*1WuHSaRniWO-^Xl8!b+D0stAl$BQjr8G`KX-vGpCc0lEAKmjl6lN z5r?ddL)6hBi2|!`NM+@MRO*^qsi>~y`%4$%P+-S_M#8ibt8Pf;m7O23?cF^-X$52l zEV@3AM^`Q9vy(=)?W+gi)8lPCP&k!)Z(Bsa#m@S7j#1gzJx&pQ!yzlYvA==iExkN@ zTMnz!68Wg=9Ius~p?A=A>P(5$@#w1MG`6<$`Il8=(j0RI#KlIj>!qL4)MMjk|8*3* zbL8w!iwnbSb<*17eb=8TBt(Uv*Qz*e>>p9CRtapnJD-#&4Xd8ojIpD~Yk&6&7;_U` z|L{sgNzJAYPkIOsaN5{^*@Xva?HTkC9>DHY*!1B^L`lv1hgXhC$EO1BSh9fYXU*VG zpVwjRvs^m2ml?)B3xE2&j_YU5;Ep8=e75zefN3cSw04`>U3D&~3|AIJAJnEseqE*p>uF=1Cv$SfvI z!(+vnRMj+4vb)@8Tb~MW$}-RYemjyN^W@U3pfWj;cyehLk|6W*KkUFMkM3W9AE!Wb zTL-_}Udr6GXl}`!5;P_!3b*7=VQyM9zuR6)b6dxl?fo)@-u`$$Pu#bHB*W+#Gp!_Y z*ZdUbq#B3_QPbElK4*QE)$x+;qpGazKD1C!=jx=^ta=2+!&oRjmg4Jf{ z?T`J78TjoBD9Y&OtwFEhrIq<48uS2IEEbY8C$TVd5`X!kj*`Qd7RI`3elib!C*xb1 z(UIgPMzT12GEcpEly0*vU|ugqP(r~!E}l-JK~G&>9S_|9Aj@uD&azvVQ&RF4YZp!> zJ3hi|zlabu5u>=y+3^vqT{xAJlDCHFJ#hbn)Ya9IXwdWH;_1O)ef$at)k@qrEf%ZQ z%DU&)(a_KUxMpn2t6Mm@e?LVzaUT6LCWo=>;TzfYZ~+;U!#wJXa^g66-~d}*-Gas9 zGQt`f8d&$-daPC}H%^NkiV}?n<5oawj2=M{sHv&JXl(bWFDox6HP$o6KRY=Jl_;PR zMP?^QdD4vyrL3&XqugjTQd3idAPA(!=*P?c_!Z!e`f9aWuk~t4qQew;9IwMq>%w#92+*iNN#Qp zadB}J6)j=I#urf#czO3X!C*Z&LD5rfCLY^S$>ZP6}eFW#%-2L)+t{`cPyqLD6))yK1?m7F>6=?Y&8f)>3zbH1O)cT}QNtB4KL(A@1i zMzF88gDrb&hn~H`?o`-XUeDI@dXfwwboAS>*qvV6UMhkfzO~q$V+s%8loj4P(&9H= ze`sC`uI?L9L4e;YK&2A7XF)0}u1lh+%Z$S*Q{ORwtSHpAyWYpI>bqzU!p`gqlf$*l zO^*g(+T?Hq0n%ebkyIin(R#FM6&9;^6WJU5R)By&tZQ6PV zS^MWhqtcj}7)kON#>?4Gv(K#2=6mv)5;@W->l(1q*>9t&xfesIn$&3j4WxkffXaq0 zwwBkAD2vjoi4E8CK;cwoC3#wO!|}v-XOJ`obIo05{&DMQIRyHAd5@%-0xA%uA0UK2qng>xb(kvMzX)7t^ z);-|T`mgSsHKM$+a{!w|Mt5QLwD>sA+;u-+k%z_ZL?el$#&|kX?ygLfm zxZ^Fo^bOhx)w*6In?vS{Q|uk08cKRK}t+0ukQSCOyP$^HEC+zzX51M#=e-?*xHWMDRcLdIV41daHy{HimwDo z6!_O=*(}MK!YeyJpmgu(cF1tpEv}m;0s8{4z4HlHyMxDncn8zs!g+OXEk`CeEj}9N zq#Ag1$#jyV_5AjYQg*!mS->;`S^;iU)ih9D+eks)H2z`1RHny;F<^CEwk+}d^k^Ph zl);*XQ|ayL;rZWh=fA(G2#AJz1&r&as9I8S@9m3Owftrb5n*)pTluK^9LHOFIo{G2 zG}l$9R*{<+L2hCsOJ~Lt6Q-rRub*8X{*4{)e}>%=_&DxOFeq1LRia4Yyj*Tyynw>F zxkKf(MiaG0*L|V-^Zhtvg-(-|F0&1rU8bqab*n5TT8~C860O$|6Rt%P1=1(EjIQZ% z;Y^PU2VC*~^2!sG?mbBPS0~0yd-+086)+rHjhfk6>CB$t`o%;=kdYF9NwiKkwbIpN z;_FlOuHQHHSZ&@fUuSI-S*t`DjsiIB z{=1M@JKVC$a8z{2;xCPfRb{~T>uo#5rL4L+z9n`rSUt3Tt nAZ`TZm+q1gPVN84&*%Ra7her>#-hHS00000NkvXXu0mjf|6N@O diff --git a/project.godot b/project.godot index 30ad535..b8382ac 100644 --- a/project.godot +++ b/project.godot @@ -11,13 +11,22 @@ config_version=4 [application] config/name="H2Grow" +run/main_scene="res://Scenes/Start.tscn" config/icon="res://icon.png" +[autoload] + +Utils="*res://Scripts/Utils.gd" + [display] window/size/resizable=false window/vsync/use_vsync=false +[editor_plugins] + +enabled=PoolStringArray( "res://addons/gdfxr/plugin.cfg" ) + [gui] common/drop_mouse_on_gui_input_disabled=true