[Done] Help with removing Inventory from assembling-machine

Place to get help with not working mods / modding interface.
TheSAguy
Smart Inserter
Smart Inserter
Posts: 1449
Joined: Mon Jan 13, 2014 6:17 pm
Contact:

[Done] Help with removing Inventory from assembling-machine

Post 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.
Last edited by TheSAguy on Tue Mar 27, 2018 4:48 pm, edited 3 times in total.

User avatar
Deadlock989
Smart Inserter
Smart Inserter
Posts: 2528
Joined: Fri Nov 06, 2015 7:41 pm

Re: Help with removing Inventory from assembling-machine

Post 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
Image

TheSAguy
Smart Inserter
Smart Inserter
Posts: 1449
Joined: Mon Jan 13, 2014 6:17 pm
Contact:

Re: Help with removing Inventory from assembling-machine

Post 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.

User avatar
Deadlock989
Smart Inserter
Smart Inserter
Posts: 2528
Joined: Fri Nov 06, 2015 7:41 pm

Re: Help with removing Inventory from assembling-machine

Post 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
Image

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Help with removing Inventory from assembling-machine

Post 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.

TheSAguy
Smart Inserter
Smart Inserter
Posts: 1449
Joined: Mon Jan 13, 2014 6:17 pm
Contact:

Re: Help with removing Inventory from assembling-machine

Post by TheSAguy »

Much appreciated!

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

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

Post by eradicator »

Be wary of "empty" fluidboxes btw, they don't exist, so trying to read them will cause an error.

TheSAguy
Smart Inserter
Smart Inserter
Posts: 1449
Joined: Mon Jan 13, 2014 6:17 pm
Contact:

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

Post 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.
Attachments
Save.zip
Save
(1.56 MiB) Downloaded 30 times
control_arboretum.lua
Control File
(7.98 KiB) Downloaded 30 times
Bio_Industries_2.2.1.zip
Mod
(5.64 MiB) Downloaded 29 times

TheSAguy
Smart Inserter
Smart Inserter
Posts: 1449
Joined: Mon Jan 13, 2014 6:17 pm
Contact:

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

Post 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.

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Help with removing Inventory from assembling-machine

Post 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.

TheSAguy
Smart Inserter
Smart Inserter
Posts: 1449
Joined: Mon Jan 13, 2014 6:17 pm
Contact:

Re: Help with removing Inventory from assembling-machine

Post 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?

User avatar
darkfrei
Smart Inserter
Smart Inserter
Posts: 2903
Joined: Thu Nov 20, 2014 11:11 pm
Contact:

Re: Help with removing Inventory from assembling-machine

Post 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
Last edited by darkfrei on Mon Mar 26, 2018 12:16 pm, edited 1 time in total.

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Help with removing Inventory from assembling-machine

Post 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

TheSAguy
Smart Inserter
Smart Inserter
Posts: 1449
Joined: Mon Jan 13, 2014 6:17 pm
Contact:

Re: Help with removing Inventory from assembling-machine

Post 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,.

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Help with removing Inventory from assembling-machine

Post 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.

TheSAguy
Smart Inserter
Smart Inserter
Posts: 1449
Joined: Mon Jan 13, 2014 6:17 pm
Contact:

Re: Help with removing Inventory from assembling-machine

Post 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.

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Help with removing Inventory from assembling-machine

Post 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.

User avatar
darkfrei
Smart Inserter
Smart Inserter
Posts: 2903
Joined: Thu Nov 20, 2014 11:11 pm
Contact:

Re: Help with removing Inventory from assembling-machine

Post 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.

TheSAguy
Smart Inserter
Smart Inserter
Posts: 1449
Joined: Mon Jan 13, 2014 6:17 pm
Contact:

Re: Help with removing Inventory from assembling-machine

Post 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.)


Post Reply

Return to “Modding help”