Cristiano Magro
2020-10-13 3d38d757384579ee62dd2f58594e376a34585bfb
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