From 0f14ae337664f928431e6f759a1bb5e31c0572e3 Mon Sep 17 00:00:00 2001 From: Matteo Benedetto Date: Sat, 27 Jun 2026 20:19:41 +0200 Subject: [PATCH] Redraw wall/bush maze tiles with richer pixel-art detail The original BMP_{1..4}_{N,S,E,W,NE,NW,SE,SW,EN,ES,WN,WS}.png tiles were very noisy low-quality checkerboard patterns. They are now redrawn as hand-styled pixel-art bush/hedge tiles: - 5-color per-theme palette (deep shadow, dark, mid, light, highlight) - irregular wall/passage boundary with natural erosion - shaded interior (darker in the center = depth) - scattered leaf clusters and highlights - kept 32x32 resolution and engine transparent-gray convention A new generator tool is added at tools/redraw_walls.py. Run it again with python3 tools/redraw_walls.py to regenerate the tiles if you want to iterate on the style or palettes. --- assets/Rat/BMP_1_E.png | Bin 174 -> 1014 bytes assets/Rat/BMP_1_EN.png | Bin 189 -> 930 bytes assets/Rat/BMP_1_ES.png | Bin 184 -> 955 bytes assets/Rat/BMP_1_N.png | Bin 197 -> 993 bytes assets/Rat/BMP_1_NE.png | Bin 197 -> 1015 bytes assets/Rat/BMP_1_NW.png | Bin 193 -> 1063 bytes assets/Rat/BMP_1_S.png | Bin 171 -> 968 bytes assets/Rat/BMP_1_SE.png | Bin 194 -> 1052 bytes assets/Rat/BMP_1_SW.png | Bin 191 -> 1048 bytes assets/Rat/BMP_1_W.png | Bin 187 -> 991 bytes assets/Rat/BMP_1_WN.png | Bin 187 -> 959 bytes assets/Rat/BMP_1_WS.png | Bin 187 -> 958 bytes assets/Rat/BMP_2_E.png | Bin 175 -> 1004 bytes assets/Rat/BMP_2_EN.png | Bin 189 -> 959 bytes assets/Rat/BMP_2_ES.png | Bin 184 -> 947 bytes assets/Rat/BMP_2_N.png | Bin 193 -> 984 bytes assets/Rat/BMP_2_NE.png | Bin 197 -> 1045 bytes assets/Rat/BMP_2_NW.png | Bin 193 -> 1061 bytes assets/Rat/BMP_2_S.png | Bin 171 -> 994 bytes assets/Rat/BMP_2_SE.png | Bin 195 -> 1060 bytes assets/Rat/BMP_2_SW.png | Bin 193 -> 1054 bytes assets/Rat/BMP_2_W.png | Bin 184 -> 1013 bytes assets/Rat/BMP_2_WN.png | Bin 187 -> 954 bytes assets/Rat/BMP_2_WS.png | Bin 187 -> 956 bytes assets/Rat/BMP_3_E.png | Bin 159 -> 1034 bytes assets/Rat/BMP_3_EN.png | Bin 175 -> 950 bytes assets/Rat/BMP_3_ES.png | Bin 160 -> 958 bytes assets/Rat/BMP_3_N.png | Bin 167 -> 986 bytes assets/Rat/BMP_3_NE.png | Bin 172 -> 1034 bytes assets/Rat/BMP_3_NW.png | Bin 174 -> 1045 bytes assets/Rat/BMP_3_S.png | Bin 155 -> 986 bytes assets/Rat/BMP_3_SE.png | Bin 168 -> 1062 bytes assets/Rat/BMP_3_SW.png | Bin 162 -> 1055 bytes assets/Rat/BMP_3_W.png | Bin 161 -> 1019 bytes assets/Rat/BMP_3_WN.png | Bin 170 -> 941 bytes assets/Rat/BMP_3_WS.png | Bin 167 -> 954 bytes assets/Rat/BMP_4_E.png | Bin 218 -> 1012 bytes assets/Rat/BMP_4_EN.png | Bin 214 -> 952 bytes assets/Rat/BMP_4_ES.png | Bin 217 -> 964 bytes assets/Rat/BMP_4_N.png | Bin 198 -> 970 bytes assets/Rat/BMP_4_NE.png | Bin 211 -> 1054 bytes assets/Rat/BMP_4_NW.png | Bin 192 -> 1056 bytes assets/Rat/BMP_4_S.png | Bin 222 -> 967 bytes assets/Rat/BMP_4_SE.png | Bin 218 -> 1060 bytes assets/Rat/BMP_4_SW.png | Bin 208 -> 1040 bytes assets/Rat/BMP_4_W.png | Bin 197 -> 1011 bytes assets/Rat/BMP_4_WN.png | Bin 195 -> 958 bytes assets/Rat/BMP_4_WS.png | Bin 208 -> 957 bytes tools/redraw_walls.py | 401 ++++++++++++++++++++++++++++++++++++++++ 49 files changed, 401 insertions(+) create mode 100644 tools/redraw_walls.py diff --git a/assets/Rat/BMP_1_E.png b/assets/Rat/BMP_1_E.png index cb995c92be8a7cb34d6014a7453911b38d97f109..4f82a727409addb9f827d92ca5f2ef28f134265c 100644 GIT binary patch literal 1014 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`Xkf@=u(@Ni>i;T+ z1q=*sK>1NH8UiCF1kAh39s~Wl(bL5-q~g}pDHp{KD{wd~9{KEf6&L zz;T7=$UEkeYaZ_!w)3(pv_~JaTa$alE%9u^r+Uu4%w?IMO|@7LEasnga9$yMSohk; z*Gl9+FbFXeFWz&E@5Wx1XQv)+DN>h@bG4HQSCE;uZK84Y9_N28+0z9d)Hf7Hh1%P( VuyOCI*Rcadl&7no%Q~loCIFphWNrWe delta 158 zcmeyyzK(H%L_HHT0|Nt}$fR^2#S`EY;>ys#!0;c)Vfg?5f68B_zd%;3r;B4q#hlu{ zjl2y8JS_SX>sa&;ioDE>vG6vKW-Xp5n2{kMA`uf=b$_pBpW=M2>o(p89^9yKSJ?h2 zi?eh-OO`{@vJ&+JL0rzYCpG?yw9R?&eLh##>Swn4s^USPIk}5?{vA^=+5xiE)78&q Iol`;+08_>|g8%>k diff --git a/assets/Rat/BMP_1_EN.png b/assets/Rat/BMP_1_EN.png index 6f8e7bf3e7fef95dd45fd3d9ad4605b3e04d3418..e4d5d358f20ed056308fa04bc51d8381fe524e6e 100644 GIT binary patch literal 930 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`Xt23s!;r_Y>i;T+ z1q=*sK>1NH8UiCF1lCPobOq?wSWg$nkcwMxCwg)nFyLXm)h21b!PloF&?{Wv&X7I@7EGPBY&hx_jmY%=_>s lL{-M^o@-QCNpCgBp)w9ZX2GdX92h}?>gnp|vd$@?2>?*_I~V`} delta 173 zcmZ3)zL#-=L_HHT0|Nt}$fR^2#S`EY;>ys#!0;c)Vfg?5f68B_zd%-wr;B4q#hl!} zjl2y8JS_J+XA1n+hVgtFs)78&qol`;+0Co>Rl>h($ diff --git a/assets/Rat/BMP_1_ES.png b/assets/Rat/BMP_1_ES.png index 99862577b28552285ff2dae5e844c71be29d1234..2970915cf887efa9ee8c7c68d7df55c0ff514bde 100644 GIT binary patch literal 955 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`Xkf@=u(@Nyuz-QV zjbYXQRX_!!U^E0qNC+Ieeyj=T)iO^P$B>F!Zzl%w9Z=wKUOMe}d?lCO?2X0jH?khJ z*J?5?{qt+uo1<(wD~@bs*sRbX)g^O+#l(D})*l8BJ_ez%!fuRA&Vfg?5e@!_17a%L$)5S5QVoq(} zM&1Sk9+tlza*dgnmiRZSzR}h6m^e?(djpg5j)jgQ2|r$aT|T`}A;;h}bL>v;o;~UL zLJBXEIZy5RwXKC?#;gh3MHJR9eg45!Ek~d)WZ}N7srHKUFAin?`4IS?efr;CzmKhw U_o7xz3j$g1>FVdQ&MBb@00sj?X8-^I diff --git a/assets/Rat/BMP_1_N.png b/assets/Rat/BMP_1_N.png index 8e601e82986815a2a1e5cab21d87f5a27a9f1b6f..a59619dd14aaf0dd888dc3da1dab73de4e8e39f1 100644 GIT binary patch literal 993 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`Xkf@=SoMFE%^e$t z1q=*sK>1NH8UiCF1X@L)^===bGQJC|+n3q(RCN9S__~5|(qA?o$!RN(fa1i{)z4*}Q$iB}UQJ!> delta 181 zcmV;m080Pi2gL!97=Ho-0000E6q08E000b7OjJbxfB=AifB^ph|Ns9rs*Lae004AJ zL_t(|oNbM<4Z<)KM4v6HtC_;9&>|F3c?xRR8G!ni(eD@{D`biEE-e}aNcmSi>2&u} zy0V{Nmo@Xr7t%86QRwrrBAYy$+Ohfr89)i1ojx~u4OXMVs4ntAx*$guxK8MKb9&(V j!QIqGWecAvZjtm2&>$R*(psj400000NkvXXu0mjf(6&t? diff --git a/assets/Rat/BMP_1_NE.png b/assets/Rat/BMP_1_NE.png index 00d71932e57cd1bff61e01bdfa3e7ca7a6b02602..b7f21754782b56063a47099121c27bd589f0f070 100644 GIT binary patch literal 1015 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`Xkf@=SoMFE%^e$t z1q=*sK>1NH8UiCF1X@X~MsG|jS=!{os7AW?>|p2rR!V)?Pcd*!jIHe9yfFE7$K z!}sNa@gtrSk{9kU{$iT5JEiU>Te8gmt9Ji89{dh`bx-lmTHAn*KRRh^Q@g}vd44f{ W-OG8m-mt(46jPqAelF{r5}E+c!f06l delta 181 zcmey)ew1;7L_G^L0|P^2NcwRg#UJ1k;@Z&Az|g?J@E^!$`2YWZam$GnKvtori(^Q| zoVgbc@*Xk}U^!4Y#r__jz~AdGoO7%V_&+K2OT62B$!qacK9A{qIs4v)Y++Xod3`?A z$bANLU~$ak;Emzljw|BRR+qZ#P1q7=mQW;e=HxJ*Bbe9 h($;zwqju%>C#CnzR9BH-`C=W&A)c;&F6*2UngEfGNR$8o diff --git a/assets/Rat/BMP_1_NW.png b/assets/Rat/BMP_1_NW.png index 92b6a64243b9c9cf3378d752bdcc62c0cbefac29..ce5d17aad0780310b541418468a08f2f16da47f0 100644 GIT binary patch literal 1063 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`Xkf@=u(@Ni>i;T+ z1q=*sK>1NH8UiCF1kAh39s~XQ$kW9!q~ccVE7PAj7a!t1 zDiXLtx}x(#HB6r3;9qI#c+06YxDOV7k->-UMkOaTUWVcyQl3nYmN*iap^r` z47=@%HYfyTFa|XI*rl7EZhOfo`KQqO79*##Li*0EKQ#_Ba)dp|Wlfvkb>yZ;zKG0$ z6EZq7cE@Mvx(62-eAaAoKlfd8a;JN&l5^!op~in%4pS`{#DDc{@O%Z#hG^vPwwAUE9X_zvizrfNd8|c V=ZV|wdzXP?*3;F`Wt~$(698Jnf&Tyi delta 177 zcmZ3^agcF>L_HHT0|Nt}$fR^2#S`EY;@Z&A!0?}e0Z9D+AAIvmA5gr&)5S5QVoq{G zLPBXm!h@`Yqy{F7=GMkWNAENBt2LI12s2-Ax_(f)PX2%zD{D`WA`cJG8pib-S0$Em z{M^gfeX=Li;T+ z1q=*sK>1NH8UiCF1kAh39s~W_?CIhdQgQ3;L~p(W3LGvo8}I!;CCa|m(|7laZTcVC zl^-U5`@ES!$nU^~1z~c_o?eq(6m#p<(J$^U=0{zvmS!`#8GI{YthJGBk6@XZvRfuv zi^+~NvPh$W8 delta 155 zcmX@XzM64@L_HHT0|Nt}$fR^2#S`EY;>ys#!0;c)Vfg?5f68B_zd%-$r;B4q#hlW< zjl2yGJk0MW+Bhvs=yyu#|1NH8UiCF1X@B}Rh8)gTplxCn9nb;Q{eV-?k_G=Qybc+3pv;^S_RAsVwlfh$IvU371g`5`MB*_gA z!iN|#d(FHa@U!bV6dgzt)^}`*;$wKff?XiCp}5wlETi=_=$_ga)>Dy(>lsR!rdiK%|G>89-oh7MuGvxX4dJ}C zLbWEPe7Sya4(6uGeFzjT>%4vS$zGj#_buL4c!;ajp8nYOkMYre&Y2I*UA;lk>FMg{ Jvd$@?2>_@%dSCzm delta 178 zcmV;j08Rg#2*Lr77=Hu<0001iRA#7tm#|Czi3wSiK(i3~(x!Q#OKfe(;#0PSeLW(i)R zQ;1%V7c0qG31*S8L6(5Xdu@~3MWUU*N#q=i;T+ z1q=*sK>1NH8UiCF1kAh39s~V)+0(@_q~ccVWNy9#3LMV42Y<&`HheZdF4Nh`d7epD zTY+I?viSaKwk;ELA|2u#Hm>>Bu;=r)Fm;C%u2rUo8kVpZFq$xO{TF#BWWzXZ$&HO_ z+?(Xy3njW)GQ>4W9;ljisMdx#c;PaJJ7(#;K0MdWWuX9u_*VSOFB3p00i_>zopr E0Qwwo$N&HU delta 175 zcmbQiv7d2*L_G^L0|P^2NcwRg#UJ1k;>z%!fuVt+p`igN@c;k+T?>oNfUIm!7srr_ zIa4Pb!@-6Q!)FFwk!_!Z~qcSq#1s1 bu~C+nFp}~#TrRj9XfK1OtDnm{r-UW|P7_1I diff --git a/assets/Rat/BMP_1_W.png b/assets/Rat/BMP_1_W.png index c0b8372bb4e724689e1aee7a6b0df5b96ec7fd07..b36ea24e205db6229cb2fd0b058d53d08e08a9a3 100644 GIT binary patch literal 991 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`Xkf@=u(@Nyuz+FJ z|5XfbK>1NH8UiCF1SHy4egpb-mZytjNX4zGlLLiX6nLCHqu$r2Hcn(z-LiY`MfrJ| z!kGs(Htpj{)&7=TKTnq7uG>W!uLEj~T&=$zUR^D0eSw9IVWC6MXSN*~jCu`4k+D7v z9#Jb~Y8ZWZf3j^kt3B(J`hkB8A(P~o8Il(4VVqd{S6uArg-vNPB9DH5V7w$9YNRl; xQRu^wXR8V}oZM-7^3`0CWA~UWn6~n3G)niVvpzDFU||Qvh^MQc%Q~loCIIW2SGE8E delta 171 zcmcc5zMFA^L_HHT0|Nt}$fR^2#S`EY;@Z&A!0?}e0Z9D+AAIvmA5c8Y)5S5QVoq{O z&lkI2vl_3?>SW}aAhF+kPa4mUTG8&142I?x|JO3E-}thL$?cc`8xUM$kjau@u3LXh z?WokN5B1p%8hp&o*Aj}gk~NrtVDV)+RP2c$R{9_|rm Ui`2OE252pVr>mdKI;Vst0G!T2$p8QV diff --git a/assets/Rat/BMP_1_WN.png b/assets/Rat/BMP_1_WN.png index d5c7822683c16497367fc3411a6f414d2227514b..e4e90beaefde11761096fba2fa1dbacd0b3210a5 100644 GIT binary patch literal 959 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`Xkf@=u(@Ni>i;T+ z1q=*sK>1NH8UiCF1kAh39s~Va<>}%WQgQ2Tpd;S_1s<&}|Nftrw%UC3f!&5egJl9P zQX3f<1g(U2t*;4q>^M!7g{>>H)JrDbyyviPMz7m~l1EmnIHoVOsGQ$;x$*V{OW6(X}8omhT6%-Ob+3^^L0tAP1hGbkG`py>F>mEhTlt^b>+y9e?Qpx6fZNaHvQ!h P2numeS3j3^P6iK1g-zStz$OUQOgZ{C>5?7UN&} zTaPX4HgzzmVAhLWv_5j9)l|cVho*<~bNpNl{^ci>CaCcIsAX9F?LK>xxj{#g7bC;} Xt8y(|e&6eW)-rgy`njxgN@xNAZ&^Z= diff --git a/assets/Rat/BMP_1_WS.png b/assets/Rat/BMP_1_WS.png index 7a7614a51f71e0a283cf1bc8bba94bee8c63d95c..025a914111fb8e0746af0d17727ef47f1535d17f 100644 GIT binary patch literal 958 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`Xkf@=u(@Ni>i;T+ z1q=*sK>1NH8UiCF1kAh39s~Va>FMGaQgQ3;L~gzV3LMUviQo5sdX+wV<_o7)}Lz-@tTZT8Z}Ww4Kj{Ud#x(xjtUqLy~FH*L!ys#!0;c)Vfg?5f68B_zd%-&r;B4q#hlu{ zjhqb*0xaKK-X2(eNXYKzohMBDJq|wL)j24%=8%xy1qZ<+hkM1^QrVLlBrZHS7o0L< z#;u!7C56fV7KH~M*q-4Re8I$mb;gzHA`2dcmb=+8ecP&X;Cj6L`l^t!#`76xk~nJo X3=WHAys?fd0lC1_)z4*}Q$iB}6eUHo diff --git a/assets/Rat/BMP_2_E.png b/assets/Rat/BMP_2_E.png index 95246fb3fb22b7499a35e1981e6e747e799b1397..6bd156845ea25a672c519d82eebd2f55446234b9 100644 GIT binary patch literal 1004 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`X!!6Ups9)B|Nj#w zPB2780p&-*Xb6my5Lm3=zZ~e-<(@8%Ar-gg24CbmqQIlI=J)@2yN~B`4I?(cp1hG| z#ng_K4ikD57BWAt`;gH7rHOgV>&4~9#f&Fb`^2lcNx!r)5uTZ@Z+JlC1KX2R&a4f~ zEb@5|HynJxsK_~mXN{y9!y2cP4a~V*A@4sZM0oyb`>=aP+YP2i_H7$=-Y}fiySILJ zg6_ux%>!DSh_NMl1)%G86?*v7U Mr>mdKI;Vst03%Fl4*&oF delta 159 zcmaFEzMgS{L_HHT0|Nt}$fR^2#S`EY;@Z%_@c%!M10?_ZmO6$3S#h2&jv*CuYWp?{ zHW=_Q-`{zeBeF^J(&Zfm(-O?M+!Ey77A$r9oV z*C%b6=dplIC1s8E#Ars*uPr@41tf}^?%T3n2|HW;PoiYQb0+7rytbW7bq|1S^>p=f JS?83{1OS(PKQ#aV diff --git a/assets/Rat/BMP_2_EN.png b/assets/Rat/BMP_2_EN.png index cb263cbda0e95b08c28efbbf9c875224d02412ff..431b79019dec11a5cc19e0844dd503eaa97be841 100644 GIT binary patch literal 959 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`X!!6Ups9)B|Nj#w zPB2780p&-*Xb6my5Lm3=zZ~e-Do+>3kcwMxCvx*O7;rdimVDp8>4BMe@>S-H$$t-d zHzt02eY)wV@q?8uGL_d}3$1t1JmxF0!Dh~vyfRgfrriw&ygr>Gkt{cN2{n{OG!zv) z;+5bFUBw_^5!7JLH!*Na#`Xh$*l)W1XYW}m>v#FWFVdQ&MBb@0Fez+e*gdg delta 173 zcmdnbzL#-=L_HHT0|Nt}$fR^2#S`EY;@Z%_@c%!M10?_ZmO6$3Svj6Ajv*Cua{D&& zHW=`*-0zTA^xnYK`&(p3$8ncMp8khTHZZzo2xx9tJ>Bnnen;S41Kx`F+{!chC->Pi zIfy#{TDjAHqc5?vs)*$_o6f7*4*!MFE(AVY`w-@ Xn=JZO;?o^xkQ+Q*{an^LB{Ts57UV)e diff --git a/assets/Rat/BMP_2_ES.png b/assets/Rat/BMP_2_ES.png index 65de7b07687854e71373d1e07868167da20cfe9c..85dea394f2a13f0dae8defe576426c708b124885 100644 GIT binary patch literal 947 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`XlQC;`0yd%|Nj#w zPB2780p&-*Xb6my5SVFl|qfX2Q`HqLMgmE)NiN- zn07^~zIP2%UY4MgSo(0rhFO&rt;y~jmMbP0l+XkK DCxJ*z delta 168 zcmdnYzJqasL_HHT0|Nt}$fR^2#S`EY;`;wTLqh|Q!|?zAe;w(vdq7sYr;B4q#hlu{ zjl2y8JS=}b#)n_XZ~A9Sa>r5`Mh;x_o+{LXN>{=GdLwJ$usg zg%n;SbDrAsYg-G)j9C-5izuvJ`uu~dT8=~)oyg7CtjN)<+4?)a(njs_5qs+c*Cbp& zUDW7sU|ggkdEr%u_o*f4#Vi-Dl~VLsxiz40YPL~;vt&lsZ9A^>3`#HGSsh@nvR7r= zuca&XLA~MYX66f%HQ4h!f3e<>xw4;OxrIZ0Zv9^qri&-No5TFmR1S2m4`cu(C_7_oVL8tVvqoh)aw=p&@PPJ~~4QAv!qQJ43_5c5;vo(Cg?@UrYy(~yu z*N>%%BWbSVZ*Qfm@~kKABofUJxHarMc_n?1n8Ku+swZwd8Ryo#S$5>Cun?lNa@ zGv(XtFZVt<_kkz;=+d_Ic@bSMj0gA zlV4r;yDgY-hV8l=?~$F6Ki_W(+jzh4kZ1hU9eo$%OAm3*d?zFN2^5c>u6{1-oD!M< DlTLg} delta 181 zcmbQrag=d_L_G^L0|P^2NcwRg#UJ1k;@SWL4FCTF`9Si26whjqib78p$B>FSb1xj^ zJ!Bxja-eXE{XIT`zt>$j=U5x?e^Tm~c(?hI*W#&s9@F`9_Pq<)!mb+f`h2L7`wZs5 z;+V<78^gUFSH!2SE_K(NuqDpO{h5Mx%6Xjt7rn~0YXjESKPdbESUx(hHS*=8t@SKM d?aJ#}foy;iIqQK$$u=)G`PfU{%H@(#f4*PM4 zUt^=>0iACO9LLLhM9gF7y?nx?<0D$=yZ+Yh9m^cUdCYx2LeyQo-fW zOPezchP)Mw2E{WEc(z_(T@ZW7Wf|LB(-f8((MZ#tS@FwiLWA;e{?eGjtkIBm)b!S~ z$S7Ht_dho6YPq$B-C>5Y3%h{fbj4$~huDskyq$Wwo+;$=mN!4xAH20~49%L%u%+Q1 zL*Q<=+;jIE-k#=tP|kaoYsTN+_R@8Xrw+a}EqK?M87n4}Zf)*lFJFCN{p24EQdOLB T9dZmWLGkM8>gTe~DWM4froMqq delta 177 zcmV;i08am<2*Cl67=Ho-0000E6q08E000b7OjJdHfPnx10Dyo1|Ns94ChQ#m003}F zL_t(|oMT{MV0B<%;A&uEfC4y!g@J)VOU!?(D5ew>1J{Dr!5e-bz$OI+jEo@+3=FIR zud%9ObqM*r0gK6uVg4H!7(;#^#crVJYX(+pECw!1zjm13x3cnUhNWxmI00000NkvXXu0mjfXp%yV diff --git a/assets/Rat/BMP_2_S.png b/assets/Rat/BMP_2_S.png index b6d2dbe95103e796618f0605c48b5a1eb80dd2f5..2994804c0b4831ba1a58bd0d5560901ec03b541c 100644 GIT binary patch literal 994 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`XlQC;`0yd%|Nj#w zPB2780p&-*Xb6my5SVFl~)4P+E*HsEMx`Tzf^W7MkG*Ti!!2CGP9 z82obiC&sq~frdMujT*Pj02uiyhnt1p3^K7OC88Lz( z-5sy3uQ)MDH$GeKD)(@SK=8vWPJb*|^KPb3DZa<0(6uOIRnMcfx)*nDkK8CS&40$i z8V&cz+ftXeByJYSHQlmVIiYxNq-7XaZ1UBwb&ReqY#f4#d#XW^;_2$=vd$@?2>`%k BVgCRC delta 155 zcmaFFzM64@L_HHT0|Nt}$fR^2#S`EY;@Z%_@c%!M10?_ZmO6$3Sy7%Yjv*CuO8YkQ zHaPGwzn^I1v@D^sXTqb+B8wHSC8$bCNwGLR363m0$EWa~Yxa)kf?EzmO$!VEl^%R& z!2;#=1qLF{UXg)3-i&LeH?BW%Vb9e6Tc#G5_dU&z6><0Ft?Yel^8#d}r>mdKI;Vst E0RKunP5=M^ diff --git a/assets/Rat/BMP_2_SE.png b/assets/Rat/BMP_2_SE.png index 23ef874b9cd045bbeefb9be91072001e4b11c9cf..b29a2e8f8dd0769bfbfaa5b88e1f657dea2c99da 100644 GIT binary patch literal 1060 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`XlQC;`2YXJhYtZK zPB2780p&-*Xb6my5Kx^I&kywLeNPw1kcwNalevXj6nLCxx9$Bub-Sj$=!L#_Z!V-a z_0F*6>eFEMIKaD&Au`8YjG;u#qb;tiLFCkm13At<4IB0z()Z^2!BkO@ap0J8oZhs} z?_VXaUSKx+xS+shR*OajzS%kYirn>^1r9ux`0;sz!ak7%)0n6_mYD_Y7K}Y#rWVh> z9C9KeI<+O0^;OmXNXEWDwI;#=VjoT`_sp=fS?83{1OU@wegOag delta 179 zcmZ3&ahP#}L_G^L0|P^2NcwRg#UJ1k;@Z%_@c%!M!_d&s@c;k+H<@}BKu*4=i(^Q| zoT(EpayA(7xZD?Ie_`3U}foy;iIs=(orc<^`p&*lYzS!b7LE<1Kz zPuEL^b+_g^_l*iOD;BUOv{udJ;5!hSaFc26)_{x6uBVF<6a~08?hBS+@NlfF;H#HQR@vE=N^=`Wk}WAz&TZ!KxvR%buCHu%8eldK!mtQw39o^DXz<#cjc zjkG6E>%V!NjH+Hd3y#MX%emjuRrp+EuhnOBe5ERn%P%e)=fr=EyH9hTx$1V@3lyQA Lu6{1-oD!M<<^pL_G^L0|P^2NcwRg#UJ1k;`;wTLqh`)H2?+v|Nno?^lJ=|mFwx^7*a83 z>V$*5Edd;??3-CXSQ*@^_ulrQj=jR*U1F?qQDsYt1QUaRRq>R+i4MK@5``AnY)Xtw&~m=8{m)&-bql2qP25{Aag^(T d+1c|a_>7h1)KB@(JPNd#!PC{xWt~$(69B^WN4x+4 diff --git a/assets/Rat/BMP_2_W.png b/assets/Rat/BMP_2_W.png index af5d651320fc8d5c72dd43a8927db352f66f664c..c15527f58bb7a6e5235c4ac0c41ae8edf829f9ca 100644 GIT binary patch literal 1013 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`XlQC;`0yd%#0iG~ z|4&3k0p&-*Xb6my5HNd^s|fV#22U5qkcwNalf8u+3^<$>mwey9DderYukPYt@qDKx zNB-#S*!gtw{BK(MqSq7U8yH=#Mli~iD>^Zzd}#`C@S3tYh*2%-OoLil12?P4G!w}~ zhn*c~W~c?;pHQ3-tg(>sIKv0l2FVF(%f$lJf)k!A8i+m@hzdzFGtZU&9EUf)NnZASymRb;;#k9(jh=VGo0q zPZ_0C#-mJ0;AWMsy;jHwU_%B#8Mijs20hPIj{8pl$(^(W{JS7iJT>BYfH|vK4I0emw&{R-p`cv`RMd+P+)ty L`njxgN@xNALDWsD delta 171 zcmV;c0960F2fG1~7=Ho-0000E6q08E000b7OjJdHfPnx10Dyo1|Ns94ChQ#m003%9 zL_t(|oMU7RVGa1d(fcS90~8<_p#co9*LrW&#*|_VWnf?k*%G)U?dFqeE_TW-v@#>FoN_%me4ya= MboFyt=akR{04cyobpQYW delta 171 zcmdnPzMFA^L_HHT0|Nt}$fR^2#S`EY;@Z%_@c%!M10?_ZmO6$3Sy`Sgjv*Cuk`s6m z5`b7BHK~EgqS-KoclFj2#~9drG&^b-Rx>XX;c}kR`0#sZ&aFsh7s&|b4Uwk~9LUoB zRlV9&Y~_Xf(k}6vlZyG3nOA>r3uwFV{&Cmy?`$d;|4T<~-MAw?6==dY2L=ZB-6FLD Sq4!!rF7R~qb6Mw<&;$Vb0YE4K diff --git a/assets/Rat/BMP_3_E.png b/assets/Rat/BMP_3_E.png index 4aed5e00b4d161b055ddea68188d3806df8a2921..a70d235091969ea3e6d653af2a01543256223a17 100644 GIT binary patch literal 1034 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`XxOr4%m4rXzkdCC z=gys;o*tlrQ7{?;BP0a+%9YLly?WHs#WAGfR%>vyP>TVN(S&>dPt9%*bI&xlFID4F zOz3+YD#j`#7Qf`?ZvNL+@pTNIj^*pu1v4~VP45(3sc5b4#4thFZ7LfJqdWr_ui=7U zIxC}`zaF$*Aj$Xiueve_6b8Mk=ov+*styzQdJ7cmpRUdA6*mF^oa z8hlGEWLj~^i)~BW#t#ouJ{*-=+xXh{XShlgi+SV^W$qL8o3=aro1`{(PNBE7T>Ik7 rDe}Iy-M7~)?tRT_;=EgTe~DWM4fhpTSS delta 142 zcmeC;n9n#tvYr75!UR<{fK-~Ni(^Q|oVCG@Tn7v|yidzLyIeEN|Mo&>Z4X(KOU~Mg zhHZST*E)p`{4u;3!YyI(u~=mb;~noU4eIN5JC=So;dFc!o?omIWY>9LBQf%%{5lT3 ttbgmhBd^@wp!DB_A${`K?MZo`Smk*n*ls^OUj?$+lik(NWt~$(697C)HZK4G diff --git a/assets/Rat/BMP_3_EN.png b/assets/Rat/BMP_3_EN.png index 8a073cb01616b27926109efcbe79cd29dbdcd536..a8a2913009a688b84aa4955b0d94fe6ccc0466f2 100644 GIT binary patch literal 950 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`X!!sC|CTLVzJC3B z=gys;o*tlrQ7{?;BP0ZJUZ~y#dbQBg#WAGf*4v4(dp)m-n`v~QRYD4lP?X~WkuPpo|U0_tS|@SB1`Y5L2{8<2Y+NH z`bcL4TSe{og)ev?C!;=}3~0WOQE2|S-_xkmKRNT~7blnen-{y24?e{p{70P)R{#J2 M07*qoM6N<$f{vd;7XSbN diff --git a/assets/Rat/BMP_3_ES.png b/assets/Rat/BMP_3_ES.png index 6a37848f60d2e1b39bdf1b1634b2668e4d291b9b..488104780b56e02343ddd10dc60a5b952c67bd9c 100644 GIT binary patch literal 958 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`XxOr4%h#`8|NsAg z=gys;o*tlrQ7{?;BP0aGe`&b^y;|w%;uunK>+M8uu>-(N^0V^4wzx_eb4BB{@VhBI zCIWxI9(>e&C{n4ebU_|#Pe?qrwIn|{9+QnZP2PSg$RU diff --git a/assets/Rat/BMP_3_N.png b/assets/Rat/BMP_3_N.png index 6a9f7c7aa7356d608e98e270e66402fa4f90b53f..2bac54b0e9ca404cd7eed278d306c11d795c2875 100644 GIT binary patch literal 986 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`XxOr4%h#`8|NsAg z=gys;o*tlrQ7{?;BP0aGe`&b^y*ky?#WAGf*4scvp~DIs%8GygPiKF$;%<)ohUluU ziy~7b5*7$bGKOg!`>{r&Q}m66h^wvo(_1gMs_*HC6kf$y;f~ tV*UQM@V28q#V<@QJ8e9C_M5zYzxcm3tarLtPP>5O!qe5yWt~$(6975PUNHaw delta 150 zcmV;H0BQf)2d4p$8Gir(0034IB`5#@0B%V{K~#90t&vL#z#t4npT&FSXp)=NleHU_ zD1wDfRwl@N(?g#M7Ty>*TpZ^3Ay1GKmqSreMEPxTpg>hnoHgtPl(GD$NNZW%{WWHF zSp(n3Sz6WxUlLSa`?u&y64a-%rv8y9nQpLXOP}Nmg9RrE!4IF^XaE2J07*qoM6N<$ Ef@(@V;Q#;t diff --git a/assets/Rat/BMP_3_NE.png b/assets/Rat/BMP_3_NE.png index 0b2e91366c35bbeb4348af72737ab921bf1255a2..c18538c57947a4fb376f730ac9ab9f9f7cbac7bc 100644 GIT binary patch literal 1034 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`XxOr4%h#`8|NsAg z=gys;o*tlrQ7{?;BP0aGe`&b^y?WHs#WAGfR%@`Q&;bPw0XmLa?$6| zB31`YR)wy&7cMy4Z?Xt5Z(@*@dBl2E&Ob&-q64Nd$`-|BSlAEm|C0G7{ezKBhX{|Lk5u)m zg){HIxt8j&f!QSb(LFOYW7~qA>vZ>fbS-Szbxn{%Oz1N6c>_#rQgx^rRNlv>C$tMad-XX;{&8@ue%WosWo@~!Ej@NIQNW?VyF1;?$ z*pn4_YZ}uI%Mu3}hpAmW2R`k%p1=^v_mAthn23x`&(u2}o0ciub0~SB!0yF%Y{iB2 ztHm4*6PB`1I3MpceebL3aSb^R?>;^Fz@5OD;roV9Bk_-Y^o#F*cw=M@vJY?`u*fxA zRV|(r?ZC$;G}*>N!k}JyOL5(eq`8xm#Ut-Cd^3~(^qBKa#S4$!plI}T^>bP0l+XkK D-|~7G delta 157 zcmV;O0Al}@2(AH;8Gir(0034IB`5#@0Ch=3K~#90y^=W&z#tF5!`y_EUsKhVY+!dTVxtYgWIwH82JEYKl~hN#`d00000 LNkvXXu0mjf?5;xn diff --git a/assets/Rat/BMP_3_S.png b/assets/Rat/BMP_3_S.png index e0079b23c53a43c960256bca009ec2b3bf829ebc..7ac628d782ec0ccdf986d5920196cc0c480ce66d 100644 GIT binary patch literal 986 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`XxOr4%h#`8|NsAg z=gys;o*tlrQ7{?;BP0aGe`&b^y*ky?#WAGf*4rRXp(6?$%?tkj|5TKn`@1Qxt&rjJ ziNHnn`?$)i8T59z=W$+&aoJRC#H`YJ+$nZFgWCZE>9Sqjep?QetWaKRI(I#j^+OlU z53LQ_j@bfr;TPN<^`W4txIv^Xg10Dm!e7n;)7qq24rdq*m$E7x%9*@fb2s<7 t^NTv~313@RRqM1)aijUF-f#X4{}@dqS${5nVEZ2w7oM(uF6*2Ung9{*Ux5Gs delta 138 zcmcb`KAUlZWIY2AgbAu@0I4KT7srr_Icp~!m8I=c19+;;(_LSVXx(--=JW zaMMWQ!Gk-mcnUUL_|&xblc`|go*$xK-~KC?SzFXLK1&tM-G8RvHnl&r@>8gH)H?Y| qe5TK|+kbshXJ<|EKKFA{hwygnp|vX0p)p$P!)JUMp& diff --git a/assets/Rat/BMP_3_SE.png b/assets/Rat/BMP_3_SE.png index 7c232ea314548bf7af92939ac240cc4cf7577af2..e5e7bca15a84b8674d23b3a8dfaa7c4d8d9983b3 100644 GIT binary patch literal 1062 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`XxOr4%h#`8|NsAg z=gys;o*tlrQ7{?;BP0aGe`&b^z53A8#WAGfR%`anvP4sd_D60KYyF!3ooi5M-Zd$d*-j`i@=;i; z*ECCUMZx?0?uz0|tFG>_<34E_vi!3pOGos&Z6Z52CnxOOX~48+rfJds%QEY}Kj2=# W#M#aE`Og_pyn4F&xvXbex@2AVuz9UuoZtw=>FFr6%|R2@MGN0846e4 zM$g+&Tfph{!EVjJZ_2^HlI8E5HCbP0l+XkK D^CCPl diff --git a/assets/Rat/BMP_3_SW.png b/assets/Rat/BMP_3_SW.png index 38a5718a392b762d81bdc0a53ee89d1da54dda3b..e3434c5d4711c09ee38ff9f741f83cf38ad2e7e2 100644 GIT binary patch literal 1055 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`XxOr4%h#`8|NsAg z=gys;o*tlrQ7{?;BP0aGe`&b^y?V>j#WAGf*4)Y5e1{Dz7wr1rPb?sDWC)_GT7czR@?<=lIEbMudbt8R1rVK`w`qHq15*@4laT=XKN zxqKaCM#O>8Wh;3Y!WrTjSsrxSqQQIKh{i%6#KjMi#=EP%{a!bcC}9|4{uG8|8-DT^oD$+-n!%r!S6|W z=N=wxU^|dn7_jye+pE7{QgT-63;o%Y(-CarQN1TG#qW%{^}VSp%NFxnuj6dF?_^dB Oicn8iKbLh*2~7ZnmVz$; delta 145 zcmV;C0B--E2%-Uy8Gir(0034IB`5#@0BK1?K~#90t&>3tz#t3+$I^%8X?a?n){BKC zt>|F`!Xh$RH#!0W3?QlCRTrDu9=QMcbITMhMl{!j?}`?u9(ozzA`hQyW^qK=537XN z`RezO`97C;7Mbto1Wl49zhWR%E!KR=&w2od{TPN8NnwQm015yANkvXXu0mjf+EF@? diff --git a/assets/Rat/BMP_3_W.png b/assets/Rat/BMP_3_W.png index 77144cf01ca204900436123da9bbc4aa2b9c0f02..8648b42d9f43de89de398b7fa803d657ca947ea5 100644 GIT binary patch literal 1019 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`XxOr4%h#`8|NsAg z=gys;o*tlrQ7{?;BP0aGe`&b^y}HfQ#WAGf*4$ukA!kL7$qw)9pE7;QTFy2%Q!KAT z@lP8ILtw{>89nhSFFVdQ&MBb@0Aq)3jQ{`u delta 144 zcmV;B0B`^M2cZFw8Gir(0034IB`5#@0BA`>K~#90wNgP2z#s^#%O1wl_Ow3Dg9A51 z;*1?9NJv{~%LN#`=mX*1fk{ml3R8S*6jV^00sq3c)=4NnX^8u}0LCDo$nk$ND~ivE y$jr*{Wsl17m5*A{FvcFDOx|Yovqs8&iVAm19m!$VJLUiY00{s|MNUMnLSTY0k3CEP diff --git a/assets/Rat/BMP_3_WN.png b/assets/Rat/BMP_3_WN.png index 4b938ffd789e5446467fad9e851d9d19a409cc35..18ce0cad1045a2edd820aa2e17bb69e82a54b194 100644 GIT binary patch literal 941 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`X!!c|>y|BB{{R1f z=gys;o*tlrQ7{?;BP0Zz#E)?Ty_(_a;uunK>+Qrqz5@yz&d~>c$5#r8Jy*-xlz+e7 zaA~8~0d^)Orp8~M2OC061NJX14PD=!ZxC`*&gAU|KIaiq6qqa?Un(fVhFu3Bef$7iB2yIKNUb-k z!_&x?mXb~Od!YH@Z7cA?<7;sgE-Jf8Gr+o!-^?+M8Gz6Jvhmg$WD|EFfIHj5GxKL2i^ zNvhN4ZXWNQn*5*EEnmZJEfU4q-{F_?wY2H`v6Zj5;~2JbMu)$yXV}5GqRdb|;OPf8 zfjJJDp9@ZI@Z>Zo)@XQR)FdYznY-&?Or&UObslR7OQo*w{<=(d2YIH&hAcihps@CI L^>bP0l+XkK0ai=F delta 150 zcmdnRzMOG_WIY2AgbAu@0I57r7srr_Icq1K<~^Xm<18P_o^0ZFI>UC0CyNs=`*W8i zC*3<@~37)QgF6*2UngI74 BIw=4E diff --git a/assets/Rat/BMP_4_E.png b/assets/Rat/BMP_4_E.png index 94dc0699e82a2f564ff4cd84699d04e0707e97f6..d47f494fbd45d497f224acde804626dd92d99b0d 100644 GIT binary patch literal 1012 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`X!wv9HBD0Tl9AE> z6I-Hy(xYHB1V&54oWS*B##4y;$P8`eut$nd%)=D^@E8o7$$gYwo>On$~(%Z=G#}b?vl-WUf5h zhWm$Cu}ku?)!d!$r+3_Ccg-}$zr_nKPxgNLf5P^R2G8FKMc+QWpPa>Z_Y6I@`JF+-H2a_03+jrz$3pfE$+aN?UOYhV0`$M$3gJoKl5Cg73-A0y2 zS)q%DsAqZ14%^(Vtii|(`@=&N{5m{+P5>in>!Re&Js2D*9T>+f?*IS*07*qoM6N<$ Eg02Zt%K!iX diff --git a/assets/Rat/BMP_4_EN.png b/assets/Rat/BMP_4_EN.png index 8451fa76bce5cd4600f6d3ec200fbeecb646c366..28bf7baa294636e1d5d1da6aa5a34b5f7c124d3f 100644 GIT binary patch literal 952 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`XqYA``TxY04|!3S zjEtgy(xYHB1V&5b%~`N(6{pIQ(gSgyjxNp$B>zXQrgz*nR#~_ARlSJNF5h_sn5x&oDg94hm~eS3j3^ HP6|j%qV)$prWxq=@ zDBWCU)(ZPN8wCNLKw(}tww;pt=WGo&+?>?Gz?N#?Tg>ia+@bN~jgIurCE=C~S!Opj w)p~bWo%wfMjwysKAS^@k$bt2{6D6N8b27=TQ&&-L0y>Am)78&qol`;+0BMs#WB>pF diff --git a/assets/Rat/BMP_4_ES.png b/assets/Rat/BMP_4_ES.png index b2ad7a1e9e157e90d327c9325b4341ec5c57a4cf..379dea911b42894cc7e1175f942e51de7308bee8 100644 GIT binary patch literal 964 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`XqYA``TxY04|!3S zjEtgy(xYHB1V&5D>9~h^^ys)ijyuFiY U!}k3fl|kX|>FVdQ&MBb@0AdtSCIA2c delta 201 zcmV;)05<=`2iXCT7=Hu<0001iRAktQxgmIRJ}PXmO2v5Nx= zfAd%vrFGmY5cu_(Bdc2lT}KB;=X;JkZ|DpWpwa+S#?-3lKtgFEQYm+@(ik_F5re=% zydW}SYgh$-FSLZ%vz&v7Wn=7~L)JU-43-TT`yBZKo)I3)Vih6a00000NkvXXu0mjf D?^RGv diff --git a/assets/Rat/BMP_4_N.png b/assets/Rat/BMP_4_N.png index ca432a4a9ec347c3a50dada70d57a0c938e841c2..43987e170deee30ac21f13603ce20a3814777b55 100644 GIT binary patch literal 970 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`XqYA``5`arl9AE> z6I-Hy(xYHB1V&5r}#O$8vRpP`jRt z%>glPCeCa}PaCYCsjXvKATFHbdujWP?Ab5hPm}n1^v$a)(J8Y->gBGiU43-%S?zoG b>gzhx;{sWiWSNRQ2Zg?;tDnm{r-UW|wXIk= delta 182 zcmV;n07?JK2gU)A7=Ho-0000E6q08E000b7OjJex006+iz<_{&|Ns9_J*i{>004DK zL_t(|oMU8Q4PaOk!tk1j0SXWd#sF3a2G#&kEK&@t-Uk?dZ`H;o1qF-@46FhF*I<)k z31#?wwQgeo7AYpi&`_}m1_msaGB9v05Dg9BYQSPwm{)?R124nx4S3wc#K0QB5W;{} k`^q&8uf;;XC16Sc04kLiTi#L2^Z)<=07*qoM6N<$f(m*=djJ3c diff --git a/assets/Rat/BMP_4_NE.png b/assets/Rat/BMP_4_NE.png index bdf1bdd9eb001293a3f4dd052d9bce8f386b7b2b..28df5f63e4e02bb0ff9e17835806739f7a2e79b9 100644 GIT binary patch literal 1054 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`X!wv9HBD0Tl9AE> z6I-Hy(xYHB1V&5lyjRC~kvJ!DN*gpSa%2&uDbIQh%X%b^MNRkq5(m^>s7oa&j<* zxcJy>z35DcZ}FS@h-VH*!fX>JUe;dGEd^Q15_6aQy=?!6<*`nY%bbbEZwpzTtzb7i z+H#`c)WR6$o^=y*o#rigcK4)ujY)-S&be)2Z!SkjE4|{{r1ikVq5dV)?l!NM``=1k z)(X8BeGqs K&t;ucLK6UnaeLDM delta 195 zcmV;!06hPm2-5+O7=Hu<0001iRA?{BP z0DnnDK~#90jgiX@12G6hA1DQw4lMew$#Mr!fyp6J4%w9!jsv6lAjp6Kg8&)I-&}wf z5CB#QesggF#43%@8I=x|&y=fd{8qj&^@c1ugV1SbL$sXw**pe1S0(t_op5{`kzvg& xRD#LiY_JaHCLH+Z2N<-RIxI{El@L0gDQ^;lDDHdTgT(*<002ovPDHLkV1j;-O{xF@ diff --git a/assets/Rat/BMP_4_NW.png b/assets/Rat/BMP_4_NW.png index 33d2de280e773c875089c785309d123ef3abc876..e17bdea89efa262cc770051e5d1b2ed199d987f4 100644 GIT binary patch literal 1056 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`X!wv9HBD0Tl9AE> z6I-Hy(xYHB1V&5I~pVZVst0kfJMP++Urd*3{(L8L*c8kOEZ^A3r9sg!8*tYs^&hr(46WkrY?Rb75oNK1&Ikky< zGkl-vO<`q=ntUSoik8FmLQ`qp#$)x(liRc3)q6)M_^wobVE=dB2j=8YoU_mG`I85V NQ%_evmvv4FO#nLHei;A& delta 176 zcmZ3$ae#4xL_HHT0|Nt}$fR^2#S`EY;`*O~;lP0d4Gj(d|Nr;5U6}$D&-Zk345^rt zoWhe>QESlh&{UXNL_tE4XAK_@4^LFY5{Zbr%h>WA1Rc{240IECV-HGgwgcz@Q*C+py;Ft1F@05pwl9-3*?telF{r5}E*1Z#Yf> diff --git a/assets/Rat/BMP_4_S.png b/assets/Rat/BMP_4_S.png index 0d61c56b6ad0f5f1f41e2655e4d8426361d5f09e..21695ab072983edae6a4d39964d984af617653ee 100644 GIT binary patch literal 967 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`XqYA``TxY04|!3S zjEtgy(xYHB1V&5%A(3=#bAMm>5`NGS^1cRWV)0M7Y%fPjGi|Ns6A!0G@1 z0E$UOK~#90jgY|!#4rp5N6Hmobr4iR!2OqCa0TKza2l|a$Neq`Cp{NNv#cNmhVCH+ ze0JsQ9)Xzd0oQ5Zgp>>d4zpJPGL}d18ruP(wdo$z6ymEv1xKz?X=1siVC(Ht8kVt0 z1!z*ZPA9e_Q4AP-b{v={EI)qCZU8cygA^-pY diff --git a/assets/Rat/BMP_4_SE.png b/assets/Rat/BMP_4_SE.png index f2464dafc0d5cf6e7e9c6fb492f321924450b723..fa4257cce9e97ea8536c9eacf4cd18d48866534f 100644 GIT binary patch literal 1060 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`X!wv9HBD0Tl9AE> z6I-Hy(xYHB1V&5Yx{s_C8iV?tE4I4|{|&L)1Gbksj&QYr4M} zD7kMuJM*C>mv!>)5J__cgAF%4XPIoX?fV1Wdh3^kOge_P^pKe2RI?b|M0*7z)Aqf z%EnLJ3JH{ERvOaK4?07*qoM6N<$ Ef?0u8&j0`b diff --git a/assets/Rat/BMP_4_SW.png b/assets/Rat/BMP_4_SW.png index 67bcc0d021e695a7a8243b7cc9ddf26f93d6b2e5..8f289ff746598b837991c04b8829bf9c8407e09c 100644 GIT binary patch literal 1040 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`XqYA``TxY04|!3S zjEtgy(xYHB1V&52ld@pYkn? z6L|TQzVRnC2*jV-Rl9l---e(7)zEO3gBqJml|yuUE?9}NoNYpHeZ$PT? zV_K_q!Ip%{$C}z!w_EG6=y4vZ=i+AiUp+ze;AI;<4c?BdunUuoIeXStf0+4s;}`c& wuIIZC%@jDl_RDm;pG_x9|FPEGsrqz;PqU4ScW?1}8BiR0y85}Sb4q9e017{JNdN!< delta 192 zcmV;x06+hb2+#qL7=Hu<0001iRAV71Ij(42#k~yZ73Ja9GVFW uaur_mVGi1!0_de?l9n1osl8O_8Ojbj*c!^&y+Z#00000 diff --git a/assets/Rat/BMP_4_W.png b/assets/Rat/BMP_4_W.png index ea529f9380af3015a4892e3505990a1898bd7bca..7db9fe045faf60470792635b38e3fda26e3fa678 100644 GIT binary patch literal 1011 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`XqYA``5`ar|A{S^ zjEtgy(xYHB1V&5q8c&0EZ=im?pY}DyRua zwzvw&&b9q5Am+{bYJvmjdzIdmg}S%DTxF_X!~Ao1_m>^-j-Kw^<>IA~|1{9Ctwr}%W8)KzM*jH|S$}VS SdwM%4nmk?oT-G@yGywpW`DnHP delta 181 zcmV;m080P!2gL!97=Ho-0000E6q08E000b7OjJex006+iz<_{&|Ns9_J*i{>004AJ zL_t(|oMU8QU=Vd+bxUAkfC4y!C6wX!QAW4aP%Kgm3|!fo%aKH|sbO_1ea#vmibYMR zTdD(N0ILJ06axbTYv>BD1y~GZU z6I-Hy(xYHB1V&5CS(Fb7 NaZgu2mvv4FO#qmyOQHY( delta 179 zcmV;k08IbB2g3o77=Ho-0000E6q08E000b7OjJex006+iz<_{&|Ns9_J*i{>0044H zL_t(|oMU8QU|iU|?Vj4ZvbDOYm~m02~G~uzDYLV0BBtW)}m)>#T1H*esk1H<^Ledv+LWC>ANE hwQi{njG@@P0{}aJ7g3YquDbvL002ovPDHLkV1gwDL-qgw diff --git a/assets/Rat/BMP_4_WS.png b/assets/Rat/BMP_4_WS.png index 4e41f88df848583ab972dbf0acaebb78a91ebc6a..bcca24732af7aa0b241db98a740b2ce4d47fd6a1 100644 GIT binary patch literal 957 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32|*`XqYA``TxY04|!3S zjEtgy(xYHB1V&5)5S5Q;?~>1M&1Jo9Gi9j{r|*ra#PA(y$w>PnG1or zhF!>MZ@hzZLfo|YjR!p(^qgBnKB_9rx-!T6fzGsqyc&*2nibJ2j90LmdKI;Vst0Kp$l1ONa4 delta 192 zcmV;x06+h|2hahK7=Hu<0001iRA>!!Qg3PiY1)HwZLAf$l$oR|vd;Jb~R$@~QJs`6Ni32pLwyxgCrq z!pg>v7Q;TXgJu_0{2{Rzdzb(dvjZ8*iskhV&Wo(nr9PVQ**O_4OK~d|hd;&%K(pt! u>|sTOsRAfddBg?*4p4L0(ZKKLWh!6pJ0-xOjZ*6X0000 int: + """Tiny integer hash in [0, 65536).""" + h = (x * 374761393 + y * 668265263 + salt * 2147483647) & 0xFFFFFFFF + h = (h ^ (h >> 13)) * 1274126177 & 0xFFFFFFFF + return h & 0xFFFF + + +def _chance(x: int, y: int, threshold: int, salt: int = 0) -> bool: + return _hash(x, y, salt) < threshold + + +def _hash_seed(x: int, y: int, salt: int) -> int: + """Return a deterministic seed in [0, 8) used to pick a cluster variant.""" + return _hash(x, y, salt) % 8 + + +# --------------------------------------------------------------------------- +# Cluster patterns: small 3x3 / 4x4 / 5x5 stamps used to add visible "leaves" +# inside the bush body. Each cluster is a small relative offset (+dx, +dy) and +# a color choice. +# --------------------------------------------------------------------------- +# A cluster is (dx, dy, color_key). The cluster is placed at integer pixel +# positions; each pixel within a small radius is set to that color (overriding +# the base body color). This adds visible "leaf clusters" on top of the body. +def _leaf_cluster_positions(cx: int, cy: int, salt: int) -> list: + """Return [(dx, dy, color_key), ...] relative to (cx, cy) for one leaf.""" + # Choose a variant: 0-7 + variant = _hash_seed(cx, cy, salt) + # Variants: + # 0: 3 leaves in a triangle + # 1: 4 leaves in a small plus + # 2: 5 leaves in a + shape + # 3: small cluster of 3 + # 4: scattered 3 + # 5: 4 leaves diagonal + # 6: single + 2 around + # 7: tight 5 cluster + clusters = { + 0: [(0, 0, "highlight"), (-2, 1, "light"), (1, 2, "light")], + 1: [(0, 0, "highlight"), (2, 0, "light"), (-2, 0, "light"), (0, 2, "light")], + 2: [(0, 0, "highlight"), (2, 0, "light"), (-2, 0, "light"), (0, 2, "light"), (0, -2, "mid")], + 3: [(0, 0, "light"), (-1, 1, "mid"), (1, -1, "mid")], + 4: [(0, 0, "highlight"), (2, 2, "light"), (-2, -1, "light")], + 5: [(0, 0, "highlight"), (2, 2, "light"), (-2, -2, "light"), (1, -1, "mid")], + 6: [(0, 0, "highlight"), (-1, 0, "light"), (0, -1, "light")], + 7: [(0, 0, "highlight"), (1, 0, "light"), (-1, 0, "light"), (0, 1, "light"), (0, -1, "light")], + } + return clusters[variant] + + +# --------------------------------------------------------------------------- +# Tile layout: where is the wall (muro di cespugli)? +# --------------------------------------------------------------------------- +def ideal_mask(shape: str) -> list: + """Return a 32x32 list-of-lists mask of the IDEAL wall footprint (True = bush).""" + mask = [[False] * SIZE for _ in range(SIZE)] + if shape == "N": + for y in range(SIZE // 2): + for x in range(SIZE): + mask[y][x] = True + elif shape == "S": + for y in range(SIZE // 2, SIZE): + for x in range(SIZE): + mask[y][x] = True + elif shape == "E": + for y in range(SIZE): + for x in range(SIZE // 2, SIZE): + mask[y][x] = True + elif shape == "W": + for y in range(SIZE): + for x in range(SIZE // 2): + mask[y][x] = True + elif shape == "NE": + for y in range(SIZE // 2): + for x in range(SIZE): + mask[y][x] = True + for y in range(SIZE): + for x in range(SIZE // 2, SIZE): + mask[y][x] = True + elif shape == "NW": + for y in range(SIZE // 2): + for x in range(SIZE): + mask[y][x] = True + for y in range(SIZE): + for x in range(SIZE // 2): + mask[y][x] = True + elif shape == "SE": + for y in range(SIZE // 2, SIZE): + for x in range(SIZE): + mask[y][x] = True + for y in range(SIZE): + for x in range(SIZE // 2, SIZE): + mask[y][x] = True + elif shape == "SW": + for y in range(SIZE // 2, SIZE): + for x in range(SIZE): + mask[y][x] = True + for y in range(SIZE): + for x in range(SIZE // 2): + mask[y][x] = True + elif shape == "EN": + for y in range(SIZE // 2, SIZE): + for x in range(SIZE // 2, SIZE): + mask[y][x] = True + for x in range(SIZE // 2, SIZE): + mask[SIZE // 2][x] = True + for y in range(SIZE // 2, SIZE): + mask[y][SIZE // 2] = True + elif shape == "ES": + for y in range(SIZE // 2, SIZE): + for x in range(SIZE // 2): + mask[y][x] = True + for x in range(SIZE // 2): + mask[SIZE // 2][x] = True + for y in range(SIZE // 2, SIZE): + mask[y][SIZE // 2 - 1] = True + elif shape == "WN": + for y in range(SIZE // 2): + for x in range(SIZE // 2, SIZE): + mask[y][x] = True + for x in range(SIZE // 2, SIZE): + mask[SIZE // 2 - 1][x] = True + for y in range(SIZE // 2): + mask[y][SIZE // 2] = True + elif shape == "WS": + for y in range(SIZE // 2): + for x in range(SIZE // 2): + mask[y][x] = True + for x in range(SIZE // 2): + mask[SIZE // 2 - 1][x] = True + for y in range(SIZE // 2): + mask[y][SIZE // 2 - 1] = True + else: + raise ValueError(f"Unknown shape: {shape}") + return mask + + +def erode_boundary(mask: list, salt: int) -> list: + """Make the wall/passage boundary irregular and natural.""" + new_mask = [row[:] for row in mask] + for y in range(SIZE): + for x in range(SIZE): + is_wall = mask[y][x] + diffs = 0 + for dy, dx in [(-1, 0), (1, 0), (0, -1), (0, 1)]: + ny, nx = y + dy, x + dx + if not (0 <= ny < SIZE and 0 <= nx < SIZE) or mask[ny][nx] != is_wall: + diffs += 1 + if diffs == 0: + continue + if is_wall: + # carve a notch out of the bush (more aggressive) + if _chance(x, y, 7500, salt): + new_mask[y][x] = False + else: + # let a leaf cluster stick out into the passage + if _chance(x, y, 5500, salt + 1): + near = False + for dy in range(-2, 3): + for dx in range(-2, 3): + ny, nx = y + dy, x + dx + if 0 <= ny < SIZE and 0 <= nx < SIZE and mask[ny][nx]: + near = True + break + if near: + break + if near: + new_mask[y][x] = True + return new_mask + + +def compute_depth(mask: list) -> list: + """For each wall pixel, return its distance from the wall/passage boundary. + + Used to determine which shade of green to use (deeper = darker). + """ + depth = [[0] * SIZE for _ in range(SIZE)] + # Boundary pixels have depth 1; interior grows with distance from boundary. + for y in range(SIZE): + for x in range(SIZE): + if not mask[y][x]: + continue + # find nearest passage pixel via BFS-lite (4-direction) + # Use a simple expansion: search outward until we find a False. + d = 1 + found = False + while d < SIZE: + ring = False + for dy in range(-d, d + 1): + for dx in range(-d, d + 1): + if abs(dy) != d and abs(dx) != d: + continue + ny, nx = y + dy, x + dx + if not (0 <= ny < SIZE and 0 <= nx < SIZE): + ring = True + break + if not mask[ny][nx]: + ring = True + break + if ring: + break + if ring: + found = True + break + d += 1 + depth[y][x] = d if found else SIZE + return depth + + +def fill_bush_detail(mask: list, depth: list, pal: dict, salt: int) -> list: + """Assign palette colors to wall pixels, with leaf clusters overlaid.""" + pixels = [[None] * SIZE for _ in range(SIZE)] + # 1) base layer: pick color by depth. + for y in range(SIZE): + for x in range(SIZE): + if not mask[y][x]: + pixels[y][x] = TRANSPARENT + continue + d = depth[y][x] + if d <= 1: + pixels[y][x] = pal["dark"] + elif d == 2: + pixels[y][x] = pal["dark"] + elif d == 3: + pixels[y][x] = pal["mid"] + elif d == 4: + pixels[y][x] = pal["mid"] + else: + pixels[y][x] = pal["deep"] + # 2) scattered mid/light/highlight "speckles" to break uniformity. + for y in range(SIZE): + for x in range(SIZE): + if not mask[y][x]: + continue + d = depth[y][x] + # A light speckle anywhere on the bush + if d <= 4 and _chance(x, y, 4500, salt + 11): + pixels[y][x] = pal["light"] + # Highlight speckle near the edge only + if d <= 2 and _chance(x, y, 3000, salt + 23): + pixels[y][x] = pal["highlight"] + # 3) Overlay leaf clusters at deterministic anchor points. + # Anchors are picked from a low-density grid so each tile gets a few clusters. + anchor_spacing = 6 + for ay in range(2, SIZE - 2, anchor_spacing): + for ax in range(2, SIZE - 2, anchor_spacing): + if not mask[ay][ax]: + continue + # Some anchors are skipped for variety + if not _chance(ax, ay, 22000, salt + 31): + continue + leaves = _leaf_cluster_positions(ax, ay, salt + 41) + for dx, dy, color_key in leaves: + nx, ny = ax + dx, ay + dy + if 0 <= nx < SIZE and 0 <= ny < SIZE and mask[ny][nx]: + pixels[ny][nx] = pal[color_key] + # 4) Soft "rim" highlight along the wall/passage boundary on the + # passage-facing side (depth=1) — adds a sense of light catching the + # outer leaves. + for y in range(SIZE): + for x in range(SIZE): + if not mask[y][x]: + continue + if depth[y][x] == 1 and _chance(x, y, 5000, salt + 53): + pixels[y][x] = pal["light"] + return pixels + + +def render_tile(shape: str, theme_index: int) -> list: + pal = THEME_PALETTES[theme_index] + salt = (theme_index * 1000) + sum(ord(c) for c in shape) + base = ideal_mask(shape) + eroded = erode_boundary(base, salt) + depth = compute_depth(eroded) + pixels = fill_bush_detail(eroded, depth, pal, salt + 99) + return pixels + + +# --------------------------------------------------------------------------- +# PNG writer (PIL mode P matching original BMP_{theme}_{shape}.png format). +# --------------------------------------------------------------------------- +def save_png_mode_p(pixels: list, path: Path) -> None: + from PIL import Image + # Build a unique palette + used = {} + # Reserve index 0 for the transparent gray (engine convention) + used[TRANSPARENT] = 0 + for y in range(SIZE): + for x in range(SIZE): + c = pixels[y][x] + if c not in used: + used[c] = len(used) + palette = [0] * (256 * 3) + for color, idx in used.items(): + palette[idx * 3] = color[0] + palette[idx * 3 + 1] = color[1] + palette[idx * 3 + 2] = color[2] + pal_img = Image.new("P", (SIZE, SIZE)) + pal_img.putpalette(palette) + for y in range(SIZE): + for x in range(SIZE): + pal_img.putpixel((x, y), used[pixels[y][x]]) + pal_img.save(path, optimize=True) + + +SHAPES = ["N", "S", "E", "W", + "NE", "NW", "SE", "SW", + "EN", "ES", "WN", "WS"] + + +def main(): + written = [] + for theme_index in range(1, 5): + for shape in SHAPES: + pixels = render_tile(shape, theme_index) + path = OUT_DIR / f"BMP_{theme_index}_{shape}.png" + save_png_mode_p(pixels, path) + written.append(str(path.relative_to(OUT_DIR.parents[1]))) + print(f"Wrote {len(written)} tile sprites.") + for w in written: + print(f" {w}") + + +if __name__ == "__main__": + main() \ No newline at end of file