Tejras3 Posted February 20, 2023 Share Posted February 20, 2023 i need to make that i can eat my item more than just one time, i thought finiteuses will do but i'm wrong The idea is that i can USE/EAT (and if it's use i need to play that eating animation) it and heal some sanity Link to comment https://forums.kleientertainment.com/forums/topic/146086-finiteuses-on-eatable-item-or-something/ Share on other sites More sharing options...
Merkyrrie Posted February 23, 2023 Share Posted February 23, 2023 Unfortunately anything eaten is always removed from your inventory at the end of the eat function, so even if the item has finite uses it both won't have its uses depleted in that function nor will that stop it from being deleted after. You'll probably need to work around this by making your own eating action and function for the item, entirely separate from the game's eat action, which can get complicated and messy but shouldn't be impossible. The gist of it would be making a custom action with a custom component attached to your food item, forgoing the edible component while also using the finiteuses component. The action can call a function in that custom component that does the same things the normal Eat function does but removing the part that deletes the food and replacing it with code that reduces the uses left on the food item. There will still be problems with this that could come up you may need to account for, as your item isn't technically food. Hopefully that gives you somewhere to go with it. If you're new to modding dst it might be a bit daunting to do/understand all that so I'm happy to continue helping if its needed. There are also multiple posts on the forums that can help explain how to do a custom action or a custom component. 1 Link to comment https://forums.kleientertainment.com/forums/topic/146086-finiteuses-on-eatable-item-or-something/#findComment-1621625 Share on other sites More sharing options...
Tejras3 Posted February 23, 2023 Author Share Posted February 23, 2023 6 hours ago, Merkyrrie said: Unfortunately anything eaten is always removed from your inventory at the end of the eat function, so even if the item has finite uses it both won't have its uses depleted in that function nor will that stop it from being deleted after. You'll probably need to work around this by making your own eating action and function for the item, entirely separate from the game's eat action, which can get complicated and messy but shouldn't be impossible. The gist of it would be making a custom action with a custom component attached to your food item, forgoing the edible component while also using the finiteuses component. The action can call a function in that custom component that does the same things the normal Eat function does but removing the part that deletes the food and replacing it with code that reduces the uses left on the food item. There will still be problems with this that could come up you may need to account for, as your item isn't technically food. Hopefully that gives you somewhere to go with it. If you're new to modding dst it might be a bit daunting to do/understand all that so I'm happy to continue helping if its needed. There are also multiple posts on the forums that can help explain how to do a custom action or a custom component. yea, now I understand how i can do that but i can't find an examples of custom action/component, i'll search more actually my another idea was that i can use edible component and delete something that was causing item to delete and just somehow add depleting of % (i saw somewhere that a guy used a lighter (from willow) and just deleted fuel component by one line) ty, i'm new and wasn't waiting for a reply really Link to comment https://forums.kleientertainment.com/forums/topic/146086-finiteuses-on-eatable-item-or-something/#findComment-1621646 Share on other sites More sharing options...
Tejras3 Posted February 23, 2023 Author Share Posted February 23, 2023 Oki, i found some examples and now i somewhat understand these things but still can't figure out what i need to steal from normal Eat function tho or maybe i just can't find the right one Link to comment https://forums.kleientertainment.com/forums/topic/146086-finiteuses-on-eatable-item-or-something/#findComment-1621660 Share on other sites More sharing options...
Tejras3 Posted February 23, 2023 Author Share Posted February 23, 2023 I don't understand what i need to put in my custom component and my head hurts already so I'll do it later ig Link to comment https://forums.kleientertainment.com/forums/topic/146086-finiteuses-on-eatable-item-or-something/#findComment-1621666 Share on other sites More sharing options...
Merkyrrie Posted February 23, 2023 Share Posted February 23, 2023 6 hours ago, Tejras3 said: I don't understand what i need to put in my custom component and my head hurts already so I'll do it later ig Basically just the Eat function from the eater component really, to emulate what already happens when you eat something. Like this maybe: Spoiler local CustomEater = Class(function(self, inst) self.inst = inst end) function CustomEater:CustomEat(food, feeder) feeder = feeder or self.inst -- This is likely going unused but the oneat pushevent wants it -- Everything in this function assumes this component is attached to the Player eater = self.inst.components.eater -- For easily changing all self function calls to go to the eater component if eater:PrefersToEat(food) then local stack_mult = self.eatwholestack and food.components.stackable ~= nil and food.components.stackable:StackSize() or 1 -- Not needed if the food isn't stackable local base_mult = self.inst.components.foodmemory ~= nil and self.inst.components.foodmemory:GetFoodMultiplier(food.prefab) or 1 -- Not needed if Warly won't be eating the food -- Both stack_mult and base_mult can likely be removed, but you'll need to remove their variables below too local health_delta = 0 local hunger_delta = 0 local sanity_delta = 0 if self.inst.components.health ~= nil and (food.components.edible.healthvalue >= 0 or self:DoFoodEffects(food)) then health_delta = food.components.edible:GetHealth(self.inst) * base_mult * eater.healthabsorption end if self.inst.components.hunger ~= nil then hunger_delta = food.components.edible:GetHunger(self.inst) * base_mult * eater.hungerabsorption end if self.inst.components.sanity ~= nil and (food.components.edible.sanityvalue >= 0 or self:DoFoodEffects(food)) then sanity_delta = food.components.edible:GetSanity(self.inst) * base_mult * eater.sanityabsorption end if eater.custom_stats_mod_fn ~= nil then health_delta, hunger_delta, sanity_delta = eater.custom_stats_mod_fn(self.inst, health_delta, hunger_delta, sanity_delta, food, feeder) end if health_delta ~= 0 then self.inst.components.health:DoDelta(health_delta * stack_mult, nil, food.prefab) end if hunger_delta ~= 0 then self.inst.components.hunger:DoDelta(hunger_delta * stack_mult) end if sanity_delta ~= 0 then self.inst.components.sanity:DoDelta(sanity_delta * stack_mult) end -- This is unneeded unless you want the food to be feedable to something like a bird in a cage, but the bird will need this component then so.. -- if feeder ~= self.inst and self.inst.components.inventoryitem ~= nil then -- local owner = self.inst.components.inventoryitem:GetGrandOwner() -- if owner ~= nil and (owner == feeder or (owner.components.container ~= nil and owner.components.container:IsOpenedBy(feeder))) then -- feeder:PushEvent("feedincontainer") -- end -- end self.inst:PushEvent("oneat", { food = food, feeder = feeder }) if eater.oneatfn ~= nil then eater.oneatfn(self.inst, food) end if food.components.edible ~= nil then food.components.edible:OnEaten(self.inst) end -- Change the Remove part of this function to Use for finiteuses. the Use function will handle removing the item instead if food:IsValid() and food.components.finiteuses then food.components.finiteuses:Use(1) -- Assuming this food isn't stackable, if it is you'll need to add a check for that and it might be messy with finiteuses end self.lasteattime = GetTime() -- This can be removed if Warly won't ever be eating this food if self.inst.components.foodmemory ~= nil and not food:HasTag("potion") then self.inst.components.foodmemory:RememberFood(food.prefab) end return true end end If you planned on putting this component on the food instead (so you don't have to add it to players) you'd need to change the self.inst to feeder and make the feeder variable properly register who the doer actually is 1 Link to comment https://forums.kleientertainment.com/forums/topic/146086-finiteuses-on-eatable-item-or-something/#findComment-1621728 Share on other sites More sharing options...
Tejras3 Posted February 24, 2023 Author Share Posted February 24, 2023 13 hours ago, Merkyrrie said: Basically just the Eat function from the eater component really, to emulate what already happens when you eat something. Like this maybe: Reveal hidden contents local CustomEater = Class(function(self, inst) self.inst = inst end) function CustomEater:CustomEat(food, feeder) feeder = feeder or self.inst -- This is likely going unused but the oneat pushevent wants it -- Everything in this function assumes this component is attached to the Player eater = self.inst.components.eater -- For easily changing all self function calls to go to the eater component if eater:PrefersToEat(food) then local stack_mult = self.eatwholestack and food.components.stackable ~= nil and food.components.stackable:StackSize() or 1 -- Not needed if the food isn't stackable local base_mult = self.inst.components.foodmemory ~= nil and self.inst.components.foodmemory:GetFoodMultiplier(food.prefab) or 1 -- Not needed if Warly won't be eating the food -- Both stack_mult and base_mult can likely be removed, but you'll need to remove their variables below too local health_delta = 0 local hunger_delta = 0 local sanity_delta = 0 if self.inst.components.health ~= nil and (food.components.edible.healthvalue >= 0 or self:DoFoodEffects(food)) then health_delta = food.components.edible:GetHealth(self.inst) * base_mult * eater.healthabsorption end if self.inst.components.hunger ~= nil then hunger_delta = food.components.edible:GetHunger(self.inst) * base_mult * eater.hungerabsorption end if self.inst.components.sanity ~= nil and (food.components.edible.sanityvalue >= 0 or self:DoFoodEffects(food)) then sanity_delta = food.components.edible:GetSanity(self.inst) * base_mult * eater.sanityabsorption end if eater.custom_stats_mod_fn ~= nil then health_delta, hunger_delta, sanity_delta = eater.custom_stats_mod_fn(self.inst, health_delta, hunger_delta, sanity_delta, food, feeder) end if health_delta ~= 0 then self.inst.components.health:DoDelta(health_delta * stack_mult, nil, food.prefab) end if hunger_delta ~= 0 then self.inst.components.hunger:DoDelta(hunger_delta * stack_mult) end if sanity_delta ~= 0 then self.inst.components.sanity:DoDelta(sanity_delta * stack_mult) end -- This is unneeded unless you want the food to be feedable to something like a bird in a cage, but the bird will need this component then so.. -- if feeder ~= self.inst and self.inst.components.inventoryitem ~= nil then -- local owner = self.inst.components.inventoryitem:GetGrandOwner() -- if owner ~= nil and (owner == feeder or (owner.components.container ~= nil and owner.components.container:IsOpenedBy(feeder))) then -- feeder:PushEvent("feedincontainer") -- end -- end self.inst:PushEvent("oneat", { food = food, feeder = feeder }) if eater.oneatfn ~= nil then eater.oneatfn(self.inst, food) end if food.components.edible ~= nil then food.components.edible:OnEaten(self.inst) end -- Change the Remove part of this function to Use for finiteuses. the Use function will handle removing the item instead if food:IsValid() and food.components.finiteuses then food.components.finiteuses:Use(1) -- Assuming this food isn't stackable, if it is you'll need to add a check for that and it might be messy with finiteuses end self.lasteattime = GetTime() -- This can be removed if Warly won't ever be eating this food if self.inst.components.foodmemory ~= nil and not food:HasTag("potion") then self.inst.components.foodmemory:RememberFood(food.prefab) end return true end end If you planned on putting this component on the food instead (so you don't have to add it to players) you'd need to change the self.inst to feeder and make the feeder variable properly register who the doer actually is Wow thank you! So now i need to create a custom action to trigger that custom eat right? Link to comment https://forums.kleientertainment.com/forums/topic/146086-finiteuses-on-eatable-item-or-something/#findComment-1621778 Share on other sites More sharing options...
Tejras3 Posted February 24, 2023 Author Share Posted February 24, 2023 (edited) Oki, I was trying to do custom action ALL DAY and finally somehow did it (i'm stupid so i forgor to add something and just realized this in the end), but now it says that variable eater isn't declared in the custom component (line 11,13 for example) and food too, really just dk what to do now xd Edited February 24, 2023 by Tejras3 Link to comment https://forums.kleientertainment.com/forums/topic/146086-finiteuses-on-eatable-item-or-something/#findComment-1621823 Share on other sites More sharing options...
Merkyrrie Posted February 24, 2023 Share Posted February 24, 2023 3 hours ago, Tejras3 said: Oki, I was trying to do custom action ALL DAY and finally somehow did it (i'm stupid so i forgor to add something and just realized this in the end), but now it says that variable eater isn't declared in the custom component (line 11,13 for example) and food too, really just dk what to do now xd My bad, it needs a local in front of it (I don't know how I missed that) local eater = self.inst.components.eater 1 Link to comment https://forums.kleientertainment.com/forums/topic/146086-finiteuses-on-eatable-item-or-something/#findComment-1621840 Share on other sites More sharing options...
Tejras3 Posted February 24, 2023 Author Share Posted February 24, 2023 1 hour ago, Merkyrrie said: My bad, it needs a local in front of it (I don't know how I missed that) local eater = self.inst.components.eater "attempt to index local 'food' (a nil value)" in if eater:PrefersToEat(food) then... Link to comment https://forums.kleientertainment.com/forums/topic/146086-finiteuses-on-eatable-item-or-something/#findComment-1621849 Share on other sites More sharing options...
Merkyrrie Posted February 24, 2023 Share Posted February 24, 2023 18 minutes ago, Tejras3 said: "attempt to index local 'food' (a nil value)" in if eater:PrefersToEat(food) then... Sounds like its not getting the paramaters for the function, what does the call to the function look like in the custom action? 1 Link to comment https://forums.kleientertainment.com/forums/topic/146086-finiteuses-on-eatable-item-or-something/#findComment-1621853 Share on other sites More sharing options...
Tejras3 Posted February 24, 2023 Author Share Posted February 24, 2023 6 minutes ago, Merkyrrie said: Sounds like its not getting the paramaters for the function, what does the call to the function look like in the custom action? It'll be no surprise if i done it wrong and actually i can ask now what i need to put instead of obj. to check for that component because it just gives an obj = nil type error or does it just mean that there is no such component in my item? Link to comment https://forums.kleientertainment.com/forums/topic/146086-finiteuses-on-eatable-item-or-something/#findComment-1621854 Share on other sites More sharing options...
Merkyrrie Posted February 25, 2023 Share Posted February 25, 2023 The parameters in the function call (where you put food and feeder) need to be variables currently accessible in wherever the function is being called. In this case, you want to replace food with "act.invobject" and feeder with "act.doer", as act.invobject in AddAction is the item being used and act.doer is the one doing it. 1 Link to comment https://forums.kleientertainment.com/forums/topic/146086-finiteuses-on-eatable-item-or-something/#findComment-1621859 Share on other sites More sharing options...
Tejras3 Posted February 25, 2023 Author Share Posted February 25, 2023 21 minutes ago, Merkyrrie said: The parameters in the function call (where you put food and feeder) need to be variables currently accessible in wherever the function is being called. In this case, you want to replace food with "act.invobject" and feeder with "act.doer", as act.invobject in AddAction is the item being used and act.doer is the one doing it. Oh oki understand that too now, had no clue about wtf i needed to put there so just copypasted the function... aaaaaaaand IT FINALLY WORKS THANK YOU I wouldn't been able to do this without your help cuz i wasn't even thinking about eater component, at first i thought that what i needed was EAT action in actions.lua. thankyouu i can finally sleep 1 Link to comment https://forums.kleientertainment.com/forums/topic/146086-finiteuses-on-eatable-item-or-something/#findComment-1621864 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