mirror of
https://github.com/minetest-mods/technic.git
synced 2025-01-09 09:40:21 +01:00
Fix machines connected to multiple networks (#655)
Machines sometimes were be a part of multiple networks and generated power for each. This is fixed by checking if the machine is already part of an other network before assigning it to the current network.
This commit is contained in:
parent
87e512ff24
commit
b268e3d526
@ -43,84 +43,106 @@ local function check_connections(pos)
|
|||||||
return connections
|
return connections
|
||||||
end
|
end
|
||||||
|
|
||||||
local function clear_networks(pos)
|
local clear_networks
|
||||||
|
|
||||||
|
local function clear_network(network_id)
|
||||||
|
if not network_id then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
for _,v in pairs(technic.networks[network_id].all_nodes) do
|
||||||
|
local pos1 = minetest.hash_node_position(v)
|
||||||
|
technic.cables[pos1] = nil
|
||||||
|
end
|
||||||
|
local network_bckup = technic.networks[network_id]
|
||||||
|
technic.networks[network_id] = nil
|
||||||
|
|
||||||
|
for _,n_pos in pairs(network_bckup.PR_nodes) do
|
||||||
|
clear_networks(n_pos)
|
||||||
|
end
|
||||||
|
for _,n_pos in pairs(network_bckup.RE_nodes) do
|
||||||
|
clear_networks(n_pos)
|
||||||
|
end
|
||||||
|
for _,n_pos in pairs(network_bckup.BA_nodes) do
|
||||||
|
clear_networks(n_pos)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
clear_networks = function(pos)
|
||||||
local node = minetest.get_node(pos)
|
local node = minetest.get_node(pos)
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
local placed = node.name ~= "air"
|
local placed = node.name ~= "air"
|
||||||
local positions = check_connections(pos)
|
local positions = check_connections(pos)
|
||||||
|
|
||||||
if #positions < 1 then return end
|
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
|
|
||||||
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
|
if #positions == 1 then
|
||||||
-- !! IMPORTANT: ../switching_station.lua -> check_node_subp() must be kept in sync
|
if 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 network = technic.networks[network_id]
|
||||||
|
local tier = network.tier
|
||||||
|
|
||||||
|
-- Actually add it to the (cached) network
|
||||||
|
-- !! IMPORTANT: ../switching_station.lua -> check_node_subp() must be kept in sync
|
||||||
|
if technic.is_tier_cable(node.name, tier) then
|
||||||
technic.cables[minetest.hash_node_position(pos)] = network_id
|
technic.cables[minetest.hash_node_position(pos)] = network_id
|
||||||
pos.visited = 1
|
table.insert(network.all_nodes,pos)
|
||||||
if technic.is_tier_cable(node.name, tier) then
|
elseif technic.machines[tier][node.name] then
|
||||||
-- Found a cable
|
-- Found a machine
|
||||||
table.insert(network.all_nodes,pos)
|
local eu_type = technic.machines[tier][node.name]
|
||||||
elseif technic.machines[tier][node.name] then
|
meta:set_string(tier.."_network", string.format("%.20g", network_id))
|
||||||
-- Found a machine
|
meta:set_int(tier.."_EU_timeout", 2)
|
||||||
local eu_type = technic.machines[tier][node.name]
|
if eu_type == technic.producer then
|
||||||
meta:set_string(tier.."_network", string.format("%.20g", network_id))
|
table.insert(network.PR_nodes, pos)
|
||||||
if eu_type == technic.producer then
|
elseif eu_type == technic.receiver then
|
||||||
table.insert(network.PR_nodes, pos)
|
table.insert(network.RE_nodes, pos)
|
||||||
elseif eu_type == technic.receiver then
|
elseif eu_type == technic.producer_receiver then
|
||||||
table.insert(network.RE_nodes, pos)
|
table.insert(network.PR_nodes, pos)
|
||||||
elseif eu_type == technic.producer_receiver then
|
table.insert(network.RE_nodes, pos)
|
||||||
table.insert(network.PR_nodes, pos)
|
elseif eu_type == technic.battery then
|
||||||
table.insert(network.RE_nodes, pos)
|
table.insert(network.BA_nodes, pos)
|
||||||
elseif eu_type == technic.battery then
|
|
||||||
table.insert(network.BA_nodes, pos)
|
|
||||||
end
|
|
||||||
-- Note: SPECIAL (i.e. switching station) is not traversed!
|
|
||||||
end
|
end
|
||||||
elseif dead_end and not placed then
|
-- Note: SPECIAL (i.e. switching station) is not traversed!
|
||||||
-- Dead end removed, remove it from the network
|
end
|
||||||
-- Get the network
|
else
|
||||||
local network_id = technic.cables[minetest.hash_node_position(positions[1])]
|
-- Dead end removed, remove it from the network
|
||||||
if not network_id then
|
-- Get the network
|
||||||
-- We're evidently not on a network, nothing to add ourselves to
|
local network_id = technic.cables[minetest.hash_node_position(positions[1])]
|
||||||
return
|
if not network_id then
|
||||||
end
|
-- We're evidently not on a network, nothing to add ourselves to
|
||||||
local network = technic.networks[network_id]
|
return
|
||||||
|
end
|
||||||
|
local network = technic.networks[network_id]
|
||||||
|
|
||||||
-- Search for and remove machine
|
-- Search for and remove machine
|
||||||
technic.cables[minetest.hash_node_position(pos)] = nil
|
technic.cables[minetest.hash_node_position(pos)] = nil
|
||||||
for tblname,table in pairs(network) do
|
for tblname,table in pairs(network) do
|
||||||
if tblname ~= "tier" then
|
if tblname ~= "tier" then
|
||||||
for machinenum,machine in pairs(table) do
|
for machinenum,machine in pairs(table) do
|
||||||
if machine.x == pos.x
|
if machine.x == pos.x
|
||||||
and machine.y == pos.y
|
and machine.y == pos.y
|
||||||
and machine.z == pos.z then
|
and machine.z == pos.z then
|
||||||
table[machinenum] = nil
|
table[machinenum] = nil
|
||||||
end
|
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
end
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
clear_network(technic.cables[minetest.hash_node_position(pos)])
|
||||||
|
|
||||||
|
for _,connected_pos in pairs(positions) do
|
||||||
|
local network_id = technic.cables[minetest.hash_node_position(connected_pos)]
|
||||||
|
-- Not a dead end, so the whole network needs to be recalculated
|
||||||
|
clear_network(network_id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -170,7 +192,7 @@ function technic.register_cable(tier, size)
|
|||||||
connects_to = {"group:technic_"..ltier.."_cable",
|
connects_to = {"group:technic_"..ltier.."_cable",
|
||||||
"group:technic_"..ltier, "group:technic_all_tiers"},
|
"group:technic_"..ltier, "group:technic_all_tiers"},
|
||||||
on_construct = clear_networks,
|
on_construct = clear_networks,
|
||||||
on_destruct = clear_networks,
|
after_destruct = clear_networks,
|
||||||
})
|
})
|
||||||
|
|
||||||
local xyz = {
|
local xyz = {
|
||||||
@ -210,7 +232,7 @@ function technic.register_cable(tier, size)
|
|||||||
connects_to = {"group:technic_"..ltier.."_cable",
|
connects_to = {"group:technic_"..ltier.."_cable",
|
||||||
"group:technic_"..ltier, "group:technic_all_tiers"},
|
"group:technic_"..ltier, "group:technic_all_tiers"},
|
||||||
on_construct = clear_networks,
|
on_construct = clear_networks,
|
||||||
on_destruct = clear_networks,
|
after_destruct = clear_networks,
|
||||||
}
|
}
|
||||||
def.node_box.fixed = {
|
def.node_box.fixed = {
|
||||||
{-size, -size, -size, size, size, size},
|
{-size, -size, -size, size, size, size},
|
||||||
|
@ -97,12 +97,14 @@ local function flatten(map)
|
|||||||
return list
|
return list
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Add a wire node to the LV/MV/HV network
|
-- Add a node to the LV/MV/HV network
|
||||||
-- Returns: indicator whether the cable is new in the network
|
-- Returns: indicator whether the node is new in the network
|
||||||
local hash_node_position = minetest.hash_node_position
|
local hash_node_position = minetest.hash_node_position
|
||||||
local function add_network_node(nodes, pos, network_id)
|
local function add_network_node(nodes, pos, network_id)
|
||||||
local node_id = hash_node_position(pos)
|
local node_id = hash_node_position(pos)
|
||||||
technic.cables[node_id] = network_id
|
if network_id then
|
||||||
|
technic.cables[node_id] = network_id
|
||||||
|
end
|
||||||
if nodes[node_id] then
|
if nodes[node_id] then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
@ -136,21 +138,31 @@ local check_node_subp = function(network, pos, machines, sw_pos, from_below, net
|
|||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
-- Normal tostring() does not have enough precision, neither does meta:set_int()
|
-- Normal tostring() does not have enough precision, neither does meta:set_int()
|
||||||
-- Lua 5.1 bug: Cannot use hexadecimal notation for compression (see LuaJIT #911)
|
-- Lua 5.1 bug: Cannot use hexadecimal notation for compression (see LuaJIT #911)
|
||||||
meta:set_string(network.tier.."_network", string.format("%.20g", network_id))
|
local network_str = string.format("%.20g", network_id)
|
||||||
|
local network_key = network.tier.."_network"
|
||||||
|
local m_network_str = meta:get_string(network_key)
|
||||||
|
|
||||||
|
if m_network_str == "" then
|
||||||
|
meta:set_string(network_key, network_str)
|
||||||
|
else
|
||||||
|
if m_network_str ~= network_str then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if eu_type == technic.producer then
|
if eu_type == technic.producer then
|
||||||
add_network_node(network.PR_nodes, pos, network_id)
|
add_network_node(network.PR_nodes, pos)
|
||||||
elseif eu_type == technic.receiver then
|
elseif eu_type == technic.receiver then
|
||||||
add_network_node(network.RE_nodes, pos, network_id)
|
add_network_node(network.RE_nodes, pos)
|
||||||
elseif eu_type == technic.producer_receiver then
|
elseif eu_type == technic.producer_receiver then
|
||||||
add_network_node(network.PR_nodes, pos, network_id)
|
add_network_node(network.PR_nodes, pos)
|
||||||
add_network_node(network.RE_nodes, pos, network_id)
|
add_network_node(network.RE_nodes, pos)
|
||||||
elseif eu_type == technic.battery then
|
elseif eu_type == technic.battery then
|
||||||
add_network_node(network.BA_nodes, pos, network_id)
|
add_network_node(network.BA_nodes, pos)
|
||||||
elseif eu_type == "SPECIAL" and from_below and
|
elseif eu_type == "SPECIAL" and from_below and
|
||||||
not vector.equals(pos, sw_pos) then
|
not vector.equals(pos, sw_pos) then
|
||||||
-- Another switching station -> disable it
|
-- Another switching station -> disable it
|
||||||
add_network_node(network.SP_nodes, pos, network_id)
|
add_network_node(network.SP_nodes, pos)
|
||||||
meta:set_int("active", 0)
|
meta:set_int("active", 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -193,7 +205,6 @@ local get_network = function(sw_pos, cable_pos, tier)
|
|||||||
end
|
end
|
||||||
return cached.PR_nodes, cached.BA_nodes, cached.RE_nodes
|
return cached.PR_nodes, cached.BA_nodes, cached.RE_nodes
|
||||||
end
|
end
|
||||||
|
|
||||||
local machines = technic.machines[tier]
|
local machines = technic.machines[tier]
|
||||||
local network = {
|
local network = {
|
||||||
tier = tier,
|
tier = tier,
|
||||||
@ -455,6 +466,7 @@ local function switching_station_timeout_count(pos, tier)
|
|||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
local timeout = meta:get_int(tier.."_EU_timeout")
|
local timeout = meta:get_int(tier.."_EU_timeout")
|
||||||
if timeout <= 0 then
|
if timeout <= 0 then
|
||||||
|
meta:set_string(tier.."_network", "")
|
||||||
meta:set_int(tier.."_EU_input", 0) -- Not needed anymore <-- actually, it is for supply converter
|
meta:set_int(tier.."_EU_input", 0) -- Not needed anymore <-- actually, it is for supply converter
|
||||||
return true
|
return true
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user