summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/game/bg_pmove.c31
-rw-r--r--src/game/g_active.c94
-rw-r--r--src/game/g_local.h2
-rw-r--r--src/game/g_weapon.c2
4 files changed, 56 insertions, 73 deletions
diff --git a/src/game/bg_pmove.c b/src/game/bg_pmove.c
index 167f40a1..8cad84fe 100644
--- a/src/game/bg_pmove.c
+++ b/src/game/bg_pmove.c
@@ -1833,7 +1833,7 @@ static void PM_GroundClimbTrace( void )
//used for delta correction
vec3_t traceCROSSsurf, traceCROSSref, surfCROSSref;
float traceDOTsurf, traceDOTref, surfDOTref, rTtDOTrTsTt;
- float traceANGsurf, traceANGref, surfANGref;
+ float traceANGref, surfANGref;
vec3_t horizontal = { 1.0f, 0.0f, 0.0f }; //arbituary vector perpendicular to refNormal
vec3_t refTOtrace, refTOsurfTOtrace, tempVec;
int rTtANGrTsTt;
@@ -1910,10 +1910,9 @@ static void PM_GroundClimbTrace( void )
pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask );
break;
}
-
+
//if we hit something
- if( trace.fraction < 1.0f && !( trace.surfaceFlags & ( SURF_SKY | SURF_SLICK ) ) &&
- !( trace.entityNum != ENTITYNUM_WORLD && i != 4 ) )
+ if( trace.fraction < 1.0f && !( trace.surfaceFlags & ( SURF_SKY | SURF_SLICK ) ) )
{
if( i == 2 || i == 3 )
{
@@ -1935,10 +1934,6 @@ static void PM_GroundClimbTrace( void )
//calculate angle between surf and trace
traceDOTsurf = DotProduct( trace.plane.normal, surfNormal );
- traceANGsurf = RAD2DEG( acos( traceDOTsurf ) );
-
- if( traceANGsurf > 180.0f )
- traceANGsurf -= 180.0f;
//calculate angle between trace and ref
traceDOTref = DotProduct( trace.plane.normal, refNormal );
@@ -1970,7 +1965,6 @@ static void PM_GroundClimbTrace( void )
//calculate reference rotated through to surf plane then to trace plane
RotatePointAroundVector( tempVec, surfCROSSref, horizontal, -surfANGref );
- RotatePointAroundVector( refTOsurfTOtrace, traceCROSSsurf, tempVec, -traceANGsurf );
//calculate angle between refTOtrace and refTOsurfTOtrace
rTtDOTrTsTt = DotProduct( refTOtrace, refTOsurfTOtrace );
@@ -1996,10 +1990,6 @@ static void PM_GroundClimbTrace( void )
//construct a point representing where the player is looking
VectorAdd( pm->ps->origin, lookdir, point );
- //check whether point is on one side of the plane, if so invert the correction angle
- if( ( abc[ 0 ] * point[ 0 ] + abc[ 1 ] * point[ 1 ] + abc[ 2 ] * point[ 2 ] - d ) > 0 )
- traceANGsurf = -traceANGsurf;
-
//find the . product of the lookdir and traceCROSSsurf
if( ( ldDOTtCs = DotProduct( lookdir, traceCROSSsurf ) ) < 0.0f )
{
@@ -2007,15 +1997,6 @@ static void PM_GroundClimbTrace( void )
ldDOTtCs = DotProduct( lookdir, traceCROSSsurf );
}
- //set the correction angle
- traceANGsurf *= 1.0f - ldDOTtCs;
-
- if( !( pm->ps->persistant[ PERS_STATE ] & PS_WALLCLIMBINGFOLLOW ) )
- {
- //correct the angle
- pm->ps->delta_angles[ PITCH ] -= ANGLE2SHORT( traceANGsurf );
- }
-
//transition from wall to ceiling
//normal for subsequent viewangle rotations
if( VectorCompare( trace.plane.normal, ceilingNormal ) )
@@ -2048,7 +2029,7 @@ static void PM_GroundClimbTrace( void )
VectorCopy( trace.plane.normal, pm->ps->grapplePoint );
pm->ps->stats[ STAT_STATE ] &= ~SS_WALLCLIMBINGCEILING;
}
-
+
//IMPORTANT: break out of the for loop if we've hit something
break;
}
@@ -2144,7 +2125,7 @@ static void PM_GroundTrace( void )
pm->ps->stats[ STAT_STATE ] &= ~SS_WALLCLIMBING;
}
- if( pm->ps->pm_type == PM_DEAD )
+ if( pm->ps->pm_type == PM_DEAD || pm->ps->pm_time )
pm->ps->stats[ STAT_STATE ] &= ~SS_WALLCLIMBING;
if( pm->ps->stats[ STAT_STATE ] & SS_WALLCLIMBING )
@@ -2318,7 +2299,7 @@ static void PM_GroundTrace( void )
if( BG_ClassHasAbility( pm->ps->stats[ STAT_PCLASS ], SCA_TAKESFALLDAMAGE ) )
PM_CrashLand( );
- }
+ }
pm->ps->groundEntityNum = trace.entityNum;
diff --git a/src/game/g_active.c b/src/game/g_active.c
index 56d773ee..090b83d6 100644
--- a/src/game/g_active.c
+++ b/src/game/g_active.c
@@ -191,54 +191,65 @@ void G_SetClientSound( gentity_t *ent )
//==============================================================
-static void G_ClientShove( gentity_t *ent, gentity_t *victim )
+/*
+==============
+ClientShove
+==============
+*/
+static int GetClientMass( gentity_t *ent )
{
- vec3_t dir, push;
- int entMass = 200, vicMass = 200;
+ int entMass = 100;
- // shoving enemies changes gameplay too much
- if( !OnSameTeam( ent, victim ) )
- return;
-
- // alien mass is directly related to their health points
- // human mass is 200, double for bsuit
if( ent->client->pers.teamSelection == PTE_ALIENS )
- {
entMass = BG_FindHealthForClass( ent->client->pers.classSelection );
- }
else if( ent->client->pers.teamSelection == PTE_HUMANS )
{
if( BG_InventoryContainsUpgrade( UP_BATTLESUIT, ent->client->ps.stats ) )
entMass *= 2;
}
else
- return;
+ return 0;
+ return entMass;
+}
- if( victim->client->pers.teamSelection == PTE_ALIENS )
- {
- vicMass = BG_FindHealthForClass( victim->client->pers.classSelection );
- }
- else if( BG_InventoryContainsUpgrade( UP_BATTLESUIT,
- victim->client->ps.stats ) )
- {
- vicMass *= 2;
- }
+static void ClientShove( gentity_t *ent, gentity_t *victim )
+{
+ vec3_t dir, push;
+ float force;
+ int entMass, vicMass;
+
+ // Don't push if the entity is not trying to move
+ if( !ent->client->pers.cmd.rightmove && !ent->client->pers.cmd.forwardmove &&
+ !ent->client->pers.cmd.upmove )
+ return;
+ // Shove is scaled by relative mass
+ entMass = GetClientMass( ent );
+ vicMass = GetClientMass( victim );
if( vicMass <= 0 || entMass <= 0 )
return;
+ // Give the victim some shove velocity
VectorSubtract( victim->r.currentOrigin, ent->r.currentOrigin, dir );
VectorNormalizeFast( dir );
+ force = g_shove.value * entMass / vicMass;
+ VectorScale( dir, force, push );
+ VectorAdd( victim->client->ps.velocity, push, victim->client->ps.velocity );
- // don't break the dretch elevator
- if( abs( dir[ 2 ] ) > abs( dir[ 0 ] ) && abs( dir[ 2 ] ) > abs( dir[ 1 ] ) )
- return;
-
- VectorScale( dir,
- ( g_shove.value * ( ( float )entMass / ( float )vicMass ) ), push );
- VectorAdd( victim->client->ps.velocity, push,
- victim->client->ps.velocity );
-
+ // Set the pmove timer so that the other client can't cancel
+ // out the movement immediately
+ if( !victim->client->ps.pm_time )
+ {
+ int time;
+
+ time = force * 2 + 0.5f;
+ if( time < 50 )
+ time = 50;
+ if( time > 200 )
+ time = 200;
+ victim->client->ps.pm_time = time;
+ victim->client->ps.pm_flags |= PMF_TIME_KNOCKBACK;
+ }
}
/*
@@ -252,19 +263,11 @@ void ClientImpacts( gentity_t *ent, pmove_t *pm )
trace_t trace;
gentity_t *other;
+ // clear a fake trace struct for touch function
memset( &trace, 0, sizeof( trace ) );
for( i = 0; i < pm->numtouch; i++ )
{
- for( j = 0; j < i; j++ )
- {
- if( pm->touchents[ j ] == pm->touchents[ i ] )
- break;
- }
-
- if( j != i )
- continue; // duplicated
-
other = &g_entities[ pm->touchents[ i ] ];
// see G_UnlaggedDetectCollisions(), this is the inverse of that.
@@ -278,17 +281,16 @@ void ClientImpacts( gentity_t *ent, pmove_t *pm )
if( ent->client->ps.weapon == WP_ALEVEL4 )
{
G_ChargeAttack( ent, other );
- G_CrushAttack( ent, other,
- ( pm->cmd.serverTime - pm->ps->commandTime ) * 0.001f );
+ G_CrushAttack( ent, other );
}
+ // shove players
if( ent->client && other->client )
- G_ClientShove( ent, other );
-
- if( !other->touch )
- continue;
+ ClientShove( ent, other );
- other->touch( other, ent, &trace );
+ // touch triggers
+ if( other->touch )
+ other->touch( other, ent, &trace );
}
}
diff --git a/src/game/g_local.h b/src/game/g_local.h
index db97d8a1..a4a5cd26 100644
--- a/src/game/g_local.h
+++ b/src/game/g_local.h
@@ -899,7 +899,7 @@ qboolean CheckVenomAttack( gentity_t *ent );
void CheckGrabAttack( gentity_t *ent );
qboolean CheckPounceAttack( gentity_t *ent );
void G_ChargeAttack( gentity_t *ent, gentity_t *victim );
-void G_CrushAttack( gentity_t *ent, gentity_t *victim, float sec );
+void G_CrushAttack( gentity_t *ent, gentity_t *victim );
void G_UpdateZaps( gentity_t *ent );
diff --git a/src/game/g_weapon.c b/src/game/g_weapon.c
index b8c0b80d..438350cf 100644
--- a/src/game/g_weapon.c
+++ b/src/game/g_weapon.c
@@ -1398,7 +1398,7 @@ G_CrushAttack
Should only be called if there was an impact between a tyrant and another player
===============
*/
-void G_CrushAttack( gentity_t *ent, gentity_t *victim, float sec )
+void G_CrushAttack( gentity_t *ent, gentity_t *victim )
{
vec3_t dir;
float jump;