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!ia0vp^oFL4>1|%O$WD@{VY)RhkE7sn8Z%gG4~v=dyO{rUg@zkN*8 lL_xjdE1|%O$WD@{VY)RhkE rgruaTp-7@BgTe~DWM4f;{PWz literal 0 HcmV?d00001 diff --git a/mods/CORE/mcl_particles/textures/mcl_particles_totem3.png b/mods/CORE/mcl_particles/textures/mcl_particles_totem3.png new file mode 100644 index 0000000000000000000000000000000000000000..55d6f49d3543ca553e475954f6012306ea7ba0bf GIT binary patch literal 155 zcmeAS@N?(olHy`uVBq!ia0vp^oFL4>1|%O$WD@{VY)RhkEp00i_>zopr0FK-$I{*Lx 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!ia0vp^oFL4>1|%O$WD@{VY)RhkEpe+aVfI>!|E{-7*my;6|m<*JP|NZ~}UtaIv zi4z?QIU*T%Il0AfO%OE_e5|H6NyhJjZ%d842m^yIw+NSW@uBHJ-3*?telF{r5}E+c C1}gjj 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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

u 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 JPDHLkV1ldgMFju= 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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 F@&5;Q6eR!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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ྶ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 delta 111997 zcmeFad3+RA`Y)X7t_~GQFh~LcIuJGungEe4NJ0`oZ4d+mBq%5-YLG3ghBZM@dj>^f zgad*K0umP#L~UHyMx1F!9l>!Beiewc zIcrs&-u%xi*MB*1Wtu-L_1!D#D--C?;v}J`Hz8rfO*c<7CxV`W>M4#duz2K*+8y(1 zQg>{aBA+)C9e-x#{f^_5?O1uzN^91vS!Gdi@kfPy`@VO<1s87M3-4Mr4-{nhr%o^b z9q_KNT(YDd(*=tbeTiw4CQVXzRuwj~YL*x7s#)GQ(;hrzNM+5ir5O%FF1@tRu$@&U zj#aa=WP8oB;w%RU&Rei(@s~Bj?#^CCi+= zyh{QZ85zxLR$lf)&E3T*c8{JtN7W2N@-10FZhJvm&Ctqp*H|E{$bf2Hw76`3t^XT)CuX=;OJ}>0VG~ksZxtN_Jsk;iBm?X4E66=+9ZW z9z$oG*MGoe(|~jRf`yBbfVr+{pg#5!onG#?3}(uMe_;@ z3a94h_r9T9_wGYGcj;0D)t=j?O_o1By;=hAsmq&dl$9=}p~x^td`FH@8p6ju&(q zJ!Z`BZ@%@`dY}b$+Bd5LyQ{$MmEiU$rK(E87<;WyF>uoKIdgCS5*3@b0F+xK&f3_K z6A(JHDl&oSu=i=(+C_{e+yVLW7aGX)unx`sA!RsCQp7Ds$oE4&BkBt1hcZE z;O05q6_Fx8GiWGgczh!}L)-Iw|+Fr4{q%e{#*}(KWf9I~SwG zC&9v;h{W3~zC>wfNTk--0-e~X976ckva)*ULTaXu?wxlwDe-0TQrCf<`Hj%85V>zG zgxaQ-vkBTDbv8{wQval~Nt5cQmzUQsu9+~RsCPWipUcO~t3fNz%gAWathl6PGPIai ztM0g?X6VkmsMeYUGW#?_f1@vby>;JNjcZGcQ+779SiHV*rUAp#%;Cl%= zsM9sYPo~$5+IexD3cVW5oIRUVfGV%KVf4TO=MwWv%2Ab$9Xob`ZmbG?kdcy;liO!> z>6rT$EL>DqRg?Ejc0`5cnc#tLNmHjytDgd&MKvWOn%0aTUQql?1f2^59qecjz7SlH znw-(1MYEEUev_w{&-hJE*B39UxoYQmaq_z~#~PnAx1xUT?epjZno@so!-$gq6-|C> zla-Z)Za5Fd-tjG3w!FJ%&tALXdrg=9EozGQwyx>B6`JqP3uP!kXIy+C4nC;Jd{AQk zf<@5%L3a#Iap9s$REnA<))O?lf^)gx=gQ|+%=_5q^Lf!lsW>S>{&@{1m(g!*XO0fg^B_Hg#uxUf5 z)${C~*3a1k9sCxsWf?iSXRltbq8+Z2#T0RLC8~eRt&{3UjJT%$w#ifLC*3wB=7VLE zr%a>HIa(;v@dr#=9QFByCW;#}&hQ5gv{18P`-PYMceY=C#T9cfxSDGnHf!Fzs<@=z zM@yD2t6#EoY0bs^Gh?c9%+6Mo^X4t6ziHwv^}~mcsvkLOH2GlW>^b$bX3wpkb9)8$ z=Qw>4Th-=srBQxBpZsTESx;Y8PvwGoyC75A#g5toU8oo zZW@Zc%rv=~`azUJ(9GnZxpmTQ6wTpDgRB{1>=V-H3|d$UA!u4u~@$pr+G+I1xr_?As)uD*vmfigus6 z=p5+}rDLx9+sIMZ?7?*axi8Lz?8YXMMvg5Xx-M|zs16u;7?J2gO!1?hiHbgQUtIKI zXM2v0Hp+cCN5X+}<}4m4agv6UIBYlA<-1lvyF*uvJA2o4ZuhwiqM|9f?7Fene>G~< z=syk|H28`9{7aWycwzQ6et%|e`ft>zvkuS0>(k z%XVnA6=#V$9iwo_;NC!|Qn=MH>9)!BH^aPPJVeg*=dg&ZJBPc_eNms1h=0$)Z0y(@ z{yplN(mxHla>!E!1$}>g(ZxBpv}@PCB)wTPKP*9gu&aR+W_Z0js{l89WZ& zx6hkbzw}PDD%P_2xW>Hno&AV0&FC?Iy5fpKuk^mOU=?gvO=;J@eF@y&;J%}(WOEVh z@O}x}{e&9gs)>C3U-|jxBgh@4HuNonU87b$3;#gxeZ{tId*HrHo1C1S%b@;;!lJVD z(ms7A6c+Zq4WJh;aBS-!En$e~A!sou4VWUfb zwvK!C${z=krql!<+yJ*-7TT~k{!GoVQCDNk`_I<%!Tx0!c9t%Mz67*gzZt3UhDR#6 z25!_aWvWubT>TW>qFGXNaPn-CQDqMvjCXxTmnI_$`DJHk_XaIy3%{ype#0DKd>rnD zAP?BmBR!WXkHHS?U2cb}Z36UFLch#`&d!0s=y#w`G10@lrQv|MN9cn#G}$81AwL<$ zFwpR-CBow#;c<@*;SaZiMs;=Ic9v?mM(FQR`fLYgQA7{gtryyr>cuPvHW&7hb;l-e zty%uyL*T8IQPzz}i)eRj>XS8huiprW2mI(ETv$YZZocJKHFUeE@j#k79)aj5v~%ad zS%dK&+U8`q!_XBr{YHyzuL#*GxHwUC#qVYR|0qAOq2`{#dbl@OR4Eop&Z&i=#u+eh6Q<#rFI3b%|GL%Pwr_i^qSjbG>pp8yb>782 zg7<$l6A|Z1;qE8>g&(+T2I2zS^Pj9WCwx}Zl!|wMOQffgU!PTLnj~6H%{^N@In~9< zqXG{HSnhgGH6MH^w!GrNrB5Q)_%u*)_z5i6zly-TO|_vNiPlMPLs7V+C&6sI&q~j% z>e7>V1P3Khsx)M~`M9BV<$%(^4XQwPyWTD$Nd6wJa;?>z?WQL^T#)Jfa zf+=rg`F(Y(dWiYCfpw41BCwa7QgZ?!TBMMSOV*O3h}0~4z|$&IixlFt zNv04aQZ@h;Zms2tJF5oj(Krngt+i5w1P>M1M1?8j^Z0U{~pb&&olx|=dDvOXHgAK24Y^CK0 zLMZ}=m_lW#cezgTR)P#cC`ItfKaw+5mO7gqGQ6?XG*=-?lCg?~s4(@Zkeml<2|_8f z6(}dAU{@akLu@qNG#PC-O;`3>HKdW*@qnFHAdSc`br6uoq;;SX8{=8mUlUTToSd&x zs0G!2zL%~3a4fZ~Qc1&ApHRmWSO%&2xZdevw%6H?Ii3m)gow;{saBhG#kCeqf_ET3 zw~6&Z+DVq++_aZk2c>5CY^#5YbDX=RFs4}4-sjYV9>#JK3;f6dbXAU|0pv-N`TTtA zU6=F8+o*SNFlElc6U;gAmCHGsIG?z~S74JZC3(Iyo3z}LX1!~F4O$}Yh!p2*rp-R- z(gu{aS4uYcR-JRw4FAHq(3Cf`Qhnrlvt+K_w4-)yF_D8_m*&Tn4Bl^Q4mPt|dm3Gx4XyV(Dj zvX|=6LQt&s8`o0j_5;{$-r?(&gqD&HCa;B6V1Ealq?yqI2D8O5m}QoQptA&8O^=-4 zjQb!=kv;gOCG_HS-BiO@yBr2av!kVTrH{bIYGt+RsGYI$!HyOGMvs7w88S{C$}MSS z-G@wbG98htX@$t86d_$q))qTC1v`6OFA&b0Cn92-oN zOb~zfE7p0{MJc&iZ=EJfNlo~Nh7I&04j+(ar?Dp}<>5ORTugm<@J>i^#As!z(kwd( z735Ke9E3w4JBVpf!yf7&Wv?2dfwe%dylZ7N3*U`0PPDdadekisP?f8uNez9G;kM_vebE5)}~A?QV1Ch+=Y;N!FQ-?W`%u_pzO|n3^4{Va(#M8&_FbW=wl) zmXGW)8~a4S4uKCn3V}i22>W`zHQPqzOx^_moy$(h#?;KPlKeJ(BWR~S07cbMg~=&l z!BUDkL}Nd>09E)KhSG!!p#?3$78I69)^wM|4W;Hpn?`BL%hXH@S&I5WWy;*YrE2^-UUD7$#^ z&bugnNf!{m48=PlR?{`9ES^&CDgsNn&VzSgozLrvV0h zZF@jZ7_8+!M8&IX2olv32CCQ+Vr4$*0X<<@x}SJbg{rh58jsx^NqxMhb&r3^*&7rg z4LKdfnMu8%m#dX#6fLF-GNd_oF~LgaM=5u6{58_ek+OoGBWO$oOWzAqt-Y2%oz!d;&5o zYU)VLQ;JRQLURyCXCGbXC=Xz4&_sbjF>OuxXzgoL56-~p#m2rM_imJ1`!F|kP3xqo zQ_5kxm}@M!5Nly=k=4OQ8gA}apbjTGLvQ0Y_sCEztW^b#rm!&7kZ>?>uygH^{rEWo zFpea!h;<@XW?+f6yk~6%dptTaaNt*{N+UBc0EwmfzO}X7zvk?uY%xV3%Hwf1yp)3= zT22*YNOjXBAL`yPy8x!9`fKPF>02aBP*r1H0Z^Gg)M08S)Wgt8-#APzvu68(s2dNn zK^B~iDG#&sEh?;0HICGUKm|sYVakz8-w6BS6%eVo4P){G)_qAqP(HjCakz)#8}@sc zw{a)y6gEr6<>ZQci=zY1lsqRS&e5TS;rB z&U=PBUTGDjq}1NYx`$c!QtLWjEzT}O5ZK)<+B*p2@yA&0n(V!a4{&MWEe*^ZQ zR_5fj)+t|LEv}YMTxYFIr|ly!P*Z0*&6;7#xb>B>me0oq?VkWsj#^4d;>@dTAKhbCGJ2c!Fd`1hhy{+)j%w`K=Yc)lDLciFS~df5s| z*K=A|4XIgsv(+cXd4QKh;Z^82aCIMZ{C-brN9XA}V(p}dsD2YcWb|Lq06sMQ7Ax6G zmhC#HD}+L5(ydk>Ye=BOpJ~atYte6s9NTpn(5uG3f$!wiTOe$}qU=rQQ>q(xDk^+8 zRc9FtU;MRX62wIrF4aQS1x|rw)2i*`+pLRkRvsZBMn2AZ2o2!vT*NY*$2hOLsMq3k zDSPVdx&(iPy3Cjiy6{)hB|EDr$7mnRN8b%8qfCB@GT6GZrRrXR@8p=$6}(rqfO|1~ z1}*w8u$&w-)tc<%uM?(OW9r(THrsqnlrO#1Np1JwbiSU4wH|`Eeg~1F^_GIR9gdj1X8&-&u+`9 z*p#5w z`(4l!?115+j(a7g>=XcMTf9M7PvI-r&+R7tf? zRQMUBcOmJC8kj1frKV(+)ihI?oB_TE!82B2tE7s9$so**R&XUz$}>eQF-z)`rX;WA zYXMAoB1_*6t+r|!Y3gGn{6t zTB|ro%P%u+(>%>vDbvBYc?yvi6s;cyQzl&L$u)x?w8mP$HWOxBC819rv@WsQ=U>UQ zFip`wn)68ced>jg>#YeKyNCW^^)O$ox2{cE4rXS5jT1eb%cdWH?XA1TCh|bVD`RHR zgtwI$obByy%4b_+Q-W=ww$PMom(Q*ZjRmgAYJ&NGlhr6~_DPx$4v{|5sen9pM+KX$;r3@;dDnjk zPW@9o#l_~}A}b^Hq}`(kK6}v$NIRNgf3Y$ut%RzM_`y<40|Qc@gOpH^Zh=n`mf>~y zyUkqE)tX`ddp-fii=5A#9!y_j#g z?896%1k339^ghp^GcNf4y<&AnV8D5g1BRS+20o#xJJ9Yz9!P%|nAq=h@jf*1OlL%2 zedpm3&)Ny)#UJ^OkTc4C&eyIt+!%~_L#%hbF+jXQVM6=#3!k)xr8vcdXv@+KpUX_^ zr>u)ofAz(@qH7-=hZDSn8-DfZB^W0yD$CI`Rkc`{kWjGg-H}K3yp&i*p7E}HJr}+g z{Ta&mdP2hCzckrjx3NWudS>(f);lL=Ke3apuY7&m3qX5h z5+(^|*QCV77$^OjVg%`>zdYM?f5H5g=4A*GpYwz3m9d?qWk$RrUU0n<5U-%OxbyKp zV+~I(Im0Q}?~FKw^aZCp%T8HC;lfVID#-OrJJR=q1aZo~*K^@}Q4*A?Q^p=^vOnjh zdBy6K`RiMEYt})WvhVe6M}RhQ8ar`l=;fW!{D20WUA!;S_7WmaDM^pMws+k2ru%QV z=4!A+n$DDq&Txyk!F9`EaSOVO-SWz_;FkVpcgv*G?nQZry6=VlWb4Fz%erx&vU&A; zPbZu{{509U^1Y`&>UHtUzpJmLU`ePu+!?+XVHsYp`eEDloD~25!xy~o`XyoR&Szfz z>SYd=y2DQ+E#Uhg{`{|B-WkI$qoB)|KTa>ce9BKkAL&zynnzvSHzaZU4y$=ii_*(Yl?Fla}P7a zKIJy0vU|_yZp90(S5Aso&|B=4(=S>B&Gskk1}V-J;u^Y09WV4Ut<5VhS;?u_yuGOC ziCP~ukf&;WTRD7oKk(tUytj{%e}tB3 z+h4H?ea>ZW{8X$s!%5;4*GZ?uN$5Ow()!&HI^lr$hsxDI=bK@Btb)pqevMIqoeW3I zKX0ykYVZBa_H2G*E_oxN>hQKrZ_M4h2g=A5&py-V-Y=$<%zB@_f%H2L%VjmUyPRlC0!}q-}Dm_HY#Kj*McmI77deiKjl(^Jjq%@6`78gHo-D|~vxTvpm zy5HgRU^FlX?>oZ@Vzldo)8Yhlj%m9ewp2%*Vg64qSXWm@$G{Yc0jPJfx--N8#KT^w zQ#S_Y#l=80{cS*xSd0VoLJrWw_q~f;`r_hc`Tr`Ovp-W}D5{M#ja(@%-n{N;@jDs4 z(DIq~w{8NRKd8)SVZ^$=Crs4f2e>^uand*bFH zJ2v)s`ZnkZkQU}4+i(tpa}UgyL3uPkXaV~$&J*H$h(G*RdI-K!yw6S;Uvz_4dx#%h z^J}ZmFkj4d&9}vTbPJomFbw9GiuqJbu@8go#pfNk`lS&kD~sOzaCO05zrXWkb8HZ7 zn2kMDS@i5j&2}H|xKUVH-aP>**IrpvjwC@8M zGfSRZ&I3z4ed3{Jg){zGS>(I=B=wx}{Nnt=Z6U@d2QR#2-{voqN?y2LeNylGB(Uua zpNJ1!pE%+Z^cDNW|0a$l*Pam**B`Vxo6p{~I#fQq`n%l;T}yFS1^%jbCX`1esJmBx zS9n+R#YG8aAJ7D~t9fVddpEV*UnCRM{_o5$TJgo;zWe@s;zgu>?YV({4<4AicTS&P z)HSv|np)WA;ck1b`f$Nsyq*v>c*YDJFbgYc7IpEiu1^%@P3yX^>{sV=%Q)@2q4eo9 z+#qJVZb%k4pnKR2ue^=3)3IlB!_}3Kf|Uv7qkEBt3FEsZ1R@^T4&J#FJ&?s7xWK$q zgdP|m9{Boq^NQ}+P_SpiKfWqN`jcaa?dd;d?%sRE1OBTXE6iPd<(@Xq{Qu4aQ~&VH z-u*|q?3>IUfT`%^?$A*F59=zNRrHHYMa5*-1*zf!bPe{3elzZm*3gvjxHDWpy~BUA zN-36A%7sy@lxX@hS1HunxT}=twMTpq^v#IAdfjJNKYQcICyVK6xDynE*?Oad3Ye;Dpi;ib8!7vX2?lc!&K}m1c^x`!KF6P!0nWg$W>hv8Q*y$kX zq#F-csRLziz>%0b^*Xx4`nz?fclwkBW1URuM%xi)-`_1CZ&A$n%-U)oO2^r>69*e1 z_gVMgZpxMBsef8)?H6H_$iSAyGu6fZP}(Qf1dshm1Ky9|tqtadWg*~YTQ=>>(T2*? zpTmaAy`X2^D%_NU8tQL`txU|oFv$1OZ7M4CId#vol1mD5g2|?O6-*VErE|b23I(o@@jx{F|llhG` zB2$YLQYH}QaxX%(NFiZ?5UKeQAzGx6Y49Xput71VW@{_}`N*uP*kHJKLiB^s>Th*D*(8V`hAw)Zdhk z^&}HkuPN3M*2Kf4d*WT!<60fp(0*qU+QTO&EX zsI83s!5W*cQ8@{47!DkrZ~b6RHfuKeQq93Ro>I2{h+c&VQ8Y1!e~62D?X-0hK5*-p z?T`8#Q`{Wh#cq&^8lLmr3rn0lIL18a<-=#Hqf4i2rg9uQ=Ho{E7YNp zXO!2b-Dx6uwlN5(j#8&E8s8@LYO3cNuRJEZ-0oqnP6H8td(zXay0}?xMG-&bA1L6o zv=68G-8psSo@?NCym1O`zl~XWwOx>|bozjQDLp;cq#eBFa8J4?Ig|3>Z@nJS2WnBC z8Fv%BZ=gjA$(KiXnAPX$0MR0a)T*}hsO|oCzE+u9q>v-6_&G8nHRGCjT8+{og*bkO zD5=ImLgH@N%e34#IuxgL!Azzje&#J;ovB3%3AbPfk(!O|K|w82$dL?&5UD9_jtWYV zLLA|uq!9(%(I|tv=~+;yIHjuZq>yZRUWrJ}y*C3yixg5PPfil4$;p{gSokkh)Gxq{(9~IGSAVUCUA8ed$a!||00K`2GI7gMM#mBAH!0^jrygi=(9Z&a2> zA5*}a9%(s(P>RwXEW?#04S^%18Yu*!6xl7ALS<=dV+wjJMi5GoAu?5##x_%s<#AdC zB(Jixxl&LXddDS>;)wJiDoewfy?X-R)e(ehhLvTAg!^)%r5TXF*abbakp__9(>#R&IQ%v{?#t>~NvkPLh zOfjSa)*kXR6ViO^wwC94paw}bszKyp+P-A3t1h+;T(nKsZl2fej7_{UYHzZ-dy*&{ z%I)rX#cQLLX2xCib>`SuPgN+K?-_3ws@K$uj(AbMOT7RnqTbYgk^7UI3&D%4>4`Hs2l-MJeTJ9;~rj^CqA4|1NkgdUnlrc0U96K6CXY1#DS3($0u zNTwr&0n;->GY5MrVRPjy_8+VCboKE>n&0RXlVf^75Tk9J`{`9f!Q?g4W+V;VBTCnx zSTb2kRApxcUZFNq^=EGj%a8eJv+olQNEiBXIGHVF$|G3K80Iyk(DsK8jR4~^^@0Ke zs0J_(BLiwT213Izsn>YmDP+=--it(jqyw5|sG`kb$3z5N?-@GLu@=8%F=iu`O=Q8{T4P+b^W zn+QTFc8N<>mewZApjoFNl)~xEGE|mQund}e2|_8dFJKClrCL!n^88K^N|A9PQ>ZMh zaPoi|j`LJOC`C{_p|X^MqiHz3=^p2-u((2nX-IH8qe*?7v)0ITT7_vfv$IHuLR`I0 zagU(FR0xq8)=MBtk}pz}mG&1bg(@*_S|98p)h?X0d*CWzAp%h$73WJW3Ma37w-{js(rawQHO(w%9vaD3@B-8N6%=IQAFT;}SUuHs=QxCX}+7zJUjE=4*r zg;&F+P~l{ntK)YNrPqiI@-DmUF~woM>bgre#X+AZwr@+NfC=l^e1gxr9;{;RF=*il2bu z1gubPRoiK1fMFn&M!^etZB<%n6x?P=m8VZ;_({=L)6JZBo`94CF)T%@eDE<;?VBnL zMEV|We66rUn$Yui;9M*qWlB%1(RkuBbs1oMERGCEbg1K9SW3#7>hJA0e0+e;s-Wjp zAJ2bi+NloE%2k84^>Pzm^(&Zmu9JY&bekypETp_tlM+=k@C+(a_-izizDJqq>|p93 z(u96oj%I3^(ua{V&=4)x@vs#z)24E>!wZLNAeYe8`>>8tt@t`FzTcB)(~G_|Q+(on zm?=JhGsS!v3y;+EIN-=sq~f%U3p2S5IMdIVDf-OFFW>}-?KK`JUD@bFBZvd0fsOAD zei=ITO4u(QI|`;VZ$@d6Le{ik2r&V(BY&T`JD*uls5qqy$e2s~==7dZTBMLV>Clx_ zSznTvMqhP?rZ}am71qShd=3W#jnX281iG@;N*ZC^Cq`?9S)@o=fEC{8j`$?L;a8e5L8BYfl;*!Xo zx(d_Q%&`Df*fh6JAWBl2#g-^5Z8A(kH6jS5sLc=x;iUbIgE4KWMg*Z071E)pELDps zD6#~h6k+LhRF(!gYeoJQgi<)-C6%QV+)~KDaW%553EQEvl!CRQNva@JM!wXL%2Ho( z`=Z%)TpeoHt+J@@AbObsEw{0A=SixvS49{Elhm{V>G^d=;7DGZsH^#yB5*F>gI(4>eU!z@8Uh zp%nzO39Wh(rz^-gdLBN)OnKVlFI0uqfMB^yM8trY9svBL0nBaBdI7`lX)s{rYkVg| z(!g#uAaFnoC`gkM)!*5Rx=nos!;iiLbG;VcC)7w2%H09_`=v-B!QU{1NO7*V$pm+L zzVl15!bm=FCXO_vt1gB|ES~p#XOm{MGl(>%dbbVRr!U}=1#K{Sd+q+Fs@!A0(AW1x zHd5j1R3`COUr~YhNPQN@NgD`JUutizzM{sC*Ku}Zc7F_W+qXn}O@GVzz#FIvFD9i( zEeZb)E`@IXi)XXt$FEWD3ck*H2T4L5|Ay|8BBdtA=m+9*^zRrEB#Rt?;LxgnVj(Jo z^Y=HCtK`*OdYmieQ%`rhv=Xje_NixSp<1jSplK_xccVwg%t6e+cXj8Rb} zHI@Z0Dfau)^LFw#(hFc3>6vWGZuIz~J2p~{IyU4T`uqeeC6d&DfAaBp$2Zyy&BH#Q zFEZK`OtJ97Dj0uB!)C*)MMIl@PM)HG{nxsvK=pJ z_)lW>2WS%eOp4U%;Cp!K-g(|ElUomOJl}hsZ|LfuptWFmv;*H4R!DD7r200QUG)Hy zVrA$2nPJ5C`M12_W+_ob700i?t|`K>0$>;1+i6=@-b1k@f)*E-m&KW2Mhx2M#C zv$pxXIsA=w<4^m%up5u2;%@v{ADwbyp5D|TE7ZE7_a!*dluww$jrsG>^ImJMs?KXw zSpMp1lCOj4E}aRb@w{M7GfqoC=Ceuz)1=p%0x53PXPVMFD>)s;g{|BSlvDAR1!hT& zC!N=0%GaHs(}+)xpAJg(HqJaE%R9ZE(ShX>ooPD)Rv22OkWFT5=nO_?v!}KsbMHP9Dih%rxkMdA(x5Nk(AMw$s&^e(a zQKERQZE_CJ>jj|{M`SIboYak6nJ4h!jkwiD_6|N7Q)Ov5kRN%SB?y&K@d2+=U0Kmp zjcbRr96>0>DOtp-EcLb6ffRyJ3g;NN3zel5tQF0;1)&uAl2=(;&!UO6cRH?~9QtT>8n=|ohP zhGtY13PQEgZbxM)1y@KlE*+4<%(&2(mZsdLp>RCY_O|v~ItmA;axbRws?itYC+L;M z!@u=4y$rV`o`MEy!yzAot+gJ!J%z_JI2DcPg=uBwG<%V!$&v;?C# zcjmKr=ippE1{YHtNBgIg{hJSX4Swq$@LHDlHYx!RnfQ@8Sg68CJ;;+1W=@88omqdU zFWLO9l{d|FZQ*UvVSxzxKm=*}Zw%z>8PA!))F`(5-3`weFiJw#>lbd~9!Q1!;E>U9h9*1k3eFn)3m?ev`c2k!Pvb^itV$1l0AXe{wVGSQ&HJsqZ3?kWD1ilC zCpOMJG5&iwZ1|`gr~9oKpAMDImFom}(os7IM`Eh)+VSj<>>FKw)OC;XN1E_)*IK7& zc7+Q&C)4|}AG1(7?&a@9ERvbL^Bbm_7OlO<{8H?~z84sABUq<40Fz=D_JhEXoVoSR z0+ZwR(ABh@0Vg1HbG!W&fL~q0NkY5h21DHBsXne@cGTQr+f=c)q0qi zcFp#V@e9BuxJd|*5sTlK4dSKPg-sL~lA9e*`^@V1eYP2P5pa}CF7#%BA`9kt>>}VO z#V+g?fgw4=j$aHgDRyDE3Jl2!wmKJ3QtG101clVhEVVPhq}YW`5*U&*EUOE^q}YYs zCNLytSl6xqlVTS(Szt(xzBcBSJnuNa6uYn~0z-0ywKdmV;{Bsvie1=Lfgw59T<&JA zxnteH&jN4>rU?Nu!Yc8b!Yx4XS$EJuuDRIhf<+!^kuh*qh`qWeu$4kTj|c43#Z@T9)@wqxy;kOha-J24iKlHcXouxW%9T%QIRKG!m+t2#lU3W2w?JDvA0L}kGLOq zc?gZm;|bxR3Vn|}GE0ERu~ER|Knd{pdmIm;ad|u`JXD__kwJ#G8!HRdLLO*kxu3GZbP86$&rOuKLh(3WHljxk@bE^VUFB2N}R&8YBut^x*w;ur{l%bn=W7@W=40o)K+W{Mw&!Lk(Ka@mEa3LM$M&17Fk)A}KMu1OsOSh?n6n+O(pm?l$U=9~Gj zeYeTF7O-;7#hx!%$n zTvNE#I_9m%?I+EKSABLST>&AA3=ibh2XQd3jrYEqsYME*g$a-_)BUf)8y34Jcz4*e zUfKA#-PA`E2CnSo#Tu?;`A$yDiQdLj%PwOXH!QFcp299w{_>B=58*uZ2pNuj<1VpbDnE&JNzp z%e%lW?(!}>AD4Idl7vkP&@CoZ$>cq4XLu4GGtF=H=9=-Z`y8t+?~*Ql-PgcOy49P~ zV6fHBf)5tAGN*qB3)c;|dNXpd7|q8&{LbGXzP5>Gt@%tr2UFH;*A@IrS!HYSMyx&_%jLxIWR6uzI z;P$11hyJ08lBc5uArCU?dL)l%5P(My(sfT<-W!*f(i_Q93h8;{ zs-S}h1w>!R`$o}ue8oR1AFPxcOi3z02(V7b1Cqym=jc2hM;n{R9C%FdHk^kOn`aM1 zuCoU!BL(b%NS-~Qd635p@g?ji3&Qy3byVKL*RG@T0esgwD(~Qn){%T=LIB^bjua#~ z_*!*TK8){DL%uO70Br(~S*1MM7o7)-!7Y*NXmNBNEsoBk!N4d&fEGvccw{f;HK@oR zFw>0W(Z$hu78tqC0wZ}87>x&xXlMk`AO_Glf%B@MkMfZyZwTn&!a?;|r|Kae=HWlhH>P}qp)Vmh=DIH-B_?l+f$9-Ep^`0#6tKpTJPVBESwJMu z0yN*46o@F)m=uWQ6Xm)ZkXR`Iw*cZi)`gglwwSN03w0pYfma7&M+RaYp!KeeZshA` z`#9Ymhq`e8E`iX;J@G%mCm9Z)?w0r)QVKgEXEhI!3U$xP+bbiO%wL!PUmY_sS(BSI|G`GyJZ9&KeoZ|18gxU@Bv}{7g~pMt9__TO}iBp90bXlvS<5pRzrw zEeiZ$<=3FV~Q zyB)^$FWCAq>4pq00?&1W4^(NwRxE%&^d|mc8UAU0tGTzor&FVDiM3n~yXkp3o>t_2 zj14p~6R)avQAk+Ui>C0SdymSgDVtqyhu7*nC21H?Qv}67Lk!P}r<;2#ysdl`$@u$w zX_XSw8pAPn3BiLJ)2cA0Xbx`2;KRH)#e!SE@Qr5>&NHzSP3H+7c{B}tAvGg+zs*UX zm0DOQcX+b#M?XNS{tBA<0bAq-$SAeev$Fvj3O#o%0kaA!S5*vfi^YhAr++rFcEg+&kbQ*e`XDC95SBJU>a zJ+uD>Z>IUMizm^%xyYMhUxIswbpOR^E-NuiQCzo_+5`VX?~ezb+0Gikd%u~`3<*KI zEe99FjR6s(Vgp-PEU9DOs)UWva-&IE=G|0XoRPU9Ap;`GfeArM0)EFos{r8Q6V0 zbxpMmMD_OR!5{gzEQtgBldfky-;ujf41QN}PFK_y#EnQPl?71t%NSJ{45P9i=Ri|*I2)o2 zLSFxza(K2TDv#yb-+koD;B`$cbQ6R(_ymr3-}Svsz0cdJvgqOBy;C+c*pt_}V-eE- z<&o^7Pd;n8C*zp{${*~qxqJC*^NVKxa|oR%nE2O5MJ)$8`v*?)L!Vq#)F0^o4m6&G z4c&pfsvLNI0rWG02KjXdzAb^*45qJowAF!qVM7_tYH*b^Msujup*ukEkc+^Qca z(QnVw4flR{@TbXDV{WPS{?(a^H+WlGfHdMIk?N;CX=Gr3-UQJGU^f&8% zcw}Gw(XabG(yl@Oo1Wg-?+tI|hGMjWKd5g)!kl+1_HHh^u<&y_?fF z)Nl@2wC}d-cHH1!SakYe-X6rCzkYSmhks1nf6WiS*^hi0zVX!F*L!?b_-W46J-}nn zl%8Arre67d-;(BY_5zQ+x8Ja4$H9Ah7B~B!yuPQK9?a{T(fLr(l--B+Z=1Zo1elcI zxl6}Q@p5lf&Rc7j_w~PU)1L0Lo9`{(*?aGbVdwQjnfSN+gQ=Ic-1zL?xx4!BZPPGy zzv^DrG2)X|PgKK`RjYB2IVg`K?2_NU&i@BLDN-g+ z!UX2c;cbvvkYc#XkxfeHKEFc`I7FV5suR9?J>xITm+0h4DJfD&K=MS&PfBT#LMjA8 z+~`TEQCg&sT7f7jdkkAgQ|Kom&k-q3>B{7nu!*1fyvEzAP>U3zK2p*M>jG~yYr^q6 z9K^!R7zx9TdR8AAsd(mBF-=%K$_mhPKY~z-Ba&B6>SLy$r;*|)cKyKbC8(?naSmBv z=(%}8sEn{Y6|b_?jZ8rg*u*_IACz|=Tv;N6O$R&R$EXFOLU!rv62eLyD&E4!s^TaD z^46+yQnlFCd3bVC+1lOk*F-KLUOag zN1kkKM*PZvvZvarg!gFBPlg}-kw)e&d1iB?(*RSF7>$4h*<`F$_66pd(RMR`I~n&R z4cE%N=qVhV_(@VJ(lIvp1Y8Qi(>wSkA$|w0dM$utkS8|g=vwb*$*n{Hrcsa8QWl2F zXH3p|?>L*p(Syjy(QH`{lzyRX8$+2U#qQK0lP=>ECFKvp%m%ZdfqS{Na6vM@jSCM@ zEYy1q19Jw9zhMyIad@Viu7Y>z+Xy|0p?&%44e&UJ6uYo2fgw3>Xm8vIFe!FnXbVVl zkep#V9`zox$wZp!AOT<4zX>j2weSx0%q`xc0;y!J^Z@p-z)pKyt!!-^u^|ty8uZBw z&fpr-)OlKJ>>2bsRk#*urH1K}`B zojd3@T#w0Cq?_lh$H;ZuxQoW~QrhX@60iUz(2X?eP;k4U=>?ATH8BGe)SmV&JiwUN zFL|4pgLCaSVOHG=kCByw zhLl*RrP@okA-2I1qF&zI`t9pGe?27kBaym07Vlg{3mfN z^%uwu#~<~qPT7LuX~mP-;33jV4sMBi?e>Vgw5+VuJ**H-yW?JKJ|!>ft1va0DQG4s z2vsW}uQ{tMRg3*e^V_%=p|j-`7+025HOt7uIdt61z;%*WSsF*AoxG$RN3urV0&#^& z+>+Pj3H`WNbptksuu7w#0S7Y)St1CveU}8i3L^`Ef@_%;DS}W6Z6+#Adi zPQ267gjgem+0v`J(#qT!Sb5yETOwE$(u$|bfgj$6TmHqr_jdAkkX}mDSEQ@ki`@v% z!lX#MpYU$H1SiQnX^zkIeCNk3=&zT9NQpi}GCoXZ$D7_N%O;L=n;t1baFz`8TPXI- zV`Ktij2cH>3GmdeMQcCCEpVNq0ZwIUZU!IncJ$8@RU{4U=X~(Ds2UhokR~Onyz?rm zcJvSq0{At`uJ8fQ6O+(Gf5bsRijNt`QliQ_zsD=EDY87o=i*^L z+TJ&W1JZ?_{{ZckB4rVLiy_1+H1$J-NRdJUC?B|nku=ot7#dD0(O8Ax(9w^v5cM`6 zAN6&&TVmn!fAx;&tGQYR24jj)~^qqX9cPQ#J-nMJ_bM@2l;D>}mMdHSkDy#}$4615W4 zil-2R=%fhX!!HD(6i4EkgT@d=q@j^Mj$%y>*N@6lihPO|+Wb<83JD8|3e#v3A-I(# z2&FhBdF4dR!4Qrcnoh(~1Rr3vRFRYbrghZl`naf zl`YZBy%rr65=T)cd6lIU>??ZJF^*!5(%vlCb1mVNxO7?r0}Aj^dQ$ zRhX*96ci_M6s1PuM9PC=I;&NUFGmVOofVY4%2GpiA*IZp<47{run-ldLWBfQeH4TW zsgS%1tBa`-@YWd=wL+n?R0dIUTaS~GFGHQmB5j~XxWl1Z7ldl1gQLpI7Oj{9>(ECK zIUz=XtT4JBcIBy^tc5>&M+e6dN<`G}~L- zoeIPlHO`qVGYK&|U!quhBpvLzFQYkiRy%lNJEx7^(LbB@3rZR|%z5Vs>PHhYDNzgP ziX34`AUf9pL7_!$QEB89eQL_|LRC-|4o+f)wN`Yt6H|}iB&vP0tpjYshGierP2Xod zgMSu1;j|YiQbp-fXjDf$YmrdoT?B>FFN6(?B<1yIK7is_ww+O^s;R0@nfO+GtO27w zj_qD~y^;gI9oz|gJC}8IBn=#u{70g5L7J4P$_`!$9qoiF6Nr3^pwL4Xqi>ND`4)d| zrqq;owzCRVMO8U?i+ESOtZhiU5e*CON#E*h7x;_#B^XE2@G%gBLHZ9AN2@C>QcZ(@ zL8az&0Zsk*H7djdf8#un$QI89=HGetpZ#)0nGk=VBxZy(!$!i%7Aw2i-`OOa>_@85 zmhND`D)=v|u~2zWdx@t&%vJMgK8?yt%>|?TTPRmIaMzgI8_Yj0Pwq$>{-+r51*BrW z6shLHPw*10O5lWhIISD=(LVT>us}Kkr*&t9w)L@>S$-*3KF;TiBYq(`u^W~qQlyYD zY5}YRNJ?jQhc*=1uv#PS=zaoHxO-`I#{Kvb`*nLEZm5Bda>hMn>41=h{cJcO1g)jx zy7{2{Q z@Jgs~ForvUXtjl)(2ql?g-Qp1+QhcKnN! zX>1TwD?zP>lp8?g7W@F2lxcdB`@&&>l)2KTlm<_=lkz~szNi>~6Zsx_YKy{%|^^c)SlVbOVb~atcyAAN*UPH6u zdiy;;mVpW`rjxKjT6~PJlX>C>`whPoyRa?-BbEevX}rBI`64OqjMVs~o0&bqZjvU& zF7?HDnQnW4BB|!U1pAO5%c2#@5mrdciu})wpokQ^ta1fLEJ=}1ZvvPUyD(G;J&okd z?fZ%L8#d`l_wtbdFP!v?X)bB8kfI9^k!c#=3XYRv7gi!LBxhLbGJr|33+pE^BxhLX zNdS{#7lt*7`XV{Q`rc;0XHx}}zDU3x9x&Pd*v5F|XAk~8#fEbZCA>Ap&K-b9`} zkd8)&+zgrWX~)9js{78fQ2Yx0f?f(F z02SnkB-C~uE@7ldA&!S3#KpWnA4bc|q;JJEYK)~UJ#_$s(lV31$R6hxVr3TgGBc8k zj~;+LDN+a-0xFSQ(_}jSEZ8nD{7wWJNaHqAxJxE_{Gb?rPMID*z;7W~D8Y|`p@-rh zIxujE;=pg@=vts%5XA-e=Zq`ZdEB8Aimgh+V}p+ySG z*vPsNDX$^4NFf1%5Gk!8GPOt{6#^krTu?MO+gI3jrj{$NR&YcQFW$q7MT->TNDUAv zojRYXMG7es2$7l+I2t}vixjd(AVg~BAw-K55*7%N@&WTy#7iSW^8xc33p#Z#mDtef zuU0R+kX96eP>P`Bl@rwm1O$7OR}^t1yCko|v}(n}xX_8CsFS=3)0$=q5~2{*D`T@% zzLHA3aPEWmTJWmw1SSKI3;=I#jzT+H6{c0l6ez?;5Pob$h_y*Gi0&UqKkd%l$HgvHm2FHEf-Mxs z__TO|f253Xk_H;cFxe1C9@}>ehiUP+|*h??`Ne6(p?b+NR~W09yEbX zo`89Cz1_r*7eGB1I8a0&13p9r4svu6DFo#21j`^k7g$)%Lk~0iW zZ#m|dViz_{U`WnOMmfP}oL?@v(BT3_7JPV5+GC)f6uYpi1%~9Yhxd&0%QY8^H4W9{ zAP<(V=k|=VDGF#gi&S(~59t|aV_XrE;6WUmV zF{1%LR6k#4oSG&}csIr%rLAHq(FPEpD=`b(fMru5Z5kt79;rv3{78L3*R`{9=_|NE z4=1@CMqT_2i(2K5hrMLVo8dd){ow%v>5bhBXncm}&2QvWRWM6WOUua;|K$_)zxaXr zN?lU;-~n(H7|HXpE0X8Owz{i<9^?A|$OH0t)`TkXGf&7q*fIQd_3dEj&a+W9Lx#QNL z)Z^{K&p4@QV(30fGABOJh+ul4pe@c|LE&%~vL1Gm2&qd%j9zIvphXdQyTHJmfN< z<4hv?`1ew9Ukwk%((Y5c)8Mt-opuaLKN~aOgJ{>;3eC6-{G15fz&yZ@5^7q--Kldo zcBi}}E=Ag(hL>Q6$v-7R-+{4S3oaFMqzO&hg)3|+Qb^!VhAqY6}YuaYSDHi(uCk=MBvso>K=k$5Lw=-P+g!damL69qa%$hxzrOhZv#;@D>L8K zfk*BW{WJ}7-dO>u+|rdI)i?NS)CGPl1Ygs`?@=BJ+{5`W(wGVVvOn{Wk|A|0r-60+ zGI{VpIkjN2dG|BBQ<}isk$5zYv9#{b`P|--e2s9yl#A)`0nCP)d;x>49|=GcmqDpe zAY&fN2Y+dQ?3ZE}Hb!71k8T2tJq|D_c45~F49S_>loJ4xVi$Iuz>u6_3%>%G6uU6- zg@fb_yXR}z7sp~lGYll)3+qqX$I{hl&7hrOQ>!EARexiT^y4=$Td!nGo+ymtBKmW4HeDEy< zFGUaqFA{`KoWkJ6Fgwdnz)bqVZl75?D20MaQwM(&1{hOn4z)?V4$fRKa7K%5sy116 zlH$HF)+DRBk6{B(+t(FpJJ5C!#9bs*QMwFWQR#ZGEV`ZGPsqS?H1g{)ng**SvR9)8 zH1m=Y^+TWrufPLMZOtG4<@vSg{u4aagk>ODG0rN^6F0aSn%E1UPw8Tc7Qk;EH9Rk| z9sU+j>K7h3C9>ZB#xH244x?<~#**L%WPs?7a zq`@`fiANx1e@cm38+Z_}xIZitf*+O%Sbi*wcIbLxgTx^?ZUy>RDN;V+hZsWqR=wrj zYKArSedCu>MFmk0^dwS;;8$fJSV=Y71w}AFcSFA@v+p$2(7tBA*L(x;;5lu_5%V=HfyWIxVnsifIY zao)K`0(m&3{7}WptL=hxrPIB(0P?}d;M-@?S1?R3)rtrr;pgDBNFhfA!dyO2$KP?6 zB8BAFvO+{^_T$T3TBMLNfew@ik`GEs%t6SSh!BOSkc=nT|0;}_M@VodQ4mT|A$jGbYOzaT!{-c&BSN9F)OMzz zUA{OO&XcT_$|3_mE2f}bK0&Bf`I2{KNt|(9(Jo&cMVaJPmO6_(K<6Cf#8Iq~yvoWD z8K)xdRmlI-+`E9sRaJfCndZ#o%q7VTO=(J}H`>Cqq?gzNDYVegln!!hpg;-*S||{N zR~rNkP&*z0Wy2LDA>? zzu(tKJZtT})^D%9_T{XzXXPAiR#8-RW4aMmp@TuIk$&Md5_JH&p2IO!-RNFRL$7Jm zmP}*TsD%?}2Uk63i)eTFokfV*v;>n*4`jD@Mad_D+*K ziCpuWct0%Oid!EY!%2zWG2L5mr)i zIufE|5)>-Hm&U6hr2PDqs`Y7EHnq8o(4}{I}^;@C=Vj~dKa7NcA}a5 zAR>wN^GKwNO6vnR^4l7KZ9la*vp!uP%8P1>N(5;F7+)WQ3^&2p0X2VqvUmY#Lwda68 zhRCqVwfF!V>OF!Dl0S5jHq_gKRoWkrS&BS>>-zkUnJ2x%8|PwQrAUjoT`WRSg-z$7 zh!km&;#L+RG=+b^t=_$KNNU5EA%c)9ElRe60fbtBA5+0|WIja@D9jPW@|I|~lgBs# zjF*&CWDDnB5QSe-(E}#i^yh_RzaHJwaTb_Z;igL=R=AN8FeN4^-p8A6zg(LhVBTFQ zvvTAS1Ajto5@mgZ^k}Q`e?lc5I-~1*MV|EdCsbXeMXK-Rb{UF(Le)iDBrhVQ%0Hp% zA}!J?BBZMBybNyUx=4%khzO~wT_~c9v`C%!f>hNA{2;e3(jv_wLaO}DZe65Bv}Z|G zT?;5tD&nYtq}6sPouXZ@Zy&k)*%f*ZCYOLW*<#$$bEbxjz(USQ@>;>$V6RtYQuP$!Cfd(Prg0b4PSz)nXQVgnoV$39Zp8yhhSpXAKH7 zER7D~bz5W(n8g|y3}q~h9^rLcdNT90qQJz`a67plrmc{BDKHTU-H&GBbz8a(9(DRL z(b6aiuiMfC!WtAaSQ`Dp>$b>#=s8a^iWw{oy|#5*dI(tqr-_5BUt$IgFEgEmC}xnY z!Q8+`!xjMz>wntx&`>}<4W^>^%inW(bW-;4pYYSCT=S2~mb(o%JBk^kMDLOA6If$D z&{lvCw81kS76Q5!Dxx~@1g9cb!DH^}5}e>Q@R*BiVbj(4m`hDkctK4(dkttU+|K6B z2Q%q3rM&qlJ_gPmgTL3%?{_PHP?{LZg64dt5qLgjf;T^TD*KHn{H$cj94Fw|i23F2 zYpUj(AS-nS?|6|VT>bOiHEQ;CAS-o7c9F;;hWQQeB6ZZaKvwFE>bf?Nl{zE4SY#0c zzv@9>hIt_?#YXHD5kqzUdI)^~<&Ms`^y?tkfCVheQ@JQ1<<-lo*L0iv(&i+QNB&cK${{ zlR6_?5Lv`v*`*C2yK)oAN}ZAI5?RDx*%k9a_PU!vR_cuGR*^*vmR)mr=}OgpOZ3#N z)EU`_MHVs42hn=6Qf$N?5iwLZpF!)%O0f}pRK!pn-xBwJR!WS-Vc10YrOwE1=55hM43>rOpsiHy z-5@J+S4j7@9$@I0O5~#^&@FBpJs%bNzNu81XvB)9@%fiWu8eB8wO-3ttFa zsX874S*bI!kBBT{pzq($N{NwpR3uQ7M-sje_%&550GiYp*~df{F?b|T?She%Vk7pr zh@mdPtOIay4Vo!(|si11DKQcaB7vIW)Drl^)@=YO0!9HN5r}MD z1Y#3(eu<-&Y>zH>C{&@JfKZi0bdrgq&VMr6G)#vu`r}0Tqp{Z%RJ{FUv@nWzXhYXi zr~^Fd;U|ioigNTrA1-3;O;1Okb})#O#1#n#b$IBG;_y&EQR=WzN1xT9rveBMXJ;?t z=Xpi$O{H3Q(c;+31xK2QfKs#WQ&; zQ6@9bMd4MDfmD@+kgB42{DX}75aRy-{wl~pk_4=zf&T-aIDwAnpZH_=MH1*J^Dx$S zlE8nGm=eJ+3CUai@VS7pEIwCa3K(F2XXk%2F@;_Q>6CEpkM6<$Vq(hb@OO9q!^D*T z{98=s+e`l|*-vH?nzW78@)sU@(&*F~&AXTL-e7+QCnk9y{;cMAP5L~%YZ6}B7PP;Ad+7&wiyw5>*Z<(fg&|KRrBwgH_?lzN*g>LeKlSMdO3IdT9sj zp9|%DSYMyv{j>N>+za`9Sc>!pTKp+g71nm+aXgZMr>neYnRij8Q2!e|=aeEXlK(l2 z5XxXbOsgH;@Zsh57os0$MO3T0zhG5rMRmRi58eypHiy^1<2tg1#vXWF&x(%5pnieH zWCng-;R^N9OVM*vc>%&}0Ek$6`0KfX72Y&z zTOvaXHNTJ6Pjcu`luxPU?nd4R8|at>uKMoAhjw?C#b#$+p1H1Ey&c^1{7Z1D07(eYo)l>j>Jj<^RdGDdQun1}*QCBEjp8-XD6x7x z=Bh<|#5OtP6S{vRHXnW8Gc?xi+=@rvYpY^4L=`%#VsPq>9<_fbSMaHTo7J{NX{xYs zM6BF#R-;hosMxy55Aov!N2=>a#}=0Nk9e6rOyVwtbPfpKq??Fv^YL zs*W;5<9&%L2Nl)!39;LZAfnb8dmL(i**>u<2Q5<iBYxXiTQ1FW3k-Ld%#3h8*7JrpVMx}RwSYh7OKeP*aQa~QJdVv z(5Q!is(vyU`#gM}lPWzQnxhbJ z`;=HVD?{Y!A=7;$M{W8Jm_buPWv0d!IX7Y=%ed~?{_3Wwv6I!t)sCx<+Sf^|^_$$9 zXz?{@yih+acE0N%salFi?e9{0Yn;2!?in5sV7X;ZfA3=~*V9Li$r?D5CUT zk0?m0WjCU42!?$_Ff`ihUx6;uoLO}fz}(3&T zsQd4XEsoq3aLjN-X}k+jkW_6c7;QpfzxW`x3dn5rr!BGLBX zzIx-Ne!SFAl=^+7J_lD-`)Uk!B!p7iKZLgTgDs~p?(et?kW}L?iPSjQg6iG|)g7>( z720OIP>rOje;RI0*f489Uum?FRGDX>8tqY;B4|%TaM)PE={cm;uAf3Z+NtWFf%+Fv zozaox#?gGW_7_l%o2l4F`zke#y;Aiq>`2poiqGWpaW6rV8^_M7mKapuf!f_MtVWXC zCLeVE9Kgx+w%4$lOz+zPrrjq)xh`@~U_wm>%tFg<9K@r-gP6xE-q~mnd6xQvh~hYi zH#XFOAjS++`07pLYrdAR?hL7)DfI_PeVx=F1XmoqDhH8xa9;M^hoow(FPl<|wT(T{ z{~B};JHG>IHEv$8x*L_H8fn$nAk{Q96H%Lo21&L3a9xY8KN1I)U5}({%S$b}b`yG@ zU5lhz_C>9WgMJIu(v(6{)gBeBz16Qpk|!K>zVTO}ocCu`2hxg$tqX@OlPH^`UVJ-t zT;$&13OpDbB7=8yc<_o?g)8tBSP-%VaeMHG4;66u7O3=xu@f5RfIKe1L;32~^R;*w zU%dvYKV0hbQh$Wh9|>1kfC$CIMAKBpf#xZ#Kx~5R??Q)2J<{wEY#JxQDbZdUNcJ|3 zBdtL+i5JnYah!R9BgxAEE#)Oj)eN7bdTJhf!0NO_S)GhKp7alDr17 zzq|%FVl}TpB)M^N11(XS3S3Q7fd=zQ8O(K&`vPn5XuykHPGqQRMB} zA4C*a^~1_;Y&aGKaSblyt9Kk<^NaZEo+$MvN&RA}KSkwA#7J|dJ+ttjH`^-5t6(CqB)9YJNZY(o*YEpM>BcwXpzd`(JH0Z(R|jw z4c#yLNVEU3TWZ&{(EMStnqUt^lAFig^5DLLQ-^03l05Us3ADS@*h}j)_%wXa;qcWS zQ#MOIxlh@Nk^6&d@ic%gEZesX?x{%f-EX9S_d}8+s22^&d$oYFIe_9VMU=KLl)-j< zYrCc%G)ua(mfT$)wrw6W~l6(vU3~G03etT?sC2s&*H0h4qx-mm1{>zpoTqypFA2Km(H#>F;vu0CJMYIplt%#<=&f%B+ZhwHVSbC@U;Hv20?*!2%BK^;E!J*q;k; zBFwVI0P{d#8Wg|k1EPc%r)~Ah#}U9XgG0X{w_F zPW2lbE&)-P<=#rZ=2!96P2WamvBeBuy`g-~596ylT6sHjG1yOWXI=*_iWUdv z7B!2z6y1V&+VU+ZCbcy4XpiI-L0e?Tm0Aj8CC+>ix0+`vZjwK#^a-Z;MI$4mW0sozKHb5cJUuCjq4lxj4Cn}5(6 zTq?l9t#hz7)%FhOT{z0tU{|NOfj8pqxzb@o1K(`JS?^V0!U^Vm@} zhyPTKF(_3tI91c&U=R7;MjI*58h<0jjx%@;O=oZ<`PN7NphpjS?&143J@?SaW^rWc znRDuvvXdi)z=Ev-;6nEnyt5(6`^G4L-$0W0jeQKrX-@!1S73S+ryxpX8=@eox-S7I z6AEt|ghEgBI}oM&&t$_ zy7h&!wGFi(j}vSLUyC#O>K(w>e4W%EB=rYN{T!)36s|JC5K1CedT`?#^&lW~G|3$3kNrNOmTwpatO!Q#FGqQu8Oz7#tR1>yT6FAK&w4NsoS;mvb zf271t@qVxmP8yzaNOCxZePwNm=2+X0=Ewzf``s6{xf)4+boreO;~W>3G?J?A4tQpBNBcVilB#dFJHJ#= z;4G@bT^xCoQRqZ#5rQ;UA_$VaFAxUr3xq-YLcam|!w3L*%*?5nb0UJQ-3vjGJL+6Q8nsqcnRvpgWdfbP60^Vt4`%> z@ie}AOZl2VL+Y1H{aI3fj?|wESJ|r&O0_&4xWhrn?B9d11=-5@HbQYP-A3ppge~)2 zr+XC7byBCLf(CIkKOT1k-UyN8n-JQ`ld%UUn@m=us23ob9 zBJWnT4*5|6t7#?C0T{0&IsoHG2?I`h9fQ+eM|Z$IWk}bl7yc9();4#tqLBVP(31VC zYLN^3)d}G-by0wy%VMxS|uS@;K zQhy0talfi^5Q(D{dW;n}(sL|5*kCmspyX*y^BslOG(Fj1HN`NO)!wc5d?eMfKLn#s z3SD^wDRQmdCAG90jguW8cN3&lSHmXr6ob%w8rusXwQCRr zNsgx0z$B3$ppfKf>KFs^_%{IL=|G2y;}B)pHxUI%eh4EJo_{_{lR?@2T|oIs0L2@R zC~X@M1xfsYWQn6~LAUrYXBe2#n*ipSfLkUa%Jxl&f+V|zP}nU#$oU53n0wrl)%h2| z&$9HaN}kylar*8-93=U7mbJcTkmTQ4zGiS%6~LHcpijjdqKxZ86eQU*gu=tbcx`klI{oQSF@MTb{vmJhTzUl7(^Go>4 zwesevFW!Y)V8_L{+rSE*rk4K0oxNI@H^^`0-c_%V9A*yTKmEoS{C%k!cwMjMiz2Ua z+}T?w-BQczdM)4aRcIf#V%A%2^4+w87SIa47qWr|a^<_eT3**{`Qk+^uW{TpkgEv| zYI$AH^81QMKtKcO*BWUB_Sp81+^VcVyVo(~y!w)oxsV;@Zlz%BBX?coS8cWXt2HZz zL<^66?0zHS%)p^)bK(c9D?fD?#dm-Qo7?j+Yj%C=u5|W?+V3ulUmxYN?aLzPmAl`A zYA}bcs{7_h*1;0h7Kxu%-XWEARh=6mBcn{VlmUv1cxwBQ_!8$5aDu+aBdwM>@fzm< zv1VPo8w|;RUktf4>eXRQUm|{kLxp5XFOujODq8kwJj<12iT4Apq$^v(Bv^8TLvUaS z`~*UlaJZli*)N(uNGv&6RVCt!;=cxSayN=OE1lU;3x2u5p&~M-h$I+8S8NZyL4@+- zQt|UsKjgY*ysBkQiL65uI|ad1V|myq9om)}XAahntBkLU{|2mZZ$bUM2?jUpnoc|?4s+OcQ6z0f*5o{G4=$MW1( z-NWL`)w|X4D_u8GG#86b7XvE)FV^6 zN5;>0&|FoYjW183q0pzjL39Fk`;=jB$@j=iMA$eQx{Jbvaiii}Mz0p>FM>4w@ZFXC z6?p_m`qz}?@3Ck;Z}H6*pA*k&`BtmG`P64l(+|RYby%UKXz~4)e$VP~4|}6w54MLq0t3}NBrM=se4XXeYKzZj zFTWQDT=y_P<2;%Gn$MMl@#}&-=#?}D3xIF7_*RSeEWX|1yDYwF@jU?^+b`)26d>Pk z@opsCgKCSAo9ODOCWFYO%~s5 z@vRo`S$w<2cQKEzfaHHgOQ6T%do8}-;;Wr-k8>7ZXYtL%ga5Swt(Jgi@$DAhVewrS z-(&H;7T-^NzyR0Usj4kLXYq9w-(>O47T+EVd#DR|`jZFkfubeQZ}D|yVSv2FH(7kE z#d{XtUbby@=x)?u3FNJXQC&L5Ul> zKf{+yExyj;ix%Hw@ztrYM{*$^mS0_{03IkTzRBX7Exy&_J&SL*_>Lft`+rxk0QjQC z_gH+d#rIphTWPZ@kNX8wfKIEcPqjMR9k$`=c)aYI==whFUebc zlf^e%e5=KK7T<319fs%jOS((}wO>-S_#TUQE5kj^S$v(v=PkZT^U{7vvo7HFOIj`7 zv-l2+@3QzFi|@7gj*B@;HuwLgOTuAuv&FlYhU;4`zRTi!E#AE>tY62xfB(;00$r=Z z3jG#eZN>RHi*L60j-`;}1@6{2yB^{L1=Y*K0(BOjxA-QD_bk50;`=S$JpRvCel6a0tR7l?&f@DVK5y~OK_1#KX$=+t-)`|87T;y@MT_sT z_+E?e5AfK2i5snuJm zynp|<1ez`0v-oz4@38nTi!WMy5A**0ztXXYqN9ZvsAa|8KSgS}oqQ_;!o$ zu=p;EFIs$0+`9kwS_1tR?nuKR@l6Tq{@-i~v|7Ap@$DAhVewrSU$pq1 z)mA~T#rIphYyCb@ZSgsaue12P#UI^d6*OCXtHpa3uYVQk!gAHJ2!0i5!Y6Ph>E{Y2 z>6Z#7=|>9HhqA3C+qoEimBSwnRPCjjYBW^s2_Q(nL%`b!b#>+nO||)gtDp>jZ&2N+ zLO(UAZp6ml2p};GDExIn5hDGtpjxmRe^OAHHCnLtWT5czLA9I!6dt1~GKV{MB9!5A zt7>b~R3pma;gV`Q30kI~2$-Z_2ZY2Q22>w*0T0;O7j-__;u3 zb`jZ$K43|-ov5}G!4f*!=dN+}N~p%uZ`Fw1B`Sl)6V-OPraIAAR7PGSs?XP0t7~g7 zijTsBSk;H^vchSaYSWdCrYQ3@k?&p#QtU-t)PfLH1QbjoA~RnXg-o-qrKYH|8*v## zi&0Zl)OfnC>^wtLnO1G?5-4KBPt_EeL}hJSj7*{;Hi=22k-0c%9K&HJi0V93Q)CmB zkxg8SHWAfwo~HT`7*B;2nL<36r#uiqNrUi!*+?Hc8Ti4 zHfWZU1w@erM3Dtd(XcRy#t=mf<3X{a=7^#W6Ge?Mg^l3(t|F&u3dWg9>=RMcC!z?N zC>m&%L;uoBBQFp|8bpx>QKUf>nZ>ne0v?zu>L*duPol^yO@UcVVn3Ne1Bs&Mh@$3* zqDF|KzB7drkZaNDL{Yljn6g0;qHb)dSLKHPZ6!nQHYK|ysjwx)8Yq2?^$o)jo z7}NemCh$&%{ve7_m_ig^4v!XjHWEd1fhimZO@aALqWMgrw}_&S5Jep!iaJ6Rb%ZD~ zfhjbBYq29lQAdcPj^KeKn?)3v#T1&QDKLvjf+mV~0N$fFG*khuo$3#(&iJ~48MLi~p%wh_AOcWV|XLZ~=qR0fM&;(6^2~461OrZ%x zkqJam!$eWTMA2@*W$0jE4i5!!VgfWC|EU&)CW`FBBRxgSjwk|T3So#MIXuZzWHnQ0 zHBqF2=Xi?7lPH>wbh9O=^KBQ~}th2u{Y-IfUseNRQyOQPtujFr?iDxzKx zMK@^D#LWQ@d)OqRXoQGr!<#l%f*~TtCQ&WT8=~m;jdJ82D(W*DWD>*S?Hk1!>5fhm zt_jA#yD=7#H+?S=MYn3KBtxi(4Pg>}LloVrQH~6uA~J+1GK45 zQ}7&xy+agvhbS5_rm(Y2p(#w^FcC!-5JeUcMQem8vV|$Mg==x85kRheWyD!#MpP@3B=(1X*@Q{K7OQI;S zB#Ht{qB>W}V0L3PNkx682%~m7O5p&WPEnYo0~FPAsn(%@S2r>;O2;J_=JG_TT?uk{ zet^cvJk>;-COVA}m?ACIUE^9GVn@?dhPjcO88&Q3R%B<35wUL zh!4VSA5kr)jOG@Vb)tPlk$o(O77#^GQ!IyW=CYGD)q>BHRMuvwPD6DYs?SiFE44-~ zQuO@WXs8xLwHd0@P~C>=GgRg(jZ$l}O`9aZFJNK2%I%9fks%c~^C66JS}0eP$`ym52<{V@(!6?Q!tKYm!0 z5+~KHp7{AXH*>PubZF^;ZF6(O+{5bV=OKjXF9V2emG~z%FU3=?gH?svUGYbTMCql8 zs_(VPj%lr z@n?o<3Ej9$lH?-7WEb7|SR`3^;@$X(ks7QIxJVnPaWo%Lp1mEEPk#@TXG_m?WBHRA zOq;8f^$>eFFQ75H7W)1cUmkI#h&vi3U#Z$d6IJT6V#F={@V{Xgr)XT=j=O|$v}Z%@ z6vq8e{Hu{ET1M;8Jc710R!B#I&WOVA`r{`@=4e5!s0B5k=1r$gmrmie(DHX2K2OSY zuW$~N=L=OI#g|1~`MU5IIGOsMkK;??F9L2arDW3|K+OFlKBr1Pc&S@#9|LbT#6;?S zRo5r*!7LW16m)MRr+3p;Qr@wMQ}c71xVDH_HS3JX$YHuD3E;GpsOqKL5?4AzZQ2_a z6$yR!*~Ciy>CM2~6C=M>wH2|M{OZKaki?Sg$^5ggdzxIYfWJV&!Nx1TI`K^P){w;F zDiJfUO?K;bW8MhHWd^+|v0#i#S z#uD@rLcm#|-YrYq>!3;ae#0t<41iZlR;gdOi8gx2;j(z*$Y}9pd<^Q0CvMT?jKnA~ zOvBsXu_?Qh4b5M}SNGb$6-S@m+32eKl8Gm(L{@joI|EJJ zen%v$ewYHo&=2tT#v`M>WEd!)8RhW+mmH|z{f+Pr3#yt_k(iK0?SPB&%b71?E2?&n z#3(iV)*%O|M=KJ?QJ*uF0PVgaef|;SG2b>E@I+r*=bp`YY$f20R_CM>*AP@+8lZ9- z>J}m2$RujAqNP!a=P(LchgR_mF`=6a)YzfWp}a=<(S|gk9l&G=xaRp zzr<144&(i4co1(}HQ;p^ybb5-ezuGN>qJ|l6~D}AWF^nDr$;2dqepOo+PD{>6%Cr& z{E&ug90_ouuHn2D3`a()`t82kjwl;i-|NHh>|!3BCVCnte*xo=d5AMwts5n?ft24lT7JV`o0*gAtlFLL_V-+uAEV2=? z%+xrdZ1IzM149#xIP#QeX%z44j6#;N<5M#eaW!Rp;#zIif(;X(m(2!IrW*6;HNnuB z`HLBoEHs!2RWUK)8BDcv6^x*T=@H+y4`2$0#&j=bOtP0TU*AV2$i@4@y6iAeG}DM{ z$pMfkYM|mu1|lQXvS0dcgGn|CCz%1_Nk(krWIz&4jpVHo*I^5YG)8TnoVeQW;hOyb zuGfd-$;LdoP4qQhehuT1g{pBXyk+*fn#4Es2Dv~jor06?_ts=1J~I{YL|@~%mopyO ziFiCgKAeiXSO_KR5R0$4&5Du+DPF-KWE=)PH}QM%-52nsxwHm0_rO3BK<$Hx<&M6a z$=2OWHRL~m($L;j3{7_OkWTo54C$tCfsvjz@)k|bfUQ=vG>X0jk)dX?@y@YnCQb|= zg~??vC2AbJamjmt5m2?gEbalFynFk%pDOxlOs+i;)bKusF93dwMx~`L@xFt1NJXzS zrYM2F$9}`C#HN|w;O-UW>Rrct{@Z-j5tECr`Gz~1`!;@@h9ZV54@x}ipqgqt7@8ta z&xWq_`ZftEx9*<}OC+lV-#7-_VZ4>Qow*ABuR(3APDRz*a}seqtLCZMha}vn`v+@Q z5#M)6VuC|3{KjN#0p|cuq?ZoGi4;dI*O-!KfK)2v;1FPTz8KdhHAC%6aPzMTE z$-_}z;xFS12|rvNr=h<=o&%sw^AlCGMMEP{q=4R&aueAJlJ+)Fvc~!N;%Azn@OtK< z6LtHxmL4mPD*8~11KarF;E|HqFyauWjHfqD$4k=CJeC!f9iFI4>%ZF5f%A!pCGj5U zVDrrw*n-+LMS=4JYiQVY*Ly~W17{ZJKWV*%Lt_`O{3oqM@t?FxW&TzZH+M*pj+?3K zyOR>|;W`qcxS50~ZWcp=aq~;TxcL-_n}5v4x)1ZUDBh-PAZ`{h6Fs81#LY_}Zr&-Q z`5Ig$Zg!fx06q9f8OfC;xgOT!bh?GTEcfqb>On-Rg*&bPn7AP(I*>VlVS~#2qX)-o7OW#wKd+GjK)?C z5*hbuvu=qp`No%EyA~~tl7EX)$hN^EW4F)RiHPq$AG#;18p_?xP-NI3v2iYh6m^KD zNJhJ8zSIPs4)v1~@#Hnp(>TQs7>Dfp%-A?@@W^Y# zk=I09qj~*|M%E1;88;g!aT)XIGEvrG`M-Ak=sODqZJ)S zBl|uxG;TI%GC_#XTm$_SeU0bE7>}&p3x8YJ(Evk+X>UK@Op z*zqF7#Ks(&6U33LL{HIEK@DXLFJ=LqBU~453gVC($X&ilvA-l}nl1Lci z=^VYVh)#Z(tbG+iTD&nS`g#ZAg#zItqj^?2BXO(46hz<--ogSwa9iSUQ4R#?lNS;q zxDpF^a>L_$F@5raL!GVPfl#VykWdQC3YqIMl)8dLV+o~}+ybH0?;v36r7*@1r5@*~ zM2Aw%dxt|Q7Uwg_+c=c+@G57JL{co3yPa!`c$G6qDbleNSJ4?H3Go>uk`zmcC4pE< zy;~Oze!(S!;na$&Ipn`ku2;%2BwhpIl!%#d>H-kw*l5C?5KdL{yeaMhR}808kt!+D zQ^L*AP@N1fWBZq*>80Qfwj|I2V{*@0^yxH_#9f-8~LuF3C-CJu58>5*Z445@u0 z&$3+g(u1%UpmxATZZ-2Bw(^;wmhSS8IMgDRwmZ?*wiQP(8rwKnsHKr$KOpjZ1=tTn zOQU!r8HH>cG}Ibv-4}>oyA`@8sv0UkilNA`!9uMNQq&=q_Bv72K<*d@BHKPY)G}~% zTOf}7B-$FSI9B|Gt$b#vVG47>7(VcdkL>EQ3kDCytyZ2pZ9y!iZ#{ zK^#2JGLSqF#MVCt<0%*#vpAJ8$y&w?$638T5+C&uKkk{E0b$oVgPY zAW_XffZV2-(@ z359;pM124B@!CIuJeCYVm zLhyul^;HKd8cBT36O4}^QB?8q<7a5;k>Y5AjvqOu-TGJXNN$jr8OsWpw;*PAa5Pop z(B%H=w2u-eM_z%q7pfI&BNc`BK1zJwiFQ?EaNHJ2UYOeOJOx=EUTM+}YnQ*V!9<(6 z;1w30H6%H~nLS9WSXO8ol7v<%32E7gB)po8;MR^vUg^*WEWwm@kypivXdzPtGUc9< zw(+X^#w4q%0!`D)&H{)eM2LHt&K^5n?x3!P)iA`!K1Oxb&Z|AViw-CCaebQgVN z(fbIlYTTG4oS*N7eQy~9eQ%fc@ydPg2^fHVXJP95(&O-(2;l=?EGx8(O%6>*NmFs> z2@g!Yl+K1nGy#w{WCGBb#?bs08dP7KJY^J-Fd=nS5vzbF6}7cCdHg6{q(yRXvk0S1 z`T~gPA}vyUheb$LeGf%+krrwGL>fXg6`zq@l$8=Kk^fjg5KLV>13+|<79r1qwFIW# z0Ffv=yMAU8vYik>EuNWN<0VDgWVDZ27w`5A#L!L{D8IBr&Q{1h#sRkWyv za#xAU8Q%t#mRZRO69nWRx{+3v(3dp+98!m$0i#x4hgg@O}?L;AXb`&&{}9n|8uutLfy6J zBNlap8q!@`f(j^{oK zH?w3ke;l}X47_^~Z#d=d8$g03-aA-C=lAPBjyP)Lnq+FCEAj`y%RX@hc)}aAQCam} zpB%N{vX)?f4g-k_`0w=pS$!xf>VI8V9@^5OK5TWGOom$x`^Q<4v$x-FZFuL$Hjk!s|8zwk`}~9|SnF)UsS; zXuSD%caRGrs_%;AP&M|dWVwy&o-Q_P+l|fBmk)xAhL&_~(_=_}zHK6nbwsVb5*pcz zjR>eQUU+XnBQ>pqHxf&q`;cw~CR<6}%x}TWnshZd#>U?NI)2Tk?uh9?+KY!K;lAqa zE0e?H?sH!q;1t2o_PWuV`J+AqF>kOjKmI|o+U?Phz6%6GLwXugo9mmoEn%5iesywq zG(Y@B*mkMM7L*%f>x`8Ks^+?|H|K)qa9aJYXXc@LX#iVNHwL{qVl8-6u#B0)8*_c^ zjh~H;ZQwr~F_*CK90c1f6T5XAKK7Quu^a9o$zt)4#JgG;~t|2mi~gd+`B{4QxsEXx@rs9j>?n zmWY6w4hZiJY-Ih?K^r;xuNz0|M$qx?6QKjJbMrdfaOJ=@+_-c^w`Dp~bJO5$T>Hms z?$B-E05t7|`_si&f|CTx*e|>{06YC$cz);9x4r?(uxp=?PiSwlFx`aMtFeu}=^h(% z)HeaMdZfnm*P&n-JB9ZKV!m!;-V2z~)?sGnv7p?fn5WHr6YqYs-S=+0IC%SO0M|`| z|4N=d?&07%ERJ*ZIutBprtscC?AFERwuX=z`}p@)AF79n*5TfWP3zFYc2i=vw%@nA z32}8u*(7xB=E>^@N}sAT2zBF%}E&ghty!>cg;=YtHcqZuKN#$GfQ@?l<6NWVCF;gX;k^NH>3giDtM0uW?nr5E zpnvDLAl*u_P+Mv&Oh0Tx((3ZYYD|B135GFKcyAzP(Z;0Jm7@)X?s68CJC{dQo9P+z zYIfWZno6r+Z05s%sm@8EyIhf`65Ztl%a|#=r_D9kGdG?T8gqj^=Ub2IX-cbWJghDW z*q5u$wGdodZMgMfzi!L4QM2Q;LG5q;>DaBh4cu(=*oGQ$Jw%!s%ydA&y@BBUgM&Y? zv+M~CPV0=oX`Km{#&!=A!*v_R@Twi*nOg@&;ve_GLhG&5bHiU~f}?Rg;k|*lI|sw1 zh1R>*fSZ~H>&_E%H9VPHe=BSYEPs%EYQ1>>;?{I_$&sz-1+;Xhhd6L88; zY9EO09xi5TbG4bHDlKR==cZ(}LqJ;*NED5c!h1GQHr;F^{lXv}@x6ga?gBAMo2E_5 zrdNiM4ponR59W#q(EK$b5XLy+y@8O^&kPO5q3Y=GL&Q_e1?LLgh%87qFIH-6eJdMm z$X5X}>eZOVA*#kY;k^)409-v4MmHAkQUzrMv0~|N_cM|(heJm76T!@F$j`- zl-Q&ZjZIarhmj72wZ4a(PmIxn>8}XEF%}B%4ZuzJTe!R;n#OBP6Pj6&?$KhZhBl_A zQ_HPIMk}H&hx3ENGEp_w3GaoV@a9t)Mv@ib?x&6OSA+%W9wXLiXy3Y-HYTlz)+rj( zUlD>~%oN@WVMeYQ#7tNa)y_2RFWoFGAoo}?P8<0a@N~1NdNCZ|O@mRMqIT6_Y=Ch7 zHb6nR;1~mi_Xgs=J{T^=2G!Fwt{G_y)?Fy(YO{TF-x~~;f`dH5@@R{?u~K+%Al$a_ z&`gKkPgQN-fSA6O;3&|t;M_*BPFv|)_shZHu+z~Ff*WxgtYuL*)(P(ognMN$IO=Q< z!QD9soO_&Dr>*p@dvh?jMh~oWYteVJZU^f`-B>5Q7lOl;QksPG)Ln2gr`o@fOvURE z!k;Y^QCV2-@nV`b(U|7c7_i(o0j$}8`D;UzjbXxj1HtMHSQmgr+o^N3EG!Inkr<@0 z$e?lCBcn?3k8vA2k`u~s=Y(#lwpXInYTJ>S_ykchh6wM4Kr-+k>YRxvyE>BNU3Z@# z%=%*n!nh}hEgFt&!Grv0aXI3&+zB}O5Du9mdd3{#y$}w4KIv?PiQEM+UI>QFv0&U2 z#T*T%U6Xa15vC1b%8EQpYSX&N2=(*0oR5aS7t(!&2cJx{Fx@6G zO`GUr?iS3U)sZzbYw+0(VJTYvM-Y|D-c>5Zjm5P+)*X$(SO%7XqQ#b~%F7KV*TBB^HQ#iddq-j3wzghlGBGOQ|`VlhtKx zRd9n41Y?%)UI-D*s;ajT!Q%;)c`#WOMkPBfRCkHksnLBq8!S|HYA4v43+_NPl7e9D z6y6IVVze>T0%SAqN)C0s5GvVep}MDvof_RtyQ-?Gp{T7KV3TSSz?O9lSj&Q9Y!%)c zh*~`uYF`JS_6AYORtwcVO>EWZzOC88P}klGsMRyh6YC_#G%$_$!1R z8CW3}ihH`)rfnn?n%q~J6*9?QA);hV5#AdJ;+Yi^1R*b3Ans1FL|f$dXDLKys{0|h z!}Jf_I7H3ZBD@!Z;TzsE#98)Zyy1Nm+$+f(3&-6h=4i8g$DD~UeF)PYf}zl0 zqL3{Xiu;<_qS1U?u0xbfh|&{8A;*Z8u|;@qAj(n8^e7C{Z)U2=9ep$T7`ku=61pvc`gO|0LFEII@NY`&={FUI>OB~xxO1W0ySfbO5gE^QwHV)xwt4&n7|PL`ML zH^5t>ZtN4@3&Ek&;~inV=1v=r%(L*^zleF-OfnDM=6(<|uNu4S4YW`6jeWv<+D_kp zyV_-9NH?m|Al~MYUS=baJGc_Iz?!;mW6zO%-Z=yflg_eVnzksVX(w!CV}*t15L; zVcQGIb)~Gl^n`LpHNTXc#>)4+6jY|P97W2QWK#g;t)=RVyOUE)%Vp~N-N_nOetvf{ zSK&N7V`xKLZIxO$B~`5!E>1b|9N59BI0S|HH3)S)A(lc!1zM^D{xGyDJ(m-;^(D>d#Y1QQv(ceqm)~t>W@zC$10dDgDSHlg%5M7 zcPd=8x#Yqj>(tySsT>;ZMw>8IhIBI2j3mDt0DU>Au<4-G_%t=7wjGqJVGYiE!B#T; z2{24jT2N!(Lie-jr%DTR8&hr>>ur1*+(s=?l8b^4jaHW~PL;E=M4H|aNhck^~nnuHrCd1TGD)sJw zS;7r-MvULEB)f3KksoMh-0%b4<~}!Ko9qa7#;OzU>Ou`!n0* zOc}pTNrDM)!=r~>L5<-kIInFr4R0HNwlutQ+h;b+X*AUEyD1oX z$&kT@rxt3TPCb=W+oq<{%Gr^6w-lC$`c-#o|0pHMsM_5y%}GmAURZ1XuZ>pq?^Ey6 z!ouX2z`~;3mw>*cv#|c+okqXrEiqhe+o_ir=d@7UbK$Q8T}f9#-CW_ncBfvB7t$xC z>LP(Twf^;V+`;@61sxr&{_%HMB%~{8DgR8DmM0~u*vgWB@-LL*4ke`c4UZiPMoYp8 z>NXTws>**F8-BvCE|WQX+B{8P_?Kns(`@+^wPRYjlkK@~l}KDLPt(1>yqIXUv!-J5 zh*d_jq~r=iU-*}+8D;785X!d<%7uSf&nOF*l}{eA!Dzzym!UtbRqzs~@@a*evgOYt z0^VKolZv=QnK9!U%MVcZ=gOlQ>ZD}8P$w0x*h1B$^64?>Ej8vvsG=yR{>F2si}(on~nCz>zbw2QHlSz#NviV4kMY14wHR_$XHdP_AYa@_^PX zDfyN`K@Sj$c)&+d1_eC;woEI$H(h(c+~mLs@HQ99U;r;1%np$BoPYzG=ajd`hC|xS zKHQDd=4l!`dis3b(FK<~kLiwT8as-#?x@zpq1H4GHK9;PwI+5{)7Vi$!H({+!D!-8 zBZ^9=E5@j=>`}32VgCH`pYlM5yUFQ9em6@vRVdKSM;oD=Bi@WRJfOR&Y3Sy>H&y1@ zijlmp(8T^n#UeATn#SHDO}!ntYMutb-f9|p8v>(FYXI!Drm@omhMgX{!2n>VH5iPp z2HX5r`5x-cnHAqD)SO&C({jPimn-9rKhRB(C+)t=;U{`vMq&F|<@;G7(A@PfJ1Dsc zGJDIXWk^ZVmHxRBWiADjBpKDwM5&qq#U8rREa_s-cXT<6u$II`k6>!<24lv zBWg!Qc}L;7<16c&z}hCm`_r^_HkR+LMs6xE=Ph4yj{Z|jN={NRhk}@rbM&8La&nT7 zxnevFjU*o-<|^E2?=LNQ+scbh_R1L-%Wit=JWaoMCesunjIFrw)OlaNbKtK0@ZV17 z-4gHWW2{2=57buG|{sE^WE;>-2VlP_J5*f z|9?z<{{6oI`+smT72cXNz)N&1@F&i;O5ATaHx8XtSLj?(@yjw=kcD^8sn}dbi_tiF z=?b_jP$r(rtgV=lA$`fM`~3QtaTm}Z%lTxVTc305sC~LCN!lFh&+zXRPw`Pf;a#s{ zeJrr0(ETBYNp%Y5$#}J5eMO4zZjvka`ElY7=F!U@KoPaPhPG#nlpH#>_Q*pn; z55{XME1L=pKd)FHP;@D^$X8rs6nETLId@2*;SUvG8Di8o6i)kN#okufKtW~R!ojRJ zHel!9f(G1BsQa*Df`vdc)Bt3z}z@L(>S zYMfCygE1t#jWHr)DnDUI6b4a;Ssr&V?Jb}#nQTE5me>6g6KJJyq8r)Z;-OCy=My2w zEPtkYL)41%QrikMkFDI{+K~)pxG5Nu@#?LUD^nT5k;Jus2ZyrSY#d2e`*(0Slg+n> zW|(BEAB21 zS}AkCu;OQxU4uzLp#K-_tF#8t8b>qQqomn*Pqi*MWU2-rKsxdx1b91sIUr@Fd>C&9{V%YoQ*Yo zz2TZ)^g<10I~6i-BOIkWq0*Gfq8t&FjDm&rWZPtF4X-|`lQ0<57O5SiMsd$I#*H34^_SOAyzf%s`=`Z zPt&pZ4oCoUF^8uBLaz;pQqm5p&R47EW|9u(;S}ok$y^FupngMDt$I9?*(2&xdwiNU!B$HpZmyr6b3P3>9O5zYKn zf|?y}rn>a*$^TGKq*GJWnn=ctdW2LvF0+q%Ii4AjK_pjlVF*br`yhR6;l@O!;Db2o z{PIkd3rO?cbM}9NkMGk__?2xCG*5D13|eF1fXd86jJ9EqOtphJxb-ZZQC_Xq&j%RH zz<`%1g^bE`=8J(jw(#80uu(Ve=^HhXjp9Cr;f8l$A0^`j;V|3f?#Vwcypzr3`3^qN ztR3&dc{L`jpjk5*Leg9Q4G7p&EeuI!31BEN_QenFa^*QS_X`!~jL5m|!9ki3%I{%gl>jeoEy*5iQ_h-h>EH;sgpD81*m_0($}N za)%GdOi*8%o7q#nGb@vDFu?)Mf=;fPl!-c+2Y{L)^OZVWXqdksLK}O*6N3rmF*`wo zHorNjP;~fum{~gg0EZaU15Y^N@9OwDnduxV!jg2rDFJ=LdIrADar zf7YPzOW<&|WNv2fQD>cj-A7cNgb+j>d8kHRdT6GamS@TQ4+?5$Q+W``VSIj~nA) zD+=MUbvpMTh-5kM(S}SFZEEnVOm)C@KHAC!8AkIY^B{gk50l{}6sI!jDoLQ?yw2J$t(IL-cndYX4)v6Iw*8c%q`A%wJVV zX8Anzi@(Mfw9QQ`OfH!&(psC+nXy5QqVv%u-8rJ}eV4V#kC@sB(puXSUfW=Dt}$s< z{pncjp`}83jM$)7)%mTM=cq1Ph-;BAl6fNP7yYDtP5SsuA$|NF IH*Ea>0I-E9-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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 F@&5;Q6eR!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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 NI+OqK>Dspz|9>JTZ;Su{ delta 112053 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 diff --git a/mods/ITEMS/mcl_armor/player.lua b/mods/ITEMS/mcl_armor/player.lua index 9dba0773c..48fdb381f 100644 --- a/mods/ITEMS/mcl_armor/player.lua +++ b/mods/ITEMS/mcl_armor/player.lua @@ -25,6 +25,8 @@ mcl_player.player_register_model("mcl_armor_character.b3d", { sit_mount = {x=484, y=484}, die = {x=498, y=498}, fly = {x=502, y=581}, + bow_walk = {x=650, y=670}, + bow_sneak = {x=675, y=695}, }, }) @@ -55,6 +57,8 @@ mcl_player.player_register_model("mcl_armor_character_female.b3d", { sit_mount = {x=484, y=484}, die = {x=498, y=498}, fly = {x=502, y=581}, + bow_walk = {x=650, y=670}, + bow_sneak = {x=675, y=695}, }, }) diff --git a/mods/PLAYER/mcl_player/init.lua b/mods/PLAYER/mcl_player/init.lua index 6cf2f0014..a3c769741 100644 --- a/mods/PLAYER/mcl_player/init.lua +++ b/mods/PLAYER/mcl_player/init.lua @@ -212,6 +212,10 @@ 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 + 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 + 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) elseif get_mouse_button(player) == true and not controls.sneak then diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index 1e1354ae0..1f881d2b6 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -51,6 +51,15 @@ local function player_collision(player) return {x,z} end +local function walking_player(player, control) + if control.up or control.down or control.left or control.right then + return true + else + return false + end +end + + -- converts yaw to degrees local function degrees(rad) return rad * 180.0 / math.pi @@ -217,8 +226,9 @@ minetest.register_globalstep(function(dtime) player_velocity_old = player:get_velocity() or player:get_player_velocity() + -- controls right and left arms pitch when shooting a bow - if string.find(wielded:get_name(), "mcl_bows:bow") and control.RMB and not control.LMB and not control.up and not control.down and not control.left and not control.right then + 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)) -- when punching From 549bdeb6e9683e7b28048a56e36089d1e79c8f71 Mon Sep 17 00:00:00 2001 From: NO11 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 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 PuQ;wB&v&o)+~j`)mnpRX 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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 XpT)8tEoFEQw41@x)z4*}Q$iB}no2*M From fe62189019f0ec704396d797d223706eb8b111eb Mon Sep 17 00:00:00 2001 From: AFCMS 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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 literal 0 HcmV?d00001 diff --git a/mods/ITEMS/mcl_bows/models/mcl_bows_rocket.mtl b/mods/ITEMS/mcl_bows/models/mcl_bows_rocket.mtl new file mode 100644 index 000000000..f231bdf4c --- /dev/null +++ b/mods/ITEMS/mcl_bows/models/mcl_bows_rocket.mtl @@ -0,0 +1,10 @@ +# Blender MTL File: 'None' +# Material Count: 1 + +newmtl None +Ns 500 +Ka 0.8 0.8 0.8 +Kd 0.8 0.8 0.8 +Ks 0.8 0.8 0.8 +d 1 +illum 2 diff --git a/mods/ITEMS/mcl_bows/models/mcl_bows_rocket.obj b/mods/ITEMS/mcl_bows/models/mcl_bows_rocket.obj new file mode 100644 index 000000000..e2bd11d34 --- /dev/null +++ b/mods/ITEMS/mcl_bows/models/mcl_bows_rocket.obj @@ -0,0 +1,1016 @@ +# Blender v3.0.0 Alpha OBJ File: '' +# www.blender.org +mtllib mcl_bows_rocket.mtl +o Plane +v -1.414214 -0.063116 0.000000 +v 0.000000 -0.063116 1.414214 +v -0.000000 -0.063116 -1.414214 +v 1.414214 -0.063116 -0.000000 +v -1.414214 -0.062205 0.000000 +v 0.000000 -0.062205 1.414214 +v -0.000000 -0.062205 -1.414214 +v 1.414214 -0.062205 -0.000000 +v -1.414214 -0.060838 0.000000 +v 0.000000 -0.060838 1.414214 +v -0.000000 -0.060838 -1.414214 +v 1.414214 -0.060838 -0.000000 +v -1.414214 -0.059926 0.000000 +v 0.000000 -0.059926 1.414214 +v -0.000000 -0.059926 -1.414214 +v 1.414214 -0.059926 -0.000000 +v -1.414214 -0.058559 0.000000 +v 0.000000 -0.058559 1.414214 +v -0.000000 -0.058559 -1.414214 +v 1.414214 -0.058559 -0.000000 +v -1.414214 -0.057648 0.000000 +v 0.000000 -0.057648 1.414214 +v -0.000000 -0.057648 -1.414214 +v 1.414214 -0.057648 -0.000000 +v -1.414214 -0.056281 0.000000 +v 0.000000 -0.056281 1.414214 +v -0.000000 -0.056281 -1.414214 +v 1.414214 -0.056281 -0.000000 +v -1.414214 -0.055369 0.000000 +v 0.000000 -0.055369 1.414214 +v -0.000000 -0.055369 -1.414214 +v 1.414214 -0.055369 -0.000000 +v -1.414214 -0.054002 0.000000 +v 0.000000 -0.054002 1.414214 +v -0.000000 -0.054002 -1.414214 +v 1.414214 -0.054002 -0.000000 +v -1.414214 -0.053091 0.000000 +v 0.000000 -0.053091 1.414214 +v -0.000000 -0.053091 -1.414214 +v 1.414214 -0.053091 -0.000000 +v -1.414214 -0.051723 0.000000 +v 0.000000 -0.051723 1.414214 +v -0.000000 -0.051723 -1.414214 +v 1.414214 -0.051723 -0.000000 +v -1.414214 -0.050812 0.000000 +v 0.000000 -0.050812 1.414214 +v -0.000000 -0.050812 -1.414214 +v 1.414214 -0.050812 -0.000000 +v -1.414214 -0.049445 0.000000 +v 0.000000 -0.049445 1.414214 +v -0.000000 -0.049445 -1.414214 +v 1.414214 -0.049445 -0.000000 +v -1.414214 -0.048533 0.000000 +v 0.000000 -0.048533 1.414214 +v -0.000000 -0.048533 -1.414214 +v 1.414214 -0.048533 -0.000000 +v -1.414214 -0.047166 0.000000 +v 0.000000 -0.047166 1.414214 +v -0.000000 -0.047166 -1.414214 +v 1.414214 -0.047166 -0.000000 +v -1.414214 -0.046255 0.000000 +v 0.000000 -0.046255 1.414214 +v -0.000000 -0.046255 -1.414214 +v 1.414214 -0.046255 -0.000000 +v -1.414214 -0.044888 0.000000 +v 0.000000 -0.044888 1.414214 +v -0.000000 -0.044888 -1.414214 +v 1.414214 -0.044888 -0.000000 +v -1.414214 -0.043976 0.000000 +v 0.000000 -0.043976 1.414214 +v -0.000000 -0.043976 -1.414214 +v 1.414214 -0.043976 -0.000000 +v -1.414214 -0.042609 0.000000 +v 0.000000 -0.042609 1.414214 +v -0.000000 -0.042609 -1.414214 +v 1.414214 -0.042609 -0.000000 +v -1.414214 -0.041698 0.000000 +v 0.000000 -0.041698 1.414214 +v -0.000000 -0.041698 -1.414214 +v 1.414214 -0.041698 -0.000000 +v -1.414214 -0.040331 0.000000 +v 0.000000 -0.040331 1.414214 +v -0.000000 -0.040331 -1.414214 +v 1.414214 -0.040331 -0.000000 +v -1.414214 -0.039419 0.000000 +v 0.000000 -0.039419 1.414214 +v -0.000000 -0.039419 -1.414214 +v 1.414214 -0.039419 -0.000000 +v -1.414214 -0.038052 0.000000 +v 0.000000 -0.038052 1.414214 +v -0.000000 -0.038052 -1.414214 +v 1.414214 -0.038052 -0.000000 +v -1.414214 -0.037141 0.000000 +v 0.000000 -0.037141 1.414214 +v -0.000000 -0.037141 -1.414214 +v 1.414214 -0.037141 -0.000000 +v -1.414214 -0.035773 0.000000 +v 0.000000 -0.035773 1.414214 +v -0.000000 -0.035773 -1.414214 +v 1.414214 -0.035773 -0.000000 +v -1.414214 -0.034862 0.000000 +v 0.000000 -0.034862 1.414214 +v -0.000000 -0.034862 -1.414214 +v 1.414214 -0.034862 -0.000000 +v -1.414214 -0.033495 0.000000 +v 0.000000 -0.033495 1.414214 +v -0.000000 -0.033495 -1.414214 +v 1.414214 -0.033495 -0.000000 +v -1.414214 -0.032583 0.000000 +v 0.000000 -0.032583 1.414214 +v -0.000000 -0.032583 -1.414214 +v 1.414214 -0.032583 -0.000000 +v -1.414214 -0.031216 0.000000 +v 0.000000 -0.031216 1.414214 +v -0.000000 -0.031216 -1.414214 +v 1.414214 -0.031216 -0.000000 +v -1.414214 -0.030305 0.000000 +v 0.000000 -0.030305 1.414214 +v -0.000000 -0.030305 -1.414214 +v 1.414214 -0.030305 -0.000000 +v -1.414214 -0.028938 0.000000 +v 0.000000 -0.028938 1.414214 +v -0.000000 -0.028938 -1.414214 +v 1.414214 -0.028938 -0.000000 +v -1.414214 -0.028026 0.000000 +v 0.000000 -0.028026 1.414214 +v -0.000000 -0.028026 -1.414214 +v 1.414214 -0.028026 -0.000000 +v -1.414214 -0.026659 0.000000 +v 0.000000 -0.026659 1.414214 +v -0.000000 -0.026659 -1.414214 +v 1.414214 -0.026659 -0.000000 +v -1.414214 -0.025748 0.000000 +v 0.000000 -0.025748 1.414214 +v -0.000000 -0.025748 -1.414214 +v 1.414214 -0.025748 -0.000000 +v -1.414214 -0.024381 0.000000 +v 0.000000 -0.024381 1.414214 +v -0.000000 -0.024381 -1.414214 +v 1.414214 -0.024381 -0.000000 +v -1.414214 -0.023469 0.000000 +v 0.000000 -0.023469 1.414214 +v -0.000000 -0.023469 -1.414214 +v 1.414214 -0.023469 -0.000000 +v -1.414214 -0.022102 0.000000 +v 0.000000 -0.022102 1.414214 +v -0.000000 -0.022102 -1.414214 +v 1.414214 -0.022102 -0.000000 +v -1.414214 -0.021191 0.000000 +v 0.000000 -0.021191 1.414214 +v -0.000000 -0.021191 -1.414214 +v 1.414214 -0.021191 -0.000000 +v -1.414214 -0.019824 0.000000 +v 0.000000 -0.019824 1.414214 +v -0.000000 -0.019824 -1.414214 +v 1.414214 -0.019824 -0.000000 +v -1.414214 -0.018912 0.000000 +v 0.000000 -0.018912 1.414214 +v -0.000000 -0.018912 -1.414214 +v 1.414214 -0.018912 -0.000000 +v -1.414214 -0.017545 0.000000 +v 0.000000 -0.017545 1.414214 +v -0.000000 -0.017545 -1.414214 +v 1.414214 -0.017545 -0.000000 +v -1.414214 -0.016634 0.000000 +v 0.000000 -0.016634 1.414214 +v -0.000000 -0.016634 -1.414214 +v 1.414214 -0.016634 -0.000000 +v -1.414214 -0.015266 0.000000 +v 0.000000 -0.015266 1.414214 +v -0.000000 -0.015266 -1.414214 +v 1.414214 -0.015266 -0.000000 +v -1.414214 -0.014355 0.000000 +v 0.000000 -0.014355 1.414214 +v -0.000000 -0.014355 -1.414214 +v 1.414214 -0.014355 -0.000000 +v -1.414214 -0.012988 0.000000 +v 0.000000 -0.012988 1.414214 +v -0.000000 -0.012988 -1.414214 +v 1.414214 -0.012988 -0.000000 +v -1.414214 -0.012076 0.000000 +v 0.000000 -0.012076 1.414214 +v -0.000000 -0.012076 -1.414214 +v 1.414214 -0.012076 -0.000000 +v -1.414214 -0.010709 0.000000 +v 0.000000 -0.010709 1.414214 +v -0.000000 -0.010709 -1.414214 +v 1.414214 -0.010709 -0.000000 +v -1.414214 -0.009798 0.000000 +v 0.000000 -0.009798 1.414214 +v -0.000000 -0.009798 -1.414214 +v 1.414214 -0.009798 -0.000000 +v -1.414214 -0.008431 0.000000 +v 0.000000 -0.008431 1.414214 +v -0.000000 -0.008431 -1.414214 +v 1.414214 -0.008431 -0.000000 +v -1.414214 -0.007519 0.000000 +v 0.000000 -0.007519 1.414214 +v -0.000000 -0.007519 -1.414214 +v 1.414214 -0.007519 -0.000000 +v -1.414214 -0.006152 0.000000 +v 0.000000 -0.006152 1.414214 +v -0.000000 -0.006152 -1.414214 +v 1.414214 -0.006152 -0.000000 +v -1.414214 -0.005241 0.000000 +v 0.000000 -0.005241 1.414214 +v -0.000000 -0.005241 -1.414214 +v 1.414214 -0.005241 -0.000000 +v -1.414214 -0.003874 0.000000 +v 0.000000 -0.003874 1.414214 +v -0.000000 -0.003874 -1.414214 +v 1.414214 -0.003874 -0.000000 +v -1.414214 -0.002962 0.000000 +v 0.000000 -0.002962 1.414214 +v -0.000000 -0.002962 -1.414214 +v 1.414214 -0.002962 -0.000000 +v -1.414214 -0.001595 0.000000 +v 0.000000 -0.001595 1.414214 +v -0.000000 -0.001595 -1.414214 +v 1.414214 -0.001595 -0.000000 +v -1.414214 -0.000684 0.000000 +v 0.000000 -0.000684 1.414214 +v -0.000000 -0.000684 -1.414214 +v 1.414214 -0.000684 -0.000000 +v -1.414214 0.000684 0.000000 +v 0.000000 0.000684 1.414214 +v -0.000000 0.000684 -1.414214 +v 1.414214 0.000684 -0.000000 +v -1.414214 0.001595 0.000000 +v 0.000000 0.001595 1.414214 +v -0.000000 0.001595 -1.414214 +v 1.414214 0.001595 -0.000000 +v -1.414214 0.002962 0.000000 +v 0.000000 0.002962 1.414214 +v -0.000000 0.002962 -1.414214 +v 1.414214 0.002962 -0.000000 +v -1.414214 0.003874 0.000000 +v 0.000000 0.003874 1.414214 +v -0.000000 0.003874 -1.414214 +v 1.414214 0.003874 -0.000000 +v -1.414214 0.005241 0.000000 +v 0.000000 0.005241 1.414214 +v -0.000000 0.005241 -1.414214 +v 1.414214 0.005241 -0.000000 +v -1.414214 0.006152 0.000000 +v 0.000000 0.006152 1.414214 +v -0.000000 0.006152 -1.414214 +v 1.414214 0.006152 -0.000000 +v -1.414214 0.007519 0.000000 +v 0.000000 0.007519 1.414214 +v -0.000000 0.007519 -1.414214 +v 1.414214 0.007519 -0.000000 +v -1.414214 0.008431 0.000000 +v 0.000000 0.008431 1.414214 +v -0.000000 0.008431 -1.414214 +v 1.414214 0.008431 -0.000000 +v -1.414214 0.009798 0.000000 +v 0.000000 0.009798 1.414214 +v -0.000000 0.009798 -1.414214 +v 1.414214 0.009798 -0.000000 +v -1.414214 0.010709 0.000000 +v 0.000000 0.010709 1.414214 +v -0.000000 0.010709 -1.414214 +v 1.414214 0.010709 -0.000000 +v -1.414214 0.012076 0.000000 +v 0.000000 0.012076 1.414214 +v -0.000000 0.012076 -1.414214 +v 1.414214 0.012076 -0.000000 +v -1.414214 0.012988 0.000000 +v 0.000000 0.012988 1.414214 +v -0.000000 0.012988 -1.414214 +v 1.414214 0.012988 -0.000000 +v -1.414214 0.014355 0.000000 +v 0.000000 0.014355 1.414214 +v -0.000000 0.014355 -1.414214 +v 1.414214 0.014355 -0.000000 +v -1.414214 0.015266 0.000000 +v 0.000000 0.015266 1.414214 +v -0.000000 0.015266 -1.414214 +v 1.414214 0.015266 -0.000000 +v -1.414214 0.016634 0.000000 +v 0.000000 0.016634 1.414214 +v -0.000000 0.016634 -1.414214 +v 1.414214 0.016634 -0.000000 +v -1.414214 0.017545 0.000000 +v 0.000000 0.017545 1.414214 +v -0.000000 0.017545 -1.414214 +v 1.414214 0.017545 -0.000000 +v -1.414214 0.018912 0.000000 +v 0.000000 0.018912 1.414214 +v -0.000000 0.018912 -1.414214 +v 1.414214 0.018912 -0.000000 +v -1.414214 0.019824 0.000000 +v 0.000000 0.019824 1.414214 +v -0.000000 0.019824 -1.414214 +v 1.414214 0.019824 -0.000000 +v -1.414214 0.021191 0.000000 +v 0.000000 0.021191 1.414214 +v -0.000000 0.021191 -1.414214 +v 1.414214 0.021191 -0.000000 +v -1.414214 0.022102 0.000000 +v 0.000000 0.022102 1.414214 +v -0.000000 0.022102 -1.414214 +v 1.414214 0.022102 -0.000000 +v -1.414214 0.023469 0.000000 +v 0.000000 0.023469 1.414214 +v -0.000000 0.023469 -1.414214 +v 1.414214 0.023469 -0.000000 +v -1.414214 0.024381 0.000000 +v 0.000000 0.024381 1.414214 +v -0.000000 0.024381 -1.414214 +v 1.414214 0.024381 -0.000000 +v -1.414214 0.025748 0.000000 +v 0.000000 0.025748 1.414214 +v -0.000000 0.025748 -1.414214 +v 1.414214 0.025748 -0.000000 +v -1.414214 0.026659 0.000000 +v 0.000000 0.026659 1.414214 +v -0.000000 0.026659 -1.414214 +v 1.414214 0.026659 -0.000000 +v -1.414214 0.028026 0.000000 +v 0.000000 0.028026 1.414214 +v -0.000000 0.028026 -1.414214 +v 1.414214 0.028026 -0.000000 +v -1.414214 0.028938 0.000000 +v 0.000000 0.028938 1.414214 +v -0.000000 0.028938 -1.414214 +v 1.414214 0.028938 -0.000000 +v -1.414214 0.030305 0.000000 +v 0.000000 0.030305 1.414214 +v -0.000000 0.030305 -1.414214 +v 1.414214 0.030305 -0.000000 +v -1.414214 0.031216 0.000000 +v 0.000000 0.031216 1.414214 +v -0.000000 0.031216 -1.414214 +v 1.414214 0.031216 -0.000000 +v -1.414214 0.032584 0.000000 +v 0.000000 0.032584 1.414214 +v -0.000000 0.032584 -1.414214 +v 1.414214 0.032584 -0.000000 +v -1.414214 0.033495 0.000000 +v 0.000000 0.033495 1.414214 +v -0.000000 0.033495 -1.414214 +v 1.414214 0.033495 -0.000000 +v -1.414214 0.034862 0.000000 +v 0.000000 0.034862 1.414214 +v -0.000000 0.034862 -1.414214 +v 1.414214 0.034862 -0.000000 +v -1.414214 0.035774 0.000000 +v 0.000000 0.035774 1.414214 +v -0.000000 0.035774 -1.414214 +v 1.414214 0.035774 -0.000000 +v -1.414214 0.037141 0.000000 +v 0.000000 0.037141 1.414214 +v -0.000000 0.037141 -1.414214 +v 1.414214 0.037141 -0.000000 +v -1.414214 0.038052 0.000000 +v 0.000000 0.038052 1.414214 +v -0.000000 0.038052 -1.414214 +v 1.414214 0.038052 -0.000000 +v -1.414214 0.039419 0.000000 +v 0.000000 0.039419 1.414214 +v -0.000000 0.039419 -1.414214 +v 1.414214 0.039419 -0.000000 +v -1.414214 0.040331 0.000000 +v 0.000000 0.040331 1.414214 +v -0.000000 0.040331 -1.414214 +v 1.414214 0.040331 -0.000000 +v -1.414214 0.041698 0.000000 +v 0.000000 0.041698 1.414214 +v -0.000000 0.041698 -1.414214 +v 1.414214 0.041698 -0.000000 +v -1.414214 0.042609 0.000000 +v 0.000000 0.042609 1.414214 +v -0.000000 0.042609 -1.414214 +v 1.414214 0.042609 -0.000000 +v -1.414214 0.043976 0.000000 +v 0.000000 0.043976 1.414214 +v -0.000000 0.043976 -1.414214 +v 1.414214 0.043976 -0.000000 +v -1.414214 0.044888 0.000000 +v 0.000000 0.044888 1.414214 +v -0.000000 0.044888 -1.414214 +v 1.414214 0.044888 -0.000000 +v -1.414214 0.046255 0.000000 +v 0.000000 0.046255 1.414214 +v -0.000000 0.046255 -1.414214 +v 1.414214 0.046255 -0.000000 +v -1.414214 0.047166 0.000000 +v 0.000000 0.047166 1.414214 +v -0.000000 0.047166 -1.414214 +v 1.414214 0.047166 -0.000000 +v -1.414214 0.048533 0.000000 +v 0.000000 0.048533 1.414214 +v -0.000000 0.048533 -1.414214 +v 1.414214 0.048533 -0.000000 +v -1.414214 0.049445 0.000000 +v 0.000000 0.049445 1.414214 +v -0.000000 0.049445 -1.414214 +v 1.414214 0.049445 -0.000000 +v -1.414214 0.050812 0.000000 +v 0.000000 0.050812 1.414214 +v -0.000000 0.050812 -1.414214 +v 1.414214 0.050812 -0.000000 +v -1.414214 0.051723 0.000000 +v 0.000000 0.051723 1.414214 +v -0.000000 0.051723 -1.414214 +v 1.414214 0.051723 -0.000000 +v -1.414214 0.053091 0.000000 +v 0.000000 0.053091 1.414214 +v -0.000000 0.053091 -1.414214 +v 1.414214 0.053091 -0.000000 +v -1.414214 0.054002 0.000000 +v 0.000000 0.054002 1.414214 +v -0.000000 0.054002 -1.414214 +v 1.414214 0.054002 -0.000000 +v -1.414214 0.055369 0.000000 +v 0.000000 0.055369 1.414214 +v -0.000000 0.055369 -1.414214 +v 1.414214 0.055369 -0.000000 +v -1.414214 0.056281 0.000000 +v 0.000000 0.056281 1.414214 +v -0.000000 0.056281 -1.414214 +v 1.414214 0.056281 -0.000000 +v -1.414214 0.057648 0.000000 +v 0.000000 0.057648 1.414214 +v -0.000000 0.057648 -1.414214 +v 1.414214 0.057648 -0.000000 +v -1.414214 0.058559 0.000000 +v 0.000000 0.058559 1.414214 +v -0.000000 0.058559 -1.414214 +v 1.414214 0.058559 -0.000000 +v -1.414214 0.059926 0.000000 +v 0.000000 0.059926 1.414214 +v -0.000000 0.059926 -1.414214 +v 1.414214 0.059926 -0.000000 +v -1.414214 0.060838 0.000000 +v 0.000000 0.060838 1.414214 +v -0.000000 0.060838 -1.414214 +v 1.414214 0.060838 -0.000000 +v -1.414214 0.062205 0.000000 +v 0.000000 0.062205 1.414214 +v -0.000000 0.062205 -1.414214 +v 1.414214 0.062205 -0.000000 +v -1.414214 0.063116 0.000000 +v 0.000000 0.063116 1.414214 +v -0.000000 0.063116 -1.414214 +v 1.414214 0.063116 -0.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +usemtl None +s off +f 1/1/1 3/2/1 4/3/1 2/4/1 +f 5/5/2 6/6/2 8/7/2 7/8/2 +f 9/9/1 11/10/1 12/11/1 10/12/1 +f 13/13/2 14/14/2 16/15/2 15/16/2 +f 17/17/1 19/18/1 20/19/1 18/20/1 +f 21/21/2 22/22/2 24/23/2 23/24/2 +f 25/25/1 27/26/1 28/27/1 26/28/1 +f 29/29/2 30/30/2 32/31/2 31/32/2 +f 33/33/1 35/34/1 36/35/1 34/36/1 +f 37/37/2 38/38/2 40/39/2 39/40/2 +f 41/41/1 43/42/1 44/43/1 42/44/1 +f 45/45/2 46/46/2 48/47/2 47/48/2 +f 49/49/1 51/50/1 52/51/1 50/52/1 +f 53/53/2 54/54/2 56/55/2 55/56/2 +f 57/57/1 59/58/1 60/59/1 58/60/1 +f 61/61/2 62/62/2 64/63/2 63/64/2 +f 65/65/1 67/66/1 68/67/1 66/68/1 +f 69/69/2 70/70/2 72/71/2 71/72/2 +f 73/73/1 75/74/1 76/75/1 74/76/1 +f 77/77/2 78/78/2 80/79/2 79/80/2 +f 81/81/1 83/82/1 84/83/1 82/84/1 +f 85/85/2 86/86/2 88/87/2 87/88/2 +f 89/89/1 91/90/1 92/91/1 90/92/1 +f 93/93/2 94/94/2 96/95/2 95/96/2 +f 97/97/1 99/98/1 100/99/1 98/100/1 +f 101/101/2 102/102/2 104/103/2 103/104/2 +f 105/105/1 107/106/1 108/107/1 106/108/1 +f 109/109/2 110/110/2 112/111/2 111/112/2 +f 113/113/1 115/114/1 116/115/1 114/116/1 +f 117/117/2 118/118/2 120/119/2 119/120/2 +f 121/121/1 123/122/1 124/123/1 122/124/1 +f 125/125/2 126/126/2 128/127/2 127/128/2 +f 129/129/1 131/130/1 132/131/1 130/132/1 +f 133/133/2 134/134/2 136/135/2 135/136/2 +f 137/137/1 139/138/1 140/139/1 138/140/1 +f 141/141/2 142/142/2 144/143/2 143/144/2 +f 145/145/1 147/146/1 148/147/1 146/148/1 +f 149/149/2 150/150/2 152/151/2 151/152/2 +f 153/153/1 155/154/1 156/155/1 154/156/1 +f 157/157/2 158/158/2 160/159/2 159/160/2 +f 161/161/1 163/162/1 164/163/1 162/164/1 +f 165/165/2 166/166/2 168/167/2 167/168/2 +f 169/169/1 171/170/1 172/171/1 170/172/1 +f 173/173/2 174/174/2 176/175/2 175/176/2 +f 177/177/1 179/178/1 180/179/1 178/180/1 +f 181/181/2 182/182/2 184/183/2 183/184/2 +f 185/185/1 187/186/1 188/187/1 186/188/1 +f 189/189/2 190/190/2 192/191/2 191/192/2 +f 193/193/1 195/194/1 196/195/1 194/196/1 +f 197/197/2 198/198/2 200/199/2 199/200/2 +f 201/201/1 203/202/1 204/203/1 202/204/1 +f 205/205/2 206/206/2 208/207/2 207/208/2 +f 209/209/1 211/210/1 212/211/1 210/212/1 +f 213/213/2 214/214/2 216/215/2 215/216/2 +f 217/217/1 219/218/1 220/219/1 218/220/1 +f 221/221/2 222/222/2 224/223/2 223/224/2 +f 225/225/1 227/226/1 228/227/1 226/228/1 +f 229/229/2 230/230/2 232/231/2 231/232/2 +f 233/233/1 235/234/1 236/235/1 234/236/1 +f 237/237/2 238/238/2 240/239/2 239/240/2 +f 241/241/1 243/242/1 244/243/1 242/244/1 +f 245/245/2 246/246/2 248/247/2 247/248/2 +f 249/249/1 251/250/1 252/251/1 250/252/1 +f 253/253/2 254/254/2 256/255/2 255/256/2 +f 257/257/1 259/258/1 260/259/1 258/260/1 +f 261/261/2 262/262/2 264/263/2 263/264/2 +f 265/265/1 267/266/1 268/267/1 266/268/1 +f 269/269/2 270/270/2 272/271/2 271/272/2 +f 273/273/1 275/274/1 276/275/1 274/276/1 +f 277/277/2 278/278/2 280/279/2 279/280/2 +f 281/281/1 283/282/1 284/283/1 282/284/1 +f 285/285/2 286/286/2 288/287/2 287/288/2 +f 289/289/1 291/290/1 292/291/1 290/292/1 +f 293/293/2 294/294/2 296/295/2 295/296/2 +f 297/297/1 299/298/1 300/299/1 298/300/1 +f 301/301/2 302/302/2 304/303/2 303/304/2 +f 305/305/1 307/306/1 308/307/1 306/308/1 +f 309/309/2 310/310/2 312/311/2 311/312/2 +f 313/313/1 315/314/1 316/315/1 314/316/1 +f 317/317/2 318/318/2 320/319/2 319/320/2 +f 321/321/1 323/322/1 324/323/1 322/324/1 +f 325/325/2 326/326/2 328/327/2 327/328/2 +f 329/329/1 331/330/1 332/331/1 330/332/1 +f 333/333/2 334/334/2 336/335/2 335/336/2 +f 337/337/1 339/338/1 340/339/1 338/340/1 +f 341/341/2 342/342/2 344/343/2 343/344/2 +f 345/345/1 347/346/1 348/347/1 346/348/1 +f 349/349/2 350/350/2 352/351/2 351/352/2 +f 353/353/1 355/354/1 356/355/1 354/356/1 +f 357/357/2 358/358/2 360/359/2 359/360/2 +f 361/361/1 363/362/1 364/363/1 362/364/1 +f 365/365/2 366/366/2 368/367/2 367/368/2 +f 369/369/1 371/370/1 372/371/1 370/372/1 +f 373/373/2 374/374/2 376/375/2 375/376/2 +f 377/377/1 379/378/1 380/379/1 378/380/1 +f 381/381/2 382/382/2 384/383/2 383/384/2 +f 385/385/1 387/386/1 388/387/1 386/388/1 +f 389/389/2 390/390/2 392/391/2 391/392/2 +f 393/393/1 395/394/1 396/395/1 394/396/1 +f 397/397/2 398/398/2 400/399/2 399/400/2 +f 401/401/1 403/402/1 404/403/1 402/404/1 +f 405/405/2 406/406/2 408/407/2 407/408/2 +f 409/409/1 411/410/1 412/411/1 410/412/1 +f 413/413/2 414/414/2 416/415/2 415/416/2 +f 417/417/1 419/418/1 420/419/1 418/420/1 +f 421/421/2 422/422/2 424/423/2 423/424/2 +f 425/425/1 427/426/1 428/427/1 426/428/1 +f 429/429/2 430/430/2 432/431/2 431/432/2 +f 433/433/1 435/434/1 436/435/1 434/436/1 +f 437/437/2 438/438/2 440/439/2 439/440/2 +f 441/441/1 443/442/1 444/443/1 442/444/1 +f 445/445/2 446/446/2 448/447/2 447/448/2 diff --git a/mods/ITEMS/mcl_bows/rocket.lua b/mods/ITEMS/mcl_bows/rocket.lua new file mode 100644 index 000000000..678aba4d4 --- /dev/null +++ b/mods/ITEMS/mcl_bows/rocket.lua @@ -0,0 +1,706 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +local math = math +local vector = vector + +-- Time in seconds after which a stuck arrow is deleted +local ARROW_TIMEOUT = 1 +-- Time after which stuck arrow is rechecked for being stuck +local STUCK_RECHECK_TIME = 0.1 + +--local GRAVITY = 9.81 + +local YAW_OFFSET = -math.pi/2 + +local function dir_to_pitch(dir) + --local dir2 = vector.normalize(dir) + local xz = math.abs(dir.x) + math.abs(dir.z) + return -math.atan2(-dir.y, xz) +end + +local function random_arrow_positions(positions, placement) + if positions == "x" then + return math.random(-4, 4) + elseif positions == "y" then + return math.random(0, 10) + end + if placement == "front" and positions == "z" then + return 3 + elseif placement == "back" and positions == "z" then + return -3 + end + return 0 +end + +local function damage_explosion(self, damagemulitplier) + mcl_explosions.explode(self.object:get_pos(), 3, {}) + local objects = minetest.get_objects_inside_radius(self.object:get_pos(), 8) + for _,obj in pairs(objects) do + if obj:is_player() then + mcl_util.deal_damage(obj, damagemulitplier - vector.distance(self.object:get_pos(), obj:get_pos()), {type = "explosion"}) + elseif obj:get_luaentity()._cmi_is_mob then + obj:punch(self.object, 1.0, { + full_punch_interval=1.0, + damage_groups={fleshy=damagemulitplier - vector.distance(self.object:get_pos(), obj:get_pos())}, + }, self.object:get_velocity()) + end + end +end + +local function particle_explosion(self) + local particle_pattern = math.random(1, 3) + local fpitch = 0 + local true_type = "" + local type = math.random(1,2) + local size = math.random(1,3) + local colors = {"red", "yellow", "blue", "green", "white"} + local this_colors = {colors[math.random(#colors)], colors[math.random(#colors)], colors[math.random(#colors)]} + + if size == 1 then + fpitch = math.random(200, 300) + elseif size == 2 then + fpitch = math.random(100, 130) + else + fpitch = math.random(60, 70) + end + + if type == 1 then + true_type = "Popper" + else + true_type = "Floof" + end + + if type == 1 then + minetest.sound_play("mcl_bows_firework", { + pos = self.object:get_pos(), + max_hear_distance = 100, + gain = 3.0, + pitch = fpitch/100 + }, true) + else + minetest.sound_play("mcl_bows_firework_soft", { + pos = self.object:get_pos(), + max_hear_distance = 100, + gain = 4.0, + pitch = fpitch/100 + }, true) + end + + if particle_pattern == 1 then + minetest.add_particlespawner({ + amount = 400 * size, + time = 0.0001, + minpos = self.object:get_pos(), + maxpos = self.object:get_pos(), + minvel = vector.new(-7 * size,-7 * size,-7 * size), + maxvel = vector.new(7 * size,7 * size,7 * size), + minexptime = .6 * size / 2, + maxexptime = .9 * size / 2, + minsize = 2 * size, + maxsize = 3 * size, + collisiondetection = false, + vertical = false, + texture = "mcl_bows_firework_"..this_colors[1]..".png", + glow = 14, + }) + minetest.add_particlespawner({ + amount = 400 * size, + time = 0.0001, + minpos = self.object:get_pos(), + maxpos = self.object:get_pos(), + minvel = vector.new(-2 * size,-2 * size,-2 * size), + maxvel = vector.new(2 * size,2 * size,2 * size), + minexptime = .6 * size / 2, + maxexptime = .9 * size / 2, + minsize = 2 * size, + maxsize = 3 * size, + collisiondetection = false, + vertical = false, + texture = "mcl_bows_firework_"..this_colors[2]..".png", + glow = 14, + }) + minetest.add_particlespawner({ + amount = 100 * size, + time = 0.0001, + minpos = self.object:get_pos(), + maxpos = self.object:get_pos(), + minvel = vector.new(-14 * size,-14 * size,-14 * size), + maxvel = vector.new(14 * size,14 * size,14 * size), + minexptime = .6 * size / 2, + maxexptime = .9 * size / 2, + minsize = 2 * size, + maxsize = 3 * size, + collisiondetection = false, + vertical = false, + texture = "mcl_bows_firework_"..this_colors[3]..".png", + glow = 14, + }) + elseif particle_pattern == 2 then + + minetest.add_particlespawner({ + amount = 240 * size, + time = 0.0001, + minpos = self.object:get_pos(), + maxpos = self.object:get_pos(), + minvel = vector.new(-5 * size,-5 * size,-5 * size), + maxvel = vector.new(5 * size,5 * size,5 * size), + minexptime = .6 * size / 2, + maxexptime = .9 * size / 2, + minsize = 2 * size, + maxsize = 3 * size, + collisiondetection = false, + vertical = false, + texture = "mcl_bows_firework_"..this_colors[1]..".png", + glow = 14, + }) + minetest.add_particlespawner({ + amount = 500 * size, + time = 0.0001, + minpos = self.object:get_pos(), + maxpos = self.object:get_pos(), + minvel = vector.new(-2 * size,-2 * size,-2 * size), + maxvel = vector.new(2 * size,2 * size,2 * size), + minexptime = .6 * size / 2, + maxexptime = .9 * size / 2, + minsize = 2 * size, + maxsize = 3 * size, + collisiondetection = false, + vertical = false, + texture = "mcl_bows_firework_"..this_colors[2]..".png", + glow = 14, + }) + minetest.add_particlespawner({ + amount = 350 * size, + time = 0.0001, + minpos = self.object:get_pos(), + maxpos = self.object:get_pos(), + minvel = vector.new(-3 * size,-3 * size,-3 * size), + maxvel = vector.new(3 * size,3 * size,3 * size), + minexptime = .6 * size / 2, + maxexptime = .9 * size / 2, + minsize = 2 * size, + maxsize = 3 * size, + collisiondetection = false, + vertical = false, + texture = "mcl_bows_firework_"..this_colors[3]..".png", + glow = 14, + }) + elseif particle_pattern == 3 then + + minetest.add_particlespawner({ + amount = 400 * size, + time = 0.0001, + minpos = self.object:get_pos(), + maxpos = self.object:get_pos(), + minvel = vector.new(-6 * size,-4 * size,-6 * size), + maxvel = vector.new(6 * size,4 * size,6 * size), + minexptime = .6 * size, + maxexptime = .9 * size, + minsize = 2 * size, + maxsize = 3 * size, + collisiondetection = false, + vertical = false, + texture = "mcl_bows_firework_"..this_colors[1]..".png", + glow = 14, + }) + minetest.add_particlespawner({ + amount = 120 * size, + time = 0.0001, + minpos = self.object:get_pos(), + maxpos = self.object:get_pos(), + minvel = vector.new(-8 * size,6 * size,-8 * size), + maxvel = vector.new(8 * size,6 * size,8 * size), + minexptime = .6 * size, + maxexptime = .9 * size, + minsize = 2 * size, + maxsize = 3 * size, + collisiondetection = false, + vertical = false, + texture = "mcl_bows_firework_"..this_colors[2]..".png", + glow = 14, + }) + minetest.add_particlespawner({ + amount = 130 * size, + time = 0.0001, + minpos = self.object:get_pos(), + maxpos = self.object:get_pos(), + minvel = vector.new(-3 * size,3 * size,-3 * size), + maxvel = vector.new(3 * size,3 * size,3 * size), + minexptime = .6 * size, + maxexptime = .9 * size, + minsize = 2 * size, + maxsize = 3 * size, + collisiondetection = false, + vertical = false, + texture = "mcl_bows_firework_"..this_colors[3]..".png", + glow = 14, + }) + end + + return size + +end + +local mod_awards = minetest.get_modpath("awards") and minetest.get_modpath("mcl_achievements") +local mod_button = minetest.get_modpath("mesecons_button") + +minetest.register_craftitem("mcl_bows:rocket", { + description = S("Arrow"), + _tt_help = S("Ammunition").."\n"..S("Damage from bow: 1-10").."\n"..S("Damage from dispenser: 3"), + _doc_items_longdesc = S("Arrows are ammunition for bows and dispensers.").."\n".. +S("An arrow fired from a bow has a regular damage of 1-9. At full charge, there's a 20% chance of a critical hit dealing 10 damage instead. An arrow fired from a dispenser always deals 3 damage.").."\n".. +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_rocket.png", + groups = { ammo=1, ammo_crossbow=1, ammo_bow_regular=1 }, + _on_dispense = function(itemstack, dispenserpos, droppos, dropnode, dropdir) + -- Shoot arrow + local shootpos = vector.add(dispenserpos, vector.multiply(dropdir, 0.51)) + local yaw = math.atan2(dropdir.z, dropdir.x) + YAW_OFFSET + mcl_bows.shoot_arrow(itemstack:get_name(), shootpos, dropdir, yaw, nil, 19, 3) + end, +}) + + + +local ARROW_ENTITY={ + physical = true, + pointable = false, + visual = "mesh", + mesh = "mcl_bows_rocket.obj", + visual_size = {x=2.5, y=2.5}, + textures = {"mcl_bows_rocket.png"}, + collisionbox = {-0.19, -0.125, -0.19, 0.19, 0.125, 0.19}, + collide_with_objects = false, + _fire_damage_resistant = true, + + _lastpos={}, + _startpos=nil, + _damage=1, -- Damage on impact + _is_critical=false, -- Whether this arrow would deal critical damage + _stuck=false, -- Whether arrow is stuck + _fuse=nil,-- Amount of time (in seconds) the arrow has been stuck so far + _fuserechecktimer=nil,-- An additional timer for periodically re-checking the stuck status of an arrow + _stuckin=nil, --Position of node in which arow is stuck. + _shooter=nil, -- ObjectRef of player or mob who shot it + _is_arrow = true, + + _viscosity=0, -- Viscosity of node the arrow is currently in + _deflection_cooloff=0, -- Cooloff timer after an arrow deflection, to prevent many deflections in quick succession +} + +-- Destroy arrow entity self at pos and drops it as an item +local function spawn_item(self, pos) + if not minetest.is_creative_enabled("") then + local item = minetest.add_item(pos, "mcl_bows:rocket") + item:set_velocity({x=0, y=0, z=0}) + item:set_yaw(self.object:get_yaw()) + end + mcl_burning.extinguish(self.object) + self.object:remove() +end + +local function damage_particles(pos, is_critical) + if is_critical then + minetest.add_particlespawner({ + amount = 15, + 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.1, y=-0.1, z=-0.1}, + maxvel = {x=0.1, y=0.1, z=0.1}, + minacc = {x=0, y=0, z=0}, + maxacc = {x=0, y=0, z=0}, + minexptime = 1, + maxexptime = 2, + minsize = 1.5, + maxsize = 1.5, + collisiondetection = false, + vertical = false, + texture = "mcl_particles_crit.png^[colorize:#bc7a57:127", + }) + end +end + +function ARROW_ENTITY.on_step(self, dtime) + mcl_burning.tick(self.object, dtime, self) + + self._time_in_air = self._time_in_air + .001 + + + local pos = self.object:get_pos() + local dpos = table.copy(pos) -- digital pos + dpos = vector.round(dpos) + local node = minetest.get_node(dpos) + + if not self._fuse then + self._fuse = 0 + end + if not self._fuserechecktimer then + self._fuserechecktimer = 0 + end + + self._fuse = self._fuse + dtime + self._fuserechecktimer = self._fuserechecktimer + dtime + + if self._fuse > 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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

f;m2@iI ztJo@xF)sVv`JDo6XF9M_bb=zg>u-f(Ae;ZO(R#G zw;zmmjf9gkIjN3(NL`Dv?jjd`MWe_D?mp2MTMG2)Ll0m1(6;eytqnG&9M~PcjZs9z zA6Qz1`qDFr+Y+xDZnIaGJl@l$OdKd2n4bEQk65!4)5ZaC-z=I%PP$}uUXo_niwoPY6~+})g;CMdP7>25e#@gs)?uXc30)lYUp)J(nn$(CT;24{3_Ew?3p7vQDi7j*NHptT9>J zYJLTEl?f8V)#kH`F)~xxBRW;>7POYq22PxldBcWox3_4po*dy)L6$_+u}p|Ef?5Ks z+nZb@DO3bO*+fK!6EWaN-HL5tpmO$fZ{#DAWx9=YNuo$8d`^Hev+^zs(!stbS+|M@ zSU2hqRw{G+CFrPLcHFwNZx#PMz8ITqDyVNa zgb<;0p43~DxV#DD`nEZXC;nk#4(P)3BSV&QNq`=LA7Tv+*V@T$EoPN(OZ6PGW~~c~ z`lC>c>;z~*5PZf&g_0HiiXD5&a1%sL7{0Xtm!L0H5Flh2+G*E;iYN3+WHu4g48?jQT#|C-gk zqbR(rH28EceKK-TDdzD7Q=fBDN%IWDm0}kehy|_twQkUnxQk2HCsQ>OpnODy5M)*a zRxFbB+bEu)Ap+j&LU!mnP7Rvq^!!#Y+!{ezlKx5yDklxFST9FdIzL*{6`=y2hGR!n zdLDSoAIB|;DFg!YJ`mNss2t#-Npg998b`LzwwA$Ns-&nLbdA)Z=W*fb1!e%{+tbpN z+RH7CD#i(!HPiWFFyqX7^Qj}GD*4y1-a?5=U_Y-Ni{>37Bps~eRt-jiIx+=veeDW znFZ9|gUO#bZFhAW@*1;NUOfQVDa*VwoZo@lY1p|eS4dN6OMb9+hko~jkL^*Gr}G<| zk*6QVNsIQpuW_W1=Y6hoQPn^Ay5aAZ;VVe_p6>jz{xcPWm+85Al6j^{ZnG|cm;ntz zu_DI^1rab%ARJ5Q3+uHXv(&q*J1k?EDi!TXtp+?^ga;D5;@?WiRwjcrUCK`CtP>rt zc<52r?1BR9duIr)jB);u^vDR`Cxn)_^Xn0~@Vux^e3Qk!pvk0pSK@0cBuo|sG4$S5 z%VGeup>~(KA<|&LZ^DfV^o&-6!0m;B@M?RAf_+tA$97D@IJj_wP6qTrLPl&q@Ol-b zqDf3&Sy~Xmee~6JU)OEvL(YBaBLk@7pAq%|x(=QfItB0Gzsmj6na2hX6xu)d$ZX^J}HTUN6ovMTPGd|D4A9X8TJ`tU4 z7wvypk!`11TH=^p6t|GQHcFY-@&bDp!NY1Q!@u(-aQRhrn@i(Y>2O2Q?8kfso;mM2 z4DYgV`@gdDEG7;x>CbHM<7;qXg`=4Sg4oC~p(X7$lX3l4#h;=9Cnms=L08cXp!`;X zOfyaT;1tS0`Pkq8yo8361lC)zEUCJtWQWTt{r&@n9ha7;rPXZWyhL|rtk0L_EO9Wu zHH;IIAsvh5@PP|x3^ikkw$tk9nylo=;6!|MnIsTE0-&?iUx64FgO}kh#5wy5m0A4l z9#!1lEh-<~x_xGPrNKM$UX`2xT4)52fn7Dp9)%M;fBuTBsTBu}UobSNlA$NZ64DiV zh@jUM8BrB?Zd9r|ksoa%jjDIGiSY4$2TixE;DrDatB(0e ztgKa$a;NDZHLugn;rEu&G{^2&HlN62W(rPX1INE*Ez5B&cOB2te!T92S$vaq{hPiw z)3Nl10M{L(LXx`$-0vRy(eIX$rJcNg#|!};xD-u%9B>^i>@+j0Z4>7tbR}Y6)D;a6 zw&yf3-#XMEN%A1?o0-571(9YiDs@QinoXrBp9F>W^`Jh67IY|vx;rFn{`!?a8;nk% zzOY1Q>3IIt68-mI4SB(rVlG_GtZmD_MSVxToI`lPR7F)~)1 z<7xim8Ra6sOA$Y2?|2K6sz)Phpx~(AeGaa#Nw^=#MtR7rlii--BHq z9)I~s%@$|5JP_0X>|AaGDW@ZN&oi@3rn(-$nuTCw>Cww8%qx@IIM z;i(sJWwm=Va8eS=ToW$<5E+(Tef#Zod^^8=h^Tq*>urpPLujhV^Ii)(c#r&{_}w%H zlUp@qJ0cBtJz#GMCDencHLRr8<@%8OULB^)>`J$Xy}EYzh35!eoaU8Ma<>Vy_k&)R zM0cgkQw_&w=9EefeY`B=Y{a<6x}L|MXpdGvJj%bKn^yAlsl%1*Ud*HxkrM?4f@o*W z=1A9LXp8EgD@D2#-wz&y2%C@tyss(9YJ$9NKNVp}ZfooK5OEAlhxs@cLsEDNfe;T7 zo_J}zbI9o3bZRHX8}8FQDWj)RH%{5iB+);q0XmM_jq*aj*0*-cvc9NP9^ShE;9n~D zCEs8r`ebTwf6d}U?(N7>4bq2K+S_PTJMb}U#*0ndACfN`$ZZT8cDH>=6nRh-*l&+J zpLE-b8SP-@h(jr8y`-l@cjZ6Z58&d+;A5w^L+eQ(XGYxOM2n-zYS>9bfK*SCJuIE+ ziw*(ap{BB$u^AV|djry!{bwq4wPW^T{ECsIwzF@2EEgwib8Y!6!=%v(^)}Bt_;NOh zx7-=bqv&@ND$8mR6vsFvNDPu`ORIk045n+le?LFzT&0ZBV;LP-ySo-6X^4k`o1@=xMcZlp+huj8(c3B4PyaRa3CxCR_mRs{iiSQ)AsDp z61Kvqz0JmcvZ-878ln^PT8Nwvd8&f-Bcnq3@D7=cv2^Kg_y#nLjJ39w@(o!SJZ={( zl_8Du%-Z|VRI5}w>OWRWZpHM5Uh2Il=4&WSEA}#v;_DW#)$S3bEK(Kghl6YpH+?b6 z7V>?yi(=Zo>W#&2Qz-?!e6G36Q}mQWEZ0oNTvOw^epD}I$To0;UV`|Q8l zQ`nDerB`s_ZanpH6(YE23B~#|AC0qW6?0+5)6^mJCxBOEOL*p(cwwCknHwc>%xIm9 z{dK)e%6g|oXC|fO3(>_IM1&dylo>D%U@hR3pNZ@x|Hu%wZjt+DTB6|r#2dzjZKN*l zV_A!?aap)*b{ZePgkUu?LeF8K(W)G@M~8cTcJ>w&^!%J!mo|rkO~Y|PBDBUN`_$RO zUu*z&R=IAzqNSgz2RPTJex~HYsuRqKaOJ$=G2nZfE$SvZYQOQm@#I$67He!>TP)K| zt#_T3$?T-$Yl^LNRmGm+wrKl+5-*Hi%Obn#*Pgh@hOejpN%_95tGAx*j4# zfhP%(#QiSUxr)6r2#bMxeq1d!a-w}Cnb)s&$yP`XqfI-P=LK|2PN&hgp`lr3=z}4d z^NWJSuVv&tHHDI{AgLrh+1VzIkCvm}&Y@l)o5wsa7!Tn|6dif^7*Du>o*NE}-4~vJ z-g>f~=NAoM)5ngPN#tQ%&Nki+~2=g7?{%^x=jU81ewU^?lVyMJQJ@wOiKRd?<>&LVNUITQ&iANHzmn=tJ# ztP*|K1Mp7OdfM~C7jRKzOOUH{!u}&G6w^ww0_Ol~K{esb>przaPW=Y?=PSx=TY9J; zsb~Zcz=hWY1Sc*PoLKD!Gv60tk&~Jsu=8QBkLVu>iSrrW39`vjW^OS~k(>?6mEd_Z zVa^dcV3GdWCE3ea36IpP#wgBVK6-u#az^=RVfl*fgM8<2HJQW$fO{6q(-|w{gek8v z9yM8#q>V^pgGll$lq@N{2_Lv{o>!IxNLc}T69HgCCtX)A#-G*o`TN+N{_7gW1X@@* z0Lm=fKHsoyJu2#cu)w4EPF&=0MA%CBh@c}03CJ+Kym5QsiYk`veufl1e-g``Yge)( z_t{kxjax8{giOl!G#;KSJFhjP-?7D9PH$@0fBpw0lycfn17*84`z!epQ9q#xzZnTC z#bcshbdzzGzi%#JA&O)wxX63plF#LfIy*ytvpHc`=D8)l#9Y3LAm(EJ~*5b^n0ps^~gR0M5s{#m?{qn#8DWrZ!5JAT4QXM=G-Dx37Ro9w2ks& zzC=>KyoJzB;DQk2SM7xlj-0rpkWif=!%3?npR%Dhr^MC683g`$kn-?OF*#cDCF2mv zk-d|e;^yd6^g9Z}Fv0a>BMQG2B=b0$nx#UQLswgb-zN$mGJ<%fk_5IeFq5@udI=8@E#0iU+obT9b`A|zf4teZ3b z(tS7WaueNX<-KtsTl34M$X_Wh5@MJ?jJ56Kv{IQ4!cML|D<&cM1xsiV_rOy=LIK@f z2tLt{yzby1^R!KvN?>b~3Q7%r7(qRo>;x4SE6x{Nc@Y5n8WmY(J!u>i!P7@YpB-nX$^i=u%F-?p>LER z5Gv5y-qq^J-4=H>Gm)X*6FRN$9mFJ?K6t+}tlD$crsj)oac0op2|j~rr<67k&#iGZXFXp!pV?$j`VhgM76V>>qNV|!(Q;- z@vB4Vy{dS$rNW?AJ%#v`~y5OZuHY)5&^+5C!VU` zJ&enVQ?xysoOW_o(-c{M-KP__2if8a<+_kR9 z^%rk3c#F>a^So6{CEcTrAk+2v6<3ay$eH78&LLZ0$D?wY?v0aHQ==dqOD|);6FetiAn6$r_FUyKg_^~_cHPfw7xgeE_Suv(sR%y_<*fC!)lIX$ z7ABM~@>!FHr@6;&<~fnl_tM9|HpC#BtbCz!ok`u6r-L8pW!@oD4jNa?IUK`xA2*xI z67d2*lpZNHvb2D!9?KE)uW zTB%Ry*ZqFUGT*k1zy_$HAT}1aZcAl*3N1VncMX-ud|C2J>-bAVkYbr!ZBQ+)Ep|^U zQK+{ypDDg4!4T+VB6jz(Jv;}6Ewh$AA1Kw(uyg(Ule ziw>yWTwvNz%l`!c8B7MIF-tY4ahH&ihL@V@FxQ@<@srxkQg2DCS%`>N`~cPP>VyxA zEPMg1FMN}=%b*YHEUIoHzq7_(T}pJC@g9#y#ES?gR(>0Pu$|aI_Y^_I&Po4z@WJsR z7mW&Dr3^dt?a1Yn)Z}F>9^%p~54^8|yv(+|;qn9X(Mz*#a;HgMfofL0McBuoohIT6 z+93b_ec5;Lq<7Wk_uY{1!yiIy(E2vax{f!2uN+;{YsX!9u?rE6jfyVx!&|NoPW#lZ zszqS^=uCi{ol)5@zuEuDVCINyudb=1zmKubG=0#(Y-LcZUz^^Q-yK9&t=$Ow5a0Cm zrWN9l<_bg;kvZA#|BkENMdGQrYnsdA$4}j(WBpF2SzJMYB-DY>i zBS-H67xATgrWsE2M@E8HeaAqeGf7XMvB~b8`g1WvM)4P>yAY&pvo}uN#y;;iZhpUb z(&b8jDbsuPMa~bEBB90h7YOJ%znu@Vr}etGO$Q+&h^W9Ru@f=%Z-L+G4`uWtc2%Dv z`q-;fg9F+%vS36cJ&)EtSCK$hniQ+sFwAwMD#7Uv5d?e>d~?H6?o?LZd~G12%mGlb zHcwaG*j8OBn~l#Uw*Rn9<`;MYz>ts=uW0OJZGXLQCXUt!e1TIJ5v05tGVT^Ukrs$e z5sruQJ(YFE)#5AVp!2)Dw0kg7i-n~lwi~%Jh+(6F2S13lCf@A-+Ig*PG(P|Z!AZox(Y%tO+KFiL)6^uN9}|N{ zg#qkQ62QX|Z0{Y3HHOc+-C6C!4zIVv`mLJR6xOypjLq}4YIUDk;8>_iOWNJlB_-H3r56b;y!x2BGbt0_NxMnOfwpLhwKaOu5=5a3*rJCZ`yW z`C8J`@RJMG+`CWc3waN`+4#6p>~Zt+Y0Yb*&p1IQG(*?MH&dF1kox?>nL#sYvd44C zC*B@0KJ{>V;^g{7&G*gS25QJ5BH%ep#=_Iq9?y-G^&CmM88z`)9>40jbWOF#C5Lc= zi%q(FDP7_@FKpPX<#gCV)PwJbzmLk#099+dXrHYXro#fGtjrF}enl$nuUYTy@1z8? zQv&%M%F;u$bCL2L%c8C@i2GP1naVin5L-0;56oNHAMlomR` zkUJQrgr_VHT_>FfueA;hO@dEVvq&EL5$KOv)Z)DRnbImUD-dzS)Iu(%7T#^s#X_Z8 zraEO=tlGd=m{)O&=$FXohx5g|Ql&PsPbyAHZE&M|Dkx@l3vU1Kvc1oY?-WG_&@McL zD(vWJmFdge=@Pq+VtrDRwquUgUajTFnChX;9YQQ;*{LjY8>n0(?|(Q)F-mLtb}s^#XhrB2Dj@oHnZ^BWP6F>F|-2(ZTl`EYo(3*T2vHYQVw>@a(B1Mh4? zbVTSBRZNAw*g-t@I$-Fsz;N2>{GOH3Q}5mDgtLs&KDf(({?*A|By?wfS6P4jby>sv?{Dma$$>psa7zB2@MB8z zq>c6qW#hxwl=31+nQt$=_3Fki-O!X`OrlDF3~dAqylsC_cOLCI9uSJy*<19qa{Sx^ zo;ID=-;CeSZE^U>%VfDG(mXWu6TzyiJ^*D^Yn_->_0n2-m-G`@|8`0VWozYfVl1J+ zo-V9-r8(5xu%B1AO#INfVe!IcS}0}MGV4POSN7ab1BZ@C?SNT_rSf;3M^qZ-iF$&o z&EKmx3W@dzzPM)$Jmib?ZRLuemf{Ikxy5z;7n0FS6~JCB=$uU%v4#oql)V{X;rLK} zEsf%~pne5-Inp9FxDmFvDxLQ&bvb9i{if3Xy*oxqd&M(zD@9W64*prOj!G|LmvbUc zH&!Yd*6$5WN%?xvb+wC&-k0$)S76@eXU5bt@U|c+=YrNnK1mXHG*y?k9#&-hY#n0x zsU^Wd%G4j8V16Ib zOc3?q4;7IrH+D#S^wpgJmChZftkUgpn!}wfrHmIQkfEqSjn2v^!aMrS=e+I-x9^P| zJkcZXq$kX{t9-PiGcs+iMRjyD?}mni`Uzkoh9v1Zrp9#y+RD)jySa$ks<*oZRU|xzT1AjjE=WvW}{D4GLs;*HlElvagwm}bCL2X6}Yp&_*P2rai5T~uIFHs zbQ<30PT0&}#)1)x8g>4tb*&^Lg)S=SIYMtbQ}0}mi$c?-lJ5zYo3|4 zGZnR;aai$}@iuWsvRsq)G~Bdp4K+6OGq`!2rzIpBmPoG9YJ@jnm5OYS6lNBtW zTRFf3KDN&wKN@pZc)E)oUB;9_^|iWv>!cH`nyXFF=xjUDpx(F!uZd%+>eH~r!)ZIZ zIu>NRw=XbVH5N)m^3(mfrS?vwrx^OE)QN8}DL;#6I}$0j^edgf<^>mkI)3Pi8NbF= z|JncTpsaiCYIU-yb-XS>ps$}!1oW^st2`KAyq`TP;j;C3~i}Aqtj(!UEyL2)dAo130-H}3T`H0 z{yxFuSh$R9sYYg*nKH>h+pLI9n0UM`?*sAu@x7KU!j7+mNFa2SSuH@5x~)6Y&|H13 z4WN@?A(@U(s<&(IYmX6pu@?yUzJ9%EY5gb?FF*-?&F{BVTLYceXnpd;4pL`H zG9uaJJyzTi9TW>yhcj6|ua&vaTuDfUN~43vZ`GEbZxXq=e^^4c{*Zee_YDsG{>*_0 zu=$VM25@Zzc**5cN%3lUZwLf@Uv4jCv@rO~e@2zpXhnSOwZG=6XZN)q6w%~2#8i&= z%8H`A7I*tX+o@|=qb+Rjf%bAxDxr|KWi3*4Q}Sv1#4q{8DX=HyLI5b&A5*ph4ITOrkLot?5s0F+<_BCQsv z;M5F8xlw`WtLk+)@2tHhS8k+FmMIzVoZK)@xmQHkAE2PI3BAPw?=_v*YyDPT_sqhH z+a#uh0IBWVK%GRj0>2EtsmKR_&(8wJD6lcvf-u=BLTp@{uJ~?Sj+MW3DVko>jP-dD_NC=&p&4UpK^mm7FD$j#D+^0>in)Pa8ZR%UTWjiF!rX8;9CW9yWsAD9{P6k} zmDk>)<`u{a@cACo6uiGLQlEcv)Od0*+~?nPVc4I&e*1%%Q5mf?epRl1!z1~QnBz^^ zhNnMQrni>Ph4@_>K<#R$rcaXX%I1j$$b_m|yRd9Y3YY59%BGs`5bObAUWECUy0vsT7+CBiied ziR2Vva6z_|ZQjjAR>Z@TVk==STUYwFV@nC!B#Pp8+p#N%x^F5-ZHevvi7Dy(PuX^G zWo!8#Aruqh%9%{Il@jG_U)<0SXZb8Dw$aj`WWcut8OnF=2tRG8Y6)q~Ez+aZjtO>b zD6fjER8?V*QJxMKz%jzl4|BSi3K387glrB!!Bc&e9#pd8ws(~qj9Q~E-~HY1`M&!+-*f-F>shY7=6A1mUhl@Wn>YId zaNt++JItafs{0mKUxF=!C2o!5Mea~^z+D;?4=8Q_Ir$81tzzXrNwE?JwZ3aikLoP{ z{%E~7yXa*;8Tg2kEahnM-kv#Sf00eh}t+kDvwT-nMf%NED>Oa{+u{{j&bFGE* zYBmf|g?enf2;KafIUoR_03g`JLOXwxyG3pCOH%VqXAP_7 zTOM9E!|c$;3&{0*cU*UTR{E<@`*98e^e)aw{V-bU{?ow_ zT-vYvIcegPBL6r#0S1&CI~F~*5E1dBM~)(;)U*aT5T-y0K`oDHkyq(nvni@E@>okm zeM{`sQ9E z?UEjBvc|vkO>GU<*s}x1i(0Scyx~UVjTGIyNVu~Ha z#aZ&F$9FV3xN1%4hD)juT)A}S#)hmO?$AtY(Vas3vxkW~CD;og|sKpPJJ zOTO{efT?2&Zab?tlVpe}<+_4dcEAH*iy)(iKy zUw_*!{5BXqoEUz$B|NY-DWK(-!2A@Oi8~4ZA~^~XAv$J1cFR-#56LMfWj}JrHg?Z5 z3CJ_sRkS(1r0(eP7j+`_f0LXDVQsOnRv>&P$R?#1MW&ZX+C(w^jnilU+x(B@tcf#$ zG9)>SIFo;ooOT<7)sQruqIkdmdBzok5JKY_^Z%6q0MMSJ>G?yCF#W8C{p^PQtU%U^ z|5{?8(P66hZ7PJ=LIBVQfT^mQq21a#yd1}LdW5QbmqB-s(~Hu|pv*%##;)$KjQp>m zl;y=Y-49}h9&w`#cd#`)&olIgH)RC3YsqCXY+qnLV&1DWhnpJ1_Ct5f(=rC!GfT)FJaKAkR|z_r~d>N z(+;-wUtrOw-ZYl?{~Xf)-{Jpb;J?KH#Nse*=ugkN!pIWNcYpzh9@Fv&?r*64(116~ zf5&_2PIB~?&nr>6{kL>L2KF8G_l3*n)u`oA=N(tMaUk*^&k!K&f(DL5lid^p&pQ6* zYv@JZcrHm)}l}yi5&|{O2#n2LL`y1>gg^{j`7HsnSgc037nd0wDjwEiW7f z@WTU+s{lY=_^yTj`8NOez5fOf#wP*5ArVJ!o559hc4z=CkD?JA0C+3?j;CQ@ipg-r z+by7)>Zy>ZVWt2I0ZeYgT)jnQPB|1+M~Zs4Q#^0GH_aGZvYJb6cG?WypS2C#X*waya6lDOCl2 z&d*DCK>kM=GzA9Geqvh~<72JE`hjjN&_1ak*KuoR;vUbSO!4>v0)kf6<^0|;kRVZgSi-S4;JNv`<&>BAK*A2x! zGvrroyZXQ0TK?ny^8d0n%8i!F*#PePK_yy1YSxkllQL{Jaz6f)4xp+AQJpTZd2UjW z=iz~M&U7T178Y@ZQfGmUYIW5RH^xTqhNDVFRRLFM(eel)5Yz`9g&U+{R9(Q$uxh~_ zi!p+z77g`3sj6oOYJP4?C_Kgb3+^CW|f(FioOQ< z2(iG=wg=-6)k;#Wdp_Yp8*H9&^K~wNUg&QHO^$|m!8k0du7?XTj#_wTmep{-8u&Ou<)vRk$4xn-NkKH?bi!w1E-3K(u~zkmiws>w6`raN#JdH4(7J;V zjGw+Ugb;NI#*YCH=*o(5R{J?nkO$4H{xtvrg7*J400Dxw`MCnBC|vMD#au<@M_H$+ zLCv4#&w*+P5Y+jzO92RK{@U*cpaMVg&nBdPl@!{~m~7SMv!ro3d=19di}piip&J@X zMbcXyYrcEvv}uNrk%F_LpU!wK|$caO3ZRSRU@!Ax>>aek5W)nY$Qo~2EE zrp+41CoJbHI7nru0DuzOR#z26OHS4V9B6Jia6nx{)3B34qb)Y7Y%kyDnhnJ5pq~2gZEFlemsjB|Ga4OoWs=p!~ko8a`MWjPv7N5xcxDIyTQQv{-@7i{@ z4qj_$OO`r1EVWoB{30k7UZn;t-*DjM0#J=Hv6G1umn+U(DHex|#Dv-ruXFLocK zhx|}Y?RRdrF7%+c!&d=(+rpy({(9A#-9`OI*kvBuQ9HH~HmN|##)ikUfo!YY5(I&O zle4q9l_O%(VI>Q;U#W4sKs_VFwm8jBBRb8SBa4!xSF2`F+iGL_nu+&Q5TNE z+k5lre`V`gj_-->i}cdyiLVb^vzOB#vY9#Do z!=Eu`rNH|t(UdSPx2o63C~+BYqpmn|HIFq#hwHsFy{hrjy>nmc7$>{<@DRl|?g0O= zKJ1(Q9~ZjU)1xU~TRX=CA7Gn%E`MkoN_Pg(@Fk=E)p6TUghYbbCKVn}#l}p}c#{ee zpkd`~7aK7imcf;d-Y-eyfy`(&WvHpCNyNjY1#>vubqlcdoOLcp@ zl{P}0H6cKu9u*kt9>R#7X__T@ReHmL7_*y5VzwL|MhH%NBpK^i0k* zUbD}t%W%5VeynRJ~=r7feAmslQ#@p3yLXgUt`QQ1P78OswZSK>{H9K!K z?r|*1*mKE_wpjYgn|Z23@hUnwoM%CEp(j!M{9A(TXJ6tbPorj#+@|rT6_?%v7wsGB z5V)HiXMa7vG+KJ-yTQ|P?wgn;qI7oz^HiXN>xJ^n5`%33po=RLxk_TcYl zC~?%V?#DvMt>?~5gRw?FTQE*w~HQW2o`cx zJi8*$m2@UrDv+wTh*q<(?INOUC70F}xNmsOYW*Yo{p&WaS-q?>x^BLeA^P2N#&y%9 zX6}s&r)*QSUu@cVT{sm4n zw6ap#7+EEjpZ@Z0xptgT^L!<;U4N0T+q3E?Lq113bos3}&{|R**3Mj$&PV1`zA$7s zz!EL%l{!zS-k%3F1E;Qs5rCMPCU}~p{P(~W4g3l+X*?O2n!<$wcsL)6L>%$=xc$h` z<;c!)Ed5(+(3|87@|DdS-XXnaeGvfmyu~63P@b}r08kvwIsvK2RV7+}I!8iZ|uo4UxNS_0_k2+t+a4bPRv~EkSK}k!~BduzSJ0yzwyj)b z_OV@RBeuG8!(OdJ`6vOXxqyq>3VGd8%_1_F$x61I_;O~3O6IU+A`sNda2;{jNSWO% zq|+)1JzSPeRR4+{1~$Yk2S5X({mL=3sX&f@_1a5;D~*6D){EO)<34=JD=pRR1lpTV z2MfyTzRFuy?KxES=%7j2g1F|9q@#;&yjl$e&G_jTxqAX^P5WQ42DNY)(lxR;x9;6woOfnYa9s! zofiviknOxo9w)#!p_}{CWDzTnu5oLpdQ1C}Ro~vi_aaP}h)Nbc#cZVaWs093a_p9- zlky$}_vr$VQ-{`wXb=iX!slI*QL(GJssx)Qltd_pBT`&tJZ5+!7#Qk{u{yOE_F*Ps z%Z);7gO}?z9)9{UNUgJC-RGDd4 z!!7E?PA;K0#lmuN|EpL>1{fnl!UlQKtSpIe+1rklg=c6Wt8&odux6>6>_e)FBhG%a zGi8O5yLQ?D80hNZnWJF_G`V6!m8BALigP?1?^cb61 z))*L?g-A8-ZQS;UK|tyE6;*R$vb9q%r{>pl+$p>WhEub(wFQ(L_)JiXFxA^L5E&h# znK1L(_@T{JM(uz@t9`*+7q!fOXSeID9$iywvWAi4?SR&jTs}Q5B*!?|7nDVC>#<9YdrTu?>-1@r~qWQ^rWcxX^`#)V|(@%dNw{AOyq|SJ#ybnVlJ4c5s4X@>6ahi{l0kt?=TTR+BVCCv+ z&Sldh*byA%L*G%`s~e3?zB(H4eI~m9)SH^IeoOtR?AYOS@=$uM%)D1^WbS!B!BZ8Y zPDzTDUWQm=R~}`>2EhxLF715KJJ)X@il7Qd_ivp%ui&F5be2dpYQh}$VV0_0l%!3{ zd9ddL?n3*!XC_VGrGHUU#p&O#NLC7i*7n0cq)t z)stAH;V#;WQ+X(pL-aHlBz>HR1$K+nm9>bE!jneoKBcn2gasE`20*3K+2>W07+9^t z`$6{(3%JjA+652yy!=jru~K`AoakD3v~{X}m0^^mBGWXU%?31rLx)zDzuOas!9X zay=kf4W!QWFGCF_kItJe+({5C$@WjDHz4if=yU*;$wMm$~ODMSELja4K!i#Pq>P?i5@Zl-vT$n+NUhU_yupk3w0#7Q{FY6}ijJT8^UQ&6Q z<8t}l9o~XjRMY5v{m~FRJlM>J)PnM`2z^sf&Ok3<+Lbft(OJ@ARaaTkq6Fe4(uhRJ zvr=bcF&}2trDJ9t{O2KG_Z}SCk{?X_(3E6VM7XmFi1ChTntvPLz|16Z5g?{As@ch< zzLU+OU&z=kU%W;msg^0_fWd`6bXEtC(<&l$&7OBO%G+H7zH>OS)ZE4IMzhDhX;a%S z9ga1OFR+n}Nc2EUE~EgN%w_>oE@UgUqVa@;`H*JT>z?-Eh0> zfi}JOyFYYgJ5+WAWwd6C^yt}r){vA(YjLc4c>PyPt<o1{1n}0U9aqPN%7472 zDeD8BD;5d}O2NgY^)sa8QZE!_`-CFi%>ChM%S(pORxnntw1m?`l}j?BT4R%}fop0^ zO6=H@`N;mJGF=hp-r3EIH48$%!gSQE94YWvW4bfOufS6v61ajlNfJo@hrWN?Add=c zHu@@el5?e!-PNzoEv+M6*Zj_O3B_WjUbwI>uK=yRb~&L7x2?r$-i9%y*bbfaR06=G zHH^MKCx7n3>JYM-h>UJLmNa}pr=EznT2tAXB1w)LJo`CD=99$%{+OfXCHk2gpSt%o z+2mD~k84=MbWtvB0Iv^uEMfs298AYzx?Hik{u*t^?ELAPp53mD$G3A=H5@q}kL(C*?qw|Fkhuf)i{Jc6Fv*R>yCQZC>xX!&M&_5 zZmZt!>d&Rh*B~cp%QP0fzwwaLw!o8u&#g5&xkfr_aaN81Ad!e5qbE<`f#BTt>uiiA zp3(O3PPh+daXk}5H($}ae`3pbmGe)|mxkL8zv*c$J#yNs20#88W*=uu2k=1TE!=Ts zj=&Y2)kDO~MubGRixRh)O~Yo1q6W)14A(tvWN~LEwjAb?rO#0ys9ZIBURO4c;Owxc zC9P{2j6@EFp8^@ADc4LNoYry-JOyXZp z6#g|=@jA)BVfK87(Wd}36O+Y}KL-FW{EALrv$5D)1BkZ1s=+0i;kU-j#)5K=eW<;n z+}ErRG)O-3BqAYauucqjvKu8riiCV8HWDL6>dulUG+0?|jP!EsJt1~bl6J2g_!*aI z_fSM7e#Rvf-_+K>m16C^z1J*TzSPOh%iG({!;P`l)6>gwsk^(6x9@kPy_=`E*GfOA z;o!K;!Ij~0gpOZe;u7tW#3U_IW3S0_};i@BD<(Q=81nRKs{A{4i{ z(m`xDw?V�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 Qoyb|&u<}Xhfw1ns0I+TuF#rGn literal 0 HcmV?d00001 diff --git a/mods/ITEMS/mcl_bows/sounds/mcl_bows_crossbow_load.ogg b/mods/ITEMS/mcl_bows/sounds/mcl_bows_crossbow_load.ogg new file mode 100644 index 0000000000000000000000000000000000000000..02d2fd1afcbb49c4eb423909287e3c80378435a0 GIT binary patch literal 7627 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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 zcmeHscUV)|w)jctMGO!iAY$ktfI}caz?L9ES|}ljA%K!lq}fn#?2%>&We^bQLLdks zL4pCnaU4K`6j4F?*cGvh4ZHqMz?nDq{_gkg`@Z|V|K9p`_St*wwf8!EmA%$J@!zr~ z2!H}VU=x62%9b=FPr%n$Yw&oUO4PTf!6Bp z{{+Y67MHRCDd@2~VpjSmZb2r*vSuI=SFw^U4^dd0Yvs0{ z1_6{o48|8JWnasq0sstTXlA8R5bb5fFRVuGEiUwwwWM~L#f6ztL_{{G_sl$*p-q#Gx#p&3D;e?j z#f;G+ntoFZJFx4D%WV0NN@ZamNbp_U6!jxvZpyOdIaYPWiQrO;+d=|taGSt}V{k7q zd{AsSG;HSo+9pujaoB+vL?KZ@NDAAS95s=gG?9ETxHvte{a|o=ddOsY*!y%QBI8H- zaPanfSy|XR5&~42x)j~F;+Yum?z!;f(lUflAW|k0q)NVtRep_EU36SiY*|}OW82oj z7MsBq^#u|D0+Ps}Dz>!l|0~hKMN$90;A8sG03MX(rJaVCcA62%W|tCeloll12Y@=o zlWnAl*bTd|mv*fN%ZAm~ch^KB!Bpff8v|$+gm5SG?3q`HQW+T4hS2h7k~_KU=QRtIq`K zVn<4q8m8#r+~8}a59>SNU@Nn*%(AtEvbf$4vuM~dy%j0QgSm<MuA+MsebR)hW;`{;s$=v#XlRhyPZtzA_BdG6&1B zy={=g8Y+dlF?nn7iKIWyriV=?-JUpjdm?AEUdBHg)?c0jfKHRP;FE={Y|N$dR6jSB zMFs!qIXmH(jv4kJGxKRNBaPS$y~g^#!47K^1F@taov>k@r0cp-K~7=U9iy&OqsEe> zrrM%H&K?YI`{6K)ZgYDg>2IDRa}g7l-20yS^8e*IRjAy1xLi}Oe6!$ui@il#GD{mu zDjzrSRR76yVz{S@xu-bXSxzo0vnV#RRM5do7-)KW?%$TbJZD3q8CXEiAtsvr&2u_2 zhU-CZYOx``S={5AVNjsEiF$um004C6srxLPBY|YwF|y+r*_KLK^WS?6I68(UUB`lg zJq`f+0Pvu;Zgii97AwyslMtiq)nh0Pb$wi36PkTA&(y=~xpB~Cn0#yTHLrB|=siZ< z@?Dgy98shv!M3fJY&=u11Ri_JK(#)gaS38bk~8#?13ga$Ue^H<95SRWiyk0!4rB4! zYw+5{#qNJrgN(3&@?iO~49IAh0vX2s;01E&bRgofU?lm^;a~6ybcFc-jTatE!c$29 zIj8?y;r}G?ZzTYlI79>d>AF=LTSM762ypa1J|F2dhh;|u&#nI1z*qYYU3c};Ql;yE zdIuO_Ut@nZTD`PRB@er_Qt4`H>|dE7fZPiXRD#5wvVqyIKkXWPkvU)OI+fwHIOyu@ zX|df{rr=+{92)@G5G8;OXb<53dZ!vsEdapfM+SrWg=c;g1Yk!6S1JKOe$-y0f4$8A z9Q#iUA#4-?9Ocnf3c#Hm z@WBym-~(I{KbF_G)5hnz`>`l63Cc9Vf=$iJ*}ZitSKom9MsazuP%ylJVpouf-6_V~ zMk64m&l^CR0iAboMKgPOC@z>k2?loB48Cy>gp-1(VJGg>i)J%ly@LB*8BbjwOZZab!3F z7+s(;B5K&g@hEmIIPYAOjT~jMuU{n)JUQ27JqUma)YS2)V8uJKUJIC_-|2(^$WCR~ z{`wZ>Wu*2w0B+D?0&qZE$Yy$D`05c_ZmQKxUpG(VNHQ61#aDGhn;$0=Jo&X`dv9BQ z5m~|bc)oW7vX)G?QUKV?ao~@xoSq?+2VR5OUPK}5vdgTQn>XfR`7SMEJ_1Z{8sHJK z9H%fJ1Lnzo-u=ZO&XOMq(v=sGT|t}%m~iX{NootpZjZ`$f%!)TNCE-yi_+#M_}OVu z7R0Rsbl#DvtI`q_w^x4M-bza_Z;i{ZUBr~GzWPJ@dnZ=`bXmSD5IpT}lgWP~iTQ_2_)pJuf^tua(r=fAZyPlL@ZSLd=w@b8S^-bo2?jc- zEMBHzl&!#=OVPL%=H_XYp7)RD4`G9I*svcr6sK(FkJe7rzu#K^>;Ce;*_vd;i&|*_ z;!3(4J~%DML1tAJW3a4?U|3iG|ab=ZHDi7uBg?i8QI=o~YAqhbML2l3f;ez1@iyKaAWker z#ODxEWg)WBc#)&k%q}1C7$ZX1YEhG&FT)92$4v^!_Py{RuvMC7*ZUq3A;iow3beXE z7zNpa#POglm`3I_^fExhQHjdVu^lVibwvTdufYL$a|FRspQ_8OQPDGEFDRx1yhDPf z*DJFynO%`<5xYP$L#D}YVztT(0|YR=1a+n#@#jEwT0VIIoFN+k*_rc47iXYknXq@m zUjzKYLh`~~<%JX(yo$;)RV~nV3(4TTbdbkl?hFb<738rn;0<0`;chC61BLk@9skDw z$Ov5j#{kF(TxM|w*pQ{*$7Qs##zNg7Yk}RxdU1dcG6Io{C>bNL`(wQYMulYbVi!Dq zb z6i`)DUw)B@$FDT5>8#q}i?gh70ssQ%GAxrLMPjNAQ0O{2wp1bG0MK`B((~7L_DZ?X zYtk?!H)S_i3f&M7QNiKvW?0^uOIuc66-0T02l)Vi5pV}QzNP>Z6JE*vM{^$l6-|9( zD~t<4b76QD@Bsik$!rcM<{{2?^;*1}yN9Q@uU`Ooyg?QsAs&DzD=%I+WqoDk#V;M5 zD;MSivM(L7uxMCv*UHl3*?XMJnl*Tm2hoeL&dtqxgQuG($(QU;Ao+jCeMfyqe22ey z`Syn4_NgNTyIYG7@Xn$LG#_MUwCR5fdv*BZ(--G7eyI_yn08$KVo)#1u6f5J1Ecpd zS*{2=?!3cbTmxApGCJi@TN@>po=x}7mg3Tji%UQ-g8&{nj*5ga<;f6CPfxF(4WjP1 zF*i|&GwC{6+H5C3_GDCma>a5v)Cz_OB2RE1j=`!*F6_;5IA&(9*%hvt1I+h0T{5}E z{cimJAl&X@|J+ORbUqgs)29jE(h@^~(LPsl*r#A|GTg?jbyRom@Ui!26WZp=R#fqiuGmfMtR><< zM9I$uC?m|+5U1$3_d}yuJcGyeq|1u-|ImBA1gN?_;_Re^5yQol9+pPWWsS6BQhIg? zc&buiFvzN)=fe36X|rnG80#3kAkx^_3Tc9r>J@6i?1ctxcCd@h&CRS-9cvmEVP}F6 z(VlCQO3%+u->XB0eje{!mmBud>5A7MgC92Q5QJRi@fhFf5O3Bed7T2Ko=JKm*8@=L zaGtz$SkA@WW^T6Uo|W~}j`5H+JlvANMG`tCIbQClHn^YO|i8(EQh$QoaCY; zlId1>S)kHrkgmPCdSW&P=&dIRcecECrhejCeqgSBf489HOg>bo;^k<68&OqZvyJ2_ zIQFp@cpkYEoaK&2S{{`m08N{5?{j81aMp+Y;cFYVnp0p)pf4ptbwRnxyZ(X>zXQ#~ zDX*@keR|LzYPohYrt5>!s5Z|;C0~Ul&t}9^vTxPaQsRzwG5(l7N?)~Nj9t%2^&sip z(0u$%KdE{{=})>rH~-dN9w4gA_Dy`vR0nhedwd5wek(s%dqqj%xkMxlzs6O(J6HJy z7+oIt^ds%W$D=`Fy8BJd*2?WkC5Lf3SwyqbfL)(FMzLxMK5u4+0%GU*n<2NskC)&r z;jQOQdZ4b5lPkVA{q)S1AX)Kx=!n7X{`Gsjh!-9&Wl(j-QepxlTXRzUtOb7cQ$Dj(Ya!?L6<$m^?7!!aYWjHC zLG{L&E%QAm147>%##eZk*qh5A#Xu3winiO6Pdmo+4ES}7Y?Fw`IZ)TFL?MSmwG|$2 zx#4qLZgly<4x_xL1J!+(n_fH`e8=8BqehHQR)U)KF?0K2C_v-*okV%WmCXYGRy3n= z^fAq8#Y)zmv%wHn?3in4oXO6$hoCozU&R^iQW74+jiXU@Bg!1kS_HpAy`4Ft%IWBOZ*+Uic~qb0(<^!&9v+`g|bgiKj=W@1B43 z9SJY_diK$A#;S6?uPf3_&KySKO^lW800pEMQT`)^eNqTr4y_+}a)fX+PIGTC>k}R> z47B?KeQULcvcBN{cTT#bSU9zICO0l7@yiNvo^FBTek7othydgQB=u@te)`L2QtwhIgQ!;H?x%L{?fLCJzjGrtMoNhP(5pz| z8l>6Esk6lh3Q^QxT+E_M+QOHoP`hZY=$HU(3aSmw3W+aOb>d+2fFA1U41@K_pRWc) zZd$p?1d2y6CH<@Bu z4^8waK!S(b_+>TT4K{k^jB--@H&a5&QumWon9vI!==wj;CB6%@o9D($82h8WoY-)Yamh=x2a5S0DNPMOZ!I`U>-uH9n4%(gcBXXV$xgtJpy*CvNUaI*958p zk5&`i5V7E*D;r|Tq=-1InqhkUwQ{ws?hvyrngBl1^Y{K>c>tzA@-p}o$Hv>~b!<0Y zr&T~dYvRP9Gu97Vae8@F`J8$a-dGinPSLF3mKC0UxVc)@Rhk0H@oR40mTHckeLe|+ z#|Nqc=yoZi5Xx445gZaS(1I#rOBwP#CdkQ=Qa-cTsgx(KqFeHK;&4J1r~A{}t@Ww` z6r=fx@i?N`9dbEtO{iSJ-A!j0OD6zI`-IY@e80AGAqDTL-mT88Rbl8X=lbRF5Ja1L z#xNa1Z5&3aK7tcfBKfRLWWoo2BngT?(^M22HLFD{A0<%NsQb1-xPnl78%u>6L&zLZOR$;~N0fM^~fN2=I=NJQR;4d+FQJh$41ty{fUBp;c@sWI!`LEe~6n6hBUi*DbDN-s~QM`Z(GwS??=k zoaw>(nm%h+*)SD9e3l=v{=v$}gCA>NqcaK-foYINl7uuH5~ z#VC~zuhA}>`KI2RE#Aagl$<_u*Q<{IaA>?qZR2DG8$e_UAb6OF1?Gd3^Kh7TTa1*4 zXl6g6P%z(Jm#>q3oxLeV3BrdHT z0m9+b;W!GI3%-6~RY~<kEAIDgIC=i9#UwIC(_K;_^axjJ zdgk14l94Q#$-?hj@p!{{*YK#~<~oP>@dwL^)*A{89u}CM_@ h@mz2nxK18jA1T) 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 Z2QkYyuAV!?7LKUJE;D1-4Oakw2LP@;_w)b& literal 0 HcmV?d00001 diff --git a/mods/ITEMS/mcl_bows/sounds/mcl_bows_firework_soft.ogg b/mods/ITEMS/mcl_bows/sounds/mcl_bows_firework_soft.ogg new file mode 100644 index 0000000000000000000000000000000000000000..8b2e7bc5bdf0d5d25ae4a1c89c881e0ff4900369 GIT binary patch literal 55786 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 c-je@FEoVy(XtS8|T4%!zRSg4e&Hs=55ATUp8vp zaB^>EX>4U6ba`-PAZ2)IW&i+q+O1bvk}M|-{O1%t0+JBRaabdK10UbXR^7AsdHlj% z(_It=LMT%y#`M4b9Oe&vm>nCZA^POK#m6O=IHM8m{_Hzhw|>uqy^Rn3=6S*B65M4! z`hLb|^y_OvaHqd~>^GqvJMkF0mXAT1D>E8rTs($^cR!tHlg_;C-nMhT5|)W)@aJb2 z5R9hi6gJ$2#Nu~OWSL)*jJx2MBw-MtFN>@mE9v{#nWy})>$@-Y;~`ZK_P ziqYvO{XTXpLZ48(D}Q*Aiw*Yu^A@`?S{$SA-DT$yDR0iE?p9U{0}DbaYnsOu@Kv=%G7akMUa7)G$DIT2%oP~Sz9@kcSD6sFdC}k?Nt%%e zOe#VUE~fwq=_rN-u87!dWm*tuuDhokBYX5F)ItaE1g3SWlwl z$p+>?gg8dvli@jw;{pUol^dA>Y(zZ3i9FZFoIqn{UCi*iy@#I;hlL*Y11h zv8SE~xHe?Cp~H_b;z%Pus2x;4qDG&P`!#BGP@9OkH7>kRLw5+*1Wh^7i5U=MM?gGG z1VCt>nAu3q@kDN7W)mYRlz|%Q1gFtN3<$bTtb-oxUda6tH>2)9;l}@joSD%5AIO;r z-9hdvZr`BR@~SAZ0Ge4iV`^nU*f1z_#2;kw_wVMr7t+P8X0ZYx-0S2TnfCyq0m#WI zX{Hoc%K-h=c-?6L&eM$RuCtWwduZWl);LZRAez|QeD&Xtls-R0Oe`c*RD%^1t8oeP9tX|h%p;j2(IkuP#3pbU?vE= zoU-R-;&`THb{+nkH9eswG`BtJsMv92+7pJWL%#8q`fY+XaiRA9+P?XPktYU)`|<~p zN^-;H-R{fDy0%bL7qMtRQLNo_J=@6APCz?O5$@Msn(y4r=^!Zmp`=9P_aW(Hu?Bxlr za@pQFmK1Jcz!$w<#hy=KZHuLuh0kPww-*(V^AZZj$R7sJyhrhXl(5*-n@=Z>NNMjV zQK~zQwM=Ez<%{uNsg5HqDbaw~?ufgDL(>`r4ex>X1mB_f5Y+o{1;*IVit|N*s&0OI zhB-avtk1e-AXyZjNywGS{RX8#PWl17x&|HII)gnBFmPACUb%*<2Vqw;&1aOK7Pj04 z?6m%ymoINo*!JcPYERhi;*?qNZ_<^Uer089Os{(%1qaVMIPZrD=cVo`CPThanUj=ZM>4W)!6JTS#He7Km!m)@I?!v87&M0+amO+6l;u_lK!_M7Grtl`_XY9{2J z+Zl)`hH}E#a$p!_eGHZdz8Ef))>l6ZlG(x+4`C`u@-KvWkF;KzWi?wGQS+tnC3dU* zh#_(W!PS#J(c!sAzn_{&9Z#Z|FLJ|21)z4wxnob}@nXB8>E#or>#sMu370LXbn5D& zQm8Vn<8i};_7wea$i0N)gKN5^X*Q?{H~7(?)SU(L%T7VH;=rI$hQ695fqwEr%c+S}vF3{8KI2 zck|PMODYeWoUeS@Fpf+b87CQrVB44 zA+R5?B0|i>sFjw@TB2-@Ii0pP-Q4tTr;B3D+l zg29(SSOBQzWm{XD^!xn)xZQ5ya=B!7asq(pOcH=>UBgo7AQc{6l&XKjZns-BG&D#P zwyevdV51dBaUQy+lA1T@@(j^>w0^0;gaNi{Y03*TiC>>k9bYqTD% z=fd^-!W1axp{c1!w(PHxqv0v+MY&8yXHgV^uBklk@iH(R6c^8)Tml0KvqYE6C0nX; z7>~rTS#|mb0sw@jWAuF*5nYekW%H3%@o%w;31=rKh|kWUC;&`m`%;2YbsV=kJu3ROaNKv*eAE$luimy-r#P22P z>>lL#+aYo9)@A8BeqMYHMDTdW_!di2R-8}Wu99UEQMrAKk+=_ioSyCt+mDSi%VGh zaB^>EX>4U6ba`-PAZ2)IW&i+q+O1bxaxAG1{AU$+2_?isS`N>M*}*LTCZMXe+dg*8 z#B{kEL4gpNl91i_`>*N#hmZHsyAZP^P3giXXi#4u$aOxar7P@T>s+_+Y1}<8Jcbx8 zpKcm9zhFGR7UW>#_4ByP&Gd*Vx;2|ZUORgTHcw0u`!i0~cWUcO_;4Kia^5PQ$?yG; z0Y;A)Wbgc7;tRiPq387_E@&CQ#EMCTvBJDZE>7QL=N|D5yhnP&?kYCUpP_J9vI*%8 zBO9mqJ$4(RH`eZ*KfS2&%Gbxw2khqTGUqs_D{L{> z6l_|cx?pv|j8dwvTtkgD)m)`&Ee-C|LW?c6+@xtM-FNN?|DJkwUAp!%Xuy?57;&VL zhYTHM!q+CxFyl-!PnkN)!SX+#RJukml!*I^G3R>wTF3!N14+O^Z zVgL^97iX7H2!1iQIJ?v%D3JVNWnAQRT8x3gFv!PA4|gx-e&o%?@Q--&e`3xp>i!Gn z+@j8y`^wulto5>Q6y5}_C|sCcJdxNisd&L3^6|fK-FGi|aM)tK7>V%gQ<`{xCJ;?f zP9ah(q_QOk_P6kAX@X7@Ww&u%Wv9(OKVp+N zk=T#*wzM#WM|17GN~~=!E9>???F5x3w%4hvya33z7`(HYaEv8jBbaiQBfEqn!875o z+o;Q4sux>Qd>F9b?d6I)p@(D1z>O`l&{;4;oBWNfG;R@YBb&94udfewVWweF{n+*( zr4rw8rEtcIUZHQ+Vi0UP48=B*Z+48rP;f&CNV1+zYuwS5bh@3n&C7jpp>QMU%k3A( zk*dl-fpX4-8&+nF=Y?EgjqNyHn)GsBAgv>f@8Jq4?*msbJ8Lvep@jz%O2r+Of?2)T zg3fxq!}|l=qpx+KfBH5z;v} zI9flG1vggC$Fp-Jea}gMYEjXpvxjKa9!;jAE*V)m`dYHt^Eh z%Xd2>b2}uwMB!n>Jgg%mreRrFlz7#^g0WA1SsYVVJX^BhH6>w(>&cfDu$FB!juY>ckUlaBh9 z@ITGS$6+%pYAyF_)Rz>#Xfe`JUl*Nx41^6rjK{gO!@A} zH_l+zsk*XC154+ll{?j<>aYZeq?-}u)`K^4yK};d?qN*16?UD|TjZ<&@%46$(?u0JKbXEaZ~aM-zt&pr9~NhPZu;XD zR(L6*e!6rAJ8XU3eYmd8R}hw^9@ty*e^v z{|72mK~gSzJpBLw00v@9M??Vs0RI60puMM)00009a7bBm000XU000XU0RWnu7ytkO z2XskIMF-^r6AK{*=J@>w0007PNkl~_u<=gEb@3X!!aBi!h0agV5Cv#o>$hr=P$WdQHoFD{(TWpsR= z?86(I+d7Bn8=VjUFP_|&w;#StKtw!5r_(7f+x9Z;TO`G(r@PM!z|_Jb-GgHS;Q6Dw z@_JpR8JqTzma3!Nc7#e>t^_b!i?&@x0r;18gjh@>k(|mm z;qlHP1e`83mCza|^URns)3|o?4vqB zSPrkE*J?28wRH8X^mx2tMD;Q03*fj?!{m1lR?ESJm2FoLe@oKR@g5{?Ut=Y+Rc<$Eiw{a=i<41dOZ{P nmqPysh(lshqR}XP8dk+0n%)n_N*?JY00000NkvXXu0mjfK(K#y 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`l^lx~1eh%1mTpC06ysvl<{o6zDEm}_?b{(Zf0U9%KZ zZf@=k8#bu=s9E^ShbwDxa&j`A(Ut*f;4caC3ugHLABsQ}16S-^bD&g*r;B4q1!HnT zNJ1Hpw|5A$A=A}M(pM$anj|8l`wZ)RN)q%#ytzw~Ja``56`Cd{b>sqH$eU@?N_rk{ zW!n7ep1qkzHJFNeMB!#hT!RT2?Q2hJ5RGaSuOTX}KmN-3bD7(8A5T-G@yGywo? CI9i$j 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 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 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!ia0vp^0wB!73?$#)eFPFP2=EDUWnt!GW8vjw7vbj<6Xi2d zmkKS7o4>X9B}5!9sH39;5nrED<_XlxQ4-`A45Yze`}3fMKt{c%i(?3ftmwgwoJ@ui ztPif=c-}efU4n(*27z}61VyG7a$J78Q1Zb82c7&jorJD>=5~Xhb|uf(y)4`@;Z9HX zmo@L?+0T0&Jox_1lrs;yS6vrZH`P3JX383uGm)3_J1d?m*@_yT+_Z%KnQQOiC2AHv oTq@g{`yQ35$bO5s%XZ-}V|t54)E+nOa*&%mUHx3vIVCg!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!ia0vp^4M6O`!VDx8ekAz-DT4r?5LXsvE;bfkPIeJ~J~2@~ z19hp;(zy9sdtc%bm*bgZ1=Pz?666;Qq`_eO^Pq(c42*rAE{-7)hu>b`>vcFmB&)BTM(WJn$tN6`~Ce68JJ%+6dvU?1dC3sEtQoH{C zd;GU~xl;o<9tg#6^V-b#U|GB3vx?W}_R9x1tYJ=(iDs4f)*yRBi{Y4f85d83(gX!b zld_*DmOP)3!*^gGbF?eNgLUlL_D&)nId5o1vMVy&(E4`YzUYtiX1}I=t5&U={^gD! zgQ|Mf{HaD#droHnrDt9`d3m;_#ir7iwi#PbtHj@wYMuDjNWD5>_T1vDHLlsKR{cD6 z$o50%?BlCSeW>F z^0(Cj;o%$Q4RY`8e0wnK9QR{ehv&C%&l5LGv5)xu`H=jJgXZyfO;s;w_FM) 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