summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/game/g_weapon.c132
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 )
{