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.
498 lines
13 KiB
498 lines
13 KiB
//========= 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; |
|
}
|
|
|