Page 1 of 2

[Done] Help with removing Inventory from assembling-machine

Posted: Thu Mar 22, 2018 9:08 pm
by TheSAguy
Hi,

I'm trying to remove inventory from an assembling-machine I have when a " radar scan" is completed.

So, when I build the assembling-machine, I store it as follow:

Code: Select all

	if entity.valid and entity.name == "bi-Arboretum" then
		   
		local arboretum = entity
		local radar_name = "bi-Arboretum-Radar"  
		
		local position_c = {position.x - 4, position.y + 3.95}
		local create_radar = surface.create_entity({name = radar_name, position = position_c, force = force})

		  
		create_radar.minable = false
		create_radar.destructible = false

		global.Arboretum_Table[entity.unit_number] = {inventory=entity, radar=create_radar }

	end

When the Radar complete's it's scan, I do this:

Code: Select all

script.on_event(defines.events.on_sector_scanned, function(event)
	
	---- Each time a Arboretum-Radar scans a sector, do ----	
	if event.radar.name == "bi-Arboretum-Radar" then
		local num = (event.radar.unit_number-1)
		Get_Arboretum_Recipe(global.Arboretum_Table[num], event) 
		
	end
	
end)
So, now I have the "global.Arboretum_Table[num]"
I can read the recipe, by using:
local recipe = ArboretumTable.inventory.get_recipe()

But I'm having a hard time being able to read the inventory content of the assembling-machine.

Currently I have 5 recipes it can have. Three of them have two ingredients and two had three ingredients. One of the ingredients is always water.

So I can identify the recipe, now I want to check and make sure the ingredients are there and if there, remove 1. (100 in the case of water)

Can someone please help me out with this.

I tried stuff like:
ArboretumTable.inventory.get_inventory(1).get_contents()

but that gives a nil.
or

for k = 1,3 do
ArboretumTable.inventory.get_inventory(k).get_contents()

Thanks.

Re: Help with removing Inventory from assembling-machine

Posted: Thu Mar 22, 2018 9:22 pm
by Deadlock989
get_inventory() takes the defined constants for different inventory types, e.g.

Code: Select all

defines.inventory.assembling_machine_input	
defines.inventory.assembling_machine_output	
defines.inventory.assembling_machine_modules
http://lua-api.factorio.com/latest/LuaC ... _inventory
http://lua-api.factorio.com/latest/defines.html

Re: Help with removing Inventory from assembling-machine

Posted: Fri Mar 23, 2018 1:06 am
by TheSAguy
Thanks Deadlock,

So I get to read the items, but not the fluid (water) with below:

Code: Select all

			local my_inv = ArboretumTable.inventory.get_inventory(defines.inventory.assembling_machine_input).get_contents()
			
					for n,a in pairs(my_inv) do
						Item_name=n
						Amount=a
					
						writeDebug("Inv is: "..Item_name)
						writeDebug("# is: "..Amount)	
					end
				
Image


So i get the fertilizer and seeds, but not the water.
What should I use to read the water?
Thanks.

Re: Help with removing Inventory from assembling-machine

Posted: Fri Mar 23, 2018 1:17 am
by Deadlock989
I don't have direct experience of this but I'm pretty sure that fluids live in the fluid boxes. In fact I think I'm right in saying that fluids can ONLY be in fluid boxes.

http://lua-api.factorio.com/latest/LuaFluidBox.html

Re: Help with removing Inventory from assembling-machine

Posted: Fri Mar 23, 2018 1:23 am
by eradicator
http://lua-api.factorio.com/latest/LuaE ... y.fluidbox
Entity.fluidbox[1].name and .amount. [x] depends on how many boxes the entity has and in what order they are defined.

Re: Help with removing Inventory from assembling-machine

Posted: Fri Mar 23, 2018 4:57 pm
by TheSAguy
Much appreciated!

Re: [Done] Help with removing Inventory from assembling-machine

Posted: Fri Mar 23, 2018 4:59 pm
by eradicator
Be wary of "empty" fluidboxes btw, they don't exist, so trying to read them will cause an error.

Re: [Done] Help with removing Inventory from assembling-machine

Posted: Fri Mar 23, 2018 6:05 pm
by TheSAguy
Okay, I'm having a hard time getting this code to work, never mind clean/optimized...

Currently I have 5 recipes it can have. Three of them have two ingredients and two had three ingredients. One of the ingredients is always water.
I first need to check that there is the needed inventory, 1 each of the items (could be 1 or 2, depending on the recipe) and 100 water.

If they are there, then I run the code to plant the tree or change the terrain or both,

Then I need to deduct the inventory.


Below is an example of Recipe 5:

Code: Select all

	elseif recipe_name == "bi_Arboretum_r5" then
				
					writeDebug(recipe_name..": Plant Tree and change the terrain to grass - 1 (advanced)")
					local pos = ArboretumTable.inventory.position
					local surface = ArboretumTable.inventory.surface					
					
					for k = 1,10 do
										
						local xxx = math.random(-plant_radius, plant_radius)
						local yyy = math.random(-plant_radius, plant_radius)
						local new_position = {x = pos.x + xxx,y = pos.y + yyy}
						local currentTilename = surface.get_tile(new_position.x, new_position.y).name
						local can_be_placed = surface.can_place_entity{name= "seedling", position = new_position, force = "neutral"}
							
						if can_be_placed and Bi_Industries.fertility[currentTilename] then 
						
							local terrain_name
							if game.active_mods["alien-biomes"] then 
								terrain_name = "vegetation-green-grass-1"
							else
								terrain_name = "grass-1"
							end
							
							surface.set_tiles{{name=terrain_name, position=new_position}}			
							
							ArboretumTable.inventory.fluidbox[1].amount = ArboretumTable.inventory.fluidbox[1].amount - 200 --<-- Not Working
							
							for n,a in pairs(my_inv) do
								Item_name=n
								Amount=a
								writeDebug("Inv is: "..Item_name)
								writeDebug("# is: "..Amount)	
								Amount = Amount-1	
								--ArboretumTable.inventory.get_inventory(defines.inventory.assembling_machine_input).clear() --<-- Not Working
								if Amount > 0 then
									ArboretumTable.inventory.get_inventory(defines.inventory.assembling_machine_input).insert({name = Item_name, count = Amount})
								end
							end
							
							local create_seedling = surface.create_entity({name = "seedling", position = new_position, force = "neutral"})
							seed_planted_arboretum (event, create_seedling)
							
							break
								
						else	
						
							writeDebug("can't plant or change terrain here")
							
						end
						
					end
Anyway I can get a little help here?

I've attached the Save, Mod and just the Control file.
I have the planting tree and changing terrain down, probably just need to change those to functions in each recipe.
Just need a little help, detecting the ingredients and deducting them once a tree is planted or terrain is changed.

I found this function, that I feel could possibly be tweaked:

Code: Select all

  local get_inventory = function(entity)
    if not entity.valid then return nil end
    local inventory = {}
    for k = 1,10 do
      local inv = entity.get_inventory(k)
      if inv then
        inventory[k] = inv.get_contents()
      end
    end
    if #inventory > 0 then
      return inventory
    else
      return nil
    end
  end
Thanks.

Re: [Done] Help with removing Inventory from assembling-machine

Posted: Sun Mar 25, 2018 11:01 pm
by TheSAguy
I really could use a little help here please.

I'm able to read the fluid box content, using:

Code: Select all

local Water_Name = ArboretumTable.inventory.fluidbox[1].name
local Water_Level = ArboretumTable.inventory.fluidbox[1].amount
But how do I alter the value? I want to deduct 100 water if there is at least 100.
Below does not work:

Code: Select all


ArboretumTable.inventory.fluidbox[1].amount = ArboretumTable.inventory.fluidbox[1].amount - 200
ArboretumTable.inventory.fluidbox[1].amount.insert({name = Water_Name, count = 100})

eradicator wrote:Be wary of "empty" fluidboxes btw, they don't exist, so trying to read them will cause an error.
So what's the solution to reading an empty fluid box?

I've tried if below then:

Code: Select all

ArboretumTable.inventory.fluidbox
ArboretumTable.inventory.fluidbox.valid
ArboretumTable.inventory.fluidbox[1]
ArboretumTable.inventory.fluidbox[1].valid
None seem to work....


For the items in the recipes, I can read them using:

Code: Select all

local my_inv = ArboretumTable.inventory.get_inventory(defines.inventory.assembling_machine_input).get_contents()

for n,a in pairs(my_inv) do								
   Item_name=n 
   Amount=a
   writeDebug("Inv is: "..Item_name)
   writeDebug("# is: "..Amount)	
end
But again, I'm having a hard time checking to make sure all inventory levels are above 0, and deducting the inventory 1 per inventory.
If I only have 1 ingredient it works using:

Code: Select all

	for n,a in pairs(my_inv) do
					
		Item_name=n
		Amount=a
		writeDebug("Inv is: "..Item_name)
		writeDebug("# is: "..Amount)	

		if Amount > 0 then
								
          		Amount = Amount-1	
			ArboretumTable.inventory.get_inventory(defines.inventory.assembling_machine_input).clear()
			ArboretumTable.inventory.get_inventory(defines.inventory.assembling_machine_input).insert({name = Item_name, count = Amount})
								
		end
						
	end
It kinda works, though crashes when there is just 1 inventory and also if there is more than 400, it just removes the excess and starts at 400...

Hope to get some help.
Thanks.

Re: Help with removing Inventory from assembling-machine

Posted: Sun Mar 25, 2018 11:34 pm
by eradicator

Code: Select all

If entity.fluidbox[1] == nil then
  entity.fluidbox[1] = {name='water',amount=10}
  end
A fluidbox sub-table will be nil if it does not contain anything. And you write it by writing a whole table to the box, you can not alter the amount directly.
I have no experience with assembler item inventory manipulation so i can't help you with that.

Re: Help with removing Inventory from assembling-machine

Posted: Mon Mar 26, 2018 2:21 am
by TheSAguy
eradicator wrote:

Code: Select all

If entity.fluidbox[1] == nil then
  entity.fluidbox[1] = {name='water',amount=10}
  end
A fluidbox sub-table will be nil if it does not contain anything. And you write it by writing a whole table to the box, you can not alter the amount directly.
I have no experience with assembler item inventory manipulation so i can't help you with that.
Thanks eradicator, that worked!

Anyone know how I can manipulate multiple inventory boxes on a assembler?

Re: Help with removing Inventory from assembling-machine

Posted: Mon Mar 26, 2018 12:15 pm
by darkfrei
TheSAguy wrote:Anyone know how I can manipulate multiple inventory boxes on a assembler?
What exactly you are need to manipulate?

entity.fluidbox[2]
http://lua-api.factorio.com/latest/LuaFluidBox.html

Re: Help with removing Inventory from assembling-machine

Posted: Mon Mar 26, 2018 12:16 pm
by eradicator
TheSAguy wrote:Anyone know how I can manipulate multiple inventory boxes on a assembler?
Looking at your code while not half asleep...
You seem to be confusing LuaInventory with LuaItemStack (again?). The result of get_inventory() is a LuaInventory, which is something like a table of LuaItemStack. Item stack count can be manipulated directly.
If stacks in assemblers behave mostly like other stacks you'd do it like this:

Code: Select all

local Inventory = entity.get_inventory(defines.whatever)
local things= 0 --stacks that are large enough
for _,stack in pairs(Inventory) do
  if stack.count > 0 then --0 or whatevert the minimum amount you need is
    things = things + 1
    end
  end
if things == #Inventory --every slot in the inventory has at least one/enough item/s
  for _,stack in pairs(Inventory) do
    stack.count  = stack.count - 1
    end
   end

Re: Help with removing Inventory from assembling-machine

Posted: Mon Mar 26, 2018 4:18 pm
by TheSAguy
eradicator wrote:
TheSAguy wrote:Anyone know how I can manipulate multiple inventory boxes on a assembler?
Looking at your code while not half asleep...
You seem to be confusing LuaInventory with LuaItemStack (again?). The result of get_inventory() is a LuaInventory, which is something like a table of LuaItemStack. Item stack count can be manipulated directly.
If stacks in assemblers behave mostly like other stacks you'd do it like this:
Thanks eradicator,
I used the below code:

Code: Select all

								local Inventory = ArboretumTable.inventory.get_inventory(defines.inventory.assembling_machine_input)
								local things = 0 --stacks that are large enough
								for _,stack in pairs(Inventory) do
									if stack.count > 0 then --0 or whatevert the minimum amount you need is
										things = things + 1
										writeDebug("things is: "..things)
									end
								end

								if things == #Inventory then --every slot in the inventory has at least one/enough item/s
									for _,stack in pairs(Inventory) do
										stack.count  = stack.count - 1
									end
								end
And got this error: (Line 94 is: "for _,stack in pairs(Inventory) do"
Image
darkfrei wrote:
TheSAguy wrote:Anyone know how I can manipulate multiple inventory boxes on a assembler?
What exactly you are need to manipulate?
Hey darkfrei,

I got the fluid box working,
All that I now want to do is manipulate the item boxes on the Assembler. (On radar scan. I have a hidden radar that scans, and each time it scans I want to check inventory in a assembler and if I have at lease 1 item(s) and 100 water, do an action)

I have two types of recipes, one has 2 ingredients, (Water and Seedlings) the second had 3 (Water, Seedlings and Fertilizer)
I'm checking to make sure there is at least 100 water and removing 100 per scan. <-- This works.

Now I want to check the 1 or 2 item boxes on the assembler.

I've tried eradicator code above and mine below without success...

Code: Select all

							local my_inv = ArboretumTable.inventory.get_inventory(defines.inventory.assembling_machine_input).get_contents()
							for n,a in pairs(my_inv) do
								
								Item_name=n
								Amount=a
								writeDebug("Inv is: "..Item_name)
								writeDebug("# is: "..Amount)	
								if Amount > 0 then
								
									Amount = Amount-1	
									ArboretumTable.inventory.get_inventory(defines.inventory.assembling_machine_input).clear()
									ArboretumTable.inventory.get_inventory(defines.inventory.assembling_machine_input).insert({name = Item_name, count = Amount})
								
								end
							
							end
Here is the coed when building the entity if needed:
--- Arboretum has been built
if entity.valid and entity.name == "bi-Arboretum" then

local arboretum = entity
local radar_name = "bi-Arboretum-Radar"

local position_c = {position.x - 4, position.y + 3.95}
local create_radar = surface.create_entity({name = radar_name, position = position_c, force = force})


create_radar.minable = false
create_radar.destructible = false

global.Arboretum_Table[entity.unit_number] = {inventory=entity, radar=create_radar }

end
Thanks,.

Re: Help with removing Inventory from assembling-machine

Posted: Mon Mar 26, 2018 5:59 pm
by eradicator
Hm. For some reason i can't get pairs() to work with inventories. I thought it worked before. You'll have to use for i=1,#Inventory instead, and also check valid_for_read before accessing the stack, because it might be an empty stack.

Re: Help with removing Inventory from assembling-machine

Posted: Mon Mar 26, 2018 7:42 pm
by TheSAguy
eradicator wrote:Hm. For some reason i can't get pairs() to work with inventories. I thought it worked before. You'll have to use for i=1,#Inventory instead, and also check valid_for_read before accessing the stack, because it might be an empty stack.
Not following you here eradicator, sorry.

Re: Help with removing Inventory from assembling-machine

Posted: Mon Mar 26, 2018 8:59 pm
by eradicator
TheSAguy wrote:
eradicator wrote:Hm. For some reason i can't get pairs() to work with inventories. I thought it worked before. You'll have to use for i=1,#Inventory instead, and also check valid_for_read before accessing the stack, because it might be an empty stack.
Not following you here eradicator, sorry.
What part of that do you not understand? Have you never used a for i=1,x loop? I simply tested by own code (from above) and noticed that for pairs(Inventory) does not work as i excepted. It returns...whatever. Something that is not a LuaItemStack, and only one. So it can't be used.

Re: Help with removing Inventory from assembling-machine

Posted: Mon Mar 26, 2018 10:02 pm
by darkfrei
The this part was bad:

Code: Select all

for i,stack in pairs(Inventory) do
The suggested part is good:

Code: Select all

for i = 1, #Inventory do
local stack = Inventory[i]
Actually, normally by lua it's the same, but not in Factorio API.

Re: Help with removing Inventory from assembling-machine

Posted: Mon Mar 26, 2018 10:31 pm
by TheSAguy
Okay, If I cahnged the code to:

Code: Select all

local Inventory = ArboretumTable.inventory.get_inventory(defines.inventory.assembling_machine_input)
					
   for i = 1, #Inventory do
        local stack = Inventory[i]
        for _,stack in pairs(Inventory) do
                 stack.count  = stack.count - 1
        end
  end
The #Inventory is correct. Reads 1 or 2, depending on the recipe. but I get this error:
Image

I checked and stack = Inventory holds the inventory item name and count.
I now just need to deduct 1 from each.

(It does crash if empty though.)

Re: Help with removing Inventory from assembling-machine

Posted: Mon Mar 26, 2018 10:53 pm
by eradicator