288 lines
7.4 KiB
Lua
288 lines
7.4 KiB
Lua
local load_time_start = os.clock()
|
|
treecapitator = {}
|
|
|
|
|
|
--------------------------------------Settings----------------------------------------------
|
|
|
|
treecapitator.drop_items = false --drop them / get them in the inventory
|
|
treecapitator.drop_leaf = false
|
|
treecapitator.default_tree = { --replaces not defined stuff (see below)
|
|
trees = {"default:tree"},
|
|
leaves = {"default:leaves"},
|
|
range = 2,
|
|
fruits = {},
|
|
}
|
|
|
|
---------------------------------------------------------------------------------------------
|
|
|
|
|
|
--the table where the trees are stored at
|
|
treecapitator.trees = {}
|
|
|
|
--a table of trunks which couldn't be redefined
|
|
treecapitator.rest_tree_nodes = {}
|
|
|
|
|
|
--------------------------------------------fcts----------------------------------------------
|
|
|
|
--definitions of functions for the destruction of nodes
|
|
local destroy_node, drop_leaf, remove_leaf
|
|
if treecapitator.drop_items then
|
|
function drop_leaf(pos, item, inv)
|
|
minetest.add_item(pos, item)
|
|
end
|
|
|
|
function destroy_node(pos, node, digger)
|
|
local drops = minetest.get_node_drops(node.name)
|
|
for _,item in ipairs(drops) do
|
|
minetest.add_item(pos, item)
|
|
end
|
|
minetest.remove_node(pos)
|
|
end
|
|
else
|
|
function drop_leaf(pos, item, inv)
|
|
if inv
|
|
and inv:room_for_item("main", item) then
|
|
inv:add_item("main", item)
|
|
else
|
|
minetest.add_item(pos, item)
|
|
end
|
|
end
|
|
|
|
function destroy_node(pos, node, digger)
|
|
minetest.node_dig(pos, node, digger)
|
|
end
|
|
end
|
|
|
|
if not treecapitator.drop_leaf then
|
|
function remove_leaf(p, leaf, inv)
|
|
local leaves_drops = minetest.get_node_drops(leaf)
|
|
for _, itemname in ipairs(leaves_drops) do
|
|
if itemname ~= leaf then
|
|
drop_leaf(p, itemname, inv)
|
|
end
|
|
end
|
|
minetest.remove_node(p) --remove the leaves
|
|
end
|
|
else
|
|
function remove_leaf(p, _, _, node, digger)
|
|
destroy_node(p, node, digger)
|
|
end
|
|
end
|
|
|
|
|
|
table.icontains = table.icontains or function(t, v)
|
|
for _,i in ipairs(t) do
|
|
if i == v then
|
|
return true
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
--tests if the node is a trunk
|
|
local function findtree(node)
|
|
if node == 0 then
|
|
return true
|
|
end
|
|
if table.icontains(treecapitator.rest_tree_nodes, node.name) then
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
--returns positions for leaves allowed to be dug
|
|
local function find_next_trees(pos, range, trees, leaves, fruits)
|
|
local tab = {}
|
|
local r = 2*range
|
|
for i = -r, r do
|
|
for j = -r, r do
|
|
for h = r,-r,-1 do
|
|
local p = {x=pos.x+j, y=pos.y+h, z=pos.z+i}
|
|
|
|
local leaf = minetest.get_node({x=p.x, y=p.y+1, z=p.z}).name
|
|
local leaf_found = table.icontains(leaves, leaf) or table.icontains(fruits, leaf)
|
|
if not leaf_found then
|
|
leaf = minetest.get_node({x=p.x, y=p.y, z=p.z+1}).name
|
|
leaf_found = table.icontains(leaves, leaf) or table.icontains(fruits, leaf)
|
|
end
|
|
|
|
if table.icontains(trees, minetest.get_node(p).name)
|
|
and leaf_found then
|
|
for z = -range+i,range+i do
|
|
for y = -range+h,range+h do
|
|
for x = -range+j,range+j do
|
|
if math.abs(z) <= range
|
|
and math.abs(y) <= range
|
|
and math.abs(x) <= range then
|
|
tab[z.." "..y.." "..x] = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
--minetest.chat_send_all(dump(tab)) <— I used these to find my mistake
|
|
local tab2,n = {},1
|
|
for z = -range,range do
|
|
for y = -range,range do
|
|
for x = -range,range do
|
|
if not tab[z.." "..y.." "..x] then
|
|
local p = {x=x, y=y, z=z}
|
|
tab2[n] = p
|
|
n = n+1
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return tab2
|
|
end
|
|
|
|
|
|
--the function which is used for capitating
|
|
local capitating = false --necessary if minetest.node_dig is used
|
|
local function capitate_tree(pos, node, digger)
|
|
if capitating then
|
|
return
|
|
end
|
|
--minetest.chat_send_all("test0") <— and this
|
|
if digger == nil then
|
|
return
|
|
end
|
|
if digger:get_player_control().sneak
|
|
or not findtree(node) then
|
|
return
|
|
end
|
|
local t1 = os.clock()
|
|
capitating = true
|
|
|
|
local np = {x=pos.x, y=pos.y+1, z=pos.z}
|
|
local nd = minetest.get_node(np)
|
|
for _,tr in ipairs(treecapitator.trees) do
|
|
local trees = tr.trees
|
|
local tree_found = table.icontains(trees, nd.name)
|
|
if tree_found then
|
|
local tab, n = {}, 1
|
|
while tree_found do
|
|
tab[n] = {vector.new(np), nd}
|
|
n = n+1
|
|
np.y = np.y+1
|
|
nd = minetest.get_node(np)
|
|
tree_found = table.icontains(trees, nd.name)
|
|
end
|
|
local leaves = tr.leaves
|
|
local fruits = tr.fruits
|
|
|
|
np.y = np.y-1
|
|
local leaf_found = table.icontains(leaves, nd.name) or table.icontains(fruits, nd.name)
|
|
if not leaf_found then
|
|
local leaf = minetest.get_node({x=np.x, y=np.y, z=np.z+1}).name
|
|
leaf_found = table.icontains(leaves, leaf) or table.icontains(fruits, leaf)
|
|
end
|
|
|
|
if leaf_found then
|
|
for _,i in ipairs(tab) do
|
|
destroy_node(i[1], i[2], digger)
|
|
end
|
|
local range = tr.range
|
|
local inv = digger:get_inventory()
|
|
local head_ps = find_next_trees(np, range, trees, leaves, fruits) --definition of the leavespositions
|
|
--minetest.chat_send_all("test1") <— this too
|
|
for _,i in ipairs(head_ps) do
|
|
local p = vector.add(np, i)
|
|
local node = minetest.get_node(p)
|
|
local nodename = node.name
|
|
if table.icontains(leaves, nodename) then
|
|
remove_leaf(p, nodename, inv, node, digger)
|
|
elseif table.icontains(fruits, nodename) then
|
|
destroy_node(p, node, digger)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
capitating = false
|
|
print(string.format("[treecapitator] tree capitated at ("..pos.x.."|"..pos.y.."|"..pos.z..") after ca. %.2fs", os.clock() - t1))
|
|
end
|
|
|
|
--adds trunks to rest_tree_nodes if they were overwritten by other mods
|
|
local tmp_trees = {}
|
|
local function test_overwritten(tree)
|
|
table.insert(tmp_trees, tree)
|
|
end
|
|
|
|
minetest.after(0, function()
|
|
for _,tree in pairs(tmp_trees) do
|
|
if not minetest.registered_nodes[tree].after_dig_node then
|
|
print("[treecapitator] Error: Overwriting "..tree.." went wrong.")
|
|
table.insert(treecapitator.rest_tree_nodes, tree)
|
|
end
|
|
end
|
|
tmp_trees = nil
|
|
end)
|
|
|
|
--tests if minetest.override_item is aviable
|
|
local new_version = minetest.override_item and true
|
|
|
|
if not new_version then
|
|
table.copy = table.copy or function(tab)
|
|
local tab2 = {}
|
|
for n,i in pairs(tab) do
|
|
tab2[n] = i
|
|
end
|
|
return tab2
|
|
end
|
|
end
|
|
|
|
--the function to register trees to become capitated
|
|
local num = 1
|
|
function treecapitator.register_tree(tab)
|
|
for name,value in pairs(treecapitator.default_tree) do
|
|
tab[name] = tab[name] or value --replaces not defined stuff
|
|
end
|
|
treecapitator.trees[num] = tab
|
|
num = num+1
|
|
|
|
for _,tree in pairs(tab.trees) do
|
|
local data = minetest.registered_nodes[tree]
|
|
if not data then
|
|
print("[treecapitator] Info: "..tree.." isn't registered yet.")
|
|
table.insert(treecapitator.rest_tree_nodes, tree)
|
|
else
|
|
if data.after_dig_node then
|
|
print("[treecapitator] Info: "..tree.." already has an after_dig_node.")
|
|
table.insert(treecapitator.rest_tree_nodes, tree)
|
|
else
|
|
if new_version then
|
|
minetest.override_item(tree, {
|
|
after_dig_node = function(pos, _, _, digger)
|
|
capitate_tree(pos, 0, digger)
|
|
end
|
|
})
|
|
else
|
|
data = table.copy(data)
|
|
data.after_dig_node = function(pos, _, _, digger)
|
|
capitate_tree(pos, 0, digger)
|
|
end
|
|
minetest.register_node(":"..tree, data)
|
|
end
|
|
test_overwritten(tree)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
dofile(minetest.get_modpath("treecapitator").."/trees.lua")
|
|
|
|
---------------------------------------------------------------------------------------------
|
|
|
|
|
|
--use register_on_dignode if trunks are left
|
|
if treecapitator.rest_tree_nodes[1] then
|
|
minetest.register_on_dignode(capitate_tree)
|
|
end
|
|
|
|
print(string.format("[treecapitator] loaded after ca. %.2fs", os.clock() - load_time_start))
|