/*
 * Class:  Elite_Stinger
 * By: James Bishop A.K.A. *PingFre@K*
 * Copyright 1998-2009 Epic Games, Inc. All Rights Reserved.
*/

class Elite_Stinger extends Elite_Weapon
	dependson(MutEM_XX);

/////////////////////////////////////////////////////////////////
// Bursting Vars
/////////////////////////////////////////////////////////////////

/** How many shots have been fired in burst */
var int BurstCnt;

/** How many shots max in burst before going to cool down */
var int BurstMax;

/** How long to cool down */
var float BurstCoolDownTime;

var() int StingerRecoil;

simulated function PostBeginPlay()
{
	super.PostBeginPlay();
	
   if ( class'MutEM_XX'.default.Config_Stinger.bDoubles )
   {
   BecomeDual();
   }

	if ( Role == ROLE_Authority )
		SetTimer(class'MutEM_XX'.default.Config_Stinger.fPriFireInterval * 2, true, 'AmmoRegen');
		
	FireInterval[0]=class'MutEM_XX'.default.Config_Stinger.fPriFireInterval;
   FireInterval[1]=class'MutEM_XX'.default.Config_Stinger.fSecFireInterval;

   Spread[0]=class'MutEM_XX'.default.Config_Stinger.fPriSpread;
   Spread[1]=class'MutEM_XX'.default.Config_Stinger.fSecSpread;

   MaxDesireability=class'MutEM_XX'.default.Config_Stinger.fAIRating;
   AIRating=class'MutEM_XX'.default.Config_Stinger.fAIRating;
   CurrentRating=class'MutEM_XX'.default.Config_Stinger.fAIRating;

   ShotCost[0]=class'MutEM_XX'.default.Config_Stinger.iShotCost;
   ShotCost[1]=class'MutEM_XX'.default.Config_Stinger.iShotCost;

   AimingHelpRadius[0]=class'MutEM_XX'.default.Config_Stinger.iAimingHelpRadius;
   AimingHelpRadius[1]=class'MutEM_XX'.default.Config_Stinger.iAimingHelpRadius;
   AimError=class'MutEM_XX'.default.Config_Stinger.iAimError;

   AmmoCount=class'MutEM_XX'.default.Config_Stinger.iAmmoCount;
   LockerAmmoCount=class'MutEM_XX'.default.Config_Stinger.iAmmoCount;
   MaxAmmoCount=class'MutEM_XX'.default.Config_Stinger.iMaxAmmoCount;

   StingerRecoil=class'MutEM_XX'.default.Config_Stinger.iStingerRecoil;
}

function AmmoRegen()
{
   if ( class'MutEM_XX'.default.Config_Stinger.bAmmoRegeneration )
   {
	   if ( Instigator != None && !IsFiring() && AmmoCount < class'MutEM_XX'.default.Config_Stinger.iMaxAmmoCount )
	   {
		   AddAmmo(1);
	   }
   }
}

/* I'm making the recoil being handled in this function */
simulated function ProcessRecoil()
{
   if (Instigator != None)
   {	// Recoil will knock the player back
      Instigator.AddVelocity( Normal(vector(Rotation) * -1 ) * class'MutEM_XX'.default.Config_Stinger.iStingerRecoil / Instigator.Mass,
      Instigator.Location,
	   InstantHitDamageTypes[0] );
   }
}

/**
 * Detect that we are trying to pickup another link gun and switch in to dual mode.
 */
function bool DenyPickupQuery(class<Inventory> ItemClass, Actor Pickup)
{
	if (ItemClass==class && DualMode != EDM_Dual)
	{
      if ( class'MutEM_XX'.default.Config_Stinger.bDoubles )
      {
		   DualMode = EDM_DualEquipping;
		   BecomeDual();			// Handle any animations/effects locally.
		}
	}
	return super.DenyPickupQuery(ItemClass, Pickup);
}

simulated state SecondaryFire extends WeaponFiring
{

	simulated function PlayWeaponAnimation( Name Sequence, float fDesiredDuration, optional bool bLoop, optional SkeletalMeshComponent SkelMesh)
	{
		if (BurstCnt != 1)
		{
			return;
		}

		fDesiredDuration = 0.8667; // @FIXME - Match anims to shot speed

		Global.PlayWeaponAnimation(Sequence, fDesiredDuration, bLoop, SkelMesh);
	}

	simulated function bool TryPutDown()
	{
		bWeaponPutDown = true;
		return true;
	}

	simulated function RefireCheckTimer()
	{
		// if out of ammo, then call weapon empty notification
		if( !HasAnyAmmo() )
		{
			WeaponEmpty();
		}
		else
		{
			// Check to see if we have shot our burst
			if (BurstCnt == BurstMax || !HasAmmo(CurrentFireMode))
			{
				GotoState('WeaponBurstCoolDown');
			}
			else
			{
				// If weapon should keep on firing, then do not leave state and fire again.
				BurstCnt++;
				FireAmmunition();
			}
		}
	}

	simulated function BeginState(name PrevStateName)
	{
		BurstCnt = 1;
		Super.BeginState(PrevStateName);
	}

	simulated function EndState(name NextStateName)
	{
		Super.EndState(NextStateName);
		Cleartimer('RefireCheckTimer');
	}
}

simulated State WeaponBurstCoolDown
{
	simulated function EndState(name NextStateName)
	{
		super.EndState(NextStateName);
		ClearTimer('WeaponReady');
	}

	simulated function BeginState(name PrevStateName)
	{

		local float CoolDowntime;

		if ( UTPawn(Owner) == None || UTPawn(Owner).FireRateMultiplier==1.0 )
		{
			CoolDownTime = BurstCoolDowntime;
		}
		else
		{
			CoolDownTime = BurstCoolDowntime*0.3125;
		}

		SetTimer(CoolDowntime,false,'WeaponReady');

	}

	simulated function WeaponReady()
	{
		// if switching to another weapon, abort firing and put down right away
		if( bWeaponPutDown )
		{
			PutDownWeapon();
		}
		else if ( PendingFire(1) )
		{
			SendToFiringState(1);
		}
		else
		{
			GotoState('Active');
		}
	}
}

simulated function PlayFireEffects( byte FireModeNum, optional vector HitLocation )
{
	local float Rate;
	// Play Weapon fire animation

	Rate = GetFireInterval(FireModeNum);

	// If we are in dual mode, we want to back it out to the normal speed

	if (DualMode == EDM_Dual)
	{
		Rate *= 2;
	}

	if ( FireModeNum < WeaponFireAnim.Length && WeaponFireAnim[FireModeNum] != '' )
	{
		PlayWeaponAnimation( GetFireAnim(FireModeNum), Rate,, UseLeftBarrel() ? LeftMesh : None );
		bLastFiredLeft=UseLeftBarrel();
	}

	// Start muzzle flash effect
	CauseMuzzleFlash();
	ShakeView();
	TrackShotCount();
   // Start Recoil effect - I had to start it somewhere
   ProcessRecoil();
}

simulated event SetPosition(UTPawn Holder)
{
	local vector OldSmallWeaponsOffset;

	if (LeftMesh != None)
	{
		switch (GetHand())
		{
			case HAND_Left:
				LeftMesh.SetScale3D(default.Mesh.Scale3D);
            LeftMesh.SetRotation(default.Mesh.Rotation);
				break;
			case HAND_Right:
				LeftMesh.SetScale3D(default.Mesh.Scale3D * vect(1,-0,1));
				LeftMesh.SetRotation(default.Mesh.Rotation * -1);
				break;
			default:
				break;
		}
	}

	OldSmallWeaponsOffset = SmallWeaponsOffset;

      SmallWeaponsOffset.X = 16.0;   ////////////////<--- Change for Shock ///////////////////////
      SmallWeaponsOffset.Y = 6.0;
      SmallWeaponsOffset.Z = -6.0;
      PlayerViewOffset.X  = 0;
      PlayerViewOffset.Y  = 2;
      PlayerViewOffset.Z  = 0;
/*
//      FireOffset.X = 0;//19;
//      FireOffset.Y = 0;
//      FireOffset.Z = 0;//-10;

      if( bLastFiredLeft )
      {
      PlayerViewOffset.X  = 0;
      PlayerViewOffset.Y  = 2;
      PlayerViewOffset.Z  = 0;
      SmallWeaponsOffset.X = 16.0;
      SmallWeaponsOffset.Y = 6.0;
      SmallWeaponsOffset.Z = -6.0;
      }
      else
      {
      PlayerViewOffset.X  = 0;
      PlayerViewOffset.Y  = 16;
      PlayerViewOffset.Z  = 0;
      SmallWeaponsOffset.X = 16.0;
      SmallWeaponsOffset.Y = 16.0;
      SmallWeaponsOffset.Z = -6.0;
      }
*/


	Super.SetPosition(Holder);

	SmallWeaponsOffset = OldSmallWeaponsOffset;
}

/**
 * Causes the muzzle flashlight to turn on and setup a time to
 * turn it back off again.
 */
simulated event CauseMuzzleFlash()
{
	local int Index;
	local UTPawn P;

	if ( WorldInfo.NetMode != NM_Client )
	{
		P = UTPawn(Instigator);
		if ( (P == None) || !P.bUpdateEyeHeight )
		{
			return;
		}
	}
	if ( !bMuzzleFlashAttached )
	{
		AttachMuzzleFlash();
	}
	CauseMuzzleFlashLight();

	if (GetHand() != HAND_Hidden)
	{
		Index = UseLeftBarrel() ? 1 : 0;

		if (EliteMachine_MuzzleFlashPSC[Index] != none)
		{
			EliteMachine_MuzzleFlashPSC[Index].SetTemplate(MuzzleFlashPSCTemplate);
			EliteMachine_MuzzleFlashPSC[Index].SetVectorParameter('MFlashScale',Vect(0.5,0.5,0.5));
			EliteMachine_MuzzleFlashPSC[Index].ActivateSystem();
		}
		
		if (EliteMachine_MuzzleFlashPSC[Index] != none && Instigator.FiringMode == 1)
		{
			EliteMachine_MuzzleFlashPSC[Index].SetTemplate(MuzzleFlashAltPSCTemplate);
			EliteMachine_MuzzleFlashPSC[Index].SetVectorParameter('MFlashScale',Vect(0.5,0.5,0.5));
			EliteMachine_MuzzleFlashPSC[Index].ActivateSystem();
		}

		// Set when to turn it off.
		if (Index > 0 )
		{
			SetTimer(MuzzleFlashDuration,false,'MuzzleFlashTimerLeft');
		}
		else
		{
			SetTimer(MuzzleFlashDuration,false,'MuzzleFlashTimerRight');
		}
	}
}

//-----------------------------------------------------------------
// AI Interface

function float GetAIRating()
{
	local UTBot B;

	B = UTBot(Instigator.Controller);
	if ( (B== None) || (B.Enemy == None) )
		return AIRating;

	if ( !B.LineOfSightTo(B.Enemy) )
		return AIRating - 0.15;

	return AIRating * FMin(Pawn(Owner).GetDamageScaling(), 1.5);
}

/* BestMode()
choose between regular or alt-fire
*/
function byte BestMode()
{
	local float EnemyDist;
	local UTBot B;

	if ( IsFiring() )
		return CurrentFireMode;

	B = UTBot(Instigator.Controller);
	if ( (B == None) || (B.Enemy == None) )
		return 0;

	EnemyDist = VSize(B.Enemy.Location - Instigator.Location);
	if ( EnemyDist < 2000 )
		return 0;
	return 1;
}

defaultproperties
{
	// First Gun
	Begin Object class=AnimNodeSequence Name=MeshSequenceA
	End Object

	// Second Gun
	Begin Object class=AnimNodeSequence Name=MeshSequenceB
	End Object

   // Skeletal Mesh
	Begin Object Name=FirstPersonMesh
		SkeletalMesh=SkeletalMesh'WP_Stinger.Mesh.SK_WP_Stinger_1P'
		Materials(0)=Material'EM_XX_Content.Slinger_Final_Mat'
      Animations=AnimNodeSequence'UTGame.Default__UTWeap_Stinger:MeshSequenceA'
      AnimSets(0)=AnimSet'WP_Stinger.Anims.K_WP_Stinger_1P_Base'
		FOV=65.0
	End Object

	// Pickup staticmesh
	Begin Object Name=PickupMesh
		SkeletalMesh=SkeletalMesh'EM_XX_Content.Mesh.Slinger_3P_Mid'
		Materials(0)=Material'EM_XX_Content.Slinger_Final_Mat'
	End Object

   BurstMax=1
   BurstCoolDownTime=0.001000
   DualIconCoordinates=(U=453.000000,V=508.000000,UL=147.000000,VL=52.000000)
   bTargetFrictionEnabled=True
   bTargetAdhesionEnabled=True

   AmmoCount=50
   LockerAmmoCount=50
   MaxAmmoCount=420
   
	EquipTime=+0.2
	PutDownTime=+0.2
	
	DualMode=EDM_DualEquipping

   ShotCost(1)=2
   IconX=273
   IconY=413
   IconWidth=84
   IconHeight=50
   IconCoordinates=(U=453.000000,V=508.000000,UL=147.000000,VL=52.000000)
   CrossHairCoordinates=(U=448.000000,V=0.000000)
   InventoryGroup=6
   AttachmentClass=Class'EM_XX.Elite_Stinger_Attach'
   GroupWeight=0.520000
   QuickPickGroup=6
   QuickPickWeight=0.900000
   WeaponFireAnim(0)="WeaponFire"
   WeaponFireAnim(1)="WeaponFire"
   WeaponFireSnd(0)=SoundCue'A_Weapon_Stinger.Weapons.A_Weapon_Stinger_FireAltCue'
   WeaponFireSnd(1)=SoundCue'A_Weapon_Stinger.Weapons.A_Weapon_Stinger_FireAltCue'
   WeaponPutDownSnd=SoundCue'A_Weapon_Stinger.Weapons.A_Weapon_Stinger_LowerCue'
   WeaponEquipSnd=SoundCue'A_Weapon_Stinger.Weapons.A_Weapon_Stinger_RaiseCue'
   WeaponColor=(B=0,G=255,R=255,A=255)
   MuzzleFlashPSCTemplate=ParticleSystem'WP_Stinger.Particles.P_Stinger_MF_Alt_Fire'
   MuzzleFlashAltPSCTemplate=ParticleSystem'WP_Stinger.Particles.P_Stinger_MF_Alt_Fire'
   MuzzleFlashLightClass=Class'UTGame.UTStingerMuzzleFlashLight'
   PlayerViewOffset=(X=0.000000,Y=2.000000,Z=0.000000)
   WidescreenRotationOffset=(Pitch=0,Yaw=0,Roll=0)
   CurrentRating=0.710000
   aimerror=700.000000
   AimingHelpRadius(0)=9.000000
   WeaponFireTypes(1)=EWFT_Projectile
   FiringStatesArray(1)="SecondaryFire"
   WeaponProjectiles(1)=Class'EM_XX.Elite_Stinger_S_Shard'
   FireInterval(0)=0.100000
   FireInterval(1)=0.280000
   Spread(0)=0.067500
   Spread(1)=0.000000
   InstantHitDamage(0)=14.000000

   FireOffset=(X=12.000000,Y=10.000000,Z=-10.000000)

   Priority=900.6
   AIRating=0.710000
   ItemName="Elite Stinger"
   MaxDesireability=0.730000
   PickupMessage="Elite Stinger"
   PickupSound=SoundCue'A_Pickups.Weapons.Cue.A_Pickup_Weapons_Stinger_Cue'
   bExportMenuData=True
   DroppedPickupMesh=PickupMesh
   PickupFactoryMesh=PickupMesh
   Name="Elite_Stinger"
}
