summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarter Kolwey <cheapiephp@gmail.com>2017-03-11 00:57:52 -0600
committerCarter Kolwey <cheapiephp@gmail.com>2017-03-11 00:57:52 -0600
commitc4acb7225a059b9eb40c1149ba043a55016eab16 (patch)
treed6ebae6794ee30897a755de6959ddcd463b9059c
parent9382558d822d9398626b39706fde385507e790c5 (diff)
Don't require a full network recalculation to add or remove a dead end
A dead end (node with only one connection) can be simply added or removed from the network without needing to traverse the whole thing.
-rw-r--r--technic/machines/register/cables.lua96
1 files changed, 91 insertions, 5 deletions
diff --git a/technic/machines/register/cables.lua b/technic/machines/register/cables.lua
index 04c6096..165db98 100644
--- a/technic/machines/register/cables.lua
+++ b/technic/machines/register/cables.lua
@@ -11,7 +11,15 @@ function technic.get_cable_tier(name)
return cable_tier[name]
end
-local function clear_networks(pos)
+local function check_connections(pos)
+ -- Build a table of all machines
+ local machines = {}
+ for tier,list in pairs(technic.machines) do
+ for k,v in pairs(list) do
+ machines[k] = v
+ end
+ end
+ local connections = {}
local positions = {
{x=pos.x+1, y=pos.y, z=pos.z},
{x=pos.x-1, y=pos.y, z=pos.z},
@@ -20,13 +28,91 @@ local function clear_networks(pos)
{x=pos.x, y=pos.y, z=pos.z+1},
{x=pos.x, y=pos.y, z=pos.z-1}}
for _,connected_pos in pairs(positions) do
+ local name = minetest.get_node(connected_pos).name
+ if machines[name] or technic.get_cable_tier(name) then
+ table.insert(connections,connected_pos)
+ end
+ end
+ return connections
+end
+
+local function clear_networks(pos)
+ local node = minetest.get_node(pos)
+ local meta = minetest.get_meta(pos)
+ local placed = node.name ~= "air"
+ local positions = check_connections(pos)
+ if #positions < 1 then return end
+ local dead_end = #positions == 1
+ for _,connected_pos in pairs(positions) do
local net = technic.cables[minetest.hash_node_position(connected_pos)]
if net and technic.networks[net] then
- for _,v in pairs(technic.networks[net].all_nodes) do
- local pos1 = minetest.hash_node_position(v)
- technic.cables[pos1] = nil
+ if dead_end and placed then
+ -- Dead end placed, add it to the network
+ -- Get the network
+ local network_id = technic.cables[minetest.hash_node_position(positions[1])]
+ if not network_id then
+ -- We're evidently not on a network, nothing to add ourselves to
+ return
+ end
+ local sw_pos = minetest.get_position_from_hash(network_id)
+ sw_pos.y = sw_pos.y + 1
+ local network = technic.networks[network_id]
+ local tier = network.tier
+
+ -- Actually add it to the (cached) network
+ -- This is similar to check_node_subp
+ technic.cables[minetest.hash_node_position(pos)] = network_id
+ pos.visited = 1
+ if technic.is_tier_cable(name, tier) then
+ table.insert(network.all_nodes,pos)
+ elseif technic.machines[tier][node.name] then
+ meta:set_string(tier.."_network",minetest.pos_to_string(sw_pos))
+ if technic.machines[tier][node.name] == technic.producer then
+ table.insert(network.PR_nodes,pos)
+ elseif technic.machines[tier][node.name] == technic.receiver then
+ table.insert(network.RE_nodes,pos)
+ elseif technic.machines[tier][node.name] == technic.producer_receiver then
+ table.insert(network.PR_nodes,pos)
+ table.insert(network.RE_nodes,pos)
+ elseif technic.machines[tier][node.name] == "SPECIAL" and
+ (pos.x ~= sw_pos.x or pos.y ~= sw_pos.y or pos.z ~= sw_pos.z) and
+ from_below then
+ table.insert(network.SP_nodes,pos)
+ elseif technic.machines[tier][node.name] == technic.battery then
+ table.insert(network.BA_nodes,pos)
+ end
+ end
+ elseif dead_end and not placed then
+ -- Dead end removed, remove it from the network
+ -- Get the network
+ local network_id = technic.cables[minetest.hash_node_position(positions[1])]
+ if not network_id then
+ -- We're evidently not on a network, nothing to add ourselves to
+ return
+ end
+ local network = technic.networks[network_id]
+
+ -- Search for and remove machine
+ technic.cables[minetest.hash_node_position(pos)] = nil
+ for tblname,table in pairs(network) do
+ if tblname ~= "tier" then
+ for machinenum,machine in pairs(table) do
+ if machine.x == pos.x
+ and machine.y == pos.y
+ and machine.z == pos.z then
+ table[machinenum] = nil
+ end
+ end
+ end
+ end
+ else
+ -- Not a dead end, so the whole network needs to be recalculated
+ for _,v in pairs(technic.networks[net].all_nodes) do
+ local pos1 = minetest.hash_node_position(v)
+ technic.cables[pos1] = nil
+ end
+ technic.networks[net] = nil
end
- technic.networks[net] = nil
end
end
end