local script_data = { has_checked = false, networks = {}, switches = {}, } local map = {} local function new_entity_entry(entity) local base = { entity_number = entity.unit_number, prev = { input = {}, output = {} }, } if script_data.networks[entity.electric_network_id] then base.prev = script_data.networks[entity.electric_network_id].prev end script_data.networks[entity.electric_network_id] = base map[entity.unit_number] = entity end local function find_entity(unit_number, entity_type) if map[unit_number] then return map[unit_number] end for _, surface in pairs(game.surfaces) do local ents = surface.find_entities_filtered({ type = entity_type }) for _, entity in pairs(ents) do if entity.unit_number == unit_number then map[entity.unit_number] = entity return entity end end end end local function rescan_worlds() local networks = script_data.networks local invalids = {} local remove = {} for idx, network in pairs(networks) do if network.entity then network.entity_number = network.entity.unit_number network.entity = nil end if network.entity_number then local assoc = find_entity(network.entity_number, "electric-pole") if not assoc then invalids[idx] = true end else remove[idx] = true end end for _, surface in pairs(game.surfaces) do local ents = surface.find_entities_filtered({ type = "electric-pole" }) for _, entity in pairs(ents) do if not networks[entity.electric_network_id] or invalids[entity.electric_network_id] then new_entity_entry(entity) invalids[entity.electric_network_id] = nil end end end if table_size(remove) > 0 then for idx, _ in pairs(remove) do networks[idx] = nil end end end local function get_ignored_networks_by_switches() local ignored = {} local max = math.max for switch_id, val in pairs(script_data.switches) do -- assume old entity if val ~= 1 and val and val.valid then script_data.switches[val.unit_number] = 1 script_data.switches[switch_id] = nil end local switch = find_entity(switch_id, "power-switch") if switch.power_switch_state and #switch.neighbours.copper > 1 then local network = max(switch.neighbours.copper[1].electric_network_id, switch.neighbours.copper[2].electric_network_id) ignored[network] = true end end return ignored end function on_power_build(event) local entity = event.entity or event.created_entity if entity and entity.type == "electric-pole" then if not script_data.networks[entity.electric_network_id] then new_entity_entry(entity) end elseif entity and entity.type == "power-switch" then script_data.switches[entity.unit_number] = 1 map[entity.unit_number] = entity end end function on_power_destroy(event) local entity = event.entity if entity.type == "electric-pole" then local pos = entity.position local max = entity.prototype and entity.prototype.max_wire_distance or game.max_electric_pole_connection_distance local area = { { pos.x - max, pos.y - max }, { pos.x + max, pos.y + max } } local surface = entity.surface local networks = script_data.networks local current_idx = entity.electric_network_id -- Make sure to create the new network ids before collecting new info if entity.neighbours.copper and event.damage_type == nil then entity.disconnect_neighbour() end local finds = surface.find_entities_filtered({ type = "electric-pole", area = area }) for _, new_entity in pairs(finds) do if new_entity ~= entity then if new_entity.electric_network_id == current_idx or not networks[new_entity.electric_network_id] then -- here we need to add the new_entity new_entity_entry(new_entity) end end end elseif entity.type == "power-switch" then script_data.switches[entity.unit_number] = nil end -- if some unexpected stuff occurs, try enabling rescan_worlds -- rescan_worlds() end function on_power_load() script_data.has_checked = false end function on_power_init() script_data.has_checked = false end function on_power_tick(event) if event.tick then local ignored = get_ignored_networks_by_switches() if not script_data.has_checked then rescan_worlds() script_data.has_checked = true end gauge_power_production_input:reset() gauge_power_production_output:reset() for idx, network in pairs(script_data.networks) do -- reset old style in case it still is old if network.entity then network.entity_number = network.entity.unit_number network.entity = nil end local entity = find_entity(network.entity_number, "electric-pole") if not entity then rescan_worlds() entity = find_entity(network.entity_number, "electric-pole") end if entity and entity.valid and not ignored[entity.electric_network_id] and entity.electric_network_id == idx then local force_name = entity.force.name local surface_name = entity.surface.name for name, n in pairs(entity.electric_network_statistics.input_counts) do gauge_power_production_input:set(n, { force_name, name, idx, surface_name }) end for name, n in pairs(entity.electric_network_statistics.output_counts) do gauge_power_production_output:set(n, { force_name, name, idx, surface_name }) end elseif entity and entity.valid and entity.electric_network_id ~= idx then -- assume this network has been merged with some other so unset script_data.networks[idx] = nil elseif entity and not entity.valid then -- Invalid entity remove anyhow script_data.networks[idx] = nil end end end end