Code3Arena

PlanetQuake | Code3Arena | Tutorials | << Prev | Tutorial15 | Next >>

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.

PlanetQuake | Code3Arena | Tutorials | << Prev | Tutorial15 | Next >>