Post tutorial Report RSS Locational Damage

How to add a simple locational damage code to Quake2. Imagine the possbilities with this code! A headshot can do 80 damage, 160 damage, or 1500 damage.. it's all your decision!!

Posted by on - Basic Server Side Coding

[page=Locational Damage for Quake2]
Hello! This is Paril here, with Paril's Mini Tutorials.

Down at Paril's Projects, as you know, AQC is in development, and well.. what's a realistic mod without being able to be hit in the head and dying one hit? Nothing!

Anyways, here's how we're going to do it.. (Also, please ignore the fact about the spacing.. it works fine in C++/Notepad)

Open up G_Combat.c..

find this:

qboolean CheckTeamDamage (edict_t *targ, edict_t *attacker)
{
		//FIXME make the next line real and uncomment this block
		// if ((ability to damage a teammate == OFF) && (targ's team == attacker's team))
	return false;
}

Right after this, copy-paste this entire code after that and before the T_Damage function:

//==============================================================
// AQC Scale damage amount by location of hit on player's body..
//==============================================================
#define VectorEmpty(a)  ((a[0]==0)&&(a[1]==0)&&(a[2]==0))
#define IsIn(x,a,b)     ((x)>=(a)&&(x)<=(b))
#define LEG_DAMAGE     (height/2.0)-abs(targ->mins[2])-3
#define STOMACH_DAMAGE (height/1.6)-abs(targ->mins[2])
#define CHEST_DAMAGE   (height/1.4)-abs(targ->mins[2])
#define NECK_DAMAGE    (height/1.1)-abs(targ->mins[2])
#define HEAD_DAMAGE    (height/0.7)-abs(targ->mins[2])
#define ARM1_DAMAGE    (height/1.4)-abs(targ->mins[8])  // Should go about between the chest and stomach, and going over by 8
#define ARM2_DAMAGE    (height/1.4)-abs(targ->mins[-8]) // Should go about between the chest and stomach, and going over by -8

//==============================================================
float location_scaling(edict_t *targ, vec3_t point, float damage, int mod) {
float z_rel, height;
edict_t *ent;

  if (!(targ->flags&FL_GODMODE))
    if (!VectorEmpty(point))
      if (IsIn(mod, MOD_BLASTER, MOD_RAILGUN)) {
        height = abs(targ->mins[2])+targ->maxs[2];
        z_rel = point[2]-targ->s.origin[2];
        if (z_rel < LEG_DAMAGE)
          return 0.35;  // Scale down by 2/3
        else
        if (z_rel < STOMACH_DAMAGE)
          return 0.66;  // Scale down by 1/3
        else
        if (z_rel < CHEST_DAMAGE)
            return 1.20;  // Scale up by 1/5
		if (z_rel < NECK_DAMAGE)
		  return 3.00;  // Scale up by 3X (Come on, a neck shot atleast has to kill&#59;) )
		if (z_rel < HEAD_DAMAGE)
		  return 8.00;  // Scale up by 8X (Pretty much dead...)
 		if (z_rel < ARM1_DAMAGE)
		  return .66;  // Scale down by 1/3
 		if (z_rel < ARM2_DAMAGE)
		  return .66;  // Scale down by 1/3

		else
          return 1.0;} // Normal Damage if hit anywhere else

  return 1.0; // keep damage the same..

}
//-----------------------------------------------------------

Now go down further, and find this line in your T_Damage function:

// friendly fire avoidance
// if enabled you can't hurt teammates (but you can hurt yourself)
// knockback still occurs
	if ((targ != attacker) && ((deathmatch->value && ((int)(dmflags->value) & (DF_MODELTEAMS | DF_SKINTEAMS))) || coop->value))
	{
		if (OnSameTeam (targ, attacker))
		{
			if ((int)(dmflags->value) & DF_NO_FRIENDLY_FIRE)
				damage = 0;
			else
				mod |= MOD_FRIENDLY_FIRE;
		}
	}

Right above that, add:

//-----------------------------------
//AQC  Scale damage by hit location (leg,stomach,chest,head)..
  damage *= location_scaling(targ, point, damage, mod);
//------------------------------------

There you go! A simple, yet effective way to implement a very good realistic feature.

Paril

Post comment Comments
Paril Author
Paril - - 24 comments

Many many things you could do with this. Maybe some text like in Action "You hit %s in the (name of part)!", Kevlar/Armor bullet hitting "%s's Kevlar Vest absorbed most of the shot".. this can be used for every weapon, including melee attacks.

Reply Good karma+1 vote
Paril Author
Paril - - 24 comments

Note, I messed up,
Try this:

#define ARM1_DAMAGE (height/1.4)-abs(targ->mins)+8 // Should go about between the chest and stomach, and going over by 8#define ARM2_DAMAGE (height/1.4)-abs(targ->mins)-8 // Should go about between the chest and stomach, and going over by -8

Reply Good karma+1 vote
Q2kerS
Q2kerS - - 1 comments

Oh, sorry, but i think you need folow line:
after (!(targ->flags&FL_GODMODE)):
Code:
if (!(targ->deadflag == DEAD_DEAD))

and before "if (!VectorEmpty(point))" for example.
It prevent an one-shot gibbing of dead enemy.

Reply Good karma Bad karma+1 vote
VoivoD
VoivoD - - 147 comments

Moddb.com

Included :-) Thanks :-)

Reply Good karma Bad karma+1 vote
Post a comment

Your comment will be anonymous unless you join the community. Or sign in with your social account: