
//------------------------------------------------------------------
// NOTE: The fsm name below MUST be changed in order for the
// script to be considered a unique entity!

fsm Generic_Defend : integer;


//------------------------------------------------------------------

// Generic_Defend:
//   Defend a target, staying near it at all times.
//   If it is destroyed, just go on a bloody rampage and attack whoever.

//------------------------------------------------------------------



//------------------------------------------------------------------
//     Constants
//------------------------------------------------------------------

	const
		#include_ <content\ABLScripts\mwconst.abi>

//------------------------------------------------------------------
//     Types
//------------------------------------------------------------------

	type
		#include_ <content\ABLScripts\mwtype.abi>
	

//------------------------------------------------------------------
//     Variables
//------------------------------------------------------------------

	var
		static ObjectID			defendTarget1;		// First target to defend
		static ObjectID			defendTarget2;		// Second target to defend
		static ObjectID			defendTarget3;		// Third target to defend
		static ObjectID			defendTarget4;		// Fourth target to defend
		static ObjectID			defendTarget5;		// Fifth target to defend

		static integer			rampageAttackRange;	// What is my attack range when my target is destroyed?
																	
		static integer			piloting;			// Piloting skill
		static integer			gunnery;			// Gunnery skill/chance to hit
		static real				minDelay;			// Minimum amount of time I will wait between shots once a weapon is reloaded
		static real				maxDelay;			// Maximum amount of time I will wait between shots once a weapon is reloaded
		static integer 			eliteLevel;			// Elite level.  This helps determine tactics, defensive manuevers, opportunity fire
													// and other things.  It indicates a general level of combat experience.
		static integer			attackThrottle;		// My attack throttle

 		static integer			isShotRadius;		// How far away from me will I detect an enemy shot?
		static integer			findTypes;			// What kind of enemies to look for

		static integer 			attackSound;		// The attack sound I play when I first attack
		static integer 			deathSound;			// The sound I play when I die
		
		static integer			mood;				// My default mood.

		static integer			takeOffDistance;	// My take-off distance if I'm an airplane (ignored if not an airplane)

//------------------------------------------------------------------
//     Init: my initialization function
//------------------------------------------------------------------

function Init;
	code
		// script-specific variables
		rampageAttackRange = 1200;

		// defendTarget*: Specifies the targets to defend, and the order in which
		// to defend them.  Fill in as many as appropriate,
		// Fill "defendTarget1" first, and proceed from there, in order,
		// and fill the rest with NO_UNIT.  You must fill in at least the first
		// defend target; the others are optional.
		defendTarget1	= NO_UNIT;
		defendTarget2	= NO_UNIT;
		defendTarget3	= NO_UNIT;
		defendTarget4	= NO_UNIT;
		defendTarget5	= NO_UNIT;

		takeOffDistance	= 150;

		// driver settings
		piloting		= 50;
		gunnery			= 30;
		minDelay		= 1.5;
		maxDelay		= 3.0;
		eliteLevel		= 30;
		attackThrottle	= 80;
		isShotRadius	= 120;
		attackSound		= -1; // no sound
		deathSound		= -1; // no sound
		mood			= NEUTRAL_START;
		findTypes		= FT_DEFAULT;

endfunction;

//------------------------------------------------------------------
//	StartState: my initial state
//------------------------------------------------------------------

state StartState;

	code
		SetFiringDelay			(ME,minDelay,maxDelay);
		SetIgnoreFriendlyFire	(ME,true);
		SetIsShotRadius			(ME,isShotRadius);
		SetEntropyMood			(ME,mood);
		SetCurMood				(ME,mood);
		SetSkillLevel			(ME,piloting,gunnery,eliteLevel);
		SetAttackThrottle		(ME,attackThrottle);

		if (orderTakeOff(takeOffDistance) == true) then
			SetTarget(ME,defendTarget1);
			trans Defend1State;
		endif;

endstate;			

//------------------------------------------------------------------
//	Defend1State: defend the first target
//------------------------------------------------------------------
state Defend1State;
	code
		if (GetTarget(ME) == NO_UNIT) then
			if (defendTarget2 <> NO_UNIT) then
				SetTarget(ME,defendTarget2);
				trans Defend2State;
			else
				trans RampageState;
			endif;
		endif;
		if (attackSound <> -1) then	
			PlaySoundOnce(attackSound);
		endif;
		OrderAttackTactic(TACTIC_DEFEND,true);

endstate;

//------------------------------------------------------------------
//	Defend2State: defend the second target (if it exists)
//------------------------------------------------------------------
state Defend2State;
	code
		if (GetTarget(ME) == NO_UNIT) then
			if (defendTarget3 <> NO_UNIT) then
				SetTarget(ME,defendTarget3);
				trans Defend3State;
			else
				trans RampageState;
			endif;
		endif;
		if (attackSound <> -1) then	
			PlaySoundOnce(attackSound);
		endif;
		OrderAttackTactic(TACTIC_DEFEND,true);

endstate;

//------------------------------------------------------------------
//	Defend3State: defend the third target (if it exists)
//------------------------------------------------------------------
state Defend3State;
	code
		if (GetTarget(ME) == NO_UNIT) then
			if (defendTarget4 <> NO_UNIT) then
				SetTarget(ME,defendTarget4);
				trans Defend4State;
			else
				trans RampageState;
			endif;
		endif;
		if (attackSound <> -1) then	
			PlaySoundOnce(attackSound);
		endif;
		OrderAttackTactic(TACTIC_DEFEND,true);

endstate;

//------------------------------------------------------------------
//	Defend4State: defend the fourth target (if it exists)
//------------------------------------------------------------------
state Defend4State;
	code
		if (GetTarget(ME) == NO_UNIT) then
			if (defendTarget5 <> NO_UNIT) then
				SetTarget(ME,defendTarget5);
				trans Defend5State;
			else
				trans RampageState;
			endif;
		endif;
		if (attackSound <> -1) then	
			PlaySoundOnce(attackSound);
		endif;
		OrderAttackTactic(TACTIC_DEFEND,true);

endstate;

//------------------------------------------------------------------
//	Defend5State: defend the fifth target (if it exists)
//------------------------------------------------------------------
state Defend5State;
	code
		if (GetTarget(ME) == NO_UNIT) then
			trans RampageState;
		endif;
		if (attackSound <> -1) then	
			PlaySoundOnce(attackSound);
		endif;
		OrderAttackTactic(TACTIC_DEFEND,true);

endstate;

//------------------------------------------------------------------
//	RampageState: I will have my revenge, in this life or the next!
//------------------------------------------------------------------

state RampageState;
	code
		if (FindEnemy(rampageAttackRange,findTypes)) then

			if (attackSound <> -1) then	
				PlaySoundOnce(attackSound);
			endif;

			OrderAttack(TRUE);

		endif;

endstate;

//------------------------------------------------------------------
//	DeadState: OK, I kicked the bucket.
//------------------------------------------------------------------

state DeadState;
	code
		if (deathSound <> -1) then	
			PlaySoundOnce(deathSound);
		endif;		

		orderDie;

endstate;


endfsm.

