From 39ed87570bdb2f86969d4be821c94b722dc71179 Mon Sep 17 00:00:00 2001 From: Joe Ludwig Date: Wed, 26 Jun 2013 15:22:04 -0700 Subject: First version of the SOurce SDK 2013 --- mp/src/game/server/hl2/grenade_beam.cpp | 443 ++++++++++++++++++++++++++++++++ 1 file changed, 443 insertions(+) create mode 100644 mp/src/game/server/hl2/grenade_beam.cpp (limited to 'mp/src/game/server/hl2/grenade_beam.cpp') 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;icurtime - 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;iRandomInt(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;icurtime - 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;iGetLocalOrigin(), 255,255,25, true, 0.1); + } + + for (int i=0;iEntsInit( this, m_hBeamChaser ); + for (int i=1;iSetBrightness(0); + } + } + // ------------------------------------------------------------------ + // Otherwise draw beams between hits + // ------------------------------------------------------------------ + else + { + m_pBeam[0]->PointEntInit( m_pHitLocation[0], m_hBeamChaser ); + + for (int i=1;iPointsInit(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 ); +} + -- cgit v1.2.3