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.
229 lines
6.4 KiB
229 lines
6.4 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: CTF AmmoPack. |
|
// |
|
//=============================================================================// |
|
#include "cbase.h" |
|
|
|
#include "tf_halloween_souls_pickup.h" |
|
|
|
#ifdef CLIENT_DLL |
|
#include "tf_shareddefs.h" |
|
#else |
|
#include "tf_gamerules.h" |
|
#include "tf_player.h" |
|
#include "particle_parse.h" |
|
#endif |
|
|
|
#define TF_SOULS_TIMEOUT 10.0f // How long before dropped souls disappear |
|
|
|
LINK_ENTITY_TO_CLASS( halloween_souls_pack, CHalloweenSoulPack ); |
|
PRECACHE_REGISTER( halloween_souls_pack ); |
|
|
|
IMPLEMENT_NETWORKCLASS_ALIASED( HalloweenSoulPack, DT_HalloweenSoulPack ) |
|
|
|
BEGIN_NETWORK_TABLE( CHalloweenSoulPack, DT_HalloweenSoulPack ) |
|
#ifdef GAME_DLL |
|
SendPropEHandle( SENDINFO( m_hTarget ) ), |
|
SendPropVector( SENDINFO( m_vecPreCurvePos ) ), |
|
SendPropVector( SENDINFO( m_vecStartCurvePos ) ), |
|
SendPropFloat( SENDINFO( m_flDuration ) ), |
|
#else |
|
RecvPropEHandle( RECVINFO( m_hTarget) ), |
|
RecvPropVector( RECVINFO( m_vecPreCurvePos) ), |
|
RecvPropVector( RECVINFO( m_vecStartCurvePos) ), |
|
RecvPropFloat( RECVINFO( m_flDuration ) ), |
|
#endif |
|
END_NETWORK_TABLE() |
|
|
|
BEGIN_PREDICTION_DATA( CHalloweenSoulPack ) |
|
END_PREDICTION_DATA() |
|
|
|
#define SOUND_PLAYER_COLLECT_SOULS "Player.ReceiveSouls" |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CHalloweenSoulPack::CHalloweenSoulPack() |
|
: m_flCreationTime( 0.f ) |
|
#ifdef GAME_DLL |
|
, m_nAmount( 1 ) |
|
#endif |
|
{ |
|
m_hTarget = NULL; |
|
m_flDuration = 2.f; |
|
} |
|
|
|
|
|
CHalloweenSoulPack::~CHalloweenSoulPack() |
|
{} |
|
|
|
|
|
void CHalloweenSoulPack::Spawn() |
|
{ |
|
BaseClass::Spawn(); |
|
|
|
SetMoveType( MOVETYPE_NOCLIP, MOVECOLLIDE_DEFAULT ); |
|
SetSolid( SOLID_BBOX ); |
|
SetCollisionGroup( COLLISION_GROUP_DEBRIS ); |
|
SetSolidFlags( FSOLID_TRIGGER ); |
|
#ifdef GAME_DLL |
|
InitSplineData(); |
|
SetTouch(&CHalloweenSoulPack::ItemTouch); |
|
#else |
|
SetNextClientThink( CLIENT_THINK_ALWAYS ); |
|
#endif |
|
} |
|
|
|
void CHalloweenSoulPack::Precache() |
|
{ |
|
PrecacheScriptSound( SOUND_PLAYER_COLLECT_SOULS ); |
|
} |
|
|
|
void CHalloweenSoulPack::FlyThink( void ) |
|
{ |
|
FlyTowardsTargetEntity(); |
|
} |
|
|
|
#ifdef CLIENT_DLL |
|
void CHalloweenSoulPack::OnDataChanged( DataUpdateType_t type ) |
|
{ |
|
BaseClass::OnDataChanged( type ); |
|
|
|
if ( type == DATA_UPDATE_CREATED ) |
|
{ |
|
switch( GetTeamNumber() ) |
|
{ |
|
case TF_TEAM_RED: |
|
ParticleProp()->Create( "halloween_pickup_active_red", PATTACH_ABSORIGIN_FOLLOW ); |
|
break; |
|
case TF_TEAM_BLUE: |
|
ParticleProp()->Create( "halloween_pickup_active", PATTACH_ABSORIGIN_FOLLOW ); |
|
break; |
|
case TEAM_SPECTATOR: |
|
ParticleProp()->Create( "halloween_pickup_active_green", PATTACH_ABSORIGIN_FOLLOW ); |
|
break; |
|
default: |
|
Assert( false ); |
|
} |
|
ParticleProp()->Create( "eb_beam_angry_ring01", PATTACH_ABSORIGIN_FOLLOW ); |
|
ParticleProp()->Create( "soul_trail", PATTACH_ABSORIGIN_FOLLOW ); |
|
InitSplineData(); |
|
} |
|
} |
|
|
|
void CHalloweenSoulPack::ClientThink() |
|
{ |
|
FlyTowardsTargetEntity(); |
|
} |
|
#endif |
|
|
|
#ifdef GAME_DLL |
|
int CHalloweenSoulPack::UpdateTransmitState() |
|
{ |
|
return SetTransmitState( FL_EDICT_ALWAYS ); |
|
} |
|
|
|
|
|
void CHalloweenSoulPack::ItemTouch( CBaseEntity *pOther ) |
|
{ |
|
// Only allow our target to pick us up, if we have one |
|
if ( pOther != m_hTarget && m_hTarget != NULL ) |
|
return; |
|
|
|
// Only allow to be picked up when done travelling |
|
float flT = ( gpGlobals->curtime - m_flCreationTime ) / m_flDuration; |
|
if ( flT < 1.f ) |
|
return; |
|
|
|
CTFPlayer * pPlayer = ToTFPlayer( pOther ); |
|
if ( pPlayer ) |
|
{ |
|
CTFPlayer *pTargetPlayer = ToTFPlayer( m_hTarget ); |
|
IGameEvent *pEvent = gameeventmanager->CreateEvent( "halloween_soul_collected" ); |
|
if ( pEvent ) |
|
{ |
|
pEvent->SetInt( "intended_target", pTargetPlayer ? pTargetPlayer->GetUserID() : -1 ); |
|
pEvent->SetInt( "collecting_player", pPlayer->GetUserID() ); |
|
pEvent->SetInt( "soul_count", m_nAmount ); |
|
gameeventmanager->FireEvent( pEvent, true ); |
|
} |
|
|
|
// Strange Tracking |
|
static CSchemaItemDefHandle hItemDef( "Activated Halloween Pass"); |
|
kill_eater_event_t eEventType = kKillEaterEvent_HalloweenSouls; |
|
EconEntity_NonEquippedItemKillTracking_NoPartnerBatched( pPlayer, hItemDef->GetDefinitionIndex(), eEventType, m_nAmount ); |
|
|
|
// Play a spooky sound in their ears |
|
CSingleUserRecipientFilter filter( pPlayer ); |
|
EmitSound_t params; |
|
params.m_nChannel = CHAN_STATIC; |
|
params.m_pSoundName = SOUND_PLAYER_COLLECT_SOULS; |
|
EmitSound( filter, pPlayer->entindex(), params ); |
|
} |
|
|
|
if ( pOther == m_hTarget || ( !m_hTarget && pOther->IsPlayer() ) ) |
|
{ |
|
UTIL_Remove( this ); |
|
} |
|
} |
|
#endif |
|
|
|
void CHalloweenSoulPack::FlyTowardsTargetEntity( void ) |
|
{ |
|
CBaseEntity* pEntity = m_hTarget.Get(); |
|
float flT = ( gpGlobals->curtime - m_flCreationTime ) / m_flDuration; |
|
#ifdef CLIENT_DLL |
|
// Client doesn't need to do anything if there's no target |
|
if ( !pEntity ) |
|
{ |
|
return; |
|
} |
|
#else |
|
bool bIsAGhost = false; |
|
if ( pEntity && pEntity->IsPlayer() ) |
|
{ |
|
CTFPlayer* pTFPlayerTarget = assert_cast< CTFPlayer* >( pEntity ); |
|
bIsAGhost = pTFPlayerTarget->m_Shared.InCond( TF_COND_HALLOWEEN_GHOST_MODE ); |
|
} |
|
|
|
// If flT > 2.f something has gone terribly wrong, just give up. |
|
// Also give up if our entity is gone, dead or now a ghost |
|
if( flT > 2.f || pEntity == NULL || !pEntity->IsAlive() || bIsAGhost ) |
|
{ |
|
m_hTarget = NULL; |
|
SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE ); |
|
SetContextThink( &CBaseEntity::SUB_Remove, gpGlobals->curtime + TF_SOULS_TIMEOUT, "RemoveThink" ); |
|
return; |
|
} |
|
#endif |
|
// Clamp |
|
const float flBiasAmt = 0.2f; |
|
flT = clamp( Bias( flT, flBiasAmt ), 0.f, 1.f ); |
|
|
|
// We want to fly through the front of their chest so they get a good show |
|
QAngle eyeAngles = pEntity->EyeAngles(); |
|
Vector vecBehindChest; |
|
AngleVectors( eyeAngles, &vecBehindChest ); |
|
vecBehindChest *= -2000; |
|
|
|
Vector vecNextCuvePos = pEntity->WorldSpaceCenter() + vecBehindChest; |
|
Vector vecOutput; |
|
Catmull_Rom_Spline( m_vecPreCurvePos, m_vecStartCurvePos, pEntity->WorldSpaceCenter(), vecNextCuvePos, flT, vecOutput ); |
|
|
|
SetAbsOrigin( vecOutput ); |
|
|
|
SetContextThink( &CHalloweenSoulPack::FlyThink, gpGlobals->curtime, "HalloweenSoulPackThink" ); |
|
} |
|
|
|
void CHalloweenSoulPack::InitSplineData( void ) |
|
{ |
|
m_flCreationTime = gpGlobals->curtime; |
|
#ifdef GAME_DLL |
|
m_vecStartCurvePos = GetAbsOrigin(); |
|
m_vecPreCurvePos = m_vecStartCurvePos + RandomVector( -2000, 2000 ); |
|
m_vecPreCurvePos.SetZ( Min( m_vecPreCurvePos.GetZ(), 0.f ) ); |
|
m_flDuration = RandomFloat( 1.f, 3.f ); |
|
#endif |
|
SetContextThink( &CHalloweenSoulPack::FlyThink, gpGlobals->curtime, "HalloweenSoulPackThink" ); |
|
}
|
|
|