diff options
Diffstat (limited to 'game/server/tf/entity_currencypack.cpp')
| -rw-r--r-- | game/server/tf/entity_currencypack.cpp | 346 |
1 files changed, 346 insertions, 0 deletions
diff --git a/game/server/tf/entity_currencypack.cpp b/game/server/tf/entity_currencypack.cpp new file mode 100644 index 0000000..b2dc51d --- /dev/null +++ b/game/server/tf/entity_currencypack.cpp @@ -0,0 +1,346 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: CTF CurrencyPack. +// +//=============================================================================// +#include "cbase.h" +#include "items.h" +#include "tf_gamerules.h" +#include "tf_shareddefs.h" +#include "tf_player.h" +#include "tf_team.h" +#include "engine/IEngineSound.h" +#include "entity_currencypack.h" +#include "tf_gamestats.h" +#include "tf_mann_vs_machine_stats.h" +#include "world.h" +#include "particle_parse.h" +#include "player_vs_environment/tf_population_manager.h" +#include "collisionutils.h" +#include "tf_objective_resource.h" + +//============================================================================= +// +// CTF CurrencyPack defines. +// + +#define TF_CURRENCYPACK_PICKUP_SOUND "MVM.MoneyPickup" +#define TF_CURRENCYPACK_VANISH_SOUND "MVM.MoneyVanish" + +#define TF_CURRENCYPACK_BLINK_PERIOD 5.0f // how long pack blinks before it vanishes +#define TF_CURRENCYPACK_BLINK_DURATION 0.25f // how long a blink lasts + +#define TF_CURRENCYPACK_GLOW_THINK_TIME 0.1f // how often should we check if cash should glow + + +LINK_ENTITY_TO_CLASS( item_currencypack_large, CCurrencyPack ); +LINK_ENTITY_TO_CLASS( item_currencypack_medium, CCurrencyPackMedium ); +LINK_ENTITY_TO_CLASS( item_currencypack_small, CCurrencyPackSmall ); + +LINK_ENTITY_TO_CLASS( item_currencypack_custom, CCurrencyPackCustom ); + +IMPLEMENT_SERVERCLASS_ST( CCurrencyPack, DT_CurrencyPack ) + SendPropBool( SENDINFO( m_bDistributed ) ), +END_SEND_TABLE() + +IMPLEMENT_AUTO_LIST( ICurrencyPackAutoList ); + + +//============================================================================= +// +// CTF CurrencyPack functions. +// + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CCurrencyPack::CCurrencyPack() +{ + m_nAmount = 0; + m_nWaveNumber = MannVsMachineStats_GetCurrentWave(); + m_bTouched = false; + m_bClaimed = false; + m_bDistributed = false; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CCurrencyPack::~CCurrencyPack() +{ +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CCurrencyPack::UpdateOnRemove( void ) +{ + BaseClass::UpdateOnRemove(); + + if ( g_pPopulationManager && !m_bTouched ) + { + if ( !m_bDistributed ) + { + g_pPopulationManager->OnCurrencyPackFade(); + } + + DispatchParticleEffect( "mvm_cash_explosion", GetAbsOrigin(), GetAbsAngles() ); + } + + if ( !m_bDistributed && TFObjectiveResource() ) + { + TFObjectiveResource()->AddMvMWorldMoney( -m_nAmount ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: Always transmitted to clients +//----------------------------------------------------------------------------- +int CCurrencyPack::UpdateTransmitState( void ) +{ + return SetTransmitState( FL_EDICT_ALWAYS ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +int CCurrencyPack::ShouldTransmit( const CCheckTransmitInfo *pInfo ) +{ + return FL_EDICT_ALWAYS; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CCurrencyPack::Spawn( void ) +{ + BaseClass::Spawn(); + m_blinkCount = 0; + m_blinkTimer.Invalidate(); + SetContextThink( &CCurrencyPack::BlinkThink, gpGlobals->curtime + GetLifeTime() - TF_CURRENCYPACK_BLINK_PERIOD - RandomFloat( 0.0, TF_CURRENCYPACK_BLINK_DURATION ), "CurrencyPackWaitingToBlinkThink" ); + + // Force collision size to see if this fixes a bunch of stuck-in-geo issues goes away + SetCollisionBounds( Vector( -10, -10, -10 ), Vector( 10, 10, 10 ) ); + + if ( m_bDistributed ) + { + DispatchParticleEffect( "mvm_cash_embers_red", PATTACH_ABSORIGIN_FOLLOW, this ); + } + else + { + DispatchParticleEffect( "mvm_cash_embers", PATTACH_ABSORIGIN_FOLLOW, this ); + } + + // Store when this drops for time-based accounting - like with wave collection bonus + m_nWaveNumber = MannVsMachineStats_GetCurrentWave(); + + // if m_nAmount != 0, we already call SetAmount + m_nAmount = m_nAmount == 0 ? TFGameRules()->CalculateCurrencyAmount_ByType( GetPackSize() ) : m_nAmount; + MannVsMachineStats_RoundEvent_CreditsDropped( m_nWaveNumber, m_nAmount ); + if ( !m_bDistributed && TFObjectiveResource() ) + { + TFObjectiveResource()->AddMvMWorldMoney( m_nAmount ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Blink off/on when about to expire and play expire sound +//----------------------------------------------------------------------------- +void CCurrencyPack::BlinkThink( void ) +{ + // This means the pack was claimed by a player via Radius Currency Collection and + // is likely flying toward them. Regardless, one second later it fires Touch(). + if ( IsClaimed() ) + return; + + ++m_blinkCount; + + SetRenderMode( kRenderTransAlpha ); + + if ( m_blinkCount & 0x1 ) + { + SetRenderColorA( 25 ); + } + else + { + SetRenderColorA( 255 ); + } + + SetContextThink( &CCurrencyPack::BlinkThink, gpGlobals->curtime + TF_CURRENCYPACK_BLINK_DURATION, "CurrencyPackBlinkThink" ); +} + + +//----------------------------------------------------------------------------- +// Become touchable when we are at rest +//----------------------------------------------------------------------------- +void CCurrencyPack::ComeToRest( void ) +{ + BaseClass::ComeToRest(); + + if ( IsClaimed() || m_bDistributed ) + return; + + // if we've come to rest in an area with no nav, just grant the money to the player + if ( TheNavMesh->GetNavArea( GetAbsOrigin() ) == NULL ) + { + TFGameRules()->DistributeCurrencyAmount( m_nAmount ); + m_bTouched = true; + UTIL_Remove( this ); + + return; + } + + // See if we've come to rest in a trigger_hurt + for ( int i = 0; i < ITriggerHurtAutoList::AutoList().Count(); i++ ) + { + CTriggerHurt *pTrigger = static_cast<CTriggerHurt*>( ITriggerHurtAutoList::AutoList()[i] ); + if ( !pTrigger->m_bDisabled ) + { + Vector vecMins, vecMaxs; + pTrigger->GetCollideable()->WorldSpaceSurroundingBounds( &vecMins, &vecMaxs ); + if ( IsPointInBox( GetCollideable()->GetCollisionOrigin(), vecMins, vecMaxs ) ) + { + TFGameRules()->DistributeCurrencyAmount( m_nAmount ); + + m_bTouched = true; + UTIL_Remove( this ); + } + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: Sets the value of a custom pack +//----------------------------------------------------------------------------- +void CCurrencyPack::SetAmount( float nAmount ) +{ + Assert( GetPackSize() == TF_CURRENCY_PACK_CUSTOM ); // Never set an amount unless we're custom + m_nAmount = nAmount; +} + +//----------------------------------------------------------------------------- +// Purpose: Distribute the money right away +//----------------------------------------------------------------------------- +void CCurrencyPack::DistributedBy( CBasePlayer* pMoneyMaker ) +{ + TFGameRules()->DistributeCurrencyAmount( m_nAmount ); + + if ( pMoneyMaker ) + { + CTF_GameStats.Event_PlayerCollectedCurrency( pMoneyMaker, m_nAmount ); + } + + m_bDistributed = true; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CCurrencyPack::Precache( void ) +{ + PrecacheScriptSound( TF_CURRENCYPACK_PICKUP_SOUND ); + PrecacheScriptSound( TF_CURRENCYPACK_VANISH_SOUND ); + PrecacheParticleSystem( "mvm_cash_embers" ); + PrecacheParticleSystem( "mvm_cash_explosion" ); + BaseClass::Precache(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CCurrencyPack::MyTouch( CBasePlayer *pPlayer ) +{ + if ( ValidTouch( pPlayer ) && !m_bTouched ) + { + CTFPlayer *pTFTouchPlayer = ToTFPlayer( pPlayer ); + if ( !pTFTouchPlayer ) + return false; + + if ( pTFTouchPlayer->IsBot() ) + return false; + + if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() ) + { + // Prevent losing team from grabbing money - screws up stats in checkpoints + if ( TFGameRules()->State_Get() == GR_STATE_TEAM_WIN ) + { + if ( TFGameRules()->GetWinningTeam() != pTFTouchPlayer->GetTeamNumber() ) + return false; + } + + // Scouts gain health when grabbing currency packs + if ( pTFTouchPlayer->GetPlayerClass()->GetClassIndex() == TF_CLASS_SCOUT ) + { + const int nCurHealth = pTFTouchPlayer->GetHealth(); + const int nMaxHealth = pTFTouchPlayer->GetMaxHealth(); + int nHealth = nCurHealth < nMaxHealth ? 50 : 25; + + // If we cross the border into insanity, scale the reward + const int nHealthCap = nMaxHealth * 4; + if ( nCurHealth > nHealthCap ) + { + nHealth = RemapValClamped( nCurHealth, nHealthCap, (nHealthCap * 1.5f), 20, 5 ); + } + + pTFTouchPlayer->TakeHealth( nHealth, DMG_IGNORE_MAXHEALTH ); + } + + MannVsMachineStats_PlayerEvent_PickedUpCredits( pTFTouchPlayer, m_nWaveNumber, m_nAmount ); + + IGameEvent *event = gameeventmanager->CreateEvent( "mvm_pickup_currency" ); + if ( event ) + { + event->SetInt( "player", pTFTouchPlayer->entindex() ); + event->SetInt( "currency", m_nAmount ); + gameeventmanager->FireEvent( event ); + } + + // is the money blinking and about to burn up? + if ( m_blinkCount > 0 ) + { + pTFTouchPlayer->AwardAchievement( ACHIEVEMENT_TF_MVM_PICKUP_MONEY_ABOUT_TO_EXPIRE ); + } + } + + CReliableBroadcastRecipientFilter filter; + EmitSound( filter, entindex(), TF_CURRENCYPACK_PICKUP_SOUND ); + + if ( !m_bDistributed ) + { + TFGameRules()->DistributeCurrencyAmount( m_nAmount, pTFTouchPlayer ); + CTF_GameStats.Event_PlayerCollectedCurrency( pTFTouchPlayer, m_nAmount ); + } + + if ( ( !pTFTouchPlayer->IsPlayerClass( TF_CLASS_SPY ) ) || + ( !pTFTouchPlayer->m_Shared.IsStealthed() && !pTFTouchPlayer->m_Shared.InCond( TF_COND_STEALTHED_BLINK ) && !pTFTouchPlayer->m_Shared.InCond( TF_COND_DISGUISED ) ) ) + { + pTFTouchPlayer->SpeakConceptIfAllowed( MP_CONCEPT_MVM_MONEY_PICKUP ); + } + + pTFTouchPlayer->SetLastObjectiveTime( gpGlobals->curtime ); + + m_bTouched = true; + } + + return m_bTouched; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +const char *CCurrencyPackCustom::GetDefaultPowerupModel( void ) +{ + // Custom packs should always be set to a value by hand + Assert( m_nAmount > 0 ); + + // Try to pick a model that's appropriate to our drop amount (which is in our multiplier) + if ( m_nAmount >= 25 ) + return "models/items/currencypack_large.mdl"; + if ( m_nAmount >= 10 ) + return "models/items/currencypack_medium.mdl"; + return "models/items/currencypack_small.mdl"; +} + |