diff options
Diffstat (limited to 'src/game/g_weapon.c')
-rw-r--r-- | src/game/g_weapon.c | 132 |
1 files changed, 56 insertions, 76 deletions
diff --git a/src/game/g_weapon.c b/src/game/g_weapon.c index 6ff825f7..ebfa230e 100644 --- a/src/game/g_weapon.c +++ b/src/game/g_weapon.c @@ -135,6 +135,54 @@ void G_BounceProjectile( vec3_t start, vec3_t impact, vec3_t dir, vec3_t endout } /* +================ +G_WideTrace + +Trace a bounding box against entities, but not the world +Also check there is a line of sight between the start and end point +================ +*/ +static void G_WideTrace( trace_t *tr, gentity_t *ent, float range, float width, gentity_t **target ) +{ + vec3_t mins, maxs; + vec3_t end; + + VectorSet( mins, -width, -width, -width ); + VectorSet( maxs, width, width, width ); + + *target = NULL; + + if( !ent->client ) + return; + + // Set aiming directions + AngleVectors( ent->client->ps.viewangles, forward, right, up ); + CalcMuzzlePoint( ent, forward, right, up, muzzle ); + VectorMA( muzzle, range, forward, end ); + + G_UnlaggedOn( muzzle, range ); + + // Trace against entities + trap_Trace( tr, muzzle, mins, maxs, end, ent->s.number, CONTENTS_BODY ); + if( tr->entityNum != ENTITYNUM_NONE ) + { + *target = &g_entities[ tr->entityNum ]; + + // Set range to the trace length plus the width, so that the end of the + // LOS trace is close to the exterior of the target's bounding box + range = Distance( muzzle, tr->endpos ) + width; + VectorMA( muzzle, range, forward, end ); + + // Trace for line of sight against the world + trap_Trace( tr, muzzle, NULL, NULL, end, 0, CONTENTS_SOLID ); + if( tr->fraction < 1.0f ) + *target = NULL; + } + + G_UnlaggedOff( ); +} + +/* ====================== SnapVectorTowards @@ -165,30 +213,14 @@ meleeAttack void meleeAttack( gentity_t *ent, float range, float width, int damage, meansOfDeath_t mod ) { trace_t tr; - vec3_t end; gentity_t *tent; gentity_t *traceEnt; - vec3_t mins, maxs; - - VectorSet( mins, -width, -width, -width ); - VectorSet( maxs, width, width, width ); - - // set aiming directions - AngleVectors( ent->client->ps.viewangles, forward, right, up ); - CalcMuzzlePoint( ent, forward, right, up, muzzle ); + G_WideTrace( &tr, ent, range, width, &traceEnt ); - VectorMA( muzzle, range, forward, end ); - - G_UnlaggedOn( muzzle, range ); - trap_Trace( &tr, muzzle, mins, maxs, end, ent->s.number, MASK_SHOT ); - G_UnlaggedOff( ); - - if( tr.surfaceFlags & SURF_NOIMPACT ) + if( traceEnt == NULL ) return; - traceEnt = &g_entities[ tr.entityNum ]; - // send blood impact if( traceEnt->takedamage && traceEnt->client ) { @@ -817,31 +849,15 @@ CheckVenomAttack qboolean CheckVenomAttack( gentity_t *ent ) { trace_t tr; - vec3_t end; gentity_t *tent; gentity_t *traceEnt; - vec3_t mins, maxs; int damage = LEVEL0_BITE_DMG; - VectorSet( mins, -LEVEL0_BITE_WIDTH, -LEVEL0_BITE_WIDTH, -LEVEL0_BITE_WIDTH ); - VectorSet( maxs, LEVEL0_BITE_WIDTH, LEVEL0_BITE_WIDTH, LEVEL0_BITE_WIDTH ); - - // set aiming directions - AngleVectors( ent->client->ps.viewangles, forward, right, up ); - - CalcMuzzlePoint( ent, forward, right, up, muzzle ); - - VectorMA( muzzle, LEVEL0_BITE_RANGE, forward, end ); - - G_UnlaggedOn( muzzle, LEVEL0_BITE_RANGE ); - trap_Trace( &tr, muzzle, mins, maxs, end, ent->s.number, MASK_SHOT ); - G_UnlaggedOff( ); + G_WideTrace( &tr, ent, LEVEL0_BITE_RANGE, LEVEL0_BITE_WIDTH, &traceEnt ); - if( tr.surfaceFlags & SURF_NOIMPACT ) + if( traceEnt == NULL ) return qfalse; - traceEnt = &g_entities[ tr.entityNum ]; - if( !traceEnt->takedamage ) return qfalse; @@ -1249,29 +1265,13 @@ areaZapFire void areaZapFire( gentity_t *ent ) { trace_t tr; - vec3_t end; gentity_t *traceEnt; - vec3_t mins, maxs; - VectorSet( mins, -LEVEL2_AREAZAP_WIDTH, -LEVEL2_AREAZAP_WIDTH, -LEVEL2_AREAZAP_WIDTH ); - VectorSet( maxs, LEVEL2_AREAZAP_WIDTH, LEVEL2_AREAZAP_WIDTH, LEVEL2_AREAZAP_WIDTH ); - - // set aiming directions - AngleVectors( ent->client->ps.viewangles, forward, right, up ); - - CalcMuzzlePoint( ent, forward, right, up, muzzle ); + G_WideTrace( &tr, ent, LEVEL2_AREAZAP_RANGE, LEVEL2_AREAZAP_WIDTH, &traceEnt ); - VectorMA( muzzle, LEVEL2_AREAZAP_RANGE, forward, end ); - - G_UnlaggedOn( muzzle, LEVEL2_AREAZAP_RANGE ); - trap_Trace( &tr, muzzle, mins, maxs, end, ent->s.number, MASK_SHOT ); - G_UnlaggedOff( ); - - if( tr.surfaceFlags & SURF_NOIMPACT ) + if( traceEnt == NULL ) return; - traceEnt = &g_entities[ tr.entityNum ]; - if( ( ( traceEnt->client && traceEnt->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) || ( traceEnt->s.eType == ET_BUILDABLE && BG_FindTeamForBuildable( traceEnt->s.modelindex ) == BIT_HUMANS ) ) && traceEnt->health > 0 ) @@ -1297,14 +1297,9 @@ CheckPounceAttack qboolean CheckPounceAttack( gentity_t *ent ) { trace_t tr; - vec3_t end; gentity_t *tent; gentity_t *traceEnt; int damage; - vec3_t mins, maxs; - - VectorSet( mins, -LEVEL3_POUNCE_WIDTH, -LEVEL3_POUNCE_WIDTH, -LEVEL3_POUNCE_WIDTH ); - VectorSet( maxs, LEVEL3_POUNCE_WIDTH, LEVEL3_POUNCE_WIDTH, LEVEL3_POUNCE_WIDTH ); if( ent->client->ps.groundEntityNum != ENTITYNUM_NONE ) { @@ -1318,26 +1313,11 @@ qboolean CheckPounceAttack( gentity_t *ent ) if( ent->client->ps.weaponTime ) return qfalse; - // set aiming directions - AngleVectors( ent->client->ps.viewangles, forward, right, up ); + G_WideTrace( &tr, ent, LEVEL3_POUNCE_RANGE, LEVEL3_POUNCE_WIDTH, &traceEnt ); - CalcMuzzlePoint( ent, forward, right, up, muzzle ); - - VectorMA( muzzle, LEVEL3_POUNCE_RANGE, forward, end ); - - G_UnlaggedOn( muzzle, LEVEL3_POUNCE_RANGE ); - trap_Trace( &tr, muzzle, mins, maxs, end, ent->s.number, MASK_SHOT ); - G_UnlaggedOff( ); - - //miss - if( tr.fraction >= 1.0 ) + if( traceEnt == NULL ) return qfalse; - if( tr.surfaceFlags & SURF_NOIMPACT ) - return qfalse; - - traceEnt = &g_entities[ tr.entityNum ]; - // send blood impact if( traceEnt->takedamage && traceEnt->client ) { |