From 3d38d757384579ee62dd2f58594e376a34585bfb Mon Sep 17 00:00:00 2001 From: Cristiano Magro <cristiano.magro@vola.it> Date: Tue, 13 Oct 2020 20:17:38 +0200 Subject: [PATCH] Collect rubber and tree --- technic/tools/xno_tree_tap.lua | 144 +++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 119 insertions(+), 25 deletions(-) diff --git a/technic/tools/xno_tree_tap.lua b/technic/tools/xno_tree_tap.lua index d030399..c73c73a 100644 --- a/technic/tools/xno_tree_tap.lua +++ b/technic/tools/xno_tree_tap.lua @@ -1,3 +1,105 @@ +-- A simple special-purpose class, this is used for building up sets of three-dimensional points for fast reference + +Pointset = {} +Pointset.__index = Pointset + +function Pointset.create() + local set = {} + setmetatable(set,Pointset) + set.points = {} + return set +end + +function Pointset:set(x, y, z, value) + -- sets a value in the 3D array "points". + if self.points[x] == nil then + self.points[x] = {} + end + if self.points[x][y] == nil then + self.points[x][y] = {} + end + self.points[x][y][z] = value +end + +function Pointset:set_if_not_in(excluded, x, y, z, value) + -- If a value is not already set for this point in the 3D array "excluded", set it in "points" + if excluded:get(x, y, z) ~= nil then + return + end + self:set(x, y, z, value) +end + +function Pointset:get(x, y, z) + -- return a value from the 3D array "points" + if self.points[x] == nil or self.points[x][y] == nil then + return nil + end + return self.points[x][y][z] +end + +function Pointset:set_pos(pos, value) + self:set(pos.x, pos.y, pos.z, value) +end + +function Pointset:set_pos_if_not_in(excluded, pos, value) + self:set_if_not_in(excluded, pos.x, pos.y, pos.z, value) +end + +function Pointset:get_pos(pos) + return self:get(pos.x, pos.y, pos.z) +end + +function Pointset:pop() + -- returns a point that's in the 3D array, and then removes it. + local pos = {} + local ytable + local ztable + local val + + local count = 0 + for _ in pairs(self.points) do count = count + 1 end + if count == 0 then + return nil + end + + pos.x, ytable = next(self.points) + pos.y, ztable = next(ytable) + pos.z, val = next(ztable) + + self.points[pos.x][pos.y][pos.z] = nil + + count = 0 + for _ in pairs(self.points[pos.x][pos.y]) do count = count + 1 end + if count == 0 then + self.points[pos.x][pos.y] = nil + end + + count = 0 + for _ in pairs(self.points[pos.x]) do count = count + 1 end + if count == 0 then + self.points[pos.x] = nil + end + + return pos, val +end + +function Pointset:get_pos_list(value) + -- Returns a list of all points with the given value in standard Minetest vector format. If no value is provided, returns all points + local outlist = {} + for x, ytable in ipairs(self.points) do + for y, ztable in ipairs(ytable) do + for z, val in ipairs(ztable) do + if (value == nil and val ~= nil ) or val == value then + table.insert(outlist, {x=x, y=y, z=z}) + end + end + end + end + return outlist +end + + + -- Configuration local xnotreetap_max_charge = 30000 -- Maximum charge of the saw @@ -16,7 +118,7 @@ } -- Remember node visited recursive and not dig twice -local node_visited = {} +local nodeVisited = Pointset.create() local timber_nodenames = {} for _, node in pairs(nodes) do @@ -51,6 +153,10 @@ -- Table for saving what was sawed down local produced = {} + +local function myString (v) + return v.x.." "..v.y.." "..v.z.." " +end -- Save the items sawed down so that we can drop them in a nice single stack local function handle_drops(drops) @@ -119,44 +225,32 @@ -- inserisco un valore in tabella local function add_table(table, toadd) - local i = 1 - while true do - local o = table[i] - if o == toadd then return end - if o == nil then break end - i = i + 1 - end - table[i] = toadd + table:set(toadd.x, toadd.y, toadd.z, true) end -- bool controllo se un valore � presente in tabella -local function in_table(table, value) - local i = 1 - while true do - local o = table[i] - if o == value then - minetest.log("action", "[Xno Tree Tap] "..value.." visited.") --print to log - return true +local function in_table(table, pos) + local val = table:get(pos.x, pos.y, pos.z) + local visited = 'NO' + + if val ~= nil then + if val then + visited = 'SI' end - if o == nil then break end - i = i + 1 + minetest.log("action", "[Xno Tree Tap] "..myString(pos).." visited? " .. visited) --print to log + return val end return false end -- verifico se un nodo � nella tabella visitato local function check_if_node_visited (pos) - return in_table(node_visited, pos) -end - -local function myString (v) - return v.x.." "..v.y.." "..v.z.." " + return in_table(nodeVisited, pos) end local function set_node_visited (pos) minetest.log("action", "[Xno Tree Tap] "..myString(pos).." set node visited.") --print to log - - add_table(node_visited, pos) + add_table(nodeVisited, pos) end -- This function does all the hard work. Recursively we dig the node at hand -- Gitblit v1.8.0