//=============================================================================
// SkaarjPlayer.
//=============================================================================
class SkaarjPlayer expands UnrealIPlayer;

#exec AUDIO IMPORT FILE="Sounds\Male\UWinjur41.WAV" NAME="MUWHit1" GROUP="Male"
#exec AUDIO IMPORT FILE="Sounds\Male\UWinjur42.WAV" NAME="MUWHit2" GROUP="Male"
#exec AUDIO IMPORT FILE="Sounds\SkaarjPlayer\gasp01.WAV" NAME="SKPGasp1" GROUP="Skaarj"
#exec AUDIO IMPORT FILE="Sounds\SkaarjPlayer\drown01.WAV" NAME="SKPDrown1" GROUP="Skaarj"
#exec AUDIO IMPORT FILE="Sounds\SkaarjPlayer\jump01.WAV" NAME="SKPJump1" GROUP="Skaarj"
#exec AUDIO IMPORT FILE="Sounds\Cow\walknc.WAV" NAME="walkC" GROUP="Cow"
#exec AUDIO IMPORT FILE="Sounds\SkaarjPlayer\injur01.WAV" NAME="SKPInjur1" GROUP="Skaarj"
#exec AUDIO IMPORT FILE="Sounds\SkaarjPlayer\injur02.WAV" NAME="SKPInjur2" GROUP="Skaarj"
#exec AUDIO IMPORT FILE="Sounds\SkaarjPlayer\injur03.WAV" NAME="SKPInjur3" GROUP="Skaarj"
#exec AUDIO IMPORT FILE="Sounds\SkaarjPlayer\injur04.WAV" NAME="SKPInjur4" GROUP="Skaarj"
#exec AUDIO IMPORT FILE="Sounds\SkaarjPlayer\death01.WAV" NAME="SKPDeath1" GROUP="Skaarj"
#exec AUDIO IMPORT FILE="Sounds\SkaarjPlayer\death02.WAV" NAME="SKPDeath2" GROUP="Skaarj"
#exec AUDIO IMPORT FILE="Sounds\SkaarjPlayer\death03.WAV" NAME="SKPDeath3" GROUP="Skaarj"
#exec AUDIO IMPORT FILE="Sounds\SkaarjPlayer\land01.WAV" NAME="Land1SK" GROUP="Skaarj"

function ForceMeshToExist()
{
	Spawn(class'SkaarjTrooper');
}

function WalkStep()
{
	local sound step;
	local float decision;

	if ( FootRegion.Zone.bWaterZone )
	{
		ServerPlaySound(sound 'LSplash', SLOT_Interact, 0.5, false, 1500.0, 1.0);
		return;
	}

	ServerPlaySound(Footstep1, SLOT_Interact, 0.1, false, 1000.0, 1.0);
}

function RunStep()
{
	local sound step;
	local float decision;

	if ( FootRegion.Zone.bWaterZone )
	{
		ServerPlaySound(sound 'LSplash', SLOT_Interact, 0.4, false, 1500.0, 1.0);
		return;
	}

	ServerPlaySound(Footstep1, SLOT_Interact, 0.4, false, 1000.0, 1.0);
}

//-----------------------------------------------------------------------------
// Animation functions

function PlayDodge()
{
	Velocity.Z = 200;
	if ( DodgeDir == DODGE_Left )
		PlayAnim('LeftDodge', 1.35, 0.1);
	else if ( DodgeDir == DODGE_Right )
		PlayAnim('RightDodge', 1.35, 0.1);
	else if ( DodgeDir == DODGE_Forward )
		PlayAnim('Lunge', 1.2, 0.1);
	else
		PlayDuck();
}
		
function PlayTurning()
{
	BaseEyeHeight = Default.BaseEyeHeight;
	PlayAnim('Turn', 0.3, 0.3);
}

function TweenToWalking(float tweentime)
{
	BaseEyeHeight = Default.BaseEyeHeight;
	if (Weapon == None)
		TweenAnim('Walk', tweentime);
	else if ( Weapon.bPointing || (CarriedDecoration != None) ) 
		TweenAnim('WalkFire', tweentime);
	else
		TweenAnim('Walk', tweentime);
}

function TweenToRunning(float tweentime)
{
	BaseEyeHeight = Default.BaseEyeHeight;
	if (bIsWalking)
		TweenToWalking(0.1);
	else if (Weapon == None)
		PlayAnim('Jog', 0.9, tweentime);
	else if ( Weapon.bPointing ) 
		PlayAnim('JogFire', 0.9, tweentime);
	else
		PlayAnim('Jog', 0.9, tweentime);
}

function PlayWalking()
{
	BaseEyeHeight = Default.BaseEyeHeight;
	if (Weapon == None)
		LoopAnim('Walk');
	else if ( Weapon.bPointing || (CarriedDecoration != None) ) 
		LoopAnim('WalkFire');
	else
		LoopAnim('Walk');
}

function PlayRunning()
{
	BaseEyeHeight = Default.BaseEyeHeight;
	if (Weapon == None)
		LoopAnim('Jog');
	else if ( Weapon.bPointing ) 
		LoopAnim('JogFire');
	else
		LoopAnim('Jog');
}

function PlayRising()
{
	BaseEyeHeight = 0.4 * Default.BaseEyeHeight;
	PlayAnim('Getup', 0.7, 0.1);
}

function PlayFeignDeath()
{
	BaseEyeHeight = 0;
	PlayAnim('Death2',0.7);
}

function PlayDying(name DamageType, vector HitLoc)
{
	local vector X,Y,Z, HitVec, HitVec2D;
	local float dotp;

	BaseEyeHeight = Default.BaseEyeHeight;
	PlayDyingSound();
			
	if ( FRand() < 0.15 )
	{
		PlayAnim('Death',0.7,0.1);
		return;
	}

	// check for big hit
	if ( (Velocity.Z > 250) && (FRand() < 0.7) )
	{
		PlayAnim('Death2', 0.7, 0.1);
		return;
	}

	// check for head hit
	if ( (DamageType == 'Decapitated') || (HitLoc.Z - Location.Z > 0.6 * CollisionHeight) )
	{
		DamageType = 'Decapitated';
		PlayAnim('Death', 0.7, 0.1);
		return;
	}

	
	if ( FRand() < 0.15)
	{
		PlayAnim('Death3', 0.7, 0.1);
		return;
	}

	GetAxes(Rotation,X,Y,Z);
	X.Z = 0;
	HitVec = Normal(HitLoc - Location);
	HitVec2D= HitVec;
	HitVec2D.Z = 0;
	dotp = HitVec2D dot X;
	
	if (Abs(dotp) > 0.71) //then hit in front or back
		PlayAnim('Death3', 0.7, 0.1);
	else
	{
		dotp = HitVec dot Y;
		if (dotp > 0.0)
			PlayAnim('Death', 0.7, 0.1);
		else
			PlayAnim('Death4', 0.7, 0.1);
	}
}

//FIXME - add death first frames as alternate takehit anims!!!

function PlayGutHit(float tweentime)
{
	if ( AnimSequence == 'GutHit' )
	{
		if (FRand() < 0.5)
			TweenAnim('LeftHit', tweentime);
		else
			TweenAnim('RightHit', tweentime);
	}
	else
		TweenAnim('GutHit', tweentime);
}

function PlayHeadHit(float tweentime)
{
	if ( AnimSequence == 'HeadHit' )
		TweenAnim('GutHit', tweentime);
	else
		TweenAnim('HeadHit', tweentime);
}

function PlayLeftHit(float tweentime)
{
	if ( AnimSequence == 'LeftHit' )
		TweenAnim('GutHit', tweentime);
	else
		TweenAnim('LeftHit', tweentime);
}

function PlayRightHit(float tweentime)
{
	if ( AnimSequence == 'RightHit' )
		TweenAnim('GutHit', tweentime);
	else
		TweenAnim('RightHit', tweentime);
}
	
function PlayLanded(float impactVel)
	{	
		impactVel = impactVel/JumpZ;
		impactVel = 0.1 * impactVel * impactVel;
		BaseEyeHeight = Default.BaseEyeHeight;

		if ( impactVel > 0.17 )
			ServerPlaySound(Land, SLOT_Talk, FMin(4, 5 * impactVel),false,1600,FRand()*0.4+0.8);
		if ( !FootRegion.Zone.bWaterZone && (impactVel > 0.01) )
			ServerPlaySound(sound'Land1', SLOT_Interact, FClamp(4.5 * impactVel,0.3,5), false, 1000, 1.0);

		if ( (GetAnimGroup(AnimSequence) == 'Dodge') && IsAnimating() )
			return;
		if ( impactVel > 0.06 )
			TweenAnim('Land', 0.12);
		else if ( !IsAnimating() )
		{
			if ( GetAnimGroup(AnimSequence) == 'TakeHit' )
				AnimEnd();
			else
				TweenAnim('Land', 0.12);
		}
	}
	
function PlayInAir()
{
	BaseEyeHeight =  Default.BaseEyeHeight;
	TweenAnim('InAir', 0.4);
}

function PlayDuck()
{
	BaseEyeHeight = 0;
	TweenAnim('Duck', 0.25);
}

function PlayCrawling()
{
	BaseEyeHeight = 0;
	LoopAnim('DuckWalk');
}

function TweenToWaiting(float tweentime)
{
	if ( (State == 'PlayerSwimming') || (Physics == PHYS_Swimming) )
	{
		BaseEyeHeight = 0.5 * Default.BaseEyeHeight;
		TweenAnim('Swim', tweentime);
	}
	else
	{
		BaseEyeHeight = Default.BaseEyeHeight;
		TweenAnim('Firing', tweentime);
	}
}
	
function PlayWaiting()
{
	local name newAnim;

	if ( (State == 'PlayerSwimming') || (Physics == PHYS_Swimming) )
	{
		BaseEyeHeight = 0.5 * Default.BaseEyeHeight;
		LoopAnim('Swim');
	}
	else
	{	
		BaseEyeHeight = Default.BaseEyeHeight;
		if ( (Weapon != None) && Weapon.bPointing )
			TweenAnim('Firing', 0.3);
		else
		{
			if ( FRand() < 0.2 )
				newAnim = 'Breath';
			else
				newAnim = 'Breath2';
			
			if ( AnimSequence == newAnim )
				LoopAnim(newAnim, 0.3 + 0.7 * FRand());
			else
				PlayAnim(newAnim, 0.3 + 0.7 * FRand(), 0.25);
		}
	}
}	

function PlayFiring()
{
	// switch animation sequence mid-stream if needed
	if (AnimSequence == 'Jog')
		AnimSequence = 'JogFire';
	else if (AnimSequence == 'StrafeLeft')
		AnimSequence = 'StrafeLeftFR';
	else if (AnimSequence == 'StrafeRight')
		AnimSequence = 'StrafeRightFR';
	else if (AnimSequence == 'Walk')
		AnimSequence = 'WalkFire';
	else if ( AnimSequence == 'InAir' )
		TweenAnim('JogFire', 0.03);
	else //if ( (AnimSequence == 'Breath') || (AnimSequence == 'Breath2') || (GetAnimGroup(AnimSequence) == 'Gesture') )
		TweenAnim('Firing', 0.02);
}

function ClientPlayWeaponSwitch(Weapon NewWeapon)
{
}

function PlaySwimming()
{
	BaseEyeHeight = 0.5 * Default.BaseEyeHeight;
	LoopAnim('Swim');
}

function TweenToSwimming(float tweentime)
{
	BaseEyeHeight = 0.5 * Default.BaseEyeHeight;
	TweenAnim('Swim',tweentime);
}

// Player Swimming
state PlayerSwimming
{
ignores SeePlayer, HearNoise, Bump;

	event PlayerTick( float DeltaTime )
	{
		// Update acceleration.
		local rotation newRotation;
		local vector X,Y,Z, OldAccel;
		GetAxes(ViewRotation,X,Y,Z);

		aForward *= 0.2;
		aStrafe  *= 0.1;
		aLookup  *= 0.24;
		aTurn    *= 0.24;
		aUp		 *= 0.1;  
		
		if (bJump > 0) aUp = FMax(300.0, 2.5 * (Abs(aForward) + Abs(aStrafe)));
		if ( (aForward != 0) || (aStrafe != 0) || (aUp != 0) )
			Buoyancy = Mass; //Don't sink if swimming
		else
			Buoyancy = Default.Buoyancy;
		OldAccel = Acceleration;
		Acceleration = aForward*X + aStrafe*Y + aUp*vect(0,0,1); 
	
		if ( (GetAnimGroup(AnimSequence) != 'Gesture') && (AnimSequence != 'Swim') )
			TweenToSwimming(0.1);

		// Update rotation.
		UpdateRotation(DeltaTime, 2);
		bUpAndOut = (aForward > 0) && ((aUp > 0) || (ViewRotation.Pitch > 2048));
	}
}

