From 5a266d6b3a12f5089fc685d226802d9422d539c8 Mon Sep 17 00:00:00 2001 From: lustlion Date: Tue, 18 Jan 2022 00:14:54 +0100 Subject: [PATCH] uh yeah i keep forgetting ab pushing these. sorry. --- assets/characters/decoration/candelabra1.png | Bin 0 -> 191 bytes assets/characters/decoration/candelabra2.png | Bin 0 -> 190 bytes assets/characters/decoration/candelabra3.png | Bin 0 -> 184 bytes assets/characters/decoration/candelabra4.png | Bin 0 -> 190 bytes assets/characters/decoration/candelabra5.png | Bin 0 -> 190 bytes assets/characters/decoration/candelabra6.png | Bin 0 -> 189 bytes assets/characters/decoration/candelabra7.png | Bin 0 -> 184 bytes assets/characters/decoration/candelabra8.png | Bin 0 -> 193 bytes assets/characters/fairy/flying1.png | Bin 0 -> 195 bytes assets/characters/fairy/flying2.png | Bin 0 -> 168 bytes assets/characters/kupo/kupo1.png | Bin 188 -> 203 bytes assets/characters/kupo/kupo2.png | Bin 185 -> 198 bytes assets/characters/kupo/kupo3.png | Bin 186 -> 201 bytes assets/characters/kupo/kupo4.png | Bin 180 -> 199 bytes assets/characters/kupo/kupo_arrow1.png | Bin 94 -> 107 bytes assets/characters/kupo/kupo_bow1.png | Bin 158 -> 179 bytes assets/characters/kupo/kupo_bow2.png | Bin 157 -> 172 bytes assets/characters/kupo/kupo_bow3.png | Bin 163 -> 179 bytes assets/characters/kupo/kupo_bow4.png | Bin 152 -> 165 bytes assets/characters/kupo/kupo_bow5.png | Bin 142 -> 155 bytes assets/characters/kupo/kupo_bow6.png | Bin 140 -> 153 bytes assets/characters/nancy/fall1.png | Bin 920 -> 1188 bytes assets/characters/nancy/fall2.png | Bin 923 -> 1191 bytes assets/characters/nancy/fall3.png | Bin 922 -> 1190 bytes assets/characters/nancy/idle1.png | Bin 919 -> 1187 bytes assets/characters/nancy/idle2.png | Bin 918 -> 1186 bytes assets/characters/nancy/idle3.png | Bin 919 -> 1187 bytes assets/characters/nancy/idle4.png | Bin 917 -> 1185 bytes assets/characters/nancy/jump1.png | Bin 916 -> 1184 bytes assets/characters/nancy/jump2.png | Bin 919 -> 1187 bytes assets/characters/nancy/jump3.png | Bin 918 -> 1186 bytes assets/characters/nancy/moth_mask/fall1.png | Bin 890 -> 155 bytes assets/characters/nancy/moth_mask/fall2.png | Bin 890 -> 155 bytes assets/characters/nancy/moth_mask/fall3.png | Bin 890 -> 155 bytes assets/characters/nancy/moth_mask/idle1.png | Bin 890 -> 155 bytes assets/characters/nancy/moth_mask/idle2.png | Bin 890 -> 155 bytes assets/characters/nancy/moth_mask/idle3.png | Bin 890 -> 155 bytes assets/characters/nancy/moth_mask/idle4.png | Bin 890 -> 155 bytes assets/characters/nancy/moth_mask/jump1.png | Bin 890 -> 157 bytes assets/characters/nancy/moth_mask/jump2.png | Bin 890 -> 157 bytes assets/characters/nancy/moth_mask/jump3.png | Bin 890 -> 157 bytes assets/characters/nancy/moth_mask/run1.png | Bin 890 -> 149 bytes assets/characters/nancy/moth_mask/run2.png | Bin 890 -> 149 bytes assets/characters/nancy/moth_mask/run3.png | Bin 890 -> 149 bytes assets/characters/nancy/moth_mask/run4.png | Bin 890 -> 149 bytes assets/characters/nancy/moth_mask/run5.png | Bin 890 -> 149 bytes assets/characters/nancy/moth_mask/run6.png | Bin 890 -> 149 bytes assets/characters/nancy/run1.png | Bin 914 -> 1182 bytes assets/characters/nancy/run2.png | Bin 915 -> 1182 bytes assets/characters/nancy/run3.png | Bin 917 -> 1185 bytes assets/characters/nancy/run4.png | Bin 919 -> 1188 bytes assets/characters/nancy/run5.png | Bin 913 -> 1181 bytes assets/characters/nancy/run6.png | Bin 916 -> 1186 bytes assets/tileset/books.png | Bin 1157 -> 1168 bytes assets/tileset/library.png | Bin 4123 -> 4303 bytes assets/ui/heonian.png | Bin 0 -> 3544 bytes data/levels/level1.lua | 4 +- data/scripts.lua | 1 + data/scripts/animation.lua | 8 +- data/scripts/debug.lua | 13 +- data/scripts/entities/arrow.lua | 8 +- data/scripts/entities/decoration.lua | 33 ++++ data/scripts/entities/fairy.lua | 64 +++++++ data/scripts/entities/kupo.lua | 53 +++--- data/scripts/entities/player.lua | 150 ++++++++++++---- data/scripts/entity.lua | 179 +++++-------------- data/scripts/enums.lua | 14 ++ data/scripts/in_out.lua | 6 - data/scripts/keybind.lua | 9 + data/scripts/level.lua | 2 - data/scripts/lights.lua | 53 +++--- data/scripts/math.lua | 8 + main.lua | 74 ++++++-- 73 files changed, 405 insertions(+), 274 deletions(-) create mode 100644 assets/characters/decoration/candelabra1.png create mode 100644 assets/characters/decoration/candelabra2.png create mode 100644 assets/characters/decoration/candelabra3.png create mode 100644 assets/characters/decoration/candelabra4.png create mode 100644 assets/characters/decoration/candelabra5.png create mode 100644 assets/characters/decoration/candelabra6.png create mode 100644 assets/characters/decoration/candelabra7.png create mode 100644 assets/characters/decoration/candelabra8.png create mode 100644 assets/characters/fairy/flying1.png create mode 100644 assets/characters/fairy/flying2.png create mode 100644 assets/ui/heonian.png create mode 100644 data/scripts/entities/decoration.lua create mode 100644 data/scripts/entities/fairy.lua create mode 100644 data/scripts/keybind.lua diff --git a/assets/characters/decoration/candelabra1.png b/assets/characters/decoration/candelabra1.png new file mode 100644 index 0000000000000000000000000000000000000000..faaaed605b09e3d0c9156e688366a2ba0eed78f5 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp@K+MO%1|+}KPrC%97>k44ofy`glX(f`RC>BNhGk44ofy`glX(f`RCu~LhGk44ofy`glX(f`6nVNhhGA&8BT6m znDH)M<>0e>59B_$ZC!4@XEB3n*X!8cyUQiwtk44ofy`glX(f`RCu~LhG|Qq^nRm?d81t`O|I$`2;;>iH%Vdq6>%SK(p5FZ(v9EgJso7huXa4V= no;tx)Jhl5yjfcMdqa^;q@BUmbe(IkCx`Dyd)z4*}Q$iB}9Og&_ literal 0 HcmV?d00001 diff --git a/assets/characters/decoration/candelabra5.png b/assets/characters/decoration/candelabra5.png new file mode 100644 index 0000000000000000000000000000000000000000..f49b4c0de9e54a7d3fd6b2b757f21e72f91e917a GIT binary patch literal 190 zcmeAS@N?(olHy`uVBq!ia0vp@K+MO%1|+}KPrC%97>k44ofy`glX(f`RCu~LhGfYY|r@O^h?eTP<`)z+k nBwJ*8VAPXq&Q(7J&8wOI3VR9ko=VC9x`Dyd)z4*}Q$iB}&a_K> literal 0 HcmV?d00001 diff --git a/assets/characters/decoration/candelabra6.png b/assets/characters/decoration/candelabra6.png new file mode 100644 index 0000000000000000000000000000000000000000..772818388f304eb0860445847579051665197b32 GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp@K+MO%1|+}KPrC%97>k44ofy`glX(f`lzX~3hG#f2H~OeZCjzyH8dv3T2Z^F50gvWm4XZulkg^Fm;>+=1&)k44ofy`glX(f`6nVNhhGA&8BT6m znDH)M<>0e>59B_$ZC!4@XEB3n*X!8cyUQiwtk44ofy`glX(f`RC~HOhG%3c+V%gZZGe=I0m#{XwAgVY}{lQ;8}WW5$Wy<8nxSGDle^pY!E q?mtZB+4L?T>dRW+svm;(?>TEu1>T79#DK%uSM1fl>%rZE3Y*f?d()P7WW13rTIRLp^;6sK2C?t{8`oX#+jnEvj~l0%GIPr^zXeUW tCe+~Pck5eDvef%at(?#HcAfjfoY|ZIW-0e>MW90%JYD@<);T3K0RSm_PC5Vp literal 0 HcmV?d00001 diff --git a/assets/characters/fairy/flying2.png b/assets/characters/fairy/flying2.png new file mode 100644 index 0000000000000000000000000000000000000000..bc77f8b422ca8759c21789c6e9c07c33b0cb7152 GIT binary patch literal 168 zcmeAS@N?(olHy`uVBq!ia0vp@K+Mg-1|*kkVowB8jKx9jP7LeL$-D$|l001;Lo_DV z`k!Pxpuls8@5+@{*AcZA$8W(hAX5*=oM@1rmedkF5mf8?xA3F_|_(? RCqUa6JYD@<);T3K0RWz#KSuxn literal 0 HcmV?d00001 diff --git a/assets/characters/kupo/kupo1.png b/assets/characters/kupo/kupo1.png index 2224a29b0b21bc6cd5dea6cad6235b51bafc713f..7c2bb4232a7ece1c5fed68f5f70be29c1b92eca2 100644 GIT binary patch delta 175 zcmV;g08szD0m}i9B!2;OQb$4nuFf3k0001mNkl(Iy`nRY8i2)IJX3wXLy&2#texxGZIa`MS zZ6=QnjKs^c+sz?W4^qiWpqIxZXjzBKDnp;LI8&h%M6kBX_#;{&K=G8bS)`{d{YH0j Y0r_5Gaf`A|UjP6A07*qoM6N<$f)vI^x&QzG delta 157 zcmV;O0Al~f0l5K?B!7TOL_t(Ijm=U?62Kq`gO1GL z8BIKV&Jh)7NMHlSb=t;G1xK||MeW4QwifwZ-@6&G2By^7pMYloC^K0`6RKT3Z`n3Y z&4*Dk@hUW$W|aTmE8+a@)pky&A?%2BPuD(khS boA(wQX@^wfnCs_400000NkvXXu0mjfn=?q4 delta 158 zcmV;P0Ac^h0lEQ@B!7WPL_t(IjkQui4uCKSql@2h{{I=`gXUpM7-5Jp_PDGq&=UQL z#YV;hCd6idd%69Iq}S37z)_zY;}d#st0H+H|lwWARA&g&jdP>6_7 z8I~w-50Dr&0hJ*=P@>*yLyTR-F*Y%#k%=%><*3$Sm33_C<`=!i32JRr1H3*rJ^%m! M07*qoM6N<$g2>uK_y7O^ diff --git a/assets/characters/kupo/kupo4.png b/assets/characters/kupo/kupo4.png index da424a2d0b60286f9d4eae877d03edb412d27416..61f6f5e6252892613d3e7fcf713643783d73f3e7 100644 GIT binary patch delta 171 zcmV;c096090mlK5B!2;OQb$4nuFf3k0001iNklrsCS}=|C3k45s@iD0}J}M+v13*C=vjee0Re}QDv|l+F`Ijk}QxU zYVB!=EEv2ibOcQuXV`(>z>?T4lr4G2d?nNyZ~6f%QXz7}&Lo0O*;aW~>t&TKVYqo; Z@c@~`VCM8Ihm8OL002ovPDHLkV1g>9Npt`J delta 152 zcmV;J0B8Tl0ki>-B!7EJL_t(IjkQwC6@V}ZBR=P``>$aKiYI-P#)1cPhI}Aqe}d=1 zh&Z#YmMbE!1P^)}iGz#1qM}FuptS21)eX|63{wP>wB96%vi*L<-lps+Nb>%@+1vxQ zllQ>6P$cq=05BA(8YL=JUN}VXSN0B8wO&@)6PBCz6&G5xZV}(TJLeVv0000gnPb!Z9=XPrc`Rdu9=XSFuSc2N)AxNqp5aG*aRg;FdVKk(0stlQ7e> SStl$RfWXt$&t;ucLK6VV1r>?_ diff --git a/assets/characters/kupo/kupo_bow1.png b/assets/characters/kupo/kupo_bow1.png index b912b83fcb5a79c17569fc76f5c2f173007095d7..6ebad6ab0868aebdd8492900c5d301ba6fcf6496 100644 GIT binary patch delta 151 zcmV;I0BHZ70kZ*+B!2;OQb$4nuFf3k0001ONkl|8@P)^c0C! zW|0z~A_9Ynh^|Bc>nurGp1p|09V8`BA$JCF1rBNf0IRr~zjff8{9TLyCENu8cuMEB z++z_Gi%o6ko&S! zg&2}Y>lcE=zM$YTB1xSAz}2M>@8*+fS(i%9?g00{s|MNUMnLSTZAdOx@T delta 128 zcmV-`0Du3i0i6MmBza^>L_t(IjkS_X3IHGoM4RaTSGJW9=J+9+Riutj5rarXMBf0w z^4!2#oS9JPstF~~WNTziCL@TthVsz$U)3VWbm1`qw-~@;fynrbKab$bj=>gKBFJ{~ i?-DD;WrFrKcC-N?A4~bgx+%i|0000kh>GZx^prwCn}Z$0707u_W%F@ delta 9 QcmZ3=ID>J5%0$Bw01x#8DgXcg diff --git a/assets/characters/kupo/kupo_bow5.png b/assets/characters/kupo/kupo_bow5.png index f8c5369f7ab755f383404d7c2ee0fca5c97a18a0..5e6bfa5fe8e11801e2cddd8e8ecda8a4c39d04f9 100644 GIT binary patch delta 20 bcmeBUoXt2vg^RH`$lZxy-8q?;6BTm-Kothr delta 9 QcmbQu*vB|QWujpg01rz83;+NC diff --git a/assets/characters/kupo/kupo_bow6.png b/assets/characters/kupo/kupo_bow6.png index 04831855c7b9c1e364fdaa72bf3b588e451c42c2..bac1bb3793e20d565c86dbe64bd0fc07adb2a5b9 100644 GIT binary patch delta 20 bcmeBSoXI#rg^RH`$lZxy-8q?;6BV-oKgR~s delta 9 QcmbQq*uywMWujpQ01qhx1^@s6 diff --git a/assets/characters/nancy/fall1.png b/assets/characters/nancy/fall1.png index c6737234c45a67f9bf38a9d8e0d311e6bd832c97..72f8f4583ff03f2390a66f22704eabb0f89b3080 100644 GIT binary patch literal 1188 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GA|hzm>B|mLR^7@ z|AF9=9*{8#Mnhnvg@DcTq)1@CU?>Ul3kK%|P;MBZfNS~}8({pqdAc};NK7s5zs<#9 zz~LnP|Ns2!yhXh~1xh@$H}?x%YFnswHHYD=1*7RPgg&ebxsLQ0QRUgcK`qY delta 26 icmZ3&IfH$I@B|mLR^7@ z|AF9=9*{8#Mnhnvg@DcTq)1@CU?>Ul3kK%|P;MBZfNS~}8({o&O$9D~j)K^6YUweW_d^Xud+!lMQ#A k7&F3IRv6r?mh0QWP-ez(I`oy)0#KszboFyt=akR{0OZ3r$N&HU delta 26 icmZ3^Ih%cg@B|mLR^7@ z|AF9=9*{8#Mnhnvg@DcTq)1@CU?>Ul3kK%|P;MBZfNS~}8({oB|mLR^7@ z|AF9=9*{8#Mnhnvg@DcTq)1@CU?>Ul3kK%|P;MBZfNS~}8({pqdb&7%X0b~=vP((k{3VshlZGMFkd@i`fL7*yh+!0ot1xm gGx^=7_iVoy#Hx81o;K*+-3Cffp00i_>zopr05>5xivR!s delta 26 icmZ3?Ih}oi@B|mLR^7@ z|AF9=9*{8#Mnhnvg@DcTq)1@CU?>Ul3kK%|P;MBZfNS~}8({pqc)B=-NKCEmXXIi~ z;9(N||Nr?mv8^pe5)~%83tWVJmn>3r+7Dp`32e}TEjwm#CmFU0;YAS&(e e8#aRt>;?=y&lx@xB|mLR^7@ z|AF9=9*{8#Mnhnvg@DcTq)1@CU?>Ul3kK%|P;MBZfNS~}8({pqdb&7dV3VL!>Nxxs}~)o6*5Wbd3i43WAs4@Z@9cC<|2^mbEuUHIGN_YxVa gyM2lq*khR4dham2`M1$#1t>vzy85}Sb4q9e0NN!s1^@s6 delta 26 icmZ3?Ih}oi@B|mLR^7@ z|AF9=9*{8#Mnhnvg@DcTq)1@CU?>Ul3kK%|P;MBZfNS~}8({o9d%8G=NK7s5zsSX) zz`<<(=YPGQ_Z8Q-i3RLhO!F@&XUsE`Zs%01&e+_m>b_&6&>6wKA9oz;4h?Y8o9e!3 d*#Xs64Xo9r4EK3Iw;ll{Cr?*Dmvv4FO#mHhGwlEX delta 26 icmZ3;IhB2a@B|mLR^7@ z|AF9=9*{8#Mnhnvg@DcTq)1@CU?>Ul3kK%|P;MBZfNS~}8({o9dAc};NKCEmKgh*k zz~MCY-~aj7m8MnBi2dZ~<B|mLR^7@ z|AF9=9*{8#Mnhnvg@DcTq)1@CU?>Ul3kK%|P;MBZfNS~}8({pqdb&7B|mLR^7@ z|AF9=9*{8#Mnhnvg@DcTq)1@CU?>Ul3kK%|P;MBZfNS~}8({pqc)B=-NK7s559DJ| z;BZR3^Z(q^n^$IiQO@UNZSh#tF(qU|q_BFyyY#MV(}Z;4)a3Y`3*%o$Na;RZD0kiX e_i>&FjHz*LT@3d{SIvF}N>84yelF{r5}E+9v^CxU delta 26 icmZ3)IgNdS@B|mLR^8||3Gj_56Bn=qaiTT zLcr#EQY6sNj3q&S!3+-1ZlnP@8lEnWAre!Q6ArM>IKa_)p5@>XZUaLj!-ZN2EL{eR iUN{6FY&f^voPoh$0)uPB!lZUkpn1CbxvXB|mLR^8||3Gj_56Bn=qaiTT zLcr#EQY6sNj3q&S!3+-1ZlnP@8lEnWAre!Q6ArM>IKa_)p5@>XZUaLj!-ZN2EL{eR iUN{6FY&f^voPoh$0)uPB!lZUkpn1CbxvXB|mLR^8||3Gj_56Bn=qaiTT zLcr#EQY6sNj3q&S!3+-1ZlnP@8lEnWAre!Q6ArM>IKa_)p5@>XZUaLj!-ZN2EL{eR iUN{6FY&f^voPoh$0)uPB!lZUkpn1CbxvXB|mLR^8||3Gj_56Bn=qaiTT zLcr#EQY6sNj3q&S!3+-1ZlnP@8lEnWAre!Q6ArM>IKa_)p5@>XZUaLj!-ZN2EL{eR iUN{6FY&f^voPoh$0)uPB!lZUkpn1CbxvXB|mLR^8||3Gj_56Bn=qaiTT zLcr#EQY6sNj3q&S!3+-1ZlnP@8lEnWAre!Q6ArM>IKa_)p5@>XZUaLj!-ZN2EL{eR iUN{6FY&f^voPoh$0)uPB!lZUkpn1CbxvXB|mLR^8||3Gj_56Bn=qaiTT zLcr#EQY6sNj3q&S!3+-1ZlnP@8lEnWAre!Q6ArM>IKa_)p5@>XZUaLj!-ZN2EL{eR iUN{6FY&f^voPoh$0)uPB!lZUkpn1CbxvXB|mLR^8||3Gj_56Bn=qaiTT zLcr#EQY6sNj3q&S!3+-1ZlnP@8lEnWAre!Q6ArM>IKa_)p5@>XZUaLj!-ZN2EL{eR iUN{6FY&f^voPoh$0)uPB!lZUkpn1CbxvXL_t(IjqQTFyn$Yk#{trg*vo|m5gr@Ztk^5EEY$98sa(3H u4J^y$07oPqr;qXU1aRI~V$F}w;RJlw8b_G2@d^L{002ovP6b4+LSTZyvpc8& literal 890 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl4m>B|mLR^8||3Gj_56Bn=qaiTT zLcr#EQY6sNj3q&S!3+-1ZlnP@8lEnWAre!Q6Ap0BIKa_)p5@>XZUaLj!-ZN2EL{eR iUN{6FY&f^vn1R8-hru;#QAIi^&^%rJT-G@yGywpdbtJw3 diff --git a/assets/characters/nancy/moth_mask/jump2.png b/assets/characters/nancy/moth_mask/jump2.png index 284391c0e99a7c60b666b8bd02a8f9dcdc7f17f7..d0c01d739cf977c47dad8d5a247bfe05f5af6d63 100644 GIT binary patch delta 140 zcmV;70CWHP2Au(r8Gi-<001BJ|6u?C00DDSM?wIu&K&6g0037>L_t(IjqQTFyn$Yk#{trg*vo|m5gr@Ztk^5EEY$98sa(3H u4J^y$07oPqr;qXU1aRI~V$F}w;RJlw8b_G2@d^L{002ovP6b4+LSTZyvpc8& literal 890 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl4m>B|mLR^8||3Gj_56Bn=qaiTT zLcr#EQY6sNj3q&S!3+-1ZlnP@8lEnWAre!Q6Ap0BIKa_)p5@>XZUaLj!-ZN2EL{eR iUN{6FY&f^vn1R8-hru;#QAIi^&^%rJT-G@yGywpdbtJw3 diff --git a/assets/characters/nancy/moth_mask/jump3.png b/assets/characters/nancy/moth_mask/jump3.png index 284391c0e99a7c60b666b8bd02a8f9dcdc7f17f7..d0c01d739cf977c47dad8d5a247bfe05f5af6d63 100644 GIT binary patch delta 140 zcmV;70CWHP2Au(r8Gi-<001BJ|6u?C00DDSM?wIu&K&6g0037>L_t(IjqQTFyn$Yk#{trg*vo|m5gr@Ztk^5EEY$98sa(3H u4J^y$07oPqr;qXU1aRI~V$F}w;RJlw8b_G2@d^L{002ovP6b4+LSTZyvpc8& literal 890 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl4m>B|mLR^8||3Gj_56Bn=qaiTT zLcr#EQY6sNj3q&S!3+-1ZlnP@8lEnWAre!Q6Ap0BIKa_)p5@>XZUaLj!-ZN2EL{eR iUN{6FY&f^vn1R8-hru;#QAIi^&^%rJT-G@yGywpdbtJw3 diff --git a/assets/characters/nancy/moth_mask/run1.png b/assets/characters/nancy/moth_mask/run1.png index 0ce1a955e2f497633754db476abebfc7b32a9ff7..fbd086c5ad043420e5fb6e83fe0aa43879ad19f9 100644 GIT binary patch delta 131 zcmV-}0DS-Y29*Jj8GHr+001BJ|6u?C00DDSM?wIu&K&6g002)(L_t(IjbmV-7x;IP z;XgJu6RDcf#fUNhAE4L(MnVeyU1a#rsP~`Y|0PtVO!^SLM7w}d?>|;H3o)9}ZAa!4 l^a29|W-P#*KMIBo000yB8b{jvpRWJ_002ovPDHLkV1m`JGYJ3y literal 890 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl4m>B|mLR^8||3Gj_56Bn=qaiTT zLcr#EQY6sNj3q&S!3+-1ZlnP@8lEnWAre!Q6AtjsIKa_)p5@>XZUaLj!-ZN2EL{eR iUN{6FY&f@EpMk-EgTdAG>W^elpn1CbxvXM diff --git a/assets/characters/nancy/moth_mask/run2.png b/assets/characters/nancy/moth_mask/run2.png index ee7afb4586f5b4d9190b5dfc73d888b6a69069a1..559c1898c12773653341b9f173b3615fa85c7201 100644 GIT binary patch delta 131 zcmeyxHkEOLWDOew1B3kM|A|0~u{g-xiDBJ2nU_G0zo(01h(&L5f`ZVW-6uZCOV92M zIr}2XMY4fEAcsL&k@dfx(Vz4yzt4a8FSII1t+pd>QS5;g-{rMuw@RFSu}%3iXH{b( jqp?`RIeFH_3~USs#HHMMN&^IdMl*Q2`njxgN@xNAjK?r^ literal 890 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl4m>B|mLR^8||3Gj_56Bn=qaiTT zLcr#EQY6sNj3q&S!3+-1ZlnP@8lEnWAre!Q6B?M+44fVrI~sgs^6ByMS-~aIsMMoj hbs@xH!Dn^}1_qNJ2GQS5;g-{rMuw@RFSu}%3iXH{b( jqp?`RIeFH_3~USs#HHMMN&^IdMl*Q2`njxgN@xNAjK?r^ literal 890 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl4m>B|mLR^8||3Gj_56Bn=qaiTT zLcr#EQY6sNj3q&S!3+-1ZlnP@8lEnWAre!Q6B?M+44fVrI~sgs^6ByMS-~aIsMMoj hbs@xH!Dn^}1_qNJ2G|;H3o)9}ZAa!4 l^a29|W-P#*KMIBo000yB8b{jvpRWJ_002ovPDHLkV1m`JGYJ3y literal 890 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl4m>B|mLR^8||3Gj_56Bn=qaiTT zLcr#EQY6sNj3q&S!3+-1ZlnP@8lEnWAre!Q6AtjsIKa_)p5@>XZUaLj!-ZN2EL{eR iUN{6FY&f@EpMk-EgTdAG>W^elpn1CbxvXM diff --git a/assets/characters/nancy/moth_mask/run5.png b/assets/characters/nancy/moth_mask/run5.png index ee7afb4586f5b4d9190b5dfc73d888b6a69069a1..559c1898c12773653341b9f173b3615fa85c7201 100644 GIT binary patch delta 131 zcmeyxHkEOLWDOew1B3kM|A|0~u{g-xiDBJ2nU_G0zo(01h(&L5f`ZVW-6uZCOV92M zIr}2XMY4fEAcsL&k@dfx(Vz4yzt4a8FSII1t+pd>QS5;g-{rMuw@RFSu}%3iXH{b( jqp?`RIeFH_3~USs#HHMMN&^IdMl*Q2`njxgN@xNAjK?r^ literal 890 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl4m>B|mLR^8||3Gj_56Bn=qaiTT zLcr#EQY6sNj3q&S!3+-1ZlnP@8lEnWAre!Q6B?M+44fVrI~sgs^6ByMS-~aIsMMoj hbs@xH!Dn^}1_qNJ2GQS5;g-{rMuw@RFSu}%3iXH{b( jqp?`RIeFH_3~USs#HHMMN&^IdMl*Q2`njxgN@xNAjK?r^ literal 890 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl4m>B|mLR^8||3Gj_56Bn=qaiTT zLcr#EQY6sNj3q&S!3+-1ZlnP@8lEnWAre!Q6B?M+44fVrI~sgs^6ByMS-~aIsMMoj hbs@xH!Dn^}1_qNJ2GB|mLR^7@ z|AF9=9*{8#Mnhnvg@DcTq)1@CU?>Ul3kK%|P;MBZfNS~}8({o9c)B=-NKEbR_vB+x z;9$=D@qd1(m}b$&?K6d#l=e5a2I!u+^q{YTTQ*5r)XY@SJ1OB|mLR^7@ z|AF9=9*{8#Mnhnvg@DcTq)1@CU?>Ul3kK%|P;MBZfNS~}8({o9c)B=-NK8#mIKV35 z$T0Ib4^xkU-VEk&rl~2%1Q@yuj1{^SLKaA$zopr0EGY)lK=n! diff --git a/assets/characters/nancy/run3.png b/assets/characters/nancy/run3.png index 3606397ec10caecee8ee614694ac1b38e860c8b7..fd4b45c5e079bb5a45698452710e8f6afe512d46 100644 GIT binary patch literal 1185 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GA|hzm>B|mLR^7@ z|AF9=9*{8#Mnhnvg@DcTq)1@CU?>Ul3kK%|P;MBZfNS~}8({o9d%8G=NK7s559DJo zU~x8mSO0vX#@5uo3bh$#o99mmdarp#$7lVO3-SU-uJ2vqq&(Ad9w*newnom+ep6UB eyg7e&!7s+POAN2)MCrZ-B_~f;KbLh*2~7a0em6(} delta 113 zcmV-%0FM8m36%$sBe5_H17-jLbW%=J06^y0W&i*HLrFwIR2Y?Yk5LK$FbG1E?tkYk z(6Yh&D71QP5kH~iK1-O{HNC=N_KAXQ1`~tAkz$S)!GpCC5Mka4$^w=Bxi?@xgK+@n T{0FPO00000NkvXXu0mjfe6=j; diff --git a/assets/characters/nancy/run4.png b/assets/characters/nancy/run4.png index 7470db745ef9fb44b3ef8917c420ffe1e7189023..11a68d11bceb958b0adefdb053c0e13806436097 100644 GIT binary patch literal 1188 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GA|hzm>B|mLR^7@ z|AF9=9*{8#Mnhnvg@DcTq)1@CU?>Ul3kK%|P;MBZfNS~}8({pqdAc};NK7s5KPkwd zz`=ZS$^Ut_4IEaVio!WFzG*Ye^^`Ns-^ty`cVbB|mLR^7@ z|AF9=9*{8#Mnhnvg@DcTq)1@CU?>Ul3kK%|P;MBZfNS~}8({p~d%8G=NK7s559DGn z;BXRtU;ljLtrJ~;EwX~QEq*0UbzK5m;0{?WrxmB|mLR^7@ z|AF9=9*{8#Mnhnvg@DcTq)1@CU?>Ul3kK%|P;MBZfNS~}8({pqc)B=-NK7s5_vB+x z;9$=D_20hx+6GBmfpiVQv;Wu~)F*Ki+zL(FK1b5&SxScKB+kR3e_KTsom?T@y!FPN f-#@R3Jl)4ooy>59-P`yPC_Q<)`njxgN@xNAYg09l delta 112 zcmV-$0FVEo36uwrBe5_H17!dKbW%=J06^y0W&i*HLP9{+_G-QN-hccqw=4DR9#GSa z&{(U30@?|C@4dCwF5lFaa*pL;8%NIva!hVlTIh^uyI!Lk3S<1_E5Rzg?+Yw$kH8^o9Yz(1GxY$mn3rSp01l0e8ll0GvT)wO~9gezc?M zZ9(xb{;%NwTmg>QBYG(Q#lKJ}91OS&aWtZX4<9o00e?|0X_Agr@f#hg_~4~8Df$`F z^V(Sa^A4}8b3rw^XKoJ$&ufreJ$CnEe-csn;Db7 zg={SS2Kl6vgJ_3Cur-j8!p5J>$tdds6qL@0`pu>T(Lr@@L=Vu`dp$X=l|fG?i0_PJ z&%g?5>3=|zUSvqdHB^lZA72BU#R2`uBpPGNw0g8X|FBA$7$UEogncp!+^m_ljJMQ(- z2Nx@yDQS%E{L6NzpQZQWpsD(zcKW`%r>keT(QgVySld_2J$fGXvv@@PCMt8LJ>q@w zK7S%XGfcCJMx4*%5ixE?{-`rX?&V7dLG8A5j4f$-JocoYMMfSu2B|_=?>&_JkI4EaOM7fk2_tSL*NykbpM)K#9 zk4MXE&(9YB2puHvOzyt$I=GkNW^?{C`?@s_u7k%bsCl&3%3MM4c{n5slnNy9Cucyc zA3VrDy8RY6K&@bi>cjm%@s{LS5DtJfIadB2aTwH2|MW6fh??^`lt0&ey!yf@KYfNP z+Mj^8`_qU-%Ng_XP3@B$re^-nLDd0@|Ec-^2N7i7n9su`Pyhe`07*qoM6N<$g5vQ< A)c^nh delta 1123 zcmV-p1f2Vj355xeF@HZvL_t(|ob6m&a_b-rg-*9qXaCEnvmpABKxLsPcKjIY%-osl z7(GGQIU>#JjWSOq?T9?h8D59|uz#feKp=1=$~+Zm7f|oN0moBvoQ^8rvRQB7fVf8 zOB}HP7au$yDS!R^>iP`{g$uWhC3KgP7D;ZppN|A5or{69yTJ2djtwK{Oe{PFRFOG1 zjMv!wznj+>9H_ap6!>ENJQXfic)n6PVF6U&LbxJ4F>pIpyLUkh72q0sj;BSFssGt~ zq2bqpupjo1u>b!A*x?;fMA#4efk5CuG_FYCv*8yL$bU<7dPsT0dm6{{cGnc|ER4~3 zXe|d6twzcsA1v{5e7QC!oDb4C%|48m%Yoz@&J&ig=7qD(<(Q(tDSztcn|}$G60gZE z=rV=%Ddk16;cKc11IMg+)KXtmKMl)b5p(|YJ50kuAKDjsfqTbuvKOi!-SG;zCYX8q zhJ#&3iGRh!?JUqSiB7XT86;*wl7AIfa_>AtJp(9jT@(a$_lni-GZ!PbIY{km7eTXSF zeq!h_V2&t1x}swE_wF<7hw+I7b43=kVxO8{&3}#;QsG!Pp>E!kr}m~tA=d1au11UV zF?)xTe_V`PzLIEpJmU3dEus$)_HS)J`T$`+><0pYH!!zPasBQy>4>A|>|!6N`wKpq z;r8*Dcx>C!2k2rT^3ml4{*z)A@@DOmNb;j{R3C)9*5p_l#&u)$*)^W9{UzO`9Q7FW z27hWgJ50v1S>^ z%6noRII3*2pSEFEsKqg=ch3`^T)wG>*QgD10c;WY*2&{IY0L$CnqU?mp+1&pURe~? z52_HW4;DS2>|S%ewR;$zo&^D_Xxmt-0e@EIgj}8W_W%JkT9w0n1gJ+nk8Ytd64iMqvDYoYLc#DpQ8vahh118*TNwF1PJ$ohlLCpzr_hqu3Q+* z=iZ9T{|DD6vTX1Jlac@c002ovPDHLkV1lVHDI5R* diff --git a/assets/tileset/library.png b/assets/tileset/library.png index e1814ea823bf3e7986fd4aa64087a0d9fb800c33..a4ffe1672dc16eceeea4e8a7ad8242df412e8692 100644 GIT binary patch delta 4295 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 delta 4114 zcmV+t5bf{JA)6qOFnOKcoP8pr>Ym^H>G-ZRU&(feN<5xW6r~O9{?~q z%W&*Q{$AtQ4Sx|Q2NcIwKHFjTP?3m@dU}A#YsG5X$c#AFroF+a;scIh)6}Z?w4{^7 zQ__e;OzIi}Wme`CRCygx#ifd`N|{`92wNEH4PqmR*chN;Le_A>d7mo&)GBc6AEK6> z{73}Oy7uHnmA|NXm7sXM-HMGM;>0Qj&8jTcp~>1bFn{@;JO}*Ojvke zUmJAm?N7vBAYx-6&)C>^KbZrFVGUQ#^IS(FL8(U!T2urYi8O@j4IsYFBYT+o^Z;eC zG@!D^a(~gtE>Z?=9vvS6=b_&3m_wKU?4*^IXPt+dXPglCH}#o9)JW=0UUrye^iJK7 zE=Be})p~#$Fw>^qq0WQ1TlTzS575^PxGF&IIYCWx09$^%-KsvxUYpj9Me+J8g7is`x#aZ!_ z(n=<(okmiZ6iA&{X!!vQYtz8!EU^Co@Z@LU;kUq}+xGN^PRa8JH-W+9z`j9X-!O3h zYky$)G%$Enr1R_lL>LD~1+?ci^olrtv@SjekIL)&U#H_x{=P7-{0EN%&z=zHw%>r# z9(Yk)KfVh*_(uK?6qne4z*&Z-=wxb{1e?RCqMzFN)N1!6L5j##ZQ!COQmk2J{!A00 zwp+l1n;cWCz}6zegPRd1} zhtG@fTZ}go3&75o;(BzJVeo{ggp~izGV4@6aXoZOl-ZuYc$SwxhwV4u?G`X_ z5SX~Ezc6pV#jJ7Vi!0Zvchm!zJwxvM^fv2c#@j8=qwgtRWAp&VTUmV91%IiH zYsgoa{iFKz?uz)_xWqAa#ug(h6OPAsMP)jC9@t*e?`|)N_=nHS@cR$Qhnc*_v3Z4I zV@c-!s?& zo(p=&d!KPkT$a~nBLjdRK45s^O_9&w$#i^`hqvVUp>x*ZZVq_TyO@nKZ~U!AW)AbR zhCq2Lx-(wZayv>dP+1Dp4W&~0$LXQ${)Z1_MKQbkiOZq^sFjeQH}v?tjDLUV9K(+v za%0^jWe8$4029hXEz_f0`hB$#n*8{o%=g)o?r=7!?0^`{A3o2O-bb>rV4p9kzY+a5 zI@Uim8Nzfboa@b_Yru~mW~Vnk4?MohQh#r7TYe+20uJGYCw+$J{-l35It!pJwZ)UqG=i#zRu zuczahWiEl)5V{4coIwq90Bu;5!zVbUDOMy$S@Fb#R~v#c>@3TPW3Sj*X6*NW73I2f zU7g(ahK&Wrj=nGQU%yyF!JQ3cl zHBkPt0jMjy`EZ4+8b2grawp$NB-;n70Po-sRYT%?QwW#0xc(v zqq7W?*JQbdUSY|^ob(W?Y+sE}I)tr7hV3O;-pwl%-meFsXB|EbO&3AB4>O!PCo%7f zG=QCDVE;j2WQGIp+lN3xammcduTMXagwGLH5xX-WE{vtZQ-9;|u{pa~Q{~>LiP%;> zu(g;Dt0rP=_(IYmZ|pyymrI=_KiLtV>N=}xe7aAcNqHR;ZAURR367Z-AbJ+xgnZ)? z-QyTN!|~nQrQUelz`SP*n5OdWHj+^zSyW+8<(j30AS8!1e}C zLna3{R1v4^{(m3;l^xE7?OAPU-TzN-hO-tiXx6YPk1j#Z0rEbCD_qt1O~)qt50Qq7 zOSz@W@O|NIgrB~U|H1mj-siu5F=+m&dKf7Gv>3EkH0jMBS`QFH4j(#y zli+%QiFX(_ul6R_iFW{>grwIi!-azgK+?^2*_D`H;VX z&u_sNo`0T6NN&>k=Sc^!`v7G4KI9;b9w0dzn*%%ax1MCm`CL!(DM;F;ee5h#4C0)^ z1a6c0t9k_0u3xdU_vXL5!f@~7WNe-|uh{$+#^+f|;zajUIllf(rZJwTdoZ6>%h#q4 zP<$UsIlBlS3)OIr6-_7cY*T)ZEL*pz2k=o;W`Ax%dIX#NJd2ST-f?yjk_^*CTt!rH zd2B4mGMSc`SApE`?Xt*wvKDyGhIHr&fWD1(vuy0vwxH(+$8TP}o=~ zKPLZm-R}Km=3~<@44l`TI9U(X-beEw&SXS3V#qaFYV zFNX)B9w6!g0+QDrAIP?aCv0-_be;eJcH~0-{A)uIffjjw6?5GppPnRxVEzEfS$`kv z0esSgq_?Cscr3Q?W_;dm>FWcL++4T!Z`vxoqO3+4ZNE(-Z&&>jjNigC%1O!jYc78& zq8`9O%C3L#L^{yMC64j=^dx_LUbTal%bS??{!PRvqt(}eP<0BO=S{*0U4%XlYv8lT z2GAi@iI3d?R7H~O&oh-!wm-T~6MyL5!ZCJMe5Mb3_~Fyy1wi6Q^`O=58boXWfc=d% zGQ-VPCki9h^Vyq_*mdGE*Tj!>n9$Ja{@3CKV2jiA9>9DHcI#*yt~b^%UorgQpXDpD z&$hmb?xAjMWhrX&KYB(sg1to412jMn5W*iJ`U3!ndH_LaJwQMDBPj4Y*MFlPASl~Q z0p!rex}f9p43F;?^E=4$1@IAE40_MPwfqyiRvI8 zo~+86zOQbYK?oCI=5)Ak)_*gn$ZdMATc74@)Iw(w&7t=UTZ{QBgfyEbI7VJ&09eW< zUOLS*ilmp@U4ds2Em_e;0}$ahuN3y#hz$S$t&-db?32M_rV~S_7(@uT2A!?@2#{2j4IZy&}s-vVXNaX~>bi=mv~5MwgRLxvv6K6l=6Dk0|%nBJk+j z)XEHM=Gya{28ga}bD!k2;iBz-iu(hYFvk4DG5a0?CiXC78GngRH}AqGkztnN0|e;qHFk|Q49KFKP+J)RX}10Y=TcXP=>b?@NOGr)$jiG*)2UXsTP z(*M3If7uN-i42XSW)aqJ9KGF{PZ`C%GQ_-G3h-`5k(VGA9V)kD#s#6kuH< ztqunCM~Fk94uwS`b>@BaeVDr@_B8(^7XV!7%jXvjAoQY0kw_p!11PJNt-9&8qv3@x zg^2VgUQ-A|QKRG9DZXTU8i5ouWGmNe1|01~8isccQ1y*kG`=%@%{@%19ZVumC5@T{ zyDMgVV}D1wL-CEWT~v&pYnW9Q&+shL-!P{USg*+8=i4nf=Rw7vk?;sja0uIc-6}80 z5i5Tr83Glxhj*Fw=8n%BKH!xF6Xs52PhN2yH6L1`04v)Q6l|K z90Eo98f_A6nkQskYgCONi3Fe?pWvv_itJHXXpv;J$c%(!AiljL{mlOXPwF5CHo|60u1Of@2w>s;{ ziC7Q_Y{tjSx%n}6{yc!g9Z}|>+CjM`PSS((XU{lCKV^6^9+YYbj#S1RxS|t(4t?`6 zJsM11c~RLa8E6K8hnL+Ye1fZ;ebpCQsn!xsF{8$&ZELO%wFh!O?Of_y7JkL}kmP+d zwDahovASmM)0;YN_t^9&QV+n&UDIu!YE)yARcWd(j?G%u4Dj$iAU6%7j^cP9tbB4? z(Wws?LND)lY&X0P=yBJ+qm+7C+y!5xDPOAVRKssqRF_?pfpaGA_{G+rnsyAxOBZpcGE^aEm`|M#=g1aq;#5$ zgmrjQoz_%cy_}@B(;(J4w!Q1;TFJyL<_12F2j z`@jvLs^xk~($87T%=L%DN} zW#G|f%+DE9Cp29(%B5GvN4YsTfIyFV9x?lmU3&^&1B0SP&ExRrg0n7DF0lo*btaOd zyoX#Ijs%Qwy~E@|+Y37pqBnU9rB#-8R@~?Y4|4EPRq3(HbH_ViRVlkRuzm3k5d0wO zhn3KY%*%+gBc{SL29~D2YR~U5=f7l(J~~mNA6SCT4zpcf0WWsb`QSU#asA1;$q8v) zd-j?0+FBXTcqWZxhrM|}r1Dck0Nm4bjWTe65nI0f^o+j!LPZzo_o+hty9Tl~Z@C9~ zw*9uKz)2Chyjr{R)Nt9u(1qZ5*6aY@S=rNrw`7oipgp_a>g`vdcf`y{ucti2T0_(u z6S!YWHg~gd%X-`hwQHSwUf zCyY4RiC}~e5cQ5$Z(8qm4jn<8jVQ_9?2$vt1S$S3kaiVbqo!ECX3@4+dj#nbo){FF zIalAuXE*nZEscsnCv2xzk-{D2X}@;M!hP%jvOcx|&<~8mfbh)4RC#6eEuz8P4%*Qz!b((=q-FOc4$oKR7vrx+5TARuheQ0qWi9|ie>QK z?us8=GZa#S&WQh5$hR`p_2#-Gk&Ip~xeJSA(t1y1F}$TvmDNKbz?(S{3dc48xdf#~ za7RX63w5YK9jo19s0s5Cew;4iDl33f8o#QGh!cwAFB=Bx)kRJeLDq0Zdv4zfp3p{< z-zd~$^qUUu8GPwqaQa{LpYORn_ANFnj%v7Z`37c)*P?(K)VUHGH2lU?4IXn5%GSd! zwKUc4d=m+mZtNwFnV9>X%BUKc$aS`@>WM{=^X*MRiQ2z2u5iB-l){E3$x>%|RiZfG zQ$&-;Z#9&&>|z=c^prpy1&NOd%0!CsUxnR@U-^MAC5r(N+l=Glbb@p0`wjIgI<3H_ zjZGZ{jUp%negg6ar`nI3L&Y<<^2Y@>%;*Hi{kL1ikaTkETw`>4`4Zt9Z$pbW<5(AI z)#A=LJh|vuw_)>r;Cu|OrtchnrVqK$Y+qyg!x-ooOq_Ss_?kpzCI?4^C|8O9PKA>> zL|FvEZ*Zf(hl<=kTF7AF{T~uS=kf*V3~sD^q%zili{fyMKfh|*;4@354FzqG*$Ar8 z5yR1x_&3N22v${YELw5H3=9F%SN`S#BVg9hHW@0w@MpE#^NujEf-gG5C*G6v7X+(m z?R#0R{tMO%dOZaJAJ@P;;j62-@%g5OOA*Kb?b}aia>3OYKuqr%*`XQoa1if$|Lje!u@u#P~pO7pslT)&OjEM{_; z{N!*APHM-XW0&!K6VRai9dka0w!Pjd*d$8RDDp8%w~DyUTuhW#w*H1Z8{Ac)$vZ&Z+Ejx6WT)nPRH{;^U(<|h?g(k=?zmN zNtzpGv44cYQgGF(^%j5xW6m!$7-QL7!b(s^syP8}_ChiaiDYl;(mdn@PZ?`e7?Y71 ziV`y$QXUhWK{Yp*J&>);Rzha~isACs^XVNFKP6cP!B`y=e9Wbu$SwVkq~!}Id|~$$ z9=j9A99RiTeXIKkG#k8vno>Qu7=qg*YvC2>Y9+Z%B2*wE$+?%2*`%BMI~G+P@YXs$ zdt##BVb?>xq}4-sTK}`8MTls%Kv=wlMr!Z1e8%zQ5%^3mbJu0!Rc+O4TSn@{_k$Wt zT(eB*bGl7j7zvFP!2qcyU~hrb-+~*2?gkNY0-XlrFV(9lcb^3dn^v;cd`@n6i_Ne=Zgw?lTgi;j z4hh$W6+-}fsE(KJt0%g$L^Vyb=86yB|G&J!3F^Dkd+|8wz9v9%|KN&-0}}_#$x;fe5Iq&vy}c5pB2YDM#|CVZpWNu_}59YFEP)(m=m(tQV|5E zvAAqcrUBQ)u9HPqRBgJ&Mu{uv)12>+iW_M97Tla1V4`7Jewg#zsb9)fp`gV zZLy;h?%-%2|4&b|`(_;p*M3nx0W)E@@CtmFxxTOhGY(5{yd$IHr<-MQLAXH)rG#-HaJvh0u$55>Q@Ix`Yq6kYf7>|!n|8k`I@szCCjhFkFh z=1`T>7t6}ilF{V3O|m8!LFJg*jbuB}pV8vYN>ZQ?0Vq;;7G5DxCwq;DV%PfXoTtv~ zC__|ZX-%kgVG)E&_3t>Wz9d^&QHOLfoyuV&1rmo;gtLhB&AIW>3{{qesi9HHj~M<$ zLz+A!(nqeWZ=#}aM)#d9{^-L<2>*uJiypr{@vvd}icpOW@)?c=zfuVFI#|Iw<>3{g zeP&3fy^tScxu>7}Qb546C7QIT0K&glI=cKw>_GT~Swj2xki}I&Ep%clkg{;7gp#sgFGokdb9P`NjsW|uS0XN!1fgWR 0 then - self.sprite_flip.x = 1 - else - angle = angle + math.rad(180) - self.sprite_flip.x = -1 - end - if self.hostile == true then self.draw_bow = true -- fix so it can rotate from 0 to 360 @@ -133,26 +127,29 @@ function Kupo:Smart() end function Kupo:HandleAnimation() - -- flip sprite to look in the direction is moving - if self.vel.x ~= 0 then self.sprite_flip.x = math.sign(self.vel.x) end + local distance_x = self.target.x - self.pos.x + local distance_y = self.target.y - self.pos.y - self.body:Animate() - self.body:Draw( - self.pos.x - Camera.pos.x - ( (self.sprite_offset.x) * math.cos(self.sprite_rotation) - (self.sprite_offset.y) * math.sin(self.sprite_rotation)) * self.sprite_scale.x * self.sprite_flip.x, - self.pos.y - Camera.pos.y - ( (self.sprite_offset.x) * math.sin(self.sprite_rotation) + (self.sprite_offset.y) * math.cos(self.sprite_rotation)) * self.sprite_scale.y * self.sprite_flip.y, - self.sprite_rotation, - self.sprite_scale.x * self.sprite_flip.x, - self.sprite_scale.y * self.sprite_flip.y - ) + if distance_x > 0 then + self.sprite_flip.x = 1 + else + self.sprite_flip.x = -1 + end - if self.draw_bow == true then - self.bow:DrawFrame( - math.min(self.bow_frame,self.bow_frames), - self.pos.x + ( 8 * math.sin(self.bow_rotation)), - self.pos.y + (2 - 6 * math.cos(self.bow_rotation)), - self.bow_rotation - ) - end + -- flip sprite to look in the direction is moving + if self.vel.x ~= 0 then self.sprite_flip.x = math.sign(self.vel.x) end + + self.body:Animate() + self:Draw(self.body) + + if self.draw_bow == true then + self.bow:DrawFrame( + math.min(self.bow_frame,self.bow_frames), + self.pos.x + ( 8 * math.sin(self.bow_rotation)), + self.pos.y + (2 - 6 * math.cos(self.bow_rotation)), + self.bow_rotation + ) + end end function Kupo:DoPhysics() diff --git a/data/scripts/entities/player.lua b/data/scripts/entities/player.lua index f3da319..4077548 100644 --- a/data/scripts/entities/player.lua +++ b/data/scripts/entities/player.lua @@ -7,15 +7,33 @@ Player.coins = 0 -- physics - o.moveSpeed = 1.5 + o.moveSpeed = 1.3 + o.zeroSpeed = 0.01 + o.move_x = 0 + + o.airFriction = 0.01 + o.groundFriction = 0.3 + + o.jumpImpulse = 3.5 + + o.dashCooldownTime = 0.1 + o.dashCooldownTimer = 0 + + o.dashTimer = 0 + o.dashTime = 0.15 + o.dashDistance = 40 + o.dashSpeed = o.dashDistance / (o.dashTime*60) + o.dashCount = 1 o.boxCollision = { from = {x = -8, y = -16}, to = {x = 8, y = 0} } - o.lightRange = 32 + o.lightRange = 0--32 + -- status + o.isDashing = false o.isJumping = false o.isOnGround = 0 o.coyoteValue = 5 @@ -26,10 +44,11 @@ o.maskType = animation.moth_mask -- sprite - o.sprite_offset = {x = 8, y = 16} o.target_offset = {x = 0, y = 12} o.body = Animation:New(animation.nancy.idle) o.mask = Animation:New(animation.moth_mask.idle) + o:centerOffset(o.body) + o:getBoundingBox(o.body, 3,-3,0,-1) -- lights o.light = CreateLight(o.pos.x,o.pos.y,o.lightRange) @@ -41,25 +60,100 @@ end function Player:Smart() - if love.keyboard.isDown("a") then self.vel.x = -self.moveSpeed - elseif love.keyboard.isDown("d") then self.vel.x = self.moveSpeed - else self.vel.x = 0 end - if love.keyboard.isDown("w") then self.vel.y = -self.moveSpeed - elseif love.keyboard.isDown("s") then self.vel.y = self.moveSpeed - else self.vel.y = 0 end -end - -function Player:DoPhysics() - self.pos.x = self.pos.x + self.vel.x - self.pos.y = self.pos.y + self.vel.y -end - -function Player:HandleAnimation() + -- light self.light.pos.x = self.pos.x-self.target_offset.x self.light.pos.y = self.pos.y-self.target_offset.y + if self.dashTimer <= 0 then + if self.isOnGround then + self.vel.x = self.vel.x * (1-self.groundFriction) + else + self.vel.x = self.vel.x * (1-self.airFriction) + end + + if math.abs(self.vel.x) < self.zeroSpeed then self.vel.x = 0 end + + if love.keyboard.isDown(keybind.moveLeft) then + self.move_x = -self.moveSpeed + elseif love.keyboard.isDown(keybind.moveRight) then + self.move_x = self.moveSpeed + else + self.move_x = 0 + end + self.vel.x = self.vel.x + + if love.keyboard.isDown(keybind.moveJump) then + if self.isOnGround then + self.vel.y = -self.jumpImpulse + end + end + end + + self.dashCooldownTimer = math.max(0,self.dashCooldownTimer - current_dt) + if love.keyboard.isDown(keybind.moveDash) then + if self.dashCooldownTimer == 0 + and not self.isDashing + and self.dashCount > 0 then + self.dashCount = self.dashCount - 1 + self.isDashing = true + local vertical = 0 + if love.keyboard.isDown(keybind.moveDown) then vertical = vertical + 1 end + if love.keyboard.isDown(keybind.moveUp) then vertical = vertical - 1 end + local horizontal = 0 + if love.keyboard.isDown(keybind.moveRight) then horizontal = horizontal + 1 end + if love.keyboard.isDown(keybind.moveLeft) then horizontal = horizontal - 1 end + + if horizontal == 0 and vertical == 0 then + horizontal = self.sprite_flip.x + end + + self.dashDirection = GetAngleFromVector(horizontal, vertical) + self.dashTimer = self.dashTime + end + else + self.isDashing = false + end +end + +function Player:DoPhysics() + + self.isOnGround = false + + self.dashTimer = self.dashTimer - current_dt + if self.dashTimer > 0 then + self.dashCooldownTimer = self.dashCooldownTime + self.vel.x = self.dashSpeed * math.cos(self.dashDirection) + self.vel.y = self.dashSpeed * math.sin(self.dashDirection) + else + self.dashTimer = 0 + self.vel.y = self.vel.y + gravity + end + + if not self:isCollidingAt(self.pos.x + self.vel.x + self.move_x, self.pos.y, objects.collisions) then + self.pos.x = self.pos.x + self.vel.x + self.move_x + else + self.vel.x = 0 + end + + if not self:isCollidingAt(self.pos.x, self.pos.y + self.vel.y, objects.collisions) then + self.pos.y = self.pos.y + self.vel.y + else + if self.vel.y > 0 then + self.isOnGround = true + self.dashCount = 1 + self.vel.y = 0 + end + end +end + +function Player:HandleAnimation() + if self.dashTimer > 0 then + self.sprite_tint = {1,1,0} + else + self.sprite_tint = {1,1,1} + end -- flip sprite to look in the direction is moving - if self.vel.x ~= 0 then self.sprite_flip.x = math.sign(self.vel.x) end + if self.move_x ~= 0 then self.sprite_flip.x = math.sign(self.move_x) end -- animation priority if self.vel.y > 1.25 then @@ -68,7 +162,7 @@ function Player:HandleAnimation() elseif self.vel.y < 0 then self.body = self.body:ChangeTo(animation.nancy.jump) self.mask = self.mask:ChangeTo(self.maskType.jump) - elseif self.vel.x ~= 0 then + elseif self.vel.x + self.move_x ~= 0 then self.body = self.body:ChangeTo(animation.nancy.run) self.mask = self.mask:ChangeTo(self.maskType.run) else @@ -82,18 +176,8 @@ function Player:HandleAnimation() end self.body:Animate() - self.body:Draw( - math.floor(self.pos.x) - Camera.pos.x - ( (self.sprite_offset.x) * math.cos(self.sprite_rotation) - (self.sprite_offset.y) * math.sin(self.sprite_rotation)) * self.sprite_scale.x * self.sprite_flip.x, - math.floor(self.pos.y)- Camera.pos.y - ( (self.sprite_offset.x) * math.sin(self.sprite_rotation) + (self.sprite_offset.y) * math.cos(self.sprite_rotation)) * self.sprite_scale.y * self.sprite_flip.y, - self.sprite_rotation, - self.sprite_scale.x * self.sprite_flip.x, - self.sprite_scale.y * self.sprite_flip.y - ) - self.mask:Draw( - math.floor(self.pos.x) - Camera.pos.x - ( (self.sprite_offset.x) * math.cos(self.sprite_rotation) - (self.sprite_offset.y) * math.sin(self.sprite_rotation)) * self.sprite_scale.x * self.sprite_flip.x, - math.floor(self.pos.y)- Camera.pos.y - ( (self.sprite_offset.x) * math.sin(self.sprite_rotation) + (self.sprite_offset.y) * math.cos(self.sprite_rotation)) * self.sprite_scale.y * self.sprite_flip.y, - self.sprite_rotation, - self.sprite_scale.x * self.sprite_flip.x, - self.sprite_scale.y * self.sprite_flip.y - ) + self:Draw(self.body) + if self.dashCount > 0 then + self:Draw(self.mask) + end end diff --git a/data/scripts/entity.lua b/data/scripts/entity.lua index 3f6cb23..38ef0d8 100644 --- a/data/scripts/entity.lua +++ b/data/scripts/entity.lua @@ -1,5 +1,4 @@ -Entity = { - } +Entity = {class = "Entity"} function Entity:New(x,y) o = {} @@ -8,14 +7,14 @@ function Entity:New(x,y) o.boxCollision = { from = {x = x, y = y}, - to = {x = x, y = y} + to = {x = x, y = y}, } - o.class = "Entity" - + o.target_offset = {x = 0, y = 0} o.sprite_offset = {x = 0, y = 0} o.sprite_scale = {x = 1, y = 1} o.sprite_rotation = math.rad(0) + o.sprite_tint = {1,1,1} o.sprite_flip = { x = 1, y = 1} o.illuminated = false @@ -24,14 +23,45 @@ function Entity:New(x,y) return o end +function Entity:centerOffset(animation,x,y) + local x = x or 0 + local y = y or 0 + self.sprite_offset.x = animation.imgs[1]:getWidth()/2 + x + self.sprite_offset.y = animation.imgs[1]:getHeight()/2 + y +end + +function Entity:getBoundingBox(animation,left,right,top,bottom) + local left = left or 0 + local right = right or 0 + local top = top or 0 + local bottom = bottom or 0 + self.boxCollision.from.x = -animation.imgs[1]:getWidth()/2 + left + self.boxCollision.to.x = animation.imgs[1]:getWidth()/2 + right + self.boxCollision.from.y = -animation.imgs[1]:getHeight()/2 + top + self.boxCollision.to.y = animation.imgs[1]:getHeight()/2 + bottom +end + +function Entity:Draw(animation) + local c1, c2, c3, a = love.graphics.getColor() + love.graphics.setColor(self.sprite_tint[1],self.sprite_tint[2],self.sprite_tint[3]) + animation:Draw( + self.pos.x - Camera.pos.x - ( (self.sprite_offset.x) * math.cos(self.sprite_rotation) - (self.sprite_offset.y) * math.sin(self.sprite_rotation)) * self.sprite_scale.x * self.sprite_flip.x, + self.pos.y - Camera.pos.y - ( (self.sprite_offset.x) * math.sin(self.sprite_rotation) + (self.sprite_offset.y) * math.cos(self.sprite_rotation)) * self.sprite_scale.y * self.sprite_flip.y, + self.sprite_rotation, + self.sprite_scale.x * self.sprite_flip.x, + self.sprite_scale.y * self.sprite_flip.y + ) + love.graphics.setColor(c1,c2,c3,a) +end + -- returns true if theres a collision at that point. also marks collisioned tile as collision true function Entity:isCollidingAt(x,y,object) local result = false for _, col in pairs(object) do - result = self.pos.x + self.boxCollision.from.x < col.to.x - and self.pos.x + self.boxCollision.to.x > col.from.x - and self.pos.y + self.boxCollision.from.y < col.to.y - and self.pos.y + self.boxCollision.to.y > col.from.y + result = x + self.boxCollision.from.x < col.to.x + and col.from.x < x + self.boxCollision.to.x + and y + self.boxCollision.from.y < col.to.y + and col.from.y < y + self.boxCollision.to.y if result == true then break end end return result @@ -39,9 +69,9 @@ end function Entity:isCollidingWith(entity) return self.pos.x + self.boxCollision.from.x < entity.pos.x + entity.boxCollision.to.x - and self.pos.x + self.boxCollision.to.x > entity.pos.x + entity.boxCollision.from.x + and entity.pos.x + entity.boxCollision.from.x < self.pos.x + self.boxCollision.to.x and self.pos.y + self.boxCollision.from.y < entity.pos.y + entity.boxCollision.to.y - and self.pos.y + self.boxCollision.to.y > entity.pos.y + entity.boxCollision.from.y + and entity.pos.y + entity.boxCollision.from.y < self.pos.y + self.boxCollision.to.y end function Entity:isCollidingAtAll(x,y) @@ -58,131 +88,8 @@ function Entity:isCollidingAtAll(x,y) return result end ---[[function Entity:Draw() - if self.sprite ~= nil then - local relative_position_x = self.pos.x - Camera.pos.x - local relative_position_y = self.pos.y - Camera.pos.y - local origin_compensation_x = - ( (self.sprite_offset.x) * math.cos(self.sprite_rotation) - (self.sprite_offset.y) * math.sin(self.sprite_rotation)) - local origin_compensation_y = - ( (self.sprite_offset.x) * math.sin(self.sprite_rotation) + (self.sprite_offset.y) * math.cos(self.sprite_rotation)) - local dimensions_x = self.sprite_scale.x * self.sprite_flip.x - local dimensions_y = self.sprite_scale.y * self.sprite_flip.y - love.graphics.draw( - self.sprite, - relative_position_x + origin_compensation_x * dimensions_x, - relative_position_y + origin_compensation_y * dimensions_y, - self.sprite_rotation, - self.sprite_scale.x * self.sprite_flip.x, - self.sprite_scale.y * self.sprite_flip.y - ) - if debug_collision then - love.graphics.setColor(1, 0, 0) - love.graphics.circle( "line", relative_position_x, relative_position_y, 2 ) - love.graphics.setColor(0, 1 ,0) - love.graphics.circle( "line", - relative_position_x + origin_compensation_x * dimensions_x, - relative_position_y + origin_compensation_y * dimensions_y, - 2 - ) - end - love.graphics.setColor(1, 1 ,1) - end -end - -function Entity:NewAnimation(anim,frames,speed) - local anim_data = { - frame = 1, - subframe = 1, - path = anim.path, - frames = anim.frames, - speed = anim.speed, - imgs = anim.imgs - } - self.animations[#self.animations+1] = anim_data - - return self.animations[#self.animations] -end - -function DrawAnimationFrame(animation, frame, x, y, rotate, sx, sy) - local x = x or 0 - local y = y or 0 - local sx = sx or 1 - local sy = sy or 1 - love.graphics.draw( - animation.imgs[frame], - x - Camera.pos.x, - y - Camera.pos.y, - rotate, - sx, - sy - ) -end - -function DrawAnimation(animation, x, y, rotate, sx, sy) - local x = x or 0 - local y = y or 0 - local sx = sx or 1 - local sy = sy or 1 - if game_paused ~= true then - -- try to animate - animation.subframe = animation.subframe + current_dt - - if animation.subframe >= animation.speed then - animation.frame = animation.frame + 1 - animation.subframe = animation.subframe - animation.speed - end - - -- cycle - if animation.frame >= animation.frames+1 then - animation.frame = animation.frame - animation.frames - end - end - love.graphics.draw( - animation.imgs[animation.frame], - x - Camera.pos.x, - y - Camera.pos.y, - rotate, - sx, - sy - ) -end - -function Entity:Animate() - if game_paused ~= true and self.anim.path ~= nil then - -- try to animate - self.anim.subframe = self.anim.subframe + current_dt - - if self.anim.subframe >= self.anim.speed then - self.anim.frame = self.anim.frame + 1 - self.anim.subframe = self.anim.subframe - self.anim.speed - end - - -- cycle - if self.anim.frame >= self.anim.frames+1 then - self.anim.frame = self.anim.frame - self.anim.frames - end - - -- change - self.sprite = self.anim.imgs[self.anim.frame] - end -end - -function Entity:LoadAnimation(anim,frames,speed) - if self.anim.path ~= anim and self.anim.path ~= anim.path then - if frames ~= nil and speed ~= nil then - self.anim.path = anim or nil - self.anim.frames = frames or 4 - self.anim.speed = speed or frames - else - self.anim.path = anim.path - self.anim.frames = anim.frames - self.anim.speed = anim.speed - end - - self.anim.imgs = anim.imgs - end -end -]]-- - require "data/scripts/entities/kupo" require "data/scripts/entities/arrow" +require "data/scripts/entities/decoration" require "data/scripts/entities/player" +require "data/scripts/entities/fairy" diff --git a/data/scripts/enums.lua b/data/scripts/enums.lua index edea2dc..46dea88 100644 --- a/data/scripts/enums.lua +++ b/data/scripts/enums.lua @@ -1,6 +1,20 @@ -- animationsç -- all these are linear animations, maybe in the future make proper animations? animation = { + fairy = { + flying = { + path = "assets/characters/fairy/flying", + frames = 2, + speed = 1/30 + } + }, + decoration = { + candelabra = { + path = "assets/characters/decoration/candelabra", + frames = 8, + speed = 1/6 + } + }, kupo = { body = { path = "assets/characters/kupo/kupo", diff --git a/data/scripts/in_out.lua b/data/scripts/in_out.lua index 914782e..47dcb8c 100644 --- a/data/scripts/in_out.lua +++ b/data/scripts/in_out.lua @@ -1,9 +1,3 @@ -function doOutput(table) - local file = io.open("map.json", "w") - io.output(file) - io.write(json.encode(table)) - io.close(file) -end function getInput(filename) local file = io.open(filename, "r") diff --git a/data/scripts/keybind.lua b/data/scripts/keybind.lua new file mode 100644 index 0000000..e1acf4c --- /dev/null +++ b/data/scripts/keybind.lua @@ -0,0 +1,9 @@ +keybind = {} + +keybind.moveLeft = "left" +keybind.moveRight = "right" +keybind.moveUp = "up" +keybind.moveDown = "down" +keybind.moveJump = "z" +keybind.moveAttack = "x" +keybind.moveDash = "c" diff --git a/data/scripts/level.lua b/data/scripts/level.lua index 77929ab..d1f75e9 100644 --- a/data/scripts/level.lua +++ b/data/scripts/level.lua @@ -8,8 +8,6 @@ function LevelLoadTiles() overlay = render another tile id or, if multiple tiles {id, id, id,} or overlay_depth = foreground/background overlay depth type = collision type - - ]] LevelData = dofile("Mothback/data/levels/"..currLevel..".lua") diff --git a/data/scripts/lights.lua b/data/scripts/lights.lua index aa84a96..48d2349 100644 --- a/data/scripts/lights.lua +++ b/data/scripts/lights.lua @@ -2,7 +2,7 @@ Lights = {} LightTimer = 0 function CreateDarkness() - return love.graphics.newCanvas(game.width, game.height) + return love.graphics.newCanvas(game.width/game.scale, game.height/game.scale) end function CreateLight(x,y,range,lum,flicker) @@ -13,10 +13,10 @@ function CreateLight(x,y,range,lum,flicker) } o.range = range o.lum = lum or 1 - o.flicker_value = flicker or 1 + o.flicker_value = flicker or 2 o.flicker = 0 o.dim = 0 - o.flicker_speed = flicker_speed or 10 + o.flicker_speed = flicker_speed or 60/12 o.flicker_time = 0 table.insert(Lights,o) return o @@ -24,7 +24,7 @@ end function SetDarkness() love.graphics.setColor(0,0,0,1) - love.graphics.rectangle("fill",0,0,game.width,game.height) + love.graphics.rectangle("fill",0,0,game.width ,game.height) end function DoLights() @@ -34,37 +34,30 @@ function DoLights() if light.flicker_time >= light.flicker_speed then light.flicker_time = light.flicker_time - light.flicker_speed - light.flicker = 0 + math.random(-1,1) + light.flicker = 0 + math.random(0,1) light.flicker = math.min(math.max(light.flicker, -light.flicker_value),light.flicker_value) end end ---[[ - -- first, border - love.graphics.setColor(1,1,1) - for _, light in pairs(Lights) do - - love.graphics.circle( - "fill", - light.pos.x - Camera.pos.x, - light.pos.y - Camera.pos.y, - light.range + light.flicker + 1 - ) - end - ]] love.graphics.setBlendMode("replace") - for _, enty in pairs(LoadedEntities) do - end - - local shades = 200 - for i=1, shades do - for _, light in pairs(Lights) do - local luminosity = shades*light.lum/100 - love.graphics.setColor(0,0,0,math.min(1,math.max(0,(shades-i-luminosity+1)/(shades-luminosity+1)))) + love.graphics.setColor(1,1,1,1) + for _, light in pairs(Lights) do + if light.range ~= 0 then love.graphics.circle( "fill", - light.pos.x - Camera.pos.x, - light.pos.y - Camera.pos.y, - (light.range + light.flicker)*(shades-i+1)/shades + (light.pos.x - Camera.pos.x) / game.scale, + (light.pos.y - Camera.pos.y) / game.scale, + (light.range + light.flicker + 1) / game.scale + ) + end + end + love.graphics.setColor(0,0,0,0) + for _, light in pairs(Lights) do + if light.range ~= 0 then + love.graphics.circle( + "fill", + (light.pos.x - Camera.pos.x) / game.scale, + (light.pos.y - Camera.pos.y) / game.scale, + (light.range + light.flicker) / game.scale ) end end @@ -75,5 +68,5 @@ function DoBorder() end function DrawDarkness() - love.graphics.draw(Canvas.Darkness, 0, 0, 0, 0.5, 0.5) + love.graphics.draw(Canvas.Darkness, 0, 0, 0, 2/game.scale) end diff --git a/data/scripts/math.lua b/data/scripts/math.lua index f2e3a48..704a8f1 100644 --- a/data/scripts/math.lua +++ b/data/scripts/math.lua @@ -7,3 +7,11 @@ function math.sign(x) return 0 end end + +function GetAngleFromVector(x,y) + local reduce = 0 + if x < 0 then + reduce = math.rad(180) + end + return math.atan(y/x) - reduce +end diff --git a/main.lua b/main.lua index e4f10f0..b13b151 100644 --- a/main.lua +++ b/main.lua @@ -1,21 +1,28 @@ function love.load() + do_pause = false + debug = false debug_collision = false + editor_mode = false + textScale = 1 fps_count = 0 fps_second = 0 fps_draw = 0 fps_total = 0 + love.graphics.setColor(1,1,1) love.keyboard.setKeyRepeat(true) love.graphics.setDefaultFilter("nearest") -- good pixel + game = { scale = 2, width = love.graphics.getWidth(), height = love.graphics.getHeight(), paused = false } + require "data/scripts" Canvas = { Darkness = CreateDarkness() @@ -23,19 +30,25 @@ function love.load() love.graphics.setCanvas(Canvas.Darkness) SetDarkness() love.graphics.setCanvas() + Camera.width = game.width Camera.height = game.height + levelList = {"level1","2","3","ewae","tileset"} levelNum = 1 currLevel = levelList[levelNum] LoadedEntities = {} LevelLoadTiles() - main_Player = Player:New(0,20) + + main_Player = Player:New(75,50) + table.insert(LoadedEntities,main_Player) table.insert(LoadedEntities,Kupo:New(700,150)) table.insert(LoadedEntities,Kupo:New(800,150)) - CreateLight(200,64,80,nil,5,{1,0,0}) - main_Player.sprite = love.graphics.newImage("assets/characters/nancy/idle1.png") + table.insert(LoadedEntities,Decoration:New(200,89,animation.decoration.candelabra,80)) + table.insert(LoadedEntities,Fairy:New(200,88)) + + gravity = 0.2 end function love.update(dt) @@ -50,16 +63,35 @@ function love.update(dt) fps_count = fps_count + 1 current_dt = dt - -- GAME STEP - if not do_pause then - SetCollisionFlags(main_Player) - for _, enty in pairs(LoadedEntities) do - enty:Smart() - enty:DoPhysics() - end + + if editor_mode then + + AnimateTiles() - Camera:CenterAt(main_Player.pos.x, main_Player.pos.y) - --camera:ScreenAt(main_Player.pos.x, main_Player.pos.y,game.width,game.height) + else + -- GAME STEP + if not do_pause then + SetCollisionFlags(main_Player) + for _, enty in pairs(LoadedEntities) do + enty:Smart() + enty:DoPhysics() + end + AnimateTiles() + Camera:CenterAt(main_Player.pos.x, main_Player.pos.y) + --camera:ScreenAt(main_Player.pos.x, main_Player.pos.y,game.width,game.height) + end + end +end + + +function love.wheelmoved(_, y) + if editor_mode then + if palette then + p_scroll = p_scroll + y + else + local oscale = game.scale + game.scale = math.max(0.1,game.scale + y/16) + end end end @@ -86,19 +118,23 @@ function love.keypressed(key) end if key == "f2" then - main_Player.pos.x, main_Player.pos.y = -16,-0.1 + if editor_mode then + + else + main_Player.pos.x, main_Player.pos.y = 16,-10 + end end if key == "f3" then LoadLevel() end - if key == "f5" then - levelNum = levelNum + 1 - if levelNum > #levelList then levelNum = levelNum - #levelList end - currLevel = levelList[levelNum] - LevelLoadTiles() - main_Player.pos.x, main_Player.pos.y = 0,-0.1 + if key == "f4" then + if editor_mode then + editor_mode = false + else + editor_mode = true + end end end