Luahh Posted May 24, 2018 Share Posted May 24, 2018 (edited) Hey, i'm trying to create a function that will run when a specified food is eaten. I know that there was been at least one post on this in the past, but it's hard to figure out how to format it, due to the way it's written so some help would be appreciated. this was their code just some help breaking it up and maybe explaining it would help 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) Edited May 24, 2018 by Luahh Link to comment Share on other sites More sharing options...
CarlZalph Posted May 24, 2018 Share Posted May 24, 2018 4 hours ago, Luahh said: Hey, i'm trying to create a function that will run when a specified food is eaten. I know that there was been at least one post on this in the past, but it's hard to figure out how to format it, due to the way it's written so some help would be appreciated. this was their code just some help breaking it up and maybe explaining it would help Formatted: local function OnEaten(inst, eater) -- ... end local 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 ) end AddPrefabPostInit( "mandrake", AddOnEaten ) AddPrefabPostInit( "cookedmandrake", AddOnEaten ) Only complicated bit is the function hooking part. In lua you can easily hook any existing function you have access to by replacing the original with a new one after storing the old. In this case the user had made a prehook, which is to say their code is to be ran before the old code. A post hook would look: local function OnEaten(inst, eater, returnvalue) -- ... return returnvalue end local function AddOnEaten(inst) local old_oneaten = inst.components.edible.oneaten -- Preserve old fn inst.components.edible:SetOnEatenFn( function(inst, eater) -- Set the new fn local returnvalue = old_oneaten(inst, eater) returnvalue = OnEaten(inst, eater, returnvalue) return returnvalue end ) end AddPrefabPostInit( "mandrake", AddOnEaten ) AddPrefabPostInit( "cookedmandrake", AddOnEaten ) Which lets you use the return value from the old function in your new function to apply any further changes if need be. Link to comment Share on other sites More sharing options...
Luahh Posted May 24, 2018 Author Share Posted May 24, 2018 (edited) 1 hour ago, CarlZalph said: Formatted: local function OnEaten(inst, eater) -- ... end local 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 ) end AddPrefabPostInit( "mandrake", AddOnEaten ) AddPrefabPostInit( "cookedmandrake", AddOnEaten ) Only complicated bit is the function hooking part. In lua you can easily hook any existing function you have access to by replacing the original with a new one after storing the old. In this case the user had made a prehook, which is to say their code is to be ran before the old code. A post hook would look: local function OnEaten(inst, eater, returnvalue) -- ... return returnvalue end local function AddOnEaten(inst) local old_oneaten = inst.components.edible.oneaten -- Preserve old fn inst.components.edible:SetOnEatenFn( function(inst, eater) -- Set the new fn local returnvalue = old_oneaten(inst, eater) returnvalue = OnEaten(inst, eater, returnvalue) return returnvalue end ) end AddPrefabPostInit( "mandrake", AddOnEaten ) AddPrefabPostInit( "cookedmandrake", AddOnEaten ) Which lets you use the return value from the old function in your new function to apply any further changes if need be. Thanks a ton for the help and I know you didn't mean to necessarily help me get this working but any ideas why this crashes my game? I changed the prefab in the AddPrefabPostInit to berries and everytime I eat a berry it crashes my game with the error message: "attempt to call upvalue 'old_oneaten' (a nil value). also i'm assuming this is supposed to be in my modmain.lua since AddPrefabPostInit doesn't work inside of a prefab file. EDIT: Got this working, after just adding this statement. if old_oneaten ~= nil then return old_oneaten(inst, eater) -- Then call the original and return the value end Thanks a ton for the help! Luah. Edited May 24, 2018 by Luahh Solved Link to comment Share on other sites More sharing options...
CarlZalph Posted May 24, 2018 Share Posted May 24, 2018 6 hours ago, Luahh said: EDIT: Got this working, after just adding this statement. if old_oneaten ~= nil then return old_oneaten(inst, eater) -- Then call the original and return the value end Thanks a ton for the help! Luah. This is a correct way to do this. Another way is to provide a blank function template if the old function doesn't exist: local old_oneaten = inst.components.edible.oneaten or function(...) return somethinghere end Where 'somethinghere' is an expected valid return result from an expected function that you're trying to hook. You could also replace the '...' with valid argument names if you know expected argument names for use with this blank function template. Link to comment Share on other sites More sharing options...
Luahh Posted May 24, 2018 Author Share Posted May 24, 2018 1 hour ago, CarlZalph said: This is a correct way to do this. Another way is to provide a blank function template if the old function doesn't exist: local old_oneaten = inst.components.edible.oneaten or function(...) return somethinghere end Where 'somethinghere' is an expected valid return result from an expected function that you're trying to hook. You could also replace the '...' with valid argument names if you know expected argument names for use with this blank function template. Are there any advantages to doing it this way? although I haven't tested it much, the way I have it right now works perfectly fine for me. Link to comment Share on other sites More sharing options...
CarlZalph Posted May 24, 2018 Share Posted May 24, 2018 (edited) 5 minutes ago, Luahh said: Are there any advantages to doing it this way? although I haven't tested it much, the way I have it right now works perfectly fine for me. It can help reduce building an indentation pyramid in your code, but nothing really major. Just an alternative style. Edited May 24, 2018 by CarlZalph 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