It is generally advisable to useObserve whenever possible, and only use Override when absolutely necessary
Override is a built-in CET function allowing developers to rewrite a game's class method. It must be registered using the Override() function inside the onInit event, in the init.lua file.
The provided callback is always filled as follows:
The first argument is the current object that execute the method. This argument is not present when function/method is static.
Others arguments passed to the targeted method, if any.
The last argument is the original callable method.
You can now generate Override using NativeDB. You need to configure option Clipboard syntax to Lua. You can click on the "copy" button of a function, pick Copy Override and it will copy the code in your clipboard.
Definition
Override(className, method, callback)
---- Override()---- @param string className The parent class name-- @param string method The method name to target-- @param function callback The callback function--Override('className', 'method', function(self [, arg1, arg2, ...], wrappedMethod)-- rewrite method()end)
If you override a static function, you must define the field 'method' with the full name of the function. Otherwise it won't work. You can find the full name using NativeDB. See a similar example with Observe.
When applying Override(), the callback would be filled with the following arguments:
Override('AimingStateEvents', 'OnEnter', function(self,stateContext,scriptInterface,wrappedMethod)-- self the 'AimingStateEvents' object-- stateContext the original method first argument-- scriptInterface the original method second argument-- wrappedMethod the original 'OnEnter' callable methodend)
The self and wrappedMethod parameters can be renamed at your convenience:
_
this
class
method
whatever
Using Wrapped Method
The last argument of the Override() function, wrappedMethod, contains the original method as a callable function. We can use it to execute the original code and/or retrieve its result (if it returns something).
It is highly recommended to know the overriden method return statement to avoid breaking the script, and use wrappedMethod accordingly.
Method -> Void
Any method declared void doesn't return a value. Overriding it follow the same logic:
Override('CrouchDecisions', 'OnStatusEffectApplied', function(self,statusEffect,wrappedMethod)-- execute original code wrappedMethod(statusEffect)-- do somethingend)
Method -> Bool / Int / Float etc...
The same logic is applied to methods with a specific return statement. Overriding it must return a compatible type:
Override('CrouchDecisions', 'OnControllingDeviceChange', function(self,value,wrappedMethod)-- execute & retrieve original codelocal result = wrappedMethod(value)-- check our conditionif condition thenreturn result -- return original codeelsereturnfalse-- return falseendend)
It is not required to execute the original code using wrappedMethod. This can be omitted, but it exposes the script to malfunctions if not handled properly.
Usage Example
Do not allow the player to crouch:
init.lua
-- onInitregisterForEvent('onInit', function()-- observe CrouchDecisions EnterCondition state Override('CrouchDecisions', 'EnterCondition', function(self,stateContext,scriptInterface,wrappedMethod)returnfalseend)end)
Advanced Example
Do not allow the player to crouch if in ADS:
init.lua
-- set initial varsisADS =false-- onInitregisterForEvent('onInit', function()-- observe ADS OnEnter state Observe('AimingStateEvents', 'OnEnter', function(self,stateContext,scriptInterface) isADS =trueend)-- observe ADS OnExit state Observe('AimingStateEvents', 'OnExit', function(self,stateContext,scriptInterface) isADS =false-- reset conditionend)-- observe CrouchDecisions EnterCondition state Override('CrouchDecisions', 'EnterCondition', function(self,stateContext,scriptInterface,wrappedMethod)-- retrieve original code resultlocal result = wrappedMethod(stateContext, scriptInterface)-- check ADS stateif isADS thenreturnfalse-- disallow crouchend-- otherwise return original logicreturn resultend)end)