From f5305e23635ce35f9d04224dce68d8f5bc26f0ca Mon Sep 17 00:00:00 2001 From: Nicholas Hayashi Date: Wed, 13 Jan 2021 01:37:34 -0500 Subject: [PATCH] idk --- main.lua | 11 +++++--- res/satelite.png | Bin 0 -> 31149 bytes sound.lua | 6 ++--- src/grid.lua | 64 +++++++++++++++++++++++++++++++++++++-------- src/mob.lua | 59 +++++++++++++++++++++++++++++++++-------- src/projectile.lua | 3 +-- src/tower.lua | 5 ++-- texture.lua | 1 + 8 files changed, 117 insertions(+), 32 deletions(-) create mode 100644 res/satelite.png diff --git a/main.lua b/main.lua index 81eb49f..00f2ab7 100644 --- a/main.lua +++ b/main.lua @@ -72,7 +72,7 @@ local function can_do_build(hex, tile, tower_type) end local function game_action(scene) - if SCORE < 0 then game_end() end + --if SCORE < 0 then game_end() end TIME = TIME + am.delta_time SCORE = SCORE + am.delta_time @@ -111,7 +111,12 @@ local function game_action(scene) TRDT = (TRDT + 1) % #table.keys(TRDTS) elseif WIN:key_pressed"tab" then - select_tower_type((SELECTED_TOWER_TYPE) % #table.keys(TOWER_TYPE) + 1) + local num_of_types = #table.keys(TOWER_TYPE) + if WIN:key_down"lshift" then + select_tower_type((SELECTED_TOWER_TYPE + num_of_types - 2) % num_of_types + 1) + else + select_tower_type((SELECTED_TOWER_TYPE) % num_of_types + 1) + end elseif WIN:key_pressed"1" then select_tower_type(TOWER_TYPE.REDEYE) elseif WIN:key_pressed"2" then select_tower_type(2) @@ -214,7 +219,7 @@ local function toolbelt() toolbelt:append(tower_select_square) local tower_type_values = table.values(TOWER_TYPE) - local keys = { '1', '2', '3', '4', '5', '6', '7', '9', '0', '-', '=' } + local keys = { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=' } for i = 1, #keys do if tower_type_values[i] then toolbelt:append( diff --git a/res/satelite.png b/res/satelite.png new file mode 100644 index 0000000000000000000000000000000000000000..e8e27a12b5ee847f04e74274f3b8af1b3cfb9b92 GIT binary patch literal 31149 zcmd3Ng;&&FwD!;~4KLk8r-Tv`g5;pY3=Am}I;3=Wr*w*R4>k0V(jg$-9a56g2;X?` zy8pws77Q%b48MKO*=NV|JUjB8rZN#eEj|DMAW~IP)CK_1`2Kz4Vx#`z=^N*Y`hn)G zt*ij38l&F_0GI))it@T1Uys^NW9a96fp-&2%Q6j1!;qb4*AUC0tg?V^OXuHmqYZ#@ zc5G?#`|lV#^142O`iD4%L&5B8oK>G4Hz>(^B=nbEAFMcuYm>rX7|0dx5Ez*~kR%b> z!)eeO7eYAdaMM2%$+3b1unj{?HzXsxnofGkobRT~oDWQ|3BxUX!+v}_xN|N?9#pL5 zoLo!EePNXG`m;Atp#1;QFVgHc!)cu&Pyb&0e{Sua?QKj4Gs=BYCJ=1Dne-9K=z==e zoc+Nz`CFiO?+qUqKF!0C31Iy4tg6k)@>Pb$y6k?>rIE&J_Iicsy|n}EQlG}F`=FN0 z$a81-;V$;@bj7 zLcaf7WjJ+#E7QIx7T|@=Ge7_dx&khJ)?YhfyV?#VK1IintR{QLr}y5{WP4&FG6q|m z68<7a>)PY$EoSL159xjfyGMxs)8(hoRgR+x zeA$-Uq}$`CRsscFk<9Omi_DGugVy)tOF^Y>uWB*WxHq}5Sul@jsN;UWH#f)dzW4U9 zIjLL~Lw&MceZD|=b0HHxh_T$t~J*`IA(fDmmgNgpX-eX^ee(;Wk4 zEmz$8Uy8dq*R>aA3`dW@1*(iY#h%sBCZAMLprvh**oBCA*l_ zPmER=k^ej@#tLA$#12Cb=xdUmd+i~s=<$V=AzSOn#~MeTWPS0{roCvUfE0CZTG35a zro8cB`hgf1uF%$gb|RNIeRmY~^~B?i8!bOXq;QEbVRpVg1QMJQj&@C)m5i7FPJ`or zS8;N^o^z35nNqAWi3v;WHoZ0@;>edfn!(Xb+ElBazJ z`Vbsnytl;vR;1O{a5%RsPtqm(i_K5)O@4fen1$twtDo33WbrJ4&)J#9&8R4#y)}Eb zwWb{cj<)ff>31tqhu=-=98tF6I$aB?k{|ha;hcFpzBQ0h+cWNFM0Ysucu5=tIHqY@ z$L`mPxpY3vf9P+d*`Tn-g{3}aJ-y~0e18TtUJE0-L!&%4^Wfx*vHWO5&?;fSesHMw ztMj_^ugMAH72u!8IPDGcywpgy+-dndOHaZl5-4&@qVPUX9{`fW)G9mU;~oDmaSHA; zfHKM0os^M}ofxm^pR0tR?kFyTHug=#NvO&*a`te%XU7bv)4loVOO;J4)D-veuk8}m zEEO&rx5$qb`JdV{Ea6{;*-M~DBhE6-Rfazp)sD^9)GKg)lFyodsi-#1W(vWHf#?4> zlpK{vH|M;u;7P3&3AbGmAk}(P7y3SVmul8_<5}i9{AEqMbn%WC{OH#+w#s)=up-#M zknpXB@uQLN-vjA3>JKZ$!?#U^2UVc!$D$Gjr8rTh||A-muXt3MYyt z@bPw%yyt9D>Z?Tg0&wt*mjrzflG?wSs2UCEmeEzU@wTCZWnTT=U^4#`a{1pTDx%rR zLmVmCUTTo6645{_TRt0o!J2ob{>hSBldPeuR6?;3W7o5#$AjC2t6?l4_LnV=$SD)$ zEIo7avtuRhfLzYX0SXy2nKw5JZ~etP@9t(^7Ev5NN_GoTNLJhkg`Mm!bfKZu+UXBI z_qp}Q1Za}~B<9+~u~Z)#wj?yd5{x&5f+yhUu$@5f>#xLX#?9evagN^6m&*sLhi9*= zd%QwUXIBlKp=!)YZ{9p_J8PF%&%Rv0f5lcID(@l7S>bA0|2*}1U{`l}{_V%aq|`PC zH2l&ZiriTAbdsg1|8erGaV7R(9>1h!mhdWz8?G^{D&bgtlyX)!5Ow zsHvMb<-A9q>zMvEA@^3F7|qY=f)h(!fykvol2cwZBxUp`jZzI$m+VQ;g|s56b9Hws z%Otl>4FQ5SSqu_t?k`6z4ELd@s*Nv(b;!50$BfA&k1Ht~07jUB;dsl>1w=9<7g1SC zzO%gnwSVu=#}wf?6NEIQ@$?82BU1h6-v!(6idua5M3{eM{-{p-Jug!xgNZugkagkIt(M_SP=f(t}4AUp}fA8$0P-tnC$ zN=X|R-=@yGREq3{I(_{^pu$|=5SJ3Fpv=M>iQZjE5Yu~ z^9@MU-#}c}T`DuD^oT|w?Q017VH&OTEQs!`LY8Oe)*GDx!R`! z-^>p$x?O*3Cv2dGI5$`9Fx$vEhz|o4Qn>vxZ4L>O%ZO$M{q^` zH!;Q)VOK}UTC{0NvW$m+-{!Hw%J*RdRfM5JFiQZ|JJ#yS1~8w1J$U~yRd$5ExT;50 zqp`QG&g4YXP4TThQEno+`yu_NuI&ti>uh9Py#>N)y!mvNK7{np+!d8?kO&Hwp)+hmfoilP(kC+sBzp)#Pxgkz)!I;e9fAZuNRs%Pm7kEuj#e4N3&EUJS;a zP{s|ZMo%i)(E5c;Ac<}5worC;U+VDlrhL6|qABmgN>|baslnq}CiDANWZ}TcxQT>(3o@@R z*dcmtM7#VsCA+GW)?$AqWMy9YLAhKS=qHhJYd8ngD zXsb5kfBo-<@MW^L;x(JRrcu!MYh~`x&SP^M8v+UYWdNYq6WV*A|EFN=3zjsYMT4k;{O4#3Su<&K-9I z^5VwfJZslze2h+-7Jw{Ku{iVJkIhw)CvPc{=mbL{N9X(fMQkFgm?YQK!u-^Hz+Ls@ zJouCWrB+5nbW;dqXjt)m(2>*m?qLxuD$T?PHsSuR^346gORJGsab*U$}?Tl>?4F)Ix?Q=6LY1zhE)bngT1e*M)xHBq|r zD|fw}c7}|x0 zpWAw4@&(ImD3yYfM^hW*#HMOitSNW! ztZHTq-Xp}xD(45ECv@IZwC=f~vY>SF)#wYz*teY^}N6=soClVnBd@Xi#} zkSC)EhK!g2)8o9KI*-U=URZ z_|pd&x5&RPEf8RkNQ038<|gGN;ysH3CMr~+k~@AP&Vn^uszkfxOCsrXOZ0=OPCu!B zb0DzdhhqBjOtFqZP21x(umAZV*&Lg)z7NuQAyEXX_0TF{amj4-y6O}%6y=0adoF!_ zKW^q?#*VO;oNh4!+6=Jcpi)r!!ImB>VY0rp+J>YKEheg#m!0Zf)4fv@6XpjBGGt%N z*Tfo!)=$Ip)I^HqkO$ovA0V#sUY=6qXZsP+Prs2>H~0Sn@`7maFE5YFFDAZ)sMRvV zd2GsucMcUG#P~c=&&J?)Ti9+K6+n_&-q3oHO#XnHoqLgge`Cs{x`6JE&3ET}uZK$c3$KHD#mSJNSVmE3?2Z#Em_ zchEq2*xp}gzrum{_oz0Y1`kz{ppWW{3uRe(Y+MKmNz??vZ#otSX*1;-^S6g|2=2FJ z);TsO6H*0CEY&1Sm&(jbTu3W6|JJ`~6Qf)5yn4sMzjB*FaVpu@ii8VvRrOa}Tu&-` zSZlF5Areoyk_WIYT7H1KorRyU%!}KJ6UpYP>f)h~)U9oW>$rw!U-u0*2)t zgazv(m7XK_-Aw8!Y+QYJRM(G+*{aGGV6sRcdr@>WC0{*_*edzALsXO7d_J6Viwco{ z-jU9|-XQB}x!*Ms)fr(@NGV-ROr`HUARCdic8|aIolKm`2B>~rza8%kmgUh0Up1Z$LWT^M3=|()0o+?vcdt1g}^t5Cw|AF4x zo2J%3_P)e#Kz6RLK-Z>}=eX$Jkgi_u8;(GB{M-&1o`A;RMZHe9P2)atkUk11ko;wg z@j@+jQ_?`sDXgYK-9xv~a;cHI;>?4ukPw#0+D6AJsd4)7D~H+wtE-e(=iU+RGP6Yd zlXU`MC!kdz4*bz_e-O^ITXg)EE~13uIFlFsOpBi1s($yr46l2{i}%s}_oYyT){?FI zM~d{>Didbj8M1B6(UsmL4I|D;j%{I{r#91-y{h0=3_ix=q;!^T3o)(1C{1W|I#=B3 z!^dwuH)Ut}U%arI#mc)~j1M=J05LQQVqxGCqw3(YIGsj>%eDopOh<=%YKvmGOd-u= z&wp1x`%!@-oib-qO~ih4cIb>hiLw~!@n&>Z!vU6IGLQ5@r zo&DFu{PW>opz%2T1yMuQ2kRMBQI4uVcCmLYQg(L)sM>a=#(f4s+I#rC2Na?8R0_7PT%Tm+rjqO`TgezZgR{nl#7aZiOC6oZs zu^Fz9qa6`x_rahAUA!NTVZP(Q6Qk^rZSrgOD_#b+M>f4>4 z+SW2lGYy~!u?AbKcypRVc`VL~A&VfQNI0sq*chjQ$~?9Fsy(ZXRU1)rHvvvg_W8OL z=1D291Z$`)B>t2qY9r9A?M6PwTHP_P$T_qI-cDPgN>#^1)&iQ%p8rBfNFyW?s7xU# zLpJ4QtUdW|HJYv9>vrZ`=-EyAtolm0TF9d(d@Is^7`!`d$2N?y^ZnQ(svfBGcd{&tjO&UW}{9JJon5WeM@eYJ=;+ z;OnYG);RO8m=b4!|8r#c73G()r4J+^j1y(j)`N5AvL&YxYiY({LfjAb&=mp#``j_a zBtvUi%1oiaTO8BVv~~XSpFI1DgNtG!ML7z|P=?4m05A2eF2l^4&jDnxz&T zd=;;++=#nL&g5f$y}F=p^lz240=xd!ofNT3rZw?za4ABxq74lJ{jm@JKoLK_i;8RU zE>4!G7+>?`lNY*@u=>hU{?4;hS07ZNjZb~yr?la0wxCf^mPr};b}sBqR^If(EXd>t zL1y|YPO=1T95{RYx$lK|_uXz&2X`Spy>Za&xvqh+sD1^0^T;P>#s{+{fA1V9sKjj|AX2FOs$#nd0s0whdB2jX1 z{o*;cJ9^*ZXCpKXXQ?rP z9$0C$Tt=RRPEuId-(|5W6!~UGyFr_N^fYKLblPYszcMFFcYN}zPyV;1roLjsixWs*e;N{|~()}5+rXA5956`I{Qb^>l%#!VZ*3_dy z844C*ejW58j@Q*-vGzaRGvp4a!3g=c{QhTugY{LlbxRDYC=8IYo|F{%AJ2NpLW8wFg30{) z3bDLAA0lJHAf_8+oe0u3?kNr$L;furQL8eE{#XLqCmv^I~xO@z_O)CdTFZ^Ah-CpRY2D!6RK}Y*6wxWqc}1iiYib`Dq^$FP60QJi-(S# z3wsh)l%*8$E=^RGc%C(IR3q1An(Dub;e5}Q)3@CCOOi{ml(QIih|HINpB+&zaq4-a$Ub_mRdD8Pa>$W2<{>l{c*}2X$SAHls5+8J^n-~3c>65=Qrx^Rj@br=z-O22VlmsZV?!HS8twAx z&Zn=$tg$B=7mV8|X7Q*J91)4u&43Hb7~TbUIEpLaRm z4}u?K&fooc)+k$R%*yL2Ys^;#)`x-of`L;XB7J@3(2zC%SvLt|E+1|hh_npP)x+A# zRf`>6%rHNW%6pLDPi~gqjD8XPU_f7NW8s9gqhM*=5;G>o7awls*CUPzY4FR|2(Erz zLU9#usonV)TU{Mf4^hxJz3CDB;r^9?%{x}l#GtD_0d@XI2Ba+2f1eC-MFml3R4m;u zNP|quw#9~irWXsbo7(l3UB<}PwzaoK2autl54>(6I7fwLA>%nRmXAHO`Jk%EKF1mu z6Ym6#Yy-2+z0Lraj1gh}plud7c1^0mY^sOng)W_}T9KuoP-e?cnUl}V1h(o8Y1q8# zk0#1St|Qw!SY*R18s@DmAihc-mRzYgYfs0Po^qp}B0OGcTt^i4mTj&GB=>{PS%GUS ziXA=$Bv1m3?)EqUa)}~(frb#ew+`=7)YDO=t%}0la+*NUA`(Y;POXJRrE=&$bb_WD z?Z8!!>04onL=jM%0ZF=bRm#EYjB$^^TzV43qiK(^ybw#&Jug~2tyA{>YHRl`pg#xbbWnDTciPn60SYgfBqIR z*&p2uQWohiTdE~(R7w)N>Wjb?b)_zKhtu+IM4-vg;#8Zg!gvjXWtl=9NM9E}znC{y zfvQZtft)d|L+GHcUS>fmAY;?2xHo{i-zvziF0%*4VHgh&A86=HjUWAx__q4Vh;a(5 zL4H3|&T%flJB8IWHZpy=iz`Z~MeO^{zGIPPkwOWc^?75pR9f*T5wp;TtiAd-4@e2% zC+@*2fh1W8S0dNB@@QIR*3 zYNcx(!n`ckVQe0o;Y9Dbz%v$F0D8LamYh7Pk5T7p_2ZE*gQP~n52jBmhPxq=>bGlO z>w~1wTB%pxCIGp~GB+k~$Q~|Ub+?)oAhNq(*bF;rxJHzBs6UQbB%~OPWDW`6c*Tyf zop8GSzH1nRKt6V#=lqenG@FyByc>G)?6S#P4BVb=DG^UNgd)~BBu+I0CUgqWp{_#^ zG3cxtQ*5J+s)5KJd_h<@e}XiQ$3e)q+K*~PbTA}dh-_5W!BM4BGl8IAw@ zUJGplszL#;Mmd|;3;XKA?bNfId9CofvQp1>&i%H>i|usxt|ruQr7h;-)#Z@6Z7p=B4^GBA0!L_Uk zxO*Bbyh7QODHum@W7RD<3R1>2YR6KC=&Q)e`?&kXm;o#ebL}?S@AX877$JB{GnXJi zk^wjTV-~<01Dz`c^|iMNI}5KJ+V>a_A}T_c>^$oKS zOUpCgeMCz>0iS>LSf-&cs5h@7Ad}nH2?RoR@wC&MK5d2zil`rs*_rwFp-`Y(7vbWf zZdOR8m}QWf5m4(R*hrG=JdY^wKrr;E(?7Q^TVe+;eZZ5QCVS1+_%#%f8Z zm^?CzdH029b~dDV%7PEDokoUDuM_qL54v&Fa@yf5dMlo;GT~KTd~uo`A5-<`W@~Pb66rzErEJBlW+7 zC$VRS6X(FuJuUPqKz_Bd^sl|LCv45+6pc8;+h8T0VoQX&ehQlIii(bW;~i8zQ;khQ zvOt~V$bg(m)-NC(d*Ef1#dfRhYHjypuoOQ4Ov z0q(D9#EPZQiI2k*b>_%SOvTs19uFzD)CS+rCM1o?)JK392a1SIDGK`til&mG1}MEl z0YQN_vq?4%BHG3ZKOhUvkpf31|0)%1*%pHGn9XI@(1+KWQz)bQs7auSo~YPaRw54z z=EPr>Ubqi8N|d0~JH$g=b0Iwa`$FEP*hN3AKBhhS(`9d?iN=QEJ08`4|j zqgWFoIZN}uY%go1&y|cS)Q-(W?0^Dx3c!Z%ZX9D^C5WA3!MPtiug?H9j*QGRB%h^Q z^W387LWG+ASJlgZboXAuksu32_M@ z36KCj5Kn6=`b?qOq|<)moF!!zG6aR?&cDtYrOF;JT%lS?KK49}S=X!~YpPN8TC3Mw zX>4%JSVm;FJr6v&KQ(sPz;;61O$5P_&DD03JH|g#rL*+)i`N>4yLl>Y7X6i>8Vodh zxQd~)Qz8lP!EYw&+mF-1*OeLuDAZ^uIcRsSPb+5PQ;7OoV+9WqM7kqEHYCYaL*Db& zdu0uTaeN@IMgLuP+~ABoT(v|W@@w;BbWQo6Q@>`Brc*Ay1Re#BkcegqPF|ilY$w*% zpQDJxFH?V(<9INTJU=sDPU&PWf^NUby@eEMq*yK9b>BtR%h{Hw`jr+I;LEw*Zye&{ zy#=+^%zhB7|FW?(geqS3hgC;pwl+6)(&l5-u_q6rc$zd*B+^6jLDrPF*RwynKZz+U4Qj_FG$*l@=Dg@(B^TsF#DZ(COE}83EAB4_U=~ zUYgQ3t5%y)Kw^LHDprYK&wCpd^{ZkPzwu8LzHLQTwZ%T%PU@uL2YP54I8vCen0`EF zdD3*YeUzX{?Eclb_+kaYBk^uVFGKfi>r9`-e(oMgZuWP_^kIivvWS^VK9RlIaSIy( zbF-j%eM_{^JFLxOsQ(on#LShD!e^{62HhVk!Hb(zI?CjSufi_CEsZLpj0fmvDdD!v z-kU_bG|6FL%S9|bd zRV(j6Vx}Y4I&49|zO2lnqWg-zaB0s$@_5>27-Vne)D7=3{KlYVv)jpSy=W4 z(ksQBy4hXRF4?J$cpylk#ydnGCWYz`i$F*HUNWi_B|amsC`t`w$6g}`dszDb#u;^A z%+%%s1w#schyRqjhz5sD@rlNL#OA-M3XKJGV}&H{cK}I{>3xH#4Z~-gRA#vB{e>(! z&UV#?d*_95g3QUUF3Djbc-T@m!@i zP2Qa(jF6qsLSg^-%f{y#c+9+bOQqofFq3z>z_pBjHoqm*16kS`x4&@lToSYkzk;4=s$* z)X8R#vsz2G!_MQj-aGgcxB9md*nHyu&3N$2S(h~U#$Jwuss9IpwpPs(`u$rW9{LcG zQRoaC`A@BsU3v)^8o%MVN@uHBjUsbLBz~JyXIS`1;gSec2e|{LN-I+an-LPVI+yz& zM#axuKGeOEg9X+nqNGEDe3+Y_F{So=BDLVrq*4Pt1Q__*m9!_A1Vv$7bUw9}ru;Gb zQnr+)OU@^gP+qr-%S-T{^B+lgOpG00?G zR`vtqcX{0i!_aGm`9^*fUeMHHE>abu)u7R2rd z_)s}EOId^7z3A(Fo&2?unF<;|yC$G)07^ykYKrF#Ca@4IP$@C`NZIAs-XHp-xV9ee z2NQVtpcxU-V5y0nRwH1q%lpCZr`;5L=ufC|@zzXVLpcf^7=Rw26$WdVo}2Pc!}}8(F8Yhr^C@%zkUoH|kR93_ z*873eX{$e$jg5cBec~_fgfEp*i4H!BaAL1mM&JhlEL0S)@}r}{dR2LJ&Qq6+6cE^s z*wB^u%U4a-||- z_ppOVRxJ}FUc?a;e#$(}KRA)p4*|j6;C{cz@n!_Dp`5=aTzo27YnH$k3JMvaDh~vnY)qrS&>volFbBr95^$(MgFUbtxbfw_-`b%L8G^xd9 z+7T_Fb(i&3j3WtS*X6QiLog2tb#n0e6{{mn&XPpc6=8$ABx`rk4lL4xuK)2{QB{$l zosSz49qj-)-7%C}Mn#npf$17fBL_M^h^9y7mUaVA6m&t2(Ai1Ja>?G=?)6lNSm!Id ze&dov!6VtGdJW50cCWJf-%B@czS$4@onk&-&Cyi;Q1`g_f(luxwLE4@}+tSH*eF>iX32mb+O7eXA+xO&36@B8Dy}D z)y)rhxh}(1RbW50e}n&07wh}sU`0LrO)EHMecu2$HBC!#s6HNR4V&Pu2qhwRqW&S# z`u_ZR0ltyz+E9oUsk-Rt^5SAQii<=+I}ya@BntYS6|krw3-qN%GsB9k0T;`V9TIV7 zau{heGf2Db%G9)nZq563b3{erD?pdL2VkkTR-z@6nGmXRC?p?0Q19mF9uCuHM;L@P zr+S_qG|H&G>_rSDt5*C*Z64wv=oHjo0Hncu2QsjB)8f?A8Yp|U>?$nra&Wb;filoT zjRpqNG22=Gx=g`BD#CSQs;nvEB8c7btoqY!_pgqC(Jyu=g;_+H&$mN71Zzl_o2`Ch z9hp0cK8soV*)Cnlv`blBeS}gCO4a6bDA*B-LhXlA=i*b3M~heWQF=>}OqRG09#!G% zngQ$Cc)$~lny0Id7n*4u)8H)w?2&i~UB2BWqnj&BR-zFdcVL_5)C+9}Pq7sFL32B6 zn({4M+M4PE6cHo6myG^A3dMut;@WH4v)*_Hh^nH%=pnx;8cKZUsTb3c0u~}kIWWdv zCRwrmk*E8S&$IJ{a>?2oSD`p8z$Cm2xAWECjqQ@8Eya$%oz`g-v}DCFzH+L-vV*;G zJbp`6n>}m@i=#M)y*!h}5(P~p&Il{jgYzr(oT`@!6LB<@)JLUOktW!7JEZi+1fx6R zybm|$2upHOkdz6EBBw=oUCRO*gh0-`WjYaxuw4T(0KtvL#B%OaN1ST-oIm z-(c_vT@#98yQvZ+L}&0Up995OLPK0}KqcHpbA2eP3&k%?`0kRS^EE#Mpvt{B^nD-v zeU2)kOwo9OeB&4Kz~LD7IzrXN?~Y%)zt~ENa}}Y~P$(n`OyFbw12e$)gvm^P+1^}9)yGBLrcLE%hy7)B_6PmdDJmM&peN}$3>6b05VcO!+24wV zE}q0+Bc5T7D3Mkc(-Oror>w((n|_}P3B_IgQsbyfw2Pq2tXWaW<)Ue)oAqImq4R(v z0N-M;w+}=%yPBe3c>0=LfrOKL^=6e0)#}bKE(ZC}Qd29uA%7WAw_EcpT$N|}>zR&u zg8Z}@)W(u>50L|=WUP>^FYcWw?RXb=&jotQWGvx^iSZYZ4pcjLI+0C5W6KG+OrXtySB5{1MnmKC#= z6mYqVTX_+&$ndJ6tc%k3UP7)TFSYg&-wxdERBpKtImz1Z^-WBa6~V_9QRO!pu+FF@ z@XHJJSI-;l!ww`Df`_bUTXrKwrQ!}!GvI8;O3900;*r#pxO&~eD4RQGMEsy&gCk8{9Yt0=!7VNz6@0nK z(*C!xeNLVTQv0%tF0Vvjt_~F)FoeR&dAGM!gN}wgE~Li(VZFbs@~!zG7;Q_{qA@x&_PXsKbU5%CcghhXws&Sc*I~8PuU_??BI^ zTmwB<){I?XKoN+g4A8yh^qO$6I5M8|=I~YjmT;0Zmm*fpS`LZ$$B(F)n#{uJNTKsz zYK`#0_=v-yanBS5ElOoIebmHC4X8ORY}$=}AiokZ1lm4yMl}$quVz_`zm>`bq|0JW zKjGC;r5ZHd#V-U#tQR~|_v+RH+Lp-XR+qe4g$yYrRFf!J6wD|qt^*z%l5&yzi+Xl? zX^zhs)yZ7M%aZpbZ!6le_a&qUtb8m3>QB zxPy^jQqdHJ1wILeW5$nNm(0z(HRFL%Ly3*nR}TcQeAcL;M7h~D2=2HM1|#urMP!QP z=%~_*RN*sfu*r?6e#%!hqiUmj=F2ATBeZi;#`b`&ydVQ@H-9rDjHK=V7zjjU~+w zGS3<4K`n!jFJVHKho0LEP3f{#hyjNrgCnCppskqSog5T+TQ0Y?J%&n@Krj;@R~pprF4~ks!t5^tQ-PKI^qgY zIC_i4$@2)&oYJ-M?~@b_Cd&HzZSuc5SQz1vl(1iHgs#$3j9r>sTTHP5e=al+LHIJ7 zORysNicuCs(m6o;=PZ2^C7$oQjQ%`lte+an4%Jsd`f`Nhp)@`;ql#eMrW!cQA%$94 zbfb__W0yI^$KOe8SPN^>lK!QcBRfS+goWjhLou3}#I1(s&3=Bg9C@^QSetZqar$!R zd#C78nZ4?J{p&d>-p@>((|dvehX@?I*h=jvtq6V^J^{u<5}nkGTc*fA3W+r__bWV* zIk_y3*Lp`w*pksBn8xoqBD1)HaXMeZY;A43WJjcNJsC1ervo}PbY0Z2&K&d4jou!a zHkJcE;TilmZp-)6b4AH>kY~YkC2rpqGBB_wCx18!tfmi2eF{R?Ne;RIjPPY5$U`O6 zGnu`ly8rp{{4+Me@zAERGR<(>K;{}RJ3@+S8Uh?Xk))Sdi@$gGm78PF_!7fhq`z%Ay_rc(wvndDyw;k zsmW6ZvD6H2YKlF(;sMOjkA`4KTAQpKt6(==;t7u9kd1XDlZHiOd00`dvE8h7FC4pv9fqVbrx_{PFNycRnxaPv zIA0@T8Zf`)J5{?a@b5wuOcauUF@@c&d7pB*$tl-N++;v=!P-%xs`8rT4`Wv+^aN0} z0S$e*2|__bsGM*<2mef)BTS8yd^Q#AN*$O#Q&cD9AtseG`|1TQDSZgDEPH;*EV6UV zPk)Y=!u=bCm`@7bG>X40>Vib_swQcF{ZY^VWOSf2^Zmfa>33SB<d~ zCdXrr(dBZ*Q5-`#{2hWPN7k*v(;M@66{}*RS`d`rV$;EE#&|oTuGzwMC|_HIOAm=b z@_c_4C8B}naUeKQ!REK!gq+4_qv0M&)F4YxtdPtC$CB$*JD`q7A~@_*kD>59q_s ztzQ?IMDso@gQVdCA-G&SCkR;BsQ|h1YQJ3q_ZB4Wm#0QeIZ3*7RY5PRdCu<39|=0g z$GUasA|Xe>6T$D&rFADlX7Uaj;JnZ>9(H^5+Z_T5Jhfv=OIfp?GX}@bLCn6&QppJ} zStk3PpEQ(b-1Z2Dm{m5(% zwty%bd}!fewaW@*BWUWOHQ1yjag|wlb>2*vy_>O?iKpnQ-_IannFPAmspM}^rhFo- zfz9hg+TPR}jZ+GIvs=QVCJso*ofal2`$8eOeO4C#wwX*h`aHv@-!kD011&6?y0+?l z>o6j5i9<*23`g+cduKkKC zEqZu{!c9cEp(a$d_<#2zmE?+#29C>x^Pck@9NlyxH?=Ybn~Sh><*eiqerCR^F~Cy{ zuELW%-&&t5Th}I3+1QvpZpvFN#arwr0-e#)AVLDjle`ES({~~DcdbL)n0zi;Nb|#G z=@u7ku2yfLA_X97Y}>0cFLiNYPHX`6R{iNvFYk<<)@&A#y$ijhkb_#!CPK}p#6p_?L*$1&oE>~8>CfHhh0JYS@jzymya86`TnvioQyz=C zccTv}+Q+mua;|hbg`vR5bNXoOBXwX+cX}ZmatxgR+|5>!zn^;>$=^ZTQWxZ4&`-?(=}0;T?@SoD2^jSJ0QM`o;k`$;MI`z6=wqVtMMgDrTbKc;)D{dYsv$p6PbekXNdxWrqBbW zymN;xjNe#kHV}3i#!8AO9t-{d#$$r~jSrld2dvIjX)P2I2TG!q&kLjQb);As%p8L@ z|1RiOPzS^_o}zEFg8;*0YtAwrHqTJ=YbeNtEJC!JX?y3zc4U5xGN;K*gR{7?pxU&IWb1(OAd7cK&zI`)l~hp4nu7Q0w%Js9}(~tSdp0C zX1sEiX~hpJ`z4-4qAOpbihqn5QJ{}$x)m`~eEZ6V?sW$0tK2YPPF)@H3UpxR1e3zz#*nW}ses=wP$7)}SHVs(ctsQV!EO7&|tN8)w2O zZxwL!~zRM`KnuC#CihBvO$7RqK_%R5H6h z3vW8_^hC6!<`QNpl%G276|IW6R!k}v5p-@zc)9|!#0jfp?k%HzFE9g%x{w1Jj_iqP zgoXLx@oPi{7Y7m%ur9b_SD+4b1}AY+!=5fqug-$vVtI3Xy+7FF-LB%6I+ZZP& zWhB{RxxOY;%e>3wuP0|AF6dT9!}XI8V}58BH&%jxh2^{3MPP4=)CC)A^9^Bw#?rft zH&}tuERmu3U_9DFO6J2lZdrBI{K(dsk$Q^#;(n`f{(O*5lNS^|ta*Le4T<%Lm1XRw zh$S5auvmh$sF_H!29wt4@_gC@E^9fFDcacT8bD-TX^vOgQ(E&B-A(1m?4?h~>wWr? zYXKy2=zeI|Icjv2MlDLI@Ytxkx+;32K^<&8JVlr2h@%3JBnwHBs{nJn=eZ<}@rO-~ zi7z(H8+>Ubc-2J4BededGAx(}#l1LGFrXrv;)-S6CMPJV7p4rFsDCpHluI7r+XX73 zNwxk%Fe>B3+{QHzd=2-)s1|U-v|(@`?i2ZmDjC=UteG{TSj~)2Lsu-!!hpNhzU)GP zSZz?IPsd>AH^vc>IPRIC)YM~o1&}(e;I%k2zRAfmjr6=C^yb8rTh8E@2|wP^Cn`yw zV^lH;`m~~&B(7t3rCnlnr!K`tTQK+IEG($@@mi&dQr8gS({*l4WH=-!GO8AYAJsy8 z{w>OQqKxxY)w*%PM2T$+iV$3m4MSunH(Ih^Y*(0$_RX3H241(%F)^X|E9k+Yt0_@I zjRCG)L9)yoYcG7);E*F{P$~~9nOD;WAq=%P#ps;8a|GJTu47?a|H zo}z8M2zBC#!TlBS_E45{%#5{oa}^EsK~5Jt6%F3?LzU>GU}$T3@xPz8U4nx^S@YFn ze5bpPq#MR5K!v=-c88vgwBhkvvRO}#Rw$$T1H8(MLY#z@w)pBGH!n1#p+b9icL|Rm zCVi`R{pO|%ciu>cgIIHbGZ}kgGT_p-imhHtJl8U`x&-4gX-jZ3^ z0cuHa14e|gRrd?Yhoj`f@aP?#u5XXX1~dI@}XeSz2+%g3ao6dhs2jUMJ7WH&3-mcvp$o_#nSK zw;#E3V8(XFrQ~$fc+`TbG`eOjr$0j2dqs;wBB^_dc37SVo{v&v>wQnB3@D%TNX?w&5NU8 z_oJe3=7E6}7UI%>6d7tA&5TENSAHErS9seXOo3zUq0XZ#*T(6l&Z+ci)0r}3S2xZqykffPYI$51JUj5601e+NU5Gm*E3&iN2+`(?adwol zmyvb+Np;9aiN5x^_!b4e#E!t!xyURCXj=-y7c{;*gmJHSovGrj(~Ve!Zm;>Mh{5*O zW~(J2nq*_RFgai*nJY6m+eBimvr}8X^*yH9LdOn{XMb4ZF8duIuxC7vyN$3pHy*jQ z8*Pn*|A2!k-)XQF@gT~r`#^4D@>auh=%+8sjg^vO+{Z3)D;Et3k_)N@Ey2#XkkYy* z{l(+wqe}ZCc`IR&jd?C*8gc;-q2V%~C`8_>>EHU5nYq6Htvg0=AlXdn z6ZwUWsM8>&*B0Dcps-yiuG>qqja|Wb+@#*!M?$dQ?2M+9NF|X~GL%{7ah*W#R8aja zbFaYqt9oS9n8m%)WiF+jK}9T&L)fq`1`|=zhes`m7Y5JOEZ3~5WCi& z%GgB}v7h}}SwI&8fTl0Ik(?_Ltnbn()By5DNxnlANGM7}Z|l#cL4K03v8fw~PIt@s z_6P_UW8X(&65@aDA0DfZV0#9U*4DUYG8;~?3SO5xZNZIK<#(feO8o;!+x%5hL{KcB zRm3{GihK<{^{_-y{Jc~$q$WbnkaNXOW0DEkzja@)Fjv)DvOd$GVcEu_WesXF>i(}c zfo;qDCH51Xg1XkO-E$E1Q){FzO@>i_MC49U10*kIdQEGkrG%vfHP`+VoX)8_CHp9z z-p3R^3E75zrC`D#BL?_1ikoKN5w1o9{1AlN6ZbtK3> zB%Kgs>m<^cMQn_n%-7V+l|}Shy!Q|N(qt{oz4$Udjh+Rf$ABfZ_pK$3mr#}FWOh`F zromYEiLXNW_+rlqLgNP+BOMx%?kZ*w+GRLIujA7G5(gU1c24G*biJ9v2S{>#KfmI! z2Oj>-sqFT##rVm9ENGZof-8PMRb(7nvVPoj>aGu9a5_2zY<=QYs}$$do4z=r*fZ6h zLj(`(lhs~5pO+kgW+d=!?yj~ikZ3bOF!od}UIQR*l*VfY7iOz*vNwUlzInBO#2JBA7d}165Q;;i=2gs9n7VnQ@*>H)t`LE zfFyf{d#NH6!>(kY(-g9{N0h}V)C`kF-|EjF7Pv`}VpukuI1Iu?a?Fefb3N2xt+ctN z4oo+kEmCMN3%xNqr^Wuu`Pf4=Nsbb$I7oAeed#N(4`7r@{?4Mk<7Y1*md1~K6_T*+>mv$i%vKA|&}4kIbk zZ|DD2o7q;aH?vBzuR6au=JQ^rJIQ(yub2b)Vi*MIN$^d>DWK@T4*l^J~Ga+`Ti#TQ`~3nY1*CWFg#W;FDpZ zZVIugadrlv{?+d$@^BWA|D|Kiuf}#5>9@dH^CF(!nVA|atUwoL6dC=a!zhQV35Kz|WFMXa>*0q16= zbG^8w_*ec#Dr~aEnMtMYr05qr%b-89!G7L5Pw^1xY&^4vG&OHq06Vt>5p;GWVPaS# z`kG{E3oSgvSs`>oPz>);Z8qP%As1dU0LMBK%P+?2x4aGJ4KUHdVI+__vpSnSSGw1S zaMMQZ5h`SD1K_)guSd%~DmM(ZNVt`g1f{N7HIZG+#`9*_QD$vCsh(I?5 zDrkOO-?&nCe%BTU9PM#BVp~`6_Aws$v$ZYntTog zXWkBGkvMi2(OoedWt>6kJi0>gDRu$MfGh(!rTPqUhA)rKFmCPE4pIfcizI*OEcz_C z`?W$DBgE!RN-5S+N(Cn|$qypC33rHK5lc`+@qYrk?TJ2O%+L z3uB#KE*-SvY8^cK#9YP07bfsXjQ?Q+f zAajv%fz6_KUVhCh(+zrqCWmSU?u2^A)qHSc;Zv|alQ~ZK;Gfw)Q-|v+HYDo;jNz-S zWKY@w+S9Ed9_3mkTR&d`O{3cxv#GFuxO15jO2TlWKgOW`4MY z@v(KrWP~Pc%2GN#s^HABw?WaEzL65&b{`-5d?4NUR!7BHN;Lpn4X&8Cw@p~270kzq zvrEDuOi%#Bn+A#Ud4wHvoN|JXQVjp0GV1dV3)V3ONkXca4FTGTujA4pHcFl8}5$BOP1nc8evp|3}g8+pH)|$(1G@-`i$dEYs#)5DVEX--P$fxCZ zFve2aeRG;|n0I!YzQ9@7vw}gG0rV=J);&EU!yGgimcu8Mxn($Tuj++0*U%@SXH^E$ z=v~TrP4V$f)dxaxX%TiL5T|bkaBpM%rR+7LEtO(K+02l-mMa4n47D(jU&Fm}Dnd^7KS1Sb zcvlN{ta_x=v<=~mm>cupusHxs9RxA4-U|%RXX`_#f}RHk*t;wd2AF=k2_u4Ud$rNj zz2u%vJ@XYmRf&e!h=1nt*=Dv&;nDZU>>|DpFOs7qFY37&>9nMku&UxmD2wj+kOO>$ ztBr=~9ea~kgZBwx@f(77*kIJr7qy-jJWy}o({vz!*4bH!YxV9_YVuo1r>#orhzXw{ zY+syqS!^AR$4$qdDcfEr=3ts+ z@#oz_QfpM6o~b)J%9t0kAYH;BJa&x-wul>fm~TP+Z!osyswtKq!b;01-I<6^DGJgV(7*4Zl=eO#NTOhC=;nN*QH2KQk(wj7-r!v!HGvSAAfPe zA^Fx~Gf|4IpH%{PpP)}SX^9d)wDm#W^kJ)F^~*JkS4C?;9iDnx3>S>|h4so+Al&{oa` z47@8<1s7ie6ZmUq`*~smATU!xzQQnAQtiWrImIqtm*0jLdvdic+4B(h8M|Fu2fkUq za=V78{|h*C*@)VESa^E86`a%N@xsBt8(YGBe-?W^5`zjdD<6xaF5%?L0{=570fDwW z4CAdYmx?yp`OVD~?v1)@_~yT(sZ%fNY&X3>5gRQ7Ep}D(lz!A%&;aVkoK}l*WYayj zWg}QI3|-MF^6`8I2oAE@dM#S6qDn5j%>^Hxq9=Mv@sqowC@)`t*X#MKW_sNRc0Pe? zeuib8`9-gu9+a;m*tp@gm)6+r;E6orcpN7L)mjmWFq^oC3N=QZj1yOT{^G0UqzhZZ?oVJf0m@4+V ziAXGMkm0WC>_5Uh8YrInpto5so7`1zM*~t<44A;_nVy49KaX1VN1~cw+jDy?Mp+cN zG|-Ql3{s$cNd3I^P}wsu{^Px0aah3`<-U=!HC3Gw$u_PMmI%`dj7DZLf^3mT8-47q z@x4c5zMnp~B*vm(SV8K)#ZSP#G3cXy`@SPK^dUnaX`fgj&PpMr>BHg7fGEspjv^VY!1b>4gRS;C_;o?1Sreh0&<_e zF2_hi=7RtJ{Q?F4M#!bVT8iN$EI_0fO=Ri`Hx#fCDx-~o1-CZ;mM7c9e_wuoq@$aEu()-qg3w=Tr(^>5kIgX2_RS9K0FxSJnfC{*q$h&N@-J^; ze3=yyReE2PvoLCJegVsxRkwQxhV>z3mTb7GuPnEK6g9abbK5r%<`9-xDanAgn`tVel_PnzsZ%=)tJ+9OeQ$ z|M>-th_c$Ci?Ek*3ne+;Dx3bNiZ_*DMuqJIY(P4+_A8({)Z9D}(EZ$HEPVe59kea> zMp3h^_I_D||E-2SE6q`wD9WfjAy9!Y}qm@Xk z{Uxy!iQSG9QbC*jzK8(Q5lH>q7pKgF^*r+|$Z5XV4+a04`{XA0& zX%SQGtamknb-ar3)9=g6-8QvL$`>C*$tV}I2%$1V3mzD#ZOot$%3K37l(MwFeRDSl z-4Gn|u-eE8JaC{vC(}|Fx)}TdChq$SROs~(+l|6r|DkDMu=~q+|?i^;< z#9uW?9Xr^SMwKKLC^Pu><1a>nwzoHfy}tt#{k-8_{aNrpSl)m^x)$gIbRj6}An0mo zd_0X1UxF1NSR8+*-Bn$UQ^1>}4d1Kn1>9RgvATuQ8T3i41swzo3KG3>~(m}k|66Mn=~GMHZOF{`s3&BbbkJc42?0N5Z@!=I$;&fBGcv3+ZA`y zRIdAFV>c{{A!lQPQSh8KJO%Yj!+)yFlh;#fTaSP5zBs;c3i=aAMlxBw4^aQMew!r9 zc~jqTxCX9F(35~4SKq%wQ9#Qc$$9VU<%vJUVv0Ro zCv@0y4OAAg2D z3Us|1xI#jWlrn|C1I-ha^yC~K2v6)gJ#C?a7zgEs%;R3LRFky6zq!WrnFj5cg8Xbi zM|xAe|E7aK!QNkP4V!*Ab|+P2f)9nt^WH@Q{;YGrAk-^E%&&LPsFP={*1Xuh6R46) zwctQ_)KScR6D;LYt%rU98F{U# zK(F>;`gt$00fapPdJlyLhz*CE9s=lz_jmP<0@Vz5%xzcPDq2|bYALCUaOj`l6E&H4 zwVNlQ&jFDllt0&3KU-?aC50c)j@}+d|IwgApse2gBN*OpaRmN}{lJ1An=e({+o<{R zE2|-*PmIFU**A#W`a2yTt<O0>AISjbmhwiU%j_@iEz3a-alps8443OoSWChCP%=c zq7lsqsDhb1F`3RKRDH{~e+FURCmyDjFy;s_$S_FQph_H5Vfxnn4z+{|CnF>6D;>N` zlt;FcM_;oUc4l?aDBlHjVCs9@iAtwjQJM9VZ&HZ5S~ap<$}dfIV-TKS03PFNCHflB zbN|}Cbwv6nz>mNEH@nlzJz9>C$C#|%I%@NAH<^U=KPRut8?eK>l@?xq@p5ta;``$1b;$2<_uIpD((X_d5 zQzeb^ZKF4kK1LNF&f10XV1;O&CadVvz|0A1pF-*-;Q1_k>FVz#Ff?#?dfgB(FOZsc zb1~YSf~nAn&h;F`nO4dfbopV#W=?*$z74yGf>kU+QJ=eOF*rzl`U2ish#bOrVOrf! zl5HZ=*BIvS6&^n_S*znY{t2`a`$W&GlNt(bjw<~PAEqK7TSv_FcToZ-Jf;SL;vDR3 zJfQ~e2|n?ZU;#xe)UzX zpQna)76c$A-F4jb+GbAGTwLDoG#uniX=6DDq=Ms3p-@Lg-&c}OFCS!46Ob1>dX9hH z`{!Ga3C^*?W5|{smub&>sPocQ=A*^sceKR5PX8IcO{gwh#$iWC==KARzjwz0OcUWQ zim@iD^jO#?a_LY+yg4434FWsAFA^(*`^v10w9)Q`KXFlYa7(@!-Xd2t7x!XpU*2Ke zQm=Ej#)FaUv-cjN_bkPkbX`uU4?rLyssG*)pi6_L54wV($a7~o$e}@%@?MY5_1$6oz_%FK$Btttvxw8Gw;HjEclRtAmNV;4b3M%Yp6E!dmio%>a|I< zUxcdvgS3!*U!Me%OeZn;v6KLc=LwahJpY)&0#PVm6;6;qB)oGw?LAEj(^JyFnjEii zs@}6i531v9hk)~Tkb28ymhj=`?rdZluY+5TkWYn78G}57xvzn{D8w)SX6r8ssi$Pu z!n7blCQgKBqlyPd0ZTE`W=JX{W{W2U$Z_irHUZH%mJF7FHR64k?|z3|c&-vV!`wjq zTahxtZI$sm38sH?0A<|$fIyuQMMG9+;S|#qjL1};TlF*pSrk60OB_-6zx%Da*+ssH z_*yHFix|8y;x^`9{LIq8I2y`!umq-`ZlhmPa0+${U>!MpH9@FZySIpO~EV|ES28&xr`{h7Ta z!lKg|kKNTMC=B!WRDlIr80Lhan{zbEQ37eB=yE@qCqmET`4@FuxG1GLu9C?92rw@WHgTX3U{0lrvwjk1XNFHQmV%)c(kS~TO3;9WSN(Z-3V>wphp;S z%)s=GOvGx`4&IaoLe$q+L;3>lLt%Z2waE`JU`(t-{kC_^Q9H*G-XVz_$k-b=p7i!5 zW>Cx!7Sxy{IPrch9PukZk+m_%vqOXrTeIcPk3?8$rU#Gau?Gr-WsF5VQVT>M{`VvL zoLzMMkl*(k88JBl?;p_vXNPgrgoEL}Kn+qL54;k-GD1J5_)N46s>ta6JNIFoleyY* ztu^6pO=$b>cIdp_2E+KKzHJzI&!(iy4NU@`L{xo0c4tw*VKY%L>`R^7pk?`tSS-LH z(EhuceBoyShvm1@8zYincq$vrAUdRiMfv6Yf<;7DELRv}2dB-3WClhQBG6h`?Y|=R zI~HpVGJP~uB{Cx32r>=Bv*A~j&l0icAf->-VaxBgx4L{IjSLH|Bgkdl+dJ&Dpveg3 zFTdJs3UsH*^av>s)=GX#_|p;<;|6?+UtU8jIdI!XpmdX_2o#dPbz$n)IkI>=XN&U8 zRb7!7;_7_q%5Ze&m8uQnHCHbfx!81ykD8EIN=kEP!K;k4>;Cz)d&a2L&XS1c6a+C5 zl%A&KsmnZaV_$e!`&pyXd!c=lh{lB(8Ar$F@07E*Z9*C*CqiO8Ny!SHq@3fy(@KwQ zqi6W3s%zH~XL)>a(qEWo6UGj^n%HdPD3KRD{>~iw{PRgJ}lZX+_bVwjfxf4oAIv zG|zj_*>lg?vs;L~J3KhNkUPd(Wa!QM?hLy1@|pJ@dfCffa;%nS;iTd=oZvP8huUT=V^plLX`u?j0CpPPP81Tg+T*CJsmffv0<2B8meI6tr@F=djP zyX(HQt-J?Y5k_`9@_;br*Oe)MiR7%>s5k|t|TTI5jS}4R@L&jnt$>KQ5QABd* z5?!`L{@+KUeufT#R}RmL`0yYVBsRN;KBcW+7~d!=M-Zvw|1k!yr{81giOPy2Zij#z zF<|u_O-RWsGQ0ND5wdw<*_I#JX=?ZUgQj#s&x<|k$X;;P|AYFezn*YV zWF$tQKV-oXfpSE`h-T0}>rFz4V*)0KMXSrt;%f`qPj&cU(#OQ0kEE-;zafSVgXqC@ ztSD$;Gu9n>FAW+v?etNnk01}X-XvPtD0;Fv_y^~H6le5A5Nv0&Nbn~?T=HO8%7U^B z4e0uCs2cnR1f@^-cL`R?)jgKBaAvlse+XL)M~{FIs9t~ho2S< zaDE|#7J~qyp0pXtHHg^GbrpJvzVV~wC9IW50tUyxt1*~daXzNRcxetgCr;nvha~C9 zp`ZW;BYvYE+^M1H>pnt{`q(IxYr4Cw1x?eQEG=WEDE70t_-tHkT@iTP~r-^DQ;NMkid47 z|AExP0jiY{0P=}DGDQ_9K@@_Dvd;d_#=Jt#h63uXtm!ha3Prv4jpI=`XoY;jU9uEG z#-ueLBXQ3vlm017oZ-eERk^KWl3({%p0rLRsiqHwD)46j<1;c+h%wZ$@F4%&9m!pT z9T;g`(%YKJt@A+^a+&a4$C}7bN-QrDu661K^{ZdjQ}SrV20Ed#W!mT42UIvt#UCsO z;&zb=pH?t>(IcrVTPbMtmFyDeLW{EcQKQyUnM+tE(|k9o2vy##o^*a6@ZLuxoug$F zDzfyIt$Q|!i4@}kucE1(4qOay@?vyAvya?eT>i|K!XuGPe_V6hB-Y*^#eGb#_ecAA z3h^*1Rf%V`VlB_cjTq`+wD^erNmSrS;Ce&)%Idw{=pVv zGhANNul;g|-j~Tgok}#$qfci)y3(A%qrw|)!J0zMvbupf5^+5Hlt#@`HJq%D#i+B`d$Dt%QoZvoDOW|LM`a_vR>=eMVDdktiD-TW`6@ z-JPx&@z70RJdvP2szzl;!vs#-;TZFZN@|EJ$A1qZnl5GXQQPy!pVLv1n8pcQ&J7%c zxizR-nR}wa|19w5+jkMd-*LTM^r@%u^hCUn1zHvmj-i=dQs&tSyp@bDecN?NsJa^F zBIdRoZ!ML6SyvvG50lZ;YH_;K1~%08qt5K-BpQ+!9{xXJ|7~z`W3&pEHEwf;GrY^; zBsU$UX62@wh=i{B&k7nMPqY-&UEW;Ftws|8_aptGb z22NdXLuXaADnoDl*=Sr?bOAXb7~wbILbv*rfd7)e_w(?V3=n3OY?N-{nzAHLg>@n? zb>*bwc?RZcMIj_kvXB%p(yCsC&oog7FTB5 z3(nTK)w>US8MUt@j601q|E_jADlbA_{tD>x{e8euqRJ#gwOswM2 zx{wkh55^IiG2!0R|A$JwrWn6DOG;5RV>5{m2VN#!x%!{TuLC@1z+!->H$VaREs!=Y zr=)KDIidyZUyX$r(HQ!G;CqpdFAmyfvSL>G{-pX?m>NA?dG@D`%JqNCG+HUNei28y zeaW>Sd~L-pCVuu@X9qMJEW;Mh5w$8>5w=&x_#u4A1q2Joa4vU-;H6YMw!~>Y3(OE!9^Et)KPy-iA zxaO9rVs9)`P&c5BT62I3!5lTC#;Ccd>3>Dr?&;Vf@W4ebeYKhA8uH!jG|%#Kfg{%# z*LSP;?zw{aEcc0H#Vu=DMdsb4BwcRTxuL+al*QMFRt^rfmR%m1Dd`??L-m1>xS!TS zQ@un)oMo*?)j1H2*D;qxJLz?y4hS?B9o%mUbWaeW#t91;+iQU9qGoH-b37lZ+q%_x z^aPfR7SlE@Hu3V5+Yj%1hRfzBd;hBOiX{5m3fyZwofsRMs&gb@LDVnr59eHDML=c)SyL%LYUJU*UhPm>t|=j--E@Rqpa)Vhx&Ml_@oMH{ z+qP(Owmi~t_vEN2omH8I8=8H$dH3P_S2@);PAiWN9xZW&3fr9P>uiw&XDzQu;NHeoK4V>**yqOlf zcef8qvR`w*o*A9}A+a{R_Jt&LFyz0V>$NJDM()#ao?gD}B#5II~R))i9&!jS`Woks0m(UmBp z$T@D18{OK@#totSr8WfiWYT3(^Q`x_0kY_li5@xX@($9MYDzTGeSv`8hxBME`=&U? zBs3yuvBVT#L;>&OZyA+w>5b&ZpZa|VoOgD^U2T2JZ^|O$EI*x8QR>%xt+EbPUWa3_ zrOpa0M9c{AJPF3unbgOff%5|Oes@=w=wRU~U{7fzUx>3-F^Hr2oFIWH0T7Dh)t1`o zgFBc0ia}+Qi)PhU2_|5sr)P}i903)mz&ETd(yCvKtphSENG{i<1UqcrT1rq*w(b1; zptK(D9q23x!Y7yhBn&r9>h9ys5Clnq2lb-x7}ST_n58hsD@A?B} zTkm$7G`|W|4IdBRt_JPhsM!rV6W><&PhYSsLc|tlHr%z;)nWN|M@-As@g~|6l{S*J z6So{k2oF!2SPwR4gyFj|PB7Hgaeuu3oBnbl%lZpq;gCAxcIMvE8-c z^r8ceFU+%fgRgy`uckpQPQRI)f+b+tnxRXb;Hn)t!8>bkqd&w-UU z2?gEF5dNgbn`ZM7rQC#cHbSiUr}B%!f4kptqcQ6wJVf?AE3EF)LQOJ}ZJFMm*2apj z^I8YsigCe&ACnZ!IWV*?vS|ibn3wdyLg-3rh&mEj=MWA zA=H$G=Tf0P4oPC#-4R@Fq0b6`h%fj-KjBtc3_!(*vFOZEU#cJci_lA&)9wcqVt`gy z`CVz>2}Q0Gz$y0@A&;)z_g+~$wPZHoHqY!X8M_J?61Mk?RR;jClcRSeajH?INU};6@nB_?l5b?( zX5bVqz;=N~(l2Ui^n7JNR5QFLfKIr`n`!Db5GNvusG2Lxn|6QHn}K1|&lS5eIb@YW z2ujK-PgN)AV}RgiiDe%RUFsH|>bxqJuPt^@ASw}Tuj@d4Zqr`4i}p2EW?B$DGOV^I z6Lab0VNhNEY>59diL0^Lq>L2Nvc0;tlnSPSAcWadd}aYsgwb8VBFZPc>){;y8HuA`+Y!vlsNer7b)Onvq5FujXu zm6pl$28M$u=!z$0<0V+O*Bv?-zv~KzOP;#R%)W9{bAbamRmf6Xwu60f8&&MhkF#f2 zTk(FmJo7&z%QYv3E#gL3EafO9;b+pwb4NIcNVIyj)10YwyVj$6!r|b(s7Mz6!!2o6 zdX+2IrF0x<;$4a5w`8o>thlYKbV2JYre*e0Xtgf7aq9@xKC0k&@BXQIGW}1-m?I1k zG2VJjAeDKq{$3|j*kO?Ich93%T9lMxq6XF>?e|$zaV8t}ljfnOb5OR;bP_M5 zRSerfrx$KJ(9)R5N?Ok1u`*0lS1&)8y3O%-R1mbeLwIz~K{rjD^P>L@>ZBKbV$&m< z=o9kiQ-7Ssv0eK0ffdpfkc~LGB>6KzsuYqukyVXR(e^r5tR!%?0p))0S><%5)%&@Y zt^fYj^}XR)CN~mOT$c2NQl_4M;#L`Z{v`gzRLo|+>v{0M68ST53HR+HPrikXBeBIe z3aVhhA|O;iF~&?-pcb5JTLRmij&VCDNiWe=GEEf^sp1|VeS7k&@9l?_1{?~$zA5ZK;p^1hkGuTi-fT-vBe*Dd+vWkqY}Kc6?${{Q)W cmv|A=v`UZY6Kb&m-oFe|kWrPcmNX6dKfy}t)c^nh literal 0 HcmV?d00001 diff --git a/sound.lua b/sound.lua index 4fe595e..1c0819a 100644 --- a/sound.lua +++ b/sound.lua @@ -6,7 +6,7 @@ SOUNDS = { EXPLOSION3 = 69338002, EXPLOSION4 = 92224102, COIN1 = 10262800, - HIT2 = 25811004, + HIT1 = 39920504, LASER1 = 79859301, LASER2 = 86914201, PUSH1 = 30455908, @@ -24,8 +24,8 @@ SOUNDS = { } -- play a sound with variable pitch -function vplay_sound(seed) - return am.play(am.sfxr_synth(seed), false, (math.random() + 0.5)/2) +function vplay_sound(seed, range) + return am.play(am.sfxr_synth(seed), false, (math.random() + 0.5)/(range and 1/range or 2)) end function play_sound(seed) diff --git a/src/grid.lua b/src/grid.lua index fec3656..d77a342 100644 --- a/src/grid.lua +++ b/src/grid.lua @@ -78,8 +78,48 @@ end function grid_cost(map, from, to) local t1, t2 = map.get(from.x, from.y), map.get(to.x, to.y) - --local base_cost = math.abs(t1.elevation) * 10 - return math.abs(10 * math.abs(t1.elevation)^0.5 - 10 * math.abs(t2.elevation)^0.5) + return 1 + 10 * math.abs(math.abs(t1.elevation)^0.5 + - math.abs(t2.elevation)^0.5) +end + +function generate_and_apply_flow_field(map, start, world) + local flow_field = dijkstra(map, start, nil, grid_cost) + local overlay_group = am.group():tag"flow_field" + for i,_ in pairs(flow_field) do + for j,f in pairs(flow_field[i]) do + if f then + map[i][j].priority = f.priority + + overlay_group:append(am.translate(hex_to_pixel(vec2(i, j))) + ^ am.text(string.format("%.1f", f.priority * 10))) + else + -- should fire exactly once per goal hex + log('no priority') + end + end + end + + -- dijkstra doesn't set the priority of the center, do it ourselves + map[HEX_GRID_CENTER.x][HEX_GRID_CENTER.y].priority = -1 + overlay_group:append(am.translate(hex_to_pixel(vec2(HEX_GRID_CENTER.x, HEX_GRID_CENTER.y))) + ^ am.text(string.format("%.1f", -10))) + + if world then world:append(overlay_group) end +end + +function redraw_flow_field_overlay(flow_field) + local overlay_group = am.group():tag"flow_field" + for i,_ in pairs(flow_field) do + for j,f in pairs(flow_field[i]) do + if f then + overlay_group:append(am.translate(hex_to_pixel(vec2(i, j))) + ^ am.text(string.format("%.1f", f.priority * 10))) + else + -- should fire exactly once per goal hex + --log('no priority') + end + end + end end function random_map(seed) @@ -127,19 +167,21 @@ function random_map(seed) node = node }) - getmetatable(map).__index.neighbours = function(hex) - return table.filter(hex_neighbours(hex), function(_hex) - local tile = map.get(_hex.x, _hex.y) - return tile and tile.elevation > -0.5 and tile.elevation <= 0.5 - end) - end - world:append(node) end end - world:append(am.translate(hex_to_pixel(HEX_GRID_CENTER)) - ^ pack_texture_into_sprite(TEX_RADAR1, HEX_PIXEL_SIZE.x, HEX_PIXEL_SIZE.y)) + getmetatable(map).__index.neighbours = function(hex) + return table.filter(hex_neighbours(hex), function(_hex) + local tile = map.get(_hex.x, _hex.y) + return tile and tile.elevation > -0.5 and tile.elevation <= 0.5 + end) + end + + generate_and_apply_flow_field(map, HEX_GRID_CENTER) + + --world:append(am.translate(hex_to_pixel(HEX_GRID_CENTER)) + -- ^ pack_texture_into_sprite(TEX_SATELLITE, HEX_PIXEL_SIZE.x*2, HEX_PIXEL_SIZE.y*2)) return map, am.translate(WORLDSPACE_COORDINATE_OFFSET) ^ world end diff --git a/src/mob.lua b/src/mob.lua index 1c0935a..c00bdde 100644 --- a/src/mob.lua +++ b/src/mob.lua @@ -84,27 +84,64 @@ local function mob_update(mob, mob_index) mob.hex = pixel_to_hex(mob.position) if mob.hex == HEX_GRID_CENTER then + log('die') update_score(-mob.health) mob_die(mob, mob_index) return true end - local frame_target = mob.path[mob.hex.x] and mob.path[mob.hex.x][mob.hex.y] - -- frame_target will be false when we are one hex away from the center, - -- or nil if something went wrong - if not frame_target then - frame_target = { hex = HEX_GRID_CENTER, priority = 0 } + -- figure out movement + local frame_target, tile = nil, nil + if mob.path then + log('A*') + + -- we have an explicitly stored target + local path_entry = mob.path[mob.hex.x] and mob.path[mob.hex.x][mob.hex.y] + frame_target = path_entry.hex + + -- check if our target is valid, and if it's not we aren't going to move this frame. + -- recalculate our path. + if last_frame_hex ~= mob.hex and not mob_can_pass_through(mob, frame_target) then + log('recalc') + mob.path = get_mob_path(mob, HEX_MAP, mob.hex, HEX_GRID_CENTER) + frame_target = nil + end + else + -- use the map's flow field - gotta find the the best neighbour + local neighbours = HEX_MAP.neighbours(mob.hex) + + if #neighbours > 0 then + local first_neighbour = neighbours[1] + tile = HEX_MAP.get(first_neighbour.x, first_neighbour.y) + local lowest_cost_hex = first_neighbour + local lowest_cost = tile.priority or 0 + + for _,n in pairs(neighbours) do + tile = HEX_MAP.get(n.x, n.y) + local current_cost = tile.priority + + if current_cost and current_cost < lowest_cost then + lowest_cost_hex = n + lowest_cost = current_cost + end + end + + frame_target = lowest_cost_hex + else + log('no neighbours') + log(table.tostring(neighbours) .. mob.hex .. mob.position) + end end - if mob_can_pass_through(mob, frame_target.hex) then + -- do movement + if frame_target then -- this is supposed to achieve frame rate independence, but i have no idea if it actually does - local rate = 1 + mob.speed * (1/frame_target.priority) / PERF_STATS.avg_fps + local rate = 1 + mob.speed / PERF_STATS.avg_fps - mob.position = mob.position + math.normalize(hex_to_pixel(frame_target.hex) - mob.position) * rate + mob.position = mob.position + math.normalize(hex_to_pixel(frame_target) - mob.position) * rate mob.node.position2d = mob.position - else - mob.path = get_mob_path(mob, HEX_MAP, mob.hex, HEX_GRID_CENTER) + log('no target') end --[[ passive animation @@ -123,7 +160,7 @@ local function make_and_register_mob() mob_update ) - mob.path = get_mob_path(mob, HEX_MAP, mob.hex, HEX_GRID_CENTER) + --mob.path = get_mob_path(mob, HEX_MAP, mob.hex, HEX_GRID_CENTER) mob.health = 10 mob.speed = 100 mob.bounty = 5 diff --git a/src/projectile.lua b/src/projectile.lua index 895b688..bba2c12 100644 --- a/src/projectile.lua +++ b/src/projectile.lua @@ -63,14 +63,13 @@ function projectile_update(projectile, projectile_index) -- hit the mob, delete ourselves, affect the world do_hit_mob(closest_mob, projectile.damage, closest_mob_index) delete_entity(PROJECTILES, projectile_index) - WORLD:action(vplay_sound(SOUNDS.HIT1)) + WORLD:action(vplay_sound(SOUNDS.HIT1, 0.5)) end function make_and_register_projectile(hex, vector, velocity, damage, hitbox_radius) local projectile = make_basic_entity(hex , am.line(vector, vector*hitbox_radius, 3, COLORS.CLARET) , projectile_update) - projectile.vector = vector projectile.velocity = velocity projectile.damage = damage diff --git a/src/tower.lua b/src/tower.lua index 4df3acf..5ec31fc 100644 --- a/src/tower.lua +++ b/src/tower.lua @@ -11,8 +11,8 @@ tower(entity) structure: TOWER_TYPE = { REDEYE = 1, - WALL = 2, - MOAT = 3, + WALL = 11, + MOAT = 12, } function get_tower_texture(tower_type) @@ -117,6 +117,7 @@ function make_and_register_tower(hex, tower_type) -- make this cell impassable HEX_MAP[hex.x][hex.y].elevation = 2 + generate_and_apply_flow_field(HEX_MAP, HEX_GRID_CENTER) register_entity(TOWERS, tower) end diff --git a/texture.lua b/texture.lua index 34b051d..0c74223 100644 --- a/texture.lua +++ b/texture.lua @@ -10,6 +10,7 @@ function load_textures() TEX_ARROW = am.texture2d("res/arrow.png") TEX_RADAR1 = am.texture2d("res/radar.png") + TEX_SATELLITE = am.texture2d("res/satelite.png") TEX_WALL_CLOSED = am.texture2d("res/wall_closed.png") TEX_MOAT1 = am.texture2d("res/moat1.png") TEX_TOWER1 = am.texture2d("res/tower1.png")