Jump to content

Recommended Posts

I am trying to have a function run after eating a prepared food. I've seen that for prefabs like dark petals and the mandrake there is an oneaten function, but I don't know if there is something similar for prepared foods. What would be the way to do this with prepared foods?

Depends.

 

If you want to do it from the character (a specific character triggers this function when eating any prepared food), you should attach a "oneatfn" or listen for the event "oneat". Then test in that function whether the food item meets the criteria.

 

If you want to attach the function to all prepared foods (independent of character), you could use AddPrefabPostInit to apply a listener for "oneaten". Or you could override the prefab file "preparedfoods.lua", which would affect prepared foods that get added later on too (if that will ever be the case), although that may cause incompatibility with other mods.

 


 

Source: dontstarveapi.com: Eater, Edible, Events, AddPrefabPostInit

For adding a listener for "oneaten" for prepared foods, would I use something like components.edible:SetOnEatenFn(somefunction) or would I have to use ListenForEvent? Also what would be the best way to add an additional effect when something is eaten? For example if I wanted to run another function after eating a mandrake but still want to keep the original effect without having to copy all of the original code. I was looking at some posts on the forums where they stored the old function and were able to call that, but I can't seem to get that to work.

@Daedalus451 Post your code so far and we can help you make it work as intended.

 

How to preserve functions and add your own code.

function SomeFunction()    print("hi")endlocal oldSomeFunction = SomeFunctionfunction SomeFunction()    print("123")    return oldSomeFunction() -- Also chains the return value, which isn't required in this exampleendSomeFunction() -- prints "123" and "hi"

Explained more here (see "Tables as objects").

Here is what I've been using to try to add to the mandrake's oneaten function. I can get it to run my function, but not the old one. I think that maybe i'm not storing the old functions, but I'm not sure.

local require = GLOBAL.requirelocal Mandrake = require "prefabs/mandrake"
local OldMandrakeOnEaten = Mandrake.OnEaten or function() end
local OldMandrakeOnEatenCooked = Mandrake.OnEaten_cooked or function() end

local function RespawnMandrake() local pt = GLOBAL.Vector3(GLOBAL.GetPlayer().Transform:GetWorldPosition()) local spawn_pt local theta = math.random() * 2 * math.pi local radius = 80 local offset = GLOBAL.FindWalkableOffset(pt, theta, radius, 12, true) if offset then spawn_pt = pt + offset end if spawn_pt then local mandrake = GLOBAL.SpawnPrefab("mandrake") if mandrake then mandrake.Physics:Teleport(spawn_pt:Get()) mandrake:FacePoint(pt) end end end local function OnEaten(inst, eater) RespawnMandrake() OldMandrakeOnEaten(inst, eater) end local function OnEaten_cooked(inst, eater) RespawnMandrake() OldMandrakeOnEatenCooked(inst, eater) end local function MandrakeInit(prefab) prefab.components.edible:SetOnEatenFn(OnEaten) end local function CookedMandrakeInit(prefab) prefab.components.edible:SetOnEatenFn(OnEaten_cooked) end AddPrefabPostInit("mandrake", MandrakeInit) AddPrefabPostInit("cookedmandrake", CookedMandrakeInit)

For the prepared foods like mandrake soup, I'm not sure what to add.

The code didn't come out right on the other post so here is hopefully the fixed one.

local require = GLOBAL.requirelocal Mandrake = require "prefabs/mandrake"local OldMandrakeOnEaten = Mandrake.OnEaten or function() endlocal OldMandrakeOnEatenCooked = Mandrake.OnEaten_cooked or function() endlocal function RespawnMandrake()	local pt = GLOBAL.Vector3(GLOBAL.GetPlayer().Transform:GetWorldPosition())	local spawn_pt	local theta = math.random() * 2 * math.pi	local radius = 10	local offset = GLOBAL.FindWalkableOffset(pt, theta, radius, 12, true)	if offset then		spawn_pt = pt + offset	end	if spawn_pt then		local mandrake = GLOBAL.SpawnPrefab("mandrake")		if mandrake then			mandrake.Physics:Teleport(spawn_pt:Get())			mandrake:FacePoint(pt)		end	endendlocal function OnEaten(inst, eater)	RespawnMandrake()	OldMandrakeOnEaten(inst, eater)endlocal function OnEaten_cooked(inst, eater)	RespawnMandrake()	OldMandrakeOnEatenCooked(inst, eater)endlocal function MandrakeInit(prefab)	prefab.components.edible:SetOnEatenFn(OnEaten)endlocal function CookedMandrakeInit(prefab)	prefab.components.edible:SetOnEatenFn(OnEaten_cooked)endAddPrefabPostInit("mandrake", MandrakeInit)AddPrefabPostInit("cookedmandrake", CookedMandrakeInit)

@Daedalus451

local function OnEaten(inst, eater)	-- ...endlocal function AddOnEaten(inst)	local old_oneaten = inst.components.edible.oneaten -- Preserve old fn	inst.components.edible:SetOnEatenFn(function(inst, eater) -- Set the new fn		OnEaten(inst, eater) -- In new fn, call your custom code		return old_oneaten(inst, eater) -- Then call the original and return the value	end)endAddPrefabPostInit("mandrake", AddOnEaten)AddPrefabPostInit("cookedmandrake",  AddOnEaten)

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
×
  • Create New...