New Radius Damage

 

 

WarZone
profile | email

posted 10-16-98 12:00 AM CT (US)
While messing with all of the new weapons in my mod (there's twenty new weapons altogether), I discovered that q2's built in radius damage function isn't set up very well.

Here's how it works:

·  Finds all targets within maxrange

·  Finds distance between explosion and target

·  Subtracts one point of damage per unit that the target is from the explosion

Here's how my new function works:

·  Finds all targets within maxrange

·  Finds distance between explosion and target

·  Evenly distributes the radius damage over the blast area. So, the target looses radius damage * (1 - (distance / maxrange))

Effectively, the damage is now evenly distributed with the outer bounds of the explosion dealing minimal damage, and the closer you get, the more damage you recieve.

Here's the new function:

/*

  ============

  T_RadiusDamage

  ============

  */

  void T_RadiusDamage (edict_t *inflictor, edict_t *attacker, float damage, edict_t *ignore, float radius, int mod)

  {

       float   points;

       edict_t *ent = NULL;

          vec3_t  v;

    vec3_t  dir;

 while ((ent = findradius(ent, inflictor->s.origin, radius)) != NULL)
        {
           if (ent == ignore)
                  continue;
           if (!ent->takedamage)
                       continue;

            VectorAdd (ent->mins, ent->maxs, v);
                VectorMA (ent->s.origin, 0.5, v, v);
                VectorSubtract (inflictor->s.origin, v, v);
                points = damage * (1 - (VectorLength (v) / radius));
         if (ent == attacker)
                        points = points * 0.5;
              if (points > 0)
             {
                   if (CanDamage (ent, inflictor))
                     {
                           VectorSubtract (ent->s.origin, inflictor->s.origin, dir);
                           T_Damage (ent, inflictor, attacker, dir, inflictor->s.origin, vec3_origin, (int)points, (int)points, DAMAGE_RADIUS, mod);
                   }
           }
   }
}

Hope you find this of use. I sure did. With the standard q2 function radius damage always had to be greater than the blast radius to ensure that at least one point was dealt per unit away from the blast while within the blast radius. However, my function allows you to specify and blast radius and any radius damage ammounts. And, by the way, rocket jumping with the new radius damage function absolutely rulez... I can't explain it exactly, but it actually "feels" more realistic : )

-WarZone-

philip
profile | email

posted 10-16-98 1:24 PM CT (US)
Warzone,
Good fix. But I was thinking, shouldn't damage attenuation be an inverse-square?
philip

ShockMan
profile | email

posted 10-16-98 4:41 PM CT (US)
Yup... agree. Change the
damage * (1 - (VectorLength (v) / radius));

to:

damage = (1 / (sqrt(VectorLength(v) / radius));

This might not be an exactly correct inverse-square... but almost. =)

Haven't tried this in quake, so dont blame me if it sux. (oh, and please shout if the above math is totaly of track... im abit rusty on this stuff =)

WarZone
profile | email

posted 10-16-98 5:24 PM CT (US)
Nope, that's not it! Try this:

damage *= 1 - (sqrt(radius) / sqrt(VectorLength(v));

Now there's a nice parabolic damage distribution :)

-WarZone-

ShockMan
profile | email

posted 10-16-98 6:39 PM CT (US)
Im most certain that the inverse square law is 1/d^2 where d is distance... (i have been wrong before tho).

And your equation doesn't quite make sense... (i notice some mistakes in my first try too =).

The way your trying, it should proberly be:
points = damage * 1 - (sqrt(VectorLength(v) / sqrt(radius));

right?

well... nevermind, I dont think any of this will be very useful in quake anyway. It just takes up CPU power... and no one will hardly notice =).

philip
profile | email

posted 10-17-98 9:45 PM CT (US)
True, but isn't the point really about calculating a 'true damage radius' function? Whether or not players notice the effects or not is secondary in my opinion..
philip

philip
profile | email

posted 10-17-98 10:04 PM CT (US)
Sorry to post another follow-up so quickly but I was thinking. Isn't the inverse-square law where the 'whatever' is attenuated (divided down) by the square of its distance from its origin? If this is so, then perhaps the function should simply be:

points = damage/(VectorLength(v)^2);

That is if vectorlength is really the distance from the origin..

It may be, however, that the other functions provided above are indeed mathematically equivalent. Dunno, but I sure like Warzone's function! If nothing else, it just looks good!!!
philip