예제 #1
0
//BB: we need a new impact decal for claws on walls, etc.
void CWeaponCrowbar::ImpactEffect( trace_t &traceHit )
{
	// See if we hit water (we don't do the other impact effects in this case)
	if ( ImpactWater( traceHit.startpos, traceHit.endpos ) )
		return;

	//FIXME: need new decals
	if (traceHit.m_pEnt->IsPlayer())
	{
		UTIL_ImpactTrace( &traceHit, DMG_BULLET );
	}
	else
	{
		UTIL_ImpactTrace( &traceHit, DMG_SLASH );//DMG_SLASH
	}
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponGauss::DoWallBreak(Vector startPos, Vector endPos, Vector aimDir, trace_t *ptr, CBasePlayer *pOwner, bool m_bBreakAll){
	trace_t *temp = ptr;
	if(m_bBreakAll){
		Vector tempPos = endPos;
		Vector beamStart = startPos;
		int x=0;
		while(DidPunchThrough(ptr)){
			temp = ptr;
			if(x==0){
				UTIL_TraceLine( startPos, tempPos, MASK_SHOT, pOwner, COLLISION_GROUP_NONE, ptr ); 
				x = 1;
			} else{
				UTIL_TraceLine( endPos, startPos, MASK_SHOT, pOwner, COLLISION_GROUP_NONE, ptr );
				x = 0;
			}
			if(ptr->DidHitWorld() && ptr->surface.flags != SURF_SKY){
				UTIL_ImpactTrace( ptr, GetAmmoDef()->DamageType(m_iPrimaryAmmoType), "ImpactGauss" );
				UTIL_DecalTrace( ptr, "RedGlowFade" );
			}
			startPos= ptr->endpos;
			tempPos = ptr->endpos + ( aimDir * MAX_TRACE_LENGTH + aimDir * 128.0f );

		}
		//DrawBeam( beamStart, ptr->startpos, 4.0, false );
	} else{
		UTIL_TraceLine( startPos, endPos, MASK_SHOT, pOwner, COLLISION_GROUP_NONE, ptr ); //Trace from gun to wall
	}

	if(!DidPunchThrough(ptr)){
			ptr = temp;
return;
	}
}
 //-----------------------------------------------------------------------------
// Purpose: Draw the first Carged Beam
//-----------------------------------------------------------------------------
 void CWeaponGauss::ChargedFireFirstBeam( void )
 {
         CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
         
         if ( pOwner == NULL )
                return;

         Vector  startPos= pOwner->Weapon_ShootPosition();
         Vector  aimDir  = pOwner->GetAutoaimVector( AUTOAIM_5DEGREES );
         Vector  endPos  = startPos + ( aimDir * MAX_TRACE_LENGTH );
         
         //Shoot a shot straight out
         trace_t tr;
         UTIL_TraceLine( startPos, endPos, MASK_SHOT, pOwner, COLLISION_GROUP_NONE, &tr );
         startPos = tr.endpos;

                         
         //Draw beam
         DrawBeam( tr.startpos, tr.endpos, 9.6, true );
 
         CPVSFilter filter( tr.endpos );
         te->GaussExplosion( filter, 0.0f, tr.endpos, tr.plane.normal, 0 );
 
         UTIL_ImpactTrace( &tr, GetAmmoDef()->DamageType(m_iPrimaryAmmoType), "ImpactGauss" );
return;
 }
//=====================================================================================//
// Purpose: Shows a decal where we just hit
//=====================================================================================//
void CTDPBludgeonWeaponBase::ImpactEffect( trace_t &tr )
{
	// FIXME: need new decals
	// Right now when hitting things the bullet decal is shown
	UTIL_ImpactTrace( &tr, DMG_CLUB );

	return;
}
//=====================================================================================//
// Purpose: Shows a decal where we just hit
//=====================================================================================//
void CTDPWeaponMaul::ImpactEffect( trace_t &tr )
{
	// FIXME: need new decals
	// Right now when hitting things the bullet decal is shown
	UTIL_ImpactTrace( &tr, DMG_SLASH );

	return;
}
예제 #6
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponStunStick::ImpactEffect( trace_t &traceHit )
{
	//Glowing spark effect for hit
	//UTIL_DecalTrace( &m_trLineHit, "PlasmaGlowFade" );
	
	//FIXME: need new decals
	UTIL_ImpactTrace( &traceHit, DMG_CLUB );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseHL2MPBludgeonWeapon::ImpactEffect( trace_t &traceHit )
{
    // See if we hit water (we don't do the other impact effects in this case)
    if ( ImpactWater( traceHit.startpos, traceHit.endpos ) )
        return;

    //FIXME: need new decals
    UTIL_ImpactTrace( &traceHit, DMG_CLUB );
}
예제 #8
0
//=========================================================
// ArmBeam - small beam from arm to nearby geometry
//=========================================================
void CNPC_Vortigaunt::ArmBeam( int side )
{
    trace_t tr;
    float flDist = 1.0;

    if ( m_iBeams >= VORTIGAUNT_MAX_BEAMS )
        return;

    Vector forward, right, up;
    Vector vecAim;
    AngleVectors( GetAbsAngles(), &forward, &right, &up );
    Vector vecSrc = GetAbsOrigin() + up * 36 + right * side * 16 + forward * 32;

    for (int i = 0; i < 3; i++)
    {
        vecAim = right * side * random->RandomFloat( 0, 1 ) + up * random->RandomFloat( -1, 1 );
        trace_t tr1;
        UTIL_TraceLine ( vecSrc, vecSrc + vecAim * 512, MASK_SOLID, this, COLLISION_GROUP_NONE, &tr1);
        if (flDist > tr1.fraction)
        {
            tr = tr1;
            flDist = tr.fraction;
        }
    }

    // Couldn't find anything close enough
    if ( flDist == 1.0 )
        return;

    if( tr.m_pEnt && tr.m_pEnt->m_takedamage )
    {
        CTakeDamageInfo info( this, this, 10, DMG_SHOCK );
        CalculateMeleeDamageForce( &info, vecAim, tr.endpos );

        tr.m_pEnt->TakeDamage( info );
    }

    UTIL_ImpactTrace( &tr, DMG_CLUB );

    m_pBeam[m_iBeams] = CBeam::BeamCreate( "sprites/lgtning.vmt", 3.0f );

    if ( m_pBeam[m_iBeams] == NULL )
        return;

    m_pBeam[m_iBeams]->PointEntInit( tr.endpos, this );
    m_pBeam[m_iBeams]->SetEndAttachment( side < 0 ? 2 : 1 );

    m_pBeam[m_iBeams]->SetColor( 96, 128, 16 );

    m_pBeam[m_iBeams]->SetBrightness( 64 );
    m_pBeam[m_iBeams]->SetNoise( 12.8 );

    m_iBeams++;
}
예제 #9
0
//-----------------------------------------------------------------------------
// Purpose:
// Input : &tr - used to figure out where to do the effect
// nDamageType - ???
//-----------------------------------------------------------------------------
void CWeaponGrapple::DoImpactEffect(trace_t &tr, int nDamageType)
{
#ifndef CLIENT_DLL
	if ((tr.surface.flags & SURF_SKY) == false)
	{
		CPVSFilter filter(tr.endpos);
		te->GaussExplosion(filter, 0.0f, tr.endpos, tr.plane.normal, 0);
		m_nBulletType = GetAmmoDef()->Index("GaussEnergy");
		UTIL_ImpactTrace(&tr, m_nBulletType);
	}
#endif
}
예제 #10
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : &tr - 
//			nDamageType - 
//-----------------------------------------------------------------------------
void CASW_PropJeep::DoImpactEffect( trace_t &tr, int nDamageType )
{
	//Draw our beam
	DrawBeam( tr.startpos, tr.endpos, 2.4 );

	if ( (tr.surface.flags & SURF_SKY) == false )
	{
		CPVSFilter filter( tr.endpos );
		te->GaussExplosion( filter, 0.0f, tr.endpos, tr.plane.normal, 0 );

		UTIL_ImpactTrace( &tr, m_nBulletType );
	}
}
예제 #11
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponStunStick::ImpactEffect( trace_t &traceHit )
{
	
//#ifndef CLIENT_DLL
	
	CEffectData	data;

	data.m_vNormal = traceHit.plane.normal;
	data.m_vOrigin = traceHit.endpos + ( data.m_vNormal * 4.0f );

	DispatchEffect( "StunstickImpact", data );

//#endif

	//FIXME: need new decals
	UTIL_ImpactTrace( &traceHit, DMG_CLUB );
}
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();
	}
}
void CSDKPlayer::FireBullet( 
						   Vector vecSrc,	// shooting postion
						   const QAngle &shootAngles,  //shooting angle
						   float vecSpread, // spread vector
						   int iDamage, // base damage
						   int iBulletType, // ammo type
						   CBaseEntity *pevAttacker, // shooter
						   bool bDoEffects,	// create impact effect ?
						   float x,	// spread x factor
						   float y	// spread y factor
						   )
{
	float fCurrentDamage = iDamage;   // damage of the bullet at it's current trajectory
	float flCurrentDistance = 0.0;  //distance that the bullet has traveled so far

	Vector vecDirShooting, vecRight, vecUp;
	AngleVectors( shootAngles, &vecDirShooting, &vecRight, &vecUp );

	if ( !pevAttacker )
		pevAttacker = this;  // the default attacker is ourselves

	// add the spray 
	Vector vecDir = vecDirShooting +
		x * vecSpread * vecRight +
		y * vecSpread * vecUp;

	VectorNormalize( vecDir );

	float flMaxRange = 8000;

	Vector vecEnd = vecSrc + vecDir * flMaxRange; // max bullet range is 10000 units

	trace_t tr; // main enter bullet trace

	UTIL_TraceLine( vecSrc, vecEnd, MASK_SOLID|CONTENTS_DEBRIS|CONTENTS_HITBOX, this, COLLISION_GROUP_NONE, &tr );

		if ( tr.fraction == 1.0f )
			return; // we didn't hit anything, stop tracing shoot

	if ( sv_showimpacts.GetBool() )
	{
#ifdef CLIENT_DLL
		// draw red client impact markers
		debugoverlay->AddBoxOverlay( tr.endpos, Vector(-2,-2,-2), Vector(2,2,2), QAngle( 0, 0, 0), 255,0,0,127, 4 );

		if ( tr.m_pEnt && tr.m_pEnt->IsPlayer() )
		{
			C_BasePlayer *player = ToBasePlayer( tr.m_pEnt );
			player->DrawClientHitboxes( 4, true );
		}
#else
		// draw blue server impact markers
		NDebugOverlay::Box( tr.endpos, Vector(-2,-2,-2), Vector(2,2,2), 0,0,255,127, 4 );

		if ( tr.m_pEnt && tr.m_pEnt->IsPlayer() )
		{
			CBasePlayer *player = ToBasePlayer( tr.m_pEnt );
			player->DrawServerHitboxes( 4, true );
		}
#endif
	}

		//calculate the damage based on the distance the bullet travelled.
		flCurrentDistance += tr.fraction * flMaxRange;

		// damage get weaker of distance
		fCurrentDamage *= pow ( 0.85f, (flCurrentDistance / 500));

		int iDamageType = DMG_BULLET | DMG_NEVERGIB;

		if( bDoEffects )
		{
			// See if the bullet ended up underwater + started out of the water
			if ( enginetrace->GetPointContents( tr.endpos ) & (CONTENTS_WATER|CONTENTS_SLIME) )
			{	
				trace_t waterTrace;
				UTIL_TraceLine( vecSrc, tr.endpos, (MASK_SHOT|CONTENTS_WATER|CONTENTS_SLIME), this, COLLISION_GROUP_NONE, &waterTrace );

				if( waterTrace.allsolid != 1 )
				{
					CEffectData	data;
					data.m_vOrigin = waterTrace.endpos;
					data.m_vNormal = waterTrace.plane.normal;
					data.m_flScale = random->RandomFloat( 8, 12 );

					if ( waterTrace.contents & CONTENTS_SLIME )
					{
						data.m_fFlags |= FX_WATER_IN_SLIME;
					}

					DispatchEffect( "gunshotsplash", data );
				}
			}
			else
			{
				//Do Regular hit effects

				// Don't decal nodraw surfaces
				if ( !( tr.surface.flags & (SURF_SKY|SURF_NODRAW|SURF_HINT|SURF_SKIP) ) )
				{
					CBaseEntity *pEntity = tr.m_pEnt;
					if ( !( !friendlyfire.GetBool() && pEntity && pEntity->IsPlayer() && pEntity->GetTeamNumber() == GetTeamNumber() ) )
					{
						UTIL_ImpactTrace( &tr, iDamageType );
					}
				}
			}
		} // bDoEffects

		// add damage to entity that we hit

#ifdef GAME_DLL
		ClearMultiDamage();

		CTakeDamageInfo info( pevAttacker, pevAttacker, fCurrentDamage, iDamageType );
		CalculateBulletDamageForce( &info, iBulletType, vecDir, tr.endpos );
		tr.m_pEnt->DispatchTraceAttack( info, vecDir, &tr );

		TraceAttackToTriggers( info, tr.startpos, tr.endpos, vecDir );

		ApplyMultiDamage();
#endif
}
예제 #14
0
//------------------------------------------------------------------------------
// 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: 
//-----------------------------------------------------------------------------
void CWeaponGauss::ChargedFire( void )
{
	CBasePlayer *pOwner = ToBasePlayer( GetOwner() );

	if(pOwner == NULL)
		return;

	bool penetrated = false;

	//Play shock sounds
    WeaponSound( SINGLE );
    WeaponSound( SPECIAL2 );

	SendWeaponAnim( ACT_VM_SECONDARYATTACK );

	StopChargeSound();




	m_bCharging = false;
	m_bChargeIndicated = false;


	m_flNextSecondaryAttack = gpGlobals->curtime + 1.0f;

	//Shoot a shot straight
	Vector  startPos= pOwner->Weapon_ShootPosition();
	Vector  aimDir  = pOwner->GetAutoaimVector( AUTOAIM_5DEGREES );
	Vector  endPos  = startPos + ( aimDir * MAX_TRACE_LENGTH );


	//Find Damage
	 float flChargeAmount = ( gpGlobals->curtime - m_flChargeStartTime ) / MAX_GAUSS_CHARGE_TIME;
	 //Clamp This
	 if ( flChargeAmount > 1.0f )
	 {
		 flChargeAmount = 1.0f;
	 }
#ifndef CLIENT_DLL
	 // float flDamage = sk_plr_max_dmg_gauss.GetFloat() + ( ( sk_plr_max_dmg_gauss.GetFloat() - sk_plr_max_dmg_gauss.GetFloat() ) * flChargeAmount );


	float flDamage = 3 + ( ( 37 - 15 ) * flChargeAmount );
#endif
	trace_t tr;
	UTIL_TraceLine( startPos, endPos, MASK_SHOT, pOwner, COLLISION_GROUP_NONE, &tr ); //Trace from gun to wall

		  UTIL_ImpactTrace( &tr, GetAmmoDef()->DamageType(m_iPrimaryAmmoType), "ImpactGauss" );
		  UTIL_DecalTrace( &tr, "RedGlowFade" );


#ifndef CLIENT_DLL
		  //RadiusDamage( CTakeDamageInfo( this, pOwner, sk_plr_max_dmg_gauss.GetFloat(), DMG_SHOCK ),tr.endpos, 90.0f, CLASS_PLAYER_ALLY, pOwner );
          RadiusDamage( CTakeDamageInfo( this, pOwner, flDamage, DMG_SHOCK ), tr.endpos, 10.0f, CLASS_PLAYER_ALLY, pOwner );
#endif


#ifndef CLIENT_DLL
	ClearMultiDamage();
#endif

		  UTIL_ImpactTrace( &tr, GetAmmoDef()->DamageType(m_iPrimaryAmmoType), "ImpactGauss" );
		  UTIL_DecalTrace( &tr, "RedGlowFade" );

#ifndef CLIENT_DLL
		 // RadiusDamage( CTakeDamageInfo( this, pOwner, sk_plr_max_dmg_gauss.GetFloat(), DMG_SHOCK ),tr.endpos, 90.0f, CLASS_PLAYER_ALLY, pOwner );
          RadiusDamage( CTakeDamageInfo( this, pOwner, flDamage, DMG_SHOCK ), tr.endpos, 10.0f, CLASS_PLAYER_ALLY, pOwner );
#endif


	  CBaseEntity *pHit = tr.m_pEnt;

	  if ( tr.DidHitWorld() ){

		  UTIL_ImpactTrace( &tr, GetAmmoDef()->DamageType(m_iPrimaryAmmoType), "ImpactGauss" );
		  UTIL_DecalTrace( &tr, "RedGlowFade" );

		  CPVSFilter filter( tr.endpos );
		  te->GaussExplosion( filter, 0.0f, tr.endpos, tr.plane.normal, 0 );

		  Vector  testPos = tr.endpos + ( aimDir * 128.0f );

		  UTIL_TraceLine( testPos, tr.endpos, MASK_SHOT, pOwner, COLLISION_GROUP_NONE, &tr ); //Trace to backside of first wall

		  UTIL_ImpactTrace( &tr, GetAmmoDef()->DamageType(m_iPrimaryAmmoType), "ImpactGauss" );
		  UTIL_DecalTrace( &tr, "RedGlowFade" );

#ifndef CLIENT_DLL
		  //RadiusDamage( CTakeDamageInfo( this, pOwner, sk_plr_max_dmg_gauss.GetFloat(), DMG_SHOCK ),tr.endpos, 90.0f, CLASS_PLAYER_ALLY, pOwner );
          RadiusDamage( CTakeDamageInfo( this, pOwner, flDamage, DMG_SHOCK ), tr.endpos, 10.0f, CLASS_PLAYER_ALLY, pOwner );
#endif


		  if ( tr.allsolid == false ){
			  UTIL_DecalTrace( &tr, "RedGlowFade" );
			  UTIL_ImpactTrace( &tr, GetAmmoDef()->DamageType(m_iPrimaryAmmoType), "ImpactGauss" );

#ifndef CLIENT_DLL
		  //RadiusDamage( CTakeDamageInfo( this, pOwner, sk_plr_max_dmg_gauss.GetFloat(), DMG_SHOCK ),tr.endpos, 90.0f, CLASS_PLAYER_ALLY, pOwner );
          RadiusDamage( CTakeDamageInfo( this, pOwner, flDamage, DMG_SHOCK ), tr.endpos, 10.0f, CLASS_PLAYER_ALLY, pOwner );
#endif

			  penetrated = true;

		  UTIL_ImpactTrace( &tr, GetAmmoDef()->DamageType(m_iPrimaryAmmoType), "ImpactGauss" );
		  UTIL_DecalTrace( &tr, "RedGlowFade" );
#ifndef CLIENT_DLL
		  //RadiusDamage( CTakeDamageInfo( this, pOwner, sk_plr_max_dmg_gauss.GetFloat(), DMG_SHOCK ),tr.endpos, 90.0f, CLASS_PLAYER_ALLY, pOwner );
          RadiusDamage( CTakeDamageInfo( this, pOwner, flDamage, DMG_SHOCK ), tr.endpos, 10.0f, CLASS_PLAYER_ALLY, pOwner );
#endif

		  }

	  } else if(pHit != NULL){
#ifndef CLIENT_DLL
		 // CTakeDamageInfo dmgInfo( this, pOwner, sk_plr_max_dmg_gauss.GetFloat(), DMG_SHOCK );
//		  CalculateBulletDamageForce( &dmgInfo, m_iPrimaryAmmoType, aimDir, tr.endpos );
          UTIL_ImpactTrace( &tr, GetAmmoDef()->DamageType(m_iPrimaryAmmoType), "ImpactGauss" );
          UTIL_DecalTrace( &tr, "RedGlowFade" );
		  //Do Direct damage to anything in our path
//		  pHit->DispatchTraceAttack( dmgInfo, aimDir, &tr );
#endif
	  }
#ifndef CLIENT_DLL
	  ApplyMultiDamage();
#endif


#ifndef CLIENT_DLL
		  //RadiusDamage( CTakeDamageInfo( this, pOwner, sk_plr_max_dmg_gauss.GetFloat(), DMG_SHOCK ),tr.endpos, 90.0f, CLASS_PLAYER_ALLY, pOwner );
          RadiusDamage( CTakeDamageInfo( this, pOwner, flDamage, DMG_SHOCK ), tr.endpos, 10.0f, CLASS_PLAYER_ALLY, pOwner );
#endif

	 Vector  newPos = tr.endpos + ( aimDir * MAX_TRACE_LENGTH);
	  QAngle  viewPunch;
	  viewPunch.x = random->RandomFloat( -4.0f, -8.0f );
	  viewPunch.y = random->RandomFloat( -0.25f,  0.25f );
	  viewPunch.z = 0;
	  pOwner->ViewPunch( viewPunch );

	 // DrawBeam( startPos, tr.endpos, 9.6, true ); //Draw beam from gun through first wall.
#ifndef CLIENT_DLL
	Vector	recoilForce = pOwner->BodyDirection3D() * -( flDamage * 15.0f );
      recoilForce[2] += 128.0f;

      pOwner->ApplyAbsVelocityImpulse( recoilForce );
#endif
	  CPVSFilter filter( tr.endpos );
	  te->GaussExplosion(filter, 0.0f, tr.endpos, tr.plane.normal, 0 );

#ifndef CLIENT_DLL
		  //RadiusDamage( CTakeDamageInfo( this, pOwner, sk_plr_max_dmg_gauss.GetFloat(), DMG_SHOCK ),tr.endpos, 90.0f, CLASS_PLAYER_ALLY, pOwner );
          RadiusDamage( CTakeDamageInfo( this, pOwner, flDamage, DMG_SHOCK ), tr.endpos, 10.0f, CLASS_PLAYER_ALLY, pOwner );
#endif


	  if ( penetrated == true ){

		  trace_t beam_tr;
		  Vector vecDest = tr.endpos + aimDir * MAX_TRACE_LENGTH;
		  UTIL_TraceLine( tr.endpos, vecDest, MASK_SHOT, pOwner, COLLISION_GROUP_NONE, &beam_tr ); //Traces from back of first wall to second wall


#ifndef CLIENT_DLL
	 // float flDamage = sk_plr_max_dmg_gauss.GetFloat() + ( ( sk_plr_max_dmg_gauss.GetFloat() - sk_plr_max_dmg_gauss.GetFloat() ) * flChargeAmount );


	float flDamage = 37 + ( ( 115 - 15 ) * flChargeAmount );
#endif



		  for(int i = 0; i < 0; i++){

			  UTIL_TraceLine(beam_tr.endpos + aimDir * 128.0f, beam_tr.endpos, MASK_SHOT, pOwner, COLLISION_GROUP_NONE, &beam_tr ); //Traces To back of second wall


UTIL_ImpactTrace( &beam_tr, GetAmmoDef()->DamageType(m_iPrimaryAmmoType), "ImpactGauss" );
UTIL_DecalTrace( &beam_tr, "RedGlowFade" );

#ifndef CLIENT_DLL
			  //RadiusDamage( CTakeDamageInfo( this, pOwner, sk_plr_max_dmg_gauss.GetFloat(), DMG_SHOCK ), beam_tr.endpos, 90.0f, CLASS_PLAYER_ALLY, pOwner );
              RadiusDamage( CTakeDamageInfo( this, pOwner, flDamage, DMG_SHOCK ), tr.endpos, 10.0f, CLASS_PLAYER_ALLY, pOwner );
#endif



		  }
		  DrawBeam( tr.endpos, beam_tr.endpos, 9.6, false );
		  DoWallBreak(tr.endpos,newPos,aimDir,&tr,pOwner,true);

UTIL_ImpactTrace( &beam_tr, GetAmmoDef()->DamageType(m_iPrimaryAmmoType), "ImpactGauss" );
UTIL_DecalTrace( &beam_tr, "RedGlowFade" );

#ifndef CLIENT_DLL
			  //RadiusDamage( CTakeDamageInfo( this, pOwner, sk_plr_max_dmg_gauss.GetFloat(), DMG_SHOCK ), beam_tr.endpos, 90.0f, CLASS_PLAYER_ALLY, pOwner );
          RadiusDamage( CTakeDamageInfo( this, pOwner, flDamage, DMG_SHOCK ), tr.endpos, 10.0f, CLASS_PLAYER_ALLY, pOwner );
#endif

	return;	  
	  }

}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CCrossbowBolt::BoltTouch( CBaseEntity *pOther )
{
	if ( pOther->IsSolidFlagSet(FSOLID_VOLUME_CONTENTS | FSOLID_TRIGGER) )
	{
		// Some NPCs are triggers that can take damage (like antlion grubs). We should hit them.
		if ( ( pOther->m_takedamage == DAMAGE_NO ) || ( pOther->m_takedamage == DAMAGE_EVENTS_ONLY ) )
			return;
	}

	if ( pOther->m_takedamage != DAMAGE_NO )
	{
		trace_t	tr, tr2;
		tr = BaseClass::GetTouchTrace();
		Vector	vecNormalizedVel = GetAbsVelocity();

		ClearMultiDamage();
		VectorNormalize( vecNormalizedVel );

#if defined(HL2_EPISODIC)
		//!!!HACKHACK - specific hack for ep2_outland_10 to allow crossbow bolts to pass through her bounding box when she's crouched in front of the player
		// (the player thinks they have clear line of sight because Alyx is crouching, but her BBOx is still full-height and blocks crossbow bolts.
		if( GetOwnerEntity() && GetOwnerEntity()->IsPlayer() && pOther->Classify() == CLASS_PLAYER_ALLY_VITAL && FStrEq(STRING(gpGlobals->mapname), "ep2_outland_10") )
		{
			// Change the owner to stop further collisions with Alyx. We do this by making her the owner.
			// The player won't get credit for this kill but at least the bolt won't magically disappear!
			SetOwnerEntity( pOther );
			return;
		}
#endif//HL2_EPISODIC

		if( GetOwnerEntity() && GetOwnerEntity()->IsPlayer() && pOther->IsNPC() )
		{
			CTakeDamageInfo	dmgInfo( this, GetOwnerEntity(), sk_plr_dmg_crossbow.GetFloat(), DMG_NEVERGIB );
			dmgInfo.AdjustPlayerDamageInflictedForSkillLevel();
			CalculateMeleeDamageForce( &dmgInfo, vecNormalizedVel, tr.endpos, 0.7f );
			dmgInfo.SetDamagePosition( tr.endpos );
			pOther->DispatchTraceAttack( dmgInfo, vecNormalizedVel, &tr );

			CBasePlayer *pPlayer = ToBasePlayer( GetOwnerEntity() );
			if ( pPlayer )
			{
				gamestats->Event_WeaponHit( pPlayer, true, "weapon_crossbow", dmgInfo );
			}

		}
		else
		{
			CTakeDamageInfo	dmgInfo( this, GetOwnerEntity(), sk_plr_dmg_crossbow.GetFloat(), DMG_BULLET | DMG_NEVERGIB );
			CalculateMeleeDamageForce( &dmgInfo, vecNormalizedVel, tr.endpos, 0.7f );
			dmgInfo.SetDamagePosition( tr.endpos );
			pOther->DispatchTraceAttack( dmgInfo, vecNormalizedVel, &tr );
		}

		ApplyMultiDamage();

		//Adrian: keep going through the glass.
		if ( pOther->GetCollisionGroup() == COLLISION_GROUP_BREAKABLE_GLASS )
			 return;

		/*if ( !pOther->IsAlive() )
		{
			// We killed it! 
			const surfacedata_t *pdata = physprops->GetSurfaceData( tr.surface.surfaceProps );
			if ( pdata->game.material == CHAR_TEX_GLASS )
			{
				return;
			}
		}*/

		SetAbsVelocity( Vector( 0, 0, 0 ) );

		// play body "thwack" sound
		EmitSound( "Weapon_Crossbow.BoltHitBody" );

		Vector vForward;

		AngleVectors( GetAbsAngles(), &vForward );
		VectorNormalize ( vForward );

		UTIL_TraceLine( GetAbsOrigin(),	GetAbsOrigin() + vForward * 128, MASK_BLOCKLOS, pOther, COLLISION_GROUP_NONE, &tr2 );

		if ( tr2.fraction != 1.0f )
		{
//			NDebugOverlay::Box( tr2.endpos, Vector( -16, -16, -16 ), Vector( 16, 16, 16 ), 0, 255, 0, 0, 10 );
//			NDebugOverlay::Box( GetAbsOrigin(), Vector( -16, -16, -16 ), Vector( 16, 16, 16 ), 0, 0, 255, 0, 10 );

			if ( tr2.m_pEnt == NULL || ( tr2.m_pEnt && tr2.m_pEnt->GetMoveType() == MOVETYPE_NONE ) )
			{
				CEffectData	data;

				data.m_vOrigin = tr2.endpos;
				data.m_vNormal = vForward;
				data.m_nEntIndex = tr2.fraction != 1.0f;
			
				DispatchEffect( "BoltImpact", data );
			}
		}
		
		SetTouch( NULL );
		SetThink( NULL );

		if ( !g_pGameRules->IsMultiplayer() )
		{
			UTIL_Remove( this );
		}
	}
	else
	{
		trace_t	tr;
		tr = BaseClass::GetTouchTrace();

		// See if we struck the world
		if ( pOther->GetMoveType() == MOVETYPE_NONE && !( tr.surface.flags & SURF_SKY ) )
		{
			EmitSound( "Weapon_Crossbow.BoltHitWorld" );

			// if what we hit is static architecture, can stay around for a while.
			Vector vecDir = GetAbsVelocity();
			float speed = VectorNormalize( vecDir );

			// See if we should reflect off this surface
			float hitDot = DotProduct( tr.plane.normal, -vecDir );
			
			if ( ( hitDot < 0.5f ) && ( speed > 100 ) )
			{
				Vector vReflection = 2.0f * tr.plane.normal * hitDot + vecDir;
				
				QAngle reflectAngles;

				VectorAngles( vReflection, reflectAngles );

				SetLocalAngles( reflectAngles );

				SetAbsVelocity( vReflection * speed * 0.75f );

				// Start to sink faster
				SetGravity( 1.0f );
			}
			else
			{
				SetThink( &CCrossbowBolt::SUB_Remove );
				SetNextThink( gpGlobals->curtime + 2.0f );
				
				//FIXME: We actually want to stick (with hierarchy) to what we've hit
				SetMoveType( MOVETYPE_NONE );
			
				Vector vForward;

				AngleVectors( GetAbsAngles(), &vForward );
				VectorNormalize ( vForward );

				CEffectData	data;

				data.m_vOrigin = tr.endpos;
				data.m_vNormal = vForward;
				data.m_nEntIndex = 0;
			
				DispatchEffect( "BoltImpact", data );
				
				UTIL_ImpactTrace( &tr, DMG_BULLET );

				AddEffects( EF_NODRAW );
				SetTouch( NULL );
				SetThink( &CCrossbowBolt::SUB_Remove );
				SetNextThink( gpGlobals->curtime + 2.0f );

				if ( m_pGlowSprite != NULL )
				{
					m_pGlowSprite->TurnOn();
					m_pGlowSprite->FadeAndDie( 3.0f );
				}
			}
			
			// Shoot some sparks
			if ( UTIL_PointContents( GetAbsOrigin() ) != CONTENTS_WATER)
			{
				g_pEffects->Sparks( GetAbsOrigin() );
			}
		}
		else
		{
			// Put a mark unless we've hit the sky
			if ( ( tr.surface.flags & SURF_SKY ) == false )
			{
				UTIL_ImpactTrace( &tr, DMG_BULLET );
			}

			UTIL_Remove( this );
		}
	}

	if ( g_pGameRules->IsMultiplayer() )
	{
//		SetThink( &CCrossbowBolt::ExplodeThink );
//		SetNextThink( gpGlobals->curtime + 0.1f );
	}
}
예제 #17
0
// -----------------------------------------------------------------------------
// Purpose:
// Note: Think function to delay the impact decal until the animation is finished 
//       playing.
// -----------------------------------------------------------------------------
void CTFWeaponBaseMelee::Smack( void )
{
	trace_t trace;

	CBasePlayer *pPlayer = GetPlayerOwner();
	if ( !pPlayer )
		return;

#if !defined (CLIENT_DLL)
	// Move other players back to history positions based on local player's lag
	lagcompensation->StartLagCompensation( pPlayer, pPlayer->GetCurrentCommand() );
#endif

	// We hit, setup the smack.
	if ( DoSwingTrace( trace ) )
	{
		// Hit sound - immediate.
		if( trace.m_pEnt->IsPlayer()  )
		{
			WeaponSound( MELEE_HIT );
		}
		else
		{
			WeaponSound( MELEE_HIT_WORLD );
		}

		// Get the current player.
		CTFPlayer *pPlayer = GetTFPlayerOwner();
		if ( !pPlayer )
			return;

		Vector vecForward; 
		AngleVectors( pPlayer->EyeAngles(), &vecForward );
		Vector vecSwingStart = pPlayer->Weapon_ShootPosition();
		Vector vecSwingEnd = vecSwingStart + vecForward * 48;

#ifndef CLIENT_DLL
		// Do Damage.
		int iCustomDamage = TF_DMG_CUSTOM_NONE;
		float flDamage = GetMeleeDamage( trace.m_pEnt, iCustomDamage );
		int iDmgType = DMG_BULLET | DMG_NEVERGIB | DMG_CLUB;
		if ( IsCurrentAttackACrit() )
		{
			// TODO: Not removing the old critical path yet, but the new custom damage is marking criticals as well for melee now.
			iDmgType |= DMG_CRITICAL;
		}
		CTFWeaponBase *pWpn = pPlayer->GetActiveTFWeapon();
		CTFUbersaw *pUbersaw = dynamic_cast<CTFUbersaw*>(pWpn);
		CWeaponMedigun *pMedigun = static_cast<CWeaponMedigun*>(pPlayer->Weapon_OwnsThisID(TF_WEAPON_MEDIGUN));
		if (pMedigun && pUbersaw)
		{
			if(trace.m_pEnt->IsPlayer() && trace.m_pEnt->GetTeamNumber() != pPlayer->GetTeamNumber())
			{
				pMedigun->AddCharge();
			}
		}
		CWeaponKritzkrieg *pKritzkrieg = static_cast<CWeaponKritzkrieg*>(pPlayer->Weapon_OwnsThisID(TF_WEAPON_KRITZKRIEG));
		if (pKritzkrieg && pUbersaw)
		{
			if(trace.m_pEnt->IsPlayer() && trace.m_pEnt->GetTeamNumber() != pPlayer->GetTeamNumber())
			{
				pKritzkrieg->AddCharge();
			}
		}
		CTakeDamageInfo info( pPlayer, pPlayer, flDamage, iDmgType, iCustomDamage );
		CalculateMeleeDamageForce( &info, vecForward, vecSwingEnd, 1.0f / flDamage * tf_meleeattackforcescale.GetFloat() );
		trace.m_pEnt->DispatchTraceAttack( info, vecForward, &trace ); 
		ApplyMultiDamage();

		OnEntityHit( trace.m_pEnt );
#endif
		// Don't impact trace friendly players or objects
		if ( trace.m_pEnt && trace.m_pEnt->GetTeamNumber() != pPlayer->GetTeamNumber() )
		{
#ifdef CLIENT_DLL
			UTIL_ImpactTrace( &trace, DMG_CLUB );
#endif
			m_bConnected = true;
		}

	}

#if !defined (CLIENT_DLL)
	lagcompensation->FinishLagCompensation( pPlayer );
#endif
}
예제 #18
0
//-----------------------------------------------------------------------------
// Allows the shooter to change the impact effect of his bullets
//-----------------------------------------------------------------------------
void CPropAPC::DoImpactEffect( trace_t &tr, int nDamageType )
{
	UTIL_ImpactTrace( &tr, nDamageType, "HelicopterImpact" );
} 
예제 #19
0
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pOther -
//-----------------------------------------------------------------------------
void CGrappleHook::HookTouch(CBaseEntity *pOther)
{
	if (!pOther->IsSolid() || pOther->IsSolidFlagSet(FSOLID_VOLUME_CONTENTS))
		return;
	if ((pOther != m_hOwner) && (pOther->m_takedamage != DAMAGE_NO))
	{
		m_hOwner->NotifyHookDied();
		SetTouch(NULL);
		SetThink(NULL);
		UTIL_Remove(this);
	}
	else
	{
		trace_t	tr;
		tr = BaseClass::GetTouchTrace();
		// See if we struck the world
		if (pOther->GetMoveType() == MOVETYPE_NONE && !(tr.surface.flags & SURF_SKY))
		{
			EmitSound("Weapon_AR2.Reload_Push");
			// if what we hit is static architecture, can stay around for a while.
			Vector vecDir = GetAbsVelocity();
			//FIXME: We actually want to stick (with hierarchy) to what we've hit
			SetMoveType(MOVETYPE_NONE);
			Vector vForward;
			AngleVectors(GetAbsAngles(), &vForward);
			VectorNormalize(vForward);
			CEffectData data;
			data.m_vOrigin = tr.endpos;
			data.m_vNormal = vForward;
			data.m_nEntIndex = 0;
			// DispatchEffect( "Impact", data );
			// AddEffects( EF_NODRAW );
			SetTouch(NULL);
			VPhysicsDestroyObject();
			VPhysicsInitNormal(SOLID_VPHYSICS, FSOLID_NOT_STANDABLE, false);
			AddSolidFlags(FSOLID_NOT_SOLID);
			// SetMoveType( MOVETYPE_NONE );
			if (!m_hPlayer)
			{
				Assert(0);
				return;
			}
			// Set Jay's gai flag
			m_hPlayer->SetPhysicsFlag(PFLAG_VPHYSICS_MOTIONCONTROLLER, true);
			//IPhysicsObject *pPhysObject = m_hPlayer->VPhysicsGetObject();
			IPhysicsObject *pRootPhysObject = VPhysicsGetObject();
			Assert(pRootPhysObject);
			//Assert(pPhysObject);
			pRootPhysObject->EnableMotion(false);
			// Root has huge mass, tip has little
			pRootPhysObject->SetMass(VPHYSICS_MAX_MASS);
			// pPhysObject->SetMass( 100 );
			// float damping = 3;
			// pPhysObject->SetDamping( &damping, &damping );
			Vector origin = m_hPlayer->GetAbsOrigin();
			Vector rootOrigin = GetAbsOrigin();
			m_fSpringLength = (origin - rootOrigin).Length();
			m_bPlayerWasStanding = ((m_hPlayer->GetFlags() & FL_DUCKING) == 0);
			SetThink(&CGrappleHook::HookedThink);
			SetNextThink(gpGlobals->curtime + 0.1f);
		}
		else
		{
			// Put a mark unless we've hit the sky
			if ((tr.surface.flags & SURF_SKY) == false)
			{
				UTIL_ImpactTrace(&tr, DMG_BULLET);
			}
			SetTouch(NULL);
			SetThink(NULL);
			m_hOwner->NotifyHookDied();
			UTIL_Remove(this);
		}
	}
}
예제 #20
0
void CSDKPlayer::FireBullet( 
						   Vector vecSrc,	// shooting postion
						   const QAngle &shootAngles,  //shooting angle
						   float vecSpread, // spread vector
						   SDKWeaponID eWeaponID,	// weapon that fired this shot
						   int iDamage, // base damage
						   int iBulletType, // ammo type
						   CBaseEntity *pevAttacker, // shooter
						   bool bDoEffects,	// create impact effect ?
						   float x,	// spread x factor
						   float y	// spread y factor
						   )
{
	float flCurrentDistance = 0.0;  //distance that the bullet has traveled so far

	Vector vecDirShooting, vecRight, vecUp;
	AngleVectors( shootAngles, &vecDirShooting, &vecRight, &vecUp );

	if ( !pevAttacker )
		pevAttacker = this;  // the default attacker is ourselves

	// add the spray 
	Vector vecDir = vecDirShooting +
		x * vecSpread * vecRight +
		y * vecSpread * vecUp;

	VectorNormalize( vecDir );

	float flMaxRange = 8000;

	Vector vecEnd = vecSrc + vecDir * flMaxRange; // max bullet range is 10000 units
	CBaseEntity* pIgnore = this;

	// initialize these before the penetration loop, we'll need them to make our tracer after
	Vector vecTracerSrc = vecSrc;
	trace_t tr; // main enter bullet trace

	for (size_t i = 0; i < 5; i++)
	{
		CTraceFilterSimpleList tf(COLLISION_GROUP_NONE);
		tf.AddEntityToIgnore(this);
		tf.AddEntityToIgnore(pIgnore);

		UTIL_TraceLine( vecSrc, vecEnd, MASK_SOLID|CONTENTS_DEBRIS|CONTENTS_HITBOX, &tf, &tr );

		if ( tr.fraction == 1.0f )
			break; // we didn't hit anything, stop tracing shoot

		if ( sv_showimpacts.GetBool() )
		{
#ifdef CLIENT_DLL
			// draw red client impact markers
			debugoverlay->AddBoxOverlay( tr.endpos, Vector(-2,-2,-2), Vector(2,2,2), QAngle( 0, 0, 0), 255,0,0,127, 4 );

			if ( tr.m_pEnt && tr.m_pEnt->IsPlayer() )
			{
				C_BasePlayer *player = ToBasePlayer( tr.m_pEnt );
				player->DrawClientHitboxes( 4, true );
			}
#else
			// draw blue server impact markers
			NDebugOverlay::Box( tr.endpos, Vector(-2,-2,-2), Vector(2,2,2), 0,0,255,127, 4 );

			if ( tr.m_pEnt && tr.m_pEnt->IsPlayer() )
			{
				CBasePlayer *player = ToBasePlayer( tr.m_pEnt );
				player->DrawServerHitboxes( 4, true );
			}
#endif
		}

		weapontype_t eWeaponType = WT_NONE;

		CSDKWeaponInfo *pWeaponInfo = CSDKWeaponInfo::GetWeaponInfo(eWeaponID);
		Assert(pWeaponInfo);
		if (pWeaponInfo)
			eWeaponType = pWeaponInfo->m_eWeaponType;

		float flDamageMultiplier = 1;
		float flMaxRange = 3000;

		// Power formula works like so:
		// pow( x, distance/y )
		// The damage will be at 1 when the distance is 0 units, and at
		// x% when the distance is y units, with a gradual decay approaching zero
		switch (eWeaponType)
		{
		case WT_RIFLE:
			flDamageMultiplier = 0.75f;
			flMaxRange = 3000;
			break;

		case WT_SHOTGUN:
			flDamageMultiplier = 0.40f;
			flMaxRange = 500;
			break;

		case WT_SMG:
			flDamageMultiplier = 0.50f;
			flMaxRange = 1000;
			break;

		case WT_PISTOL:
		default:
			flDamageMultiplier = 0.55f;
			flMaxRange = 1500;
			break;
		}

		//calculate the damage based on the distance the bullet travelled.
		flCurrentDistance += tr.fraction * flMaxRange;

		// First 500 units, no decrease in damage.
		if (eWeaponType == WT_SHOTGUN)
			flCurrentDistance -= 350;
		else
			flCurrentDistance -= 500;

		if (flCurrentDistance < 0)
			flCurrentDistance = 0;

		if (flCurrentDistance > flMaxRange)
			flCurrentDistance = flMaxRange;

		float flDistanceMultiplier = pow(flDamageMultiplier, (flCurrentDistance / flMaxRange));

		int iDamageType = DMG_BULLET | DMG_NEVERGIB | GetAmmoDef()->DamageType(iBulletType);

		if (i == 0)
			iDamageType |= DMG_DIRECT;

		if( bDoEffects )
		{
			// See if the bullet ended up underwater + started out of the water
			if ( enginetrace->GetPointContents( tr.endpos ) & (CONTENTS_WATER|CONTENTS_SLIME) )
			{	
				trace_t waterTrace;
				UTIL_TraceLine( vecSrc, tr.endpos, (MASK_SHOT|CONTENTS_WATER|CONTENTS_SLIME), pIgnore, COLLISION_GROUP_NONE, &waterTrace );

				if( waterTrace.allsolid != 1 )
				{
					CEffectData	data;
					data.m_vOrigin = waterTrace.endpos;
					data.m_vNormal = waterTrace.plane.normal;
					data.m_flScale = random->RandomFloat( 8, 12 );

					if ( waterTrace.contents & CONTENTS_SLIME )
					{
						data.m_fFlags |= FX_WATER_IN_SLIME;
					}

					DispatchEffect( "gunshotsplash", data );
				}
			}
			else
			{
				//Do Regular hit effects

				// Don't decal nodraw surfaces
				if ( !( tr.surface.flags & (SURF_SKY|SURF_NODRAW|SURF_HINT|SURF_SKIP) ) )
				{
					CBaseEntity *pEntity = tr.m_pEnt;
					//Tony; only while using teams do we check for friendly fire.
					if ( pEntity && pEntity->IsPlayer() && (pEntity->GetBaseAnimating() && !pEntity->GetBaseAnimating()->IsRagdoll()) )
					{
#if defined ( SDK_USE_TEAMS )
						if ( pEntity->GetTeamNumber() == GetTeamNumber() )
						{
							if ( !friendlyfire.GetBool() )
								UTIL_ImpactTrace( &tr, iDamageType );
						}
#else
						UTIL_ImpactTrace( &tr, iDamageType );
#endif
					}
					//Tony; non player, just go nuts,
					else
					{
						UTIL_ImpactTrace( &tr, iDamageType );
					}
				}
			}
		} // bDoEffects

		// add damage to entity that we hit

#ifdef GAME_DLL
		float flBulletDamage = iDamage * flDistanceMultiplier / (i+1);	// Each iteration the bullet drops in strength

		ClearMultiDamage();

		CTakeDamageInfo info( pevAttacker, pevAttacker, flBulletDamage, iDamageType );
		CalculateBulletDamageForce( &info, iBulletType, vecDir, tr.endpos );
		tr.m_pEnt->DispatchTraceAttack( info, vecDir, &tr );

		TraceAttackToTriggers( info, tr.startpos, tr.endpos, vecDir );

		ApplyMultiDamage();
#else
		flDistanceMultiplier = flDistanceMultiplier; // Silence warning.
#endif

		pIgnore = tr.m_pEnt;

		float flPenetrationDistance;
		switch (eWeaponType)
		{
		case WT_RIFLE:
			flPenetrationDistance = 25;
			break;

		case WT_SHOTGUN:
			flPenetrationDistance = 5;
			break;

		case WT_SMG:
			flPenetrationDistance = 15;
			break;

		case WT_PISTOL:
		default:
			flPenetrationDistance = 15;
			break;
		}

		Vector vecBackwards = tr.endpos + vecDir * flPenetrationDistance;
		if (tr.m_pEnt->IsBSPModel())
			UTIL_TraceLine( vecBackwards, tr.endpos, CONTENTS_SOLID|CONTENTS_MOVEABLE, NULL, COLLISION_GROUP_NONE, &tr );
		else
			UTIL_TraceLine( vecBackwards, tr.endpos, CONTENTS_HITBOX, NULL, COLLISION_GROUP_NONE, &tr );

		if (tr.startsolid)
			break;
		
		if (tr.m_pEnt)
		{
			// let's have a bullet exit effect if we penetrated a solid surface
			if (tr.m_pEnt->IsBSPModel())
				UTIL_ImpactTrace( &tr, iDamageType );

			// ignore the entity we just hit for the next trace to avoid weird impact behaviors
			pIgnore = tr.m_pEnt;
		}

		// Set up the next trace.
		vecSrc = tr.endpos + vecDir;	// One unit in the direction of fire so that we firmly embed ourselves in whatever solid was hit.
	}
	
	// the bullet's done penetrating, let's spawn our particle system
	if (bDoEffects && (pevAttacker == this))
		MakeTracer( vecTracerSrc, tr, TRACER_TYPE_DEFAULT );
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponGaussGun::ChargedFire()
{
	if ( InGameRules()->IsMultiplayer() )
	{
	}

	CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
	
	if ( !pOwner )
		return;

	bool penetrated = false;

	//Play shock sounds
	WeaponSound( SINGLE );
	WeaponSound( SPECIAL2 );

	SendWeaponAnim( ACT_VM_SECONDARYATTACK );
	StopChargeSound();

	m_bCharging = false;
	m_bChargeIndicated = false;

	m_flNextPrimaryAttack	= gpGlobals->curtime + 0.2f;
	m_flNextSecondaryAttack = gpGlobals->curtime + 0.5f;

	//Shoot a shot straight out
	Vector	startPos= pOwner->Weapon_ShootPosition();
	Vector	aimDir	= pOwner->GetAutoaimVector( AUTOAIM_5DEGREES );
	Vector	endPos	= startPos + ( aimDir * MAX_TRACE_LENGTH );
	
	trace_t	tr;
	UTIL_TraceLine( startPos, endPos, MASK_SHOT, pOwner, COLLISION_GROUP_NONE, &tr );
	
#ifndef CLIENT_DLL

	ClearMultiDamage();

	//Find how much damage to do
	float flChargeAmount = ( gpGlobals->curtime - m_flChargeStartTime ) / MAX_GAUSS_CHARGE_TIME;

	//Clamp this
	if ( flChargeAmount > 1.0f )
		flChargeAmount = 1.0f;

	//Determine the damage amount
	float flDamage = sk_plr_dmg_gauss.GetFloat() + ( ( sk_plr_max_dmg_gauss.GetFloat() - sk_plr_dmg_gauss.GetFloat() ) * flChargeAmount );

#endif

	CBaseEntity *pHit = tr.m_pEnt;

	if ( tr.DidHitWorld() )
	{
		//Try wall penetration
		UTIL_ImpactTrace( &tr, GetAmmoDef()->DamageType(m_iPrimaryAmmoType), "ImpactGauss" );
		UTIL_DecalTrace( &tr, "RedGlowFade" );

		CPVSFilter filter( tr.endpos );
		te->GaussExplosion( filter, 0.0f, tr.endpos, tr.plane.normal, 0 );
		
		Vector	testPos = tr.endpos + ( aimDir * 48.0f );

		UTIL_TraceLine( testPos, tr.endpos, MASK_SHOT, pOwner, COLLISION_GROUP_NONE, &tr );
			
		if ( tr.allsolid == false )
		{
			UTIL_DecalTrace( &tr, "RedGlowFade" );

			penetrated = true;
		}
	}

#ifndef CLIENT_DLL
	else if ( pHit != NULL )
	{
		CTakeDamageInfo dmgInfo( this, pOwner, flDamage, DMG_SHOCK | DMG_DISSOLVE );
		CalculateBulletDamageForce( &dmgInfo, m_iPrimaryAmmoType, aimDir, tr.endpos );

		//Do direct damage to anything in our path
		pHit->DispatchTraceAttack( dmgInfo, aimDir, &tr );
	}

	ApplyMultiDamage();
#endif

	UTIL_ImpactTrace( &tr, GetAmmoDef()->DamageType(m_iPrimaryAmmoType), "ImpactGauss" );

	QAngle	viewPunch;

	viewPunch.x = random->RandomFloat( -4.0f, -8.0f );
	viewPunch.y = random->RandomFloat( -0.25f,  0.25f );
	viewPunch.z = 0;

	pOwner->ViewPunch( viewPunch );

	DrawBeam( startPos, tr.endpos, 25, true );

#ifndef CLIENT_DLL
	Vector	recoilForce = pOwner->BodyDirection2D() * -( flDamage * 10.0f );
	recoilForce[2] += 300.0f;//128

	pOwner->ApplyAbsVelocityImpulse( recoilForce );
#endif

	CPVSFilter filter( tr.endpos );
	te->GaussExplosion( filter, 0.0f, tr.endpos, tr.plane.normal, 0 );

#ifndef CLIENT_DLL
	if ( penetrated == true )
		RadiusDamage( CTakeDamageInfo( this, this, flDamage, DMG_SHOCK ), tr.endpos, 200.0f, CLASS_NONE, NULL );

	// Register a muzzleflash for the AI
	pOwner->SetMuzzleFlashTime( gpGlobals->curtime + 0.5 );
#endif
}
void CASW_Shotgun_Pellet_Predicted::PelletTouch( CBaseEntity *pOther )
{
	if (!pOther)
		return;

	if (pOther == m_pLastHit)		// don't damage the same alien twice
		return;

	if ( !pOther->IsSolid() || pOther->IsSolidFlagSet(FSOLID_VOLUME_CONTENTS) )
		return;

	// make sure we don't die on things we shouldn't
	if (!ASWGameRules() || !ASWGameRules()->ShouldCollide(GetCollisionGroup(), pOther->GetCollisionGroup()))
		return;

	if ( pOther->m_takedamage != DAMAGE_NO )
	{
		trace_t	tr, tr2;
		tr = BaseClass::GetTouchTrace();
		Vector	vecNormalizedVel = GetAbsVelocity();
		VectorNormalize( vecNormalizedVel );
#ifdef GAME_DLL
		ClearMultiDamage();		

		if( GetOwnerEntity() && GetOwnerEntity()->IsPlayer() && pOther->IsNPC() )
		{
			CTakeDamageInfo	dmgInfo( this, GetOwnerEntity(), m_flDamage, DMG_NEVERGIB );
			dmgInfo.AdjustPlayerDamageInflictedForSkillLevel();
			CalculateMeleeDamageForce( &dmgInfo, vecNormalizedVel, tr.endpos, 0.7f );
			dmgInfo.SetDamagePosition( tr.endpos );
			pOther->DispatchTraceAttack( dmgInfo, vecNormalizedVel, &tr );
		}
		else
		{
			CTakeDamageInfo	dmgInfo( this, GetOwnerEntity(), m_flDamage, DMG_BULLET | DMG_NEVERGIB );
			CalculateMeleeDamageForce( &dmgInfo, vecNormalizedVel, tr.endpos, 0.7f );
			dmgInfo.SetDamagePosition( tr.endpos );
			pOther->DispatchTraceAttack( dmgInfo, vecNormalizedVel, &tr );
		}

		ApplyMultiDamage();
#endif
		//Adrian: keep going through the glass.
		if ( pOther->GetCollisionGroup() == COLLISION_GROUP_BREAKABLE_GLASS )
			 return;

		// pellets should carry on through spawnable enemies?
		//IASW_Spawnable_NPC* pSpawnable = dynamic_cast<IASW_Spawnable_NPC*>(pOther);
		//if (pSpawnable && asw_shotgun_pellets_pass.GetBool())
		//{
			//m_pLastHit = pOther;
			//return;
		//}

		SetAbsVelocity( Vector( 0, 0, 0 ) );

		// play body "thwack" sound
		EmitSound( "Weapon_Crossbow.BoltHitBody" );

		Vector vForward;

		AngleVectors( GetAbsAngles(), &vForward );
		VectorNormalize ( vForward );

		UTIL_TraceLine( GetAbsOrigin(),	GetAbsOrigin() + vForward * 128, MASK_OPAQUE, pOther, COLLISION_GROUP_NONE, &tr2 );
#ifdef GAME_DLL
		if ( tr2.fraction != 1.0f )
		{
//			NDebugOverlay::Box( tr2.endpos, Vector( -16, -16, -16 ), Vector( 16, 16, 16 ), 0, 255, 0, 0, 10 );
//			NDebugOverlay::Box( GetAbsOrigin(), Vector( -16, -16, -16 ), Vector( 16, 16, 16 ), 0, 0, 255, 0, 10 );

			if ( tr2.m_pEnt == NULL || ( tr2.m_pEnt && tr2.m_pEnt->GetMoveType() == MOVETYPE_NONE ) )
			{
				CEffectData	data;

				data.m_vOrigin = tr2.endpos;
				data.m_vNormal = vForward;
				data.m_nEntIndex = tr2.fraction != 1.0f;
			
				//DispatchEffect( "BoltImpact", data );
			}
		}		
#endif
		SetTouch( NULL );
		SetThink( NULL );

		//KillEffects();
		//UTIL_Remove( this );
		//Release();
		SetThink( &CASW_Shotgun_Pellet_Predicted::SUB_Remove );
		SetNextThink( gpGlobals->curtime );
	}
	else
	{
		trace_t	tr;
		tr = BaseClass::GetTouchTrace();

		// See if we struck the world
		if ( pOther->GetMoveType() == MOVETYPE_NONE && !( tr.surface.flags & SURF_SKY ) )
		{
			//EmitSound( "Weapon_Crossbow.BoltHitWorld" );

			// if what we hit is static architecture, can stay around for a while.
			Vector vecDir = GetAbsVelocity();
			VectorNormalize( vecDir );
								
			SetMoveType( MOVETYPE_NONE );
		
			Vector vForward;

			AngleVectors( GetAbsAngles(), &vForward );
			VectorNormalize ( vForward );
#ifdef GAME_DLL
			CEffectData	data;

			data.m_vOrigin = tr.endpos;
			data.m_vNormal = vForward;
			data.m_nEntIndex = 0;
#endif
			//DispatchEffect( "BoltImpact", data );
			
			UTIL_ImpactTrace( &tr, DMG_BULLET );

			AddEffects( EF_NODRAW );
			SetTouch( NULL );
			//KillEffects();
			SetThink( &CASW_Shotgun_Pellet_Predicted::SUB_Remove );
			SetNextThink( gpGlobals->curtime + 2.0f );
			
			// Shoot some sparks
#ifdef GAME_DLL
			if ( UTIL_PointContents( GetAbsOrigin(), CONTENTS_WATER ) != CONTENTS_WATER)
			{
				g_pEffects->Sparks( GetAbsOrigin() );
			}
#endif
		}
		else
		{
			// Put a mark unless we've hit the sky
			if ( ( tr.surface.flags & SURF_SKY ) == false )
			{
				UTIL_ImpactTrace( &tr, DMG_BULLET );
			}
			//KillEffects();
			//UTIL_Remove( this );
			//Release();
			SetThink( &CASW_Shotgun_Pellet_Predicted::SUB_Remove );
			SetNextThink( gpGlobals->curtime );
		}
	}
}
예제 #23
0
//Called from PhysicsSimulate() or ReceiveMessage()
bool CDHLProjectile::OnTouch( trace_t &touchtr, bool bDecalOnly /*= false*/, ITraceFilter* pTraceFilter /*= NULL*/ )
{
	//Direction
	Vector vecDir = touchtr.endpos - touchtr.startpos;
	if ( vecDir == vec3_origin ) //Sometimes endpos==startpos so we need to get dir from velocity instead
	{
		#ifdef CLIENT_DLL
			vecDir = GetLocalVelocity();
		#else
			vecDir = m_vecCurVelocity;
		#endif
		VectorNormalize( vecDir );
	}

	CBaseEntity* ent = touchtr.m_pEnt;
	if ( !ent )
		return false;

	if ( touchtr.DidHit() )
	{
		//Never collide with self, shooter, or other projectiles
		if ( ent == this || dynamic_cast<CDHLProjectile*>(ent)
			|| ent == (CBaseEntity*)m_pShooter )
			//|| ( (m_iType == DHL_PROJECTILE_TYPE_COMBATKNIFE) && (ent == m_pFiringWeapon) ) ) //Combat knife - don't collide with weapon ent
			return false;

		//Hack: Sometimes hits are registered prematurely (usually to the torso area) with no hitbox.  Pretend nothing happened unless one is found.
		if ( ent->IsPlayer() && touchtr.hitgroup == 0 )
			return false;

		//Check friendly fire
		if ( CheckFriendlyFire( ent ) )
		{
			if ( !bDecalOnly )
			{
				ClearMultiDamage();

				//Do damage
				CTakeDamageInfo	dmgInfo( this, GetOwnerEntity(), m_iDamage, DMG_BULLET  );
				if ( m_iType == DHL_PROJECTILE_TYPE_COMBATKNIFE )
				{
					//CalculateMeleeDamageForce( &dmgInfo, vecDir, touchtr.endpos, 0.01f );
					Vector vecForce = vecDir;
					VectorNormalize( vecForce );
					//vecForce *= 10.0f; //Ripped from C_ClientRagdoll::ImpactTrace
					dmgInfo.SetDamageForce( vecForce );

					#ifndef CLIENT_DLL
						if ( IsOnFire() )
						{
							CBaseAnimating* pBAnim = dynamic_cast<CBaseAnimating*>(ent);
							if ( pBAnim )
								pBAnim->Ignite( 10.0f, false );
						}
					#endif
				}
				else
					CalculateBulletDamageForce( &dmgInfo, m_iAmmoType, vecDir, touchtr.endpos, 1.0f );
				dmgInfo.SetDamagePosition( touchtr.endpos );
				ent->DispatchTraceAttack( dmgInfo, vecDir, &touchtr );
				ApplyMultiDamage();
			}

			#ifdef CLIENT_DLL
				if ( ent->GetCollisionGroup() == COLLISION_GROUP_BREAKABLE_GLASS )
					return false;

				//Decals and such
				if ( !( touchtr.surface.flags & SURF_SKY ) && !touchtr.allsolid )
				{
					IPredictionSystem::SuppressEvents( false );
					if ( (m_iType == DHL_PROJECTILE_TYPE_BULLET || m_iType == DHL_PROJECTILE_TYPE_PELLET) )
					{
						UTIL_ImpactTrace( &touchtr, DMG_BULLET );
					}
					if ( m_iType == DHL_PROJECTILE_TYPE_COMBATKNIFE )
						PlayImpactSound( touchtr.m_pEnt, touchtr, touchtr.endpos, touchtr.surface.surfaceProps );
					IPredictionSystem::SuppressEvents( !prediction->IsFirstTimePredicted() );
				}
			#endif
		}

		if ( pTraceFilter && m_iType != DHL_PROJECTILE_TYPE_COMBATKNIFE )
		{
			PenetrationData_t nPenetrationData = DHLShared::TestPenetration( touchtr, m_pShooter, pTraceFilter, 
				m_iTimesPenetrated, m_flDistanceTravelled, m_iAmmoType );
			if ( nPenetrationData.m_bShouldPenetrate )
			{
				m_flDistanceTravelled += GetLocalOrigin().DistTo( nPenetrationData.m_vecNewBulletPos );
				MoveProjectileToPosition( nPenetrationData.m_vecNewBulletPos );
				m_iTimesPenetrated++;
				return true; //Keep going - but don't do anything else in this frame of PhysicsSimulate()
			}
		}
	
		//We're done unless what we hit was breakable glass
		if ( ent->GetCollisionGroup() != COLLISION_GROUP_BREAKABLE_GLASS )
		{
			#ifdef CLIENT_DLL
				m_bCollided = true;
				AddEffects( EF_NODRAW );
				if ( m_pTrail ) //NULL pointer here sometimes somehow...
					m_pTrail->AddEffects( EF_NODRAW );
			#else
				EntityMessageBegin( this );
					WRITE_BYTE( MSG_NOTIFY_REMOVAL );
				MessageEnd();
				
				if ( touchtr.DidHitWorld() && m_iType == DHL_PROJECTILE_TYPE_COMBATKNIFE && !( touchtr.surface.flags & SURF_SKY ) )
				{
					CBaseCombatWeapon* pKnifeEnt = assert_cast<CBaseCombatWeapon*>(CreateEntityByName( "weapon_combatknife" ));
					if ( pKnifeEnt )
					{
						pKnifeEnt->AddSpawnFlags( SF_NORESPAWN ); //Needed for weapon spawn & VPhysics setup to work correctly
						pKnifeEnt->SetAbsOrigin( touchtr.endpos );
						QAngle angles = vec3_angle;
						Vector vecKnifeDir = touchtr.startpos - touchtr.endpos;
						VectorAngles( vecKnifeDir, angles );
						angles[PITCH] -= 15.0f; //Correct for the .mdl being offset a bit
						pKnifeEnt->SetLocalAngles( angles );
						DispatchSpawn( pKnifeEnt );

						//Spawns vphys object and sets it up, essentially a copy of CWeaponHL2MPBase::FallInit()
						pKnifeEnt->VPhysicsDestroyObject();
						//Using SOLID_VPHYSICS instead of SOLID_BBOX (as ordinary weapons do) helps resolve some of the client side collision oddities
						Assert( pKnifeEnt->VPhysicsInitNormal( SOLID_VPHYSICS, FSOLID_NOT_STANDABLE | FSOLID_TRIGGER, true ) );
						pKnifeEnt->SetPickupTouch(); //Sets up automagic removal after time
						IPhysicsObject* pKnifePhys = pKnifeEnt->VPhysicsGetObject();
						if ( pKnifePhys )
						{
							//Knives are solid to bullets...the only way to make them non-solid to bullets is to do SetSolid( SOLID_NONE ) or AddSolidFlags( FSOLID_NOT_SOLID )
							//which breaks the +use pickup even with FSOLID_TRIGGER set.  Let's just call it a feature :)
							pKnifePhys->EnableMotion( false );
							pKnifePhys->EnableCollisions( false );
						}

						if ( IsOnFire() )
							pKnifeEnt->Ignite( 10.0f, false );
					}
				}

				//SetThink( &CDHLProjectile::SUB_Remove );
				//SetNextThink( gpGlobals->curtime + 0.1 );
				//SUB_Remove();
				//SetMoveType( MOVETYPE_NONE );
				m_flRemoveAt = gpGlobals->curtime + 0.1f; //Give the notification message a head start so that the client will have time to react
			#endif
		}
	}
	return true;
}
예제 #24
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CASW_PropJeep::FireChargedCannon( void )
{
	bool penetrated = false;

	m_bCannonCharging	= false;
	m_flCannonTime		= gpGlobals->curtime + 0.5f;

	StopChargeSound();

	CPASAttenuationFilter sndFilter( this, "PropJeep.FireChargedCannon" );
	EmitSound( sndFilter, entindex(), "PropJeep.FireChargedCannon" );

	//Find the direction the gun is pointing in
	Vector aimDir;
	GetCannonAim( &aimDir );

	Vector endPos = m_vecGunOrigin + ( aimDir * MAX_TRACE_LENGTH );
	
	//Shoot a shot straight out
	trace_t	tr;
	UTIL_TraceLine( m_vecGunOrigin, endPos, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr );
	
	ClearMultiDamage();

	//Find how much damage to do
	float flChargeAmount = ( gpGlobals->curtime - m_flCannonChargeStartTime ) / MAX_GAUSS_CHARGE_TIME;

	//Clamp this
	if ( flChargeAmount > 1.0f )
	{
		flChargeAmount = 1.0f;
	}

	//Determine the damage amount
	//FIXME: Use ConVars!
	float flDamage = 15 + ( ( 250 - 15 ) * flChargeAmount );

	CBaseEntity *pHit = tr.m_pEnt;
	
	//Look for wall penetration
	if ( tr.DidHitWorld() && !(tr.surface.flags & SURF_SKY) )
	{
		//Try wall penetration
		UTIL_ImpactTrace( &tr, m_nBulletType, "ImpactJeep" );
		UTIL_DecalTrace( &tr, "RedGlowFade" );

		CPVSFilter filter( tr.endpos );
		te->GaussExplosion( filter, 0.0f, tr.endpos, tr.plane.normal, 0 );
		
		Vector	testPos = tr.endpos + ( aimDir * 48.0f );

		UTIL_TraceLine( testPos, tr.endpos, MASK_SHOT, GetDriver(), COLLISION_GROUP_NONE, &tr );
			
		if ( tr.allsolid == false )
		{
			UTIL_DecalTrace( &tr, "RedGlowFade" );

			penetrated = true;
		}
	}
	else if ( pHit != NULL )
	{
		CTakeDamageInfo dmgInfo( this, GetDriver(), flDamage, DMG_SHOCK );
		CalculateBulletDamageForce( &dmgInfo, GetAmmoDef()->Index("GaussEnergy"), aimDir, tr.endpos, 1.0f + flChargeAmount * 4.0f );

		//Do direct damage to anything in our path
		pHit->DispatchTraceAttack( dmgInfo, aimDir, &tr );
	}

	ApplyMultiDamage();

	//Kick up an effect
	if ( !(tr.surface.flags & SURF_SKY) )
	{
  		UTIL_ImpactTrace( &tr, m_nBulletType, "ImpactJeep" );

		//Do a gauss explosion
		CPVSFilter filter( tr.endpos );
		te->GaussExplosion( filter, 0.0f, tr.endpos, tr.plane.normal, 0 );
	}

	//Show the effect
	DrawBeam( m_vecGunOrigin, tr.endpos, 9.6 );

	// Register a muzzleflash for the AI
	if ( m_hPlayer )
	{
		m_hPlayer->SetMuzzleFlashTime( gpGlobals->curtime + 0.5f );
	}

	//Rock the car
	IPhysicsObject *pObj = VPhysicsGetObject();

	if ( pObj != NULL )
	{
		Vector	shoveDir = aimDir * -( flDamage * 500.0f );

		pObj->ApplyForceOffset( shoveDir, m_vecGunOrigin );
	}

	//Do radius damage if we didn't penetrate the wall
	if ( penetrated == true )
	{
		RadiusDamage( CTakeDamageInfo( this, this, flDamage, DMG_SHOCK ), tr.endpos, 200.0f, CLASS_NONE, NULL );
	}
}
void CASW_Flamer_Projectile::FlameHit( CBaseEntity *pOther, const Vector &vecHitPos, bool bOnlyHurtUnignited )
{
	if (!pOther)
		return;

	bool bHurt = true;

	if ( pOther->m_takedamage != DAMAGE_NO)
	{
		if ( pOther == m_pLastHitEnt )
			return;

		if ( bOnlyHurtUnignited)
		{
			CBaseAnimating* pAnim = dynamic_cast<CBaseAnimating*>(pOther);
			if ( pAnim && pAnim->IsOnFire() )
			{
				bHurt = false;
			}
		}

		if ( bHurt )
		{
			Vector	vecNormalizedVel = GetAbsVelocity();

			ClearMultiDamage();
			VectorNormalize( vecNormalizedVel );

			if( GetOwnerEntity() && GetOwnerEntity()->IsPlayer() && pOther->IsNPC() )
			{
				CTakeDamageInfo	dmgInfo( this, m_pGetsCreditedForDamage, m_flDamage, DMG_BURN );
				dmgInfo.AdjustPlayerDamageInflictedForSkillLevel();
				CalculateMeleeDamageForce( &dmgInfo, vecNormalizedVel, vecHitPos, asw_flamer_force.GetFloat() );
				dmgInfo.SetDamagePosition( vecHitPos );
				dmgInfo.SetWeapon( m_hCreatorWeapon.Get() );

				pOther->TakeDamage(dmgInfo);
			}
			else
			{
				CTakeDamageInfo	dmgInfo( this, m_pGetsCreditedForDamage, m_flDamage, DMG_BURN );
				CalculateMeleeDamageForce( &dmgInfo, vecNormalizedVel, vecHitPos, asw_flamer_force.GetFloat() );
				dmgInfo.SetDamagePosition( vecHitPos );
				dmgInfo.SetWeapon( m_hCreatorWeapon.Get() );

				pOther->TakeDamage(dmgInfo);
			}

			ApplyMultiDamage();

			// keep going through normal entities?
			m_pLastHitEnt = pOther;
		}

		if ( pOther->Classify() == CLASS_ASW_SHIELDBUG )	// We also want to bounce off shield bugs
		{
			Vector vel = GetAbsVelocity();
			Vector dir = vel;
			VectorNormalize( dir );

			// reflect velocity around normal
			vel = -2.0f * dir + vel;
			vel *= 0.4f;

			// absorb 80% in impact
			SetAbsVelocity( vel );
		}

		return;
	}

	if ( pOther->GetCollisionGroup() == ASW_COLLISION_GROUP_PASSABLE )
		return;

	trace_t	tr;
	tr = BaseClass::GetTouchTrace();

	// See if we struck the world
	if ( pOther->GetMoveType() == MOVETYPE_NONE && !( tr.surface.flags & SURF_SKY ) )
	{
		Vector vel = GetAbsVelocity();
		if ( tr.startsolid )
		{
			if ( !m_inSolid )
			{
				// UNDONE: Do a better contact solution that uses relative velocity?
				vel *= -1.0f; // bounce backwards
				SetAbsVelocity(vel);
			}
			m_inSolid = true;
			return;
		}
		m_inSolid = false;
		if ( tr.DidHit() )
		{
			Vector dir = vel;
			VectorNormalize(dir);

			// reflect velocity around normal
			vel = -2.0f * tr.plane.normal * DotProduct(vel,tr.plane.normal) + vel;
			vel *= 0.4f;
			
			// absorb 80% in impact
			//vel *= GRENADE_COEFFICIENT_OF_RESTITUTION;
			SetAbsVelocity( vel );
		}
		return;
	}
	else
	{
		// Put a mark unless we've hit the sky
		if ( ( tr.surface.flags & SURF_SKY ) == false )
		{
			UTIL_ImpactTrace( &tr, DMG_BURN );
		}
		KillEffects();
		UTIL_Remove( this );
	}
}
void CDODPlayer::FireBullets( const FireBulletsInfo_t &info )
{
	trace_t			tr;								
	trace_t			reverseTr;						//Used to find exit points
	static int		iMaxPenetrations	= 6;
	int				iPenetrations		= 0;
	float			flDamage			= info.m_iDamage;		//Remaining damage in the bullet
	Vector			vecSrc				= info.m_vecSrc;
	Vector			vecEnd				= vecSrc + info.m_vecDirShooting * info.m_flDistance;

	static int		iTraceMask = ( ( MASK_SOLID | CONTENTS_DEBRIS | CONTENTS_HITBOX | CONTENTS_PRONE_HELPER ) & ~CONTENTS_GRATE );
	 
	CBaseEntity		*pLastHitEntity		= this;	// start with us so we don't trace ourselves
		
	int iDamageType = GetAmmoDef()->DamageType( info.m_iAmmoType );
	int iCollisionGroup = COLLISION_GROUP_NONE;

#ifdef GAME_DLL
	bool iNumHeadshots = 0;
#endif

	while ( flDamage > 0 && iPenetrations < iMaxPenetrations )
	{
		//DevMsg( 2, "penetration: %d, starting dmg: %.1f\n", iPenetrations, flDamage );

		CBaseEntity *pPreviousHit = pLastHitEntity;

		// skip the shooter always
		CTraceFilterSkipTwoEntities ignoreShooterAndPrevious( this, pPreviousHit, iCollisionGroup );
		UTIL_TraceLine( vecSrc, vecEnd, iTraceMask, &ignoreShooterAndPrevious, &tr );

		const float rayExtension = 40.0f;
		UTIL_ClipTraceToPlayers( vecSrc, vecEnd + info.m_vecDirShooting * rayExtension, iTraceMask, &ignoreShooterAndPrevious, &tr );

		if ( tr.fraction == 1.0f )
			break; // we didn't hit anything, stop tracing shoot

		// New hitbox code that uses hitbox groups instead of trying to trace
		// through the player
		if ( tr.m_pEnt && tr.m_pEnt->IsPlayer() )
		{
			switch( tr.hitgroup )
			{
#ifdef GAME_DLL
			case HITGROUP_HEAD:
				{
					if ( tr.m_pEnt->GetTeamNumber() != GetTeamNumber() )
					{
						iNumHeadshots++;
					}
				}
				break;
#endif

			case HITGROUP_LEFTARM:
			case HITGROUP_RIGHTARM:
				{
					//DevMsg( 2, "Hit arms, tracing against alt hitboxes.. \n" );

					CDODPlayer *pPlayer = ToDODPlayer( tr.m_pEnt );

					// set hitbox set to "dod_no_arms"
					pPlayer->SetHitboxSet( 1 );

					trace_t newTr;

					// re-fire the trace
					UTIL_TraceLine( vecSrc, vecEnd, iTraceMask, &ignoreShooterAndPrevious, &newTr );

					// if we hit the same player in the chest
					if ( tr.m_pEnt == newTr.m_pEnt )
					{
						//DevMsg( 2, ".. and we hit the chest.\n" );

						Assert( tr.hitgroup != newTr.hitgroup );	// If we hit this, hitbox sets are broken

						// use that damage instead
						tr = newTr;
					}

					// set hitboxes back to "dod"
					pPlayer->SetHitboxSet( 0 );
				}
				break;

			default:
				break;
			}			
		}
			
		pLastHitEntity = tr.m_pEnt;

		if ( sv_showimpacts.GetBool() )
		{
#ifdef CLIENT_DLL
			// draw red client impact markers
			debugoverlay->AddBoxOverlay( tr.endpos, Vector(-1,-1,-1), Vector(1,1,1), QAngle(0,0,0), 255, 0, 0, 127, 4 );

			if ( tr.m_pEnt && tr.m_pEnt->IsPlayer() )
			{
				C_BasePlayer *player = ToBasePlayer( tr.m_pEnt );
				player->DrawClientHitboxes( 4, true );
			}
#else
			// draw blue server impact markers
			NDebugOverlay::Box( tr.endpos, Vector(-1,-1,-1), Vector(1,1,1), 0,0,255,127, 4 );

			if ( tr.m_pEnt && tr.m_pEnt->IsPlayer() )
			{
				CBasePlayer *player = ToBasePlayer( tr.m_pEnt );
				player->DrawServerHitboxes( 4, true );
			}
#endif
		}

#ifdef CLIENT_DLL
		// See if the bullet ended up underwater + started out of the water
		if ( enginetrace->GetPointContents( tr.endpos ) & (CONTENTS_WATER|CONTENTS_SLIME) )
		{	
			trace_t waterTrace;
			UTIL_TraceLine( vecSrc, tr.endpos, (MASK_SHOT|CONTENTS_WATER|CONTENTS_SLIME), this, iCollisionGroup, &waterTrace );
			
			if( waterTrace.allsolid != 1 )
			{
				CEffectData	data;
 				data.m_vOrigin = waterTrace.endpos;
				data.m_vNormal = waterTrace.plane.normal;
				data.m_flScale = random->RandomFloat( 8, 12 );

				if ( waterTrace.contents & CONTENTS_SLIME )
				{
					data.m_fFlags |= FX_WATER_IN_SLIME;
				}

				DispatchEffect( "gunshotsplash", data );
			}
		}
		else
		{
			//Do Regular hit effects

			// Don't decal nodraw surfaces
			if ( !( tr.surface.flags & (SURF_SKY|SURF_NODRAW|SURF_HINT|SURF_SKIP) ) )
			{
				CBaseEntity *pEntity = tr.m_pEnt;
				if ( !( !friendlyfire.GetBool() && pEntity && pEntity->GetTeamNumber() == GetTeamNumber() ) )
				{
					UTIL_ImpactTrace( &tr, iDamageType );
				}
			}
		}
#endif

		// Get surface where the bullet entered ( if it had different surfaces on enter and exit )
		surfacedata_t *pSurfaceData = physprops->GetSurfaceData( tr.surface.surfaceProps );
		Assert( pSurfaceData );
		
		float flMaterialMod = GetDensityFromMaterial(pSurfaceData);

		if ( iDamageType & DMG_MACHINEGUN )
		{
			flMaterialMod *= 0.65;
		}

		// try to penetrate object
		Vector penetrationEnd;
		float flMaxDistance = flDamage / flMaterialMod;

#ifndef CLIENT_DLL
		ClearMultiDamage();

		float flActualDamage = flDamage;

		CTakeDamageInfo dmgInfo( info.m_pAttacker, info.m_pAttacker, flActualDamage, iDamageType );
		CalculateBulletDamageForce( &dmgInfo, info.m_iAmmoType, info.m_vecDirShooting, tr.endpos );
		tr.m_pEnt->DispatchTraceAttack( dmgInfo, info.m_vecDirShooting, &tr );

		DevMsg( 2, "Giving damage ( %.1f ) to entity of type %s\n", flActualDamage, tr.m_pEnt->GetClassname() );

		TraceAttackToTriggers( dmgInfo, tr.startpos, tr.endpos, info.m_vecDirShooting );
#endif

		int stepsize = 16;

		// displacement always stops the bullet
		if ( tr.IsDispSurface() )
		{
			DevMsg( 2, "bullet was stopped by displacement\n" );
			ApplyMultiDamage();
			break;
		}

		// trace through the solid to find the exit point and how much material we went through
		if ( !TraceToExit( tr.endpos, info.m_vecDirShooting, penetrationEnd, stepsize, flMaxDistance ) )
		{
			DevMsg( 2, "bullet was stopped\n" );
			ApplyMultiDamage();
			break;
		}

		// find exact penetration exit
		CTraceFilterSimple ignoreShooter( this, iCollisionGroup );
		UTIL_TraceLine( penetrationEnd, tr.endpos, iTraceMask, &ignoreShooter, &reverseTr );

		// Now we can apply the damage, after we have traced the entity
		// so it doesn't break or die before we have a change to test against it
#ifndef CLIENT_DLL
		ApplyMultiDamage();
#endif

		// Continue looking for the exit point
		if( reverseTr.m_pEnt != tr.m_pEnt && reverseTr.m_pEnt != NULL )
		{
			// something was blocking, trace again
			CTraceFilterSkipTwoEntities ignoreShooterAndBlocker( this, reverseTr.m_pEnt, iCollisionGroup );
			UTIL_TraceLine( penetrationEnd, tr.endpos, iTraceMask, &ignoreShooterAndBlocker, &reverseTr );
		}

		if ( sv_showimpacts.GetBool() )
		{
			debugoverlay->AddLineOverlay( penetrationEnd, reverseTr.endpos, 255, 0, 0, true, 3.0 );
		}

		// penetration was successful

#ifdef CLIENT_DLL
		// bullet did penetrate object, exit Decal
		if ( !( reverseTr.surface.flags & (SURF_SKY|SURF_NODRAW|SURF_HINT|SURF_SKIP) ) )
		{
			CBaseEntity *pEntity = reverseTr.m_pEnt;
			if ( !( !friendlyfire.GetBool() && pEntity && pEntity->GetTeamNumber() == GetTeamNumber() ) )
			{
				UTIL_ImpactTrace( &reverseTr, iDamageType );
			}
		}
#endif

		//setup new start end parameters for successive trace

		// New start point is our last exit point
		vecSrc = reverseTr.endpos + /* 1.0 * */ info.m_vecDirShooting;

		// Reduce bullet damage by material and distanced travelled through that material
		// if it is < 0 we won't go through the loop again
		float flTraceDistance = VectorLength( reverseTr.endpos - tr.endpos );
		
		flDamage -= flMaterialMod * flTraceDistance;

		if( flDamage > 0 )
		{
			DevMsg( 2, "Completed penetration, new damage is %.1f\n", flDamage );
		}
		else
		{
			DevMsg( 2, "bullet was stopped\n" );
		}

		iPenetrations++;
	}

#ifdef GAME_DLL
	HandleHeadshotAchievement( iNumHeadshots );
#endif
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponGrapple::PrimaryAttack( void )
{
	// Can't have an active hook out
	if ( m_hHook != NULL )
		return;
 
	#ifndef CLIENT_DLL
	CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );

	if ( !pPlayer )
	{
		return;
	}

	if ( m_iClip1 <= 0 )
	{
		if ( !m_bFireOnEmpty )
		{
			Reload();
		}
		else
		{
			WeaponSound( EMPTY );
			m_flNextPrimaryAttack = 0.15;
		}

		return;
	}

	m_iPrimaryAttacks++;
	gamestats->Event_WeaponFired( pPlayer, true, GetClassname() );

	WeaponSound( SINGLE );
	pPlayer->DoMuzzleFlash();

	SendWeaponAnim( ACT_VM_PRIMARYATTACK );
	pPlayer->SetAnimation( PLAYER_ATTACK1 );

	m_flNextPrimaryAttack = gpGlobals->curtime + 0.75;
	m_flNextSecondaryAttack = gpGlobals->curtime + 0.75;

	//Disabled so we can shoot all the time that we want
	//m_iClip1--;

	Vector vecSrc		= pPlayer->Weapon_ShootPosition();
	Vector vecAiming	= pPlayer->GetAutoaimVector( AUTOAIM_SCALE_DEFAULT );	

	//We will not shoot bullets anymore
	//pPlayer->FireBullets( 1, vecSrc, vecAiming, vec3_origin, MAX_TRACE_LENGTH, m_iPrimaryAmmoType, 0 );

	pPlayer->SetMuzzleFlashTime( gpGlobals->curtime + 0.5 );

	CSoundEnt::InsertSound( SOUND_COMBAT, GetAbsOrigin(), 600, 0.2, GetOwner() );

	if ( !m_iClip1 && pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) <= 0 )
	{
		// HEV suit - indicate out of ammo condition
		pPlayer->SetSuitUpdate( "!HEV_AMO0", FALSE, 0 ); 
	}

	trace_t tr;
	Vector vecShootOrigin, vecShootDir, vecDir, vecEnd;

	//Gets the direction where the player is aiming
	AngleVectors (pPlayer->EyeAngles(), &vecDir);

	//Gets the position of the player
	vecShootOrigin = pPlayer->Weapon_ShootPosition();

	//Gets the position where the hook will hit
	vecEnd	= vecShootOrigin + (vecDir * MAX_TRACE_LENGTH);	
	
	//Traces a line between the two vectors
	UTIL_TraceLine( vecShootOrigin, vecEnd, MASK_SHOT, pPlayer, COLLISION_GROUP_NONE, &tr);

	//Draws the beam
	DrawBeam( vecShootOrigin, tr.endpos, 15.5 );

	//Creates an energy impact effect if we don't hit the sky or other places
	if ( (tr.surface.flags & SURF_SKY) == false )
	{
		CPVSFilter filter( tr.endpos );
		te->GaussExplosion( filter, 0.0f, tr.endpos, tr.plane.normal, 0 );
		m_nBulletType = GetAmmoDef()->Index("GaussEnergy");
		UTIL_ImpactTrace( &tr, m_nBulletType );

		//Makes a sprite at the end of the beam
		m_pLightGlow = CSprite::SpriteCreate( "sprites/physcannon_bluecore2b.vmt", GetAbsOrigin(), TRUE);

		//Sets FX render and color
		m_pLightGlow->SetTransparency( 9, 255, 255, 255, 200, kRenderFxNoDissipation );
		
		//Sets the position
		m_pLightGlow->SetAbsOrigin(tr.endpos);
		
		//Bright
		m_pLightGlow->SetBrightness( 255 );
		
		//Scale
		m_pLightGlow->SetScale( 0.65 );
	}
	#endif

	FireHook();
 
	SetWeaponIdleTime( gpGlobals->curtime + SequenceDuration( ACT_VM_PRIMARYATTACK ) );
}
예제 #28
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : *pOther - 
//-----------------------------------------------------------------------------
void CCrossbowBolt::BoltTouch( CBaseEntity *pOther )
{
	if ( !pOther->IsSolid() || pOther->IsSolidFlagSet(FSOLID_VOLUME_CONTENTS) )
		return;

	if ( pOther->m_takedamage != DAMAGE_NO )
	{
		trace_t	tr, tr2;
		tr = BaseClass::GetTouchTrace();
		Vector	vecNormalizedVel = GetAbsVelocity();

		ClearMultiDamage();
		VectorNormalize( vecNormalizedVel );

		if( GetOwnerEntity() && GetOwnerEntity()->IsPlayer() && pOther->IsNPC() )
		{
			CTakeDamageInfo	dmgInfo( this, GetOwnerEntity(), m_iDamage, DMG_NEVERGIB );
			dmgInfo.AdjustPlayerDamageInflictedForSkillLevel();
			CalculateMeleeDamageForce( &dmgInfo, vecNormalizedVel, tr.endpos, 0.7f );
			dmgInfo.SetDamagePosition( tr.endpos );
			pOther->DispatchTraceAttack( dmgInfo, vecNormalizedVel, &tr );
		}
		else
		{
			CTakeDamageInfo	dmgInfo( this, GetOwnerEntity(), m_iDamage, DMG_BULLET | DMG_NEVERGIB );
			CalculateMeleeDamageForce( &dmgInfo, vecNormalizedVel, tr.endpos, 0.7f );
			dmgInfo.SetDamagePosition( tr.endpos );
			pOther->DispatchTraceAttack( dmgInfo, vecNormalizedVel, &tr );
		}

		ApplyMultiDamage();

		//Adrian: keep going through the glass.
		if ( pOther->GetCollisionGroup() == COLLISION_GROUP_BREAKABLE_GLASS )
			 return;

		SetAbsVelocity( Vector( 0, 0, 0 ) );

		// play body "thwack" sound
		EmitSound( "Weapon_Crossbow.BoltHitBody" );

		Vector vForward;

		AngleVectors( GetAbsAngles(), &vForward );
		VectorNormalize ( vForward );

		UTIL_TraceLine( GetAbsOrigin(),	GetAbsOrigin() + vForward * 128, MASK_OPAQUE, pOther, COLLISION_GROUP_NONE, &tr2 );

		if ( tr2.fraction != 1.0f )
		{
//			NDebugOverlay::Box( tr2.endpos, Vector( -16, -16, -16 ), Vector( 16, 16, 16 ), 0, 255, 0, 0, 10 );
//			NDebugOverlay::Box( GetAbsOrigin(), Vector( -16, -16, -16 ), Vector( 16, 16, 16 ), 0, 0, 255, 0, 10 );

			if ( tr2.m_pEnt == NULL || ( tr2.m_pEnt && tr2.m_pEnt->GetMoveType() == MOVETYPE_NONE ) )
			{
				CEffectData	data;

				data.m_vOrigin = tr2.endpos;
				data.m_vNormal = vForward;
				data.m_nEntIndex = tr2.fraction != 1.0f;
			
				DispatchEffect( "BoltImpact", data );
			}
		}
		
		SetTouch( NULL );
		SetThink( NULL );

		UTIL_Remove( this );
	}
	else
	{
		trace_t	tr;
		tr = BaseClass::GetTouchTrace();

		// See if we struck the world
		if ( pOther->GetMoveType() == MOVETYPE_NONE && !( tr.surface.flags & SURF_SKY ) )
		{
			EmitSound( "Weapon_Crossbow.BoltHitWorld" );

			// if what we hit is static architecture, can stay around for a while.
			Vector vecDir = GetAbsVelocity();
			float speed = VectorNormalize( vecDir );

			// See if we should reflect off this surface
			float hitDot = DotProduct( tr.plane.normal, -vecDir );
			
			if ( ( hitDot < 0.5f ) && ( speed > 100 ) )
			{
				Vector vReflection = 2.0f * tr.plane.normal * hitDot + vecDir;
				
				QAngle reflectAngles;

				VectorAngles( vReflection, reflectAngles );

				SetLocalAngles( reflectAngles );

				SetAbsVelocity( vReflection * speed * 0.75f );

				// Start to sink faster
				SetGravity( 1.0f );
			}
			else
			{
				SetThink( &CCrossbowBolt::SUB_Remove );
				SetNextThink( gpGlobals->curtime + 2.0f );
				
				//FIXME: We actually want to stick (with hierarchy) to what we've hit
				SetMoveType( MOVETYPE_NONE );
			
				Vector vForward;

				AngleVectors( GetAbsAngles(), &vForward );
				VectorNormalize ( vForward );

				CEffectData	data;

				data.m_vOrigin = tr.endpos;
				data.m_vNormal = vForward;
				data.m_nEntIndex = 0;
			
				DispatchEffect( "BoltImpact", data );
				
				UTIL_ImpactTrace( &tr, DMG_BULLET );

				AddEffects( EF_NODRAW );
				SetTouch( NULL );
				SetThink( &CCrossbowBolt::SUB_Remove );
				SetNextThink( gpGlobals->curtime + 2.0f );

				if ( m_pGlowSprite != NULL )
				{
					m_pGlowSprite->TurnOn();
					m_pGlowSprite->FadeAndDie( 3.0f );
				}
			}
			
			// Shoot some sparks
			if ( UTIL_PointContents( GetAbsOrigin() ) != CONTENTS_WATER)
			{
				g_pEffects->Sparks( GetAbsOrigin() );
			}
		}
		else
		{
			// Put a mark unless we've hit the sky
			if ( ( tr.surface.flags & SURF_SKY ) == false )
			{
				UTIL_ImpactTrace( &tr, DMG_BULLET );
			}

			UTIL_Remove( this );
		}
	}

	if ( g_pGameRules->IsMultiplayer() )
	{
//		SetThink( &CCrossbowBolt::ExplodeThink );
//		SetNextThink( gpGlobals->curtime + 0.1f );
	}
}
//=========================================================
// Disparo
//=========================================================
void CWeaponGaussGun::Fire()
{
	CBasePlayer *pOwner = ToBasePlayer(GetOwner());
	
	// ¿El jugador no ha sido creado?
	if ( !pOwner )
		return;

	m_bCharging = false;

	if ( m_hViewModel == NULL )
	{
		CBaseViewModel *vm = pOwner->GetViewModel();

		if ( vm )
			m_hViewModel.Set(vm);
	}

	Vector	startPos	= pOwner->Weapon_ShootPosition();
	Vector	aimDir		= pOwner->GetAutoaimVector(AUTOAIM_5DEGREES);

	Vector vecUp, vecRight;
	VectorVectors(aimDir, vecRight, vecUp);

	float x, y, z;

	//Gassian spread
	do {
		x = random->RandomFloat(-0.5,0.5) + random->RandomFloat(-0.5,0.5);
		y = random->RandomFloat(-0.5,0.5) + random->RandomFloat(-0.5,0.5);
		z = x*x+y*y;
	} while (z > 1);

	aimDir			= aimDir + x * GetBulletSpread().x * vecRight + y * GetBulletSpread().y * vecUp;
	Vector endPos	= startPos + (aimDir * MAX_TRACE_LENGTH);
	
	// Shoot a shot straight out
	trace_t	tr;
	UTIL_TraceLine(startPos, endPos, MASK_SHOT, pOwner, COLLISION_GROUP_NONE, &tr);
	
#ifndef CLIENT_DLL

	ClearMultiDamage();

	CBaseEntity *pHit = tr.m_pEnt;	
	CTakeDamageInfo dmgInfo(this, pOwner, sk_plr_dmg_gauss.GetFloat(), DMG_SHOCK | DMG_DISSOLVE);

	if ( pHit != NULL )
	{
		CalculateBulletDamageForce(&dmgInfo, m_iPrimaryAmmoType, aimDir, tr.endpos);
		pHit->DispatchTraceAttack(dmgInfo, aimDir, &tr);
	}
	
	if ( tr.DidHitWorld() )
	{
		float hitAngle = -DotProduct( tr.plane.normal, aimDir );

		if ( hitAngle < 0.5f )
		{
			Vector vReflection;
		
			vReflection = 2.0 * tr.plane.normal * hitAngle + aimDir;			
			startPos	= tr.endpos;
			endPos		= startPos + (vReflection * MAX_TRACE_LENGTH);
			
			// Draw beam to reflection point
			DrawBeam(tr.startpos, tr.endpos, 15, true);

			CPVSFilter filter(tr.endpos);
			te->GaussExplosion(filter, 0.0f, tr.endpos, tr.plane.normal, 0);

			UTIL_ImpactTrace(&tr, GetAmmoDef()->DamageType(m_iPrimaryAmmoType), "ImpactGauss");

			//Find new reflection end position
			UTIL_TraceLine(startPos, endPos, MASK_SHOT, pOwner, COLLISION_GROUP_NONE, &tr);

			if ( tr.m_pEnt != NULL )
			{
				dmgInfo.SetDamageForce(GetAmmoDef()->DamageForce(m_iPrimaryAmmoType) * vReflection);
				dmgInfo.SetDamagePosition(tr.endpos);
				tr.m_pEnt->DispatchTraceAttack(dmgInfo, vReflection, &tr);
			}

			// Connect reflection point to end
			DrawBeam(tr.startpos, tr.endpos, 10);
		}
		else
			DrawBeam(tr.startpos, tr.endpos, 15, true);
	}
	else
		DrawBeam(tr.startpos, tr.endpos, 15, true);
	
	ApplyMultiDamage();

#endif

	UTIL_ImpactTrace(&tr, GetAmmoDef()->DamageType(m_iPrimaryAmmoType), "ImpactGauss");

	CPVSFilter filter(tr.endpos);
	te->GaussExplosion(filter, 0.0f, tr.endpos, tr.plane.normal, 0);

	m_flNextSecondaryAttack = gpGlobals->curtime + 0.5f;

	AddViewKick();

	// Register a muzzleflash for the AI
#ifndef CLIENT_DLL
	pOwner->SetMuzzleFlashTime(gpGlobals->curtime + 0.5);
#endif

}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
 void CWeaponGauss::Fire( void )
 {
         CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
         
         if ( pOwner == NULL )
                return;

        m_bCharging = false;
 
         Vector  startPos= pOwner->Weapon_ShootPosition();
         Vector  aimDir  = pOwner->GetAutoaimVector( AUTOAIM_5DEGREES );
 
         Vector vecUp, vecRight;
         VectorVectors( aimDir, vecRight, vecUp );
 
         float x, y, z;
 
         //Gassian spread
         do {
                 x = random->RandomFloat(-0.5,0.5) + random->RandomFloat(-0.5,0.5);
                 y = random->RandomFloat(-0.5,0.5) + random->RandomFloat(-0.5,0.5);
                z = x*x+y*y;
         } while (z > 1);

 
         Vector  endPos  = startPos + ( aimDir * MAX_TRACE_LENGTH );
         
         //Shoot a shot straight out
         trace_t tr;
         UTIL_TraceLine( startPos, endPos, MASK_SHOT, pOwner, COLLISION_GROUP_NONE, &tr );
#ifndef CLIENT_DLL
         ClearMultiDamage();
#endif
 
         CBaseEntity *pHit = tr.m_pEnt;
#ifndef CLIENT_DLL         
         CTakeDamageInfo dmgInfo( this, pOwner, sk_dmg_gauss.GetFloat(), DMG_SHOCK | DMG_BULLET );
#endif
 
         if ( pHit != NULL )
        {
#ifndef CLIENT_DLL
                 CalculateBulletDamageForce( &dmgInfo, m_iPrimaryAmmoType, aimDir, tr.endpos, 7.0f * 5.0f  );
                 pHit->DispatchTraceAttack( dmgInfo, aimDir, &tr );
#endif
         }
         
         if ( tr.DidHitWorld() )
         {
                 float hitAngle = -DotProduct( tr.plane.normal, aimDir );
 
                 if ( hitAngle < 0.5f )
                 {
                         Vector vReflection;
                 
                         vReflection = 2.0 * tr.plane.normal * hitAngle + aimDir;
                         
                         startPos        = tr.endpos;
                         endPos          = startPos + ( vReflection * MAX_TRACE_LENGTH );
                         
                         //Draw beam to reflection point
                         DrawBeam( tr.startpos, tr.endpos, 1.6, true );
 
                         CPVSFilter filter( tr.endpos );
                         te->GaussExplosion( filter, 0.0f, tr.endpos, tr.plane.normal, 0 );
 
                         UTIL_ImpactTrace( &tr, GetAmmoDef()->DamageType(m_iPrimaryAmmoType), "ImpactGauss" );
 
                         //Find new reflection end position
                         UTIL_TraceLine( startPos, endPos, MASK_SHOT, pOwner, COLLISION_GROUP_NONE, &tr );
 
                         if ( tr.m_pEnt != NULL )
                         {
#ifndef CLIENT_DLL
                                 dmgInfo.SetDamageForce( GetAmmoDef()->DamageForce(m_iPrimaryAmmoType) * vReflection );
                                 dmgInfo.SetDamagePosition( tr.endpos );
                                 tr.m_pEnt->DispatchTraceAttack( dmgInfo, vReflection, &tr );
#endif
                         }

                         //Connect reflection point to end
                         DrawBeam( tr.startpos, tr.endpos, 0.4 );
                 }
                 else
                {
                         DrawBeam( tr.startpos, tr.endpos, 1.6, true );
                 }
         }
         else
         {
                 DrawBeam( tr.startpos, tr.endpos, 1.6, true );
         }
#ifndef CLIENT_DLL         
         ApplyMultiDamage();
#endif
 
         UTIL_ImpactTrace( &tr, GetAmmoDef()->DamageType(m_iPrimaryAmmoType), "ImpactGauss" );
 
         CPVSFilter filter( tr.endpos );
         te->GaussExplosion( filter, 0.0f, tr.endpos, tr.plane.normal, 0 );
 
         m_flNextSecondaryAttack = gpGlobals->curtime + 1.0f;
 
         AddViewKick();


return;
 }