//------------------------------------------------------------------ // 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; FIELD; FIELD; FIELD; FIELD; FIELD; FIELD; } 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_ //------------------------------------------------------------------ // Types //------------------------------------------------------------------ type #include_ //------------------------------------------------------------------ // 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 = ; withdrawRange = ; takeOffDistance = ; piloting = ; gunnery = ; minDelay = ; maxDelay = ; eliteLevel = ; isShotRadius = ; attackThrottle = ; speed = ; triggerID = ; destination[0] = ; destination[1] = ; destination[2] = ; // 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.