Jump to content

[Solved] When inventory bar gets item


Recommended Posts

Hi,

I need function that triggers when inventory bar gets item.

 

This function works perfect when item leaves inventory bar.

inst.components.inventoryitem:SetOnRemovedFn(fn)

 

But this one:

inst.components.inventoryitem:SetOnPickupFn(fn)

or this one:

inst.components.inventoryitem:SeOnPutInInventoryFn(fn)

Works only halfway... -.-

I mean it trigger when inventory bar gets item. but it also trigger when item is held by mouse.

 

How to trigger it only in inventory bar?

Link to comment
Share on other sites

You should be able to call inventoryitem.owner.inventory:GetActiveItem() (where inventoryitem is the inventoryitem component on your item, and you of course make sure to check whether it has an owner first and that that owner has an inventory). This function retrieves the item currently being held in the mouse. If it's nil, then the item is not being held in the mouse by the owner, and thus it must be in his inventory.

Link to comment
Share on other sites

I tried owner.inventory:GetActiveItem() before, and there's no effect no matter what I try.

local function OnPutInInventory(inst, owner)
	if owner then
		local active_item = owner.components.inventory:GetActiveItem()
		if active_item == nil then
			--my fn
		end
	end
end

It does my fn on bar and on mouse too. -,-

That's reason why I make this thread...

Link to comment
Share on other sites

Try putting in this, and see what all the print statements say. They should show you the status of everything when trying different ways of putting things into your inventory. Maybe you'll see something that'll help you. You can also look into using the GetItemSlot() function from inventory, to see where the item has been put.

local function OnPutInInventory(inst, owner)
	print("-----------------------------------------")
	if inst == nil then
		print("OnPutInInventory => inst was nil")
		return
	end
	print("inst prefab: "..inst.prefab)
	if owner == nil then
		print("OnPutInInventory => owner was nil")
	end
	if owner then
		local active_item = owner.components.inventory:GetActiveItem()
		print("OnPutInInventory => active_item prefab: "..(active_item ~= nil and active_item.prefab or "no active item"))
		if active_item == nil or active_item ~= inst then
			print("OnPutInInventory => Executing my code!")
			--my fn
		end
	end
end

 

Link to comment
Share on other sites

Print is handy...

I tried your code and it kept saying "no active item", on bar and mouse...

Detecting owner is pointless I think, because there'll be always owner?

Changed for inv, this one doesn't crash if item is put in container...

Spoiler

local function OnPutInInventory(inst, owner)
	print("-----------------------------------------")
	if inst == nil then
		print("OnPutInInventory => inst was nil")
		return
	end
	print("OnPutInInventory => inst prefab: "..inst.prefab)
	if owner == nil then
		print("OnPutInInventory => owner was nil")
	end
	print("OnPutInInventory => owner prefab: "..owner.prefab)
	local inv = owner.components.inventory
	if inv == nil then
		print("OnPutInInventory => inv was nil")
	end
	if inv then
		print("OnPutInInventory => active_item prefab: "..(inv.activeitem ~= nil and inv.activeitem.prefab or "no active item"))
		if inv.activeitem == nil or inv.activeitem ~= inst then
			print("OnPutInInventory => Executing my code!")
			--my fn
		end
	end
end

 

 

Link to comment
Share on other sites

Just now, zetake said:

Print is handy...

Indeed :D

Just now, zetake said:

I tried your code and it kept saying "no active item", on bar and mouse...

Interesting. I guess that means that the item is being removed from the hand

Just now, zetake said:

Detecting owner is pointless I think, because there'll be always owner?

Apparently you are already the owner of an item when you have it in your mouse. I just wondered if maybe that would be a way to see if it had been put into an inventory, but apparently not. When an item is dropped, "owner" is set to nil.

Just now, zetake said:

Changed for inv, this one doesn't crash if item is put in container...

Good catch.

GetItemSlot(item) on your player's inventory should return nil if the item is not in it. You can check like that. You may also have to check whether the item was equippedm, for which you can use IsItemEquipped(item).

Link to comment
Share on other sites

This one

local slot = inv:GetItemSlot(inst)

and this one

local slot = inv:GetItemSlotByName(inst.prefab)

kept saying slot was nil... in bar and mouse...
What's more interestint, InventoryItem:SetOnActiveItemFn(fn) trigger when item is held >.<
Why can't I have other way?

 

P.S: Item is custom, do it matters?

Link to comment
Share on other sites

That doesn't sound right.The item is definitely being put into the slot before your OnPutInInventory is called. Some more debugging is in order. Check that everything you think you know about the state is as you think it is, and meticulously study it. If something doesn't make sense, make absolutely sure that what you're printing is correct, and if so, you gotta find out why that thing doesn't make sense to you, because for some reason, it makes sense for the game :)

Sorry, I don't have much time atm to dive into things like this. Normally, I'd debug things for people. I just don't have the time right now.

Link to comment
Share on other sites

Am I missing something?

Spoiler

OnPutInInventory:

Spoiler


local function OnPutInInventory(inst, owner)
	print("-----------------------------------------")
	
	if inst == nil then
		print("OnPutInInventory => inst was nil.")
	else
		print("OnPutInInventory => inst prefab was: "..inst.prefab)
	end
	
	if owner == nil then
		print("OnPutInInventory => owner was nil.")
	else
		print("OnPutInInventory => owner prefab was: "..owner.prefab)
	end
	
	local inv = owner.components.inventory
	if inv == nil then
		print("OnPutInInventory => inventory was nil.")
	end
	
	local slot1 = inst.components.inventoryitem:GetSlotNum()
	if slot1 == nil then
		print("OnPutInInventory => slot1 was nil.")
	else
		print("OnPutInInventory => slot1 WASN'T NIL! HURRAY!")
	end
	
	if inv then
		local active_item = inv:GetActiveItem()
		if active_item == nil then
			print("OnPutInInventory => active item was nil.")
		else
			print("OnPutInInventory => active item WASN'T NIL! HURRAY!")
		end
	
		local slot2 = inv:GetItemSlot(inst)
		if slot2 == nil then
			print("OnPutInInventory => slot2 was nil.")
		else
			print("OnPutInInventory => slot2 WASN'T NIL! HURRAY!")
		end
		
		local slot3 = inv:GetItemSlotByName(inst.prefab)
		if slot3 == nil then
			print("OnPutInInventory => slot3 was nil.")
		else
			print("OnPutInInventory => slot3 WASN'T NIL! HURRAY!")
		end
		
		local slot4 = inv:GetItemSlotByName("blueisr")
		if slot4 == nil then
			print("OnPutInInventory => slot4 was nil.")
		else
			print("OnPutInInventory => slot4 WASN'T NIL! HURRAY!")
		end
		
		local container = inst.components.inventoryitem:GetContainer()
		if container == nil then
			print("OnPutInInventory => container was nil.")
		else		
			local slot5 = container:GetItemSlot(inst)
			if slot5 == nil then
				print("OnPutInInventory => slot5 was nil.")
			else
				print("OnPutInInventory => slot5 WASN'T NIL! HURRAY!")
			end
		end
		
		--if  then
		--	print("OnPutInInventory => Executing my code!")
		--	inst.components.container:Open(owner)
		--end
	end
end

 

OnRemoved:

Spoiler


local function OnRemoved(inst, owner)
	local inv = owner.components.inventory
	if inv then
		local open = inst.components.container.open
		if open then
			inst.components.container:Close(owner)
		end
	end
end

 

Log:

Spoiler


[00:02:30]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(19,1) -----------------------------------------	
[00:02:30]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(24,1) OnPutInInventory => inst prefab was: blueisr	
[00:02:30]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(30,1) OnPutInInventory => owner prefab was: wendy	
[00:02:30]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(40,1) OnPutInInventory => slot1 was nil.	
[00:02:30]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(48,1) OnPutInInventory => active item was nil.	
[00:02:30]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(55,1) OnPutInInventory => slot2 was nil.	
[00:02:30]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(62,1) OnPutInInventory => slot3 was nil.	
[00:02:30]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(69,1) OnPutInInventory => slot4 was nil.	
[00:02:30]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(80,1) OnPutInInventory => slot5 was nil.	
[00:02:31]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(19,1) -----------------------------------------	
[00:02:31]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(24,1) OnPutInInventory => inst prefab was: blueisr	
[00:02:31]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(30,1) OnPutInInventory => owner prefab was: backpack	
[00:02:31]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(35,1) OnPutInInventory => inventory was nil.	
[00:02:31]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(42,1) OnPutInInventory => slot1 WASN'T NIL! HURRAY!	
[00:02:32]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(19,1) -----------------------------------------	
[00:02:32]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(24,1) OnPutInInventory => inst prefab was: blueisr	
[00:02:32]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(30,1) OnPutInInventory => owner prefab was: wendy	
[00:02:32]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(40,1) OnPutInInventory => slot1 was nil.	
[00:02:32]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(48,1) OnPutInInventory => active item was nil.	
[00:02:32]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(55,1) OnPutInInventory => slot2 was nil.	
[00:02:32]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(62,1) OnPutInInventory => slot3 was nil.	
[00:02:32]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(69,1) OnPutInInventory => slot4 was nil.	
[00:02:32]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(80,1) OnPutInInventory => slot5 was nil.	
[00:02:33]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(19,1) -----------------------------------------	
[00:02:33]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(24,1) OnPutInInventory => inst prefab was: blueisr	
[00:02:33]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(30,1) OnPutInInventory => owner prefab was: wendy	
[00:02:33]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(40,1) OnPutInInventory => slot1 was nil.	
[00:02:33]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(48,1) OnPutInInventory => active item was nil.	
[00:02:33]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(55,1) OnPutInInventory => slot2 was nil.	
[00:02:33]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(62,1) OnPutInInventory => slot3 was nil.	
[00:02:33]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(69,1) OnPutInInventory => slot4 was nil.	
[00:02:33]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(80,1) OnPutInInventory => slot5 was nil.	
[00:02:33]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(19,1) -----------------------------------------	
[00:02:33]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(24,1) OnPutInInventory => inst prefab was: blueisr	
[00:02:33]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(30,1) OnPutInInventory => owner prefab was: wendy	
[00:02:33]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(40,1) OnPutInInventory => slot1 was nil.	
[00:02:33]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(48,1) OnPutInInventory => active item was nil.	
[00:02:33]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(55,1) OnPutInInventory => slot2 was nil.	
[00:02:33]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(62,1) OnPutInInventory => slot3 was nil.	
[00:02:33]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(69,1) OnPutInInventory => slot4 was nil.	
[00:02:33]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(80,1) OnPutInInventory => slot5 was nil.	
[00:02:34]: ../mods/[HAM] Container Slots (1.00)/scripts/prefabs/isrs.lua(19,1) -----------------------------------------

 

 

It doesn't work with OnPutInInventory or OnPickup, and it doesn't work with custom or vanilla item... >.<

Link to comment
Share on other sites

Ah, I think I see it now. These lines in inventory GiveActiveItem() tell the story:

inst.components.inventoryitem:OnPutInInventory(self.inst)

self:SetActiveItem(inst)
self.inst:PushEvent("itemget", {item=inst, slot = nil})

Your OnPutInInventory IS actually called before the item is made the active item. Interestingly, the inventory pushes the "itemget" event afterwards on the instance with the inventory component on it, which can be the player or a container (note that backpacks being worn are considered an "overflow container" and are actually handled by the player's inventory component; I'm not sure how that works when they are on the ground, or what other special stuff might be going on with those), so perhaps that's a better way to approach this? The data it sends along tells you that slot is nil when it is in the mouse.

Link to comment
Share on other sites

Uhmm

                inst.components.inventoryitem:OnPutInInventory(self.inst)
	    	    self.itemslots[slot] = inst
			    self.inst:PushEvent("itemget", {item=inst, slot = slot, src_pos = screen_src_pos})

Well, it has to be done otherway... T.T

P.S: In containers fn is called after... Eh

Link to comment
Share on other sites

1 minute ago, zetake said:

Uhmm


                inst.components.inventoryitem:OnPutInInventory(self.inst)
	    	    self.itemslots[slot] = inst
			    self.inst:PushEvent("itemget", {item=inst, slot = slot, src_pos = screen_src_pos})

 

Yes, that's the code from GiveItem(), as in when an item is given directly to the player, and the code I posted is from GiveActiveItem() which is called when the player puts an item into their mouse.

You're going to have to figure out a way to work within the system. It seems the events are the best way to get there.

Link to comment
Share on other sites

OnRemoved triggers twice too...

It goes like this:

Spoiler

From ground/else to hand:
OnPickup > OnPutInInventory

From bar to mouse:
OnRemoved > OnPickup > OnPutInInventory > OnActiveItem

From bar to container:
OnRemoved > OnPutInInventory(container owner)

From mouse to ground:
OnRemoved > OnDropped(owner nil)

From mouse to bar:
OnRemoved > OnPickup > OnPutInInventory

From mouse to container:
OnRemoved > OnPutInInventory(container owner)

From container to bar:
OnRemoved(container owner) > OnPickup > OnPutInInventory

From container to mouse:
OnRemoved(container owner) > OnPickup > OnPutInInventory > OnActiveItem

From humid to ground:
OnRemoved > OnDropped(owner nil)

So, I used as a base the one that triggers only once which is OnActiveItem.

AAAAANNND it works like it should. ;D

Spoiler

modmain

Spoiler


AddClassPostConstruct("components/inventoryitem", function(self, inst)
	self.inbar = false
	local inbar = self.inbar
	function self:GetInBar()
		return inbar
	end
	function self:SetInBar()
		if inbar then
			inbar = false
		else
			inbar = true
		end
	end
end)

AddClassPostConstruct("components/container", function(self, inst)
	function self:SetOpenable(yes)
		if yes then
			self.canbeopened = true
		end
		if not yes then
			self.canbeopened = false
		end
	end
end)

 

custom item/container

Spoiler


local function OnPutInInventory(inst, owner)
	local container = inst.components.container
	local invitem = inst.components.inventoryitem
	local inv = owner.components.inventory
	if inv then
		if not invitem:GetInBar() then
			invitem:SetInBar()
			if not container:IsOpen() then
				inst.components.container:Open(owner)
			end
		end
	else
		container:SetOpenable(false)	-- container item will not be able to be opened in another container
		if not invitem:GetInBar() then
			invitem:SetInBar()			-- in case when item will be put in container
		end
	end
end

local function OnActiveItem(inst, owner)
	local invitem = inst.components.inventoryitem
	if invitem:GetInBar() then				-- in case when item will be put in container
		invitem:SetInBar()
	end
end

local function OnDropped(inst, owner)
	local invitem = inst.components.inventoryitem
	if invitem:GetInBar() then
		invitem:SetInBar()				-- in case when item will be dropped without mouse
	end
end


local function OnRemoved(inst, owner)
	local container = inst.components.container
	local inv = owner.components.inventory
	if inv then
		if container:IsOpen() then
			inst.components.container:Close(owner)
		end
	else
		container:SetOpenable(true)		-- container item once again will be able to be opened
	end
end

and in fn()



	invitem:SetOnDroppedFn(OnDropped)
    invitem:SetOnActiveItemFn(OnActiveItem)
	invitem:SetOnPutInInventoryFn(OnPutInInventory)
    invitem:SetOnRemovedFn(OnRemoved)

 

 

This trigges fn1 only on inventory bar and fn2 when it leaves inventory bar. (From mouse left, ctrl + left mouse and humid.)

Why I needed this? Because I made custom container that is inventory item and it's not equipable item like a backpack, but I wanted it to work as one.

Yes, I could make new equipable slot, but I'm not sure if it's good idea, I mean new equipable slot doesn't suit my new item...

P.S: Dind't know that you can drop item from mouse to bar via right mouse button... XD
 

Link to comment
Share on other sites

Wow, you really did some studying for this, and it paid off beautifully :)

You managed to do this without breaking anything :D You should be proud!

Don't make a new equip slot. There are several mods out there doing that already, and you don't want to fiddle with making your mod compatible with them all.

Link to comment
Share on other sites

However, from container to bar it doesn't work... (Because container doesn't have active item...)

So, I make better version that works always...

Spoiler

local function OnPutInInventory(inst, owner)
	local invitem = inst.components.inventoryitem
	local inv = owner.components.inventory
	if inv then
		if not invitem:GetInBar() then
			invitem:SetInBar()
		end
		inst:DoTaskInTime(0.01, function()
			if invitem:GetInBar() then
				if not container:IsOpen() then
					inst.components.container:Open(owner)
				end
			end
		end)
	end
end

local function OnActiveItem(inst, owner)
	local invitem = inst.components.inventoryitem
	if invitem:GetInBar() then
		invitem:SetInBar()
	end
end

 

Quote

OnActiveItem says to OnPutInInventory: You can't be after me!

OnPutInInventory takes out DoTaskInTime: OH, REALLY?

 

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

Please be aware that the content of this thread may be outdated and no longer applicable.

×
  • Create New...