//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: The Escort's Shield weapon // // $Revision: $ // $NoKeywords: $ //=============================================================================// #include "cbase.h" #include "weapon_shield.h" #include "in_buttons.h" #include #include "mathlib/mathlib.h" #include "engine/IEngineSound.h" #if defined( CLIENT_DLL ) #include "c_shield.h" #else #include "tf_shield.h" #endif //----------------------------------------------------------------------------- // Shield WEAPON //----------------------------------------------------------------------------- LINK_ENTITY_TO_CLASS( weapon_shield, CWeaponShield ); PRECACHE_WEAPON_REGISTER(weapon_shield); IMPLEMENT_NETWORKCLASS_ALIASED( WeaponShield, DT_WeaponShield ) BEGIN_NETWORK_TABLE(CWeaponShield, DT_WeaponShield) #ifdef CLIENT_DLL RecvPropEHandle (RECVINFO(m_hDeployedShield)), #else SendPropEHandle (SENDINFO(m_hDeployedShield)), #endif END_NETWORK_TABLE() BEGIN_PREDICTION_DATA( CWeaponShield ) DEFINE_FIELD( m_bIsDeployed, FIELD_BOOLEAN ), DEFINE_FIELD( m_bShieldPositionLocked, FIELD_BOOLEAN ), END_PREDICTION_DATA() //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- CWeaponShield::CWeaponShield( void ) { SetPredictionEligible( true ); m_bIsDeployed = false; } void CWeaponShield::UpdateOnRemove( void ) { #ifdef GAME_DLL if ( m_hDeployedShield.Get() ) { m_hDeployedShield.Get()->Remove( ); m_hDeployedShield.Set( NULL ); } #endif // Chain at end to mimic destructor unwind order BaseClass::UpdateOnRemove(); } //----------------------------------------------------------------------------- // Purpose: Given the distance the hit occurred at, return the damage done //----------------------------------------------------------------------------- float CWeaponShield::GetDamage( float flDistance, int iLocation ) { // Can't injure at all over this distance return 0.0; } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- float CWeaponShield::GetFireRate( void ) { return 1.0; } //----------------------------------------------------------------------------- // Deploy the shield! //----------------------------------------------------------------------------- bool CWeaponShield::Deploy( ) { if ( !BaseClass::Deploy() ) return false; // NOTE: the underlying system can cause Deploy to be called twice in a row if ( m_bIsDeployed ) return true; // We gotta make the actual shield effect.... CBaseTFPlayer *pPlayer = ToBaseTFPlayer( GetOwner() ); if ( !pPlayer ) return false; #ifdef GAME_DLL Assert( !m_hDeployedShield.Get().IsValid() ); m_hDeployedShield = CreateMobileShield( pPlayer ); #endif SetShieldPositionLocked( false ); m_bIsDeployed = true; return true; } //----------------------------------------------------------------------------- // Purpose: Remove the shield //----------------------------------------------------------------------------- bool CWeaponShield::Holster( CBaseCombatWeapon *pSwitchingTo ) { #ifdef GAME_DLL if ( m_hDeployedShield.Get() ) { m_hDeployedShield.Get()->Remove( ); m_hDeployedShield.Set( NULL ); } #endif m_bIsDeployed = false; return BaseClass::Holster( pSwitchingTo ); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CWeaponShield::ItemPostFrame( void ) { CBaseTFPlayer *pPlayer = ToBaseTFPlayer( GetOwner() ); if (pPlayer == NULL) return; // Disabled if ( ComputeEMPFireState() ) { // Handle deployment & pick-up (firing is handled on the client) if ( pPlayer->m_nButtons & IN_ATTACK2 ) { if ( gpGlobals->curtime >= m_flNextPrimaryAttack) { PrimaryAttack(); } } } WeaponIdle(); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CWeaponShield::PrimaryAttack( void ) { CShield *shield = m_hDeployedShield.Get(); if ( shield ) { SetShieldPositionLocked( !m_bShieldPositionLocked ); #ifdef GAME_DLL if ( m_bShieldPositionLocked ) { ClientPrint( ToBasePlayer(GetOwner()), HUD_PRINTCENTER, "Projected Shield Locked" ); } else { ClientPrint( ToBasePlayer(GetOwner()), HUD_PRINTCENTER, "Projected Shield Tracking" ); } #endif } m_flNextPrimaryAttack = gpGlobals->curtime + 0.25f; } //----------------------------------------------------------------------------- // Lock the projected shield //----------------------------------------------------------------------------- void CWeaponShield::SetShieldPositionLocked( bool bLocked ) { m_bShieldPositionLocked = bLocked; if ( m_hDeployedShield.Get() ) { if ( bLocked && m_hDeployedShield.Get()->IsAlwaysOrienting() ) { CBaseTFPlayer *pPlayer = ToBaseTFPlayer( GetOwner() ); m_hDeployedShield.Get()->SetCenterAngles( pPlayer->EyeAngles() ); } m_hDeployedShield.Get()->SetAlwaysOrient( !bLocked ); } } //----------------------------------------------------------------------------- // Idle processing //----------------------------------------------------------------------------- void CWeaponShield::WeaponIdle( void ) { bool isEmped = IsOwnerEMPed(); if (m_hDeployedShield.Get()) { m_hDeployedShield.Get()->SetEMPed( isEmped ); } }