//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponCombatLaserRifle::PrimaryAttack( void )
{
	CBaseTFPlayer *pPlayer = (CBaseTFPlayer*)GetOwner();
	if (!pPlayer)
		return;
	
	WeaponSound(SINGLE);

	// Fire the bullets
	Vector vecSrc = pPlayer->Weapon_ShootPosition( );
	Vector vecAiming;
	pPlayer->EyeVectors( &vecAiming );

	PlayAttackAnimation( GetPrimaryAttackActivity() );

	// Reduce the spread if the player's ducking
	Vector vecSpread = GetBulletSpread();
	vecSpread *= m_flInaccuracy;

	TFGameRules()->FireBullets( CTakeDamageInfo( this, pPlayer, weapon_combat_laserrifle_damage.GetFloat(), DMG_PLASMA), 1, 
		vecSrc, vecAiming, vecSpread, weapon_combat_laserrifle_range.GetFloat(), m_iPrimaryAmmoType, 0, entindex(), 0 );

	m_flInaccuracy += 0.3;
	m_flInaccuracy = clamp(m_flInaccuracy, 0, 1);

	m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate();
	m_iClip1 = m_iClip1 - 1;
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponCombatPlasmaGrenadeLauncher::PrimaryAttack( void )
{
	CBaseTFPlayer *pPlayer = (CBaseTFPlayer*)GetOwner();
	if (!pPlayer)
		return;
	
	WeaponSound(SINGLE);

	// Fire the bullets
	Vector vecSrc = pPlayer->Weapon_ShootPosition( );

	PlayAttackAnimation( GetPrimaryAttackActivity() );

	// Launch the grenade
	Vector vecForward;
	pPlayer->EyeVectors( &vecForward );
	Vector vecOrigin = pPlayer->EyePosition();
	vecOrigin += (vecForward);

#if !defined( CLIENT_DLL )
	float flSpeed = 1200;

	CGrenadeAntiPersonnel* pGrenade = CGrenadeAntiPersonnel::Create(vecOrigin, vecForward * flSpeed, pPlayer );
	pGrenade->SetModel( "models/weapons/w_grenade.mdl" );
	pGrenade->SetBounceSound( "PlasmaGrenade.Bounce" );
	pGrenade->SetDamage( weapon_combat_plasmagrenadelauncher_damage.GetFloat() );
	pGrenade->SetDamageRadius( weapon_combat_plasmagrenadelauncher_radius.GetFloat() );
	pGrenade->SetExplodeOnContact( true );
#endif

	m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate();
	m_iClip1 = m_iClip1 - 1;
}
void CWeaponStickyLauncher::PrimaryAttack( void )
{
	// Only the player fires this way so we can cast
	CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );

	if (!pPlayer)
		return;

	m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate();

	WeaponSound(SINGLE);
	pPlayer->m_fEffects |= EF_MUZZLEFLASH;

	SendWeaponAnim( GetPrimaryAttackActivity() );

	// player "shoot" animation
	pPlayer->SetAnimation( PLAYER_ATTACK1 );

	Vector vecSrc = pPlayer->Weapon_ShootPosition( );
	Vector vecAiming = pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES );
	m_iClip1 = m_iClip1 - 1;

	LaunchStickyBomb( pPlayer, vecSrc, vecAiming );
	AddViewKick();
}
void CASW_Weapon_Stim::InjectStim()
{
	CASW_Marine *pMarine = GetMarine();

	if (pMarine)		// firing from a marine
	{
		//make the proper weapon sound
		WeaponSound(SINGLE);
#ifndef CLIENT_DLL
		bool bThisActive = (pMarine->GetActiveASWWeapon() == this);
#endif
		// sets the animation on the weapon model iteself
		SendWeaponAnim( GetPrimaryAttackActivity() );

		// sets the animation on the marine holding this weapon
		//pMarine->SetAnimation( PLAYER_ATTACK1 );
#ifndef CLIENT_DLL

		// make it cause the slow time
		float fDuration = MarineSkills()->GetBestSkillValue( ASW_MARINE_SKILL_DRUGS );
		if (fDuration < 0)
			fDuration = asw_stim_duration.GetFloat();

		//CALL_ATTRIB_HOOK_FLOAT( fDuration, mod_duration );

		ASWGameRules()->StartStim( fDuration, pMarine->GetCommander() );

		pMarine->OnWeaponFired( this, 1 );
#endif
		// decrement ammo
		m_iClip1 -= 1;

		m_flNextPrimaryAttack = gpGlobals->curtime + 4.0f;

		if (!m_iClip1 && pMarine->GetAmmoCount(m_iPrimaryAmmoType) <= 0)
		{
			// stim weapon is lost when all stims are gone
#ifndef CLIENT_DLL
			if (pMarine)
			{
				pMarine->Weapon_Detach(this);
				if (bThisActive)
					pMarine->SwitchToNextBestWeapon(NULL);
			}
			Kill();
#endif
		}		
	}
}
Exemple #5
0
//-----------------------------------------------------------------------------
// Purpose: Tells us we're always a translucent entity
//-----------------------------------------------------------------------------
bool C_WeaponStunStick::InSwing( void )
{
	int activity = GetActivity();

	// FIXME: This is needed until the actual animation works
	if ( ShouldDrawUsingViewModel() == false )
		return true;

	// These are the swing activities this weapon can play
	if ( activity == GetPrimaryAttackActivity() || 
		 activity == GetSecondaryAttackActivity() ||
		 activity == ACT_VM_MISSCENTER ||
		 activity == ACT_VM_MISSCENTER2 )
		return true;

	return false;
}
//-----------------------------------------------------------------------------
// Purpose: Tells us we're always a translucent entity
//-----------------------------------------------------------------------------
bool C_WeaponStunStick::InSwing( void )
{
	int activity = GetActivity();

	// FIXME: This is needed until the actual animation works
	if ( IsCarriedByLocalPlayer() == false || ::input->CAM_IsThirdPerson())
		return true;

	// These are the swing activities this weapon can play
	if ( activity == GetPrimaryAttackActivity() || 
		 activity == GetSecondaryAttackActivity() ||
		 activity == ACT_VM_MISSCENTER ||
		 activity == ACT_VM_MISSCENTER2 )
		return true;

	return false;
}
//-----------------------------------------------------------------------------
// Purpose: Firing
//-----------------------------------------------------------------------------
void CWeaponRocketLauncher::PrimaryAttack( void )
{
	CBaseTFPlayer *pPlayer = ( CBaseTFPlayer* )GetOwner();
	if ( !pPlayer )
		return;

	if ( !ComputeEMPFireState() )
		return;

	// Weapon "Fire" sound.
	WeaponSound( SINGLE );

	// Play the attack animation (need one for rocket launcher - deploy?)
	PlayAttackAnimation( GetPrimaryAttackActivity() );

	// Fire the rocket (Get the position and angles).
	Vector vecFirePos = pPlayer->Weapon_ShootPosition();
	Vector vecFireAng;
	pPlayer->EyeVectors( &vecFireAng );

	// Shift it down a bit so the firer can see it
	Vector vecRight;
	AngleVectors( pPlayer->EyeAngles() + pPlayer->m_Local.m_vecPunchAngle, NULL, &vecRight, NULL );
	vecFirePos += Vector( 0, 0, -8 ) + vecRight * 12;

	// Create the rocket.
#if !defined( CLIENT_DLL )
	CWeaponGrenadeRocket *pRocket = CWeaponGrenadeRocket::Create( vecFirePos, vecFireAng, weapon_rocket_launcher_range.GetFloat(), pPlayer );
#else
	CWeaponGrenadeRocket *pRocket = CWeaponGrenadeRocket::Create( vecFirePos, vecFireAng, 0, pPlayer );
#endif
	if ( pRocket )
	{
		pRocket->SetRealOwner( pPlayer );
#if !defined( CLIENT_DLL )
		pRocket->SetDamage( weapon_rocket_launcher_damage.GetFloat() );
#endif
	}

	// Essentially you are done!
	m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate();
	m_iClip1 = m_iClip1 - 1;
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponCombat_ChargeablePlasma::PrimaryAttack( void )
{
	CBaseTFPlayer *pPlayer = (CBaseTFPlayer*)GetOwner();
	if (!pPlayer)
		return;
	
	WeaponSound(SINGLE);

	// Fire the bullets
	Vector vecSrc = pPlayer->Weapon_ShootPosition( );
	Vector vecAiming;
	pPlayer->EyeVectors( &vecAiming );

	// If we already have a lock target from button down, see if we shouldn't try and get a new one
	// Only do this is the button was released immediately
	if ( !m_hLockTarget || ( m_flLockedAt < gpGlobals->curtime ) )
	{
		m_hLockTarget = GetLockTarget();
	}

	PlayAttackAnimation( GetPrimaryAttackActivity() );

	// Shift it down a bit so the firer can see it
	Vector right;
	AngleVectors( pPlayer->EyeAngles() + pPlayer->m_Local.m_vecPunchAngle, NULL, &right, NULL );
	Vector vecStartSpot = vecSrc + Vector(0,0,-8) + right * 12;

	CGuidedPlasma *pShot = CGuidedPlasma::Create(vecStartSpot, vecAiming, m_hLockTarget, m_vecTargetOffset, pPlayer);

	// Set it's charged power level
	if (m_bHasCharge)
		m_flPower = min( MAX_CHARGED_TIME, gpGlobals->curtime - m_flChargeStartTime );
	else
		m_flPower = 0.0f;

	float flDamageMult = RemapVal( m_flPower, 0, MAX_CHARGED_TIME, 1.0, MAX_CHARGED_POWER );
	pShot->SetPowerLevel( flDamageMult );

	m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate();
	m_iClip1 = m_iClip1 - 1;
	m_hLockTarget = NULL;
}
//-----------------------------------------------------------------------------
// Purpose: Prepare the launcher to fire
//-----------------------------------------------------------------------------
void CGEWeaponRocketLauncher::PrimaryAttack( void )
{
	CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
	if (!pPlayer)
		return;

	// If my clip is empty (and I use clips) start reload
	if ( UsesClipsForAmmo1() && !m_iClip1 ) 
	{
		Reload();
		return;
	}

	// Bring us back to center view
	pPlayer->ViewPunchReset();

	// Note that this is a primary attack and prepare the grenade attack to pause.
	m_bPreLaunch = true;
	SendWeaponAnim( GetPrimaryAttackActivity() );
	ToGEPlayer(pPlayer)->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY );

	m_flRocketSpawnTime = gpGlobals->curtime + GetFireDelay();
	m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate();
}
Exemple #10
0
void CASW_Weapon_T75::PrimaryAttack( void )
{	
	// Only the player fires this way so we can cast
	CASW_Player *pPlayer = GetCommander();
	if (!pPlayer)
		return;

	CASW_Marine *pMarine = GetMarine();
#ifndef CLIENT_DLL
	bool bThisActive = (pMarine && pMarine->GetActiveWeapon() == this);
#endif

	// weapon is lost when all charges are gone
	if ( UsesClipsForAmmo1() && !m_iClip1 ) 
	{
		//Reload();
#ifndef CLIENT_DLL
		if (pMarine)
		{
			pMarine->Weapon_Detach(this);
			if (bThisActive)
				pMarine->SwitchToNextBestWeapon(NULL);
		}
		Kill();
#endif
		return;
	}

	if ( !pMarine || pMarine->GetWaterLevel() == 3 )		// firing from a marine
		return;

	// sets the animation on the weapon model iteself
	SendWeaponAnim( GetPrimaryAttackActivity() );

#ifndef CLIENT_DLL
	Vector	vecSrc		= pMarine->Weapon_ShootPosition( );
	// TODO: Fix for AI
	Vector	vecAiming	= pPlayer->GetAutoaimVectorForMarine(pMarine, GetAutoAimAmount(), GetVerticalAdjustOnlyAutoAimAmount());

	if ( !pMarine->IsInhabited() && vecSrc.DistTo( pMarine->m_vecOffhandItemSpot ) < 150.0f )
	{
		vecSrc.x = pMarine->m_vecOffhandItemSpot.x;
		vecSrc.y = pMarine->m_vecOffhandItemSpot.y;
		vecSrc.z += 50.0f;
	}
	
	QAngle ang = pPlayer->EyeAngles();
	ang.x = 0;
	ang.z = 0;
	CShotManipulator Manipulator( vecAiming );
	AngularImpulse rotSpeed(0,0,720);
			
	Vector newVel = Manipulator.ApplySpread(GetBulletSpread());

	newVel *= ASW_MINE_VELOCITY;

	if ( !pMarine->IsInhabited() )
	{
		newVel = vec3_origin;
	}

	CASW_T75 *pT75 = CASW_T75::ASW_T75_Create( vecSrc, ang, newVel, rotSpeed, pMarine, this );
	if ( pT75 && !pMarine->IsInhabited() )
	{
		pT75->ActivateUseIcon( pMarine, ASW_USE_RELEASE_QUICK );
	}

	//pMarine->GetMarineSpeech()->Chatter(CHATTER_MINE_DEPLOYED);
#endif
	// decrement ammo
	m_iClip1 -= 1;

#ifndef CLIENT_DLL
	DestroyIfEmpty( true );
#endif

	m_flSoonestPrimaryAttack = gpGlobals->curtime + ASW_FLARES_FASTEST_REFIRE_TIME;
	if (m_iClip1 > 0)		// only force the fire wait time if we have ammo for another shot
		m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate();
	else
		m_flNextPrimaryAttack = gpGlobals->curtime;
}
void CASW_Weapon_Shotgun::PrimaryAttack( void )
{
	// If my clip is empty (and I use clips) start reload
	if ( UsesClipsForAmmo1() && !m_iClip1 ) 
	{
		Reload();
		return;
	}

	CASW_Player *pPlayer = GetCommander();
	CASW_Marine *pMarine = GetMarine();

	if (pMarine)		// firing from a marine
	{
		// MUST call sound before removing a round from the clip of a CMachineGun
		WeaponSound(SINGLE);
		if (m_iClip1 <= AmmoClickPoint())
		{
			LowAmmoSound();
		}

		m_bIsFiring = true;

		// tell the marine to tell its weapon to draw the muzzle flash
		pMarine->DoMuzzleFlash();

		// sets the animation on the weapon model iteself
		SendWeaponAnim( GetPrimaryAttackActivity() );

#ifdef GAME_DLL	// check for turning on lag compensation
		if (pPlayer && pMarine->IsInhabited())
		{
			CASW_Lag_Compensation::RequestLagCompensation( pPlayer, pPlayer->GetCurrentUserCommand() );
		}
#endif

		Vector vecSrc = pMarine->Weapon_ShootPosition( );
		// hull trace out to this shoot position, so we can be sure we're not firing from over an alien's head
		trace_t tr;
		CTraceFilterSimple tracefilter(pMarine, COLLISION_GROUP_NONE);
		Vector vecMarineMiddle(pMarine->GetAbsOrigin());
		vecMarineMiddle.z = vecSrc.z;
		AI_TraceHull( vecMarineMiddle, vecSrc, Vector( -10, -10, -20 ), Vector( 10, 10, 10 ), MASK_SHOT, &tracefilter, &tr );
		vecSrc = tr.endpos;

		Vector vecAiming = vec3_origin;
		if ( pPlayer && pMarine->IsInhabited() )
		{
			vecAiming = pPlayer->GetAutoaimVectorForMarine(pMarine, GetAutoAimAmount(), GetVerticalAdjustOnlyAutoAimAmount());	// 45 degrees = 0.707106781187
		}
		else
		{
#ifndef CLIENT_DLL
			vecAiming = pMarine->GetActualShootTrajectory( vecSrc );
#endif
		}

		if (true)		// hitscan pellets
		{

#ifndef CLIENT_DLL
			if (asw_DebugAutoAim.GetBool())
			{
				NDebugOverlay::Line(vecSrc, vecSrc + vecAiming * asw_weapon_max_shooting_distance.GetFloat(), 64, 0, 64, false, 120.0);
			}
#endif
			int iPellets = GetNumPellets();
			for (int i=0;i<iPellets;i++)
			{
				FireBulletsInfo_t info( 1, vecSrc, vecAiming, GetAngularBulletSpread(), asw_weapon_max_shooting_distance.GetFloat(), m_iPrimaryAmmoType );
				info.m_pAttacker = pMarine;
				info.m_iTracerFreq = 1;
				info.m_nFlags = FIRE_BULLETS_NO_PIERCING_SPARK | FIRE_BULLETS_HULL | FIRE_BULLETS_ANGULAR_SPREAD;
				info.m_flDamage = GetWeaponDamage();
				info.m_flDamageForceScale = asw_weapon_force_scale.GetFloat();
	#ifndef CLIENT_DLL
				if (asw_debug_marine_damage.GetBool())
					Msg("Weapon dmg = %f\n", info.m_flDamage);
				info.m_flDamage *= pMarine->GetMarineResource()->OnFired_GetDamageScale();
	#endif
				// shotgun bullets have a base 50% chance of piercing
				//float fPiercingChance = 0.5f;
				//if (pMarine->GetMarineResource() && pMarine->GetMarineProfile() && pMarine->GetMarineProfile()->GetMarineClass() == MARINE_CLASS_SPECIAL_WEAPONS)
					//fPiercingChance += MarineSkills()->GetSkillBasedValueByMarine(pMarine, ASW_MARINE_SKILL_PIERCING);
				
				//pMarine->FirePenetratingBullets(info, 5, fPiercingChance);

				//pMarine->FirePenetratingBullets(info, 5, 1.0f, i, false );
				pMarine->FirePenetratingBullets(info, 0, 1.0f, i, false );
			}
		}
		else	// projectile pellets
		{
#ifndef CLIENT_DLL
			CShotManipulator Manipulator( vecAiming );
					
			int iPellets = GetNumPellets();
			for (int i=0;i<iPellets;i++)
			{
				// create a pellet at some random spread direction
				//CASW_Shotgun_Pellet *pPellet = 			
				Vector newVel = Manipulator.ApplySpread(GetBulletSpread());
				//Vector newVel = ApplySpread( vecAiming, GetBulletSpread() );
				if ( pMarine->GetWaterLevel() == 3 )
					newVel *= PELLET_WATER_VELOCITY;
				else
					newVel *= PELLET_AIR_VELOCITY;
				newVel *= (1.0 + (0.1 * random->RandomFloat(-1,1)));
				CreatePellet(vecSrc, newVel, pMarine);
				
				//CASW_Shotgun_Pellet_Predicted::CreatePellet(vecSrc, newVel, pPlayer, pMarine);
			}
#endif
		}

		// increment shooting stats
#ifndef CLIENT_DLL
		if (pMarine && pMarine->GetMarineResource())
		{
			pMarine->GetMarineResource()->UsedWeapon(this, 1);
			pMarine->OnWeaponFired( this, GetNumPellets() );
		}
#endif

		// decrement ammo
		m_iClip1 -= 1;
#ifdef GAME_DLL
		CASW_Marine *pMarine = GetMarine();
		if (pMarine && m_iClip1 <= 0 && pMarine->GetAmmoCount(m_iPrimaryAmmoType) <= 0 )
		{
			// check he doesn't have ammo in an ammo bay
			CASW_Weapon_Ammo_Bag* pAmmoBag = dynamic_cast<CASW_Weapon_Ammo_Bag*>(pMarine->GetASWWeapon(0));
			if (!pAmmoBag)
				pAmmoBag = dynamic_cast<CASW_Weapon_Ammo_Bag*>(pMarine->GetASWWeapon(1));
			if (!pAmmoBag || !pAmmoBag->CanGiveAmmoToWeapon(this))
				pMarine->OnWeaponOutOfAmmo(true);
		}
#endif
	}
	
	if (m_iClip1 > 0)		// only force the fire wait time if we have ammo for another shot
		m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate();
	else
		m_flNextPrimaryAttack = gpGlobals->curtime;
	m_fSlowTime = gpGlobals->curtime + 0.1f;
}
void CWeaponSMG1::PrimaryAttack( void )
{
	// Only the player fires this way so we can cast
	CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
	if (!pPlayer)
		return;
	
	// Abort here to handle burst and auto fire modes
	if ( (UsesClipsForAmmo1() && m_iClip1 == 0) || ( !UsesClipsForAmmo1() && !pPlayer->GetAmmoCount(m_iPrimaryAmmoType) ) )
		return;

	m_nShotsFired++;

	pPlayer->DoMuzzleFlash();

	// To make the firing framerate independent, we may have to fire more than one bullet here on low-framerate systems, 
	// especially if the weapon we're firing has a really fast rate of fire.
	int iBulletsToFire = 0;
	float fireRate = GetFireRate();

	while ( m_flNextPrimaryAttack <= gpGlobals->curtime )
	{
		// MUST call sound before removing a round from the clip of a CHLMachineGun
		WeaponSound(SINGLE, m_flNextPrimaryAttack);
		m_flNextPrimaryAttack = gpGlobals->curtime + fireRate;
		iBulletsToFire++;
	}

	// Make sure we don't fire more than the amount in the clip, if this weapon uses clips
	if ( UsesClipsForAmmo1() )
	{
		if ( iBulletsToFire > m_iClip1 )
			iBulletsToFire = m_iClip1;
		m_iClip1 -= iBulletsToFire;
	}

	CSDKPlayer *pSDKPlayer = ToSDKPlayer( pPlayer );

	// Fire the bullets
	FireBulletsInfo_t info;
	info.m_iShots = iBulletsToFire;
	info.m_vecSrc = pSDKPlayer->Weapon_ShootPosition( );
	info.m_vecDirShooting = pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES );
	info.m_vecSpread = GetBulletSpread();
	info.m_flDistance = MAX_TRACE_LENGTH;
	info.m_iAmmoType = m_iPrimaryAmmoType;
	info.m_iTracerFreq = 2;
	info.m_iDamage = GetSDKWpnData().m_iDamage;
	pPlayer->FireBullets( info );

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

	SendWeaponAnim( GetPrimaryAttackActivity() );
	pPlayer->SetAnimation( PLAYER_ATTACK1 );
	pSDKPlayer->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY );
}
void CASW_Weapon_Assault_Shotgun::SecondaryAttack()
{
	// Only the player fires this way so we can cast
	CASW_Player *pPlayer = GetCommander();
	if (!pPlayer)
		return;

	CASW_Marine *pMarine = GetMarine();

	if (!pMarine)
		return;

	//Must have ammo
	bool bUsesSecondary = UsesSecondaryAmmo();
	bool bUsesClips = UsesClipsForAmmo2();
	int iAmmoCount = pMarine->GetAmmoCount(m_iSecondaryAmmoType);
	bool bInWater = ( pMarine->GetWaterLevel() == 3 );
	if ( (bUsesSecondary &&  
			(   ( bUsesClips && m_iClip2 <= 0) ||
			    ( !bUsesClips && iAmmoCount<=0 )
				) )
				 || bInWater || m_bInReload )
	{
		SendWeaponAnim( ACT_VM_DRYFIRE );
		BaseClass::WeaponSound( EMPTY );
		m_flNextSecondaryAttack = gpGlobals->curtime + 0.5f;
		return;
	}

	BaseClass::WeaponSound( SPECIAL1 );		
			
#ifndef CLIENT_DLL
	pMarine->GetMarineSpeech()->Chatter(CHATTER_GRENADE);
	Vector vecSrc = pMarine->Weapon_ShootPosition();
	Vector	vecThrow;
	// check for turning on lag compensation
	if (pPlayer && pMarine->IsInhabited())
	{
		CASW_Lag_Compensation::RequestLagCompensation( pPlayer, pPlayer->GetCurrentUserCommand() );
	}

	vecThrow = UTIL_LaunchVector(vecSrc, pPlayer->GetCrosshairTracePos(), asw_vindicator_grenade_gravity.GetFloat()) * 8.0f * asw_vindicator_grenade_velocity.GetFloat();
	QAngle angAiming = pPlayer->EyeAnglesWithCursorRoll();

	float fGrenadeDamage = MarineSkills()->GetSkillBasedValueByMarine(pMarine, ASW_MARINE_SKILL_GRENADES, ASW_MARINE_SUBSKILL_GRENADE_INCENDIARY_DMG);
	float fGrenadeRadius = MarineSkills()->GetSkillBasedValueByMarine(pMarine, ASW_MARINE_SKILL_GRENADES, ASW_MARINE_SUBSKILL_GRENADE_RADIUS);
	if (asw_debug_marine_damage.GetBool())
	{
		Msg("Grenade damage = %f radius = %f\n", fGrenadeDamage, fGrenadeRadius);
	}
	// check the grenade fits where we want to spawn it
	Ray_t ray;
	trace_t pm;
	ray.Init( pMarine->WorldSpaceCenter(), vecSrc, -Vector(4,4,4), Vector(4,4,4) );
	UTIL_TraceRay( ray, MASK_SOLID, pMarine, COLLISION_GROUP_PROJECTILE, &pm );
	if (pm.fraction < 1.0f)
		vecSrc = pm.endpos;

	CASW_Grenade_Vindicator::Vindicator_Grenade_Create( 
		fGrenadeDamage,
		fGrenadeRadius,
		vecSrc, angAiming, vecThrow, AngularImpulse(0,0,0), pMarine, this );

	pMarine->OnWeaponFired( this, 1, true );
#endif

	SendWeaponAnim( GetPrimaryAttackActivity() );

	pMarine->DoAnimationEvent( PLAYERANIMEVENT_FIRE_GUN_PRIMARY );

	// Decrease ammo
	if ( bUsesClips )
	{
		m_iClip2 -= 1;
	}
	else
	{
		pMarine->RemoveAmmo( 1, m_iSecondaryAmmoType );
	}

#ifndef CLIENT_DLL
	ASWFailAdvice()->OnMarineUsedSecondary();

	CEffectData	data;
	data.m_vOrigin = GetAbsOrigin();
	//data.m_vNormal = dir;
	//data.m_flScale = (float)amount;
	CPASFilter filter( data.m_vOrigin );
	filter.SetIgnorePredictionCull(true);
	DispatchParticleEffect( "muzzleflash_grenadelauncher_main", PATTACH_POINT_FOLLOW, this, "muzzle", false, -1, &filter );
#endif

	// Can shoot again immediately
	m_flNextPrimaryAttack = gpGlobals->curtime + 0.5f;

	// Can blow up after a short delay (so have time to release mouse button)
	m_flNextSecondaryAttack = gpGlobals->curtime + 1.0f;
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponLaserRifle::PrimaryAttack( void )
{
	CBaseTFPlayer *pPlayer = ToBaseTFPlayer( m_hOwner );
	if ( !pPlayer )
		return;
	
	if ( !ComputeEMPFireState() )
		return;

	WeaponSound(SINGLE);

	PlayAttackAnimation( GetPrimaryAttackActivity() );

	pPlayer->m_fEffects |= EF_MUZZLEFLASH;

	// Fire the beam: BLOW OFF AUTOAIM
	Vector vecSrc	 = pPlayer->Weapon_ShootPosition( pPlayer->GetOrigin() );
	Vector vecAiming, right, up;
	pPlayer->EyeVectors( &vecAiming, &right, &up);

	Vector vecSpread = VECTOR_CONE_4DEGREES;

	// Get endpoint
	float x, y, z;
	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 vecDir = vecAiming + x * vecSpread.x * right + y * vecSpread.y * up;
	Vector vecEnd = vecSrc + vecDir * weapon_laserrifle_range.GetFloat();

	trace_t tr;
	float damagefactor = TFGameRules()->WeaponTraceLine(vecSrc, vecEnd, MASK_SHOT, pPlayer, DMG_ENERGYBEAM, &tr);

	// Hit target?
	if (tr.fraction != 1.0)
	{
		CBaseEntity *pEntity = CBaseEntity::Instance(tr.u.ent);
		if ( pEntity )
		{
			ClearMultiDamage();
			float flDamage = GetDamage( (tr.endpos - vecSrc).Length(), tr.hitgroup );
			flDamage *= damagefactor;  
			pEntity->TraceAttack( CTakeDamageInfo( pPlayer, pPlayer, flDamage, DMG_ENERGYBEAM ), vecDir, &tr );
			ApplyMultiDamage( pPlayer, pPlayer );
		}

		g_pEffects->EnergySplash( tr.endpos, tr.plane.normal );
	}

	// Get hacked gun position
	AngleVectors( pPlayer->EyeAngles() + pPlayer->m_Local.m_vecPunchAngle, NULL, &right, NULL );
	Vector vecTracerSrc = vecSrc + Vector (0,0,-8) + right * 12 + vecDir * 16;

	// Laser beam
	CBroadcastRecipientFilter filter;
	te->BeamPoints( filter, 0.0,
					&vecTracerSrc, 
					&tr.endpos, 
					m_iSpriteTexture, 
					0,		// Halo index
					0,		// Start frame
					0,		// Frame rate
					0.2,	// Life
					15,		// Width
					15,		// EndWidth
					0,		// FadeLength
					0,		// Amplitude
					200,	// r
					200,	// g
					255,	// b
					255,	// a
					255	);	// speed

	pPlayer->m_iAmmo[m_iPrimaryAmmoType]--;
	m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate();

	CheckRemoveDisguise();
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWarsWeapon::PrimaryAttack( void )
{
	VPROF_BUDGET( "CWarsWeapon::PrimaryAttack", VPROF_BUDGETGROUP_UNITS );

	CUnitBase *pOwner = GetOwner()  ? GetOwner()->MyUnitPointer() : NULL;
	if( !pOwner )
		return;

#ifndef CLIENT_DLL
	if( m_bEnableBurst )
	{
		// Auto reset burst shots next time we fire
		if( m_nBurstShotsRemaining <= 0 )
		{
			m_nBurstShotsRemaining = GetRandomBurst();
		}
	}
#endif // CLIENT_DLL

	pOwner->DoMuzzleFlash();
	
	SendWeaponAnim( GetPrimaryAttackActivity() );

	Vector vecShootOrigin, vecShootDir;
	GetShootOriginAndDirection(vecShootOrigin, vecShootDir);

    int shots = 0;

	// Assume still firing if gpGlobals.curtime-nextprimaryattack falss within this range
	// In the other case reset nextprimaryattack, so we only fire one shot
	if( (gpGlobals->curtime - m_flNextPrimaryAttack) > m_fFireTimeOut )
		m_flNextPrimaryAttack = gpGlobals->curtime;

	//WeaponSound(SINGLE, m_flNextPrimaryAttack);
	while( m_flNextPrimaryAttack <= gpGlobals->curtime )
	{
#ifdef CLIENT_DLL
		// MUST call sound before removing a round from the clip of a CMachineGun
		WeaponSound(SINGLE, m_flNextPrimaryAttack);
#endif // CLIENT_DLL
		m_flNextPrimaryAttack = m_flNextPrimaryAttack + m_fFireRate;
		shots += 1;
		if( !m_fFireRate )
			break;
	}
    
	// Fill in bullets info
	FireBulletsInfo_t info;
	info.m_vecSrc = vecShootOrigin;
	info.m_vecDirShooting = vecShootDir;
	info.m_iShots = shots;
	info.m_flDistance = m_fMaxBulletRange;
	info.m_iAmmoType = GetPrimaryAmmoType();
	info.m_iTracerFreq = 2;
	info.m_vecSpread = m_vBulletSpread;
	info.m_flDamage = m_fOverrideAmmoDamage;

	pOwner->FireBullets( info );

#ifndef CLIENT_DLL
	if( m_bEnableBurst )
	{
		m_nBurstShotsRemaining -= shots;
		// Dispatch burst finished event if we have no shots left
		// It's up to the AI to rest
		if( m_nBurstShotsRemaining <= 0 )
		{
			pOwner->DispatchBurstFinished();
		}
	}
#endif // CLIENT_DLL

	// Add our view kick in
	AddViewKick();
}
void CASW_Weapon_Buff_Grenade::PrimaryAttack( void )
{	
	// Only the player fires this way so we can cast
	CASW_Player *pPlayer = GetCommander();

	if (!pPlayer)
		return;

	CASW_Marine *pMarine = GetMarine();
#ifndef CLIENT_DLL
	bool bThisActive = (pMarine && pMarine->GetActiveWeapon() == this);
#endif

	// mine weapon is lost when all mines are gone
	if ( UsesClipsForAmmo1() && !m_iClip1 ) 
	{
		//Reload();
#ifndef CLIENT_DLL
		if (pMarine)
		{
			pMarine->Weapon_Detach(this);
			if (bThisActive)
				pMarine->SwitchToNextBestWeapon(NULL);
		}
		Kill();
#endif
		return;
	}

	if ( !pMarine || pMarine->GetWaterLevel() == 3 )
		return;

	// MUST call sound before removing a round from the clip of a CMachineGun
	//WeaponSound(SINGLE);

	// tell the marine to tell its weapon to draw the muzzle flash
	//pMarine->DoMuzzleFlash();

	// sets the animation on the weapon model iteself
	SendWeaponAnim( GetPrimaryAttackActivity() );

	//pMarine->DoAnimationEvent(PLAYERANIMEVENT_HEAL);

	// sets the animation on the marine holding this weapon
	//pMarine->SetAnimation( PLAYER_ATTACK1 );
#ifndef CLIENT_DLL
	Vector	vecSrc		= pMarine->Weapon_ShootPosition( );
	Vector	vecAiming	= pPlayer->GetAutoaimVectorForMarine(pMarine, GetAutoAimAmount(), GetVerticalAdjustOnlyAutoAimAmount());	// 45 degrees = 0.707106781187
	
	if ( !pMarine->IsInhabited() && vecSrc.DistTo( pMarine->m_vecOffhandItemSpot ) < 150.0f )
	{
		vecSrc.x = pMarine->m_vecOffhandItemSpot.x;
		vecSrc.y = pMarine->m_vecOffhandItemSpot.y;
		vecSrc.z += 50.0f;
	}

	QAngle ang = pPlayer->EyeAngles();
	ang.x = 0;
	ang.z = 0;
	CShotManipulator Manipulator( vecAiming );
	AngularImpulse rotSpeed(0,0,720);
	
	// create a pellet at some random spread direction			
	Vector newVel = Manipulator.ApplySpread(GetBulletSpread());

	newVel *= ASW_MINE_VELOCITY;
	if ( !pMarine->IsInhabited() )
	{
		newVel = vec3_origin;
	}

	float flRadius = asw_damage_amp_radius.GetFloat();
	float flDuration = asw_damage_amp_duration.GetFloat();
	CASW_BuffGrenade_Projectile::Grenade_Projectile_Create( vecSrc, ang, newVel, rotSpeed, pMarine, flRadius, flDuration );

	pMarine->OnWeaponFired( this, 1 );

	pMarine->GetMarineSpeech()->Chatter(CHATTER_MINE_DEPLOYED);
#endif
	// decrement ammo
	m_iClip1 -= 1;

#ifndef CLIENT_DLL
	DestroyIfEmpty( true );
#endif

	m_flSoonestPrimaryAttack = gpGlobals->curtime + ASW_FLARES_FASTEST_REFIRE_TIME;
	if (m_iClip1 > 0)		// only force the fire wait time if we have ammo for another shot
		m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate();
	else
		m_flNextPrimaryAttack = gpGlobals->curtime;
}
void CASW_Weapon_Flechette::PrimaryAttack()
{
	// If my clip is empty (and I use clips) start reload
	if ( UsesClipsForAmmo1() && !m_iClip1 ) 
	{		
		Reload();
		return;
	}

	CASW_Player *pPlayer = GetCommander();
	CASW_Marine *pMarine = GetMarine();

	if (pMarine)		// firing from a marine
	{
		m_bIsFiring = true;

		// MUST call sound before removing a round from the clip of a CMachineGun
		WeaponSound(SINGLE);

		if (m_iClip1 <= AmmoClickPoint())
		{
			LowAmmoSound();
		}

		// tell the marine to tell its weapon to draw the muzzle flash
		pMarine->DoMuzzleFlash();

		// sets the animation on the weapon model iteself
		SendWeaponAnim( GetPrimaryAttackActivity() );

		Vector vecDir;
		Vector vecSrc	 = pMarine->Weapon_ShootPosition( );
		if ( pPlayer && pMarine->IsInhabited() )
		{
			vecDir = pPlayer->GetAutoaimVectorForMarine(pMarine, GetAutoAimAmount(), GetVerticalAdjustOnlyAutoAimAmount());	// 45 degrees = 0.707106781187
		}
		else
		{
#ifdef CLIENT_DLL
			Msg("Error, clientside firing of a weapon that's being controlled by an AI marine\n");
#else
			vecDir = pMarine->GetActualShootTrajectory( vecSrc );
#endif
		}
		
		int iShots = 1;

		// Make sure we don't fire more than the amount in the clip
		if ( UsesClipsForAmmo1() )
		{
			iShots = MIN( iShots, m_iClip1 );
			m_iClip1 -= iShots;

#ifdef GAME_DLL
			CASW_Marine *pMarine = GetMarine();
			if (pMarine && m_iClip1 <= 0 && pMarine->GetAmmoCount(m_iPrimaryAmmoType) <= 0 )
			{
				pMarine->OnWeaponOutOfAmmo(true);
			}
#endif
			

		}
		else
		{
			iShots = MIN( iShots, pMarine->GetAmmoCount( m_iPrimaryAmmoType ) );
			pMarine->RemoveAmmo( iShots, m_iPrimaryAmmoType );
		}

/*#ifndef CLIENT_DLL
		if (asw_debug_marine_damage.GetBool())
			Msg("Weapon dmg = %d\n", info.m_flDamage);
		info.m_flDamage *= pMarine->GetMarineResource()->OnFired_GetDamageScale();
#endif*/
				
		// increment shooting stats
#ifndef CLIENT_DLL
		float fGrenadeDamage = MarineSkills()->GetSkillBasedValueByMarine(pMarine, ASW_MARINE_SKILL_GRENADES, ASW_MARINE_SUBSKILL_GRENADE_FLECHETTE_DMG);

		QAngle vecRocketAngle;
		VectorAngles(vecDir, vecRocketAngle);
		vecRocketAngle[YAW] += random->RandomFloat(-10, 10);
		CASW_Rocket::Create(fGrenadeDamage, vecSrc, vecRocketAngle, GetMarine());

		if (pMarine && pMarine->GetMarineResource())
		{
			pMarine->GetMarineResource()->UsedWeapon(this, iShots);
			pMarine->OnWeaponFired( this, iShots );
		}

		if (ASWGameRules())
			ASWGameRules()->m_fLastFireTime = gpGlobals->curtime;
#endif
		m_flNextPrimaryAttack = m_flNextPrimaryAttack + GetFireRate();
	}	
}
void CASW_Weapon_Pistol::PrimaryAttack( void )
{
	// If my clip is empty (and I use clips) start reload
	if ( UsesClipsForAmmo1() && !m_iClip1 ) 
	{
		Reload();
		return;
	}

	CASW_Player *pPlayer = GetCommander();
	CASW_Marine *pMarine = GetMarine();

	if (pMarine)		// firing from a marine
	{
		// MUST call sound before removing a round from the clip of a CMachineGun
		WeaponSound(SINGLE);
		if (m_iClip1 <= AmmoClickPoint())
			BaseClass::WeaponSound( EMPTY );

		m_bIsFiring = true;

		// tell the marine to tell its weapon to draw the muzzle flash
		pMarine->DoMuzzleFlash();

		// sets the animation on the weapon model iteself
		SendWeaponAnim( GetPrimaryAttackActivity() );

		// sets the animation on the marine holding this weapon
		//pMarine->SetAnimation( PLAYER_ATTACK1 );

#ifdef GAME_DLL	// check for turning on lag compensation
		if (pPlayer && pMarine->IsInhabited())
		{
			CASW_Lag_Compensation::RequestLagCompensation( pPlayer, pPlayer->GetCurrentUserCommand() );
		}
#endif

		//	if (asw_pistol_hitscan.GetBool())
		if (true)
		{
			FireBulletsInfo_t info;
			info.m_vecSrc = pMarine->Weapon_ShootPosition( );
			if ( pPlayer && pMarine->IsInhabited() )
			{
				info.m_vecDirShooting = pPlayer->GetAutoaimVectorForMarine(pMarine, GetAutoAimAmount(), GetVerticalAdjustOnlyAutoAimAmount());	// 45 degrees = 0.707106781187
			}
			else
			{
#ifdef CLIENT_DLL
				Msg("Error, clientside firing of a weapon that's being controlled by an AI marine\n");
#else
				info.m_vecDirShooting = pMarine->GetActualShootTrajectory( info.m_vecSrc );
#endif
			}
			
			info.m_iShots = 1;			

			// Make sure we don't fire more than the amount in the clip
			if ( UsesClipsForAmmo1() )
			{
				info.m_iShots = MIN( info.m_iShots, m_iClip1 );
				m_iClip1 -= info.m_iShots;
#ifdef GAME_DLL
				CASW_Marine *pMarine = GetMarine();
				if (pMarine && m_iClip1 <= 0 && pMarine->GetAmmoCount(m_iPrimaryAmmoType) <= 0 )
				{
					pMarine->OnWeaponOutOfAmmo(true);
				}
#endif
			}
			else
			{
				info.m_iShots = MIN( info.m_iShots, pMarine->GetAmmoCount( m_iPrimaryAmmoType ) );
				pMarine->RemoveAmmo( info.m_iShots, m_iPrimaryAmmoType );
			}

			info.m_flDistance = asw_weapon_max_shooting_distance.GetFloat();
			info.m_iAmmoType = m_iPrimaryAmmoType;
			info.m_iTracerFreq = 1;
			info.m_flDamageForceScale = asw_weapon_force_scale.GetFloat();
		
			info.m_vecSpread = GetBulletSpread();
			info.m_flDamage = GetWeaponDamage();
#ifndef CLIENT_DLL
			if (asw_debug_marine_damage.GetBool())
				Msg("Weapon dmg = %f\n", info.m_flDamage);
			info.m_flDamage *= pMarine->OnFired_GetDamageScale();
#endif

			pMarine->FireBullets( info );

			//FireBulletsInfo_t info( 1, vecSrc, vecAiming, GetBulletSpread(), MAX_TRACE_LENGTH, m_iPrimaryAmmoType );
			//info.m_pAttacker = pMarine;

			// Fire the bullets, and force the first shot to be perfectly accuracy
			//pMarine->FireBullets( info );
		}
		else	// projectile pistol
		{
		
#ifndef CLIENT_DLL
			Vector vecSrc = pMarine->Weapon_ShootPosition( );
			Vector vecAiming = vec3_origin;
			if ( pPlayer && pMarine->IsInhabited() )
			{
				vecAiming = pPlayer->GetAutoaimVectorForMarine(pMarine, GetAutoAimAmount(), GetVerticalAdjustOnlyAutoAimAmount());	// 45 degrees = 0.707106781187
			}
			else
			{
				vecAiming = pMarine->GetActualShootTrajectory( vecSrc );
			}

			CShotManipulator Manipulator( vecAiming );
			AngularImpulse rotSpeed(0,0,720);
					
			Vector newVel = Manipulator.ApplySpread(GetBulletSpread());
			if ( pMarine->GetWaterLevel() == 3 )
				newVel *= PELLET_WATER_VELOCITY;
			else
				newVel *= PELLET_AIR_VELOCITY;
			newVel *= (1.0 + (0.1 * random->RandomFloat(-1,1)));
			CASW_Shotgun_Pellet::Shotgun_Pellet_Create( vecSrc, QAngle(0,0,0),
					newVel, rotSpeed, pMarine, GetWeaponDamage() );

			// decrement ammo
			m_iClip1 -= 1;
			CASW_Marine *pMarine = GetMarine();
			if (pMarine && m_iClip1 <= 0 && pMarine->GetAmmoCount(m_iPrimaryAmmoType) <= 0 )
			{
				pMarine->OnWeaponOutOfAmmo(true);
			}
#endif
		}

		// increment shooting stats
#ifndef CLIENT_DLL
		if (pMarine && pMarine->GetMarineResource())
		{
			pMarine->GetMarineResource()->UsedWeapon(this, 1);
			pMarine->OnWeaponFired( this, 1 );
		}
#endif		
	}
	
	if (m_iClip1 > 0)		// only force the fire wait time if we have ammo for another shot
		m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate();
	else
		m_flNextPrimaryAttack = gpGlobals->curtime;
	m_fSlowTime = gpGlobals->curtime + 0.03f;

	if ( m_currentPistol == ASW_WEAPON_PISTOL_LEFT )
	{
		m_currentPistol = ASW_WEAPON_PISTOL_RIGHT;
	}
	else
	{
		m_currentPistol = ASW_WEAPON_PISTOL_LEFT;
	}
}
//-----------------------------------------------------------------------------
// Purpose: 
//
//
//-----------------------------------------------------------------------------
void CHL2MPMachineGun::PrimaryAttack( void )
{
	// Only the player fires this way so we can cast
	CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
	if (!pPlayer)
		return;
	
	// Abort here to handle burst and auto fire modes
	if ( (UsesClipsForAmmo1() && m_iClip1 == 0) || ( !UsesClipsForAmmo1() && !pPlayer->GetAmmoCount(m_iPrimaryAmmoType) ) )
		return;

	m_nShotsFired++;

	// MUST call sound before removing a round from the clip of a CHLMachineGun
	// FIXME: only called once, will miss multiple sound events per frame if needed
	// FIXME: m_flNextPrimaryAttack is always in the past, it's not clear what'll happen with sounds
	WeaponSound(SINGLE, m_flNextPrimaryAttack);
	// Msg("%.3f\n", m_flNextPrimaryAttack.Get() );

	pPlayer->DoMuzzleFlash();

	// To make the firing framerate independent, we may have to fire more than one bullet here on low-framerate systems, 
	// especially if the weapon we're firing has a really fast rate of fire.
	int iBulletsToFire = 0;
	float fireRate = GetFireRate();

	while ( m_flNextPrimaryAttack <= gpGlobals->curtime )
	{
		m_flNextPrimaryAttack = m_flNextPrimaryAttack + fireRate;
		iBulletsToFire++;
	}

	// Make sure we don't fire more than the amount in the clip, if this weapon uses clips
	if ( UsesClipsForAmmo1() )
	{
		if ( iBulletsToFire > m_iClip1 )
			iBulletsToFire = m_iClip1;
		m_iClip1 -= iBulletsToFire;
	}

	CHL2MP_Player *pHL2MPPlayer = ToHL2MPPlayer( pPlayer );

		// Fire the bullets
	FireBulletsInfo_t info;
	info.m_iShots = iBulletsToFire;
	info.m_vecSrc = pHL2MPPlayer->Weapon_ShootPosition( );
	info.m_vecDirShooting = pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES );
	info.m_vecSpread = pHL2MPPlayer->GetAttackSpread( this );
	info.m_flDistance = MAX_TRACE_LENGTH;
	info.m_iAmmoType = m_iPrimaryAmmoType;
	info.m_iTracerFreq = 2;
	FireBullets( info );

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

	SendWeaponAnim( GetPrimaryAttackActivity() );
	pPlayer->SetAnimation( PLAYER_ATTACK1 );
}
//=====================================================================================//
// Purpose: Swing the weapon. bIsSecondary determines which Attack() function was used
//=====================================================================================//
void CTDPWeaponMaul::Swing( int bIsSecondary )
{

	// Do we have a valid owner holding the weapon?
	CTDPPlayer *pPlayer = GetPlayerOwner();
	if ( !pPlayer )
		return;

	// Get the player's position
	Vector vSwingStart = pPlayer->Weapon_ShootPosition( );
	Vector vForward;
	pPlayer->EyeVectors( &vForward, NULL, NULL );

	// Get the attack end position by using the weapon's range
	Vector vSwingEnd = vSwingStart + vForward * GetRange();

	trace_t tr;
	UTIL_TraceLine( vSwingStart, vSwingEnd, MASK_SHOT_HULL, pPlayer, COLLISION_GROUP_NONE, &tr );

	// Let's get our animation sequence depending on the attack type
	Activity nHitActivity = ( bIsSecondary ) ? GetSecondaryAttackActivity() : GetPrimaryAttackActivity();

#if defined( GAME_DLL )
	// Like bullets, bludgeon traces have to trace against triggers.
	CTakeDamageInfo triggerInfo( GetOwner(), GetOwner(), GetDamageForActivity( nHitActivity ), DMG_CLUB );
	TraceAttackToTriggers( triggerInfo, tr.startpos, tr.endpos, vec3_origin );
#endif

	// We didn't hit anything. Let's check for hull trace now
	if ( tr.fraction == 1.0f )
	{
		// hull is +/- 16, so use cuberoot of 2 to determine how big the hull is from center to the corner point
		float bludgeonHullRadius = 1.732f * BLUDGEON_HULL_DIM;

		// Back off by hull "radius"
		vSwingEnd -= vForward * bludgeonHullRadius;

		UTIL_TraceHull( vSwingStart, vSwingEnd, g_bludgeonMins, g_bludgeonMaxs, MASK_SHOT_HULL, pPlayer, COLLISION_GROUP_NONE, &tr );

		// Check if we hit something and if we have hit an entity
		if ( tr.fraction < 1.0 && tr.m_pEnt )
		{
			// Get the position of the entity we just hit
			Vector vToTarget = tr.m_pEnt->GetAbsOrigin() - vSwingStart;
			VectorNormalize( vToTarget );

			float dot = vToTarget.Dot( vForward );

			// Make sure they are sort of facing the guy at least...
			if ( dot < 0.70721f )
			{
				// Force a miss
				tr.fraction = 1.0f;
			}
			else
			{
				// We are sort of facing something. Let's see we should impact based on the melee swing trajectory
				BaseClass::ChooseIntersectionPointAndActivity( tr, g_bludgeonMins, g_bludgeonMaxs, pPlayer );
			}
		}
	}

	// See if we happened to hit water along the way
	BaseClass::ImpactWater( vSwingStart, tr.endpos );

	// Check for hit results
	if ( tr.fraction == 1.0f )
	{
		// We didn't hit anything so let's change the animation sequence to full swing
		nHitActivity = ( bIsSecondary ) ? GetSecondaryMissActivity() : GetPrimaryMissActivity();
	}
	else
	{
		// We hit something. We can keep the same animation sequence.
		BaseClass::Hit( tr, nHitActivity );
	}

	//Play swing sound
	WeaponSound( SINGLE );

	// Send the anim
	SendWeaponAnim( nHitActivity );

	// Setup our next attack times
	m_flNextPrimaryAttack = m_flNextSecondaryAttack = gpGlobals->curtime + GetFireRate();

	// Setup our next time to idle
	m_flTimeWeaponIdle = gpGlobals->curtime + GetTime2Idle();
}
void CASW_Weapon::PrimaryAttack( void )
{
	// If my clip is empty (and I use clips) start reload
	if ( UsesClipsForAmmo1() && !m_iClip1 ) 
	{		
		Reload();
		return;
	}

	CASW_Player *pPlayer = GetCommander();
	CASW_Marine *pMarine = GetMarine();
	if ( !pMarine )
		return;

	m_bIsFiring = true;
	// MUST call sound before removing a round from the clip of a CMachineGun
	WeaponSound(SINGLE);

	if (m_iClip1 <= AmmoClickPoint())
	{
		LowAmmoSound();
	}

	// tell the marine to tell its weapon to draw the muzzle flash
	pMarine->DoMuzzleFlash();

	// sets the animation on the weapon model itself
	SendWeaponAnim( GetPrimaryAttackActivity() );

	// sets the animation on the marine holding this weapon
	//pMarine->SetAnimation( PLAYER_ATTACK1 );

#ifdef GAME_DLL	// check for turning on lag compensation
	if (pPlayer && pMarine->IsInhabited())
	{
		CASW_Lag_Compensation::RequestLagCompensation( pPlayer, pPlayer->GetCurrentUserCommand() );
	}
#endif

	FireBulletsInfo_t info;
	info.m_vecSrc = pMarine->Weapon_ShootPosition( );
	if ( pPlayer && pMarine->IsInhabited() )
	{
		info.m_vecDirShooting = pPlayer->GetAutoaimVectorForMarine(pMarine, GetAutoAimAmount(), GetVerticalAdjustOnlyAutoAimAmount());	// 45 degrees = 0.707106781187
	}
	else
	{
#ifdef CLIENT_DLL
		Msg("Error, clientside firing of a weapon that's being controlled by an AI marine\n");
#else
		info.m_vecDirShooting = pMarine->GetActualShootTrajectory( info.m_vecSrc );
#endif
	}

	// To make the firing framerate independent, we may have to fire more than one bullet here on low-framerate systems, 
	// especially if the weapon we're firing has a really fast rate of fire.
	info.m_iShots = 0;
	float fireRate = GetFireRate();
	while ( m_flNextPrimaryAttack <= gpGlobals->curtime )
	{
		m_flNextPrimaryAttack = m_flNextPrimaryAttack + fireRate;
		info.m_iShots++;
		if ( !fireRate )
			break;
	}

	// Make sure we don't fire more than the amount in the clip
	if ( UsesClipsForAmmo1() )
	{
		info.m_iShots = MIN( info.m_iShots, m_iClip1 );
		m_iClip1 -= info.m_iShots;

#ifdef GAME_DLL
		CASW_Marine *pMarine = GetMarine();
		if (pMarine && m_iClip1 <= 0 && pMarine->GetAmmoCount(m_iPrimaryAmmoType) <= 0 )
		{
			// check he doesn't have ammo in an ammo bay
			CASW_Weapon_Ammo_Bag* pAmmoBag = dynamic_cast<CASW_Weapon_Ammo_Bag*>(pMarine->GetASWWeapon(0));
			if (!pAmmoBag)
				pAmmoBag = dynamic_cast<CASW_Weapon_Ammo_Bag*>(pMarine->GetASWWeapon(1));
			if (!pAmmoBag || !pAmmoBag->CanGiveAmmoToWeapon(this))
				pMarine->OnWeaponOutOfAmmo(true);
		}
#endif
	}
	else
	{
		info.m_iShots = MIN( info.m_iShots, pMarine->GetAmmoCount( m_iPrimaryAmmoType ) );
		pMarine->RemoveAmmo( info.m_iShots, m_iPrimaryAmmoType );
	}

	info.m_flDistance = asw_weapon_max_shooting_distance.GetFloat();
	info.m_iAmmoType = m_iPrimaryAmmoType;
	info.m_iTracerFreq = 1;  // asw tracer test everytime
	info.m_flDamageForceScale = asw_weapon_force_scale.GetFloat();

	info.m_vecSpread = pMarine->GetActiveWeapon()->GetBulletSpread();
	info.m_flDamage = GetWeaponDamage();
#ifndef CLIENT_DLL
	if (asw_debug_marine_damage.GetBool())
		Msg("Weapon dmg = %f\n", info.m_flDamage);
	info.m_flDamage *= pMarine->GetMarineResource()->OnFired_GetDamageScale();
	if (asw_DebugAutoAim.GetBool())
	{
		NDebugOverlay::Line(info.m_vecSrc, info.m_vecSrc + info.m_vecDirShooting * info.m_flDistance, 64, 0, 64, true, 1.0);
	}
#endif

	pMarine->FireBullets( info );

	// increment shooting stats
#ifndef CLIENT_DLL
	if (pMarine && pMarine->GetMarineResource())
	{
		pMarine->GetMarineResource()->UsedWeapon(this, info.m_iShots);
		pMarine->OnWeaponFired( this, info.m_iShots );
	}
#endif
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponHL2Pistol::PrimaryAttack( void )
{
	if ( ( gpGlobals->curtime - m_flLastAttackTime ) > 0.5f )
	{
		m_nNumShotsFired = 0;
	}
	else
	{
		m_nNumShotsFired++;
	}

	m_flLastAttackTime = gpGlobals->curtime;
	m_flSoonestPrimaryAttack = gpGlobals->curtime + PISTOL_FASTEST_REFIRE_TIME;

	CBasePlayer *pOwner = ToBasePlayer( GetOwner() );

	if( pOwner )
	{
		// Each time the player fires the pistol, reset the view punch. This prevents
		// the aim from 'drifting off' when the player fires very quickly. This may
		// not be the ideal way to achieve this, but it's cheap and it works, which is
		// great for a feature we're evaluating. (sjb)
		pOwner->ViewPunchReset();
	}

		// Only the player fires this way so we can cast
	CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
	if (!pPlayer)
		return;
	
	// Abort here to handle burst and auto fire modes
	if ( (UsesClipsForAmmo1() && m_iClip1 == 0) || ( !UsesClipsForAmmo1() && !pPlayer->GetAmmoCount(m_iPrimaryAmmoType) ) )
		return;

	m_nShotsFired++;

	pPlayer->DoMuzzleFlash();

	// To make the firing framerate independent, we may have to fire more than one bullet here on low-framerate systems, 
	// especially if the weapon we're firing has a really fast rate of fire.
	int iBulletsToFire = 0;
	float fireRate = GetFireRate();

	while ( m_flNextPrimaryAttack <= gpGlobals->curtime )
	{
		// MUST call sound before removing a round from the clip of a CHLMachineGun
		WeaponSound(SINGLE, m_flNextPrimaryAttack);
		m_flNextPrimaryAttack = m_flNextPrimaryAttack + fireRate;
		iBulletsToFire++;
	}

	// Make sure we don't fire more than the amount in the clip, if this weapon uses clips
	if ( UsesClipsForAmmo1() )
	{
		if ( iBulletsToFire > m_iClip1 )
			iBulletsToFire = m_iClip1;
		m_iClip1 -= iBulletsToFire;
	}

	CSDKPlayer *pSDKPlayer = ToSDKPlayer( pPlayer );

	// Fire the bullets
	FireBulletsInfo_t info;
	info.m_iShots = iBulletsToFire;
	info.m_vecSrc = pSDKPlayer->Weapon_ShootPosition( );
	info.m_vecDirShooting = pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES );
	info.m_vecSpread = GetBulletSpread();
	info.m_flDistance = MAX_TRACE_LENGTH;
	info.m_iAmmoType = m_iPrimaryAmmoType;
	info.m_iTracerFreq = 2;
	info.m_iDamage = GetSDKWpnData().m_iDamage;
	pPlayer->FireBullets( info );

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

	SendWeaponAnim( GetPrimaryAttackActivity() );
	pPlayer->SetAnimation( PLAYER_ATTACK1 );
	pSDKPlayer->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY );

	// Abort here to handle burst and auto fire modes
	if ( (UsesClipsForAmmo1() && m_iClip1 == 0) || ( !UsesClipsForAmmo1() && !pOwner->GetAmmoCount(m_iPrimaryAmmoType) ) )
		return;

	// Add an accuracy penalty which can move past our maximum penalty time if we're really spastic
	m_flAccuracyPenalty += PISTOL_ACCURACY_SHOT_PENALTY_TIME;
}
void CASW_Weapon_HealGrenade::PrimaryAttack( void )
{	
	CASW_Player *pPlayer = GetCommander();
	if (!pPlayer)
		return;

	CASW_Marine *pMarine = GetMarine();
#ifndef CLIENT_DLL
	bool bThisActive = (pMarine && pMarine->GetActiveWeapon() == this);
#endif

	if ( !pMarine )
		return;

	// MUST call sound before removing a round from the clip of a CMachineGun
	WeaponSound(SINGLE);

	// sets the animation on the weapon model iteself
	SendWeaponAnim( GetPrimaryAttackActivity() );

	// sets the animation on the marine holding this weapon
	//pMarine->SetAnimation( PLAYER_ATTACK1 );
#ifndef CLIENT_DLL
	Vector	vecSrc		= pMarine->Weapon_ShootPosition( );
	Vector	vecAiming	= pPlayer->GetAutoaimVectorForMarine(pMarine, GetAutoAimAmount(), GetVerticalAdjustOnlyAutoAimAmount());	// 45 degrees = 0.707106781187

	if ( !pMarine->IsInhabited() && vecSrc.DistTo( pMarine->m_vecOffhandItemSpot ) < 150.0f )
	{
		vecSrc.x = pMarine->m_vecOffhandItemSpot.x;
		vecSrc.y = pMarine->m_vecOffhandItemSpot.y;
		vecSrc.z += 50.0f;
	}

	QAngle ang = pPlayer->EyeAngles();
	ang.x = 0;
	ang.z = 0;
	CShotManipulator Manipulator( vecAiming );
	AngularImpulse rotSpeed(0,0,720);

	// create a pellet at some random spread direction			
	Vector newVel = Manipulator.ApplySpread(GetBulletSpread());
	if ( pMarine->GetWaterLevel() != 3 )
	{
		CreateProjectile( vecSrc, ang, newVel, rotSpeed, pMarine );
		pMarine->OnWeaponFired( this, 1 );
	}

	pMarine->GetMarineSpeech()->Chatter(CHATTER_MEDKIT);
#endif

	// decrement ammo
	m_iClip1 -= 1;

#ifndef CLIENT_DLL
	// destroy if empty
	if ( UsesClipsForAmmo1() && !m_iClip1 ) 
	{
		ASWFailAdvice()->OnMedSatchelEmpty();

		pMarine->GetMarineSpeech()->Chatter( CHATTER_MEDS_NONE );

		if ( pMarine )
		{
			pMarine->Weapon_Detach(this);
			if ( bThisActive )
				pMarine->SwitchToNextBestWeapon(NULL);
		}
		Kill();

		return;
	}
#endif

	m_flSoonestPrimaryAttack = gpGlobals->curtime + GetRefireTime();
	if (m_iClip1 > 0)		// only force the fire wait time if we have ammo for another shot
		m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate();
	else
		m_flNextPrimaryAttack = gpGlobals->curtime;

	//m_flLastFireTime = gpGlobals->curtime;
}
void CASW_Weapon_Medkit::SelfHeal()
{
	CASW_Marine *pMarine = GetMarine();

	if (pMarine)		// firing from a marine
	{
		if (pMarine->GetHealth() >= pMarine->GetMaxHealth())		// already on full health
			return;

		if (pMarine->GetHealth() <= 0)		// aleady dead!
			return;

		if (pMarine->m_bSlowHeal)			// already healing
			return;

		if (pMarine->GetFlags() & FL_FROZEN)	// don't allow this if the marine is frozen
			return;

		// MUST call sound before removing a round from the clip of a CMachineGun
		WeaponSound(SINGLE);

		// sets the animation on the weapon model iteself
		SendWeaponAnim( GetPrimaryAttackActivity() );

		// sets the animation on the marine holding this weapon
		//pMarine->SetAnimation( PLAYER_ATTACK1 );
#ifndef CLIENT_DLL
		bool bMedic = (pMarine->GetMarineProfile() && pMarine->GetMarineProfile()->CanUseFirstAid());
		// put a slow heal onto the marine, play a particle effect
		if (!pMarine->m_bSlowHeal && pMarine->GetHealth() < pMarine->GetMaxHealth())
		{
			pMarine->AddSlowHeal( GetHealAmount(), 1, pMarine, this );

			// Fire event
			IGameEvent * event = gameeventmanager->CreateEvent( "player_heal" );
			if ( event )
			{
				CASW_Player *pPlayer = GetCommander();
				event->SetInt( "userid", ( pPlayer ? pPlayer->GetUserID() : 0 ) );
				event->SetInt( "entindex", pMarine->entindex() );
				gameeventmanager->FireEvent( event );
			}

			if ( ASWGameRules()->GetInfoHeal() )
			{
				ASWGameRules()->GetInfoHeal()->OnMarineHealed( pMarine, pMarine, this );

			}
			pMarine->OnWeaponFired( this, 1 );
		}
		
		if (pMarine->IsInfested() && bMedic)
		{
			float fCure = GetInfestationCureAmount();
			// cure infestation
			if (fCure < 100)
				pMarine->CureInfestation(pMarine, fCure);
		}
#endif
		// decrement ammo
		m_iClip1 -= 1;

#ifndef CLIENT_DLL
		DestroyIfEmpty( false );
#endif
	}
}
//-----------------------------------------------------------------------------
// Purpose: 
//
//
//-----------------------------------------------------------------------------
void CHLMachineGun::PrimaryAttack( void )
{
	// Only the player fires this way so we can cast
	CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
	if (!pPlayer)
		return;
	
	// Abort here to handle burst and auto fire modes
	if ( (UsesClipsForAmmo1() && m_iClip1 == 0) || ( !UsesClipsForAmmo1() && !pPlayer->GetAmmoCount(m_iPrimaryAmmoType) ) )
		return;

	m_nShotsFired++;

	pPlayer->DoMuzzleFlash();

	// To make the firing framerate independent, we may have to fire more than one bullet here on low-framerate systems, 
	// especially if the weapon we're firing has a really fast rate of fire.
	int iBulletsToFire = 0;
	float fireRate = GetFireRate();

	// MUST call sound before removing a round from the clip of a CHLMachineGun
	while ( m_flNextPrimaryAttack <= gpGlobals->curtime )
	{
		WeaponSound(SINGLE, m_flNextPrimaryAttack);
		m_flNextPrimaryAttack = m_flNextPrimaryAttack + fireRate;
		iBulletsToFire++;
	}

	// Make sure we don't fire more than the amount in the clip, if this weapon uses clips
	if ( UsesClipsForAmmo1() )
	{
		if ( iBulletsToFire > m_iClip1 )
			iBulletsToFire = m_iClip1;
		m_iClip1 -= iBulletsToFire;
	}

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

	// Fire the bullets
	FireBulletsInfo_t info;
	info.m_iShots = iBulletsToFire;
	info.m_vecSrc = pPlayer->Weapon_ShootPosition( );
	info.m_vecDirShooting = pPlayer->GetAutoaimVector( AUTOAIM_SCALE_DEFAULT );
	info.m_vecSpread = pPlayer->GetAttackSpread( this );
	info.m_flDistance = MAX_TRACE_LENGTH;
	info.m_iAmmoType = m_iPrimaryAmmoType;
	info.m_iTracerFreq = 2;
	FireBullets( info );

	//Factor in the view kick
	AddViewKick();

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

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

	// Register a muzzleflash for the AI
	pPlayer->SetMuzzleFlashTime( gpGlobals->curtime + 0.5 );
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponCombatBurstRifle::PrimaryAttack( void )
{
	CBaseTFPlayer *pPlayer = (CBaseTFPlayer*)GetOwner();
	if (!pPlayer)
		return;
	
	WeaponSound(SINGLE);

	// Fire the bullets
	Vector vecSrc = pPlayer->Weapon_ShootPosition( );
	Vector vecSpread = GetBulletSpread();
	Vector vecAiming, vecRight, vecUp;
	pPlayer->EyeVectors( &vecAiming, &vecRight, &vecUp );

	// Add some inaccuracy
	int seed = 0;
	float x, y, z;
	do 
	{
		float x1, x2, y1, y2;

		// Note the additional seed because otherwise we get the same set of random #'s and will get stuck
		//  in an infinite loop here potentially
		// FIXME:  Can we use a gaussian random # function instead?  ywb
		x1 = SHARED_RANDOMFLOAT_SEED( -0.5, 0.5, ++seed );
		x2 = SHARED_RANDOMFLOAT_SEED( -0.5, 0.5, ++seed );
		y1 = SHARED_RANDOMFLOAT_SEED( -0.5, 0.5, ++seed );
		y2 = SHARED_RANDOMFLOAT_SEED( -0.5, 0.5, ++seed );

		x = x1 + x2;
		y = y1 + y2;

		z = x*x+y*y;
	} while (z > 1);
	Vector vecDir = vecAiming + x * vecSpread.x * vecRight + y * vecSpread.y * vecUp;

	PlayAttackAnimation( GetPrimaryAttackActivity() );

	// Shift it down a bit so the firer can see it
	Vector right, forward;
	AngleVectors( pPlayer->EyeAngles() + pPlayer->m_Local.m_vecPunchAngle, &forward, &right, NULL );
	Vector vecStartSpot = vecSrc;

	// Get the firing position
#ifdef CLIENT_DLL
	// On our client, grab the viewmodel's firing position
	Vector vecWorldOffset = vecStartSpot + Vector(0,0,-8) + right * 12 + forward * 16;
#else
	// For everyone else, grab the weapon model's position
	/*
	Vector vecWorldOffset;
	QAngle angIgnore;
	GetAttachment( LookupAttachment( "muzzle" ), vecWorldOffset, angIgnore );
	*/

	Vector vecWorldOffset = vecStartSpot + Vector(0,0,-8) + right * 12 + forward * 16;
#endif
	Vector gunOffset = vecWorldOffset - vecStartSpot;

	CPowerPlasmaProjectile *pPlasma = CPowerPlasmaProjectile::CreatePredicted( vecStartSpot, vecDir, gunOffset, DMG_ENERGYBEAM, pPlayer );
	if ( pPlasma )
	{
		pPlasma->SetDamage( weapon_combat_burstrifle_damage.GetFloat() );
		pPlasma->m_hOwner = pPlayer;
		pPlasma->SetPower( 2.0 );
		pPlasma->SetMaxRange( weapon_combat_burstrifle_range.GetFloat() );
		pPlasma->Activate();
	}

	m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate();
	m_iClip1 = m_iClip1 - 1;
}