Ships only break off an attack if an AI command tells them to. To make a ship "sensible" you can add ENERGY_LOW= "[do stuff]" (for example make it do a moral check by rolling a dice and deciding to flee, jump out or keep fighting). Similar checks can be done with INCOMING_MISSILE. If you omitt these then you have a state that fights until destroyed.
When low on shields it "Considers" what it should do in the MARK_HURT state:-
But this one will keep fighting until it or its target is dead (although it will have the sense to run if a q-mine is deployed!) :-
Code: Select all
{
GLOBAL = {
ENTER = ();
EXIT = ();
UPDATE = ("pauseAI: 1.0", "setSpeedFactorTo: 0.75", performIdle, "setStateTo: DECIDE_COURSE"); };
"DECIDE_COURSE" = {
ENTER = ( "rollD: 2");
"ENERGY_LOW" = (fireMissile);
"ROLL_1" = ("setStateTo: GO_TO_WITCHPOINT");
"ROLL_2" = ("setStateTo: GO_TO_STATION");
EXIT = ();
"TARGET_FOUND" = (setTargetToFoundTarget, "setStateTo: FLEE_MINE");
UPDATE = ("scanForNearestShipWithRole: EQ_QC_MINE"); };
"GO_TO_STATION" = {
ENTER = ("setSpeedFactorTo: 0.75", "scanForNearestShipWithRole: player");
"ENERGY_LOW" = ();
"TARGET_FOUND" = (setTargetToFoundTarget, "setStateTo: REACT_TO_PLAYER");
"NOTHING_FOUND" = (setTargetToSystemStation, "setDesiredRangeTo: 5000.0", setDestinationToTarget, checkCourseToDestination);
"COURSE_OK" = ("setSpeedFactorTo: 0.75", performFlyToRangeFromDestination);
"DESIRED_RANGE_ACHIEVED" = ("setStateTo: GO_TO_WITCHPOINT");
"AEGIS_IN_DOCKING_RANGE" = ("setStateTo: GO_TO_WITCHPOINT");
"INCOMING_MISSILE" = (setTargetToPrimaryAggressor, fightOrFleeMissile, setTargetToPrimaryAggressor, "setStateTo: FLEE_NPC_ATTACK");
ATTACKED = (setTargetToPrimaryAggressor, "setStateTo: FLEE_NPC_ATTACK");
UPDATE = ("pauseAI: 1.0", "scanForNearestShipWithRole: player");
EXIT = ();
};
"GO_TO_WITCHPOINT" = {
ENTER = ("setSpeedFactorTo: 0.75", "scanForNearestShipWithRole: player");
"TARGET_FOUND" = (setTargetToFoundTarget, "setStateTo: REACT_TO_PLAYER");
"NOTHING_FOUND" = (setDestinationToWitchpoint, "setDesiredRangeTo: 1000.0", setDestinationToTarget, checkCourseToDestination);
"COURSE_OK" = ("setSpeedFactorTo: 0.75", performFlyToRangeFromDestination);
"DESIRED_RANGE_ACHIEVED" = ("setStateTo: GO_TO_STATION");
"INCOMING_MISSILE" = (setTargetToPrimaryAggressor, fightOrFleeMissile, "setStateTo: FLEE_NPC_ATTACK");
ATTACKED = (setTargetToPrimaryAggressor, "setStateTo: FLEE_NPC_ATTACK");
UPDATE = ("pauseAI: 1.0", "scanForNearestShipWithRole: player");
EXIT = ();
};
"FLEE_NPC_ATTACK" = {
ENTER = ("addFuel: 3", "setSpeedFactorTo: 2.0", "setDesiredRangeTo: 25600", performFlee);
"ENERGY_LOW" = ();
"INCOMING_MISSILE" = (setTargetToPrimaryAggressor, fightOrFleeMissile, performFlee);
ATTACKED = (setTargetToPrimaryAggressor, performFlee);
"TARGET_LOST" = (performIdle, "addFuel: -3", "setStateTo: DECIDE_COURSE");
"TARGET_DESTROYED" = (performIdle, "addFuel: -3", "setStateTo: DECIDE_COURSE");
EXIT = ();
"REACHED_SAFETY" = (performIdle, "addFuel: -3", "setStateTo: DECIDE_COURSE");
UPDATE = (); };
"REACT_TO_PLAYER" = {
ENTER = ("rollD: 9");
"ENERGY_LOW" = (fireMissile);
"ROLL_1" = ("setStateTo: FOUND_PLAYER_HURRY_ON_COURSE");
"ROLL_2" = ("setStateTo: FOUND_PLAYER_FIGHT_PLAYER");
"ROLL_3" = ("setStateTo: FOUND_PLAYER_FIGHT_PLAYER");
"ROLL_4" = ("setStateTo: FOUND_PLAYER_FIGHT_PLAYER");
"ROLL_5" = ("setStateTo: FOUND_PLAYER_FIGHT_PLAYER");
"ROLL_6" = ("setStateTo: FOUND_PLAYER_FIGHT_PLAYER");
"ROLL_7" = ("setStateTo: FOUND_PLAYER_FLEE_PLAYER");
"ROLL_8" = ("setStateTo: FOUND_PLAYER_FLEE_PLAYER");
"ROLL_9" = ("setStateTo: FOUND_PLAYER_FLEE_PLAYER");
EXIT = ();
"TARGET_FOUND" = (setTargetToFoundTarget, "setStateTo: FLEE_MINE");
UPDATE = ("pauseAI: 1.0", "scanForNearestShipWithRole: EQ_QC_MINE"); };
"FOUND_PLAYER_HURRY_ON_COURSE" = {
ENTER = ("setSpeedFactorTo: 1.1");
"ENERGY_LOW" = ();
"COURSE_OK" = ("setSpeedFactorTo: 1.1", performFlyToRangeFromDestination);
"DESIRED_RANGE_ACHIEVED" = ("setStateTo: DECIDE_COURSE");
"INCOMING_MISSILE" = (setTargetToPrimaryAggressor, fightOrFleeMissile, "setStateTo: REACT_TO_PLAYER_ATTACK");
ATTACKED = (setTargetToPrimaryAggressor, "setStateTo: REACT_TO_PLAYER_ATTACK");
"TARGET_FOUND" = (setTargetToFoundTarget, "setStateTo: FLEE_MINE");
UPDATE = ("pauseAI: 1.0", "scanForNearestShipWithRole: EQ_QC_MINE");
EXIT = (); };
"FOUND_PLAYER_FLEE_PLAYER" = {
ENTER = (fireMissile, "commsMessage: [mark-fleeing]", "addFuel: 2", "setSpeedFactorTo: 2.0", "setDesiredRangeTo: 25600", performFlee);
"ENERGY_LOW" = (fireMissile);
"INCOMING_MISSILE" = (fireMissile, setTargetToPrimaryAggressor, fightOrFleeMissile, "setStateTo: REACT_TO_PLAYER_ATTACK");
ATTACKED = (fireMissile, setTargetToPrimaryAggressor, "setStateTo: REACT_TO_PLAYER_ATTACK");
"TARGET_LOST" = (performIdle, "addFuel: -2", "setStateTo: DECIDE_COURSE");
"TARGET_DESTROYED" = (performIdle, "addFuel: -2", "setStateTo: DECIDE_COURSE");
EXIT = ();
"REACHED_SAFETY" = (performIdle, "addFuel: -2", "setStateTo: DECIDE_COURSE");
UPDATE = (); };
"FOUND_PLAYER_FIGHT_PLAYER" = {
ENTER = ("scanForNearestShipWithRole: player");
"ENERGY_LOW" = (fireMissile);
"TARGET_FOUND" = (setTargetToFoundTarget, setTargetToPrimaryAggressor, "setStateTo: ATTACK_SHIP");
"NOTHING_FOUND" = ("setStateTo: DECIDE_COURSE");
UPDATE = ("pauseAI: 1.0", "scanForNearestShipWithRole: player"); };
"ATTACK_SHIP" = {
ENTER = (fireMissile, "sendTargetCommsMessage: [mark-fighting]", performAttack);
"ATTACKED" = (fireMissile, setTargetToPrimaryAggressor);
"ENERGY_LOW" = ("setStateTo: MARK_HURT");
"INCOMING_MISSILE" = (fireMissile, setTargetToPrimaryAggressor, fightOrFleeMissile);
"TARGET_DESTROYED" = ("setStateTo: SEARCH_AGAIN");
"TARGET_LOST" = ("setStateTo: SEARCH_AGAIN");
"FRUSTRATED" = (performAttack);
"TARGET_FOUND" = (setTargetToFoundTarget, "setStateTo: FLEE_MINE");
UPDATE = ("pauseAI: 1.0", "scanForNearestShipWithRole: EQ_QC_MINE");
EXIT = (); };
"SEARCH_AGAIN" = {
ENTER = ("scanForNearestShipWithRole: player");
"ENERGY_LOW" = (fireMissile);
"TARGET_FOUND" = (setTargetToFoundTarget, setTargetToPrimaryAggressor, "setStateTo: FIGHT_TO_DEATH");
"NOTHING_FOUND" = ("setStateTo: NO_HAILS_FLY_TO_STATION");
UPDATE = ("pauseAI: 1.0", "scanForNearestShipWithRole: player"); };
"NO_HAILS_FLY_TO_STATION" = {
ENTER = ("setSpeedFactorTo: 0.75", "scanForNearestShipWithRole: player");
"ENERGY_LOW" = (fireMissile);
"TARGET_FOUND" = (setTargetToFoundTarget, "setStateTo: FIGHT_TO_DEATH");
"NOTHING_FOUND" = (setTargetToSystemStation, "setDesiredRangeTo: 5000.0", setDestinationToTarget, checkCourseToDestination);
"COURSE_OK" = ("setSpeedFactorTo: 0.75", performFlyToRangeFromDestination);
"DESIRED_RANGE_ACHIEVED" = ("setStateTo: GO_TO_WITCHPOINT");
"AEGIS_IN_DOCKING_RANGE" = ("setStateTo: GO_TO_WITCHPOINT");
"INCOMING_MISSILE" = (setTargetToPrimaryAggressor, fightOrFleeMissile, "setStateTo: FLEE_NPC_ATTACK");
ATTACKED = (setTargetToPrimaryAggressor, "setStateTo: FLEE_NPC_ATTACK");
UPDATE = ("pauseAI: 1.0", "scanForNearestShipWithRole: player");
EXIT = ();
};
"REACT_TO_PLAYER_ATTACK" = {
ENTER = ("rollD: 9");
"ENERGY_LOW" = (fireMissile);
"ROLL_1" = ("setStateTo: FOUND_PLAYER_FIGHT_PLAYER");
"ROLL_2" = ("setStateTo: FOUND_PLAYER_FIGHT_PLAYER");
"ROLL_3" = ("setStateTo: FOUND_PLAYER_FIGHT_PLAYER");
"ROLL_4" = ("setStateTo: FOUND_PLAYER_FIGHT_PLAYER");
"ROLL_5" = ("setStateTo: FOUND_PLAYER_FIGHT_PLAYER");
"ROLL_6" = ("setStateTo: FOUND_PLAYER_FIGHT_PLAYER");
"ROLL_7" = ("setStateTo: FOUND_PLAYER_FIGHT_PLAYER");
"ROLL_8" = ("setStateTo: FOUND_PLAYER_FIGHT_PLAYER");
"ROLL_9" = ("setStateTo: FOUND_PLAYER_FLEE_PLAYER");
EXIT = ();
"TARGET_FOUND" = (setTargetToFoundTarget, "setStateTo: FLEE_MINE");
UPDATE = ("pauseAI: 1.0", "scanForNearestShipWithRole: EQ_QC_MINE"); };
"MARK_HURT" = {
ENTER = ("rollD: 9");
"ENERGY_LOW" = (fireMissile);
"ROLL_1" = ("setStateTo: JUMP_OUT");
"ROLL_2" = ("setStateTo: JUMP_OUT");
"ROLL_3" = ("setStateTo: JUMP_OUT");
"ROLL_4" = ("setStateTo: BEG_FOR_LIFE");
"ROLL_5" = ("setStateTo: FOUND_PLAYER_FLEE_PLAYER");
"ROLL_6" = ("setStateTo: FOUND_PLAYER_FLEE_PLAYER");
"ROLL_7" = ("setStateTo: FIGHT_TO_DEATH");
"ROLL_8" = ("setStateTo: FIGHT_TO_DEATH");
"ROLL_9" = ("setStateTo: FIGHT_TO_DEATH");
EXIT = ();
"TARGET_FOUND" = (setTargetToFoundTarget, "setStateTo: FLEE_MINE");
UPDATE = ("pauseAI: 1.0", "scanForNearestShipWithRole: EQ_QC_MINE"); };
"FIGHT_TO_DEATH" = {
ENTER = (fireMissile, performAttack);
"ATTACKED" = (fireMissile, setTargetToPrimaryAggressor);
"ENERGY_LOW" = (fireMissile);
"INCOMING_MISSILE" = (fireMissile, setTargetToPrimaryAggressor, fightOrFleeMissile);
"TARGET_DESTROYED" = ("setStateTo: SEARCH_AGAIN");
"TARGET_LOST" = ("setStateTo: SEARCH_AGAIN");
"FRUSTRATED" = (performAttack);
EXIT = ();
"TARGET_FOUND" = (setTargetToFoundTarget, "setStateTo: FLEE_MINE");
UPDATE = ("pauseAI: 1.0", "scanForNearestShipWithRole: EQ_QC_MINE"); };
"BEG_FOR_LIFE" = {
ENTER = ("commsMessage: [mark-begging]", setTargetToSystemStation, "setDesiredRangeTo: 5000.0", setDestinationToTarget, checkCourseToDestination, "setSpeedFactorTo: 0.5");
"ENERGY_LOW" = ();
"COURSE_OK" = ("setSpeedFactorTo: 0.5", performFlyToRangeFromDestination);
"DESIRED_RANGE_ACHIEVED" = ("setStateTo: GO_TO_WITCHPOINT");
"AEGIS_IN_DOCKING_RANGE" = ("setStateTo: GO_TO_WITCHPOINT");
"INCOMING_MISSILE" = (setTargetToPrimaryAggressor, fightOrFleeMissile, "setStateTo: BEG_FAILED");
ATTACKED = (setTargetToPrimaryAggressor, "setStateTo: BEG_FAILED");
"TARGET_FOUND" = (setTargetToFoundTarget, "setStateTo: FLEE_MINE");
UPDATE = ("pauseAI: 1.0", "scanForNearestShipWithRole: EQ_QC_MINE");
EXIT = (); };
"BEG_FAILED" = {
ENTER = (fireMissile, "scanForNearestShipWithRole: player");
"ENERGY_LOW" = (fireMissile);
"TARGET_FOUND" = (setTargetToFoundTarget, setTargetToPrimaryAggressor, "setStateTo: FIGHT_TO_DEATH");
"NOTHING_FOUND" = ("setStateTo: DECIDE_COURSE");
UPDATE = ("pauseAI: 1.0", "scanForNearestShipWithRole: player"); };
"JUMP_OUT" = {
ENTER = (fireMissile, "commsMessage: [mark-jumping]", "safeScriptActionOnTarget: set: mission_random_hits_status JUMPING", "addFuel: 7", performHyperSpaceExitWithoutReplacing);
EXIT = ();
UPDATE = ("pauseAI: 1.0", performHyperSpaceExitWithoutReplacing);
"ENERGY_LOW" = (fireMissile);
"INCOMING_MISSILE" = (fireMissile, fightOrFleeMissile, setTargetToPrimaryAggressor, "setStateTo: FLEE_NPC_ATTACK");
ATTACKED = (fireMissile, setTargetToPrimaryAggressor, "setStateTo: FLEE_NPC_ATTACK");
"WITCHSPACE OKAY" = (wormholeEscorts);
"WITCHSPACE BLOCKED" = (setTargetToFoundTarget, setDestinationWithinTarget, "setDesiredRangeTo: 10000.0", performFlyToRangeFromDestination);
"WITCHSPACE UNAVAILABLE" = ("addFuel: -7", "setStateTo: FIGHT_TO_DEATH");
};
"FLEE_MINE" = {
ENTER = (fireMissile, "rollD: 3");
"ROLL_1" = ("setStateTo: JUMP_OUT");
"ROLL_2" = ("setStateTo: JUMP_OUT");
"ROLL_3" = ("setStateTo: MINE_RUN");
UPDATE = ();
EXIT = (); };
"MINE_RUN" = {
ENTER = ("commsMessage: [mine-fleeing]", setDestinationToTarget, "addFuel: 7", "setSpeedFactorTo: 2.0", "setDesiredRangeTo: 35600", performFlee);
"ENERGY_LOW" = (fireMissile);
"ATTACKED" = (fireMissile, setTargetToPrimaryAggressor, "setStateTo: FIGHT_TO_DEATH");
"INCOMING_MISSILE" = (fireMissile, setTargetToPrimaryAggressor, fightOrFleeMissile, "setStateTo: FIGHT_TO_DEATH");
EXIT = ();
"DESIRED_RANGE_ACHIEVED" = ("setStateTo: DECIDE_COURSE");
"GONE_BEYOND_RANGE" = ("setStateTo: DECIDE_COURSE");
UPDATE = ("pauseAI: 1.0", checkDistanceTravelled); };
}