Nominative99 Posted November 24, 2019 Share Posted November 24, 2019 (edited) Hello to All! EDIT: I have been working on this since yesterday, and now the issue has changed slightly. Please excuse my edits. I have been working on making some custom items for a friend's character. All the functions he wanted have been completed and I am currently in the process of testing for crashing, balance, code cleanup/commenting and likewise. I've hit a snag though when it comes to the use of containers such as the backpack, chest, etc. The items I've made are supposed to be character exclusive and undroppable. The character spawns with their exclusive item and that same item is used for various recipes. Once the "fuel" runs out, it reverts back to the original item. My issue is, when this item is placed in a backpack/container and it's dropped in the world. When the fuel hits zero, the item disappears. It doesn't get added back into the container's inventory nor does it just "loot drop" into the world. It has to do with the function "OnFinished". This is called when the fuel hits zero, it gets removed, then immediately gives the player the original item. A pseudo "replace" function essentially. I couldn't find any "replace with" function to use. local function OnFinished(inst) local owner = inst.components.inventoryitem:GetGrandOwner() local flask = SpawnPrefab("wyrdflask") inst:Remove() if owner ~= nil then -- CHECK IF THE OWNER ITEM IS VALID IN THE EVENT THE FLASK SOMEHOW ENDS UP IN THE WORLD owner.components.inventory:GiveItem(flask) else inst.components.lootdropper:SpawnLootPrefab("wyrdflask") -- DROPS NORMAL FLASK AS BASIC LOOT IN THE CASE OF ABOVE end end Even though the item "undroppable", it isn't immune to container shenanigans such as putting it in a backpack. So if someone puts the crafted item into a backpack or container and it reaches zero, it's gone if that container is dropped anywhere in the world. I did put in a check to see if the owner is nil in the event the item somehow gets dropped into the world, but unfortunately, it sees the container as an owner. I speculated that perhaps the "world" aka nil would cause the item to just "loot drop" into the world, but it just makes it disappear completely. It probably sees the grandowner as Limbo or something, and I unfortunately don't know how to exactly check if "owner = limbo". It might be better to make it so it cannot go into a backpack/chest/etc in the first place, but I don't know how to go about that. If anyone could provide assistance, I would be extremely grateful. Thank You! P.S. If anyone could assist in making the items pickup exclusive by this character named "wyrd", that would also be grand. I've tried using this below at the very bottom of the item's function fn(sim), but when testing, any character I spawn as can pick it up. local oldOnPickup = inst.components.inventoryitem.OnPickup inst.components.inventoryitem.OnPickup = function(self, pickupguy) if pickupguy.prefab == "wyrd" then if not self.inst.itemowner then self.inst.itemowner = pickupguy end if pickupguy == self.inst.itemowner then oldOnPickup(self, pickupguy) elseif pickupguy.components.talker then pickupguy.components.talker:Say("That flask is cursed...") end elseif pickupguy.components.talker then pickupguy.components.talker:Say("Definately can't touch this...") end end wyrdflask_health.lua Edited November 26, 2019 by Nominative99 Changes Since Posted. Cleaned up Post and added Script. Link to comment Share on other sites More sharing options...
Nominative99 Posted November 26, 2019 Author Share Posted November 26, 2019 (edited) Good news, I've figured out the disappearing issue. I got so wrapped up that I overlooked using "components.container". Disappearing issue solved thankfully. local function OnFinished(inst) local owner = inst.components.inventoryitem.owner local flask = SpawnPrefab("wyrdflask") inst:Remove() if owner ~= nil and owner.components.inventory then -- CHECK IF THE OWNER ITEM IS VALID AND NOT A CONTAINER owner.components.inventory:GiveItem(flask) elseif owner ~= nil and owner.components.container then -- OR IF THE OWNER IS VALID AND IS A CONTAINER owner.components.container:GiveItem(flask) else inst.components.lootdropper:SpawnLootPrefab("wyrdflask") -- DROPS NORMAL FLASK AS BASIC LOOT IN THE CASE OF ABOVE end end I just need assistance on making the item "bag proof" or at least drop into the world if it's in a container. Unfortunately the code (located in first post) I am using to make it a character exclusive pickup is not working. I've tried testing it on characters that are not the character "wyrd", but they are all able to pickup the item and at the same type spit out the taker:Say() comments. Thank You Edited November 26, 2019 by Nominative99 Link to comment Share on other sites More sharing options...
maliblues Posted November 26, 2019 Share Posted November 26, 2019 (edited) I've been trying to figure it out and this is what I have that works (so far). inst:AddComponent("inventoryitem") inst.components.inventoryitem:SetOnPutInInventoryFn(OnPutInInventory) local function OnPutInInventory(inst) print("flask put inventory fn ran") local owner = inst.components.inventoryitem:GetGrandOwner() -------------- if owner then print("flask picked by", owner.name, owner.prefab) --just for testing end ------------- if owner.components.inventory and owner.prefab ~= "wyrd" then inst:DoTaskInTime(0.1, function() owner.components.inventory:DropItem(inst) owner.components.talker:Say("That flask is cursed...") end) end if owner.components.container then --for chests --test when in backpack with diff owner inst:DoTaskInTime(0.1, function() owner.components.container:DropItem(inst) end) end end In the quick tests I did when it is picked up by someone and if it isn't the character prefab given then it is dropped back down. Also when put in a chest it will get dropped (I think that's what you wanted). Now it does go in the backpack of the character that can carry it but I haven't tested what happens with a different player taking the backpack. I found this post helpful, before I was getting some weird issues where the item would drop but also another copy remain in the inventory. I think it needs more testing still but just posting what I had and can look more into it later if needed. It isn't perfect but maybe it can be of some use. Also I'll just attach the copy I worked on, I didn't have the art files so just added random DST ones. wyrdflask_health.lua Edited November 26, 2019 by maliblues Link to comment Share on other sites More sharing options...
Nominative99 Posted November 27, 2019 Author Share Posted November 27, 2019 (edited) Definitely appreciate it and is practically perfect. With the backpack, any other character can pick it up, the the second it is interacted with the mouse, it pops out which works perfectly really. You most likely noticed the "undroppable" tag, which overrides the drop function, so it still goes into the player's inventory (It's a requirement for the character). I've posted the code below. "API Friendly Approach" - by Jjmarco AddComponentPostInit("inventory", function(self) -- Adding a new Function "fn" -- Store the default Item Drop Function local DropItem_base = self.DropItem function self:DropItem(item, ...) -- If the item has the tag "undroppable", do nothing. if item:HasTag("undroppable") then return false else return DropItem_base(self, item, ...) -- otherwise, use default execution end end end) Is there a way to add an additional check in the PostInit so that the "return false" not only checks for the "undroppable" tag, but also if the player character is "wyrd"? I've been searching around trying a few ends, but I might be applying it incorrectly. Thank You modmain.lua Edited November 27, 2019 by Nominative99 Link to comment Share on other sites More sharing options...
Nominative99 Posted November 27, 2019 Author Share Posted November 27, 2019 Wait, I think I got it. Found it after some searching and looking at examples in the workshop. AddComponentPostInit("inventory", function(self) -- Adding a new Function "fn" -- Store the default Item Drop Function local DropItem_base = self.DropItem function self:DropItem(item, ...) -- If the item has the tag "undroppable", do nothing. if item:HasTag("undroppable") and GLOBAL.ThePlayer:HasTag("bartender") then return false else return DropItem_base(self, item, ...) -- otherwise, use default execution end end end) Lastly, I did find one bug in regards to the containers. If the player tries to "Store" it into a container, it crashes with "attempt to index local 'owner' (a nil value)" I made a tweak to check if the owner was "nil", then just return. Prevents it from crashing really. Item goes into the backpack and that's perfectly fine. local function OnPutInInventory(inst) local owner = inst.components.inventoryitem:GetGrandOwner() if owner == nil then return elseif owner.components.inventory and owner.prefab ~= "wyrd" then inst:DoTaskInTime(0.1, function() owner.components.inventory:DropItem(inst) owner.components.talker:Say("That flask is cursed...") end) end if owner.components.container then --for chests --test when in backpack with diff owner inst:DoTaskInTime(0.1, function() owner.components.container:DropItem(inst) end) end end Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now