This code has room for improvement, however, that exercise is left to the user.
in weapons.qc, before W_FireAxe, put this:
Code: Select all
// because spawnmeatspray is defined below W_FireAxe...
void(vector org, vector vel) SpawnMeatSpray;
/*
================
CheckForHeadshotDamage
================
*/
float(vector headorg, vector shotorg, vector shotdir, float headsize, float hitrange, float damage, float multiplier) CheckForHeadshotDamage =
{
local float dist, braingibs;
local vector endpoint;
// find out how far away the shot on bbox is from headorigin
dist = vlen(headorg - shotorg);
// If the distance from shotorigin and headorigin is too
// far away, then assume flat out that this was a miss.
if(dist > hitrange)
return damage;
// If the distance is within the headsize, assume that we have
// a hit
if(dist <= headsize)
{
return ceil(damage*multiplier);
}
// Now, we must determine if the shot has hit within valid check range
// then we need to check if the shot would have hit the head
if(dist <= hitrange)
{
// Set endpoint to compare against headorigin
// it should go from the shotorg in the amount of dist
// in the direction of shotdir
endpoint = shotorg+shotdir*dist;
// Find out if endpoint has hit within headsize
// if so, return double damage
if(vlen(endpoint - headorg) <= headsize)
{
// throw some gibs to help highlight headshot
braingibs = 2;
while(braingibs)
{
SpawnMeatSpray(headorg, (shotdir*(150+ceil(random()*100))));
braingibs = braingibs - 1;
}
return ceil(damage*multiplier);
}
}
// Nothing hit the head, so return normal damage
return damage;
};
All targets that you intend to use this with should have .view_ofs set. For example, the same view_ofs of '0 0 22' should work fine for grunts and enforcers.
In traceattack type weapons, usage is as follows:
Code: Select all
if(trace_ent.classname == "player" || (trace_ent.flags & FL_MONSTER))
damage = damage+CheckForHeadshotDamage((trace_ent.origin+trace_ent.view_ofs), trace_endpos, v_forward, 12, 40, damage, 4);
For use with projectile weapons, in the touch function:
Code: Select all
mvdir = normalize(self.velocity);
if(other.classname == "player" || (other.flags & FL_MONSTER))
damage = damage+CheckForHeadshotDamage((other.origin+other.view_ofs), self.origin, mvdir, 12, 40, damage, 2);