From d6cdf5b2ebb826c2105cd8b4d506aa3f348cf598 Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Tue, 25 Mar 2025 22:03:18 -0400 Subject: [PATCH] Initial save game UI work (WIP) --- save_load/assets/folder-open-hover.png | Bin 0 -> 887 bytes save_load/assets/folder-open-hover.png.import | 34 ++++++ save_load/assets/folder-open-normal.png | Bin 0 -> 842 bytes .../assets/folder-open-normal.png.import | 34 ++++++ save_load/assets/folder-open-pressed.png | Bin 0 -> 771 bytes .../assets/folder-open-pressed.png.import | 34 ++++++ save_load/assets/save-hover.png | Bin 0 -> 869 bytes save_load/assets/save-hover.png.import | 34 ++++++ save_load/assets/save-normal.png | Bin 0 -> 855 bytes save_load/assets/save-normal.png.import | 34 ++++++ save_load/assets/save-pressed.png | Bin 0 -> 773 bytes save_load/assets/save-pressed.png.import | 34 ++++++ save_load/assets/trash-hover.png | Bin 0 -> 860 bytes save_load/assets/trash-hover.png.import | 34 ++++++ save_load/assets/trash-normal.png | Bin 0 -> 826 bytes save_load/assets/trash-normal.png.import | 34 ++++++ save_load/assets/trash-pressed.png | Bin 0 -> 768 bytes save_load/assets/trash-pressed.png.import | 34 ++++++ save_load/autoloads/save_game_manager.gd | 22 ++-- .../components/save_level_data_component.gd | 82 ++++++++------ .../save_file_highlight_panel_theme.tres | 4 + .../resources/save_file_panel_theme.tres | 8 ++ save_load/ui/save_file.gd | 63 +++++++++++ save_load/ui/save_file.gd.uid | 1 + save_load/ui/save_file.tscn | 100 ++++++++++++++++++ save_load/ui/save_files_list.gd | 29 +++++ save_load/ui/save_files_list.gd.uid | 1 + save_load/ui/save_load_ui.tscn | 50 +++++++++ 28 files changed, 624 insertions(+), 42 deletions(-) create mode 100644 save_load/assets/folder-open-hover.png create mode 100644 save_load/assets/folder-open-hover.png.import create mode 100644 save_load/assets/folder-open-normal.png create mode 100644 save_load/assets/folder-open-normal.png.import create mode 100644 save_load/assets/folder-open-pressed.png create mode 100644 save_load/assets/folder-open-pressed.png.import create mode 100644 save_load/assets/save-hover.png create mode 100644 save_load/assets/save-hover.png.import create mode 100644 save_load/assets/save-normal.png create mode 100644 save_load/assets/save-normal.png.import create mode 100644 save_load/assets/save-pressed.png create mode 100644 save_load/assets/save-pressed.png.import create mode 100644 save_load/assets/trash-hover.png create mode 100644 save_load/assets/trash-hover.png.import create mode 100644 save_load/assets/trash-normal.png create mode 100644 save_load/assets/trash-normal.png.import create mode 100644 save_load/assets/trash-pressed.png create mode 100644 save_load/assets/trash-pressed.png.import create mode 100644 save_load/resources/save_file_highlight_panel_theme.tres create mode 100644 save_load/resources/save_file_panel_theme.tres create mode 100644 save_load/ui/save_file.gd create mode 100644 save_load/ui/save_file.gd.uid create mode 100644 save_load/ui/save_file.tscn create mode 100644 save_load/ui/save_files_list.gd create mode 100644 save_load/ui/save_files_list.gd.uid create mode 100644 save_load/ui/save_load_ui.tscn diff --git a/save_load/assets/folder-open-hover.png b/save_load/assets/folder-open-hover.png new file mode 100644 index 0000000000000000000000000000000000000000..06ead5b436be70d30aad0287095b259781d4dfd8 GIT binary patch literal 887 zcmV--1Bm>IP)@$Gi#A0>i;|F9^s;%1 zK*%Tx!d4kf1=7Ol1(FJjpoU0<(kDpEX>sq+^>*&eeVcpF%y0QW4}b2L|LgOdThXi- zM)5FqVH3u+uakHYPbT)qhYvjAO*ZMZ&hb_xgZO`Em-6gDT$ChOTUv>IKByAt-Z zxKmMn)wZV?rtndYpjB*0*rz%Igrc0mb{uc<#3Wu8LuD9|T+<>|J6BQ8h++Ez5uFr6 zKYshK_!jTuHAVURe39(07LI7YG>+Tx9KILB{ey!XEa;rZa8L|;2M0ME&ZS3w)9|*)X`89E?sTY-^VrWLq0guXQns>o74ShAS5jGKP!r4EFTtMZ2H6 zS`2Fx<(cl&HHOtVjC~mb!d4s=!)3kHJl(3z~grY2mh7-dCeo4*DYKM--ad+b6&`<$ux~YYIrqgtNFtI1X>lvix zjS1TyIMEGcvwpx-rjXN$a<+vv_mpc(v7XV{ec# zjNpO9$q_|)B7-Py(R_K;MI?8%c&pE$;j~KCztq3}S9?g+Gk7Os$gdUUx%MDi&&Idr zw){-eHJPgIMl$EwIJZl0PL7WbA#J*ME%AXf{@L$2Y**c^UCaVAd N002ovPDHLkV1jx|tgZk6 literal 0 HcmV?d00001 diff --git a/save_load/assets/folder-open-hover.png.import b/save_load/assets/folder-open-hover.png.import new file mode 100644 index 0000000..f68715f --- /dev/null +++ b/save_load/assets/folder-open-hover.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://by4w5ll3le7g6" +path="res://.godot/imported/folder-open-hover.png-a1ef3a807e674ab8f8806dada553ab61.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://save_load/assets/folder-open-hover.png" +dest_files=["res://.godot/imported/folder-open-hover.png-a1ef3a807e674ab8f8806dada553ab61.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/save_load/assets/folder-open-normal.png b/save_load/assets/folder-open-normal.png new file mode 100644 index 0000000000000000000000000000000000000000..2a3f3a3713dff4e4d4a74191412229db6c0435c8 GIT binary patch literal 842 zcmV-Q1GW5#P)1v3Or=n=v_zt^g;0@EVGu$Df)qkQv?zmUr|nFrHbK-PT114)Hc=4-89@-Z z35={rf-(sd3X7l=EEj2knZ7N&6T{_<&i|b8-Oc$9hk5Szch0#NLXuP=>8zwaNn=V* z+Zg4aiglACvS<(iurB7lX{G5&+GVs)4=0Rp6tfqd9}jF=$j(z&%MFIfKj- zr~%g`HRTL41Uir-&?4Zvq)50=l5J2)yMz3x%HYylfYZRL(D-&>5AZT)kOAmlpf?Nc z?-B4CC=QvLV<96Hu*~co@Z4eAkh7f3k-j^|%9k2sLL2mS^P&RS2GrzH&z!eOQkj`er5vu3N`W4r(?dXj2B2Tk+H`WV1K8(zDsBbNrvw>z@mzt_oOVf7 zsd(}rP+1_5rNFvW3eQQ$*d$P6X20@yS5*UibM?$fk_%M>`yHn4d;$jA6=!@j*>FAK z*e3$q_8>HOI>vqiBdI`!^$Fc zYgwBXq@)tyn8Va-W+NVWaYu0dk(MV9#W~gcP;laf>NLUaePeq_V{|X=deJnHETpf!5$4~>6{qaU0_ctL@^KCrjD?(WOe$HR z;LHJcJUVH(AV0*`iwH34nA9j~HPGs?JvFn>9_3@pLZKRk>~~CB!~CUfrN;%Q4(J9p zx;81XKTJ|N@CB$~Y3MglYi8sBJ!xi>z!jE`x?%x|?)M}W0gr(L1rGQEXfm@u;heh($ literal 0 HcmV?d00001 diff --git a/save_load/assets/folder-open-normal.png.import b/save_load/assets/folder-open-normal.png.import new file mode 100644 index 0000000..23f63a6 --- /dev/null +++ b/save_load/assets/folder-open-normal.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cmq51cgasug81" +path="res://.godot/imported/folder-open-normal.png-f7f228a37723c0515dbd7272838372e1.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://save_load/assets/folder-open-normal.png" +dest_files=["res://.godot/imported/folder-open-normal.png-f7f228a37723c0515dbd7272838372e1.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/save_load/assets/folder-open-pressed.png b/save_load/assets/folder-open-pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..448ad270e0db1bf87a488907ece0ba9f10de7040 GIT binary patch literal 771 zcmV+e1N{7nP)_C z(EKE1!$6U>7J7@7c$SejPCyrSWeHgi&?X#Do|zeBKIp@YK!@N&A=l6h9{d(dusm_A zYH1F3V{Cza0hZ!+mXPoZ*K2U!i@1kjfi(4YR_wqR;GklO;bZ^=Y&s$-jy(%(^~LbhXdzO5+T({krh zA-4qbL^u@KI+;kZV(R^)UpTG*|7Boc=dg;HuwoA!5iU_*pDu+S=It zH_MO2U4yP#EM&}UKK9DhT>nA-Oj$D00!}Z^ zMzqriK|U{x7svE3puER8xs$NMYu6&%O1%#Bv8(Wp>xC;tFH-DVBLSR+ODTQa-fzE! zFS0AM)w=z_#C*W!WW#&Z|D#U1dSyQikvn~B^ijN(7c_%vO?LQ=3V0c#iyiKDxTCsX zXVtRZ$7Tb3a52!A7?YC-)*k8H`z%+*elyq~{{Tke^4RO9zbF6z002ovPDHLkV1j~- BZ+ZX# literal 0 HcmV?d00001 diff --git a/save_load/assets/folder-open-pressed.png.import b/save_load/assets/folder-open-pressed.png.import new file mode 100644 index 0000000..3e826ff --- /dev/null +++ b/save_load/assets/folder-open-pressed.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://blyryo60jydgi" +path="res://.godot/imported/folder-open-pressed.png-b69b4af3e2256bb46d3464e4d48a50c0.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://save_load/assets/folder-open-pressed.png" +dest_files=["res://.godot/imported/folder-open-pressed.png-b69b4af3e2256bb46d3464e4d48a50c0.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/save_load/assets/save-hover.png b/save_load/assets/save-hover.png new file mode 100644 index 0000000000000000000000000000000000000000..04fdbf9a9e255b05b6ce7ceea0bf4a57a4cf53c0 GIT binary patch literal 869 zcmV-r1DgDaP)?xHXurl2CI=(UMTL^3QQ5N(+lwJoV-gi1dl{{S;YgrKst zoh3EUFQrXpL{y-)u!T;%Y;niBKIT5})%ScOc;GJX+&TAtzjJ=fnR8>LixgXcT3|m= z0xV^IWD*zz>QTBUtWwMedooB5As)C&<2IpVA`UFKDE!Qe$9p8of$?@hfu?{=)d;*n ziUySKb5*>I^HRz;UDNKq;a02VgJoF~sa4U=KmYt9ZxaCb-h2*8F;PL!>Cg-o^Wr03HLI(^Y^zq_`6?zvn_$8}M5#&$?qsQHuAQ zwP1m{e+npzoBVxy0mko5lpdVQLT7>A1q8kaILAM?`I<_xwxG>qAL(#QenBvk?LffV7J}98;NW@|%GhKuN~865yevXb_S{Jjd5BsWf9;v+tY}m}ypdN%hWb z5}8v9*y7=Lnc2*8+KSuZCTBK8oJ743z*>*M&q5fy1JM9XX93ZW2_Pskvu8kK77!28 zK@{h@prlhVhwe)PLQ*5}2q=pH(QIaqiEx_cxK5ZWEwDKYId*M`u|J7pwH~`cF6^=a)yae8u*?hhij8#g+oU2aKP?pMJP*Tkz=k}H|sXT5( zn@ddD!fZ9rE$LEFJ|O7~a5Lt7MZhgdr-J|>X&ul3SdyFwbV^zu!U?nj8zXKMdffBN z^L;(g5(0qZ9^M47$IR-?tPa?lcDs>I$3g(G-NS1)v!S#aY7l7mmBS$bDEIKjWAe&F z0PxMjtMl*<$1RbUI}^VJwr23oOBw@iyZ4L0Ige~#!85U>lR5PCCql@?kAVI~$o09d ztgt>{W&+N*&>5E|fU{1v@TG*AeFP2xpJEIj0}h(mSWx|dnGL&Q?JDraGvqUH1*kT& zks$j4Gn)dgNxJTm)V8!7@F5>2v*Zm;nqQ2%XSJnV2!QXlZ9{;%`YPVZs9#J2nZK9{ zNs`JWz4PcfR1CZTc4o-z26`pkPZ-~qf;PFHW0&V!w@Iqx&u`YE6=wc(Ky}K+?|UoI zfA5;vs5u)e0iFUiD@6Go;Ha6+rd-^f1&#oB+|h(=HXVPJ$9I$9e4@oQAQixx0xLbq hzni@-Gy5+&{sxYa>JtA8VvYa+002ovPDHLkV1n6gg*X5J literal 0 HcmV?d00001 diff --git a/save_load/assets/save-normal.png.import b/save_load/assets/save-normal.png.import new file mode 100644 index 0000000..cb6ff20 --- /dev/null +++ b/save_load/assets/save-normal.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ja8bc1h5x85o" +path="res://.godot/imported/save-normal.png-126e9be66da8efc0f0eb84b8cc03c6ff.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://save_load/assets/save-normal.png" +dest_files=["res://.godot/imported/save-normal.png-126e9be66da8efc0f0eb84b8cc03c6ff.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/save_load/assets/save-pressed.png b/save_load/assets/save-pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..28f2cdd3021eefe536b64312fe67a9ca97c525ce GIT binary patch literal 773 zcmV+g1N!`lP)cxXUZlbh;sGwdHTW`_&10yP4#9oyiyejBX5K;?0*uOxKBIMwY zsyDS*gxW^DSPLR37zNWqTBG%li9BBBC2y0LWD5Dh5;FVdz4`9$?Ci`!Ir@MUFb6CG zD@|&D<(vJ~h&8|%@TZAJYi$Wg)MEVe78_m{i7`XQJCo=$uxx535d$s*ol4&{Fb@2X z{|A6!<+)_YS+1nN3Ahc!eSLA@0dN{f2fa9>Fn=R{;s1~}N?}n=KOrOTG!vb`W<@?O zO3g%CMtWK4E6qegBd}Ic_(^M!1_ptA1rmdP0@m;dI9Y+jeJ_bv1Rp#T^11yrkeC3v z0!So*hXgoH(!mMqZIw{XvHLA9As5F^xe&-Vz`%T+BzCwEcnRbpCh*u{Ca!5=z=gnf z@&1fs0MoD}4mjkX^EK!w;er=HuO%n3?!;{ZZ32x(tU-fvP?Ga)B3l3^fmf2eM~bjV zi7*%dW-A;UW`H9#zB@3Vh>E~)$kem|T(w5voGcBO8qnD&2t?t;>wvpJhl5UsR6=?z z>_S7p21ULMJd^fY>F)t9Ss-v+k!69s;?x7cK2LSSi(?iDY*%C{*^Nq=5n0)B*aCrW zMYa%9)@^~nw}5!y$I-Ay>@A^jLQEjzy(Ej%0eVQRYyX9!a^LFpje7@ z#Z;**(rO=Akw~0%(8&VlBS=jnJ5GND4g;S;JUb5@l3!E#z#Om(xB+}o`ac8L<(Z7t zd|(l{3EYw(wbc^?K18u(nvu|y{NlZ|c1l@|fL3i=Z_rll#G3>CifNkiE2dVW3wW#8 zIU56>0y}*QdnndI?>X-8jlf39Id&_3PoP*TEMW7RwOVfdf8a+~A%PL^RKz9qTP?;< zQhujQTxOzReA$d>#(U8V+>w+pXTa!Rz&o+YzuE8)^z?%)bdEGf00000NkvXXu0mjf D;R05P literal 0 HcmV?d00001 diff --git a/save_load/assets/save-pressed.png.import b/save_load/assets/save-pressed.png.import new file mode 100644 index 0000000..8583721 --- /dev/null +++ b/save_load/assets/save-pressed.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://crqgyft4gfilt" +path="res://.godot/imported/save-pressed.png-49f5851a0548d3847310651a4ef477c2.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://save_load/assets/save-pressed.png" +dest_files=["res://.godot/imported/save-pressed.png-49f5851a0548d3847310651a4ef477c2.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/save_load/assets/trash-hover.png b/save_load/assets/trash-hover.png new file mode 100644 index 0000000000000000000000000000000000000000..a75b5e77b3640b88a22dcba55b76dc5f878a10d6 GIT binary patch literal 860 zcmV-i1Ec(jP)#Z3P?ALdQaF z3>J2mQY|h

w)6@y--_XyRASVkdB(v%9k&*$=#_b|3R*-hbYE^Zqlt1|gdTdw?O} zAh1qT?JMvScqU*v%=|_O!&d=gz%`&J;4r^{8^E}LpFsx51qD!mabOfMLoA>P90iz$ z=dpRff&%a=#LBBYv0uRJAS)209gom>tGn@id6Bq`X88p5L3>&gCZUW8#w-p`7P?M}2uuDGA0KWq;VK4mxa9tt41UwNi zZ?u*7)xe^Hp;`hSCb7g8Sipl0aSK=@;KyHeKnlJn#u-R3OjL7!UN&A;$QlZTe1ZT} zb2r>7aXkY7>TYy8kO$-@a0Gbgbx4<|xg9`RzsZ`Ym_bZAL6x_LzyCTcH8u zfDH-kKpRotTlvm`q>7o-oW64)saoJPr)LPYQVgI4d~yVkGCt(VgPeAOdWtvO#$jA-2|I)br46o$qq{q71x^Dy mfz2yq_($Lk_6NLK9fdy}0>xs){Ko140000X-U$cq_#W&+*WopSa0J?DLwCsL{Ac13JEcs09rHjNo!C? zi4>F2K?iRJ828ja3hZ3PJ6ulyuGePV%r1GR;6vb|$C))tp@yM#0P6r!l1VB8cYu?? zh9X6hgspPrM^#>0}<`JmG ztpQ2Lf?o0%n3OaeAv+9A2C~zEZrmEE#9h>1RRJ*J(CKyk{Nj+CNO1O0)+yAJF)#BJ z>XcN7Ig+R0{q=qU=*R*<3$P`J7iep6cj{*}uVxl@XY6M*uU-&#XVnx^0|OB7DHK41 z%|lh^ps-h<+`thi`#fWn1_n_1F94JqxCYi!sA&OIn}@RAg}vsWI5kl3c_?fSN?Zf= zF61tsF(NL2usZmWG0%GriUJU49vWTseI6Kd$c?e~7r@apb5K+feRZsIS3_irl13yg z1}k7+#JPQe%wnKZ43WF$xc`ewwl!kr-s}?rGphjSd>mtD&w>3}%|THsUEaN*=v$iw zpRFec0G(+8%sP0bIs$N|*-RV&Qx4t%N!RPpg>L}8o;G12hwKL4g#ercYVkil7DU+< z=@np)nZ1wWi3e&Nx)+5y48RWH1<*~tGz%Otv$;4mfSG*&P62Z{8-F^?c;8go9;DN9 z9aCmm(tSzYK8528WEap6>;<;f$m1V@xBU47o>#&C20aO_8DkH?LI3~&07*qoM6N<$ Ef}~Dq4*&oF literal 0 HcmV?d00001 diff --git a/save_load/assets/trash-normal.png.import b/save_load/assets/trash-normal.png.import new file mode 100644 index 0000000..37967e7 --- /dev/null +++ b/save_load/assets/trash-normal.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dvp5yeoqw36yt" +path="res://.godot/imported/trash-normal.png-9a70475e0bfa21e155c8f068d078dd58.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://save_load/assets/trash-normal.png" +dest_files=["res://.godot/imported/trash-normal.png-9a70475e0bfa21e155c8f068d078dd58.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/save_load/assets/trash-pressed.png b/save_load/assets/trash-pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..3a8c56e4f8dd6dae21ee0b83fbeacb3c1383225a GIT binary patch literal 768 zcmV+b1ONPqP) zz#{MtPqYh|2eyG;%C-&6sj+gW2N@KPwz<5OuV-9&$r2N36se>Ha0#e7T#%}Yqf~-v z=&Zoo09Fj;F91g)yz_Yikh0ARaKljkIdI)z%z?R3VQ2_o2*3f20S%z-Fs~1~wUy3e zsE1xjTO&|~)t-`iPpbl~m)QN+0cL=$61vY8FcT;wHQ+MvSU`CXcrWlrfK%#u4d_^| zo{4-NxG(T;0xy7X{mk7!S3r8zql;V<^yw;H|JeurD6>Rq+#>*K?w?9maU*NS>=Qos zD0DhT0fZ$05b6M=wLlG+RY7NRnwwQJnJo~dM?%oNN|+>?h8Hw_7ouq}VeBPApNF;w z^*0HVtO_!dG1o8Aeyb_Qo_Fm+6OMVAf>;7DnoxFE9P|3$)m#7=0rq>yKnK*^nbWAR z%`9$C>on?XFNm8n(S>>i2G9e(>Hrj}9!ji(;<7+kU<-sMX{=db0L}jbKv>`y7`jkt z0VLH!uF0qlvWbDb>!G+hD0K|v9mwM*WrQt&xHxD#<{8&PIsi8H(96j0U%;}^Z&|(5 z$y(JxI{G0Tl=(aHbcd27lQ*-aLFzXe=g;@elyQ+h9 zM>^kof$?=p#pKlE0l;Wh0G|b3Jx2hNn{C(tSQB_>fIB%Te;4^)Nz#cRW{~5+#~6Tb z8O(ot0%c{%(p}&L@X2PtXB6ja%#$=Lazw>~Z{;_ELut)A void: if event.is_action_pressed("quick_save"): - save_game() + quick_save() if event.is_action_pressed("quick_load"): - load_game() + quick_load() -func save_game() -> void: +func quick_save() -> void: var save_level_data_component: SaveLevelDataComponent = get_tree().get_first_node_in_group("save_level_data_component") - if save_level_data_component == null: push_error("Could not find SaveLevelDataComponent node in level") return - save_level_data_component.save_game() + save_level_data_component.quick_save_game() game_saved.emit() -func load_game() -> void: - EntityManager.reset_world.emit() - +func quick_load() -> void: var save_level_data_component: SaveLevelDataComponent = get_tree().get_first_node_in_group("save_level_data_component") - if save_level_data_component == null: push_error("Could not find SaveLevelDataComponent node in level") return - save_level_data_component.load_game() + # TODO: Don't reset world if quicksave not found + EntityManager.reset_world.emit() + save_level_data_component.quick_load_game() game_loaded.emit() diff --git a/save_load/components/save_level_data_component.gd b/save_load/components/save_level_data_component.gd index f7e8f5b..3f9280e 100644 --- a/save_load/components/save_level_data_component.gd +++ b/save_load/components/save_level_data_component.gd @@ -10,21 +10,61 @@ extends Node ## * Linux: ~/.local/share/godot/app_userdata/[project_name][br] @export var save_game_data_path: String = "user://game_data/" @export var save_file_name: String = "save_%s_game_data.tres" +@export var quicksave_file_name: String = "quicksave_%s_game_data.tres" var level_scene_name: String var game_data_resource: SaveGameDataResource -var level_save_file_name: String -var save_game_file_path: String +#var level_save_file_name: String +#var save_game_file_path: String func _ready() -> void: add_to_group("save_level_data_component") level_scene_name = get_parent().name - level_save_file_name = save_file_name % level_scene_name - save_game_file_path = save_game_data_path + level_save_file_name + +func list_saves() -> Array[SaveFileDetailsResource]: # TODO: Update hints + var save_files: Array[SaveFileDetailsResource] = [] + if !DirAccess.dir_exists_absolute(save_game_data_path): + return save_files + + for filename: String in ResourceLoader.list_directory(save_game_data_path): + if !filename.begins_with("save_"): continue + if !filename.ends_with(".tres"): continue # Screenshots, etc + + var _save_path: String = save_game_data_path + filename + var _save_icon: String = filename.replace(".tres", ".png") + var _save_resource: SaveFileDetailsResource = SaveFileDetailsResource.new() + var _loaded_file: FileAccess = FileAccess.open(_save_path, FileAccess.READ) + + _save_resource.filename = filename + _save_resource.date_created = Time.get_datetime_string_from_unix_time(FileAccess.get_modified_time(_save_path)) + _save_resource.filesize = _loaded_file.get_length() + + if FileAccess.file_exists(save_game_data_path + _save_icon): + _save_resource.save_icon = _save_icon + + save_files.append(_save_resource) + + return save_files + +func load_game() -> void: + _load_game_resource(save_file_name % level_scene_name) + +func quick_load_game() -> void: + # TODO: Change this to a dynamic quick save file + # This might be left as 01 (01 always the last quicksave) + _load_game_resource(quicksave_file_name % "01") + +func quick_save_game() -> void: + # TODO: Change this to a dynamic quick save file + _save_game_as_resource(quicksave_file_name % "01") + +func save_game() -> void: + _save_game_as_resource(save_file_name % level_scene_name) + func save_node_data() -> void: var nodes: Array = get_tree().get_nodes_in_group("save_data_component") @@ -38,17 +78,21 @@ func save_node_data() -> void: var save_final_resource: Node3DDataResource = save_data_resource.duplicate() game_data_resource.save_data_nodes.append(save_final_resource) -func save_game() -> void: + + +func _save_game_as_resource(resource_filename: String) -> void: if !DirAccess.dir_exists_absolute(save_game_data_path): DirAccess.make_dir_absolute(save_game_data_path) + var save_game_file_path: String = save_game_data_path + resource_filename save_node_data() var result: int = ResourceSaver.save(game_data_resource, save_game_file_path) if result != OK: printerr("Failed to save game: ", result) -func load_game() -> void: +func _load_game_resource(resource_filename: String) -> void: + var save_game_file_path: String = save_game_data_path + resource_filename if !FileAccess.file_exists(save_game_file_path): printerr("Failed to load save. File does not exist: ", save_game_file_path) return @@ -62,29 +106,3 @@ func load_game() -> void: for resource: Resource in game_data_resource.save_data_nodes: if resource is Node3DDataResource: (resource as Node3DDataResource)._load_data(root_node) - - -func list_saves() -> Array[SaveFileDetailsResource]: # TODO: Update hints - var save_files: Array[SaveFileDetailsResource] = [] - if !DirAccess.dir_exists_absolute(save_game_data_path): - return save_files - - for filename: String in ResourceLoader.list_directory(save_game_data_path): - if !filename.begins_with("save_"): continue - if !filename.ends_with(".tres"): continue # Screenshots, etc - - var _save_path: String = save_game_data_path + filename - var _save_icon: String = filename.replace(".tres", ".png") - var _save_resource: SaveFileDetailsResource = SaveFileDetailsResource.new() - var _loaded_file: FileAccess = FileAccess.open(_save_path, FileAccess.READ) - - _save_resource.filename = filename - _save_resource.date_created = Time.get_datetime_string_from_unix_time(FileAccess.get_modified_time(_save_path)) - _save_resource.filesize = _loaded_file.get_length() - - if FileAccess.file_exists(save_game_data_path + _save_icon): - _save_resource.save_icon = _save_icon - - save_files.append(_save_resource) - - return save_files diff --git a/save_load/resources/save_file_highlight_panel_theme.tres b/save_load/resources/save_file_highlight_panel_theme.tres new file mode 100644 index 0000000..083bbaa --- /dev/null +++ b/save_load/resources/save_file_highlight_panel_theme.tres @@ -0,0 +1,4 @@ +[gd_resource type="StyleBoxFlat" format=3 uid="uid://bwm315lqbbb87"] + +[resource] +bg_color = Color(0.728173, 0.579132, 0.164487, 1) diff --git a/save_load/resources/save_file_panel_theme.tres b/save_load/resources/save_file_panel_theme.tres new file mode 100644 index 0000000..7835864 --- /dev/null +++ b/save_load/resources/save_file_panel_theme.tres @@ -0,0 +1,8 @@ +[gd_resource type="StyleBoxFlat" format=3 uid="uid://biousyggn7iua"] + +[resource] +content_margin_left = 5.0 +content_margin_top = 5.0 +content_margin_right = 5.0 +content_margin_bottom = 5.0 +bg_color = Color(0, 0.65098, 0.886275, 0) diff --git a/save_load/ui/save_file.gd b/save_load/ui/save_file.gd new file mode 100644 index 0000000..976b6f8 --- /dev/null +++ b/save_load/ui/save_file.gd @@ -0,0 +1,63 @@ +class_name SaveFilePanel +extends Panel + + +@export var save_panel_highlight: StyleBoxFlat +@export var save_panel_normal: StyleBoxFlat + +@export_group("Node Exports") +@export var save_name_label: Label +@export var save_date_label: Label +@export var save_icon: TextureRect +@export var save_button: TextureButton +@export var load_button: TextureButton +@export var delete_button: TextureButton + +var save_file_details: SaveFileDetailsResource + + +func _ready() -> void: + mouse_entered.connect(_on_mouse_entered) + mouse_exited.connect(_on_mouse_exited) + + delete_button.pressed.connect(_on_delete_button_pressed) + save_button.pressed.connect(_on_save_button_pressed) + load_button.pressed.connect(_on_load_button_pressed) + + +func initialize(_resource: SaveFileDetailsResource) -> void: + save_file_details = _resource + set_save_date() + set_save_icon() + set_save_name() + +func set_save_date() -> void: + save_date_label.text = save_file_details.date_created + +func set_save_icon() -> void: + save_icon.texture = load(save_file_details.save_icon) + +func set_save_name() -> void: + # TODO: Remove extension from name + save_name_label.text = save_file_details.filename + + + +func _on_delete_button_pressed() -> void: + SaveGameManager.delete_save_file.emit(save_file_details.filename) + print("DELETING: ", save_file_details.filename) + +func _on_load_button_pressed() -> void: + SaveGameManager.load_save_file.emit(save_file_details.filename) + print("LOADING: ", save_file_details.filename) + +func _on_save_button_pressed() -> void: + SaveGameManager.create_save_file.emit(save_file_details.filename) + print("SAVING: ", save_file_details.filename) + + +func _on_mouse_entered() -> void: + set("theme_override_styles/panel", save_panel_highlight) + +func _on_mouse_exited() -> void: + set("theme_override_styles/panel", save_panel_normal) diff --git a/save_load/ui/save_file.gd.uid b/save_load/ui/save_file.gd.uid new file mode 100644 index 0000000..276bc14 --- /dev/null +++ b/save_load/ui/save_file.gd.uid @@ -0,0 +1 @@ +uid://dcfdyua5gwpw4 diff --git a/save_load/ui/save_file.tscn b/save_load/ui/save_file.tscn new file mode 100644 index 0000000..b3fcaa3 --- /dev/null +++ b/save_load/ui/save_file.tscn @@ -0,0 +1,100 @@ +[gd_scene load_steps=14 format=3 uid="uid://bb7poutsn4ex2"] + +[ext_resource type="Texture2D" uid="uid://dknv7amroftm8" path="res://assets/icon.svg" id="1_714lu"] +[ext_resource type="StyleBox" uid="uid://biousyggn7iua" path="res://save_load/resources/save_file_panel_theme.tres" id="1_cqw77"] +[ext_resource type="Texture2D" uid="uid://cmq51cgasug81" path="res://save_load/assets/folder-open-normal.png" id="1_k6haa"] +[ext_resource type="Script" uid="uid://dcfdyua5gwpw4" path="res://save_load/ui/save_file.gd" id="2_5g2eu"] +[ext_resource type="Texture2D" uid="uid://blyryo60jydgi" path="res://save_load/assets/folder-open-pressed.png" id="2_714lu"] +[ext_resource type="Texture2D" uid="uid://ja8bc1h5x85o" path="res://save_load/assets/save-normal.png" id="2_jgxci"] +[ext_resource type="Texture2D" uid="uid://crqgyft4gfilt" path="res://save_load/assets/save-pressed.png" id="3_cqw77"] +[ext_resource type="StyleBox" uid="uid://bwm315lqbbb87" path="res://save_load/resources/save_file_highlight_panel_theme.tres" id="3_om23c"] +[ext_resource type="Texture2D" uid="uid://by4w5ll3le7g6" path="res://save_load/assets/folder-open-hover.png" id="3_ubfnn"] +[ext_resource type="Texture2D" uid="uid://o3l0j53mgkan" path="res://save_load/assets/save-hover.png" id="4_5g2eu"] +[ext_resource type="Texture2D" uid="uid://dvp5yeoqw36yt" path="res://save_load/assets/trash-normal.png" id="4_c2bnc"] +[ext_resource type="Texture2D" uid="uid://brwa8yljyrlgy" path="res://save_load/assets/trash-pressed.png" id="5_jgxci"] +[ext_resource type="Texture2D" uid="uid://cmrtuy0i5qc01" path="res://save_load/assets/trash-hover.png" id="6_cqw77"] + +[node name="SaveFilePanel" type="Panel" node_paths=PackedStringArray("save_name_label", "save_date_label", "save_icon", "save_button", "load_button", "delete_button")] +custom_minimum_size = Vector2(420, 60) +offset_right = 420.0 +offset_bottom = 60.0 +theme_override_styles/panel = ExtResource("1_cqw77") +script = ExtResource("2_5g2eu") +save_panel_highlight = ExtResource("3_om23c") +save_panel_normal = ExtResource("1_cqw77") +save_name_label = NodePath("HBoxContainer/NameDate/SaveName") +save_date_label = NodePath("HBoxContainer/NameDate/SaveDate") +save_icon = NodePath("HBoxContainer/SaveFileIcon") +save_button = NodePath("HBoxContainer/Actions/SaveButton") +load_button = NodePath("HBoxContainer/Actions/LoadButton") +delete_button = NodePath("HBoxContainer/Actions/DeleteButton") + +[node name="HBoxContainer" type="HBoxContainer" parent="."] +custom_minimum_size = Vector2(400, 0) +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -200.0 +offset_top = -20.5 +offset_right = 200.0 +offset_bottom = 20.5 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_horizontal = 0 + +[node name="SaveFileIcon" type="TextureRect" parent="HBoxContainer"] +layout_mode = 2 +texture = ExtResource("1_714lu") +expand_mode = 3 + +[node name="NameDate" type="VBoxContainer" parent="HBoxContainer"] +layout_mode = 2 +size_flags_vertical = 8 + +[node name="SaveName" type="Label" parent="HBoxContainer/NameDate"] +layout_mode = 2 +text = "Save name #1" + +[node name="SaveDate" type="Label" parent="HBoxContainer/NameDate"] +layout_mode = 2 +theme_override_font_sizes/font_size = 10 +text = "2025/03/20 13:43:12" + +[node name="Actions" type="HBoxContainer" parent="HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 10 + +[node name="SaveButton" type="TextureButton" parent="HBoxContainer/Actions"] +clip_contents = true +custom_minimum_size = Vector2(32, 32) +layout_mode = 2 +tooltip_text = "Load Save" +texture_normal = ExtResource("2_jgxci") +texture_pressed = ExtResource("3_cqw77") +texture_hover = ExtResource("4_5g2eu") +ignore_texture_size = true +stretch_mode = 5 + +[node name="LoadButton" type="TextureButton" parent="HBoxContainer/Actions"] +clip_contents = true +custom_minimum_size = Vector2(32, 32) +layout_mode = 2 +tooltip_text = "Load Save" +texture_normal = ExtResource("1_k6haa") +texture_pressed = ExtResource("2_714lu") +texture_hover = ExtResource("3_ubfnn") +ignore_texture_size = true +stretch_mode = 5 + +[node name="DeleteButton" type="TextureButton" parent="HBoxContainer/Actions"] +custom_minimum_size = Vector2(32, 32) +layout_mode = 2 +tooltip_text = "Delete Save" +texture_normal = ExtResource("4_c2bnc") +texture_pressed = ExtResource("5_jgxci") +texture_hover = ExtResource("6_cqw77") +ignore_texture_size = true +stretch_mode = 5 diff --git a/save_load/ui/save_files_list.gd b/save_load/ui/save_files_list.gd new file mode 100644 index 0000000..382eb31 --- /dev/null +++ b/save_load/ui/save_files_list.gd @@ -0,0 +1,29 @@ +extends VBoxContainer + + +@export var save_file_scene: PackedScene + + +func _ready() -> void: + SaveGameManager.refresh_saves_list.connect(_on_refresh_saves_list) + refresh_saves_list() + +## Clear the SaveFilesList node of all saves and load most recent saves +func refresh_saves_list() -> void: + _clear_save_files_list() + + var save_level_data_component: SaveLevelDataComponent = get_tree().get_first_node_in_group("save_level_data_component") + var save_files: Array[SaveFileDetailsResource] = save_level_data_component.list_saves() + + for save_resource: SaveFileDetailsResource in save_files: + var _save_file: SaveFilePanel = save_file_scene.instantiate() + _save_file.initialize(save_resource) + add_child(_save_file) + + +func _clear_save_files_list() -> void: + for _panel: SaveFilePanel in get_children(): + _panel.queue_free() + +func _on_refresh_saves_list() -> void: + refresh_saves_list() diff --git a/save_load/ui/save_files_list.gd.uid b/save_load/ui/save_files_list.gd.uid new file mode 100644 index 0000000..ba9e57b --- /dev/null +++ b/save_load/ui/save_files_list.gd.uid @@ -0,0 +1 @@ +uid://cqabj86bq8whn diff --git a/save_load/ui/save_load_ui.tscn b/save_load/ui/save_load_ui.tscn new file mode 100644 index 0000000..2250372 --- /dev/null +++ b/save_load/ui/save_load_ui.tscn @@ -0,0 +1,50 @@ +[gd_scene load_steps=3 format=3 uid="uid://dauchkhmnyk7n"] + +[ext_resource type="Script" uid="uid://cqabj86bq8whn" path="res://save_load/ui/save_files_list.gd" id="1_t4pkj"] +[ext_resource type="PackedScene" uid="uid://bb7poutsn4ex2" path="res://save_load/ui/save_file.tscn" id="1_tqtxm"] + +[node name="SaveLoadUI" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_horizontal = 6 +size_flags_vertical = 4 + +[node name="Panel" type="Panel" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="MarginContainer" type="MarginContainer" parent="Panel"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_constants/margin_left = 20 +theme_override_constants/margin_top = 20 +theme_override_constants/margin_right = 20 +theme_override_constants/margin_bottom = 20 + +[node name="VBoxContainer" type="VBoxContainer" parent="Panel/MarginContainer"] +layout_mode = 2 + +[node name="Label" type="Label" parent="Panel/MarginContainer/VBoxContainer"] +layout_mode = 2 +theme_override_font_sizes/font_size = 40 +text = "Load Save" +horizontal_alignment = 1 + +[node name="SaveFilesList" type="VBoxContainer" parent="Panel/MarginContainer/VBoxContainer"] +clip_contents = true +layout_mode = 2 +size_flags_horizontal = 4 +script = ExtResource("1_t4pkj") +save_file_scene = ExtResource("1_tqtxm")