From 51f960932701e6cf10cf1c369c8c562ce51b7ed4 Mon Sep 17 00:00:00 2001 From: chexit Date: Fri, 30 Oct 2026 15:07:54 +0300 Subject: [PATCH] Distinct item icons: a silhouette per item and category instead of one remote (#99) Co-Authored-By: Claude Opus 5.5 --- .../airdef/textures/item/deploy_buk.png | Bin 404 -> 265 bytes .../airdef/textures/item/deploy_depot.png | Bin 397 -> 336 bytes .../assets/airdef/textures/item/deploy_ew.png | Bin 400 -> 241 bytes .../airdef/textures/item/deploy_gepard.png | Bin 396 -> 278 bytes .../airdef/textures/item/deploy_irist.png | Bin 400 -> 297 bytes .../airdef/textures/item/deploy_light.png | Bin 388 -> 249 bytes .../airdef/textures/item/deploy_nasams.png | Bin 395 -> 297 bytes .../airdef/textures/item/deploy_p1sun.png | Bin 386 -> 286 bytes .../airdef/textures/item/deploy_pantsir.png | Bin 402 -> 307 bytes .../airdef/textures/item/deploy_patriot.png | Bin 397 -> 285 bytes .../airdef/textures/item/deploy_radar.png | Bin 403 -> 314 bytes .../airdef/textures/item/deploy_s400.png | Bin 399 -> 243 bytes .../airdef/textures/item/deploy_s500.png | Bin 407 -> 409 bytes .../airdef/textures/item/deploy_tor.png | Bin 401 -> 338 bytes .../airdef/textures/item/deploy_tzm.png | Bin 400 -> 316 bytes .../airdef/textures/item/designator.png | Bin 392 -> 154 bytes .../assets/airdef/textures/item/flare_gun.png | Bin 386 -> 139 bytes .../airdef/textures/item/launch_geran3.png | Bin 393 -> 223 bytes .../airdef/textures/item/launch_iskander.png | Bin 404 -> 210 bytes .../airdef/textures/item/launch_kalibr.png | Bin 403 -> 233 bytes .../airdef/textures/item/launch_kh101.png | Bin 408 -> 184 bytes .../airdef/textures/item/launch_kh22.png | Bin 409 -> 254 bytes .../airdef/textures/item/launch_kinzhal.png | Bin 393 -> 151 bytes .../airdef/textures/item/launch_lancet.png | Bin 392 -> 149 bytes .../airdef/textures/item/launch_oreshnik.png | Bin 397 -> 269 bytes .../airdef/textures/item/launch_shahed.png | Bin 408 -> 243 bytes .../airdef/textures/item/launch_zircon.png | Bin 394 -> 128 bytes .../assets/airdef/textures/item/mover.png | Bin 404 -> 464 bytes .../assets/airdef/textures/item/remover.png | Bin 411 -> 257 bytes tools/gen_models.py | 366 +++++++++++++++++- 30 files changed, 351 insertions(+), 15 deletions(-) diff --git a/airdef-mod/assets/airdef/textures/item/deploy_buk.png b/airdef-mod/assets/airdef/textures/item/deploy_buk.png index 8b6d862edd000ef14cca41dfc63cbb06285796d7..397519fd9fbcefea34a2d011b97c13e5e6224297 100644 GIT binary patch delta 238 zcmVw(MOXFv^(nZtL?qM(MI o?@I`~>VwFciA1oK(CsYM#;e=$%jS-VwXt{PS5<(x8?F zZSN>-!1aAGDOx?# zq0n|U5+tJr&w*Mu^g*zyBr_`ste97xjq0Zxgfvhzl2CZ=e%V)cag^hwU|)%8L9G@0 zgJQc)_;g~KWeVIDX9NR&T2O8_xV@C66qqKGIz#7I$Y_aGKD`4wPZ3@d77nxrkrQLh zkb*ntrv=U^ymK5#lZ4nTF`*?E8a-Dm%rGsO>6Sb-v=ykLChs$%hbQHDGXL-k$^mgs z%mYSd^oI>a6_H&=RgN2s1id(e2k$S+Cde_j&8iXb1nB Y7nxj$pIB$;f&c&j07*qoM6N<$fl!XwqAu1A7?0A~o@iM(%U*YY2PL-APti#7C zwbUfJrcgP`Ejhhd6L56AjVeKF&myEK>yY447~*7g1Je{fW}l$?c>6`61fv70N+DR3 zhm&;yhx>b!#x9UZA4iO4i7kXwcJO-jg5Nc}KCp|f&)k@A&H!NpXd#ui00000NkvXX Hu0mjf)3lNN delta 370 zcmV-&0ge990*wQZB!5&%L_t(|oW+tmPQySHMbCUZw&VQ68c?_0;%zO6@{I|ruaej8}2Vua%82rlNRe}yH ztXMHx$J{@@{J5j{0kIFby?grgwVTV+hNm0GHsbo~gvcp!Ykx2batD*hqq?RYU`3AE z3Y@4B;TEy5^o?XjNK(}8fO@P^GmBOe9y0lzi?;L^OT<951HwGUiGa#`E|L#iFJY8= z=6b}?W$l1fu|jkNn1Fa0uq+Dd-Vo(BER<^iWFrI9p|@60cX2+Vk0#G@tf`PXXzzeh zkxnGmej>f0Yik6=0j`v&T();GKHAM0GqDj-1X&fcsT7H>h<7_}1C(n|C_HIZvD6x0 zLQ<}gcEG%|Z3kp!pPUregV(o$=l2vj=z!lKHqDQ8P}Awu@6Mr`W-5Qw7i(pH7piL- Qi~s-t07*qoM6N<$f~Wnj{Qv*} diff --git a/airdef-mod/assets/airdef/textures/item/deploy_ew.png b/airdef-mod/assets/airdef/textures/item/deploy_ew.png index b0cec21964773cd77ceffc21636f28211c412593..c0decf4b746f0808dad2f71bdf27cce7adc6b3df 100644 GIT binary patch delta 214 zcmV;{04e{F1MvZnBYyz6Nkl_3b| z*p3byT+Q%C9TNiq!1C`414RaW|HDj~0o?!DC^O&}2Yz{i2K-?nBjiZ|0L`E|KlVS4 Qvj6}907*qoM6N<$fH#*5VV`TKE!TDcFdO zU}YzQg@})#;3HUC`4Sf1vWeMDCNrX)yJEERhtqt_`Ofgee@EuQ?*3-5Qz0}S?NiK3 zLFN=AuOSbdUS56K(er}N)NpWk{_VAstl`YM3_Ou+1(Qtw-1P_NJNun_7^`0OSk~F z&DmRD#pS|VtWd7N4hQW5i7jO{B{ZP@n6Bic)>C_-mxXqLPZXwF#w6gw3w5DB3$;B% zRY`jXQBh(AjBlCZ#N%{KG)x&fO>JM>1(|}z=e)T-Y1KtZgA10YreVDFiw?ACR3b?B zOx5obAw+J5IEQ=m?Sfuf;;lw>!u8GlC)?OsBc0{YTiE|OlgT7}%ujC?I{0he0fx_q UzSND*aR2}S07*qoM6N<$f`h-k00000 diff --git a/airdef-mod/assets/airdef/textures/item/deploy_gepard.png b/airdef-mod/assets/airdef/textures/item/deploy_gepard.png index e8fd049ccd74494361ec8b7a8d211c7923ca2c71..caad7296bbc5169b91ac8996dd0716bf68423328 100644 GIT binary patch delta 251 zcmVQf_MTqZahJjg5WLOXQ#_t zLeV1#>TP_J$^5h+C>eO;Ua(f(RCiHT@DJ4@=6ROyc^t>)ooYS5Jxr_&NbsCp-ZUN9 z7O_TySV8x@UtQRiK#`2NO!9{NyW1+#!3gu_;N@w;`GKVmICSlh)svkiiK2^!lZ&e# zM|P|B{y4EO2F!pH=umv@7mTv#Vi`=ryI48U+r@`t`l2{eE5R)kpXr=I8H2V7Q5jO5 z+E&Xh5(Q4ruMhU}`aF?sXw}A753RCVd==qu;uDE4Tr{T|i$MSY002ovPDHLkV1fjm BdG!DQ delta 370 zcmV-&0ge8a0*nKYBYy!?Nkl|c=}SKdc;n0b#wn?x6AXRo~L?%5nNv!6YvD*k$E*8wJ!LJRqEQS-vIKpO*s*>ETB@j4UX!PQZKs5}=Gl$!CDikOBovG6Z zm0-L=+c-QzWg{_PGu?LVuxoOQ)`B*KVZgGr*l4Mfl!gg1c|+(4(znE|8-9b2XviCZvVz&BLW~Pa zpAgoD&1AQg0YFiXAhdL*;PKV){PIDJ24AL3`~T>7tyZgUcYeFmOYm2H0{b0{32td4 QZvX%Q07*qoM6N<$g1&;UasU7T diff --git a/airdef-mod/assets/airdef/textures/item/deploy_irist.png b/airdef-mod/assets/airdef/textures/item/deploy_irist.png index 00c947c2bf55b9430d808dfe66939aa99adac8cd..c4bc462579e9068af973d1a2086d02b46aca6289 100644 GIT binary patch delta 271 zcmV+q0r38i1E~U#BYyz!NklKR3d3fYmVZ(3^Q-uo7q3`zhSMFU3m$wjY(a&nQukebb4{} z(_F^0!C`xGZ*aUOj;@ZR)e)?<@;ZLxGP)*?V^!4yNgIc$x__{Y$>afNd~`PBJi1+R z&+iuT93ch$-p#63nR|7&r;j_72J)OdI3StcGk&w|%M9fSpJo@mje&S649 zGDli;SbB3z(7`wme@P~0yTM+Ou?QFRyWeYW;$<>IrSnFP>K=AIQxpH|NBaBt0vo7( V7O}yk6951J00>D%PDHLkV1i4MfusNc delta 374 zcmV-+0g3*p0+0icBYy!`Nkl8S%6oo&J=g0PrH@gc@K(%j?7AZ=VE=Wje z@(er)JrWHSC9jYco`Dj{n|Q~b@y`rO$u5dT#gT4vbnkbM4*YLrr^fZW%M_zWwVJ^g zQgDcBq)HRVs^HtFhd*xQDZn|&=Z|0i`t9z+&6y`pjosYw{(t_K(jDFs}*?btrp*Nsc^$qM{wA->f*ZKx z242CN2&6Iwqog)K2`qe@Nq;-PKhpyLBu!J{In7O_sf~yI9a+AG>e?KlX*5yxflCtO zff7&Jz^4L*04rMHcHMOvvMmS%#K0OQm;_2Z6k7KtVq4HsgI7I(DuzJ8uPZEd-D{w1 zA&O4#8lMwH;jz`Te8dcbARu#~=DNjrh0X*nTGNjaJ3CxP=wZyCn3dqmPmG~kosp;V Y0zx1~?IL3KLjV8(07*qoM6N<$f}}WLo&W#< delta 362 zcmV-w0hRvw0fYmPBYy!)NklO&pe-m3z|S zxEFm0x=|x#%WB;b)q=1OoSMM)S?IfReu70lpuFZKLM4&O8=7^Xm=ck{n4r%+I87lL zs6G9~h?WBPnqv`nZeAe6ioR8h;&3u?`Xr>*BetM+uk!+}LCYSugk&|lxc9|X zz5^3_s>-lSfzA)$2Wnd}xrvmWe9*!t*=#oQc0Rjvw8FpUH_QWwD3K3}&j0`b07*qo IM6N<$f&`1NH~;_u diff --git a/airdef-mod/assets/airdef/textures/item/deploy_nasams.png b/airdef-mod/assets/airdef/textures/item/deploy_nasams.png index 289e6c2536e5c33c14c4628cbc6dfdaf7082eb93..ea0e0c557081b840f07f265badb1cae6b13f2b9d 100644 GIT binary patch delta 271 zcmV+q0r38d1E~U#BYyz!Nkl-CnW^Wxp(4RzO|x#6b7 z0I7F^gAKyj@?z4jbAjil7u*`6M%){^RFEX0d5NTtZgieFJb&7!C=al#M>Y#wYKVKZ z(x7eewZLk5$*&^(^aJxx=s0=%a0O*f7T~paXq-?AIvCv`h_r-QusS~9a%3#fieQ#V z8(7$Y;)vGtHXyMhx00;sCQfu5D%PDHLkV1f%SfXV;> delta 369 zcmV-%0gnEu0*eEXBYy!>Nkl^*5Jq3yZrlAAV8s<8aRQDoGrQT0I00AS z5*&a_AhDe@Z~~;+4!a~IapKtRHi8}L5iM5pNws;ZdZjA(-zkp4&#TKE`yQPKmbs!U z6sheA$$^vnzJL5Mqee!RxVwG$=eFycA0wuYL0DB>-+ZTVl7BKQavAV@!*Ev7WH~KJ zwnuDgd}rzXf&2) diff --git a/airdef-mod/assets/airdef/textures/item/deploy_p1sun.png b/airdef-mod/assets/airdef/textures/item/deploy_p1sun.png index 887f15d8c49916f348ee11c5020bcff656b48d97..016b9fd4437474128b517065c66f3738c847d9c8 100644 GIT binary patch delta 259 zcmV+e0sQ`g1D*nqBYyzpNkl+)w1<270RV)9d5x9NM;Zvj!uZ-4?G(`tX=! zHeE+WK}*D};pTqD$qFSo`a!5|&(dGh)Cr-`UwLrxyPPS?7<_ftb;Lm!wJ|4DAUQ*v zB4k{ZDA}`K-A*;+*e#plN#tx4UvLblj1M#KgK)4KJA6%`$A<+5ONY6LzBytg45F|% z7LB9I6{#t|8%SNCH`aF#%<-~)Mr3OJlMq5VwZ3!rXD`y_`2@_EV(IhfP{RNK002ov JPDHLkV1k-0d_e#J delta 360 zcmV-u0hj)s0)hjOBYy!&Nkl40jGb3wsSXthySO}yru2TiOh_BR5 z+SDn7!MBkjti3v}<`_aMugnTp{@`yuW}bn6;G>hA7N2jv#3%w{v}iFh>55tf`lF{- z@blN>t2^ox$PIk|@$lwrcenS8PMsDe4Sc)%%4VC>A4=Rg{+m@7j$OzS{&ia1B2YfNX0D zh6NxNMVS)q1x9ZW!QrFF#*||<&~1x#fIk^yU7&`Rm^R2G7+XLZX=bwy=tLpJOjczu zS>m=vB^}=C|6$M?&=oI)V^1qBxw3@Tk>r7CmMGn?FR@HEcqJ%j*f$P64aliPDT|VR z9nfh@F9U8YaKAeoP~|XsM>wPl;B0ogUHmua&Mbf7o%sv$dW+^(VJR{I0000#L7x6eS)=7tb71p z#O~G?Py|5`D-UdZ0I{-CtOebTOA^_Iz@Fr|;tIhZ0-68kpP6I^{vWEUirrbnC8%W! z>Kys{KJBZf_~qk~jrGlJ0?Cn``QqUW@xlt0=chML4o`cnEPqQ`*g=Ot0YxB0dh>5% zf~3o^<;&>=LqNnJ(a{uv{jH-JV@jxp6k$oQSnP|KH1+n$2R=$h&g!m=2;Q$h#$^5 z#I13B{`BpSGkPxQwCCf8FMqA}_Wg?m({o@`;D6oabEc3m;tV&yD0_r8 zXigRaIR`2V(!t=y79}SjFsPc~N3;>^9mK|B4whv0T>ZGKn0fg)l1>9*lIsHBZ74P% zM#1YRlIz}5i@+vIe%0f;pmrTcmua=&CKi5BqWoR%7%Lqb0cs z+(x%9=!8VZhH)xQv^R>rZkgmrnkpVKtqW`eQS}%Jv1F>jV~eLmMXr_&%Q+Cm-2a8q zJ94W*c&c%W=bG-27J}t7#v^Ik;%d+LuRrhE#Z!xul5HLqf(NtP?aJMHXwPz}f6Q<5 Wl!S^Wdku&H0000su}%U(5Qe|qy<1j%4q}6ap`yS}5+jiW5-N)` z##aIo3a-M+m{4f+#m-}aAzakl5hD;Q!e30XGyBcVKX6=%<5>O$H+v1)Y@&9Z`tmWt zd+6OfX89P1C5oy%xxTCa398Li*L#}0_X)%x+9NYZSTc04 z?hD|zg&?1NejA{b<%ANSOOHuI911^MFnt}8c#Sibb}RZ}biP4q6my+m=1>-kn2@DT z39R5%h*K7?lfouJ{^7D{xNSZB>i20n=G5Bl$77Fr!NOr`1+H>nB$9BT>;M1&07*qo IM6N<$f?geb%K!iX delta 371 zcmV-(0gV2g0*wQZBYy!@Nklth#Ov#qC3(rp75dV# z9$KcHX;u)_z}@ZVKW?g-r0lu3~KehD0YE+HU85 zTwtRTR~}sOjE4%927FLd(*w0SE+^QFEtrhcg-_oSbPcbbSL7a|Da!(?8!^op85-U` zH7LDjnI}x++HM+8nw#|wjTy#u3{YM@sID0iyaQ{YcC|AdCt%K8CLOHS~h@0%L=GKq5&j& z1e7#XQ_LD>4K(b4mYNPtUdY6WKM!t327$Q2b9u?-7@Nu!ChlzT27Fv0@L(NeZ{A5KW^EJMj>L$K?{eH_HKQW|`v32E%!JXRg_v!b$Yv!cFzv>3> W5q%LD(Kf{Z0000lpBYyz8Nkl z;LU^#_8?g(I3ybvy6{6mK~cZz|0?(?BuV1xXv?1=KOHLn1c+NwySz(R_`W0TPuXW{ zY^50nGxq5k?I}is@x3vMBJr|;GJ-QchjhWk36LFj*@j#hoKY&-p60~Id9ws73_b+{ z4^ugGO`;2WvWw0w(iohy4+P$W9wq6Nf-so8)f;C^th+QDlC*qWQ~l#Bd>>c!%~lox SsE(Ha00002|N}^>}tb;tF#Egh&a->zGV| zk(!}btVQwe=HqWO`qbdAj@-O`|Hs#^-@H6y`V?fVc=h@P;(rWb%ryGIN(v6TK)JJa zMxuDcw)3BUiv)U8th9H3^3(gLdgD0&D0?o2Pu#ux{*s|hV z7OFH7FH1(}sU$70fPMheEn|60|7qas=b6d~Mp|4t`}y~4x7*D>>%N}z1plZX8u^4% T+Silo00000NkvXXu0mjf{29MJ diff --git a/airdef-mod/assets/airdef/textures/item/deploy_s500.png b/airdef-mod/assets/airdef/textures/item/deploy_s500.png index 5b40c2bdf2ca7766a8bbee224c3a93e43d2f126d..7ed223276f6522740519e1ae813e84864680ffd0 100644 GIT binary patch delta 382 zcmV-^0fGLP1DOMmB!6H@L_t(|oYj&`P8=~5MUQ{=fvkZ+7L}ovx%~X1wrK?FUO;jsOGo}(9b1NfCf^sI^~d>{Zg_EVsy{D36}~<{ z(W}Kt;cwSp^y=oc@HT!6e;)5hOI!K=mVO9@e?Q&BFcyBeyMIMZ<(&ePm9Ec)gY>Kq z>wFL;B8Ai7nB7}*y9Kp^jkV7xbmOY+KCtcwg zOKS4|f=L22^Rt#?GO=n;9THMCJMbJXtIf;RdCte<52^$RBePn1=@3?kc}L?S8WZEj z-Zl7X=Ig~T^LNI;d4pKPWE}?+=B#f_*vls=&?$lM+D;zA@O|V|8Xskb{AtN4=ws7N+_~c5-y|UN>X^>i+dt cGXHD-0<|}l*m-C7kpKVy07*qoM6N<$f(bOY9{>OV delta 380 zcmV-?0fYXT1D6AkB!6B>L_t(|oW+nmj?^$1h9Ad&NhUK9f`TJVL&GKLD7eB3iGmYQ zP(Ve21QOj|fHNR*3WUT7sCHMQOlIsj{z1?&gEmm{N^Tx~e*Jug{~d7(o^shv%530$(A{3 zRB}w`<5Z_$$AMN^k`;(uOCA$J%v!ILxk9H*=>q#^T3$ij zIGoh9H9UQApSBCk(NLFw8pX1~US+bJkmiU{13orbBdDCluG6wX*VW`1##GbzfuIxN z7}?~B>--mgAa#d=9gj%m@pmhlb)sb=t~+{{mkst5R4-|-1FSOQP~-18N{pmRFB_~k zhDujRBZ#r0^fT_tVExPnyKE4`K=PU>C7(Wj`^6qVddQ9UDC^D&Zq0VPEkDm~GiNLO aYkmM+>WA6ZsW)%{0000fRu=~?xPRS3g26`V#GO9VhWM?i zVh9^MKQ7rqd7W$RAoIX%K$?J$m7y^hV+nDGNWhB2);$l8PqP0Cp}}cQHyaxTF@dx- zWUeDI0oo2DDLt0RMqe{%(}CcH45hL<27)Ap)W-N`Jk*n@(u>E3j{#;2Lx_l-5)8~@ zLmVu2FrbP{Dlifk5vmT~TO`}do_EdXM>?+W0z0(7_Y?o8UIFZ`Z=%&^kthHF002ov JPDHLkV1g~pil+p1Qtzs%rS(GKa>i^Ow5lO8QFh zO+}|I&O?Vmii(dPKHcld4gqd^!ujRR(P`K3-j2NN(3lx`e}DCw{k%p+5iy*#hT&96 zxt#{=#2`{p#fBmpdQ%bd4x2Jk6Q%*C%rUOP+8NhhzXMy|JY7)Zh_0FjlmT3A`LTCg zJbTP-DXhXT8nO8Pb{Y^K1$JApJ~5Tve5_+XOG~3#5-k zYsflb-0+0icB!5>)L_t(|oW+q(PTVjU#ea5^N$mWYPLI$Hqb|DO8n9u5s$QUL zjzGKXK|q2#z&+S-0i>B>k~oR&xT3pGDgvuM$(yIoKfm`G{BOy?_T*W)YLN{deeI*J(B;FliPX7d0k0vlrqRzXb(19kVvS; zFkeAhkYhuc1#UuG(il(yY-cf9G@pQ=SlArnVr18%;})+Lw9X-iHvpn^OM-)_qRs-( zQjzx-`LW=`xS6l8X#-;ANSxu}{^i?hK7XlDX2(7*CV*G9Ua!N;d2MF8gLmpTtC)(J T5+ahy00000NkvXXu0mjfVr{l* diff --git a/airdef-mod/assets/airdef/textures/item/designator.png b/airdef-mod/assets/airdef/textures/item/designator.png index a2dda9bb056725028a61cf9d3a344080cfc42d58..26534c5464b336e879a01f9635000bb2e2ef1c15 100644 GIT binary patch delta 126 zcmV-^0D=FA1DXMlBXe$9fFY3NhNgAsdJ6!XK1ZD zo`;d!C4w?J)i~YI+O`L}8_|R!fUOs=Y342MH81os6u2?OXi@{o4B6#5%fbrknqnPv gG7$6&q5E#415)2X=q)qeWdHyG07*qoM6N<$f;L_?;{X5v delta 366 zcmV-!0g?Wi0f+;TBYy!;Nkl?Aq&Gd*g&>KnnD{0J;S&1<#4@ zlTaa1QBXsi*ol8PyNH6~#?rN@IMPU?qnV>`2L89yz486so9M-%M~HckX@pDMpdI+( z#M>`lpY7=TfbQnlKYf1YReziJpB4oA-Y6O99zS4>qS<7Gvwz2xBV&>>?H0f!3&R&= zmEh+BJ8Dce({+JOpAyg0Izck8H9wiyiCHH&s+xV8^DqTO6cTb;6WOYPHn2`0;5S@_Rh_I3RDUt35001+*D6lL= R-nsw)002ovPDHLkV1fD7b(Ep-f}yAv5kqTb>dAt!P*Va#WO ziulc!4}a{!@}=ZKZa%W-_vgI$wOF^uVB8pX`8VQQD%(Iiz<-&h&m-knts9iCg~5{4 zCqf8FrSRR1Yck5n!ay%NIH36M>%QIMzuuC{imBbA9`A)_ViUoTpfdzzDRhCU zJ5>Gsbcve=)RQNBjmZfq4BBeO{EWA|^%KmWgsw)?^a5!niy}=4>K#nW6YMb<3WZN2 ze%nBZ*rLPsLSY{xOlCcScbcGf1Zg1-AT`0w*trHIb|Iq!h8ZWeKOW-|yuxr*@VJ{!wqeHiI2$*DcQg0000w0000cyrwiQE;-ug zM}FPk{k3DqfW}u`U0(k4w6pIQaDT@^fRl>z^B)8SOWQMa6@RLVqy%$g_&v(&F(Ai| zPz4$ph^j_;ib`svO4cDtq=I#Oe&0YU_|<{`~Ex%r9s zfzm6&26`5I06jM5rlg!hwJ4a0p)?k=RhXPv^fKKb)dj^c5K;@?^O7D>Dr2;xukCb$ zt=-T{Lq{No%xK48@hpisQs<{>K-~SUxFw0>DL){lAl4SI9g5lX6+|DAn#70h8F9Nx z4qdcJC<)R}Hz?NejVram)koOl-NUt{We>}}_+hP9tGt^-nRg=h^$K%lf!3W9)!nP*LVN(nJ9v zrB4w-O_L%8k3h#WB=13q6n^Yo|Bh#jNS8IjqT)!mIXZLhHy7Sp!LIS;_|v%XBO4Ro z?iUFCfVKy0RDmGn^5@lmZ`5uXFvQxhcPIDbF;j1DDMLfk8gRAMSg zE!?C)>>70ulPwd5Dx~fPhA2jDJdN67!f>8|RgWzfRQn^Be{O-2uOD;bR#1#?zF?0O zXDx}?@@>7OlL?3rF*vfMoGbf~4q42C-D=_841Yx?J;j^=NWxtP#bNbBj9#MC82 z-lC-^aOpfjAafr;E_iIV2(4(fX1{|wVG)C$ClK)pRd`G&@gromVcT{r@x-o~FW6KS z(pUnSgB~bzMXGb07ev7%{=yej&to$pvx?u>H~+k&!w>Xv0@EA5uJw97KF@2JDbpME Y1Y6U4Ph3j%4*&oF07*qoM6N<$g2Jk_C;$Ke diff --git a/airdef-mod/assets/airdef/textures/item/launch_kalibr.png b/airdef-mod/assets/airdef/textures/item/launch_kalibr.png index b7d4c319ef4634f99f1c852d0792636657ab59d1..6a8121d5de2d5fd31065858436a17af57c27edc3 100644 GIT binary patch delta 206 zcmV;<05SiQ1L*;fBYyy}Nkl15QgD*XLoH&^7#V6$O7NN;FCCzfUz$S zax5PpkHdsu@RYUFGA*2M@aN=I)UMF&27#aI%-IIPK7 zwd5t3Sa6F5Eso&Ayb8zD%lBiqkFB=5&HOI}iR9?#MdEM!1gKR)9ch}Bp#T5?07*qo IM6N<$f;I?Z%m4rY delta 377 zcmV-<0fzqR0h0reBYy!}Nkl8S%6h_bd*yHt2HreDM_CctrC}^l6B&fne zP$Pwo0wP7CO%ox+Q^DH1_U`!33<@1<6e|^gddoT<`iMr_d`2NEm_V(%uD;Xk_pZ|E)>vejl$9g75d}@9J XaZiOseoy6J00000NkvXXu0mjf-0`@e diff --git a/airdef-mod/assets/airdef/textures/item/launch_kh101.png b/airdef-mod/assets/airdef/textures/item/launch_kh101.png index f08221b8610646dc8ea093f6cb955d1afa7041f8..63cbf2203bc9b679e3223d4df66d3b919a305a5e 100644 GIT binary patch delta 157 zcmV;O0Al}`1GoW@BYyyYNkl>En#)0(Kq-2G+l*u4QBT z!SI(2RgCf9U);`JfaW}0Vnl~Q0@UxwnvlbTy3t4oP?V4cHx>W@1zAW?F=Yt600000 LNkvXXu0mjf+HXVR delta 382 zcmV-^0fGLw0hj}jBYy#3Nkl47Qagpt^_21JF>UNJWK2 zM?pZwz;$af1enAyUt*gXp?1?N zWP@krN-RAe%YE`JBK3mHEapL`0XnkmJZ|vDfu7SmSY)_EtijB(=@nMAJf?G^UX#Zi zL()N!QaFuG`gdtS+P1{1X2_ul197WJltHX#Jw5^>fHgTj?#V*RLgyq4L!%W8pzCHD zP}u?LK5(yUdVE`QAd9Hvj+t07*qoM6N<$f(&G}4gdfE diff --git a/airdef-mod/assets/airdef/textures/item/launch_kh22.png b/airdef-mod/assets/airdef/textures/item/launch_kh22.png index 0029cc99652ad050d1979e7e92a832055677b4f9..8882d27dd9738998b1ddc5f933287a9a0dc3987b 100644 GIT binary patch delta 227 zcmV<90383B1O5S!BYyzJNklP(`UIq?O8N{SUl4~Ch?$NQOKfWJo&1d7+!#MC8reCMrTuz0oI^s25kg}nPS8*~+L zrykRqNfbq*%0(&S0iSn=J!GMSiWqq|f?+0*xdLc_Oh_!}i(K{w3@gH5nWe!3N{MY;p>msNKu|^GgV!wTHByBX`A=P dM_>6TxC6VYPMo1I22%h4002ovPDHLkV1kk{WJUl0 delta 383 zcmV-_0f7Gg0ht4kBYy#4Nklk&YY9N3Crg@K%0I+UK!MFkSKSSfa5*{r{*vkp2LP|GQ^#*(NW!ji-aItsHPyBwkID`a1Cuz^YK z$g>6~k(b7iBzRl~EMF%WBb20Qso6CUrUit7s&6j?VlglaFgF90U$KrUt?!QB$jv*p zurE`*T2SehPpd7GM~c>QIIg&S$05y9{WdgXG(W!oeA6E8?osn4!EeVyI9Hp^Mvm`X d&nUwG)?Y^ii?AZ3h4KIZ002ovPDHLkV1li^xHkX* diff --git a/airdef-mod/assets/airdef/textures/item/launch_kinzhal.png b/airdef-mod/assets/airdef/textures/item/launch_kinzhal.png index 21610e7ccb6fe7a45d3553fb26efc10f23e3f5a2..0d6cdfb9d567507f64d4208c9b09ed6ea46b0982 100644 GIT binary patch delta 123 zcmV->0EGXE1D64iBXj^>NklaX zO!_E7sq!Hdhzf<^>(`9u5rvL8ijyi^nr3UxI{VBVcxj3I#=8&ibKP}J(o?V{sh%*G zC?T+0!^QdKe>HkRY$M;!P9N;{_0!41)Ax>J zp{g@6W^9_7lp&f85YV|;0OTTp%*eK8R+jG}aODC?_8bU-_r-dGL_vGdk-CDn-qP3v zZqE=BxsdCC>>@ffC^a#@67*Rk<}Fo@m`!>Dpb8*7W*AAWBi+@M6*3y;n|A#T+|*FG zksKjN@I`~EBxw7?fGoG`06BWPvOxu~DRP{y>4zJXHw;r=A3@iK++Q>5l1*LmJC5K3 z8Bb-O00@64v~3VM@$<*8f8Oz%*VsAW<8qN6)o!=TcjvJ?%a47gZUF-gkaDO5r_}%e N002ovPDHLkV1nM=v`+v4 diff --git a/airdef-mod/assets/airdef/textures/item/launch_lancet.png b/airdef-mod/assets/airdef/textures/item/launch_lancet.png index 71c8977f53de6f83fa8e471b69fa2192b09a3084..61bdf4eccc6c82ea084152d390fc717d8d3d9311 100644 GIT binary patch delta 121 zcmV-<0EYjF1C;@gBXR&-Nkl87-1QRKn%Eoc3`f*%O0e zn3|bDoq|3a$(69KH9OtYbUmr75Tz)*EDI{1Fb;2VcA}O9sWXyfWHKHf+GW8ZWV{iD zj1{eJ(5)eaf@gBIW{`CG4(j4J2W?pePfEeCny5Xn@6lzt+#q6zR18^xvY`8vU`JXN zK<3XdYp`1>(oT-GAMWpu?8C=%$}%#`CI>%zYVyA{b+kSoB#j- M07*qoM6N<$g0#e~Bme*a diff --git a/airdef-mod/assets/airdef/textures/item/launch_oreshnik.png b/airdef-mod/assets/airdef/textures/item/launch_oreshnik.png index f45d56d0e49e8f6b0fcef173b1e83fc5fba4761d..6f48cacbc46532ca40008ba976d9b3b863d75fc8 100644 GIT binary patch delta 242 zcmVA2;f_NXp1rafwzy2#3!N}D_Fxn?73ce4jVDJCv=1h0(G$ zz{M8hp&yjh@fu=BsTSDF`_HWC>$URu#QU}etIz|>!W1%s!)w{VsD?U%6hmkQjG-Au zv{9-#JWJIy*O9zZ!n~<*relf=d@FQ1a&Y@BKc4V%b*PnhC>`V_c^XLqVw94U)#(W_ s_ta8BvB>$ux3XWAyNjJq+~e;)0I?5LTNSNLbN~PV07*qoM6N<$f(MUu4FCWD delta 371 zcmV-(0gV2Q0*wQZBYy!@NklL0a*bZeXwRc<2TQKz857*!&r);;**~A>FBdqhl7(G*RV> z79}DRZWM5aSD$|T@yDMF+Am&`>Q4sw`)32Cf?T z^}1z5D5OMoP*iDIAX8!!NlpBYyz8Nklv)`E3R$CLJ=^zP#< z<;8@iK-q|nD;YlsKW#v4(4Hn4^qZ%&D3J1skYvykgV#A8YczZv7WK&~|6V7{uuuO> S&)+)$0000ow>K}AJH zyV`;ViB~|>2#J!X;297NyaPKwn`G=HHex#xv=J4bbekjJ<9luR-%(@m?B(+)hZ0*P zg!UTabHerpRi{X2`0)ATA3ZV_^gjdd-oO3pZLeNWxs1U*lYj8$>XIg1V4EISSW<5| zn3{qxFKAbmc1Tb)Xsc<5Bcv6TD>=D-UeI56tgD`GDSZ0=LIWVpfg2Adcfmvg%CRK3Hlr@x@b zAY*}-4U#MLK}a@%crNi>$Fa%hC$J%+bVK8peEa(4mOXm>1ZOIgaTCFv+3j}mcinYn c`YQjJUn&xPcFYnHrvLx|07*qoM6N<$g2Z067ytkO diff --git a/airdef-mod/assets/airdef/textures/item/launch_zircon.png b/airdef-mod/assets/airdef/textures/item/launch_zircon.png index 79e324d918371d9b8cead7c81a67849c65f2d55a..1b743d913357ec817b4a47842c483c1fbbdde0f4 100644 GIT binary patch delta 100 zcmV-q0Gt1c1AqaLBV7PTNkll{L$FBP`RG@WACcAO1@ z-~+#Y-@WM3Q-DebzW=!WXWHjaH#1L9jjo0--@Z}?2~o1MdwJ0#67~P3DWIm2PN@~=~ z;R?-akjpF7Rp7i8sInm0mir=;b&biEV|2@a$D_nKM;wvXUdTz^hR>TzKkmwdosp6Y9reUi5rYLUL=E^TI5N(i zVxmJk;6p`p7Jr`-BH_}(+U_@vCXmO-6wlY^w`KL?vAU|}%l184d3~z%W_TsdKn7BRkJXeW95qhA%HSA%AY+@y5)^bsd4MJp$^K?QnB#(7*{ui3EXP-=Ho{)oPQ%imsN1sbvW?sO~$V#;g zejw+_!J|T&3CUrI{JCc5reLyK5L4V>G}W4rTk1L2WbK8+E_@ijq@31bpP zD->l8cMNFuLFE~2kH96MmO%@@G-yoLDnh0S#05OTAf8|v&R_1}PDv>_O%gtw_I%pz z-u}i*87N7Q{oqD};7>$-D>aYl+#W8~3YE~Pa{^fo+={?n23>22%0{Mb_(Eg4P%U$3 g5QOt@n)nl406KV8O<2uN0000007*qoM6N<$f|Jr^NB{r; delta 385 zcmV-{0e=300-FPnBYy#6Nkl1gh6otRNJ3HfDZ(<|jmWsk9Jq3A=6nTI= zM7nfTq)AP|dw`S@QBzP_NJt5>lgzGX=O?l&@Je2&a-=Edn>k14&cJgk+XbJ$d`r{J zvYZ&oRZF82m<+iwWMX-H{O&K0+6}1mJ+oJ@nQb;le;mx<*MH(iuYuYH>n!qp@sp|z z1fvMuBWj#6>Kt~R4F@PHf^1BJjv60FIPVG0;G7-~$hBvDUz2&ooAa|RyS}`j2=KBj zhXZu3`Hdx?dcJ;mk0e2NmL@-hQhEWh3qm8H0~2qE(Xk30kFB9Nu-MfZRc} zSEQIYEQMe^t9qtJ`)0U7e8>sX@ggr!Q%F*g7YU7{9{J%0J{G7+qIH65D#GXvae)e< zt@Ln%by;G&8f9CWbtI9HWRR$d%bvgAAQTUf6x}p(c5=F9AFn= dy: + err += dy + x0 += sx + if e2 <= dx: + err += dx + y0 += sy + + def disc(self, cx, cy, r, key): + for y in range(cy - r - 1, cy + r + 2): + for x in range(cx - r - 1, cx + r + 2): + if (x - cx) ** 2 + (y - cy) ** 2 <= r * r + 0.5 * r: + self.px(x, y, key) + + def ring(self, cx, cy, lo, hi, key): + for y in range(16): + for x in range(16): + if lo <= (x - cx) ** 2 + (y - cy) ** 2 <= hi: + self.px(x, y, key) + + def poly(self, pts, key): + # Выпуклый многоугольник: заливка по строкам между крайними пересечениями рёбер. + n = len(pts) + for y in range(min(p[1] for p in pts), max(p[1] for p in pts) + 1): + xs = [] + for i in range(n): + (x1, y1), (x2, y2) = pts[i], pts[(i + 1) % n] + if y1 == y2: + if y1 == y: + xs += [x1, x2] + elif min(y1, y2) <= y <= max(y1, y2): + xs.append(x1 + (y - y1) * (x2 - x1) / (y2 - y1)) + if xs: + for x in range(math.ceil(min(xs) - 1e-9), math.floor(max(xs) + 1e-9) + 1): + self.px(x, y, key) + + +def _sam_base(c): + c.rect(2, 8, 13, 11, "b") + c.rect(3, 12, 4, 13, "k") + c.rect(11, 12, 12, 13, "k") + + +# Развёртывание ПВО: машина + пусковая установка. +def _gepard(c): # ствольная турель, два длинных ствола + _sam_base(c) + c.disc(7, 6, 2, "b") + c.line(9, 5, 15, 5, "d") + c.line(9, 7, 15, 7, "d") + + +def _pantsir(c): # ствольная турель с ракетными контейнерами сверху + _sam_base(c) + c.disc(7, 7, 2, "b") + c.rect(4, 3, 5, 5, "l") + c.rect(9, 3, 10, 5, "l") + c.line(9, 6, 11, 6, "d") + + +def _s400(c): # три вертикальных контейнера + _sam_base(c) + for x in (3, 6, 9): + c.rect(x, 2, x + 1, 7, "b") + c.rect(x, 2, x + 1, 2, "l") + + +def _s500(c): # четыре вертикальных контейнера + _sam_base(c) + for x in (2, 5, 8, 11): + c.rect(x, 2, x + 1, 7, "b") + c.rect(x, 2, x + 1, 2, "l") + + +def _patriot(c): # наклонный пусковой короб + _sam_base(c) + c.poly([(3, 8), (11, 3), (13, 5), (5, 10)], "b") + c.line(7, 7, 9, 5, "d") + + +def _buk(c): # наклонные направляющие с ракетой + _sam_base(c) + c.line(3, 8, 10, 2, "d") + c.line(5, 9, 12, 3, "d") + c.disc(12, 2, 1, "w") + + +def _irist(c): # два наклонных контейнера + _sam_base(c) + c.poly([(3, 8), (7, 3), (9, 4), (5, 9)], "b") + c.poly([(7, 9), (11, 3), (13, 4), (9, 10)], "b") + + +def _nasams(c): # два горизонтальных контейнера + _sam_base(c) + c.rect(3, 2, 12, 3, "b") + c.rect(3, 5, 12, 6, "b") + c.line(3, 4, 12, 4, "d") + + +def _tor(c): # сетка коротких вертикальных ячеек + _sam_base(c) + for x in (3, 6, 9): + c.rect(x, 2, x + 1, 3, "b") + c.rect(x, 5, x + 1, 6, "b") + + +def _p1sun(c): # короб с мачтой + _sam_base(c) + c.rect(3, 5, 12, 7, "b") + c.line(7, 1, 7, 4, "d") + c.px(7, 1, "r") + + +# Радиолокация и РЭБ. +def _radar(c): # параболическая антенна на стойке + c.disc(8, 5, 3, "l") + c.line(8, 8, 8, 12, "d") + c.rect(5, 13, 11, 14, "d") + + +def _ew(c): # штырь-антенна с сигнальными дугами + c.line(8, 6, 8, 14, "d") + c.disc(8, 4, 1, "b") + c.line(5, 2, 4, 4, "l") + c.line(4, 4, 4, 6, "l") + c.line(4, 6, 5, 8, "l") + c.line(11, 2, 12, 4, "l") + c.line(12, 4, 12, 6, "l") + c.line(12, 6, 11, 8, "l") + + +# Снабжение. +def _depot(c): # штабель ящиков на поддоне + c.rect(3, 8, 12, 13, "b") + c.line(3, 10, 12, 10, "d") + c.line(3, 12, 12, 12, "d") + c.rect(2, 14, 13, 14, "d") + c.rect(4, 4, 9, 7, "l") + c.line(4, 6, 9, 6, "d") + + +def _tzm(c): # грузовик с кабиной и кузовом + c.rect(2, 7, 5, 11, "b") + c.rect(3, 8, 4, 9, "w") + c.rect(6, 4, 14, 11, "l") + c.rect(3, 12, 4, 13, "k") + c.rect(10, 12, 11, 13, "k") + c.rect(13, 12, 14, 13, "k") + + +# Прожектор. +def _searchlight(c): + c.rect(3, 4, 10, 8, "b") + c.poly([(10, 4), (15, 1), (15, 11), (10, 8)], "y") + c.line(6, 9, 6, 13, "d") + c.rect(3, 14, 9, 14, "d") + + +# Целеуказатель: кольцо с засечками. +def _designator(c): + c.ring(8, 8, 16, 26, "r") + c.rect(7, 1, 8, 2, "r") + c.rect(7, 13, 8, 14, "r") + c.rect(1, 7, 2, 8, "r") + c.rect(13, 7, 14, 8, "r") + c.rect(7, 7, 8, 8, "r") + + +# Пуски: огонь сзади, силуэт типа спереди. +def _launch_base(c): + c.rect(0, 7, 1, 8, "o") + c.px(0, 7, "y") + + +def _shahed(c): # треугольное крыло + _launch_base(c) + c.poly([(5, 2), (5, 13), (13, 7)], "b") + + +def _geran3(c): # реактивный самолёт со стреловидным крылом + _launch_base(c) + c.rect(3, 7, 13, 8, "b") + c.poly([(6, 7), (9, 2), (11, 2), (9, 7)], "d") + c.poly([(6, 8), (9, 13), (11, 13), (9, 8)], "d") + c.poly([(3, 7), (4, 3), (5, 3), (5, 7)], "d") + + +def _lancet(c): # малый дрон с прямым крылом + _launch_base(c) + c.rect(3, 7, 12, 8, "b") + c.rect(7, 2, 8, 13, "d") + c.rect(3, 6, 4, 9, "d") + + +def _kh101(c): # крылатая ракета: стреловидные крылья и хвост + _launch_base(c) + c.rect(3, 7, 12, 8, "b") + c.poly([(12, 6), (15, 7), (15, 8), (12, 9)], "b") + c.poly([(6, 7), (9, 3), (10, 3), (8, 7)], "d") + c.poly([(6, 8), (9, 12), (10, 12), (8, 8)], "d") + c.rect(2, 5, 3, 10, "d") + + +def _kalibr(c): # крылатая ракета: тонкий корпус и четыре хвостовых киля + _launch_base(c) + c.rect(2, 7, 13, 8, "b") + c.poly([(13, 6), (15, 7), (15, 8), (13, 9)], "b") + c.rect(2, 4, 3, 5, "d") + c.rect(2, 10, 3, 11, "d") + + +def _kh22(c): # толстый корпус с большими дельта-крыльями + _launch_base(c) + c.rect(3, 6, 11, 9, "b") + c.poly([(11, 6), (15, 7), (15, 8), (11, 9)], "b") + c.poly([(4, 6), (8, 2), (9, 2), (7, 6)], "d") + c.poly([(4, 9), (8, 13), (9, 13), (7, 9)], "d") + + +def _zircon(c): # гиперзвук: корпус с одним передним стрейком + _launch_base(c) + c.rect(2, 7, 12, 8, "b") + c.poly([(12, 7), (15, 7), (12, 8)], "b") + c.poly([(8, 7), (12, 3), (13, 3), (11, 7)], "d") + + +def _iskander(c): # баллистическая: длинный корпус, конус, сопло + _launch_base(c) + c.rect(3, 7, 11, 8, "b") + c.poly([(11, 6), (15, 7), (15, 8), (11, 9)], "l") + c.rect(2, 6, 2, 9, "d") + + +def _oreshnik(c): # баллистическая с тремя головными частями + _launch_base(c) + c.rect(2, 6, 10, 9, "b") + c.poly([(10, 5), (13, 6), (10, 7)], "l") + c.poly([(10, 8), (13, 9), (10, 10)], "l") + c.poly([(10, 6), (15, 7), (10, 8)], "b") + + +def _kinzhal(c): # аэробаллистическая: корпус с треугольными килями + _launch_base(c) + c.rect(3, 7, 11, 8, "b") + c.poly([(11, 6), (15, 7), (11, 9)], "b") + c.poly([(4, 7), (7, 3), (8, 3), (6, 7)], "d") + c.poly([(4, 8), (7, 12), (8, 12), (6, 8)], "d") + + +def _mover(c): # четыре стрелки перемещения + c.poly([(8, 0), (4, 5), (12, 5)], "b") + c.rect(7, 4, 8, 7, "b") + c.poly([(8, 15), (4, 10), (12, 10)], "b") + c.rect(7, 8, 8, 11, "b") + c.poly([(0, 8), (5, 4), (5, 12)], "b") + c.rect(4, 7, 7, 8, "b") + c.poly([(15, 8), (10, 4), (10, 12)], "b") + c.rect(8, 7, 11, 8, "b") + + +def _remover(c): # стрелка вниз над лотком: свёртывание + c.poly([(8, 9), (3, 4), (13, 4)], "b") + c.rect(7, 1, 8, 4, "b") + c.rect(2, 11, 13, 13, "b") + c.line(2, 11, 13, 11, "l") + + +def _flare(c): # звезда осветительной ракеты на стержне + c.disc(8, 7, 1, "y") + c.line(8, 2, 8, 4, "y") + c.line(8, 10, 8, 12, "y") + c.line(3, 7, 5, 7, "y") + c.line(11, 7, 13, 7, "y") + c.line(4, 4, 5, 5, "w") + c.line(11, 4, 10, 5, "w") + c.line(4, 10, 5, 9, "w") + c.line(11, 10, 10, 9, "w") + c.rect(7, 12, 8, 15, "k") + + +ICON_DRAW = { + "designator": _designator, + "launch_shahed": _shahed, "launch_geran3": _geran3, "launch_lancet": _lancet, + "launch_kh101": _kh101, "launch_kalibr": _kalibr, "launch_kh22": _kh22, + "launch_zircon": _zircon, "launch_iskander": _iskander, "launch_oreshnik": _oreshnik, + "launch_kinzhal": _kinzhal, + "deploy_patriot": _patriot, "deploy_gepard": _gepard, "deploy_pantsir": _pantsir, + "deploy_s400": _s400, "deploy_s500": _s500, "deploy_irist": _irist, + "deploy_nasams": _nasams, "deploy_buk": _buk, "deploy_tor": _tor, "deploy_p1sun": _p1sun, + "deploy_radar": _radar, "deploy_ew": _ew, + "deploy_depot": _depot, "deploy_tzm": _tzm, + "deploy_light": _searchlight, + "mover": _mover, "remover": _remover, "flare_gun": _flare, +} + + +def item_icon(name, color, seed): + c = _Icon(color, seed) + ICON_DRAW[name](c) + # Контур по краю силуэта: тёмные предметы — светлым, светлые — тёмным, чтобы читались на обоих фонах. + # Альфа-маска не меняется: контур перекрашивает только уже нарисованные пиксели. + lum = 0.3 * color[0] + 0.59 * color[1] + 0.11 * color[2] + edge = (160, 160, 160) if lum < 100 else (70, 70, 70) if lum > 190 else None + if edge: + src = c.im.copy() + + def opaque(x, y): + return 0 <= x < 16 and 0 <= y < 16 and src.getpixel((x, y))[3] > 0 + + for y in range(16): + for x in range(16): + if opaque(x, y) and not all(opaque(x + dx, y + dy) for dx, dy in ((1, 0), (-1, 0), (0, 1), (0, -1))): + c.im.putpixel((x, y), edge + (255,)) + return c.im def write_json(path, obj): @@ -1350,7 +1686,7 @@ def main(): im = GT.burn(im, zlib.crc32(name.encode()), "glass" if base.startswith("glass") else "paint") im.save(os.path.join(a, "textures", "block", name + ".png")) for i, (name, title, color) in enumerate(ITEMS): - item_icon(color, i).save(os.path.join(a, "textures", "item", name + ".png")) + item_icon(name, color, zlib.crc32(name.encode())).save(os.path.join(a, "textures", "item", name + ".png")) write_json(os.path.join(a, "models", "item", name + ".json"), {"parent": "minecraft:item/generated", "textures": {"layer0": f"{NS}:item/{name}"}}) write_json(os.path.join(a, "items", name + ".json"),