summaryrefslogtreecommitdiff
path: root/game/server/tf2/tf_walker_strider.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_strider.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_strider.cpp')
-rw-r--r--game/server/tf2/tf_walker_strider.cpp395
1 files changed, 395 insertions, 0 deletions
diff --git a/game/server/tf2/tf_walker_strider.cpp b/game/server/tf2/tf_walker_strider.cpp
new file mode 100644
index 0000000..8fd9b36
--- /dev/null
+++ b/game/server/tf2/tf_walker_strider.cpp
@@ -0,0 +1,395 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "tf_walker_strider.h"
+#include "npcevent.h"
+#include "engine/IEngineSound.h"
+#include "tf_gamerules.h"
+#include "shake.h"
+#include "in_buttons.h"
+#include "studio.h"
+
+
+#define STRIDER_AE_FOOTSTEP_LEFT 1
+#define STRIDER_AE_FOOTSTEP_RIGHT 2
+#define STRIDER_AE_FOOTSTEP_BACK 3
+#define STRIDER_AE_FOOTSTEP_LEFTM 4
+#define STRIDER_AE_FOOTSTEP_RIGHTM 5
+#define STRIDER_AE_FOOTSTEP_BACKM 6
+#define STRIDER_AE_FOOTSTEP_LEFTL 7
+#define STRIDER_AE_FOOTSTEP_RIGHTL 8
+#define STRIDER_AE_FOOTSTEP_BACKL 9
+
+
+// How many inches/sec the strider's torso moves up and down to get the torso at the right height.
+#define STRIDER_TORSO_VERTICAL_SLIDE_SPEED 100
+#define STRIDER_FIRE_TIME 5
+#define STRIDER_FIRE_INTERVAL 0.3
+#define STRIDER_FIRE_ANGLE_ERROR 6 // N degrees of error when he fires.
+#define WALKER_STRIDER_MODEL "models/objects/walker_strider.mdl"
+
+
+IMPLEMENT_SERVERCLASS_ST( CWalkerStrider, DT_WalkerStrider )
+ SendPropInt( SENDINFO( m_bCrouched ), 1, SPROP_UNSIGNED )
+END_SEND_TABLE()
+LINK_ENTITY_TO_CLASS( walker_strider, CWalkerStrider );
+PRECACHE_REGISTER( walker_strider );
+
+
+char *g_StriderFeet[] =
+{
+ "left foot",
+ "right foot",
+ "back foot"
+};
+#define NUM_STRIDER_FEET ARRAYSIZE( g_StriderFeet )
+
+
+CWalkerStrider::CWalkerStrider()
+{
+ m_bCrouched = false;
+ m_flOriginToLowestLegHeight = -1;
+ m_flWantedZ = -1;
+ m_bFiring = false;
+ m_vDriverAngles.Init();
+}
+
+
+void CWalkerStrider::Precache()
+{
+ PrecacheModel( WALKER_STRIDER_MODEL );
+
+ PrecacheScriptSound( "Brush.Footstep" );
+ PrecacheScriptSound( "Brush.Fire" );
+
+ BaseClass::Precache();
+}
+
+
+void CWalkerStrider::Spawn()
+{
+ SpawnWalker(
+ WALKER_STRIDER_MODEL, // Model name.
+ OBJ_WALKER_STRIDER, // Object type.
+ Vector( -186, -157, -504 ), // Placement dimensions.
+ Vector( 194, 159, 41 ),
+ 200, // Health.
+ 1, // Max passengers.
+ 2.0 // 2x animation speed boost
+ );
+}
+
+bool CWalkerStrider::IsPassengerVisible( int nRole )
+{
+ if ( nRole == VEHICLE_ROLE_DRIVER )
+ return false;
+
+ return true;
+}
+
+
+void CWalkerStrider::Fire()
+{
+ EnableWalkMode( false );
+ m_bFiring = true;
+ m_flFireEndTime = gpGlobals->curtime + STRIDER_FIRE_TIME;
+ ResetSequence( LookupSequence( "shoot01a" ) );
+ m_flAnimTime = m_flPrevAnimTime = 0;
+ SetCycle( 0 );
+ m_flNextShootTime = gpGlobals->curtime;
+
+ m_vFireAngles[ROLL] = 0;
+ m_vFireAngles[PITCH] = m_vDriverAngles[PITCH];
+ m_vFireAngles[YAW] = GetAbsAngles()[YAW];
+
+ // Play the fire sound.
+ CPASAttenuationFilter filter( this, "Brush.Fire" );
+ EmitSound( filter, 0, "Brush.Fire", &GetAbsOrigin() );
+}
+
+
+void CWalkerStrider::Crouch()
+{
+ // Disable the base class's walking functionality while we're crouched.
+ EnableWalkMode( false );
+
+ m_bCrouched = true;
+ m_flNextCrouchTime = gpGlobals->curtime + 0.3;
+ ResetSequence( LookupSequence( "low" ) );
+
+ // HACK: there should be a better way to this.. like CBaseAnimating::ResetAnimation,
+ // or ResetSequence should do it.
+ m_flAnimTime = m_flPrevAnimTime = 0;
+ SetCycle( 0 );
+
+ // HACK CITY.. This forces it to invalidate the abs origins of the gun bases.
+ Vector vPos = GetLocalOrigin();
+ SetLocalOrigin( vPos + Vector( 100, 0, 0 ) );
+ SetLocalOrigin( vPos );
+}
+
+
+void CWalkerStrider::UnCrouch()
+{
+ EnableWalkMode( true );
+ m_flNextCrouchTime = gpGlobals->curtime + 0.3;
+ m_bCrouched = false;
+
+ // HACK CITY.. This forces it to invalidate the abs origins of the gun bases.
+ Vector vPos = GetLocalOrigin();
+ SetLocalOrigin( vPos + Vector( 100, 0, 0 ) );
+ SetLocalOrigin( vPos );
+}
+
+
+void CWalkerStrider::WalkerThink()
+{
+ float dt = GetTimeDelta();
+
+ BaseClass::WalkerThink();
+
+ if ( m_bCrouched )
+ {
+ // Just sit there until they hit IN_DUCK again.
+ if ( (m_LastButtons & IN_DUCK) && gpGlobals->curtime > m_flNextCrouchTime )
+ {
+ UnCrouch();
+ }
+ }
+ else
+ {
+ if ( gpGlobals->curtime > m_flNextCrouchTime )
+ {
+ if ( m_LastButtons & IN_DUCK )
+ {
+ // They want to crouch.
+ Crouch();
+ }
+ else if ( !m_bFiring && (m_LastButtons & IN_ATTACK) )
+ {
+ Fire();
+ }
+ }
+ }
+
+ m_vDriverAngles = m_vLastCmdViewAngles;
+ if ( m_bCrouched )
+ {
+ // The "low" animation gets back up at the end so don't let that happen.
+ SetCycle( MIN( GetCycle(), 0.5f ) );
+ }
+ else if ( m_bFiring )
+ {
+ if ( gpGlobals->curtime > m_flFireEndTime )
+ {
+ m_bFiring = false;
+ EnableWalkMode( true );
+ }
+ else
+ {
+ // Shoot?
+ if ( gpGlobals->curtime >= m_flNextShootTime )
+ {
+ Vector vSrc = GetAbsOrigin();
+ Vector vForward;
+
+ QAngle vFireAngles = m_vFireAngles;
+ vFireAngles[YAW] += RandomFloat( -STRIDER_FIRE_ANGLE_ERROR, STRIDER_FIRE_ANGLE_ERROR );
+ vFireAngles[PITCH] += RandomFloat( -STRIDER_FIRE_ANGLE_ERROR, STRIDER_FIRE_ANGLE_ERROR );
+
+ AngleVectors( vFireAngles, &vForward );
+ trace_t trace;
+ UTIL_TraceLine( vSrc, vSrc + vForward * 2000, MASK_SOLID, this, COLLISION_GROUP_NONE, &trace );
+
+ Vector vHitPos = trace.endpos;
+ float flDamageRadius = 100;
+ float flDamage = 50;
+
+ CBasePlayer *pDriver = GetPassenger( VEHICLE_ROLE_DRIVER );
+ if ( pDriver )
+ {
+ UTIL_ImpactTrace( &trace, DMG_ENERGYBEAM, "Strider" );
+
+ // Tell the client entity to make a beam effect.
+ EntityMessageBegin( this, true );
+ WRITE_VEC3COORD( vHitPos );
+ MessageEnd();
+
+ UTIL_ScreenShake( vHitPos, 10.0, 150.0, 1.0, 100, SHAKE_START );
+ RadiusDamage( CTakeDamageInfo( this, pDriver, flDamage, DMG_BLAST ), vHitPos, flDamageRadius, CLASS_NONE, NULL );
+ }
+
+ m_flNextShootTime = gpGlobals->curtime + STRIDER_FIRE_INTERVAL;
+ }
+ }
+ }
+ else
+ {
+ // Move our torso within range of our feet.
+ if ( m_flOriginToLowestLegHeight != -1 )
+ {
+ trace_t trace;
+ UTIL_TraceLine(
+ GetAbsOrigin(),
+ GetAbsOrigin() - Vector( 0, 0, 2000 ),
+ MASK_SOLID_BRUSHONLY,
+ this,
+ COLLISION_GROUP_NONE,
+ &trace );
+
+ if ( trace.fraction < 1 )
+ {
+ m_flWantedZ = trace.endpos.z + m_flOriginToLowestLegHeight;
+ }
+
+ // Move our Z towards the wanted Z.
+ if ( m_flWantedZ != -1 )
+ {
+ Vector vCur = GetAbsOrigin();
+ vCur.z = Approach( m_flWantedZ, vCur.z, STRIDER_TORSO_VERTICAL_SLIDE_SPEED * dt );
+ SetAbsOrigin( vCur );
+ }
+ }
+ }
+}
+
+
+void CWalkerStrider::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
+{
+ // Sapper removal
+ if ( RemoveEnemyAttachments( pActivator ) )
+ return;
+
+ CBaseTFPlayer *pPlayer = dynamic_cast<CBaseTFPlayer*>(pActivator);
+ if ( !pPlayer || !InSameTeam( pPlayer ) )
+ return;
+
+ // Ok, put them in the driver role.
+ AttemptToBoardVehicle( pPlayer );
+}
+
+
+void CWalkerStrider::SetupMove( CBasePlayer *pPlayer, CUserCmd *ucmd, IMoveHelper *pHelper, CMoveData *move )
+{
+ BaseClass::SetupMove( pPlayer, ucmd, pHelper, move );
+}
+
+
+//
+//
+// This is a TOTAL hack, but we don't have any nodes that work well at all for mounted guns.
+// This all goes away when we get a new model.
+//
+//
+float sideDist = 90;
+float downDist = -400;
+bool CWalkerStrider::GetAttachment( int iAttachment, matrix3x4_t &attachmentToWorld )
+{
+ CStudioHdr *pStudioHdr = GetModelPtr( );
+ if ( !pStudioHdr || iAttachment < 1 || iAttachment > pStudioHdr->GetNumAttachments() )
+ {
+ return false;
+ }
+
+ Vector vLocalPos( 0, 0, 0 );
+ const mstudioattachment_t &pAttachment = pStudioHdr->pAttachment( iAttachment-1 );
+ if ( stricmp( pAttachment.pszName(), "build_point_left_gun" ) == 0 )
+ {
+ vLocalPos.y = sideDist;
+ }
+ else if ( stricmp( pAttachment.pszName(), "build_point_right_gun" ) == 0 )
+ {
+ vLocalPos.y = -sideDist;
+ }
+ else if ( stricmp( pAttachment.pszName(), "ThirdPersonCameraOrigin" ) == 0 )
+ {
+ }
+ else
+ {
+ // Ok, it's not one of our magical attachments. Use the regular attachment setup stuff.
+ return BaseClass::GetAttachment( iAttachment, attachmentToWorld );
+ }
+
+ if ( m_bCrouched )
+ {
+ vLocalPos.z += downDist;
+ }
+
+ // Now build the output matrix.
+ matrix3x4_t localMatrix;
+ SetIdentityMatrix( localMatrix );
+ PositionMatrix( vLocalPos, localMatrix );
+
+ ConcatTransforms( EntityToWorldTransform(), localMatrix, attachmentToWorld );
+ return true;
+}
+
+
+bool CWalkerStrider::StartBuilding( CBaseEntity *pBuilder )
+{
+ if ( !BaseClass::StartBuilding( pBuilder ) )
+ return false;
+
+ // Now figure out our ideal Z distance from our lowest foot to our torso.
+ Vector vOrigin;
+ QAngle vAngles;
+ BaseClass::GetAttachment( "left foot", vOrigin, vAngles );
+ m_flOriginToLowestLegHeight = GetAbsOrigin().z - vOrigin.z;
+ m_flOriginToLowestLegHeight -= 40; // fudge it a little so the legs have room to stretch.
+ return true;
+}
+
+
+void CWalkerStrider::FootHit( const char *pFootName )
+{
+ if ( m_bCrouched || gpGlobals->curtime > m_flDontMakeSoundsUntil )
+ {
+ Vector footPosition;
+ QAngle angles;
+
+ ((BaseClass*)this)->GetAttachment( pFootName, footPosition, angles );
+ CPASAttenuationFilter filter( this, "Brush.Footstep" );
+ EmitSound( filter, entindex(), "Brush.Footstep", &footPosition );
+
+ UTIL_ScreenShake( footPosition, 20.0, 1.0, 0.5, 200, SHAKE_START, false );
+
+ CBasePlayer *pPlayer = GetPassenger( VEHICLE_ROLE_DRIVER );
+ if ( pPlayer )
+ {
+ CTakeDamageInfo info( this, pPlayer, 20, DMG_CLUB );
+ TFGameRules()->RadiusDamage( info, footPosition, 200, CLASS_NONE );
+ }
+
+ m_flDontMakeSoundsUntil = gpGlobals->curtime + 0.4;
+ }
+}
+
+
+void CWalkerStrider::HandleAnimEvent( animevent_t *pEvent )
+{
+ switch( pEvent->event )
+ {
+ case STRIDER_AE_FOOTSTEP_LEFT:
+ case STRIDER_AE_FOOTSTEP_LEFTM:
+ case STRIDER_AE_FOOTSTEP_LEFTL:
+ FootHit( "left foot" );
+ break;
+
+ case STRIDER_AE_FOOTSTEP_RIGHT:
+ case STRIDER_AE_FOOTSTEP_RIGHTM:
+ case STRIDER_AE_FOOTSTEP_RIGHTL:
+ FootHit( "right foot" );
+ break;
+
+ case STRIDER_AE_FOOTSTEP_BACK:
+ case STRIDER_AE_FOOTSTEP_BACKM:
+ case STRIDER_AE_FOOTSTEP_BACKL:
+ FootHit( "back foot" );
+ break;
+ }
+}
+