TUTORIAL 15 - Leg Shots
by McBain
1. Pre-requisite Tutorial
[Ed's note: You need to implement a locational damage tutoroial first. We have used
Tutorial 14 by Calrathan or you can
use your own locational damage code - just hook it in like below. We've also
got foot shots in our locational damage, which also slow you down. Thanks
to McBain for letting us post his code - Sum].
I thought it would be cool to make leg damage slow the player down.
When the player picks up health it returns their speed.
You can easily make this so that any damage slows the player.
2. Reduce Speed When Hit
First go to g_combat.c in the game project.
If you have done the above tutorial the code should look like this:
// Check the location ignoring the rotation info
switch ( targ->client->lasthurt_location &
~(LOCATION_BACK | LOCATION_LEFT | LOCATION_RIGHT | LOCATION_FRONT) )
{
case LOCATION_HEAD:
take *= 1.8;
break;
case LOCATION_FACE:
if (targ->client->lasthurt_location & LOCATION_FRONT)
take *= 5.0; // Faceshots REALLY suck
else
take *= 1.8;
break;
case LOCATION_SHOULDER:
if (targ->client->lasthurt_location & (LOCATION_FRONT | LOCATION_BACK))
take *= 1.4; // Throat or nape of neck
else
take *= 1.1; // Shoulders
break;
case LOCATION_CHEST:
if (targ->client->lasthurt_location & (LOCATION_FRONT | LOCATION_BACK))
take *= 1.3; // Belly or back
else
take *= 0.8; // Arms
break;
case LOCATION_STOMACH:
take *= 1.2;
break;
case LOCATION_GROIN:
if (targ->client->lasthurt_location & LOCATION_FRONT)
take *= 1.3; // Groin shot
break;
case LOCATION_LEG:
take *= 0.7;
break;
case LOCATION_FOOT:
take *= 0.5;
break;
}
The locational damage checks for leg hits on the lower part of the body (the actual
percentage varies when the player crouches and does 70% damage to the legs and 50% damage to the foot.
You can change these however you want.
Now to make the leg damage slow the player down add this line just
under take *= 0.7; and take *= 0.7; .
case LOCATION_GROIN:
if (targ->client->lasthurt_location & LOCATION_FRONT)
take *= 1.3; // Groin shot
break;
case LOCATION_LEG:
take *= 0.7;
targ->client->ps.speed -= take; // slowdown if shot in legs, McBain
break;
case LOCATION_FOOT:
take *= 0.5;
targ->client->ps.speed -= take; // slowdown if shot in foot, McBain
break;
}
This is pretty self explanatory. targ is the damaged player and the
speed is decreased by the amount of damage taken. You could scale that however you want.
3. Reset Speed At Respawn
Now open g_client.c and go to the ClientSpawn function. Change the
code as follows:
// health will count down towards max_health
ent->health = client->ps.stats[STAT_HEALTH] = client->ps.stats[STAT_MAX_HEALTH] * 1.25;
// return to normal speed, McBain
client->ps.speed = g_speed.value;
G_SetOrigin( ent, spawn_origin );
VectorCopy( spawn_origin, client->ps.origin );
This just means that the players speed will return to the server's
normal value when the player spawns (after a death obviously).
4. Regain Speed On Health Pickup
Now go to g_items.c go to the Pickup_Health function and add my code
here:
if ( ent->count ) {
quantity = ent->count;
} else {
quantity = ent->item->quantity;
}
other->health += quantity;
// return speed upon health pickup or more than maximum health, McBain
other->client->ps.speed += quantity;
if (other->client->ps.speed > g_speed.value) {
other->client->ps.speed = g_speed.value;
}
if (other->health >= other->client->ps.stats[STAT_MAX_HEALTH]) {
other->client->ps.speed = g_speed.value;
}
// end McBain
if (other->health > max ) {
other->health = max;
}
This just makes it so that if the player picks up health they get that
much speed back. If the player picks up health and gets to 100 or more health they go to
maximum speed.
The only thing this code doesn't do is make it so if you picked up a
megahealth and got leg damage, you may have more than 100 health and run slower, but this
is easily fixed. I will leave that to the reader (I hate when people say that). Besides
all you would have to do is pick up a health and you would be back to normal speed.
5. One More Fix
One last thing. The Quake code updates player speed during every
"player think" mostly to check for the haste power-up. You need to make it so it doesn't
change the player speed since we made want it to get slower.
Open up g_active.c, go to the ClientThink_real function and comment
this out like below:
client->ps.gravity = g_gravity.value;
// set speed
// out by McBain for speed damage
// client->ps.speed = g_speed.value;
if ( client->ps.powerups[PW_HASTE] ) {
client->ps.speed *= 1.3;
}
Notice haste still makes you 1.3 times faster.
Props to wchar_t* for the location damage tutorial.
|