Page 1 of 1

Read fluid in assembling machine input/output slot [control.lua][SOLVED]

Posted: Thu Jan 20, 2022 11:53 am
by oldskoolmatt
Pretty straight forward, it was fairly easy to read contents for items using this bit of code, yet, i can't get it to work with fluids, what am i missing?

Code: Select all

local count = player.surface.count_entities_filtered{area=DEFINED_AREA, type="assembling-machine"}
if count >=  1 then
    for _, entity in pairs(player.surface.find_entities_filtered{area=DEFINED_AREA, type="assembling-machine"}) do

        local item_input = {}
        local item_output = {}
				
        for content, amount in pairs(entity.get_inventory(defines.inventory.assembling_machine_output).get_contents()) do
            item_output = MY_FUNCTION(content, amount)
        end
		
        for content, amount in pairs(entity.get_inventory(defines.inventory.assembling_machine_input).get_contents()) do
            item_input =  MY_FUNCTION(content, amount)
        end
    end
end

Re: Read fluid in assembling machine input/output slot [control.lua]

Posted: Thu Jan 20, 2022 1:05 pm
by Stringweasel
If you want the input/output fluid of an assembly machine I'm pretty sure you should use the fluid boxes and not the inventory.

https://lua-api.factorio.com/latest/Lua ... y.fluidbox

Re: Read fluid in assembling machine input/output slot [control.lua]

Posted: Thu Jan 20, 2022 1:13 pm
by Pi-C
oldskoolmatt wrote: Thu Jan 20, 2022 11:53 am Pretty straight forward, it was fairly easy to read contents for items using this bit of code, yet, i can't get it to work with fluids, what am i missing?
Have you ever seen an unbarreled fluid in any inventory? Try get_fluid_contents() instead!

EDIT: entity.get_fluid_contents will return all fluids in an entity, so if you have fluids as input and as output, querying the output fluidbox directly (as suggested by stringweasel) would be better.

By the way:

Code: Select all

local count = player.surface.count_entities_filtered{area=DEFINED_AREA, type="assembling-machine"}
if count >=  1 then
    for _, entity in pairs(player.surface.find_entities_filtered{area=DEFINED_AREA, type="assembling-machine"}) do
…
    end
end
Do you really need the count? Otherwise, surface.find_entities_filtered will always return a table (which may be empty), so the wrapper around the for-loop shouldn't be necessary.

Re: Read fluid in assembling machine input/output slot [control.lua]

Posted: Thu Jan 20, 2022 1:30 pm
by oldskoolmatt
Do you really need the count? Otherwise, surface.find_entities_filtered will always return a table (which may be empty), so the wrapper around the for-loop shouldn't be necessary.
The script keeps scanning for entities (on_tick) and apparently COUNT is much more UPS friendly than FIND.
Runnning a COUNT check first and then, only if the count check is met, running the FIND command, helps preventing UPS drops when many different entities are around and no wanted entities are nearby

Re: Read fluid in assembling machine input/output slot [control.lua]

Posted: Thu Jan 20, 2022 1:33 pm
by oldskoolmatt
Stringweasel wrote: Thu Jan 20, 2022 1:05 pm If you want the input/output fluid of an assembly machine I'm pretty sure you should use the fluid boxes and not the inventory.

https://lua-api.factorio.com/latest/Lua ... y.fluidbox
Indeed, i did try early on but i did write it wrong, the correct syntax is as follow

Code: Select all

local fluid = entity.fluidbox[1]
fluid_input = MY_FUNCTION(fluid.name, fluid.amount)
probably need to add some safety checks like fluidbox_valid etc etc

Re: Read fluid in assembling machine input/output slot [control.lua]

Posted: Thu Jan 20, 2022 2:02 pm
by Pi-C
oldskoolmatt wrote: Thu Jan 20, 2022 1:30 pm The script keeps scanning for entities (on_tick) and apparently COUNT is much more UPS friendly than FIND.
Agreed, that makes sense. But from your code snippet it wasn't clear this would run in on_tick. :-)

Re: Read fluid in assembling machine input/output slot [control.lua]

Posted: Thu Jan 20, 2022 2:29 pm
by oldskoolmatt
This is not serviceable in this exact case (on_tick script), it will definitely crash at some point
Indeed, i did try early on but i did write it wrong, the correct syntax is as follow

Code: Select all

local fluid = entity.fluidbox[1]
fluid_input = MY_FUNCTION(fluid.name, fluid.amount)
probably need to add some safety checks like fluidbox_valid etc etc
Turns out that this syntax is the way to go:

Code: Select all

if entity and entity.fluidbox then
    for content, amount in pairs(entity.get_fluid_contents()) do
        fluid_input = MY_FUNCTION(content, amount)
    end
end