Skip to content

Critical Hits

szapp edited this page Oct 12, 2019 · 12 revisions

The feature Critical Hits (GFA_CRITICALHITS) implements critical hits for ranged weapons. The customization allows to change the damage output depending on which body part was hit. Furthermore, the damage behavior of projectiles can be altered. For example, projectiles can be set to never kill, but always only knockout a certain enemy.

On projectile collision and positive hit registration with an NPC, a "config function" is called (GFA_GetCriticalHit). In this function, based on the hit NPC, the bone (body part) that was hit, the weapon used, the damage, etc., you may alter the damage of the shot (the base damage of the weapon, not the final, applied damage).
Originally, this was implemented to allow critical hits (e.g. head shots). However, the possibilities go beyond that, as any body part may change the damage or trigger other events.

This differs, if free aiming for ranged weapons is not activated (e.g. disabled in the game menu, or when playing with keyboard controls only). If that is the case, the shot cannot be checked for a specific bone of the model and a different config function is called instead (GFA_GetCriticalHitAutoAim). This function is essentially the same as the one described above, but without a bone. Instead, you may work with probabilities to achieve similar mechanics.

Keep in mind, that you should always adjust both of these alternatives, because there are players that prefer to play the game keyboard-only or others who might not like free aiming (boring!).

Additionally, the config functions may not only alter the damage value, but also its behavior. This damage behavior defines things like prevention of killing a target or performing instant (one-shot) kills or knockouts and allowing for interesting weapon features (e.g. a "knockout bow" for thieves).

Note, that the damage behavior is not compatible with custom damage calculation, like this. If using different damage calculation, you should always leave the damage behavior set to DMG_NO_CHANGE, otherwise strange side-effects may occur, concerning the damage dealt.

 

Contents

1.   Damage Message Class
2.   Config Functions
    2.1.   GFA_GetCriticalHit
    2.2.   GFA_GetCriticalHitAutoAim


Damage Message Class

To alter the damage of a shot an instance of the class DmgMsg is provided to the config functions whose properties can be adjusted.

class DmgMsg {
    var int value;      // Base damage (float)
    var int type;       // Damage type (read-only)
    var int protection; // Protection of target NPC against DmgMsg.type (read-only)
    var int behavior;   // Damage behavior as defined below (DMG_*)
    var string info;    // Optional debug information
};

The available damage behaviors are:

DMG_NO_CHANGE Do not change anything. Default
DMG_DO_NOT_KNOCKOUT Normal damage, shot may kill but never knockout (HP ≠ 1).
DMG_DO_NOT_KILL Normal damage, shot may knockout but never kill (HP > 0).
DMG_INSTANT_KNOCKOUT One-shot knockout (1 HP).
DMG_INSTANT_KILL One-shot kill (0 HP).

Config Functions

The configuration of this feature is found in the file config/criticalHit.d.

GFA_GetCriticalHit

This function is called every time (any kind of) NPC is hit by a projectile (arrows and bolts). Originally it was meant to design critical hits based on a specific bone of the model, but it can also be used to change the damage (or to trigger any other kind of special events) based on any bone of the model that was hit. Additionally, it allows to specify a "damage behavior". The damage behavior defines how much damage is eventually applied to the victim. This allows, e.g. to prevent a victim from dying, and instead knock it out with one shot (see examples in function).

The global variable GFA_ProjectilePtr will contain the pointer to the projectile (oCItem) in question for the duration of the function. Outside of the function this variable will always be reset to zero.

Note: This function is specific to active free aiming. For critical hits without free aiming see GFA_GetCriticalHitAutoAim below.

Ideas: incorporate weapon-specific stats, head shot talent, special knockout munition, dependency on target, ...
Examples are given inside the function, but commented out to serve as inspiration of what is possible.
By default, critical hits for all Gothic 1 and Gothic 2 monsters are defined as head shots.

func void GFA_GetCriticalHit(C_Npc target, string bone, C_Item weapon, int talent, int dmgMsgPtr)
target The NPC that is hit by the projectile.
bone The model node that was hit (e.g. "BIP01 HEAD").
weapon The ranged weapon of the player (might be empty if unequipped immediately!).
talent The talent value of the player depending on the ranged weapon.
dmgMsgPtr Instance pointer to the damage message.

 

GFA_GetCriticalHitAutoAim

This function is analogous to GFA_GetCriticalHit above, but is called when free aiming for ranged weapons is not active.

The global variable GFA_ProjectilePtr will contain the pointer to the projectile (oCItem) in question for the duration of the function. Outside of the function this variable will always be reset to zero.

Note: This function would not be necessary for Gothic 1, as it already has critical hits for auto aiming by default. Nevertheless, the original critical hit calculation of Gothic 1 is disabled and replaced by this function. This way, the critical hit chance can be manipulated if desired. The lines of code below for Gothic 1 are the same as default behavior of Gothic 1.

Ideas: scale critical hit chance with player skill and distance, ...
Examples are given inside the function (section of Gothic 2), but commented out to serve as inspiration of what is possible.

func void GFA_GetCriticalHitAutoAim(C_Npc target, C_Item weapon, int talent, int dmgMsgPtr)
target The NPC that is hit by the projectile.
weapon The ranged weapon of the player (might be empty if unequipped immediately!).
talent The talent value of the player depending on the ranged weapon.
dmgMsgPtr Instance pointer to the damage message.