mirror of
https://github.com/minetest-mods/technic.git
synced 2024-12-22 13:52:31 +01:00
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.
This commit is contained in:
parent
9382558d82
commit
c4acb7225a
@ -11,7 +11,15 @@ function technic.get_cable_tier(name)
|
|||||||
return cable_tier[name]
|
return cable_tier[name]
|
||||||
end
|
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 = {
|
local positions = {
|
||||||
{x=pos.x+1, y=pos.y, z=pos.z},
|
{x=pos.x+1, y=pos.y, z=pos.z},
|
||||||
{x=pos.x-1, y=pos.y, z=pos.z},
|
{x=pos.x-1, y=pos.y, z=pos.z},
|
||||||
@ -19,9 +27,86 @@ local function clear_networks(pos)
|
|||||||
{x=pos.x, y=pos.y-1, z=pos.z},
|
{x=pos.x, y=pos.y-1, z=pos.z},
|
||||||
{x=pos.x, y=pos.y, z=pos.z+1},
|
{x=pos.x, y=pos.y, z=pos.z+1},
|
||||||
{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
|
for _,connected_pos in pairs(positions) do
|
||||||
local net = technic.cables[minetest.hash_node_position(connected_pos)]
|
local net = technic.cables[minetest.hash_node_position(connected_pos)]
|
||||||
if net and technic.networks[net] then
|
if net and technic.networks[net] then
|
||||||
|
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
|
for _,v in pairs(technic.networks[net].all_nodes) do
|
||||||
local pos1 = minetest.hash_node_position(v)
|
local pos1 = minetest.hash_node_position(v)
|
||||||
technic.cables[pos1] = nil
|
technic.cables[pos1] = nil
|
||||||
@ -29,6 +114,7 @@ local function clear_networks(pos)
|
|||||||
technic.networks[net] = nil
|
technic.networks[net] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function technic.register_cable(tier, size)
|
function technic.register_cable(tier, size)
|
||||||
|
Loading…
Reference in New Issue
Block a user