mirror of
https://github.com/minetest-mods/digtron.git
synced 2025-01-03 01:27:28 +01:00
Optimization of table allocation, more sophisticated entity damage (#37)
This pass cleans up a lot of unnecessary table allocation and disposal, which should help with memory usage and garbage collection. It also adds some sophistication to the entity damage process from diggers, allowing items to be picked up into Digtron inventory.
This commit is contained in:
parent
fe753a9bed
commit
5c0700456c
@ -76,10 +76,10 @@ digtron.award_layout = function(layout, player)
|
|||||||
awards.unlock(name, "digtron_size100")
|
awards.unlock(name, "digtron_size100")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if table.getn(layout.diggers) > 24 then
|
if layout.diggers ~= nil and table.getn(layout.diggers) > 24 then
|
||||||
awards.unlock(name, "digtron_digger25")
|
awards.unlock(name, "digtron_digger25")
|
||||||
end
|
end
|
||||||
if table.getn(layout.builders) > 24 then
|
if layout.builders ~= nil and table.getn(layout.builders) > 24 then
|
||||||
awards.unlock(name, "digtron_builder25")
|
awards.unlock(name, "digtron_builder25")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
187
class_layout.lua
187
class_layout.lua
@ -39,13 +39,6 @@ function DigtronLayout.create(pos, player)
|
|||||||
--initialize. We're assuming that the start position is a controller digtron, should be a safe assumption since only the controller node should call this
|
--initialize. We're assuming that the start position is a controller digtron, should be a safe assumption since only the controller node should call this
|
||||||
self.traction = 0
|
self.traction = 0
|
||||||
self.all = {}
|
self.all = {}
|
||||||
self.inventories = {}
|
|
||||||
self.fuelstores = {}
|
|
||||||
self.battery_holders = {} -- technic batteries
|
|
||||||
self.power_connectors = {} -- technic power cable
|
|
||||||
self.diggers = {}
|
|
||||||
self.builders = {}
|
|
||||||
self.auto_ejectors = {}
|
|
||||||
self.extents = {}
|
self.extents = {}
|
||||||
self.water_touching = false
|
self.water_touching = false
|
||||||
self.lava_touching = false
|
self.lava_touching = false
|
||||||
@ -118,21 +111,30 @@ function DigtronLayout.create(pos, player)
|
|||||||
|
|
||||||
-- add a reference to this node's position to special node lists
|
-- add a reference to this node's position to special node lists
|
||||||
if group_number == 2 then
|
if group_number == 2 then
|
||||||
|
self.inventories = self.inventories or {}
|
||||||
table.insert(self.inventories, node_image)
|
table.insert(self.inventories, node_image)
|
||||||
elseif group_number == 3 then
|
elseif group_number == 3 then
|
||||||
|
self.diggers = self.diggers or {}
|
||||||
table.insert(self.diggers, node_image)
|
table.insert(self.diggers, node_image)
|
||||||
elseif group_number == 4 then
|
elseif group_number == 4 then
|
||||||
|
self.builders = self.builders or {}
|
||||||
table.insert(self.builders, node_image)
|
table.insert(self.builders, node_image)
|
||||||
elseif group_number == 5 then
|
elseif group_number == 5 then
|
||||||
|
self.fuelstores = self.fuelstores or {}
|
||||||
table.insert(self.fuelstores, node_image)
|
table.insert(self.fuelstores, node_image)
|
||||||
elseif group_number == 6 then
|
elseif group_number == 6 then
|
||||||
|
self.inventories = self.inventories or {}
|
||||||
|
self.fuelstores = self.fuelstores or {}
|
||||||
table.insert(self.inventories, node_image)
|
table.insert(self.inventories, node_image)
|
||||||
table.insert(self.fuelstores, node_image)
|
table.insert(self.fuelstores, node_image)
|
||||||
elseif group_number == 7 then
|
elseif group_number == 7 then -- technic batteries
|
||||||
|
self.battery_holders = self.battery_holders or {}
|
||||||
table.insert(self.battery_holders, node_image)
|
table.insert(self.battery_holders, node_image)
|
||||||
elseif group_number == 8 then
|
elseif group_number == 8 then
|
||||||
table.insert(self.power_connectors, node_image)
|
self.power_connectors = self.power_connectors or {}
|
||||||
|
table.insert(self.power_connectors, node_image) -- technic power connectors
|
||||||
elseif group_number == 9 and node_image.meta.fields["autoeject"] == "true" then
|
elseif group_number == 9 and node_image.meta.fields["autoeject"] == "true" then
|
||||||
|
self.auto_ejectors = self.auto_ejectors or {}
|
||||||
table.insert(self.auto_ejectors, node_image)
|
table.insert(self.auto_ejectors, node_image)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -202,32 +204,60 @@ local wallmounted_rotate = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
--90 degrees CW about x-axis: (x, y, z) -> (x, -z, y)
|
--90 degrees CW about x-axis: (x, y, z) -> (x, -z, y)
|
||||||
--90 degrees CCW about x-axis: (x, y, z) -> (x, z, -y)
|
--90 degrees CCW about x-axis: (x, y, z) -> (x, z, -y)
|
||||||
--90 degrees CW about y-axis: (x, y, z) -> (-z, y, x)
|
--90 degrees CW about y-axis: (x, y, z) -> (-z, y, x)
|
||||||
--90 degrees CCW about y-axis: (x, y, z) -> (z, y, -x)
|
--90 degrees CCW about y-axis: (x, y, z) -> (z, y, -x)
|
||||||
--90 degrees CW about z-axis: (x, y, z) -> (y, -x, z)
|
--90 degrees CW about z-axis: (x, y, z) -> (y, -x, z)
|
||||||
--90 degrees CCW about z-axis: (x, y, z) -> (-y, x, z)
|
--90 degrees CCW about z-axis: (x, y, z) -> (-y, x, z)
|
||||||
|
-- operates directly on the pos vector
|
||||||
local rotate_pos = function(axis, direction, pos)
|
local rotate_pos = function(axis, direction, pos)
|
||||||
if axis == "x" then
|
if axis == "x" then
|
||||||
if direction < 0 then
|
if direction < 0 then
|
||||||
return {x= pos.x, y= -pos.z, z= pos.y}
|
local temp_z = pos.z
|
||||||
|
pos.z = pos.y
|
||||||
|
pos.y = -temp_z
|
||||||
else
|
else
|
||||||
return {x= pos.x, y= pos.z, z= -pos.y}
|
local temp_z = pos.z
|
||||||
|
pos.z = -pos.y
|
||||||
|
pos.y = temp_z
|
||||||
end
|
end
|
||||||
elseif axis == "y" then
|
elseif axis == "y" then
|
||||||
if direction < 0 then
|
if direction < 0 then
|
||||||
return {x= -pos.z, y= pos.y, z= pos.x}
|
local temp_x = pos.x
|
||||||
|
pos.x = -pos.z
|
||||||
|
pos.z = temp_x
|
||||||
else
|
else
|
||||||
return {x= pos.z, y= pos.y, z= -pos.x}
|
local temp_x = pos.x
|
||||||
|
pos.x = pos.z
|
||||||
|
pos.z = -temp_x
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if direction < 0 then
|
if direction < 0 then
|
||||||
return {x= -pos.y, y= pos.x, z= pos.z}
|
local temp_x = pos.x
|
||||||
|
pos.x = -pos.y
|
||||||
|
pos.y = temp_x
|
||||||
else
|
else
|
||||||
return {x= pos.y, y= -pos.x, z= pos.z}
|
local temp_x = pos.x
|
||||||
|
pos.x = pos.y
|
||||||
|
pos.y = -temp_x
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
return pos
|
||||||
|
end
|
||||||
|
|
||||||
|
-- operates directly on the pos vector
|
||||||
|
local subtract_in_place = function(pos, subtract)
|
||||||
|
pos.x = pos.x - subtract.x
|
||||||
|
pos.y = pos.y - subtract.y
|
||||||
|
pos.z = pos.z - subtract.z
|
||||||
|
return pos
|
||||||
|
end
|
||||||
|
local add_in_place = function(pos, add)
|
||||||
|
pos.x = pos.x + add.x
|
||||||
|
pos.y = pos.y + add.y
|
||||||
|
pos.z = pos.z + add.z
|
||||||
|
return pos
|
||||||
end
|
end
|
||||||
|
|
||||||
local rotate_node_image = function(node_image, origin, axis, direction, old_pos_pointset)
|
local rotate_node_image = function(node_image, origin, axis, direction, old_pos_pointset)
|
||||||
@ -250,14 +280,23 @@ local rotate_node_image = function(node_image, origin, axis, direction, old_pos_
|
|||||||
old_pos_pointset:set(node_image.pos.x, node_image.pos.y, node_image.pos.z, true)
|
old_pos_pointset:set(node_image.pos.x, node_image.pos.y, node_image.pos.z, true)
|
||||||
|
|
||||||
-- position in space relative to origin
|
-- position in space relative to origin
|
||||||
local pos = vector.subtract(node_image.pos, origin)
|
local pos = subtract_in_place(node_image.pos, origin)
|
||||||
pos = rotate_pos(axis, direction, pos)
|
pos = rotate_pos(axis, direction, pos)
|
||||||
-- Move back to original reference frame
|
-- Move back to original reference frame
|
||||||
node_image.pos = vector.add(pos, origin)
|
node_image.pos = add_in_place(pos, origin)
|
||||||
|
|
||||||
return node_image
|
return node_image
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local top = {
|
||||||
|
[0]={axis="y", dir=-1},
|
||||||
|
{axis="z", dir=1},
|
||||||
|
{axis="z", dir=-1},
|
||||||
|
{axis="x", dir=1},
|
||||||
|
{axis="x", dir=-1},
|
||||||
|
{axis="y", dir=1},
|
||||||
|
}
|
||||||
-- Rotates 90 degrees widdershins around the axis defined by facedir (which in this case is pointing out the front of the node, so it needs to be converted into an upward-pointing axis internally)
|
-- Rotates 90 degrees widdershins around the axis defined by facedir (which in this case is pointing out the front of the node, so it needs to be converted into an upward-pointing axis internally)
|
||||||
function DigtronLayout.rotate_layout_image(self, facedir)
|
function DigtronLayout.rotate_layout_image(self, facedir)
|
||||||
-- To convert this into the direction the "top" of the axle node is pointing in:
|
-- To convert this into the direction the "top" of the axle node is pointing in:
|
||||||
@ -268,14 +307,6 @@ function DigtronLayout.rotate_layout_image(self, facedir)
|
|||||||
-- 16, 17, 18, 19 == (-1,0,0)
|
-- 16, 17, 18, 19 == (-1,0,0)
|
||||||
-- 20, 21, 22, 23== (0,-1,0)
|
-- 20, 21, 22, 23== (0,-1,0)
|
||||||
|
|
||||||
local top = {
|
|
||||||
[0]={axis="y", dir=-1},
|
|
||||||
{axis="z", dir=1},
|
|
||||||
{axis="z", dir=-1},
|
|
||||||
{axis="x", dir=1},
|
|
||||||
{axis="x", dir=-1},
|
|
||||||
{axis="y", dir=1},
|
|
||||||
}
|
|
||||||
local params = top[math.floor(facedir/4)]
|
local params = top[math.floor(facedir/4)]
|
||||||
|
|
||||||
for k, node_image in pairs(self.all) do
|
for k, node_image in pairs(self.all) do
|
||||||
@ -299,7 +330,7 @@ function DigtronLayout.move_layout_image(self, dir)
|
|||||||
|
|
||||||
for k, node_image in pairs(self.all) do
|
for k, node_image in pairs(self.all) do
|
||||||
self.old_pos_pointset:set(node_image.pos.x, node_image.pos.y, node_image.pos.z, true)
|
self.old_pos_pointset:set(node_image.pos.x, node_image.pos.y, node_image.pos.z, true)
|
||||||
node_image.pos = vector.add(node_image.pos, dir)
|
node_image.pos = add_in_place(node_image.pos, dir)
|
||||||
self.nodes_dug:set(node_image.pos.x, node_image.pos.y, node_image.pos.z, false) -- we've moved a digtron node into this space, mark it so that we don't dig it.
|
self.nodes_dug:set(node_image.pos.x, node_image.pos.y, node_image.pos.z, false) -- we've moved a digtron node into this space, mark it so that we don't dig it.
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -329,41 +360,56 @@ end
|
|||||||
-- if done during mid-write. So we need to defer the calls until after the
|
-- if done during mid-write. So we need to defer the calls until after the
|
||||||
-- Digtron has been fully written.
|
-- Digtron has been fully written.
|
||||||
|
|
||||||
local node_callbacks = function(dug_nodes, placed_nodes, player)
|
-- using local counters and shared tables like this allows us to avoid some needless allocating and garbage-collecting of tables
|
||||||
for _, dug_node in pairs(dug_nodes) do
|
local dug_nodes_count = 0
|
||||||
local old_pos = dug_node[1]
|
local dug_node_pos = {}
|
||||||
local old_node = dug_node[2]
|
local dug_node = {}
|
||||||
local old_meta = dug_node[3]
|
local dug_node_meta = {}
|
||||||
|
|
||||||
for _, callback in ipairs(minetest.registered_on_dignodes) do
|
local placed_nodes_count = 0
|
||||||
-- Copy pos and node because callback can modify them
|
local placed_node_pos = {}
|
||||||
local pos_copy = {x=old_pos.x, y=old_pos.y, z=old_pos.z}
|
local placed_new_node = {}
|
||||||
local oldnode_copy = {name=old_node.name, param1=old_node.param1, param2=old_node.param2}
|
local placed_old_node = {}
|
||||||
callback(pos_copy, oldnode_copy, digtron.fake_player)
|
|
||||||
end
|
|
||||||
|
|
||||||
local old_def = minetest.registered_nodes[old_node.name]
|
local node_callbacks = function(player)
|
||||||
if old_def ~= nil and old_def.after_dig_node ~= nil then
|
if dug_nodes_count > 0 then
|
||||||
old_def.after_dig_node(old_pos, old_node, old_meta, player)
|
for i = 1, dug_nodes_count do
|
||||||
|
local old_pos = dug_node_pos[i]
|
||||||
|
local old_node = dug_node[i]
|
||||||
|
local old_meta = dug_node_meta[i]
|
||||||
|
|
||||||
|
for _, callback in ipairs(minetest.registered_on_dignodes) do
|
||||||
|
-- Copy pos and node because callback can modify them
|
||||||
|
local pos_copy = {x=old_pos.x, y=old_pos.y, z=old_pos.z}
|
||||||
|
local oldnode_copy = {name=old_node.name, param1=old_node.param1, param2=old_node.param2}
|
||||||
|
callback(pos_copy, oldnode_copy, digtron.fake_player)
|
||||||
|
end
|
||||||
|
|
||||||
|
local old_def = minetest.registered_nodes[old_node.name]
|
||||||
|
if old_def ~= nil and old_def.after_dig_node ~= nil then
|
||||||
|
old_def.after_dig_node(old_pos, old_node, old_meta, player)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, placed_node in pairs(placed_nodes) do
|
if placed_nodes_count > 0 then
|
||||||
local new_pos = placed_node[1]
|
for i = 1, placed_nodes_count do
|
||||||
local new_node = placed_node[2]
|
local new_pos = placed_node_pos[i]
|
||||||
local old_node = placed_node[3]
|
local new_node = placed_new_node[i]
|
||||||
|
local old_node = placed_old_node[i]
|
||||||
|
|
||||||
for _, callback in ipairs(minetest.registered_on_placenodes) do
|
for _, callback in ipairs(minetest.registered_on_placenodes) do
|
||||||
-- Copy pos and node because callback can modify them
|
-- Copy pos and node because callback can modify them
|
||||||
local pos_copy = {x=new_pos.x, y=new_pos.y, z=new_pos.z}
|
local pos_copy = {x=new_pos.x, y=new_pos.y, z=new_pos.z}
|
||||||
local oldnode_copy = {name=old_node.name, param1=old_node.param1, param2=old_node.param2}
|
local oldnode_copy = {name=old_node.name, param1=old_node.param1, param2=old_node.param2}
|
||||||
local newnode_copy = {name=new_node.name, param1=new_node.param1, param2=new_node.param2}
|
local newnode_copy = {name=new_node.name, param1=new_node.param1, param2=new_node.param2}
|
||||||
callback(pos_copy, newnode_copy, digtron.fake_player, oldnode_copy)
|
callback(pos_copy, newnode_copy, digtron.fake_player, oldnode_copy)
|
||||||
end
|
end
|
||||||
|
|
||||||
local new_def = minetest.registered_nodes[new_node.name]
|
local new_def = minetest.registered_nodes[new_node.name]
|
||||||
if new_def ~= nil and new_def.after_place_node ~= nil then
|
if new_def ~= nil and new_def.after_place_node ~= nil then
|
||||||
new_def.after_place_node(new_pos, player)
|
new_def.after_place_node(new_pos, player)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -388,22 +434,23 @@ local set_meta_with_retry = function(meta, meta_table)
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local air_node = {name="air"}
|
||||||
function DigtronLayout.write_layout_image(self, player)
|
function DigtronLayout.write_layout_image(self, player)
|
||||||
local dug_nodes = {}
|
|
||||||
local placed_nodes = {}
|
|
||||||
|
|
||||||
-- destroy the old digtron
|
-- destroy the old digtron
|
||||||
local oldpos, _ = self.old_pos_pointset:pop()
|
local oldpos, _ = self.old_pos_pointset:pop()
|
||||||
while oldpos ~= nil do
|
while oldpos ~= nil do
|
||||||
local old_node = minetest.get_node(oldpos)
|
local old_node = minetest.get_node(oldpos)
|
||||||
local old_meta = minetest.get_meta(oldpos)
|
local old_meta = minetest.get_meta(oldpos)
|
||||||
|
|
||||||
if not set_node_with_retry(oldpos, {name="air"}) then
|
if not set_node_with_retry(oldpos, air_node) then
|
||||||
minetest.log("error", "DigtronLayout.write_layout_image failed to destroy old Digtron node, aborting write.")
|
minetest.log("error", "DigtronLayout.write_layout_image failed to destroy old Digtron node, aborting write.")
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
table.insert(dug_nodes, {oldpos, old_node, old_meta})
|
dug_nodes_count = dug_nodes_count + 1
|
||||||
|
dug_node_pos[dug_nodes_count] = oldpos
|
||||||
|
dug_node[dug_nodes_count] = old_node
|
||||||
|
dug_node_meta[dug_nodes_count] = old_meta
|
||||||
oldpos, _ = self.old_pos_pointset:pop()
|
oldpos, _ = self.old_pos_pointset:pop()
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -418,15 +465,19 @@ function DigtronLayout.write_layout_image(self, player)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
table.insert(placed_nodes, {new_pos, new_node, old_node})
|
placed_nodes_count = placed_nodes_count + 1
|
||||||
|
placed_node_pos[placed_nodes_count] = new_pos
|
||||||
|
placed_new_node[placed_nodes_count] = new_node
|
||||||
|
placed_old_node[placed_nodes_count] = old_node
|
||||||
end
|
end
|
||||||
|
|
||||||
-- fake_player will be passed to callbacks to prevent actual player from "taking the blame" for this action.
|
-- fake_player will be passed to callbacks to prevent actual player from "taking the blame" for this action.
|
||||||
-- For example, the hunger mod shouldn't be making the player hungry when he moves Digtron.
|
-- For example, the hunger mod shouldn't be making the player hungry when he moves Digtron.
|
||||||
digtron.fake_player:update(self.controller, player:get_player_name())
|
digtron.fake_player:update(self.controller, player:get_player_name())
|
||||||
-- note that the actual player is still passed to the per-node after_place_node and after_dig_node, should they exist.
|
-- note that the actual player is still passed to the per-node after_place_node and after_dig_node, should they exist.
|
||||||
node_callbacks(dug_nodes, placed_nodes, player)
|
node_callbacks(player)
|
||||||
|
dug_nodes_count = 0
|
||||||
|
placed_nodes_count = 0
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -3,6 +3,13 @@
|
|||||||
Pointset = {}
|
Pointset = {}
|
||||||
Pointset.__index = Pointset
|
Pointset.__index = Pointset
|
||||||
|
|
||||||
|
-- from builtin\game\misc.lua, modified to take values directly to avoid creating an intermediate vector
|
||||||
|
local hash_node_position_values = function(x, y, z)
|
||||||
|
return (z + 32768) * 65536 * 65536
|
||||||
|
+ (y + 32768) * 65536
|
||||||
|
+ x + 32768
|
||||||
|
end
|
||||||
|
|
||||||
function Pointset.create()
|
function Pointset.create()
|
||||||
local set = {}
|
local set = {}
|
||||||
setmetatable(set,Pointset)
|
setmetatable(set,Pointset)
|
||||||
@ -12,13 +19,7 @@ end
|
|||||||
|
|
||||||
function Pointset:set(x, y, z, value)
|
function Pointset:set(x, y, z, value)
|
||||||
-- sets a value in the 3D array "points".
|
-- sets a value in the 3D array "points".
|
||||||
if self.points[x] == nil then
|
self.points[hash_node_position_values(x,y,z)] = value
|
||||||
self.points[x] = {}
|
|
||||||
end
|
|
||||||
if self.points[x][y] == nil then
|
|
||||||
self.points[x][y] = {}
|
|
||||||
end
|
|
||||||
self.points[x][y][z] = value
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function Pointset:set_if_not_in(excluded, x, y, z, value)
|
function Pointset:set_if_not_in(excluded, x, y, z, value)
|
||||||
@ -31,10 +32,7 @@ end
|
|||||||
|
|
||||||
function Pointset:get(x, y, z)
|
function Pointset:get(x, y, z)
|
||||||
-- return a value from the 3D array "points"
|
-- return a value from the 3D array "points"
|
||||||
if self.points[x] == nil or self.points[x][y] == nil then
|
return self.points[hash_node_position_values(x,y,z)]
|
||||||
return nil
|
|
||||||
end
|
|
||||||
return self.points[x][y][z]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function Pointset:set_pos(pos, value)
|
function Pointset:set_pos(pos, value)
|
||||||
@ -51,48 +49,19 @@ end
|
|||||||
|
|
||||||
function Pointset:pop()
|
function Pointset:pop()
|
||||||
-- returns a point that's in the 3D array, and then removes it.
|
-- returns a point that's in the 3D array, and then removes it.
|
||||||
local pos = {}
|
local hash, value = next(self.points)
|
||||||
local ytable
|
if hash == nil then return nil end
|
||||||
local ztable
|
local pos = minetest.get_position_from_hash(hash)
|
||||||
local val
|
self.points[hash] = nil
|
||||||
|
return pos, value
|
||||||
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
|
end
|
||||||
|
|
||||||
function Pointset:get_pos_list(value)
|
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
|
-- 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 = {}
|
local outlist = {}
|
||||||
for x, ytable in ipairs(self.points) do
|
for hash, pointsval in pairs(self.points) do
|
||||||
for y, ztable in ipairs(ytable) do
|
if value == nil or pointsval == value then
|
||||||
for z, val in ipairs(ztable) do
|
table.insert(outlist, minetest.get_position_from_hash(hash))
|
||||||
if (value == nil and val ~= nil ) or val == value then
|
|
||||||
table.insert(outlist, {x=x, y=y, z=z})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return outlist
|
return outlist
|
||||||
|
@ -25,7 +25,10 @@ end
|
|||||||
|
|
||||||
setting("bool", "uses_resources", true, "Digtron uses resources when active")
|
setting("bool", "uses_resources", true, "Digtron uses resources when active")
|
||||||
setting("bool", "lava_impassible", true, "Lava counts as a protected node")
|
setting("bool", "lava_impassible", true, "Lava counts as a protected node")
|
||||||
setting("bool", "damage_creatures", true, "Diggers damage creatures")
|
setting("bool", "damage_creatures", true, "Diggers damage creatures") -- TODO: legacy setting, remove eventually
|
||||||
|
setting("int", "damage_hp", 8, "Damage diggers do")
|
||||||
|
|
||||||
|
if digtron.config.damage_creatures == false then digtron.config.damage_hp = 0 end -- TODO: remove when damage_creatures is removed
|
||||||
|
|
||||||
-- Enables the spray of particles out the back of a digger head and puffs of smoke from the controller
|
-- Enables the spray of particles out the back of a digger head and puffs of smoke from the controller
|
||||||
local particle_effects = minetest.settings:get_bool("enable_particles")
|
local particle_effects = minetest.settings:get_bool("enable_particles")
|
||||||
|
@ -4,6 +4,8 @@ local S, NS = dofile(MP.."/intllib.lua")
|
|||||||
|
|
||||||
-- Note: builders go in group 4 and have both test_build and execute_build methods.
|
-- Note: builders go in group 4 and have both test_build and execute_build methods.
|
||||||
|
|
||||||
|
local node_inventory_table = {type="node"} -- a reusable parameter for get_inventory calls, set the pos parameter before using.
|
||||||
|
|
||||||
local displace_due_to_help_button = 1.0
|
local displace_due_to_help_button = 1.0
|
||||||
if minetest.get_modpath("doc") then
|
if minetest.get_modpath("doc") then
|
||||||
displace_due_to_help_button = 0.0
|
displace_due_to_help_button = 0.0
|
||||||
@ -42,7 +44,6 @@ end
|
|||||||
|
|
||||||
local builder_formspec = function(pos, meta)
|
local builder_formspec = function(pos, meta)
|
||||||
local nodemeta = "nodemeta:"..pos.x .. "," .. pos.y .. "," ..pos.z
|
local nodemeta = "nodemeta:"..pos.x .. "," .. pos.y .. "," ..pos.z
|
||||||
minetest.debug(nodemeta)
|
|
||||||
return builder_formspec_string
|
return builder_formspec_string
|
||||||
:gsub("${extrusion}", meta:get_int("extrusion"), 1)
|
:gsub("${extrusion}", meta:get_int("extrusion"), 1)
|
||||||
:gsub("${period}", meta:get_int("period"), 1)
|
:gsub("${period}", meta:get_int("period"), 1)
|
||||||
@ -200,7 +201,8 @@ minetest.register_node("digtron:builder", {
|
|||||||
return 0 -- don't allow craft items unless their on_place is whitelisted.
|
return 0 -- don't allow craft items unless their on_place is whitelisted.
|
||||||
end
|
end
|
||||||
|
|
||||||
local inv = minetest.get_inventory({type="node", pos=pos})
|
node_inventory_table.pos = pos
|
||||||
|
local inv = minetest.get_inventory(node_inventory_table)
|
||||||
inv:set_stack(listname, index, stack:take_item(1))
|
inv:set_stack(listname, index, stack:take_item(1))
|
||||||
|
|
||||||
-- If we're adding a wallmounted item and the build facing is greater than 5, reset it to 0
|
-- If we're adding a wallmounted item and the build facing is greater than 5, reset it to 0
|
||||||
@ -213,7 +215,8 @@ minetest.register_node("digtron:builder", {
|
|||||||
end,
|
end,
|
||||||
|
|
||||||
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
|
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
|
||||||
local inv = minetest.get_inventory({type="node", pos=pos})
|
node_inventory_table.pos = pos
|
||||||
|
local inv = minetest.get_inventory(node_inventory_table)
|
||||||
inv:set_stack(listname, index, ItemStack(""))
|
inv:set_stack(listname, index, ItemStack(""))
|
||||||
return 0
|
return 0
|
||||||
end,
|
end,
|
||||||
@ -246,7 +249,8 @@ minetest.register_node("digtron:builder", {
|
|||||||
|
|
||||||
local return_items = {}
|
local return_items = {}
|
||||||
|
|
||||||
local inv = minetest.get_inventory({type="node", pos=pos})
|
node_inventory_table.pos = pos
|
||||||
|
local inv = minetest.get_inventory(node_inventory_table)
|
||||||
local item_stack = inv:get_stack("main", 1)
|
local item_stack = inv:get_stack("main", 1)
|
||||||
|
|
||||||
if item_stack:is_empty() then
|
if item_stack:is_empty() then
|
||||||
@ -296,7 +300,8 @@ minetest.register_node("digtron:builder", {
|
|||||||
end
|
end
|
||||||
local built_count = 0
|
local built_count = 0
|
||||||
|
|
||||||
local inv = minetest.get_inventory({type="node", pos=pos})
|
node_inventory_table.pos = pos
|
||||||
|
local inv = minetest.get_inventory(node_inventory_table)
|
||||||
local item_stack = inv:get_stack("main", 1)
|
local item_stack = inv:get_stack("main", 1)
|
||||||
if item_stack:is_empty() then
|
if item_stack:is_empty() then
|
||||||
return built_count
|
return built_count
|
||||||
|
@ -15,6 +15,8 @@ local controller_nodebox ={
|
|||||||
{-0.5, -0.5, -0.5, -0.125, -0.125, -0.3125}, -- back_connector_4
|
{-0.5, -0.5, -0.5, -0.125, -0.125, -0.3125}, -- back_connector_4
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local node_inventory_table = {type="node"} -- a reusable parameter for get_inventory calls, set the pos parameter before using.
|
||||||
|
|
||||||
-- Master controller. Most complicated part of the whole system. Determines which direction a digtron moves and triggers all of its component parts.
|
-- Master controller. Most complicated part of the whole system. Determines which direction a digtron moves and triggers all of its component parts.
|
||||||
minetest.register_node("digtron:controller", {
|
minetest.register_node("digtron:controller", {
|
||||||
description = S("Digtron Control Module"),
|
description = S("Digtron Control Module"),
|
||||||
@ -128,7 +130,7 @@ local function auto_cycle(pos)
|
|||||||
meta:set_string("infotext", status)
|
meta:set_string("infotext", status)
|
||||||
if return_code == 1 then --return code 1 happens when there's unloaded nodes adjacent, just keep trying.
|
if return_code == 1 then --return code 1 happens when there's unloaded nodes adjacent, just keep trying.
|
||||||
if digtron.config.emerge_unloaded_mapblocks then
|
if digtron.config.emerge_unloaded_mapblocks then
|
||||||
minetest.emerge_area(vector.add(pos, -128), vector.add(pos, 128))
|
minetest.emerge_area(vector.add(pos, -80), vector.add(pos, 80))
|
||||||
end
|
end
|
||||||
minetest.after(meta:get_int("period"), auto_cycle, newpos)
|
minetest.after(meta:get_int("period"), auto_cycle, newpos)
|
||||||
else
|
else
|
||||||
@ -150,7 +152,7 @@ local function auto_cycle(pos)
|
|||||||
meta:set_string("infotext", status)
|
meta:set_string("infotext", status)
|
||||||
if return_code == 1 then --return code 1 happens when there's unloaded nodes adjacent, call emerge and keep trying.
|
if return_code == 1 then --return code 1 happens when there's unloaded nodes adjacent, call emerge and keep trying.
|
||||||
if digtron.config.emerge_unloaded_mapblocks then
|
if digtron.config.emerge_unloaded_mapblocks then
|
||||||
minetest.emerge_area(vector.add(pos, -128), vector.add(pos, 128))
|
minetest.emerge_area(vector.add(pos, -80), vector.add(pos, 80))
|
||||||
end
|
end
|
||||||
minetest.after(meta:get_int("period"), auto_cycle, newpos)
|
minetest.after(meta:get_int("period"), auto_cycle, newpos)
|
||||||
else
|
else
|
||||||
@ -220,13 +222,15 @@ minetest.register_node("digtron:auto_controller", {
|
|||||||
if minetest.get_item_group(stack:get_name(), "digtron") ~= 0 then
|
if minetest.get_item_group(stack:get_name(), "digtron") ~= 0 then
|
||||||
return 0 -- pointless setting a Digtron node as a stop block
|
return 0 -- pointless setting a Digtron node as a stop block
|
||||||
end
|
end
|
||||||
local inv = minetest.get_inventory({type="node", pos=pos})
|
node_inventory_table.pos = pos
|
||||||
|
local inv = minetest.get_inventory(node_inventory_table)
|
||||||
inv:set_stack(listname, index, stack:take_item(1))
|
inv:set_stack(listname, index, stack:take_item(1))
|
||||||
return 0
|
return 0
|
||||||
end,
|
end,
|
||||||
|
|
||||||
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
|
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
|
||||||
local inv = minetest.get_inventory({type="node", pos=pos})
|
node_inventory_table.pos = pos
|
||||||
|
local inv = minetest.get_inventory(node_inventory_table)
|
||||||
inv:set_stack(listname, index, ItemStack(""))
|
inv:set_stack(listname, index, ItemStack(""))
|
||||||
return 0
|
return 0
|
||||||
end,
|
end,
|
||||||
|
@ -4,6 +4,9 @@ local S, NS = dofile(MP.."/intllib.lua")
|
|||||||
|
|
||||||
-- Note: diggers go in group 3 and have an execute_dig method.
|
-- Note: diggers go in group 3 and have an execute_dig method.
|
||||||
|
|
||||||
|
local damage_hp = digtron.config.damage_hp
|
||||||
|
local damage_hp_half = damage_hp/2
|
||||||
|
|
||||||
local digger_nodebox = {
|
local digger_nodebox = {
|
||||||
{-0.5, -0.5, 0, 0.5, 0.5, 0.4375}, -- Block
|
{-0.5, -0.5, 0, 0.5, 0.5, 0.4375}, -- Block
|
||||||
{-0.4375, -0.3125, 0.4375, 0.4375, 0.3125, 0.5}, -- Cutter1
|
{-0.4375, -0.3125, 0.4375, 0.4375, 0.3125, 0.5}, -- Cutter1
|
||||||
@ -132,15 +135,15 @@ minetest.register_node("digtron:digger", {
|
|||||||
local digpos = digtron.find_new_pos(pos, facing)
|
local digpos = digtron.find_new_pos(pos, facing)
|
||||||
|
|
||||||
if protected_nodes:get(digpos.x, digpos.y, digpos.z) then
|
if protected_nodes:get(digpos.x, digpos.y, digpos.z) then
|
||||||
return 0, {}
|
return 0
|
||||||
end
|
end
|
||||||
|
|
||||||
return digtron.mark_diggable(digpos, nodes_dug, player)
|
return digtron.mark_diggable(digpos, nodes_dug, player)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
damage_creatures = function(player, pos, controlling_coordinate)
|
damage_creatures = function(player, pos, controlling_coordinate, items_dropped)
|
||||||
local facing = minetest.get_node(pos).param2
|
local facing = minetest.get_node(pos).param2
|
||||||
digtron.damage_creatures(player, digtron.find_new_pos(pos, facing), 8)
|
digtron.damage_creatures(player, pos, digtron.find_new_pos(pos, facing), damage_hp, items_dropped)
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -184,33 +187,33 @@ minetest.register_node("digtron:intermittent_digger", {
|
|||||||
|
|
||||||
on_rightclick = intermittent_on_rightclick,
|
on_rightclick = intermittent_on_rightclick,
|
||||||
|
|
||||||
-- returns fuel_cost, item_produced
|
-- returns fuel_cost, item_produced (a table or nil)
|
||||||
execute_dig = function(pos, protected_nodes, nodes_dug, controlling_coordinate, lateral_dig, player)
|
execute_dig = function(pos, protected_nodes, nodes_dug, controlling_coordinate, lateral_dig, player)
|
||||||
if lateral_dig == true then
|
if lateral_dig == true then
|
||||||
return 0, {}
|
return 0
|
||||||
end
|
end
|
||||||
|
|
||||||
local facing = minetest.get_node(pos).param2
|
local facing = minetest.get_node(pos).param2
|
||||||
local digpos = digtron.find_new_pos(pos, facing)
|
local digpos = digtron.find_new_pos(pos, facing)
|
||||||
|
|
||||||
if protected_nodes:get(digpos.x, digpos.y, digpos.z) then
|
if protected_nodes:get(digpos.x, digpos.y, digpos.z) then
|
||||||
return 0, {}
|
return 0
|
||||||
end
|
end
|
||||||
|
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
if (digpos[controlling_coordinate] + meta:get_int("offset")) % meta:get_int("period") ~= 0 then
|
if (digpos[controlling_coordinate] + meta:get_int("offset")) % meta:get_int("period") ~= 0 then
|
||||||
return 0, {}
|
return 0
|
||||||
end
|
end
|
||||||
|
|
||||||
return digtron.mark_diggable(digpos, nodes_dug, player)
|
return digtron.mark_diggable(digpos, nodes_dug, player)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
damage_creatures = function(player, pos, controlling_coordinate)
|
damage_creatures = function(player, pos, controlling_coordinate, items_dropped)
|
||||||
local facing = minetest.get_node(pos).param2
|
local facing = minetest.get_node(pos).param2
|
||||||
local targetpos = digtron.find_new_pos(pos, facing)
|
local targetpos = digtron.find_new_pos(pos, facing)
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
if (targetpos[controlling_coordinate] + meta:get_int("offset")) % meta:get_int("period") == 0 then
|
if (targetpos[controlling_coordinate] + meta:get_int("offset")) % meta:get_int("period") == 0 then
|
||||||
digtron.damage_creatures(player, targetpos, 8)
|
digtron.damage_creatures(player, pos, targetpos, damage_hp, items_dropped)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
@ -255,19 +258,19 @@ minetest.register_node("digtron:soft_digger", {
|
|||||||
local digpos = digtron.find_new_pos(pos, facing)
|
local digpos = digtron.find_new_pos(pos, facing)
|
||||||
|
|
||||||
if protected_nodes:get(digpos.x, digpos.y, digpos.z) then
|
if protected_nodes:get(digpos.x, digpos.y, digpos.z) then
|
||||||
return 0, {}
|
return 0
|
||||||
end
|
end
|
||||||
|
|
||||||
if digtron.is_soft_material(digpos) then
|
if digtron.is_soft_material(digpos) then
|
||||||
return digtron.mark_diggable(digpos, nodes_dug, player)
|
return digtron.mark_diggable(digpos, nodes_dug, player)
|
||||||
end
|
end
|
||||||
|
|
||||||
return 0, {}
|
return 0
|
||||||
end,
|
end,
|
||||||
|
|
||||||
damage_creatures = function(player, pos, controlling_coordinate)
|
damage_creatures = function(player, pos, controlling_coordinate, items_dropped)
|
||||||
local facing = minetest.get_node(pos).param2
|
local facing = minetest.get_node(pos).param2
|
||||||
digtron.damage_creatures(player, digtron.find_new_pos(pos, facing), 4)
|
digtron.damage_creatures(player, pos, digtron.find_new_pos(pos, facing), damage_hp_half, items_dropped)
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -312,34 +315,34 @@ minetest.register_node("digtron:intermittent_soft_digger", {
|
|||||||
|
|
||||||
execute_dig = function(pos, protected_nodes, nodes_dug, controlling_coordinate, lateral_dig, player)
|
execute_dig = function(pos, protected_nodes, nodes_dug, controlling_coordinate, lateral_dig, player)
|
||||||
if lateral_dig == true then
|
if lateral_dig == true then
|
||||||
return 0, {}
|
return 0
|
||||||
end
|
end
|
||||||
|
|
||||||
local facing = minetest.get_node(pos).param2
|
local facing = minetest.get_node(pos).param2
|
||||||
local digpos = digtron.find_new_pos(pos, facing)
|
local digpos = digtron.find_new_pos(pos, facing)
|
||||||
|
|
||||||
if protected_nodes:get(digpos.x, digpos.y, digpos.z) then
|
if protected_nodes:get(digpos.x, digpos.y, digpos.z) then
|
||||||
return 0, {}
|
return 0
|
||||||
end
|
end
|
||||||
|
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
if (digpos[controlling_coordinate] + meta:get_int("offset")) % meta:get_int("period") ~= 0 then
|
if (digpos[controlling_coordinate] + meta:get_int("offset")) % meta:get_int("period") ~= 0 then
|
||||||
return 0, {}
|
return 0
|
||||||
end
|
end
|
||||||
|
|
||||||
if digtron.is_soft_material(digpos) then
|
if digtron.is_soft_material(digpos) then
|
||||||
return digtron.mark_diggable(digpos, nodes_dug, player)
|
return digtron.mark_diggable(digpos, nodes_dug, player)
|
||||||
end
|
end
|
||||||
|
|
||||||
return 0, {}
|
return 0
|
||||||
end,
|
end,
|
||||||
|
|
||||||
damage_creatures = function(player, pos, controlling_coordinate)
|
damage_creatures = function(player, pos, controlling_coordinate, items_dropped)
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
local facing = minetest.get_node(pos).param2
|
local facing = minetest.get_node(pos).param2
|
||||||
local targetpos = digtron.find_new_pos(pos, facing)
|
local targetpos = digtron.find_new_pos(pos, facing)
|
||||||
if (targetpos[controlling_coordinate] + meta:get_int("offset")) % meta:get_int("period") == 0 then
|
if (targetpos[controlling_coordinate] + meta:get_int("offset")) % meta:get_int("period") == 0 then
|
||||||
digtron.damage_creatures(player, targetpos, 4)
|
digtron.damage_creatures(player, pos, targetpos, damage_hp_half, items_dropped)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
@ -398,15 +401,19 @@ minetest.register_node("digtron:dual_digger", {
|
|||||||
|
|
||||||
if protected_nodes:get(digpos.x, digpos.y, digpos.z) ~= true then
|
if protected_nodes:get(digpos.x, digpos.y, digpos.z) ~= true then
|
||||||
local forward_cost, forward_items = digtron.mark_diggable(digpos, nodes_dug, player)
|
local forward_cost, forward_items = digtron.mark_diggable(digpos, nodes_dug, player)
|
||||||
for _, item in pairs(forward_items) do
|
if forward_items ~= nil then
|
||||||
table.insert(items, item)
|
for _, item in pairs(forward_items) do
|
||||||
|
table.insert(items, item)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
cost = cost + forward_cost
|
cost = cost + forward_cost
|
||||||
end
|
end
|
||||||
if protected_nodes:get(digdown.x, digdown.y, digdown.z) ~= true then
|
if protected_nodes:get(digdown.x, digdown.y, digdown.z) ~= true then
|
||||||
local down_cost, down_items = digtron.mark_diggable(digdown, nodes_dug, player)
|
local down_cost, down_items = digtron.mark_diggable(digdown, nodes_dug, player)
|
||||||
for _, item in pairs(down_items) do
|
if down_items ~= nil then
|
||||||
table.insert(items, item)
|
for _, item in pairs(down_items) do
|
||||||
|
table.insert(items, item)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
cost = cost + down_cost
|
cost = cost + down_cost
|
||||||
end
|
end
|
||||||
@ -414,10 +421,10 @@ minetest.register_node("digtron:dual_digger", {
|
|||||||
return cost, items
|
return cost, items
|
||||||
end,
|
end,
|
||||||
|
|
||||||
damage_creatures = function(player, pos, controlling_coordinate)
|
damage_creatures = function(player, pos, controlling_coordinate, items_dropped)
|
||||||
local facing = minetest.get_node(pos).param2
|
local facing = minetest.get_node(pos).param2
|
||||||
digtron.damage_creatures(player, digtron.find_new_pos(pos, facing), 8)
|
digtron.damage_creatures(player, pos, digtron.find_new_pos(pos, facing), damage_hp, items_dropped)
|
||||||
digtron.damage_creatures(player, digtron.find_new_pos_downward(pos, facing), 8)
|
digtron.damage_creatures(player, pos, digtron.find_new_pos_downward(pos, facing), damage_hp, items_dropped)
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -475,15 +482,19 @@ minetest.register_node("digtron:dual_soft_digger", {
|
|||||||
|
|
||||||
if protected_nodes:get(digpos.x, digpos.y, digpos.z) ~= true and digtron.is_soft_material(digpos) then
|
if protected_nodes:get(digpos.x, digpos.y, digpos.z) ~= true and digtron.is_soft_material(digpos) then
|
||||||
local forward_cost, forward_items = digtron.mark_diggable(digpos, nodes_dug, player)
|
local forward_cost, forward_items = digtron.mark_diggable(digpos, nodes_dug, player)
|
||||||
for _, item in pairs(forward_items) do
|
if forward_items ~= nil then
|
||||||
table.insert(items, item)
|
for _, item in pairs(forward_items) do
|
||||||
|
table.insert(items, item)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
cost = cost + forward_cost
|
cost = cost + forward_cost
|
||||||
end
|
end
|
||||||
if protected_nodes:get(digdown.x, digdown.y, digdown.z) ~= true and digtron.is_soft_material(digdown) then
|
if protected_nodes:get(digdown.x, digdown.y, digdown.z) ~= true and digtron.is_soft_material(digdown) then
|
||||||
local down_cost, down_items = digtron.mark_diggable(digdown, nodes_dug, player)
|
local down_cost, down_items = digtron.mark_diggable(digdown, nodes_dug, player)
|
||||||
for _, item in pairs(down_items) do
|
if down_items ~= nil then
|
||||||
table.insert(items, item)
|
for _, item in pairs(down_items) do
|
||||||
|
table.insert(items, item)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
cost = cost + down_cost
|
cost = cost + down_cost
|
||||||
end
|
end
|
||||||
@ -491,9 +502,9 @@ minetest.register_node("digtron:dual_soft_digger", {
|
|||||||
return cost, items
|
return cost, items
|
||||||
end,
|
end,
|
||||||
|
|
||||||
damage_creatures = function(player, pos, controlling_coordinate)
|
damage_creatures = function(player, pos, controlling_coordinate, items_dropped)
|
||||||
local facing = minetest.get_node(pos).param2
|
local facing = minetest.get_node(pos).param2
|
||||||
digtron.damage_creatures(player, digtron.find_new_pos(pos, facing), 4)
|
digtron.damage_creatures(player, pos, digtron.find_new_pos(pos, facing), damage_hp_half, items_dropped)
|
||||||
digtron.damage_creatures(player, digtron.find_new_pos_downward(pos, facing), 4)
|
digtron.damage_creatures(player, pos, digtron.find_new_pos_downward(pos, facing), damage_hp_half, items_dropped)
|
||||||
end,
|
end,
|
||||||
})
|
})
|
@ -144,25 +144,31 @@ minetest.register_node("digtron:duplicator", {
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- clear inventories of image's nodes
|
-- clear inventories of image's nodes
|
||||||
for _, node_image in pairs(layout.inventories) do
|
if layout.inventories ~= nil then
|
||||||
local main_inventory = node_image.meta.inventory.main
|
for _, node_image in pairs(layout.inventories) do
|
||||||
if type(main_inventory) ~= "table" then
|
local main_inventory = node_image.meta.inventory.main
|
||||||
main_inventory = {}
|
if type(main_inventory) ~= "table" then
|
||||||
end
|
main_inventory = {}
|
||||||
for index, _ in pairs(main_inventory) do
|
end
|
||||||
main_inventory[index] = ItemStack(nil)
|
for index, _ in pairs(main_inventory) do
|
||||||
|
main_inventory[index] = ItemStack(nil)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
for _, node_image in pairs(layout.fuelstores) do
|
if layout.fuelstores ~= nil then
|
||||||
local fuel_inventory = node_image.meta.inventory.fuel
|
for _, node_image in pairs(layout.fuelstores) do
|
||||||
for index, _ in pairs(fuel_inventory) do
|
local fuel_inventory = node_image.meta.inventory.fuel
|
||||||
fuel_inventory[index] = ItemStack(nil)
|
for index, _ in pairs(fuel_inventory) do
|
||||||
|
fuel_inventory[index] = ItemStack(nil)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
for _, node_image in pairs(layout.battery_holders) do
|
if layout.battery_holders ~= nil then
|
||||||
local battery_inventory = node_image.meta.inventory.batteries
|
for _, node_image in pairs(layout.battery_holders) do
|
||||||
for index, _ in pairs(battery_inventory) do
|
local battery_inventory = node_image.meta.inventory.batteries
|
||||||
battery_inventory[index] = ItemStack(nil)
|
for index, _ in pairs(battery_inventory) do
|
||||||
|
battery_inventory[index] = ItemStack(nil)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -58,15 +58,17 @@ local function eject_items(pos, node, player, eject_even_without_pipeworks)
|
|||||||
|
|
||||||
-- Build a list of all the items that builder nodes want to use.
|
-- Build a list of all the items that builder nodes want to use.
|
||||||
local filter_items = {}
|
local filter_items = {}
|
||||||
for _, node_image in pairs(layout.builders) do
|
if layout.builders ~= nil then
|
||||||
filter_items[node_image.meta.inventory.main[1]:get_name()] = true
|
for _, node_image in pairs(layout.builders) do
|
||||||
|
filter_items[node_image.meta.inventory.main[1]:get_name()] = true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Look through the inventories and find an item that's not on that list.
|
-- Look through the inventories and find an item that's not on that list.
|
||||||
local source_node = nil
|
local source_node = nil
|
||||||
local source_index = nil
|
local source_index = nil
|
||||||
local source_stack = nil
|
local source_stack = nil
|
||||||
for _, node_image in pairs(layout.inventories) do
|
for _, node_image in pairs(layout.inventories or {}) do
|
||||||
if type(node_image.meta.inventory.main) ~= "table" then
|
if type(node_image.meta.inventory.main) ~= "table" then
|
||||||
node_image.meta.inventory.main = {}
|
node_image.meta.inventory.main = {}
|
||||||
end
|
end
|
||||||
|
@ -69,11 +69,15 @@ minetest.register_node("digtron:power_connector", {
|
|||||||
on_receive_fields = function(pos, formname, fields, sender)
|
on_receive_fields = function(pos, formname, fields, sender)
|
||||||
local layout = DigtronLayout.create(pos, sender)
|
local layout = DigtronLayout.create(pos, sender)
|
||||||
local max_cost = 0
|
local max_cost = 0
|
||||||
for _, node_image in pairs(layout.builders) do
|
if layout.builders ~= nil then
|
||||||
max_cost = max_cost + (digtron.config.build_cost * (node_image.meta.fields.extrusion or 1))
|
for _, node_image in pairs(layout.builders) do
|
||||||
|
max_cost = max_cost + (digtron.config.build_cost * (node_image.meta.fields.extrusion or 1))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
for _, node_image in pairs(layout.diggers) do
|
if layout.diggers ~= nil then
|
||||||
max_cost = max_cost + max_dig_cost
|
for _, node_image in pairs(layout.diggers) do
|
||||||
|
max_cost = max_cost + max_dig_cost
|
||||||
|
end
|
||||||
end
|
end
|
||||||
local current_max = max_cost * digtron.config.power_ratio
|
local current_max = max_cost * digtron.config.power_ratio
|
||||||
|
|
||||||
|
@ -6,8 +6,9 @@ digtron_uses_resources (Digtron uses resources) bool true
|
|||||||
#When true, lava counts as protected blocks.
|
#When true, lava counts as protected blocks.
|
||||||
digtron_lava_impassible (Lava is impassible to Digtrons) bool true
|
digtron_lava_impassible (Lava is impassible to Digtrons) bool true
|
||||||
|
|
||||||
#When true, diggers deal damage to creatures when they trigger.
|
#Sets how much HP damage a digger does. Soft material diggers do half this.
|
||||||
digtron_damage_creatures (Digtrons cause damage) bool true
|
#Set to 0 to disable damage entirely.
|
||||||
|
digtron_damage_hp (Diggers damage this many hp) int 8
|
||||||
|
|
||||||
#How many seconds a digtron waits between cycles.
|
#How many seconds a digtron waits between cycles.
|
||||||
#Auto-controllers can make this wait longer, but cannot make it shorter.
|
#Auto-controllers can make this wait longer, but cannot make it shorter.
|
||||||
|
133
util.lua
133
util.lua
@ -3,6 +3,8 @@
|
|||||||
dofile( minetest.get_modpath( "digtron" ) .. "/util_item_place_node.lua" ) -- separated out to avoid potential for license complexity
|
dofile( minetest.get_modpath( "digtron" ) .. "/util_item_place_node.lua" ) -- separated out to avoid potential for license complexity
|
||||||
dofile( minetest.get_modpath( "digtron" ) .. "/util_execute_cycle.lua" ) -- separated out simply for tidiness, there's some big code in there
|
dofile( minetest.get_modpath( "digtron" ) .. "/util_execute_cycle.lua" ) -- separated out simply for tidiness, there's some big code in there
|
||||||
|
|
||||||
|
local node_inventory_table = {type="node"} -- a reusable parameter for get_inventory calls, set the pos parameter before using.
|
||||||
|
|
||||||
-- Apparently node_sound_metal_defaults is a newer thing, I ran into games using an older version of the default mod without it.
|
-- Apparently node_sound_metal_defaults is a newer thing, I ran into games using an older version of the default mod without it.
|
||||||
if default.node_sound_metal_defaults ~= nil then
|
if default.node_sound_metal_defaults ~= nil then
|
||||||
digtron.metal_sounds = default.node_sound_metal_defaults()
|
digtron.metal_sounds = default.node_sound_metal_defaults()
|
||||||
@ -17,14 +19,16 @@ digtron.find_new_pos = function(pos, facing)
|
|||||||
return vector.add(pos, dir)
|
return vector.add(pos, dir)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local facedir_to_down_dir_table = {
|
||||||
|
[0]={x=0, y=-1, z=0},
|
||||||
|
{x=0, y=0, z=-1},
|
||||||
|
{x=0, y=0, z=1},
|
||||||
|
{x=-1, y=0, z=0},
|
||||||
|
{x=1, y=0, z=0},
|
||||||
|
{x=0, y=1, z=0}
|
||||||
|
}
|
||||||
digtron.facedir_to_down_dir = function(facing)
|
digtron.facedir_to_down_dir = function(facing)
|
||||||
return (
|
return facedir_to_down_dir_table[math.floor(facing/4)]
|
||||||
{[0]={x=0, y=-1, z=0},
|
|
||||||
{x=0, y=0, z=-1},
|
|
||||||
{x=0, y=0, z=1},
|
|
||||||
{x=-1, y=0, z=0},
|
|
||||||
{x=1, y=0, z=0},
|
|
||||||
{x=0, y=1, z=0}})[math.floor(facing/4)]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
digtron.find_new_pos_downward = function(pos, facing)
|
digtron.find_new_pos_downward = function(pos, facing)
|
||||||
@ -42,7 +46,7 @@ digtron.mark_diggable = function(pos, nodes_dug, player)
|
|||||||
|
|
||||||
-- prevent digtrons from being marked for digging.
|
-- prevent digtrons from being marked for digging.
|
||||||
if minetest.get_item_group(target.name, "digtron") ~= 0 or minetest.get_item_group(target.name, "digtron_protected") ~= 0 then
|
if minetest.get_item_group(target.name, "digtron") ~= 0 or minetest.get_item_group(target.name, "digtron_protected") ~= 0 then
|
||||||
return 0, {}
|
return 0
|
||||||
end
|
end
|
||||||
|
|
||||||
local targetdef = minetest.registered_nodes[target.name]
|
local targetdef = minetest.registered_nodes[target.name]
|
||||||
@ -73,7 +77,7 @@ digtron.mark_diggable = function(pos, nodes_dug, player)
|
|||||||
return material_cost, minetest.get_node_drops(target.name, "")
|
return material_cost, minetest.get_node_drops(target.name, "")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return 0, {}
|
return 0
|
||||||
end
|
end
|
||||||
|
|
||||||
digtron.can_build_to = function(pos, protected_nodes, dug_nodes)
|
digtron.can_build_to = function(pos, protected_nodes, dug_nodes)
|
||||||
@ -108,11 +112,14 @@ end
|
|||||||
digtron.place_in_inventory = function(itemname, inventory_positions, fallback_pos)
|
digtron.place_in_inventory = function(itemname, inventory_positions, fallback_pos)
|
||||||
--tries placing the item in each inventory node in turn. If there's no room, drop it at fallback_pos
|
--tries placing the item in each inventory node in turn. If there's no room, drop it at fallback_pos
|
||||||
local itemstack = ItemStack(itemname)
|
local itemstack = ItemStack(itemname)
|
||||||
for k, location in pairs(inventory_positions) do
|
if inventory_positions ~= nil then
|
||||||
local inv = minetest.get_inventory({type="node", pos=location.pos})
|
for k, location in pairs(inventory_positions) do
|
||||||
itemstack = inv:add_item("main", itemstack)
|
node_inventory_table.pos = location.pos
|
||||||
if itemstack:is_empty() then
|
local inv = minetest.get_inventory(node_inventory_table)
|
||||||
return nil
|
itemstack = inv:add_item("main", itemstack)
|
||||||
|
if itemstack:is_empty() then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
minetest.add_item(fallback_pos, itemstack)
|
minetest.add_item(fallback_pos, itemstack)
|
||||||
@ -124,7 +131,8 @@ digtron.place_in_specific_inventory = function(itemname, pos, inventory_position
|
|||||||
--is trying to keep various inventories organized manually stuff will go back where it came from,
|
--is trying to keep various inventories organized manually stuff will go back where it came from,
|
||||||
--probably.
|
--probably.
|
||||||
local itemstack = ItemStack(itemname)
|
local itemstack = ItemStack(itemname)
|
||||||
local inv = minetest.get_inventory({type="node", pos=pos})
|
node_inventory_table.pos = pos
|
||||||
|
local inv = minetest.get_inventory(node_inventory_table)
|
||||||
local returned_stack = inv:add_item("main", itemstack)
|
local returned_stack = inv:add_item("main", itemstack)
|
||||||
if not returned_stack:is_empty() then
|
if not returned_stack:is_empty() then
|
||||||
-- we weren't able to put the item back into that particular inventory for some reason.
|
-- we weren't able to put the item back into that particular inventory for some reason.
|
||||||
@ -134,10 +142,12 @@ digtron.place_in_specific_inventory = function(itemname, pos, inventory_position
|
|||||||
end
|
end
|
||||||
|
|
||||||
digtron.take_from_inventory = function(itemname, inventory_positions)
|
digtron.take_from_inventory = function(itemname, inventory_positions)
|
||||||
|
if inventory_positions == nil then return nil end
|
||||||
--tries to take an item from each inventory node in turn. Returns location of inventory item was taken from on success, nil on failure
|
--tries to take an item from each inventory node in turn. Returns location of inventory item was taken from on success, nil on failure
|
||||||
local itemstack = ItemStack(itemname)
|
local itemstack = ItemStack(itemname)
|
||||||
for k, location in pairs(inventory_positions) do
|
for k, location in pairs(inventory_positions) do
|
||||||
local inv = minetest.get_inventory({type="node", pos=location.pos})
|
node_inventory_table.pos = location.pos
|
||||||
|
local inv = minetest.get_inventory(node_inventory_table)
|
||||||
local output = inv:remove_item("main", itemstack)
|
local output = inv:remove_item("main", itemstack)
|
||||||
if not output:is_empty() then
|
if not output:is_empty() then
|
||||||
return location.pos
|
return location.pos
|
||||||
@ -159,24 +169,31 @@ digtron.get_controlling_coordinate = function(pos, facedir)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local fuel_craft = {method="fuel", width=1, items={}} -- reusable crafting recipe table for get_craft_result calls below
|
||||||
-- Searches fuel store inventories for burnable items and burns them until target is reached or surpassed
|
-- Searches fuel store inventories for burnable items and burns them until target is reached or surpassed
|
||||||
-- (or there's nothing left to burn). Returns the total fuel value burned
|
-- (or there's nothing left to burn). Returns the total fuel value burned
|
||||||
-- if the "test" parameter is set to true, doesn't actually take anything out of inventories.
|
-- if the "test" parameter is set to true, doesn't actually take anything out of inventories.
|
||||||
-- We can get away with this sort of thing for fuel but not for builder inventory because there's just one
|
-- We can get away with this sort of thing for fuel but not for builder inventory because there's just one
|
||||||
-- controller node burning stuff, not multiple build heads drawing from inventories in turn. Much simpler.
|
-- controller node burning stuff, not multiple build heads drawing from inventories in turn. Much simpler.
|
||||||
digtron.burn = function(fuelstore_positions, target, test)
|
digtron.burn = function(fuelstore_positions, target, test)
|
||||||
|
if fuelstore_positions == nil then
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
local current_burned = 0
|
local current_burned = 0
|
||||||
for k, location in pairs(fuelstore_positions) do
|
for k, location in pairs(fuelstore_positions) do
|
||||||
if current_burned > target then
|
if current_burned > target then
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
local inv = minetest.get_inventory({type="node", pos=location.pos})
|
node_inventory_table.pos = location.pos
|
||||||
|
local inv = minetest.get_inventory(node_inventory_table)
|
||||||
local invlist = inv:get_list("fuel")
|
local invlist = inv:get_list("fuel")
|
||||||
for i, itemstack in pairs(invlist) do
|
for i, itemstack in pairs(invlist) do
|
||||||
local fuel_per_item = minetest.get_craft_result({method="fuel", width=1, items={itemstack:peek_item(1)}}).time
|
fuel_craft.items[1] = itemstack:peek_item(1)
|
||||||
|
local fuel_per_item = minetest.get_craft_result(fuel_craft).time
|
||||||
if fuel_per_item ~= 0 then
|
if fuel_per_item ~= 0 then
|
||||||
local actual_burned = math.min(
|
local actual_burned = math.min(
|
||||||
math.ceil((target - current_burned)/fuel_per_item ), -- burn this many, if we can.
|
math.ceil((target - current_burned)/fuel_per_item), -- burn this many, if we can.
|
||||||
itemstack:get_count() -- how many we have at most.
|
itemstack:get_count() -- how many we have at most.
|
||||||
)
|
)
|
||||||
if test ~= true then
|
if test ~= true then
|
||||||
@ -203,6 +220,10 @@ end
|
|||||||
-- factor, since if taken at face value (10000 EU), the batteries would be the ultimate power source barely
|
-- factor, since if taken at face value (10000 EU), the batteries would be the ultimate power source barely
|
||||||
-- ever needing replacement.
|
-- ever needing replacement.
|
||||||
digtron.tap_batteries = function(battery_positions, target, test)
|
digtron.tap_batteries = function(battery_positions, target, test)
|
||||||
|
if (battery_positions == nil) then
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
local current_burned = 0
|
local current_burned = 0
|
||||||
-- 1 coal block is 370 PU
|
-- 1 coal block is 370 PU
|
||||||
-- 1 coal lump is 40 PU
|
-- 1 coal lump is 40 PU
|
||||||
@ -210,15 +231,12 @@ digtron.tap_batteries = function(battery_positions, target, test)
|
|||||||
-- local power_ratio = 100 -- How much charge equals 1 unit of PU from coal
|
-- local power_ratio = 100 -- How much charge equals 1 unit of PU from coal
|
||||||
-- setting Moved to digtron.config.power_ratio
|
-- setting Moved to digtron.config.power_ratio
|
||||||
|
|
||||||
if (battery_positions == nil) then
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
|
|
||||||
for k, location in pairs(battery_positions) do
|
for k, location in pairs(battery_positions) do
|
||||||
if current_burned > target then
|
if current_burned > target then
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
local inv = minetest.get_inventory({type="node", pos=location.pos})
|
node_inventory_table.pos = location.pos
|
||||||
|
local inv = minetest.get_inventory(node_inventory_table)
|
||||||
local invlist = inv:get_list("batteries")
|
local invlist = inv:get_list("batteries")
|
||||||
|
|
||||||
if (invlist == nil) then
|
if (invlist == nil) then
|
||||||
@ -272,10 +290,6 @@ digtron.tap_batteries = function(battery_positions, target, test)
|
|||||||
return current_burned
|
return current_burned
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
digtron.remove_builder_item = function(pos)
|
digtron.remove_builder_item = function(pos)
|
||||||
local objects = minetest.env:get_objects_inside_radius(pos, 0.5)
|
local objects = minetest.env:get_objects_inside_radius(pos, 0.5)
|
||||||
if objects ~= nil then
|
if objects ~= nil then
|
||||||
@ -289,7 +303,8 @@ end
|
|||||||
|
|
||||||
digtron.update_builder_item = function(pos)
|
digtron.update_builder_item = function(pos)
|
||||||
digtron.remove_builder_item(pos)
|
digtron.remove_builder_item(pos)
|
||||||
local inv = minetest.get_inventory({type="node", pos=pos})
|
node_inventory_table.pos = pos
|
||||||
|
local inv = minetest.get_inventory(node_inventory_table)
|
||||||
local item_stack = inv:get_stack("main", 1)
|
local item_stack = inv:get_stack("main", 1)
|
||||||
if not item_stack:is_empty() then
|
if not item_stack:is_empty() then
|
||||||
digtron.create_builder_item = item_stack:get_name()
|
digtron.create_builder_item = item_stack:get_name()
|
||||||
@ -297,15 +312,61 @@ digtron.update_builder_item = function(pos)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
digtron.damage_creatures = function(player, pos, amount)
|
local damage_def = {
|
||||||
local objects = minetest.env:get_objects_inside_radius(pos, 1.0)
|
full_punch_interval = 1.0,
|
||||||
|
damage_groups = {},
|
||||||
|
}
|
||||||
|
digtron.damage_creatures = function(player, source_pos, target_pos, amount, items_dropped)
|
||||||
|
local objects = minetest.env:get_objects_inside_radius(target_pos, 1.0)
|
||||||
|
if objects ~= nil then
|
||||||
|
damage_def.damage_groups.fleshy = amount
|
||||||
|
local velocity = {
|
||||||
|
x = target_pos.x-source_pos.x,
|
||||||
|
y = target_pos.y-source_pos.y + 0.2,
|
||||||
|
z = target_pos.z-source_pos.z,
|
||||||
|
}
|
||||||
|
for _, obj in ipairs(objects) do
|
||||||
|
if obj:is_player() then
|
||||||
|
-- See issue #2960 for status of a "set player velocity" method
|
||||||
|
-- instead, knock the player back
|
||||||
|
newpos = {
|
||||||
|
x = target_pos.x + velocity.x,
|
||||||
|
y = target_pos.y + velocity.y,
|
||||||
|
z = target_pos.z + velocity.z,
|
||||||
|
}
|
||||||
|
obj:set_pos(newpos)
|
||||||
|
obj:punch(player, 1.0, damage_def, nil)
|
||||||
|
else
|
||||||
|
local lua_entity = obj:get_luaentity()
|
||||||
|
if lua_entity ~= nil then
|
||||||
|
if lua_entity.name == "__builtin:item" then
|
||||||
|
table.insert(items_dropped, lua_entity.itemstring)
|
||||||
|
lua_entity.itemstring = ""
|
||||||
|
obj:remove()
|
||||||
|
else
|
||||||
|
if obj.add_velocity ~= nil then
|
||||||
|
obj:add_velocity(velocity)
|
||||||
|
else
|
||||||
|
local vel = obj:get_velocity()
|
||||||
|
obj:set_velocity(vector.add(vel, velocity))
|
||||||
|
end
|
||||||
|
obj:punch(player, 1.0, damage_def, nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- If we killed any mobs they might have dropped some stuff, vacuum that up now too.
|
||||||
|
objects = minetest.env:get_objects_inside_radius(target_pos, 1.0)
|
||||||
if objects ~= nil then
|
if objects ~= nil then
|
||||||
for _, obj in ipairs(objects) do
|
for _, obj in ipairs(objects) do
|
||||||
if obj then
|
if not obj:is_player() then
|
||||||
obj:punch(player, 1.0, {
|
local lua_entity = obj:get_luaentity()
|
||||||
full_punch_interval = 1.0,
|
if lua_entity ~= nil and lua_entity.name == "__builtin:item" then
|
||||||
damage_groups = {fleshy = amount},
|
table.insert(items_dropped, lua_entity.itemstring)
|
||||||
}, nil )
|
lua_entity.itemstring = ""
|
||||||
|
obj:remove()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -80,8 +80,10 @@ local function move_player_test(layout, player)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local node_inventory_table = {type="node"} -- a reusable parameter for get_inventory calls, set the pos parameter before using.
|
||||||
local function test_stop_block(pos, items)
|
local function test_stop_block(pos, items)
|
||||||
local inv = minetest.get_inventory({type="node", pos=pos})
|
node_inventory_table.pos = pos
|
||||||
|
local inv = minetest.get_inventory(node_inventory_table)
|
||||||
local item_stack = inv:get_stack("stop", 1)
|
local item_stack = inv:get_stack("stop", 1)
|
||||||
if not item_stack:is_empty() then
|
if not item_stack:is_empty() then
|
||||||
for _, item in pairs(items) do
|
for _, item in pairs(items) do
|
||||||
@ -129,22 +131,24 @@ digtron.execute_dig_cycle = function(pos, clicker)
|
|||||||
-- This builds a set of nodes that will be dug and returns a list of products that will be generated
|
-- This builds a set of nodes that will be dug and returns a list of products that will be generated
|
||||||
-- but doesn't actually dig the nodes yet. That comes later.
|
-- but doesn't actually dig the nodes yet. That comes later.
|
||||||
-- If we dug them now, sand would fall and some digtron nodes would die.
|
-- If we dug them now, sand would fall and some digtron nodes would die.
|
||||||
for k, location in pairs(layout.diggers) do
|
if layout.diggers ~= nil then
|
||||||
local target = minetest.get_node(location.pos)
|
for k, location in pairs(layout.diggers) do
|
||||||
local targetdef = minetest.registered_nodes[target.name]
|
local target = minetest.get_node(location.pos)
|
||||||
if targetdef.execute_dig ~= nil then
|
local targetdef = minetest.registered_nodes[target.name]
|
||||||
local fuel_cost, dropped = targetdef.execute_dig(location.pos, layout.protected, layout.nodes_dug, controlling_coordinate, false, clicker)
|
if targetdef.execute_dig ~= nil then
|
||||||
if table.getn(dropped) > 0 then
|
local fuel_cost, dropped = targetdef.execute_dig(location.pos, layout.protected, layout.nodes_dug, controlling_coordinate, false, clicker)
|
||||||
for _, itemname in pairs(dropped) do
|
if dropped ~= nil then
|
||||||
table.insert(items_dropped, itemname)
|
for _, itemname in pairs(dropped) do
|
||||||
end
|
table.insert(items_dropped, itemname)
|
||||||
if digtron.config.particle_effects then
|
end
|
||||||
table.insert(particle_systems, dig_dust(vector.add(location.pos, dir), target.param2))
|
if digtron.config.particle_effects then
|
||||||
|
table.insert(particle_systems, dig_dust(vector.add(location.pos, dir), target.param2))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
digging_fuel_cost = digging_fuel_cost + fuel_cost
|
||||||
|
else
|
||||||
|
minetest.log(string.format("%s has digger group but is missing execute_dig method! This is an error in mod programming, file a bug.", targetdef.name))
|
||||||
end
|
end
|
||||||
digging_fuel_cost = digging_fuel_cost + fuel_cost
|
|
||||||
else
|
|
||||||
minetest.log(string.format("%s has digger group but is missing execute_dig method! This is an error in mod programming, file a bug.", targetdef.name))
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -186,22 +190,24 @@ digtron.execute_dig_cycle = function(pos, clicker)
|
|||||||
local test_items = {}
|
local test_items = {}
|
||||||
local test_fuel_items = {}
|
local test_fuel_items = {}
|
||||||
local test_build_fuel_cost = 0
|
local test_build_fuel_cost = 0
|
||||||
for k, location in pairs(layout.builders) do
|
if layout.builders ~= nil then
|
||||||
local target = minetest.get_node(location.pos)
|
for k, location in pairs(layout.builders) do
|
||||||
local targetdef = minetest.registered_nodes[target.name]
|
local target = minetest.get_node(location.pos)
|
||||||
local test_location = vector.add(location.pos, dir)
|
local targetdef = minetest.registered_nodes[target.name]
|
||||||
if targetdef.test_build ~= nil then
|
local test_location = vector.add(location.pos, dir)
|
||||||
test_build_return_code, test_build_return_items, failed_to_find = targetdef.test_build(location.pos, test_location, layout.inventories, layout.protected, layout.nodes_dug, controlling_coordinate, layout.controller)
|
if targetdef.test_build ~= nil then
|
||||||
for k, return_item in pairs(test_build_return_items) do
|
test_build_return_code, test_build_return_items, failed_to_find = targetdef.test_build(location.pos, test_location, layout.inventories, layout.protected, layout.nodes_dug, controlling_coordinate, layout.controller)
|
||||||
table.insert(test_items, return_item)
|
for k, return_item in pairs(test_build_return_items) do
|
||||||
test_build_fuel_cost = test_build_fuel_cost + digtron.config.build_cost
|
table.insert(test_items, return_item)
|
||||||
|
test_build_fuel_cost = test_build_fuel_cost + digtron.config.build_cost
|
||||||
|
end
|
||||||
|
if test_build_return_code > 1 then
|
||||||
|
can_build = false
|
||||||
|
break
|
||||||
|
end
|
||||||
|
else
|
||||||
|
minetest.log(string.format("%s has builder group but is missing test_build method! This is an error in mod programming, file a bug.", targetdef.name))
|
||||||
end
|
end
|
||||||
if test_build_return_code > 1 then
|
|
||||||
can_build = false
|
|
||||||
break
|
|
||||||
end
|
|
||||||
else
|
|
||||||
minetest.log(string.format("%s has builder group but is missing test_build method! This is an error in mod programming, file a bug.", targetdef.name))
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -210,17 +216,19 @@ digtron.execute_dig_cycle = function(pos, clicker)
|
|||||||
|
|
||||||
local power_from_cables = 0
|
local power_from_cables = 0
|
||||||
if minetest.get_modpath("technic") then
|
if minetest.get_modpath("technic") then
|
||||||
local power_inputs = {}
|
if layout.power_connectors ~= nil then
|
||||||
for _, power_connector in pairs(layout.power_connectors) do
|
local power_inputs = {}
|
||||||
if power_connector.meta.fields.HV_network and power_connector.meta.fields.HV_EU_input then
|
for _, power_connector in pairs(layout.power_connectors) do
|
||||||
power_inputs[power_connector.meta.fields.HV_network] = tonumber(power_connector.meta.fields.HV_EU_input)
|
if power_connector.meta.fields.HV_network and power_connector.meta.fields.HV_EU_input then
|
||||||
|
power_inputs[power_connector.meta.fields.HV_network] = tonumber(power_connector.meta.fields.HV_EU_input)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
for _, power in pairs(power_inputs) do
|
||||||
|
power_from_cables = power_from_cables + power
|
||||||
|
end
|
||||||
|
power_from_cables = power_from_cables / digtron.config.power_ratio
|
||||||
|
test_fuel_burned = power_from_cables
|
||||||
end
|
end
|
||||||
for _, power in pairs(power_inputs) do
|
|
||||||
power_from_cables = power_from_cables + power
|
|
||||||
end
|
|
||||||
power_from_cables = power_from_cables / digtron.config.power_ratio
|
|
||||||
test_fuel_burned = power_from_cables
|
|
||||||
|
|
||||||
if test_fuel_needed - test_fuel_burned > 0 then
|
if test_fuel_needed - test_fuel_burned > 0 then
|
||||||
-- check for the available electrical power
|
-- check for the available electrical power
|
||||||
@ -271,12 +279,12 @@ digtron.execute_dig_cycle = function(pos, clicker)
|
|||||||
local move_player = move_player_test(layout, clicker)
|
local move_player = move_player_test(layout, clicker)
|
||||||
|
|
||||||
-- damage the weak flesh
|
-- damage the weak flesh
|
||||||
if digtron.config.damage_creatures then
|
if digtron.config.damage_hp > 0 and layout.diggers ~= nil then
|
||||||
for k, location in pairs(layout.diggers) do
|
for k, location in pairs(layout.diggers) do
|
||||||
local target = minetest.get_node(location.pos)
|
local target = minetest.get_node(location.pos)
|
||||||
local targetdef = minetest.registered_nodes[target.name]
|
local targetdef = minetest.registered_nodes[target.name]
|
||||||
if targetdef.damage_creatures ~= nil then
|
if targetdef.damage_creatures ~= nil then
|
||||||
targetdef.damage_creatures(clicker, location.pos, controlling_coordinate)
|
targetdef.damage_creatures(clicker, location.pos, controlling_coordinate, items_dropped)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -302,33 +310,37 @@ digtron.execute_dig_cycle = function(pos, clicker)
|
|||||||
local building_fuel_cost = 0
|
local building_fuel_cost = 0
|
||||||
local strange_failure = false
|
local strange_failure = false
|
||||||
-- execute_build on all digtron components that have one
|
-- execute_build on all digtron components that have one
|
||||||
for k, location in pairs(layout.builders) do
|
if layout.builders ~= nil then
|
||||||
local target = minetest.get_node(location.pos)
|
for k, location in pairs(layout.builders) do
|
||||||
local targetdef = minetest.registered_nodes[target.name]
|
local target = minetest.get_node(location.pos)
|
||||||
if targetdef.execute_build ~= nil then
|
local targetdef = minetest.registered_nodes[target.name]
|
||||||
--using the old location of the controller as fallback so that any leftovers land with the rest of the digger output. Not that there should be any.
|
if targetdef.execute_build ~= nil then
|
||||||
local build_return = targetdef.execute_build(location.pos, clicker, layout.inventories, layout.protected, layout.nodes_dug, controlling_coordinate, oldpos)
|
--using the old location of the controller as fallback so that any leftovers land with the rest of the digger output. Not that there should be any.
|
||||||
if build_return < 0 then
|
local build_return = targetdef.execute_build(location.pos, clicker, layout.inventories, layout.protected, layout.nodes_dug, controlling_coordinate, oldpos)
|
||||||
-- This happens if there's insufficient inventory, but we should have confirmed there was sufficient inventory during test phase.
|
if build_return < 0 then
|
||||||
-- So this should never happen. However, "should never happens" happen sometimes. So
|
-- This happens if there's insufficient inventory, but we should have confirmed there was sufficient inventory during test phase.
|
||||||
-- don't interrupt the build cycle as a whole, we've already moved so might as well try to complete as much as possible.
|
-- So this should never happen. However, "should never happens" happen sometimes. So
|
||||||
strange_failure = true
|
-- don't interrupt the build cycle as a whole, we've already moved so might as well try to complete as much as possible.
|
||||||
build_return = (build_return * -1) - 1
|
strange_failure = true
|
||||||
elseif digtron.config.uses_resources then
|
build_return = (build_return * -1) - 1
|
||||||
building_fuel_cost = building_fuel_cost + (digtron.config.build_cost * build_return)
|
elseif digtron.config.uses_resources then
|
||||||
|
building_fuel_cost = building_fuel_cost + (digtron.config.build_cost * build_return)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
minetest.log(string.format("%s has builder group but is missing execute_build method! This is an error in mod programming, file a bug.", targetdef.name))
|
||||||
end
|
end
|
||||||
else
|
|
||||||
minetest.log(string.format("%s has builder group but is missing execute_build method! This is an error in mod programming, file a bug.", targetdef.name))
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
for k, location in pairs(layout.auto_ejectors) do
|
if layout.auto_ejectors ~= nil then
|
||||||
local target = minetest.get_node(location.pos)
|
for k, location in pairs(layout.auto_ejectors) do
|
||||||
local targetdef = minetest.registered_nodes[target.name]
|
local target = minetest.get_node(location.pos)
|
||||||
if targetdef.execute_eject ~= nil then
|
local targetdef = minetest.registered_nodes[target.name]
|
||||||
targetdef.execute_eject(location.pos, target, clicker)
|
if targetdef.execute_eject ~= nil then
|
||||||
else
|
targetdef.execute_eject(location.pos, target, clicker)
|
||||||
minetest.log(string.format("%s has an ejector group but is missing execute_eject method! This is an error in mod programming, file a bug.", targetdef.name))
|
else
|
||||||
|
minetest.log(string.format("%s has an ejector group but is missing execute_eject method! This is an error in mod programming, file a bug.", targetdef.name))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -460,22 +472,24 @@ digtron.execute_downward_dig_cycle = function(pos, clicker)
|
|||||||
-- This builds a set of nodes that will be dug and returns a list of products that will be generated
|
-- This builds a set of nodes that will be dug and returns a list of products that will be generated
|
||||||
-- but doesn't actually dig the nodes yet. That comes later.
|
-- but doesn't actually dig the nodes yet. That comes later.
|
||||||
-- If we dug them now, sand would fall and some digtron nodes would die.
|
-- If we dug them now, sand would fall and some digtron nodes would die.
|
||||||
for k, location in pairs(layout.diggers) do
|
if layout.diggers ~= nil then
|
||||||
local target = minetest.get_node(location.pos)
|
for k, location in pairs(layout.diggers) do
|
||||||
local targetdef = minetest.registered_nodes[target.name]
|
local target = minetest.get_node(location.pos)
|
||||||
if targetdef.execute_dig ~= nil then
|
local targetdef = minetest.registered_nodes[target.name]
|
||||||
local fuel_cost, dropped = targetdef.execute_dig(location.pos, layout.protected, layout.nodes_dug, controlling_coordinate, true, clicker)
|
if targetdef.execute_dig ~= nil then
|
||||||
if table.getn(dropped) > 0 then
|
local fuel_cost, dropped = targetdef.execute_dig(location.pos, layout.protected, layout.nodes_dug, controlling_coordinate, true, clicker)
|
||||||
for _, itemname in pairs(dropped) do
|
if dropped ~= nil then
|
||||||
table.insert(items_dropped, itemname)
|
for _, itemname in pairs(dropped) do
|
||||||
end
|
table.insert(items_dropped, itemname)
|
||||||
if digtron.config.particle_effects then
|
end
|
||||||
table.insert(particle_systems, dig_dust(vector.add(location.pos, dir), target.param2))
|
if digtron.config.particle_effects then
|
||||||
|
table.insert(particle_systems, dig_dust(vector.add(location.pos, dir), target.param2))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
digging_fuel_cost = digging_fuel_cost + fuel_cost
|
||||||
|
else
|
||||||
|
minetest.log(string.format("%s has digger group but is missing execute_dig method! This is an error in mod programming, file a bug.", targetdef.name))
|
||||||
end
|
end
|
||||||
digging_fuel_cost = digging_fuel_cost + fuel_cost
|
|
||||||
else
|
|
||||||
minetest.log(string.format("%s has digger group but is missing execute_dig method! This is an error in mod programming, file a bug.", targetdef.name))
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -513,7 +527,7 @@ digtron.execute_downward_dig_cycle = function(pos, clicker)
|
|||||||
local move_player = move_player_test(layout, clicker)
|
local move_player = move_player_test(layout, clicker)
|
||||||
|
|
||||||
-- damage the weak flesh
|
-- damage the weak flesh
|
||||||
if digtron.config.damage_creatures then
|
if digtron.config.damage_hp > 0 and layout.diggers ~= nil then
|
||||||
for k, location in pairs(layout.diggers) do
|
for k, location in pairs(layout.diggers) do
|
||||||
local target = minetest.get_node(location.pos)
|
local target = minetest.get_node(location.pos)
|
||||||
local targetdef = minetest.registered_nodes[target.name]
|
local targetdef = minetest.registered_nodes[target.name]
|
||||||
@ -574,9 +588,6 @@ digtron.execute_downward_dig_cycle = function(pos, clicker)
|
|||||||
minetest.log("action", string.format("%s uses Digtron to dig %s at (%d, %d, %d)", clicker:get_player_name(), minetest.get_node(node_to_dig).name, node_to_dig.x, node_to_dig.y, node_to_dig.z))
|
minetest.log("action", string.format("%s uses Digtron to dig %s at (%d, %d, %d)", clicker:get_player_name(), minetest.get_node(node_to_dig).name, node_to_dig.x, node_to_dig.y, node_to_dig.z))
|
||||||
minetest.remove_node(node_to_dig)
|
minetest.remove_node(node_to_dig)
|
||||||
end
|
end
|
||||||
-- all of the digtron's nodes wind up in nodes_dug, so this is an ideal place to stick
|
|
||||||
-- a check to make sand fall after the digtron has passed.
|
|
||||||
--minetest.check_for_falling({x=node_to_dig.x, y=node_to_dig.y+1, z=node_to_dig.z})
|
|
||||||
node_to_dig, whether_to_dig = layout.nodes_dug:pop()
|
node_to_dig, whether_to_dig = layout.nodes_dug:pop()
|
||||||
end
|
end
|
||||||
return pos, status_text, 0
|
return pos, status_text, 0
|
||||||
|
Loading…
Reference in New Issue
Block a user