Community Forum

Can I override a general function without breaking other mods?

Forum Overview >> Farming Simulator 17

CategoryFarming Simulator 17
Created30.01.2017 18:02

Tim Derks (timmiej93) 30.01.2017 19:03
For my mod, I need to override the "setIsFilling()" method from the fillable specialization.
I have now done this by simply putting the following code in my lua file:

function Fillable:setIsFilling(isFilling, noEventSend)
-- do Stuff

If I understand correctly, this overrides the "setIsFilling()" function for ALL fillables. So no matter what, if any fillable tries to fill something, even when my mod isn't even placed on the map.
As long as my mod is the only one that overrides this function, I think there won't be any problems (it implements the default behavior as well), but as soon as there is another mod that overrides this function, I think both mods won't work.
Is there a way to properly override this function, so that it will only get used when a fillable is filling from my mod, and otherwise uses the default (or other mod's) function?

Bilbo Beutlin (BBeutlin) 31.01.2017 01:39
You should NEVER do that.

I'm astonished anyway, that your method by re-defining a function works properly. The LUA parser should give a syntax error in the style "function declared multiple". IIRC so it did really in FS15.

In many mods one finds also hard assignments in the style "default:function1 = myMod:function2". However this works apparently, it works only for your configuration.
Another mod does a similiar and you are wondering why your or the mod function doesn't work anymore.
There's also a risk, that a patch introduces a new method and it doesn't work anymore.

Use the appended- or overwrittenFunction() style for compatibilty.

Tim Derks (timmiej93) 31.01.2017 15:25
"Another mod does a similiar and you are wondering why your or the mod function doesn't work anymore."
That's exactly why I'm asking about this. I really want to prevent this.
Could you explain to me how the overwrittenFunction() style works? I haven't found any documentation on them, and never seen anyone use them before.


Alright, I did some experimenting, and it works. Not sure if it is proper, so I'll let you guys be the judge of that. My code is below (with a link to pastebin for easier reading), could anyone please tell me if this is the correct way of doing this?

myMod = {}
function myMod:func1()

function myMod:func2()

function custom_FillableSetIsFilling(self, superFunc, isFilling, noEventSend)
-- check if is filling from my mod or from default trigger
if (fillingFromCustomTrigger) then
-- do custom stuff
if superFunc ~= nil then
superFunc(self, isFilling, noEventSend)

Pastebin link:
(exactly the same, but highlighted, for convenience)

Bilbo Beutlin (BBeutlin) 31.01.2017 20:08
In the vehicle spec LUAs you'll find many examples for usage of "Utils.overwrittenFunction()", "Utils.appendedFunction()" and also for "superFunc()".

Then keep in mind, you should use only function names you declared earlier with "myMod = {}".
Means, instead "function custom_FillableSetIsFilling()" you should use "myMod:functionXYZ()". First for better style, readability and debugging. Second function declaration without specifier are meant for global system functions. You can never be sure, that it isn't perhaps used by a later enhancement/patch.

Tim Derks (timmiej93) 31.01.2017 21:03
Well that's exactly where I run into issues. When I place

"Fillable.setIsFilling = Utils.overwrittenFunction(Fillable.setIsFilling, self.custom_FillableSetIsFilling);"

in my myMod:load() function, and

"function myMod:custom_FillableSetIsFilling(fillable, superFunc, isFilling, noEventSend)"

a bit further down, I start getting random errors which make absolutely no sense. Am I doing this wrong then?
Do I have to place the "Fillable.setIsFilling = Utils.overwrittenFunction(Fillable.setIsFilling, self.custom_FillableSetIsFilling);" section outside of all functions?


After a lot of fiddling around, I found something that works and is probably correct (but please correct me if it isn't)

Instead of the above, I now have

"function myMod:custom_FillableSetIsFilling(superFunc, isFilling, noEventSend)" (fillable removed, since now self gets passed implicitly again, don't know why)

I also removed

"Fillable.setIsFilling = Utils.overwrittenFunction(Fillable.setIsFilling, self.custom_FillableSetIsFilling);"

from myMod:load(), and placed it at the very end of my Lua file. This seems to be working now. Is it correct?

Bilbo Beutlin (BBeutlin) 31.01.2017 23:02
I have always used something like:
defaultLua.function = Utils.overwrittenFunction(defaultLua.function, myMod.myFunction);
and placed it in the myMod:load() section.

But yes, you can also place it somewhere at end of your LUA outside any function, since the global code is executed at the very first run.
In any case you should avoid the "self" construct. The "self" is only valid under certain circumstances.

Note: Log in to post. Create a new account here.