RED4ext.SDK icon indicating copy to clipboard operation
RED4ext.SDK copied to clipboard

Reverse engineering the scripting events

Open WopsS opened this issue 2 years ago • 1 comments

Is your feature request related to a problem? Please describe. Currently there is no method to hook game event's gamePuppet::OnDamageReceived, gamePuppet::OnHit, etc..

Describe the solution you'd like The best solution would be to reverse and hook into events natively, without additional dependencies, allowing modders to hook these function from C++.

Describe alternatives you've considered An alternative to this would be to do like yamashi did it for Cyber Engine Tweaks, but that would require to have additional libraries added as dependencies for the SDK which I would not like to. If there is no other solution than this, a plugin API can be added so that the main loader can take care of hooking.

WopsS avatar Aug 23 '21 18:08 WopsS

There are 3 kinds of events / callbacks:

  1. Based on method name To catch the event you just have to define function with the right signature and name. It's called by name just like any other function. For example, OnInitialize() in widgets controllers. Since it's literally just the function with the right name, there can't be more than one listener function.
  2. Based on event classes inherited from redEvent To catch such event you have to define function that takes exactly one argument of the type of the event class and has isEvent flag. It's auto wired during initialization. For example, OnHit(evt : handle:gameeventsHitEvent). It can be triggered using method target.QueueEvent(evt).
  3. Callback managers Different types have their own functions to register and unregister listeners. The signature of the listener is always fixed and different for different events. You just have to know it from examples. So to catch the event you have to define a listener function and later call some Register() function on callback manager giving it the name of your callback function and the target object to call that function on. For example, a method to register listener for blackboard RegisterListenerBool(id : gamebbScriptID_Bool, object : handle:IScriptable, func : CName, fireIfValueExist : Bool). I think this is the type based on native callbacks, they store Callback<T> instances (wrapping target object with the method named) and then invoke them.

psiberx avatar Aug 22 '22 21:08 psiberx