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_ministrider.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_ministrider.cpp')
| -rw-r--r-- | game/server/tf2/tf_walker_ministrider.cpp | 515 |
1 files changed, 515 insertions, 0 deletions
diff --git a/game/server/tf2/tf_walker_ministrider.cpp b/game/server/tf2/tf_walker_ministrider.cpp new file mode 100644 index 0000000..3bc406a --- /dev/null +++ b/game/server/tf2/tf_walker_ministrider.cpp @@ -0,0 +1,515 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include "cbase.h" +#include "tf_walker_ministrider.h" +#include "in_buttons.h" +#include "studio.h" +#include "shake.h" +#include "tf_gamerules.h" +#include "npcevent.h" +#include "ndebugoverlay.h" +#include "te_effect_dispatch.h" +#include "beam_shared.h" +#include "ai_activity.h" + +#define WALKER_MINI_STRIDER_MODEL "models/objects/alien_vehicle_strider.mdl" +#define STRIDER_TORSO_VERTICAL_SLIDE_SPEED 100 + +float LARGE_GUN_FIRE_TIME = 3; + +// Skirmisher CVars +ConVar tf_skirmisher_speed( "tf_skirmisher_speed", "300" ); +ConVar tf_skirmisher_machinegun_range( "tf_skirmisher_machinegun_range", "2000" ); +ConVar tf_skirmisher_machinegun_damage( "tf_skirmisher_machinegun_damage", "20" ); +ConVar tf_skirmisher_machinegun_rof( "tf_skirmisher_machinegun_rof", "10" ); + +IMPLEMENT_SERVERCLASS_ST( CWalkerMiniStrider, DT_WalkerMiniStrider ) +END_SEND_TABLE() + +LINK_ENTITY_TO_CLASS( walker_mini_strider, CWalkerMiniStrider ); +PRECACHE_REGISTER( walker_mini_strider ); + + + +CWalkerMiniStrider::CWalkerMiniStrider() +{ + m_flWantedZ = -1; + m_bFiringMachineGun = m_bFiringLargeGun = false; + m_flOriginToLowestLegHeight = 133; + m_State = STATE_NORMAL; + m_bFiringLeftGun = true; + m_flNextFootstepSoundTime = 0; +} + + +CWalkerMiniStrider::~CWalkerMiniStrider() +{ + UTIL_Remove( m_pEnergyBeam ); +} + + +void CWalkerMiniStrider::Precache() +{ + PrecacheModel( WALKER_MINI_STRIDER_MODEL ); + + PrecacheScriptSound( "Skirmisher.Footstep" ); + PrecacheScriptSound( "Skirmisher.GunSound" ); + PrecacheScriptSound( "Skirmisher.GunChargeSound" ); + + BaseClass::Precache(); +} + + +void CWalkerMiniStrider::Spawn() +{ + SpawnWalker( + WALKER_MINI_STRIDER_MODEL, // Model name. + OBJ_WALKER_MINI_STRIDER, // Object type. + Vector( 0, 0, 140 ) + Vector( -100, -100, -100 ), // Placement dimensions. + Vector( 0, 0, 140 ) + Vector( 100, 100, 100 ), + 200, // Health. + 1, // Max passengers. + 1.0 // 1x speed multiplier + ); + + SetVelocityDecayRate( 110 ); +} + + +bool CWalkerMiniStrider::IsPassengerVisible( int nRole ) +{ + if ( nRole == VEHICLE_ROLE_DRIVER ) + return false; + + return true; +} + + +void CWalkerMiniStrider::StartFiringMachineGun() +{ + StopFiringLargeGun(); + m_bFiringMachineGun = true; + m_flNextShootTime = gpGlobals->curtime; +} + + +void CWalkerMiniStrider::StopFiringMachineGun() +{ + m_bFiringMachineGun = false; +} + + +Vector CWalkerMiniStrider::GetLargeGunShootOrigin() +{ + Vector vRet; + QAngle dummyAngle; + if ( GetAttachment( LookupAttachment( "LargeGun" ), vRet, dummyAngle ) ) + { + return vRet; + } + else + { + return GetAbsOrigin(); + } +} + + +void CWalkerMiniStrider::StartFiringLargeGun() +{ + CBasePlayer *pPlayer = GetPassenger( VEHICLE_ROLE_DRIVER ); + Assert( pPlayer ); + if ( !pPlayer ) + return; + + // Figure out what we're shooting at. + Vector vSrc = GetLargeGunShootOrigin(); + + Vector vEyePos = pPlayer->EyePosition(); + Vector vEyeForward; + AngleVectors( pPlayer->LocalEyeAngles(), &vEyeForward ); + + trace_t trace; + UTIL_TraceLine( vEyePos, vEyePos + vEyeForward * 2000, MASK_SOLID, this, COLLISION_GROUP_NONE, &trace ); + if ( trace.fraction < 1 ) + { + m_vLargeGunForward = trace.endpos - vSrc; + VectorNormalize( m_vLargeGunForward ); + + trace_t trace; + UTIL_TraceLine( vSrc, vSrc + m_vLargeGunForward * 2000, MASK_SOLID, this, COLLISION_GROUP_NONE, &trace ); + if ( trace.fraction < 1 ) + { + EnableWalkMode( false ); + + m_vLargeGunTargetPos = trace.endpos; + m_flLargeGunCountdown = LARGE_GUN_FIRE_TIME; + m_bFiringLargeGun = true; + + // Show an energy beam until we actually shoot. + m_pEnergyBeam = CBeam::BeamCreate( "sprites/physbeam.vmt", 25 ); + m_pEnergyBeam->SetColor( 255, 0, 0 ); + m_pEnergyBeam->SetBrightness( 100 ); + m_pEnergyBeam->SetNoise( 4 ); + m_pEnergyBeam->PointsInit( vSrc, m_vLargeGunTargetPos ); + m_pEnergyBeam->LiveForTime( LARGE_GUN_FIRE_TIME ); + + // Play a charge-up sound. + CPASAttenuationFilter filter( this, "Skirmisher.GunChargeSound" ); + EmitSound( filter, 0, "Skirmisher.GunChargeSound", &vSrc ); + } + } +} + + +void CWalkerMiniStrider::StopFiringLargeGun() +{ + if ( m_bFiringLargeGun ) + { + m_bFiringLargeGun = false; + + UTIL_Remove( m_pEnergyBeam ); + m_pEnergyBeam = NULL; + + EnableWalkMode( true ); + } +} + + +void CWalkerMiniStrider::UpdateLargeGun() +{ + float dt = GetTimeDelta(); + + if ( !m_bFiringLargeGun ) + return; + + m_flLargeGunCountdown -= dt; + if ( m_flLargeGunCountdown <= 0 ) + { + // Fire! + Vector vSrc = GetLargeGunShootOrigin(); + trace_t trace; + UTIL_TraceLine( vSrc, vSrc + m_vLargeGunForward * 2000, MASK_SOLID, this, COLLISION_GROUP_NONE, &trace ); + if ( trace.fraction < 1 ) + { + CBasePlayer *pDriver = GetPassenger( VEHICLE_ROLE_DRIVER ); + if ( pDriver ) + { + UTIL_ImpactTrace( &trace, DMG_ENERGYBEAM, "Strider" ); + + Vector vHitPos = trace.endpos; + float flDamageRadius = 100; + float flDamage = 100; + + CPASFilter filter( vHitPos ); + te->Explosion( filter, 0.0, + &vHitPos, + g_sModelIndexFireball, + 2.0, + 15, + TE_EXPLFLAG_NONE, + flDamageRadius, + flDamage ); + + UTIL_ScreenShake( vHitPos, 10.0, 150.0, 1.0, 100, SHAKE_START ); + RadiusDamage( CTakeDamageInfo( this, pDriver, flDamage, DMG_BLAST ), vHitPos, flDamageRadius, CLASS_NONE, NULL ); + } + } + + StopFiringLargeGun(); + } +} + + +void CWalkerMiniStrider::Crouch() +{ + if ( m_State == STATE_CROUCHING || m_State == STATE_CROUCHED ) + return; + + // Disable the base class's walking functionality while we're crouched. + EnableWalkMode( false ); + + SetActivity( ACT_CROUCH ); + m_flCrouchTimer = SequenceDuration(); + m_State = STATE_CROUCHING; +} + + +void CWalkerMiniStrider::UnCrouch() +{ + if ( m_State == STATE_CROUCHING || m_State == STATE_UNCROUCHING || m_State == STATE_NORMAL ) + return; + + SetActivity( ACT_STAND ); + + m_flCrouchTimer = SequenceDuration(); + + m_State = STATE_UNCROUCHING; +} + + +void CWalkerMiniStrider::UpdateCrouch() +{ + float dt = GetTimeDelta(); + + m_flCrouchTimer -= dt; + if ( m_flCrouchTimer <= 0 ) + { + if ( m_State == STATE_CROUCHING ) + { + m_State = STATE_CROUCHED; + SetActivity( ACT_CROUCHIDLE ); + } + else if ( m_State == STATE_UNCROUCHING ) + { + EnableWalkMode( true ); + m_State = STATE_NORMAL; + SetActivity( ACT_IDLE ); + } + } +} + + +void CWalkerMiniStrider::FireMachineGun() +{ + CBaseEntity *pDriver = GetPassenger( VEHICLE_ROLE_DRIVER ); + if ( pDriver ) + { + // Alternate the gun we're firing + char *attachmentNames[2] = { "MachineGun_Left", "MachineGun_Right" }; + int iAttachment = LookupAttachment( attachmentNames[!m_bFiringLeftGun] ); + m_bFiringLeftGun = !m_bFiringLeftGun; + + Vector vAttachmentPos; + QAngle vAttachmentAngles; + GetAttachment( iAttachment, vAttachmentPos, vAttachmentAngles ); + + Vector vEyePos = pDriver->EyePosition(); + Vector vEyeForward; + QAngle vecAngles = pDriver->LocalEyeAngles(); + // Use the skirmisher's yaw + vecAngles[YAW] = GetAbsAngles()[YAW]; + AngleVectors( vecAngles, &vEyeForward ); + + // Trace ahead to find out where the crosshair is aiming + trace_t trace; + float flMaxRange = tf_skirmisher_machinegun_range.GetFloat(); + UTIL_TraceLine( + vEyePos, + vEyePos + vEyeForward * flMaxRange, + MASK_SOLID, + this, + COLLISION_GROUP_NONE, + &trace ); + + Vector vecDir; + if ( trace.fraction < 1.0 ) + { + vecDir = (trace.endpos - vAttachmentPos ); + VectorNormalize( vecDir ); + } + else + { + vecDir = vEyeForward; + } + + // Shoot! + TFGameRules()->FireBullets( CTakeDamageInfo( this, pDriver, tf_skirmisher_machinegun_damage.GetFloat(), DMG_BULLET ), + 1, // Num shots + vAttachmentPos, + vecDir, + VECTOR_CONE_3DEGREES, // Spread + flMaxRange, // Range + DMG_BULLET, + 1, // Tracer freq + entindex(), + iAttachment, // Attachment ID + "MinigunTracer" ); + + m_flNextShootTime += (1.0f / tf_skirmisher_machinegun_rof.GetFloat()); + + // Play the fire sound. + Vector vCenter = WorldSpaceCenter(); + CPASAttenuationFilter filter( this, "Skirmisher.GunSound" ); + EmitSound( filter, 0, "Skirmisher.GunSound", &vCenter ); + } +} + + +void CWalkerMiniStrider::WalkerThink() +{ + float dt = GetTimeDelta(); + + BaseClass::WalkerThink(); + + // Shoot the machine gun? + if ( !m_bFiringLargeGun ) + { + if ( m_LastButtons & IN_ATTACK ) + { + if ( !m_bFiringMachineGun ) + StartFiringMachineGun(); + } + else if ( m_bFiringMachineGun ) + { + StopFiringMachineGun(); + } + } + + // Fire the large gun? + if ( !m_bFiringMachineGun ) + { + if ( m_LastButtons & IN_ATTACK2 ) + { + if ( !m_bFiringLargeGun ) + StartFiringLargeGun(); + } + } + + + UpdateCrouch(); + + // Make sure it's crouched when there is no driver. + if ( GetPassenger( VEHICLE_ROLE_DRIVER ) ) + { + if ( m_LastButtons & IN_DUCK ) + { + Crouch(); + } + else + { + UnCrouch(); + } + } + else + { + Crouch(); + } + + if ( m_bFiringMachineGun ) + { + while ( gpGlobals->curtime > m_flNextShootTime ) + { + FireMachineGun(); + } + } + + UpdateLargeGun(); + + // Move our torso within range of our feet. + if ( m_flOriginToLowestLegHeight != -1 ) + { + Vector vCenter = WorldSpaceCenter(); + + //NDebugOverlay::EntityBounds( this, 255, 100, 0, 0 ,0 ); + //NDebugOverlay::Line( vCenter, vCenter-Vector(0,0,2000), 255,0,0, true, 0 ); + + trace_t trace; + UTIL_TraceLine( + vCenter, + vCenter - 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 = vCenter; + vCur.z = Approach( m_flWantedZ, vCur.z, STRIDER_TORSO_VERTICAL_SLIDE_SPEED * dt ); + SetAbsOrigin( GetAbsOrigin() + Vector( 0, 0, vCur.z - vCenter.z ) ); + } + } +} + + +void CWalkerMiniStrider::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 CWalkerMiniStrider::SetupMove( CBasePlayer *pPlayer, CUserCmd *ucmd, IMoveHelper *pHelper, CMoveData *move ) +{ + BaseClass::SetupMove( pPlayer, ucmd, pHelper, move ); +} + + +bool CWalkerMiniStrider::StartBuilding( CBaseEntity *pBuilder ) +{ + return BaseClass::StartBuilding( pBuilder ); +} + + +Vector CWalkerMiniStrider::GetWalkerLocalMovement() +{ + float dt = GetTimeDelta(); + + Vector vForward, vRight; + AngleVectors( GetLocalAngles(), &vForward, &vRight, NULL ); + + float flSpeed = (tf_skirmisher_speed.GetFloat() / 100) * dt; + Vector vMovement = + vForward * (GetSteerVelocity().x * flSpeed) + + vRight * (GetSteerVelocity().y * flSpeed); + + return GetLocalOrigin() + vMovement; +} + + +void CWalkerMiniStrider::SetPassenger( int nRole, CBasePlayer *pPassenger ) +{ + BaseClass::SetPassenger( nRole, pPassenger ); + + if ( nRole == VEHICLE_ROLE_DRIVER && pPassenger ) + UnCrouch(); +} + + +void CWalkerMiniStrider::FootHit( const char *pFootName ) +{ + if ( gpGlobals->curtime >= m_flNextFootstepSoundTime ) + { + Vector footPosition; + QAngle angles; + + ((BaseClass*)this)->GetAttachment( pFootName, footPosition, angles ); + CPASAttenuationFilter filter( this, "Skirmisher.Footstep" ); + EmitSound( filter, entindex(), "Skirmisher.Footstep", &footPosition ); + + m_flNextFootstepSoundTime = gpGlobals->curtime + 0.2; + } +} + + +void CWalkerMiniStrider::HandleAnimEvent( animevent_t *pEvent ) +{ + switch( pEvent->event ) + { + case 1: + case 2: + case 3: + { + FootHit( "back foot" ); + } + break; + } +} |