Back to Index Page generated: Dec 20, 2024, 7:22:09 AM

Expansion Anarchies

Content

Warnings

  1. XML script list found

Manifest

from Expansion Manager's OXP list from Expansion Manifest
Description In certain Anarchy-systems you will find Hacker Outposts, Salvage Gangs, Sentinel Stations or Renegade Stations. Depending on your legal status these may be more or less useful to you, and docking with them may be more or less dangerous to you. In certain Anarchy-systems you will find Hacker Outposts, Salvage Gangs, Sentinel Stations or Renegade Stations. Depending on your legal status these may be more or less useful to you, and docking with them may be more or less dangerous to you.
Identifier oolite.oxp.Commander_McLane.Anarchies oolite.oxp.Commander_McLane.Anarchies
Title Anarchies Anarchies
Category Systems Systems
Author Commander McLane, Killer Wolf, Arexack Heretic, Eric Walch, spara, Norby, phkb and Griff Commander McLane, Killer Wolf, Arexack Heretic, Eric Walch, spara, Norby, phkb and Griff
Version 2.9.4 2.9.4
Tags
Required Oolite Version
Maximum Oolite Version
Required Expansions
Optional Expansions
Conflict Expansions
Information URL http://wiki.alioth.net/index.php/Anarchies_OXP n/a
Download URL https://wiki.alioth.net/img_auth.php/9/9f/Anarchies-2.9.4.oxz n/a
License CC BY-NC-SA 3 CC BY-NC-SA 3
File Size n/a
Upload date 1610873396

Documentation

Also read http://wiki.alioth.net/index.php/Anarchies

anarchies_facelift_readme_and_licence.txt

Anarchies Facelift OXP ver 0.5 (20.08.2013)

Author: spara (Mika Spåra)

_Description_

This oxp upgrades Anarchies oxp by Commander McLane to better fit in to a Griffified game and adds support for some popular oxps.


* Salvaged ship models in Salvage-Gang bases are replaced with ship models from installed shipset. In theory this works with every shipset, in practise it has been tweaked to work with Griff's shipset.
* Sentinel Station and Renegade Station are replaced with ADCK's retextured Navy Bases.
* Salvager Tugger is replaced with Griff's Hognose. Salvaged ship towed by Tugger is replaced with a ship model from installed shipset. Again tweaked to work with Griff's shipset.
* Salvager Phoenix is retextured using Griff's Mamba & Python textures. Normal map and emission map is added.
* Hacker Viper is replaced with a Griff's Viper model.
* Rock textures of Salvage Gang base and Hacker Outpost have been Griffified with Griff's texture and custom shaders. Normal maps and emission maps have been added when needed.
* All stations have custom BGS tunnel texture.
* Compatibility with random shipnames oxp where appropriate.
* Compatibility with skilled NPCs oxp where appropriate.

_Requirements_

* Anarchies by Commander McLane


_Install_

Install the OXP by copying anarchies_facelift.oxp to AddOns-folder

------

This work is licensed under the Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/

readMe.txt

Anarchies v 2.9.4

by "Commander McLane"

with major contributions by "Killer Wolf", "Arexack_Heretic", "Eric Walch", "spara",  "Norby", "phkb" and "Griff"
and a lot of help and advice by others


an Expansion Pack for Oolite by Giles Williams

based on "Elite" by Ian Bell and David Braben


Introduction

It's a dangerous Ooniverse out there. Especially if you choose the life of a "privateer", looking for high profits without a special regard to your legal rating. A little trading in guns and drugs, a little racketeering, a little plundering of ships that hadn't been crippled before you arrived at the scene, some unfortunate confrontations with the police; and before soon you find yourself on GalCop's "most wanted"-list, a handsome sum on your head, hunted not only by your fellow pirates, but also by bounty hunters and the police. An uncomfortable position indeed.

If you install this OXP things get worse.

Overview

Install this OXP, and the appearance of Anarchy-systems in Oolite will change. In certain Anarchy-systems you will find Hacker Outposts, Salvage Gangs, Sentinel Stations or Renegade Stations. Depending on your legal status these may be more or less useful to you, and docking with them may be more or less dangerous to you.

Anarchies.oxp also modifies the way how the game deals with your legal status in general. First of all the bounty on your head—which translates into a bad legal status of 'Offender' or 'Fugitive'—will stick to you for a much longer time. If you don't commit more crimes, your status will get cleared after a while, just by jumping from system to system, as it was in the plain game. But once you are 'Fugitive' and the stations don't accept requests from your docking computer anymore, this will take much longer than without this OXP installed. It may take almost forever to get downrated to an 'Offender' rating again. The OXP also shuts the back-door of using your escape pod to become 'Clean' again. With Anachies.oxp installed, your legal status travels with you even in your escape capsule, and is locked into your new ship's transponder, as soon as you arrive at a station.

But the OXP offers also a variety of new ways of getting rid of an 'Offender'- or 'Fugitive'-status. These ways include the purchase of certain items on certain asteroids; but also bribing a GalCop official in the main station of an Anarchy-system is an option. You can even do something for your legal reputation if you choose to help the cops (but this will not prevent them from attacking you, as long as you're still 'Fugitive' or 'Offender' yourself).

Notable Features

1) In some Anarchies you will find a Hacker Outpost. These are huge inhabited asteroids, usually hidden in an asteroid field far away from the main station and GalCop's zone of influence. If you don't get a clue by one of their henchmen you won't find it. And if the henchman doesn't accept you as a fellow privateer you will have to tease him a little before he will share his information.

Even if the Hackers prefer Anarchies with a higher tech level, they are still technologically far ahead of that themselves. The Hackers are welcoming to a pilot who is—for whatever reason—in some trouble with GalCop, and they have a solution to offer—for a price. If you want, they can hack into GalCop's central database and clear your whole legal record, provided you have enough money to maintain the quite expensive sub-ether broadband connection they need for their work.

Apart from that you may be able to make some good deals with the Hackers. Living far away from the space lanes they are always in need of all every-day supplies. And they are happy to obtain the raw materials for their home-built computer systems. On the other hand there is not much pastime in the outpost apart from building sophisticated high-end soft- and hardware. So you may stumble over many an occasion in the outpost's market-section.

2) In some Anarchies, and even in non-Anarchy-systems, usually in the medium-range tech level, you can't miss the local Salvage Gang. Again this is a huge, hollowed-out asteroid, which is home to a gang of salvagers. You will find them wherever there is something to salvage, i.e. usually in the middle of the main corridor. Most of their business is legal, or at least not illegal enough to draw too much of GalCop's attention towards them. A clever commander will find many a bargain on the asteroid's market, especially as far as used alloys and machinery are concerned.

A visit to the Salvager's equipment store can perhaps be even more rewarding. Don't bother with the original, first-hand equipment. If they have any, it will be more expensive than in the system's main station. But quite often they manage to recover complete and (almost) unharmed equipment items from stranded shipwrecks. They refurbish and sell these items, and this is where you are in for some real bargains, if you feel the urge to fully equip your ship. The only question is: Can you trust the Salvager's advertising slogans? And what exactly is the One-Gunfight-Guarantee™? But anyway, it's cheap; so you can probably even afford to fix it, if it breaks.

Finally for the not-quite-so-legal part of their business: If GalCop for some odd reason doesn't seem to like you, there will be a special piece of equipment, which you will be able to obtain in the more shady Salvage Gangs in Anarchy-systems; sort of under the counter, so-to-speak. It may or may not be helpful to you; you will find out.

3) In some of the rougher Anarchy-systems, usually at the lower end of the tech level-spectrum, GalCop already feels that it is losing control of the space lanes to the pirates. That's the reason for the installation of a Sentinel Station at the outer end of the corridor, somewhere close to the witchpoint. Seeing a Sentinel Station guard his way has been a relief for many a trader who had underestimated the real danger of making business in Anarchy-systems.

The Sentinel Station offers not only protection to honest pilots, but also a range of services in its equipment-section. Of course you're dealing with the military here, so don't expect shopping to be cheap. But on the other hand, the superior quality of the offered equipment is out of the question. A clever pilot, however, may make some good deals in the station's market.

Oh, and don't even think about attacking a Sentinel Station. If you are in range of its plasma turrets, this will have been your last thought.

4) It should also be mentioned that in some cases GalCop's fears were justified. It has lost control to the pirates, who simply have overrun the military station and turned it into a Renegade Station. Unfortunately for harmless traders there is no way to tell from the distance whether the outlaws already have taken over the station. And once you are in scanner range it may be too late. The Renegades love to attack unsuspecting victims (and suspecting victims as well, for that matter). And even if they are busy attacking somebody else, or you have luckily slipped through their scanner grid, please don't attempt to dock with the Renegade Station. No, really; don't. And if you do, don't say I haven't warned you!

On the other hand, if you feel you are one of them (and I'm not talking about some parking violations; what I mean is, if you are a real criminal), and have righteously earned a good bad reputation; well, in that case you should seriously consider to pay the Renegades a visit. Their station is as close to a safe haven for all sorts of racketeers as it gets. The equipment-department may not be worth a visit—in the fight following the initial attack on the Sentinel Station much of the stock was destroyed, and generally the Renegades are not very well-known for their particularly caring and careful attitude towards things anyway; so the few intact items remaining on the shelves are much sought after among the criminals on the station, and thus equally expensive. And that is, if you want to risk a gunfight with some awful-looking and heavily armed creatures in the first place, in order to even get to the store and bid for one of the rusty missiles. On the other hand, a visit to the Renegade Station's market may feel like pirates' paradise. It is here that you really appreciate why you chose this kind of career anyway.

5) Even some main stations offer new opportunities hitherto unknown to not-so-law-abiding pilots. If you have managed to dock at all, which may require manual abilities, depending on your register of previous convictions, and have passed through the initial controls without being forced to lick the hangar clean—you know what I mean—then it may be worthwhile to hang around in the equipment department, and watch out for dubious GalCop personnel. Rumour has it that especially in stations in Anarchy-systems discipline among GalCop officials has become a little lax, and you might find an officer willing to take a bribe for clearing your legal record. Of course the conscience of an official of the Galactic Co-operative of Worlds, invested with a position of responsibility in an environment with a less-than-desirable amount of comfort and safety has its value, and therefore its price. A word of warning, though: If goes without saying that the attempt to bargain in such a delicate matter as bribing someone who has access to GalCop's central database will be at your own risk.

6) On the other hand, GalCop's military arm, the Galactic Navy, is always interested in skilled pilots with combat effectiveness. The ongoing war against the Thargoids means that the Navy sometimes can't be too picky in whom it calls to active reserve duty. Therefore GalCop issues an amnesty order from time to time. Pilots willing to take the offer have to report at a naval Behemoth parked in a system close to a current war zone. The amnesty offer is announced foremost in all kinds of meeting points for commanders who have a legal record to clear, among them Hacker Outposts and Salvage Gangs. GalCop is only considering an amnesty for criminals in exchange for their help if the Navy is really in a tight spot, therefore expect the deadline until the offer expires to be equally tight. If you make it in time and find the Behemoth, you'll be given a naval assignment. You have to fulfill it—and come back in one piece—in order to get your legal record cleared. Just don't get yourself involved in criminal activities again! (NOTE: everything mentioned in this paragraph requires Behemoth.oxp to be installed. If you don't have it, you won't receive any amnesty offers.)

Featured Stations and Ships

1) The Hacker Outpost. Dockable Asteroid. Modeled by Killer Wolf for this OXP. Shader effects by Griff. Killer Wolf expresses his thanks to Charlie, Griff, Selezen, Arexack_Heretic, LittleBear, Dr. Nil, Ahruman and anybody else who has helped building it.

2) The Salvage Gang. Dockable Asteroid. Modeled by Killer Wolf for this OXP. Shader effects by Griff. Credits see above.

3) The Sentinel Station. Dockable Station. Modeled by Aegidian for gwxstations.oxp and taken from that OXP. Only the colour of the plasma bolts was altered.

4) The Renegade Station. Clone of the Sentinel Station, again another colour of the plasma bolts.

5) The Renegade Viper. Pirate ship, Hacker henchman and defense ship of Hacker Outpost and Renegade Station. Modeled by 8bitapocalypse for renegade_viper.oxp and taken from that OXP.

6) The Salvager Phoenix. Defense ship of Salvage Gang and Renegade Station, and scavenger. Modeled by Cmdr Wyvern for phoenix.oxp and taken from that OXP. Salvager logo was added to the original texture.

7) The Salvager Tugger. Tugship of the Salvage Gang. Modeled by murgh for tugs.oxp and taken from that OXP. Salvager logo was added to the original texture.

7b) A couple of tugged ships. A variety of ships from the original set, taken from murgh's tugs.oxp.

8) Three bounty hunters. They will come after the player, as long as he is 'Fugitive'. Asp, CobraMkIII and Fer-de-Lance from the original set, hardened and with custom AI.

Minimum Requirements

Anarchies2.8.oxp requires at least Oolite 1.76. I recommend you upgrade to the latest version of Oolite if you haven't yet.

The amnesty offer requires Behemoth.oxp to be installed.

Download Location

This OXP is available for download through the Elite Wiki.

Installation

Move or copy the file Anarchies2.8.oxp from this folder to the AddOns folder inside the Oolite main folder. Restart Oolite. If you have any previous version of Anarchies.oxp installed, please remove it first.

Thanks

Last but not least I want to give lots of thanks to all who have contributed so far: Julyy for the original idea, Killer Wolf for a couple of very good suggestions that I could incorporate and for two beautiful asteroid models, Griff for providing some beautiful shader effects for these asteroids, Arexack_Heretic for a lot of very useful and practical advice, LittleBear for pointing me to BlackMonks as an example for some things I was trying to do, Eric Walch for bringing some problems in the script to my attention and providing imaginative suggestions how to solve them, and for not only introducing me to the secrets of ship-scripts, but also providing ready-made scripts for whatever I wanted to do, Disembodied for the amnesty idea, the ship-designers whose work I took the liberty to use in this OXP, Cap'n Hack for still hosting Oosat1 (and for guest-starring in this OXP), Ahruman, another_commander and the others for improving Oolite, Aegidian for this wonderful game, and all the other members of the Oolite BB who contributed to this OXP!

License:

This work is licensed under the Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License. To view a copy of this license, visit the Creative Commons' website or send a letter to Creative Commons, 171 Second Street, Suite 300, San Fransisco, California, 94105, USA.

Practically this means that you may rip it apart and use whatever seems useful to you, as long as you credit the original author ("Commander McLane"), and share your work under the same license. It would be nice—although by no means necessary—to give me a note (either on the Oolite BB, or via email), if you intend to use parts of it.

History:

version 2.9.4 (July/2020)
- fixed conditions script so ships derived from anarchies-renegade_viper could be spawned.

version 2.9.3 (March/2017)
- fixed semicolon problems in Mac, thanks to hoqllnq. 

version 2.9.2 (December 2016)
- updated all subentities to use new style
- updated equipment.plist to OpenStep format.
- updated shipdata.plist to OpenStep format.
- changed ’background’ properties of mission screens to ’overlay’
- added screen ID to all mission screens.
- updated station market scripts to use new style.
- updated equipment conditions to use a condition script.
- updated shipdata.plist to use a condition script.
- fixed incorrect texture reference in "afl-m-dock" definition.

version 2.9.1 (November 2016)
- ffixed issues with double Behemoths appearing in system
- fixed issues with the amnesty mission not being triggered when docking at the Behemoth
- fixed javascript "undefined" error relating to "bouy-witchspace".

version 2.9 (October 2014)
- cconverted to OXZ format
- contain the facelift by spara
- you can save in the additional stations, except in the Hacker Outpost which is not stationary

version 2.8 (April 2012)
- fixed a problem that made the amnesty mission unfinishable if the game was saved and reloaded while doing it

version 2.7 (March 2012)
- fixed a problem that could limit other OXPs' (or the main game's) freedom to make the cloaking device repairable

version 2.6 (January 2012)
- moved some more previously overlooked methods to their own name space
- fixed problem of vanishing Sentinel Asteroids with Oolite 1.76
- fixed a small bug where removing the second henchman would give an error message
- Sentinel and Renegade Stations are aligned with the planet again
- Sentinel and Renegade Stations now are behaving like they're supposed to for the first time
- Sentinel Stations now have patrol ships to secure the space lane
- Oolite 1.76 required

version 2.5 (March 2011)
- changed all JS-scripts to strict mode
- moved all self-defined methods into their own namespace
- implemented another idea for coming clean: doing a Navy reserve mission and getting amnesty on completion
- for this to fully work Oolite 1.75.1 is now required

version 2.4 (February 2011)
- Salvage Gangs' hails are now sent via ship script instead AI, giving more timing flexibility
- Salvager Tugger is now part of the Salvage Gang's ship group, therefore it will be defended by the Gang
- two of the tugged ship models included in the OXP
- fixed another bug introduced with the shader bugfix in 2.3
- Cloaking Device no longer buyable in Hacker Outpost by accident, but still repairable
- fixed a nasty bug that removed the player's extra energy unit whenever he bought new equipment
- replaced all instances of pseudo random with scrambledPseudoRandomNumber; this will change the distribution of Salvage Gangs across systems, but not the overall number of them
- cleaning-up of AIs and shipdata
- requires now Oolite 1.75

version 2.3 (November 2009)
- fixed the bugs introduced with the shader bugfix in 2.2 (thanks, Griff!)
- JS: replaced all setOrientation and setPosition, as needed in Oolite 1.73
- JS: changed the handling of defense groups according to the requirements of Oolite 1.73
- requires Oolite 1.73

version 2.2 (July 2009)
- fixed a bug with the Salvage Gang's shaders (thanks, another_commander and Griff!)

version 2.1 (January 2009)
- fixed a bug that would let Salvager Tuggers not appear in version 2.0
- fixed a bug with the Sentinel and Renegade Stations that would cause them to behave strangely when attacked

version 2.0 (January 2009)
- revised the Hacker Outpost model, closing the visible gaps around the tunnel exits
- tunnels in both Hacker Outpost and Salvage Gang replaced with models that use shaders (thanks, Griff!)
- docking bays in both Hacker Outpost and Salvage Gang replaced with Griff's models (ditto!)
- tweaked tugger model a little
- henchmen will no longer give the Hacker Outpost's location to everybody
- simplified the Hacker Outpost spawning
- Salvage Gang now aligning with the planet, and asteroid field spawned via ship script
- fixed a bug that would give the bribe offer too often
- fixed a bug that had replaced all Renegade Stations with Sentinel Stations in 1.1
- fixed a bug that would not initialise some processes if a new commander was started
- player's bounty now reduced 10% per jump if fugitive, instead of a 20 or 10 points
- salvaged equipment is now installed on buying, instead of waiting for launch
- equipment failure chance is now triggered through a timer, instead of a bunch of events; and now uses the new EquipmentInfo object
- there is also a chance now that salvaged equipment will work just fine, removing the failure possibility
- some minor tweaks in this readMe
- JS: replaced player.ship.bounty with player.bounty, which wasn't supported in Oolite 1.72
- JS: replaced all 'let' with 'var'
- requires now Oolite 1.72.1

version 1.1 (November 2008)
- the main script is now completely in JavaScript
- Hacker Outposts are now correctly facing the planet, via their new ship-script (thanks, Eric!)
- as a bonus also their Sentinel Asteroids are finally placed correctly and work (thanks, Eric!)
- added some flashers to the asteroid models
- AIs improved
- Hacker Outposts, Salvage Gangs and Renegade Stations have now their correct commodity prices
- requires Oolite 1.72

version 1.0 (February 2008)
- fully functional version
- requires Oolite 1.65

version 0.1 (March 2007)
- teaser with basic functionality

Equipment

Name Visible Cost [deci-credits] Tech-Level
Advanced Space Compass (salvaged) yes 3000 1+
Advanced Navigational Array (salvaged) yes 10000 1+
Docking Computers (salvaged) yes 7000 1+
E.C.M. System (salvaged) yes 3000 1+
Energy Bomb (salvaged) yes 4500 1+
Extra Energy Unit (salvaged) yes 7500 1+
Escape Pod (salvaged) yes 5000 1+
Witchdrive Fuel Injectors (salvaged) yes 3000 1+
Fuel Scoops (salvaged) yes 2400 1+
Galactic Hyperdrive (salvaged) yes 25000 1+
External Heat Shielding (salvaged) yes 7000 1+
Multipass yes 5000 6+
Multi-Passed ID yes 5000 3+
Multi-Targeting System (salvaged) yes 1600 1+
Naval Energy Unit (salvaged) yes 250000 1+
Military Shield Enhancement (salvaged) yes 215000 1+
Scanner Targeting Enhancement (salvaged) yes 2000 1+
Shield Boosters (salvaged) yes 70000 1+
Target System Memory Expansion (salvaged) yes 6000 1+
Wormhole Scanner (salvaged) yes 11500 1+

Ships

Name
afl-anarchies-salvaged-boa2
afl-anarchies-salvaged-cobra1
afl-anarchies-salvaged-cobra3
afl-anarchies-salvaged-fdl
afl-anarchies-salvaged-python
GalCop Viper
Docking Slit - Vertical
anarchies-behemoth-beacon
Bounty Hunter
Bounty Hunter
Bounty Hunter
Hacker Aerial
Hacker Aerial
Building
Building
Building
Building
Building
Docking Slit (horizontal)
anarchies-hacker-henchman
Hacker Outpost Inside
Hacker Outpost
Radar Building
Hacker Viper
Phoenix
Phoenix
Renegade Phoenix
Renegade Station
Renegade Viper
Renegade Viper
Ball Turret
Salvage Gang
anarchies-salvage-gang1
anarchies-salvage-gang2
anarchies-salvage-gang3
anarchies-salvage-gang4
anarchies-salvage-gang5
anarchies-salvaged-boa2
anarchies-salvaged-cobra1
anarchies-salvaged-cobra3
anarchies-salvaged-fdl
anarchies-salvaged-python
Salvager Bighut
Salvager Crane
Salvager Cutter
Salvager Sidehut
Salvager Hognose
anarchies-salvager-hog-cobra1
anarchies-salvager-hog-cobra3
anarchies-salvager-hog-fdl
anarchies-salvager-hog-python
Salvager Inside
Salvager Phoenix
Salvager Sidehut
Salvager Smallhut
Salvager Tunnel
Salvager Tunnel
Scavenger Phoenix
Sentinel Asteroid
Sentinel Station
Ball Turret
anarchies-stationturret2
Tug Jaw
Tug Line

Models

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

Scripts

Path
Scripts/anarchies-hacker-outpost-script.js
/*

anarchies-hacker-outpost-script.js

Script for turning Hacker Outposts towards the planet and moving their Sentinel Asteroids.


Oolite
Copyright © 2003-2012 Giles C Williams and contributors

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.


Anarchies.oxp
Copyright © 2007-2012 "Commander McLane"

This work is licensed under the Creative Commons
Attribution-Noncommercial-Share Alike 3.0 Unported License.

To view a copy of this license, visit
http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter
to Creative Commons, 171 Second Street, Suite 300, San Francisco,
California, 94105, USA.

*/

"use strict";

this.name           = "anarchies-hacker-outpost-script";
this.description    = "Ship script for Hacker Outposts";
this.author         = "Eric Walch & Commander McLane";
this.copyright      = "© 2012 Commander McLane";
this.license		= "CC-by-nc-sa 3.0";
this.version        = "2.8";


this.shipSpawned = function()
{
    // next line sets up a vector outpost --> planet
    var targetVector = system.mainPlanet.position.subtract(this.ship.position).direction();
    // next line aligns the heading to the targetVector by rotating
    this.ship.orientation = targetVector.rotationTo(new Vector3D(0,0,1));
    // an asteroid cluster is added around the outpost
    system.addShips("asteroid", 20, this.ship.position, 15000);

    // next line starts a timer for broadcasting advertising messages
	this.messageTimer = new Timer(this, this.$broadcastMessage, 30, 30);
}

this.$broadcastMessage = function()
{
    // one of the messages defined in descriptions.plist is broadcast
    if(!player.ship.docked) this.ship.commsMessage(expandDescription("[anarchies_hackerOutpost_hail]"));
    // the interval until the next broadcast is set at a random value between 40 and 60 seconds
    this.messageTimer.interval = 40 + (Math.random() * 20);
}

this.$moveSentinels = function()
{
    // set position for all sentinels
    for (var i=1; i<this.ship.escortGroup.ships.length; i++)
    {
        // copy the ship orientation into the sentinels
        this.ship.escortGroup.ships[i].orientation = this.ship.orientation;
        // place them within 6000 meters around the mother
        this.ship.escortGroup.ships[i].position = this.ship.position.add(Vector3D.random(6000));
    }
}

this.otherShipDocked = function(ship)
{
	if(ship.isPlayer)
	{
		// makes the cloaking device repairable--but not buyable--on a Hacker Outpost
        this.cloakingDeviceDefaultTechLevel = EquipmentInfo.infoForKey("EQ_CLOAKING_DEVICE").effectiveTechLevel;
		if(player.ship.equipmentStatus("EQ_CLOAKING_DEVICE") == "EQUIPMENT_DAMAGED") EquipmentInfo.infoForKey("EQ_CLOAKING_DEVICE").effectiveTechLevel = 10;
	}
}

this.stationLaunchedShip = function(ship)
{
	if(ship.isPlayer)
	{
		// restores the tech level setting for the cloaking device
        EquipmentInfo.infoForKey("EQ_CLOAKING_DEVICE").effectiveTechLevel = this.cloakingDeviceDefaultTechLevel;
	}
}

this.playerWillEnterWitchspace = this.shipDied = function()
{
    // the broadcast timer is stopped and deleted when the player leaves the system
    this.messageTimer.stop();
    delete this.messageTimer;
}
Scripts/anarchies-henchman-script.js
/*

anarchies-henchman-script.js

Ship script for the Hacker Henchmen.


Oolite
Copyright © 2004-2012 Giles C Williams and contributors

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.


Anarchies.oxp
Copyright © 2007-2012 "Commander McLane"

This work is licensed under the Creative Commons
Attribution-Noncommercial-Share Alike 3.0 Unported License.

To view a copy of this license, visit
http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter
to Creative Commons, 171 Second Street, Suite 300, San Francisco,
California, 94105, USA.

*/

"use strict";

this.name           = "anarchies-henchman-script";
this.description    = "Ship script for Hacker Henchmen";
this.author         = "Commander McLane";
this.copyright      = "© 2012 Commander McLane";
this.license		= "CC-by-nc-sa 3.0";
this.version        = "2.8";


this.shipSpawned = function()
{
    this.ship.primaryRole = "pirate";
}

this.$checkPlayerLegalStatus = function()
{
	if(player.bounty >= 15) this.ship.reactToAIMessage("PLAYER_OFFENDER");
	else this.ship.reactToAIMessage("PLAYER_CLEAN");
}

this.$createHackerOutpost = function()
{
	var selectPosition = Math.ceil(Math.random()*4);
	switch(selectPosition)
	{
	case 1:
		system.legacy_addShipsAtPrecisely("anarchies_hacker_outpost", 1, "wpm", [50000, -100000, -200000]);
		break;
		
	case 2:
		system.legacy_addShipsAtPrecisely("anarchies_hacker_outpost", 1, "pwm", [100000, 75000, -350000]);
		break;
		
	case 3:
		system.legacy_addShipsAtPrecisely("anarchies_hacker_outpost", 1, "pwu", [0, 0.75, 0.5]);
		break;
		
	case 4:
		system.legacy_addShipsAtPrecisely("anarchies_hacker_outpost", 1, "psu", [0, 0.6, 0.5]);
		break;
	}
	this.$removeOtherHenchman();
}

this.$removeOtherHenchman = function()
{
	// remove the other henchman if it didn't die already for some other reason
    if(system.shipsWithRole("anarchies_henchman", player.ship)[1])
        system.shipsWithRole("anarchies_henchman", player.ship)[1].remove();
}

this.shipEnergyIsLow = function ()
{
	if(system.countShipsWithRole("anarchies_hacker_outpost") === 0 && this.ship.target === player.ship)
	{
		if(!this.attackCounter) this.attackCounter = 1;
		switch(this.attackCounter)
		{
		case 1:
			this.ship.commsMessage("Please stop!");
			this.ship.energy *= 1.5;
			break;
			
		case 2:
			this.ship.commsMessage("I've got some information for you.");
			this.ship.energy *= 1.5;
			break;
			
		case 3:
			this.ship.commsMessage("There's a Hacker Outpost in this system.");
			this.ship.energy *= 1.5;
			break;
			
		case 4:
			this.ship.commsMessage("Follow the 'H' on your compass and let me go!");
			this.$createHackerOutpost();
			break;
		}
		this.attackCounter ++;
	}
}

this.shipDied = function()
{
	delete this.attackCounter;
}
Scripts/anarchies-salvage-gang-script.js
/*

anarchies-salvage-gang-script.js

Script for turning Salvage Gangs towards the planet and creating an asteroid field around them, and broadcast advertisements.


Oolite
Copyright © 2004-2012 Giles C Williams and contributors

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.


Anarchies.oxp
Copyright © 2007-2012 "Commander McLane"

This work is licensed under the Creative Commons
Attribution-Noncommercial-Share Alike 3.0 Unported License.

To view a copy of this license, visit
http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter
to Creative Commons, 171 Second Street, Suite 300, San Francisco,
California, 94105, USA.

*/

"use strict";

this.name           = "anarchies-salvage-gang-script";
this.description    = "Ship script for Salvage Gangs";
this.author         = "Commander McLane";
this.copyright      = "© 2012 Commander McLane";
this.license		= "CC-by-nc-sa 3.0";
this.version        = "2.8";


this.shipSpawned = function()
{
    // asteroid is aligned towards the z-axis and therefore towards the planet
    this.ship.orientation = [1, 0, 0, 0];
    // an asteroid cluster is added around the outpost
    system.addShips("asteroid", 20, this.ship.position, 15000);
    // timer for broadcasting advertising messages is started
	this.messageTimer = new Timer(this, this.$broadcastMessage, 30, 30);
}

this.$broadcastMessage = function()
{
    // one of the messages defined in descriptions.plist is broadcast
    if(!player.ship.docked) this.ship.commsMessage(expandDescription("[anarchies_salvageGang_hail]"));
    // the interval until the next broadcast is set at a random value between 40 and 60 seconds
    this.messageTimer.interval = 40 + (Math.random() * 20);
}

this.playerWillEnterWitchspace = this.shipDied = function()
{
    // the broadcast timer is stopped and deleted when the player leaves the system
    this.messageTimer.stop();
    delete this.messageTimer;
}
Scripts/anarchies-salvager-tugger-script.js
/*

anarchies-salvager-tugger-script.js

Script for making the Salvager Tugger part of the Salvage Gang's ship group.


Oolite
Copyright © 2004-2012 Giles C Williams and contributors

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.


Anarchies.oxp
Copyright © 2007-2012 "Commander McLane"

This work is licensed under the Creative Commons
Attribution-Noncommercial-Share Alike 3.0 Unported License.

To view a copy of this license, visit
http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter
to Creative Commons, 171 Second Street, Suite 300, San Francisco,
California, 94105, USA.

*/

"use strict";

this.name           = "anarchies-salvager-tugger-script";
this.description    = "Ship script for Salvager Tuggers";
this.author         = "Commander McLane";
this.copyright      = "© 2012 Commander McLane";
this.license		= "CC-by-nc-sa 3.0";
this.version        = "2.8";


this.shipSpawned = function()
{
	// establishing the ship group of the Salvage Gang
	var salvageGangGroup = system.shipsWithRole("anarchies_salvage_gang", this.ship)[0].group;
	// adding this ship (Salvager Tugger) to the group
	salvageGangGroup.addShip(this.ship);
	// setting the group attribute to this ship itself
	this.ship.group = salvageGangGroup;
}
Scripts/anarchies-sentinel-station-patrol-script.js
/*

anarchies-sentinel-station-patrol-script.js

Ship script for Sentinel Station Patrols.


Oolite
Copyright © 2004-2012 Giles C Williams and contributors

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.


Anarchies.oxp
Copyright © 2007-2012 "Commander McLane"

This work is licensed under the Creative Commons
Attribution-Noncommercial-Share Alike 3.0 Unported License.

To view a copy of this license, visit
http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter
to Creative Commons, 171 Second Street, Suite 300, San Francisco,
California, 94105, USA.

*/

"use strict";

this.name           = "anarchies-sentinel-station-patrol-script";
this.description    = "Ship script for Sentinel Station Patrols";
this.author         = "Commander McLane";
this.copyright      = "© 2012 Commander McLane";
this.license		= "CC-by-nc-sa 3.0";
this.version        = "2.8";


this.$requestPatrolCoordinates = function()
{
    // if the Sentinel Station was destroyed, the patrol ships turn into normal police
    if(!this.ship.group.leader)
    {
        this.ship.switchAI("route1patrolAI.plist");
        return;
    }
    // depending on the patrol's current position it gets a new destination around the station
    switch(this.ship.AIState)
    {
        case "HEAD_FOR_PATROLPOINT_1":
            this.ship.savedCoordinates = this.ship.group.leader.position.add(this.ship.group.leader.vectorForward.multiply(-30000));
            break;
        
        case "HEAD_FOR_PATROLPOINT_2":
            this.ship.savedCoordinates = this.ship.group.leader.position.add(this.ship.group.leader.vectorUp.multiply(15000));
            break;
        
        case "HEAD_FOR_PATROLPOINT_3":
            this.ship.savedCoordinates = this.ship.group.leader.position.add(this.ship.group.leader.vectorForward.multiply(30000));
    }
}

this.$scanForRandomOffender = function()
{
    // the normal scan for offenders doesn't work in anarchies, therefore we're doing it by script
    // details in anarchies-sentinel-station-script.js
    function $isOffender(entity)
    {
        return entity.isShip && entity.scanClass !== "CLASS_ROCK" && entity.scanClass !== "CLASS_CARGO" && !entity.isCloaked && entity.bounty - randomBlindness > 0
    }
    var randomBlindness = Math.floor(Math.random() * 50);
    var offenders = system.filteredEntities(this, $isOffender, this.ship, 25600);
    if(offenders.length === 0)
    {
        this.ship.sendAIMessage("NOTHING_FOUND");
    }
    else
    {
        var targetedOffender = offenders[Math.floor(Math.random() * offenders.length)];
        this.ship.target = targetedOffender;
        this.ship.sendAIMessage("TARGET_FOUND");
    }
}
Scripts/anarchies-sentinel-station-script.js
/*

anarchies-sentinel-station-script.js

Script for turning Sentinel and Renegade Stations towards the planet.


Oolite
Copyright © 2004-2012 Giles C Williams and contributors

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.


Anarchies.oxp
Copyright © 2007-2012 "Commander McLane"

This work is licensed under the Creative Commons
Attribution-Noncommercial-Share Alike 3.0 Unported License.

To view a copy of this license, visit
http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter
to Creative Commons, 171 Second Street, Suite 300, San Francisco,
California, 94105, USA.

*/

"use strict";

this.name           = "anarchies-sentinel-station-script";
this.description    = "Ship script for Sentinel and Renegade Stations";
this.author         = "Commander McLane";
this.copyright      = "© 2012 Commander McLane";
this.license		= "CC-by-nc-sa 3.0";
this.version        = "2.9";


this.shipSpawned = function()
{
    // station is aligned along the z-axis and therefore towards the planet
    this.ship.orientation = [1, 0, 0, 0];
    // two variables for controlling the station's launch queue are initialised
    this.queuingDefenseShips = 0;
    this.queuingPatrolShips = 0;
}

this.stationLaunchedShip = function(ship)
{
    // if one of the defense ships is launched it gets subtracted from the queue counter
    if(ship.primaryRole === "defense_ship") this.queuingDefenseShips--;
    // same for the patrol ships
    if(ship.AI === "anarchiesSentinelStationPatrolAI.plist") this.queuingPatrolShips--;
    // if a trader has launched it gets a chance to head for the planet instead of jumping out
    if(ship.primaryRole === "trader" && Math.random() < 0.4) ship.switchAI("route1traderAI.plist");
}

this.shipTargetAcquired = function(target)
{
    // the station would never get a TARGET_LOST when its current target leaves scanner range
    // therefore we're tracing the target by a script timer in 2-second intervals once it's acquired
    // but not if it's not a piloted ship, or it already has a trace on it
    if(!target.isPiloted || (target === this.currentTarget && this.traceTargetTimer.isRunning)) return;
    // the current target is stored
    this.currentTarget = target;
    // if the timer already exists it is started
    if(this.traceTargetTimer)
    {
        this.traceTargetTimer.start();
    }
    // otherwise it is created
    else
    {
        this.traceTargetTimer = new Timer(this, this.$checkForTargetDistance, 2, 2);
    }
}

this.shipTargetLost = function(target)
{
    // after losing the target the timer is stopped
    this.traceTargetTimer.stop();
}

this.$checkForTargetDistance = function()
{
    // if the station's current target gets out of scanner range and then some
    // the station loses it
    if(this.ship.target && this.ship.position.distanceTo(this.ship.target.position) > 28000)
    {
        this.ship.target = null;
    }
}

this.$launchDefenseShip = function()
{
    // custom defense ship launching, because we don't want all defense ships launched every time
    // five at a time is enough
    function $isMyDefenseShip(entity)
    {
        return entity.isShip && entity.primaryRole === "defense_ship" && entity.owner === this.ship
    }
    // we count the already launched defense ships and add those already in the launch queue
    // if less than five, another one gets ready for launch
    if(system.filteredEntities(this, $isMyDefenseShip, this.ship, 25600).length + this.queuingDefenseShips < 5)
    {
        // however, the actual launch may take a while
        this.ship.launchDefenseShip();
        // therefore we're adding the new defense ship to the queue counter
        this.queuingDefenseShips++;
    }
}

this.$launchPatrolShip = function()
{
    // custom patrol ship launching, we only want four at a time
    function $isMyPatrolShip(entity)
    {
        return entity.isShip && entity.primaryRole === "police" && entity.group.leader === this.ship
    }
    // we count the already launched patrol ships and add those already in the launch queue
    // if less than four, another one gets ready for launch
    if(system.filteredEntities(this, $isMyPatrolShip, this.ship, 35000).length + this.queuingPatrolShips < 4)
    {
        // first we raise the counter
        this.queuingPatrolShips++;
        // the ship gets ready for launch
        var patrolShip = this.ship.launchShipWithRole("police");
        // it is added to the station's group
        this.ship.group.addShip(patrolShip);
        patrolShip.group = this.ship.group;
        // and it gets a custom script and AI
        patrolShip.setScript("anarchies-sentinel-station-patrol-script.js");
        patrolShip.switchAI("anarchiesSentinelStationPatrolAI.plist");
    }
}

this.$launchScavenger = function()
{
    // we don't want too many scavengers at a time
    if(system.countShipsWithPrimaryRole("scavenger", this.ship, 25600) === 0) this.ship.launchScavenger();
}

this.$scanForRandomOffender = function()
{
    // as Sentinel Stations are only spawned in anarchy systems, the normal scan for offenders is useless, because it doesn't find any ship in an anarchy
    // therefore we do the scan by script
    function $isOffender(entity)
    {
        return entity.isShip && entity.scanClass !== "CLASS_ROCK" && entity.scanClass !== "CLASS_CARGO" && !entity.isCloaked && entity.bounty - randomBlindness > 0
    }
    // like the normal AI method, our scan isn't perfect; there is a random chance to evade it as long as you're offender
    var randomBlindness = Math.floor(Math.random() * 50);
    // all found ships are put in an array
    var offenders = system.filteredEntities(this, $isOffender, this.ship, 25600);
    // if it's empty, no offenders were found
    if(offenders.length === 0)
    {
        this.ship.sendAIMessage("NOTHING_FOUND");
    }
    // otherwise one of the found ships gets randomly chosen and targeted
    else
    {
        var targetedOffender = offenders[Math.floor(Math.random() * offenders.length)];
        this.ship.target = targetedOffender;
        this.ship.sendAIMessage("TARGET_FOUND");
    }
}

this.playerWillEnterWitchspace = this.shipDied = function()
{
    // the tracing timer is stopped and deleted when the player leaves the system
    if(this.traceTargetTimer)
    {
        this.traceTargetTimer.stop();
        delete this.traceTargetTimer;
    }
}
Scripts/anarchies.js
/*

anarchies.js

Script for Anarchies.oxp.


Oolite
Copyright © 2004-2012 Giles C Williams and contributors

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.


Anarchies.oxp
Copyright © 2007-2012 "Commander McLane"

This work is licensed under the Creative Commons
Attribution-Noncommercial-Share Alike 3.0 Unported License.

To view a copy of this license, visit
http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter
to Creative Commons, 171 Second Street, Suite 300, San Francisco,
California, 94105, USA.

*/

"use strict";

this.name           = "Anarchies";
this.description    = "Script for Anarchies.oxp";
this.author         = "Commander McLane";
this.copyright      = "© 2012 Commander McLane";
this.license		= "CC-by-nc-sa 3.0";
this.version        = "2.9.2";


/* variables */

this.equipment_key = new Array(
	"EQ_ECM",
	"EQ_FUEL_SCOOPS",
	"EQ_ESCAPE_POD",
	"EQ_ENERGY_BOMB",
	"EQ_ENERGY_UNIT",
	"EQ_NAVAL_ENERGY_UNIT",
	"EQ_DOCK_COMP",
	"EQ_GAL_DRIVE",
	"EQ_FUEL_INJECTION",
	"EQ_SCANNER_SHOW_MISSILE_TARGET",
	"EQ_MULTI_TARGET",
	"EQ_ADVANCED_COMPASS",
	"EQ_ADVANCED_NAVIGATIONAL_ARRAY",
	"EQ_TARGET_MEMORY",
	"EQ_SHIELD_BOOSTER",
	"EQ_NAVAL_SHIELD_BOOSTER",
	"EQ_HEAT_SHIELD",
	"EQ_WORMHOLE_SCANNER"
);

this.behemoth_names = new Array(
    "Argus",
    "Atlas",
    "Bolverk",
    "Colossus",
    "Geryon",
    "Gog",
    "Goliath",
    "Grid",
    "Loki",
    "Magog",
    "Nimrod",
    "Surt",
    "Talos",
    "Tethys",
    "Titan",
    "Ymir"
);


/* functions */

this.$setUpSystem = function(populator)
{
	// nothing is done on relaunching from a station
	if(this.systemIsSetUp) return;
	// system is set up
	this.systemIsSetUp = true;
    // if on an amnesty mission, a battle in interstellar space is set up
    if(system.isInterstellarSpace && missionVariables.anarchies_amnesty == "GO_TO_BATTLE" && Math.round((System.infoForSystem(galaxyNumber, this.system1).coordinates.x + System.infoForSystem(galaxyNumber, this.system2).coordinates.x) / 2 * 2.5 * 10) / 10 == player.ship.galaxyCoordinates.x && Math.round((System.infoForSystem(galaxyNumber, this.system1).coordinates.y + System.infoForSystem(galaxyNumber, this.system2).coordinates.y) / 2 * 5 * 10) / 10 == player.ship.galaxyCoordinates.y)
    {
        system.addShips("behemoth", 3, [0, 0, 0], 15000);
        system.addShips("thargoid", 4, [0, 0, 0], 20000);
        var amnestyReservists = system.addShips("pirate", 5, [0, 0, 0], 15000);
        amnestyReservists.forEach(function(ship){
            this.$prepareAmnestyReservist(ship);
            ship.switchAI("anarchiesAmnestyReservistAI.plist");
        }, this);
        // more ships join the battle over time
        this.addShipsToBattleTimer = new Timer(this, this.$addShipsToBattle, 15, 15);
        // the player's kills are counted
        this.thargoidsKilled = 0;
        missionVariables.anarchies_amnesty = "FIGHT_IN_BATTLE";
        this.systemIsSetUp = true;
    }
    // nothing more is done in interstellar space
    if(system.isInterstellarSpace) return;
	// in Anarchies the following things are added:
	if(system.government === 0)
	{
		// low TL Anarchies have the chance to get either a Sentinel or a Renegade Station
		if(system.techLevel < 3)
		{
			var sdist = 0.2; //where will be the station in the main lane
			var spos = system.mainPlanet.position.multiply(sdist);
			if(system.scrambledPseudoRandomNumber(842) < 0.4) {
				if(populator) { //for Oolite 1.79 and above
					system.setPopulator("anarchies_sentinel_station", {
						callback: function(pos) {
						system.addShips("anarchies_sentinel_station", 1, pos, 0);
						}.bind(this),
						location: "COORDINATES",
						coordinates: spos,
						deterministic: true
					});
				} else system.addShipsToRoute("anarchies_sentinel_station", 1, sdist, "wp");
			} else if(system.scrambledPseudoRandomNumber(842) < 0.6) {
				if(populator) { //for Oolite 1.79 and above
					system.setPopulator("anarchies_renegade_station", {
						callback: function(pos) {
						system.addShips("anarchies_renegade_station", 1, pos, 0);
						}.bind(this),
						location: "COORDINATES",
						coordinates: spos,
						deterministic: true
					});
				} else system.addShipsToRoute("anarchies_renegade_station", 1, sdist, "wp");
			}
		}
		// middle TL Anarchies have the chance to get a Salvage Gang
		else if(system.techLevel < 6)
		{
			if(system.scrambledPseudoRandomNumber(842) < 0.6)
			{
				var sdist = 0.3; //where will be the station in the main lane
				var spos = system.mainPlanet.position.multiply(sdist);
				if(populator) { //for Oolite 1.79 and above
					system.setPopulator("anarchies_salvage_gang", {
						callback: function(pos) {
						system.addShips("anarchies_salvage_gang", 1, pos, 0);
						system.addShipsToRoute("anarchies_salvager_tugger", 1, 0.25, "wp");
						}.bind(this),
						location: "COORDINATES",
						coordinates: spos,
						deterministic: true
					});
				} else {
					system.addShipsToRoute("anarchies_salvage_gang", 1, sdist, "wp");
					system.addShipsToRoute("anarchies_salvager_tugger", 1, 0.25, "wp");
				}
			}
		}
		// high TL Anarchies have the chance to get a Hacker Outpost, through meeting a henchman
		else
		{
			system.addShipsToRoute("anarchies_henchman", 1, 0.2, "wp");
			system.addShipsToRoute("anarchies_henchman", 1, 0.3, "ws");
		}
	}
	// also non-Anarchy systems may get a Salvage Gang
	else if(system.scrambledPseudoRandomNumber(842) < 0.15)
	{
		system.addShipsToRoute("anarchies_salvage_gang", 1, 0.4, "wp");
		system.addShipsToRoute("anarchies_salvager_tugger", 1, 0.35, "wp");
	}
    // if an amnesty is offered, a Behemoth waits in-system
    if(missionVariables.anarchies_amnesty == "OFFER_MADE" && system.ID == this.amnestySystem && this.amnestyDeadline - (clock.minutes / 24 / 60) < 2.5 && this.amnestyDeadline - (clock.minutes / 24 / 60) > 0)
    {
		this.behemothPosition = new Vector3D(system.mainPlanet.position.subtract(system.mainStation.position));
		this.behemothPosition.z = 0;
		this.behemothPosition = this.behemothPosition.direction();
		this.behemothPosition = this.behemothPosition.multiply(system.mainPlanet.radius * 3);
		this.behemothPosition = this.behemothPosition.add(system.mainPlanet.position);
		var behemoth = system.addShips("behemoth-" + this.behemothName.toLowerCase(), 1, this.behemothPosition, 0);
		behemoth[0].switchAI("anarchiesBehemothAI.plist");
		behemoth[0].primaryRole = "anarchies_behemoth";
		// the Behemoth gets a beacon for easier finding it
		var beaconDistance = 6000;
		if(this.behemothName == "Colossus" || this.behemothName == "Geryon" || this.behemothName == "Gog" || this.behemothName == "Goliath" || this.behemothName == "Loki" || this.behemothName == "Magog" || this.behemothName == "Nimrod" || this.behemothName == "Titan") beaconDistance = -6000;
		var bc = system.addShips("anarchies_behemoth_beacon", 1, behemoth[0].position.add(behemoth[0].orientation.vectorForward().multiply(beaconDistance)), 0)[0];
		bc.beaconLabel = "Behemoth: " + expandDescription("[mission_anarchies_amnesty_behemoth_name]");
        // up to 20 amnesty seekers are added en route to the Behemoth
		var amnestySeekersNumber = Math.ceil(((1 - (this.amnestyDeadline - (clock.minutes / 24 / 60))) * 20) * ((Math.random() * 0.5) + 0.5));
		for(var i = 0; i < amnestySeekersNumber; i++)
		{
			var amnestySeeker = system.addShips("pirate", 1, this.behemothPosition.multiply(Math.random()), 10000);
			amnestySeeker[0].savedCoordinates = this.behemothPosition;
			amnestySeeker[0].switchAI("anarchiesAmnestySeekerAI.plist");
			amnestySeeker[0].bounty += Math.round(Math.random() * 50);
		}
		//further amnesty seekers are added by timer
		this.addAmnestySeekersTimer = new Timer(this, this.$addAmnestySeekers, 15, 30);
		// half as much bounty hunters are added en route as well
		for(var i = 0; i < (amnestySeekersNumber / 2); i++)
		{
			var amnestyHunter = system.addShips("hunter", 1, this.behemothPosition.multiply(Math.random()), 10000);
			amnestyHunter[0].savedCoordinates = this.behemothPosition;
			amnestyHunter[0].switchAI("anarchiesAmnestyHunterAI.plist");
		}
    }
    // after battle, the Behemoth waits in-system again
    if(missionVariables.anarchies_amnesty == "FOUGHT_IN_BATTLE" && system.ID == this.amnestySystem)
    {
		this.behemothPosition = new Vector3D(system.mainPlanet.position.subtract(system.mainStation.position));
		this.behemothPosition.z = 0;
		this.behemothPosition = this.behemothPosition.direction();
		this.behemothPosition = this.behemothPosition.multiply(system.mainPlanet.radius * 3);
		this.behemothPosition = this.behemothPosition.add(system.mainPlanet.position);
		var behemoth = system.addShips("behemoth-" + this.behemothName.toLowerCase(), 1, this.behemothPosition, 0);
		behemoth[0].switchAI("anarchiesBehemothAI.plist");
		behemoth[0].primaryRole = "anarchies_behemoth";
		// the Behemoth gets a beacon for easier finding it
		var beaconDistance = 6000;
		if(this.behemothName == "Colossus" || this.behemothName == "Geryon" || this.behemothName == "Gog" || this.behemothName == "Goliath" || this.behemothName == "Loki" || this.behemothName == "Magog" || this.behemothName == "Nimrod" || this.behemothName == "Titan") beaconDistance = -6000;
		var bc = system.addShips("anarchies_behemoth_beacon", 1, behemoth[0].position.add(behemoth[0].orientation.vectorForward().multiply(beaconDistance)), 0)[0];
		bc.beaconLabel = "Behemoth: " + expandDescription("[mission_anarchies_amnesty_behemoth_name]");
        if (populator === false) system.shipsWithPrimaryRole("buoy-witchpoint")[0].commsMessage("Amnesty seekers head for the Behemoth '" + expandDescription("[mission_anarchies_amnesty_behemoth_name]") + "'. ★ on your compass.");
		// up to 8 returning reservists are added en route to the Behemoth
		var returningReservistsNumber = Math.ceil(Math.random() * 8);
		for(var i = 0; i < returningReservistsNumber; i++)
		{
			var returningReservist = system.addShips("pirate", 1, this.behemothPosition.multiply(Math.random()), 10000);
			returningReservist[0].savedCoordinates = this.behemothPosition;
			this.$prepareAmnestyReservist(returningReservist[0]);
			returningReservist[0].switchAI("anarchiesReturningReservistAI.plist");
		}
		//further returning reservists are added by timer
		this.addReturningReservistsTimer = new Timer(this, this.$addReturningReservists, 15, 30);
    }
}

this.$addAmnestySeekers = function()
{
    // adds more ships heading for the waiting Behemoth
    var amnestySeeker = system.addShipsToRoute("pirate", 1, 0);
    amnestySeeker[0].savedCoordinates = this.behemothPosition;
    amnestySeeker[0].switchAI("anarchiesAmnestySeekerAI.plist");
    amnestySeeker[0].bounty += Math.round(Math.random() * 50);
    this.addAmnestySeekersTimer.interval = (Math.random() * 150) + 20;
}

this.$addShipsToBattle = function()
{
    // randomly adds Thargoids and/or amnesty seeking pirates to the interstellar battle
    // if only 4 or less Thargoids are left, no further reinforcements are added
    if(system.countShipsWithRole("thargoid") < 5)
    {
        this.addShipsToBattleTimer.stop();
        return;
    }
    if(Math.random() < 0.65) system.addShips("thargoid", 1);
    if(Math.random() < 0.65)
    {
        var amnestyReservist = system.addShips("pirate", 1);
        this.$prepareAmnestyReservist(amnestyReservist[0]);
        amnestyReservist[0].switchAI("anarchiesAmnestyReservistAI.plist");
    }
    this.addShipsToBattleTimer.interval = (Math.random() * 30) + 10;
}

this.$addReturningReservists = function()
{
    // adds more ships heading for the waiting Behemoth
    var returningReservist = system.addShipsToRoute("pirate", 1, 0);
    returningReservist[0].savedCoordinates = this.behemothPosition;
    this.$prepareAmnestyReservist(returningReservist[0]);
    returningReservist[0].switchAI("anarchiesReturningReservistAI.plist");
    this.addReturningReservistsTimer.interval = (Math.random() * 150) + 20;
}

this.$addBountyHunters = function()
{
	// fugitive players may encounter bounty hunters, when they enter a new system or launch
	if(player.bounty > 50 && Math.random() < 0.35)
	{
		system.addShips("anarchies_bounty_hunter", 2, player.ship.position, 15000);
		system.addShipsToRoute("anarchies_bounty_hunter", 2, 0.5, "wp");
	}
	// very fugitive players WILL encounter bounty hunters close to the main station
	if(player.bounty > 255) system.addShipsToRoute("anarchies_bounty_hunter", 2, 1.0);
}

this.$bonusOnBounty = function(target)
{
	// if the player isn't clean and his target was a criminal, he may get a bounty reduction instead of a payment
	if(player.bounty > 0 && !target.hasRole("asteroid") && target.bounty > 0 && Math.random() < 0.16)
	{
		// the reduction depends on the target's bounty
		player.bounty -= Math.ceil(Math.sqrt(target.bounty) * 2 / 3);
		// the player's bounty isn't reduced below 0
		if(player.bounty < 0) player.bounty = 0;
		// the awarded bounty is reduced from the player's money again. unfortunately this isn't yet displayed in the default kill-message
		player.credits -= target.bounty;
		// another message is displayed
		player.consoleMessage("GalCop thanks for your help. The bounty for this kill was exchanged for a reduction of your own bounty.", 6);
	}
}

this.$setUpEquipmentFailureTimer = function()
{
	if(!this.equipmentFailureTimer)
	{
		this.equipmentFailureTimer = new Timer(this, this.$salvagedEquipmentFailed, 20, 20);
	}
	this.equipmentFailureTimer.stop();
}

this.$salvagedEquipmentFailed = function()
{
	// gives a chance that salvaged equipment bought from a Salvage Gang may fail
	// or become working as first hand equipment by simply removing the failure chance
	// not executed if no salvaged equipment has been installed
	if(!missionVariables.anarchies_salvaged_equipment || missionVariables.anarchies_salvaged_equipment == 0) return;
	// there is a 1% random chance for failing, and 0.5% for becoming indistinguishable from first hand equipment
	var failureChance = Math.random();
	if(failureChance < 0.73 || failureChance >= 0.745) return;
	// one of the possible equipment items is chosen
	var equipCount = 0;
	var failingEquipment;
	// the number of possible equipment items is established and stored in equipCount
	for(var i = 0; i < this.equipment_key.length; i++)
	{
		if((missionVariables.anarchies_salvaged_equipment & Math.pow(2,i)) != 0) equipCount++;
	}
	// one of those is chosen with equal probability
	for(var i = 0; i < this.equipment_key.length; i++)
	{
		if((missionVariables.anarchies_salvaged_equipment & Math.pow(2,i)) != 0)
		{
			if(Math.random() < (1/equipCount))
			{
				failingEquipment = i;
				break;
			}
			equipCount--;
		}
	}
	// check if the equipment hasn't been disabled otherwise (in which case it is also removed from the list, because it has to be repaired or newly bought anyway)
	// also check whether we want to make it fail, or make it like first hand equipment; it fails only on the 1% chance from above
	if(player.ship.equipmentStatus(this.equipment_key[failingEquipment]) === "EQUIPMENT_OK" && failureChance < 0.74)
	{
		// equipment status is set to "damaged" and player is notified
		player.ship.setEquipmentStatus(this.equipment_key[failingEquipment], "EQUIPMENT_DAMAGED");
		player.consoleMessage("Oh no! Your second-hand " + EquipmentInfo.infoForKey(this.equipment_key[failingEquipment]).name + " just broke!", 6);
	}
	// item is removed from the list of installed salvaged equipment
	// which also happens on the 0.5% chance from above, or if the equipment was damaged or removed otherwise
	missionVariables.anarchies_salvaged_equipment = missionVariables.anarchies_salvaged_equipment & (Math.pow(2,this.equipment_key.length) - 1 - Math.pow(2,failingEquipment));
}

this.$newBountyCalculation1 = function(cause)
{
	// stores the player's bounty before jumping
	this.playerBounty = player.bounty;
	// a galactic jump still clears the player's bounty
	if(cause == "galactic jump") this.playerBounty = 0;
}

this.$newBountyCalculation2 = function()
{
	// calculates the bounty on the player after arriving in a new system, replacing Oolite's own formula which halves the bounty
	// does nothing for a misjump
	if(system.isInterstellarSpace) return;
	// the default mechanism is used for bounties < 51
	// between 51 and 60 there is a small chance only of reduction, making it likely to stay fugitive for a long time
	if(this.playerBounty > 50 && this.playerBounty < 61 && Math.random() > 0.93) player.bounty = 50;
	// above 60 there is a reduction by 10% (rounded)
	if(this.playerBounty > 60) player.bounty = Math.ceil(this.playerBounty * 0.9);
}

this.$bribeGalcopOfficial = function()
{
	// only started if no other missionscreen is running and only once before next jump
	if(!missionVariables.offering && !this.bribeOffer)
	{
		// offer is made, first missionscreen
		mission.runScreen({screenID:"anarchies_bribe", titleKey:"Anarchies_bribetitle", messageKey:"Anarchies_bribeoffer", choicesKey:"Anarchies_bribeoffer_offer"}, this.$evaluateBribeofferChoices);
		this.bribeOffer = "APPROACH";
		// mission_offering is set, to prevent legacy scripts from running missionscreens
		missionVariables.offering = "ANARCHIES";
		// dice is thrown to establish the bribesum requested
		var bribedice = Math.random();
		if(bribedice < 0.3)
		{
			this.bribesum = 8000;
			this.lowersum = 5000;
			missionVariables.anarchies_bribestring = "8000";
			missionVariables.anarchies_lowerstring = "5000";
		}
		else if(bribedice < 0.7)
		{
			this.bribesum = 10000;
			this.lowersum = 6000;
			missionVariables.anarchies_bribestring = "10000";
			missionVariables.anarchies_lowerstring = "6000";
		}
		else
		{
			this.bribesum = 12000;
			this.lowersum = 7000;
			missionVariables.anarchies_bribestring = "12000";
			missionVariables.anarchies_lowerstring = "7000";
		}
	}
	else if(this.bribeOffer == "DONE")
	{
		// if no further offers are made, let's get rid of some variables which are of no need anymore
		delete this.bribesum;
		delete this.lowersum;
		delete missionVariables.anarchies_bribestring;
		delete missionVariables.anarchies_lowerstring;
		this.bribeOffer = "END";
		// is reset only by the next jump
        // legacy scripts may run missionscreens again
        delete missionVariables.offering;
	}
}

this.$evaluateBribeofferChoices = function(choice)
{
	if(this.bribeOffer === "APPROACH")
	{
		// second screen, depending on YES or NO
		if(choice === "Anarchies_offer_2_NO")
		{
			mission.runScreen({screenID:"anarchies_bribe", titleKey:"Anarchies_bribetitle", messageKey:"Anarchies_bribeoffer_rejected"});
			this.bribeOffer = "DONE";
			// end, no other offer is made before leaving the system
		}
		else if(choice === "Anarchies_offer_1_YES")
		{
			mission.runScreen({screenID:"anarchies_bribe", titleKey:"Anarchies_bribetitle", messageKey:"Anarchies_bribechoice", choicesKey:"Anarchies_bribe_choices"}, this.$evaluateBribeofferChoices);
			this.bribeOffer = "OFFER";
		}
	}
	else if(this.bribeOffer === "OFFER")
	{
		// third screen, you may have accepted, refused, or tried to bargain
		if(choice === "Anarchies_choice_1_YES")
		{
			// accepted, deal made
			player.credits -= this.bribesum;
			mission.runScreen({screenID:"anarchies_bribe", titleKey:"Anarchies_bribetitle", messageKey:"Anarchies_bribed"});
			player.bounty = 0;
			this.bribeOffer = "DONE";
		}
		else if(choice === "Anarchies_choice_2_NO")
		{
			// refused, bad choice!
			mission.runScreen({screenID:"anarchies_bribe", titleKey:"Anarchies_bribetitle", messageKey:"Anarchies_not_bribed"});
			player.bounty = 350;
			this.bribeOffer = "DONE";
			// no further offer before leaving the system, but beware of bounty hunters!
		}
		else if(choice === "Anarchies_choice_3_LOWER")
		{
			// tried to bargain, let's see...
			if(Math.random() < 0.6)
			{
				// successful, you got your bargain
				player.credits -= this.lowersum;
				mission.runScreen({screenID:"anarchies_bribe", titleKey:"Anarchies_bribetitle", messageKey:"Anarchies_lowered"});
				player.bounty = 0;
			}
			else
			{
				// oh, oh; bad karma
				mission.runScreen({screenID:"anarchies_bribe", titleKey:"Anarchies_bribetitle", messageKey:"Anarchies_not_lowered"});
				player.bounty = 350;
			}
			this.bribeOffer = "DONE";
			// no further offer before leaving the system, see above
		}
	}
}

this.$multipass = function()
{
	// determines the result of using a Multipass, depending on the player's bounty and credits
	// the following will be passed to a shared missionscreen display function
	this.specialEquipment = "EQ_MULTIPASS";
	this.pageTitle = "Connecting to GalCop's central database";
	this.dotCount = 0;
	this.countEnd = 12;
	// costs of sub-ether connection are calculated according to the player's current bounty
	if(player.bounty > 120)
	{
		// have you got enough money?
		if(player.credits >= 7000)
		{
			this.notification = "Anarchies_Multipass_used_successfully";
			player.bounty = 0;
			player.credits -= 7000;
		}
		// or not?
		else
		{
			this.notification = "Anarchies_Multipass_connection_cancelled";
			player.bounty = 100;
			player.credits = 0;
			this.countEnd = 6;
		}
	}
	else if(player.bounty > 50)
	{
		if(player.credits >= 5000)
		{
			this.notification = "Anarchies_Multipass_used_successfully";
			player.bounty = 0;
			player.credits -= 5000;
		}
		else
		{
			this.notification = "Anarchies_Multipass_connection_cancelled";
			player.bounty = 45;
			player.credits = 0;
			this.countEnd = 6;
		}
	}
	else if(player.bounty > 20)
	{
		if(player.credits >= 3000)
		{
			this.notification = "Anarchies_Multipass_used_successfully";
			player.bounty = 0;
			player.credits -= 3000;
		}
		else
		{
			this.notification = "Anarchies_Multipass_connection_cancelled";
			player.bounty = 18;
			player.credits = 0;
			this.countEnd = 6;
		}
	}
	else
	{
		if(player.credits >= 1000)
		{
			this.notification = "Anarchies_Multipass_used_successfully";
			player.bounty = 0;
			player.credits -= 1000;
		}
		else
		{
			this.notification = "Anarchies_Multipass_connection_cancelled";
			player.bounty = 1;
			player.credits = 0;
			this.countEnd = 6;
		}
	}
	// progress notification is started with a timer, relevant data has been stored above
	this.dotTimer = new Timer(this, this.$progressDots, 0, 1.2);
}

this.$multipassedID = function()
{
	// calculates the result of buying a Multi-passed ID, depending on a dice-roll
	// again data for the missionscreen display function, which is the same as above
	this.specialEquipment = "EQ_MULTIPASSED_ID";
	this.pageTitle = "Installing a new transponder";
	this.dotCount = 0;
	this.countEnd = 6;
	// whose second-hand transponder you get, is purely random
	var chance = Math.random();
	if(chance < 0.15)
	{
		this.notification = "Anarchies_Multipassed_ID_highFUG";
		player.bounty = 205;
	}
	else if(chance < 0.3)
	{
		this.notification = "Anarchies_Multipassed_ID_lowFUG";
		player.bounty = 58;
	}
	else if(chance < 0.6)
	{
		this.notification = "Anarchies_Multipassed_ID_OFFEND";
		player.bounty = 15;
	}
	else
	{
		this.notification = "Anarchies_Multipassed_ID_CLEAN";
		player.bounty = 0;
	}
	// the rest is again done with a timer, to which the relevant data is passed
	this.dotTimer = new Timer(this, this.$progressDots, 0, 1.2);
}

this.$progressDots = function()
{
	// prints a couple of dots to indicate a process being executed, afterwards gives out a result screen
	// used by both this.$multipass and this.$multipassedID
	if(this.dotCount > this.countEnd)
	{
		// when we had enough small dots plotted, the final result is displayed, multipass or multipassed ID removed, and mission_offering cleared
		this.dotTimer.stop();
		delete this.dotTimer;
		mission.runScreen({screenID:"anarchies_progress", title:this.pageTitle, messageKey:this.notification});
		player.ship.removeEquipment(this.specialEquipment);
		return;
	}
	mission.runScreen({screenID:"anarchies_progress", title:this.pageTitle, messageKey:"Anarchies_progress_notification_dot_" + this.dotCount, choicesKey:"Anarchies_empty"});
	this.dotCount ++;
}

this.$rippedOffByRenegades = function()
{
	// nothing happens if the player is fugitive
	if(player.bounty > 50) return;
	if(!this.rippedOff)
	{
		mission.runScreen({screenID:"anarchies_renegades", title:"Ambush", messageKey:"Anarchies_Renegade_Station_Rippedoff"}, this.$launchPlayer);
		// how much money have you got?
		if(player.credits < 10000)
		{
			mission.addMessageTextKey("Anarchies_Renegade_Station_Rippedoff_1");
			player.credits = 0;
		}
		else
		{
			mission.addMessageTextKey("Anarchies_Renegade_Station_Rippedoff_2");
			player.credits -= 10000;
		}
		this.rippedOff = true;
	}
}

this.$launchPlayer = function()
{
	player.ship.removeAllCargo();
	this.rippedOff = null;
	player.ship.launch();
	// and off you go
}

this.$setSalvagedEquipmentChances = function()
{
	// sets the availability chances for salvaged equipment items
	// these are verified in equipment.plist
	missionVariables.salvaged_ecm_chance = Math.floor(Math.random()*100);
	missionVariables.salvaged_fuel_scoops_chance = Math.floor(Math.random()*100);
	missionVariables.salvaged_escape_pod_chance = Math.floor(Math.random()*100);
	missionVariables.salvaged_energy_bomb_chance = Math.floor(Math.random()*100);
	missionVariables.salvaged_energy_unit_chance = Math.floor(Math.random()*100);
	missionVariables.salvaged_naval_unit_chance = Math.floor(Math.random()*100);
	missionVariables.salvaged_dock_comp_chance = Math.floor(Math.random()*100);
	missionVariables.salvaged_gal_drive_chance = Math.floor(Math.random()*100);
	missionVariables.salvaged_injectors_chance = Math.floor(Math.random()*100);
	missionVariables.salvaged_target_enhancement_chance = Math.floor(Math.random()*100);
	missionVariables.salvaged_multi_target_chance = Math.floor(Math.random()*100);
	missionVariables.salvaged_adv_compass_chance = Math.floor(Math.random()*100);
	missionVariables.salvaged_adv_array_chance = Math.floor(Math.random()*100);
	missionVariables.salvaged_target_memory_chance = Math.floor(Math.random()*100);
	missionVariables.salvaged_shield_booster_chance = Math.floor(Math.random()*100);
	missionVariables.salvaged_naval_booster_chance = Math.floor(Math.random()*100);
	missionVariables.salvaged_heat_shield_chance = Math.floor(Math.random()*100);
	missionVariables.salvaged_wormhole_scanner_chance = Math.floor(Math.random()*100);
}

this.$salvagedEquipmentBought = function(boughtEquipmentKey)
{
	// checks which salvaged equipment was bought at a Salvage Gang
	for(var i = 0; i < this.equipment_key.length; i++)
	{
		// whatever it was ...
		if(boughtEquipmentKey == (this.equipment_key[i] + "_SALVAGED")) break;
	}
	// the equipment is stored in a missionVariable, to make it failable later
	missionVariables.anarchies_salvaged_equipment = missionVariables.anarchies_salvaged_equipment | Math.pow(2,i);
	// to make it usable the salvaged equipment is replaced with the standard variant
	player.ship.removeEquipment(boughtEquipmentKey);
	player.ship.awardEquipment(this.equipment_key[i]);
}

this.$resetSalvagedEquipmentChances = function()
{
	// delete a bunch of unnecessary missionVariables at launching from a Salvage Gang
	delete missionVariables.salvaged_ecm_chance;
	delete missionVariables.salvaged_fuel_scoops_chance;
	delete missionVariables.salvaged_escape_pod_chance;
	delete missionVariables.salvaged_energy_bomb_chance;
	delete missionVariables.salvaged_energy_unit_chance;
	delete missionVariables.salvaged_naval_unit_chance;
	delete missionVariables.salvaged_dock_comp_chance;
	delete missionVariables.salvaged_gal_drive_chance;
	delete missionVariables.salvaged_injectors_chance;
	delete missionVariables.salvaged_target_enhancement_chance;
	delete missionVariables.salvaged_multi_target_chance;
	delete missionVariables.salvaged_adv_compass_chance;
	delete missionVariables.salvaged_adv_array_chance;
	delete missionVariables.salvaged_target_memory_chance;
	delete missionVariables.salvaged_shield_booster_chance;
	delete missionVariables.salvaged_naval_booster_chance;
	delete missionVariables.salvaged_heat_shield_chance;
	delete missionVariables.salvaged_wormhole_scanner_chance;
}

this.$displayTimeDHM = function(minutes)
{
    // this function takes an integer number of minutes and converts it into a string of the form
    // 'd' days, 'h' hours and 'm' minutes, accomodating all cases of singular, plural, and 0
    if(minutes < 0) minutes = -minutes;
    var daysComponent = Math.floor(minutes / 24 / 60);
    var hoursComponent = Math.floor((minutes % (24 * 60)) / 60);
    var minutesComponent = minutes % 60;
    var timeString = "";
    if(daysComponent > 0) timeString += daysComponent + " day";
    if(daysComponent > 1) timeString += "s";
    if(timeString != "")
    {
        if(hoursComponent > 0 && minutesComponent > 0) timeString += ", ";
        else if(hoursComponent > 0) timeString += " and ";
    }
    if(hoursComponent > 0) timeString += hoursComponent + " hour";
    if(hoursComponent > 1) timeString += "s";
    if(timeString != "" && minutesComponent > 0) timeString += " and ";
    if(minutesComponent > 0) timeString += minutesComponent + " minute";
    if(minutesComponent > 1) timeString += "s";
    if(timeString == "") timeString = "no time";
    return timeString;
}

this.$amnestyOffer = function()
{
    if(!missionVariables.anarchies_amnesty && worldScripts.behemoth && (((player.ship.dockedStation.name == "Free Trade Zone" || player.ship.dockedStation.name == "Hacker Outpost" || player.ship.dockedStation.name == "Salvage Gang") && Math.random() < 0.2) || (system.government == 0 && Math.random() < 0.05) || (system.government > 0 && Math.random() < 0.02)))
    {
        // a system in the galaxy is randomly chosen
        this.amnestySystem = Math.floor(Math.random() * 256);
        if(this.amnestySystem == system.ID) return;
        // and the route from the current system calculated
        var amnestyRoute = system.info.routeToSystem(System.infoForSystem(galaxyNumber, this.amnestySystem), "OPTIMIZED_BY_TIME");
        // if the chosen system is unreachable, the code stops
        if(amnestyRoute == null) return;
        // the amnesty system, its name and distance are stored in the save-file, both for later reference and for transfering them to a mission screen
        missionVariables.anarchies_amnesty_system = this.amnestySystem;
        missionVariables.anarchies_amnesty_system_name = System.infoForSystem(galaxyNumber, this.amnestySystem).name;
        var amnestySystemDistance = Math.round(system.info.distanceToSystem(System.infoForSystem(galaxyNumber, this.amnestySystem)) * 5) / 5;
        missionVariables.anarchies_amnesty_system_distance = amnestySystemDistance;
        // the deadline is calculated:
        // first the minimum time is extended by a factor of 1.25, (it's possible to play with that; for bigger distances it's impossible to meet the deadline with few long jumps)
        // then it is rounded to noon of the day
        this.amnestyDeadline = Math.round((clock.hours + (amnestyRoute.time * 1.25) + 12) / 24) - 0.5;
        // if you could only arrive earliest in the afternoon, the deadline is extended one day
        if(this.amnestyDeadline < (clock.hours + amnestyRoute.time) / 24) this.amnestyDeadline += 1;
        // the deadline is stored in the save-file for later reference
        missionVariables.anarchies_amnesty_deadline = this.amnestyDeadline;
        // the day is stored in the save-file, again for displaying it on mission screens
        missionVariables.anarchies_amnesty_offer_date = Math.floor(this.amnestyDeadline);
        // like for contracts, the start window is calculated, and saved in the save-file for display on screen
        // first the time until deadline
        missionVariables.anarchies_amnesty_time = this.$displayTimeDHM((this.amnestyDeadline * 24 * 60) - clock.minutes);
        // then the end of the start window (time until deadline minus minimum travel time)
        missionVariables.anarchies_amnesty_start_time = this.$displayTimeDHM((this.amnestyDeadline * 24 * 60) - clock.minutes - Math.floor(amnestyRoute.time * 60));
        // one of the Behemoths is chosen randomly
        var behemothNumber = Math.floor(Math.random() * 16);
        this.behemothName = this.behemoth_names[behemothNumber];
        missionVariables.anarchies_amnesty_behemoth_name = this.behemothName;
        // all necessary information is put on a news screen
        mission.runScreen({screenID:"anarchies_amnesty", titleKey:"Anarchies_iNewstitle", messageKey:"Anarchies_amnesty_news", overlay:"anarchies_iNews.png"});
        missionVariables.anarchies_amnesty = "OFFER_MADE";
        return;
    }
	
    if(missionVariables.anarchies_amnesty == "OFFER_MADE" && system.ID == this.amnestySystem && player.ship.dockedStation.displayName.indexOf("Behemoth") >= 0 && player.ship.dockedStation.displayName.indexOf(this.behemothName) >= 0)
    {
        // no further ships jump into the system
        this.addAmnestySeekersTimer.stop();
        // one of the systems in range is randomly chosen
        this.system1 = system.info.systemsInRange()[Math.floor(Math.random() * system.info.systemsInRange().length)];
        // a second one is chosen, in range of the first system
        this.system2 = System.infoForSystem(galaxyNumber, this.system1.systemID).systemsInRange()[Math.floor(Math.random() * System.infoForSystem(galaxyNumber, this.system1.systemID).systemsInRange().length)];
        // the two systems are ordered in proximity to the current system
        if(system.info.distanceToSystem(System.infoForSystem(galaxyNumber, this.system1.systemID)) > system.info.distanceToSystem(System.infoForSystem(galaxyNumber, this.system2.systemID)))
        {
            var changeSystems = this.system1;
            this.system1 = this.system2;
            this.system2 = changeSystems;
        }
        // their numbers and names are put into mission variables, for later reference and to put them on a mission screen
        missionVariables.anarchies_amnesty_destination1_name = this.system1.name;
        missionVariables.anarchies_amnesty_destination2_name = this.system2.name;
        this.system1 = this.system1.systemID;
        this.system2 = this.system2.systemID;
        missionVariables.anarchies_amnesty_destination1 = this.system1;
        missionVariables.anarchies_amnesty_destination2 = this.system2;
        // the mission briefing is given
        mission.runScreen({screenID:"anarchies_amnesty", title:"Amnesty offer", messageKey:"Anarchies_amnesty_briefing", overlay:"anarchies_military_star.png"});
        // the two systems are marked, the player has to misjump between them
        mission.markSystem(this.system1, this.system2);
        // the relevant information is put on the manifest screen
        mission.setInstructionsKey("Anarchies_amnesty_order");
        // other ships join the player, he may travel with them
        this.launchAmnestyReservistsTimer = new Timer(this, this.$launchAmnestyReservist, 5, 20);
        missionVariables.anarchies_amnesty = "GO_TO_BATTLE";
        return;
    }
    if(missionVariables.anarchies_amnesty == "FOUGHT_IN_BATTLE" && system.ID == this.amnestySystem && player.ship.dockedStation.displayName.indexOf("Behemoth") >= 0 && player.ship.dockedStation.displayName.indexOf(this.behemothName) >= 0)
    {
        // no further ships jump into the system
        this.addReturningReservistsTimer.stop();
        // how well did the player?
        if(missionVariables.anarchies_amnesty_thargoids_killed >= 4)
        {
            // he succeeded, amnesty is granted
            missionVariables.anarchies_amnesty_order_date = this.amnestyDeadline - 14.5;
            mission.runScreen({screenID:"anarchies_amnesty", title:"Amnesty granted", messageKey:"Anarchies_amnesty_debriefing_yes", overlay:"anarchies_military_star.png"});
            player.bounty = 0;
        }
        else
        {
            // he didn't succeed, but there are different levels of failure
            switch(missionVariables.anarchies_amnesty_thargoids_killed)
            {
                // complete failure
                case 0:
                    missionVariables.anarchies_amnesty_debriefing_1 = "is not a single kill of a capital Thargoid ship";
                    missionVariables.anarchies_amnesty_debriefing_2 = "";
                    break;
                // at least he did something
                case 1:
                    missionVariables.anarchies_amnesty_debriefing_1 = "is only one kill of a capital Thargoid ship";
                    missionVariables.anarchies_amnesty_debriefing_2 = "For your participation in the battle 500 Cr have been transferred to your account. ";
                    player.credits += 500;
                    break;
                // almost there, but not yet
                default:
                    missionVariables.anarchies_amnesty_debriefing_1 = "are only " + missionVariables.anarchies_amnesty_thargoids_killed + " kills of capital Thargoid ships";
                    missionVariables.anarchies_amnesty_debriefing_2 = "For your participation in the battle 1000 Cr have been transferred to your account. ";
                    player.credits += 1000;
            }
            // information about the outcome
            mission.runScreen({screenID:"anarchies_amnesty", title:"No amnesty granted", messageKey:"Anarchies_amnesty_debriefing_no", overlay:"anarchies_military_star.png"});
            player.credits += 1000;
        }
        // mission ends, clear all variables
        this.$endAmnestyOffer();
        // launch some happy, freshly pardoned pirates
        var clearedReservists = Math.ceil(Math.random() * 6);
        while(clearedReservists > 0)
        {
            var clearedReservist = system.shipsWithPrimaryRole("anarchies_behemoth")[0].launchShipWithRole("pirate");
            clearedReservist.bounty = 0;
            clearedReservist.setAI("exitingTraderAI.plist");
            clearedReservists --;
        }
    }
}

this.$displayTimeTillAmnestyDeadline = function()
{
    // displays the remaining time till deadline, and the remaining distance on the manifest screen
    // if there isn't currently an offer, nothing is displayed
    if(!missionVariables.anarchies_amnesty || missionVariables.anarchies_amnesty != "OFFER_MADE") return;
    // if the offer has expired, the information is cleared
    if((this.amnestyDeadline * 24 * 60) - clock.minutes < 0)
    {
        mission.setInstructions(null);
        return;
    }
    // the remaining time is recalculated and the mission variable refreshed
    missionVariables.anarchies_amnesty_time = this.$displayTimeDHM((this.amnestyDeadline * 24 * 60) - clock.minutes);
    // the remaining distance is recalculated and the mission variable refreshed
    var amnestySystemDistance = Math.round(system.info.distanceToSystem(System.infoForSystem(galaxyNumber, this.amnestySystem)) * 5) / 5;
    missionVariables.anarchies_amnesty_system_distance = amnestySystemDistance;
    mission.setInstructionsKey("Anarchies_amnesty_reminder");
}

this.$launchAmnestyReservist = function()
{
    // launch a candidate for amnesty from the Behemoth
    var amnestyReservist = system.shipsWithPrimaryRole("anarchies_behemoth")[0].launchShipWithRole("pirate");
    this.$prepareAmnestyReservist(amnestyReservist);
    amnestyReservist.switchAI("anarchiesAmnestyReservistAI.plist");
    this.launchAmnestyReservistsTimer.interval = (Math.random() * 40) + 5;
}

this.$prepareAmnestyReservist = function(ship)
{
    // the reservists need some amendments to their ship scripts
    // jumping towards the battle
    ship.script.$jumpToTargetSystem = function()
    {
        if(system.ID == worldScripts.Anarchies.system1)
        {
            var targetSystem = worldScripts.Anarchies.system2;
            this.ship.scriptedMisjump = true;
        }
        else
        {
            var targetSystem = worldScripts.Anarchies.system1;
        }
        if(this.ship.exitSystem(targetSystem) == false) this.ship.reactToAIMessage("WITCHSPACE_UNAVAILABLE");
    }
    // check for correct system after the battle
    ship.script.$checkSystem = function()
    {
        if(system.ID == worldScripts.Anarchies.amnestySystem)
        {
            this.ship.savedCoordinates = worldScripts.Anarchies.behemothPosition;
            this.ship.reactToAIMessage("AMNESTY_SYSTEM");
        }
        else
        {
            this.ship.reactToAIMessage("SYSTEM1");
        }
    }
    // jumping towards the Behemoth after battle
    ship.script.$jumpToAmnestySystem = function()
    {
        if(system.info.distanceToSystem(System.infoForSystem(galaxyNumber, worldScripts.Anarchies.amnestySystem)) < 7)
        {
            var targetSystem = worldScripts.Anarchies.amnestySystem;
        }
        else
        {
            var targetSystem = worldScripts.Anarchies.system1;
        }
        if(this.ship.exitSystem(targetSystem) == false) this.ship.reactToAIMessage("WITCHSPACE_UNAVAILABLE");
    }
    // new bounty calculation, analog to the player
    // storing the bounty before jump
    ship.script.$CMcLoldShipWillEnterWormhole = ship.script.shipWillEnterWormhole;
    ship.script.shipWillEnterWormhole = function()
    {
        this.shipBounty = this.ship.bounty;
        if(ship.script.$CMcLoldShipWillEnterWormhole) ship.script.$CMcLoldShipWillEnterWormhole();
    }
    // restoring the bounty according to a new calculation after jump
    ship.script.$CMcLoldShipExitedWormhole = ship.script.shipExitedWormhole;
    ship.script.shipExitedWormhole = function()
    {
        if(this.ship.script.shipBounty)
        {
            if(this.shipBounty > 50) this.ship.bounty = this.shipBounty;
            if(this.shipBounty > 55) this.ship.bounty = Math.ceil(this.shipBounty * 0.9);
            if(system.isInterstellarSpace) this.ship.bounty = this.shipBounty;
        }
        if(ship.script.$CMcLoldShipExitedWormhole) ship.script.$CMcLoldShipExitedWormhole();
    }
    // when created first time, the ship has a considerable bounty
    ship.bounty += Math.round(Math.random() * 50);
    // to enable sunskimming, it gets proper insulation
    ship.heatInsulation = 7;
}

this.$endAmnestyOffer = function()
{
    // clear all traces of the amnesty mission
    if(this.system1) mission.unmarkSystem(this.system1, this.system2);
    mission.setInstructions(null);
    delete missionVariables.anarchies_amnesty_system;
    delete missionVariables.anarchies_amnesty_system_name;
    delete missionVariables.anarchies_amnesty_system_distance;
    delete missionVariables.anarchies_amnesty_deadline;
    delete missionVariables.anarchies_amnesty_offer_date;
    delete missionVariables.anarchies_amnesty_time;
    delete missionVariables.anarchies_amnesty_start_time;
    delete missionVariables.anarchies_amnesty_behemoth_name;
    delete missionVariables.anarchies_amnesty_destination1;
    delete missionVariables.anarchies_amnesty_destination2;
    delete missionVariables.anarchies_amnesty_destination1_name;
    delete missionVariables.anarchies_amnesty_destination2_name;
    delete missionVariables.anarchies_amnesty_thargoids_killed;
    delete missionVariables.anarchies_amnesty_order_date;
    delete missionVariables.anarchies_amnesty_debriefing_1;
    delete missionVariables.anarchies_amnesty_debriefing_2;
    delete missionVariables.anarchies_amnesty;
}


/* event handlers */

this.startUp = function()
{
    this.$setUpEquipmentFailureTimer();
        this.$firstMissionScreenOpportunity = true;
	this.escapePodUsed = false;
	this.systemIsSetUp = false;
    // restore some amnesty-related variables from the save-game
    if(missionVariables.anarchies_amnesty)
    {
        this.amnestySystem = missionVariables.anarchies_amnesty_system;
        this.amnestyDeadline = missionVariables.anarchies_amnesty_deadline;
        this.behemothName = missionVariables.anarchies_amnesty_behemoth_name;
        this.system1 = missionVariables.anarchies_amnesty_destination1;
        this.system2 = missionVariables.anarchies_amnesty_destination2;
    }
}

this.shipWillEnterWitchspace = function(cause)
{
	this.$newBountyCalculation1(cause);
	this.systemIsSetUp = false;
    // leaving the battle means leaving the battle
    if(missionVariables.anarchies_amnesty == "FIGHT_IN_BATTLE") missionVariables.anarchies_amnesty = "FOUGHT_IN_BATTLE";
    // all timers are stopped if the player leaves the system
    if(this.addAmnestySeekersTimer && this.addAmnestySeekersTimer.isRunning) this.addAmnestySeekersTimer.stop();
    if(this.launchAmnestyReservistsTimer && this.launchAmnestyReservistsTimer.isRunning) this.launchAmnestyReservistsTimer.stop();
    if(this.addShipsToBattleTimer && this.addShipsToBattleTimer.isRunning) this.addShipsToBattleTimer.stop();
    if(this.addReturningReservistsTimer && this.addReturningReservistsTimer.isRunning) this.addReturningReservistsTimer.stop();
}

this.shipWillExitWitchspace = function()
{
	this.$newBountyCalculation2();
	this.$addBountyHunters();
    // four days after the last amnesty deadline the variables are cleared, and another offer becomes possible
    if(missionVariables.anarchies_amnesty && missionVariables.anarchies_amnesty != "FIGHT_IN_BATTLE" && clock.days > this.amnestyDeadline + 4) this.$endAmnestyOffer();
	this.$setUpSystem(false);
	delete this.bribeOffer;
}

this.shipExitedWitchspace = function() 
{
    if(missionVariables.anarchies_amnesty == "OFFER_MADE" && system.ID == this.amnestySystem && this.amnestyDeadline - (clock.minutes / 24 / 60) < 2.5 && this.amnestyDeadline - (clock.minutes / 24 / 60) > 0)
	{
		var buoy = system.shipsWithPrimaryRole("buoy-witchpoint");
		if (buoy && buoy.length > 0) buoy[0].commsMessage("Amnesty seekers head for the Behemoth '" + expandDescription("[mission_anarchies_amnesty_behemoth_name]") + "'. ★ on your compass.");
	}
}

this.shipWillDockWithStation = function(station)
{
        this.$firstMissionScreenOpportunity = true;

	// stops the equipment failure timer while docked
	this.equipmentFailureTimer.stop();
	// restores the player's bounty after using the escape pod
	if(this.escapePodUsed)
	{
		player.bounty = this.playerBounty;
		this.escapePodUsed = false;
	}
	if(station.name == "Salvage Gang") this.$setSalvagedEquipmentChances();
}

this.missionScreenOpportunity = function()
{
    if( this.$firstMissionScreenOpportunity ) {
        this.$firstMissionScreenOpportunity = false;
	if(player.ship.docked && player.ship.dockedStation.isMainStation && this.bribeOffer != null && this.bribeOffer != "END") this.$bribeGalcopOfficial();
	if(player.ship.docked && player.ship.dockedStation.name === "Renegade Station") this.$rippedOffByRenegades();
    // you get an explanatory briefing at your first visit on a Hacker Outpost; the fact is stored in mission_anarchies_multipass
	if(player.ship.docked && player.ship.dockedStation.name === "Hacker Outpost" && !missionVariables.anarchies_multipass)
    	{
        	mission.runScreen({screenID:"anarchies_hacker", title:"Welcome to the Hacker Outpost", messageKey:"Anarchies_Hacker_Outpost_Briefing"});
        	missionVariables.anarchies_multipass = "YES";
    	}
    	if(player.ship.docked) this.$amnestyOffer();
    }
}

this.guiScreenWillChange = function(to, from)
{
    if(to == "GUI_SCREEN_MANIFEST") this.$displayTimeTillAmnestyDeadline();
}

this.guiScreenChanged = function(to, from)
{
	// a corrupt GalCop official turns up only in Anarchy main stations, in the equipment department, if the player has enough money and isn't clean, and by chance
	if(player.ship.docked && player.ship.dockedStation.isMainStation && system.government == 0 && !missionVariables.offering && player.bounty > 0 && player.credits >= 12000 && to == "GUI_SCREEN_EQUIP_SHIP" && Math.random() > 0.86) this.$bribeGalcopOfficial();
}

this.playerBoughtEquipment = function(equipmentKey)
{
	// the processes are now run immediately after buying the equipment, independent from the next tickle
	if(equipmentKey == "EQ_MULTIPASS") this.$multipass();
	if(equipmentKey == "EQ_MULTIPASSED_ID") this.$multipassedID();
	// if you buy a used Naval energy unit while you still have the normal one, Oolite 1.72 would remove your expensive new purchase again
	// we don't want that, so we're removing the standard unit, and everything's fine
	if(equipmentKey == "EQ_NAVAL_ENERGY_UNIT_SALVAGED")
	{
		player.ship.removeEquipment("EQ_ENERGY_UNIT");
		// the extra energy unit is also removed from the list of bought salvaged equipment, if it should have been listed there
		missionVariables.anarchies_salvaged_equipment = missionVariables.anarchies_salvaged_equipment & (Math.pow(2,this.equipment_key.length) - 1 - Math.pow(2,4));
	}
	// any used equipment is installed properly right away
	if(equipmentKey.substr(equipmentKey.length - 9,9) === "_SALVAGED") this.$salvagedEquipmentBought(equipmentKey);
}

this.shipWillLaunchFromStation = function(station)
{
	if(station.name === "Salvage Gang") this.$resetSalvagedEquipmentChances();
	this.$addBountyHunters();
	this.$setUpSystem(false);
	this.equipmentFailureTimer.start();
}

this.shipTargetDestroyed = function(target)
{
    // the bonus on your own bounty if you have killed a pirate is currently disabled,
    // because Oolite is doing this all on its own since version 1.74
    // this.$bonusOnBounty(target);
    // when fighting a battle to get amnesty, your kills are counted
    if(system.isInterstellarSpace && missionVariables.anarchies_amnesty == "FIGHT_IN_BATTLE" && target.hasRole("thargoid") && !player.ship.isCloaked)
    {
        this.thargoidsKilled ++
        missionVariables.anarchies_amnesty_thargoids_killed = this.thargoidsKilled;
        if(this.thargoidsKilled <= 4)
        {
            player.consoleMessage(expandMissionText("Anarchies_amnesty_" + this.thargoidsKilled + "_killed"));
            mission.setInstructionsKey("Anarchies_amnesty_" + this.thargoidsKilled + "_killed");
        }
    }
}

this.shipLaunchedEscapePod = function(escapepod)
{
	// stores the player's bounty in a script variable
	this.playerBounty = player.bounty;
	// remembers use of escape pod
	this.escapePodUsed = true;
}

this.systemWillPopulate = function() { //for Oolite 1.79 and above
	this.$setUpSystem(true);
}
Scripts/anarchies_conditions.js
"use strict";
this.name        = "Anarchies_Conditions";
this.author      = "phkb";
this.copyright   = "2015 phkb";
this.description = "Condition script for ships and equipment.";
this.licence     = "CC BY-NC-SA 3.0";
this.version     = "2.9.4";

this.allowSpawnShip = function(shipKey) {
    switch (shipKey) {
        case "anarchies-renegade_viper":
        case "anarchies-hacker-viper":
        case "anarchies-renegade-viper":
        case "anarchies-hacker-henchman": 
            if (system.info.government < 2) return true;
            break;
        case "anarchies-scavenger-phoenix":
            if (system.info.government === 0) return true;
            break;
        
    }
    return false;
}

this.allowAwardEquipment = function(equipment, ship, context) {
    if (context === "scripted") return true;
    var _dockedStation = player.ship.dockedStation;
    
    switch (equipment) {
        case "EQ_MULTIPASS":
            if (_dockedStation && _dockedStation.displayName === "Hacker Outpost" && system.info.government === 0) return true;
            break;
        case "EQ_MULTIPASSED_ID":
            if (_dockedStation && _dockedStation.displayName === "Salvage Gang" && system.info.government === 0) return true;
            break;
        case "EQ_ECM_SALVAGED":
            if (_dockedStation && _dockedStation.displayName === "Salvage Gang" && missionVariables.salvaged_ecm_chance > 65) return true;
            break;
        case "EQ_FUEL_SCOOPS_SALVAGED":
            if (_dockedStation && _dockedStation.displayName === "Salvage Gang" && missionVariables.salvaged_fuel_scoops_chance > 65) return true;
            break;
        case "EQ_ESCAPE_POD_SALVAGED":
            if (_dockedStation && _dockedStation.displayName === "Salvage Gang" && missionVariables.salvaged_escape_pod_chance > 75) return true;
            break;
        case "EQ_ENERGY_BOMB_SALVAGED":
            if (_dockedStation && _dockedStation.displayName === "Salvage Gang" && missionVariables.salvaged_energy_bomb_chance > 75) return true;
            break;
        case "EQ_ENERGY_UNIT_SALVAGED":
            if (_dockedStation && _dockedStation.displayName === "Salvage Gang" && missionVariables.salvaged_energy_unit_chance > 80) return true;
            break;
        case "EQ_NAVAL_ENERGY_UNIT_SALVAGED":
            if (_dockedStation && _dockedStation.displayName === "Salvage Gang" && missionVariables.salvaged_naval_unit_chance > 90) return true;
            break;
        case "EQ_DOCK_COMP_SALVAGED":
            if (_dockedStation && _dockedStation.displayName === "Salvage Gang" && missionVariables.salvaged_dock_comp_chance > 75) return true;
            break;
        case "EQ_GAL_DRIVE_SALVAGED":
            if (_dockedStation && _dockedStation.displayName === "Salvage Gang" && missionVariables.salvaged_gal_drive_chance > 85) return true;
            break;
        case "EQ_FUEL_INJECTION_SALVAGED":
            if (_dockedStation && _dockedStation.displayName === "Salvage Gang" && missionVariables.salvaged_injectors_chance > 65) return true;
            break;
        case "EQ_SCANNER_SHOW_MISSILE_TARGET_SALVAGED":
            if (_dockedStation && _dockedStation.displayName === "Salvage Gang" && missionVariables.salvaged_target_enhancement_chance > 65) return true;
            break;
        case "EQ_MULTI_TARGET_SALVAGED":
            if (_dockedStation && _dockedStation.displayName === "Salvage Gang" && missionVariables.salvaged_multi_target_chance > 65) return true;
            break;
        case "EQ_ADVANCED_COMPASS_SALVAGED":
            if (_dockedStation && _dockedStation.displayName === "Salvage Gang" && missionVariables.salvaged_adv_compass_chance > 65) return true;
            break;
        case "EQ_ADVANCED_NAVIGATIONAL_ARRAY_SALVAGED":
            if (_dockedStation && _dockedStation.displayName === "Salvage Gang" && missionVariables.salvaged_adv_array_chance > 75) return true;
            break;
        case "EQ_TARGET_MEMORY_SALVAGED":
            if (_dockedStation && _dockedStation.displayName === "Salvage Gang" && missionVariables.salvaged_target_memory_chance > 65) return true;
            break;
        case "EQ_SHIELD_BOOSTER_SALVAGED":
            if (_dockedStation && _dockedStation.displayName === "Salvage Gang" && missionVariables.salvaged_shield_booster_chance > 75) return true;
            break;
        case "EQ_NAVAL_SHIELD_BOOSTER_SALVAGED":
            if (_dockedStation && _dockedStation.displayName === "Salvage Gang" && missionVariables.salvaged_naval_booster_chance > 85) return true;
            break;
        case "EQ_HEAT_SHIELD_SALVAGED":
            if (_dockedStation && _dockedStation.displayName === "Salvage Gang" && missionVariables.salvaged_heat_shield_chance > 75) return true;
            break;
        case "EQ_WORMHOLE_SCANNER_SALVAGED":
            if (_dockedStation && _dockedStation.displayName === "Salvage Gang" && missionVariables.salvaged_wormhole_scanner_chance > 80) return true;
            break;
    }
    return false;
}
Scripts/hackeroutpost_market.js
"use strict";
this.name = "hackeroutpost_market";
this.author = "spara";
this.copyright = "2014 spara";
this.license     = "CC BY-NC-SA 4.0";

this.$originalDefs = {
      "food" : [0, 0, 47, -8, -1, -3, 12, 3, 0],
      "textiles" : [0, 0, 55, -9, -1, -1, 15, 3, 0],
      "radioactives" : [0, 0, 45, -5, -3, 0, 15, 7, 0],
      "slaves" : [0, 0, 6, 0, 0, 0, 7, 0, 0],
      "liquor_wines" : [0, 0, 128, 0, 0, 0, 63, 0, 0],
      "luxuries" : [0, 0, 236, 4, 1, -1, 7, 3, 0],
      "narcotics" : [0, 0, 208, 0, 0, 0, 79, 0, 0],
      "computers" : [0, 0, 82, 7, 5, 25, 15, 15, 0],
      "machinery" : [0, 0, 103, 6, 6, 20, 7, 7, 0],
      "alloys" : [0, 0, 124, 1, 1, 2, 15, 3, 0],
      "firearms" : [0, 0, 159, 5, 0, 0, 15, 0, 0],
      "furs" : [0, 0, 170, 0, 0, 0, 31, 0, 0],
      "minerals" : [0, 0, 24, -1, -1, 7, 3, 15, 0],
      "gold" : [0, 0, 110, -1, -1, -2, 7, 5, 1],
      "platinum" : [0, 0, 195, -2, -2, -1, 15, 3, 1],
      "gem_stones" : [0, 0, 54, -1, -1, 3, 7, 3, 2],
      "alien_items" : [0, 0, 137, 0, 0, 0, 31, 0, 0]
};

this.updateLocalCommodityDefinition = function(goodDefinition) {
	var commodity = goodDefinition.key;
	var oldDefs = this.$originalDefs[commodity];
	//old style definition found for the good. calculate it the old way
	if (oldDefs) {
		var market_base_price = oldDefs[2];
		var market_eco_adjust_price = oldDefs[3];
		var market_eco_adjust_quantity = oldDefs[4];
		var market_base_quantity = oldDefs[5];
		var market_mask_price = oldDefs[6];
		var market_mask_quantity = oldDefs[7];
		var market_rnd = Math.floor(Math.random() * 256);

		var economy = system.economy;

		var price = (market_base_price + (market_rnd & market_mask_price) + (economy * market_eco_adjust_price)) & 255;
		price *= 0.4;

		var quantity = (market_base_quantity + (market_rnd & market_mask_quantity) - (economy * market_eco_adjust_quantity)) & 255;
		if (quantity > 127) quantity = 0;
		quantity &= 63;

		goodDefinition.price = price * 10;
		goodDefinition.quantity = quantity;
	}
	//no definition found. nullify the goods.
	else {
		goodDefinition.price = 0;
		goodDefinition.quantity = 0;
	}
	return goodDefinition;
};
Scripts/salvagegang_market.js
"use strict";
this.name = "salvagegang_market";
this.author = "spara";
this.copyright = "2014 spara";
this.license     = "CC BY-NC-SA 4.0";

this.$originalDefs = {
      "food" : [0, 0, 29, -2, -2, -3, 1, 3, 0],
      "textiles" : [0, 0, 30, -1, -1, -4, 3, 3, 0],
      "radioactives" : [0, 0, 58, -3, -3, 0, 7, 7, 0],
      "slaves" : [0, 0, 9, 0, 0, 0, 7, 0, 0],
      "liquor_wines" : [0, 0, 106, -5, 0, 0, 15, 0, 0],
      "luxuries" : [0, 0, 206, 6, 1, -3, 7, 3, 0],
      "narcotics" : [0, 0, 208, 0, 0, 0, 79, 0, 0],
      "computers" : [0, 0, 134, 14, 0, 15, 3, 15, 0],
      "machinery" : [0, 0, 75, 0, 0, 18, 28, 31, 0],
      "alloys" : [0, 0, 42, 0, 0, 32, 31, 31, 0],
      "firearms" : [0, 0, 155, 3, 0, 0, 15, 0, 0],
      "furs" : [0, 0, 130, 0, 0, 0, 63, 0, 0],
      "minerals" : [0, 0, 22, -1, -1, 7, 3, 15, 0],
      "gold" : [0, 0, 78, 0, 0, -6, 15, 29, 1],
      "platinum" : [0, 0, 150, 0, 0, -9, 15, 31, 1],
      "gem_stones" : [0, 0, 34, 0, 0, -4, 14, 15, 2],
      "alien_items" : [0, 0, 58, 15, 0, 0, 7, 0, 0]
};

this.updateLocalCommodityDefinition = function(goodDefinition) {
	var commodity = goodDefinition.key;
	var oldDefs = this.$originalDefs[commodity];
	//old style definition found for the good. calculate it the old way
	if (oldDefs) {
		var market_base_price = oldDefs[2];
		var market_eco_adjust_price = oldDefs[3];
		var market_eco_adjust_quantity = oldDefs[4];
		var market_base_quantity = oldDefs[5];
		var market_mask_price = oldDefs[6];
		var market_mask_quantity = oldDefs[7];
		var market_rnd = Math.floor(Math.random() * 256);

		var economy = system.economy;

		var price = (market_base_price + (market_rnd & market_mask_price) + (economy * market_eco_adjust_price)) & 255;
		price *= 0.4;

		var quantity = (market_base_quantity + (market_rnd & market_mask_quantity) - (economy * market_eco_adjust_quantity)) & 255;
		if (quantity > 127) quantity = 0;
		quantity &= 63;

		goodDefinition.price = price * 10;
		goodDefinition.quantity = quantity;
	}
	//no definition found. nullify the goods.
	else {
		goodDefinition.price = 0;
		goodDefinition.quantity = 0;
	}
	return goodDefinition;
};
Scripts/sentinelstation_market.js
"use strict";
this.name = "sentinelstation_market";
this.author = "spara";
this.copyright = "2014 spara";
this.license     = "CC BY-NC-SA 4.0";

this.$originalDefs = {
      "food" : [0, 0, 43, -3, 0, -1, 7, 5, 0],
      "textiles" : [0, 0, 33, -2, 0, -1, 7, 7, 0],
      "radioactives" : [0, 0, 65, -3, -3, 2, 7, 7, 0],
      "slaves" : [0, 0, 37, -5, -31, -189, 73, 7, 0],
      "liquor_wines" : [0, 0, 29, 5, -5, 251, 15, 15, 0],
      "luxuries" : [0, 0, 163, 11, 8, 54, 15, 3, 0],
      "narcotics" : [0, 0, 205, 5, 29, 8, 15, 0, 0],
      "computers" : [0, 0, 154, 14, 14, 56, 3, 3, 0],
      "machinery" : [0, 0, 117, 6, 6, 40, 7, 7, 0],
      "alloys" : [0, 0, 78, 1, 1, 17, 31, 31, 0],
      "firearms" : [0, 0, 136, 13, 13, 29, 28, 0, 0],
      "furs" : [0, 0, 176, -9, -9, 220, 63, 63, 0],
      "minerals" : [0, 0, 32, -1, -1, 53, 3, 3, 0],
      "gold" : [0, 0, 107, -1, -1, 66, 7, 7, 1],
      "platinum" : [0, 0, 185, -2, -2, 55, 31, 31, 1],
      "gem_stones" : [0, 0, 55, -1, -1, 250, 15, 15, 2],
      "alien_items" : [0, 0, 21, 15, 0, 0, 63, 0, 0]
};

this.updateLocalCommodityDefinition = function(goodDefinition) {
	var commodity = goodDefinition.key;
	var oldDefs = this.$originalDefs[commodity];
	//old style definition found for the good. calculate it the old way
	if (oldDefs) {
		var market_base_price = oldDefs[2];
		var market_eco_adjust_price = oldDefs[3];
		var market_eco_adjust_quantity = oldDefs[4];
		var market_base_quantity = oldDefs[5];
		var market_mask_price = oldDefs[6];
		var market_mask_quantity = oldDefs[7];
		var market_rnd = Math.floor(Math.random() * 256);

		var economy = system.economy;

		var price = (market_base_price + (market_rnd & market_mask_price) + (economy * market_eco_adjust_price)) & 255;
		price *= 0.4;

		var quantity = (market_base_quantity + (market_rnd & market_mask_quantity) - (economy * market_eco_adjust_quantity)) & 255;
		if (quantity > 127) quantity = 0;
		quantity &= 63;

		goodDefinition.price = price * 10;
		goodDefinition.quantity = quantity;
	}
	//no definition found. nullify the goods.
	else {
		goodDefinition.price = 0;
		goodDefinition.quantity = 0;
	}
	return goodDefinition;
};