diff --git a/reaction/game/bg_public.h b/reaction/game/bg_public.h index 352aacbb..32b7a11d 100644 --- a/reaction/game/bg_public.h +++ b/reaction/game/bg_public.h @@ -5,6 +5,9 @@ //----------------------------------------------------------------------------- // // $Log$ +// Revision 1.53 2002/03/30 17:37:48 jbravo +// Added damage tracking to the server. Added zcam flic mode. cleaned up g_damage. +// // Revision 1.52 2002/03/23 05:17:42 jbravo // Major cleanup of game -> cgame communication with LCA vars. // @@ -606,6 +609,7 @@ typedef enum { PERS_CAPTURES // captures */ PERS_SAVEDTEAM, // JBravo: for TP + PERS_DAMAGE_DELT, // JBravo: Keeping track of damage. PERS_WEAPONMODES // Blaze: Holds the different weapond modes for the different guns see below for the defines to use } persEnum_t; //RQ3 Weapon modes - If the bit is set, then the weapon is in the more restrictive mode, as in if it's set to 1 it's semi, 3rnd burst, etc diff --git a/reaction/game/g_active.c b/reaction/game/g_active.c index 0f09df76..7a97b098 100644 --- a/reaction/game/g_active.c +++ b/reaction/game/g_active.c @@ -5,6 +5,9 @@ //----------------------------------------------------------------------------- // // $Log$ +// Revision 1.65 2002/03/30 17:37:48 jbravo +// Added damage tracking to the server. Added zcam flic mode. cleaned up g_damage. +// // Revision 1.64 2002/03/30 02:54:24 jbravo // MOre spec tweaks and a scoreboard fix // @@ -568,9 +571,10 @@ void SpectatorThink( gentity_t *ent, usercmd_t *ucmd ) { if(ucmd->upmove >=10 ) { if (!(client->ps.pm_flags & PMF_JUMP_HELD)) { client->ps.pm_flags |= PMF_JUMP_HELD; - if (client->sess.spectatorState == SPECTATOR_ZCAM) - CameraSwingCycle(ent, 1); - else + if (client->sess.spectatorState == SPECTATOR_ZCAM) { + if (client->camera->mode == CAMERA_MODE_SWING) + CameraSwingCycle(ent, 1); + } else Cmd_FollowCycle_f(ent, 1); } } @@ -586,10 +590,20 @@ void SpectatorThink( gentity_t *ent, usercmd_t *ucmd ) { if (client->sess.spectatorState == SPECTATOR_FREE && OKtoFollow(clientNum)) { client->sess.spectatorState = SPECTATOR_ZCAM; client->specMode = SPECTATOR_ZCAM; + client->camera->mode = CAMERA_MODE_SWING; client->ps.stats[STAT_RQ3] |= RQ3_ZCAM; client->ps.pm_flags &= ~PMF_FOLLOW; CameraSwingCycle(ent, 1); RQ3_SpectatorMode(ent); + } else if (client->sess.spectatorState == SPECTATOR_ZCAM && client->camera->mode == CAMERA_MODE_SWING + && OKtoFollow(clientNum)) { + client->sess.spectatorState = SPECTATOR_ZCAM; + client->specMode = SPECTATOR_ZCAM; + client->camera->mode = CAMERA_MODE_FLIC; + client->ps.stats[STAT_RQ3] |= RQ3_ZCAM; + client->ps.pm_flags &= ~PMF_FOLLOW; + CameraFlicBegin (ent); + RQ3_SpectatorMode(ent); } else if (client->sess.spectatorState == SPECTATOR_ZCAM && OKtoFollow(clientNum)) { client->sess.spectatorState = SPECTATOR_FOLLOW; client->specMode = SPECTATOR_FOLLOW; diff --git a/reaction/game/g_combat.c b/reaction/game/g_combat.c index 660f523f..827bf8d4 100644 --- a/reaction/game/g_combat.c +++ b/reaction/game/g_combat.c @@ -5,6 +5,9 @@ //----------------------------------------------------------------------------- // // $Log$ +// Revision 1.54 2002/03/30 17:37:48 jbravo +// Added damage tracking to the server. Added zcam flic mode. cleaned up g_damage. +// // Revision 1.53 2002/03/18 19:18:39 slicer // Fixed bandage bugs ( i hope ) // @@ -117,7 +120,9 @@ void AddScore( gentity_t *ent, vec3_t origin, int score ) { //} // show score plum - ScorePlum(ent, origin, score); + // JBravo: not in TP + if (g_gametype.integer != GT_TEAMPLAY) + ScorePlum(ent, origin, score); // ent->client->ps.persistant[PERS_SCORE] += score; if (g_gametype.integer == GT_TEAM) @@ -1357,27 +1362,12 @@ dflags these flags are used to control how T_Damage works void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, vec3_t dir, vec3_t point, int damage, int dflags, int mod ) { gclient_t *client; - int take; - int save; - int asave; - int knockback; - int max; - int bleeding = 0; // damage causes bleeding - int instant_dam = 1; - vec3_t bulletPath; - vec3_t bulletAngle; - - //Elder: added for M3 and Pistols - vec_t dist; - vec3_t line; - - int clientHeight; - int clientFeetZ; - int clientRotation; - int bulletHeight; - int bulletRotation; // Degrees rotation around client. - int impactRotation; - + int take, save, asave, knockback, max; + int bleeding = 0, instant_dam = 1; + vec3_t bulletPath, bulletAngle, line; + vec_t dist; + int clientHeight, clientFeetZ, clientRotation, bulletHeight; + int bulletRotation, impactRotation; gentity_t *tent; #ifdef MISSIONPACK @@ -1401,7 +1391,7 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, // the intermission has allready been qualified for, so don't // allow any extra scoring - if ( level.intermissionQueued ) { + if (level.intermissionQueued) { return; } @@ -1418,125 +1408,81 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, // Elder: respawn protection -- only for gunfire though! // No safety from falling! // NiceAss: Or TELEFAGS! - if ( targ->client && inflictor && + if (targ->client && inflictor && level.time - targ->client->respawnTime < g_RQ3_respawnProtectTime.integer * 1000 && mod != MOD_TELEFRAG) return; - if ( !inflictor ) { + if (!inflictor) { inflictor = &g_entities[ENTITYNUM_WORLD]; } - if ( !attacker ) { + if (!attacker) { attacker = &g_entities[ENTITYNUM_WORLD]; } - // shootable doors / buttons don't actually have any health - //Blaze: Dont want to be able to shoot doors open - /* - if ( targ->s.eType == ET_MOVER ) { - if ( targ->use && (targ->moverState == MOVER_POS1 - || targ->moverState == ROTATOR_POS1) ) { - targ->use( targ, inflictor, attacker ); - } - return; - } - */ - if ( targ->s.eType == ET_MOVER && targ->health <= 0 ) { + if (targ->s.eType == ET_MOVER && targ->health <= 0) { return; } - //Elder: from action source - // damage reduction for shotgun and mk23/akimbo - // if far away, reduce it to original action levels - //Note: doesn't handle shots on non-clients (e.g. breakables) - if (targ->client && inflictor->client) { - if ( mod == MOD_M3) { - VectorSubtract(targ->client->ps.origin, inflictor->client->ps.origin, line ); - dist = VectorLength( line ); - if ( dist > 450.0 ) { + //Elder: from action source + // damage reduction for shotgun and mk23/akimbo + // if far away, reduce it to original action levels + //Note: doesn't handle shots on non-clients (e.g. breakables) + if (targ->client && inflictor->client) { + if (mod == MOD_M3) { + VectorSubtract(targ->client->ps.origin, inflictor->client->ps.origin, line); + dist = VectorLength(line); + if (dist > 450.0) { damage -= 2; } + } else if (mod == MOD_PISTOL || mod == MOD_AKIMBO) { + VectorSubtract(targ->client->ps.origin, inflictor->client->ps.origin, line); + dist = VectorLength(line); + if (dist > 600.0 && dist < 1400.0) { + damage = (int)(damage * 2/3); + } + //Elder: added >= ... 1400.0 is a magic number for perfect shots if not in :) + else if (dist >= 1400.0) { + damage = (int)(damage * 1/2); + } } - else if ( mod == MOD_PISTOL || mod == MOD_AKIMBO ) { - VectorSubtract(targ->client->ps.origin, inflictor->client->ps.origin, line ); - dist = VectorLength( line ); - // G_Printf("Distance from target: %f\n", dist); - if ( dist > 600.0 && dist < 1400.0 ) { - // G_Printf("Damage reduced to 2/3\n"); - damage = (int)(damage * 2/3); - } - //Elder: added >= ... 1400.0 is a magic number for perfect shots if not in :) - else if ( dist >= 1400.0 ) { - // G_Printf("Damage reduced to 1/2\n"); - damage = (int)(damage * 1/2); - } - } - } + } //Blaze: If we shot a breakable item subtract the damage from its health and try to break it - if ( targ->s.eType == ET_BREAKABLE ) { - targ->health -= damage; - G_BreakGlass( targ, point, mod ); + if (targ->s.eType == ET_BREAKABLE) { + targ->health -= damage; + G_BreakGlass(targ, point, mod); return; - } + } + #ifdef MISSIONPACK if( g_gametype.integer == GT_OBELISK && CheckObeliskAttack( targ, attacker ) ) { return; } #endif - // reduce damage by the attacker's handicap value - // unless they are rocket jumping - // NiceAss: This isn't needed - /* - if ( attacker->client && attacker != targ ) { - max = 100;//100 is the max health, no handicap attacker->client->ps.stats[STAT_MAX_HEALTH]; -#ifdef MISSIONPACK - if( bg_itemlist[attacker->client->ps.stats[STAT_PERSISTANT_POWERUP]].giTag == PW_GUARD ) { - max /= 2; - } -#endif - damage = damage * max / 100; - } - */ client = targ->client; - if ( client ) { - if ( client->noclip ) { + if (client) { + if (client->noclip) { return; } } - if ( !dir ) { + if (!dir) { dflags |= DAMAGE_NO_KNOCKBACK; } else { VectorNormalize(dir); } - //Elder: this is a simplifed knockback calc - Action has a radically different one. - //knockback = damage; - - //if ( knockback > 200 ) { - //knockback = 200; - //} - - //if ( mod == MOD_KICK ) - //{ - //knockback = 200; - //} - - if ( targ->flags & FL_NO_KNOCKBACK ) { + if (targ->flags & FL_NO_KNOCKBACK) { knockback = 0; - } - else if ( dflags & DAMAGE_NO_KNOCKBACK ) { + } else if (dflags & DAMAGE_NO_KNOCKBACK) { knockback = 0; - } - else - { + } else { //Elder: select knockback - switch (mod) - { + switch (mod) { case MOD_HANDCANNON: knockback = RQ3_HANDCANNON_KICK; break; @@ -1573,7 +1519,6 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, knockback = 400; break; default: - //G_Printf("Unknown MOD\n"); G_Printf("G_Damage: Received unknown MOD - using default knockback\n"); knockback = 50; break; @@ -1584,14 +1529,13 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, // This was added when the possibility of missing was added from spherical head detection. // We don't want someone flying back from a sniper to the head when it actually missed! // Hal: Make sure we have valid pointers before accessing them - if ( (dir != NULL) && (point != NULL) && G_HitPlayer ( targ, dir, point ) ) { + if ((dir != NULL) && (point != NULL) && G_HitPlayer (targ, dir, point)) { // figure momentum add, even if the damage won't be taken - if ( knockback && targ->client ) { + if (knockback && targ->client) { vec3_t kvel, flydir; float mass; - if ( mod != MOD_FALLING ) - { + if (mod != MOD_FALLING) { VectorCopy(dir, flydir); flydir[2] += 0.4f; } @@ -1612,14 +1556,14 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, // set the timer so that the other client can't cancel // out the movement immediately - if ( !targ->client->ps.pm_time ) { - int t; + if (!targ->client->ps.pm_time) { + int t; t = knockback * 2; - if ( t < 50 ) { + if (t < 50) { t = 50; } - if ( t > 200 ) { + if (t > 200) { t = 200; } targ->client->ps.pm_time = t; @@ -1629,11 +1573,9 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, // NiceAss: This was moved too // add to the attacker's hit counter (if the target isn't a general entity like a prox mine) - if ( attacker->client && targ != attacker && targ->health > 0 - && targ->s.eType != ET_MISSILE - && targ->s.eType != ET_GENERAL) - { - if ( OnSameTeam( targ, attacker ) ) { + if (attacker->client && targ != attacker && targ->health > 0 && + targ->s.eType != ET_MISSILE && targ->s.eType != ET_GENERAL) { + if (OnSameTeam(targ, attacker)) { attacker->client->ps.persistant[PERS_HITS]--; } else { attacker->client->ps.persistant[PERS_HITS]++; @@ -1643,17 +1585,17 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, } // check for completely getting out of the damage - if ( !(dflags & DAMAGE_NO_PROTECTION) ) { + if (!(dflags & DAMAGE_NO_PROTECTION)) { // if TF_NO_FRIENDLY_FIRE is set, don't do damage to the target // if the attacker was on the same team #ifdef MISSIONPACK if ( mod != MOD_JUICED && targ != attacker && !(dflags & DAMAGE_NO_TEAM_PROTECTION) && OnSameTeam (targ, attacker) ) { #else - if ( targ != attacker && OnSameTeam (targ, attacker) ) { + if (targ != attacker && OnSameTeam(targ, attacker)) { #endif // JBravo: more FF tweaks - if ( g_friendlyFire.integer == 2 && level.team_round_going ) { + if (g_friendlyFire.integer == 2 && level.team_round_going) { return; } } @@ -1669,35 +1611,15 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, #endif // check for godmode - if ( targ->flags & FL_GODMODE ) { + if (targ->flags & FL_GODMODE) { return; } } -// hawkins: no battlesuit for reaction - /* - // battlesuit protects from all radius damage (but takes knockback) - // and protects 50% against all damage - if ( client && client->ps.powerups[PW_BATTLESUIT] ) { - G_AddEvent( targ, EV_POWERUP_BATTLESUIT, 0 ); - if ( ( dflags & DAMAGE_RADIUS ) || ( mod == MOD_FALLING ) ) { - return; - } - damage *= 0.5; - } - */ //Blaze: Add falling damage for limping - if ( mod == MOD_FALLING ) targ->client->ps.stats[STAT_RQ3] |= RQ3_LEGDAMAGE; + if (mod == MOD_FALLING) targ->client->ps.stats[STAT_RQ3] |= RQ3_LEGDAMAGE; - - // always give half damage if hurting self - // calculated after knockback, so rocket jumping works - //Elder: no way >:) - //if ( targ == attacker) { - //damage *= 0.5; - //} - - if ( damage < 1 ) { + if (damage < 1) { damage = 1; } take = damage; @@ -1707,315 +1629,223 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, asave = CheckArmor (targ, take, dflags); take -= asave; - if ( g_debugDamage.integer ) { + if (g_debugDamage.integer) { G_Printf( "%i: client:%i health:%i damage:%i armor:%i\n", level.time, targ->s.number, - targ->health, take, asave ); + targ->health, take, asave); } - - // Elder: moved below location damage - // add to the damage inflicted on a player this frame - // the total will be turned into screen blends and view angle kicks - // at the end of the frame - /* - if ( client ) { - if ( attacker ) { - client->ps.persistant[PERS_ATTACKER] = attacker->s.number; - } else { - client->ps.persistant[PERS_ATTACKER] = ENTITYNUM_WORLD; - } - client->damage_armor += asave; - client->damage_blood += take; - client->damage_knockback += knockback; - if ( dir ) { - VectorCopy ( dir, client->damage_from ); - client->damage_fromWorld = qfalse; - } else { - VectorCopy ( targ->r.currentOrigin, client->damage_from ); - client->damage_fromWorld = qtrue; - } - } - */ - // See if it's the player hurting the emeny flag carrier #ifdef MISSIONPACK if( g_gametype.integer == GT_CTF || g_gametype.integer == GT_1FCTF ) { #else - if( g_gametype.integer == GT_CTF) { + if (g_gametype.integer == GT_CTF) { #endif - Team_CheckHurtCarrier(targ, attacker); + Team_CheckHurtCarrier(targ, attacker); } - if (targ->client) - { + if (targ->client) { // set the last client who damaged the target targ->client->lasthurt_client = attacker->s.number; targ->client->lasthurt_mod = mod; - //if(targ->client->bleeding == 0)//Do bleeding damage first so that you dont do faster more bleeding with different guns - // targ->client->bleeding = take*BLEED_TIME; -// Begin Duffman + // Begin Duffman // Modify the damage for location damage - if ( point && targ && targ->health > 0 && attacker && take) - { + if (point && targ && targ->health > 0 && attacker && take) { // First things first. If we're not damaging them, why are we here? - //Elder: removed M3, handcannon, and grenades from location damage code + // Elder: removed M3, handcannon, and grenades from location damage code - if (take && - mod == MOD_M3 || + if (take && mod == MOD_M3 || mod == MOD_HANDCANNON || mod == MOD_GRENADE || - mod == MOD_GRENADE_SPLASH) - { + mod == MOD_GRENADE_SPLASH) { bleeding = 1; instant_dam = 0; //No location damage - //targ->client->lasthurt_location = LOCATION_STOMACH|LOCATION_FRONT; targ->client->lasthurt_location = LOCATION_NONE|LOCATION_FRONT; //Elder: we'll use the shotgun damage report model from AQ2 - if (mod == MOD_HANDCANNON || mod == MOD_M3) - { + if (mod == MOD_HANDCANNON || mod == MOD_M3) { //Elder: do shotgun report like AQ2 int playernum = targ - g_entities; - //playernum--; if (playernum >= 0 && playernum < MAX_CLIENTS) tookShellHit[playernum] = 1; - } - else { + } else { // Grenade stuff - don't print if you hurt yourself // We could re-use the shotgun report for grenades if (targ != attacker) trap_SendServerCommand( attacker-g_entities, va("print \"You hit %s^7\n\"", targ->client->pers.netname)); } - } - - - else if (take && - mod == MOD_PISTOL || - mod == MOD_M4 || - mod == MOD_SNIPER || - mod == MOD_MP5 || - mod == MOD_AKIMBO || - //mod == MOD_M3 || - //mod == MOD_HANDCANNON || - //mod == MOD_GRENADE || - //mod == MOD_GRENADE_SPLASH || - mod == MOD_KNIFE || - mod == MOD_KNIFE_THROWN) - { - bleeding = 1; - instant_dam = 0; + } else if (take && mod == MOD_PISTOL || mod == MOD_M4 || + mod == MOD_SNIPER || mod == MOD_MP5 || mod == MOD_AKIMBO || + mod == MOD_KNIFE || mod == MOD_KNIFE_THROWN) { + bleeding = 1; + instant_dam = 0; // Point[2] is the REAL world Z. We want Z relative to the clients feet + // Where the feet are at [real Z] + clientFeetZ = targ->r.currentOrigin[2] + targ->r.mins[2]; + // How tall the client is [Relative Z] + clientHeight = targ->r.maxs[2] - targ->r.mins[2]; + // Where the bullet struck [Relative Z] + bulletHeight = point[2] - clientFeetZ; + // Get a vector aiming from the client to the bullet hit + VectorSubtract(targ->r.currentOrigin, point, bulletPath); + // Convert it into PITCH, ROLL, YAW + vectoangles(bulletPath, bulletAngle); + clientRotation = targ->client->ps.viewangles[YAW]; + bulletRotation = bulletAngle[YAW]; - // Where the feet are at [real Z] - clientFeetZ = targ->r.currentOrigin[2] + targ->r.mins[2]; - // How tall the client is [Relative Z] - clientHeight = targ->r.maxs[2] - targ->r.mins[2]; - // Where the bullet struck [Relative Z] - bulletHeight = point[2] - clientFeetZ; + impactRotation = abs(clientRotation-bulletRotation); - // Get a vector aiming from the client to the bullet hit - VectorSubtract(targ->r.currentOrigin, point, bulletPath); - // Convert it into PITCH, ROLL, YAW - vectoangles(bulletPath, bulletAngle); + impactRotation += 45; // just to make it easier to work with + impactRotation = impactRotation % 360; // Keep it in the 0-359 range - clientRotation = targ->client->ps.viewangles[YAW]; - bulletRotation = bulletAngle[YAW]; + if (impactRotation < 90) { + if (attacker->client && level.team_round_going) + attacker->client->pers.records[REC_BACKSHOTS]++; + targ->client->lasthurt_location = LOCATION_BACK; + } else if (impactRotation < 180) { + if (attacker->client && level.team_round_going) + attacker->client->pers.records[REC_RIGHTSHOTS]++; + targ->client->lasthurt_location = LOCATION_RIGHT; + } else if (impactRotation < 270) { + if (attacker->client && level.team_round_going) + attacker->client->pers.records[REC_FRONTSHOTS]++; + targ->client->lasthurt_location = LOCATION_FRONT; + } else if (impactRotation < 360) { + if (attacker->client && level.team_round_going) + attacker->client->pers.records[REC_LEFTSHOTS]++; + targ->client->lasthurt_location = LOCATION_LEFT; + } else + targ->client->lasthurt_location = LOCATION_NONE; - impactRotation = abs(clientRotation-bulletRotation); - - impactRotation += 45; // just to make it easier to work with - impactRotation = impactRotation % 360; // Keep it in the 0-359 range - - if (impactRotation < 90) - { - if (attacker->client && level.team_round_going) - attacker->client->pers.records[REC_BACKSHOTS]++; - targ->client->lasthurt_location = LOCATION_BACK; - } - else if (impactRotation < 180) - { - if (attacker->client && level.team_round_going) - attacker->client->pers.records[REC_RIGHTSHOTS]++; - targ->client->lasthurt_location = LOCATION_RIGHT; - } - else if (impactRotation < 270) - { - if (attacker->client && level.team_round_going) - attacker->client->pers.records[REC_FRONTSHOTS]++; - targ->client->lasthurt_location = LOCATION_FRONT; - } - else if (impactRotation < 360) - { - if (attacker->client && level.team_round_going) - attacker->client->pers.records[REC_LEFTSHOTS]++; - targ->client->lasthurt_location = LOCATION_LEFT; - } - else - targ->client->lasthurt_location = LOCATION_NONE; - - // NiceAss: Added for better head hit-detection. + // NiceAss: Added for better head hit-detection. if (!G_HitPlayer(targ, dir, point)) { - // NiceAss: It didn't intersect the sphere (head) and it's above the shoulders so it hit the air. - return; + // NiceAss: It didn't intersect the sphere (head) and it's above the shoulders so it hit the air. + return; } - // The upper body never changes height, just distance from the feet - if (bulletHeight > clientHeight - 2) - targ->client->lasthurt_location |= LOCATION_HEAD; - else if (bulletHeight > clientHeight - 8) - targ->client->lasthurt_location |= LOCATION_FACE; - else if (bulletHeight > clientHeight - 10) - targ->client->lasthurt_location |= LOCATION_SHOULDER; - else if (bulletHeight > clientHeight - 16) - targ->client->lasthurt_location |= LOCATION_CHEST; - else if (bulletHeight > clientHeight - 26) - targ->client->lasthurt_location |= LOCATION_STOMACH; - else if (bulletHeight > clientHeight - 29) - targ->client->lasthurt_location |= LOCATION_GROIN; - //else if (bulletHeight < 4) - // targ->client->lasthurt_location |= LOCATION_FOOT; - else - // The leg is the only thing that changes size when you duck, - // so we check for every other parts RELATIVE location, and - // whats left over must be the leg. - targ->client->lasthurt_location |= LOCATION_LEG; + // The upper body never changes height, just distance from the feet + if (bulletHeight > clientHeight - 2) + targ->client->lasthurt_location |= LOCATION_HEAD; + else if (bulletHeight > clientHeight - 8) + targ->client->lasthurt_location |= LOCATION_FACE; + else if (bulletHeight > clientHeight - 10) + targ->client->lasthurt_location |= LOCATION_SHOULDER; + else if (bulletHeight > clientHeight - 16) + targ->client->lasthurt_location |= LOCATION_CHEST; + else if (bulletHeight > clientHeight - 26) + targ->client->lasthurt_location |= LOCATION_STOMACH; + else if (bulletHeight > clientHeight - 29) + targ->client->lasthurt_location |= LOCATION_GROIN; + else + // The leg is the only thing that changes size when you duck, + // so we check for every other parts RELATIVE location, and + // whats left over must be the leg. + targ->client->lasthurt_location |= LOCATION_LEG; + switch (targ->client->lasthurt_location & + ~(LOCATION_BACK | LOCATION_LEFT | LOCATION_RIGHT | LOCATION_FRONT)) { + case LOCATION_HEAD: + case LOCATION_FACE: + if (attacker->client && level.team_round_going) + attacker->client->pers.records[REC_HEADSHOTS]++; + //save headshot time for player_die + targ->client->headShotTime = level.time; - //G_Printf("In loc damage: %d incomming\n",take); - // Check the location ignoring the rotation info - //Elder: moved up - /* - if (mod == MOD_HANDCANNON || mod == MOD_M3) - { - //trap_SendServerCommand( attacker-g_entities, va("print \"You hit %s^7\n\"", targ->client->pers.netname)); - //Elder: do shotgun report like AQ2 - int playernum = targ - g_entities; + //Elder: reusing line so we don't have to declare more variables + line[0] = line[1] = 0; + line[2] = 20; + trap_SendServerCommand(attacker-g_entities, va("print \"You hit %s^7 in the head.\n\"", + targ->client->pers.netname)); + trap_SendServerCommand(targ-g_entities, va("print \"Head Damage.\n\"")); - playernum--; - if (playernum >= 0 && playernum <= MAX_CLIENTS - 1) - tookShellHit[playernum] = 1; - - //bleeding = 1; - //instant_dam = 0; - } - else if (mod == MOD_GRENADE || mod == MOD_GRENADE_SPLASH ) - { - trap_SendServerCommand( attacker-g_entities, va("print \"You hit %s^7\n\"", targ->client->pers.netname)); - } - else */ - if (1) - { - switch ( targ->client->lasthurt_location & - ~(LOCATION_BACK | LOCATION_LEFT | LOCATION_RIGHT | LOCATION_FRONT) ) - { - case LOCATION_HEAD: - case LOCATION_FACE: - if (attacker->client && level.team_round_going) - attacker->client->pers.records[REC_HEADSHOTS]++; - //save headshot time for player_die - targ->client->headShotTime = level.time; - - //Elder: reusing line so we don't have to declare more variables - line[0] = 0; - line[1] = 0; - line[2] = 20; - - trap_SendServerCommand( attacker-g_entities, va("print \"You hit %s^7 in the head.\n\"", targ->client->pers.netname)); - trap_SendServerCommand( targ-g_entities, va("print \"Head Damage.\n\"")); - - //Setup headshot spray and sound - //Only do if not knife or SSG -- SSG has its own trail of blood - if (mod != MOD_SNIPER && mod != MOD_KNIFE && mod != MOD_KNIFE_THROWN) - { - VectorAdd(targ->s.pos.trBase, line, line); - tent = G_TempEntity(line, EV_HEADSHOT); + //Setup headshot spray and sound + //Only do if not knife or SSG -- SSG has its own trail of blood + if (mod != MOD_SNIPER && mod != MOD_KNIFE && mod != MOD_KNIFE_THROWN) { + VectorAdd(targ->s.pos.trBase, line, line); + tent = G_TempEntity(line, EV_HEADSHOT); + tent->s.eventParm = DirToByte(dir); + tent->s.otherEntityNum = targ->s.clientNum; + } + take *= 1.8; //+ 1; + break; + case LOCATION_SHOULDER: + case LOCATION_CHEST: + if (attacker->client && level.team_round_going) + attacker->client->pers.records[REC_CHESTSHOTS]++; + // Vest stuff - is the knife supposed to be affected? + // NiceAss: Added mod != MOD_KNIFE_THROWN so kevlar doesn't help against thrown knives + if (bg_itemlist[targ->client->ps.stats[STAT_HOLDABLE_ITEM]].giTag == HI_KEVLAR + && mod != MOD_KNIFE_THROWN) { + targ->client->kevlarHit = qtrue; + if (attacker->client->ps.weapon == WP_SSG3000) { + trap_SendServerCommand(attacker-g_entities, va("print \"%s ^7has a Kevlar Vest, too bad you have AP rounds...\n\"", + targ->client->pers.netname)); + trap_SendServerCommand(targ-g_entities, va("print \"Kevlar Vest absorbed some of %s^7's AP sniper round\n\"", + attacker->client->pers.netname)); + take = take * 0.325; + } else { + if (mod != MOD_KNIFE) { // && mod != MOD_KNIFE_THROWN) + trap_SendServerCommand(attacker-g_entities, va("print \"%s^7 has a Kevlar Vest - AIM FOR THE HEAD!\n\"", + targ->client->pers.netname)); + } else { + trap_SendServerCommand(attacker-g_entities, va("print \"You hit %s^7 in the chest.\n\"", + targ->client->pers.netname)); + trap_SendServerCommand(targ-g_entities, va("print \"Kevlar Vest absorbed most of %s ^7shot\n\"", + attacker->client->pers.netname )); + } + take = take/10; + instant_dam = 1; + bleeding = 0; + } + //Kevlar sound + if (mod != MOD_KNIFE && mod != MOD_KNIFE_THROWN) { + tent = G_TempEntity(targ->s.pos.trBase, EV_BULLET_HIT_KEVLAR); tent->s.eventParm = DirToByte(dir); - tent->s.otherEntityNum = targ->s.clientNum; + //tent = G_TempEntity2(targ->s.pos.trBase, EV_RQ3_SOUND, RQ3_SOUND_KEVLARHIT); } - take *= 1.8; //+ 1; - break; - case LOCATION_SHOULDER: - case LOCATION_CHEST: - if (attacker->client && level.team_round_going) - attacker->client->pers.records[REC_CHESTSHOTS]++; - //Vest stuff - is the knife supposed to be affected? - // NiceAss: Added mod != MOD_KNIFE_THROWN so kevlar doesn't help against thrown knives - if (bg_itemlist[targ->client->ps.stats[STAT_HOLDABLE_ITEM]].giTag == HI_KEVLAR - && mod != MOD_KNIFE_THROWN) - { - targ->client->kevlarHit = qtrue; - //if ((attacker->client->ps.stats[STAT_WEAPONS] & (1 << WP_SSG3000)) == (1 << WP_SSG3000)) - if (attacker->client->ps.weapon == WP_SSG3000) - { - trap_SendServerCommand(attacker-g_entities, va("print \"%s ^7has a Kevlar Vest, too bad you have AP rounds...\n\"",targ->client->pers.netname)); - trap_SendServerCommand(targ-g_entities, va("print \"Kevlar Vest absorbed some of %s^7's AP sniper round\n\"",attacker->client->pers.netname)); - take = take * 0.325; - } - else - { - if (mod != MOD_KNIFE)// && mod != MOD_KNIFE_THROWN) - trap_SendServerCommand( attacker-g_entities, va("print \"%s^7 has a Kevlar Vest - AIM FOR THE HEAD!\n\"", targ->client->pers.netname)); - else - trap_SendServerCommand( attacker-g_entities, va("print \"You hit %s^7 in the chest.\n\"", targ->client->pers.netname)); - trap_SendServerCommand( targ-g_entities, va("print \"Kevlar Vest absorbed most of %s ^7shot\n\"", attacker->client->pers.netname )); - take = take/10; - instant_dam = 1; - bleeding = 0; - } - //Kevlar sound - if (mod != MOD_KNIFE && mod != MOD_KNIFE_THROWN) - { - tent = G_TempEntity(targ->s.pos.trBase, EV_BULLET_HIT_KEVLAR); - tent->s.eventParm = DirToByte(dir); - //tent = G_TempEntity2(targ->s.pos.trBase, EV_RQ3_SOUND, RQ3_SOUND_KEVLARHIT); - } - } - else - { - trap_SendServerCommand( attacker-g_entities, va("print \"You hit %s^7 in the chest.\n\"", targ->client->pers.netname)); - trap_SendServerCommand( targ-g_entities, va("print \"Chest Damage.\n\"")); - take *= 0.65; - } - break; - case LOCATION_STOMACH: - case LOCATION_GROIN: - if (attacker->client && level.team_round_going) - attacker->client->pers.records[REC_STOMACHSHOTS]++; - trap_SendServerCommand( attacker-g_entities, va("print \"You hit %s^7 in the stomach.\n\"", targ->client->pers.netname)); - trap_SendServerCommand( targ-g_entities, va("print \"Stomach Damage.\n\"")); - take *= 0.4; - break; - case LOCATION_LEG: - case LOCATION_FOOT: - if (attacker->client && level.team_round_going) - attacker->client->pers.records[REC_LEGSHOTS]++; - trap_SendServerCommand( attacker-g_entities, va("print \"You hit %s^7 in the leg.\n\"", targ->client->pers.netname)); - trap_SendServerCommand( targ-g_entities, va("print \"Leg Damage.\n\"")); - targ->client->ps.stats[STAT_RQ3] |= RQ3_LEGDAMAGE; - take *= 0.25; - break; - } + } else { + trap_SendServerCommand(attacker-g_entities, va("print \"You hit %s^7 in the chest.\n\"", + targ->client->pers.netname)); + trap_SendServerCommand(targ-g_entities, va("print \"Chest Damage.\n\"")); + take *= 0.65; + } + break; + case LOCATION_STOMACH: + case LOCATION_GROIN: + if (attacker->client && level.team_round_going) + attacker->client->pers.records[REC_STOMACHSHOTS]++; + trap_SendServerCommand(attacker-g_entities, va("print \"You hit %s^7 in the stomach.\n\"", + targ->client->pers.netname)); + trap_SendServerCommand(targ-g_entities, va("print \"Stomach Damage.\n\"")); + take *= 0.4; + break; + case LOCATION_LEG: + case LOCATION_FOOT: + if (attacker->client && level.team_round_going) + attacker->client->pers.records[REC_LEGSHOTS]++; + trap_SendServerCommand(attacker-g_entities, va("print \"You hit %s^7 in the leg.\n\"", + targ->client->pers.netname)); + trap_SendServerCommand(targ-g_entities, va("print \"Leg Damage.\n\"")); + targ->client->ps.stats[STAT_RQ3] |= RQ3_LEGDAMAGE; + take *= 0.25; + break; } - // G_Printf("In loc damage: %d outgoing\n",take); - +// G_Printf("In loc damage: %d outgoing\n",take); } -// take = G_LocationDamage(point, targ, attacker, take); - } - - else - targ->client->lasthurt_location = LOCATION_NONE; +// take = G_LocationDamage(point, targ, attacker, take); + } else + targ->client->lasthurt_location = LOCATION_NONE; // End Duffman } // add to the damage inflicted on a player this frame // the total will be turned into screen blends and view angle kicks // at the end of the frame - if ( client ) { - if ( attacker ) { + if (client) { + if (attacker) { client->ps.persistant[PERS_ATTACKER] = attacker->s.number; } else { client->ps.persistant[PERS_ATTACKER] = ENTITYNUM_WORLD; @@ -2023,11 +1853,11 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, client->damage_armor += asave; client->damage_blood += take; client->damage_knockback += knockback; - if ( dir ) { - VectorCopy ( dir, client->damage_from ); + if (dir) { + VectorCopy (dir, client->damage_from); client->damage_fromWorld = qfalse; } else { - VectorCopy ( targ->r.currentOrigin, client->damage_from ); + VectorCopy (targ->r.currentOrigin, client->damage_from); client->damage_fromWorld = qtrue; } } @@ -2036,57 +1866,32 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, // do the damage if (take) { // G_Printf("(%d) taken as damage\n",take); - if (instant_dam) - { +// JBravo: for Damage delt tracking + attacker->client->ps.persistant[PERS_DAMAGE_DELT] += take; + if (instant_dam) { // G_Printf("(%d) instant damage\n",take); targ->health = targ->health - take; } - if ( targ->client ) { + if (targ->client) { targ->client->ps.stats[STAT_HEALTH] = targ->health; } - if ( targ->health <= 0 ) { - //Elder: removed so we can play with bodies :) - //if ( client ) { - //targ->flags |= FL_NO_KNOCKBACK; - //} - + if (targ->health <= 0) { if (targ->health < -999) { targ->health = -999; } targ->enemy = attacker; targ->die (targ, inflictor, attacker, take, mod); return; - // Elder: why was this commented out? - } else if ( targ->pain ) { + } else if (targ->pain) { targ->pain (targ, attacker, take); } } - /* - // Elder: crash code because conditional was missing - if (client) - { - if (!(targ->flags & FL_GODMODE) && (take)) - { - // this one was missing - if (targ->pain) - targ->pain (targ, attacker, take); - } - } - // Elder: this is commented out because of redundancy - if (take) - { - if (targ->pain) targ->pain (targ, attacker, take); - } - */ - - if (client) - { - if (client->lasthurt_location && bleeding) - { + if (client) { + if (client->lasthurt_location && bleeding) { // Elder: use the server FPS - int realBleedTime; + int realBleedTime; realBleedTime = trap_Cvar_VariableIntegerValue("sv_fps"); if (realBleedTime <= 0) @@ -2098,16 +1903,7 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, VectorClear(targ->client->bleedloc_offset); else VectorSubtract (point, targ->r.currentOrigin, targ->client->bleedloc_offset); - - //G_Printf("(%d) = damage",damage); - //G_Printf("(%d) = bleeding",client->bleeding); } - //if (bleeding) - //{ - // client->bleeding += damage * BLEED_TIME; - // G_Printf("(%d) = damage",damage); - // G_Printf("(%d) = bleeding",client->bleeding); - //} } } diff --git a/reaction/game/g_teamplay.c b/reaction/game/g_teamplay.c index 34fd26df..a718679b 100644 --- a/reaction/game/g_teamplay.c +++ b/reaction/game/g_teamplay.c @@ -5,6 +5,9 @@ //----------------------------------------------------------------------------- // // $Log$ +// Revision 1.48 2002/03/30 17:37:49 jbravo +// Added damage tracking to the server. Added zcam flic mode. cleaned up g_damage. +// // Revision 1.47 2002/03/30 02:29:43 jbravo // Lots of spectator code updates. Removed debugshit, added some color. // @@ -163,6 +166,8 @@ //----------------------------------------------------------------------------- #include "g_local.h" +#include "zcam.h" + gitem_t *BG_FindItemForHoldable( holdable_t pw ); char *ConcatArgs( int start ); int touch[MAX_GENTITIES]; @@ -1346,7 +1351,8 @@ void RQ3_SpectatorMode(gentity_t *ent) { if (ent->client->sess.spectatorState == SPECTATOR_ZCAM) trap_SendServerCommand(ent->client->ps.clientNum, - va("print \"\n" S_COLOR_MAGENTA "Spectator Mode-" S_COLOR_YELLOW"ZCAM\n")); + va("print \"\n" S_COLOR_MAGENTA "Spectator Mode-" S_COLOR_YELLOW"ZCAM-%s\n", + (ent->client->camera->mode == CAMERA_MODE_SWING)? "SWING":"FLIC")); else trap_SendServerCommand(ent->client->ps.clientNum, va("print \"\n" S_COLOR_MAGENTA "Spectator Mode-" S_COLOR_YELLOW"%s\n",