From 2db21b597b0ffac5fbca10981232180123988a41 Mon Sep 17 00:00:00 2001 From: Adrien Ufferte Date: Sat, 6 Jun 2026 11:13:22 +0200 Subject: [PATCH 1/3] Minigames wheel version 2 --- assets/gardens/animals/ant_body.png | Bin 0 -> 2841 bytes .../animals/ant_body.png.import} | 8 +- assets/gardens/animals/ant_face.png | Bin 0 -> 953 bytes .../animals/ant_face.png.import} | 8 +- assets/gardens/animals/caterpillar_body.png | Bin 0 -> 2890 bytes .../animals/caterpillar_body.png.import | 40 ++ assets/gardens/animals/caterpillar_face.png | Bin 0 -> 806 bytes .../animals/caterpillar_face.png.import | 40 ++ assets/gardens/animals/crab_body.png | Bin 0 -> 2253 bytes assets/gardens/animals/crab_body.png.import | 40 ++ assets/gardens/animals/crab_face.png | Bin 0 -> 1005 bytes .../animals/crab_face.png.import} | 8 +- assets/gardens/animals/frog_body.png | Bin 0 -> 2729 bytes .../animals/frog_body.png.import} | 8 +- assets/gardens/animals/frog_face.png | Bin 0 -> 1707 bytes assets/gardens/animals/frog_face.png.import | 40 ++ assets/gardens/animals/jellyfish_body.png | Bin 0 -> 5332 bytes .../gardens/animals/jellyfish_body.png.import | 40 ++ assets/gardens/animals/jellyfish_face.png | Bin 0 -> 1131 bytes .../gardens/animals/jellyfish_face.png.import | 40 ++ assets/gardens/animals/monkey_body.png | Bin 0 -> 3817 bytes assets/gardens/animals/monkey_body.png.import | 40 ++ assets/gardens/animals/monkey_face.png | Bin 0 -> 1080 bytes assets/gardens/animals/monkey_face.png.import | 40 ++ assets/gardens/animals/parakeet_body.png | Bin 0 -> 2392 bytes .../gardens/animals/parakeet_body.png.import | 40 ++ assets/gardens/animals/parakeet_face.png | Bin 0 -> 1929 bytes .../gardens/animals/parakeet_face.png.import | 40 ++ assets/gardens/animals/penguin_body.png | Bin 0 -> 2758 bytes .../gardens/animals/penguin_body.png.import | 40 ++ assets/gardens/animals/penguin_face.png | Bin 0 -> 1145 bytes .../gardens/animals/penguin_face.png.import | 40 ++ assets/gardens/animals/turtle_body.png | Bin 0 -> 5488 bytes assets/gardens/animals/turtle_body.png.import | 40 ++ assets/gardens/animals/turtle_face.png | Bin 0 -> 917 bytes assets/gardens/animals/turtle_face.png.import | 40 ++ assets/gardens/buttons/movie_icon.png | Bin 0 -> 2388 bytes assets/gardens/buttons/movie_icon.png.import | 40 ++ .../{ => victory_assets}/animals/ant.png | Bin .../animals/ant.png.import | 6 +- .../animals/caterpillar.png | Bin .../animals/caterpillar.png.import | 6 +- .../{ => victory_assets}/animals/crab.png | Bin .../animals/crab.png.import | 6 +- .../{ => victory_assets}/animals/frog.png | Bin .../animals/frog.png.import | 6 +- .../animals/jellyfish.png | Bin .../animals/jellyfish.png.import | 6 +- .../animals/khaki_turtle.png | Bin .../animals/khaki_turtle.png.import | 6 +- .../{ => victory_assets}/animals/monkey.png | Bin .../animals/monkey.png.import | 6 +- .../{ => victory_assets}/animals/penguin.png | Bin .../animals/penguin.png.import | 6 +- .../animals/pink_jellyfish.png | Bin .../animals/pink_jellyfish.png.import | 6 +- .../animals/red_parakeet.png | Bin .../animals/red_parakeet.png.import | 6 +- .../{ => victory_assets}/animals/turtle.png | Bin .../animals/turtle.png.import | 6 +- .../animals/yellow_parakeet.png | Bin .../animals/yellow_parakeet.png.import | 6 +- assets/lesson_screen/bottom.png | Bin 11678 -> 0 bytes assets/lesson_screen/branches.png | Bin 40124 -> 0 bytes assets/lesson_screen/top_left.png | Bin 11949 -> 0 bytes assets/lesson_screen/top_right.png | Bin 11870 -> 0 bytes resources/gardens/garden.gd | 8 + resources/gardens/garden_01.tscn | 7 +- resources/gardens/garden_02.tscn | 7 +- resources/gardens/garden_03.tscn | 7 +- resources/gardens/garden_04.tscn | 7 +- resources/gardens/garden_05.tscn | 7 +- resources/gardens/garden_06.tscn | 7 +- resources/gardens/garden_07.tscn | 7 +- resources/gardens/garden_08.tscn | 7 +- resources/gardens/garden_09.tscn | 7 +- resources/gardens/garden_10.tscn | 7 +- resources/gardens/garden_11.tscn | 7 +- resources/gardens/garden_12.tscn | 7 +- resources/shaders/grayscale.gdshader | 7 + resources/shaders/grayscale.gdshader.uid | 1 + resources/user/student_progression.gd | 181 ++++++--- sources/gardens/boss_button.tscn | 2 + sources/gardens/gardens.gd | 369 ++++++++++++++---- sources/gardens/gardens.tscn | 215 +++------- sources/gardens/minigame_layout.gd | 23 -- sources/gardens/minigame_layout.gd.uid | 1 - sources/gardens/minigame_wedge.gd | 61 +++ sources/gardens/minigame_wedge.gd.uid | 1 + sources/gardens/minigame_wedge.tscn | 63 +++ sources/utils/autoloads/database.gd | 10 +- 91 files changed, 1322 insertions(+), 408 deletions(-) create mode 100644 assets/gardens/animals/ant_body.png rename assets/{lesson_screen/top_right.png.import => gardens/animals/ant_body.png.import} (73%) create mode 100644 assets/gardens/animals/ant_face.png rename assets/{lesson_screen/top_left.png.import => gardens/animals/ant_face.png.import} (73%) create mode 100644 assets/gardens/animals/caterpillar_body.png create mode 100644 assets/gardens/animals/caterpillar_body.png.import create mode 100644 assets/gardens/animals/caterpillar_face.png create mode 100644 assets/gardens/animals/caterpillar_face.png.import create mode 100644 assets/gardens/animals/crab_body.png create mode 100644 assets/gardens/animals/crab_body.png.import create mode 100644 assets/gardens/animals/crab_face.png rename assets/{lesson_screen/bottom.png.import => gardens/animals/crab_face.png.import} (73%) create mode 100644 assets/gardens/animals/frog_body.png rename assets/{lesson_screen/branches.png.import => gardens/animals/frog_body.png.import} (73%) create mode 100644 assets/gardens/animals/frog_face.png create mode 100644 assets/gardens/animals/frog_face.png.import create mode 100644 assets/gardens/animals/jellyfish_body.png create mode 100644 assets/gardens/animals/jellyfish_body.png.import create mode 100644 assets/gardens/animals/jellyfish_face.png create mode 100644 assets/gardens/animals/jellyfish_face.png.import create mode 100644 assets/gardens/animals/monkey_body.png create mode 100644 assets/gardens/animals/monkey_body.png.import create mode 100644 assets/gardens/animals/monkey_face.png create mode 100644 assets/gardens/animals/monkey_face.png.import create mode 100644 assets/gardens/animals/parakeet_body.png create mode 100644 assets/gardens/animals/parakeet_body.png.import create mode 100644 assets/gardens/animals/parakeet_face.png create mode 100644 assets/gardens/animals/parakeet_face.png.import create mode 100644 assets/gardens/animals/penguin_body.png create mode 100644 assets/gardens/animals/penguin_body.png.import create mode 100644 assets/gardens/animals/penguin_face.png create mode 100644 assets/gardens/animals/penguin_face.png.import create mode 100644 assets/gardens/animals/turtle_body.png create mode 100644 assets/gardens/animals/turtle_body.png.import create mode 100644 assets/gardens/animals/turtle_face.png create mode 100644 assets/gardens/animals/turtle_face.png.import create mode 100644 assets/gardens/buttons/movie_icon.png create mode 100644 assets/gardens/buttons/movie_icon.png.import rename assets/gardens/{ => victory_assets}/animals/ant.png (100%) rename assets/gardens/{ => victory_assets}/animals/ant.png.import (76%) rename assets/gardens/{ => victory_assets}/animals/caterpillar.png (100%) rename assets/gardens/{ => victory_assets}/animals/caterpillar.png.import (74%) rename assets/gardens/{ => victory_assets}/animals/crab.png (100%) rename assets/gardens/{ => victory_assets}/animals/crab.png.import (76%) rename assets/gardens/{ => victory_assets}/animals/frog.png (100%) rename assets/gardens/{ => victory_assets}/animals/frog.png.import (76%) rename assets/gardens/{ => victory_assets}/animals/jellyfish.png (100%) rename assets/gardens/{ => victory_assets}/animals/jellyfish.png.import (75%) rename assets/gardens/{ => victory_assets}/animals/khaki_turtle.png (100%) rename assets/gardens/{ => victory_assets}/animals/khaki_turtle.png.import (74%) rename assets/gardens/{ => victory_assets}/animals/monkey.png (100%) rename assets/gardens/{ => victory_assets}/animals/monkey.png.import (75%) rename assets/gardens/{ => victory_assets}/animals/penguin.png (100%) rename assets/gardens/{ => victory_assets}/animals/penguin.png.import (75%) rename assets/gardens/{ => victory_assets}/animals/pink_jellyfish.png (100%) rename assets/gardens/{ => victory_assets}/animals/pink_jellyfish.png.import (73%) rename assets/gardens/{ => victory_assets}/animals/red_parakeet.png (100%) rename assets/gardens/{ => victory_assets}/animals/red_parakeet.png.import (74%) rename assets/gardens/{ => victory_assets}/animals/turtle.png (100%) rename assets/gardens/{ => victory_assets}/animals/turtle.png.import (75%) rename assets/gardens/{ => victory_assets}/animals/yellow_parakeet.png (100%) rename assets/gardens/{ => victory_assets}/animals/yellow_parakeet.png.import (73%) delete mode 100644 assets/lesson_screen/bottom.png delete mode 100644 assets/lesson_screen/branches.png delete mode 100644 assets/lesson_screen/top_left.png delete mode 100644 assets/lesson_screen/top_right.png create mode 100644 resources/shaders/grayscale.gdshader create mode 100644 resources/shaders/grayscale.gdshader.uid delete mode 100644 sources/gardens/minigame_layout.gd delete mode 100644 sources/gardens/minigame_layout.gd.uid create mode 100644 sources/gardens/minigame_wedge.gd create mode 100644 sources/gardens/minigame_wedge.gd.uid create mode 100644 sources/gardens/minigame_wedge.tscn diff --git a/assets/gardens/animals/ant_body.png b/assets/gardens/animals/ant_body.png new file mode 100644 index 0000000000000000000000000000000000000000..e5f317852ada914148d0c7e4f51be4cde59c635a GIT binary patch literal 2841 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 literal 0 HcmV?d00001 diff --git a/assets/lesson_screen/top_left.png.import b/assets/gardens/animals/ant_face.png.import similarity index 73% rename from assets/lesson_screen/top_left.png.import rename to assets/gardens/animals/ant_face.png.import index 7f8ebbf4..1cf6d29f 100644 --- a/assets/lesson_screen/top_left.png.import +++ b/assets/gardens/animals/ant_face.png.import @@ -2,16 +2,16 @@ importer="texture" type="CompressedTexture2D" -uid="uid://dkomjpclxvmqf" -path="res://.godot/imported/top_left.png-2ca3f2b1716a8a640fa40c3a481bc4d9.ctex" +uid="uid://by3xfdin7jrsn" +path="res://.godot/imported/ant_face.png-b00fa29a7fcfe1e19ec19735f3395466.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/lesson_screen/top_left.png" -dest_files=["res://.godot/imported/top_left.png-2ca3f2b1716a8a640fa40c3a481bc4d9.ctex"] +source_file="res://assets/gardens/animals/ant_face.png" +dest_files=["res://.godot/imported/ant_face.png-b00fa29a7fcfe1e19ec19735f3395466.ctex"] [params] diff --git a/assets/gardens/animals/caterpillar_body.png b/assets/gardens/animals/caterpillar_body.png new file mode 100644 index 0000000000000000000000000000000000000000..4e5e48971d64fd3265efac7eba020901fac68edf GIT binary patch literal 2890 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 literal 0 HcmV?d00001 diff --git a/assets/gardens/animals/caterpillar_body.png.import b/assets/gardens/animals/caterpillar_body.png.import new file mode 100644 index 00000000..2c501777 --- /dev/null +++ b/assets/gardens/animals/caterpillar_body.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b6nrx0dn0h3f2" +path="res://.godot/imported/caterpillar_body.png-c691b990e51d372f5dfdafa881ea6750.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/gardens/animals/caterpillar_body.png" +dest_files=["res://.godot/imported/caterpillar_body.png-c691b990e51d372f5dfdafa881ea6750.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/gardens/animals/caterpillar_face.png b/assets/gardens/animals/caterpillar_face.png new file mode 100644 index 0000000000000000000000000000000000000000..4f0706166296c23d1ed5ec63ee7bbedb2670e342 GIT binary patch literal 806 zcmeAS@N?(olHy`uVBq!ia0vp^r9kY@!3HF+KJ6+8Qk(@Ik;M!Q+(IDCc$cQX8R4lw1R>_u0oBYdqw{@SnOnVabNgD zoMpH5j@JPNJAJKH9w}UL6c<0+D7It|U+2Rs$AYpve|-FXpjqYp)4~s5`%X97Dzf;T z?)H;!u(fv=eX^oSCUnALuA&gfKCKghtd^@3$Pg^+mrP*i*jdP-!~FNaZ?n(yZHUS$e^Rz?E=H}*!)z#KLeSO=Gefd(dB5d`;Z{N&fVq#j7Hdf@<<>tP9 z_jQX`kM9Y?Qg9JTFJn}tgQe4G2`v| zTm811_*&ZAFOSgK78|oRY-NbnlFVNjdZ&#pnJf*^_~G+*!{y!Lfg*oDr=7Lclij+R z?|qz#r<2Taf4zCLW>u9$?h`(4=s78dvAyqBFMm`Z_IKBmvip{tLc$+OEs6sjy(N4}7I| z`mEuf2cPv1q(5NpeZJ@CPi?8`cT#8da~urZebJ-X;W1C1dA;X5H|_I*tUup{Q=AxZ drltK1r(QAMUSX(v8<_AJJYD@<);T3K0RRy&aX0_~ literal 0 HcmV?d00001 diff --git a/assets/gardens/animals/caterpillar_face.png.import b/assets/gardens/animals/caterpillar_face.png.import new file mode 100644 index 00000000..f83f9ca2 --- /dev/null +++ b/assets/gardens/animals/caterpillar_face.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cnihbmks0piwi" +path="res://.godot/imported/caterpillar_face.png-d383b965d4555da185ab647f352d95f3.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/gardens/animals/caterpillar_face.png" +dest_files=["res://.godot/imported/caterpillar_face.png-d383b965d4555da185ab647f352d95f3.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/gardens/animals/crab_body.png b/assets/gardens/animals/crab_body.png new file mode 100644 index 0000000000000000000000000000000000000000..656f8af6e22b6679be331cf056e6b779f1e2b889 GIT binary patch literal 2253 zcmV;;2r~DHP)Oaf z1?avm(0%P?S69Y;fG7`8zy-Q)>Fx*D0u(iys4|QcapIVw6U34niCxUl9?|>~$r(`; ze}DjsrVfYv^UTNL%;AD<+bGBv%V`*)lnP2BmZtKovk839sWqQctCn z8UUX0uNHs`A;d^zbdI2uJ_K-pn`;OFhlCJ4uFXWEQc5)d|MmFS?+76Wu?^1&Tu=kR zmdC%>2_fA$b{CTr3P8nYd!16cozV6?Z~$*X0oI(wBB`i5KHE!RZ9{<%ybXO8u#2C= zgc4g+?unZLyKGTPt8wk;8D8!BIfR2A*M1UDtwz`^|?rL=kUI)L9#c(4LByrPu8a&2n>5Can({xJw4#xfsv6oRUwlY$L* zz`|*xcPORXizyu>2t%^{nSuxEElK7}0IG{T_%7=pRuSCy#E@wF$m#vc3ceRXeQ)ZL z>{^7714qPln<~^2Ft2sv^#+?x5oy{m?JW7pRJb_gL|pMb_BGa|OZqAw4T ztx)3;ZU+8FlppYG+QImfnFg2`T}tT=fS+QN6bZXHbUTkrsnJ1XS-wn_*&;!m@75zUz_uxniNn(`7l zM~OG=I{%0ro-WwQ7|xx-3%`rtCphl8H#(x|6|SBc=2Jzzd(>j0wcWt>E_c z2G~twgw=M5XA=UE#dLT{2&sd4W*zwu)6F5+1Odkby(Z_mvB0K=CZ1T3bdHjP*dYpI z2dtVsLOulr*m?Z|cCJx7h$R4jobYLxC#g*4o&-(Pwji`G!{HE1OG~PYp^Bd#KYskR z-EL3vn^@CAMbh$A9TDQknx>&#E?XxyYIPsvT;a7 zR9+AbtS#|mV`F1XPyo2NxPWcj==FLS4u@$JC6koPWrPT80eJ32gp!g zNp=e&Aah7lBs~mg=7uzB&GyeLGS<=nkSnSo(RLm%WEn0*ogUJbdCGpC+CdRn^1{O8 z2|Xesdq`84Y=2gfx&lzPr+O_6ns+R)@SwDLv9dk2iy}Xvn;Ikv3dr|V2Lt(CVlfE~ zC|H)MO4OnnX4URC6hzxp#eTbpxHKb=n5Oyd%a<=dLQ(ism8Uvv_xt^S-@SYHfy#qU zle4q4%j4tYH3%!mWgk=NQyNO?cC*=h@c#Y#x$sy)P=KwDH&kS*Q6?&1kzNCU48Ujc9VOE=ALUh8A3+^nq_MC#2qmKO^Z~bqG^S}jYBrlz zo|Z9&2}>KlOQ_xq(*t970SVf+35mtL>;GQzH#JY~HUq>IYi(!dltgTdfr zFc|zzSmHNxoSmIrHk-`{r>CcD0HO$6l~ooMo*H&XHUQ|YR%^N0Z1%o=`=+2s>Efz# zUx6hl2@}>Y1y5pBh^hzt&q;Zw19)NE_UhZWZ!c#_Sf4hu&eIA73M;F_q(W4`Sf`l7 zuk+UUv9*&z^CXh3)lv|2a81ISJXVq0KWz?T5pw!Lq@BE{?l0Sv@j9;Ffp8m7h zY-Yk^+wJzbX_}7!{0hL&2+xl^*2Cq(?t!J**&~EVnbxBEDa{xG*)^R^(+1e^U~^$% z;qu9oCu{fa-BVXU0YOlaKY_nP9R5R;-=>kpY!arumd2~2;8f8EVD0TDFx@uRM^J#j z_<;~ofq$E+{QUvb7FBb7cc%`oivM(kRhi2$Kv017+ADx>n+Zr-gBrxNMKy%K-JK}U z*Lm8uz4q?iJAD59S$g5VfB)X>cDw%z+3mXb?jx*`a`Sn7dM*szlrhzgQV^6<1O77*o$TJgP2T-9 zVyVYq%OPqI<`W68V)1)0@jOefKby9v1`$P2fb~2pV9NrNel)P!qaz-WN4|9Ud#oPy zq*Rb)QN3^rs*DK2W`-<_>Yki7H9;K$gw0fH@hpp~gGF8r!P>0)R7=AVgxv=#+rF&G bP+a~GuQh^Ny0-D~00000NkvXXu0mjf;&(k> literal 0 HcmV?d00001 diff --git a/assets/gardens/animals/crab_body.png.import b/assets/gardens/animals/crab_body.png.import new file mode 100644 index 00000000..90ea3770 --- /dev/null +++ b/assets/gardens/animals/crab_body.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b2e61oot7ht35" +path="res://.godot/imported/crab_body.png-d5ff5fcdad64e46336ef16b4a3fb00c7.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/gardens/animals/crab_body.png" +dest_files=["res://.godot/imported/crab_body.png-d5ff5fcdad64e46336ef16b4a3fb00c7.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/gardens/animals/crab_face.png b/assets/gardens/animals/crab_face.png new file mode 100644 index 0000000000000000000000000000000000000000..cdc629c565471b42cbc77170e48202a5ff3a7727 GIT binary patch literal 1005 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 literal 0 HcmV?d00001 diff --git a/assets/lesson_screen/branches.png.import b/assets/gardens/animals/frog_body.png.import similarity index 73% rename from assets/lesson_screen/branches.png.import rename to assets/gardens/animals/frog_body.png.import index 6f76bd84..fb0dab24 100644 --- a/assets/lesson_screen/branches.png.import +++ b/assets/gardens/animals/frog_body.png.import @@ -2,16 +2,16 @@ importer="texture" type="CompressedTexture2D" -uid="uid://cffuqacgb1jra" -path="res://.godot/imported/branches.png-59c95c0c624c68eb2181d2b0fe6a5080.ctex" +uid="uid://oagcnmxs0xx1" +path="res://.godot/imported/frog_body.png-ac6c4a085cb17c6bc169773a464b64b6.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/lesson_screen/branches.png" -dest_files=["res://.godot/imported/branches.png-59c95c0c624c68eb2181d2b0fe6a5080.ctex"] +source_file="res://assets/gardens/animals/frog_body.png" +dest_files=["res://.godot/imported/frog_body.png-ac6c4a085cb17c6bc169773a464b64b6.ctex"] [params] diff --git a/assets/gardens/animals/frog_face.png b/assets/gardens/animals/frog_face.png new file mode 100644 index 0000000000000000000000000000000000000000..4c249c47781a717d1c12c7f290c112374d676bef GIT binary patch literal 1707 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 MPgg&ebxsLQ0BTzNpa1{> literal 0 HcmV?d00001 diff --git a/assets/gardens/animals/jellyfish_face.png.import b/assets/gardens/animals/jellyfish_face.png.import new file mode 100644 index 00000000..9f3ecb32 --- /dev/null +++ b/assets/gardens/animals/jellyfish_face.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dppmdv8u3cwl1" +path="res://.godot/imported/jellyfish_face.png-5c0a129760def337aa729a02e1028153.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/gardens/animals/jellyfish_face.png" +dest_files=["res://.godot/imported/jellyfish_face.png-5c0a129760def337aa729a02e1028153.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/gardens/animals/monkey_body.png b/assets/gardens/animals/monkey_body.png new file mode 100644 index 0000000000000000000000000000000000000000..bc059f3515380a6af93d58df90653db6b99a8888 GIT binary patch literal 3817 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 literal 0 HcmV?d00001 diff --git a/assets/gardens/animals/monkey_body.png.import b/assets/gardens/animals/monkey_body.png.import new file mode 100644 index 00000000..62f624ab --- /dev/null +++ b/assets/gardens/animals/monkey_body.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dr12efhuotfgt" +path="res://.godot/imported/monkey_body.png-b049cc78b0f6869945a1c7d6a1301ad4.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/gardens/animals/monkey_body.png" +dest_files=["res://.godot/imported/monkey_body.png-b049cc78b0f6869945a1c7d6a1301ad4.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/gardens/animals/monkey_face.png b/assets/gardens/animals/monkey_face.png new file mode 100644 index 0000000000000000000000000000000000000000..769b99080b555569da80d3d7d7b1c65048f06dd8 GIT binary patch literal 1080 zcmeAS@N?(olHy`uVBq!ia0vp^r9hm*!3HFE^wl>3Db50q$YKTtZXpn6ymYtj4+8`9 zD^C~4kcv5PZ}0b3u9P|UF}*+g@lW}luM!8H4BR4u)UI-IZ4+C@f9&72xX%9$2Xs}r z;xcv4+*E07E$&_-=JV>b&%cKBZi~fk<~el-QsnIQe{7QaG?DZD+<3J*CCxG$oKVGQ?3VbOOc93-bf>5A^6TMX+9AF0g;7!*C^ShwsGB-}7c2RCx5CA&>D- zyW@@Z5=W#`MGsum1VXIvyeOD2$ zH{9*DDSTx}+}X6vk#X_ylT+Tmv<%#Ttn=FP8UHR8vK`3Po9?{*cI)e1A8O^_mPs>A z@K7nJtK+*~x}Wie^sHEx4*@!2|99=#~x4gN1dRrRz*Q&XFk2hS*XxS_-F8(mbXy%gVl`1<; z+1Ho85xrjgYP#1_rt75>JyZ^{o12*(TEF{l-iGICZE4$AUDb-Ye)QL`svi%&eJlG> zy8piW)~MQiGqFcfq6`my|9fAv-^Av6*47IzOD??se)#yVyYE&%FR_wUSk`_&!aaBU zZ3`P4m(4eioIT6ibySI~l}SuYEY5DNxy|-HdwA}D57ZI6m}3S+ff^zOMMXmA?EYH6 zdwa2_y_jo5hXAO@~t- zOI?gJ1wLVInRfm;P=8w)d);d9Z<_mRR@0B7ubv_&e P76lBRu6{1-oD!M00009a7bBm000XT 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 literal 0 HcmV?d00001 diff --git a/assets/gardens/animals/parakeet_face.png.import b/assets/gardens/animals/parakeet_face.png.import new file mode 100644 index 00000000..048af348 --- /dev/null +++ b/assets/gardens/animals/parakeet_face.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://l52tfb7fdrpt" +path="res://.godot/imported/parakeet_face.png-94d7bc7370d8ae647ca7d22a41893e3f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/gardens/animals/parakeet_face.png" +dest_files=["res://.godot/imported/parakeet_face.png-94d7bc7370d8ae647ca7d22a41893e3f.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/gardens/animals/penguin_body.png b/assets/gardens/animals/penguin_body.png new file mode 100644 index 0000000000000000000000000000000000000000..1d7fda19e656e0c46fb799da847ad75de619f4d7 GIT binary patch literal 2758 zcmb_e`8(8$7ygVdu4V?4Jq9Bp!XQM;m9b=vL5i46VuqF}*#^TTOO_Gc>`WOE2FZGD z5jT@PAQWRa960vS%;_-zK!pBn(AV+M0{{RAnj0HB1ZJ&d_xg;Q$uOGu6rjW8nU{25 zvrhyVVHVW#r(wg~C8$0N+h7Ch6^^$F9{XgYk$w&#c)4T)u%Crj?+G#7PRK(nN1rMP z{=*kBaD?BppUr@pjT>wZvWCW+QtB+R61Sxg5x&!5n9=G>B3_WY7DaIueEPg!{`eAW zAPJfut|lpWooWPrNmRKS#+S_^-2#IeDkRS0zyFU-fUf()yU^!pjO{)fFsqcom zM_*#9F6vXG$0K?($DBqz(fuvzK-QX8I1f|RTT;B;7H41hOqa~_$b!wc6yR?<{1C|_ zV*V!#brtZPZaT*kyBAwf^7{^R`x>^D`~7=b+xKCUm&YuY*dkL9vJClqzBOY2uZM-R5)%@_Kr|A~hYS8DM_UlW}N^eDg3 zmD0)~ykC+v6)criGPW0M?L#9!4`c?ZtipnIW^tpk;rs{272bgE)Ko*_;n<{xLZ1jIx2kQ9P<08{&1J$ zCl_Pi?l|N!El{Amq)yvY#Pp6Z$EiW!t)P0k-t0n&%PX|Xbl$Abi4>0)nx#otQyaMG|A=14fzzaWB@n4X#fQRilrb=SU~RWU6k|9XmZ zEndh=@xT%Yf+-$q2kIYxk@OOtw%>WtsnM_fzP>&#J3D(I$Uh+9c$8e*j3%eT5jWn( zs_Vsc=;Rvn)uP%2USK8gRn8FPx)#UQG`G*0%DkuBhu8jAqy#mBMjQQITHoUpHlu0H zD6yt&)Ti^1)}}v=hI1t`q~Y+_j&zTrx!KOtyAUvtXLoFWe?NUO{YfV~3U@`hU(kYE z$NFr535Qtmmzwnr+MJL6}I|9Qa`{|oePH5q-Z zI<2kod$K;Jv)m_gOgqJO{u-u1z1#EbQjTK6d^yRb5iZ3nl23R+qWvu1j zd*7pOF0T?7*P!~(SAnKx=cXrxHS0otv)S#_Cy{3Y(#6G}_zS=I149D`*I|F{O&pzp&}F38Oenos;v*bT0Yka{4N&WT~!9^~{hk#0jsP$w?)3 zF2|9c7lrBFc=-6Sy!EhkqMZXm=-b9cj(ZOYLmy15%&m}!dSaUUeltJaO3^YCoMa{* zic7*GUPX0Pn=cgt^$JbgzCNYGn#PqpmSH1?c5xjl8}cBQty_)|>N8&-#B(k# zvWzGihuNQK+k)TFLRDHl2>TcyZ7dk6G<3nqp)T!h8+9a7>@UU08Z=QzXLZ?gi7eOK#d5A*PkOVNG~LQ2-IKsW~CgQxy}DNZZ1HJs~%0n0tlZY_XhE z=Pn`n0l6Lrw^e3)+Rz;uZf3xjC z9>>g@D4$fJB%@M4S`N?~lsd|Lf2m?6#A-*<-i69HzV#dz&QjtbXy<1ukpC($Y3cSo zpRCR;KBil5(;n{-=>IabH<)I%Pul-*OFL*&IsFCL2E9+T$+A-X3MIf9%07ETfgr7X zwn)_%p~{+?n#$$RlsTf!e%@R}r&hz5G3EN}9_et`A+;bw2xnhXE`1Ibv2r@b`eB46 zhz@#5QcO)U$;gW+WV6#i;K%u~nMwp7C;hFLI_KFh57*>5F^|+v zkF@+i`5ct|Af1^`FfqzPxgVy_H*4KqEsc4=Bq z;D7guxZKktkkS3q0Mi(>g;Z=Sj?tzG@IHME7`zL{)Q_7sV%~aQfpPB~{tl*M*7z>Z ztuSj)Mo5Ht=6MNdPoj}6qN7_Zq~T6NRybE*V7-9^Gy>}Gd0c(bO=BL|x$!2R$-Jp@ zER^vmHsR*YNo`ymbcz<d7szA6ZK<23U>d4C51!M6>^1f1)lPTN{1}b!;l&rp1D2Capd~#UuIL=&~+gD Yr`pm^yUs5s&SMIgn_M+6MY)Cl7m&av`~Uy| literal 0 HcmV?d00001 diff --git a/assets/gardens/animals/penguin_body.png.import b/assets/gardens/animals/penguin_body.png.import new file mode 100644 index 00000000..76a24047 --- /dev/null +++ b/assets/gardens/animals/penguin_body.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://noekve4gjudr" +path="res://.godot/imported/penguin_body.png-72481c56dc380b551e94e0f413ef0cf8.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/gardens/animals/penguin_body.png" +dest_files=["res://.godot/imported/penguin_body.png-72481c56dc380b551e94e0f413ef0cf8.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/gardens/animals/penguin_face.png b/assets/gardens/animals/penguin_face.png new file mode 100644 index 0000000000000000000000000000000000000000..ad9453a220a358f8f33c78290e83d5c426385994 GIT binary patch literal 1145 zcmeAS@N?(olHy`uVBq!ia0vp^r9eD^gAGWU^{Vs&Db50q$YKTtZXpn6ymYtj4+8^> zwx^3@NX4ADclKv5E@e3W@q1^nH2e1F29?|VUMehUE@)>Iw2E06`DEI+Kg??qc8M;& zdui!hmG0*cBz9_)OiGYx@w=qMu2mClIH$S$t>qnsD~ji3Gk+=bs!f0X^UiZq)BDdk z@3-%(ocH{X_L#k9-f*%w#IaB7L?El>Dg}4ZCo7s{LMJTdDx!|yUc1-K zJ31};K0EN9PVYKd(E@u;x`zIP6lYVY_RU#x$I%st^d~EGRM0e*k{P!Dq+%T z6X;X7xi9tM!zADPZ31Cxme;qWJp8nq`%Ji&=(q3RXU?8oZD%(>XZDOIT^|Gz($m|$ zmKyE&87E}(HAvR9@3BmQdY96xuU6dL+&Q_qyzh$g4+XDd2+r-g>^1AxZ{EAt_Uz9hhO=ptgI2N}IC$`2>)XufuZ&Gw3OxSb^W1zh zrLuD7<;%fRy=;LZjDPGNYVyzjAFwuTW!P$$K$pcAcWkgdyJ#sBa z&}j*n{h_Aa;p3#A%QhLzZoA^n+VQwT{6|Jcg?`Hh!&kfCIvKLxVHJBhKXdM+rx^*C#=LbZWUVMUt0&*jH9K@=oW@`O#Z6b^jyaxbO1bi6)9-5?cc0yE zP14=@+-u^lKijyEy8cRkG1qWk+2ZP)X(wEKo62_l==-tk+bQ?E6IZ{~3Fx|&_<*PO z^WO5Ee;@pt`rH1s?Zc1i(T5MW0-ahRb^N>0(!Zt;EzZRj<=gK#FTHg8`g^-s62EiL z`#O)O@7c@$k@}aXhDS*c_wV1lLrcY5-mUzQwDF6m^ZPva53kI*CvErC{&N3k z+_ybdPW4OgFhyP8%Y9Di|T|nRhwM??&VT@RYP}*&O_>^V_M`5^3D9u Zm@ogU#Gs|ArVor>faFqB0#AAz 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 XNg_nyIJXCAp@Otvx@wgwmSO(~TETf( literal 0 HcmV?d00001 diff --git a/assets/gardens/animals/turtle_body.png.import b/assets/gardens/animals/turtle_body.png.import new file mode 100644 index 00000000..03587e45 --- /dev/null +++ b/assets/gardens/animals/turtle_body.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b7rqldqdft30a" +path="res://.godot/imported/turtle_body.png-0f50da4036c6750167a288e6f006a813.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/gardens/animals/turtle_body.png" +dest_files=["res://.godot/imported/turtle_body.png-0f50da4036c6750167a288e6f006a813.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/gardens/animals/turtle_face.png b/assets/gardens/animals/turtle_face.png new file mode 100644 index 0000000000000000000000000000000000000000..95f4e78926e48162053fda24dcce42b49e8f00f3 GIT binary patch literal 917 zcmeAS@N?(olHy`uVBq!ia0vp^r9eE7gAGXXw7dQVQk(@Ik;M!Q+(IDCc`Qm5#82AuC-wJnmG{f%{IxteJARvNy2MWVr*GH;uit*Z zTt$EVx^91c)HJ47AJbCi$oz~XYkNam=GyVTBA78pBXtw93 zy?f`ztvBB{X_CtG=g&PqDII=)WdBzy&u`zpU3&d>)22;Dn;(DpP_SoC%Dd*(kDG(+ zJ@xeTHtpYEpYFc+qJ;i_UxV)^o_hNF$G3ly{`~oKx!v!Ts~=CTn)Rf5`|Z85hHuNP zy}i9pepr|`Y4UylqCLBI%_`enyLscqj3u|~7&m<_FrP7a My85}Sb4q9e0EU{5mjD0& literal 0 HcmV?d00001 diff --git a/assets/gardens/animals/turtle_face.png.import b/assets/gardens/animals/turtle_face.png.import new file mode 100644 index 00000000..7fcd487d --- /dev/null +++ b/assets/gardens/animals/turtle_face.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://nu4kpbywwpgn" +path="res://.godot/imported/turtle_face.png-e570d8d931a8a1c99178dba731ef0fdb.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/gardens/animals/turtle_face.png" +dest_files=["res://.godot/imported/turtle_face.png-e570d8d931a8a1c99178dba731ef0fdb.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/gardens/buttons/movie_icon.png b/assets/gardens/buttons/movie_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..52bfb441f69e504ad74182b95956f74a33ad117a GIT binary patch literal 2388 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 S^Mz(j0*4PBbGhlvVE-GAWlNv{ literal 0 HcmV?d00001 diff --git a/assets/gardens/buttons/movie_icon.png.import b/assets/gardens/buttons/movie_icon.png.import new file mode 100644 index 00000000..fb379f4b --- /dev/null +++ b/assets/gardens/buttons/movie_icon.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c1ml42sp1vqga" +path="res://.godot/imported/movie_icon.png-3b93e2f2cfeeb8eec0332bbcd7cda143.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/gardens/buttons/movie_icon.png" +dest_files=["res://.godot/imported/movie_icon.png-3b93e2f2cfeeb8eec0332bbcd7cda143.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/gardens/animals/ant.png b/assets/gardens/victory_assets/animals/ant.png similarity index 100% rename from assets/gardens/animals/ant.png rename to assets/gardens/victory_assets/animals/ant.png diff --git a/assets/gardens/animals/ant.png.import b/assets/gardens/victory_assets/animals/ant.png.import similarity index 76% rename from assets/gardens/animals/ant.png.import rename to assets/gardens/victory_assets/animals/ant.png.import index 7e989d6f..b6c20ad1 100644 --- a/assets/gardens/animals/ant.png.import +++ b/assets/gardens/victory_assets/animals/ant.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://cn0brlkbklxuu" -path="res://.godot/imported/ant.png-a1470874074de10588ffd54aa0bc8a95.ctex" +path="res://.godot/imported/ant.png-d3fdfb32e41ad1bbed889f9d21d54167.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/gardens/animals/ant.png" -dest_files=["res://.godot/imported/ant.png-a1470874074de10588ffd54aa0bc8a95.ctex"] +source_file="res://assets/gardens/victory_assets/animals/ant.png" +dest_files=["res://.godot/imported/ant.png-d3fdfb32e41ad1bbed889f9d21d54167.ctex"] [params] diff --git a/assets/gardens/animals/caterpillar.png b/assets/gardens/victory_assets/animals/caterpillar.png similarity index 100% rename from assets/gardens/animals/caterpillar.png rename to assets/gardens/victory_assets/animals/caterpillar.png diff --git a/assets/gardens/animals/caterpillar.png.import b/assets/gardens/victory_assets/animals/caterpillar.png.import similarity index 74% rename from assets/gardens/animals/caterpillar.png.import rename to assets/gardens/victory_assets/animals/caterpillar.png.import index 03a5ca20..60f51eb1 100644 --- a/assets/gardens/animals/caterpillar.png.import +++ b/assets/gardens/victory_assets/animals/caterpillar.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://ixkyfsxu07qx" -path="res://.godot/imported/caterpillar.png-03f6801670b49c8e0cea7190046ee5e8.ctex" +path="res://.godot/imported/caterpillar.png-606aeb5ed693d22c4a80f41968e1d449.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/gardens/animals/caterpillar.png" -dest_files=["res://.godot/imported/caterpillar.png-03f6801670b49c8e0cea7190046ee5e8.ctex"] +source_file="res://assets/gardens/victory_assets/animals/caterpillar.png" +dest_files=["res://.godot/imported/caterpillar.png-606aeb5ed693d22c4a80f41968e1d449.ctex"] [params] diff --git a/assets/gardens/animals/crab.png b/assets/gardens/victory_assets/animals/crab.png similarity index 100% rename from assets/gardens/animals/crab.png rename to assets/gardens/victory_assets/animals/crab.png diff --git a/assets/gardens/animals/crab.png.import b/assets/gardens/victory_assets/animals/crab.png.import similarity index 76% rename from assets/gardens/animals/crab.png.import rename to assets/gardens/victory_assets/animals/crab.png.import index 0594a3a5..05289d22 100644 --- a/assets/gardens/animals/crab.png.import +++ b/assets/gardens/victory_assets/animals/crab.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://d3vt2qpngkkjs" -path="res://.godot/imported/crab.png-0a38ba7f13130791be164b6db99b3bb7.ctex" +path="res://.godot/imported/crab.png-6b9401bccc35a6e58de3bee1aa707608.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/gardens/animals/crab.png" -dest_files=["res://.godot/imported/crab.png-0a38ba7f13130791be164b6db99b3bb7.ctex"] +source_file="res://assets/gardens/victory_assets/animals/crab.png" +dest_files=["res://.godot/imported/crab.png-6b9401bccc35a6e58de3bee1aa707608.ctex"] [params] diff --git a/assets/gardens/animals/frog.png b/assets/gardens/victory_assets/animals/frog.png similarity index 100% rename from assets/gardens/animals/frog.png rename to assets/gardens/victory_assets/animals/frog.png diff --git a/assets/gardens/animals/frog.png.import b/assets/gardens/victory_assets/animals/frog.png.import similarity index 76% rename from assets/gardens/animals/frog.png.import rename to assets/gardens/victory_assets/animals/frog.png.import index 3515a96d..f5ebc738 100644 --- a/assets/gardens/animals/frog.png.import +++ b/assets/gardens/victory_assets/animals/frog.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://yo3o4m6o7a0" -path="res://.godot/imported/frog.png-dbd41735c012909d9c488ecbaa029907.ctex" +path="res://.godot/imported/frog.png-50e8b0bcbd5c11e9fc83314d35821855.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/gardens/animals/frog.png" -dest_files=["res://.godot/imported/frog.png-dbd41735c012909d9c488ecbaa029907.ctex"] +source_file="res://assets/gardens/victory_assets/animals/frog.png" +dest_files=["res://.godot/imported/frog.png-50e8b0bcbd5c11e9fc83314d35821855.ctex"] [params] diff --git a/assets/gardens/animals/jellyfish.png b/assets/gardens/victory_assets/animals/jellyfish.png similarity index 100% rename from assets/gardens/animals/jellyfish.png rename to assets/gardens/victory_assets/animals/jellyfish.png diff --git a/assets/gardens/animals/jellyfish.png.import b/assets/gardens/victory_assets/animals/jellyfish.png.import similarity index 75% rename from assets/gardens/animals/jellyfish.png.import rename to assets/gardens/victory_assets/animals/jellyfish.png.import index ec121f88..1a2acb72 100644 --- a/assets/gardens/animals/jellyfish.png.import +++ b/assets/gardens/victory_assets/animals/jellyfish.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://bfqwlmmliem8f" -path="res://.godot/imported/jellyfish.png-354519775b79ac38eb7fb5b2e6d6f3a9.ctex" +path="res://.godot/imported/jellyfish.png-fef4023badc953c6e37065baefef9dda.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/gardens/animals/jellyfish.png" -dest_files=["res://.godot/imported/jellyfish.png-354519775b79ac38eb7fb5b2e6d6f3a9.ctex"] +source_file="res://assets/gardens/victory_assets/animals/jellyfish.png" +dest_files=["res://.godot/imported/jellyfish.png-fef4023badc953c6e37065baefef9dda.ctex"] [params] diff --git a/assets/gardens/animals/khaki_turtle.png b/assets/gardens/victory_assets/animals/khaki_turtle.png similarity index 100% rename from assets/gardens/animals/khaki_turtle.png rename to assets/gardens/victory_assets/animals/khaki_turtle.png diff --git a/assets/gardens/animals/khaki_turtle.png.import b/assets/gardens/victory_assets/animals/khaki_turtle.png.import similarity index 74% rename from assets/gardens/animals/khaki_turtle.png.import rename to assets/gardens/victory_assets/animals/khaki_turtle.png.import index 73273f66..681d5646 100644 --- a/assets/gardens/animals/khaki_turtle.png.import +++ b/assets/gardens/victory_assets/animals/khaki_turtle.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://6bosyi1wv8vu" -path="res://.godot/imported/khaki_turtle.png-365be2d89ffda872bfafc7a90e7d6e36.ctex" +path="res://.godot/imported/khaki_turtle.png-c9b0e5c5db5d16603c89e5aede131fd5.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/gardens/animals/khaki_turtle.png" -dest_files=["res://.godot/imported/khaki_turtle.png-365be2d89ffda872bfafc7a90e7d6e36.ctex"] +source_file="res://assets/gardens/victory_assets/animals/khaki_turtle.png" +dest_files=["res://.godot/imported/khaki_turtle.png-c9b0e5c5db5d16603c89e5aede131fd5.ctex"] [params] diff --git a/assets/gardens/animals/monkey.png b/assets/gardens/victory_assets/animals/monkey.png similarity index 100% rename from assets/gardens/animals/monkey.png rename to assets/gardens/victory_assets/animals/monkey.png diff --git a/assets/gardens/animals/monkey.png.import b/assets/gardens/victory_assets/animals/monkey.png.import similarity index 75% rename from assets/gardens/animals/monkey.png.import rename to assets/gardens/victory_assets/animals/monkey.png.import index 703e3d6b..bfddf5ff 100644 --- a/assets/gardens/animals/monkey.png.import +++ b/assets/gardens/victory_assets/animals/monkey.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://kygm5ieixgne" -path="res://.godot/imported/monkey.png-723d94951cc580ff3e0ae5233294daa2.ctex" +path="res://.godot/imported/monkey.png-984367ba67c6aee1976b0b6e125be90d.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/gardens/animals/monkey.png" -dest_files=["res://.godot/imported/monkey.png-723d94951cc580ff3e0ae5233294daa2.ctex"] +source_file="res://assets/gardens/victory_assets/animals/monkey.png" +dest_files=["res://.godot/imported/monkey.png-984367ba67c6aee1976b0b6e125be90d.ctex"] [params] diff --git a/assets/gardens/animals/penguin.png b/assets/gardens/victory_assets/animals/penguin.png similarity index 100% rename from assets/gardens/animals/penguin.png rename to assets/gardens/victory_assets/animals/penguin.png diff --git a/assets/gardens/animals/penguin.png.import b/assets/gardens/victory_assets/animals/penguin.png.import similarity index 75% rename from assets/gardens/animals/penguin.png.import rename to assets/gardens/victory_assets/animals/penguin.png.import index 2947a8da..c64d62f4 100644 --- a/assets/gardens/animals/penguin.png.import +++ b/assets/gardens/victory_assets/animals/penguin.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://cy1nrnl520goj" -path="res://.godot/imported/penguin.png-7b214b7f40894092c07f326efebcbe8d.ctex" +path="res://.godot/imported/penguin.png-a3d9b15f5a490402f4093a86cd9fc481.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/gardens/animals/penguin.png" -dest_files=["res://.godot/imported/penguin.png-7b214b7f40894092c07f326efebcbe8d.ctex"] +source_file="res://assets/gardens/victory_assets/animals/penguin.png" +dest_files=["res://.godot/imported/penguin.png-a3d9b15f5a490402f4093a86cd9fc481.ctex"] [params] diff --git a/assets/gardens/animals/pink_jellyfish.png b/assets/gardens/victory_assets/animals/pink_jellyfish.png similarity index 100% rename from assets/gardens/animals/pink_jellyfish.png rename to assets/gardens/victory_assets/animals/pink_jellyfish.png diff --git a/assets/gardens/animals/pink_jellyfish.png.import b/assets/gardens/victory_assets/animals/pink_jellyfish.png.import similarity index 73% rename from assets/gardens/animals/pink_jellyfish.png.import rename to assets/gardens/victory_assets/animals/pink_jellyfish.png.import index 1e8c7730..a61f69ae 100644 --- a/assets/gardens/animals/pink_jellyfish.png.import +++ b/assets/gardens/victory_assets/animals/pink_jellyfish.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://dcuobvoav863b" -path="res://.godot/imported/pink_jellyfish.png-47ea6885f7ba9be8ff5f438c055bc4a1.ctex" +path="res://.godot/imported/pink_jellyfish.png-99508b215ac7a943286e22be8a93bcd0.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/gardens/animals/pink_jellyfish.png" -dest_files=["res://.godot/imported/pink_jellyfish.png-47ea6885f7ba9be8ff5f438c055bc4a1.ctex"] +source_file="res://assets/gardens/victory_assets/animals/pink_jellyfish.png" +dest_files=["res://.godot/imported/pink_jellyfish.png-99508b215ac7a943286e22be8a93bcd0.ctex"] [params] diff --git a/assets/gardens/animals/red_parakeet.png b/assets/gardens/victory_assets/animals/red_parakeet.png similarity index 100% rename from assets/gardens/animals/red_parakeet.png rename to assets/gardens/victory_assets/animals/red_parakeet.png diff --git a/assets/gardens/animals/red_parakeet.png.import b/assets/gardens/victory_assets/animals/red_parakeet.png.import similarity index 74% rename from assets/gardens/animals/red_parakeet.png.import rename to assets/gardens/victory_assets/animals/red_parakeet.png.import index c364e158..8d6ccabe 100644 --- a/assets/gardens/animals/red_parakeet.png.import +++ b/assets/gardens/victory_assets/animals/red_parakeet.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://da7ppeamjqjpw" -path="res://.godot/imported/red_parakeet.png-546f9c816968cb8f1bb25596ab769016.ctex" +path="res://.godot/imported/red_parakeet.png-da45ba4c38e1e0997bf4da3dc9da41b8.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/gardens/animals/red_parakeet.png" -dest_files=["res://.godot/imported/red_parakeet.png-546f9c816968cb8f1bb25596ab769016.ctex"] +source_file="res://assets/gardens/victory_assets/animals/red_parakeet.png" +dest_files=["res://.godot/imported/red_parakeet.png-da45ba4c38e1e0997bf4da3dc9da41b8.ctex"] [params] diff --git a/assets/gardens/animals/turtle.png b/assets/gardens/victory_assets/animals/turtle.png similarity index 100% rename from assets/gardens/animals/turtle.png rename to assets/gardens/victory_assets/animals/turtle.png diff --git a/assets/gardens/animals/turtle.png.import b/assets/gardens/victory_assets/animals/turtle.png.import similarity index 75% rename from assets/gardens/animals/turtle.png.import rename to assets/gardens/victory_assets/animals/turtle.png.import index 3336bf5b..a4fabc72 100644 --- a/assets/gardens/animals/turtle.png.import +++ b/assets/gardens/victory_assets/animals/turtle.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://bsw6v8ix7bb2s" -path="res://.godot/imported/turtle.png-b25459e1a6a7c121b59fc65afcb3f82e.ctex" +path="res://.godot/imported/turtle.png-c250d2a66dd72bd5fa41354b999b1000.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/gardens/animals/turtle.png" -dest_files=["res://.godot/imported/turtle.png-b25459e1a6a7c121b59fc65afcb3f82e.ctex"] +source_file="res://assets/gardens/victory_assets/animals/turtle.png" +dest_files=["res://.godot/imported/turtle.png-c250d2a66dd72bd5fa41354b999b1000.ctex"] [params] diff --git a/assets/gardens/animals/yellow_parakeet.png b/assets/gardens/victory_assets/animals/yellow_parakeet.png similarity index 100% rename from assets/gardens/animals/yellow_parakeet.png rename to assets/gardens/victory_assets/animals/yellow_parakeet.png diff --git a/assets/gardens/animals/yellow_parakeet.png.import b/assets/gardens/victory_assets/animals/yellow_parakeet.png.import similarity index 73% rename from assets/gardens/animals/yellow_parakeet.png.import rename to assets/gardens/victory_assets/animals/yellow_parakeet.png.import index bc179af0..834d3466 100644 --- a/assets/gardens/animals/yellow_parakeet.png.import +++ b/assets/gardens/victory_assets/animals/yellow_parakeet.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://bd5pxoufamqy" -path="res://.godot/imported/yellow_parakeet.png-ce114f4bc0be41f81a9d2e24bceb2fcf.ctex" +path="res://.godot/imported/yellow_parakeet.png-3b1b7946f714148f55147e3efdf195ad.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/gardens/animals/yellow_parakeet.png" -dest_files=["res://.godot/imported/yellow_parakeet.png-ce114f4bc0be41f81a9d2e24bceb2fcf.ctex"] +source_file="res://assets/gardens/victory_assets/animals/yellow_parakeet.png" +dest_files=["res://.godot/imported/yellow_parakeet.png-3b1b7946f714148f55147e3efdf195ad.ctex"] [params] diff --git a/assets/lesson_screen/bottom.png b/assets/lesson_screen/bottom.png deleted file mode 100644 index 5ff5cd66f5a1ec004dd321fc68404829671551b5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11678 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 I_3VWI2gQx3tpET3 diff --git a/assets/lesson_screen/branches.png b/assets/lesson_screen/branches.png deleted file mode 100644 index 7b4d37b776b54685bc27b1825888649fb49151f5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40124 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

4O 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 diff --git a/assets/lesson_screen/top_right.png b/assets/lesson_screen/top_right.png deleted file mode 100644 index 48c8f44c7565f18dc7dca51b39ec254d9508c927..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11870 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 lCjTYGf3xBLJ1H2S(f2%&om%OK{&#R}nS void: init_unlocks() +static func get_minigame_count_for_lesson(lesson_number: int) -> int: + return Database.get_exercise_for_lesson(lesson_number).size() + + +static func _build_default_lesson_unlock(lesson_number: int) -> Dictionary: + var minigame_count: int = get_minigame_count_for_lesson(lesson_number) + return { + "look_and_learn": Status.LOCKED, + "games": _make_locked_games_array(minigame_count), + "last_duration": _make_zero_durations(minigame_count), + "total_duration": _make_zero_durations(minigame_count), + } + + +static func _make_locked_games_array(minigame_count: int) -> Array: + var games: Array = [] + for _index: int in range(minigame_count): + games.append(Status.LOCKED) + return games + + +static func _make_zero_durations(minigame_count: int) -> PackedInt32Array: + var durations: PackedInt32Array = PackedInt32Array() + durations.resize(minigame_count) + return durations + + # Make sure the unlocks are correct func init_unlocks() -> void: if not unlocks: @@ -35,22 +62,13 @@ func init_unlocks() -> void: else: unlocks = unlocks # Force ensure_data_integrity() _sanitize_boss_progression() - + # Verify the lessons var number_of_lessons: int = Database.get_lessons_count() if unlocks.size() != number_of_lessons: for index: int in range(number_of_lessons): if not unlocks.has(index+1): - unlocks[index + 1] = { - "look_and_learn": Status.LOCKED, - "games": [ - Status.LOCKED, - Status.LOCKED, - Status.LOCKED, - ], - "last_duration": PackedInt32Array([0, 0, 0]), - "total_duration": PackedInt32Array([0, 0, 0]) - } + unlocks[index + 1] = _build_default_lesson_unlock(index + 1) # Make sure that the first garden is always accessible if unlocks.has(1): @@ -74,37 +92,39 @@ func ensure_data_integrity(data: Dictionary[int, Dictionary]) -> Dictionary: if not result.has(index): if not is_init: Log.warn("StudentProgression: Garden %d missing → added with default values." % index) - result[index] = { - "games": [Status.LOCKED, Status.LOCKED, Status.LOCKED], - "look_and_learn": Status.LOCKED, - "last_duration": PackedInt32Array([0, 0, 0]), - "total_duration": PackedInt32Array([0, 0, 0]) - } + result[index] = _build_default_lesson_unlock(index) # Check internal structure for index: int in result.keys(): var garden: Dictionary = result[index] + var minigame_count: int = get_minigame_count_for_lesson(index) # Check missing keys if not garden.has("games"): if not is_init: Log.warn("StudentProgression: Garden %d: Add missing key 'games'." % index) - garden["games"] = [Status.LOCKED, Status.LOCKED, Status.LOCKED] + garden["games"] = _make_locked_games_array(minigame_count) if not garden.has("look_and_learn"): if not is_init: Log.warn("StudentProgression: Garden %d: Add missing key 'look_and_learn'." % index) garden["look_and_learn"] = Status.LOCKED if not garden.has("last_duration"): - garden["last_duration"] = PackedInt32Array([0, 0, 0]) + garden["last_duration"] = _make_zero_durations(minigame_count) if not garden.has("total_duration"): - garden["total_duration"] = PackedInt32Array([0, 0, 0]) + garden["total_duration"] = _make_zero_durations(minigame_count) # Check array "games" - if typeof(garden["games"]) != TYPE_ARRAY or (garden["games"] as Array).size() != 3: + if typeof(garden["games"]) != TYPE_ARRAY or (garden["games"] as Array).size() != minigame_count: if not is_init: Log.warn("StudentProgression: Garden %d: invalid format for 'games' → reset." % index) - garden["games"] = [Status.LOCKED, Status.LOCKED, Status.LOCKED] + garden["games"] = _make_locked_games_array(minigame_count) + + # Make sure duration arrays match the minigame count + if (garden["last_duration"] as PackedInt32Array).size() != minigame_count: + garden["last_duration"] = _make_zero_durations(minigame_count) + if (garden["total_duration"] as PackedInt32Array).size() != minigame_count: + garden["total_duration"] = _make_zero_durations(minigame_count) # Check value outside of possible enum values - for game_index: int in range(3): + for game_index: int in range((garden["games"] as Array).size()): if garden["games"][game_index] not in [Status.LOCKED, Status.UNLOCKED, Status.COMPLETED]: garden["games"][game_index] = Status.LOCKED if garden["look_and_learn"] not in [Status.LOCKED, Status.UNLOCKED, Status.COMPLETED]: @@ -126,30 +146,57 @@ func ensure_data_integrity(data: Dictionary[int, Dictionary]) -> Dictionary: # First garden (key 1) is always unlocked prev_completed = true + var minigame_count: int = (garden["games"] as Array).size() + # Case: previous garden not completed if not prev_completed: - for game_index: int in range(3): - if garden["games"][game_index] != Status.LOCKED or garden["look_and_learn"] != Status.LOCKED: - if not is_init: - Log.warn("StudentProgression: Garden %d: invalid progression (previous not finished) → reset." % index) - garden["games"] = [Status.LOCKED, Status.LOCKED, Status.LOCKED] - garden["look_and_learn"] = Status.LOCKED - break + var needs_reset: bool = garden["look_and_learn"] != Status.LOCKED + if not needs_reset: + for game_index: int in range(minigame_count): + if garden["games"][game_index] != Status.LOCKED: + needs_reset = true + break + if needs_reset: + if not is_init: + Log.warn("StudentProgression: Garden %d: invalid progression (previous not finished) → reset." % index) + garden["games"] = _make_locked_games_array(minigame_count) + garden["look_and_learn"] = Status.LOCKED continue - # Case: lesson completed → unlock games if needed + # Enforce sequential unlock: first non-COMPLETED game → UNLOCKED, everything + # after it → LOCKED (including out-of-order COMPLETED in old saves). if garden["look_and_learn"] == Status.COMPLETED: - for game_index: int in range(3): - if garden["games"][game_index] == Status.LOCKED: - garden["games"][game_index] = Status.UNLOCKED + var next_to_play: int = -1 + for game_index: int in range(minigame_count): + if garden["games"][game_index] != Status.COMPLETED: + next_to_play = game_index + break + if next_to_play >= 0: + if garden["games"][next_to_play] == Status.LOCKED: + garden["games"][next_to_play] = Status.UNLOCKED if not is_init: - Log.warn("StudentProgression: Garden %d: game %d unlocked because lesson is completed" % [index, game_index + 1]) - - # Case: previous garden completed → unlock lesson if needed - elif garden["look_and_learn"] == Status.LOCKED: - garden["look_and_learn"] = Status.UNLOCKED - if not is_init: - Log.warn("StudentProgression: Garden %d: lesson unlocked because previous garden is completed" % index) + Log.warn("StudentProgression: Garden %d: minigame %d unlocked because it is next to play" % [index, next_to_play]) + for game_index: int in range(next_to_play + 1, minigame_count): + if garden["games"][game_index] != Status.LOCKED: + var was_completed: bool = garden["games"][game_index] == Status.COMPLETED + garden["games"][game_index] = Status.LOCKED + if not is_init: + if was_completed: + Log.warn("StudentProgression: Garden %d: minigame %d demoted from COMPLETED to LOCKED (out of play order — minigame %d not yet completed)" % [index, game_index, next_to_play]) + else: + Log.warn("StudentProgression: Garden %d: minigame %d re-locked (waits for minigame %d to be completed)" % [index, game_index, game_index - 1]) + else: + # L&L not completed → no game may be UNLOCKED (COMPLETED preserved). + for game_index: int in range(minigame_count): + if garden["games"][game_index] == Status.UNLOCKED: + garden["games"][game_index] = Status.LOCKED + if not is_init: + Log.warn("StudentProgression: Garden %d: minigame %d re-locked (look-and-learn not completed)" % [index, game_index]) + # Case: previous garden completed → unlock lesson if needed + if garden["look_and_learn"] == Status.LOCKED: + garden["look_and_learn"] = Status.UNLOCKED + if not is_init: + Log.warn("StudentProgression: Garden %d: lesson unlocked because previous garden is completed" % index) _sanitize_boss_progression() return result @@ -238,19 +285,25 @@ func get_max_unlocked_lesson_index() -> int: func is_lesson_completed(lesson_number: int) -> bool: - return unlocks[lesson_number]["look_and_learn"] == Status.COMPLETED and unlocks[lesson_number]["games"][0] == Status.COMPLETED and unlocks[lesson_number]["games"][1] == Status.COMPLETED and unlocks[lesson_number]["games"][2] == Status.COMPLETED + if unlocks[lesson_number]["look_and_learn"] != Status.COMPLETED: + return false + for game_status: int in unlocks[lesson_number]["games"]: + if game_status != Status.COMPLETED: + return false + return true # Return true if the progression is saved or false if the look and learn was already completed func look_and_learn_completed(lesson_number: int) -> bool: if unlocks[lesson_number]["look_and_learn"] == Status.COMPLETED: return false - + unlocks[lesson_number]["look_and_learn"] = Status.COMPLETED - - for index: int in range(3): - unlocks[lesson_number]["games"][index] = Status.UNLOCKED - + + var games: Array = unlocks[lesson_number]["games"] + if games.size() > 0 and games[0] == Status.LOCKED: + games[0] = Status.UNLOCKED + last_modified = Time.get_datetime_string_from_system(true) progression_changed.emit() return true @@ -258,20 +311,27 @@ func look_and_learn_completed(lesson_number: int) -> bool: # Return true if the progression is saved or false if the game was already completed func game_completed(lesson_number: int, game_number: int) -> bool: - # If the game is already completed, do nothing - if unlocks[lesson_number]["games"][game_number] == Status.COMPLETED: + var games: Array = unlocks[lesson_number]["games"] + + if games[game_number] == Status.COMPLETED: return false - - unlocks[lesson_number]["games"][game_number] = Status.COMPLETED - + + games[game_number] = Status.COMPLETED + + var next_game_index: int = game_number + 1 + if next_game_index < games.size() and games[next_game_index] == Status.LOCKED: + games[next_game_index] = Status.UNLOCKED + var all_completed: bool = true - for index: int in range(3): - all_completed = all_completed and unlocks[lesson_number]["games"][index] == Status.COMPLETED - + for game_status: int in games: + if game_status != Status.COMPLETED: + all_completed = false + break + if all_completed: if unlocks.has(lesson_number + 1): unlocks[lesson_number + 1]["look_and_learn"] = Status.UNLOCKED - + last_modified = Time.get_datetime_string_from_system(true) progression_changed.emit() return true @@ -320,13 +380,14 @@ func clear_boss_block() -> void: func add_level_time(lesson_number: int, game_number: int, time_spent: int) -> void: Log.trace("StudentProgression: Add time to level %d, minigame %d. Time added: %s" % [lesson_number, game_number, time_spent]) - if game_number > 2: - Log.error("StudentProgression: Cannot log a level time for a minigame number superior to 2") - return - if not unlocks.has(lesson_number): Log.error("StudentProgression: Cannot log a level time for lesson %d because it does not exists in progression data" % lesson_number) return + + var minigame_count: int = (unlocks[lesson_number]["games"] as Array).size() + if game_number < 0 or game_number >= minigame_count: + Log.error("StudentProgression: Cannot log a level time for minigame %d in lesson %d (lesson has %d minigame(s))" % [game_number, lesson_number, minigame_count]) + return if not (unlocks[lesson_number] as Dictionary).has("last_duration") or not (unlocks[lesson_number]["last_duration"] as PackedInt32Array).size() > game_number: Log.error("StudentProgression: Cannot log a last_duration for lesson %d, game %d, because it does not exists" % [lesson_number, game_number]) diff --git a/sources/gardens/boss_button.tscn b/sources/gardens/boss_button.tscn index 3b3a2e78..e4aebf58 100644 --- a/sources/gardens/boss_button.tscn +++ b/sources/gardens/boss_button.tscn @@ -14,6 +14,7 @@ offset_bottom = 512.0 pivot_offset = Vector2(180, 180) size_flags_horizontal = 4 size_flags_vertical = 4 +mouse_filter = 1 texture_normal = ExtResource("lesson_circle") texture_pressed = ExtResource("lesson_circle") texture_hover = ExtResource("lesson_circle") @@ -35,6 +36,7 @@ anchor_right = 0.5 anchor_bottom = 0.5 grow_horizontal = 2 grow_vertical = 2 +mouse_filter = 1 [node name="Border" type="TextureRect" parent="." unique_id=758604924] unique_name_in_owner = true diff --git a/sources/gardens/gardens.gd b/sources/gardens/gardens.gd index e134c678..9bfd1d66 100644 --- a/sources/gardens/gardens.gd +++ b/sources/gardens/gardens.gd @@ -4,6 +4,22 @@ extends Control signal minigame_layout_opened() const KALULU: GDScript = preload("res://sources/minigames/base/kalulu_ingame.gd") +const MINIGAME_WEDGE_SCENE: PackedScene = preload("res://sources/gardens/minigame_wedge.tscn") +# Wheel geometry, in MinigameSelection-local coords (canvas 2560×1800). +const WHEEL_CENTER: Vector2 = Vector2(1280, 900) +# Matches the inner edge of big_button.png; past this the gray ring hides everything. +const WHEEL_RADIUS: float = 815.0 +const WHEEL_ARC_SEGMENTS: int = 48 +const WHEEL_ICON_DISTANCE_RATIO: float = 0.55 +const WHEEL_DIVIDER_WIDTH: float = 12.0 +const WHEEL_HIGHLIGHT_WIDTH: float = 12.0 +# Outline around the central Look-and-Learn button. Drawn at the button's visible +# edge. Colored dark by default, gold when L&L is the next-to-play step. +const LESSON_BUTTON_OUTLINE_RADIUS: float = 192.0 +# Top inset of the wheel's central label so the grapheme text sits just below the +# button center, mirroring the movie icon just above it. The 384x384 button has +# its center at y=192; the label (vertical-centered) then centers at y=(this+384)/2. +const LESSON_BUTTON_LABEL_TOP_OFFSET: float = 104.0 const GARDEN_SCENES: Array[PackedScene] = [ preload("res://resources/gardens/garden_01.tscn"), preload("res://resources/gardens/garden_02.tscn"), @@ -48,12 +64,12 @@ static var cached_layout_lessons: int = 0 get: return _gardens_layout @export var starting_garden: int = -1 -@export_category("Colors") -@export var unlocked_color: Color = Color("1c2662") -@export var locked_color: Color = Color("1d2229") -@export_group("Minigames") +@export_category("Minigames") @export var minigame_scene_paths: PackedStringArray = PackedStringArray() -@export var minigames_icons: Array[Texture] = [] +## Animal body (colored by the garden) and face (kept as-is for eyes/mouth details). +## Both arrays must be the same length and aligned with `minigame_scene_paths`. +@export var minigames_body_icons: Array[Texture] = [] +@export var minigames_face_icons: Array[Texture] = [] var _minigame_scene_cache: Dictionary = {} var lessons: Dictionary = {} @@ -84,17 +100,16 @@ var is_back_button_hold_active: bool = false @onready var boss_buttons_container: Control = %BossButtons @onready var minigame_selection: Control = %MinigameSelection @onready var lesson_button: LessonButton = %LessonButton +@onready var lesson_button_outline: Line2D = %LessonButtonOutline +@onready var lesson_button_movie_icon: TextureRect = %MovieIcon @onready var lesson_button_particles: GPUParticles2D = %LessonButtonParticles @onready var back_button: BackButton = %BackButton @onready var right_audio_stream_player: AudioStreamPlayer = $RightAudioStreamPlayer @onready var left_audio_stream_player: AudioStreamPlayer = $LeftAudioStreamPlayer @onready var feedback_audio_stream_player: AudioStreamPlayer = $FeedBackAudioStreamPlayer @onready var feedback_audio_stream_player2: AudioStreamPlayer = $FeedBackAudioStreamPlayer2 -@onready var minigame_layout_1: MinigameLayout = %MinigameBackground1 -@onready var minigame_layout_2: MinigameLayout = %MinigameBackground2 -@onready var minigame_layout_3: MinigameLayout = %MinigameBackground3 -@onready var minigame_background: TextureRect = %MinigameBackground -@onready var minigame_background_center: TextureRect = %MinigameBackgroundCenter +@onready var wedges_container: Control = %WedgesContainer +@onready var background_rect: ColorRect = %BackgroundRect @onready var lock: Control = %Lock @onready var kalulu: KALULU = %Kalulu @onready var kalulu_button: CanvasItem = %KaluluButton @@ -669,7 +684,6 @@ func _process(_delta: float) -> void: _process_back_button_hold(_delta) locked_line.position.x = - scroll_container.scroll_horizontal unlocked_line.position.x = - scroll_container.scroll_horizontal - boss_buttons_container.position.x = - scroll_container.scroll_horizontal parallax_background.scroll_offset.x = - scroll_container.scroll_horizontal clouds.scroll_offset = scroll_container.scroll_horizontal @@ -688,17 +702,191 @@ func _process_back_button_hold(delta: float) -> void: _confirm_back_button_pressed() -func _get_minigame_layouts() -> Array[MinigameLayout]: - return [minigame_layout_1, minigame_layout_2, minigame_layout_3] +# Single source of truth for wedge geometry. Returns the pie-slice's start/end +# angles and the bisector angle along which the icon sits, for wedge `wedge_index` +# of a wheel showing `minigame_count` wedges (1..3). +# N=1: full disc, icon to the left of the L&L button. +# N=2: game 0 left half, game 1 right half. +# N=3: game 0 top-right, game 1 bottom, game 2 top-left. +static func _get_wedge_angles(minigame_count: int, wedge_index: int) -> Dictionary: + if minigame_count == 1: + return {start = 0.0, end = TAU, icon = PI} + if minigame_count == 2: + if wedge_index == 0: + return {start = PI / 2.0, end = 3.0 * PI / 2.0, icon = PI} + return {start = -PI / 2.0, end = PI / 2.0, icon = 0.0} + if wedge_index == 0: + return {start = -PI / 2.0, end = PI / 6.0, icon = -PI / 6.0} + if wedge_index == 1: + return {start = PI / 6.0, end = 5.0 * PI / 6.0, icon = PI / 2.0} + return {start = 5.0 * PI / 6.0, end = 3.0 * PI / 2.0, icon = 7.0 * PI / 6.0} + + +static func _get_wedge_layout(minigame_count: int, wedge_index: int) -> Dictionary: + var angles: Dictionary = _get_wedge_angles(minigame_count, wedge_index) + var polygon: PackedVector2Array = _generate_full_disc_polygon() if minigame_count == 1 \ + else _generate_pie_slice_polygon(angles.start as float, angles.end as float) + return {polygon = polygon, icon_center = _wedge_icon_position(angles.icon as float)} + + +static func _generate_pie_slice_polygon(start_angle: float, end_angle: float, radius: float = WHEEL_RADIUS) -> PackedVector2Array: + var wheel_points: PackedVector2Array = PackedVector2Array() + wheel_points.append(WHEEL_CENTER) + var span: float = end_angle - start_angle + for index: int in range(WHEEL_ARC_SEGMENTS + 1): + var angle: float = start_angle + span * (float(index) / float(WHEEL_ARC_SEGMENTS)) + wheel_points.append(WHEEL_CENTER + Vector2(cos(angle), sin(angle)) * radius) + return wheel_points + + +static func _generate_full_disc_polygon(radius: float = WHEEL_RADIUS) -> PackedVector2Array: + var wheel_points: PackedVector2Array = PackedVector2Array() + for index: int in range(WHEEL_ARC_SEGMENTS): + var angle: float = TAU * float(index) / float(WHEEL_ARC_SEGMENTS) + wheel_points.append(WHEEL_CENTER + Vector2(cos(angle), sin(angle)) * radius) + return wheel_points + + +# Wedge polygon with outer arc inset by half the stroke width so the gold line +# stays inside the wedge. Radial edges keep their angles (fall on the dividers). +static func _generate_wedge_highlight_polygon(minigame_count: int, wedge_index: int) -> PackedVector2Array: + var inset_radius: float = WHEEL_RADIUS - WHEEL_HIGHLIGHT_WIDTH * 0.5 + if minigame_count == 1: + return _generate_full_disc_polygon(inset_radius) + var angles: Dictionary = _get_wedge_angles(minigame_count, wedge_index) + return _generate_pie_slice_polygon(angles.start as float, angles.end as float, inset_radius) + + +static func _wedge_icon_position(angle_rad: float) -> Vector2: + return WHEEL_CENTER + Vector2(cos(angle_rad), sin(angle_rad)) * (WHEEL_RADIUS * WHEEL_ICON_DISTANCE_RATIO) + + +static func _get_divider_segments(minigame_count: int) -> Array[PackedVector2Array]: + var segments: Array[PackedVector2Array] = [] + if minigame_count < 2: + return segments + for wedge_index: int in range(minigame_count): + var start_angle: float = _get_wedge_angles(minigame_count, wedge_index).start as float + var edge: Vector2 = WHEEL_CENTER + Vector2(cos(start_angle), sin(start_angle)) * WHEEL_RADIUS + segments.append(PackedVector2Array([WHEEL_CENTER, edge])) + return segments + + +func _clear_wheel() -> void: + for child: Node in wedges_container.get_children(): + child.queue_free() + + +func _build_wheel(exercises: Array[int], lesson_unlocks: Dictionary) -> void: + _clear_wheel() + var minigame_count: int = exercises.size() + for wedge_index: int in range(minigame_count): + var layout: Dictionary = _get_wedge_layout(minigame_count, wedge_index) + var exercise_type: int = exercises[wedge_index] + var icon_index: int = exercise_type - 1 + var status: StudentProgression.Status = lesson_unlocks["games"][wedge_index] as StudentProgression.Status + var wedge: MinigameWedge = MINIGAME_WEDGE_SCENE.instantiate() + wedges_container.add_child(wedge) + var is_wedge_locked: bool = status == StudentProgression.Status.LOCKED + wedge.configure( + layout.polygon as PackedVector2Array, + layout.icon_center as Vector2, + minigames_body_icons[icon_index], + minigames_face_icons[icon_index], + _wedge_color_for_status(status), + _body_color_for_status(status), + is_wedge_locked, + ) + wedge.is_disabled = is_wedge_locked + wedge.pressed.connect(_on_minigame_button_pressed.bind(icon_index, wedge_index)) + _apply_wedge_status_effects(wedge, status, wedge_index) + + for line_points: PackedVector2Array in _get_divider_segments(minigame_count): + var divider: Line2D = Line2D.new() + divider.width = WHEEL_DIVIDER_WIDTH + divider.default_color = current_garden.wheel_background + divider.points = line_points + wedges_container.add_child(divider) + + _draw_next_to_play_highlight(lesson_unlocks, minigame_count) + + +func _next_to_play_wedge_index(lesson_unlocks: Dictionary) -> int: + if lesson_unlocks["look_and_learn"] != StudentProgression.Status.COMPLETED: + return -1 + var games: Array = lesson_unlocks["games"] + for index: int in range(games.size()): + if games[index] == StudentProgression.Status.UNLOCKED: + return index + return -1 + + +func _draw_next_to_play_highlight(lesson_unlocks: Dictionary, minigame_count: int) -> void: + # L&L's "next to play" cue is the lesson-button outline color swap, handled + # in _configure_lesson_button_outline(). Wedges get a separate gold ring here. + var wedge_index: int = _next_to_play_wedge_index(lesson_unlocks) + if wedge_index < 0: + return + _draw_wedge_highlight(minigame_count, wedge_index) + + +func _draw_wedge_highlight(minigame_count: int, wedge_index: int) -> void: + _add_highlight_line(_generate_wedge_highlight_polygon(minigame_count, wedge_index)) + + +# Adds a gold outline tracing the given polygon to the wheel. The polyline is +# closed automatically. z_index lifts the line above Branches; LessonButton's +# higher z_index keeps it on top in turn. +func _add_highlight_line(polygon_points: PackedVector2Array) -> void: + if polygon_points.is_empty(): + return + var outline: PackedVector2Array = PackedVector2Array(polygon_points) + outline.append(polygon_points[0]) + var line: Line2D = Line2D.new() + line.width = WHEEL_HIGHLIGHT_WIDTH + line.default_color = Garden.WHEEL_HIGHLIGHT + line.joint_mode = Line2D.LINE_JOINT_ROUND + line.begin_cap_mode = Line2D.LINE_CAP_ROUND + line.end_cap_mode = Line2D.LINE_CAP_ROUND + line.points = outline + line.z_index = 5 + wedges_container.add_child(line) + + +func _wedge_color_for_status(status: StudentProgression.Status) -> Color: + match status: + StudentProgression.Status.LOCKED: + return Garden.WHEEL_WEDGE_LOCKED + _: + return current_garden.wheel_wedge_unlocked + + +# Animal body tint: gray when locked, garden's signature color otherwise. +func _body_color_for_status(status: StudentProgression.Status) -> Color: + if status == StudentProgression.Status.LOCKED: + return Garden.ANIMAL_LOCKED_COLOR + return current_garden.animal_unlocked_color + + +func _apply_wedge_status_effects(wedge: MinigameWedge, status: StudentProgression.Status, wedge_index: int) -> void: + if status != StudentProgression.Status.COMPLETED: + return + if not transition_data \ + or not transition_data.get("minigame_completed", false) \ + or transition_data.get("minigame_number", -1) != wedge_index \ + or not transition_data.get("first_clear", false): + return + await minigame_layout_opened + create_tween().tween_property(wedge, "modulate:a", 0.6, 0.5) + wedge.right() func _open_minigames_layout(button: LessonButton, lesson_number: int) -> void: if in_minigame_selection or not UserDataManager.student_progression: return - # Gets the correct exercises for the lesson var exercises: Array[int] = Database.get_exercise_for_lesson(lesson_number) - if not exercises or exercises.size() < 3: - Log.error("Gardens: Cannot open minigame layout for lesson %d: expected 3 exercises, got %d" % [lesson_number, exercises.size() if exercises else 0]) + if exercises.is_empty(): + Log.error("Gardens: Cannot open minigame layout for lesson %d: no minigames defined" % lesson_number) return feedback_audio_stream_player2.pitch_scale = 1.1 feedback_audio_stream_player2.play() @@ -714,69 +902,84 @@ func _open_minigames_layout(button: LessonButton, lesson_number: int) -> void: current_button_global_position = button.global_position # Gets the current lesson unlocks var lesson_unlocks: Dictionary = UserDataManager.student_progression.unlocks[current_lesson_number] - var are_minigames_locked: bool = lesson_unlocks["games"][0] == StudentProgression.Status.LOCKED and lesson_unlocks["games"][1] == StudentProgression.Status.LOCKED and lesson_unlocks["games"][2] == StudentProgression.Status.LOCKED # Deactivate the mouse filters on the buttons behind the layout for lesson_button_item: LessonButton in current_garden.get_lesson_buttons(): lesson_button_item.mouse_filter = Control.MOUSE_FILTER_IGNORE - # Background - if are_minigames_locked: - minigame_background_center.modulate = locked_color - else: - minigame_background_center.modulate = current_garden.color - # Lesson button - _handle_lesson_button(current_lesson_number, lesson_unlocks["look_and_learn"] as StudentProgression.Status) - # Minigames - var minigame_layouts: Array[MinigameLayout] = _get_minigame_layouts() - for layout_index: int in minigame_layouts.size(): - _fill_minigame_choice(minigame_layouts[layout_index], exercises[layout_index], lesson_unlocks["games"][layout_index] as StudentProgression.Status, layout_index) + var ll_status: StudentProgression.Status = lesson_unlocks["look_and_learn"] as StudentProgression.Status + background_rect.color = current_garden.wheel_background + _configure_lesson_button_outline(ll_status) + _center_lesson_button_label() + _handle_lesson_button(current_lesson_number, ll_status) + _build_wheel(exercises, lesson_unlocks) # Animations minigame_selection.show() back_button.hide() kalulu_button.hide() line_particles.hide() - minigame_background.size = 300.0 * Vector2.ONE - minigame_background.global_position = current_button_global_position - minigame_background.show() - minigame_background_center.size = 300.0 * Vector2.ONE - minigame_background_center.global_position = current_button_global_position - minigame_background_center.show() - var tween: Tween = create_tween().set_parallel(true).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_BACK) - tween.tween_property(minigame_background_center, "scale", (1800.0 / 300.0) * Vector2.ONE, 0.25) - tween.tween_property(minigame_background_center, "global_position", Vector2(380.0, 0), 0.25) - tween.tween_property(minigame_background, "scale", (1800.0 / 300.0) * Vector2.ONE, 0.25) - tween.tween_property(minigame_background, "global_position", Vector2(380.0, 0), 0.25) - tween.chain().tween_property(minigame_selection, "modulate:a", 1.0, 0.25) + var tween: Tween = create_tween().set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_BACK) + tween.tween_property(minigame_selection, "modulate:a", 1.0, 0.25) await tween.finished minigame_layout_opened.emit() +# Perfectly centers the grapheme label horizontally and drops it just below the +# button center, so it pairs with the movie icon sitting just above. Done in code +# because instanced-scene property overrides on the inherited Label don't survive +# Godot re-saves. This LessonButton is a dedicated wheel instance, so it doesn't +# affect the garden lesson buttons. +func _center_lesson_button_label() -> void: + var label: Label = lesson_button.label + label.anchor_left = 0.0 + label.anchor_top = 0.0 + label.anchor_right = 1.0 + label.anchor_bottom = 1.0 + label.offset_left = 0.0 + label.offset_right = 0.0 + label.offset_top = LESSON_BUTTON_LABEL_TOP_OFFSET + label.offset_bottom = 0.0 + + +func _configure_lesson_button_outline(ll_status: StudentProgression.Status) -> void: + # Gold when L&L is the next-to-play step (UNLOCKED but not yet COMPLETED), + # divider color otherwise. Replaces the separate gold ring we used to draw. + var color: Color = Garden.WHEEL_HIGHLIGHT if ll_status == StudentProgression.Status.UNLOCKED else current_garden.wheel_background + lesson_button_outline.default_color = color + var circle_points: PackedVector2Array = _generate_full_disc_polygon(LESSON_BUTTON_OUTLINE_RADIUS) + if circle_points.size() > 0: + circle_points.append(circle_points[0]) + lesson_button_outline.points = circle_points + + func _handle_lesson_button(lesson_number: int, status: StudentProgression.Status) -> void: lesson_button.text = lessons[lesson_number][0].grapheme + # Center stays the unlocked-wedge color across all states; pair it with the + # garden's dark color so the label and icon stay readable on it. + lesson_button.set_garden_colors( + current_garden.wheel_wedge_unlocked, + current_garden.unlocked_lesson, + current_garden.wheel_wedge_unlocked, + current_garden.unlocked_lesson, + ) lesson_button.set_button_disabled(status == StudentProgression.Status.LOCKED) lesson_button.completed = status == StudentProgression.Status.COMPLETED + # Override the hardcoded gray LessonButton uses when disabled, so the L&L + # center button keeps a uniform background regardless of progression state. + lesson_button.center.modulate = current_garden.wheel_wedge_unlocked lesson_button_particles.emitting = status == StudentProgression.Status.UNLOCKED + lesson_button_movie_icon.modulate = _lesson_button_label_color(status) if status == StudentProgression.Status.COMPLETED: if transition_data and transition_data.has("look_and_learn_completed") and transition_data.look_and_learn_completed: await minigame_layout_opened lesson_button.right() -func _fill_minigame_choice(minigame_layout: MinigameLayout, exercise_type: int, status: StudentProgression.Status, minigame_number: int) -> void: - minigame_layout.icon.texture = minigames_icons[exercise_type-1] - minigame_layout.is_disabled = status == StudentProgression.Status.LOCKED +# Mirrors LessonButton._update_visual_state() so the movie icon tracks the label. +func _lesson_button_label_color(status: StudentProgression.Status) -> Color: + if status == StudentProgression.Status.LOCKED: + return LessonButton.LOCKED_LABEL_COLOR if status == StudentProgression.Status.COMPLETED: - if transition_data and transition_data.has("minigame_completed") and transition_data.minigame_completed and transition_data.has("minigame_number") and transition_data.minigame_number == minigame_number and transition_data.has("first_clear") and transition_data.first_clear: - minigame_layout.self_modulate = unlocked_color - await minigame_layout_opened - create_tween().tween_property(minigame_layout, "self_modulate:a", 0, 0.5) - minigame_layout.right() - else: - minigame_layout.self_modulate.a = 0 - elif status == StudentProgression.Status.LOCKED: - minigame_layout.self_modulate = locked_color - else: - minigame_layout.self_modulate = unlocked_color - minigame_layout.pressed.connect(_on_minigame_button_pressed.bind(exercise_type - 1, minigame_number)) + return lesson_button.completed_label_color + return lesson_button.unlocked_label_color func _get_minigame_scene(scene_index: int) -> PackedScene: @@ -811,26 +1014,18 @@ func _close_minigames_layout() -> void: in_minigame_selection = false feedback_audio_stream_player2.pitch_scale = 0.75 feedback_audio_stream_player2.play() - var tween: Tween = create_tween().set_parallel(true).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_BACK) + var tween: Tween = create_tween().set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_BACK) tween.tween_property(minigame_selection, "modulate:a", 0.0, 0.25) - var other_tween: Tween = tween.chain() - other_tween.tween_property(minigame_background_center, "scale", Vector2.ONE, 0.25) - other_tween.tween_property(minigame_background_center, "global_position", current_button_global_position, 0.25) - other_tween.tween_property(minigame_background, "scale", Vector2.ONE, 0.25) - other_tween.tween_property(minigame_background, "global_position", current_button_global_position, 0.25) await tween.finished if current_button: current_button.show_placeholder(false) minigame_selection.hide() - minigame_background.hide() - minigame_background_center.hide() back_button.show() kalulu_button.show() line_particles.show() for button: LessonButton in current_garden.get_lesson_buttons(): button.mouse_filter = Control.MOUSE_FILTER_STOP - for layout: MinigameLayout in _get_minigame_layouts(): - layout.pressed.disconnect(_on_minigame_button_pressed) + _clear_wheel() #region Lesson setup and path @@ -967,8 +1162,6 @@ func _sync_boss_buttons_container() -> void: if not boss_buttons_container or not garden_parent: return boss_buttons_container.mouse_filter = Control.MOUSE_FILTER_IGNORE - boss_buttons_container.position = Vector2.ZERO - boss_buttons_container.size = scroll_container.size func _clear_boss_buttons() -> void: @@ -1014,7 +1207,6 @@ func _set_up_boss_buttons() -> void: boss_button.set_button_disabled(true) var garden_index: int = _get_garden_index_for_lesson(gate_lesson) boss_button.pressed.connect(_on_boss_button_pressed.bind(gate_lesson, garden_index)) - boss_button.gui_input.connect(_on_boss_button_gui_input) _set_up_final_boss_button() @@ -1041,7 +1233,6 @@ func _set_up_final_boss_button() -> void: boss_button.position = final_boss_center - final_boss_size * 0.5 boss_button.set_button_disabled(false) boss_button.pressed.connect(_on_final_boss_button_pressed.bind(final_lesson_number, last_garden_index)) - boss_button.gui_input.connect(_on_boss_button_gui_input) _update_final_boss_scroll_space(final_boss_center, final_boss_size) @@ -1268,6 +1459,8 @@ func _on_minigame_button_pressed(scene_index: int, minigame_number: int) -> void if not minigame_scene: Log.error("Gardens: Missing minigame scene for index %d" % scene_index) return + # Block a second wedge click during the curtain-close await below. + _lock() feedback_audio_stream_player.play() await (OpeningCurtain as OpeningCurtainClass).close() Minigame.transition_data = { @@ -1308,19 +1501,6 @@ func _on_scroll_container_gui_input(event: InputEvent) -> void: scroll_container.scroll_horizontal -= int(motion_event.relative.x) -func _on_boss_button_gui_input(event: InputEvent) -> void: - # Boss buttons live outside the ScrollContainer, so without forwarding, - # their default STOP mouse filter would swallow scroll events that pass over them. - if event is InputEventMouseButton: - var mb: InputEventMouseButton = event - if mb.button_index == MOUSE_BUTTON_WHEEL_UP or mb.button_index == MOUSE_BUTTON_WHEEL_DOWN \ - or mb.button_index == MOUSE_BUTTON_WHEEL_LEFT or mb.button_index == MOUSE_BUTTON_WHEEL_RIGHT: - _on_scroll_container_gui_input(event) - return - if is_scrolling and event is InputEventMouseMotion: - _on_scroll_container_gui_input(event) - - func _scroll_by_garden(p_direction: int) -> void: var target_scroll: int = scroll_container.scroll_horizontal + p_direction * 200 scroll_container.scroll_horizontal = target_scroll @@ -1357,6 +1537,31 @@ func _on_area_2d_input_event(_viewport: Node, event: InputEvent, _shape_idx: int _close_minigames_layout() +# BackgroundRect spans the wheel screen with mouse_filter=STOP so it absorbs +# every click that doesn't hit the L&L button (which is on top of it). We +# dispatch the click to the matching wedge via point-in-polygon, or close the +# wheel if the click falls outside every wedge. +func _on_background_rect_gui_input(event: InputEvent) -> void: + if is_locked or not in_minigame_selection: + return + if not event.is_action_pressed("left_click"): + return + var click_pos: Vector2 = (event as InputEventMouseButton).position + for child: Node in wedges_container.get_children(): + if child is MinigameWedge: + var wedge: MinigameWedge = child + if Geometry2D.is_point_in_polygon(click_pos, wedge.polygon.polygon): + # Hit on a wedge — enabled ones launch the minigame; disabled + # ones play the wrong-click feedback. Either way the click is + # consumed so the wheel stays open. + if wedge.is_disabled: + wedge.wrong() + else: + wedge.pressed.emit() + return + _close_minigames_layout() + + func _on_kalulu_button_pressed() -> void: kalulu_button.hide() if current_garden.get_progress_ratio() > 0.75: diff --git a/sources/gardens/gardens.tscn b/sources/gardens/gardens.tscn index f0e14cee..d297d1e0 100644 --- a/sources/gardens/gardens.tscn +++ b/sources/gardens/gardens.tscn @@ -2,36 +2,17 @@ [ext_resource type="Script" uid="uid://djolw68efn6r5" path="res://sources/gardens/gardens.gd" id="1_qlsw4"] [ext_resource type="Texture2D" uid="uid://jlwblk7lj7vi" path="res://assets/vfx/fx_10.png" id="3_xbvhu"] -[ext_resource type="Texture2D" uid="uid://cq5wwf7y1msh7" path="res://assets/minigames/crabs/graphic/gauge_icon_crab_full.png" id="5_h8c5w"] -[ext_resource type="Texture2D" uid="uid://di2qcv6jw8wh0" path="res://assets/minigames/parakeets/graphic/gauge_icon_parakeet_full.png" id="6_hekq6"] -[ext_resource type="Texture2D" uid="uid://cq87j1xw4c31r" path="res://assets/minigames/jellyfish/graphic/gauge_icon_jellyfish_full.png" id="6_p30hm"] -[ext_resource type="Texture2D" uid="uid://cffuqacgb1jra" path="res://assets/lesson_screen/branches.png" id="7_axgdc"] -[ext_resource type="Texture2D" uid="uid://c3okdxpi317x5" path="res://assets/minigames/monkeys/graphic/gauge_icon_monkey_full.png" id="9_68su4"] -[ext_resource type="Texture2D" uid="uid://re7qgivb3n5w" path="res://assets/minigames/frog/graphics/gauge_icon_frog_full.png" id="10_5wvwc"] -[ext_resource type="Texture2D" uid="uid://nwbekpbuu472" path="res://assets/minigames/ants/graphics/gauge_icon_ant_full.png" id="12_ohgqx"] -[ext_resource type="Texture2D" uid="uid://bc3e0qths2cvt" path="res://assets/minigames/boss/boss_icon_full.png" id="16_5rwfp"] -[ext_resource type="Texture2D" uid="uid://bmdhpgxmur1vo" path="res://assets/minigames/caterpillar/graphics/gauge_icon_caterpillar_full.png" id="16_prl1o"] [ext_resource type="AudioStream" uid="uid://4bv1hr6r68op" path="res://assets/gardens/ui_transition_right.mp3" id="17_37f6y"] -[ext_resource type="Texture2D" uid="uid://rnqme2j272qf" path="res://assets/minigames/turtles/graphic/gauge_icon_turtle_full.png" id="18_12pcf"] [ext_resource type="AudioStream" uid="uid://bwgrj3quwtbvm" path="res://assets/gardens/ui_transition_left.mp3" id="18_bdar8"] -[ext_resource type="Texture2D" uid="uid://bb00fhnenbml5" path="res://assets/lesson_screen/big_button.png" id="20_elp7t"] -[ext_resource type="Texture2D" uid="uid://dq23np4euf6da" path="res://assets/minigames/penguin/graphic/gauge_icon_penguin_full.png" id="20_ouafq"] -[ext_resource type="Texture2D" uid="uid://dlnklpyefn0m2" path="res://assets/lesson_screen/big_button_center.png" id="21_r0a4h"] -[ext_resource type="Material" uid="uid://dne7hgkrp4tdy" path="res://resources/gardens/minigame_icon_material.tres" id="22_cgp31"] -[ext_resource type="Texture2D" uid="uid://dkomjpclxvmqf" path="res://assets/lesson_screen/top_left.png" id="23_p1d10"] -[ext_resource type="Texture2D" uid="uid://rux5delnabp5" path="res://assets/lesson_screen/top_right.png" id="24_30f83"] [ext_resource type="AudioStream" uid="uid://bgof22p2ofunc" path="res://assets/sfx/ui_yes_button.mp3" id="24_ljadf"] [ext_resource type="PackedScene" uid="uid://delcgui3v0eek" path="res://sources/lesson_screen/lesson_button.tscn" id="25_0ruwb"] [ext_resource type="Texture2D" uid="uid://dx7w01wdyq0b5" path="res://assets/particles/bigstar_x36_15fps.png" id="25_00sy7"] [ext_resource type="AudioStream" uid="uid://vyj4leik80w2" path="res://assets/sfx/swoosh.mp3" id="25_npbuv"] -[ext_resource type="Texture2D" uid="uid://cqhbpt3lk6f15" path="res://assets/lesson_screen/bottom.png" id="25_tyvq6"] [ext_resource type="AudioStream" uid="uid://dlxvbjp63w6wm" path="res://assets/look_and_learn/effect.wav" id="26_5g3l0"] -[ext_resource type="Script" uid="uid://ddew42fnpmsx1" path="res://sources/gardens/minigame_layout.gd" id="28_kvgph"] [ext_resource type="PackedScene" uid="uid://cyoioissvrkj8" path="res://sources/ui/back_button.tscn" id="29_back_button"] [ext_resource type="Texture2D" uid="uid://dj0ygi5q6kbdw" path="res://assets/minigames/minigame_ui/graphic/button_back_normal.png" id="29_cgp31"] [ext_resource type="Texture2D" uid="uid://gmoc5mxxfqin" path="res://assets/minigames/minigame_ui/graphic/button_back_pressed.png" id="30_wnxkf"] [ext_resource type="Texture2D" uid="uid://bnvx1mujmy3vf" path="res://assets/minigames/minigame_ui/graphic/button_back_disabled.png" id="31_b65yw"] -[ext_resource type="PackedScene" uid="uid://cn2rw06pltyiu" path="res://sources/utils/fx/right.tscn" id="33_5y3ye"] [ext_resource type="Texture2D" uid="uid://iw84x6mx8h2g" path="res://assets/minigames/minigame_ui/graphic/button_kalulu_normal.png" id="41_xcos2"] [ext_resource type="Texture2D" uid="uid://ub1dnysbojn8" path="res://assets/minigames/minigame_ui/graphic/button_kalulu_pressed.png" id="42_l35j3"] [ext_resource type="Texture2D" uid="uid://crnxawhf68po3" path="res://assets/minigames/minigame_ui/graphic/button_kalulu_disabled.png" id="43_jfyfk"] @@ -40,6 +21,25 @@ [ext_resource type="Texture2D" uid="uid://rx270y4n7tul" path="res://assets/minigames/parakeets/graphic/cloud_1.png" id="46_cloud1"] [ext_resource type="Texture2D" uid="uid://dphj3hqfnnw4p" path="res://assets/minigames/parakeets/graphic/cloud_2.png" id="47_cloud2"] [ext_resource type="Texture2D" uid="uid://1btgagsporxa" path="res://assets/minigames/parakeets/graphic/cloud_3.png" id="48_cloud3"] +[ext_resource type="Texture2D" uid="uid://d1j23o6nq476v" path="res://assets/gardens/animals/ant_body.png" id="ant_body"] +[ext_resource type="Texture2D" uid="uid://by3xfdin7jrsn" path="res://assets/gardens/animals/ant_face.png" id="ant_face"] +[ext_resource type="Texture2D" uid="uid://b6nrx0dn0h3f2" path="res://assets/gardens/animals/caterpillar_body.png" id="caterpillar_body"] +[ext_resource type="Texture2D" uid="uid://cnihbmks0piwi" path="res://assets/gardens/animals/caterpillar_face.png" id="caterpillar_face"] +[ext_resource type="Texture2D" uid="uid://b2e61oot7ht35" path="res://assets/gardens/animals/crab_body.png" id="crab_body"] +[ext_resource type="Texture2D" uid="uid://ruclqu4dc13u" path="res://assets/gardens/animals/crab_face.png" id="crab_face"] +[ext_resource type="Texture2D" uid="uid://oagcnmxs0xx1" path="res://assets/gardens/animals/frog_body.png" id="frog_body"] +[ext_resource type="Texture2D" uid="uid://b4243242f34g0" path="res://assets/gardens/animals/frog_face.png" id="frog_face"] +[ext_resource type="Texture2D" uid="uid://bb3we2it550v6" path="res://assets/gardens/animals/jellyfish_body.png" id="jellyfish_body"] +[ext_resource type="Texture2D" uid="uid://dppmdv8u3cwl1" path="res://assets/gardens/animals/jellyfish_face.png" id="jellyfish_face"] +[ext_resource type="Texture2D" uid="uid://dr12efhuotfgt" path="res://assets/gardens/animals/monkey_body.png" id="monkey_body"] +[ext_resource type="Texture2D" uid="uid://dc52xvm4y6rir" path="res://assets/gardens/animals/monkey_face.png" id="monkey_face"] +[ext_resource type="Texture2D" uid="uid://c1ml42sp1vqga" path="res://assets/gardens/buttons/movie_icon.png" id="movie_icon"] +[ext_resource type="Texture2D" uid="uid://c2yalimkyunxi" path="res://assets/gardens/animals/parakeet_body.png" id="parakeet_body"] +[ext_resource type="Texture2D" uid="uid://l52tfb7fdrpt" path="res://assets/gardens/animals/parakeet_face.png" id="parakeet_face"] +[ext_resource type="Texture2D" uid="uid://noekve4gjudr" path="res://assets/gardens/animals/penguin_body.png" id="penguin_body"] +[ext_resource type="Texture2D" uid="uid://dbg7mxg3x7vd4" path="res://assets/gardens/animals/penguin_face.png" id="penguin_face"] +[ext_resource type="Texture2D" uid="uid://b7rqldqdft30a" path="res://assets/gardens/animals/turtle_body.png" id="turtle_body"] +[ext_resource type="Texture2D" uid="uid://nu4kpbywwpgn" path="res://assets/gardens/animals/turtle_face.png" id="turtle_face"] [sub_resource type="CanvasItemMaterial" id="CanvasItemMaterial_ey6av"] blend_mode = 1 @@ -123,7 +123,8 @@ grow_vertical = 2 mouse_filter = 2 script = ExtResource("1_qlsw4") minigame_scene_paths = PackedStringArray("res://sources/minigames/jellyfish/jellyfish_minigame.tscn", "res://sources/minigames/crabs/crabs_minigame.tscn", "res://sources/minigames/parakeets/parakeets_minigame.tscn", "res://sources/minigames/monkeys/monkeys_minigame.tscn", "res://sources/minigames/caterpillar/caterpillar_minigame.tscn", "res://sources/minigames/frog/frog_minigame.tscn", "res://sources/minigames/turtles/turtles_minigame.tscn", "res://sources/minigames/ants/ants_minigame.tscn", "res://sources/minigames/penguin/penguin_minigame.tscn", "res://sources/minigames/boss/boss_minigame.tscn") -minigames_icons = Array[Texture]([ExtResource("6_p30hm"), ExtResource("5_h8c5w"), ExtResource("6_hekq6"), ExtResource("9_68su4"), ExtResource("16_prl1o"), ExtResource("10_5wvwc"), ExtResource("18_12pcf"), ExtResource("12_ohgqx"), ExtResource("20_ouafq"), ExtResource("16_5rwfp")]) +minigames_body_icons = Array[Texture]([ExtResource("jellyfish_body"), ExtResource("crab_body"), ExtResource("parakeet_body"), ExtResource("monkey_body"), ExtResource("caterpillar_body"), ExtResource("frog_body"), ExtResource("turtle_body"), ExtResource("ant_body"), ExtResource("penguin_body")]) +minigames_face_icons = Array[Texture]([ExtResource("jellyfish_face"), ExtResource("crab_face"), ExtResource("parakeet_face"), ExtResource("monkey_face"), ExtResource("caterpillar_face"), ExtResource("frog_face"), ExtResource("turtle_face"), ExtResource("ant_face"), ExtResource("penguin_face")]) [node name="RightAudioStreamPlayer" type="AudioStreamPlayer" parent="." unique_id=941811110] stream = ExtResource("17_37f6y") @@ -207,9 +208,8 @@ size_flags_horizontal = 3 custom_minimum_size = Vector2(80, 2.08165e-12) layout_mode = 2 -[node name="BossButtons" type="Control" parent="." unique_id=1176317047] +[node name="BossButtons" type="Control" parent="ScrollContainer" unique_id=1176317047] unique_name_in_owner = true -anchors_preset = 0 mouse_filter = 2 [node name="LockedLine" type="Line2D" parent="." unique_id=1229207154] @@ -237,20 +237,6 @@ volume_db = -5.0 [node name="CanvasLayer" type="CanvasLayer" parent="." unique_id=1456876816] -[node name="MinigameBackgroundCenter" type="TextureRect" parent="CanvasLayer" unique_id=380724732] -unique_name_in_owner = true -visible = false -modulate = Color(0.109804, 0.14902, 0.384314, 1) -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -mouse_filter = 2 -texture = ExtResource("21_r0a4h") -expand_mode = 1 -stretch_mode = 5 - [node name="MinigameSelection" type="Control" parent="CanvasLayer" unique_id=613163331] unique_name_in_owner = true visible = false @@ -265,121 +251,17 @@ grow_vertical = 2 pivot_offset = Vector2(1280, 900) mouse_filter = 2 -[node name="MinigameBackground1" type="TextureRect" parent="CanvasLayer/MinigameSelection" unique_id=405469610] +[node name="BackgroundRect" type="ColorRect" parent="CanvasLayer/MinigameSelection" unique_id=380724732] unique_name_in_owner = true -layout_mode = 0 -offset_right = 40.0 -offset_bottom = 40.0 -mouse_filter = 2 -texture = ExtResource("23_p1d10") -script = ExtResource("28_kvgph") - -[node name="TextureRect" type="TextureRect" parent="CanvasLayer/MinigameSelection/MinigameBackground1" unique_id=1383000761] -material = ExtResource("22_cgp31") -custom_minimum_size = Vector2(256, 256) -layout_mode = 0 -offset_left = 704.0 -offset_top = 576.0 -offset_right = 960.0 -offset_bottom = 832.0 -size_flags_horizontal = 4 -size_flags_vertical = 4 -texture = ExtResource("10_5wvwc") -expand_mode = 1 -stretch_mode = 5 - -[node name="RightFX" parent="CanvasLayer/MinigameSelection/MinigameBackground1/TextureRect" unique_id=1031123340 instance=ExtResource("33_5y3ye")] layout_mode = 1 -anchors_preset = 8 -anchor_left = 0.5 -anchor_top = 0.5 -anchor_right = 0.5 -anchor_bottom = 0.5 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 2 -[node name="Area2D" type="Area2D" parent="CanvasLayer/MinigameSelection/MinigameBackground1" unique_id=802836280] - -[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="CanvasLayer/MinigameSelection/MinigameBackground1/Area2D" unique_id=1785915721] -polygon = PackedVector2Array(1279, 61.6, 1284, 63.6, 1284, 901.8, 1280.8, 905, 1278.5, 905, 556, 1324.3, 554, 1323.2, 554, 1321.5, 513, 1244.5, 513, 1241.3, 489, 1185.4, 489, 1184.3, 467, 1114.3, 467, 1109, 459, 1080.3, 459, 1079, 458.1, 1066, 455, 1061.6, 455, 1060, 446, 1005.2, 446, 1004, 440, 930.1, 440, 865, 441.1, 865, 445.1, 801, 446.3, 801, 460.3, 713, 461.5, 713, 481.5, 638, 482.6, 638, 500.6, 586, 501.7, 586, 513, 562.5, 513, 561.5, 510.8, 557, 513.7, 557, 540.7, 501, 541.9, 501, 570.8, 450, 572.2, 450, 576, 446.2, 574.6, 444.5, 575.7, 442, 577, 442, 587, 429.3, 587, 425.5, 588.8, 422, 590, 422, 639, 357, 640.1, 357, 691.1, 301, 693.1, 301, 745.2, 252, 747.3, 252, 809.3, 204, 811.4, 204, 865.4, 169, 867.5, 169, 957.5, 124, 960.6, 124, 996, 111.6, 996, 111, 1001.3, 107, 1002.9, 107, 1022, 102.5, 1025.2, 99, 1026.8, 99, 1075.7, 85, 1077.2, 85, 1080, 85.5, 1110.7, 77, 1113.2, 77, 1115.6, 77.6, 1118.2, 75, 1119.7, 75, 1182.8, 65, 1184.8, 65, 1185.8, 66, 1204.8, 63, 1207.6, 63, 1209.2, 64.1, 1212.4, 62, 1214.5, 62, 1216.6, 63.1, 1252, 61.1, 1252, 60, 1279, 60) - -[node name="MinigameBackground2" type="TextureRect" parent="CanvasLayer/MinigameSelection" unique_id=1529070021] +[node name="WedgesContainer" type="Control" parent="CanvasLayer/MinigameSelection" unique_id=1010111213] unique_name_in_owner = true -layout_mode = 0 -offset_right = 2560.0 -offset_bottom = 1800.0 -mouse_filter = 2 -texture = ExtResource("24_30f83") -script = ExtResource("28_kvgph") - -[node name="TextureRect" type="TextureRect" parent="CanvasLayer/MinigameSelection/MinigameBackground2" unique_id=373021186] -material = ExtResource("22_cgp31") -custom_minimum_size = Vector2(256, 256) -layout_mode = 0 -offset_left = 1600.0 -offset_top = 576.0 -offset_right = 1856.0 -offset_bottom = 832.0 -size_flags_horizontal = 4 -size_flags_vertical = 4 -texture = ExtResource("10_5wvwc") -expand_mode = 1 -stretch_mode = 5 - -[node name="RightFX" parent="CanvasLayer/MinigameSelection/MinigameBackground2/TextureRect" unique_id=1160342672 instance=ExtResource("33_5y3ye")] -layout_mode = 1 -anchors_preset = 8 -anchor_left = 0.5 -anchor_top = 0.5 -anchor_right = 0.5 -anchor_bottom = 0.5 -grow_horizontal = 2 -grow_vertical = 2 - -[node name="Area2D" type="Area2D" parent="CanvasLayer/MinigameSelection/MinigameBackground2" unique_id=204471632] - -[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="CanvasLayer/MinigameSelection/MinigameBackground2/Area2D" unique_id=1948283316] -polygon = PackedVector2Array(1378, 65.1, 1378, 66.3, 1457, 78.3, 1457, 79.5, 1537, 99.4, 1537, 100.6, 1608, 125.6, 1608, 126.7, 1663, 151.7, 1663, 153, 1671.5, 159, 1673.3, 159, 1682, 161.5, 1682, 162.9, 1750, 202.9, 1750, 204, 1801, 240, 1801, 241.1, 1839, 272.1, 1839, 273.1, 1879, 310.1, 1879, 312.4, 1880.1, 314, 1885, 315.6, 1885, 318.2, 1936, 374.2, 1936, 376.3, 1983, 438.3, 1983, 439.5, 2026, 511.4, 2026, 515.5, 2044, 547.5, 2044, 548.6, 2045.7, 557, 2046.3, 557, 2061, 587.5, 2061, 590.6, 2082, 646.6, 2082, 651, 2082.7, 655, 2087, 661.4, 2087, 663, 2107, 744.8, 2107, 748, 2119, 835.9, 2119, 837, 2121, 923, 2120, 923, 2120, 955, 2118.8, 955, 2111.8, 1029, 2110.7, 1029, 2104.7, 1068, 2103.7, 1068, 2098.7, 1096, 2097.5, 1096, 2088, 1127.3, 2088, 1128.7, 2089.8, 1134, 2087.4, 1134, 2052.4, 1235, 2051.3, 1235, 2017.3, 1306, 2016.3, 1306, 2010.2, 1317, 2008.5, 1317, 2003, 1320.3, 2001, 1319.2, 2001, 1318.1, 1276, 902.2, 1276, 63.9, 1279, 61.9, 1279, 59.9) - -[node name="MinigameBackground3" type="TextureRect" parent="CanvasLayer/MinigameSelection" unique_id=433963142] -unique_name_in_owner = true -layout_mode = 0 -offset_right = 2560.0 -offset_bottom = 1800.0 -mouse_filter = 2 -texture = ExtResource("25_tyvq6") -script = ExtResource("28_kvgph") - -[node name="TextureRect" type="TextureRect" parent="CanvasLayer/MinigameSelection/MinigameBackground3" unique_id=1532680395] -material = ExtResource("22_cgp31") -custom_minimum_size = Vector2(256, 256) -layout_mode = 0 -offset_left = 1152.0 -offset_top = 1248.0 -offset_right = 1408.0 -offset_bottom = 1504.0 -size_flags_horizontal = 4 -size_flags_vertical = 4 -texture = ExtResource("10_5wvwc") -expand_mode = 1 -stretch_mode = 5 - -[node name="RightFX" parent="CanvasLayer/MinigameSelection/MinigameBackground3/TextureRect" unique_id=151107649 instance=ExtResource("33_5y3ye")] -layout_mode = 1 -anchors_preset = 8 -anchor_left = 0.5 -anchor_top = 0.5 -anchor_right = 0.5 -anchor_bottom = 0.5 -grow_horizontal = 2 -grow_vertical = 2 - -[node name="Area2D" type="Area2D" parent="CanvasLayer/MinigameSelection/MinigameBackground3" unique_id=1208926048] - -[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="CanvasLayer/MinigameSelection/MinigameBackground3/Area2D" unique_id=890040811] -polygon = PackedVector2Array(1902, 1250.8, 1902, 1251.9, 2010.3, 1316.1, 2009.5, 1319, 2008.1, 1319, 1986.2, 1358, 1985, 1358, 1974, 1371.7, 1974, 1372.4, 1970.4, 1382, 1969, 1382, 1916, 1451, 1914.9, 1451, 1865.9, 1504, 1863.8, 1504, 1827.8, 1539, 1825.7, 1539, 1791.7, 1568, 1789.6, 1568, 1720.6, 1617, 1717.7, 1617, 1702.7, 1628, 1700.5, 1628, 1633.5, 1664, 1632.6, 1664, 1556.4, 1695, 1555.1, 1695, 1509, 1707.5, 1509, 1708.3, 1498.4, 1713, 1497.4, 1713, 1407.2, 1732, 1406.2, 1732, 1330.1, 1740, 1328, 1740, 1254, 1741, 1254, 1739.9, 1184, 1735.9, 1184, 1734.8, 1112, 1724.7, 1112, 1723.5, 1094.7, 1718, 1085, 1719.3, 1085, 1717.4, 1072.6, 1713, 1065, 1714.4, 1065, 1712.4, 1030.7, 1701, 1030.1, 1701, 1024, 1702.6, 1024, 1700.5, 1009, 1696.5, 1009, 1695, 1006.3, 1693, 994, 1691.8, 994, 1690.4, 969, 1681.4, 969, 1680.1, 964.3, 1677, 962.8, 1677, 961.5, 1678.4, 959, 1677.3, 959, 1676.4, 924, 1662.4, 924, 1661.3, 875, 1637.2, 875, 1636.1, 826, 1608.2, 826, 1607.1, 781, 1577.1, 781, 1576, 738, 1543, 738, 1541.9, 695, 1503.9, 695, 1502.8, 661, 1468.8, 661, 1466.7, 615, 1414.8, 615, 1412.7, 582, 1368.7, 582, 1365.6, 553.7, 1321.1, 554.8, 1319, 556, 1319, 560, 1314, 562.5, 1314, 619.4, 1279, 621.5, 1279, 1276, 897.9, 1276, 894.6) - -[node name="Branches" type="TextureRect" parent="CanvasLayer/MinigameSelection" unique_id=301987876] layout_mode = 1 anchors_preset = 15 anchor_right = 1.0 @@ -387,10 +269,16 @@ anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 2 mouse_filter = 2 -texture = ExtResource("7_axgdc") + +[node name="LessonButtonOutline" type="Line2D" parent="CanvasLayer/MinigameSelection" unique_id=1010111290] +unique_name_in_owner = true +z_index = 11 +width = 12.0 +joint_mode = 2 [node name="LessonButton" parent="CanvasLayer/MinigameSelection" unique_id=843010913 instance=ExtResource("25_0ruwb")] unique_name_in_owner = true +z_index = 10 layout_mode = 1 anchors_preset = 8 anchor_left = 0.5 @@ -404,6 +292,25 @@ offset_bottom = 192.0 grow_horizontal = 2 grow_vertical = 2 +[node name="MovieIcon" type="TextureRect" parent="CanvasLayer/MinigameSelection/LessonButton" unique_id=1010111291] +unique_name_in_owner = true +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -42.0 +offset_top = -94.0 +offset_right = 42.0 +offset_bottom = -10.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +texture = ExtResource("movie_icon") +expand_mode = 1 +stretch_mode = 6 + [node name="LessonButtonParticles" type="GPUParticles2D" parent="CanvasLayer/MinigameSelection/LessonButton" unique_id=1605639976] unique_name_in_owner = true z_index = 1 @@ -414,21 +321,6 @@ emitting = false texture = ExtResource("25_00sy7") process_material = SubResource("ParticleProcessMaterial_4gqpn") -[node name="MinigameBackground" type="TextureRect" parent="CanvasLayer" unique_id=2050203805] -unique_name_in_owner = true -visible = false -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -size_flags_horizontal = 4 -size_flags_vertical = 4 -mouse_filter = 2 -texture = ExtResource("20_elp7t") -expand_mode = 1 -stretch_mode = 5 - [node name="BackButton" parent="CanvasLayer" unique_id=1838227918 instance=ExtResource("29_back_button")] custom_minimum_size = Vector2(275, 275) offset_left = 50.0 @@ -513,6 +405,7 @@ texture = ExtResource("47_cloud2") texture = ExtResource("48_cloud3") [connection signal="gui_input" from="ScrollContainer" to="." method="_on_scroll_container_gui_input"] +[connection signal="gui_input" from="CanvasLayer/MinigameSelection/BackgroundRect" to="." method="_on_background_rect_gui_input"] [connection signal="pressed" from="CanvasLayer/MinigameSelection/LessonButton" to="." method="_on_lesson_button_pressed"] [connection signal="button_down" from="CanvasLayer/BackButton" to="." method="_on_back_button_button_down"] [connection signal="button_up" from="CanvasLayer/BackButton" to="." method="_on_back_button_button_up"] diff --git a/sources/gardens/minigame_layout.gd b/sources/gardens/minigame_layout.gd deleted file mode 100644 index b5ee2bcb..00000000 --- a/sources/gardens/minigame_layout.gd +++ /dev/null @@ -1,23 +0,0 @@ -class_name MinigameLayout -extends TextureRect - -signal pressed() - -var is_disabled: bool = false - -@onready var icon: TextureRect = $TextureRect -@onready var area: Area2D = $Area2D -@onready var right_fx: RightFX = $TextureRect/RightFX - - -func _ready() -> void: - area.connect("input_event", _on_click) - - -func _on_click(_viewport: Node, event: InputEvent, _shape_idx: int) -> void: - if event.is_action_pressed("left_click") and not is_disabled: - pressed.emit() - - -func right() -> void: - right_fx.play() diff --git a/sources/gardens/minigame_layout.gd.uid b/sources/gardens/minigame_layout.gd.uid deleted file mode 100644 index 029ed474..00000000 --- a/sources/gardens/minigame_layout.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://ddew42fnpmsx1 diff --git a/sources/gardens/minigame_wedge.gd b/sources/gardens/minigame_wedge.gd new file mode 100644 index 00000000..6ac03ff9 --- /dev/null +++ b/sources/gardens/minigame_wedge.gd @@ -0,0 +1,61 @@ +class_name MinigameWedge +extends Control + +signal pressed() + +const ICON_SIZE: Vector2 = Vector2(256, 256) +const GRAYSCALE_SHADER: Shader = preload("res://resources/shaders/grayscale.gdshader") + +var is_disabled: bool = false + +@onready var polygon: Polygon2D = $Polygon2D +@onready var area: Area2D = $Area2D +@onready var collision: CollisionPolygon2D = $Area2D/CollisionPolygon2D +@onready var icon_body_rect: TextureRect = $IconBodyRect +@onready var icon_face_rect: TextureRect = $IconFaceRect +@onready var right_fx: RightFX = $IconFaceRect/RightFX +@onready var wrong_fx: WrongFX = $IconFaceRect/WrongFX + + +func _ready() -> void: + area.input_event.connect(_on_click) + + +func configure( + wedge_polygon: PackedVector2Array, + icon_center: Vector2, + body_texture: Texture, + face_texture: Texture, + wedge_color: Color, + body_color: Color, + is_locked: bool, +) -> void: + polygon.polygon = wedge_polygon + polygon.color = wedge_color + collision.polygon = wedge_polygon + var icon_origin: Vector2 = icon_center - ICON_SIZE * 0.5 + icon_body_rect.position = icon_origin + icon_body_rect.texture = body_texture + icon_body_rect.modulate = body_color + icon_face_rect.position = icon_origin + icon_face_rect.texture = face_texture + # Desaturate the face when locked. + if is_locked: + var grayscale: ShaderMaterial = ShaderMaterial.new() + grayscale.shader = GRAYSCALE_SHADER + icon_face_rect.material = grayscale + else: + icon_face_rect.material = null + + +func right() -> void: + right_fx.play() + + +func wrong() -> void: + wrong_fx.play() + + +func _on_click(_viewport: Node, event: InputEvent, _shape_idx: int) -> void: + if event.is_action_pressed("left_click") and not is_disabled: + pressed.emit() diff --git a/sources/gardens/minigame_wedge.gd.uid b/sources/gardens/minigame_wedge.gd.uid new file mode 100644 index 00000000..8d05e1ef --- /dev/null +++ b/sources/gardens/minigame_wedge.gd.uid @@ -0,0 +1 @@ +uid://dh555xp8ebnb8 diff --git a/sources/gardens/minigame_wedge.tscn b/sources/gardens/minigame_wedge.tscn new file mode 100644 index 00000000..ffc06c07 --- /dev/null +++ b/sources/gardens/minigame_wedge.tscn @@ -0,0 +1,63 @@ +[gd_scene format=3 uid="uid://b1u0xkalulu01"] + +[ext_resource type="Script" uid="uid://dh555xp8ebnb8" path="res://sources/gardens/minigame_wedge.gd" id="1_wedge"] +[ext_resource type="PackedScene" uid="uid://cn2rw06pltyiu" path="res://sources/utils/fx/right.tscn" id="3_rightfx"] +[ext_resource type="PackedScene" uid="uid://dlmbxcgiv8tpr" path="res://sources/utils/fx/wrong.tscn" id="4_wrongfx"] + +[node name="MinigameWedge" type="Control" unique_id=1762693146] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +script = ExtResource("1_wedge") + +[node name="Polygon2D" type="Polygon2D" parent="." unique_id=1912619179] + +[node name="Area2D" type="Area2D" parent="." unique_id=870297940] + +[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="Area2D" unique_id=1114106226] + +[node name="IconBodyRect" type="TextureRect" parent="." unique_id=2053672816] +custom_minimum_size = Vector2(256, 256) +layout_mode = 0 +offset_right = 256.0 +offset_bottom = 256.0 +size_flags_horizontal = 4 +size_flags_vertical = 4 +mouse_filter = 2 +expand_mode = 1 +stretch_mode = 5 + +[node name="IconFaceRect" type="TextureRect" parent="." unique_id=2053672817] +custom_minimum_size = Vector2(256, 256) +layout_mode = 0 +offset_right = 256.0 +offset_bottom = 256.0 +size_flags_horizontal = 4 +size_flags_vertical = 4 +mouse_filter = 2 +expand_mode = 1 +stretch_mode = 5 + +[node name="RightFX" parent="IconFaceRect" unique_id=333957231 instance=ExtResource("3_rightfx")] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="WrongFX" parent="IconFaceRect" unique_id=333957232 instance=ExtResource("4_wrongfx")] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +grow_horizontal = 2 +grow_vertical = 2 diff --git a/sources/utils/autoloads/database.gd b/sources/utils/autoloads/database.gd index 3e635b07..224f5ad7 100644 --- a/sources/utils/autoloads/database.gd +++ b/sources/utils/autoloads/database.gd @@ -104,13 +104,13 @@ func get_exercise_for_lesson(lesson_nb: int) -> Array[int]: INNER JOIN Lessons ON Lessons.ID = LessonsExercises.LessonID WHERE LessonNB == " + str(lesson_nb) db.query(query) - + # Exercise* == 0 means "no minigame in this slot": drop zeros so size = count. var result: Array[int] = [] for element: Dictionary in db.query_result: - result.append(element.Exercise1) - result.append(element.Exercise2) - result.append(element.Exercise3) - + for column: String in ["Exercise1", "Exercise2", "Exercise3"]: + var exercise_id: int = element[column] as int + if exercise_id > 0: + result.append(exercise_id) return result From fe696c8b20fc5af9c20b6a699e12e92c881fcd94 Mon Sep 17 00:00:00 2001 From: Adrien Ufferte Date: Sat, 6 Jun 2026 17:20:47 +0200 Subject: [PATCH 2/3] debug lessons numbers different from 3 --- resources/user/student_progression.gd | 36 ++++++++++-- sources/menus/settings/lesson_unlock.gd | 77 ++++++++++++------------- 2 files changed, 69 insertions(+), 44 deletions(-) diff --git a/resources/user/student_progression.gd b/resources/user/student_progression.gd index 64b4bf26..67736be5 100644 --- a/resources/user/student_progression.gd +++ b/resources/user/student_progression.gd @@ -55,6 +55,25 @@ static func _make_zero_durations(minigame_count: int) -> PackedInt32Array: return durations +# Resizes a games status array to target_size, keeping the existing statuses for +# the slots that remain (trim surplus / pad new slots with LOCKED). Used when a +# lesson's minigame count changes so old saves don't lose progress on resize. +static func _resize_games_array(games: Array, target_size: int) -> Array: + var resized: Array = [] + for index: int in range(target_size): + resized.append(games[index] if index < games.size() else Status.LOCKED) + return resized + + +# Same idea for the duration metrics: keep recorded times for remaining slots. +static func _resize_durations(durations: PackedInt32Array, target_size: int) -> PackedInt32Array: + var resized: PackedInt32Array = PackedInt32Array() + resized.resize(target_size) + for index: int in range(mini(target_size, durations.size())): + resized[index] = durations[index] + return resized + + # Make sure the unlocks are correct func init_unlocks() -> void: if not unlocks: @@ -111,17 +130,24 @@ func ensure_data_integrity(data: Dictionary[int, Dictionary]) -> Dictionary: if not garden.has("total_duration"): garden["total_duration"] = _make_zero_durations(minigame_count) - # Check array "games" - if typeof(garden["games"]) != TYPE_ARRAY or (garden["games"] as Array).size() != minigame_count: + # Check array "games": a corrupt (non-array) value is reset, but a size + # mismatch (the lesson's minigame count changed) is resized in place so we + # keep existing progress for the slots that remain instead of wiping it. + if typeof(garden["games"]) != TYPE_ARRAY: if not is_init: Log.warn("StudentProgression: Garden %d: invalid format for 'games' → reset." % index) garden["games"] = _make_locked_games_array(minigame_count) + elif (garden["games"] as Array).size() != minigame_count: + if not is_init: + Log.warn("StudentProgression: Garden %d: 'games' resized from %d to %d, progress preserved." % [index, (garden["games"] as Array).size(), minigame_count]) + garden["games"] = _resize_games_array(garden["games"] as Array, minigame_count) - # Make sure duration arrays match the minigame count + # Keep duration metrics aligned with the minigame count, preserving the + # recorded times for the slots that remain. if (garden["last_duration"] as PackedInt32Array).size() != minigame_count: - garden["last_duration"] = _make_zero_durations(minigame_count) + garden["last_duration"] = _resize_durations(garden["last_duration"] as PackedInt32Array, minigame_count) if (garden["total_duration"] as PackedInt32Array).size() != minigame_count: - garden["total_duration"] = _make_zero_durations(minigame_count) + garden["total_duration"] = _resize_durations(garden["total_duration"] as PackedInt32Array, minigame_count) # Check value outside of possible enum values for game_index: int in range((garden["games"] as Array).size()): diff --git a/sources/menus/settings/lesson_unlock.gd b/sources/menus/settings/lesson_unlock.gd index a2d2da6d..82d8b02d 100644 --- a/sources/menus/settings/lesson_unlock.gd +++ b/sources/menus/settings/lesson_unlock.gd @@ -23,7 +23,7 @@ func _ready() -> void: exercise_option_button_1.add_item(tr(status)) exercise_option_button_2.add_item(tr(status)) exercise_option_button_3.add_item(tr(status)) - + reload() @@ -45,77 +45,76 @@ func reload() -> void: func _set_lesson_number(value: int) -> void: lesson_number = value - + if not lesson_label: return - + lesson_label.text = str(lesson_number) - + look_and_learn_option_button.select(unlocks[lesson_number]["look_and_learn"] as int) - exercise_option_button_1.select(unlocks[lesson_number]["games"][0] as int) - exercise_option_button_2.select(unlocks[lesson_number]["games"][1] as int) - exercise_option_button_3.select(unlocks[lesson_number]["games"][2] as int) + # A lesson can have 1–3 minigames, so only populate the buttons that map to a + # real game and disable the surplus ones (the grid keeps all three cells). + var games: Array = unlocks[lesson_number]["games"] + var exercise_buttons: Array[OptionButton] = [exercise_option_button_1, exercise_option_button_2, exercise_option_button_3] + for index: int in range(exercise_buttons.size()): + var button: OptionButton = exercise_buttons[index] + if index < games.size(): + button.disabled = false + button.select(games[index] as int) + else: + button.disabled = true + button.select(-1) func _set_lesson_gps(value: String) -> void: lesson_gps = value if not gps_label: return - + gps_label.text = value func _on_look_and_learn_option_button_item_selected(index: int) -> void: unlocks[lesson_number]["look_and_learn"] = index - + if index == StudentProgression.Status.LOCKED: if lesson_number == 1: unlocks[lesson_number]["look_and_learn"] = StudentProgression.Status.UNLOCKED else: unlocks[lesson_number - 1]["look_and_learn"] = StudentProgression.Status.UNLOCKED - unlocks[lesson_number - 1]["games"][0] = StudentProgression.Status.LOCKED - unlocks[lesson_number - 1]["games"][1] = StudentProgression.Status.LOCKED - unlocks[lesson_number - 1]["games"][2] = StudentProgression.Status.LOCKED - - unlocks[lesson_number]["games"][0] = StudentProgression.Status.LOCKED - unlocks[lesson_number]["games"][1] = StudentProgression.Status.LOCKED - unlocks[lesson_number]["games"][2] = StudentProgression.Status.LOCKED - + _set_lesson_games(lesson_number - 1, StudentProgression.Status.LOCKED) + + _set_lesson_games(lesson_number, StudentProgression.Status.LOCKED) + for lesson: int in unlocks.keys(): if lesson > lesson_number: unlocks[lesson]["look_and_learn"] = StudentProgression.Status.LOCKED - unlocks[lesson]["games"][0] = StudentProgression.Status.LOCKED - unlocks[lesson]["games"][1] = StudentProgression.Status.LOCKED - unlocks[lesson]["games"][2] = StudentProgression.Status.LOCKED - + _set_lesson_games(lesson, StudentProgression.Status.LOCKED) + elif index == StudentProgression.Status.UNLOCKED: - unlocks[lesson_number]["games"][0] = StudentProgression.Status.LOCKED - unlocks[lesson_number]["games"][1] = StudentProgression.Status.LOCKED - unlocks[lesson_number]["games"][2] = StudentProgression.Status.LOCKED + _set_lesson_games(lesson_number, StudentProgression.Status.LOCKED) for lesson: int in unlocks.keys(): if lesson < lesson_number: unlocks[lesson]["look_and_learn"] = StudentProgression.Status.COMPLETED - unlocks[lesson]["games"][0] = StudentProgression.Status.COMPLETED - unlocks[lesson]["games"][1] = StudentProgression.Status.COMPLETED - unlocks[lesson]["games"][2] = StudentProgression.Status.COMPLETED + _set_lesson_games(lesson, StudentProgression.Status.COMPLETED) elif lesson > lesson_number: unlocks[lesson]["look_and_learn"] = StudentProgression.Status.LOCKED - unlocks[lesson]["games"][0] = StudentProgression.Status.LOCKED - unlocks[lesson]["games"][1] = StudentProgression.Status.LOCKED - unlocks[lesson]["games"][2] = StudentProgression.Status.LOCKED + _set_lesson_games(lesson, StudentProgression.Status.LOCKED) elif index == StudentProgression.Status.COMPLETED: - unlocks[lesson_number]["games"][0] = StudentProgression.Status.UNLOCKED - unlocks[lesson_number]["games"][1] = StudentProgression.Status.UNLOCKED - unlocks[lesson_number]["games"][2] = StudentProgression.Status.UNLOCKED + _set_lesson_games(lesson_number, StudentProgression.Status.UNLOCKED) for lesson: int in unlocks.keys(): if lesson < lesson_number: unlocks[lesson]["look_and_learn"] = StudentProgression.Status.COMPLETED - unlocks[lesson]["games"][0] = StudentProgression.Status.COMPLETED - unlocks[lesson]["games"][1] = StudentProgression.Status.COMPLETED - unlocks[lesson]["games"][2] = StudentProgression.Status.COMPLETED + _set_lesson_games(lesson, StudentProgression.Status.COMPLETED) elif lesson > lesson_number: unlocks[lesson]["look_and_learn"] = StudentProgression.Status.LOCKED - unlocks[lesson]["games"][0] = StudentProgression.Status.LOCKED - unlocks[lesson]["games"][1] = StudentProgression.Status.LOCKED - unlocks[lesson]["games"][2] = StudentProgression.Status.LOCKED + _set_lesson_games(lesson, StudentProgression.Status.LOCKED) unlocks_changed.emit() + + +# Sets every minigame of a lesson to the same status, respecting the lesson's +# actual minigame count (1–3) rather than assuming a fixed three. +func _set_lesson_games(lesson: int, status: StudentProgression.Status) -> void: + var games: Array = unlocks[lesson]["games"] + for game_index: int in range(games.size()): + games[game_index] = status From fcd84fdb356948cbf35a20d091dbc2f6c0e3c6e0 Mon Sep 17 00:00:00 2001 From: Adrien Ufferte Date: Sat, 6 Jun 2026 18:11:45 +0200 Subject: [PATCH 3/3] Protect against out of bounds for minigame index --- sources/gardens/gardens.gd | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sources/gardens/gardens.gd b/sources/gardens/gardens.gd index 9bfd1d66..71deb8cd 100644 --- a/sources/gardens/gardens.gd +++ b/sources/gardens/gardens.gd @@ -784,6 +784,13 @@ func _build_wheel(exercises: Array[int], lesson_unlocks: Dictionary) -> void: var layout: Dictionary = _get_wedge_layout(minigame_count, wedge_index) var exercise_type: int = exercises[wedge_index] var icon_index: int = exercise_type - 1 + # Guard against exercise types with no matching wheel icon (e.g. the + # removed fish minigame, type 10): fall back to the highest available one + # so we never index past the icon arrays. + var max_icon_index: int = minigames_body_icons.size() - 1 + if icon_index < 0 or icon_index > max_icon_index: + Log.error("Gardens: Exercise type %d has no wheel icon (%d available); using the highest available minigame instead." % [exercise_type, minigames_body_icons.size()]) + icon_index = clampi(icon_index, 0, max_icon_index) var status: StudentProgression.Status = lesson_unlocks["games"][wedge_index] as StudentProgression.Status var wedge: MinigameWedge = MINIGAME_WEDGE_SCENE.instantiate() wedges_container.add_child(wedge)