const QAngle& CASW_Weapon_Hornet_Barrage::GetRocketAngle()
{
	static QAngle angRocket = vec3_angle;
	CASW_Player *pPlayer = GetCommander();
	CASW_Marine *pMarine = GetMarine();
	if ( !pPlayer || !pMarine || pMarine->GetHealth() <= 0 )
	{
		return angRocket;
	}

	Vector vecDir = pPlayer->GetAutoaimVectorForMarine(pMarine, GetAutoAimAmount(), GetVerticalAdjustOnlyAutoAimAmount());	// 45 degrees = 0.707106781187
	VectorAngles( vecDir, angRocket );
	angRocket[ YAW ] += random->RandomFloat( -35, 35 );
	return angRocket;
}
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;
}
Exemplo n.º 3
0
void CASW_Weapon_Sniper_Rifle::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;

	// 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

	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 )
		{
			// 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;
	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->GetMarineResource()->OnFired_GetDamageScale();
#endif

	int iPenetration = 1;
	if ( pMarine->GetDamageBuffEndTime() > gpGlobals->curtime )		// sniper rifle penetrates more targets when marine is in a damage amp
	{
		iPenetration = 3;
	}
	pMarine->FirePenetratingBullets( info, iPenetration, 3.5f, 0, true, NULL, false  );

	// 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;
}
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_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;
}
Exemplo n.º 6
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;
}
Exemplo n.º 7
0
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
}
void CASW_Weapon_Ammo_Satchel::DeployAmmoDrop()
{
	CASW_Player *pPlayer = GetCommander();
	if ( !pPlayer )
		return;

	if ( gpGlobals->curtime <= m_fLastAmmoDropTime + 1.0f )
	{
		return;
	}
	m_fLastAmmoDropTime = gpGlobals->curtime;
	if( m_iClip1 <= 0  )
	{
		//softcopy: TODO
		//temporary let it work; "asw_ent_create asw_weapon_ammo_satchel", to make ammo pack with pre-defined packs
		//Assert( false );     
		m_iClip1 = AMMO_SATCHEL_DEFAULT_DROP_COUNT; 	
		Assert( true );								

		return;
	}

	CASW_Marine *pMarine = GetMarine();
	if ( !pMarine )
		return;
	
	WeaponSound(SINGLE);

#ifndef CLIENT_DLL
	Vector	vecAiming	= pPlayer->GetAutoaimVectorForMarine(pMarine, GetAutoAimAmount(), GetVerticalAdjustOnlyAutoAimAmount());	// 45 degrees = 0.707106781187
	Vector	vecSrc		= pMarine->Weapon_ShootPosition( ) + (vecAiming * 8);

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

	Vector newVel = GetBulletSpread();
	if ( pMarine->GetWaterLevel() == 3 )
	{		
		CBaseEntity::EmitSound( "ASW_Ammobag.Fail" );
		return;
	}
	
	Vector vecSatchelMins = Vector(-20,-20,0);
	Vector vecSatchelMaxs = Vector(20,20,60);
	trace_t tr;

	UTIL_TraceHull( vecSrc + Vector( 0, 0, 50 ),
				vecSrc + Vector( 0, 0, -50 ),
				vecSatchelMins,
				vecSatchelMaxs,
				MASK_SOLID,
				pMarine,
				COLLISION_GROUP_NONE,
				&tr );

	if ( tr.startsolid || tr.allsolid || ( tr.DidHit() && tr.fraction <= 0 ) || tr.fraction >= 1.0f ) // if there's something in the way, or no floor, don't deploy
	{
		// Try right under the player
		vecSrc = pMarine->GetAbsOrigin();

		UTIL_TraceHull( vecSrc + Vector( 0, 0, 50 ),
			vecSrc + Vector( 0, 0, 50 ),
			vecSatchelMins,
			vecSatchelMaxs,
			MASK_SOLID,
			pMarine,
			COLLISION_GROUP_NONE,
			&tr );

		if ( tr.startsolid || tr.allsolid || ( tr.DidHit() && tr.fraction <= 0 ) || tr.fraction >= 1.0f )
		{
			// Ok, fail
			CBaseEntity::EmitSound( "ASW_Ammobag.Fail" );
			return;
		}
	}

	vecSrc.z = tr.endpos.z;

	CASW_Ammo_Drop *pAmmoDrop = (CASW_Ammo_Drop *)CreateEntityByName( "asw_ammo_drop" );	

	UTIL_TraceLine( vecSrc, vecSrc + Vector(0, 0, -60), 
		MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr);

	UTIL_SetOrigin( pAmmoDrop, tr.endpos );
	pAmmoDrop->SetDeployer( pMarine );
	DispatchSpawn( pAmmoDrop );
	pAmmoDrop->PlayDeploySound();

	// Rotate it in the marine's facing direction
	QAngle angMarine = pMarine->GetAbsAngles();
	angMarine.x = 0;
	angMarine.z = 0;
	pAmmoDrop->SetAbsAngles( angMarine );

	CBaseEntity *pHelpHelpImBeingSupressed = (CBaseEntity*) te->GetSuppressHost();
	te->SetSuppressHost( NULL );
	DispatchParticleEffect( "ammo_satchel_take_med", pAmmoDrop->GetAbsOrigin() + Vector( 0, 0, 4 ), vec3_angle );
	te->SetSuppressHost( pHelpHelpImBeingSupressed );
	pMarine->OnWeaponFired( this, 1 );

	IGameEvent * event = gameeventmanager->CreateEvent( "player_deploy_ammo" );
	if ( event )
	{
		CASW_Marine *pMarine = GetMarine();
		CASW_Player *pPlayer = NULL;

		if ( pMarine )
		{
			pPlayer = pMarine->GetCommander();
		}

		event->SetInt( "userid", ( pPlayer ? pPlayer->GetUserID() : 0 ) );

		gameeventmanager->FireEvent( event );
	}
#endif

	m_iClip1--;
	if ( m_iClip1 <= 0 )
	{
#ifndef CLIENT_DLL
		pMarine->Weapon_Detach(this);
		Kill();
#endif
		pMarine->SwitchToNextBestWeapon( NULL );
	}
}
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 CASW_Weapon_Chainsaw::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 || !pMarine->IsAlive())
	{
		EndAttack();
		return;
	}

	// don't fire underwater
	if ( pMarine->GetWaterLevel() == 3 )
	{
		if ( m_fireState != FIRE_OFF || m_hBeam )
		{
			EndAttack();
		}
		else
		{
			WeaponSound( EMPTY );
		}

		m_flNextPrimaryAttack = gpGlobals->curtime + GetWeaponInfo()->m_flFireRate;
		m_flNextSecondaryAttack = gpGlobals->curtime + GetWeaponInfo()->m_flFireRate;
		return;
	}

#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( );
	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
	}

	// make vecaiming go down at 45 degrees
	vecAiming.z = 0;
	VectorNormalize(vecAiming);
	vecAiming.z = -1.0f;
	VectorNormalize(vecAiming);

	switch( m_fireState )
	{
		case FIRE_OFF:
		{
			//if ( !HasAmmo() )
			//{
				//m_flNextPrimaryAttack = gpGlobals->curtime + 0.25;
				//m_flNextSecondaryAttack = gpGlobals->curtime + 0.25;
				//WeaponSound( EMPTY );
				//return;
			//}

			m_flAmmoUseTime = gpGlobals->curtime;// start using ammo ASAP.

			SendWeaponAnim( ACT_VM_PRIMARYATTACK );
						
			m_flShakeTime = 0;
			m_flStartFireTime = gpGlobals->curtime;

			SetWeaponIdleTime( gpGlobals->curtime + 0.1 );

			m_flDmgTime = gpGlobals->curtime + ASW_CHAINSAW_PULSE_INTERVAL;			
			SetFiringState(FIRE_STARTUP);
		}
		break;

		case FIRE_STARTUP:
		{
			Fire( vecSrc, vecAiming );
#ifndef CLIENT_DLL
			pMarine->OnWeaponFired( this, 1 );
#endif
		
			if ( gpGlobals->curtime >= ( m_flStartFireTime + ASW_CHAINSAW_CHARGE_UP_TIME ) )
			{
                //EmitSound( "ASW_Chainsaw.AttackLoop" );
				
				SetFiringState(FIRE_CHARGE);
			}

			if ( !HasAmmo() )
			{
				EndAttack();
				m_flNextPrimaryAttack = gpGlobals->curtime + 1.0;
				m_flNextSecondaryAttack = gpGlobals->curtime + 1.0;
			}
		}
		break;

		case FIRE_CHARGE:
		{
			Fire( vecSrc, vecAiming );
#ifndef CLIENT_DLL
			pMarine->OnWeaponFired( this, 1 );
#endif
		
			if ( !HasAmmo() )
			{
				EndAttack();
				m_flNextPrimaryAttack = gpGlobals->curtime + 1.0;
				m_flNextSecondaryAttack = gpGlobals->curtime + 1.0;
			}
		}
		break;
	}
}