[Resolved] Need help with Inventory check

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

[Resolved] Need help with Inventory check

Post by TheSAguy »

Hi,

I'm trying to read the inventory of a turret when it kills a unit, but am gettign an error when the turret does not have any inventory to check.
Not sure what to add to my code to precent this.

The error line is:

Code: Select all

local inventoryContent = inventory.get_contents()
The full code is:

Code: Select all

local function On_Death(event)

	local entity = event.entity	
	
	if event.force ~= nil and entity.force.name == "enemy" and  entity.type	 == "unit" and event.cause then 

			local name = entity.name
			local inventory = event.cause.get_inventory(1)
			local inventoryContent = inventory.get_contents()	-- <-- Line causign issue	
			local AmmoType
			local Ammo = 0
			
			if inventoryContent ~= nil then
				for n,a in pairs(inventoryContent) do
					AmmoType=n
					Ammo=a
				end
			end
			
			writeDebug("Ammo Type: " .. AmmoType) -- disply Ammo Type
			writeDebug("Ammo Count: " .. Ammo) -- disply Ammo Count
			if AmmoType == "basic-dart-magazine_c"  or AmmoType == "enhanced-dart-magazine_c"   then
				-- do something
			end
			
	end
	
	
end
Error:
Image

Thanks.
Last edited by TheSAguy on Sat Sep 02, 2017 3:26 am, edited 3 times in total.
Nexela
Smart Inserter
Smart Inserter
Posts: 1828
Joined: Wed May 25, 2016 11:09 am
Contact:

Re: Need help with Inventory check

Post by Nexela »

Code: Select all

local function On_Death(event)

	local entity = event.entity	
	
	if event.force ~= nil and entity.force.name == "enemy" and  entity.type	 == "unit" and event.cause then 
              local name = entity.name
              if event.cause.type == "turret"

			local inventory = event.cause.get_inventory(defines.inventory.turret_ammo)
                        if inventory then ...............
                        

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

Re: Need help with Inventory check

Post by TheSAguy »

That did the trick!
Thanks.
TheSAguy
Smart Inserter
Smart Inserter
Posts: 1456
Joined: Mon Jan 13, 2014 6:17 pm
Contact:

Re: [Resolved] Need help with Inventory check

Post by TheSAguy »

Question on getting the inventory of the players gun.
When I use:

Code: Select all

local inventory = event.cause.get_inventory(defines.inventory.player_ammo)
It is getting the inventory of the first gun position and not the Active gun's inventory.
How does one get the Active / Gun being used's inventory?

Thanks.
Nexela
Smart Inserter
Smart Inserter
Posts: 1828
Joined: Wed May 25, 2016 11:09 am
Contact:

Re: [Resolved] Need help with Inventory check

Post by Nexela »

Code: Select all

if event.cause and event.cause.character then
  local inventory = event.cause.get_inventory(defines.inventory.player_ammo)
    if inventory  then -- Should always have a valid inventory here but just in case
      local current_ammo = inventory[event.cause.character.selected_gun_index]
      local current_gun = event.cause.get_inventory(defines.inventory.player_gun)[event.cause.character.selected_gun_index] 
         if current_ammo.valid_for_read   and current_gun.valid_for_read
TheSAguy
Smart Inserter
Smart Inserter
Posts: 1456
Joined: Mon Jan 13, 2014 6:17 pm
Contact:

Re: Need help with Inventory check

Post by TheSAguy »

Thanks Nexela, you responded so fast I did not even notice till now.

So it's not liking "cause.character"
It's saying:
Image

I can't find the online documentation for what is valid with "Cause"

Code so far:

Code: Select all

	--- Conversion Player Ammo
	if event.force ~= nil and entity.force.name == "enemy" and  entity.type	 == "unit" and event.cause and event.cause.type == "player" and event.cause.character then 
	
	
		local name = entity.name
		local inventory = event.cause.get_inventory(defines.inventory.player_ammo)

		if inventory then

		    local current_ammo = inventory[event.cause.character.selected_gun_index]
			local current_gun = event.cause.get_inventory(defines.inventory.player_gun)[event.cause.character.selected_gun_index] 	

       if current_ammo.valid_for_read   and current_gun.valid_for_read then
		 
		 
TheSAguy
Smart Inserter
Smart Inserter
Posts: 1456
Joined: Mon Jan 13, 2014 6:17 pm
Contact:

Re: Need help with Inventory check

Post by TheSAguy »

Anyone have a way to fix this?

"Cause" can't use "Character"
and "Selected_gun_index" needs "Character"

Since you know that the Cause is due to the character, first check, can we just drop the cause part somehow and focus on active character?

Thanks.
Nexela
Smart Inserter
Smart Inserter
Posts: 1828
Joined: Wed May 25, 2016 11:09 am
Contact:

Re: Need help with Inventory check

Post by Nexela »

The cause is the character so you can remove the cause.character check then

and event.cause.character --< delete that

change any event.cause.character. to event.cause.
TheSAguy
Smart Inserter
Smart Inserter
Posts: 1456
Joined: Mon Jan 13, 2014 6:17 pm
Contact:

Re: Need help with Inventory check

Post by TheSAguy »

I'm still not sure how to correct these two lines now:

Code: Select all

 local current_ammo = inventory[event.cause.character.selected_gun_index]
      local current_gun = event.cause.get_inventory(defines.inventory.player_gun)[event.cause.character.selected_gun_index] 
Crashing when removing "Character"
Nexela
Smart Inserter
Smart Inserter
Posts: 1828
Joined: Wed May 25, 2016 11:09 am
Contact:

Re: Need help with Inventory check

Post by Nexela »

Crashing when removing "Character"


Since I am not able to test, I would need the error it spews out :)
TheSAguy
Smart Inserter
Smart Inserter
Posts: 1456
Joined: Mon Jan 13, 2014 6:17 pm
Contact:

Re: Need help with Inventory check

Post by TheSAguy »

My bad.

Here is the error:
Image
Line 512 is:

Code: Select all

local current_ammo = event.cause.get_inventory(defines.inventory.player_gun)[event.cause.selected_gun_index]
Code:

Code: Select all

--- Conversion Player Ammo
	if event.force ~= nil and entity.force.name == "enemy" and  entity.type	 == "unit" and event.cause and event.cause.type == "player" then 
	
	
		local name = entity.name
		local inventory = event.cause.get_inventory(defines.inventory.player_ammo)

		if inventory then

		local current_gun = inventory[event.cause.selected_gun_index]
        local current_ammo = event.cause.get_inventory(defines.inventory.player_gun)[event.cause.selected_gun_index]    	

       --if current_ammo.valid_for_read   and current_gun.valid_for_read then
		 
		 
		
			writeDebug("Ammo Type: " .. current_ammo)
			writeDebug("Ammo Count: " .. current_gun)
			
			local inventoryContent = inventory.get_contents()		
			local AmmoType
			local Ammo = 0
				
			if inventoryContent ~= nil then
				for n,a in pairs(inventoryContent) do
					AmmoType=n
					Ammo=a
				end
			end
				
			--writeDebug("Ammo Type: " .. AmmoType)
			--writeDebug("Ammo Count: " .. Ammo)
			if AmmoType == "basic-dart-magazine_c"  or AmmoType == "enhanced-dart-magazine_c"  or AmmoType == "firearm-magazine_c"  or AmmoType == "copper-bullet-magazine_c"  or AmmoType == "piercing-rounds-magazine_c"  or AmmoType == "uranium-rounds-magazine_c"  or AmmoType == "Biological-bullet-magazine_c" then
				Convert = surface.create_entity({name = name, position = pos, force = event.cause.force.name})
				Convert.health = entity.prototype.max_health / 4
			end
			
		end	

	end
	
Control, Mod also attached.
Again, I'm trying to read the Active Gun's Ammo Type.

Thanks Nexela
Attachments
Natural_Evolution_Buildings_7.3.6.zip
MOD
(2.65 MiB) Downloaded 79 times
control.lua
Control
(19.55 KiB) Downloaded 82 times
Nexela
Smart Inserter
Smart Inserter
Posts: 1828
Joined: Wed May 25, 2016 11:09 am
Contact:

Re: Need help with Inventory check

Post by Nexela »

Code: Select all

--Put this table at the top of the file somewhere outside of other functions
local AMMO_TYPES = {
	["basic-dart-magazine_c"] = true,
	["enhanced-dart-magazine_c"] = true,
	["firearm-magazine_c"] = true,
	["copper-bullet-magazine_c"] = true,
	["piercing-rounds-magazine_c"] = true,
	["uranium-rounds-magazine_c"] = true,
	["Biological-bullet-magazine_c"] = true,
}

--replace both turret and character portions of function with this
-- lines 470 to 543
local enemy_force = event.force and event.force.name == "enemy" and event.force
local ammo
if entity.type == "unit" and enemy_force and event.cause then
	if event.cause.type == "ammo-turret" then
		local turret = event.cause
		ammo = turret.get_inventory(defines.inventory.ammo_turret)[1]
	elseif event.cause.type == "player" then
		local character = event.cause
		local index = character.selected_gun_index
		ammo = character.get_inventory(defines.inventory.player_ammo)[index]
	end

	if ammo and ammo.valid_for_read and AMMO_TYPES[ammo.name]then
		local Convert = surface.create_entity({name = entity.name, position = pos, force = enemy_force})
		Convert.health = entity.prototype.max_health / 4
	end
end
TheSAguy
Smart Inserter
Smart Inserter
Posts: 1456
Joined: Mon Jan 13, 2014 6:17 pm
Contact:

Re: Need help with Inventory check

Post by TheSAguy »

Thanks so much Nexela!
The "ammo = turret.get_inventory(defines.inventory.ammo_turret)[1]" part of the Ammo-turret did not work. It came back as a 'nil'.

So I blended what I had before and your new code into the below and it works.

Code: Select all

	--- Conversion Ammo Stuff
	local ammo

	if event.force ~= nil and entity.force.name == "enemy" and  entity.type	 == "unit" and event.cause then 

		if event.cause.type == "ammo-turret" then
		
			local inventory = event.cause.get_inventory(defines.inventory.turret_ammo)
			
			if inventory then
				local inventoryContent = inventory.get_contents()		
				local AmmoType
					
				if inventoryContent ~= nil then
					for n,a in pairs(inventoryContent) do
						AmmoType=n
					end
				end

				if AMMO_TYPES[AmmoType] then
					
					local Convert = surface.create_entity({name = entity.name, position = pos, force = event.cause.force.name})
					Convert.health = entity.prototype.max_health / 4
				end
			  
			end
			
		elseif event.cause.type == "player" then

			local character = event.cause
			local index = character.selected_gun_index
			ammo = character.get_inventory(defines.inventory.player_ammo)[index]
		  
			if ammo and ammo.valid_for_read and AMMO_TYPES[ammo.name] then

			local Convert = surface.create_entity({name = entity.name, position = pos, force = event.cause.force.name})
			Convert.health = entity.prototype.max_health / 4
			end
	   end

	end
Thanks again!
Nexela
Smart Inserter
Smart Inserter
Posts: 1828
Joined: Wed May 25, 2016 11:09 am
Contact:

Re: Need help with Inventory check

Post by Nexela »

TheSAguy wrote:The "ammo = turret.get_inventory(defines.inventory.ammo_turret)[1]" part of the Ammo-turret did not work. It came back as a 'nil'.

ooops that should be defines.inventory.turret_ammo and it should work


There are a few limitations to the code though
for both character and turret the last shot won't do anything if the player or gun is out of ammo.

Here is a slightly better version that should work

Code: Select all

--Put this table at the top of the file somewhere outside of other functions
local AMMO_TYPES = {
    ["basic-dart-magazine_c"] = true,
    ["enhanced-dart-magazine_c"] = true,
    ["firearm-magazine_c"] = true,
    ["copper-bullet-magazine_c"] = true,
    ["piercing-rounds-magazine_c"] = true,
    ["uranium-rounds-magazine_c"] = true,
    ["Biological-bullet-magazine_c"] = true,
}

--replace both turret and character portions of function with this
-- lines 470 to 543
local enemy_force = event.force and event.force.name == "enemy" and event.force
local ammo
if entity.type == "unit" and enemy_force and event.cause then
    if event.cause.type == "ammo-turret" then
        local turret = event.cause
        local inventory = turret.get_inventory(defines.inventory.turret_ammo)
        for k in pairs(inventory.get_contents()) do
            if AMMO_TYPES[k] then
                ammo = inventory.find_item_stack(k)
                break
            end
        end
    elseif event.cause.type == "player" then
        local character = event.cause
        local index = character.selected_gun_index
        ammo = character.get_inventory(defines.inventory.player_ammo)[index]
    end

    if ammo and ammo.valid_for_read and AMMO_TYPES[ammo.name]then
        local Convert = surface.create_entity({name = entity.name, position = pos, force = enemy_force})
        Convert.health = entity.prototype.max_health / 4
    end
end
TheSAguy
Smart Inserter
Smart Inserter
Posts: 1456
Joined: Mon Jan 13, 2014 6:17 pm
Contact:

Re: [Resolved] Need help with Inventory check

Post by TheSAguy »

Thanks,
It still did not like this line:

Code: Select all

local enemy_force = event.force and event.force.name == "enemy" and event.force
if entity.type == "unit" and enemy_force and event.cause then
Was never true, so just replaced with:

Code: Select all

if event.force ~= nil and entity.force.name == "enemy" and  entity.type	 == "unit" and event.cause then 
And the last part updated to:
local Convert = surface.create_entity({name = entity.name, position = pos, force = event.cause.force.name})
Since that was the whole purpose of this little exercise, convert units to the player :)


Thanks for all your help with this!
Nexela wrote:
for both character and turret the last shot won't do anything if the player or gun is out of ammo.
You need to use the last bullet on yourself, not the biter...

Final Code:

Code: Select all

	--- Conversion Ammo Stuff
	local ammo
	if event.force ~= nil and entity.force.name == "enemy" and  entity.type	 == "unit" and event.cause then 
	writeDebug("Step 1")
		if event.cause.type == "ammo-turret" then
			local turret = event.cause
			local inventory = turret.get_inventory(defines.inventory.turret_ammo)
			for k in pairs(inventory.get_contents()) do
				if AMMO_TYPES[k] then
					ammo = inventory.find_item_stack(k)
					break
				end
			end
		elseif event.cause.type == "player" then
			local character = event.cause
			local index = character.selected_gun_index
			ammo = character.get_inventory(defines.inventory.player_ammo)[index]
		end

		if ammo and ammo.valid_for_read and AMMO_TYPES[ammo.name]then
			local Convert = surface.create_entity({name = entity.name, position = pos, force = event.cause.force.name})
			Convert.health = entity.prototype.max_health / 4
		end
	end
	
Post Reply

Return to “Modding help”