mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-08 01:39:36 +00:00
add hl1,portal,dod source code
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user