game_shared/gamemovement.cpp
31323334353637
#ifndef CLIENT_DLL
#include "env_player_surface_trigger.h"
static ConVar dispcoll_drawplane( "dispcoll_drawplane", "0" );
#endif
31323334353637383940
#ifndef CLIENT_DLL
#include "env_player_surface_trigger.h"
#include "ff_player.h" // |-- Mirv: Fall sounds
static ConVar dispcoll_drawplane( "dispcoll_drawplane", "0" );
#else
#include "c_ff_player.h" // |-- Mirv: Fall sounds
#endif
46474849505152
#endif
// [MD] I'll remove this eventually. For now, I want the ability to A/B the optimizations.
bool g_bMovementOptimizations = true;
// Roughly how often we want to update the info about the ground surface we're on.
// We don't need to do this very often.
49505152535455
#endif
// [MD] I'll remove this eventually. For now, I want the ability to A/B the optimizations.
bool g_bMovementOptimizations = true; // |-- Mirv: Changed to false, but not sure if necessary (voogru: changed back to true, uh, yeah, it's necessary otherwise movement is choppy and sucky.)
// Roughly how often we want to update the info about the ground surface we're on.
// We don't need to do this very often.
616263646566
#define NUM_CROUCH_HINTS 3
#ifndef _XBOX
void COM_Log( char *pszFile, char *fmt, ...)
{
6465666768697071727374757677
#define NUM_CROUCH_HINTS 3
static ConVar sv_sharkingfriction("sv_sharkingfriction", "1", FCVAR_REPLICATED | FCVAR_CHEAT);
#define SV_SHARKINGFRICTION sv_sharkingfriction.GetFloat()
//static ConVar ffdev_headcrush_damage("ffdev_headcrush_damage", "108", FCVAR_FF_FFDEV_REPLICATED, "Straight headcrush damage; not used if usefalldamage is on");
#define HEADCRUSH_DAMAGE 108.0f
//static ConVar ffdev_headcrush_usefalldamage("ffdev_headcrush_usefalldamage", "4.0", FCVAR_FF_FFDEV_REPLICATED, "0 = off, > 0 means take FALLDAMAGE * val damage");
#define HEADCRUSH_USEFALLDAMAGE 4.0f
#ifndef _XBOX
void COM_Log( char *pszFile, char *fmt, ...)
{
583584585586587588589590591592593594
}
}
if ( !m_bSpeedCropped && ( mv->m_nButtons & IN_SPEED ) && !( player->m_Local.m_bDucked && !player->m_Local.m_bDucking ))
{
float frac = 1.0f; // TODO can we remove this ?
mv->m_flForwardMove *= frac;
mv->m_flSideMove *= frac;
mv->m_flUpMove *= frac;
m_bSpeedCropped = true;
}
594595596597598599600601602603604605606607608
}
}
// squeek: transition from walk -> crouch brought you back to full speed; only stop cropping speed when the player is fully ducked
if ( !m_bSpeedCropped && ( mv->m_nButtons & IN_SPEED ) /*&& !(mv->m_nButtons & IN_DUCK)*/ && !( player->m_Local.m_bDucked /*&& !player->m_Local.m_bDucking*/ ))
{
// Bug ID #0000363: +speed command not fully implemented
float frac = 0.5f;
mv->m_flForwardMove *= frac;
mv->m_flSideMove *= frac;
mv->m_flUpMove *= frac;
m_bSpeedCropped = true;
}
858859860861862863864865866867868
// Are we backing into water from steps or something? If so, don't pop forward
if ( curspeed != 0.0 && ( DotProduct( flatvelocity, flatforward ) < 0.0 ) )
return;
Vector vecStart;
// Start line trace at waist height (using the center of the player for this here)
vecStart= mv->m_vecAbsOrigin + (GetPlayerMins() + GetPlayerMaxs() ) * 0.5;
Vector vecEnd;
VectorMA( vecStart, 24.0f, flatforward, vecEnd );
872873874875876877878879880881882883884885886887
// Are we backing into water from steps or something? If so, don't pop forward
if ( curspeed != 0.0 && ( DotProduct( flatvelocity, flatforward ) < 0.0 ) )
{
//DevMsg( "[Movement] (curspeed == 0.0) && (DotProduct(flatvelocity, flatforward) >= 0.0)\n" );
return;
}
//DevMsg( "[Movement] DotProduct( flatvelocity, flatforward ): %f\n", DotProduct( flatvelocity, flatforward ) );
Vector vecStart;
// Start line trace at waist height (using the center of the player for this here)
vecStart= mv->m_vecAbsOrigin /*+ (GetPlayerMins() + GetPlayerMaxs() ) * 0.5*/; // |-- Mirv: AbsOrigin is already centred now
Vector vecEnd;
VectorMA( vecStart, 24.0f, flatforward, vecEnd );
878879880881882883884
return;
}
vecStart.z = mv->m_vecAbsOrigin.z + player->GetViewOffset().z + WATERJUMP_HEIGHT;
VectorMA( vecStart, 24.0f, flatforward, vecEnd );
VectorMA( vec3_origin, -50.0f, tr.plane.normal, player->m_vecWaterJumpVel );
897898899900901902903
return;
}
vecStart.z = mv->m_vecAbsOrigin.z + player->GetViewOffset().z + WATERJUMP_HEIGHT + (GetPlayerMaxs().z - GetPlayerMins().z ) * 0.5f; // |-- Mirv: Add on half of bbox too now that we're centred around it
VectorMA( vecStart, 24.0f, flatforward, vecEnd );
VectorMA( vec3_origin, -50.0f, tr.plane.normal, player->m_vecWaterJumpVel );
888889890891892893894895896897
// Now trace down to see if we would actually land on a standable surface.
VectorCopy( vecEnd, vecStart );
vecEnd.z -= 1024.0f;
TracePlayerBBox( vecStart, vecEnd, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, tr );
if ( ( tr.fraction < 1.0f ) && ( tr.plane.normal.z >= 0.7 ) )
{
mv->m_vecVelocity[2] = 256.0f; // Push up
mv->m_nOldButtons |= IN_JUMP; // Don't jump again until released
player->AddFlag( FL_WATERJUMP );
player->m_flWaterJumpTime = 2000.0f; // Do this for 2 seconds
907908909910911912913914915916917918919
// Now trace down to see if we would actually land on a standable surface.
VectorCopy( vecEnd, vecStart );
vecEnd.z -= 1024.0f;
TracePlayerBBox( vecStart, vecEnd, PlayerSolidMask(true), COLLISION_GROUP_PLAYER_MOVEMENT, tr );
if ( ( tr.fraction < 1.0f ) && ( tr.plane.normal.z >= 1.0 ) ) // Jiggles: Was "tr.plain.normal.z >= 0.7"
// I changed it to 1.0 to try and prevent the water jump
// from triggering when the player was merely walking out
// of the water on a slope (see Mantis issue 1164)
{
mv->m_vecVelocity[2] = /*256.0f*/ /*320.0f*/ 380.0f; // Push up
mv->m_nOldButtons |= IN_JUMP; // Don't jump again until released
player->AddFlag( FL_WATERJUMP );
player->m_flWaterJumpTime = 2000.0f; // Do this for 2 seconds
945946947948949950951952953954955956957958959960961962963964965966967968969
//
for (i=0 ; i<3 ; i++)
{
wishvel[i] = forward[i]*mv->m_flForwardMove + right[i]*mv->m_flSideMove;
}
// if we have the jump key down, move us up as well
if (mv->m_nButtons & IN_JUMP)
{
wishvel[2] += mv->m_flClientMaxSpeed;
}
// Sinking after no other movement occurs
else if (!mv->m_flForwardMove && !mv->m_flSideMove && !mv->m_flUpMove)
{
wishvel[2] -= 60; // drift towards bottom
}
else // Go straight up by upmove amount.
{
// exaggerate upward movement along forward as well
float upwardMovememnt = mv->m_flForwardMove * forward.z * 2;
upwardMovememnt = clamp( upwardMovememnt, 0, mv->m_flClientMaxSpeed );
wishvel[2] += mv->m_flUpMove + upwardMovememnt;
}
// Copy it over and determine speed
967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002
//
for (i=0 ; i<3 ; i++)
{
// Bug #0000964: +moveup/+movedown don't work
// Hey, get some up velocity wishing going on to buddy! Don't forget about us +moveup/+movedown users!
wishvel[i] = forward[i]*mv->m_flForwardMove + right[i]*mv->m_flSideMove + up[i]*mv->m_flUpMove;
}
bool bIsSharking = false;
// --> Mirv: Sharking fix
// if we have the jump key down, move us up as well
if (mv->m_nButtons & IN_JUMP)
{
//wishvel[2] += mv->m_flClientMaxSpeed;
mv->m_vecVelocity[2] = 100.0f;
bIsSharking = true;
}
// <-- Mirv: Trimping fix
// Sinking after no other movement occurs
if (!mv->m_flForwardMove && !mv->m_flSideMove && !mv->m_flUpMove && player->GetGroundEntity() == NULL) // |-- Mirv: But only when not on ground, to fix #0000432: Standing underwater on a slope causes player to slip
{
wishvel[2] -= 60; // drift towards bottom
}
else // Go straight up by upmove amount.
{
// --> Mirv: No lets not do this (trackerid: 0000945)
// exaggerate upward movement along forward as well
//float upwardMovememnt = mv->m_flForwardMove * forward.z * 2;
//upwardMovememnt = clamp( upwardMovememnt, 0, mv->m_flClientMaxSpeed );
//wishvel[2] += mv->m_flUpMove + upwardMovememnt;
// <--
}
// Copy it over and determine speed
970971972973974975976977978979980981
VectorCopy (wishvel, wishdir);
wishspeed = VectorNormalize(wishdir);
// Cap speed.
if (wishspeed > mv->m_flMaxSpeed)
{
VectorScale (wishvel, mv->m_flMaxSpeed/wishspeed, wishvel);
wishspeed = mv->m_flMaxSpeed;
}
// Slow us down a bit.
wishspeed *= 0.8;
100310041005100610071008100910101011101210131014101510161017101810191020
VectorCopy (wishvel, wishdir);
wishspeed = VectorNormalize(wishdir);
// --> Jon: cap swimming speed if cloaked
float flMaxSpeed = mv->m_flMaxSpeed;
if (ToFFPlayer(player)->IsCloaked())
flMaxSpeed = SPY_MAXCLOAKSPEED;
// Cap speed.
if (wishspeed > flMaxSpeed)
{
VectorScale (wishvel, flMaxSpeed/wishspeed, wishvel);
wishspeed = flMaxSpeed;
}
// <--
// Slow us down a bit.
wishspeed *= 0.8;
985986987988989990991
speed = VectorNormalize(temp);
if (speed)
{
newspeed = speed - gpGlobals->frametime * speed * sv_friction.GetFloat() * player->m_surfaceFriction;
if (newspeed < 0.1f)
{
newspeed = 0;
1024102510261027102810291030103110321033
speed = VectorNormalize(temp);
if (speed)
{
if (!bIsSharking)
newspeed = speed - gpGlobals->frametime * speed * /*sv_friction.GetFloat()*/ 4.0f * /*player->m_surfaceFriction*/ 1.0f; // |-- Mirv: More TFC Feeling (tm) friction
else
newspeed = speed - gpGlobals->frametime * speed * SV_SHARKINGFRICTION * /*player->m_surfaceFriction*/ 1.0f;
if (newspeed < 0.1f)
{
newspeed = 0;
1005100610071008100910101011
if (addspeed > 0)
{
VectorNormalize(wishvel);
accelspeed = sv_accelerate.GetFloat() * wishspeed * gpGlobals->frametime * player->m_surfaceFriction;
if (accelspeed > addspeed)
{
accelspeed = addspeed;
1047104810491050105110521053
if (addspeed > 0)
{
VectorNormalize(wishvel);
accelspeed = sv_accelerate.GetFloat() * wishspeed * gpGlobals->frametime * /*player->m_surfaceFriction*/ 1.0f; // |-- Mirv: More TFC Feeling (tm) friction
if (accelspeed > addspeed)
{
accelspeed = addspeed;
115311541155115611571158
{
// copy z value from slide move
mv->m_vecVelocity.z = vecDownVel.z;
}
float flStepDist = mv->m_vecAbsOrigin.z - vecPos.z;
119511961197119811991200120112021203120412051206120712081209
{
// copy z value from slide move
mv->m_vecVelocity.z = vecDownVel.z;
// --> Mirv:
// If we have stepped up far enough then flag for smoothstairs
float flDistance = vecUpPos.z - vecPos.z;
if (flDistance >= 8.0f)
{
player->m_bSmoothStair = true;
}
// <-- Mirv
}
float flStepDist = mv->m_vecAbsOrigin.z - vecPos.z;
1222122312241225122612271228
friction = sv_friction.GetFloat();
// Grab friction value.
friction *= player->m_surfaceFriction; // player friction?
// Bleed off some speed, but if we have less than the bleed
// threshhold, bleed the theshold amount.
1273127412751276127712781279
friction = sv_friction.GetFloat();
// Grab friction value.
friction *= /*player->m_surfaceFriction*/ 1.0f; // |-- Mirv: More TFC Feeling (tm) friction
// Bleed off some speed, but if we have less than the bleed
// threshhold, bleed the theshold amount.
1316131713181319132013211322
return;
// Determine acceleration speed after acceleration
accelspeed = accel * wishspeed * gpGlobals->frametime * player->m_surfaceFriction;
// Cap it
if (accelspeed > addspeed)
1367136813691370137113721373
return;
// Determine acceleration speed after acceleration
accelspeed = accel * wishspeed * gpGlobals->frametime * /*player->m_surfaceFriction*/ 1.0f; // |-- Mirv: More TFC Feeling (tm) friction
// Cap it
if (accelspeed > addspeed)
1423142414251426142714281429
return;
// Determine amount of accleration.
accelspeed = accel * gpGlobals->frametime * wishspeed * player->m_surfaceFriction;
// Cap at addspeed
if (accelspeed > addspeed)
1474147514761477147814791480
return;
// Determine amount of accleration.
accelspeed = accel * gpGlobals->frametime * wishspeed * /*player->m_surfaceFriction*/ 1.0f; // |-- Mirv: More TFC Feeling (tm) friction
// Cap at addspeed
if (accelspeed > addspeed)
146614671468146914701471
//This is incredibly hacky. The real problem is that trace returning that strange value we can't network over.
if ( flDelta > 0.5f * COORD_RESOLUTION)
{
mv->m_vecAbsOrigin = trace.endpos;
}
}
151715181519152015211522152315241525152615271528152915301531
//This is incredibly hacky. The real problem is that trace returning that strange value we can't network over.
if ( flDelta > 0.5f * COORD_RESOLUTION)
{
// --> Mirv:
// If we have stepped up far enough then flag for smoothstairs
float flDistance = mv->m_vecAbsOrigin.z - trace.endpos.z;
if (flDistance >= 8.0f)
{
player->m_bSmoothStair = true;
}
// <-- Mirv
mv->m_vecAbsOrigin = trace.endpos;
}
}
1618161916201621162216231624
TryPlayerMove();
// See if we are still in water?
CheckWater();
return;
}
// If we are swimming in the water, see if we are nudging against a place we can jump up out
1678167916801681168216831684168516861687168816891690
TryPlayerMove();
// See if we are still in water?
CheckWater();
// hlstriker: Make sure player isn't swimming before we return
if( player->GetWaterLevel() < WL_Waist )
{
player->m_flWaterJumpTime = 0;
return;
}
}
// If we are swimming in the water, see if we are nudging against a place we can jump up out
17041705170617071708170917101711171217131714
FinishGravity();
}
// If we are on ground, no downward velocity.
if ( player->GetGroundEntity() != NULL )
{
mv->m_vecVelocity[2] = 0;
}
CheckFalling();
}
17701771177217731774177517761777177817791780178117821783
FinishGravity();
}
// --> Mirv: Can't remember why this is commented out
// If we are on ground, no downward velocity.
if ( player->GetGroundEntity() != NULL )
{
mv->m_vecVelocity[2] = 0;
}
// <-- Mirv: Can't remember why this is commented out
CheckFalling();
}
1886188718881889189018911892
// threshhold, bleed the theshold amount.
float control = (spd < maxspeed/4.0) ? maxspeed/4.0 : spd;
float friction = sv_friction.GetFloat() * player->m_surfaceFriction;
// Add the amount to the drop amount.
float drop = control * friction * gpGlobals->frametime;
1955195619571958195919601961
// threshhold, bleed the theshold amount.
float control = (spd < maxspeed/4.0) ? maxspeed/4.0 : spd;
float friction = sv_friction.GetFloat() * /*player->m_surfaceFriction*/ 1.0f; // |-- Mirv: More TFC Feeling (tm) friction
// Add the amount to the drop amount.
float drop = control * friction * gpGlobals->frametime;
2185218621872188218921902191219221932194
// the whole way, zero out our velocity and return that we
// are blocked by floor and wall.
if (pm.allsolid)
{
// entity is trapped in another solid
VectorCopy (vec3_origin, mv->m_vecVelocity);
return 4;
}
// If we moved some portion of the total distance, then
22542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282
// the whole way, zero out our velocity and return that we
// are blocked by floor and wall.
if (pm.allsolid)
{
#ifdef EXTRA_LOCAL_ORIGIN_ACCURACY
// If we have the extra local origin accuracy fix in then normal behaviour
VectorCopy (vec3_origin, mv->m_vecVelocity);
return 4;
#endif
// this is limited by the network fractional bits used for coords
// because net coords will be only be accurate to 5 bits fractional
// Standard collision test epsilon
// 1/32nd inch collision epsilon
Ray_t ray;
ray.Init(mv->m_vecAbsOrigin, end, GetPlayerMins() + Vector(DIST_EPSILON, DIST_EPSILON, DIST_EPSILON), GetPlayerMaxs() - Vector(DIST_EPSILON, DIST_EPSILON, DIST_EPSILON));
UTIL_TraceRay(ray, PlayerSolidMask(), mv->m_nPlayerHandle.Get(), COLLISION_GROUP_PLAYER_MOVEMENT, &pm);
// entity is trapped in another solid
if (pm.allsolid)
{
VectorCopy (vec3_origin, mv->m_vecVelocity);
return 4;
}
allFraction += pm.fraction;
}
// If we moved some portion of the total distance, then
2266226722682269227022712272
}
else
{
ClipVelocity( original_velocity, planes[i], new_velocity, 1.0 + sv_bounce.GetFloat() * (1 - player->m_surfaceFriction) );
}
}
2354235523562357235823592360
}
else
{
ClipVelocity( original_velocity, planes[i], new_velocity, 1.0 + sv_bounce.GetFloat() * (1 - /*player->m_surfaceFriction*/ 1.0f) ); // |-- Mirv: More TFC Feeling (tm) friction
}
}
304330443045304630473048
// Now check a point that is at the player hull midpoint.
point[2] = mv->m_vecAbsOrigin[2] + (GetPlayerMins()[2] + GetPlayerMaxs()[2])*0.5;
cont = enginetrace->GetPointContents( point );
// If that point is also under water...
if ( cont & MASK_WATER )
31313132313331343135313631373138313931403141
// Now check a point that is at the player hull midpoint.
point[2] = mv->m_vecAbsOrigin[2] + (GetPlayerMins()[2] + GetPlayerMaxs()[2])*0.5;
// // Bug #0000017: Can't jump out of "deep" water |-- Mulch
// // Raising the point to check for waist deep water 4 units
// point[ 2 ] += 4.0f;
cont = enginetrace->GetPointContents( point );
// If that point is also under water...
if ( cont & MASK_WATER )
3213321432153216321732183219
point[1] = mv->m_vecAbsOrigin[1];
point[2] = mv->m_vecAbsOrigin[2] - 2; // move a total of 4 units to try and avoid some
// epsilon error
Vector bumpOrigin;
bumpOrigin = mv->m_vecAbsOrigin;
bumpOrigin.z += 2;
3306330733083309331033113312
point[1] = mv->m_vecAbsOrigin[1];
point[2] = mv->m_vecAbsOrigin[2] - 2; // move a total of 4 units to try and avoid some
// epsilon error
Vector bumpOrigin;
bumpOrigin = mv->m_vecAbsOrigin;
bumpOrigin.z += 2;
32213222322332243225322632273228322932303231
// Shooting up really fast. Definitely not on ground.
// On ladder moving up, so not on ground either
// NOTE: 145 is a jump.
if ( mv->m_vecVelocity[2] > 140 ||
( mv->m_vecVelocity[2] > 0.0f && player->GetMoveType() == MOVETYPE_LADDER ) )
{
SetGroundEntity( (CBaseEntity *)NULL );
}
else
{
// Try and move down.
3314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338
// Shooting up really fast. Definitely not on ground.
// On ladder moving up, so not on ground either
// NOTE: 145 is a jump.
// --> Mirv: Changed value to accomodate for ramp bug
float flUpSpeedLimit;
if( ( mv->m_nButtons & IN_JUMP ) && !( mv->m_nOldButtons & IN_JUMP ) )
flUpSpeedLimit = 260000;
else
flUpSpeedLimit = 180; //260;
// Scouts going up ramps can easily break past 140, and our new
// jump speed is 268 anyway, so 260 is going to be a better value
// UNDONE: Using HL value for testing.
// UNUNDONE: Using the HL value but dynamically like before.
if ( mv->m_vecVelocity[2] > flUpSpeedLimit ||
( mv->m_vecVelocity[2] > 0.0f && player->GetMoveType() == MOVETYPE_LADDER ) )
{
SetGroundEntity( (CBaseEntity *)NULL );
}
// <-- Mirv: Changed value to accomodate for ramp bug
else
{
// Try and move down.
331033113312331333143315
//-----------------------------------------------------------------------------
void CGameMovement::CheckFalling( void )
{
if ( player->GetGroundEntity() != NULL &&
!IsDead() &&
player->m_Local.m_flFallVelocity >= PLAYER_FALL_PUNCH_THRESHOLD )
341734183419342034213422342334243425342634273428342934303431
//-----------------------------------------------------------------------------
void CGameMovement::CheckFalling( void )
{
CFFPlayer *pPlayer = ToFFPlayer(player);
// Jiggles: To stop players from double jumping off other players
if ( player->GetGroundEntity() && player->GetGroundEntity()->IsPlayer() )
pPlayer->m_bCanDoubleJump = false;
else
pPlayer->m_bCanDoubleJump = true;
if ( player->GetGroundEntity() != NULL &&
!IsDead() &&
player->m_Local.m_flFallVelocity >= PLAYER_FALL_PUNCH_THRESHOLD )
332033213322332333243325
if ( player->GetWaterLevel() > 0 )
{
// They landed in water.
}
else
{
3436343734383439344034413442
if ( player->GetWaterLevel() > 0 )
{
// They landed in water.
fvol = 0.0f;
}
else
{
3349335033513352335333543355
}
else if ( player->m_Local.m_flFallVelocity > PLAYER_MAX_SAFE_FALL_SPEED / 2 )
{
fvol = 0.85;
}
else if ( player->m_Local.m_flFallVelocity < PLAYER_MIN_BOUNCE_SPEED )
{
34663467346834693470347134723473
}
else if ( player->m_Local.m_flFallVelocity > PLAYER_MAX_SAFE_FALL_SPEED / 2 )
{
// 0000608: Makes dropping damage sound from heights that dont inflict damage
fvol = 0; //0.85;
}
else if ( player->m_Local.m_flFallVelocity < PLAYER_MIN_BOUNCE_SPEED )
{
3359336033613362336333643365336633673368336933703371
if ( fvol > 0.0 )
{
//
// Play landing sound right away.
player->m_flStepSoundTime = 400;
// Play step sound for current texture.
player->PlayStepSound( mv->m_vecAbsOrigin, player->m_pSurfaceData, fvol, true );
//
// Knock the screen around a little bit, temporary effect.
//
3477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501
if ( fvol > 0.0 )
{
// --> Mirv: Use a fall sound, and reduce the volume for spies
CFFPlayer *pFFPlayer = ToFFPlayer(player);
Assert( pFFPlayer );
pFFPlayer->PlayFallSound( mv->m_vecAbsOrigin, player->m_pSurfaceData, fvol );
//
// Play landing sound right away.
// #0000599: footstep continues to play after cratering
// #0000401: Oddity with the fall sound.
pFFPlayer->m_flStepSoundTime = gpGlobals->curtime + 0.600f;
pFFPlayer->m_flJumpTime = gpGlobals->curtime + 0.600f;
// Play step sound for current texture.
//player->PlayStepSound( mv->m_vecAbsOrigin, player->m_pSurfaceData, fvol, true );
// <-- Mirv: Use a fall sound, and reduce the volume for spies
//
// Knock the screen around a little bit, temporary effect.
//
337533763377337833793380
{
player->m_Local.m_vecPunchAngle.Set( PITCH, 8 );
}
}
if (bAlive)
35053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536
{
player->m_Local.m_vecPunchAngle.Set( PITCH, 8 );
}
if (fvol == 1.0f)
{
#ifdef GAME_DLL
if (player->GetGroundEntity() && player->GetGroundEntity()->IsPlayer())
{
CFFPlayer *pCrushedPlayer = ToFFPlayer(player->GetGroundEntity());
if (pCrushedPlayer && pCrushedPlayer != player)
{
float flCrushDamage = 0.0f;
if (HEADCRUSH_USEFALLDAMAGE > 0)
{
float flFallDamage = g_pGameRules->FlPlayerFallDamage( player );
flCrushDamage = flFallDamage * HEADCRUSH_USEFALLDAMAGE;
}
else
{
flCrushDamage = HEADCRUSH_DAMAGE;
}
CTakeDamageInfo info( player, player, flCrushDamage, DMG_DIRECT, KILLTYPE_HEADCRUSH );
pCrushedPlayer->TakeDamage(info);
}
}
#endif
}
}
if (bAlive)
3486348734883489349034913492
VectorCopy( mv->m_vecAbsOrigin, newOrigin );
if ( player->GetGroundEntity() != NULL )
{
for ( i = 0; i < 3; i++ )
{
364236433644364536463647364836493650
VectorCopy( mv->m_vecAbsOrigin, newOrigin );
// The extra check (m_Local.m_bDucked) added because players were popping up
// into the air when they hadn't yet been moved down for the duck
if ( player->GetGroundEntity() != NULL && player->m_Local.m_bDucked )
{
for ( i = 0; i < 3; i++ )
{
349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519
newOrigin[i] += ( VEC_DUCK_HULL_MIN[i] - VEC_HULL_MIN[i] );
}
}
else
{
// If in air an letting go of crouch, make sure we can offset origin to make
// up for uncrouching
Vector hullSizeNormal = VEC_HULL_MAX - VEC_HULL_MIN;
Vector hullSizeCrouch = VEC_DUCK_HULL_MAX - VEC_DUCK_HULL_MIN;
Vector viewDelta = ( hullSizeNormal - hullSizeCrouch );
viewDelta.Negate();
VectorAdd( newOrigin, viewDelta, newOrigin );
}
player->m_Local.m_bDucked = false;
player->RemoveFlag( FL_DUCKING );
player->m_Local.m_bDucking = false;
player->SetViewOffset( GetPlayerViewOffset( false ) );
player->m_Local.m_flDucktime = 0;
VectorCopy( newOrigin, mv->m_vecAbsOrigin );
// Recategorize position since ducking can change origin
CategorizePosition();
}
//-----------------------------------------------------------------------------
365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725
newOrigin[i] += ( VEC_DUCK_HULL_MIN[i] - VEC_HULL_MIN[i] );
}
}
//trace = pmove->PM_PlayerTrace( newOrigin, newOrigin, PM_NORMAL, -1 );
TracePlayerBBox(newOrigin, newOrigin, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, trace);
if ( !trace.startsolid )
{
player->m_Local.m_bDucked = false; // pmove->usehull = 0;
// Oh, no, changing hulls stuck us into something, try unsticking downward first.
//trace = pmove->PM_PlayerTrace( newOrigin, newOrigin, PM_NORMAL, -1 );
TracePlayerBBox(newOrigin, newOrigin, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, trace);
if ( trace.startsolid )
{
// See if we are stuck? If so, stay ducked with the duck hull until we have a clear spot
//Con_Printf( "unstick got stuck\n" );
player->m_Local.m_bDucked = true; // pmove->usehull = 1;
return;
}
player->RemoveFlag(FL_DUCKING); // pmove->flags &= ~FL_DUCKING;
player->m_Local.m_bDucking = false;
//pmove->view_ofs[2] = VEC_VIEW;
Vector vecViewOffset = player->GetViewOffset();
vecViewOffset[2] = VEC_VIEW[2];
player->SetViewOffset(vecViewOffset);
player->m_Local.m_flDucktime = 0;
VectorCopy( newOrigin, mv->m_vecAbsOrigin );
// Recatagorize position since ducking can change origin
CategorizePosition();
}
//int i;
//trace_t trace;
//Vector newOrigin;
//VectorCopy( mv->m_vecAbsOrigin, newOrigin );
//if ( player->GetGroundEntity() != NULL )
//{
// for ( i = 0; i < 3; i++ )
// {
// newOrigin[i] += ( VEC_DUCK_HULL_MIN[i] - VEC_HULL_MIN[i] );
// }
//}
//else
//{
// // If in air an letting go of crouch, make sure we can offset origin to make
// // up for uncrouching
// Vector hullSizeNormal = VEC_HULL_MAX - VEC_HULL_MIN;
// Vector hullSizeCrouch = VEC_DUCK_HULL_MAX - VEC_DUCK_HULL_MIN;
// Vector viewDelta = ( hullSizeNormal - hullSizeCrouch );
// viewDelta.Negate();
// //VectorAdd( newOrigin, viewDelta, newOrigin ); // |-- Mirv: I think this is causing the duck bug
//}
//player->m_Local.m_bDucked = false;
//player->RemoveFlag( FL_DUCKING );
//player->m_Local.m_bDucking = false;
//player->SetViewOffset( GetPlayerViewOffset( false ) );
//player->m_Local.m_flDucktime = 0;
//
//VectorCopy( newOrigin, mv->m_vecAbsOrigin );
//// Recategorize position since ducking can change origin
//CategorizePosition();
}
//-----------------------------------------------------------------------------
3599360036013602360336043605
{
Vector hullSizeNormal = VEC_HULL_MAX - VEC_HULL_MIN;
Vector hullSizeCrouch = VEC_DUCK_HULL_MAX - VEC_DUCK_HULL_MIN;
Vector viewDelta = ( hullSizeNormal - hullSizeCrouch );
VectorAdd( mv->m_vecAbsOrigin, viewDelta, mv->m_vecAbsOrigin );
}
3805380638073808380938103811
{
Vector hullSizeNormal = VEC_HULL_MAX - VEC_HULL_MIN;
Vector hullSizeCrouch = VEC_DUCK_HULL_MAX - VEC_DUCK_HULL_MIN;
Vector viewDelta = ( hullSizeNormal - hullSizeCrouch ) / 2.0f; // |-- Mirv: We only want half the difference
VectorAdd( mv->m_vecAbsOrigin, viewDelta, mv->m_vecAbsOrigin );
}
3623362436253626362736283629
Vector hullSizeNormal = VEC_HULL_MAX - VEC_HULL_MIN;
Vector hullSizeCrouch = VEC_DUCK_HULL_MAX - VEC_DUCK_HULL_MIN;
Vector viewDelta = ( hullSizeNormal - hullSizeCrouch );
VectorAdd( mv->m_vecAbsOrigin, viewDelta, mv->m_vecAbsOrigin );
// See if we are stuck?
3829383038313832383338343835
Vector hullSizeNormal = VEC_HULL_MAX - VEC_HULL_MIN;
Vector hullSizeCrouch = VEC_DUCK_HULL_MAX - VEC_DUCK_HULL_MIN;
Vector viewDelta = ( hullSizeNormal - hullSizeCrouch ) / 2.0f; // |-- Mirv: We only want half the difference
VectorAdd( mv->m_vecAbsOrigin, viewDelta, mv->m_vecAbsOrigin );
// See if we are stuck?
370337043705370637073708370937103711371237133714371537163717
//-----------------------------------------------------------------------------
void CGameMovement::Duck( void )
{
int buttonsChanged = ( mv->m_nOldButtons ^ mv->m_nButtons ); // These buttons have changed this frame
int buttonsPressed = buttonsChanged & mv->m_nButtons; // The changed ones still down are "pressed"
int buttonsReleased = buttonsChanged & mv->m_nOldButtons; // The changed ones which were previously down are "released"
// Check to see if we are in the air.
bool bInAir = ( player->GetGroundEntity() == NULL );
bool bInDuck = ( player->GetFlags() & FL_DUCKING ) ? true : false;
bool bDuckJump = ( player->m_Local.m_flJumpTime > 0.0f );
bool bDuckJumpTime = ( player->m_Local.m_flDuckJumpTime > 0.0f );
if ( mv->m_nButtons & IN_DUCK )
{
390939103911391239133914391539163917391839193920392139223923392439253926
//-----------------------------------------------------------------------------
void CGameMovement::Duck( void )
{
if (!player->IsAlive())
return;
int i;
float time;
float duckFraction;
int buttonsChanged = ( mv->m_nOldButtons ^ mv->m_nButtons ); // These buttons have changed this frame
int nButtonPressed = buttonsChanged & mv->m_nButtons; // The changed ones still down are "pressed"
//int duckchange = buttonsChanged & IN_DUCK ? 1 : 0;
//int duckpressed = nButtonPressed & IN_DUCK ? 1 : 0;
if ( mv->m_nButtons & IN_DUCK )
{
3722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914
mv->m_nOldButtons &= ~IN_DUCK;
}
// Handle death.
if ( IsDead() )
return;
// Slow down ducked players.
HandleDuckingSpeedCrop();
// If the player is holding down the duck button, the player is in duck transition, ducking, or duck-jumping.
if ( ( mv->m_nButtons & IN_DUCK ) || player->m_Local.m_bDucking || bInDuck || bDuckJump )
{
// DUCK
if ( ( mv->m_nButtons & IN_DUCK ) || bDuckJump )
{
// XBOX SERVER ONLY
#if !defined(CLIENT_DLL) && defined(_XBOX)
if ( buttonsPressed & IN_DUCK )
{
// Hinting logic
if ( player->GetToggledDuckState() && player->m_nNumCrouches < NUM_CROUCH_HINTS )
{
UTIL_HudHintText( player, "#Valve_Hint_Crouch" );
player->m_nNumCrouches++;
}
}
#endif
// Have the duck button pressed, but the player currently isn't in the duck position.
if ( ( buttonsPressed & IN_DUCK ) && !bInDuck && !bDuckJump && !bDuckJumpTime )
{
player->m_Local.m_flDucktime = GAMEMOVEMENT_DUCK_TIME;
player->m_Local.m_bDucking = true;
}
// The player is in duck transition and not duck-jumping.
if ( player->m_Local.m_bDucking && !bDuckJump && !bDuckJumpTime )
{
float flDuckMilliseconds = max( 0.0f, GAMEMOVEMENT_DUCK_TIME - ( float )player->m_Local.m_flDucktime );
float flDuckSeconds = flDuckMilliseconds * 0.001f;
// Finish in duck transition when transition time is over, in "duck", in air.
if ( ( flDuckSeconds > TIME_TO_DUCK ) || bInDuck || bInAir )
{
FinishDuck();
}
else
{
// Calc parametric time
float flDuckFraction = SimpleSpline( flDuckSeconds / TIME_TO_DUCK );
SetDuckedEyeOffset( flDuckFraction );
}
}
if ( bDuckJump )
{
// Make the bounding box small immediately.
if ( !bInDuck )
{
StartUnDuckJump();
}
else
{
// Check for a crouch override.
if ( !( mv->m_nButtons & IN_DUCK ) )
{
trace_t trace;
if ( CanUnDuckJump( trace ) )
{
FinishUnDuckJump( trace );
player->m_Local.m_flDuckJumpTime = ( GAMEMOVEMENT_TIME_TO_UNDUCK * ( 1.0f - trace.fraction ) ) + GAMEMOVEMENT_TIME_TO_UNDUCK_INV;
}
}
}
}
}
// UNDUCK (or attempt to...)
else
{
if ( player->m_Local.m_bInDuckJump )
{
// Check for a crouch override.
if ( !( mv->m_nButtons & IN_DUCK ) )
{
trace_t trace;
if ( CanUnDuckJump( trace ) )
{
FinishUnDuckJump( trace );
if ( trace.fraction < 1.0f )
{
player->m_Local.m_flDuckJumpTime = ( GAMEMOVEMENT_TIME_TO_UNDUCK * ( 1.0f - trace.fraction ) ) + GAMEMOVEMENT_TIME_TO_UNDUCK_INV;
}
}
}
else
{
player->m_Local.m_bInDuckJump = false;
}
}
if ( bDuckJumpTime )
return;
// Try to unduck unless automovement is not allowed
// NOTE: When not onground, you can always unduck
if ( player->m_Local.m_bAllowAutoMovement || bInAir )
{
// We released the duck button, we aren't in "duck" and we are not in the air - start unduck transition.
if ( ( buttonsReleased & IN_DUCK ) )
{
if ( bInDuck && !bDuckJump )
{
player->m_Local.m_flDucktime = GAMEMOVEMENT_DUCK_TIME;
}
else if ( player->m_Local.m_bDucking && !player->m_Local.m_bDucked )
{
// Invert time if release before fully ducked!!!
float unduckMilliseconds = 1000.0f * TIME_TO_UNDUCK;
float duckMilliseconds = 1000.0f * TIME_TO_DUCK;
float elapsedMilliseconds = GAMEMOVEMENT_DUCK_TIME - player->m_Local.m_flDucktime;
float fracDucked = elapsedMilliseconds / duckMilliseconds;
float remainingUnduckMilliseconds = fracDucked * unduckMilliseconds;
player->m_Local.m_flDucktime = GAMEMOVEMENT_DUCK_TIME - unduckMilliseconds + remainingUnduckMilliseconds;
}
}
// Check to see if we are capable of unducking.
if ( CanUnduck() )
{
// or unducking
if ( ( player->m_Local.m_bDucking || player->m_Local.m_bDucked ) )
{
float flDuckMilliseconds = max( 0.0f, GAMEMOVEMENT_DUCK_TIME - (float)player->m_Local.m_flDucktime );
float flDuckSeconds = flDuckMilliseconds * 0.001f;
// Finish ducking immediately if duck time is over or not on ground
if ( flDuckSeconds > TIME_TO_UNDUCK || ( bInAir && !bDuckJump ) )
{
FinishUnDuck();
}
else
{
// Calc parametric time
float flDuckFraction = SimpleSpline( 1.0f - ( flDuckSeconds / TIME_TO_UNDUCK ) );
SetDuckedEyeOffset( flDuckFraction );
player->m_Local.m_bDucking = true;
}
}
}
else
{
// Still under something where we can't unduck, so make sure we reset this timer so
// that we'll unduck once we exit the tunnel, etc.
if ( player->m_Local.m_flDucktime != GAMEMOVEMENT_DUCK_TIME )
{
SetDuckedEyeOffset(1.0f);
player->m_Local.m_flDucktime = GAMEMOVEMENT_DUCK_TIME;
}
}
}
}
}
// HACK: (jimd 5/25/2006) we have a reoccuring bug (#50063 in Tracker) where the player's
// view height gets left at the ducked height while the player is standing, but we haven't
// been able to repro it to find the cause. It may be fixed now due to a change I'm
// also making in UpdateDuckJumpEyeOffset but just in case, this code will sense the
// problem and restore the eye to the proper position. It doesn't smooth the transition,
// but it is preferable to leaving the player's view too low.
//
// If the player is still alive and not an observer, check to make sure that
// his view height is at the standing height.
else if ( !IsDead() && !player->IsObserver() )
{
if ( ( player->m_Local.m_flDuckJumpTime == 0.0f ) && ( player->GetViewOffset().z != GetPlayerViewOffset( false ).z ) )
{
// we should rarely ever get here, so assert so a coder knows when it happens
Assert(0);
DevMsg( 1, "Restoring player view height\n" );
// set the eye height to the non-ducked height
SetDuckedEyeOffset(0.0f);
}
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CGameMovement::PlayerMove( void )
393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230
mv->m_nOldButtons &= ~IN_DUCK;
}
//if ( player->GetFlags() & FL_DUCKING )
//{
// pmove->cmd.forwardmove *= 0.333;
// pmove->cmd.sidemove *= 0.333;
// pmove->cmd.upmove *= 0.333;
//}
HandleDuckingSpeedCrop();
if ( ( mv->m_nButtons & IN_DUCK ) || ( player->m_Local.m_bDucking ) || ( player->GetFlags() & FL_DUCKING ) )
{
if ( mv->m_nButtons & IN_DUCK )
{
if ( (nButtonPressed & IN_DUCK ) && !( player->GetFlags() & FL_DUCKING ) )
{
// Use 1 second so super long jump will work
player->m_Local.m_flDucktime = 1000;
player->m_Local.m_bDucking = true;
}
time = max( 0.0, ( 1.0 - (float)player->m_Local.m_flDucktime / 1000.0 ) );
if ( player->m_Local.m_bDucking )
{
// Finish ducking immediately if duck time is over or not on ground
if ( ( (float)player->m_Local.m_flDucktime / 1000.0 <= ( 1.0 - TIME_TO_DUCK ) ) ||
( player->GetGroundEntity() == NULL ) && player->m_Local.m_flDucktime > 0 )
{
player->m_Local.m_bDucked = true; //pmove->usehull = 1;
//pmove->view_ofs[2] = VEC_DUCK_VIEW;
Vector vecOffset = player->GetViewOffset();
vecOffset[2] = VEC_DUCK_VIEW[2];
player->SetViewOffset(vecOffset);
player->AddFlag(FL_DUCKING); //player->GetFlags() |= FL_DUCKING;
//player->m_Local.m_bDucking = false;
// HACKHACK - Fudge for collision bug - no time to fix this properly
if ( player->GetGroundEntity() != NULL )
{
trace_t pm;
TracePlayerBBox(mv->m_vecAbsOrigin, mv->m_vecAbsOrigin - (VEC_DUCK_HULL_MIN - VEC_HULL_MIN), PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, pm);
for ( i = 0; i < 3; i++ )
{
//Assert(pm.fraction == 1.0f);
mv->m_vecAbsOrigin[i] -= pm.fraction * ( VEC_DUCK_HULL_MIN[i] - VEC_HULL_MIN[i] );
}
// See if we are stuck?
FixPlayerCrouchStuck(true);
// Recatagorize position since ducking can change origin
CategorizePosition();
}
else
{
player->m_Local.m_bDucking = false;
}
}
else
{
float fMore = VEC_DUCK_HULL_MIN[2] - VEC_HULL_MIN[2];
// Calc parametric time
duckFraction = SplineFraction( time, (1.0/TIME_TO_DUCK) );
//pmove->view_ofs[2] = ((VEC_DUCK_VIEW - fMore ) * duckFraction) + (VEC_VIEW * (1-duckFraction));
Vector vecViewOfs = player->GetViewOffset();
vecViewOfs[2] = ((VEC_DUCK_VIEW[2] - fMore ) * duckFraction) + (VEC_VIEW[2] * (1-duckFraction));
player->SetViewOffset(vecViewOfs);
}
}
}
else
{
// Try to unduck
FinishUnDuck();
}
}
// int buttonsChanged = ( mv->m_nOldButtons ^ mv->m_nButtons ); // These buttons have changed this frame
// int buttonsPressed = buttonsChanged & mv->m_nButtons; // The changed ones still down are "pressed"
// int buttonsReleased = buttonsChanged & mv->m_nOldButtons; // The changed ones which were previously down are "released"
//
// // Check to see if we are in the air.
// bool bInAir = ( player->GetGroundEntity() == NULL );
// bool bInDuck = ( player->GetFlags() & FL_DUCKING ) ? true : false;
// bool bDuckJump = ( player->m_Local.m_flJumpTime > 0.0f );
// bool bDuckJumpTime = ( player->m_Local.m_flDuckJumpTime > 0.0f );
//
// if ( mv->m_nButtons & IN_DUCK )
// {
// mv->m_nOldButtons |= IN_DUCK;
// }
// else
// {
// mv->m_nOldButtons &= ~IN_DUCK;
// }
//
// // Handle death.
// if ( IsDead() )
// return;
//
// // Slow down ducked players.
// HandleDuckingSpeedCrop();
//
// // If the player is holding down the duck button, the player is in duck transition, ducking, or duck-jumping.
// if ( ( mv->m_nButtons & IN_DUCK ) || player->m_Local.m_bDucking || bInDuck || bDuckJump )
// {
// // DUCK
// if ( ( mv->m_nButtons & IN_DUCK ) || bDuckJump )
// {
//// XBOX SERVER ONLY
//#if !defined(CLIENT_DLL) && defined(_XBOX)
// if ( buttonsPressed & IN_DUCK )
// {
// // Hinting logic
// if ( player->GetToggledDuckState() && player->m_nNumCrouches < NUM_CROUCH_HINTS )
// {
// UTIL_HudHintText( player, "#Valve_Hint_Crouch" );
// player->m_nNumCrouches++;
// }
// }
//#endif
// // Have the duck button pressed, but the player currently isn't in the duck position.
// if ( ( buttonsPressed & IN_DUCK ) && !bInDuck && !bDuckJump && !bDuckJumpTime )
// {
// player->m_Local.m_flDucktime = GAMEMOVEMENT_DUCK_TIME;
// player->m_Local.m_bDucking = true;
// }
//
// // The player is in duck transition and not duck-jumping.
// if ( player->m_Local.m_bDucking && !bDuckJump && !bDuckJumpTime )
// {
// float flDuckMilliseconds = max( 0.0f, GAMEMOVEMENT_DUCK_TIME - ( float )player->m_Local.m_flDucktime );
// float flDuckSeconds = flDuckMilliseconds * 0.001f;
//
// // Finish in duck transition when transition time is over, in "duck", in air.
// if ( ( flDuckSeconds > TIME_TO_DUCK ) || bInDuck || bInAir )
// {
// FinishDuck();
// }
// else
// {
// // Calc parametric time
// float flDuckFraction = SimpleSpline( flDuckSeconds / TIME_TO_DUCK );
// SetDuckedEyeOffset( flDuckFraction );
// }
// }
//
// if ( bDuckJump )
// {
// // Make the bounding box small immediately.
// if ( !bInDuck )
// {
// StartUnDuckJump();
// }
// else
// {
// // Check for a crouch override.
// if ( !( mv->m_nButtons & IN_DUCK ) )
// {
// trace_t trace;
// if ( CanUnDuckJump( trace ) )
// {
// FinishUnDuckJump( trace );
// player->m_Local.m_flDuckJumpTime = ( GAMEMOVEMENT_TIME_TO_UNDUCK * ( 1.0f - trace.fraction ) ) + GAMEMOVEMENT_TIME_TO_UNDUCK_INV;
// }
// }
// }
// }
// }
// // UNDUCK (or attempt to...)
// else
// {
// if ( player->m_Local.m_bInDuckJump )
// {
// // Check for a crouch override.
// if ( !( mv->m_nButtons & IN_DUCK ) )
// {
// trace_t trace;
// if ( CanUnDuckJump( trace ) )
// {
// FinishUnDuckJump( trace );
//
// if ( trace.fraction < 1.0f )
// {
// player->m_Local.m_flDuckJumpTime = ( GAMEMOVEMENT_TIME_TO_UNDUCK * ( 1.0f - trace.fraction ) ) + GAMEMOVEMENT_TIME_TO_UNDUCK_INV;
// }
// }
// }
// else
// {
// player->m_Local.m_bInDuckJump = false;
// }
// }
//
// if ( bDuckJumpTime )
// return;
//
// // Try to unduck unless automovement is not allowed
// // NOTE: When not onground, you can always unduck
// if ( player->m_Local.m_bAllowAutoMovement || bInAir )
// {
// // We released the duck button, we aren't in "duck" and we are not in the air - start unduck transition.
// if ( ( buttonsReleased & IN_DUCK ) )
// {
// if ( bInDuck && !bDuckJump )
// {
// player->m_Local.m_flDucktime = GAMEMOVEMENT_DUCK_TIME;
// }
// else if ( player->m_Local.m_bDucking && !player->m_Local.m_bDucked )
// {
// // Invert time if release before fully ducked!!!
// float unduckMilliseconds = 1000.0f * TIME_TO_UNDUCK;
// float duckMilliseconds = 1000.0f * TIME_TO_DUCK;
// float elapsedMilliseconds = GAMEMOVEMENT_DUCK_TIME - player->m_Local.m_flDucktime;
//
// float fracDucked = elapsedMilliseconds / duckMilliseconds;
// float remainingUnduckMilliseconds = fracDucked * unduckMilliseconds;
//
// player->m_Local.m_flDucktime = GAMEMOVEMENT_DUCK_TIME - unduckMilliseconds + remainingUnduckMilliseconds;
// }
// }
//
//
// // Check to see if we are capable of unducking.
// if ( CanUnduck() )
// {
// // or unducking
// if ( ( player->m_Local.m_bDucking || player->m_Local.m_bDucked ) )
// {
// float flDuckMilliseconds = max( 0.0f, GAMEMOVEMENT_DUCK_TIME - (float)player->m_Local.m_flDucktime );
// float flDuckSeconds = flDuckMilliseconds * 0.001f;
//
// // Finish ducking immediately if duck time is over or not on ground
// if ( flDuckSeconds > TIME_TO_UNDUCK || ( bInAir && !bDuckJump ) )
// {
// FinishUnDuck();
// }
// else
// {
// // Calc parametric time
// float flDuckFraction = SimpleSpline( 1.0f - ( flDuckSeconds / TIME_TO_UNDUCK ) );
// SetDuckedEyeOffset( flDuckFraction );
// player->m_Local.m_bDucking = true;
// }
// }
// }
// else
// {
// // Still under something where we can't unduck, so make sure we reset this timer so
// // that we'll unduck once we exit the tunnel, etc.
// if ( player->m_Local.m_flDucktime != GAMEMOVEMENT_DUCK_TIME )
// {
// SetDuckedEyeOffset(1.0f);
// player->m_Local.m_flDucktime = GAMEMOVEMENT_DUCK_TIME;
// }
// }
// }
// }
// }
// // HACK: (jimd 5/25/2006) we have a reoccuring bug (#50063 in Tracker) where the player's
// // view height gets left at the ducked height while the player is standing, but we haven't
// // been able to repro it to find the cause. It may be fixed now due to a change I'm
// // also making in UpdateDuckJumpEyeOffset but just in case, this code will sense the
// // problem and restore the eye to the proper position. It doesn't smooth the transition,
// // but it is preferable to leaving the player's view too low.
// //
// // If the player is still alive and not an observer, check to make sure that
// // his view height is at the standing height.
// else if ( !IsDead() && !player->IsObserver() )
// {
// if ( ( player->m_Local.m_flDuckJumpTime == 0.0f ) && ( player->GetViewOffset().z != GetPlayerViewOffset( false ).z ) )
// {
// // we should rarely ever get here, so assert so a coder knows when it happens
// //Assert(0); // |-- We get this every spawn, thanks.
// //DevMsg( 1, "Restoring player view height\n" );
//
// // set the eye height to the non-ducked height
// SetDuckedEyeOffset(0.0f);
// }
// }
}
//-----------------------------------------------------------------------------
// Purpose: Movement while building in Fortress Forever
//-----------------------------------------------------------------------------
void CGameMovement::FullBuildMove( void )
{
// Do nothing, super class does the work.
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CGameMovement::PlayerMove( void )
39673968396939703971397239733974
UpdateDuckJumpEyeOffset();
Duck();
// Don't run ladder code if dead on on a train
if ( !player->pl.deadflag && !(player->GetFlags() & FL_ONTRAIN) )
{
// If was not on a ladder now, but was on one before,
// get off of the ladder
42834284428542864287428842894290429142924293
UpdateDuckJumpEyeOffset();
Duck();
// If statement modifed by Mulch so players don't
// get randomly stuck on ladders while flying around in observer mode
// Don't run ladder code if dead or on a train
if ( !player->pl.deadflag && !(player->GetFlags() & FL_ONTRAIN) && (player->GetMoveType() != MOVETYPE_OBSERVER) )
{
// If was not on a ladder now, but was on one before,
// get off of the ladder
399239933994399539963997
switch (player->GetMoveType())
{
case MOVETYPE_NONE:
break;
case MOVETYPE_NOCLIP:
4311431243134314431543164317
switch (player->GetMoveType())
{
case MOVETYPE_NONE:
FullBuildMove();
break;
case MOVETYPE_NOCLIP:
4053405440554056405740584059
case MOVECOLLIDE_DEFAULT:
{
if (player->GetMoveCollide() == MOVECOLLIDE_FLY_BOUNCE)
backoff = 2.0 - player->m_surfaceFriction;
else
backoff = 1;
4373437443754376437743784379
case MOVECOLLIDE_DEFAULT:
{
if (player->GetMoveCollide() == MOVECOLLIDE_FLY_BOUNCE)
backoff = 2.0 - /*player->m_surfaceFriction*/ 1.0f; // |-- Mirv: More TFC Feeling (tm) friction
else
backoff = 1;