From 0fb44d5afe49e31ce7f3d521e5440d17982bf263 Mon Sep 17 00:00:00 2001 From: Cristiano Magro <cristiano.magro@vola.it> Date: Sun, 11 Oct 2020 17:35:24 +0200 Subject: [PATCH] collect rubber and cut tree --- technic/tools/xno_tree_tap.lua | 421 +++++++++++++++++++++++++++------------------------- 1 files changed, 221 insertions(+), 200 deletions(-) diff --git a/technic/tools/xno_tree_tap.lua b/technic/tools/xno_tree_tap.lua index dd81828..99bc4da 100644 --- a/technic/tools/xno_tree_tap.lua +++ b/technic/tools/xno_tree_tap.lua @@ -9,17 +9,18 @@ -- First value is node name; second is whether the node is considered even if chainsaw_leaves is false. local nodes = { - -- Rubber trees from moretrees or technic_worldgen if moretrees isn't installed - {"moretrees:rubber_tree_trunk_empty", true}, - {"moretrees:rubber_tree_trunk", true}, - {"moretrees:rubber_tree_leaves", false}, + -- Rubber trees from moretrees or technic_worldgen if moretrees isn't installed + {"moretrees:rubber_tree_trunk_empty", true}, + {"moretrees:rubber_tree_trunk", true}, + {"moretrees:rubber_tree_leaves", false}, } + local timber_nodenames = {} for _, node in pairs(nodes) do - if chainsaw_leaves or node[2] then - timber_nodenames[node[1]] = true - end + if chainsaw_leaves or node[2] then + timber_nodenames[node[1]] = true + end end @@ -30,14 +31,14 @@ -- This function checks if the specified node should be sawed local function check_if_node_sawed(pos) - local node_name = minetest.get_node(pos).name - if timber_nodenames[node_name] - or (xnotreetap_leaves and minetest.get_item_group(node_name, "leaves") ~= 0) - or minetest.get_item_group(node_name, "tree") ~= 0 then - return true - end + local node_name = minetest.get_node(pos).name + if timber_nodenames[node_name] + or (xnotreetap_leaves and minetest.get_item_group(node_name, "leaves") ~= 0) + or minetest.get_item_group(node_name, "tree") ~= 0 then + return true + end - return false + return false end -- Table for saving what was sawed down @@ -45,16 +46,16 @@ -- Save the items sawed down so that we can drop them in a nice single stack local function handle_drops(drops) - for _, item in ipairs(drops) do - local stack = ItemStack(item) - local name = stack:get_name() - local p = produced[name] - if not p then - produced[name] = stack - else - p:set_count(p:get_count() + stack:get_count()) - end - end + for _, item in ipairs(drops) do + local stack = ItemStack(item) + local name = stack:get_name() + local p = produced[name] + if not p then + produced[name] = stack + else + p:set_count(p:get_count() + stack:get_count()) + end + end end --- Iterator over positions to try to saw around a sawed node. @@ -63,49 +64,49 @@ -- the chainsaw from cutting down nodes below the cutting position. -- @param pos Sawing position. local function iterSawTries(pos) - -- Copy position to prevent mangling it - local pos = vector.new(pos) - local i = 0 + -- Copy position to prevent mangling it + local pos = vector.new(pos) + local i = 0 - return function() - i = i + 1 - -- Given a (top view) area like so (where 5 is the starting position): - -- X --> - -- Z 123 - -- | 456 - -- V 789 - -- This will return positions 1, 4, 7, 2, 8 (skip 5), 3, 6, 9, - -- and the position above 5. - if i == 1 then - -- Move to starting position - pos.x = pos.x - 1 - pos.z = pos.z - 1 - elseif i == 4 or i == 7 then - -- Move to next X and back to start of Z when we reach - -- the end of a Z line. - pos.x = pos.x + 1 - pos.z = pos.z - 2 - elseif i == 5 then - -- Skip the middle position (we've already run on it) - -- and double-increment the counter. - pos.z = pos.z + 2 - i = i + 1 - elseif i <= 9 then - -- Go to next Z. - pos.z = pos.z + 1 - elseif i == 10 then - -- Move back to center and up. - -- The Y+ position must be last so that we don't dig - -- straight upward and not come down (since the Y- - -- position isn't checked). - pos.x = pos.x - 1 - pos.z = pos.z - 1 - pos.y = pos.y + 1 - else - return nil - end - return pos - end + return function() + i = i + 1 + -- Given a (top view) area like so (where 5 is the starting position): + -- X --> + -- Z 123 + -- | 456 + -- V 789 + -- This will return positions 1, 4, 7, 2, 8 (skip 5), 3, 6, 9, + -- and the position above 5. + if i == 1 then + -- Move to starting position + pos.x = pos.x - 1 + pos.z = pos.z - 1 + elseif i == 4 or i == 7 then + -- Move to next X and back to start of Z when we reach + -- the end of a Z line. + pos.x = pos.x + 1 + pos.z = pos.z - 2 + elseif i == 5 then + -- Skip the middle position (we've already run on it) + -- and double-increment the counter. + pos.z = pos.z + 2 + i = i + 1 + elseif i <= 9 then + -- Go to next Z. + pos.z = pos.z + 1 + elseif i == 10 then + -- Move back to center and up. + -- The Y+ position must be last so that we don't dig + -- straight upward and not come down (since the Y- + -- position isn't checked). + pos.x = pos.x - 1 + pos.z = pos.z - 1 + pos.y = pos.y + 1 + else + return nil + end + return pos + end end @@ -114,174 +115,194 @@ -- This function does all the hard work. Recursively we dig the node at hand -- if it is in the table and then search the surroundings for more stuff to dig. local function recursive_dig(pos, remaining_charge) - if remaining_charge < xnotreetap_charge_per_node then - return remaining_charge - end - local node = minetest.get_node(pos) + if remaining_charge < xnotreetap_charge_per_node then + return remaining_charge + end + local node = minetest.get_node(pos) - if not check_if_node_sawed(pos) then - return remaining_charge - end + if not check_if_node_sawed(pos) then + return remaining_charge + end - -- Wood found - cut it - handle_drops(minetest.get_node_drops(node.name, "")) - minetest.remove_node(pos) - remaining_charge = remaining_charge - xnotreetap_charge_per_node - -- Check surroundings and run recursively if any charge left - for npos in iterSawTries(pos) do - if remaining_charge < xnotreetap_charge_per_node then - break - end - if check_if_node_sawed(npos) then - remaining_charge = recursive_dig(npos, remaining_charge) - else - minetest.check_for_falling(npos) - end - end - return remaining_charge + if node.name == "moretrees:rubber_tree_trunk" then + --raccolta gomma + node.name = "moretrees:rubber_tree_trunk_empty" + minetest.swap_node(pos, node) + minetest.handle_node_drops(pointed_thing.above, {"technic:raw_latex"}, user) + remaining_charge = remaining_charge - xnotreetap_charge_per_node + + -- Wood found - cut it + handle_drops(minetest.get_node_drops(node.name, "")) + minetest.remove_node(pos) + remaining_charge = remaining_charge - xnotreetap_charge_per_node + + if not technic.creative_mode then + local item_wear = tonumber(itemstack:get_wear()) + item_wear = item_wear + 819 + if item_wear > 65535 then + itemstack:clear() + return itemstack + end + itemstack:set_wear(item_wear) + end + end + + -- Check surroundings and run recursively if any charge left + for npos in iterSawTries(pos) do + if remaining_charge < xnotreetap_charge_per_node then + break + end + if check_if_node_sawed(npos) then + remaining_charge = recursive_dig(npos, remaining_charge) + else + minetest.check_for_falling(npos) + end + end + return remaining_charge end -- Function to randomize positions for new node drops local function get_drop_pos(pos) - local drop_pos = {} + local drop_pos = {} - for i = 0, 8 do - -- Randomize position for a new drop - drop_pos.x = pos.x + math.random(-3, 3) - drop_pos.y = pos.y - 1 - drop_pos.z = pos.z + math.random(-3, 3) + for i = 0, 8 do + -- Randomize position for a new drop + drop_pos.x = pos.x + math.random(-3, 3) + drop_pos.y = pos.y - 1 + drop_pos.z = pos.z + math.random(-3, 3) - -- Move the randomized position upwards until - -- the node is air or unloaded. - for y = drop_pos.y, drop_pos.y + 5 do - drop_pos.y = y - local node = minetest.get_node_or_nil(drop_pos) + -- Move the randomized position upwards until + -- the node is air or unloaded. + for y = drop_pos.y, drop_pos.y + 5 do + drop_pos.y = y + local node = minetest.get_node_or_nil(drop_pos) - if not node then - -- If the node is not loaded yet simply drop - -- the item at the original digging position. - return pos - elseif node.name == "air" then - -- Add variation to the entity drop position, - -- but don't let drops get too close to the edge - drop_pos.x = drop_pos.x + (math.random() * 0.8) - 0.5 - drop_pos.z = drop_pos.z + (math.random() * 0.8) - 0.5 - return drop_pos - end - end - end + if not node then + -- If the node is not loaded yet simply drop + -- the item at the original digging position. + return pos + elseif node.name == "air" then + -- Add variation to the entity drop position, + -- but don't let drops get too close to the edge + drop_pos.x = drop_pos.x + (math.random() * 0.8) - 0.5 + drop_pos.z = drop_pos.z + (math.random() * 0.8) - 0.5 + return drop_pos + end + end + end - -- Return the original position if this takes too long - return pos + -- Return the original position if this takes too long + return pos end -- Chainsaw entry point local function xnotreetap_dig(pos, current_charge) - -- Start sawing things down - local remaining_charge = recursive_dig(pos, current_charge) - minetest.sound_play("chainsaw", {pos = pos, gain = 1.0, - max_hear_distance = 10}) + -- Start sawing things down + local remaining_charge = recursive_dig(pos, current_charge) + minetest.sound_play("chainsaw", {pos = pos, gain = 1.0, + max_hear_distance = 10}) - -- Now drop items for the player - for name, stack in pairs(produced) do - -- Drop stacks of stack max or less - local count, max = stack:get_count(), stack:get_stack_max() - stack:set_count(max) - while count > max do - minetest.add_item(get_drop_pos(pos), stack) - count = count - max - end - stack:set_count(count) - minetest.add_item(get_drop_pos(pos), stack) - end + -- Now drop items for the player + for name, stack in pairs(produced) do + -- Drop stacks of stack max or less + local count, max = stack:get_count(), stack:get_stack_max() + stack:set_count(max) + while count > max do + minetest.add_item(get_drop_pos(pos), stack) + count = count - max + end + stack:set_count(count) + minetest.add_item(get_drop_pos(pos), stack) + end - -- Clean up - produced = {} + -- Clean up + produced = {} - return remaining_charge + return remaining_charge end minetest.register_tool("technic:xnotreetap", { - description = S("Xno Tree Tap"), - inventory_image = "technic_tree_tap.png", - stack_max = 1, - wear_represents = "technic_RE_charge", - on_refill = technic.refill_RE_charge, - on_use = function(itemstack, user, pointed_thing) - if pointed_thing.type ~= "node" then - return itemstack - end + description = S("Xno Tree Tap"), + inventory_image = "technic_tree_tap.png", + stack_max = 1, + wear_represents = "technic_RE_charge", + on_refill = technic.refill_RE_charge, + on_use = function(itemstack, user, pointed_thing) + if pointed_thing.type ~= "node" then + return itemstack + end - //check tool charge - local meta = minetest.deserialize(itemstack:get_metadata()) - if not meta or not meta.charge or - meta.charge < xnotreetap_charge_per_node then - return - end + --check tool charge + local meta = minetest.deserialize(itemstack:get_metadata()) + if not meta or not meta.charge or + meta.charge < xnotreetap_charge_per_node then + return + end - //check node protection - local pos = pointed_thing.under - if minetest.is_protected(pos, user:get_player_name()) then - minetest.record_protection_violation(pos, user:get_player_name()) - return - end + --check node protection + local pos = pointed_thing.under + if minetest.is_protected(pos, user:get_player_name()) then + minetest.record_protection_violation(pos, user:get_player_name()) + return + end - local node = minetest.get_node(pos) - local node_name = node.name - if node_name ~= "moretrees:rubber_tree_trunk" then - return - end + --can collect only from rubber + local node = minetest.get_node(pos) + local node_name = node.name + if node_name ~= "moretrees:rubber_tree_trunk" then + return + end - //raccolta gomma - node.name = "moretrees:rubber_tree_trunk_empty" - minetest.swap_node(pos, node) - minetest.handle_node_drops(pointed_thing.above, {"technic:raw_latex"}, user) + --raccolta gomma + -- node.name = "moretrees:rubber_tree_trunk_empty" + -- minetest.swap_node(pos, node) + -- minetest.handle_node_drops(pointed_thing.above, {"technic:raw_latex"}, user) + -- + -- if not technic.creative_mode then + -- local item_wear = tonumber(itemstack:get_wear()) + -- item_wear = item_wear + 819 + -- if item_wear > 65535 then + -- itemstack:clear() + -- return itemstack + -- end + -- itemstack:set_wear(item_wear) + -- end + -- return itemstack - if not technic.creative_mode then - local item_wear = tonumber(itemstack:get_wear()) - item_wear = item_wear + 819 - if item_wear > 65535 then - itemstack:clear() - return itemstack - end - itemstack:set_wear(item_wear) - end - return itemstack + -- Send current charge to digging function so that the + -- chainsaw will stop after digging a number of nodes + meta.charge = xnotreetap_dig(pointed_thing.under, meta.charge) + if not technic.creative_mode then + technic.set_RE_wear(itemstack, meta.charge, xnotreetap_max_charge) + itemstack:set_metadata(minetest.serialize(meta)) + end + return itemstack - -- Send current charge to digging function so that the - -- chainsaw will stop after digging a number of nodes - meta.charge = xnotreetap_dig(pointed_thing.under, meta.charge) - if not technic.creative_mode then - technic.set_RE_wear(itemstack, meta.charge, xnotreetap_max_charge) - itemstack:set_metadata(minetest.serialize(meta)) - end - return itemstack - - end, + end, }) minetest.register_craft({ - output = "technic:xnotreetap", - recipe = { - {"pipeworks:tube_1", "group:wood", "default:stick"}, - {"technic:battery", "default:stick", "default:stick"} - {"technic:battery", "default:stick", "default:stick"} - }, + output = "technic:xnotreetap", + recipe = { + {"pipeworks:tube_1", "group:wood", "default:stick"}, + {"technic:battery", "default:stick", "default:stick"}, + {"technic:battery", "default:stick", "default:stick"}, + }, }) minetest.register_abm({ - label = "Tools: xno tree tap", - nodenames = {"moretrees:rubber_tree_trunk_empty"}, - interval = 60, - chance = 15, - action = function(pos, node) - if minetest.find_node_near(pos, (moretrees and moretrees.leafdecay_radius) or 5, {"moretrees:rubber_tree_leaves"}) then - node.name = "moretrees:rubber_tree_trunk" - minetest.swap_node(pos, node) - end - end + label = "Tools: xno tree tap", + nodenames = {"moretrees:rubber_tree_trunk_empty"}, + interval = 60, + chance = 15, + action = function(pos, node) + if minetest.find_node_near(pos, (moretrees and moretrees.leafdecay_radius) or 5, {"moretrees:rubber_tree_leaves"}) then + node.name = "moretrees:rubber_tree_trunk" + minetest.swap_node(pos, node) + end + end }) -- Gitblit v1.8.0