Fixes a serious sniper rifle shot crash
This commit is contained in:
Victor Chow 2001-07-01 20:20:56 +00:00
parent fc11d6fe2e
commit 316a3ae002
3 changed files with 84 additions and 30 deletions

View file

@ -1496,17 +1496,19 @@ void ClientEndFrame( gentity_t *ent ) {
ent->client->ps.stats[STAT_RQ3] &= ~RQ3_BANDAGE_WORK; ent->client->ps.stats[STAT_RQ3] &= ~RQ3_BANDAGE_WORK;
} }
//Elder: M4 ride-up/kick -- condition for non-burst and ammo only //Elder: M4 ride-up/kick -- condition for non-burst and ammo only
if ( ent->client->ps.weapon == WP_M4 && ent->client->ps.ammo[WP_M4] > 0 && if ( ent->client->ps.weapon == WP_M4 && ent->client->ps.ammo[WP_M4] > 0 &&
(ent->client->ps.persistant[PERS_WEAPONMODES] & RQ3_M4MODE) != RQ3_M4MODE && (ent->client->ps.persistant[PERS_WEAPONMODES] & RQ3_M4MODE) != RQ3_M4MODE &&
(ent->client->buttons & BUTTON_ATTACK) == BUTTON_ATTACK) (ent->client->buttons & BUTTON_ATTACK) == BUTTON_ATTACK)
{ {
//G_Printf("bullets: %d, viewangle: %f\n", ent->client->consecutiveShots, ent->client->ps.viewangles[0]); //G_Printf("bullets: %d, viewangle: %f\n", ent->client->consecutiveShots, ent->client->ps.viewangles[0]);
ent->client->ps.delta_angles[0] = ANGLE2SHORT(ent->client->consecutiveShots * -0.7); ent->client->ps.delta_angles[0] = ANGLE2SHORT(SHORT2ANGLE(ent->client->ps.delta_angles[0]) - 0.7);
} }
else else if (ent->client->consecutiveShots)
{ {
ent->client->ps.delta_angles[0] = 0; //Restore view after shots
ent->client->ps.delta_angles[0] = ANGLE2SHORT(SHORT2ANGLE(ent->client->ps.delta_angles[0]) - ent->client->consecutiveShots * -0.7);
ent->client->consecutiveShots = 0; ent->client->consecutiveShots = 0;
} }

View file

@ -2039,8 +2039,8 @@ void Cmd_OpenDoor(gentity_t *ent)
//Use_BinaryMover( ent->parent, ent, other ); //Use_BinaryMover( ent->parent, ent, other );
gentity_t *door = NULL; gentity_t *door = NULL;
//Don't open doors if intermission or dead //Don't open doors if dead
if (level.intermissiontime || ent->client->ps.stats[STAT_HEALTH] <= 0) if (ent->client->ps.stats[STAT_HEALTH] <= 0)
return; return;
while ((door = findradius(door,ent->r.currentOrigin,100)) != NULL) while ((door = findradius(door,ent->r.currentOrigin,100)) != NULL)

View file

@ -1043,71 +1043,121 @@ void Weapon_SSG3000_FireOld(gentity_t *ent)
/* /*
================= =================
Elder: Elder:
This is based on the railgun code This is a triple-hybrid bastard child of
railgun_fire, old SSG, and bullet_fire code
weapon_ssg3000_fire weapon_ssg3000_fire
================= =================
*/ */
#define MAX_SSG3000_HITS 5 #define MAX_SSG3000_HITS 4
void Weapon_SSG3000_Fire (gentity_t *ent) { void Weapon_SSG3000_Fire (gentity_t *ent) {
vec3_t end; vec3_t end;
trace_t trace; trace_t trace;
gentity_t *tent; gentity_t *tent[MAX_SSG3000_HITS];
gentity_t *tentWall;
gentity_t *traceEnt; gentity_t *traceEnt;
int damage; int damage;
int i; int i;
int hits; int hits;
int unlinked; int unlinked;
int passent; int passent;
qboolean hitBreakable;
gentity_t *unlinkedEntities[MAX_SSG3000_HITS]; gentity_t *unlinkedEntities[MAX_SSG3000_HITS];
qboolean hitBreakable;
float r;
float u;
float spread;
VectorMA (muzzle, 8192*16, forward, end);
//Elder: added to assist in zoom crap
if (RQ3_isZoomed(ent)) {
spread = 0;
}
else {
spread = RQ3Spread(ent, SNIPER_SPREAD);
r = random() * M_PI * 2.0f;
u = sin(r) * crandom() * spread * 16;
r = cos(r) * crandom() * spread * 16;
VectorMA (end, r, right, end);
VectorMA (end, u, up, end);
}
//damage = 100 * s_quadFactor; //damage = 100 * s_quadFactor;
damage = SNIPER_DAMAGE; damage = SNIPER_DAMAGE;
VectorMA (muzzle, 8192, forward, end); //VectorMA (muzzle, 8192*16, forward, end);
// trace only against the solids, so the SSG3000 will go through people // trace only against the solids, so the SSG3000 will go through people
unlinked = 0; unlinked = 0;
hits = 0; hits = 0;
passent = ent->s.number; passent = ent->s.number;
G_Printf("NewSSG3000: Start\n"); //G_Printf("(%d) SSG: Begin loop\n", level.time);
do { do {
//Elder: need to store this flag because //Elder: need to store this flag because
//the entity may get wiped out in G_Damage //the entity may get wiped out in G_Damage
hitBreakable = qfalse; hitBreakable = qfalse;
//G_Printf("(%d) SSG: Trapping trace\n", level.time);
trap_Trace (&trace, muzzle, NULL, NULL, end, passent, MASK_SHOT ); trap_Trace (&trace, muzzle, NULL, NULL, end, passent, MASK_SHOT );
if ( trace.entityNum >= ENTITYNUM_MAX_NORMAL ) { if ( trace.entityNum >= ENTITYNUM_MAX_NORMAL ) {
//G_Printf("(%d) SSG: OOB Entity: exiting loop\n", level.time);
break; break;
} }
traceEnt = &g_entities[ trace.entityNum ]; traceEnt = &g_entities[ trace.entityNum ];
if ( traceEnt->takedamage ) { if ( traceEnt->takedamage ) {
//G_Printf("(%d) SSG: hit damagable entity\n", level.time);
//flag hitBreakable - bullets go through even //flag hitBreakable - bullets go through even
//if it doesn't "shatter" - but that's usually //if it doesn't "shatter" - but that's usually
//not the case //not the case
if ( traceEnt->s.eType == ET_BREAKABLE ) { if ( traceEnt->s.eType == ET_BREAKABLE ) {
//G_Printf("(%d) SSG: Hit a breakable\n", level.time);
hitBreakable = qtrue; hitBreakable = qtrue;
} }
// send impacts
if ( traceEnt->client )
{
tent[unlinked] = G_TempEntity( trace.endpos, EV_BULLET_HIT_FLESH );
tent[unlinked]->s.eventParm = traceEnt->s.number;
}
else
{
tent[unlinked] = G_TempEntity( trace.endpos, EV_BULLET_HIT_WALL );
tent[unlinked]->s.eventParm = DirToByte( trace.plane.normal );
}
tent[unlinked]->s.otherEntityNum = ent->s.number;
if( LogAccuracyHit( traceEnt, ent ) ) { if( LogAccuracyHit( traceEnt, ent ) ) {
hits++; hits++;
} }
//G_Printf("(%d) SSG: Doing damage to target\n", level.time);
G_Damage (traceEnt, ent, ent, forward, trace.endpos, damage, 0, MOD_SNIPER); G_Damage (traceEnt, ent, ent, forward, trace.endpos, damage, 0, MOD_SNIPER);
} }
//Elder: go through non-solids and breakables //Elder: go through non-solids and breakables
//If we ever wanted to "shoot through walls" we'd do stuff here //If we ever wanted to "shoot through walls" we'd do stuff here
if ( hitBreakable == qfalse && (trace.contents & CONTENTS_SOLID)) { if ( hitBreakable == qfalse && (trace.contents & CONTENTS_SOLID)) {
//G_Printf("(%d) SSG: did not hit breakable and hit solid, exiting loop\n", level.time);
break; // we hit something solid enough to stop the beam break; // we hit something solid enough to stop the beam
} }
//G_Printf("(%d) SSG: Unlinking trace entity\n", level.time);
// unlink this entity, so the next trace will go past it // unlink this entity, so the next trace will go past it
trap_UnlinkEntity( traceEnt ); trap_UnlinkEntity( traceEnt );
unlinkedEntities[unlinked] = traceEnt; unlinkedEntities[unlinked] = traceEnt;
unlinked++; unlinked++;
//G_Printf("(%d) SSG: Unlinked count: %d\n", level.time, unlinked);
} while ( unlinked < MAX_SSG3000_HITS ); } while ( unlinked < MAX_SSG3000_HITS );
//G_Printf("(%d) SSG: Relinking unlinked entities\n", level.time);
// link back in any entities we unlinked // link back in any entities we unlinked
for ( i = 0 ; i < unlinked ; i++ ) { for ( i = 0 ; i < unlinked ; i++ ) {
trap_LinkEntity( unlinkedEntities[i] ); trap_LinkEntity( unlinkedEntities[i] );
@ -1118,20 +1168,16 @@ void Weapon_SSG3000_Fire (gentity_t *ent) {
// snap the endpos to integers to save net bandwidth, but nudged towards the line // snap the endpos to integers to save net bandwidth, but nudged towards the line
SnapVectorTowards( trace.endpos, muzzle ); SnapVectorTowards( trace.endpos, muzzle );
// send bullet impact //G_Printf("(%d) SSG: Sending bullet impact event\n", level.time);
if ( traceEnt->takedamage && traceEnt->client ) {
//Elder: should probably change to something more spectacular
tent = G_TempEntity( trace.endpos, EV_BULLET_HIT_FLESH );
tent->s.eventParm = traceEnt->s.number;
if( LogAccuracyHit( traceEnt, ent ) ) {
ent->client->accuracy_hits++;
}
} else {
tent = G_TempEntity( trace.endpos, EV_BULLET_HIT_WALL );
tent->s.eventParm = DirToByte( trace.plane.normal );
}
tent->s.otherEntityNum = ent->s.number;
// send wall bullet impact
// no explosion at end if SURF_NOIMPACT
if ( !(trace.surfaceFlags & SURF_NOIMPACT) )
{
tentWall = G_TempEntity( trace.endpos, EV_BULLET_HIT_WALL );
tentWall->s.eventParm = DirToByte( trace.plane.normal );
tentWall->s.otherEntityNum = ent->s.number;
}
// send railgun beam effect // send railgun beam effect
//tent = G_TempEntity( trace.endpos, EV_RAILTRAIL ); //tent = G_TempEntity( trace.endpos, EV_RAILTRAIL );
@ -1152,6 +1198,8 @@ void Weapon_SSG3000_Fire (gentity_t *ent) {
//} //}
//tent->s.clientNum = ent->s.clientNum; //tent->s.clientNum = ent->s.clientNum;
//G_Printf("(%d) SSG: Shooter reward\n", level.time);
// give the shooter a reward sound if they have made two railgun hits in a row // give the shooter a reward sound if they have made two railgun hits in a row
if ( hits == 0 ) { if ( hits == 0 ) {
// complete miss // complete miss
@ -1172,6 +1220,9 @@ void Weapon_SSG3000_Fire (gentity_t *ent) {
ent->client->accuracy_hits++; ent->client->accuracy_hits++;
} }
//Elder: bolt action plus save last zoom
ent->client->weaponfireNextTime = level.time + RQ3_SSG3000_BOLT_DELAY;
RQ3_SaveZoomLevel(ent);
} }
@ -1482,6 +1533,7 @@ void FireWeapon( gentity_t *ent ) {
Weapon_M4_Fire ( ent ); Weapon_M4_Fire ( ent );
break; break;
case WP_SSG3000: case WP_SSG3000:
//Weapon_SSG3000_FireOld( ent );
Weapon_SSG3000_Fire ( ent ); Weapon_SSG3000_Fire ( ent );
break; break;
case WP_MP5: case WP_MP5: