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_beam.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_beam.cpp')
| -rw-r--r-- | mp/src/game/server/hl2/grenade_beam.cpp | 443 |
1 files changed, 443 insertions, 0 deletions
diff --git a/mp/src/game/server/hl2/grenade_beam.cpp b/mp/src/game/server/hl2/grenade_beam.cpp new file mode 100644 index 00000000..0f20c7de --- /dev/null +++ b/mp/src/game/server/hl2/grenade_beam.cpp @@ -0,0 +1,443 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Projectile shot by mortar synth.
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#include "cbase.h"
+#include "grenade_beam.h"
+#include "beam_shared.h"
+#include "ndebugoverlay.h"
+#include "decals.h"
+#include "engine/IEngineSound.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+#define GRENADEBEAM_DEFAULTWIDTH 2.0
+
+// ==============================================================================
+// > CGrenadeBeamChaser
+// ==============================================================================
+BEGIN_DATADESC( CGrenadeBeamChaser )
+
+ DEFINE_FIELD( m_pTarget, FIELD_CLASSPTR ),
+
+ // Function pointers
+ DEFINE_FUNCTION( ChaserThink ),
+
+END_DATADESC()
+
+LINK_ENTITY_TO_CLASS( grenade_beam_chaser, CGrenadeBeamChaser );
+
+//------------------------------------------------------------------------------
+// Purpose :
+// Input :
+// Output :
+//------------------------------------------------------------------------------
+void CGrenadeBeamChaser::Spawn( void )
+{
+ SetSolid( SOLID_NONE );
+ SetMoveType( MOVETYPE_FLY );
+ SetThink(&CGrenadeBeamChaser::ChaserThink);
+ SetNextThink( gpGlobals->curtime );
+}
+
+//------------------------------------------------------------------------------
+// Purpose :
+// Input :
+// Output :
+//------------------------------------------------------------------------------
+void CGrenadeBeamChaser::ChaserThink( void )
+{
+ Vector vTargetPos;
+ m_pTarget->GetChaserTargetPos(&vTargetPos);
+ Vector vTargetDir = (vTargetPos - GetLocalOrigin());
+
+ // -------------------------------------------------
+ // Check to see if we'll pass our target this frame
+ // If so get the next target
+ // -------------------------------------------------
+ float flTargetDist = vTargetDir.Length();
+ if ((gpGlobals->frametime * m_pTarget->m_flBeamSpeed) > flTargetDist)
+ {
+ m_pTarget->GetNextTargetPos(&vTargetPos);
+ vTargetDir = (vTargetPos - GetLocalOrigin());
+ flTargetDist = vTargetDir.Length();
+ }
+
+ if (flTargetDist != 0)
+ {
+ //--------------------------------------
+ // Set our velocity to chase the target
+ //--------------------------------------
+ VectorNormalize(vTargetDir);
+ SetAbsVelocity( vTargetDir * m_pTarget->m_flBeamSpeed );
+ }
+ SetNextThink( gpGlobals->curtime );
+}
+
+//------------------------------------------------------------------------------
+// Purpose :
+// Input :
+// Output :
+//------------------------------------------------------------------------------
+CGrenadeBeamChaser* CGrenadeBeamChaser::ChaserCreate( CGrenadeBeam *pTarget )
+{
+ CGrenadeBeamChaser *pChaser = (CGrenadeBeamChaser *)CreateEntityByName( "grenade_beam_chaser" );
+ pChaser->SetLocalOrigin( pTarget->GetLocalOrigin() );
+ pChaser->m_pTarget = pTarget;
+ pChaser->Spawn();
+ return pChaser;
+}
+
+// ==============================================================================
+// > CGrenadeBeam
+// ==============================================================================
+BEGIN_DATADESC( CGrenadeBeam )
+
+ DEFINE_FIELD( m_vLaunchPos, FIELD_POSITION_VECTOR ),
+ DEFINE_FIELD( m_flBeamWidth, FIELD_FLOAT ),
+ DEFINE_FIELD( m_flBeamSpeed, FIELD_FLOAT ),
+ DEFINE_FIELD( m_flBeamLag, FIELD_FLOAT ),
+ DEFINE_FIELD( m_flLaunchTime, FIELD_TIME ),
+ DEFINE_FIELD( m_flLastTouchTime, FIELD_TIME ),
+ DEFINE_FIELD( m_hBeamChaser, FIELD_EHANDLE ),
+ DEFINE_FIELD( m_nNumHits, FIELD_INTEGER ),
+
+ DEFINE_ARRAY( m_pHitLocation, FIELD_VECTOR, GRENADEBEAM_MAXHITS ),
+ DEFINE_ARRAY( m_pBeam, FIELD_CLASSPTR, GRENADEBEAM_MAXBEAMS ),
+
+ // Function pointers
+ DEFINE_ENTITYFUNC( GrenadeBeamTouch ),
+ DEFINE_THINKFUNC( KillBeam ),
+
+END_DATADESC()
+
+LINK_ENTITY_TO_CLASS( grenade_beam, CGrenadeBeam );
+
+//------------------------------------------------------------------------------
+// Purpose :
+// Input :
+// Output :
+//------------------------------------------------------------------------------
+void CGrenadeBeam::Spawn( void )
+{
+ Precache( );
+ SetSolid( SOLID_BBOX );
+ SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE );
+
+ //UNDONE/HACK: this model is never used but one is needed
+ SetModel( "Models/weapons/flare.mdl" );
+ AddEffects( EF_NODRAW );
+
+ SetTouch( &CGrenadeBeam::GrenadeBeamTouch );
+ SetNextThink( gpGlobals->curtime );
+
+ m_takedamage = DAMAGE_NO;
+ m_iHealth = 1;
+ SetGravity( 0.0001 );
+ m_nNumHits = 0;
+ UTIL_SetSize( this, vec3_origin, vec3_origin );
+}
+
+
+//------------------------------------------------------------------------------
+// Purpose :
+// Input :
+// Output :
+//------------------------------------------------------------------------------
+CGrenadeBeam* CGrenadeBeam::Create( CBaseEntity* pOwner, const Vector &vStart)
+{
+ CGrenadeBeam *pEnergy = (CGrenadeBeam *)CreateEntityByName( "grenade_beam" );
+ pEnergy->Spawn();
+ pEnergy->SetOwnerEntity( pOwner );
+ pEnergy->SetRenderColor( 255, 0, 0, 0 );
+ pEnergy->m_flBeamWidth = GRENADEBEAM_DEFAULTWIDTH;
+ UTIL_SetOrigin( pEnergy, vStart );
+
+ return pEnergy;
+}
+
+//------------------------------------------------------------------------------
+// Purpose :
+// Input :
+// Output :
+//------------------------------------------------------------------------------
+void CGrenadeBeam::Format(color32 clrColor, float flWidth)
+{
+ m_clrRender = clrColor;
+ m_flBeamWidth = flWidth;
+}
+
+//------------------------------------------------------------------------------
+// Purpose :
+// Input :
+// Output :
+//------------------------------------------------------------------------------
+void CGrenadeBeam::Shoot(Vector vDirection, float flSpeed, float flLifetime, float flLag, float flDamage )
+{
+ SetThink ( &CGrenadeBeam::KillBeam );
+ SetNextThink( gpGlobals->curtime + flLifetime );
+ m_hBeamChaser = CGrenadeBeamChaser::ChaserCreate(this);
+ m_flBeamSpeed = flSpeed;
+ SetAbsVelocity( vDirection * flSpeed );
+ m_flBeamLag = flLag;
+ m_flDamage = flDamage;
+ m_flLaunchTime = gpGlobals->curtime;
+ m_vLaunchPos = GetAbsOrigin();
+ m_flLastTouchTime = 0;
+ CreateBeams();
+ UpdateBeams();
+}
+
+//------------------------------------------------------------------------------
+// Purpose :
+// Input :
+// Output :
+//------------------------------------------------------------------------------
+void CGrenadeBeam::KillBeam(void)
+{
+ SetThink(NULL);
+ SetTouch(NULL);
+ m_hBeamChaser->SetThink(NULL);
+ UTIL_Remove(m_hBeamChaser);
+ UTIL_Remove(this);
+
+ for (int i=0;i<GRENADEBEAM_MAXBEAMS;i++)
+ {
+ if (m_pBeam[i])
+ {
+ UTIL_Remove(m_pBeam[i]);
+ }
+ }
+}
+//------------------------------------------------------------------------------
+// Purpose :
+// Input :
+// Output :
+//------------------------------------------------------------------------------
+void CGrenadeBeam::GrenadeBeamTouch( CBaseEntity *pOther )
+{
+ //---------------------------------------------------------
+ // Make sure I'm not caught in a corner, if so remove me
+ //---------------------------------------------------------
+ if (gpGlobals->curtime - m_flLastTouchTime < 0.01)
+ {
+ KillBeam();
+ return;
+ }
+ m_flLastTouchTime = gpGlobals->curtime;
+
+ // ---------------------------------------
+ // If I have room for another hit, add it
+ // ---------------------------------------
+ if (m_nNumHits < GRENADEBEAM_MAXHITS)
+ {
+ m_pHitLocation[m_nNumHits] = GetLocalOrigin();
+ m_nNumHits++;
+ }
+ // Otherwise copy over old hit, and force chaser into last hit position
+ else
+ {
+ m_hBeamChaser->SetLocalOrigin( m_pHitLocation[0] );
+ for (int i=0;i<m_nNumHits-1;i++)
+ {
+ m_pHitLocation[i] = m_pHitLocation[i+1];
+ }
+ m_pHitLocation[m_nNumHits-1]=GetLocalOrigin();
+ }
+ UpdateBeams();
+
+ // --------------------------------------
+ // Smoke or bubbles effect
+ // --------------------------------------
+ if (UTIL_PointContents ( GetAbsOrigin() ) & MASK_WATER)
+ {
+ UTIL_Bubbles(GetAbsOrigin()-Vector(3,3,3),GetAbsOrigin()+Vector(3,3,3),10);
+ }
+ else
+ {
+ UTIL_Smoke(GetAbsOrigin(), random->RandomInt(5, 10), 10);
+ }
+
+ // --------------------------------------------
+ // Play burn sounds
+ // --------------------------------------------
+ if (pOther->m_takedamage)
+ {
+ pOther->TakeDamage( CTakeDamageInfo( this, this, m_flDamage, DMG_BURN ) );
+ KillBeam();
+ return;
+ }
+
+ EmitSound( "GrenadeBeam.HitSound" );
+
+ trace_t tr;
+ Vector vDirection = GetAbsVelocity();
+ VectorNormalize(vDirection);
+ UTIL_TraceLine( GetAbsOrigin()-vDirection, GetAbsOrigin()+vDirection, MASK_SOLID, NULL, COLLISION_GROUP_NONE, &tr );
+ UTIL_DecalTrace( &tr, "RedGlowFade" );
+ UTIL_ImpactTrace( &tr, DMG_ENERGYBEAM );
+}
+
+//------------------------------------------------------------------------------
+// Purpose :
+// Input :
+// Output :
+//------------------------------------------------------------------------------
+void CGrenadeBeam::GetNextTargetPos(Vector *vPosition)
+{
+ // Only advance if tail launch time has passed
+ if (gpGlobals->curtime - m_flLaunchTime > m_flBeamLag)
+ {
+ if (m_nNumHits > 0)
+ {
+ for (int i=0;i<m_nNumHits-1;i++)
+ {
+ m_pHitLocation[i] = m_pHitLocation[i+1];
+ }
+ m_nNumHits--;
+
+ UpdateBeams();
+ }
+ }
+ GetChaserTargetPos(vPosition);
+}
+
+//------------------------------------------------------------------------------
+// Purpose :
+// Input :
+// Output :
+//------------------------------------------------------------------------------
+void CGrenadeBeam::GetChaserTargetPos(Vector *vPosition)
+{
+ // -----------------------------
+ // Launch chaser after a delay
+ // -----------------------------
+ if (gpGlobals->curtime - m_flLaunchTime < m_flBeamLag)
+ {
+ *vPosition = m_vLaunchPos;
+ }
+ else if (m_nNumHits > 0)
+ {
+ *vPosition = m_pHitLocation[0];
+ }
+ else
+ {
+ *vPosition = GetLocalOrigin();
+ }
+}
+
+//------------------------------------------------------------------------------
+// Purpose :
+// Input :
+// Output :
+//------------------------------------------------------------------------------
+void CGrenadeBeam::CreateBeams(void)
+{
+ for ( int i=0; i < GRENADEBEAM_MAXBEAMS; ++i )
+ {
+ m_pBeam[i] = CBeam::BeamCreate( "sprites/laser.vmt", m_flBeamWidth );
+ m_pBeam[i]->SetColor( m_clrRender->r, m_clrRender->g, m_clrRender->b );
+ m_pBeam[i]->EntsInit( this, m_hBeamChaser );
+ m_pBeam[i]->SetBrightness( 255 );
+ m_pBeam[i]->SetNoise( 1 );
+ m_pBeam[i]->SetBeamFlag( FBEAM_SHADEIN );
+ m_pBeam[i]->SetBeamFlag( FBEAM_SHADEOUT );
+ }
+}
+/*
+void CGrenadeBeam::DebugBeams(void)
+{
+ if (m_nNumHits > 0)
+ {
+ NDebugOverlay::Line(GetLocalOrigin(), m_pHitLocation[m_nNumHits-1], 255,255,25, true, 0.1);
+ NDebugOverlay::Line(m_hBeamChaser->GetLocalOrigin(), m_pHitLocation[0], 255,255,25, true, 0.1);
+
+ for (int i=0;i<m_nNumHits-1;i++)
+ {
+ NDebugOverlay::Line(m_pHitLocation[i], m_pHitLocation[i+1], 255,255,25, true, 0.1);
+ }
+ }
+ else
+ {
+ NDebugOverlay::Line(GetLocalOrigin(), m_hBeamChaser->GetLocalOrigin(), 255,255,25, true, 0.1);
+ }
+
+ for (int i=0;i<m_nNumHits;i++)
+ {
+ NDebugOverlay::Cross3D(m_pHitLocation[i], Vector(-8,-8,-8),Vector(8,8,8),0,255,0,true,0.1);
+ }
+}
+*/
+
+//------------------------------------------------------------------------------
+// Purpose :
+// Input :
+// Output :
+//------------------------------------------------------------------------------
+void CGrenadeBeam::UpdateBeams(void)
+{
+ // ------------------------------------------------------------------
+ // If no hits, draw a single beam between the grenade and the chaser
+ // ------------------------------------------------------------------
+ if (m_nNumHits == 0)
+ {
+ m_pBeam[0]->EntsInit( this, m_hBeamChaser );
+ for (int i=1;i<GRENADEBEAM_MAXBEAMS;i++)
+ {
+ m_pBeam[i]->SetBrightness(0);
+ }
+ }
+ // ------------------------------------------------------------------
+ // Otherwise draw beams between hits
+ // ------------------------------------------------------------------
+ else
+ {
+ m_pBeam[0]->PointEntInit( m_pHitLocation[0], m_hBeamChaser );
+
+ for (int i=1;i<GRENADEBEAM_MAXBEAMS-1;i++)
+ {
+ if (i<m_nNumHits)
+ {
+ m_pBeam[i]->PointsInit(m_pHitLocation[i-1],m_pHitLocation[i]);
+ m_pBeam[i]->SetBrightness(255);
+ }
+ else
+ {
+ m_pBeam[i]->SetBrightness(0);
+ }
+ }
+
+ m_pBeam[GRENADEBEAM_MAXBEAMS-1]->PointEntInit( m_pHitLocation[m_nNumHits-1], this );
+ m_pBeam[GRENADEBEAM_MAXBEAMS-1]->SetBrightness(255);
+ }
+}
+
+//------------------------------------------------------------------------------
+// Purpose :
+// Input :
+// Output :
+//------------------------------------------------------------------------------
+void CGrenadeBeam::Precache( void )
+{
+ PrecacheModel("sprites/laser.vmt");
+
+ //UNDONE/HACK: this model is never used but one is needed
+ PrecacheModel("Models/weapons/flare.mdl");
+
+ PrecacheScriptSound( "GrenadeBeam.HitSound" );
+}
+
+//------------------------------------------------------------------------------
+// Purpose : Send even though we don't have a model
+// Input :
+// Output :
+//------------------------------------------------------------------------------
+int CGrenadeBeam::UpdateTransmitState(void)
+{
+ return SetTransmitState( FL_EDICT_PVSCHECK );
+}
+
|