damage_effect

The damage effect tag determines the results of damage application in a wide range of use cases, including but not limited to: projectile impacts, detonations, melee attacks, falling, and vehicle collisions. They can be part of an effect.

A damage effect is not strictly about applying shield and health damage to units; these tags can have an area of effect, impart acceleration on additional objects like items and projectiles too, and cause screen effects like colour flashes and shaking.

Bleedthrough #

When damage to shields exceeds the currently shield vitality, damage carries over to health. When this occurs, the damage multiplier of the shields still carries over to the health damage. This even occurs if the current shield vitality is 0. The result is that the initial carryover health damage may be higher than expected with weapons like the plasma rifle, which have a 2x shield multiplier. Subsequent shots will impact the body and use its material type modifiers instead.

Impact damage formula #

When applying a damage_effect as a projectile impact, the game may take projectile fields into account as well. When air or water damage ranges are set, the projectile's travel distance will scale damage between damage lower bound and a random selection between upper bounds. If air damage range is not set, it always uses the random high bound.

Firstly, the game randomly picks a value between the two upper bounds (will always be the same if both values are the same). Up to the projectile minimum air damage range, 100% unmodified damage is applied. However, past the minimum and up to the maximum damage ranges, damage linearly scales to the lower bound. Past this distance, the projectile disappears (but does not detonate).

In pseudocode, and assuming within max range:

//falloff is 0 to 1 based on travel distance between air damage ranges
let falloff = max(0,
  (travel_distance - air_damage_min) /
  (air_damage_max - air_damage_min)
);

//given a random_value between 0 and 1, interpolate between the two high bounds
let upper_bound_delta = upper_bound_2 - upper_bound_1;
let random_upper_bound = upper_bound_1 + random_value * upper_bound_delta;

//interpolate between lower and random upper bound
let raw_damage = (
  falloff * lower_bound +
  (1.0 - falloff) * random_upper_bound
);
//finally, damage is scaled by the multiplier for the impacted material
let damage_done = material_damage_multiplier * raw_damage;

Structure and fields #

Field Type Comments
radius f32 (world units) (min & max)

The minimum radius determines the sphere in which damage is 100% of damage upper bound. Damage fades linearly to damage lower bound at the maximum radius. Outside the maximum radius, 0 damage is dealt. The aoe core radius field does not affect this calculation.

cutoff scale f32
  • Maximum: 1
flags bitfield(32)
Flag Mask Comments
do not scale damage by distance 0x1
pad(16)
pad(4)
type enum
Option Value Comments
none 0x0
lighten 0x1
darken 0x2
max 0x3
min 0x4
invert 0x5
tint 0x6
priority enum
Option Value Comments
low 0x0
medium 0x1
high 0x2
pad(8)
pad(4)
duration f32 (seconds)
fade function enum
Option Value Comments
linear 0x0
early 0x1
very early 0x2
late 0x3
very late 0x4
cosine 0x5
pad(2)
pad(4)
pad(4)
maximum intensity f32
  • Maximum: 1
pad(4)
color
ColorARGB
  • alpha: f32
  • red: f32
  • green: f32
  • blue: f32
low frequency vibrate frequency f32
  • Maximum: 1
low frequency vibrate duration f32 (seconds)
low frequency vibrate fade function enum
Option Value Comments
linear 0x0
early 0x1
very early 0x2
late 0x3
very late 0x4
cosine 0x5
pad(2)
pad(8)
high frequency vibrate frequency f32
  • Maximum: 1
high frequency vibrate duration f32 (seconds)
high frequency vibrate fade function enum
Option Value Comments
linear 0x0
early 0x1
very early 0x2
late 0x3
very late 0x4
cosine 0x5
pad(2)
pad(4)
pad(16)
pad(8)
temporary camera impulse duration f32 (seconds)
temporary camera impulse fade function enum
Option Value Comments
linear 0x0
early 0x1
very early 0x2
late 0x3
very late 0x4
cosine 0x5
pad(2)
temporary camera impulse rotation Angle: f32
temporary camera impulse pushback f32 (world units)
jitter f32 (world units) (min & max)
pad(8)
permanent camera impulse angle Angle: f32
pad(4)
pad(12)
camera shaking duration f32 (seconds)

Controls how long camera shaking lasts. On PC, short camera shakes (0.05) get skipped occasionally at high FPS since this feature is still tied to frame rate. This is fixed and interpolated by Chimera.

camera shaking falloff function enum
Option Value Comments
linear 0x0
early 0x1
very early 0x2
late 0x3
very late 0x4
cosine 0x5
pad(2)
camera shaking random translation f32 (world units)
camera shaking random rotation Angle: f32
pad(4)
pad(8)
camera shaking wobble function enum
Option Value Comments
one 0x0
zero 0x1
cosine 0x2
cosine variable period 0x3
diagonal wave 0x4
diagonal wave variable period 0x5
slide 0x6
slide variable period 0x7
noise 0x8
jitter 0x9
wander 0xa
spark 0xb
pad(2)
camera shaking wobble period f32 (seconds)
camera shaking wobble weight f32
pad(12)
pad(16)
pad(4)
pad(108)
pad(4)
breaking effect forward velocity f32 (world units per second)
breaking effect forward radius f32 (world units)
breaking effect forward exponent f32
pad(4)
pad(8)
breaking effect outward velocity f32 (world units per second)
breaking effect outward radius f32 (world units)
breaking effect outward exponent f32
pad(8)
pad(4)
damage side effect enum
Option Value Comments
none 0x0
harmless 0x1
lethal to the unsuspecting 0x2
emp 0x3
damage category enum
Option Value Comments
none 0x0
falling 0x1
bullet 0x2
grenade 0x3
high explosive 0x4
sniper 0x5
melee 0x6
flame 0x7
mounted weapon 0x8
vehicle 0x9
plasma 0xa
needle 0xb
shotgun 0xc
damage flags bitfield(32)
Flag Mask Comments
does not hurt owner 0x1
can cause headshots 0x2

If enabled, any headshot against an unshielded enemy will kill it regardless of the amount of damage inflicted. Even a 1-damage pistol still instantly kills a Hunter because of this flag. It is an instant kill even if the shield threshold is met with a headshot (after shields have been reduced to 0 by the damage effect but health is full). For example, even though the pistol deals 25 damage and players have 75 shield vitality, if the final shot is a headshot the player dies. Although there is also a can cause multiplayer headshots flag, it has a separate meaning and this flag applies to both SP and MP.

pings resistant units 0x4
does not hurt friends 0x8
does not ping units 0x10
detonates explosives 0x20

If enabled, causes the effect to trigger the explosion of dropped grenades within its radius, used for explosion chaining. This only applies to maps loaded in singleplayer mode. Note that the item receiving damage (e.g. the grenade equipment) must also have its destroyed by explosions flag enabled. If the grenade has been placed within the scenario in Sapien, the does accelerate flag will also need to be checked in the properties window.

only hurts shields 0x40
causes flaming death 0x80
damage indicators always point down 0x100
skips shields 0x200
only hurts one infection form 0x400
can cause multiplayer headshots 0x800

Applies a 2x damage multiplier to headshots in multiplayer (based on how the map was loaded, not scenario type). This multiplier stacks with material modifiers below, so for example a cyborg armor modifier of 2 with this flag enabled results in a 4x headshot damage modifier.

infection form pop 0x1000
damage aoe core radius f32 (world units)

Objects within this radius will be damaged regardless of obstructions in the BSP. Outside this radius, there must be a line of sight between the effect and target. Contrary to the Guerilla tooltip, this field does not determine if the damage has an area of effect; see radius.

damage lower bound f32

Sets the minimum amount of damage done when this effect is applied in a scaled way. For example, projectiles can have min and max damage ranges for air and water.

damage upper bound from f32

Maximum damage will be randomly chosen between this value and the next.

damage upper bound to f32

If set to the same value as the previous field, max damage will be the same every time. Otherwise, a random value is chosen between upper bounds.

damage vehicle passthrough penalty f32
damage active camouflage damage f32
damage stun f32
  • Maximum: 1
damage maximum stun f32
  • Maximum: 1
damage stun time f32 (seconds)
pad(4)
damage instantaneous acceleration f32

Controls how much moveable objects are accelerated by this effect. This is scaled by the acceleration scale field of object.

pad(8)
dirt f32
sand f32
stone f32
snow f32
wood f32
metal hollow f32
metal thin f32
metal thick f32
rubber f32
glass f32
force field f32
grunt f32
hunter armor f32
hunter skin f32
elite f32
jackal f32
jackal energy shield f32
engineer skin f32
engineer force field f32
flood combat form f32
flood carrier form f32
cyborg armor f32

Also labeled as simply cyborg in Guerilla. Used to modify damage on all body parts of the cyborg (spartan) biped.

cyborg energy shield f32

Damage modifier for the "cyborg energy shield" material type. See the shield material type field of the unit's model_collision_geometry tag.

human armor f32
human skin f32
sentinel f32
monitor f32
plastic f32
water f32
leaves f32
elite energy shield f32

Damage modifier for the "elite energy shield" material type. See the shield material type field of the unit's model_collision_geometry tag. Note that this field receives a hard-coded singleplayer adjustment at map compile time for the pistol's damage effect.

ice f32
hunter shield f32
pad(12)
pad(16)

This information was partially generated using Invader tag definitions.

Acknowledgements

Thanks to the following individuals for their research or contributions to this topic:

  • Conscars (Checking multiplayer headshot flag and radii behaviour)
  • gbMichelle (Reverse engineering the damage formula)
  • Kavawuvi (Invader tag definitions)
  • Mortis (Explaining headshot damage and bleedthrough)
  • MosesOfEgypt (Tag structure research)