diff options
| author | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
|---|---|---|
| committer | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
| commit | 39ed87570bdb2f86969d4be821c94b722dc71179 (patch) | |
| tree | abc53757f75f40c80278e87650ea92808274aa59 /mp/src/game/server/hl2/grenade_tripwire.cpp | |
| download | source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip | |
First version of the SOurce SDK 2013
Diffstat (limited to 'mp/src/game/server/hl2/grenade_tripwire.cpp')
| -rw-r--r-- | mp/src/game/server/hl2/grenade_tripwire.cpp | 397 |
1 files changed, 397 insertions, 0 deletions
diff --git a/mp/src/game/server/hl2/grenade_tripwire.cpp b/mp/src/game/server/hl2/grenade_tripwire.cpp new file mode 100644 index 00000000..6359c309 --- /dev/null +++ b/mp/src/game/server/hl2/grenade_tripwire.cpp @@ -0,0 +1,397 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Implements the tripmine grenade.
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#include "cbase.h"
+#include "util.h"
+#include "shake.h"
+#include "grenade_tripwire.h"
+#include "grenade_homer.h"
+#include "rope.h"
+#include "rope_shared.h"
+#include "engine/IEngineSound.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+ConVar sk_dmg_tripwire ( "sk_dmg_tripwire","0");
+ConVar sk_tripwire_radius ( "sk_tripwire_radius","0");
+
+#define GRENADETRIPWIRE_MISSILEMDL "models/Weapons/ar2_grenade.mdl"
+
+#define TGRENADE_LAUNCH_VEL 1200
+#define TGRENADE_SPIN_MAG 50
+#define TGRENADE_SPIN_SPEED 100
+#define TGRENADE_MISSILE_OFFSET 50
+#define TGRENADE_MAX_ROPE_LEN 1500
+
+LINK_ENTITY_TO_CLASS( npc_tripwire, CTripwireGrenade );
+
+BEGIN_DATADESC( CTripwireGrenade )
+
+ DEFINE_FIELD( m_flPowerUp, FIELD_TIME ),
+ DEFINE_FIELD( m_nMissileCount, FIELD_INTEGER ),
+ DEFINE_FIELD( m_vecDir, FIELD_VECTOR ),
+ DEFINE_FIELD( m_vTargetPos, FIELD_POSITION_VECTOR ),
+ DEFINE_FIELD( m_vTargetOffset, FIELD_VECTOR ),
+ DEFINE_FIELD( m_pRope, FIELD_CLASSPTR ),
+ DEFINE_FIELD( m_pHook, FIELD_CLASSPTR ),
+
+ // Function Pointers
+ DEFINE_FUNCTION( WarningThink ),
+ DEFINE_FUNCTION( PowerupThink ),
+ DEFINE_FUNCTION( RopeBreakThink ),
+ DEFINE_FUNCTION( FireThink ),
+
+END_DATADESC()
+
+CTripwireGrenade::CTripwireGrenade()
+{
+ m_vecDir.Init();
+}
+
+void CTripwireGrenade::Spawn( void )
+{
+ Precache( );
+
+ SetMoveType( MOVETYPE_FLY );
+ SetSolid( SOLID_BBOX );
+ AddSolidFlags( FSOLID_NOT_SOLID );
+
+ SetModel( "models/Weapons/w_slam.mdl" );
+
+ m_nMissileCount = 0;
+
+ UTIL_SetSize(this, Vector( -4, -4, -2), Vector(4, 4, 2));
+
+ m_flPowerUp = gpGlobals->curtime + 1.2;//<<CHECK>>get rid of this
+
+ SetThink( WarningThink );
+ SetNextThink( gpGlobals->curtime + 1.0f );
+
+ m_takedamage = DAMAGE_YES;
+
+ m_iHealth = 1;
+
+ m_pRope = NULL;
+ m_pHook = NULL;
+
+ // Tripwire grenade sits at 90 on wall so rotate back to get m_vecDir
+ QAngle angles = GetLocalAngles();
+ angles.x -= 90;
+
+ AngleVectors( angles, &m_vecDir );
+}
+
+
+void CTripwireGrenade::Precache( void )
+{
+ PrecacheModel("models/Weapons/w_slam.mdl");
+
+ PrecacheModel(GRENADETRIPWIRE_MISSILEMDL);
+}
+
+
+void CTripwireGrenade::WarningThink( void )
+{
+ // play activate sound
+ EmitSound( "TripwireGrenade.Activate" );
+
+ // set to power up
+ SetThink( PowerupThink );
+ SetNextThink( gpGlobals->curtime + 1.0f );
+}
+
+
+void CTripwireGrenade::PowerupThink( void )
+{
+ if (gpGlobals->curtime > m_flPowerUp)
+ {
+ MakeRope( );
+ RemoveSolidFlags( FSOLID_NOT_SOLID );
+ m_bIsLive = true;
+ }
+ SetNextThink( gpGlobals->curtime + 0.1f );
+}
+
+
+void CTripwireGrenade::BreakRope( void )
+{
+ if (m_pRope)
+ {
+ m_pRope->m_RopeFlags |= ROPE_COLLIDE;
+ m_pRope->DetachPoint(0);
+
+ Vector vVelocity;
+ m_pHook->GetVelocity( &vVelocity, NULL );
+ if (vVelocity.Length() > 1)
+ {
+ m_pRope->DetachPoint(1);
+ }
+ }
+}
+
+
+void CTripwireGrenade::MakeRope( void )
+{
+ SetThink( RopeBreakThink );
+
+ // Delay first think slightly so rope has time
+ // to appear if person right in front of it
+ SetNextThink( gpGlobals->curtime + 1.0f );
+
+ // Create hook for end of tripwire
+ m_pHook = (CTripwireHook*)CBaseEntity::Create( "tripwire_hook", GetLocalOrigin(), GetLocalAngles() );
+ if (m_pHook)
+ {
+ Vector vShootVel = 800*(m_vecDir + Vector(0,0,0.3)+RandomVector(-0.01,0.01));
+ m_pHook->SetVelocity( vShootVel, vec3_origin);
+ m_pHook->SetOwnerEntity( this );
+ m_pHook->m_hGrenade = this;
+
+ m_pRope = CRopeKeyframe::Create(this,m_pHook,0,0);
+ if (m_pRope)
+ {
+ m_pRope->m_Width = 1;
+ m_pRope->m_RopeLength = 3;
+ m_pRope->m_Slack = 100;
+
+ CPASAttenuationFilter filter( this,"TripwireGrenade.ShootRope" );
+ EmitSound( filter, entindex(),"TripwireGrenade.ShootRope" );
+ }
+ }
+}
+
+void CTripwireGrenade::Attach( void )
+{
+ StopSound( "TripwireGrenade.ShootRope" );
+}
+
+void CTripwireGrenade::RopeBreakThink( void )
+{
+ // See if I can go solid yet (has dropper moved out of way?)
+ if (IsSolidFlagSet(FSOLID_NOT_SOLID))
+ {
+ trace_t tr;
+ Vector vUpBit = GetAbsOrigin();
+ vUpBit.z += 5.0;
+
+ UTIL_TraceEntity( this, GetAbsOrigin(), vUpBit, MASK_SHOT, &tr );
+ if ( !tr.startsolid && (tr.fraction == 1.0) )
+ {
+ RemoveSolidFlags( FSOLID_NOT_SOLID );
+ }
+ }
+
+ // Check if rope had gotten beyond it's max length
+ float flRopeLength = (GetAbsOrigin()-m_pHook->GetAbsOrigin()).Length();
+ if (flRopeLength > TGRENADE_MAX_ROPE_LEN)
+ {
+ // Shoot missiles at hook
+ m_iHealth = 0;
+ BreakRope();
+ m_vTargetPos = m_pHook->GetAbsOrigin();
+ CrossProduct ( m_vecDir, Vector(0,0,1), m_vTargetOffset );
+ m_vTargetOffset *=TGRENADE_MISSILE_OFFSET;
+ SetThink(FireThink);
+ FireThink();
+ }
+
+ // Check to see if can see hook
+ // NOT MASK_SHOT because we want only simple hit boxes
+ trace_t tr;
+ UTIL_TraceLine( GetAbsOrigin(), m_pHook->GetAbsOrigin(), MASK_SOLID, this, COLLISION_GROUP_NONE, &tr );
+
+ // If can't see hook
+ CBaseEntity *pEntity = tr.m_pEnt;
+ if (tr.fraction != 1.0 && pEntity != m_pHook)
+ {
+ // Shoot missiles at place where rope was intersected
+ m_iHealth = 0;
+ BreakRope();
+ m_vTargetPos = tr.endpos;
+ CrossProduct ( m_vecDir, Vector(0,0,1), m_vTargetOffset );
+ m_vTargetOffset *=TGRENADE_MISSILE_OFFSET;
+ SetThink(FireThink);
+ FireThink();
+ return;
+ }
+
+ SetNextThink( gpGlobals->curtime + 0.1f );
+}
+
+//------------------------------------------------------------------------------
+// Purpose : Die if I take any damage
+// Input :
+// Output :
+//------------------------------------------------------------------------------
+int CTripwireGrenade::OnTakeDamage_Alive( const CTakeDamageInfo &info )
+{
+ // Killed upon any damage
+ Event_Killed( info );
+ return 0;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: If someone damaged, me shoot of my missiles and die
+// Input :
+// Output :
+//-----------------------------------------------------------------------------
+void CTripwireGrenade::Event_Killed( const CTakeDamageInfo &info )
+{
+ if (m_iHealth > 0)
+ {
+ // Fire missiles and blow up
+ for (int i=0;i<6;i++)
+ {
+ Vector vTargetPos = GetAbsOrigin() + RandomVector(-600,600);
+ FireMissile(vTargetPos);
+ }
+ BreakRope();
+ UTIL_Remove(this);
+ }
+}
+
+//------------------------------------------------------------------------------
+// Purpose : Fire a missile at the target position
+// Input :
+// Output :
+//------------------------------------------------------------------------------
+void CTripwireGrenade::FireMissile(const Vector &vTargetPos)
+{
+ Vector vTargetDir = (vTargetPos - GetAbsOrigin());
+ VectorNormalize(vTargetDir);
+
+ float flGravity = 0.0001; // No gravity on the missiles
+ bool bSmokeTrail = true;
+ float flHomingSpeed = 0;
+ Vector vLaunchVelocity = TGRENADE_LAUNCH_VEL*vTargetDir;
+ float flSpinMagnitude = TGRENADE_SPIN_MAG;
+ float flSpinSpeed = TGRENADE_SPIN_SPEED;
+
+ //<<CHECK>> hold in string_t
+ CGrenadeHomer *pGrenade = CGrenadeHomer::CreateGrenadeHomer( MAKE_STRING(GRENADETRIPWIRE_MISSILEMDL), MAKE_STRING("TripwireGrenade.FlySound"), GetAbsOrigin(), vec3_angle, edict() );
+
+ pGrenade->Spawn( );
+ pGrenade->SetSpin(flSpinMagnitude,flSpinSpeed);
+ pGrenade->SetHoming(0,0,0,0,0);
+ pGrenade->SetDamage(sk_dmg_tripwire.GetFloat());
+ pGrenade->SetDamageRadius(sk_tripwire_radius.GetFloat());
+ pGrenade->Launch(this,NULL,vLaunchVelocity,flHomingSpeed,flGravity,bSmokeTrail);
+
+ // Calculate travel time
+ float flTargetDist = (GetAbsOrigin() - vTargetPos).Length();
+
+ pGrenade->m_flDetonateTime = gpGlobals->curtime + flTargetDist/TGRENADE_LAUNCH_VEL;
+
+}
+
+//------------------------------------------------------------------------------
+// Purpose : Shoot off a series of missiles over time, then go intert
+// Input :
+// Output :
+//------------------------------------------------------------------------------
+void CTripwireGrenade::FireThink()
+{
+ SetNextThink( gpGlobals->curtime + 0.16f );
+
+ Vector vTargetPos = m_vTargetPos + (m_vTargetOffset * m_nMissileCount);
+ FireMissile(vTargetPos);
+
+ vTargetPos = m_vTargetPos - (m_vTargetOffset * m_nMissileCount);
+ FireMissile(vTargetPos);
+
+
+ m_nMissileCount++;
+ if (m_nMissileCount > 4)
+ {
+ m_iHealth = -1;
+ SetThink( NULL );
+ }
+}
+
+// ####################################################################
+// CTripwireHook
+//
+// This is what the tripwire shoots out at the end of the rope
+// ####################################################################
+LINK_ENTITY_TO_CLASS( tripwire_hook, CTripwireHook );
+
+//---------------------------------------------------------
+// Save/Restore
+//---------------------------------------------------------
+BEGIN_DATADESC( CTripwireHook )
+
+ DEFINE_FIELD( m_hGrenade, FIELD_EHANDLE ),
+ DEFINE_FIELD( m_bAttached, FIELD_BOOLEAN ),
+
+END_DATADESC()
+
+
+void CTripwireHook::Spawn( void )
+{
+
+ Precache( );
+ SetModel( "models/Weapons/w_grenade.mdl" );//<<CHECK>>
+
+ UTIL_SetSize(this, Vector( -1, -1, -1), Vector(1,1, 1));
+
+ m_takedamage = DAMAGE_NO;
+ m_bAttached = false;
+
+ CreateVPhysics();
+}
+
+bool CTripwireHook::CreateVPhysics()
+{
+ // Create the object in the physics system
+ IPhysicsObject *pPhysicsObject = VPhysicsInitNormal( SOLID_BBOX, 0, false );
+
+ // Make sure I get touch called for static geometry
+ if ( pPhysicsObject )
+ {
+ int flags = pPhysicsObject->GetCallbackFlags();
+ flags |= CALLBACK_GLOBAL_TOUCH_STATIC;
+ pPhysicsObject->SetCallbackFlags(flags);
+ }
+ return true;
+}
+
+
+void CTripwireHook::Precache( void )
+{
+ PrecacheModel("models/Weapons/w_grenade.mdl"); //<<CHECK>>
+}
+
+void CTripwireHook::EndTouch( CBaseEntity *pOther )
+{
+ //<<CHECK>>do instead by clearing touch function
+ if (!m_bAttached)
+ {
+ m_bAttached = true;
+
+ SetVelocity(vec3_origin, vec3_origin);
+ SetMoveType( MOVETYPE_NONE );
+
+ EmitSound( "TripwireGrenade.Hook" );
+
+ // Let the tripwire grenade know that I've attached
+ CTripwireGrenade* pGrenade = dynamic_cast<CTripwireGrenade*>((CBaseEntity*)m_hGrenade);
+ if (pGrenade)
+ {
+ pGrenade->Attach();
+ }
+ }
+}
+
+void CTripwireHook::SetVelocity( const Vector &velocity, const AngularImpulse &angVelocity )
+{
+ IPhysicsObject *pPhysicsObject = VPhysicsGetObject();
+ if ( pPhysicsObject )
+ {
+ pPhysicsObject->AddVelocity( &velocity, &angVelocity );
+ }
+}
\ No newline at end of file |