Locational Damage

 

      Note: This tutorial is written by me Koolio but the code is not completely by me ... I just improved it a little most credit goes out to Stalker he wrote the code not me.

      I was going to do this tut for a long time now and since I got an E-mail for it I will do it now. Okay ... Um ... Let's start now shall we?
      Make a new file called locdam.qc. Do it now ... I'll hold on ... Okay, let's go on to step one: Copy and paste this into locdam.qc:


/*
=================================================
 Location Based Damage        by Stalker 8-5-99
=================================================
*/

/*

Returns value for which area of body hit, which then can be used to determine
the amount of damage to do.

1 = head
2 = torso
3 = leg

"Inflictor" is a nail / rocket / shotgun owner etc.
"Targ" is the entity taking damage

*/

float (entity targ, entity inflictor) hit_location =
{
	local float ofs;

	// compensate for better head shots with large bounding box
	if ((targ.absmax_z - targ.origin_z) > 32 && self.classname != "monster_shambler")
		ofs = 40;
	else
		ofs = 20;

	if (inflictor.size != '0 0 0' || inflictor.classname == "player" || inflictor.classname == "soldier")
	{	// if using shotgun then...
		if (trace_ent != world && trace_ent.movetype != MOVETYPE_NONE)
		{
			// if ( (trace_endpos_z >= trace_ent.absmax_z - ofs) && (trace_endpos_z <= trace_ent.absmax_z) )
			if (self.origin_z > other.origin_z + 17)  //added by koolio
			{     // Head Shot			
				if (self.origin_z < other.origin_z + 20)  //koolio
					return;  //koolio
				else  //koolio
				bprint ("head shot\n");		//koolio
				return 1;				//koolio
			}

//    else 
			if ( (trace_endpos_z < trace_ent.absmax_z - ofs) && (trace_endpos_z > trace_ent.origin_z) )
			{       // Chest shot
				bprint ("chest shot\n");
				return 2;
			}
			else if ( (trace_endpos_z < trace_ent.origin_z) && (trace_endpos_z > trace_ent.absmin_z) )
			{       // Leg shot
				bprint ("leg shot\n");
				return 3;
			}
		}
	}

	// if inflictor is a spike/rocket etc.
	if (targ.movetype != MOVETYPE_NONE) // if targ is a player/monster
	{
		//if ( (inflictor.origin_z >= targ.absmax_z - ofs) && (inflictor.origin_z <= targ.absmax_z) )
		if (self.origin_z > other.origin_z + 17)    
		{       // Head Shot
		if (self.origin_z < other.origin_z + 20)
			return;
			bprint ("head shot\n");
			return 1;
		}
		else if ( (inflictor.origin_z < targ.absmax_z - ofs) && (inflictor.origin_z > targ.origin_z) )
		{       // Chest shot -- Normal damage
			bprint ("Chest shot\n");
			return 2;
		}
		else if (inflictor.origin_z < targ.origin_z && inflictor.origin_z > targ.absmin_z)
		{       // Leg shot -- 0.5 - 0.7 x damage
				bprint ("Leg shot\n");
				return 3;
		}
	}
	else
	{	// hit something other then player or monster so normal damage
		return 2; 
	}

};




/*
Returns amount of damage to do based on location type "a"

if a = 1, 1.3 to 1.7 times damage
if a = 2, 0.8 to 1.2 times damage
if a = 3, 0.5 to 0.7 times damage

*/

float (float a, float damage) location_damage =
{

	if (a == 1)
	{	// Head Shot -- Upto 1.7 x damage
		damage = damage * (3 + random()*0.4);
	}
	else 
	if (a == 2)
	{	// Chest shot -- 0.8 - 1.2 x damage
		damage = damage * (0.8 + random()*0.4);
	}
	else if (a == 3)
	{	// Leg shot -- 0.5 - 0.7 x damage
		damage = damage * (0.5 + random()*0.2);
	}

	return damage;  // return amount of damage

};

      Alrighty ... I should explain this if you don't grasp it:
      First we check where you aim on the bbox (and if you aim at a shambler compensate for it) and print a message...
      Then it returns a value which we use later on in location_damage...
      So this returns the amount of damage that should be done (you can change this)...The part in the
      headshots is a bit hacky perhaps...
      It is because I added something here that makes sure you aim at the head (and not the chest like it was originally and
      also not waaaay above it).
      Okay so now we got some damage but how do we use it? Okay hold on I'll tell you now.

      First thing you do now is save up locdam.qc and add it BEFORE weapons.qc in the progs.src file ... Finished? Okay let's move on ... Open weapons.qc and look for this line of code (or anything similair):


if (other.takedamage)
	(in spike_touch and superspike_touch)
if (trace_ent.takedamage)
	(in trace_attack)


      Then after this add:


	{
		rand = hit_location(other, self);       //get location
		rand = location_damage (rand, 9);       //set damage

		spawn_touchblood (9);
		T_Damage (other, self, self.owner, rand);

      And add:

local float rand;

      At the beginning of the function you use it in after the bracket.
      This also means you got to change the number after the self.owner bit to rand like i did in the above example
      So just examine the code and compare with this. That should be sufficient to figure it out. And do this for all weapons you want Locational Damage with.
      The neato thing of this is that this code also works for monsters since they use trace_attack and spike_touch too.
      If you don't want this then just do this:

if (other.takedamage && other.flags != FL_MONSTER) etc ...
      This COULD work I dunno I just made it up ... But it should be similar to this I guess.
      Okay, that would be it for today. Save up and compile. Also, as an extra note if it won't E-mail me and tell me. I fiddled some with this code for my mod so you can blow heads of and I don't have the original code handy here...But it should that's all (there were just some lines commented out by me so it can be fixed when broken just try first.
      So here we get to the 'What We Learned' bit (I always wanted to write one).  

 

 


What We Learned

1. Location Damage is not that hard to code
2. We can check where the player aims to get different effects
3. Stalker is a good coder
4. Stalker is my friend

 


Author: Koolio
AI chat on ICQ: 45625330
Return to home