mirror of
https://github.com/remijouannet/graftorio2.git
synced 2025-12-05 23:40:12 +00:00
193 lines
5.5 KiB
Lua
193 lines
5.5 KiB
Lua
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
|