Jump to content

Overriding a function of a component


Recommended Posts

@Ultroman Have you tried AddComponentPostInit?

 

I skimmed over your code and noticed that you're using "self", but the parameter isn't being received anywhere. The outer function takes in "inst" as its first param.

The self variable is auto-implemented when using colons, which is not the case here.

Link to comment
Share on other sites

@Blueberrys

Thanks for your response.

 

I wanted to get around using AddComponentPostInit, because I only want to change one method for all player characters, and not necessarily change the method of the actual component, as it might be used for other entities than players.

 

I think I may have asked my question in a more complicated way than I could, but I'm not able to edit my post yet.

 

What I want to do, is to replace the function Sanity:Recalc(dt) inside sanity.lua with my own function. I'm sure that the replacing is actually working, as the method stops working entirely when I enable my mod.

 

What I'm trying is (very cut down):

local function myfunction(dt)    -- Copied the code from the original Sanity:Recalc(dt) function declaration in sanity.lua.    -- The original code uses self (as indicated by the colon in the declaration), and easing    -- which is loaded/required inside the original sanity.lua outside the function.endlocal function ChangeSanity(inst)    inst.components.sanity.Recalc = myfunctionendAddPrefabPostInit("world", function(inst) --this makes sure it loads after other mods add characters    for k,v in pairs(GLOBAL.DST_CHARACTERLIST) do        AddPrefabPostInit(v, ChangeSanity)    end    for k,v in pairs(GLOBAL.MODCHARACTERLIST) do        AddPrefabPostInit(v, ChangeSanity)    endend)

As stated, I've now simply copied the original code, and am trying to get Recalc to work normally, when replaced with my copied function. After that, I plan to edit it, but for now, I just want the actual replacing to not break the method.

 

I have tried this instead:

local Sanity = require("components/sanity")local function Sanity:myfunction(dt)    -- Copied the code from the original Sanity:Recalc(dt) function declaration in sanity.lua.    -- The original code uses self (as indicated by the colon in the declaration) and easing,    -- which is loaded/required inside the original sanity.lua.end

but it tells me that instead of the colon, it expected a (.

 

I have also tried this:

local function ChangeSanity(inst)    inst.components.sanity.Sanity:Recalc = myfunctionend

but that also gives me an error.

 

So my questions are:

- How do I correctly replace this function inside sanity.lua, so the self-variable used in the original code, works in my copied function?

 

- I thought that replacing it, would make it "load into" the original component, so that easing and such still worked, as they are defined in the original component. Is that not true? Or does it tell the sanity-component to go use the function in my modmain.lua instead? And if the latter, do I have to define the easing using require outside the function? What about all the other references to other components?

 

- Am I still going to be able to use my mod-variables inside the function?

Link to comment
Share on other sites

@Ultroman

 

The colon syntax applies the "self" variable automatically, both when declaring a function and when calling it.

For example,

function Obj:some_fn()    -- self is received as first param    -- Calling Obj.some_fn(1) will pass "1" as "self"    -- print(self) would print 1end-- ...Obj:some_fn()-- Passes in "Obj" as the first param.-- Since some_fn accounts for it above, it will be seen internally as "self".

-

 

You can not use the "local" keyword when defining children functions, it just doesn't make sense.

Obj = {}-- Valid-- Defining "some_fn" as a child of "Obj", with automatic self variablefunction Obj:some_fn()    -- ...end-- Invalid-- Here, you're just saying "make a local function called "Obj:some_fn"-- You can't do that cause function names can't contain a colonlocal function Obj:some_fn()    -- ...end-- Also Invalid, same reasonlocal function Obj.some_fn()    -- ...end

-

 

 

How do I correctly replace this function inside sanity.lua, so the self-variable used in the original code, works in my copied function?
 

Using your first approach, "myfunction" should look like this:

local function myfunction(self, dt)    -- ...end

Second approach, it should be like this:

-- require sanity...function Sanity:myfunction(dt)    -- ...end

-

 

I thought that replacing it, would make it "load into" the original component, so that easing and such still worked, as they are defined in the original component. Is that not true? Or does it tell the sanity-component to go use the function in my modmain.lua instead? And if the latter, do I have to define the easing using require outside the function? What about all the other references to other components?

When you replace the function externally, it will simply override the reference. When the code comes to a point that it tries to access "sanity.Recalc", it will refer to your function instead of that one. The previous function can be considered "discarded". (That actually depends on whether there are any references to it remaining, but it certainly won't be used through this reference)

 

Am I still going to be able to use my mod-variables inside the function?

You have access to the variables in your script as usual, and you may access the variables passed into the function through the component, such as "self".

More on scope in lua.

 

 

Also, why not use AddPlayerPostInit instead of looping all the characters?

local function fn(player_inst)    -- ...endAddPlayerPostInit(fn)
Link to comment
Share on other sites

specifically:

-- thislocal function getfunky() print("no") end-- is actually thislocal getfunky = function() print("no") end-- and thisfunction Banana:Peel() ..... end-- is actually thisBanana.Peel = function(self) ..... end

 
 
When you use the word "local", you are saying "a variable that can be used only by the function its in*, and any functions that are defined inside of it.
 
Every function has what's called a local environment which is a table that contains all of its local variables.  When you declare a local variable, you are adding it to that table.  When you use colon syntax, like function Banana:Peel, you are specifically telling Lua to add the variable with the function to the Banana table, rather than the local environment table.
 
 
 *or only used by the file its in, if used outside of a function

 

Edit: I got 99 problems, and proper capitalization is one

 

Edit 2: I feel like it's necessary to mention that this is not 100% technically accurate.  The environment is a different beast than the scope, but this explanation should suffice on the the path to learning all that.

Link to comment
Share on other sites

@Blueberrys and Corrosive

Wow, that is a lot of valuable insight! Thank you very much, both of you.

 

Also, why not use AddPlayerPostInit instead of looping all the characters?

local function fn(player_inst)    -- ...endAddPlayerPostInit(fn)

 

I am still missing one piece of vital information:

What do I write inside the local function (fn), to make it replace the Recalc function of the player's sanity-component, with my function? Like this?:

local function myfunction(self, dt)    -- all the code from the original Recalc functionendlocal function fn(player_inst)    player_inst.components.sanity.Recalc = myfunctionendAddPlayerPostInit(fn)

As it is atm...

-- require sanity... function Sanity:myfunction(dt)    -- all the code from the original Recalc functionend

...if I'm not mistaken, this simply overwrites the function in the overall sanity-component of the person enabling the mod, which requires all players to download the mod for it to work.

Link to comment
Share on other sites

@Blueberrys and Corrosive

Wow, that is a lot of valuable insight! Thank you very much, both of you.

 

I am still missing one piece of vital information:

What do I write inside the local function (fn), to make it replace the Recalc function of the player's sanity-component, with my function? Like this?:

local function myfunction(self, dt)    -- all the code from the original Recalc functionendlocal function fn(player_inst)    player_inst.component.sanity.Recalc = myfunctionendAddPlayerPostInit(fn)

As it is atm...

-- require sanity... function Sanity:myfunction(dt)    -- all the code from the original Recalc functionend

...if I'm not mistaken, this simply overwrites the function in the overall sanity-component of the person enabling the mod, which requires all players to download the mod for it to work.

 

You can do it like that (I think, not sure about Together), but if you only want to add something independent from the other stuff, consider this:

 

local oldfn = player_inst.component.sanity.Recalc --remember the old function

 

player_inst.component.sanity.Recalc = function(...) --make a new function, which...

  oldfn(...) --does all the old stuff...

  myfunction(...) --and my stuff.

end

Link to comment
Share on other sites

Thanks for your response, Mobbstar.

 

I'm wanting to make a lot of changes in the original code (after I make it work normally with the original code being replaced by my function, which for now contains the original code), so simply extending the function doesn't really make sense to me.

 

I'll try the approach you say should work, and report back.

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