//=============================================================================
// Warrior.
//=============================================================================
class Warrior expands ScriptedPawn;

#alwaysexec MESH IMPORT MESH=Warrior ANIVFILE=MODELS\warr_a.3D DATAFILE=MODELS\warr_d.3D X=0 Y=0 Z=0
#alwaysexec MESH ORIGIN MESH=Warrior X=00 Y=150 Z=-100 YAW=64

#alwaysexec MESH SEQUENCE MESH=GasBag SEQ=All      STARTFRAME=0  NUMFRAMES=1
#alwaysexec MESH SEQUENCE MESH=GasBag SEQ=TwoPunch STARTFRAME=0  NUMFRAMES=1 Group=Attack
#alwaysexec MESH SEQUENCE MESH=GasBag SEQ=Belch    STARTFRAME=0 NUMFRAMES=1 Group=MovingAttack
#alwaysexec MESH SEQUENCE MESH=GasBag SEQ=ThreatBelch    STARTFRAME=0 NUMFRAMES=1
#alwaysexec MESH SEQUENCE MESH=GasBag SEQ=Deflate  STARTFRAME=0 NUMFRAMES=1
#alwaysexec MESH SEQUENCE MESH=GasBag SEQ=TakeHit  STARTFRAME=0 NUMFRAMES=1
#alwaysexec MESH SEQUENCE MESH=GasBag SEQ=Fiddle   STARTFRAME=0 NUMFRAMES=1
#alwaysexec MESH SEQUENCE MESH=GasBag SEQ=Fighter  STARTFRAME=0 NUMFRAMES=1
#alwaysexec MESH SEQUENCE MESH=GasBag SEQ=Float    STARTFRAME=0 NUMFRAMES=1
#alwaysexec MESH SEQUENCE MESH=GasBag SEQ=Grab     STARTFRAME=0 NUMFRAMES=1
#alwaysexec MESH SEQUENCE MESH=GasBag SEQ=Pound    STARTFRAME=0 NUMFRAMES=1 Group=Attack
#alwaysexec MESH SEQUENCE MESH=GasBag SEQ=T1       STARTFRAME=0 NUMFRAMES=1
#alwaysexec MESH SEQUENCE MESH=GasBag SEQ=T2       STARTFRAME=0 NUMFRAMES=1
#alwaysexec MESH SEQUENCE MESH=GasBag SEQ=T3       STARTFRAME=0 NUMFRAMES=1
#alwaysexec MESH SEQUENCE MESH=GasBag SEQ=T4       STARTFRAME=0 NUMFRAMES=1

#alwaysexec TEXTURE IMPORT NAME=Warrior1 FILE=MODELS\war-tex2.PCX GROUP="Skins" 


#alwaysexec MESHMAP SCALE MESHMAP=Warrior X=0.1 Y=0.1 Z=0.2
#alwaysexec MESHMAP SETTEXTURE MESHMAP=Warrior NUM=7 TEXTURE=Warrior1 

#exec MESH NOTIFY MESH=GasBag SEQ=Belch TIME=0.5 FUNCTION=SpawnBelch
#exec MESH NOTIFY MESH=GasBag SEQ=TwoPunch TIME=0.35 FUNCTION=PunchDamageTarget
#exec MESH NOTIFY MESH=GasBag SEQ=TwoPunch TIME=0.7 FUNCTION=PunchDamageTarget
#exec MESH NOTIFY MESH=GasBag SEQ=Pound TIME=0.33 FUNCTION=PoundDamageTarget
#exec MESH NOTIFY MESH=GasBag SEQ=Deflate TIME=0.80 FUNCTION=LandThump

#exec AUDIO IMPORT FILE="Sounds\Gassius\2punch1a.WAV" NAME="twopunch1g" GROUP="Gasbag"
#exec AUDIO IMPORT FILE="Sounds\Gassius\injur1a.WAV" NAME="injur1g" GROUP="Gasbag"
#exec AUDIO IMPORT FILE="Sounds\Gassius\injur2a.WAV" NAME="injur2g" GROUP="Gasbag"
#exec AUDIO IMPORT FILE="Sounds\Gassius\yell2a.WAV" NAME="yell2g" GROUP="Gasbag"
#exec AUDIO IMPORT FILE="Sounds\Gassius\yell3a.WAV" NAME="yell3g" GROUP="Gasbag"
#exec AUDIO IMPORT FILE="Sounds\Gassius\nearby1.WAV" NAME="nearby1g" GROUP="Gasbag"
#exec AUDIO IMPORT FILE="Sounds\Gassius\death1a.WAV" NAME="death1g" GROUP="Gasbag"
#exec AUDIO IMPORT FILE="Sounds\Gassius\hit1a.WAV" NAME="hit1g" GROUP="Gasbag"
#exec AUDIO IMPORT FILE="Sounds\Gassius\amb2gb.WAV" NAME="amb2g" GROUP="Gasbag"

//-----------------------------------------------------------------------------
// Gasbag variables.

// Attack damage.
var() byte
	PunchDamage,	// Basic damage done by each punch.
	PoundDamage;	// Basic damage done by pound.

var(Sounds)	sound Punch;
var(Sounds) sound Pound;
var(Sounds) sound PunchHit;
var GasBag ParentBag;
var int numChildren;

//-----------------------------------------------------------------------------
// Gasbag functions.

function Destroyed()
{
	if ( ParentBag != None )
		ParentBag.numChildren--;
	CallParent.Destroyed();
}

function PreSetMovement()
{
	bCanJump = true;
	bCanWalk = true;
	bCanSwim = false;
	bCanFly = true;
	bCanDuck = true;
	MinHitWall = -0.6;
	if (Intelligence > BRAINS_Reptile)
		bCanOpenDoors = true;
	if (Intelligence == BRAINS_Human)
		bCanDoSpecial = true;
}

function TryToDuck(vector duckDir, bool bReversed)
{
	local vector HitLocation, HitNormal, Extent;
	local actor HitActor;

	//log("duck");			
	duckDir.Z = 0;
	if ( (Skill == 0) && (FRand() < 0.5) )
		DuckDir *= -1;	

	Extent.X = CollisionRadius;
	Extent.Y = CollisionRadius;
	Extent.Z = CollisionHeight;
	HitActor = Trace(HitLocation, HitNormal, Location + 100 * duckDir, Location, false, Extent);
	if (HitActor != None)
	{
		duckDir *= -1;
		HitActor = Trace(HitLocation, HitNormal, Location + 100 * duckDir, Location, false, Extent);
	}
	if (HitActor != None)
		return;

	//log("good duck");
	Destination = Location + 150 * duckDir;
	Velocity = 400 * duckDir;
	AirSpeed *= 2.5;
	GotoState('TacticalMove', 'DoMove');
}	


function SetMovementPhysics()
{
	SetPhysics(PHYS_Flying); 
}

singular function Falling()
{
	SetPhysics(PHYS_Flying);
}

function PlayWaiting()
	{
	local float decision;
	local float animspeed;
	animspeed = 0.3 + 0.5 * FRand(); 

	decision = FRand();
	if (!bool(NextAnim)) //pick first waiting animation
		NextAnim = 'Float';
		
	LoopAnim(NextAnim, animspeed);
	////log("Next brute waiting anim is "$nextanim);
	if (NextAnim == 'Float')
		{
		if (decision < 0.15)
			NextAnim = 'Fiddle';			
		}
	else if (NextAnim == 'Fiddle')
		{
		if (decision < 0.5)
			NextAnim = 'Float';
		else if (decision < 0.65)
			NextAnim = 'Grab';
 		}
 	else
 		NextAnim = 'Float';
	}

function PlayPatrolStop()
{
	PlayWaiting();
}

function PlayWaitingAmbush()
{
	PlayWaiting();
}

function TweenToFighter(float tweentime)
{
	TweenAnim('Fighter', tweentime);
}

function TweenToRunning(float tweentime)
{
	if ( (AnimSequence == 'Belch') && IsAnimating() )
		return;
	if ( (AnimSequence != 'Float') || !bAnimLoop )
		TweenAnim('Float', tweentime);
}

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

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

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

function PlayRunning()
{
	if ( AnimSequence == 'Belch' )
		LoopAnim('Float', -1.0/AirSpeed, 0.5, 0.4);
	else
		LoopAnim('Float', -1.0/AirSpeed,, 0.4);
}

function PlayWalking()
{
	LoopAnim('Float', -1.0/AirSpeed,, 0.4);
}


function PlayThreatening()
{
	local float decision;

	decision = FRand();
	
	if ( decision < 0.7 )
		PlayAnim('Float', 0.4, 0.4);
	else if ( decision < 0.8 )
		PlayAnim('ThreatBelch', 0.4, 0.25);
	else
	{
		PlayThreateningSound();
		TweenAnim('Fighter', 0.3);
	}
}

function PlayTurning()
{
	LoopAnim('Float');
}
function PlayDying(name DamageType, vector HitLocation)
{
	PlaySound(Die, SLOT_Talk);
	PlayAnim('Deflate', 0.7, 0.1);
}

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

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

function PlayInAir()
{
	LoopAnim('Float');
}

function PlayLanded(float impactVel)
{
	PlayAnim('Float');
}


function PlayVictoryDance()
{
	PlayAnim('Pound', 0.6, 0.1);
	PlaySound(PunchHit, SLOT_Interact);		
}
	
function PlayMeleeAttack()
{
	local vector adjust;
	adjust = vect(0,0,0);
	adjust.Z = Target.CollisionHeight;
	Acceleration = AccelRate * Normal(Target.Location - Location + adjust);
	if (FRand() < 0.5)
	{
		PlaySound(Punch, SLOT_Interact);
		PlayAnim('TwoPunch');
	}
	else
	{
		PlaySound(Pound, SLOT_Interact);
		PlayAnim('Pound');
	};
}

function PlayRangedAttack()
{
	local vector adjust;
	adjust = vect(0,0,0);
	adjust.Z = Target.CollisionHeight + 20;
	Acceleration = AccelRate * Normal(Target.Location - Location + adjust);
	PlayAnim('Belch');
}

function SpawnBelch()
{
	local vector projStart;
	 
	projStart = Location + 0.5 * CollisionRadius * vect(0,0,1);
	spawn(RangedProjectile ,self,'',projStart,AdjustAim(ProjectileSpeed, projStart, 400, bLeadTarget, bWarnTarget));
}

function PunchDamageTarget()
{
	if (MeleeDamageTarget(PunchDamage, (PunchDamage * 1300 * Normal(Target.Location - Location))))
		PlaySound(PunchHit, SLOT_Interact);
}

function PoundDamageTarget()
{
	if (MeleeDamageTarget(PoundDamage, (PoundDamage * 800 * Normal(Target.Location - Location))))
		PlaySound(PunchHit, SLOT_Interact);
}

function PlayMovingAttack()
{
	if ( AnimSequence == 'Float' )
		PlayAnim('Belch', 1.0, 0.2);
	else
		PlayAnim('Belch');
}

State TacticalMove
{
ignores SeePlayer, HearNoise;

	function EndState()
	{
		AirSpeed = Default.AirSpeed;
		CallParent.EndState();
	}
}

