Code for 0-11-00 VM release
Server-side
This commit is contained in:
Victor Chow 2001-09-01 16:14:14 +00:00
parent 50d1af5408
commit 58a94376e0
13 changed files with 525 additions and 147 deletions

View file

@ -1353,6 +1353,7 @@ char *eventnames[] = {
"EV_BULLET_HIT_KEVLAR", // Elder: sparks
"EV_SSG3000_HIT_FLESH", // Elder: SSG3000 blood spray
"EV_JUMPKICK", // Elder: sound + jumpkick message
"EV_EJECTBLOOD", // Elder: when bleeding, every 2s release blood
"EV_MISSILE_HIT",
"EV_MISSILE_MISS",

View file

@ -452,14 +452,22 @@ static qboolean PM_CheckJump( void ) {
pm->ps->velocity[2] += 135;
}
else
pm->ps->velocity[2] += 100; // More velocity
pm->ps->velocity[2] += 75; // More velocity ; was 100
if (pm->debugLevel)
Com_Printf("^4Hit a double jump^7\n");
// Com_Printf("%i:CPM->Double Jump, after %ims\n", c_pmove, (pm->jumpTime - pm->ps->stats[STAT_JUMPTIME]));
} else {
pm->ps->velocity[2] += JUMP_VELOCITY;
}
pm->ps->stats[STAT_JUMPTIME] = 400; // Time that the second jump is within to get the higher jump
// Time that the second jump is within to get the higher jump
if (pml.ladder == qtrue)
{
// Elder: more for ladder jumps
pm->ps->stats[STAT_JUMPTIME] = 500;
}
else
pm->ps->stats[STAT_JUMPTIME] = 250; // 400
// end Blaze
PM_AddEvent( EV_JUMP );
@ -1833,7 +1841,8 @@ static void PM_BeginWeaponChange( int weapon ) {
pm->ps->weapon == WP_M3 ||
pm->ps->weapon == WP_HANDCANNON ||
pm->ps->weapon == WP_SSG3000 ||
pm->ps->weapon == WP_M4)
pm->ps->weapon == WP_M4 ||
pm->ps->weapon == WP_AKIMBO)
PM_StartWeaponAnim(WP_ANIM_DISARM);
}
@ -1850,7 +1859,8 @@ static void PM_BeginWeaponChange( int weapon ) {
pm->ps->weapon == WP_M3 ||
pm->ps->weapon == WP_HANDCANNON ||
pm->ps->weapon == WP_SSG3000 ||
pm->ps->weapon == WP_M4)
pm->ps->weapon == WP_M4 ||
pm->ps->weapon == WP_AKIMBO)
PM_StartWeaponAnim(WP_ANIM_DISARM);
PM_StartTorsoAnim( TORSO_DROP );
@ -1926,7 +1936,8 @@ static void PM_FinishWeaponChange( void ) {
pm->ps->weapon == WP_M3 ||
pm->ps->weapon == WP_HANDCANNON ||
pm->ps->weapon == WP_SSG3000 ||
pm->ps->weapon == WP_M4)
pm->ps->weapon == WP_M4 ||
pm->ps->weapon == WP_AKIMBO)
PM_StartWeaponAnim(WP_ANIM_ACTIVATE);
PM_StartTorsoAnim( TORSO_RAISE );
@ -1954,7 +1965,8 @@ static void PM_TorsoAnimation( void ) {
pm->ps->weapon == WP_M3 ||
pm->ps->weapon == WP_HANDCANNON ||
pm->ps->weapon == WP_SSG3000 ||
pm->ps->weapon == WP_M4)
pm->ps->weapon == WP_M4 ||
pm->ps->weapon == WP_AKIMBO)
PM_ContinueWeaponAnim( WP_ANIM_IDLE );
// PM_ContinueWeaponAnim( WP_ANIM_READY );
@ -2355,6 +2367,20 @@ static void PM_Weapon( void ) {
}
}
// Elder: new akimbo code
if ( pm->ps->weapon == WP_AKIMBO )
{
if (pm->ps->ammo[WP_AKIMBO] == 0 && pm->ps->stats[STAT_BURST])
{
pm->ps->stats[STAT_BURST] = 0;
pm->cmd.buttons &= ~BUTTON_ATTACK;
}
else if (pm->ps->stats[STAT_BURST])
{
pm->cmd.buttons |= BUTTON_ATTACK;
}
}
// check for item using
// Elder: removed
/*
@ -2407,7 +2433,8 @@ static void PM_Weapon( void ) {
pm->ps->weapon == WP_M3 ||
pm->ps->weapon == WP_HANDCANNON ||
pm->ps->weapon == WP_SSG3000 ||
pm->ps->weapon == WP_M4))
pm->ps->weapon == WP_M4 ||
pm->ps->weapon == WP_AKIMBO))
PM_ContinueWeaponAnim(WP_ANIM_IDLE);
}
}
@ -2454,7 +2481,8 @@ static void PM_Weapon( void ) {
pm->ps->weapon == WP_M3 ||
pm->ps->weapon == WP_HANDCANNON ||
pm->ps->weapon == WP_SSG3000 ||
pm->ps->weapon == WP_M4)
pm->ps->weapon == WP_M4 ||
pm->ps->weapon == WP_AKIMBO)
PM_StartWeaponAnim( WP_ANIM_IDLE );
return;
}
@ -2544,13 +2572,18 @@ static void PM_Weapon( void ) {
pm->ps->weapon == WP_M3 ||
pm->ps->weapon == WP_HANDCANNON ||
pm->ps->weapon == WP_SSG3000 ||
pm->ps->weapon == WP_M4)
pm->ps->weapon == WP_M4 ||
pm->ps->weapon == WP_AKIMBO)
PM_StartWeaponAnim( WP_ANIM_FIRE );
}
}
pm->ps->weaponstate = WEAPON_FIRING;
// Elder: akimbo check to auto-fire the second bullet
//if ( pm->ps->weapon == WP_AKIMBO && pm->ps->stats[STAT_BURST] == 0)
//pm->ps->stats[STAT_BURST] = 1;
// Elder: increment stat if alt-fire mode --needs to be predicted as well
if ( (pm->ps->weapon == WP_M4 &&
(pm->ps->persistant[PERS_WEAPONMODES] & RQ3_M4MODE) == RQ3_M4MODE) ||
@ -2598,15 +2631,15 @@ static void PM_Weapon( void ) {
{
pm->ps->stats[STAT_WEAPONS] &= ~( 1 << WP_GRENADE);
}
//Elder: remove one more bullet/shell if handcannon/akimbo
//Elder: remove one more bullet/shell if handcannon
else if (pm->ps->weapon == WP_HANDCANNON)
{
pm->ps->ammo[ WP_HANDCANNON ]--;
}
//Elder: take away an extra bullet if available - handled in g_weapon.c as well
else if (pm->ps->weapon == WP_AKIMBO && pm->ps->ammo[ WP_AKIMBO ] > 0) {
pm->ps->ammo[ WP_AKIMBO ] --;
}
//else if (pm->ps->weapon == WP_AKIMBO && pm->ps->ammo[ WP_AKIMBO ] > 0) {
//pm->ps->ammo[ WP_AKIMBO ] --;
//}
//Elder: sync bullets a la AQ2 style
if (pm->ps->weapon == WP_AKIMBO && pm->ps->ammo[WP_AKIMBO] < 12) {
@ -2664,7 +2697,16 @@ static void PM_Weapon( void ) {
addTime = RQ3_M3_DELAY;
break;
case WP_AKIMBO:
addTime = RQ3_AKIMBO_DELAY;
if (pm->ps->stats[STAT_BURST])
{
addTime = RQ3_AKIMBO_DELAY2;
pm->ps->stats[STAT_BURST] = 0;
}
else
{
pm->ps->stats[STAT_BURST] = 1;
addTime = RQ3_AKIMBO_DELAY;
}
break;
case WP_GRENADE:
addTime = RQ3_GRENADE_DELAY;
@ -3205,7 +3247,8 @@ void PmoveSingle (pmove_t *pmove) {
pm->ps->weapon == WP_M3 ||
pm->ps->weapon == WP_HANDCANNON ||
pm->ps->weapon == WP_SSG3000 ||
pm->ps->weapon == WP_M4)
pm->ps->weapon == WP_M4 ||
pm->ps->weapon == WP_AKIMBO)
PM_WeaponAnimation();
// torso animation

View file

@ -188,7 +188,7 @@ typedef enum {
#define THROW_DAMAGE 250 //Throwing Knife damage
#define GRENADE_DAMAGE 170
#define GRENADE_SPLASH_DAMAGE 170
#define GRENADE_SPLASH_RADIUS 340 //Splash damage * 2
#define GRENADE_SPLASH_RADIUS 340 //340 Splash damage * 2
#define PISTOL_SPREAD 140
#define MP5_SPREAD 250
@ -220,8 +220,10 @@ typedef enum {
#define RQ3_HANDCANNON_DELAY 1200
#define RQ3_SSG3000_DELAY 1400
#define RQ3_SSG3000_BOLT_DELAY 1300// Elder: delay before zooming back in
#define RQ3_AKIMBO_DELAY 500 // Elder: two delays: one for the total delay
#define RQ3_AKIMBO_DELAY2 200 // one for the time to start the second shot
//#define RQ3_AKIMBO_DELAY 500 // Elder: two delays: one for the total delay
//#define RQ3_AKIMBO_DELAY2 200 // one for the time to start the second shot
#define RQ3_AKIMBO_DELAY 200
#define RQ3_AKIMBO_DELAY2 300
#define RQ3_KNIFE_DELAY 800
#define RQ3_THROW_DELAY 800
#define RQ3_GRENADE_DELAY 750 // Elder: I made this up
@ -680,10 +682,27 @@ typedef enum {
REC_GRENADEDEATHS,
REC_KNIFETHROWDEATHS,
REC_KNIFESLASHDEATHS,
REC_KICKDEATHS,
REC_BLEEDDEATHS,
REC_FALLINGDEATHS,
REC_SUICIDES, // e.g. for MPELP award, those loonies :)
REC_WORLDDEATHS, // crushers, doors, etc.
// Kill tally
REC_HEADKILLS,
REC_CHESTKILLS,
REC_STOMACHKILLS,
REC_LEGKILLS,
REC_MK23KILLS,
REC_M3KILLS,
REC_MP5KILLS,
REC_M4KILLS,
REC_SSG3000KILLS,
REC_HANDCANNONKILLS,
REC_AKIMBOKILLS,
REC_GRENADEKILLS,
REC_KNIFETHROWKILLS,
REC_KNIFESLASHKILLS,
REC_KICKKILLS,
REC_STEALTHKILLS, // this is a derived record -- remove?
// Movement tally - dunno about these ones since they are related to pmove
REC_CAMPCOUNT,
@ -806,6 +825,7 @@ typedef enum {
EV_BULLET_HIT_KEVLAR, // Elder: sparks
EV_SSG3000_HIT_FLESH,
EV_JUMPKICK, // Elder: sound + jumpkick message
EV_EJECTBLOOD, // Elder: when bleeding, every 2s release blood
EV_MISSILE_HIT,
EV_MISSILE_MISS,

View file

@ -1330,10 +1330,12 @@ void ClientThink_real( gentity_t *ent ) {
//Elder: added for akimbos and 3rb and sniper zoom
switch( ent->client->ps.weapon ) {
case WP_AKIMBO:
/*
if ( ent->client->weaponfireNextTime != 0 &&
level.time >= ent->client->weaponfireNextTime) {
FireWeapon( ent );
}
*/
break;
case WP_M3:
//Elder: try to do a fast reload if it's queued
@ -1643,7 +1645,6 @@ void ClientEndFrame( gentity_t *ent ) {
// Begin Duffman
// Update the clips Amount in weapon for the client
// Elder: the STAT takes precedence over the server-side only listing
ent->client->ps.stats[STAT_CLIPS] = ent->client->numClips[ent->client->ps.weapon];
// End Duffman
@ -1667,7 +1668,7 @@ void ClientEndFrame( gentity_t *ent ) {
(ent->client->ps.ammo[WP_M4] <= 0 || ent->client->ps.weaponstate != WEAPON_FIRING))
{
//Restore view after shots if not firing
ent->client->ps.delta_angles[0] = ANGLE2SHORT(SHORT2ANGLE(ent->client->ps.delta_angles[0]) - ent->client->consecutiveShots * -0.7);
ent->client->ps.delta_angles[0] = ANGLE2SHORT(SHORT2ANGLE(ent->client->ps.delta_angles[0]) - ent->client->consecutiveShots * -0.7f);
ent->client->consecutiveShots = 0;
}

View file

@ -590,7 +590,8 @@ static void G_AddBot( const char *name, float skill, const char *team, int delay
key = "model";
model = Info_ValueForKey( botinfo, key );
if ( !*model ) {
model = "visor/default";
// Elder: changed to our default
model = "grunt/resdog";
}
Info_SetValueForKey( userinfo, key, model );
key = "team_model";

View file

@ -1046,6 +1046,7 @@ void ClientSpawn(gentity_t *ent) {
int savedPing;
// char *savedAreaBits;
int accuracy_hits, accuracy_shots;
/*
int knifeShots = 0;
int knifeHits = 0;
int mk23Shots = 0;
@ -1064,7 +1065,7 @@ void ClientSpawn(gentity_t *ent) {
int akimboHits = 0;
int grenShots = 0;
int grenHits = 0;
*/
int eventSequence;
char userinfo[MAX_INFO_STRING];
@ -1128,6 +1129,7 @@ void ClientSpawn(gentity_t *ent) {
// savedAreaBits = client->areabits;
accuracy_hits = client->accuracy_hits;
accuracy_shots = client->accuracy_shots;
/*
knifeShots = client->knifeShots;
knifeHits = client->knifeHits;
mk23Shots = client->mk23Shots;
@ -1144,6 +1146,7 @@ void ClientSpawn(gentity_t *ent) {
akimboHits = client->akimboHits;
grenShots = client->grenShots;
grenHits = client->grenHits;
*/
for ( i = 0 ; i < MAX_PERSISTANT ; i++ ) {
persistant[i] = client->ps.persistant[i];

View file

@ -1681,7 +1681,8 @@ void Cmd_Bandage (gentity_t *ent)
ent->client->ps.weapon == WP_M3 ||
ent->client->ps.weapon == WP_HANDCANNON ||
ent->client->ps.weapon == WP_SSG3000 ||
ent->client->ps.weapon == WP_M4)
ent->client->ps.weapon == WP_M4 ||
ent->client->ps.weapon == WP_AKIMBO)
{
ent->client->ps.generic1 = ( ( ent->client->ps.generic1 & ANIM_TOGGLEBIT )
^ ANIM_TOGGLEBIT ) | WP_ANIM_DISARM;
@ -1692,7 +1693,7 @@ void Cmd_Bandage (gentity_t *ent)
^ ANIM_TOGGLEBIT ) | TORSO_DROP;
ent->client->ps.weaponTime += 6000;
ent->client->ps.weaponTime += BLEED_BANDAGE_TIME;
ent->client->bleedtick = 4;
//Elder: added to track health to bleed off
ent->client->bleedBandageCount = BLEED_BANDAGE;
@ -2390,7 +2391,7 @@ void Cmd_PlayerStats_f( gentity_t *ent )
{
//char textbuf[1024];
/*
trap_SendServerCommand( ent-g_entities, va("print \"%s:\n\"",ent->client->pers.netname ));
trap_SendServerCommand( ent-g_entities, va("print \"----------------------------------\n\""));
trap_SendServerCommand( ent-g_entities, va("print \"| Weapon | Accuracy | Hits/Shots |\n\""));
@ -2404,6 +2405,8 @@ void Cmd_PlayerStats_f( gentity_t *ent )
trap_SendServerCommand( ent-g_entities, va("print \"| HC | %.1f | %d/%d |\n\"", (float)(ent->client->hcHits / (ent->client->hcShots ? ent->client->hcShots : 1)), ent->client->hcHits, ent->client->hcShots));
trap_SendServerCommand( ent-g_entities, va("print \"| SSG | %.1f | %d/%d |\n\"", (float)(ent->client->ssgHits / (ent->client->ssgShots ? ent->client->ssgShots : 1)), ent->client->ssgHits, ent->client->ssgShots));
trap_SendServerCommand( ent-g_entities, va("print \"----------------------------------\n\""));
*/
}
/*

View file

@ -340,6 +340,9 @@ void body_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int d
return;
}
if (attacker->client)
attacker->client->pers.records[REC_GIBSHOTS]++;
GibEntity( self, 0 );
}
@ -586,6 +589,8 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
if ( killer < 0 || killer >= MAX_CLIENTS ) {
killer = ENTITYNUM_WORLD;
killerName = "<world>";
// Elder: Statistics tracking
self->client->pers.records[REC_WORLDDEATHS]++;
}
if ( meansOfDeath < 0 || meansOfDeath >= sizeof( modNames ) / sizeof( modNames[0] ) ) {
@ -599,21 +604,129 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
self->client->pers.netname, obit );
// broadcast the death event to everyone
// Elder: use appropriate obit event
// Elder: use appropriate obit event and update statistics tracking
if ( (self->client->lasthurt_location & LOCATION_HEAD) == LOCATION_HEAD ||
(self->client->lasthurt_location & LOCATION_FACE) == LOCATION_FACE )
{
// head kill
self->client->pers.records[REC_HEADDEATHS]++;
if (attacker && attacker->client)
attacker->client->pers.records[REC_HEADKILLS]++;
ent = G_TempEntity( self->r.currentOrigin, EV_OBITUARY_HEAD );
}
else if ( (self->client->lasthurt_location & LOCATION_CHEST) == LOCATION_CHEST ||
(self->client->lasthurt_location & LOCATION_SHOULDER) == LOCATION_SHOULDER)
{
// chest kill
self->client->pers.records[REC_CHESTDEATHS]++;
if (attacker && attacker->client)
attacker->client->pers.records[REC_CHESTKILLS]++;
ent = G_TempEntity( self->r.currentOrigin, EV_OBITUARY_CHEST );
}
else if ( (self->client->lasthurt_location & LOCATION_STOMACH) == LOCATION_STOMACH ||
(self->client->lasthurt_location & LOCATION_GROIN) == LOCATION_GROIN)
{
// stomach kill
self->client->pers.records[REC_STOMACHDEATHS]++;
if (attacker && attacker->client)
attacker->client->pers.records[REC_STOMACHKILLS]++;
ent = G_TempEntity( self->r.currentOrigin, EV_OBITUARY_STOMACH );
}
else if ( (self->client->lasthurt_location & LOCATION_LEG) == LOCATION_LEG ||
(self->client->lasthurt_location & LOCATION_FOOT) == LOCATION_FOOT)
{
// leg kill
self->client->pers.records[REC_LEGDEATHS]++;
if (attacker && attacker->client)
attacker->client->pers.records[REC_LEGKILLS]++;
ent = G_TempEntity( self->r.currentOrigin, EV_OBITUARY_LEGS );
}
else
{
// non-location/world kill
ent = G_TempEntity( self->r.currentOrigin, EV_OBITUARY );
}
// Elder: Statistics tracking
switch ( meansOfDeath )
{
case MOD_KNIFE:
/*
if (attacker && attacker->client)
{
if ( attacker->client->ps.persistant[PERS_WEAPONMODES] & RQ3_KNIFEMODE )
{
attacker->client->pers.records[REC_KNIFESLASHKILLS]++;
self->client->pers.records[REC_KNIFESLASHDEATHS]++;
}
else
{
attacker->client->pers.records[REC_KNIFETHROWKILLS]++;
self->client->pers.records[REC_KNIFETHROWDEATHS]++;
}
}
else
{
// just count it as a slash death if no attacker
self->client->pers.records[REC_KNIFESLASHDEATHS]++;
}
*/
if (attacker && attacker->client)
attacker->client->pers.records[REC_KNIFESLASHKILLS]++;
self->client->pers.records[REC_KNIFESLASHDEATHS]++;
break;
case MOD_KNIFE_THROWN:
if (attacker && attacker->client)
attacker->client->pers.records[REC_KNIFETHROWKILLS]++;
self->client->pers.records[REC_KNIFETHROWDEATHS]++;
break;
case MOD_PISTOL:
if (attacker && attacker->client)
attacker->client->pers.records[REC_MK23KILLS]++;
self->client->pers.records[REC_MK23DEATHS]++;
break;
case MOD_M3:
if (attacker && attacker->client)
attacker->client->pers.records[REC_M3KILLS]++;
self->client->pers.records[REC_M3DEATHS]++;
break;
case MOD_M4:
if (attacker && attacker->client)
attacker->client->pers.records[REC_M4KILLS]++;
self->client->pers.records[REC_M4DEATHS]++;
break;
case MOD_MP5:
if (attacker && attacker->client)
attacker->client->pers.records[REC_MP5KILLS]++;
self->client->pers.records[REC_MP5DEATHS]++;
break;
case MOD_SNIPER:
if (attacker && attacker->client)
attacker->client->pers.records[REC_SSG3000KILLS]++;
self->client->pers.records[REC_SSG3000DEATHS]++;
break;
case MOD_HANDCANNON:
if (attacker && attacker->client)
attacker->client->pers.records[REC_HANDCANNONKILLS]++;
self->client->pers.records[REC_HANDCANNONDEATHS]++;
break;
case MOD_AKIMBO:
if (attacker && attacker->client)
attacker->client->pers.records[REC_AKIMBOKILLS]++;
self->client->pers.records[REC_AKIMBODEATHS]++;
break;
case MOD_GRENADE:
case MOD_GRENADE_SPLASH:
if (attacker && attacker->client)
attacker->client->pers.records[REC_GRENADEKILLS]++;
self->client->pers.records[REC_GRENADEDEATHS]++;
break;
case MOD_KICK:
if (attacker && attacker->client)
attacker->client->pers.records[REC_KICKKILLS]++;
self->client->pers.records[REC_KICKDEATHS]++;
break;
}
ent->s.eventParm = meansOfDeath;
ent->s.otherEntityNum = self->s.number;
@ -706,6 +819,9 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
// if I committed suicide, the flag does not fall, it returns.
if (meansOfDeath == MOD_SUICIDE) {
// Elder: Statistics tracking
self->client->pers.records[REC_SUICIDES]++;
if ( self->client->ps.powerups[PW_NEUTRALFLAG] ) { // only happens in One Flag CTF
Team_ReturnFlag( TEAM_FREE );
self->client->ps.powerups[PW_NEUTRALFLAG] = 0;
@ -741,36 +857,6 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
//RQ3_ResetItem(bg_itemlist[self->client->ps.stats[STAT_HOLDABLE_ITEM]].giTag);
//self->client->ps.stats[STAT_HOLDABLE_ITEM] = 0;
//}
// Elder: weapons are smart enough to return themselves
/*
// Elder: obviously we don't worry about the pistol or knives here
weaponInventory = self->client->ps.stat[STAT_WEAPONS];
if ( (weaponInventory & (1 << WP_M3) ) == (1 << WP_M3) ) {
RQ3_ResetWeapon( WP_M3 );
self->client->pers.hadUniqueWeapon[ WP_M3 ] = qfalse;
}
if ( (weaponInventory & (1 << WP_M4) ) == (1 << WP_M4) ) {
RQ3_ResetWeapon( WP_M4 );
self->client->pers.hadUniqueWeapon[ WP_M4 ] = qfalse;
}
if ( (weaponInventory & (1 << WP_MP5) ) == (1 << WP_MP5) ) {
RQ3_ResetWeapon( WP_MP5 );
self->client->pers.hadUniqueWeapon[ WP_MP5 ] = qfalse;
}
if ( (weaponInventory & (1 << WP_HANDCANNON) ) == (1 << WP_HANDCANNON) ) {
RQ3_ResetWeapon( WP_HANDCANNON );
self->client->pers.hadUniqueWeapon[ WP_HANDCANNON ] = qfalse;
}
if ( (weaponInventory & (1 << WP_SSG3000) ) == (1 << WP_SSG3000) ) {
RQ3_ResetWeapon( WP_SSG3000 );
self->client->pers.hadUniqueWeapon[ WP_SSG3000 ] = qfalse;
}
self->client->uniqueWeapons = 0;
*/
}
#ifdef MISSIONPACK
TossClientPersistantPowerups( self );
@ -1620,13 +1706,29 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
impactRotation = impactRotation % 360; // Keep it in the 0-359 range
if (impactRotation < 90)
{
if (attacker->client)
attacker->client->pers.records[REC_BACKSHOTS]++;
targ->client->lasthurt_location = LOCATION_BACK;
}
else if (impactRotation < 180)
{
if (attacker->client)
attacker->client->pers.records[REC_RIGHTSHOTS]++;
targ->client->lasthurt_location = LOCATION_RIGHT;
}
else if (impactRotation < 270)
{
if (attacker->client)
attacker->client->pers.records[REC_FRONTSHOTS]++;
targ->client->lasthurt_location = LOCATION_FRONT;
}
else if (impactRotation < 360)
{
if (attacker->client)
attacker->client->pers.records[REC_LEFTSHOTS]++;
targ->client->lasthurt_location = LOCATION_LEFT;
}
else
targ->client->lasthurt_location = LOCATION_NONE;
@ -1681,6 +1783,8 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
{
case LOCATION_HEAD:
case LOCATION_FACE:
if (attacker->client)
attacker->client->pers.records[REC_HEADSHOTS]++;
//save headshot time for player_die
targ->client->headShotTime = level.time;
@ -1705,6 +1809,8 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
break;
case LOCATION_SHOULDER:
case LOCATION_CHEST:
if (attacker->client)
attacker->client->pers.records[REC_CHESTSHOTS]++;
//Vest stuff - is the knife supposed to be affected?
if (bg_itemlist[targ->client->ps.stats[STAT_HOLDABLE_ITEM]].giTag == HI_KEVLAR)
{
@ -1744,12 +1850,16 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
break;
case LOCATION_STOMACH:
case LOCATION_GROIN:
if (attacker->client)
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)
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;
@ -1815,25 +1925,45 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
targ->enemy = attacker;
targ->die (targ, inflictor, attacker, take, mod);
return;
}// else if ( targ->pain ) {
// targ->pain (targ, attacker, take);
//}
// Elder: why was this commented out?
} else if ( targ->pain ) {
targ->pain (targ, attacker, take);
}
}
/*
// Elder: crash code because conditional was missing
if (client)
{
if (!(targ->flags & FL_GODMODE) && (take)) targ->pain (targ, attacker, take);
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)
{
client->bleeding += take * BLEED_TIME;
// Elder: use the server FPS
int realBleedTime;
realBleedTime = trap_Cvar_VariableIntegerValue("sv_fps");
if (realBleedTime <= 0)
realBleedTime = BLEED_TIME;
client->bleeding += take * realBleedTime;
VectorSubtract (point, targ->r.absmax, targ->client->bleedloc_offset);
//G_Printf("(%d) = damage",damage);
//G_Printf("(%d) = bleeding",client->bleeding);
}
@ -1956,8 +2086,10 @@ qboolean G_RadiusDamage ( vec3_t origin, gentity_t *attacker, float damage, floa
if ( dist >= radius ) {
continue;
}
points = damage * ( 1.0 - dist / radius );
// Q2 radius damage
points = damage - 0.5f * dist;
// Q3 radius damage
//points = damage * ( 1.0 - dist / radius );
//Elder: reduce grenade damage if crouching
if (ent->r.maxs[2] < 20)

View file

@ -12,11 +12,19 @@
#define GAMEVERSION "reaction"
#define BODY_QUEUE_SIZE 8
//Blaze: How long someone bleeds for
#define BLEED_TIME 10 // 10 = 1 second is time for losing 1 health at slowest bleed rate
//Elder: Everyone knows you lose 6 health from the moment you start bandaging
//Let's enforce that in-code because it's sometimes 7 or even 8
#define BLEED_BANDAGE 6
// Blaze: How long someone bleeds for
// Elder: This doesn't work the same as Q2 because clients and servers can
// run independent "clocks." Normal servers send snapshots every 50ms
// (20 snapshots per second) so we double it from 10.
// Ideally, this number should match the server's sv_fps cvar value for those
// that run non-standard server frame rates.
#define BLEED_TIME 20
// Elder: Everyone knows you lose 6 health from the moment you start bandaging
// Let's enforce that in-code because it's sometimes 7 or even 8
// Elder: LOL it's 3, dumb Elder!
#define BLEED_BANDAGE 3
#define BLEED_BANDAGE_TIME 5400 // 27 x 2
// types of locations that can be hit
#define LOC_HDAM 1 // head
@ -263,7 +271,9 @@ typedef struct {
int voteCount; // to prevent people from constantly calling votes
int teamVoteCount; // to prevent people from constantly calling votes
qboolean teamInfo; // send team overlay updates?
qboolean hadUniqueWeapon[MAX_WEAPONS]; //Elder: for "ammo" in last gun
int sayTime; // Elder: say validation stuff
int sayCount;
int sayWarnings;
@ -271,6 +281,7 @@ typedef struct {
int sayMuteTime;
qboolean sayModerated; // so warnings are not repeated for multi-line, same-frame messages
int records[REC_NUM_RECORDS]; // Elder: for our statistics tracking
} clientPersistant_t;
@ -336,6 +347,7 @@ struct gclient_s {
//Blaze: For weapon stats
//Will need to pass these along in g_client to the new client after spawn
// Elder: to be merged into rq3Record_t for more comprehensive tracking
/*
int knifeShots;
int knifeHits;
int mk23Shots;
@ -354,7 +366,7 @@ struct gclient_s {
int akimboHits;
int grenShots;
int grenHits;
*/
int lastkilled_client; // last client that this client killed
int lasthurt_client; // last client that damaged this client
@ -392,21 +404,23 @@ struct gclient_s {
//Elder: C3A laser tutorial
gentity_t *lasersight; // lasersight OR flashlight if in use
int bleeding; //Blaze: remaining points to bleed away
int bleed_remain; //Blaze: How much left to bleed
int bleedloc; //Blaze: Where are we bleeding
// Bleeding server-only cvars
int bleeding; // Blaze: remaining points to bleed away
int bleed_remain; // Blaze: How much left to bleed
int bleedloc; // Blaze: Where are we bleeding
vec3_t bleedloc_offset; // Blaze: location of bleeding (from origin)
int bleed_delay; // Elder: time for next spurt of blood
vec3_t bleednorm;
//qboolean isBleeding; //Blaze: is client bleeding
// int legDamage; //Blaze: Client has leg damage - holds number of hits too
int bleedtick; //Blaze: Holds # of seconds till bleeding stops.
int bleedBandageCount; //Elder: hack to restrict amount of bleeding to 6 points
//qboolean isBleeding; // Blaze: is client bleeding
// int legDamage; // Blaze: Client has leg damage - holds number of hits too
int bleedtick; // Blaze: Holds # of seconds till bleeding stops.
int bleedBandageCount; // Elder: hack to restrict amount of bleeding to 3 points
int headShotTime; // Elder: got headshot?
//Elder: server only needs to know for sniper spread - ARGH
// int zoomed; // Hawkins (SSG zoom)
//qboolean semi; // hawkins (semiauto mode for m4, mp5, pistol)
int shots; //Blaze: Number of shots fired so far with this weapon
int shots; // Blaze: Number of shots fired so far with this weapon
int weaponfireNextTime; // for akimbos
int lastzoom; // Elder: save last zoom state when firing
@ -422,7 +436,6 @@ struct gclient_s {
int uniqueItems;
int killStreak; // Elder: replaces the old STAT_STREAK
qboolean kevlarHit; // Elder: kevlar hit -- FIXME: poor implementation
//int records[RECORD_TOTAL]; // Elder: for our awards when we implement it
#ifdef MISSIONPACK
@ -936,6 +949,7 @@ extern vmCvar_t g_proxMineTimeout;
//Blaze: Reaction cvars
extern vmCvar_t g_rxn_knifelimit;
extern vmCvar_t g_RQ3_maxWeapons;
extern vmCvar_t g_RQ3_statLog;
//Elder: spam protection cvars
extern vmCvar_t g_RQ3_messageMaxCount; // Max messages in interval
extern vmCvar_t g_RQ3_messageInterval; // Time interval for spam check

View file

@ -64,6 +64,7 @@ vmCvar_t g_listEntity;
//Blaze: Reaction cvars
vmCvar_t g_rxn_knifelimit;
vmCvar_t g_RQ3_maxWeapons;
vmCvar_t g_RQ3_statLog;
//Elder: spam protection cvars
vmCvar_t g_RQ3_messageMaxCount;
vmCvar_t g_RQ3_messageInterval;
@ -171,6 +172,7 @@ static cvarTable_t gameCvarTable[] = {
{ &g_rankings, "g_rankings", "0", 0, 0, qfalse},
//Blaze: Reaction stuff
{ &g_RQ3_maxWeapons, "g_RQ3_maxWeapons", "1",0,0, qtrue},
{ &g_RQ3_statLog, "sv_RQ3_statLog", "1", CVAR_ARCHIVE | CVAR_SERVERINFO, 0, qfalse},
{ &g_RQ3_messageMaxCount, "sv_RQ3_messageMaxCount", SAY_MAX_NUMBER, CVAR_ARCHIVE, 0, qfalse },
{ &g_RQ3_messageInterval, "sv_RQ3_messageInterval", SAY_PERIOD_TIME, CVAR_ARCHIVE, 0, qfalse },
{ &g_RQ3_messageMaxWarnings, "sv_RQ3_messageMaxWarnings", SAY_MAX_WARNINGS, CVAR_ARCHIVE, 0, qfalse },
@ -1159,6 +1161,60 @@ void LogExit( const char *string ) {
}
#endif
// Don't print bot statistics
if ( g_RQ3_statLog.integer && !(g_entities[cl - level.clients].r.svFlags & SVF_BOT) )
{
// Elder: Statistics tracking for server
G_LogPrintf( "-----------------------------------\n");
G_LogPrintf( "Reaction Quake 3 Statistics Results for client %i %s\n", level.sortedClients[i], cl->pers.netname );
G_LogPrintf( "Kicks: %i kills %i deaths %i\n", cl->pers.records[REC_KICKHITS],
cl->pers.records[REC_KICKKILLS], cl->pers.records[REC_KICKDEATHS]);
G_LogPrintf( "Knife Throw Stats: hits/shots %i/%i kills %i deaths %i\n",
cl->pers.records[REC_KNIFETHROWHITS], cl->pers.records[REC_KNIFETHROWSHOTS],
cl->pers.records[REC_KNIFETHROWKILLS], cl->pers.records[REC_KNIFETHROWDEATHS]);
G_LogPrintf( "Knife Slash Stats: hits/shots %i/%i kills %i deaths %i\n",
cl->pers.records[REC_KNIFESLASHHITS], cl->pers.records[REC_KNIFESLASHSHOTS],
cl->pers.records[REC_KNIFESLASHKILLS], cl->pers.records[REC_KNIFESLASHDEATHS]);
G_LogPrintf( "MK23 Stats: hits/shots %i/%i kills %i deaths %i\n",
cl->pers.records[REC_MK23HITS], cl->pers.records[REC_MK23SHOTS],
cl->pers.records[REC_MK23KILLS], cl->pers.records[REC_MK23DEATHS]);
G_LogPrintf( "MP5 Stats: hits/shots %i/%i kills %i deaths %i\n",
cl->pers.records[REC_MP5HITS], cl->pers.records[REC_MP5SHOTS],
cl->pers.records[REC_MP5KILLS], cl->pers.records[REC_MP5DEATHS]);
G_LogPrintf( "M4 Stats: hits/shots %i/%i kills %i deaths %i\n",
cl->pers.records[REC_M4HITS], cl->pers.records[REC_M4SHOTS],
cl->pers.records[REC_M4KILLS], cl->pers.records[REC_M4DEATHS]);
G_LogPrintf( "M3 Stats: hits/shots %i/%i kills %i deaths %i\n",
cl->pers.records[REC_M3HITS], cl->pers.records[REC_M3SHOTS],
cl->pers.records[REC_M3KILLS], cl->pers.records[REC_M3DEATHS]);
G_LogPrintf( "HC Stats: hits/shots %i/%i kills %i deaths %i\n",
cl->pers.records[REC_HANDCANNONHITS], cl->pers.records[REC_HANDCANNONSHOTS],
cl->pers.records[REC_HANDCANNONKILLS], cl->pers.records[REC_HANDCANNONDEATHS]);
G_LogPrintf( "SSG3000 Stats: hits/shots %i/%i kills %i deaths %i\n",
cl->pers.records[REC_SSG3000HITS], cl->pers.records[REC_SSG3000SHOTS],
cl->pers.records[REC_SSG3000KILLS], cl->pers.records[REC_SSG3000DEATHS]);
G_LogPrintf( "Akimbo Stats: hits/shots %i/%i kills %i deaths %i\n",
cl->pers.records[REC_AKIMBOHITS], cl->pers.records[REC_AKIMBOSHOTS],
cl->pers.records[REC_AKIMBOKILLS], cl->pers.records[REC_AKIMBODEATHS]);
G_LogPrintf( "Grenade Stats: hits/shots %i/%i kills %i deaths %i\n",
cl->pers.records[REC_GRENADEHITS], cl->pers.records[REC_GRENADESHOTS],
cl->pers.records[REC_GRENADEKILLS], cl->pers.records[REC_GRENADEDEATHS]);
G_LogPrintf( "Location Shot Stats 1: head %i chest %i stomach %i leg %i\n",
cl->pers.records[REC_HEADSHOTS], cl->pers.records[REC_CHESTSHOTS],
cl->pers.records[REC_STOMACHSHOTS], cl->pers.records[REC_LEGSHOTS]);
G_LogPrintf( "Location Shot Stats 2: front %i back %i left %i right %i\n",
cl->pers.records[REC_FRONTSHOTS], cl->pers.records[REC_BACKSHOTS],
cl->pers.records[REC_LEFTSHOTS], cl->pers.records[REC_RIGHTSHOTS]);
G_LogPrintf( "Location Kill Stats: head %i chest %i stomach %i leg %i\n",
cl->pers.records[REC_HEADKILLS], cl->pers.records[REC_CHESTKILLS],
cl->pers.records[REC_STOMACHKILLS], cl->pers.records[REC_LEGKILLS]);
G_LogPrintf( "Location Death Stats: head %i chest %i stomach %i leg %i\n",
cl->pers.records[REC_HEADDEATHS], cl->pers.records[REC_CHESTDEATHS],
cl->pers.records[REC_STOMACHDEATHS], cl->pers.records[REC_LEGDEATHS]);
G_LogPrintf( "Morbid Stats: corpse shots %i gib shots %i\n",
cl->pers.records[REC_CORPSESHOTS], cl->pers.records[REC_GIBSHOTS]);
G_LogPrintf( "-----------------------------------\n");
}
}
#ifdef MISSIONPACK
@ -1824,14 +1880,6 @@ start = trap_Milliseconds();
}
end = trap_Milliseconds();
// Elder: added for unique items
//if (level.time - level.uniqueItemsTime >= 30000)
//if (level.time % 30000 < 1)
//{
//level.uniqueItemsTime = level.time;
//RQ3_CheckUniqueItems();
//}
// see if it is time to do a tournement restart
CheckTournament();
@ -1862,9 +1910,9 @@ end = trap_Milliseconds();
/*
==============
Added by Elder
RQ3_StartUniqueItems
Added by Elder
Spawns items at the beginning of a level
==============
*/
@ -1900,10 +1948,5 @@ void RQ3_StartUniqueItems ( void )
rq3_temp = (gentity_t*)SelectRandomDeathmatchSpawnPoint();
Drop_Item (rq3_temp, rq3_item, angle);
angle += 30;
//rq3_item = BG_FindItem( "Kevlar Vest" );
//rq3_item = BG_FindItemForHoldable( HI_SLIPPERS );
//rq3_temp = SelectSpawnPoint(ent->client->ps.origin,spawn_origin, spawn_angles);
//Drop_Item (rq3_temp, rq3_item, 0);
}

View file

@ -65,8 +65,13 @@ void G_ExplodeMissile( gentity_t *ent ) {
if( G_RadiusDamage( ent->r.currentOrigin, ent->parent, ent->splashDamage, ent->splashRadius, ent
, ent->splashMethodOfDeath ) ) {
g_entities[ent->r.ownerNum].client->accuracy_hits++;
if (ent->s.weapon == WP_KNIFE)g_entities[ent->r.ownerNum].client->knifeHits++;
if (ent->s.weapon == WP_GRENADE)g_entities[ent->r.ownerNum].client->grenHits++;
// Elder: Statistics tracking
if (ent->s.weapon == WP_KNIFE)
g_entities[ent->r.ownerNum].client->pers.records[REC_KNIFETHROWHITS]++;
//g_entities[ent->r.ownerNum].client->knifeHits++;
if (ent->s.weapon == WP_GRENADE)
g_entities[ent->r.ownerNum].client->pers.records[REC_GRENADEHITS]++;
//g_entities[ent->r.ownerNum].client->grenHits++;
}
}
//Elder: huhh?
@ -309,8 +314,13 @@ void G_MissileImpact( gentity_t *ent, trace_t *trace ) {
if ( ent->damage ) {
if( LogAccuracyHit( other, &g_entities[ent->r.ownerNum] ) ) {
g_entities[ent->r.ownerNum].client->accuracy_hits++;
if (ent->s.weapon == WP_KNIFE)g_entities[ent->r.ownerNum].client->knifeHits++;
if (ent->s.weapon == WP_GRENADE)g_entities[ent->r.ownerNum].client->grenHits++;
// Elder: Statistics tracking
if (ent->s.weapon == WP_KNIFE)
g_entities[ent->r.ownerNum].client->pers.records[REC_KNIFETHROWHITS]++;
//g_entities[ent->r.ownerNum].client->knifeHits++;
if (ent->s.weapon == WP_GRENADE)
g_entities[ent->r.ownerNum].client->pers.records[REC_GRENADEHITS]++;
//g_entities[ent->r.ownerNum].client->grenHits++;
hitClient = qtrue;
}
BG_EvaluateTrajectoryDelta( &ent->s.pos, level.time, velocity );
@ -515,8 +525,13 @@ void G_MissileImpact( gentity_t *ent, trace_t *trace ) {
other, ent->splashMethodOfDeath ) ) {
if( !hitClient ) {
g_entities[ent->r.ownerNum].client->accuracy_hits++;
if (ent->s.weapon == WP_KNIFE)g_entities[ent->r.ownerNum].client->knifeHits++;
if (ent->s.weapon == WP_GRENADE)g_entities[ent->r.ownerNum].client->grenHits++;
// Elder: Statistics tracking
if (ent->s.weapon == WP_KNIFE)
g_entities[ent->r.ownerNum].client->pers.records[REC_KNIFETHROWHITS]++;
//g_entities[ent->r.ownerNum].client->knifeHits++;
if (ent->s.weapon == WP_GRENADE)
g_entities[ent->r.ownerNum].client->pers.records[REC_GRENADEHITS]++;
//g_entities[ent->r.ownerNum].client->grenHits++;
}
}
}
@ -699,12 +714,22 @@ fire_grenade
gentity_t *fire_grenade (gentity_t *self, vec3_t start, vec3_t dir) {
gentity_t *bolt;
int speed;
vec3_t up, right;
if (self->client)
AngleVectors( self->client->ps.viewangles, NULL, right, up);
else
{
// just in case we put those shooters back
up[0] = up[1] = up[2] = 0;
right[0] = right[1] = right[2] = 0;
}
VectorNormalize (dir);
bolt = G_Spawn();
bolt->classname = "grenade";
bolt->nextthink = level.time + 2500;
bolt->nextthink = level.time + 2000; // Action had 2 seconds
bolt->think = G_ExplodeMissile;
bolt->s.eType = ET_MISSILE;
bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN;
@ -726,6 +751,9 @@ gentity_t *fire_grenade (gentity_t *self, vec3_t start, vec3_t dir) {
//Elder: grenade toggle distances/speeds
if ( self->client) {
// Elder: Statistics tracking
self->client->pers.records[REC_GRENADESHOTS]++;
if ( self->client->ps.stats[STAT_HEALTH] <= 0 ||
(self->client->ps.stats[STAT_RQ3] & RQ3_BANDAGE_WORK) == RQ3_BANDAGE_WORK) {
//Always drop close range if dead or about to bandage
@ -752,7 +780,10 @@ gentity_t *fire_grenade (gentity_t *self, vec3_t start, vec3_t dir) {
}
VectorScale( dir, speed, bolt->s.pos.trDelta );
VectorMA (bolt->s.pos.trDelta, 200 + crandom() * 10.0f, up, bolt->s.pos.trDelta);
VectorMA (bolt->s.pos.trDelta, crandom() * 10.0f, right, bolt->s.pos.trDelta);
SnapVector( bolt->s.pos.trDelta ); // save net bandwidth
VectorCopy (start, bolt->r.currentOrigin);
@ -792,6 +823,11 @@ gentity_t *fire_knife (gentity_t *self, vec3_t start, vec3_t dir)
VectorCopy (dir, bolt->s.apos.trBase);
VectorCopy (dir, bolt->r.currentAngles);
if (self->client)
{
// Elder: Statistics tracking
self->client->pers.records[REC_KNIFETHROWSHOTS]++;
}
//Elder: not needed anymore
//Saving stuff for Makro's knife equations
//VectorCopy( start, bolt->s.origin2);

View file

@ -98,6 +98,8 @@ qboolean JumpKick( gentity_t *ent )
else {
G_Damage( traceEnt, ent, ent, forward, tr.endpos,
damage, DAMAGE_NO_LOCATIONAL, MOD_KICK );
if (ent->client)
ent->client->pers.records[REC_KICKHITS]++;
}
// send blood impact + event stuff
@ -335,9 +337,30 @@ void Bullet_Fire (gentity_t *ent, float spread, int damage, int MOD ) {
float r;
float u;
gentity_t *tent;
gentity_t *tent2;
gentity_t *traceEnt;
int i, passent;
// Elder: Statistics tracking
if (ent->client)
{
switch (MOD)
{
case MOD_PISTOL:
ent->client->pers.records[REC_MK23SHOTS]++;
break;
case MOD_M4:
ent->client->pers.records[REC_M4SHOTS]++;
break;
case MOD_MP5:
ent->client->pers.records[REC_MP5SHOTS]++;
break;
case MOD_AKIMBO:
ent->client->pers.records[REC_AKIMBOSHOTS]++;
break;
}
}
//Elder: removed - for some reason it's set to 0
//damage *= s_quadFactor;
@ -397,25 +420,30 @@ void Bullet_Fire (gentity_t *ent, float spread, int damage, int MOD ) {
//tent->s.eventParm = traceEnt->s.number;
tent->s.eventParm = DirToByte(forward);
tent->s.otherEntityNum2 = traceEnt->s.number;
tent->s.otherEntityNum = ent->s.number;
}
if( LogAccuracyHit( traceEnt, ent ) ) {
ent->client->accuracy_hits++;
// Elder: Statistics tracking
switch (MOD)
{
case MOD_PISTOL:
ent->client->mk23Hits++;
break;
case MOD_M4:
ent->client->m4Hits++;
break;
case MOD_MP5:
ent->client->mp5Hits++;
break;
case MOD_AKIMBO:
ent->client->akimboHits++;
break;
case MOD_PISTOL:
ent->client->pers.records[REC_MK23HITS]++;
//ent->client->mk23Hits++;
break;
case MOD_M4:
ent->client->pers.records[REC_M4HITS]++;
//ent->client->m4Hits++;
break;
case MOD_MP5:
ent->client->pers.records[REC_MP5HITS]++;
//ent->client->mp5Hits++;
break;
case MOD_AKIMBO:
ent->client->pers.records[REC_AKIMBOHITS]++;
//ent->client->akimboHits++;
break;
}
}
//Elder: *******************TEST CODE *****************
@ -426,11 +454,13 @@ void Bullet_Fire (gentity_t *ent, float spread, int damage, int MOD ) {
(tr.surfaceFlags & SURF_METAL2) ) {
tent = G_TempEntity( tr.endpos, EV_BULLET_HIT_METAL );
tent->s.eventParm = DirToByte( tr.plane.normal );
tent->s.otherEntityNum = ent->s.number;
} else {
tent = G_TempEntity( tr.endpos, EV_BULLET_HIT_WALL );
tent->s.eventParm = DirToByte( tr.plane.normal );
tent->s.otherEntityNum = ent->s.number;
}
tent->s.otherEntityNum = ent->s.number;
//tent->s.otherEntityNum = ent->s.number;
//G_Printf("Surfaceflags: %d\n", tr.surfaceFlags);
if ( traceEnt->takedamage) {
@ -456,10 +486,12 @@ void Bullet_Fire (gentity_t *ent, float spread, int damage, int MOD ) {
// FIXME: poor implementation
if (traceEnt->client && bg_itemlist[traceEnt->client->ps.stats[STAT_HOLDABLE_ITEM]].giTag == HI_KEVLAR) {
if (traceEnt->client->kevlarHit == qfalse) {
tent = G_TempEntity( tr.endpos, EV_BULLET_HIT_FLESH );
tent2 = G_TempEntity( tr.endpos, EV_BULLET_HIT_FLESH );
//tent->s.eventParm = traceEnt->s.number;
tent->s.eventParm = DirToByte(forward);
tent->s.otherEntityNum2 = traceEnt->s.number;
tent2->s.eventParm = DirToByte(forward);
tent2->s.otherEntityNum2 = traceEnt->s.number;
// Need this?
tent2->s.otherEntityNum = ent->s.number;
}
else
traceEnt->client->kevlarHit = qfalse;
@ -597,12 +629,22 @@ void ShotgunPattern( vec3_t origin, vec3_t origin2, int seed, gentity_t *ent, in
//Elder: added
if (shotType == WP_M3)
{
// Elder: Statistics tracking
ent->client->pers.records[REC_M3SHOTS]++;
count = DEFAULT_M3_COUNT;
else if (shotType == WP_HANDCANNON) {
}
else if (shotType == WP_HANDCANNON)
{
// Elder: Statistics tracking
ent->client->pers.records[REC_HANDCANNONSHOTS]++;
count = DEFAULT_HANDCANNON_COUNT;
hc_multipler = 4;
}
else {
else
{
// Elder: Statistics tracking
ent->client->pers.records[REC_HANDCANNONSHOTS]++;
count = DEFAULT_HANDCANNON_COUNT;
hc_multipler = 5;
}
@ -631,13 +673,16 @@ void ShotgunPattern( vec3_t origin, vec3_t origin2, int seed, gentity_t *ent, in
if( ShotgunPellet( origin, end, ent ) && !hitClient ) {
hitClient = qtrue;
ent->client->accuracy_hits++;
// Elder: Statistics tracking
switch (shotType)
{
case WP_M3:
ent->client->m3Hits++;
ent->client->pers.records[REC_M3HITS]++;
//ent->client->m3Hits++;
break;
case WP_HANDCANNON:
ent->client->hcHits++;
ent->client->pers.records[REC_HANDCANNONHITS]++;
//ent->client->hcHits++;
break;
}
}
@ -1054,6 +1099,9 @@ void Knife_Attack ( gentity_t *self, int damage)
gentity_t *hitent;
gentity_t *tent;
if (self->client)
self->client->pers.records[REC_KNIFESLASHSHOTS]++;
VectorMA( muzzle, KNIFE_RANGE, forward, end );
trap_Trace (&tr, muzzle, NULL, NULL, end, self->s.number, MASK_SHOT);
hitent = &g_entities[ tr.entityNum ];
@ -1072,6 +1120,8 @@ void Knife_Attack ( gentity_t *self, int damage)
{
tent = G_TempEntity(tr.endpos, EV_RQ3_SOUND);
tent->s.eventParm = RQ3_SOUND_KNIFEHIT;
if (self->client)
self->client->pers.records[REC_KNIFESLASHHITS]++;
}
}
else
@ -1401,6 +1451,9 @@ void Weapon_SSG3000_Fire (gentity_t *ent) {
float u;
float spread;
// Elder: Statistics tracking
if (ent->client)
ent->client->pers.records[REC_SSG3000SHOTS]++;
VectorMA (muzzle, 8192*16, forward, end);
@ -1595,7 +1648,8 @@ void Weapon_SSG3000_Fire (gentity_t *ent) {
ent->client->rewardTime = level.time + REWARD_SPRITE_TIME;
}
ent->client->accuracy_hits++;
ent->client->ssgHits++;
ent->client->pers.records[REC_SSG3000HITS]++;
//ent->client->ssgHits++;
}
//Elder: bolt action plus save last zoom
@ -1770,10 +1824,10 @@ void Weapon_Akimbo_Fire(gentity_t *ent)
Bullet_Fire( ent, RQ3_Spread(ent, spread), AKIMBO_DAMAGE, MOD_AKIMBO);
//Elder: reset plus added 1 bullet check
if (ent->client->weaponfireNextTime > 0 || ent->client->ps.ammo[WP_AKIMBO] < 2)
ent->client->weaponfireNextTime = 0;
else
ent->client->weaponfireNextTime = level.time + RQ3_AKIMBO_DELAY2;
//if (ent->client->weaponfireNextTime > 0 || ent->client->ps.ammo[WP_AKIMBO] < 2)
//ent->client->weaponfireNextTime = 0;
//else
//ent->client->weaponfireNextTime = level.time + RQ3_AKIMBO_DELAY2;
//Bullet_Fire( ent, RQ3_Spread(ent, spread), AKIMBO_DAMAGE, MOD_AKIMBO);
}
@ -1788,7 +1842,8 @@ void Weapon_Grenade_Fire(gentity_t *ent)
gentity_t *m;
// extra vertical velocity
forward[2] += 0.5f;
// Elder: not present in AQ2
//forward[2] += 0.5f;
VectorNormalize( forward );
m = fire_grenade (ent, muzzle, forward);
@ -1823,6 +1878,8 @@ qboolean LogAccuracyHit( gentity_t *target, gentity_t *attacker ) {
}
if( target->client->ps.stats[STAT_HEALTH] <= 0 ) {
// Elder: Statistics tracking
attacker->client->pers.records[REC_CORPSESHOTS]++;
return qfalse;
}
@ -1909,40 +1966,40 @@ void FireWeapon( gentity_t *ent ) {
//Blaze: The functions get called when you shoot your gun
case WP_KNIFE:
Weapon_Knife_Fire (ent);
ent->client->knifeShots++;
//ent->client->knifeShots++;
break;
case WP_GRENADE:
Weapon_Grenade_Fire ( ent );
ent->client->grenShots++;
//ent->client->grenShots++;
break;
case WP_PISTOL:
Weapon_MK23_Fire ( ent );
ent->client->mk23Shots++;
//ent->client->mk23Shots++;
break;
case WP_M4:
Weapon_M4_Fire ( ent );
ent->client->m4Shots++;
//ent->client->m4Shots++;
break;
case WP_SSG3000:
//Weapon_SSG3000_FireOld( ent );
Weapon_SSG3000_Fire ( ent );
ent->client->ssgShots++;
//ent->client->ssgShots++;
break;
case WP_MP5:
Weapon_MP5_Fire ( ent );
ent->client->mp5Shots++;
//ent->client->mp5Shots++;
break;
case WP_HANDCANNON:
Weapon_HandCannon_Fire ( ent );
ent->client->hcShots++;
//ent->client->hcShots++;
break;
case WP_M3:
Weapon_M3_Fire ( ent );
ent->client->m3Shots++;
//ent->client->m3Shots++;
break;
case WP_AKIMBO:
Weapon_Akimbo_Fire ( ent );
ent->client->akimboShots++;
//ent->client->akimboShots++;
break;
#ifdef MISSIONPACK
case WP_NAILGUN:

View file

@ -6,20 +6,30 @@ void CheckBleeding(gentity_t *targ)
{
int damage;
int temp;
int realBleedTime;
gentity_t *tent;
// Elder: use the server's FPS as a basis for bleed time
realBleedTime = trap_Cvar_VariableIntegerValue( "sv_fps" );
// just safety check it
if (realBleedTime <= 0)
realBleedTime = BLEED_TIME;
if (!(targ->client->bleeding) || (targ->health <=0)) return;
if (!(targ->client->bleeding) || (targ->health <=0))
return;
temp = (int)(targ->client->bleeding * .2);
temp = (int)(targ->client->bleeding * 0.2f);
targ->client->bleeding -= temp;
if (temp <= 0) temp = 1;
if (temp <= 0)
temp = 1;
targ->client->bleed_remain += temp;
damage = (int)(targ->client->bleed_remain/BLEED_TIME);
damage = (int)(targ->client->bleed_remain/realBleedTime);
if (targ->client->bleed_remain >= BLEED_TIME)
if (targ->client->bleed_remain >= realBleedTime)
{
//G_Printf("Bleed Remain: %i\n", targ->client->bleed_remain);
//G_Printf("Bleed Remain: %i Server Time: %i\n", targ->client->bleed_remain, level.time);
if ( (targ->client->ps.stats[STAT_RQ3] & RQ3_BANDAGE_WORK) == RQ3_BANDAGE_WORK &&
targ->client->bleedBandageCount < 1)
{
@ -46,7 +56,21 @@ void CheckBleeding(gentity_t *targ)
}
else
{
targ->client->bleed_remain %= BLEED_TIME;
targ->client->bleed_remain %= realBleedTime;
}
if (targ->client->bleed_delay <= level.time)
{
vec3_t bleedOrigin;
targ->client->bleed_delay = level.time + 2000; // 2 seconds
VectorAdd(targ->client->bleedloc_offset, targ->r.absmax, bleedOrigin);
//gi.cprintf(ent, PRINT_HIGH, "Bleeding now.\n");
//EjectBlooder(ent, pos, pos);
// do bleeding
//tent = G_TempEntity(bleedOrigin, EV_EJECTBLOOD);
}
}
}
@ -71,8 +95,8 @@ void StartBandage(gentity_t *ent)
if ( temp <= 0 )
temp = 1;
ent->client->bleed_remain += temp;
damage = (int)(ent->client->bleed_remain/BLEED_TIME);
if ( ent->client->bleed_remain >= BLEED_TIME )
damage = (int)(ent->client->bleed_remain/realBleedTime);
if ( ent->client->bleed_remain >= realBleedTime )
{
ent->health -= damage;
if ( damage > 1 )
@ -88,7 +112,7 @@ void StartBandage(gentity_t *ent)
}
else
{
ent->client->bleed_remain %= BLEED_TIME;
ent->client->bleed_remain %= realBleedTime;
}
if (ent->client->bleeddelay <= level.time)
{