diff --git a/technic/machines/power_monitor.lua b/technic/machines/power_monitor.lua index 51eeeee..e17a790 100644 --- a/technic/machines/power_monitor.lua +++ b/technic/machines/power_monitor.lua @@ -6,13 +6,38 @@ local S = technic.getter local cable_entry = "^technic_cable_connection_overlay.png" +-- Get registered cable or nil, returns nil if area is not loaded +local function get_cable(pos) + local node = minetest.get_node_or_nil(pos) + return (node and technic.get_cable_tier(node.name)) and node +end + +-- return the position of connected cable or nil +local function get_connected_cable_network(pos) + local param2 = minetest.get_node(pos).param2 + -- should probably also work sideways or upside down but for now it wont + if param2 > 3 then return end + -- Below? + local checkpos = {x=pos.x,y=pos.y-1,z=pos.z} + local network_id = get_cable(checkpos) and technic.pos2network(checkpos) + if network_id then + return network_id + end + -- Behind? + checkpos = vector.add(minetest.facedir_to_dir(param2),pos) + network_id = get_cable(checkpos) and technic.pos2network(checkpos) + if network_id then + return network_id + end +end + -- return the position of the associated switching station or nil local function get_swpos(pos) - local network_hash = technic.cables[minetest.hash_node_position(pos)] - local network = network_hash and minetest.get_position_from_hash(network_hash) - local swpos = network and {x=network.x,y=network.y+1,z=network.z} + local network_id = get_connected_cable_network(pos) + local network = network_id and technic.networks[network_id] + local swpos = network and technic.network2sw_pos(network_id) local is_powermonitor = swpos and minetest.get_node(swpos).name == "technic:switching_station" - return is_powermonitor and swpos or nil + return (is_powermonitor and network.all_nodes[network_id]) and swpos end minetest.register_craft({ @@ -99,11 +124,7 @@ minetest.register_abm({ action = function(pos, node, active_object_count, active_object_count_wider) local meta = minetest.get_meta(pos) local sw_pos = get_swpos(pos) - local timeout = 0 - for tier in pairs(technic.machines) do - timeout = math.max(technic.get_timeout(tier, pos),timeout) - end - if timeout > 0 and sw_pos then + if sw_pos then local sw_meta = minetest.get_meta(sw_pos) local supply = sw_meta:get_int("supply") local demand = sw_meta:get_int("demand") @@ -115,9 +136,3 @@ minetest.register_abm({ end end, }) - -for tier in pairs(technic.machines) do - -- RE in order to use the "timeout" functions, although it consumes 0 power - technic.register_machine(tier, "technic:power_monitor", "RE") -end - diff --git a/technic/machines/register/cables.lua b/technic/machines/register/cables.lua index 4b82631..7b57f47 100644 --- a/technic/machines/register/cables.lua +++ b/technic/machines/register/cables.lua @@ -60,10 +60,11 @@ local function clear_networks(pos) -- Actually add it to the (cached) network -- This is similar to check_node_subp - technic.cables[minetest.hash_node_position(pos)] = network_id + local pos_hash = minetest.hash_node_position(pos) + technic.cables[pos_hash] = network_id pos.visited = 1 if technic.is_tier_cable(name, tier) then - table.insert(network.all_nodes,pos) + network.all_nodes[pos_hash] = pos elseif technic.machines[tier][node.name] then if technic.machines[tier][node.name] == technic.producer then table.insert(network.PR_nodes,pos) diff --git a/technic/machines/switching_station.lua b/technic/machines/switching_station.lua index 328e606..18a80ed 100644 --- a/technic/machines/switching_station.lua +++ b/technic/machines/switching_station.lua @@ -6,7 +6,7 @@ technic.redundant_warn = {} local overload_reset_time = tonumber(minetest.settings:get("technic.overload_reset_time") or "20") local overloaded_networks = {} -local reset_overloaded = function(network_id) +local function reset_overloaded(network_id) local remaining = math.max(0, overloaded_networks[network_id] - minetest.get_us_time()) if remaining == 0 then -- Clear cache, remove overload and restart network @@ -216,11 +216,23 @@ end local node_timeout = {} -technic.pos2network = function(pos) - return technic.cables[minetest.hash_node_position(pos)] +function technic.pos2network(pos) + return pos and technic.cables[minetest.hash_node_position(pos)] end -technic.get_timeout = function(tier, pos) +function technic.network2pos(network_id) + return network_id and minetest.get_position_from_hash(network_id) +end + +function technic.network2sw_pos(network_id) + -- Return switching station position for network. + -- It is not guaranteed that position actually contains switching station. + local sw_pos = minetest.get_position_from_hash(network_id) + sw_pos.y = sw_pos.y + 1 + return sw_pos +end + +function technic.get_timeout(tier, pos) if node_timeout[tier] == nil then -- it is normal that some multi tier nodes always drop here when checking all LV, MV and HV tiers return 0 @@ -228,7 +240,7 @@ technic.get_timeout = function(tier, pos) return node_timeout[tier][minetest.hash_node_position(pos)] or 0 end -technic.touch_node = function(tier, pos, timeout) +function technic.touch_node(tier, pos, timeout) if node_timeout[tier] == nil then -- this should get built up during registration node_timeout[tier] = {} @@ -278,7 +290,6 @@ local function get_network(network_id, sw_pos, pos1, tier) BA_nodes = flatten(BA_nodes) RE_nodes = flatten(RE_nodes) SP_nodes = flatten(SP_nodes) - all_nodes = flatten(all_nodes) technic.networks[network_id] = {tier = tier, all_nodes = all_nodes, SP_nodes = SP_nodes, PR_nodes = PR_nodes, RE_nodes = RE_nodes, BA_nodes = BA_nodes} return PR_nodes, BA_nodes, RE_nodes @@ -317,7 +328,7 @@ local function run_nodes(list, run_stage) end end -technic.switching_station_run = function(pos) +function technic.switching_station_run(pos) if not technic.powerctrl_state then return end local t0 = minetest.get_us_time()