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/tf/tf_weapon_buff_item.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'game/shared/tf/tf_weapon_buff_item.cpp')
| -rw-r--r-- | game/shared/tf/tf_weapon_buff_item.cpp | 498 |
1 files changed, 498 insertions, 0 deletions
diff --git a/game/shared/tf/tf_weapon_buff_item.cpp b/game/shared/tf/tf_weapon_buff_item.cpp new file mode 100644 index 0000000..3055bf5 --- /dev/null +++ b/game/shared/tf/tf_weapon_buff_item.cpp @@ -0,0 +1,498 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#include "cbase.h" +#include "tf_weapon_buff_item.h" +#include "tf_gamerules.h" + +// Client specific. +#ifdef CLIENT_DLL +#include "c_tf_player.h" +#include "c_baseentity.h" +// Server specific. +#else +#include "tf_player.h" +#include "tf_gamestats.h" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +//============================================================================= +// +// Weapon Buff Item tables. +// +IMPLEMENT_NETWORKCLASS_ALIASED( TFBuffItem, DT_TFWeaponBuffItem ) + +BEGIN_NETWORK_TABLE( CTFBuffItem, DT_TFWeaponBuffItem ) +END_NETWORK_TABLE() + +BEGIN_PREDICTION_DATA( CTFBuffItem ) +END_PREDICTION_DATA() + +LINK_ENTITY_TO_CLASS( tf_weapon_buff_item, CTFBuffItem ); +PRECACHE_WEAPON_REGISTER( tf_weapon_buff_item ); + +// Models and Buffs need to be aligned +const char* BannerModels[] = +{ + "models/weapons/c_models/c_buffbanner/c_buffbanner.mdl", +#ifdef STAGING_ONLY + "models/workshop/weapons/c_models/c_battalion_buffbanner/c_battalion_buffbanner.mdl", + "models/workshop_partner/weapons/c_models/c_shogun_warbanner/c_shogun_warbanner.mdl", +#else + "models/weapons/c_models/c_battalion_buffbanner/c_batt_buffbanner.mdl", + "models/weapons/c_models/c_shogun_warbanner/c_shogun_warbanner.mdl", +#endif + "models/workshop/weapons/c_models/c_paratooper_pack/c_paratrooper_parachute.mdl" +}; + +#define CLOSED_PARACHUTE_MDL "models/workshop/weapons/c_models/c_paratooper_pack/c_paratrooper_pack.mdl" +#define OPEN_PARACHUTE_MDL "models/workshop/weapons/c_models/c_paratooper_pack/c_paratrooper_pack_open.mdl" + +COMPILE_TIME_ASSERT( ARRAYSIZE( BannerModels ) == NUM_BUFF_ITEM_TYPES ); +//============================================================================= +// +// Weapon Buff Item functions. +// + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CTFBuffItem::CTFBuffItem() +{ +#ifdef CLIENT_DLL + ListenForGameEvent( "deploy_buff_banner" ); + m_iBuffType = -1; + m_hBannerEntity = NULL; +#endif + m_bPlayingHorn = false; + + UseClientSideAnimation(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CTFBuffItem::~CTFBuffItem() +{ +#ifdef CLIENT_DLL + if ( m_hBannerEntity ) + { + m_hBannerEntity->Release(); + m_hBannerEntity = NULL; + } +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CTFBuffItem::Precache() +{ + // Need to make this dynamic, but the item data isn't available here? + for ( int i=0; i<ARRAYSIZE(BannerModels); i++ ) + { + PrecacheModel( BannerModels[i] ); + } + + PrecacheModel( "models/weapons/c_models/c_buffpack/c_buffpack.mdl" ); +#ifdef STAGING_ONLY + PrecacheModel( "models/workshop/weapons/c_models/c_battalion_buffpack/c_battalion_buffpack.mdl" ); + PrecacheModel( "models/workshop_partner/weapons/c_models/c_shogun_warpack/c_shogun_warpack.mdl" ); +#else + PrecacheModel( "models/weapons/c_models/c_battalion_buffpack/c_batt_buffpack.mdl" ); + PrecacheModel( "models/weapons/c_models/c_shogun_warpack/c_shogun_warpack.mdl" ); +#endif + PrecacheModel( OPEN_PARACHUTE_MDL ); + PrecacheModel( CLOSED_PARACHUTE_MDL ); + + PrecacheScriptSound( "Weapon_BuffBanner.HornRed" ); + PrecacheScriptSound( "Weapon_BuffBanner.HornBlue" ); + PrecacheScriptSound( "Weapon_BattalionsBackup.HornRed" ); + PrecacheScriptSound( "Weapon_BattalionsBackup.HornBlue" ); + PrecacheScriptSound( "Weapon_BuffBanner.Flag" ); + PrecacheScriptSound( "Samurai.Conch" ); + + BaseClass::Precache(); +} + +// ----------------------------------------------------------------------------- +// Purpose: +// ----------------------------------------------------------------------------- +void CTFBuffItem::PrimaryAttack() +{ + if ( !CanAttack() ) + return; + + CTFPlayer* pPlayer = ToTFPlayer( GetPlayerOwner() ); + if ( !pPlayer ) + return; + + if ( pPlayer->m_Shared.GetRageMeter() < 100.f ) + return; + + if ( m_bPlayingHorn ) + return; + + if ( pPlayer->GetTeamNumber() == TF_TEAM_RED ) + { + pPlayer->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY ); + SendWeaponAnim( ACT_VM_PRIMARYATTACK ); + } + else + { + pPlayer->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_SECONDARY ); + SendWeaponAnim( ACT_VM_SECONDARYATTACK ); + } + SetContextThink( &CTFBuffItem::BlowHorn, gpGlobals->curtime + 0.22f, "BlowHorn" ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Attaches the item to the player. +//----------------------------------------------------------------------------- +void CTFBuffItem::Equip( CBaseCombatCharacter* pOwner ) +{ + BaseClass::Equip( pOwner ); + + CTFPlayer *pTFPlayer = ToTFPlayer( pOwner ); + if ( pTFPlayer ) + { + pTFPlayer->m_Shared.SetParachuteEquipped( true ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Remove item from the player. +//----------------------------------------------------------------------------- +void CTFBuffItem::Detach( void ) +{ + CTFPlayer *pTFPlayer = GetTFPlayerOwner(); + if ( pTFPlayer ) + { + pTFPlayer->m_Shared.SetParachuteEquipped( false ); + } + + BaseClass::Detach(); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CTFBuffItem::BlowHorn( void ) +{ + CTFPlayer* pPlayer = ToTFPlayer( GetPlayerOwner() ); + if ( !pPlayer ) + return; + + if ( !pPlayer->IsAlive() ) + return; + +#ifdef GAME_DLL + // Use the buff type to try and figure out what sort of mesh we have and what + // sort of sound to play. This isn't the cleanest thing in the world. + int iBuffType = 0; + CALL_ATTRIB_HOOK_INT( iBuffType, set_buff_type ); + + // Samurai conch shell. + if ( iBuffType == EConcheror ) + { + pPlayer->EmitSound( "Samurai.Conch" ); + } + // Bugle. + else if ( iBuffType == EBuffBanner ) + { + if ( pPlayer->GetTeamNumber() == TF_TEAM_BLUE ) + { + pPlayer->EmitSound( "Weapon_BuffBanner.HornBlue" ); + } + else + { + pPlayer->EmitSound( "Weapon_BuffBanner.HornRed" ); + } + } + else if ( iBuffType == EBattalion ) + { + if ( pPlayer->GetTeamNumber() == TF_TEAM_BLUE ) + { + pPlayer->EmitSound( "Weapon_BattalionsBackup.HornBlue" ); + } + else + { + pPlayer->EmitSound( "Weapon_BattalionsBackup.HornRed" ); + } + } + + // Strange Tracking + if ( !pPlayer->IsBot() ) + { + EconEntity_OnOwnerKillEaterEventNoPartner( dynamic_cast<CEconEntity *>( this ), pPlayer, kKillEaterEvent_BannersDeployed ); + } +#endif + + m_bPlayingHorn = true; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CTFBuffItem::RaiseFlag( void ) +{ + CTFPlayer* pPlayer = ToTFPlayer( GetPlayerOwner() ); + if ( !pPlayer ) + return; + + if ( !pPlayer->IsAlive() ) + return; + + m_bPlayingHorn = false; + + int iBuffType = 0; + CALL_ATTRIB_HOOK_INT( iBuffType, set_buff_type ); + +#if GAME_DLL + // this event needs to be sent before we call ActivateSoldierBuff() below + IGameEvent* event = gameeventmanager->CreateEvent( "deploy_buff_banner" ); + if ( event ) + { + event->SetInt( "buff_type", iBuffType ); + event->SetInt( "buff_owner", pPlayer->GetUserID() ); + gameeventmanager->FireEvent( event ); + } + + pPlayer->EmitSound( "Weapon_BuffBanner.Flag" ); + pPlayer->SpeakConceptIfAllowed( MP_CONCEPT_PLAYER_BATTLECRY ); +#endif + + pPlayer->m_Shared.ActivateRageBuff( this, iBuffType ); + pPlayer->SelectLastItem(); + +} + +//----------------------------------------------------------------------------- +// Don't let them holster while they are blowing the horn. +//----------------------------------------------------------------------------- +bool CTFBuffItem::Holster( CBaseCombatWeapon *pSwitchingTo ) +{ + if ( m_bPlayingHorn ) + { + return false; + } + else + { + return BaseClass::Holster( pSwitchingTo ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CTFBuffItem::FireGameEvent( IGameEvent* event ) +{ +#ifdef CLIENT_DLL + const char *name = event->GetName(); + + if ( 0 == Q_strcmp( name, "deploy_buff_banner" ) ) + { + CTFPlayer* pPlayer = ToTFPlayer( ClientEntityList().GetEnt( engine->GetPlayerForUserID( event->GetInt( "buff_owner" ) ) ) ); + if ( pPlayer == GetOwner() ) + { + CreateBanner(); + } + } + + BaseClass::FireGameEvent( event ); +#endif +} + +// ----------------------------------------------------------------------------- +// Purpose: +// ----------------------------------------------------------------------------- +void CTFBuffItem::CreateBanner() +{ +#ifdef CLIENT_DLL + + if ( m_hBannerEntity == NULL ) + { + CTFPlayer* pPlayer = ToTFPlayer( GetPlayerOwner() ); + if ( !pPlayer || !pPlayer->IsAlive() ) + return; + + C_TFBuffBanner* pBanner = new C_TFBuffBanner; + if ( !pBanner ) + return; + + //Assert( iBuffType > 0 ); + //Assert( iBuffType <= ARRAYSIZE(BannerModels) ); + pBanner->m_nSkin = 0; + pBanner->InitializeAsClientEntity( BannerModels[GetBuffType()-1], RENDER_GROUP_OPAQUE_ENTITY ); + pBanner->SetBuffItem( this ); + pBanner->SetBuffType( GetBuffType() ); + pBanner->ForceClientSideAnimationOn(); + SetBanner( pBanner ); + int iSpine = pPlayer->LookupBone( "bip_spine_3" ); + Assert( iSpine != -1 ); + if ( iSpine != -1 ) + { + pBanner->AttachEntityToBone( pPlayer, iSpine ); + } + } +#endif +} + +#ifdef CLIENT_DLL +//----------------------------------------------------------------------------- +void CTFBuffItem::NotifyShouldTransmit( ShouldTransmitState_t state ) +{ + if ( state == SHOULDTRANSMIT_END ) + { + // Kill the item - It will be recreated later + if ( m_hBannerEntity ) + { + m_hBannerEntity->Release(); + m_hBannerEntity = NULL; + } + } + + BaseClass::NotifyShouldTransmit( state ); +} + +void CTFBuffItem::OnDataChanged( DataUpdateType_t updateType ) +{ + if ( updateType == DATA_UPDATE_CREATED ) + { + SetNextClientThink( CLIENT_THINK_ALWAYS ); + } + + BaseClass::OnDataChanged( updateType ); +} + +void CTFBuffItem::ClientThink( void ) +{ + if ( m_iBuffType == -1 || m_iBuffType == 0 ) + { + m_iBuffType = GetBuffType(); + + if ( m_iBuffType != EParachute ) + { + SetNextClientThink( CLIENT_THINK_NEVER ); + } + } +} + +#endif // CLIENT_DLL + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CTFBuffItem::WeaponReset( void ) +{ + BaseClass::WeaponReset(); + + m_bPlayingHorn = false; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CTFBuffItem::SendWeaponAnim( int iActivity ) +{ + CTFPlayer *pPlayer = GetTFPlayerOwner(); + if ( !pPlayer ) + return BaseClass::SendWeaponAnim( iActivity ); + + switch ( iActivity ) + { + case ACT_VM_DRAW: + iActivity = ACT_ITEM1_VM_DRAW; + break; + case ACT_VM_HOLSTER: + iActivity = ACT_ITEM1_VM_HOLSTER; + break; + case ACT_VM_IDLE: + if ( m_bPlayingHorn ) + { + RaiseFlag(); + iActivity = ACT_RESET; + } + else + { + iActivity = ACT_ITEM1_VM_IDLE; + } + break; + case ACT_VM_PULLBACK: + iActivity = ACT_ITEM1_VM_PULLBACK; + break; + case ACT_VM_PRIMARYATTACK: + m_bPlayingHorn = true; + iActivity = ACT_ITEM1_VM_PRIMARYATTACK; + break; + case ACT_VM_SECONDARYATTACK: + m_bPlayingHorn = true; + iActivity = ACT_ITEM1_VM_SECONDARYATTACK; + break; + case ACT_VM_IDLE_TO_LOWERED: + iActivity = ACT_ITEM1_VM_IDLE_TO_LOWERED; + break; + case ACT_VM_IDLE_LOWERED: + iActivity = ACT_ITEM1_VM_IDLE_LOWERED; + break; + case ACT_VM_LOWERED_TO_IDLE: + iActivity = ACT_ITEM1_VM_LOWERED_TO_IDLE; + break; + default: + break; + } + + return BaseClass::SendWeaponAnim( iActivity ); +} + +bool CTFBuffItem::CanReload( void ) +{ + return false; +} + +//----------------------------------------------------------------------------- +// Purpose: UI Progress +//----------------------------------------------------------------------------- +float CTFBuffItem::GetProgress( void ) +{ + CTFPlayer *pPlayer = GetTFPlayerOwner(); + if ( !pPlayer ) + return 0.f; + + return pPlayer->m_Shared.GetRageMeter() / 100.0f; +} + + +//----------------------------------------------------------------------------- +// Purpose: UI Progress (same as GetProgress() without the division by 100.0f) +//----------------------------------------------------------------------------- +bool CTFBuffItem::IsFull( void ) +{ + CTFPlayer *pPlayer = GetTFPlayerOwner(); + if ( !pPlayer ) + return false; + + return ( pPlayer->m_Shared.GetRageMeter() >= 100.0f ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CTFBuffItem::EffectMeterShouldFlash( void ) +{ + CTFPlayer *pPlayer = GetTFPlayerOwner(); + if ( !pPlayer ) + return false; + + if ( pPlayer && (IsFull() || pPlayer->m_Shared.IsRageDraining()) ) + return true; + else + return false; +} |