diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/server/tf2/tf_walker_strider.cpp | |
| download | archived-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.cpp | 395 |
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; + } +} + |