mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-15 13:16:58 +00:00
1
This commit is contained in:
@@ -0,0 +1,229 @@
|
||||
//========= 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" );
|
||||
}
|
||||
Reference in New Issue
Block a user