From f56bb35301836e56582a575a75864392a0177875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20P=2E=20Tjern=C3=B8?= Date: Mon, 2 Dec 2013 19:31:46 -0800 Subject: Fix line endings. WHAMMY. --- mp/src/game/shared/basegrenade_shared.cpp | 1116 ++++++++++++++--------------- 1 file changed, 558 insertions(+), 558 deletions(-) (limited to 'mp/src/game/shared/basegrenade_shared.cpp') diff --git a/mp/src/game/shared/basegrenade_shared.cpp b/mp/src/game/shared/basegrenade_shared.cpp index 7ac9becd..b981d078 100644 --- a/mp/src/game/shared/basegrenade_shared.cpp +++ b/mp/src/game/shared/basegrenade_shared.cpp @@ -1,558 +1,558 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//=============================================================================// -#include "cbase.h" -#include "decals.h" -#include "basegrenade_shared.h" -#include "shake.h" -#include "engine/IEngineSound.h" - -#if !defined( CLIENT_DLL ) - -#include "soundent.h" -#include "entitylist.h" -#include "gamestats.h" - -#endif - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -extern short g_sModelIndexFireball; // (in combatweapon.cpp) holds the index for the fireball -extern short g_sModelIndexWExplosion; // (in combatweapon.cpp) holds the index for the underwater explosion -extern short g_sModelIndexSmoke; // (in combatweapon.cpp) holds the index for the smoke cloud -extern ConVar sk_plr_dmg_grenade; - -#if !defined( CLIENT_DLL ) - -// Global Savedata for friction modifier -BEGIN_DATADESC( CBaseGrenade ) - // nextGrenade - DEFINE_FIELD( m_hThrower, FIELD_EHANDLE ), - // m_fRegisteredSound ??? - DEFINE_FIELD( m_bIsLive, FIELD_BOOLEAN ), - DEFINE_FIELD( m_DmgRadius, FIELD_FLOAT ), - DEFINE_FIELD( m_flDetonateTime, FIELD_TIME ), - DEFINE_FIELD( m_flWarnAITime, FIELD_TIME ), - DEFINE_FIELD( m_flDamage, FIELD_FLOAT ), - DEFINE_FIELD( m_iszBounceSound, FIELD_STRING ), - DEFINE_FIELD( m_bHasWarnedAI, FIELD_BOOLEAN ), - - // Function Pointers - DEFINE_THINKFUNC( Smoke ), - DEFINE_ENTITYFUNC( BounceTouch ), - DEFINE_ENTITYFUNC( SlideTouch ), - DEFINE_ENTITYFUNC( ExplodeTouch ), - DEFINE_USEFUNC( DetonateUse ), - DEFINE_THINKFUNC( DangerSoundThink ), - DEFINE_THINKFUNC( PreDetonate ), - DEFINE_THINKFUNC( Detonate ), - DEFINE_THINKFUNC( TumbleThink ), - -END_DATADESC() - -void SendProxy_CropFlagsToPlayerFlagBitsLength( const SendProp *pProp, const void *pStruct, const void *pVarData, DVariant *pOut, int iElement, int objectID); - -#endif - -IMPLEMENT_NETWORKCLASS_ALIASED( BaseGrenade, DT_BaseGrenade ) - -BEGIN_NETWORK_TABLE( CBaseGrenade, DT_BaseGrenade ) -#if !defined( CLIENT_DLL ) - SendPropFloat( SENDINFO( m_flDamage ), 10, SPROP_ROUNDDOWN, 0.0, 256.0f ), - SendPropFloat( SENDINFO( m_DmgRadius ), 10, SPROP_ROUNDDOWN, 0.0, 1024.0f ), - SendPropInt( SENDINFO( m_bIsLive ), 1, SPROP_UNSIGNED ), -// SendPropTime( SENDINFO( m_flDetonateTime ) ), - SendPropEHandle( SENDINFO( m_hThrower ) ), - - SendPropVector( SENDINFO( m_vecVelocity ), 0, SPROP_NOSCALE ), - // HACK: Use same flag bits as player for now - SendPropInt ( SENDINFO(m_fFlags), PLAYER_FLAG_BITS, SPROP_UNSIGNED, SendProxy_CropFlagsToPlayerFlagBitsLength ), -#else - RecvPropFloat( RECVINFO( m_flDamage ) ), - RecvPropFloat( RECVINFO( m_DmgRadius ) ), - RecvPropInt( RECVINFO( m_bIsLive ) ), -// RecvPropTime( RECVINFO( m_flDetonateTime ) ), - RecvPropEHandle( RECVINFO( m_hThrower ) ), - - // Need velocity from grenades to make animation system work correctly when running - RecvPropVector( RECVINFO(m_vecVelocity), 0, RecvProxy_LocalVelocity ), - - RecvPropInt( RECVINFO( m_fFlags ) ), -#endif -END_NETWORK_TABLE() - -LINK_ENTITY_TO_CLASS( grenade, CBaseGrenade ); - -#if defined( CLIENT_DLL ) - -BEGIN_PREDICTION_DATA( CBaseGrenade ) - - DEFINE_PRED_FIELD( m_hThrower, FIELD_EHANDLE, FTYPEDESC_INSENDTABLE ), - DEFINE_PRED_FIELD( m_bIsLive, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ), - DEFINE_PRED_FIELD( m_DmgRadius, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ), -// DEFINE_PRED_FIELD_TOL( m_flDetonateTime, FIELD_FLOAT, FTYPEDESC_INSENDTABLE, TD_MSECTOLERANCE ), - DEFINE_PRED_FIELD( m_flDamage, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ), - - DEFINE_PRED_FIELD_TOL( m_vecVelocity, FIELD_VECTOR, FTYPEDESC_INSENDTABLE, 0.5f ), - DEFINE_PRED_FIELD_TOL( m_flNextAttack, FIELD_FLOAT, FTYPEDESC_INSENDTABLE, TD_MSECTOLERANCE ), - -// DEFINE_FIELD( m_fRegisteredSound, FIELD_BOOLEAN ), -// DEFINE_FIELD( m_iszBounceSound, FIELD_STRING ), - -END_PREDICTION_DATA() - -#endif - -// Grenades flagged with this will be triggered when the owner calls detonateSatchelCharges -#define SF_DETONATE 0x0001 - -// UNDONE: temporary scorching for PreAlpha - find a less sleazy permenant solution. -void CBaseGrenade::Explode( trace_t *pTrace, int bitsDamageType ) -{ -#if !defined( CLIENT_DLL ) - - SetModelName( NULL_STRING );//invisible - AddSolidFlags( FSOLID_NOT_SOLID ); - - m_takedamage = DAMAGE_NO; - - // Pull out of the wall a bit - if ( pTrace->fraction != 1.0 ) - { - SetAbsOrigin( pTrace->endpos + (pTrace->plane.normal * 0.6) ); - } - - Vector vecAbsOrigin = GetAbsOrigin(); - int contents = UTIL_PointContents ( vecAbsOrigin ); - -#if defined( TF_DLL ) - // Since this code only runs on the server, make sure it shows the tempents it creates. - // This solves a problem with remote detonating the pipebombs (client wasn't seeing the explosion effect) - CDisablePredictionFiltering disabler; -#endif - - if ( pTrace->fraction != 1.0 ) - { - Vector vecNormal = pTrace->plane.normal; - surfacedata_t *pdata = physprops->GetSurfaceData( pTrace->surface.surfaceProps ); - CPASFilter filter( vecAbsOrigin ); - - te->Explosion( filter, -1.0, // don't apply cl_interp delay - &vecAbsOrigin, - !( contents & MASK_WATER ) ? g_sModelIndexFireball : g_sModelIndexWExplosion, - m_DmgRadius * .03, - 25, - TE_EXPLFLAG_NONE, - m_DmgRadius, - m_flDamage, - &vecNormal, - (char) pdata->game.material ); - } - else - { - CPASFilter filter( vecAbsOrigin ); - te->Explosion( filter, -1.0, // don't apply cl_interp delay - &vecAbsOrigin, - !( contents & MASK_WATER ) ? g_sModelIndexFireball : g_sModelIndexWExplosion, - m_DmgRadius * .03, - 25, - TE_EXPLFLAG_NONE, - m_DmgRadius, - m_flDamage ); - } - -#if !defined( CLIENT_DLL ) - CSoundEnt::InsertSound ( SOUND_COMBAT, GetAbsOrigin(), BASEGRENADE_EXPLOSION_VOLUME, 3.0 ); -#endif - - // Use the thrower's position as the reported position - Vector vecReported = m_hThrower ? m_hThrower->GetAbsOrigin() : vec3_origin; - - CTakeDamageInfo info( this, m_hThrower, GetBlastForce(), GetAbsOrigin(), m_flDamage, bitsDamageType, 0, &vecReported ); - - RadiusDamage( info, GetAbsOrigin(), m_DmgRadius, CLASS_NONE, NULL ); - - UTIL_DecalTrace( pTrace, "Scorch" ); - - EmitSound( "BaseGrenade.Explode" ); - - SetThink( &CBaseGrenade::SUB_Remove ); - SetTouch( NULL ); - SetSolid( SOLID_NONE ); - - AddEffects( EF_NODRAW ); - SetAbsVelocity( vec3_origin ); - -#if HL2_EPISODIC - // Because the grenade is zipped out of the world instantly, the EXPLOSION sound that it makes for - // the AI is also immediately destroyed. For this reason, we now make the grenade entity inert and - // throw it away in 1/10th of a second instead of right away. Removing the grenade instantly causes - // intermittent bugs with env_microphones who are listening for explosions. They will 'randomly' not - // hear explosion sounds when the grenade is removed and the SoundEnt thinks (and removes the sound) - // before the env_microphone thinks and hears the sound. - SetNextThink( gpGlobals->curtime + 0.1 ); -#else - SetNextThink( gpGlobals->curtime ); -#endif//HL2_EPISODIC - -#if defined( HL2_DLL ) - CBasePlayer *pPlayer = ToBasePlayer( m_hThrower.Get() ); - if ( pPlayer ) - { - gamestats->Event_WeaponHit( pPlayer, true, "weapon_frag", info ); - } -#endif - -#endif -} - - -void CBaseGrenade::Smoke( void ) -{ - Vector vecAbsOrigin = GetAbsOrigin(); - if ( UTIL_PointContents ( vecAbsOrigin ) & MASK_WATER ) - { - UTIL_Bubbles( vecAbsOrigin - Vector( 64, 64, 64 ), vecAbsOrigin + Vector( 64, 64, 64 ), 100 ); - } - else - { - CPVSFilter filter( vecAbsOrigin ); - - te->Smoke( filter, 0.0, - &vecAbsOrigin, g_sModelIndexSmoke, - m_DmgRadius * 0.03, - 24 ); - } -#if !defined( CLIENT_DLL ) - SetThink ( &CBaseGrenade::SUB_Remove ); -#endif - SetNextThink( gpGlobals->curtime ); -} - -void CBaseGrenade::Event_Killed( const CTakeDamageInfo &info ) -{ - Detonate( ); -} - -#if !defined( CLIENT_DLL ) -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CBaseGrenade::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - // Support player pickup - if ( useType == USE_TOGGLE ) - { - CBasePlayer *pPlayer = ToBasePlayer( pActivator ); - if ( pPlayer ) - { - pPlayer->PickupObject( this ); - return; - } - } - - // Pass up so we still call any custom Use function - BaseClass::Use( pActivator, pCaller, useType, value ); -} -#endif - -//----------------------------------------------------------------------------- -// Purpose: Timed grenade, this think is called when time runs out. -//----------------------------------------------------------------------------- -void CBaseGrenade::DetonateUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - SetThink( &CBaseGrenade::Detonate ); - SetNextThink( gpGlobals->curtime ); -} - -void CBaseGrenade::PreDetonate( void ) -{ -#if !defined( CLIENT_DLL ) - CSoundEnt::InsertSound ( SOUND_DANGER, GetAbsOrigin(), 400, 1.5, this ); -#endif - - SetThink( &CBaseGrenade::Detonate ); - SetNextThink( gpGlobals->curtime + 1.5 ); -} - - -void CBaseGrenade::Detonate( void ) -{ - trace_t tr; - Vector vecSpot;// trace starts here! - - SetThink( NULL ); - - vecSpot = GetAbsOrigin() + Vector ( 0 , 0 , 8 ); - UTIL_TraceLine ( vecSpot, vecSpot + Vector ( 0, 0, -32 ), MASK_SHOT_HULL, this, COLLISION_GROUP_NONE, & tr); - - if( tr.startsolid ) - { - // Since we blindly moved the explosion origin vertically, we may have inadvertently moved the explosion into a solid, - // in which case nothing is going to be harmed by the grenade's explosion because all subsequent traces will startsolid. - // If this is the case, we do the downward trace again from the actual origin of the grenade. (sjb) 3/8/2007 (for ep2_outland_09) - UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() + Vector( 0, 0, -32), MASK_SHOT_HULL, this, COLLISION_GROUP_NONE, &tr ); - } - - Explode( &tr, DMG_BLAST ); - - if ( GetShakeAmplitude() ) - { - UTIL_ScreenShake( GetAbsOrigin(), GetShakeAmplitude(), 150.0, 1.0, GetShakeRadius(), SHAKE_START ); - } -} - - -// -// Contact grenade, explode when it touches something -// -void CBaseGrenade::ExplodeTouch( CBaseEntity *pOther ) -{ - trace_t tr; - Vector vecSpot;// trace starts here! - - Assert( pOther ); - if ( !pOther->IsSolid() ) - return; - - Vector velDir = GetAbsVelocity(); - VectorNormalize( velDir ); - vecSpot = GetAbsOrigin() - velDir * 32; - UTIL_TraceLine( vecSpot, vecSpot + velDir * 64, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr ); - - Explode( &tr, DMG_BLAST ); -} - - -void CBaseGrenade::DangerSoundThink( void ) -{ - if (!IsInWorld()) - { - Remove( ); - return; - } - -#if !defined( CLIENT_DLL ) - CSoundEnt::InsertSound ( SOUND_DANGER, GetAbsOrigin() + GetAbsVelocity() * 0.5, GetAbsVelocity().Length( ), 0.2, this ); -#endif - - SetNextThink( gpGlobals->curtime + 0.2 ); - - if (GetWaterLevel() != 0) - { - SetAbsVelocity( GetAbsVelocity() * 0.5 ); - } -} - - -void CBaseGrenade::BounceTouch( CBaseEntity *pOther ) -{ - if ( pOther->IsSolidFlagSet(FSOLID_TRIGGER | FSOLID_VOLUME_CONTENTS) ) - return; - - // don't hit the guy that launched this grenade - if ( pOther == GetThrower() ) - return; - - // only do damage if we're moving fairly fast - if ( (pOther->m_takedamage != DAMAGE_NO) && (m_flNextAttack < gpGlobals->curtime && GetAbsVelocity().Length() > 100)) - { - if (m_hThrower) - { -#if !defined( CLIENT_DLL ) - trace_t tr; - tr = CBaseEntity::GetTouchTrace( ); - ClearMultiDamage( ); - Vector forward; - AngleVectors( GetLocalAngles(), &forward, NULL, NULL ); - CTakeDamageInfo info( this, m_hThrower, 1, DMG_CLUB ); - CalculateMeleeDamageForce( &info, GetAbsVelocity(), GetAbsOrigin() ); - pOther->DispatchTraceAttack( info, forward, &tr ); - ApplyMultiDamage(); -#endif - } - m_flNextAttack = gpGlobals->curtime + 1.0; // debounce - } - - Vector vecTestVelocity; - // m_vecAngVelocity = Vector (300, 300, 300); - - // this is my heuristic for modulating the grenade velocity because grenades dropped purely vertical - // or thrown very far tend to slow down too quickly for me to always catch just by testing velocity. - // trimming the Z velocity a bit seems to help quite a bit. - vecTestVelocity = GetAbsVelocity(); - vecTestVelocity.z *= 0.45; - - if ( !m_bHasWarnedAI && vecTestVelocity.Length() <= 60 ) - { - // grenade is moving really slow. It's probably very close to where it will ultimately stop moving. - // emit the danger sound. - - // register a radius louder than the explosion, so we make sure everyone gets out of the way -#if !defined( CLIENT_DLL ) - CSoundEnt::InsertSound ( SOUND_DANGER, GetAbsOrigin(), m_flDamage / 0.4, 0.3, this ); -#endif - m_bHasWarnedAI = true; - } - - if (GetFlags() & FL_ONGROUND) - { - // add a bit of static friction -// SetAbsVelocity( GetAbsVelocity() * 0.8 ); - - // SetSequence( random->RandomInt( 1, 1 ) ); // FIXME: missing tumble animations - } - else - { - // play bounce sound - BounceSound(); - } - m_flPlaybackRate = GetAbsVelocity().Length() / 200.0; - if (m_flPlaybackRate > 1.0) - m_flPlaybackRate = 1; - else if (m_flPlaybackRate < 0.5) - m_flPlaybackRate = 0; - -} - - - -void CBaseGrenade::SlideTouch( CBaseEntity *pOther ) -{ - // don't hit the guy that launched this grenade - if ( pOther == GetThrower() ) - return; - - // m_vecAngVelocity = Vector (300, 300, 300); - - if (GetFlags() & FL_ONGROUND) - { - // add a bit of static friction -// SetAbsVelocity( GetAbsVelocity() * 0.95 ); - - if (GetAbsVelocity().x != 0 || GetAbsVelocity().y != 0) - { - // maintain sliding sound - } - } - else - { - BounceSound(); - } -} - -void CBaseGrenade ::BounceSound( void ) -{ - // Doesn't need to do anything anymore! Physics makes the sound. -} - -void CBaseGrenade ::TumbleThink( void ) -{ - if (!IsInWorld()) - { - Remove( ); - return; - } - - StudioFrameAdvance( ); - SetNextThink( gpGlobals->curtime + 0.1f ); - - // - // Emit a danger sound one second before exploding. - // - if (m_flDetonateTime - 1 < gpGlobals->curtime) - { -#if !defined( CLIENT_DLL ) - CSoundEnt::InsertSound ( SOUND_DANGER, GetAbsOrigin() + GetAbsVelocity() * (m_flDetonateTime - gpGlobals->curtime), 400, 0.1, this ); -#endif - } - - if (m_flDetonateTime <= gpGlobals->curtime) - { - SetThink( &CBaseGrenade::Detonate ); - } - - if (GetWaterLevel() != 0) - { - SetAbsVelocity( GetAbsVelocity() * 0.5 ); - m_flPlaybackRate = 0.2; - } -} - -void CBaseGrenade::Precache( void ) -{ - BaseClass::Precache( ); - - PrecacheScriptSound( "BaseGrenade.Explode" ); -} - -//----------------------------------------------------------------------------- -// Purpose: -// Output : CBaseCombatCharacter -//----------------------------------------------------------------------------- -CBaseCombatCharacter *CBaseGrenade::GetThrower( void ) -{ - CBaseCombatCharacter *pResult = ToBaseCombatCharacter( m_hThrower ); - if ( !pResult && GetOwnerEntity() != NULL ) - { - pResult = ToBaseCombatCharacter( GetOwnerEntity() ); - } - return pResult; -} - -//----------------------------------------------------------------------------- - -void CBaseGrenade::SetThrower( CBaseCombatCharacter *pThrower ) -{ - m_hThrower = pThrower; - - // if this is the first thrower, set it as the original thrower - if ( NULL == m_hOriginalThrower ) - { - m_hOriginalThrower = pThrower; - } -} - -//----------------------------------------------------------------------------- -// Purpose: Destructor -// Input : -// Output : -//----------------------------------------------------------------------------- -CBaseGrenade::~CBaseGrenade(void) -{ -}; - -//----------------------------------------------------------------------------- -// Purpose: Constructor -// Input : -// Output : -//----------------------------------------------------------------------------- -CBaseGrenade::CBaseGrenade(void) -{ - m_hThrower = NULL; - m_hOriginalThrower = NULL; - m_bIsLive = false; - m_DmgRadius = 100; - m_flDetonateTime = 0; - m_bHasWarnedAI = false; - - SetSimulatedEveryTick( true ); -}; - - - - - - - - - - - - - - +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// +#include "cbase.h" +#include "decals.h" +#include "basegrenade_shared.h" +#include "shake.h" +#include "engine/IEngineSound.h" + +#if !defined( CLIENT_DLL ) + +#include "soundent.h" +#include "entitylist.h" +#include "gamestats.h" + +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +extern short g_sModelIndexFireball; // (in combatweapon.cpp) holds the index for the fireball +extern short g_sModelIndexWExplosion; // (in combatweapon.cpp) holds the index for the underwater explosion +extern short g_sModelIndexSmoke; // (in combatweapon.cpp) holds the index for the smoke cloud +extern ConVar sk_plr_dmg_grenade; + +#if !defined( CLIENT_DLL ) + +// Global Savedata for friction modifier +BEGIN_DATADESC( CBaseGrenade ) + // nextGrenade + DEFINE_FIELD( m_hThrower, FIELD_EHANDLE ), + // m_fRegisteredSound ??? + DEFINE_FIELD( m_bIsLive, FIELD_BOOLEAN ), + DEFINE_FIELD( m_DmgRadius, FIELD_FLOAT ), + DEFINE_FIELD( m_flDetonateTime, FIELD_TIME ), + DEFINE_FIELD( m_flWarnAITime, FIELD_TIME ), + DEFINE_FIELD( m_flDamage, FIELD_FLOAT ), + DEFINE_FIELD( m_iszBounceSound, FIELD_STRING ), + DEFINE_FIELD( m_bHasWarnedAI, FIELD_BOOLEAN ), + + // Function Pointers + DEFINE_THINKFUNC( Smoke ), + DEFINE_ENTITYFUNC( BounceTouch ), + DEFINE_ENTITYFUNC( SlideTouch ), + DEFINE_ENTITYFUNC( ExplodeTouch ), + DEFINE_USEFUNC( DetonateUse ), + DEFINE_THINKFUNC( DangerSoundThink ), + DEFINE_THINKFUNC( PreDetonate ), + DEFINE_THINKFUNC( Detonate ), + DEFINE_THINKFUNC( TumbleThink ), + +END_DATADESC() + +void SendProxy_CropFlagsToPlayerFlagBitsLength( const SendProp *pProp, const void *pStruct, const void *pVarData, DVariant *pOut, int iElement, int objectID); + +#endif + +IMPLEMENT_NETWORKCLASS_ALIASED( BaseGrenade, DT_BaseGrenade ) + +BEGIN_NETWORK_TABLE( CBaseGrenade, DT_BaseGrenade ) +#if !defined( CLIENT_DLL ) + SendPropFloat( SENDINFO( m_flDamage ), 10, SPROP_ROUNDDOWN, 0.0, 256.0f ), + SendPropFloat( SENDINFO( m_DmgRadius ), 10, SPROP_ROUNDDOWN, 0.0, 1024.0f ), + SendPropInt( SENDINFO( m_bIsLive ), 1, SPROP_UNSIGNED ), +// SendPropTime( SENDINFO( m_flDetonateTime ) ), + SendPropEHandle( SENDINFO( m_hThrower ) ), + + SendPropVector( SENDINFO( m_vecVelocity ), 0, SPROP_NOSCALE ), + // HACK: Use same flag bits as player for now + SendPropInt ( SENDINFO(m_fFlags), PLAYER_FLAG_BITS, SPROP_UNSIGNED, SendProxy_CropFlagsToPlayerFlagBitsLength ), +#else + RecvPropFloat( RECVINFO( m_flDamage ) ), + RecvPropFloat( RECVINFO( m_DmgRadius ) ), + RecvPropInt( RECVINFO( m_bIsLive ) ), +// RecvPropTime( RECVINFO( m_flDetonateTime ) ), + RecvPropEHandle( RECVINFO( m_hThrower ) ), + + // Need velocity from grenades to make animation system work correctly when running + RecvPropVector( RECVINFO(m_vecVelocity), 0, RecvProxy_LocalVelocity ), + + RecvPropInt( RECVINFO( m_fFlags ) ), +#endif +END_NETWORK_TABLE() + +LINK_ENTITY_TO_CLASS( grenade, CBaseGrenade ); + +#if defined( CLIENT_DLL ) + +BEGIN_PREDICTION_DATA( CBaseGrenade ) + + DEFINE_PRED_FIELD( m_hThrower, FIELD_EHANDLE, FTYPEDESC_INSENDTABLE ), + DEFINE_PRED_FIELD( m_bIsLive, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ), + DEFINE_PRED_FIELD( m_DmgRadius, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ), +// DEFINE_PRED_FIELD_TOL( m_flDetonateTime, FIELD_FLOAT, FTYPEDESC_INSENDTABLE, TD_MSECTOLERANCE ), + DEFINE_PRED_FIELD( m_flDamage, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ), + + DEFINE_PRED_FIELD_TOL( m_vecVelocity, FIELD_VECTOR, FTYPEDESC_INSENDTABLE, 0.5f ), + DEFINE_PRED_FIELD_TOL( m_flNextAttack, FIELD_FLOAT, FTYPEDESC_INSENDTABLE, TD_MSECTOLERANCE ), + +// DEFINE_FIELD( m_fRegisteredSound, FIELD_BOOLEAN ), +// DEFINE_FIELD( m_iszBounceSound, FIELD_STRING ), + +END_PREDICTION_DATA() + +#endif + +// Grenades flagged with this will be triggered when the owner calls detonateSatchelCharges +#define SF_DETONATE 0x0001 + +// UNDONE: temporary scorching for PreAlpha - find a less sleazy permenant solution. +void CBaseGrenade::Explode( trace_t *pTrace, int bitsDamageType ) +{ +#if !defined( CLIENT_DLL ) + + SetModelName( NULL_STRING );//invisible + AddSolidFlags( FSOLID_NOT_SOLID ); + + m_takedamage = DAMAGE_NO; + + // Pull out of the wall a bit + if ( pTrace->fraction != 1.0 ) + { + SetAbsOrigin( pTrace->endpos + (pTrace->plane.normal * 0.6) ); + } + + Vector vecAbsOrigin = GetAbsOrigin(); + int contents = UTIL_PointContents ( vecAbsOrigin ); + +#if defined( TF_DLL ) + // Since this code only runs on the server, make sure it shows the tempents it creates. + // This solves a problem with remote detonating the pipebombs (client wasn't seeing the explosion effect) + CDisablePredictionFiltering disabler; +#endif + + if ( pTrace->fraction != 1.0 ) + { + Vector vecNormal = pTrace->plane.normal; + surfacedata_t *pdata = physprops->GetSurfaceData( pTrace->surface.surfaceProps ); + CPASFilter filter( vecAbsOrigin ); + + te->Explosion( filter, -1.0, // don't apply cl_interp delay + &vecAbsOrigin, + !( contents & MASK_WATER ) ? g_sModelIndexFireball : g_sModelIndexWExplosion, + m_DmgRadius * .03, + 25, + TE_EXPLFLAG_NONE, + m_DmgRadius, + m_flDamage, + &vecNormal, + (char) pdata->game.material ); + } + else + { + CPASFilter filter( vecAbsOrigin ); + te->Explosion( filter, -1.0, // don't apply cl_interp delay + &vecAbsOrigin, + !( contents & MASK_WATER ) ? g_sModelIndexFireball : g_sModelIndexWExplosion, + m_DmgRadius * .03, + 25, + TE_EXPLFLAG_NONE, + m_DmgRadius, + m_flDamage ); + } + +#if !defined( CLIENT_DLL ) + CSoundEnt::InsertSound ( SOUND_COMBAT, GetAbsOrigin(), BASEGRENADE_EXPLOSION_VOLUME, 3.0 ); +#endif + + // Use the thrower's position as the reported position + Vector vecReported = m_hThrower ? m_hThrower->GetAbsOrigin() : vec3_origin; + + CTakeDamageInfo info( this, m_hThrower, GetBlastForce(), GetAbsOrigin(), m_flDamage, bitsDamageType, 0, &vecReported ); + + RadiusDamage( info, GetAbsOrigin(), m_DmgRadius, CLASS_NONE, NULL ); + + UTIL_DecalTrace( pTrace, "Scorch" ); + + EmitSound( "BaseGrenade.Explode" ); + + SetThink( &CBaseGrenade::SUB_Remove ); + SetTouch( NULL ); + SetSolid( SOLID_NONE ); + + AddEffects( EF_NODRAW ); + SetAbsVelocity( vec3_origin ); + +#if HL2_EPISODIC + // Because the grenade is zipped out of the world instantly, the EXPLOSION sound that it makes for + // the AI is also immediately destroyed. For this reason, we now make the grenade entity inert and + // throw it away in 1/10th of a second instead of right away. Removing the grenade instantly causes + // intermittent bugs with env_microphones who are listening for explosions. They will 'randomly' not + // hear explosion sounds when the grenade is removed and the SoundEnt thinks (and removes the sound) + // before the env_microphone thinks and hears the sound. + SetNextThink( gpGlobals->curtime + 0.1 ); +#else + SetNextThink( gpGlobals->curtime ); +#endif//HL2_EPISODIC + +#if defined( HL2_DLL ) + CBasePlayer *pPlayer = ToBasePlayer( m_hThrower.Get() ); + if ( pPlayer ) + { + gamestats->Event_WeaponHit( pPlayer, true, "weapon_frag", info ); + } +#endif + +#endif +} + + +void CBaseGrenade::Smoke( void ) +{ + Vector vecAbsOrigin = GetAbsOrigin(); + if ( UTIL_PointContents ( vecAbsOrigin ) & MASK_WATER ) + { + UTIL_Bubbles( vecAbsOrigin - Vector( 64, 64, 64 ), vecAbsOrigin + Vector( 64, 64, 64 ), 100 ); + } + else + { + CPVSFilter filter( vecAbsOrigin ); + + te->Smoke( filter, 0.0, + &vecAbsOrigin, g_sModelIndexSmoke, + m_DmgRadius * 0.03, + 24 ); + } +#if !defined( CLIENT_DLL ) + SetThink ( &CBaseGrenade::SUB_Remove ); +#endif + SetNextThink( gpGlobals->curtime ); +} + +void CBaseGrenade::Event_Killed( const CTakeDamageInfo &info ) +{ + Detonate( ); +} + +#if !defined( CLIENT_DLL ) +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CBaseGrenade::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) +{ + // Support player pickup + if ( useType == USE_TOGGLE ) + { + CBasePlayer *pPlayer = ToBasePlayer( pActivator ); + if ( pPlayer ) + { + pPlayer->PickupObject( this ); + return; + } + } + + // Pass up so we still call any custom Use function + BaseClass::Use( pActivator, pCaller, useType, value ); +} +#endif + +//----------------------------------------------------------------------------- +// Purpose: Timed grenade, this think is called when time runs out. +//----------------------------------------------------------------------------- +void CBaseGrenade::DetonateUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) +{ + SetThink( &CBaseGrenade::Detonate ); + SetNextThink( gpGlobals->curtime ); +} + +void CBaseGrenade::PreDetonate( void ) +{ +#if !defined( CLIENT_DLL ) + CSoundEnt::InsertSound ( SOUND_DANGER, GetAbsOrigin(), 400, 1.5, this ); +#endif + + SetThink( &CBaseGrenade::Detonate ); + SetNextThink( gpGlobals->curtime + 1.5 ); +} + + +void CBaseGrenade::Detonate( void ) +{ + trace_t tr; + Vector vecSpot;// trace starts here! + + SetThink( NULL ); + + vecSpot = GetAbsOrigin() + Vector ( 0 , 0 , 8 ); + UTIL_TraceLine ( vecSpot, vecSpot + Vector ( 0, 0, -32 ), MASK_SHOT_HULL, this, COLLISION_GROUP_NONE, & tr); + + if( tr.startsolid ) + { + // Since we blindly moved the explosion origin vertically, we may have inadvertently moved the explosion into a solid, + // in which case nothing is going to be harmed by the grenade's explosion because all subsequent traces will startsolid. + // If this is the case, we do the downward trace again from the actual origin of the grenade. (sjb) 3/8/2007 (for ep2_outland_09) + UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() + Vector( 0, 0, -32), MASK_SHOT_HULL, this, COLLISION_GROUP_NONE, &tr ); + } + + Explode( &tr, DMG_BLAST ); + + if ( GetShakeAmplitude() ) + { + UTIL_ScreenShake( GetAbsOrigin(), GetShakeAmplitude(), 150.0, 1.0, GetShakeRadius(), SHAKE_START ); + } +} + + +// +// Contact grenade, explode when it touches something +// +void CBaseGrenade::ExplodeTouch( CBaseEntity *pOther ) +{ + trace_t tr; + Vector vecSpot;// trace starts here! + + Assert( pOther ); + if ( !pOther->IsSolid() ) + return; + + Vector velDir = GetAbsVelocity(); + VectorNormalize( velDir ); + vecSpot = GetAbsOrigin() - velDir * 32; + UTIL_TraceLine( vecSpot, vecSpot + velDir * 64, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr ); + + Explode( &tr, DMG_BLAST ); +} + + +void CBaseGrenade::DangerSoundThink( void ) +{ + if (!IsInWorld()) + { + Remove( ); + return; + } + +#if !defined( CLIENT_DLL ) + CSoundEnt::InsertSound ( SOUND_DANGER, GetAbsOrigin() + GetAbsVelocity() * 0.5, GetAbsVelocity().Length( ), 0.2, this ); +#endif + + SetNextThink( gpGlobals->curtime + 0.2 ); + + if (GetWaterLevel() != 0) + { + SetAbsVelocity( GetAbsVelocity() * 0.5 ); + } +} + + +void CBaseGrenade::BounceTouch( CBaseEntity *pOther ) +{ + if ( pOther->IsSolidFlagSet(FSOLID_TRIGGER | FSOLID_VOLUME_CONTENTS) ) + return; + + // don't hit the guy that launched this grenade + if ( pOther == GetThrower() ) + return; + + // only do damage if we're moving fairly fast + if ( (pOther->m_takedamage != DAMAGE_NO) && (m_flNextAttack < gpGlobals->curtime && GetAbsVelocity().Length() > 100)) + { + if (m_hThrower) + { +#if !defined( CLIENT_DLL ) + trace_t tr; + tr = CBaseEntity::GetTouchTrace( ); + ClearMultiDamage( ); + Vector forward; + AngleVectors( GetLocalAngles(), &forward, NULL, NULL ); + CTakeDamageInfo info( this, m_hThrower, 1, DMG_CLUB ); + CalculateMeleeDamageForce( &info, GetAbsVelocity(), GetAbsOrigin() ); + pOther->DispatchTraceAttack( info, forward, &tr ); + ApplyMultiDamage(); +#endif + } + m_flNextAttack = gpGlobals->curtime + 1.0; // debounce + } + + Vector vecTestVelocity; + // m_vecAngVelocity = Vector (300, 300, 300); + + // this is my heuristic for modulating the grenade velocity because grenades dropped purely vertical + // or thrown very far tend to slow down too quickly for me to always catch just by testing velocity. + // trimming the Z velocity a bit seems to help quite a bit. + vecTestVelocity = GetAbsVelocity(); + vecTestVelocity.z *= 0.45; + + if ( !m_bHasWarnedAI && vecTestVelocity.Length() <= 60 ) + { + // grenade is moving really slow. It's probably very close to where it will ultimately stop moving. + // emit the danger sound. + + // register a radius louder than the explosion, so we make sure everyone gets out of the way +#if !defined( CLIENT_DLL ) + CSoundEnt::InsertSound ( SOUND_DANGER, GetAbsOrigin(), m_flDamage / 0.4, 0.3, this ); +#endif + m_bHasWarnedAI = true; + } + + if (GetFlags() & FL_ONGROUND) + { + // add a bit of static friction +// SetAbsVelocity( GetAbsVelocity() * 0.8 ); + + // SetSequence( random->RandomInt( 1, 1 ) ); // FIXME: missing tumble animations + } + else + { + // play bounce sound + BounceSound(); + } + m_flPlaybackRate = GetAbsVelocity().Length() / 200.0; + if (m_flPlaybackRate > 1.0) + m_flPlaybackRate = 1; + else if (m_flPlaybackRate < 0.5) + m_flPlaybackRate = 0; + +} + + + +void CBaseGrenade::SlideTouch( CBaseEntity *pOther ) +{ + // don't hit the guy that launched this grenade + if ( pOther == GetThrower() ) + return; + + // m_vecAngVelocity = Vector (300, 300, 300); + + if (GetFlags() & FL_ONGROUND) + { + // add a bit of static friction +// SetAbsVelocity( GetAbsVelocity() * 0.95 ); + + if (GetAbsVelocity().x != 0 || GetAbsVelocity().y != 0) + { + // maintain sliding sound + } + } + else + { + BounceSound(); + } +} + +void CBaseGrenade ::BounceSound( void ) +{ + // Doesn't need to do anything anymore! Physics makes the sound. +} + +void CBaseGrenade ::TumbleThink( void ) +{ + if (!IsInWorld()) + { + Remove( ); + return; + } + + StudioFrameAdvance( ); + SetNextThink( gpGlobals->curtime + 0.1f ); + + // + // Emit a danger sound one second before exploding. + // + if (m_flDetonateTime - 1 < gpGlobals->curtime) + { +#if !defined( CLIENT_DLL ) + CSoundEnt::InsertSound ( SOUND_DANGER, GetAbsOrigin() + GetAbsVelocity() * (m_flDetonateTime - gpGlobals->curtime), 400, 0.1, this ); +#endif + } + + if (m_flDetonateTime <= gpGlobals->curtime) + { + SetThink( &CBaseGrenade::Detonate ); + } + + if (GetWaterLevel() != 0) + { + SetAbsVelocity( GetAbsVelocity() * 0.5 ); + m_flPlaybackRate = 0.2; + } +} + +void CBaseGrenade::Precache( void ) +{ + BaseClass::Precache( ); + + PrecacheScriptSound( "BaseGrenade.Explode" ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : CBaseCombatCharacter +//----------------------------------------------------------------------------- +CBaseCombatCharacter *CBaseGrenade::GetThrower( void ) +{ + CBaseCombatCharacter *pResult = ToBaseCombatCharacter( m_hThrower ); + if ( !pResult && GetOwnerEntity() != NULL ) + { + pResult = ToBaseCombatCharacter( GetOwnerEntity() ); + } + return pResult; +} + +//----------------------------------------------------------------------------- + +void CBaseGrenade::SetThrower( CBaseCombatCharacter *pThrower ) +{ + m_hThrower = pThrower; + + // if this is the first thrower, set it as the original thrower + if ( NULL == m_hOriginalThrower ) + { + m_hOriginalThrower = pThrower; + } +} + +//----------------------------------------------------------------------------- +// Purpose: Destructor +// Input : +// Output : +//----------------------------------------------------------------------------- +CBaseGrenade::~CBaseGrenade(void) +{ +}; + +//----------------------------------------------------------------------------- +// Purpose: Constructor +// Input : +// Output : +//----------------------------------------------------------------------------- +CBaseGrenade::CBaseGrenade(void) +{ + m_hThrower = NULL; + m_hOriginalThrower = NULL; + m_bIsLive = false; + m_DmgRadius = 100; + m_flDetonateTime = 0; + m_bHasWarnedAI = false; + + SetSimulatedEveryTick( true ); +}; + + + + + + + + + + + + + + -- cgit v1.2.3