How to create a hook
Examples of creating hooks
Created by HJHughJanus on github, copied here for easier maintainability.
Example
Goal: Ragdoll any NPC hit by a bullet. System: I need to find out how Cyberpunk 2077 handles bullets and damage → a look through the decompiled game scripts shows there is a class called „DamageSystem“. This class looked up on Cyberdoc shows there is a function wihtin that class called „ProcessLocalizedDamage“. Back in the decompiled game scripts the code of this function seems to handle a „hit event“ and checking if the bullet hit the head or any weak spots. That is very close to my goal, so I will use this function for the hook. Functions: I want to ragdoll an NPC, so I will need a function to do that. I search on Cyberdoc for „ragdoll“ and find something called „ApplyRagdollImpulseEvent“. I search this function in the decompiled game scripts to find out how it is used.
First, I need to specify which system I want to use for injection, then specify the function.
@wrapMethod(DamageSystem)
private func ProcessLocalizedDamage(hitEvent: ref<gameHitEvent>) {
}In this function I must now call the vanilla function first, so I don‘t overwrite any of the vanilla action – you can do this via the function wrappedMethod(params) (this one automatically calls the vanilla function).
@wrapMethod(DamageSystem)
private func ProcessLocalizedDamage(hitEvent: ref<gameHitEvent>) {
wrappedMethod(hitEvent);
}Then I copy some code from the vanilla function to handle some errors and set up my variables.
@wrapMethod(DamageSystem)
private func ProcessLocalizedDamage(hitEvent: ref<gameHitEvent>) {
wrappedMethod(hitEvent);
//variables
let hitUserData: ref<HitShapeUserDataBase>;
let hitShapes: array<HitShapeData> = hitEvent.hitRepresentationResult.hitShapes;
//error handling and setting up hitUserData (copy & paste from original)
if !hitEvent.attackData.GetInstigator().IsPlayer() {
return;
};
if AttackData.IsAreaOfEffect(hitEvent.attackData.GetAttackType()) {
return;
};
if ArraySize(hitShapes) > 0 {
hitUserData = DamageSystemHelper.GetHitShapeUserDataBase(hitShapes[0]);
};
if !IsDefined(hitUserData) {
return;
};
}
Now my actual code can take effect. Since I found the „ApplyRagdollImpulseEvent“ and looked up how it is used, I know this will not be done in one line. So, to keep the code in the wrapper function simple, I will write a separate function below which sets up the ragdolling for me.
Now my actual code can take effect. Since I found the „ApplyRagdollImpulseEvent“ and looked up how it is used, I know this will not be done in one line. So, to keep the code in the wrapper function simple, I will write a separate function below which sets up the ragdolling for me.
The whole file now looks like this:
This file I save and then put into D:\PATH\TO\CYBERPUNK2077\r6\scripts so the game will load it.
When I start the game, every NPC hit by a bullet should be ragdolled with a push.
Where to go next?
Understand what kind hooks are available:
Hook AnnotationsFind what to hook:
Things to hookLast updated