From 683be360169f5feb9f002abca298a9cc5c62389b Mon Sep 17 00:00:00 2001 From: Victor Chow Date: Tue, 26 Jun 2001 02:06:50 +0000 Subject: [PATCH] Elder: Locational obits plus several Reaction cmd fixes and game fixes --- reaction/game/bg_misc.c | 6 +++ reaction/game/bg_pmove.c | 31 +++++++++-- reaction/game/bg_public.h | 4 ++ reaction/game/g_active.c | 4 +- reaction/game/g_cmds.c | 8 +-- reaction/game/g_combat.c | 111 ++++++++++++++++++++++++++++++-------- reaction/game/g_local.h | 4 ++ reaction/game/g_weapon.c | 81 +++++++++++++++++++++++++++- 8 files changed, 216 insertions(+), 33 deletions(-) diff --git a/reaction/game/bg_misc.c b/reaction/game/bg_misc.c index e2ca4640..756db730 100644 --- a/reaction/game/bg_misc.c +++ b/reaction/game/bg_misc.c @@ -1254,6 +1254,12 @@ char *eventnames[] = { "EV_DEATH2", "EV_DEATH3", "EV_OBITUARY", + //Elder: + //Location-specific obits- need separate events b/c you can't stuff >8bits in eventParm + "EV_OBITUARY_HEAD", + "EV_OBITUARY_CHEST", + "EV_OBITUARY_STOMACH", + "EV_OBITUARY_LEGS", "EV_POWERUP_QUAD", "EV_POWERUP_BATTLESUIT", diff --git a/reaction/game/bg_pmove.c b/reaction/game/bg_pmove.c index 877820ea..7bf46064 100644 --- a/reaction/game/bg_pmove.c +++ b/reaction/game/bg_pmove.c @@ -1927,14 +1927,21 @@ static void PM_Weapon( void ) { pm->ps->weaponstate = WEAPON_FIRING; - // check for out of ammo or one bullet in akimbo - if ( ! pm->ps->ammo[ pm->ps->weapon ] || - pm->ps->weapon == WP_AKIMBO && pm->ps->ammo[ pm->ps->weapon ] == 1) { + // check for out of ammo + if ( ! pm->ps->ammo[ pm->ps->weapon ]) { PM_AddEvent( EV_NOAMMO ); pm->ps->weaponTime += 500; return; } + //if ( ! pm->ps->ammo[ pm->ps->weapon ] || + //pm->ps->weapon == WP_AKIMBO && pm->ps->ammo[ pm->ps->weapon ] == 1) { + //PM_AddEvent( EV_NOAMMO ); + //pm->ps->weaponTime += 500; + //return; + //} + + // take an ammo away if not infinite if ( pm->ps->ammo[ pm->ps->weapon ] != -1 ) { //Blaze: Dont remove ammo for knife @@ -1944,9 +1951,15 @@ static void PM_Weapon( void ) { pm->ps->ammo[ pm->ps->weapon ]--; } //Elder: remove one more bullet/shell if handcannon/akimbo - if (pm->ps->weapon == WP_HANDCANNON || pm->ps->weapon == WP_AKIMBO) { + if (pm->ps->weapon == WP_HANDCANNON) { pm->ps->ammo[ pm->ps->weapon ]--; } + + //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 ] --; + } + //Elder: sync bullets a la AQ2 style if (pm->ps->weapon == WP_AKIMBO && pm->ps->ammo[pm->ps->weapon] < 12) { pm->ps->ammo[WP_PISTOL] = pm->ps->ammo[WP_AKIMBO]; @@ -1955,6 +1968,9 @@ static void PM_Weapon( void ) { pm->ps->ammo[WP_AKIMBO]--; } } + + + // fire weapon PM_AddEvent( EV_FIRE_WEAPON ); @@ -2024,6 +2040,13 @@ static void PM_Weapon( void ) { } pm->ps->weaponTime += addTime; + + //Auto-switch when out of ammo with grenade or knife + if ( (pm->ps->weapon == WP_KNIFE || pm->ps->weapon == WP_GRENADE) && + !pm->ps->ammo[ pm->ps->weapon ]) { + PM_AddEvent( EV_NOAMMO ); + pm->ps->weaponTime += 150; + } } /* diff --git a/reaction/game/bg_public.h b/reaction/game/bg_public.h index 6b7969a8..9769f490 100644 --- a/reaction/game/bg_public.h +++ b/reaction/game/bg_public.h @@ -656,6 +656,10 @@ typedef enum { EV_DEATH2, EV_DEATH3, EV_OBITUARY, + EV_OBITUARY_HEAD, + EV_OBITUARY_CHEST, + EV_OBITUARY_STOMACH, + EV_OBITUARY_LEGS, EV_POWERUP_QUAD, EV_POWERUP_BATTLESUIT, diff --git a/reaction/game/g_active.c b/reaction/game/g_active.c index 2a96ccd1..caab45e6 100644 --- a/reaction/game/g_active.c +++ b/reaction/game/g_active.c @@ -171,7 +171,9 @@ void P_DamageFeedback( gentity_t *player ) { // play an appropriate pain sound if ( (level.time > player->pain_debounce_time) && !(player->flags & FL_GODMODE) ) { - player->pain_debounce_time = level.time + 700; + //player->pain_debounce_time = level.time + 700; + //Elder: reduced pain debounce time so we can have a few more sounds :) + player->pain_debounce_time = level.time + 250; switch ( client->lasthurt_location & ~(LOCATION_BACK | LOCATION_LEFT | LOCATION_RIGHT | LOCATION_FRONT) ) { diff --git a/reaction/game/g_cmds.c b/reaction/game/g_cmds.c index 4af224ad..30861546 100644 --- a/reaction/game/g_cmds.c +++ b/reaction/game/g_cmds.c @@ -1800,13 +1800,13 @@ void Cmd_Reload( gentity_t *ent ) { //check for fast reloads if (ent->client->fastReloads) { //Fast reload - G_Printf("Using fast reloads\n"); + //G_Printf("Using fast reloads\n"); delay = RQ3_M3_FAST_RELOAD_DELAY; ent->client->fastReloads = 1; } else { //Regular reload - G_Printf("Using regular reloads\n"); + //G_Printf("Using regular reloads\n"); delay = RQ3_M3_RELOAD_DELAY; ent->client->fastReloads = 0; } @@ -1887,13 +1887,13 @@ void Cmd_Reload( gentity_t *ent ) { //check for fast reloads if (ent->client->fastReloads) { //Fast reload - G_Printf("Using fast reloads\n"); + //G_Printf("Using fast reloads\n"); delay = RQ3_SSG3000_FAST_RELOAD_DELAY; ent->client->fastReloads = 1; } else { //Regular reload - G_Printf("Using regular reloads\n"); + //G_Printf("Using regular reloads\n"); delay = RQ3_SSG3000_RELOAD_DELAY; ent->client->fastReloads = 0; } diff --git a/reaction/game/g_combat.c b/reaction/game/g_combat.c index 5ba25552..31a2ead2 100644 --- a/reaction/game/g_combat.c +++ b/reaction/game/g_combat.c @@ -585,7 +585,18 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int self->client->pers.netname, obit ); // broadcast the death event to everyone - ent = G_TempEntity( self->r.currentOrigin, EV_OBITUARY ); + // Elder: use appropriate obit event + if ( (self->client->lasthurt_location & LOCATION_HEAD) == LOCATION_HEAD) + ent = G_TempEntity( self->r.currentOrigin, EV_OBITUARY_HEAD ); + else if ( (self->client->lasthurt_location & LOCATION_CHEST) == LOCATION_CHEST) + ent = G_TempEntity( self->r.currentOrigin, EV_OBITUARY_CHEST ); + else if ( (self->client->lasthurt_location & LOCATION_STOMACH) == LOCATION_STOMACH) + ent = G_TempEntity( self->r.currentOrigin, EV_OBITUARY_STOMACH ); + else if ( (self->client->lasthurt_location & LOCATION_LEG) == LOCATION_LEG) + ent = G_TempEntity( self->r.currentOrigin, EV_OBITUARY_LEGS ); + else + ent = G_TempEntity( self->r.currentOrigin, EV_OBITUARY ); + ent->s.eventParm = meansOfDeath; ent->s.otherEntityNum = self->s.number; ent->s.otherEntityNum2 = killer; @@ -636,8 +647,9 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int DMReward->r.svFlags = SVF_BROADCAST; } - if( meansOfDeath == MOD_GAUNTLET ) { - + //if( meansOfDeath == MOD_GAUNTLET ) { + //Elder: changed to knife slash heh + if( meansOfDeath == MOD_KNIFE ) { // play humiliation on player //Blaze: Removed because it uses the persistant stats stuff //attacker->client->ps.persistant[PERS_GAUNTLET_FRAG_COUNT]++; @@ -1335,9 +1347,10 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, // always give half damage if hurting self // calculated after knockback, so rocket jumping works - if ( targ == attacker) { - damage *= 0.5; - } + //Elder: no way >:) + //if ( targ == attacker) { + //damage *= 0.5; + //} if ( damage < 1 ) { damage = 1; @@ -1396,20 +1409,51 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, if ( point && targ && targ->health > 0 && attacker && take) { - // First things first. If we're not damaging them, why are we here? + // First things first. If we're not damaging them, why are we here? + //Elder: removed M3, handcannon, and grenades from location damage code + + if (take && + mod == MOD_M3 || + mod == MOD_HANDCANNON || + mod == MOD_GRENADE || + 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) + { + //Elder: do shotgun report like AQ2 + int playernum = targ - g_entities; + + playernum--; + if (playernum >= 0 && playernum <= MAX_CLIENTS - 1) + tookShellHit[playernum] = 1; + } + else { + //Grenade stuff + trap_SendServerCommand( attacker-g_entities, va("print \"You hit %s^7\n\"", targ->client->pers.netname)); + } + } - 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) - { + + 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; @@ -1470,11 +1514,27 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, //G_Printf("In loc damage: %d incomming\n",take); // Check the location ignoring the rotation info - if (mod == MOD_HANDCANNON || mod == MOD_M3 || mod == MOD_GRENADE || mod == MOD_GRENADE_SPLASH ) + //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; + + 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 + else */ + if (1) { switch ( targ->client->lasthurt_location & ~(LOCATION_BACK | LOCATION_LEFT | LOCATION_RIGHT | LOCATION_FRONT) ) @@ -1566,7 +1626,7 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, // G_Printf("(%d) taken as damage\n",take); if (instant_dam) { - G_Printf("(%d) instant damage\n",take); + //G_Printf("(%d) instant damage\n",take); targ->health = targ->health - take; } if ( targ->client ) { @@ -1731,6 +1791,12 @@ qboolean G_RadiusDamage ( vec3_t origin, gentity_t *attacker, float damage, floa points = damage * ( 1.0 - dist / radius ); + //Elder: reduce grenade damage if crouching + if (ent->r.maxs[2] < 20) + { + points = points * 0.5; // hefty reduction in damage + } + if( CanDamage (ent, origin) ) { if( LogAccuracyHit( ent, attacker ) ) { hitClient = qtrue; @@ -1739,6 +1805,7 @@ qboolean G_RadiusDamage ( vec3_t origin, gentity_t *attacker, float damage, floa // push the center of mass higher than the origin so players // get knocked into the air more dir[2] += 24; + G_Damage (ent, NULL, attacker, dir, origin, (int)points, DAMAGE_RADIUS, mod); } } diff --git a/reaction/game/g_local.h b/reaction/game/g_local.h index 34b18a63..20cc4bac 100644 --- a/reaction/game/g_local.h +++ b/reaction/game/g_local.h @@ -649,6 +649,10 @@ qboolean CheckGauntletAttack( gentity_t *ent ); //Blaze: No need for these because no gauntlet //void Weapon_HookFree (gentity_t *ent); //void Weapon_HookThink (gentity_t *ent); +//Elder: for shotgun damage reports +void RQ3_InitShotgunDamageReport( void ); +void RQ3_ProduceShotgunDamageReport(gentity_t *self); +extern int tookShellHit[MAX_CLIENTS]; // diff --git a/reaction/game/g_weapon.c b/reaction/game/g_weapon.c index 591cacfc..8b252850 100644 --- a/reaction/game/g_weapon.c +++ b/reaction/game/g_weapon.c @@ -13,6 +13,9 @@ static float s_quadFactor; static vec3_t forward, right, up; static vec3_t muzzle; +//Elder: used for shell damage - we have no more malloc function so make it static? +int tookShellHit[MAX_CLIENTS]; + #define NUM_NAILSHOTS 10 /* @@ -1068,6 +1071,9 @@ void Weapon_HandCannon_Fire(gentity_t *ent) { gentity_t *tent, *tent2; + //Elder: added for damage report + RQ3_InitShotgunDamageReport(); + // send shotgun blast tent = G_TempEntity( muzzle, EV_HANDCANNON ); VectorScale( forward, 4096, tent->s.origin2 ); @@ -1086,6 +1092,8 @@ void Weapon_HandCannon_Fire(gentity_t *ent) //Elder: note negative one ShotgunPattern(tent2->s.pos.trBase, tent2->s.origin2, tent2->s.eventParm, ent, -1 ); + //Elder: added for damage report + RQ3_ProduceShotgunDamageReport(ent); } /* ============ @@ -1097,6 +1105,9 @@ void Weapon_M3_Fire(gentity_t *ent) //Blaze: call to shotgun fire function here gentity_t *tent; + //Elder: added for damage report + RQ3_InitShotgunDamageReport(); + // send shotgun blast tent = G_TempEntity( muzzle, EV_SHOTGUN ); VectorScale( forward, 4096, tent->s.origin2 ); @@ -1105,6 +1116,72 @@ void Weapon_M3_Fire(gentity_t *ent) tent->s.otherEntityNum = ent->s.number; ShotgunPattern( tent->s.pos.trBase, tent->s.origin2, tent->s.eventParm, ent, WP_M3 ); + + //Elder: added for damage report + RQ3_ProduceShotgunDamageReport(ent); +} + +/* +============== +RQ3_ShotgunDamageReport + +Added by Elder +Used to determine hits from a shotgun source +Modelled after the one done for AQ2 +============== +*/ + +void RQ3_InitShotgunDamageReport( void ) +{ + //Elder: Reset all tookShellHit 'slots' to zero + memset(tookShellHit, 0, MAX_CLIENTS * sizeof(int)); +} + +//Elder: almost straight out of the AQ2 source +void RQ3_ProduceShotgunDamageReport(gentity_t *self) +{ + + int l; + int total_to_print = 0; + int printed = 0; + static char textbuf[1024]; + + for (l = 1; l <= g_maxclients.integer; l++) + { + if (tookShellHit[l - 1]) + total_to_print++; + } + + if (total_to_print) + { + if (total_to_print > 10) + total_to_print = 10; + + strcpy(textbuf, "You hit "); + for (l = 1; l <= g_maxclients.integer; l++) + { + if (tookShellHit[l - 1]) + { + if (printed == (total_to_print - 1)) + { + if (total_to_print == 2) + strcat(textbuf, " and "); + else if (total_to_print != 1) + strcat(textbuf, ", and "); + } + else if (printed) + strcat(textbuf, ", "); + + strcat(textbuf, g_entities[l].client->pers.netname); + //strcat(textbuf, g_edicts[l].client->pers.netname); + printed++; + } + if (printed == total_to_print) + break; + } + trap_SendServerCommand( self-g_entities, va("print \"%s^7\n\"", textbuf)); + //gi.cprintf(self, PRINT_HIGH, "%s\n", textbuf); + } } /* @@ -1119,8 +1196,8 @@ void Weapon_Akimbo_Fire(gentity_t *ent) spread = AKIMBO_SPREAD; Bullet_Fire( ent, RQ3Spread(ent, spread), AKIMBO_DAMAGE, MOD_AKIMBO); - //Elder: reset - if (ent->client->weaponfireNextTime > 0) + //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;