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.
291 lines
7.7 KiB
291 lines
7.7 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// TF Pumpkin Bomb |
|
// |
|
//============================================================================= |
|
#include "cbase.h" |
|
#include "tf_pumpkin_bomb.h" |
|
#include "takedamageinfo.h" |
|
#include "tf_shareddefs.h" |
|
#include "props_shared.h" |
|
#ifdef GAME_DLL |
|
#include "te_effect_dispatch.h" |
|
#include "tf_fx.h" |
|
#include "tf_projectile_base.h" |
|
#include "basegrenade_shared.h" |
|
#include "tf_gamerules.h" |
|
#include "tf_weaponbase_rocket.h" |
|
#endif |
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
#define PUMPKIN_MODEL "models/props_halloween/pumpkin_explode.mdl" |
|
#define TEAM_PUMPKIN "models/props_halloween/pumpkin_explode_teamcolor.mdl" |
|
|
|
LINK_ENTITY_TO_CLASS( tf_pumpkin_bomb, CTFPumpkinBomb ); |
|
|
|
IMPLEMENT_NETWORKCLASS_ALIASED( TFPumpkinBomb, DT_TFPumpkinBomb ) |
|
|
|
BEGIN_NETWORK_TABLE( CTFPumpkinBomb, DT_TFPumpkinBomb ) |
|
END_NETWORK_TABLE() |
|
|
|
IMPLEMENT_AUTO_LIST( ITFPumpkinBomb ); |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CTFPumpkinBomb::CTFPumpkinBomb() |
|
{ |
|
#ifdef GAME_DLL |
|
m_bIsSpell = false; |
|
#endif |
|
|
|
m_bDead = false; |
|
m_bPrecached = false; |
|
|
|
m_iTeam = TF_TEAM_HALLOWEEN; |
|
m_flDamage = 150.0f; |
|
m_flScale = 1.0f; |
|
m_flRadius = 300.0f; |
|
m_flLifeTime = -1.0f; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFPumpkinBomb::Precache() |
|
{ |
|
BaseClass::Precache(); |
|
|
|
// always allow late precaching, so we don't pay the cost of the |
|
// Halloween pumpkin bomb for the entire year |
|
|
|
bool bAllowPrecache = CBaseEntity::IsPrecacheAllowed(); |
|
CBaseEntity::SetAllowPrecache( true ); |
|
|
|
int iModel = PrecacheModel( PUMPKIN_MODEL ); |
|
PrecacheGibsForModel( iModel ); |
|
|
|
PrecacheModel( TEAM_PUMPKIN ); |
|
|
|
PrecacheScriptSound( "Halloween.PumpkinExplode" ); |
|
|
|
CBaseEntity::SetAllowPrecache( bAllowPrecache ); |
|
|
|
m_bPrecached = true; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
void CTFPumpkinBomb::SetInitParams( float scale, float damage, float radius, int iTeam, float flLifeTime ) |
|
{ |
|
m_iTeam = iTeam; |
|
m_flDamage = damage; |
|
m_flScale = scale; |
|
m_flRadius = radius; |
|
|
|
if ( flLifeTime > 0 ) |
|
{ |
|
m_flLifeTime = flLifeTime; |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
void CTFPumpkinBomb::Spawn() |
|
{ |
|
if ( !m_bPrecached ) |
|
{ |
|
Precache(); |
|
} |
|
|
|
if ( m_iTeam != TF_TEAM_HALLOWEEN ) |
|
{ |
|
SetModel( TEAM_PUMPKIN ); |
|
m_nSkin = m_iTeam == TF_TEAM_BLUE ? 2 : 1; // This is actually opposite of what you'd think so Blue team can Hurt Blue Pumpkins |
|
SetCollisionGroup( TFCOLLISION_GROUP_TANK ); |
|
SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE ); |
|
SetSolid( SOLID_BBOX ); |
|
SetHealth( 1 ); |
|
} |
|
else |
|
{ |
|
SetModel( PUMPKIN_MODEL ); |
|
SetMoveType( MOVETYPE_VPHYSICS ); |
|
SetSolid( SOLID_VPHYSICS ); |
|
SetHealth( 1 ); |
|
} |
|
|
|
BaseClass::Spawn(); |
|
|
|
SetModelScale( m_flScale ); |
|
m_takedamage = DAMAGE_YES; |
|
m_bDead = false; |
|
|
|
SetTouch( &CTFPumpkinBombShim::Touch ); |
|
#ifdef GAME_DLL |
|
if ( m_flLifeTime > 0 ) |
|
{ |
|
SetContextThink( &CTFPumpkinBomb::RemovePumpkin, gpGlobals->curtime + m_flLifeTime, "RemovePumpkin" ); |
|
} |
|
#endif |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
void CTFPumpkinBomb::RemovePumpkin() |
|
{ |
|
#ifdef GAME_DLL |
|
CPVSFilter filter( GetAbsOrigin() ); |
|
TE_TFParticleEffect( filter, 0.0, m_iTeam == TF_TEAM_RED ? "spell_pumpkin_mirv_goop_red" : "spell_pumpkin_mirv_goop_blue", GetAbsOrigin(), vec3_angle ); |
|
UTIL_Remove( this ); |
|
#endif // GAME_DLL |
|
} |
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFPumpkinBomb::PumpkinTouch( CBaseEntity *pOther ) |
|
{ |
|
if ( !pOther ) |
|
return; |
|
|
|
#ifdef GAME_DLL |
|
if ( pOther->GetFlags() & FL_GRENADE ) |
|
{ |
|
// Only let my team destroy |
|
CBaseEntity *pAttacker = NULL; |
|
|
|
CBaseGrenade *pGrenade = dynamic_cast<CBaseGrenade*>(pOther); |
|
if ( pGrenade ) |
|
{ |
|
pAttacker = pGrenade->GetThrower(); |
|
// Do a proper explosion |
|
Vector velDir = pGrenade->GetAbsVelocity(); |
|
VectorNormalize( velDir ); |
|
Vector vecSpot = pGrenade->GetAbsOrigin() - velDir * 32; |
|
trace_t tr; |
|
UTIL_TraceLine( vecSpot, vecSpot + velDir * 64, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr ); |
|
// Boom |
|
pGrenade->Explode( &tr, DMG_BLAST ); |
|
} |
|
else |
|
{ |
|
CTFBaseRocket *pRocket = dynamic_cast<CTFBaseRocket*>(pOther); |
|
if ( pRocket ) |
|
{ |
|
Vector velDir = pRocket->GetAbsVelocity(); |
|
VectorNormalize( velDir ); |
|
Vector vecSpot = pRocket->GetAbsOrigin() - velDir * 32; |
|
trace_t tr; |
|
UTIL_TraceLine( vecSpot, vecSpot + velDir * 64, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr ); |
|
pRocket->Explode( &tr, this ); |
|
} |
|
} |
|
|
|
if ( !pAttacker ) |
|
{ |
|
CTFBaseProjectile *pProj = dynamic_cast<CTFBaseProjectile*>(pOther); |
|
if ( pProj ) |
|
{ |
|
pAttacker = pProj->GetScorer(); |
|
} |
|
} |
|
|
|
if ( m_iTeam != TF_TEAM_HALLOWEEN && pOther->GetTeamNumber() != m_iTeam ) |
|
{ |
|
RemovePumpkin(); |
|
} |
|
else |
|
{ |
|
TakeDamage( CTakeDamageInfo( pOther, pAttacker, 10.f, DMG_CRUSH ) ); |
|
} |
|
} |
|
else if ( FStrEq( STRING(pOther->m_iClassname), "trigger_hurt" ) ) |
|
{ |
|
RemovePumpkin(); |
|
} |
|
#endif |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
#ifdef GAME_DLL |
|
int CTFPumpkinBomb::OnTakeDamage( const CTakeDamageInfo &info ) |
|
{ |
|
CPVSFilter filter( GetAbsOrigin() ); |
|
if ( m_iTeam != TF_TEAM_HALLOWEEN ) |
|
{ |
|
TE_TFParticleEffect( filter, 0.0, m_iTeam == TF_TEAM_RED ? "spell_pumpkin_mirv_goop_red" : "spell_pumpkin_mirv_goop_blue", GetAbsOrigin(), vec3_angle ); |
|
} |
|
|
|
// if damage is from same team, Setlife to one and pass to base class |
|
if ( info.GetAttacker()->GetTeamNumber() == m_iTeam ) |
|
{ |
|
SetHealth( 1 ); |
|
} |
|
else if ( m_iTeam != TF_TEAM_HALLOWEEN ) |
|
{ |
|
RemovePumpkin(); |
|
return 0; |
|
} |
|
|
|
return BaseClass::OnTakeDamage( info ); |
|
} |
|
//----------------------------------------------------------------------------- |
|
void CTFPumpkinBomb::Event_Killed( const CTakeDamageInfo &info ) |
|
{ |
|
if ( m_bDead ) |
|
return; |
|
|
|
m_bDead = true; |
|
|
|
if ( m_iTeam != TF_TEAM_HALLOWEEN && info.GetAttacker()->GetTeamNumber() != m_iTeam ) |
|
{ |
|
RemovePumpkin(); |
|
return; |
|
} |
|
|
|
trace_t tr; |
|
Vector vecSpot = GetAbsOrigin() + Vector ( 0 , 0 , 8 ); |
|
UTIL_TraceLine( vecSpot, vecSpot + Vector ( 0, 0, -32 ), MASK_SHOT_HULL, this, COLLISION_GROUP_NONE, &tr ); |
|
|
|
// Explosion effect and gibs. |
|
Vector vecOrigin = GetAbsOrigin(); |
|
QAngle vecAngles = GetAbsAngles(); |
|
CPVSFilter filter( vecOrigin ); |
|
TE_TFExplosion( filter, 0.0f, vecOrigin, tr.plane.normal, TF_WEAPON_PUMPKIN_BOMB, -1 ); |
|
TE_TFParticleEffect( filter, 0.0f, "pumpkin_explode", vecOrigin, vecAngles ); |
|
|
|
// Deal damage. |
|
SetSolid( SOLID_NONE ); |
|
if ( info.GetAttacker() ) |
|
{ |
|
ChangeTeam( info.GetAttacker()->GetTeamNumber() ); |
|
} |
|
CTakeDamageInfo damage_info( this, info.GetAttacker(), NULL, m_flDamage, DMG_BLAST | DMG_HALF_FALLOFF | DMG_NOCLOSEDISTANCEMOD ); |
|
damage_info.SetDamageCustom( m_bIsSpell ? TF_DMG_CUSTOM_SPELL_MIRV : TF_DMG_CUSTOM_PUMPKIN_BOMB ); |
|
|
|
if ( TFGameRules() ) |
|
{ |
|
CTFRadiusDamageInfo radiusinfo( &damage_info, vecOrigin, m_flRadius, this ); |
|
TFGameRules()->RadiusDamage( radiusinfo ); |
|
} |
|
|
|
// Don't decal players with scorch. |
|
if ( tr.m_pEnt && !tr.m_pEnt->IsPlayer() ) |
|
{ |
|
UTIL_DecalTrace( &tr, "Scorch" ); |
|
} |
|
|
|
Break(); |
|
|
|
BaseClass::Event_Killed( info ); |
|
} |
|
|
|
void CTFPumpkinBomb::Break( void ) |
|
{ |
|
CPVSFilter filter( GetAbsOrigin() ); |
|
UserMessageBegin( filter, "BreakModel" ); |
|
WRITE_SHORT( GetModelIndex() ); |
|
WRITE_VEC3COORD( GetAbsOrigin() ); |
|
WRITE_ANGLES( GetAbsAngles() ); |
|
WRITE_SHORT( m_nSkin ); |
|
MessageEnd(); |
|
} |
|
#endif
|
|
|