From 8054d2caf5f0c07f9e91534e703490f4a54e9e5a Mon Sep 17 00:00:00 2001 From: root Date: Sun, 5 Sep 2021 16:06:04 +0200 Subject: [PATCH] update --- mods/bees/init.lua | 3 +- mods/bonemeal/mods.lua | 1 + mods/farming/textures/farming_cocoa_beans.png | Bin 187 -> 173 bytes mods/mobs_monster/dungeon_master.lua | 38 ++- mods/mobs_monster/license.txt | 4 + mods/mobs_monster/mese_monster.lua | 3 + .../textures/mobs_dungeon_master_nether.png | Bin 0 -> 3192 bytes .../mobs_dungeon_master_netherdeep.png | Bin 0 -> 2795 bytes mods/mobs_redo/api.lua | 6 +- mods/moreblocks/circular_saw.lua | 14 +- mods/moreblocks/init.lua | 12 +- mods/moreblocks/mod.conf | 3 +- mods/moreblocks/nodes.lua | 14 +- mods/moreblocks/sounds.lua | 20 ++ mods/moreblocks/stairsplus/API.md | 2 +- mods/moreblocks/stairsplus/custom.lua | 2 +- mods/moreblocks/stairsplus/microblocks.lua | 2 +- mods/moreblocks/stairsplus/panels.lua | 2 +- mods/moreblocks/stairsplus/registrations.lua | 138 ++++---- mods/moreblocks/stairsplus/slabs.lua | 2 +- mods/moreblocks/stairsplus/slopes.lua | 2 +- mods/moreblocks/stairsplus/stairs.lua | 2 +- mods/morelights/README.md | 2 +- mods/morelights/crafts.md | 26 +- mods/morelights/modpack.conf | 1 + mods/morelights/modpack.txt | 0 mods/morelights/morelights/init.lua | 43 ++- mods/morelights/morelights/mod.conf | 2 +- mods/morelights/morelights_extras/init.lua | 88 +++-- mods/morelights/morelights_vintage/init.lua | 2 +- mods/protector/init.lua | 2 +- mods/protector/pvp.lua | 6 +- mods/protector/tool.lua | 5 + mods/skinsdb/meta/character_1141.txt | 2 +- mods/skinsdb/meta/character_2114.txt | 3 + mods/skinsdb/meta/character_2115.txt | 3 + mods/skinsdb/meta/character_2116.txt | 3 + ...{character_2113.txt => character_2117.txt} | 2 +- mods/skinsdb/meta/character_2118.txt | 3 + mods/skinsdb/textures/character_2113.png | Bin 3178 -> 0 bytes mods/skinsdb/textures/character_2114.png | Bin 0 -> 9508 bytes mods/skinsdb/textures/character_2115.png | Bin 0 -> 6213 bytes mods/skinsdb/textures/character_2116.png | Bin 0 -> 10429 bytes mods/skinsdb/textures/character_2117.png | Bin 0 -> 3771 bytes mods/skinsdb/textures/character_2118.png | Bin 0 -> 1302 bytes mods/techpack/README.md | 1 + mods/techpack/gravelsieve/init.lua | 6 +- mods/techpack/tubelib_addons1/harvester.lua | 36 +- .../tubelib_addons1/locale/template.txt | 1 + .../locale/tubelib_addons1.de.tr | 1 + mods/techpack/tubelib_addons1/nodes.lua | 68 ++-- mods/unified_inventory/init.lua | 3 +- mods/unified_inventory/internal.lua | 320 ++++++++---------- 53 files changed, 528 insertions(+), 371 deletions(-) create mode 100644 mods/mobs_monster/textures/mobs_dungeon_master_nether.png create mode 100644 mods/mobs_monster/textures/mobs_dungeon_master_netherdeep.png create mode 100644 mods/moreblocks/sounds.lua delete mode 100644 mods/morelights/modpack.txt create mode 100644 mods/skinsdb/meta/character_2114.txt create mode 100644 mods/skinsdb/meta/character_2115.txt create mode 100644 mods/skinsdb/meta/character_2116.txt rename mods/skinsdb/meta/{character_2113.txt => character_2117.txt} (70%) create mode 100644 mods/skinsdb/meta/character_2118.txt delete mode 100644 mods/skinsdb/textures/character_2113.png create mode 100644 mods/skinsdb/textures/character_2114.png create mode 100644 mods/skinsdb/textures/character_2115.png create mode 100644 mods/skinsdb/textures/character_2116.png create mode 100644 mods/skinsdb/textures/character_2117.png create mode 100644 mods/skinsdb/textures/character_2118.png diff --git a/mods/bees/init.lua b/mods/bees/init.lua index c2b93828..d8bd4977 100644 --- a/mods/bees/init.lua +++ b/mods/bees/init.lua @@ -279,7 +279,8 @@ minetest.register_node("bees:hive_wild", { {items = {"bees:honey_comb"}, rarity = 5} } }, - groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, attached_node = 1}, + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3}, + --, attached_node = 1}, node_box = { -- VanessaE's wild hive nodebox contribution type = "fixed", fixed = { diff --git a/mods/bonemeal/mods.lua b/mods/bonemeal/mods.lua index dfbcd6ff..46858b06 100644 --- a/mods/bonemeal/mods.lua +++ b/mods/bonemeal/mods.lua @@ -68,6 +68,7 @@ if minetest.get_modpath("ethereal") then {"ethereal:mushroom_sapling", ethereal.grow_mushroom_tree, "soil"}, {"ethereal:willow_sapling", ethereal.grow_willow_tree, "soil"}, {"ethereal:redwood_sapling", ethereal.grow_redwood_tree, "soil"}, + {"ethereal:giant_redwood_sapling", ethereal.grow_giant_redwood_tree, "soil"}, {"ethereal:orange_tree_sapling", ethereal.grow_orange_tree, "soil"}, {"ethereal:bamboo_sprout", ethereal.grow_bamboo_tree, "soil"}, {"ethereal:birch_sapling", ethereal.grow_birch_tree, "soil"}, diff --git a/mods/farming/textures/farming_cocoa_beans.png b/mods/farming/textures/farming_cocoa_beans.png index 4022f8e8b748f132bcae1a762a0ee96d80c75fe4..9605e51f121361b7a39fa7dc63c7f899ab68a7aa 100644 GIT binary patch delta 145 zcmdnZxR!B(O1)5kPlzi+evYYnPh`!yKW-lEgQ;VRM7AOORj^pC1E*a3x!Ad%?OB3=CXAV_p4R);T3K0RU*aDzE?m delta 159 zcmV;Q0AT;E0lNW^B!3l9OjJcyw+TTa4NWT*VK^OdL?ww>HkW5c)I#eM00001bW%=J z06^y0W&i*HR7pfZR0!8&U_b$Efe^}&)e%G|i7GM*f*3(Uf{X$nhM|%GSWSXpVyZ|W zNTookh!9XQn_!BFpb$v0K$2jJnjuKBAY+gygux&vCNklXqxpIiijED>`1n92M^5Ec#fBffP`p?!cd3C$u+u#1kufM;i3?shz`Ae3Il24C2 z-hJ577=sYtz2|OG@Nnudi;2vntiyzdQ^(`;j^(0YS+D4I|7TtZfyxwLY!-ZZcgx4_ z!pHLtbrb=U-qHT#P+3Y^R)lGcUnHn9<#qKLT7?|mJt7_4y}n|xOldEBKAnyjBak8> zEi1ST?4M6Ood=>MAxRPtf-qHFy+~DZ8Gpq1lg zJ>Y@CI1Z-3C{N^=f95W!9|M0-}G_my-@xEu;HOMkf-p+)qZWsLhUw_5dfAuxr ze)vFtoXEUlu%0rC3DOWR0`zlFI40Dq1y@x?l11E)NA`VB8f9!x9n-eK=P`$i#?6j( zUGQCJSy)Zl8t5RM41u{?5^pNJl&IyJfBDyc35&_{Z9u}mGbXz|ARL# zZn(Q>-h8}g*NnJ8aNo3qu15@#cCvJnL&b)tzM-8g56wV3S!6m9tC>S`MfI~+_%B~0 zgBN#i(_M?sA|eU@^X-4}pTGJI+5X7Yc|ZVL8SvxB|Krzxe9!8zCF%p}cA)Ji0(&M8 zCSE;ni4QIFI8o;l%39JxgFChC+JV*FkV--EIPo!#nXN;}U;M&vjvePW8{D9|oi8l< zj&N}FHX+&dT$T&If4L&Ua@#)>o)y9?ys)TpBG;BsJ4`BZndBJ4=3yq)Ehd+UMq#cM zCXv`KgV~Myz^Cy%-2SP4w%T-@dw`&q_YOJTNT<#d+pr zBhFVjne3@Yhg!uBhLNxCca)_jBS1x(Ls!5s6Dm&<3REU}9iG`u5utF%PH~JY`gKA8 zj3%KhJzfe5w zfVIqnBaA#}TTny;I`BljV;8OP(lSLc&MP);%j;{;<+;b>InN1oqzMTz!eC;_cf*41 zBIn2J5@jvw)!hm!B;V#SFaG!r8%~5)P(%|dhKmW1ULaDBoE$3?AnO1*YUT;r!lHv1 zx*5G2&?zJn#OVl=U^hn`vo%K<(5)0Yl;qkFlrah+Xr_rwPmEK97Xe8)a5NDw^h^?Y z)*>P826_b9Mv|qFPXm`Hg*FLw+z^(Ms1Nu&32>>Q+0Uq1F$b2Xd8W@2R@)0-IL&wU zf=||<20c=x89iVFPd$uKK|TzGqokM>i%mdI$iqdlsRe14^6CD>LwSXtVc9zFCWjCb z(~az>nk>;oa$=zcFZ7wXAL%0nz}M!99O1G@5l+`LB zC}w&)(>+VFWXHCvxW3jzaZNS}eBg)zK{{&opXF?IhI(A&XdAF@T0EZGG|WLrYy@K( zvPunl@Bm!Sg3qokm$qkDsfKMv6Q@Xv-`GhrQr? zuTUerI1X&e3*oJ26%@SL+#+(zEDdoOFbtMXLpwEeItOWKx{$DUB$pXc3X;7cC`Ojr zl6MlBtKw~@1f5EmeNJUG*q9=B)TN}~M;zA$y^mjI>A*fya6C zr`r@y6op6N5k*KV1asiA#uFbL!3jofk!vB|Mv0&mIgfeG+B9?`L3Waxb;w=isrMHO z-Ev#BY~qx>^gKOY;3AmpNU_d|%bGMzu-*~N3~fe!|4?&k;HRjf^)aa(m=JjBF%u|1 zD;D=1*NNsL4a89NhHY9>-0#4JTvv{7*0)4Xu&hJkRX`XE_8&EyIcA(j+Ogx^k59Cd zCC*dIMFl@WpCsrkCY(o{2-pTC2bGYt7i3bc-d=N|t}`}L6CY-#G{jU;A1uGWxnpP* zU#=|5O2XW6KJLjf$>w^2lQY}HneW~`^RR`Vb_LVevbk9hsWY}WXcuBbh{KU@uWxy( zGK`y%Zc)DVHl=RQ&{l2dmk=-`}2WWk6YLPn(s#u54AZ@zi^W1(1v1G)wg3d)nEj3h>c zRI}kPzJ$E4G3SwBP8fAV7AlIQVAnUat-xLcBASWi#MPC?IuBA%mIX2%&`%)6$Y^4i zEMwqN!!RO*pqWFyc-9n?puR4M6UVGaya`Cs1*>JreAG<6=jD2ZOk=u9kWdke3vDR5 z-W05IkBBOE=N8AGRxB3$JheQ&lN1abqLMC4P*V^fj6}Pf))=m0fz~}q8WBYSlYv2N zcKZX96b#Y8g_$BT1apWvd(P8LnS}UC^5J36^FBw0j=h%D^`5wh5ornDle!*H0SFY{ zQzsD*i;^bGs6PIHuql6Naz5Li$z#vHnb3A-wOBG)O+U;Wn;rnydiF_1T^UZJ;OP|e zF)eA+h;bQ!T_O(?8*@T118{e0al=5+oHgfRVwz_>e`>hL6GanIY!H*KTQl{_2XSNTRk^6?g9*DU2hE20##X4(1q}IJzhJ+Ok+$hGC!?6-6NErw|`ZtZ!rFqxiE^0P1*bxRwJplla7eGniF?JXVz?SNfFst0-{h{pig7>-^r&yKwk6oFzm0b(ZZM&ebC z(LFdn(5_H_k4Bp)@_D*CWMHWPBt zs3fMJQ|u@qNdO2%fS(OrtO(AUFSZR&mma^VP~H*=M_@*Br?73$P$z5`Ij_$TC>l<_ zplC;A^z!QMQ&o}eG?5!{))V#vU6?Tsphd#Rx+F1%V4BcL#3c&3JsucS$2qD{lc8=K zoQly>;F6eKm@#WbCnZG`kVcZNQ#47%r$xzOQK7oKlAo<#@+cD8pFGQ{0RhL*)1@W3 zH7pK0dOV3~NlZ%`f;Iz}a!Hj|e99wU{_q|*T(CjGri{tcgi{nl)1cc9P953Zn&l#A eB?Ld-KlA@3>9)#ntOLRT0000dn=nM+rCwsa-tR{#I|K%k-N)S>g*p|2JbUAN+& zS%}S@IdN7rv}JaR%#*b1ByEa4aa6>{{=-`46Q8;7fkn@3q%fBmscNaK3ZyO#Wz~`1x~ik5p=BvBvs5)Ta_OczS6_$bUdoH9t{u6zR(4E; zW-eU!`@&6;&2?3zu;I)GPRUg;xA_#{_Nbfj={ZM zwQM9RV`g0{wU|L+eanDTT z{C=)?dn=O*enxS1#N*S%Lg3D0uX+K!3ek)X#@BxF;|(g_xM%!nPH;!jmn z%6M&KxH9}jgKC{gN^i}Ff>BC8WA(zrv$gQYeZqj$+Bfcb)r)DzWCdx1-TUnR++Tk2 zKq@potg+GORg1L8&o($p**@S&mqu<_53np72ooj^noW*3c)dc$yh4;8J$^pxZc3to z;e&^K+Mzk2S0#yw8nk!V_{7y#O4MRqWxvBtllF?+30r+uZT501bzgk_waaM8&Jm+E z2Q7kIPv8CMdZRFH*F`>g`dmFR+T5nON2^&5%!r}wf zE$$Yys|?;yB&-&!XKe4$eM&H4T`;+zwnL-JUCKP={U5nH@x_~kOd#IZ6=bQ}U*7ok z@G)sdt3uEsiYdm_A{GtenEgJph}}ozOU{?%^RnQ0!R4HGjdiz#>E@KtB{w(BMvezF z%ZTQ>DtaJ!zLJ{6nVZ8NLC7p%al=MTTw}XUJ)y|R+JqhQI?bGPNm?gq(reM(F7I^$ znlW(op4%%nb`6g|Gsp(&a&d{wf2+D_58nhZDyQC@cdn((dgr?_wcuSsh zc*Nl@K~PG|TkMk7O5zWWsaBcK%VO^R#+&4O;s5T>T$p?HaElo02JIzP<@g1RFSuJ1 z-DmrVT9f*?yBmxGsu}5=dPMjU#we!R<>)EhEvkJcA?9q}QTu|$Tk`v)RT?#lil7KA zRe8Cxd;5dvU^IPRi3jGJpAyw+B`gy5+GK00of4=@jWDON$8t)g!qy>;U9tvYm1d1b zy&U&?gB;a>)iv|FtDxpO>-ut3(awkBu0(RSbn|Fl(izn_OjtKjFBk7^m7vwzG`jRV z%s&t}m{m$|7@l!CC|Q|Zm3q%wgc+}w^ddHQm|QbX&9%fY+>>uLILql=v(=&2VDrm39PoX~rDXqRZ?=7e_ z84hV>Xi+Q(pigqfU`F~aomQy^F{>U$jed=+Lib)d=3>fXx4e$;n68-@WO)himwm<& zgOSMY)^qEs;CAZC*>?t8_sFKDPHX%0kJ;a*)uZ-+-R&}P<`-;Wxhe~;B*gX7q}oYI z{O#{pUUB{dt8uw)>5_FoHWLe%JU&p^_QRrC>b+It>L>O$xGRWvc>IiJLfqr7MjkU5 zmX^C-mJnXOWj-NFKIQ;sQx0iN-gg-Kpo( z#3SuhQVnkCV-F4=(Hqq6&AQC7Zw&168-X7G;5Yqq<@RnGoKWyz{pj(IpL)A4pn z)NY*2?|sYx<#U!*qHBT%`NSYzYE4(-g-j@5HsQ+$^lBtsRtZsFo@hEX>V4KZ!HT`Z z(&>sjwrdO%#tS-Kl0Hem?KQ=^-1mB$;8zqM$hzFTS6dN>3aOQ#eWh5`NglDBmu90{ zF1B1Sz9#;7Js(qVk%V+p?rv$exhK*OY@9I~l=)q`rMTeqHIqA5Dc+S6+CPAAZ=jOke4NJ=7N~wm`NvYlO6_bqhdm6WFZPMwN zhSIxF`?&0SaK-J4w=W$3?ym^MZ}(X?`V=|s4xNPCyv*?eX~Aqxcnd-$|=>FTzo_Fm}akZy2nqr%E*=kn;%s$Wp-mFx2Yz2ru#hlaACC7 zp_)^4iI)8Ig3%f2ilD-LMpEJQmOLzvJ*#C2r!UPj0KW}PQ>`a@vArL z%g{<84h5#}Q{5p-xtOrLP`!KU{%P*zCr=2rDQ0vwXyU^w!jPiPW+-_3pNje}pVpZ5 zN<|bCHX7ys?gH{H!r~)T0f>iYhPF#;7jfCm_o>yxEidl}TsH{k^!n5brsqEW;Tu7P zSC9Ulznyw^5oo!z`rE%+T3gjh7BJ%qkJ{;yMoA3@zlh(M}4|IqK^dMUX#>W z&K$oRczth^q``9T_}#VFhYvW-9YiP2kMB`$IlB2?^^AHEA~KT-0=h*5fs5*$)lQ&& zUI+@}F9o)23QynrW`0-dvS9nQ3*r x9Jtm}Q`b^8GAX!|8(P?3HFQrmg*bER{{X(G+@@Ej;8Fkp002ovPDHLkV1jV6q@w@; literal 0 HcmV?d00001 diff --git a/mods/mobs_redo/api.lua b/mods/mobs_redo/api.lua index d6d35107..95492452 100644 --- a/mods/mobs_redo/api.lua +++ b/mods/mobs_redo/api.lua @@ -8,7 +8,7 @@ local use_cmi = minetest.global_exists("cmi") mobs = { mod = "redo", - version = "20210816", + version = "20210905", intllib = S, invis = minetest.global_exists("invisibility") and invisibility or {} } @@ -4771,6 +4771,10 @@ function mobs:feed_tame(self, clicker, feed_count, breed, tame) if clicker:get_player_control().sneak then + if type(self.follow) == "string" then + self.follow = {self.follow} + end + minetest.chat_send_player(clicker:get_player_name(), S("@1 follows:\n- @2", self.name:split(":")[2], diff --git a/mods/moreblocks/circular_saw.lua b/mods/moreblocks/circular_saw.lua index 60231fc9..933e2dd3 100644 --- a/mods/moreblocks/circular_saw.lua +++ b/mods/moreblocks/circular_saw.lua @@ -337,6 +337,10 @@ function circular_saw.on_metadata_inventory_take( local input_stack = inv:get_stack(listname, index) if not input_stack:is_empty() and input_stack:get_name()~=stack:get_name() then local player_inv = player:get_inventory() + + -- Prevent arbitrary item duplication. + inv:remove_item(listname, input_stack) + if player_inv:room_for_item("main", input_stack) then player_inv:add_item("main", input_stack) end @@ -363,9 +367,15 @@ function circular_saw.on_metadata_inventory_take( -- The recycle field plays no role here since it is processed immediately. end +local has_default_mod = minetest.get_modpath("default") + function circular_saw.on_construct(pos) local meta = minetest.get_meta(pos) - local fancy_inv = default.gui_bg..default.gui_bg_img..default.gui_slots + local fancy_inv = "" + if has_default_mod then + -- prepend background and slot styles from default if available + fancy_inv = default.gui_bg..default.gui_bg_img..default.gui_slots + end meta:set_string( "formspec", "size[11,10]"..fancy_inv.. "label[0,0;" ..F(S("Input\nmaterial")).. "]" .. @@ -437,7 +447,7 @@ minetest.register_node("moreblocks:circular_saw", { sunlight_propagates = true, paramtype2 = "facedir", groups = {choppy = 2,oddly_breakable_by_hand = 2}, - sounds = default.node_sound_wood_defaults(), + sounds = moreblocks.node_sound_wood_defaults(), on_construct = circular_saw.on_construct, can_dig = circular_saw.can_dig, -- Set the owner of this circular saw. diff --git a/mods/moreblocks/init.lua b/mods/moreblocks/init.lua index c3e9b637..2fc51ead 100644 --- a/mods/moreblocks/init.lua +++ b/mods/moreblocks/init.lua @@ -17,9 +17,13 @@ moreblocks.S = S moreblocks.NS = NS dofile(modpath .. "/config.lua") +dofile(modpath .. "/sounds.lua") dofile(modpath .. "/circular_saw.lua") dofile(modpath .. "/stairsplus/init.lua") -dofile(modpath .. "/nodes.lua") -dofile(modpath .. "/redefinitions.lua") -dofile(modpath .. "/crafting.lua") -dofile(modpath .. "/aliases.lua") + +if minetest.get_modpath("default") then + dofile(modpath .. "/nodes.lua") + dofile(modpath .. "/redefinitions.lua") + dofile(modpath .. "/crafting.lua") + dofile(modpath .. "/aliases.lua") +end diff --git a/mods/moreblocks/mod.conf b/mods/moreblocks/mod.conf index 011d4a0d..422fe31a 100644 --- a/mods/moreblocks/mod.conf +++ b/mods/moreblocks/mod.conf @@ -1,5 +1,4 @@ name = moreblocks description = Adds various miscellaneous blocks to the game. -depends = default -optional_depends = intllib,stairs,farming,wool,basic_materials +optional_depends = default,intllib,stairs,farming,wool,basic_materials min_minetest_version = 5.0.0 diff --git a/mods/moreblocks/nodes.lua b/mods/moreblocks/nodes.lua index fbe66dcc..68792cb5 100644 --- a/mods/moreblocks/nodes.lua +++ b/mods/moreblocks/nodes.lua @@ -7,15 +7,15 @@ Licensed under the zlib license. See LICENSE.md for more information. local S = moreblocks.S -local sound_dirt = default.node_sound_dirt_defaults() -local sound_wood = default.node_sound_wood_defaults() -local sound_stone = default.node_sound_stone_defaults() -local sound_glass = default.node_sound_glass_defaults() -local sound_leaves = default.node_sound_leaves_defaults() +local sound_dirt = moreblocks.node_sound_dirt_defaults() +local sound_wood = moreblocks.node_sound_wood_defaults() +local sound_stone = moreblocks.node_sound_stone_defaults() +local sound_glass = moreblocks.node_sound_glass_defaults() +local sound_leaves = moreblocks.node_sound_leaves_defaults() -- Don't break on 0.4.14 and earlier. -local sound_metal = (default.node_sound_metal_defaults - and default.node_sound_metal_defaults() or sound_stone) +local sound_metal = (moreblocks.node_sound_metal_defaults + and moreblocks.node_sound_metal_defaults() or sound_stone) local function tile_tiles(name) local tex = "moreblocks_" ..name.. ".png" diff --git a/mods/moreblocks/sounds.lua b/mods/moreblocks/sounds.lua new file mode 100644 index 00000000..5385d275 --- /dev/null +++ b/mods/moreblocks/sounds.lua @@ -0,0 +1,20 @@ +--[[ +More Blocks: sound definitions + +Copyright © 2011-2021 Hugo Locurcio and contributors. +Licensed under the zlib license. See LICENSE.md for more information. +--]] + +local has_default_mod = minetest.get_modpath("default") +for _, sound in ipairs({"dirt", "wood", "stone", "metal", "glass", "leaves"}) do + -- use sound-function from default if available + -- otherwise fall back to a no-op function (no sounds) + local sound_function_name = "node_sound_" .. sound .. "_defaults" + if has_default_mod then + -- use default sounds + moreblocks[sound_function_name] = default[sound_function_name] + else + -- no-op + moreblocks[sound_function_name] = function() end + end +end diff --git a/mods/moreblocks/stairsplus/API.md b/mods/moreblocks/stairsplus/API.md index c0fea321..46b838d6 100644 --- a/mods/moreblocks/stairsplus/API.md +++ b/mods/moreblocks/stairsplus/API.md @@ -10,7 +10,7 @@ description = "Wooden", tiles = {"default_wood.png"}, groups = {oddly_breakabe_by_hand=1}, - sounds = default.node_sound_wood_defaults(), + sounds = moreblocks.node_sound_wood_defaults(), }) ``` The following register only a particular type of microblock. diff --git a/mods/moreblocks/stairsplus/custom.lua b/mods/moreblocks/stairsplus/custom.lua index 0b3078f1..961d1ea8 100644 --- a/mods/moreblocks/stairsplus/custom.lua +++ b/mods/moreblocks/stairsplus/custom.lua @@ -69,7 +69,7 @@ local function register_custom_subset(subset, modname, subname, recipeitem, grou description = description, drop = drop, light_source = light, - sounds = default.node_sound_stone_defaults(), + sounds = moreblocks.node_sound_stone_defaults(), }) end diff --git a/mods/moreblocks/stairsplus/microblocks.lua b/mods/moreblocks/stairsplus/microblocks.lua index d2c9579a..88f94fc2 100644 --- a/mods/moreblocks/stairsplus/microblocks.lua +++ b/mods/moreblocks/stairsplus/microblocks.lua @@ -15,7 +15,7 @@ local function register_micro(modname, subname, recipeitem, groups, images, desc description = description, drop = drop, light_source = light, - sounds = default.node_sound_stone_defaults(), + sounds = moreblocks.node_sound_stone_defaults(), }) end diff --git a/mods/moreblocks/stairsplus/panels.lua b/mods/moreblocks/stairsplus/panels.lua index ff572c7e..40f33204 100644 --- a/mods/moreblocks/stairsplus/panels.lua +++ b/mods/moreblocks/stairsplus/panels.lua @@ -15,7 +15,7 @@ local function register_panel(modname, subname, recipeitem, groups, images, desc description = description, drop = drop, light_source = light, - sounds = default.node_sound_stone_defaults(), + sounds = moreblocks.node_sound_stone_defaults(), }) end diff --git a/mods/moreblocks/stairsplus/registrations.lua b/mods/moreblocks/stairsplus/registrations.lua index 5a2eb772..8b7864ee 100644 --- a/mods/moreblocks/stairsplus/registrations.lua +++ b/mods/moreblocks/stairsplus/registrations.lua @@ -6,75 +6,77 @@ Licensed under the zlib license. See LICENSE.md for more information. --]] -- default registrations -local default_nodes = { -- Default stairs/slabs/panels/microblocks: - "stone", - "stone_block", - "cobble", - "mossycobble", - "brick", - "sandstone", - "steelblock", - "goldblock", - "copperblock", - "bronzeblock", - "diamondblock", - "tinblock", - "desert_stone", - "desert_stone_block", - "desert_cobble", - "meselamp", - "glass", - "tree", - "wood", - "jungletree", - "junglewood", - "pine_tree", - "pine_wood", - "acacia_tree", - "acacia_wood", - "aspen_tree", - "aspen_wood", - "obsidian", - "obsidian_block", - "obsidianbrick", - "obsidian_glass", - "stonebrick", - "desert_stonebrick", - "sandstonebrick", - "silver_sandstone", - "silver_sandstone_brick", - "silver_sandstone_block", - "desert_sandstone", - "desert_sandstone_brick", - "desert_sandstone_block", - "sandstone_block", - "coral_skeleton", - "ice", -} +if minetest.get_modpath("default") then + local default_nodes = { -- Default stairs/slabs/panels/microblocks: + "stone", + "stone_block", + "cobble", + "mossycobble", + "brick", + "sandstone", + "steelblock", + "goldblock", + "copperblock", + "bronzeblock", + "diamondblock", + "tinblock", + "desert_stone", + "desert_stone_block", + "desert_cobble", + "meselamp", + "glass", + "tree", + "wood", + "jungletree", + "junglewood", + "pine_tree", + "pine_wood", + "acacia_tree", + "acacia_wood", + "aspen_tree", + "aspen_wood", + "obsidian", + "obsidian_block", + "obsidianbrick", + "obsidian_glass", + "stonebrick", + "desert_stonebrick", + "sandstonebrick", + "silver_sandstone", + "silver_sandstone_brick", + "silver_sandstone_block", + "desert_sandstone", + "desert_sandstone_brick", + "desert_sandstone_block", + "sandstone_block", + "coral_skeleton", + "ice", + } -for _, name in pairs(default_nodes) do - local mod = "default" - local nodename = mod .. ":" .. name - local ndef = table.copy(minetest.registered_nodes[nodename]) - ndef.sunlight_propagates = true + for _, name in pairs(default_nodes) do + local mod = "default" + local nodename = mod .. ":" .. name + local ndef = table.copy(minetest.registered_nodes[nodename]) + ndef.sunlight_propagates = true - -- Stone and desert_stone drop cobble and desert_cobble respectively. - if type(ndef.drop) == "string" then - ndef.drop = ndef.drop:gsub(".+:", "") + -- Stone and desert_stone drop cobble and desert_cobble respectively. + if type(ndef.drop) == "string" then + ndef.drop = ndef.drop:gsub(".+:", "") + end + + -- Use the primary tile for all sides of cut glasslike nodes and disregard paramtype2. + if #ndef.tiles > 1 and ndef.drawtype and ndef.drawtype:find("glass") then + ndef.tiles = {ndef.tiles[1]} + ndef.paramtype2 = nil + end + + mod = "moreblocks" + stairsplus:register_all(mod, name, nodename, ndef) + minetest.register_alias_force("stairs:stair_" .. name, mod .. ":stair_" .. name) + minetest.register_alias_force("stairs:stair_outer_" .. name, mod .. ":stair_" .. name .. "_outer") + minetest.register_alias_force("stairs:stair_inner_" .. name, mod .. ":stair_" .. name .. "_inner") + minetest.register_alias_force("stairs:slab_" .. name, mod .. ":slab_" .. name) end - - -- Use the primary tile for all sides of cut glasslike nodes and disregard paramtype2. - if #ndef.tiles > 1 and ndef.drawtype and ndef.drawtype:find("glass") then - ndef.tiles = {ndef.tiles[1]} - ndef.paramtype2 = nil - end - - mod = "moreblocks" - stairsplus:register_all(mod, name, nodename, ndef) - minetest.register_alias_force("stairs:stair_" .. name, mod .. ":stair_" .. name) - minetest.register_alias_force("stairs:stair_outer_" .. name, mod .. ":stair_" .. name .. "_outer") - minetest.register_alias_force("stairs:stair_inner_" .. name, mod .. ":stair_" .. name .. "_inner") - minetest.register_alias_force("stairs:slab_" .. name, mod .. ":slab_" .. name) end -- farming registrations @@ -118,7 +120,7 @@ if minetest.get_modpath("basic_materials") then description = "Concrete", tiles = {"basic_materials_concrete_block.png",}, groups = {cracky=1, level=2, concrete=1}, - sounds = default.node_sound_stone_defaults(), + sounds = moreblocks.node_sound_stone_defaults(), }) minetest.register_alias("prefab:concrete_stair","technic:stair_concrete") @@ -128,7 +130,7 @@ if minetest.get_modpath("basic_materials") then description = "Cement", tiles = {"basic_materials_cement_block.png"}, groups = {cracky=2, not_in_creative_inventory=1}, - sounds = default.node_sound_stone_defaults(), + sounds = moreblocks.node_sound_stone_defaults(), sunlight_propagates = true, }) diff --git a/mods/moreblocks/stairsplus/slabs.lua b/mods/moreblocks/stairsplus/slabs.lua index abccd2a2..520b17db 100644 --- a/mods/moreblocks/stairsplus/slabs.lua +++ b/mods/moreblocks/stairsplus/slabs.lua @@ -15,7 +15,7 @@ local function register_slab(modname, subname, recipeitem, groups, images, descr description = description, drop = drop, light_source = light, - sounds = default.node_sound_stone_defaults(), + sounds = moreblocks.node_sound_stone_defaults(), }) end diff --git a/mods/moreblocks/stairsplus/slopes.lua b/mods/moreblocks/stairsplus/slopes.lua index 5ab00b00..df3469b8 100644 --- a/mods/moreblocks/stairsplus/slopes.lua +++ b/mods/moreblocks/stairsplus/slopes.lua @@ -15,7 +15,7 @@ local function register_slope(modname, subname, recipeitem, groups, images, desc description = description, drop = drop, light_source = light, - sounds = default.node_sound_stone_defaults(), + sounds = moreblocks.node_sound_stone_defaults(), }) end diff --git a/mods/moreblocks/stairsplus/stairs.lua b/mods/moreblocks/stairsplus/stairs.lua index 82770c2d..a90a0264 100644 --- a/mods/moreblocks/stairsplus/stairs.lua +++ b/mods/moreblocks/stairsplus/stairs.lua @@ -15,7 +15,7 @@ local function register_stair(modname, subname, recipeitem, groups, images, desc description = description, drop = drop, light_source = light, - sounds = default.node_sound_stone_defaults(), + sounds = moreblocks.node_sound_stone_defaults(), }) end diff --git a/mods/morelights/README.md b/mods/morelights/README.md index fc2bedff..c4403a11 100644 --- a/mods/morelights/README.md +++ b/mods/morelights/README.md @@ -17,7 +17,7 @@ models. Some nodes (ceiling lights, bar lights, poles) can be rotated to serve different purposes. -Morelights currently supports both Minetest Game and MineClone 2. +Morelights currently supports Minetest Game, MineClone 2, and Hades Revisited. ## Craft Recipes diff --git a/mods/morelights/crafts.md b/mods/morelights/crafts.md index bd394d15..14f2b690 100644 --- a/mods/morelights/crafts.md +++ b/mods/morelights/crafts.md @@ -1,17 +1,22 @@ # Craft recipes for Morelights items -Copper = copper ingot (Minetest Game) or redstone (MineClone 2) +Copper = copper ingot (Minetest Game, Hades Revisited) or redstone +(MineClone 2). Dye = white or dark grey dye, depending on the desired color of the item. For MineClone 2, use bone meal or grey dye. -Dark Wood = jungle wood planks (Minetest Game) or spruce wood (MineClone 2). +Dark Wood = jungle wood planks (Minetest Game), spruce wood (MineClone 2), or +tropical wood planks (Hades Revisited). Glass = regular, non-stained glass block. -Glass Pane = regular, non-stained glass pane. +Glass Pane = regular, non-stained glass pane. For Hades Revisited, if +`hades_extensionmods`/`hades_xpanes` is not available, use regular glass +instead. -Steel = steel ingot (Minetest Game) or iron ingot (MineClone 2). +Steel = steel ingot (Minetest Game, Hades Revisited) or iron ingot +(MineClone 2). ## Basic items @@ -185,10 +190,12 @@ Use light/dark grey wool. ### Brass Ingot -Minetest Game: Craft from one steel and one tin ingot. +Minetest Game, Hades Revisited: Craft from one steel and one tin ingot. MineClone 2: Craft from one iron ingot and one redstone. +If `basic_materials` is installed, its Brass Ingot will be used instead. + ### Brass Chain ``` @@ -259,14 +266,12 @@ MineClone 2: Craft from one iron ingot and one redstone. +--------+ | Glass | +--------+ -| Cotton | +| String | +--------+ | Brass | +--------+ ``` -For MineClone 2, use string instead of cotton. - ### Vintage Chandelier ``` @@ -294,7 +299,8 @@ For MineClone 2, use string instead of cotton. +---------+-------+---------+ ``` -Crystal = mese fragment (Minetest Game) or nether quartz (MineClone 2). +Crystal = mese fragment (Minetest Game, Hades Revisited) or nether quartz +(MineClone 2). ### Grass Light @@ -343,6 +349,8 @@ For MineClone 2, use polished stone. For MineClone 2, use cut sandstone. +For Hades Revisited, use fine sandstone. + ### Stair Light ``` diff --git a/mods/morelights/modpack.conf b/mods/morelights/modpack.conf index 9b04856d..908dba0c 100644 --- a/mods/morelights/modpack.conf +++ b/mods/morelights/modpack.conf @@ -1,2 +1,3 @@ name = morelights description = A lightweight modpack providing flexible interior and exterior lighting options for different styles of builds. +min_minetest_version = 5.4 diff --git a/mods/morelights/modpack.txt b/mods/morelights/modpack.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/mods/morelights/morelights/init.lua b/mods/morelights/morelights/init.lua index 01c8f2be..9f619acb 100644 --- a/mods/morelights/morelights/init.lua +++ b/mods/morelights/morelights/init.lua @@ -19,8 +19,8 @@ end function morelights.on_place_hanging(itemstack, placer, pointed_thing, ceilingName) - local ceiling = minetest.get_node(vector.add(pointed_thing.above, - {x=0, y=1, z=0})) + local ceiling = minetest.get_node( + vector.add(pointed_thing.above, vector.new(0, 1, 0))) if ceiling.name ~= "air" and minetest.get_item_group(ceiling.name, "mounted_ceiling") == 0 @@ -53,9 +53,11 @@ if minetest.get_modpath("mcl_core") then morelights.game = "mineclone2" elseif minetest.get_modpath("default") then morelights.game = "minetest_game" +elseif minetest.get_modpath("hades_core") then + morelights.game = "hades_revisited" else error("Morelights requires a compatible game " .. - "(Minetest Game or MineClone 2).") + "(Minetest Game, MineClone 2, or Hades Revisited).") end if morelights.game == "minetest_game" then @@ -70,6 +72,12 @@ elseif morelights.game == "mineclone2" then glass = mcl_sounds.node_sound_glass_defaults(), metal = mcl_sounds.node_sound_metal_defaults() } +elseif morelights.game == "hades_revisited" then + morelights.sounds = { + default = hades_sounds.node_sound_defaults(), + glass = hades_sounds.node_sound_glass_defaults(), + metal = hades_sounds.node_sound_metal_defaults() + } end morelights.craft_items = { @@ -88,7 +96,7 @@ morelights.craft_items = { sandstone_block = "default:sandstone_block", dirt = "default:dirt", grass = "default:grass_1", - cotton = "farming:cotton", + string = "farming:string", stick = "default:stick", } @@ -111,8 +119,31 @@ if morelights.game == "mineclone2" then a.sandstone_block = "mcl_core:sandstonesmooth" a.dirt = "mcl_core:dirt" a.grass = "mcl_flowers:tallgrass" - a.cotton = "mcl_mobitems:string" + a.string = "mcl_mobitems:string" a.stick = "mcl_core:stick" +elseif morelights.game == "hades_revisited" then + a.glass = "hades_core:glass" + -- HR doesn't have glass panes. :( + a.glass_pane = "hades_core:glass" + if minetest.get_modpath("hades_xpanes") then + a.glass_pane = "hades_xpanes:pane_flat" + end + + a.steel = "hades_core:steel_ingot" + a.copper = "hades_core:copper_ingot" + a.tin = "hades_core:tin_ingot" + a.crystal_fragment = "hades_core:mese_crystal_fragment" + a.dye_dark = "dye:dark_grey" + a.dye_light = "dye:white" + a.wool_dark = "wool:grey" + a.wool_light = "wool:white" + a.wood_dark = "hades_trees:jungle_wood" + a.stone_block = "hades_core:stone_block" + a.sandstone_block = "hades_core:sandstone" + a.dirt = "hades_core:dirt" + a.grass = "hades_grass:grass_1" + a.string = "hades_farming:cotton" + a.stick = "hades_core:stick" end -- Use basic_materials brass if available, otherwise register our own. @@ -121,4 +152,4 @@ if minetest.get_modpath("basic_materials") then end local path = minetest.get_modpath("morelights") -dofile(path .. DIR_DELIM .. "nodes.lua") +dofile(path .. "/nodes.lua") diff --git a/mods/morelights/morelights/mod.conf b/mods/morelights/morelights/mod.conf index 6b597e94..6f468470 100644 --- a/mods/morelights/morelights/mod.conf +++ b/mods/morelights/morelights/mod.conf @@ -1,3 +1,3 @@ name = morelights description = Base mod providing basic items, which the rest of the modpack depends on. -optional_depends = default, mcl_core +optional_depends = default, mcl_core, hades_core diff --git a/mods/morelights/morelights_extras/init.lua b/mods/morelights/morelights_extras/init.lua index 4467b893..6703ca83 100644 --- a/mods/morelights/morelights_extras/init.lua +++ b/mods/morelights/morelights_extras/init.lua @@ -35,41 +35,63 @@ do -- For MineClone 2, use node coloring to match environment. -- See the mcl_core:dirt_with_grass definition in -- ITEMS/mcl_core/nodes_base.lua. - local override = { - tiles = { - "mcl_core_grass_block_top.png", - {name = "default_dirt.png", color = "#FFFFFF"} - }, - overlay_tiles = { - {name = "morelights_extras_blocklight.png", color = "#FFFFFF"}, - "", - { - name = "mcl_core_grass_block_side_overlay.png", - tileable_vertical = false - } - }, - paramtype2 = "color", - palette = "mcl_core_palette_grass.png", - palette_index = 0, - color = "#55aa60", - drop = "morelights_extras:dirt_with_grass", + def.tiles = { + "mcl_core_grass_block_top.png", + {name = "default_dirt.png", color = "#FFFFFF"} + } + def.overlay_tiles = { + {name = "morelights_extras_blocklight.png", color = "#FFFFFF"}, + "", + { + name = "mcl_core_grass_block_side_overlay.png", + tileable_vertical = false + } + } + def.paramtype2 = "color" + def.palette = "mcl_core_palette_grass.png" + def.palette_index = 0 + def.color = "#55aa60" + def.drop = "morelights_extras:dirt_with_grass" - on_construct = function(pos) - local node = minetest.get_node(pos) - if node.param2 == 0 then - local grass_node = mcl_core.get_grass_block_type(pos) - if grass_node.param2 ~= 0 then - minetest.set_node(pos, { - name = "morelights_extras:dirt_with_grass", - param2 = grass_node.param2 - }) - end + def.on_construct = function(pos) + local node = minetest.get_node(pos) + if node.param2 == 0 then + local grass_node = mcl_core.get_grass_block_type(pos) + if grass_node.param2 ~= 0 then + minetest.set_node(pos, { + name = "morelights_extras:dirt_with_grass", + param2 = grass_node.param2 + }) end end + end + elseif morelights.game == "hades_revisited" then + -- For Hades Revisited, grass color is seasonal. + -- See hades_core/dirt.lua, ABM in hades_core/functions.lua. + def.tiles = { + "hades_core_grass_cover_colorable.png", + {name = "default_dirt.png", color = "#FFFFFF"}, } + def.overlay_tiles = { + {name = "morelights_extras_blocklight.png", color = "#FFFFFF"}, + "", + { + name = "hades_core_grass_side_cover_colorable.png", + tileable_vertical = false + }, + } + def.paramtype2 = "color" + def.palette = "hades_core_palette_grass.png" + def.palette_index = 0 + def.color = "#acef6a" + -- To enable seasonal grass coloring. + def.groups.dirt_with_grass = 1 + -- To prevent color retention on digging. + def.drop = "morelights_extras:dirt_with_grass" - for k, v in pairs(override) do - def[k] = v + def.on_place = function(itemstack, placer, pointed_thing) + local param2 = hades_core.get_seasonal_grass_color_param2() + return minetest.item_place(itemstack, placer, pointed_thing, param2) end end @@ -97,6 +119,8 @@ do local tile = "default_sandstone_block.png" if morelights.game == "mineclone2" then tile = "mcl_core_sandstone_smooth.png" + elseif morelights.game == "hades_revisited" then + tile = "default_sandstone.png" end minetest.register_node("morelights_extras:sandstone_block", { @@ -158,8 +182,8 @@ minetest.register_node("morelights_extras:stairlight", { or node.name:match("^mcl_stairs:stair_")) then -- Set `above` to the node actually above the stair, since that's -- where the node is placed. - pointed_thing.above = vector.add(pointed_thing.under, - {x=0, y=1, z=0}) + pointed_thing.above = + vector.add(pointed_thing.under, vector.new(0, 1, 0)) return minetest.item_place_node(itemstack, placer, pointed_thing, node.param2) end diff --git a/mods/morelights/morelights_vintage/init.lua b/mods/morelights/morelights_vintage/init.lua index 40dcf077..974390d3 100644 --- a/mods/morelights/morelights_vintage/init.lua +++ b/mods/morelights/morelights_vintage/init.lua @@ -348,7 +348,7 @@ minetest.register_craft({ output = "morelights_vintage:oillamp", recipe = { {"", a.glass, ""}, - {"", a.cotton, ""}, + {"", a.string, ""}, {"", a.brass, ""} } }) diff --git a/mods/protector/init.lua b/mods/protector/init.lua index 7044b740..2e20b109 100644 --- a/mods/protector/init.lua +++ b/mods/protector/init.lua @@ -805,4 +805,4 @@ if minetest.get_modpath("mesecons_mvps") then end -print (S("[MOD] Protector Redo loaded")) +print ("[MOD] Protector Redo loaded") diff --git a/mods/protector/pvp.lua b/mods/protector/pvp.lua index 0efb62a8..529fb1ae 100644 --- a/mods/protector/pvp.lua +++ b/mods/protector/pvp.lua @@ -23,7 +23,7 @@ and minetest.settings:get_bool("protector_pvp") then if not player or not hitter then - print(S("[Protector] on_punchplayer called with nil objects")) + print("[Protector] on_punchplayer called with nil objects") end if not hitter:is_player() then @@ -64,9 +64,9 @@ and minetest.settings:get_bool("protector_pvp") then end) else - print(S("[Protector] pvp_protect not active, update your version of Minetest")) + print("[Protector] pvp_protect not active, update your version of Minetest") end else - print(S("[Protector] pvp_protect is disabled")) + print("[Protector] pvp_protect is disabled") end diff --git a/mods/protector/tool.lua b/mods/protector/tool.lua index 14570a61..3f6709d0 100644 --- a/mods/protector/tool.lua +++ b/mods/protector/tool.lua @@ -78,6 +78,11 @@ minetest.register_craftitem("protector:tool", { return end + -- do not place protector out of map bounds + if minetest.find_node_near(pos, 1, {"ignore"}) then + return + end + -- do we have protectors to use ? local nod local inv = user:get_inventory() diff --git a/mods/skinsdb/meta/character_1141.txt b/mods/skinsdb/meta/character_1141.txt index e5aadf75..44599bfa 100644 --- a/mods/skinsdb/meta/character_1141.txt +++ b/mods/skinsdb/meta/character_1141.txt @@ -1,3 +1,3 @@ Skeleton I dont know -CC BY-SA 3.0 +CC BY-SA 4.0 diff --git a/mods/skinsdb/meta/character_2114.txt b/mods/skinsdb/meta/character_2114.txt new file mode 100644 index 00000000..3e80a858 --- /dev/null +++ b/mods/skinsdb/meta/character_2114.txt @@ -0,0 +1,3 @@ +TommyInnit +Christian_Soldier +CC 0 (1.0) diff --git a/mods/skinsdb/meta/character_2115.txt b/mods/skinsdb/meta/character_2115.txt new file mode 100644 index 00000000..a60fcdd5 --- /dev/null +++ b/mods/skinsdb/meta/character_2115.txt @@ -0,0 +1,3 @@ +Dream(fixed4Real) +Christian_Soldier +CC 0 (1.0) diff --git a/mods/skinsdb/meta/character_2116.txt b/mods/skinsdb/meta/character_2116.txt new file mode 100644 index 00000000..5c7754c5 --- /dev/null +++ b/mods/skinsdb/meta/character_2116.txt @@ -0,0 +1,3 @@ +Ranboo +Christian_Soldier +CC 0 (1.0) diff --git a/mods/skinsdb/meta/character_2113.txt b/mods/skinsdb/meta/character_2117.txt similarity index 70% rename from mods/skinsdb/meta/character_2113.txt rename to mods/skinsdb/meta/character_2117.txt index fdcb5f33..94ea851c 100644 --- a/mods/skinsdb/meta/character_2113.txt +++ b/mods/skinsdb/meta/character_2117.txt @@ -1,3 +1,3 @@ -nick_ +nick_ I nick_ CC BY-SA 3.0 diff --git a/mods/skinsdb/meta/character_2118.txt b/mods/skinsdb/meta/character_2118.txt new file mode 100644 index 00000000..ee9161c3 --- /dev/null +++ b/mods/skinsdb/meta/character_2118.txt @@ -0,0 +1,3 @@ +RedMiniontoby +Miniontoby +CC BY-NC-SA 4.0 diff --git a/mods/skinsdb/textures/character_2113.png b/mods/skinsdb/textures/character_2113.png deleted file mode 100644 index 835334e0361d14a1e58bf7be1b7436a75ab4b804..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3178 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 NeH|lYnU-Dne*mt)>w*9P diff --git a/mods/skinsdb/textures/character_2114.png b/mods/skinsdb/textures/character_2114.png new file mode 100644 index 0000000000000000000000000000000000000000..c8a96abb1343cacf2671db4d977812a5956ef8c3 GIT binary patch literal 9508 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 F{{c6eZ@&Nl literal 0 HcmV?d00001 diff --git a/mods/skinsdb/textures/character_2115.png b/mods/skinsdb/textures/character_2115.png new file mode 100644 index 0000000000000000000000000000000000000000..008c8e8c1fa97241f4f00f110e959ebea388ff23 GIT binary patch literal 6213 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� zrwU>?6`C5daemc-u3^2IDxli*#5<%l4gSBxHJc^&2J^L^?9ILCJca`A$s!8ZrY;n+ zFrI-f$y@q&{irJMZ@f1PGWJ^$W6OSH0iiaQhA_&&wUwjk~J^bjp zVRd9H69|1*h9ZWJqG|$6xArcKY)OE~md4<8s`9%y3Q!!|D<$)igGVmP5CV`I{h#kQ zGjOx#%9$U2Gj>`_(9MDvzyzmgNzC+WXC)7)G_1KIhEr&~RUDIhzuy#4%;KnkmJUH2 zktH+?Vn3`PhoI(a;9KdHhiZKBV)k#lIE)2 z4{`9Z_bz#he}ui?JmxgJ`kDBd@V+wkP^lQ=LtjM7Zf9derNdl5#52T)t9W1whZrQXNS|G|aF z+ZT^t7T3E88>>wpH{bguIgMf%{!|$7;e7+K`EVFWm6P{5(_(0fUu~D zH_LWX?pC`=U;Z!Wo7lcX!4=av{OwC!+^}meMgl~|Ss<7n-nYGg^EC%I zl}FI%c{p3|i*e_hju=qy`xu=L@ygq6OdDlzv#F9L>y#`Vmad`c_~>{c%IlrlaHS*% zs}w5i1QD!lJuI$y0>E%lN3|8;%(5#0EYv;ho95vR;JDF79?*3qN!}{poXc$h${!E_ z>Ovj!rVi!z@7xpTYz@n+t{C0-LyQ$ogou%|b(}ig-Z%~$E@lubv4lpw>tpArjp<$< z%PmJd$ptx}EVf-)XD)2wqwgQU$rswVcDjOU*TWteUexvT#pINi!0~;0zfvqnOgpYC z0CY+Xw4G4A%xlMq#Q3>Y7c(Ok+D?FNgBby)lIJiMqwhv?U+;u)7m_d=%w>di1eSWz z31psf|DowvXxH^o$m$yaEVW!r4p~@Oc0j{<3S?$9>=-q%SocKggg>{G6d(Sj+96V>^qBi?=K%o>!U zCm=Bd_6#LwhNK^jPvhJPLbyRB-lxIz4xbSKN-)wC11Y5Szn<<18|vLa^3=W^_Igf8 zJW2*whJtgeNwRepZPAA^SxOo)GJ$!H-z&#%+a2@Zz>gxC)>fMyE}h6qU1mSPQb-0+ z$byMsQ$AN)9>&Wiu#hUJ3caYrtBY;iaGiy@RR?<~vf_=u|6vc8jO4L%AdA6l2DP4t zTt>q?wdDIkK99(EFyBbZqyS}_ShAKRq0tz6-SzmNLy~a$dFQB!f~BJEBsqZjg1w7W zie8B3oVk%$xhD4{0MwJB9Ql=;L`~?4%85NN{4CUv=daHa!gSqgcjSZbIgi zn?{nXbXBe?0C)US5zoF{#eE0HW$OFm@6@n=TUiob>Ji2z0Z3WFFk%j9cRKPv1lJm# zO`04UYa0xkAGaZ_0xX9!qvpnQh6lwDVszXHtM6pQ^J)B3M+z$fldy8)uGyI0CJ4UJ zJV;83t>fIPgS@4q)eWQqthPC3+8YV7VrdA@LlCA>q*bFI;GgE|xbZ_4{`svo-dybA zzMCiT%-=Kw0LER(B52`8xJ;F8VE`)t*I_6S6vN8mbTo(U!x^DD6Wfo@_AxtQVR6kD zFOOGr%&mGT*qVSrkjgm?wy8>92&Ie(%JN5=1@vMVqajCD zK(iB|oKI$VGGf<6HYt_N0Wt8&nQhW6QI^}TB*1fxKCa!L!OL&7@R7?)$eWq~z&t>@ zQ-SG%A02SN7nYA8lUBj7r4|n`R35yL6r;R<;CSoPCns5s*_>=M`9Xa5 z*l%O+aPl`E8!dXBNju#~x$%m@c&Nw>nq*mem6HAkSZjI`25g0y6bH)&meyPhm6F6b z;{S literal 0 HcmV?d00001 diff --git a/mods/skinsdb/textures/character_2118.png b/mods/skinsdb/textures/character_2118.png new file mode 100644 index 0000000000000000000000000000000000000000..834bb72d0858dfa8f859ff7e34d82d1f15b6e67d GIT binary patch literal 1302 zcmV+x1?l>UP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D1gl9zK~!i%%EW3mlcYPZ|U?x8ibR@wCL_-h_DkPtN`UnV`kNgBbBtm}jDWZspeyO0K zU_?U_A0G-De1XJd)J09=OrnTpU$d_4ZhKEn-QJqop6QwH9vtz&nYy>?R!`s4x2k$} z9SXplw`aN9^u^QTX>Ap;b?zV9D&lL(1%AiNL}URD-s{m8(aIYiC;`^bY}GwPZ$0R4 zXaN$sjRmLP|E(nXR{^mKP!9|fxj!?@wK^;`8eV`i%#SOyQPJ=MEa!cynOUyYVWH9R z0@NF?y#P)v#~hHJ)v2u_<~I*%D;)m1|BqM3*wnDD!^;ClnEgQZ0KC{Z zBfHu9g50L2n)iX?{1I|pzDD!rs^^cZ0KeoHJH6T(1Ha>IYYdT>!|hE(JBv#z6nL(4 zXR~&y!?+44_w@Zlcs%o6ZH=MUDlkt0JVmr&Pk}J=tKI`HxE+c}S{OHQ<6)Br!pt8R z+}74sQV|0K1KRRX@eB5ox!y0|GUz@OYv`ou}l z3B5j7u>ikv-wN(~lYKKDka9NrMUWPzlsfuweKQVcj^FhF_(6M00?9<7+`PFqA)MUw zOpQOT5^qBB>;s_Vt4hO9j|OviNd|fh_{~5eXyl!~YMmM=ZnyPXwDt ze2%6mPB{i4b^&lxsZ@$qa4RveA%Ncv%aaF=4i#U6xAlxrYU0>(Fp0$RYXr2%{1}8p zZ*Q-6qp-30iEr9MJKpb0yLqcZD{-(hnM_HH5RfN-q^pH~cP3Ew*{JvDUOV1zNmODG z5_mG%Y*rC=KA)#tE~g0Fh85AVipd?ks;2U0u3NC69RY+k(T#9P_#$#=q5XlVK6` z>kxyHBwlV+fCvD7_~UW@B)YVEjhB?XzyR<8_#y%z$)nv@R{@A#0F-my&H>oAT>t<8 M07*qoM6N<$f@e-;T>t<8 literal 0 HcmV?d00001 diff --git a/mods/techpack/README.md b/mods/techpack/README.md index 4a3ab2aa..c2e8fbc4 100644 --- a/mods/techpack/README.md +++ b/mods/techpack/README.md @@ -186,6 +186,7 @@ tubelib_addons13 optional: minecart - 2020-11-20 V2.04 * Switch to AGPL v3, adapt to minetest 5.3, add translation support, fix minor bugs - 2021-01-24 V2.05 * PR #74, #76: Implement checks for valid connection sides for many nodes - 2021-06-06 V2.06 * PR #78 - #89, chest cart added +- 2021-09-03 V2.07 * FR #103, Add Altitude to harvester menu ## New in v2 (from players point of view) diff --git a/mods/techpack/gravelsieve/init.lua b/mods/techpack/gravelsieve/init.lua index dd530a22..1ae7edcc 100644 --- a/mods/techpack/gravelsieve/init.lua +++ b/mods/techpack/gravelsieve/init.lua @@ -693,7 +693,7 @@ minetest.register_node("gravelsieve:compressed_gravel", { }) minetest.register_craft({ - output = "gravelsieve:sieve", + output = "gravelsieve:sieve3", recipe = { {"group:wood", "", "group:wood"}, {"group:wood", "default:steel_ingot", "group:wood"}, @@ -702,10 +702,10 @@ minetest.register_craft({ }) minetest.register_craft({ - output = "gravelsieve:auto_sieve", + output = "gravelsieve:auto_sieve3", type = "shapeless", recipe = { - "gravelsieve:sieve", "default:mese_crystal", "default:mese_crystal", + "gravelsieve:sieve3", "default:mese_crystal", "default:mese_crystal", }, }) diff --git a/mods/techpack/tubelib_addons1/harvester.lua b/mods/techpack/tubelib_addons1/harvester.lua index e853576e..9e0dffc8 100644 --- a/mods/techpack/tubelib_addons1/harvester.lua +++ b/mods/techpack/tubelib_addons1/harvester.lua @@ -3,7 +3,7 @@ Tubelib Addons 1 ================ - Copyright (C) 2017-2020 Joachim Stolberg + Copyright (C) 2017-2021 Joachim Stolberg AGPL v3 See LICENSE.txt for more information @@ -27,7 +27,7 @@ local P = minetest.string_to_pos local M = minetest.get_meta local CYCLE_TIME = 6 -local MAX_HEIGHT = 18 -- harvesting altitude +local START_HEIGHT = 18 -- harvesting altitude local MAX_DIAMETER = 33 local BURNING_TIME = 20 -- fuel local STANDBY_TICKS = 4 -- used for blocked state @@ -35,13 +35,14 @@ local COUNTDOWN_TICKS = 2 local OFFSET = 5 -- for uneven terrains -- start on top of the base block -local function working_start_pos(pos) +local function working_start_pos(pos, altitude) local working_pos = table.copy(pos) - working_pos.y = working_pos.y + MAX_HEIGHT + working_pos.y = working_pos.y + (altitude or START_HEIGHT) return working_pos end local Radius2Idx = {[4]=1 ,[6]=2, [8]=3, [10]=4, [12]=5, [14]=6, [16]=7} +local Altitude2Idx = {[-2]=1 ,[-1]=2, [0]=3, [1]=4, [2]=5, [4]=6, [6]=7, [8]=8, [10]=9, [14]=10, [18]=11} local function formspec(self, pos, meta) -- some recalculations @@ -52,6 +53,7 @@ local function formspec(self, pos, meta) fuel = 0 end local radius = Radius2Idx[this.radius] or 2 + local altitude = Altitude2Idx[this.altitude or START_HEIGHT] or 11 return "size[9,8]".. default.gui_bg.. @@ -59,7 +61,9 @@ local function formspec(self, pos, meta) default.gui_slots.. "dropdown[0,0;1.5;radius;4,6,8,10,12,14,16;"..radius.."]".. "label[1.6,0.2;"..S("Area radius").."]".. - "checkbox[0,1;endless;"..S("Run endless")..";"..endless.."]".. + "dropdown[0,1;1.5;altitude;-2,-1,0,1,2,4,6,8,10,14,18;"..altitude.."]".. + "label[1.6,1.2;"..S("Altitude ").."]".. + "checkbox[0,2;endless;"..S("Run endless")..";"..endless.."]".. "list[context;main;5,0;4,4;]".. "list[context;fuel;1.5,3;1,1;]".. "item_image[1.5,3;1,1;tubelib_addons1:biofuel]".. @@ -82,7 +86,7 @@ local State = tubelib.NodeStates:new({ on_start = function(pos, meta, oldstate) local this = minetest.deserialize(meta:get_string("this")) this.idx = 0 - this.working_pos = working_start_pos(pos) + this.working_pos = working_start_pos(pos, this.altitude) meta:set_string("this", minetest.serialize(this)) end, formspec_func = formspec, @@ -210,7 +214,7 @@ local function calc_new_pos(pos, this, meta) if this.idx >= this.max then if this.endless == 1 then this.idx = 0 - this.working_pos = working_start_pos(pos) + this.working_pos = working_start_pos(pos, this.altitude) return true else return false @@ -227,7 +231,7 @@ local function harvest_field(this, meta) local inv = meta:get_inventory() local pos = table.copy(this.working_pos) local start_y_pos = pos.y - 1 - local stop_y_pos = pos.y - MAX_HEIGHT - OFFSET + local stop_y_pos = pos.y - (this.altitude or START_HEIGHT) - OFFSET if minetest.is_protected(pos, this.owner) then return true end @@ -297,6 +301,7 @@ local function on_receive_fields(pos, formname, fields, player) local meta = M(pos) local this = minetest.deserialize(meta:get_string("this")) local radius = this.radius + local altitude = this.altitude or START_HEIGHT if fields.radius ~= nil then radius = tonumber(fields.radius) @@ -308,6 +313,15 @@ local function on_receive_fields(pos, formname, fields, player) State:stop(pos, meta) end + if fields.altitude ~= nil then + altitude = tonumber(fields.altitude) + end + if altitude ~= this.altitude then + this.altitude = altitude + meta:set_string("this", minetest.serialize(this)) + State:stop(pos, meta) + end + if fields.endless ~= nil then this.endless = fields.endless == "true" and 1 or 0 end @@ -334,7 +348,7 @@ minetest.register_node("tubelib_addons1:harvester_base", { local this = { number = number, owner = placer:get_player_name(), - working_pos = working_start_pos(pos), + working_pos = working_start_pos(pos, START_HEIGHT), fuel = 0, endless = 0, radius = 6, @@ -392,7 +406,7 @@ minetest.register_node("tubelib_addons1:harvester_defect", { local this = { number = number, owner = placer:get_player_name(), - working_pos = working_start_pos(pos), + working_pos = working_start_pos(pos, START_HEIGHT), fuel = 0, endless = 0, radius = 6, @@ -487,7 +501,7 @@ minetest.register_lbm({ local meta = M(pos) local this = minetest.deserialize(meta:get_string("this")) if this then - this.working_pos = this.copter_pos or working_start_pos(pos) + this.working_pos = this.copter_pos or working_start_pos(pos, this.altitude) meta:set_string("this", minetest.serialize(this)) end end diff --git a/mods/techpack/tubelib_addons1/locale/template.txt b/mods/techpack/tubelib_addons1/locale/template.txt index b899b77c..92a216de 100644 --- a/mods/techpack/tubelib_addons1/locale/template.txt +++ b/mods/techpack/tubelib_addons1/locale/template.txt @@ -41,6 +41,7 @@ Tubelib Grinder= ### harvester.lua ### : running (= +Altitude = Area radius= Tubelib Harvester= Tubelib Harvester Base= diff --git a/mods/techpack/tubelib_addons1/locale/tubelib_addons1.de.tr b/mods/techpack/tubelib_addons1/locale/tubelib_addons1.de.tr index 14ec1906..69f795e6 100644 --- a/mods/techpack/tubelib_addons1/locale/tubelib_addons1.de.tr +++ b/mods/techpack/tubelib_addons1/locale/tubelib_addons1.de.tr @@ -41,6 +41,7 @@ Tubelib Grinder=Tubelib Mühle ### harvester.lua ### : running (=: läuft ( +Altitude = Flughöhe Area radius=Flächenradius Tubelib Harvester=Tubelib Ernter Tubelib Harvester Base=Tubelib Ernter Basis diff --git a/mods/techpack/tubelib_addons1/nodes.lua b/mods/techpack/tubelib_addons1/nodes.lua index b73c3ec7..0a165503 100644 --- a/mods/techpack/tubelib_addons1/nodes.lua +++ b/mods/techpack/tubelib_addons1/nodes.lua @@ -90,36 +90,44 @@ end -- Farming Redo ----------------------------------------------- -------------------------------- if farming.mod == "redo" then - fn("farming:wheat_8", "farming:wheat", "farming:wheat_1") - fn("farming:cotton_8", "farming:cotton", "farming:cotton_1") - fn("farming:carrot_8", "farming:carrot 2", "farming:carrot_1") - fn("farming:potato_4", "farming:potato 3", "farming:potato_1") - fn("farming:tomato_8", "farming:tomato 3", "farming:tomato_1") - fn("farming:cucumber_4", "farming:cucumber 2", "farming:cucumber_1") - fn("farming:corn_8", "farming:corn 2", "farming:corn_1") - fn("farming:coffee_5", "farming:coffee_beans 2", "farming:coffee_1") - fn("farming:melon_8", "farming:melon_slice 4", "farming:melon_1") - fn("farming:pumpkin_8", "farming:pumpkin_slice 4","farming:pumpkin_1") - fn("farming:raspberry_4", "farming:raspberries", "farming:raspberry_1") - fn("farming:blueberry_4", "farming:blueberries", "farming:blueberry_1") - fn("farming:rhubarb_3", "farming:rhubarb 2", "farming:rhubarb_1") - fn("farming:beanpole_5", "farming:beans 3", "farming:beanpole_1") - fn("farming:grapes_8", "farming:grapes 3", "farming:grapes_1") - fn("farming:barley_7", "farming:barley", "farming:barley_1") - fn("farming:chili_8", "farming:chili_pepper 2", "farming:chili_1") - fn("farming:hemp_8", "farming:hemp_leaf", "farming:hemp_1") - fn("farming:oat_8", "farming:oat", "farming:oat_1") - fn("farming:rye_8", "farming:rye", "farming:rye_1") - fn("farming:rice_8", "farming:rice", "farming:rice_1") - fn('farming:beetroot_5', 'farming:beetroot 2', 'farming:beetroot_1') - fn('farming:cocoa_4', 'farming:cocoa_beans 2', 'farming:cocoa_1') - fn('farming:garlic_5', 'farming:garlic 2', 'farming:garlic_1') - fn('farming:onion_5', 'farming:onion 2', 'farming:onion_1') - fn('farming:pea_5', 'farming:pea_pod 3', 'farming:pea_1') - fn('farming:pepper_5', 'farming:pepper 2', 'farming:pepper_1') - fn('farming:pepper_6', 'farming:pepper_yellow 2','farming:pepper_1') - fn('farming:pepper_7', 'farming:pepper_red 2', 'farming:pepper_1') - fn('farming:pineapple_8', 'farming:pineapple 1', 'farming:pineapple_1') + fn("farming:artichoke_5", "farming:artichoke", "farming:artichoke_1") + fn("farming:barley_7", "farming:barley", "farming:barley_1") + fn("farming:beanpole_5", "farming:beans 3", "farming:beanpole_1") + fn("farming:beetroot_5", "farming:beetroot 2", "farming:beetroot_1") + fn("farming:blackberry_4", "farming:blackberry", "farming:blackberry_1") + fn("farming:blueberry_4", "farming:blueberries", "farming:blueberry_1") + fn("farming:cabbage_6", "farming:cabbage", "farming:cabbage_1") + fn("farming:carrot_8", "farming:carrot 2", "farming:carrot_1") + fn("farming:chili_8", "farming:chili_pepper 2", "farming:chili_1") + fn("farming:cocoa_4", "farming:cocoa_beans 2", "farming:cocoa_1") + fn("farming:coffee_5", "farming:coffee_beans 2", "farming:coffee_1") + fn("farming:corn_8", "farming:corn 2", "farming:corn_1") + fn("farming:cotton_8", "farming:cotton", "farming:cotton_1") + fn("farming:cucumber_4", "farming:cucumber 2", "farming:cucumber_1") + fn("farming:garlic_5", "farming:garlic 2", "farming:garlic_1") + fn("farming:grapes_8", "farming:grapes 3", "farming:grapes_1") + fn("farming:hemp_8", "farming:hemp_leaf", "farming:hemp_1") + fn("farming:lettuce_5", "farming:lettuce", "farming:lettuce_1") + fn("farming:melon_8", "farming:melon_slice 4", "farming:melon_1") + fn("farming:mint_4", "farming:mint_leaf 2", "farming:mint_1") + fn("farming:oat_8", "farming:oat", "farming:oat_1") + fn("farming:onion_5", "farming:onion 2", "farming:onion_1") + fn("farming:parsley_3", "farming:parsley", "farming:parsley_1") + fn("farming:pea_5", "farming:pea_pod 3", "farming:pea_1") + fn("farming:pepper_5", "farming:pepper 2", "farming:pepper_1") + fn("farming:pepper_6", "farming:pepper_yellow 2", "farming:pepper_1") + fn("farming:pepper_7", "farming:pepper_red 2", "farming:pepper_1") + fn("farming:pineapple_8", "farming:pineapple 1", "farming:pineapple_1") + fn("farming:potato_4", "farming:potato 3", "farming:potato_1") + fn("farming:pumpkin_8", "farming:pumpkin_slice 4", "farming:pumpkin_1") + fn("farming:raspberry_4", "farming:raspberries", "farming:raspberry_1") + fn("farming:rhubarb_3", "farming:rhubarb 2", "farming:rhubarb_1") + fn("farming:rice_8", "farming:rice", "farming:rice_1") + fn("farming:rye_8", "farming:rye", "farming:rye_1") + fn("farming:soy_7", "farming:soy_pod", "farming:soy_1") + fn("farming:tomato_8", "farming:tomato 3", "farming:tomato_1") + fn("farming:vanilla_8", "farming:vanilla 2", "farming:vanilla_1") + fn("farming:wheat_8", "farming:wheat", "farming:wheat_1") end ------------------------------------------------------------------------------- diff --git a/mods/unified_inventory/init.lua b/mods/unified_inventory/init.lua index 00a3fc54..53759038 100644 --- a/mods/unified_inventory/init.lua +++ b/mods/unified_inventory/init.lua @@ -43,7 +43,8 @@ unified_inventory = { imgscale = 1.25, list_img_offset = 0.13, standard_background = "background9[0,0;1,1;ui_formbg_9_sliced.png;true;16]", - version = 2 + + version = 3 } local ui = unified_inventory diff --git a/mods/unified_inventory/internal.lua b/mods/unified_inventory/internal.lua index cdf71edb..f83f96be 100644 --- a/mods/unified_inventory/internal.lua +++ b/mods/unified_inventory/internal.lua @@ -22,7 +22,9 @@ end function ui.get_per_player_formspec(player_name) local draw_lite_mode = ui.lite_mode and not minetest.check_player_privs(player_name, {ui_full=true}) - return table.copy(draw_lite_mode and ui.style_lite or ui.style_full), draw_lite_mode + local style = table.copy(draw_lite_mode and ui.style_lite or ui.style_full) + style.is_lite_mode = draw_lite_mode + return style end local function formspec_button(ui_peruser, name, image, offset, pos, scale, label) @@ -41,113 +43,82 @@ local function formspec_button(ui_peruser, name, image, offset, pos, scale, labe string.format("tooltip[%s;%s]", name, F(label or name)) end -function ui.get_formspec(player, page) - - if not player then - return "" - end - - local player_name = player:get_player_name() - local ui_peruser,draw_lite_mode = ui.get_per_player_formspec(player_name) - - ui.current_page[player_name] = page - local pagedef = ui.pages[page] - - if not pagedef then - return "" -- Invalid page name - end - - local formspec = { - "formspec_version[4]", - "size["..ui_peruser.formw..","..ui_peruser.formh.."]", - pagedef.formspec_prepend and "" or "no_prepend[]", - ui.standard_background - } - - local n = 5 - - local perplayer_formspec = ui.get_per_player_formspec(player_name) - local fsdata = pagedef.get_formspec(player, perplayer_formspec) - - formspec[n] = fsdata.formspec - n = n+1 - +local function formspec_add_filters(player, formspec, style) local button_row = 0 local button_col = 0 + local n = #formspec + 1 -- Main buttons local filtered_inv_buttons = {} for i, def in pairs(ui.buttons) do - if not (draw_lite_mode and def.hide_lite) then + if not (style.is_lite_mode and def.hide_lite) then table.insert(filtered_inv_buttons, def) end end for i, def in pairs(filtered_inv_buttons) do - - if draw_lite_mode and i > 4 then + if style.is_lite_mode and i > 4 then button_row = 1 button_col = 1 end if def.type == "image" then + local pos_x = style.main_button_x + style.btn_spc * (i - 1) - button_col * style.btn_spc * 4 + local pos_y = style.main_button_y + button_row * style.btn_spc if (def.condition == nil or def.condition(player) == true) then formspec[n] = string.format("image_button[%f,%f;%f,%f;%s;%s;]", - ui_peruser.main_button_x + ui_peruser.btn_spc * (i - 1) - button_col * ui_peruser.btn_spc * 4, - ui_peruser.main_button_y + button_row * ui_peruser.btn_spc, - ui_peruser.btn_size,ui_peruser.btn_size, + pos_x, pos_y, style.btn_size, style.btn_size, F(def.image), F(def.name)) formspec[n+1] = "tooltip["..F(def.name)..";"..(def.tooltip or "").."]" n = n+2 else formspec[n] = string.format("image[%f,%f;%f,%f;%s^[colorize:#808080:alpha]", - ui_peruser.main_button_x + ui_peruser.btn_spc * (i - 1) - button_col * ui_peruser.btn_spc * 4, - ui_peruser.main_button_y + button_row * ui_peruser.btn_spc, - ui_peruser.btn_size,ui_peruser.btn_size,def.image) + pos_x, pos_y, style.btn_size, style.btn_size, + def.image) n = n+1 end end end +end - if fsdata.draw_inventory ~= false then - -- Player inventory - formspec[n] = "listcolors[#00000000;#00000000]" - formspec[n+1] = ui_peruser.standard_inv - n = n+2 - end +local function formspec_add_categories(player, formspec, ui_peruser) + local player_name = player:get_player_name() + local n = #formspec + 1 - if fsdata.draw_item_list == false then - return table.concat(formspec, "") - end - - -- Category filters - - local categories_pos = { ui_peruser.page_x, ui_peruser.page_y-ui_peruser.btn_spc-0.5 } - local categories_scroll_pos = { ui_peruser.page_x, ui_peruser.form_header_y-(draw_lite_mode and 0 or 0.2) } + local categories_pos = { + ui_peruser.page_x, + ui_peruser.page_y-ui_peruser.btn_spc-0.5 + } + local categories_scroll_pos = { + ui_peruser.page_x, + ui_peruser.form_header_y - (ui_peruser.is_lite_mode and 0 or 0.2) + } formspec[n] = string.format("background9[%f,%f;%f,%f;%s;false;3]", ui_peruser.page_x-0.1, categories_scroll_pos[2], - (ui_peruser.btn_spc * ui_peruser.pagecols) + 0.13, 1.4+(draw_lite_mode and 0 or 0.2), + (ui_peruser.btn_spc * ui_peruser.pagecols) + 0.13, 1.4 + (ui_peruser.is_lite_mode and 0 or 0.2), "ui_smallbg_9_sliced.png") n = n + 1 - formspec[n] = string.format("label[%f,%f;%s]", ui_peruser.page_x, ui_peruser.form_header_y+(draw_lite_mode and 0.3 or 0.2), "Category:") + formspec[n] = string.format("label[%f,%f;%s]", + ui_peruser.page_x, + ui_peruser.form_header_y + (ui_peruser.is_lite_mode and 0.3 or 0.2), F(S("Category:"))) n = n + 1 local scroll_offset = 0 - local category_count = #unified_inventory.category_list + local category_count = #ui.category_list if category_count > ui_peruser.pagecols then - scroll_offset = unified_inventory.current_category_scroll[player_name] + scroll_offset = ui.current_category_scroll[player_name] end - for index, category in ipairs(unified_inventory.category_list) do + for index, category in ipairs(ui.category_list) do local column = index - scroll_offset if column > 0 and column <= ui_peruser.pagecols then local scale = 0.8 - if unified_inventory.current_category[player_name] == category.name then + if ui.current_category[player_name] == category.name then scale = 1 end formspec[n] = formspec_button(ui_peruser, "category_"..category.name, category.symbol, categories_pos, {column-1, 0}, scale, category.label) @@ -162,10 +133,13 @@ function ui.get_formspec(player, page) if category_count > ui_peruser.pagecols and category_count - scroll_offset > ui_peruser.pagecols then -- next formspec[n] = formspec_button(ui_peruser, "next_category", "ui_right_icon.png", categories_scroll_pos, {ui_peruser.pagecols - 1, 0}, 0.8, S("Scroll categories right")) - n = n + 1 end +end + +local function formspec_add_search_box(player, formspec, ui_peruser) + local player_name = player:get_player_name() + local n = #formspec + 1 - -- Search box formspec[n] = "field_close_on_enter[searchbox;false]" formspec[n+1] = string.format("field[%f,%f;%f,%f;searchbox;;%s]", @@ -182,7 +156,16 @@ function ui.get_formspec(player, page) ui_peruser.btn_size, ui_peruser.btn_size) formspec[n+5] = "tooltip[searchresetbutton;"..F(S("Reset search and display everything")).."]" - n = n + 6 + if ui.activefilter[player_name] ~= "" then + formspec[n+6] = string.format("label[%f,%f;%s: %s]", + ui_peruser.page_x, ui_peruser.page_y - 0.25, + F(S("Filter")), F(ui.activefilter[player_name])) + end +end + +local function formspec_add_item_browser(player, formspec, ui_peruser) + local player_name = player:get_player_name() + local n = #formspec + 1 -- Controls to flip items pages @@ -195,9 +178,9 @@ function ui.get_formspec(player, page) { "ui_skip_forward_icon.png", "end_list", S("Last page") }, } - if draw_lite_mode then - btnlist[5] = nil + if ui_peruser.is_lite_mode then btnlist[2] = nil + btnlist[5] = nil end local bn = 0 @@ -212,69 +195,109 @@ function ui.get_formspec(player, page) n = n + 2 end - local no_matches = S("No matching items") - if draw_lite_mode then - no_matches = S("No matches.") - end - -- Items list if #ui.filtered_items_list[player_name] == 0 then - formspec[n] = "label["..ui_peruser.page_x..","..(ui_peruser.page_y+0.15)..";" .. F(no_matches) .. "]" - else - local dir = ui.active_search_direction[player_name] - local list_index = ui.current_index[player_name] - local page2 = math.floor(list_index / (ui_peruser.items_per_page) + 1) - local pagemax = math.floor( - (#ui.filtered_items_list[player_name] - 1) - / (ui_peruser.items_per_page) + 1) - for y = 0, ui_peruser.pagerows - 1 do - for x = 0, ui_peruser.pagecols - 1 do - local name = ui.filtered_items_list[player_name][list_index] - local item = minetest.registered_items[name] - if item then - -- Clicked on current item: Flip crafting direction - if name == ui.current_item[player_name] then - local cdir = ui.current_craft_direction[player_name] - if cdir == "recipe" then - dir = "usage" - elseif cdir == "usage" then - dir = "recipe" - end - else - -- Default: use active search direction by default - dir = ui.active_search_direction[player_name] - end + local no_matches = S("No matching items") + if ui_peruser.is_lite_mode then + no_matches = S("No matches.") + end - local button_name = "item_button_" .. dir .. "_" - .. ui.mangle_for_formspec(name) - formspec[n] = ("item_image_button[%f,%f;%f,%f;%s;%s;]"):format( - ui_peruser.page_x + x * ui_peruser.btn_spc, - ui_peruser.page_y + y * ui_peruser.btn_spc, - ui_peruser.btn_size, ui_peruser.btn_size, - name, button_name - ) - formspec[n + 1] = ("tooltip[%s;%s \\[%s\\]]"):format( - button_name, minetest.formspec_escape(item.description), - item.mod_origin or "??" - ) - n = n + 2 - list_index = list_index + 1 + formspec[n] = "label["..ui_peruser.page_x..","..(ui_peruser.page_y+0.15)..";" .. F(no_matches) .. "]" + return + end + + local dir = ui.active_search_direction[player_name] + local list_index = ui.current_index[player_name] + local page2 = math.floor(list_index / (ui_peruser.items_per_page) + 1) + local pagemax = math.floor( + (#ui.filtered_items_list[player_name] - 1) + / (ui_peruser.items_per_page) + 1) + for y = 0, ui_peruser.pagerows - 1 do + for x = 0, ui_peruser.pagecols - 1 do + local name = ui.filtered_items_list[player_name][list_index] + local item = minetest.registered_items[name] + if item then + -- Clicked on current item: Flip crafting direction + if name == ui.current_item[player_name] then + local cdir = ui.current_craft_direction[player_name] + if cdir == "recipe" then + dir = "usage" + elseif cdir == "usage" then + dir = "recipe" + end + else + -- Default: use active search direction by default + dir = ui.active_search_direction[player_name] end + + local button_name = "item_button_" .. dir .. "_" + .. ui.mangle_for_formspec(name) + formspec[n] = ("item_image_button[%f,%f;%f,%f;%s;%s;]"):format( + ui_peruser.page_x + x * ui_peruser.btn_spc, + ui_peruser.page_y + y * ui_peruser.btn_spc, + ui_peruser.btn_size, ui_peruser.btn_size, + name, button_name + ) + formspec[n + 1] = ("tooltip[%s;%s \\[%s\\]]"):format( + button_name, minetest.formspec_escape(item.description), + item.mod_origin or "??" + ) + n = n + 2 + list_index = list_index + 1 end end - formspec[n] = string.format("label[%f,%f;%s: %s]", - ui_peruser.page_buttons_x + ui_peruser.btn_spc * (draw_lite_mode and 1 or 2), - ui_peruser.page_buttons_y + 0.1 + ui_peruser.btn_spc * 2, - F(S("Page")), S("@1 of @2",page2,pagemax)) end - n= n+1 + formspec[n] = string.format("label[%f,%f;%s: %s]", + ui_peruser.page_buttons_x + ui_peruser.btn_spc * (ui_peruser.is_lite_mode and 1 or 2), + ui_peruser.page_buttons_y + 0.1 + ui_peruser.btn_spc * 2, + F(S("Page")), S("@1 of @2",page2,pagemax)) +end - if ui.activefilter[player_name] ~= "" then - formspec[n] = string.format("label[%f,%f;%s: %s]", - ui_peruser.page_x, ui_peruser.page_y - 0.25, - F(S("Filter")), F(ui.activefilter[player_name])) +function ui.get_formspec(player, page) + + if not player then + return "" end - return table.concat(formspec, "") + + local player_name = player:get_player_name() + local ui_peruser = ui.get_per_player_formspec(player_name) + + ui.current_page[player_name] = page + local pagedef = ui.pages[page] + + if not pagedef then + return "" -- Invalid page name + end + + local fs = { + "formspec_version[4]", + "size["..ui_peruser.formw..","..ui_peruser.formh.."]", + pagedef.formspec_prepend and "" or "no_prepend[]", + ui.standard_background + } + + local perplayer_formspec = ui.get_per_player_formspec(player_name) + local fsdata = pagedef.get_formspec(player, perplayer_formspec) + + fs[#fs + 1] = fsdata.formspec + + formspec_add_filters(player, fs, ui_peruser) + + if fsdata.draw_inventory ~= false then + -- Player inventory + fs[#fs + 1] = "listcolors[#00000000;#00000000]" + fs[#fs + 1] = ui_peruser.standard_inv + end + + if fsdata.draw_item_list == false then + return table.concat(fs, "") + end + + formspec_add_categories(player, fs, ui_peruser) + formspec_add_search_box(player, fs, ui_peruser) + formspec_add_item_browser(player, fs, ui_peruser) + + return table.concat(fs) end function ui.set_inventory_formspec(player, page) @@ -355,60 +378,3 @@ function ui.apply_filter(player, filter, search_dir) ui.set_inventory_formspec(player, ui.current_page[player_name]) end - -function ui.items_in_group(groups) - local items = {} - for name, item in pairs(minetest.registered_items) do - for _, group in pairs(groups:split(',')) do - if item.groups[group] then - table.insert(items, name) - end - end - end - return items -end - -function ui.sort_inventory(inv) - local inlist = inv:get_list("main") - local typecnt = {} - local typekeys = {} - for _, st in ipairs(inlist) do - if not st:is_empty() then - local n = st:get_name() - local w = st:get_wear() - local m = st:get_metadata() - local k = string.format("%s %05d %s", n, w, m) - if not typecnt[k] then - typecnt[k] = { - name = n, - wear = w, - metadata = m, - stack_max = st:get_stack_max(), - count = 0, - } - table.insert(typekeys, k) - end - typecnt[k].count = typecnt[k].count + st:get_count() - end - end - table.sort(typekeys) - local outlist = {} - for _, k in ipairs(typekeys) do - local tc = typecnt[k] - while tc.count > 0 do - local c = math.min(tc.count, tc.stack_max) - table.insert(outlist, ItemStack({ - name = tc.name, - wear = tc.wear, - metadata = tc.metadata, - count = c, - })) - tc.count = tc.count - c - end - end - if #outlist > #inlist then return end - while #outlist < #inlist do - table.insert(outlist, ItemStack(nil)) - end - inv:set_list("main", outlist) -end