diff --git a/better-air-filtering/control.lua b/better-air-filtering/control.lua index 60d35b0..6ae8cc1 100644 --- a/better-air-filtering/control.lua +++ b/better-air-filtering/control.lua @@ -1,25 +1,17 @@ -function onTick(event) - local maxRadius = 4 - local radius = event.tick % 30 - if radius <= maxRadius then - for _, surface in pairs(game.surfaces) do - local filters = surface.find_entities_filtered { - name = {"air-filter-machine-1", "air-filter-machine-2", "air-filter-machine-3"} - } - updateAirFilters(surface, filters, radius) - end - end -end -function updateAirFilters(surface, filters, radius) - -- Carefull not to suck in more pollution than can process - -- This would make air filters OP because they would capture cloud without the need to filter + +function updateAirFilters(surface, filters) for _, filter in pairs(filters) do local chunk_pollution = surface.get_pollution(filter.position) if chunk_pollution > 0 then - local to_insert = math.min(chunk_pollution, 4) - local inserted_amount = filter.insert_fluid({name="pollution", amount=to_insert}) - surface.pollute(filter.position, -inserted_amount) + local suctionRate = getSuctionRate(filter) + game.print(suctionRate) + if suctionRate > 0 then + local to_insert = math.min(chunk_pollution, suctionRate) + local inserted_amount = filter.insert_fluid({name="pollution", amount=to_insert}) + surface.pollute(filter.position, -inserted_amount) + game.print("Inserted: " .. inserted_amount) + end end end end @@ -52,23 +44,109 @@ function chunkToPosition(chunk) return {x=chunk.x *32, y=chunk.y*32} end -function movePollution(chunkFrom, chunkTo, amount) - +function movePollution(surface, chunkFrom, chunkTo, amount) + amount = math.min(amount, surface.get_pollution(chunkToPosition(chunkFrom))) + surface.pollute(chunkToPosition(chunkFrom), -amount) + surface.pollute(chunkToPosition(chunkTo), amount) + return amount end -function getPurificationRate(entity) - -- TODO implement - -- 0 if not able to run - -- based on crafting speed and amount of power (if possible) +function getBasePurificationRate(entity) + -- Depends mostly on recipe. Should be multiplied by crafting speed to achieve actual max purification rate + if entity.name == "air-filter-machine-1" then + return 4 -- 4 max pollution cleaning per second among mk1 recipes + elseif entity.name == "air-filter-machine-2" or entity.name == "air-filter-machine-3" then + return 6 -- 6 max pollution cleaning for mk2 and mk3 recipes (liquid) + else + return 0 + end end -function getSucktionRate(entity) - return 1/4 * getPurificationRate(entity) +function getSuctionRate(entity) + if not entity.is_crafting() and getSpaceForPollution(entity) == 0 then + return 0 + else + return getBasePurificationRate(entity) * entity.crafting_speed * energyCraftingModifier(entity) + end end --- TODO --- Make more efficient --- flow rate of machines +function energyCraftingModifier(entity) + -- Approximation to speed modifier for machine running out of power + if entity.electric_buffer_size then + return entity.energy / entity.electric_buffer_size + else + return 1 + end +end + +function getSpaceForPollution(entity) + if #entity.fluidbox < 1 then + return 0 + end + local capacity = entity.fluidbox.get_capacity(1) + local pollutionFluid = entity.fluidbox[1] + local pollution = 0 + if pollutionFluid then + pollution = pollutionFluid.amount + end + return capacity - pollution +end + +function generateFunctions() + local functions = {} + + local function test(event) + for _, surface in pairs(game.surfaces) do + local filters = surface.find_entities_filtered { + name = {"air-filter-machine-1", "air-filter-machine-2", "air-filter-machine-3"} + } + updateAirFilters(surface, filters, 0) + end + end + table.insert(functions, test) + + + return functions +end + + +function spreadOverTicks(functions, interval) + local tickMap = {} + local funcs = {} + for index, f in pairs(functions) do + -- amount of functions to be inserted in this tick update to fit them all in the remaining interval + local functionsPerTick = math.ceil((#functions - index) / (interval - #tickMap - 1)) + table.insert(funcs, f) + if #funcs >= functionsPerTick then + table.insert(tickMap, funcs) + funcs = {} + end + end + if #funcs > 0 then + table.insert(tickMap, funcs) + funcs = {} + end + + local function onTick(event) + local step = (event.tick % interval) + 1 + game.print("Step: " .. step) + local funcs = tickMap[step] + if funcs ~= nil then + for _, f in pairs(funcs) do + f(event) + end + end + end + + return onTick +end + + +script.on_load(function() + local functions = generateFunctions() + local onTick = spreadOverTicks(functions, 30) + + script.on_event(defines.events.on_tick, onTick) +end) -script.on_event(defines.events.on_tick, onTick) diff --git a/better-air-filtering/prototypes/recipe.lua b/better-air-filtering/prototypes/recipe.lua index 046884a..6be7d95 100644 --- a/better-air-filtering/prototypes/recipe.lua +++ b/better-air-filtering/prototypes/recipe.lua @@ -105,7 +105,7 @@ data:extend({ enabled = "true", ingredients = { - { type = "fluid", name = "pollution", amount = 25, fluidbox_index = 1 }, + { type = "fluid", name = "pollution", amount = 20, fluidbox_index = 1 }, { type = "item", name = "unused-air-filter", amount = 1 }, }, results = { { type = "item", name = "used-air-filter", amount = 1 } } @@ -117,7 +117,7 @@ data:extend({ category = "air-filtering-advanced", subgroup = "raw-material", order = "f[plastic-bar]-f[filter-air]", - energy_required = 0.5, + energy_required = 1, enabled = "true", ingredients = {