From f1229c5401494b7d809817fa43e4d25076451341 Mon Sep 17 00:00:00 2001 From: talamh Date: Sun, 2 May 2021 01:58:40 +0000 Subject: [PATCH 001/296] Added spawn egg for killer rabbitt --- .../mobs_mc_spawn_icon_rabbit_caerbannog.png | Bin 0 -> 1897 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_rabbit_caerbannog.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_rabbit_caerbannog.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_rabbit_caerbannog.png new file mode 100644 index 0000000000000000000000000000000000000000..4244a83c6f0a93ff1f7d65180fd6d56b43e98af3 GIT binary patch literal 1897 zcmV-v2bTDWP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+O1YulI182{O1&N1WN)Wj>8%;H<;s3VuS0|@?KYW zmmM}(W=UmAvR(i0-{Jnj!5qBvK`o{j4;()E#2Fnst|Om!I{bNG56AAjv%C8R!z5_s zdbGIg9d^ceUiP}y$*_lqg;HNH%KI02EyT7q*gLL`gsu&awXn-;A>p;Nzn;tG))ABG zqYHJ7AM5=|11>jjUX){qq#k$AhiXjd8y{Z5Tbn>d&;9R>K0doWl!1x6kQ}(%L@4tj z$!NoQXN;M)EV3+%3aG{IQ1sL0_4V-zx!cf}BD1U*2UO;c{F~ZCB17#+Av|IV<8+T;Z@u_B<0# zLrPT0*$`v}XQf0883%c4lxa{u+e#G>J$F{L%oXBR2ctoZ#1(Rq_<7P`l_X6JVpoKN zz{)okI=4;dc9jepH!_FlAS_0h@>i$(&Y&@7LJ=Kya|K*HBO55DazySR41*#x7OCMR zc%L7SsjEQ2aMEmWFdt>E0QpOxx8RafXu-gM_R1sDwiW#G=JYD!H<&Qhg0IR;^Z3&5fHhx|g6?PQug-im@jMu2TUL$2>JVjJ)Tm z+|=wyJc}R$WSHVKnu?=QtWgX4k#5C0k&@74l-_&0nZM zRQI^rPS^%yVYyRXk>0&FnxL&&4|}Qy>|;&%M(f@gq=T{5_4$b}k9f+$Q^fUg6gfFW zwnkcjn(r*hu3^nfr|$=3&&w&UqcpzM%N~COS(kRf29#~Q5b+2nBlzMqa#wEwL6vJu zVOnjpH5$}!kABV3%@vBpcD{GJweaa8&Lki4GFFpb^0iQDDnknAwvg&Gp4;Au#saK$ zVRvs%JZob+HwYC`f`Yv^%X+@Xe@ySw=uRtWJO_kc(nu|(a&K7EHNmR(bT6(=*FuFA z)h?R*NagX8(x*|^U1*EeEPd=GfD?Mjr#XWL{Qch$%Y_QXTw6&y?#y+B!{VT8uKx1G zr}D|)J2Jk={o|7Vc}|~F@duZ6QWxPwxUB)L%JgzDt?zz{YW5HG@r4cmQA9RD<3UIBDK7$1w-QnX|n=&!S6J#FSNeT0%D6YqIUEif*S>-oYH>emR5}^Fkwg@_oh35b$_S93CGmdz$@Es=#J; zeN9ja714I3q6@tu+)BDBeyF5T)-tFLe)~f-Vq8coja2Q-F895(dJZ}6uSk_y2F|BM z2ufQ4noTQziPQIMt^tazs0rq%XIq2V_qc*JAdmcS!E-OmM6aK8ekfIob4^iObE(#y zUHC(`UzN+Jt^3o7f4Y$32Qj(-0gvB171uc!#sB~S24YJ`L;%PDS^!tH0(VpZ000Sa zNLh0L01FcU01FcV0GgZ_00007bV*G`2jv9<0V4$`wT`m@000?uMObu0Z*6U5Zgc=c za%Ew3Wn>_CX>@2HM@dakSAh-}0004CNklbF5XOHoK`b;JVIM$K99Z8z zgPq_DXerpKg^gMWSBOs`_yF2S;;Kp&{r>lkCK@B4V3=Z)r$1%5iFTC>(}10W(?Yt0g{KT~|LB0{1RiBgp!Ypopv*h^Cyz`N@%B3xU*m=o zt`rm4%`%KJzZ1nVec%Xe6THe6MC2Pa2#BJHEhpZv%>xfW)2*`v&{}%{_i;?3R4HDb z=M{hjU}YMGL~8(+ouB79BEnr9^9gJkL&Mt2MOG*rgJ*!3k+ECA8*mx~W9K~f7fu|v j9Vl0|3LH#0`#-TSNF9Mg)SuCN00000NkvXXu0mjfBRps$ literal 0 HcmV?d00001 From e6b61a1551948352bf7e3dce3f59f7238a5d413e Mon Sep 17 00:00:00 2001 From: talamh Date: Sun, 2 May 2021 02:00:21 +0000 Subject: [PATCH 002/296] Update 'mods/ENTITIES/mobs_mc/rabbit.lua' --- mods/ENTITIES/mobs_mc/rabbit.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ENTITIES/mobs_mc/rabbit.lua b/mods/ENTITIES/mobs_mc/rabbit.lua index 90d5c27bf..2a9521ecb 100644 --- a/mods/ENTITIES/mobs_mc/rabbit.lua +++ b/mods/ENTITIES/mobs_mc/rabbit.lua @@ -233,4 +233,4 @@ mobs:spawn(spawn_grass) mobs:register_egg("mobs_mc:rabbit", S("Rabbit"), "mobs_mc_spawn_icon_rabbit.png", 0) -- Note: This spawn egg does not exist in Minecraft -mobs:register_egg("mobs_mc:killer_bunny", S("Killer Bunny"), "mobs_mc_spawn_icon_rabbit.png^[colorize:#FF0000:192", 0) -- TODO: Update inventory image +mobs:register_egg("mobs_mc:killer_bunny", S("Killer Bunny"), "mobs_mc_spawn_icon_rabbit_caerbannog.png", 0) From e9f38c6b90ea33234a75a1a95dc03b94c760f602 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Sat, 22 May 2021 10:47:28 +0200 Subject: [PATCH 003/296] WIP raycast base buckets --- mods/ITEMS/mcl_buckets/init.lua | 320 +++++++++++++++++++++----------- 1 file changed, 211 insertions(+), 109 deletions(-) diff --git a/mods/ITEMS/mcl_buckets/init.lua b/mods/ITEMS/mcl_buckets/init.lua index 7e67eee8e..3103aeb4f 100644 --- a/mods/ITEMS/mcl_buckets/init.lua +++ b/mods/ITEMS/mcl_buckets/init.lua @@ -44,129 +44,166 @@ local place_liquid = function(pos, itemstring) sound_place(itemstring, pos) minetest.add_node(pos, {name=itemstring, param2=fullness}) end +local function give_bucket(new_bucket, itemstack, user) + if itemstack:get_count() == 1 then + return new_bucket + else + local inv = user:get_inventory() + if inv:room_for_item("main", new_bucket) then + inv:add_item("main", new_bucket) + else + minetest.add_item(user:get_pos(), new_bucket) + end + if not minetest.is_creative_enabled(user:get_player_name()) then + itemstack:take_item() + end + return itemstack + end +end + +local function bucket_raycast(user) + local pos = user:get_pos() + pos.y = pos.y + user:get_properties().eye_height + local look_dir = user:get_look_dir() + look_dir = vector.multiply(look_dir, 6) + local pos2 = vector.add(pos, look_dir) + + local ray = raycast(pos, pos2, false, true) + if ray then + for pointed_thing in ray do + if pointed_thing and get_node_group(get_node(pointed_thing.above).name, "_mcl_bucket_pointable") == 1 then + --minetest.chat_send_all("found!") + return {under=pointed_thing.under,above=pointed_thing.above} + end + end + end + return nil +end function mcl_buckets.register_liquid(def) - for i=1, #def.source_take do - mcl_buckets.liquids[def.source_take[i]] = { + for _,source in ipairs(def.source_take) do + mcl_buckets.liquids[source] = { source_place = def.source_place, - source_take = def.source_take[i], + source_take = source, on_take = def.on_take, itemname = def.itemname, } if type(def.source_place) == "string" then - mcl_buckets.liquids[def.source_place] = mcl_buckets.liquids[def.source_take[i]] + mcl_buckets.liquids[def.source_place] = mcl_buckets.liquids[source] end end - if def.itemname ~= nil then - minetest.register_craftitem(def.itemname, { - description = def.name, - _doc_items_longdesc = def.longdesc, - _doc_items_usagehelp = def.usagehelp, - _tt_help = def.tt_help, - inventory_image = def.inventory_image, - stack_max = 1, - groups = def.groups, - on_place = function(itemstack, user, pointed_thing) - -- Must be pointing to node - if pointed_thing.type ~= "node" then - return - end + if def.itemname == nil or def.itemname == "" then + error(string.format("[mcl_bucket] Invalid itemname then registering [%s]!", def.name)) + end - local node = minetest.get_node(pointed_thing.under) - local place_pos = pointed_thing.under - local nn = node.name - -- Call on_rightclick if the pointed node defines it - if user and not user:get_player_control().sneak then - if minetest.registered_nodes[nn] and minetest.registered_nodes[nn].on_rightclick then - return minetest.registered_nodes[nn].on_rightclick(place_pos, node, user, itemstack) or itemstack - end - end + minetest.register_craftitem(def.itemname, { + description = def.name, + _doc_items_longdesc = def.longdesc, + _doc_items_usagehelp = def.usagehelp, + _tt_help = def.tt_help, + inventory_image = def.inventory_image, + stack_max = 1, + groups = def.groups, + on_place = function(itemstack, user, pointed_thing) + -- Must be pointing to node + if pointed_thing.type ~= "node" then + return + end - local node_place - if type(def.source_place) == "function" then - node_place = def.source_place(place_pos) - else - node_place = def.source_place + local node = minetest.get_node(pointed_thing.under) + local place_pos = pointed_thing.under + local nn = node.name + -- Call on_rightclick if the pointed node defines it + if user and not user:get_player_control().sneak then + if minetest.registered_nodes[nn] and minetest.registered_nodes[nn].on_rightclick then + return minetest.registered_nodes[nn].on_rightclick(place_pos, node, user, itemstack) or itemstack end - -- Check if pointing to a buildable node - local item = itemstack:get_name() + end - if def.extra_check and def.extra_check(place_pos, user) == false then - -- Fail placement of liquid - elseif minetest.registered_nodes[nn] and minetest.registered_nodes[nn].buildable_to then - -- buildable; replace the node - local pns = user:get_player_name() - if minetest.is_protected(place_pos, pns) then - minetest.record_protection_violation(place_pos, pns) + local node_place + if type(def.source_place) == "function" then + node_place = def.source_place(place_pos) + else + node_place = def.source_place + end + -- Check if pointing to a buildable node + local item = itemstack:get_name() + + if def.extra_check and def.extra_check(place_pos, user) == false then + -- Fail placement of liquid + elseif minetest.registered_nodes[nn] and minetest.registered_nodes[nn].buildable_to then + -- buildable; replace the node + local pns = user:get_player_name() + if minetest.is_protected(place_pos, pns) then + minetest.record_protection_violation(place_pos, pns) + return itemstack + end + place_liquid(place_pos, node_place) + if mod_doc and doc.entry_exists("nodes", node_place) then + doc.mark_entry_as_revealed(user:get_player_name(), "nodes", node_place) + end + else + -- not buildable to; place the liquid above + -- check if the node above can be replaced + local abovenode = minetest.get_node(pointed_thing.above) + if minetest.registered_nodes[abovenode.name] and minetest.registered_nodes[abovenode.name].buildable_to then + local pn = user:get_player_name() + if minetest.is_protected(pointed_thing.above, pn) then + minetest.record_protection_violation(pointed_thing.above, pn) return itemstack end - place_liquid(place_pos, node_place) + place_liquid(pointed_thing.above, node_place) if mod_doc and doc.entry_exists("nodes", node_place) then doc.mark_entry_as_revealed(user:get_player_name(), "nodes", node_place) end else - -- not buildable to; place the liquid above - -- check if the node above can be replaced - local abovenode = minetest.get_node(pointed_thing.above) - if minetest.registered_nodes[abovenode.name] and minetest.registered_nodes[abovenode.name].buildable_to then - local pn = user:get_player_name() - if minetest.is_protected(pointed_thing.above, pn) then - minetest.record_protection_violation(pointed_thing.above, pn) - return itemstack - end - place_liquid(pointed_thing.above, node_place) - if mod_doc and doc.entry_exists("nodes", node_place) then - doc.mark_entry_as_revealed(user:get_player_name(), "nodes", node_place) - end - else - -- do not remove the bucket with the liquid - return - end - end - - -- Handle bucket item and inventory stuff - if not minetest.is_creative_enabled(user:get_player_name()) then - -- Add empty bucket and put it into inventory, if possible. - -- Drop empty bucket otherwise. - local new_bucket = ItemStack("mcl_buckets:bucket_empty") - if itemstack:get_count() == 1 then - return new_bucket - else - local inv = user:get_inventory() - if inv:room_for_item("main", new_bucket) then - inv:add_item("main", new_bucket) - else - minetest.add_item(user:get_pos(), new_bucket) - end - itemstack:take_item() - return itemstack - end - else + -- do not remove the bucket with the liquid return end - end, - _on_dispense = function(stack, pos, droppos, dropnode, dropdir) - local iname = stack:get_name() - local buildable = minetest.registered_nodes[dropnode.name].buildable_to or dropnode.name == "mcl_portals:portal" + end - if def.extra_check and def.extra_check(droppos, nil) == false then - -- Fail placement of liquid - elseif buildable then - -- buildable; replace the node - local node_place - if type(def.source_place) == "function" then - node_place = def.source_place(droppos) + -- Handle bucket item and inventory stuff + if not minetest.is_creative_enabled(user:get_player_name()) then + -- Add empty bucket and put it into inventory, if possible. + -- Drop empty bucket otherwise. + local new_bucket = ItemStack("mcl_buckets:bucket_empty") + if itemstack:get_count() == 1 then + return new_bucket + else + local inv = user:get_inventory() + if inv:room_for_item("main", new_bucket) then + inv:add_item("main", new_bucket) else - node_place = def.source_place + minetest.add_item(user:get_pos(), new_bucket) end - place_liquid(droppos, node_place) - stack:set_name("mcl_buckets:bucket_empty") + itemstack:take_item() + return itemstack end - return stack - end, - }) - end + else + return + end + end, + _on_dispense = function(stack, pos, droppos, dropnode, dropdir) + local iname = stack:get_name() + local buildable = minetest.registered_nodes[dropnode.name].buildable_to or dropnode.name == "mcl_portals:portal" + + if def.extra_check and def.extra_check(droppos, nil) == false then + -- Fail placement of liquid + elseif buildable then + -- buildable; replace the node + local node_place + if type(def.source_place) == "function" then + node_place = def.source_place(droppos) + else + node_place = def.source_place + end + place_liquid(droppos, node_place) + stack:set_name("mcl_buckets:bucket_empty") + end + return stack + end, + }) end minetest.register_craftitem("mcl_buckets:bucket_empty", { @@ -174,26 +211,25 @@ minetest.register_craftitem("mcl_buckets:bucket_empty", { _doc_items_longdesc = S("A bucket can be used to collect and release liquids."), _doc_items_usagehelp = S("Punch a liquid source to collect it. You can then use the filled bucket to place the liquid somewhere else."), _tt_help = S("Collects liquids"), - - liquids_pointable = true, + --liquids_pointable = true, inventory_image = "bucket.png", stack_max = 16, on_place = function(itemstack, user, pointed_thing) - -- Must be pointing to node + --[[-- Must be pointing to node if pointed_thing.type ~= "node" then return itemstack end -- Call on_rightclick if the pointed node defines it - local node = minetest.get_node(pointed_thing.under) - local nn = node.name - if user and not user:get_player_control().sneak then - if minetest.registered_nodes[nn] and minetest.registered_nodes[nn].on_rightclick then - return minetest.registered_nodes[nn].on_rightclick(pointed_thing.under, node, user, itemstack) or itemstack - end - end + + + local pointed_liquid = bucket_raycast(user) -- Can't steal liquids + if minetest.is_protected(pointed_liquid.above, user:get_player_name()) then + minetest.record_protection_violation(pointed_liquid.under, user:get_player_name()) + return itemstack + end if minetest.is_protected(pointed_thing.above, user:get_player_name()) then minetest.record_protection_violation(pointed_thing.under, user:get_player_name()) return itemstack @@ -208,8 +244,8 @@ minetest.register_craftitem("mcl_buckets:bucket_empty", { if not minetest.is_creative_enabled(user:get_player_name()) then new_bucket = ItemStack({name = liquiddef.itemname}) if liquiddef.on_take then - liquiddef.on_take(user) - end + liquiddef.on_take(user) + end end minetest.add_node(pointed_thing.under, {name="air"}) @@ -252,7 +288,73 @@ minetest.register_craftitem("mcl_buckets:bucket_empty", { end return itemstack end + end]] + if pointed_thing.type ~= "node" then + return itemstack end + local node = minetest.get_node(pointed_thing.under) + local nn = node.name + if user and not user:get_player_control().sneak then + if minetest.registered_nodes[nn] and minetest.registered_nodes[nn].on_rightclick then + return minetest.registered_nodes[nn].on_rightclick(pointed_thing.under, node, user, itemstack) or itemstack + end + end + + local liquid_node = bucket_raycast(user) + if liquid_node then + if minetest.is_protected(liquid_node.above, user:get_player_name()) then + minetest.record_protection_violation(liquid_node.above, user:get_player_name()) + end + local liquid_name = get_node(liquid_node.above).name + if liquid_name then + local liquid_def = mcl_buckets.liquids[liquid_name] + if liquid_def then + local new_bucket + --minetest.chat_send_all("test") + -- Fill bucket, but not in Creative Mode + -- FIXME: remove this line + --if not minetest.is_creative_enabled(user:get_player_name()) then + if not false then + new_bucket = ItemStack({name = liquid_def.itemname}) + if liquid_def.on_take then + liquid_def.on_take(user) + end + end + add_node(liquid_node.above, {name="air"}) + sound_take(nn, liquid_node.above) + + if mod_doc and doc.entry_exists("nodes", liquid_name) then + doc.mark_entry_as_revealed(user:get_player_name(), "nodes", liquid_name) + end + if new_bucket then + return give_bucket(new_bucket, itemstack, user) + end + else + minetest.log("error", string.format("[mcl_buckets] Node [%s] has invalid group [_mcl_bucket_pointable]!", liquid_name)) + end + end + return itemstack + else + -- FIXME: replace this ugly code by cauldrons API + if nn == "mcl_cauldrons:cauldron_3" then + -- Take water out of full cauldron + minetest.set_node(pointed_thing.under, {name="mcl_cauldrons:cauldron"}) + if not minetest.is_creative_enabled(user:get_player_name()) then + new_bucket = ItemStack("mcl_buckets:bucket_water") + end + sound_take("mcl_core:water_source", pointed_thing.under) + elseif nn == "mcl_cauldrons:cauldron_3r" then + -- Take river water out of full cauldron + minetest.set_node(pointed_thing.under, {name="mcl_cauldrons:cauldron"}) + if not minetest.is_creative_enabled(user:get_player_name()) then + new_bucket = ItemStack("mcl_buckets:bucket_river_water") + end + sound_take("mclx_core:river_water_source", pointed_thing.under) + end + if new_bucket then + return give_bucket(new_bucket, itemstack, user) + end + end end, _on_dispense = function(stack, pos, droppos, dropnode, dropdir) -- Fill empty bucket with liquid or drop bucket if no liquid From 5d65c8a3aa58da596befac454eae5ed205e2e510 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Sat, 22 May 2021 18:57:51 +0200 Subject: [PATCH 004/296] Working empty bucket --- mods/ITEMS/mcl_buckets/init.lua | 6 ++++++ mods/ITEMS/mcl_core/nodes_liquid.lua | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/mods/ITEMS/mcl_buckets/init.lua b/mods/ITEMS/mcl_buckets/init.lua index 3103aeb4f..327d553c8 100644 --- a/mods/ITEMS/mcl_buckets/init.lua +++ b/mods/ITEMS/mcl_buckets/init.lua @@ -11,6 +11,11 @@ local mod_doc = minetest.get_modpath("doc") local mod_mcl_core = minetest.get_modpath("mcl_core") local mod_mclx_core = minetest.get_modpath("mclx_core") +local raycast = minetest.raycast +local get_node = minetest.get_node +local add_node = minetest.add_node +local get_node_group = minetest.get_node_group + if mod_mcl_core then minetest.register_craft({ output = 'mcl_buckets:bucket_empty 1', @@ -355,6 +360,7 @@ minetest.register_craftitem("mcl_buckets:bucket_empty", { return give_bucket(new_bucket, itemstack, user) end end + return itemstack end, _on_dispense = function(stack, pos, droppos, dropnode, dropdir) -- Fill empty bucket with liquid or drop bucket if no liquid diff --git a/mods/ITEMS/mcl_core/nodes_liquid.lua b/mods/ITEMS/mcl_core/nodes_liquid.lua index c49b685eb..47c22c7c6 100644 --- a/mods/ITEMS/mcl_core/nodes_liquid.lua +++ b/mods/ITEMS/mcl_core/nodes_liquid.lua @@ -100,7 +100,7 @@ S("• When water is directly below lava, the water turns into stone."), liquid_range = 7, post_effect_color = {a=209, r=0x03, g=0x3C, b=0x5C}, stack_max = 64, - groups = { water=3, liquid=3, puts_out_fire=1, freezes=1, not_in_creative_inventory=1, dig_by_piston=1}, + groups = { water=3, liquid=3, puts_out_fire=1, freezes=1, not_in_creative_inventory=1, dig_by_piston=1, _mcl_bucket_pointable=1}, _mcl_blast_resistance = 100, -- Hardness intentionally set to infinite instead of 100 (Minecraft value) to avoid problems in creative mode _mcl_hardness = -1, @@ -203,7 +203,7 @@ S("• When lava is directly above water, the water turns into stone."), _mcl_node_death_message = lava_death_messages, post_effect_color = {a=245, r=208, g=73, b=10}, stack_max = 64, - groups = { lava=3, lava_source=1, liquid=2, destroys_items=1, not_in_creative_inventory=1, dig_by_piston=1, set_on_fire=15, fire_damage=1}, + groups = { lava=3, lava_source=1, liquid=2, destroys_items=1, not_in_creative_inventory=1, dig_by_piston=1, set_on_fire=15, fire_damage=1, _mcl_bucket_pointable=1}, _mcl_blast_resistance = 100, -- Hardness intentionally set to infinite instead of 100 (Minecraft value) to avoid problems in creative mode _mcl_hardness = -1, From 17202115fa2e99fb825dcaf53c73bbaf9a47cb82 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Sat, 22 May 2021 18:58:58 +0200 Subject: [PATCH 005/296] cache general functions --- mods/ITEMS/mcl_buckets/init.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mods/ITEMS/mcl_buckets/init.lua b/mods/ITEMS/mcl_buckets/init.lua index 327d553c8..7f5ab2b16 100644 --- a/mods/ITEMS/mcl_buckets/init.lua +++ b/mods/ITEMS/mcl_buckets/init.lua @@ -11,6 +11,10 @@ local mod_doc = minetest.get_modpath("doc") local mod_mcl_core = minetest.get_modpath("mcl_core") local mod_mclx_core = minetest.get_modpath("mclx_core") +local vector = vector +local math = math +local string = string + local raycast = minetest.raycast local get_node = minetest.get_node local add_node = minetest.add_node From a65db15b5caf92e1e18c07880ea62b8ff5ce61ff Mon Sep 17 00:00:00 2001 From: NO11 Date: Sat, 29 May 2021 19:21:15 +0000 Subject: [PATCH 006/296] Totem particle textures --- .../textures/mcl_particles_totem1.png | Bin 0 -> 148 bytes .../textures/mcl_particles_totem2.png | Bin 0 -> 154 bytes .../textures/mcl_particles_totem3.png | Bin 0 -> 155 bytes .../textures/mcl_particles_totem4.png | Bin 0 -> 165 bytes 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 mods/CORE/mcl_particles/textures/mcl_particles_totem1.png create mode 100644 mods/CORE/mcl_particles/textures/mcl_particles_totem2.png create mode 100644 mods/CORE/mcl_particles/textures/mcl_particles_totem3.png create mode 100644 mods/CORE/mcl_particles/textures/mcl_particles_totem4.png diff --git a/mods/CORE/mcl_particles/textures/mcl_particles_totem1.png b/mods/CORE/mcl_particles/textures/mcl_particles_totem1.png new file mode 100644 index 0000000000000000000000000000000000000000..15fe082e104d5d524ab2fa7b9af63c29c196756d GIT binary patch literal 148 zcmeAS@N?(olHy`uVBq!ia0y~yVBiE{4mJh`h6fYb1Q-|?*pj^6T^PXNr}OT5kaU4Z zWHAE+-(e7DJf6QIg@J*Ay~NYkmHjEJsF;#OCqL&81_lO2PZ!4!iOb0e3$znlp8fg% p|G#}q(?mhN<1Rg(K0M9*3=B?(SlHg|7mxs%?&<31vd$@?2>=a_CAk0q literal 0 HcmV?d00001 diff --git a/mods/CORE/mcl_particles/textures/mcl_particles_totem2.png b/mods/CORE/mcl_particles/textures/mcl_particles_totem2.png new file mode 100644 index 0000000000000000000000000000000000000000..2ab88983d5bc683b0c80841c53d820b10179f03b GIT binary patch literal 154 zcmeAS@N?(olHy`uVBq!ia0y~yVBiE{4mJh`h6fYb1Q-|?*pj^6T^PXNr}OT5kaU4Z zWHAE+-(e7DJf6QIg@J*Ay~NYkmHjEJsF;$n1ED%d@dG_c3 x|Nr(eO%o>yIty-MDrxmO5^>zc)I5-%fnoW79u9Av_rV}bJYD@<);T3K0RWENDmwrG literal 0 HcmV?d00001 diff --git a/mods/CORE/mcl_particles/textures/mcl_particles_totem4.png b/mods/CORE/mcl_particles/textures/mcl_particles_totem4.png new file mode 100644 index 0000000000000000000000000000000000000000..d6e6502b7fd0c0d1a68c8afdcea112d4693e07db GIT binary patch literal 165 zcmeAS@N?(olHy`uVBq!ia0y~yVBiE{4mJh`h6fYb1Q-|?*pj^6T^PXNr}OT5kaU4Z zWHAE+-(e7DJf6QIg@J*Ay~NYkmHjEJsF;#b(3S&w3=9lLo-U3d5|@(`6qpQ@ivRup z|6gA3;E59*3ppYgcR9Jma7_?35`3(tHc7_sf^SQWy9fh=F1HAmbMc|+AnQC`{an^L HB{Ts5&IT&{ literal 0 HcmV?d00001 From 75e263debca16802eabb977cbae1f1895dd32bc5 Mon Sep 17 00:00:00 2001 From: NO11 Date: Sat, 29 May 2021 19:24:16 +0000 Subject: [PATCH 007/296] Add code for totem partciles --- mods/ITEMS/mcl_totems/init.lua | 48 ++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/mods/ITEMS/mcl_totems/init.lua b/mods/ITEMS/mcl_totems/init.lua index 499d7362d..e64404c2c 100644 --- a/mods/ITEMS/mcl_totems/init.lua +++ b/mods/ITEMS/mcl_totems/init.lua @@ -4,6 +4,41 @@ minetest.register_on_leaveplayer(function(player) hud_totem[player] = nil end) +-- Totem particle registration +-- TODO: real MC colors, these are randomly selected colors: +local colors = {"#7FFF00", "#698B22", "#BCEE68", "#EEEE00", "#C5F007"} +for c, color in pairs(colors) do + local colorizing = ".png^[colorize:"..color + for n = 1, 4 do + minetest.register_entity("mcl_totems:totem_particle"..n.."_color"..c, { + physical = true, + collide_with_objects = false, + collisionbox = {-0.02,-0.02,-0.02, 0.02,0.02,0.02}, + pointable = false, + visual = "sprite", + visual_size = {x=0.2, y=0.2}, + textures = {"mcl_particles_totem"..n..colorizing}, + spritediv = {x=1, y=1}, + initial_sprite_basepos = {x=0, y=0}, + static_save = false, + glow = 5, + on_activate = function(self, staticdata) + self.object:set_velocity({x = math.random(-4, 4)*math.random(), y = math.random(-1, 4)*math.random(), z = math.random(-4, 4)*math.random()}) + minetest.after(0.3, function() + self.object:set_acceleration({x=0, y=-4, z=0}) + self.object:set_velocity({x=0, y=0, z=0}) + end) + end, + on_step = function(self, dtime) + local r = math.random(1,80) + if r == 1 then + self.object:remove() + end + end + }) + end +end + -- Save the player from death when holding totem of undying in hand mcl_damage.register_modifier(function(obj, damage, reason) if obj:is_player() then @@ -32,7 +67,16 @@ mcl_damage.register_modifier(function(obj, damage, reason) -- Effects minetest.sound_play({name = "mcl_totems_totem", gain=1}, {pos=ppos, max_hear_distance=16}, true) - -- Big totem overlay + --Particles + for i = 1, 200 do + local particle = "mcl_totems:totem_particle"..math.random(1, 4).."_color"..math.random(1, 5) + minetest.after(math.random(1, 2)*math.random(), function() + local new_pos = obj:get_pos() + minetest.add_entity({x=new_pos.x, y=new_pos.y + 1, z=new_pos.z}, particle) + end) + end + + -- Big totem overlay if not hud_totem[obj] then hud_totem[obj] = obj:hud_add({ hud_elem_type = "image", @@ -55,4 +99,4 @@ mcl_damage.register_modifier(function(obj, damage, reason) end end end -end, 1000) +end, 1000) \ No newline at end of file From 640b0dc4859014f15939cce0be36dd06c2b1419c Mon Sep 17 00:00:00 2001 From: AFCMS Date: Wed, 2 Jun 2021 00:23:11 +0200 Subject: [PATCH 008/296] basic title API working (testing needed) --- mods/HUD/mcl_title/init.lua | 161 ++++++++++++++++++++++++++++++++++++ mods/HUD/mcl_title/mod.conf | 4 + 2 files changed, 165 insertions(+) create mode 100644 mods/HUD/mcl_title/init.lua create mode 100644 mods/HUD/mcl_title/mod.conf diff --git a/mods/HUD/mcl_title/init.lua b/mods/HUD/mcl_title/init.lua new file mode 100644 index 000000000..9975ff840 --- /dev/null +++ b/mods/HUD/mcl_title/init.lua @@ -0,0 +1,161 @@ +--TODO: use SSCSM to reduce lag and network trafic (just send modchannel messages) +--TODO: exactly mc like layout + +local huds_idx = {} + +huds_idx.title = {} +huds_idx.subtitle = {} +huds_idx.actionbar = {} + +mcl_title = {} +mcl_title.defaults = {fadein = 10, stay = 70, fadeout = 20} +mcl_title.layout = {} +mcl_title.layout.title = {position = {x = 0.5, y = 0.5}, alignment = {x = 0, y = -1.3}, size = 5} +mcl_title.layout.subtitle = {position = {x = 0.5, y = 0.5}, alignment = {x = 0, y = 1.9}, size = 2} +mcl_title.layout.actionbar = {position = {x = 0.5, y = 1}, alignment = {x = 0, y = -15}, size = 1} + +local get_color = mcl_util.get_color + +local function gametick_to_secondes(gametick) + return gametick / 20 +end + + +--PARAMS SYSTEM +local player_params = {} + +minetest.register_on_joinplayer(function(player) + player_params[player] = { + stay = gametick_to_secondes(mcl_title.defaults.stay), + --fadeIn = gametick_to_secondes(mcl_title.defaults.fadein), + --fadeOut = gametick_to_secondes(mcl_title.defaults.fadeout), + } +end) + +minetest.register_on_leaveplayer(function(player) + player_params = nil +end) + +function mcl_title.params_set(player, data) + player_params[player] = { + stay = gametick_to_secondes(data.stay) or gametick_to_secondes(mcl_title.defaults.stay), + --fadeIn = gametick_to_secondes(data.fadeIn) or gametick_to_secondes(mcl_title.defaults.fadein), + --fadeOut = gametick_to_secondes(data.fadeOut) or gametick_to_secondes(mcl_title.defaults.fadeout), + } +end + +function mcl_title.params_get(player) + return player_params[player] +end + +--API FUNCTIONS + +function mcl_title.set(player, type, data) + if not data.color then + data.color = "white" + end + local _, hex_color = get_color(data.color) + if not hex_color then + return false + end + + if huds_idx[type][player] then + player:hud_remove(huds_idx[type][player]) + end + + --TODO: enable this code then Fleckenstein's pr get merged + --[[ + local bold + if data.bold == "true" then + bold = true + else + bold = false + end + + local italic + if data.italic == "true" then + italic = true + else + italic = false + end]] + + local stay = mcl_title.params_get(player).stay + + huds_idx[type][player] = player:hud_add({ + hud_elem_type = "text", + position = mcl_title.layout[type].position, + alignment = mcl_title.layout[type].alignment, + text = data.text, + --bold = bold, + --italic = italic, + size = {x = mcl_title.layout[type].size}, + number = hex_color, + z_index = 1100, + }) + + minetest.after(stay, function() + if huds_idx[type][player] then + player:hud_remove(huds_idx[type][player]) + end + huds_idx[type][player] = nil + end) + return true +end + +function mcl_title.remove(player, type) + if huds_idx[type][player] then + player:hud_remove(huds_idx[type][player]) + end + huds_idx[type][player] = nil +end + +function mcl_title.clear(player) + mcl_title.remove(player, "title") + mcl_title.remove(player, "subtitle") + mcl_title.remove(player, "actionbar") +end + +minetest.register_on_dieplayer(function(player) + mcl_title.clear(player) +end) + + +--TEMP STUFF!! +--TODO: remove then testing/tweaking done +minetest.register_chatcommand("title", { + func = function(name, param) + local player = minetest.get_player_by_name(name) + mcl_title.set(player, "title", {text=param, color="gold"}) + end, +}) + +minetest.register_chatcommand("subtitle", { + func = function(name, param) + local player = minetest.get_player_by_name(name) + mcl_title.set(player, "subtitle", {text=param, color="gold"}) + end, +}) + +minetest.register_chatcommand("actionbar", { + func = function(name, param) + local player = minetest.get_player_by_name(name) + mcl_title.set(player, "actionbar", {text=param, color="gold"}) + end, +}) + +minetest.register_chatcommand("timeout", { + func = function(name, param) + local player = minetest.get_player_by_name(name) + mcl_title.params_set(player, {stay = 600}) + end, +}) + +minetest.register_chatcommand("all", { + func = function(name, param) + local player = minetest.get_player_by_name(name) + mcl_title.params_set(player, {stay = 600}) + mcl_title.set(player, "title", {text=param, color="gold"}) + mcl_title.set(player, "subtitle", {text=param, color="gold"}) + mcl_title.set(player, "actionbar", {text=param, color="gold"}) + end, +}) \ No newline at end of file diff --git a/mods/HUD/mcl_title/mod.conf b/mods/HUD/mcl_title/mod.conf new file mode 100644 index 000000000..0f29a8118 --- /dev/null +++ b/mods/HUD/mcl_title/mod.conf @@ -0,0 +1,4 @@ +name = mcl_title +description = Add an API to add in HUD title +depends = mcl_colors +author = AFCMS \ No newline at end of file From 6b53dda79bf8b31309206ea29b6e84184cc17fc7 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Wed, 2 Jun 2021 00:25:15 +0200 Subject: [PATCH 009/296] add todo list --- mods/HUD/mcl_title/init.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/mods/HUD/mcl_title/init.lua b/mods/HUD/mcl_title/init.lua index 9975ff840..41b4dfc4a 100644 --- a/mods/HUD/mcl_title/init.lua +++ b/mods/HUD/mcl_title/init.lua @@ -1,4 +1,5 @@ --TODO: use SSCSM to reduce lag and network trafic (just send modchannel messages) +--TODO: fadeIn and fadeOut animation (needs engine change: SSCSM or native support) --TODO: exactly mc like layout local huds_idx = {} From c8102838cb80e5ada8649a7ccf48c1c288a4de2b Mon Sep 17 00:00:00 2001 From: AFCMS Date: Wed, 2 Jun 2021 00:26:10 +0200 Subject: [PATCH 010/296] add missing TODO entry (bold+italic) --- mods/HUD/mcl_title/init.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/mods/HUD/mcl_title/init.lua b/mods/HUD/mcl_title/init.lua index 41b4dfc4a..807ed19c9 100644 --- a/mods/HUD/mcl_title/init.lua +++ b/mods/HUD/mcl_title/init.lua @@ -65,6 +65,7 @@ function mcl_title.set(player, type, data) end --TODO: enable this code then Fleckenstein's pr get merged + --TODO: be sure API is correctly used --[[ local bold if data.bold == "true" then From 7e64470f7086c2978f0ad48710d6c0f253b6c3cb Mon Sep 17 00:00:00 2001 From: AFCMS Date: Wed, 2 Jun 2021 11:07:31 +0200 Subject: [PATCH 011/296] fix future API usage of bold+italic pr --- mods/HUD/mcl_title/init.lua | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/mods/HUD/mcl_title/init.lua b/mods/HUD/mcl_title/init.lua index 807ed19c9..83277b3bf 100644 --- a/mods/HUD/mcl_title/init.lua +++ b/mods/HUD/mcl_title/init.lua @@ -64,22 +64,10 @@ function mcl_title.set(player, type, data) player:hud_remove(huds_idx[type][player]) end - --TODO: enable this code then Fleckenstein's pr get merged - --TODO: be sure API is correctly used - --[[ - local bold - if data.bold == "true" then - bold = true - else - bold = false - end + --TODO: enable this code then Fleckenstein's pr get merged (in about 5-6 years) - local italic - if data.italic == "true" then - italic = true - else - italic = false - end]] + --if data.bold == nil then data.bold = false end + --if data.italic == nil then data.italic = false end local stay = mcl_title.params_get(player).stay @@ -88,8 +76,8 @@ function mcl_title.set(player, type, data) position = mcl_title.layout[type].position, alignment = mcl_title.layout[type].alignment, text = data.text, - --bold = bold, - --italic = italic, + --bold = data.bold, + --italic = data.italic, size = {x = mcl_title.layout[type].size}, number = hex_color, z_index = 1100, From b9fd1ac227c59407a92ca208d1fd71681c7952f0 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Wed, 2 Jun 2021 11:12:15 +0200 Subject: [PATCH 012/296] credit digminecraft for the tutorial --- mods/HUD/mcl_title/init.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mods/HUD/mcl_title/init.lua b/mods/HUD/mcl_title/init.lua index 83277b3bf..a2fd82b24 100644 --- a/mods/HUD/mcl_title/init.lua +++ b/mods/HUD/mcl_title/init.lua @@ -1,3 +1,5 @@ +--Based on https://www.digminecraft.com/game_commands/title_command.php + --TODO: use SSCSM to reduce lag and network trafic (just send modchannel messages) --TODO: fadeIn and fadeOut animation (needs engine change: SSCSM or native support) --TODO: exactly mc like layout From ee21a24fb61705bedfee8b2ad935b1e389018a58 Mon Sep 17 00:00:00 2001 From: NO11 Date: Mon, 7 Jun 2021 17:13:50 +0000 Subject: [PATCH 013/296] Don't register a separate entity for every particle --- mods/ITEMS/mcl_totems/init.lua | 60 ++++++++++++++++------------------ 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/mods/ITEMS/mcl_totems/init.lua b/mods/ITEMS/mcl_totems/init.lua index e64404c2c..a6429f7b8 100644 --- a/mods/ITEMS/mcl_totems/init.lua +++ b/mods/ITEMS/mcl_totems/init.lua @@ -7,37 +7,34 @@ end) -- Totem particle registration -- TODO: real MC colors, these are randomly selected colors: local colors = {"#7FFF00", "#698B22", "#BCEE68", "#EEEE00", "#C5F007"} -for c, color in pairs(colors) do - local colorizing = ".png^[colorize:"..color - for n = 1, 4 do - minetest.register_entity("mcl_totems:totem_particle"..n.."_color"..c, { - physical = true, - collide_with_objects = false, - collisionbox = {-0.02,-0.02,-0.02, 0.02,0.02,0.02}, - pointable = false, - visual = "sprite", - visual_size = {x=0.2, y=0.2}, - textures = {"mcl_particles_totem"..n..colorizing}, - spritediv = {x=1, y=1}, - initial_sprite_basepos = {x=0, y=0}, - static_save = false, - glow = 5, - on_activate = function(self, staticdata) - self.object:set_velocity({x = math.random(-4, 4)*math.random(), y = math.random(-1, 4)*math.random(), z = math.random(-4, 4)*math.random()}) - minetest.after(0.3, function() - self.object:set_acceleration({x=0, y=-4, z=0}) - self.object:set_velocity({x=0, y=0, z=0}) - end) - end, - on_step = function(self, dtime) - local r = math.random(1,80) - if r == 1 then - self.object:remove() - end - end +minetest.register_entity("mcl_totems:totem_particle", { + physical = true, + collide_with_objects = false, + collisionbox = {-0.02,-0.02,-0.02, 0.02,0.02,0.02}, + pointable = false, + visual = "sprite", + visual_size = {x=0.2, y=0.2}, + spritediv = {x=1, y=1}, + initial_sprite_basepos = {x=0, y=0}, + static_save = false, + glow = 5, + on_activate = function(self, staticdata) + self.object:set_properties({ + textures = {"mcl_particles_totem"..math.random(1, 4)..".png^[colorize:"..colors[math.random(#colors)]} }) + self.object:set_velocity({x = math.random(-4, 4)*math.random(), y = math.random(-1, 4)*math.random(), z = math.random(-4, 4)*math.random()}) + minetest.after(0.3, function() + self.object:set_acceleration({x=0, y=-4, z=0}) + self.object:set_velocity({x=0, y=0, z=0}) + end) + end, + on_step = function(self, dtime) + local r = math.random(1,50) + if r == 1 then + self.object:remove() + end end -end +}) -- Save the player from death when holding totem of undying in hand mcl_damage.register_modifier(function(obj, damage, reason) @@ -68,11 +65,10 @@ mcl_damage.register_modifier(function(obj, damage, reason) minetest.sound_play({name = "mcl_totems_totem", gain=1}, {pos=ppos, max_hear_distance=16}, true) --Particles - for i = 1, 200 do - local particle = "mcl_totems:totem_particle"..math.random(1, 4).."_color"..math.random(1, 5) + for i = 1, 150 do minetest.after(math.random(1, 2)*math.random(), function() local new_pos = obj:get_pos() - minetest.add_entity({x=new_pos.x, y=new_pos.y + 1, z=new_pos.z}, particle) + minetest.add_entity({x = new_pos.x, y = new_pos.y + 1, z = new_pos.z}, "mcl_totems:totem_particle") end) end From 2603c4768ba34be059b8f3dd175985bc08683cea Mon Sep 17 00:00:00 2001 From: AFCMS Date: Mon, 7 Jun 2021 22:32:05 +0200 Subject: [PATCH 014/296] mcl_title: basic mc like layout (collide with other mods) --- mods/HUD/mcl_title/init.lua | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/mods/HUD/mcl_title/init.lua b/mods/HUD/mcl_title/init.lua index a2fd82b24..ffd740b4a 100644 --- a/mods/HUD/mcl_title/init.lua +++ b/mods/HUD/mcl_title/init.lua @@ -1,7 +1,11 @@ ---Based on https://www.digminecraft.com/game_commands/title_command.php +--Based on: +--https://www.digminecraft.com/game_commands/title_command.php +--https://youtu.be/oVrtQRO2hpY --TODO: use SSCSM to reduce lag and network trafic (just send modchannel messages) --TODO: fadeIn and fadeOut animation (needs engine change: SSCSM or native support) +--TODO: allow obfuscating text (needs engine change: SSCSM or native support) +--TODO: allow colorizing and styling of part of the text (NEEDS ENGINE CHANGE!!!) --TODO: exactly mc like layout local huds_idx = {} @@ -13,9 +17,9 @@ huds_idx.actionbar = {} mcl_title = {} mcl_title.defaults = {fadein = 10, stay = 70, fadeout = 20} mcl_title.layout = {} -mcl_title.layout.title = {position = {x = 0.5, y = 0.5}, alignment = {x = 0, y = -1.3}, size = 5} -mcl_title.layout.subtitle = {position = {x = 0.5, y = 0.5}, alignment = {x = 0, y = 1.9}, size = 2} -mcl_title.layout.actionbar = {position = {x = 0.5, y = 1}, alignment = {x = 0, y = -15}, size = 1} +mcl_title.layout.title = {position = {x = 0.5, y = 0.5}, alignment = {x = 0, y = -1.3}, size = 7} +mcl_title.layout.subtitle = {position = {x = 0.5, y = 0.5}, alignment = {x = 0, y = 1.7}, size = 4} +mcl_title.layout.actionbar = {position = {x = 0.5, y = 1}, alignment = {x = 0, y = -11}, size = 2} local get_color = mcl_util.get_color From 99ccd9ea4c77d09a7e4062f16819a3bbdff9fe53 Mon Sep 17 00:00:00 2001 From: NO11 Date: Tue, 8 Jun 2021 15:13:00 +0000 Subject: [PATCH 015/296] Fix possible crash --- mods/ITEMS/mcl_totems/init.lua | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/mods/ITEMS/mcl_totems/init.lua b/mods/ITEMS/mcl_totems/init.lua index a6429f7b8..1847d579b 100644 --- a/mods/ITEMS/mcl_totems/init.lua +++ b/mods/ITEMS/mcl_totems/init.lua @@ -22,8 +22,11 @@ minetest.register_entity("mcl_totems:totem_particle", { self.object:set_properties({ textures = {"mcl_particles_totem"..math.random(1, 4)..".png^[colorize:"..colors[math.random(#colors)]} }) - self.object:set_velocity({x = math.random(-4, 4)*math.random(), y = math.random(-1, 4)*math.random(), z = math.random(-4, 4)*math.random()}) - minetest.after(0.3, function() + local t = math.random(1, 2)*math.random() + minetest.after(t, function() + self.object:set_velocity({x = math.random(-4, 4)*math.random(), y = math.random(-1, 4)*math.random(), z = math.random(-4, 4)*math.random()}) + end) + minetest.after(0.3 + t, function() self.object:set_acceleration({x=0, y=-4, z=0}) self.object:set_velocity({x=0, y=0, z=0}) end) @@ -65,12 +68,14 @@ mcl_damage.register_modifier(function(obj, damage, reason) minetest.sound_play({name = "mcl_totems_totem", gain=1}, {pos=ppos, max_hear_distance=16}, true) --Particles - for i = 1, 150 do - minetest.after(math.random(1, 2)*math.random(), function() - local new_pos = obj:get_pos() + + minetest.after(0.1, function() + local new_pos = obj:get_pos() + if not new_pos then return end + for i = 1, 150 do minetest.add_entity({x = new_pos.x, y = new_pos.y + 1, z = new_pos.z}, "mcl_totems:totem_particle") - end) - end + end + end) -- Big totem overlay if not hud_totem[obj] then From ee2fa60cae6f151720c1ac7949218f7fee6d4013 Mon Sep 17 00:00:00 2001 From: NO11 Date: Wed, 9 Jun 2021 14:47:42 +0000 Subject: [PATCH 016/296] local totem particle position --- mods/ITEMS/mcl_totems/init.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_totems/init.lua b/mods/ITEMS/mcl_totems/init.lua index 1847d579b..ecdc20da0 100644 --- a/mods/ITEMS/mcl_totems/init.lua +++ b/mods/ITEMS/mcl_totems/init.lua @@ -72,8 +72,9 @@ mcl_damage.register_modifier(function(obj, damage, reason) minetest.after(0.1, function() local new_pos = obj:get_pos() if not new_pos then return end + local particlepos = {x = new_pos.x, y = new_pos.y + 1, z = new_pos.z} for i = 1, 150 do - minetest.add_entity({x = new_pos.x, y = new_pos.y + 1, z = new_pos.z}, "mcl_totems:totem_particle") + minetest.add_entity(particlepos, "mcl_totems:totem_particle") end end) From 40f4287ff200ec20bb2d25650a0b37606bd74b38 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Sat, 12 Jun 2021 12:21:01 +0200 Subject: [PATCH 017/296] new buckets fixes --- mods/ITEMS/mcl_buckets/init.lua | 50 ++++++++++++++++------------ mods/ITEMS/mcl_buckets/register.lua | 2 +- mods/ITEMS/mcl_core/nodes_liquid.lua | 4 +-- 3 files changed, 31 insertions(+), 25 deletions(-) diff --git a/mods/ITEMS/mcl_buckets/init.lua b/mods/ITEMS/mcl_buckets/init.lua index 23d7244e5..f2f61ccfc 100644 --- a/mods/ITEMS/mcl_buckets/init.lua +++ b/mods/ITEMS/mcl_buckets/init.lua @@ -18,7 +18,8 @@ local string = string local raycast = minetest.raycast local get_node = minetest.get_node local add_node = minetest.add_node -local get_node_group = minetest.get_node_group +local add_item = minetest.add_item + if mod_mcl_core then minetest.register_craft({ @@ -26,7 +27,7 @@ if mod_mcl_core then recipe = { {"mcl_core:iron_ingot", "", "mcl_core:iron_ingot"}, {"", "mcl_core:iron_ingot", ""}, - } + }, }) end @@ -34,42 +35,47 @@ mcl_buckets = {} mcl_buckets.liquids = {} -- Sound helper functions for placing and taking liquids -local sound_place = function(itemname, pos) +local function sound_place(itemname, pos) local def = minetest.registered_nodes[itemname] if def and def.sounds and def.sounds.place then minetest.sound_play(def.sounds.place, {gain=1.0, pos = pos, pitch = 1 + math.random(-10, 10)*0.005}, true) end end -local sound_take = function(itemname, pos) +local function sound_take(itemname, pos) local def = minetest.registered_nodes[itemname] if def and def.sounds and def.sounds.dug then minetest.sound_play(def.sounds.dug, {gain=1.0, pos = pos, pitch = 1 + math.random(-10, 10)*0.005}, true) end end -local place_liquid = function(pos, itemstring) +local function place_liquid(pos, itemstring) local fullness = minetest.registered_nodes[itemstring].liquid_range sound_place(itemstring, pos) minetest.add_node(pos, {name=itemstring, param2=fullness}) end local function give_bucket(new_bucket, itemstack, user) - if itemstack:get_count() == 1 then - return new_bucket - else - local inv = user:get_inventory() - if inv:room_for_item("main", new_bucket) then - inv:add_item("main", new_bucket) - else - minetest.add_item(user:get_pos(), new_bucket) - end - if not minetest.is_creative_enabled(user:get_player_name()) then - itemstack:take_item() - end + local inv = user:get_inventory() + if minetest.is_creative_enabled(user:get_player_name()) then + --TODO: is a full bucket added if inv doesn't contain one? return itemstack + else + if itemstack:get_count() == 1 then + return new_bucket + else + if inv:room_for_item("main", new_bucket) then + inv:add_item("main", new_bucket) + else + add_item(user:get_pos(), new_bucket) + end + itemstack:take_item() + return itemstack + end end end +local pointable_sources = {} + local function bucket_raycast(user) local pos = user:get_pos() pos.y = pos.y + user:get_properties().eye_height @@ -77,10 +83,10 @@ local function bucket_raycast(user) look_dir = vector.multiply(look_dir, 6) local pos2 = vector.add(pos, look_dir) - local ray = raycast(pos, pos2, false, true) + local ray = raycast(pos, pos2, false, true) if ray then for pointed_thing in ray do - if pointed_thing and get_node_group(get_node(pointed_thing.above).name, "_mcl_bucket_pointable") == 1 then + if pointed_thing and pointable_sources[get_node(pointed_thing.above).name] then --minetest.chat_send_all("found!") return {under=pointed_thing.under,above=pointed_thing.above} end @@ -97,6 +103,7 @@ function mcl_buckets.register_liquid(def) on_take = def.on_take, itemname = def.itemname, } + pointable_sources[source] = true if type(def.source_place) == "string" then mcl_buckets.liquids[def.source_place] = mcl_buckets.liquids[source] end @@ -137,7 +144,7 @@ function mcl_buckets.register_liquid(def) node_place = def.source_place end -- Check if pointing to a buildable node - local item = itemstack:get_name() + --local item = itemstack:get_name() if def.extra_check and def.extra_check(place_pos, user) == false then -- Fail placement of liquid @@ -308,7 +315,7 @@ minetest.register_craftitem("mcl_buckets:bucket_empty", { return minetest.registered_nodes[nn].on_rightclick(pointed_thing.under, node, user, itemstack) or itemstack end end - + local new_bucket local liquid_node = bucket_raycast(user) if liquid_node then if minetest.is_protected(liquid_node.above, user:get_player_name()) then @@ -318,7 +325,6 @@ minetest.register_craftitem("mcl_buckets:bucket_empty", { if liquid_name then local liquid_def = mcl_buckets.liquids[liquid_name] if liquid_def then - local new_bucket --minetest.chat_send_all("test") -- Fill bucket, but not in Creative Mode -- FIXME: remove this line diff --git a/mods/ITEMS/mcl_buckets/register.lua b/mods/ITEMS/mcl_buckets/register.lua index 863aa074c..12790598c 100644 --- a/mods/ITEMS/mcl_buckets/register.lua +++ b/mods/ITEMS/mcl_buckets/register.lua @@ -3,7 +3,7 @@ local mod_mcl_core = minetest.get_modpath("mcl_core") local mod_mclx_core = minetest.get_modpath("mclx_core") local has_awards = minetest.get_modpath("awards") -local sound_place = function(itemname, pos) +local function sound_place(itemname, pos) local def = minetest.registered_nodes[itemname] if def and def.sounds and def.sounds.place then minetest.sound_play(def.sounds.place, {gain=1.0, pos = pos, pitch = 1 + math.random(-10, 10)*0.005}, true) diff --git a/mods/ITEMS/mcl_core/nodes_liquid.lua b/mods/ITEMS/mcl_core/nodes_liquid.lua index d4234b8ac..0e0f71a11 100644 --- a/mods/ITEMS/mcl_core/nodes_liquid.lua +++ b/mods/ITEMS/mcl_core/nodes_liquid.lua @@ -95,7 +95,7 @@ S("• When water is directly below lava, the water turns into stone."), liquid_range = 7, post_effect_color = {a=209, r=0x03, g=0x3C, b=0x5C}, stack_max = 64, - groups = { water=3, liquid=3, puts_out_fire=1, freezes=1, not_in_creative_inventory=1, dig_by_piston=1, _mcl_bucket_pointable=1}, + groups = { water=3, liquid=3, puts_out_fire=1, freezes=1, not_in_creative_inventory=1, dig_by_piston=1}, _mcl_blast_resistance = 100, -- Hardness intentionally set to infinite instead of 100 (Minecraft value) to avoid problems in creative mode _mcl_hardness = -1, @@ -196,7 +196,7 @@ S("• When lava is directly above water, the water turns into stone."), damage_per_second = 4*2, post_effect_color = {a=245, r=208, g=73, b=10}, stack_max = 64, - groups = { lava=3, lava_source=1, liquid=2, destroys_items=1, not_in_creative_inventory=1, dig_by_piston=1, set_on_fire=15, fire_damage=1, _mcl_bucket_pointable=1}, + groups = { lava=3, lava_source=1, liquid=2, destroys_items=1, not_in_creative_inventory=1, dig_by_piston=1, set_on_fire=15, fire_damage=1}, _mcl_blast_resistance = 100, -- Hardness intentionally set to infinite instead of 100 (Minecraft value) to avoid problems in creative mode _mcl_hardness = -1, From 30e2e0d70afbbadf9fc7181bfde097ccf6fdd014 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Mon, 14 Jun 2021 14:36:17 +0200 Subject: [PATCH 018/296] test values --- mods/ITEMS/mcl_buckets/init.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mods/ITEMS/mcl_buckets/init.lua b/mods/ITEMS/mcl_buckets/init.lua index f2f61ccfc..70a219ffb 100644 --- a/mods/ITEMS/mcl_buckets/init.lua +++ b/mods/ITEMS/mcl_buckets/init.lua @@ -77,10 +77,11 @@ end local pointable_sources = {} local function bucket_raycast(user) - local pos = user:get_pos() + --local pos = user:get_pos() + local pos = mcl_util.get_object_center(user) pos.y = pos.y + user:get_properties().eye_height local look_dir = user:get_look_dir() - look_dir = vector.multiply(look_dir, 6) + look_dir = vector.multiply(look_dir, 4) local pos2 = vector.add(pos, look_dir) local ray = raycast(pos, pos2, false, true) From ef1c06e3d1cbba4ec4091ab88edcb310b788dbb2 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Sat, 19 Jun 2021 10:58:22 +0200 Subject: [PATCH 019/296] fix documentation of `music_record` group --- GROUPS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GROUPS.md b/GROUPS.md index 8c0c3563e..8286b29bc 100644 --- a/GROUPS.md +++ b/GROUPS.md @@ -149,7 +149,7 @@ These groups are used mostly for informational purposes * `trapdoor=2`: Open trapdoor * `glass=1`: Glass (full cubes only) * `rail=1`: Rail -* `music_record`: Music Disc (rating is track ID) +* `music_record`: Item is Music Disc * `tnt=1`: Block is TNT * `boat=1`: Boat * `minecart=1`: Minecart From 61b02209511f66972ff509695bd6c332aa731d29 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Sat, 19 Jun 2021 22:36:37 +0200 Subject: [PATCH 020/296] apply erlehmann fix for music discs not playing (better code) --- mods/ITEMS/mcl_jukebox/init.lua | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/mods/ITEMS/mcl_jukebox/init.lua b/mods/ITEMS/mcl_jukebox/init.lua index 2c9fef689..6c51a6c94 100644 --- a/mods/ITEMS/mcl_jukebox/init.lua +++ b/mods/ITEMS/mcl_jukebox/init.lua @@ -94,7 +94,9 @@ minetest.register_craft({ }) local function play_record(pos, itemstack, player) - local name = itemstack:get_name() + local item_name = itemstack:get_name() + -- ensure the jukebox uses the new record names for old records + local name = minetest.registered_aliases[item_name] or item_name if mcl_jukebox.registered_records[name] then local cname = player:get_player_name() if active_tracks[cname] then @@ -239,25 +241,10 @@ mcl_jukebox.register_record("The Clueless Frog (Jordach's Mix)", "SoundHelix", " --add backward compatibility minetest.register_alias("mcl_jukebox:record_1", "mcl_jukebox:record_13") -mcl_jukebox.registered_records["mcl_jukebox:record_1"] = mcl_jukebox.registered_records["mcl_jukebox:record_13"] - minetest.register_alias("mcl_jukebox:record_2", "mcl_jukebox:record_wait") -mcl_jukebox.registered_records["mcl_jukebox:record_2"] = mcl_jukebox.registered_records["mcl_jukebox:record_wait"] - minetest.register_alias("mcl_jukebox:record_3", "mcl_jukebox:record_blocks") -mcl_jukebox.registered_records["mcl_jukebox:record_3"] = mcl_jukebox.registered_records["mcl_jukebox:record_blocks"] - minetest.register_alias("mcl_jukebox:record_4", "mcl_jukebox:record_far") -mcl_jukebox.registered_records["mcl_jukebox:record_4"] = mcl_jukebox.registered_records["mcl_jukebox:record_far"] - minetest.register_alias("mcl_jukebox:record_5", "mcl_jukebox:record_chirp") -mcl_jukebox.registered_records["mcl_jukebox:record_5"] = mcl_jukebox.registered_records["mcl_jukebox:record_chirp"] - minetest.register_alias("mcl_jukebox:record_6", "mcl_jukebox:record_strad") -mcl_jukebox.registered_records["mcl_jukebox:record_6"] = mcl_jukebox.registered_records["mcl_jukebox:record_strad"] - minetest.register_alias("mcl_jukebox:record_7", "mcl_jukebox:record_mellohi") -mcl_jukebox.registered_records["mcl_jukebox:record_7"] = mcl_jukebox.registered_records["mcl_jukebox:record_mellohi"] - -minetest.register_alias("mcl_jukebox:record_8", "mcl_jukebox:record_mall") -mcl_jukebox.registered_records["mcl_jukebox:record_8"] = mcl_jukebox.registered_records["mcl_jukebox:record_mall"] \ No newline at end of file +minetest.register_alias("mcl_jukebox:record_8", "mcl_jukebox:record_mall") \ No newline at end of file From 586c18b00f7803557262ee7f1a465c89bc8e1665 Mon Sep 17 00:00:00 2001 From: kay27 Date: Tue, 22 Jun 2021 03:15:39 +0400 Subject: [PATCH 021/296] [mcl_mobs/api] Continue float function on acceleration.y equals zero --- mods/ENTITIES/mcl_mobs/api/mob_functions/movement.lua | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/movement.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/movement.lua index 893f8eede..d9698a0a7 100644 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/movement.lua +++ b/mods/ENTITIES/mcl_mobs/api/mob_functions/movement.lua @@ -32,12 +32,15 @@ end mobs.float = function(self) local acceleration = self.object:get_acceleration() - if acceleration and acceleration.y ~= 0 then - self.object:set_acceleration(vector.new(0,0,0)) - else + + if not acceleration then return end + if acceleration.y ~= 0 then + self.object:set_acceleration({x=0, y=0, z=0}) + end + local current_velocity = self.object:get_velocity() local goal_velocity = { @@ -46,7 +49,7 @@ mobs.float = function(self) z = 0, } - local new_velocity_addition = vector.subtract(goal_velocity,current_velocity) + local new_velocity_addition = vector.subtract(goal_velocity, current_velocity) new_velocity_addition.x = 0 new_velocity_addition.z = 0 From c6b662ce7ae58a37dea89a88ea1edac6243b62d1 Mon Sep 17 00:00:00 2001 From: kay27 Date: Tue, 22 Jun 2021 05:10:45 +0400 Subject: [PATCH 022/296] [mcl_mobs/api] Add mob flow code from Crafter --- mods/ENTITIES/mcl_mobs/api/api.lua | 1 + .../mcl_mobs/api/mob_functions/ai.lua | 31 ++++++-- .../mcl_mobs/api/mob_functions/flow_lib.lua | 78 +++++++++++++++++++ 3 files changed, 102 insertions(+), 8 deletions(-) create mode 100644 mods/ENTITIES/mcl_mobs/api/mob_functions/flow_lib.lua diff --git a/mods/ENTITIES/mcl_mobs/api/api.lua b/mods/ENTITIES/mcl_mobs/api/api.lua index d1840f671..639eb517d 100644 --- a/mods/ENTITIES/mcl_mobs/api/api.lua +++ b/mods/ENTITIES/mcl_mobs/api/api.lua @@ -129,6 +129,7 @@ end local api_path = minetest.get_modpath(minetest.get_current_modname()).."/api/mob_functions/" --ignite all parts of the api +dofile(api_path .. "flow_lib.lua") dofile(api_path .. "ai.lua") dofile(api_path .. "animation.lua") dofile(api_path .. "collision.lua") diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/ai.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/ai.lua index d16d24929..88ce3274b 100644 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/ai.lua +++ b/mods/ENTITIES/mcl_mobs/api/mob_functions/ai.lua @@ -9,6 +9,8 @@ local minetest_get_item_group = minetest.get_item_group local minetest_get_node = minetest.get_node local minetest_line_of_sight = minetest.line_of_sight local minetest_get_node_light = minetest.get_node_light +local minetest_registered_nodes = minetest.registered_nodes +local flow = mobs.get_flowing_dir local DOUBLE_PI = math.pi * 2 local THIRTY_SECONDTH_PI = DOUBLE_PI * 0.03125 @@ -521,8 +523,8 @@ ______ _ | _| | | | | | | | | | |_| | \_| |_|\__, | - __/ | - |___/ + __/ | + |___/ ]]-- -- state switching logic (stand, walk, run, attacks) @@ -675,12 +677,12 @@ end --[[ ___ |_ | - | |_ _ _ __ ___ _ __ - | | | | | '_ ` _ \| '_ \ + | |_ _ _ __ ___ _ __ + | | | | | '_ ` _ \| '_ \ /\__/ / |_| | | | | | | |_) | \____/ \__,_|_| |_| |_| .__/ - | | - |_| + | | + |_| ]]-- @@ -787,8 +789,8 @@ ___ ___ _ _ _ | |\/| |/ _` | | '_ \ | | / _ \ / _` | |/ __| | | | | (_| | | | | | | |___| (_) | (_| | | (__ \_| |_/\__,_|_|_| |_| \_____/\___/ \__, |_|\___| - __/ | - |___/ + __/ | + |___/ ]]-- --the main loop @@ -1011,6 +1013,19 @@ function mobs.mob_step(self, dtime) end end + --mobs flow from Crafter + local pos = self.object:get_pos() + if pos then + local flow_dir = flow(pos) + if flow_dir then + flow_dir = vector.multiply(flow_dir,10) + local vel = self.object:get_velocity() + local acceleration = vector.new(flow_dir.x-vel.x,flow_dir.y-vel.y,flow_dir.z-vel.z) + acceleration = vector.multiply(acceleration, 0.01) + self.object:add_velocity(acceleration) + end + end + --mob is stunned after being hit if self.pause_timer > 0 then self.pause_timer = self.pause_timer - dtime diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/flow_lib.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/flow_lib.lua new file mode 100644 index 000000000..aa64bfb4e --- /dev/null +++ b/mods/ENTITIES/mcl_mobs/api/mob_functions/flow_lib.lua @@ -0,0 +1,78 @@ +--this is from https://github.com/HybridDog/builtin_item/blob/e6dfd9dce86503b3cbd1474257eca5f6f6ca71c2/init.lua#L50 +local +minetest,vector,math,pairs,minetest_get_node,vector_subtract,minetest_registered_nodes += +minetest,vector,math,pairs,minetest.get_node,vector.subtract,minetest.registered_nodes + +local tab +local n +local function get_nodes(pos) + tab,n = {},1 + for i = -1,1,2 do + for _,p in pairs({ + {x=pos.x+i, y=pos.y, z=pos.z}, + {x=pos.x, y=pos.y, z=pos.z+i} + }) do + tab[n] = {p, minetest_get_node(p)} + n = n+1 + end + end + return tab +end + + +local data +local param2 +local nd +local par2 +local name +local tmp +local c_node +function mobs.get_flowing_dir(pos) + c_node = minetest_get_node(pos).name + if c_node ~= "mcl_core:water_flowing" and c_node ~= "mcl_core:water" then + return nil + end + data = get_nodes(pos) + param2 = minetest_get_node(pos).param2 + if param2 > 7 then + return nil + end + if c_node == "mcl_core:water" then + for _,i in pairs(data) do + nd = i[2] + name = nd.name + par2 = nd.param2 + if name == "mcl_core:water_flowing" and par2 == 7 then + return(vector_subtract(i[1],pos)) + end + end + end + for _,i in pairs(data) do + nd = i[2] + name = nd.name + par2 = nd.param2 + if name == "mcl_core:water_flowing" and par2 < param2 then + return(vector_subtract(i[1],pos)) + end + end + for _,i in pairs(data) do + nd = i[2] + name = nd.name + par2 = nd.param2 + if name == "mcl_core:water_flowing" and par2 >= 11 then + return(vector_subtract(i[1],pos)) + end + end + for _,i in pairs(data) do + nd = i[2] + name = nd.name + par2 = nd.param2 + tmp = minetest_registered_nodes[name] + if tmp and not tmp.walkable and name ~= "mcl_core:water_flowing" and name ~= "mcl_core:water" then + return(vector_subtract(i[1],pos)) + end + end + + return nil +end From 7ff476b9b9ecc0c4653edc789e8db5f6fa567d76 Mon Sep 17 00:00:00 2001 From: kay27 Date: Tue, 22 Jun 2021 16:53:55 +0400 Subject: [PATCH 023/296] Fix igloo hidden trapdoor with minetest.after(), https://git.minetest.land/MineClone2/MineClone2/issues/1797 --- mods/MAPGEN/mcl_structures/init.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mods/MAPGEN/mcl_structures/init.lua b/mods/MAPGEN/mcl_structures/init.lua index 8efdd91b1..533c9cab0 100644 --- a/mods/MAPGEN/mcl_structures/init.lua +++ b/mods/MAPGEN/mcl_structures/init.lua @@ -187,8 +187,6 @@ function mcl_structures.generate_igloo(pos, rotation, pr) if real_depth <= 6 then return success end - -- Place hidden trapdoor - minetest.set_node(tpos, {name="mcl_doors:trapdoor", param2=20+minetest.dir_to_facedir(dir)}) -- TODO: more reliable param2 -- Generate ladder to basement for y=1, real_depth-1 do set_brick({x=tpos.x-1,y=tpos.y-y,z=tpos.z }) @@ -199,6 +197,10 @@ function mcl_structures.generate_igloo(pos, rotation, pr) end -- Place basement mcl_structures.generate_igloo_basement(bpos, rotation, pr) + -- Place hidden trapdoor + minetest.after(5, function(tpos, dir) + minetest.set_node(tpos, {name="mcl_doors:trapdoor", param2=20+minetest.dir_to_facedir(dir)}) -- TODO: more reliable param2 + end, tpos, dir) end return success end From 16d79c38ceb2e11fbdcd940035dacf6d52282c11 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Sat, 26 Jun 2021 23:48:59 +0200 Subject: [PATCH 024/296] fix typo in mcl_enchanting french translation --- mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.fr.tr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.fr.tr b/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.fr.tr index e1178e782..985499964 100644 --- a/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.fr.tr +++ b/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.fr.tr @@ -7,7 +7,7 @@ Blast Protection=Protection contre les explosions Reduces explosion damage and knockback.=Réduit les dégâts d'explosion et de recul. Channeling=Canalisation Channels a bolt of lightning toward a target. Works only during thunderstorms and if target is unobstructed with opaque blocks.=Canalise un éclair vers une cible. Fonctionne uniquement pendant les orages et si la cible n'est pas obstruée par des blocs opaques. -Curse of Binding=Malédiction du lien éterne +Curse of Binding=Malédiction du lien éternel Item cannot be removed from armor slots except due to death, breaking or in Creative Mode.=L'objet ne peut pas être retiré des emplacements d'armure sauf en cas de mort, de rupture ou en mode créatif. Curse of Vanishing=Malédiction de disparition Item destroyed on death.=Objet détruit à la mort. From a9ceeabc4b71634c15c46b1843f222ff7c825212 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Mon, 28 Jun 2021 13:46:18 +0200 Subject: [PATCH 025/296] fix typo in mcl_craftguide --- mods/HELP/mcl_craftguide/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/HELP/mcl_craftguide/init.lua b/mods/HELP/mcl_craftguide/init.lua index 378b420ff..3bc7b705a 100644 --- a/mods/HELP/mcl_craftguide/init.lua +++ b/mods/HELP/mcl_craftguide/init.lua @@ -155,7 +155,7 @@ end local custom_crafts, craft_types = {}, {} function mcl_craftguide.register_craft_type(name, def) - local func = "mcl_craftguide.register_craft_guide(): " + local func = "mcl_craftguide.register_craft_type(): " assert(name, func .. "'name' field missing") assert(def.description, func .. "'description' field missing") assert(def.icon, func .. "'icon' field missing") From 21992dc2653616db974ebfc6f0c48e436592fa34 Mon Sep 17 00:00:00 2001 From: NO11 Date: Sat, 3 Jul 2021 12:10:32 +0000 Subject: [PATCH 026/296] Fix #1746 (make anvils destroy items when falling) --- mods/ITEMS/mcl_anvils/init.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mods/ITEMS/mcl_anvils/init.lua b/mods/ITEMS/mcl_anvils/init.lua index fbf6fb751..e641183de 100644 --- a/mods/ITEMS/mcl_anvils/init.lua +++ b/mods/ITEMS/mcl_anvils/init.lua @@ -276,6 +276,12 @@ local function damage_anvil_by_using(pos) end local function damage_anvil_by_falling(pos, distance) + for _,object in pairs(minetest.get_objects_inside_radius(pos, 0.8)) do + local entity = object:get_luaentity() + if not object:is_player() and entity and entity.name == "__builtin:item" then + object:remove() + end + end local r = math.random(1, 100) if distance > 1 then if r <= (5*distance) then From d45e1c07bdb00f62d592d4984c63da789b8cdc2c Mon Sep 17 00:00:00 2001 From: NO11 Date: Sat, 3 Jul 2021 12:19:49 +0000 Subject: [PATCH 027/296] Remove unnecessary code --- mods/ITEMS/mcl_anvils/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_anvils/init.lua b/mods/ITEMS/mcl_anvils/init.lua index e641183de..509e78321 100644 --- a/mods/ITEMS/mcl_anvils/init.lua +++ b/mods/ITEMS/mcl_anvils/init.lua @@ -278,7 +278,7 @@ end local function damage_anvil_by_falling(pos, distance) for _,object in pairs(minetest.get_objects_inside_radius(pos, 0.8)) do local entity = object:get_luaentity() - if not object:is_player() and entity and entity.name == "__builtin:item" then + if entity and entity.name == "__builtin:item" then object:remove() end end From 0a474ee5781fa84147dd478e8a9cfa9c5007273a Mon Sep 17 00:00:00 2001 From: Nils Dagsson Moskopp Date: Wed, 23 Jun 2021 03:06:24 +0200 Subject: [PATCH 028/296] Reduce snow layer silk touch drop amount MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It was possible to duplicate snow layers by placing them and then mining them using a tool enchanted with silk touch. This commit fixes the “snow dupe” by reducing the amount of snow layers dropped in this case by one. --- mods/ITEMS/mcl_core/nodes_base.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_core/nodes_base.lua b/mods/ITEMS/mcl_core/nodes_base.lua index d4bfd7636..abc650bb0 100644 --- a/mods/ITEMS/mcl_core/nodes_base.lua +++ b/mods/ITEMS/mcl_core/nodes_base.lua @@ -1041,7 +1041,7 @@ for i=1,8 do drop = "mcl_throwing:snowball "..(i+1), _mcl_blast_resistance = 0.1, _mcl_hardness = 0.1, - _mcl_silk_touch_drop = {"mcl_core:snow " .. (i+1)}, + _mcl_silk_touch_drop = {"mcl_core:snow " .. i}, }) end From 4afdea56dbbca4ea0a9cc15343a64f8d1d18583d Mon Sep 17 00:00:00 2001 From: NO11 Date: Mon, 5 Jul 2021 12:28:14 +0000 Subject: [PATCH 029/296] Move code of making anvils destroy items when falling --- mods/ENTITIES/mcl_falling_nodes/init.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mods/ENTITIES/mcl_falling_nodes/init.lua b/mods/ENTITIES/mcl_falling_nodes/init.lua index 01681a159..d527603de 100644 --- a/mods/ENTITIES/mcl_falling_nodes/init.lua +++ b/mods/ENTITIES/mcl_falling_nodes/init.lua @@ -19,7 +19,10 @@ local function deal_falling_damage(self, dtime) end self._hit = self._hit or {} for _, obj in ipairs(minetest.get_objects_inside_radius(pos, 1)) do - if mcl_util.get_hp(obj) > 0 and not self._hit[obj] then + local entity = obj:get_luaentity() + if entity and entity.name == "__builtin:item" then + obj:remove() + elseif mcl_util.get_hp(obj) > 0 and not self._hit[obj] then self._hit[obj] = true local way = self._startpos.y - pos.y local damage = (way - 1) * 2 From 5cc4fe955fc083e86503fdf2c3d10302b70f3168 Mon Sep 17 00:00:00 2001 From: NO11 Date: Mon, 5 Jul 2021 12:30:01 +0000 Subject: [PATCH 030/296] Remove old code of making anvils destroy items when falling --- mods/ITEMS/mcl_anvils/init.lua | 6 ------ 1 file changed, 6 deletions(-) diff --git a/mods/ITEMS/mcl_anvils/init.lua b/mods/ITEMS/mcl_anvils/init.lua index 509e78321..fbf6fb751 100644 --- a/mods/ITEMS/mcl_anvils/init.lua +++ b/mods/ITEMS/mcl_anvils/init.lua @@ -276,12 +276,6 @@ local function damage_anvil_by_using(pos) end local function damage_anvil_by_falling(pos, distance) - for _,object in pairs(minetest.get_objects_inside_radius(pos, 0.8)) do - local entity = object:get_luaentity() - if entity and entity.name == "__builtin:item" then - object:remove() - end - end local r = math.random(1, 100) if distance > 1 then if r <= (5*distance) then From b22e4ae99d08b15f3e0d2c827ab8693dfcdbf91b Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 6 Jul 2021 11:02:59 +0200 Subject: [PATCH 031/296] Update links in README.md --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index aeab8ab1a..fce4d43a7 100644 --- a/README.md +++ b/README.md @@ -77,15 +77,15 @@ To install MineClone 2 (if you haven't already), move this directory into the “games” directory of your Minetest data directory. Consult the help of Minetest to learn more. -## Reporting bugs -Please report all bugs and missing Minecraft features here: +## Useful links +The MineClone2 repository is hosted at Mesehub. To contribute or report issues, head there. - - -## Chatting with the community -Join our discord server at: - - +* Mesehub: +* Discord: +* IRC: +* Matrix: +* Reddit: +* Minetest forums: ## Project description The main goal of **MineClone 2** is to be a clone of Minecraft and to be released as free software. From f4a30959ce9ec234a1ca8e56eeb583b378e066a5 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 6 Jul 2021 09:01:36 +0000 Subject: [PATCH 032/296] Update 'README.md' --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index fce4d43a7..22b5d0d7b 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,7 @@ The MineClone2 repository is hosted at Mesehub. To contribute or report issues, * Mesehub: * Discord: +* YouTube * IRC: * Matrix: * Reddit: From ae2c5ede3058bbb4ad868ea5e128b4ed9143bf7e Mon Sep 17 00:00:00 2001 From: erlehmann Date: Mon, 3 May 2021 14:30:47 +0000 Subject: [PATCH 033/296] Merge pull request 'Remove wrong preview banner crafting recipes' (#55) from banner-crafting-fix into master Reviewed-on: https://git.minetest.land/Mineclonia/Mineclonia/pulls/55 Reviewed-by: E --- mods/ITEMS/mcl_banners/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_banners/init.lua b/mods/ITEMS/mcl_banners/init.lua index 490e22643..a396caf7d 100644 --- a/mods/ITEMS/mcl_banners/init.lua +++ b/mods/ITEMS/mcl_banners/init.lua @@ -573,7 +573,7 @@ for colorid, colortab in pairs(mcl_banners.colors) do end, }) - if mod_mcl_core and minetest.get_modpath("mcl_wool") then + if mod_mcl_core and minetest.get_modpath("mcl_wool") and pattern_name == "" then minetest.register_craft({ output = itemstring, recipe = { From 2f22ce79cc5839b94f926186ce51be3653fc8393 Mon Sep 17 00:00:00 2001 From: erlehmann Date: Sat, 19 Jun 2021 13:01:11 +0000 Subject: [PATCH 034/296] Merge pull request 'ITEMS/mcl_banners: Allow more layers for banners with gradients' (#74) from e/Mineclonia:banner-gradient-limits into master MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-on: https://git.minetest.land/Mineclonia/Mineclonia/pulls/74 Reviewed-by: Elias Åström Reviewed-by: erlehmann --- mods/ITEMS/mcl_banners/patterncraft.lua | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/mods/ITEMS/mcl_banners/patterncraft.lua b/mods/ITEMS/mcl_banners/patterncraft.lua index bc2771fee..79778a665 100644 --- a/mods/ITEMS/mcl_banners/patterncraft.lua +++ b/mods/ITEMS/mcl_banners/patterncraft.lua @@ -8,9 +8,6 @@ local N = function(s) return s end -- Maximum number of layers which can be put on a banner by crafting. local max_layers_crafting = 12 --- Maximum number of layers when banner includes a gradient (workaround, see below). -local max_layers_gradient = 3 - -- Max. number lines in the descriptions for the banner layers. -- This is done to avoid huge tooltips. local max_layer_lines = 6 @@ -398,16 +395,6 @@ local function banner_pattern_craft(itemstack, player, old_craft_grid, craft_inv if #layers >= max_layers_crafting then return ItemStack("") end - -- Lower layer limit when banner includes any gradient. - -- Workaround to circumvent Minetest bug (https://github.com/minetest/minetest/issues/6210) - -- TODO: Remove this restriction when bug #6210 is fixed. - if #layers >= max_layers_gradient then - for l=1, #layers do - if layers[l].pattern == "gradient" or layers[l].pattern == "gradient_up" then - return ItemStack("") - end - end - end local matching_pattern local max_i = player:get_inventory():get_size("craft") From 8f584be235e3ff67fcd73e9480c1002ee006b670 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Thu, 8 Jul 2021 15:03:06 +0200 Subject: [PATCH 035/296] Fix #1814 - Don't open crafting table formspec if player is sneaking --- mods/ITEMS/mcl_crafting_table/init.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mods/ITEMS/mcl_crafting_table/init.lua b/mods/ITEMS/mcl_crafting_table/init.lua index 58b46d668..eae503eeb 100644 --- a/mods/ITEMS/mcl_crafting_table/init.lua +++ b/mods/ITEMS/mcl_crafting_table/init.lua @@ -6,6 +6,7 @@ local text_color = "#313131" local itemslot_bg = mcl_formspec.get_itemslot_bg mcl_crafting_table = {} + function mcl_crafting_table.show_crafting_form(player) player:get_inventory():set_width("craft", 3) player:get_inventory():set_size("craft", 9) @@ -30,7 +31,6 @@ function mcl_crafting_table.show_crafting_form(player) ) end -local show_crafting_form = mcl_crafting_table.show_crafting_form --cache function for better performances minetest.register_node("mcl_crafting_table:crafting_table", { description = S("Crafting Table"), _tt_help = S("3×3 crafting grid"), @@ -43,7 +43,9 @@ minetest.register_node("mcl_crafting_table:crafting_table", { paramtype2 = "facedir", groups = {handy=1,axey=1, deco_block=1, material_wood=1,flammable=-1}, on_rightclick = function(pos, node, player, itemstack) - show_crafting_form(player) + if not player:get_player_control().sneak then + mcl_crafting_table.show_crafting_form(player) + end end, sounds = mcl_sounds.node_sound_wood_defaults(), _mcl_blast_resistance = 2.5, From 3b2a25a6cb338e9acdc9e2c8e72cb1221147f878 Mon Sep 17 00:00:00 2001 From: cora Date: Fri, 25 Jun 2021 15:25:45 +0000 Subject: [PATCH 036/296] Merge pull request 'mcl_inventory: Remove _mcl_autogroup dependency from mcl_inventory' (#76) from fix_inventory_depends into master Reviewed-on: https://git.minetest.land/Mineclonia/Mineclonia/pulls/76 Reviewed-by: cora --- mods/HUD/mcl_inventory/creative.lua | 9 ++++----- mods/HUD/mcl_inventory/mod.conf | 5 ++--- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/mods/HUD/mcl_inventory/creative.lua b/mods/HUD/mcl_inventory/creative.lua index 6eac1c329..ff9cccf9e 100644 --- a/mods/HUD/mcl_inventory/creative.lua +++ b/mods/HUD/mcl_inventory/creative.lua @@ -27,10 +27,9 @@ local function replace_enchanted_books(tbl) end end ---[[ Populate all the item tables. We only do this once. Note this mod must be -loaded after _mcl_autogroup for this to work, because it required certain -groups to be set. ]] -do +--[[ Populate all the item tables. We only do this once. Note this code must be +executed after loading all the other mods in order to work. ]] +minetest.register_on_mods_loaded(function() for name,def in pairs(minetest.registered_items) do if (not def.groups.not_in_creative_inventory or def.groups.not_in_creative_inventory == 0) and def.description and def.description ~= "" then local function is_redstone(def) @@ -108,7 +107,7 @@ do table.sort(to_sort) replace_enchanted_books(to_sort) end -end +end) local function filter_item(name, description, lang, filter) local desc diff --git a/mods/HUD/mcl_inventory/mod.conf b/mods/HUD/mcl_inventory/mod.conf index 7585d9f70..10e669265 100644 --- a/mods/HUD/mcl_inventory/mod.conf +++ b/mods/HUD/mcl_inventory/mod.conf @@ -1,6 +1,5 @@ name = mcl_inventory author = BlockMen description = Adds the player inventory and creative inventory. -depends = mcl_init, mcl_formspec, mcl_player -optional_depends = _mcl_autogroup, mcl_armor, mcl_brewing, mcl_potions, mcl_enchanting, mcl_craftguide - +depends = mcl_init, mcl_formspec, mcl_enchanting +optional_depends = mcl_armor, mcl_brewing, mcl_potions, mcl_enchanting, mcl_craftguide, mcl_player From fb01e619466d5e5147cd1609f45444667dab7d82 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Thu, 8 Jul 2021 15:31:27 +0200 Subject: [PATCH 037/296] Fix server crash when dispensing an unknown item This works similar to 2aafb2f2d01a6ece9ed4642a7081c53dbf22f773, however it is a cleaner way to do it. --- mods/ITEMS/REDSTONE/mcl_dispensers/init.lua | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua b/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua index ee7f29016..7c2c07393 100644 --- a/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua +++ b/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua @@ -129,8 +129,13 @@ local dispenserdef = { dropitem:set_count(1) local stack_id = stacks[r].stackpos local stackdef = stack:get_definition() + + if not stackdef then + return + end + local iname = stack:get_name() - local igroups = minetest.registered_items[iname].groups + local igroups = stackdef.groups --[===[ Dispense item ]===] From c558e30ea55b1a93710f53093c07fa2bbe87bc32 Mon Sep 17 00:00:00 2001 From: cora Date: Tue, 15 Jun 2021 01:13:24 +0200 Subject: [PATCH 038/296] Fix server crash when players dig unknown nodes Digging unknown nodes crashes the Clamity Minetest server, which runs modified Minetest: https://github.com/ClamityAnarchy/minetest Crashes did occur with commit d5434bf008 of that Minetest version. This commit makes unknown nodes explicitly not harvestable. --- mods/CORE/_mcl_autogroup/init.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mods/CORE/_mcl_autogroup/init.lua b/mods/CORE/_mcl_autogroup/init.lua index ba8b659c0..e04fb2eac 100644 --- a/mods/CORE/_mcl_autogroup/init.lua +++ b/mods/CORE/_mcl_autogroup/init.lua @@ -207,6 +207,10 @@ end function mcl_autogroup.can_harvest(nodename, toolname) local ndef = minetest.registered_nodes[nodename] + if not ndef then + return false + end + if minetest.get_item_group(nodename, "dig_immediate") >= 2 then return true end From 6e1758400ef4999d2189f7656d1c7bbcdc76e4ce Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Thu, 8 Jul 2021 15:39:08 +0200 Subject: [PATCH 039/296] Remove feature freeze notice from README --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 22b5d0d7b..034d381ab 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ -# (Currently in feature freeze) - # MineClone 2 An unofficial Minecraft-like game for Minetest. Forked from MineClone by davedevils. Developed by many people. Not developed or endorsed by Mojang AB. From 509568b4b01e7529af9c8ad1e00980eba7bbd648 Mon Sep 17 00:00:00 2001 From: NO11 Date: Thu, 8 Jul 2021 16:49:19 +0000 Subject: [PATCH 040/296] Use real Minecraft colors for totem particles! --- mods/ITEMS/mcl_totems/init.lua | 38 ++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/mods/ITEMS/mcl_totems/init.lua b/mods/ITEMS/mcl_totems/init.lua index ecdc20da0..2311e88d7 100644 --- a/mods/ITEMS/mcl_totems/init.lua +++ b/mods/ITEMS/mcl_totems/init.lua @@ -5,8 +5,32 @@ minetest.register_on_leaveplayer(function(player) end) -- Totem particle registration --- TODO: real MC colors, these are randomly selected colors: -local colors = {"#7FFF00", "#698B22", "#BCEE68", "#EEEE00", "#C5F007"} +function rgb_to_hex(rgb) + local hexadecimal = "#" + + for key, value in pairs(rgb) do + local hex = "" + + while value > 0 do + local index = math.fmod(value, 16) + 1 + value = math.floor(value / 16) + hex = string.sub("0123456789ABCDEF", index, index) .. hex + end + + local len = string.len(hex) + + if len == 0 then + hex = "00" + elseif len == 1 then + hex = "0" .. hex + end + + hexadecimal = hexadecimal .. hex + end + + return hexadecimal +end + minetest.register_entity("mcl_totems:totem_particle", { physical = true, collide_with_objects = false, @@ -17,10 +41,16 @@ minetest.register_entity("mcl_totems:totem_particle", { spritediv = {x=1, y=1}, initial_sprite_basepos = {x=0, y=0}, static_save = false, - glow = 5, + glow = 14, on_activate = function(self, staticdata) + local color + if math.random(0, 3) == 0 then + color = rgb_to_hex({ (0.6 + math.random() * 0.2) * 255, (0.6 + math.random() * 0.3) * 255, (math.random() * 0.2) * 255 }) + else + color = rgb_to_hex({ (0.1 + math.random() * 0.4) * 255, (0.6 + math.random() * 0.3) * 255, (math.random() * 0.2) * 255 }) + end self.object:set_properties({ - textures = {"mcl_particles_totem"..math.random(1, 4)..".png^[colorize:"..colors[math.random(#colors)]} + textures = { "mcl_particles_totem"..math.random(1, 4)..".png^[colorize:"..color } }) local t = math.random(1, 2)*math.random() minetest.after(t, function() From 8e931e92f57ce18792a846828e0e942f52f8eef1 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Fri, 9 Jul 2021 11:34:23 +0200 Subject: [PATCH 041/296] refactor mcl_title to be more efficient --- mods/HUD/mcl_title/init.lua | 120 +++++++++++++++++++++++++++--------- 1 file changed, 90 insertions(+), 30 deletions(-) diff --git a/mods/HUD/mcl_title/init.lua b/mods/HUD/mcl_title/init.lua index ffd740b4a..48c3a909f 100644 --- a/mods/HUD/mcl_title/init.lua +++ b/mods/HUD/mcl_title/init.lua @@ -8,8 +8,17 @@ --TODO: allow colorizing and styling of part of the text (NEEDS ENGINE CHANGE!!!) --TODO: exactly mc like layout +--Note that the table storing timeouts use playername as index insteed of player objects (faster) +--This is intended in order to speedup the process of removing HUD elements the the timeout is up + local huds_idx = {} +local hud_hide_timeouts = {} + +hud_hide_timeouts.title = {} +hud_hide_timeouts.subtitle = {} +hud_hide_timeouts.actionbar = {} + huds_idx.title = {} huds_idx.subtitle = {} huds_idx.actionbar = {} @@ -19,10 +28,13 @@ mcl_title.defaults = {fadein = 10, stay = 70, fadeout = 20} mcl_title.layout = {} mcl_title.layout.title = {position = {x = 0.5, y = 0.5}, alignment = {x = 0, y = -1.3}, size = 7} mcl_title.layout.subtitle = {position = {x = 0.5, y = 0.5}, alignment = {x = 0, y = 1.7}, size = 4} -mcl_title.layout.actionbar = {position = {x = 0.5, y = 1}, alignment = {x = 0, y = -11}, size = 2} +mcl_title.layout.actionbar = {position = {x = 0.5, y = 1}, alignment = {x = 0, y = 0}, size = 1} local get_color = mcl_util.get_color +local string = string +local pairs = pairs + local function gametick_to_secondes(gametick) return gametick / 20 end @@ -32,15 +44,64 @@ end local player_params = {} minetest.register_on_joinplayer(function(player) - player_params[player] = { + local playername = player:get_player_name() + player_params[playername] = { stay = gametick_to_secondes(mcl_title.defaults.stay), --fadeIn = gametick_to_secondes(mcl_title.defaults.fadein), --fadeOut = gametick_to_secondes(mcl_title.defaults.fadeout), - } + } + local _, hex_color = get_color("white") + huds_idx.title[player] = player:hud_add({ + hud_elem_type = "text", + position = mcl_title.layout.title.position, + alignment = mcl_title.layout.title.alignment, + text = "", + --bold = data.bold, + --italic = data.italic, + size = {x = mcl_title.layout.title.size}, + number = hex_color, + z_index = 100, + }) + huds_idx.subtitle[player] = player:hud_add({ + hud_elem_type = "text", + position = mcl_title.layout.subtitle.position, + alignment = mcl_title.layout.subtitle.alignment, + text = "", + --bold = data.bold, + --italic = data.italic, + size = {x = mcl_title.layout.subtitle.size}, + number = hex_color, + z_index = 100, + }) + huds_idx.actionbar[player] = player:hud_add({ + hud_elem_type = "text", + position = mcl_title.layout.actionbar.position, + offset = {x = 0, y = -210}, + alignment = mcl_title.layout.actionbar.alignment, + --bold = data.bold, + --italic = data.italic, + text = "", + size = {x = mcl_title.layout.actionbar.size}, + number = hex_color, + z_index = 100, + }) end) minetest.register_on_leaveplayer(function(player) - player_params = nil + local playername = player:get_player_name() + + --remove player params from the list + player_params[player] = nil + + --remove HUD idx from the list (HUD elements are removed by the engine) + huds_idx.title[player] = nil + huds_idx.subtitle[player] = nil + huds_idx.actionbar[player] = nil + + --remove timers form list + hud_hide_timeouts.title[playername] = nil + hud_hide_timeouts.subtitle[playername] = nil + hud_hide_timeouts.actionbar[playername] = nil end) function mcl_title.params_set(player, data) @@ -66,43 +127,22 @@ function mcl_title.set(player, type, data) return false end - if huds_idx[type][player] then - player:hud_remove(huds_idx[type][player]) - end - --TODO: enable this code then Fleckenstein's pr get merged (in about 5-6 years) --if data.bold == nil then data.bold = false end --if data.italic == nil then data.italic = false end - local stay = mcl_title.params_get(player).stay + player:hud_change(huds_idx[type][player], "text", data.text) + player:hud_change(huds_idx[type][player], "number", hex_color) - huds_idx[type][player] = player:hud_add({ - hud_elem_type = "text", - position = mcl_title.layout[type].position, - alignment = mcl_title.layout[type].alignment, - text = data.text, - --bold = data.bold, - --italic = data.italic, - size = {x = mcl_title.layout[type].size}, - number = hex_color, - z_index = 1100, - }) - - minetest.after(stay, function() - if huds_idx[type][player] then - player:hud_remove(huds_idx[type][player]) - end - huds_idx[type][player] = nil - end) + hud_hide_timeouts[type][player:get_player_name()] = data.stay or mcl_title.params_get(player).stay return true end function mcl_title.remove(player, type) - if huds_idx[type][player] then - player:hud_remove(huds_idx[type][player]) + if player then + player:hud_change(huds_idx[type][player], "text", "") end - huds_idx[type][player] = nil end function mcl_title.clear(player) @@ -115,6 +155,26 @@ minetest.register_on_dieplayer(function(player) mcl_title.clear(player) end) +minetest.register_globalstep(function(dtime) + local new_timeouts = { + title = {}, + subtitle = {}, + actionbar = {}, + } + for element, content in pairs(hud_hide_timeouts) do + for name, timeout in pairs(content) do + timeout = timeout - dtime + if timeout <= 0 then + local player = minetest.get_player_by_name(name) + mcl_title.remove(player, element) + else + new_timeouts[element][name] = timeout + end + end + end + hud_hide_timeouts = new_timeouts +end) + --TEMP STUFF!! --TODO: remove then testing/tweaking done From d2f7d3136028f726d3aaba1ff7e4304e1952aef5 Mon Sep 17 00:00:00 2001 From: Emojigit Date: Sat, 10 Jul 2021 10:16:55 +0800 Subject: [PATCH 042/296] Fix warning in `mcl_end` This fixes: ``` 2021-07-10 10:00:58: WARNING[Main]: get_mapgen_params is deprecated; use get_mapgen_setting instead (at .../../games/MineClone2/mods/ITEMS/mcl_end/chorus_plant.lua:456) ``` --- mods/ITEMS/mcl_end/chorus_plant.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_end/chorus_plant.lua b/mods/ITEMS/mcl_end/chorus_plant.lua index 24307b5ed..4dc54db18 100644 --- a/mods/ITEMS/mcl_end/chorus_plant.lua +++ b/mods/ITEMS/mcl_end/chorus_plant.lua @@ -453,7 +453,7 @@ function mcl_end.grow_chorus_plant_step(pos, node, pr) end --- ABM --- -local seed = minetest.get_mapgen_params().seed +local seed = minetest.get_mapgen_setting("seed") local pr = PseudoRandom(seed) minetest.register_abm({ label = "Chorus plant growth", From b6eb0ab66ce4c90741a71928913615a6cdf37fd7 Mon Sep 17 00:00:00 2001 From: NO11 Date: Sat, 10 Jul 2021 15:12:41 +0000 Subject: [PATCH 043/296] Fix #1808 (Make end credits speed up when pressing jump) --- mods/HUD/mcl_credits/init.lua | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/mods/HUD/mcl_credits/init.lua b/mods/HUD/mcl_credits/init.lua index 294373875..633a68c8f 100644 --- a/mods/HUD/mcl_credits/init.lua +++ b/mods/HUD/mcl_credits/init.lua @@ -156,7 +156,16 @@ function mcl_credits.show(player) offset = {x = -5, y = -5}, z_index = 1001, number = 0xFFFFFF, - }) + }), + player:hud_add({ + hud_elem_type = "text", + text = " Jump to speed up (additionally sprint)", + position = {x = 0, y = 1}, + alignment = {x = 1, y = -1}, + offset = {x = -5, y = -5}, + z_index = 1002, + number = 0xFFFFFF, + }), }, } add_hud_element({ @@ -216,13 +225,24 @@ end) minetest.register_globalstep(function(dtime) for _, huds in pairs(mcl_credits.players) do local player = huds.player - if not huds.new and player:get_player_control().sneak then + local control = player:get_player_control() + if not huds.new and control.sneak then mcl_credits.hide(player) else local moving = {} local any for id, y in pairs(huds.moving) do - y = y - 1 + + if not control.jump then + y = y - 1 + else + if not control.aux1 then + y = y - 3 + else + y = y - 8 + end + end + if y > -100 then if id == huds.icon then y = math.max(400, y) From 357474e32f5ace629711c409bfe28908b3f072f8 Mon Sep 17 00:00:00 2001 From: NO11 Date: Sat, 10 Jul 2021 17:28:24 +0000 Subject: [PATCH 044/296] Add better credits background --- mods/HUD/mcl_credits/textures/credits_bg.png | Bin 0 -> 63056 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 mods/HUD/mcl_credits/textures/credits_bg.png diff --git a/mods/HUD/mcl_credits/textures/credits_bg.png b/mods/HUD/mcl_credits/textures/credits_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..ad74cbd3070227751113b46a48353ed8724f37db GIT binary patch literal 63056 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

_%cp93MR!&A(7A2qK7s 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 Ro{0be002ovPDHLkV1ldgMFju= literal 0 HcmV?d00001 From b7e6db537b65f4ea7cfbaff9dba588138a1d319e Mon Sep 17 00:00:00 2001 From: NO11 Date: Sat, 10 Jul 2021 17:32:01 +0000 Subject: [PATCH 045/296] Support new credits background --- mods/HUD/mcl_credits/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/HUD/mcl_credits/init.lua b/mods/HUD/mcl_credits/init.lua index 633a68c8f..40373df16 100644 --- a/mods/HUD/mcl_credits/init.lua +++ b/mods/HUD/mcl_credits/init.lua @@ -142,7 +142,7 @@ function mcl_credits.show(player) ids = { player:hud_add({ hud_elem_type = "image", - text = "menu_bg.png", + text = "credits_bg.png", position = {x = 0, y = 0}, alignment = {x = 1, y = 1}, scale = {x = -100, y = -100}, From f46c4ebad7c1b1539062f7f9c073f9c61715ffd4 Mon Sep 17 00:00:00 2001 From: NO11 Date: Sun, 11 Jul 2021 11:11:22 +0000 Subject: [PATCH 046/296] Simplify code --- mods/HUD/mcl_credits/init.lua | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/mods/HUD/mcl_credits/init.lua b/mods/HUD/mcl_credits/init.lua index 40373df16..929a9992b 100644 --- a/mods/HUD/mcl_credits/init.lua +++ b/mods/HUD/mcl_credits/init.lua @@ -232,14 +232,12 @@ minetest.register_globalstep(function(dtime) local moving = {} local any for id, y in pairs(huds.moving) do - - if not control.jump then - y = y - 1 - else - if not control.aux1 then - y = y - 3 - else - y = y - 8 + y = y - 1 + + if control.jump then + y = y - 2 + if control.aux1 then + y = y - 5 end end From 46d48ccf2f62a80b6710c4b7bbe12ca3a6417aa9 Mon Sep 17 00:00:00 2001 From: NO11 Date: Sun, 11 Jul 2021 11:42:12 +0000 Subject: [PATCH 047/296] Add support for translation --- mods/HUD/mcl_credits/init.lua | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/mods/HUD/mcl_credits/init.lua b/mods/HUD/mcl_credits/init.lua index 929a9992b..235b2a3cb 100644 --- a/mods/HUD/mcl_credits/init.lua +++ b/mods/HUD/mcl_credits/init.lua @@ -1,23 +1,26 @@ +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) + mcl_credits = { players = {}, } -mcl_credits.description = "A faithful Open Source clone of Minecraft" +mcl_credits.description = S("A faithful Open Source clone of Minecraft") -- Sub-lists are sorted by number of commits, but the list should not be rearranged (-> new contributors are just added at the end of the list) mcl_credits.people = { - {"Creator of MineClone", 0x0A9400, { + { S("Creator of MineClone"), 0x0A9400, { "davedevils", }}, - {"Creator of MineClone2", 0xFBF837, { + { S("Creator of MineClone2"), 0xFBF837, { "Wuzzy", }}, - {"Maintainers", 0xFF51D5, { + { S("Maintainers"), 0xFF51D5, { "Fleckenstein", "kay27", "oilboi", }}, - {"Developers", 0xF84355, { + { S("Developers"), 0xF84355, { "bzoss", "AFCMS", "epCode", @@ -30,7 +33,7 @@ mcl_credits.people = { "Code-Sploit", "NO11", }}, - {"Contributors", 0x52FF00, { + { S("Contributors"), 0x52FF00, { "Laurent Rocher", "HimbeerserverDE", "TechDudie", @@ -64,7 +67,7 @@ mcl_credits.people = { "NO11", "j45", }}, - {"Original Mod Authors", 0x343434, { + { S("Original Mod Authors"), 0x343434, { "Wuzzy", "Fleckenstein", "BlockMen", @@ -96,12 +99,12 @@ mcl_credits.people = { "jordan4ibanez", "paramat", }}, - {"3D Models", 0x0019FF, { + { S("3D Models"), 0x0019FF, { "22i", "tobyplowy", "epCode", }}, - {"Textures", 0xFF9705, { + { S("Textures"), 0xFF9705, { "XSSheep", "Wuzzy", "kingoscargames", @@ -110,7 +113,7 @@ mcl_credits.people = { "yutyo", "NO11", }}, - {"Translations", 0x00FF60, { + { S("Translations"), 0x00FF60, { "Wuzzy", "Rocher Laurent", "wuniversales", @@ -150,7 +153,7 @@ function mcl_credits.show(player) }), player:hud_add({ hud_elem_type = "text", - text = "Sneak to skip", + text = S("Sneak to skip"), position = {x = 1, y = 1}, alignment = {x = -1, y = -1}, offset = {x = -5, y = -5}, @@ -159,7 +162,7 @@ function mcl_credits.show(player) }), player:hud_add({ hud_elem_type = "text", - text = " Jump to speed up (additionally sprint)", + text = " "..S("Jump to speed up (additionally sprint)"), position = {x = 0, y = 1}, alignment = {x = 1, y = -1}, offset = {x = -5, y = -5}, @@ -233,7 +236,7 @@ minetest.register_globalstep(function(dtime) local any for id, y in pairs(huds.moving) do y = y - 1 - + if control.jump then y = y - 2 if control.aux1 then From a0d3f517458de005d130361cf4d96bef17d6f206 Mon Sep 17 00:00:00 2001 From: NO11 Date: Sun, 11 Jul 2021 11:43:28 +0000 Subject: [PATCH 048/296] Add template for translations --- mods/HUD/mcl_credits/locale/template.txt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 mods/HUD/mcl_credits/locale/template.txt diff --git a/mods/HUD/mcl_credits/locale/template.txt b/mods/HUD/mcl_credits/locale/template.txt new file mode 100644 index 000000000..3ee9fa56c --- /dev/null +++ b/mods/HUD/mcl_credits/locale/template.txt @@ -0,0 +1,14 @@ +# textdomain: mcl_credits +3D Models= +A faithful Open Source clone of Minecraft= +Contributors= +Creator of MineClone= +Creator of MineClone2= +Developers= +Jump to speed up (additionally sprint)= +Maintainers= +MineClone5= +Original Mod Authors= +Sneak to skip= +Textures= +Translations= From 848f1489e861d78fba56bac9d27886bf5c5dd909 Mon Sep 17 00:00:00 2001 From: NO11 Date: Sun, 11 Jul 2021 11:44:00 +0000 Subject: [PATCH 049/296] Add german translation --- mods/HUD/mcl_credits/locale/mcl_credits.de.tr | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 mods/HUD/mcl_credits/locale/mcl_credits.de.tr diff --git a/mods/HUD/mcl_credits/locale/mcl_credits.de.tr b/mods/HUD/mcl_credits/locale/mcl_credits.de.tr new file mode 100644 index 000000000..6a38d18e6 --- /dev/null +++ b/mods/HUD/mcl_credits/locale/mcl_credits.de.tr @@ -0,0 +1,13 @@ +# textdomain: mcl_credits +3D Models=3D Modelle +A faithful Open Source clone of Minecraft=Ein treuer Open-Source-Klon von Minecraft +Contributors=Mitwirkende +Creator of MineClone=Schöpfer von MineClone +Creator of MineClone2=Schöpfer von MineClone2 +Developers=Entwickler +Jump to speed up (additionally sprint)=Springen, um zu beschleunigen (zusätzlich sprinten) +Maintainers=Betreuer +Original Mod Authors=Original-Mod-Autoren +Sneak to skip=Schleichen zum Überspringen +Textures=Texturen +Translations=Übersetzungen From 5ceb48fcb13ae20a4295cc7c0d4cbcfa30c26a8c Mon Sep 17 00:00:00 2001 From: NO11 Date: Mon, 12 Jul 2021 18:05:52 +0000 Subject: [PATCH 050/296] Faster rgb to hex --- mods/ITEMS/mcl_totems/init.lua | 61 +++++++++++----------------------- 1 file changed, 20 insertions(+), 41 deletions(-) diff --git a/mods/ITEMS/mcl_totems/init.lua b/mods/ITEMS/mcl_totems/init.lua index 2311e88d7..5f9b254a3 100644 --- a/mods/ITEMS/mcl_totems/init.lua +++ b/mods/ITEMS/mcl_totems/init.lua @@ -5,64 +5,43 @@ minetest.register_on_leaveplayer(function(player) end) -- Totem particle registration -function rgb_to_hex(rgb) - local hexadecimal = "#" - for key, value in pairs(rgb) do - local hex = "" - - while value > 0 do - local index = math.fmod(value, 16) + 1 - value = math.floor(value / 16) - hex = string.sub("0123456789ABCDEF", index, index) .. hex - end - - local len = string.len(hex) - - if len == 0 then - hex = "00" - elseif len == 1 then - hex = "0" .. hex - end - - hexadecimal = hexadecimal .. hex - end - - return hexadecimal +function rgb_to_hex(r, g, b) + return string.format("%02x%02x%02x", r, g, b) end minetest.register_entity("mcl_totems:totem_particle", { physical = true, collide_with_objects = false, - collisionbox = {-0.02,-0.02,-0.02, 0.02,0.02,0.02}, + collisionbox = { -0.02, -0.02, -0.02, 0.02, 0.02, 0.02 }, pointable = false, visual = "sprite", - visual_size = {x=0.2, y=0.2}, - spritediv = {x=1, y=1}, - initial_sprite_basepos = {x=0, y=0}, + visual_size = { x = 0.2, y = 0.2 }, + spritediv = { x = 1, y = 1 }, + initial_sprite_basepos = { x = 0, y = 0 }, static_save = false, glow = 14, on_activate = function(self, staticdata) local color if math.random(0, 3) == 0 then - color = rgb_to_hex({ (0.6 + math.random() * 0.2) * 255, (0.6 + math.random() * 0.3) * 255, (math.random() * 0.2) * 255 }) + color = rgb_to_hex( 153 + math.random() * 51, 153 + math.random() * 76.5, math.random() * 51) else - color = rgb_to_hex({ (0.1 + math.random() * 0.4) * 255, (0.6 + math.random() * 0.3) * 255, (math.random() * 0.2) * 255 }) + color = rgb_to_hex(25.5 + math.random() * 102, 153 + math.random() * 76.5, math.random() * 51) end self.object:set_properties({ - textures = { "mcl_particles_totem"..math.random(1, 4)..".png^[colorize:"..color } + textures = { "mcl_particles_totem"..math.random(1, 4)..".png^[colorize:#"..color } }) local t = math.random(1, 2)*math.random() minetest.after(t, function() - self.object:set_velocity({x = math.random(-4, 4)*math.random(), y = math.random(-1, 4)*math.random(), z = math.random(-4, 4)*math.random()}) + self.object:set_velocity({ x = math.random(-4, 4) * math.random(), y = math.random(-1, 4) * math.random(), z = math.random(-4, 4) * math.random() }) end) minetest.after(0.3 + t, function() - self.object:set_acceleration({x=0, y=-4, z=0}) - self.object:set_velocity({x=0, y=0, z=0}) + self.object:set_acceleration({ x = 0, y = -4, z = 0 }) + self.object:set_velocity({ x = 0, y = 0, z = 0 }) end) end, on_step = function(self, dtime) - local r = math.random(1,50) + local r = math.random(1, 50) if r == 1 then self.object:remove() end @@ -79,7 +58,7 @@ mcl_damage.register_modifier(function(obj, damage, reason) local ppos = obj:get_pos() local pnname = minetest.get_node(ppos).name -- Some exceptions when _not_ to save the player - for n=1, #mobs_mc.misc.totem_fail_nodes do + for n = 1, #mobs_mc.misc.totem_fail_nodes do if pnname == mobs_mc.misc.totem_fail_nodes[n] then return end @@ -95,14 +74,14 @@ mcl_damage.register_modifier(function(obj, damage, reason) end -- Effects - minetest.sound_play({name = "mcl_totems_totem", gain=1}, {pos=ppos, max_hear_distance=16}, true) + minetest.sound_play({ name = "mcl_totems_totem", gain = 1 }, { pos = ppos, max_hear_distance = 16 }, true) --Particles minetest.after(0.1, function() local new_pos = obj:get_pos() if not new_pos then return end - local particlepos = {x = new_pos.x, y = new_pos.y + 1, z = new_pos.z} + local particlepos = { x = new_pos.x, y = new_pos.y + 1, z = new_pos.z } for i = 1, 150 do minetest.add_entity(particlepos, "mcl_totems:totem_particle") end @@ -113,9 +92,9 @@ mcl_damage.register_modifier(function(obj, damage, reason) hud_totem[obj] = obj:hud_add({ hud_elem_type = "image", text = "mcl_totems_totem.png", - position = { x=0.5, y=1 }, - scale = { x=17, y=17 }, - offset = { x=0, y=-178 }, + position = { x = 0.5, y = 1 }, + scale = { x = 17, y = 17 }, + offset = { x = 0, y = -178 }, z_index = 100, }) minetest.after(3, function() @@ -131,4 +110,4 @@ mcl_damage.register_modifier(function(obj, damage, reason) end end end -end, 1000) \ No newline at end of file +end, 1000) From 960b653979a7285d6fa785ce5cff83aeca4cb80d Mon Sep 17 00:00:00 2001 From: epCode Date: Mon, 12 Jul 2021 11:50:37 -0700 Subject: [PATCH 051/296] fix #1299 --- .../mcl_armor/models/mcl_armor_character.b3d | Bin 493300 -> 554680 bytes .../models/mcl_armor_character.blend | Bin 1210268 -> 1242020 bytes .../models/mcl_armor_character_female.b3d | Bin 493300 -> 554680 bytes .../models/mcl_armor_character_female.blend | Bin 1210092 -> 1242244 bytes mods/ITEMS/mcl_armor/player.lua | 4 ++++ mods/PLAYER/mcl_player/init.lua | 4 ++++ mods/PLAYER/mcl_playerplus/init.lua | 12 +++++++++++- 7 files changed, 19 insertions(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_armor/models/mcl_armor_character.b3d b/mods/ITEMS/mcl_armor/models/mcl_armor_character.b3d index 95f763eab25205397a85236cb0f610212481e585..b3a943f4679e6484c8f6ae37e0879f3249427407 100644 GIT binary patch delta 106756 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 delta 64362 zcmb4McUV)``@eyU;3QFF)G)<8AaH^MF5ZBOySVqD)>d1sb++0fH{#wX=v8YKaW6=? zH-JKfy4yO?I$K4wt~zlu#QdK3oSR5e;mhw29`19_C+|JuJ@0$okvEx7eP6Hia*c>U zU7sv+UE{jidBh@DSzBbzwkO*9lrUYy z)MVAHEizZzlbiJ^p^1s0YFJxjHEmC|tWOCSP4yGJ(i+O@SX*T7wkNsuDIqSMpz2y% zWc6%M^{r0{K^X+qz}g~H*`69&pAzm!sK(Y7ncDW`VSP$in@MPSSzBb@wkIF!Q$oZc zf@)%Ik@?x4np&R{ULGPV(cIc1Yhin8X?;paK1@)ptu3-Pwx_n%r-T7nZ*`Bnvr(oMtd)re7+fzr|QzzR~i0vuV_Qcqp!fa2SZBMN2NoRWs zw>?GJp1Rncy4s$)S)UTNXB4V-)>xTqVl%BQzJ+W}?pDTYm{KR5G7gzR7EtXMKMc7>y zj$J%tqeNF}u?ZWez>oX~6$p#T>imr*E=*6iZ zrQB$#1iSkM#~zxrpUd9$!h#M>YGb6FDqf?LPdIkel#|&fo>kQx>kZ6bBbdX zy4L1Vrz}XJ+xNB6trD>AILBt)^f&8{TTs@`6l3*Duzikl>{cPr-0P?XZ552h8V=Zm zNl!fFH60thUwJUK92(0{ZPam&ZD;Z~k34Qc?Mx}g+78%+=TAK3bsQVjPd()Bj*Y7y zd&uREjblqaIE6!F`STjLTzW>OgMBJ??V|@p3g8O?9xze#Q^t}hyz@f4Ha4!~dY|FUm*%yl}sAb$s zgQ^m2QYpu-85x$nwbX*vjx-w@R)Sqy#<5=YYG z9xk$2&`_={#j_GDtl%(t%pnV42l7RGyC8t*x-EXB7H>@`cm@DFvkCY3;7U5mZQx)ynTNcF1(3;T6l+OKN|x*3{Q zf(1rsW@Uut^;R01RRRVMTPJbY`jKWs^GdLeoZF%jtnv-VHeZ&|_k9g{O9vPn8?Kc@ zWBC(O?%?5b*SZp{xmQi~Amv@z8hfQ`jpSx;7!zQmb zwsXK@S>^B8nDy9WVt_+q`Kg&saV(SF%4|AiK}_~uqoxup$W?zyuKJr&jDZeV5X|x* z$HqxdJSHNC#_}WRca&pgDS_tCj#`i`#c0%4f*o_5V_nny&0~&RkZW3sG1vjiKkiwH zdhC9NV>b&;%-zpe&}Jdo*umk`Irjhx#3l_BO%tm9!O0dOOIrerFcXRPo z3%cE8HD~Np33z@!$7U5endj$QP*!1_F{Bb~wR;>}>h?IBzGp!tZj+3mm0;UF=GeNi z=d#;9<}64N`|Jcdcko{8y}S~%8X;n)(d*w8o&mvgExDYdb0G6JiWqV!x29TCHf z)2_86eC@!A(DNU-oH64{Qup{IBQRTm@aymxW<>o~CK!a3aI<=~nYCqHj=~sZ$oEc0 zV8{ZtPDBjzy3=f-Ja+xaFea&#%Nc(CJHvLbWb{GC5wL4S3{&(Z4*|GLT8UP1)0vA! zT#oDdjfQ-WWCWHh5Y7*eVWLZX?N+V%vUQB|4VQE0YqKG?aWVo!7O;ikF-%C~eRfz6 zQyMd|kjuF<@{VCKr%Fa($pW}qL=2Pk?=CzDnB4~p$IiQTp1J>s%UQF_*;u1~G6GB1 zI*3ADz2Ne*`?vWM=EPktXZmWTv6Va-fguZ6SP5O%F?iLi+x+K9=deEcTn?un*WBn{ zD;a?$3t+#97{>hYE4&@nl^8zRJuL4kmlMA)*!adZ8M#Q3x7264C{D?%bBJ9%($6KMquOuczbvZ^Htze zfe$<{tKW6?hatva%eEn~YOSO`yS&VfV>BlJuu;dkoCm!|8@HEkLtxbc_9AT7rC);h zzIvI5C)lsh`YJqz`Qc4tyn5CZ3FDuSa%vErQxG1*bZPj`Zp*$(2@LCZl*>`CdSx6^ zvJHWC3v_OW$1rbecE$@(BJG&JG?K*!Uf_{{bqiQH6v|j%-nX`sl54m48J-eYxzKql zJcfB{>Sg!R3x71hixcSg2rmv8zkv0Lh+%%2z5`>ehrqh(qgLHD%IRbTHZfoyhQ~11 zYNQ4Mn^-40bh0~#w==Wgrt!6FG6Gu}z`(3WUcALyWCdIK3#+vn$5!lKAE((ufmh`^L z7yKYoss`-LGA>pnBe0pF6OLZ`pXvN<+DXYDadUE;2!=ECybF(EibvJ3W5t%z0j@D) zuknUQG6KUHu(F64=7~bEhnj%YmgswFG8zqh9_z(KlHDQ`ri3B+M!Z z;q%+K9t6T*Dg*XY13o7WxJXhvU@8L^R-(kZ63r#a93ttRhmzg_qZz=`67#+zoEmYU zWWYj(4%kJ2`pp)SH_~%)^9Wbi-Ls=*z%07x+^Iau#2J7?ugt5Euu`%LblCV>vt^Aq zI9Ol|Lq}yNcE)NYKCxg70~RE~76(aiNzxc`lEMI67_e>;G0e4^_98}77+lWUeZj_8 zuE_|DVE|VqyFg=r>;fAZupkp_r+-=|&Xg1en9hJb6duF8nQO0;!?JnyysR3xLQ)@K zIs+Dj_Ol9v_M={-jmf3k5SY$@txOqsxPNXOT(S*;MGe?bDwTafJ;RcI<#Hyqdu@DJ zybXb+Z5_mbR`y!v-9e&dF0Uk71}tsB?hB7$zU?`?D$IO}%Q??IGoCElhT2Qmzr$mgez*JE$*T{BCSg6#a5V zO=CT`WCT_>U>}6XFm>)_*b#1Y&nawaK9`gA^0Ki*tz-mNH()&?VwlO(zQO~x$)Li2 zA2GG>aXBxho;41YCnGSs0sI&Sv1|<{Y?ZKCL(eh6kGY)5UmiDhuAhv+>IUrj@EGQ= zyA83vuwF;ry)ZE8g^BVZrvVDi$086=OO3`vLDo!$&eEL^|cWL5G>u>PRfSNzu}!GTl4!6(5+ zz*S`DmsqD-S-JwB1luMehPg1iN-f19h=CGknZ6}TimIp7Lh5}58=>q`6&mxOhR|KpOt`}C*7K2_k7z&k$V zT$NlBShzfM;G~LN5|y&3gG<7W(H&h9_D96QC1E{m|8YrFdSV@15?B%(b&v!VxFpz? zAYz`|i2bTov4Pv7Lndsn>z{0gndp|q*S%FJ}1((F(3WT8kT8LJR)B00VbSH8l&4#_3Kg1w)Be!`QpYUD?0{$Zn!b2;k$ zb`A;_927V99Vn;0IX$~UY!!C+6qhqN?wRq#M-K(tI3k9LpE}TP)fyab64vDmms6s8 zWZeGIL%~jph+%HVw<;&ZId;*tMqx)Ua5;VF+%GkWb=V~>vx3Kkp`@xg1f*oL<*vCm)U81-W=XWy#h#|#y1`|4+Xx~Y(7mq6jtog*C9-HDVGzqE6FH)^iZ%6zLG}` zv*U@^#Wk3nWn9j*S{sdzYz_*J+?r>`5D$fQ#7(1)hF<@`<;c_nCUtv^#^iW{oEI2qQ5@oeQ|FUp7@oSeD`+|3h{1^Kv z8(#8I{1@!7cd#9jhoVYY$w6U#=jR_azTSm9Ub7!iwc8wc#ZXg%w;W zR`O6(2`f1$SSo_6kTY$}CV42TL|F1rR0)e66zwWM9=1V%hoafsj3+-j{e(RfU&lMe z4v{tIbN4x^!nc{VY@0s8Y~b2=Lh7RN0whW_y|-5D8+%Q+apOjuOaX}x@Hb(ymZg3P zX2VXr6AJfyAwZ%;Yd$y8Nu^xitYzQP?b)1aMZ&+!#tD!Y;lmgF<)jK179+MH*Pi`x zV3BaB)8_(YK{S!xu-@Sf)5?Nav04ZAi#_dT>@^+lK&JP(K(tl?F`cdgyK2 zusEev z-;Ry{EtEB{D;1o&3=kl{L2dWKk2z!KlG?H7y%^U2w^BjXr@sK{4b~MZ$090BJbOqx zw%!*E+v{bi@MK{>!Oe-6op);dO_WbNw&6O49U*@&jC&m=KxRW*X*H4@R^$4Iw(Rc$ z!=7sLUU;@CN`QO^SdCBdQmaWZR#@YnqNzWV^jMJkk#P9>mE3%lr0+gvz^mI+3kxb5be2#%S2Wm7UlhI+X}h_Y4yt8NrYD z$#7CBE!6_q>rXneeXkS?gQt!VAQi!H{Us-rvTtf2+p>2@cHs14VR4610;D2%^0`}` zRLa-=gV-|%JFpw&#X_gT(E?;1`0<+KPO9*3kAm3gjXJO%Vv(?We8m&Q?o+pCU6n<`fIi~{NHTyk4I6DePF9Y6*iXy$ z%?xH|U3n)w9sPv>Nd`^vyz6Fc)w1ut4rZ(Ed?%D>#|s{W=alMeS~fQ@nEh$qJHhGv zcmdJ}{4ftF&lPLghVo!mGx?q1-sVdIvIYG3=(kQP05%9}PO(63;lA%6d9?ttKZ1uO-jd%}oy9T~AT;oWdY-i1JYRrwzR^?rPGf|E*F z{ut>l4iq3PU%}ynD7@$TwN9#V#}f-NcX&65?s8J>lcyeH?$Xp8g-0NfH{UwS8wjUY zRc1jny_qx=$HSwxv}IRGa%{)XQ39B*elQ{Bz$We3&It?~=KfyzwKz(ENP06YXOz80 zw_|ILX4pN?N`KLG;gUih^ClG={-Q!wm{+)^QHMt=dqNEFU01P~01zmhjH&{MkB8C@a^M3f=x5C_oGx1`JHR%|Uoy^$TE)=^LKUE$_fiO(_!o*)>*x;B^bUNZ8sKi>%lzWG9cP_-Yg zJL#kf-;%6l>rDt|(e`)317^GcfoZ=AB*^^hT6TmcnBAyToFz9S8S-D#n}_qWni%I0Y=CC|`^Cli z_Dh`m2gZIY(IxrXWO8?}>#-xvHeh{zbL=*3d5#Q%&|lf1$loh$=4=y3zvqK$8s!9>9Gej)JzDId~E_Abl^yNFiTN2 zTfpe)g9J;mx5@1GY;?fp*1_1K%>+xbw+Y?5>bVkK&T3gHFgQ1xfWgR-Nrc~Zb+udK zchc;xoFN@N#0}-{Wj%mvD?VHAJ&za;-znsChsqjEN=pi zPRX|?tgnFw>~@y$1WEcPD>3;u$CaQlcI;d-2$J+o=yLUE4Yiw{b?w3Ha@t`TXybojo~{ z_$^TwOJc~jkx2v!q~#%r-_pn|4L&(Cy@Uk|(0W4UmVe7F51fA6jLBM(#BZ{ei#}Ad zC+x74Bo~|v!tlaTe@S~J4T9u?6YP{1%k2k&_nyTv*3qznWIDBr!Zm6ermKCGJR~xK)mp7v}gRNrF^TKO|F}5Y`N}Kl?TT zeUr!uk||EG{WjSPXq(`#Mg%{}6en1lMu7kWISlqH1#H`@sw$Ex?m*aqZvF~#4oFy* zU^BIz+K7)py=}xdB)vuw#|gOGP!kW6u1ZWAsxQ@8AAd!q6Y>0Fak zaYDH4mb3lrsA(9R=}g2a$rLB6R`0QcmezH_*kp1!=0uVzPQYUt<=Wo~sfHMQ>Ny!P zNfjqpS#eE=LEOQLr9cu|BvYJVDgB6)@(e@e{z5cXDMtvCRBcswdW1xzcu! zRB?i}YAkmWaCK-TkyVFA5<+!oB%xA=MiLWsXe7Z;hei_QbZ8{eOov7iwsdGD;Yo)^ z5{GnXBmqZP9BtA+v}oAwtUDA%eOn)i zoqljJjrUbyETnkASxKlK%bwA_H&e3>E}?&GYiIMu3(oa9@VP_xO0QU!q2HRLua<-^ z%jl7Pm!c@ARvzNlr7OhDx!17CXvO{!7|XWKd2T*(y$M4{#bw{4D5{~^UG&fULfgPK z15d~LTDLB-?A|5+nmyihXH-;D_I-+?t~YcR4{z>ndgv+lu$xc20kQ1xssETGM@?ql z`8F$mX>ds+BT+w=Q)gz#1vWzTP7 z*}bQ)nuVeb%=hPBXa7r4RM&s91pOEF1)t%M>}K=bj9B(=pNr=22km8=#=4pxQ51D0 z?}|2IU4nQ3RrjZPD zv`RChI6ADf&LHz^ilV-Gyj=df*e2bkYb6m@m_ zO3`D*2GRFtZ`)U=0K0WXEZeoYXx1dk!ZOB0ncq?rwa6n{d$(3C(@dQc;Y%0*u%2>7 zEIVyyy1Bz2rA)UUd-6V)os}w>CUo9h7RxsBJ#5aO|AP5d7tZ&&?A!=5t$s-?Ygu{3 z++zA&X4@a_&Bb6QoS!HxyVc8-*Y~vm)U89Gw;-0?aP64c>)a(KqkC&}2}Mzd?%vQ| z8{14+Qd(%ouw!Cl*`{}YGv9c0lv(voZ7!uKD);wYg04_4$fKSDmJo&)9GDf$PF$8} z-rFISX{N1Zeos+U_VJ^_MX#QwhtdDq1_86tz^U1M)x0BY6Eo+^+w3xmqCCUo+99vw z#mv6Puu(E z@JFMW7i)~X{))3wW$jGw7|TX?d}_Y)3^8oUYW~0#Y5h7hi)GQ}SLP0LYcaPjMQ6)o z6jgUuQ!&P)nkkyPVz(x_idfd|a`smX7 zELuiUzduRRPA%$cO8VlA9pSj!bJ?ELosZ~!FNN&NX~i$O>g*Y+zdDyae2_l!$PyZ| zX!`oY)npVEpFR<_3|}fTPaD}0`250LHu4*nBRld#I(6gM@da0%8)1#n&P_&9ryKmD zO-$-)N_tCP3v+=#_*D0AT#j_U71HSdzwS_Ve%V!LH3u&~bdWx>)e;&KJbnG)8ZwI7 z)4a2o;QCW=yK^K>&$4w!LreO!zQcA^R_b z!y90lz~D>o<(r*1EnqqZU&^j4qo|q3j|#iP)`};0pTP3jn&|`wXV2!V=49#M)Pv>w zeV0Jz^fWOC@RjnvCvsPZRK`zR%UmDU@3&4`OY4OuuV0VZF+};JzWSZotdvny?fZAM zOK$Zt`CNCwgRt&lc@dJ?y|uZ4jH3FteyGii3l=6Ke&l868ueguRNA@DJOJ2#pHuQ{$`Z zE`27LhuoKiwZ0Q&_L5PQf0xx_oJSv1#!ucRz*t3d#EMw<$Xk2Ncb$FfJaWtt~Ef5Wu>y{p+rMp62}R>Hw`HBFj*MRpRi=CW9}|BWnjzX?wm__nhz z9EHfwv{6Y5O@%2W6&BtL%=hQwShoNA9CN2HZ!8(@UiL*=cHW%CA{HeXwHifNkSZEh-~sCiR%iMn5Wgz&qb zb~6q8F_sbE#95w4@G7Tv53xD zDpG%(wHt}k&ADtR8GU5a&s#!tSIhX^d`SyrJk56=-=tR01M`LNC)N#)PaKZ;c{S;J zT+<1@$wJN_$PZ#^DZ{&H>;0xi%lOfDS27re6QvITtkbHE+aZ>AN!d&Li|cKHdfzY& z`mGB~u=ksO1=zfvO(DncNrM4ef4;4_Yb)`we8fU_G(~BEux!h(J0X@ft>H-RI%=I*1u9+!QwAa%x2$?>SU<*#~fKZye$KtdP^WTWI znsoX&Iji$ZMrAaEY*$%QwOtTP%WHbpc+W3d)GQ(2n*xF#|E@QK0aMhqCJ;-@+cZD$ zEA*x4^NrEQ=T@u}^&Zppq5AkiC@sllLeQC`zG=@+Bw*IH8But|RGsE9yF!a)JH*m% zw_Bk-y5go#{{r#g!b-s3GYiLd?Y=l<*5u8drtXVB46(HKSK_sWCpRJ=T~1p06?^!B zWAA>L8;T0nhDB1mxOu_dyoyWv{#v( z#oYZz4NcBB5Ur~K*ilA~o&Qa>um|6(nf^!I%@9kg-*Yj#bYK>0vEwzCb%2A<%wNZ` zSHAQJ`|%$w>HiuQ>E?SBrLf-Vi)s>q;bAIQH`io}meD?L!s~ zY?;MDEUjV9ndrwxKEZ2?hS*jDh_`#sv6DlehGqp+58Z1l%Ys;%&xP8-lRrdgclfI? z)=K!)D~=uJJc!v5JS%kLp>f#|OViZWp=Ik=AYH*T8)E`p-}@X}v(qM~#n`mS(3B@T zvLTkH6%w?qyccQ*MY`F9DiCjXiDSPvon`|39)>$xM z7h27=RBi}*bMrTC{e6Wt;{e|GdLPI7pRO5}y5E=S`;*cPQL{%6=W8F#zoAVv%*U^@ z-iP*X;8@SPjl;eV3S#8PnwlYMw&9x?ZQHVJG}Yx47B$u#-Lsry<+J_5f)rs)$$5Xy z46!ti7SpsVodQh1H~iYR@-PV4(cZV4hqaM*6k=&l>Yq&ue?3CzvwW>>z(D-m3XZL| zw@Fy0FT<>Q+0G2HwEe?JY3~*+5qnJdC_aF$u$g21-Be*|DV#ske7>(4VriztAfZj@ zm*SpSnH|3_PUG0WCb@)->erZgf3S`jVrdgk-_v?6Un>-}m|%Cn(C-|}M&~n88!2Y} zxu@9>OEavTB>Yyrm)7H(DR|YaDvC_&`x1$JX zkz+&LJ;TQD4raQ)X<_ztqNsHloN#AI9g`a(Us{HjgUl;C$gz{VRS)Za+>3enM_n_7 z*u<5S1a;{m(c_z5wj~C<{uIXs{__tL@tZR z+aNH`m(GX2X_=c1F}4GVLBi$ZA=;#pZg|-M2Y=!dj#Z+C%olYwg?5>?DjPy<2ZoQ* zcI@o0?J=P`UN!55vi3WU^_v^a9DdM0w52j48$xV0CgvQt_{@8bm3v2rEuicmQ+Klsyv)VdQ9MxV(&?c^K5@YXb%5qGB_(H2yq z*JQabcR}E--ve7a$XOc`hgdme#Nmvod+?=!Lvd)92%DmVYuAcEV_3gTbwv;sBJqe7LFg~ zLMu3ky^UCxpncf(vNm4fi=~-$q@c@Ym`*bqzlWjsldoh$>}}mZ*Wd%oHi!@FeNJ0sKSsMUD(R=QRNm$KiN!x|1^Z$5uL46K&; z620Bl(RPM`u%m{9*qdhRB4frnGji*gVjD2<0cbeIM-6Ajp*Q*LGPYP1IjA+@v3dTY&|FNK0>q=KgP1cBnxl~Y_0QA^I9 zEUcZCk`~=I0keX29H6*7%IPhLsO<^S3$q{Y463z>e4!ZV!UREY)hBw3!-@++YWx?B zHs+L4=n+I>;#RO#akZ8d7ev$s^$XFq_~$EaL3~rY?Q_&y5K*gKZ*d6<7sTr-0)yfT zk`&i;;Z-(-@ycUiz}7*7-YO`kw;;Obh=l=QC$*#Ef~a44aQP8~;%YiKm^t*Ie`pJ3 zL^cEi%VVtrfX{&5a`(O-`dHFi5F;#)#ZGD~aZp?t9YYA*5IyYo%%ZU;cgqk;ac$uJX$aL?AzcE5|}$vZ`2!S7Izzg&P&bF{?@#!kbma zLe!J1Dj1@nRmDP(w2D~d4Z+hYg1sT8+GcJB*My#jzuM^3kq&Ck`%I==)`oB@Mcqgf zm_*%Dep*jjr94?8qTnMUg6JugbOxp2E?IwCr8urkNA2sG5ClsppK(GOf4e)aR=(Pl zj&|f`qJN-Svsp}M5_OAt-@$Y}_?l2o?SeFP`&Al(xG1H+E138TA+%a~)+rP5Q%nd# zpj7+-EqrPTujoOmlxLS^BHiyIf`})Tw^TGSiMkcMERup7=n#{rTf_&>rd3M!BWdV6bvlAzCROkTiAxB^do;Q=(ul4%G$0(D%=Oj+nbp_**_-@@ zu5>-cI=zVIU)hTw9!crOB9VWwo>nX4HHVPz%uEEKN6M>iFj=1Pjg zQwtgB-Rg7%K|{*56JDM*{JhU;m0XO=Mk{A!qE{3}t^cCGcKx@shoaVQ0nJJj5yS@d zi}oWEAIQ*Z#rHi$lq=hhAPh*o>?WFc&%v}>IcCX0RP&q(LBx;R+!XIiB3?#iG4UYaFjxDkJg$myE{s0g}dCu(81vHY)Lv`V3IJA|C(nGnSHs6oEL>AY+l ztycc^Aq#a~xeq}ok7~%{_blR#(`l8$#28WUV@3p#JBo@<%iu5kLaQ6O_0L8w)zcBg z=qRco-r!}|{n>n8HiWLH9NEQyq9sNKq&t3-sugBIsH`HZJUjfL0GUgeY9UYYl$iN;2J4-h_rKO$cIcRCG@~ z_?4Iq8;yREj=m`o5ro*N=p4K|3$OdL1-x$*T~E33k_nkRi3p-<)UIRr94&-%q*6AW zZbG-FhzMe6)Uq>pc^C8Bexg-M?_DBl{Z>RS&^7yK(a0p~;_%!QEnkT!#m|Hwa7KAN zLMF_R)%VsjpKX#dsFjK2_AdV)TCMy!BpuDGYeEpUq6)iWS+kOyvzGl1qelG<2!d3UAwqhO zYyz!P=7k+Z^KOXGG$;cd-g^W=z=@iA z9r1Y~w1?79djxGY8xe$-D9s#v2snHQlqt)y(2*$_NCjP6HkUs-X^8@A;Bf#!EQwm{ zhi57sgi&|)qm%3QAqXAm-yYXy@^e3@)ynlx(vj+PDuO5xRW~sW#KtQALN8h+|8i?4 zdNq7MQp-Le06YNid`p`_WY*br8OY^nDuPH5wSJulN?;y;VG^xUYEP#ic77Iuzz?N+ z69}hb13oZ{gv4|duSi4Q(B+n(HSxYNv|4dObqFmyz7Ii&hbs6^F!8^3q1B41+XU2N z!65|E9Ew_*mX4d1aqTmaw{kCnzzs$Dq-I#PiAs6CEDbH}Z$N&~rCW?Sb|Ide;%TG_ z9jl&&AV@>enWBIjhKD;xnR<@oZqMLsj5QJVR-4g*s(sC?8 z8?D=tfhXLR^7FRSYQA6> zO;?9l$7^mtpoq0LZ`ehR+-PQSxx&@AJln75b)+ge$5oxyE?=Xey_PiYvSjPqSd@^GVN9y z;sxO|zQre!=Wh?Cy=&ud*!Xy26}plvlIppLme)2(KY&1qA}^aytNFY{npT_~o-X~? zK|?H*RuKu^b*2feKQ2l?Z7>ygt>Hf(O{)|-9}&H|nIZj>!8IiE)7H>x<+C{^w7kS9 z{boTP)*nl;kl;1zXT zNwi_50dstM&LsWtfE+L68ghs?+!qn=W|DqqzzvUVEpJ>xtCXGh3aD^ty7aRGI@~p% zsG1J@($LM8M(IZca`CNkIgyq1wIZ5(VpE@{@E2*AwG^`z+}v0XE>FEF`-5U}P3rFwTI;S3+*!uEpd;iC>u! z>SmOF0w7P4&9EX0c9w_=C!|Xi{|zXeS9GM+jdbBAbUy5$RO){L7S78*4x`V`4D{}1 zhE(0(2kYheeE$$yrP#406FrlqOU3*tZ8~4pk5(%lIE$!ZmPsnxKS&h$+goXMxbtTw z)ZiR-{pIbXV%(2yt-snFk0*_Pb@=1r!(Ym={I zG{&c39Uey`dS(`K&did^?svq?u?EioGfCJ}0qxw9DOK9mX|4u2OG zw+qP?4DML%olLkG{*s)*HiHCM0EMIC{@0{ zCS8Y=Pn(+1#(O5I$o)G!Xu_Y$#5E!c^AV+z_T>7qoZRJlf1ZKX-4~?__Wcm3kOlZ% zfuVFgCHmQb?kWYTXni4;F$>92*&LgWwoT5EYSb5CfsufDK$e4sQd8!QU&@?3Jh>&n(0C@9k|U;fxjrA55h#qT^RF1ZVMBNcp^$Q<+Jg0 z7n1YcIZ#CWXjoRzUW>6|v6|ew`D77o=wp&9##3SjAHI!ND-*|vc z8M5+Wnp6tDrNljobzsDWA40~z(xuAp+0x;~7SW$Y2hrntCaKPQH2#!y=jzr!9mPbX zNM+rJ;VwPDasaJTJ~=OwSVSik+e!tJNgLfYs!>rw%^rC)@R+RIVkda zx>TM$9?QnnWC+1ajcE7FLsB*NL_8EN8naV7+(h@{J}Kv;vSl?V2U z=-}TbsfPMgOg)B}eACW~Xy#`oQZn66Q1J52bT#Kh!Vl_3uDWdW`iBf86&Oo{s|(18 zoBWyqbUo$X_J-|9|#Dw7QvXw6gsk+k>%eAA4_ zYpyJDKZH6D6cI^|r?B2nBKCXax^x5^NmAr}@TZoLYyI&pCiLith)AM*4ZObzL{B_B zU_vYUn-EEtpN^-$9ve;oG2OB{_UII>6(ZN4rqzleO^BZvAy=*r7~r`3vkZ-!{%)o~i^$f2g9?z~SCtyY}(y_EXx(QgdcfurlCjpXG8 zv|8SDfJ*c4CGDBG(DyfvwI0Cw9Xwbl0Kle}Ei@;7v_=DhD919sU^mk^(tPkSib z7c~!DRrtFBdus|#X}j?9x3pUMVM_Zz`IZ|2*j?izpsx6(@waGIc!4I!a57_nhWKn) zE$MoIot##WJruHm!`CycM&OHO?i%dCG03&u%698!U^2>HVKo9_YS@Y6PX~9$T?PNr zDrN2K836;wZ%M^Y9DREcJ~fSWb@^?1ppw3@ zXX=j#J~b70DMG$>HO&7lJrz4~zFQ$g@>8GCYDGz*tA_e6E)X0z^`~9ZcID-lX|?i~ zexr@KKkGE$!lCAx5iIyLKIsoyoTNP!i%iuG6EhbZuoGwP zQ85y)w{m$vfad(xC?j^@=uf6~Dci04fiL`>Rw=}*+Q8t*JE_=#(_^K!E1&zARx7^y zcY|h3HPe3VygA+}IFir1L#vfg5PNHtSzL-`kwm+veuh{rh?68S0 z5PIO(D!!l4-H__FKNUM`sF|oc-|r@^R%RSq?Egh{sfIXeCI!JVlWEDlr;iOt8NMhL zJ8I->wEXIOw5L2?t=T2E3cxNJ`3=;KkFM#WRv7<@($v^8${)LC^16zVeBldPt!OrY z4>&lyS}JzSh-0+f_`CoYwPL5(svTqaA{D!2k~*Yy<)bgro^?zIlxUqlcE&uMk;dmd zrah{6iC6o-ri0tL@_mZwHg4dHp;k;3_*>8M(OA>2>tJ15?1qVR6T9+;)3iG5HEr7O zpWUz>cEiNe2zYT8{{TlZAddw8tSr5%pm|E)5|04vo9Vb&D=p&Gd+wT`$Z-d;UnaN2 zI?dtF9t8Zs*9gG=82JKiBz~d$*B!TM0_KGUU|)=GJU_C#f$o$UIl{T%{#img(x!=>newg=zuBCS@?Z@v#q{N<1a zJ6m$QX}j}=d|IuD9`T@3cM2cI&?9<@acn{K?=wnrclu1Yl2#ez<{; zIz@XZ2H#IMJXDW1f|KRrAyrrpDY#j5o+@p3KItT_RtSY_G=B{n7Kq&}jrxjRc>O=L zS~1Ho(l~R=Mh$kcj9w>70$_`3tfu#eod)b)sZl4G?2f#7FBikkdC?l|Ug_9HIeX}K zL-O&n2JCz>c!=Hjey3=)f?wCdm}F^bz>b&PL`mu?|LRwg>N_sffE_MAC$M;%g{7-v z`||~wrYc5*oh|wh)Ppa~qt%M#U(M6BKEr6Rv!x&pb;p|UR>$L-X5QyC*w50hmDq)k zZ{ea=JfnjT6dwxKU>}RPTq}vBbE5(@XGR62VjoLh4=vGzO4FX10dNqolV!yZSh@Yc zYfjUu>aO+c`Jc!b5DO|R|77nIOy z#TV-I-Cv9{wE!PWwDT!VH!Kh3ana)L-#$-o0dAJrLG!fycePzSl-Y5ayMGQzYXR<- z$-+FWOXl!XPtYpGi)O~%V+S2>0dAKszWYgx#N_45W0|`PHHH@8e%U2v1!9S#Tsz^| z?mb9s0coB!UOx;3`8<^`$fs5E;U|yo{-*JP7T}E;^Th%!?|zx~P!4Wu-aYtWS_|;U z^h%k9^;-;nu~K8n-0gb9*aG`yl9p>h63xNup@>&IrM#wteQ}`^y{j0B?-Jo_3w8y_ zW9w^3Nt0v&-u}HLyMWEg%dSiJX9vKYfs`~cq=D?7iPf>9`{3Nv*KE9oR4}2v0zl(yR3%xajpX(2E^1|~8_|I+Z$t-@0wh!r3}rgj zcwt`+``S=2skVW5XGCdUC_McxV6w9q+_lmqFCM>>typQ2UD?ayh$dEZM0QvIU`zWL0?^OMg? zZlXzheA^)X!eby78H&{5iwys~8KNOoJ+#{Hyaq0dAEvZ7ZhuZ2Ndb?3+HT}J^5^~8 zhOUEkfuw-PK1oo!|MTXG<~3~!AdZ=Rd>xgGx4Uaa{>t#`lp)W--ZX0(iU#0E1z@&!Ym!PX@<2rW*}88&YHg+AXGmwH6un)O! zX|>||^1&K-DK1T+f2r-xM>lX$D__&WsWrCT2q0A`lJS*z7N1u}s}vpwLsIX)xsr;D zPUs$s-FS`MMJ=zjWmM|gg609Zyo7#($Uo1cJ-~wS&$~a{AF|w@H&X^lyYwz(|Ly=M zp#^reOnrcb0y+80bE5+Mw?AKyLh42kiTypFTS%)E7w^vwSW~bo09T37XG$EVj915{ z9$M1YKng;%#B25=J{1Zu12T@erjq&(?}cte@1Nn98MZ%PU?7zqBDCFz-j7#1X)fL` z3Lr%t&cPDZa#1VqOj;RmW75h1Qomu7L?5oL&z{QVT~#a<7BShT`}8MgFN?`!&SRGDX`1j*wTKfMYKY8b}3&(^mDmBQq#) z+U;tAq*lT*ZFm03Wm*jj82~&%$|4jBL`Nu7hF3FAF6*Wtzm=C81n-x>W#0YSnuMKyXh>;;J@|eF&F3L|o`&iI-RHWF`&R^;7(r#+OQ&DQVyBY?P5qVclE5J3(y8RQ#rr|5Cl z9AcV94%P+KjjbO@+$kPf=?3wd4))VuI2}M-DYJ?4kq1SN3pkN+F@Shc772KTHuwRRDILoW3mLTY^Hj;o!lUo8sGH--&H?Z1NEMPyXACeJKBJ#(tFlHe+APf19yC z<-g6i1i^osv0LT8&Dgc_-)8Jy`EN6JvDlj3tvmpUGZRawjC{sr1}?XkJbaa9w&*GxP+sWczP4mcTL zkCjUE>9|whH8aWkTTAm{aE-qg+k>UjeALfxFkz`QAI2sLE_UC}v6klZ;aA|5kV^C6 z$u0hEt36$Pe)I0I=l!BxcflZ}(tMckmU-mIGHpB|mFDyDT!RTqrTOqaYo>MQ=Z$tz za?$&HHU}n$ez)Pi4d>Gq$2>EvY$Cr{)eAJ8HyI}dHQhXSD zsgDCTw~hy{KzCZc2!o|sd>C9D$@0c8T$Ej=I@QLVa2d8(Slsz&=`%YHvDV%z8ng?~ zMykDsv2=G8Ar$Sr39o}xY!7#~?Cbu?sZLEl1ca=$_Apj6)Sdr)yo*xRJ3riZbGbcBV9k#^6dEg3*Q?FISgr#bF7#x+-f?qSpMXB=H?t(j|>Uo$S#9UXt|2P+A z!|3cKz_HeHd3bIGT{)3IuW?p3Fx+bj3?LQF!(=<(s>%QQrHfLP``h=J*QF|Xxbyo* zh`&A1r9qdIukc}%s^a0k!u2_JxyaV~Wz^v=c$=i6co>^e)XcGoh^i%8H&ED18O}i@xQ<;#+g9i_} zhIiTwEU3rDe0@LnqmNxPlD&60Rpy=Us zG+4R$o8|HY@=&Gu8^KoF`k}R1U+?Pe8qFXxQ<}YzXZH5X)~uo2?2Wno0|_%S)loL= z$xpUhKYPow+VBQ9$u3lyyAeSza^&x9FFIP~=5ChPcL-K#?nV@fI-@x?l;&>n4<-|5 zReHM-?1txCt*buwt{&_dNus&Z%Z-ecd-#`V-P+i*T5!NP@(`tY8yQS}C2Y5@Xy{q3 z`g4XzRhqRCZI`^(Tjze}UA_9z-6TdR&Dn@!%ob`}A0&7OSC<2=(u<7@J;_PkZY^x& zSuMEv?lo`{rS}?<`RcP(qP1Hi&uW4aBb8=rWbjR)R_Vc3Calt$tyC=ezy*!rO3SuV z!SZ^^@m?lbWy2~B-b#{-&(XOaBueAAlEB5VN@3J;F7UQv$-NH?GqrI)>W|5gsuqe6k6O8gdmntVWnjqkt@8(*_2jxWl}=va91X* z()dm&6If}8S0=2|C$CJ{kIVHzcB*V(rLA6>1cTtlB<&12>@9yS_u|XmEh4QWJbnDC zEQsvEFZi|!-}+%+?(DE{q(7|*o<21PO%3YLw;z71b*nETxYMIrNavv#b72F+FdOk- z$l=rLCBKWK`K13AwAQuU$hJG0m32Xbg`*%b0=zjinZLdI8P|Wz7PEc%9_w&#pEjX% zu-9M7{HqTfjtwJL+1j1F*X%N5&HbNGb?cEppP)u4csS@YQXkyJqs4$h14-`?s>P|( zN&MC;UfJDhRkL?nG~8Op$EOBqIkEA260fi1nf?0pbNeM-Co>8mJ`2)|i8r@2w}i{B z1?V)!{+Gn(E@iS$6^_h0x_XZp)e&v0MvLvAcpF>2&LdnBnqoS;D<<<{3tu|&2TECO zcUNaoGBNAcHpAAW4n}rQAU=*Ir-8}b>n8I%lb<+d&MhZRf7G2tA;sPA^7XIwR%!9{ z*+KHzEoy?6`eeR;^gV~UU$k^5>w6aE6@P|!ieJXfHk7MegoWJW?UVTqyZ&}0?S4<{ zHzJKiy+xBdw{2g%b#>h|D&|3!c`Wv8J(_W*#^#>XP9}a0#TUCH4jVX{V$((j2^r~ zx*b}`qGDr%wAR+iD(ZX!g`s1U`N`fV9Qk|Fr4L6`;!wE}GPjk1u|(*_Uvy3tA#Pn# zGXMRg!;S_u_DCBihjJ+8ump~=4U{SvrFy@*s8}NNv#Aq1vP3NAtvg|4lRIeJx|5EUt#S%t+=_D`h%{Z+k2yA8E&-{G(OS=Z4-w8~v*~ zpyK$%xNq>}`k(j&45WlIw>55PUO`XoJ&TvdP?&-+5--AQhNPeH488>QqwwNZg z4I^)g5Db?=YpC%t8IC@ay&SLodvYiyN$-%85pMY2IBvZxm@0uDQ;*hXIPM+rbfjJH z!J)du^48gm3LUx{uMa4a3ngf;z)u!pDhQb%7C-cGKc1P1G52U^EZ8+4X#Q)OT7P$F4<7oX} zr~d#;+jdPDbzNF}qy_gJ&3@5N@cYXZjD|nFo$HL{puNC`AIp>M9UF2eW2rT4rtMY3 z?~J`C%Z^EX0zJm+T|eY#dTXyV=f9d9>RPreX>71uo??vbRnKW*Sb}yFeA#lV6k~|> z<52Cgds!XB?{&%>H*~A$-0jeqwiA59Es>JXJY@?Q>*xMHp#p6k*lWoYi8JQ0sDb(I ztyebPtrTNk#sTLIQ__RHpx%Ake9%se#UEEglP6pF+LRzyC^{$ z)1B>+oAn^60gJL4&l^p|u=Q^n2fsK;92N>dVcJ}9(b{=g(>MQXMy<`H#Fk?Fx8F84 z_76pK!J@N;HW&QgBsS}IUaA=tIDMm9i(ftSGIk$%%qbYcX>-B#QF-As#lM)%qNJ$jKOTmFGdkmL z!xd++0~XHSvGGmf><{N|v-b7(sZDmvj2oB8ZefjiEb5H%menyFtJB%J<7fa>@3^Eh zPg#^7{d9Pp?RC<8!-C%BU3Lq$^1$gQ94}gKm7)xO9BPsRhRw7+{CR<)rxGHFvqCd% zj6kK*qT_>YDVHl4r@i~w#ZhVO8FegA%Iw&XL;2F1g4)DU*QGT_T5zaoat)S3QF{{_ zEgMgHAmzlj;ZWriTdOc5(dRc~#GIm#4TWjP)*p_%lsZl5%%Sut;jOb7-u1sX9y}y> zC8q%p;k{jy=;*V+!;#sy8;4q`!H;K%I5ye~jXlV2fl&O=bK}7QPsf_;Jvfv|IS-^a zoJXjedT@J&cyLw+eZ7UU5;Sh$p!<4dhU4i;Pek{qTJe8%ur-^MYVg}CzoY<*L-C~2&v4ckSEPL(8#vm}u>Y=dEv8g=IGaZS zk9LOndwzAKS2-=sND>-yDAJm#|K4_RaRdGJK-a^Iwl{1v`+yX+r7nlst?QYKZGU@x zXFL&pk93HjmZ0qo#}w?6e)SIGP|+og-C_%v-`N;;wWvoAmKp60`%O6M7$%J0D2-pL z<51`2+isuj@BUTv8@{UO5<$`4aD2g8$AmhIrQsExuqghT^88O*>;hjSngXvKEB~LJM*@Ai))QhfQfv)_1C8m%Q_h$P5f2Ile(1rWrd7|TW&YeE$%Nvxw4Tew zJFy1+#K8?+)+wV<;BU?MHdmh#YR^6AZ$`!1aPdQ1|Ciae{MJ!KF5LQO8!{X{y-ctD53R2|+l>i30e&wLsvXuis_<-@?;&Zrpw|t}Hu_nI|^f zv&?ql^gI`ZJH8b71BX1>0mDPGuH5xwab@}b=>Z0QQl0JbT{@GkfF*(4)Xa0iz2vv2~#unPP{6PKy+A$wgi~ z`iGYG@@L8uTbG`dSNoP*f;BbSv;bMY*-iRc_;4aQaKGv~Uy{iqzm1W_)w&J7fmknXT zCyAM`Rxs0?c>;fOMjg(O&{AqUGls*J<+`bp_2*JN37D|p09<0mxZaC=#9?n*cW|HS`^wt9OZZL0 z{SRi7Ms9RzDjgB{Rm(51e>5u0+I{C%6&ClK`DdOt`{>(8h5?^<6s@@q&maN*U1!U2 z7UhJy>ki!Zui#+_^FH9x`;TlKW#2rQp26b2Gc0FV#;Jm^?eTvV^%aAfbVGJjHYBb; z2fX!rMsoeb8O*8e&gQI8)9;~BoBv~0KenHDO4ipMN3pmMO-%E*?c$Tg>_tAJbyBux zP)NC z{$||4&R;ylmgb!zURWr9hagn~=IyB*M|J;5GUE<5IBtn}^_w4U_e0kdTefHGcbR)G zJZ*11Zoe6KvT%T(L;&*AkHdX# zV-j=g8pr91UQXdTh`BgwS|zlU+RcpNaGzVD{bYTkPXmn6pOt*ne2~owbEqHTd0quJ7IS z8<%&Up2AXr-&!Sv`${n}?thc-SPkc!q=>6$MU&;A`wg!JcICAo??ep_*TGj0l{fZ2 z`N9zW%~rDCsHf1^4J`h+j+HrF2QNsQWr)5#TnxKC+j*>!>pyxHMcu1J+zR)>(V0(0 z$E%3#vFZ1n8yUiJ7Ohs!qJ4L6vA7>j81r|tBr(bm(6=bP3@l!}+8Xw<N~| z;(oY$&B@|gy@%oPHPQ{Z=zSF@Q?)1S*n-eKS&yb?u(&Vw+dEZE?Cd38`f-ZWY!Hl- zDPNqyzN2ha+!sF{bTY%R<|BPTr#ONI4vvXe&`Y!Wu>-tQvLCkX!AcX(_mfk$U7tmuim&!o^*7m?R?|@87tqjWmu0q@~$-)*T~{!-Y~7=;pUHz zMFTmn>e)S5!VPc5A~;o}utqSU-1QZ?P=Zd*OPQRkupkQt<*uWEt)+rxEGRdWfWm4eAb5es5}@3$ zaCq{$_!TO-baMLz#ca27atY-QQI=z&3QRSoX2WuTa>powmuax-<$%>dxx*EOsoZk% zH*oTTT4R7gxv7b@KA{y1%8hk~|EQI4&Q3KsQ0|%fcZp92|mS(7A8Gf`ivq3@XbN2gpo7QJP% zKIDL^(`D7_M}3w)6I2~h3;NNG?Sb!wQ@a4QKDatvR<&U20%|`5Ri{2%nhW4y_$w!u z1yzSZp@fScsvVqy!PTkt)e%GOTfkzaK-XOb%l@sE3oPh5Rd}h^59zW}CBWCqY6;MF zy46)CF44lE>sUGgCxhC=bUD=i0=`ZiTW9$Fr~a)CA=&^5LQjpPI(y{+Nd;3E0Hepm5y)1le5<6D0-=XNOL_;SZ%I@x2tD<0 z`F&A!P*X5nDKL8K;A)@MDgo<*&_fBhmTGn-`ZowYU8z)e0TP12=&8nP7f^2;sxSzB z1I213EeCZiEFB0v0Zd?b3nyV|H3gz-si(0t(|TyFCIV z4GZd!u61x|4C)`P2&TJ?vK|_5AQ)I=0;q|#mY@pDRughrOgQzBpu3%MFyf2Z1Dhzd_*Z=&D!O%NKTX$ zi%dmvEcq(E;)0R4C=Pbr&vZGE#3(Bk84VXKO5`b>a`nty7WoYqup2Cr9c9HL^FgtK z`|Xj-A`e2rZ^9xeQdTT7B=v91YeeGqn*=N0MKI>NkNjN(&z@`ZCI0f4E%H8$g+H_L z6nE|9*Et_tpPSt)kKwfW5@2C-HMW<6)#gjw$Q3wkzN9qphj|RA&6lXLd5Xe46(vxj zK<$W=hhn`MiwfIvE)lHFmsBpr5>SHVORUGc>w*Qfkuao9kI-kTjYRcBL4rCvqQ+|H zqRox~ONbE!pH;0Cl+dO}s9>GT#N~Nwvm+F%RTy%$*%5#2d*ofTV7QAmJwgS;`qXOF z658wt#cJh336dRAj_03n?w1CJ654!8X;=u>=1bgRX}*M<`#473fwlP(VClx8OGhoC z&6lXL)N0s}P}sj5)5Q7Oj@Kos1lE~?AsAqiFLCu*`b=$lgo-K2`Y!1a<&ktQ^pR9Q zZFWT2QUcNMl*(s6$YVHddPJ=R-3&Am(ew!3YpD`iH>6l?cEstk>dipG+VqH83H9vY zTBu&2(FGZWlCadmF6k1j&r%nlX4B?NN)wD#)#ghmR_y^)E=`vZpT$eC8mu+3HeW)q zTAzR=wE2?Kuvq3g^j#G^1LqaMcu!R?2lZKPzQmnimwbt8a>W%E7%p6sFQI~=gxWDN zJ8iy1jn(=D&6m)03B|f7At=X_HeaF!pHm%WSZ8g%M2)3NP-jE21ErHCg(g9LsB7~j zRIqwE=Lx@X?Kz~T_P({v-o)h z6O(*N$pKQE9-)(geroGOj5a$$^-~{vFjDV4h7>?(jpRJk)q>%N+VlujLT!DzakSYH zcUWz9#2Fx6Uz22wwdoOef=PCS9@Ls0Ny80Q*d<+}4UlR}z{J{oi902<`4V?nnl2#$ z68RDeR<9k^Seq{amc}u)!dNANSl48TP_zR}nw>Tq;!dzS8}g?2I%hIOD8oyjHXGtj2_+j+ zrk6`3Lp(!oFxIq@y0+yu4BGk6NL_L-Vbq22hDf?HOa+%hN90HuOXsy{R2d)tZhd4! zD!dck5Rr^w1~}`<2#&F!n@&?;EoXj;KsMxWQ>uauDM79=4OnL74q*+lAsaH77+J7f z)JBEMzrUBk5gpbd8#1{?_)#${LA2!#s^g%YrhWbEhVBat4loIgvH_^+^#6h*pB zPGC9^@a|nPk;spH{HV(&EQbdZR?NhVC1G7*VWExL(IE}_5ixH&5$wSvlz<&ikn@QCHKL()#%Nt=>rF%m zlmB21@*9?_RU5#Z<(T*qX0kX8|G zF!{w~$gQ3j@qSFpD5Nq1ER8p+WmqcBi9pt3@Q10&vby%f!;+O_EZboH#1<**khK^* z`JWi;k%_u+zkkL=pp;|6wa883sYi4n))S+3x}jmZS&>LWjPt0zNp_VS7t2HD%R-?U zWLj3lMj|WG>x&>__=hFAiel!9-pKOsS?||ZWPiB_gh}s04+VNu}5@4H7(8M zXC(|=i-f}3iR+bpG)J`Z-|1=uu8&=dg>^6PY8!gxRd0jMLTNd$n0Zy1i9wNt}#fMip}q z#!|2bI>sN0stq3G?T=%R;KBsW9I&rfplLL%Or6`#kBh&(Y z_gZ#Z{=!kN4*?@U&j9qUv`8>g> zDT+zE7t_$Why%-|fp8aF_&}e$wIJ8UTqR(A>{>AC(mf2^xtM1L!81XWi+Qsjycx7O zJ~OMO{Vd>ux{}wJ2%lMX&}I5-JD>=WPg(o%8S;V z(YlaIVY=Co;JABqXH?jED7VJ#S~)3y9(SOf|IV&4xWiWC-V`jV-m$=H;2V7ktT z)IpAFh)7_yWsPcJwfB3-`@XO+N3=Fg(S=m%?o%@g6t;Dqp~+eQ+{K4f^KWUDvzz#lMui#yIuB)bx5+#Pl*3~c_iqhB_T?Ax-a>(uxt}L z54#-Zu2qcyojmvPW(7OA1Wl*QSSBJIbTW0UkD}?(60mJ*$l$8h2++x}Mje%RnirzA zvY@LGc=&96aL4qyDRP`*5^dHI7F~@YgMI6PDE8cSM=^cp;%Zx-kSLiR6kH!nvdv%L zlXu6$LNAw(hR8;Hv>JhNbRWNZq{6=RxJfGPOCKf`_N5P#3j5NBNrips!=%E#^kGtA zU-~equrGa>RM?k3Oe*Y4A0`#{r4N$|`_hL=g?;J6q{6=RVNzjV`Y@@mFMXI)*q1&` zD(p)iCKdLj50eV}(uYZfed)ub!d^RE*?EM6Bt<6eT=9kb6gXDki2Q&L4gmr}i@ zi68lM)0`(Af3T0g(;yS1stT~oI1!`@IBXvL9`H+B{u&pRBXwzz<==U1CP)>L%fy0n z$gGO~f$!NaeDh18Id%9MS)&}QGeN4V62XHFvTz!BEd20)dh!G6`RAP6w?E6H!r@Gi zDu04)yq!@<6;-(W=udg}D<m66{5*b zzN=sdsj5r_@3v`4)rWr%;k)JhmMwKRN%wcxw1ZU13X^E*64_e+IFgSXxiPzM_y^L8 zv_^JDz{fy|U=Sb1<-^N|YK-N39GjW_xL}yHr@YAyQsqamI0V96KAHV=>3F`+;eOcz zx=oh6&UUbaR8@D%EnJvV5K|MX!J ze>ITFKHYtxv}4^Tc91GrVMf$i;;g^GPYe3l@#V{(q{;jG+d-;=WVx^cu>@U?xJ?2- z{9?S|@EpBH>M;H*J9w5nyV&gv!#EuXip=^);J15CktY1QLF#vLgdGG-b~Xzv=KS<7 zusiMweAL)L_VNAAQjE`NJGpdrPEICeREcqC1%dauca05wy;Umk_{I)aCa*KoKz?>33$Zt2n``~5L?&^OuR^MP~m zpZdE5Ue}-zSLxzr=}gKizBDd%m)Xv2;!)fc@Zzz)xHp!0qn0R9Y7DksW+bmJ1vs zI8R%E8=VsPi6gwY)aUc0PkO&=2L+VDBrV|b8OXr%0zW+XF57(257Mz`yd9)aw%UCW z{zDbU@2yt_zI$pe8?Z7-depd?9W+t)AAxA$vXxf+-P47uZ`v%xSB;~!2rAu@!9VWN&vA{Q&Ihys_XOz4i7i5B4RuN>u zFqsn!jb}d-c*E1ytT?TfG}88GCfKGdIM%>0YhBvn40$Q=tvmX&O9y#M6RkTl!8TGTs7Yh8D)&XXZJ&9Runnq`Wrpnl+B4{eb;rHP}f&Wt!Opf0} z+hlF%bZ!@Ts=PgtY)rf>WqVR6@c*?-j{EBB0{ddm?z_NTp|ID>O9mBlyn5%4+6U`Z> zX0e%Gi4QQR>`OFXZx$T~GAqkP77sf>6*FE7d}J)AQ z&(&@=C;*#oxGM0|({tJ5IZ5p5cFjy+zNKyA^5+HqX^Xq;fbl=Dc~#?0;KIs@p(nFe zMV;EG1b)z@x4pQrmFBZYM!#zULzWi_u`kSJ|8zVe@Vhn#a6`UX%Eq<$$OMM03TM{Y zANf{`TfA&F+gab=1WGImLQ5~~@}d6Eh9Mn$PH}Q4~LjQk}F$({Ma|xdb_%> zui$lOGwZ!{qzNopKE80)$w8ZXSUpkTe>KH&j=*#_tlU@=ShD&w0FFM>zD?j~oAg}8 zyW7~~i^iGAeXuhQ7dvID(qo1#H*&lQ)H%SqtdDQ7aAcdnFEZ)5mOpM|zpFCN1nw-m z0z#u49;tQvivs`16wB>du!Z%y^|cA4T3H2r&4tU!wtAPqw`kdj^If))je9ZF1iD>; z=tmA88kpn>eVi@uV#^4w^On`@(s%lsK*5z4jRtB%!vG!j3;e(yHMw^#EoN7~=w$*a zmz6+d-0c$k{eKtu%wGbyTK}8PCi0z3Am#EYh&_RHv(oq(g4>-I_(_w!IKQ`3*o;9f zO~=ZXOt%I8S_hFWNNvuZo$@>mL|xv+aCD1H=b`9_0^jq`RQ7ISH8$+X zi8v5-#S&OL7x%pRRN(8Z8O{29^w7Mu>&7_Hb!<$W>msA!>tDYR_(NVi8*O%&$2Xf2 z2fi+Ed0=I}PJQwAD}i6#&7a-!Vy1c4v-WY|>#`-fi;RY^3$F$K`k({m`qSSwe_U8T zt}QOYWx)X=!@O|OIH6GB?>DlTe|=D3T0d}GD^PfXwY;?*6doofy+Y87wNT)r+XR@W z{58uIv$10)i~4*1H)7t#>mFTJL5UwBF4yXuX?Z(0Vt+p!IHsLF?TNgVwtl2Ca89 N3|e1oxV+O9{|^Ut6eR!v diff --git a/mods/ITEMS/mcl_armor/models/mcl_armor_character.blend b/mods/ITEMS/mcl_armor/models/mcl_armor_character.blend index a5626aaccb7fefd5eed3164226a0dc78c9a3f317..a613eef89303dc9b6df5b5bbf63c46a1ef996702 100644 GIT binary patch delta 127846 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

M#qPm#r@mTNabk6K!?%m%t$nw35-S$i(vH0 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 delta 111997 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 M*~IaCT)**u0kDNA-T(jq diff --git a/mods/ITEMS/mcl_armor/models/mcl_armor_character_female.b3d b/mods/ITEMS/mcl_armor/models/mcl_armor_character_female.b3d index 1b4205344e2ca724be8fa876718a321e7ea83139..4e17ee34105e5fd7028051e7509ae0ae9d2dcae1 100644 GIT binary patch delta 106756 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 delta 64362 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 N3|e1oxV+O9{|^Ut6eR!v diff --git a/mods/ITEMS/mcl_armor/models/mcl_armor_character_female.blend b/mods/ITEMS/mcl_armor/models/mcl_armor_character_female.blend index 828cd942cc229d07a8ed920dfe5eabeca002926e..b0494efbff8f5d46bf13b3f4765abd55cb15c200 100644 GIT binary patch delta 129515 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 Gy8jCzCU1-Y delta 112053 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 Date: Mon, 12 Jul 2021 21:41:57 +0000 Subject: [PATCH 052/296] Remove object:is_player --- mods/ITEMS/mcl_core/functions.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_core/functions.lua b/mods/ITEMS/mcl_core/functions.lua index 6e1a977d9..eceb81c51 100644 --- a/mods/ITEMS/mcl_core/functions.lua +++ b/mods/ITEMS/mcl_core/functions.lua @@ -203,7 +203,8 @@ minetest.register_abm({ chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) for _,object in pairs(minetest.get_objects_inside_radius(pos, 0.9)) do - if not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" then + local entity = object:get_luaentity() + if entity and entity.name == "__builtin:item" then object:remove() end end From d26b1b1402056b5add6bf25d5e791bfc6c8b1ab1 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Wed, 14 Jul 2021 09:10:01 +0200 Subject: [PATCH 053/296] use mcl_util.call_on_rightclick insteed of current implementation --- mods/ITEMS/mcl_buckets/init.lua | 27 ++++++++++++++++----------- mods/ITEMS/mcl_buckets/mod.conf | 2 +- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/mods/ITEMS/mcl_buckets/init.lua b/mods/ITEMS/mcl_buckets/init.lua index 70a219ffb..fdd08bdf9 100644 --- a/mods/ITEMS/mcl_buckets/init.lua +++ b/mods/ITEMS/mcl_buckets/init.lua @@ -3,6 +3,7 @@ local modname = minetest.get_current_modname() local S = minetest.get_translator(modname) local modpath = minetest.get_modpath(modname) +-- Compatibility with old bucket mod minetest.register_alias("bucket:bucket_empty", "mcl_buckets:bucket_empty") minetest.register_alias("bucket:bucket_water", "mcl_buckets:bucket_water") minetest.register_alias("bucket:bucket_lava", "mcl_buckets:bucket_lava") @@ -11,6 +12,7 @@ local mod_doc = minetest.get_modpath("doc") local mod_mcl_core = minetest.get_modpath("mcl_core") --local mod_mclx_core = minetest.get_modpath("mclx_core") +-- Localize some functions for faster access local vector = vector local math = math local string = string @@ -127,16 +129,15 @@ function mcl_buckets.register_liquid(def) if pointed_thing.type ~= "node" then return end + -- Call on_rightclick if the pointed node defines it + local new_stack = mcl_util.call_on_rightclick(itemstack, user, pointed_thing) + if new_stack then + return new_stack + end local node = minetest.get_node(pointed_thing.under) local place_pos = pointed_thing.under local nn = node.name - -- Call on_rightclick if the pointed node defines it - if user and not user:get_player_control().sneak then - if minetest.registered_nodes[nn] and minetest.registered_nodes[nn].on_rightclick then - return minetest.registered_nodes[nn].on_rightclick(place_pos, node, user, itemstack) or itemstack - end - end local node_place if type(def.source_place) == "function" then @@ -306,16 +307,20 @@ minetest.register_craftitem("mcl_buckets:bucket_empty", { return itemstack end end]] + -- Must be pointing to node if pointed_thing.type ~= "node" then return itemstack end + + -- Call on_rightclick if the pointed node defines it + local new_stack = mcl_util.call_on_rightclick(itemstack, user, pointed_thing) + if new_stack then + return new_stack + end + local node = minetest.get_node(pointed_thing.under) local nn = node.name - if user and not user:get_player_control().sneak then - if minetest.registered_nodes[nn] and minetest.registered_nodes[nn].on_rightclick then - return minetest.registered_nodes[nn].on_rightclick(pointed_thing.under, node, user, itemstack) or itemstack - end - end + local new_bucket local liquid_node = bucket_raycast(user) if liquid_node then diff --git a/mods/ITEMS/mcl_buckets/mod.conf b/mods/ITEMS/mcl_buckets/mod.conf index 5a78e70ad..0d7b764b8 100644 --- a/mods/ITEMS/mcl_buckets/mod.conf +++ b/mods/ITEMS/mcl_buckets/mod.conf @@ -1,6 +1,6 @@ name = mcl_buckets author = Kahrl description = -depends = mcl_worlds +depends = mcl_worlds, mcl_util optional_depends = mcl_core, mclx_core, doc From b0127fc1c3cb66ba0e024b9ea4cf82080ea80ced Mon Sep 17 00:00:00 2001 From: AFCMS Date: Wed, 14 Jul 2021 09:18:15 +0200 Subject: [PATCH 054/296] fix bucket dispense function --- mods/ITEMS/mcl_buckets/init.lua | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/mods/ITEMS/mcl_buckets/init.lua b/mods/ITEMS/mcl_buckets/init.lua index fdd08bdf9..95ec97443 100644 --- a/mods/ITEMS/mcl_buckets/init.lua +++ b/mods/ITEMS/mcl_buckets/init.lua @@ -205,11 +205,16 @@ function mcl_buckets.register_liquid(def) _on_dispense = function(stack, pos, droppos, dropnode, dropdir) local iname = stack:get_name() local buildable = minetest.registered_nodes[dropnode.name].buildable_to or dropnode.name == "mcl_portals:portal" + if not buildable then return stack end - if def.extra_check and def.extra_check(droppos, nil) == false then - -- Fail placement of liquid - elseif buildable then - -- buildable; replace the node + local result + if def.extra_check then + result = def.extra_check(droppos, nil) + if result == nil then result = true end + else + result = true + end + if result then -- Fail placement of liquid if result is false local node_place if type(def.source_place) == "function" then node_place = def.source_place(droppos) From ca277b6769c8edb1c498c268dd349bd2cd6c72ee Mon Sep 17 00:00:00 2001 From: AFCMS Date: Wed, 14 Jul 2021 11:29:15 +0200 Subject: [PATCH 055/296] mcl_bucket code refactoring + fix extra_check noot working --- mods/ITEMS/mcl_buckets/API.md | 30 +++++- mods/ITEMS/mcl_buckets/init.lua | 144 ++++++++++++++++++++++------ mods/ITEMS/mcl_buckets/register.lua | 26 +---- 3 files changed, 149 insertions(+), 51 deletions(-) diff --git a/mods/ITEMS/mcl_buckets/API.md b/mods/ITEMS/mcl_buckets/API.md index 53f7d3698..4595d8e72 100644 --- a/mods/ITEMS/mcl_buckets/API.md +++ b/mods/ITEMS/mcl_buckets/API.md @@ -15,7 +15,33 @@ Accept folowing params: * longdesc: long explanatory description (for help) * usagehelp: short usage explanation (for help) * tt_help: very short tooltip help -* extra_check(pos, placer): (optional) function(pos) which can returns false to avoid placing the liquid. Placer is object/player who is placing the liquid, can be nil. +* extra_check(pos, placer): (optional) function(pos) * groups: optional list of item groups -This function can be called from any mod (which depends on this one) \ No newline at end of file + +**Usage exemple:** +```lua +mcl_buckets.register_liquid({ + itemname = "dummy:bucket_dummy", + source_place = "dummy:dummy_source", + source_take = {"dummy:dummy_source"}, + inventory_image = "bucket_dummy.png", + name = S("Dummy liquid Bucket"), + longdesc = S("This bucket is filled with a dummy liquid."), + usagehelp = S("Place it to empty the bucket and create a dummy liquid source."), + tt_help = S("Places a dummy liquid source"), + extra_check = function(pos, placer) + --pos = pos where the liquid should be placed + --placer people who tried to place the bucket (can be nil) + + --no liquid node will be placed + --the bucket will not be emptied + --return false, false + + --liquid node will be placed + --the bucket will be emptied + return true, true + end, + groups = { dummy_group = 123 }, +}) +``` \ No newline at end of file diff --git a/mods/ITEMS/mcl_buckets/init.lua b/mods/ITEMS/mcl_buckets/init.lua index 95ec97443..9ae712ced 100644 --- a/mods/ITEMS/mcl_buckets/init.lua +++ b/mods/ITEMS/mcl_buckets/init.lua @@ -56,6 +56,7 @@ local function place_liquid(pos, itemstring) sound_place(itemstring, pos) minetest.add_node(pos, {name=itemstring, param2=fullness}) end + local function give_bucket(new_bucket, itemstack, user) local inv = user:get_inventory() if minetest.is_creative_enabled(user:get_player_name()) then @@ -81,6 +82,7 @@ local pointable_sources = {} local function bucket_raycast(user) --local pos = user:get_pos() local pos = mcl_util.get_object_center(user) + --local pos = vector.add(user:get_pos(), user:get_bone_position("Head_Control")) pos.y = pos.y + user:get_properties().eye_height local look_dir = user:get_look_dir() look_dir = vector.multiply(look_dir, 4) @@ -98,6 +100,53 @@ local function bucket_raycast(user) return nil end +local function get_node_place(source_place, place_pos) + local node_place + if type(source_place) == "function" then + node_place = source_place(place_pos) + else + node_place = source_place + end + return node_place +end + +local function get_extra_check(check, pos, user) + local result + local take_bucket + if check then + result, take_bucket = check(pos, user) + if result == nil then result = true end + if take_bucket == nil then take_bucket = true end + else + result = true + take_bucket = true + end + return result, take_bucket +end + +local function get_bucket_drop(itemstack, user, take_bucket) + -- Handle bucket item and inventory stuff + if take_bucket and not minetest.is_creative_enabled(user:get_player_name()) then + -- Add empty bucket and put it into inventory, if possible. + -- Drop empty bucket otherwise. + local new_bucket = ItemStack("mcl_buckets:bucket_empty") + if itemstack:get_count() == 1 then + return new_bucket + else + local inv = user:get_inventory() + if inv:room_for_item("main", new_bucket) then + inv:add_item("main", new_bucket) + else + add_item(user:get_pos(), new_bucket) + end + itemstack:take_item() + return itemstack + end + else + return itemstack + end +end + function mcl_buckets.register_liquid(def) for _,source in ipairs(def.source_take) do mcl_buckets.liquids[source] = { @@ -135,23 +184,75 @@ function mcl_buckets.register_liquid(def) return new_stack end - local node = minetest.get_node(pointed_thing.under) - local place_pos = pointed_thing.under - local nn = node.name + local undernode = get_node(pointed_thing.under) + local abovenode = get_node(pointed_thing.above) + local nn = undernode.name + local buildable1 = minetest.registered_nodes[undernode.name] and minetest.registered_nodes[undernode.name].buildable_to + local buildable2 = minetest.registered_nodes[abovenode.name] and minetest.registered_nodes[abovenode.name].buildable_to + if not buildable1 and not buildable2 then return itemstack end --if both nodes aren't buildable_to, skip + + if buildable1 then + local result, take_bucket = get_extra_check(def.extra_check, pointed_thing.under, user) + if result then + local node_place = get_node_place(def.source_place, pointed_thing.under) + local pns = user:get_player_name() - local node_place - if type(def.source_place) == "function" then - node_place = def.source_place(place_pos) + -- Check protection + if minetest.is_protected(pointed_thing.under, pns) then + minetest.record_protection_violation(pointed_thing.under, pns) + return itemstack + end + + -- Place liquid + place_liquid(pointed_thing.under, node_place) + + -- Update doc mod + if mod_doc and doc.entry_exists("nodes", node_place) then + doc.mark_entry_as_revealed(user:get_player_name(), "nodes", node_place) + end + end + return get_bucket_drop(itemstack, user, take_bucket) + elseif buildable2 then + local result, take_bucket = get_extra_check(def.extra_check, pointed_thing.above, user) + if result then + local node_place = get_node_place(def.source_place, pointed_thing.above) + local pns = user:get_player_name() + + -- Check protection + if minetest.is_protected(pointed_thing.above, pns) then + minetest.record_protection_violation(pointed_thing.above, pns) + return itemstack + end + + -- Place liquid + place_liquid(pointed_thing.above, node_place) + + -- Update doc mod + if mod_doc and doc.entry_exists("nodes", node_place) then + doc.mark_entry_as_revealed(user:get_player_name(), "nodes", node_place) + end + end + return get_bucket_drop(itemstack, user, take_bucket) else - node_place = def.source_place + return itemstack end + -- Check if pointing to a buildable node --local item = itemstack:get_name() - if def.extra_check and def.extra_check(place_pos, user) == false then - -- Fail placement of liquid - elseif minetest.registered_nodes[nn] and minetest.registered_nodes[nn].buildable_to then - -- buildable; replace the node + --[[ + if buildable_to_1 then + if can_place(pos) then + Place + end + else if buildable_to_2 then + if can_place2() then + Place + end + end + ]] + --[[ + if result then -- Fail placement of liquid if result is false local pns = user:get_player_name() if minetest.is_protected(place_pos, pns) then minetest.record_protection_violation(place_pos, pns) @@ -200,28 +301,17 @@ function mcl_buckets.register_liquid(def) end else return - end + end]] end, _on_dispense = function(stack, pos, droppos, dropnode, dropdir) local iname = stack:get_name() local buildable = minetest.registered_nodes[dropnode.name].buildable_to or dropnode.name == "mcl_portals:portal" if not buildable then return stack end - - local result - if def.extra_check then - result = def.extra_check(droppos, nil) - if result == nil then result = true end - else - result = true - end + local result, take_bucket = get_extra_check(def.extra_check, droppos, nil) if result then -- Fail placement of liquid if result is false - local node_place - if type(def.source_place) == "function" then - node_place = def.source_place(droppos) - else - node_place = def.source_place - end - place_liquid(droppos, node_place) + place_liquid(droppos, get_node_place(def.source_place, droppos)) + end + if take_bucket then stack:set_name("mcl_buckets:bucket_empty") end return stack diff --git a/mods/ITEMS/mcl_buckets/register.lua b/mods/ITEMS/mcl_buckets/register.lua index 12790598c..97349533e 100644 --- a/mods/ITEMS/mcl_buckets/register.lua +++ b/mods/ITEMS/mcl_buckets/register.lua @@ -53,15 +53,6 @@ if mod_mcl_core then usagehelp = S("Place it to empty the bucket and create a water source."), tt_help = S("Places a water source"), extra_check = function(pos, placer) - -- Check protection - local placer_name = "" - if placer then - placer_name = placer:get_player_name() - end - if placer and minetest.is_protected(pos, placer_name) then - minetest.record_protection_violation(pos, placer_name) - return false - end local nn = minetest.get_node(pos).name -- Pour water into cauldron if minetest.get_item_group(nn, "cauldron") ~= 0 then @@ -70,13 +61,13 @@ if mod_mcl_core then minetest.set_node(pos, {name="mcl_cauldrons:cauldron_3"}) end sound_place("mcl_core:water_source", pos) - return false + return false, true -- Evaporate water if used in Nether (except on cauldron) else local dim = mcl_worlds.pos_to_dimension(pos) if dim == "nether" then minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true) - return false + return false, true end end end, @@ -96,15 +87,6 @@ if mod_mclx_core then usagehelp = S("Place it to empty the bucket and create a river water source."), tt_help = S("Places a river water source"), extra_check = function(pos, placer) - -- Check protection - local placer_name = "" - if placer then - placer_name = placer:get_player_name() - end - if placer and minetest.is_protected(pos, placer_name) then - minetest.record_protection_violation(pos, placer_name) - return false - end local nn = minetest.get_node(pos).name -- Pour into cauldron if minetest.get_item_group(nn, "cauldron") ~= 0 then @@ -113,13 +95,13 @@ if mod_mclx_core then minetest.set_node(pos, {name="mcl_cauldrons:cauldron_3r"}) end sound_place("mcl_core:water_source", pos) - return false + return false, true else -- Evaporate water if used in Nether (except on cauldron) local dim = mcl_worlds.pos_to_dimension(pos) if dim == "nether" then minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true) - return false + return false, true end end end, From cd08df175c767fe502065d5327d37ec633c7af2e Mon Sep 17 00:00:00 2001 From: AFCMS Date: Wed, 14 Jul 2021 11:41:09 +0200 Subject: [PATCH 056/296] add better documentation --- mods/ITEMS/mcl_buckets/API.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_buckets/API.md b/mods/ITEMS/mcl_buckets/API.md index 4595d8e72..abbdb0a07 100644 --- a/mods/ITEMS/mcl_buckets/API.md +++ b/mods/ITEMS/mcl_buckets/API.md @@ -23,7 +23,14 @@ Accept folowing params: ```lua mcl_buckets.register_liquid({ itemname = "dummy:bucket_dummy", - source_place = "dummy:dummy_source", + --source_place = "dummy:dummy_source", + source_place = function(pos) + if condition then + return "dummy:dummy_source" + else + return "dummy:dummy_source_nether" + end + end, source_take = {"dummy:dummy_source"}, inventory_image = "bucket_dummy.png", name = S("Dummy liquid Bucket"), From 88e59d3592b7f56044273296bce96e299cf2de17 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Wed, 14 Jul 2021 11:52:27 +0200 Subject: [PATCH 057/296] more mt like API (improved readability) --- mods/ITEMS/mcl_buckets/API.md | 14 +-- mods/ITEMS/mcl_buckets/init.lua | 150 +--------------------------- mods/ITEMS/mcl_buckets/register.lua | 9 +- 3 files changed, 14 insertions(+), 159 deletions(-) diff --git a/mods/ITEMS/mcl_buckets/API.md b/mods/ITEMS/mcl_buckets/API.md index abbdb0a07..93af64acf 100644 --- a/mods/ITEMS/mcl_buckets/API.md +++ b/mods/ITEMS/mcl_buckets/API.md @@ -1,15 +1,18 @@ # mcl_buckets Add an API to register buckets to mcl -## mcl_buckets.register_liquid(def) +## mcl_buckets.register_liquid(itemname, def) + +Register a new bucket of liquid. + +`itemname` is the itemstring of the new bucket item + +`def` is a table containing the folowing fields: -Register a new liquid -Accept folowing params: * source_place: a string or function. * string: name of the node to place * function(pos): will returns name of the node to place with pos being the placement position * source_take: table of liquid source node names to take -* itemname: itemstring of the new bucket item (or nil if liquid is not takeable) * inventory_image: texture of the new bucket item (ignored if itemname == nil) * name: user-visible bucket description * longdesc: long explanatory description (for help) @@ -21,8 +24,7 @@ Accept folowing params: **Usage exemple:** ```lua -mcl_buckets.register_liquid({ - itemname = "dummy:bucket_dummy", +mcl_buckets.register_liquid("dummy:bucket_dummy", { --source_place = "dummy:dummy_source", source_place = function(pos) if condition then diff --git a/mods/ITEMS/mcl_buckets/init.lua b/mods/ITEMS/mcl_buckets/init.lua index 9ae712ced..11fede816 100644 --- a/mods/ITEMS/mcl_buckets/init.lua +++ b/mods/ITEMS/mcl_buckets/init.lua @@ -147,13 +147,13 @@ local function get_bucket_drop(itemstack, user, take_bucket) end end -function mcl_buckets.register_liquid(def) +function mcl_buckets.register_liquid(itemname, def) for _,source in ipairs(def.source_take) do mcl_buckets.liquids[source] = { source_place = def.source_place, source_take = source, on_take = def.on_take, - itemname = def.itemname, + itemname = itemname, } pointable_sources[source] = true if type(def.source_place) == "string" then @@ -161,11 +161,7 @@ function mcl_buckets.register_liquid(def) end end - if def.itemname == nil or def.itemname == "" then - error(string.format("[mcl_bucket] Invalid itemname then registering [%s]!", def.name)) - end - - minetest.register_craftitem(def.itemname, { + minetest.register_craftitem(itemname, { description = def.name, _doc_items_longdesc = def.longdesc, _doc_items_usagehelp = def.usagehelp, @@ -236,72 +232,6 @@ function mcl_buckets.register_liquid(def) else return itemstack end - - -- Check if pointing to a buildable node - --local item = itemstack:get_name() - - --[[ - if buildable_to_1 then - if can_place(pos) then - Place - end - else if buildable_to_2 then - if can_place2() then - Place - end - end - ]] - --[[ - if result then -- Fail placement of liquid if result is false - local pns = user:get_player_name() - if minetest.is_protected(place_pos, pns) then - minetest.record_protection_violation(place_pos, pns) - return itemstack - end - place_liquid(place_pos, node_place) - if mod_doc and doc.entry_exists("nodes", node_place) then - doc.mark_entry_as_revealed(user:get_player_name(), "nodes", node_place) - end - else - -- not buildable to; place the liquid above - -- check if the node above can be replaced - local abovenode = minetest.get_node(pointed_thing.above) - if minetest.registered_nodes[abovenode.name] and minetest.registered_nodes[abovenode.name].buildable_to then - local pn = user:get_player_name() - if minetest.is_protected(pointed_thing.above, pn) then - minetest.record_protection_violation(pointed_thing.above, pn) - return itemstack - end - place_liquid(pointed_thing.above, node_place) - if mod_doc and doc.entry_exists("nodes", node_place) then - doc.mark_entry_as_revealed(user:get_player_name(), "nodes", node_place) - end - else - -- do not remove the bucket with the liquid - return - end - end - - -- Handle bucket item and inventory stuff - if not minetest.is_creative_enabled(user:get_player_name()) then - -- Add empty bucket and put it into inventory, if possible. - -- Drop empty bucket otherwise. - local new_bucket = ItemStack("mcl_buckets:bucket_empty") - if itemstack:get_count() == 1 then - return new_bucket - else - local inv = user:get_inventory() - if inv:room_for_item("main", new_bucket) then - inv:add_item("main", new_bucket) - else - minetest.add_item(user:get_pos(), new_bucket) - end - itemstack:take_item() - return itemstack - end - else - return - end]] end, _on_dispense = function(stack, pos, droppos, dropnode, dropdir) local iname = stack:get_name() @@ -328,80 +258,6 @@ minetest.register_craftitem("mcl_buckets:bucket_empty", { inventory_image = "bucket.png", stack_max = 16, on_place = function(itemstack, user, pointed_thing) - --[[-- Must be pointing to node - if pointed_thing.type ~= "node" then - return itemstack - end - - -- Call on_rightclick if the pointed node defines it - - - local pointed_liquid = bucket_raycast(user) - - -- Can't steal liquids - if minetest.is_protected(pointed_liquid.above, user:get_player_name()) then - minetest.record_protection_violation(pointed_liquid.under, user:get_player_name()) - return itemstack - end - if minetest.is_protected(pointed_thing.above, user:get_player_name()) then - minetest.record_protection_violation(pointed_thing.under, user:get_player_name()) - return itemstack - end - - -- Check if pointing to a liquid source - local liquiddef = mcl_buckets.liquids[nn] - local new_bucket - if liquiddef and liquiddef.itemname and (nn == liquiddef.source_take) then - - -- Fill bucket, but not in Creative Mode - if not minetest.is_creative_enabled(user:get_player_name()) then - new_bucket = ItemStack({name = liquiddef.itemname}) - if liquiddef.on_take then - liquiddef.on_take(user) - end - end - - minetest.add_node(pointed_thing.under, {name="air"}) - sound_take(nn, pointed_thing.under) - - if mod_doc and doc.entry_exists("nodes", nn) then - doc.mark_entry_as_revealed(user:get_player_name(), "nodes", nn) - end - - elseif nn == "mcl_cauldrons:cauldron_3" then - -- Take water out of full cauldron - minetest.set_node(pointed_thing.under, {name="mcl_cauldrons:cauldron"}) - if not minetest.is_creative_enabled(user:get_player_name()) then - new_bucket = ItemStack("mcl_buckets:bucket_water") - end - sound_take("mcl_core:water_source", pointed_thing.under) - elseif nn == "mcl_cauldrons:cauldron_3r" then - -- Take river water out of full cauldron - minetest.set_node(pointed_thing.under, {name="mcl_cauldrons:cauldron"}) - if not minetest.is_creative_enabled(user:get_player_name()) then - new_bucket = ItemStack("mcl_buckets:bucket_river_water") - end - sound_take("mclx_core:river_water_source", pointed_thing.under) - end - - -- Add liquid bucket and put it into inventory, if possible. - -- Drop new bucket otherwise. - if new_bucket then - if itemstack:get_count() == 1 then - return new_bucket - else - local inv = user:get_inventory() - if inv:room_for_item("main", new_bucket) then - inv:add_item("main", new_bucket) - else - minetest.add_item(user:get_pos(), new_bucket) - end - if not minetest.is_creative_enabled(user:get_player_name()) then - itemstack:take_item() - end - return itemstack - end - end]] -- Must be pointing to node if pointed_thing.type ~= "node" then return itemstack diff --git a/mods/ITEMS/mcl_buckets/register.lua b/mods/ITEMS/mcl_buckets/register.lua index 97349533e..46abce1d0 100644 --- a/mods/ITEMS/mcl_buckets/register.lua +++ b/mods/ITEMS/mcl_buckets/register.lua @@ -19,7 +19,7 @@ end]] if mod_mcl_core then -- Lava bucket - mcl_buckets.register_liquid({ + mcl_buckets.register_liquid("mcl_buckets:bucket_lava", { source_place = function(pos) local dim = mcl_worlds.pos_to_dimension(pos) if dim == "nether" then @@ -34,7 +34,6 @@ if mod_mcl_core then awards.unlock(user:get_player_name(), "mcl:hotStuff") end end, - itemname = "mcl_buckets:bucket_lava", inventory_image = "bucket_lava.png", name = S("Lava Bucket"), longdesc = S("A bucket can be used to collect and release liquids. This one is filled with hot lava, safely contained inside. Use with caution."), @@ -43,10 +42,9 @@ if mod_mcl_core then }) -- Water bucket - mcl_buckets.register_liquid({ + mcl_buckets.register_liquid("mcl_buckets:bucket_water", { source_place = "mcl_core:water_source", source_take = {"mcl_core:water_source"}, - itemname = "mcl_buckets:bucket_water", inventory_image = "bucket_water.png", name = S("Water Bucket"), longdesc = S("A bucket can be used to collect and release liquids. This one is filled with water."), @@ -77,10 +75,9 @@ end if mod_mclx_core then -- River water bucket - mcl_buckets.register_liquid({ + mcl_buckets.register_liquid("mcl_buckets:bucket_river_water", { source_place = "mclx_core:river_water_source", source_take = {"mclx_core:river_water_source"}, - itemname = "mcl_buckets:bucket_river_water", inventory_image = "bucket_river_water.png", name = S("River Water Bucket"), longdesc = S("A bucket can be used to collect and release liquids. This one is filled with river water."), From cf5703d528426bbbb810c327ecfe59b0c9867cf0 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Wed, 14 Jul 2021 11:53:37 +0200 Subject: [PATCH 058/296] fix luacheck warnings --- mods/ITEMS/mcl_buckets/init.lua | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/mods/ITEMS/mcl_buckets/init.lua b/mods/ITEMS/mcl_buckets/init.lua index 11fede816..a496fb2ff 100644 --- a/mods/ITEMS/mcl_buckets/init.lua +++ b/mods/ITEMS/mcl_buckets/init.lua @@ -182,11 +182,10 @@ function mcl_buckets.register_liquid(itemname, def) local undernode = get_node(pointed_thing.under) local abovenode = get_node(pointed_thing.above) - local nn = undernode.name local buildable1 = minetest.registered_nodes[undernode.name] and minetest.registered_nodes[undernode.name].buildable_to local buildable2 = minetest.registered_nodes[abovenode.name] and minetest.registered_nodes[abovenode.name].buildable_to if not buildable1 and not buildable2 then return itemstack end --if both nodes aren't buildable_to, skip - + if buildable1 then local result, take_bucket = get_extra_check(def.extra_check, pointed_thing.under, user) if result then @@ -234,7 +233,6 @@ function mcl_buckets.register_liquid(itemname, def) end end, _on_dispense = function(stack, pos, droppos, dropnode, dropdir) - local iname = stack:get_name() local buildable = minetest.registered_nodes[dropnode.name].buildable_to or dropnode.name == "mcl_portals:portal" if not buildable then return stack end local result, take_bucket = get_extra_check(def.extra_check, droppos, nil) From 6d7aafe0d462bccdb8a7a32f78a27898fb1705d7 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Wed, 14 Jul 2021 15:13:40 +0200 Subject: [PATCH 059/296] Revert "more mt like API (improved readability)" This reverts commit 88e59d3592b7f56044273296bce96e299cf2de17. --- mods/ITEMS/mcl_buckets/API.md | 14 ++- mods/ITEMS/mcl_buckets/init.lua | 150 +++++++++++++++++++++++++++- mods/ITEMS/mcl_buckets/register.lua | 9 +- 3 files changed, 159 insertions(+), 14 deletions(-) diff --git a/mods/ITEMS/mcl_buckets/API.md b/mods/ITEMS/mcl_buckets/API.md index 93af64acf..abbdb0a07 100644 --- a/mods/ITEMS/mcl_buckets/API.md +++ b/mods/ITEMS/mcl_buckets/API.md @@ -1,18 +1,15 @@ # mcl_buckets Add an API to register buckets to mcl -## mcl_buckets.register_liquid(itemname, def) - -Register a new bucket of liquid. - -`itemname` is the itemstring of the new bucket item - -`def` is a table containing the folowing fields: +## mcl_buckets.register_liquid(def) +Register a new liquid +Accept folowing params: * source_place: a string or function. * string: name of the node to place * function(pos): will returns name of the node to place with pos being the placement position * source_take: table of liquid source node names to take +* itemname: itemstring of the new bucket item (or nil if liquid is not takeable) * inventory_image: texture of the new bucket item (ignored if itemname == nil) * name: user-visible bucket description * longdesc: long explanatory description (for help) @@ -24,7 +21,8 @@ Register a new bucket of liquid. **Usage exemple:** ```lua -mcl_buckets.register_liquid("dummy:bucket_dummy", { +mcl_buckets.register_liquid({ + itemname = "dummy:bucket_dummy", --source_place = "dummy:dummy_source", source_place = function(pos) if condition then diff --git a/mods/ITEMS/mcl_buckets/init.lua b/mods/ITEMS/mcl_buckets/init.lua index a496fb2ff..b75c10696 100644 --- a/mods/ITEMS/mcl_buckets/init.lua +++ b/mods/ITEMS/mcl_buckets/init.lua @@ -147,13 +147,13 @@ local function get_bucket_drop(itemstack, user, take_bucket) end end -function mcl_buckets.register_liquid(itemname, def) +function mcl_buckets.register_liquid(def) for _,source in ipairs(def.source_take) do mcl_buckets.liquids[source] = { source_place = def.source_place, source_take = source, on_take = def.on_take, - itemname = itemname, + itemname = def.itemname, } pointable_sources[source] = true if type(def.source_place) == "string" then @@ -161,7 +161,11 @@ function mcl_buckets.register_liquid(itemname, def) end end - minetest.register_craftitem(itemname, { + if def.itemname == nil or def.itemname == "" then + error(string.format("[mcl_bucket] Invalid itemname then registering [%s]!", def.name)) + end + + minetest.register_craftitem(def.itemname, { description = def.name, _doc_items_longdesc = def.longdesc, _doc_items_usagehelp = def.usagehelp, @@ -231,6 +235,72 @@ function mcl_buckets.register_liquid(itemname, def) else return itemstack end + + -- Check if pointing to a buildable node + --local item = itemstack:get_name() + + --[[ + if buildable_to_1 then + if can_place(pos) then + Place + end + else if buildable_to_2 then + if can_place2() then + Place + end + end + ]] + --[[ + if result then -- Fail placement of liquid if result is false + local pns = user:get_player_name() + if minetest.is_protected(place_pos, pns) then + minetest.record_protection_violation(place_pos, pns) + return itemstack + end + place_liquid(place_pos, node_place) + if mod_doc and doc.entry_exists("nodes", node_place) then + doc.mark_entry_as_revealed(user:get_player_name(), "nodes", node_place) + end + else + -- not buildable to; place the liquid above + -- check if the node above can be replaced + local abovenode = minetest.get_node(pointed_thing.above) + if minetest.registered_nodes[abovenode.name] and minetest.registered_nodes[abovenode.name].buildable_to then + local pn = user:get_player_name() + if minetest.is_protected(pointed_thing.above, pn) then + minetest.record_protection_violation(pointed_thing.above, pn) + return itemstack + end + place_liquid(pointed_thing.above, node_place) + if mod_doc and doc.entry_exists("nodes", node_place) then + doc.mark_entry_as_revealed(user:get_player_name(), "nodes", node_place) + end + else + -- do not remove the bucket with the liquid + return + end + end + + -- Handle bucket item and inventory stuff + if not minetest.is_creative_enabled(user:get_player_name()) then + -- Add empty bucket and put it into inventory, if possible. + -- Drop empty bucket otherwise. + local new_bucket = ItemStack("mcl_buckets:bucket_empty") + if itemstack:get_count() == 1 then + return new_bucket + else + local inv = user:get_inventory() + if inv:room_for_item("main", new_bucket) then + inv:add_item("main", new_bucket) + else + minetest.add_item(user:get_pos(), new_bucket) + end + itemstack:take_item() + return itemstack + end + else + return + end]] end, _on_dispense = function(stack, pos, droppos, dropnode, dropdir) local buildable = minetest.registered_nodes[dropnode.name].buildable_to or dropnode.name == "mcl_portals:portal" @@ -256,6 +326,80 @@ minetest.register_craftitem("mcl_buckets:bucket_empty", { inventory_image = "bucket.png", stack_max = 16, on_place = function(itemstack, user, pointed_thing) + --[[-- Must be pointing to node + if pointed_thing.type ~= "node" then + return itemstack + end + + -- Call on_rightclick if the pointed node defines it + + + local pointed_liquid = bucket_raycast(user) + + -- Can't steal liquids + if minetest.is_protected(pointed_liquid.above, user:get_player_name()) then + minetest.record_protection_violation(pointed_liquid.under, user:get_player_name()) + return itemstack + end + if minetest.is_protected(pointed_thing.above, user:get_player_name()) then + minetest.record_protection_violation(pointed_thing.under, user:get_player_name()) + return itemstack + end + + -- Check if pointing to a liquid source + local liquiddef = mcl_buckets.liquids[nn] + local new_bucket + if liquiddef and liquiddef.itemname and (nn == liquiddef.source_take) then + + -- Fill bucket, but not in Creative Mode + if not minetest.is_creative_enabled(user:get_player_name()) then + new_bucket = ItemStack({name = liquiddef.itemname}) + if liquiddef.on_take then + liquiddef.on_take(user) + end + end + + minetest.add_node(pointed_thing.under, {name="air"}) + sound_take(nn, pointed_thing.under) + + if mod_doc and doc.entry_exists("nodes", nn) then + doc.mark_entry_as_revealed(user:get_player_name(), "nodes", nn) + end + + elseif nn == "mcl_cauldrons:cauldron_3" then + -- Take water out of full cauldron + minetest.set_node(pointed_thing.under, {name="mcl_cauldrons:cauldron"}) + if not minetest.is_creative_enabled(user:get_player_name()) then + new_bucket = ItemStack("mcl_buckets:bucket_water") + end + sound_take("mcl_core:water_source", pointed_thing.under) + elseif nn == "mcl_cauldrons:cauldron_3r" then + -- Take river water out of full cauldron + minetest.set_node(pointed_thing.under, {name="mcl_cauldrons:cauldron"}) + if not minetest.is_creative_enabled(user:get_player_name()) then + new_bucket = ItemStack("mcl_buckets:bucket_river_water") + end + sound_take("mclx_core:river_water_source", pointed_thing.under) + end + + -- Add liquid bucket and put it into inventory, if possible. + -- Drop new bucket otherwise. + if new_bucket then + if itemstack:get_count() == 1 then + return new_bucket + else + local inv = user:get_inventory() + if inv:room_for_item("main", new_bucket) then + inv:add_item("main", new_bucket) + else + minetest.add_item(user:get_pos(), new_bucket) + end + if not minetest.is_creative_enabled(user:get_player_name()) then + itemstack:take_item() + end + return itemstack + end + end]] -- Must be pointing to node if pointed_thing.type ~= "node" then return itemstack diff --git a/mods/ITEMS/mcl_buckets/register.lua b/mods/ITEMS/mcl_buckets/register.lua index 46abce1d0..97349533e 100644 --- a/mods/ITEMS/mcl_buckets/register.lua +++ b/mods/ITEMS/mcl_buckets/register.lua @@ -19,7 +19,7 @@ end]] if mod_mcl_core then -- Lava bucket - mcl_buckets.register_liquid("mcl_buckets:bucket_lava", { + mcl_buckets.register_liquid({ source_place = function(pos) local dim = mcl_worlds.pos_to_dimension(pos) if dim == "nether" then @@ -34,6 +34,7 @@ if mod_mcl_core then awards.unlock(user:get_player_name(), "mcl:hotStuff") end end, + itemname = "mcl_buckets:bucket_lava", inventory_image = "bucket_lava.png", name = S("Lava Bucket"), longdesc = S("A bucket can be used to collect and release liquids. This one is filled with hot lava, safely contained inside. Use with caution."), @@ -42,9 +43,10 @@ if mod_mcl_core then }) -- Water bucket - mcl_buckets.register_liquid("mcl_buckets:bucket_water", { + mcl_buckets.register_liquid({ source_place = "mcl_core:water_source", source_take = {"mcl_core:water_source"}, + itemname = "mcl_buckets:bucket_water", inventory_image = "bucket_water.png", name = S("Water Bucket"), longdesc = S("A bucket can be used to collect and release liquids. This one is filled with water."), @@ -75,9 +77,10 @@ end if mod_mclx_core then -- River water bucket - mcl_buckets.register_liquid("mcl_buckets:bucket_river_water", { + mcl_buckets.register_liquid({ source_place = "mclx_core:river_water_source", source_take = {"mclx_core:river_water_source"}, + itemname = "mcl_buckets:bucket_river_water", inventory_image = "bucket_river_water.png", name = S("River Water Bucket"), longdesc = S("A bucket can be used to collect and release liquids. This one is filled with river water."), From ec6086d8e631fc19bd9dfca43eb5109f3125d0e4 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Wed, 14 Jul 2021 15:14:23 +0200 Subject: [PATCH 060/296] cleanup --- mods/ITEMS/mcl_buckets/init.lua | 140 -------------------------------- 1 file changed, 140 deletions(-) diff --git a/mods/ITEMS/mcl_buckets/init.lua b/mods/ITEMS/mcl_buckets/init.lua index b75c10696..312669c5e 100644 --- a/mods/ITEMS/mcl_buckets/init.lua +++ b/mods/ITEMS/mcl_buckets/init.lua @@ -235,72 +235,6 @@ function mcl_buckets.register_liquid(def) else return itemstack end - - -- Check if pointing to a buildable node - --local item = itemstack:get_name() - - --[[ - if buildable_to_1 then - if can_place(pos) then - Place - end - else if buildable_to_2 then - if can_place2() then - Place - end - end - ]] - --[[ - if result then -- Fail placement of liquid if result is false - local pns = user:get_player_name() - if minetest.is_protected(place_pos, pns) then - minetest.record_protection_violation(place_pos, pns) - return itemstack - end - place_liquid(place_pos, node_place) - if mod_doc and doc.entry_exists("nodes", node_place) then - doc.mark_entry_as_revealed(user:get_player_name(), "nodes", node_place) - end - else - -- not buildable to; place the liquid above - -- check if the node above can be replaced - local abovenode = minetest.get_node(pointed_thing.above) - if minetest.registered_nodes[abovenode.name] and minetest.registered_nodes[abovenode.name].buildable_to then - local pn = user:get_player_name() - if minetest.is_protected(pointed_thing.above, pn) then - minetest.record_protection_violation(pointed_thing.above, pn) - return itemstack - end - place_liquid(pointed_thing.above, node_place) - if mod_doc and doc.entry_exists("nodes", node_place) then - doc.mark_entry_as_revealed(user:get_player_name(), "nodes", node_place) - end - else - -- do not remove the bucket with the liquid - return - end - end - - -- Handle bucket item and inventory stuff - if not minetest.is_creative_enabled(user:get_player_name()) then - -- Add empty bucket and put it into inventory, if possible. - -- Drop empty bucket otherwise. - local new_bucket = ItemStack("mcl_buckets:bucket_empty") - if itemstack:get_count() == 1 then - return new_bucket - else - local inv = user:get_inventory() - if inv:room_for_item("main", new_bucket) then - inv:add_item("main", new_bucket) - else - minetest.add_item(user:get_pos(), new_bucket) - end - itemstack:take_item() - return itemstack - end - else - return - end]] end, _on_dispense = function(stack, pos, droppos, dropnode, dropdir) local buildable = minetest.registered_nodes[dropnode.name].buildable_to or dropnode.name == "mcl_portals:portal" @@ -326,80 +260,6 @@ minetest.register_craftitem("mcl_buckets:bucket_empty", { inventory_image = "bucket.png", stack_max = 16, on_place = function(itemstack, user, pointed_thing) - --[[-- Must be pointing to node - if pointed_thing.type ~= "node" then - return itemstack - end - - -- Call on_rightclick if the pointed node defines it - - - local pointed_liquid = bucket_raycast(user) - - -- Can't steal liquids - if minetest.is_protected(pointed_liquid.above, user:get_player_name()) then - minetest.record_protection_violation(pointed_liquid.under, user:get_player_name()) - return itemstack - end - if minetest.is_protected(pointed_thing.above, user:get_player_name()) then - minetest.record_protection_violation(pointed_thing.under, user:get_player_name()) - return itemstack - end - - -- Check if pointing to a liquid source - local liquiddef = mcl_buckets.liquids[nn] - local new_bucket - if liquiddef and liquiddef.itemname and (nn == liquiddef.source_take) then - - -- Fill bucket, but not in Creative Mode - if not minetest.is_creative_enabled(user:get_player_name()) then - new_bucket = ItemStack({name = liquiddef.itemname}) - if liquiddef.on_take then - liquiddef.on_take(user) - end - end - - minetest.add_node(pointed_thing.under, {name="air"}) - sound_take(nn, pointed_thing.under) - - if mod_doc and doc.entry_exists("nodes", nn) then - doc.mark_entry_as_revealed(user:get_player_name(), "nodes", nn) - end - - elseif nn == "mcl_cauldrons:cauldron_3" then - -- Take water out of full cauldron - minetest.set_node(pointed_thing.under, {name="mcl_cauldrons:cauldron"}) - if not minetest.is_creative_enabled(user:get_player_name()) then - new_bucket = ItemStack("mcl_buckets:bucket_water") - end - sound_take("mcl_core:water_source", pointed_thing.under) - elseif nn == "mcl_cauldrons:cauldron_3r" then - -- Take river water out of full cauldron - minetest.set_node(pointed_thing.under, {name="mcl_cauldrons:cauldron"}) - if not minetest.is_creative_enabled(user:get_player_name()) then - new_bucket = ItemStack("mcl_buckets:bucket_river_water") - end - sound_take("mclx_core:river_water_source", pointed_thing.under) - end - - -- Add liquid bucket and put it into inventory, if possible. - -- Drop new bucket otherwise. - if new_bucket then - if itemstack:get_count() == 1 then - return new_bucket - else - local inv = user:get_inventory() - if inv:room_for_item("main", new_bucket) then - inv:add_item("main", new_bucket) - else - minetest.add_item(user:get_pos(), new_bucket) - end - if not minetest.is_creative_enabled(user:get_player_name()) then - itemstack:take_item() - end - return itemstack - end - end]] -- Must be pointing to node if pointed_thing.type ~= "node" then return itemstack From 8fff20eec9f1045c9d16d2a4cdb79c989d627966 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Wed, 14 Jul 2021 15:18:12 +0200 Subject: [PATCH 061/296] fix misleading API --- mods/ITEMS/mcl_buckets/init.lua | 12 ++++++------ mods/ITEMS/mcl_buckets/register.lua | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/mods/ITEMS/mcl_buckets/init.lua b/mods/ITEMS/mcl_buckets/init.lua index 312669c5e..17d333485 100644 --- a/mods/ITEMS/mcl_buckets/init.lua +++ b/mods/ITEMS/mcl_buckets/init.lua @@ -153,7 +153,7 @@ function mcl_buckets.register_liquid(def) source_place = def.source_place, source_take = source, on_take = def.on_take, - itemname = def.itemname, + bucketname = def.bucketname, } pointable_sources[source] = true if type(def.source_place) == "string" then @@ -161,11 +161,11 @@ function mcl_buckets.register_liquid(def) end end - if def.itemname == nil or def.itemname == "" then + if def.bucketname == nil or def.bucketname == "" then error(string.format("[mcl_bucket] Invalid itemname then registering [%s]!", def.name)) end - minetest.register_craftitem(def.itemname, { + minetest.register_craftitem(def.bucketname, { description = def.name, _doc_items_longdesc = def.longdesc, _doc_items_usagehelp = def.usagehelp, @@ -289,7 +289,7 @@ minetest.register_craftitem("mcl_buckets:bucket_empty", { -- FIXME: remove this line --if not minetest.is_creative_enabled(user:get_player_name()) then if not false then - new_bucket = ItemStack({name = liquid_def.itemname}) + new_bucket = ItemStack({name = liquid_def.bucketname}) if liquid_def.on_take then liquid_def.on_take(user) end @@ -337,9 +337,9 @@ minetest.register_craftitem("mcl_buckets:bucket_empty", { local liquiddef = mcl_buckets.liquids[dropnode.name] local new_bucket - if liquiddef and liquiddef.itemname and (dropnode.name == liquiddef.source_take) then + if liquiddef and liquiddef.bucketname and (dropnode.name == liquiddef.source_take) then -- Fill bucket - new_bucket = ItemStack({name = liquiddef.itemname}) + new_bucket = ItemStack({name = liquiddef.bucketname}) sound_take(dropnode.name, droppos) collect_liquid = true end diff --git a/mods/ITEMS/mcl_buckets/register.lua b/mods/ITEMS/mcl_buckets/register.lua index 97349533e..1a7c8fe14 100644 --- a/mods/ITEMS/mcl_buckets/register.lua +++ b/mods/ITEMS/mcl_buckets/register.lua @@ -34,7 +34,7 @@ if mod_mcl_core then awards.unlock(user:get_player_name(), "mcl:hotStuff") end end, - itemname = "mcl_buckets:bucket_lava", + bucketname = "mcl_buckets:bucket_lava", inventory_image = "bucket_lava.png", name = S("Lava Bucket"), longdesc = S("A bucket can be used to collect and release liquids. This one is filled with hot lava, safely contained inside. Use with caution."), @@ -46,7 +46,7 @@ if mod_mcl_core then mcl_buckets.register_liquid({ source_place = "mcl_core:water_source", source_take = {"mcl_core:water_source"}, - itemname = "mcl_buckets:bucket_water", + bucketname = "mcl_buckets:bucket_water", inventory_image = "bucket_water.png", name = S("Water Bucket"), longdesc = S("A bucket can be used to collect and release liquids. This one is filled with water."), @@ -80,7 +80,7 @@ if mod_mclx_core then mcl_buckets.register_liquid({ source_place = "mclx_core:river_water_source", source_take = {"mclx_core:river_water_source"}, - itemname = "mcl_buckets:bucket_river_water", + bucketname = "mcl_buckets:bucket_river_water", inventory_image = "bucket_river_water.png", name = S("River Water Bucket"), longdesc = S("A bucket can be used to collect and release liquids. This one is filled with river water."), From 873a1e73dc58bf38ca4738feb86f4f4ab8c5d2ba Mon Sep 17 00:00:00 2001 From: AFCMS Date: Wed, 14 Jul 2021 15:22:27 +0200 Subject: [PATCH 062/296] fix documentation --- mods/ITEMS/mcl_buckets/API.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/ITEMS/mcl_buckets/API.md b/mods/ITEMS/mcl_buckets/API.md index abbdb0a07..94ec48de5 100644 --- a/mods/ITEMS/mcl_buckets/API.md +++ b/mods/ITEMS/mcl_buckets/API.md @@ -9,7 +9,7 @@ Accept folowing params: * string: name of the node to place * function(pos): will returns name of the node to place with pos being the placement position * source_take: table of liquid source node names to take -* itemname: itemstring of the new bucket item (or nil if liquid is not takeable) +* bucketname: itemstring of the new bucket item * inventory_image: texture of the new bucket item (ignored if itemname == nil) * name: user-visible bucket description * longdesc: long explanatory description (for help) @@ -22,7 +22,7 @@ Accept folowing params: **Usage exemple:** ```lua mcl_buckets.register_liquid({ - itemname = "dummy:bucket_dummy", + bucketname = "dummy:bucket_dummy", --source_place = "dummy:dummy_source", source_place = function(pos) if condition then From dc17cc91a3ea225936869d1f01b1bed498efd0e8 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Thu, 15 Jul 2021 00:01:56 +0200 Subject: [PATCH 063/296] make raycast start from player head --- mods/ITEMS/mcl_buckets/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_buckets/init.lua b/mods/ITEMS/mcl_buckets/init.lua index 17d333485..f1d131ea2 100644 --- a/mods/ITEMS/mcl_buckets/init.lua +++ b/mods/ITEMS/mcl_buckets/init.lua @@ -81,7 +81,7 @@ local pointable_sources = {} local function bucket_raycast(user) --local pos = user:get_pos() - local pos = mcl_util.get_object_center(user) + local pos = user:get_pos() --local pos = vector.add(user:get_pos(), user:get_bone_position("Head_Control")) pos.y = pos.y + user:get_properties().eye_height local look_dir = user:get_look_dir() From 49bde37a5e80a91f7ad0f03ef371aa32cf7972b8 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Thu, 15 Jul 2021 01:03:50 +0200 Subject: [PATCH 064/296] rewrite README to markdown --- mods/ITEMS/mcl_buckets/{README.txt => README.md} | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) rename mods/ITEMS/mcl_buckets/{README.txt => README.md} (67%) diff --git a/mods/ITEMS/mcl_buckets/README.txt b/mods/ITEMS/mcl_buckets/README.md similarity index 67% rename from mods/ITEMS/mcl_buckets/README.txt rename to mods/ITEMS/mcl_buckets/README.md index 06862d589..b783cc133 100644 --- a/mods/ITEMS/mcl_buckets/README.txt +++ b/mods/ITEMS/mcl_buckets/README.md @@ -1,9 +1,12 @@ -Bucket mod. -Originally taken from Minetest Game, adapted for MineClone 2. +# MineClone2 Bucket (`mcl_bucket`) +Originally taken from Minetest Game, adapted for MineClone2. + +This mod add buckets to the game, including an API to register your own (see `API.md`). + +## License -License of source code: ------------------------ Copyright (C) 2011-2012 Kahrl + Copyright (C) 2011-2012 celeron55, Perttu Ahola This program is free software; you can redistribute it and/or modify From 9d9e21301271da166248a2356b81e0225d738fde Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Sat, 10 Jul 2021 10:54:59 +0200 Subject: [PATCH 065/296] Fix some implicit hard and soft-dependencies These issues were found while testing minetest#8603 and are caused by relying on the undefined mod loading order --- mods/ITEMS/mcl_armor/mod.conf | 2 +- mods/ITEMS/mcl_brewing/mod.conf | 2 +- mods/PLAYER/mcl_playerplus/mod.conf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mods/ITEMS/mcl_armor/mod.conf b/mods/ITEMS/mcl_armor/mod.conf index 9264e8362..fad2e494c 100644 --- a/mods/ITEMS/mcl_armor/mod.conf +++ b/mods/ITEMS/mcl_armor/mod.conf @@ -1,5 +1,5 @@ name = mcl_armor author = stu description = Adds craftable armor that is visible to other players. -depends = mcl_core, mcl_player, mcl_enchanting +depends = mcl_core, mcl_player, mcl_enchanting, mcl_damage optional_depends = mcl_fire, ethereal, bakedclay diff --git a/mods/ITEMS/mcl_brewing/mod.conf b/mods/ITEMS/mcl_brewing/mod.conf index 2c27c979e..0f6217f09 100644 --- a/mods/ITEMS/mcl_brewing/mod.conf +++ b/mods/ITEMS/mcl_brewing/mod.conf @@ -1,4 +1,4 @@ name = mcl_brewing author = bzoss depends = mcl_init, mcl_formspec, mcl_sounds, mcl_potions, mcl_mobitems -optional_depends = mcl_core, doc, screwdriver +optional_depends = mcl_core, doc, screwdriver, mesecons_mvps diff --git a/mods/PLAYER/mcl_playerplus/mod.conf b/mods/PLAYER/mcl_playerplus/mod.conf index 6989957d7..b77c9e2e5 100644 --- a/mods/PLAYER/mcl_playerplus/mod.conf +++ b/mods/PLAYER/mcl_playerplus/mod.conf @@ -1,5 +1,5 @@ name = mcl_playerplus author = TenPlus1 description = Adds some simple player-related gameplay effects: Hurt by touching a cactus, suffocation and more. -depends = mcl_init, mcl_core, mcl_particles, mcl_hunger, playerphysics, mcl_playerinfo, mcl_weather, mcl_spawn, mcl_enchanting, mcl_damage +depends = mcl_init, mcl_core, mcl_particles, mcl_hunger, playerphysics, mcl_playerinfo, mcl_weather, mcl_spawn, mcl_enchanting, mcl_damage, mcl_sprint From 60fcafeee4fdeb9a236f141801fc95e103685178 Mon Sep 17 00:00:00 2001 From: Tianyang Zhang Date: Thu, 15 Jul 2021 19:25:32 -0700 Subject: [PATCH 066/296] Update description of emerald --- mods/ITEMS/mcl_core/craftitems.lua | 2 +- mods/ITEMS/mcl_core/locale/mcl_core.de.tr | 2 +- mods/ITEMS/mcl_core/locale/mcl_core.es.tr | 2 +- mods/ITEMS/mcl_core/locale/mcl_core.fr.tr | 2 +- mods/ITEMS/mcl_core/locale/mcl_core.pl.tr | 2 +- mods/ITEMS/mcl_core/locale/mcl_core.ru.tr | 2 +- mods/ITEMS/mcl_core/locale/template.txt | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/mods/ITEMS/mcl_core/craftitems.lua b/mods/ITEMS/mcl_core/craftitems.lua index 03f30b7b9..836f21688 100644 --- a/mods/ITEMS/mcl_core/craftitems.lua +++ b/mods/ITEMS/mcl_core/craftitems.lua @@ -93,7 +93,7 @@ minetest.register_craftitem("mcl_core:gold_ingot", { minetest.register_craftitem("mcl_core:emerald", { description = S("Emerald"), - _doc_items_longdesc = S("Emeralds are not very useful on their own, but they can exchanged for gold ingots by crafting."), + _doc_items_longdesc = S("Emeralds are used for trading with villagers."), inventory_image = "mcl_core_emerald.png", stack_max = 64, groups = { craftitem=1 }, diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.de.tr b/mods/ITEMS/mcl_core/locale/mcl_core.de.tr index 0a1cbad37..f5a28c76f 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.de.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.de.tr @@ -95,7 +95,7 @@ Dirt acts as a soil for a few plants. When in light, this block may grow a grass Emerald=Smaragd Emerald Ore=Smaragderz Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=Smaragderz ist das Erz von Smaragden. Es ist sehr selten und kann nur einzeln gefunden werden, nicht in Ansammlungen. -Emeralds are not very useful on their own, but they can exchanged for gold ingots by crafting.=Smaragde sind nicht besonders nützlich, aber man kann sie in der Fertigung durch Goldbarren eintauschen. +Emeralds are used for trading with villagers.=Smaragde sind nicht besonders nützlich, aber man kann sie in der Fertigung durch Goldbarren eintauschen. Flint=Feuerstein Flint is a raw material.=Feuerstein ist ein Rohstoff. Flowing Lava=Fließende Lava diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.es.tr b/mods/ITEMS/mcl_core/locale/mcl_core.es.tr index 1e1029c0f..54ee95d16 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.es.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.es.tr @@ -95,7 +95,7 @@ Dirt acts as a soil for a few plants. When in light, this block may grow a grass Emerald=Esmeralda Emerald Ore=Mena de esmeralda Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=El mineral esmeralda es el mineral de las esmeraldas. Es muy raro y se puede encontrar solo, no en grupos. -Emeralds are not very useful on their own, but they can exchanged for gold ingots by crafting.=Las esmeraldas no son muy útiles por sí mismas, pero pueden cambiarse por lingotes de oro haciendo artesanías. +Emeralds are used for trading with villagers.=Las esmeraldas no son muy útiles por sí mismas, pero pueden cambiarse por lingotes de oro haciendo artesanías. Flint=Pedernal Flint is a raw material.=El pedernal es una materia prima. Flowing Lava=Lava que fluye diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr b/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr index 725025e48..84657c8a1 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr @@ -95,7 +95,7 @@ Dirt acts as a soil for a few plants. When in light, this block may grow a grass Emerald=Emeraude Emerald Ore=Minerai d'Emeraude Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=Le minerai d'émeraude produit des émeraudes. Il est très rare et peut être trouvé seul, pas en filons. -Emeralds are not very useful on their own, but they can exchanged for gold ingots by crafting.=Les émeraudes ne sont pas très utiles seules, mais elles peuvent être échangées contre des lingots d'or. +Emeralds are used for trading with villagers.=Les émeraudes ne sont pas très utiles seules, mais elles peuvent être échangées contre des lingots d'or. Flint=Silex Flint is a raw material.=Le silex est une matière première. Flowing Lava=Lave qui coule diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.pl.tr b/mods/ITEMS/mcl_core/locale/mcl_core.pl.tr index 832a47830..90a75f810 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.pl.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.pl.tr @@ -95,7 +95,7 @@ Dirt acts as a soil for a few plants. When in light, this block may grow a grass Emerald=Szmaragd Emerald Ore=Ruda szmaragdu Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=Ruda szmaragdu jest bardzo rzadka i występuje samotnie, nie w grupach. -Emeralds are not very useful on their own, but they can exchanged for gold ingots by crafting.=Szmaragdy nie są zbyt użyteczne same w sobie, ale można z nich wytworzyć sztabki złota. +Emeralds are used for trading with villagers.=Szmaragdy nie są zbyt użyteczne same w sobie, ale można z nich wytworzyć sztabki złota. Flint=Krzemień Flint is a raw material.=Krzemień jest surowym materiałem. Flowing Lava=Płynąca lawa diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr b/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr index f93db7c2c..07236037b 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr @@ -95,7 +95,7 @@ Dirt acts as a soil for a few plants. When in light, this block may grow a grass Emerald=Изумруд Emerald Ore=Изумрудная руда Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=Изумрудная руда встречается очень редко и всегда по одному блоку. -Emeralds are not very useful on their own, but they can exchanged for gold ingots by crafting.=Изумруды не очень полезны сами по себе, но их можно обменять на золотые слитки. +Emeralds are used for trading with villagers.=Изумруды не очень полезны сами по себе, но их можно обменять на золотые слитки. Flint=Кремень Flint is a raw material.=Кремень это необработанный материал. Flowing Lava=Текущая лава diff --git a/mods/ITEMS/mcl_core/locale/template.txt b/mods/ITEMS/mcl_core/locale/template.txt index 2cb74f5d1..1e8ee04ce 100644 --- a/mods/ITEMS/mcl_core/locale/template.txt +++ b/mods/ITEMS/mcl_core/locale/template.txt @@ -95,7 +95,7 @@ Dirt acts as a soil for a few plants. When in light, this block may grow a grass Emerald= Emerald Ore= Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.= -Emeralds are not very useful on their own, but they can exchanged for gold ingots by crafting.= +Emeralds are used for trading with villagers.= Flint= Flint is a raw material.= Flowing Lava= From b364faa7c7d76370953f798e207837f4e6b7cfab Mon Sep 17 00:00:00 2001 From: AFCMS Date: Sat, 17 Jul 2021 16:22:46 +0200 Subject: [PATCH 067/296] make bucket use 5 lenght raycast --- mods/ITEMS/mcl_buckets/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_buckets/init.lua b/mods/ITEMS/mcl_buckets/init.lua index f1d131ea2..931214b95 100644 --- a/mods/ITEMS/mcl_buckets/init.lua +++ b/mods/ITEMS/mcl_buckets/init.lua @@ -85,7 +85,7 @@ local function bucket_raycast(user) --local pos = vector.add(user:get_pos(), user:get_bone_position("Head_Control")) pos.y = pos.y + user:get_properties().eye_height local look_dir = user:get_look_dir() - look_dir = vector.multiply(look_dir, 4) + look_dir = vector.multiply(look_dir, 5) local pos2 = vector.add(pos, look_dir) local ray = raycast(pos, pos2, false, true) From 48166625d4ddba283d0ca5dca9c548dfb0595337 Mon Sep 17 00:00:00 2001 From: NO11 Date: Sun, 18 Jul 2021 17:21:53 +0000 Subject: [PATCH 068/296] Add mcl_item_id mod --- mods/HELP/mcl_item_id/init.lua | 35 ++++++++++++++++++++++++++++++++++ mods/HELP/mcl_item_id/mod.conf | 3 +++ 2 files changed, 38 insertions(+) create mode 100644 mods/HELP/mcl_item_id/init.lua create mode 100644 mods/HELP/mcl_item_id/mod.conf diff --git a/mods/HELP/mcl_item_id/init.lua b/mods/HELP/mcl_item_id/init.lua new file mode 100644 index 000000000..1d165d8c6 --- /dev/null +++ b/mods/HELP/mcl_item_id/init.lua @@ -0,0 +1,35 @@ +local game = "mineclone2" + +local same_id = { + heads = { "skeleton", "zombie", "creeper", "wither_skeleton" }, + mobitems = { "rabbit", "chicken" }, + walls = { + "andesite", "brick", "cobble", "diorite", "endbricks", + "granite", "mossycobble", "netherbrick", "prismarine", + "rednetherbrick", "redsandstone", "sandstone", + "stonebrick", "stonebrickmossy", + }, + wool = { + "black", "blue", "brown", "cyan", "green", + "grey", "light_blue", "lime", "magenta", "orange", + "pink", "purple", "red", "silver", "white", "yellow", + }, +} + +tt.register_snippet(function(itemstring) + local def = minetest.registered_items[itemstring] + local desc = def.description + local item_split = itemstring:find(":") + local new_id = game .. itemstring:sub(item_split) + for mod, ids in pairs(same_id) do + for _, id in pairs(ids) do + if itemstring == "mcl_" .. mod .. ":" .. id then + new_id = game .. ":" .. id .. "_" .. mod:gsub("s", "") + end + end + end + minetest.register_alias(new_id, itemstring) + if minetest.settings:get_bool("mcl_item_id_debug", true) then + return new_id, "#555555" + end +end) diff --git a/mods/HELP/mcl_item_id/mod.conf b/mods/HELP/mcl_item_id/mod.conf new file mode 100644 index 000000000..c45e17fd3 --- /dev/null +++ b/mods/HELP/mcl_item_id/mod.conf @@ -0,0 +1,3 @@ +name = mcl_item_id +author = NO11 +depends = tt \ No newline at end of file From f2a4d6bd561a6499ea24875c23046340b8b572e0 Mon Sep 17 00:00:00 2001 From: NO11 Date: Sun, 18 Jul 2021 17:23:12 +0000 Subject: [PATCH 069/296] Add item id setting --- settingtypes.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/settingtypes.txt b/settingtypes.txt index ea1c1a50a..f605019ad 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -153,3 +153,7 @@ fix_doubleplants (Mcimport double plant fixes) bool true # Allow players to create Minecraft-like maps. enable_real_maps (Enable Real Maps) bool true + +[Debugging] +# If enabled, this will show the itemstring of an item in the description. +mcl_item_id_debug (Item ID Debug) bool false \ No newline at end of file From 801d9a25715ee5ac1f7a99fc24b0b78fd4b60814 Mon Sep 17 00:00:00 2001 From: NO11 Date: Sun, 18 Jul 2021 18:01:55 +0000 Subject: [PATCH 070/296] Remove some spaces --- mods/HELP/mcl_item_id/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/HELP/mcl_item_id/init.lua b/mods/HELP/mcl_item_id/init.lua index 1d165d8c6..e715ac9e9 100644 --- a/mods/HELP/mcl_item_id/init.lua +++ b/mods/HELP/mcl_item_id/init.lua @@ -17,7 +17,7 @@ local same_id = { } tt.register_snippet(function(itemstring) - local def = minetest.registered_items[itemstring] + local def = minetest.registered_items[itemstring] local desc = def.description local item_split = itemstring:find(":") local new_id = game .. itemstring:sub(item_split) From 96e8e6a86f00835d2e7d5dc36974ec5cfcf2a919 Mon Sep 17 00:00:00 2001 From: NO11 Date: Mon, 19 Jul 2021 12:21:30 +0000 Subject: [PATCH 071/296] Use mineclone: instead of mineclone2: for item IDs --- mods/HELP/mcl_item_id/init.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mods/HELP/mcl_item_id/init.lua b/mods/HELP/mcl_item_id/init.lua index e715ac9e9..e7772d141 100644 --- a/mods/HELP/mcl_item_id/init.lua +++ b/mods/HELP/mcl_item_id/init.lua @@ -1,4 +1,4 @@ -local game = "mineclone2" +local game = "mineclone" local same_id = { heads = { "skeleton", "zombie", "creeper", "wither_skeleton" }, @@ -30,6 +30,6 @@ tt.register_snippet(function(itemstring) end minetest.register_alias(new_id, itemstring) if minetest.settings:get_bool("mcl_item_id_debug", true) then - return new_id, "#555555" - end + return new_id, "#555555" + end end) From 559cf85c9449b77591603ca561618668a3fb027e Mon Sep 17 00:00:00 2001 From: Tianyang Zhang Date: Mon, 19 Jul 2021 09:12:39 -0700 Subject: [PATCH 072/296] Improve description of emerald --- mods/ITEMS/mcl_core/craftitems.lua | 2 +- mods/ITEMS/mcl_core/locale/mcl_core.de.tr | 2 +- mods/ITEMS/mcl_core/locale/mcl_core.es.tr | 2 +- mods/ITEMS/mcl_core/locale/mcl_core.fr.tr | 2 +- mods/ITEMS/mcl_core/locale/mcl_core.pl.tr | 2 +- mods/ITEMS/mcl_core/locale/mcl_core.ru.tr | 2 +- mods/ITEMS/mcl_core/locale/template.txt | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/mods/ITEMS/mcl_core/craftitems.lua b/mods/ITEMS/mcl_core/craftitems.lua index 836f21688..85a078766 100644 --- a/mods/ITEMS/mcl_core/craftitems.lua +++ b/mods/ITEMS/mcl_core/craftitems.lua @@ -93,7 +93,7 @@ minetest.register_craftitem("mcl_core:gold_ingot", { minetest.register_craftitem("mcl_core:emerald", { description = S("Emerald"), - _doc_items_longdesc = S("Emeralds are used for trading with villagers."), + _doc_items_longdesc = S("Emeralds are used in villager trades as currency."), inventory_image = "mcl_core_emerald.png", stack_max = 64, groups = { craftitem=1 }, diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.de.tr b/mods/ITEMS/mcl_core/locale/mcl_core.de.tr index f5a28c76f..8b75dfd40 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.de.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.de.tr @@ -95,7 +95,7 @@ Dirt acts as a soil for a few plants. When in light, this block may grow a grass Emerald=Smaragd Emerald Ore=Smaragderz Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=Smaragderz ist das Erz von Smaragden. Es ist sehr selten und kann nur einzeln gefunden werden, nicht in Ansammlungen. -Emeralds are used for trading with villagers.=Smaragde sind nicht besonders nützlich, aber man kann sie in der Fertigung durch Goldbarren eintauschen. +Emeralds are used in villager trades as currency.=Smaragde sind nicht besonders nützlich, aber man kann sie in der Fertigung durch Goldbarren eintauschen. Flint=Feuerstein Flint is a raw material.=Feuerstein ist ein Rohstoff. Flowing Lava=Fließende Lava diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.es.tr b/mods/ITEMS/mcl_core/locale/mcl_core.es.tr index 54ee95d16..d77f45dc2 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.es.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.es.tr @@ -95,7 +95,7 @@ Dirt acts as a soil for a few plants. When in light, this block may grow a grass Emerald=Esmeralda Emerald Ore=Mena de esmeralda Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=El mineral esmeralda es el mineral de las esmeraldas. Es muy raro y se puede encontrar solo, no en grupos. -Emeralds are used for trading with villagers.=Las esmeraldas no son muy útiles por sí mismas, pero pueden cambiarse por lingotes de oro haciendo artesanías. +Emeralds are used in villager trades as currency.=Las esmeraldas no son muy útiles por sí mismas, pero pueden cambiarse por lingotes de oro haciendo artesanías. Flint=Pedernal Flint is a raw material.=El pedernal es una materia prima. Flowing Lava=Lava que fluye diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr b/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr index 84657c8a1..4d6a3ed43 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr @@ -95,7 +95,7 @@ Dirt acts as a soil for a few plants. When in light, this block may grow a grass Emerald=Emeraude Emerald Ore=Minerai d'Emeraude Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=Le minerai d'émeraude produit des émeraudes. Il est très rare et peut être trouvé seul, pas en filons. -Emeralds are used for trading with villagers.=Les émeraudes ne sont pas très utiles seules, mais elles peuvent être échangées contre des lingots d'or. +Emeralds are used in villager trades as currency.=Les émeraudes ne sont pas très utiles seules, mais elles peuvent être échangées contre des lingots d'or. Flint=Silex Flint is a raw material.=Le silex est une matière première. Flowing Lava=Lave qui coule diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.pl.tr b/mods/ITEMS/mcl_core/locale/mcl_core.pl.tr index 90a75f810..f8dbbde6b 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.pl.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.pl.tr @@ -95,7 +95,7 @@ Dirt acts as a soil for a few plants. When in light, this block may grow a grass Emerald=Szmaragd Emerald Ore=Ruda szmaragdu Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=Ruda szmaragdu jest bardzo rzadka i występuje samotnie, nie w grupach. -Emeralds are used for trading with villagers.=Szmaragdy nie są zbyt użyteczne same w sobie, ale można z nich wytworzyć sztabki złota. +Emeralds are used in villager trades as currency.=Szmaragdy nie są zbyt użyteczne same w sobie, ale można z nich wytworzyć sztabki złota. Flint=Krzemień Flint is a raw material.=Krzemień jest surowym materiałem. Flowing Lava=Płynąca lawa diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr b/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr index 07236037b..ad9d863b2 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr @@ -95,7 +95,7 @@ Dirt acts as a soil for a few plants. When in light, this block may grow a grass Emerald=Изумруд Emerald Ore=Изумрудная руда Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=Изумрудная руда встречается очень редко и всегда по одному блоку. -Emeralds are used for trading with villagers.=Изумруды не очень полезны сами по себе, но их можно обменять на золотые слитки. +Emeralds are used in villager trades as currency.=Изумруды не очень полезны сами по себе, но их можно обменять на золотые слитки. Flint=Кремень Flint is a raw material.=Кремень это необработанный материал. Flowing Lava=Текущая лава diff --git a/mods/ITEMS/mcl_core/locale/template.txt b/mods/ITEMS/mcl_core/locale/template.txt index 1e8ee04ce..19d156711 100644 --- a/mods/ITEMS/mcl_core/locale/template.txt +++ b/mods/ITEMS/mcl_core/locale/template.txt @@ -95,7 +95,7 @@ Dirt acts as a soil for a few plants. When in light, this block may grow a grass Emerald= Emerald Ore= Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.= -Emeralds are used for trading with villagers.= +Emeralds are used in villager trades as currency.= Flint= Flint is a raw material.= Flowing Lava= From 999b82c94a167cdb62d2894fe45718bd48a91ce9 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Tue, 20 Jul 2021 15:21:07 +0200 Subject: [PATCH 073/296] small documentation graphical improvement --- CONTRIBUTING.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1b5098a4f..4c9bf3e38 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -52,17 +52,17 @@ Each mod must provide `mod.conf`. Each mod which add API functions should store functions inside a global table named like the mod. Public functions should not use self references but rather just access the table directly. Functions should be defined in this way: -``` +```lua function mcl_xyz.stuff(param) end ``` Insteed of this way: -``` +```lua mcl_xyz.stuff = function(param) end ``` Indentation must be unified, more likely with tabs. Time sensitive mods should make a local copy of most used API functions to improve performances. -``` +```lua local vector = vector local get_node = minetest.get_node ``` From b5f7ae54583197b55bb5e8f5f81a6605fa4f74e8 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Tue, 20 Jul 2021 15:47:26 +0200 Subject: [PATCH 074/296] working implementation + support of other mods --- mods/ENTITIES/mcl_boats/init.lua | 2 +- mods/ENTITIES/mcl_boats/mod.conf | 2 +- mods/ENTITIES/mcl_minecarts/init.lua | 2 +- mods/ENTITIES/mcl_minecarts/mod.conf | 2 +- mods/HUD/mcl_title/init.lua | 5 ++--- mods/ITEMS/mcl_beds/functions.lua | 2 +- 6 files changed, 7 insertions(+), 8 deletions(-) diff --git a/mods/ENTITIES/mcl_boats/init.lua b/mods/ENTITIES/mcl_boats/init.lua index 76ace7a45..e81e9ffc5 100644 --- a/mods/ENTITIES/mcl_boats/init.lua +++ b/mods/ENTITIES/mcl_boats/init.lua @@ -84,7 +84,7 @@ local function attach_object(self, obj) end end, name) obj:set_look_horizontal(yaw) - mcl_tmp_message.message(obj, S("Sneak to dismount")) + mcl_title.set(obj, "actionbar", {text=S("Sneak to dismount"), color="white", stay=3}) else obj:get_luaentity()._old_visual_size = visual_size end diff --git a/mods/ENTITIES/mcl_boats/mod.conf b/mods/ENTITIES/mcl_boats/mod.conf index a5d6cc8cb..61463b6ec 100644 --- a/mods/ENTITIES/mcl_boats/mod.conf +++ b/mods/ENTITIES/mcl_boats/mod.conf @@ -1,7 +1,7 @@ name = mcl_boats author = PilzAdam description = Adds drivable boats. -depends = mcl_player, flowlib +depends = mcl_player, flowlib, mcl_title optional_depends = mcl_core, doc_identifier diff --git a/mods/ENTITIES/mcl_minecarts/init.lua b/mods/ENTITIES/mcl_minecarts/init.lua index e33e120a1..a76ab538a 100644 --- a/mods/ENTITIES/mcl_minecarts/init.lua +++ b/mods/ENTITIES/mcl_minecarts/init.lua @@ -646,7 +646,7 @@ register_minecart( if player then mcl_player.player_set_animation(player, "sit" , 30) player:set_eye_offset({x=0, y=-5.5, z=0},{x=0, y=-4, z=0}) - mcl_tmp_message.message(clicker, S("Sneak to dismount")) + mcl_title.set(clicker, "actionbar", {text=S("Sneak to dismount"), color="white", stay=3}) end end, name) end diff --git a/mods/ENTITIES/mcl_minecarts/mod.conf b/mods/ENTITIES/mcl_minecarts/mod.conf index 9fff9175d..3b8ae5551 100644 --- a/mods/ENTITIES/mcl_minecarts/mod.conf +++ b/mods/ENTITIES/mcl_minecarts/mod.conf @@ -1,6 +1,6 @@ name = mcl_minecarts author = Krock description = Minecarts are vehicles to move players quickly on rails. -depends = mcl_explosions, mcl_core, mcl_sounds, mcl_player, mcl_achievements, mcl_chests, mcl_furnaces, mesecons_commandblock, mcl_hoppers, mcl_tnt, mesecons +depends = mcl_title, mcl_explosions, mcl_core, mcl_sounds, mcl_player, mcl_achievements, mcl_chests, mcl_furnaces, mesecons_commandblock, mcl_hoppers, mcl_tnt, mesecons optional_depends = doc_identifier, mcl_wip diff --git a/mods/HUD/mcl_title/init.lua b/mods/HUD/mcl_title/init.lua index 48c3a909f..03fe17614 100644 --- a/mods/HUD/mcl_title/init.lua +++ b/mods/HUD/mcl_title/init.lua @@ -45,7 +45,7 @@ local player_params = {} minetest.register_on_joinplayer(function(player) local playername = player:get_player_name() - player_params[playername] = { + player_params[player] = { stay = gametick_to_secondes(mcl_title.defaults.stay), --fadeIn = gametick_to_secondes(mcl_title.defaults.fadein), --fadeOut = gametick_to_secondes(mcl_title.defaults.fadeout), @@ -127,14 +127,13 @@ function mcl_title.set(player, type, data) return false end - --TODO: enable this code then Fleckenstein's pr get merged (in about 5-6 years) + --TODO: enable this code then Fleckenstein's pr get merged (in about 5-6 years lol) --if data.bold == nil then data.bold = false end --if data.italic == nil then data.italic = false end player:hud_change(huds_idx[type][player], "text", data.text) player:hud_change(huds_idx[type][player], "number", hex_color) - hud_hide_timeouts[type][player:get_player_name()] = data.stay or mcl_title.params_get(player).stay return true end diff --git a/mods/ITEMS/mcl_beds/functions.lua b/mods/ITEMS/mcl_beds/functions.lua index dc9afe2ba..f323ca4c7 100644 --- a/mods/ITEMS/mcl_beds/functions.lua +++ b/mods/ITEMS/mcl_beds/functions.lua @@ -330,7 +330,7 @@ function mcl_beds.on_rightclick(pos, player, is_top) message = select(2, lay_down(player, ppos, other)) end if message then - mcl_tmp_message.message(player, message) + mcl_title.set(player, "actionbar", {text=message, color="white", stay=3}) end else lay_down(player, nil, nil, false) From c31c852a6ea63eb2ffed49089881866fb59df0ed Mon Sep 17 00:00:00 2001 From: AFCMS Date: Tue, 20 Jul 2021 16:14:34 +0200 Subject: [PATCH 075/296] add documentation --- mods/ENTITIES/mcl_boats/init.lua | 2 +- mods/ENTITIES/mcl_minecarts/init.lua | 2 +- mods/HUD/mcl_title/API.md | 42 ++++++++++++++++++++++++++++ mods/HUD/mcl_title/init.lua | 2 +- mods/ITEMS/mcl_beds/functions.lua | 2 +- 5 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 mods/HUD/mcl_title/API.md diff --git a/mods/ENTITIES/mcl_boats/init.lua b/mods/ENTITIES/mcl_boats/init.lua index e81e9ffc5..311b07882 100644 --- a/mods/ENTITIES/mcl_boats/init.lua +++ b/mods/ENTITIES/mcl_boats/init.lua @@ -84,7 +84,7 @@ local function attach_object(self, obj) end end, name) obj:set_look_horizontal(yaw) - mcl_title.set(obj, "actionbar", {text=S("Sneak to dismount"), color="white", stay=3}) + mcl_title.set(obj, "actionbar", {text=S("Sneak to dismount"), color="white", stay=60}) else obj:get_luaentity()._old_visual_size = visual_size end diff --git a/mods/ENTITIES/mcl_minecarts/init.lua b/mods/ENTITIES/mcl_minecarts/init.lua index a76ab538a..4d3873cc2 100644 --- a/mods/ENTITIES/mcl_minecarts/init.lua +++ b/mods/ENTITIES/mcl_minecarts/init.lua @@ -646,7 +646,7 @@ register_minecart( if player then mcl_player.player_set_animation(player, "sit" , 30) player:set_eye_offset({x=0, y=-5.5, z=0},{x=0, y=-4, z=0}) - mcl_title.set(clicker, "actionbar", {text=S("Sneak to dismount"), color="white", stay=3}) + mcl_title.set(clicker, "actionbar", {text=S("Sneak to dismount"), color="white", stay=60}) end end, name) end diff --git a/mods/HUD/mcl_title/API.md b/mods/HUD/mcl_title/API.md new file mode 100644 index 000000000..50614be4f --- /dev/null +++ b/mods/HUD/mcl_title/API.md @@ -0,0 +1,42 @@ +# mcl_title + +Allow mods to show messages in the hud of players. + +## mcl_title.set(player, type, data) + +Show a hud message of `type` to player `player` with `data` as params. + +The element will stay for the per-player param `stay` or `data.stay` (in gametick which is 1/20 second). + +Here is a usage exemple: + +```lua +--show a title in the HUD with minecraft color "gold" +mcl_title.set(player, "title", {text="dummy text", color="gold"}) + +--show a subtitle in the HUD with hex color "#612D2D" +mcl_title.set(player, "subtitle", {text="dummy subtitle", color="#612D2D"}) + +--show an actionbar in the HUD (above the hotbar) with minecraft color "red" +mcl_title.set(player, "subtitle", {text="dummy actionbar", color="red"}) + +--show a title in the HUD with minecraft color "gold" staying for 3 seconds (override stay setting) +mcl_title.set(player, "title", {text="dummy text", color="gold", stay=3}) +``` + +## mcl_title.remove(player, type) + +Hide HUD element of type `type` for player `player`. + +## mcl_title.clear(player) + +Remove every title/subtitle/actionbar from a player. +Basicaly run `mcl_title.remove(player, type)` for every type. + +## mcl_title.params_set(player, params) + +Allow mods to set `stay` and upcomming `fadeIn`/`fadeOut` params. + +```lua +mcl_title.params_set(player, {stay = 600}) --elements with no 'data.stay' field will stay during 30s (600/20) +``` \ No newline at end of file diff --git a/mods/HUD/mcl_title/init.lua b/mods/HUD/mcl_title/init.lua index 03fe17614..d1dbece4b 100644 --- a/mods/HUD/mcl_title/init.lua +++ b/mods/HUD/mcl_title/init.lua @@ -134,7 +134,7 @@ function mcl_title.set(player, type, data) player:hud_change(huds_idx[type][player], "text", data.text) player:hud_change(huds_idx[type][player], "number", hex_color) - hud_hide_timeouts[type][player:get_player_name()] = data.stay or mcl_title.params_get(player).stay + hud_hide_timeouts[type][player:get_player_name()] = gametick_to_secondes(data.stay) or mcl_title.params_get(player).stay return true end diff --git a/mods/ITEMS/mcl_beds/functions.lua b/mods/ITEMS/mcl_beds/functions.lua index f323ca4c7..e196f69ad 100644 --- a/mods/ITEMS/mcl_beds/functions.lua +++ b/mods/ITEMS/mcl_beds/functions.lua @@ -330,7 +330,7 @@ function mcl_beds.on_rightclick(pos, player, is_top) message = select(2, lay_down(player, ppos, other)) end if message then - mcl_title.set(player, "actionbar", {text=message, color="white", stay=3}) + mcl_title.set(player, "actionbar", {text=message, color="white", stay=60}) end else lay_down(player, nil, nil, false) From 31d3ea8a871fef4acbab8493d85768ea7884ac76 Mon Sep 17 00:00:00 2001 From: NO11 Date: Tue, 20 Jul 2021 20:09:43 +0000 Subject: [PATCH 076/296] Fix #1801 (add better texture for golden boots) --- .../textures/mcl_armor_inv_boots_gold.png | Bin 167 -> 409 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_boots_gold.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_boots_gold.png index dc452d41372344c624d15270867e81ea7551b52a..ef1f9fa87ca43be01bc084da406069ce278d3c1f 100644 GIT binary patch delta 382 zcmV-^0fGLf0ht4kB!32COGiWi{{a60|De66lK=n!32;bRa{vG?BLDy{BLR4&KXw2B z00(qQO+^Rg2NVS)N@!D*zX#WvQEA z04#(nBfex{Rjq`aWmi8Z5*|?Csfm&M27np1J9o)$LRS>Zl1E_v~4!`V2#&%;Q32n c`Ir8}H*o=PdJ9oayZ`_I07*qoM6N<$g80X(CIA2c delta 139 zcmV;60CfME1E&FyB!6y6L_t(|0b>|^;Q#;s_%N*uz|=^*L1E2{L6~|5?CR0_55iDB zhB#gWt}HkG|LS1U|0NYl7zO~vz;Ylp*bIQ#0#bm>0I(cT4PFC4nsFKc#25y^G?Rl- t4M^~)Ar`|7ppFYb4017LDUoUb0H9FFs6zF<5C8xG07*qoLI9vb# From a0d52010bf6dcfe3b7fa1175dc5c76923b515eed Mon Sep 17 00:00:00 2001 From: NO11 Date: Wed, 21 Jul 2021 22:16:37 +0000 Subject: [PATCH 077/296] Fix that aliases attemp to register mineclone:book_enchanted again and again --- mods/HELP/mcl_item_id/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/HELP/mcl_item_id/init.lua b/mods/HELP/mcl_item_id/init.lua index e7772d141..01eb40362 100644 --- a/mods/HELP/mcl_item_id/init.lua +++ b/mods/HELP/mcl_item_id/init.lua @@ -28,7 +28,7 @@ tt.register_snippet(function(itemstring) end end end - minetest.register_alias(new_id, itemstring) + minetest.register_alias_force(new_id, itemstring) if minetest.settings:get_bool("mcl_item_id_debug", true) then return new_id, "#555555" end From fef23d0b6f224ed178d109ec5d74137168119421 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Thu, 22 Jul 2021 00:39:05 +0200 Subject: [PATCH 078/296] fix missing depend to `mcl_credits` of `mcl_portals` --- mods/ITEMS/mcl_portals/mod.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_portals/mod.conf b/mods/ITEMS/mcl_portals/mod.conf index d99344a76..610b590c6 100644 --- a/mods/ITEMS/mcl_portals/mod.conf +++ b/mods/ITEMS/mcl_portals/mod.conf @@ -1,4 +1,4 @@ name = mcl_portals description = Adds buildable portals to the Nether and End dimensions. -depends = mcl_nether, mcl_end, mcl_particles, mcl_spawn +depends = mcl_nether, mcl_end, mcl_particles, mcl_spawn, mcl_credits optional_depends = awards, doc From 667ef5cad51684f79debd5a133dc78f3ea29974c Mon Sep 17 00:00:00 2001 From: AFCMS Date: Thu, 22 Jul 2021 00:46:43 +0200 Subject: [PATCH 079/296] cache doc modpath --- mods/ITEMS/mcl_portals/portal_end.lua | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/mods/ITEMS/mcl_portals/portal_end.lua b/mods/ITEMS/mcl_portals/portal_end.lua index d591537e1..9f0db352a 100644 --- a/mods/ITEMS/mcl_portals/portal_end.lua +++ b/mods/ITEMS/mcl_portals/portal_end.lua @@ -4,6 +4,8 @@ local table = table local vector = vector local math = math +local has_doc = minetest.get_modpath("doc") + -- Parameters --local SPAWN_MIN = mcl_vars.mg_end_min+70 --local SPAWN_MAX = mcl_vars.mg_end_min+98 @@ -339,7 +341,7 @@ minetest.register_node("mcl_portals:end_portal_frame_eye", { _mcl_hardness = -1, }) -if minetest.get_modpath("doc") then +if has_doc then doc.add_entry_alias("nodes", "mcl_portals:end_portal_frame", "nodes", "mcl_portals:end_portal_frame_eye") end @@ -366,7 +368,7 @@ minetest.override_item("mcl_end:ender_eye", { end minetest.set_node(pointed_thing.under, { name = "mcl_portals:end_portal_frame_eye", param2 = node.param2 }) - if minetest.get_modpath("doc") then + if has_doc then doc.mark_entry_as_revealed(user:get_player_name(), "nodes", "mcl_portals:end_portal_frame") end minetest.sound_play( @@ -381,7 +383,7 @@ minetest.override_item("mcl_end:ender_eye", { -- Epic 'portal open' sound effect that can be heard everywhere minetest.sound_play("mcl_portals_open_end_portal", {gain=0.8}, true) end_portal_area(ppos) - if minetest.get_modpath("doc") then + if has_doc then doc.mark_entry_as_revealed(user:get_player_name(), "nodes", "mcl_portals:portal_end") end end From a44d9643ae8b826f1e5efb67259d6d77320dfade Mon Sep 17 00:00:00 2001 From: NO11 Date: Thu, 22 Jul 2021 19:23:48 +0000 Subject: [PATCH 080/296] Fix several problems in `mcl_item_id` --- mods/HELP/mcl_item_id/init.lua | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/mods/HELP/mcl_item_id/init.lua b/mods/HELP/mcl_item_id/init.lua index 01eb40362..3b3128f26 100644 --- a/mods/HELP/mcl_item_id/init.lua +++ b/mods/HELP/mcl_item_id/init.lua @@ -28,8 +28,12 @@ tt.register_snippet(function(itemstring) end end end - minetest.register_alias_force(new_id, itemstring) - if minetest.settings:get_bool("mcl_item_id_debug", true) then + if new_id ~= game .. ":book_enchanted" then + minetest.register_alias_force(new_id, itemstring) + end + if minetest.settings:get_bool("mcl_item_id_debug", false) then return new_id, "#555555" end end) + +minetest.register_alias_force(game .. ":book_enchanted", "mcl_enchanting:book_enchanted") From 75b425ffd77b85ba3081ddf2e47f8b6695ec8fa5 Mon Sep 17 00:00:00 2001 From: NO11 Date: Fri, 23 Jul 2021 12:23:30 +0000 Subject: [PATCH 081/296] Fix #1842 make other mods not using "mineclone" name space for item ids --- mods/HELP/mcl_item_id/init.lua | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/mods/HELP/mcl_item_id/init.lua b/mods/HELP/mcl_item_id/init.lua index 3b3128f26..50247a858 100644 --- a/mods/HELP/mcl_item_id/init.lua +++ b/mods/HELP/mcl_item_id/init.lua @@ -1,4 +1,5 @@ local game = "mineclone" +local mcl_mods = {} local same_id = { heads = { "skeleton", "zombie", "creeper", "wither_skeleton" }, @@ -10,17 +11,34 @@ local same_id = { "stonebrick", "stonebrickmossy", }, wool = { - "black", "blue", "brown", "cyan", "green", + "black", "blue", "brown", "cyan", "green", "grey", "light_blue", "lime", "magenta", "orange", "pink", "purple", "red", "silver", "white", "yellow", }, } +local worldmt = io.open(minetest.get_worldpath() .. "/world.mt", "r") +local gameid = worldmt:read("*a"):match("gameid%s*=%s*(%S+)\n") +worldmt:close() + +for _, mod in pairs(minetest.get_modnames()) do + if minetest.get_modpath(mod):match("/games/" .. gameid .. "/") then + table.insert(mcl_mods, mod) + end +end + +local function item_id(id) + if minetest.settings:get_bool("mcl_item_id_debug", false) then + return id, "#555555" + end +end + tt.register_snippet(function(itemstring) local def = minetest.registered_items[itemstring] local desc = def.description local item_split = itemstring:find(":") local new_id = game .. itemstring:sub(item_split) + local mcl_mod = itemstring:sub(1, item_split) for mod, ids in pairs(same_id) do for _, id in pairs(ids) do if itemstring == "mcl_" .. mod .. ":" .. id then @@ -28,12 +46,15 @@ tt.register_snippet(function(itemstring) end end end - if new_id ~= game .. ":book_enchanted" then - minetest.register_alias_force(new_id, itemstring) - end - if minetest.settings:get_bool("mcl_item_id_debug", false) then - return new_id, "#555555" + for _, modname in pairs(mcl_mods) do + if modname .. ":" == mcl_mod then + if new_id ~= game .. ":book_enchanted" and new_id ~= itemstring then + minetest.register_alias_force(new_id, itemstring) + end + return item_id(new_id) + end end + return item_id(itemstring) end) minetest.register_alias_force(game .. ":book_enchanted", "mcl_enchanting:book_enchanted") From 09a68443cd641ed73631cc076916616e518402ea Mon Sep 17 00:00:00 2001 From: NO11 Date: Fri, 23 Jul 2021 16:12:43 +0000 Subject: [PATCH 082/296] Better fix for #1842 (make other mods not using "mineclone" name space for item ids) --- mods/HELP/mcl_item_id/init.lua | 57 ++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/mods/HELP/mcl_item_id/init.lua b/mods/HELP/mcl_item_id/init.lua index 50247a858..4e9c7c9f1 100644 --- a/mods/HELP/mcl_item_id/init.lua +++ b/mods/HELP/mcl_item_id/init.lua @@ -1,5 +1,20 @@ +mcl_item_id = {} + local game = "mineclone" -local mcl_mods = {} + +function mcl_item_id.set_mod_namespace(modname, namespace) + local namespace = namespace or modname + mcl_item_id[modname .. "_namespace"] = namespace +end + +function mcl_item_id.get_mod_namespace(modname) + local namespace = mcl_item_id[modname .. "_namespace"] + if namespace then + return namespace + else + return "" + end +end local same_id = { heads = { "skeleton", "zombie", "creeper", "wither_skeleton" }, @@ -17,28 +32,15 @@ local same_id = { }, } -local worldmt = io.open(minetest.get_worldpath() .. "/world.mt", "r") -local gameid = worldmt:read("*a"):match("gameid%s*=%s*(%S+)\n") -worldmt:close() - -for _, mod in pairs(minetest.get_modnames()) do - if minetest.get_modpath(mod):match("/games/" .. gameid .. "/") then - table.insert(mcl_mods, mod) - end -end - -local function item_id(id) - if minetest.settings:get_bool("mcl_item_id_debug", false) then - return id, "#555555" - end -end - tt.register_snippet(function(itemstring) local def = minetest.registered_items[itemstring] local desc = def.description local item_split = itemstring:find(":") - local new_id = game .. itemstring:sub(item_split) - local mcl_mod = itemstring:sub(1, item_split) + local id_part1 = itemstring:sub(1, item_split) + local id_part2 = itemstring:sub(item_split) + local modname = id_part1:gsub("%:", "") + local new_id = game .. id_part2 + local mod_namespace = mcl_item_id.get_mod_namespace(modname) for mod, ids in pairs(same_id) do for _, id in pairs(ids) do if itemstring == "mcl_" .. mod .. ":" .. id then @@ -46,15 +48,16 @@ tt.register_snippet(function(itemstring) end end end - for _, modname in pairs(mcl_mods) do - if modname .. ":" == mcl_mod then - if new_id ~= game .. ":book_enchanted" and new_id ~= itemstring then - minetest.register_alias_force(new_id, itemstring) - end - return item_id(new_id) - end + + if mod_namespace then + new_id = mod_namespace .. id_part2 + end + if new_id ~= game .. ":book_enchanted" then + minetest.register_alias_force(new_id, itemstring) + end + if minetest.settings:get_bool("mcl_item_id_debug", false) then + return new_id, "#555555" end - return item_id(itemstring) end) minetest.register_alias_force(game .. ":book_enchanted", "mcl_enchanting:book_enchanted") From e44e9eaf623809bc2fa4c617dd6e9629aa5b3879 Mon Sep 17 00:00:00 2001 From: NO11 Date: Fri, 23 Jul 2021 21:35:10 +0000 Subject: [PATCH 083/296] Fix typo --- mods/HELP/mcl_item_id/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/HELP/mcl_item_id/init.lua b/mods/HELP/mcl_item_id/init.lua index 4e9c7c9f1..911d8225b 100644 --- a/mods/HELP/mcl_item_id/init.lua +++ b/mods/HELP/mcl_item_id/init.lua @@ -12,7 +12,7 @@ function mcl_item_id.get_mod_namespace(modname) if namespace then return namespace else - return "" + return end end From c05e57efb1f3d55c89354c28a84e76abe63aadd5 Mon Sep 17 00:00:00 2001 From: NO11 Date: Sat, 24 Jul 2021 14:09:47 +0000 Subject: [PATCH 084/296] Fix some crashes with set_mod_namespace and bugs --- mods/HELP/mcl_item_id/init.lua | 46 +++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/mods/HELP/mcl_item_id/init.lua b/mods/HELP/mcl_item_id/init.lua index 911d8225b..9a2f926e8 100644 --- a/mods/HELP/mcl_item_id/init.lua +++ b/mods/HELP/mcl_item_id/init.lua @@ -1,22 +1,38 @@ -mcl_item_id = {} +mcl_item_id = { + mod_namespaces = {}, +} local game = "mineclone" function mcl_item_id.set_mod_namespace(modname, namespace) local namespace = namespace or modname - mcl_item_id[modname .. "_namespace"] = namespace + mcl_item_id.mod_namespaces[modname] = namespace + minetest.register_on_mods_loaded(function() + for item, def in pairs(minetest.registered_items) do + local item_split = item:find(":") + if item_split then + local id_modname = item:sub(1, item_split - 1) + local id_string = item:sub(item_split) + if id_modname == modname then + minetest.register_alias_force(namespace .. id_string, item) + end + end + end + end) end function mcl_item_id.get_mod_namespace(modname) - local namespace = mcl_item_id[modname .. "_namespace"] + local namespace = mcl_item_id.mod_namespaces[modname] if namespace then return namespace else - return + return game end end local same_id = { + enchanting = { "table" }, + experience = { "bottle" }, heads = { "skeleton", "zombie", "creeper", "wither_skeleton" }, mobitems = { "rabbit", "chicken" }, walls = { @@ -34,13 +50,11 @@ local same_id = { tt.register_snippet(function(itemstring) local def = minetest.registered_items[itemstring] - local desc = def.description local item_split = itemstring:find(":") - local id_part1 = itemstring:sub(1, item_split) - local id_part2 = itemstring:sub(item_split) - local modname = id_part1:gsub("%:", "") - local new_id = game .. id_part2 - local mod_namespace = mcl_item_id.get_mod_namespace(modname) + local id_string = itemstring:sub(item_split) + local id_modname = itemstring:sub(1, item_split - 1) + local new_id = game .. id_string + local mod_namespace = mcl_item_id.get_mod_namespace(id_modname) for mod, ids in pairs(same_id) do for _, id in pairs(ids) do if itemstring == "mcl_" .. mod .. ":" .. id then @@ -48,16 +62,12 @@ tt.register_snippet(function(itemstring) end end end - - if mod_namespace then - new_id = mod_namespace .. id_part2 - end - if new_id ~= game .. ":book_enchanted" then + if mod_namespace ~= game then + new_id = mod_namespace .. id_string + else minetest.register_alias_force(new_id, itemstring) end if minetest.settings:get_bool("mcl_item_id_debug", false) then return new_id, "#555555" end -end) - -minetest.register_alias_force(game .. ":book_enchanted", "mcl_enchanting:book_enchanted") +end) \ No newline at end of file From 65d33b935ab23e6a43b069c62124d51ead05c165 Mon Sep 17 00:00:00 2001 From: NO11 Date: Sat, 24 Jul 2021 14:45:55 +0000 Subject: [PATCH 085/296] Add API-md for `mcl_item_id` --- mods/HELP/mcl_item_id/API.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 mods/HELP/mcl_item_id/API.md diff --git a/mods/HELP/mcl_item_id/API.md b/mods/HELP/mcl_item_id/API.md new file mode 100644 index 000000000..a2f244e0c --- /dev/null +++ b/mods/HELP/mcl_item_id/API.md @@ -0,0 +1,24 @@ +# mcl_item_id +Show the item ID of an item in the description. +With this API, you can register a different name space than "mineclone" for your mod. + +## mcl_item_id.set_mod_namespace(modname, namespace) +Set a name space for all items in a mod. + +* param1: the modname +* param2: (optional) string of the desired name space, if nil, it is the name of the mod + +## mcl_item_id.get_mod_namespace(modname) +Get the name space of a mod registered with mcl_item_id.set_mod_namespace(modname, namespace). + +* param1: the modname + +### Examples: + +The name of the mod is "mod" which registered an item called "mod:itemname". + +* mcl_item_id.set_mod_namespace("mod", "mymod") will show "mymod:itemname" in the description of "mod:itemname" +* mcl_item_id.set_mod_namespace(minetest.get_current_modname()) will show "mod:itemname" in the description of "mod:itemname" +* mcl_item_id.get_mod_namespace(minetest.get_current_modname()) will return "mod" + +(If no namespace is set by a mod, mcl_item_id.get_mod_namespace(minetest.get_current_modname()) will return "mineclone") From 5c5c405ccf92762af6f0757d4a3b015ff14d0d37 Mon Sep 17 00:00:00 2001 From: NO11 Date: Sat, 24 Jul 2021 15:19:10 +0000 Subject: [PATCH 086/296] Add missing check --- mods/HELP/mcl_item_id/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/HELP/mcl_item_id/init.lua b/mods/HELP/mcl_item_id/init.lua index 9a2f926e8..e6df1af03 100644 --- a/mods/HELP/mcl_item_id/init.lua +++ b/mods/HELP/mcl_item_id/init.lua @@ -13,7 +13,7 @@ function mcl_item_id.set_mod_namespace(modname, namespace) if item_split then local id_modname = item:sub(1, item_split - 1) local id_string = item:sub(item_split) - if id_modname == modname then + if id_modname == modname and modname ~= namespace then minetest.register_alias_force(namespace .. id_string, item) end end From 4846076c8fc2555dff12bf148c5b1d83ab39ec9d Mon Sep 17 00:00:00 2001 From: NO11 Date: Sat, 24 Jul 2021 19:07:44 +0000 Subject: [PATCH 087/296] `mcl_item_id` simplify code --- mods/HELP/mcl_item_id/init.lua | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/mods/HELP/mcl_item_id/init.lua b/mods/HELP/mcl_item_id/init.lua index e6df1af03..f3e6d2735 100644 --- a/mods/HELP/mcl_item_id/init.lua +++ b/mods/HELP/mcl_item_id/init.lua @@ -7,18 +7,6 @@ local game = "mineclone" function mcl_item_id.set_mod_namespace(modname, namespace) local namespace = namespace or modname mcl_item_id.mod_namespaces[modname] = namespace - minetest.register_on_mods_loaded(function() - for item, def in pairs(minetest.registered_items) do - local item_split = item:find(":") - if item_split then - local id_modname = item:sub(1, item_split - 1) - local id_string = item:sub(item_split) - if id_modname == modname and modname ~= namespace then - minetest.register_alias_force(namespace .. id_string, item) - end - end - end - end) end function mcl_item_id.get_mod_namespace(modname) @@ -64,7 +52,8 @@ tt.register_snippet(function(itemstring) end if mod_namespace ~= game then new_id = mod_namespace .. id_string - else + end + if mod_namespace ~= id_modname then minetest.register_alias_force(new_id, itemstring) end if minetest.settings:get_bool("mcl_item_id_debug", false) then From 4aabd7d9e721a860864157ac5145985d8a2360b9 Mon Sep 17 00:00:00 2001 From: NO11 Date: Sun, 1 Aug 2021 12:10:00 +0000 Subject: [PATCH 088/296] Make size/position of potion HUD more MC like --- mods/ITEMS/mcl_potions/functions.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mods/ITEMS/mcl_potions/functions.lua b/mods/ITEMS/mcl_potions/functions.lua index 09b95115a..c3b034b66 100644 --- a/mods/ITEMS/mcl_potions/functions.lua +++ b/mods/ITEMS/mcl_potions/functions.lua @@ -35,13 +35,13 @@ local function potions_init_icons(player) local name = player:get_player_name() icon_ids[name] = {} for e=1, EFFECT_TYPES do - local x = -7 + -38 * e + local x = -52 * e - 2 local id = player:hud_add({ hud_elem_type = "image", text = "blank.png", position = { x = 1, y = 0 }, - offset = { x = x, y = 272 }, - scale = { x = 2, y = 2 }, + offset = { x = x, y = 3 }, + scale = { x = 3, y = 3 }, alignment = { x = 1, y = 1 }, z_index = 100, }) From 5c563d6ffd16ba6d64691fff5e0356b85eb4fe80 Mon Sep 17 00:00:00 2001 From: NO11 Date: Mon, 2 Aug 2021 12:24:34 +0000 Subject: [PATCH 089/296] Make eating particles much more MC like! --- mods/PLAYER/mcl_hunger/hunger.lua | 32 ++++++++++++------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/mods/PLAYER/mcl_hunger/hunger.lua b/mods/PLAYER/mcl_hunger/hunger.lua index 5dec8b1b0..d9a6fd5fe 100644 --- a/mods/PLAYER/mcl_hunger/hunger.lua +++ b/mods/PLAYER/mcl_hunger/hunger.lua @@ -152,26 +152,18 @@ function mcl_hunger.item_eat(hunger_change, replace_with_item, poisontime, poiso -- If false, force item to not spawn any food partiles when eaten if def._food_particles ~= false and texture and texture ~= "" then local v = user:get_velocity() or user:get_player_velocity() - local minvel = vector.add(v, {x=-1, y=1, z=-1}) - local maxvel = vector.add(v, {x=1, y=2, z=1}) - - minetest.add_particlespawner({ - amount = math.min(math.max(8, hunger_change*2), 25), - time = 0.1, - minpos = {x=pos.x, y=pos.y, z=pos.z}, - maxpos = {x=pos.x, y=pos.y, z=pos.z}, - minvel = minvel, - maxvel = maxvel, - minacc = {x=0, y=-5, z=0}, - maxacc = {x=0, y=-9, z=0}, - minexptime = 1, - maxexptime = 1, - minsize = 1, - maxsize = 2, - collisiondetection = true, - vertical = false, - texture = texture, - }) + for i = 0, math.min(math.max(8, hunger_change*2), 25) do + minetest.add_particle({ + pos = { x = pos.x, y = pos.y, z = pos.z }, + velocity = vector.add(v, { x = math.random(-1, 1), y = math.random(1, 2), z = math.random(-1, 1) }), + acceleration = { x = 0, y = math.random(-9, -5), z = 0 }, + expirationtime = 1, + size = math.random(1, 2), + collisiondetection = true, + vertical = false, + texture = "[combine:3x3:" .. -i .. "," .. -i .. "=" .. texture, + }) + end end minetest.sound_play("mcl_hunger_bite", { max_hear_distance = 12, From df0c1f1dd1e32dc74a1b9e9a767037c517cdf071 Mon Sep 17 00:00:00 2001 From: Emily Date: Fri, 6 Aug 2021 11:14:17 +0200 Subject: [PATCH 090/296] Make bows and fishing rods show their durability in description (Fixes issue #1773) --- mods/HELP/mcl_tt/snippets_mcl.lua | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mods/HELP/mcl_tt/snippets_mcl.lua b/mods/HELP/mcl_tt/snippets_mcl.lua index 3c79f52e8..121d8ed70 100644 --- a/mods/HELP/mcl_tt/snippets_mcl.lua +++ b/mods/HELP/mcl_tt/snippets_mcl.lua @@ -107,3 +107,8 @@ tt.register_snippet(function(itemstring) end end) +tt.register_snippet(function(itemstring, _, itemstack) + if itemstring:sub(1, 23) == "mcl_fishing:fishing_rod" or itemstring:sub(1, 12) == "mcl_bows:bow" then + return S("Durability: @1 uses", mcl_util.calculate_durability(itemstack or ItemStack(itemstring))) + end +end) From 5bb57a81ad46c163b58da046920b8a4bee18b30b Mon Sep 17 00:00:00 2001 From: Emily Date: Fri, 6 Aug 2021 11:55:27 +0200 Subject: [PATCH 091/296] Add durability tooltip to translation template --- mods/HELP/mcl_tt/locale/template.txt | 1 + mods/HELP/mcl_tt/snippets_mcl.lua | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/mods/HELP/mcl_tt/locale/template.txt b/mods/HELP/mcl_tt/locale/template.txt index 1259216c7..6fb735b13 100644 --- a/mods/HELP/mcl_tt/locale/template.txt +++ b/mods/HELP/mcl_tt/locale/template.txt @@ -45,3 +45,4 @@ Mining durability: @1= Block breaking strength: @1= @1 uses= Unlimited uses= +Durability: @1= diff --git a/mods/HELP/mcl_tt/snippets_mcl.lua b/mods/HELP/mcl_tt/snippets_mcl.lua index 121d8ed70..825776f5f 100644 --- a/mods/HELP/mcl_tt/snippets_mcl.lua +++ b/mods/HELP/mcl_tt/snippets_mcl.lua @@ -109,6 +109,6 @@ end) tt.register_snippet(function(itemstring, _, itemstack) if itemstring:sub(1, 23) == "mcl_fishing:fishing_rod" or itemstring:sub(1, 12) == "mcl_bows:bow" then - return S("Durability: @1 uses", mcl_util.calculate_durability(itemstack or ItemStack(itemstring))) + return S("Durability: @1", S("@1 uses", mcl_util.calculate_durability(itemstack or ItemStack(itemstring)))) end end) From 664c2381374ee25f423d2b0d0eb66b838257eca6 Mon Sep 17 00:00:00 2001 From: NO11 Date: Fri, 6 Aug 2021 10:52:55 +0000 Subject: [PATCH 092/296] Add german translation for the bow/fishing rod desc --- mods/HELP/mcl_tt/locale/mcl_tt.de.tr | 1 + 1 file changed, 1 insertion(+) diff --git a/mods/HELP/mcl_tt/locale/mcl_tt.de.tr b/mods/HELP/mcl_tt/locale/mcl_tt.de.tr index 8f878afc7..54c376c3b 100644 --- a/mods/HELP/mcl_tt/locale/mcl_tt.de.tr +++ b/mods/HELP/mcl_tt/locale/mcl_tt.de.tr @@ -45,3 +45,4 @@ Mining durability: @1=Grabehaltbarkeit: @1 Block breaking strength: @1=Blockbruchstärke: @1 @1 uses=@1 Verwendungen Unlimited uses=Unbegrenzte Verwendungen +Durability: @1=Haltbarkeit: @1 From f8dcf056707c917f2b77aead6669ee0d05905c86 Mon Sep 17 00:00:00 2001 From: NO11 Date: Wed, 11 Aug 2021 15:41:45 +0000 Subject: [PATCH 093/296] Add MC like nodebox for anvils --- mods/ITEMS/mcl_anvils/init.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mods/ITEMS/mcl_anvils/init.lua b/mods/ITEMS/mcl_anvils/init.lua index fbf6fb751..51b78da6f 100644 --- a/mods/ITEMS/mcl_anvils/init.lua +++ b/mods/ITEMS/mcl_anvils/init.lua @@ -297,9 +297,10 @@ local anvildef = { node_box = { type = "fixed", fixed = { - {-8/16, 2/16, -5/16, 8/16, 8/16, 5/16}, -- top - {-5/16, -4/16, -2/16, 5/16, 5/16, 2/16}, -- middle - {-8/16, -8/16, -5/16, 8/16, -4/16, 5/16}, -- base + { -6/16, -8/16, -6/16, 6/16, -4/16, 6/16 }, + { -5/16, -4/16, -4/16, 5/16, -3/16, 4/16 }, + { -4/16, -3/16, -2/16, 4/16, 2/16, 2/16 }, + { -8/16, 2/16, -5/16, 8/16, 8/16, 5/16 }, } }, sounds = mcl_sounds.node_sound_metal_defaults(), From cb55c36863b429a8328c98bc478d525d081727ca Mon Sep 17 00:00:00 2001 From: NO11 Date: Wed, 11 Aug 2021 15:44:43 +0000 Subject: [PATCH 094/296] Correct the texture of anvils Because of the new node_nox, the textures have to be a little bit bigger. --- .../mcl_anvils_anvil_top_damaged_0.png | Bin 195 -> 6074 bytes .../mcl_anvils_anvil_top_damaged_1.png | Bin 209 -> 5855 bytes .../mcl_anvils_anvil_top_damaged_2.png | Bin 220 -> 5882 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/mods/ITEMS/mcl_anvils/textures/mcl_anvils_anvil_top_damaged_0.png b/mods/ITEMS/mcl_anvils/textures/mcl_anvils_anvil_top_damaged_0.png index 84c64e9159abbd2703d701a32211caa4cc9b8418..43938aa7265afa58d0394ae683e7815a6159dc40 100644 GIT binary patch literal 6074 zcmeHLc~leE8Xr&uBUW6hpdcYERbaA_1QLnL5+DK+AS~8(GBd%^WF{s9Nd&d1R0PEx zH*hKL3l*y(wSrVZT2aAbU5co>hf9Ifr`Vsmazd}VTxU)EOh5kIO6y+Vtdc~$0%5X z4Xl(6749Bmk3Y;QKN~bc2-&=Bm*%;ugOl5;behBa`K4^Tm&y*i+JgDlrCWU?e-5d$ zPt%6oeGzzMNrz?*X^+eeT;?aXFFU>J_Pm8(SYi>OCv4l2X~sWVMP7Yd<6f1&xt%O5 zYCkseVN7Z@oA`EF(7A7417RJjxqTOXlWl!#{9}%CaCOFZ=Rv^pzF++{bls1K4+p)R zQL<7|i^s8ZO3D2lGrwxFE*@@ElB@bv)PfLdhdJg&3nuUPJ9_NNHP^?$-Z85;?X7yc zLpdHV7c4n@$HTVu&p=;4zmpb?@~LEb^r%6LvV*eSU1uFxUM%xV&-QM9xUpY)!?78@ z!OS3!XGm+na`EwfGggM1o$M1kt)R-sJL?Y3!hT9$k2&XP7t)5viS{!u9_~5HG%_59 z#-?YUuo@VYkY5;Y;lC%`;TOO#_DaNq%is9fu`OLTkabg$?E#ag1}kmUhh$YvR~Dv- z?Eyv(Xw~O>;SL8or{L>e$u&-=&DvaiXe!SH*?7j3fv%Hb`-;A`7t2RRz+k^7WsRqe zQ~7OC+Wd{DVpyuG6@_NQCn(Njqz`8Kedm&plUSegB7a!P-Q|VTetJ=7={S$(c9mXg z;kb~-*-=rw&1V8xebxpJ>$}9wF!5^cA^OhBYshBT6OFnG&TjLTA(M9;uMd^EX3L8< zWr!lDzT(%!{}wc2$B}E{g2EP1H7B%x)a+f?+|KiF`e%aR?;%f))NN_{A!rSMWZ0{; z`32t|tcw^{b8abl;gs!U^E<^}fS>L`nC0Q@nBDohUCwu6t(+%3x+`y3mg;w6U}#?1 zjm)CK#IM&o%0@)om+yWW!QL%O98h_~*m~;gC&cFOmJhdnHT$aH!Yzqm#vftdMiK{QJb5 zt%{Zv8{8e7CDo3%jl<4bUHW10qS;Nx>HU|wjrNMlb-Q}4a>@Mb;a|!En(y8A_dMy#{qb2`)`GmeI)w}B9-WmHs%i7MXN2Kh3G5hIW_mkr%44CzJ#*!A?7_WH-P;jgH!EY)oiG_b?cTA6G5hW-);V5mwOMm^TqUA*H(K{s`4vq9nP63J43-_ew$qTH8PMEws z#&S()$u?=grTY3&$A{Xt#UBtI_j%lK%iU_BBOS*lW-z1bJ68K=+78HS{qt$vou>|T zo<|rz*$s%sXl=+S`XdrktO41c*0)~qjO(#kibPN$Q;`rh0a7_R@6APKEMWg3V zl*4mp!$O2HZY<5$ATp>mYLtZN2DJ*;i40KZ334_2aRE4ThoYb*6OwN0F5>vh_(0l8l-k2olNpDbVy7}Kj zztzhGHt8w~B;Z6Us5DT_pz;+V1dJgf(@$?D3JJO1Fz5pd1t3oVL!i(H^#M5?C7bU9 zb0EGKzXz2R*O3qoqZE}vtzlvqBH}9$0iVwmfP5~BfIKc&0s1KUN|2B6IX;k=5{8uA z9uyH;ECItIRnM#_Dg;AB9E8I`x!!D0$%he;heCW%feMr$#8-N;AwG{ML{JkIRR@uu zOe$t@ne2BnG8IHB39VYph{JG%(Cgm4l4EK#nuI9XI0CMZK*;wNa(Fzhkk5Muibb_L zjKC>Y4x7pCOdEkkL4;Nfkzxj>h7wSg22U`#P=%qEgW@Dab%&V2G0hv)8c~22g-Ajx zCkU08L1jy)C{0a8_w8yIQ5XT698F*pp*pUs=lr1rmTBl~>LrQc!{Gm5ik?a6@&AqI z9kiRpPfO|v?d%9`gkly7lON~#5V)Hu3QfRtq}C|?n??N_&bM>JhG069&>DNhk4EQo zjyjJd6=sr(PB$F`A_(r3Uk4?jh^YkKui%*wo`51^MpyT|b-_Nckrj|P7lKe8h`ha=d*Yj+d}=M|8932qme9w5VSKij!hSFs9a+>P#Qiwf{!HpN)Pd zN^LGSmjkk?9+PvtMO?0k=fmi%_CLBj0atAEAH;aug8Hi{m5Y zA#B0>>Hc4qClv8HZ!Q{~zdTf`8b$n(Lpn&p|%PKFjq<_F1k^vd?mTl6{uzlkBrxpJX4Ci}vn|0*WJI zhMqBQEcR%+I{*N-vM{*>002lueS6^Z`C_qHDwVpqxp{he?mT#F0001HWYolHVEp~7 zN@}184Gsj-EgV7s0O+d;nWO`NeuJsU4A_)o3jly6DGirc-m~gAz`@I{au?+^T^i^o zx4Hr@D;;=>Zq@tIBlb|b+~zm)A*Za5Ir3Vb9I74EKeu*qx-BlG4Zrl9Sru|NHpAo8 zgG+gi&njvgCcQdnQGYH4N1wiNx{%}XgN&^}8(RWPrj*bddoQ8&J9&UN@{rxo*mcy` O6RBikV7~v1h5rJhQRw{u delta 168 zcmV;Z09XIIFT(+lBYyxAP)t-s0000rH8njwJxNJPCMG5_g{t@2{xwnxfY!o1m=5Hpkx&&VMYdA3f<* zke78TURM65f7Q&E)6%q1(c%DjCf&CglDtjw&Pyg17tXM5Xa4ki$W+k}+Y+apP1z&a(J1~8He2!hrX@5T9>9(DYWq)wO zmXCRDm7WOQ&aQtf^mvbixr}V*-pJLw2(GW->sQ@xep+U6HF3Gkw#-Med?u_RFg_rVKp2K{wOpwbzKyg3}j% zXw!T990s$TT%$;Kk8=X>p*pWt+18=cXGER;7lr=k{A@ z*ANyWaJqD6iVcn?O{Zvx9?rFL8?wsav;~Tv%~KvUXVM6LmSb)#RN+Ou=FO#IRwjB1_h! zdrg}0nq3uI_AB-w85yR1=nA^qCNBZF6=dn+Q~brub* zGoq4QTAqIS(3*oud05E^ne(jph69C?yj>xuuZ9dycyNyh&dBs!_bL%^pC=7@MHE!$ z`;RS1A%(v9{zUGbhY8UMhtDt%ygGCn`>X9jd(DH*u@O(R6nX1xZ^$3TL`0 zMP~ioU-ehk_L-A?yTL|XLwUaW+?8#m7fMQ2Y#ofb?RXck?b4-;;c;W}gq7P@Ca%{1 zc-?H+L%{)A$-D=n9+uh9^B}+eGfR;3Dq-i`kuM8XEBc<=H=i+gchvEUKMqOf{LAey zJ>zENvWxFCF1}l9mf`WDlzMZ`vpG?fP5YVmCbhd2$fj=R>^-(7@uvHf-#HJqXTD!N z`1-jmF1K%0n!0LCi~RTJU?nZ%TAFqo*3%qvczFW0TyWshU5vSHJARRS3ROr0ZB^Lllsi?1Sn9$ev zLE+rCrURm!gs zms`&aiOP1+tMzjh(E{7bH8<{YF8i-FU+)M(+Y|J5`=XzSOO{PNAGUPsQrGkyla6I+ zqVF9&J9Ss>)YkQFsmVtVWjFFKG4#0`vra=anw^50NCcEkDrh2!QjE}a3Kd`o z&#^j{2%e1)WHBN`F#+XS>2V4fl?W(P*ujiol`j&D2F}Hih`Aw=@Z8xjPeK{%W#y^k z>l7*lLWsyZg&b4!bpnb}myfCWhHg5AY=jWA1(fLEFtV=_N60K1i^ib(>(F?J;$=nl z#3fRGxZn6r30xu-P+|!}#i!G?S}je>q$zP39pv$NbOuC+ASy1AQq>62rCtIok&FoX$-nT(SxBT{Nq36`z%8pnV>@G;fPwP z!C}Nd9>ECL?nza0jkaiZfh|z-X@;Zg8OTP#DqhCg_(O15o64n@! z3jG8W!+iM?C5%e=#-ALJ%j6*(HdP8SK`M*I^`P>kVh)wVg&~9oa+q8RvzwFi^^p&xl|U{gG1#ZA|90`mT)|zJRXzF+4(gvekU=mBv(cx;YwW*$&CeiVYMQ6*+j1sOC5GSVe5 zf4mY`hzJ1%RfuE=U4_Yv1BQ(;EC;~|k>PX*D4?-lr%>^IaYRHY@kpgoE}$4@OEyRv z4;9(7^SJPXl(3O#1S1l|iR(ObJ|Y?2*z`1>C4b%L!T+Tc5v$Z<|DVn$XqSpNPH2_* z>`**Z9EZTfmvue|?otXzWT=|J6NG=WsQES?7_79&(x!r)R_Y#5@7UoT>(ZKK6!(1gyy)002NQLKy7d>w#q-TNifa9@7W_0OEvx z-jSBqT`Er6n1Ysmlj4#!x%)SzaDO1L-UaBbs=cRct&4|ev;%}A0Rma`<6kW*+O_w3 z@+>ay?G!GKt4RsnpMOXCW|is8`UkGVZ|ydJvn_vglHU7z!Ut$@-TI$bj_}&tx0C_4 akwUgRUaj0-vC;5ngU~<3Z@15^lz#)4DYXCq delta 163 zcmV;U09^myEztpxBL)B%P)t-slm8VMe;sF9xBvhE0d!JMQvg8b*k%9#0B1==K~#7F z9m~ND0zn8yVRmd_SutKmw*g}ZBrp|#Q-K{g{Tu$8}E3 za0gU)FPMq~VeUxoV_~1)8Mu6f0uhP5d4|=ssf}NuvD_28@-6qm<9r^S{_@Ka5oW~6 RhyMTo002ovPDHLkV1mc^K{fyY diff --git a/mods/ITEMS/mcl_anvils/textures/mcl_anvils_anvil_top_damaged_2.png b/mods/ITEMS/mcl_anvils/textures/mcl_anvils_anvil_top_damaged_2.png index 5f5cfbffa6f0ebd6c1fa06ad201cb312ca6875e0..096f65eac2203e52431aebcd73c473f68a690441 100644 GIT binary patch literal 5882 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 ByH@}J delta 171 zcmV;c0960_E!+W+BL)B)P)t-slM5Cbe{A6T_y7O^0d!JMQvg8b*k%9#0B=b|K~#7F zV_;xZHWCt6U|?Wiatuo=0Wp|GDl*&+Kn#!eaEM4nNO_3>h~Zu$=mKU4I*Nybr5xQW z(!tux(!*LIx-v>azzmo0a!0U~dwGc Date: Fri, 13 Aug 2021 11:35:18 +0200 Subject: [PATCH 095/296] Update French translation (part 1) --- mods/ENTITIES/mcl_boats/locale/mcl_boats.fr.tr | 5 +++-- .../mcl_minecarts/locale/mcl_minecarts.fr.tr | 1 + mods/ENTITIES/mobs_mc/locale/template.txt | 1 + mods/HELP/doc/doc_items/locale/doc_items.fr.tr | 2 +- mods/HUD/mcl_credits/locale/mcl_credits.de.tr | 1 + mods/HUD/mcl_credits/locale/mcl_credits.es.tr | 14 ++++++++++++++ mods/HUD/mcl_credits/locale/mcl_credits.fr.tr | 14 ++++++++++++++ mods/HUD/mcl_credits/locale/mcl_credits.pl.tr | 14 ++++++++++++++ mods/HUD/mcl_credits/locale/mcl_credits.ru.tr | 14 ++++++++++++++ mods/ITEMS/mcl_chests/init.lua | 2 +- mods/ITEMS/mcl_chests/locale/template.txt | 2 +- .../ITEMS/mcl_fireworks/locale/mcl_fireworks.es.tr | 3 +++ .../ITEMS/mcl_fireworks/locale/mcl_fireworks.fr.tr | 3 +++ .../ITEMS/mcl_fireworks/locale/mcl_fireworks.ru.tr | 3 +++ mods/ITEMS/mcl_maps/locale/mcl_maps.fr.tr | 5 ++++- 15 files changed, 78 insertions(+), 6 deletions(-) create mode 100644 mods/HUD/mcl_credits/locale/mcl_credits.es.tr create mode 100644 mods/HUD/mcl_credits/locale/mcl_credits.fr.tr create mode 100644 mods/HUD/mcl_credits/locale/mcl_credits.pl.tr create mode 100644 mods/HUD/mcl_credits/locale/mcl_credits.ru.tr create mode 100644 mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.es.tr create mode 100644 mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.fr.tr create mode 100644 mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.ru.tr diff --git a/mods/ENTITIES/mcl_boats/locale/mcl_boats.fr.tr b/mods/ENTITIES/mcl_boats/locale/mcl_boats.fr.tr index 04d6d9da9..785d50146 100644 --- a/mods/ENTITIES/mcl_boats/locale/mcl_boats.fr.tr +++ b/mods/ENTITIES/mcl_boats/locale/mcl_boats.fr.tr @@ -6,6 +6,7 @@ Boats are used to travel on the surface of water.=Les bateaux sont utilisés pou Dark Oak Boat=Bateau en Chêne Noir Jungle Boat=Bateau en Acajou Oak Boat=Bateau en Chêne -Rightclick on a water source to place the boat. Rightclick the boat to enter it. Use [Left] and [Right] to steer, [Forwards] to speed up and [Backwards] to slow down or move backwards. Rightclick the boat again to leave it, punch the boat to make it drop as an item.=Faites un clic droit sur une source d'eau pour placer le bateau. Faites un clic droit sur le bateau pour y entrer. Utilisez [Gauche] et [Droite] pour diriger, [Avant] pour accélérer et [Arrière] pour ralentir ou reculer. Cliquez de nouveau avec le bouton droit sur le bateau pour le quitter, frappez le bateau pour le faire tomber en tant qu'objet. +Rightclick on a water source to place the boat. Rightclick the boat to enter it. Use [Left] and [Right] to steer, [Forwards] to speed up and [Backwards] to slow down or move backwards. Use [Sneak] to leave the boat, punch the boat to make it drop as an item.=Faites un clic droit sur une source d'eau pour placer le bateau. Faites un clic droit sur le bateau pour y entrer. Utilisez [Gauche] et [Droite] pour diriger, [Avant] pour accélérer et [Arrière] pour ralentir ou reculer. Utilisez [Sneak] pour le quitter, frappez le bateau pour le faire tomber en tant qu'objet. Spruce Boat=Bateau en Sapin -Water vehicle=Véhicule aquatique \ No newline at end of file +Water vehicle=Véhicule aquatique +Sneak to dismount= \ No newline at end of file diff --git a/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.fr.tr b/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.fr.tr index 39cdfd013..67ed5eb1b 100644 --- a/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.fr.tr +++ b/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.fr.tr @@ -33,3 +33,4 @@ Activates minecarts when powered=Active les wagonnets lorsqu'il est alimenté Emits redstone power when a minecart is detected=Émet de l'énergie redstone lorsqu'un wagonnet est détecté Vehicle for fast travel on rails=Véhicule pour voyager rapidement sur rails Can be ignited by tools or powered activator rail=Peut être allumé par des outils ou un rail d'activation motorisé +Sneak to dismount= \ No newline at end of file diff --git a/mods/ENTITIES/mobs_mc/locale/template.txt b/mods/ENTITIES/mobs_mc/locale/template.txt index 04ba9e465..7b55c1b89 100644 --- a/mods/ENTITIES/mobs_mc/locale/template.txt +++ b/mods/ENTITIES/mobs_mc/locale/template.txt @@ -28,6 +28,7 @@ Pig= Polar Bear= Rabbit= Killer Bunny= +The Killer Bunny= Sheep= Shulker= Silverfish= diff --git a/mods/HELP/doc/doc_items/locale/doc_items.fr.tr b/mods/HELP/doc/doc_items/locale/doc_items.fr.tr index 5d655404d..824ceeeba 100644 --- a/mods/HELP/doc/doc_items/locale/doc_items.fr.tr +++ b/mods/HELP/doc/doc_items/locale/doc_items.fr.tr @@ -2,7 +2,7 @@ Using it as fuel turns it into: @1.=L'utiliser comme combustible le transforme en : @1. @1 seconds=@1 secondes # Item count times item name -%@1×@2=%@1×@ +@1×@2=@1×@ # Itemname (25%) @1 (@2%)=@1 (@2%) # Itemname (<0.5%) diff --git a/mods/HUD/mcl_credits/locale/mcl_credits.de.tr b/mods/HUD/mcl_credits/locale/mcl_credits.de.tr index 6a38d18e6..fa26f5bc4 100644 --- a/mods/HUD/mcl_credits/locale/mcl_credits.de.tr +++ b/mods/HUD/mcl_credits/locale/mcl_credits.de.tr @@ -7,6 +7,7 @@ Creator of MineClone2=Schöpfer von MineClone2 Developers=Entwickler Jump to speed up (additionally sprint)=Springen, um zu beschleunigen (zusätzlich sprinten) Maintainers=Betreuer +MineClone5=MineClone5 Original Mod Authors=Original-Mod-Autoren Sneak to skip=Schleichen zum Überspringen Textures=Texturen diff --git a/mods/HUD/mcl_credits/locale/mcl_credits.es.tr b/mods/HUD/mcl_credits/locale/mcl_credits.es.tr new file mode 100644 index 000000000..a8886286e --- /dev/null +++ b/mods/HUD/mcl_credits/locale/mcl_credits.es.tr @@ -0,0 +1,14 @@ +# textdomain: mcl_credits +3D Models= +A faithful Open Source clone of Minecraft= +Contributors= +Creator of MineClone= +Creator of MineClone2= +Developers= +Jump to speed up (additionally sprint)= +Maintainers= +MineClone5= +Original Mod Authors= +Sneak to skip= +Textures= +Translations= \ No newline at end of file diff --git a/mods/HUD/mcl_credits/locale/mcl_credits.fr.tr b/mods/HUD/mcl_credits/locale/mcl_credits.fr.tr new file mode 100644 index 000000000..b34249eff --- /dev/null +++ b/mods/HUD/mcl_credits/locale/mcl_credits.fr.tr @@ -0,0 +1,14 @@ +# textdomain: mcl_credits +3D Models=Modèles 3D +A faithful Open Source clone of Minecraft=Un clone open source de Minecraft +Contributors=Contributeurs +Creator of MineClone=Créateur de MineClone +Creator of MineClone2=Créateur de MineClone2 +Developers=Développeurs +Jump to speed up (additionally sprint)=Saut pour accélérer (peut être combiné avec sprint) +Maintainers=Mainteneurs +MineClone5=MineClone5 +Original Mod Authors=Auteurs des mods originaux +Sneak to skip=Shift pour passer +Textures=Textures +Translations=Traductions \ No newline at end of file diff --git a/mods/HUD/mcl_credits/locale/mcl_credits.pl.tr b/mods/HUD/mcl_credits/locale/mcl_credits.pl.tr new file mode 100644 index 000000000..a8886286e --- /dev/null +++ b/mods/HUD/mcl_credits/locale/mcl_credits.pl.tr @@ -0,0 +1,14 @@ +# textdomain: mcl_credits +3D Models= +A faithful Open Source clone of Minecraft= +Contributors= +Creator of MineClone= +Creator of MineClone2= +Developers= +Jump to speed up (additionally sprint)= +Maintainers= +MineClone5= +Original Mod Authors= +Sneak to skip= +Textures= +Translations= \ No newline at end of file diff --git a/mods/HUD/mcl_credits/locale/mcl_credits.ru.tr b/mods/HUD/mcl_credits/locale/mcl_credits.ru.tr new file mode 100644 index 000000000..a8886286e --- /dev/null +++ b/mods/HUD/mcl_credits/locale/mcl_credits.ru.tr @@ -0,0 +1,14 @@ +# textdomain: mcl_credits +3D Models= +A faithful Open Source clone of Minecraft= +Contributors= +Creator of MineClone= +Creator of MineClone2= +Developers= +Jump to speed up (additionally sprint)= +Maintainers= +MineClone5= +Original Mod Authors= +Sneak to skip= +Textures= +Translations= \ No newline at end of file diff --git a/mods/ITEMS/mcl_chests/init.lua b/mods/ITEMS/mcl_chests/init.lua index cd66c3fc4..69f6a601d 100644 --- a/mods/ITEMS/mcl_chests/init.lua +++ b/mods/ITEMS/mcl_chests/init.lua @@ -1133,7 +1133,7 @@ for color, desc in pairs(boxtypes) do if mod_doc then if is_canonical then longdesc = S("A shulker box is a portable container which provides 27 inventory slots for any item except shulker boxes. Shulker boxes keep their inventory when broken, so shulker boxes as well as their contents can be taken as a single item. Shulker boxes come in many different colors.") - usagehelp = S("To access the inventory of a shulker box, place and right-click it. To take a shulker box and its contents with you, just break and collect it, the items will not fall out.") + usagehelp = S("To access the inventory of a shulker box, place and right-click it. To take a shulker box and its contents with you, just break and collect it, the items will not fall out. Place the shulker box again to be able to retrieve its contents.") entry_name = S("Shulker Box") else create_entry = false diff --git a/mods/ITEMS/mcl_chests/locale/template.txt b/mods/ITEMS/mcl_chests/locale/template.txt index 1d947184b..d680c24c9 100644 --- a/mods/ITEMS/mcl_chests/locale/template.txt +++ b/mods/ITEMS/mcl_chests/locale/template.txt @@ -24,7 +24,7 @@ Red Shulker Box= Grey Shulker Box= Black Shulker Box= A shulker box is a portable container which provides 27 inventory slots for any item except shulker boxes. Shulker boxes keep their inventory when broken, so shulker boxes as well as their contents can be taken as a single item. Shulker boxes come in many different colors.= -To access the inventory of a shulker box, place and right-click it. To take a shulker box and its contents with you, just break and collect it, the items will not fall out.= +To access the inventory of a shulker box, place and right-click it. To take a shulker box and its contents with you, just break and collect it, the items will not fall out. Place the shulker box again to be able to retrieve its contents.= Shulker Box= Large Chest= Inventory= diff --git a/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.es.tr b/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.es.tr new file mode 100644 index 000000000..e66eb06a5 --- /dev/null +++ b/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.es.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_fireworks +Firework Rocket= +Flight Duration:= \ No newline at end of file diff --git a/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.fr.tr b/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.fr.tr new file mode 100644 index 000000000..b02faa428 --- /dev/null +++ b/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.fr.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_fireworks +Firework Rocket=Fusée +Flight Duration:=Durée de vol : \ No newline at end of file diff --git a/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.ru.tr b/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.ru.tr new file mode 100644 index 000000000..e66eb06a5 --- /dev/null +++ b/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.ru.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_fireworks +Firework Rocket= +Flight Duration:= \ No newline at end of file diff --git a/mods/ITEMS/mcl_maps/locale/mcl_maps.fr.tr b/mods/ITEMS/mcl_maps/locale/mcl_maps.fr.tr index 9ef7cd5c5..1808e839d 100644 --- a/mods/ITEMS/mcl_maps/locale/mcl_maps.fr.tr +++ b/mods/ITEMS/mcl_maps/locale/mcl_maps.fr.tr @@ -1,5 +1,8 @@ # textdomain: mcl_maps Empty Map=Carte Vierge Empty maps are not useful as maps, but they can be stacked and turned to maps which can be used.=Les cartes vierges ne sont pas utiles en tant que cartes, mais elles peuvent être empilées et transformées en cartes utilisables. -Rightclick to start using the map (which can't be stacked anymore).=Clic droit pour commencer à utiliser la carte (qui ne peut plus être empilée). +Rightclick to create a filled map (which can't be stacked anymore).=Clic droit pour créer une carte remplie (qui ne peut plus être empilée). Map=Carte +Shows a map image.=Affiche une carte. +When created, the map saves the nearby area as an image that can be viewed any time by holding the map.=Lors de sa création, la carte sauvegarde le terrain proche sous forme d'image qui peut être consultée n'importe quand en tenant la carte dans la main. +Hold the map in your hand. This will display a map on your screen.=Tenez la carte dans votre main. Cela affichera la carte à l'écran. From 58a292a4f3edcf6816936b89a6b32275fb785299 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Mon, 16 Aug 2021 13:48:08 +0200 Subject: [PATCH 096/296] fix inconsistency --- mods/HUD/mcl_title/init.lua | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/mods/HUD/mcl_title/init.lua b/mods/HUD/mcl_title/init.lua index d1dbece4b..ffdc45639 100644 --- a/mods/HUD/mcl_title/init.lua +++ b/mods/HUD/mcl_title/init.lua @@ -36,7 +36,11 @@ local string = string local pairs = pairs local function gametick_to_secondes(gametick) - return gametick / 20 + if gametick then + return gametick / 20 + else + return nil + end end @@ -46,9 +50,9 @@ local player_params = {} minetest.register_on_joinplayer(function(player) local playername = player:get_player_name() player_params[player] = { - stay = gametick_to_secondes(mcl_title.defaults.stay), - --fadeIn = gametick_to_secondes(mcl_title.defaults.fadein), - --fadeOut = gametick_to_secondes(mcl_title.defaults.fadeout), + stay = mcl_title.defaults.stay, + --fadeIn = mcl_title.defaults.fadein, + --fadeOut = mcl_title.defaults.fadeout, } local _, hex_color = get_color("white") huds_idx.title[player] = player:hud_add({ @@ -106,9 +110,9 @@ end) function mcl_title.params_set(player, data) player_params[player] = { - stay = gametick_to_secondes(data.stay) or gametick_to_secondes(mcl_title.defaults.stay), - --fadeIn = gametick_to_secondes(data.fadeIn) or gametick_to_secondes(mcl_title.defaults.fadein), - --fadeOut = gametick_to_secondes(data.fadeOut) or gametick_to_secondes(mcl_title.defaults.fadeout), + stay = data.stay or mcl_title.defaults.stay, + --fadeIn = data.fadeIn or mcl_title.defaults.fadein, + --fadeOut = data.fadeOut or mcl_title.defaults.fadeout, } end @@ -134,7 +138,7 @@ function mcl_title.set(player, type, data) player:hud_change(huds_idx[type][player], "text", data.text) player:hud_change(huds_idx[type][player], "number", hex_color) - hud_hide_timeouts[type][player:get_player_name()] = gametick_to_secondes(data.stay) or mcl_title.params_get(player).stay + hud_hide_timeouts[type][player:get_player_name()] = gametick_to_secondes(data.stay) or gametick_to_secondes(mcl_title.params_get(player).stay) return true end From 40898d3e9dfeb492ecaca2621308c8c125ef5471 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Mon, 16 Aug 2021 14:19:50 +0200 Subject: [PATCH 097/296] WIP bold and italic support --- mods/HUD/mcl_title/init.lua | 38 +++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/mods/HUD/mcl_title/init.lua b/mods/HUD/mcl_title/init.lua index ffdc45639..933158d20 100644 --- a/mods/HUD/mcl_title/init.lua +++ b/mods/HUD/mcl_title/init.lua @@ -43,6 +43,23 @@ local function gametick_to_secondes(gametick) end end +--https://github.com/minetest/minetest/blob/b3b075ea02034306256b486dd45410aa765f035a/doc/lua_api.txt#L8477 + +local function style_to_bits(bold, italic) + if bold then + if italic then + return 3 + else + return 1 + end + else + if italic then + return 2 + else + return 0 + end + end +end --PARAMS SYSTEM local player_params = {} @@ -60,8 +77,7 @@ minetest.register_on_joinplayer(function(player) position = mcl_title.layout.title.position, alignment = mcl_title.layout.title.alignment, text = "", - --bold = data.bold, - --italic = data.italic, + style = 0, size = {x = mcl_title.layout.title.size}, number = hex_color, z_index = 100, @@ -71,8 +87,7 @@ minetest.register_on_joinplayer(function(player) position = mcl_title.layout.subtitle.position, alignment = mcl_title.layout.subtitle.alignment, text = "", - --bold = data.bold, - --italic = data.italic, + style = 0, size = {x = mcl_title.layout.subtitle.size}, number = hex_color, z_index = 100, @@ -82,8 +97,7 @@ minetest.register_on_joinplayer(function(player) position = mcl_title.layout.actionbar.position, offset = {x = 0, y = -210}, alignment = mcl_title.layout.actionbar.alignment, - --bold = data.bold, - --italic = data.italic, + style = 0, text = "", size = {x = mcl_title.layout.actionbar.size}, number = hex_color, @@ -131,13 +145,12 @@ function mcl_title.set(player, type, data) return false end - --TODO: enable this code then Fleckenstein's pr get merged (in about 5-6 years lol) - - --if data.bold == nil then data.bold = false end - --if data.italic == nil then data.italic = false end - player:hud_change(huds_idx[type][player], "text", data.text) player:hud_change(huds_idx[type][player], "number", hex_color) + + --apply bold and italic + player:hud_change(huds_idx[type][player], "style", style_to_bits(data.bold, data.italic)) + hud_hide_timeouts[type][player:get_player_name()] = gametick_to_secondes(data.stay) or gametick_to_secondes(mcl_title.params_get(player).stay) return true end @@ -145,6 +158,7 @@ end function mcl_title.remove(player, type) if player then player:hud_change(huds_idx[type][player], "text", "") + player:hud_change(huds_idx[type][player], "style", 0) --no styling end end @@ -184,7 +198,7 @@ end) minetest.register_chatcommand("title", { func = function(name, param) local player = minetest.get_player_by_name(name) - mcl_title.set(player, "title", {text=param, color="gold"}) + mcl_title.set(player, "title", {text=param, color="gold", bold=true, italic=true}) end, }) From df4b8e64cc153ba70457a199661e1e6e92e30bf9 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Thu, 19 Aug 2021 19:21:33 +0200 Subject: [PATCH 098/296] finish `mcl_title` API + doc --- mods/HUD/mcl_title/API.md | 8 ++++++ mods/HUD/mcl_title/init.lua | 28 +++++++++++--------- mods/HUD/mcl_tmp_message/API.md | 7 ----- mods/HUD/mcl_tmp_message/init.lua | 44 ------------------------------- mods/HUD/mcl_tmp_message/mod.conf | 3 --- 5 files changed, 23 insertions(+), 67 deletions(-) delete mode 100644 mods/HUD/mcl_tmp_message/API.md delete mode 100644 mods/HUD/mcl_tmp_message/init.lua delete mode 100644 mods/HUD/mcl_tmp_message/mod.conf diff --git a/mods/HUD/mcl_title/API.md b/mods/HUD/mcl_title/API.md index 50614be4f..97d75ece8 100644 --- a/mods/HUD/mcl_title/API.md +++ b/mods/HUD/mcl_title/API.md @@ -39,4 +39,12 @@ Allow mods to set `stay` and upcomming `fadeIn`/`fadeOut` params. ```lua mcl_title.params_set(player, {stay = 600}) --elements with no 'data.stay' field will stay during 30s (600/20) +``` + +## mcl_title.params_get(player) + +Get `stay` and upcomming `fadeIn` and `fadeOut` params of a player as a table. + +```lua +mcl_title.params_get(player) ``` \ No newline at end of file diff --git a/mods/HUD/mcl_title/init.lua b/mods/HUD/mcl_title/init.lua index 933158d20..2ea1571c8 100644 --- a/mods/HUD/mcl_title/init.lua +++ b/mods/HUD/mcl_title/init.lua @@ -32,7 +32,7 @@ mcl_title.layout.actionbar = {position = {x = 0.5, y = 1}, alignment = {x = 0, y local get_color = mcl_util.get_color -local string = string +--local string = string local pairs = pairs local function gametick_to_secondes(gametick) @@ -44,7 +44,7 @@ local function gametick_to_secondes(gametick) end --https://github.com/minetest/minetest/blob/b3b075ea02034306256b486dd45410aa765f035a/doc/lua_api.txt#L8477 - +--[[ local function style_to_bits(bold, italic) if bold then if italic then @@ -60,24 +60,25 @@ local function style_to_bits(bold, italic) end end end +]] --PARAMS SYSTEM local player_params = {} minetest.register_on_joinplayer(function(player) - local playername = player:get_player_name() + --local playername = player:get_player_name() player_params[player] = { stay = mcl_title.defaults.stay, --fadeIn = mcl_title.defaults.fadein, --fadeOut = mcl_title.defaults.fadeout, } - local _, hex_color = get_color("white") + local _, hex_color = get_color("white") huds_idx.title[player] = player:hud_add({ hud_elem_type = "text", position = mcl_title.layout.title.position, alignment = mcl_title.layout.title.alignment, text = "", - style = 0, + --style = 0, size = {x = mcl_title.layout.title.size}, number = hex_color, z_index = 100, @@ -87,7 +88,7 @@ minetest.register_on_joinplayer(function(player) position = mcl_title.layout.subtitle.position, alignment = mcl_title.layout.subtitle.alignment, text = "", - style = 0, + --style = 0, size = {x = mcl_title.layout.subtitle.size}, number = hex_color, z_index = 100, @@ -97,7 +98,7 @@ minetest.register_on_joinplayer(function(player) position = mcl_title.layout.actionbar.position, offset = {x = 0, y = -210}, alignment = mcl_title.layout.actionbar.alignment, - style = 0, + --style = 0, text = "", size = {x = mcl_title.layout.actionbar.size}, number = hex_color, @@ -116,7 +117,7 @@ minetest.register_on_leaveplayer(function(player) huds_idx.subtitle[player] = nil huds_idx.actionbar[player] = nil - --remove timers form list + --remove timers from list hud_hide_timeouts.title[playername] = nil hud_hide_timeouts.subtitle[playername] = nil hud_hide_timeouts.actionbar[playername] = nil @@ -149,7 +150,7 @@ function mcl_title.set(player, type, data) player:hud_change(huds_idx[type][player], "number", hex_color) --apply bold and italic - player:hud_change(huds_idx[type][player], "style", style_to_bits(data.bold, data.italic)) + --player:hud_change(huds_idx[type][player], "style", style_to_bits(data.bold, data.italic)) hud_hide_timeouts[type][player:get_player_name()] = gametick_to_secondes(data.stay) or gametick_to_secondes(mcl_title.params_get(player).stay) return true @@ -158,7 +159,7 @@ end function mcl_title.remove(player, type) if player then player:hud_change(huds_idx[type][player], "text", "") - player:hud_change(huds_idx[type][player], "style", 0) --no styling + --player:hud_change(huds_idx[type][player], "style", 0) --no styling end end @@ -193,8 +194,8 @@ minetest.register_globalstep(function(dtime) end) ---TEMP STUFF!! ---TODO: remove then testing/tweaking done +--DEBUG STUFF!! +--[[ minetest.register_chatcommand("title", { func = function(name, param) local player = minetest.get_player_by_name(name) @@ -231,4 +232,5 @@ minetest.register_chatcommand("all", { mcl_title.set(player, "subtitle", {text=param, color="gold"}) mcl_title.set(player, "actionbar", {text=param, color="gold"}) end, -}) \ No newline at end of file +}) +]] \ No newline at end of file diff --git a/mods/HUD/mcl_tmp_message/API.md b/mods/HUD/mcl_tmp_message/API.md deleted file mode 100644 index 0a3fc06a3..000000000 --- a/mods/HUD/mcl_tmp_message/API.md +++ /dev/null @@ -1,7 +0,0 @@ -# mcl_temp_message - -Allow mods to show short messages in the hud of players. - -## mcl_tmp_message.message(player, message) - -Show above the hotbar a hud message to player . \ No newline at end of file diff --git a/mods/HUD/mcl_tmp_message/init.lua b/mods/HUD/mcl_tmp_message/init.lua deleted file mode 100644 index 1456cd592..000000000 --- a/mods/HUD/mcl_tmp_message/init.lua +++ /dev/null @@ -1,44 +0,0 @@ -mcl_tmp_message = {} - -local huds = {} -local hud_hide_timeouts = {} - -function mcl_tmp_message.message(player, message) - local name = player:get_player_name() - player:hud_change(huds[name], "text", message) - hud_hide_timeouts[name] = 3 -end - -minetest.register_on_joinplayer(function(player) - huds[player:get_player_name()] = player:hud_add({ - hud_elem_type = "text", - position = {x=0.5, y=1}, - offset = {x = 0, y = -210}, - alignment = {x=0, y=0}, - number = 0xFFFFFF , - text = "", - z_index = 100, - }) -end) - -minetest.register_on_leaveplayer(function(player) - local name = player:get_player_name() - huds[name] = nil - hud_hide_timeouts[name] = nil -end) - -minetest.register_globalstep(function(dtime) - local new_timeouts = {} - for name, timeout in pairs(hud_hide_timeouts) do - timeout = timeout - dtime - if timeout <= 0 then - local player = minetest.get_player_by_name(name) - if player then - player:hud_change(huds[name], "text", "") - end - else - new_timeouts[name] = timeout - end - end - hud_hide_timeouts = new_timeouts -end) diff --git a/mods/HUD/mcl_tmp_message/mod.conf b/mods/HUD/mcl_tmp_message/mod.conf deleted file mode 100644 index ad453643e..000000000 --- a/mods/HUD/mcl_tmp_message/mod.conf +++ /dev/null @@ -1,3 +0,0 @@ -name = mcl_tmp_message -author = Fleckenstein -description = A simple API to show a temporary message to a player From af8e88f44cad6465e91530b0f87e8588e885cff3 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Tue, 24 Aug 2021 08:25:42 +0200 Subject: [PATCH 099/296] fix error in `mcl_title` documentation --- mods/HUD/mcl_title/API.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/HUD/mcl_title/API.md b/mods/HUD/mcl_title/API.md index 97d75ece8..37f1c279f 100644 --- a/mods/HUD/mcl_title/API.md +++ b/mods/HUD/mcl_title/API.md @@ -21,7 +21,7 @@ mcl_title.set(player, "subtitle", {text="dummy subtitle", color="#612D2D"}) mcl_title.set(player, "subtitle", {text="dummy actionbar", color="red"}) --show a title in the HUD with minecraft color "gold" staying for 3 seconds (override stay setting) -mcl_title.set(player, "title", {text="dummy text", color="gold", stay=3}) +mcl_title.set(player, "title", {text="dummy text", color="gold", stay=60}) ``` ## mcl_title.remove(player, type) From f0af15fcd8006a66ce91ba3efbf77c24a8e8ffca Mon Sep 17 00:00:00 2001 From: NO11 Date: Thu, 26 Aug 2021 10:14:57 +0000 Subject: [PATCH 100/296] Make anvil selection/collision box more MC like --- mods/ITEMS/mcl_anvils/init.lua | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/mods/ITEMS/mcl_anvils/init.lua b/mods/ITEMS/mcl_anvils/init.lua index 51b78da6f..e1685c60e 100644 --- a/mods/ITEMS/mcl_anvils/init.lua +++ b/mods/ITEMS/mcl_anvils/init.lua @@ -284,6 +284,12 @@ local function damage_anvil_by_falling(pos, distance) end end +local anvilbox = { + type = "fixed", + fixed = { + { -8 / 16, -8 / 16, -6 / 16, 8 / 16, 8 / 16, 6 / 16 }, + }, +} local anvildef = { groups = {pickaxey=1, falling_node=1, falling_node_damage=1, crush_after_fall=1, deco_block=1, anvil=1}, tiles = {"mcl_anvils_anvil_top_damaged_0.png^[transformR90", "mcl_anvils_anvil_base.png", "mcl_anvils_anvil_side.png"}, @@ -297,12 +303,14 @@ local anvildef = { node_box = { type = "fixed", fixed = { - { -6/16, -8/16, -6/16, 6/16, -4/16, 6/16 }, - { -5/16, -4/16, -4/16, 5/16, -3/16, 4/16 }, - { -4/16, -3/16, -2/16, 4/16, 2/16, 2/16 }, - { -8/16, 2/16, -5/16, 8/16, 8/16, 5/16 }, + { -6 / 16, -8 / 16, -6 / 16, 6 / 16, -4 / 16, 6 / 16 }, + { -5 / 16, -4 / 16, -4 / 16, 5 / 16, -3 / 16, 4 / 16 }, + { -4 / 16, -3 / 16, -2 / 16, 4 / 16, 2 / 16, 2 / 16 }, + { -8 / 16, 2 / 16, -5 / 16, 8 / 16, 8 / 16, 5 / 16 }, } }, + selection_box = anvilbox, + collision_box = anvilbox, sounds = mcl_sounds.node_sound_metal_defaults(), _mcl_blast_resistance = 1200, _mcl_hardness = 5, From 2b322a451f9ecd71918c9eeb6f40a386d031bfea Mon Sep 17 00:00:00 2001 From: NO11 Date: Thu, 26 Aug 2021 10:17:15 +0000 Subject: [PATCH 101/296] remove space --- mods/ITEMS/mcl_totems/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_totems/init.lua b/mods/ITEMS/mcl_totems/init.lua index 5f9b254a3..2206fcb2a 100644 --- a/mods/ITEMS/mcl_totems/init.lua +++ b/mods/ITEMS/mcl_totems/init.lua @@ -87,7 +87,7 @@ mcl_damage.register_modifier(function(obj, damage, reason) end end) - -- Big totem overlay + -- Big totem overlay if not hud_totem[obj] then hud_totem[obj] = obj:hud_add({ hud_elem_type = "image", From ca086109bf17787e3a7b075ceb07ccb82810a3bb Mon Sep 17 00:00:00 2001 From: NO11 Date: Tue, 31 Aug 2021 21:04:57 +0000 Subject: [PATCH 102/296] support tables for `_repair_material` --- mods/ITEMS/mcl_anvils/init.lua | 44 +++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/mods/ITEMS/mcl_anvils/init.lua b/mods/ITEMS/mcl_anvils/init.lua index e1685c60e..d3b32b844 100644 --- a/mods/ITEMS/mcl_anvils/init.lua +++ b/mods/ITEMS/mcl_anvils/init.lua @@ -53,6 +53,15 @@ local function get_consumed_materials(tool, material) return materials_used end +local function contains(table, value) + for _, i in pairs(table) do + if i == value then + return true + end + end + return false +end + -- Given 2 input stacks, tells you which is the tool and which is the material. -- Returns ("tool", input1, input2) if input1 is tool and input2 is material. -- Returns ("material", input2, input1) if input1 is material and input2 is tool. @@ -60,9 +69,15 @@ end local function distinguish_tool_and_material(input1, input2) local def1 = input1:get_definition() local def2 = input2:get_definition() - if def1.type == "tool" and def1._repair_material then + local r1 = def1._repair_material + local r2 = def2._repair_material + if def1.type == "tool" and r1 and type(r1) == "table" and contains(r1, input2) then return "tool", input1, input2 - elseif def2.type == "tool" and def2._repair_material then + elseif def2.type == "tool" and r2 and type(r2) == "table" and contains(r2, input1) then + return "material", input2, input1 + elseif def1.type == "tool" and r1 then + return "tool", input1, input2 + elseif def2.type == "tool" and r2 then return "material", input2, input1 else return nil @@ -121,11 +136,28 @@ local function update_anvil_slots(meta) local distinguished, tool, material = distinguish_tool_and_material(input1, input2) if distinguished then local tooldef = tool:get_definition() + local repair = tooldef._repair_material local has_correct_material = false - if string.sub(tooldef._repair_material, 1, 6) == "group:" then - has_correct_material = minetest.get_item_group(material:get_name(), string.sub(tooldef._repair_material, 7)) ~= 0 - elseif material:get_name() == tooldef._repair_material then - has_correct_material = true + local material_name = material:get_name() + if type(repair) == "string" then + if string.sub(repair, 1, 6) == "group:" then + has_correct_material = minetest.get_item_group(material_name, string.sub(repair, 7)) ~= 0 + elseif material_name == repair then + has_correct_material = true + end + else + if contains(repair, material_name) then + has_correct_material = true + else + for _, r in pairs(repair) do + if string.sub(r, 1, 6) == "group:" then + if minetest.get_item_group(material_name, string.sub(r, 7)) ~= 0 then + has_correct_material = true + end + + end + end + end end if has_correct_material and tool:get_wear() > 0 then local materials_used = get_consumed_materials(tool, material) From 0da7b3fbda988d11ee79a03ca3c2719d6906e20f Mon Sep 17 00:00:00 2001 From: NO11 Date: Thu, 2 Sep 2021 20:38:01 +0000 Subject: [PATCH 103/296] Make cactus mechanisms more MC like (Fix #1741) --- mods/ITEMS/mcl_core/functions.lua | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/mods/ITEMS/mcl_core/functions.lua b/mods/ITEMS/mcl_core/functions.lua index eceb81c51..af4821c90 100644 --- a/mods/ITEMS/mcl_core/functions.lua +++ b/mods/ITEMS/mcl_core/functions.lua @@ -184,6 +184,7 @@ minetest.register_abm({ end, }) +-- Cactus mechanisms minetest.register_abm({ label = "Cactus growth", nodenames = {"mcl_core:cactus"}, @@ -195,19 +196,31 @@ minetest.register_abm({ end, }) --- Make cactus destroy items minetest.register_abm({ label = "Cactus destroy items", nodenames = {"mcl_core:cactus"}, interval = 1, chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) - for _,object in pairs(minetest.get_objects_inside_radius(pos, 0.9)) do + for _, object in pairs(minetest.get_objects_inside_radius(pos, 0.9)) do local entity = object:get_luaentity() if entity and entity.name == "__builtin:item" then object:remove() end end + local posses = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } } + for _, p in pairs(posses) do + if minetest.registered_nodes[minetest.get_node(vector.new(pos.x + p[1], pos.y, pos.z + p[2])).name].walkable then + local posy = pos.y + while minetest.get_node(vector.new(pos.x, posy, pos.z)).name == "mcl_core:cactus" do + local pos = vector.new(pos.x, posy, pos.z) + minetest.remove_node(pos) + minetest.add_item(vector.offset(pos, math.random(-0.5, 0.5), 0, math.random(-0.5, 0.5)), "mcl_core:cactus") + posy = posy + 1 + end + break + end + end end, }) From bf62eb33fa97cc345fcab2515b2360cd18b80fbf Mon Sep 17 00:00:00 2001 From: NO11 Date: Fri, 3 Sep 2021 14:06:21 +0000 Subject: [PATCH 104/296] Change label of cactus abm --- mods/ITEMS/mcl_core/functions.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_core/functions.lua b/mods/ITEMS/mcl_core/functions.lua index af4821c90..2ef73af72 100644 --- a/mods/ITEMS/mcl_core/functions.lua +++ b/mods/ITEMS/mcl_core/functions.lua @@ -197,7 +197,7 @@ minetest.register_abm({ }) minetest.register_abm({ - label = "Cactus destroy items", + label = "Cactus mechanisms", nodenames = {"mcl_core:cactus"}, interval = 1, chance = 1, From 5fedd914fb110aa8adeed1c3fe633a2c9e25c9e7 Mon Sep 17 00:00:00 2001 From: NO11 Date: Sat, 4 Sep 2021 19:14:08 +0000 Subject: [PATCH 105/296] Fix strange behaviour when filling end portal with bedrock inside (#1749) --- mods/ITEMS/mcl_portals/portal_end.lua | 4 ---- 1 file changed, 4 deletions(-) diff --git a/mods/ITEMS/mcl_portals/portal_end.lua b/mods/ITEMS/mcl_portals/portal_end.lua index 9f0db352a..e4982c39b 100644 --- a/mods/ITEMS/mcl_portals/portal_end.lua +++ b/mods/ITEMS/mcl_portals/portal_end.lua @@ -391,7 +391,3 @@ minetest.override_item("mcl_end:ender_eye", { return itemstack end, }) -minetest.override_item("mcl_core:bedrock", { - after_destruct = destroy_portal, -}) - From f41cea71fd61473090cd04ac8f206f56b9cd3410 Mon Sep 17 00:00:00 2001 From: NO11 Date: Mon, 6 Sep 2021 13:30:08 +0000 Subject: [PATCH 106/296] Make it possible to use shears in the dispenser for mobs (Fix #1233) --- mods/ITEMS/REDSTONE/mcl_dispensers/init.lua | 53 +++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua b/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua index 7c2c07393..62ed2dc71 100644 --- a/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua +++ b/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua @@ -168,6 +168,59 @@ local dispenserdef = { end inv:set_stack("main", stack_id, stack) + + -- Use shears on sheeps + elseif igroups.shears then + for _, obj in pairs(minetest.get_objects_inside_radius(droppos, 1)) do + local entity = obj:get_luaentity() + if entity and not entity.child and not entity.gotten then + local entname = entity.name + local pos = obj:get_pos() + local used, texture = false + if entname == "mobs_mc:sheep" then + minetest.add_item(pos, entity.drops[2].name .. " " .. math.random(1, 3)) + if not entity.color then + entity.color = "unicolor_white" + end + entity.base_texture = { "blank.png", "mobs_mc_sheep.png" } + texture = entity.base_texture + entity.drops = { + { name = mobs_mc.items.mutton_raw, chance = 1, min = 1, max = 2 }, + } + used = true + elseif entname == "mobs_mc:snowman" then + texture = { + "mobs_mc_snowman.png", + "blank.png", "blank.png", + "blank.png", "blank.png", + "blank.png", "blank.png", + } + used = true + elseif entname == "mobs_mc:mooshroom" then + local droppos = vector.offset(pos, 0, 1.4, 0) + if entity.base_texture[1] == "mobs_mc_mooshroom_brown.png" then + minetest.add_item(droppos, mobs_mc.items.mushroom_brown .. " 5") + else + minetest.add_item(droppos, mobs_mc.items.mushroom_red .. " 5") + end + local oldyaw = obj:get_yaw() + obj:remove() + local cow = minetest.add_entity(pos, "mobs_mc:cow") + cow:set_yaw(oldyaw) + obj = cow + entity = cow:get_luaentity() + used = true + end + if used then + obj:set_properties({ textures = texture }) + entity.gotten = true + minetest.sound_play("mcl_tools_shears_cut", { pos = pos }, true) + stack:add_wear(65535 / stackdef._mcl_diggroups.shearsy.uses) + inv:set_stack("main", stack_id, stack) + end + end + end + -- Spawn Egg elseif igroups.spawn_egg then -- Spawn mob From dc8436fdf95afe224437d5fa6e3c883fa322f2a6 Mon Sep 17 00:00:00 2001 From: NO11 Date: Mon, 6 Sep 2021 14:34:25 +0000 Subject: [PATCH 107/296] Destroy objects near cactus faster (make it possible to throw items at a cactus) --- mods/ENTITIES/mcl_item_entity/init.lua | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index ab1ac5752..7869b9d79 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -575,7 +575,7 @@ minetest.register_entity(":__builtin:item", { return true end, - on_step = function(self, dtime) + on_step = function(self, dtime, moveresult) if self._removed then self.object:set_properties({ physical = false @@ -642,6 +642,18 @@ minetest.register_entity(":__builtin:item", { end end + -- Destroy item when it collides with a cactus + if moveresult and moveresult.collides then + for _, collision in pairs(moveresult.collisions) do + local pos = collision.node_pos + if collision.type == "node" and minetest.get_node(pos).name == "mcl_core:cactus" then + self._removed = true + self.object:remove() + return + end + end + end + -- Push item out when stuck inside solid opaque node if def and def.walkable and def.groups and def.groups.opaque == 1 then local shootdir From 1a5339e907c1b5d572e2fe38a8b4451bf9bfff43 Mon Sep 17 00:00:00 2001 From: NO11 Date: Wed, 8 Sep 2021 14:22:53 +0000 Subject: [PATCH 108/296] Only use the shears once in dispenser if there are more mobs in front of the dispenser --- mods/ITEMS/REDSTONE/mcl_dispensers/init.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua b/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua index 62ed2dc71..82d53c806 100644 --- a/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua +++ b/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua @@ -217,6 +217,7 @@ local dispenserdef = { minetest.sound_play("mcl_tools_shears_cut", { pos = pos }, true) stack:add_wear(65535 / stackdef._mcl_diggroups.shearsy.uses) inv:set_stack("main", stack_id, stack) + break end end end From 89ff666a6a7a456daf22a224f42ba7a34919aeec Mon Sep 17 00:00:00 2001 From: NO11 Date: Sun, 12 Sep 2021 12:21:18 +0000 Subject: [PATCH 109/296] Add playersSleepingPercentage server setting (Fix #920) --- mods/ITEMS/mcl_beds/functions.lua | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/mods/ITEMS/mcl_beds/functions.lua b/mods/ITEMS/mcl_beds/functions.lua index e196f69ad..fd8a6d7cd 100644 --- a/mods/ITEMS/mcl_beds/functions.lua +++ b/mods/ITEMS/mcl_beds/functions.lua @@ -9,6 +9,7 @@ local weather_mod = minetest.get_modpath("mcl_weather") local explosions_mod = minetest.get_modpath("mcl_explosions") local spawn_mod = minetest.get_modpath("mcl_spawn") local worlds_mod = minetest.get_modpath("mcl_worlds") +local players_in_bed_setting = tonumber(minetest.settings:get("mcl_playersSleepingPercentage")) -- Helper functions @@ -34,19 +35,10 @@ local function is_night_skip_enabled() end local function check_in_beds(players) - local in_bed = mcl_beds.player if not players then players = minetest.get_connected_players() end - - for n, player in pairs(players) do - local name = player:get_player_name() - if not in_bed[name] then - return false - end - end - - return #players > 0 + return players_in_bed_setting <= (#mcl_beds.player * 100) / #players end -- These monsters do not prevent sleep @@ -198,8 +190,8 @@ end local function update_formspecs(finished, ges) local ges = ges or #minetest.get_connected_players() local form_n = "size[12,5;true]" - local all_in_bed = ges == player_in_bed - local night_skip = is_night_skip_enabled() + local all_in_bed = players_in_bed_setting <= (player_in_bed * 100) / ges + local night_skip = is_night_skip_enabled() and players_in_bed_setting <= 100 local button_leave = "button_exit[4,3;4,0.75;leave;"..F(S("Leave bed")).."]" local button_abort = "button_exit[4,3;4,0.75;leave;"..F(S("Abort sleep")).."]" local bg_presleep = "bgcolor[#00000080;true]" @@ -212,7 +204,7 @@ local function update_formspecs(finished, ges) return elseif not is_sp then local text = S("Players in bed: @1/@2", player_in_bed, ges) - if not night_skip then + if not night_skip or players_in_bed_setting > 100 then text = text .. "\n" .. S("Note: Night skip is disabled.") form_n = form_n .. bg_presleep form_n = form_n .. button_leave @@ -221,7 +213,13 @@ local function update_formspecs(finished, ges) form_n = form_n .. bg_sleep form_n = form_n .. button_abort else - text = text .. "\n" .. S("You will fall asleep when all players are in bed.") + local comment = "You will fall asleep when " + if players_in_bed_setting == 100 then + comment = comment .. "all players are in bed." + else + comment = comment .. players_in_bed_setting .. "% of all players are in bed." + end + text = text .. "\n" .. S(comment) form_n = form_n .. bg_presleep form_n = form_n .. button_leave end From 0bc9ab9233811b508e1aa29c4b1ea421b47fead3 Mon Sep 17 00:00:00 2001 From: NO11 Date: Sun, 12 Sep 2021 12:23:28 +0000 Subject: [PATCH 110/296] Add playersSleepingPercentage setting to settingtypes.txt --- settingtypes.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/settingtypes.txt b/settingtypes.txt index f605019ad..89e11833f 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -33,6 +33,11 @@ mcl_tnt_griefing (TNT destroys blocks) bool true # This setting is only read at startup. enable_bed_respawn (Respawn at bed) bool true +# How many players have to sleep to skip the night, in percent. +# Setting to 0 will mean 1 player is always enough to skip the night. Setting above 100 will prevent skipping the night. +# 100 by default. +mcl_playersSleepingPercentage (Players Sleeping Percentage) int 100 + # If enabled, the night can be skipped if all players are in bed. # This setting is only read at startup. enable_bed_night_skip (Skip night when sleeping) bool true From cd84c472dcb67b32b74397f87c00503b7414fc77 Mon Sep 17 00:00:00 2001 From: NO11 Date: Sun, 12 Sep 2021 12:49:39 +0000 Subject: [PATCH 111/296] Add translation support. --- mods/ITEMS/mcl_beds/functions.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mods/ITEMS/mcl_beds/functions.lua b/mods/ITEMS/mcl_beds/functions.lua index fd8a6d7cd..01ccec851 100644 --- a/mods/ITEMS/mcl_beds/functions.lua +++ b/mods/ITEMS/mcl_beds/functions.lua @@ -215,11 +215,11 @@ local function update_formspecs(finished, ges) else local comment = "You will fall asleep when " if players_in_bed_setting == 100 then - comment = comment .. "all players are in bed." + comment = S(comment .. "all players are in bed.") else - comment = comment .. players_in_bed_setting .. "% of all players are in bed." + comment = S(comment .. "@1% of all players are in bed.", players_in_bed_setting) end - text = text .. "\n" .. S(comment) + text = text .. "\n" .. comment form_n = form_n .. bg_presleep form_n = form_n .. button_leave end From 9f9799d96e699a0b64bce5fee061deeb040b3aa4 Mon Sep 17 00:00:00 2001 From: NO11 Date: Sun, 12 Sep 2021 12:50:54 +0000 Subject: [PATCH 112/296] Update template.txt in mcl_beds --- mods/ITEMS/mcl_beds/locale/template.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/mods/ITEMS/mcl_beds/locale/template.txt b/mods/ITEMS/mcl_beds/locale/template.txt index 8301dfa33..5525bd91b 100644 --- a/mods/ITEMS/mcl_beds/locale/template.txt +++ b/mods/ITEMS/mcl_beds/locale/template.txt @@ -37,5 +37,6 @@ Players in bed: @1/@2= Note: Night skip is disabled.= You're sleeping.= You will fall asleep when all players are in bed.= +You will fall asleep when @1% of all players are in bed.= You're in bed.= Allows you to sleep= From 410b7c7844b674a062e1726a058e992698b9b34e Mon Sep 17 00:00:00 2001 From: NO11 Date: Sun, 12 Sep 2021 12:52:26 +0000 Subject: [PATCH 113/296] Update german translation for mcl_beds --- mods/ITEMS/mcl_beds/locale/mcl_beds.de.tr | 1 + 1 file changed, 1 insertion(+) diff --git a/mods/ITEMS/mcl_beds/locale/mcl_beds.de.tr b/mods/ITEMS/mcl_beds/locale/mcl_beds.de.tr index 16592115e..eb6967941 100644 --- a/mods/ITEMS/mcl_beds/locale/mcl_beds.de.tr +++ b/mods/ITEMS/mcl_beds/locale/mcl_beds.de.tr @@ -37,5 +37,6 @@ Players in bed: @1/@2=Spieler im Bett: @1/@2 Note: Night skip is disabled.=Anmerkung: Überspringen der Nacht deaktiviert. You're sleeping.=Sie schlafen. You will fall asleep when all players are in bed.=Sie werden einschlafen, wenn alle Spieler im Bett sind. +You will fall asleep when @1% of all players are in bed.=Sie werden einschlafen, wenn @1% der Spieler im Bett sind. You're in bed.=Sie sind im Bett. Allows you to sleep=Zum Einschafen From 1c192f4fbbee2089ff72912cf369e8591fd4e481 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 8 Jul 2021 15:34:50 +0200 Subject: [PATCH 114/296] Do not send useless HUDCHANGE packets Several mods set or unset the visibility of a HUD bar way too often (e.g. in a globalstep handler), causing the server to send a lot of superfluous HUDCHANGE packets to each client. Returning from hb.hide_hudbar() early if HUD bar visibility would not change prevents sending these packets. --- mods/HUD/hudbars/init.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mods/HUD/hudbars/init.lua b/mods/HUD/hudbars/init.lua index 08f1914ca..505ff403b 100644 --- a/mods/HUD/hudbars/init.lua +++ b/mods/HUD/hudbars/init.lua @@ -425,6 +425,7 @@ function hb.hide_hudbar(player, identifier) local name = player:get_player_name() local hudtable = hb.get_hudtable(identifier) if hudtable == nil then return false end + if hudtable.hudstate[name].hidden == true then return true end if hb.settings.bar_type == "progress_bar" then if hudtable.hudids[name].icon then player:hud_change(hudtable.hudids[name].icon, "scale", {x=0,y=0}) @@ -443,6 +444,7 @@ function hb.unhide_hudbar(player, identifier) local name = player:get_player_name() local hudtable = hb.get_hudtable(identifier) if hudtable == nil then return false end + if hudtable.hudstate[name].hidden == false then return true end local value = hudtable.hudstate[name].value local max = hudtable.hudstate[name].max if hb.settings.bar_type == "progress_bar" then From 95c4d6472bc57c056c5116be88d8f99550ec04b6 Mon Sep 17 00:00:00 2001 From: Nils Dagsson Moskopp Date: Sun, 4 Jul 2021 03:25:05 +0200 Subject: [PATCH 115/296] Send FOV packets only when necessary Before this change, about 10 to 30 FOV packets were sent from the server to each connected client each second. This patch only sends FOV packets when the FOV actually needs to be changed, i.e. when the player starts or stops sprinting. --- mods/PLAYER/mcl_sprint/init.lua | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/mods/PLAYER/mcl_sprint/init.lua b/mods/PLAYER/mcl_sprint/init.lua index 73a518c42..4c0d609c9 100644 --- a/mods/PLAYER/mcl_sprint/init.lua +++ b/mods/PLAYER/mcl_sprint/init.lua @@ -69,18 +69,19 @@ local function setSprinting(playerName, sprinting) --Sets the state of a player local controls = player:get_player_control() if players[playerName] then players[playerName].sprinting = sprinting + local fov_old = players[playerName].fov + local fov_new = fov_old + local fade_time = .15 if sprinting == true or controls.RMB and string.find(player:get_wielded_item():get_name(), "mcl_bows:bow") and player:get_wielded_item():get_name() ~= "mcl_bows:bow" then if sprinting == true then - players[playerName].fov = math.min(players[playerName].fov + 0.05, 1.2) - players[playerName].fade_time = .15 + fov_new = math.min(players[playerName].fov + 0.05, 1.2) else - players[playerName].fov = .7 + fov_new = .7 players[playerName].fade_time = .3 end - player:set_fov(players[playerName].fov, true, players[playerName].fade_time) if sprinting == true then playerphysics.add_physics_factor(player, "speed", "mcl_sprint:sprint", mcl_sprint.SPEED) end @@ -88,12 +89,15 @@ local function setSprinting(playerName, sprinting) --Sets the state of a player and player:get_wielded_item():get_name() ~= "mcl_bows:bow_0" and player:get_wielded_item():get_name() ~= "mcl_bows:bow_1" and player:get_wielded_item():get_name() ~= "mcl_bows:bow_2" then - players[playerName].fov = math.max(players[playerName].fov - 0.05, 1.0) - player:set_fov(players[playerName].fov, true, 0.15) + fov_new = math.max(players[playerName].fov - 0.05, 1.0) if sprinting == false then playerphysics.remove_physics_factor(player, "speed", "mcl_sprint:sprint") end end + if fov_new ~= fov_old then + players[playerName].fov = fov_new + player:set_fov(fov_new, true, fade_time) + end return true end return false From 693a5317efd84eeb1141414e0b48930a09bdceec Mon Sep 17 00:00:00 2001 From: sfan5 Date: Wed, 28 Jul 2021 20:44:48 +0200 Subject: [PATCH 116/296] Fix non-serializable item entity unload crash MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some items, like shulkers or books, can have so much metadata that the corresponding item entity can not be serialized by the Minetest engine. Without this patch, dropping such an item and then moving away crashes Minetest, as it can not serialize the entity with serializeString16() when unloading a map block. The patch resets the overlong metadata of non-serializable item entities. This avoids a crash and makes it possible to retrieve a “sanitized” item without metadata when the mapblock containing the item entity is reloaded. Originally sfan5 guessed the maximum possible item entity serialization size that would not lead to a crash as 65530 bytes, but anon5 calculated it to be actually 65487 bytes. This has been experimentally verified by erlehmann. --- mods/ENTITIES/mcl_item_entity/init.lua | 28 +++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index 7869b9d79..7a2758ed0 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -480,7 +480,7 @@ minetest.register_entity(":__builtin:item", { end, get_staticdata = function(self) - return minetest.serialize({ + local data = minetest.serialize({ itemstring = self.itemstring, always_collect = self.always_collect, age = self.age, @@ -488,6 +488,32 @@ minetest.register_entity(":__builtin:item", { _flowing = self._flowing, _removed = self._removed, }) + -- sfan5 guessed that the biggest serializable item + -- entity would have a size of 65530 bytes. This has + -- been experimentally verified to be still too large. + -- + -- anon5 has calculated that the biggest serializable + -- item entity has a size of exactly 65487 bytes: + -- + -- 1. serializeString16 can handle max. 65535 bytes. + -- 2. The following engine metadata is always saved: + -- • 1 byte (version) + -- • 2 byte (length prefix) + -- • 14 byte “__builtin:item” + -- • 4 byte (length prefix) + -- • 2 byte (health) + -- • 3 × 4 byte = 12 byte (position) + -- • 4 byte (yaw) + -- • 1 byte (version 2) + -- • 2 × 4 byte = 8 byte (pitch and roll) + -- 3. This leaves 65487 bytes for the serialization. + if #data > 65487 then -- would crash the engine + local stack = ItemStack(self.itemstring) + stack:get_meta():from_table(nil) + self.itemstring = stack:to_string() + return self:get_staticdata() + end + return data end, on_activate = function(self, staticdata, dtime_s) From 256de2bc365466735900dde62c749035ee700843 Mon Sep 17 00:00:00 2001 From: Nils Dagsson Moskopp Date: Thu, 29 Jul 2021 15:46:50 +0200 Subject: [PATCH 117/296] Log warning for non-serializable item entity fix --- mods/ENTITIES/mcl_item_entity/init.lua | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index 7a2758ed0..cfd141f04 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -511,6 +511,13 @@ minetest.register_entity(":__builtin:item", { local stack = ItemStack(self.itemstring) stack:get_meta():from_table(nil) self.itemstring = stack:to_string() + minetest.log( + "warning", + "Overlong item entity metadata removed: “" .. + self.itemstring .. + "” had serialized length of " .. + #data + ) return self:get_staticdata() end return data From 27e4bd6d09b8a1ea36e9b0120b5aa7b90d16cc5a Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sat, 18 Sep 2021 22:28:20 +0200 Subject: [PATCH 118/296] Fix burning entity packet spam - Use upright_sprite for 3rd person flame display, which is both closer to minecraft and allows for client side texture animation - Take care of flame HUD in the MineClone2Client --- mods/ENTITIES/mcl_burning/api.lua | 18 +++-------- mods/ENTITIES/mcl_burning/init.lua | 51 +++++++++++++----------------- 2 files changed, 27 insertions(+), 42 deletions(-) diff --git a/mods/ENTITIES/mcl_burning/api.lua b/mods/ENTITIES/mcl_burning/api.lua index 4cb19cca1..969985205 100644 --- a/mods/ENTITIES/mcl_burning/api.lua +++ b/mods/ENTITIES/mcl_burning/api.lua @@ -67,14 +67,9 @@ function mcl_burning.set_on_fire(obj, burn_time) end if not storage.burn_time or burn_time >= storage.burn_time then - if obj:is_player() and not storage.fire_hud_id then - storage.fire_hud_id = obj:hud_add({ - hud_elem_type = "image", - position = {x = 0.5, y = 0.5}, - scale = {x = -100, y = -100}, - text = "mcl_burning_entity_flame_animated.png^[opacity:180^[verticalframe:" .. mcl_burning.animation_frames .. ":" .. 1, - z_index = 1000, - }) + if obj:is_player() then + mcl_burning.channels[obj]:send_all(tostring(mcl_burning.animation_frames)) + mcl_burning.channels[obj]:send_all("start") end storage.burn_time = burn_time storage.fire_damage_timer = 0 @@ -95,7 +90,6 @@ function mcl_burning.set_on_fire(obj, burn_time) fire_entity:set_properties({visual_size = size}) fire_entity:set_attach(obj, "", offset, {x = 0, y = 0, z = 0}) local fire_luaentity = fire_entity:get_luaentity() - fire_luaentity:update_frame(obj, storage) for _, other in pairs(minetest.get_objects_inside_radius(fire_entity:get_pos(), 0)) do local other_luaentity = other:get_luaentity() @@ -111,9 +105,7 @@ function mcl_burning.extinguish(obj) if mcl_burning.is_burning(obj) then local storage = mcl_burning.get_storage(obj) if obj:is_player() then - if storage.fire_hud_id then - obj:hud_remove(storage.fire_hud_id) - end + mcl_burning.channels[obj]:send_all("stop") mcl_burning.storage[obj] = {} else storage.burn_time = nil @@ -143,4 +135,4 @@ function mcl_burning.tick(obj, dtime, storage) end end end -end \ No newline at end of file +end diff --git a/mods/ENTITIES/mcl_burning/init.lua b/mods/ENTITIES/mcl_burning/init.lua index 34b7ca2d4..313e75dca 100644 --- a/mods/ENTITIES/mcl_burning/init.lua +++ b/mods/ENTITIES/mcl_burning/init.lua @@ -7,6 +7,7 @@ local get_item_group = minetest.get_item_group mcl_burning = { storage = {}, + channels = {}, animation_frames = tonumber(minetest.settings:get("fire_animation_frames")) or 8 } @@ -54,12 +55,11 @@ minetest.register_on_joinplayer(function(player) end mcl_burning.storage[player] = storage + mcl_burning.channels[player] = minetest.mod_channel_join("mcl_burning:" .. player:get_player_name()) end) minetest.register_on_leaveplayer(function(player) - local storage = mcl_burning.storage[player] - storage.fire_hud_id = nil - player:get_meta():set_string("mcl_burning:data", minetest.serialize(storage)) + player:get_meta():set_string("mcl_burning:data", minetest.serialize(mcl_burning.storage[player])) mcl_burning.storage[player] = nil end) @@ -68,27 +68,28 @@ minetest.register_entity("mcl_burning:fire", { initial_properties = { physical = false, collisionbox = {0, 0, 0, 0, 0, 0}, - visual = "cube", + visual = "upright_sprite", + textures = { + name = "mcl_burning_entity_flame_animated.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 1.0, + }, + }, + spritediv = {x = 1, y = mcl_burning.animation_frames}, pointable = false, glow = -1, backface_culling = false, }, animation_frame = 0, animation_timer = 0, - on_step = function(self, dtime) - local parent, storage = self:sanity_check() - - if parent then - self.animation_timer = self.animation_timer + dtime - if self.animation_timer >= 0.1 then - self.animation_timer = 0 - self.animation_frame = self.animation_frame + 1 - if self.animation_frame > mcl_burning.animation_frames - 1 then - self.animation_frame = 0 - end - self:update_frame(parent, storage) - end - else + on_activate = function(self) + self.object:set_sprite({x = 0, y = 0}, mcl_burning.animation_frames, 1.0 / mcl_burning.animation_frames) + end, + on_step = function(self) + if not self:sanity_check() then self.object:remove() end end, @@ -96,23 +97,15 @@ minetest.register_entity("mcl_burning:fire", { local parent = self.object:get_attach() if not parent then - return + return false end local storage = mcl_burning.get_storage(parent) if not storage or not storage.burn_time then - return + return false end - return parent, storage - end, - update_frame = function(self, parent, storage) - local frame_overlay = "^[opacity:180^[verticalframe:" .. mcl_burning.animation_frames .. ":" .. self.animation_frame - local fire_texture = "mcl_burning_entity_flame_animated.png" .. frame_overlay - self.object:set_properties({textures = {"blank.png", "blank.png", fire_texture, fire_texture, fire_texture, fire_texture}}) - if parent:is_player() then - parent:hud_change(storage.fire_hud_id, "text", "mcl_burning_hud_flame_animated.png" .. frame_overlay) - end + return true end, }) From 0e15accada59737c415a0920e93b65a39e5aa2ae Mon Sep 17 00:00:00 2001 From: NO11 Date: Sun, 19 Sep 2021 11:15:19 +0000 Subject: [PATCH 119/296] Enable fly in creative mode --- mods/MISC/mcl_privs/init.lua | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/mods/MISC/mcl_privs/init.lua b/mods/MISC/mcl_privs/init.lua index 63694ab11..5a23c00fb 100644 --- a/mods/MISC/mcl_privs/init.lua +++ b/mods/MISC/mcl_privs/init.lua @@ -3,3 +3,14 @@ local S = minetest.get_translator(minetest.get_current_modname()) minetest.register_privilege("maphack", { description = S("Can place and use advanced blocks like mob spawners, command blocks and barriers."), }) + +minetest.register_on_joinplayer(function(player) + local name = user:get_player_name() + local fly = false + if minetest.is_creative_enabled(name) then + fly = true + end + minetest.set_player_privs(name, { + fly = fly, + }) +end) From 18a83fa5d725c51563a2f35bf818b7c9b9041680 Mon Sep 17 00:00:00 2001 From: NO11 Date: Sun, 19 Sep 2021 11:18:09 +0000 Subject: [PATCH 120/296] Fix typo --- mods/MISC/mcl_privs/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/MISC/mcl_privs/init.lua b/mods/MISC/mcl_privs/init.lua index 5a23c00fb..091ddb65e 100644 --- a/mods/MISC/mcl_privs/init.lua +++ b/mods/MISC/mcl_privs/init.lua @@ -5,7 +5,7 @@ minetest.register_privilege("maphack", { }) minetest.register_on_joinplayer(function(player) - local name = user:get_player_name() + local name = player:get_player_name() local fly = false if minetest.is_creative_enabled(name) then fly = true From fed43586f202cd71fe374560f90b42bef18361ec Mon Sep 17 00:00:00 2001 From: NO11 Date: Sun, 19 Sep 2021 11:28:07 +0000 Subject: [PATCH 121/296] fix typo --- mods/MISC/mcl_privs/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/MISC/mcl_privs/init.lua b/mods/MISC/mcl_privs/init.lua index 091ddb65e..1d1465676 100644 --- a/mods/MISC/mcl_privs/init.lua +++ b/mods/MISC/mcl_privs/init.lua @@ -6,7 +6,7 @@ minetest.register_privilege("maphack", { minetest.register_on_joinplayer(function(player) local name = player:get_player_name() - local fly = false + local fly = nil if minetest.is_creative_enabled(name) then fly = true end From f10d579d9c45bdddb7f2ae1935d74821b9c6a8b3 Mon Sep 17 00:00:00 2001 From: NO11 Date: Sun, 19 Sep 2021 12:07:21 +0000 Subject: [PATCH 122/296] Only change fly priv on join if it wasn't revoked or granted --- mods/MISC/mcl_privs/init.lua | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/mods/MISC/mcl_privs/init.lua b/mods/MISC/mcl_privs/init.lua index 1d1465676..c63f7c5c5 100644 --- a/mods/MISC/mcl_privs/init.lua +++ b/mods/MISC/mcl_privs/init.lua @@ -6,6 +6,10 @@ minetest.register_privilege("maphack", { minetest.register_on_joinplayer(function(player) local name = player:get_player_name() + + local meta = player:get_meta() + if meta:get_int("fly_changed") == 1 then return end + local fly = nil if minetest.is_creative_enabled(name) then fly = true @@ -14,3 +18,13 @@ minetest.register_on_joinplayer(function(player) fly = fly, }) end) + +for _, action in pairs({ "grant", "revoke" }) do + minetest["register_on_priv_" .. action](function(name, _, priv) + if priv == "fly" then + local player = minetest.get_player_by_name(name) + local meta = player:get_meta() + meta:set_int("fly_changed", 1) + end + end) +end \ No newline at end of file From c6003398b5f4149b3eaffe585fde40e8374c721b Mon Sep 17 00:00:00 2001 From: NO11 Date: Sun, 19 Sep 2021 13:14:36 +0000 Subject: [PATCH 123/296] Remove chain armor recipes, because villagers spawn now --- mods/MISC/mcl_temp_helper_recipes/init.lua | 34 ---------------------- 1 file changed, 34 deletions(-) diff --git a/mods/MISC/mcl_temp_helper_recipes/init.lua b/mods/MISC/mcl_temp_helper_recipes/init.lua index 420cd6c2e..b7607946d 100644 --- a/mods/MISC/mcl_temp_helper_recipes/init.lua +++ b/mods/MISC/mcl_temp_helper_recipes/init.lua @@ -35,40 +35,6 @@ minetest.register_craft({ }, }) -minetest.register_craft({ - output = "mcl_armor:helmet_chain", - recipe = { - { "xpanes:bar_flat", "mcl_core:iron_ingot", "xpanes:bar_flat" }, - { "xpanes:bar_flat", "", "xpanes:bar_flat" }, - } -}) - -minetest.register_craft({ - output = "mcl_armor:leggings_chain", - recipe = { - { "xpanes:bar_flat", "mcl_core:iron_ingot", "xpanes:bar_flat" }, - { "xpanes:bar_flat", "", "xpanes:bar_flat" }, - { "xpanes:bar_flat", "", "xpanes:bar_flat" }, - } -}) - -minetest.register_craft({ - output = "mcl_armor:boots_chain", - recipe = { - { "xpanes:bar_flat", "", "xpanes:bar_flat" }, - { "xpanes:bar_flat", "", "xpanes:bar_flat" }, - } -}) - -minetest.register_craft({ - output = "mcl_armor:chestplate_chain", - recipe = { - { "xpanes:bar_flat", "", "xpanes:bar_flat" }, - { "xpanes:bar_flat", "mcl_core:iron_ingot", "xpanes:bar_flat" }, - { "xpanes:bar_flat", "xpanes:bar_flat", "xpanes:bar_flat" }, - } -}) - -- Make red sand, red sandstone and more craftable in v6 -- NOTE: When you change these, also update mcl_craftguide for the "v6" icon in -- the craft guide! From 3e54acce9db66ff7d330cbcffe20c8ae8ffcd91a Mon Sep 17 00:00:00 2001 From: AFCMS Date: Mon, 20 Sep 2021 09:47:24 +0200 Subject: [PATCH 124/296] fix emerald help text translation --- mods/ITEMS/mcl_core/locale/mcl_core.de.tr | 2 +- mods/ITEMS/mcl_core/locale/mcl_core.es.tr | 2 +- mods/ITEMS/mcl_core/locale/mcl_core.fr.tr | 2 +- mods/ITEMS/mcl_core/locale/mcl_core.pl.tr | 2 +- mods/ITEMS/mcl_core/locale/mcl_core.ru.tr | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.de.tr b/mods/ITEMS/mcl_core/locale/mcl_core.de.tr index 0a1cbad37..b064cebbe 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.de.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.de.tr @@ -95,7 +95,7 @@ Dirt acts as a soil for a few plants. When in light, this block may grow a grass Emerald=Smaragd Emerald Ore=Smaragderz Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=Smaragderz ist das Erz von Smaragden. Es ist sehr selten und kann nur einzeln gefunden werden, nicht in Ansammlungen. -Emeralds are not very useful on their own, but they can exchanged for gold ingots by crafting.=Smaragde sind nicht besonders nützlich, aber man kann sie in der Fertigung durch Goldbarren eintauschen. +Emeralds are used in villager trades as currency.= Flint=Feuerstein Flint is a raw material.=Feuerstein ist ein Rohstoff. Flowing Lava=Fließende Lava diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.es.tr b/mods/ITEMS/mcl_core/locale/mcl_core.es.tr index 1e1029c0f..1937babd3 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.es.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.es.tr @@ -95,7 +95,7 @@ Dirt acts as a soil for a few plants. When in light, this block may grow a grass Emerald=Esmeralda Emerald Ore=Mena de esmeralda Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=El mineral esmeralda es el mineral de las esmeraldas. Es muy raro y se puede encontrar solo, no en grupos. -Emeralds are not very useful on their own, but they can exchanged for gold ingots by crafting.=Las esmeraldas no son muy útiles por sí mismas, pero pueden cambiarse por lingotes de oro haciendo artesanías. +Emeralds are used in villager trades as currency.= Flint=Pedernal Flint is a raw material.=El pedernal es una materia prima. Flowing Lava=Lava que fluye diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr b/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr index 725025e48..64aadd6db 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr @@ -95,7 +95,7 @@ Dirt acts as a soil for a few plants. When in light, this block may grow a grass Emerald=Emeraude Emerald Ore=Minerai d'Emeraude Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=Le minerai d'émeraude produit des émeraudes. Il est très rare et peut être trouvé seul, pas en filons. -Emeralds are not very useful on their own, but they can exchanged for gold ingots by crafting.=Les émeraudes ne sont pas très utiles seules, mais elles peuvent être échangées contre des lingots d'or. +Emeralds are used in villager trades as currency.=Les émeraudes sont utilisées pour faire des échanges avec les villageois. Flint=Silex Flint is a raw material.=Le silex est une matière première. Flowing Lava=Lave qui coule diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.pl.tr b/mods/ITEMS/mcl_core/locale/mcl_core.pl.tr index 832a47830..68dfbd3d0 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.pl.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.pl.tr @@ -95,7 +95,7 @@ Dirt acts as a soil for a few plants. When in light, this block may grow a grass Emerald=Szmaragd Emerald Ore=Ruda szmaragdu Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=Ruda szmaragdu jest bardzo rzadka i występuje samotnie, nie w grupach. -Emeralds are not very useful on their own, but they can exchanged for gold ingots by crafting.=Szmaragdy nie są zbyt użyteczne same w sobie, ale można z nich wytworzyć sztabki złota. +Emeralds are used in villager trades as currency.= Flint=Krzemień Flint is a raw material.=Krzemień jest surowym materiałem. Flowing Lava=Płynąca lawa diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr b/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr index f93db7c2c..2d5b5462c 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr @@ -95,7 +95,7 @@ Dirt acts as a soil for a few plants. When in light, this block may grow a grass Emerald=Изумруд Emerald Ore=Изумрудная руда Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=Изумрудная руда встречается очень редко и всегда по одному блоку. -Emeralds are not very useful on their own, but they can exchanged for gold ingots by crafting.=Изумруды не очень полезны сами по себе, но их можно обменять на золотые слитки. +Emeralds are used in villager trades as currency.= Flint=Кремень Flint is a raw material.=Кремень это необработанный материал. Flowing Lava=Текущая лава From e0c7e938dea19a3df5efd9fa73b61c85d17640ed Mon Sep 17 00:00:00 2001 From: AFCMS Date: Mon, 20 Sep 2021 07:55:51 +0000 Subject: [PATCH 125/296] =?UTF-8?q?Mise=20=C3=A0=20jour=20de=20'mods/ITEMS?= =?UTF-8?q?/mcl=5Fcore/locale/mcl=5Fcore.fr.tr'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mods/ITEMS/mcl_core/locale/mcl_core.fr.tr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr b/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr index 4d6a3ed43..64aadd6db 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr @@ -95,7 +95,7 @@ Dirt acts as a soil for a few plants. When in light, this block may grow a grass Emerald=Emeraude Emerald Ore=Minerai d'Emeraude Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=Le minerai d'émeraude produit des émeraudes. Il est très rare et peut être trouvé seul, pas en filons. -Emeralds are used in villager trades as currency.=Les émeraudes ne sont pas très utiles seules, mais elles peuvent être échangées contre des lingots d'or. +Emeralds are used in villager trades as currency.=Les émeraudes sont utilisées pour faire des échanges avec les villageois. Flint=Silex Flint is a raw material.=Le silex est une matière première. Flowing Lava=Lave qui coule From e8134345d4476be032117723b5397926ff6d5199 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Mon, 20 Sep 2021 07:56:25 +0000 Subject: [PATCH 126/296] =?UTF-8?q?Mise=20=C3=A0=20jour=20de=20'mods/ITEMS?= =?UTF-8?q?/mcl=5Fcore/locale/mcl=5Fcore.de.tr'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mods/ITEMS/mcl_core/locale/mcl_core.de.tr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.de.tr b/mods/ITEMS/mcl_core/locale/mcl_core.de.tr index 8b75dfd40..b064cebbe 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.de.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.de.tr @@ -95,7 +95,7 @@ Dirt acts as a soil for a few plants. When in light, this block may grow a grass Emerald=Smaragd Emerald Ore=Smaragderz Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=Smaragderz ist das Erz von Smaragden. Es ist sehr selten und kann nur einzeln gefunden werden, nicht in Ansammlungen. -Emeralds are used in villager trades as currency.=Smaragde sind nicht besonders nützlich, aber man kann sie in der Fertigung durch Goldbarren eintauschen. +Emeralds are used in villager trades as currency.= Flint=Feuerstein Flint is a raw material.=Feuerstein ist ein Rohstoff. Flowing Lava=Fließende Lava From b2af00db2201f1ddc20c0b9650c983402aaa10b7 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Mon, 20 Sep 2021 07:57:04 +0000 Subject: [PATCH 127/296] =?UTF-8?q?Mise=20=C3=A0=20jour=20de=20'mods/ITEMS?= =?UTF-8?q?/mcl=5Fcore/locale/mcl=5Fcore.es.tr'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mods/ITEMS/mcl_core/locale/mcl_core.es.tr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.es.tr b/mods/ITEMS/mcl_core/locale/mcl_core.es.tr index d77f45dc2..1937babd3 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.es.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.es.tr @@ -95,7 +95,7 @@ Dirt acts as a soil for a few plants. When in light, this block may grow a grass Emerald=Esmeralda Emerald Ore=Mena de esmeralda Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=El mineral esmeralda es el mineral de las esmeraldas. Es muy raro y se puede encontrar solo, no en grupos. -Emeralds are used in villager trades as currency.=Las esmeraldas no son muy útiles por sí mismas, pero pueden cambiarse por lingotes de oro haciendo artesanías. +Emeralds are used in villager trades as currency.= Flint=Pedernal Flint is a raw material.=El pedernal es una materia prima. Flowing Lava=Lava que fluye From e36a8c5acf48d473db9ae5807b176b94a779e15c Mon Sep 17 00:00:00 2001 From: AFCMS Date: Mon, 20 Sep 2021 07:58:25 +0000 Subject: [PATCH 128/296] =?UTF-8?q?Mise=20=C3=A0=20jour=20de=20'mods/ITEMS?= =?UTF-8?q?/mcl=5Fcore/locale/mcl=5Fcore.pl.tr'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mods/ITEMS/mcl_core/locale/mcl_core.pl.tr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.pl.tr b/mods/ITEMS/mcl_core/locale/mcl_core.pl.tr index f8dbbde6b..68dfbd3d0 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.pl.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.pl.tr @@ -95,7 +95,7 @@ Dirt acts as a soil for a few plants. When in light, this block may grow a grass Emerald=Szmaragd Emerald Ore=Ruda szmaragdu Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=Ruda szmaragdu jest bardzo rzadka i występuje samotnie, nie w grupach. -Emeralds are used in villager trades as currency.=Szmaragdy nie są zbyt użyteczne same w sobie, ale można z nich wytworzyć sztabki złota. +Emeralds are used in villager trades as currency.= Flint=Krzemień Flint is a raw material.=Krzemień jest surowym materiałem. Flowing Lava=Płynąca lawa From b0cf07a020ba353545465b8909fd88ad8725c4cd Mon Sep 17 00:00:00 2001 From: AFCMS Date: Mon, 20 Sep 2021 07:59:00 +0000 Subject: [PATCH 129/296] =?UTF-8?q?Mise=20=C3=A0=20jour=20de=20'mods/ITEMS?= =?UTF-8?q?/mcl=5Fcore/locale/mcl=5Fcore.ru.tr'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mods/ITEMS/mcl_core/locale/mcl_core.ru.tr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr b/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr index ad9d863b2..2d5b5462c 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr @@ -95,7 +95,7 @@ Dirt acts as a soil for a few plants. When in light, this block may grow a grass Emerald=Изумруд Emerald Ore=Изумрудная руда Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=Изумрудная руда встречается очень редко и всегда по одному блоку. -Emeralds are used in villager trades as currency.=Изумруды не очень полезны сами по себе, но их можно обменять на золотые слитки. +Emeralds are used in villager trades as currency.= Flint=Кремень Flint is a raw material.=Кремень это необработанный материал. Flowing Lava=Текущая лава From 89e90b13eb53085a801c37c639a796a0a917cac0 Mon Sep 17 00:00:00 2001 From: NO11 Date: Mon, 20 Sep 2021 14:16:59 +0000 Subject: [PATCH 130/296] Use on_newplayer --- mods/MISC/mcl_privs/init.lua | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/mods/MISC/mcl_privs/init.lua b/mods/MISC/mcl_privs/init.lua index c63f7c5c5..302557f86 100644 --- a/mods/MISC/mcl_privs/init.lua +++ b/mods/MISC/mcl_privs/init.lua @@ -4,12 +4,9 @@ minetest.register_privilege("maphack", { description = S("Can place and use advanced blocks like mob spawners, command blocks and barriers."), }) -minetest.register_on_joinplayer(function(player) +minetest.register_on_newplayer(function(player) local name = player:get_player_name() - local meta = player:get_meta() - if meta:get_int("fly_changed") == 1 then return end - local fly = nil if minetest.is_creative_enabled(name) then fly = true @@ -18,13 +15,3 @@ minetest.register_on_joinplayer(function(player) fly = fly, }) end) - -for _, action in pairs({ "grant", "revoke" }) do - minetest["register_on_priv_" .. action](function(name, _, priv) - if priv == "fly" then - local player = minetest.get_player_by_name(name) - local meta = player:get_meta() - meta:set_int("fly_changed", 1) - end - end) -end \ No newline at end of file From df1d8077e6123cef815bc4f30dd02838b9b84dec Mon Sep 17 00:00:00 2001 From: NO11 Date: Tue, 21 Sep 2021 18:07:36 +0000 Subject: [PATCH 131/296] Some fixes for mcl_beds - remove enable_bed_night_skip setting (mcl_playersSleepingPercentage setting can be used to enable disable night skip) - make it possible to change mcl_playersSleepingPercentage ingame - fix weird bug which allowed only numbers <= 0 --- mods/ITEMS/mcl_beds/functions.lua | 39 +++++++++++++++---------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/mods/ITEMS/mcl_beds/functions.lua b/mods/ITEMS/mcl_beds/functions.lua index 01ccec851..e7306b40a 100644 --- a/mods/ITEMS/mcl_beds/functions.lua +++ b/mods/ITEMS/mcl_beds/functions.lua @@ -9,36 +9,36 @@ local weather_mod = minetest.get_modpath("mcl_weather") local explosions_mod = minetest.get_modpath("mcl_explosions") local spawn_mod = minetest.get_modpath("mcl_spawn") local worlds_mod = minetest.get_modpath("mcl_worlds") -local players_in_bed_setting = tonumber(minetest.settings:get("mcl_playersSleepingPercentage")) -- Helper functions local function get_look_yaw(pos) local n = minetest.get_node(pos) - if n.param2 == 1 then - return math.pi / 2, n.param2 - elseif n.param2 == 3 then - return -math.pi / 2, n.param2 - elseif n.param2 == 0 then - return math.pi, n.param2 + local param = n.param2 + if param == 1 then + return math.pi / 2, param + elseif param == 3 then + return -math.pi / 2, param + elseif param == 0 then + return math.pi, param else - return 0, n.param2 + return 0, param end end +local function players_in_bed_setting() + return tonumber(minetest.settings:get("mcl_playersSleepingPercentage")) +end + local function is_night_skip_enabled() - local enable_night_skip = minetest.settings:get_bool("enable_bed_night_skip") - if enable_night_skip == nil then - enable_night_skip = true - end - return enable_night_skip + return players_in_bed_setting() <= 100 end local function check_in_beds(players) if not players then players = minetest.get_connected_players() end - return players_in_bed_setting <= (#mcl_beds.player * 100) / #players + return players_in_bed_setting() <= (player_in_bed * 100) / #players end -- These monsters do not prevent sleep @@ -190,8 +190,8 @@ end local function update_formspecs(finished, ges) local ges = ges or #minetest.get_connected_players() local form_n = "size[12,5;true]" - local all_in_bed = players_in_bed_setting <= (player_in_bed * 100) / ges - local night_skip = is_night_skip_enabled() and players_in_bed_setting <= 100 + local all_in_bed = players_in_bed_setting() <= (player_in_bed * 100) / ges + local night_skip = is_night_skip_enabled() local button_leave = "button_exit[4,3;4,0.75;leave;"..F(S("Leave bed")).."]" local button_abort = "button_exit[4,3;4,0.75;leave;"..F(S("Abort sleep")).."]" local bg_presleep = "bgcolor[#00000080;true]" @@ -204,7 +204,7 @@ local function update_formspecs(finished, ges) return elseif not is_sp then local text = S("Players in bed: @1/@2", player_in_bed, ges) - if not night_skip or players_in_bed_setting > 100 then + if not night_skip then text = text .. "\n" .. S("Note: Night skip is disabled.") form_n = form_n .. bg_presleep form_n = form_n .. button_leave @@ -214,10 +214,10 @@ local function update_formspecs(finished, ges) form_n = form_n .. button_abort else local comment = "You will fall asleep when " - if players_in_bed_setting == 100 then + if players_in_bed_setting() == 100 then comment = S(comment .. "all players are in bed.") else - comment = S(comment .. "@1% of all players are in bed.", players_in_bed_setting) + comment = S(comment .. "@1% of all players are in bed.", players_in_bed_setting()) end text = text .. "\n" .. comment form_n = form_n .. bg_presleep @@ -347,7 +347,6 @@ function mcl_beds.on_rightclick(pos, player, is_top) end end - -- Callbacks minetest.register_on_joinplayer(function(player) local meta = player:get_meta() From 71f448537cb523c9f8287b630ccce6f1ddd91cca Mon Sep 17 00:00:00 2001 From: NO11 Date: Tue, 21 Sep 2021 18:14:24 +0000 Subject: [PATCH 132/296] Remove unused setting from settingtypes.txt --- settingtypes.txt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/settingtypes.txt b/settingtypes.txt index 89e11833f..542711675 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -36,11 +36,9 @@ enable_bed_respawn (Respawn at bed) bool true # How many players have to sleep to skip the night, in percent. # Setting to 0 will mean 1 player is always enough to skip the night. Setting above 100 will prevent skipping the night. # 100 by default. +# The setting can be changed ingame using `/set mcl_playersSleepingPercentage ` mcl_playersSleepingPercentage (Players Sleeping Percentage) int 100 -# If enabled, the night can be skipped if all players are in bed. -# This setting is only read at startup. -enable_bed_night_skip (Skip night when sleeping) bool true # Normally, players drop all their items when they die. Enable this # setting, so players always keep their inventory on death. mcl_keepInventory (Keep inventory on death) bool false From e83438e42cb677e6336f52e5e17973fcbef5663c Mon Sep 17 00:00:00 2001 From: NO11 Date: Tue, 21 Sep 2021 18:19:07 +0000 Subject: [PATCH 133/296] Update mcl_bed README.txt --- mods/ITEMS/mcl_beds/README.txt | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/mods/ITEMS/mcl_beds/README.txt b/mods/ITEMS/mcl_beds/README.txt index cda6ebd92..34b493702 100644 --- a/mods/ITEMS/mcl_beds/README.txt +++ b/mods/ITEMS/mcl_beds/README.txt @@ -12,15 +12,7 @@ Authors of media (textures) BlockMen (CC BY-SA 3.0) This mod adds a bed to Minetest which allows to skip the night. -To sleep, rightclick the bed. If playing in singleplayer mode the night gets skipped -immediately. If playing multiplayer you get shown how many other players are in bed too, -if all players are sleeping the night gets skipped. The night skip can be forced if more -than 50% of the players are lying in bed and use this option. - -Another feature is a controlled respawning. If you have slept in bed (not just lying in -it) your respawn point is set to the beds location and you will respawn there after +To sleep, rightclick the bed. +Another feature is a controlled respawning. If you have slept in bed your respawn point is set to the beds location and you will respawn there after death. -You can disable the respawn at beds by setting "enable_bed_respawn = false" in -minetest.conf. -You can disable the night skip feature by setting "enable_bed_night_skip = false" in -minetest.conf or by using the /set command in-game. +Use the mcl_playersSleepingPercentage setting to enable/disable night skipping or set a percentage of how many players need to sleep to skip the night. \ No newline at end of file From 8697b38d60325f289eb75fd19b83e86e877946bc Mon Sep 17 00:00:00 2001 From: NO11 Date: Mon, 27 Sep 2021 20:00:11 +0000 Subject: [PATCH 134/296] Remove on_newplayer ... --- mods/MISC/mcl_privs/init.lua | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/mods/MISC/mcl_privs/init.lua b/mods/MISC/mcl_privs/init.lua index 302557f86..c63f7c5c5 100644 --- a/mods/MISC/mcl_privs/init.lua +++ b/mods/MISC/mcl_privs/init.lua @@ -4,9 +4,12 @@ minetest.register_privilege("maphack", { description = S("Can place and use advanced blocks like mob spawners, command blocks and barriers."), }) -minetest.register_on_newplayer(function(player) +minetest.register_on_joinplayer(function(player) local name = player:get_player_name() + local meta = player:get_meta() + if meta:get_int("fly_changed") == 1 then return end + local fly = nil if minetest.is_creative_enabled(name) then fly = true @@ -15,3 +18,13 @@ minetest.register_on_newplayer(function(player) fly = fly, }) end) + +for _, action in pairs({ "grant", "revoke" }) do + minetest["register_on_priv_" .. action](function(name, _, priv) + if priv == "fly" then + local player = minetest.get_player_by_name(name) + local meta = player:get_meta() + meta:set_int("fly_changed", 1) + end + end) +end \ No newline at end of file From 03be73656648136fdabff2dd68c6e44ed184f475 Mon Sep 17 00:00:00 2001 From: NO11 Date: Mon, 27 Sep 2021 20:13:12 +0000 Subject: [PATCH 135/296] Dont skip night if no players are in bed --- mods/ITEMS/mcl_beds/functions.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mods/ITEMS/mcl_beds/functions.lua b/mods/ITEMS/mcl_beds/functions.lua index e7306b40a..e2bece033 100644 --- a/mods/ITEMS/mcl_beds/functions.lua +++ b/mods/ITEMS/mcl_beds/functions.lua @@ -38,6 +38,9 @@ local function check_in_beds(players) if not players then players = minetest.get_connected_players() end + if player_in_bed < 0 then + return false + end return players_in_bed_setting() <= (player_in_bed * 100) / #players end From 16c73c1cb652b02f77e6140e9ad41f602d5f29aa Mon Sep 17 00:00:00 2001 From: NO11 Date: Tue, 28 Sep 2021 13:16:19 +0000 Subject: [PATCH 136/296] Add forgotten `=` --- 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 e2bece033..062219294 100644 --- a/mods/ITEMS/mcl_beds/functions.lua +++ b/mods/ITEMS/mcl_beds/functions.lua @@ -38,7 +38,7 @@ local function check_in_beds(players) if not players then players = minetest.get_connected_players() end - if player_in_bed < 0 then + if player_in_bed <= 0 then return false end return players_in_bed_setting() <= (player_in_bed * 100) / #players From e9437e9e1e623a493ecf2abbac91fefd775c5aa4 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Wed, 29 Sep 2021 21:06:51 +0200 Subject: [PATCH 137/296] fix crash then using function in `_mcl_armor_[texture, preview]` tool field --- mods/ITEMS/mcl_enchanting/engine.lua | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/mods/ITEMS/mcl_enchanting/engine.lua b/mods/ITEMS/mcl_enchanting/engine.lua index d2a749947..6050aeed2 100644 --- a/mods/ITEMS/mcl_enchanting/engine.lua +++ b/mods/ITEMS/mcl_enchanting/engine.lua @@ -270,8 +270,14 @@ function mcl_enchanting.initialize() new_def.groups.not_in_creative_inventory = 1 new_def.groups.not_in_craft_guide = 1 new_def.groups.enchanted = 1 - new_def._mcl_armor_texture = new_def._mcl_armor_texture and new_def._mcl_armor_texture .. mcl_enchanting.overlay - new_def._mcl_armor_preview = new_def._mcl_armor_preview and new_def._mcl_armor_preview .. mcl_enchanting.overlay + + if new_def._mcl_armor_texture and not type(new_def._mcl_armor_texture) == "function" then + new_def._mcl_armor_texture = new_def._mcl_armor_texture .. mcl_enchanting.overlay + end + if new_def._mcl_armor_preview and not type(new_def._mcl_armor_preview) == "function" then + new_def._mcl_armor_preview = new_def._mcl_armor_preview .. mcl_enchanting.overlay + end + new_def._mcl_enchanting_enchanted_tool = new_name new_def.after_use = get_after_use_callback(itemdef) local register_list = register_item_list From a410d173069baf3d38f5fe5a704e4db562e5dd8a Mon Sep 17 00:00:00 2001 From: NO11 Date: Thu, 30 Sep 2021 20:14:13 +0000 Subject: [PATCH 138/296] Fix that all of new players' default_privs are removed --- mods/MISC/mcl_privs/init.lua | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/mods/MISC/mcl_privs/init.lua b/mods/MISC/mcl_privs/init.lua index c63f7c5c5..f06ff3582 100644 --- a/mods/MISC/mcl_privs/init.lua +++ b/mods/MISC/mcl_privs/init.lua @@ -6,7 +6,6 @@ minetest.register_privilege("maphack", { minetest.register_on_joinplayer(function(player) local name = player:get_player_name() - local meta = player:get_meta() if meta:get_int("fly_changed") == 1 then return end @@ -14,12 +13,12 @@ minetest.register_on_joinplayer(function(player) if minetest.is_creative_enabled(name) then fly = true end - minetest.set_player_privs(name, { - fly = fly, - }) + local player_privs = minetest.get_player_privs(name) + player_privs.fly = fly + minetest.set_player_privs(name, player_privs) end) -for _, action in pairs({ "grant", "revoke" }) do +for _, action in pairs({"grant", "revoke"}) do minetest["register_on_priv_" .. action](function(name, _, priv) if priv == "fly" then local player = minetest.get_player_by_name(name) From 8e3f9d216944d258cd385223db037ef1882deb63 Mon Sep 17 00:00:00 2001 From: NO11 Date: Thu, 9 Sep 2021 09:22:27 +0000 Subject: [PATCH 139/296] add basic lightning API --- mods/ENVIRONMENT/lightning/init.lua | 75 ++++++++++++++++++----------- 1 file changed, 46 insertions(+), 29 deletions(-) diff --git a/mods/ENVIRONMENT/lightning/init.lua b/mods/ENVIRONMENT/lightning/init.lua index 3d5955d6e..3230f0b0a 100644 --- a/mods/ENVIRONMENT/lightning/init.lua +++ b/mods/ENVIRONMENT/lightning/init.lua @@ -24,13 +24,14 @@ local get_objects_inside_radius = minetest.get_objects_inside_radius local get_item_group = minetest.get_item_group lightning = { - interval_low = 17, - interval_high = 503, - range_h = 100, - range_v = 50, - size = 100, - -- disable this to stop lightning mod from striking - auto = true, + interval_low = 17, + interval_high = 503, + range_h = 100, + range_v = 50, + size = 100, + -- disable this to stop lightning mod from striking + auto = true, + on_strike_functions = {}, } local rng = PcgRandom(32321123312123) @@ -54,6 +55,18 @@ end minetest.register_globalstep(revertsky) +-- lightning strike API + +-- See README.md +--[[ + lightning.register_on_strike(function(pos, pos2, objects) + -- code + end) +]] +function lightning.register_on_strike(func) + table.insert(lightning.on_strike_functions, func) +end + -- select a random strike point, midpoint local function choose_pos(pos) if not pos then @@ -79,14 +92,14 @@ local function choose_pos(pos) pos.z = math.floor(pos.z - (lightning.range_h / 2) + rng:next(1, lightning.range_h)) end - local b, pos2 = line_of_sight(pos, {x = pos.x, y = pos.y - lightning.range_v, z = pos.z}, 1) + local b, pos2 = line_of_sight(pos, { x = pos.x, y = pos.y - lightning.range_v, z = pos.z }, 1) -- nothing but air found if b then return nil, nil end - local n = get_node({x = pos2.x, y = pos2.y - 1/2, z = pos2.z}) + local n = get_node({ x = pos2.x, y = pos2.y - 1/2, z = pos2.z }) if n.name == "air" or n.name == "ignore" then return nil, nil end @@ -94,7 +107,6 @@ local function choose_pos(pos) return pos, pos2 end --- lightning strike API -- * pos: optional, if not given a random pos will be chosen -- * returns: bool - success if a strike happened function lightning.strike(pos) @@ -108,21 +120,30 @@ function lightning.strike(pos) if not pos then return false end + local objects = get_objects_inside_radius(pos2, 3.5) + if lightning.on_strike_functions then + for _, func in pairs(lightning.on_strike_functions) do + func(pos, pos2, objects) + end + end +end + + +lightning.register_on_strike(function(pos, pos2, objects) + local particle_pos = vector.offset(pos2, 0, (lightning.size / 2) + 0.5, 0) + local particle_size = lightning.size * 10 + local time = 0.2 add_particlespawner({ amount = 1, - time = 0.2, + time = time, -- make it hit the top of a block exactly with the bottom - minpos = {x = pos2.x, y = pos2.y + (lightning.size / 2) + 1/2, z = pos2.z }, - maxpos = {x = pos2.x, y = pos2.y + (lightning.size / 2) + 1/2, z = pos2.z }, - minvel = {x = 0, y = 0, z = 0}, - maxvel = {x = 0, y = 0, z = 0}, - minacc = {x = 0, y = 0, z = 0}, - maxacc = {x = 0, y = 0, z = 0}, - minexptime = 0.2, - maxexptime = 0.2, - minsize = lightning.size * 10, - maxsize = lightning.size * 10, + minpos = particle_pos, + maxpos = particle_pos, + minexptime = time, + maxexptime = time, + minsize = particle_size, + maxsize = particle_size, collisiondetection = true, vertical = true, -- to make it appear hitting the node that will get set on fire, make sure @@ -135,10 +156,7 @@ function lightning.strike(pos) sound_play({ name = "lightning_thunder", gain = 10 }, { pos = pos, max_hear_distance = 500 }, true) -- damage nearby objects, transform mobs - -- TODO: use an API insteed of hardcoding this behaviour - local objs = get_objects_inside_radius(pos2, 3.5) - for o=1, #objs do - local obj = objs[o] + for _, obj in pairs(objects) do local lua = obj:get_luaentity() -- pig → zombie pigman (no damage) if lua and lua.name == "mobs_mc:pig" then @@ -155,7 +173,7 @@ function lightning.strike(pos) end obj:set_properties({textures = lua.base_texture}) -- villager → witch (no damage) - --elseif lua and lua.name == "mobs_mc:villager" then + -- elseif lua and lua.name == "mobs_mc:villager" then -- Witches are incomplete, this code is unused -- TODO: Enable this code when witches are working. --[[ @@ -172,7 +190,7 @@ function lightning.strike(pos) obj:set_yaw(rot) -- Other objects: Just damage else - mcl_util.deal_damage(obj, 5, {type = "lightning_bolt"}) + mcl_util.deal_damage(obj, 5, { type = "lightning_bolt" }) end end @@ -223,8 +241,7 @@ function lightning.strike(pos) end end end - -end +end) -- if other mods disable auto lightning during initialization, don't trigger the first lightning. after(5, function(dtime) From e4af02ea526ef32da38ca7094f13b1c7c128bc83 Mon Sep 17 00:00:00 2001 From: NO11 Date: Thu, 9 Sep 2021 09:54:58 +0000 Subject: [PATCH 140/296] Add function to replace mobs --- mods/CORE/mcl_util/init.lua | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/mods/CORE/mcl_util/init.lua b/mods/CORE/mcl_util/init.lua index a7504af08..363b9b5fe 100644 --- a/mods/CORE/mcl_util/init.lua +++ b/mods/CORE/mcl_util/init.lua @@ -538,3 +538,12 @@ function mcl_util.get_object_name(object) return luaentity.nametag and luaentity.nametag ~= "" and luaentity.nametag or luaentity.description or luaentity.name end end + +function mcl_util.replace_mob(obj, mob) + local rot = obj:get_yaw() + local pos = obj:get_pos() + obj:remove() + obj = minetest.add_entity(pos, mob) + obj:set_yaw(rot) + return obj +end From 463fe2af5f3343dcecefec9eb5147f34ec04cb3d Mon Sep 17 00:00:00 2001 From: NO11 Date: Thu, 9 Sep 2021 09:57:36 +0000 Subject: [PATCH 141/296] use mcl_util.replace_mob function to simplify lightning code --- mods/ENVIRONMENT/lightning/init.lua | 38 +++++++---------------------- 1 file changed, 9 insertions(+), 29 deletions(-) diff --git a/mods/ENVIRONMENT/lightning/init.lua b/mods/ENVIRONMENT/lightning/init.lua index 3230f0b0a..5568e63fc 100644 --- a/mods/ENVIRONMENT/lightning/init.lua +++ b/mods/ENVIRONMENT/lightning/init.lua @@ -128,8 +128,6 @@ function lightning.strike(pos) end end - - lightning.register_on_strike(function(pos, pos2, objects) local particle_pos = vector.offset(pos2, 0, (lightning.size / 2) + 0.5, 0) local particle_size = lightning.size * 10 @@ -158,37 +156,19 @@ lightning.register_on_strike(function(pos, pos2, objects) -- damage nearby objects, transform mobs for _, obj in pairs(objects) do local lua = obj:get_luaentity() - -- pig → zombie pigman (no damage) if lua and lua.name == "mobs_mc:pig" then - local rot = obj:get_yaw() - obj:remove() - obj = add_entity(pos2, "mobs_mc:pigman") - obj:set_yaw(rot) - -- mooshroom: toggle color red/brown (no damage) + mcl_util.replace_mob(obj, "mobs_mc:pigman") elseif lua and lua.name == "mobs_mc:mooshroom" then if lua.base_texture[1] == "mobs_mc_mooshroom.png" then lua.base_texture = { "mobs_mc_mooshroom_brown.png", "mobs_mc_mushroom_brown.png" } else lua.base_texture = { "mobs_mc_mooshroom.png", "mobs_mc_mushroom_red.png" } end - obj:set_properties({textures = lua.base_texture}) - -- villager → witch (no damage) - -- elseif lua and lua.name == "mobs_mc:villager" then - -- Witches are incomplete, this code is unused - -- TODO: Enable this code when witches are working. - --[[ - local rot = obj:get_yaw() - obj:remove() - obj = minetest.add_entity(pos2, "mobs_mc:witch") - obj:set_yaw(rot) - ]] - -- charged creeper + obj:set_properties({ textures = lua.base_texture }) + elseif lua and lua.name == "mobs_mc:villager" then + mcl_util.replace_mob(obj, "mobs_mc:witch") elseif lua and lua.name == "mobs_mc:creeper" then - local rot = obj:get_yaw() - obj:remove() - obj = add_entity(pos2, "mobs_mc:creeper_charged") - obj:set_yaw(rot) - -- Other objects: Just damage + mcl_util.replace_mob(obj, "mobs_mc:creeper_charged") else mcl_util.deal_damage(obj, 5, { type = "lightning_bolt" }) end @@ -204,7 +184,7 @@ lightning.register_on_strike(function(pos, pos2, objects) local name = player:get_player_name() if ps[name] == nil then ps[name] = {p = player, sky = sky} - mcl_weather.skycolor.add_layer("lightning", {{r=255,g=255,b=255}}, true) + mcl_weather.skycolor.add_layer("lightning", { { r = 255, g = 255, b = 255 } }, true) mcl_weather.skycolor.active = true end end @@ -219,7 +199,7 @@ lightning.register_on_strike(function(pos, pos2, objects) if rng:next(1,100) <= 3 then skeleton_lightning = true end - if get_item_group(get_node({x = pos2.x, y = pos2.y - 1, z = pos2.z}).name, "liquid") < 1 then + if get_item_group(get_node({ x = pos2.x, y = pos2.y - 1, z = pos2.z }).name, "liquid") < 1 then if get_node(pos2).name == "air" then -- Low chance for a lightning to spawn skeleton horse + skeletons if skeleton_lightning then @@ -228,7 +208,7 @@ lightning.register_on_strike(function(pos, pos2, objects) local angle, posadd angle = math.random(0, math.pi*2) for i=1,3 do - posadd = {x=math.cos(angle),y=0,z=math.sin(angle)} + posadd = { x=math.cos(angle),y=0,z=math.sin(angle) } posadd = vector.normalize(posadd) local mob = add_entity(vector.add(pos2, posadd), "mobs_mc:skeleton") mob:set_yaw(angle-math.pi/2) @@ -237,7 +217,7 @@ lightning.register_on_strike(function(pos, pos2, objects) -- Cause a fire else - set_node(pos2, {name = "mcl_fire:fire"}) + set_node(pos2, { name = "mcl_fire:fire" }) end end end From fe91d7f3e0a5c629cb1f3abad593671ee851ee39 Mon Sep 17 00:00:00 2001 From: NO11 Date: Thu, 9 Sep 2021 10:07:45 +0000 Subject: [PATCH 142/296] use mcl_util.replace_mob function to simplify dispenser code --- mods/ITEMS/REDSTONE/mcl_dispensers/init.lua | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua b/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua index 82d53c806..47acacbb9 100644 --- a/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua +++ b/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua @@ -203,12 +203,8 @@ local dispenserdef = { else minetest.add_item(droppos, mobs_mc.items.mushroom_red .. " 5") end - local oldyaw = obj:get_yaw() - obj:remove() - local cow = minetest.add_entity(pos, "mobs_mc:cow") - cow:set_yaw(oldyaw) - obj = cow - entity = cow:get_luaentity() + obj = mcl_util.replace_mob(obj, "mobs_mc:cow") + entity = obj:get_luaentity() used = true end if used then From 9188467a6adfdc6bd8edfeb8f156c510ce7ab1b0 Mon Sep 17 00:00:00 2001 From: NO11 Date: Thu, 9 Sep 2021 12:31:19 +0000 Subject: [PATCH 143/296] add API.md for lightning mod --- mods/ENVIRONMENT/lightning/API.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 mods/ENVIRONMENT/lightning/API.md diff --git a/mods/ENVIRONMENT/lightning/API.md b/mods/ENVIRONMENT/lightning/API.md new file mode 100644 index 000000000..6a4dd11cf --- /dev/null +++ b/mods/ENVIRONMENT/lightning/API.md @@ -0,0 +1,31 @@ +# lightning +Lightning mod for MineClone2 with the following API: + +## lightning.register_on_strike(function(pos, pos2, objects)) +Custom function called when a lightning strikes. + +* `pos`: impact position +* `pos2`: rounded node position where fire is placed +* `objects`: table with ObjectRefs of all objects within a radius of 3.5 around pos2 + +## lightning.strike(pos) +Let a lightning strike. + +* pos: optional, if not given a random pos will be chosen +* returns: bool - success if a strike happened + + +### Examples: + +``` +lightning.register_on_strike(function(pos, pos2, objects) + for _, obj in pairs(objects) do + obj:remove() + end + minetest.add_entity(pos, "mobs_mc:sheep") +end) + +minetest.register_on_respawnplayer(function(player) + lightning.strike(player:get_pos()) +end) +``` \ No newline at end of file From 72ea9069bd848eb4bcbd030bc32b859370c5cef5 Mon Sep 17 00:00:00 2001 From: NO11 Date: Thu, 9 Sep 2021 12:35:05 +0000 Subject: [PATCH 144/296] correct lightning API.md a bit --- mods/ENVIRONMENT/lightning/API.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/ENVIRONMENT/lightning/API.md b/mods/ENVIRONMENT/lightning/API.md index 6a4dd11cf..ad4f0a3b4 100644 --- a/mods/ENVIRONMENT/lightning/API.md +++ b/mods/ENVIRONMENT/lightning/API.md @@ -11,8 +11,8 @@ Custom function called when a lightning strikes. ## lightning.strike(pos) Let a lightning strike. -* pos: optional, if not given a random pos will be chosen -* returns: bool - success if a strike happened +* `pos`: optional, if not given a random pos will be chosen +* `returns`: bool - success if a strike happened ### Examples: From 03829dd51884c92fae3d8ee0dd04f3dad1155dec Mon Sep 17 00:00:00 2001 From: NO11 Date: Thu, 9 Sep 2021 12:35:50 +0000 Subject: [PATCH 145/296] fix typo --- mods/ENVIRONMENT/lightning/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ENVIRONMENT/lightning/init.lua b/mods/ENVIRONMENT/lightning/init.lua index 5568e63fc..b234092af 100644 --- a/mods/ENVIRONMENT/lightning/init.lua +++ b/mods/ENVIRONMENT/lightning/init.lua @@ -57,7 +57,7 @@ minetest.register_globalstep(revertsky) -- lightning strike API --- See README.md +-- See API.md --[[ lightning.register_on_strike(function(pos, pos2, objects) -- code From 0584d16569103bb5cd15c5e5041efb842d5b8784 Mon Sep 17 00:00:00 2001 From: NO11 Date: Thu, 9 Sep 2021 13:21:33 +0000 Subject: [PATCH 146/296] add lightning API support for mobs --- mods/ENVIRONMENT/lightning/init.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mods/ENVIRONMENT/lightning/init.lua b/mods/ENVIRONMENT/lightning/init.lua index b234092af..83494462f 100644 --- a/mods/ENVIRONMENT/lightning/init.lua +++ b/mods/ENVIRONMENT/lightning/init.lua @@ -156,6 +156,10 @@ lightning.register_on_strike(function(pos, pos2, objects) -- damage nearby objects, transform mobs for _, obj in pairs(objects) do local lua = obj:get_luaentity() + if lua and lua._on_strike then + lua._on_strike(lua, pos, pos2, objects) + end + -- remove this when mob API is done if lua and lua.name == "mobs_mc:pig" then mcl_util.replace_mob(obj, "mobs_mc:pigman") elseif lua and lua.name == "mobs_mc:mooshroom" then From 9ccf8de606c4ce4e6b903ac3ce6727d01f3d5160 Mon Sep 17 00:00:00 2001 From: NO11 Date: Sat, 9 Oct 2021 14:41:56 +0000 Subject: [PATCH 147/296] Fix crash on startup if mcl_playersSleepingPercentage is not defined (#1874) --- 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 062219294..b8478fc1f 100644 --- a/mods/ITEMS/mcl_beds/functions.lua +++ b/mods/ITEMS/mcl_beds/functions.lua @@ -27,7 +27,7 @@ local function get_look_yaw(pos) end local function players_in_bed_setting() - return tonumber(minetest.settings:get("mcl_playersSleepingPercentage")) + return tonumber(minetest.settings:get("mcl_playersSleepingPercentage")) or 100 end local function is_night_skip_enabled() From 1c458a2e7258565e0d98050263cf98ec17607c71 Mon Sep 17 00:00:00 2001 From: epCode Date: Fri, 15 Oct 2021 12:00:37 -0700 Subject: [PATCH 148/296] Add crossbows --- mods/ITEMS/mcl_bows/arrow.lua | 6 +- mods/ITEMS/mcl_bows/crossbow.lua | 454 ++++++++ mods/ITEMS/mcl_bows/init.lua | 6 + .../ITEMS/mcl_bows/models/mcl_bows_rocket.b3d | Bin 0 -> 11758 bytes .../ITEMS/mcl_bows/models/mcl_bows_rocket.mtl | 10 + .../ITEMS/mcl_bows/models/mcl_bows_rocket.obj | 1016 +++++++++++++++++ mods/ITEMS/mcl_bows/rocket.lua | 706 ++++++++++++ .../sounds/mcl_bows_crossbow_drawback_0.ogg | Bin 0 -> 13529 bytes .../sounds/mcl_bows_crossbow_drawback_1.ogg | Bin 0 -> 13401 bytes .../sounds/mcl_bows_crossbow_drawback_2.ogg | Bin 0 -> 10139 bytes .../sounds/mcl_bows_crossbow_load.ogg | Bin 0 -> 7627 bytes .../sounds/mcl_bows_crossbow_shoot.ogg | Bin 0 -> 9767 bytes .../mcl_bows/sounds/mcl_bows_firework.ogg | Bin 0 -> 42143 bytes .../sounds/mcl_bows_firework_soft.ogg | Bin 0 -> 55786 bytes .../mcl_bows/textures/mcl_bows_crossbow.png | Bin 0 -> 2311 bytes .../mcl_bows/textures/mcl_bows_crossbow_0.png | Bin 0 -> 2369 bytes .../mcl_bows/textures/mcl_bows_crossbow_1.png | Bin 0 -> 2383 bytes .../mcl_bows/textures/mcl_bows_crossbow_2.png | Bin 0 -> 2362 bytes .../mcl_bows/textures/mcl_bows_crossbow_3.png | Bin 0 -> 2794 bytes .../textures/mcl_bows_firework_blue.png | Bin 0 -> 630 bytes .../textures/mcl_bows_firework_green.png | Bin 0 -> 627 bytes .../textures/mcl_bows_firework_red.png | Bin 0 -> 622 bytes .../textures/mcl_bows_firework_white.png | Bin 0 -> 1577 bytes .../textures/mcl_bows_firework_yellow.png | Bin 0 -> 1717 bytes .../mcl_bows/textures/mcl_bows_rocket.png | Bin 0 -> 2133 bytes .../textures/mcl_bows_rocket_particle.png | Bin 0 -> 4675 bytes mods/ITEMS/mcl_enchanting/enchantments.lua | 14 +- mods/ITEMS/mcl_mobspawners/init.lua | 3 +- mods/ITEMS/mcl_potions/tipped_arrow.lua | 2 +- mods/PLAYER/mcl_player/init.lua | 6 +- mods/PLAYER/mcl_playerplus/init.lua | 13 + 31 files changed, 2221 insertions(+), 15 deletions(-) create mode 100644 mods/ITEMS/mcl_bows/crossbow.lua create mode 100644 mods/ITEMS/mcl_bows/models/mcl_bows_rocket.b3d create mode 100644 mods/ITEMS/mcl_bows/models/mcl_bows_rocket.mtl create mode 100644 mods/ITEMS/mcl_bows/models/mcl_bows_rocket.obj create mode 100644 mods/ITEMS/mcl_bows/rocket.lua create mode 100644 mods/ITEMS/mcl_bows/sounds/mcl_bows_crossbow_drawback_0.ogg create mode 100644 mods/ITEMS/mcl_bows/sounds/mcl_bows_crossbow_drawback_1.ogg create mode 100644 mods/ITEMS/mcl_bows/sounds/mcl_bows_crossbow_drawback_2.ogg create mode 100644 mods/ITEMS/mcl_bows/sounds/mcl_bows_crossbow_load.ogg create mode 100644 mods/ITEMS/mcl_bows/sounds/mcl_bows_crossbow_shoot.ogg create mode 100644 mods/ITEMS/mcl_bows/sounds/mcl_bows_firework.ogg create mode 100644 mods/ITEMS/mcl_bows/sounds/mcl_bows_firework_soft.ogg create mode 100644 mods/ITEMS/mcl_bows/textures/mcl_bows_crossbow.png create mode 100644 mods/ITEMS/mcl_bows/textures/mcl_bows_crossbow_0.png create mode 100644 mods/ITEMS/mcl_bows/textures/mcl_bows_crossbow_1.png create mode 100644 mods/ITEMS/mcl_bows/textures/mcl_bows_crossbow_2.png create mode 100644 mods/ITEMS/mcl_bows/textures/mcl_bows_crossbow_3.png create mode 100644 mods/ITEMS/mcl_bows/textures/mcl_bows_firework_blue.png create mode 100644 mods/ITEMS/mcl_bows/textures/mcl_bows_firework_green.png create mode 100644 mods/ITEMS/mcl_bows/textures/mcl_bows_firework_red.png create mode 100644 mods/ITEMS/mcl_bows/textures/mcl_bows_firework_white.png create mode 100644 mods/ITEMS/mcl_bows/textures/mcl_bows_firework_yellow.png create mode 100644 mods/ITEMS/mcl_bows/textures/mcl_bows_rocket.png create mode 100644 mods/ITEMS/mcl_bows/textures/mcl_bows_rocket_particle.png diff --git a/mods/ITEMS/mcl_bows/arrow.lua b/mods/ITEMS/mcl_bows/arrow.lua index 9a22ee622..343707617 100644 --- a/mods/ITEMS/mcl_bows/arrow.lua +++ b/mods/ITEMS/mcl_bows/arrow.lua @@ -43,7 +43,7 @@ S("An arrow fired from a bow has a regular damage of 1-9. At full charge, there' S("Arrows might get stuck on solid blocks and can be retrieved again. They are also capable of pushing wooden buttons."), _doc_items_usagehelp = S("To use arrows as ammunition for a bow, just put them anywhere in your inventory, they will be used up automatically. To use arrows as ammunition for a dispenser, place them in the dispenser's inventory. To retrieve an arrow that sticks in a block, simply walk close to it."), inventory_image = "mcl_bows_arrow_inv.png", - groups = { ammo=1, ammo_bow=1, ammo_bow_regular=1 }, + groups = { ammo=1, ammo_bow=1, ammo_bow_regular=1, ammo_crossbow=1 }, _on_dispense = function(itemstack, dispenserpos, droppos, dropnode, dropdir) -- Shoot arrow local shootpos = vector.add(dispenserpos, vector.multiply(dropdir, 0.51)) @@ -324,7 +324,9 @@ function ARROW_ENTITY.on_step(self, dtime) end if not obj:is_player() then mcl_burning.extinguish(self.object) - self.object:remove() + if self._piercing == 0 then + self.object:remove() + end end return end diff --git a/mods/ITEMS/mcl_bows/crossbow.lua b/mods/ITEMS/mcl_bows/crossbow.lua new file mode 100644 index 000000000..e3124156b --- /dev/null +++ b/mods/ITEMS/mcl_bows/crossbow.lua @@ -0,0 +1,454 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +mcl_bows_s = {} + +-- local arrows = { +-- ["mcl_bows:arrow"] = "mcl_bows:arrow_entity", +-- } + +local GRAVITY = 9.81 +local BOW_DURABILITY = 385 + +-- Charging time in microseconds +local _BOW_CHARGE_TIME_HALF = 350000 -- bow level 1 +local _BOW_CHARGE_TIME_FULL = 900000 -- bow level 2 (full charge) + +local BOW_CHARGE_TIME_HALF = 350000 -- bow level 1 +local BOW_CHARGE_TIME_FULL = 900000 -- bow level 2 (full charge) + +-- Factor to multiply with player speed while player uses bow +-- This emulates the sneak speed. +local PLAYER_USE_CROSSBOW_SPEED = tonumber(minetest.settings:get("movement_speed_crouch")) / tonumber(minetest.settings:get("movement_speed_walk")) + +-- TODO: Use Minecraft speed (ca. 53 m/s) +-- Currently nerfed because at full speed the arrow would easily get out of the range of the loaded map. +local BOW_MAX_SPEED = 68 + +local function play_load_sound(id, pos) + minetest.sound_play("mcl_bows_crossbow_drawback_"..id, {pos=pos, max_hear_distance=12}, true) +end + +--[[ Store the charging state of each player. +keys: player name +value: +nil = not charging or player not existing +number: currently charging, the number is the time from minetest.get_us_time + in which the charging has started +]] +local bow_load = {} + +-- Another player table, this one stores the wield index of the bow being charged +local bow_index = {} + +function mcl_bows_s.shoot_arrow_crossbow(arrow_item, pos, dir, yaw, shooter, power, damage, is_critical, crossbow_stack, collectable) + local obj = minetest.add_entity({x=pos.x,y=pos.y,z=pos.z}, arrow_item.."_entity") + if power == nil then + power = BOW_MAX_SPEED --19 + end + if damage == nil then + damage = 3 + end + local knockback + if crossbow_stack then + local enchantments = mcl_enchanting.get_enchantments(crossbow_stack) + if enchantments.piercing then + obj:get_luaentity()._piercing = 1 * enchantments.piercing + else + obj:get_luaentity()._piercing = 0 + end + end + obj:set_velocity({x=dir.x*power, y=dir.y*power, z=dir.z*power}) + obj:set_acceleration({x=0, y=-GRAVITY, z=0}) + obj:set_yaw(yaw-math.pi/2) + local le = obj:get_luaentity() + le._shooter = shooter + le._source_object = shooter + le._damage = damage + le._is_critical = is_critical + le._startpos = pos + le._knockback = knockback + le._collectable = collectable + minetest.sound_play("mcl_bows_crossbow_shoot", {pos=pos, max_hear_distance=16}, true) + if shooter and shooter:is_player() then + if obj:get_luaentity().player == "" then + obj:get_luaentity().player = shooter + end + obj:get_luaentity().node = shooter:get_inventory():get_stack("main", 1):get_name() + end + return obj +end + +local function get_arrow(player) + local inv = player:get_inventory() + local arrow_stack, arrow_stack_id + for i=1, inv:get_size("main") do + local it = inv:get_stack("main", i) + if not it:is_empty() and minetest.get_item_group(it:get_name(), "ammo_crossbow") ~= 0 then + arrow_stack = it + arrow_stack_id = i + break + end + end + return arrow_stack, arrow_stack_id +end + +local function player_shoot_arrow(itemstack, player, power, damage, is_critical) + local has_multishot_enchantment = mcl_enchanting.has_enchantment(player:get_wielded_item(), "multishot") + local arrow_itemstring = wielditem:get_meta():get("arrow") + + if not arrow_itemstring then + return false + end + + local playerpos = player:get_pos() + local dir = player:get_look_dir() + local yaw = player:get_look_horizontal() + + if has_multishot_enchantment then + mcl_bows_s.shoot_arrow_crossbow(arrow_itemstring, {x=playerpos.x,y=playerpos.y+1.5,z=playerpos.z}, {x=dir.x, y=dir.y, z=dir.z + .2}, yaw, player, power, damage, is_critical, player:get_wielded_item(), false) + mcl_bows_s.shoot_arrow_crossbow(arrow_itemstring, {x=playerpos.x,y=playerpos.y+1.5,z=playerpos.z}, {x=dir.x, y=dir.y, z=dir.z - .2}, yaw, player, power, damage, is_critical, player:get_wielded_item(), false) + mcl_bows_s.shoot_arrow_crossbow(arrow_itemstring, {x=playerpos.x,y=playerpos.y+1.5,z=playerpos.z}, dir, yaw, player, power, damage, is_critical, player:get_wielded_item(), true) + else + mcl_bows_s.shoot_arrow_crossbow(arrow_itemstring, {x=playerpos.x,y=playerpos.y+1.5,z=playerpos.z}, dir, yaw, player, power, damage, is_critical, player:get_wielded_item(), true) + end + return true +end + +-- Bow item, uncharged state +minetest.register_tool("mcl_bows:crossbow", { + description = S("Corssbow"), + _tt_help = S("Launches arrows"), + _doc_items_longdesc = S("Bows are ranged weapons to shoot arrows at your foes.").."\n".. +S("The speed and damage of the arrow increases the longer you charge. The regular damage of the arrow is between 1 and 9. At full charge, there's also a 20% of a critical hit, dealing 10 damage instead."), + _doc_items_usagehelp = S("To use the bow, you first need to have at least one arrow anywhere in your inventory (unless in Creative Mode). Hold down the right mouse button to charge, release to shoot."), + _doc_items_durability = BOW_DURABILITY, + inventory_image = "mcl_bows_crossbow.png", + wield_scale = mcl_vars.tool_wield_scale, + stack_max = 1, + range = 4, + -- Trick to disable digging as well + on_use = function() return end, + on_place = function(itemstack, player, pointed_thing) + if pointed_thing and pointed_thing.type == "node" then + -- Call on_rightclick if the pointed node defines it + local node = minetest.get_node(pointed_thing.under) + if player and not player:get_player_control().sneak then + if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then + return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, player, itemstack) or itemstack + end + end + end + + itemstack:get_meta():set_string("active", "true") + return itemstack + end, + on_secondary_use = function(itemstack) + itemstack:get_meta():set_string("active", "true") + return itemstack + end, + groups = {weapon=1,weapon_ranged=1,crossbow=1,enchantability=1}, + _mcl_uses = 326, +}) + +minetest.register_tool("mcl_bows:crossbow_loaded", { + description = S("Corssbow"), + _tt_help = S("Launches arrows"), + _doc_items_longdesc = S("Corssbow are ranged weapons to shoot arrows at your foes.").."\n".. +S("The speed and damage of the arrow increases the longer you charge. The regular damage of the arrow is between 1 and 9. At full charge, there's also a 20% of a critical hit, dealing 10 damage instead."), + _doc_items_usagehelp = S("To use the corssbow, you first need to have at least one arrow anywhere in your inventory (unless in Creative Mode). Hold down the right mouse button to charge, release to load an arrow into the chamber, then to shoot press left mouse."), + _doc_items_durability = BOW_DURABILITY, + inventory_image = "mcl_bows_crossbow_3.png", + wield_scale = mcl_vars.tool_wield_scale, + stack_max = 1, + range = 4, + -- Trick to disable digging as well + on_use = function() return end, + on_place = function(itemstack, player, pointed_thing) + if pointed_thing and pointed_thing.type == "node" then + -- Call on_rightclick if the pointed node defines it + local node = minetest.get_node(pointed_thing.under) + if player and not player:get_player_control().sneak then + if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then + return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, player, itemstack) or itemstack + end + end + end + + itemstack:get_meta():set_string("active", "true") + return itemstack + end, + on_secondary_use = function(itemstack) + itemstack:get_meta():set_string("active", "true") + return itemstack + end, + groups = {weapon=1,weapon_ranged=1,crossbow=1,enchantability=1}, + _mcl_uses = 326, +}) + +-- Iterates through player inventory and resets all the bows in "charging" state back to their original stage +local function reset_bows(player) + local inv = player:get_inventory() + local list = inv:get_list("main") + for place, stack in pairs(list) do + if stack:get_name() == "mcl_bows:crossbow" or stack:get_name() == "mcl_bows:crossbow_enchanted" then + stack:get_meta():set_string("active", "") + elseif stack:get_name()=="mcl_bows:crossbow_0" or stack:get_name()=="mcl_bows:crossbow_1" or stack:get_name()=="mcl_bows:crossbow_2" then + stack:set_name("mcl_bows:crossbow") + stack:get_meta():set_string("active", "") + list[place] = stack + elseif stack:get_name()=="mcl_bows:crossbow_0_enchanted" or stack:get_name()=="mcl_bows:crossbow_1_enchanted" or stack:get_name()=="mcl_bows:crossbow_2_enchanted" then + stack:set_name("mcl_bows:crossbow_enchanted") + stack:get_meta():set_string("active", "") + list[place] = stack + end + end + inv:set_list("main", list) +end + +-- Resets the bow charging state and player speed. To be used when the player is no longer charging the bow +local function reset_bow_state(player, also_reset_bows) + bow_load[player:get_player_name()] = nil + bow_index[player:get_player_name()] = nil + if minetest.get_modpath("playerphysics") then + playerphysics.remove_physics_factor(player, "speed", "mcl_bows:use_crossbow") + end + if also_reset_bows then + reset_bows(player) + end +end + +-- Bow in charging state +for level=0, 2 do + minetest.register_tool("mcl_bows:crossbow_"..level, { + description = S("Crossbow"), + _doc_items_create_entry = false, + inventory_image = "mcl_bows_crossbow_"..level..".png", + wield_scale = mcl_vars.tool_wield_scale, + stack_max = 1, + range = 0, -- Pointing range to 0 to prevent punching with bow :D + groups = {not_in_creative_inventory=1, not_in_craft_guide=1, bow=1, enchantability=1}, + -- Trick to disable digging as well + on_use = function() return end, + on_drop = function(itemstack, dropper, pos) + reset_bow_state(dropper) + itemstack:get_meta():set_string("active", "") + if mcl_enchanting.is_enchanted(itemstack:get_name()) then + itemstack:set_name("mcl_bows:crossbow_enchanted") + else + itemstack:set_name("mcl_bows:crossbow") + end + minetest.item_drop(itemstack, dropper, pos) + itemstack:take_item() + return itemstack + end, + -- Prevent accidental interaction with itemframes and other nodes + on_place = function(itemstack) + return itemstack + end, + _mcl_uses = 385, + }) +end + + +controls.register_on_release(function(player, key, time) + if key~="RMB" then return end + --local inv = minetest.get_inventory({type="player", name=player:get_player_name()}) + local wielditem = player:get_wielded_item() + if wielditem:get_name()=="mcl_bows:crossbow_2" and get_arrow(player) or wielditem:get_name()=="mcl_bows:crossbow_2" and minetest.is_creative_enabled(player:get_player_name()) or wielditem:get_name()=="mcl_bows:crossbow_2_enchanted" and get_arrow(player) or wielditem:get_name()=="mcl_bows:crossbow_2_enchanted" and minetest.is_creative_enabled(player:get_player_name()) then + local arrow_stack, arrow_stack_id = get_arrow(player) + local arrow_itemstring + + if minetest.is_creative_enabled(player:get_player_name()) then + if arrow_stack then + arrow_itemstring = arrow_stack:get_name() + else + arrow_itemstring = "mcl_bows:arrow" + end + else + arrow_itemstring = arrow_stack:get_name() + arrow_stack:take_item() + player:get_inventory():set_stack("main", arrow_stack_id, arrow_stack) + end + + wielditem:get_meta():set_string("arrow", arrow_itemstring) + + if wielditem:get_name()=="mcl_bows:crossbow_2" then + wielditem:set_name("mcl_bows:crossbow_loaded") + else + wielditem:set_name("mcl_bows:crossbow_loaded_enchanted") + end + player:set_wielded_item(wielditem) + minetest.sound_play("mcl_bows_crossbow_load", {pos=player:get_pos(), max_hear_distance=16}, true) + else + reset_bow_state(player, true) + end +end) + +controls.register_on_press(function(player, key, time) + if key~="LMB" then return end + wielditem = player:get_wielded_item() + if wielditem:get_name()=="mcl_bows:crossbow_loaded" or wielditem:get_name()=="mcl_bows:crossbow_loaded_enchanted" then + local enchanted = mcl_enchanting.is_enchanted(wielditem:get_name()) + local speed, damage + local p_load = bow_load[player:get_player_name()] + local charge + -- Type sanity check + if type(p_load) == "number" then + charge = minetest.get_us_time() - p_load + else + -- In case something goes wrong ... + -- Just assume minimum charge. + charge = 0 + minetest.log("warning", "[mcl_bows] Player "..player:get_player_name().." fires arrow with non-numeric bow_load!") + end + charge = math.max(math.min(charge, BOW_CHARGE_TIME_FULL), 0) + + local charge_ratio = charge / BOW_CHARGE_TIME_FULL + charge_ratio = math.max(math.min(charge_ratio, 1), 0) + + -- Calculate damage and speed + -- Fully charged + local is_critical = false + speed = BOW_MAX_SPEED + local r = math.random(1,5) + if r == 1 then + -- 20% chance for critical hit + damage = 10 + is_critical = true + else + damage = 9 + end + + local has_shot = player_shoot_arrow(wielditem, player, speed, damage, is_critical) + + if enchanted then + wielditem:set_name("mcl_bows:crossbow_enchanted") + else + wielditem:set_name("mcl_bows:crossbow") + end + + if has_shot and not minetest.is_creative_enabled(player:get_player_name()) then + local durability = BOW_DURABILITY + local unbreaking = mcl_enchanting.get_enchantment(wielditem, "unbreaking") + local multishot = mcl_enchanting.get_enchantment(wielditem, "multishot") + if unbreaking > 0 then + durability = durability * (unbreaking + 1) + end + if multishot then + durability = durability / 3 + end + wielditem:add_wear(65535/durability) + end + player:set_wielded_item(wielditem) + reset_bow_state(player, true) + end +end) + +controls.register_on_hold(function(player, key, time) + local name = player:get_player_name() + local creative = minetest.is_creative_enabled(name) + if key ~= "RMB" then + return + end + --local inv = minetest.get_inventory({type="player", name=name}) + local wielditem = player:get_wielded_item() + local enchantments = mcl_enchanting.get_enchantments(wielditem) + if enchantments.quick_charge then + BOW_CHARGE_TIME_HALF = _BOW_CHARGE_TIME_HALF - (enchantments.quick_charge * 0.13 * 1000000 * .5) + BOW_CHARGE_TIME_FULL = _BOW_CHARGE_TIME_FULL - (enchantments.quick_charge * 0.13 * 1000000) + else + BOW_CHARGE_TIME_HALF = _BOW_CHARGE_TIME_HALF + BOW_CHARGE_TIME_FULL = _BOW_CHARGE_TIME_FULL + end + + if bow_load[name] == nil and (wielditem:get_name()=="mcl_bows:crossbow" or wielditem:get_name()=="mcl_bows:crossbow_enchanted") and wielditem:get_meta():get("active") and (creative or get_arrow(player)) then + local enchanted = mcl_enchanting.is_enchanted(wielditem:get_name()) + if enchanted then + wielditem:set_name("mcl_bows:crossbow_0_enchanted") + play_load_sound(0, player:get_pos()) + else + wielditem:set_name("mcl_bows:crossbow_0") + play_load_sound(0, player:get_pos()) + end + player:set_wielded_item(wielditem) + if minetest.get_modpath("playerphysics") then + -- Slow player down when using bow + playerphysics.add_physics_factor(player, "speed", "mcl_bows:use_crossbow", PLAYER_USE_CROSSBOW_SPEED) + end + bow_load[name] = minetest.get_us_time() + bow_index[name] = player:get_wield_index() + else + if player:get_wield_index() == bow_index[name] then + if type(bow_load[name]) == "number" then + if wielditem:get_name() == "mcl_bows:crossbow_0" and minetest.get_us_time() - bow_load[name] >= BOW_CHARGE_TIME_HALF then + wielditem:set_name("mcl_bows:crossbow_1") + play_load_sound(1, player:get_pos()) + elseif wielditem:get_name() == "mcl_bows:crossbow_0_enchanted" and minetest.get_us_time() - bow_load[name] >= BOW_CHARGE_TIME_HALF then + wielditem:set_name("mcl_bows:crossbow_1_enchanted") + play_load_sound(1, player:get_pos()) + elseif wielditem:get_name() == "mcl_bows:crossbow_1" and minetest.get_us_time() - bow_load[name] >= BOW_CHARGE_TIME_FULL then + wielditem:set_name("mcl_bows:crossbow_2") + play_load_sound(2, player:get_pos()) + elseif wielditem:get_name() == "mcl_bows:crossbow_1_enchanted" and minetest.get_us_time() - bow_load[name] >= BOW_CHARGE_TIME_FULL then + wielditem:set_name("mcl_bows:crossbow_2_enchanted") + play_load_sound(2, player:get_pos()) + end + else + if wielditem:get_name() == "mcl_bows:crossbow_0" or wielditem:get_name() == "mcl_bows:crossbow_1" or wielditem:get_name() == "mcl_bows:crossbow_2" then + wielditem:set_name("mcl_bows:crossbow") + play_load_sound(1, player:get_pos()) + elseif wielditem:get_name() == "mcl_bows:crossbow_0_enchanted" or wielditem:get_name() == "mcl_bows:crossbow_1_enchanted" or wielditem:get_name() == "mcl_bows:crossbow_2_enchanted" then + wielditem:set_name("mcl_bows:crossbow_enchanted") + play_load_sound(1, player:get_pos()) + end + end + player:set_wielded_item(wielditem) + else + reset_bow_state(player, true) + end + end +end) + +minetest.register_globalstep(function(dtime) + for _, player in pairs(minetest.get_connected_players()) do + local name = player:get_player_name() + local wielditem = player:get_wielded_item() + local wieldindex = player:get_wield_index() + --local controls = player:get_player_control() + if type(bow_load[name]) == "number" and ((wielditem:get_name()~="mcl_bows:crossbow_0" and wielditem:get_name()~="mcl_bows:crossbow_1" and wielditem:get_name()~="mcl_bows:crossbow_2" and wielditem:get_name()~="mcl_bows:crossbow_0_enchanted" and wielditem:get_name()~="mcl_bows:crossbow_1_enchanted" and wielditem:get_name()~="mcl_bows:crossbow_2_enchanted") or wieldindex ~= bow_index[name]) then + reset_bow_state(player, true) + end + end +end) + +minetest.register_on_joinplayer(function(player) + reset_bows(player) +end) + +minetest.register_on_leaveplayer(function(player) + reset_bow_state(player, true) +end) + +if minetest.get_modpath("mcl_core") and minetest.get_modpath("mcl_mobitems") then + minetest.register_craft({ + output = "mcl_bows:crossbow", + recipe = { + {"mcl_core:stick", "mcl_core:iron_ingot", "mcl_core:stick"}, + {"mcl_mobitems:string", "mcl_bows:arrow", "mcl_mobitems:string"}, + {"", "mcl_core:stick", ""}, + } + }) +end + +minetest.register_craft({ + type = "fuel", + recipe = "group:bow", + burntime = 15, +}) + +-- Add entry aliases for the Help +if minetest.get_modpath("doc") then + doc.add_entry_alias("tools", "mcl_bows:crossbow", "tools", "mcl_bows:crossbow_0") + doc.add_entry_alias("tools", "mcl_bows:crossbow", "tools", "mcl_bows:crossbow_1") + doc.add_entry_alias("tools", "mcl_bows:crossbow", "tools", "mcl_bows:crossbow_2") +end diff --git a/mods/ITEMS/mcl_bows/init.lua b/mods/ITEMS/mcl_bows/init.lua index a2745d950..d5b06dac7 100644 --- a/mods/ITEMS/mcl_bows/init.lua +++ b/mods/ITEMS/mcl_bows/init.lua @@ -1,5 +1,11 @@ +--Bow dofile(minetest.get_modpath("mcl_bows") .. "/arrow.lua") dofile(minetest.get_modpath("mcl_bows") .. "/bow.lua") +dofile(minetest.get_modpath("mcl_bows") .. "/rocket.lua") +--Crossbow +dofile(minetest.get_modpath("mcl_bows") .. "/crossbow.lua") + +--Compatiblility with older MineClone worlds minetest.register_alias("mcl_throwing:bow", "mcl_bows:bow") minetest.register_alias("mcl_throwing:arrow", "mcl_bows:arrow") diff --git a/mods/ITEMS/mcl_bows/models/mcl_bows_rocket.b3d b/mods/ITEMS/mcl_bows/models/mcl_bows_rocket.b3d new file mode 100644 index 0000000000000000000000000000000000000000..0a34f1eaa63c07c7f37e90df2300497fc6c5385f GIT binary patch literal 11758 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 SSLc+M3cN4yo ARROW_TIMEOUT then + self._stuck = true + end + if self._stuck then + if self._fuse > ARROW_TIMEOUT then + local eploded_particle = particle_explosion(self) + damage_explosion(self, eploded_particle * 17) + mcl_burning.extinguish(self.object) + self.object:remove() + return + end + -- Drop arrow as item when it is no longer stuck + -- FIXME: Arrows are a bit slow to react and continue to float in mid air for a few seconds. + if self._fuserechecktimer > STUCK_RECHECK_TIME then + local stuckin_def + if self._stuckin then + stuckin_def = minetest.registered_nodes[minetest.get_node(self._stuckin).name] + end + -- TODO: In MC, arrow just falls down without turning into an item + if stuckin_def and stuckin_def.walkable == false then + spawn_item(self, pos) + return + end + self._fuserechecktimer = 0 + end + -- Pickup arrow if player is nearby (not in Creative Mode) + local objects = minetest.get_objects_inside_radius(pos, 1) + for _,obj in ipairs(objects) do + if obj:is_player() then + if self._collectable and not minetest.is_creative_enabled(obj:get_player_name()) then + if obj:get_inventory():room_for_item("main", "mcl_bows:rocket") then + obj:get_inventory():add_item("main", "mcl_bows:rocket") + minetest.sound_play("item_drop_pickup", { + pos = pos, + max_hear_distance = 16, + gain = 1.0, + }, true) + end + end + mcl_burning.extinguish(self.object) + self.object:remove() + return + end + end + + -- Check for object "collision". Done every tick (hopefully this is not too stressing) + else + + if self._in_player == false then + minetest.add_particlespawner({ + amount = 1, + time = .0001, + minpos = pos, + maxpos = pos, + minvel = vector.new(-0.1,-0.1,-0.1), + maxvel = vector.new(0.1,0.1,0.1), + minexptime = 0.5, + maxexptime = 0.5, + minsize = 2, + maxsize = 2, + collisiondetection = false, + vertical = false, + texture = "mcl_bows_rocket_particle.png", + glow = 1, + }) + end + -- We just check for any hurtable objects nearby. + -- The radius of 3 is fairly liberal, but anything lower than than will cause + -- arrow to hilariously go through mobs often. + -- TODO: Implement an ACTUAL collision detection (engine support needed). + local objs = minetest.get_objects_inside_radius(pos, 1.5) + local closest_object + local closest_distance + + if self._deflection_cooloff > 0 then + self._deflection_cooloff = self._deflection_cooloff - dtime + end + + -- Iterate through all objects and remember the closest attackable object + for k, obj in pairs(objs) do + local ok = false + -- Arrows can only damage players and mobs + if obj:is_player() then + ok = true + elseif obj:get_luaentity() then + if (obj:get_luaentity()._cmi_is_mob or obj:get_luaentity()._hittable_by_projectile) then + ok = true + end + end + + if ok then + local dist = vector.distance(pos, obj:get_pos()) + if not closest_object or not closest_distance then + closest_object = obj + closest_distance = dist + elseif dist < closest_distance then + closest_object = obj + closest_distance = dist + end + end + end + + -- If an attackable object was found, we will damage the closest one only + + if closest_object then + local obj = closest_object + local is_player = obj:is_player() + local lua = obj:get_luaentity() + if obj == self._shooter and self._time_in_air > 1.02 or obj ~= self._shooter and (is_player or (lua and (lua._cmi_is_mob or lua._hittable_by_projectile))) then + if obj:get_hp() > 0 then + -- Check if there is no solid node between arrow and object + local ray = minetest.raycast(self.object:get_pos(), obj:get_pos(), true) + for pointed_thing in ray do + if pointed_thing.type == "object" and pointed_thing.ref == closest_object then + -- Target reached! We can proceed now. + break + elseif pointed_thing.type == "node" then + local nn = minetest.get_node(minetest.get_pointed_thing_position(pointed_thing)).name + local def = minetest.registered_nodes[nn] + if (not def) or def.walkable then + -- There's a node in the way. Delete arrow without damage + mcl_burning.extinguish(self.object) + self.object:remove() + return + end + end + end + + -- Punch target object but avoid hurting enderman. + if not lua or lua.name ~= "mobs_mc:enderman" then + if self._in_player == false then + damage_particles(self.object:get_pos(), self._is_critical) + end + if mcl_burning.is_burning(self.object) then + mcl_burning.set_on_fire(obj, 5) + end + if self._in_player == false then + obj:punch(self.object, 1.0, { + full_punch_interval=1.0, + damage_groups={fleshy=self._damage}, + }, self.object:get_velocity()) + if obj:is_player() then + local eploded_particle = particle_explosion(self) + damage_explosion(self, eploded_particle * 17) + mcl_burning.extinguish(self.object) + self.object:remove() + end + end + end + + + if is_player then + if self._shooter and self._shooter:is_player() and self._in_player == false then + -- “Ding” sound for hitting another player + minetest.sound_play({name="mcl_bows_hit_player", gain=0.1}, {to_player=self._shooter:get_player_name()}, true) + end + end + + if lua then + local entity_name = lua.name + -- Achievement for hitting skeleton, wither skeleton or stray (TODO) with an arrow at least 50 meters away + -- NOTE: Range has been reduced because mobs unload much earlier than that ... >_> + -- TODO: This achievement should be given for the kill, not just a hit + if self._shooter and self._shooter:is_player() and vector.distance(pos, self._startpos) >= 20 then + if mod_awards and (entity_name == "mobs_mc:skeleton" or entity_name == "mobs_mc:stray" or entity_name == "mobs_mc:witherskeleton") then + awards.unlock(self._shooter:get_player_name(), "mcl:snipeSkeleton") + end + end + end + if self._in_player == false then + minetest.sound_play({name="mcl_bows_hit_other", gain=0.3}, {pos=self.object:get_pos(), max_hear_distance=16}, true) + end + end + if not obj:is_player() then + mcl_burning.extinguish(self.object) + if self._piercing == 0 then + local eploded_particle = particle_explosion(self) + damage_explosion(self, eploded_particle * 17) + self.object:remove() + end + end + return + end + end + end + + -- Check for node collision + if self._lastpos.x~=nil and not self._stuck then + local def = minetest.registered_nodes[node.name] + local vel = self.object:get_velocity() + -- Arrow has stopped in one axis, so it probably hit something. + -- This detection is a bit clunky, but sadly, MT does not offer a direct collision detection for us. :-( + if (math.abs(vel.x) < 0.0001) or (math.abs(vel.z) < 0.0001) or (math.abs(vel.y) < 0.00001) then + -- Check for the node to which the arrow is pointing + local dir + if math.abs(vel.y) < 0.00001 then + if self._lastpos.y < pos.y then + dir = {x=0, y=1, z=0} + else + dir = {x=0, y=-1, z=0} + end + else + dir = minetest.facedir_to_dir(minetest.dir_to_facedir(minetest.yaw_to_dir(self.object:get_yaw()-YAW_OFFSET))) + end + self._stuckin = vector.add(dpos, dir) + local snode = minetest.get_node(self._stuckin) + local sdef = minetest.registered_nodes[snode.name] + + -- If node is non-walkable, unknown or ignore, don't make arrow stuck. + -- This causes a deflection in the engine. + if not sdef or sdef.walkable == false or snode.name == "ignore" then + self._stuckin = nil + if self._deflection_cooloff <= 0 then + -- Lose 1/3 of velocity on deflection + local newvel = vector.multiply(vel, 0.6667) + + self.object:set_velocity(newvel) + -- Reset deflection cooloff timer to prevent many deflections happening in quick succession + self._deflection_cooloff = 1.0 + end + else + + -- Node was walkable, make arrow stuck + self._stuck = true + self._fuserechecktimer = 0 + + self.object:set_velocity({x=0, y=0, z=0}) + self.object:set_acceleration({x=0, y=0, z=0}) + + minetest.sound_play({name="mcl_bows_hit_other", gain=0.3}, {pos=self.object:get_pos(), max_hear_distance=16}, true) + + if mcl_burning.is_burning(self.object) and snode.name == "mcl_tnt:tnt" then + tnt.ignite(self._stuckin) + end + + -- Push the button! Push, push, push the button! + if mod_button and minetest.get_item_group(node.name, "button") > 0 and minetest.get_item_group(node.name, "button_push_by_arrow") == 1 then + local bdir = minetest.wallmounted_to_dir(node.param2) + -- Check the button orientation + if vector.equals(vector.add(dpos, bdir), self._stuckin) then + mesecon.push_button(dpos, node) + end + end + end + elseif (def and def.liquidtype ~= "none") then + -- Slow down arrow in liquids + local v = def.liquid_viscosity + if not v then + v = 0 + end + --local old_v = self._viscosity + self._viscosity = v + local vpenalty = math.max(0.1, 0.98 - 0.1 * v) + if math.abs(vel.x) > 0.001 then + vel.x = vel.x * vpenalty + end + if math.abs(vel.z) > 0.001 then + vel.z = vel.z * vpenalty + end + self.object:set_velocity(vel) + end + end + + -- Update yaw + if not self._stuck then + local vel = self.object:get_velocity() + local yaw = minetest.dir_to_yaw(vel)+YAW_OFFSET + local pitch = dir_to_pitch(vel) + self.object:set_rotation({ x = 0, y = yaw, z = pitch }) + end + + -- Update internal variable + self._lastpos={x=pos.x, y=pos.y, z=pos.z} +end + +-- Force recheck of stuck arrows when punched. +-- Otherwise, punching has no effect. +function ARROW_ENTITY.on_punch(self) + if self._stuck then + self._fuserechecktimer = STUCK_RECHECK_TIME + end +end + +function ARROW_ENTITY.get_staticdata(self) + local out = { + lastpos = self._lastpos, + startpos = self._startpos, + damage = self._damage, + is_critical = self._is_critical, + stuck = self._stuck, + stuckin = self._stuckin, + } + if self._stuck then + -- If _fuse is missing for some reason, assume the maximum + if not self._fuse then + self._fuse = ARROW_TIMEOUT + end + out.stuckstarttime = minetest.get_gametime() - self._fuse + end + if self._shooter and self._shooter:is_player() then + out.shootername = self._shooter:get_player_name() + end + return minetest.serialize(out) +end + +function ARROW_ENTITY.on_activate(self, staticdata, dtime_s) + self._time_in_air = 1.0 + self._in_player = false + local data = minetest.deserialize(staticdata) + if data then + self._stuck = data.stuck + if data.stuck then + if data.stuckstarttime then + -- First, check if the stuck arrow is aleady past its life timer. + -- If yes, delete it. + self._fuse = minetest.get_gametime() - data.stuckstarttime + if self._fuse > ARROW_TIMEOUT then + mcl_burning.extinguish(self.object) + self.object:remove() + return + end + end + + self._fuse = 2 + -- Perform a stuck recheck on the next step. + self._fuserechecktimer = STUCK_RECHECK_TIME + + self._stuckin = data.stuckin + end + + -- Get the remaining arrow state + self._lastpos = data.lastpos + self._startpos = data.startpos + self._damage = data.damage + self._is_critical = data.is_critical + if data.shootername then + local shooter = minetest.get_player_by_name(data.shootername) + if shooter and shooter:is_player() then + self._shooter = shooter + end + end + end + self.object:set_armor_groups({ immortal = 1 }) +end + +minetest.register_entity("mcl_bows:rocket_entity", ARROW_ENTITY) + +if minetest.get_modpath("mcl_core") and minetest.get_modpath("mcl_mobitems") then + minetest.register_craft({ + output = "mcl_bows:rocket 1", + recipe = { + {"mcl_core:paper"}, + {"mcl_fireworks:rocket_2"}, + {"mcl_bows:arrow"}, + } + }) +end + +if minetest.get_modpath("doc_identifier") then + doc.sub.identifier.register_object("mcl_bows:rocket_entity", "craftitems", "mcl_bows:rocket") +end diff --git a/mods/ITEMS/mcl_bows/sounds/mcl_bows_crossbow_drawback_0.ogg b/mods/ITEMS/mcl_bows/sounds/mcl_bows_crossbow_drawback_0.ogg new file mode 100644 index 0000000000000000000000000000000000000000..f4f81b30749b453245ee3b3280244ceecb167fe0 GIT binary patch literal 13529 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 e*8{%PUj#&N^p*&fe$j&)LK0>~moC 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 literal 0 HcmV?d00001 diff --git a/mods/ITEMS/mcl_bows/sounds/mcl_bows_crossbow_shoot.ogg b/mods/ITEMS/mcl_bows/sounds/mcl_bows_crossbow_shoot.ogg new file mode 100644 index 0000000000000000000000000000000000000000..a7d7b69d12fdd3ff614c0c612faa7a2d03f40459 GIT binary patch literal 9767 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 literal 0 HcmV?d00001 diff --git a/mods/ITEMS/mcl_bows/textures/mcl_bows_crossbow_1.png b/mods/ITEMS/mcl_bows/textures/mcl_bows_crossbow_1.png new file mode 100644 index 0000000000000000000000000000000000000000..3769f2967b880e0b3eaa1162b8db067891f48b19 GIT binary patch literal 2383 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 literal 0 HcmV?d00001 diff --git a/mods/ITEMS/mcl_bows/textures/mcl_bows_crossbow_3.png b/mods/ITEMS/mcl_bows/textures/mcl_bows_crossbow_3.png new file mode 100644 index 0000000000000000000000000000000000000000..8a8f1b03fcfaf94a5ef572da591dc05a5c80080f GIT binary patch literal 2794 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 QCIA2c07*qoM6N<$f>%QorT_o{ literal 0 HcmV?d00001 diff --git a/mods/ITEMS/mcl_bows/textures/mcl_bows_firework_green.png b/mods/ITEMS/mcl_bows/textures/mcl_bows_firework_green.png new file mode 100644 index 0000000000000000000000000000000000000000..acd74d6d1c59b86acfa3c74c9861a414b28f061c GIT binary patch literal 627 zcmV-(0*w8MP)EX>4Tx04R}tkv&MmKpe$iTSX}?4pxxj5U@H~5EXIMDionYs1;guFuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|=H{g6A|?JWDYS_3;J6>}?mh0_0scmXsb<$WplX(p zP9}tGZdK@cMG#>OU>H$}nfjb4rrU7TlmpZjx!mAuISpFljzbi*RvAfDc| zbk6(45mu5E;&b9LgDyz?$aUG}H_kbWYY7*5n`d(!Ey()lA#h$5yuo&qkMnX zWrgz=XSGset$XqphVt6VGS_JiA&EsSL4*JqHIz|-g*dGmDJIgipYZTU9luB}nOtQs zax9<<6_Voz|AXJ%nuW;;Hz||=x?gPjV+82g1)6o+{yw(t<_QpZ2ClTWzuEw1K1r{) zwb&8Rw+&oew>5bWxZD8-pLEHP94SE4Unl_YXY@@up#K&KuDQLn_Hp_EWT>mu4RCM> zj20<--Q(T8oxS~grq$mMb0c!6Z+X|p00009a7bBm000XU000XU0RWnu7ytkO2XskI zMF-^y4HYOI7BNEw0001jNklYzcxul;3SeR&5wJig1tv8yW=TBiUj2Rk;NLBT z1~FzyOHM~2W>KuF-~D}k{QG_s4GatnLd>G_?8+>RtZ1tL{Qu4H6T?YR4kIfwBQupf zJsdQ!pobs^Koev^jveIiMvFLf4X^$_KmL6`{-lAT;laOKkeH{wrvVGvFD=Wy1!MpK N002ovPDHLkV1m_i4Y~jT literal 0 HcmV?d00001 diff --git a/mods/ITEMS/mcl_bows/textures/mcl_bows_firework_red.png b/mods/ITEMS/mcl_bows/textures/mcl_bows_firework_red.png new file mode 100644 index 0000000000000000000000000000000000000000..4d7355c57a57e45bcf3060f4831604a1bc07d10a GIT binary patch literal 622 zcmV-!0+IcRP)EX>4Tx04R}tkv&MmKpe$iTSX}?4pxxj5U@H~5EXIMDionYs1;guFuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|=H{g6A|?JWDYS_3;J6>}?mh0_0scmXsb<$WplX(p zP9}tGZdK@cMG#>OU>H$}nfjb4rrU7TlmpZjx!mAuISpFljzbi*RvAfDc| zbk6(45mu5E;&b9LgDyz?$aUG}H_kbWYY7*5n`d(!Ey()lA#h$5yuo&qkMnX zWrgz=XSGset$XqphVt6VGS_JiA&EsSL4*JqHIz|-g*dGmDJIgipYZTU9luB}nOtQs zax9<<6_Voz|AXJ%nuW;;Hz||=x?gPjV+82g1)6o+{yw(t<_QpZ2ClTWzuEw1K1r{) zwb&8Rw+&oew>5bWxZD8-pLEHP94SE4Unl_YXY@@up#K&KuDQLn_Hp_EWT>mu4RCM> zj20<--Q(T8oxS~grq$mMb0c!6Z+X|p00009a7bBm000XU000XU0RWnu7ytkO2XskI zMF-^y4HYO23x-o+0001eNklYjYH!a#3SeR&5wJk@si`qbO5#!X_xbaGw{9Uc zFiT2uIyy3oiegv&`t|qy`%yG7FfcHSin1#!GqSRxss8`__fJeGK>#BwD zaB^>EX>4U6ba`-PAZ2)IW&i+q+TB-Mmg6W4{nsjH2}nXbmV?2Z(>v(p&&4*bI92IN zI`uJULfMjKA;i5PT(tiF)#)Gn#IcaKm_iQ0;pel@QlKQa|MGTc=ePUu;HGl1)A<5n zokHsV7|Y>bV7HGBa|~Xtc1p(^Nk^a=`3R_EWP#FdlZ0J%JNqM0UUwzr6mL^qWS8}D z+)_C%ja%q5$atn(gO5O|8N5_vRaUp%)1HBji?s~CnMleQ~hmHR9@|8xt*8vf` zbYg|PWUO4IF_;^7c!3b^2XD3kJljFPyIDV2s$kGIm=h*g+_HyQj6c?vZagde407KU zOtBpS01?JEB*O{@Twpa0?4n3y295~?6=W{h8w(g=xfG#-feK<3_!n3fS#En$gETJlmVmQVH7YN)ZMnrms& zw4qG2&|*t1x3V&=s1&PTZ4GN&)0)@PvDUhF->rupd+NEDleL4@PwfTP_+U*oriNcU zS%Z~goFRCW6C0d?G4Tw><6r;_S_Wq>vG+2V8=Sc;*c2v6(gruwcrXSE{mNpUPwqaL zdx|%*^b~LM9dk6O`w8X<)P3gd3)b2==jz7Tz6%GYPOqvPyOB}Pn z$B~>6F+B%GK6;v;QF)z7t(%D+bEAGvpruLIIwLPfWS)}l4R=x|8UD;5&Veqd(6g}Q z&#+u1eGiL1g5`n+y#dQb(i^Z`B)tL4MbaCvTqL~#%SF-~uv}1~H(0dQdoLY*vb#nj!0flKpLr_UWLm+T+Z)Rz1WdHzpoPCi!NW(xJ#a~mUQd%7> z_<=))>SRGw#8InIgbJlrXw|{w(hs3YLz3d+D7Y3J{8+3yxH#+T;3^1$A0TdSPKqv4 z;{TFDix>}%`|XH%&pJjd5P ze0;r&@htCie~z${HyPj)iD#H@Sj6kZQ=68~d7n7KN|Hi+PCRPR1&JTIF1!53x#+OK zGb2VOJx3fN7K?2xw=pXjD)A(7R8cj`7qTuZoVPfu%gm2FkDyqg5ltM4I;F9{xecpCXq`t_?79%%cJolH&*egWuhng^6)DDHI1fUu^qh z7zpeFjhbzLAKP~01n@rtS6a(osRPrWq}N(n^a$wL1}?5!n!E>G?g0Hyx@1U>MD5y92^28Mao|Dcz0KOZ~vZY_V)upL2{ECAdxKq z000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2jvP57Y-u@zorTR004DKL_t(2&)t$e z4uBvGgZ%TyO0aUeK b{`;X<* zaB^>EX>4U6ba`-PAZ2)IW&i+q+Ray4lI$o9{MRYw2uL6h$H6QSbAvhlB;Z=Qt9q&K z_wkCbk!2x?OaU(H|NT4YAN+(xC}^^nV|4h19I_M$=JqeIJG-#%=YzWlZ}fD1Ay9er zem|yi+85~cHsBJ2kGFcV^NrZ)=;HZw=x1bs(C(9jUbddY=_vOt#BAw4)kAh)Ps5eU zdHJ+lU!BZnx>tk*l$yfIi*(Q4t-I|E{JhwgsbBX1JN9wOp3nt-o5|;>0vtOHAb^B`kq}05s1dK zq8we&nPXsh0CK;EMYM!VA*aa%U2qWQ71&~ z?1~lgl3BS(V=_1IumT}GPTq6@d}$~B?yi1Ns$ftT%!UaTcWf7j@~yV~;@QJa(eG8k zl-lV45FxfA8TMenMfS>(T@p#mz|lZZLFR(Baex6Fw{^{uR&F#CNrp{ya^?~q0Rz^jOLGWZ{9&kVE$^Fv7 zU*zaWK^dPQD3=_?Xlgq)fZrxY7om(Dz~`u8s^qZH?4xnbZ<`iE!>Y+A*M zv&`K~Ju<>N+uohjnzvZ799*rphwxQuv~z1`qRnS_v^`1XY<=mA1zx)O;qpOGr{Lp? zkQt}&lDcA>b!ExJSwFnrNel@+KhAE0?XdQ@m0HJA-@Zl)9m{=>@6`)$eSDS|Jxx?} zN#^P}39KztIUy5Y>H~iCHMjTpwUZZ|=cY@{=2ld~PPxN>+~<`i_E5j)-?1}3z(=3p z_Y!>c34SlZN1x#L5`6RtelNjCpWycreDt&Od+h0F<@X35{jB^R;i8|F-y?kV?edec zLTL*T|6`WE@GTAcg5Nz;eB~?eY2xpbdxjsqQh)LG@USz}i(B)DJ2QQAYkqf%Jsx88 zyVLA;h|#xBv2XPBC(ix9$kD(DSVmR<4>_^-vPu8QtpET4g=s@WP)S2WAaHVTW@&6? z004NLeUUv#!$2IxUsI)0S{*F-fkTGsWIiY`*(|B^zB7!Qv7@$TN^?j0c1%S<&p#sF2bjC3L{W^*fI z;1xl1qYq&WNX*n{Q>i38$Jaf4e7%eDEbnuFjF%XP9nS#OuUUo0iUbpE$xw zl0tk=JZjJdi66NxyZpwv=&-;uBSt1YM;sv*i)}2oF)JA=@g#9nQ8mgJvMwu}w>Yci zDr?@8zc7^7mY29ra|j76U=b;ZkWs}3%CHclRU^ejn)c%!{z1o|B9~0A4KQ-dqXHF@ z;|KqP-`$#piE%e66bCwAZ2Myv2@ApqkCqV!s6DuPlGk$N9?CIg4fdwrD zF-`dY?>BZ0e}BIIi8GpCqigv4^ZEBT`|&3Y6b=8r-GanC^*s#$Sz#~>;{u0_00000 LNkvXXu0mjfC5$>B literal 0 HcmV?d00001 diff --git a/mods/ITEMS/mcl_bows/textures/mcl_bows_rocket.png b/mods/ITEMS/mcl_bows/textures/mcl_bows_rocket.png new file mode 100644 index 0000000000000000000000000000000000000000..800185ce08db4e4327442dcee0a0393223ad1bc5 GIT binary patch literal 2133 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 FV1hj1Dy9Gc literal 0 HcmV?d00001 diff --git a/mods/ITEMS/mcl_enchanting/enchantments.lua b/mods/ITEMS/mcl_enchanting/enchantments.lua index ecc9fe113..17b6b6ac6 100644 --- a/mods/ITEMS/mcl_enchanting/enchantments.lua +++ b/mods/ITEMS/mcl_enchanting/enchantments.lua @@ -379,8 +379,8 @@ mcl_enchanting.enchantments.mending = { inv_tool_tab = true, } --- requires missing MineClone2 feature ---[[mcl_enchanting.enchantments.multishot = { + +mcl_enchanting.enchantments.multishot = { name = S("Multishot"), max_level = 1, primary = {crossbow = true}, @@ -396,10 +396,10 @@ mcl_enchanting.enchantments.mending = { power_range_table = {{20, 50}}, inv_combat_tab = true, inv_tool_tab = false, -}]]-- +} -- requires missing MineClone2 feature ---[[mcl_enchanting.enchantments.piercing = { +mcl_enchanting.enchantments.piercing = { name = S("Piercing"), max_level = 4, primary = {crossbow = true}, @@ -415,7 +415,7 @@ mcl_enchanting.enchantments.mending = { power_range_table = {{1, 50}, {11, 50}, {21, 50}, {31, 50}}, inv_combat_tab = true, inv_tool_tab = false, -}]]-- +} -- implemented in mcl_bows mcl_enchanting.enchantments.power = { @@ -456,7 +456,7 @@ mcl_enchanting.enchantments.punch = { } -- requires missing MineClone2 feature ---[[mcl_enchanting.enchantments.quick_charge = { +mcl_enchanting.enchantments.quick_charge = { name = S("Quick Charge"), max_level = 3, primary = {crossbow = true}, @@ -472,7 +472,7 @@ mcl_enchanting.enchantments.punch = { power_range_table = {{12, 50}, {32, 50}, {52, 50}}, inv_combat_tab = true, inv_tool_tab = false, -}]]-- +} -- unimplemented --[[mcl_enchanting.enchantments.respiration = { diff --git a/mods/ITEMS/mcl_mobspawners/init.lua b/mods/ITEMS/mcl_mobspawners/init.lua index 6c5d7f6e4..b756d4a6d 100644 --- a/mods/ITEMS/mcl_mobspawners/init.lua +++ b/mods/ITEMS/mcl_mobspawners/init.lua @@ -230,7 +230,7 @@ local function spawn_mobs(pos, elapsed) -- spawn up to 4 mobs in random air blocks if air then - local max = 4 + local max = 200 if spawn_count_overrides[mob] then max = spawn_count_overrides[mob] end @@ -387,4 +387,3 @@ minetest.register_lbm({ respawn_doll(pos) end, }) - diff --git a/mods/ITEMS/mcl_potions/tipped_arrow.lua b/mods/ITEMS/mcl_potions/tipped_arrow.lua index ab55cb72a..1717533a8 100644 --- a/mods/ITEMS/mcl_potions/tipped_arrow.lua +++ b/mods/ITEMS/mcl_potions/tipped_arrow.lua @@ -463,4 +463,4 @@ function mcl_potions.register_arrow(name, desc, color, def) if minetest.get_modpath("doc_identifier") then doc.sub.identifier.register_object("mcl_bows:arrow_entity", "craftitems", "mcl_bows:arrow") end -end \ No newline at end of file +end diff --git a/mods/PLAYER/mcl_player/init.lua b/mods/PLAYER/mcl_player/init.lua index a3c769741..2a4c25c34 100644 --- a/mods/PLAYER/mcl_player/init.lua +++ b/mods/PLAYER/mcl_player/init.lua @@ -9,7 +9,7 @@ local animation_blend = 0 local function get_mouse_button(player) local controls = player:get_player_control() local get_wielded_item_name = player:get_wielded_item():get_name() - if controls.RMB and not string.find(get_wielded_item_name, "mcl_bows:bow") or controls.LMB then + if controls.RMB and not string.find(get_wielded_item_name, "mcl_bows:bow") and not string.find(get_wielded_item_name, "mcl_bows:crossbow") or controls.LMB then return true else return false @@ -212,9 +212,9 @@ minetest.register_globalstep(function(dtime) player_set_animation(player, "swim_walk_mine", animation_speed_mod) elseif not controls.sneak and head_in_water and is_sprinting == true then player_set_animation(player, "swim_walk", animation_speed_mod) - elseif string.find(player:get_wielded_item():get_name(), "mcl_bows:bow") and controls.RMB and controls.sneak then + elseif string.find(player:get_wielded_item():get_name(), "mcl_bows:bow") and controls.RMB and controls.sneak or string.find(player:get_wielded_item():get_name(), "mcl_bows:crossbow_") and controls.sneak then player_set_animation(player, "bow_sneak", animation_speed_mod) - elseif string.find(player:get_wielded_item():get_name(), "mcl_bows:bow") and controls.RMB then + elseif string.find(player:get_wielded_item():get_name(), "mcl_bows:bow") and controls.RMB or string.find(player:get_wielded_item():get_name(), "mcl_bows:crossbow_") then player_set_animation(player, "bow_walk", animation_speed_mod) elseif is_sprinting == true and get_mouse_button(player) == true and not controls.sneak and not head_in_water then player_set_animation(player, "run_walk_mine", animation_speed_mod) diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index 1f881d2b6..f86d5e26a 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -127,6 +127,7 @@ minetest.register_globalstep(function(dtime) for _,player in pairs(get_connected_players()) do --[[ + _ _ _ __ _ _ __ (_)_ __ ___ __ _| |_(_) ___ _ __ ___ / _` | '_ \| | '_ ` _ \ / _` | __| |/ _ \| '_ \/ __| @@ -220,6 +221,10 @@ minetest.register_globalstep(function(dtime) player:set_bone_position("Wield_Item", vector.new(0,3.9,1.3), vector.new(90,0,0)) elseif string.find(wielded:get_name(), "mcl_bows:bow") then player:set_bone_position("Wield_Item", vector.new(.5,4.5,-1.6), vector.new(90,0,20)) + elseif string.find(wielded:get_name(), "mcl_bows:crossbow_loaded") then + player:set_bone_position("Wield_Item", vector.new(-1.5,5.7,1.8), vector.new(64,90,0)) + elseif string.find(wielded:get_name(), "mcl_bows:crossbow") then + player:set_bone_position("Wield_Item", vector.new(-1.5,5.7,1.8), vector.new(90,90,0)) else player:set_bone_position("Wield_Item", vector.new(-1.5,4.9,1.8), vector.new(135,0,90)) end @@ -231,6 +236,14 @@ minetest.register_globalstep(function(dtime) if string.find(wielded:get_name(), "mcl_bows:bow") and control.RMB then player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(pitch+90,-30,pitch * -1 * .35)) player:set_bone_position("Arm_Left_Pitch_Control", vector.new(3.5,5.785,0), vector.new(pitch+90,43,pitch * .35)) + -- controls right and left arms pitch when holing a loaded crossbow + elseif string.find(wielded:get_name(), "mcl_bows:crossbow_loaded") then + player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(pitch+90,-30,pitch * -1 * .35)) + player:set_bone_position("Arm_Left_Pitch_Control", vector.new(3.5,5.785,0), vector.new(pitch+90,43,pitch * .35)) + -- controls right and left arms pitch when loading a crossbow + elseif string.find(wielded:get_name(), "mcl_bows:crossbow_") then + player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(45,-20,25)) + player:set_bone_position("Arm_Left_Pitch_Control", vector.new(3,5.785,0), vector.new(55,20,-45)) -- when punching elseif control.LMB and not parent then player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(pitch,0,0)) From e5c5a785533115a82cea5414f61e6844ed47b27d Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sun, 24 Oct 2021 20:13:34 +0200 Subject: [PATCH 149/296] Update contribution guidelines --- CODE_OF_CONDUCT.md | 128 +++++++++++++++++++++++++++++++ CONTRIBUTING.md | 186 ++++++++++++++++++++++++++------------------- 2 files changed, 236 insertions(+), 78 deletions(-) create mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..8086a2f44 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +eliasfleckenstein@web.de. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1b5098a4f..84ac10f20 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,101 +1,127 @@ -# Contributing to MineClone 2 -So you want to contribute to MineClone 2? +# Contributing to MineClone2 +So you want to contribute to MineClone2? Wow, thank you! :-) But first, some things to note: -MineClone 2's development target is to make a free software clone of Minecraft, -***version 1.12***, ***PC edition***, *** + Optifine features supported by the Minetest Engine ***. +MineClone2's development target is to make a free software clone of Minecraft, +***version 1.17***, ***Java Edition***, *** + Optifine features supported by the Minetest Engine***. The priority is making polished features up to version 1.12. -MineClone 2 is maintained by three persons. Namely, kay27, EliasFleckenstein and jordan4ibanez. You can find us -in the Minetest forums (forums.minetest.net), in IRC in the #mineclone2 -channel on irc.freenode.net. And finally, you can send e-mails to - or . +MineClone2 is maintained by Nicu and Fleckenstein. If you have any +problems or questions, contact us (See Links section below). -By sending us patches or asking us to include your changes in this game, -you agree that they fall under the terms of the LGPLv2.1, which basically -means they will become part of a free software. +You can help with MineClone2's development in many different ways, +whether you're a programmer or not. -## The suggested workflow -We don't **dictate** your workflow, but in order to work with us in an efficient -way, you can follow these suggestions: +## Links +* [Mesehub](https://git.minetest.land/MineClone2/MineClone2) +* [Discord](https://discord.gg/xE4z8EEpDC) +* [YouTube](https://www.youtube.com/channel/UClI_YcsXMF3KNeJtoBfnk9A) +* [IRC](https://web.libera.chat/#mineclone2) +* [Matrix](https://app.element.io/#/room/#mc2:matrix.org) +* [Reddit](https://www.reddit.com/r/MineClone2/) +* [Minetest forums](https://forum.minetest.net/viewtopic.php?f=50&t=16407) -For small and medium changes: +## Using git +MineClone2 is developed using the version control system [git](https://git-scm.com/). If you want to +contribute code to the project, it is **highly recommended** that you learn the git basics. +However, if you're not a programmer or don't plan to help with the coding part of the development, +it's still useful if you know it - in case you want to contribute files that are not related to code, +or to easily keep your game updated and test out pull requests. However, it's not required in this +case. -* Fork the repository +## How you can help as a non-programmer + +As someone who does not know how to write programs in Lua or does not +know how to use the Minetest API, you can still help us out a lot. +For example, by opening an issue in the [Issue tracker](https://git.minetest.land/MineClone2/MineClone2/issues), you can +report a bug or request a feature. + +### Rules about both bugs and feature requests +* Stay polite towards the developers and anyone else involved in the discussion. +* Choose a descriptive title. +* Try to use proper english and please start the title with a capital letter. +* Always check the currently opened issues before creating a new one. Don't report bugs that have already been reported or request features that already have been requested. +* If you know about Minetest's inner workings, please think about whether the bug / the feature that you are reporting / requesting is actually an issue with Minetest itself, and if it is, head to the [Minetest issue tracker](https://github.com/minetest/minetest/issues) instead. +* If you need any help regarding creating a Mesehub account or opening an issue, feel free to ask on the Discord / Matrix server or the IRC channel. + +### Reporting bugs +* A bug is an unintended behavior or, in the worst case, a crash. However, it is not a bug if you believe something is missing in the game. In this case, please read "Requesting features" +* If you report a crash, always include the error message. If you play in singleplayer, post a screenshot of the message that minetest showed when the crash happened (or copy the message into your issue). If you are a server admin, you can find error messages in the log file of the server. +* Tell us which MineClone2 and minetest versions you are using. +* It's always useful to tell us what you were doing to trigger the bug, e.g. before the crash happened or what causes the faulty behavior + +### Requesting features +* Make sure the feature you request is Minecraft 1.17 Java Edition or Optifine behavior. +* Don't beg for something to be implemented. We are not going to rethink our development roadmap because someone sais "Pls pls make this I'm waiting for this so bad!!!11!". +* Check whether the feature has been implemented in a newer version of MineClone2, in case you are not using the latest one. + +### Testing code +If you want to help us with speeding up MineClone2 development and making the game more stable, a great way to do that is by testing out new features from contributors. +For most new things that get into the game, a pull request is created. A pull request is essentially a programmer saying "Look, I modified the game, please apply my changes to the upstream version of the game". +However, every programmer makes mistakes sometimes, some of which are hard to spot. You can help by downloading this modified version of the game and trying it out - then you tell us whether the code works and does what it claims to do or whether you have encountered any issues. +You can find currently open pull requests here: . Note that pull requests that start with a `WIP:` are not done yet, and therefore might not work, so it's not very useful to try them out yet. + +### Profiling +If you own a server, a great way to help us improve MineClone2's code is by giving us profiler results. Profiler results give us detailed information about the game's performance and let us know where the real troublespots are. This way we can make the game faster. +Minetest has a built in profiler. Simply set `profiler.load = true` in your configuration file and restart the server. After running the server for some time, just run `/profiler save` in chat - then you will find a file in the world directory containing the results. Open a new issue and upload the file. You can name the issue " profiler results". + +### Let us know your opinion +It is always encouraged to actively contribute to issue discussions, let us know what you think about a topic and help us make decisions. + +### Crediting +If you opened or have contributed to an issue, you receive the `Community` role on our Discord (after asking for it). + +## How you can help as a programmer +(Almost) all the MineClone2 development is done using pull requests. If you feel like a problem needs to fixed or you want to make a new feature, you could start writing the code right away and notifying us when you're, but it it never hurts to discuss things first. If there is no issue on the topic, open one. If there is an issue, tell us that you'd like to take care of it, to avoid duplicate work. Note that we appreciate any effort, so even if you are a relatively new programmer, you can already contribute to the project - if you have problems or questions regarding git, Lua, or the Minetest API - or the MineClone2 codebase, feel free to ask them on our Discord. +By asking us to include your changes in this game, you agree that they fall under the terms of the GPLv3, which basically means they will become part of a free software. +If your code leads to bugs or crashes after being merged, it is your responsibility to fix them as soon as possible. + +### The recommended workflow +* Fork the repository (in case you have not already) * Do your change in a new branch * Create a pull request to get your changes merged into master +* Keep your pull request up to date by regulary merging upstream +* After the pull request got merged, you can delete the branch -For small changes, sending us a patch is also good. +### Git Guidelines +* We use merge rather than rebase or squash merge +* We don't use git submodules. +* Your commit names should be relatively descriptive, e.g. when saying "Fix #issueid", the commit message should also contain the title of the issue. -For big changes: Same as above, but consider notifying us first to avoid -duplicate work and possible tears of rejection. ;-) +### Code Guidelines +* Each mod must provide `mod.conf`. +* Each mod which add API functions should store functions inside a global table named like the mod. +* Public functions should not use self references but rather just access the table directly. +* Use modern Minetest API +* Use spaces instead of tabs +* Even if it improves performance, it is discouraged to localize variables at the beggining of files, since if another mod overrides some of the functions / variables you localized, you will still have a reference to the old function. -For trusted people, we might give them direct commit access to this -repository. In this case, you obviously don't need to fork, but you still -need to show your contributions align with the project goals. We still -reserve the right to revert everything that we don't like. -For bigger changes, we strongly recommend to use feature branches and -discuss with me first. +### Changes to Gameplay +Pull Requests that change gameplay have to be properly researched and need to state their sources. These PRs also need Fleckenstein's approval before they are merged. +You can use these sources: -If your code causes bugs and crashes, it is your responsibility to fix them as soon as possible. +* Minecraft code (Name the source file and line, however DONT post any proprietary code). You can use MCP to decompile Minecraft. +* Testing things inside of Minecraft (Attach screenshots / video footage of the results) +* Official Minecraft Wiki (Include a link to the page) -We mostly use plain merging rather than rebasing or squash merging. +### Developer status +Active and trusted contributors are often granted write access to the MineClone2 repository. However you should not push things directly to MineClone2 master - rather, do your work on a branch on your private repo, then create a pull request. This way other people can review your changes and make sure they work before they get merged. You are allowed to merge PRs if they have recieved the necessary feedback. +You may also be assigned to issues or pull requests as a developer. In this case it is your responsibility to fix the issue / review and merge the pull request when it is ready. You can also unassign yourself from the issue / PR if you have no time or don't want to take care of it for some other reason (after all, everyone is a volunteer and we can't expect you to do work that you are not intrested in) - the important thing is really that you make sure to inform us if you won't take care of something that has been assigned to you. +Also, please assign yourself to something that you want to work on to avoid duplicate work. +As a developer, it should be easy to reach you about your code. You should be on the Discord (or, if you really don't like Discord, Matrix or IRC). -Your commit names should be relatively descriptive, e.g. when saying "Fix #issueid", the commit message should also contain the title of the issue. +### Maintainer status +Maintainers are responsible for making sure issues are addressed and pull requests are reviewed and merged, by assigning either themselves or Developers to issues / PRs. +Maintainers are responsible for making releases, making sure guidelines are kept and making project decisions based on what the community wants. +Maintainers grant/revoke developer access. -Contributors will be credited in `CREDITS.md`. +Currently there are two maintainers with different responsibility fields: -## Code Style +* Fleckenstein - responsible for gameplay review, technical guidelines and issue/PR delegation +* Nicu - responsible for community related issues -Each mod must provide `mod.conf`. -Each mod which add API functions should store functions inside a global table named like the mod. -Public functions should not use self references but rather just access the table directly. -Functions should be defined in this way: -``` -function mcl_xyz.stuff(param) end -``` -Insteed of this way: -``` -mcl_xyz.stuff = function(param) end -``` -Indentation must be unified, more likely with tabs. - -Time sensitive mods should make a local copy of most used API functions to improve performances. -``` -local vector = vector -local get_node = minetest.get_node -``` - - -## Features > 1.12 - -If you want to make a feature that was added in a Minecraft version later than 1.12, you should fork MineClone5 (mineclone5 branch in the repository) and add your changes to this. - -## What we accept - -* Every MC features up to version 1.12 JE. -* Every already finished and working good features from versions above (only when making a MineClone5 PR / Contribution). -* Except features which couldn't be done easily and bugfree because of Minetest engine limitations. Eg. we CAN extend world boundaries by playing with map chunks, just teleporting player onto next layer after 31000 , but it would cost too much (time, code, bugs, performance, stability, etc). -* Some features, approved by the rest of the community, I mean maybe some voting and really missing any negative feedback. - -## What we reject - -* Any features which cause critical bugs, sending them to rework/fix or trying to fix immediately. -* Some small portions of big entirely missing features which just definitely break gamplay balance give nothing useful -* Controversial features, which some people support while others do not should be discussed well, with publishing forum announcements, at least during the week. In case if there are still doubts - send them into the mod. - -## Reporting bugs -Report all bugs and missing Minecraft features here: - - - -## Direct discussion -We have an IRC channel! Join us on #mineclone2 in freenode.net. - - - -## Creating releases +#### Creating releases * Launch MineClone2 to make sure it still runs * Update the version number in README.md * Use `git tag ` to tag the latest commit with the version number @@ -103,3 +129,7 @@ We have an IRC channel! Join us on #mineclone2 in freenode.net. * Update ContentDB (https://content.minetest.net/packages/Wuzzy/mineclone2/) * Update first post in forum thread (https://forum.minetest.net/viewtopic.php?f=50&t=16407) * Post release announcement and changelog in forums + +## Crediting +Contributors, Developers and Maintainers will be credited in `CREDITS.md`. If you make your first time contribution, please add yourself to this file. +There are also Discord roles for Contributors, Developers and Maintainers. From 5c55ddff1e77db995979c6e64457190455fa07f5 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sun, 24 Oct 2021 20:21:54 +0200 Subject: [PATCH 150/296] Delete merge artifact --- CONTRIBUTING.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 67554d9fa..84ac10f20 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -81,7 +81,6 @@ If your code leads to bugs or crashes after being merged, it is your responsibil * Fork the repository (in case you have not already) * Do your change in a new branch * Create a pull request to get your changes merged into master -<<<<<<< HEAD * Keep your pull request up to date by regulary merging upstream * After the pull request got merged, you can delete the branch From 832e634e3bae8e37657a5e8eb23950d6c37c0509 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sun, 24 Oct 2021 20:44:37 +0200 Subject: [PATCH 151/296] Use tabs instead of spaces, spaces are braindead --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 84ac10f20..b47ab9aa0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -94,7 +94,7 @@ If your code leads to bugs or crashes after being merged, it is your responsibil * Each mod which add API functions should store functions inside a global table named like the mod. * Public functions should not use self references but rather just access the table directly. * Use modern Minetest API -* Use spaces instead of tabs +* Use tabs instead of spaces * Even if it improves performance, it is discouraged to localize variables at the beggining of files, since if another mod overrides some of the functions / variables you localized, you will still have a reference to the old function. ### Changes to Gameplay From dafe860e56ac7ce866affe414fe7eef20b5fd3db Mon Sep 17 00:00:00 2001 From: NO11 Date: Sun, 24 Oct 2021 19:31:51 +0000 Subject: [PATCH 152/296] simple totem particles --- mods/ITEMS/mcl_totems/init.lua | 77 +++++++++------------------------- 1 file changed, 20 insertions(+), 57 deletions(-) diff --git a/mods/ITEMS/mcl_totems/init.lua b/mods/ITEMS/mcl_totems/init.lua index 2206fcb2a..79b2c8de0 100644 --- a/mods/ITEMS/mcl_totems/init.lua +++ b/mods/ITEMS/mcl_totems/init.lua @@ -4,49 +4,7 @@ minetest.register_on_leaveplayer(function(player) hud_totem[player] = nil end) --- Totem particle registration - -function rgb_to_hex(r, g, b) - return string.format("%02x%02x%02x", r, g, b) -end - -minetest.register_entity("mcl_totems:totem_particle", { - physical = true, - collide_with_objects = false, - collisionbox = { -0.02, -0.02, -0.02, 0.02, 0.02, 0.02 }, - pointable = false, - visual = "sprite", - visual_size = { x = 0.2, y = 0.2 }, - spritediv = { x = 1, y = 1 }, - initial_sprite_basepos = { x = 0, y = 0 }, - static_save = false, - glow = 14, - on_activate = function(self, staticdata) - local color - if math.random(0, 3) == 0 then - color = rgb_to_hex( 153 + math.random() * 51, 153 + math.random() * 76.5, math.random() * 51) - else - color = rgb_to_hex(25.5 + math.random() * 102, 153 + math.random() * 76.5, math.random() * 51) - end - self.object:set_properties({ - textures = { "mcl_particles_totem"..math.random(1, 4)..".png^[colorize:#"..color } - }) - local t = math.random(1, 2)*math.random() - minetest.after(t, function() - self.object:set_velocity({ x = math.random(-4, 4) * math.random(), y = math.random(-1, 4) * math.random(), z = math.random(-4, 4) * math.random() }) - end) - minetest.after(0.3 + t, function() - self.object:set_acceleration({ x = 0, y = -4, z = 0 }) - self.object:set_velocity({ x = 0, y = 0, z = 0 }) - end) - end, - on_step = function(self, dtime) - local r = math.random(1, 50) - if r == 1 then - self.object:remove() - end - end -}) +local particle_colors = {"98BF22", "C49E09", "337D0B", "B0B021", "1E9200"} -- TODO: real MC colors -- Save the player from death when holding totem of undying in hand mcl_damage.register_modifier(function(obj, damage, reason) @@ -74,27 +32,32 @@ mcl_damage.register_modifier(function(obj, damage, reason) end -- Effects - minetest.sound_play({ name = "mcl_totems_totem", gain = 1 }, { pos = ppos, max_hear_distance = 16 }, true) - - --Particles + minetest.sound_play({name = "mcl_totems_totem", gain = 1}, {pos=ppos, max_hear_distance = 16}, true) - minetest.after(0.1, function() - local new_pos = obj:get_pos() - if not new_pos then return end - local particlepos = { x = new_pos.x, y = new_pos.y + 1, z = new_pos.z } - for i = 1, 150 do - minetest.add_entity(particlepos, "mcl_totems:totem_particle") - end - end) + for i = 1, 100 do + minetest.add_particle({ + pos = vector.offset(ppos, 0, math.random(-10, 10) / 10, 0), + velocity = vector.new(math.random(-15, 15) / 10, math.random(0, 15) / 10, math.random(-15, 15) / 10), + acceleration = vector.new(0, -math.random(1, 10) / 10, 0), + expirationtime = math.random(1, 3), + size = math.random(1, 2), + collisiondetection = true, + collision_removal = true, + object_collision = false, + texture = "mcl_particles_totem" .. math.random(1, 4) .. ".png^[colorize:#" .. particle_colors[math.random(#particle_colors)], + glow = 10, + }) + + end -- Big totem overlay if not hud_totem[obj] then hud_totem[obj] = obj:hud_add({ hud_elem_type = "image", text = "mcl_totems_totem.png", - position = { x = 0.5, y = 1 }, - scale = { x = 17, y = 17 }, - offset = { x = 0, y = -178 }, + position = {x = 0.5, y = 1}, + scale = {x = 17, y = 17}, + offset = {x = 0, y = -178}, z_index = 100, }) minetest.after(3, function() From 6e94550a12ad7685a18e09fc5235238ac0a06770 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 25 Oct 2021 08:44:12 +0000 Subject: [PATCH 153/296] Clarification about tab indent Signed-off-by: Elias Fleckenstein --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b47ab9aa0..1765a8799 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -94,7 +94,7 @@ If your code leads to bugs or crashes after being merged, it is your responsibil * Each mod which add API functions should store functions inside a global table named like the mod. * Public functions should not use self references but rather just access the table directly. * Use modern Minetest API -* Use tabs instead of spaces +* Use tabs for indentation (rather than spaces) * Even if it improves performance, it is discouraged to localize variables at the beggining of files, since if another mod overrides some of the functions / variables you localized, you will still have a reference to the old function. ### Changes to Gameplay From f3693138c85a3f91a79a5f26ab10bcc914e02062 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 25 Oct 2021 08:46:33 +0000 Subject: [PATCH 154/296] Use proper English Signed-off-by: Elias Fleckenstein --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1765a8799..ebea65736 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,7 +5,7 @@ Wow, thank you! :-) But first, some things to note: MineClone2's development target is to make a free software clone of Minecraft, -***version 1.17***, ***Java Edition***, *** + Optifine features supported by the Minetest Engine***. The priority is making polished features up to version 1.12. +***version 1.17***, ***Java Edition***, *** + Optifine features supported by the Minetest Engine ***. The priority is making polished features up to version 1.12. MineClone2 is maintained by Nicu and Fleckenstein. If you have any problems or questions, contact us (See Links section below). @@ -40,7 +40,7 @@ report a bug or request a feature. ### Rules about both bugs and feature requests * Stay polite towards the developers and anyone else involved in the discussion. * Choose a descriptive title. -* Try to use proper english and please start the title with a capital letter. +* Try to use proper English and please start the title with a capital letter. * Always check the currently opened issues before creating a new one. Don't report bugs that have already been reported or request features that already have been requested. * If you know about Minetest's inner workings, please think about whether the bug / the feature that you are reporting / requesting is actually an issue with Minetest itself, and if it is, head to the [Minetest issue tracker](https://github.com/minetest/minetest/issues) instead. * If you need any help regarding creating a Mesehub account or opening an issue, feel free to ask on the Discord / Matrix server or the IRC channel. From b18e077ba3d99c0f2a3660a8b7a9bc5f973b98f4 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 25 Oct 2021 08:47:56 +0000 Subject: [PATCH 155/296] Markdown fix to development target info Signed-off-by: Elias Fleckenstein --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ebea65736..4f3bc9c39 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,7 +5,7 @@ Wow, thank you! :-) But first, some things to note: MineClone2's development target is to make a free software clone of Minecraft, -***version 1.17***, ***Java Edition***, *** + Optifine features supported by the Minetest Engine ***. The priority is making polished features up to version 1.12. +***version 1.17***, ***Java Edition***, ***+ Optifine features supported by the Minetest Engine***. The priority is making polished features up to version 1.12. MineClone2 is maintained by Nicu and Fleckenstein. If you have any problems or questions, contact us (See Links section below). From b9999195ec99104aaa5ff6584600893c2bb739c8 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 25 Oct 2021 16:52:56 +0200 Subject: [PATCH 156/296] Add publishing releases to my responsibility field --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b47ab9aa0..e9a14a54f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -118,7 +118,7 @@ Maintainers grant/revoke developer access. Currently there are two maintainers with different responsibility fields: -* Fleckenstein - responsible for gameplay review, technical guidelines and issue/PR delegation +* Fleckenstein - responsible for gameplay review, publishing releases, technical guidelines and issue/PR delegation * Nicu - responsible for community related issues #### Creating releases From 664244d25c5212bd672b3e42db70489a46771162 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 25 Oct 2021 17:20:58 +0200 Subject: [PATCH 157/296] Make sure PRs are tested at least twice before being merged --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e9a14a54f..eaced68fa 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -106,7 +106,7 @@ You can use these sources: * Official Minecraft Wiki (Include a link to the page) ### Developer status -Active and trusted contributors are often granted write access to the MineClone2 repository. However you should not push things directly to MineClone2 master - rather, do your work on a branch on your private repo, then create a pull request. This way other people can review your changes and make sure they work before they get merged. You are allowed to merge PRs if they have recieved the necessary feedback. +Active and trusted contributors are often granted write access to the MineClone2 repository. However you should not push things directly to MineClone2 master - rather, do your work on a branch on your private repo, then create a pull request. This way other people can review your changes and make sure they work before they get merged. You are allowed to merge PRs if they have recieved the necessary feedback and have been tested to not lead to any crashes and do what they claim to do by at least two different people. You may also be assigned to issues or pull requests as a developer. In this case it is your responsibility to fix the issue / review and merge the pull request when it is ready. You can also unassign yourself from the issue / PR if you have no time or don't want to take care of it for some other reason (after all, everyone is a volunteer and we can't expect you to do work that you are not intrested in) - the important thing is really that you make sure to inform us if you won't take care of something that has been assigned to you. Also, please assign yourself to something that you want to work on to avoid duplicate work. As a developer, it should be easy to reach you about your code. You should be on the Discord (or, if you really don't like Discord, Matrix or IRC). From 4b1606eaee2d5da2c36e1892efae3bae37d3b13e Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 25 Oct 2021 18:26:31 +0200 Subject: [PATCH 158/296] Update 'git for non-programmers' section --- CONTRIBUTING.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 79d08e22a..93b52c32b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -25,10 +25,10 @@ whether you're a programmer or not. ## Using git MineClone2 is developed using the version control system [git](https://git-scm.com/). If you want to contribute code to the project, it is **highly recommended** that you learn the git basics. -However, if you're not a programmer or don't plan to help with the coding part of the development, -it's still useful if you know it - in case you want to contribute files that are not related to code, -or to easily keep your game updated and test out pull requests. However, it's not required in this -case. +For non-programmers and people who do not plan to contribute code to Mineclone2, git is not required. +However, git is a tool that will be referenced frequently because of its usefulness. +As such, it is valuable in learning how git works and its terminology. It can also help you in +keeping your game updated, and easily testing pull requests. ## How you can help as a non-programmer From 27f35fe422c560bad9109e09460ff36a9f1f024a Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 25 Oct 2021 18:48:11 +0200 Subject: [PATCH 159/296] Add info about discord server in 'Let us know your opinion' section --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 93b52c32b..1e1b20778 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -67,7 +67,7 @@ If you own a server, a great way to help us improve MineClone2's code is by givi Minetest has a built in profiler. Simply set `profiler.load = true` in your configuration file and restart the server. After running the server for some time, just run `/profiler save` in chat - then you will find a file in the world directory containing the results. Open a new issue and upload the file. You can name the issue " profiler results". ### Let us know your opinion -It is always encouraged to actively contribute to issue discussions, let us know what you think about a topic and help us make decisions. +It is always encouraged to actively contribute to issue discussions on MeseHub, let us know what you think about a topic and help us make decisions. Also, note that a lot of discussion takes place on the Discord server, so it's definitely worth checking it out. ### Crediting If you opened or have contributed to an issue, you receive the `Community` role on our Discord (after asking for it). From d2242363889327ecc44ef1c1924f3f16160e2604 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 25 Oct 2021 18:58:30 +0200 Subject: [PATCH 160/296] Consistency about line length (not a convention, just something applied to this file) --- CONTRIBUTING.md | 201 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 147 insertions(+), 54 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1e1b20778..7e914ac17 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,8 +4,10 @@ Wow, thank you! :-) But first, some things to note: -MineClone2's development target is to make a free software clone of Minecraft, -***version 1.17***, ***Java Edition***, ***+ Optifine features supported by the Minetest Engine***. The priority is making polished features up to version 1.12. +MineClone2's development target is to make a free software clone of +Minecraft, ***version 1.17***, ***Java Edition***, ***+ Optifine +features supported by the Minetest Engine***. The priority is making +polished features up to version 1.12. MineClone2 is maintained by Nicu and Fleckenstein. If you have any problems or questions, contact us (See Links section below). @@ -23,59 +25,116 @@ whether you're a programmer or not. * [Minetest forums](https://forum.minetest.net/viewtopic.php?f=50&t=16407) ## Using git -MineClone2 is developed using the version control system [git](https://git-scm.com/). If you want to -contribute code to the project, it is **highly recommended** that you learn the git basics. -For non-programmers and people who do not plan to contribute code to Mineclone2, git is not required. -However, git is a tool that will be referenced frequently because of its usefulness. -As such, it is valuable in learning how git works and its terminology. It can also help you in +MineClone2 is developed using the version control system +[git](https://git-scm.com/). If you want to contribute code to the +project, it is **highly recommended** that you learn the git basics. +For non-programmers and people who do not plan to contribute code to +Mineclone2, git is not required. However, git is a tool that will be +referenced frequently because of its usefulness. As such, it is valuable +in learning how git works and its terminology. It can also help you in keeping your game updated, and easily testing pull requests. ## How you can help as a non-programmer As someone who does not know how to write programs in Lua or does not -know how to use the Minetest API, you can still help us out a lot. -For example, by opening an issue in the [Issue tracker](https://git.minetest.land/MineClone2/MineClone2/issues), you can -report a bug or request a feature. +know how to use the Minetest API, you can still help us out a lot. For +example, by opening an issue in the +[Issue tracker](https://git.minetest.land/MineClone2/MineClone2/issues), +you can report a bug or request a feature. ### Rules about both bugs and feature requests -* Stay polite towards the developers and anyone else involved in the discussion. +* Stay polite towards the developers and anyone else involved in the +discussion. * Choose a descriptive title. -* Try to use proper English and please start the title with a capital letter. -* Always check the currently opened issues before creating a new one. Don't report bugs that have already been reported or request features that already have been requested. -* If you know about Minetest's inner workings, please think about whether the bug / the feature that you are reporting / requesting is actually an issue with Minetest itself, and if it is, head to the [Minetest issue tracker](https://github.com/minetest/minetest/issues) instead. -* If you need any help regarding creating a Mesehub account or opening an issue, feel free to ask on the Discord / Matrix server or the IRC channel. +* Try to use proper English and please start the title with a capital +letter. +* Always check the currently opened issues before creating a new one. +Don't report bugs that have already been reported or request features +that already have been requested. +* If you know about Minetest's inner workings, please think about +whether the bug / the feature that you are reporting / requesting is +actually an issue with Minetest itself, and if it is, head to the +[Minetest issue tracker](https://github.com/minetest/minetest/issues) +instead. +* If you need any help regarding creating a Mesehub account or opening +an issue, feel free to ask on the Discord / Matrix server or the IRC +channel. ### Reporting bugs -* A bug is an unintended behavior or, in the worst case, a crash. However, it is not a bug if you believe something is missing in the game. In this case, please read "Requesting features" -* If you report a crash, always include the error message. If you play in singleplayer, post a screenshot of the message that minetest showed when the crash happened (or copy the message into your issue). If you are a server admin, you can find error messages in the log file of the server. +* A bug is an unintended behavior or, in the worst case, a crash. +However, it is not a bug if you believe something is missing in the +game. In this case, please read "Requesting features" +* If you report a crash, always include the error message. If you play +in singleplayer, post a screenshot of the message that minetest showed +when the crash happened (or copy the message into your issue). If you +are a server admin, you can find error messages in the log file of the +server. * Tell us which MineClone2 and minetest versions you are using. -* It's always useful to tell us what you were doing to trigger the bug, e.g. before the crash happened or what causes the faulty behavior +* It's always useful to tell us what you were doing to trigger the bug, +e.g. before the crash happened or what causes the faulty behavior ### Requesting features -* Make sure the feature you request is Minecraft 1.17 Java Edition or Optifine behavior. -* Don't beg for something to be implemented. We are not going to rethink our development roadmap because someone sais "Pls pls make this I'm waiting for this so bad!!!11!". -* Check whether the feature has been implemented in a newer version of MineClone2, in case you are not using the latest one. +* Make sure the feature you request is Minecraft 1.17 Java Edition or +Optifine behavior. +* Don't beg for something to be implemented. We are not going to rethink +our development roadmap because someone sais "Pls pls make this I'm +waiting for this so bad!!!11!". +* Check whether the feature has been implemented in a newer version of +MineClone2, in case you are not using the latest one. ### Testing code -If you want to help us with speeding up MineClone2 development and making the game more stable, a great way to do that is by testing out new features from contributors. -For most new things that get into the game, a pull request is created. A pull request is essentially a programmer saying "Look, I modified the game, please apply my changes to the upstream version of the game". -However, every programmer makes mistakes sometimes, some of which are hard to spot. You can help by downloading this modified version of the game and trying it out - then you tell us whether the code works and does what it claims to do or whether you have encountered any issues. -You can find currently open pull requests here: . Note that pull requests that start with a `WIP:` are not done yet, and therefore might not work, so it's not very useful to try them out yet. +If you want to help us with speeding up MineClone2 development and +making the game more stable, a great way to do that is by testing out +new features from contributors. For most new things that get into the +game, a pull request is created. A pull request is essentially a +programmer saying "Look, I modified the game, please apply my changes +to the upstream version of the game". However, every programmer makes +mistakes sometimes, some of which are hard to spot. You can help by +downloading this modified version of the game and trying it out - then +you tell us whether the code works and does what it claims to do or +whether you have encountered any issues. You can find currently open +pull requests here: +. Note that pull +requests that start with a `WIP:` are not done yet, and therefore might +not work, so it's not very useful to try them out yet. ### Profiling -If you own a server, a great way to help us improve MineClone2's code is by giving us profiler results. Profiler results give us detailed information about the game's performance and let us know where the real troublespots are. This way we can make the game faster. -Minetest has a built in profiler. Simply set `profiler.load = true` in your configuration file and restart the server. After running the server for some time, just run `/profiler save` in chat - then you will find a file in the world directory containing the results. Open a new issue and upload the file. You can name the issue " profiler results". +If you own a server, a great way to help us improve MineClone2's code +is by giving us profiler results. Profiler results give us detailed +information about the game's performance and let us know where the real +troublespots are. This way we can make the game faster. Minetest has a +built in profiler. Simply set `profiler.load = true` in your +configuration file and restart the server. After running the server for +some time, just run `/profiler save` in chat - then you will find a file +in the world directory containing the results. Open a new issue and +upload the file. You can name the issue " profiler +results". ### Let us know your opinion -It is always encouraged to actively contribute to issue discussions on MeseHub, let us know what you think about a topic and help us make decisions. Also, note that a lot of discussion takes place on the Discord server, so it's definitely worth checking it out. +It is always encouraged to actively contribute to issue discussions on +MeseHub, let us know what you think about a topic and help us make +decisions. Also, note that a lot of discussion takes place on the +Discord server, so it's definitely worth checking it out. ### Crediting -If you opened or have contributed to an issue, you receive the `Community` role on our Discord (after asking for it). +If you opened or have contributed to an issue, you receive the +`Community` role on our Discord (after asking for it). ## How you can help as a programmer -(Almost) all the MineClone2 development is done using pull requests. If you feel like a problem needs to fixed or you want to make a new feature, you could start writing the code right away and notifying us when you're, but it it never hurts to discuss things first. If there is no issue on the topic, open one. If there is an issue, tell us that you'd like to take care of it, to avoid duplicate work. Note that we appreciate any effort, so even if you are a relatively new programmer, you can already contribute to the project - if you have problems or questions regarding git, Lua, or the Minetest API - or the MineClone2 codebase, feel free to ask them on our Discord. -By asking us to include your changes in this game, you agree that they fall under the terms of the GPLv3, which basically means they will become part of a free software. -If your code leads to bugs or crashes after being merged, it is your responsibility to fix them as soon as possible. +(Almost) all the MineClone2 development is done using pull requests. +If you feel like a problem needs to fixed or you want to make a new +feature, you could start writing the code right away and notifying us +when you're, but it it never hurts to discuss things first. If there is +no issue on the topic, open one. If there is an issue, tell us that +you'd like to take care of it, to avoid duplicate work. Note that we +appreciate any effort, so even if you are a relatively new programmer, +you can already contribute to the project - if you have problems or +questions regarding git, Lua, or the Minetest API - or the MineClone2 +codebase, feel free to ask them on our Discord. By asking us to include +your changes in this game, you agree that they fall under the terms of +the GPLv3, which basically means they will become part of a free +software. If your code leads to bugs or crashes after being merged, it +is your responsibility to fix them as soon as possible. ### The recommended workflow * Fork the repository (in case you have not already) @@ -87,49 +146,83 @@ If your code leads to bugs or crashes after being merged, it is your responsibil ### Git Guidelines * We use merge rather than rebase or squash merge * We don't use git submodules. -* Your commit names should be relatively descriptive, e.g. when saying "Fix #issueid", the commit message should also contain the title of the issue. +* Your commit names should be relatively descriptive, e.g. when saying +"Fix #issueid", the commit message should also contain the title of the +issue. ### Code Guidelines * Each mod must provide `mod.conf`. -* Each mod which add API functions should store functions inside a global table named like the mod. -* Public functions should not use self references but rather just access the table directly. +* Each mod which add API functions should store functions inside a +global table named like the mod. +* Public functions should not use self references but rather just access +the table directly. * Use modern Minetest API * Use tabs for indentation (rather than spaces) -* Even if it improves performance, it is discouraged to localize variables at the beggining of files, since if another mod overrides some of the functions / variables you localized, you will still have a reference to the old function. +* Even if it improves performance, it is discouraged to localize +variables at the beggining of files, since if another mod overrides some +of the functions / variables you localized, you will still have a +reference to the old function. ### Changes to Gameplay -Pull Requests that change gameplay have to be properly researched and need to state their sources. These PRs also need Fleckenstein's approval before they are merged. +Pull Requests that change gameplay have to be properly researched and +need to state their sources. These PRs also need Fleckenstein's approval +before they are merged. You can use these sources: -* Minecraft code (Name the source file and line, however DONT post any proprietary code). You can use MCP to decompile Minecraft. -* Testing things inside of Minecraft (Attach screenshots / video footage of the results) +* Minecraft code (Name the source file and line, however DONT post any +proprietary code). You can use MCP to decompile Minecraft. +* Testing things inside of Minecraft (Attach screenshots / video footage +of the results) * Official Minecraft Wiki (Include a link to the page) ### Developer status -Active and trusted contributors are often granted write access to the MineClone2 repository. However you should not push things directly to MineClone2 master - rather, do your work on a branch on your private repo, then create a pull request. This way other people can review your changes and make sure they work before they get merged. You are allowed to merge PRs if they have recieved the necessary feedback and have been tested to not lead to any crashes and do what they claim to do by at least two different people. -You may also be assigned to issues or pull requests as a developer. In this case it is your responsibility to fix the issue / review and merge the pull request when it is ready. You can also unassign yourself from the issue / PR if you have no time or don't want to take care of it for some other reason (after all, everyone is a volunteer and we can't expect you to do work that you are not intrested in) - the important thing is really that you make sure to inform us if you won't take care of something that has been assigned to you. -Also, please assign yourself to something that you want to work on to avoid duplicate work. -As a developer, it should be easy to reach you about your code. You should be on the Discord (or, if you really don't like Discord, Matrix or IRC). +Active and trusted contributors are often granted write access to the +MineClone2 repository. However you should not push things directly to +MineClone2 master - rather, do your work on a branch on your private +repo, then create a pull request. This way other people can review your +changes and make sure they work before they get merged. You are allowed +to merge PRs if they have recieved the necessary feedback and have been +tested to not lead to any crashes and do what they claim to do by at +least two different people. You may also be assigned to issues or pull +requests as a developer. In this case it is your responsibility to fix +the issue / review and merge the pull request when it is ready. You can +also unassign yourself from the issue / PR if you have no time or don't +want to take care of it for some other reason (after all, everyone is a +volunteer and we can't expect you to do work that you are not intrested +in) - the important thing is really that you make sure to inform us if +you won't take care of something that has been assigned to you. Also, +please assign yourself to something that you want to work on to avoid +duplicate work. As a developer, it should be easy to reach you about +your code. You should be on the Discord (or, if you really don't like +Discord, Matrix or IRC). ### Maintainer status -Maintainers are responsible for making sure issues are addressed and pull requests are reviewed and merged, by assigning either themselves or Developers to issues / PRs. -Maintainers are responsible for making releases, making sure guidelines are kept and making project decisions based on what the community wants. -Maintainers grant/revoke developer access. +Maintainers are responsible for making sure issues are addressed and +pull requests are reviewed and merged, by assigning either themselves or +Developers to issues / PRs. Maintainers are responsible for making +releases, making sure guidelines are kept and making project decisions +based on what the community wants. Maintainers grant/revoke developer +access. Currently there are two maintainers with different +responsibility fields: -Currently there are two maintainers with different responsibility fields: - -* Fleckenstein - responsible for gameplay review, publishing releases, technical guidelines and issue/PR delegation +* Fleckenstein - responsible for gameplay review, publishing releases, +technical guidelines and issue/PR delegation * Nicu - responsible for community related issues #### Creating releases * Launch MineClone2 to make sure it still runs * Update the version number in README.md -* Use `git tag ` to tag the latest commit with the version number +* Use `git tag ` to tag the latest commit with the +version number * Push to repo (don't forget `--tags`!) -* Update ContentDB (https://content.minetest.net/packages/Wuzzy/mineclone2/) -* Update first post in forum thread (https://forum.minetest.net/viewtopic.php?f=50&t=16407) +* Update ContentDB +(https://content.minetest.net/packages/Wuzzy/mineclone2/) +* Update first post in forum thread +(https://forum.minetest.net/viewtopic.php?f=50&t=16407) * Post release announcement and changelog in forums ## Crediting -Contributors, Developers and Maintainers will be credited in `CREDITS.md`. If you make your first time contribution, please add yourself to this file. -There are also Discord roles for Contributors, Developers and Maintainers. +Contributors, Developers and Maintainers will be credited in +`CREDITS.md`. If you make your first time contribution, please add +yourself to this file. There are also Discord roles for Contributors, +Developers and Maintainers. From 74890101520d4b04578dbc333aab38ea6cdf6eca Mon Sep 17 00:00:00 2001 From: NO11 Date: Mon, 25 Oct 2021 17:08:38 +0000 Subject: [PATCH 161/296] Use particlespawners instead of single particles --- mods/ITEMS/mcl_totems/init.lua | 37 +++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/mods/ITEMS/mcl_totems/init.lua b/mods/ITEMS/mcl_totems/init.lua index 79b2c8de0..aa188855f 100644 --- a/mods/ITEMS/mcl_totems/init.lua +++ b/mods/ITEMS/mcl_totems/init.lua @@ -34,20 +34,29 @@ mcl_damage.register_modifier(function(obj, damage, reason) -- Effects minetest.sound_play({name = "mcl_totems_totem", gain = 1}, {pos=ppos, max_hear_distance = 16}, true) - for i = 1, 100 do - minetest.add_particle({ - pos = vector.offset(ppos, 0, math.random(-10, 10) / 10, 0), - velocity = vector.new(math.random(-15, 15) / 10, math.random(0, 15) / 10, math.random(-15, 15) / 10), - acceleration = vector.new(0, -math.random(1, 10) / 10, 0), - expirationtime = math.random(1, 3), - size = math.random(1, 2), - collisiondetection = true, - collision_removal = true, - object_collision = false, - texture = "mcl_particles_totem" .. math.random(1, 4) .. ".png^[colorize:#" .. particle_colors[math.random(#particle_colors)], - glow = 10, - }) - + for i = 1, 4 do + for c = 1, #particle_colors do + minetest.add_particlespawner({ + amount = math.round(100/(4 * #particle_colors)), + time = 1, + minpos = vector.offset(ppos, 0, -1, 0), + maxpos = vector.offset(ppos, 0, 1, 0), + minvel = vector.new(-1.5, 0, -1.5), + maxvel = vector.new(1.5, 1.5, 1.5), + minacc = vector.new(0, -0.1, 0), + maxacc = vector.new(0, -1, 0), + minexptime = 1, + maxexptime = 3, + minsize = 1, + maxsize = 2, + collisiondetection = true, + collision_removal = true, + object_collision = false, + vertical = false, + texture = "mcl_particles_totem" .. i .. ".png^[colorize:#" .. particle_colors[c], + glow = 10, + }) + end end -- Big totem overlay From a6def5e9bb7ddc3e70b13be51e4a53f1f33dcbba Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 25 Oct 2021 19:14:53 +0200 Subject: [PATCH 162/296] Remove guideline about localizing variables --- CONTRIBUTING.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7e914ac17..722deefaf 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -158,10 +158,6 @@ global table named like the mod. the table directly. * Use modern Minetest API * Use tabs for indentation (rather than spaces) -* Even if it improves performance, it is discouraged to localize -variables at the beggining of files, since if another mod overrides some -of the functions / variables you localized, you will still have a -reference to the old function. ### Changes to Gameplay Pull Requests that change gameplay have to be properly researched and From 6580bcab5a80644f940dbaf172b64979bbe5d6d5 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 25 Oct 2021 19:15:26 +0200 Subject: [PATCH 163/296] Add info about Minestorm and add links for MCP and Minestorm --- CONTRIBUTING.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 722deefaf..f9d97c063 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -166,7 +166,10 @@ before they are merged. You can use these sources: * Minecraft code (Name the source file and line, however DONT post any -proprietary code). You can use MCP to decompile Minecraft. +proprietary code). You can use +[MCP](https://minecraft.fandom.com/wiki/Programs_and_editors/Mod_Coder_Pack) +to decompile Minecraft or look at +[Minestorm](https://github.com/Minestom/Minestom) code. * Testing things inside of Minecraft (Attach screenshots / video footage of the results) * Official Minecraft Wiki (Include a link to the page) From 362de4c920453f838349f43261f2cd9f46ba6951 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 25 Oct 2021 19:16:24 +0200 Subject: [PATCH 164/296] Add minecraft wiki link --- CONTRIBUTING.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f9d97c063..3637bdf1c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -172,7 +172,8 @@ to decompile Minecraft or look at [Minestorm](https://github.com/Minestom/Minestom) code. * Testing things inside of Minecraft (Attach screenshots / video footage of the results) -* Official Minecraft Wiki (Include a link to the page) +* [Official Minecraft Wiki](https://minecraft.fandom.com/wiki/Minecraft_Wiki) +(Include a link to the specific page you used) ### Developer status Active and trusted contributors are often granted write access to the From 3a422e3afc91a9dded5f613770b776759a2f8376 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 25 Oct 2021 19:25:48 +0200 Subject: [PATCH 165/296] Reword 'understandable English' rule --- CONTRIBUTING.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3637bdf1c..03a76ce57 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -46,8 +46,9 @@ you can report a bug or request a feature. * Stay polite towards the developers and anyone else involved in the discussion. * Choose a descriptive title. -* Try to use proper English and please start the title with a capital -letter. +* Please write in plain, understandable English. It will be easier to +communicate. +* Please start the issue title with a capital letter. * Always check the currently opened issues before creating a new one. Don't report bugs that have already been reported or request features that already have been requested. From 756d28e2c61300205731e0cd370329e2dbb3a708 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 25 Oct 2021 19:31:07 +0200 Subject: [PATCH 166/296] Use iliekprogrammar's wording in the begging rule --- CONTRIBUTING.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 03a76ce57..df3b5c059 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -77,9 +77,10 @@ e.g. before the crash happened or what causes the faulty behavior ### Requesting features * Make sure the feature you request is Minecraft 1.17 Java Edition or Optifine behavior. -* Don't beg for something to be implemented. We are not going to rethink -our development roadmap because someone sais "Pls pls make this I'm -waiting for this so bad!!!11!". +* Begging or excessive attention seeking does not help us in the +slightest, and may very well disrupt Mineclone2 development. It's better +to put that energy into helping or researching the feature in question. +After all, we're just volunteers working on our spare time. * Check whether the feature has been implemented in a newer version of MineClone2, in case you are not using the latest one. From 7707c3132c4da6c6f5db246d802c589610ab100d Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 25 Oct 2021 19:46:13 +0200 Subject: [PATCH 167/296] Fix duplicate and forgotten word in 'helping as a programmer' section --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index df3b5c059..9b209d912 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -126,8 +126,8 @@ If you opened or have contributed to an issue, you receive the (Almost) all the MineClone2 development is done using pull requests. If you feel like a problem needs to fixed or you want to make a new feature, you could start writing the code right away and notifying us -when you're, but it it never hurts to discuss things first. If there is -no issue on the topic, open one. If there is an issue, tell us that +when you're done, but it never hurts to discuss things first. If there +is no issue on the topic, open one. If there is an issue, tell us that you'd like to take care of it, to avoid duplicate work. Note that we appreciate any effort, so even if you are a relatively new programmer, you can already contribute to the project - if you have problems or From c9987884358cff0548af0d017b5d073274aaa00a Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 25 Oct 2021 19:48:14 +0200 Subject: [PATCH 168/296] Reword 'help for junior devs' section --- CONTRIBUTING.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9b209d912..cd7f9c465 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -128,15 +128,17 @@ If you feel like a problem needs to fixed or you want to make a new feature, you could start writing the code right away and notifying us when you're done, but it never hurts to discuss things first. If there is no issue on the topic, open one. If there is an issue, tell us that -you'd like to take care of it, to avoid duplicate work. Note that we -appreciate any effort, so even if you are a relatively new programmer, -you can already contribute to the project - if you have problems or -questions regarding git, Lua, or the Minetest API - or the MineClone2 -codebase, feel free to ask them on our Discord. By asking us to include -your changes in this game, you agree that they fall under the terms of -the GPLv3, which basically means they will become part of a free -software. If your code leads to bugs or crashes after being merged, it -is your responsibility to fix them as soon as possible. +you'd like to take care of it, to avoid duplicate work. We appreciate +any contributing effort to Mineclone2. If you are a relatively new +programmer, you can reach us on Discord, Matrix or IRC for questions +about git, Lua, Minetest API, Mineclone2 codebase or anything related +to MineClone2. We can help you avoid writing code that would be deemed +inadequeate, or help you become familiar with Mineclone2 better, or even +help using development tools. By asking us to include your changes in +this game, you agree that they fall under the terms of the GPLv3, which +basically means they will become part of a free software. If your code +leads to bugs or crashes after being merged, it is your responsibility +to fix them as soon as possible. ### The recommended workflow * Fork the repository (in case you have not already) From 5edf27ac88cbbbd249e781f0ca623b1f3696733f Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 25 Oct 2021 19:54:10 +0200 Subject: [PATCH 169/296] Reword 'bug responsibility' section --- CONTRIBUTING.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cd7f9c465..66a1a3452 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -136,9 +136,10 @@ to MineClone2. We can help you avoid writing code that would be deemed inadequeate, or help you become familiar with Mineclone2 better, or even help using development tools. By asking us to include your changes in this game, you agree that they fall under the terms of the GPLv3, which -basically means they will become part of a free software. If your code -leads to bugs or crashes after being merged, it is your responsibility -to fix them as soon as possible. +basically means they will become part of a free software. Sometimes, +your code may cause crashes or bugs - we try to avoid such scenarios by +testing everytime before merging it, but if your merged work causes +problems, we ask you fix the issues as soon as possible. ### The recommended workflow * Fork the repository (in case you have not already) From 7f43ba6e36f857374803025664f0855dc7abceac Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 25 Oct 2021 19:56:03 +0200 Subject: [PATCH 170/296] Clarify rule about merging upstream --- CONTRIBUTING.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 66a1a3452..ec0974e63 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -145,7 +145,9 @@ problems, we ask you fix the issues as soon as possible. * Fork the repository (in case you have not already) * Do your change in a new branch * Create a pull request to get your changes merged into master -* Keep your pull request up to date by regulary merging upstream +* Keep your pull request up to date by regulary merging upstream. It is +imperative that conflicts are resolved prior to merging the pull +request. * After the pull request got merged, you can delete the branch ### Git Guidelines From a877c615a5723e3a83bb5b42b90dd9f1938d67be Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 25 Oct 2021 20:01:12 +0200 Subject: [PATCH 171/296] Clarify tabs usage: Use spaces for alignment --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ec0974e63..dfe2d9265 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -164,7 +164,7 @@ global table named like the mod. * Public functions should not use self references but rather just access the table directly. * Use modern Minetest API -* Use tabs for indentation (rather than spaces) +* Tabs should be used for indent, spaces for alignment ### Changes to Gameplay Pull Requests that change gameplay have to be properly researched and From 6e7827902cb9f5951550139cdb7d32c350aa7f1c Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 25 Oct 2021 20:04:08 +0200 Subject: [PATCH 172/296] Use the wording 'reproduce a problem' in the reporting bugs section --- CONTRIBUTING.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index dfe2d9265..3d29321c7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -71,8 +71,9 @@ when the crash happened (or copy the message into your issue). If you are a server admin, you can find error messages in the log file of the server. * Tell us which MineClone2 and minetest versions you are using. -* It's always useful to tell us what you were doing to trigger the bug, -e.g. before the crash happened or what causes the faulty behavior +* Tell us how to reproduce the problem: What you were doing to trigger +the bug, e.g. before the crash happened or what causes the faulty +behavior. ### Requesting features * Make sure the feature you request is Minecraft 1.17 Java Edition or From fba30eccd67e54852d98c320732c8add0a6acb2b Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 25 Oct 2021 20:04:51 +0200 Subject: [PATCH 173/296] Add rule about double quotes for strings --- CONTRIBUTING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3d29321c7..c829fa3f3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -166,6 +166,7 @@ global table named like the mod. the table directly. * Use modern Minetest API * Tabs should be used for indent, spaces for alignment +* Use double quotes for strings ### Changes to Gameplay Pull Requests that change gameplay have to be properly researched and From 47fbb0c176b849a14cc7f62d9a026303f73d5d37 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 25 Oct 2021 20:18:03 +0200 Subject: [PATCH 174/296] Mod naming convention, snake case convention --- CONTRIBUTING.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c829fa3f3..3495d4ad3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -160,6 +160,7 @@ issue. ### Code Guidelines * Each mod must provide `mod.conf`. +* Mod names are snake case, and newly added mods start with `mcl_` * Each mod which add API functions should store functions inside a global table named like the mod. * Public functions should not use self references but rather just access @@ -167,6 +168,7 @@ the table directly. * Use modern Minetest API * Tabs should be used for indent, spaces for alignment * Use double quotes for strings +* Use snake_case rather than CamelCase ### Changes to Gameplay Pull Requests that change gameplay have to be properly researched and From a80438d58e7aec6bfb817578633099226138ffd4 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 25 Oct 2021 20:21:45 +0200 Subject: [PATCH 175/296] Advice about atomic commits --- CONTRIBUTING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3495d4ad3..926fab212 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -157,6 +157,7 @@ request. * Your commit names should be relatively descriptive, e.g. when saying "Fix #issueid", the commit message should also contain the title of the issue. +* Try to keep your commits as atomic as possible ### Code Guidelines * Each mod must provide `mod.conf`. From 64660617964c6a51fa5a7237446e7ebeab8ef8db Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 25 Oct 2021 20:33:45 +0200 Subject: [PATCH 176/296] Add back function declaration guideline, provide examples for code style guidelines --- CONTRIBUTING.md | 79 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 71 insertions(+), 8 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 926fab212..827497799 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -161,15 +161,78 @@ issue. ### Code Guidelines * Each mod must provide `mod.conf`. -* Mod names are snake case, and newly added mods start with `mcl_` -* Each mod which add API functions should store functions inside a -global table named like the mod. +* Mod names are snake case, and newly added mods start with `mcl_`, e.g. +`mcl_core`, `mcl_farming`, `mcl_monster_eggs` +* To export functions, store them inside a global table named like the +mod, e.g. + +```lua +mcl_example = {} + +function mcl_example.do_something() + -- ... +end + +``` + * Public functions should not use self references but rather just access -the table directly. -* Use modern Minetest API -* Tabs should be used for indent, spaces for alignment -* Use double quotes for strings -* Use snake_case rather than CamelCase +the table directly, e.g. + +```lua +-- bad +function mcl_example:do_something() +end + +-- good +function mcl_example.do_something() +end +``` + +* Use modern Minetest API, e.g. no usage of `minetest.env` +* Tabs should be used for indent, spaces for alignment, e.g. + +```lua + +-- use tabs for indent + +for i = 1, 10 do + if i % 3 == 0 then + print(i) + end +end + +-- use tabs for indent and spaces to align things + +some_table = { + {"a string", 5}, + {"a very much longer string", 10}, +} +``` + +* Use double quotes for strings, e.g. `"asdf"` rather than `'asdf'` +* Use snake_case rather than CamelCase, e.g. `my_function` rather than +`MyFunction` +* Dont declare functions as an assignment, e.g. + +```lua +-- bad +local some_local_func = function() + -- ... +end + +my_mod.some_func = function() + -- ... +end + +-- good +local function some_local_func() + -- ... +end + +function my_mod.some_func() + -- ... +end +``` ### Changes to Gameplay Pull Requests that change gameplay have to be properly researched and From da5e703675429381932b8d8fb9c863ccd3d16f96 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 25 Oct 2021 20:36:29 +0200 Subject: [PATCH 177/296] Clarify that 'make atomic commits' is just an advise --- CONTRIBUTING.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 827497799..1f2d1d0de 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -157,7 +157,8 @@ request. * Your commit names should be relatively descriptive, e.g. when saying "Fix #issueid", the commit message should also contain the title of the issue. -* Try to keep your commits as atomic as possible +* Try to keep your commits as atomic as possible (advise, but completely +optional) ### Code Guidelines * Each mod must provide `mod.conf`. From f3d16d264cb46f1659b85795a75c1b762be4b615 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 25 Oct 2021 20:41:09 +0200 Subject: [PATCH 178/296] Add notice about Minetest not supporting capital letters in modnames --- CONTRIBUTING.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1f2d1d0de..9c235880d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -163,7 +163,8 @@ optional) ### Code Guidelines * Each mod must provide `mod.conf`. * Mod names are snake case, and newly added mods start with `mcl_`, e.g. -`mcl_core`, `mcl_farming`, `mcl_monster_eggs` +`mcl_core`, `mcl_farming`, `mcl_monster_eggs`. Keep in mind Minetest +does not support capital letters in mod names. * To export functions, store them inside a global table named like the mod, e.g. From eccba76732bff067bf677bee46acfc51e1298234 Mon Sep 17 00:00:00 2001 From: NO11 Date: Mon, 25 Oct 2021 20:25:34 +0000 Subject: [PATCH 179/296] Use math.floor instead of math.round --- mods/ITEMS/mcl_totems/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_totems/init.lua b/mods/ITEMS/mcl_totems/init.lua index aa188855f..b11e68df7 100644 --- a/mods/ITEMS/mcl_totems/init.lua +++ b/mods/ITEMS/mcl_totems/init.lua @@ -37,7 +37,7 @@ mcl_damage.register_modifier(function(obj, damage, reason) for i = 1, 4 do for c = 1, #particle_colors do minetest.add_particlespawner({ - amount = math.round(100/(4 * #particle_colors)), + amount = math.floor(100 / (4 * #particle_colors)), time = 1, minpos = vector.offset(ppos, 0, -1, 0), maxpos = vector.offset(ppos, 0, 1, 0), From 30f7c638f377f7a2387974736ccd6ac171e5b0a6 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 25 Oct 2021 22:55:48 +0200 Subject: [PATCH 180/296] mcl_enchanting: Add spanish translations and update template Credit to: todoporlalibertad Reviewed by j45 --- .../locale/mcl_enchanting.es.tr | 123 +++++++++++ mods/ITEMS/mcl_enchanting/locale/template.txt | 205 ++++++++++-------- 2 files changed, 240 insertions(+), 88 deletions(-) create mode 100644 mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.es.tr diff --git a/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.es.tr b/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.es.tr new file mode 100644 index 000000000..a977e8fe6 --- /dev/null +++ b/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.es.tr @@ -0,0 +1,123 @@ +# textdomain: mcl_enchanting + + +### enchantments.lua ### + +Arrows passes through multiple objects.=Las flechas atraviesan multiples enemigos. +Arrows set target on fire.=Las flechas prenderan los enemigos. +Bane of Arthropods=Perdición de los Artrópodos +Channeling=Conductividad + +Channels a bolt of lightning toward a target. Works only during thunderstorms and if target is unobstructed with opaque blocks.=Canaliza los rayos de una tormenta hacia el enemigo. + +Curse of Vanishing=Maldición de Desaparición +Decreases crossbow charging time.=Disminuye el tiempo de carga de las ballestas. +Decreases time until rod catches something.=Disminuye el tiempo que tardan en picar los cebos en la pesca. +Depth Strider=Agilidad acuática +Efficiency=Eficiencia +Extends underwater breathing time.=Aumenta el tiempo de mantener la respiración. +Fire Aspect=Aspecto Ígneo +Flame=Fuego +Fortune=Fortuna +Frost Walker=Paso Helado +Impaling=Empalamiento +Increases arrow damage.=Incrementa el daño de las flechas. +Increases arrow knockback.=Incrementa el empuje de las flechas. +Increases certain block drops.=Incrementa la cantidad de objetos que sueltan los bloques. + +Increases damage and applies Slowness IV to arthropod mobs (spiders, cave spiders, silverfish and endermites).=Incrementa el daño y ralentiza a los artrópodos. (arañas, lepismas, endermitas, etc) + +Increases damage to undead mobs.=Incrementa el daño contra no-muertos. +Increases damage.=Incrementa el daño. +Increases item durability.=Incrementa la durabilidad de una herramienta. +Increases knockback.=Incrementa el empuje. +Increases mining speed.=Incrementa la velocidad de picado. +Increases mob loot.=Incrementa el botín de los enemigos. +Increases rate of good loot (enchanting books, etc.)=Incrementa la probabilidad de encontrar tesoros. +Increases sweeping attack damage.=Incrementa el daño de efecto area. +Increases underwater movement speed.=Incrementa la velocidad de nado bajo el agua. +Increases walking speed on soul sand.=Incrementa la velocidad al caminar sobre arena de Almas. +Infinity=Infinidad +Item destroyed on death.=El objeto se destruye tras tu muerte. +Knockback=Empuje +Looting=Botín +Loyalty=Lealtad +Luck of the Sea=Suerte Marina +Lure=Atracción +Mending=Reparación +Mined blocks drop themselves.=Los bloques se minarán enteros. +Multishot=Multidisparo +Piercing=Perforación +Power=Poder +Punch=Retroceso +Quick Charge=Carga Rápida +Repair the item while gaining XP orbs.=Repara los objetos portados al recibir orbes de experiencia. +Respiration=Respiración +Riptide=Propulsión acuática +Sets target on fire.=Incencia al enemigo. +Sharpness=Filo +Shoot 3 arrows at the cost of one.=Dispara 3 flechas al precio de una. +Shooting consumes no regular arrows.=No se consumiran las flechas lanzadas. +Silk Touch=Toque de Seda +Smite=Golpeo +Soul Speed=Velocidad de Almas +Sweeping Edge=Filo Arrasador +Trident deals additional damage to ocean mobs.=Incrementa el daño del tridente sobre criaturas acuáticas. + +Trident launches player with itself when thrown. Works only in water or rain.=El tridente impulsa al portador dentro del agua o bajo la lluvia. + +Trident returns after being thrown. Higher levels reduce return time.=El tridente regresa al portador tras lanzarlo. + +Turns water beneath the player into frosted ice and prevents the damage from magma blocks.=Congela el agua bajo tus pies y evita el daño de los bloques de magma. + +Unbreaking=Irrompibilidad + +### engine.lua ### + +@1 Enchantment Levels=Nivel de encantamiento: @1 +@1 Lapis Lazuli=@1 Lapis Lázuli +Inventory=Inventario +Level requirement: @1=Nivel requerido: @1 + +### init.lua ### + +'@1' is not a valid number='@1' no es un número válido +'@1' is not a valid number.='@1' no es un número válido + []= [] +@1 can't be combined with @2.=@1 no se puede combinar con @2 + +After finally selecting your enchantment; left-click on the selection, and you will see both the lapis lazuli and your experience levels consumed. And, an enchanted item left in its place.=Despues elige tu encantamiento, los niveles de experiencia y el lapis lázuli seran consumidos y el encantamiento aplicado al objeto. + +After placing your items in the slots, the enchanting options will be shown. Hover over the options to read what is available to you.=Coloca el objeto en su ranura yse mostraran los encantamientos a elegir. + +Enchant=Encantamiento +Enchant an item=Encantar objeto +Enchanted Book=Libro Encantado +Enchanting Table=Mesa de Encantamientos + +Enchanting Tables will let you enchant armors, tools, weapons, and books with various abilities. But, at the cost of some experience, and lapis lazuli.=La mesa de Encantamientos dara a tus herramientas, armas o armadura algunas habilidades magicas. Pero a coste de algo de experiencia y lapis lázuli. + +Enchanting succeded.=Encantado correctamente. +Forcefully enchant an item=Encantar objeto a la fuerza. + +Place a tool, armor, weapon or book into the top left slot, and then place 1-3 Lapis Lazuli in the slot to the right.=Coloca una herramienta, arma, armadura o libro sobre la ranura izquierda, coloca de 1 a 3 Lapis lázulis en la ranura derecha. + +Player '@1' cannot be found.=Jugador @1 no encontrado. +Rightclick the Enchanting Table to open the enchanting menu.=Clic derecho sobre la mesa de encantamientos para abrir la interfaz. +Spend experience, and lapis to enchant various items.=Experiencia y Lapis para encantar varios objetos. + +The number you have entered (@1) is too big, it must be at most @2.=@1 es muy grande, debe ser menor que @2 + +The number you have entered (@1) is too small, it must be at least @2.=@1 es muy pequeño, debe ser mayor a @2 + +The selected enchantment can't be added to the target item.=El encantamiento seleccionado no puede añadirse a ese objeto. +The target doesn't hold an item.=El jugador no sujeta un objeto. +The target item is not enchantable.=El objeto del jugador no se puede encantar. +There is no such enchantment '@1'.=@1 no es un encantamiento. + +These options are randomized, and dependent on experience level; but the enchantment strength can be increased.=Las opciones seran aleatorias dependiendo del nivel de experiencia, los niveles de encantamiento pueden ser aumentados. + +To increase the enchantment strength, place bookshelves around the enchanting table. However, you will need to keep 1 air node between the table, & the bookshelves to empower the enchanting table.=Para aumentar los niveles de encantamientos, coloca librerias alrededor y cerca de la mesa de encantamientos. + +Usage: /enchant []=Usa: /enchant [] +Usage: /forceenchant []=Usa /forceenchant [] diff --git a/mods/ITEMS/mcl_enchanting/locale/template.txt b/mods/ITEMS/mcl_enchanting/locale/template.txt index 08fa82097..1f540d6d3 100644 --- a/mods/ITEMS/mcl_enchanting/locale/template.txt +++ b/mods/ITEMS/mcl_enchanting/locale/template.txt @@ -1,100 +1,129 @@ # textdomain: mcl_enchanting -Aqua Affinity= -Increases underwater mining speed.= -Bane of Arthropods= -Increases damage and applies Slowness IV to arthropod mobs (spiders, cave spiders, silverfish and endermites).= -Blast Protection= -Reduces explosion damage and knockback.= -Channeling= -Channels a bolt of lightning toward a target. Works only during thunderstorms and if target is unobstructed with opaque blocks.= -Curse of Binding= -Item cannot be removed from armor slots except due to death, breaking or in Creative Mode.= -Curse of Vanishing= -Item destroyed on death.= -Depth Strider= -Increases underwater movement speed.= -Efficiency= -Increases mining speed.= -Feather Falling= -Reduces fall damage.= -Fire Aspect= -Sets target on fire.= -Fire Protection= -Reduces fire damage.= -Flame= -Arrows set target on fire.= -Fortune= -Increases certain block drops.= -Frost Walker= -Turns water beneath the player into frosted ice and prevents the damage from magma blocks.= -Impaling= -Trident deals additional damage to ocean mobs.= -Infinity= -Shooting consumes no regular arrows.= -Knockback= -Increases knockback.= -Looting= -Increases mob loot.= -Loyalty= -Trident returns after being thrown. Higher levels reduce return time.= -Luck of the Sea= -Increases rate of good loot (enchanting books, etc.)= -Lure= -Decreases time until rod catches something.= -Mending= -Repair the item while gaining XP orbs.= -Multishot= -Shoot 3 arrows at the cost of one.= -Piercing= + + +### enchantments.lua ### + Arrows passes through multiple objects.= -Power= -Increases arrow damage.= -Projectile Protection= -Reduces projectile damage.= -Protection= -Reduces most types of damage by 4% for each level.= -Punch= -Increases arrow knockback.= -Quick Charge= +Arrows set target on fire.= +Bane of Arthropods= +Channeling= + +Channels a bolt of lightning toward a target. Works only during thunderstorms and if target is unobstructed with opaque blocks.= + +Curse of Vanishing= Decreases crossbow charging time.= -Respiration= +Decreases time until rod catches something.= +Depth Strider= +Efficiency= Extends underwater breathing time.= -Riptide= -Trident launches player with itself when thrown. Works only in water or rain.= -Sharpness= -Increases damage.= -Silk Touch= -Mined blocks drop themselves.= -Smite= +Fire Aspect= +Flame= +Fortune= +Frost Walker= +Impaling= +Increases arrow damage.= +Increases arrow knockback.= +Increases certain block drops.= + +Increases damage and applies Slowness IV to arthropod mobs (spiders, cave spiders, silverfish and endermites).= + Increases damage to undead mobs.= -Soul Speed= -Increases walking speed on soul sand.= -Sweeping Edge= -Increases sweeping attack damage.= -Thorns= -Reflects some of the damage taken when hit, at the cost of reducing durability with each proc.= -Unbreaking= +Increases damage.= Increases item durability.= -Inventory= -@1 Lapis Lazuli= +Increases knockback.= +Increases mining speed.= +Increases mob loot.= +Increases rate of good loot (enchanting books, etc.)= +Increases sweeping attack damage.= +Increases underwater movement speed.= +Increases walking speed on soul sand.= +Infinity= +Item destroyed on death.= +Knockback= +Looting= +Loyalty= +Luck of the Sea= +Lure= +Mending= +Mined blocks drop themselves.= +Multishot= +Piercing= +Power= +Punch= +Quick Charge= +Repair the item while gaining XP orbs.= +Respiration= +Riptide= +Sets target on fire.= +Sharpness= +Shoot 3 arrows at the cost of one.= +Shooting consumes no regular arrows.= +Silk Touch= +Smite= +Soul Speed= +Sweeping Edge= +Trident deals additional damage to ocean mobs.= + +Trident launches player with itself when thrown. Works only in water or rain.= + +Trident returns after being thrown. Higher levels reduce return time.= + +Turns water beneath the player into frosted ice and prevents the damage from magma blocks.= + +Unbreaking= + +### engine.lua ### + @1 Enchantment Levels= +@1 Lapis Lazuli= +Inventory= Level requirement: @1= -Enchant an item= - []= -Usage: /enchant []= -Player '@1' cannot be found.= -There is no such enchantment '@1'.= -The target doesn't hold an item.= -The selected enchantment can't be added to the target item.= + +### init.lua ### + '@1' is not a valid number= -The number you have entered (@1) is too big, it must be at most @2.= -The number you have entered (@1) is too small, it must be at least @2.= -@1 can't be combined with @2.= -Enchanting succeded.= -Forcefully enchant an item= -Usage: /forceenchant []= -The target item is not enchantable.= '@1' is not a valid number.= + []= +@1 can't be combined with @2.= + +After finally selecting your enchantment; left-click on the selection, and you will see both the lapis lazuli and your experience levels consumed. And, an enchanted item left in its place.= + +After placing your items in the slots, the enchanting options will be shown. Hover over the options to read what is available to you.= + +Enchant= +Enchant an item= Enchanted Book= Enchanting Table= -Enchant= + +Enchanting Tables will let you enchant armors, tools, weapons, and books with various abilities. But, at the cost of some experience, and lapis lazuli.= + +Enchanting succeded.= +Forcefully enchant an item= + +Place a tool, armor, weapon or book into the top left slot, and then place 1-3 Lapis Lazuli in the slot to the right.= + +Player '@1' cannot be found.= +Rightclick the Enchanting Table to open the enchanting menu.= +Spend experience, and lapis to enchant various items.= + +The number you have entered (@1) is too big, it must be at most @2.= + +The number you have entered (@1) is too small, it must be at least @2.= + +The selected enchantment can't be added to the target item.= +The target doesn't hold an item.= +The target item is not enchantable.= +There is no such enchantment '@1'.= + +These options are randomized, and dependent on experience level; but the enchantment strength can be increased.= + +To increase the enchantment strength, place bookshelves around the enchanting table. However, you will need to keep 1 air node between the table, & the bookshelves to empower the enchanting table.= + +Usage: /enchant []= +Usage: /forceenchant []= + + +##### not used anymore ##### + +# textdomain: mcl_enchanting +Aqua Affinity= From 0369465630508956cb75d1c2c055e71a67b74b73 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 25 Oct 2021 22:59:21 +0200 Subject: [PATCH 181/296] Add todoporlalibertad to translation credits --- CREDITS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CREDITS.md b/CREDITS.md index 296e7c23b..de3dcae61 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -110,6 +110,7 @@ * wuniversales * kay27 * pitchum +* todoporlalibertad ## Special thanks * celeron55 for creating Minetest From 4e8e6fbb51a6a110619dbe0f2d6acccbc87dfa60 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 26 Oct 2021 11:42:33 +0200 Subject: [PATCH 182/296] Update development target section --- CONTRIBUTING.md | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9c235880d..6cdd0db6e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,10 +4,22 @@ Wow, thank you! :-) But first, some things to note: -MineClone2's development target is to make a free software clone of -Minecraft, ***version 1.17***, ***Java Edition***, ***+ Optifine -features supported by the Minetest Engine***. The priority is making -polished features up to version 1.12. +MineClone2's development target is to... + +- Crucially, create a stable, moddable, free/libre clone of Minecraft +based on the Minetest engine with polished features, usable in both +singleplayer and multiplayer. Currently, most of **Minecraft Java +Edition 1.12.2** features are already implemented and polishing existing +features are prioritised over new feature requests. +- With lessened priority yet strictly, implement features targetting +**Minecraft version 1.17 + Optifine** (Optifine only as far as supported +by the Minetest Engine). This means features in parity with the listed +Minecraft experiences are prioritised over those that don't fulfill this +scope. +- Optionally, create a performant experience that will run relatively +well on really low spec computers. Unfortunately, due to Minecraft's +mechanisms and Minetest engine's limitations along with a very small +playerbase on low spec computers, optimizations are hard to investigate. MineClone2 is maintained by Nicu and Fleckenstein. If you have any problems or questions, contact us (See Links section below). @@ -298,7 +310,7 @@ version number (https://forum.minetest.net/viewtopic.php?f=50&t=16407) * Post release announcement and changelog in forums -## Crediting +### Crediting Contributors, Developers and Maintainers will be credited in `CREDITS.md`. If you make your first time contribution, please add yourself to this file. There are also Discord roles for Contributors, From e341b2a6fe22c879abb66353a7539fd32320bb27 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 26 Oct 2021 11:55:08 +0200 Subject: [PATCH 183/296] Split code contributor section --- CONTRIBUTING.md | 81 ++++++++++++++++++++++++++++--------------------- 1 file changed, 46 insertions(+), 35 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6cdd0db6e..6c5aa2cd1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -137,24 +137,8 @@ If you opened or have contributed to an issue, you receive the ## How you can help as a programmer (Almost) all the MineClone2 development is done using pull requests. -If you feel like a problem needs to fixed or you want to make a new -feature, you could start writing the code right away and notifying us -when you're done, but it never hurts to discuss things first. If there -is no issue on the topic, open one. If there is an issue, tell us that -you'd like to take care of it, to avoid duplicate work. We appreciate -any contributing effort to Mineclone2. If you are a relatively new -programmer, you can reach us on Discord, Matrix or IRC for questions -about git, Lua, Minetest API, Mineclone2 codebase or anything related -to MineClone2. We can help you avoid writing code that would be deemed -inadequeate, or help you become familiar with Mineclone2 better, or even -help using development tools. By asking us to include your changes in -this game, you agree that they fall under the terms of the GPLv3, which -basically means they will become part of a free software. Sometimes, -your code may cause crashes or bugs - we try to avoid such scenarios by -testing everytime before merging it, but if your merged work causes -problems, we ask you fix the issues as soon as possible. -### The recommended workflow +### Recommended workflow * Fork the repository (in case you have not already) * Do your change in a new branch * Create a pull request to get your changes merged into master @@ -163,7 +147,45 @@ imperative that conflicts are resolved prior to merging the pull request. * After the pull request got merged, you can delete the branch -### Git Guidelines +### Discuss first +If you feel like a problem needs to fixed or you want to make a new +feature, you could start writing the code right away and notifying us +when you're done, but it never hurts to discuss things first. If there +is no issue on the topic, open one. If there is an issue, tell us that +you'd like to take care of it, to avoid duplicate work. + +### Don't hesitate to ask for help +We appreciate any contributing effort to MineClone2. If you are a +relatively new programmer, you can reach us on Discord, Matrix or IRC +for questions about git, Lua, Minetest API, MineClone2 codebase or +anything related to MineClone2. We can help you avoid writing code that +would be deemed inadequeate, or help you become familiar with MineClone2 +better, or even help using development tools. + +### Maintain your own code, even if alreay got merged +Sometimes, your code may cause crashes or bugs - we try to avoid such +scenarios by testing everytime before merging it, but if your merged +work causes problems, we ask you fix the issues as soon as possible. + +### Changing Gameplay +Pull Requests that change gameplay have to be properly researched and +need to state their sources. These PRs also need Fleckenstein's approval +before they are merged. +You can use these sources: + +* Minecraft code (Name the source file and line, however DONT post any +proprietary code). You can use +[MCP](https://minecraft.fandom.com/wiki/Programs_and_editors/Mod_Coder_Pack) +to decompile Minecraft or look at +[Minestorm](https://github.com/Minestom/Minestom) code. +* Testing things inside of Minecraft (Attach screenshots / video footage +of the results) +* [Official Minecraft Wiki](https://minecraft.fandom.com/wiki/Minecraft_Wiki) +(Include a link to the specific page you used) + +### Keep our guidelines + +#### Git Guidelines * We use merge rather than rebase or squash merge * We don't use git submodules. * Your commit names should be relatively descriptive, e.g. when saying @@ -172,7 +194,7 @@ issue. * Try to keep your commits as atomic as possible (advise, but completely optional) -### Code Guidelines +#### Code Guidelines * Each mod must provide `mod.conf`. * Mod names are snake case, and newly added mods start with `mcl_`, e.g. `mcl_core`, `mcl_farming`, `mcl_monster_eggs`. Keep in mind Minetest @@ -226,7 +248,7 @@ some_table = { * Use double quotes for strings, e.g. `"asdf"` rather than `'asdf'` * Use snake_case rather than CamelCase, e.g. `my_function` rather than `MyFunction` -* Dont declare functions as an assignment, e.g. +* Don't declare functions as an assignment, e.g. ```lua -- bad @@ -248,21 +270,10 @@ function my_mod.some_func() end ``` -### Changes to Gameplay -Pull Requests that change gameplay have to be properly researched and -need to state their sources. These PRs also need Fleckenstein's approval -before they are merged. -You can use these sources: - -* Minecraft code (Name the source file and line, however DONT post any -proprietary code). You can use -[MCP](https://minecraft.fandom.com/wiki/Programs_and_editors/Mod_Coder_Pack) -to decompile Minecraft or look at -[Minestorm](https://github.com/Minestom/Minestom) code. -* Testing things inside of Minecraft (Attach screenshots / video footage -of the results) -* [Official Minecraft Wiki](https://minecraft.fandom.com/wiki/Minecraft_Wiki) -(Include a link to the specific page you used) +### Licensing +By asking us to include your changes in +this game, you agree that they fall under the terms of the GPLv3, which +basically means they will become part of a free software. ### Developer status Active and trusted contributors are often granted write access to the From a0789e72f04ee7c5bbc03c1fcf68e082eceac980 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 26 Oct 2021 11:57:17 +0200 Subject: [PATCH 184/296] Move licensing down, just before crediting --- CONTRIBUTING.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6c5aa2cd1..f7e21d481 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -270,11 +270,6 @@ function my_mod.some_func() end ``` -### Licensing -By asking us to include your changes in -this game, you agree that they fall under the terms of the GPLv3, which -basically means they will become part of a free software. - ### Developer status Active and trusted contributors are often granted write access to the MineClone2 repository. However you should not push things directly to @@ -321,6 +316,11 @@ version number (https://forum.minetest.net/viewtopic.php?f=50&t=16407) * Post release announcement and changelog in forums +### Licensing +By asking us to include your changes in +this game, you agree that they fall under the terms of the GPLv3, which +basically means they will become part of a free software. + ### Crediting Contributors, Developers and Maintainers will be credited in `CREDITS.md`. If you make your first time contribution, please add From 70425e9f30611ab7dcbbbf5518ed113fdf1e1809 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 26 Oct 2021 11:59:32 +0200 Subject: [PATCH 185/296] Split profiling section --- CONTRIBUTING.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f7e21d481..1f063a062 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -117,11 +117,13 @@ not work, so it's not very useful to try them out yet. If you own a server, a great way to help us improve MineClone2's code is by giving us profiler results. Profiler results give us detailed information about the game's performance and let us know where the real -troublespots are. This way we can make the game faster. Minetest has a -built in profiler. Simply set `profiler.load = true` in your -configuration file and restart the server. After running the server for -some time, just run `/profiler save` in chat - then you will find a file -in the world directory containing the results. Open a new issue and +troublespots are. This way we can make the game faster. + +#### Using Minetest's profiler +Minetest has a built in profiler. Simply set `profiler.load = true` in +your configuration file and restart the server. After running the server +for some time, just run `/profiler save` in chat - then you will find a +file in the world directory containing the results. Open a new issue and upload the file. You can name the issue " profiler results". From ea0f52763c2b183368b8a0f4690c34d060bdafac Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 26 Oct 2021 12:04:16 +0200 Subject: [PATCH 186/296] Split developer responsibilities into a list --- CONTRIBUTING.md | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1f063a062..58762bfcb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -274,22 +274,27 @@ end ### Developer status Active and trusted contributors are often granted write access to the -MineClone2 repository. However you should not push things directly to +MineClone2 repository. + +#### Developer responsibilities +- You should not push things directly to MineClone2 master - rather, do your work on a branch on your private repo, then create a pull request. This way other people can review your -changes and make sure they work before they get merged. You are allowed -to merge PRs if they have recieved the necessary feedback and have been +changes and make sure they work before they get merged. +- Merge PRs if they have recieved the necessary feedback and have been tested to not lead to any crashes and do what they claim to do by at -least two different people. You may also be assigned to issues or pull +least two different people. +- You may also be assigned to issues or pull requests as a developer. In this case it is your responsibility to fix the issue / review and merge the pull request when it is ready. You can also unassign yourself from the issue / PR if you have no time or don't want to take care of it for some other reason (after all, everyone is a volunteer and we can't expect you to do work that you are not intrested -in) - the important thing is really that you make sure to inform us if -you won't take care of something that has been assigned to you. Also, -please assign yourself to something that you want to work on to avoid -duplicate work. As a developer, it should be easy to reach you about +in) - **the important thing is that you make sure to inform us if you +won't take care of something that has been assigned to you.** +- Please assign yourself to something that you want to work on to avoid +duplicate work. +- As a developer, it should be easy to reach you about your code. You should be on the Discord (or, if you really don't like Discord, Matrix or IRC). From 1bd972bff7cf48e7076cc28f5c03a6067f5b27b2 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 26 Oct 2021 12:11:18 +0200 Subject: [PATCH 187/296] Split maintainer responsibilities into list --- CONTRIBUTING.md | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 58762bfcb..fed4885b4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -299,19 +299,25 @@ your code. You should be on the Discord (or, if you really don't like Discord, Matrix or IRC). ### Maintainer status -Maintainers are responsible for making sure issues are addressed and -pull requests are reviewed and merged, by assigning either themselves or -Developers to issues / PRs. Maintainers are responsible for making -releases, making sure guidelines are kept and making project decisions -based on what the community wants. Maintainers grant/revoke developer -access. Currently there are two maintainers with different -responsibility fields: +Maintainers carry the main responsibility for the project. +#### Maintainer responsibilities +- Making sure issues are addressed and pull requests are reviewed and +merged, by assigning either themselves or Developers to issues / PRs +- Making releases +- Making sure guidelines are kept +- Making project decisions based on what the community wants +- Granting/revoking developer access +- Enforcing the code of conduct (See CODE_OF_CONDUCT.md) +- Moderating official community spaces (See Links section) +- Resolving conflicts and problems within the community + +#### Current maintainers * Fleckenstein - responsible for gameplay review, publishing releases, technical guidelines and issue/PR delegation * Nicu - responsible for community related issues -#### Creating releases +#### Release process * Launch MineClone2 to make sure it still runs * Update the version number in README.md * Use `git tag ` to tag the latest commit with the From 64ebdd0f18beabe915bcabed52b52bf1bb7433e5 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 26 Oct 2021 12:16:00 +0200 Subject: [PATCH 188/296] Update line length in licensing section --- CONTRIBUTING.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fed4885b4..eb93cc2ff 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -330,9 +330,9 @@ version number * Post release announcement and changelog in forums ### Licensing -By asking us to include your changes in -this game, you agree that they fall under the terms of the GPLv3, which -basically means they will become part of a free software. +By asking us to include your changes in this game, you agree that they +fall under the terms of the GPLv3, which basically means they will +become part of a free software. ### Crediting Contributors, Developers and Maintainers will be credited in From 0c567c7921b63d2b690577cd45de2467bdbebb43 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 26 Oct 2021 12:22:21 +0200 Subject: [PATCH 189/296] Update maintainer section in CREDITS.md (leave kay27 in, but remove jordan since he never did any maintainance work) --- CREDITS.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CREDITS.md b/CREDITS.md index de3dcae61..3d039f6b1 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -8,8 +8,8 @@ ## Maintainers * Fleckenstein +* Nicu * kay27 -* jordan4ibanez ## Developers * bzoss @@ -19,7 +19,6 @@ * iliekprogrammar * MysticTempest * Rootyjr -* Nicu * aligator * Code-Sploit * NO11 From c315d155e1a51a678931be04b16ae9bcc3cf91ae Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 26 Oct 2021 12:35:19 +0200 Subject: [PATCH 190/296] Update CREDITS.md --- CREDITS.md | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/CREDITS.md b/CREDITS.md index 3d039f6b1..95884dcac 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -22,6 +22,8 @@ * aligator * Code-Sploit * NO11 +* cora +* jordan4ibanez ## Contributors * Laurent Rocher @@ -47,8 +49,24 @@ * dBeans * nickolas360 * yutyo -* ztianyang +* Tianyang Zhang * j45 +* Marcin Serwin +* erlehmann +* E +* Benjamin Schötz +* Doloment +* Sydney Gems +* talamh +* Emily2255 +* Emojigit +* FinishedFragment +* sfan5 +* Blue Blancmange +* Jared Moody +* SmallJoker +* Sven792 +* aldum ## MineClone5 * kay27 @@ -73,7 +91,6 @@ * Rochambeau * rubenwardy * stu -* jordan4ibanez * 4aiman * Kahrl * Krock @@ -102,6 +119,7 @@ * xMrVizzy * yutyo * NO11 +* kay27 ## Translations * Wuzzy @@ -110,6 +128,7 @@ * kay27 * pitchum * todoporlalibertad +* Marcin Serwin ## Special thanks * celeron55 for creating Minetest From 797da20fa7d4c83f411a4c2586ed16b1c1da913a Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 26 Oct 2021 13:08:07 +0200 Subject: [PATCH 191/296] Add script to automatically generate ingame credits from CREDITS.md --- mods/HUD/mcl_credits/init.lua | 121 +------------------------ mods/HUD/mcl_credits/people.lua | 141 ++++++++++++++++++++++++++++++ tools/generate_ingame_credits.lua | 49 +++++++++++ 3 files changed, 193 insertions(+), 118 deletions(-) create mode 100644 mods/HUD/mcl_credits/people.lua create mode 100755 tools/generate_ingame_credits.lua diff --git a/mods/HUD/mcl_credits/init.lua b/mods/HUD/mcl_credits/init.lua index 235b2a3cb..db3ac8436 100644 --- a/mods/HUD/mcl_credits/init.lua +++ b/mods/HUD/mcl_credits/init.lua @@ -3,123 +3,8 @@ local S = minetest.get_translator(modname) mcl_credits = { players = {}, -} - -mcl_credits.description = S("A faithful Open Source clone of Minecraft") - --- Sub-lists are sorted by number of commits, but the list should not be rearranged (-> new contributors are just added at the end of the list) -mcl_credits.people = { - { S("Creator of MineClone"), 0x0A9400, { - "davedevils", - }}, - { S("Creator of MineClone2"), 0xFBF837, { - "Wuzzy", - }}, - { S("Maintainers"), 0xFF51D5, { - "Fleckenstein", - "kay27", - "oilboi", - }}, - { S("Developers"), 0xF84355, { - "bzoss", - "AFCMS", - "epCode", - "ryvnf", - "iliekprogrammar", - "MysticTempest", - "Rootyjr", - "Nicu", - "aligator", - "Code-Sploit", - "NO11", - }}, - { S("Contributors"), 0x52FF00, { - "Laurent Rocher", - "HimbeerserverDE", - "TechDudie", - "Alexander Minges", - "ArTee3", - "ZeDique la Ruleta", - "pitchum", - "wuniversales", - "Bu-Gee", - "David McMackins II", - "Nicholas Niro", - "Wouters Dorian", - "Blue Blancmange", - "Jared Moody", - "Li0n", - "Midgard", - "Saku Laesvuori", - "Yukitty", - "ZedekThePD", - "aldum", - "dBeans", - "nickolas360", - "yutyo", - "ztianyang", - "j45", - }}, - {"MineClone5", 0xA60014, { - "kay27", - "Debiankaios", - "epCode", - "NO11", - "j45", - }}, - { S("Original Mod Authors"), 0x343434, { - "Wuzzy", - "Fleckenstein", - "BlockMen", - "TenPlus1", - "PilzAdam", - "ryvnf", - "stujones11", - "Arcelmi", - "celeron55", - "maikerumine", - "GunshipPenguin", - "Qwertymine3", - "Rochambeau", - "rubenwardy", - "stu", - "oilboi", - "4aiman", - "Kahrl", - "Krock", - "UgnilJoZ", - "lordfingle", - "22i", - "bzoss", - "kilbith", - "xeranas", - "kddekadenz", - "sofar", - "4Evergreen4", - "jordan4ibanez", - "paramat", - }}, - { S("3D Models"), 0x0019FF, { - "22i", - "tobyplowy", - "epCode", - }}, - { S("Textures"), 0xFF9705, { - "XSSheep", - "Wuzzy", - "kingoscargames", - "leorockway", - "xMrVizzy", - "yutyo", - "NO11", - }}, - { S("Translations"), 0x00FF60, { - "Wuzzy", - "Rocher Laurent", - "wuniversales", - "kay27", - "pitchum", - }}, + description = S("A faithful Open Source clone of Minecraft"), + people = dofile(minetest.get_modpath(modname) .. "/people.lua"), } local function add_hud_element(def, huds, y) @@ -243,7 +128,7 @@ minetest.register_globalstep(function(dtime) y = y - 5 end end - + if y > -100 then if id == huds.icon then y = math.max(400, y) diff --git a/mods/HUD/mcl_credits/people.lua b/mods/HUD/mcl_credits/people.lua new file mode 100644 index 000000000..2861b5052 --- /dev/null +++ b/mods/HUD/mcl_credits/people.lua @@ -0,0 +1,141 @@ +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) + +return { + {S("Creator of MineClone"), 0x0A9400, { + "davedevils", + }}, + {S("Creator of MineClone2"), 0xFBF837, { + "Wuzzy", + }}, + {S("Maintainers"), 0xFF51D5, { + "Fleckenstein", + "Nicu", + "kay27", + }}, + {S("Developers"), 0xF84355, { + "bzoss", + "AFCMS", + "epCode", + "ryvnf", + "iliekprogrammar", + "MysticTempest", + "Rootyjr", + "aligator", + "Code-Sploit", + "NO11", + "cora", + "jordan4ibanez", + }}, + {S("Contributors"), 0x52FF00, { + "Laurent Rocher", + "HimbeerserverDE", + "TechDudie", + "Alexander Minges", + "ArTee3", + "ZeDique la Ruleta", + "pitchum", + "wuniversales", + "Bu-Gee", + "David McMackins II", + "Nicholas Niro", + "Wouters Dorian", + "Blue Blancmange", + "Jared Moody", + "Li0n", + "Midgard", + "Saku Laesvuori", + "Yukitty", + "ZedekThePD", + "aldum", + "dBeans", + "nickolas360", + "yutyo", + "Tianyang Zhang", + "j45", + "Marcin Serwin", + "erlehmann", + "E", + "Benjamin Schötz", + "Doloment", + "Sydney Gems", + "talamh", + "Emily2255", + "Emojigit", + "FinishedFragment", + "sfan5", + "Blue Blancmange", + "Jared Moody", + "SmallJoker", + "Sven792", + "aldum", + }}, + {S("MineClone5"), 0xA60014, { + "kay27", + "Debiankaios", + "epCode", + "NO11", + "j45", + }}, + {S("Original Mod Authors"), 0x343434, { + "Wuzzy", + "Fleckenstein", + "BlockMen", + "TenPlus1", + "PilzAdam", + "ryvnf", + "stujones11", + "Arcelmi", + "celeron55", + "maikerumine", + "GunshipPenguin", + "Qwertymine3", + "Rochambeau", + "rubenwardy", + "stu", + "4aiman", + "Kahrl", + "Krock", + "UgnilJoZ", + "lordfingle", + "22i", + "bzoss", + "kilbith", + "xeranas", + "kddekadenz", + "sofar", + "4Evergreen4", + "jordan4ibanez", + "paramat", + }}, + {S("3D Models"), 0x0019FF, { + "22i", + "tobyplowy", + "epCode", + }}, + {S("Textures"), 0xFF9705, { + "XSSheep", + "Wuzzy", + "kingoscargames", + "leorockway", + "xMrVizzy", + "yutyo", + "NO11", + "kay27", + }}, + {S("Translations"), 0x00FF60, { + "Wuzzy", + "Rocher Laurent", + "wuniversales", + "kay27", + "pitchum", + "todoporlalibertad", + "Marcin Serwin", + }}, + {S("Special thanks"), 0x00E9FF, { + "celeron55 for creating Minetest", + "Jordach for the jukebox music compilation from Big Freaking Dig", + "The workaholics who spent way too much time writing for the Minecraft Wiki. It's an invaluable resource for creating this game", + "Notch and Jeb for being the major forces behind Minecraft", + }}, +} diff --git a/tools/generate_ingame_credits.lua b/tools/generate_ingame_credits.lua new file mode 100755 index 000000000..89b633ef0 --- /dev/null +++ b/tools/generate_ingame_credits.lua @@ -0,0 +1,49 @@ +#! /usr/bin/env lua +-- Script to automatically generate mods/HUD/mcl_credits/people.lua from CREDITS.md +-- Run from MCL2 root folder + +local colors = { + ["Creator of MineClone"] = "0x0A9400", + ["Creator of MineClone2"] = "0xFBF837", + ["Maintainers"] = "0xFF51D5", + ["Developers"] = "0xF84355", + ["Contributors"] = "0x52FF00", + ["MineClone5"] = "0xA60014", + ["Original Mod Authors"] = "0x343434", + ["3D Models"] = "0x0019FF", + ["Textures"] = "0xFF9705", + ["Translations"] = "0x00FF60", + ["Special thanks"] = "0x00E9FF", +} + +local from = io.open("CREDITS.md", "r") +local to = io.open("mods/HUD/mcl_credits/people.lua", "w") + +to:write([[ +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) + +]]) + +to:write("return {\n") + +local started_block = false + +for line in from:lines() do + if line:find("## ") == 1 then + if started_block then + to:write("\t}},\n") + end + local title = line:sub(4, #line) + to:write("\t{S(\"" .. title .. "\"), " .. (colors[title] or "0xFFFFFF") .. ", {\n") + started_block = true + elseif line:find("*") == 1 then + to:write("\t\t\"" .. line:sub(3, #line) .. "\",\n") + end +end + +if started_block then + to:write("\t}},\n") +end + +to:write("}\n") From 835076ea4b2ed25d850ce2452b858fd26ab4364f Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 26 Oct 2021 14:28:40 +0200 Subject: [PATCH 192/296] Document asset contributions --- CONTRIBUTING.md | 57 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index eb93cc2ff..e817f81bd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -113,6 +113,63 @@ pull requests here: requests that start with a `WIP:` are not done yet, and therefore might not work, so it's not very useful to try them out yet. +### Contributing assets +Due to license problems, MineClone2 can unfortunately not use +Minecraft's assets, therefore we are always looking for asset +contributions. To contribute assets, it can be useful to learn git +basics and read the section for Programmers of this document, however +this is not required. It's also a good idea to join the Discord server +(or alternatively IRC or Matrix). + +#### Textures +For textures we use the Pixel Perfection texture pack. This is mostly +enough; however in some cases - e.g. for newer minecraft features, it's +useful to have texture artists around. If you want to make such +contributions, join our Discord server. Demands for textures will be +communicated there. + +#### Sounds +MineClone2 currently does not have a consistent way to handle sounds. +The sounds in the game come from different sources, like the SnowZone +ressource pack or minetest_game. Unfortunately, MineClone2 does not play +a sound in every situation you would get one in Minecraft. Any help with +sounds is greatly appreciated, however if you add new sounds you should +probably work together with a programmer, to write the code to actually +play these sounds in game. + +#### 3D Models +Most of the 3D Models in MineClone2 come from +[22i's repository](https://github.com/22i/minecraft-voxel-blender-models). +Similar to the textures, we need people that can make 3D Models with +Blender on demand. Many of the models have to be patched, some new +animations have to be added etc. + +#### Translations + +##### Workflow +To add/update support for your language to MineClone2, you should take +the steps documented in the section for Programmers, add/update the +translation files of the mods that you want to update. You can add +support for all mods, just some of them or only one mod; you can update +the translation file entirely or only partly; basically any effort is +valued. If your changes are small, you can also send them to developers +via E-Mail, Discord, IRC or Matrix - they will credit you appropriately. + +##### Things to note +You can use the script at `tools/check_translate_files.py` to compare +the translation files for the language you are working on with the +template files, to see what is missing and what is out of date with +the template file. However, template files are often incomplete and/or +out of date, sometimes they don't match the code. You can update the +translation files if that is required, you can also modifiy the code in +your translation PR if it's related to translation. You can also work on +multiple languages at the same time in one PR. + +#### Crediting +Asset contributions will be credited in their own respective sections in +CREDITS.md. If you have commited the results yourself, you will also be +credited in the Contributors section. + ### Profiling If you own a server, a great way to help us improve MineClone2's code is by giving us profiler results. Profiler results give us detailed From 19689dd857c047fb857489ed4385b4c5440400c6 Mon Sep 17 00:00:00 2001 From: NO11 Date: Tue, 26 Oct 2021 16:50:10 +0000 Subject: [PATCH 193/296] Use enchanted golden apple for thing banner --- mods/ITEMS/mcl_banners/patterncraft.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mods/ITEMS/mcl_banners/patterncraft.lua b/mods/ITEMS/mcl_banners/patterncraft.lua index 79778a665..767235b1e 100644 --- a/mods/ITEMS/mcl_banners/patterncraft.lua +++ b/mods/ITEMS/mcl_banners/patterncraft.lua @@ -119,8 +119,7 @@ local patterns = { name = N("@1 Thing Charge"), type = "shapeless", - -- TODO: Replace with enchanted golden apple - { e, "mcl_core:apple_gold", d }, + { e, "mcl_core:apple_gold_enchanted", d }, }, ["rhombus"] = { name = N("@1 Lozenge"), From d30e014233957a0b31f06c0e0f753ab005028282 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 27 Oct 2021 18:40:45 +0200 Subject: [PATCH 194/296] Mineclone2 -> MineClone2 --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e817f81bd..bd02346b4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -41,7 +41,7 @@ MineClone2 is developed using the version control system [git](https://git-scm.com/). If you want to contribute code to the project, it is **highly recommended** that you learn the git basics. For non-programmers and people who do not plan to contribute code to -Mineclone2, git is not required. However, git is a tool that will be +MineClone2, git is not required. However, git is a tool that will be referenced frequently because of its usefulness. As such, it is valuable in learning how git works and its terminology. It can also help you in keeping your game updated, and easily testing pull requests. @@ -91,7 +91,7 @@ behavior. * Make sure the feature you request is Minecraft 1.17 Java Edition or Optifine behavior. * Begging or excessive attention seeking does not help us in the -slightest, and may very well disrupt Mineclone2 development. It's better +slightest, and may very well disrupt MineClone2 development. It's better to put that energy into helping or researching the feature in question. After all, we're just volunteers working on our spare time. * Check whether the feature has been implemented in a newer version of From 90796ec7b44d0eab168c77cae2c205e2b296b62f Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 27 Oct 2021 18:42:11 +0200 Subject: [PATCH 195/296] can unfortunately not -> unfortunately cannot --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bd02346b4..d200085ff 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -114,7 +114,7 @@ requests that start with a `WIP:` are not done yet, and therefore might not work, so it's not very useful to try them out yet. ### Contributing assets -Due to license problems, MineClone2 can unfortunately not use +Due to license problems, MineClone2 unfortunately cannot use Minecraft's assets, therefore we are always looking for asset contributions. To contribute assets, it can be useful to learn git basics and read the section for Programmers of this document, however From 61dccfb9e529be38be73fea6cf1f90827e410e26 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 27 Oct 2021 18:44:10 +0200 Subject: [PATCH 196/296] Reword up to date guideline for feature requests --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d200085ff..482bd6c00 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -94,8 +94,8 @@ Optifine behavior. slightest, and may very well disrupt MineClone2 development. It's better to put that energy into helping or researching the feature in question. After all, we're just volunteers working on our spare time. -* Check whether the feature has been implemented in a newer version of -MineClone2, in case you are not using the latest one. +* Ensure the requested feature has not been implemented in MineClone2 +latest or development versions. ### Testing code If you want to help us with speeding up MineClone2 development and From c1934c4f3a7d720854a9ece52fc7d34213733d59 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 27 Oct 2021 18:45:37 +0200 Subject: [PATCH 197/296] Reword feature request alignment with development goals guideline --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 482bd6c00..d8929c9e5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -88,8 +88,8 @@ the bug, e.g. before the crash happened or what causes the faulty behavior. ### Requesting features -* Make sure the feature you request is Minecraft 1.17 Java Edition or -Optifine behavior. +* Ensure the requested feature fulfills our development targets and +goals. * Begging or excessive attention seeking does not help us in the slightest, and may very well disrupt MineClone2 development. It's better to put that energy into helping or researching the feature in question. From 938911e7e383e0f625574c40c49e4ce1b5f551e6 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 27 Oct 2021 18:46:58 +0200 Subject: [PATCH 198/296] even help using -> assist you use --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d8929c9e5..949b61ddb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -219,7 +219,7 @@ relatively new programmer, you can reach us on Discord, Matrix or IRC for questions about git, Lua, Minetest API, MineClone2 codebase or anything related to MineClone2. We can help you avoid writing code that would be deemed inadequeate, or help you become familiar with MineClone2 -better, or even help using development tools. +better, or assist you use development tools. ### Maintain your own code, even if alreay got merged Sometimes, your code may cause crashes or bugs - we try to avoid such From fb2a501a9c5d104096b968cb13ea97e11c75f46b Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 27 Oct 2021 18:47:38 +0200 Subject: [PATCH 199/296] Keep our guidelines -> Stick to our guidelines --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 949b61ddb..a6385f627 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -242,7 +242,7 @@ of the results) * [Official Minecraft Wiki](https://minecraft.fandom.com/wiki/Minecraft_Wiki) (Include a link to the specific page you used) -### Keep our guidelines +### Stick to our guidelines #### Git Guidelines * We use merge rather than rebase or squash merge From 4db9952a84df35d96b127b40a2e93735ae2e8b83 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 27 Oct 2021 18:48:38 +0200 Subject: [PATCH 200/296] if -> only when --- CONTRIBUTING.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a6385f627..35b3eaa3e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -338,9 +338,9 @@ MineClone2 repository. MineClone2 master - rather, do your work on a branch on your private repo, then create a pull request. This way other people can review your changes and make sure they work before they get merged. -- Merge PRs if they have recieved the necessary feedback and have been -tested to not lead to any crashes and do what they claim to do by at -least two different people. +- Merge PRs only when they have recieved the necessary feedback and have +been tested to not lead to any crashes and do what they claim to do by +at least two different people. - You may also be assigned to issues or pull requests as a developer. In this case it is your responsibility to fix the issue / review and merge the pull request when it is ready. You can From 11e364b3ec7bc472f04f6d17cc38113ea5aacd97 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 27 Oct 2021 18:52:26 +0200 Subject: [PATCH 201/296] Give development target it's own headline --- CONTRIBUTING.md | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 35b3eaa3e..c328ca371 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,10 +2,13 @@ So you want to contribute to MineClone2? Wow, thank you! :-) -But first, some things to note: +MineClone2 is maintained by Nicu and Fleckenstein. If you have any +problems or questions, contact us (See Links section below). -MineClone2's development target is to... +You can help with MineClone2's development in many different ways, +whether you're a programmer or not. +## MineClone2's development target is to... - Crucially, create a stable, moddable, free/libre clone of Minecraft based on the Minetest engine with polished features, usable in both singleplayer and multiplayer. Currently, most of **Minecraft Java @@ -21,12 +24,6 @@ well on really low spec computers. Unfortunately, due to Minecraft's mechanisms and Minetest engine's limitations along with a very small playerbase on low spec computers, optimizations are hard to investigate. -MineClone2 is maintained by Nicu and Fleckenstein. If you have any -problems or questions, contact us (See Links section below). - -You can help with MineClone2's development in many different ways, -whether you're a programmer or not. - ## Links * [Mesehub](https://git.minetest.land/MineClone2/MineClone2) * [Discord](https://discord.gg/xE4z8EEpDC) From 6fd8ff8865af2841366a730239e9babc465cb65d Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 27 Oct 2021 18:54:39 +0200 Subject: [PATCH 202/296] testing -> test --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c328ca371..56876fad1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -40,8 +40,8 @@ project, it is **highly recommended** that you learn the git basics. For non-programmers and people who do not plan to contribute code to MineClone2, git is not required. However, git is a tool that will be referenced frequently because of its usefulness. As such, it is valuable -in learning how git works and its terminology. It can also help you in -keeping your game updated, and easily testing pull requests. +in learning how git works and its terminology. It can also help you +keeping your game updated, and easily test pull requests. ## How you can help as a non-programmer From bbdd8f55eb28acf6245864f3eeff8aa0071949a6 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Thu, 28 Oct 2021 09:34:39 +0200 Subject: [PATCH 203/296] Reword 'reporting issues' part in 'testing pull requests' section --- CONTRIBUTING.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 56876fad1..de3ae536e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -103,9 +103,10 @@ programmer saying "Look, I modified the game, please apply my changes to the upstream version of the game". However, every programmer makes mistakes sometimes, some of which are hard to spot. You can help by downloading this modified version of the game and trying it out - then -you tell us whether the code works and does what it claims to do or -whether you have encountered any issues. You can find currently open -pull requests here: +tell us if the code works as expected without any issues. Ideally, you +would report issues will pull requests similar to when you were +reporting bugs that are the mainline (See Reporting bugs section). You +can find currently open pull requests here: . Note that pull requests that start with a `WIP:` are not done yet, and therefore might not work, so it's not very useful to try them out yet. From 5b37f5600504608e3cd0dbffc1c43c15a6b6c14d Mon Sep 17 00:00:00 2001 From: NO11 Date: Thu, 28 Oct 2021 09:43:14 +0000 Subject: [PATCH 204/296] Remove small gray border of buttons in creative inventory pages --- mods/HUD/mcl_inventory/creative.lua | 1339 +++++++++++++-------------- 1 file changed, 669 insertions(+), 670 deletions(-) diff --git a/mods/HUD/mcl_inventory/creative.lua b/mods/HUD/mcl_inventory/creative.lua index ff9cccf9e..2be0be4bc 100644 --- a/mods/HUD/mcl_inventory/creative.lua +++ b/mods/HUD/mcl_inventory/creative.lua @@ -1,670 +1,669 @@ -local S = minetest.get_translator(minetest.get_current_modname()) -local F = minetest.formspec_escape - --- Prepare player info table -local players = {} - --- Containing all the items for each Creative Mode tab -local inventory_lists = {} - ---local mod_player = minetest.get_modpath("mcl_player") - --- Create tables -local builtin_filter_ids = {"blocks","deco","redstone","rail","food","tools","combat","mobs","brew","matr","misc","all"} -for _, f in pairs(builtin_filter_ids) do - inventory_lists[f] = {} -end - -local function replace_enchanted_books(tbl) - for k, item in ipairs(tbl) do - if item:find("mcl_enchanting:book_enchanted") == 1 then - local _, enchantment, level = item:match("(%a+) ([_%w]+) (%d+)") - level = level and tonumber(level) - if enchantment and level then - tbl[k] = mcl_enchanting.enchant(ItemStack("mcl_enchanting:book_enchanted"), enchantment, level) - end - end - end -end - ---[[ Populate all the item tables. We only do this once. Note this code must be -executed after loading all the other mods in order to work. ]] -minetest.register_on_mods_loaded(function() - for name,def in pairs(minetest.registered_items) do - if (not def.groups.not_in_creative_inventory or def.groups.not_in_creative_inventory == 0) and def.description and def.description ~= "" then - local function is_redstone(def) - return def.mesecons or def.groups.mesecon or def.groups.mesecon_conductor_craftable or def.groups.mesecon_effecor_off - end - local function is_tool(def) - return def.groups.tool or (def.tool_capabilities and def.tool_capabilities.damage_groups == nil) - end - local function is_weapon_or_armor(def) - return def.groups.weapon or def.groups.weapon_ranged or def.groups.ammo or def.groups.combat_item or ((def.groups.armor_head or def.groups.armor_torso or def.groups.armor_legs or def.groups.armor_feet or def.groups.horse_armor) and def.groups.non_combat_armor ~= 1) - end - -- Is set to true if it was added in any category besides misc - local nonmisc = false - if def.groups.building_block then - table.insert(inventory_lists["blocks"], name) - nonmisc = true - end - if def.groups.deco_block then - table.insert(inventory_lists["deco"], name) - nonmisc = true - end - if is_redstone(def) then - table.insert(inventory_lists["redstone"], name) - nonmisc = true - end - if def.groups.transport then - table.insert(inventory_lists["rail"], name) - nonmisc = true - end - if (def.groups.food and not def.groups.brewitem) or def.groups.eatable then - table.insert(inventory_lists["food"], name) - nonmisc = true - end - if is_tool(def) then - table.insert(inventory_lists["tools"], name) - nonmisc = true - end - if is_weapon_or_armor(def) then - table.insert(inventory_lists["combat"], name) - nonmisc = true - end - if def.groups.spawn_egg == 1 then - table.insert(inventory_lists["mobs"], name) - nonmisc = true - end - if def.groups.brewitem then - table.insert(inventory_lists["brew"], name) - nonmisc = true - end - if def.groups.craftitem then - table.insert(inventory_lists["matr"], name) - nonmisc = true - end - -- Misc. category is for everything which is not in any other category - if not nonmisc then - table.insert(inventory_lists["misc"], name) - end - - table.insert(inventory_lists["all"], name) - end - end - - for ench, def in pairs(mcl_enchanting.enchantments) do - local str = "mcl_enchanting:book_enchanted " .. ench .. " " .. def.max_level - if def.inv_tool_tab then - table.insert(inventory_lists["tools"], str) - end - if def.inv_combat_tab then - table.insert(inventory_lists["combat"], str) - end - table.insert(inventory_lists["all"], str) - end - - for _, to_sort in pairs(inventory_lists) do - table.sort(to_sort) - replace_enchanted_books(to_sort) - end -end) - -local function filter_item(name, description, lang, filter) - local desc - if not lang then - desc = string.lower(description) - else - desc = string.lower(minetest.get_translated_string(lang, description)) - end - return string.find(name, filter) or string.find(desc, filter) -end - -local function set_inv_search(filter, player) - local playername = player:get_player_name() - local inv = minetest.get_inventory({type="detached", name="creative_"..playername}) - local creative_list = {} - local lang = minetest.get_player_information(playername).lang_code - for name,def in pairs(minetest.registered_items) do - if (not def.groups.not_in_creative_inventory or def.groups.not_in_creative_inventory == 0) and def.description and def.description ~= "" then - if filter_item(string.lower(def.name), def.description, lang, filter) then - table.insert(creative_list, name) - end - end - end - for ench, def in pairs(mcl_enchanting.enchantments) do - for i = 1, def.max_level do - local stack = mcl_enchanting.enchant(ItemStack("mcl_enchanting:book_enchanted"), ench, i) - if filter_item("mcl_enchanting:book_enchanted", minetest.strip_colors(stack:get_description()), lang, filter) then - table.insert(creative_list, "mcl_enchanting:book_enchanted " .. ench .. " " .. i) - end - end - end - table.sort(creative_list) - replace_enchanted_books(creative_list) - - inv:set_size("main", #creative_list) - inv:set_list("main", creative_list) -end - -local function set_inv_page(page, player) - local playername = player:get_player_name() - local inv = minetest.get_inventory({type="detached", name="creative_"..playername}) - inv:set_size("main", 0) - local creative_list = {} - if inventory_lists[page] then -- Standard filter - creative_list = inventory_lists[page] - end - inv:set_size("main", #creative_list) - inv:set_list("main", creative_list) -end - -local function init(player) - local playername = player:get_player_name() - minetest.create_detached_inventory("creative_"..playername, { - allow_move = function(inv, from_list, from_index, to_list, to_index, count, player) - if minetest.is_creative_enabled(playername) then - return count - else - return 0 - end - end, - allow_put = function(inv, listname, index, stack, player) - return 0 - end, - allow_take = function(inv, listname, index, stack, player) - if minetest.is_creative_enabled(player:get_player_name()) then - return -1 - else - return 0 - end - end, - }, playername) - set_inv_page("all", player) -end - --- Create the trash field -local trash = minetest.create_detached_inventory("trash", { - allow_put = function(inv, listname, index, stack, player) - if minetest.is_creative_enabled(player:get_player_name()) then - return stack:get_count() - else - return 0 - end - end, - on_put = function(inv, listname, index, stack, player) - inv:set_stack(listname, index, "") - end, -}) -trash:set_size("main", 1) - -local noffset = {} -- numeric tab offset -local offset = {} -- string offset: -local boffset = {} -- -local hoch = {} -local filtername = {} ---local bg = {} - -local noffset_x_start = -0.24 -local noffset_x = noffset_x_start -local noffset_y = -0.25 -local function next_noffset(id, right) - if right then - noffset[id] = { 8.94, noffset_y } - else - noffset[id] = { noffset_x, noffset_y } - noffset_x = noffset_x + 1.25 - end -end - --- Upper row -next_noffset("blocks") -next_noffset("deco") -next_noffset("redstone") -next_noffset("rail") -next_noffset("brew") -next_noffset("misc") -next_noffset("nix", true) - -noffset_x = noffset_x_start -noffset_y = 8.12 - --- Lower row -next_noffset("food") -next_noffset("tools") -next_noffset("combat") -next_noffset("mobs") -next_noffset("matr") -next_noffset("inv", true) - -for k,v in pairs(noffset) do - offset[k] = tostring(v[1]) .. "," .. tostring(v[2]) - boffset[k] = tostring(v[1]+0.19) .. "," .. tostring(v[2]+0.25) -end - -hoch["blocks"] = "" -hoch["deco"] = "" -hoch["redstone"] = "" -hoch["rail"] = "" -hoch["brew"] = "" -hoch["misc"] = "" -hoch["nix"] = "" -hoch["default"] = "" -hoch["food"] = "_down" -hoch["tools"] = "_down" -hoch["combat"] = "_down" -hoch["mobs"] = "_down" -hoch["matr"] = "_down" -hoch["inv"] = "_down" - -filtername["blocks"] = S("Building Blocks") -filtername["deco"] = S("Decoration Blocks") -filtername["redstone"] = S("Redstone") -filtername["rail"] = S("Transportation") -filtername["misc"] = S("Miscellaneous") -filtername["nix"] = S("Search Items") -filtername["food"] = S("Foodstuffs") -filtername["tools"] = S("Tools") -filtername["combat"] = S("Combat") -filtername["mobs"] = S("Mobs") -filtername["brew"] = S("Brewing") -filtername["matr"] = S("Materials") -filtername["inv"] = S("Survival Inventory") - ---local dark_bg = "crafting_creative_bg_dark.png" - ---[[local function reset_menu_item_bg() - bg["blocks"] = dark_bg - bg["deco"] = dark_bg - bg["redstone"] = dark_bg - bg["rail"] = dark_bg - bg["misc"] = dark_bg - bg["nix"] = dark_bg - bg["food"] = dark_bg - bg["tools"] = dark_bg - bg["combat"] = dark_bg - bg["mobs"] = dark_bg - bg["brew"] = dark_bg - bg["matr"] = dark_bg - bg["inv"] = dark_bg - bg["default"] = dark_bg -end]] - - -function mcl_inventory.set_creative_formspec(player, start_i, pagenum, inv_size, show, page, filter) - --reset_menu_item_bg() - pagenum = math.floor(pagenum) or 1 - - local playername = player:get_player_name() - - if not inv_size then - if page == "nix" then - local inv = minetest.get_inventory({type="detached", name="creative_"..playername}) - inv_size = inv:get_size("main") - elseif page and page ~= "inv" then - inv_size = #(inventory_lists[page]) - else - inv_size = 0 - end - end - local pagemax = math.max(1, math.floor((inv_size-1) / (9*5) + 1)) - local name = "nix" - local main_list - local listrings = "listring[detached:creative_"..playername..";main]".. - "listring[current_player;main]".. - "listring[detached:trash;main]" - - if page then - name = page - if players[playername] then - players[playername].page = page - end - end - --bg[name] = "crafting_creative_bg.png" - - local inv_bg = "crafting_inventory_creative.png" - if name == "inv" then - inv_bg = "crafting_inventory_creative_survival.png" - - -- Show armor and player image - local player_preview - if minetest.settings:get_bool("3d_player_preview", true) then - player_preview = mcl_player.get_player_formspec_model(player, 3.9, 1.4, 1.2333, 2.4666, "") - else - player_preview = "image[3.9,1.4;1.2333,2.4666;"..mcl_player.player_get_preview(player).."]" - end - - -- Background images for armor slots (hide if occupied) - local armor_slot_imgs = "" - local inv = player:get_inventory() - if inv:get_stack("armor", 2):is_empty() then - armor_slot_imgs = armor_slot_imgs .. "image[2.5,1.3;1,1;mcl_inventory_empty_armor_slot_helmet.png]" - end - if inv:get_stack("armor", 3):is_empty() then - armor_slot_imgs = armor_slot_imgs .. "image[2.5,2.75;1,1;mcl_inventory_empty_armor_slot_chestplate.png]" - end - if inv:get_stack("armor", 4):is_empty() then - armor_slot_imgs = armor_slot_imgs .. "image[5.5,1.3;1,1;mcl_inventory_empty_armor_slot_leggings.png]" - end - if inv:get_stack("armor", 5):is_empty() then - armor_slot_imgs = armor_slot_imgs .. "image[5.5,2.75;1,1;mcl_inventory_empty_armor_slot_boots.png]" - end - - -- Survival inventory slots - main_list = "list[current_player;main;0,3.75;9,3;9]".. - mcl_formspec.get_itemslot_bg(0,3.75,9,3).. - -- armor - "list[current_player;armor;2.5,1.3;1,1;1]".. - "list[current_player;armor;2.5,2.75;1,1;2]".. - "list[current_player;armor;5.5,1.3;1,1;3]".. - "list[current_player;armor;5.5,2.75;1,1;4]".. - mcl_formspec.get_itemslot_bg(2.5,1.3,1,1).. - mcl_formspec.get_itemslot_bg(2.5,2.75,1,1).. - mcl_formspec.get_itemslot_bg(5.5,1.3,1,1).. - mcl_formspec.get_itemslot_bg(5.5,2.75,1,1).. - armor_slot_imgs.. - -- player preview - player_preview.. - -- crafting guide button - "image_button[9,1;1,1;craftguide_book.png;__mcl_craftguide;]".. - "tooltip[__mcl_craftguide;"..F(S("Recipe book")).."]".. - -- help button - "image_button[9,2;1,1;doc_button_icon_lores.png;__mcl_doc;]".. - "tooltip[__mcl_doc;"..F(S("Help")).."]".. - -- skins button - "image_button[9,3;1,1;mcl_skins_button.png;__mcl_skins;]".. - "tooltip[__mcl_skins;"..F(S("Select player skin")).."]".. - -- achievements button - "image_button[9,4;1,1;mcl_achievements_button.png;__mcl_achievements;]".. - --"style_type[image_button;border=;bgimg=;bgimg_pressed=]".. - "tooltip[__mcl_achievements;"..F(S("Achievements")).."]" - - -- For shortcuts - listrings = listrings .. - "listring[detached:"..playername.."_armor;armor]".. - "listring[current_player;main]" - else - -- Creative inventory slots - main_list = "list[detached:creative_"..playername..";main;0,1.75;9,5;"..tostring(start_i).."]".. - mcl_formspec.get_itemslot_bg(0,1.75,9,5).. - -- Page buttons - "label[9.0,5.5;"..F(S("@1/@2", pagenum, pagemax)).."]".. - "image_button[9.0,6.0;0.7,0.7;crafting_creative_prev.png;creative_prev;]".. - "image_button[9.5,6.0;0.7,0.7;crafting_creative_next.png;creative_next;]" - end - - local tab_icon = { - blocks = "mcl_core:brick_block", - deco = "mcl_flowers:peony", - redstone = "mesecons:redstone", - rail = "mcl_minecarts:golden_rail", - misc = "mcl_buckets:bucket_lava", - nix = "mcl_compass:compass", - food = "mcl_core:apple", - tools = "mcl_core:axe_iron", - combat = "mcl_core:sword_gold", - mobs = "mobs_mc:cow", - brew = "mcl_potions:dragon_breath", - matr = "mcl_core:stick", - inv = "mcl_chests:chest", - } - local function tab(current_tab, this_tab) - local bg_img - if current_tab == this_tab then - bg_img = "crafting_creative_active"..hoch[this_tab]..".png" - else - bg_img = "crafting_creative_inactive"..hoch[this_tab]..".png" - end - return - "style["..this_tab..";border=false;bgimg=;bgimg_pressed=]".. - "item_image_button[" .. boffset[this_tab] ..";1,1;"..tab_icon[this_tab]..";"..this_tab..";]".. - "image[" .. offset[this_tab] .. ";1.5,1.44;" .. bg_img .. "]" .. - "image[" .. boffset[this_tab] .. ";1,1;crafting_creative_marker.png]" - end - local caption = "" - if name ~= "inv" and filtername[name] then - caption = "label[0,1.2;"..F(minetest.colorize("#313131", filtername[name])).."]" - end - - local formspec = "size[10,9.3]".. - "no_prepend[]".. - mcl_vars.gui_nonbg..mcl_vars.gui_bg_color.. - "background[-0.19,-0.25;10.5,9.87;"..inv_bg.."]".. - "label[-5,-5;"..name.."]".. - tab(name, "blocks") .. - "tooltip[blocks;"..F(filtername["blocks"]).."]".. - tab(name, "deco") .. - "tooltip[deco;"..F(filtername["deco"]).."]".. - tab(name, "redstone") .. - "tooltip[redstone;"..F(filtername["redstone"]).."]".. - tab(name, "rail") .. - "tooltip[rail;"..F(filtername["rail"]).."]".. - tab(name, "misc") .. - "tooltip[misc;"..F(filtername["misc"]).."]".. - tab(name, "nix") .. - "tooltip[nix;"..F(filtername["nix"]).."]".. - caption.. - "list[current_player;main;0,7;9,1;]".. - mcl_formspec.get_itemslot_bg(0,7,9,1).. - main_list.. - tab(name, "food") .. - "tooltip[food;"..F(filtername["food"]).."]".. - tab(name, "tools") .. - "tooltip[tools;"..F(filtername["tools"]).."]".. - tab(name, "combat") .. - "tooltip[combat;"..F(filtername["combat"]).."]".. - tab(name, "mobs") .. - "tooltip[mobs;"..F(filtername["mobs"]).."]".. - tab(name, "brew") .. - "tooltip[brew;"..F(filtername["brew"]).."]".. - tab(name, "matr") .. - "tooltip[matr;"..F(filtername["matr"]).."]".. - tab(name, "inv") .. - "tooltip[inv;"..F(filtername["inv"]).."]".. - "list[detached:trash;main;9,7;1,1;]".. - mcl_formspec.get_itemslot_bg(9,7,1,1).. - "image[9,7;1,1;crafting_creative_trash.png]".. - listrings - - if name == "nix" then - if filter == nil then - filter = "" - end - formspec = formspec .. "field[5.3,1.34;4,0.75;search;;"..minetest.formspec_escape(filter).."]" - formspec = formspec .. "field_close_on_enter[search;false]" - end - if pagenum then formspec = formspec .. "p"..tostring(pagenum) end - player:set_inventory_formspec(formspec) -end - -minetest.register_on_player_receive_fields(function(player, formname, fields) - local page = nil - - if not minetest.is_creative_enabled(player:get_player_name()) then - return - end - if formname ~= "" or fields.quit == "true" then - -- No-op if formspec closed or not player inventory (formname == "") - return - end - - local name = player:get_player_name() - - if fields.blocks then - if players[name].page == "blocks" then return end - set_inv_page("blocks",player) - page = "blocks" - elseif fields.deco then - if players[name].page == "deco" then return end - set_inv_page("deco",player) - page = "deco" - elseif fields.redstone then - if players[name].page == "redstone" then return end - set_inv_page("redstone",player) - page = "redstone" - elseif fields.rail then - if players[name].page == "rail" then return end - set_inv_page("rail",player) - page = "rail" - elseif fields.misc then - if players[name].page == "misc" then return end - set_inv_page("misc",player) - page = "misc" - elseif fields.nix then - set_inv_page("all",player) - page = "nix" - elseif fields.food then - if players[name].page == "food" then return end - set_inv_page("food",player) - page = "food" - elseif fields.tools then - if players[name].page == "tools" then return end - set_inv_page("tools",player) - page = "tools" - elseif fields.combat then - if players[name].page == "combat" then return end - set_inv_page("combat",player) - page = "combat" - elseif fields.mobs then - if players[name].page == "mobs" then return end - set_inv_page("mobs",player) - page = "mobs" - elseif fields.brew then - if players[name].page == "brew" then return end - set_inv_page("brew",player) - page = "brew" - elseif fields.matr then - if players[name].page == "matr" then return end - set_inv_page("matr",player) - page = "matr" - elseif fields.inv then - if players[name].page == "inv" then return end - page = "inv" - elseif fields.search == "" and not fields.creative_next and not fields.creative_prev then - set_inv_page("all", player) - page = "nix" - elseif fields.search and not fields.creative_next and not fields.creative_prev then - set_inv_search(string.lower(fields.search),player) - page = "nix" - end - - if page then - players[name].page = page - end - if players[name].page then - page = players[name].page - end - - -- Figure out current scroll bar from formspec - --local formspec = player:get_inventory_formspec() - - local start_i = players[name].start_i - - if fields.creative_prev then - start_i = start_i - 9*5 - elseif fields.creative_next then - start_i = start_i + 9*5 - else - -- Reset scroll bar if not scrolled - start_i = 0 - end - if start_i < 0 then - start_i = start_i + 9*5 - end - - local inv_size - if page == "nix" then - local inv = minetest.get_inventory({type="detached", name="creative_"..name}) - inv_size = inv:get_size("main") - elseif page and page ~= "inv" then - inv_size = #(inventory_lists[page]) - else - inv_size = 0 - end - - if start_i >= inv_size then - start_i = start_i - 9*5 - end - if start_i < 0 or start_i >= inv_size then - start_i = 0 - end - players[name].start_i = start_i - - local filter = "" - if not fields.nix and fields.search and fields.search ~= "" then - filter = fields.search - players[name].filter = filter - end - - mcl_inventory.set_creative_formspec(player, start_i, start_i / (9*5) + 1, inv_size, false, page, filter) -end) - - -if minetest.is_creative_enabled("") then - minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack) - -- Place infinite nodes, except for shulker boxes - local group = minetest.get_item_group(itemstack:get_name(), "shulker_box") - return group == 0 or group == nil - end) - - function minetest.handle_node_drops(pos, drops, digger) - if not digger or not digger:is_player() then - for _,item in ipairs(drops) do - minetest.add_item(pos, item) - end - end - local inv = digger:get_inventory() - if inv then - for _,item in ipairs(drops) do - if not inv:contains_item("main", item, true) then - inv:add_item("main", item) - end - end - end - end - - mcl_inventory.update_inventory_formspec = function(player) - local page - - local name = player:get_player_name() - - if players[name].page then - page = players[name].page - else - page = "nix" - end - - -- Figure out current scroll bar from formspec - --local formspec = player:get_inventory_formspec() - local start_i = players[name].start_i - - local inv_size - if page == "nix" then - local inv = minetest.get_inventory({type="detached", name="creative_"..name}) - inv_size = inv:get_size("main") - elseif page and page ~= "inv" then - inv_size = #(inventory_lists[page]) - else - inv_size = 0 - end - - local filter = players[name].filter - if filter == nil then - filter = "" - end - - mcl_inventory.set_creative_formspec(player, start_i, start_i / (9*5) + 1, inv_size, false, page, filter) - end -end - -minetest.register_on_joinplayer(function(player) - -- Initialize variables and inventory - local name = player:get_player_name() - if not players[name] then - players[name] = {} - players[name].page = "nix" - players[name].filter = "" - players[name].start_i = 0 - end - init(player) - mcl_inventory.set_creative_formspec(player, 0, 1, nil, false, "nix", "") -end) +local S = minetest.get_translator(minetest.get_current_modname()) +local F = minetest.formspec_escape + +-- Prepare player info table +local players = {} + +-- Containing all the items for each Creative Mode tab +local inventory_lists = {} + +--local mod_player = minetest.get_modpath("mcl_player") + +-- Create tables +local builtin_filter_ids = {"blocks","deco","redstone","rail","food","tools","combat","mobs","brew","matr","misc","all"} +for _, f in pairs(builtin_filter_ids) do + inventory_lists[f] = {} +end + +local function replace_enchanted_books(tbl) + for k, item in ipairs(tbl) do + if item:find("mcl_enchanting:book_enchanted") == 1 then + local _, enchantment, level = item:match("(%a+) ([_%w]+) (%d+)") + level = level and tonumber(level) + if enchantment and level then + tbl[k] = mcl_enchanting.enchant(ItemStack("mcl_enchanting:book_enchanted"), enchantment, level) + end + end + end +end + +--[[ Populate all the item tables. We only do this once. Note this code must be +executed after loading all the other mods in order to work. ]] +minetest.register_on_mods_loaded(function() + for name,def in pairs(minetest.registered_items) do + if (not def.groups.not_in_creative_inventory or def.groups.not_in_creative_inventory == 0) and def.description and def.description ~= "" then + local function is_redstone(def) + return def.mesecons or def.groups.mesecon or def.groups.mesecon_conductor_craftable or def.groups.mesecon_effecor_off + end + local function is_tool(def) + return def.groups.tool or (def.tool_capabilities and def.tool_capabilities.damage_groups == nil) + end + local function is_weapon_or_armor(def) + return def.groups.weapon or def.groups.weapon_ranged or def.groups.ammo or def.groups.combat_item or ((def.groups.armor_head or def.groups.armor_torso or def.groups.armor_legs or def.groups.armor_feet or def.groups.horse_armor) and def.groups.non_combat_armor ~= 1) + end + -- Is set to true if it was added in any category besides misc + local nonmisc = false + if def.groups.building_block then + table.insert(inventory_lists["blocks"], name) + nonmisc = true + end + if def.groups.deco_block then + table.insert(inventory_lists["deco"], name) + nonmisc = true + end + if is_redstone(def) then + table.insert(inventory_lists["redstone"], name) + nonmisc = true + end + if def.groups.transport then + table.insert(inventory_lists["rail"], name) + nonmisc = true + end + if (def.groups.food and not def.groups.brewitem) or def.groups.eatable then + table.insert(inventory_lists["food"], name) + nonmisc = true + end + if is_tool(def) then + table.insert(inventory_lists["tools"], name) + nonmisc = true + end + if is_weapon_or_armor(def) then + table.insert(inventory_lists["combat"], name) + nonmisc = true + end + if def.groups.spawn_egg == 1 then + table.insert(inventory_lists["mobs"], name) + nonmisc = true + end + if def.groups.brewitem then + table.insert(inventory_lists["brew"], name) + nonmisc = true + end + if def.groups.craftitem then + table.insert(inventory_lists["matr"], name) + nonmisc = true + end + -- Misc. category is for everything which is not in any other category + if not nonmisc then + table.insert(inventory_lists["misc"], name) + end + + table.insert(inventory_lists["all"], name) + end + end + + for ench, def in pairs(mcl_enchanting.enchantments) do + local str = "mcl_enchanting:book_enchanted " .. ench .. " " .. def.max_level + if def.inv_tool_tab then + table.insert(inventory_lists["tools"], str) + end + if def.inv_combat_tab then + table.insert(inventory_lists["combat"], str) + end + table.insert(inventory_lists["all"], str) + end + + for _, to_sort in pairs(inventory_lists) do + table.sort(to_sort) + replace_enchanted_books(to_sort) + end +end) + +local function filter_item(name, description, lang, filter) + local desc + if not lang then + desc = string.lower(description) + else + desc = string.lower(minetest.get_translated_string(lang, description)) + end + return string.find(name, filter) or string.find(desc, filter) +end + +local function set_inv_search(filter, player) + local playername = player:get_player_name() + local inv = minetest.get_inventory({type="detached", name="creative_"..playername}) + local creative_list = {} + local lang = minetest.get_player_information(playername).lang_code + for name,def in pairs(minetest.registered_items) do + if (not def.groups.not_in_creative_inventory or def.groups.not_in_creative_inventory == 0) and def.description and def.description ~= "" then + if filter_item(string.lower(def.name), def.description, lang, filter) then + table.insert(creative_list, name) + end + end + end + for ench, def in pairs(mcl_enchanting.enchantments) do + for i = 1, def.max_level do + local stack = mcl_enchanting.enchant(ItemStack("mcl_enchanting:book_enchanted"), ench, i) + if filter_item("mcl_enchanting:book_enchanted", minetest.strip_colors(stack:get_description()), lang, filter) then + table.insert(creative_list, "mcl_enchanting:book_enchanted " .. ench .. " " .. i) + end + end + end + table.sort(creative_list) + replace_enchanted_books(creative_list) + + inv:set_size("main", #creative_list) + inv:set_list("main", creative_list) +end + +local function set_inv_page(page, player) + local playername = player:get_player_name() + local inv = minetest.get_inventory({type="detached", name="creative_"..playername}) + inv:set_size("main", 0) + local creative_list = {} + if inventory_lists[page] then -- Standard filter + creative_list = inventory_lists[page] + end + inv:set_size("main", #creative_list) + inv:set_list("main", creative_list) +end + +local function init(player) + local playername = player:get_player_name() + minetest.create_detached_inventory("creative_"..playername, { + allow_move = function(inv, from_list, from_index, to_list, to_index, count, player) + if minetest.is_creative_enabled(playername) then + return count + else + return 0 + end + end, + allow_put = function(inv, listname, index, stack, player) + return 0 + end, + allow_take = function(inv, listname, index, stack, player) + if minetest.is_creative_enabled(player:get_player_name()) then + return -1 + else + return 0 + end + end, + }, playername) + set_inv_page("all", player) +end + +-- Create the trash field +local trash = minetest.create_detached_inventory("trash", { + allow_put = function(inv, listname, index, stack, player) + if minetest.is_creative_enabled(player:get_player_name()) then + return stack:get_count() + else + return 0 + end + end, + on_put = function(inv, listname, index, stack, player) + inv:set_stack(listname, index, "") + end, +}) +trash:set_size("main", 1) + +local noffset = {} -- numeric tab offset +local offset = {} -- string offset: +local boffset = {} -- +local hoch = {} +local filtername = {} +--local bg = {} + +local noffset_x_start = -0.24 +local noffset_x = noffset_x_start +local noffset_y = -0.25 +local function next_noffset(id, right) + if right then + noffset[id] = { 8.94, noffset_y } + else + noffset[id] = { noffset_x, noffset_y } + noffset_x = noffset_x + 1.25 + end +end + +-- Upper row +next_noffset("blocks") +next_noffset("deco") +next_noffset("redstone") +next_noffset("rail") +next_noffset("brew") +next_noffset("misc") +next_noffset("nix", true) + +noffset_x = noffset_x_start +noffset_y = 8.12 + +-- Lower row +next_noffset("food") +next_noffset("tools") +next_noffset("combat") +next_noffset("mobs") +next_noffset("matr") +next_noffset("inv", true) + +for k,v in pairs(noffset) do + offset[k] = tostring(v[1]) .. "," .. tostring(v[2]) + boffset[k] = tostring(v[1]+0.19) .. "," .. tostring(v[2]+0.25) +end + +hoch["blocks"] = "" +hoch["deco"] = "" +hoch["redstone"] = "" +hoch["rail"] = "" +hoch["brew"] = "" +hoch["misc"] = "" +hoch["nix"] = "" +hoch["default"] = "" +hoch["food"] = "_down" +hoch["tools"] = "_down" +hoch["combat"] = "_down" +hoch["mobs"] = "_down" +hoch["matr"] = "_down" +hoch["inv"] = "_down" + +filtername["blocks"] = S("Building Blocks") +filtername["deco"] = S("Decoration Blocks") +filtername["redstone"] = S("Redstone") +filtername["rail"] = S("Transportation") +filtername["misc"] = S("Miscellaneous") +filtername["nix"] = S("Search Items") +filtername["food"] = S("Foodstuffs") +filtername["tools"] = S("Tools") +filtername["combat"] = S("Combat") +filtername["mobs"] = S("Mobs") +filtername["brew"] = S("Brewing") +filtername["matr"] = S("Materials") +filtername["inv"] = S("Survival Inventory") + +--local dark_bg = "crafting_creative_bg_dark.png" + +--[[local function reset_menu_item_bg() + bg["blocks"] = dark_bg + bg["deco"] = dark_bg + bg["redstone"] = dark_bg + bg["rail"] = dark_bg + bg["misc"] = dark_bg + bg["nix"] = dark_bg + bg["food"] = dark_bg + bg["tools"] = dark_bg + bg["combat"] = dark_bg + bg["mobs"] = dark_bg + bg["brew"] = dark_bg + bg["matr"] = dark_bg + bg["inv"] = dark_bg + bg["default"] = dark_bg +end]] + + +function mcl_inventory.set_creative_formspec(player, start_i, pagenum, inv_size, show, page, filter) + --reset_menu_item_bg() + pagenum = math.floor(pagenum) or 1 + + local playername = player:get_player_name() + + if not inv_size then + if page == "nix" then + local inv = minetest.get_inventory({type="detached", name="creative_"..playername}) + inv_size = inv:get_size("main") + elseif page and page ~= "inv" then + inv_size = #(inventory_lists[page]) + else + inv_size = 0 + end + end + local pagemax = math.max(1, math.floor((inv_size-1) / (9*5) + 1)) + local name = "nix" + local main_list + local listrings = "listring[detached:creative_"..playername..";main]".. + "listring[current_player;main]".. + "listring[detached:trash;main]" + + if page then + name = page + if players[playername] then + players[playername].page = page + end + end + --bg[name] = "crafting_creative_bg.png" + + local inv_bg = "crafting_inventory_creative.png" + if name == "inv" then + inv_bg = "crafting_inventory_creative_survival.png" + + -- Show armor and player image + local player_preview + if minetest.settings:get_bool("3d_player_preview", true) then + player_preview = mcl_player.get_player_formspec_model(player, 3.9, 1.4, 1.2333, 2.4666, "") + else + player_preview = "image[3.9,1.4;1.2333,2.4666;"..mcl_player.player_get_preview(player).."]" + end + + -- Background images for armor slots (hide if occupied) + local armor_slot_imgs = "" + local inv = player:get_inventory() + if inv:get_stack("armor", 2):is_empty() then + armor_slot_imgs = armor_slot_imgs .. "image[2.5,1.3;1,1;mcl_inventory_empty_armor_slot_helmet.png]" + end + if inv:get_stack("armor", 3):is_empty() then + armor_slot_imgs = armor_slot_imgs .. "image[2.5,2.75;1,1;mcl_inventory_empty_armor_slot_chestplate.png]" + end + if inv:get_stack("armor", 4):is_empty() then + armor_slot_imgs = armor_slot_imgs .. "image[5.5,1.3;1,1;mcl_inventory_empty_armor_slot_leggings.png]" + end + if inv:get_stack("armor", 5):is_empty() then + armor_slot_imgs = armor_slot_imgs .. "image[5.5,2.75;1,1;mcl_inventory_empty_armor_slot_boots.png]" + end + + -- Survival inventory slots + main_list = "list[current_player;main;0,3.75;9,3;9]".. + mcl_formspec.get_itemslot_bg(0,3.75,9,3).. + -- armor + "list[current_player;armor;2.5,1.3;1,1;1]".. + "list[current_player;armor;2.5,2.75;1,1;2]".. + "list[current_player;armor;5.5,1.3;1,1;3]".. + "list[current_player;armor;5.5,2.75;1,1;4]".. + mcl_formspec.get_itemslot_bg(2.5,1.3,1,1).. + mcl_formspec.get_itemslot_bg(2.5,2.75,1,1).. + mcl_formspec.get_itemslot_bg(5.5,1.3,1,1).. + mcl_formspec.get_itemslot_bg(5.5,2.75,1,1).. + armor_slot_imgs.. + -- player preview + player_preview.. + -- crafting guide button + "image_button[9,1;1,1;craftguide_book.png;__mcl_craftguide;]".. + "tooltip[__mcl_craftguide;"..F(S("Recipe book")).."]".. + -- help button + "image_button[9,2;1,1;doc_button_icon_lores.png;__mcl_doc;]".. + "tooltip[__mcl_doc;"..F(S("Help")).."]".. + -- skins button + "image_button[9,3;1,1;mcl_skins_button.png;__mcl_skins;]".. + "tooltip[__mcl_skins;"..F(S("Select player skin")).."]".. + -- achievements button + "image_button[9,4;1,1;mcl_achievements_button.png;__mcl_achievements;]".. + --"style_type[image_button;border=;bgimg=;bgimg_pressed=]".. + "tooltip[__mcl_achievements;"..F(S("Achievements")).."]" + + -- For shortcuts + listrings = listrings .. + "listring[detached:"..playername.."_armor;armor]".. + "listring[current_player;main]" + else + -- Creative inventory slots + main_list = "list[detached:creative_"..playername..";main;0,1.75;9,5;"..tostring(start_i).."]".. + mcl_formspec.get_itemslot_bg(0,1.75,9,5).. + -- Page buttons + "label[9.0,5.5;"..F(S("@1/@2", pagenum, pagemax)).."]".. + "image_button[9.0,6.0;0.7,0.7;crafting_creative_prev.png;creative_prev;]".. + "image_button[9.5,6.0;0.7,0.7;crafting_creative_next.png;creative_next;]" + end + + local tab_icon = { + blocks = "mcl_core:brick_block", + deco = "mcl_flowers:peony", + redstone = "mesecons:redstone", + rail = "mcl_minecarts:golden_rail", + misc = "mcl_buckets:bucket_lava", + nix = "mcl_compass:compass", + food = "mcl_core:apple", + tools = "mcl_core:axe_iron", + combat = "mcl_core:sword_gold", + mobs = "mobs_mc:cow", + brew = "mcl_potions:dragon_breath", + matr = "mcl_core:stick", + inv = "mcl_chests:chest", + } + local function tab(current_tab, this_tab) + local bg_img + if current_tab == this_tab then + bg_img = "crafting_creative_active"..hoch[this_tab]..".png" + else + bg_img = "crafting_creative_inactive"..hoch[this_tab]..".png" + end + return + "style["..this_tab..";border=false;bgimg=;bgimg_pressed=]".. + "item_image_button[" .. boffset[this_tab] ..";1,1;"..tab_icon[this_tab]..";"..this_tab..";]".. + "image[" .. offset[this_tab] .. ";1.5,1.44;" .. bg_img .. "]" + end + local caption = "" + if name ~= "inv" and filtername[name] then + caption = "label[0,1.2;"..F(minetest.colorize("#313131", filtername[name])).."]" + end + + local formspec = "size[10,9.3]".. + "no_prepend[]".. + mcl_vars.gui_nonbg..mcl_vars.gui_bg_color.. + "background[-0.19,-0.25;10.5,9.87;"..inv_bg.."]".. + "label[-5,-5;"..name.."]".. + tab(name, "blocks") .. + "tooltip[blocks;"..F(filtername["blocks"]).."]".. + tab(name, "deco") .. + "tooltip[deco;"..F(filtername["deco"]).."]".. + tab(name, "redstone") .. + "tooltip[redstone;"..F(filtername["redstone"]).."]".. + tab(name, "rail") .. + "tooltip[rail;"..F(filtername["rail"]).."]".. + tab(name, "misc") .. + "tooltip[misc;"..F(filtername["misc"]).."]".. + tab(name, "nix") .. + "tooltip[nix;"..F(filtername["nix"]).."]".. + caption.. + "list[current_player;main;0,7;9,1;]".. + mcl_formspec.get_itemslot_bg(0,7,9,1).. + main_list.. + tab(name, "food") .. + "tooltip[food;"..F(filtername["food"]).."]".. + tab(name, "tools") .. + "tooltip[tools;"..F(filtername["tools"]).."]".. + tab(name, "combat") .. + "tooltip[combat;"..F(filtername["combat"]).."]".. + tab(name, "mobs") .. + "tooltip[mobs;"..F(filtername["mobs"]).."]".. + tab(name, "brew") .. + "tooltip[brew;"..F(filtername["brew"]).."]".. + tab(name, "matr") .. + "tooltip[matr;"..F(filtername["matr"]).."]".. + tab(name, "inv") .. + "tooltip[inv;"..F(filtername["inv"]).."]".. + "list[detached:trash;main;9,7;1,1;]".. + mcl_formspec.get_itemslot_bg(9,7,1,1).. + "image[9,7;1,1;crafting_creative_trash.png]".. + listrings + + if name == "nix" then + if filter == nil then + filter = "" + end + formspec = formspec .. "field[5.3,1.34;4,0.75;search;;"..minetest.formspec_escape(filter).."]" + formspec = formspec .. "field_close_on_enter[search;false]" + end + if pagenum then formspec = formspec .. "p"..tostring(pagenum) end + player:set_inventory_formspec(formspec) +end + +minetest.register_on_player_receive_fields(function(player, formname, fields) + local page = nil + + if not minetest.is_creative_enabled(player:get_player_name()) then + return + end + if formname ~= "" or fields.quit == "true" then + -- No-op if formspec closed or not player inventory (formname == "") + return + end + + local name = player:get_player_name() + + if fields.blocks then + if players[name].page == "blocks" then return end + set_inv_page("blocks",player) + page = "blocks" + elseif fields.deco then + if players[name].page == "deco" then return end + set_inv_page("deco",player) + page = "deco" + elseif fields.redstone then + if players[name].page == "redstone" then return end + set_inv_page("redstone",player) + page = "redstone" + elseif fields.rail then + if players[name].page == "rail" then return end + set_inv_page("rail",player) + page = "rail" + elseif fields.misc then + if players[name].page == "misc" then return end + set_inv_page("misc",player) + page = "misc" + elseif fields.nix then + set_inv_page("all",player) + page = "nix" + elseif fields.food then + if players[name].page == "food" then return end + set_inv_page("food",player) + page = "food" + elseif fields.tools then + if players[name].page == "tools" then return end + set_inv_page("tools",player) + page = "tools" + elseif fields.combat then + if players[name].page == "combat" then return end + set_inv_page("combat",player) + page = "combat" + elseif fields.mobs then + if players[name].page == "mobs" then return end + set_inv_page("mobs",player) + page = "mobs" + elseif fields.brew then + if players[name].page == "brew" then return end + set_inv_page("brew",player) + page = "brew" + elseif fields.matr then + if players[name].page == "matr" then return end + set_inv_page("matr",player) + page = "matr" + elseif fields.inv then + if players[name].page == "inv" then return end + page = "inv" + elseif fields.search == "" and not fields.creative_next and not fields.creative_prev then + set_inv_page("all", player) + page = "nix" + elseif fields.search and not fields.creative_next and not fields.creative_prev then + set_inv_search(string.lower(fields.search),player) + page = "nix" + end + + if page then + players[name].page = page + end + if players[name].page then + page = players[name].page + end + + -- Figure out current scroll bar from formspec + --local formspec = player:get_inventory_formspec() + + local start_i = players[name].start_i + + if fields.creative_prev then + start_i = start_i - 9*5 + elseif fields.creative_next then + start_i = start_i + 9*5 + else + -- Reset scroll bar if not scrolled + start_i = 0 + end + if start_i < 0 then + start_i = start_i + 9*5 + end + + local inv_size + if page == "nix" then + local inv = minetest.get_inventory({type="detached", name="creative_"..name}) + inv_size = inv:get_size("main") + elseif page and page ~= "inv" then + inv_size = #(inventory_lists[page]) + else + inv_size = 0 + end + + if start_i >= inv_size then + start_i = start_i - 9*5 + end + if start_i < 0 or start_i >= inv_size then + start_i = 0 + end + players[name].start_i = start_i + + local filter = "" + if not fields.nix and fields.search and fields.search ~= "" then + filter = fields.search + players[name].filter = filter + end + + mcl_inventory.set_creative_formspec(player, start_i, start_i / (9*5) + 1, inv_size, false, page, filter) +end) + + +if minetest.is_creative_enabled("") then + minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack) + -- Place infinite nodes, except for shulker boxes + local group = minetest.get_item_group(itemstack:get_name(), "shulker_box") + return group == 0 or group == nil + end) + + function minetest.handle_node_drops(pos, drops, digger) + if not digger or not digger:is_player() then + for _,item in ipairs(drops) do + minetest.add_item(pos, item) + end + end + local inv = digger:get_inventory() + if inv then + for _,item in ipairs(drops) do + if not inv:contains_item("main", item, true) then + inv:add_item("main", item) + end + end + end + end + + mcl_inventory.update_inventory_formspec = function(player) + local page + + local name = player:get_player_name() + + if players[name].page then + page = players[name].page + else + page = "nix" + end + + -- Figure out current scroll bar from formspec + --local formspec = player:get_inventory_formspec() + local start_i = players[name].start_i + + local inv_size + if page == "nix" then + local inv = minetest.get_inventory({type="detached", name="creative_"..name}) + inv_size = inv:get_size("main") + elseif page and page ~= "inv" then + inv_size = #(inventory_lists[page]) + else + inv_size = 0 + end + + local filter = players[name].filter + if filter == nil then + filter = "" + end + + mcl_inventory.set_creative_formspec(player, start_i, start_i / (9*5) + 1, inv_size, false, page, filter) + end +end + +minetest.register_on_joinplayer(function(player) + -- Initialize variables and inventory + local name = player:get_player_name() + if not players[name] then + players[name] = {} + players[name].page = "nix" + players[name].filter = "" + players[name].start_i = 0 + end + init(player) + mcl_inventory.set_creative_formspec(player, 0, 1, nil, false, "nix", "") +end) From 28b73042114ae4a7f1077d41d1e0cff8d224be64 Mon Sep 17 00:00:00 2001 From: NO11 Date: Tue, 2 Nov 2021 22:55:49 +0100 Subject: [PATCH 205/296] Break minecart it's near a cactus (Fix #924) --- mods/ENTITIES/mcl_minecarts/init.lua | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/mods/ENTITIES/mcl_minecarts/init.lua b/mods/ENTITIES/mcl_minecarts/init.lua index 4d3873cc2..119a13523 100644 --- a/mods/ENTITIES/mcl_minecarts/init.lua +++ b/mods/ENTITIES/mcl_minecarts/init.lua @@ -198,7 +198,20 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o else self._last_float_check = self._last_float_check + dtime end - local pos, rou_pos, node + + local pos, rou_pos, node = self.object:get_pos() + local r = 0.6 + for _, node_pos in pairs({{r, 0}, {0, r}, {-r, 0}, {0, -r}}) do + if minetest.get_node(vector.offset(pos, node_pos[1], 0, node_pos[2])).name == "mcl_core:cactus" then + detach_driver(self) + for d = 1, #drop do + minetest.add_item(pos, drop[d]) + end + self.object:remove() + return + end + end + -- Drop minecart if it isn't on a rail anymore if self._last_float_check >= mcl_minecarts.check_float_time then pos = self.object:get_pos() From db696d0e2b41e41c5859c0748a046144c3cf5981 Mon Sep 17 00:00:00 2001 From: Artem Arbatsky Date: Fri, 24 Sep 2021 16:50:54 +0500 Subject: [PATCH 206/296] Add missing call for on_die function --- mods/ENTITIES/mcl_mobs/api/mob_functions/death_logic.lua | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/death_logic.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/death_logic.lua index 45e46d3db..03e6789ed 100644 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/death_logic.lua +++ b/mods/ENTITIES/mcl_mobs/api/mob_functions/death_logic.lua @@ -122,7 +122,10 @@ mobs.death_logic = function(self, dtime) if self.death_animation_timer >= 1.25 then item_drop(self,false,1) mobs.death_effect(self) - mcl_experience.throw_experience(self.object:get_pos(), math_random(self.xp_min, self.xp_max)) + mcl_experience.throw_experience(self.object:get_pos(), math_random(self.xp_min, self.xp_max)) + if self.on_die then + self.on_die(self, self.object:get_pos()) + end self.object:remove() return end @@ -155,4 +158,4 @@ mobs.death_logic = function(self, dtime) if self.pause_timer <= 0 then mobs.set_velocity(self,0) end -end \ No newline at end of file +end From 2607d40f1fcb4680f324aea4ad733fbe48a0fbfa Mon Sep 17 00:00:00 2001 From: Nils Dagsson Moskopp Date: Sat, 17 Jul 2021 07:23:20 +0200 Subject: [PATCH 207/296] Add script to show packets count from debug logs Mineclonia has inherited mods from MineClone 2 that send a lot of network packets. This behaviour wastes bandwith and is most likely a major reason for the unusually high amount of lag that MineClone2 and Mineclonia have. Many network packets that are sent by Mineclonia are entirely useless. Analyzing minetest log files to figure out what kind of packets are sent and how often is a first step in getting rid of useless traffic. --- tools/analyze-packet-spam | 60 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100755 tools/analyze-packet-spam diff --git a/tools/analyze-packet-spam b/tools/analyze-packet-spam new file mode 100755 index 000000000..310616fd9 --- /dev/null +++ b/tools/analyze-packet-spam @@ -0,0 +1,60 @@ +#!/bin/sh -eu +# analyze-packet-spam – show minetest client packet count per second +# Copyright © 2021 Nils Dagsson Moskopp (erlehmann) + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. + +# Dieses Programm hat das Ziel, die Medienkompetenz der Leser zu +# steigern. Gelegentlich packe ich sogar einen handfesten Buffer +# Overflow oder eine Format String Vulnerability zwischen die anderen +# Codezeilen und schreibe das auch nicht dran. + +# This script takes a minetest log with at least INFO log level and +# outputs the MINETEST network protocol packet count per second. + +# To collect such a log file of minetest running for 10 minutes, run: +# timeout 600 minetest --info >log.txt 2>&1 >/dev/null + +# To get packet counts from that file, run: +# ./analyze-packet-spam "${TEMPFILE}" + +TIMESTAMP_START=$( <"${TEMPFILE}" head -n1 |cut -d' ' -f1 ) +TIMESTAMP_END=$( <"${TEMPFILE}" tail -n1 |cut -d' ' -f1 ) +DURATION=$(( 30 + ${TIMESTAMP_END} - ${TIMESTAMP_START} )) + +PACKET_NAME_SEEN='' +<"${TEMPFILE}" tac \ + |while read _ PACKET_NAME PACKET_COUNT; do + case "${PACKET_NAME_SEEN}" in + *"${PACKET_NAME}"*) + ;; + *) + PACKET_COUNT_PER_SECOND=$( + printf '1k %s %s /p' "${PACKET_COUNT}" "${DURATION}" \ + |dc + ) + printf '%s\t%s\n' "${PACKET_COUNT_PER_SECOND}" "${PACKET_NAME}" + PACKET_NAME_SEEN="${PACKET_NAME_SEEN} ${PACKET_NAME}" + ;; + esac + done + +unlink "${TEMPFILE}" From 148575a05b8d0204155e0d5ce4cf1dcd45490f19 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 3 Nov 2021 16:28:13 +0100 Subject: [PATCH 208/296] Remove unused hud_manager.hud_exists function --- mods/HUD/mcl_experience/init.lua | 9 --------- 1 file changed, 9 deletions(-) diff --git a/mods/HUD/mcl_experience/init.lua b/mods/HUD/mcl_experience/init.lua index e514ffc19..b7175ccfb 100644 --- a/mods/HUD/mcl_experience/init.lua +++ b/mods/HUD/mcl_experience/init.lua @@ -116,15 +116,6 @@ function hud_manager.change_hud(data) end end --- gets if hud exists -function hud_manager.hud_exists(player,hud_name) - local name = player:get_player_name() - if player_huds[name] and player_huds[name][hud_name] then - return true - else - return false - end -end ------------------- -- saves specific users data for when they relog From a4e73886d566d2718ed6700731dd57198faa5744 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 3 Nov 2021 19:36:57 +0100 Subject: [PATCH 209/296] Rework XP API --- mods/ENTITIES/mcl_item_entity/init.lua | 4 +- .../api/mob_functions/death_logic.lua | 4 +- mods/ENTITIES/mobs_mc/ender_dragon.lua | 2 +- mods/HUD/mcl_experience/bottle.lua | 63 ++ mods/HUD/mcl_experience/command.lua | 39 + mods/HUD/mcl_experience/init.lua | 723 ++++-------------- mods/HUD/mcl_experience/orb.lua | 220 ++++++ .../{experience.ogg => mcl_experience.ogg} | Bin ...vel_up.ogg => mcl_experience_level_up.ogg} | Bin ...erience_bar.png => mcl_experience_bar.png} | Bin ....png => mcl_experience_bar_background.png} | Bin ...erience_orb.png => mcl_experience_orb.png} | Bin mods/ITEMS/mcl_enchanting/enchantments.lua | 43 ++ mods/ITEMS/mcl_enchanting/engine.lua | 6 +- mods/ITEMS/mcl_fishing/init.lua | 6 +- mods/ITEMS/mcl_furnaces/init.lua | 4 +- mods/ITEMS/mcl_mobspawners/init.lua | 2 +- 17 files changed, 538 insertions(+), 578 deletions(-) create mode 100644 mods/HUD/mcl_experience/bottle.lua create mode 100644 mods/HUD/mcl_experience/command.lua create mode 100644 mods/HUD/mcl_experience/orb.lua rename mods/HUD/mcl_experience/sounds/{experience.ogg => mcl_experience.ogg} (100%) rename mods/HUD/mcl_experience/sounds/{level_up.ogg => mcl_experience_level_up.ogg} (100%) rename mods/HUD/mcl_experience/textures/{experience_bar.png => mcl_experience_bar.png} (100%) rename mods/HUD/mcl_experience/textures/{experience_bar_background.png => mcl_experience_bar_background.png} (100%) rename mods/HUD/mcl_experience/textures/{experience_orb.png => mcl_experience_orb.png} (100%) diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index cfd141f04..678f8e2b7 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -290,10 +290,10 @@ function minetest.handle_node_drops(pos, drops, digger) end end - if digger and mcl_experience.throw_experience and not silk_touch_drop then + if digger and mcl_experience.throw_xp and not silk_touch_drop then local experience_amount = minetest.get_item_group(dug_node.name,"xp") if experience_amount > 0 then - mcl_experience.throw_experience(pos, experience_amount) + mcl_experience.throw_xp(pos, experience_amount) end end diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/death_logic.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/death_logic.lua index 45e46d3db..27d0030ea 100644 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/death_logic.lua +++ b/mods/ENTITIES/mcl_mobs/api/mob_functions/death_logic.lua @@ -122,7 +122,7 @@ mobs.death_logic = function(self, dtime) if self.death_animation_timer >= 1.25 then item_drop(self,false,1) mobs.death_effect(self) - mcl_experience.throw_experience(self.object:get_pos(), math_random(self.xp_min, self.xp_max)) + mcl_experience.throw_xp(self.object:get_pos(), math_random(self.xp_min, self.xp_max)) self.object:remove() return end @@ -155,4 +155,4 @@ mobs.death_logic = function(self, dtime) if self.pause_timer <= 0 then mobs.set_velocity(self,0) end -end \ No newline at end of file +end diff --git a/mods/ENTITIES/mobs_mc/ender_dragon.lua b/mods/ENTITIES/mobs_mc/ender_dragon.lua index bafb3f84a..3634e20f4 100644 --- a/mods/ENTITIES/mobs_mc/ender_dragon.lua +++ b/mods/ENTITIES/mobs_mc/ender_dragon.lua @@ -103,7 +103,7 @@ mobs:register_mob("mobs_mc:enderdragon", { mcl_portals.spawn_gateway_portal() mcl_structures.call_struct(self._portal_pos, "end_exit_portal_open") if self._initial then - mcl_experience.throw_experience(pos, 11500) -- 500 + 11500 = 12000 + mcl_experience.throw_xp(pos, 11500) -- 500 + 11500 = 12000 minetest.set_node(vector.add(self._portal_pos, vector.new(3, 5, 3)), {name = mobs_mc.items.dragon_egg}) end end diff --git a/mods/HUD/mcl_experience/bottle.lua b/mods/HUD/mcl_experience/bottle.lua new file mode 100644 index 000000000..10e42a57d --- /dev/null +++ b/mods/HUD/mcl_experience/bottle.lua @@ -0,0 +1,63 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +minetest.register_entity("mcl_experience:bottle",{ + textures = {"mcl_experience_bottle.png"}, + hp_max = 1, + visual_size = {x = 0.35, y = 0.35}, + collisionbox = {-0.1, -0.1, -0.1, 0.1, 0.1, 0.1}, + pointable = false, + on_step = function(self, dtime) + local pos = self.object:get_pos() + local node = minetest.get_node(pos) + local n = node.name + if n ~= "air" and n ~= "mcl_portals:portal" and n ~= "mcl_portals:portal_end" and minetest.get_item_group(n, "liquid") == 0 then + minetest.sound_play("mcl_potions_breaking_glass", {pos = pos, max_hear_distance = 16, gain = 1}) + mcl_experience.throw_xp(pos, math.random(3, 11)) + minetest.add_particlespawner({ + amount = 50, + time = 0.1, + minpos = vector.add(pos, vector.new(-0.1, 0.5, -0.1)), + maxpos = vector.add(pos, vector.new( 0.1, 0.6, 0.1)), + minvel = vector.new(-2, 0, -2), + maxvel = vector.new( 2, 2, 2), + minacc = vector.new(0, 0, 0), + maxacc = vector.new(0, 0, 0), + minexptime = 0.5, + maxexptime = 1.25, + minsize = 1, + maxsize = 2, + collisiondetection = true, + vertical = false, + texture = "mcl_particles_effect.png^[colorize:blue:127", + }) + self.object:remove() + end + end, +}) + +local function throw_xp_bottle(pos, dir, velocity) + minetest.sound_play("mcl_throwing_throw", {pos = pos, gain = 0.4, max_hear_distance = 16}, true) + local obj = minetest.add_entity(pos, "mcl_experience:bottle") + obj:set_velocity(vector.multiply(dir, velocity)) + local acceleration = vector.multiply(dir, -3) + acceleration.y = -9.81 + obj:set_acceleration(acceleration) +end + +minetest.register_craftitem("mcl_experience:bottle", { + description = "Bottle o' Enchanting", + inventory_image = "mcl_experience_bottle.png", + wield_image = "mcl_experience_bottle.png", + stack_max = 64, + on_use = function(itemstack, placer, pointed_thing) + throw_xp_bottle(vector.add(placer:get_pos(), vector.new(0, 1.5, 0)), placer:get_look_dir(), 10) + if not minetest.is_creative_enabled(placer:get_player_name()) then + itemstack:take_item() + end + return itemstack + end, + _on_dispense = function(_, pos, _, _, dir) + throw_xp_bottle(vector.add(pos, vector.multiply(dir, 0.51)), dir, 10) + end +}) + diff --git a/mods/HUD/mcl_experience/command.lua b/mods/HUD/mcl_experience/command.lua new file mode 100644 index 000000000..040031b5a --- /dev/null +++ b/mods/HUD/mcl_experience/command.lua @@ -0,0 +1,39 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +minetest.register_chatcommand("xp", { + params = S("[[] ]"), + description = S("Gives a player some XP"), + privs = {server=true}, + func = function(name, params) + local player, xp = nil, 1000 + local P, i = {}, 0 + for str in string.gmatch(params, "([^ ]+)") do + i = i + 1 + P[i] = str + end + if i > 2 then + return false, S("Error: Too many parameters!") + end + if i > 0 then + xp = tonumber(P[i]) + end + if i < 2 then + player = minetest.get_player_by_name(name) + end + if i == 2 then + player = minetest.get_player_by_name(P[1]) + end + + if not xp then + return false, S("Error: Incorrect value of XP") + end + + if not player then + return false, S("Error: Player not found") + end + + mcl_experience.add_xp(player, xp) + + return true, S("Added @1 XP to @2, total: @3, experience level: @4", tostring(xp), player:get_player_name(), tostring(mcl_experience.get_xp(player)), tostring(mcl_experience.get_level(player))) + end, +}) diff --git a/mods/HUD/mcl_experience/init.lua b/mods/HUD/mcl_experience/init.lua index b7175ccfb..aea805fa2 100644 --- a/mods/HUD/mcl_experience/init.lua +++ b/mods/HUD/mcl_experience/init.lua @@ -1,632 +1,227 @@ -local S = minetest.get_translator(minetest.get_current_modname()) - -mcl_experience = {} - -local vector = vector -local math = math -local string = string - -local pool = {} -local registered_nodes -local max_xp = 2^31-1 -local max_orb_age = 300 -- seconds - -local gravity = {x = 0, y = -((tonumber(minetest.settings:get("movement_gravity"))) or 9.81), z = 0} -local size_min, size_max = 20, 59 -- percents -local delta_size = size_max - size_min -local size_to_xp = { - {-32768, 2}, -- 1 - { 3, 6}, -- 2 - { 7, 16}, -- 3 - { 17, 36}, -- 4 - { 37, 72}, -- 5 - { 73, 148}, -- 6 - { 149, 306}, -- 7 - { 307, 616}, -- 8 - { 617, 1236}, -- 9 - { 1237, 2476}, --10 - { 2477, 32767} --11 +mcl_experience = { + on_add_xp = {}, } -local function xp_to_size(xp) - local i, l = 1, #size_to_xp - while (xp > size_to_xp[i][1]) and (i < l) do - i = i + 1 - end - return ((i-1) / (l-1) * delta_size + size_min)/100 -end +local modpath = minetest.get_modpath(minetest.get_current_modname()) -minetest.register_on_mods_loaded(function() - registered_nodes = minetest.registered_nodes -end) +dofile(modpath .. "/command.lua") +dofile(modpath .. "/orb.lua") +dofile(modpath .. "/bottle.lua") -local function load_data(player) - local name = player:get_player_name() - pool[name] = {} - local temp_pool = pool[name] - local meta = player:get_meta() - temp_pool.xp = meta:get_int("xp") or 0 - temp_pool.level = mcl_experience.xp_to_level(temp_pool.xp) - temp_pool.bar, temp_pool.bar_step, temp_pool.xp_next_level = mcl_experience.xp_to_bar(temp_pool.xp, temp_pool.level) - temp_pool.last_time= minetest.get_us_time()/1000000 -end +-- local storage --- saves data to be utilized on next login -local function save_data(player) - local name = player:get_player_name() - local temp_pool = pool[name] - local meta = player:get_meta() - meta:set_int("xp", temp_pool.xp) - pool[name] = nil -end +local hud_bars = {} +local hud_levels = {} +local caches = {} -local player_huds = {} -- the list of players hud lists (3d array) -hud_manager = {} -- hud manager class +-- helpers --- terminate the player's list on leave -minetest.register_on_leaveplayer(function(player) - local name = player:get_player_name() - player_huds[name] = nil -end) - --- create instance of new hud -function hud_manager.add_hud(player,hud_name,def) - local name = player:get_player_name() - if minetest.is_creative_enabled(name) then - return - end - local local_hud = player:hud_add({ - hud_elem_type = def.hud_elem_type, - position = def.position, - text = def.text, - text2 = def.text2, - number = def.number, - item = def.item, - direction = def.direction, - size = def.size, - offset = def.offset, - z_index = def.z_index, - alignment = def.alignment, - scale = def.scale, - }) - -- create new 3d array here - -- depends.txt is not needed - -- with it here - if not player_huds[name] then - player_huds[name] = {} - end - - player_huds[name][hud_name] = local_hud -end - --- delete instance of hud -function hud_manager.remove_hud(player,hud_name) - local name = player:get_player_name() - if player_huds[name] and player_huds[name][hud_name] then - player:hud_remove(player_huds[name][hud_name]) - player_huds[name][hud_name] = nil - end -end - --- change element of hud -function hud_manager.change_hud(data) - local name = data.player:get_player_name() - if player_huds[name] and player_huds[name][data.hud_name] then - data.player:hud_change(player_huds[name][data.hud_name], data.element, data.data) - end -end - -------------------- - --- saves specific users data for when they relog -minetest.register_on_leaveplayer(function(player) - save_data(player) -end) - --- is used for shutdowns to save all data -local function save_all() - for name,_ in pairs(pool) do - local player = minetest.get_player_by_name(name) - if player then - save_data(player) - end - end -end - --- save all data to mod storage on shutdown -minetest.register_on_shutdown(function() - save_all() -end) - - -function mcl_experience.get_player_xp_level(player) - local name = player:get_player_name() - return pool[name].level -end - -function mcl_experience.set_player_xp_level(player,level) - local name = player:get_player_name() - if level == pool[name].level then - return - end - pool[name].level = level - pool[name].xp, pool[name].bar_step, pool[name].xp_next_level = mcl_experience.bar_to_xp(pool[name].bar, level) - hud_manager.change_hud({player = player, hud_name = "xp_level", element = "text", data = tostring(level)}) - -- we may don't update the bar -end - -local name -local temp_pool -minetest.register_on_joinplayer(function(player) - - load_data(player) - - name = player:get_player_name() - temp_pool = pool[name] - - hud_manager.add_hud(player,"experience_bar", - { - hud_elem_type = "image", - name = "experience bar", - text = "experience_bar_background.png^[lowpart:" .. math.floor(temp_pool.bar / 36 * 100) .. ":experience_bar.png^[transformR270", - position = {x=0.5, y=1}, - offset = {x = (-9 * 28) - 3, y = -(48 + 24 + 16 - 5)}, - scale = {x = 2.8, y = 3.0}, - alignment = { x = 1, y = 1 }, - z_index = 11, - }) - - hud_manager.add_hud(player,"xp_level", - { - hud_elem_type = "text", position = {x=0.5, y=1}, - name = "xp_level", text = tostring(temp_pool.level), - number = 0x80FF20, - offset = {x = 0, y = -(48 + 24 + 24)}, - z_index = 12, - }) -end) - -function mcl_experience.xp_to_level(xp) +local function xp_to_level(xp) local xp = xp or 0 local a, b, c, D + if xp > 1507 then - a, b, c = 4.5, -162.5, 2220-xp + a, b, c = 4.5, -162.5, 2220 - xp elseif xp > 352 then - a, b, c = 2.5, -40.5, 360-xp + a, b, c = 2.5, -40.5, 360 - xp else a, b, c = 1, 6, -xp end - D = b*b-4*a*c + + D = b * b - 4 * a * c + if D == 0 then - return math.floor(-b/2/a) - elseif D > 0 then - local v1, v2 = -b/2/a, math.sqrt(D)/2/a - return math.floor((math.max(v1-v2, v1+v2))) + return math.floor(-b / 2 / a) + elseif D > 0 then + local v1, v2 = -b / 2 / a, math.sqrt(D) / 2 / a + return math.floor(math.max(v1 - v2, v1 + v2)) end + return 0 end -function mcl_experience.level_to_xp(level) - if (level >= 1 and level <= 16) then +local function level_to_xp(level) + if level >= 1 and level <= 16 then return math.floor(math.pow(level, 2) + 6 * level) - elseif (level >= 17 and level <= 31) then + elseif level >= 17 and level <= 31 then return math.floor(2.5 * math.pow(level, 2) - 40.5 * level + 360) elseif level >= 32 then - return math.floor(4.5 * math.pow(level, 2) - 162.5 * level + 2220); + return math.floor(4.5 * math.pow(level, 2) - 162.5 * level + 2220) end + return 0 end -function mcl_experience.xp_to_bar(xp, level) - local level = level or mcl_experience.xp_to_level(xp) - local xp_this_level = mcl_experience.level_to_xp(level) - local xp_next_level = mcl_experience.level_to_xp(level+1) - local bar_step = 36 / (xp_next_level-xp_this_level) - local bar = (xp-xp_this_level) * bar_step - return bar, bar_step, xp_next_level +local function calculate_bounds(level) + return level_to_xp(level), level_to_xp(level + 1) end -function mcl_experience.bar_to_xp(bar, level) - local xp_this_level = mcl_experience.level_to_xp(level) - local xp_next_level = mcl_experience.level_to_xp(level+1) - local bar_step = 36 / (xp_next_level-xp_this_level) - local xp = xp_this_level + math.floor(bar/36*(xp_next_level-xp_this_level)) - return xp, bar_step, xp_next_level +local function xp_to_bar(xp, level) + local xp_min, xp_max = calculate_bounds(level) + + return (xp - xp_min) / (xp_max - xp_min) end -function mcl_experience.add_experience(player, experience) - local name = player:get_player_name() - local temp_pool = pool[name] +local function bar_to_xp(bar, level) + local xp_min, xp_max = calculate_bounds(level) - local inv = player:get_inventory() - local candidates = { - {list = "main", index = player:get_wield_index()}, - {list = "armor", index = 2}, - {list = "armor", index = 3}, - {list = "armor", index = 4}, - {list = "armor", index = 5}, - } - local final_candidates = {} - for _, can in ipairs(candidates) do - local stack = inv:get_stack(can.list, can.index) - local wear = stack:get_wear() - if mcl_enchanting.has_enchantment(stack, "mending") and wear > 0 then - can.stack = stack - can.wear = wear - table.insert(final_candidates, can) - end - end - if #final_candidates > 0 then - local can = final_candidates[math.random(#final_candidates)] - local stack, list, index, wear = can.stack, can.list, can.index, can.wear - local uses = mcl_util.calculate_durability(stack) - local multiplier = 2 * 65535 / uses - local repair = experience * multiplier - local new_wear = wear - repair - if new_wear < 0 then - experience = math.floor(-new_wear / multiplier + 0.5) - new_wear = 0 - else - experience = 0 - end - stack:set_wear(math.floor(new_wear)) - inv:set_stack(list, index, stack) - end + return xp_min + bar * (xp_max - xp_min) +end - local old_bar, old_xp, old_level = temp_pool.bar, temp_pool.xp, temp_pool.level - temp_pool.xp = math.min(math.max(temp_pool.xp + experience, 0), max_xp) +local function get_time() + return minetest.get_us_time() / 1000000 +end - if (temp_pool.xp < temp_pool.xp_next_level) and (temp_pool.xp >= old_xp) then - temp_pool.bar = temp_pool.bar + temp_pool.bar_step * experience - else - temp_pool.level = mcl_experience.xp_to_level(temp_pool.xp) - temp_pool.bar, temp_pool.bar_step, temp_pool.xp_next_level = mcl_experience.xp_to_bar(temp_pool.xp, temp_pool.level) - end +-- api - if old_bar ~= temp_pool.bar then - hud_manager.change_hud({player = player, hud_name = "experience_bar", element = "text", data = "experience_bar_background.png^[lowpart:" .. math.floor(temp_pool.bar / 36 * 100) .. ":experience_bar.png^[transformR270",}) - end +function mcl_experience.get_level(player) + return caches[player].level +end - if experience > 0 and minetest.get_us_time()/1000000 - temp_pool.last_time > 0.01 then - if old_level ~= temp_pool.level then - minetest.sound_play("level_up",{gain=0.2,to_player = name}) - temp_pool.last_time = minetest.get_us_time()/1000000 + 0.2 - else - minetest.sound_play("experience",{gain=0.1,to_player = name,pitch=math.random(75,99)/100}) - temp_pool.last_time = minetest.get_us_time()/1000000 - end - end +function mcl_experience.set_level(player, level) + local cache = caches[player] - if old_level ~= temp_pool.level then - hud_manager.change_hud({player = player, hud_name = "xp_level", element = "text", data = tostring(temp_pool.level)}) + if level ~= cache.level then + mcl_experience.set_xp(player, math.floor(bar_to_xp(xp_to_bar(mcl_experience.get_xp(player), cache.level), level))) end end ---reset player level -local name -local temp_pool -local xp_amount -minetest.register_on_dieplayer(function(player) - if minetest.settings:get_bool("mcl_keepInventory", false) then - return - end +function mcl_experience.get_xp(player) + return player:get_meta():get_int("xp") +end - name = player:get_player_name() - temp_pool = pool[name] - xp_amount = temp_pool.xp +function mcl_experience.set_xp(player, xp) + player:get_meta():set_int("xp", xp) - temp_pool.xp = 0 - temp_pool.level = 0 - temp_pool.bar, temp_pool.bar_step, temp_pool.xp_next_level = mcl_experience.xp_to_bar(temp_pool.xp, temp_pool.level) + mcl_experience.update(player) +end - hud_manager.change_hud({player = player, hud_name = "xp_level", element = "text", data = tostring(temp_pool.level)}) - hud_manager.change_hud({player = player, hud_name = "experience_bar", element = "text", data = "experience_bar_background.png^[lowpart:" .. math.floor(temp_pool.bar / 36 * 100) .. ":experience_bar.png^[transformR270",}) +function mcl_experience.add_xp(player, xp) + for _, cb in ipairs(mcl_experience.on_add_xp) do + xp = cb.func(player, xp) or xp - mcl_experience.throw_experience(player:get_pos(), xp_amount) -end) - -local collector, pos, pos2 -local direction, distance, player_velocity, goal -local currentvel, acceleration, multiplier, velocity -local node, vel, def -local is_moving, is_slippery, slippery, slip_factor -local size -local function xp_step(self, dtime) - --if item set to be collected then only execute go to player - if self.collected == true then - if not self.collector then - self.collected = false - return - end - collector = minetest.get_player_by_name(self.collector) - if collector and collector:get_hp() > 0 and vector.distance(self.object:get_pos(),collector:get_pos()) < 7.25 then - self.object:set_acceleration(vector.new(0,0,0)) - self.disable_physics(self) - --get the variables - pos = self.object:get_pos() - pos2 = collector:get_pos() - - player_velocity = collector:get_velocity() or collector:get_player_velocity() - - pos2.y = pos2.y + 0.8 - - direction = vector.direction(pos,pos2) - distance = vector.distance(pos2,pos) - multiplier = distance - if multiplier < 1 then - multiplier = 1 - end - goal = vector.multiply(direction,multiplier) - currentvel = self.object:get_velocity() - - if distance > 1 then - multiplier = 20 - distance - velocity = vector.multiply(direction,multiplier) - goal = velocity - acceleration = vector.new(goal.x-currentvel.x,goal.y-currentvel.y,goal.z-currentvel.z) - self.object:add_velocity(vector.add(acceleration,player_velocity)) - elseif distance < 0.8 then - mcl_experience.add_experience(collector, self._xp) - self.object:remove() - end - return - else - self.collector = nil - self.enable_physics(self) + if xp == 0 then + break end end + local cache = caches[player] + local old_level = cache.level - self.age = self.age + dtime - if self.age > max_orb_age then - self.object:remove() - return - end + mcl_experience.set_xp(player, mcl_experience.get_xp(player) + xp) - pos = self.object:get_pos() + local current_time = get_time() - if pos then - node = minetest.get_node_or_nil({ - x = pos.x, - y = pos.y -0.25, - z = pos.z - }) - else - return - end + if current_time - cache.last_time > 0.01 then + local name = player:get_player_name() - -- Remove nodes in 'ignore' - if node and node.name == "ignore" then - self.object:remove() - return - end - - if not self.physical_state then - return -- Don't do anything - end - - -- Slide on slippery nodes - vel = self.object:get_velocity() - def = node and registered_nodes[node.name] - is_moving = (def and not def.walkable) or - vel.x ~= 0 or vel.y ~= 0 or vel.z ~= 0 - is_slippery = false - - if def and def.walkable then - slippery = minetest.get_item_group(node.name, "slippery") - is_slippery = slippery ~= 0 - if is_slippery and (math.abs(vel.x) > 0.2 or math.abs(vel.z) > 0.2) then - -- Horizontal deceleration - slip_factor = 4.0 / (slippery + 4) - self.object:set_acceleration({ - x = -vel.x * slip_factor, - y = 0, - z = -vel.z * slip_factor + if old_level == cache.level then + minetest.sound_play("mcl_experience", { + to_player = name, + gain = 0.1, + pitch = math.random(75, 99) / 100, }) - elseif vel.y == 0 then - is_moving = false + + cache.last_time = current_time + else + minetest.sound_play("mcl_experience_level_up", { + to_player = name, + gain = 0.2, + }) + + cache.last_time = current_time + 0.2 end end - - if self.moving_state == is_moving and self.slippery_state == is_slippery then - -- Do not update anything until the moving state changes - return - end - - self.moving_state = is_moving - self.slippery_state = is_slippery - - if is_moving then - self.object:set_acceleration(gravity) - else - self.object:set_acceleration({x = 0, y = 0, z = 0}) - self.object:set_velocity({x = 0, y = 0, z = 0}) - end end -minetest.register_entity("mcl_experience:orb", { - initial_properties = { - hp_max = 1, - physical = true, - collide_with_objects = false, - collisionbox = {-0.2, -0.2, -0.2, 0.2, 0.2, 0.2}, - visual = "sprite", - visual_size = {x = 0.4, y = 0.4}, - textures = {name="experience_orb.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}}, - spritediv = {x = 1, y = 14}, - initial_sprite_basepos = {x = 0, y = 0}, - is_visible = true, - pointable = false, - static_save = false, - }, - moving_state = true, - slippery_state = false, - physical_state = true, - -- Item expiry - age = 0, - -- Pushing item out of solid nodes - force_out = nil, - force_out_start = nil, - --Collection Variables - collectable = false, - try_timer = 0, - collected = false, - delete_timer = 0, - radius = 4, - - - on_activate = function(self, staticdata, dtime_s) - self.object:set_velocity(vector.new( - math.random(-2,2)*math.random(), - math.random(2,5), - math.random(-2,2)*math.random() - )) - self.object:set_armor_groups({immortal = 1}) - self.object:set_velocity({x = 0, y = 2, z = 0}) - self.object:set_acceleration(gravity) - local xp = tonumber(staticdata) - self._xp = xp - size = xp_to_size(xp) - self.object:set_properties({ - visual_size = {x = size, y = size}, - glow = 14, - }) - self.object:set_sprite({x=1,y=math.random(1,14)}, 14, 0.05, false) - end, - - enable_physics = function(self) - if not self.physical_state then - self.physical_state = true - self.object:set_properties({physical = true}) - self.object:set_velocity({x=0, y=0, z=0}) - self.object:set_acceleration(gravity) - end - end, - - disable_physics = function(self) - if self.physical_state then - self.physical_state = false - self.object:set_properties({physical = false}) - self.object:set_velocity({x=0, y=0, z=0}) - self.object:set_acceleration({x=0, y=0, z=0}) - end - end, - on_step = function(self, dtime) - xp_step(self, dtime) - end, -}) - -minetest.register_chatcommand("xp", { - params = S("[[] ]"), - description = S("Gives a player some XP"), - privs = {server=true}, - func = function(name, params) - local player, xp = nil, 1000 - local P, i = {}, 0 - for str in string.gmatch(params, "([^ ]+)") do - i = i + 1 - P[i] = str - end - if i > 2 then - return false, S("Error: Too many parameters!") - end - if i > 0 then - xp = tonumber(P[i]) - end - if i < 2 then - player = minetest.get_player_by_name(name) - end - if i == 2 then - player = minetest.get_player_by_name(P[1]) - end - if not xp then - return false, S("Error: Incorrect value of XP") - end - if not player then - return false, S("Error: Player not found") - end - mcl_experience.add_experience(player, xp) - local playername = player:get_player_name() - minetest.chat_send_player(name, S("Added @1 XP to @2, total: @3, experience level: @4", tostring(xp), playername, tostring(pool[playername].xp), tostring(pool[playername].level))) - end, -}) - -function mcl_experience.throw_experience(pos, amount) +function mcl_experience.throw_xp(pos, total_xp) local i, j = 0, 0 - local obj, xp - while i < amount and j < 100 do - xp = math.min(math.random(1, math.min(32767, amount-math.floor(i/2))), amount-i) - obj = minetest.add_entity(pos, "mcl_experience:orb", tostring(xp)) + + while i < total_xp and j < 100 do + local xp = math.min(math.random(1, math.min(32767, total_xp - math.floor(i / 2))), total_xp - i) + local obj = minetest.add_entity(pos, "mcl_experience:orb", tostring(xp)) + if not obj then return false end - obj:set_velocity({ - x=math.random(-2,2)*math.random(), - y=math.random(2,5), - z=math.random(-2,2)*math.random() - }) + + obj:set_velocity(vector.new( + math.random(-2, 2) * math.random(), + math.random( 2, 5), + math.random(-2, 2) * math.random() + )) + i = i + xp j = j + 1 end end -minetest.register_entity("mcl_experience:bottle",{ - textures = {"mcl_experience_bottle.png"}, - hp_max = 1, - visual_size = {x = 0.35, y = 0.35}, - collisionbox = {-0.1, -0.1, -0.1, 0.1, 0.1, 0.1}, - pointable = false, - on_step = function(self, dtime) - local pos = self.object:get_pos() - local node = minetest.get_node(pos) - local n = node.name - if n ~= "air" and n ~= "mcl_portals:portal" and n ~= "mcl_portals:portal_end" and minetest.get_item_group(n, "liquid") == 0 then - minetest.sound_play("mcl_potions_breaking_glass", {pos = pos, max_hear_distance = 16, gain = 1}) - mcl_experience.throw_experience(pos, math.random(3, 11)) - minetest.add_particlespawner({ - amount = 50, - time = 0.1, - minpos = vector.add(pos, vector.new(-0.1, 0.5, -0.1)), - maxpos = vector.add(pos, vector.new( 0.1, 0.6, 0.1)), - minvel = vector.new(-2, 0, -2), - maxvel = vector.new( 2, 2, 2), - minacc = vector.new(0, 0, 0), - maxacc = vector.new(0, 0, 0), - minexptime = 0.5, - maxexptime = 1.25, - minsize = 1, - maxsize = 2, - collisiondetection = true, - vertical = false, - texture = "mcl_particles_effect.png^[colorize:blue:127", - }) - self.object:remove() - end - end, -}) +function mcl_experience.update(player) + local xp = mcl_experience.get_xp(player) + local cache = caches[player] -local function throw_xp_bottle(pos, dir, velocity) - minetest.sound_play("mcl_throwing_throw", {pos = pos, gain = 0.4, max_hear_distance = 16}, true) - local obj = minetest.add_entity(pos, "mcl_experience:bottle") - obj:set_velocity(vector.multiply(dir, velocity)) - local acceleration = vector.multiply(dir, -3) - acceleration.y = -9.81 - obj:set_acceleration(acceleration) + cache.level = xp_to_level(xp) + + if not minetest.is_creative_enabled(player:get_player_name()) then + player:hud_change(hud_bars[player], "text", "mcl_experience_bar_background.png^[lowpart:" + .. math.floor(math.floor(xp_to_bar(xp, cache.level) * 18) / 18 * 100) + .. ":mcl_experience_bar.png^[transformR270" + ) + + if cache.level == 0 then + player:hud_change(hud_levels[player], "text", "") + else + player:hud_change(hud_levels[player], "text", tostring(cache.level)) + end + end end -minetest.register_craftitem("mcl_experience:bottle", { - description = "Bottle o' Enchanting", - inventory_image = "mcl_experience_bottle.png", - wield_image = "mcl_experience_bottle.png", - stack_max = 64, - on_use = function(itemstack, placer, pointed_thing) - throw_xp_bottle(vector.add(placer:get_pos(), vector.new(0, 1.5, 0)), placer:get_look_dir(), 10) - if not minetest.is_creative_enabled(placer:get_player_name()) then - itemstack:take_item() - end - return itemstack - end, - _on_dispense = function(_, pos, _, _, dir) - throw_xp_bottle(vector.add(pos, vector.multiply(dir, 0.51)), dir, 10) +function mcl_experience.register_on_add_xp(func, priority) + table.insert(mcl_experience.on_add_xp, {func = func, priority = priority or 0}) +end + +-- callbacks + +minetest.register_on_joinplayer(function(player) + caches[player] = { + last_time = get_time(), + } + + if not minetest.is_creative_enabled(player:get_player_name()) then + hud_bars[player] = player:hud_add({ + hud_elem_type = "image", + position = {x = 0.5, y = 1}, + offset = {x = (-9 * 28) - 3, y = -(48 + 24 + 16 - 5)}, + scale = {x = 2.8, y = 3.0}, + alignment = {x = 1, y = 1}, + z_index = 11, + }) + + hud_levels[player] = player:hud_add({ + hud_elem_type = "text", + position = {x = 0.5, y = 1}, + number = 0x80FF20, + offset = {x = 0, y = -(48 + 24 + 24)}, + z_index = 12, + }) end -}) + + mcl_experience.update(player) +end) + +minetest.register_on_leaveplayer(function(player) + hud_bars[player] = nil + hud_levels[player] = nil + caches[player] = nil +end) + +minetest.register_on_dieplayer(function(player) + if not minetest.settings:get_bool("mcl_keepInventory", false) then + mcl_experience.throw_xp(player:get_pos(), mcl_experience.get_xp(player)) + mcl_experience.set_xp(player, 0) + end +end) + +minetest.register_on_mods_loaded(function() + table.sort(mcl_experience.on_add_xp, function(a, b) return a.priority < b.priority end) +end) diff --git a/mods/HUD/mcl_experience/orb.lua b/mods/HUD/mcl_experience/orb.lua new file mode 100644 index 000000000..9aecce00d --- /dev/null +++ b/mods/HUD/mcl_experience/orb.lua @@ -0,0 +1,220 @@ +local size_min, size_max = 20, 59 +local delta_size = size_max - size_min + +local size_to_xp = { + {-32768, 2}, -- 1 + { 3, 6}, -- 2 + { 7, 16}, -- 3 + { 17, 36}, -- 4 + { 37, 72}, -- 5 + { 73, 148}, -- 6 + { 149, 306}, -- 7 + { 307, 616}, -- 8 + { 617, 1236}, -- 9 + { 1237, 2476}, -- 10 + { 2477, 32767} -- 11 +} + +local function xp_to_size(xp) + local i, l = 1, #size_to_xp + + while xp > size_to_xp[i][1] and i < l do + i = i + 1 + end + + return ((i - 1) / (l - 1) * delta_size + size_min) / 100 +end + +local max_orb_age = 300 -- seconds +local gravity = vector.new(0, -((tonumber(minetest.settings:get("movement_gravity"))) or 9.81), 0) + +local collector, pos, pos2 +local direction, distance, player_velocity, goal +local currentvel, acceleration, multiplier, velocity +local node, vel, def +local is_moving, is_slippery, slippery, slip_factor +local size +local function xp_step(self, dtime) + --if item set to be collected then only execute go to player + if self.collected == true then + if not self.collector then + self.collected = false + return + end + collector = minetest.get_player_by_name(self.collector) + if collector and collector:get_hp() > 0 and vector.distance(self.object:get_pos(),collector:get_pos()) < 7.25 then + self.object:set_acceleration(vector.new(0,0,0)) + self.disable_physics(self) + --get the variables + pos = self.object:get_pos() + pos2 = collector:get_pos() + + player_velocity = collector:get_velocity() or collector:get_player_velocity() + + pos2.y = pos2.y + 0.8 + + direction = vector.direction(pos,pos2) + distance = vector.distance(pos2,pos) + multiplier = distance + if multiplier < 1 then + multiplier = 1 + end + goal = vector.multiply(direction,multiplier) + currentvel = self.object:get_velocity() + + if distance > 1 then + multiplier = 20 - distance + velocity = vector.multiply(direction,multiplier) + goal = velocity + acceleration = vector.new(goal.x-currentvel.x,goal.y-currentvel.y,goal.z-currentvel.z) + self.object:add_velocity(vector.add(acceleration,player_velocity)) + elseif distance < 0.8 then + mcl_experience.add_xp(collector, self._xp) + self.object:remove() + end + return + else + self.collector = nil + self.enable_physics(self) + end + end + + + self.age = self.age + dtime + if self.age > max_orb_age then + self.object:remove() + return + end + + pos = self.object:get_pos() + + if pos then + node = minetest.get_node_or_nil({ + x = pos.x, + y = pos.y -0.25, + z = pos.z + }) + else + return + end + + -- Remove nodes in 'ignore' + if node and node.name == "ignore" then + self.object:remove() + return + end + + if not self.physical_state then + return -- Don't do anything + end + + -- Slide on slippery nodes + vel = self.object:get_velocity() + def = node and minetest.registered_nodes[node.name] + is_moving = (def and not def.walkable) or + vel.x ~= 0 or vel.y ~= 0 or vel.z ~= 0 + is_slippery = false + + if def and def.walkable then + slippery = minetest.get_item_group(node.name, "slippery") + is_slippery = slippery ~= 0 + if is_slippery and (math.abs(vel.x) > 0.2 or math.abs(vel.z) > 0.2) then + -- Horizontal deceleration + slip_factor = 4.0 / (slippery + 4) + self.object:set_acceleration({ + x = -vel.x * slip_factor, + y = 0, + z = -vel.z * slip_factor + }) + elseif vel.y == 0 then + is_moving = false + end + end + + if self.moving_state == is_moving and self.slippery_state == is_slippery then + -- Do not update anything until the moving state changes + return + end + + self.moving_state = is_moving + self.slippery_state = is_slippery + + if is_moving then + self.object:set_acceleration(gravity) + else + self.object:set_acceleration({x = 0, y = 0, z = 0}) + self.object:set_velocity({x = 0, y = 0, z = 0}) + end +end + +minetest.register_entity("mcl_experience:orb", { + initial_properties = { + hp_max = 1, + physical = true, + collide_with_objects = false, + collisionbox = {-0.2, -0.2, -0.2, 0.2, 0.2, 0.2}, + visual = "sprite", + visual_size = {x = 0.4, y = 0.4}, + textures = {name="mcl_experience_orb.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}}, + spritediv = {x = 1, y = 14}, + initial_sprite_basepos = {x = 0, y = 0}, + is_visible = true, + pointable = false, + static_save = false, + }, + moving_state = true, + slippery_state = false, + physical_state = true, + -- Item expiry + age = 0, + -- Pushing item out of solid nodes + force_out = nil, + force_out_start = nil, + --Collection Variables + collectable = false, + try_timer = 0, + collected = false, + delete_timer = 0, + radius = 4, + + + on_activate = function(self, staticdata, dtime_s) + self.object:set_velocity(vector.new( + math.random(-2,2)*math.random(), + math.random(2,5), + math.random(-2,2)*math.random() + )) + self.object:set_armor_groups({immortal = 1}) + self.object:set_velocity({x = 0, y = 2, z = 0}) + self.object:set_acceleration(gravity) + local xp = tonumber(staticdata) + self._xp = xp + size = xp_to_size(xp) + self.object:set_properties({ + visual_size = {x = size, y = size}, + glow = 14, + }) + self.object:set_sprite({x=1,y=math.random(1,14)}, 14, 0.05, false) + end, + + enable_physics = function(self) + if not self.physical_state then + self.physical_state = true + self.object:set_properties({physical = true}) + self.object:set_velocity({x=0, y=0, z=0}) + self.object:set_acceleration(gravity) + end + end, + + disable_physics = function(self) + if self.physical_state then + self.physical_state = false + self.object:set_properties({physical = false}) + self.object:set_velocity({x=0, y=0, z=0}) + self.object:set_acceleration({x=0, y=0, z=0}) + end + end, + on_step = function(self, dtime) + xp_step(self, dtime) + end, +}) diff --git a/mods/HUD/mcl_experience/sounds/experience.ogg b/mods/HUD/mcl_experience/sounds/mcl_experience.ogg similarity index 100% rename from mods/HUD/mcl_experience/sounds/experience.ogg rename to mods/HUD/mcl_experience/sounds/mcl_experience.ogg diff --git a/mods/HUD/mcl_experience/sounds/level_up.ogg b/mods/HUD/mcl_experience/sounds/mcl_experience_level_up.ogg similarity index 100% rename from mods/HUD/mcl_experience/sounds/level_up.ogg rename to mods/HUD/mcl_experience/sounds/mcl_experience_level_up.ogg diff --git a/mods/HUD/mcl_experience/textures/experience_bar.png b/mods/HUD/mcl_experience/textures/mcl_experience_bar.png similarity index 100% rename from mods/HUD/mcl_experience/textures/experience_bar.png rename to mods/HUD/mcl_experience/textures/mcl_experience_bar.png diff --git a/mods/HUD/mcl_experience/textures/experience_bar_background.png b/mods/HUD/mcl_experience/textures/mcl_experience_bar_background.png similarity index 100% rename from mods/HUD/mcl_experience/textures/experience_bar_background.png rename to mods/HUD/mcl_experience/textures/mcl_experience_bar_background.png diff --git a/mods/HUD/mcl_experience/textures/experience_orb.png b/mods/HUD/mcl_experience/textures/mcl_experience_orb.png similarity index 100% rename from mods/HUD/mcl_experience/textures/experience_orb.png rename to mods/HUD/mcl_experience/textures/mcl_experience_orb.png diff --git a/mods/ITEMS/mcl_enchanting/enchantments.lua b/mods/ITEMS/mcl_enchanting/enchantments.lua index 17b6b6ac6..e876baf31 100644 --- a/mods/ITEMS/mcl_enchanting/enchantments.lua +++ b/mods/ITEMS/mcl_enchanting/enchantments.lua @@ -379,6 +379,49 @@ mcl_enchanting.enchantments.mending = { inv_tool_tab = true, } +mcl_experience.register_on_add_xp(function(player, xp) + local inv = player:get_inventory() + + local candidates = { + {list = "main", index = player:get_wield_index()}, + {list = "armor", index = 2}, + {list = "armor", index = 3}, + {list = "armor", index = 4}, + {list = "armor", index = 5}, + } + + local final_candidates = {} + for _, can in ipairs(candidates) do + local stack = inv:get_stack(can.list, can.index) + local wear = stack:get_wear() + if mcl_enchanting.has_enchantment(stack, "mending") and wear > 0 then + can.stack = stack + can.wear = wear + table.insert(final_candidates, can) + end + end + + if #final_candidates > 0 then + local can = final_candidates[math.random(#final_candidates)] + local stack, list, index, wear = can.stack, can.list, can.index, can.wear + local uses = mcl_util.calculate_durability(stack) + local multiplier = 2 * 65535 / uses + local repair = xp * multiplier + local new_wear = wear - repair + + if new_wear < 0 then + xp = math.floor(-new_wear / multiplier + 0.5) + new_wear = 0 + else + xp = 0 + end + + stack:set_wear(math.floor(new_wear)) + inv:set_stack(list, index, stack) + end + + return xp +end, 0) mcl_enchanting.enchantments.multishot = { name = S("Multishot"), diff --git a/mods/ITEMS/mcl_enchanting/engine.lua b/mods/ITEMS/mcl_enchanting/engine.lua index 6050aeed2..02425945c 100644 --- a/mods/ITEMS/mcl_enchanting/engine.lua +++ b/mods/ITEMS/mcl_enchanting/engine.lua @@ -499,7 +499,7 @@ function mcl_enchanting.show_enchanting_formspec(player) .. "real_coordinates[true]" .. "image[3.15,0.6;7.6,4.1;mcl_enchanting_button_background.png]" local itemstack = inv:get_stack("enchanting_item", 1) - local player_levels = mcl_experience.get_player_xp_level(player) + local player_levels = mcl_experience.get_level(player) local y = 0.65 local any_enchantment = false local table_slots = mcl_enchanting.get_table_slots(player, itemstack, num_bookshelves) @@ -549,11 +549,11 @@ function mcl_enchanting.handle_formspec_fields(player, formname, fields) if not slot then return end - local player_level = mcl_experience.get_player_xp_level(player) + local player_level = mcl_experience.get_level(player) if player_level < slot.level_requirement then return end - mcl_experience.set_player_xp_level(player, player_level - button_pressed) + mcl_experience.set_level(player, player_level - button_pressed) inv:remove_item("enchanting_lapis", cost) mcl_enchanting.set_enchanted_itemstring(itemstack) mcl_enchanting.set_enchantments(itemstack, slot.enchantments) diff --git a/mods/ITEMS/mcl_fishing/init.lua b/mods/ITEMS/mcl_fishing/init.lua index e0c78832f..ade0be818 100644 --- a/mods/ITEMS/mcl_fishing/init.lua +++ b/mods/ITEMS/mcl_fishing/init.lua @@ -37,7 +37,7 @@ local fish = function(itemstack, player, pointed_thing) local num = 0 local ent = nil local noent = true - + local durability = 65 local unbreaking = mcl_enchanting.get_enchantment(itemstack, "unbreaking") if unbreaking > 0 then @@ -117,8 +117,8 @@ local fish = function(itemstack, player, pointed_thing) else minetest.add_item(pos, item) end - if mcl_experience.throw_experience then - mcl_experience.throw_experience(pos, math.random(1,6)) + if mcl_experience.throw_xp then + mcl_experience.throw_xp(pos, math.random(1,6)) end if not minetest.is_creative_enabled(player:get_player_name()) then diff --git a/mods/ITEMS/mcl_furnaces/init.lua b/mods/ITEMS/mcl_furnaces/init.lua index ca43b275a..dca476762 100644 --- a/mods/ITEMS/mcl_furnaces/init.lua +++ b/mods/ITEMS/mcl_furnaces/init.lua @@ -75,9 +75,9 @@ local function give_xp(pos, player) local xp = meta:get_int("xp") if xp > 0 then if player then - mcl_experience.add_experience(player, xp) + mcl_experience.add_xp(player, xp) else - mcl_experience.throw_experience(vector.add(pos, dir), xp) + mcl_experience.throw_xp(vector.add(pos, dir), xp) end meta:set_int("xp", 0) end diff --git a/mods/ITEMS/mcl_mobspawners/init.lua b/mods/ITEMS/mcl_mobspawners/init.lua index b756d4a6d..6e4b24c96 100644 --- a/mods/ITEMS/mcl_mobspawners/init.lua +++ b/mods/ITEMS/mcl_mobspawners/init.lua @@ -317,7 +317,7 @@ minetest.register_node("mcl_mobspawners:spawner", { if obj then obj:remove() end - mcl_experience.throw_experience(pos, math.random(15, 43)) + mcl_experience.throw_xp(pos, math.random(15, 43)) end, on_punch = function(pos) From 34f329a9d559c326e1c198ce1fbbfa16c1edee8e Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 3 Nov 2021 19:57:21 +0100 Subject: [PATCH 210/296] TextureConverter: Implement grass palette conversion Source: https://minecraft.fandom.com/wiki/Tint Since the MineClone2 biomes do not entirely match with the Minecraft ones I picked the Minecraft biomes that seem to match them best. This also changes the palette index of the nether to match the desert instead of the mesa biome and changes the color of grass blocks in item form to the default minecraft one. --- mods/ITEMS/mcl_core/nodes_base.lua | 2 +- mods/MAPGEN/mcl_biomes/init.lua | 2 +- tools/Texture_Converter.py | 67 +++++++++++++++++++++--------- 3 files changed, 50 insertions(+), 21 deletions(-) diff --git a/mods/ITEMS/mcl_core/nodes_base.lua b/mods/ITEMS/mcl_core/nodes_base.lua index abc650bb0..fe1ee58c2 100644 --- a/mods/ITEMS/mcl_core/nodes_base.lua +++ b/mods/ITEMS/mcl_core/nodes_base.lua @@ -365,7 +365,7 @@ minetest.register_node("mcl_core:dirt_with_grass", { overlay_tiles = {"mcl_core_grass_block_top.png", "", {name="mcl_core_grass_block_side_overlay.png", tileable_vertical=false}}, palette = "mcl_core_palette_grass.png", palette_index = 0, - color = "#55aa60", + color = "#8EB971", is_ground_content = true, stack_max = 64, groups = {handy=1,shovely=1,dirt=2,grass_block=1, grass_block_no_snow=1, soil=1, soil_sapling=2, soil_sugarcane=1, cultivatable=2, spreading_dirt_type=1, enderman_takable=1, building_block=1}, diff --git a/mods/MAPGEN/mcl_biomes/init.lua b/mods/MAPGEN/mcl_biomes/init.lua index a630dba04..a04822439 100644 --- a/mods/MAPGEN/mcl_biomes/init.lua +++ b/mods/MAPGEN/mcl_biomes/init.lua @@ -1496,7 +1496,7 @@ local function register_dimension_biomes() heat_point = 100, humidity_point = 0, _mcl_biome_type = "hot", - _mcl_palette_index = 19, + _mcl_palette_index = 17, }) --[[ THE END ]] diff --git a/tools/Texture_Converter.py b/tools/Texture_Converter.py index 820fa9c08..bdf249113 100755 --- a/tools/Texture_Converter.py +++ b/tools/Texture_Converter.py @@ -118,17 +118,6 @@ def colorize_alpha(colormap, source, colormap_pixel, texture_size, destination): colorize(colormap, source, colormap_pixel, texture_size, tempfile2.name) os.system("composite -compose Dst_In "+source+" "+tempfile2.name+" -alpha Set "+destination) -# This function is unused atm. -# TODO: Implemnt colormap extraction -def extract_colormap(colormap, colormap_pixel, positions): - os.system("convert -size 16x16 canvas:black "+tempfile1.name) - x=0 - y=0 - for p in positions: - os.system("convert "+colormap+" -crop 1x1+"+colormap_pixel+" -depth 8 "+tempfile2.name) - os.system("composite -geometry 16x16+"+x+"+"+y+" "+tempfile2.name) - x = x+1 - def target_dir(directory): if make_texture_pack: return output_dir + "/" + output_dir_name @@ -397,20 +386,60 @@ def convert_textures(): colorize_alpha(FOLIAG, tex_dir+"/blocks/vine.png", "16+39", str(PXSIZE), target_dir("/mods/ITEMS/mcl_core/textures")+"/mcl_core_vine.png") # Tall grass, fern (inventory images) - pcol = "49+172" # Plains grass color + pcol = "50+173" # Plains grass color colorize_alpha(GRASS, tex_dir+"/blocks/tallgrass.png", pcol, str(PXSIZE), target_dir("/mods/ITEMS/mcl_flowers/textures")+"/mcl_flowers_tallgrass_inv.png") colorize_alpha(GRASS, tex_dir+"/blocks/fern.png", pcol, str(PXSIZE), target_dir("/mods/ITEMS/mcl_flowers/textures")+"/mcl_flowers_fern_inv.png") colorize_alpha(GRASS, tex_dir+"/blocks/double_plant_fern_top.png", pcol, str(PXSIZE), target_dir("/mods/ITEMS/mcl_flowers/textures")+"/mcl_flowers_double_plant_fern_inv.png") colorize_alpha(GRASS, tex_dir+"/blocks/double_plant_grass_top.png", pcol, str(PXSIZE), target_dir("/mods/ITEMS/mcl_flowers/textures")+"/mcl_flowers_double_plant_grass_inv.png") - # TODO: Convert grass palette - - offset = [ - [ pcol, "", "grass" ], # Default grass: Plains + # Convert grass palette: https://minecraft.fandom.com/wiki/Tint + grass_colors = [ + # [Coords or #Color, AdditionalTint], # Index - Minecraft biome name (MineClone2 biome names) + ["50+173"], # 0 - Plains (flat, Plains, Plains_beach, Plains_ocean, End) + ["0+255"], # 1 - Savanna (Savanna, Savanna_beach, Savanna_ocean) + ["255+255"], # 2 - Ice Spikes (IcePlainsSpikes, IcePlainsSpikes_ocean) + ["255+255"], # 3 - Snowy Taiga (ColdTaiga, ColdTaiga_beach, ColdTaiga_beach_water, ColdTaiga_ocean) + ["178+193"], # 4 - Giant Tree Taiga (MegaTaiga, MegaTaiga_ocean) + ["178+193"], # 5 - Giant Tree Taiga (MegaSpruceTaiga, MegaSpruceTaiga_ocean) + ["203+239"], # 6 - Montains (ExtremeHills, ExtremeHills_beach, ExtremeHills_ocean) + ["203+239"], # 7 - Montains (ExtremeHillsM, ExtremeHillsM_ocean) + ["203+239"], # 8 - Montains (ExtremeHills+, ExtremeHills+_snowtop, ExtremeHills+_ocean) + ["50+173"], # 9 - Beach (StoneBeach, StoneBeach_ocean) + ["255+255"], # 10 - Snowy Tundra (IcePlains, IcePlains_ocean) + ["50+173"], # 11 - Sunflower Plains (SunflowerPlains, SunflowerPlains_ocean) + ["191+203"], # 12 - Taiga (Taiga, Taiga_beach, Taiga_ocean) + ["76+112"], # 13 - Forest (Forest, Forest_beach, Forest_ocean) + ["76+112"], # 14 - Flower Forest (FlowerForest, FlowerForest_beach, FlowerForest_ocean) + ["101+163"], # 15 - Birch Forest (BirchForest, BirchForest_ocean) + ["101+163"], # 16 - Birch Forest Hills (BirchForestM, BirchForestM_ocean) + ["0+255"], # 17 - Desert and Nether (Desert, Desert_ocean, Nether) + ["76+112", "#28340A"], # 18 - Dark Forest (RoofedForest, RoofedForest_ocean) + ["#90814d"], # 19 - Mesa (Mesa, Mesa_sandlevel, Mesa_ocean, ) + ["#90814d"], # 20 - Mesa (MesaBryce, MesaBryce_sandlevel, MesaBryce_ocean) + ["#90814d"], # 21 - Mesa (MesaPlateauF, MesaPlateauF_grasstop, MesaPlateauF_sandlevel, MesaPlateauF_ocean) + ["#90814d"], # 22 - Mesa (MesaPlateauFM, MesaPlateauFM_grasstop, MesaPlateauFM_sandlevel, MesaPlateauFM_ocean) + ["0+255"], # 23 - Shattered Savanna (or Savanna Plateau ?) (SavannaM, SavannaM_ocean) + ["12+36"], # 24 - Jungle (Jungle, Jungle_shore, Jungle_ocean) + ["12+36"], # 25 - Modified Jungle (JungleM, JungleM_shore, JungleM_ocean) + ["12+61"], # 26 - Jungle Edge (JungleEdge, JungleEdge_ocean) + ["12+61"], # 27 - Modified Jungle Edge (JungleEdgeM, JungleEdgeM_ocean) + ["#6A7039"], # 28 - Swamp (Swampland, Swampland_shore, Swampland_ocean) + ["25+25"], # 29 - Mushroom Fields and Mushroom Field Shore (MushroomIsland, MushroomIslandShore, MushroomIsland_ocean) ] - for o in offset: - colorize(GRASS, tex_dir+"/blocks/grass_top.png", o[0], str(PXSIZE), target_dir("/mods/ITEMS/mcl_core/textures")+"/default_"+o[2]+".png") - colorize_alpha(GRASS, tex_dir+"/blocks/grass_side_overlay.png", o[0], str(PXSIZE), target_dir("/mods/ITEMS/mcl_core/textures")+"/default_"+o[2]+"_side.png") + + grass_palette_file = target_dir("/mods/ITEMS/mcl_core/textures") + "/mcl_core_palette_grass.png" + os.system("convert -size 16x16 canvas:transparent " + grass_palette_file) + + for i, color in enumerate(grass_colors): + if color[0][0] == "#": + os.system("convert -size 1x1 xc:\"" + color[0] + "\" " + tempfile1.name + ".png") + else: + os.system("convert " + GRASS + " -crop 1x1+" + color[0] + " " + tempfile1.name + ".png") + + if len(color) > 1: + os.system("convert " + tempfile1.name + ".png \\( -size 1x1 xc:\"" + color[1] + "\" \\) -compose blend -define compose:args=50,50 -composite " + tempfile1.name + ".png") + + os.system("convert " + grass_palette_file + " \\( " + tempfile1.name + ".png -geometry +" + str(i % 16) + "+" + str(int(i / 16)) + " \\) -composite " + grass_palette_file) # Metadata if make_texture_pack: From 970988cb39bcd1ab35e17de886ffdd46aa52eee0 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 4 Aug 2021 12:41:25 +0200 Subject: [PATCH 211/296] Add sugar cane colorisation --- mods/ITEMS/mcl_core/functions.lua | 10 +++++++--- mods/ITEMS/mcl_core/nodes_cactuscane.lua | 13 +++++++++++++ .../mcl_core/textures/default_papyrus.png | Bin 277 -> 1953 bytes 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/mods/ITEMS/mcl_core/functions.lua b/mods/ITEMS/mcl_core/functions.lua index 2ef73af72..d2ff3690a 100644 --- a/mods/ITEMS/mcl_core/functions.lua +++ b/mods/ITEMS/mcl_core/functions.lua @@ -773,8 +773,7 @@ end local grass_spread_randomizer = PseudoRandom(minetest.get_mapgen_setting("seed")) --- Return appropriate grass block node for pos -function mcl_core.get_grass_block_type(pos) +function mcl_core.get_grass_palette_index(pos) local biome_data = minetest.get_biome_data(pos) local index = 0 if biome_data then @@ -785,7 +784,12 @@ function mcl_core.get_grass_block_type(pos) index = reg_biome._mcl_palette_index end end - return {name="mcl_core:dirt_with_grass", param2=index} + return index +end + +-- Return appropriate grass block node for pos +function mcl_core.get_grass_block_type(pos) + return {name = "mcl_core:dirt_with_grass", param2 = mcl_core.get_grass_palette_index(pos)} end ------------------------------ diff --git a/mods/ITEMS/mcl_core/nodes_cactuscane.lua b/mods/ITEMS/mcl_core/nodes_cactuscane.lua index 839102534..e61d6df80 100644 --- a/mods/ITEMS/mcl_core/nodes_cactuscane.lua +++ b/mods/ITEMS/mcl_core/nodes_cactuscane.lua @@ -53,7 +53,10 @@ minetest.register_node("mcl_core:reeds", { _doc_items_longdesc = S("Sugar canes are a plant which has some uses in crafting. Sugar canes will slowly grow up to 3 blocks when they are next to water and are placed on a grass block, dirt, sand, red sand, podzol or coarse dirt. When a sugar cane is broken, all sugar canes connected above will break as well."), _doc_items_usagehelp = S("Sugar canes can only be placed top of other sugar canes and on top of blocks on which they would grow."), drawtype = "plantlike", + paramtype2 = "color", tiles = {"default_papyrus.png"}, + palette = "mcl_core_palette_grass.png", + palette_index = 0, inventory_image = "mcl_core_reeds.png", wield_image = "mcl_core_reeds.png", paramtype = "light", @@ -79,6 +82,7 @@ minetest.register_node("mcl_core:reeds", { groups = {dig_immediate=3, craftitem=1, deco_block=1, plant=1, non_mycelium_plant=1, dig_by_piston=1}, sounds = mcl_sounds.node_sound_leaves_defaults(), node_placement_prediction = "", + drop = "mcl_core:reeds", -- to prevent color inheritation on_place = mcl_util.generate_on_place_plant_function(function(place_pos, place_node) local soil_pos = {x=place_pos.x, y=place_pos.y-1, z=place_pos.z} local soil_node = minetest.get_node_or_nil(soil_pos) @@ -114,6 +118,15 @@ minetest.register_node("mcl_core:reeds", { return false end), + on_construct = function(pos) + local node = minetest.get_node(pos) + if node.param2 == 0 then + node.param2 = mcl_core.get_grass_palette_index(pos) + if node.param2 ~= 0 then + minetest.set_node(pos, node) + end + end + end, _mcl_blast_resistance = 0, _mcl_hardness = 0, }) diff --git a/mods/ITEMS/mcl_core/textures/default_papyrus.png b/mods/ITEMS/mcl_core/textures/default_papyrus.png index b6e2062ec6e5f4d2bf5c2a41437627ac6935e687..c928402f9507ddf95b93d2c43f31738a09356b81 100644 GIT binary patch delta 1951 zcmV;Q2VnS>0-+C(7=H)^0002B`ZwwT00i-RR9JLUVRs;Ka&Km7Y-J#Hd2nSQWq4_3 z004N}tyfuc?I;ZW*D87mNFavgFjl=C^zvI^z}G|alBzbb(G^%a=m_CJ{r69Uf8-+c z1`IoIgSAR76HK5ef>*~C#uJqp&-p_w;i88*J@3bANsmJ)bWuADFIs@N9SXemsrLL(xTfIyeTVF$u_Jc{_mWGeDOhFA46^-_kAk6sKO_VrgfLM0g!Q zzUlRLL!XZIMt?-t0Vd@h%b9m;#kW?E)kR|^qIPD~2sSP=GBHWW^?1!nb8@rDZnPlH ztEjS2UQ|{|TE>7RtTaG_1tT`BqtBQHqM=GodZH{ub)DCa0%hHKGQD9Vr-LrSAn8mM zv=%jOEI9mz;V+{X&jn>Fp&08_f7#%>!QV7!E%y+i@_##4f{S`y3yjWOf66Q&1l#0| zM}SwG^sA5jkyI51d4$=^0;5WYiNtv3mL5E7na9!}TL{6GX+T0GzFEMa76z0>&1g|M zB8Mn(^g>V+EpbbISzwa>AW6VT=q4 zA71$$0e<$jgitwe@j`VsuK4s0(u7soCpPo{~A{3;lv+ zy?^TB?bUm)b9(U@RrD}r?`f-li!SyKPH{-SEvfp)yAs7IQe`yqr%*P?kmOv;u1sa? zSvW=H7wtK7Gem?5_p>9 zY7N#f+O$@jDS!UVm|sQoDWl!Z&awE-7wrcHy+*tB{j<2erZFmL7|_&}q5|!&h0_q<@5M>+ITC z8P+}^`^f%go~faEC&JF-()of3-|Us7#T|P7Md;u&c4xX-y)l%Xyxbn#o=$z+`D{BYoJ%7KQugYl#Z^zlmE5^N;(jKRiJJBlGM`%4gZA0`$ z->BRVLikGzFVW8a9)`vXGSGP*wer|cXPsAH^sD~E*z_v{c?UOV`?KJ!C4hWUZB`fH zu!O>2e+k@rxO}OcYqw|IOnZsjW;5HkzK?ePH2aXsUTbhqbDw0w7p&?N+kakOlMlcE z{{iyl_o#?U>4X3P0V8QcLr_UWLm+T+Z)Rz1WdHzpoSl%dO2beThQHRJrRX4vgE(Yx zEx6dpr78r$LW~uxPHEC&F*k-JrT7NEi9SpRLGTTH0R?CO8yy_X;)TQiaX9Dy@4e7; zlgJd#9+knLU8vG1 z%S&h+h`aMLv#etCb`TtiAH;5K(pdZ?-i=Lc+3p4=nMFUI_BN~I^y1w1RXcc`(8tGR z#EdBkB^_z1&M{r~r5-sU_Y_3Zgt2;a&6M1T3ORWkiUuOxrY3K@%762fGLpwsUN+$l zBTt)${on7kkF#pCv9-v;Jgizvs^(+@?~kxHgpFrtU)N-{e!s0|rd!SY^NnAA?NBgF z<9F8p0007FOGiWi|A&vvzW@LL32;bRa{vGf6951U69E94oEQKA00(qQO+^Rg2m}fd z2@>7nWdHyH21!IgRDUSXZPC9<13?f5@ZTOO6m4X=GKHOm5Ku^$*GOR*u)f}ag}qOZ z&h+{KR=$9wusCci4g@{YNlYVak#mjUR6Fc9^Zl8?by}DQMn);BT?F7ZEnJ13t!hPU zP^EpRpxEnKHW=XXyn|A1`h+Ig^1|h`$=vICPdiZ13Ysl?q~)-g8*F|8tQK llh9+?wVNdCEf~PDfp2QAPj|0&ecJ#4002ovPDHLkV1niRxds3L delta 261 zcmZ3;Kb2{ML_G^L0|Ud`yN`kx7#MT|d_r6q7#PZ@2YIII#~H{bv^WLkn%%#DUoTwO zEX9J|zkIA>Q02Ngg~8?g~v4lR9#NFXYX% zX(c@mw=!*h^>N#jWF8#{!MCZJSv-wSXB4wC9o#$wHow}q#l@WM8uJ;&<3?UrBqI0> zteJROq68-_zBjc_2C_((JF}urUT~+m>G^{sI9!Xbfpvn0|SGntDnm{ Hr-UW|Y&cq) From 47340386e20501cad0d2e7a0deba2a64a0022c0a Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 3 Nov 2021 20:55:33 +0100 Subject: [PATCH 212/296] Turn parethesized sentence about voluntary work into normal one --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index de3ae536e..6d46237ca 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -343,9 +343,9 @@ at least two different people. requests as a developer. In this case it is your responsibility to fix the issue / review and merge the pull request when it is ready. You can also unassign yourself from the issue / PR if you have no time or don't -want to take care of it for some other reason (after all, everyone is a +want to take care of it for some other reason. After all, everyone is a volunteer and we can't expect you to do work that you are not intrested -in) - **the important thing is that you make sure to inform us if you +in. **The important thing is that you make sure to inform us if you won't take care of something that has been assigned to you.** - Please assign yourself to something that you want to work on to avoid duplicate work. From 4d93e13f80873075b492a35ef340ab49f2b6ff4f Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 3 Nov 2021 20:59:27 +0100 Subject: [PATCH 213/296] Reword developer presence in public discussion rooms rule --- CONTRIBUTING.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6d46237ca..bbe097c0c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -349,9 +349,10 @@ in. **The important thing is that you make sure to inform us if you won't take care of something that has been assigned to you.** - Please assign yourself to something that you want to work on to avoid duplicate work. -- As a developer, it should be easy to reach you about -your code. You should be on the Discord (or, if you really don't like -Discord, Matrix or IRC). +- As a developer, it should be easy to reach you about your work. You +should be in at least one of the public MineClone2 discussion rooms - +preferrably Discord, but if you really don't like Discord, Matrix +or IRC are fine too. ### Maintainer status Maintainers carry the main responsibility for the project. From 6473494cbcf66e2454d33bc7b678dbf0c21ccdd1 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 3 Nov 2021 21:01:43 +0100 Subject: [PATCH 214/296] prioritised -> prioritized --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bbe097c0c..ad9090930 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -13,11 +13,11 @@ whether you're a programmer or not. based on the Minetest engine with polished features, usable in both singleplayer and multiplayer. Currently, most of **Minecraft Java Edition 1.12.2** features are already implemented and polishing existing -features are prioritised over new feature requests. +features are prioritized over new feature requests. - With lessened priority yet strictly, implement features targetting **Minecraft version 1.17 + Optifine** (Optifine only as far as supported by the Minetest Engine). This means features in parity with the listed -Minecraft experiences are prioritised over those that don't fulfill this +Minecraft experiences are prioritized over those that don't fulfill this scope. - Optionally, create a performant experience that will run relatively well on really low spec computers. Unfortunately, due to Minecraft's From c2f0f0297be67de7ddc5775c5a5a63de9b5bb637 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 3 Nov 2021 21:02:15 +0100 Subject: [PATCH 215/296] Optifine -> OptiFine --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ad9090930..ed5d2704d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,7 +15,7 @@ singleplayer and multiplayer. Currently, most of **Minecraft Java Edition 1.12.2** features are already implemented and polishing existing features are prioritized over new feature requests. - With lessened priority yet strictly, implement features targetting -**Minecraft version 1.17 + Optifine** (Optifine only as far as supported +**Minecraft version 1.17 + OptiFine** (OptiFine only as far as supported by the Minetest Engine). This means features in parity with the listed Minecraft experiences are prioritized over those that don't fulfill this scope. From 7c1777c53ac4ae388b1127d0266c5ec801fed4fb Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 3 Nov 2021 21:03:17 +0100 Subject: [PATCH 216/296] minetest -> Minetest --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ed5d2704d..ea1175534 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -75,11 +75,11 @@ channel. However, it is not a bug if you believe something is missing in the game. In this case, please read "Requesting features" * If you report a crash, always include the error message. If you play -in singleplayer, post a screenshot of the message that minetest showed +in singleplayer, post a screenshot of the message that Minetest showed when the crash happened (or copy the message into your issue). If you are a server admin, you can find error messages in the log file of the server. -* Tell us which MineClone2 and minetest versions you are using. +* Tell us which MineClone2 and Minetest versions you are using. * Tell us how to reproduce the problem: What you were doing to trigger the bug, e.g. before the crash happened or what causes the faulty behavior. From faff9316e0b21cc32aa73e5f9fda7993ce56d1f1 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 3 Nov 2021 21:03:58 +0100 Subject: [PATCH 217/296] minecraft -> Minecraft --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ea1175534..e8711bceb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -121,7 +121,7 @@ this is not required. It's also a good idea to join the Discord server #### Textures For textures we use the Pixel Perfection texture pack. This is mostly -enough; however in some cases - e.g. for newer minecraft features, it's +enough; however in some cases - e.g. for newer Minecraft features, it's useful to have texture artists around. If you want to make such contributions, join our Discord server. Demands for textures will be communicated there. From 6000c29171b7bcee909293addb60fb2fe012fd58 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 3 Nov 2021 21:04:52 +0100 Subject: [PATCH 218/296] ressource -> resource --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e8711bceb..3f9186a32 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -129,7 +129,7 @@ communicated there. #### Sounds MineClone2 currently does not have a consistent way to handle sounds. The sounds in the game come from different sources, like the SnowZone -ressource pack or minetest_game. Unfortunately, MineClone2 does not play +resource pack or minetest_game. Unfortunately, MineClone2 does not play a sound in every situation you would get one in Minecraft. Any help with sounds is greatly appreciated, however if you add new sounds you should probably work together with a programmer, to write the code to actually From d6907970111ea975cd3fbbbb1f403721514fef7f Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 3 Nov 2021 21:05:38 +0100 Subject: [PATCH 219/296] commited -> committed --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3f9186a32..f69a83015 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -159,7 +159,7 @@ the translation files for the language you are working on with the template files, to see what is missing and what is out of date with the template file. However, template files are often incomplete and/or out of date, sometimes they don't match the code. You can update the -translation files if that is required, you can also modifiy the code in +translation files if that is required, you can also modify the code in your translation PR if it's related to translation. You can also work on multiple languages at the same time in one PR. From cdf6533e0ac2c1321c5a048d28db3556af6d4161 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 3 Nov 2021 21:06:08 +0100 Subject: [PATCH 220/296] regulary -> regularly --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f69a83015..2246e4bf9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -199,7 +199,7 @@ If you opened or have contributed to an issue, you receive the * Fork the repository (in case you have not already) * Do your change in a new branch * Create a pull request to get your changes merged into master -* Keep your pull request up to date by regulary merging upstream. It is +* Keep your pull request up to date by regularly merging upstream. It is imperative that conflicts are resolved prior to merging the pull request. * After the pull request got merged, you can delete the branch From bb6fe65aa5a3bb04b094f71851067e25b42b901b Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 3 Nov 2021 21:06:35 +0100 Subject: [PATCH 221/296] inadequeate -> inadequate --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2246e4bf9..bc90905e0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -216,7 +216,7 @@ We appreciate any contributing effort to MineClone2. If you are a relatively new programmer, you can reach us on Discord, Matrix or IRC for questions about git, Lua, Minetest API, MineClone2 codebase or anything related to MineClone2. We can help you avoid writing code that -would be deemed inadequeate, or help you become familiar with MineClone2 +would be deemed inadequate, or help you become familiar with MineClone2 better, or assist you use development tools. ### Maintain your own code, even if alreay got merged From e70161501f3a01ac7c1ef3f3e895e1b07f334ec9 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 3 Nov 2021 21:06:58 +0100 Subject: [PATCH 222/296] alreay -> already --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bc90905e0..b9f277a69 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -219,7 +219,7 @@ anything related to MineClone2. We can help you avoid writing code that would be deemed inadequate, or help you become familiar with MineClone2 better, or assist you use development tools. -### Maintain your own code, even if alreay got merged +### Maintain your own code, even if already got merged Sometimes, your code may cause crashes or bugs - we try to avoid such scenarios by testing everytime before merging it, but if your merged work causes problems, we ask you fix the issues as soon as possible. From 18dd1cabd0e523d25323a881071eb717b47bdeea Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 3 Nov 2021 21:07:28 +0100 Subject: [PATCH 223/296] everytime -> every time --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b9f277a69..4e4be4ff7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -221,7 +221,7 @@ better, or assist you use development tools. ### Maintain your own code, even if already got merged Sometimes, your code may cause crashes or bugs - we try to avoid such -scenarios by testing everytime before merging it, but if your merged +scenarios by testing every time before merging it, but if your merged work causes problems, we ask you fix the issues as soon as possible. ### Changing Gameplay From 39f66eb4a025c8e4207ccadd690eb0467b8701be Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 3 Nov 2021 21:08:11 +0100 Subject: [PATCH 224/296] repo -> repository --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4e4be4ff7..b9f443573 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -334,8 +334,8 @@ MineClone2 repository. #### Developer responsibilities - You should not push things directly to MineClone2 master - rather, do your work on a branch on your private -repo, then create a pull request. This way other people can review your -changes and make sure they work before they get merged. +repository, then create a pull request. This way other people can review +your changes and make sure they work before they get merged. - Merge PRs only when they have recieved the necessary feedback and have been tested to not lead to any crashes and do what they claim to do by at least two different people. From 46d1dd42d4f2c5ca4fd839fdf683c102c95ff5e7 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 3 Nov 2021 21:08:47 +0100 Subject: [PATCH 225/296] recieved -> received --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b9f443573..67cc2c3e6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -336,7 +336,7 @@ MineClone2 repository. MineClone2 master - rather, do your work on a branch on your private repository, then create a pull request. This way other people can review your changes and make sure they work before they get merged. -- Merge PRs only when they have recieved the necessary feedback and have +- Merge PRs only when they have received the necessary feedback and have been tested to not lead to any crashes and do what they claim to do by at least two different people. - You may also be assigned to issues or pull From 61d0dc8182d37e2da33e3d6c7d0e082d813e3e20 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 3 Nov 2021 21:09:13 +0100 Subject: [PATCH 226/296] intrested -> interested --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 67cc2c3e6..8ab8ee818 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -344,7 +344,7 @@ requests as a developer. In this case it is your responsibility to fix the issue / review and merge the pull request when it is ready. You can also unassign yourself from the issue / PR if you have no time or don't want to take care of it for some other reason. After all, everyone is a -volunteer and we can't expect you to do work that you are not intrested +volunteer and we can't expect you to do work that you are not interested in. **The important thing is that you make sure to inform us if you won't take care of something that has been assigned to you.** - Please assign yourself to something that you want to work on to avoid From c6e9d763d673816251d37c03eb19318c7bd8a8a6 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 3 Nov 2021 21:09:57 +0100 Subject: [PATCH 227/296] repo -> repository (in release process documentation) --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8ab8ee818..2b1f16ad8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -378,7 +378,7 @@ technical guidelines and issue/PR delegation * Update the version number in README.md * Use `git tag ` to tag the latest commit with the version number -* Push to repo (don't forget `--tags`!) +* Push to repository (don't forget `--tags`!) * Update ContentDB (https://content.minetest.net/packages/Wuzzy/mineclone2/) * Update first post in forum thread From 24ca8252a9aa97303475b6e15aac21ac65f0804f Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 3 Nov 2021 21:14:22 +0100 Subject: [PATCH 228/296] community wants -> community feedback --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2b1f16ad8..961e16cee 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -362,7 +362,7 @@ Maintainers carry the main responsibility for the project. merged, by assigning either themselves or Developers to issues / PRs - Making releases - Making sure guidelines are kept -- Making project decisions based on what the community wants +- Making project decisions based on community feedback - Granting/revoking developer access - Enforcing the code of conduct (See CODE_OF_CONDUCT.md) - Moderating official community spaces (See Links section) From a77e79d985fc384ea49810b1feb2d625a9c9feac Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 3 Nov 2021 21:15:20 +0100 Subject: [PATCH 229/296] where the real troublespots are -> places to investigate optimization issues --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 961e16cee..7abbcc5ea 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -171,8 +171,8 @@ credited in the Contributors section. ### Profiling If you own a server, a great way to help us improve MineClone2's code is by giving us profiler results. Profiler results give us detailed -information about the game's performance and let us know where the real -troublespots are. This way we can make the game faster. +information about the game's performance and let us know places to +investigate optimization issues. This way we can make the game faster. #### Using Minetest's profiler Minetest has a built in profiler. Simply set `profiler.load = true` in From f9e7f584926946148c22675fa816e30ab8e366d0 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Thu, 4 Nov 2021 12:21:06 +0100 Subject: [PATCH 230/296] Reword necessary PR feedback section --- CONTRIBUTING.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7abbcc5ea..5d84ea47b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -336,9 +336,9 @@ MineClone2 repository. MineClone2 master - rather, do your work on a branch on your private repository, then create a pull request. This way other people can review your changes and make sure they work before they get merged. -- Merge PRs only when they have received the necessary feedback and have -been tested to not lead to any crashes and do what they claim to do by -at least two different people. +- Merge PRs only when they have recieved the necessary feedback and have +been tested by at least two different people (including the author of +the pull request), to avoid crashes or the introduction of new bugs. - You may also be assigned to issues or pull requests as a developer. In this case it is your responsibility to fix the issue / review and merge the pull request when it is ready. You can From b937b38b1c24f14e25e24621978110ed1b7602bd Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Thu, 4 Nov 2021 12:26:14 +0100 Subject: [PATCH 231/296] Separate translations and assets --- CONTRIBUTING.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5d84ea47b..5e00fddd8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -142,9 +142,14 @@ Similar to the textures, we need people that can make 3D Models with Blender on demand. Many of the models have to be patched, some new animations have to be added etc. -#### Translations +#### Crediting +Asset contributions will be credited in their own respective sections in +CREDITS.md. If you have commited the results yourself, you will also be +credited in the Contributors section. -##### Workflow +### Contributing Translations + +#### Workflow To add/update support for your language to MineClone2, you should take the steps documented in the section for Programmers, add/update the translation files of the mods that you want to update. You can add @@ -153,7 +158,7 @@ the translation file entirely or only partly; basically any effort is valued. If your changes are small, you can also send them to developers via E-Mail, Discord, IRC or Matrix - they will credit you appropriately. -##### Things to note +#### Things to note You can use the script at `tools/check_translate_files.py` to compare the translation files for the language you are working on with the template files, to see what is missing and what is out of date with @@ -164,9 +169,9 @@ your translation PR if it's related to translation. You can also work on multiple languages at the same time in one PR. #### Crediting -Asset contributions will be credited in their own respective sections in -CREDITS.md. If you have commited the results yourself, you will also be -credited in the Contributors section. +Translation contributions will be credited in their own in CREDITS.md. +If you have commited the results yourself, you will also be credited in +the Contributors section. ### Profiling If you own a server, a great way to help us improve MineClone2's code From 649f481b51162e4314da28c58769d9730e9b216c Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Thu, 4 Nov 2021 12:28:36 +0100 Subject: [PATCH 232/296] provide example for non-descriptive title --- CONTRIBUTING.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5e00fddd8..9be680d6a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -54,7 +54,8 @@ you can report a bug or request a feature. ### Rules about both bugs and feature requests * Stay polite towards the developers and anyone else involved in the discussion. -* Choose a descriptive title. +* Choose a descriptive title (e.g. not just "crash", "bug" or "question" +). * Please write in plain, understandable English. It will be easier to communicate. * Please start the issue title with a capital letter. From 4a3a8841cdf956807e4b97a7dee2774ae873a930 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Thu, 4 Nov 2021 12:31:13 +0100 Subject: [PATCH 233/296] Add ingame credits script to release process --- CONTRIBUTING.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9be680d6a..e8ea2bf5b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -380,6 +380,8 @@ technical guidelines and issue/PR delegation * Nicu - responsible for community related issues #### Release process +* Run `tools/generate_ingame_credits.lua` to update the ingame credits +from `CREDITS.md` and commit the result (if anything changed) * Launch MineClone2 to make sure it still runs * Update the version number in README.md * Use `git tag ` to tag the latest commit with the From ce4c0ed4c199028ebb69614629e7ece31a395e4b Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Thu, 4 Nov 2021 12:56:34 +0100 Subject: [PATCH 234/296] free -> free/libre --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e8ea2bf5b..de13bce7d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -396,7 +396,7 @@ version number ### Licensing By asking us to include your changes in this game, you agree that they fall under the terms of the GPLv3, which basically means they will -become part of a free software. +become part of a free/libre software. ### Crediting Contributors, Developers and Maintainers will be credited in From be86b603f8391d733f174bb6ccd44869f8327948 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Thu, 4 Nov 2021 13:14:35 +0100 Subject: [PATCH 235/296] Update README.md to reflect new contribution guidelines --- README.md | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 034d381ab..fe32f0039 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# MineClone 2 +# MineClone2 An unofficial Minecraft-like game for Minetest. Forked from MineClone by davedevils. Developed by many people. Not developed or endorsed by Mojang AB. @@ -69,9 +69,9 @@ an explanation. This game requires [Minetest](http://minetest.net) to run (version 5.3.0 or later). So you need to install Minetest first. Only stable versions of Minetest are officially supported. -There is no support for running MineClone 2 in development versions of Minetest. +There is no support for running MineClone2 in development versions of Minetest. -To install MineClone 2 (if you haven't already), move this directory into the +To install MineClone2 (if you haven't already), move this directory into the “games” directory of your Minetest data directory. Consult the help of Minetest to learn more. @@ -86,20 +86,21 @@ The MineClone2 repository is hosted at Mesehub. To contribute or report issues, * Reddit: * Minetest forums: -## Project description -The main goal of **MineClone 2** is to be a clone of Minecraft and to be released as free software. - -* **Target of development: Minecraft, PC Edition, version 1.12** (later known as “Java Edition”) -* MineClone2 also includes Optifine features supported by the Minetest -* In general, Minecraft is aimed to be cloned as good as possible -* Cloning the gameplay has highest priority -* MineClone 2 will use different assets, but with a similar style -* Limitations found in Minetest will be documented in the course of development -* Features of later Minecraft versions are collected in the mineclone5 branch - -## Using features from newer versions of Minecraft -For > 1.12 features, checkout MineClone5. It includes features from newer Minecraft versions. -Download it here: https://git.minetest.land/MineClone2/MineClone2/src/branch/mineclone5 +## Target +- Crucially, create a stable, moddable, free/libre clone of Minecraft +based on the Minetest engine with polished features, usable in both +singleplayer and multiplayer. Currently, most of **Minecraft Java +Edition 1.12.2** features are already implemented and polishing existing +features are prioritized over new feature requests. +- With lessened priority yet strictly, implement features targetting +**Minecraft version 1.17 + OptiFine** (OptiFine only as far as supported +by the Minetest Engine). This means features in parity with the listed +Minecraft experiences are prioritized over those that don't fulfill this +scope. +- Optionally, create a performant experience that will run relatively +well on really low spec computers. Unfortunately, due to Minecraft's +mechanisms and Minetest engine's limitations along with a very small +playerbase on low spec computers, optimizations are hard to investigate. ## Completion status This game is currently in **beta** stage. @@ -186,7 +187,7 @@ Technical differences from Minecraft: * Different engine (Minetest) * Different easter eggs -… and finally, MineClone 2 is free software (“free” as in “freedom”)! +… and finally, MineClone2 is free software (“free” as in “freedom”)! ## Other readme files From 23ca11c8e1b0f4e802ea5b41ac63c32136dc760a Mon Sep 17 00:00:00 2001 From: Nils Dagsson Moskopp Date: Thu, 4 Nov 2021 01:53:58 +0100 Subject: [PATCH 236/296] Use RLE compression in tga_encoder --- mods/CORE/tga_encoder/init.lua | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/mods/CORE/tga_encoder/init.lua b/mods/CORE/tga_encoder/init.lua index 96afda5e1..973e44855 100644 --- a/mods/CORE/tga_encoder/init.lua +++ b/mods/CORE/tga_encoder/init.lua @@ -38,18 +38,31 @@ function image:encode_header() self.data = self.data .. string.char(0) -- image id .. string.char(0) -- color map type - .. string.char(2) -- image type (uncompressed true-color image = 2) + .. string.char(10) -- image type (RLE RGB = 10) self:encode_colormap_spec() -- color map specification self:encode_image_spec() -- image specification end function image:encode_data() + local current_pixel = '' + local previous_pixel = '' + local count = 1 + local encoded = '' + local rle_packet = '' for _, row in ipairs(self.pixels) do for _, pixel in ipairs(row) do - self.data = self.data - .. string.char(pixel[3], pixel[2], pixel[1]) + current_pixel = string.char(pixel[3], pixel[2], pixel[1]) + if current_pixel ~= previous_pixel or count == 128 then + encoded = encoded .. rle_packet + count = 1 + previous_pixel = current_pixel + else + count = count + 1 + end + rle_packet = string.char(128 + count - 1) .. current_pixel end end + self.data = self.data .. encoded .. rle_packet end function image:encode_footer() From 4926c0560da96ef4d0677487212fac519f6c2083 Mon Sep 17 00:00:00 2001 From: Nils Dagsson Moskopp Date: Thu, 4 Nov 2021 15:15:28 +0100 Subject: [PATCH 237/296] Speed up TGA encoding by creating fewer strings --- mods/CORE/tga_encoder/init.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mods/CORE/tga_encoder/init.lua b/mods/CORE/tga_encoder/init.lua index 973e44855..39309c9c9 100644 --- a/mods/CORE/tga_encoder/init.lua +++ b/mods/CORE/tga_encoder/init.lua @@ -47,13 +47,13 @@ function image:encode_data() local current_pixel = '' local previous_pixel = '' local count = 1 - local encoded = '' + local packets = {} local rle_packet = '' for _, row in ipairs(self.pixels) do for _, pixel in ipairs(row) do current_pixel = string.char(pixel[3], pixel[2], pixel[1]) if current_pixel ~= previous_pixel or count == 128 then - encoded = encoded .. rle_packet + packets[#packets +1] = rle_packet count = 1 previous_pixel = current_pixel else @@ -62,7 +62,8 @@ function image:encode_data() rle_packet = string.char(128 + count - 1) .. current_pixel end end - self.data = self.data .. encoded .. rle_packet + packets[#packets +1] = rle_packet + self.data = self.data .. table.concat(packets) end function image:encode_footer() From d1d11f97406500ada5fe8e29577a36bd5bd6bf31 Mon Sep 17 00:00:00 2001 From: Dieter44 <55900078+Dieter44@users.noreply.github.com> Date: Thu, 4 Nov 2021 20:58:54 +0100 Subject: [PATCH 238/296] Fixed debug hudbars for player saturation and exhaustion when mcl_hunger_debug=true is set in .config file --- mods/PLAYER/mcl_hunger/init.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/PLAYER/mcl_hunger/init.lua b/mods/PLAYER/mcl_hunger/init.lua index 8c154700a..90a622a18 100644 --- a/mods/PLAYER/mcl_hunger/init.lua +++ b/mods/PLAYER/mcl_hunger/init.lua @@ -91,8 +91,8 @@ end -- register saturation hudbar hb.register_hudbar("hunger", 0xFFFFFF, S("Food"), { icon = "hbhunger_icon.png", bgicon = "hbhunger_bgicon.png", bar = "hbhunger_bar.png" }, 1, 20, 20, false) if mcl_hunger.debug then - hb.register_hudbar("saturation", 0xFFFFFF, S("Saturation"), { icon = "mcl_hunger_icon_saturation.png", bgicon = "mcl_hunger_bgicon_saturation.png", bar = "mcl_hunger_bar_saturation.png" }, 1, mcl_hunger.SATURATION_INIT, 200, false, S("%s: %.1f/%d")) - hb.register_hudbar("exhaustion", 0xFFFFFF, S("Exhaust."), { icon = "mcl_hunger_icon_exhaustion.png", bgicon = "mcl_hunger_bgicon_exhaustion.png", bar = "mcl_hunger_bar_exhaustion.png" }, 1, 0, mcl_hunger.EXHAUST_LVL, false, S("%s: %d/%d")) + hb.register_hudbar("saturation", 0xFFFFFF, S("Saturation"), { icon = "mcl_hunger_icon_saturation.png", bgicon = "mcl_hunger_bgicon_saturation.png", bar = "mcl_hunger_bar_saturation.png" }, 1, mcl_hunger.SATURATION_INIT, 200, false) + hb.register_hudbar("exhaustion", 0xFFFFFF, S("Exhaust."), { icon = "mcl_hunger_icon_exhaustion.png", bgicon = "mcl_hunger_bgicon_exhaustion.png", bar = "mcl_hunger_bar_exhaustion.png" }, 1, 0, mcl_hunger.EXHAUST_LVL, false) end minetest.register_on_joinplayer(function(player) From d0d60804a39da1b8d8a980861440b1146747ec20 Mon Sep 17 00:00:00 2001 From: Dieter44 <55900078+Dieter44@users.noreply.github.com> Date: Thu, 4 Nov 2021 21:01:28 +0100 Subject: [PATCH 239/296] Implemented health regeneration mechanics as described in minecraft wiki. Saturation values and different regeneration speeds now used. --- mods/PLAYER/mcl_hunger/init.lua | 84 +++++++++++++++++++-------------- 1 file changed, 48 insertions(+), 36 deletions(-) diff --git a/mods/PLAYER/mcl_hunger/init.lua b/mods/PLAYER/mcl_hunger/init.lua index 90a622a18..535ccbed1 100644 --- a/mods/PLAYER/mcl_hunger/init.lua +++ b/mods/PLAYER/mcl_hunger/init.lua @@ -134,46 +134,58 @@ minetest.register_on_player_hpchange(function(player, hp_change) end end) -local main_timer = 0 -local timer = 0 -- Half second timer -local timerMult = 1 -- Cycles from 0 to 7, each time when timer hits half a second -minetest.register_globalstep(function(dtime) - main_timer = main_timer + dtime - timer = timer + dtime - if main_timer > mcl_hunger.HUD_TICK or timer > 0.25 then - if main_timer > mcl_hunger.HUD_TICK then main_timer = 0 end - for _,player in pairs(minetest.get_connected_players()) do - local name = player:get_player_name() - local h = tonumber(mcl_hunger.get_hunger(player)) - local hp = player:get_hp() - if timer > 0.25 then - -- Slow health regeneration, and hunger damage (every 4s). - -- Regeneration rate based on tutorial video . - -- Minecraft Wiki seems to be wrong in claiming that full hunger gives 0.5s regen rate. - if timerMult == 0 then - if h >= 18 and hp > 0 and hp < 20 then - -- +1 HP, +exhaustion - player:set_hp(hp+1) - mcl_hunger.exhaust(name, mcl_hunger.EXHAUST_REGEN) - mcl_hunger.update_exhaustion_hud(player, mcl_hunger.get_exhaustion(player)) - elseif h == 0 then - -- Damage hungry player down to 1 HP - -- TODO: Allow starvation at higher difficulty levels - if hp-1 > 0 then - mcl_util.deal_damage(player, 1, {type = "starve"}) + +local fastFoodTickTimer = 0 -- 0.5 second cycle +local slowFoodTickTimer = 0 -- 4 second cycle +minetest.register_globalstep(function(dtime) + fastFoodTickTimer = fastFoodTickTimer + dtime + slowFoodTickTimer = slowFoodTickTimer + dtime + + local fastTimerWrapped = false -- if the fastFoodTickTimer wrapped around and everything dependent should be updated + local slowTimerWrapped = false + + if fastFoodTickTimer > 0.5 then + fastFoodTickTimer = 0 + fastTimerWrapped = true + end + if slowFoodTickTimer > 4.0 then + slowFoodTickTimer = 0 + slowTimerWrapped = true + end + + if fastTimerWrapped or slowTimerWrapped then -- only update players if something must be updated + for _,player in ipairs(minetest.get_connected_players()) do + + local playerName = player:get_player_name() + local foodLevel = mcl_hunger.get_hunger(player) + local foodSaturationLevel = mcl_hunger.get_saturation(player) + local playerHealth = player:get_hp() + + if playerHealth < 20 then + if foodLevel == 20 and foodSaturationLevel >= 6 then -- fast regeneration (2 health per second) + if fastTimerWrapped then + player:set_hp(playerHealth+1) + mcl_hunger.exhaust(playerName, mcl_hunger.EXHAUST_REGEN) + mcl_hunger.update_exhaustion_hud(player, mcl_hunger.get_exhaustion(player)) + end + elseif foodLevel >= 18 then -- slow regeneration (1 health every 4 seconds) + if slowTimerWrapped then + player:set_hp(playerHealth+1) + mcl_hunger.exhaust(playerName, mcl_hunger.EXHAUST_REGEN) + mcl_hunger.update_exhaustion_hud(player, mcl_hunger.get_exhaustion(player)) end end end - - end - end - end - if timer > 0.25 then - timer = 0 - timerMult = timerMult + 2 - if timerMult > 7 then - timerMult = 0 + + if foodLevel == 0 then --starvation + maximumStarvation = 1 -- the amount of health at which a player will stop to get harmed by starvation (10 for Easy, 1 for Normal, 0 for Hard) + -- TODO: implement Minecraft-like difficulty modes and the update maximumStarvation here + if playerHealth > maximumStarvation and slowTimerWrapped then + mcl_util.deal_damage(player, 1, {type = "starve"}) + end + end + end end end) From 1b259f928bb32e30208235d17560097ba059b047 Mon Sep 17 00:00:00 2001 From: NO11 Date: Sat, 6 Nov 2021 13:12:03 +0000 Subject: [PATCH 240/296] Add simple bone meal API - callback api - particle api --- mods/ITEMS/mcl_dye/init.lua | 83 ++++++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 34 deletions(-) diff --git a/mods/ITEMS/mcl_dye/init.lua b/mods/ITEMS/mcl_dye/init.lua index b9b5d92ac..274e31fcf 100644 --- a/mods/ITEMS/mcl_dye/init.lua +++ b/mods/ITEMS/mcl_dye/init.lua @@ -128,26 +128,35 @@ for _, row in ipairs(dyelocal.dyes) do end -- Bone Meal -local function bone_meal_particle(pos) +function mcl_dye.add_bone_meal_particle(pos, def) + if not def then + def = {} + end minetest.add_particlespawner({ - amount = 10, - time = 0.1, - minpos = { x = pos.x - 0.5, y = pos.y - 0.5, z = pos.z - 0.5 }, - maxpos = { x = pos.x + 0.5, y = pos.y + 0.5, z = pos.z + 0.5 }, - minvel = { x = 0, y = 0, z = 0}, - maxvel = { x = 0, y = 0, z = 0}, - minacc = { x = 0, y = 0, z = 0}, - maxacc = { x = 0, y = 0, z = 0}, - minexptime = 1, - maxexptime = 4, - minsize = 0.7, - maxsize = 2.4, + amount = def.amount or 10, + time = def.time or 0.1, + minpos = def.minpos or vector.subtract(pos, 0.5), + maxpos = def.maxpos or vector.add(pos, 0.5), + minvel = def.minvel or vector.new(0, 0, 0), + maxvel = def.maxvel or vector.new(0, 0, 0), + minacc = def.minacc or vector.new(0, 0, 0), + minacc = def.minacc or vector.new(0, 0, 0), + minexptime = def.minexptime or 1, + maxexptime = def.maxexptime or 4, + minsize = def.minsize or 0.7, + maxsize = def.maxsize or 2.4, texture = "mcl_particles_bonemeal.png^[colorize:#00EE00:125", -- TODO: real MC color - glow = 5, + glow = def.glow or 5, }) end -function mcl_dye.apply_bone_meal(pointed_thing) +mcl_dye.bone_meal_callbacks = {} + +function mcl_dye.register_on_bone_meal_apply(func) + table.insert(mcl_dye.bone_meal_callbacks, func) +end + +local function apply_bone_meal(pointed_thing) -- Bone meal currently spawns all flowers found in the plains. local flowers_table_plains = { "mcl_flowers:dandelion", @@ -183,14 +192,21 @@ function mcl_dye.apply_bone_meal(pointed_thing) local pos = pointed_thing.under local n = minetest.get_node(pos) if n.name == "" then return false end + + for _, func in pairs(mcl_dye.bone_meal_callbacks) do + if func(pointed_thing, user) then + return true + end + end + if minetest.get_item_group(n.name, "sapling") >= 1 then - bone_meal_particle(pos) + mcl_dye.add_bone_meal_particle(pos) -- Saplings: 45% chance to advance growth stage if math.random(1,100) <= 45 then return mcl_core.grow_sapling(pos, n) end elseif minetest.get_item_group(n.name, "mushroom") == 1 then - bone_meal_particle(pos) + mcl_dye.add_bone_meal_particle(pos) -- Try to grow huge mushroom -- Must be on a dirt-type block @@ -240,39 +256,37 @@ function mcl_dye.apply_bone_meal(pointed_thing) return false -- Wheat, Potato, Carrot, Pumpkin Stem, Melon Stem: Advance by 2-5 stages elseif string.find(n.name, "mcl_farming:wheat_") then - bone_meal_particle(pos) + mcl_dye.add_bone_meal_particle(pos) local stages = math.random(2, 5) return mcl_farming:grow_plant("plant_wheat", pos, n, stages, true) elseif string.find(n.name, "mcl_farming:potato_") then - bone_meal_particle(pos) + mcl_dye.add_bone_meal_particle(pos) local stages = math.random(2, 5) return mcl_farming:grow_plant("plant_potato", pos, n, stages, true) elseif string.find(n.name, "mcl_farming:carrot_") then - bone_meal_particle(pos) + mcl_dye.add_bone_meal_particle(pos) local stages = math.random(2, 5) return mcl_farming:grow_plant("plant_carrot", pos, n, stages, true) elseif string.find(n.name, "mcl_farming:pumpkin_") then - bone_meal_particle(pos) + mcl_dye.add_bone_meal_particle(pos) local stages = math.random(2, 5) return mcl_farming:grow_plant("plant_pumpkin_stem", pos, n, stages, true) elseif string.find(n.name, "mcl_farming:melontige_") then - bone_meal_particle(pos) + mcl_dye.add_bone_meal_particle(pos) local stages = math.random(2, 5) return mcl_farming:grow_plant("plant_melon_stem", pos, n, stages, true) elseif string.find(n.name, "mcl_farming:beetroot_") then - bone_meal_particle(pos) + mcl_dye.add_bone_meal_particle(pos) -- Beetroot: 75% chance to advance to next stage if math.random(1, 100) <= 75 then return mcl_farming:grow_plant("plant_beetroot", pos, n, 1, true) end elseif n.name == "mcl_cocoas:cocoa_1" or n.name == "mcl_cocoas:cocoa_2" then - bone_meal_particle(pos) + mcl_dye.add_bone_meal_particle(pos) -- Cocoa: Advance by 1 stage mcl_cocoas.grow(pos) return true elseif minetest.get_item_group(n.name, "grass_block") == 1 then - local grass_block_pos = {x = pos.x, y = pos.y + 1, z = pos.z} - bone_meal_particle(grass_block_pos) -- Grass Block: Generate tall grass and random flowers all over the place for i = -2, 2 do for j = -2, 2 do @@ -285,6 +299,7 @@ function mcl_dye.apply_bone_meal(pointed_thing) -- Randomly generate flowers, tall grass or nothing if math.random(1,100) <= 90 then -- 90% tall grass, 10% flower + mcl_dye.add_bone_meal_particle(pos, {amount = 4}) if math.random(1,100) <= 90 then local col = n2.param2 minetest.add_node(pos, {name="mcl_flowers:tallgrass", param2=col}) @@ -314,24 +329,24 @@ function mcl_dye.apply_bone_meal(pointed_thing) -- Double flowers: Drop corresponding item elseif n.name == "mcl_flowers:rose_bush" or n.name == "mcl_flowers:rose_bush_top" then - bone_meal_particle(pos) + mcl_dye.add_bone_meal_particle(pos) minetest.add_item(pos, "mcl_flowers:rose_bush") return true elseif n.name == "mcl_flowers:peony" or n.name == "mcl_flowers:peony_top" then - bone_meal_particle(pos) + mcl_dye.add_bone_meal_particle(pos) minetest.add_item(pos, "mcl_flowers:peony") return true elseif n.name == "mcl_flowers:lilac" or n.name == "mcl_flowers:lilac_top" then - bone_meal_particle(pos) + mcl_dye.add_bone_meal_particle(pos) minetest.add_item(pos, "mcl_flowers:lilac") return true elseif n.name == "mcl_flowers:sunflower" or n.name == "mcl_flowers:sunflower_top" then - bone_meal_particle(pos) + mcl_dye.add_bone_meal_particle(pos) minetest.add_item(pos, "mcl_flowers:sunflower") return true elseif n.name == "mcl_flowers:tallgrass" then - bone_meal_particle(pos) + mcl_dye.add_bone_meal_particle(pos) -- Tall Grass: Grow into double tallgrass local toppos = { x=pos.x, y=pos.y+1, z=pos.z } local topnode = minetest.get_node(toppos) @@ -342,7 +357,7 @@ function mcl_dye.apply_bone_meal(pointed_thing) end elseif n.name == "mcl_flowers:fern" then - bone_meal_particle(pos) + mcl_dye.add_bone_meal_particle(pos) -- Fern: Grow into large fern local toppos = { x=pos.x, y=pos.y+1, z=pos.z } local topnode = minetest.get_node(toppos) @@ -374,7 +389,7 @@ minetest.register_craftitem("mcl_dye:white", { end -- Use the bone meal on the ground - if(mcl_dye.apply_bone_meal(pointed_thing) and (not minetest.is_creative_enabled(user:get_player_name()))) then + if (apply_bone_meal(pointed_thing, user) and (not minetest.is_creative_enabled(user:get_player_name()))) then itemstack:take_item() end return itemstack @@ -387,7 +402,7 @@ minetest.register_craftitem("mcl_dye:white", { else pointed_thing = { above = pos, under = droppos } end - local success = mcl_dye.apply_bone_meal(pointed_thing) + local success = apply_bone_meal(pointed_thing, nil) if success then stack:take_item() end From 7bbc1e99519e12e47e0f88d84b9a999aa0affdb4 Mon Sep 17 00:00:00 2001 From: NO11 Date: Sat, 6 Nov 2021 13:34:22 +0000 Subject: [PATCH 241/296] Add API.md for bone meal API --- mods/ITEMS/mcl_dye/API.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 mods/ITEMS/mcl_dye/API.md diff --git a/mods/ITEMS/mcl_dye/API.md b/mods/ITEMS/mcl_dye/API.md new file mode 100644 index 000000000..04169f966 --- /dev/null +++ b/mods/ITEMS/mcl_dye/API.md @@ -0,0 +1,14 @@ +# mcl_dye + +# Bone meal API +Callback and particle functions. + +## mcl_dye.add_bone_meal_particle(pos, def) +Spawns standard or custom bone meal particles. +* `pos`: position, is ignored if you define def.minpos and def.maxpos +* `def`: (optional) particle definition + +## mcl_dye.register_on_bone_meal_apply(function(pointed_thing, user)) +Called when the bone meal is applied anywhere. +* `pointed_thing`: exact pointing location (see Minetest API), where the bone meal is applied +* `user`: ObjectRef of the player who aplied the bone meal, can be nil! \ No newline at end of file From ea46c8741bc8e89b789ff63ef3e989e8e490ec37 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sun, 7 Nov 2021 20:29:11 +0100 Subject: [PATCH 242/296] Add OpenCollective link and credits --- CONTRIBUTING.md | 8 ++++++++ CREDITS.md | 3 +++ README.md | 1 + mods/HUD/mcl_credits/people.lua | 3 +++ tools/generate_ingame_credits.lua | 1 + 5 files changed, 16 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index de13bce7d..27a820d87 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -32,6 +32,7 @@ playerbase on low spec computers, optimizations are hard to investigate. * [Matrix](https://app.element.io/#/room/#mc2:matrix.org) * [Reddit](https://www.reddit.com/r/MineClone2/) * [Minetest forums](https://forum.minetest.net/viewtopic.php?f=50&t=16407) +* [OpenCollective](https://opencollective.com/mineclone2) ## Using git MineClone2 is developed using the version control system @@ -194,9 +195,16 @@ MeseHub, let us know what you think about a topic and help us make decisions. Also, note that a lot of discussion takes place on the Discord server, so it's definitely worth checking it out. +### Funding +You can help pay for our infrastructure (Mesehub) by donating to our +OpenCollective link (See Links section). + ### Crediting If you opened or have contributed to an issue, you receive the `Community` role on our Discord (after asking for it). +OpenCollective Funders are credited in their own section in +`CREDITS.md` and receive a special role "Funder" on our discord (unless +they have made their donation Incognito). ## How you can help as a programmer (Almost) all the MineClone2 development is done using pull requests. diff --git a/CREDITS.md b/CREDITS.md index 95884dcac..dfbe58375 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -130,6 +130,9 @@ * todoporlalibertad * Marcin Serwin +## Funders +* 40W + ## Special thanks * celeron55 for creating Minetest * Jordach for the jukebox music compilation from Big Freaking Dig diff --git a/README.md b/README.md index fe32f0039..b8dc50f1f 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,7 @@ The MineClone2 repository is hosted at Mesehub. To contribute or report issues, * Matrix: * Reddit: * Minetest forums: +* OpenCollective: ## Target - Crucially, create a stable, moddable, free/libre clone of Minecraft diff --git a/mods/HUD/mcl_credits/people.lua b/mods/HUD/mcl_credits/people.lua index 2861b5052..8f1d4c2e9 100644 --- a/mods/HUD/mcl_credits/people.lua +++ b/mods/HUD/mcl_credits/people.lua @@ -132,6 +132,9 @@ return { "todoporlalibertad", "Marcin Serwin", }}, + {S("Funders"), 0xF7FF00, { + "40W", + }}, {S("Special thanks"), 0x00E9FF, { "celeron55 for creating Minetest", "Jordach for the jukebox music compilation from Big Freaking Dig", diff --git a/tools/generate_ingame_credits.lua b/tools/generate_ingame_credits.lua index 89b633ef0..db124aaf6 100755 --- a/tools/generate_ingame_credits.lua +++ b/tools/generate_ingame_credits.lua @@ -13,6 +13,7 @@ local colors = { ["3D Models"] = "0x0019FF", ["Textures"] = "0xFF9705", ["Translations"] = "0x00FF60", + ["Funders"] = "0xF7FF00", ["Special thanks"] = "0x00E9FF", } From a34ae040c8ea78d8a4f697bbce7485365f549f0a Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 8 Nov 2021 14:02:22 +0100 Subject: [PATCH 243/296] Add ContentDB links --- CONTRIBUTING.md | 1 + README.md | 1 + 2 files changed, 2 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 27a820d87..a7383df79 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -32,6 +32,7 @@ playerbase on low spec computers, optimizations are hard to investigate. * [Matrix](https://app.element.io/#/room/#mc2:matrix.org) * [Reddit](https://www.reddit.com/r/MineClone2/) * [Minetest forums](https://forum.minetest.net/viewtopic.php?f=50&t=16407) +* [ContentDB](https://content.minetest.net/packages/wuzzy/mineclone2/) * [OpenCollective](https://opencollective.com/mineclone2) ## Using git diff --git a/README.md b/README.md index b8dc50f1f..8f8f0b1e6 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,7 @@ The MineClone2 repository is hosted at Mesehub. To contribute or report issues, * Matrix: * Reddit: * Minetest forums: +* ContentDB: * OpenCollective: ## Target From 30ce6f8a779d5f4a3ab564c46b3d7ecbdaaf11b5 Mon Sep 17 00:00:00 2001 From: NO11 Date: Mon, 8 Nov 2021 13:16:20 +0000 Subject: [PATCH 244/296] Fix typo min -> max --- mods/ITEMS/mcl_dye/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_dye/init.lua b/mods/ITEMS/mcl_dye/init.lua index 274e31fcf..2f6b0f105 100644 --- a/mods/ITEMS/mcl_dye/init.lua +++ b/mods/ITEMS/mcl_dye/init.lua @@ -140,7 +140,7 @@ function mcl_dye.add_bone_meal_particle(pos, def) minvel = def.minvel or vector.new(0, 0, 0), maxvel = def.maxvel or vector.new(0, 0, 0), minacc = def.minacc or vector.new(0, 0, 0), - minacc = def.minacc or vector.new(0, 0, 0), + maxacc = def.maxacc or vector.new(0, 0, 0), minexptime = def.minexptime or 1, maxexptime = def.maxexptime or 4, minsize = def.minsize or 0.7, From 976f522b9d25952768a77f7d6a9ae990d186da37 Mon Sep 17 00:00:00 2001 From: Dieter44 <55900078+Dieter44@users.noreply.github.com> Date: Mon, 8 Nov 2021 15:33:53 +0100 Subject: [PATCH 245/296] Combine slowFoodTickTimer and fastFoodTickTimer to a single food_tick_timer --- mods/PLAYER/mcl_hunger/init.lua | 69 +++++++++++++-------------------- 1 file changed, 27 insertions(+), 42 deletions(-) diff --git a/mods/PLAYER/mcl_hunger/init.lua b/mods/PLAYER/mcl_hunger/init.lua index 535ccbed1..0405c28ef 100644 --- a/mods/PLAYER/mcl_hunger/init.lua +++ b/mods/PLAYER/mcl_hunger/init.lua @@ -136,57 +136,42 @@ end) -local fastFoodTickTimer = 0 -- 0.5 second cycle -local slowFoodTickTimer = 0 -- 4 second cycle + +local food_tick_timer = 0 minetest.register_globalstep(function(dtime) - fastFoodTickTimer = fastFoodTickTimer + dtime - slowFoodTickTimer = slowFoodTickTimer + dtime + food_tick_timer = food_tick_timer + dtime - local fastTimerWrapped = false -- if the fastFoodTickTimer wrapped around and everything dependent should be updated - local slowTimerWrapped = false - - if fastFoodTickTimer > 0.5 then - fastFoodTickTimer = 0 - fastTimerWrapped = true - end - if slowFoodTickTimer > 4.0 then - slowFoodTickTimer = 0 - slowTimerWrapped = true - end - - if fastTimerWrapped or slowTimerWrapped then -- only update players if something must be updated - for _,player in ipairs(minetest.get_connected_players()) do + for _,player in ipairs(minetest.get_connected_players()) do + + local player_name = player:get_player_name() + local food_level = mcl_hunger.get_hunger(player) + local food_saturation_level = mcl_hunger.get_saturation(player) + local player_health = player:get_hp() + + if food_tick_timer > 4.0 then + food_tick_timer = 0 - local playerName = player:get_player_name() - local foodLevel = mcl_hunger.get_hunger(player) - local foodSaturationLevel = mcl_hunger.get_saturation(player) - local playerHealth = player:get_hp() + if food_level >= 18 and player_health < 20 then --slow regenration + food_tick_timer = 0 + player:set_hp(player_health+1) + mcl_hunger.exhaust(player_name, mcl_hunger.EXHAUST_REGEN) + mcl_hunger.update_exhaustion_hud(player, mcl_hunger.get_exhaustion(player)) - if playerHealth < 20 then - if foodLevel == 20 and foodSaturationLevel >= 6 then -- fast regeneration (2 health per second) - if fastTimerWrapped then - player:set_hp(playerHealth+1) - mcl_hunger.exhaust(playerName, mcl_hunger.EXHAUST_REGEN) - mcl_hunger.update_exhaustion_hud(player, mcl_hunger.get_exhaustion(player)) - end - elseif foodLevel >= 18 then -- slow regeneration (1 health every 4 seconds) - if slowTimerWrapped then - player:set_hp(playerHealth+1) - mcl_hunger.exhaust(playerName, mcl_hunger.EXHAUST_REGEN) - mcl_hunger.update_exhaustion_hud(player, mcl_hunger.get_exhaustion(player)) - end - end - end - - if foodLevel == 0 then --starvation - maximumStarvation = 1 -- the amount of health at which a player will stop to get harmed by starvation (10 for Easy, 1 for Normal, 0 for Hard) + elseif food_level == 0 then --starvation + maximumStarvation = 1 --the amount of health at which a player will stop to get harmed by starvation (10 for Easy, 1 for Normal, 0 for Hard) -- TODO: implement Minecraft-like difficulty modes and the update maximumStarvation here - if playerHealth > maximumStarvation and slowTimerWrapped then + if player_health > maximumStarvation then mcl_util.deal_damage(player, 1, {type = "starve"}) end end - + + elseif food_tick_timer > 0.5 and food_level == 20 and food_saturation_level >= 6 then --fast regeneration + food_tick_timer = 0 + player:set_hp(player_health+1) + mcl_hunger.exhaust(player_name, mcl_hunger.EXHAUST_REGEN) + mcl_hunger.update_exhaustion_hud(player, mcl_hunger.get_exhaustion(player)) end + end end) From 2f053885414d0cc5d480e92d2acc63e7e7de8b1a Mon Sep 17 00:00:00 2001 From: Dieter44 <55900078+Dieter44@users.noreply.github.com> Date: Mon, 8 Nov 2021 15:49:05 +0100 Subject: [PATCH 246/296] Add one food_tick_timer per player instead of using one for all players. --- mods/PLAYER/mcl_hunger/init.lua | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/mods/PLAYER/mcl_hunger/init.lua b/mods/PLAYER/mcl_hunger/init.lua index 0405c28ef..1e3d07a47 100644 --- a/mods/PLAYER/mcl_hunger/init.lua +++ b/mods/PLAYER/mcl_hunger/init.lua @@ -137,11 +137,16 @@ end) -local food_tick_timer = 0 +local food_tick_timers = {} --one food_tick_timer per player, keys are the player-objects minetest.register_globalstep(function(dtime) - food_tick_timer = food_tick_timer + dtime - for _,player in ipairs(minetest.get_connected_players()) do + + local food_tick_timer = food_tick_timers[player] + if food_tick_timer == nil then + food_tick_timer = 0 + else + food_tick_timer = food_tick_timer + dtime + end local player_name = player:get_player_name() local food_level = mcl_hunger.get_hunger(player) @@ -172,6 +177,7 @@ minetest.register_globalstep(function(dtime) mcl_hunger.update_exhaustion_hud(player, mcl_hunger.get_exhaustion(player)) end + food_tick_timers[player] = food_tick_timer --update food_tick_timer table end end) From e82d21040c952e78fa8c64c8a32405d311a8a43c Mon Sep 17 00:00:00 2001 From: Dieter44 <55900078+Dieter44@users.noreply.github.com> Date: Mon, 8 Nov 2021 19:15:56 +0100 Subject: [PATCH 247/296] minor changes, ipairs() replaced with pairs() --- mods/PLAYER/mcl_hunger/init.lua | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/mods/PLAYER/mcl_hunger/init.lua b/mods/PLAYER/mcl_hunger/init.lua index 1e3d07a47..3a7af7e67 100644 --- a/mods/PLAYER/mcl_hunger/init.lua +++ b/mods/PLAYER/mcl_hunger/init.lua @@ -139,15 +139,9 @@ end) local food_tick_timers = {} --one food_tick_timer per player, keys are the player-objects minetest.register_globalstep(function(dtime) - for _,player in ipairs(minetest.get_connected_players()) do + for _,player in pairs(minetest.get_connected_players()) do - local food_tick_timer = food_tick_timers[player] - if food_tick_timer == nil then - food_tick_timer = 0 - else - food_tick_timer = food_tick_timer + dtime - end - + local food_tick_timer = food_tick_timers[player] and food_tick_timers[player] + dtime or 0 local player_name = player:get_player_name() local food_level = mcl_hunger.get_hunger(player) local food_saturation_level = mcl_hunger.get_saturation(player) @@ -157,15 +151,14 @@ minetest.register_globalstep(function(dtime) food_tick_timer = 0 if food_level >= 18 and player_health < 20 then --slow regenration - food_tick_timer = 0 player:set_hp(player_health+1) mcl_hunger.exhaust(player_name, mcl_hunger.EXHAUST_REGEN) mcl_hunger.update_exhaustion_hud(player, mcl_hunger.get_exhaustion(player)) elseif food_level == 0 then --starvation - maximumStarvation = 1 --the amount of health at which a player will stop to get harmed by starvation (10 for Easy, 1 for Normal, 0 for Hard) + local maximum_starvation = 1 --the amount of health at which a player will stop to get harmed by starvation (10 for Easy, 1 for Normal, 0 for Hard) -- TODO: implement Minecraft-like difficulty modes and the update maximumStarvation here - if player_health > maximumStarvation then + if player_health > maximum_starvation then mcl_util.deal_damage(player, 1, {type = "starve"}) end end From a7bc460fae77f2a841bb7a5b9e735226373a4e44 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 9 Nov 2021 17:39:39 +0100 Subject: [PATCH 248/296] Fix boat and enchanting book texture glitches / warnings --- mods/ENTITIES/mcl_boats/init.lua | 10 ++++++++-- mods/ITEMS/mcl_enchanting/init.lua | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/mods/ENTITIES/mcl_boats/init.lua b/mods/ENTITIES/mcl_boats/init.lua index 311b07882..f46c14d46 100644 --- a/mods/ENTITIES/mcl_boats/init.lua +++ b/mods/ENTITIES/mcl_boats/init.lua @@ -115,7 +115,7 @@ local boat = { collisionbox = {-0.5, -0.35, -0.5, 0.5, 0.3, 0.5}, visual = "mesh", mesh = "mcl_boats_boat.b3d", - textures = {"mcl_boats_texture_oak_boat.png"}, + textures = {"mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png"}, visual_size = boat_visual_size, hp_max = boat_max_hp, damage_texture_modifier = "^[colorize:white:0", @@ -148,6 +148,11 @@ function boat.on_activate(self, staticdata, dtime_s) self._v = data.v self._last_v = self._v self._itemstring = data.itemstring + + while #data.textures < 5 do + table.insert(data.textures, data.textures[1]) + end + self.object:set_properties({textures = data.textures}) end end @@ -434,8 +439,9 @@ for b=1, #boat_ids do pos = vector.add(pos, vector.multiply(dir, boat_y_offset_ground)) end local boat = minetest.add_entity(pos, "mcl_boats:boat") + local texture = "mcl_boats_texture_"..images[b].."_boat.png" boat:get_luaentity()._itemstring = itemstring - boat:set_properties({textures = { "mcl_boats_texture_"..images[b].."_boat.png" }}) + boat:set_properties({textures = { texture, texture, texture, texture, texture }}) boat:set_yaw(placer:get_look_horizontal()) if not minetest.is_creative_enabled(placer:get_player_name()) then itemstack:take_item() diff --git a/mods/ITEMS/mcl_enchanting/init.lua b/mods/ITEMS/mcl_enchanting/init.lua index 5aec1ced6..9f9fbd271 100644 --- a/mods/ITEMS/mcl_enchanting/init.lua +++ b/mods/ITEMS/mcl_enchanting/init.lua @@ -183,7 +183,7 @@ minetest.register_entity("mcl_enchanting:book", { collisionbox = {0, 0, 0}, pointable = false, physical = false, - textures = {"mcl_enchanting_book_entity.png"}, + textures = {"mcl_enchanting_book_entity.png", "mcl_enchanting_book_entity.png", "mcl_enchanting_book_entity.png", "mcl_enchanting_book_entity.png", "mcl_enchanting_book_entity.png"}, static_save = false, }, _player_near = false, From 017bf705e9f5b549a45d448b89a0d1d347db370c Mon Sep 17 00:00:00 2001 From: Dieter44 <55900078+Dieter44@users.noreply.github.com> Date: Tue, 9 Nov 2021 19:35:32 +0100 Subject: [PATCH 249/296] Fixing that player can regenerate health in death screen and then respawn without HP being set to maximum --- mods/PLAYER/mcl_hunger/init.lua | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/mods/PLAYER/mcl_hunger/init.lua b/mods/PLAYER/mcl_hunger/init.lua index 3a7af7e67..e54fb2fb2 100644 --- a/mods/PLAYER/mcl_hunger/init.lua +++ b/mods/PLAYER/mcl_hunger/init.lua @@ -150,10 +150,12 @@ minetest.register_globalstep(function(dtime) if food_tick_timer > 4.0 then food_tick_timer = 0 - if food_level >= 18 and player_health < 20 then --slow regenration - player:set_hp(player_health+1) - mcl_hunger.exhaust(player_name, mcl_hunger.EXHAUST_REGEN) - mcl_hunger.update_exhaustion_hud(player, mcl_hunger.get_exhaustion(player)) + if food_level >= 18 then --slow regenration + if player_health > 0 and player_health < 20 then + player:set_hp(player_health+1) + mcl_hunger.exhaust(player_name, mcl_hunger.EXHAUST_REGEN) + mcl_hunger.update_exhaustion_hud(player, mcl_hunger.get_exhaustion(player)) + end elseif food_level == 0 then --starvation local maximum_starvation = 1 --the amount of health at which a player will stop to get harmed by starvation (10 for Easy, 1 for Normal, 0 for Hard) @@ -164,10 +166,12 @@ minetest.register_globalstep(function(dtime) end elseif food_tick_timer > 0.5 and food_level == 20 and food_saturation_level >= 6 then --fast regeneration - food_tick_timer = 0 - player:set_hp(player_health+1) - mcl_hunger.exhaust(player_name, mcl_hunger.EXHAUST_REGEN) - mcl_hunger.update_exhaustion_hud(player, mcl_hunger.get_exhaustion(player)) + if player_health > 0 and player_health < 20 then + food_tick_timer = 0 + player:set_hp(player_health+1) + mcl_hunger.exhaust(player_name, mcl_hunger.EXHAUST_REGEN) + mcl_hunger.update_exhaustion_hud(player, mcl_hunger.get_exhaustion(player)) + end end food_tick_timers[player] = food_tick_timer --update food_tick_timer table From fa22ec4dd0b9c70eebb108bfef004e9100655bd2 Mon Sep 17 00:00:00 2001 From: iliekprogrammar Date: Wed, 10 Nov 2021 02:50:49 +0800 Subject: [PATCH 250/296] Add helper functions to update/merge tables. --- mods/CORE/mcl_util/init.lua | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/mods/CORE/mcl_util/init.lua b/mods/CORE/mcl_util/init.lua index 363b9b5fe..d91c86f09 100644 --- a/mods/CORE/mcl_util/init.lua +++ b/mods/CORE/mcl_util/init.lua @@ -1,5 +1,27 @@ mcl_util = {} +-- Updates all values in t using values from to*. +function table.update(t, ...) + for _, to in ipairs{...} do + for k,v in pairs(to) do + t[k] = v + end + end + return t +end + +-- Updates nil values in t using values from to*. +function table.update_nil(t, ...) + for _, to in ipairs{...} do + for k,v in pairs(to) do + if t[k] == nil then + t[k] = v + end + end + end + return t +end + -- Based on minetest.rotate_and_place --[[ From f61143758edc46cb1e4d7feef5a78d35c7c31d75 Mon Sep 17 00:00:00 2001 From: iliekprogrammar Date: Wed, 10 Nov 2021 12:54:28 +0800 Subject: [PATCH 251/296] Fix small typo in API.md --- mods/CORE/mcl_worlds/API.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/CORE/mcl_worlds/API.md b/mods/CORE/mcl_worlds/API.md index dd96b01b5..69508e924 100644 --- a/mods/CORE/mcl_worlds/API.md +++ b/mods/CORE/mcl_worlds/API.md @@ -12,7 +12,7 @@ Params: * pos: position -## mcl_worlds.y_to_layer(y) +## mcl_worlds.y_to_layer(y) This function is used to calculate the minetest y layer and dimension of the given minecraft layer. Mainly used for ore generation. Takes an Y coordinate as input and returns: @@ -78,4 +78,4 @@ Table containing all function registered with mcl_worlds.register_on_dimension_c Notify this mod of a dimension change of to * player: player, player who changed the dimension -* dimension: string, new dimension ("overworld", "nether", "end", "void") \ No newline at end of file +* dimension: string, new dimension ("overworld", "nether", "end", "void") From 8979230c4262411d8e2ae47ba8433e84e63585d1 Mon Sep 17 00:00:00 2001 From: NO11 Date: Wed, 10 Nov 2021 17:15:27 +0000 Subject: [PATCH 252/296] Several fixes for applying bone meal to grass --- mods/ITEMS/mcl_dye/init.lua | 53 +++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/mods/ITEMS/mcl_dye/init.lua b/mods/ITEMS/mcl_dye/init.lua index 2f6b0f105..2b4d8a2f2 100644 --- a/mods/ITEMS/mcl_dye/init.lua +++ b/mods/ITEMS/mcl_dye/init.lua @@ -288,38 +288,39 @@ local function apply_bone_meal(pointed_thing) return true elseif minetest.get_item_group(n.name, "grass_block") == 1 then -- Grass Block: Generate tall grass and random flowers all over the place - for i = -2, 2 do - for j = -2, 2 do - pos = pointed_thing.above - pos = {x=pos.x+i, y=pos.y, z=pos.z+j} - n = minetest.get_node(pos) - local n2 = minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}) + for i = -7, 7 do + for j = -7, 7 do + for y = -1, 1 do + pos = vector.offset(pointed_thing.above, i, y, j) + n = minetest.get_node(pos) + local n2 = minetest.get_node(vector.offset(pos, 0, -1, 0)) - if n.name ~= "" and n.name == "air" and (minetest.get_item_group(n2.name, "grass_block_no_snow") == 1) then - -- Randomly generate flowers, tall grass or nothing - if math.random(1,100) <= 90 then - -- 90% tall grass, 10% flower - mcl_dye.add_bone_meal_particle(pos, {amount = 4}) - if math.random(1,100) <= 90 then - local col = n2.param2 - minetest.add_node(pos, {name="mcl_flowers:tallgrass", param2=col}) - else - local flowers_table - if mg_name == "v6" then - flowers_table = flowers_table_plains + if n.name ~= "" and n.name == "air" and (minetest.get_item_group(n2.name, "grass_block_no_snow") == 1) then + -- Randomly generate flowers, tall grass or nothing + if math.random(1, 100) <= 90 / ((math.abs(i) + math.abs(j)) / 2)then + -- 90% tall grass, 10% flower + mcl_dye.add_bone_meal_particle(pos, {amount = 4}) + if math.random(1,100) <= 90 then + local col = n2.param2 + minetest.add_node(pos, {name="mcl_flowers:tallgrass", param2=col}) else - local biome = minetest.get_biome_name(minetest.get_biome_data(pos).biome) - if biome == "Swampland" or biome == "Swampland_shore" or biome == "Swampland_ocean" or biome == "Swampland_deep_ocean" or biome == "Swampland_underground" then - flowers_table = flowers_table_swampland - elseif biome == "FlowerForest" or biome == "FlowerForest_beach" or biome == "FlowerForest_ocean" or biome == "FlowerForest_deep_ocean" or biome == "FlowerForest_underground" then - flowers_table = flowers_table_flower_forest - elseif biome == "Plains" or biome == "Plains_beach" or biome == "Plains_ocean" or biome == "Plains_deep_ocean" or biome == "Plains_underground" or biome == "SunflowerPlains" or biome == "SunflowerPlains_ocean" or biome == "SunflowerPlains_deep_ocean" or biome == "SunflowerPlains_underground" then + local flowers_table + if mg_name == "v6" then flowers_table = flowers_table_plains else - flowers_table = flowers_table_simple + local biome = minetest.get_biome_name(minetest.get_biome_data(pos).biome) + if biome == "Swampland" or biome == "Swampland_shore" or biome == "Swampland_ocean" or biome == "Swampland_deep_ocean" or biome == "Swampland_underground" then + flowers_table = flowers_table_swampland + elseif biome == "FlowerForest" or biome == "FlowerForest_beach" or biome == "FlowerForest_ocean" or biome == "FlowerForest_deep_ocean" or biome == "FlowerForest_underground" then + flowers_table = flowers_table_flower_forest + elseif biome == "Plains" or biome == "Plains_beach" or biome == "Plains_ocean" or biome == "Plains_deep_ocean" or biome == "Plains_underground" or biome == "SunflowerPlains" or biome == "SunflowerPlains_ocean" or biome == "SunflowerPlains_deep_ocean" or biome == "SunflowerPlains_underground" then + flowers_table = flowers_table_plains + else + flowers_table = flowers_table_simple + end end + minetest.add_node(pos, {name=flowers_table[math.random(1, #flowers_table)]}) end - minetest.add_node(pos, {name=flowers_table[math.random(1, #flowers_table)]}) end end end From 0b6467d6798c8620db1dee91152feda66087fdfe Mon Sep 17 00:00:00 2001 From: Dieter44 <55900078+Dieter44@users.noreply.github.com> Date: Thu, 11 Nov 2021 16:03:04 +0100 Subject: [PATCH 253/296] Reduce creeper run_velocity to 2.1, to fix #1691 --- mods/ENTITIES/mobs_mc/creeper.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ENTITIES/mobs_mc/creeper.lua b/mods/ENTITIES/mobs_mc/creeper.lua index 999cc5f2d..616e823c8 100644 --- a/mods/ENTITIES/mobs_mc/creeper.lua +++ b/mods/ENTITIES/mobs_mc/creeper.lua @@ -37,7 +37,7 @@ mobs:register_mob("mobs_mc:creeper", { }, makes_footstep_sound = false, walk_velocity = 1.05, - run_velocity = 3.25, + run_velocity = 2.1, runaway_from = { "mobs_mc:ocelot", "mobs_mc:cat" }, attack_type = "explode", eye_height = 1.25, From 68810a2a74ff3dca000234b26c749fb5486d5996 Mon Sep 17 00:00:00 2001 From: Dieter44 <55900078+Dieter44@users.noreply.github.com> Date: Thu, 11 Nov 2021 16:47:32 +0100 Subject: [PATCH 254/296] Change creeper fuse range and defuse range according to minecraft wiki: https://minecraft.fandom.com/wiki/Creeper and: https://minecraft.fandom.com/wiki/Explosion. Fix of #1689 --- mods/ENTITIES/mobs_mc/creeper.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/creeper.lua b/mods/ENTITIES/mobs_mc/creeper.lua index 616e823c8..eb1f108c6 100644 --- a/mods/ENTITIES/mobs_mc/creeper.lua +++ b/mods/ENTITIES/mobs_mc/creeper.lua @@ -47,8 +47,8 @@ mobs:register_mob("mobs_mc:creeper", { --explosion_radius = 3, --explosion_damage_radius = 6, --explosiontimer_reset_radius = 6, - reach = 1.5, - defuse_reach = 4, + reach = 3, + defuse_reach = 5.2, explosion_timer = 0.3, allow_fuse_reset = true, stop_to_explode = true, @@ -186,8 +186,8 @@ mobs:register_mob("mobs_mc:creeper_charged", { --explosion_radius = 3, --explosion_damage_radius = 6, --explosiontimer_reset_radius = 3, - reach = 1.5, - defuse_reach = 4, + reach = 3, + defuse_reach = 10.4, explosion_timer = 0.3, allow_fuse_reset = true, stop_to_explode = true, From 10a5f8c4bfdbfec27fe83ab3c40478e7217c3680 Mon Sep 17 00:00:00 2001 From: Dieter44 <55900078+Dieter44@users.noreply.github.com> Date: Thu, 11 Nov 2021 16:50:29 +0100 Subject: [PATCH 255/296] Adding attribute hostile=true to charged creeper to fix that the charged creeper has no behavior: Issue #1756 --- mods/ENTITIES/mobs_mc/creeper.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/mods/ENTITIES/mobs_mc/creeper.lua b/mods/ENTITIES/mobs_mc/creeper.lua index eb1f108c6..2b66d0f07 100644 --- a/mods/ENTITIES/mobs_mc/creeper.lua +++ b/mods/ENTITIES/mobs_mc/creeper.lua @@ -151,6 +151,7 @@ mobs:register_mob("mobs_mc:creeper_charged", { description = S("Charged Creeper"), type = "monster", spawn_class = "hostile", + hostile = true, hp_min = 20, hp_max = 20, xp_min = 5, From 03d22852ee8a5b203840266f39d302a8854e3cfb Mon Sep 17 00:00:00 2001 From: Dieter44 <55900078+Dieter44@users.noreply.github.com> Date: Thu, 11 Nov 2021 16:56:44 +0100 Subject: [PATCH 256/296] Replace mobs:boom with equivalent mcl_explosions.exlode() to fix game crash when creeper is right-clicked with flint and steel. Issue #1753 --- mods/ENTITIES/mobs_mc/creeper.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/creeper.lua b/mods/ENTITIES/mobs_mc/creeper.lua index 2b66d0f07..1e23231c1 100644 --- a/mods/ENTITIES/mobs_mc/creeper.lua +++ b/mods/ENTITIES/mobs_mc/creeper.lua @@ -95,7 +95,8 @@ mobs:register_mob("mobs_mc:creeper", { if self._forced_explosion_countdown_timer then self._forced_explosion_countdown_timer = self._forced_explosion_countdown_timer - dtime if self._forced_explosion_countdown_timer <= 0 then - mobs:boom(self, mcl_util.get_object_center(self.object), self.explosion_strength) + local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false + mcl_explosions.explode(mcl_util.get_object_center(self.object), self.explosion_strength, { griefing = mobs_griefing, drop_chance = 1.0}, self.object) end end end, @@ -220,7 +221,8 @@ mobs:register_mob("mobs_mc:creeper_charged", { if self._forced_explosion_countdown_timer then self._forced_explosion_countdown_timer = self._forced_explosion_countdown_timer - dtime if self._forced_explosion_countdown_timer <= 0 then - mobs:boom(self, mcl_util.get_object_center(self.object), self.explosion_strength) + local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false + mcl_explosions.explode(mcl_util.get_object_center(self.object), self.explosion_strength, { griefing = mobs_griefing, drop_chance = 1.0}, self.object) end end end, From 0564121183177331901cb5a99e501500f086e535 Mon Sep 17 00:00:00 2001 From: iliekprogrammar Date: Fri, 12 Nov 2021 02:28:27 +0800 Subject: [PATCH 257/296] Code style for #1890 --- mods/PLAYER/mcl_hunger/init.lua | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/mods/PLAYER/mcl_hunger/init.lua b/mods/PLAYER/mcl_hunger/init.lua index e54fb2fb2..21c1e0860 100644 --- a/mods/PLAYER/mcl_hunger/init.lua +++ b/mods/PLAYER/mcl_hunger/init.lua @@ -134,38 +134,37 @@ minetest.register_on_player_hpchange(function(player, hp_change) end end) - - - -local food_tick_timers = {} --one food_tick_timer per player, keys are the player-objects +local food_tick_timers = {} -- one food_tick_timer per player, keys are the player-objects minetest.register_globalstep(function(dtime) for _,player in pairs(minetest.get_connected_players()) do - + local food_tick_timer = food_tick_timers[player] and food_tick_timers[player] + dtime or 0 local player_name = player:get_player_name() local food_level = mcl_hunger.get_hunger(player) local food_saturation_level = mcl_hunger.get_saturation(player) local player_health = player:get_hp() - + if food_tick_timer > 4.0 then food_tick_timer = 0 - - if food_level >= 18 then --slow regenration + + if food_level >= 18 then -- slow regenration if player_health > 0 and player_health < 20 then player:set_hp(player_health+1) mcl_hunger.exhaust(player_name, mcl_hunger.EXHAUST_REGEN) mcl_hunger.update_exhaustion_hud(player, mcl_hunger.get_exhaustion(player)) end - - elseif food_level == 0 then --starvation - local maximum_starvation = 1 --the amount of health at which a player will stop to get harmed by starvation (10 for Easy, 1 for Normal, 0 for Hard) + + elseif food_level == 0 then -- starvation + -- the amount of health at which a player will stop to get + -- harmed by starvation (10 for Easy, 1 for Normal, 0 for Hard) + local maximum_starvation = 1 -- TODO: implement Minecraft-like difficulty modes and the update maximumStarvation here if player_health > maximum_starvation then mcl_util.deal_damage(player, 1, {type = "starve"}) end end - - elseif food_tick_timer > 0.5 and food_level == 20 and food_saturation_level >= 6 then --fast regeneration + + elseif food_tick_timer > 0.5 and food_level == 20 and food_saturation_level >= 6 then -- fast regeneration if player_health > 0 and player_health < 20 then food_tick_timer = 0 player:set_hp(player_health+1) @@ -173,8 +172,8 @@ minetest.register_globalstep(function(dtime) mcl_hunger.update_exhaustion_hud(player, mcl_hunger.get_exhaustion(player)) end end - - food_tick_timers[player] = food_tick_timer --update food_tick_timer table + + food_tick_timers[player] = food_tick_timer -- update food_tick_timer table end end) From 740f7583ef991e59b8f62ce3344744515aa2f10d Mon Sep 17 00:00:00 2001 From: iliekprogrammar Date: Fri, 12 Nov 2021 02:49:18 +0800 Subject: [PATCH 258/296] Add Dieter44 to CREDITS.md --- CREDITS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CREDITS.md b/CREDITS.md index dfbe58375..1381b1c37 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -67,6 +67,7 @@ * SmallJoker * Sven792 * aldum +* Dieter44 ## MineClone5 * kay27 From 2a08f3143561d52e01fad66a5b4dadd1b765b0a2 Mon Sep 17 00:00:00 2001 From: NO11 Date: Fri, 12 Nov 2021 14:09:59 +0000 Subject: [PATCH 259/296] Use particlespawners for better performance (sponge particles) --- mods/ITEMS/mcl_sponges/init.lua | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/mods/ITEMS/mcl_sponges/init.lua b/mods/ITEMS/mcl_sponges/init.lua index a1998ecb0..e9755479b 100644 --- a/mods/ITEMS/mcl_sponges/init.lua +++ b/mods/ITEMS/mcl_sponges/init.lua @@ -115,16 +115,22 @@ function place_wet_sponge(itemstack, placer, pointed_thing) if mcl_worlds.pos_to_dimension(pointed_thing.above) == "nether" then minetest.item_place_node(ItemStack("mcl_sponges:sponge"), placer, pointed_thing) local pos = pointed_thing.above - for n = 0, 25 do - minetest.add_particle({ - pos = {x = pos.x + math.random(-1, 1)*math.random()/2, y = pos.y + 0.6, z = pos.z + math.random(-1, 1)*math.random()/2}, - velocity = {x = 0, y = math.random(), z = 0}, - acceleration = {x=0, y=0, z=0}, - expirationtime = math.random(), + + for n = 1, 5 do + minetest.add_particlespawner({ + amount = 5, + time = 0.1, + minpos = vector.offset(pos, -0.5, 0.6, -0.5), + maxpos = vector.offset(pos, 0.5, 0.6, 0.5), + minvel = vector.new(0, 0.1, 0), + maxvel = vector.new(0, 1, 0), + minexptime = 0.1, + maxexptime = 1, + minsize = 2, + maxsize = 5, collisiondetection = false, vertical = false, - size = math.random(2, 5), - texture = "mcl_particles_sponge"..math.random(1, 5)..".png", + texture = "mcl_particles_sponge" .. n .. ".png", }) end if not minetest.is_creative_enabled(name) then From 490e40d042325302dd5a7e58880cba82be514937 Mon Sep 17 00:00:00 2001 From: NO11 Date: Fri, 12 Nov 2021 15:41:09 +0000 Subject: [PATCH 260/296] Bone meal particles: add some velocity, correct glow --- mods/ITEMS/mcl_dye/init.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mods/ITEMS/mcl_dye/init.lua b/mods/ITEMS/mcl_dye/init.lua index 2b4d8a2f2..dfb962446 100644 --- a/mods/ITEMS/mcl_dye/init.lua +++ b/mods/ITEMS/mcl_dye/init.lua @@ -137,8 +137,8 @@ function mcl_dye.add_bone_meal_particle(pos, def) time = def.time or 0.1, minpos = def.minpos or vector.subtract(pos, 0.5), maxpos = def.maxpos or vector.add(pos, 0.5), - minvel = def.minvel or vector.new(0, 0, 0), - maxvel = def.maxvel or vector.new(0, 0, 0), + minvel = def.minvel or vector.new(-0.01, 0.01, -0.01), + maxvel = def.maxvel or vector.new(0.01, 0.01, 0.01), minacc = def.minacc or vector.new(0, 0, 0), maxacc = def.maxacc or vector.new(0, 0, 0), minexptime = def.minexptime or 1, @@ -146,7 +146,7 @@ function mcl_dye.add_bone_meal_particle(pos, def) minsize = def.minsize or 0.7, maxsize = def.maxsize or 2.4, texture = "mcl_particles_bonemeal.png^[colorize:#00EE00:125", -- TODO: real MC color - glow = def.glow or 5, + glow = def.glow or 1, }) end From 0cc0a7e01de8fc00dd63eab1b960701940719a66 Mon Sep 17 00:00:00 2001 From: NO11 Date: Fri, 12 Nov 2021 17:49:27 +0000 Subject: [PATCH 261/296] Make dripping particles MC-like --- mods/ENTITIES/drippingwater/init.lua | 167 ++++++++++----------------- 1 file changed, 59 insertions(+), 108 deletions(-) diff --git a/mods/ENTITIES/drippingwater/init.lua b/mods/ENTITIES/drippingwater/init.lua index e17bdda40..a4855acdc 100644 --- a/mods/ENTITIES/drippingwater/init.lua +++ b/mods/ENTITIES/drippingwater/init.lua @@ -1,114 +1,65 @@ ---Dripping Water Mod ---by kddekadenz +-- Dripping Water Mod +-- by kddekadenz local math = math -- License of code, textures & sounds: CC0 ---Drop entities +local function register_drop(liquid, glow, sound, nodes) + minetest.register_entity("drippingwater:drop_" .. liquid, { + hp_max = 1, + physical = true, + collide_with_objects = false, + collisionbox = {-0.01, 0.01, -0.01, 0.01, 0.01, 0.01}, + glow = glow, + pointable = false, + visual = "sprite", + visual_size = {x = 0.1, y = 0.1}, + textures = {""}, + spritediv = {x = 1, y = 1}, + initial_sprite_basepos = {x = 0, y = 0}, + static_save = false, + _dropped = false, + on_activate = function(self) + self.object:set_properties({ + textures = {"[combine:2x2:" .. -math.random(1, 16) .. "," .. -math.random(1, 16) .. "=default_" .. liquid .. "_source_animated.png"} + }) + end, + on_step = function(self, dtime) + local k = math.random(1, 222) + local ownpos = self.object:get_pos() + if k == 1 then + self.object:set_acceleration(vector.new(0, -5, 0)) + end + if minetest.get_node(vector.offset(ownpos, 0, 0.5, 0)).name == "air" then + self.object:set_acceleration(vector.new(0, -5, 0)) + end + if minetest.get_node(vector.offset(ownpos, 0, -0.1, 0)).name ~= "air" then + if not self.object:get_luaentity()._dropped then + self.object:get_luaentity()._dropped = true + minetest.sound_play({name = "drippingwater_" .. sound .. "drip"}, {pos = ownpos, gain = 0.5, max_hear_distance = 8}, true) + end + if k < 3 then + self.object:remove() + end + end + end, + }) + minetest.register_abm({ + label = "Create drops", + nodenames = nodes, + neighbors = {"group:" .. liquid}, + interval = 2, + chance = 22, + action = function(pos) + if minetest.get_item_group(minetest.get_node(vector.offset(pos, 0, 1, 0)).name, liquid) ~= 0 + and minetest.get_node(vector.offset(pos, 0, -1, 0)).name == "air" then + local x, z = math.random(-45, 45) / 100, math.random(-45, 45) / 100 + minetest.add_entity(vector.offset(pos, x, -0.520, z), "drippingwater:drop_" .. liquid) + end + end, + }) +end ---water - -local water_tex = "default_water_source_animated.png^[verticalframe:16:0" -minetest.register_entity("drippingwater:drop_water", { - hp_max = 1, - physical = true, - collide_with_objects = false, - collisionbox = {-0.025,-0.05,-0.025,0.025,-0.01,0.025}, - pointable = false, - visual = "cube", - visual_size = {x=0.05, y=0.1}, - textures = {water_tex, water_tex, water_tex, water_tex, water_tex, water_tex}, - spritediv = {x=1, y=1}, - initial_sprite_basepos = {x=0, y=0}, - static_save = false, - on_activate = function(self, staticdata) - self.object:set_sprite({x=0,y=0}, 1, 1, true) - end, - on_step = function(self, dtime) - local k = math.random(1,222) - local ownpos = self.object:get_pos() - if k==1 then - self.object:set_acceleration({x=0, y=-5, z=0}) - end - if minetest.get_node({x=ownpos.x, y=ownpos.y +0.5, z=ownpos.z}).name == "air" then - self.object:set_acceleration({x=0, y=-5, z=0}) - end - if minetest.get_node({x=ownpos.x, y=ownpos.y -0.5, z=ownpos.z}).name ~= "air" then - self.object:remove() - minetest.sound_play({name="drippingwater_drip"}, {pos = ownpos, gain = 0.5, max_hear_distance = 8}, true) - end - end, -}) - - ---lava - -local lava_tex = "default_lava_source_animated.png^[verticalframe:16:0" -minetest.register_entity("drippingwater:drop_lava", { - hp_max = 1, - physical = true, - collide_with_objects = false, - collisionbox = {-0.025,-0.05,-0.025,0.025,-0.01,0.025}, - glow = math.max(7, minetest.registered_nodes["mcl_core:lava_source"].light_source - 3), - pointable = false, - visual = "cube", - visual_size = {x=0.05, y=0.1}, - textures = {lava_tex, lava_tex, lava_tex, lava_tex, lava_tex, lava_tex}, - spritediv = {x=1, y=1}, - initial_sprite_basepos = {x=0, y=0}, - static_save = false, - on_activate = function(self, staticdata) - self.object:set_sprite({x=0,y=0}, 1, 0, true) - end, - on_step = function(self, dtime) - local k = math.random(1,222) - local ownpos = self.object:get_pos() - if k == 1 then - self.object:set_acceleration({x=0, y=-5, z=0}) - end - if minetest.get_node({x=ownpos.x, y=ownpos.y +0.5, z=ownpos.z}).name == "air" then - self.object:set_acceleration({x=0, y=-5, z=0}) - end - if minetest.get_node({x=ownpos.x, y=ownpos.y -0.5, z=ownpos.z}).name ~= "air" then - self.object:remove() - minetest.sound_play({name="drippingwater_lavadrip"}, {pos = ownpos, gain = 0.5, max_hear_distance = 8}, true) - end - end, -}) - - - ---Create drop - -minetest.register_abm({ - label = "Create water drops", - nodenames = {"group:opaque", "group:leaves"}, - neighbors = {"group:water"}, - interval = 2, - chance = 22, - action = function(pos) - if minetest.get_item_group(minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z}).name, "water") ~= 0 - and minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}).name == "air" then - local i = math.random(-45,45) / 100 - minetest.add_entity({x=pos.x + i, y=pos.y - 0.501, z=pos.z + i}, "drippingwater:drop_water") - end - end, -}) - ---Create lava drop - -minetest.register_abm({ - label = "Create lava drops", - nodenames = {"group:opaque"}, - neighbors = {"group:lava"}, - interval = 2, - chance = 22, - action = function(pos) - if minetest.get_item_group(minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z}).name, "lava") ~= 0 - and minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}).name == "air" then - local i = math.random(-45,45) / 100 - minetest.add_entity({x=pos.x + i, y=pos.y - 0.501, z=pos.z + i}, "drippingwater:drop_lava") - end - end, -}) \ No newline at end of file +register_drop("water", 1, "", {"group:opaque", "group:leaves"}) +register_drop("lava", math.max(7, minetest.registered_nodes["mcl_core:lava_source"].light_source - 3), "lava", {"group:opaque"}) \ No newline at end of file From 7ed964756e1798ba7e2feb6b3459e1fb66dae914 Mon Sep 17 00:00:00 2001 From: NO11 Date: Fri, 12 Nov 2021 18:00:04 +0000 Subject: [PATCH 262/296] local luaentity --- mods/ENTITIES/drippingwater/init.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mods/ENTITIES/drippingwater/init.lua b/mods/ENTITIES/drippingwater/init.lua index a4855acdc..45a211d8f 100644 --- a/mods/ENTITIES/drippingwater/init.lua +++ b/mods/ENTITIES/drippingwater/init.lua @@ -35,8 +35,9 @@ local function register_drop(liquid, glow, sound, nodes) self.object:set_acceleration(vector.new(0, -5, 0)) end if minetest.get_node(vector.offset(ownpos, 0, -0.1, 0)).name ~= "air" then - if not self.object:get_luaentity()._dropped then - self.object:get_luaentity()._dropped = true + local ent = self.object:get_luaentity() + if not ent._dropped then + ent._dropped = true minetest.sound_play({name = "drippingwater_" .. sound .. "drip"}, {pos = ownpos, gain = 0.5, max_hear_distance = 8}, true) end if k < 3 then From 5515e2baa169ee3e5e2fe55043f8fe3272a5269a Mon Sep 17 00:00:00 2001 From: NO11 Date: Fri, 12 Nov 2021 21:49:47 +0000 Subject: [PATCH 263/296] Add 64 items to inventory when creative is on --- mods/HUD/mcl_inventory/creative.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mods/HUD/mcl_inventory/creative.lua b/mods/HUD/mcl_inventory/creative.lua index 2be0be4bc..43301ce0b 100644 --- a/mods/HUD/mcl_inventory/creative.lua +++ b/mods/HUD/mcl_inventory/creative.lua @@ -667,3 +667,9 @@ minetest.register_on_joinplayer(function(player) init(player) mcl_inventory.set_creative_formspec(player, 0, 1, nil, false, "nix", "") end) + +minetest.register_on_player_inventory_action(function(player, action, inventory, inventory_info) + if minetest.is_creative_enabled(player:get_player_name()) and action == "put" and inventory_info.listname == "main" then + player:get_inventory():set_stack("main", inventory_info.index, inventory_info.stack:get_name() .. " 64") + end +end) From 96c4fb60d8641b4181edb902ed24dbf173828d09 Mon Sep 17 00:00:00 2001 From: iliekprogrammar Date: Sat, 13 Nov 2021 10:46:16 +0800 Subject: [PATCH 264/296] Fix crash on startup during immediate runtime by mcl_burning The crash occurs if mcl_burning:data is deserialized to nil. The cause of mcl_burning being set to "return nil" is unknown. Therefore, when it occurs, it will be logged as warning. --- mods/ENTITIES/mcl_burning/init.lua | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/mods/ENTITIES/mcl_burning/init.lua b/mods/ENTITIES/mcl_burning/init.lua index 313e75dca..a47824537 100644 --- a/mods/ENTITIES/mcl_burning/init.lua +++ b/mods/ENTITIES/mcl_burning/init.lua @@ -44,18 +44,18 @@ minetest.register_on_respawnplayer(function(player) mcl_burning.extinguish(player) end) -minetest.register_on_joinplayer(function(player) - local storage - - local burn_data = player:get_meta():get_string("mcl_burning:data") - if burn_data == "" then - storage = {} - else - storage = minetest.deserialize(burn_data) +function mcl_burning.init_player(player) + local meta = player:get_meta() + -- NOTE: mcl_burning:data may be "return nil" (which deserialize into nil) for reasons unknown. + if meta:get_string("mcl_burning:data"):find("return nil", 1, true) then + minetest.log("warning", "[mcl_burning] 'mcl_burning:data' player meta field is invalid! Please report this bug") end - - mcl_burning.storage[player] = storage + mcl_burning.storage[player] = meta:contains("mcl_burning:data") and minetest.deserialize(meta:get_string("mcl_burning:data")) or {} mcl_burning.channels[player] = minetest.mod_channel_join("mcl_burning:" .. player:get_player_name()) +end + +minetest.register_on_joinplayer(function(player) + mcl_burning.init_player(player) end) minetest.register_on_leaveplayer(function(player) From bd1491854369913b8e1373dd5cadcd7280415535 Mon Sep 17 00:00:00 2001 From: iliekprogrammar Date: Sat, 13 Nov 2021 12:12:20 +0800 Subject: [PATCH 265/296] Reduce defuse reach for charged creeper 5.2 is actually half of the estimated MC creeper defuse range, which is 10.4. The reason for this change is to balance the creeper in MCL2 where it fuses whilst moving making it more difficult than MC. In MC, the creeper does not move while fusing. --- mods/ENTITIES/mobs_mc/creeper.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ENTITIES/mobs_mc/creeper.lua b/mods/ENTITIES/mobs_mc/creeper.lua index 1e23231c1..a7e33d1bd 100644 --- a/mods/ENTITIES/mobs_mc/creeper.lua +++ b/mods/ENTITIES/mobs_mc/creeper.lua @@ -189,7 +189,7 @@ mobs:register_mob("mobs_mc:creeper_charged", { --explosion_damage_radius = 6, --explosiontimer_reset_radius = 3, reach = 3, - defuse_reach = 10.4, + defuse_reach = 5.2, explosion_timer = 0.3, allow_fuse_reset = true, stop_to_explode = true, From ae8068cca671f5e215045fa4227e05b21fe5ebc5 Mon Sep 17 00:00:00 2001 From: NO11 Date: Sat, 13 Nov 2021 11:17:46 +0000 Subject: [PATCH 266/296] Use stack_max instead of 64 for all items --- mods/HUD/mcl_inventory/creative.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mods/HUD/mcl_inventory/creative.lua b/mods/HUD/mcl_inventory/creative.lua index 43301ce0b..4f9f1685a 100644 --- a/mods/HUD/mcl_inventory/creative.lua +++ b/mods/HUD/mcl_inventory/creative.lua @@ -670,6 +670,7 @@ end) minetest.register_on_player_inventory_action(function(player, action, inventory, inventory_info) if minetest.is_creative_enabled(player:get_player_name()) and action == "put" and inventory_info.listname == "main" then - player:get_inventory():set_stack("main", inventory_info.index, inventory_info.stack:get_name() .. " 64") + local stack = inventory_info.stack + player:get_inventory():set_stack("main", inventory_info.index, stack:get_name() .. " " .. stack:get_stack_max()) end -end) +end) \ No newline at end of file From d4da8555708f2db411cbd0352cc4d7e62b7ee99d Mon Sep 17 00:00:00 2001 From: NO11 Date: Sat, 13 Nov 2021 12:25:10 +0000 Subject: [PATCH 267/296] Add button to switch between max stack size and just one item --- mods/HUD/mcl_inventory/creative.lua | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/mods/HUD/mcl_inventory/creative.lua b/mods/HUD/mcl_inventory/creative.lua index 4f9f1685a..de03886d9 100644 --- a/mods/HUD/mcl_inventory/creative.lua +++ b/mods/HUD/mcl_inventory/creative.lua @@ -289,6 +289,17 @@ filtername["inv"] = S("Survival Inventory") bg["default"] = dark_bg end]] +local function get_stack_size(player) + return player:get_meta():get_int("switch_stack") +end + +local function set_stack_size(player, n) + player:get_meta():set_int("switch_stack", n) +end + +minetest.register_on_newplayer(function (player) + set_stack_size(player, 64) +end) function mcl_inventory.set_creative_formspec(player, start_i, pagenum, inv_size, show, page, filter) --reset_menu_item_bg() @@ -349,6 +360,11 @@ function mcl_inventory.set_creative_formspec(player, start_i, pagenum, inv_size, armor_slot_imgs = armor_slot_imgs .. "image[5.5,2.75;1,1;mcl_inventory_empty_armor_slot_boots.png]" end + local switch_overlay = "blank.png" + if get_stack_size(player) == 64 then + switch_overlay = "mcl_inventory_button_switch_stack.png" + end + -- Survival inventory slots main_list = "list[current_player;main;0,3.75;9,3;9]".. mcl_formspec.get_itemslot_bg(0,3.75,9,3).. @@ -376,7 +392,10 @@ function mcl_inventory.set_creative_formspec(player, start_i, pagenum, inv_size, -- achievements button "image_button[9,4;1,1;mcl_achievements_button.png;__mcl_achievements;]".. --"style_type[image_button;border=;bgimg=;bgimg_pressed=]".. - "tooltip[__mcl_achievements;"..F(S("Achievements")).."]" + "tooltip[__mcl_achievements;"..F(S("Achievements")).."]".. + -- switch stack size button + "image_button[9,5;1,1;default_apple.png^" .. switch_overlay .. ";__switch_stack;]".. + "tooltip[__switch_stack;"..F(S("Switch stack size")).."]" -- For shortcuts listrings = listrings .. @@ -544,6 +563,12 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) elseif fields.search and not fields.creative_next and not fields.creative_prev then set_inv_search(string.lower(fields.search),player) page = "nix" + elseif fields.__switch_stack then + local switch = 1 + if get_stack_size(player) == 1 then + switch = 64 + end + set_stack_size(player, switch) end if page then @@ -669,7 +694,7 @@ minetest.register_on_joinplayer(function(player) end) minetest.register_on_player_inventory_action(function(player, action, inventory, inventory_info) - if minetest.is_creative_enabled(player:get_player_name()) and action == "put" and inventory_info.listname == "main" then + if minetest.is_creative_enabled(player:get_player_name()) and action == "put" and inventory_info.listname == "main" and get_stack_size(player) == 64 then local stack = inventory_info.stack player:get_inventory():set_stack("main", inventory_info.index, stack:get_name() .. " " .. stack:get_stack_max()) end From d7e59f6a359c2bb371e63829b51f74ae685735ab Mon Sep 17 00:00:00 2001 From: NO11 Date: Sat, 13 Nov 2021 12:26:01 +0000 Subject: [PATCH 268/296] Add switch stack size overlay texture --- .../mcl_inventory_button_switch_stack.png | Bin 0 -> 8936 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 mods/HUD/mcl_inventory/textures/mcl_inventory_button_switch_stack.png diff --git a/mods/HUD/mcl_inventory/textures/mcl_inventory_button_switch_stack.png b/mods/HUD/mcl_inventory/textures/mcl_inventory_button_switch_stack.png new file mode 100644 index 0000000000000000000000000000000000000000..ac56d833d0c6c4efcb9633794ffc9d767247d962 GIT binary patch literal 8936 zcmVP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+O3*rmgF{;h5us}vjoBe%fW*=XLc~lpYMW^sghLc zE~#6o%7~-|pScF0+yD2!$NdlgmDqwyxwg_vdH65&)WhIQd*1*0{q3K0f8YP&`t0++ z-|oJ51U5w-`TkkQ=lH?){M!j%_we@n?XG?Hg!Z}6XUEqCqwXB|vVI&S+rzuvr_Y7@ ze!rC7>W@RU@P5wEfp;jMf3e<6e_up@yB{~CN|aXSs2IYIK0fz%dq)uU&&R>P_cw#m zZ@#m~-A(l~5(4tO$NTzxo*x7ByC8pkbAOEf_qRU;Ka9`z_=i}QPmK8T(;YtlJoq=n zKbFJyh{Er8So8HykMsF=&T8lE_vuC|M6`S=>TzGu(K#GwggoBU3O|*9neX-fbbi`1 zo=I}nGaut;`tAc+InF1){P4%``#Jq&h$-w)`3zx_C~a%8h8|{Ao|1n22{rb(Vk4I` zY)AT14Bun%_rCq!Z~Dfam*>#nxtQmazx;9kYUkhiapz2h$Up5nR*WmCav6p)r{5e! zLj3vUE#Clt{e05@{7^rXDjCc-%#8;ekG+?$?0>7Rc=H@NF7x?zg?Dv*E4LOvc&0rIW$g#vq zZh9OfE2T{R)YPbY-g@t21UISH?(T+CJptzjOCn=6)$} zF1KIGTljaGb4uNRBXf?_{W)(x$=VXn&6}~e3l-BR(tXQDXu}0tT&EcQr$5X zTRvrtnZ0B`h5B4pLGZ?-OPE{n0H%GJy6F}`>Cr3Ld0-(I~EdQv(s0xGV|GN zo1?8}XVLsUgCDsa*Q?QWKDR`!K!!ra`o2@=(Mg{mV^Gj12EXefAUx>UeYRG%w=hQC zDK1-#s4~PEeeK1LS=ue0hS-UmF!nvxxpYsnrwX**>}1!5r(E z;)vAu=^D!OjJ?n741d=?>RBg*5sYDk6TF>T`ZDfU$13sU);%q9a%z5)ms2vAsxb`X zLEz|`;$At$Y5H8Gi-H9=t;0`XMBD2yVwJ@eT0C5;Yx6XH6b82l*?CVcWv-{Kv!a2U zQeUI*HJ{V1oiyHVw1=xZKl9??nSC2&r!$uCahvKa$JRCA(?Nkn!FJ>d9T?ZW;8@Qd zGw$FQCE!|DIb?WrwObikdg*U|Qa$c1pW5eo3v1@|czV+3P@(mDYCUmZEjHC!WSew zDn(NLaI@(xKSoyO&WXXcK!Pf0IdZK_WqV>7U^>5xQym-K(9S&~t%nQGHTe!$hG`@t z+O$HpDE$5uPI#gNUi)V zd+y(*^`}|&Xh6i->AR@cDCg$%H+ufvlFO#xC;e5S4WmV?QJh!NC2^;|V61Xs`tLcovP+69=rGKR8i=r|wP#sTPkDir))%>l1{_6F!1V z%PwV)%5wk$n=S=F8dbLPSnw4RsPIVi^KumJZ2;14v2|20YHBN)vr2j3&NiLwBpp3xU)w z-7u!x)hEu*(0KL0!#wdu%D7h=y`TenZzb(Ax`tQ|)p>NIoJWN%svaUCwBX+r$~1Ue z^g<-5nnD8FH)sCJr_&emH=eV@IAG+V>1mtMo=}HaVu2o8P`)Ai-~9!aPBKEljpSe> z8Wb+}mx8h?8JyS>8G1y2ta@$tqBfp`HYMnVj3FHm1{1(4K<%WM$Th41Bd<28Tyz8{ z!e}($t_USjB&`8N1MM&3oxQ5+DK&%xtXJLc8bnyL@0-|MfO){pL#qH6vV+1}2H)Paq} zg@kATNd$yW>!g_>WI7ol!K?5%_TJq@SZ7iMaHxoCtb76~uR41bSND$5aBfG|JfR{N zW5C1(D15e3E&URixL<)Ek%|P-NwhX_DBd3zMJAy$_%=sJ_X)Dc)bk^2H|a(jqD?qq z5SCLXvQ|vF4j=%j24b|x-BET61W%X`f_)4GMqFHr7Wf)oc*ZSQ5WL&okK#yy!VqX0 zh`JVEN$)bap}5LhjVB1;*cLu*~fZJtz+GLdSI;B0O51uAqCebdjZY zjFNs-{ zETl#hY#JHvf>&sSi^r4br4e1ex{b z+cWp|fN1WTvxBY}sIO5PXu@!tkXG3C32EMW#Hn8LgIMJNz2j`KJC@LLcKrw{o5Z_c zvn)SxEPjcL)kGV!Fg}#%y>%46EK$L;|g>TIuO?xac5z(KUM_{RSF%D zc0jW_h%q5q1C{YrlS8F&3jz7al^8hQ5l;cwbzB=HL9#ArDE)$sk{zBw0Vr^6Z)g>h z1(zndan^yNswLx+RiO-Q!147xssjb&1v%*c>Li|GEnFKm62O^2ZVC8vBuW?_8AX{) z$p#4vNo{~FURMf15{SD^8$^v;9f3kYZZOiPAGOxi%MUOIVjynVAvzA(b;BxStSNJ0 z2;;|uFR3e*@k^{*YJsz>< zAwC193(gPbp$s|hy6xbv%OvBpK)x}8s!)qi50c6r^T>5Q;~vC_%N*KgXT-aX#dh3y z^0XKv+hF)IkjI5)k`x?(uh4~1sDXAL>4Al;J-+Qui*V_Uqc1+z;4i%5Cr|p;HtsJ) z&tGVrIAg7%w0M6fE(p_3MpQ}gRTT0JNPfC#1qSF~Q$b&iEDuF%Vp#9s5Rv7mm~H{Pwb5JC+LnpvbW@$rowf-=O<)s`NAEs( zqJ)bKJagpnuy@Gkq^hZ!MI8>a-w*1zL%k}Wy&?jFE=>(T64kJ=`5w{+7;CEu4oPDR zA+Z{8iQtf`bPx#N>x80~Ithfum_R|p2i&*anbn8`B~*D94~{W3KP9Pgk7#C2BRsA` zL52nB97!1wcassJctOJp6kxc?obn*V2X{dXb|1Ig10uWo@nTl+Qp(+}h4TJ<+4ia_13YKkARwNA7 zLqZ1NM4a7z2>t}XK#DpwfA-`safJjF)3gZ%fk>HBK_kRPmdQfF1)_e#o!dSMq2y*q zCAJ_n+istOaWPpVQUm+;P&#Fm5T%e2AV)F?mrMdOtq%glf(Hcr~D;C4w@zUP1CBtqM=>_|;0acE+35*XScG<2;Es6lYKC4%}GxuF$% zZ8+Xc0~8m*z-+`OmUxlx{-NoZC7J9|ocBbKkctB|kM+LnN*ej_p1uAscfX4*VI5@1 z*ZC(;dOZ8O=G^O@H(BM(L6mDQ-ViCNCV7cN@ty3j8`yoS35O9h9o($ZQIsi~aDOm0 z?SlXp!cLU}(tLD7fNOO^6Ryvi&R^A2%TS`GTqEC20;^o2Mw63uuH5L~1wLUa*uCka zkm{q!MQT#AhH_sGf0(vG9nz%~ZV*A2O)H0=#<}y*S6F*l$ry^oMi>IkDX7*tvHG1)G0Ug`~zebc*AW%M) zexVVCOz_)FigM{Q;aMeZM)V*b9Ehb$G1Mo~v@)u=I|G{mQmp;V43VlwN@keXG?|Jq zfi)=cjH-&5goAoU;Lw$X2{3k9I&~uz)&yfwOi$kLBqw3#__8Qlg++>lenb{`n&!+- zVkk%quV!hALx}P;MSk+~&5}h!h$H@`p?W^}b5tni7xDLN1f~7fh)}-vN0bQ0WD>*5S3?#ZRdn}K z|M`-HyI(xgi-KR8kb{cBd<^*mG}eKxVLX1JD7YJzWYRWhUwU8a;mTHZn=={$kpd!Y zum&O3cvQR<=FMx4g2x~jB3L?qH!h1mI;cemt5;~gOUlMY`VaOSYKRL-O8FPm32j30 z18sD`HaG^;nlc>aC0(978HLo=-gpk4Yy>`$2=lVI`gh3S;>hfs<8))LfWIdB!wtHYqs zSO}DpctX%avs5z3c_VP5)^sSvDU*eOh9aN?oaQ`QMZ*$S43(`I9aM$_#ss4?Q`aDt z7Eh2IphyG3tAf$D)`0-BRN+IC06u{$OFkk(>)jmHSWQif+)6aU1c(}CSqrCffZs4= z)=V{MdkOq=>X?r3uui$SY_=A-hT0nD7(K zcOJ&B;&p-|IujilhgKvy&;uSk2Cb2L)Fw6_JxtCJU-DYUSi0t%r4ia~$9|e4n?Ovz zK7+>$Z>4IL5_UpD9E7(f{Pe;EFgGVgFTST}woWJ9!`;{MjQaZwE;%|m=Q7;IS@${kDj2!^$MSGr$2#+Q}TE{|YI_nA;)HZ7Wov&`d`IQt&Yoh*6 zrht!F?`aEr*3lDm%PR1R8uh(qaDMOKepM#&-oydV$nTs84w=;ISq0XSJriw2VGN$s3dN`otC8ZT)A z0jmcZKus#KDIhVF9jf;r2~g@>{wcP?t&j2mCpyOnqpwLc23@O+k zh6HPp!j&~E?`8PBP0jSs8>l8qfa*r6iijDhMQ0L~6Lo|})MEVBtgPK7zlt9AA|V`J z7)_JXR1fFUe*BLBPWJdfP8W5AXVPMYU>Ehpkejq`)=V-KMfL5V#pWvf)66(NRER)c z5ZbkxSdlWxZp?-@nX9+bv8z)M2U}IqT1`5>X+7V;47NXx-qW#Ya4l8C ze?tpLcmY(O<{mW1E-Ve2jNp_DxpxvCv09JY3qJ_iLTPX*3NJ+e&W!wt4BPPP8eqyKQS-;fcsxY?Gl#P*tFkc+Z~uR$HvM zM%9`03CUIrjHPw$>^Q0YNNLnY-z(aihid)U}F^ zZ0hx${yKhB6|4CI{OKhaJWpxpc`_Y4*n_2~p~@4YOPVBZdQ5oZjEQWUa$u&ZGOzNg zF+@!@-FVX-K~ojzu$a)rplg_V1wiwVpb_efv7;fiYABmt9&4~R=ue6%Ik>xHGaA3Q z{5ei6Kq)lszTBVPl(e|hWd|nlNzuJ;5CQFg$POGGyfTIyV_Z3>hOp|A8TW+^DK1j) zj^4of5BoL&a}N8xJ!*eH?J6{cerZMX(Ytq)e|;DVb&7q(We_*qZ;299NN~K}#4FG@ zNWV<(vUN+{W5F0R#YDkqvQHAL1%v}2=citSAaM9C$`|XF>HOLKetM73a1;UwjCa}^ z+ikJ6f_#IWge@xr!4!_>Y5dmf1nf!vzL)V%QfXD3xg zn&RmQ%z)b|QHpIxcunt$aSa+Ei!mq?sWDBr10s+YPlxfr=j(-_skhmPZ7fY|1+iig z`(3qnGwZFLc!fPJ0+Vj_d>8DX#FG>%_&81Pi9spIV!aLk@y6?eN-Q0hJl#wH*A?xx zz4Lg1F4P(=qTpRCt$Gg%(X1D%5=uKWa@Q0@_EN{0EIL!{p;@yP}zUlkso9Z5+P#Ii>A<Z!kCyj=%QYzn zzo>1fO|9_h?T-O-ZE&XJ{y|+p8%Y*ijGDSoHF(eSKp#ZjZ@niX;Lw78Z!K3zB;k@~ zuc*{%)-G6fOk9*zU zIvI1TrJ|Iyz?>2KSU`NrgGh4Y&cEI{;Q#0e-G3oGcbogWCx0)oddUaVBvaIzL{4*n zl$@sSq>T=uzPtYiK;V$Ov1LXB0004nX+uL$Nkc;*aB^>EX>4Tx0C=2zkv&MmP!xqv zQ$^7h2Rn#3WT;LSL`4J_twIqhgj%6h2a}inL6e3g#l=x@EjakISaoo5*44pP5Cnff z+}xZLU8KbOl0u6ZA6(wYdG8$VyAKfRWu{pjV}PdHW-1XEGuc(K>lM8SQ_UbEGs~Eh zq$GUT*F6G!zl-rK|9gL~u$r?N5DTxwGo6|zju4B5Hdfl06-|wJk~perI^_!)k5$fFoV9Y5HT&c*4CVBdWv){V zA%R6KL4pVcRg_SMjTr4ZDHc+69{2GNx_*gV3b{&Ppt)9ZlBw~cbfD20g0G$ zuy{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G` z2jvS53<42edvZwt00;a@L_t(&-tCxAh#S`($G^Y#-u%;ytX*ln(*BXV)jFx25S(=y zQXJa4B&XQ!lDLIX+7cSbrT7r&p%h9F1w&{GIg~&TI`&kOk``KAXbm}KoyJLQmUTAS zT}fSgrLiQhRvKwE^JZQTSuLsSIJfLV=K})+GrXDa`~80JecumANJvOXNJvOXNJvOX zNJvOXNJvOXNJvOXNJvOX_>!T6^fPB)d4nFaeH^j;`@Z+$i!ZACJujEb_tbUz^l6kz zC5VF}c=0!H5&`t1XHGemp{E?j0b>kN6rtU2qtofgUa!~v_~Va50O|__)0s1893e!C zF@}1*jw@HL;Of<@-BPJE5CUciQLr z{r*|c^AN`|;y4Cl43=fB`@X+fEEfM!tyVt-5Z@z>>Cs0YEpX0HL{W6kFpRTt93uz< zY;SKvDRl|J{-*cYSKc53Navgh!A~-xS0km0uIu8)jT>mU+t4%(Pd@o13WdUvR;%?3 z#@Jz{)HMK%i0)2vBBBKVzm-xJ9mj$1`|vyuD=RCA;~4uc`Z3$bxl<22rmmguwVU5{ z4jn3P-MVRA`{0AP(P(&K81AIg={v6L8pGkxuGMN2&1UoIwY9a7h~7MQ?AZIG`p#rB z4(I&5l=9rn%uF!|f>ga;hiRIK;~2x?5K$EEzvv^D58EOs}dN!M_aL#YmYBd|cRI}N9yx;FHFvgA((G39akH)fXJH;4#jxl!5vMji+i)OQl zVzKx?-`)3`9v>fvrfKMQyQtM_a9tNdh?Y{SEQENMF*XE1!{P8a5q-rp&2dfBu)ARG zZM&sX2|@_Oag1BHZoze3c%Fyp>1i;=4vuIc1WeN;(=^fV_t9##VB0pHdg>|t z^YimNN~xgTZi`B#GIss?^?&wyy?-&rBF0!100V&I$B#ce7!1ByC=_P9-7Y@)`=eSQ5+B0?&aI?5P(K9x#6oy+C)+qZ9H zV`C%ecDtTo7_n{JoO5pPPR@ae^nXpj`1m-sx3{seu@N>Jjk=VwmrkeS)2B}h$8iqp zy8eA#*V)F##+qrGwS|R+X~x*|nx>U3%fi;y7C!puqdWb6|C(i4j%k{coOAs^iDr!L zrQTpLK&4W_%E}6smzM{oX};$;&IW*CyWM_yQG&Vm!e_koo85i zVh3u=8kvRB{r2`Y!Z7sG>GVy;*gN@r{#^i^h@Ow4XfHFQlp>SK{7^~>%d+5k9+sAt zl$5eRJw5F&EG!63)5eJ?55QoIA(cwOvMd2W-&fHimo$pFVHmJ&d(-p0>qN8zAl`jd zjmkhN1t}#`sT3T?fu?CVdh{q>c;N*iBHOa8Q~7-UwIB%Q!!XPmhM~>P&Edj@3&`bi zKLBueUqwqPF&qvdgn&{C*=!cR?+5L6yH7-;G>8quP@|L5$Wlrv_xASPND=@YK&jDa zlr&9)uIqb?WICOOl=AULqrvx8v{DK?J39!&5K$Cic6Jtn!Jr_e{2CECBe#{wWXQ5C zL{Wqw2+-|zQLR?tc^(FX!QS;*W@ctkEEe&=0}r6xZsXFWOQRIue;ew$E)2s!DwRSm zmxJedV-G#_(8H!_{v@4FZ#s^Hv9YlQUDwfUHqmG_5Jiz}x7&Zyb$z+jYGHeO8#_BY zBTGs|L{n2!-%?6F5yvrn-^c3eDjdi8`{d;0Uk-xkm~-Blnwsj&%*>>-*{oA679R}5 z@IfI2G);qH7|=8gtE;Q1R4ULkO|Gr2{c&z??hl1R0h5!Hqhll670ybf(yvX^d}34< zVHl#(X#Dx&#fz`+w`dhbQHL@1yI!wXU0GTAsbLt03WWk}+uo~n&-38AF0Ng>hMPBU zBA?IidFs2))DdHhh)4+`)X0L47D2->m|+-v-y_}WbbJ6;f*=499m!_1Pe>_`#&JB_ zp0KsGg=)2mN~Hqd_czAI#;y|4CII!)OE2BsG6I0u_x+xf@{a4ej_bNw9LIY;d|yTH z_PA8JTxM|`f4~@fd3kyHmq8F*=yW>pJa2EM1^~;lVB7X(#@Np_P3zrn?9I*1rj&BM z)9D;-Hk+9+3?ZeA0YnF-8>)J}o)2K?dEQ%L7`nS1Q24$N&iP0%gb?qQN~PBQI-R$ct`;C*!<>cbxVtk;Q{dfKJ z=VrwhHTyqroQa7EwYa#bkdW}DS Date: Sat, 13 Nov 2021 15:19:34 +0000 Subject: [PATCH 269/296] localize wielditem in crossbow.lua (Fix #1901) --- mods/ITEMS/mcl_bows/crossbow.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/ITEMS/mcl_bows/crossbow.lua b/mods/ITEMS/mcl_bows/crossbow.lua index e3124156b..5ae21a1f3 100644 --- a/mods/ITEMS/mcl_bows/crossbow.lua +++ b/mods/ITEMS/mcl_bows/crossbow.lua @@ -92,7 +92,7 @@ local function get_arrow(player) return arrow_stack, arrow_stack_id end -local function player_shoot_arrow(itemstack, player, power, damage, is_critical) +local function player_shoot_arrow(wielditem, player, power, damage, is_critical) local has_multishot_enchantment = mcl_enchanting.has_enchantment(player:get_wielded_item(), "multishot") local arrow_itemstring = wielditem:get_meta():get("arrow") @@ -286,7 +286,7 @@ end) controls.register_on_press(function(player, key, time) if key~="LMB" then return end - wielditem = player:get_wielded_item() + local wielditem = player:get_wielded_item() if wielditem:get_name()=="mcl_bows:crossbow_loaded" or wielditem:get_name()=="mcl_bows:crossbow_loaded_enchanted" then local enchanted = mcl_enchanting.is_enchanted(wielditem:get_name()) local speed, damage From bcb6251d2058d46ca75cb262fd2628ea44526731 Mon Sep 17 00:00:00 2001 From: NO11 Date: Sat, 13 Nov 2021 17:26:17 +0000 Subject: [PATCH 270/296] Use label instead of extra texture --- mods/HUD/mcl_inventory/creative.lua | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/mods/HUD/mcl_inventory/creative.lua b/mods/HUD/mcl_inventory/creative.lua index de03886d9..a3314ec0a 100644 --- a/mods/HUD/mcl_inventory/creative.lua +++ b/mods/HUD/mcl_inventory/creative.lua @@ -1,5 +1,6 @@ local S = minetest.get_translator(minetest.get_current_modname()) local F = minetest.formspec_escape +local C = minetest.colorize -- Prepare player info table local players = {} @@ -360,11 +361,8 @@ function mcl_inventory.set_creative_formspec(player, start_i, pagenum, inv_size, armor_slot_imgs = armor_slot_imgs .. "image[5.5,2.75;1,1;mcl_inventory_empty_armor_slot_boots.png]" end - local switch_overlay = "blank.png" - if get_stack_size(player) == 64 then - switch_overlay = "mcl_inventory_button_switch_stack.png" - end - + local stack_size = get_stack_size(player) + -- Survival inventory slots main_list = "list[current_player;main;0,3.75;9,3;9]".. mcl_formspec.get_itemslot_bg(0,3.75,9,3).. @@ -394,8 +392,9 @@ function mcl_inventory.set_creative_formspec(player, start_i, pagenum, inv_size, --"style_type[image_button;border=;bgimg=;bgimg_pressed=]".. "tooltip[__mcl_achievements;"..F(S("Achievements")).."]".. -- switch stack size button - "image_button[9,5;1,1;default_apple.png^" .. switch_overlay .. ";__switch_stack;]".. - "tooltip[__switch_stack;"..F(S("Switch stack size")).."]" + "image_button[9,5;1,1;default_apple.png;__switch_stack;]".. + "label[9.4,5.4;".. F(C("#FFFFFF", stack_size ~= 1 and stack_size or "")) .."]".. + "tooltip[__switch_stack;"..F(S("Switch stack size")).."]" -- For shortcuts listrings = listrings .. From add97d39a6171ee5bc20c829dc98074d37fcc14f Mon Sep 17 00:00:00 2001 From: NO11 Date: Sat, 13 Nov 2021 17:28:13 +0000 Subject: [PATCH 271/296] delete overlay texture --- .../mcl_inventory_button_switch_stack.png | Bin 8936 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 mods/HUD/mcl_inventory/textures/mcl_inventory_button_switch_stack.png diff --git a/mods/HUD/mcl_inventory/textures/mcl_inventory_button_switch_stack.png b/mods/HUD/mcl_inventory/textures/mcl_inventory_button_switch_stack.png deleted file mode 100644 index ac56d833d0c6c4efcb9633794ffc9d767247d962..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8936 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 Date: Sat, 13 Nov 2021 18:56:52 +0000 Subject: [PATCH 272/296] Use on_joinplayer instead of on_newplayer --- mods/HUD/mcl_inventory/creative.lua | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/mods/HUD/mcl_inventory/creative.lua b/mods/HUD/mcl_inventory/creative.lua index a3314ec0a..d2dedd556 100644 --- a/mods/HUD/mcl_inventory/creative.lua +++ b/mods/HUD/mcl_inventory/creative.lua @@ -291,15 +291,17 @@ filtername["inv"] = S("Survival Inventory") end]] local function get_stack_size(player) - return player:get_meta():get_int("switch_stack") + return player:get_meta():get_int("mcl_inventory:switch_stack") end local function set_stack_size(player, n) - player:get_meta():set_int("switch_stack", n) + player:get_meta():set_int("mcl_inventory:switch_stack", n) end -minetest.register_on_newplayer(function (player) - set_stack_size(player, 64) +minetest.register_on_joinplayer(function (player) + if get_stack_size(player) == 0 then + set_stack_size(player, 64) + end end) function mcl_inventory.set_creative_formspec(player, start_i, pagenum, inv_size, show, page, filter) From 7ef6613f0967718463e9be3f1f90f97811d8346a Mon Sep 17 00:00:00 2001 From: NO11 Date: Mon, 15 Nov 2021 21:39:43 +0100 Subject: [PATCH 273/296] Rename drippingwater mod to mcl_dripping --- .../{drippingwater => mcl_dripping}/init.lua | 0 .../{drippingwater => mcl_dripping}/mod.conf | 0 .../{drippingwater => mcl_dripping}/readme.txt | 0 .../sounds/drippingwater_drip.1.ogg | Bin .../sounds/drippingwater_drip.2.ogg | Bin .../sounds/drippingwater_drip.3.ogg | Bin .../sounds/drippingwater_lavadrip.1.ogg | Bin .../sounds/drippingwater_lavadrip.2.ogg | Bin .../sounds/drippingwater_lavadrip.3.ogg | Bin 9 files changed, 0 insertions(+), 0 deletions(-) rename mods/ENTITIES/{drippingwater => mcl_dripping}/init.lua (100%) rename mods/ENTITIES/{drippingwater => mcl_dripping}/mod.conf (100%) rename mods/ENTITIES/{drippingwater => mcl_dripping}/readme.txt (100%) rename mods/ENTITIES/{drippingwater => mcl_dripping}/sounds/drippingwater_drip.1.ogg (100%) rename mods/ENTITIES/{drippingwater => mcl_dripping}/sounds/drippingwater_drip.2.ogg (100%) rename mods/ENTITIES/{drippingwater => mcl_dripping}/sounds/drippingwater_drip.3.ogg (100%) rename mods/ENTITIES/{drippingwater => mcl_dripping}/sounds/drippingwater_lavadrip.1.ogg (100%) rename mods/ENTITIES/{drippingwater => mcl_dripping}/sounds/drippingwater_lavadrip.2.ogg (100%) rename mods/ENTITIES/{drippingwater => mcl_dripping}/sounds/drippingwater_lavadrip.3.ogg (100%) diff --git a/mods/ENTITIES/drippingwater/init.lua b/mods/ENTITIES/mcl_dripping/init.lua similarity index 100% rename from mods/ENTITIES/drippingwater/init.lua rename to mods/ENTITIES/mcl_dripping/init.lua diff --git a/mods/ENTITIES/drippingwater/mod.conf b/mods/ENTITIES/mcl_dripping/mod.conf similarity index 100% rename from mods/ENTITIES/drippingwater/mod.conf rename to mods/ENTITIES/mcl_dripping/mod.conf diff --git a/mods/ENTITIES/drippingwater/readme.txt b/mods/ENTITIES/mcl_dripping/readme.txt similarity index 100% rename from mods/ENTITIES/drippingwater/readme.txt rename to mods/ENTITIES/mcl_dripping/readme.txt diff --git a/mods/ENTITIES/drippingwater/sounds/drippingwater_drip.1.ogg b/mods/ENTITIES/mcl_dripping/sounds/drippingwater_drip.1.ogg similarity index 100% rename from mods/ENTITIES/drippingwater/sounds/drippingwater_drip.1.ogg rename to mods/ENTITIES/mcl_dripping/sounds/drippingwater_drip.1.ogg diff --git a/mods/ENTITIES/drippingwater/sounds/drippingwater_drip.2.ogg b/mods/ENTITIES/mcl_dripping/sounds/drippingwater_drip.2.ogg similarity index 100% rename from mods/ENTITIES/drippingwater/sounds/drippingwater_drip.2.ogg rename to mods/ENTITIES/mcl_dripping/sounds/drippingwater_drip.2.ogg diff --git a/mods/ENTITIES/drippingwater/sounds/drippingwater_drip.3.ogg b/mods/ENTITIES/mcl_dripping/sounds/drippingwater_drip.3.ogg similarity index 100% rename from mods/ENTITIES/drippingwater/sounds/drippingwater_drip.3.ogg rename to mods/ENTITIES/mcl_dripping/sounds/drippingwater_drip.3.ogg diff --git a/mods/ENTITIES/drippingwater/sounds/drippingwater_lavadrip.1.ogg b/mods/ENTITIES/mcl_dripping/sounds/drippingwater_lavadrip.1.ogg similarity index 100% rename from mods/ENTITIES/drippingwater/sounds/drippingwater_lavadrip.1.ogg rename to mods/ENTITIES/mcl_dripping/sounds/drippingwater_lavadrip.1.ogg diff --git a/mods/ENTITIES/drippingwater/sounds/drippingwater_lavadrip.2.ogg b/mods/ENTITIES/mcl_dripping/sounds/drippingwater_lavadrip.2.ogg similarity index 100% rename from mods/ENTITIES/drippingwater/sounds/drippingwater_lavadrip.2.ogg rename to mods/ENTITIES/mcl_dripping/sounds/drippingwater_lavadrip.2.ogg diff --git a/mods/ENTITIES/drippingwater/sounds/drippingwater_lavadrip.3.ogg b/mods/ENTITIES/mcl_dripping/sounds/drippingwater_lavadrip.3.ogg similarity index 100% rename from mods/ENTITIES/drippingwater/sounds/drippingwater_lavadrip.3.ogg rename to mods/ENTITIES/mcl_dripping/sounds/drippingwater_lavadrip.3.ogg From d2a03ec0b91c7e5580daab13cea2b585501e50d6 Mon Sep 17 00:00:00 2001 From: NO11 Date: Mon, 15 Nov 2021 21:44:23 +0100 Subject: [PATCH 274/296] Rename entity ids --- mods/ENTITIES/mcl_dripping/init.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/ENTITIES/mcl_dripping/init.lua b/mods/ENTITIES/mcl_dripping/init.lua index 45a211d8f..57ba7ecfe 100644 --- a/mods/ENTITIES/mcl_dripping/init.lua +++ b/mods/ENTITIES/mcl_dripping/init.lua @@ -6,7 +6,7 @@ local math = math -- License of code, textures & sounds: CC0 local function register_drop(liquid, glow, sound, nodes) - minetest.register_entity("drippingwater:drop_" .. liquid, { + minetest.register_entity("mcl_dripping:drop_" .. liquid, { hp_max = 1, physical = true, collide_with_objects = false, @@ -56,7 +56,7 @@ local function register_drop(liquid, glow, sound, nodes) if minetest.get_item_group(minetest.get_node(vector.offset(pos, 0, 1, 0)).name, liquid) ~= 0 and minetest.get_node(vector.offset(pos, 0, -1, 0)).name == "air" then local x, z = math.random(-45, 45) / 100, math.random(-45, 45) / 100 - minetest.add_entity(vector.offset(pos, x, -0.520, z), "drippingwater:drop_" .. liquid) + minetest.add_entity(vector.offset(pos, x, -0.520, z), "mcl_dripping:drop_" .. liquid) end end, }) From a9804879e208de4c8774498d05bb17a5ff0facaf Mon Sep 17 00:00:00 2001 From: NO11 Date: Mon, 15 Nov 2021 21:54:16 +0100 Subject: [PATCH 275/296] Rename drippingwater to mcl_dripping in mod.conf and readme.txt --- mods/ENTITIES/mcl_dripping/mod.conf | 2 +- mods/ENTITIES/mcl_dripping/readme.txt | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mods/ENTITIES/mcl_dripping/mod.conf b/mods/ENTITIES/mcl_dripping/mod.conf index 1de118f4c..921d5e59f 100644 --- a/mods/ENTITIES/mcl_dripping/mod.conf +++ b/mods/ENTITIES/mcl_dripping/mod.conf @@ -1,4 +1,4 @@ -name = drippingwater +name = mcl_dripping author = kddekadenz description = Drops are generated rarely under solid nodes depends = mcl_core diff --git a/mods/ENTITIES/mcl_dripping/readme.txt b/mods/ENTITIES/mcl_dripping/readme.txt index f609163ed..afe35608e 100644 --- a/mods/ENTITIES/mcl_dripping/readme.txt +++ b/mods/ENTITIES/mcl_dripping/readme.txt @@ -1,12 +1,12 @@ -Dripping Water Mod +Dripping Mod by kddekadenz -modified for MineClone 2 by Wuzzy +modified for MineClone 2 by Wuzzy and NO11 Installing instructions: - 1. Copy the drippingwater mod folder into games/gamemode/mods + 1. Copy the mcl_dripping mod folder into games/gamemode/mods 2. Start game and enjoy :) From c757e98b4fbd9110d5afbcda53f4fcc37131ea84 Mon Sep 17 00:00:00 2001 From: NO11 Date: Wed, 17 Nov 2021 00:37:11 +0100 Subject: [PATCH 276/296] Fix #1911, error in lightning callback --- mods/ENVIRONMENT/lightning/init.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mods/ENVIRONMENT/lightning/init.lua b/mods/ENVIRONMENT/lightning/init.lua index 83494462f..3579316e8 100644 --- a/mods/ENVIRONMENT/lightning/init.lua +++ b/mods/ENVIRONMENT/lightning/init.lua @@ -215,7 +215,9 @@ lightning.register_on_strike(function(pos, pos2, objects) posadd = { x=math.cos(angle),y=0,z=math.sin(angle) } posadd = vector.normalize(posadd) local mob = add_entity(vector.add(pos2, posadd), "mobs_mc:skeleton") - mob:set_yaw(angle-math.pi/2) + if mob then + mob:set_yaw(angle-math.pi/2) + end angle = angle + (math.pi*2) / 3 end From 9919011aca6fbcf9cbb086d8260e4da0d1de3625 Mon Sep 17 00:00:00 2001 From: NO11 Date: Wed, 17 Nov 2021 16:43:48 +0100 Subject: [PATCH 277/296] Fix enchanted books losing their enchantments in creative inventory --- mods/HUD/mcl_inventory/creative.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mods/HUD/mcl_inventory/creative.lua b/mods/HUD/mcl_inventory/creative.lua index d2dedd556..76139160b 100644 --- a/mods/HUD/mcl_inventory/creative.lua +++ b/mods/HUD/mcl_inventory/creative.lua @@ -695,8 +695,9 @@ minetest.register_on_joinplayer(function(player) end) minetest.register_on_player_inventory_action(function(player, action, inventory, inventory_info) - if minetest.is_creative_enabled(player:get_player_name()) and action == "put" and inventory_info.listname == "main" and get_stack_size(player) == 64 then - local stack = inventory_info.stack - player:get_inventory():set_stack("main", inventory_info.index, stack:get_name() .. " " .. stack:get_stack_max()) + local stack = inventory_info.stack + local item = stack:get_name() + if minetest.is_creative_enabled(player:get_player_name()) and action == "put" and inventory_info.listname == "main" and get_stack_size(player) == 64 and not item:find("mcl_enchanting:book_enchanted") then + player:get_inventory():set_stack("main", inventory_info.index, item .. " " .. stack:get_stack_max()) end end) \ No newline at end of file From 30528b0a2c4fb0cd54f30dfe0ba38d568a2f9b18 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 17 Nov 2021 18:25:12 +0100 Subject: [PATCH 278/296] Fix crash when opening a chest with an unknown node on top --- mods/ITEMS/mcl_chests/init.lua | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/mods/ITEMS/mcl_chests/init.lua b/mods/ITEMS/mcl_chests/init.lua index 69f6a601d..7a0e54c69 100644 --- a/mods/ITEMS/mcl_chests/init.lua +++ b/mods/ITEMS/mcl_chests/init.lua @@ -608,10 +608,12 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile on_rightclick = function(pos, node, clicker) local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "left") - if minetest.registered_nodes[minetest.get_node({x = pos.x, y = pos.y + 1, z = pos.z}).name].groups.opaque == 1 - or minetest.registered_nodes[minetest.get_node({x = pos_other.x, y = pos_other.y + 1, z = pos_other.z}).name].groups.opaque == 1 then - -- won't open if there is no space from the top - return false + local above_def = minetest.registered_nodes[minetest.get_node({x = pos.x, y = pos.y + 1, z = pos.z}).name] + local above_def_other = minetest.registered_nodes[minetest.get_node({x = pos_other.x, y = pos_other.y + 1, z = pos_other.z}).name] + + if not above_def or above_def.groups.opaque == 1 or not above_def_other or above_def_other.groups.opaque == 1 then + -- won't open if there is no space from the top + return false end local name = minetest.get_meta(pos):get_string("name") From 903d1777be98e62e1f9c11aedcda8236688dc796 Mon Sep 17 00:00:00 2001 From: NO11 Date: Thu, 18 Nov 2021 17:40:32 +0100 Subject: [PATCH 279/296] Use set_count instead of creating a new item and checking for enchanted books --- mods/HUD/mcl_inventory/creative.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mods/HUD/mcl_inventory/creative.lua b/mods/HUD/mcl_inventory/creative.lua index 76139160b..f5a9574eb 100644 --- a/mods/HUD/mcl_inventory/creative.lua +++ b/mods/HUD/mcl_inventory/creative.lua @@ -695,9 +695,9 @@ minetest.register_on_joinplayer(function(player) end) minetest.register_on_player_inventory_action(function(player, action, inventory, inventory_info) - local stack = inventory_info.stack - local item = stack:get_name() - if minetest.is_creative_enabled(player:get_player_name()) and action == "put" and inventory_info.listname == "main" and get_stack_size(player) == 64 and not item:find("mcl_enchanting:book_enchanted") then - player:get_inventory():set_stack("main", inventory_info.index, item .. " " .. stack:get_stack_max()) + if minetest.is_creative_enabled(player:get_player_name()) and get_stack_size(player) == 64 and action == "put" and inventory_info.listname == "main" then + local stack = inventory_info.stack + stack:set_count(stack:get_stack_max()) + player:get_inventory():set_stack("main", inventory_info.index, stack) end -end) \ No newline at end of file +end) From b0aceae73dbfc3405b4b3a3d0db63e759e9a48f1 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Fri, 19 Nov 2021 15:22:40 +0100 Subject: [PATCH 280/296] Fix reference dupe glitches --- mods/ITEMS/mcl_chests/init.lua | 4 ++-- mods/ITEMS/mcl_furnaces/init.lua | 4 ++-- mods/ITEMS/mcl_hoppers/init.lua | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/mods/ITEMS/mcl_chests/init.lua b/mods/ITEMS/mcl_chests/init.lua index 7a0e54c69..d87ae2a1d 100644 --- a/mods/ITEMS/mcl_chests/init.lua +++ b/mods/ITEMS/mcl_chests/init.lua @@ -293,7 +293,7 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile local function drop_items_chest(pos, oldnode, oldmetadata) local meta = minetest.get_meta(pos) - local meta2 = meta + local meta2 = meta:to_table() if oldmetadata then meta:from_table(oldmetadata) end @@ -305,7 +305,7 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile minetest.add_item(p, stack) end end - meta:from_table(meta2:to_table()) + meta:from_table(meta2) end local function on_chest_blast(pos) diff --git a/mods/ITEMS/mcl_furnaces/init.lua b/mods/ITEMS/mcl_furnaces/init.lua index dca476762..9f836d161 100644 --- a/mods/ITEMS/mcl_furnaces/init.lua +++ b/mods/ITEMS/mcl_furnaces/init.lua @@ -461,7 +461,7 @@ minetest.register_node("mcl_furnaces:furnace", { on_timer = furnace_node_timer, after_dig_node = function(pos, oldnode, oldmetadata, digger) local meta = minetest.get_meta(pos) - local meta2 = meta + local meta2 = meta:to_table() meta:from_table(oldmetadata) local inv = meta:get_inventory() for _, listname in ipairs({"src", "dst", "fuel"}) do @@ -471,7 +471,7 @@ minetest.register_node("mcl_furnaces:furnace", { minetest.add_item(p, stack) end end - meta:from_table(meta2:to_table()) + meta:from_table(meta2) end, on_construct = function(pos) diff --git a/mods/ITEMS/mcl_hoppers/init.lua b/mods/ITEMS/mcl_hoppers/init.lua index 9defa26ca..f9ba1a8c8 100644 --- a/mods/ITEMS/mcl_hoppers/init.lua +++ b/mods/ITEMS/mcl_hoppers/init.lua @@ -61,7 +61,7 @@ local def_hopper = { after_dig_node = function(pos, oldnode, oldmetadata, digger) local meta = minetest.get_meta(pos) - local meta2 = meta + local meta2 = meta:to_table() meta:from_table(oldmetadata) local inv = meta:get_inventory() for i=1,inv:get_size("main") do @@ -71,7 +71,7 @@ local def_hopper = { minetest.add_item(p, stack) end end - meta:from_table(meta2:to_table()) + meta:from_table(meta2) end, allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) local name = player:get_player_name() From 46394e7e1f82856c9c9de262857bb08c2d8ea820 Mon Sep 17 00:00:00 2001 From: Nils Dagsson Moskopp Date: Wed, 17 Nov 2021 18:03:45 +0100 Subject: [PATCH 281/296] Add obsidian boat that always sinks --- mods/ENTITIES/mcl_boats/init.lua | 11 ++++++----- .../textures/mcl_boats_obsidian_boat.png | Bin 0 -> 264 bytes .../textures/mcl_boats_texture_obsidian_boat.png | Bin 0 -> 535 bytes 3 files changed, 6 insertions(+), 5 deletions(-) create mode 100644 mods/ENTITIES/mcl_boats/textures/mcl_boats_obsidian_boat.png create mode 100644 mods/ENTITIES/mcl_boats/textures/mcl_boats_texture_obsidian_boat.png diff --git a/mods/ENTITIES/mcl_boats/init.lua b/mods/ENTITIES/mcl_boats/init.lua index f46c14d46..beff5fb52 100644 --- a/mods/ENTITIES/mcl_boats/init.lua +++ b/mods/ENTITIES/mcl_boats/init.lua @@ -342,7 +342,8 @@ function boat.on_step(self, dtime, moveresult) self.object:get_velocity().y) else p.y = p.y + 1 - if is_water(p) then + local is_obsidian_boat = self.object:get_luaentity()._itemstring == "mcl_boats:boat_obsidian" + if is_water(p) or is_obsidian_boat then -- Inside water: Slowly sink local y = self.object:get_velocity().y y = y - 0.01 @@ -382,13 +383,13 @@ end -- Register one entity for all boat types minetest.register_entity("mcl_boats:boat", boat) -local boat_ids = { "boat", "boat_spruce", "boat_birch", "boat_jungle", "boat_acacia", "boat_dark_oak" } -local names = { S("Oak Boat"), S("Spruce Boat"), S("Birch Boat"), S("Jungle Boat"), S("Acacia Boat"), S("Dark Oak Boat") } +local boat_ids = { "boat", "boat_spruce", "boat_birch", "boat_jungle", "boat_acacia", "boat_dark_oak", "boat_obsidian" } +local names = { S("Oak Boat"), S("Spruce Boat"), S("Birch Boat"), S("Jungle Boat"), S("Acacia Boat"), S("Dark Oak Boat"), S("Obsidian Boat") } local craftstuffs = {} if minetest.get_modpath("mcl_core") then - craftstuffs = { "mcl_core:wood", "mcl_core:sprucewood", "mcl_core:birchwood", "mcl_core:junglewood", "mcl_core:acaciawood", "mcl_core:darkwood" } + craftstuffs = { "mcl_core:wood", "mcl_core:sprucewood", "mcl_core:birchwood", "mcl_core:junglewood", "mcl_core:acaciawood", "mcl_core:darkwood", "mcl_core:obsidian" } end -local images = { "oak", "spruce", "birch", "jungle", "acacia", "dark_oak" } +local images = { "oak", "spruce", "birch", "jungle", "acacia", "dark_oak", "obsidian" } for b=1, #boat_ids do local itemstring = "mcl_boats:"..boat_ids[b] diff --git a/mods/ENTITIES/mcl_boats/textures/mcl_boats_obsidian_boat.png b/mods/ENTITIES/mcl_boats/textures/mcl_boats_obsidian_boat.png new file mode 100644 index 0000000000000000000000000000000000000000..6ae10c0c4b4dfd9e13a5008aa3a60c15d85b2930 GIT binary patch literal 264 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd7G?$phPQVgfdmW!d_r7Vn7PMoQb@Y-&yfo$yU_xFVdQ&MBb@0P{jy^8f$< literal 0 HcmV?d00001 diff --git a/mods/ENTITIES/mcl_boats/textures/mcl_boats_texture_obsidian_boat.png b/mods/ENTITIES/mcl_boats/textures/mcl_boats_texture_obsidian_boat.png new file mode 100644 index 0000000000000000000000000000000000000000..af3c24b30e5fa0fa9937cf9f874aa43651924013 GIT binary patch literal 535 zcmeAS@N?(olHy`uVBq!ia0y~yU}#`qU~phzW?*1Y_>ttpz`$S-;1lA?!pz0S!pq4n z!p|or%4eW16st$K#jz{DKySD{%Pm8(`uoPSN^$j@E5?Q*}$1jUDcEZ5K2tiaKvz_Y9P&5S0^xn(_utqZby43{N% zP4-f|{{DOXw|Ti!134ZD#c%W4%=lngyW+Eo*XQ=j2RE!?PLYXbmH5^mdqa!in0Of% zPlM6~1xb^#pC^_)pOC|MU>|d|E5n0z?Ai8CA|E+#XhpIsGThMmcHh3}kMw50rhThc zt(yMjjv#}ode!`?MpAoDXE5B*ntAEu<=K`Nn@V5WW^6sJ5`R;wb>dqi_3D7xbBnLm zxMr_f_4Cvr+Yh0$kFP3~|4?&vm;B#L5&Ra`&)-FTec=AznSakq%kNtSc0c=C`?&Fm zQ1yYAmg!mYW*ga`mxisr+I>yvd-F}X2{t7+RZdRf`*W}Ez?RDAk8BG(C*|yNP&s+^ zn}hADS5xK7-&PBRhi{ZO$i27o?ZK>b+>dP?p5MMbPuwiUKH~T1L-H>Un#bQYRlT6u Qa~Tv#p00i_>zopr058tt4FCWD literal 0 HcmV?d00001 From 9edf277905d42ad98644217b1dd7448e5a5b11bd Mon Sep 17 00:00:00 2001 From: Glaucos Ginez Date: Sun, 21 Nov 2021 22:13:24 -0300 Subject: [PATCH 282/296] Fix mobs spawn count --- mods/ITEMS/mcl_mobspawners/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_mobspawners/init.lua b/mods/ITEMS/mcl_mobspawners/init.lua index 6e4b24c96..0795fb611 100644 --- a/mods/ITEMS/mcl_mobspawners/init.lua +++ b/mods/ITEMS/mcl_mobspawners/init.lua @@ -230,7 +230,7 @@ local function spawn_mobs(pos, elapsed) -- spawn up to 4 mobs in random air blocks if air then - local max = 200 + local max = 4 if spawn_count_overrides[mob] then max = spawn_count_overrides[mob] end From d3015edeb9489d8a046cd3a635acc7bff14db8f5 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 29 Nov 2021 19:12:49 +0100 Subject: [PATCH 283/296] Fix reference dupes for droppers and dispensers --- mods/ITEMS/REDSTONE/mcl_dispensers/init.lua | 4 ++-- mods/ITEMS/REDSTONE/mcl_droppers/init.lua | 4 ++-- mods/ITEMS/REDSTONE/mcl_droppers/init_new.lua | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua b/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua index 47acacbb9..0cd0608c4 100644 --- a/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua +++ b/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua @@ -82,7 +82,7 @@ local dispenserdef = { end, after_dig_node = function(pos, oldnode, oldmetadata, digger) local meta = minetest.get_meta(pos) - local meta2 = meta + local meta2 = meta:to_table() meta:from_table(oldmetadata) local inv = meta:get_inventory() for i=1, inv:get_size("main") do @@ -92,7 +92,7 @@ local dispenserdef = { minetest.add_item(p, stack) end end - meta:from_table(meta2:to_table()) + meta:from_table(meta2) end, _mcl_blast_resistance = 3.5, _mcl_hardness = 3.5, diff --git a/mods/ITEMS/REDSTONE/mcl_droppers/init.lua b/mods/ITEMS/REDSTONE/mcl_droppers/init.lua index b5bcc1d08..abb351091 100644 --- a/mods/ITEMS/REDSTONE/mcl_droppers/init.lua +++ b/mods/ITEMS/REDSTONE/mcl_droppers/init.lua @@ -55,7 +55,7 @@ local dropperdef = { sounds = mcl_sounds.node_sound_stone_defaults(), after_dig_node = function(pos, oldnode, oldmetadata, digger) local meta = minetest.get_meta(pos) - local meta2 = meta + local meta2 = meta:to_table() meta:from_table(oldmetadata) local inv = meta:get_inventory() for i=1, inv:get_size("main") do @@ -65,7 +65,7 @@ local dropperdef = { minetest.add_item(p, stack) end end - meta:from_table(meta2:to_table()) + meta:from_table(meta2) end, allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) local name = player:get_player_name() diff --git a/mods/ITEMS/REDSTONE/mcl_droppers/init_new.lua b/mods/ITEMS/REDSTONE/mcl_droppers/init_new.lua index 5409e6abc..bd8c0a3c3 100644 --- a/mods/ITEMS/REDSTONE/mcl_droppers/init_new.lua +++ b/mods/ITEMS/REDSTONE/mcl_droppers/init_new.lua @@ -53,7 +53,7 @@ local dropperdef = { sounds = mcl_sounds.node_sound_stone_defaults(), after_dig_node = function(pos, oldnode, oldmetadata, digger) local meta = minetest.get_meta(pos) - local meta2 = meta + local meta2 = meta:to_table() meta:from_table(oldmetadata) local inv = meta:get_inventory() for i=1, inv:get_size("main") do @@ -63,7 +63,7 @@ local dropperdef = { minetest.add_item(p, stack) end end - meta:from_table(meta2:to_table()) + meta:from_table(meta2) end, allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) local name = player:get_player_name() From e6b200aaf3b0a56860272a57012f24ccfa7182ff Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Thu, 2 Dec 2021 16:19:59 +0100 Subject: [PATCH 284/296] Fix access to ender inventory without an ender chest --- mods/ITEMS/mcl_chests/init.lua | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/mods/ITEMS/mcl_chests/init.lua b/mods/ITEMS/mcl_chests/init.lua index d87ae2a1d..ad5c781f7 100644 --- a/mods/ITEMS/mcl_chests/init.lua +++ b/mods/ITEMS/mcl_chests/init.lua @@ -1055,6 +1055,20 @@ minetest.register_on_joinplayer(function(player) inv:set_size("enderchest", 9*3) end) +minetest.register_allow_player_inventory_action(function(player, action, inv, info) + if inv:get_location().type == "player" and ( + action == "move" and (info.from_list == "enderchest" or info.to_list == "enderchest") + or action == "put" and info.listname == "enderchest" + or action == "take" and info.listname == "enderchest" + ) then + local def = player:get_wielded_item():get_definition() + + if not minetest.find_node_near(player:get_pos(), def and def.range or ItemStack():get_definition().range, "mcl_chests:ender_chest_small", true) then + return 0 + end + end +end) + minetest.register_craft({ output = "mcl_chests:ender_chest", recipe = { From 92686e5412b593776bcc9c5568c94e0aea23a8eb Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Thu, 2 Dec 2021 17:28:19 +0100 Subject: [PATCH 285/296] Fix broken mcl_util.calculate_durability --- mods/CORE/mcl_util/init.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mods/CORE/mcl_util/init.lua b/mods/CORE/mcl_util/init.lua index d91c86f09..d548f6cac 100644 --- a/mods/CORE/mcl_util/init.lua +++ b/mods/CORE/mcl_util/init.lua @@ -478,7 +478,9 @@ function mcl_util.calculate_durability(itemstack) end end end - uses = uses or (next(itemstack:get_tool_capabilities().groupcaps) or {}).uses + + local _, groupcap = next(itemstack:get_tool_capabilities().groupcaps) + uses = uses or (groupcap or {}).uses end return uses or 0 From 261faafb7c2d05f1269fb3733912dd82cc815aec Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 7 Dec 2021 15:47:23 +0100 Subject: [PATCH 286/296] Fix get_possible_enchantments to not return incompatible enchantments, even if treasure enchantments are allowed --- mods/ITEMS/mcl_enchanting/engine.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mods/ITEMS/mcl_enchanting/engine.lua b/mods/ITEMS/mcl_enchanting/engine.lua index 02425945c..d02be418d 100644 --- a/mods/ITEMS/mcl_enchanting/engine.lua +++ b/mods/ITEMS/mcl_enchanting/engine.lua @@ -123,7 +123,7 @@ function mcl_enchanting.can_enchant(itemstack, enchantment, level) if itemname == "" then return false, "item missing" end - local supported, primary = mcl_enchanting.item_supports_enchantment(itemstack:get_name(), enchantment) + local supported, primary = mcl_enchanting.item_supports_enchantment(itemname, enchantment) if not supported then return false, "item not supported" end @@ -132,7 +132,7 @@ function mcl_enchanting.can_enchant(itemstack, enchantment, level) end if level > enchantment_def.max_level then return false, "level too high", enchantment_def.max_level - elseif level < 1 then + elseif level < 1 then return false, "level too small", 1 end local item_enchantments = mcl_enchanting.get_enchantments(itemstack) @@ -298,8 +298,8 @@ end function mcl_enchanting.get_possible_enchantments(itemstack, enchantment_level, treasure) local possible_enchantments, weights, accum_weight = {}, {}, 0 for enchantment, enchantment_def in pairs(mcl_enchanting.enchantments) do - local _, _, _, primary = mcl_enchanting.can_enchant(itemstack, enchantment, 1) - if primary or treasure then + local can_enchant, _, _, primary = mcl_enchanting.can_enchant(itemstack, enchantment, 1) + if can_enchant and (primary or treasure) then table.insert(possible_enchantments, enchantment) accum_weight = accum_weight + enchantment_def.weight weights[enchantment] = accum_weight From 882db9f873213ad9e6901b7be62b4b32658f70c4 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 7 Dec 2021 15:49:12 +0100 Subject: [PATCH 287/296] Remove unused and completely unlogical enchantment_level paramenter from get_possible_enchantments --- mods/ITEMS/mcl_enchanting/engine.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/ITEMS/mcl_enchanting/engine.lua b/mods/ITEMS/mcl_enchanting/engine.lua index d02be418d..d4953b7da 100644 --- a/mods/ITEMS/mcl_enchanting/engine.lua +++ b/mods/ITEMS/mcl_enchanting/engine.lua @@ -295,7 +295,7 @@ function mcl_enchanting.initialize() end end -function mcl_enchanting.get_possible_enchantments(itemstack, enchantment_level, treasure) +function mcl_enchanting.get_possible_enchantments(itemstack, treasure) local possible_enchantments, weights, accum_weight = {}, {}, 0 for enchantment, enchantment_def in pairs(mcl_enchanting.enchantments) do local can_enchant, _, _, primary = mcl_enchanting.can_enchant(itemstack, enchantment, 1) @@ -327,7 +327,7 @@ function mcl_enchanting.generate_random_enchantments(itemstack, enchantment_leve if enchantment_level == 0 then break end - local possible, weights, accum_weight = mcl_enchanting.get_possible_enchantments(itemstack, enchantment_level, treasure) + local possible, weights, accum_weight = mcl_enchanting.get_possible_enchantments(itemstack, treasure) local selected_enchantment, enchantment_power if #possible > 0 then local r = math.random(accum_weight) From b3958a956d3dfb7751a14670076b8d6b3fd3731e Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 7 Dec 2021 16:16:07 +0100 Subject: [PATCH 288/296] Refactor random enchantment selection code --- mods/ITEMS/mcl_enchanting/engine.lua | 113 +++++++++++++-------------- 1 file changed, 54 insertions(+), 59 deletions(-) diff --git a/mods/ITEMS/mcl_enchanting/engine.lua b/mods/ITEMS/mcl_enchanting/engine.lua index d4953b7da..b1cb74fb4 100644 --- a/mods/ITEMS/mcl_enchanting/engine.lua +++ b/mods/ITEMS/mcl_enchanting/engine.lua @@ -295,17 +295,22 @@ function mcl_enchanting.initialize() end end -function mcl_enchanting.get_possible_enchantments(itemstack, treasure) - local possible_enchantments, weights, accum_weight = {}, {}, 0 +function mcl_enchanting.get_random_enchantment(itemstack, treasure, weighted, exclude, pr) + local possible = {} + for enchantment, enchantment_def in pairs(mcl_enchanting.enchantments) do local can_enchant, _, _, primary = mcl_enchanting.can_enchant(itemstack, enchantment, 1) - if can_enchant and (primary or treasure) then - table.insert(possible_enchantments, enchantment) - accum_weight = accum_weight + enchantment_def.weight - weights[enchantment] = accum_weight + + if can_enchant and (primary or treasure) and (not exclude or table.indexof(exclude, enchantment) == -1) then + local weight = weighted and enchantment_def.weight or 1 + + for i = 1, weight do + table.insert(possible, enchantment) + end end end - return possible_enchantments, weights, accum_weight + + return #possible > 0 and possible[pr and pr:next(1, #possible) or math.random(#possible)] end function mcl_enchanting.generate_random_enchantments(itemstack, enchantment_level, treasure, no_reduced_bonus_chance, ignore_already_enchanted) @@ -324,41 +329,42 @@ function mcl_enchanting.generate_random_enchantments(itemstack, enchantment_leve enchantment_level = enchantment_level * 2 repeat enchantment_level = math.floor(enchantment_level / 2) + if enchantment_level == 0 then break end - local possible, weights, accum_weight = mcl_enchanting.get_possible_enchantments(itemstack, treasure) - local selected_enchantment, enchantment_power - if #possible > 0 then - local r = math.random(accum_weight) - for _, enchantment in ipairs(possible) do - if weights[enchantment] >= r then - selected_enchantment = enchantment - break - end - end - local enchantment_def = mcl_enchanting.enchantments[selected_enchantment] - local power_range_table = enchantment_def.power_range_table - for i = enchantment_def.max_level, 1, -1 do - local power_range = power_range_table[i] - if enchantment_level >= power_range[1] and enchantment_level <= power_range[2] then - enchantment_power = i - break - end - end - if not description then - if not enchantment_power then - return - end - description = mcl_enchanting.get_enchantment_description(selected_enchantment, enchantment_power) - end - if enchantment_power then - enchantments[selected_enchantment] = enchantment_power - mcl_enchanting.enchant(itemstack, selected_enchantment, enchantment_power) - end - else + + local selected_enchantment = mcl_enchanting.get_random_enchantment(itemstack, treasure, true) + + if not selected_enchantment then break end + + local enchantment_def = mcl_enchanting.enchantments[selected_enchantment] + local power_range_table = enchantment_def.power_range_table + + local enchantment_power + + for i = enchantment_def.max_level, 1, -1 do + local power_range = power_range_table[i] + if enchantment_level >= power_range[1] and enchantment_level <= power_range[2] then + enchantment_power = i + break + end + end + + if not description then + if not enchantment_power then + return + end + + description = mcl_enchanting.get_enchantment_description(selected_enchantment, enchantment_power) + end + + if enchantment_power then + enchantments[selected_enchantment] = enchantment_power + mcl_enchanting.enchant(itemstack, selected_enchantment, enchantment_power) + end until not no_reduced_bonus_chance and math.random() >= (enchantment_level + 1) / 50 return enchantments, description end @@ -381,32 +387,21 @@ function mcl_enchanting.get_randomly_enchanted_book(enchantment_level, treasure, return mcl_enchanting.enchant_randomly(ItemStack("mcl_books:book"), enchantment_level, treasure, no_reduced_bonus_chance, true) end -function mcl_enchanting.get_uniform_randomly_enchanted_book(except, pr) - except = except or except - local stack = ItemStack("mcl_enchanting:book_enchanted") - local list = {} - for enchantment in pairs(mcl_enchanting.enchantments) do - if table.indexof(except, enchantment) == -1 then - table.insert(list, enchantment) - end +function mcl_enchanting.enchant_uniform_randomly(stack, exclude, pr) + local enchantment = mcl_enchanting.get_random_enchantment(stack, true, weighted, exclude, pr) + + if enchantment then + local max_level = mcl_enchanting.enchantments[enchantment].max_level + mcl_enchanting.enchant(stack, enchantment, pr and pr:next(1, max_level) or math.random(max_level)) end - local index, level - if pr then - index = pr:next(1,#list) - else - index = math.random(#list) - end - local enchantment = list[index] - local enchantment_def = mcl_enchanting.enchantments[enchantment] - if pr then - level = pr:next(1, enchantment_def.max_level) - else - level = math.random(enchantment_def.max_level) - end - mcl_enchanting.enchant(stack, enchantment, level) + return stack end +function mcl_enchanting.get_uniform_randomly_enchanted_book(exclude, pr) + return mcl_enchanting.enchant_uniform_randomly(ItemStack("mcl_books:book"), exclude, pr) +end + function mcl_enchanting.get_random_glyph_row() local glyphs = "" local x = 1.3 From ec7e245b9d165c0ffdd8963909c494f835ccf19a Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 7 Dec 2021 17:57:18 +0100 Subject: [PATCH 289/296] Various fixes to the enchanting and loot system - enchanted loot generated by mapgen now uses PseudoRandom for randomness - prevent fishing loot from generating loot 32767 times (!!!) when only 1 is needed - bows and fishing rods obtained from the treasure section of fishing loot are now enchanted - there is now a function to uniform enchant items other than books --- mods/CORE/mcl_loot/init.lua | 23 ++++---- mods/ENTITIES/mobs_mc/villager.lua | 2 +- mods/ITEMS/mcl_enchanting/engine.lua | 57 ++++++++++++-------- mods/ITEMS/mcl_fishing/init.lua | 26 ++++++--- mods/MAPGEN/mcl_dungeons/init.lua | 3 ++ mods/MAPGEN/mcl_structures/init.lua | 4 +- mods/MAPGEN/tsm_railcorridors/gameconfig.lua | 4 +- 7 files changed, 76 insertions(+), 43 deletions(-) diff --git a/mods/CORE/mcl_loot/init.lua b/mods/CORE/mcl_loot/init.lua index 1b2c50807..b90cd4428 100644 --- a/mods/CORE/mcl_loot/init.lua +++ b/mods/CORE/mcl_loot/init.lua @@ -58,26 +58,27 @@ function mcl_loot.get_loot(loot_definitions, pr) end if item then local itemstring = item.itemstring - local itemstack = item.itemstack + if itemstring then + local stack = ItemStack(itemstring) + if item.amount_min and item.amount_max then - itemstring = itemstring .. " " .. pr:next(item.amount_min, item.amount_max) + stack:set_count(pr:next(item.amount_min, item.amount_max)) end + if item.wear_min and item.wear_max then -- Sadly, PseudoRandom only allows very narrow ranges, so we set wear in steps of 10 local wear_min = math.floor(item.wear_min / 10) local wear_max = math.floor(item.wear_max / 10) - local wear = pr:next(wear_min, wear_max) * 10 - if not item.amount_min and not item.amount_max then - itemstring = itemstring .. " 1" - end - - itemstring = itemstring .. " " .. tostring(wear) + stack:set_wear(pr:next(wear_min, wear_max) * 10) end - table.insert(items, itemstring) - elseif itemstack then - table.insert(items, itemstack) + + if item.func then + item.func(stack, pr) + end + + table.insert(items, stack) else minetest.log("error", "[mcl_loot] INTERNAL ERROR! Failed to select random loot item!") end diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index 06cec9ed6..ce2e76575 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -409,7 +409,7 @@ local init_trades = function(self, inv) local offered_stack = ItemStack({name = offered_item, count = offered_count}) if mcl_enchanting.is_enchanted(offered_item) then if mcl_enchanting.is_book(offered_item) then - offered_stack = mcl_enchanting.get_uniform_randomly_enchanted_book({"soul_speed"}) + mcl_enchanting.enchant_uniform_randomly(offered_stack, {"soul_speed"}) else mcl_enchanting.enchant_randomly(offered_stack, math.random(5, 19), false, false, true) mcl_enchanting.unload_enchantments(offered_stack) diff --git a/mods/ITEMS/mcl_enchanting/engine.lua b/mods/ITEMS/mcl_enchanting/engine.lua index b1cb74fb4..97a176b97 100644 --- a/mods/ITEMS/mcl_enchanting/engine.lua +++ b/mods/ITEMS/mcl_enchanting/engine.lua @@ -295,6 +295,16 @@ function mcl_enchanting.initialize() end end +function mcl_enchanting.random(pr, ...) + local r = pr and pr:next(...) or math.random(...) + + if pr and not ({...})[1] then + r = r / 32767 + end + + return r +end + function mcl_enchanting.get_random_enchantment(itemstack, treasure, weighted, exclude, pr) local possible = {} @@ -310,23 +320,30 @@ function mcl_enchanting.get_random_enchantment(itemstack, treasure, weighted, ex end end - return #possible > 0 and possible[pr and pr:next(1, #possible) or math.random(#possible)] + return #possible > 0 and possible[mcl_enchanting.random(pr, 1, #possible)] end -function mcl_enchanting.generate_random_enchantments(itemstack, enchantment_level, treasure, no_reduced_bonus_chance, ignore_already_enchanted) +function mcl_enchanting.generate_random_enchantments(itemstack, enchantment_level, treasure, no_reduced_bonus_chance, ignore_already_enchanted, pr) local itemname = itemstack:get_name() + if not mcl_enchanting.can_enchant_freshly(itemname) and not ignore_already_enchanted then return end + itemstack = ItemStack(itemstack) + local enchantability = minetest.get_item_group(itemname, "enchantability") - enchantability = 1 + math.random(0, math.floor(enchantability / 4)) + math.random(0, math.floor(enchantability / 4)) + enchantability = 1 + mcl_enchanting.random(pr, 0, math.floor(enchantability / 4)) + mcl_enchanting.random(pr, 0, math.floor(enchantability / 4)) + enchantment_level = enchantment_level + enchantability - enchantment_level = enchantment_level + enchantment_level * (math.random() + math.random() - 1) * 0.15 + enchantment_level = enchantment_level + enchantment_level * (mcl_enchanting.random(pr) + mcl_enchanting.random(pr) - 1) * 0.15 enchantment_level = math.max(math.floor(enchantment_level + 0.5), 1) + local enchantments = {} local description + enchantment_level = enchantment_level * 2 + repeat enchantment_level = math.floor(enchantment_level / 2) @@ -334,7 +351,7 @@ function mcl_enchanting.generate_random_enchantments(itemstack, enchantment_leve break end - local selected_enchantment = mcl_enchanting.get_random_enchantment(itemstack, treasure, true) + local selected_enchantment = mcl_enchanting.get_random_enchantment(itemstack, treasure, true, nil, pr) if not selected_enchantment then break @@ -365,43 +382,41 @@ function mcl_enchanting.generate_random_enchantments(itemstack, enchantment_leve enchantments[selected_enchantment] = enchantment_power mcl_enchanting.enchant(itemstack, selected_enchantment, enchantment_power) end - until not no_reduced_bonus_chance and math.random() >= (enchantment_level + 1) / 50 + + until not no_reduced_bonus_chance and mcl_enchanting.random(pr) >= (enchantment_level + 1) / 50 + return enchantments, description end -function mcl_enchanting.generate_random_enchantments_reliable(itemstack, enchantment_level, treasure, no_reduced_bonus_chance, ignore_already_enchanted) +function mcl_enchanting.generate_random_enchantments_reliable(itemstack, enchantment_level, treasure, no_reduced_bonus_chance, ignore_already_enchanted, pr) local enchantments + repeat - enchantments = mcl_enchanting.generate_random_enchantments(itemstack, enchantment_level, treasure, no_reduced_bonus_chance, ignore_already_enchanted) + enchantments = mcl_enchanting.generate_random_enchantments(itemstack, enchantment_level, treasure, no_reduced_bonus_chance, ignore_already_enchanted, pr) until enchantments + return enchantments end -function mcl_enchanting.enchant_randomly(itemstack, enchantment_level, treasure, no_reduced_bonus_chance, ignore_already_enchanted) +function mcl_enchanting.enchant_randomly(itemstack, enchantment_level, treasure, no_reduced_bonus_chance, ignore_already_enchanted, pr) + local enchantments = mcl_enchanting.generate_random_enchantments_reliable(itemstack, enchantment_level, treasure, no_reduced_bonus_chance, ignore_already_enchanted, pr) + mcl_enchanting.set_enchanted_itemstring(itemstack) - mcl_enchanting.set_enchantments(itemstack, mcl_enchanting.generate_random_enchantments_reliable(itemstack, enchantment_level, treasure, no_reduced_bonus_chance, ignore_already_enchanted)) + mcl_enchanting.set_enchantments(itemstack, enchantments) + return itemstack end -function mcl_enchanting.get_randomly_enchanted_book(enchantment_level, treasure, no_reduced_bonus_chance) - return mcl_enchanting.enchant_randomly(ItemStack("mcl_books:book"), enchantment_level, treasure, no_reduced_bonus_chance, true) -end - function mcl_enchanting.enchant_uniform_randomly(stack, exclude, pr) - local enchantment = mcl_enchanting.get_random_enchantment(stack, true, weighted, exclude, pr) + local enchantment = mcl_enchanting.get_random_enchantment(stack, true, false, exclude, pr) if enchantment then - local max_level = mcl_enchanting.enchantments[enchantment].max_level - mcl_enchanting.enchant(stack, enchantment, pr and pr:next(1, max_level) or math.random(max_level)) + mcl_enchanting.enchant(stack, enchantment, mcl_enchanting.random(pr, 1, mcl_enchanting.enchantments[enchantment].max_level)) end return stack end -function mcl_enchanting.get_uniform_randomly_enchanted_book(exclude, pr) - return mcl_enchanting.enchant_uniform_randomly(ItemStack("mcl_books:book"), exclude, pr) -end - function mcl_enchanting.get_random_glyph_row() local glyphs = "" local x = 1.3 diff --git a/mods/ITEMS/mcl_fishing/init.lua b/mods/ITEMS/mcl_fishing/init.lua index ade0be818..788e591dc 100644 --- a/mods/ITEMS/mcl_fishing/init.lua +++ b/mods/ITEMS/mcl_fishing/init.lua @@ -71,7 +71,9 @@ local fish = function(itemstack, player, pointed_thing) { itemstring = "mcl_fishing:salmon_raw", weight = 25 }, { itemstring = "mcl_fishing:clownfish_raw", weight = 2 }, { itemstring = "mcl_fishing:pufferfish_raw", weight = 13 }, - } + }, + stacks_min = 1, + stacks_max = 1, }, pr) elseif r <= junk_value then -- Junk @@ -88,21 +90,29 @@ local fish = function(itemstack, player, pointed_thing) { itemstring = "mcl_mobitems:bone", weight = 10 }, { itemstring = "mcl_dye:black", weight = 1, amount_min = 10, amount_max = 10 }, { itemstring = "mcl_mobitems:string", weight = 10 }, -- TODO: Tripwire Hook - } + }, + stacks_min = 1, + stacks_max = 1, }, pr) else -- Treasure items = mcl_loot.get_loot({ items = { - -- TODO: Enchanted Bow - { itemstring = "mcl_bows:bow", wear_min = 49144, wear_max = 65535 }, -- 75%-100% damage - { itemstack = mcl_enchanting.get_randomly_enchanted_book(30, true, true)}, - -- TODO: Enchanted Fishing Rod - { itemstring = "mcl_fishing:fishing_rod", wear_min = 49144, wear_max = 65535 }, -- 75%-100% damage + { itemstring = "mcl_bows:bow", wear_min = 49144, wear_max = 65535, func = function(stack, pr) + mcl_enchanting.enchant_randomly(stack, 30, true, false, false, pr) + end }, -- 75%-100% damage + { itemstring = "mcl_books:book", func = function(stack, pr) + mcl_enchanting.enchant_randomly(stack, 30, true, true, false, pr) + end }, + { itemstring = "mcl_fishing:fishing_rod", wear_min = 49144, wear_max = 65535, func = function(stack, pr) + mcl_enchanting.enchant_randomly(stack, 30, true, false, false, pr) + end }, -- 75%-100% damage { itemstring = "mcl_mobs:nametag", }, { itemstring = "mcl_mobitems:saddle", }, { itemstring = "mcl_flowers:waterlily", }, - } + }, + stacks_min = 1, + stacks_max = 1, }, pr) end local item diff --git a/mods/MAPGEN/mcl_dungeons/init.lua b/mods/MAPGEN/mcl_dungeons/init.lua index 58e23b12e..e65294313 100644 --- a/mods/MAPGEN/mcl_dungeons/init.lua +++ b/mods/MAPGEN/mcl_dungeons/init.lua @@ -323,6 +323,9 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) { itemstring = "mcl_jukebox:record_4", weight = 15 }, { itemstring = "mobs_mc:iron_horse_armor", weight = 15 }, { itemstring = "mcl_core:apple_gold", weight = 15 }, + { itemstring = "mcl_books:book", weight = 10, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly({"soul_speed"}, pr) + end }, { itemstack = mcl_enchanting.get_uniform_randomly_enchanted_book({"soul_speed"}, pr), weight = 10 }, { itemstring = "mobs_mc:gold_horse_armor", weight = 10 }, { itemstring = "mobs_mc:diamond_horse_armor", weight = 5 }, diff --git a/mods/MAPGEN/mcl_structures/init.lua b/mods/MAPGEN/mcl_structures/init.lua index 533c9cab0..7ca7789be 100644 --- a/mods/MAPGEN/mcl_structures/init.lua +++ b/mods/MAPGEN/mcl_structures/init.lua @@ -454,7 +454,9 @@ local function temple_placement_callback(p1, p2, size, rotation, pr) { itemstring = "mcl_mobitems:bone", weight = 25, amount_min = 4, amount_max=6 }, { itemstring = "mcl_mobitems:rotten_flesh", weight = 25, amount_min = 3, amount_max=7 }, { itemstring = "mcl_mobitems:spider_eye", weight = 25, amount_min = 1, amount_max=3 }, - { itemstack = mcl_enchanting.get_uniform_randomly_enchanted_book({"soul_speed"}, pr), weight = 20, }, + { itemstring = "mcl_books:book", weight = 20, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly({"soul_speed"}, pr) + end }, { itemstring = "mcl_mobitems:saddle", weight = 20, }, { itemstring = "mcl_core:apple_gold", weight = 20, }, { itemstring = "mcl_core:gold_ingot", weight = 15, amount_min = 2, amount_max = 7 }, diff --git a/mods/MAPGEN/tsm_railcorridors/gameconfig.lua b/mods/MAPGEN/tsm_railcorridors/gameconfig.lua index 168ecf535..cbe2c9bed 100644 --- a/mods/MAPGEN/tsm_railcorridors/gameconfig.lua +++ b/mods/MAPGEN/tsm_railcorridors/gameconfig.lua @@ -66,7 +66,9 @@ function tsm_railcorridors.get_treasures(pr) items = { { itemstring = "mcl_mobs:nametag", weight = 30 }, { itemstring = "mcl_core:apple_gold", weight = 20 }, - { itemstack = mcl_enchanting.get_uniform_randomly_enchanted_book({"soul_speed"}, pr), weight = 10 }, + { itemstring = "mcl_books:book", weight = 10, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly({"soul_speed"}, pr) + end }, { itemstring = "", weight = 5}, { itemstring = "mcl_core:pick_iron", weight = 5 }, { itemstring = "mcl_core:apple_gold_enchanted", weight = 1 }, From 0e9a56fa353ed689bd86dd6a853f5adbb11b0c19 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 7 Dec 2021 18:19:41 +0100 Subject: [PATCH 290/296] Add stacks to enchant_uniform_randomly --- mods/MAPGEN/mcl_dungeons/init.lua | 124 +++++++++---------- mods/MAPGEN/mcl_structures/init.lua | 2 +- mods/MAPGEN/tsm_railcorridors/gameconfig.lua | 2 +- 3 files changed, 63 insertions(+), 65 deletions(-) diff --git a/mods/MAPGEN/mcl_dungeons/init.lua b/mods/MAPGEN/mcl_dungeons/init.lua index e65294313..905e26396 100644 --- a/mods/MAPGEN/mcl_dungeons/init.lua +++ b/mods/MAPGEN/mcl_dungeons/init.lua @@ -63,6 +63,67 @@ local surround_vectors = { { x=0, y=0, z=1 }, } +local loottable = +{ + { + stacks_min = 1, + stacks_max = 3, + items = { + { itemstring = "mcl_mobs:nametag", weight = 20 }, + { itemstring = "mcl_mobitems:saddle", weight = 20 }, + { itemstring = "mcl_jukebox:record_1", weight = 15 }, + { itemstring = "mcl_jukebox:record_4", weight = 15 }, + { itemstring = "mobs_mc:iron_horse_armor", weight = 15 }, + { itemstring = "mcl_core:apple_gold", weight = 15 }, + { itemstring = "mcl_books:book", weight = 10, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) + end }, + { itemstring = "mobs_mc:gold_horse_armor", weight = 10 }, + { itemstring = "mobs_mc:diamond_horse_armor", weight = 5 }, + { itemstring = "mcl_core:apple_gold_enchanted", weight = 2 }, + } + }, + { + stacks_min = 1, + stacks_max = 4, + items = { + { itemstring = "mcl_farming:wheat_item", weight = 20, amount_min = 1, amount_max = 4 }, + { itemstring = "mcl_farming:bread", weight = 20 }, + { itemstring = "mcl_core:coal_lump", weight = 15, amount_min = 1, amount_max = 4 }, + { itemstring = "mesecons:redstone", weight = 15, amount_min = 1, amount_max = 4 }, + { itemstring = "mcl_farming:beetroot_seeds", weight = 10, amount_min = 2, amount_max = 4 }, + { itemstring = "mcl_farming:melon_seeds", weight = 10, amount_min = 2, amount_max = 4 }, + { itemstring = "mcl_farming:pumpkin_seeds", weight = 10, amount_min = 2, amount_max = 4 }, + { itemstring = "mcl_core:iron_ingot", weight = 10, amount_min = 1, amount_max = 4 }, + { itemstring = "mcl_buckets:bucket_empty", weight = 10 }, + { itemstring = "mcl_core:gold_ingot", weight = 5, amount_min = 1, amount_max = 4 }, + }, + }, + { + stacks_min = 3, + stacks_max = 3, + items = { + { itemstring = "mcl_mobitems:bone", weight = 10, amount_min = 1, amount_max = 8 }, + { itemstring = "mcl_mobitems:gunpowder", weight = 10, amount_min = 1, amount_max = 8 }, + { itemstring = "mcl_mobitems:rotten_flesh", weight = 10, amount_min = 1, amount_max = 8 }, + { itemstring = "mcl_mobitems:string", weight = 10, amount_min = 1, amount_max = 8 }, + }, + } +} + +-- Bonus loot for v6 mapgen: Otherwise unobtainable saplings. +if mg_name == "v6" then + table.insert(loottable, { + stacks_min = 1, + stacks_max = 3, + items = { + { itemstring = "mcl_core:birchsapling", weight = 1, amount_min = 1, amount_max = 2 }, + { itemstring = "mcl_core:acaciasapling", weight = 1, amount_min = 1, amount_max = 2 }, + { itemstring = "", weight = 6 }, + }, + }) +end + local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) if calls_remaining >= 1 then return end @@ -310,69 +371,6 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) set_node(pos, {name="mcl_chests:chest", param2=facedir}) local meta = get_meta(pos) - - local loottable = - { - { - stacks_min = 1, - stacks_max = 3, - items = { - { itemstring = "mcl_mobs:nametag", weight = 20 }, - { itemstring = "mcl_mobitems:saddle", weight = 20 }, - { itemstring = "mcl_jukebox:record_1", weight = 15 }, - { itemstring = "mcl_jukebox:record_4", weight = 15 }, - { itemstring = "mobs_mc:iron_horse_armor", weight = 15 }, - { itemstring = "mcl_core:apple_gold", weight = 15 }, - { itemstring = "mcl_books:book", weight = 10, func = function(stack, pr) - mcl_enchanting.enchant_uniform_randomly({"soul_speed"}, pr) - end }, - { itemstack = mcl_enchanting.get_uniform_randomly_enchanted_book({"soul_speed"}, pr), weight = 10 }, - { itemstring = "mobs_mc:gold_horse_armor", weight = 10 }, - { itemstring = "mobs_mc:diamond_horse_armor", weight = 5 }, - { itemstring = "mcl_core:apple_gold_enchanted", weight = 2 }, - } - }, - { - stacks_min = 1, - stacks_max = 4, - items = { - { itemstring = "mcl_farming:wheat_item", weight = 20, amount_min = 1, amount_max = 4 }, - { itemstring = "mcl_farming:bread", weight = 20 }, - { itemstring = "mcl_core:coal_lump", weight = 15, amount_min = 1, amount_max = 4 }, - { itemstring = "mesecons:redstone", weight = 15, amount_min = 1, amount_max = 4 }, - { itemstring = "mcl_farming:beetroot_seeds", weight = 10, amount_min = 2, amount_max = 4 }, - { itemstring = "mcl_farming:melon_seeds", weight = 10, amount_min = 2, amount_max = 4 }, - { itemstring = "mcl_farming:pumpkin_seeds", weight = 10, amount_min = 2, amount_max = 4 }, - { itemstring = "mcl_core:iron_ingot", weight = 10, amount_min = 1, amount_max = 4 }, - { itemstring = "mcl_buckets:bucket_empty", weight = 10 }, - { itemstring = "mcl_core:gold_ingot", weight = 5, amount_min = 1, amount_max = 4 }, - }, - }, - { - stacks_min = 3, - stacks_max = 3, - items = { - { itemstring = "mcl_mobitems:bone", weight = 10, amount_min = 1, amount_max = 8 }, - { itemstring = "mcl_mobitems:gunpowder", weight = 10, amount_min = 1, amount_max = 8 }, - { itemstring = "mcl_mobitems:rotten_flesh", weight = 10, amount_min = 1, amount_max = 8 }, - { itemstring = "mcl_mobitems:string", weight = 10, amount_min = 1, amount_max = 8 }, - }, - } - } - - -- Bonus loot for v6 mapgen: Otherwise unobtainable saplings. - if mg_name == "v6" then - table_insert(loottable, { - stacks_min = 1, - stacks_max = 3, - items = { - { itemstring = "mcl_core:birchsapling", weight = 1, amount_min = 1, amount_max = 2 }, - { itemstring = "mcl_core:acaciasapling", weight = 1, amount_min = 1, amount_max = 2 }, - { itemstring = "", weight = 6 }, - }, - }) - end - minetest.log("action", "[mcl_dungeons] Filling chest " .. tostring(c) .. " at " .. minetest.pos_to_string(pos)) mcl_loot.fill_inventory(meta:get_inventory(), "main", mcl_loot.get_multi_loot(loottable, pr), pr) end diff --git a/mods/MAPGEN/mcl_structures/init.lua b/mods/MAPGEN/mcl_structures/init.lua index 7ca7789be..be1be0f67 100644 --- a/mods/MAPGEN/mcl_structures/init.lua +++ b/mods/MAPGEN/mcl_structures/init.lua @@ -455,7 +455,7 @@ local function temple_placement_callback(p1, p2, size, rotation, pr) { itemstring = "mcl_mobitems:rotten_flesh", weight = 25, amount_min = 3, amount_max=7 }, { itemstring = "mcl_mobitems:spider_eye", weight = 25, amount_min = 1, amount_max=3 }, { itemstring = "mcl_books:book", weight = 20, func = function(stack, pr) - mcl_enchanting.enchant_uniform_randomly({"soul_speed"}, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, { itemstring = "mcl_mobitems:saddle", weight = 20, }, { itemstring = "mcl_core:apple_gold", weight = 20, }, diff --git a/mods/MAPGEN/tsm_railcorridors/gameconfig.lua b/mods/MAPGEN/tsm_railcorridors/gameconfig.lua index cbe2c9bed..de4b18119 100644 --- a/mods/MAPGEN/tsm_railcorridors/gameconfig.lua +++ b/mods/MAPGEN/tsm_railcorridors/gameconfig.lua @@ -67,7 +67,7 @@ function tsm_railcorridors.get_treasures(pr) { itemstring = "mcl_mobs:nametag", weight = 30 }, { itemstring = "mcl_core:apple_gold", weight = 20 }, { itemstring = "mcl_books:book", weight = 10, func = function(stack, pr) - mcl_enchanting.enchant_uniform_randomly({"soul_speed"}, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, { itemstring = "", weight = 5}, { itemstring = "mcl_core:pick_iron", weight = 5 }, From b945975427e3bd0c7436efea4d8d2835cc98bd4e Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Thu, 9 Dec 2021 18:11:05 +0100 Subject: [PATCH 291/296] Slime splitting: nil check child to prevent crash (that happened on oysterity-mcl2) --- mods/ENTITIES/mobs_mc/slime+magma_cube.lua | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/slime+magma_cube.lua b/mods/ENTITIES/mobs_mc/slime+magma_cube.lua index 48aacfcce..9236b255e 100644 --- a/mods/ENTITIES/mobs_mc/slime+magma_cube.lua +++ b/mods/ENTITIES/mobs_mc/slime+magma_cube.lua @@ -31,12 +31,14 @@ local spawn_children_on_die = function(child_mob, children_count, spawn_distance speed_penalty = 0.5 end local mob = minetest.add_entity(newpos, child_mob) - if (not mother_stuck) then - mob:set_velocity(vector.multiply(dir, eject_speed * speed_penalty)) + if mob then + if (not mother_stuck) then + mob:set_velocity(vector.multiply(dir, eject_speed * speed_penalty)) + end + mob:set_yaw(angle - math.pi/2) + table.insert(children, mob) + angle = angle + (math.pi*2)/children_count end - mob:set_yaw(angle - math.pi/2) - table.insert(children, mob) - angle = angle + (math.pi*2)/children_count end -- If mother was murdered, children attack the killer after 1 second if self.state == "attack" then From e4feb233e077ee4878c4bf85a88d24bc709c20b2 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Thu, 9 Dec 2021 18:20:24 +0100 Subject: [PATCH 292/296] Fix hopper dupe --- mods/ITEMS/mcl_hoppers/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_hoppers/init.lua b/mods/ITEMS/mcl_hoppers/init.lua index f9ba1a8c8..36a21ad95 100644 --- a/mods/ITEMS/mcl_hoppers/init.lua +++ b/mods/ITEMS/mcl_hoppers/init.lua @@ -350,7 +350,7 @@ minetest.register_abm({ local inv = meta:get_inventory() for _,object in pairs(minetest.get_objects_inside_radius(pos, 2)) do - if not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" then + if not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" and not object:get_luaentity()._removed then if inv and inv:room_for_item("main", ItemStack(object:get_luaentity().itemstring)) then -- Item must get sucked in when the item just TOUCHES the block above the hopper -- This is the reason for the Y calculation. From 0c8e5dc7a40985bb887c33bee955742cafa68e3e Mon Sep 17 00:00:00 2001 From: kay27 Date: Thu, 9 Dec 2021 02:55:57 +0400 Subject: [PATCH 293/296] Disable Nether portal node rotation by screwdriver --- mods/ITEMS/mcl_portals/portal_nether.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mods/ITEMS/mcl_portals/portal_nether.lua b/mods/ITEMS/mcl_portals/portal_nether.lua index 3f15a134d..46025619c 100644 --- a/mods/ITEMS/mcl_portals/portal_nether.lua +++ b/mods/ITEMS/mcl_portals/portal_nether.lua @@ -237,6 +237,11 @@ local function destroy_nether_portal(pos, node) check_remove({x = pos.x, y = pos.y + 1, z = pos.z}) end +local on_rotate +if minetest.get_modpath("screwdriver") then + on_rotate = screwdriver.disallow +end + minetest.register_node(PORTAL, { description = S("Nether Portal"), _doc_items_longdesc = S("A Nether portal teleports creatures and objects to the hot and dangerous Nether dimension (and back!). Enter at your own risk!"), @@ -286,6 +291,7 @@ minetest.register_node(PORTAL, { groups = { creative_breakable = 1, portal = 1, not_in_creative_inventory = 1 }, sounds = mcl_sounds.node_sound_glass_defaults(), after_destruct = destroy_nether_portal, + on_rotate = on_rotate, _mcl_hardness = -1, _mcl_blast_resistance = 0, From 5a4abcbcb7d7aef5d61dbc54c9a783cd9b494ce7 Mon Sep 17 00:00:00 2001 From: chmodsayshello Date: Fri, 10 Dec 2021 13:59:31 +0000 Subject: [PATCH 294/296] fixed daylightsensor's register_abms By changing the check if a normal/inverted daylightsensor should update by turning on and off, I made them workling again --- mods/ITEMS/REDSTONE/mesecons_solarpanel/init.lua | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/mods/ITEMS/REDSTONE/mesecons_solarpanel/init.lua b/mods/ITEMS/REDSTONE/mesecons_solarpanel/init.lua index ed0e4c608..1c89293cc 100644 --- a/mods/ITEMS/REDSTONE/mesecons_solarpanel/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_solarpanel/init.lua @@ -96,8 +96,9 @@ minetest.register_abm({ chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) local light = minetest.get_node_light(pos, nil) + local time = minetest.get_us_time() - if light >= 12 and minetest.get_timeofday() > 0.2 and minetest.get_timeofday() < 0.8 then + if light >= 14 and time > 6000 then minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_on", param2=node.param2}) mesecon.receptor_on(pos, mesecon.rules.pplate) end @@ -111,8 +112,9 @@ minetest.register_abm({ chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) local light = minetest.get_node_light(pos, nil) + local time = minetest.get_us_time() - if light < 12 then + if light < 14 and time > 18000 then minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_off", param2=node.param2}) mesecon.receptor_off(pos, mesecon.rules.pplate) end @@ -203,8 +205,9 @@ minetest.register_abm({ chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) local light = minetest.get_node_light(pos, nil) + local time = minetest.get_us_time() - if light < 12 then + if light < 14 and time > 18000 then minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_inverted_on", param2=node.param2}) mesecon.receptor_on(pos, mesecon.rules.pplate) end @@ -218,8 +221,9 @@ minetest.register_abm({ chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) local light = minetest.get_node_light(pos, nil) + local time = minetest.get_us_time() - if light >= 12 and minetest.get_timeofday() > 0.8 and minetest.get_timeofday() < 0.2 then + if light >= 14 and time > 6000 then minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_inverted_off", param2=node.param2}) mesecon.receptor_off(pos, mesecon.rules.pplate) end From e2360204a7a7b754b0ccdf5336c6a230cea491eb Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sun, 12 Dec 2021 15:55:52 +0100 Subject: [PATCH 295/296] Revert "fixed daylightsensor's register_abms" This reverts commit 5a4abcbcb7d7aef5d61dbc54c9a783cd9b494ce7. --- mods/ITEMS/REDSTONE/mesecons_solarpanel/init.lua | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/mods/ITEMS/REDSTONE/mesecons_solarpanel/init.lua b/mods/ITEMS/REDSTONE/mesecons_solarpanel/init.lua index 1c89293cc..ed0e4c608 100644 --- a/mods/ITEMS/REDSTONE/mesecons_solarpanel/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_solarpanel/init.lua @@ -96,9 +96,8 @@ minetest.register_abm({ chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) local light = minetest.get_node_light(pos, nil) - local time = minetest.get_us_time() - if light >= 14 and time > 6000 then + if light >= 12 and minetest.get_timeofday() > 0.2 and minetest.get_timeofday() < 0.8 then minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_on", param2=node.param2}) mesecon.receptor_on(pos, mesecon.rules.pplate) end @@ -112,9 +111,8 @@ minetest.register_abm({ chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) local light = minetest.get_node_light(pos, nil) - local time = minetest.get_us_time() - if light < 14 and time > 18000 then + if light < 12 then minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_off", param2=node.param2}) mesecon.receptor_off(pos, mesecon.rules.pplate) end @@ -205,9 +203,8 @@ minetest.register_abm({ chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) local light = minetest.get_node_light(pos, nil) - local time = minetest.get_us_time() - if light < 14 and time > 18000 then + if light < 12 then minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_inverted_on", param2=node.param2}) mesecon.receptor_on(pos, mesecon.rules.pplate) end @@ -221,9 +218,8 @@ minetest.register_abm({ chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) local light = minetest.get_node_light(pos, nil) - local time = minetest.get_us_time() - if light >= 14 and time > 6000 then + if light >= 12 and minetest.get_timeofday() > 0.8 and minetest.get_timeofday() < 0.2 then minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_inverted_off", param2=node.param2}) mesecon.receptor_off(pos, mesecon.rules.pplate) end From bfd1fd69d18676facec9e457fc75f6e2fa185420 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sun, 19 Dec 2021 18:59:09 +0100 Subject: [PATCH 296/296] Fix potential crash when falling onto unknown node --- mods/PLAYER/mcl_playerplus/init.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index f86d5e26a..50fec2bd6 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -550,7 +550,8 @@ mcl_damage.register_modifier(function(obj, damage, reason) node = minetest.get_node(pos) end if node then - if minetest.registered_nodes[node.name].walkable then + local def = minetest.registered_nodes[node.name] + if not def or def.walkable then return end if minetest.get_item_group(node.name, "water") ~= 0 then