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/shared/tf2/weapon_grenade_rocket.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'game/shared/tf2/weapon_grenade_rocket.cpp')
| -rw-r--r-- | game/shared/tf2/weapon_grenade_rocket.cpp | 390 |
1 files changed, 390 insertions, 0 deletions
diff --git a/game/shared/tf2/weapon_grenade_rocket.cpp b/game/shared/tf2/weapon_grenade_rocket.cpp new file mode 100644 index 0000000..2f32f56 --- /dev/null +++ b/game/shared/tf2/weapon_grenade_rocket.cpp @@ -0,0 +1,390 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Rockets (Weapon) +// +//=============================================================================// + +#include "cbase.h" +#include "weapon_grenade_rocket.h" + +#if defined( CLIENT_DLL ) +// Client Only +#include "hud.h" +#include "particles_simple.h" +#else +// Server Only +#include "gameinterface.h" +#include "engine/IEngineSound.h" +#include "explode.h" +#include "tf_team.h" +#include "env_laserdesignation.h" +#include "iservervehicle.h" +#endif + +LINK_ENTITY_TO_CLASS( weapon_grenade_rocket, CWeaponGrenadeRocket ); +BEGIN_PREDICTION_DATA( CWeaponGrenadeRocket ) +END_PREDICTION_DATA() + +IMPLEMENT_NETWORKCLASS_ALIASED( WeaponGrenadeRocket, DT_WeaponGrenadeRocket ) +BEGIN_NETWORK_TABLE( CWeaponGrenadeRocket, DT_WeaponGrenadeRocket ) +//#if !defined( CLIENT_DLL ) +//#else +//#endif +END_NETWORK_TABLE() + +#define WEAPON_GRENADE_ROCKET_VELOCITY 1000 + +#if !defined( CLIENT_DLL ) +// Server Only +ConVar weapon_grenade_rocket_track_range_mod( "weapon_grenade_rocket_track_range_mod","1.5", FCVAR_NONE, "Range multiplier when a rocket's tracking a designated target." ); +ConVar weapon_grenade_rocket_force( "weapon_grenade_rocket_force","150.0", FCVAR_NONE, "Rocket force modifier." ); +#endif + +//----------------------------------------------------------------------------- +// Purpose: Constructor +//----------------------------------------------------------------------------- +CWeaponGrenadeRocket::CWeaponGrenadeRocket() +{ + m_flDamage = 100.0f; + +#if !defined( CLIENT_DLL ) + // Server Only + UseClientSideAnimation(); +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: Deconstructor +//----------------------------------------------------------------------------- +CWeaponGrenadeRocket::~CWeaponGrenadeRocket() +{ +#if defined( CLIENT_DLL ) + StopSound( entindex(), "GrenadeRocket.FlyLoop" ); +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: Create a weapon grenade rocket +//----------------------------------------------------------------------------- +CWeaponGrenadeRocket *CWeaponGrenadeRocket::Create( const Vector &vecOrigin, const Vector &vecForward, float flMaxRange, CBaseEntity *pOwner ) +{ +#if !defined( CLIENT_DLL ) + CWeaponGrenadeRocket *pRocket = ( CWeaponGrenadeRocket* )CreateEntityByName( "weapon_grenade_rocket" ); + + UTIL_SetOrigin( pRocket, vecOrigin ); + QAngle angles; + VectorAngles( vecForward, angles ); + pRocket->SetLocalAngles( angles ); + pRocket->Spawn(); + pRocket->SetOwnerEntity( pOwner ); + pRocket->ChangeTeam( pOwner->GetTeamNumber() ); + pRocket->SetMaxRange( flMaxRange ); + + return pRocket; +#else + return NULL; +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CWeaponGrenadeRocket::SetMaxRange( float flRange ) +{ + m_flMaxRange = flRange; + m_flFallingSpeed = 200; // Initial falling speed + + // Reduce max range for upward shots + Vector vecForward; + GetVectors( &vecForward, NULL, NULL ); + if ( vecForward.z > 0 ) + { + m_flMaxRange = MAX(1, m_flMaxRange - (vecForward.z * 1200)); + } + else + { + m_flMaxRange -= (vecForward.z * 2400); + } + +#if !defined( CLIENT_DLL ) + if ( m_flMaxRange ) + { + float flSpeed = GetLocalVelocity().Length(); + Assert( flSpeed ); + m_flExceedRangeTime = gpGlobals->curtime + (m_flMaxRange / flSpeed); + + // Start looking for designators + SetThink( TrackThink ); + SetNextThink( gpGlobals->curtime + 0.1f ); + } +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CWeaponGrenadeRocket::Spawn( void ) +{ +#if !defined( CLIENT_DLL ) + Precache(); + + m_flRadius = 100; + SetMoveType( MOVETYPE_FLY ); + SetSolid( SOLID_BBOX ); + SetModel( "models/weapons/w_missile.mdl" ); + UTIL_SetSize( this, vec3_origin, vec3_origin ); + + SetCollisionGroup( TFCOLLISION_GROUP_WEAPON ); + + // Forward! + Vector forward; + AngleVectors( GetLocalAngles(), &forward, NULL, NULL ); + SetAbsVelocity( forward * WEAPON_GRENADE_ROCKET_VELOCITY ); + + SetTouch( RocketTouch ); +#else + // Start our flying sound loop + CPASAttenuationFilter filter( this ); + filter.MakeReliable(); + EmitSound( filter, entindex(), "GrenadeRocket.FlyLoop" ); +#endif +} + +#if !defined( CLIENT_DLL ) +// Server Only + +//----------------------------------------------------------------------------- +// Purpose: Return my owner as my scorer +//----------------------------------------------------------------------------- +CBasePlayer *CWeaponGrenadeRocket::GetScorer( void ) +{ + return ToBasePlayer( m_hOwner ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CWeaponGrenadeRocket::Precache( void ) +{ + PrecacheModel( "models/weapons/w_missile.mdl" ); + + PrecacheScriptSound( "GrenadeRocket.FlyLoop" ); +} + +//----------------------------------------------------------------------------- +// Purpose: We've exceeded this rocket's range, start heading downward, randomly +//----------------------------------------------------------------------------- +void CWeaponGrenadeRocket::ExceededRangeThink( void ) +{ + Vector vecZ( 0,0,1 ); + Vector vecPerp; + + // Weave drunkely and head down + Vector vecVelocity = GetLocalVelocity(); + CrossProduct( vecVelocity, vecZ, vecPerp ); + VectorNormalize( vecPerp ); + vecPerp *= random->RandomFloat(-100,100); + vecVelocity += vecPerp; + vecVelocity.z -= m_flFallingSpeed; + m_flFallingSpeed += 50; + SetLocalVelocity( vecVelocity ); + + SetAnglesToMatchVelocity(); + SetNextThink( gpGlobals->curtime + 0.3 ); +} + +//----------------------------------------------------------------------------- +// Purpose: Track towards my my designated target +//----------------------------------------------------------------------------- +void CWeaponGrenadeRocket::TrackThink( void ) +{ + SetNextThink( gpGlobals->curtime + 0.3 ); + + // Have I exceeded my range? + if ( gpGlobals->curtime > m_flExceedRangeTime ) + { + SetThink( ExceededRangeThink ); + // Start falling immediately + ExceededRangeThink(); + return; + } + + // Look for any laser designators in tracking view + int iTeam = GetTeamNumber(); + int iCount = CEnvLaserDesignation::GetNumLaserDesignators( iTeam ); + if ( !iCount ) + return; + + // Get the potential lock range + float flIncreasedMaxRange = m_flMaxRange * weapon_grenade_rocket_track_range_mod.GetFloat(); + float flNearestDot = 0.95; + Vector vecNearestTarget = vec3_origin; + bool bFoundOne = false; + + // Any valid designated targets? + for ( int i = 0; i < iCount; i++ ) + { + Vector vecTarget; + if ( !CEnvLaserDesignation::GetLaserDesignation( iTeam, i, &vecTarget ) ) + continue; + + // Check validity of designated target + Vector vecToTarget = ( vecTarget - GetAbsOrigin() ); + float flDistanceSqr = vecToTarget.LengthSqr(); + // Make sure it's not too far + if ( flDistanceSqr > (flIncreasedMaxRange*flIncreasedMaxRange) ) + continue; + + // Make sure it's near my flight path + VectorNormalize(vecToTarget); + Vector vecForward; + GetVectors( &vecForward, NULL, NULL ); + float flDot = DotProduct( vecToTarget, vecForward ); + if ( flDot < flNearestDot ) + continue; + + flNearestDot = flDot; + vecNearestTarget = vecTarget; + bFoundOne = true; + } + + // No valid targets + if ( !bFoundOne ) + return; + + SetNextThink( gpGlobals->curtime + 0.1f ); + + // Turn towards my target + Vector vecToTarget = (vecNearestTarget - GetAbsOrigin()); + VectorNormalize(vecToTarget); + + // Shamelessly ripped from HL1 RPG + float flSpeed = GetAbsVelocity().Length(); + SetAbsVelocity( (GetAbsVelocity() * 0.5) + (vecToTarget * flSpeed * 0.498) ); + + SetAnglesToMatchVelocity(); +} + +//----------------------------------------------------------------------------- +// Purpose: Set angles to match our velocity +//----------------------------------------------------------------------------- +void CWeaponGrenadeRocket::SetAnglesToMatchVelocity( void ) +{ + QAngle angles; + VectorAngles( GetAbsVelocity(), angles ); + SetLocalAngles( angles ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CWeaponGrenadeRocket::RocketTouch( CBaseEntity *pOther ) +{ + Assert( pOther ); + if ( !pOther->IsSolid() ) + return; + + // Apply forces to vehicles. + if ( pOther->GetServerVehicle() ) + { + ApplyForcesToVehicle( pOther ); + } + + CPASFilter filter( GetAbsOrigin() ); + te->Explosion( filter, 0.0, &GetAbsOrigin(), g_sModelIndexFireball, 2.0, 15, TE_EXPLFLAG_NONE, 100, m_flDamage ); + + // Use the owner's position as the reported position + Vector vecReported = vec3_origin; + if ( GetOwnerEntity() ) + { + vecReported = GetOwnerEntity()->GetAbsOrigin(); + } + RadiusDamage( CTakeDamageInfo( this, GetOwnerEntity(), vec3_origin, GetAbsOrigin(), GetDamage(), GetDamageType(), 0, &vecReported ), GetAbsOrigin(), GetDamageRadius(), CLASS_NONE, NULL ); + + UTIL_Remove( this ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CWeaponGrenadeRocket::ApplyForcesToVehicle( CBaseEntity *pEntity ) +{ + // Check team - don't apply forces to our own team's vehicles. + if ( pEntity->GetTeam() == GetTeam() ) + return; + + IServerVehicle *pVehicle = pEntity->GetServerVehicle(); + if ( !pVehicle ) + return; + + IPhysicsObject *pPhysObject = pEntity->VPhysicsGetObject(); + if ( pPhysObject ) + { + //------------------------------------------------------------ + // Rocket the vehicle in the direction of the incoming rocket. + //------------------------------------------------------------ + Vector vecForceDir = GetAbsVelocity(); + vecForceDir.z = 0.0f; + VectorNormalize( vecForceDir ); + + float flForce = pPhysObject->GetMass(); + flForce += ( 4.0f * 100.0f ); // Wheels + flForce *= weapon_grenade_rocket_force.GetFloat(); + + vecForceDir *= flForce; + + pPhysObject->ApplyForceOffset( vecForceDir, GetAbsOrigin() ); + } +} + +#else +// Client Only + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CWeaponGrenadeRocket::OnDataChanged( DataUpdateType_t updateType ) +{ + BaseClass::OnDataChanged( updateType ); + + // Only think when "rocketing." + SetNextClientThink( CLIENT_THINK_ALWAYS ); +} + +//----------------------------------------------------------------------------- +// Purpose: Spawn rocket effects! +//----------------------------------------------------------------------------- +void CWeaponGrenadeRocket::ClientThink( void ) +{ + // Fire smoke puffs out the side + CSmartPtr<CSimpleEmitter> pSmokeEmitter = CSimpleEmitter::Create( "C_GrenadeRocket::Effect" ); + pSmokeEmitter->SetSortOrigin( GetAbsOrigin() ); + PMaterialHandle hSphereMaterial = pSmokeEmitter->GetPMaterial( "particle/particle_noisesphere" ); + int iSmokeClouds = random->RandomInt( 1,2 ); + for ( int i = 0; i < iSmokeClouds; i++ ) + { + SimpleParticle *pParticle = ( SimpleParticle* ) pSmokeEmitter->AddParticle( sizeof( SimpleParticle ), hSphereMaterial, GetAbsOrigin() ); + if ( !pParticle ) + return; + + // Particle data. + pParticle->m_flLifetime = 0.0f; + pParticle->m_flDieTime = random->RandomFloat( 0.1f, 0.3f ); + + pParticle->m_uchStartSize = 10; + pParticle->m_uchEndSize = pParticle->m_uchStartSize + 2; + + pParticle->m_vecVelocity = GetAbsVelocity(); + pParticle->m_uchStartAlpha = 255; + pParticle->m_uchEndAlpha = 64; + pParticle->m_flRoll = random->RandomFloat( 180, 360 ); + pParticle->m_flRollDelta = random->RandomFloat( -1, 1 ); + + pParticle->m_uchColor[0] = 50; + pParticle->m_uchColor[1] = 250; + pParticle->m_uchColor[2] = 50; + } +} + +#endif + |