You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
305 lines
8.5 KiB
305 lines
8.5 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
|
|
//========= Copyright © 1996-2001, Valve LLC, All rights reserved. ============ |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
//============================================================================= |
|
#include "cbase.h" |
|
#include "gamemovement.h" |
|
#include "in_buttons.h" |
|
#include <stdarg.h> |
|
#include "movevars_shared.h" |
|
#include "engine/IEngineTrace.h" |
|
#include "SoundEmitterSystem/isoundemittersystembase.h" |
|
#include "decals.h" |
|
#include "tier0/vprof.h" |
|
#include "hl1_gamemovement.h" |
|
|
|
|
|
// Expose our interface. |
|
static CHL1GameMovement g_GameMovement; |
|
IGameMovement *g_pGameMovement = ( IGameMovement * )&g_GameMovement; |
|
|
|
EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CGameMovement, IGameMovement, INTERFACENAME_GAMEMOVEMENT, g_GameMovement ); |
|
|
|
#ifdef CLIENT_DLL |
|
#include "hl1/c_hl1mp_player.h" |
|
#else |
|
#include "hl1mp_player.h" |
|
#endif |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
bool CHL1GameMovement::CheckJumpButton( void ) |
|
{ |
|
m_pHL1Player = ToHL1Player( player ); |
|
|
|
Assert( m_pHL1Player ); |
|
|
|
if (m_pHL1Player->pl.deadflag) |
|
{ |
|
mv->m_nOldButtons |= IN_JUMP ; // don't jump again until released |
|
return false; |
|
} |
|
|
|
// See if we are waterjumping. If so, decrement count and return. |
|
if (m_pHL1Player->m_flWaterJumpTime) |
|
{ |
|
m_pHL1Player->m_flWaterJumpTime -= gpGlobals->frametime; |
|
if (m_pHL1Player->m_flWaterJumpTime < 0) |
|
m_pHL1Player->m_flWaterJumpTime = 0; |
|
|
|
return false; |
|
} |
|
|
|
// If we are in the water most of the way... |
|
if ( m_pHL1Player->GetWaterLevel() >= 2 ) |
|
{ |
|
// swimming, not jumping |
|
SetGroundEntity( NULL ); |
|
|
|
if(m_pHL1Player->GetWaterType() == CONTENTS_WATER) // We move up a certain amount |
|
mv->m_vecVelocity[2] = 100; |
|
else if (m_pHL1Player->GetWaterType() == CONTENTS_SLIME) |
|
mv->m_vecVelocity[2] = 80; |
|
|
|
// play swiming sound |
|
if ( m_pHL1Player->m_flSwimSoundTime <= 0 ) |
|
{ |
|
// Don't play sound again for 1 second |
|
m_pHL1Player->m_flSwimSoundTime = 1000; |
|
PlaySwimSound(); |
|
} |
|
|
|
return false; |
|
} |
|
|
|
// No more effect |
|
if (m_pHL1Player->GetGroundEntity() == NULL) |
|
{ |
|
mv->m_nOldButtons |= IN_JUMP; |
|
return false; // in air, so no effect |
|
} |
|
|
|
if ( mv->m_nOldButtons & IN_JUMP ) |
|
return false; // don't pogo stick |
|
|
|
// In the air now. |
|
SetGroundEntity( NULL ); |
|
|
|
m_pHL1Player->PlayStepSound( (Vector &)mv->GetAbsOrigin(), player->GetSurfaceData(), 1.0, true ); |
|
|
|
MoveHelper()->PlayerSetAnimation( PLAYER_JUMP ); |
|
|
|
float flGroundFactor = 1.0f; |
|
if ( player->GetSurfaceData() ) |
|
{ |
|
flGroundFactor = 1.0;//player->GetSurfaceData()->game.jumpFactor; |
|
} |
|
|
|
// Acclerate upward |
|
// If we are ducking... |
|
float startz = mv->m_vecVelocity[2]; |
|
if ( ( m_pHL1Player->m_Local.m_bDucking ) || ( m_pHL1Player->GetFlags() & FL_DUCKING ) ) |
|
{ |
|
// d = 0.5 * g * t^2 - distance traveled with linear accel |
|
// t = sqrt(2.0 * 45 / g) - how long to fall 45 units |
|
// v = g * t - velocity at the end (just invert it to jump up that high) |
|
// v = g * sqrt(2.0 * 45 / g ) |
|
// v^2 = g * g * 2.0 * 45 / g |
|
// v = sqrt( g * 2.0 * 45 ) |
|
|
|
// Adjust for super long jump module |
|
// UNDONE -- note this should be based on forward angles, not current velocity. |
|
if ( m_pHL1Player->m_bHasLongJump && |
|
( mv->m_nButtons & IN_DUCK ) && |
|
( m_pHL1Player->m_Local.m_flDucktime > 0 ) && |
|
mv->m_vecVelocity.Length() > 50 ) |
|
{ |
|
m_pHL1Player->m_Local.m_vecPunchAngle.Set( PITCH, -5 ); |
|
|
|
mv->m_vecVelocity = m_vecForward * PLAYER_LONGJUMP_SPEED * 1.6; |
|
mv->m_vecVelocity.z = sqrt(2 * 800 * 56.0); |
|
} |
|
else |
|
{ |
|
mv->m_vecVelocity[2] = flGroundFactor * sqrt(2 * 800 * 45.0); // 2 * gravity * height |
|
} |
|
} |
|
else |
|
{ |
|
mv->m_vecVelocity[2] += flGroundFactor * sqrt(2 * 800 * 45.0); // 2 * gravity * height |
|
} |
|
FinishGravity(); |
|
|
|
mv->m_outWishVel.z += mv->m_vecVelocity[2] - startz; |
|
mv->m_outStepHeight += 0.1f; |
|
|
|
if ( gpGlobals->maxClients > 1 ) |
|
#ifdef CLIENT_DLL |
|
(dynamic_cast<C_HL1MP_Player*>(m_pHL1Player))->DoAnimationEvent( PLAYERANIMEVENT_JUMP ); |
|
#else |
|
(dynamic_cast<CHL1MP_Player*>(m_pHL1Player))->DoAnimationEvent( PLAYERANIMEVENT_JUMP ); |
|
#endif |
|
|
|
// Flag that we jumped. |
|
mv->m_nOldButtons |= IN_JUMP; // don't jump again until released |
|
return true; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: See if duck button is pressed and do the appropriate things |
|
//----------------------------------------------------------------------------- |
|
void CHL1GameMovement::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; |
|
|
|
if ( mv->m_nButtons & IN_DUCK ) |
|
{ |
|
mv->m_nOldButtons |= IN_DUCK; |
|
} |
|
else |
|
{ |
|
mv->m_nOldButtons &= ~IN_DUCK; |
|
} |
|
|
|
// Handle death. |
|
if ( IsDead() ) |
|
{ |
|
if ( bInDuck ) |
|
{ |
|
// Unduck |
|
FinishUnDuck(); |
|
} |
|
return; |
|
} |
|
|
|
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 ) |
|
{ |
|
if ( ( mv->m_nButtons & IN_DUCK ) ) |
|
{ |
|
// Have the duck button pressed, but the player currently isn't in the duck position. |
|
if ( ( buttonsPressed & IN_DUCK ) && !bInDuck ) |
|
{ |
|
// Use 1 second so super long jump will work |
|
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 ) |
|
{ |
|
float flDuckMilliseconds = MAX( 0.0f, GAMEMOVEMENT_DUCK_TIME - ( float )player->m_Local.m_flDucktime ); |
|
float flDuckSeconds = flDuckMilliseconds / GAMEMOVEMENT_DUCK_TIME; |
|
|
|
// 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 ); |
|
} |
|
} |
|
} |
|
else |
|
{ |
|
// Try to unduck unless automovement is not allowed |
|
// NOTE: When not onground, you can always unduck |
|
if ( player->m_Local.m_bAllowAutoMovement || bInAir ) |
|
{ |
|
if ( ( buttonsReleased & IN_DUCK ) && bInDuck ) |
|
{ |
|
// Use 1 second so super long jump will work |
|
player->m_Local.m_flDucktime = GAMEMOVEMENT_DUCK_TIME; |
|
} |
|
|
|
// 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 / GAMEMOVEMENT_DUCK_TIME; |
|
|
|
// Finish ducking immediately if duck time is over or not on ground |
|
if ( flDuckSeconds > TIME_TO_UNDUCK || ( bInAir ) ) |
|
{ |
|
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. |
|
player->m_Local.m_flDucktime = GAMEMOVEMENT_DUCK_TIME; |
|
SetDuckedEyeOffset( 1.0f ); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
void CHL1GameMovement::HandleDuckingSpeedCrop() |
|
{ |
|
if ( !( m_iSpeedCropped & SPEED_CROPPED_DUCK ) ) |
|
{ |
|
if ( player->GetFlags() & FL_DUCKING ) |
|
{ |
|
float frac = 0.33333333f; |
|
mv->m_flForwardMove *= frac; |
|
mv->m_flSideMove *= frac; |
|
mv->m_flUpMove *= frac; |
|
m_iSpeedCropped |= SPEED_CROPPED_DUCK; |
|
} |
|
} |
|
} |
|
|
|
void CHL1GameMovement::CheckParameters( void ) |
|
{ |
|
if ( mv->m_nButtons & IN_SPEED ) |
|
{ |
|
mv->m_flClientMaxSpeed = 100; |
|
} |
|
else |
|
{ |
|
mv->m_flClientMaxSpeed = mv->m_flMaxSpeed; |
|
} |
|
|
|
CHL1_Player* pHL1Player = dynamic_cast<CHL1_Player*>(player); |
|
if( pHL1Player && pHL1Player->IsPullingObject() ) |
|
{ |
|
mv->m_flClientMaxSpeed = mv->m_flMaxSpeed * 0.5f; |
|
} |
|
|
|
BaseClass::CheckParameters(); |
|
}
|
|
|