Jump to content

Running a function after eating food


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?

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

@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").

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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)
Link to comment
Share on other sites

@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)
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...