//=============================================================================
// DoubleAutoMag
//=============================================================================

//=============================================================================
// Begin Class
class DoubleAutoMag expands AutoMag;

var() class<DoubleAutoMag> DoubleAutoMagClass;
var DoubleAutoMag SlaveAutoMag;		// The left (second) DoubleAutoMag is a slave to the right.
var bool MasterAutoMag;             // This switch defines whether the DoubleAutoMag is a master or slave
var bool TwoMags;                   // True if two mags are deployed
var bool PrimaryFire, AlternateFire;
var float CarryValue;

replication
{
	reliable if ( Role == ROLE_Authority )
		SlaveAutoMag, MasterAutoMag;
}

event float BotDesireability(Pawn Bot)
{
	local DoubleAutoMag AlreadyHas;
	local float desire;

	desire = MaxDesireability + Bot.AdjustDesireFor(self);
	AlreadyHas = DoubleAutoMag(Bot.FindInventoryType(class));
	if ( (AlreadyHas != None) && AlreadyHas.TwoMags )
	{
		if ( (RespawnTime < 10)
			&& ( bHidden || (AlreadyHas.AmmoType == None)
				|| (AlreadyHas.AmmoType.AmmoAmount < AlreadyHas.AmmoType.MaxAmmo)) )
			return 0;
		if ( Level.Game.bCoopWeaponMode )
			return 0;
		if ( AlreadyHas.AmmoType == None )
			return 0.25 * desire;

		if ( AlreadyHas.AmmoType.AmmoAmount > 0 )
			return FMax( 0.25 * desire, 
					AlreadyHas.AmmoType.MaxDesireability
					 * FMin(1, 0.15 * AlreadyHas.AmmoType.MaxAmmo/AlreadyHas.AmmoType.AmmoAmount) ); 
	}
	if ( (Bot.Weapon == None) || (Bot.Weapon.AIRating <= 0.4) )
		return 2*desire;

	return desire;
}

auto state Pickup
{
	// When touched by an actor.
	function Touch( actor Other )
	{
		local Inventory oldItem;
		local Inventory Copy;
		
		// If touched by a player pawn, let him pick this up.
		if(ValidTouch(Other))
		{
			oldItem = Pawn(Other).FindInventoryType(DoubleAutoMagClass);
			if ((oldItem == none) || (DoubleAutoMag(oldItem).TwoMags)) {
				SpawnCopy(Pawn(Other));
				Pawn(Other).ClientMessage(PickupMessage, 'Pickup');
				PlaySound (PickupSound);		
				if ( Level.Game.Difficulty > 1 )
					Other.MakeNoise(0.1 * Level.Game.Difficulty);
			} else {	
				PlaySound (PickupSound);		
				if ( Level.Game.Difficulty > 1 )
					Other.MakeNoise(0.1 * Level.Game.Difficulty);
				Copy = SpawnCopy(Pawn(Other));
				if (DoubleAutoMag(oldItem).SetSlaveAutoMag(Copy))
					DoubleAutoMag(Copy).SetupSlaveAutoMag();
			}			
		}
	}
}

function bool HandlePickupQuery( inventory Item )
{
	if ((MasterAutoMag) && (SlaveAutoMag == None))
		return false;

	return Super.HandlePickupQuery(Item);
}

function bool SetRightHand()
{
	local Rotator newRot;

	if (PlayerPawn(Owner) != None)
	{
		// Set the Right handed mesh and correct the offset.	
		Mesh = mesh'AutoMagR';
		PlayerViewOffset.Y = Default.PlayerViewOffset.Y * -1;
		PlayerViewOffset.X = Default.PlayerViewOffset.X;
		PlayerViewOffset.Z = Default.PlayerViewOffset.Z;
		PlayerViewOffset *= 100;
		FireOffset.Y = Default.FireOffset.Y * -1;
		newRot = Rotation;
		newRot.Roll = Default.Rotation.Roll * -1;
		setRotation(newRot);
		SetLocation( Owner.Location + CalcDrawOffset() );
	}
	
	return true;
}

function bool SetLeftHand()
{
	local Rotator newRot;
	
	if (PlayerPawn(Owner) != None)
	{
		Mesh = mesh'AutoMagL';
		PlayerViewOffset.Y = Default.PlayerViewOffset.Y;
		PlayerViewOffset.X = Default.PlayerViewOffset.X;
		PlayerViewOffset.Z = Default.PlayerViewOffset.Z;
		PlayerViewOffset *= 100;
		FireOffset.Y = Default.FireOffset.Y;
		newRot = Rotation;
		newRot.Roll = Default.Rotation.Roll;
		setRotation(newRot);
		SetLocation(Owner.Location + CalcDrawOffset());
	}
	
	return true;
}

function bool SetSlaveAutoMag(Inventory SlaveMag)
{
	// Set the SlaveAutoMag reference.
	SlaveAutoMag = DoubleAutoMag(SlaveMag);

	TwoMags = true;
	AmmoType.AddAmmo(PickupAmmoCount);
	if (PlayerPawn(Owner) != None) {
		PlayerPawn(Owner).ClientMessage("Time to kick some ass John Woo style!");
		SetRightHand();
		PlayTwirl();
	}

	return true;
}

function bool SetupSlaveAutoMag()
{
	TwoMags = True;				// We now have two mags...
	SlaveAutoMag = none;		// A Slave doesn't have any slaves...
	MasterAutoMag = false;		// This isn't the Master

	SetLeftHand();

	GoToState('Idle2');
	
	return true;
}

function GiveTo( pawn Other )
{
	Instigator = Other;
	BecomeItem();
	Other.AddInventory(Self);
}

function inventory SpawnCopy( pawn Other )
{
	local Weapon newWeapon;

	newWeapon = Weapon(Super.SpawnCopy(Other));
	newWeapon.Instigator = Other;
	newWeapon.GiveAmmo(Other);
	newWeapon.SetSwitchPriority(Other);
	if ((!Other.bNeverSwitchOnPickup) && (!Other.IsA('DoubleAutoMag')))
		newWeapon.WeaponSet(Other);
	newWeapon.AmbientGlow = 0;
	return newWeapon;
}

function bool WeaponSet(Pawn Other)
{
	if (Other.IsA('DoubleAutoMag'))
		return false;
	return Super.WeaponSet(Other);
}

function setHand(float Hand)
{
	local rotator newRot;

	if (SlaveAutoMag == none) {
		if (Hand == -1) {
			SetRightHand();
		} else if (Hand == 0) {
			Super.SetHand(Hand);
			Mesh = mesh'AutoMagR';	
		} else if (Hand == 1) {
			SetLeftHand();
		}
	}
}

function BringUp()
{
	if ((MasterAutoMag) && (SlaveAutoMag != none)) {
		SetRightHand();
		SlaveAutoMag.SetLeftHand();
		SlaveAutoMag.BringUp();
	}
	if ( Owner.IsA('PlayerPawn') )
		PlayerPawn(Owner).EndZoom();	
	bWeaponUp = false;
	PlaySelect();
	GotoState('Active');
}

function Timer()
{
	if (SlaveAutoMag != none)
	{
		if (PrimaryFire) {
			PrimaryFire = false;
			SlaveAutoMag.Fire(CarryValue);
		} else if (AlternateFire) {
			AlternateFire = false;
			SlaveAutoMag.AltFire(CarryValue);
		}
	}
	SetTimer(0.0, false);
}

function Fire(float Value)
{
	if ((MasterAutoMag) && (SlaveAutoMag != none))
	{
		PrimaryFire = true;
		CarryValue = Value;
		SetTimer(0.25, true);
	}
	Super.Fire(Value);
}

function AltFire( float Value )
{
	if ((MasterAutoMag) && (SlaveAutoMag != none))
	{
		AlternateFire = true;
		CarryValue = Value;
		SetTimer(0.25, true);
	}
	Super.AltFire(Value);
}

state Active
{
	function Fire(float F) 
	{
	}

	function AltFire(float F) 
	{
	}

	function bool PutDown()
	{
		if ( bWeaponUp || (AnimFrame < 0.75) ) {
			if ((MasterAutoMag) && (SlaveAutoMag != none))
				SlaveAutoMag.GoToState('DownWeapon');
			GotoState('DownWeapon');
		} else
			bChangeWeapon = true;
		return True;
	}

	function BeginState()
	{
		bChangeWeapon = false;
	}

Begin:
	if ((MasterAutoMag) && (SlaveAutoMag != none)) {
		FinishAnim();
		PlayPostSelect();
		FinishAnim();
		PlayTwirl();
	}
	FinishAnim();
	if ( bChangeWeapon )
		GotoState('DownWeapon');
	bWeaponUp = True;
	if (MasterAutoMag) {
		PlayPostSelect();
		FinishAnim();
	}
	Finish();
}

State DownWeapon
{
ignores Fire, AltFire;

	function bool PutDown()
	{
		return true; //just keep putting it down
	}

	function BeginState()
	{
		bChangeWeapon = false;
	}

Begin:
	if ((MasterAutoMag) && (SlaveAutoMag != none))
		SlaveAutoMag.GoToState('DownWeapon');
	TweenDown();
	FinishAnim();
	bOnlyOwnerSee = false;
	Pawn(Owner).ChangedWeapon();
}

state NormalFire
{
Begin:
	if (AnimSequence!='Shoot0') 
	{
		PlayAnim('Shoot',2.5, 0.02);
		FinishAnim();
	}
	PlayAnim('Shoot0',0.26, 0.04);	
	FinishAnim();
	if (ClipCount>15) PlaySound(Misc1Sound, SLOT_None, 3.5*Pawn(Owner).SoundDampening);	
	if ( bChangeWeapon )
		GotoState('DownWeapon');
	else if ( PlayerPawn(Owner) == None )
		Super.Finish();
	// This else if is changed so that the left gun reloads.  (Originally, the code
	// had any weapon that got to this point that wasn't the player's main weapon
	// go into the idle state.  I don't see why they did that...
	else if (AmmoType.AmmoAmount<=0)
		GotoState('Idle');
	else if (ClipCount>=20) GoToState('NewClip');
	else if ( Pawn(Owner).bFire!=0 ) Global.Fire(0);
	else if ( Pawn(Owner).bAltFire!=0 )Global.AltFire(0);		
	PlayAnim('Shoot2',0.8, 0.0);	
	FinishAnim();
	GoToState('Idle');
}

state AltFiring
{
ignores Fire, AltFire;

Begin:
	FinishAnim();
	PlayAnim('Shot2a', 1.2, 0.05);	
	FinishAnim();
Repeater:	
	if (AmmoType.UseAmmo(1)) 
	{
		if ( PlayerPawn(Owner) != None )
			PlayerPawn(Owner).ShakeView(ShakeTime, ShakeMag, ShakeVert);
		ClipCount++;	
		TraceFire(AltAccuracy);
		PlayAltFiring();	
		FinishAnim();
	}
	if ( AltAccuracy < 3 ) 
		AltAccuracy += 0.5;
	if (ClipCount>15) PlaySound(Misc1Sound, SLOT_None, 3.5*Pawn(Owner).SoundDampening);		
	if ( bChangeWeapon )
		GotoState('DownWeapon');
	else if ( (Pawn(Owner).bAltFire!=0) 
		&& AmmoType.AmmoAmount>0 && ClipCount<20)
	{
		if ( PlayerPawn(Owner) == None )
			Pawn(Owner).bAltFire = int( FRand() < AltReFireRate );
		Goto('Repeater');	
	}
	PlayAnim('Shot2c', 0.7, 0.05);	
	FinishAnim();	
	PlayAnim('T2', 0.9, 0.05);	
	FinishAnim();
	Finish();
}

State Idle2
{
	Begin:
	if (!MasterAutoMag) {
		BringUp();
	}		
}

function TweenTwirl()
{
	TweenAnim('Twirl',0.001);
}

function PlayTwirl()
{
	PlayAnim('Twirl', 0.8, 0.0);
}

function PlaySelect()
{
	Super.PlaySelect();
}

function Finish()
{
	if ( bChangeWeapon )
		GotoState('DownWeapon');
	else if ( PlayerPawn(Owner) == None )
		Super.Finish();
	else if (AmmoType.AmmoAmount<=0)
		GotoState('Idle');
	else if (ClipCount>=20) GoToState('NewClip');
	else if ( Pawn(Owner).bFire!=0 )
		Global.Fire(0);
	else if ( Pawn(Owner).bAltFire!=0 )
		Global.AltFire(0);
	else 
		GotoState('Idle');
}

simulated event RenderOverlays(canvas Canvas)
{
	Super.RenderOverlays(Canvas);
	if (SlaveAutoMag != None)
		SlaveAutoMag.RenderOverlays(Canvas);
}

// End Class
//=============================================================================

defaultproperties
{
	 ItemName="Double AutoMag"
	 DeathMessage="%k riddled %o full of holes with the %w."
     AIRating=0.400000
	 bHidden=True
     DoubleAutoMagClass=Class'Botpack.DoubleAutoMag'
     MasterAutoMag=True
}
