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/dod/fx_dod_shared.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'game/shared/dod/fx_dod_shared.cpp')
| -rw-r--r-- | game/shared/dod/fx_dod_shared.cpp | 370 |
1 files changed, 370 insertions, 0 deletions
diff --git a/game/shared/dod/fx_dod_shared.cpp b/game/shared/dod/fx_dod_shared.cpp new file mode 100644 index 0000000..1590012 --- /dev/null +++ b/game/shared/dod/fx_dod_shared.cpp @@ -0,0 +1,370 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include "cbase.h" +#include "fx_dod_shared.h" +#include "weapon_dodbase.h" +#include "engine/ivdebugoverlay.h" + +#ifndef CLIENT_DLL + #include "ilagcompensationmanager.h" +#endif + +#ifndef CLIENT_DLL + +//============================================================================= +// +// Explosions. +// +class CTEDODExplosion : public CBaseTempEntity +{ +public: + + DECLARE_CLASS( CTEDODExplosion, CBaseTempEntity ); + DECLARE_SERVERCLASS(); + + CTEDODExplosion( const char *name ); + +public: + + Vector m_vecOrigin; + Vector m_vecNormal; +}; + +// Singleton to fire explosion objects +static CTEDODExplosion g_TEDODExplosion( "DODExplosion" ); + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *name - +//----------------------------------------------------------------------------- +CTEDODExplosion::CTEDODExplosion( const char *name ) : CBaseTempEntity( name ) +{ + m_vecOrigin.Init(); + m_vecNormal.Init(); +} + +IMPLEMENT_SERVERCLASS_ST( CTEDODExplosion, DT_TEDODExplosion ) + SendPropFloat( SENDINFO_NOCHECK( m_vecOrigin[0] ), -1, SPROP_COORD_MP_INTEGRAL ), + SendPropFloat( SENDINFO_NOCHECK( m_vecOrigin[1] ), -1, SPROP_COORD_MP_INTEGRAL ), + SendPropFloat( SENDINFO_NOCHECK( m_vecOrigin[2] ), -1, SPROP_COORD_MP_INTEGRAL ), + SendPropVector( SENDINFO_NOCHECK( m_vecNormal ), 6, 0, -1.0f, 1.0f ), +END_SEND_TABLE() + +void TE_DODExplosion( IRecipientFilter &filter, float flDelay, const Vector &vecOrigin, const Vector &vecNormal ) +{ + VectorCopy( vecOrigin, g_TEDODExplosion.m_vecOrigin ); + VectorCopy( vecNormal, g_TEDODExplosion.m_vecNormal ); + + // Send it over the wire + g_TEDODExplosion.Create( filter, flDelay ); +} + +#endif + +#ifdef CLIENT_DLL + + #include "fx_impact.h" + + extern void FX_TracerSound( const Vector &start, const Vector &end, int iTracerType ); + + // this is a cheap ripoff from CBaseCombatWeapon::WeaponSound(): + void FX_WeaponSound( + int iPlayerIndex, + WeaponSound_t sound_type, + const Vector &vOrigin, + CDODWeaponInfo *pWeaponInfo ) + { + + // If we have some sounds from the weapon classname.txt file, play a random one of them + const char *shootsound = pWeaponInfo->aShootSounds[ sound_type ]; + if ( !shootsound || !shootsound[0] ) + return; + + CBroadcastRecipientFilter filter; // this is client side only + + if ( !te->CanPredict() ) + return; + + CBaseEntity::EmitSound( filter, iPlayerIndex, shootsound, &vOrigin ); + } + + class CGroupedSound + { + public: + string_t m_SoundName; + Vector m_vPos; + }; + + CUtlVector<CGroupedSound> g_GroupedSounds; + + + // Called by the ImpactSound function. + void ShotgunImpactSoundGroup( const char *pSoundName, const Vector &vEndPos ) + { + // Don't play the sound if it's too close to another impact sound. + for ( int i=0; i < g_GroupedSounds.Count(); i++ ) + { + CGroupedSound *pSound = &g_GroupedSounds[i]; + + if ( vEndPos.DistToSqr( pSound->m_vPos ) < 300*300 ) + { + if ( Q_stricmp( pSound->m_SoundName, pSoundName ) == 0 ) + return; + } + } + + // Ok, play the sound and add it to the list. + CLocalPlayerFilter filter; + C_BaseEntity::EmitSound( filter, NULL, pSoundName, &vEndPos ); + + int tail = g_GroupedSounds.AddToTail(); + g_GroupedSounds[tail].m_SoundName = pSoundName; + g_GroupedSounds[tail].m_vPos = vEndPos; + } + + + void StartGroupingSounds() + { + Assert( g_GroupedSounds.Count() == 0 ); + SetImpactSoundRoute( ShotgunImpactSoundGroup ); + } + + + void EndGroupingSounds() + { + g_GroupedSounds.Purge(); + SetImpactSoundRoute( NULL ); + } + +#else + + #include "te_firebullets.h" + + // Server doesn't play sounds anyway. + void StartGroupingSounds() {} + void EndGroupingSounds() {} + void FX_WeaponSound ( int iPlayerIndex, + WeaponSound_t sound_type, + const Vector &vOrigin, + CDODWeaponInfo *pWeaponInfo ) {}; + +#endif + + + +// This runs on both the client and the server. +// On the server, it only does the damage calculations. +// On the client, it does all the effects. +void FX_FireBullets( + int iPlayerIndex, + const Vector &vOrigin, + const QAngle &vAngles, + int iWeaponID, + int iMode, + int iSeed, + float flSpread + ) +{ + bool bDoEffects = true; + +#ifdef CLIENT_DLL + C_DODPlayer *pPlayer = ToDODPlayer( ClientEntityList().GetBaseEntity( iPlayerIndex ) ); +#else + CDODPlayer *pPlayer = ToDODPlayer( UTIL_PlayerByIndex( iPlayerIndex) ); +#endif + + const char * weaponAlias = WeaponIDToAlias( iWeaponID ); + + if ( !weaponAlias ) + { + DevMsg("FX_FireBullets: weapon alias for ID %i not found\n", iWeaponID ); + return; + } + + //MATTTODO: Why are we looking up the weapon info again when every weapon + // stores its own m_pWeaponInfo pointer? + + char wpnName[128]; + Q_snprintf( wpnName, sizeof( wpnName ), "weapon_%s", weaponAlias ); + WEAPON_FILE_INFO_HANDLE hWpnInfo = LookupWeaponInfoSlot( wpnName ); + + if ( hWpnInfo == GetInvalidWeaponInfoHandle() ) + { + DevMsg("FX_FireBullets: LookupWeaponInfoSlot failed for weapon %s\n", wpnName ); + return; + } + + CDODWeaponInfo *pWeaponInfo = static_cast< CDODWeaponInfo* >( GetFileWeaponInfoFromHandle( hWpnInfo ) ); + +#ifdef CLIENT_DLL + if( pPlayer && !pPlayer->IsDormant() ) + pPlayer->DoAnimationEvent( PLAYERANIMEVENT_FIRE_GUN ); +#else + if( pPlayer ) + pPlayer->DoAnimationEvent( PLAYERANIMEVENT_FIRE_GUN ); +#endif + +#ifndef CLIENT_DLL + // if this is server code, send the effect over to client as temp entity + // Dispatch one message for all the bullet impacts and sounds. + TE_FireBullets( + iPlayerIndex, + vOrigin, + vAngles, + iWeaponID, + iMode, + iSeed, + flSpread + ); + + bDoEffects = false; // no effects on server + + // Let the player remember the usercmd he fired a weapon on. Assists in making decisions about lag compensation. + pPlayer->NoteWeaponFired(); +#endif + + + + WeaponSound_t sound_type = SINGLE; + + if ( bDoEffects) + { + FX_WeaponSound( iPlayerIndex, sound_type, vOrigin, pWeaponInfo ); + } + + // Fire bullets, calculate impacts & effects + if ( !pPlayer ) + return; + + StartGroupingSounds(); + +#if !defined (CLIENT_DLL) + // Move other players back to history positions based on local player's lag + lagcompensation->StartLagCompensation( pPlayer, pPlayer->GetCurrentCommand() ); +#endif + + RandomSeed( iSeed ); + + float x, y; + do + { + x = random->RandomFloat( -0.5, 0.5 ) + random->RandomFloat( -0.5, 0.5 ); + y = random->RandomFloat( -0.5, 0.5 ) + random->RandomFloat( -0.5, 0.5 ); + } while ( (x * x + y * y) > 1.0f ); + + Vector vecForward, vecRight, vecUp; + AngleVectors( vAngles, &vecForward, &vecRight, &vecUp ); + + Vector vecDirShooting = vecForward + + x * flSpread * vecRight + + y * flSpread * vecUp; + + vecDirShooting.NormalizeInPlace(); + + FireBulletsInfo_t info( 1 /*shots*/, vOrigin, vecDirShooting, Vector( flSpread, flSpread, FLOAT32_NAN), MAX_COORD_RANGE, pWeaponInfo->iAmmoType ); + info.m_flDamage = pWeaponInfo->m_iDamage; + info.m_pAttacker = pPlayer; + + pPlayer->FireBullets( info ); + +#ifdef CLIENT_DLL + + { + trace_t tr; + UTIL_TraceLine( vOrigin, vOrigin + vecDirShooting * MAX_COORD_RANGE, MASK_SOLID, pPlayer, COLLISION_GROUP_NONE, &tr ); + + // if this is a local player, start at attachment on view model + // else start on attachment on weapon model + + int iEntIndex = pPlayer->entindex(); + int iAttachment = 1; + + Vector vecStart = tr.startpos; + QAngle angAttachment; + + C_DODPlayer *pLocalPlayer = C_DODPlayer::GetLocalDODPlayer(); + + bool bInToolRecordingMode = clienttools->IsInRecordingMode(); + + // try to align tracers to actual weapon barrel if possible + if ( pPlayer->IsLocalPlayer() && !bInToolRecordingMode ) + { + C_BaseViewModel *pViewModel = pPlayer->GetViewModel(0); + + if ( pViewModel ) + { + iEntIndex = pViewModel->entindex(); + pViewModel->GetAttachment( iAttachment, vecStart, angAttachment ); + } + } + else if ( pLocalPlayer && + pLocalPlayer->GetObserverTarget() == pPlayer && + pLocalPlayer->GetObserverMode() == OBS_MODE_IN_EYE ) + { + // get our observer target's view model + + C_BaseViewModel *pViewModel = pLocalPlayer->GetViewModel(0); + + if ( pViewModel ) + { + iEntIndex = pViewModel->entindex(); + pViewModel->GetAttachment( iAttachment, vecStart, angAttachment ); + } + } + else if ( !pPlayer->IsDormant() ) + { + // fill in with third person weapon model index + C_BaseCombatWeapon *pWeapon = pPlayer->GetActiveWeapon(); + + if( pWeapon ) + { + iEntIndex = pWeapon->entindex(); + + int nModelIndex = pWeapon->GetModelIndex(); + int nWorldModelIndex = pWeapon->GetWorldModelIndex(); + if ( bInToolRecordingMode && nModelIndex != nWorldModelIndex ) + { + pWeapon->SetModelIndex( nWorldModelIndex ); + } + + pWeapon->GetAttachment( iAttachment, vecStart, angAttachment ); + + if ( bInToolRecordingMode && nModelIndex != nWorldModelIndex ) + { + pWeapon->SetModelIndex( nModelIndex ); + } + } + } + + switch( pWeaponInfo->m_iTracerType ) + { + case 1: // Machine gun, heavy tracer + UTIL_Tracer( vecStart, tr.endpos, iEntIndex, TRACER_DONT_USE_ATTACHMENT, 5000.0, true, "BrightTracer" ); + break; + + case 2: // rifle, smg, light tracer + vecStart += vecDirShooting * 150; + UTIL_Tracer( vecStart, tr.endpos, iEntIndex, TRACER_DONT_USE_ATTACHMENT, 5000.0, true, "FaintTracer" ); + break; + + case 0: // pistols etc, just do the sound + { + FX_TracerSound( vecStart, tr.endpos, TRACER_TYPE_DEFAULT ); + } + default: + break; + } + } +#endif + +#if !defined (CLIENT_DLL) + lagcompensation->FinishLagCompensation( pPlayer ); +#endif + + EndGroupingSounds(); +} + |