From 39ed87570bdb2f86969d4be821c94b722dc71179 Mon Sep 17 00:00:00 2001 From: Joe Ludwig Date: Wed, 26 Jun 2013 15:22:04 -0700 Subject: First version of the SOurce SDK 2013 --- mp/src/game/server/hl2/grenade_ar2.cpp | 253 +++++++++++++++++++++++++++++++++ 1 file changed, 253 insertions(+) create mode 100644 mp/src/game/server/hl2/grenade_ar2.cpp (limited to 'mp/src/game/server/hl2/grenade_ar2.cpp') diff --git a/mp/src/game/server/hl2/grenade_ar2.cpp b/mp/src/game/server/hl2/grenade_ar2.cpp new file mode 100644 index 00000000..6e5c67f2 --- /dev/null +++ b/mp/src/game/server/hl2/grenade_ar2.cpp @@ -0,0 +1,253 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" +#include "grenade_ar2.h" +#include "weapon_ar2.h" +#include "soundent.h" +#include "decals.h" +#include "shake.h" +#include "smoke_trail.h" +#include "ar2_explosion.h" +#include "vstdlib/random.h" +#include "engine/IEngineSound.h" +#include "world.h" + +#ifdef PORTAL + #include "portal_util_shared.h" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#define AR2_GRENADE_MAX_DANGER_RADIUS 300 + +extern short g_sModelIndexFireball; // (in combatweapon.cpp) holds the index for the smoke cloud + +// Moved to HL2_SharedGameRules because these are referenced by shared AmmoDef functions +extern ConVar sk_plr_dmg_smg1_grenade; +extern ConVar sk_npc_dmg_smg1_grenade; +extern ConVar sk_max_smg1_grenade; + +ConVar sk_smg1_grenade_radius ( "sk_smg1_grenade_radius","0"); + +ConVar g_CV_SmokeTrail("smoke_trail", "1", 0); // temporary dust explosion switch + +BEGIN_DATADESC( CGrenadeAR2 ) + + DEFINE_FIELD( m_hSmokeTrail, FIELD_EHANDLE ), + DEFINE_FIELD( m_fSpawnTime, FIELD_TIME ), + DEFINE_FIELD( m_fDangerRadius, FIELD_FLOAT ), + + // Function pointers + DEFINE_ENTITYFUNC( GrenadeAR2Touch ), + DEFINE_THINKFUNC( GrenadeAR2Think ), + +END_DATADESC() + +LINK_ENTITY_TO_CLASS( grenade_ar2, CGrenadeAR2 ); + +void CGrenadeAR2::Spawn( void ) +{ + Precache( ); + SetSolid( SOLID_BBOX ); + SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE ); + + // Hits everything but debris + SetCollisionGroup( COLLISION_GROUP_PROJECTILE ); + + SetModel( "models/Weapons/ar2_grenade.mdl"); + UTIL_SetSize(this, Vector(-3, -3, -3), Vector(3, 3, 3)); +// UTIL_SetSize(this, Vector(0, 0, 0), Vector(0, 0, 0)); + + SetUse( &CGrenadeAR2::DetonateUse ); + SetTouch( &CGrenadeAR2::GrenadeAR2Touch ); + SetThink( &CGrenadeAR2::GrenadeAR2Think ); + SetNextThink( gpGlobals->curtime + 0.1f ); + + if( GetOwnerEntity() && GetOwnerEntity()->IsPlayer() ) + { + m_flDamage = sk_plr_dmg_smg1_grenade.GetFloat(); + } + else + { + m_flDamage = sk_npc_dmg_smg1_grenade.GetFloat(); + } + + m_DmgRadius = sk_smg1_grenade_radius.GetFloat(); + m_takedamage = DAMAGE_YES; + m_bIsLive = true; + m_iHealth = 1; + + SetGravity( UTIL_ScaleForGravity( 400 ) ); // use a lower gravity for grenades to make them easier to see + SetFriction( 0.8 ); + SetSequence( 0 ); + + m_fDangerRadius = 100; + + m_fSpawnTime = gpGlobals->curtime; + + // ------------- + // Smoke trail. + // ------------- + if( g_CV_SmokeTrail.GetInt() && !IsXbox() ) + { + m_hSmokeTrail = SmokeTrail::CreateSmokeTrail(); + + if( m_hSmokeTrail ) + { + m_hSmokeTrail->m_SpawnRate = 48; + m_hSmokeTrail->m_ParticleLifetime = 1; + m_hSmokeTrail->m_StartColor.Init(0.1f, 0.1f, 0.1f); + m_hSmokeTrail->m_EndColor.Init(0,0,0); + m_hSmokeTrail->m_StartSize = 12; + m_hSmokeTrail->m_EndSize = m_hSmokeTrail->m_StartSize * 4; + m_hSmokeTrail->m_SpawnRadius = 4; + m_hSmokeTrail->m_MinSpeed = 4; + m_hSmokeTrail->m_MaxSpeed = 24; + m_hSmokeTrail->m_Opacity = 0.2f; + + m_hSmokeTrail->SetLifetime(10.0f); + m_hSmokeTrail->FollowEntity(this); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: The grenade has a slight delay before it goes live. That way the +// person firing it can bounce it off a nearby wall. However if it +// hits another character it blows up immediately +// Input : +// Output : +//----------------------------------------------------------------------------- +void CGrenadeAR2::GrenadeAR2Think( void ) +{ + SetNextThink( gpGlobals->curtime + 0.05f ); + + if (!m_bIsLive) + { + // Go live after a short delay + if (m_fSpawnTime + MAX_AR2_NO_COLLIDE_TIME < gpGlobals->curtime) + { + m_bIsLive = true; + } + } + + // If I just went solid and my velocity is zero, it means I'm resting on + // the floor already when I went solid so blow up + if (m_bIsLive) + { + if (GetAbsVelocity().Length() == 0.0 || + GetGroundEntity() != NULL ) + { + Detonate(); + } + } + + // The old way of making danger sounds would scare the crap out of EVERYONE between you and where the grenade + // was going to hit. The radius of the danger sound now 'blossoms' over the grenade's lifetime, making it seem + // dangerous to a larger area downrange than it does from where it was fired. + if( m_fDangerRadius <= AR2_GRENADE_MAX_DANGER_RADIUS ) + { + m_fDangerRadius += ( AR2_GRENADE_MAX_DANGER_RADIUS * 0.05 ); + } + + CSoundEnt::InsertSound( SOUND_DANGER, GetAbsOrigin() + GetAbsVelocity() * 0.5, m_fDangerRadius, 0.2, this, SOUNDENT_CHANNEL_REPEATED_DANGER ); +} + +void CGrenadeAR2::Event_Killed( const CTakeDamageInfo &info ) +{ + Detonate( ); +} + +void CGrenadeAR2::GrenadeAR2Touch( CBaseEntity *pOther ) +{ + Assert( pOther ); + if ( !pOther->IsSolid() ) + return; + + // If I'm live go ahead and blow up + if (m_bIsLive) + { + Detonate(); + } + else + { + // If I'm not live, only blow up if I'm hitting an chacter that + // is not the owner of the weapon + CBaseCombatCharacter *pBCC = ToBaseCombatCharacter( pOther ); + if (pBCC && GetThrower() != pBCC) + { + m_bIsLive = true; + Detonate(); + } + } +} + +void CGrenadeAR2::Detonate(void) +{ + if (!m_bIsLive) + { + return; + } + m_bIsLive = false; + m_takedamage = DAMAGE_NO; + + if(m_hSmokeTrail) + { + UTIL_Remove(m_hSmokeTrail); + m_hSmokeTrail = NULL; + } + + CPASFilter filter( GetAbsOrigin() ); + + te->Explosion( filter, 0.0, + &GetAbsOrigin(), + g_sModelIndexFireball, + 2.0, + 15, + TE_EXPLFLAG_NONE, + m_DmgRadius, + m_flDamage ); + + Vector vecForward = GetAbsVelocity(); + VectorNormalize(vecForward); + trace_t tr; + UTIL_TraceLine ( GetAbsOrigin(), GetAbsOrigin() + 60*vecForward, MASK_SHOT, + this, COLLISION_GROUP_NONE, &tr); + + + if ((tr.m_pEnt != GetWorldEntity()) || (tr.hitbox != 0)) + { + // non-world needs smaller decals + if( tr.m_pEnt && !tr.m_pEnt->IsNPC() ) + { + UTIL_DecalTrace( &tr, "SmallScorch" ); + } + } + else + { + UTIL_DecalTrace( &tr, "Scorch" ); + } + + UTIL_ScreenShake( GetAbsOrigin(), 25.0, 150.0, 1.0, 750, SHAKE_START ); + + RadiusDamage ( CTakeDamageInfo( this, GetThrower(), m_flDamage, DMG_BLAST ), GetAbsOrigin(), m_DmgRadius, CLASS_NONE, NULL ); + + UTIL_Remove( this ); +} + +void CGrenadeAR2::Precache( void ) +{ + PrecacheModel("models/Weapons/ar2_grenade.mdl"); +} + + +CGrenadeAR2::CGrenadeAR2(void) +{ + m_hSmokeTrail = NULL; +} -- cgit v1.2.3