You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
843 lines
19 KiB
843 lines
19 KiB
//========= 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
|
|
|