Back to Index Page generated: May 8, 2024, 6:16:03 AM

Expansion Military Fiasco

Content

Warnings

  1. License not specified
  2. XML script list found
  3. XML Manifest found
  4. Unknown key 'licence' in XML manifest.plist

Manifest

from Expansion Manager's OXP list from Expansion Manifest
Description Equips the Galactic Navy with the powerful Leviathan Cruiser, supported by the Military Wolf Mark II, the Basilisk, the Hydra and the Rattle Cutter. These ships are occasionally seen in the space lanes, but are more often encountered in Witch Space fighting the Thargoid menace. Also adds a mission that can start in any galaxy. Equips the Galactic Navy with the powerful Leviathan Cruiser, supported by the Military Wolf Mark II, the Basilisk, the Hydra and the Rattle Cutter. These ships are occasionally seen in the space lanes, but are more often encountered in Witch Space fighting the Thargoid menace. Also adds a mission that can start in any galaxy.
Identifier oolite.oxp.Murgh.MilitaryFiasco oolite.oxp.Murgh.MilitaryFiasco
Title Military Fiasco Military Fiasco
Category Missions Missions
Author Murgh Murgh
Version 2.5.3 2.5.3
Tags Leviathan, basilisk, Hydra, Rattle Cutter Leviathan, basilisk, Hydra, Rattle Cutter
Required Oolite Version
Maximum Oolite Version
Required Expansions
Optional Expansions
Conflict Expansions
Information URL http://wiki.alioth.net/index.php/Military_Fiasco n/a
Download URL https://wiki.alioth.net/img_auth.php/d/db/MilitaryFiasco_2.5.3.oxz n/a
License
File Size n/a
Upload date 1610873485

Documentation

Also read http://wiki.alioth.net/index.php/Military%20Fiasco

Military Fiasco readme.rtf

{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\paperw11900\paperh16840\margl1440\margr1440\vieww23640\viewh16560\viewkind0
\pard\tx586\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural

\f0\b\fs48 \cf0 Military Fiasco
\b0\fs24 \
Version 2.5.3 Written by Murgh.\
\
The Military Fiasco OXP equips the Galactic Navy with the powerful Leviathan Cruiser, supported by the Military Wolf Mark II, the Basilisk, the Hydra and the Rattle Cutter. These ships are occasionally seen in the space lanes, but are more often encountered in Witch Space fighting the Thargoid menace.\
A mission is also added. Wouldn\'92t you know it, those careless chaps at the Military have lost the secret plans to these gruesome battleships, allowing a clan of pirates to mass-produce them. Guess who they will contact for assistance!\
\
Minimum version Oolite 1.74\
\pard\tx586\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li180\fi-180\ql\qnatural\pardirnatural
\cf0 -----\
\
version 2.5.3\
- Added fix to prevent update missions to be shown before mission start.\
\
version 2.5.2\
- Added compatibility for future 1.75.\
\
version 2.5\
- Added the new mission screen concept .\
- Raised minimum Oolite version to 1.74\
\
Version 2.4.4\
- Added a incompatibility code for future Oolite 1.74 (Needs new code than)\
\
Version 2.4.3\
- Removed a bug that only affected Oolite 1.65: The initial briefing stopped halfway.\
\
Version 2.4.2\
- Adapted for Oolite 1.72 and 1.73.\
- Added better cloaking detection.\
- When a laser is shot of and it stays intact, it can be scooped now.\
- Pirates are now likely to jump to the next system when all subentities with lasers are shot of and their energy is low.\
\
Version 2.4.1\
- Removed a bug introduced in version 2.4 with the carrier escorts.\
\
Version 2.4\
- Subentities now sometimes fall off in one piece before they explode.\
\
Version 2.3 Additions by Eric Walch:\
- Adapted to Oolite 1.71 Runs now only on Oolite versions until 1.65 and on the current test version 1.71.2+ It does not work with the Oolite test versions 1.68 till 1.71.1 although some of the pirate ships will be there when played on those versions.\
- Removed a bug that made most defence ships of the stolen Leviathan crashing into the carrier on launch. To keep the game in balance I lowered the number of maximum defenders to the value of the plain Leviathan. Changed Leviathan and defence ship AI so they still keep monitoring for an approaching player during docking procedure of the defenders. (only the AI used on the restart of the mission. The first time the mission run they keeps using the original AI.)\
\
Version 2.2.3\
- There is a bug in the oolite 1.70 command that placed one of the targets at the wrong location. This command is replaced by an other placement command so it will also work on the current oolite version.\
\
Version 2.2.2\
- The Java version had an other spelled name than the legacy spelled name. (military-fiasco & military-Fiasco) This resulted in that they did not see each others mission text when switching versions during a mission. Although the missions runs fine, the briefing on the F5 screen is missing. This one now has the right name. (all lowercase) However, when already accepted a mission with version 2.2.0 or 2.2.1 that briefing will miss in this version.\
\
Version 2.2.1\
- Removed a typo the prevented the new progress screen to appear.\
\
Version 2.2  Additions by Eric Walch:\
- Translated the script into JavaScript. On Oolite 1.65 or older the old scripting will be used. On version 1.70 and newer the JS scripting will be used. It will not run on the intermediate test versions 1.68 or 1.69 because they use an to incomplete implementation of the JS commands.\
- Added a progress message that pop's up occasionally to confirm to the player that the script is still doing something.\
- With the JavaScript version, the mission will restart sometimes after completion. You will have the choice to accept or reject the restart of the mission.\
\
Version 2.1  Additions by Eric Walch:\
- The version of Murgh was not compatible with other mission OXP's running simultaniously. Now added code for compatibility with other mission offering OXP's. So called MOP code (Mission Offering Protection).\
- Changed the program structure slightly so that is uses less processor time. The game itself is in no way altered. Specially after finishing the game it still kept checking all possible game conditions and thereby consuming useless time. Will now use a minimum of time when finished but should stay in place when one still wants to see all the nice new ships to randomly appear. \
- Removed a bug that made it impossible to restart the game after a delay.\
- Gave leviathan escorts a separate entry in shipdata.plist with its own AI file and added code to make that they always get role "escort". (needed to fix a bug in Oolite itself that was present until at least the current version 1.70). Gave one ship a higher max_flight_speed to be able to follow the mother.\
- Changed intelligence code of the leviathan defenders so they do a 5 seconds speed burst after launching. In the old situation they regularly were hit by the mother when launching at full speed.\
- Changed intelligence code of the military leviathan. Main noticeable difference is that he will move around obstacles instead of just flying through it. This is standard practice for current Oolite internal ships.\
- Renamed several "military" AI.plist references into "militaryFiasco" AI.plist references to avoid potential name conflicts with other OXP's.\
The game play itself is in no way altered. I didn't change the intelligence of the target ships. It is just as easy or difficult as it was before.\
Renamed version to "Military Fiasco 2.1"\
\
Version 2.0  Original version by Murgh\
\
Link to wiki page: http://wiki.alioth.net/index.php/Military_Fiasco}

Equipment

This expansion declares no equipment. This may be related to warnings.

Ships

Name
Basilisk
basilisk-defender
Basilisk Laser Mount
Hydra
hydra1-defender
Hydra 2
hydra2-defender
Hydra Laser Mount
Leviathan
leviathan-pirate
Leviathan Bridge
mil-ballturret
Military Basilisk
Basilisk Laser Mount
Military Hydra
Military Hydra 2
Hydra Laser Mount
Military Rattle Cutter
Rattle Laser Mount
Wolf Mark II Paragon
Wolf Laser Mount
Rattle Cutter
rattle-defender
Rattle Laser Mount

Models

This expansion declares no models. This may be related to warnings.

Scripts

Path
Scripts/leviathanFighter.js
this.name      = "leviathanFighter"; 
this.author    = "eric walch"; 
this.copyright = "� 2008 the Oolite team.";
this.description = "ship script for the military defenders & escorts";
this.version   = "1.03";

this.shipLaunchedFromStation = function (station)
{
    this.ship.switchAI("militaryFiascoInterceptAI.plist");
    
    // sometimes the target is already destroyd on launch. AI alone can't handle this.
    if(!this.ship.target) this.ship.reactToAIMessage("TARGET_LOST");
    
    
    if (station.speed > 0 && this.ship.equipmentStatus("EQ_FUEL_INJECTION") != "EQUIPMENT_OK")
    {
        this.ship.awardEquipment("EQ_FUEL_INJECTION"); // allow for a fast launch!
    }
    if (this.ship.fuel < 5) this.ship.fuel = 5;
}

this.shipBeingAttacked = function (attacker)
{
	// correcting friendly fire
	if (attacker && attacker.isShip && this.ship.group && attacker.group == this.ship.group)
	{
		if (this.ship.bounty) this.ship.bounty = 0;
		if (attacker.bounty) attacker.bounty = 0;
		if (attacker.target == this.ship)
		{
			attacker.target = null;
			attacker.reactToAIMessage("LOST_TARGET");
		}
	}
}
Scripts/militaryFiasco.js
"use strict";
this.name        = "military_fiasco"; 
this.author      = "Written by Murgh"; 
this.copyright   = "� 2008 the Oolite team."; 
this.description = "Translation into JS by Eric Walch"; 
this.version     = "2.5.3"; 

this.startUp = function ()
{
	 if (!missionVariables.military_fiasco)  missionVariables.military_fiasco = "MIL_START";
	 if (!missionVariables.military_fiasco_progresscount) missionVariables.military_fiasco_progresscount = 0;
	 if (!missionVariables.military_fiasco_killcount) missionVariables.military_fiasco_killcount = 0;
}

this.missionScreenOpportunity = function ()
{
    if (player.ship.docked) 
    {
        this.missionOffers();
    }
}

this.missionOffers = function ()
{
	var fiascoStatus = missionVariables.military_fiasco;
	if (fiascoStatus === "MIL_COMPLETE" || fiascoStatus === "MIL_DELAY" || fiascoStatus === "MIL_NEVER") return;
    if (player.ship.dockedStation.isMainStation)
    {
        if ((fiascoStatus === "MIL_START" || fiascoStatus === "MIL_RESTART"))
        {
            if (player.score > 1000 && player.bounty < 5)
            {
                missionVariables.military_fiasco_old_killcount = missionVariables.military_fiasco_killcount;
                mission.runScreen({title: "Military Fiasco", messageKey: "military_fiasco_intro", 
                                    choicesKey: "military_fiasco_offer1_yesnonever", music: "military_fiasco_theme.ogg"},
                                    this.choiceEvaluation);
                this.offer = "military_fiasco_first";
                missionVariables.military_fiasco_progresscount = 0;
            }
            return;
        }
		var killCount = missionVariables.military_fiasco_killcount - missionVariables.military_fiasco_old_killcount;
        if (fiascoStatus === "MIL_ACTIVE" && killCount > 0)
        {
			mission.runScreen({title: "Military Fiasco", messageKey: "military_fiasco_disp1",
                                overlay: "military_star.png", choicesKey: "military_fiasco_disp1_yesno",
                                music: "military_fiasco_teaser.ogg"}, this.choiceEvaluation);
			this.offer = "military_fiasco_second";
			missionVariables.military_fiasco_progresscount = 0;
        }
        if (fiascoStatus === "MIL_STAGE1" && killCount > 8)
        {
			mission.runScreen({title: "Military Fiasco", messageKey: "military_fiasco_disp1",
                                overlay: "military_star.png", choicesKey: "military_fiasco_disp2_yesno",
                                music: "military_fiasco_teaser.ogg"}, this.choiceEvaluation);
			this.offer = "military_fiasco_third";
			missionVariables.military_fiasco_progresscount = 0;
        }
        if (fiascoStatus === "MIL_STAGE2" && killCount > 19)
        {
			mission.runScreen({title: "Military Fiasco", messageKey: "military_fiasco_disp1", 
                                overlay: "military_star.png", choicesKey: "military_fiasco_disp3_yesno",
                                music: "military_fiasco_teaser.ogg"}, this.choiceEvaluation);
			this.offer = "military_fiasco_fourth";
			missionVariables.military_fiasco_progresscount = 0;
        }
        if (fiascoStatus === "MIL_LEVI_DESTROYED")
        {
            mission.runScreen({title: "Military Fiasco", messageKey: "military_fiasco_disp1", 
                                overlay: "military_star.png", choicesKey: "military_fiasco_disp4_justyes",
                                music: "military_fiasco_theme.ogg"}, this.choiceEvaluation);
            this.offer = "military_fiasco_fifth";
            missionVariables.military_fiasco_progresscount = 0;
        }
        if (missionVariables.military_fiasco_progresscount > 4)
        {
            mission.runScreen({title: "Military Fiasco", messageKey: "military_fiasco_progress",
                                overlay: "military_star.png", music: "military_fiasco_teaser.ogg"});
            missionVariables.military_fiasco_progresscount = 0;
        }
    }
}

this.choiceEvaluation = function (choice)
{
    if (!player.ship.docked) return;
    if (choice === "YesFiasco")
    {
        switch (this.offer)
        {
        case "military_fiasco_first":
            {
                player.credits -= 5;
                if(missionVariables.military_fiasco == "MIL_START")
                    mission.runScreen({title: "Military Fiasco", messageKey: "military_fiasco_brief1a",
                                        overlay: "military_star.png", choicesKey: "military_fiasco_cont1_yesno",
                                        model: "mil-rattle"}, this.choiceEvaluation)
                else 
                    mission.runScreen({title: "Military Fiasco", messageKey: "military_fiasco_brief1aBis",
                                        overlay: "military_star.png", choicesKey: "military_fiasco_cont1_yesno", 
                                        model: "mil-rattle"}, this.choiceEvaluation);
                this.offer = "military_fiasco_first2";
                break;
            }
        case "military_fiasco_first2":
            {
                mission.runScreen({title: "Military Fiasco", messageKey: "military_fiasco_brief1b",
                                    overlay: "military_star.png", choicesKey: "military_fiasco_cont1_yesno", 
                                    model: "mil-basilisk"}, this.choiceEvaluation);
                this.offer = "military_fiasco_first3";
                break;
            }
        case "military_fiasco_first3":
            {
                mission.runScreen({title: "Military Fiasco", messageKey: "military_fiasco_brief1c",
                                    overlay: "military_star.png", choicesKey: "military_fiasco_cont1_yesno", 
                                    model: "mil-hydra1"}, this.choiceEvaluation);
                this.offer = "military_fiasco_first4";
                break;
            }
        case "military_fiasco_first4":
            {
                mission.runScreen({title: "Military Fiasco", messageKey: "military_fiasco_brief1d", overlay: "military_star.png"});
                player.credits += 100;
                mission.setInstructionsKey("mission_military_desc1");
                missionVariables.military_fiasco = "MIL_ACTIVE";
                this.offer = null;
                break;
            }
        case "military_fiasco_second":
            {
                mission.runScreen({title: "Military Fiasco", messageKey: "military_fiasco_message1", overlay: "military_star.png"});
                mission.setInstructionsKey("mission_military_desc1");
                missionVariables.military_fiasco = "MIL_STAGE1";
                this.offer = null;
                break;
            }
        case "military_fiasco_third":
            {
                mission.runScreen({title: "Military Fiasco", messageKey: "military_fiasco_message2", overlay: "military_star.png"});
                mission.setInstructionsKey("mission_military_desc1");
                missionVariables.military_fiasco = "MIL_STAGE2";
                this.offer = null;
                break;
            }
        case "military_fiasco_fourth":
            {
                mission.runScreen({title: "Military Fiasco", messageKey: "military_fiasco_message3", overlay: "military_star.png"});
                mission.setInstructionsKey("mission_military_desc2");
                missionVariables.military_fiasco = "MIL_STAGE3";
                missionVariables.military_fiasco_helpers = Math.round(missionVariables.military_fiasco_killcount/100) + 3;
                this.offer = null;
                break;
            }
        case "military_fiasco_fifth":
            {
                mission.runScreen({title: "Military Fiasco", messageKey: "military_fiasco_debrief", overlay: "military_star.png"});
                mission.setInstructionsKey(null);
                missionVariables.military_fiasco = "MIL_COMPLETE";
                missionVariables.military_fiasco_old_killcount = null;
				missionVariables.military_fiasco_helpers = null;
                player.ship.manifest["gold"] += 100;
                this.offer = null;
                break;
            }
        default:
                break;
        };
    }
    if (choice === "NoFiasco")
    {
        missionVariables.military_fiasco_delay = missionVariables.military_fiasco;
        missionVariables.military_fiasco = "MIL_DELAY";
        mission.setInstructionsKey("mission_military_desc3");
        this.offer = null;
    }
    if (choice === "NeverFiasco")
    {
        missionVariables.military_fiasco = "MIL_NEVER";
        missionVariables.military_fiasco_old_killcount = null;
        this.offer = null;
    }
}

this.shipExitedWitchspace = function ()
{
    if (system.isInterstellarSpace)
	{
		if (Math.random() < 0.10) this.leviathan = new Timer(this, this.addCarrier, Math.random()*23.5+1.5);
		return;
	}
	// Scanning for offenders does nothing in anarchies and only little in low gevernments. So don't add the real military vessel there.
	// keep those governments dangerous
	switch (missionVariables.military_fiasco)
	{
	case "MIL_ACTIVE":
		{
			if (Math.random() < 0.17) system.addShipsToRoute("smship", 1, 0.2+Math.random()*0.5);
			if (Math.random() < 0.06 && system.government > Math.random()*3) this.leviathan = new Timer(this, this.addCarrier, Math.random()*8+0.5);
			break;
		}
	case "MIL_STAGE1":
		{
			if (Math.random() < 0.26) system.addShipsToRoute("smship", 2, 0.3+Math.random()*0.5);
			if (Math.random() < 0.11 && system.government > Math.random()*3) this.leviathan = new Timer(this, this.addCarrier, Math.random()*8+0.5);
			break;
		}
	case "MIL_STAGE2":
		{
			if (Math.random() < 0.33) system.addShipsToRoute("smship", 3, 0.3+Math.random()*0.5);
			if (Math.random() < 0.11 && system.government > Math.random()*3) this.leviathan = new Timer(this, this.addCarrier, Math.random()*8+0.5);
			break;
		}
	case "MIL_STAGE3":
		{
			if (Math.random() < 0.21) 
			{
				var sunVector = system.sun.position.direction().multiply(30E3);
                var mom = system.addShips("leviathan-pirate", 1, sunVector, 5000)[0];
				var helpers = missionVariables.military_fiasco_helpers;
				if (helpers < 1) helpers = 1;
				var smships = system.addShips("smship", helpers, mom.position, 8000);
				for (var i=0; i<smships.length;i++)
					if (smships[i].isValid) //could already have been destroyed
					{
						smships[i].script.isHelper = true;
						smships[i].script.mom = mom;
					}
			}
			if (Math.random() < 0.11 && system.government > Math.random()*3) this.leviathan = new Timer(this, this.addCarrier, Math.random()*8+0.5);
			break;
		}
	case "MIL_DELAY":
		{
			if (Math.random() < 0.02 && missionVariables.military_fiasco_progresscount > 1) 
			{
				if (missionVariables.military_fiasco_delay) missionVariables.military_fiasco = missionVariables.military_fiasco_delay
				else missionVariables.military_fiasco = "MIL_START";
				missionVariables.military_fiasco_delay = null;
			}
			if (Math.random() < 0.06 && system.government > Math.random()*3) this.leviathan = new Timer(this, this.addCarrier, Math.random()*8+0.5);
			break;
		}
	case "MIL_NEVER":
		{
			if (Math.random() < 0.001 && missionVariables.military_fiasco_progresscount > 25) missionVariables.military_fiasco = "MIL_START";
			if (Math.random() < 0.035 && system.government > Math.random()*3) this.leviathan = new Timer(this, this.addCarrier, Math.random()*8+0.5);
			break;
		}
	case "MIL_COMPLETE":
		{
			if (Math.random() < 0.001 && missionVariables.military_fiasco_progresscount > 10) missionVariables.military_fiasco = "MIL_RESTART";
			if (Math.random() < 0.035 && system.government > Math.random()*3) this.leviathan = new Timer(this, this.addCarrier, Math.random()*8+0.5);
			break;
		}
	default: 
		{
			break;
		}
	}
}

// add carrier with short delay.
this.addCarrier = function ()
{
	if (!system.isInterstellarSpace) system.addShips("leviathan", 1);
}
Scripts/smCarrier.js
this.name           = "smCarrier";
this.author         = "Eric Walch";
this.copyright      = "Feb2008";
this.description    = "Captured Leviathan";
this.version        = "1.02";

this.shipSpawned = function ()
{
    this.spareEnergy = (missionVariables.military_fiasco_killcount > 40) ? missionVariables.military_fiasco_killcount * 10 : 0;
	this.oldBounty = this.ship.bounty;
    delete this.shipSpawned;
}

this.shipDied = function ()
{
    missionVariables.military_fiasco = "MIL_LEVI_DESTROYED";
	mission.setInstructionsKey("mission_military_desc4", "military_fiasco");
}

this.otherShipDocked = function (ship)
{
    if (ship.isPlayer) player.consoleMessage(expandDescription("You'll be dead in minutes now."), 3);
}

this.stationLaunchedShip = function(ship)
{
    if (ship.isPlayer) ship.fuel = 0;
}

this.clearBounty = function ()
{
    // don't attract police, only player.
    if (this.ship.bounty !== 0) 
	{
		this.oldBounty = this.ship.bounty;
		this.ship.bounty = 0;
	}
}

this.setBounty = function ()
{
    if (this.ship.bounty === 0) this.ship.bounty = this.oldBounty;
    if (!this.alreadyMet && !player.ship.isCloaked)
    {
        this.ship.commsMessage("Hey commander, I'll have my revenge this time");
        this.alreadyMet = true;
    }
    this.callTroops();
}

this.callTroops = function ()
{
    var smships = system.shipsWithPrimaryRole("smship");
    for (var i=0; i<smships.length;i++)
        if (smships[i].isValid) //could have already been destroyed
        {
            if (!(smships[i].target && smships[i].target === this.ship.target))
			{
				smships[i].target = this.ship.target;
				smships[i].reactToAIMessage("ATTACK_MAIN_TARGET");
			}
        }
    smships = system.shipsWithRole("smship-defender");
    for (var i=0; i<smships.length;i++)
        if (smships[i].isValid) //could have already been destroyed
        {
            smships[i].target = this.ship.target;
            smships[i].AIState = "ATTACK_SHIP";
        }
}

this.shipBeingAttacked = function ()
{
    if (this.ship.energy < this.ship.maxEnergy * 0.5 && this.spareEnergy > 0)
    {
        this.ship.commsMessage("You fool, my energy banks are reloading.")
        if (this.spareEnergy > 500)
        {
            this.spareEnergy -= 500;
            this.ship.energy += 500;
        }
        else
        {
            this.ship.energy += this.spareEnergy;
            this.spareEnergy = 0;
        }
    }
}

this.witchpoint = function ()
{
	this.direction = "witchpoint";
	this.clearBounty();
}

this.planet = function ()
{
	this.direction = "planet";
	this.clearBounty();
}

this.whichDirection = function ()
{
	if (this.direction === "witchpoint") this.ship.reactToAIMessage("GO_TO_WITCHPOINT")
	else this.ship.reactToAIMessage("GO_TO_PLANET");
}
Scripts/smShip.js
this.name           = "smShip";
this.author         = "Eric Walch";
this.copyright      = "may2008";
this.description    = "Stolen Military ships";
this.version        = "1.02";

this.isHelper = false; // set true by WorldScript in end mission.

this.spawnedAsEscort = function ()
{
	this.isHelper = true;
	this.mom = system.shipsWithPrimaryRole("leviathan-pirate")[0] // define mother ship on spawning
}

this.shipSpawned = function ()
{
    if (this.isHelper) this.ship.switchAI("smShipDefenceAI.plist")
    
    if (this.ship.primaryRole == "defense_ship")
    {
        this.ship.AIState = "CLEAR_LAUNCHING_BAY" // Missed "LAUNCHED OKAY" message on AI switching
        this.mom = system.shipsWithPrimaryRole("leviathan-pirate")[0] // define mother ship on launch
    }
    if (missionVariables.military_fiasco_killcount > 150 && Math.random() < 0.5) this.ship.fuel = 70
    delete this.shipSpawned;
}

this.shipDied = function (who)
{
    if (who && who.isPlayer)
    {
        missionVariables.military_fiasco_killcount++
        missionVariables.military_fiasco_progresscount++
		if (this.isHelper) missionVariables.military_fiasco_helpers--
    }
}

this.shipEnergyIsLow = function ()
{
	if (this.ship.subEntities.length == 0 && Math.random() < 0.05 && !this.mom) this.ship.reactToAIMessage("JUMP_AWAY")
}

this.checkTarget = function ()
{
    // prefent targetting his own kind when player hits the Leviathan from outside his scanner range or cloacked hit.
    if (this.ship.target 
            && (this.ship.target.primaryRole == "smship" || this.ship.target.primaryRole == "leviathan-pirate"
            || this.ship.target.primaryRole == "defense_ship"))
    {
        if (this.mom && this.mom.target) this.ship.target = this.mom.target
        else this.ship.AIState = "TRAVEL_TO_LURK_AREA"
    }
}

this.checkCloakedTarget = function ()
{
    if (this.ship.target && !this.ship.target.isCloaked) this.ship.reactToAIMessage("TARGET_DECLOAKED")
}

// check mother to prevent it forcing in stop mode for docking.
this.checkMother = function ()
{
    if (this.mom)
    {
        if (this.mom.AIState == "ATTACK_TARGET") this.ship.reactToAIMessage("MOM_BUSY")
        else this.ship.reactToAIMessage("MOM_IDLE")
    }
}

this.findMom = function ()
{
    if (this.mom)
    {
        this.ship.target = this.mom
		this.ship.reactToAIMessage("FOUND_MOM")
    }
}
Scripts/smShipSubent.js
"use strict";
this.name           = "smShipSubentity";
this.author         = "Eric Walch";
this.copyright      = "august2008";
this.description    = "Code that adds a loose subentity at the position of a killed subentity.";
this.version        = "1.07";

this.shipDied = function ()
{
    if (this.ship.isSubEntity)
    {
        var mom = this.ship.owner;
        if ((this.ship.entityPersonality^15)&15 > 12)
        {
            var subent = this.ship.owner.spawnOne(this.ship.primaryRole);
            if (subent.isValid)
            {
                subent.orientation = mom.orientation;
                subent.position = this.localToGlobal(this.ship.position.multiply(1.1), mom);
                subent.velocity = mom.velocity.multiply(0.7);
            }
        }
        else if (this.ship.mass > 1000 && (this.ship.entityPersonality & 15 < 4))
        {
            mom.spawn("alloy", Math.ceil(Math.random()*(Math.log(this.ship.mass)-5)));
        }
        // if (mom.subEntities.length == 1) mom.reactToAIMessage("ENERGY_LOW"); // last sub is shot away.
    }
    else
    {
        if (this.ship.mass > 1000 && Math.random()< 0.2) this.ship.spawnOne("alloy");
        if (this.timer) {this.timer.stop(); delete this.timer};
    }
    delete this.shipDied;
}

this.localToGlobal = function (position, ship)
{
    var orientation = ship.orientation;
	if (0 < oolite.compareVersion("1.75")) orientation.w = -orientation.w;
	return ship.position.add(position.rotateBy(orientation));
}

this.countdown = function () // called by AI
{
    if (Math.random()>0.05) this.timer = new Timer(this, this.$die, Math.random()*1.3+0.2);
}

this.$die = function ()
{
    this.ship.reactToAIMessage("SUBENT_DIED");
}

this.entityDestroyed = function ()
{
    if (this.timer) {this.timer.stop(); delete this.timer};
}