//=========================================================
// HandleAnimEvent - catches the monster-specific messages
// that occur when tagged animation frames are played.
//=========================================================
void CShambler :: HandleAnimEvent( MonsterEvent_t *pEvent )
{
	switch( pEvent->event )
	{
	case SHAM_IDLE_SOUND:
		if( RANDOM_FLOAT( 0.0f, 1.0f ) > 0.8f )
			EMIT_SOUND( edict(), CHAN_VOICE, "shambler/sidle.wav", 1.0, ATTN_IDLE );
		break;
	case SHAM_LEFT_STEP:
		// dont make sound steps while shambler do melee attack
		if( m_hEnemy == NULL || (m_hEnemy->pev->origin - pev->origin).Length() > 100 )
		{
			EMIT_SOUND( edict(), CHAN_BODY, "shambler/step1.wav", 0.6, ATTN_IDLE );
			UTIL_ScreenShake( pev->origin + Vector( 0, 0, -24 ), 2.0f, 2.0f, 0.5f, 250.0f );
		}
		break;
	case SHAM_RIGHT_STEP:
		if( m_hEnemy == NULL || (m_hEnemy->pev->origin - pev->origin).Length() > 100 )
		{
			EMIT_SOUND( edict(), CHAN_BODY, "shambler/step2.wav", 0.6, ATTN_IDLE );
			UTIL_ScreenShake( pev->origin + Vector( 0, 0, -24 ), 2.0f, 2.0f, 0.5f, 250.0f );
		}
		break;
	case SHAM_CAST_LIGHTNING:
		CastLightning ();
		break;
	case SHAM_BEGIN_CHARGING:
		BeginCharging ();
		break;
	case SHAM_END_CHARGING:
		EndCharging ();
		break;
	case SHAM_SMASH:
		ShamblerSmash ();
		break;
	case SHAM_SMASH_SOUND:
		EMIT_SOUND( edict(), CHAN_VOICE, "shambler/melee1.wav", 1.0, ATTN_NORM );
		break;
	case SHAM_SWING_SOUND:
		EMIT_SOUND( edict(), CHAN_VOICE, "shambler/melee2.wav", 1.0, ATTN_NORM );
		break;
	case SHAM_SWING_LEFT:
		ShamblerClaw( 250 );
		break;
	case SHAM_SWING_RIGHT:
		ShamblerClaw( -250 );
		break;
	default:
		CQuakeMonster::HandleAnimEvent( pEvent );
		break;
	}
}
void CStickyBomb::Detonate()
{
	SetBombOrigin();
	ExplosionCreate( GetAbsOrigin(), GetAbsAngles(), m_hOperator, 100, 250, true );
	UTIL_ScreenShake( GetAbsOrigin(), 25.0, 150.0, 1.0, 250, SHAKE_START );
	UTIL_Remove( this );
}
示例#3
0
void CBaseGrenade::Detonate( void )
{
	trace_t		tr;
	Vector		vecSpot;// trace starts here!

	SetThink( NULL );

	vecSpot = GetAbsOrigin() + Vector ( 0 , 0 , 8 );
	UTIL_TraceLine ( vecSpot, vecSpot + Vector ( 0, 0, -32 ), MASK_SHOT_HULL, this, COLLISION_GROUP_NONE, & tr);

	if( tr.startsolid )
	{
		// Since we blindly moved the explosion origin vertically, we may have inadvertently moved the explosion into a solid,
		// in which case nothing is going to be harmed by the grenade's explosion because all subsequent traces will startsolid.
		// If this is the case, we do the downward trace again from the actual origin of the grenade. (sjb) 3/8/2007  (for ep2_outland_09)
		UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() + Vector( 0, 0, -32), MASK_SHOT_HULL, this, COLLISION_GROUP_NONE, &tr );
	}

	Explode( &tr, DMG_BLAST );

	if ( GetShakeAmplitude() )
	{
		UTIL_ScreenShake( GetAbsOrigin(), GetShakeAmplitude(), 150.0, 1.0, GetShakeRadius(), SHAKE_START );
	}
}
示例#4
0
void CNPC_Gargantua::StompAttack( void )
{
	trace_t trace;

	Vector vecForward;
	AngleVectors(GetAbsAngles(), &vecForward );
	Vector vecStart = GetAbsOrigin() + Vector(0,0,60) + 35 * vecForward;

	CBaseEntity* pPlayer = GetEnemy();
	if ( !pPlayer )
		return;

	Vector vecAim = pPlayer->GetAbsOrigin() - GetAbsOrigin();
	VectorNormalize( vecAim );
	Vector vecEnd = (vecAim * 1024) + vecStart;

	UTIL_TraceLine( vecStart, vecEnd, MASK_SOLID, this, COLLISION_GROUP_NONE, &trace );
//	NDebugOverlay::Line( vecStart, vecEnd, 255, 0, 0, false, 10.0f );

	CStomp::StompCreate( vecStart, trace.endpos, 0, this );
	UTIL_ScreenShake( GetAbsOrigin(), 12.0, 100.0, 2.0, 1000, SHAKE_START );
	CPASAttenuationFilter filter( this );
	EmitSound( filter, entindex(), "Garg.StompSound" );

	UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() - Vector(0,0,20), MASK_SOLID, this, COLLISION_GROUP_NONE, &trace );
	if ( trace.fraction < 1.0 )
	{
		UTIL_DecalTrace( &trace, "SmallScorch" );
	}
}
//------------------------------------------------------------------------------
// Pow!
//------------------------------------------------------------------------------
void CQUAGrenadeHelicopter::DoExplosion( const Vector &vecOrigin, const Vector &vecVelocity )
{
	ExplosionCreate( GetAbsOrigin(), GetAbsAngles(), this, 75.0, 
		275.0, (SF_ENVEXPLOSION_NOSPARKS|SF_ENVEXPLOSION_NODLIGHTS|SF_ENVEXPLOSION_NODECAL|SF_ENVEXPLOSION_NOFIREBALL|SF_ENVEXPLOSION_NOPARTICLES), 
		55000.0 );

	if ( GetShakeAmplitude() )
	{
		UTIL_ScreenShake( GetAbsOrigin(), GetShakeAmplitude(), 150.0, 1.0, GetShakeRadius(), SHAKE_START );
	}

	CEffectData data;

	// If we're under water do a water explosion
	if ( GetWaterLevel() != 0 && (GetWaterType() & CONTENTS_WATER) )
	{
		data.m_vOrigin = WorldSpaceCenter();
		data.m_flMagnitude = 128;
		data.m_flScale = 128;
		data.m_fFlags = 0;
		DispatchEffect( "WaterSurfaceExplosion", data );
	}
	else
	{
		// Otherwise do a normal explosion
		data.m_vOrigin = GetAbsOrigin();
		DispatchEffect( "HelicopterMegaBomb", data );
	}

	UTIL_Remove( this );
}
示例#6
0
void CPropThumper::Thump ( void )
{
    if ( m_iHammerAttachment != -1 )
    {
        Vector vOrigin;
        GetAttachment( m_iHammerAttachment, vOrigin );

        CEffectData	data;

        data.m_nEntIndex = entindex();
        data.m_vOrigin = vOrigin;
        data.m_flScale = m_iDustScale * m_flPlaybackRate;
        DispatchEffect( "ThumperDust", data );
        UTIL_ScreenShake( vOrigin, 10.0 * m_flPlaybackRate, m_flPlaybackRate, m_flPlaybackRate / 2, THUMPER_RADIUS * m_flPlaybackRate, SHAKE_START, false );
    }

    EmitSound( "coast.thumper_dust" );
    CSoundEnt::InsertSound ( SOUND_THUMPER, GetAbsOrigin(), THUMPER_RADIUS * m_flPlaybackRate, THUMPER_SOUND_DURATION, this );

    if ( m_flPlaybackRate < 0.7f )
        return;

    if( m_iDustScale == THUMPER_MIN_SCALE )
        EmitSound( "coast.thumper_hit" );
    else
        EmitSound( "coast.thumper_large_hit" );

}
void QUA_helicopter::Event_Killed( const CTakeDamageInfo &info )
{
	//m_lifeState=LIFE_DYING;

	// Calculate death force
	m_vecTotalBulletForce = CalcDamageForceVector( info );

	CBasePlayer *pPlayer = m_hPlayer;
	if ( pPlayer )
		 {
		pPlayer->LeaveVehicle(); // Force exit vehicle
		CBaseEntity *pAPC=this->GetBaseEntity();
		CTakeDamageInfo playerinfo;
			if (info.GetAttacker()==pAPC && info.GetInflictor()==pAPC) {
				playerinfo.SetAttacker(pPlayer);
				playerinfo.SetInflictor(pPlayer);
				playerinfo.SetDamage(10000);
				playerinfo.SetDamageType(DMG_BLAST);
			} else {
				playerinfo.SetAttacker(info.GetAttacker());
				playerinfo.SetInflictor(info.GetInflictor());
				playerinfo.SetDamage(10000);
				playerinfo.SetDamageType(DMG_BLAST);
			}
		playerinfo.SetDamagePosition( pPlayer->WorldSpaceCenter() );
		playerinfo.SetDamageForce( Vector(0,0,-1) );
		pPlayer->TakeDamage( playerinfo );
		m_hPlayer = NULL;
		 }
	m_OnDeath.FireOutput( info.GetAttacker(), this );
	//StopSmoking();
	Vector vecAbsMins, vecAbsMaxs;
	CollisionProp()->WorldSpaceAABB( &vecAbsMins, &vecAbsMaxs );

	Vector vecNormalizedMins, vecNormalizedMaxs;
	CollisionProp()->WorldToNormalizedSpace( vecAbsMins, &vecNormalizedMins );
	CollisionProp()->WorldToNormalizedSpace( vecAbsMaxs, &vecNormalizedMaxs );

	Vector vecAbsPoint;
	CPASFilter filter( GetAbsOrigin() );
	for (int i = 0; i < 5; i++)
	{
		CollisionProp()->RandomPointInBounds( vecNormalizedMins, vecNormalizedMaxs, &vecAbsPoint );
		te->Explosion( filter, random->RandomFloat( 0.0, 1.0 ),	&vecAbsPoint, 
			g_sModelIndexFireball, random->RandomInt( 4, 10 ), 
			random->RandomInt( 8, 15 ), 
			( i < 2 ) ? TE_EXPLFLAG_NODLIGHTS : TE_EXPLFLAG_NOPARTICLES | TE_EXPLFLAG_NOFIREBALLSMOKE | TE_EXPLFLAG_NODLIGHTS,
			100, 0 );
	}
	// Aqui destruiremos todo
	StopLoopingSounds();
	BecomeRagdoll( info, m_vecTotalBulletForce );
	UTIL_ScreenShake( vecAbsPoint, 25.0, 150.0, 1.0, 750.0f, SHAKE_START );

	CreateCorpse();
	
	//BecomeRagdoll( info, m_vecTotalBulletForce );
    //BecomeRagdollOnClient(m_vecTotalBulletForce);
	//Dissolve(NULL, gpGlobals->curtime, false, ENTITY_DISSOLVE_NORMAL);
}
示例#8
0
//-----------------------------------------------------------------------------
// Creates the explosion effect
//-----------------------------------------------------------------------------
void CEnvHeadcrabCanister::Detonate( )
{
	// Send the impact output
	m_OnImpacted.FireOutput( this, this, 0 );

	if ( !HasSpawnFlags( SF_NO_IMPACT_SOUND ) )
	{
		StopSound( "HeadcrabCanister.IncomingSound" );
		EmitSound( "HeadcrabCanister.Explosion" );
	}

	// If we're supposed to be removed, do that now
	if ( HasSpawnFlags( SF_REMOVE_ON_IMPACT ) )
	{
		SetAbsOrigin( m_vecImpactPosition );
		SetModel( ENV_HEADCRABCANISTER_BROKEN_MODEL );
		SetMoveType( MOVETYPE_NONE );
		IncrementInterpolationFrame();
		m_bLanded = true;
		
		// Become invisible so our trail can finish up
		AddEffects( EF_NODRAW );
		SetSolidFlags( FSOLID_NOT_SOLID );

		SetThink( &CEnvHeadcrabCanister::SUB_Remove );
		SetNextThink( gpGlobals->curtime + ENV_HEADCRABCANISTER_TRAIL_TIME );

		return;
	}

	// Test for damaging things
	TestForCollisionsAgainstWorld( m_vecImpactPosition );

	// Shake the screen unless flagged otherwise
	if ( !HasSpawnFlags( SF_NO_SHAKE ) )
	{
		CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());

		// If the player is on foot, then do a more limited shake
		float shakeRadius = ( pPlayer && pPlayer->IsInAVehicle() ) ? sk_env_headcrabcanister_shake_radius_vehicle.GetFloat() : sk_env_headcrabcanister_shake_radius.GetFloat();

		UTIL_ScreenShake( m_vecImpactPosition, sk_env_headcrabcanister_shake_amplitude.GetFloat(), 150.0, 1.0, shakeRadius, SHAKE_START );
	}

	// Do explosion effects
	if ( !HasSpawnFlags( SF_NO_IMPACT_EFFECTS ) )
	{
		// Normal explosion
		ExplosionCreate( m_vecImpactPosition, GetAbsAngles(), this, 50.0f, 500.0f, 
			SF_ENVEXPLOSION_NODLIGHTS | SF_ENVEXPLOSION_NOSPARKS | SF_ENVEXPLOSION_NODAMAGE | SF_ENVEXPLOSION_NOSOUND, 1300.0f );
			
		// Dust explosion
		AR2Explosion *pExplosion = AR2Explosion::CreateAR2Explosion( m_vecImpactPosition );
		
		if( pExplosion )
		{
			pExplosion->SetLifetime(10);
		}
	}
}
示例#9
0
/* <f69e5> ../cstrike/dlls/mortar.cpp:226 */
void CMortar::MortarExplode(void)
{
	// mortar beam
	MESSAGE_BEGIN(MSG_BROADCAST, SVC_TEMPENTITY);
		WRITE_BYTE(TE_BEAMPOINTS);
		WRITE_COORD(pev->origin.x);
		WRITE_COORD(pev->origin.y);
		WRITE_COORD(pev->origin.z);
		WRITE_COORD(pev->origin.x);
		WRITE_COORD(pev->origin.y);
		WRITE_COORD(pev->origin.z + 1024);
		WRITE_SHORT(m_spriteTexture);
		WRITE_BYTE(0); // framerate
		WRITE_BYTE(0); // framerate
		WRITE_BYTE(1); // life
		WRITE_BYTE(40); // width
		WRITE_BYTE(0); // noise
		WRITE_BYTE(255); // r, g, b
		WRITE_BYTE(160); // r, g, b
		WRITE_BYTE(100); // r, g, b
		WRITE_BYTE(128); // brightness
		WRITE_BYTE(0); // speed
	MESSAGE_END();

	TraceResult tr;
	UTIL_TraceLine(pev->origin + Vector(0, 0, 1024), pev->origin - Vector(0, 0, 1024), dont_ignore_monsters, ENT(pev), &tr);

	Explode(&tr, (DMG_BLAST | DMG_MORTAR));
	UTIL_ScreenShake(tr.vecEndPos, 25.0, 150.0, 1.0, 750);
}
示例#10
0
//------------------------------------------------------------------------------
// Purpose: Console command to cause a screen shake.
//------------------------------------------------------------------------------
void CC_Shake( void )
{
	CBasePlayer *pPlayer = UTIL_GetCommandClient();
	if (pPlayer)
	{
		UTIL_ScreenShake( pPlayer->WorldSpaceCenter(), 25.0, 150.0, 1.0, 750, SHAKE_START );
	}
}
示例#11
0
void CSDKPlayer::OnDamagedByExplosion( const CTakeDamageInfo &info )
{
	if ( info.GetInflictor() && info.GetInflictor()->ClassMatches( "mortarshell" ) )
	{
		// No ear ringing for mortar
		UTIL_ScreenShake( info.GetInflictor()->GetAbsOrigin(), 4.0, 1.0, 0.5, 1000, SHAKE_START, false );
		return;
	}
	BaseClass::OnDamagedByExplosion( info );
}
示例#12
0
//-----------------------------------------------------------------------------
// Add a smoke trail since we've taken more damage
//-----------------------------------------------------------------------------
void CPropAPC::AddSmokeTrail( const Vector &vecPos )
{
	// Start this trail out with a bang!
	ExplosionCreate( vecPos, vec3_angle, this, 1000, 500, SF_ENVEXPLOSION_NODAMAGE | 
		SF_ENVEXPLOSION_NOSPARKS | SF_ENVEXPLOSION_NODLIGHTS | SF_ENVEXPLOSION_NOSMOKE | 
		SF_ENVEXPLOSION_NOFIREBALLSMOKE, 0 );
	UTIL_ScreenShake( vecPos, 25.0, 150.0, 1.0, 750.0f, SHAKE_START );

	if ( m_nSmokeTrailCount == MAX_SMOKE_TRAILS )
		return;

	SmokeTrail *pSmokeTrail =  SmokeTrail::CreateSmokeTrail();
	if( !pSmokeTrail )
		return;

	// See if there's an attachment for this smoke trail
	char buf[32];
	Q_snprintf( buf, 32, "damage%d", m_nSmokeTrailCount );
	int nAttachment = LookupAttachment( buf );

	++m_nSmokeTrailCount;

	pSmokeTrail->m_SpawnRate = 4;
	pSmokeTrail->m_ParticleLifetime = 5.0f;
	pSmokeTrail->m_StartColor.Init( 0.7f, 0.7f, 0.7f );
	pSmokeTrail->m_EndColor.Init( 0.6, 0.6, 0.6 );
	pSmokeTrail->m_StartSize = 32;
	pSmokeTrail->m_EndSize = 64;
	pSmokeTrail->m_SpawnRadius = 4;
	pSmokeTrail->m_Opacity = 0.5f;
	pSmokeTrail->m_MinSpeed = 16;
	pSmokeTrail->m_MaxSpeed = 16;
	pSmokeTrail->m_MinDirectedSpeed	= 16.0f;
	pSmokeTrail->m_MaxDirectedSpeed	= 16.0f;
	pSmokeTrail->SetLifetime( 5 );
	pSmokeTrail->SetParent( this, nAttachment );

	Vector vecForward( 0, 0, 1 );
	QAngle angles;
	VectorAngles( vecForward, angles );

	if ( nAttachment == 0 )
	{
		pSmokeTrail->SetAbsOrigin( vecPos );
		pSmokeTrail->SetAbsAngles( angles );
	}
	else
	{
		pSmokeTrail->SetLocalOrigin( vec3_origin );
		pSmokeTrail->SetLocalAngles( angles );
	}

	pSmokeTrail->SetMoveType( MOVETYPE_NONE );
}
示例#13
0
void CTripmineGrenade::DelayDeathThink( void )
{
	KillBeam();
	trace_t tr;
	UTIL_TraceLine ( GetAbsOrigin() + m_vecDir * 8, GetAbsOrigin() - m_vecDir * 64,  MASK_SOLID, this, COLLISION_GROUP_NONE, & tr);
	UTIL_ScreenShake( GetAbsOrigin(), 25.0, 150.0, 1.0, 750, SHAKE_START );

	ExplosionCreate( GetAbsOrigin() + m_vecDir * 8, GetAbsAngles(), m_hOwner, GetDamage(), 200, 
		SF_ENVEXPLOSION_NOSPARKS | SF_ENVEXPLOSION_NODLIGHTS | SF_ENVEXPLOSION_NOSMOKE, 0.0f, this);

	UTIL_Remove( this );
}
//------------------------------------------------------------------------------
// Pow!
//------------------------------------------------------------------------------
void CPropAPC2::ExplodeAndThrowChunk( const Vector &vecExplosionPos )
{
	ExplosionCreate( vecExplosionPos, vec3_angle, this, 1000, 500.0f, 
		SF_ENVEXPLOSION_NODAMAGE | SF_ENVEXPLOSION_NOSPARKS | SF_ENVEXPLOSION_NODLIGHTS	|
		SF_ENVEXPLOSION_NOSMOKE  | SF_ENVEXPLOSION_NOFIREBALLSMOKE, 0 );
	UTIL_ScreenShake( vecExplosionPos, 25.0, 150.0, 1.0, 750.0f, SHAKE_START );

	// Drop a flaming, smoking chunk.
	CGib *pChunk = CREATE_ENTITY( CGib, "gib" );
	pChunk->Spawn( "models/gibs/hgibs.mdl" );
	pChunk->SetBloodColor( DONT_BLEED );

	QAngle vecSpawnAngles;
	vecSpawnAngles.Random( -90, 90 );
	pChunk->SetAbsOrigin( vecExplosionPos );
	pChunk->SetAbsAngles( vecSpawnAngles );

	int nGib = random->RandomInt( 0, APC_MAX_CHUNKS - 1 );
	pChunk->Spawn( s_pChunkModelName[nGib] );
	pChunk->SetOwnerEntity( this );
	pChunk->m_lifeTime = random->RandomFloat( 6.0f, 8.0f );
	pChunk->SetCollisionGroup( COLLISION_GROUP_DEBRIS );
	IPhysicsObject *pPhysicsObject = pChunk->VPhysicsInitNormal( SOLID_VPHYSICS, pChunk->GetSolidFlags(), false );
	
	// Set the velocity
	if ( pPhysicsObject )
	{
		pPhysicsObject->EnableMotion( true );
		Vector vecVelocity;

		QAngle angles;
		angles.x = random->RandomFloat( -40, 0 );
		angles.y = random->RandomFloat( 0, 360 );
		angles.z = 0.0f;
		AngleVectors( angles, &vecVelocity );
		
		vecVelocity *= random->RandomFloat( 300, 900 );
		vecVelocity += GetAbsVelocity();

		AngularImpulse angImpulse;
		angImpulse = RandomAngularImpulse( -180, 180 );

		pChunk->SetAbsVelocity( vecVelocity );
		pPhysicsObject->SetVelocity(&vecVelocity, &angImpulse );
		}

	CEntityFlame *pFlame = CEntityFlame::Create( pChunk, false );
	if ( pFlame != NULL )
	{
		pFlame->SetLifetime( pChunk->m_lifeTime );
	}
	pChunk->Dissolve( NULL, gpGlobals->curtime, false, ENTITY_DISSOLVE_NORMAL );
}
示例#15
0
void CNPC_Gargantua::HandleAnimEvent( animevent_t *pEvent )
{
	CPASAttenuationFilter filter( this );

	switch( pEvent->event )
	{
	case GARG_AE_SLASH_LEFT:
		{
			// HACKHACK!!!
			CBaseEntity *pHurt = GargantuaCheckTraceHullAttack( GARG_ATTACKDIST + 10.0, sk_gargantua_dmg_slash.GetFloat(), DMG_SLASH );

			if (pHurt)
			{
				if ( pHurt->GetFlags() & ( FL_NPC | FL_CLIENT ) )
				{
					pHurt->ViewPunch( QAngle( -30, -30, 30 ) );

					Vector vRight;
					AngleVectors( GetAbsAngles(), NULL, &vRight, NULL );
					pHurt->SetAbsVelocity( pHurt->GetAbsVelocity() - vRight * 100 );
				}

				EmitSound( filter, entindex(), "Garg.AttackHit" );
			}
			else // Play a random attack miss sound
			{
				EmitSound( filter, entindex(),"Garg.AttackMiss" );
			}
		}
		break;

	case GARG_AE_RIGHT_FOOT:
	case GARG_AE_LEFT_FOOT:

		UTIL_ScreenShake( GetAbsOrigin(), 4.0, 3.0, 1.0, 1500, SHAKE_START );
		EmitSound( filter, entindex(), "Garg.Footstep" );
		break;

	case GARG_AE_STOMP:
		StompAttack();
		m_seeTime = gpGlobals->curtime + 12;
		break;

	case GARG_AE_BREATHE:
		EmitSound( filter, entindex(), "Garg.Breath" );
		break;

	default:
		BaseClass::HandleAnimEvent(pEvent);
		break;
	}
}
示例#16
0
void CGrenadeAR2::Detonate(void)
{
	if (!m_bIsLive)
	{
		return;
	}
	m_bIsLive		= false;
	m_takedamage	= DAMAGE_NO;	

	if(m_hSmokeTrail)
	{
		UTIL_Remove(m_hSmokeTrail);
		m_hSmokeTrail = NULL;
	}

	CPASFilter filter( GetAbsOrigin() );

	te->Explosion( filter, 0.0,
		&GetAbsOrigin(), 
		g_sModelIndexFireball,
		2.0, 
		15,
		TE_EXPLFLAG_NONE,
		m_DmgRadius,
		m_flDamage );

	Vector vecForward = GetAbsVelocity();
	VectorNormalize(vecForward);
	trace_t		tr;
	UTIL_TraceLine ( GetAbsOrigin(), GetAbsOrigin() + 60*vecForward, MASK_SHOT, 
		this, COLLISION_GROUP_NONE, &tr);


	if ((tr.m_pEnt != GetWorldEntity()) || (tr.hitbox != 0))
	{
		// non-world needs smaller decals
		if( tr.m_pEnt && !tr.m_pEnt->IsNPC() )
		{
			UTIL_DecalTrace( &tr, "SmallScorch" );
		}
	}
	else
	{
		UTIL_DecalTrace( &tr, "Scorch" );
	}

	UTIL_ScreenShake( GetAbsOrigin(), 25.0, 150.0, 1.0, 750, SHAKE_START );

	RadiusDamage ( CTakeDamageInfo( this, GetThrower(), m_flDamage, DMG_BLAST ), GetAbsOrigin(), m_DmgRadius, CLASS_NONE, NULL );

	UTIL_Remove( this );
}
示例#17
0
void CGargantua::HandleAnimEvent(AnimEvent_t& event)
{
	switch( event.event )
	{
	case GARG_AE_SLASH_LEFT:
		{
			// HACKHACK!!!
			CBaseEntity *pHurt = GargantuaCheckTraceHullAttack( GARG_ATTACKDIST + 10.0, gSkillData.GetGargantuaDmgSlash(), DMG_SLASH );
			if (pHurt)
			{
				if ( pHurt->GetFlags().Any( FL_MONSTER | FL_CLIENT ) )
				{
					pHurt->SetPunchAngle( Vector(
						-30, // pitch
						-30, // yaw
						30 //roll
					) );
					//UTIL_MakeVectors( GetAbsAngles() );	// called by CheckTraceHullAttack
					pHurt->SetAbsVelocity( pHurt->GetAbsVelocity() - gpGlobals->v_right * 100 );
				}
				EMIT_SOUND_DYN ( this, CHAN_WEAPON, pAttackHitSounds[ RANDOM_LONG(0,ARRAYSIZE(pAttackHitSounds)-1) ], 1.0, ATTN_NORM, 0, 50 + RANDOM_LONG(0,15) );
			}
			else // Play a random attack miss sound
				EMIT_SOUND_DYN ( this, CHAN_WEAPON, pAttackMissSounds[ RANDOM_LONG(0,ARRAYSIZE(pAttackMissSounds)-1) ], 1.0, ATTN_NORM, 0, 50 + RANDOM_LONG(0,15) );

			Vector forward;
			UTIL_MakeVectorsPrivate( GetAbsAngles(), &forward, nullptr, nullptr );
		}
		break;

	case GARG_AE_RIGHT_FOOT:
	case GARG_AE_LEFT_FOOT:
		UTIL_ScreenShake( GetAbsOrigin(), 4.0, 3.0, 1.0, 750 );
		EMIT_SOUND_DYN ( this, CHAN_BODY, pFootSounds[ RANDOM_LONG(0,ARRAYSIZE(pFootSounds)-1) ], 1.0, ATTN_GARG, 0, PITCH_NORM + RANDOM_LONG(-10,10) );
		break;

	case GARG_AE_STOMP:
		StompAttack();
		m_seeTime = gpGlobals->time + 12;
		break;

	case GARG_AE_BREATHE:
		EMIT_SOUND_DYN ( this, CHAN_VOICE, pBreatheSounds[ RANDOM_LONG(0,ARRAYSIZE(pBreatheSounds)-1) ], 1.0, ATTN_GARG, 0, PITCH_NORM + RANDOM_LONG(-10,10) );
		break;

	default:
		CBaseMonster::HandleAnimEvent( event );
		break;
	}
}
void CNPC_Gargantua::HandleAnimEvent( animevent_t *pEvent )
{
	CPASAttenuationFilter filter( this );

	switch( pEvent->event )
	{
	case GARG_AE_SLASH_LEFT:
		{
			// HACKHACK!!!
			CBaseEntity *pHurt = GargantuaCheckTraceHullAttack( GARG_ATTACKDIST + 10.0, sk_gargantua_dmg_slash.GetFloat(), DMG_SLASH );

			if (pHurt)
			{
				if ( pHurt->GetFlags() & ( FL_NPC | FL_CLIENT ) )
				{
					pHurt->ViewPunch( QAngle( -30, -30, 30 ) );

					Vector vRight;
					AngleVectors( GetAbsAngles(), NULL, &vRight, NULL );
					pHurt->SetAbsVelocity( pHurt->GetAbsVelocity() - vRight * 100 );
				}

				enginesound->EmitSound( filter, entindex(), CHAN_WEAPON, pAttackHitSounds[ random->RandomInt(0,ARRAYSIZE(pAttackHitSounds)-1) ], 1.0, ATTN_NORM, 0, 50 + random->RandomInt(0,15) );
			}
			else // Play a random attack miss sound
				enginesound->EmitSound( filter, entindex(), CHAN_WEAPON, pAttackMissSounds[ random->RandomInt(0,ARRAYSIZE(pAttackMissSounds)-1) ], 1.0, ATTN_NORM, 0, 50 + random->RandomInt(0,15) );
		}
		break;

	case GARG_AE_RIGHT_FOOT:
	case GARG_AE_LEFT_FOOT:

		UTIL_ScreenShake( GetAbsOrigin(), 4.0, 3.0, 1.0, 1500, SHAKE_START );
		enginesound->EmitSound( filter, entindex(), CHAN_BODY, pFootSounds[ random->RandomInt(0,ARRAYSIZE(pFootSounds)-1) ], 1.0, ATTN_GARG, 0, PITCH_NORM + random->RandomInt(-10,10) );
		break;

	case GARG_AE_STOMP:
		StompAttack();
		m_seeTime = gpGlobals->curtime + 12;
		break;

	case GARG_AE_BREATHE:
		enginesound->EmitSound( filter, entindex(), CHAN_VOICE, pBreatheSounds[ random->RandomInt(0,ARRAYSIZE(pBreatheSounds)-1) ], 1.0, ATTN_GARG, 0, PITCH_NORM + random->RandomInt(-10,10) );
		break;

	default:
		BaseClass::HandleAnimEvent(pEvent);
		break;
	}
}
示例#19
0
//=========================================================
// HandleAnimEvent - catches the monster-specific messages
// that occur when tagged animation frames are played.
//=========================================================
void CMGargantua::HandleAnimEvent(MonsterEvent_t *pEvent)
{
	switch( pEvent->event )
	{
	case GARG_AE_SLASH_LEFT:
		{
			// HACKHACK!!!
			
			edict_t *pHurt = GargantuaCheckTraceHullAttack( GARG_ATTACKDIST + 10.0, gSkillData.gargantuaDmgSlash, DMG_SLASH );
			if (pHurt)
			{
				if ( pHurt->v.flags & (FL_MONSTER|FL_CLIENT) )
				{
					pHurt->v.punchangle.x = -30; // pitch
					pHurt->v.punchangle.y = -30;	// yaw
					pHurt->v.punchangle.z = 30;	// roll
					//UTIL_MakeVectors(pev->angles);	// called by CheckTraceHullAttack
					pHurt->v.velocity = pHurt->v.velocity - gpGlobals->v_right * 100;
				}
				EMIT_SOUND_DYN ( edict(), CHAN_WEAPON, pAttackHitSounds[ RANDOM_LONG(0,ARRAYSIZE(pAttackHitSounds)-1) ], 1.0, ATTN_NORM, 0, 50 + RANDOM_LONG(0,15) );
			}
			else // Play a random attack miss sound
				EMIT_SOUND_DYN ( edict(), CHAN_WEAPON, pAttackMissSounds[ RANDOM_LONG(0,ARRAYSIZE(pAttackMissSounds)-1) ], 1.0, ATTN_NORM, 0, 50 + RANDOM_LONG(0,15) );

			Vector forward;
			UTIL_MakeVectorsPrivate( pev->angles, forward, NULL, NULL );
		}
		break;

	case GARG_AE_RIGHT_FOOT:
	case GARG_AE_LEFT_FOOT:
		UTIL_ScreenShake( pev->origin, 4.0, 3.0, 1.0, 750 );
		EMIT_SOUND_DYN ( edict(), CHAN_BODY, pFootSounds[ RANDOM_LONG(0,ARRAYSIZE(pFootSounds)-1) ], 1.0, ATTN_GARG, 0, PITCH_NORM + RANDOM_LONG(-10,10) );
		break;

	case GARG_AE_STOMP:
		StompAttack();
		m_seeTime = gpGlobals->time + 12;
		break;

	case GARG_AE_BREATHE:
		EMIT_SOUND_DYN ( edict(), CHAN_VOICE, pBreatheSounds[ RANDOM_LONG(0,ARRAYSIZE(pBreatheSounds)-1) ], 1.0, ATTN_GARG, 0, PITCH_NORM + RANDOM_LONG(-10,10) );
		break;

	default:
		CMBaseMonster::HandleAnimEvent(pEvent);
		break;
	}
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CPlayer_Missile::BlowUp(void)
{
	// Don't take damage any more
	m_takedamage	= DAMAGE_NO;

	// Mark as dead so won't be attacked
	m_lifeState = LIFE_DEAD;

	// Stop fly and launch sounds
	StopSound( "Player_Manhack.Fly" );
	StopSound( "Player_Manhack.Fire" );

	CPASFilter filter( GetAbsOrigin() );
	te->Explosion( filter, 0.0,
		&GetAbsOrigin(), 
		g_sModelIndexFireball,
		2.0, 
		15,
		TE_EXPLFLAG_NONE,
		m_flDamageRadius,
		m_flDamage );

	Vector vecForward = GetAbsVelocity();
	VectorNormalize(vecForward);
	trace_t		tr;
	UTIL_TraceLine ( GetAbsOrigin(), GetAbsOrigin() + 60*vecForward,  MASK_SOLID_BRUSHONLY, 
		this, COLLISION_GROUP_NONE, &tr);

	UTIL_DecalTrace( &tr, "Scorch" );

	UTIL_ScreenShake( GetAbsOrigin(), 25.0, 150.0, 1.0, 750, SHAKE_START );
	CSoundEnt::InsertSound ( SOUND_DANGER, GetAbsOrigin(), 1024, 3.0 );

	RadiusDamage ( CTakeDamageInfo( this, this, m_flDamage, DMG_BLAST ), GetAbsOrigin(), m_flDamageRadius, CLASS_NONE );

	SetThink(ExplodeThink);
	SetTouch(NULL);
	m_vBounceVel	= -0.2 * GetAbsVelocity();
	AddSolidFlags( FSOLID_NOT_SOLID );
	Relink();

	// Stop emitting smoke
	if(m_hSmokeTrail)
	{
		((SmokeTrail*)(CBaseEntity*)m_hSmokeTrail)->SetEmit(false);
	}
}
示例#21
0
void CBaseGrenade::Detonate( void )
{
	trace_t		tr;
	Vector		vecSpot;// trace starts here!

	SetThink( NULL );

	vecSpot = GetAbsOrigin() + Vector ( 0 , 0 , 8 );
	UTIL_TraceLine ( vecSpot, vecSpot + Vector ( 0, 0, -32 ), MASK_SHOT_HULL, this, COLLISION_GROUP_NONE, & tr);

	Explode( &tr, DMG_BLAST );

	if ( GetShakeAmplitude() )
	{
		UTIL_ScreenShake( GetAbsOrigin(), GetShakeAmplitude(), 150.0, 1.0, GetShakeRadius(), SHAKE_START );
	}
}
示例#22
0
void CMGargantua::StompAttack( void )
{
	TraceResult trace;

	UTIL_MakeVectors( pev->angles );
	Vector vecStart = pev->origin + Vector(0,0,60) + 35 * gpGlobals->v_forward;
	Vector vecAim = ShootAtEnemy( vecStart );
	Vector vecEnd = (vecAim * 1024) + vecStart;

	UTIL_TraceLine( vecStart, vecEnd, ignore_monsters, edict(), &trace );
	CStomp::StompCreate( vecStart, trace.vecEndPos, 0 );
	UTIL_ScreenShake( pev->origin, 12.0, 100.0, 2.0, 1000 );
	EMIT_SOUND_DYN ( edict(), CHAN_WEAPON, pStompSounds[ RANDOM_LONG(0,ARRAYSIZE(pStompSounds)-1) ], 1.0, ATTN_GARG, 0, PITCH_NORM + RANDOM_LONG(-10,10) );

	UTIL_TraceLine( pev->origin, pev->origin - Vector(0,0,20), ignore_monsters, edict(), &trace );
	if ( trace.flFraction < 1.0 )
		UTIL_DecalTrace( &trace, DECAL_GARGSTOMP1 );
}
void CWalkerMiniStrider::UpdateLargeGun()
{
	float dt = GetTimeDelta();

	if ( !m_bFiringLargeGun )
		return;

	m_flLargeGunCountdown -= dt;
	if ( m_flLargeGunCountdown <= 0 )
	{
		// Fire!
		Vector vSrc = GetLargeGunShootOrigin();
		trace_t trace;
		UTIL_TraceLine( vSrc, vSrc + m_vLargeGunForward * 2000, MASK_SOLID, this, COLLISION_GROUP_NONE, &trace );
		if ( trace.fraction < 1 )
		{
			CBasePlayer *pDriver = GetPassenger( VEHICLE_DRIVER );
			if ( pDriver )
			{
				UTIL_ImpactTrace( &trace, DMG_ENERGYBEAM, "Strider" );

				Vector vHitPos = trace.endpos;
				float flDamageRadius = 100;
				float flDamage = 100;

				CPASFilter filter( vHitPos );
				te->Explosion( filter, 0.0,
					&vHitPos, 
					g_sModelIndexFireball,
					2.0, 
					15,
					TE_EXPLFLAG_NONE,
					flDamageRadius,
					flDamage );

				UTIL_ScreenShake( vHitPos, 10.0, 150.0, 1.0, 100, SHAKE_START );
				RadiusDamage( CTakeDamageInfo( this, pDriver, flDamage, DMG_BLAST ), vHitPos, flDamageRadius, CLASS_NONE );
			}
		}

		StopFiringLargeGun();
	}
}
示例#24
0
void CNPC_Gargantua::DeathEffect( void )
{
	int i;

	Vector vForward;
	AngleVectors( GetAbsAngles(), &vForward );
	Vector deathPos = GetAbsOrigin() + vForward * 100;

	Vector position = GetAbsOrigin();
	position.z += 32;

	CPASFilter filter( GetAbsOrigin() );
	for ( i = 0; i < 7; i++)
	{
		te->Explosion( filter, i * 0.2,	&GetAbsOrigin(), g_sModelIndexFireball,	10, 15, TE_EXPLFLAG_NONE, 100, 0 );
		position.z += 15;
	}

	UTIL_Smoke(GetAbsOrigin(),random->RandomInt(10, 15), 10);
	UTIL_ScreenShake( GetAbsOrigin(), 25.0, 100.0, 5.0, 1000, SHAKE_START );

}
//------------------------------------------------------------------------------
// Purpose :
// Input   :
// Output  :
//------------------------------------------------------------------------------
void CGrenadePathfollower::Detonate(void)
{
	StopSound(entindex(), CHAN_BODY, STRING(m_sFlySound));

	m_takedamage	= DAMAGE_NO;	

	if(m_hRocketTrail)
	{
		UTIL_Remove(m_hRocketTrail);
		m_hRocketTrail = NULL;
	}

	CPASFilter filter( GetAbsOrigin() );

	te->Explosion( filter, 0.0,
		&GetAbsOrigin(), 
		g_sModelIndexFireball,
		0.5, 
		15,
		TE_EXPLFLAG_NONE,
		m_DmgRadius,
		m_flDamage );

	Vector vecForward = GetAbsVelocity();
	VectorNormalize(vecForward);
	trace_t		tr;
	UTIL_TraceLine ( GetAbsOrigin(), GetAbsOrigin() + 60*vecForward,  MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, & tr);

	UTIL_DecalTrace( &tr, "Scorch" );

	UTIL_ScreenShake( GetAbsOrigin(), 25.0, 150.0, 1.0, 750, SHAKE_START );
	CSoundEnt::InsertSound ( SOUND_DANGER, GetAbsOrigin(), 400, 0.2 );

	RadiusDamage ( CTakeDamageInfo( this, GetThrower(), m_flDamage, DMG_BLAST ), GetAbsOrigin(),  m_DmgRadius, CLASS_NONE, NULL );
	CPASAttenuationFilter filter2( this, "GrenadePathfollower.StopSounds" );
	EmitSound( filter2, entindex(), "GrenadePathfollower.StopSounds" );
	UTIL_Remove( this );
}
示例#26
0
//-----------------------------------------------------------------------------
// Purpose: Create the explosion effect for the final big boom
//-----------------------------------------------------------------------------
void CWeaponStriderBuster::CreateDestroyedEffect( void )
{
	CBaseEntity *pTrail;

	StopParticleEffects( this );
	
	for ( int i = 0; i < 3; i++ )
	{
		pTrail = CreateEntityByName( "sparktrail" );
		pTrail->SetOwnerEntity( this );
		DispatchSpawn( pTrail );
	}
	
	DispatchParticleEffect( "striderbuster_explode_core", GetAbsOrigin(), GetAbsAngles() );

	// Create liquid fountain gushtacular effect here!
	CEffectData	data;

	int nNumSteps = 6;
	float flRadStep = (2*M_PI) / nNumSteps;
	for ( int i = 0; i < nNumSteps; i++ )
	{
		data.m_vOrigin = GetAbsOrigin() + RandomVector( -32.0f, 32.0f );
		data.m_vNormal.x = cos( flRadStep*i );
		data.m_vNormal.y = sin( flRadStep*i );
		data.m_vNormal.z = 0.0f;
		data.m_flScale = ( random->RandomInt( 0, 5 ) == 0 ) ? 1 : 2;

		DispatchEffect( "StriderBlood", data );
	}

	// More effects
	UTIL_ScreenShake( GetAbsOrigin(), 20.0f, 150.0, 1.0, 1250.0f, SHAKE_START );

	data.m_vOrigin = GetAbsOrigin();
	DispatchEffect( "cball_explode", data );
}
示例#27
0
void CPropThumper::Thump ( void )
{
	if ( m_iHammerAttachment != -1 )
	{
		Vector vOrigin;
		GetAttachment( m_iHammerAttachment, vOrigin );

		CEffectData	data;

		data.m_nEntIndex = entindex();
		data.m_vOrigin = vOrigin;
		data.m_flScale = m_iDustScale * m_flPlaybackRate;
		DispatchEffect( "ThumperDust", data );
		UTIL_ScreenShake( vOrigin, 10.0 * m_flPlaybackRate, m_flPlaybackRate, m_flPlaybackRate / 2, THUMPER_RADIUS * m_flPlaybackRate, SHAKE_START, false );
	}

	EmitSound( "coast.thumper_dust" );
	CSoundEnt::InsertSound ( SOUND_THUMPER, GetAbsOrigin(), THUMPER_RADIUS * m_flPlaybackRate, THUMPER_SOUND_DURATION, this );

	if ( thumper_show_radius.GetBool() )
	{
		NDebugOverlay::Box( GetAbsOrigin(), Vector(-THUMPER_RADIUS, -THUMPER_RADIUS, -THUMPER_RADIUS), Vector(THUMPER_RADIUS, THUMPER_RADIUS, THUMPER_RADIUS), 
			255, 64, 64, 255, THUMPER_SOUND_DURATION );
	}

	if ( m_flPlaybackRate < 0.7f )
		 return;

	if( m_iDustScale == THUMPER_MIN_SCALE )
		 EmitSound( "coast.thumper_hit" );
	else
		 EmitSound( "coast.thumper_large_hit" );

	// Signal that we've thumped
	m_OnThumped.FireOutput( this, this );
}
示例#28
0
void CGrenade::Explode2( TraceResult* pTrace, int bitsDamageType )
{
    pev->model		= iStringNull;	// invisible
    pev->solid		= SOLID_NOT;	// intangible
    pev->takedamage = DAMAGE_NO;

    UTIL_ScreenShake( pTrace->vecEndPos, 25.0, 150.0, 1.0, 3000.0 );

    g_pGameRules->m_bTargetBombed = true;

    if( g_pGameRules->IsCareer() )
    {
        // TODO: implements this.
        // TheCareerTasks->LatchRoundEndMessage();
    }

    m_fJustBlew = TRUE;
    g_pGameRules->CheckWinConditions();

    if( pTrace->flFraction != 1.0 )
    {
        pev->origin = pTrace->vecEndPos + ( pTrace->vecPlaneNormal * ( pev->dmg - 24 ) * 0.6 );
    }

    bool isInWater = UTIL_PointContents( pev->origin ) == CONTENTS_WATER;

    MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, pev->origin );
    WRITE_BYTE( TE_SPRITE );
    WRITE_COORD( pev->origin.x );
    WRITE_COORD( pev->origin.y );
    WRITE_COORD( pev->origin.z - 10.0 );
    WRITE_SHORT( g_sModelIndexFireball3 );
    WRITE_BYTE( ( pev->dmg - 275 ) * 0.6 );
    WRITE_BYTE( 150 );
    MESSAGE_END();

    MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, pev->origin );
    WRITE_BYTE( TE_SPRITE );
    WRITE_COORD( pev->origin.x + RANDOM_FLOAT( -512, 512 ) );
    WRITE_COORD( pev->origin.y + RANDOM_FLOAT( -512, 512 ) );
    WRITE_COORD( pev->origin.z + RANDOM_FLOAT( -10, 10 ) );
    WRITE_SHORT( g_sModelIndexFireball2 );
    WRITE_BYTE( ( pev->dmg - 275 ) * 0.6 );
    WRITE_BYTE( 150 );
    MESSAGE_END();

    MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, pev->origin );
    WRITE_BYTE( TE_SPRITE );
    WRITE_COORD( pev->origin.x + RANDOM_FLOAT( -512, 512 ) );
    WRITE_COORD( pev->origin.y + RANDOM_FLOAT( -512, 512 ) );
    WRITE_COORD( pev->origin.z + RANDOM_FLOAT( -10, 10 ) );
    WRITE_SHORT( g_sModelIndexFireball3 );
    WRITE_BYTE( ( pev->dmg - 275 ) * 0.6 );
    WRITE_BYTE( 150 );
    MESSAGE_END();

    MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, pev->origin );
    WRITE_BYTE( TE_SPRITE );
    WRITE_COORD( pev->origin.x + RANDOM_FLOAT( -512, 512 ) );
    WRITE_COORD( pev->origin.y + RANDOM_FLOAT( -512, 512 ) );
    WRITE_COORD( pev->origin.z + RANDOM_FLOAT( -10, 10 ) );
    WRITE_SHORT( g_sModelIndexFireball );
    WRITE_BYTE( ( pev->dmg - 275 ) * 0.6 );
    WRITE_BYTE( 150 );
    MESSAGE_END();

    EMIT_SOUND( ENT( pev ), CHAN_WEAPON, "weapons/c4_explode1.wav", VOL_NORM, 0.25 );

    CSoundEnt::InsertSound( bits_SOUND_COMBAT, pev->origin, NORMAL_EXPLOSION_VOLUME, 3.0 );

    entvars_t *pevOwner;

    if ( pev->owner )
        pevOwner = VARS( pev->owner );
    else
        pevOwner = NULL;

    pev->owner = NULL; // Can't traceline attack owner if this is set.

    // TODO: Fix me.
    //RadiusDamage( pev, pevOwner, pev->dmg, g_pGameRules->m_flBombRadius, CLASS_NONE, bitsDamageType );

    if( g_pGameRules->IsCareer() )
    {
        // TODO: implements this.
        // TheCareerTasks->UnlatchRoundEndMessage();
    }

    MESSAGE_BEGIN( MSG_SPEC, SVC_DIRECTOR );
    WRITE_BYTE( 9 );
    WRITE_BYTE( DRC_CMD_EVENT );
    WRITE_SHORT( ENTINDEX( this->edict() ) );
    WRITE_SHORT( NULL );
    WRITE_ENTITY( DRC_FLAG_FINAL | 15 );
    MESSAGE_END();

    UTIL_DecalTrace( pTrace, RANDOM_FLOAT( 0 , 1 ) < 0.5 ? DECAL_SCORCH1 : DECAL_SCORCH2 );

    switch ( RANDOM_LONG( 0, 2 ) )
    {
    case 0:
        EMIT_SOUND( ENT( pev ), CHAN_VOICE, "weapons/debris1.wav", 0.55, ATTN_NORM );
        break;
    case 1:
        EMIT_SOUND( ENT( pev ), CHAN_VOICE, "weapons/debris2.wav", 0.55, ATTN_NORM );
        break;
    case 2:
        EMIT_SOUND( ENT( pev ), CHAN_VOICE, "weapons/debris3.wav", 0.55, ATTN_NORM );
        break;
    }

    pev->effects |= EF_NODRAW;
    SetThink( &CGrenade::Smoke2 );

    pev->velocity	= g_vecZero;
    pev->nextthink	= gpGlobals->time + 0.85;

    if( !isInWater )
    {
        int sparkCount = RANDOM_LONG( 0, 3 );

        for( int i = 0; i < sparkCount; i++ )
        {
            Create( "spark_shower", pev->origin, pTrace->vecPlaneNormal, NULL );
        }
    }
}
void CEgon::Fire( const Vector &vecOrigSrc, const Vector &vecDir )
{
	Vector vecDest = vecOrigSrc + vecDir * 2048;
	edict_t		*pentIgnore;
	TraceResult tr;

	pentIgnore = m_pPlayer->edict();
	Vector tmpSrc = vecOrigSrc + gpGlobals->v_up * -8 + gpGlobals->v_right * 3;

	// ALERT( at_console, "." );
	
	UTIL_TraceLine( vecOrigSrc, vecDest, dont_ignore_monsters, pentIgnore, &tr );

	if (tr.fAllSolid)
		return;

#ifndef CLIENT_DLL
	CBaseEntity *pEntity = CBaseEntity::Instance(tr.pHit);

	if (pEntity == NULL)
		return;

	if ( g_pGameRules->IsMultiplayer() )
	{
		if ( m_pSprite && pEntity->pev->takedamage )
		{
			m_pSprite->pev->effects &= ~EF_NODRAW;
		}
		else if ( m_pSprite )
		{
			m_pSprite->pev->effects |= EF_NODRAW;
		}
	}


#endif

	float timedist;

	switch ( m_fireMode )
	{
	case FIRE_NARROW:
#ifndef CLIENT_DLL
		if ( pev->dmgtime < gpGlobals->time )
		{
			// Narrow mode only does damage to the entity it hits
			ClearMultiDamage();
			if (pEntity->pev->takedamage)
			{
				pEntity->TraceAttack( m_pPlayer->pev, gSkillData.plrDmgEgonNarrow, vecDir, &tr, DMG_ENERGYBEAM );
			}
			ApplyMultiDamage(m_pPlayer->pev, m_pPlayer->pev);

			if ( g_pGameRules->IsMultiplayer() )
			{
				// multiplayer uses 1 ammo every 1/10th second
				if ( gpGlobals->time >= m_flAmmoUseTime )
				{
					UseAmmo( 1 );
					m_flAmmoUseTime = gpGlobals->time + 0.1;
				}
			}
			else
			{
				// single player, use 3 ammo/second
				if ( gpGlobals->time >= m_flAmmoUseTime )
				{
					UseAmmo( 1 );
					m_flAmmoUseTime = gpGlobals->time + 0.166;
				}
			}

			pev->dmgtime = gpGlobals->time + GetPulseInterval();
		}
#endif
		timedist = ( pev->dmgtime - gpGlobals->time ) / GetPulseInterval();
		break;
	
	case FIRE_WIDE:
#ifndef CLIENT_DLL
		if ( pev->dmgtime < gpGlobals->time )
		{
			// wide mode does damage to the ent, and radius damage
			ClearMultiDamage();
			if (pEntity->pev->takedamage)
			{
				pEntity->TraceAttack( m_pPlayer->pev, gSkillData.plrDmgEgonWide, vecDir, &tr, DMG_ENERGYBEAM | DMG_ALWAYSGIB);
			}
			ApplyMultiDamage(m_pPlayer->pev, m_pPlayer->pev);

			if ( g_pGameRules->IsMultiplayer() )
			{
				// radius damage a little more potent in multiplayer.
				::RadiusDamage( tr.vecEndPos, pev, m_pPlayer->pev, gSkillData.plrDmgEgonWide/4, 128, CLASS_NONE, DMG_ENERGYBEAM | DMG_BLAST | DMG_ALWAYSGIB );
			}

			if ( !m_pPlayer->IsAlive() )
				return;

			if ( g_pGameRules->IsMultiplayer() )
			{
				//multiplayer uses 5 ammo/second
				if ( gpGlobals->time >= m_flAmmoUseTime )
				{
					UseAmmo( 1 );
					m_flAmmoUseTime = gpGlobals->time + 0.2;
				}
			}
			else
			{
				// Wide mode uses 10 charges per second in single player
				if ( gpGlobals->time >= m_flAmmoUseTime )
				{
					UseAmmo( 1 );
					m_flAmmoUseTime = gpGlobals->time + 0.1;
				}
			}

			pev->dmgtime = gpGlobals->time + GetDischargeInterval();
			if ( m_shakeTime < gpGlobals->time )
			{
				UTIL_ScreenShake( tr.vecEndPos, 5.0, 150.0, 0.75, 250.0 );
				m_shakeTime = gpGlobals->time + 1.5;
			}
		}
#endif
		timedist = ( pev->dmgtime - gpGlobals->time ) / GetDischargeInterval();
		break;
	}

	if ( timedist < 0 )
		timedist = 0;
	else if ( timedist > 1 )
		timedist = 1;
	timedist = 1-timedist;

	UpdateEffect( tmpSrc, tr.vecEndPos, timedist );
}
void CPropCannon::LaunchProjectile( void )
{
	//ADRIANTODO: Come back to this once we get the right model and remove all the fix ups caused by temp content.

	Vector vTipPos, vTipForward, vTipRight, vUp;

	GetAttachment( "cable_tip", vTipPos, &vTipForward, &vTipRight, &vUp );

	bool bCollided = false;
	bool bInSky = false;
	float gravity = -gpGlobals->frametime * 600;
	Vector vOrigin = vTipPos;
	Vector vVelocity = vTipRight * 2500;

	float flDistance = 0.0f;

	int iFailSafe = 0;
	
	while ( bCollided == false && iFailSafe < 100000 )
	{
		Vector vOldOrigin = vOrigin;
		vOrigin = vOrigin + vVelocity * gpGlobals->frametime;

		flDistance += (vOrigin - vOldOrigin).Length();

		if ( g_cannon_debug.GetBool() == true )
		{
			NDebugOverlay::Line( vOldOrigin, vOrigin, 0, 255, 0, true, 5 );
		}

		trace_t pm;		
		UTIL_TraceLine( vOldOrigin, vOrigin, MASK_SOLID, this, COLLISION_GROUP_NONE, &pm );

		if ( pm.surface.flags & SURF_SKY || pm.allsolid == true ) 
		{
			bInSky = true;
			iFailSafe++;
		}
		else
		{
			bInSky = false;
		}

		iFailSafe++;

		if ( pm.fraction != 1.0f && bInSky == false )
		{
			bCollided = true;
			vOrigin = pm.endpos;

			if ( g_cannon_debug.GetBool() == true )
			{
				NDebugOverlay::Box( vOrigin, Vector( 256, 256, 256 ), Vector( -256, -256, -256 ), 255, 0, 0, 0, 5 );
			}
		}
		else
		{
			vVelocity[2] += gravity;
		}
	}
	
	float flTravelTime = flDistance / vVelocity.Length();

	if ( flTravelTime > g_cannon_max_traveltime.GetFloat() )
	{
		flTravelTime = g_cannon_max_traveltime.GetFloat();

		if ( bCollided == false )
		{
			vOrigin = vec3_origin; 
		}
	}

	m_flFlyTime = gpGlobals->curtime + flTravelTime;
	m_vCrashPoint = vOrigin;

	m_flNextAttackTime = gpGlobals->curtime + g_cannon_reloadtime.GetFloat();
	
	EmitSound( "HeadcrabCanister.LaunchSound" );

	UTIL_ScreenShake( GetDriver()->GetAbsOrigin(), 50.0, 150.0, 1.0, 750, SHAKE_START, true );
}