
//------------------------------------------------------------------
// 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, trigger,"ID of trigger that makes the unit wake up",1>;

FIELD<INT, speed,"Movement Speed",600>;		
FIELD<INT, DestX,"X coordinate of destination (-1 = none)",-1>;
FIELD<INT, DestY,"Y coordinate of destination (-1 = none)",-1>;
FIELD<INT, DestZ,"Z coordinate of destination (-1 = none)",-1>;
}

fsm Generic_Reinforcement : integer;


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

// Generic_Reinforcement:
//   Shuts down, waits until a trigger, powers up, moves to a specific
//   point (if specified) and attacks anything that comes near

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



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

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

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

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

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

	var
	static integer			attackRange1;		// At what range do I start shooting (as I'm moving to the point)?
	static integer			attackRange2;		// At what range do I start shooting (as a reinforcement)?
	static integer			withdrawRange;		// At what range do I stop shooting (as a reinforcement)?

	static integer			triggerID;			// The index of my global trigger
	static LocPoint			destination;		// The destination to move to when ready
																
	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 			speed;				// What speed so I move at?
	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			findTypes;			// What kind of enemies to look for

 	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
		attackRange1		= <attackRange>;
		withdrawRange	= <withdrawRange>;
		takeOffDistance	= <takeOffDistance>;
 		piloting		= <piloting>;
		gunnery			= <gunnery>;
		minDelay		= <minDelay>;
		maxDelay		= <maxDelay>;
		eliteLevel		= <eliteLevel>;
		isShotRadius	= <isShotRadius>;
    attackThrottle	= <attackThrottle>;
		speed			= <speed>;
		triggerID		= <trigger>;
  	destination[0]	= <DestX>;
		destination[1]	= <DestY>;
		destination[2]	= <DestZ>;

		// script-specific variables

		attackRange2	= attackrange1;




		// driver settings
		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);
				
		trans ShutdownAndWaitState;

endstate;		

//------------------------------------------------------------------
//	ShutdownAndWaitState: shut down and wait for the trigger to be set, then go
//------------------------------------------------------------------

state ShutdownAndWaitState;
	code
		Shutdown(ME);

		if ((GetGlobalTrigger(triggerID)) or (isshot(me))) then
			if (orderTakeOff(takeOffDistance) == true) then
				Startup(ME);

				if ((destination[0] == -1) and (destination[1] == -1) and (destination[2] == -1)) then
					trans AttackState;
				endif;

				trans MoveToPointState;
			endif;
		endif;

endstate;

//------------------------------------------------------------------
//	MoveToPointState: go to the destination, and attack when we get there
//------------------------------------------------------------------

state MoveToPointState;
	code
		if (OrderMoveToLocPoint(destination,speed,true,true)) then
			orderstopattacking;
			SetTarget(ME,NO_UNIT);
			trans WaitAtPointState;
		else
			if (FindEnemy(attackRange1,findTypes)) then

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

				OrderAttack(false);
			endif;
		endif;
endstate;

//------------------------------------------------------------------
//	WaitAtPointState: I got to the point; let's look around
//------------------------------------------------------------------

state WaitAtPointState;
	code
		if (FindEnemy(attackRange2,findTypes)) then
			trans AttackState;
		endif;
endstate;

//------------------------------------------------------------------
//	AttackState: let's find someone and hurt them
//------------------------------------------------------------------

state AttackState;
	code
		if (LeaveAttackState(withdrawRange)) then
			OrderStopAttacking;
			SetTarget(ME,NO_UNIT);
			trans MoveToPointState;
		endif;

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

		OrderAttack(TRUE);

endstate;

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

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

		orderDie;

endstate;


endfsm.

