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

UIFIELDS
{
FIELD<		 INT,attackRange,"Attack Range",500>;		// At what range do I start shooting?
FIELD<		 INT,withdrawRange,"Withdraw Range",750>;		// At what range do I withdraw from combat entirely?

FIELD< 		 INT,piloting,"Piloting Skill",50>;			// Piloting skill
FIELD< 		 INT,gunnery,"Gunnery Skill",50>;			// Gunnery skill/chance to hit
FIELD< 		 FLOAT,minDelay,"Minimum fire Delay",1.0>;			// Minimum amount of time I will wait between shots once a weapon is reloaded
FIELD< 		 FLOAT,maxDelay,"Maximum fire Delay",2.0>;			// Maximum amount of time I will wait between shots once a weapon is reloaded
FIELD< 		 INT,eliteLevel,"Elite Level",60>;			// Elite level.  This helps determine tactics, defensive manuevers, opportunity fire
													// and other things.  It indicates a general level of combat experience.
FIELD<  		 INT,isShotRadius,"Is Shot Radius",120>;		// How far away from me will I detect an enemy shot?
		
FIELD<INT,	takeOffDistance,"Take Off Distance (ignored if not a plane)",160>;
FIELD<INT,	attackThrottle,"Percent throttle when in combat",80>;
FIELD<INT,	groupToAttack,"what group of objects am I attacking?",12>;

}


fsm Generic_AttackList : integer;


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

// Generic_AttackList:
//   This script can be used to attack (or defend) a series of targets
//   contained in a group.  The unit will use a specified tactic
//   on the first living target in the group, and if that unit is
//   destroyed, it will switch to the next one.  When there are no
//   units left in the group, it will go on a rampage, attacking
//   any enemies it can find.

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


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

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

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

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

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

	var
		static integer			AttackRange;		// When all my targets are destroyed, at what range do I start shooting?

		static integer			myGroupID;			// The ID of my group ... i.e. this script will
													// call GroupObjectID(groupID)
		static integer			tactic;				// The tactic to use to attack (or defend) my targets
																	
		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 			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
	
		// Variables set by editor
		attackRange		= <attackRange>;
		withdrawRange	= <withdrawRange>;
		takeOffDistance	= <takeOffDistance>;
 		piloting		= <piloting>;
		gunnery			= <gunnery>;
		minDelay		= <minDelay>;
		maxDelay		= <maxDelay>;
		eliteLevel		= <eliteLevel>;
		isShotRadius	= <isShotRadius>;
    attackThrottle	= <attackThrottle>;
		myGroupID			= <groupToAttack>;
		
																		
		tactic				= TACTIC_PICK_BEST;
		attackSound		= -1; // no sound
		deathSound		= -1; // no sound
		mood			= NEUTRAL_START;

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
			trans AttackFirstLivingTargetState;
		endif;

endstate;			

//------------------------------------------------------------------
//	AttackFirstLivingTargetState: get the first object in my group, set
//  it as my target, and issue the attack order with my tactic
//------------------------------------------------------------------

state AttackFirstLivingTargetState;

	var
		ObjectID next_target;

	code
		if (GetTarget(ME) == NO_UNIT) then
			next_target = GroupGetFirstObject(GroupObjectID(myGroupID));

			if (next_target == NO_UNIT) then
				trans RampageState;
			endif;

			SetTarget(ME,next_target);
		endif;

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

		OrderAttackTactic(tactic,TRUE);

endstate;

//------------------------------------------------------------------
//	RampageState: no targets remain -- let's kick some ass!
//------------------------------------------------------------------

state RampageState;
	code
		if (GetTarget(ME) == NO_UNIT) then
			FindEnemy(AttackRange,FT_DEFAULT);
		endif;

		if (GetTarget(ME) <> NO_UNIT) 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.

