//------------------------------------------------------------------ // 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_ //------------------------------------------------------------------ // Types //------------------------------------------------------------------ type #include_ //------------------------------------------------------------------ // 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.