summaryrefslogtreecommitdiff
path: root/game/shared/tf/tf_projectile_nail.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'game/shared/tf/tf_projectile_nail.cpp')
-rw-r--r--game/shared/tf/tf_projectile_nail.cpp254
1 files changed, 254 insertions, 0 deletions
diff --git a/game/shared/tf/tf_projectile_nail.cpp b/game/shared/tf/tf_projectile_nail.cpp
new file mode 100644
index 0000000..33ff4d5
--- /dev/null
+++ b/game/shared/tf/tf_projectile_nail.cpp
@@ -0,0 +1,254 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// TF Nail
+//
+//=============================================================================
+#include "cbase.h"
+#include "tf_projectile_nail.h"
+#include "tf_gamerules.h"
+
+#ifdef CLIENT_DLL
+#include "c_basetempentity.h"
+#include "c_te_legacytempents.h"
+#include "c_te_effect_dispatch.h"
+#include "input.h"
+#include "c_tf_player.h"
+#include "cliententitylist.h"
+#endif
+
+#ifdef GAME_DLL
+#include "tf_player.h"
+#endif
+
+
+//=============================================================================
+//
+// TF Syringe Projectile functions (Server specific).
+//
+#define SYRINGE_MODEL "models/weapons/w_models/w_syringe_proj.mdl"
+#define SYRINGE_DISPATCH_EFFECT "ClientProjectile_Syringe"
+
+LINK_ENTITY_TO_CLASS( tf_projectile_syringe, CTFProjectile_Syringe );
+PRECACHE_REGISTER( tf_projectile_syringe );
+
+#ifdef STAGING_ONLY
+LINK_ENTITY_TO_CLASS( tf_projectile_tranq, CTFProjectile_Tranq );
+PRECACHE_REGISTER( tf_projectile_tranq );
+#endif // STAGING_ONLY
+
+short g_sModelIndexSyringe;
+void PrecacheSyringe(void *pUser)
+{
+ g_sModelIndexSyringe = modelinfo->GetModelIndex( SYRINGE_MODEL );
+}
+
+PRECACHE_REGISTER_FN(PrecacheSyringe);
+
+//-----------------------------------------------------------------------------
+// CTFProjectile_Syringe
+//-----------------------------------------------------------------------------
+#define SYRINGE_GRAVITY 0.3f
+#define SYRINGE_VELOCITY 1000.0f
+// Purpose:
+//-----------------------------------------------------------------------------
+CTFBaseProjectile *CTFProjectile_Syringe::Create(
+ const Vector &vecOrigin,
+ const QAngle &vecAngles,
+ CTFWeaponBaseGun *pLauncher /*= NULL*/,
+ CBaseEntity *pOwner /*= NULL*/,
+ CBaseEntity *pScorer /*= NULL*/,
+ bool bCritical /*= false */
+) {
+ return CTFBaseProjectile::Create( "tf_projectile_syringe", vecOrigin, vecAngles, pOwner, SYRINGE_VELOCITY, g_sModelIndexSyringe, SYRINGE_DISPATCH_EFFECT, pScorer, bCritical );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+unsigned int CTFProjectile_Syringe::PhysicsSolidMaskForEntity( void ) const
+{
+ return BaseClass::PhysicsSolidMaskForEntity() | CONTENTS_REDTEAM | CONTENTS_BLUETEAM;
+}
+
+//-----------------------------------------------------------------------------
+float CTFProjectile_Syringe::GetGravity( void )
+{
+ return SYRINGE_GRAVITY;
+}
+
+#ifdef STAGING_ONLY
+//-----------------------------------------------------------------------------
+// CTFProjectile_Tranq
+#define TRANQ_GRAVITY 0.1f
+#define TRANQ_VELOCITY 2000.0f
+#define TRANQ_STUN 0.50f
+#define TRANQ_DURATION 1.5f
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CTFBaseProjectile *CTFProjectile_Tranq::Create(
+ const Vector &vecOrigin,
+ const QAngle &vecAngles,
+ CTFWeaponBaseGun *pLauncher /*= NULL*/,
+ CBaseEntity *pOwner /*= NULL*/,
+ CBaseEntity *pScorer /*= NULL*/,
+ bool bCritical /*= false */
+) {
+ return CTFBaseProjectile::Create( "tf_projectile_tranq", vecOrigin, vecAngles, pOwner, TRANQ_VELOCITY, g_sModelIndexSyringe, SYRINGE_DISPATCH_EFFECT, pScorer, bCritical );
+}
+
+//-----------------------------------------------------------------------------
+float CTFProjectile_Tranq::GetGravity( void )
+{
+ return TRANQ_GRAVITY;
+}
+
+#ifdef GAME_DLL
+//-----------------------------------------------------------------------------
+void CTFProjectile_Tranq::ProjectileTouch( CBaseEntity *pOther )
+{
+ // Verify a correct "other."
+ Assert( pOther );
+ if ( !pOther->IsSolid() || pOther->IsSolidFlagSet( FSOLID_VOLUME_CONTENTS ) )
+ return;
+
+ // Handle hitting skybox (disappear).
+ const trace_t *pTrace = &CBaseEntity::GetTouchTrace();
+ trace_t *pNewTrace = const_cast<trace_t*>( pTrace );
+
+ if( pTrace->surface.flags & SURF_SKY )
+ {
+ UTIL_Remove( this );
+ return;
+ }
+
+ // pass through ladders
+ if( pTrace->surface.flags & CONTENTS_LADDER )
+ return;
+
+ if ( TFGameRules() && TFGameRules()->GameModeUsesUpgrades() )
+ {
+ // Projectile shields
+ if ( InSameTeam( pOther ) && pOther->IsCombatItem() )
+ return;
+ }
+
+ if ( pOther->IsWorld() )
+ {
+ SetAbsVelocity( vec3_origin );
+ AddSolidFlags( FSOLID_NOT_SOLID );
+
+ // Remove immediately. Clientside projectiles will stick in the wall for a bit.
+ UTIL_Remove( this );
+ return;
+ }
+
+ // determine the inflictor, which is the weapon which fired this projectile
+ CBaseEntity *pInflictor = GetLauncher();
+
+ CTakeDamageInfo info;
+ info.SetAttacker( GetOwnerEntity() ); // the player who operated the thing that emitted nails
+ info.SetInflictor( pInflictor ); // the weapon that emitted this projectile
+ info.SetWeapon( pInflictor );
+ info.SetDamage( GetDamage() );
+ info.SetDamageForce( GetDamageForce() );
+ info.SetDamagePosition( GetAbsOrigin() );
+ info.SetDamageType( GetDamageType() );
+
+ Vector dir;
+ AngleVectors( GetAbsAngles(), &dir );
+
+ pOther->DispatchTraceAttack( info, dir, pNewTrace );
+ ApplyMultiDamage();
+
+ CTFPlayer *pTFVictim = ToTFPlayer( pOther );
+ CTFPlayer *pTFOwner = ToTFPlayer( GetOwnerEntity() );
+
+ if ( pTFVictim && pTFOwner && !InSameTeam( pTFVictim ) )
+ {
+ // Apply Slow Condition
+ pTFVictim->m_Shared.StunPlayer( TRANQ_DURATION, TRANQ_STUN, TF_STUN_MOVEMENT, pTFOwner );
+ pTFVictim->m_Shared.AddCond( TF_COND_TRANQ_MARKED, PERMANENT_CONDITION, pTFOwner ); // Tranq marked until you die
+ pTFVictim->ApplyPunchImpulseX( -2.0f ); // Apply a flinch
+
+ // Apply a boost to the attacker
+ //pTFOwner->m_Shared.AddCond( TF_COND_SPEED_BOOST, 3.0f );
+ pTFOwner->m_Shared.AddCond( TF_COND_TRANQ_SPY_BOOST, 3.0f );
+ }
+
+ UTIL_Remove( this );
+}
+#endif // GAME_DLL
+#endif // STAGING_ONLY
+
+#ifdef CLIENT_DLL
+
+//-----------------------------------------------------------------------------
+void GetSyringeTrailParticleName( CTFPlayer *pPlayer, CAttribute_String *attrParticleName, bool bCritical )
+{
+ int iTeamNumber = TF_TEAM_RED;
+ if ( pPlayer )
+ {
+ iTeamNumber = pPlayer->GetTeamNumber();
+ CTFWeaponBase *pWeapon = pPlayer->GetActiveTFWeapon();
+ if ( pWeapon )
+ {
+ static CSchemaAttributeDefHandle pAttrDef_ParticleName( "projectile particle name" );
+ CEconItemView *pItem = pWeapon->GetAttributeContainer()->GetItem();
+ if ( pAttrDef_ParticleName && pItem )
+ {
+ if ( pItem->FindAttribute( pAttrDef_ParticleName, attrParticleName ) )
+ {
+ const char * pParticleName = attrParticleName->value().c_str();
+ if ( iTeamNumber == TF_TEAM_BLUE && V_stristr( pParticleName, "_teamcolor_red" ))
+ {
+ static char pBlue[256];
+ V_StrSubst( attrParticleName->value().c_str(), "_teamcolor_red", "_teamcolor_blue", pBlue, 256 );
+ attrParticleName->set_value( pBlue );
+ }
+ return;
+ }
+ }
+ }
+ }
+
+ if ( iTeamNumber == TF_TEAM_BLUE )
+ {
+ attrParticleName->set_value( bCritical ? "nailtrails_medic_blue_crit" : "nailtrails_medic_blue" );
+ }
+ else
+ {
+ attrParticleName->set_value( bCritical ? "nailtrails_medic_red_crit" : "nailtrails_medic_red" );
+ }
+ return;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: For Synrgine Projectiles, Add effects
+//-----------------------------------------------------------------------------
+void ClientsideProjectileSyringeCallback( const CEffectData &data )
+{
+ // Get the syringe and add it to the client entity list, so we can attach a particle system to it.
+ C_TFPlayer *pPlayer = dynamic_cast<C_TFPlayer*>( ClientEntityList().GetBaseEntityFromHandle( data.m_hEntity ) );
+ if ( pPlayer )
+ {
+ C_LocalTempEntity *pSyringe = ClientsideProjectileCallback( data, SYRINGE_GRAVITY );
+ if ( pSyringe )
+ {
+ CAttribute_String attrParticleName;
+
+ pSyringe->m_nSkin = ( pPlayer->GetTeamNumber() == TF_TEAM_RED ) ? 0 : 1;
+ bool bCritical = ( ( data.m_nDamageType & DMG_CRITICAL ) != 0 );
+ GetSyringeTrailParticleName( pPlayer, &attrParticleName, bCritical );
+
+ pSyringe->AddParticleEffect( attrParticleName.value().c_str() );
+ pSyringe->AddEffects( EF_NOSHADOW );
+ pSyringe->flags |= FTENT_USEFASTCOLLISIONS;
+ }
+ }
+}
+
+DECLARE_CLIENT_EFFECT( SYRINGE_DISPATCH_EFFECT, ClientsideProjectileSyringeCallback );
+
+#endif