mirror of
https://github.com/nillerusr/source-engine.git
synced 2024-12-29 09:33:00 +00:00
844 lines
19 KiB
C++
844 lines
19 KiB
C++
//========= Copyright Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose:
|
|
//
|
|
//=============================================================================//
|
|
|
|
#include "cbase.h"
|
|
#include "weapon_mg42.h"
|
|
#include "engine/ivdebugoverlay.h"
|
|
|
|
#if defined( CLIENT_DLL )
|
|
|
|
#include "tier1/KeyValues.h"
|
|
#include "particles_simple.h"
|
|
#include "particles_localspace.h"
|
|
#include "fx.h"
|
|
#include "c_dod_player.h"
|
|
|
|
#else
|
|
|
|
#include "dod_player.h"
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef CLIENT_DLL
|
|
void ToolFramework_PostToolMessage( HTOOLHANDLE hEntity, KeyValues *msg );
|
|
#endif
|
|
|
|
|
|
IMPLEMENT_NETWORKCLASS_ALIASED( WeaponMG42, DT_WeaponMG42 )
|
|
|
|
#ifdef GAME_DLL
|
|
|
|
BEGIN_DATADESC( CWeaponMG42 )
|
|
DEFINE_THINKFUNC( CoolThink ),
|
|
END_DATADESC()
|
|
|
|
#endif
|
|
|
|
BEGIN_NETWORK_TABLE( CWeaponMG42, DT_WeaponMG42 )
|
|
#ifdef CLIENT_DLL
|
|
RecvPropInt ( RECVINFO( m_iWeaponHeat ) ),
|
|
RecvPropTime ( RECVINFO( m_flNextCoolTime ) ),
|
|
RecvPropBool ( RECVINFO( m_bOverheated ) ),
|
|
#else
|
|
SendPropInt ( SENDINFO( m_iWeaponHeat ), 7, SPROP_UNSIGNED ),
|
|
SendPropFloat ( SENDINFO( m_flNextCoolTime ) ),
|
|
SendPropBool ( SENDINFO( m_bOverheated ) ),
|
|
#endif
|
|
END_NETWORK_TABLE()
|
|
|
|
#ifdef CLIENT_DLL
|
|
BEGIN_PREDICTION_DATA( CWeaponMG42 )
|
|
DEFINE_PRED_FIELD( m_iWeaponHeat, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),
|
|
DEFINE_PRED_FIELD_TOL( m_flNextCoolTime, FIELD_FLOAT, FTYPEDESC_INSENDTABLE, TD_MSECTOLERANCE ),
|
|
DEFINE_PRED_FIELD( m_bOverheated, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),
|
|
END_PREDICTION_DATA()
|
|
#endif
|
|
|
|
LINK_ENTITY_TO_CLASS( weapon_mg42, CWeaponMG42 );
|
|
PRECACHE_WEAPON_REGISTER( weapon_mg42 );
|
|
|
|
acttable_t CWeaponMG42::m_acttable[] =
|
|
{
|
|
{ ACT_DOD_STAND_AIM, ACT_DOD_STAND_AIM_MG, false },
|
|
{ ACT_DOD_CROUCH_AIM, ACT_DOD_CROUCH_AIM_MG, false },
|
|
{ ACT_DOD_CROUCHWALK_AIM, ACT_DOD_CROUCHWALK_AIM_MG, false },
|
|
{ ACT_DOD_WALK_AIM, ACT_DOD_WALK_AIM_MG, false },
|
|
{ ACT_DOD_RUN_AIM, ACT_DOD_RUN_AIM_MG, false },
|
|
{ ACT_PRONE_IDLE, ACT_DOD_PRONE_AIM_MG, false },
|
|
{ ACT_PRONE_FORWARD, ACT_DOD_PRONEWALK_IDLE_MG, false },
|
|
{ ACT_DOD_STAND_IDLE, ACT_DOD_STAND_IDLE_MG, false },
|
|
{ ACT_DOD_CROUCH_IDLE, ACT_DOD_CROUCH_IDLE_MG, false },
|
|
{ ACT_DOD_CROUCHWALK_IDLE, ACT_DOD_CROUCHWALK_IDLE_MG, false },
|
|
{ ACT_DOD_WALK_IDLE, ACT_DOD_WALK_IDLE_MG, false },
|
|
{ ACT_DOD_RUN_IDLE, ACT_DOD_RUN_IDLE_MG, false },
|
|
{ ACT_SPRINT, ACT_DOD_SPRINT_IDLE_MG, false },
|
|
|
|
// Deployed Aim
|
|
{ ACT_DOD_DEPLOYED, ACT_DOD_DEPLOY_MG, false },
|
|
{ ACT_DOD_PRONE_DEPLOYED, ACT_DOD_PRONE_DEPLOY_MG, false },
|
|
|
|
// Attack ( prone? deployed? )
|
|
{ ACT_RANGE_ATTACK1, ACT_DOD_PRIMARYATTACK_MG, false },
|
|
{ ACT_DOD_PRIMARYATTACK_CROUCH, ACT_DOD_PRIMARYATTACK_MG, false },
|
|
{ ACT_DOD_PRIMARYATTACK_PRONE, ACT_DOD_PRIMARYATTACK_PRONE_MG, false },
|
|
{ ACT_DOD_PRIMARYATTACK_DEPLOYED, ACT_DOD_PRIMARYATTACK_DEPLOYED_MG, false },
|
|
{ ACT_DOD_PRIMARYATTACK_PRONE_DEPLOYED, ACT_DOD_PRIMARYATTACK_PRONE_DEPLOYED_MG,false },
|
|
|
|
// Reload ( prone? deployed? )
|
|
{ ACT_DOD_RELOAD_DEPLOYED, ACT_DOD_RELOAD_DEPLOYED_MG, false },
|
|
{ ACT_DOD_RELOAD_PRONE_DEPLOYED, ACT_DOD_RELOAD_PRONE_DEPLOYED_MG, false },
|
|
|
|
// Hand Signals
|
|
{ ACT_DOD_HS_IDLE, ACT_DOD_HS_IDLE_MG42, false },
|
|
{ ACT_DOD_HS_CROUCH, ACT_DOD_HS_CROUCH_MG42, false },
|
|
};
|
|
|
|
IMPLEMENT_ACTTABLE( CWeaponMG42 );
|
|
|
|
void CWeaponMG42::Spawn( void )
|
|
{
|
|
m_iWeaponHeat = 0;
|
|
m_flNextCoolTime = 0;
|
|
|
|
m_bOverheated = false;
|
|
|
|
#ifdef CLIENT_DLL
|
|
m_pEmitter = NULL;
|
|
m_flParticleAccumulator = 0.0;
|
|
m_hParticleMaterial = ParticleMgr()->GetPMaterial( "sprites/effects/bazookapuff" );
|
|
#endif
|
|
|
|
BaseClass::Spawn();
|
|
}
|
|
|
|
#ifdef CLIENT_DLL
|
|
|
|
CWeaponMG42::~CWeaponMG42()
|
|
{
|
|
if ( clienttools->IsInRecordingMode() && m_pEmitter.IsValid() && m_pEmitter->GetToolParticleEffectId() != TOOLPARTICLESYSTEMID_INVALID )
|
|
{
|
|
KeyValues *msg = new KeyValues( "ParticleSystem_ActivateEmitter" );
|
|
msg->SetInt( "id", m_pEmitter->GetToolParticleEffectId() );
|
|
msg->SetFloat( "time", gpGlobals->curtime );
|
|
msg->SetInt( "active", 0 );
|
|
|
|
msg->SetInt( "emitter", 0 );
|
|
ToolFramework_PostToolMessage( HTOOLHANDLE_INVALID, msg );
|
|
|
|
msg->SetInt( "emitter", 1 );
|
|
ToolFramework_PostToolMessage( HTOOLHANDLE_INVALID, msg );
|
|
|
|
msg->SetInt( "emitter", 2 );
|
|
ToolFramework_PostToolMessage( HTOOLHANDLE_INVALID, msg );
|
|
|
|
msg->SetInt( "emitter", 3 );
|
|
ToolFramework_PostToolMessage( HTOOLHANDLE_INVALID, msg );
|
|
|
|
msg->deleteThis();
|
|
}
|
|
}
|
|
|
|
void CWeaponMG42::OnDataChanged( DataUpdateType_t updateType )
|
|
{
|
|
BaseClass::OnDataChanged( updateType );
|
|
|
|
// BUG! This can happen more than once!
|
|
if ( updateType == DATA_UPDATE_CREATED )
|
|
{
|
|
if ( !m_pEmitter.IsValid() )
|
|
{
|
|
m_pEmitter = CSimpleEmitter::Create( "MGOverheat" );
|
|
}
|
|
|
|
Assert( m_pEmitter.IsValid() );
|
|
}
|
|
|
|
ClientThinkList()->SetNextClientThink( GetClientHandle(), CLIENT_THINK_ALWAYS );
|
|
}
|
|
|
|
// Client Think emits smoke particles based on heat
|
|
// ( except if we are holstered )
|
|
void CWeaponMG42::ClientThink( void )
|
|
{
|
|
m_pEmitter->SetSortOrigin( GetAbsOrigin() );
|
|
|
|
float flEmitRate = 0.0; //particles per second
|
|
|
|
// Only smoke if we are dropped ( no owner ) or if we have an owner and are active
|
|
if ( GetOwner() == NULL || GetOwner()->GetActiveWeapon() == this )
|
|
{
|
|
if ( m_iWeaponHeat > 85 )
|
|
{
|
|
flEmitRate = 30;
|
|
}
|
|
else if ( m_iWeaponHeat > 80 )
|
|
{
|
|
flEmitRate = 20;
|
|
}
|
|
else if ( m_iWeaponHeat > 65 )
|
|
{
|
|
flEmitRate = 10;
|
|
}
|
|
else if ( m_iWeaponHeat > 50 )
|
|
{
|
|
flEmitRate = 5;
|
|
}
|
|
}
|
|
|
|
m_flParticleAccumulator += ( gpGlobals->frametime * flEmitRate );
|
|
|
|
while( m_flParticleAccumulator > 0.0 )
|
|
{
|
|
EmitSmokeParticle();
|
|
|
|
m_flParticleAccumulator -= 1.0;
|
|
}
|
|
}
|
|
|
|
void CWeaponMG42::EmitSmokeParticle( void )
|
|
{
|
|
Vector vFront, vBack;
|
|
QAngle angles;
|
|
|
|
C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
|
|
|
|
bool bViewModel = false;
|
|
|
|
// if this is locally owned
|
|
if ( GetPlayerOwner() == pLocalPlayer )
|
|
{
|
|
C_BaseViewModel *vm = pLocalPlayer->GetViewModel( 0 );
|
|
|
|
if ( !vm )
|
|
return;
|
|
|
|
vm->GetAttachment( 1, vFront, angles );
|
|
vm->GetAttachment( 2, vBack, angles );
|
|
|
|
bViewModel = true;
|
|
}
|
|
else
|
|
{
|
|
// could be dropped, or held by another player
|
|
GetAttachment( 1, vFront, angles );
|
|
GetAttachment( 2, vBack, angles );
|
|
}
|
|
|
|
// Get a position somewhere on the barrel
|
|
Vector vPos = vBack + random->RandomFloat(0.0, 1.0 ) * ( vFront - vBack );
|
|
|
|
SimpleParticle *pParticle = m_pEmitter->AddSimpleParticle( m_hParticleMaterial, vPos );
|
|
if ( pParticle )
|
|
{
|
|
pParticle->m_vecVelocity = Vector( 0,0,12 );
|
|
pParticle->m_flRoll = random->RandomFloat( 0, 0.5 );
|
|
pParticle->m_flRollDelta = ( random->RandomInt(0,1) == 0 ? 1 : -1 ) * random->RandomFloat( 0.5, 1.0 );
|
|
pParticle->m_flDieTime = 1.8f;
|
|
pParticle->m_flLifetime = 0;
|
|
pParticle->m_uchColor[0] = 200;
|
|
pParticle->m_uchColor[1] = 200;
|
|
pParticle->m_uchColor[2] = 200;
|
|
pParticle->m_uchStartAlpha = 60;
|
|
pParticle->m_uchEndAlpha = 0;
|
|
pParticle->m_uchStartSize = 4;
|
|
pParticle->m_uchEndSize = 25;
|
|
pParticle->m_iFlags = 0; //bViewModel ? FLE_VIEWMODEL : 0;
|
|
}
|
|
}
|
|
|
|
#else
|
|
|
|
// This function does the cooling when the weapon is dropped or holstered
|
|
// regular, predicted cooling is done in ItemPostFrame
|
|
void CWeaponMG42::CoolThink( void )
|
|
{
|
|
if ( m_iWeaponHeat > 0 )
|
|
m_iWeaponHeat--;
|
|
|
|
SetContextThink( &CWeaponMG42::CoolThink, gpGlobals->curtime + 0.1, COOL_CONTEXT );
|
|
}
|
|
|
|
#endif
|
|
|
|
void CWeaponMG42::Precache()
|
|
{
|
|
PrecacheMaterial( "sprites/effects/bazookapuff" );
|
|
|
|
PrecacheScriptSound( "Weapon_Mg42.OverHeat" );
|
|
|
|
BaseClass::Precache();
|
|
}
|
|
|
|
bool CWeaponMG42::Reload( void )
|
|
{
|
|
if( !IsDeployed() )
|
|
{
|
|
#ifdef CLIENT_DLL
|
|
CDODPlayer *pPlayer = ToDODPlayer( GetPlayerOwner() );
|
|
|
|
if ( pPlayer )
|
|
pPlayer->HintMessage( HINT_MG_DEPLOY_TO_RELOAD );
|
|
#endif
|
|
return false;
|
|
}
|
|
|
|
return BaseClass::Reload();
|
|
}
|
|
|
|
void CWeaponMG42::FinishReload( void )
|
|
{
|
|
BaseClass::FinishReload();
|
|
|
|
//Reset the heat when you complete a reload
|
|
m_iWeaponHeat = 0;
|
|
}
|
|
|
|
void CWeaponMG42::PrimaryAttack( void )
|
|
{
|
|
if( m_bOverheated )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ( m_iClip1 <= 0 )
|
|
{
|
|
if (m_bFireOnEmpty)
|
|
{
|
|
PlayEmptySound();
|
|
m_flNextPrimaryAttack = gpGlobals->curtime + 0.2;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
CDODPlayer *pPlayer = ToDODPlayer( GetPlayerOwner() );
|
|
Assert( pPlayer );
|
|
|
|
if( m_iWeaponHeat >= 99 )
|
|
{
|
|
//can't fire anymore, wait until heat is below 80
|
|
#ifdef CLIENT_DLL
|
|
pPlayer->HintMessage( HINT_WEAPON_OVERHEAT );
|
|
#endif
|
|
m_bOverheated = true;
|
|
m_bInAttack = true;
|
|
|
|
EmitSound( "Weapon_Mg42.OverHeat" );
|
|
return;
|
|
}
|
|
|
|
m_iWeaponHeat += 1; //2;
|
|
m_flNextCoolTime = gpGlobals->curtime + 0.16f;
|
|
|
|
if( !IsDeployed() )
|
|
{
|
|
#ifdef CLIENT_DLL
|
|
pPlayer->HintMessage( HINT_MG_FIRE_UNDEPLOYED );
|
|
#endif
|
|
pPlayer->m_Shared.SetSlowedTime( 0.2 );
|
|
|
|
float flStamina = pPlayer->m_Shared.GetStamina();
|
|
|
|
pPlayer->m_Shared.SetStamina( flStamina - 15 );
|
|
}
|
|
|
|
BaseClass::PrimaryAttack();
|
|
}
|
|
|
|
void CWeaponMG42::ItemPostFrame( void )
|
|
{
|
|
ItemFrameCool();
|
|
|
|
if( m_iWeaponHeat < 80 )
|
|
m_bOverheated = false;
|
|
|
|
BaseClass::ItemPostFrame();
|
|
}
|
|
|
|
void CWeaponMG42::ItemBusyFrame( void )
|
|
{
|
|
ItemFrameCool();
|
|
|
|
BaseClass::ItemBusyFrame();
|
|
}
|
|
|
|
void CWeaponMG42::ItemFrameCool( void )
|
|
{
|
|
if( gpGlobals->curtime > m_flNextCoolTime )
|
|
{
|
|
if ( m_iWeaponHeat > 0 )
|
|
m_iWeaponHeat--;
|
|
|
|
m_flNextCoolTime = gpGlobals->curtime + 0.16f;
|
|
}
|
|
}
|
|
|
|
bool CWeaponMG42::Deploy( void )
|
|
{
|
|
// stop the fake cooling when we deploy the weapon
|
|
SetContextThink( NULL, 0.0, COOL_CONTEXT );
|
|
|
|
return BaseClass::Deploy();
|
|
}
|
|
|
|
bool CWeaponMG42::Holster( CBaseCombatWeapon *pSwitchingTo )
|
|
{
|
|
#ifndef CLIENT_DLL
|
|
SetContextThink( &CWeaponMG42::CoolThink, gpGlobals->curtime + 0.1, COOL_CONTEXT );
|
|
#endif
|
|
|
|
return BaseClass::Holster(pSwitchingTo);
|
|
}
|
|
|
|
void CWeaponMG42::Drop( const Vector &vecVelocity )
|
|
{
|
|
#ifndef CLIENT_DLL
|
|
SetContextThink( &CWeaponMG42::CoolThink, gpGlobals->curtime + 0.1, COOL_CONTEXT );
|
|
#endif
|
|
|
|
BaseClass::Drop( vecVelocity );
|
|
}
|
|
|
|
Activity CWeaponMG42::GetReloadActivity( void )
|
|
{
|
|
return ACT_VM_RELOAD;
|
|
}
|
|
|
|
Activity CWeaponMG42::GetDrawActivity( void )
|
|
{
|
|
Activity actDraw;
|
|
|
|
if( 0 && m_iClip1 <= 0 )
|
|
actDraw = ACT_VM_DRAW_EMPTY;
|
|
else
|
|
actDraw = ACT_VM_DRAW;
|
|
|
|
return actDraw;
|
|
}
|
|
|
|
Activity CWeaponMG42::GetDeployActivity( void )
|
|
{
|
|
Activity actDeploy;
|
|
|
|
switch ( m_iClip1 )
|
|
{
|
|
case 8:
|
|
actDeploy = ACT_VM_DEPLOY_8;
|
|
break;
|
|
case 7:
|
|
actDeploy = ACT_VM_DEPLOY_7;
|
|
break;
|
|
case 6:
|
|
actDeploy = ACT_VM_DEPLOY_6;
|
|
break;
|
|
case 5:
|
|
actDeploy = ACT_VM_DEPLOY_5;
|
|
break;
|
|
case 4:
|
|
actDeploy = ACT_VM_DEPLOY_4;
|
|
break;
|
|
case 3:
|
|
actDeploy = ACT_VM_DEPLOY_3;
|
|
break;
|
|
case 2:
|
|
actDeploy = ACT_VM_DEPLOY_2;
|
|
break;
|
|
case 1:
|
|
actDeploy = ACT_VM_DEPLOY_1;
|
|
break;
|
|
case 0:
|
|
actDeploy = ACT_VM_DEPLOY_EMPTY;
|
|
break;
|
|
default:
|
|
actDeploy = ACT_VM_DEPLOY;
|
|
break;
|
|
}
|
|
|
|
return actDeploy;
|
|
}
|
|
|
|
Activity CWeaponMG42::GetUndeployActivity( void )
|
|
{
|
|
Activity actUndeploy;
|
|
|
|
switch ( m_iClip1 )
|
|
{
|
|
case 8:
|
|
actUndeploy = ACT_VM_UNDEPLOY_8;
|
|
break;
|
|
case 7:
|
|
actUndeploy = ACT_VM_UNDEPLOY_7;
|
|
break;
|
|
case 6:
|
|
actUndeploy = ACT_VM_UNDEPLOY_6;
|
|
break;
|
|
case 5:
|
|
actUndeploy = ACT_VM_UNDEPLOY_5;
|
|
break;
|
|
case 4:
|
|
actUndeploy = ACT_VM_UNDEPLOY_4;
|
|
break;
|
|
case 3:
|
|
actUndeploy = ACT_VM_UNDEPLOY_3;
|
|
break;
|
|
case 2:
|
|
actUndeploy = ACT_VM_UNDEPLOY_2;
|
|
break;
|
|
case 1:
|
|
actUndeploy = ACT_VM_UNDEPLOY_1;
|
|
break;
|
|
case 0:
|
|
actUndeploy = ACT_VM_UNDEPLOY_EMPTY;
|
|
break;
|
|
default:
|
|
actUndeploy = ACT_VM_UNDEPLOY;
|
|
break;
|
|
}
|
|
|
|
return actUndeploy;
|
|
}
|
|
|
|
Activity CWeaponMG42::GetIdleActivity( void )
|
|
{
|
|
Activity actIdle;
|
|
|
|
if( IsDeployed() )
|
|
{
|
|
switch ( m_iClip1 )
|
|
{
|
|
case 8:
|
|
actIdle = ACT_VM_IDLE_DEPLOYED_8;
|
|
break;
|
|
case 7:
|
|
actIdle = ACT_VM_IDLE_DEPLOYED_7;
|
|
break;
|
|
case 6:
|
|
actIdle = ACT_VM_IDLE_DEPLOYED_6;
|
|
break;
|
|
case 5:
|
|
actIdle = ACT_VM_IDLE_DEPLOYED_5;
|
|
break;
|
|
case 4:
|
|
actIdle = ACT_VM_IDLE_DEPLOYED_4;
|
|
break;
|
|
case 3:
|
|
actIdle = ACT_VM_IDLE_DEPLOYED_3;
|
|
break;
|
|
case 2:
|
|
actIdle = ACT_VM_IDLE_DEPLOYED_2;
|
|
break;
|
|
case 1:
|
|
actIdle = ACT_VM_IDLE_DEPLOYED_1;
|
|
break;
|
|
case 0:
|
|
actIdle = ACT_VM_IDLE_DEPLOYED_EMPTY;
|
|
break;
|
|
default:
|
|
actIdle = ACT_VM_IDLE_DEPLOYED;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch ( m_iClip1 )
|
|
{
|
|
case 8:
|
|
actIdle = ACT_VM_IDLE_8;
|
|
break;
|
|
case 7:
|
|
actIdle = ACT_VM_IDLE_7;
|
|
break;
|
|
case 6:
|
|
actIdle = ACT_VM_IDLE_6;
|
|
break;
|
|
case 5:
|
|
actIdle = ACT_VM_IDLE_5;
|
|
break;
|
|
case 4:
|
|
actIdle = ACT_VM_IDLE_4;
|
|
break;
|
|
case 3:
|
|
actIdle = ACT_VM_IDLE_3;
|
|
break;
|
|
case 2:
|
|
actIdle = ACT_VM_IDLE_2;
|
|
break;
|
|
case 1:
|
|
actIdle = ACT_VM_IDLE_1;
|
|
break;
|
|
case 0:
|
|
actIdle = ACT_VM_IDLE_EMPTY;
|
|
break;
|
|
default:
|
|
actIdle = ACT_VM_IDLE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return actIdle;
|
|
}
|
|
|
|
Activity CWeaponMG42::GetPrimaryAttackActivity( void )
|
|
{
|
|
Activity actPrim;
|
|
|
|
if( IsDeployed() )
|
|
{
|
|
switch ( m_iClip1 )
|
|
{
|
|
case 8:
|
|
actPrim = ACT_VM_PRIMARYATTACK_DEPLOYED_8;
|
|
break;
|
|
case 7:
|
|
actPrim = ACT_VM_PRIMARYATTACK_DEPLOYED_7;
|
|
break;
|
|
case 6:
|
|
actPrim = ACT_VM_PRIMARYATTACK_DEPLOYED_6;
|
|
break;
|
|
case 5:
|
|
actPrim = ACT_VM_PRIMARYATTACK_DEPLOYED_5;
|
|
break;
|
|
case 4:
|
|
actPrim = ACT_VM_PRIMARYATTACK_DEPLOYED_4;
|
|
break;
|
|
case 3:
|
|
actPrim = ACT_VM_PRIMARYATTACK_DEPLOYED_3;
|
|
break;
|
|
case 2:
|
|
actPrim = ACT_VM_PRIMARYATTACK_DEPLOYED_2;
|
|
break;
|
|
case 1:
|
|
actPrim = ACT_VM_PRIMARYATTACK_DEPLOYED_1;
|
|
break;
|
|
case 0:
|
|
actPrim = ACT_VM_PRIMARYATTACK_DEPLOYED_EMPTY;
|
|
break;
|
|
default:
|
|
actPrim = ACT_VM_PRIMARYATTACK_DEPLOYED;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch ( m_iClip1 )
|
|
{
|
|
case 8:
|
|
actPrim = ACT_VM_PRIMARYATTACK_8;
|
|
break;
|
|
case 7:
|
|
actPrim = ACT_VM_PRIMARYATTACK_7;
|
|
break;
|
|
case 6:
|
|
actPrim = ACT_VM_PRIMARYATTACK_6;
|
|
break;
|
|
case 5:
|
|
actPrim = ACT_VM_PRIMARYATTACK_5;
|
|
break;
|
|
case 4:
|
|
actPrim = ACT_VM_PRIMARYATTACK_4;
|
|
break;
|
|
case 3:
|
|
actPrim = ACT_VM_PRIMARYATTACK_3;
|
|
break;
|
|
case 2:
|
|
actPrim = ACT_VM_PRIMARYATTACK_2;
|
|
break;
|
|
case 1:
|
|
actPrim = ACT_VM_PRIMARYATTACK_1;
|
|
break;
|
|
case 0:
|
|
actPrim = ACT_VM_PRIMARYATTACK_EMPTY;
|
|
break;
|
|
default:
|
|
actPrim = ACT_VM_PRIMARYATTACK;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return actPrim;
|
|
}
|
|
|
|
float CWeaponMG42::GetRecoil( void )
|
|
{
|
|
CDODPlayer *p = ToDODPlayer( GetPlayerOwner() );
|
|
|
|
if( p && p->m_Shared.IsInMGDeploy() )
|
|
{
|
|
return 0.0f;
|
|
}
|
|
|
|
return 20;
|
|
}
|
|
|
|
#ifdef CLIENT_DLL
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// This is called after sending this entity's recording state
|
|
//-----------------------------------------------------------------------------
|
|
void CWeaponMG42::CleanupToolRecordingState( KeyValues *msg )
|
|
{
|
|
BaseClass::CleanupToolRecordingState( msg );
|
|
|
|
// Generally, this is used to allow the entity to clean up
|
|
// allocated state it put into the message, but here we're going
|
|
// to use it to send particle system messages because we
|
|
// know the smoke has been recorded at this point
|
|
if ( !clienttools->IsInRecordingMode() || !m_pEmitter.IsValid() )
|
|
return;
|
|
|
|
// NOTE: Particle system destruction message will be sent by the particle effect itself.
|
|
if ( m_pEmitter->GetToolParticleEffectId() == TOOLPARTICLESYSTEMID_INVALID )
|
|
{
|
|
int nId = m_pEmitter->AllocateToolParticleEffectId();
|
|
|
|
KeyValues *msg = new KeyValues( "ParticleSystem_Create" );
|
|
msg->SetString( "name", "CWeaponMG42 smoke" );
|
|
msg->SetInt( "id", nId );
|
|
msg->SetFloat( "time", gpGlobals->curtime );
|
|
|
|
KeyValues *pEmitter0 = msg->FindKey( "DmeSpriteEmitter", true );
|
|
pEmitter0->SetInt( "count", 5 ); // particles per second, when duration is < 0
|
|
pEmitter0->SetFloat( "duration", -1 );
|
|
pEmitter0->SetString( "material", "sprites/effects/bazookapuff" );
|
|
pEmitter0->SetInt( "active", 0 );
|
|
|
|
KeyValues *pInitializers = pEmitter0->FindKey( "initializers", true );
|
|
|
|
KeyValues *pPosition = pInitializers->FindKey( "DmeRandomAttachmentPositionEntityInitializer", true );
|
|
pPosition->SetPtr( "entindex", (void*)entindex() );
|
|
pPosition->SetInt( "attachmentIndex0", 1 );
|
|
pPosition->SetInt( "attachmentIndex1", 2 );
|
|
|
|
KeyValues *pLifetime = pInitializers->FindKey( "DmeRandomLifetimeInitializer", true );
|
|
pLifetime->SetFloat( "minLifetime", 1.8f );
|
|
pLifetime->SetFloat( "maxLifetime", 1.8f );
|
|
|
|
KeyValues *pVelocity = pInitializers->FindKey( "DmeConstantVelocityInitializer", true );
|
|
pVelocity->SetFloat( "velocityX", 0.0f );
|
|
pVelocity->SetFloat( "velocityY", 0.0f );
|
|
pVelocity->SetFloat( "velocityZ", 12.0f );
|
|
|
|
KeyValues *pRoll = pInitializers->FindKey( "DmeRandomRollInitializer", true );
|
|
pRoll->SetFloat( "minRoll", 0.0f );
|
|
pRoll->SetFloat( "maxRoll", 0.5f );
|
|
|
|
KeyValues *pRollSpeed = pInitializers->FindKey( "DmeSplitRandomRollSpeedInitializer", true );
|
|
pRollSpeed->SetFloat( "minRollSpeed", 0.5f );
|
|
pRollSpeed->SetFloat( "maxRollSpeed", 1.0f );
|
|
|
|
KeyValues *pColor = pInitializers->FindKey( "DmeRandomInterpolatedColorInitializer", true );
|
|
pColor->SetColor( "color1", Color( 200, 200, 200, 255 ) );
|
|
pColor->SetColor( "color2", Color( 200, 200, 200, 255 ) );
|
|
|
|
KeyValues *pAlpha = pInitializers->FindKey( "DmeRandomAlphaInitializer", true );
|
|
pAlpha->SetInt( "minStartAlpha", 60 );
|
|
pAlpha->SetInt( "maxStartAlpha", 60 );
|
|
pAlpha->SetInt( "minEndAlpha", 0 );
|
|
pAlpha->SetInt( "maxEndAlpha", 0 );
|
|
|
|
KeyValues *pSize = pInitializers->FindKey( "DmeRandomSizeInitializer", true );
|
|
pSize->SetFloat( "minStartSize", 4 );
|
|
pSize->SetFloat( "maxStartSize", 4 );
|
|
pSize->SetFloat( "minEndSize", 25 );
|
|
pSize->SetFloat( "maxEndSize", 25 );
|
|
|
|
KeyValues *pUpdaters = pEmitter0->FindKey( "updaters", true );
|
|
|
|
pUpdaters->FindKey( "DmePositionVelocityUpdater", true );
|
|
pUpdaters->FindKey( "DmeRollUpdater", true );
|
|
pUpdaters->FindKey( "DmeAlphaLinearUpdater", true );
|
|
pUpdaters->FindKey( "DmeSizeUpdater", true );
|
|
|
|
// create emitters for each emission rate: 5,10,20,30
|
|
KeyValues *pEmitter1 = pEmitter0->MakeCopy();
|
|
pEmitter1->SetInt( "count", 10 );
|
|
msg->AddSubKey( pEmitter1 );
|
|
|
|
KeyValues *pEmitter2 = pEmitter0->MakeCopy();
|
|
pEmitter2->SetInt( "count", 20 );
|
|
msg->AddSubKey( pEmitter2 );
|
|
|
|
KeyValues *pEmitter3 = pEmitter0->MakeCopy();
|
|
pEmitter3->SetInt( "count", 30 );
|
|
msg->AddSubKey( pEmitter3 );
|
|
|
|
// mark only the appropriate emitter active
|
|
bool bHolstered = GetOwner() && GetOwner()->GetActiveWeapon() != this;
|
|
if ( !bHolstered )
|
|
{
|
|
if ( m_iWeaponHeat > 85 )
|
|
{
|
|
pEmitter3->SetInt( "active", 1 );
|
|
}
|
|
else if ( m_iWeaponHeat > 80 )
|
|
{
|
|
pEmitter2->SetInt( "active", 1 );
|
|
}
|
|
else if ( m_iWeaponHeat > 65 )
|
|
{
|
|
pEmitter1->SetInt( "active", 1 );
|
|
}
|
|
else if ( m_iWeaponHeat > 50 )
|
|
{
|
|
pEmitter0->SetInt( "active", 1 );
|
|
}
|
|
}
|
|
|
|
ToolFramework_PostToolMessage( HTOOLHANDLE_INVALID, msg );
|
|
msg->deleteThis();
|
|
}
|
|
else
|
|
{
|
|
int nEmitterIndex = -1;
|
|
bool bHolstered = GetOwner() && GetOwner()->GetActiveWeapon() != this;
|
|
if ( !bHolstered )
|
|
{
|
|
if ( m_iWeaponHeat > 85 )
|
|
{
|
|
nEmitterIndex = 3;
|
|
}
|
|
else if ( m_iWeaponHeat > 80 )
|
|
{
|
|
nEmitterIndex = 2;
|
|
}
|
|
else if ( m_iWeaponHeat > 65 )
|
|
{
|
|
nEmitterIndex = 1;
|
|
}
|
|
else if ( m_iWeaponHeat > 50 )
|
|
{
|
|
nEmitterIndex = 0;
|
|
}
|
|
}
|
|
|
|
KeyValues *msg = new KeyValues( "ParticleSystem_ActivateEmitter" );
|
|
msg->SetInt( "id", m_pEmitter->GetToolParticleEffectId() );
|
|
msg->SetFloat( "time", gpGlobals->curtime );
|
|
|
|
msg->SetInt( "emitter", 0 );
|
|
msg->SetInt( "active", nEmitterIndex == 0 );
|
|
ToolFramework_PostToolMessage( HTOOLHANDLE_INVALID, msg );
|
|
|
|
msg->SetInt( "emitter", 1 );
|
|
msg->SetInt( "active", nEmitterIndex == 1 );
|
|
ToolFramework_PostToolMessage( HTOOLHANDLE_INVALID, msg );
|
|
|
|
msg->SetInt( "emitter", 2 );
|
|
msg->SetInt( "active", nEmitterIndex == 2 );
|
|
ToolFramework_PostToolMessage( HTOOLHANDLE_INVALID, msg );
|
|
|
|
msg->SetInt( "emitter", 3 );
|
|
msg->SetInt( "active", nEmitterIndex == 3 );
|
|
ToolFramework_PostToolMessage( HTOOLHANDLE_INVALID, msg );
|
|
|
|
msg->deleteThis();
|
|
}
|
|
}
|
|
|
|
#endif
|