347 lines
11 KiB
C++
347 lines
11 KiB
C++
//========= 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";
|
|
}
|
|
|