Jump to content

[HELP] Give Item not working?


Recommended Posts

Hi to all,

I'm trying to get my item to go back to my inventory when it gets broken, triggering it with OnFinished, and here is the code:

local function OnFinished (inst, owner)
if owner and owner.components and owner.components.inventory and inst.components.finiteuses:GetPercent() <= 0 then
local item = owner.components.inventory:unequip(EQUIPSLOTS.HANDS)
			 owner.components.inventory:GiveItem(item)
	

end
end

This isn't crashing,  this was the thing I initially thought of, but it also doesn't seem to work. I've also tried

local function OnFinished (inst, owner)
if owner and owner.components and owner.components.inventory and inst.components.finiteuses:GetPercent() <= 0 then 
local katana = owner.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)
if katana then 
local katana = owner.components.inventory:Unequip(EQUIPSLOTS.HANDS)
data.owner.components.inventory:GiveItem(katana)
end
end
end

something I did after I read a post in the forums, but both just.. do nothing when the weapon breaks. The character still goes into the animation but the item doesn't get sent into my inventory nor gets unequipped... they did implement it differently in such a way that an event would be listened to and the "breaking" is treated like a separate function but I thought since there's OnFinished already I could use that instead.. or maybe I cant?

I've also noticed that my item tends to go beyond 0%, and I'm not sure how to prevent that.

 

Anyone can help me? It would be very appreciated, and I know the solution might be simple, but uh.. yeah.. I've been having at this for four hours now; its /fun AF/ but I'm losing a ton of sleep... and a nudge in the right direction would be great. Many thanks.

 

Edited by SourNVitriol
Link to comment
Share on other sites

local function OnBreak(inst, owner)
if inst.components.finiteuses:GetPercent() <= 0 then
  if owner and owner.components and owner.components.inventory then
  owner.components.inventory:GiveItem(inst)  
  owner.components.inventory:unequip(inst)     
  if owner.components.talker then
  owner.components.talker:Say("It's dull.")
  end
end
end
end



    inst:ListenForEvent("percentusedchange", OnBreak)

So I tried something new, and it still isn't working.. Can anyone point me out to what causes the "break" animation fx? I've looked into finiteuses components and all I see is onfinished, and it says nothing about how the fx appear.. It seems like when a finiteuse item breaks, you go into a gettinghit state, but I'm not sure how to hook to that.

Edited by SourNVitriol
Link to comment
Share on other sites

I think I've come up with a solution for you, @SourNVitriol

Spoiler

Just add the following to your item's prefab file, make sure it's anywhere underneath your "equippable" component variables so that they've been declared first, else you'll get an error by trying to store them:


local old_onequip = inst.components.equippable and inst.components.equippable.onequipfn
local old_onunequip = inst.components.equippable and inst.components.equippable.onunequipfn
--Store any other "equippable" variables youve set here

local function onBreak(inst, data)
	local owner = inst.components.inventoryitem.owner
	if data and data.percent <= 0 or inst.components.finiteuses:GetPercent() <= 0 then
		if owner then
			if inst.components.inventoryitem.cangoincontainer then
	            owner.components.inventory:GiveItem(inst)
	        else
	            owner.components.inventory:DropItem(inst, true, true)
	        end
			owner.components.talker:Say("It's dull.")
		end
		inst:RemoveComponent("equippable")
	elseif inst.components.equippable == nil then
		inst:AddComponent("equippable")
		inst.components.equippable:SetOnEquip(old_onequip)
		inst.components.equippable:SetOnUnequip(old_onunequip)
		--Recall any other stored "equippable" variables youve set here
	end
end

if GLOBAL.TheWorld.ismastersim then
	inst.components.finiteuses:SetOnFinished(nil)
	inst:ListenForEvent("percentusedchange", onBreak)
end

 

This makes it so as soon as you've used up the item, it gets sent to the player's inventory at 0% and removes the "equippable" component to prevent them from equipping it again until it's been repaired. The only little bug I was coming across was if you're a client (non-host or on a world with caves) the item doesn't update to 0% when it's sent to your inventory and instead says 1% until you do something to update it (pick it up, examine it, etc).

I've made a note in the code but I'll say it here, too, that it's important to store any other "equippable" variables you've set for your weapon prior to removing the component because by removing and adding the component, you're essentially resetting everything to the component's default values (onequip and onunequip would then be nil). Also be sure to set the component variables to their stored values after you add the component back to your item (also noted in the code).

Also it's important to make sure you push the "percentusedchange" event in the OnLoad() function of finiteuses, but I remember giving you a hand with that so you should already have that part taken care of. ;) Lemme know if there's anything else I can do.

Edited by w00tyd00d
Link to comment
Share on other sites

22 hours ago, w00tyd00d said:

 

  Reveal hidden contents

Just add the following to your item's prefab file, make sure it's anywhere underneath your "equippable" component variables so that they've been declared first, else you'll get an error by trying to store them:



local old_onequip = inst.components.equippable and inst.components.equippable.onequipfn
local old_onunequip = inst.components.equippable and inst.components.equippable.onunequipfn
--Store any other "equippable" variables youve set here

local function onBreak(inst, data)
	local owner = inst.components.inventoryitem.owner
	if data and data.percent <= 0 or inst.components.finiteuses:GetPercent() <= 0 then
		if owner then
			if inst.components.inventoryitem.cangoincontainer then
	            owner.components.inventory:GiveItem(inst)
	        else
	            owner.components.inventory:DropItem(inst, true, true)
	        end
			owner.components.talker:Say("It's dull.")
		end
		inst:RemoveComponent("equippable")
	elseif inst.components.equippable == nil then
		inst:AddComponent("equippable")
		inst.components.equippable:SetOnEquip(old_onequip)
		inst.components.equippable:SetOnUnequip(old_onunequip)
		--Recall any other stored "equippable" variables youve set here
	end
end

if GLOBAL.TheWorld.ismastersim then
	inst.components.finiteuses:SetOnFinished(nil)
	inst:ListenForEvent("percentusedchange", onBreak)
end

 

 

Also it's important to make sure you push the "percentusedchange" event in the OnLoad() function of finiteuses, but I remember giving you a hand with that so you should already have that part taken care of. ;) Lemme know if there's anything else I can do.

Thanks w00tyd00d! I've put it in the code as you've said and made it work. It didn't at all occur to me that you could've nil valued the OnFinished. Idk why i kept banging at the same function... but at least I'm learning more methods as I go along :D All thanks to you, friend!

Although I'm not sure what you're asking of me with the percentusedchange; I "could" (havent yet) add it to the OnLoad function of finite uses, and just trigger it push it although I'm not sure what it does. I'm kinda puzzled since even before I did anything with it, the code already worked and gave the proper values even when I disconnect and reconnect, then reequip without a percentusedchange event at OnLoad.

About the bug, im not able to reproduce it client side for some reason, but I do go into the negatives when I use it at 1%. Though I'm not much bothered by it, currently figuring out how to make it so it doesnt happen. And it really shouldn't since in finite uses:

function FiniteUses:SetUses(val)
    local was_positive = self.current > 0
    self.current = val
    self.inst:PushEvent("percentusedchange", {percent = self:GetPercent()})
    if self.current <= 0 then
        self.current = 0
        if was_positive and self.onfinished ~= nil then
            self.onfinished(self.inst)
        end
    end
end

Im gonna now try to add the current <=0 code (well, something similar) to OnBreak and see where that goes.

Edited by SourNVitriol
Update
Link to comment
Share on other sites

21 minutes ago, SourNVitriol said:

Although I'm not sure what you're asking of me with the percentusedchange; I can add it to the OnLoad function of finite uses, and just trigger it push it although I'm not sure what it does. I'm kinda puzzled since even before I did anything with it, the code already worked even when I disconnect and reconnect, then reequip without a percentcheck on load.

If it works when without needing it then great! What adding the PushEvent to the OnLoad() function basically does is update your ListenForEvent function of the same name right as the entity is loaded in to the world. Thinking on it now it actually makes sense, it would only be important when it comes to spawned in things to the world (like when you find damaged items at boons) but in this particular case it's a non-issue because you'll never find anything spawned in at 0% durability. :p 

The reason it works by default is normally an item is set at its max durability when it's spawned in (unless spawned in by a boon) but because it has save data (thanks to its OnSave function) saying it has a lower durability, the game then applies the durability to the current value and that automatically procs the PushEvent for "percentusedchange". In case it's still unclear, PushEvent and ListenForEvent are basically just lock-and-key functions using a specific "key word" for refining when to run context-specific functions with context-specific data, such as when something's durability has been updated in some way. ;)

21 minutes ago, SourNVitriol said:

About the bug, im not able to reproduce it client side for some reason, but I do go into the negatives when I use it at 1%.

Yeah I did occasionally see that as well lol I only ever saw it as -0% tho, and it was only ever while the item was the active item (on your cursor). It could just be a side effect of the game never having to worry about something at 0% durability before, but if you manage to find a solution for it then even better :) 

Edited by w00tyd00d
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
  • Create New...