I was scratching my head for a while why my modified MCP Scud wasn’t killing players consistently.
In idGameLocal::RadiusDamage you’ll see
trace_t tr;
if ( damageDecl->GetNoTrace() || ent->CanDamage( origin, damagePoint, MASK_EXPLOSIONSOLID, ignoreDamage, &tr ) ) {
// get the damage scale
damageScale = dmgPower * ( 1.0f - dist / radius );
dir = ent->GetPhysics()->GetOrigin() - inflictor->GetPhysics()->GetOrigin();
dir.Normalize();
ent->Damage( inflictor, attacker, dir, damageDecl, damageScale, &tr );
}
Well there’s the short answer, with GetNoTrace() the trace struct isn’t initialized, yet it’s being passed in regardless, thus there will be garbage values for those that try to use it.
A change to
damageDecl->GetNoTrace() ? NULL : &tr
for the Damage parameter is the initial fix, but it warrants a closer look to see how the Damage functions of the entity classes use it.
GetNoTrace is only used on the MCP scud, in theory so it skips the trace checks for the explosion and thus kills all.
idPlayer:: Damage ? We see collision passing into CalcDamagePoints, also Pain, and Killed in the form of the joint Killed and Pain don’t seem to use location, but I haven’t tracked it exhaustively (there’s Killed and Pain for some other entity classes, and they also pass onto script functions).
CalcDamagePoints passes it on to GetDamageScaleForTrace, that’s where the trouble was, with garbage values it would often spit out a scale of 0, thus no damage.
With the above change GetDamageScaleForTrace isn’t even called, which is fine, if you’re not discriminating whether there’s a trace from the explosion you probably don’t care which part of the body is hit either
sdTransport:: Damage?, it wont pass on Damage to each vehicle part, in the case of the scud the damage is high usually enough to just kill the vehicle. Maybe there will be some edge cases (literally) of the explosion where some bits won’t fall of that should have.