From f3c551e7924ec899a688cbfca99762b17876c1a1 Mon Sep 17 00:00:00 2001 From: = <=> Date: Sat, 2 May 2026 21:53:31 +0200 Subject: [PATCH] Added exploration node to DSL and worked on vertical pathfinding (Closed gates blocked horizontal movement as well) --- Assets/Objects/Decorations.glb | Bin 52740 -> 129008 bytes Prefabs/DSL/ExploreNode.tscn | 35 ++++++++++ Scripts/DSL/Nodes/ExploreNode.cs | 90 +++++++++++++++++++++++++ Scripts/DSL/Nodes/ExploreNode.cs.uid | 1 + Scripts/Helpers/GameData.cs | 2 +- Scripts/Helpers/ResourceLoader.cs | 3 +- Scripts/Helpers/UIHandler.cs | 2 +- Scripts/Robot/Robot.cs | 1 + Scripts/WorldGeneration/Map.cs | 10 +-- Scripts/WorldGeneration/Pathfinding.cs | 37 ++++++++-- Scripts/WorldGeneration/Tile.cs | 2 +- Scripts/WorldGeneration/WFC.cs | 2 +- 12 files changed, 169 insertions(+), 16 deletions(-) create mode 100644 Prefabs/DSL/ExploreNode.tscn create mode 100644 Scripts/DSL/Nodes/ExploreNode.cs create mode 100644 Scripts/DSL/Nodes/ExploreNode.cs.uid diff --git a/Assets/Objects/Decorations.glb b/Assets/Objects/Decorations.glb index 5eab544869d134fbe9e26bf61da53604a1c26557..01c066877f6fd6d55a07e2298cdf7cba12d9787d 100644 GIT binary patch literal 129008 zcmeFacbp|f^*($$5F|*>>9S;4mdRmZr!QFqBqNHzUD#b%SXkIy6a=IdMa7I52r6b> z6J}A_ipXSp>FPSwJ@?MSxyw#I zA{LQH{}IWi+lxH?q~o4(#hisJS1w*PXZ{s)&Ru-b;uQ;5EnhKb{+y%FTe1A2v4YdmXd% z-1Amps8uT#UbJ%A!d1m^rw`5>8z_E;h9^b_Cq^gc4$mDpO#c zTfTDfq8UL3<_^pqo;Nf;G(0&zG(I^#JUKj3i80iRapK~Y%P(DV&f=L7<_!;yj|~hC z4vvhXOiWIU&mEXIHZnFkGB!RjI50LmFg`gkcWBu4qblH z%H_*ujxjcGlF>&7#zw{`CME_a<_^vq9T~tiPfiR^P7aR_4-C(poHvS-(Sd;xT+YbY zU@@r|;?h?vUAS!eE-YGp>DkK`pR{xlW@7%T6_+mVjeHdDGcN7ovsWCuc-6vX%a)#V z;_^$+J@2B$E79|cIcG0ix%klK%a*S=V&OT($~b*s9>$m)A0HhapBNt)85keLRS%61 zjExQsO$L2XXieP(HGDmPCDx3qmFw1vWG5TCpY#imrR*pFmKIX{WIXdQO zeax}ynB&zk2Ww*WG7wg0+{43BVJ{GjF(Ey^9#c>{MrN zaHJL#*SI$5aP2xccj1>YI93@Gvr`*$qBbTjbM2Urc9Vx@+~qUo&RKX47TwC_E2bY9XJ5Kx$>J5KE?xY*V!58P{KAWuU$pq5 zRVQD5F&^jG>M-DcjPQu#mGw%YH{>;(W-i2X=Z@vk*OEUwky$QX0 zFo3r*tlsf~fr*LXiLp^cb~KIf?Qn8zbYO67cpPsNW21}rADCEs8ysD*@MlEc-y3J` zT+GY|Y*>9RrK$HIHnHIDGj9a<{h8g@-if|9f=`2)0oL9LypG~t>CQAhI6i?X9-hFB zn7~$nn}JEV;-MjRI>x0GvHnf4&fCF3Bh|YFgP)WaM+CyX?PUL!w|Tg zqa%~}6&;^pj24^S+KF)74Cf|Mzlg^E1@-^`lbdg?GbeHFjc`1=F)3@`|Ee#x#Y^qk zm#T9ZC5lE`4Tqd<0Y#~Zat*pU(JkM#gecORc)nMuG_Iq_s>VP*h) z0&EmCE&dr-fNhv7I&=#7n{@3iB6Ev9u(EA6%>W(`cJII=*{-CfD{w>@AH!$9;n#pq zheynPsE`3hYLR{Oy&Qx^E} z*0*dnwdB=bykpg~pRynXZDW1aQjpV96dxA3Fi8uZUb{E zhwnb1h_5zAzgzdr7N~vb7vGz@VdGVqwRhh5g{ju?)r>in4_`B-=lSrLIKEu)*u7Kt zto!`TXWzK-$>^I;seR&!U9vkduG%+jyk*95t!)kOl1-1>$vCc_x0mcpEpqR=+h-it zXL%hLJa%+(JyrXWVjd(@%lW%u;}OK1w!Dt9e;r<2kITMmzb{U0`MiUs=i|QrPU*SY z>FbnCEw7XD)$%&2$J%+n+c}$#i|a*PJy&}Vu9tdzc3pXjB(g4w$o{gCY>9eH8Iw`j zLbgS{tqjSaY$KbY-c0tBr^-&U2kJd!YuQS6mwiz0BiqY%vbXGtdRN(8c92Oq81=!j zo6M269FF>M*-Q46!(Xh!>Jd3oj*wxQi+V1W;yhVTBGi#= zESt(MvHjtduh!0B?lGNuc&ueQ&?^p)4u?SpwO%9(+g3)4S&kr&9dZv9;S zv^|b;OY7uloYFcu8pp*k{dMeG9OY=7(mFZHEv=KIaVi|{kHy%<{#Wjo=-dLA?HyY9 zc+Ma4+r+Q}tLOByy+a?0p3|SBSW7?KttF5BttF4`)+WeoL0K2supu&deUvScom(Mm zHb>bAS-crC>8U6&GHnZF*?K4uGJ69_QK!haUp~53mt~#bFBpc+DwypV+CN^l7Z^j9 zKRI;;Vsf?EK2fnZCD3^7S({~hzV7gB@TS2jAAaApbF*x-!?K0OVAXcs6X&k+VbylucGs>6!K!UBV*0RZy9Y5tFtt5)#^%{jIiD^} zZ4doui|p)jKKo&6W1P`)K3$mF7-w-gpZ&1vJhz-r#V&cxu~2^#aPOzA~O&w4$ByzK3957x~Y)@m0k->4%rSY;N}9O%Kcdx&5_kLNMoqF?Egg z!_>3-%5Ab^OFjKCuaO+yix5oB=Rdqf_K#A3KTQ3MulKPZerY+Mi@&~TDg^62;(ii> zb`Lonx@n%9);ryu70GrsQg{jh4_J{*GedXFyG8{;=& z)&IA0{ZM}sR{gr?Gkz03aqhfq@#mJVnZSJd@b-Tn$=>qWOV^x-XI}{3sQbk!#+*b< zAHHJ0PfjuBQp60w)OIdnF2p?hFtxo6G4H~&F9cJY#`NLmL#M_J!PM6NPOE!hIiD^} zZ7aXCQ}=>$KKo&6W1I!$e7Z2_ka3ok^Vtup&NIvTWK4@y=U2=5WXvY4IvK}@Ifoi2 z1anV&!)Y%s?t2L4b&>yc4$lZ z?VY-RDfRcm)X(@|EAMGPd@}UE9@o1J`*R4U<{QB0eiDMIe`n19o!Fm4 zF!fW9?nV9Z_h0dmDeB=~6oNNKuIcrL;5Y93$tmjp0`!Mq<|*UrzSj>kk90kUU|u8n z+$Tfuo1kCUe+XvI>Y5M1Tm#?0dgFc=g1N@XUtX@aepuK4m&*0S_1}cKei&2t-hP;C zKsAJ5&N=zqt3xo?3^jkbTtEFV*AL_CKHm>hgYG9Gm}`uD?pGn0Yex5+5X?2Bdrk=E z{&~Q|2TbvO&xd(W|M&22Q+#I&!MrZU979YW<~%dzlJa@l4^!Lzh{^XrAEvhdA|~I* zLNK*yOdsYPYRnK!Z6WV_L!UpRx5xIw)E4r-$2hw0^~2Pu?`A&CIUGSueHQn_)TuFj zm~*IcLNNEVrN3FXxbGpD*Frwu`9m=Gw-pcVHpSl`Lonxr@pX;$!_@HJue8^wo_?6u zNDiMbA()y!`sp)z?^pdW^)tTe?}z!kxB%D7-ycITHIvW%Bm`6cD$GAWe+a?U&-l6* z^~2ng$>ClUg82+0pVu3L`Fx>%{{9<+x$iN)?tA?(^GMfo2USKLj&p zb+-w#ud?k6FbYm9vES0R{dM)#Z$%r&EXP6+1y$v?nGbUg&p}Lmmi5EbsWE++bEt7bF!#4>TI=_|@92kl zE#&a~ln~7QEj?qC;`@;h%sF9vU1R+)H9Yp;MW1XJ@LetKZ<{i+|P ze#Yl#@*$Yd3tl5XZx6wGzx4Bb_HDvC=lo1Q1nd0sGx-qAJ((J~7lmLxgY1rC#-*czwL*)W*Af7Z~I}c0o4$KIp^f-`*1(Z^+V12e%lXo{V=BP^ZhXO z=zbD{xyE$A3c*}6y61#ot{>fhLhu>y{rMWcKXCo{@V#4ncMYG>yr&`f`L|B>{$9d| z4?q9#uEq?(s*T^P`tUuaPVT)SShew4;KQno&*%_LZG4yD`?C*o4*CATclZ!YZ5q>u zsZC>sU~1#L#M$M1x-jRE?-Km{Bm`3%<8;dTbYW`Km?3zdRS&G;9?1J1f_Yu!^L-!$ zKeG9E*KmL4=O-bU^T7DJ#`lf~lYJxt>F?&LN){ zAz1Gb_mdF(+j9Q7KZjuEOR*lx-06q;ojW;Tk;7?*bbNx_%2l_0TyOm_*9@QO{QMyVbNw); z?!Emm=Ug>}V9q)DyxtJZIamE5nDeiiLohWk-?=A;U|yr{S0R|1x&QF{sU~1!cG5k9RALe}WyBPkhLI|cd#ykTteVE!9 zlYhq&g1M*h^JINq_rtsva`^WrA(+o}e!i{G_kNi3!1%hx`eAC|=b5UfALjLv!}}6~ zsh^*(K32Y;^uyH8_^Q7jrha}0q0ftcn3~Da=TSe*X9~X`(dSD)%zR-?-HZBR?#Zel z1asYz&+84r+>=#v2zWV2To3#Xg8N|z z=6WOl;`05ZALjbucOv}zjS$TB!z)&WshRQlObNkU5Blu$Vct{zEvw$sewf##F@2cYG)@Snwvgv3 z|CUvsr~NRsg*;CgN1vztFm>{8O|$a-#DzJZ{2S5b<@-rLOr09XhdGBDCj_g`)64f0 z#|KTHk$d$6aKdir5rFFCvyA(;C4_i2AF-%t8s>Suhe=MYT&{2NYvUi8D% z%)dv~=TSe*XA1wmRG%;XFms0*bT8_MxhJcJ5X?2K*BFAiC#&WV%=NFDLohXPjdA^i zU|u8n`aJ4~sae;22&QJn)cvp@=6c}YaB@Ek!CY_TuPonB`eCjguKByl_mh5@>xVIQ z@9l><=c*wDbN1xoQrXUP}|EX2$0; zB?R+d9*?~G%52Z`_u{{`#?SP>VZQhy3m2@orTA}I6s_y;K9T+4dxOQlZ&rSlbNx?l znfk>?R`&k=vvP{gYh&IK5VOZY%r%afYfMa+&MrBnhBW~?ZOonq#woAe#_Vw%I=hwm zEc%ri3S7qQR_3$dS2^W;_V~CKS4?W?aiG%`v&SiQ_V{H?z4oHLs-dE@@F~B_@#wTM zdm0*I_Bd6YW&Di&R$kf4F8S8OpG{UC*?kc(+qMSQHOuq0Khyth2fcSwTWvJ;lRsSW z*@xbARre5J@_q(P>*Dyv^~LdP;|Toe>ES)V%G^%iZe^@jPM5z`l^oc|f)mh(SjEKi);J+kYe zoc}^^sZH00?pJ!fUXE|vivHTVt>`z}1ph^*mD$LaZ=b5Ji{Jg~{;4!h}q*HX4et3m>XTwRSncy>MZ81)VZe0@#wTM zdm0*I_Balm-O79xT1pKCE@Q5#%xA%`a!Q@0u3|o2F{zVm``fZ z`7GKzI&I9JhRU_um_1HaXBmHr{aTl=$_AhImfQdJ>o={L1I)I61M6Dg`P!f9Jy_Sn zx<*p#u50_)5H7TE#pjDJ=OUvV@~$FUg)0@ z(-+4#u79j)^*YDpTxFGc$SU)hdFE}Za=$S5_4gB3OkW(|xRv>@jfFV9Jp`O?xqiqg z?mgBI^%PjIblOg9tY}+Pt{+}6)?BfEiZ$rs_{N2PXB@vaRn=QR+=sb-G!ECZ>gjsM zWxnY3f?L1dQhzO`FOF~AivHSIh{NYXp|8A0T+g+8WY>e4|6-pk?>qCQw%*8v{uvzK zxV|`kZN2%|d#z(}{#B38Ki5Ckn_e&1n_jQZ|CD3?XT=)+PE}_)55@f|_mJEBJ+B#8$JX^w?n}4Z_W?3p9N)OUIDTy$fj_Juf`-*7!Us z=Rd2=t@k~r%BkqjD)V0(3wmbXPo~#Tk;CQsDe&}tt*!swJCA4H)?og7oa%cK=3n3a zYR?zXI;`CzU0bSW+V<9)KD#wvYU_>Ma{cT2DW2WFaVzV;7N@fQjW$&^Ll5Vn7^^Z5 zv+pOF@jHGkU7Z zDc3_8!yB{rOmB$U?k|KW8X)Pd}H+ zxhi6mF?;VP%CB-tou#hX&rdjKm1hw5z+!E>p4a4JeH3%;diSV2*SwtSI;oCZc|J0~ zihEqbW)n$(B=MNcY-OPW{R(ThieLun4<2;pfqHD5v_bAt4vA)Z7SiF0b z@3*t>Cz!X{_mj8t9g^=+#X7348Llh+zJ^%$tm-=wTXpRbE5FJqpX0?kta6AeF?$-= z>WSIoRCSi|r`WIDLvHW)c>=jQHpbHZoWFnReqO}mdj**;j&I!A_mk=Gc`Nf!`#sb% zZ{~N>>EA^;_xvg6Uw{AQJ(~Ue1oL8^k9Mu{`Kar;$Um;{k;0_QLe*cUCzFr%=pfz$mQAhliBwZ*Skmc zbB{8=X1v3Ap0oUX()pg_e|OT9pONp3!+nzZ-g{pv$JM;%XEOSkXU0gb&xcN+0Rev>tTAu&G-%l-?%`SgQVzh?|1NfaaQ?z z&SD=be@8BGxdyn07w5{aa?15k?6c%6XZr3=uQl*{--$HD>~YF#v@wgE);+GOp%Sx8 zTx!t2mngJ*blR9b4Gl4S9EVQV-?C2W=NM(oVx5;d3x0Vmh4xZssjK(dML8GK&$@Cx z3w}dP>eQIMHB%W^uf5<@HB@32KFsIr-^b3rpA`E*8*$IzU#PLZ^gJx>#g#B)qCgh#qo_>uAdoWdE)SQ5MBS!>RkVYztpDdjn`XS zZ{_;uoYXkJaVz?3aVq+2+HSh>S=n9py>iN0e43uMS}(|+y6IWj&wl*EDYa~uNB?x- zjp#Qt{FfV|10{@YWtEUduI1xJZmq#q?P^tXZe)Ro{N417|&Yrx83Q9 zqMys&bmMkY9M4+*KdX6tU+5-NzrgjWE&gBDxIXeZp0!Ur(Z#j2i+;Q=_M_GI(czCz zaXzixdZ+Hx?{IxSOFqZ5c3br0b@}YgH*S|LTC!xyXQ98CZ?)w8_lc`{T}At%i(A=U z&_#PsY4x0z{44Xz3O?5HjPrZ%yKm}#T(8gG2S4?F9hUv|TH}pI6ljMU+iAf z>u=9_9XH*0If~!jdEb2p?Y(Hn>{IiuE_ggApH`mOB|9JMplb7b{&b+8^ZL0?X!%ZD zKNq>N7yqXWxGA+P8H-ukPErkI(MkYv03X-@j+yzh~dSi{BGx-@hI2 z;oL{{eOvcmJ)eF5p8fn}_Vbh3&ri4y%zl0{`}v9MJ$&~4d-`*6`?{Ym-v7qfqVV*egRWIfpsUx;ofsXRrtk?m1$FB{2L@>JOz_2#mjY$~y=gL)m= zLbjImB|;s^CbFCCC@s`2*-M6H57`^_-ZCcp${_x2!M-T-WM`Qx2cSMcc9q>_NcKa$ zpX?-)a)cZzhsl&2EKiq{8MYa*U0(uR(UV#_sa9+QhB%BjQVC-E?3A$eccBIYhRUb#a_6&%rT)^L1elk&Yy?0gj91LLAS+`3A5Zd8M2t%TO%Wysbd%fH$d&(|2UMsJ{aU;%mfxT5eCgZXXj(5l{INpcz zePBN($IJdQg5x&%5RRj8J_38Zd`7zRCDdP%&&wC&8}cpG-;yuO*X65n59)j5n{tf7aO@_+Je`9A9J%a7#|`H}nt^-tuF@-z9Z`~meJG=%8panuh_YyTbT;auzPx%{;L7d+WI}t642BN>pA{2?99z7(#!LdP<;%MXi zH>Pw?*qHCkeqDxR; z5?vj=K6+*JTGX$N-W0tvdPDSP)NhX76WtWOJ$g6lcSmoHULD;My$$u-qSr+?MDK`h zMtyVis_6aEr=pKXpNKvjeKh)P^yTOa(O088qAx|Ci#`&467?seuS8#qJ{_$_y*gSG z-4lH~`eyXq=``+ z@5A|XVLui<5Uq@!kK-rNk8s?L^XJ1p5dAm0EBYboA4coP-RJ|+H=-`ef1;m7S4FSD z@mTbG9N)+JD`0;XZ4&=q^e5DRigt(}jb0YL5XWuNhj9EhdKCCWsCSHi6MYc%2cyqK zaeRGrD~>NlpU3e}oZku?$D77)j9!C7;>V-Mqo?5fHL#n;bK>_#H{#el-U!FGIKMI4 z2=$%OTcUU2XvI6>xIMZPcqg>(9Ul-6$9tp9jR)f_J_Pk4@kqQN9*gIro*y3^PsIDi z`=j1JJ}{n&2jYED?-P&5N5_Z7Pec8*__+A=_}KV()W^qX#wW(liqAlOMto{~M0|4m zOw`YekBX0ppBt?|wAE%6)U8{>DxAB^80e>i@3{DJtR@tXK^ z@#o`D#ka>_jPHx@j_;4Z65kttGk!S!zxapocjF(#AB(SzUxWHJaW}prepP%8>TBXp z$JfVSjlY5V8}ZxXx5QtMzl8cr@tfjz#@~y7g!)JEhvJXKKaRhJ`djgP;`8H!;(0i( zi(ibRgY$W?=f^LL_lt*cyg7aYju+y52=-<1C*nN50rd^>o$>SHbK;kxerf#i_@;O? zJ`~65_+2<&i}OQaZ;HPbzdn91>i5PE#_x;U@g$D(;>9@Lj`K;__r>3iZ;cnBUKC#( ze>Q%4d>W4D$E$GMhV#>4KO5f_KO;U8$7kYC;`jp2kA%G|ekeXGJ^{x)@t1Ktfb$bz zABr!FPl=y{}*!tdDyAWb0&uWV2)|)LSJ_ zP5u{elx%`}lO#&gWb;?4JxL`z5<1d!XJU z8BNBMy^`%wZ=cLd<|l_G2Pa1)3z9>VqmomTlaiB@XCx;i&rTL43zH?u8Ob@x(&V|x z%4Ah?QF2N0{N%;S3zKV;tCDMymnUybUZ32MygGSZa(*(E9EtkKGU?s1Hn* zCr?jakh~Q2OOt0Nrz9^)u0VZ7a$ItH@|xrgsNaw*PR>o4 zCj-gG$(A@?o4g9gJ~-bJb|86k^0wrisNb2~lDs|nNb)h%A4}eqd?@Lj9%WlgT%ehm-$HewchW`9botTe~#N*+u8oBS*JU-Gx)KS`86HQg}XC|x&wO1gQvW4c|sbGlW! zL%M4^FWoPlo9>zJlMbZ^rIYDYI+`As9-KZSJvu!mJt93Sos<4Oc_NvUK9L-d?w>xM z{3Y2x{Y$b}8mD7vhB`|(NjFXxq{FC()AiCV(j(JjQ6HP`luf0!J&|H@ypX-*h5flYAP--sv7V266uBWDnF&Prs3T0muAw z1VFd&)(s!kAPv4WiC4Fal zbNZU}4XEFczB_$y`lj?c)YqkNO;@L%NI#l>D*aIU@$~letLc~0FQ;qLFQoUR-%h`o zemDJk`e6El^jGQ6(_f?yr$0@9m;N>VbNcu659wdhf2HfLgPXO^|I%okhtdzHpH3e_ z`E~ls^poiaP=6r(ar)WxkLf>9|0Dfc`jzx==_9BgNxSL2=@aQX>)ea-o%DO@dh7ff z^}o~m)9cek>8UtAmVOY&%W!@w?Dgqw=}GCcaom~Sf#dx+e>UuG=?~NQrJqOr`SdsG z+tOF0A3^<*^#9T?re~xV;P_U0ACAx9`~ui7rhiI5mwp5FH`4#452WX%3vs+QeHD(o zalR1tf%L!WUFj=PzcPJu`m=OJn&Ws!dJB&4<2;A`S^8-D+;lmPpQJy+@mriPhkZ1S z*Li7rIgZED-{bfv&M$|J*SR&lDt$2yS?BTe@$|;@R^Z1`Z~BU#bw&RE=~ZugbgBt| zY|{^B%JE^w`NS2!TcdGYn0>X~g-`4L9RI#(T2B*J4dnQ+>d`nH*J9P6ag?L&qbGc@ z(8KmB{=<$RDCUjr7HeO&D`sC8*1nwED%P>sZtVo`Z)~?%`8tQ>==C;XYSX?=nDulDBOV#egWvAqfN-YG}1u04&ZajN60 zX6;LDN3MTY@BUh>G1+c0$JKVls#)Vug9}&3RjfMo{=WC@UoWU)y+>@X;_0cK~Z=obNJp1E`7k4+j`aM%4hx~SdD!@G``c^nuozv42I%dhU_d?Ir zPAho$&MmY1Pdi@q7xvs=9ng)RwQcsAbH7vkJ5diOt8&(^CB{|FdX;*vw%1-87xQDT zy&9{oTj#AlRyF=KAJ<}ZKG~QxemS>Z{pSAmG}PwPt+}eb7_&AvI%4%+=$fhCFT2J( z{N9|*ob#%V8dg1a4$AWx_ou?^%|p|;Mf|2~Svzn1_r=8zY>vWnj?pS&h;(4t&U3cY z-=+^%D(CdGy+a?0o)_`JwU+)|<5nzr>~AgkY`6B#sZ&qcDm&$rH}v{_VD-K@Kczfx zWjtTK`suy?)BMr${LZP{RK<%)B2{*$Q>BiEo@i+on`!)b~^r@2oPGkT>0r*TepdOa5BRejix90pp{6y5DJ->(#4QgP#|Dru{spzm-k<$uHto zEU$y@wB%F2pxj#Gi?b*2-y?`|u6BC`!&aGX=J|2^@x8FpHK!7In(_3(W46#4t%d#DZZP2q<4zVYe!u5c^V{5J9& zd@r~e>do-|J;CSosaL}_C&oWzC(N_zUkW= z_1^fdauL1<+!gh%_|EQ3d=s}D>fLbmG<<8eJL=u>ecBwyE!h$Ej`((T zd(=Cl-WlJ^?SSt`Cs9x0JHP{BSx?}b&0X*v=NRfSd?$J&EbC!>=hw#ffpbyM#dn`a zmceud{cT7zUkZ__5Q^-rEM^GLK(w1wFe^ddMNwKy7- ziMWnKP#+=@z8^go3*iiueTwg84?=wq=4d;Na{}rUpmb|!IS%!4_>OQRe2;q!>SJ)t zC*%9aV^JTA?|RR|Tpoq`D9p;XxY8p~AAx%?i3k^-qXY}99C)>l=UEjUsxEE%3??1Vq34dX7b++Fx$JUVJ!}t99 zitN8{fBZmle0YP0-;=%S&@+lSF8p}+m1|T_6IKo6_^@gq$A?t|IWD}(Z6BIaJxy3O zkmJLufgB%J4dl4+y*J;Ksh%dR8p!cs)j*C9s|Iph`08Jt)V=w-qq6x|E}Uw@KmY9s z*~{NISa5v!4?jLE+wJ_53yu$uWyfYK-ne_gap6ak!+Uy~uxcR3hgAbPKCBwZabeEM z3%AI!W$$=(q1lJ;UU6i$*CiJg93Ou0y!qL}?Os-Je0Ybu4#_q>t5a}Xm^xKM6IKo6 z_^@gq$A?t|IWElkS#rxr_PJ|6SZMa)5C7+&?B}=KP;h+s_CFtx-S+sq3yu#*Cro7D z+hY1&xG;69h9;~U$njy-K#mWq269}O^K;A|`(_(la8GevK77NAhqA#Jeyrg5@Y|lh zNA|=|zf^F1_}4$!Kil)4A1F93Or5Hs39ANjd{{M*W@_ z!m5EBA65@nOwza(q~GoE#UXPSw+dRRcLbtQyGiVbws63sa}& zdlS|iC&!01$I0UXKJv~iWHIU=Os(~CIRt@C1Fm-CaH(||ja(q~GoE#t494E(xsZ;edVbws6 z532@pd{{M*W&86V@Cj$A>k?$?;*$adKRkI#o{-Rt@C% zuxcR3hgAbPE=--8?@d^9oE#t494E(zHOI+uVd_*pO;|OM@dO;|OM@nOwza(q~GoE#UXPSw+dRRcLbtQyGiVbws63sa}&dlS|i zC&!01$I0}4PL2<2j+5iVn&afS z@NLh$vZtpBs|Ip>ST&I2!>WNC7p6|l_a>}4PL2<2j+5iVn&afSFmePI1!kXjc z_^{?UIXePI1!kXjc_^{?UIX94E(zHOI;EVa;)JTv)Dq z{T=#wR1;PWk?$#G%oR6R{tHIU=Os(~CI zRt@C1Fm-CaH(||ja(q~GoE#t494E(xsZ;edVbws6532@pd{{M*W&86V@Cj$A>k?$?;*$adKRkI#o{-Rt@C%uxcR3hgAbPE=--8?@d^9oE#t4 z94E(zHOI+uVd_*pO;|OMST&I2!>WNC7p6|l_a>}4PL2<2j+5iVn&afSFmePI1!kXjc_^{?U zIX<Hkn&ag7u;w^9KCC%Tjtf(#>S@BNfgB%J4dnQ+Y9PmjsZ;a432Tm%ST&I2!>WNC7rt=p?q0q(Va;)Jd{}dw93R#kC&z`a{nxL0dYZ6m zAjgMQ135md8pv^B>ePI1!kXjc_^{?UIXW&86V@Cj$A>k?$?;*$adKRkI#o{-Rt@C%uxcR3hgAbPE=--8 z?@d^9oE#t494E(zHOI+uVd_*pO;|OM94E(zHOI;EVa;)JT=WNCA65)*L6tg{f2ZG-1_1jt{E_a(q}dkmJJCsrlZ7 zHOI;EVa;)Jd{}dw92cfe)zgGk135md8p!cs)j*C5Q>W&86V@Cj$A>k?$?;*$adKRk zI#o{-Rt@C%uxcR3hgAbPE&!3PZL%Rk?$#G%oR6R{tHIU=Os(~CIRt@C1Fm-CaH(||j za(q~GoE#t494E(xsZ;edVbws6532@pd{{M*Qp^V zST&I2!>WNCA65k?$?;*$adKRE#kS}4^fY1BK#mWq26B8@ zHIU=N)T#O2gf+*>@nOwza(q~GoE#UXPSw+dRRcLbtQyGiVbws63sa}&dlS|iC&!01 z$I0)*L6thc(B^abfCIJxy3O zkmJLufgB%J4dl2m{?qYt*>^V24*kRl`0vk)z;=0#|K@&|=lWwf8P4IK!RfL;`}pE; zoaw&BxFvr^9G4zwTKnVCV>vE8HI7G5jbp}|ouBgmm!o&1oWo+ycyD>`SR1^jUG`ba zpK;&IzP>1wkq=Iu^g8k z%W>(caXfl5)k5phV>vE8mgCY><9PIR1N2yqOONHa^wc;WJz0Pr%W>(k9G9LN$D^kk zpvQ7tdMwAKr^fN<$pZ9Pj!Tc_xb)OG9zERvJ(lCrV>vE8HI7G57NEy+TzV|WrKiU6 z=;;RNu^g8k%W>(caXfmm06muD(qlO;JvEL;Pd7l1<+$`%j!RFCA^9?Nm* zsc}4dx&eAD$EC+|TzYC8kDe?*kL9@ZSdL3ijpNbN4bWpbE9HJ_o*KuaCkxPHIW9ex(c=U7w^jMBdkL9@Z)HohJS%4nP zap|!fm!2BOqo*67$8ubHEXSp%#_{OM0`yppOONHa^wc;WJ>393mgCZ6IW9dljz>=x zpvQ7tdMwAKr^fN<=?3Vr9G4!;ap|dXJbJPKJ(lCrV>vE8HI7G5H$ac&xb#?#OHYmC z(US$}u^g8k%W>(caXfmu0eURQrN?qydTJbxo-9C*<+$`%j!RFC9HJ_o*KuaryHQha$I^W$EByn@#x6{^jMBdkL9@Z)HohJ-2gq7 z8Wu%da?jLmgCZ6IW9dljz>>7 zK#%3P^jMBdPmSZzlLhFp9G4!;ap|dXJbJnTdMwAK$8ubHY8;QAEI^Otxb#?#OHYmC z(bEmkV>vE8mgCY><9PIB0eURQrN?qydTJbxo^F61%W>(k9G9LN$D=0;&|^6+J(lCr zQ{#B_bOZEQj!Tc_xb)OG9z9ur9?Nm*u^gA48porj8=%K>TzV|WrKiU6=*a@~SdL4N z<+$|JI37LS06muD(qlO;JvEL;PZprZa$I^W$EByn@#yIW=&>A^9?Nm*sc}4dvH(4n z8Wu%db$C6EXSqCa$I_99FLwX zK#%3P^jMBdPmSZz(+$vLIW9ex(c=TiedMwAK$8ubHY8;QAZh#)kap|!fm!2BO zqbCc{V>vE8mgCY><9PIR1N2yqOONHa^wc;WJz0Pr%W>(k9G9LN$D^kkpvQ7tdMwAK zr^fN<$pZ9Pj!Tc_xb)OG9zERvJ(lCrV>vE8HI7G57NEy+TzV|WrKiU6=;;RNu^g8k z%W>(caXfmm06muD(qlO;JvEL;Pd7l1<+$`%j!RFCA^9?Nm*sc}4dx&eAD z$EC+|TzYC8kDe?*kL9@ZSdL3ijpNbN4bWpbE9HJ_o*KuaCkxPHIW9ex(c=U7w^jMBdkL9@Z)HohJS%4nPap|!fm!2BO zqo*67$8ubHEXSp%#_{OM0`yppOONHa^wc;WJ>393mgCZ6IW9dljz>=xpvQ7tdMwAK zr^fN<=?3Vr9G4!;ap|dXJbJPKJ(lCrV>vE8HI7G5H$ac&xb#?#OHYmC(US$}u^g8k z%W>(caXfmu0eURQrN?qydTJbxo-9C*<+$`%j!RFC9HJ_o*KuaryHQha$I^W$EByn@#x6{^jMBdkL9@Z)HohJ-2gq78Wu%da?jLmgCZ6IW9dljz>>7K#%3P^jMBd zPmSZzlLhFp9G4!;ap|dXJbJnTdMwAK$8ubHY8;QAEI^Otxb#?#OHYmC(bEmkV>vE8 zmgCY><9PIB0eURQrN?qydTJbxo^F61%W>(k9G9LN$D=0;&|^6+J(lCrQ{#B_bOZEQ zj!Tc_xb)OG9z9ur9?Nm*u^gA48porj8=%K>TzV|WrKiU6=*a@~SdL4N<+$|JI37LS z06muD(qlO;JvEL;PZprZa$I^W$EByn@#yIW=&>A^9?Nm*sc}4dvH(4n8Wu%db$C6EXSqCa$I_99FLwXK#%3P^jMBd zPmSZz(+$vLIW9ex(c=TiedMwAK$8ubHY8;QAZh#)kap|!fm!2BOqbCc{V>vE8 zmgCY><9PIR1N2yqOONHa^wc;WJz0Pr%W>(k9G9LN$D^kkpvQ7tdMwAKr^fN<$pZ9P zj!Tc_xb)OG9zERvJ(lCrV>vE8HI7G57NEy+TzV|WrKiU6=;;RNu^g8k%W>(caXfmm z06muD(qlO;JvEL;Pd7l1<+$`%j!RFCA^9?Nm*sc}4dx&eAD$EC+|TzYC8 zkDe?*kL9@ZSdL3ijpNbN4bWpbE9HJ_ zo*KuaCkxPHIW9ex(c=U7w^jMBdkL9@Z)HohJS%4nPap|!fm!2BOqo*67$8ubH zEXSp%#_{OM0`yppOONHa^wc;WJ>393mgCZ6IW9dljz>=xpvQ7tdMwAKr^fN<=?3Vr z9G4!;ap|dXJbJPKJ(lCrV>vE8HI7G5H$ac&xb#?#OHYmC(US$}u^g8k%W>(caXfmu z0eURQrN?qydTJbxo-9C*<+$`%j!RF4bLUh!E^Lm%bN;uMTP3Fh%XXf#o&Gj`uu?hi zunnb!(yrJd9=O($muuXLC695eC7$!EK@1rIJkzg))wuY-9wnHCE3x(}!$zvRA>1VsOZf(JXORD35*Fnk4_;j;h zjzXTmvR}JmJM^KnP}r`PJjSt>ezsdnp1@}qmU=C?ANZ?4t*#s z6t=4+k8!M}pY7I?C-7NI9^0)gcyLK|9Pm0Qc^RK>_RCSo6Ik|ZS8Rtqlokrx)sn|J z*3!>*YsnM%tR;`_))qXtq&g0G9hAI`PdEGJDC7w&`?V{!Lmx^Dh3#s|V;pPgXS=oJ z34GR)$98KA9$Zo#2fPkSUdE@J{c;rY1eX2U72BZ?rG>(Fwd665we+*yTJi)wYsq7~ zwFM6@sg46)2PH4#)6IT43V8y{e(j3w(1+4OVY^!L7{^-r*={X)0-v?yvEAB&2bWaG z0k4CSm+|RlzZ``;fn~pT#dhdJX`!%PEqRP%E&Xh_mOO#aTJqR#ZNY;}s^fsyLCMSb zbhBTMLY}~~U%O&E^r5s+*shj5#<7-uwp&Y{z-KLaY`3=H!6nsk!0VvoWqi8XFGnFy zVA-!-u^swQS}1H+OCIA`OF!GKB~Re9mOQpwTkznL>NwzaQ1UW9-Rzg6kSDP0*RI$O zeJCvywyPzNajd1E?bebf@L5Y9+pR5la7lF>@H!}Y8J}+U%TdS^SoUjIY==IS77E+d zlE*mK($98l$rJdjC6Dda7CgA5Iu3Xpl)Q{jH~Zx% z$z!{<1rIK%jsso?B`@RC&3-uwc>>FR?TYQthtfh}yIS%X$6ET?ZY_BNpS9$%-P(c& zmsH0AuY;18@#$v29ECiAWxsaCcIZQCp|D*od5mK%{cN|EJb}+z^4M-|!GlYx!9Rie7e~$ zM1Mwig*<^}zjnoT=tF6tuw5;AjAJeRY`2y?fzMj<*lumXgG;L8 zfY(9E%lLG&Uyeeaz_MSvVmtJqv{2ZtmORF>mVUNdOP;`IEqQFWw&1}f)p5Y)GCtkxm!ps; zu-9wnHCE3x(}! z$zvRA>1VsOZf(JX zORD35*Fnk4_;j;hjzXTmvR}JmJM^KnP}r`PJjSt>ezsdnp1@} zqmU=C?ANZ?4t*#s6t=4+k8!M}pY7I?C-7NI9^0)gcyLK|9Pm0Qc^RK>_RCSo6Ik|Z zS8Rtqlokrx)sn|J*3!>*YsnM%tR;`_))qXtq&g0G9hAI`PdEGJDC7w&`?V{!Lmx^D zh3#s|V;pPgXS=oJ34GR)$98KA9$Zo#2fPkSUdE@J{c;rY1eX2U72BZ?rG>(Fwd665 zwe+*yTJi)wYsq7~wFM6@sg46)2PH4#)6IT43V8y{e(j3w(1+4OVY^!L7{^-r*={X) z0-v?yvEAB&2bWaG0k4CSm+|RlzZ``;fn~pT#dhdJX`!%PEqRP%E&Xh_mOO#aTJqR# zZNY;}s^fsyLCMSbbhBTMLY}~~U%O&E^r5s+*shj5#<7-uwp&Y{z-KLaY`3=H!6nsk z!0VvoWqi8XFGnFyVA-!-u^swQS}1H+OCIA`OF!GKB~Re9mOQpwTkznL>NwzaQ1UW9 z-Rzg6kSDP0*RI$OeJCvywyPzNajd1E?bebf@L5Y9+pR5la7lF>@H!}Y8J}+U%TdS^ zSoUjIY==IS77E+dlE*mK($98l$rJdjC6Dda7CgA5Iu3Xpl)Q{jH~Zx%$z!{<1rIK%jsso?B`@RC&3-uwc>>FR?TYQthtfh}yIS%X$6ET? zZY_BNpS9$%-P(c&msH0AuY;18@#$v29ECiAWxsaCcIZQCp|D*od5mK%{cN|EJb}+z z^4M-|!GlYx!9Rie7e~$M1Mwig*<^}zjnoT=tF6tuw5;AjAJeRY`2y? zfzMj<*lumXgG;L8fY(9E%lLG&Uyeeaz_MSvVmtJqv{2ZtmORF>mVUNdOP;`IEqQFW zw&1}f)p5Y)GCtkxm!ps;u-9wnHCE3x(}!$zvRA>1VsOZf(JXORD35*Fnk4_;j;hjzXTmvR}JmJM^KnP}r`PJjSt>ezsdnp1@}< zd2F|~;K3!;alq@KqmU=C?ANZ?4t*#s6t=4+k8!M}pY7I?C-7NI9^0)gcyLK|9Pm0Q zc^RK>_RCSo6Ik|ZS8Rtqlokrx)sn|J*3!>*YsnM%tR;`_))qXtq&g0G9hAI`PdEGJ zDC7w&`?V{!Lmx^Dh3#s|V;pPgXS=oJ34GR)$98KA9$Zo#2fPkSUdE@J{c;rY1eX2U z72BZ?rG>(Fwd665we+*yTJi)wYsq7~wFM6@sg46)2PH4#)6IT43V8y{e(j3w(1+4O zVY^!L7{^-r*={X)0-v?yvEAB&2bWaG0k4CSm+|RlzZ``;fn~pT#dhdJX`!%PEqRP% zE&Xh_mOO#aTJqR#ZNY;}s^fsyLCMSbbhBTMLY}~~U%O&E^r5s+*shj5#<7-uwp&Y{ zz-KLaY_Ho`){zY*Mp<9hl?`NT)LYBuvZZVzo1xxJo+=y3CX%2|5MVvoLN-Rdu|%?! zJVjE}scb6S%TBTz>fNLzJIfrIhkBmuD|6)l*$4GLvZw4Wd&v%{caUvm7uiqtK)r`- zC;Q8;vLospWp5dhQ8^IxfifZEGGC5BeS{n;hslw0FzSP4N)D2?jG!Ko0U47+WC7|0 zGAM`3qzt1T#$`TTj+K*8pCrf2adM)ZiTX@AU7jOn$+J*DOHP%O*qve@$wk(zlP+uVD$+>dAJQwwIWu>f==gB3gFOiF6nOrQ3P%n~> zERhv*A?gcdp^f@8Dr*Dyz4Oq5gmg$K5`vUSr_v%N64FRZD$*?yinMe} zhlC;}5=w)VNJ|LPQUU^Vz2D3`YjioYzGtodJLf+4b?@i=zh_2M;FM@oG$)!EjfSJ6 zY0-jcakK)ih?Yf5qc5Tja6_~S$&3RkR2$isnU2qOYS>a8)!vS|2Ts z7Q%(mm(jP;)@Uc(8GRpp7ww1+!^6>m=wNgt+7I_fd!k*@zGw^F5`7bGi++f9!`;!Q z=uosh+6*^Gd!wJC6VX|CHaZ=hihho+!E4dw=t^`wx&$vp7ou~~#ppOZ9{m`djDC&I z!}HP6=xTH(ItGtLzeK-9ccO>zVf1@+FM1F;-9rf}1tLiFIQk=s=r+6^-H7f+OpoBB z=w@VeKe`2PMNgu5l#r5AJXB(Oik_zQFg>NAw3LBT!Bmujl2J-Z025FgN<^tCIZRG* zDIF!D_%J>_L(fuH$^moG^Yk3OKm}nz%18OB5aoq=DL3V$Jd_1yp^TJ`UZPwu7iFRX zl$|oe%=99?LdB>IEJG!!1eK<$uqsue%2bUizzS5J%F=686c(kIsW?@na!k zHRx?>P3@>N>`d=c2kJz(J(lSKBOV^5sic6Xf%zX@iYpKqLDP5KB0kdAoZoe^eK&iBd8yZrJ*zc4xo?e zGnzuP;4GR>(`Y6wflFv1Euy6~AI_(_G@ItpWH^~7&{SGLbKo4BNQ-F(O@fo?bNYf- z(OS5czM?PbYuX04(Pr90-_a(xi8jzW`i54*m9&gj)3>x9uBYX+mDbP-xPms)4%$rz z-~rl4d+7%{2~W~7I!>qPC_GAs=^*_`yWlSRp7zjBbO;`z?R0|n(@waPj?m9^o-V`7 zbdi3cU+FHqOSkAY-J_fECS9W|bc4>pb99<6&~J1VUZpd1hc3}sc$Tiy1A0Wl4^R<5 zA?8Fd5y$5Q{1nH9aoJfp4*x-l`kfwAJT`tz#`h^96F-CxDe%*roYTNGoRXj6)SL}w zl~Zw2n3OZ{3!IDd!F-&DU*wm#I4sUZ zxG0z4!muzG}Q zuEW(~b*{>l`E@P}%W_FB&u?%QScOY*Ev~?2U>UB)Z*c=|3Y&5xew&+cd)S`aa9i%c ztzau|!Oi#`t`F<;o7|9Fb9307>vB78%=KVBZpodvEBAms_0Uce`((OGe2c&q{8XTXINFc~P>%?2=8g$n%mGrj?YEUS5!_Fsr1J zT#`xBz%=rlyd(vr2rMEmOCfnh%ER(fM#{>oQVN!m;!;#fN`9DM@<>4`EyZ9l$t&fg zu;hdJq=ZzIDpCX1kk_S}yde!?L#ZeAq>2@DQ`+;SXo|^s`8f9g0-ZAG?402 z309Ii(nOj|8`wtPk(Sb0y1{PJS-Qx3(h+u)_R?0~m1eM+G?Et5N!r17(pb7mD`^Uw zN(cEsddUDdK>A7_=`SPUNEs%>HjF5iP1NM+1 z@~MoKNpO-(kn!@F%!PAhmduvVWd@ufQ)RMDmoadRd?Mpyrc8lTWR%R2i830FmT9s; z7Rw5_LYB!=`9e0p4YF3&$wpZN*T`yFDPPGVxJc&768TzI!BsL}*2{8P2p7ti@~v!@ zop7goFW<=yISdcW0XZl~WIx<5dt{gFlPz$Id?VZB2iXmG%O*J_+hsG{EPLfAIU#4^ zSvf7IRz6 zyWEop;(8Aysv49a>0|jrBE1c7%MH0JtdHO$xhbaisnizXam?lt7~(ut2JN^eOp^=JM9cR>$}=PJ85s&TYG3v?W5gc zckQNK^nGm$+v+>oUO&*Tu&cJxUfNOHz&84x_SZo=3=Y!|b%=hX0lbRZn4eRZ&Ysw3bC?WbdPs1ASw^ke-@r|2v=OQ-8JovBOU5?!c^bg9mV^L4Jy z)_FP^PSy!JRTt7OvH=^h^C(x4~_?S-0qSx(RO54Z2Rh z(UoweF4NWet*(dbb-8ZUHM#<>(2cr7ck2OoK=nS}7kLqDPs6Xm1 zxJ$p+J^GU#f`@dwp3wce6YkU_`m>(b%kZ*Z)L-;hy$kQ^ExoPx^d`Ki*Yt|s&~xyd zp4JQcn_h)i^^D%pOL`Wb)$95|AF0>_RAf(-EfGv)@hyQpWpQC#b5o0Bf2g8<*T)*q z%pR-ReNAX&58*=%_OvCpG%$^&v}Y`}WrNu)vt_a8EECLR=`F2gv}7=uCAJjytfhnL zEQw{cRF)JbwG8%x<+6M*pXIR^?IkM?i(3&ZY9*{NENlfWzrAcZVNQGAa@#9b02Z+9 zR?PBR4w%CVS!pY0m0%@%&0e*NRvXr~8dlTlSan$4s#;}x-O9qUR?^Db8&(BYu~Jsc zDp(m<#;Vy{*1(#=rq;;bwkFmdwzoFc);d@#*veX1GkeGC!}|87HMG{&95%PQ*3KGR zJy_3LS|{sjJzx)e-`=wiY%m;b18krTv3{_h^|qeY*Sf$i_O5la{?-fjvW_;$x?5-1 z+4|T=Ho`{3(e{abY@gaxIMpWEWSeFa;Y1r}V{C#Ahr{hd8)=`}SUA>(+7ugQ!{9I* zZ!>LjK4}^3>Zv@JXYw>KjX&ovc>ym1i}=f4$Y1gDu)LS? zvi_=F<8v=dO0ub`CvXT;T64#*MK$rb+6`ccthCG>v?^D z+v~!*UfXN>n_d}K_Sd|szvZ=HEwA7Wyt-F{mAsBO@#fwJw()norMLEOu$y=GF8-c( zgdM%TxAk|u8Eoc_yoGo2cCei{_O9N_o5H5v!9Va`J^&8zzTU_C`$#y_hxu^-*oVTQ zKG+BPhu#zR^!L5Df8>MUAn)!Yyr1`gJ$#6N>SKKpoa7UHynp6%;as2Pv;A|Q0cZGB zpX}3p3>@R1_&A^GQ{WUI<#T+ZkA|atnlJFhz5=fBWxmwE@C|T-ul04l(bvE=zS>v% zSH1`?@_D|*zxGvdmCyI}zT6kWh5n^~>sx&%-09!@cfP|9!^3{S5Bd?`5BK{X-{t#! z3*6%0_%{E+cf;Mj$q)H<-wZeVUjNBY_*rA9-|)N6 z;Sqe~H{HU0zXfmk6OR`XhNK}LDsgx!JRQ=*^dU`18#07cFjYtql7*BZ0Zb6$ghU~A zNDh;SxFKCg65_-7;hFGk$Qp9M9O3!!TzDZAgat#skUta(d12m=JLC*`LKc`MWDMED zOCcA`6*7eaA$!OSGlv($E1_5@1IvVxp+qPhs=}(FQm7oNg$l4jC?Cp(*FsTPG`t*& zhl-&bEEfugDxp*;0*i!K!yBPis0ZtXH$$E9R%iiRgr=ccXc-#A#-U-T9~y<4ux5BY z)DBHT1K1!`56wf}Py^NoZ->^QUFZxuhj&AV&?)qWy+e=CGxQ1FVfWB2bP4Z=wy4htWKA>pGi4vq_>!G%*J`E$_h|n*L4MW2KI3Ro+J_}RAEI2Dn57WZTummm%3&WzYG|Y$d!`v`C%nOs@ z>Xk<|7{<8pV&Sz|NGZ{>>XnJ#Ag0|jv2r|e|=-- z3HbHh_~-SXPyafL&BU(%%Kjz^_k|M?VqkH75` zoB5kQ|2KDuY4M+P8{{(nE87Tb-`Keg_A&XAG4K9kZWHqylaE;&#k~8E=a_uV_kUeu r@-gRsU1M@F-~V-u$;F)idF4ONgW_Vk pathPoints; + public ExploreNode() + { + DisplayText = "Explore"; + } + public override NodeResult Execute(Robot robot, double delta) + { + if (pathPoints == null) + { + int safetyCounter = 0; + while (true) + { + targetPosition = new Vector3I(GameData.rand.Next(GameData.layerSize), GameData.currentLayer, GameData.rand.Next(GameData.layerSize)); + if (!GameData.map[targetPosition.Y].tiles[targetPosition.X, targetPosition.Z].wasVisited) break; + safetyCounter++; + if (safetyCounter > Math.Pow(GameData.layerSize, 2) * 2) + { + lastExecutionMessage = "No tiles left to explore"; + return NodeResult.SUCCESS; + } + } + } + + pathPoints ??= [.. Pathfinding.GetPath(Pathfinding.GetClosestStartPoint(robot.Position), targetPosition)]; + + if (pathPoints.Count <= 0) + { + lastExecutionMessage = "No path available"; + return NodeResult.FAILURE; + } + + startPosition = robot.Position; + Vector3 target = pathPoints[0] - startPosition; + float distance = target.Length(); + + if (distance < 0.1f) + { + robot.Position = pathPoints[0]; + Vector3I mapIndex = Pathfinding.GetClosestStartPoint(robot.Position); + Tile tile = GameData.map[mapIndex.Y].tiles[mapIndex.X, mapIndex.Z]; + if (!tile.wasVisited) + { + tile.wasVisited = true; + tile.ContentNode.Visible = true; + } + pathPoints.Remove(pathPoints[0]); + if (pathPoints.Count <= 0) + { + lastExecutionMessage = "Current exploration finished"; + pathPoints = null; + return NodeResult.RUNNING; + } + + lastExecutionMessage = ""; + return NodeResult.RUNNING; + } + + Vector3 direction = target / distance; + Vector3 lookDirection = new Vector3(direction.X, 0, direction.Z); + if (lookDirection.Length() > 0.1f) + { + robot.LookAt(robot.GlobalPosition + lookDirection, Vector3.Up); + } + robot.GlobalPosition += direction * (float)delta * GameData.robotSpeed; + + return NodeResult.RUNNING; + } + + public override ProgramNode Duplicate() + { + ExploreNode duplicate = new ExploreNode + { + targetPosition = targetPosition + }; + return duplicate; + } + + public override void ReadParameters(NodeDisplay display) + { + //Currently does nothing + } +} \ No newline at end of file diff --git a/Scripts/DSL/Nodes/ExploreNode.cs.uid b/Scripts/DSL/Nodes/ExploreNode.cs.uid new file mode 100644 index 0000000..d47703a --- /dev/null +++ b/Scripts/DSL/Nodes/ExploreNode.cs.uid @@ -0,0 +1 @@ +uid://cj4t6w5rd0cv2 diff --git a/Scripts/Helpers/GameData.cs b/Scripts/Helpers/GameData.cs index aba0569..de2b9d6 100644 --- a/Scripts/Helpers/GameData.cs +++ b/Scripts/Helpers/GameData.cs @@ -14,7 +14,7 @@ public partial class GameData public static bool canMove = true; public static int maxRobotCount = 1000; public static List robots = new List(); - public static float robotSpeed = 5f; + public static float robotSpeed = 20f; public static float tileWidth = 6; public static float tileHeight = 4; diff --git a/Scripts/Helpers/ResourceLoader.cs b/Scripts/Helpers/ResourceLoader.cs index 1c5cdc7..6d32e0a 100644 --- a/Scripts/Helpers/ResourceLoader.cs +++ b/Scripts/Helpers/ResourceLoader.cs @@ -52,7 +52,8 @@ public partial class ResourceLoader { { new MoveNode(), GD.Load($"res://Prefabs/DSL/MoveNode.tscn") }, { new HarvestNode(), GD.Load($"res://Prefabs/DSL/HarvestNode.tscn") }, - { new CraftNode(), GD.Load($"res://Prefabs/DSL/CraftNode.tscn") } + { new CraftNode(), GD.Load($"res://Prefabs/DSL/CraftNode.tscn") }, + { new ExploreNode(), GD.Load($"res://Prefabs/DSL/ExploreNode.tscn") } }; return nodes; } diff --git a/Scripts/Helpers/UIHandler.cs b/Scripts/Helpers/UIHandler.cs index f02f1c5..4614224 100644 --- a/Scripts/Helpers/UIHandler.cs +++ b/Scripts/Helpers/UIHandler.cs @@ -30,7 +30,7 @@ public partial class UIHandler : Control if (Input.IsActionJustPressed("map")) { - map.ShowMap(); + map.ShowMap(false); } if (Input.IsActionJustPressed("menu")) diff --git a/Scripts/Robot/Robot.cs b/Scripts/Robot/Robot.cs index f9dac69..b1eced4 100644 --- a/Scripts/Robot/Robot.cs +++ b/Scripts/Robot/Robot.cs @@ -26,6 +26,7 @@ public partial class Robot : Node3D { isExecuting = false; } + GD.Print(currentNode.lastExecutionMessage); break; case NodeResult.FAILURE: isExecuting = false; diff --git a/Scripts/WorldGeneration/Map.cs b/Scripts/WorldGeneration/Map.cs index ec3bffc..1249557 100644 --- a/Scripts/WorldGeneration/Map.cs +++ b/Scripts/WorldGeneration/Map.cs @@ -13,13 +13,15 @@ public partial class Map : PanelContainer // Called every frame. 'delta' is the elapsed time since the previous frame. public override void _Process(double delta) { - + ShowMap(true); } - public void ShowMap() + public void ShowMap(bool isUpdate) { - - Visible = !Visible; + if (!isUpdate) + { + Visible = !Visible; + } if (!Visible) return; foreach (Node node in grid.GetChildren()) { diff --git a/Scripts/WorldGeneration/Pathfinding.cs b/Scripts/WorldGeneration/Pathfinding.cs index 319282d..adde9ac 100644 --- a/Scripts/WorldGeneration/Pathfinding.cs +++ b/Scripts/WorldGeneration/Pathfinding.cs @@ -8,7 +8,7 @@ public class Pathfinding private static Dictionary coordToId = new(); private static Dictionary idToCoord = new(); private static long nextId = 1; - private static long[] layerGateIds = new long[GameData.ruinSize]; + private static Dictionary verticalConnections = new(); private static long GetOrCreateId(Vector3I coord) { @@ -27,7 +27,7 @@ public class Pathfinding aStar.Clear(); coordToId.Clear(); idToCoord.Clear(); - layerGateIds = new long[GameData.ruinSize]; + verticalConnections.Clear(); nextId = 1; for (int y = 0; y < GameData.ruinSize; y++) @@ -45,10 +45,6 @@ public class Pathfinding long id = GetOrCreateId(coord); aStar.AddPoint(id, tile.Position); - if (tile.collapsedMesh == "gate") - { - layerGateIds[y] = id; - } } } } @@ -74,6 +70,19 @@ public class Pathfinding long toId = coordToId[to]; + if (from.Y != to.Y && GameData.map[from.Y].tiles[from.X, from.Z].collapsedMesh == "gate") + { + verticalConnections[from.Y] = (fromId, toId); + if (GameData.map[from.Y].isGateOpen) + { + if (!aStar.ArePointsConnected(fromId, toId)) + { + aStar.ConnectPoints(fromId, toId, true); + } + } + continue; + } + if (!aStar.ArePointsConnected(fromId, toId)) { aStar.ConnectPoints(fromId, toId); @@ -89,7 +98,21 @@ public class Pathfinding public static void UpdateGatePoint(int layer, bool isOpen) { - aStar.SetPointDisabled(layerGateIds[layer], !isOpen); + if (!verticalConnections.ContainsKey(layer)) + return; + + var (fromId, toId) = verticalConnections[layer]; + + if (isOpen) + { + if (!aStar.ArePointsConnected(fromId, toId)) + aStar.ConnectPoints(fromId, toId, true); + } + else + { + if (aStar.ArePointsConnected(fromId, toId)) + aStar.DisconnectPoints(fromId, toId); + } } public static List GetPath(Vector3I start, Vector3I end) diff --git a/Scripts/WorldGeneration/Tile.cs b/Scripts/WorldGeneration/Tile.cs index 139f13d..80fe4ad 100644 --- a/Scripts/WorldGeneration/Tile.cs +++ b/Scripts/WorldGeneration/Tile.cs @@ -134,7 +134,7 @@ public partial class Tile ContentNode.AddChild(decoration); if (!key.ToLower().Contains("gate")) { - decoration.LookAt(transform.Origin, Vector3.Up); + //decoration.LookAt(transform.Origin, Vector3.Up); } } } diff --git a/Scripts/WorldGeneration/WFC.cs b/Scripts/WorldGeneration/WFC.cs index de9c710..c19306e 100644 --- a/Scripts/WorldGeneration/WFC.cs +++ b/Scripts/WorldGeneration/WFC.cs @@ -181,7 +181,7 @@ public class WFC } else { - return fromTile.collapsedMesh == "gate" && GameData.map[from.Y].isGateOpen; + return fromTile.collapsedMesh == "gate"; } }