//=============================================================================
// Queen.
//=============================================================================
class Queen expands ScriptedPawn;

#exec MESH IMPORT MESH=SkQueen ANIVFILE=MODELS\queen_a.3D DATAFILE=MODELS\queen_d.3D X=0 Y=0 Z=0
#exec MESH ORIGIN MESH=SkQueen X=0 Y=-100 Z=80 YAW=64 ROLL=-64

#exec MESH SEQUENCE MESH=Skqueen SEQ=All		STARTFRAME=0	NUMFRAMES=318
#exec MESH SEQUENCE MESH=Skqueen SEQ=ThreeHit	STARTFRAME=0	NUMFRAMES=35  Group=Attack 
#exec MESH SEQUENCE MESH=Skqueen SEQ=Claw		STARTFRAME=35   NUMFRAMES=20  Group=Attack
#exec MESH SEQUENCE MESH=Skqueen SEQ=Gouge		STARTFRAME=55   NUMFRAMES=25  Group=Attack
#exec MESH SEQUENCE MESH=Skqueen SEQ=Jump		STARTFRAME=80   NUMFRAMES=1
#exec MESH SEQUENCE MESH=Skqueen SEQ=Land		STARTFRAME=81   NUMFRAMES=1
#exec MESH SEQUENCE MESH=Skqueen SEQ=Meditate	STARTFRAME=82   NUMFRAMES=40
#exec MESH SEQUENCE MESH=Skqueen SEQ=OutCold	STARTFRAME=122  NUMFRAMES=41
#exec MESH SEQUENCE MESH=Skqueen SEQ=TakeHit	STARTFRAME=122  NUMFRAMES=1
#exec MESH SEQUENCE MESH=Skqueen SEQ=Run		STARTFRAME=163  NUMFRAMES=20
#exec MESH SEQUENCE MESH=Skqueen SEQ=Scream		STARTFRAME=183  NUMFRAMES=45
#exec MESH SEQUENCE MESH=Skqueen SEQ=Fighter	STARTFRAME=228  NUMFRAMES=1
#exec MESH SEQUENCE MESH=Skqueen SEQ=Shoot1		STARTFRAME=228  NUMFRAMES=45  Group=Attack
#exec MESH SEQUENCE MESH=Skqueen SEQ=Stab		STARTFRAME=273  NUMFRAMES=15  Group=Attack
#exec MESH SEQUENCE MESH=Skqueen SEQ=Walk		STARTFRAME=288  NUMFRAMES=30

#exec TEXTURE IMPORT NAME=JQueen1 FILE=MODELS\queen.PCX GROUP=Skins
#exec MESHMAP SCALE MESHMAP=Skqueen X=0.2 Y=0.2 Z=0.4
#exec MESHMAP SETTEXTURE MESHMAP=Skqueen NUM=1 TEXTURE=Jqueen1 

#exec MESH NOTIFY MESH=Skqueen SEQ=Shoot1 TIME=0.167 FUNCTION=SpawnShot
#exec MESH NOTIFY MESH=Skqueen SEQ=Shoot1 TIME=0.255 FUNCTION=SpawnShot
#exec MESH NOTIFY MESH=Skqueen SEQ=Shoot1 TIME=0.344 FUNCTION=SpawnShot
#exec MESH NOTIFY MESH=Skqueen SEQ=Shoot1 TIME=0.433 FUNCTION=SpawnShot
#exec MESH NOTIFY MESH=Skqueen SEQ=OutCold TIME=0.60 FUNCTION=LandThump
#exec MESH NOTIFY MESH=Skqueen SEQ=Claw   TIME=0.5   FUNCTION=ClawDamageTarget
#exec MESH NOTIFY MESH=Skqueen SEQ=Gouge  TIME=0.4   FUNCTION=ClawDamageTarget
#exec MESH NOTIFY MESH=Skqueen SEQ=Stab   TIME=0.33  FUNCTION=StabDamageTarget
#exec MESH NOTIFY MESH=Skqueen SEQ=Walk   TIME=0.26  FUNCTION=FootStep
#exec MESH NOTIFY MESH=Skqueen SEQ=Walk   TIME=0.76  FUNCTION=FootStep
#exec MESH NOTIFY MESH=Skqueen SEQ=Run    TIME=0.25  FUNCTION=FootStep
#exec MESH NOTIFY MESH=Skqueen SEQ=Run    TIME=0.75  FUNCTION=FootStep

#exec AUDIO IMPORT FILE="Sounds\Queen\claw1Q.WAV" NAME="claw1Q" GROUP="Queen"
#exec AUDIO IMPORT FILE="Sounds\Queen\shoot1Q.UFX" NAME="shoot1Q" GROUP="Queen"
#exec AUDIO IMPORT FILE="Sounds\Queen\yell1Q.WAV" NAME="yell1Q" GROUP="Queen"
#exec AUDIO IMPORT FILE="Sounds\Queen\yell2Q.WAV" NAME="yell2Q" GROUP="Queen"
#exec AUDIO IMPORT FILE="Sounds\Queen\yell3Q.WAV" NAME="yell3Q" GROUP="Queen"
#exec AUDIO IMPORT FILE="Sounds\Queen\stab1Q.UFX" NAME="stab1Q" GROUP="Queen"
#exec AUDIO IMPORT FILE="Sounds\Queen\outcoldQ.WAV" NAME="outcoldQ" GROUP="Queen"
#exec AUDIO IMPORT FILE="Sounds\Queen\nearby2Q.WAV" NAME="nearby2Q" GROUP="Queen"
#exec AUDIO IMPORT FILE="Sounds\Queen\amb1Q.WAV" NAME="amb1Q" GROUP="Queen"
#exec AUDIO IMPORT FILE="Sounds\Queen\nearby2Q.WAV" NAME="nearby2Q" GROUP="Queen"
#exec AUDIO IMPORT FILE="Sounds\Titan\step1a.WAV" NAME="step1t" GROUP="Titan"

//Queen variables;
var() byte ClawDamage,
	StabDamage;
var() name ScreamEvent;

var byte row;
var(Sounds) sound footstep;
var(Sounds) sound Scream;
var(Sounds) sound stab;
var(Sounds) sound shoot;
var(Sounds) sound claw;

var bool	bJustScreamed;
var bool	bEndFootStep;

function eAttitude AttitudeToCreature(Pawn Other)
{
	if ( Other.IsA('Skaarj') )
	{
		if ( Other.IsA('SkaarjBerserker') )
			return ATTITUDE_Hate;
		else
			return ATTITUDE_Friendly;
	}
	else if ( Other.IsA('Pupae') )
		return ATTITUDE_Friendly;
	else if ( Other.IsA('Nali') )
		return ATTITUDE_Hate;
	else
		return ATTITUDE_Ignore;
}


function ThrowOther(Pawn Other)
{
	local float dist, shake;
	local PlayerPawn aPlayer;
	local vector Momentum;

	if ( Other.mass > 500 )
		return;

	aPlayer = PlayerPawn(Other);				
	if (aPlayer == None)
	{	
		if (Other.Physics != PHYS_Walking)
			return;
		dist = Size(Location - Other.Location);
		if (dist > 500)
			return;
	}
	else
	{
		dist = Size(Location - Other.Location);
		shake = FMax(500, 1500 - dist);
		if ( dist > 1500 )
			return;
		aPlayer.ShakeView( FMax(0, 0.35 - dist/20000), shake, 0.015 * shake);
		if ( (Other.Physics != PHYS_Walking) || (dist > 1500) )
			return;
	}
	
	Momentum = -0.5 * Other.Velocity + 100 * Normal(Other.Location - Location);
	Momentum.Z =  7000000.0/((0.5 * dist + 500) * Other.Mass);
	Other.ClientAddVelocity(Momentum);
}

function FootStep()
{
	bEndFootstep = false;
	PlaySound(Footstep, SLOT_Interact, 8);
}

function Scream()
{
	local actor A;
	local pawn Thrown;

	if (ScreamEvent != '')
		foreach AllActors( class 'Actor', A, ScreamEvent )
			A.Trigger( Self, Instigator );
			
	//throw all nearby creatures, and play sound
	Thrown = Level.PawnList;
	While ( Thrown != None )
	{
		ThrowOther(Thrown);
		Thrown = Thrown.nextPawn;
	}
}

function PlayWaiting()
{
	local float decision;
	local float animspeed;
	
	if (bEndFootStep)
		FootStep();
	decision = FRand();
	animspeed = 0.2 + 0.5 * FRand();
	LoopAnim('Meditate', animspeed);
}

function PlayChallenge()
{
	if (bEndFootStep)
		FootStep();
	TweenAnim('Fighter', 0.15);
}

function TweenToFighter(float tweentime)
{
	bEndFootStep = ( ((AnimSequence == 'Walk') || (AnimSequence == 'Run')) && (AnimFrame > 0.1) );   
	TweenAnim('Fighter', tweentime);
}

function TweenToRunning(float tweentime)
{
	if ( (AnimSequence != 'Run') || !bAnimLoop )
		TweenAnim('Run', tweentime);
}

function TweenToWalking(float tweentime)
{
	TweenAnim('Walk', tweentime);
}

function TweenToWaiting(float tweentime)
{
	TweenAnim('Meditate', tweentime);
}

function TweenToPatrolStop(float tweentime)
{
	TweenAnim('Meditate', tweentime);
}

function PlayRunning()
{
	LoopAnim('Run', -1.0/GroundSpeed,, 0.8);
}

function PlayWalking()
{
	LoopAnim('Walk', -1.0/GroundSpeed,, 0.8);
}

function PlayThreatening()
{
	DesiredSpeed = 0.0;

	if ( FRand() < 0.75)
		PlayAnim('Meditate', 0.4 + 0.6 * FRand(), 0.3);
	else 
	{
		TweenAnim('Fighter', 0.3);
		PlayThreateningSound();
	}
}

function PlayTurning()
{
	if (bEndFootStep)
		FootStep();
	DesiredSpeed = 0.0;
	TweenAnim('Run', 0.4);
}

function PlayDying(name DamageType, vector HitLocation)
{
	PlayAnim('OutCold', 0.7, 0.1);
	PlaySound(Die, SLOT_Talk);	
}

function PlayTakeHit(float tweentime, vector HitLoc, int Damage)
{
	TweenAnim('TakeHit', tweentime);
}

function SpawnShot()
{
	local vector X,Y,Z, projStart;

	GetAxes(Rotation,X,Y,Z);
	
	if (row == 0)
		MakeNoise(1.0);
	
	projStart = Location + 1 * CollisionRadius * X + ( 0.7 - 0.2 * row) * CollisionHeight * Z + 0.2 * CollisionRadius * Y;
	spawn(RangedProjectile ,self,'',projStart,AdjustAim(ProjectileSpeed, projStart, 400 * (4 - row)/(3.5-skill), false, bWarnTarget));

	projStart = Location + 1 * CollisionRadius * X + ( 0.7 - 0.2 * row) * CollisionHeight * Z - 0.2 * CollisionRadius * Y;
	spawn(RangedProjectile ,self,'',projStart,AdjustAim(ProjectileSpeed, projStart, 400 * (4 - row)/(3.5-skill), true, bWarnTarget));
	row++;
}

function PlayVictoryDance()
{
	if (bEndFootStep)
		FootStep();
	DesiredSpeed = 0.0;
	PlayAnim('ThreeHit', 0.7, 0.15); //gib the enemy here!
	PlaySound(Threaten, SLOT_Talk);		
}

function ClawDamageTarget()
{
	if ( MeleeDamageTarget(ClawDamage, (50000.0 * (Normal(Target.Location - Location)))) )
		PlaySound(Claw, SLOT_Interact);
}

function StabDamageTarget()
{
	local vector X,Y,Z;
	GetAxes(Rotation,X,Y,Z);
	
	if ( MeleeDamageTarget(StabDamage, (15000.0 * ( Y + vect(0,0,1)))) )
		PlaySound(Stab, SLOT_Interact);
}

function PlayMeleeAttack()
{
	local float decision;

	if (bEndFootStep)
		FootStep();
	decision = FRand();
	if (decision < 0.4)
	{
		PlaySound(Stab, SLOT_Interact);
 		PlayAnim('Stab');
 	}
	else if (decision < 0.7)
	{
		PlaySound(Claw, SLOT_Interact);
		PlayAnim('Claw');
	} 
	else 
	{
		PlaySound(Claw, SLOT_Interact);
		PlayAnim('Gouge');
	}
}

function TweenToFalling()
{
	TweenAnim('Jump', 0.2);
}

function PlayInAir()
{
	TweenAnim('Jump', 0.5);
}

function PlayLanded(float impactVel)
{
	TweenAnim('Land', 0.1);
}

function PlayRangedAttack()
{
	if (bEndFootStep)
		FootStep();
	if ( ! bJustScreamed && (FRand() < 0.3))
	{
		PlaySound(Scream, SLOT_Talk, 2 * TransientSoundVolume);
		PlayAnim('Scream');
		Scream();
		bJustScreamed = true;
	}
	else
	{
		row = 0;
		bJustScreamed = false;
		PlayAnim('Shoot1'); 
		PlaySound(Shoot, SLOT_Interact);			
	}
}

