summaryrefslogtreecommitdiff
path: root/game/server/tf2/tf_walker_base.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/server/tf2/tf_walker_base.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'game/server/tf2/tf_walker_base.cpp')
-rw-r--r--game/server/tf2/tf_walker_base.cpp302
1 files changed, 302 insertions, 0 deletions
diff --git a/game/server/tf2/tf_walker_base.cpp b/game/server/tf2/tf_walker_base.cpp
new file mode 100644
index 0000000..7fa3711
--- /dev/null
+++ b/game/server/tf2/tf_walker_base.cpp
@@ -0,0 +1,302 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "tf_walker_base.h"
+
+
+#include "in_buttons.h"
+#include "shake.h"
+
+
+static float MAX_WALKER_VEL = 100;
+
+
+IMPLEMENT_SERVERCLASS_ST( CWalkerBase, DT_WalkerBase )
+END_SEND_TABLE()
+
+
+CWalkerBase::CWalkerBase()
+{
+ m_vSteerVelocity.Init();
+ m_iMovePoseParamX = -1;
+ m_iMovePoseParamY = -1;
+ m_bWalkMode = false;
+ m_flDontMakeSoundsUntil = 0;
+ m_flPlaybackSpeedBoost = 1;
+ m_flVelocityDecayRate = 80;
+ m_LastButtons = 0;
+ m_vLastCmdViewAngles.Init();
+}
+
+
+void CWalkerBase::SpawnWalker(
+ const char *pModelName,
+ int objectType,
+ const Vector &vPlacementMins,
+ const Vector &vPlacementMaxs,
+ int iHealth,
+ int nMaxPassengers,
+ float flPlaybackSpeedBoost
+ )
+{
+ SetModel( pModelName );
+ SetType( objectType );
+
+ UTIL_SetSize( this, vPlacementMins, vPlacementMaxs );
+ m_iHealth = iHealth;
+ m_flPlaybackSpeedBoost = flPlaybackSpeedBoost;
+
+ m_takedamage = DAMAGE_YES;
+ SetMaxPassengerCount( nMaxPassengers );
+
+
+
+ // The model should be set before the derived class calls our Spawn().
+ Assert( GetModel() );
+
+ // By default, all walkers use the walk_box animation as they move.
+ m_iMovePoseParamX = LookupPoseParameter( "move_x" );
+ m_iMovePoseParamY = LookupPoseParameter( "move_y" );
+ EnableWalkMode( true );
+
+ // The base class spawn sets a default collision group, so this needs to
+ // be called post.
+ SetCollisionGroup( COLLISION_GROUP_VEHICLE );
+
+ BaseClass::Spawn();
+
+
+ // HACKHACK: this is just so CBaseObject doesn't call StudioFrameAdvance for us. We should probably have
+ // a specific flag for this behavior.
+ m_fObjectFlags |= OF_DOESNT_HAVE_A_MODEL;
+ m_fObjectFlags &= ~OF_MUST_BE_BUILT_ON_ATTACHMENT;
+
+
+ // We animate, so let's not use manual mode for now.
+ SetMoveType( MOVETYPE_STEP );
+ AddSolidFlags( FSOLID_CUSTOMRAYTEST | FSOLID_CUSTOMBOXTEST );
+
+ EnableServerIK();
+
+ SetContextThink( WalkerThink, gpGlobals->curtime, "WalkerThink" );
+}
+
+void CWalkerBase::EnableWalkMode( bool bEnable )
+{
+ m_bWalkMode = bEnable;
+
+ // Stop any movement..
+ m_vSteerVelocity.Init();
+
+ if ( bEnable )
+ {
+ ResetSequence( LookupSequence( "walk_box" ) );
+
+ // HACK: there should be a better way to this.. like CBaseAnimating::ResetAnimation,
+ // or ResetSequence should do it.
+ SetCycle( 0 );
+ }
+}
+
+
+void CWalkerBase::AdjustInitialBuildAngles()
+{
+ QAngle vNewAngles = GetAbsAngles();
+ vNewAngles[YAW] += 90;
+ SetAbsAngles( vNewAngles );
+}
+
+
+void CWalkerBase::WalkerThink()
+{
+ float dt = GetTimeDelta();
+
+ // Decay our velocity.
+ if ( m_bWalkMode )
+ {
+ m_flPlaybackRate = m_flPlaybackSpeedBoost;
+
+
+ float flDecayRate = m_flVelocityDecayRate;
+
+ float flLen = m_vSteerVelocity.Length();
+ Vector2DNormalize( m_vSteerVelocity );
+
+ float flDecayAmt = flDecayRate * dt;
+ flLen = MAX( 0, flLen - flDecayAmt );
+ m_vSteerVelocity *= flLen;
+
+
+ // Setup our pose parameters.
+ SetPoseParameter( m_iMovePoseParamX, RemapVal( m_vSteerVelocity.x, -MAX_WALKER_VEL, MAX_WALKER_VEL, -1, 1 ) );
+ SetPoseParameter( m_iMovePoseParamY, RemapVal( m_vSteerVelocity.y, -MAX_WALKER_VEL, MAX_WALKER_VEL, -1, 1 ) );
+
+ // Use an idle animation if they're not moving.
+ int iWantedSequence = LookupSequence( "walk_box" );
+ if ( m_vSteerVelocity.x == 0 && m_vSteerVelocity.y == 0 )
+ {
+ iWantedSequence = LookupSequence( "idle" );
+
+ // HACK: HL2 Strider has no idle
+ if ( iWantedSequence == -1 )
+ iWantedSequence = LookupSequence( "ragdoll" );
+ }
+
+ if ( iWantedSequence != -1 && GetSequence() != iWantedSequence )
+ ResetSequence( iWantedSequence );
+ }
+
+
+ // Now ask the model how far it thought it moved based on the animation.
+ // Turns out the animation thinks it's moving just a tiny bit, even when we're centered on the idle animation,
+ // so we just force it not to move here if we know we're not supposed to move.
+ if ( m_vSteerVelocity.Length() > 0 )
+ {
+ Vector vNewPos = GetWalkerLocalMovement();
+
+ SetLocalOrigin( vNewPos );
+ }
+
+
+ // Hard-coded for now. These should come from the vehicle's script eventually.
+ // Now slowly rotate towards the player's eye angles.
+ CBasePlayer *pPlayer = GetPassenger( VEHICLE_ROLE_DRIVER );
+ if ( pPlayer )
+ {
+ static float flAccelRate = 180;
+ static float flRotateRate = 60;
+
+
+ // Figure out a force to apply to our current velocity.
+ Vector2D vAccel( 0, 0 );
+
+ if ( m_LastButtons & IN_FORWARD )
+ vAccel.x += flAccelRate;
+
+ if ( m_LastButtons & IN_BACK )
+ vAccel.x -= flAccelRate;
+
+ if ( m_LastButtons & IN_MOVELEFT )
+ vAccel.y -= flAccelRate;
+
+ if ( m_LastButtons & IN_MOVERIGHT )
+ vAccel.y += flAccelRate;
+
+ m_vSteerVelocity += vAccel * dt;
+
+
+ m_vSteerVelocity.x = clamp( m_vSteerVelocity.x, -MAX_WALKER_VEL, MAX_WALKER_VEL );
+ m_vSteerVelocity.y = clamp( m_vSteerVelocity.y, -MAX_WALKER_VEL, MAX_WALKER_VEL );
+
+
+ float wantedYaw = m_vLastCmdViewAngles[YAW];
+ QAngle curAngles = GetAbsAngles();
+ curAngles[YAW] = ApproachAngle( wantedYaw, curAngles[YAW], flRotateRate * dt );
+ SetAbsAngles( curAngles );
+ }
+
+
+ DispatchAnimEvents( this );
+
+
+ // Get another think.
+ SetContextThink( WalkerThink, gpGlobals->curtime + dt, "WalkerThink" );
+}
+
+
+Vector CWalkerBase::GetWalkerLocalMovement()
+{
+ bool bIgnored;
+ Vector vNewPos;
+ QAngle vNewAngles;
+ GetIntervalMovement( GetAnimTimeInterval(), bIgnored, vNewPos, vNewAngles );
+ return vNewPos;
+}
+
+
+const Vector2D& CWalkerBase::GetSteerVelocity() const
+{
+ return m_vSteerVelocity;
+}
+
+
+
+void CWalkerBase::Spawn()
+{
+ // Derived classes should call SpawnWalker instead of chaining down to CWalkerBase::Spawn().
+ Assert( false );
+}
+
+
+void CWalkerBase::Activate()
+{
+ WalkerActivate();
+ BaseClass::Activate();
+}
+
+void CWalkerBase::WalkerActivate( void )
+{
+ // Until we're finished building, turn off vphysics-based motion
+ SetSolid( SOLID_VPHYSICS );
+ VPhysicsInitStatic();
+
+ SetPoseParameter( m_iMovePoseParamX, 0 );
+ SetPoseParameter( m_iMovePoseParamY, 0 );
+}
+
+
+void CWalkerBase::SetVelocityDecayRate( float flDecayRate )
+{
+ m_flVelocityDecayRate = flDecayRate;
+}
+
+
+float CWalkerBase::GetTimeDelta() const
+{
+ return 0.1;
+}
+
+
+void CWalkerBase::SetupMove( CBasePlayer *pPlayer, CUserCmd *ucmd, IMoveHelper *pHelper, CMoveData *move )
+{
+ // This calls StudioFrameAdvance for us.
+ //BaseClass::SetupMove( pPlayer, ucmd, pHelper, move );
+
+ // Lose control when the player dies
+ if ( pPlayer->IsAlive() == false )
+ {
+ m_LastButtons = 0;
+ return;
+ }
+
+ // Only the driver gets to drive.
+ int nRole = GetPassengerRole( pPlayer );
+ if ( nRole != VEHICLE_ROLE_DRIVER )
+ return;
+
+ m_LastButtons = ucmd->buttons;
+ m_vLastCmdViewAngles = ucmd->viewangles;
+}
+
+
+bool CWalkerBase::IsPassengerVisible( int nRole )
+{
+ return true;
+}
+
+
+bool CWalkerBase::StartBuilding( CBaseEntity *pBuilder )
+{
+ if ( !BaseClass::StartBuilding( pBuilder ) )
+ return false;
+
+ WalkerActivate();
+ return true;
+}
+
+
+