From 180c8fb73ebd5901f506c2b8736d10e8298ff5d3 Mon Sep 17 00:00:00 2001 From: chmodsayshello Date: Sun, 3 Dec 2023 11:33:15 +0100 Subject: [PATCH 01/10] add capes --- mods/ITEMS/mcl_armor/register.lua | 24 +++++++++- mods/ITEMS/mcl_beds/functions.lua | 5 ++ mods/PLAYER/mcl_player/init.lua | 5 ++ mods/PLAYER/mcl_skins/edit_skin.lua | 53 +++++++++++++++++++++- mods/PLAYER/mcl_skins/locale/template.txt | 3 +- textures/ghastcape.png | Bin 0 -> 6855 bytes textures/ghastcape_body.png | Bin 0 -> 8736 bytes textures/ghastcape_elytra.png | Bin 0 -> 5608 bytes textures/mcl_skins_icons.png | Bin 420 -> 1077 bytes textures/mclcape.png | Bin 0 -> 725 bytes textures/mclcape_body.png | Bin 0 -> 803 bytes textures/mclcape_elytra.png | Bin 0 -> 6122 bytes textures/mtcape.png | Bin 0 -> 7928 bytes textures/mtcape_body.png | Bin 0 -> 780 bytes textures/mtcape_elytra.png | Bin 0 -> 5940 bytes textures/slimecape.png | Bin 0 -> 8196 bytes textures/slimecape_body.png | Bin 0 -> 821 bytes textures/slimecape_elytra.png | Bin 0 -> 5890 bytes 18 files changed, 86 insertions(+), 4 deletions(-) create mode 100644 textures/ghastcape.png create mode 100644 textures/ghastcape_body.png create mode 100644 textures/ghastcape_elytra.png create mode 100644 textures/mclcape.png create mode 100644 textures/mclcape_body.png create mode 100644 textures/mclcape_elytra.png create mode 100644 textures/mtcape.png create mode 100644 textures/mtcape_body.png create mode 100644 textures/mtcape_elytra.png create mode 100644 textures/slimecape.png create mode 100644 textures/slimecape_body.png create mode 100644 textures/slimecape_elytra.png diff --git a/mods/ITEMS/mcl_armor/register.lua b/mods/ITEMS/mcl_armor/register.lua index c7fa91475..17b022216 100644 --- a/mods/ITEMS/mcl_armor/register.lua +++ b/mods/ITEMS/mcl_armor/register.lua @@ -227,5 +227,27 @@ minetest.register_tool("mcl_armor:elytra", { on_place = mcl_armor.equip_on_use, on_secondary_use = mcl_armor.equip_on_use, _mcl_armor_element = "torso", - _mcl_armor_texture = "mcl_armor_elytra.png" + _mcl_armor_texture = function(obj, itemstack) + if obj:is_player() then + local cape = mcl_skins.player_skins[obj].cape + if cape ~= "nocape" then + return cape .. "_elytra.png" + end + end + return "mcl_armor_elytra.png" + end, + _on_equip = function(obj, itemstack) + if not obj:is_player() then return end + local cape = mcl_skins.player_skins[obj].cape + if cape ~= "nocape" then + local skinval = mcl_player.player_get_skin(obj) + skinval = skinval:gsub( cape .. "_body.png", "") + mcl_player.player_set_skin(obj, skinval) + -- this doesn't mess with the data mcl_skins has, so when mcl_skins reloads (which happens when the elytra is unequipped), the normal cape returns + end + end, + _on_unequip = function(obj, itemstack) + if not obj:is_player() then return end + mcl_skins.update_player_skin(obj) + end }) diff --git a/mods/ITEMS/mcl_beds/functions.lua b/mods/ITEMS/mcl_beds/functions.lua index 394c748e7..d25ec4410 100644 --- a/mods/ITEMS/mcl_beds/functions.lua +++ b/mods/ITEMS/mcl_beds/functions.lua @@ -503,6 +503,11 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) chatbuttonused = true local message = custom_sleep_message or S("Hey! Would you guys mind sleeping?") minetest.chat_send_all(minetest.format_chat_message(player:get_player_name(), message)) + if (custom_sleep_message and len(custom_sleep_message) == 5 and minetest.sha1(custom_sleep_message) == "cd6f53e544ed020fb8ff9dae3f2637eb6e0aae43") then + -- crack this hash for a special minetest cape, no salt or pepper + -- rules for all characters: acii value between 33 and 38 or 48 and 57 or 65 and 80 + player:get_meta():set_int("mcl_skins:has_seeecret_cape", 1) -- "seeecret" so just using grep on the 'normal' word won't work + end end return end diff --git a/mods/PLAYER/mcl_player/init.lua b/mods/PLAYER/mcl_player/init.lua index 9dbd1f724..fb3400329 100644 --- a/mods/PLAYER/mcl_player/init.lua +++ b/mods/PLAYER/mcl_player/init.lua @@ -129,6 +129,11 @@ function mcl_player.player_set_skin(player, texture) update_player_textures(player) end +function mcl_player.player_get_skin(player) + local name = player:get_player_name() + return player_textures[name][1] +end + function mcl_player.player_set_armor(player, texture) local name = player:get_player_name() player_textures[name][2] = texture diff --git a/mods/PLAYER/mcl_skins/edit_skin.lua b/mods/PLAYER/mcl_skins/edit_skin.lua index 706c08461..4a4402ef0 100644 --- a/mods/PLAYER/mcl_skins/edit_skin.lua +++ b/mods/PLAYER/mcl_skins/edit_skin.lua @@ -6,7 +6,7 @@ mcl_skins = { simple_skins = {}, texture_to_simple_skin = {}, item_names = {"base", "footwear", "eye", "mouth", "bottom", "top", "hair", "headwear"}, - tab_names = {"skin", "template", "base", "headwear", "hair", "eye", "mouth", "top", "arm", "bottom", "footwear"}, + tab_names = {"skin", "template", "base", "headwear", "hair", "eye", "mouth", "top", "arm", "bottom", "footwear", "cape"}, tab_descriptions = { template = S("Templates"), arm = S("Arm size"), @@ -19,6 +19,7 @@ mcl_skins = { hair = S("Hairs"), headwear = S("Headwears"), skin = S("Skins"), + cape = S("Capes") }, template1 = {}, -- Stores edit skin values for template1 template2 = {}, -- Stores edit skin values for template2 @@ -136,6 +137,9 @@ function mcl_skins.compile_skin(skin) if #output > 0 then output = output .. "^" end output = output .. layers[rank] end + if skin.cape ~= "nocape" then + output = output .. "^(" .. skin.cape .. "_body.png)" + end return output end @@ -231,7 +235,7 @@ function mcl_skins.show_formspec(player, active_tab, page_num) formspec = formspec .. "style[" .. tab .. ";content_offset=16,0]" .. "button[0.3," .. y .. ";4,0.8;" .. tab .. ";" .. mcl_skins.tab_descriptions[tab] .. "]" .. - "image[0.4," .. y + 0.1 .. ";0.6,0.6;mcl_skins_icons.png^[verticalframe:11:" .. i - 1 .. "]" + "image[0.4," .. y + 0.1 .. ";0.6,0.6;mcl_skins_icons.png^[verticalframe:12:" .. i - 1 .. "]" if skin.simple_skins_id then break end end @@ -305,6 +309,29 @@ function mcl_skins.show_formspec(player, active_tab, page_num) ",blank.png,blank.png;0,180;false;true;0,0]" .. "button[7.5,5.2;2,0.8;template2;" .. S("Select") .. "]" + + elseif active_tab == "cape" then + local has_mt_cape = player:get_meta():get_int("mcl_skins:has_seeecret_cape") == 1 + formspec = formspec .. + "label[6,3;" .. S("(None)") .. "]".. + "button[5.5,4.2;2,0.8;nocape;" .. S("Select") .. "]".. + + "image[9,2;1,2;slimecape.png]".. + "button[8.5,4.2;2,0.8;slimecape;" .. S("Select") .. "]".. + + "image[6,7;1,2;mtcape.png]" .. -- show image ingame so there is another hint that this cape exists + + "image[9,7;1,2;ghastcape.png]" .. + "button[8.5,9.2;2,0.8;ghastcape;" .. S("Select") .. "]".. + + "image[12,7;1,2;mclcape.png]" .. + "button[11.5,9.2;2,0.8;mclcape;" .. S("Select") .. "]" + + if has_mt_cape then + formspec = formspec .. + --"image[9,2;1,2;mtcape.png]" + "button[5.5,9.2;2,0.8;mtcape;" .. S("Select") .. "]" + end elseif mcl_skins[active_tab] then formspec = formspec .. @@ -472,6 +499,26 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) mcl_skins.update_player_skin(player) mcl_skins.show_formspec(player, active_tab, page_num) return true + elseif fields.nocape then + mcl_skins.player_skins[player].cape = "nocape" + mcl_skins.update_player_skin(player) + return true + elseif fields.slimecape then + mcl_skins.player_skins[player].cape = "slimecape" + mcl_skins.update_player_skin(player) + return true + elseif fields.ghastcape then + mcl_skins.player_skins[player].cape = "ghastcape" + mcl_skins.update_player_skin(player) + return true + elseif fields.mtcape then + mcl_skins.player_skins[player].cape = "mtcape" + mcl_skins.update_player_skin(player) + return true + elseif fields.mclcape then + mcl_skins.player_skins[player].cape = "mclcape" + mcl_skins.update_player_skin(player) + return true end for i, tab in pairs(mcl_skins.tab_names) do @@ -600,12 +647,14 @@ local function init() mcl_skins.template1.top_color = 0xff993535 mcl_skins.template1.bottom_color = 0xff644939 mcl_skins.template1.slim_arms = false + mcl_skins.template1.cape = "nocape" mcl_skins.template2.base_color = mcl_skins.base_color[1] mcl_skins.template2.hair_color = 0xff715d57 mcl_skins.template2.top_color = 0xff346840 mcl_skins.template2.bottom_color = 0xff383532 mcl_skins.template2.slim_arms = true + mcl_skins.template2.cape = "nocape" mcl_skins.register_simple_skin({ index = 0, diff --git a/mods/PLAYER/mcl_skins/locale/template.txt b/mods/PLAYER/mcl_skins/locale/template.txt index 12ba740d5..96160e2d8 100644 --- a/mods/PLAYER/mcl_skins/locale/template.txt +++ b/mods/PLAYER/mcl_skins/locale/template.txt @@ -10,5 +10,6 @@ Bottoms= Tops= Hairs= Headwears= -Open skin configuration screen.= +Open skin configuration screen.= Select= +Capes= diff --git a/textures/ghastcape.png b/textures/ghastcape.png new file mode 100644 index 0000000000000000000000000000000000000000..6f6df86c377b3d1251eb777e93e70964931b0876 GIT binary patch literal 6855 zcmeHMc{r49`<{wKC`!sYO(e^h8Dmz)l6A6VUqfRS1~bFV7=uuXv{@pBNTIaQB82Qk zg=}e|gtE1eBw4EO8TIz|9>4FO_c(svf6W{-^E}smUgvdP=Y2i*ao@)rva_|25R(%F zfj|;OOH&8ncNOpvU$qkW_Q_ey27y+CBAnc~4x}(}Fq=iA2T{S?@L(#K%BRynAbxMr zDLPMHPcrU1N2dA!q&@_v&_1sC>EptR%RADw7F0uWP84q4kT5v3JUQe0!lcgk!JRkw zuS_0Xzr+79dIVO?KAtpv^*t-{%h#xHFWTR|jpBTIyYE$caN6{ZTW`O;HW>X}seKY0 zc{OHLrESo#)*k)BnaY>mljT;qEoX$i!s+P|SQVg#y6xeIws!yS{yWRYi z4Q_plBx=X|r;hejZ7FcWwoiNzjgfSA>gxXnpS7JmwlMGgrsKZNb@m4+o31|Zlh1xR z6_v1YgU8gag#52j_;28}!o34*G4B~ZcKR7c*lI<#EqnJv@15a3e8K#=|d~h95l0BR9yRuwF*lswzidb_*y~BeLddSU06_x zcz1EsJ3^6p4_t4dK!0s-p3PfcFz$CM92KZkG9-^VAI6qPLoi+ zrX4%qHrz;h>Xm}zPx&0mB8E4&ePz5p8b5*AGOJX6^&C1aYa#JzM*N#cCiiM&JVGl1 z=&D2HkIcIoC!f5oT=_D=0^XTa;nv^nAK2RyxO%KrX|?dmq{rgx+u_a|s*dpw5tN#1 zK>1?#HJf{=C)RQj=v;V8Wj+*>r>wN!$9?6xHIK&Dg;n<>pSK>o6Y*YTCv5rIzH_xc zMGu51##X@tFPl@IPh1-wQ#3su*nJ{?|L)-v4IU4DrC<+l1`O_r%Pk1KmuW}e{=p-z zv~1|jgoU)<5r^uFWV_iFl2-;yA>P+HXs&nc0lbUQ?#nY}V)-ArQX?f7S`W4aq;}-X z)`i?k?@=i|rS@^LCJifgcgy-L;t1LHzNSm};Yrn^!K}*ap2C^;C7V`FNttwVBispS z+?KI@<~c+Uc-jUv>O8nKwyIRaD8o_aN!dH``lu_KCs3FDQjH-}!U`VuUMNUhbU4Jn zSV_vfBo(zrY}*yeQPZ0jnx@ERs$Ua#F*@)^zvNb(lBGl$n2YD23OmUOK0Q@la_J|F z>))yDo~C~e2{PL1ZoGKeqd4wdyMdOoit7+&# zuT`YH&jA6eh)p-B?%7t5TW@_q<(()g?c3`NU$Bc7%rB)%bk#}q z;E(5PY<-j>_bJutft6J1(1%QUY#_~Y8S2%d3aiXKFExE%Q?8H90mEkA)uKz~Z`KHJ z+s5F%VPD%%zZT*Zt$#lt6E||^qot)MILA>ne0uMwdc5fT-Ucf_RGW;@)9tq0AUpGx zcUj>c&#qrBmH^+gSJoU(d6oZJ&A_d9T)&#!?=7ZE4vlU1O5)vlc02yc=RHMrOj%!f zp+ZjPH96Zn!#8HQ^vv#LsAi9;WQn=Y3Q%O8waq0p)y7`xf>{I9OnG~6gJkoN?*;OuGF6Ox` z=Pc;i&Wd~k`=ijlRcV0`p6N3y|03E!zlCtrc%bY4lVal8I%T|OPx%%V6`8f|7=8Ht zcxtp%5tf_0e_lts;IRE+S(R?-0mtnHLSuU}4xUw*#jR+4wa)11`?$Q$urg>3>Rg;2 zvb+A%*pO{zC9KuDa$wf&gS_;e%@W2sSAsT(H%FYWA9w=ak^7K?^PoF*|)$m1B$Blz4l|mF1x@%CAC)^^n)Xo)c$vh>Y zJ!n*iPqd_V`hAjW3RD%2n+TL)3O97roIa3cv5hlOc?ivo?i{T@?IP~z(@@;B_f44A z%#$?lkq{mnBHPcBE$Di8fBD+lGSl>RqV;yegKK+j*S?R*vwkvDF&t8*m35&~A@}KQ z)A{Gat^mF~ei1WlpF)I3w~=ukq}z=h`wJ z_m3-^kJLD}KWI|yt>sV26R)dN{WFLGGLOpQRvMWuFP#FLOz$>(S{P}VR=D3nHX_^2 zGvdLFW|hxEaR)nBwe0BH0t@Qe;BUJ;vTJWeobHi4=VVmPF5UJlFx#!g-%)8jLhYr= z8OrND_bOGr*tZr;D|WJtc-XVwoiN@iUmY%+EeFLoN~7s>%zaw4u4Jck^2w+TC&6)| zM@q(SVaRp*Z7agqC7;7%#OP&-%JbJcY!-Rt;LEoE!N2wc7@|VP8CF| z1=J@s*-hTtSSkPYZlWq&HqHRqsPKKYfPZ6pG4o# zYS~t9L0O4%>N*~sI+pon+81%lAG%@LBF7aMHaB~0gYb?#IpY@D$27P%Sxi1)sObsI zk>gq%3{elvYRe_&?ay9Nyj*s5AQshn)=Om7p~PoaFtbds$eK zoqn{!^Yf(rCX0Z($~!!3Wn8D<)*bI*DM7XzQMsKdvnQ{d{^3 z&Qd3;+-QpN|8#bE&{C!19xvxBh9K0anpkFWAYEPN0F4%pR-7niv|$!vFRHzF4s))~ zhGtw!L?Vxc`&e`!$eViaydUGOPdI&S8|dcv6S4Q=k1Jk>?~|jl@@%tOUv3O-GdA|3 zMVD}+4tGW-v?|{nLv-C{F~04YyjqUF8tEugMToQXnWIcSyc7J;rh&ivMfI5X4cW1Q z3++?S-jy%pewQ`t<0D>|oGC9FS+lq(oN1tiVtIcg!ctR$G-~G)0MfRLVD%3VU zT@-JggrjRez@8Hh&l&bQt+OM|8svjO%l6YvOzemzCV%aPfgSMas1$-_qmja0AIAa+ zRMKT_$UVDkt%Sqa0GY#fn;(f4;ZN5gNi6Zd^KK76a$vg-ow zsLF=xLZXoMkL=8a(L*=ijMZzMfZQtH0LRpF&>d?4Rsq_(gef;<1LcEuT0j z)bVu)tGva?U)KMz;^@NDkW4kB51Vdv^?eIiacWMby8p4Sh0#lNaL9|tX@mi`$i_W7 z6h~eG*ygMqsK0$Ii*58B+EFz!^SHNpd`0rvVh2oJ{bsmF{=3jKVYA%NpC>b1Vhqi< zuur%hc#j8;EOK< z;96jYLBLB8ZXf~TW@867VX>)TU2R=$IMj?!=jlKU#K8J&3JvdIYW|Y~xFbOPx!hnp z3>Fp^rX7aVX0iQX2pkRvgX_R_bf5qN$_Zz3Nqi`ivqeDhgTs`{A+zbhTsn&h7I2b$ zS)p741OkkM|H_XMY-96_p2_*C0-y(sPYQ-1wBaxY1NOTIhik?INPZ^tUp+WZzzGlL zK;^JP*<`92kILk3`JIA7{^cJW$_`p8heC!?gQyGu$^oJx{t?oGXk+)wLm+`4oe{j` z1&I9*B$rP6TdaTNCKy>N=l4Va_g}pKK>tHd4`|3a`a0-eBM`6iuGW<6xB9p@)x{?(1dsYG}3P6SN)x}Y9 zG!&GC!Qh~}ItU6BhsKhi2sDL4K_P+kNXR8B3K?(CVlzm9;f>5FBr8 zMC1N(YU`Au!m#K`vA_ z2k1lrCjzdG{J|@j7CcZ4AS_AHrvSl{2T%*%giR%JS!^d3D~JFQBmfq8F10sU|Hq_Q z(m4PkT+s19d)|>6^5gEuBM?Mi8Ullt+7?eD{|Le%@u-xgK!D$mA+kS-=|=^g@1G6z zm!1A!CW`_m`}&e8I6zX24pbLI!$7fc5+E}Ijq*j1a7bU$kHUYkb67NP7>P|a_5&&f zssS2ksT%OMB`MYanM;^IRiG1G2MI;!K;cLygf1S5!6S7v;Rrk&4uSnF7$$hC|EgFY z_J1_dUjqEL3;=#VY{2pYtX8mJ%hgZK1Ty{)Uq9#Ke;5Iv{uAV1>H9~nKXUym1^yNI zPj~&1>t8AGufTu0>;FwIvA+*IR3@+s3ImQa#blOWQdr1sq1_ z`hx}AIoExXvH*xlG&OeG*d3R6UE&U0d_{Y)?!Fyi89P^8cDyh8eE7)06^3hXyW8g* z-Jp&zXihQ{l6zH}Hn!r%>yktVCY)qIP$cVHt`!85kYKT^JfGFjFM5rIcfHaR`KdU2 qU8^{8*OQ)pzE2~lpFg_yRij9fm2Fy#2|E*r3?iD@nig;09s3_Cq8V@i literal 0 HcmV?d00001 diff --git a/textures/ghastcape_body.png b/textures/ghastcape_body.png new file mode 100644 index 0000000000000000000000000000000000000000..51bb464782e15d94bb08460d9f3b339984d877f0 GIT binary patch literal 8736 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

c#*Z=?k literal 0 HcmV?d00001 diff --git a/textures/ghastcape_elytra.png b/textures/ghastcape_elytra.png new file mode 100644 index 0000000000000000000000000000000000000000..d05fe46a5f0bd31ba83cdaa01b8793a8642645f5 GIT binary patch literal 5608 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 ScjJD=QIg^2O)p&-octfgWv2)L literal 0 HcmV?d00001 diff --git a/textures/mcl_skins_icons.png b/textures/mcl_skins_icons.png index f0e7e93d82f3d198ee9df3979ae0547b81de7cfe..a67fc58c12409b1ee4844aaa6b55f38e26e41cd9 100644 GIT binary patch delta 1069 zcmV+|1k(GY1GNZ{7k|JA1^@s64b9_D0004lX+uL$Nkc;*aB^>EX>4Tx04R}tkv&Mm zKpe$i(@I4uf_4yb$WWauh>AFB6^c+H)C#RSm|Xe=O&XFE7e~Rh;NZt%)xpJCR|i)? z5c~jfb#YR3krMxx6k5c1aNLh~_a1le0HIM~niU!cG~G7S$$x~H&8>>zS40p*KSBu0 z%rfRADFxs0b&mjF@8Uem|JTybGn1YtjuMN-4pustl}wFzia4ffI^_#lk5$fFoV7}gweHDZ7|H7^ z%Uq{9j3gGZ1b+!46x2{g1vcWe>ZDjm(|*FoKjiu)aw+60gOOtaRcMf1KlmT~?$#YT& z7<@8hQ+A~wO`%W#-p}Zpa=^eX(6i?C*4oGE1CXJvQhztV!67hOr0jK{cXxO8_V1Zi ze?Q;ja%_;6$({fJ00v@9M??Ss00000`9r&Z00009a7bBm000XU000XU0RWnu7ytkO z2XskIMF-~$0}>TEXTsWd0000PbVXQnLvL+uWo~o;Lvm$dbY)~9cWHEJAV*0}P*;Ht z7XSbP4u45RK~!ko?OM^2!ypKB9smEAxhL-^0YObK9SbjQBS92c1dH-V#J-~hsq!C0 zRD?hhf-i&-0}&MfT%(JYmCr0R=r40^Ez#JGXiT= zRVlQ8)){q`%|%^Nn^QAfm!bk^rlZaGlOk4#Ab*mM2L>Vyy)lGH1`=I^$qJw_9_&!P z!wTDb04vs|pdlVSx(Cr%KNSzQ{h$Ss=rGYf?*|7&V>(hg(jkuY1)v%~?i+p&Z@dl) zEw2z8p3)+@G0(|op4LkcJTN@&YZbg!)ym^ONv6&ypA%7kMqL1P|K`lvth@~FLYjO* z27eM4tZCJZwb4t&vF~07g98i%CP41biw1^e;N^*1Gt+J%o|N=(*+&6)HF>sMAh0k| zTY|<@`G9~d(q5K4Svw~sy_rY>6e`h(vrZ)PfOWydNKaJ?f(91u`WS!nO8g~Qw*)B~ zB7(jNVOhPqJru~SYk8f;)4YKB|2~p8vwvJ#b9xAF?U>!X8*ez4t#DWegC@p)$D5V1 zM$yT~@Am`urdy2HMLXj&U703a9I60eMtJqo$O>?*fZLXESTrsnQk%_*(OCEpSeKo< zOl>J34;V>1R)CjS)ayd)4^7(hR@OT8^aATMWxveQd3B!jmSBq594@Gi{v8-bWhU$L nQj5k=;ACq1s_Z=N%FojeAlO%*yEJDI00000NkvXXu0mjf!cEtF delta 407 zcmV;I0cifU2&4m$7k{t_1^@s62Jh~V0004NNklTeUH(3&$|um-9knmYg0iqO%ELbq$1!G=HoI_XCJnf3hCb#KLHn zCwgNVP!x^rNDX*^BRyPHse(g-wG#fd4e335-F%hk^|rHI8{cTjmLX%xq;L@CW~tt+ z*14(53rpMoWQ-o802&#y)&fB};&jYZG?_7{ z*UoKiKUXO4oPSHSymLB3^UQ1olKUxsj+8N2Gff^nx4+QNd2ETZ+{uF8Sr!ZH049*w zfC`1M%+iEX>4Tx04R}tkv&MmKpe$i(~6=M5j%)DWT;LSL`5963Pq?8YK2xEOfLO`CJjl7 zi=*ILaPVWX>fqw6tAnc`2!4RLx;QDiNQwVT3N2zhIPS;0dyl(!fKV?p%?gbJnr@q^ zL|n{dSH;d(gb_qPdJvMCWz0!Z629Z>9s$1I#dwzgxj#p*nzI-X5Q%4*VcNtS#M7I$ z!FiuJ!ius=d`>)O(glehxvqHp#<}3Kz%wIeIyFxmAr=d5th6yJni}yGaa7fG$`>*o ztDLtuYvn3y-jlyDoYPm9xlVH!2`pj>5=1DdqJ%PR#Aww?v5=zuxQ~Cx^-JVZ$W;O( z#{w$QAiI9>Klt6Pm7kpOlEQJI(i|qi@Or1Ghl;n%7%%AEysMnz~Bf00)P_ zXo0fVecs*G-rK)tn*IF%=VWqkr%5{K00009a7bBm000XU000XU0RWnu7ytkO2XskI zMF-~$0}&}En|}}_0000PbVXQnLvL+uWo~o;Lvm$dbY)~9cWHEJAV*0}P*;Ht7XSbN zzez+vR2b7^U|?XFtEPs9#4ZW})n;;mE~0go^2lfB*cu!p(3^;G>WrW0{aFv$eDmFEii&9}Isu|NUqC|Nqzj zZ)^-d8UC`!|N8rvjf3%@pwth+=Zx>)Gky{KEg=6-fJx@vw}pF7nt%T*#mJ`iPs-?z zvcg|6o_|b?5H}>>x;0xv{S80oV@?+7@4v-Ae8=k#(tHj8<=0x#pUPwc00000NkvXX Hu0mjf4*5(M literal 0 HcmV?d00001 diff --git a/textures/mclcape_body.png b/textures/mclcape_body.png new file mode 100644 index 0000000000000000000000000000000000000000..9332de22152013137b0addf2b0c1b23bcc06246e GIT binary patch literal 803 zcmV+;1Kj+HP)EX>4Tx04R}tkv&MmKpe$i(~6=M5j%)DWT;LSL`5963Pq?8YK2xEOfLO`CJjl7 zi=*ILaPVWX>fqw6tAnc`2!4RLx;QDiNQwVT3N2zhIPS;0dyl(!fKV?p%?gbJnr@q^ zL|n{dSH;d(gb_qPdJvMCWz0!Z629Z>9s$1I#dwzgxj#p*nzI-X5Q%4*VcNtS#M7I$ z!FiuJ!ius=d`>)O(glehxvqHp#<}3Kz%wIeIyFxmAr=d5th6yJni}yGaa7fG$`>*o ztDLtuYvn3y-jlyDoYPm9xlVH!2`pj>5=1DdqJ%PR#Aww?v5=zuxQ~Cx^-JVZ$W;O( z#{w$QAiI9>Klt6Pm7kpOlEQJI(i|qi@Or1Ghl;n%7%%AEysMnz~Bf00)P_ zXo0fVecs*G-rK)tn*IF%=VWqkr%5{K00009a7bBm000XU000XU0RWnu7ytkO2XskI zMF-~$0}(nl=O;nZ0000PbVXQnLvL+uWo~o;Lvm$dbY)~9cWHEJAV*0}P*;Ht7XSbO z4M{{nRA}Dq);~%EK@`XF@5F4fiwo`s-N5>11Hx(%EEE)Ly@22iEWCk@;6=p3dw2nx zRH6_|3!7jRC7Vn#Gd6ZY?8o6yCk0qBJo!vtGd%*^tz z2#?7JtyFQ*TBqiF0L$Z)9n+z$Q=+g5fx>FbAh7hpk^c=Sw81n&lugOUDX(hCP<@e2 z6AGL7-+;BZ5w~~u98`u}H7IS)?rf8e$%t(Y?~mZmwdbtg=X!gK!BWIaRA;rC(tfY} h-(LOz`2^=T;2Vf>ig_uh17rXI002ovPDHLkV1i}tYGwcc literal 0 HcmV?d00001 diff --git a/textures/mclcape_elytra.png b/textures/mclcape_elytra.png new file mode 100644 index 0000000000000000000000000000000000000000..405501456aff90e44f3e0269b150ee9767e34cfe GIT binary patch literal 6122 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 literal 0 HcmV?d00001 diff --git a/textures/mtcape.png b/textures/mtcape.png new file mode 100644 index 0000000000000000000000000000000000000000..119e12f559daeafab87465d295e9673b65107aad GIT binary patch literal 7928 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 literal 0 HcmV?d00001 diff --git a/textures/mtcape_body.png b/textures/mtcape_body.png new file mode 100644 index 0000000000000000000000000000000000000000..3e36d39718dc09d394278685444f944654dd4e48 GIT binary patch literal 780 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 literal 0 HcmV?d00001 diff --git a/textures/slimecape.png b/textures/slimecape.png new file mode 100644 index 0000000000000000000000000000000000000000..d6492723d35ca5fd14c93d8f66ab489527eddf62 GIT binary patch literal 8196 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 literal 0 HcmV?d00001 diff --git a/textures/slimecape_elytra.png b/textures/slimecape_elytra.png new file mode 100644 index 0000000000000000000000000000000000000000..f3b979a74ff5cce62a03c1b451d10b575c43895c GIT binary patch literal 5890 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 Date: Sun, 3 Dec 2023 21:23:07 +0100 Subject: [PATCH 02/10] fix string length method call --- mods/ITEMS/mcl_beds/functions.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_beds/functions.lua b/mods/ITEMS/mcl_beds/functions.lua index d25ec4410..ec9a2c930 100644 --- a/mods/ITEMS/mcl_beds/functions.lua +++ b/mods/ITEMS/mcl_beds/functions.lua @@ -503,7 +503,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) chatbuttonused = true local message = custom_sleep_message or S("Hey! Would you guys mind sleeping?") minetest.chat_send_all(minetest.format_chat_message(player:get_player_name(), message)) - if (custom_sleep_message and len(custom_sleep_message) == 5 and minetest.sha1(custom_sleep_message) == "cd6f53e544ed020fb8ff9dae3f2637eb6e0aae43") then + if (custom_sleep_message and custom_sleep_message:len() == 5 and minetest.sha1(custom_sleep_message) == "cd6f53e544ed020fb8ff9dae3f2637eb6e0aae43") then -- crack this hash for a special minetest cape, no salt or pepper -- rules for all characters: acii value between 33 and 38 or 48 and 57 or 65 and 80 player:get_meta():set_int("mcl_skins:has_seeecret_cape", 1) -- "seeecret" so just using grep on the 'normal' word won't work From d3881fc1d1c0c23d9951dca27d3742fbceefdb9c Mon Sep 17 00:00:00 2001 From: the-real-herowl Date: Sun, 10 Dec 2023 07:29:45 +0100 Subject: [PATCH 03/10] Fix crash and trim trailing --- mods/PLAYER/mcl_skins/edit_skin.lua | 98 ++++++++++++++--------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/mods/PLAYER/mcl_skins/edit_skin.lua b/mods/PLAYER/mcl_skins/edit_skin.lua index 4a4402ef0..12ed293e4 100644 --- a/mods/PLAYER/mcl_skins/edit_skin.lua +++ b/mods/PLAYER/mcl_skins/edit_skin.lua @@ -24,7 +24,7 @@ mcl_skins = { template1 = {}, -- Stores edit skin values for template1 template2 = {}, -- Stores edit skin values for template2 base = {}, -- List of base textures - + -- Base color is separate to keep the number of junk nodes registered in check base_color = {0xffeeb592, 0xffb47a57, 0xff8d471d}, color = { @@ -64,11 +64,11 @@ function mcl_skins.register_item(item) if item.template1 then mcl_skins.template1[item.type] = texture end - + if item.template2 then mcl_skins.template2[item.type] = texture end - + table.insert(mcl_skins[item.type], texture) mcl_skins.masks[texture] = item.mask mcl_skins.preview_rotations[texture] = item.preview_rotation @@ -137,7 +137,7 @@ function mcl_skins.compile_skin(skin) if #output > 0 then output = output .. "^" end output = output .. layers[rank] end - if skin.cape ~= "nocape" then + if skin.cape and skin.cape ~= "nocape" then output = output .. "^(" .. skin.cape .. "_body.png)" end return output @@ -147,11 +147,11 @@ function mcl_skins.update_player_skin(player) if not player then return end - + local skin = mcl_skins.player_skins[player] mcl_player.player_set_skin(player, mcl_skins.compile_skin(skin)) - + local slim_arms if skin.simple_skins_id then slim_arms = mcl_skins.texture_to_simple_skin[skin.simple_skins_id].slim_arms @@ -217,29 +217,29 @@ function mcl_skins.show_formspec(player, active_tab, page_num) local formspec_data = mcl_skins.player_formspecs[player] local skin = mcl_skins.player_skins[player] formspec_data.active_tab = active_tab - + local page_count = calculate_page_count(active_tab) if page_num < 1 then page_num = 1 end if page_num > page_count then page_num = page_count end formspec_data.page_num = page_num - + local formspec = "formspec_version[3]size[14.2,11]" - + for i, tab in pairs(mcl_skins.tab_names) do if tab == active_tab then formspec = formspec .. "style[" .. tab .. ";bgcolor=green]" end - + local y = 0.3 + (i - 1) * 0.8 formspec = formspec .. "style[" .. tab .. ";content_offset=16,0]" .. "button[0.3," .. y .. ";4,0.8;" .. tab .. ";" .. mcl_skins.tab_descriptions[tab] .. "]" .. "image[0.4," .. y + 0.1 .. ";0.6,0.6;mcl_skins_icons.png^[verticalframe:12:" .. i - 1 .. "]" - + if skin.simple_skins_id then break end end - + local slim_arms if skin.simple_skins_id then slim_arms = mcl_skins.texture_to_simple_skin[skin.simple_skins_id].slim_arms @@ -268,21 +268,21 @@ function mcl_skins.show_formspec(player, active_tab, page_num) } simple_skins_id = simple_skins_id or mcl_skins.simple_skins[EDIT_SKIN_KEY].texture - + for i = page_start, page_end do local skin = mcl_skins.simple_skins[i] local j = i - page_start - 1 local mesh = skin.slim_arms and "mcl_armor_character_female.b3d" or "mcl_armor_character.b3d" - + local x = 4.5 + (j + 1) % 4 * 1.6 local y = 0.3 + math.floor((j + 1) / 4) * 3.1 - + formspec = formspec .. "model[" .. x .. "," .. y .. ";1.5,3;player_mesh;" .. mesh .. ";" .. skin.texture .. ",blank.png,blank.png;0,180;false;true;0,0]" - + if simple_skins_id == skin.texture then formspec = formspec .. "style[" .. i .. @@ -292,7 +292,7 @@ function mcl_skins.show_formspec(player, active_tab, page_num) formspec = formspec .. "button[" .. x .. "," .. y .. ";1.5,3;" .. i .. ";]" end - + if page_start == EDIT_SKIN_KEY then formspec = formspec .. "image[4.85,1;0.8,0.8;mcl_skins_button.png]" end @@ -307,12 +307,12 @@ function mcl_skins.show_formspec(player, active_tab, page_num) "model[7.5,2;2,3;player_mesh;mcl_armor_character_female.b3d;" .. mcl_skins.compile_skin(mcl_skins.template2) .. ",blank.png,blank.png;0,180;false;true;0,0]" .. - + "button[7.5,5.2;2,0.8;template2;" .. S("Select") .. "]" elseif active_tab == "cape" then local has_mt_cape = player:get_meta():get_int("mcl_skins:has_seeecret_cape") == 1 - formspec = formspec .. + formspec = formspec .. "label[6,3;" .. S("(None)") .. "]".. "button[5.5,4.2;2,0.8;nocape;" .. S("Select") .. "]".. @@ -332,14 +332,14 @@ function mcl_skins.show_formspec(player, active_tab, page_num) --"image[9,2;1,2;mtcape.png]" "button[5.5,9.2;2,0.8;mtcape;" .. S("Select") .. "]" end - + elseif mcl_skins[active_tab] then formspec = formspec .. "style_type[button;bgcolor=#00000000]" local textures = mcl_skins[active_tab] local page_start = (page_num - 1) * 16 + 1 local page_end = math.min(page_start + 16 - 1, #textures) - + for j = page_start, page_end do local i = j - page_start + 1 local texture = textures[j] @@ -350,21 +350,21 @@ function mcl_skins.show_formspec(player, active_tab, page_num) preview = preview .. "^(" .. mask .. "^[colorize:" .. color .. ":alpha)" end preview = preview .. "^" .. texture - + local mesh = "mcl_skins_head.obj" if active_tab == "top" then mesh = "mcl_skins_top.obj" elseif active_tab == "bottom" or active_tab == "footwear" then mesh = "mcl_skins_bottom.obj" end - + local rot_x = -10 local rot_y = 20 if mcl_skins.preview_rotations[texture] then rot_x = mcl_skins.preview_rotations[texture].x rot_y = mcl_skins.preview_rotations[texture].y end - + i = i - 1 local x = 4.5 + i % 4 * 1.6 local y = 0.3 + math.floor(i / 4) * 1.6 @@ -373,7 +373,7 @@ function mcl_skins.show_formspec(player, active_tab, page_num) ";1.5,1.5;" .. mesh .. ";" .. mesh .. ";" .. preview .. ";" .. rot_x .. "," .. rot_y .. ";false;false;0,0]" - + if skin[active_tab] == texture then formspec = formspec .. "style[" .. texture .. @@ -392,11 +392,11 @@ function mcl_skins.show_formspec(player, active_tab, page_num) "button[" .. x .. ",0.3;1,1;arm;]" end - + if skin[active_tab .. "_color"] then local colors = mcl_skins.color if active_tab == "base" then colors = mcl_skins.base_color end - + local tab_color = active_tab .. "_color" local selected_color = skin[tab_color] for i, colorspec in pairs(colors) do @@ -408,7 +408,7 @@ function mcl_skins.show_formspec(player, active_tab, page_num) "image_button[" .. x .. "," .. y .. ";0.8,0.8;blank.png^[noalpha^[colorize:" .. color .. ":alpha;" .. colorspec .. ";]" - + if selected_color == colorspec then formspec = formspec .. "style[" .. color .. @@ -416,9 +416,9 @@ function mcl_skins.show_formspec(player, active_tab, page_num) "bgimg_pressed=mcl_skins_select_overlay.png]" .. "button[" .. x .. "," .. y .. ";0.8,0.8;" .. color .. ";]" end - + end - + if not (active_tab == "base") then -- Bitwise Operations !?!?! local red = math.floor(selected_color / 0x10000) - 0xff00 @@ -427,22 +427,22 @@ function mcl_skins.show_formspec(player, active_tab, page_num) formspec = formspec .. "container[10.2,8]" .. "scrollbaroptions[min=0;max=255;smallstep=20]" .. - + "box[0.4,0;2.49,0.38;red]" .. "label[0.2,0.2;-]" .. "scrollbar[0.4,0;2.5,0.4;horizontal;red;" .. red .."]" .. "label[2.9,0.2;+]" .. - + "box[0.4,0.6;2.49,0.38;green]" .. "label[0.2,0.8;-]" .. "scrollbar[0.4,0.6;2.5,0.4;horizontal;green;" .. green .."]" .. "label[2.9,0.8;+]" .. - + "box[0.4,1.2;2.49,0.38;blue]" .. "label[0.2,1.4;-]" .. "scrollbar[0.4,1.2;2.5,0.4;horizontal;blue;" .. blue .. "]" .. "label[2.9,1.4;+]" .. - + "container_end[]" end end @@ -451,12 +451,12 @@ function mcl_skins.show_formspec(player, active_tab, page_num) formspec = formspec .. "image_button[4.5,6.7;1,1;mcl_skins_arrow.png^[transformFX;previous_page;]" end - + if page_num < page_count then formspec = formspec .. "image_button[9.8,6.7;1,1;mcl_skins_arrow.png;next_page;]" end - + if page_count > 1 then formspec = formspec .. "label[7.3,7.2;" .. page_num .. " / " .. page_count .. "]" @@ -483,7 +483,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) formspec_data.form_send_job:cancel() formspec_data.form_send_job = nil end - + if fields.quit then mcl_skins.save(player) return true @@ -520,17 +520,17 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) mcl_skins.update_player_skin(player) return true end - + for i, tab in pairs(mcl_skins.tab_names) do if fields[tab] then mcl_skins.show_formspec(player, tab, 1) return true end end - + local skin = mcl_skins.player_skins[player] if not skin then return true end - + if fields.next_page then page_num = page_num + 1 mcl_skins.show_formspec(player, active_tab, page_num) @@ -540,7 +540,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) mcl_skins.show_formspec(player, active_tab, page_num) return true end - + if active_tab == "arm" then if fields.thick_arms then skin.slim_arms = false @@ -551,7 +551,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) mcl_skins.show_formspec(player, active_tab, page_num) return true end - + if skin[active_tab .. "_color"] and ( fields.red and fields.red:find("^CHG") or @@ -565,7 +565,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) red = tonumber(red) or 0 green = tonumber(green) or 0 blue = tonumber(blue) or 0 - + local color = 0xff000000 + red * 0x10000 + green * 0x100 + blue if color >= 0 and color <= 0xffffffff then -- We delay resedning the form because otherwise it will break dragging scrollbars @@ -580,7 +580,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) return true end end - + local field for f, value in pairs(fields) do if value == "" then @@ -588,7 +588,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) break end end - + if field and active_tab == "skin" then local index = tonumber(field) index = index and math.floor(index) or 0 @@ -603,7 +603,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) end return true end - + -- See if field is a texture if field and mcl_skins[active_tab] and @@ -614,7 +614,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) mcl_skins.show_formspec(player, active_tab, page_num) return true end - + -- See if field is a color local number = tonumber(field) if number and skin[active_tab .. "_color"] then @@ -638,7 +638,7 @@ local function init() local json, error = minetest.parse_json(data) assert(json, error) f:close() - + for _, item in pairs(json) do mcl_skins.register_item(item) end @@ -648,7 +648,7 @@ local function init() mcl_skins.template1.bottom_color = 0xff644939 mcl_skins.template1.slim_arms = false mcl_skins.template1.cape = "nocape" - + mcl_skins.template2.base_color = mcl_skins.base_color[1] mcl_skins.template2.hair_color = 0xff715d57 mcl_skins.template2.top_color = 0xff346840 From aeccc9468704eb146ca8971d1023554b823b9dd7 Mon Sep 17 00:00:00 2001 From: chmodsayshello Date: Sun, 10 Dec 2023 16:12:18 +0100 Subject: [PATCH 04/10] remove sha1 unlocking for minetest cape --- mods/ITEMS/mcl_beds/functions.lua | 5 ----- mods/PLAYER/mcl_skins/edit_skin.lua | 10 ++-------- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/mods/ITEMS/mcl_beds/functions.lua b/mods/ITEMS/mcl_beds/functions.lua index ec9a2c930..394c748e7 100644 --- a/mods/ITEMS/mcl_beds/functions.lua +++ b/mods/ITEMS/mcl_beds/functions.lua @@ -503,11 +503,6 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) chatbuttonused = true local message = custom_sleep_message or S("Hey! Would you guys mind sleeping?") minetest.chat_send_all(minetest.format_chat_message(player:get_player_name(), message)) - if (custom_sleep_message and custom_sleep_message:len() == 5 and minetest.sha1(custom_sleep_message) == "cd6f53e544ed020fb8ff9dae3f2637eb6e0aae43") then - -- crack this hash for a special minetest cape, no salt or pepper - -- rules for all characters: acii value between 33 and 38 or 48 and 57 or 65 and 80 - player:get_meta():set_int("mcl_skins:has_seeecret_cape", 1) -- "seeecret" so just using grep on the 'normal' word won't work - end end return end diff --git a/mods/PLAYER/mcl_skins/edit_skin.lua b/mods/PLAYER/mcl_skins/edit_skin.lua index 12ed293e4..3dff5f49a 100644 --- a/mods/PLAYER/mcl_skins/edit_skin.lua +++ b/mods/PLAYER/mcl_skins/edit_skin.lua @@ -311,7 +311,6 @@ function mcl_skins.show_formspec(player, active_tab, page_num) "button[7.5,5.2;2,0.8;template2;" .. S("Select") .. "]" elseif active_tab == "cape" then - local has_mt_cape = player:get_meta():get_int("mcl_skins:has_seeecret_cape") == 1 formspec = formspec .. "label[6,3;" .. S("(None)") .. "]".. "button[5.5,4.2;2,0.8;nocape;" .. S("Select") .. "]".. @@ -319,7 +318,8 @@ function mcl_skins.show_formspec(player, active_tab, page_num) "image[9,2;1,2;slimecape.png]".. "button[8.5,4.2;2,0.8;slimecape;" .. S("Select") .. "]".. - "image[6,7;1,2;mtcape.png]" .. -- show image ingame so there is another hint that this cape exists + "image[6,7;1,2;mtcape.png]" .. + "button[5.5,9.2;2,0.8;mtcape;" .. S("Select") .. "]" .. "image[9,7;1,2;ghastcape.png]" .. "button[8.5,9.2;2,0.8;ghastcape;" .. S("Select") .. "]".. @@ -327,12 +327,6 @@ function mcl_skins.show_formspec(player, active_tab, page_num) "image[12,7;1,2;mclcape.png]" .. "button[11.5,9.2;2,0.8;mclcape;" .. S("Select") .. "]" - if has_mt_cape then - formspec = formspec .. - --"image[9,2;1,2;mtcape.png]" - "button[5.5,9.2;2,0.8;mtcape;" .. S("Select") .. "]" - end - elseif mcl_skins[active_tab] then formspec = formspec .. "style_type[button;bgcolor=#00000000]" From 0f91b763e9e16da152fa9782b89cad598b9d1752 Mon Sep 17 00:00:00 2001 From: chmodsayshello Date: Sun, 17 Dec 2023 14:54:25 +0100 Subject: [PATCH 05/10] add cape api --- mods/ITEMS/mcl_armor/register.lua | 10 +-- mods/PLAYER/mcl_skins/edit_skin.lua | 131 +++++++++++++++++++--------- mods/PLAYER/mcl_skins/list.json | 30 +++++++ 3 files changed, 123 insertions(+), 48 deletions(-) diff --git a/mods/ITEMS/mcl_armor/register.lua b/mods/ITEMS/mcl_armor/register.lua index 17b022216..e6ed664cc 100644 --- a/mods/ITEMS/mcl_armor/register.lua +++ b/mods/ITEMS/mcl_armor/register.lua @@ -230,18 +230,18 @@ minetest.register_tool("mcl_armor:elytra", { _mcl_armor_texture = function(obj, itemstack) if obj:is_player() then local cape = mcl_skins.player_skins[obj].cape - if cape ~= "nocape" then - return cape .. "_elytra.png" + if cape ~= "blank.png" then + return cape:gsub("_body", "_elytra") end end return "mcl_armor_elytra.png" end, - _on_equip = function(obj, itemstack) + _on_equip = function(obj, itemstack) if not obj:is_player() then return end local cape = mcl_skins.player_skins[obj].cape - if cape ~= "nocape" then + if cape ~= "blank.png" then local skinval = mcl_player.player_get_skin(obj) - skinval = skinval:gsub( cape .. "_body.png", "") + skinval = skinval:gsub("^" .. cape, "") mcl_player.player_set_skin(obj, skinval) -- this doesn't mess with the data mcl_skins has, so when mcl_skins reloads (which happens when the elytra is unequipped), the normal cape returns end diff --git a/mods/PLAYER/mcl_skins/edit_skin.lua b/mods/PLAYER/mcl_skins/edit_skin.lua index 3dff5f49a..2d3b50a11 100644 --- a/mods/PLAYER/mcl_skins/edit_skin.lua +++ b/mods/PLAYER/mcl_skins/edit_skin.lua @@ -5,7 +5,7 @@ local EDIT_SKIN_KEY = -1 -- The key used for edit skin in the mcl_skins.simple_s mcl_skins = { simple_skins = {}, texture_to_simple_skin = {}, - item_names = {"base", "footwear", "eye", "mouth", "bottom", "top", "hair", "headwear"}, + item_names = {"base", "footwear", "eye", "mouth", "bottom", "top", "hair", "headwear", "cape"}, tab_names = {"skin", "template", "base", "headwear", "hair", "eye", "mouth", "top", "arm", "bottom", "footwear", "cape"}, tab_descriptions = { template = S("Templates"), @@ -21,6 +21,7 @@ mcl_skins = { skin = S("Skins"), cape = S("Capes") }, + cape = {}, template1 = {}, -- Stores edit skin values for template1 template2 = {}, -- Stores edit skin values for template2 base = {}, -- List of base textures @@ -60,7 +61,21 @@ mcl_skins = { function mcl_skins.register_item(item) assert(mcl_skins[item.type], "Skin item type " .. item.type .. " does not exist.") + + if item.type == "cape" then + local func = item.selector_func + + if type(func) == "string" then + func = loadstring(func)() + end + + table.insert(mcl_skins.cape, {name=item.name, selector_func=func, mask=item.mask}) + mcl_skins.masks[item.name] = item.mask + return + end + local texture = item.texture or "blank.png" + if item.template1 then mcl_skins.template1[item.type] = texture end @@ -137,9 +152,6 @@ function mcl_skins.compile_skin(skin) if #output > 0 then output = output .. "^" end output = output .. layers[rank] end - if skin.cape and skin.cape ~= "nocape" then - output = output .. "^(" .. skin.cape .. "_body.png)" - end return output end @@ -207,6 +219,8 @@ end) local function calculate_page_count(tab) if tab == "skin" then return math.ceil((#mcl_skins.simple_skins + 2) / 8) + elseif tab == "cape" then + return math.ceil(#mcl_skins.cape / 5) elseif mcl_skins[tab] then return math.ceil(#mcl_skins[tab] / 16) end @@ -253,6 +267,9 @@ function mcl_skins.show_formspec(player, active_tab, page_num) mcl_skins.compile_skin(skin) .. ",blank.png,blank.png;0,180;false;true;0,0]" + + local cape_tab = active_tab == "cape" + if active_tab == "skin" then local page_start = (page_num - 1) * 8 - 1 local page_end = math.min(page_start + 8 - 1, #mcl_skins.simple_skins) @@ -310,22 +327,36 @@ function mcl_skins.show_formspec(player, active_tab, page_num) "button[7.5,5.2;2,0.8;template2;" .. S("Select") .. "]" - elseif active_tab == "cape" then - formspec = formspec .. - "label[6,3;" .. S("(None)") .. "]".. - "button[5.5,4.2;2,0.8;nocape;" .. S("Select") .. "]".. + elseif cape_tab then + local possize = {{"6,2;1,2", "5.5,4.2;2,0.8"}, {"9,2;1,2","8.5,4.2;2,0.8"}, {"6,7;1,2","5.5,9.2;2,0.8"}, {"9,7;1,2","8.5,9.2;2,0.8"},{"12,7;1,2","11.5,9.2;2,0.8"}} + local slot_start = 1 + local slot_end = #mcl_skins.cape % (page_num * 5) - "image[9,2;1,2;slimecape.png]".. - "button[8.5,4.2;2,0.8;slimecape;" .. S("Select") .. "]".. + if slot_end == 0 then slot_end = 5 end + + if page_num == 1 then + formspec = formspec .. + "label[6,3;" .. S("(None)") .. "]".. + "button[5.5,4.2;2,0.8;nocape;" .. S("Select") .. "]" + slot_start = 2 + end - "image[6,7;1,2;mtcape.png]" .. - "button[5.5,9.2;2,0.8;mtcape;" .. S("Select") .. "]" .. - - "image[9,7;1,2;ghastcape.png]" .. - "button[8.5,9.2;2,0.8;ghastcape;" .. S("Select") .. "]".. - - "image[12,7;1,2;mclcape.png]" .. - "button[11.5,9.2;2,0.8;mclcape;" .. S("Select") .. "]" + for slot = slot_start, slot_end do + local cape = mcl_skins.cape[((page_num -1) * 5) + slot] + local pos = possize[slot] + + local show = true + if type(cape.selector_func) == "function" then + show = cape.selector_func(player) + end + if not show then + slot = slot - 1 + else + formspec = formspec .. + "image[" .. possize[slot][1] .. ";" .. cape.name ..".png]".. + "button[" .. possize[slot][2] .. ";" .. cape.name ..";" .. S("Select") .. "]" + end + end elseif mcl_skins[active_tab] then formspec = formspec .. @@ -442,18 +473,33 @@ function mcl_skins.show_formspec(player, active_tab, page_num) end if page_num > 1 then - formspec = formspec .. - "image_button[4.5,6.7;1,1;mcl_skins_arrow.png^[transformFX;previous_page;]" + if cape_tab then + formspec = formspec .. + "image_button[4.5,0.7;1,1;mcl_skins_arrow.png^[transformFX;previous_page;]" + else + formspec = formspec .. + "image_button[4.5,6.7;1,1;mcl_skins_arrow.png^[transformFX;previous_page;]" + end end if page_num < page_count then - formspec = formspec .. - "image_button[9.8,6.7;1,1;mcl_skins_arrow.png;next_page;]" + if cape_tab then + formspec = formspec .. + "image_button[9.8,0.7;1,1;mcl_skins_arrow.png;next_page;]" + else + formspec = formspec .. + "image_button[9.8,6.7;1,1;mcl_skins_arrow.png;next_page;]" + end end if page_count > 1 then - formspec = formspec .. - "label[7.3,7.2;" .. page_num .. " / " .. page_count .. "]" + if cape_tab then + formspec = formspec .. + "label[7.3,1.2;" .. page_num .. " / " .. page_count .. "]" + else + formspec = formspec .. + "label[7.3,7.2;" .. page_num .. " / " .. page_count .. "]" + end end local player_name = player:get_player_name() @@ -494,25 +540,18 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) mcl_skins.show_formspec(player, active_tab, page_num) return true elseif fields.nocape then - mcl_skins.player_skins[player].cape = "nocape" - mcl_skins.update_player_skin(player) - return true - elseif fields.slimecape then - mcl_skins.player_skins[player].cape = "slimecape" - mcl_skins.update_player_skin(player) - return true - elseif fields.ghastcape then - mcl_skins.player_skins[player].cape = "ghastcape" - mcl_skins.update_player_skin(player) - return true - elseif fields.mtcape then - mcl_skins.player_skins[player].cape = "mtcape" - mcl_skins.update_player_skin(player) - return true - elseif fields.mclcape then - mcl_skins.player_skins[player].cape = "mclcape" + mcl_skins.player_skins[player].cape = "blank.png" mcl_skins.update_player_skin(player) return true + elseif active_tab == "cape" then + for cape_index = ((page_num - 1) * 5) + 1, math.min(#mcl_skins.cape, page_num * 5) do + local cape = mcl_skins.cape[cape_index] + if fields[cape.name] then + mcl_skins.player_skins[player].cape = cape.mask -- the actual overlay image + mcl_skins.update_player_skin(player) + return true + end + end end for i, tab in pairs(mcl_skins.tab_names) do @@ -641,14 +680,14 @@ local function init() mcl_skins.template1.top_color = 0xff993535 mcl_skins.template1.bottom_color = 0xff644939 mcl_skins.template1.slim_arms = false - mcl_skins.template1.cape = "nocape" + mcl_skins.template1.cape = "blank.png" mcl_skins.template2.base_color = mcl_skins.base_color[1] mcl_skins.template2.hair_color = 0xff715d57 mcl_skins.template2.top_color = 0xff346840 mcl_skins.template2.bottom_color = 0xff383532 mcl_skins.template2.slim_arms = true - mcl_skins.template2.cape = "nocape" + mcl_skins.template2.cape = "blank.png" mcl_skins.register_simple_skin({ index = 0, @@ -662,3 +701,9 @@ local function init() end init() + +if not minetest.settings:get_bool("mcl_keepInventory", false) then + minetest.register_on_dieplayer(function(player) + mcl_skins.update_player_skin(player) -- ensures players have their cape again after dying with an elytra + end) +end \ No newline at end of file diff --git a/mods/PLAYER/mcl_skins/list.json b/mods/PLAYER/mcl_skins/list.json index dc7afbfe1..6c10e3d53 100644 --- a/mods/PLAYER/mcl_skins/list.json +++ b/mods/PLAYER/mcl_skins/list.json @@ -263,5 +263,35 @@ "mask": "mcl_skins_base_1_mask.png", "template1": true, "template2": true + }, + { + "type": "cape", + "name": "mtcape", + "mask": "mtcape_body.png", + "selector_func" : null + }, + { + "type": "cape", + "name": "slimecape", + "mask": "slimecape_body.png", + "selector_func" : null + }, + { + "type": "cape", + "name": "ghastcape", + "mask": "ghastcape_body.png", + "selector_func" : null + }, + { + "type": "cape", + "name": "mtcape", + "mask": "mtcape_body.png", + "selector_func" : null + }, + { + "type": "cape", + "name": "mclcape", + "mask": "mclcape_body.png", + "selector_func" : "return function (player) local playername = player:get_player_name() local maintainers_and_devs = {mcl_credits.people[1][3], mcl_credits.people[2][3], mcl_credits.people[3][3], mcl_credits.people[4][3], mcl_credits.people[5][3], mcl_credits.people[6][3]} for _, array in pairs(maintainers_and_devs) do for _, name in pairs(array) do if name == playername then return true end end end return false end" } ] From 146b0ade37e579b6622ce6e15d814e161b5b18c7 Mon Sep 17 00:00:00 2001 From: chmodsayshello Date: Sun, 17 Dec 2023 15:06:09 +0100 Subject: [PATCH 06/10] update elytra cape instantly --- mods/PLAYER/mcl_skins/edit_skin.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mods/PLAYER/mcl_skins/edit_skin.lua b/mods/PLAYER/mcl_skins/edit_skin.lua index 2d3b50a11..09374c70a 100644 --- a/mods/PLAYER/mcl_skins/edit_skin.lua +++ b/mods/PLAYER/mcl_skins/edit_skin.lua @@ -542,6 +542,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) elseif fields.nocape then mcl_skins.player_skins[player].cape = "blank.png" mcl_skins.update_player_skin(player) + mcl_armor.update(player) --update elytra cape return true elseif active_tab == "cape" then for cape_index = ((page_num - 1) * 5) + 1, math.min(#mcl_skins.cape, page_num * 5) do @@ -549,6 +550,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) if fields[cape.name] then mcl_skins.player_skins[player].cape = cape.mask -- the actual overlay image mcl_skins.update_player_skin(player) + mcl_armor.update(player) --update elytra cape return true end end From 89eb0f9b3ea44608346a04f4e48cf783760f8512 Mon Sep 17 00:00:00 2001 From: chmodsayshello Date: Sun, 17 Dec 2023 15:20:32 +0100 Subject: [PATCH 07/10] remove test selector_func --- mods/PLAYER/mcl_skins/list.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/PLAYER/mcl_skins/list.json b/mods/PLAYER/mcl_skins/list.json index 6c10e3d53..2d4df05c4 100644 --- a/mods/PLAYER/mcl_skins/list.json +++ b/mods/PLAYER/mcl_skins/list.json @@ -292,6 +292,6 @@ "type": "cape", "name": "mclcape", "mask": "mclcape_body.png", - "selector_func" : "return function (player) local playername = player:get_player_name() local maintainers_and_devs = {mcl_credits.people[1][3], mcl_credits.people[2][3], mcl_credits.people[3][3], mcl_credits.people[4][3], mcl_credits.people[5][3], mcl_credits.people[6][3]} for _, array in pairs(maintainers_and_devs) do for _, name in pairs(array) do if name == playername then return true end end end return false end" + "selector_func" : null } ] From bfe333ef6070fef35e14f39bf81e5350cd38f83c Mon Sep 17 00:00:00 2001 From: chmodsayshello Date: Sun, 17 Dec 2023 15:45:53 +0100 Subject: [PATCH 08/10] fix cape rendering conflicts The elytra and the normal cape were able to render at the same time while wearing an elytra. --- mods/ITEMS/mcl_armor/register.lua | 2 +- mods/PLAYER/mcl_skins/edit_skin.lua | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/mods/ITEMS/mcl_armor/register.lua b/mods/ITEMS/mcl_armor/register.lua index e6ed664cc..f4f1fb4d0 100644 --- a/mods/ITEMS/mcl_armor/register.lua +++ b/mods/ITEMS/mcl_armor/register.lua @@ -241,7 +241,7 @@ minetest.register_tool("mcl_armor:elytra", { local cape = mcl_skins.player_skins[obj].cape if cape ~= "blank.png" then local skinval = mcl_player.player_get_skin(obj) - skinval = skinval:gsub("^" .. cape, "") + skinval = skinval:gsub("%^" .. cape, "") mcl_player.player_set_skin(obj, skinval) -- this doesn't mess with the data mcl_skins has, so when mcl_skins reloads (which happens when the elytra is unequipped), the normal cape returns end diff --git a/mods/PLAYER/mcl_skins/edit_skin.lua b/mods/PLAYER/mcl_skins/edit_skin.lua index 09374c70a..61f290fb9 100644 --- a/mods/PLAYER/mcl_skins/edit_skin.lua +++ b/mods/PLAYER/mcl_skins/edit_skin.lua @@ -161,8 +161,16 @@ function mcl_skins.update_player_skin(player) end local skin = mcl_skins.player_skins[player] + local skinval = mcl_skins.compile_skin(skin) - mcl_player.player_set_skin(player, mcl_skins.compile_skin(skin)) + if player:get_inventory():get_stack("armor", 3):get_name() == "mcl_armor:elytra" then + skinval = skinval:gsub("%^" .. skin.cape, "") + -- don't render the "normal" cape on players while wearing the elytra. + -- this is NOT used when the player puts an elytra on, see register.lua in mcl_armor for that. + -- this is used when a player joins or changes something regarding their skin. + end + + mcl_player.player_set_skin(player, skinval) local slim_arms if skin.simple_skins_id then @@ -705,7 +713,7 @@ end init() if not minetest.settings:get_bool("mcl_keepInventory", false) then - minetest.register_on_dieplayer(function(player) + minetest.register_on_respawnplayer(function(player) mcl_skins.update_player_skin(player) -- ensures players have their cape again after dying with an elytra end) end \ No newline at end of file From 96dbcc45d0fdc7f36d9987d2af24a0a6f3b4b184 Mon Sep 17 00:00:00 2001 From: chmodsayshello Date: Fri, 22 Dec 2023 09:46:19 +0100 Subject: [PATCH 09/10] fix cape being registered twice --- mods/PLAYER/mcl_skins/list.json | 6 ------ 1 file changed, 6 deletions(-) diff --git a/mods/PLAYER/mcl_skins/list.json b/mods/PLAYER/mcl_skins/list.json index 2d4df05c4..1c0b106e9 100644 --- a/mods/PLAYER/mcl_skins/list.json +++ b/mods/PLAYER/mcl_skins/list.json @@ -282,12 +282,6 @@ "mask": "ghastcape_body.png", "selector_func" : null }, - { - "type": "cape", - "name": "mtcape", - "mask": "mtcape_body.png", - "selector_func" : null - }, { "type": "cape", "name": "mclcape", From 45c84b1f1dc70e42c46b055051d7c0476c087840 Mon Sep 17 00:00:00 2001 From: chmodsayshello Date: Sat, 13 Jan 2024 12:17:09 +0100 Subject: [PATCH 10/10] fix formspec --- mods/PLAYER/mcl_skins/edit_skin.lua | 49 ++++++++++++++++------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/mods/PLAYER/mcl_skins/edit_skin.lua b/mods/PLAYER/mcl_skins/edit_skin.lua index 61f290fb9..94866c87d 100644 --- a/mods/PLAYER/mcl_skins/edit_skin.lua +++ b/mods/PLAYER/mcl_skins/edit_skin.lua @@ -224,11 +224,17 @@ minetest.register_on_leaveplayer(function(player) mcl_skins.player_formspecs[player] = nil end) -local function calculate_page_count(tab) +local function calculate_page_count(tab, player) if tab == "skin" then return math.ceil((#mcl_skins.simple_skins + 2) / 8) elseif tab == "cape" then - return math.ceil(#mcl_skins.cape / 5) + local player_capes = 0 + for _, cape in pairs(mcl_skins.cape) do + if type(cape.selector_func) == "nil" or cape.selector_func(player) then + player_capes = player_capes + 1 + end + end + return math.ceil((player_capes + 1) / 5) -- add one so the player can select no cape as well elseif mcl_skins[tab] then return math.ceil(#mcl_skins[tab] / 16) end @@ -240,7 +246,7 @@ function mcl_skins.show_formspec(player, active_tab, page_num) local skin = mcl_skins.player_skins[player] formspec_data.active_tab = active_tab - local page_count = calculate_page_count(active_tab) + local page_count = calculate_page_count(active_tab, player) if page_num < 1 then page_num = 1 end if page_num > page_count then page_num = page_count end formspec_data.page_num = page_num @@ -337,33 +343,32 @@ function mcl_skins.show_formspec(player, active_tab, page_num) elseif cape_tab then local possize = {{"6,2;1,2", "5.5,4.2;2,0.8"}, {"9,2;1,2","8.5,4.2;2,0.8"}, {"6,7;1,2","5.5,9.2;2,0.8"}, {"9,7;1,2","8.5,9.2;2,0.8"},{"12,7;1,2","11.5,9.2;2,0.8"}} - local slot_start = 1 - local slot_end = #mcl_skins.cape % (page_num * 5) + local player_capes = {} -- contains all capes the player is allowed to wear + for _, cape in pairs (mcl_skins.cape) do + if type(cape.selector_func) == "nil" or cape.selector_func(player) then + table.insert(player_capes, cape) + end + end - if slot_end == 0 then slot_end = 5 end + local slot_offset = 0 if page_num == 1 then formspec = formspec .. "label[6,3;" .. S("(None)") .. "]".. "button[5.5,4.2;2,0.8;nocape;" .. S("Select") .. "]" - slot_start = 2 + slot_offset = 1 end - for slot = slot_start, slot_end do - local cape = mcl_skins.cape[((page_num -1) * 5) + slot] + local array_start = page_num * 5 - 4 + local index_offset = page_num == 1 and 1 or 2 + + for slot = 1 + slot_offset, page_num ~= page_count and 5 or (#player_capes % 5 == 0 and 1 or #player_capes % 5) + slot_offset do + local cape = player_capes[array_start + slot - slot_offset - index_offset] local pos = possize[slot] - - local show = true - if type(cape.selector_func) == "function" then - show = cape.selector_func(player) - end - if not show then - slot = slot - 1 - else - formspec = formspec .. - "image[" .. possize[slot][1] .. ";" .. cape.name ..".png]".. - "button[" .. possize[slot][2] .. ";" .. cape.name ..";" .. S("Select") .. "]" - end + + formspec = formspec .. + "image[" .. possize[slot][1] .. ";" .. cape.name ..".png]".. + "button[" .. possize[slot][2] .. ";" .. cape.name ..";" .. S("Select") .. "]" end elseif mcl_skins[active_tab] then @@ -551,6 +556,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) mcl_skins.player_skins[player].cape = "blank.png" mcl_skins.update_player_skin(player) mcl_armor.update(player) --update elytra cape + mcl_skins.show_formspec(player, active_tab, page_num) return true elseif active_tab == "cape" then for cape_index = ((page_num - 1) * 5) + 1, math.min(#mcl_skins.cape, page_num * 5) do @@ -559,6 +565,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) mcl_skins.player_skins[player].cape = cape.mask -- the actual overlay image mcl_skins.update_player_skin(player) mcl_armor.update(player) --update elytra cape + mcl_skins.show_formspec(player, active_tab, page_num) return true end end