As mentioned, I've never made a Factorio mod before, but I've spent a little while optimising it and this seems to work. There may be some improvements needed. One problem I had was getting the game to properly recognise all the air filtering machines on game-start, so I had to hackily implement the Init
check. If I used script.on_init()
then it'd only load about 2 or 3 machines until I placed one down to get it to update/refresh.
You're welcome to use this code however you please:
local mk2_chunks = {
{0, 0}, {1, 0}, {-1, 0}, {0, 1}, {0, -1} -- Center + Cardinal Directions
}
local mk3_chunks = {
{0, 0}, {1, 0}, {-1, 0}, {0, 1}, {0, -1}, -- Center + Cardinal
{2, 0}, {-2, 0}, {0, 2}, {0, -2}, -- 2 Chunks out in cardinal
{1, 1}, {1, -1}, {-1, 1}, {-1, -1} -- 1 Chunk diagonally
}
Init = false
Machines = {}
function IsMachineActive(entity)
if not entity or not entity.valid then return false end
-- Check if machine has power
if entity.energy == 0 then
return false
end
-- Check if machine has a filter inside
local inv = entity.get_inventory(defines.inventory.furnace_source)
if inv and not inv.is_empty() then
return true
end
return false
end
-- Function to remove pollution within a specified chunk radius
function RemovePollution(base_position, chunk_offsets, removal_amount)
local surface = game.surfaces[1]
for _, offset in pairs(chunk_offsets) do
local chunk_x = math.floor((base_position.x / 32) + offset[1]) * 32
local chunk_y = math.floor((base_position.y / 32) + offset[2]) * 32
local pollution = surface.get_pollution({chunk_x, chunk_y})
surface.pollute({chunk_x, chunk_y}, -math.min(removal_amount, pollution))
end
end
function FindMachines()
if not Init then Init = true end
local surface = game.surfaces[1]
Machines = surface.find_entities_filtered({name = {"air-filter-machine-mk2", "air-filter-machine-mk3"}})
end
function Execute(e)
if not Init then FindMachines() end
for _, machine in pairs(Machines) do
if IsMachineActive(machine) then
if machine.name == "air-filter-machine-mk2" then
RemovePollution(machine.position, mk2_chunks, 50)
elseif machine.name == "air-filter-machine-mk3" then
RemovePollution(machine.position, mk3_chunks, 100)
end
end
end
end
-- Update machines when new one is placed
local filter = {
{ filter = "name", name = "air-filter-machine-mk2" },
{ filter = "name", name = "air-filter-machine-mk3", mode = "or"}
}
script.on_event(defines.events.on_built_entity, FindMachines, filter)
script.on_nth_tick(60, Execute)