Add a tool to insert network metadata into nodes

This also involves modifications of the network update routines
as the modification of metadata does not trigger the callbacks
used for this purpose.
Instead the tool manually forces updates to networks around the node.
Currently we cannot detect the digging of a node with specific
metadata associated, thus we currently need to trigger network updates
for ALL nodes digged which can incur much lag for heavy recalculations.
This commit is contained in:
Valentin Anger 2018-09-22 16:20:27 +02:00
parent 00024a4cde
commit f161e121fd
2 changed files with 66 additions and 27 deletions

View File

@ -65,8 +65,8 @@ local function net_build(pos, callerpos, master_arg)
local node = minetest.get_node(nodepos) local node = minetest.get_node(nodepos)
local meta = minetest.get_meta(nodepos) local meta = minetest.get_meta(nodepos)
local net_passive = minetest.get_item_group(node.name,"sparktech_net_passive") local net_passive = minetest.get_item_group(node.name,"sparktech_net_passive")
if (not net_passive and meta:get_int("sparktech_net_passive") == 1) then if (net_passive == 0 and meta:get_int("sparktech_net_passive") == 1) then
net_passive = true net_passive = 1
end end
local net_trigger = minetest.get_item_group(node.name,"sparktech_net_trigger") local net_trigger = minetest.get_item_group(node.name,"sparktech_net_trigger")
-- net passives are followed along to create the network (aka cables) but they do not get power, -- net passives are followed along to create the network (aka cables) but they do not get power,
@ -86,7 +86,7 @@ local function net_build(pos, callerpos, master_arg)
-- Now the node shouldnt be processed by the net_build anymore -- Now the node shouldnt be processed by the net_build anymore
processed[#processed + 1] = nodepos processed[#processed + 1] = nodepos
end end
if (net_passive == 1 or ntrigontrig) then if (net_passive ~= 0 or ntrigontrig) then
net_build(nodepos, pos) net_build(nodepos, pos)
end end
end end
@ -102,17 +102,22 @@ local function net_build(pos, callerpos, master_arg)
return -- at this point all nodes have been processed, so we can return to the calling node return -- at this point all nodes have been processed, so we can return to the calling node
end end
local function add_node(pos, newnode)
minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack, pointed_thing) local meta = minetest.get_meta(pos)
if (minetest.get_item_group(itemstack:get_name(), "sparktech_net_passive") == 1 ) then if (minetest.get_item_group(newnode.name, "sparktech_net_passive") == 1 or meta:get_int("sparktech_net_passive") ~= 0) then
net_build(pos) -- only call this with none if the node really is not a trigger, otherwise the net will be build from it but it will not be contained net_build(pos) -- only call this with none if the node really is not a trigger, otherwise the net will be build from it but it will not be contained
elseif (minetest.get_item_group(itemstack:get_name(), "sparktech_net_trigger") == 1 ) then elseif (minetest.get_item_group(newnode.name, "sparktech_net_trigger") == 1 ) then
meta:set_string("net_master", nil)
net_build(pos, nil, pos) net_build(pos, nil, pos)
end end
end
minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack, pointed_thing)
add_node(pos, newnode)
end) end)
minetest.register_on_dignode(function(pos, oldnode, digger) local function remove_node(pos, oldnode, force)
if ((minetest.get_item_group(oldnode.name, "sparktech_net_passive") == 1) or (minetest.get_item_group(oldnode.name, "sparktech_net_trigger") == 1)) then if (force or (minetest.get_item_group(oldnode.name, "sparktech_net_passive") == 1) or (minetest.get_item_group(oldnode.name, "sparktech_net_trigger") == 1)) then
local top = {x = pos.x, y = pos.y + 1, z = pos.z} local top = {x = pos.x, y = pos.y + 1, z = pos.z}
local bottom = {x = pos.x, y = pos.y - 1, z = pos.z} local bottom = {x = pos.x, y = pos.y - 1, z = pos.z}
local left = {x = pos.x - 1, y = pos.y, z = pos.z} local left = {x = pos.x - 1, y = pos.y, z = pos.z}
@ -121,13 +126,14 @@ minetest.register_on_dignode(function(pos, oldnode, digger)
local back = {x = pos.x, y = pos.y, z = pos.z + 1} local back = {x = pos.x, y = pos.y, z = pos.z + 1}
for sidename, nodepos in pairs({top=top, bottom=bottom, left=left, right=right, front=front, back=back}) do for sidename, nodepos in pairs({top=top, bottom=bottom, left=left, right=right, front=front, back=back}) do
local target_node = minetest.get_node(nodepos) local target_node = minetest.get_node(nodepos)
local meta = minetest.get_meta(nodepos) add_node(nodepos, target_node)
if (minetest.get_item_group(target_node.name, "sparktech_net_passive") == 1) then
net_build(nodepos)
elseif (minetest.get_item_group(target_node.name, "sparktech_net_trigger") == 1) then
meta:set_string("net_master", nil)
net_build(nodepos, nil, nodepos)
end
end end
end end
end
minetest.register_on_dignode(function(pos, oldnode, digger)
remove_node(pos, oldnode, true) -- FIXME Get rid of this! Somehow detect if a dynamic net_passive node is destroyed instead of updating speculatively
end) end)
sparktech.add_node_to_net = add_node
sparktech.remove_node_from_net = remove_node

View File

@ -0,0 +1,33 @@
local NAME = minetest.get_current_modname()
minetest.register_tool(NAME .. ":cableinserter", {
description = "Cable Inserter",
inventory_image = "multimeter.png",
stack_max = 1,
on_place = function(itemstack, placer, pointed_thing)
-- TODO Check that nodes does not already interact with the grid
if pointed_thing["type"] == "node" then
local node = minetest.get_node(pointed_thing.under)
local meta = minetest.get_meta(pointed_thing.under)
if meta:get_int("sparktech_net_passive") == 1 then
meta:set_int("sparktech_net_passive", 0)
sparktech.remove_node_from_net(pointed_thing.under, node, true)
minetest.debug("Removed cable")
else
meta:set_int("sparktech_net_passive", 1)
sparktech.add_node_to_net(pointed_thing.under, node)
minetest.debug("Added cable")
end
end
return itemstack
end
})
minetest.register_craft({
output = NAME .. ":cableinserter",
recipe = {
{ "group:steelplate", "", "" },
{ "", "group:steelplate", "" },
{ "", "group:steelplate", ""},
}
})