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.
346 lines
11 KiB
346 lines
11 KiB
//========= 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"; |
|
} |
|
|
|
|