Scripts/smugglers_contracts.js |
"use strict";
this.name = "Smugglers_Contracts";
this.author = "phkb and cim";
this.description = "Adds smuggling contracts via an interface screen, with code borrowed heavily from the cargo contracts system, authored by cim.";
this.licence = "CC BY-NC-SA 3.0";
this._disabled = false;
/*
Note: The smuggling contract system is independent of the standard cargo contract system. The reason for this is that
smuggled cargo might exist in a number of different places (smuggling compartment, or hidden under a manifest relabel)
This means the normal cargo contract system cannot pick up the presence of hidden cargo.
The end result is that a lot of the standard cargo contract core code has been reproduced here as JS.
TODO: add "Negotiate" option to haggle for the fee
*/
//=============================================================================================================
/**** Configuration options and API ****/
/* OXPs which wish to add a background to the summary pages should
set this value */
this._smugglingSummaryPageBackground = "";
/* OXPs which wish to add an overlay to the parcel mission screens
should set this value */
this._smugglingPageOverlay = "";
this._smugglingPageOverlayHeight = 0;
this._suspendedDestination = null;
this._suspendedHUD = false;
this._smugglingContracts = [];
this._smugglingRepGood = 0;
this._smugglingRepBad = 0;
this._smugglingRepUnknown = 0;
this._maxRep = 70;
this._checkForCargo = false;
this._marketrnd = 0;
//=============================================================================================================
/* this.$addSmugglingContractToSystem(cargo)
* This function adds the defined smuggling contract to the black market contract list.
* A contract definition is an object with the following parameters, all required:
*
* destination: system ID of destination system
* commodity: the cargo type
* size: the number of units of cargo
* deadline: the deadline for delivery, in clock seconds
* payment: the payment for delivery on time, in credits
*
* and optionally, the following parameters:
*
* deposit: the deposit payment required by the player (default 0)
* route: a route object generated with system.info.routeToSystem
* describing the route between the source and destination
* systems.
*
* If this is not specified, it will be generated automatically.
*
* The function will return true if the contract can be added, false
* otherwise.
*/
this.$addSmugglingContractToSystem = function $addSmugglingContractToSystem(cargo) {
if (cargo.destination < 0 || cargo.destination > 255) {
log(this.name, "Rejected contract: destination missing or invalid");
return false;
}
if (cargo.deadline <= clock.adjustedSeconds) {
log(this.name, "Rejected contract: deadline invalid");
return false;
}
if (cargo.payment < 0) {
log(this.name, "Rejected contract: payment invalid");
return false;
}
if (!cargo.size || cargo.size < 1) {
log(this.name, "Rejected contract: size invalid");
return false;
}
if (!cargo.commodity) {
log(this.name, "Rejected contract: commodity unspecified");
return false;
}
if (!system.mainStation.market[cargo.commodity]) {
log(this.name, "Rejected contract: commodity invalid");
return false;
}
if (!cargo.route) {
var destinationInfo = System.infoForSystem(galaxyNumber, cargo.destination);
cargo.route = system.info.routeToSystem(destinationInfo);
if (!cargo.route) {
log(this.name, "Rejected contract: route invalid");
return false;
}
}
if (!cargo.deposit) {
cargo.deposit = 0;
} else if (cargo.deposit >= cargo.payment) {
log(this.name, "Rejected contract: deposit higher than total payment");
return false;
}
this._contracts.push(cargo);
return true;
}
//=============================================================================================================
/* Event handlers */
//-------------------------------------------------------------------------------------------------------------
this.startUpComplete = function () {
if (this._disabled === true) {
delete this.shipExitedWitchspace;
delete this.playerWillSaveGame;
delete this.shipWillLaunchFromStation;
delete this.guiScreenWillChange;
delete this.guiScreenChanged;
delete this.startUp;
return;
}
this._helper = worldScripts["oolite-contracts-helpers"];
var core = worldScripts.Smugglers_CoreFunctions;
this.$padTextRight = core.$padTextRight;
this.$padTextLeft = core.$padTextLeft;
this.$isBigGuiActive = core.$isBigGuiActive;
this.$rand = core.$rand;
if (missionVariables.Smuggling_MarketRnd) this._marketrnd = missionVariables.Smuggling_MarketRnd;
if (missionVariables.Smuggling_RepGood) {
this._smugglingRepGood = missionVariables.Smuggling_RepGood;
this._smugglingRepBad = missionVariables.Smuggling_RepBad;
this._smugglingRepUnknown = missionVariables.Smuggling_RepUnknown;
}
this.$normaliseSmugglingReputation();
if (missionVariables.Smuggling_ActiveContracts) {
this._smugglingContracts = JSON.parse(missionVariables.Smuggling_ActiveContracts);
}
// stored contents of systems's cargo contract list
if (missionVariables.Smuggling_Contracts) {
this._contracts = JSON.parse(missionVariables.Smuggling_Contracts);
} else {
this.$initialiseSmugglingContractsForSystem();
}
// its unclear whether this or ContractsOnBB will get to it's startUpComplete first, so we'll force the issue here
if (worldScripts.ContractsOnBB) {
worldScripts.ContractsOnBB.$convertSmugglingContracts();
}
var xui = worldScripts.XenonUI;
if (xui) xui.$addMissionScreenException("oolite-smuggling-contracts-details"); // smuggling-contracts-details
var xrui = worldScripts.XenonReduxUI;
if (xrui) xrui.$addMissionScreenException("oolite-smuggling-contracts-details");
}
//-------------------------------------------------------------------------------------------------------------
this.shipExitedWitchspace = function () {
if (!system.isInterstellarSpace && !system.sun.hasGoneNova && system.stations.length > 1) {
// must be a regular system with at least one station other than the main one
this._marketrnd = this.$rand(256) - 1;
this.$erodeSmugglingReputation();
this.$initialiseSmugglingContractsForSystem();
this.$adjustMarket();
}
}
//-------------------------------------------------------------------------------------------------------------
this.playerWillSaveGame = function () {
// encode the contract list to a string for storage in the savegame
missionVariables.Smuggling_Contracts = JSON.stringify(this._contracts);
missionVariables.Smuggling_RepGood = this._smugglingRepGood;
missionVariables.Smuggling_RepBad = this._smugglingRepBad;
missionVariables.Smuggling_RepUnknown = this._smugglingRepUnknown;
missionVariables.Smuggling_ActiveContracts = JSON.stringify(this._smugglingContracts);
missionVariables.Smuggling_MarketRnd = this._marketrnd;
}
//-------------------------------------------------------------------------------------------------------------
// when the player exits the mission screens, reset their destination
// system and HUD settings, which the mission screens may have
// affected.
this.shipWillLaunchFromStation = function () {
this.$resetViews();
}
//-------------------------------------------------------------------------------------------------------------
this.shipDockedWithStation = function (station) {
if (player.ship.dockedStation.allegiance === "galcop") this._checkForCargo = true;
}
//-------------------------------------------------------------------------------------------------------------
this.missionScreenOpportunity = function () {
if (this._checkForCargo === true) {
this._checkForCargo = false;
this.$checkForCompletedContracts();
}
}
//-------------------------------------------------------------------------------------------------------------
this.guiScreenWillChange = function (to, from) {
this.$resetViews();
if (to === "GUI_SCREEN_MANIFEST") this.$updateManifest();
}
//-------------------------------------------------------------------------------------------------------------
this.guiScreenChanged = function (to, from) {
if (to != "GUI_SCREEN_MISSION") this.$resetViews();
}
//=============================================================================================================
/* Interface functions */
//-------------------------------------------------------------------------------------------------------------
// runs through all smuggling contracts looking for any completed ones
this.$checkForCompletedContracts = function $checkForCompletedContracts() {
if (this._smugglingContracts.length === 0) return;
var sc = worldScripts.Smugglers_Equipment;
var sdm = worldScripts.Smugglers_DockMaster;
var p = player.ship;
var list = [];
for (var i = this._smugglingContracts.length - 1; i >= 0; i--) {
var m = this._smugglingContracts[i];
var errorCode = "";
var new_payment = 0;
var percent_delivered = 0;
// are we in the right system
if (m.destination === system.ID && m.destinationName === system.name) {
if (clock.adjustedSeconds <= m.deadline) {
var onhand = 0;
onhand += sdm.$getTotalUnlabelled(m.commodity); // add any cargo currently hiding under a relabel
onhand += p.manifest[m.commodity]; // add any visible cargo in the hold
onhand -= sdm.$getTotalRelabelled(m.commodity); // take away any cargo that might be masked by a label (ie. cargo that looks like the commodity but really isn't)
onhand += sc.$getCargoQuantity(m.commodity); // add any cargo in the smuggling compartment
onhand += sc.$checkHyperCargo(m.commodity); // add any cargo in hyper cargo
if (onhand >= m.size) {
errorCode = "success";
player.credits += m.fee;
this.$removeCargo(m.commodity, m.size);
player.setPlayerRole("trader-smuggler");
} else {
percent_delivered = 100.0 * (onhand / m.size);
var acceptable_ratio = 100.0 - 10.0 * system.ID / 256; // down to 90%
if (percent_delivered >= acceptable_ratio) {
var shortfall = 100 - percent_delivered;
new_payment = percent_delivered * (m.fee) / 100.0;
player.credits += new_payment;
errorCode = "short";
this.$removeCargo(m.commodity, m.size);
player.setPlayerRole("trader-smuggler");
} else {
errorCode = "refused_short";
}
}
} else {
errorCode = "late";
}
} else {
if (clock.adjustedSeconds > m.deadline) {
errorCode = "failed";
}
}
var desc = "";
// adjust the fee and reputation based on the result
switch (errorCode) {
case "success":
// build a contact
var contactHome = this.$rand(256) - 1;
var contact = "a " + System.infoForSystem(galaxyNumber, contactHome).inhabitant.toLowerCase() + " from " + System.systemNameForID(contactHome);
desc = expandDescription("[smuggled-cargo-delivered-okay]", {
cargo: this.$descriptionForGoods(m),
fee: formatCredits(m.fee, true, true),
contactdesc: contact
});
this.$increaseSmugglingReputation(10);
this.$contractCompletedEmail(errorCode, m.fee, m);
if (this.$anyContractsLeftForSystem(i, m.destination) === false)
mission.unmarkSystem({
system: m.destination,
name: "smuggling_contract_" + m.destination
});
break;
case "late":
desc = expandDescription("[smuggled-cargo-delivered-late]", {
cargo: this.$descriptionForGoods(m)
});
this.$decreaseSmugglingReputation(10);
this.$contractCompletedEmail(errorCode, 0, m);
if (this.$anyContractsLeftForSystem(i, m.destination) === false)
mission.unmarkSystem({
system: m.destination,
name: "smuggling_contract_" + m.destination
});
break;
case "failed":
desc = expandDescription("[smuggled-cargo-failed]", {
cargo: this.$descriptionForGoods(m)
});
this.$decreaseSmugglingReputation(10);
this.$contractCompletedEmail(errorCode, 0, m);
if (this.$anyContractsLeftForSystem(i, m.destination) === false)
mission.unmarkSystem({
system: m.destination,
name: "smuggling_contract_" + m.destination
});
break;
case "short":
desc = expandDescription("[smuggled-cargo-short]", {
cargo: this.$descriptionForGoods(m),
fee: formatCredits(new_payment, true, true),
percent: percent_delivered
});
this.$contractCompletedEmail(errorCode, new_payment, m);
if (this.$anyContractsLeftForSystem(i, m.destination) === false)
mission.unmarkSystem({
system: m.destination,
name: "smuggling_contract_" + m.destination
});
break;
case "refused_short":
desc = expandDescription("[smuggled-cargo-refused-short]", {
cargo: this.$descriptionForGoods(m)
});
// reset the error so we can skip this one - the player still has time to complete the contract
errorCode = "";
break;
}
if (desc != "") list.push(desc);
// if we got to this point with a result of some kind, remove the contract
if (errorCode != "") {
if (worldScripts.ContractsOnBB) {
worldScripts.ContractsOnBB.$removeSmugglingContract(i);
}
this._smugglingContracts.splice(i, 1);
}
}
if (list.length > 0) {
// add all contract summary items to the arrival report
var text = "";
for (var i = 0; i < list.length; i++) {
text += list[i] + "\n\n";
}
mission.runScreen({
title: "Smuggling Contracts",
message: text,
exitScreen: "GUI_SCREEN_STATUS"
});
}
}
//-------------------------------------------------------------------------------------------------------------
// removes a specific amount of the commodity, from various locations in this order:
// 1. relabelled commodities, 2. standard hold, 3. smuggling compartmnt, 4. hypercargo
// returns quantity not found (should be zero in most circumstances)
this.$removeCargo = function $removeCargo(commodity, amount) {
var se = worldScripts.Smugglers_Equipment;
var sdm = worldScripts.Smugglers_DockMaster;
var p = player.ship;
var sum = amount;
// is there any relabelled cargo?
if (sdm.$getTotalRelabelled(commodity) > 0) {
// unlabel the cargo so the next bit will pick it up
var relbl_remain = sdm.$removeRealCargoQuantity(commodity, sum);
}
// do we have the cargo anywhere? check normal hold
if (p.manifest[commodity] >= sum) {
p.manifest[commodity] -= sum;
sum = 0;
} else if (p.manifest[commodity] > 0) {
sum -= p.manifest[commodity];
p.manifest[commodity] = 0;
}
// smuggling compartment
if (sum > 0 && se.$getCargoQuantity(commodity) > 0) {
var remain = se.$removeCargo(commodity, sum);
sum = remain;
}
// and hypercargo
if (sum > 0 && se.$checkHyperCargo(commodity) > 0) {
var remain = se.$removeHyperCargo(commodity, sum);
sum = remain;
}
return sum;
}
//-------------------------------------------------------------------------------------------------------------
// resets HUD and jump destination
this.$resetViews = function $resetViews() {
if (this._suspendedHUD !== false) {
player.ship.hudHidden = false;
this._suspendedHUD = false;
}
if (this._suspendedDestination !== null) {
player.ship.targetSystem = this._suspendedDestination;
this._suspendedDestination = null;
}
}
//-------------------------------------------------------------------------------------------------------------
// initialise a new smuggling contract list for the current system
this.$initialiseSmugglingContractsForSystem = function $initialiseSmugglingContractsForSystem() {
// clear list
this._contracts = [];
var checklist = [];
var si = worldScripts.Smugglers_Illegal;
var destlist = [];
if (si._illegalGoods.length > 0) {
for (var i = 0; i < si._illegalGoods.length; i++) {
if (destlist.indexOf(si._illegalGoods[i].systemID) === -1)
destlist.push(si._illegalGoods[i].systemID);
}
} else {
// no illegal goods defined - shouldn't happen, but just in case
return;
}
var numContracts = Math.floor(5 * Math.random() + 5 * Math.random() + 5 * Math.random() + (this.$getSmugglingReputationPrecise() * Math.random()));
if (this.$getSmugglingReputationPrecise() >= 0 && numContracts < 5) {
numContracts += 5;
}
if (numContracts > 16) {
numContracts = 16;
} else if (numContracts < 0) {
numContracts = 0;
}
for (var i = 0; i < numContracts; i++) {
var cargo = new Object;
// pick a random system to take the goods to
var destination = destlist[this.$rand(destlist.length) - 1];
// discard if chose the current system
if (destination === system.ID) continue;
if (typeof destination === "undefined") continue;
// get the SystemInfo object for the destination
var destinationInfo = System.infoForSystem(galaxyNumber, destination);
if (destinationInfo.sun_gone_nova) continue;
var daysUntilDeparture = 1 + (Math.random() * (7 + this.$getSmugglingReputationPrecise() - destinationInfo.government));
if (daysUntilDeparture <= 0) {
// loses some more contracts if reputation negative
continue;
}
var commodities = si.$illegalGoodsListCommodityOnly(destination, true);
var attempts = 0;
do {
var remotePrice = 0;
attempts++;
var commodity = commodities[Math.floor(Math.random() * commodities.length)];
// sub-tc contracts only available for top rep
if (system.mainStation.market[commodity]["quantity_unit"] != 0 && this.$getSmugglingReputationPrecise() < 6.5) {
} else {
remotePrice = this.$priceForCommodity(commodity, destinationInfo);
}
//log(this.name, "contract " + i + "--attempt " + attempts + ": " + commodity + " remoteprice = " + remotePrice + ", sourcepriceadj = " + system.mainStation.market[commodity].price / 20);
} while (remotePrice < system.mainStation.market[commodity].price / 20 && attempts < 10);
// failed to find a good one.
if (attempts === 10) continue;
// don't overload the player with all the same type of contracts
var checkcount = 0;
for (var j = 0; j < checklist.length; j++) {
if (checklist[j] === commodity) checkcount += 1;
}
if (checkcount >= 3) continue;
cargo.commodity = commodity;
var amount = 0;
// larger unit sizes for kg/g commodities
switch (parseInt(system.mainStation.market[commodity]["quantity_unit"])) {
case 1:
amount = this.$rand(20) + 10;
break;
case 2:
amount = this.$rand(40) + 20;
break;
case 0:
amount = this.$rand(10);
if (amount > 5 && Math.random() > 0.5) amount += (this.$rand(5) - 3);
break;
}
cargo.size = amount;
// adjustment to prices based on quantity (larger = more profitable)
var discount = Math.min(10 + Math.floor(amount / 10), 35);
var unitPrice = system.mainStation.market[commodity].price * (100 - discount) / 1000;
var localValue = Math.floor(unitPrice * amount);
remotePrice = remotePrice * (200 + discount) / 200;
var remoteValue = Math.floor(remotePrice * amount);
var profit = remoteValue - localValue;
// skip if unprofitable
if (profit <= 100) continue;
// check that a route to the destination exists
// route calculation is expensive so leave this check to last
var routeToDestination = system.info.routeToSystem(destinationInfo);
// if the system cannot be reached, ignore this contract
if (!routeToDestination) continue;
// we now have a valid destination, so generate the rest of
// the parcel details
cargo.destination = destination;
// we'll need this again later, and route calculation is slow
cargo.route = routeToDestination;
// higher share for transporter for longer routes, less safe systems
var share = 100 + destinationInfo.government - (10 * routeToDestination.route.length);
if (share < 10) share = 10;
share = 100 - share;
// safety: now multiply the fee by 2 compared with 1.76 contracts
// prevents exploit discovered by Mad Hollander at
// http://aegidian.org/bb/viewtopic.php?p=188127
localValue *= 2;
// this may need to be raised further
// absolute value of profit remains the same
var fee = (localValue + Math.floor(profit * (share / 100))) * 2;
fee -= fee % 20; // round to nearest 20 credits;
cargo.payment = fee;
cargo.deposit = localValue - (localValue % 20);
// rare but not impossible; last safety check
if (cargo.deposit >= cargo.payment) continue;
// time allowed for delivery is time taken by "fewest jumps"
// route, plus timer above. Higher reputation makes longer
// times available.
cargo.deadline = clock.adjustedSeconds + Math.floor(daysUntilDeparture * 86400) + (cargo.route.time * 3600);
// make sure the illegal good will be illegal when the player arrives, based on the route time
var def = si.$illegalGoodsDefinition(destination, commodity);
if (def && def.end < cargo.deadline) continue;
// add it to the check list so we can make sure we don't offer too many of the same type of contract
checklist.push(commodity);
// add parcel to contract list
this.$addSmugglingContractToSystem(cargo);
}
}
//-------------------------------------------------------------------------------------------------------------
// if the interface is activated, this function is run.
this.$smugglingContractsScreens = function $smugglingContractsScreens(interfaceKey) {
// the interfaceKey parameter is not used here, but would be useful if
// this callback managed more than one interface entry
this.$validateSmugglingContracts();
// set up variables used to remember state on the mission screens
this._suspendedDestination = null;
this._suspendedHUD = false;
this._contractIndex = 0;
this._routeMode = "LONG_RANGE_CHART_SHORTEST";
this._lastOptionChosen = "06_EXIT";
// start on the summary page if more than one contract is available
var summary = (this._contracts.length > 1);
this.$smugglingContractsDisplay(summary);
}
//-------------------------------------------------------------------------------------------------------------
// this function is called after the player makes a choice which keeps
// them in the system, and also on initial entry to the system
// to select the appropriate mission screen and display it
this.$smugglingContractsDisplay = function $smugglingContractsDisplay(summary) {
// Again. Has to be done on every call to this function, but also
// has to be done at the start.
this.$validateSmugglingContracts();
// if there are no contracts (usually because the player has taken
// the last one) display a message and quit.
if (this._contracts.length === 0) {
var missionConfig = {
titleKey: "smuggling-contracts-none-available-title",
messageKey: "smuggling-contracts-none-available-message",
allowInterrupt: true,
screenID: "oolite-smuggling-contracts-none",
exitScreen: "GUI_SCREEN_INTERFACES"
};
if (this._smugglingSummaryPageBackground != "") {
missionConfig.background = this._smugglingSummaryPageBackground;
}
if (this._smugglingPageOverlay != "") {
if (this._smugglingPageOverlayHeight != 0) {
missionConfig.overlay = {
name: this._smugglingPageOverlay,
height: this._smugglingPageOverlayHeight
};
} else {
missionConfig.overlay = this._smugglingPageOverlay;
}
}
mission.runScreen(missionConfig);
// no callback, just exits contracts system
return;
}
// make sure that the 'currently selected contract' pointer
// is in bounds
if (this._contractIndex >= this._contracts.length) {
this._contractIndex = 0;
} else if (this._contractIndex < 0) {
this._contractIndex = this._contracts.length - 1;
}
// sub functions display either summary or detail screens
if (summary) {
this.$smugglingContractSummaryPage();
} else {
this.$smugglingContractSinglePage();
}
}
//-------------------------------------------------------------------------------------------------------------
// display the mission screen for the summary page
this.$smugglingContractSummaryPage = function $smugglingContractSummaryPage() {
var playerrep = this._helper._playerSkill(this.$getSmugglingReputationPrecise());
// column 'tab stops'
var columns = [9, 15, 21, 26];
var anyWithSpace = false;
// column header line
var headline = expandMissionText("smuggling-contracts-column-goods");
// pad to correct length to give a table-like layout
headline += this._helper._paddingText(headline, columns[0]);
headline += expandMissionText("smuggling-contracts-column-destination");
headline += this._helper._paddingText(headline, columns[1]);
headline += expandMissionText("smuggling-contracts-column-within");
headline += this._helper._paddingText(headline, columns[2]);
headline += expandMissionText("smuggling-contracts-column-deposit");
headline += this._helper._paddingText(headline, columns[3]);
headline += expandMissionText("smuggling-contracts-column-fee");
// required because of way choices are displayed.
headline = " " + headline;
// setting options dynamically; one contract per line
var options = new Object;
var i;
for (i = 0; i < this._contracts.length; i++) {
// temp variable to simplify following code
var cargo = this._contracts[i];
// write the description, padded to line up with the headers
var optionText = this.$descriptionForGoods(cargo);
optionText += this._helper._paddingText(optionText, columns[0]);
optionText += System.infoForSystem(galaxyNumber, cargo.destination).name;
optionText += this._helper._paddingText(optionText, columns[1]);
optionText += this._helper._timeRemaining(cargo);
optionText += this._helper._paddingText(optionText, columns[2]);
// right-align the fee so that the credits signs line up
var priceText = formatCredits(cargo.deposit, false, true);
priceText = this._helper._paddingText(priceText, 3.5) + priceText;
optionText += priceText
optionText += this._helper._paddingText(optionText, columns[3]);
// right-align the fee so that the credits signs line up
priceText = formatCredits(cargo.payment - cargo.deposit, false, true);
priceText = this._helper._paddingText(priceText, 3.5) + priceText;
optionText += priceText
// need to pad the number in the key to maintain alphabetical order
var istr = i;
if (i < 10) {
istr = "0" + i;
}
// needs to be aligned left to line up with the heading
options["01_CONTRACT_" + istr] = {
text: optionText,
alignment: "LEFT"
};
// check if there's space for this contract
if (!this.$hasSpaceFor(cargo)) {
options["01_CONTRACT_" + istr].color = "darkGrayColor";
} else {
anyWithSpace = true;
// if there doesn't appear to be sufficient time remaining
if (this._helper._timeRemainingSeconds(cargo) < this._helper._timeEstimateSeconds(cargo)) {
options["01_CONTRACT_" + istr].color = "orangeColor";
}
}
}
// if we've come from the detail screen, make sure the last
// contract shown there is selected here
var icstr = this._contractIndex;
if (icstr < 10) icstr = "0" + this._contractIndex;
var initialChoice = "01_CONTRACT_" + icstr;
// if none of them have any space...
if (!anyWithSpace) initialChoice = "06_EXIT";
// next, an empty string gives an unselectable row
options["02_SPACER"] = "";
// now need to add further spacing to fill the remaining rows, or
// the options will end up at the bottom of the screen.
var rowsToFill = 21;
if (player.ship.hudHidden || this.$isBigGuiActive() === true) rowsToFill = 27;
for (i = 4 + this._contracts.length; i < rowsToFill; i++) {
// each key needs to be unique at this stage.
options["07_SPACER_" + i] = "";
}
// numbered 06 to match the option of the same function in the other branch
options["06_EXIT"] = expandMissionText("smuggling-contracts-command-quit");
var missionConfig = {
titleKey: "smuggling-contracts-title-summary",
message: headline,
allowInterrupt: true,
screenID: "oolite-smuggling-contracts-summary",
exitScreen: "GUI_SCREEN_INTERFACES",
choices: options,
initialChoicesKey: initialChoice
};
if (this._smugglingSummaryPageBackground != "") {
missionConfig.background = this._smugglingSummaryPageBackground;
}
if (this._smugglingPageOverlay != "") {
if (this._smugglingPageOverlayHeight != 0) {
missionConfig.overlay = {
name: this._smugglingPageOverlay,
height: this._smugglingPageOverlayHeight
};
} else {
missionConfig.overlay = this._smugglingPageOverlay;
}
}
// now run the mission screen
mission.runScreen(missionConfig, this.$processSmugglingChoice, this);
}
//-------------------------------------------------------------------------------------------------------------
// display the mission screen for the contract detail page
this.$smugglingContractSinglePage = function $smugglingContractSinglePage() {
var playerrep = this._helper._playerSkill(this.$getSmugglingReputationPrecise());
// temp variable to simplify code
var cargo = this._contracts[this._contractIndex];
// This mission screen uses the long range chart as a backdrop.
// This means that the first 18 lines are taken up by the chart,
// and we can't put text there without overwriting the chart.
// We therefore need to hide the player's HUD, to get the full 27
// lines.
if (!player.ship.hudHidden && this.$isBigGuiActive() === false) {
this._suspendedHUD = true; // note that we hid it, for later
player.ship.hudHidden = true;
}
// We also set the player's witchspace destination temporarily
// so we need to store the old one in a variable to reset it later
this._suspendedDestination = player.ship.targetSystem;
// That done, we can set the player's destination so the map looks
// right.
player.ship.targetSystem = cargo.destination;
// start with 18 blank lines, since we don't want to overlap the chart
var message = new Array(18).join("\n");
message += expandMissionText("smuggling-contracts-long-description", {
"smuggling-contracts-longdesc-goods": this.$descriptionForGoods(cargo),
"smuggling-contracts-longdesc-destination": this._helper._systemName(cargo.destination),
"smuggling-contracts-longdesc-deadline": this._helper._timeRemaining(cargo),
"smuggling-contracts-longdesc-time": this._helper._timeEstimate(cargo),
"smuggling-contracts-longdesc-payment": formatCredits(cargo.payment, false, true),
"smuggling-contracts-longdesc-deposit": formatCredits(cargo.deposit, false, true)
});
// use a special background
var backgroundSpecial = "LONG_RANGE_CHART";
// the available options will vary quite a bit, so this rather
// than a choicesKey in missiontext.plist
var options = new Object;
// this is the only option which is always available
options["06_EXIT"] = expandMissionText("smuggling-contracts-command-quit");
// if the player has sufficient space
if (this.$hasSpaceFor(cargo)) {
options["05_ACCEPT"] = {
text: expandMissionText("smuggling-contracts-command-accept")
};
// if there's not much time left, change the option colour as a warning!
if (this._helper._timeRemainingSeconds(cargo) < this._helper._timeEstimateSeconds(cargo)) {
options["05_ACCEPT"].color = "orangeColor";
}
} else {
options["05_UNAVAILABLE"] = {
text: expandMissionText("smuggling-contracts-command-unavailable"),
color: "darkGrayColor",
unselectable: true
};
}
// if the ship has a working advanced nav array, can switch
// between 'quickest' and 'shortest' routes
// (and also upgrade the special background)
if (player.ship.hasEquipmentProviding("EQ_ADVANCED_NAVIGATIONAL_ARRAY")) {
backgroundSpecial = this._routeMode;
if (this._routeMode === "LONG_RANGE_CHART_SHORTEST") {
options["01_MODE"] = expandMissionText("smuggling-contracts-command-ana-quickest");
} else {
options["01_MODE"] = expandMissionText("smuggling-contracts-command-ana-shortest");
}
}
// if there's more than one, need options for forward, back, and listing
if (this._contracts.length > 1) {
options["02_BACK"] = expandMissionText("smuggling-contracts-command-back");
options["03_NEXT"] = expandMissionText("smuggling-contracts-command-next");
options["04_LIST"] = expandMissionText("smuggling-contracts-command-list");
} else {
// if not, we may need to set a different choice
// we never want 05_ACCEPT to end up selected initially
if (this._lastChoice === "02_BACK" || this._lastChoice === "03_NEXT" || this._lastChoice === "04_LIST") {
this._lastChoice = "06_EXIT";
}
}
var title = expandMissionText("smuggling-contracts-title-detail", {
"smuggling-contracts-title-detail-number": this._contractIndex + 1,
"smuggling-contracts-title-detail-total": this._contracts.length
});
// finally, after all that setup, actually create the mission screen
var missionConfig = {
title: title,
message: message,
allowInterrupt: true,
screenID: "oolite-smuggling-contracts-details",
exitScreen: "GUI_SCREEN_INTERFACES",
backgroundSpecial: backgroundSpecial,
choices: options,
initialChoicesKey: this._lastChoice
};
if (this._smugglingPageOverlay != "") {
if (this._smugglingPageOverlayHeight != 0) {
missionConfig.overlay = {
name: this._smugglingPageOverlay,
height: this._smugglingPageOverlayHeight
};
} else {
missionConfig.overlay = this._smugglingPageOverlay;
}
}
mission.runScreen(missionConfig, this.$processSmugglingChoice, this);
}
//-------------------------------------------------------------------------------------------------------------
this.$processSmugglingChoice = function $processSmugglingChoice(choice) {
this.$resetViews();
// can occur if ship launches mid mission screen
if (choice == null) return;
// now process the various choices
if (choice.match(/^01_CONTRACT_/)) {
// contract selected from summary page
// set the index to that contract, and show details
var index = parseInt(choice.slice(12), 10);
this._contractIndex = index;
this._lastChoice = "04_LIST";
this.$smugglingContractsDisplay(false);
} else if (choice === "01_MODE") {
// advanced navigation array mode flip
this._routeMode = (this._routeMode === "LONG_RANGE_CHART_SHORTEST") ? "LONG_RANGE_CHART_QUICKEST" : "LONG_RANGE_CHART_SHORTEST";
this._lastChoice = "01_MODE";
this.$smugglingContractsDisplay(false);
} else if (choice === "02_BACK") {
// reduce contract index (parcelContractsDisplay manages wraparound)
this._contractIndex--;
this._lastChoice = "02_BACK";
this.$smugglingContractsDisplay(false);
} else if (choice === "03_NEXT") {
// increase contract index (parcelContractsDisplay manages wraparound)
this._contractIndex++;
this._lastChoice = "03_NEXT";
this.$smugglingContractsDisplay(false);
} else if (choice === "04_LIST") {
// display the summary page
this.$smugglingContractsDisplay(true);
} else if (choice === "05_ACCEPT") {
this.$acceptContract();
// do not leave the setting as accept for the next contract!
this._lastChoice = "03_NEXT";
this.$smugglingContractsDisplay(false);
}
// if we get this far without having called smugglingContractsDisplay
// that means either 'exit' or an unrecognised option was chosen
if (choice === "06_EXIT") {
var sbm = worldScripts.Smugglers_BlackMarket;
sbm.$initialBlackMarket();
}
}
//-------------------------------------------------------------------------------------------------------------
// move goods from the contracts list to the player's ship (if possible)
this.$acceptContract = function $acceptContract() {
var cargo = this._contracts[this._contractIndex];
if (cargo.deposit > player.credits) {
this._helper._soundFailure();
return;
}
// give the cargo to the player
var result = this.$awardContract(cargo.size, cargo.commodity, system.ID, cargo.destination, cargo.deadline, cargo.payment, cargo.deposit, cargo.route);
if (result) {
// pay the deposit
player.credits -= cargo.deposit;
// give the player the merchandise
player.ship.manifest[cargo.commodity] += cargo.size;
mission.markSystem({
system: cargo.destination,
name: "smuggling_contract_" + cargo.destination,
markerShape: "MARKER_PLUS"
});
// remove the contract from the station list
this._contracts.splice(this._contractIndex, 1);
this._helper._soundSuccess();
} else {
// else must have had manifest change recently
// (unlikely, but another OXP could have done it)
this._helper._soundFailure();
}
}
//-------------------------------------------------------------------------------------------------------------
// store the contract
this.$awardContract = function $awardContract(quantity, commodity, source, destination, deadline, payment, deposit, route) {
var cargo = {};
cargo.size = quantity;
cargo.commodity = commodity;
cargo.start = source;
cargo.startName = System.systemNameForID(source);
cargo.destination = destination;
cargo.destinationName = System.systemNameForID(destination);
cargo.deadline = deadline;
cargo.fee = payment;
cargo.premium = deposit;
cargo.route = route;
this._smugglingContracts.push(cargo);
this.$contractStartedEmail(cargo);
return true;
}
//-------------------------------------------------------------------------------------------------------------
// removes any expired parcels
this.$validateSmugglingContracts = function $validateSmugglingContracts() {
var c = this._contracts.length - 1;
var removed = false;
// iterate downwards so we can safely remove as we go
for (var i = c; i >= 0; i--) {
// if the time remaining is less than 1/3 of the estimated
// delivery time, even in the best case it's probably not
// going to get there.
if (this._helper._timeRemainingSeconds(this._contracts[i]) < this._helper._timeEstimateSeconds(this._contracts[i]) / 3) {
if (worldScripts.ContractsOnBB) {
worldScripts.ContractsOnBB.$reindexContracts(34000, i);
}
// remove it
this._contracts.splice(i, 1);
removed = true;
}
}
}
//=============================================================================================================
/* Utility functions */
//-------------------------------------------------------------------------------------------------------------
// lower-cases the initial letter of the package contents
this.$formatPackageName = function $formatPackageName(name) {
return name.charAt(0).toLowerCase() + name.slice(1);
}
//-------------------------------------------------------------------------------------------------------------
// calculates a sample price for a commodity in a distant system
this.$priceForCommodity = function $priceForCommodity(commodity, systeminfo) {
//sample price returns decicredits, need credits
var si = worldScripts.Smugglers_Illegal;
var goods = si.$illegalGoodsListCommodityOnly(systeminfo.systemID);
if (goods.indexOf(commodity) >= 0) {
//return Math.round((si._commodityInfo[commodity][1] - (Math.random() * 15)), 2)
return (systeminfo.samplePrice(commodity) * si._commodityInfo[commodity][1]) / 10;
} else {
return systeminfo.samplePrice(commodity) / 10;
}
}
//-------------------------------------------------------------------------------------------------------------
// description of the cargo
this.$descriptionForGoods = function $descriptionForGoods(cargo) {
var unit = "tons";
var stn = system.mainStation;
if (!stn && system.stations.length > 0) stn = system.stations[0];
if (!stn) return "";
if (stn.market[cargo.commodity]["quantity_unit"] === "1") {
unit = "kilograms";
} else if (stn.market[cargo.commodity]["quantity_unit"] === "2") {
unit = "grams";
}
return cargo.size + expandDescription("[cargo-" + unit + "-symbol]") + " " + displayNameForCommodity(cargo.commodity);
}
//-------------------------------------------------------------------------------------------------------------
// check if player's ship has space for the cargo and can afford the deposit
this.$hasSpaceFor = function $hasSpaceFor(cargo) {
if (cargo.deposit > player.credits) {
return false;
}
var amountInTC = cargo.size;
if (system.mainStation.market[cargo.commodity]["quantity_unit"] === "1") {
var spareSafe = 499 - (player.ship.manifest[cargo.commodity] % 1000);
amountInTC -= spareSafe;
amountInTC = Math.ceil(amountInTC / 1000);
if (amountInTC < 0) {
amountInTC = 0;
}
} else if (system.mainStation.market[cargo.commodity]["quantity_unit"] === "2") {
var spareSafe = 499999 - (player.ship.manifest[cargo.commodity] % 1000000);
amountInTC -= spareSafe;
amountInTC = Math.ceil(amountInTC / 1000000);
if (amountInTC < 0) {
amountInTC = 0;
}
}
return (amountInTC <= player.ship.cargoSpaceAvailable);
}
//-------------------------------------------------------------------------------------------------------------
// returns true if another contracts exists for the given system ID, otherwise false
this.$anyContractsLeftForSystem = function $anyContractsLeftForSystem(idx_ignore, sysID) {
for (var i = 0; i < this._smugglingContracts.length; i++) {
if (i != idx_ignore && this._smugglingContracts[i].destination === sysID) return true;
}
return false;
}
//-------------------------------------------------------------------------------------------------------------
// update the manifest screen with any contracts
this.$updateManifest = function $updateManifest() {
// don't try an update in interstellar space
if (system.isInterstellarSpace) return;
if (this._smugglingContracts.length > 0) {
var list = [];
list.push("Smuggling Contracts:");
for (var i = 0; i < this._smugglingContracts.length; i++) {
var cargo = this._smugglingContracts[i];
var message = expandMissionText("smuggling-contracts-long-descr-manifest", {
"smuggling-contracts-longdesc-goods": this.$descriptionForGoods(cargo),
"smuggling-contracts-longdesc-destination": cargo.destinationName,
"smuggling-contracts-longdesc-deadline": this.$formatTravelTime(this._helper._timeRemainingSeconds(cargo)),
"smuggling-contracts-longdesc-time": this._helper._timeEstimate(cargo),
"smuggling-contracts-longdesc-payment": formatCredits(cargo.fee, false, true),
"smuggling-contracts-longdesc-deposit": formatCredits(cargo.deposit, false, true)
});
list.push(message);
}
mission.setInstructions(list, this.name);
} else {
mission.setInstructions(null, this.name);
}
}
//=============================================================================================================
// Smuggling reputation functions
// essentially a JS recreation of the same rep functions in core code to give the player a separate reputation for smuggling
//-------------------------------------------------------------------------------------------------------------
this.$getSmugglingReputation = function $getSmugglingReputation() {
return parseInt(this.$smugglingReputation() / 10);
}
//-------------------------------------------------------------------------------------------------------------
this.$getSmugglingReputationPrecise = function $getSmugglingReputationPrecise() {
return this.$smugglingReputation() / 10;
}
//-------------------------------------------------------------------------------------------------------------
this.$smugglingReputation = function $smugglingReputation() {
var good = this._smugglingRepGood;
var bad = this._smugglingRepBad;
var unknown = this._smugglingRepUnknown;
if (unknown > 0) {
unknown = this._maxRep - (((2 * unknown) + (this._marketrnd % unknown)) / 3);
} else {
unknown = this._maxRep;
}
return (good + unknown - 3 * bad) / 2;
}
//-------------------------------------------------------------------------------------------------------------
this.$decreaseSmugglingReputation = function $decreaseSmugglingReputation(amount) {
var good = this._smugglingRepGood;
var bad = this._smugglingRepBad;
var unknown = this._smugglingRepUnknown;
for (var i = 0; i < amount; i++) {
if (good > 0) {
// shift a bean from good to bad
good--;
if (bad < this._maxRep) bad++;
} else {
// shift a bean from unknown to bad
if (unknown > 0) unknown--;
if (bad < this._maxRep) bad++;
}
}
this._smugglingRepGood = good;
this._smugglingRepBad = bad;
this._smugglingRepUnknown = unknown;
}
//-------------------------------------------------------------------------------------------------------------
this.$increaseSmugglingReputation = function $increaseSmugglingReputation(amount) {
var good = this._smugglingRepGood;
var bad = this._smugglignRepBad;
var unknown = this._smugglingRepUnknown;
for (var i = 0; i < amount; i++) {
if (bad > 0) {
// shift a bean from bad to unknown
bad--;
if (unknown < this._maxRep) unknown++;
} else {
// shift a bean from unknown to good
if (unknown > 0) unknown--;
if (good < this._maxRep) good++;
}
}
this._smugglingRepGood = good;
this._smugglingRepBad = bad;
this._smugglingRepUnknown = unknown;
}
//-------------------------------------------------------------------------------------------------------------
this.$erodeSmugglingReputation = function $erodeSmugglingReputation() {
var good = this._smugglingRepGood;
var bad = this._smugglingRepBad;
var unknown = this._smugglingRepUnknown;
if (unknown < this._maxRep) {
if (bad > 0) {
bad--;
} else {
if (good > 0) good--;
}
unknown++;
}
this._smugglingRepGood = good;
this._smugglingRepBad = bad;
this._smugglingRepUnknown = unknown;
}
//-------------------------------------------------------------------------------------------------------------
this.$normaliseSmugglingReputation = function $normaliseSmugglingReputation() {
var good = this._smugglingRepGood;
var bad = this._smugglingRepBad;
var unknown = this._smugglingRepUnknown;
var c = good + bad + unknown;
if (c === 0) {
unknown = this._maxRep;
} else if (c != this._maxRep) {
good = good * this._maxRep / c;
bad = bad * this._maxRep / c;
unknown = this._maxRep - good - bad;
}
this._smugglingRepGood = good;
this._smugglingRepBad = bad;
this._smugglingRepUnknown = unknown;
}
//-------------------------------------------------------------------------------------------------------------
// format the travel time
this.$formatTravelTime = function $formatTravelTime(seconds) {
// this function uses an hours-only format
// but provides enough information to use a days&hours format if
// oolite-contracts-time-format in missiontext.plist is overridden
// extra minutes are discarded
var hours = Math.floor(seconds / 3600);
var days = Math.floor(hours / 24);
var spareHours = hours % 24;
return expandMissionText("smuggling-time-format", {
"smuggling-time-format-hours": hours,
"smuggling-time-format-days": days,
"smuggling-time-format-spare-hours": spareHours
});
}
//-------------------------------------------------------------------------------------------------------------
// routine to zero out quantities of any illegal goods under contract
// so if the player arrives short, he can't just buy one, launch, redock and complete the contract
this.$adjustMarket = function $adjustMarket() {
var stn = system.mainStation;
if (stn) {
for (var i = this._smugglingContracts.length - 1; i >= 0; i--) {
var m = this._smugglingContracts[i];
// are we in the right system
if (m.destination === system.ID && m.destinationName === system.name) {
// set the market quantity to zero
stn.setMarketQuantity(m.commodity, 0);
}
}
}
}
//-------------------------------------------------------------------------------------------------------------
// send email to player when a contract is started. (1.81 only)
this.$contractStartedEmail = function $contractStartedEmail(contract) {
var w = worldScripts.EmailSystem;
if (!w) return;
var ga = worldScripts.GalCopAdminServices;
if (ga._disableContracts === true) return;
var msg = "";
var subj = "";
var sndr = "";
sndr = expandDescription("[smuggling-contract-sender]");
subj = "Accepted contract: " + this.$descriptionForGoods(contract);
msg = expandDescription("[smuggling-contract-start]", {
description: this.$descriptionForGoods(contract),
systemname: System.systemNameForID(contract.destination),
time: global.clock.clockStringForTime(contract.deadline),
fee: contract.fee.toFixed(2)
});
w.$createEmail({
sender: sndr,
subject: subj,
date: global.clock.seconds,
message: msg
});
}
//-------------------------------------------------------------------------------------------------------------
this.$contractCompletedEmail = function $contractCompletedEmail(result, fee, contract) {
var w = worldScripts.EmailSystem;
if (!w) return;
var ga = worldScripts.GalCopAdminServices;
if (ga._disableContracts === true) return;
var msg = "";
var subj = "";
var sndr = "";
sndr = expandDescription("[smuggling-contract-sender]");
msg = expandDescription("[smuggling-contract-" + result + "]", {
description: this.$descriptionForGoods(contract),
systemname: System.systemNameForID(contract.destination),
time: global.clock.clockStringForTime(contract.deadline),
fee: (fee / 10).toFixed(2)
});
subj = expandDescription("[smuggling-contract-" + result + "-subject]");
w.$createEmail({
sender: sndr,
subject: subj,
date: global.clock.seconds,
message: msg,
expiryDays: ga._defaultExpiryDays
});
} |
Scripts/smugglers_dockmaster.js |
"use strict";
this.name = "Smugglers_DockMaster";
this.author = "phkb";
this.description = "Looks after the Dock Master interface screen.";
this.licence = "CC BY-NC-SA 3.0";
this._disabled = false;
this._debug = true;
this._bribeChance = []; // holds the chance a each dock master can be bribed
this._cargoLabelled = []; // array of original commodity and quantities, and new labels
// {oldCommodity: name, newCommodity: name, quantity: number of tons relabelled
this._bribeAttempted = false;
this._dockMasterStartTime = 0;
this._dockMasterEndTime = 0;
this._noSwitch = []; // these commodities can't be relabelled - populated through the smugglers_equipment.startUpComplete function
this._display = 0;
this._milkRuns = [];
this._successfulBribes = [];
this._cargoAtLaunch = [];
this._bribeCount = [];
this._menuColor = "orangeColor";
this._itemColor = "yellowColor";
this._disabledColor = "darkGrayColor";
this._galJump = false;
this._destReleaseCount = 0;
this._flagged = [];
this._curPage = 0;
this._marker = {};
//-------------------------------------------------------------------------------------------------------------
this.startUpComplete = function () {
if (this._disabled) {
delete this.shipDockedWithStation;
delete this.shipLaunchedFromStation;
delete this.playerWillSaveGame;
delete this.shipExitedWitchspace;
delete this.playerEnteredNewGalaxy;
delete this.shipSpawned;
delete this.shipTakingDamage;
delete this.playerSoldCargo;
delete this.startUpComplete;
delete this.guiScreenChanged;
return;
}
// add a mission screen exception to Xenon UI
if (worldScripts.XenonUI) {
var wx = worldScripts.XenonUI;
wx.$addMissionScreenException("oolite-smuggling-dockmaster-milkrun");
}
// add a mission screen exception to Xenon Redux UI
if (worldScripts.XenonReduxUI) {
var wxr = worldScripts.XenonReduxUI;
wxr.$addMissionScreenException("oolite-smuggling-dockmaster-milkrun");
}
var core = worldScripts.Smugglers_CoreFunctions;
this.$padTextRight = core.$padTextRight;
this.$padTextLeft = core.$padTextLeft;
this.$isBigGuiActive = core.$isBigGuiActive;
this.$rand = core.$rand;
this.$getMilkRuns();
if (missionVariables.Smuggling_BribeChance) {
this._bribeChance = JSON.parse(missionVariables.Smuggling_BribeChance);
delete missionVariables.Smuggling_BribeChance;
} else {
this.$setupChance();
}
if (missionVariables.Smuggling_Relabels) {
this._cargoLabelled = JSON.parse(missionVariables.Smuggling_Relabels);
delete missionVariables.Smuggling_Relabels;
}
if (missionVariables.Smuggling_SuccessfulBribes) {
this._successfulBribes = JSON.parse(missionVariables.Smuggling_SuccessfulBribes);
delete missionVariables.Smuggling_SuccessfulBribes;
}
if (missionVariables.Smuggling_BribeAttempted) this._bribeAttemped = (missionVariables.Smuggling_BribeAttemped === 1 ? true : false);
if (missionVariables.Smuggling_DockMasterStartTime) {
this._dockMasterStartTime = missionVariables.Smuggling_DockMasterStartTime;
this._dockMasterEndTime = missionVariables.Smuggling_DockMasterEndTime;
} else {
this.$setDockMasterHours();
}
if (missionVariables.Smuggling_BribeCount) {
this._bribeCount = JSON.parse(missionVariables.Smuggling_BribeCount);
delete missionVariables.Smuggling_BribeCount;
} else {
this.$resetBribeCount();
}
if (missionVariables.Smuggling_DockMasterFlagged) {
this._flagged = JSON.parse(missionVariables.Smuggling_DockMasterFlagged);
delete missionVariables.Smuggling_DockMasterFlagged;
}
if (missionVariables.Smuggling_DockMasterUnlockCount) {
this._destReleaseCount = missionVariables.Smuggling_DockMasterUnlockCount;
delete missionVariables.Smuggling_DockMasterUnlockCount;
}
// set up the interface screen, if required
this.$initMainInterface(player.ship.dockedStation);
if (this._cargoLabelled.length > 0) {
this.$initUnlabelInterface(player.ship.dockedStation);
}
// upgraded features in v1.84
if (0 < oolite.compareVersion("1.84")) {
delete this.shipDumpedCargo;
} else {
delete this.shipSpawned;
}
}
//-------------------------------------------------------------------------------------------------------------
this.shipDockedWithStation = function (station) {
// set up dock master interface screen
this.$initMainInterface(station);
if (this._cargoLabelled.length > 0) {
this.$initUnlabelInterface(station);
}
}
//-------------------------------------------------------------------------------------------------------------
this.shipLaunchedFromStation = function (station) {
if (missionVariables.Smuggling_BribeChance) delete missionVariables.Smuggling_BribeChance;
if (missionVariables.Smuggling_Relabels) delete missionVariables.Smuggling_Relabels;
if (missionVariables.Smuggling_SuccessfulBribes) delete missionVariables.Smuggling_SuccessfulBribes;
if (missionVariables.Smuggling_BribeCount) delete missionVariables.Smuggling_BribeCount;
var p = player.ship;
var m = p.manifest.list;
this._cargoAtLaunch = [];
// grab a snapshot of the cargo for comparison later
for (var i = 0; i < m.length; i++) {
if (m[i].quantity > 0) this._cargoAtLaunch.push({
commodity: m[i].commodity,
quantity: m[i].quantity
});
}
}
//-------------------------------------------------------------------------------------------------------------
this.playerWillSaveGame = function () {
missionVariables.Smuggling_BribeChance = JSON.stringify(this._bribeChance);
missionVariables.Smuggling_Relabels = JSON.stringify(this._cargoLabelled);
missionVariables.Smuggling_SuccessfulBribes = JSON.stringify(this._successfulBribes);
missionVariables.Smuggling_BribeCount = JSON.stringify(this._bribeCount);
missionVariables.Smuggling_BribeAttempted = (this._bribeAttemped ? 1 : 0);
if (this._flagged.length > 0) {
missionVariables.Smuggling_DockMasterFlagged = JSON.stringify(this._flagged)
}
missionVariables.Smuggling_DockMasterUnlockCount = this._destReleaseCount;
}
//-------------------------------------------------------------------------------------------------------------
this.shipExitedWitchspace = function () {
this._bribeAttempted = false;
this._destReleaseCount = 0;
this._flagged = [];
this.$setDockMasterHours();
if (this._galJump === true) {
this._galJump = false;
this.$setupChance();
this.$getMilkRuns();
this.$resetBribeCount();
}
}
//-------------------------------------------------------------------------------------------------------------
this.playerEnteredNewGalaxy = function (galaxyNumber) {
this._successfulBribes = [];
this._galJump = true;
}
//-------------------------------------------------------------------------------------------------------------
this.shipSpawned = function (ship) {
// did the player just dump relabelled cargo?
// if so, reduce the count in the array
// and unlabel the dumped cargo
var p = player.ship;
if (p && ship && ship.isCargo && ship.position && p.position && p.position.distanceTo(ship) < 300) {
//gotcha
var total = this.$getTotalRelabelled(ship.commodity);
if (p.manifest[ship.commodity] < total) {
for (var i = 0; i < this._cargoLabelled.length; i++) {
// find the first matching relabelled commodity and adjust it
if (this._cargoLabelled[i].newCommodity === ship.commodity && this._cargoLabelled[i].quantity > 0) {
this._cargoLabelled[i].quantity -= ship.commodityAmount;
var check = ship.setCargo(this._cargoLabelled[i].oldCommodity);
break;
}
}
}
}
}
//-------------------------------------------------------------------------------------------------------------
this.shipDumpedCargo = function(cargo) {
var p = player.ship;
var total = this.$getTotalRelabelled(cargo.commodity);
if (p.manifest[cargo.commodity] < total) {
for (var i = 0; i < this._cargoLabelled.length; i++) {
// find the first matching relabelled commodity and adjust it
if (this._cargoLabelled[i].newCommodity === cargo.commodity && this._cargoLabelled[i].quantity > 0) {
this._cargoLabelled[i].quantity -= cargo.commodityAmount;
var check = ship.setCargo(this._cargoLabelled[i].oldCommodity);
break;
}
}
}
}
//-------------------------------------------------------------------------------------------------------------
this.shipTakingDamage = function (dmg_amount, whom, type) {
// work out if the any of the relabelled cargo was destroyed
// if so, reduce the count in the array
// basically, relabelled cargo should be destroyed first
var p = player.ship;
var se = worldScripts.Smugglers_Equipment;
for (var i = 0; i < se._commodityIDList.length; i++) {
var holdamt = p.manifest[se._commodityIDList[i]];
var origamt = this.$launchAmount(se._commodityIDList[i]);
var amount = this.$getTotalRelabelled(se._commodityIDList[i]);
if (holdamt < origamt && amount > 0) {
// how many units do we have to remove?
var to_remove = (origamt - holdamt);
// find the first instance of a relabelled cargo
for (var j = 0; j < this._cargoLabelled.length; j++) {
if (this._cargoLabelled[j].quantity > 0 && to_remove > 0) {
// reduce the cargo by the removed amount
this._cargoLabelled[j].quantity -= to_remove;
// if we've just gone negative, we've wiped out all of that cargo batch
if (this._cargoLabelled[j].quantity < 0) {
// pick up the remainder
to_remove = this._cargoLabelled[j].quantity * -1;
// reset this one back to zero
this._cargoLabelled[j].quantity = 0;
}
}
}
}
}
}
//-------------------------------------------------------------------------------------------------------------
// if we scoop cargo make sure it gets added to the at_launch list
this.shipScoopedOther = function (whom) {
var si = worldScripts.Smugglers_Illegal;
var check = 0;
if (si._commodityInfo[whom.commodity]) {
check = si._commodityInfo[whom.commodity][0];
if (check > 0) {
var origamt = this.$launchAmount(whom.commodity);
if (origamt > 0) {
for (var i = 0; i < this._cargoAtLaunch.length; i++) {
if (this._cargoAtLaunch[i].commodity === whom.commodity) this._cargoAtLaunch[i].quantity += whom.commodityAmount;
}
} else {
this._cargoAtLaunch.push({
commodity: whom.commodity,
quantity: whom.commodityAmount
});
}
}
}
}
//-------------------------------------------------------------------------------------------------------------
this.playerSoldCargo = function (commodity, units, price) {
// did the player just sell cargo that has been relabelled?
// if so, reverse the sale: add the relabelled units back, give the player their money back, and send a console message
var p = player.ship;
var relabelled_amount = this.$getTotalRelabelled(commodity);
if (relabelled_amount > 0 && p.manifest[commodity] < relabelled_amount) {
var goodunits = units - relabelled_amount;
if (units === 1) goodunits = 0;
var reclaimunits = units - goodunits;
p.manifest[commodity] = relabelled_amount;
p.dockedStation.setMarketQuantity(commodity, p.dockedStation.market[commodity].quantity - reclaimunits);
player.credits -= ((reclaimunits * price) / 10);
player.consoleMessage("Sale of relabelled cargo reversed");
}
}
//-------------------------------------------------------------------------------------------------------------
this.guiScreenChanged_hide = function (to, from) {
if (guiScreen === "GUI_SCREEN_INTERFACES") {
mission.unmarkSystem({
system: this._marker.id1,
name: this.name + "_mark1"
});
mission.unmarkSystem({
system: this._marker.id2,
name: this.name + "_mark2"
});
if (this._marker.id1 < this._marker.id2) {
SystemInfo.setInterstellarProperty(galaxyNumber, this._marker.id1, this._marker.id2, 2, "link_color", null);
} else {
SystemInfo.setInterstellarProperty(galaxyNumber, this._marker.id2, this._marker.id1, 2, "link_color", null);
}
this._marker = {};
delete this.guiScreenChanged;
}
}
//-------------------------------------------------------------------------------------------------------------
// returns the total number of units that have been relabelled to the passed commodity type
this.$getTotalRelabelled = function $getTotalRelabelled(commodity) {
var amount = 0;
for (var i = 0; i < this._cargoLabelled.length; i++) {
if (this._cargoLabelled[i].newCommodity === commodity) amount += this._cargoLabelled[i].quantity;
}
return amount;
}
//-------------------------------------------------------------------------------------------------------------
// returns the total number of units of the original commodity
this.$getTotalUnlabelled = function $getTotalUnlabelled(commodity) {
var amount = 0;
for (var i = 0; i < this._cargoLabelled.length; i++) {
if (this._cargoLabelled[i].oldCommodity === commodity) amount += this._cargoLabelled[i].quantity;
}
return amount;
}
//-------------------------------------------------------------------------------------------------------------
// returns the amount of a particular commodity we had at launch
this.$launchAmount = function $launchAmount(commodity) {
for (var i = 0; i < this._cargoAtLaunch.length; i++) {
if (this._cargoAtLaunch[i].commodity === commodity) return this._cargoAtLaunch[i].quantity;
}
return 0;
}
//-------------------------------------------------------------------------------------------------------------
// initialise the dock master F4 screen entries
this.$initMainInterface = function $initMainInterface(station) {
// no station? no interface
if (!station) return;
// not galcop aligned? no interface
if (station.allegiance != "galcop") return;
// did we get to the station when the dock master is on duty?
if (clock.hoursComponent < this._dockMasterStartTime || clock.hoursComponent > this._dockMasterEndTime) return;
if (this._bribeAttempted === false) {
station.setInterface(this.name + "dockmaster", {
title: "Dock master",
category: "Station Interfaces",
summary: "Talk to the dock master of the station",
callback: this.$initialDockMasterOptions.bind(this)
});
}
}
//-------------------------------------------------------------------------------------------------------------
// initialises the remove labelling interface screen
this.$initUnlabelInterface = function $initUnlabelInterface(station) {
station.setInterface(this.name + "unlabel", {
title: "Remove cargo relabelling",
category: "Ship Systems",
summary: "Removes fake manifest labelling applied to your cargo.",
callback: this.$removeLabellingList.bind(this)
});
}
//-------------------------------------------------------------------------------------------------------------
this.$initialDockMasterOptions = function $initialDockMasterOptions() {
this._display = 0;
this.$showDockMasterOptions();
}
//-------------------------------------------------------------------------------------------------------------
this.$showDockMasterOptions = function $showDockMasterOptions() {
var curChoices = {};
var text = "";
var p = player.ship;
var def = "";
var pagesize = 20;
if (this.$isBigGuiActive() === true) pagesize = 26;
if (this._display === 0) {
if (clock.hoursComponent < 12) text += "Good morning";
if (clock.hoursComponent >= 12 && clock.hoursComponent < 18) text += "Good afternoon";
if (clock.hoursComponent >= 18) text += "Good evening";
text += " " + expandDescription("[dockmaster-welcome]");
var itemcount = 1;
curChoices["01_MILKRUN"] = {
text: "[dockmaster-milkruns]",
color: this._menuColor
};
if (this._bribeAttempted === false && player.credits > 0 && this.$playerHasBribableCargo() === true) {
curChoices["02_BRIBE"] = {
text: "[dockmaster-bribe-cargo]",
color: this._menuColor
};
itemcount += 1;
}
if (worldScripts.BountySystem_MostWanted && worldScripts.StationDockControl && p.equipmentStatus("EQ_HUNTER_LICENCE") === "EQUIPMENT_OK" && this._destReleaseCount < 3 && this._flagged.length > 0) {
curChoices["05_HUNTER_REQ"] = {
text: "[dockmaster-release-dest]",
color: this._menuColor
};
itemcount += 1;
}
curChoices["98_SPACER"] = "";
itemcount += 1;
curChoices["99_EXIT"] = {
text: "Return",
color: this._itemColor
};
for (var i = 0; i < ((pagesize - 2) - itemcount); i++) {
curChoices["99_SPACER_" + i] = "";
}
def = "99_EXIT";
var opts = {
screenID: "oolite-smuggling-dockmaster-map",
title: "Dock Master",
allowInterrupt: true,
overlay: {
name: "stgu-chat.png",
height: 546
},
exitScreen: "GUI_SCREEN_INTERFACES",
choices: curChoices,
initialChoicesKey: def,
message: text
};
}
// milk runs
if (this._display === 1) {
text = expandDescription("[milkrun-apology]");
var found = false;
for (var i = this._milkRuns.length - 1; i >= 0; i--) {
var dist1 = System.infoForSystem(galaxyNumber, system.ID).distanceToSystem(System.infoForSystem(galaxyNumber, this._milkRuns[i].id1));
var dist2 = System.infoForSystem(galaxyNumber, system.ID).distanceToSystem(System.infoForSystem(galaxyNumber, this._milkRuns[i].id2));
if (dist1 < 15 || dist2 < 15) {
// found one
text = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + expandDescription("[milkrun]", {
system1: System.infoForSystem(galaxyNumber, this._milkRuns[i].id1).name,
system2: System.infoForSystem(galaxyNumber, this._milkRuns[i].id2).name
});
this._marker = this._milkRuns[i];
this.guiScreenChanged = this.guiScreenChanged_hide;
mission.markSystem({
system: this._milkRuns[i].id1,
name: this.name + "_mark1",
markerShape: "MARKER_SQUARE",
markerColor: "whiteColor",
markerScale: 1.5
});
mission.markSystem({
system: this._milkRuns[i].id2,
name: this.name + "_mark2",
markerShape: "MARKER_SQUARE",
markerColor: "whiteColor",
markerScale: 1.5
});
if (this._milkRuns[i].id1 < this._milkRuns[i].id2) {
SystemInfo.setInterstellarProperty(galaxyNumber, this._milkRuns[i].id1, this._milkRuns[i].id2, 2, "link_color", "whiteColor");
} else {
SystemInfo.setInterstellarProperty(galaxyNumber, this._milkRuns[i].id2, this._milkRuns[i].id1, 2, "link_color", "whiteColor");
}
found = true;
break;
}
}
if (found === false) {
var opts = {
screenID: "oolite-smuggling-dockmaster-map",
title: "Dock Master",
allowInterrupt: true,
overlay: {
name: "stgu-chat.png",
height: 546
},
exitScreen: "GUI_SCREEN_INTERFACES",
message: text
};
} else {
var opts = {
screenID: "oolite-smuggling-dockmaster-milkrun",
title: "Dock Master",
allowInterrupt: true,
backgroundSpecial: "LONG_RANGE_CHART",
exitScreen: "GUI_SCREEN_INTERFACES",
message: text
};
}
}
// display cargo to alter
if (this._display === 2) {
var cargo = p.manifest.list;
var itemcount = 0;
var list = [];
for (var i = 0; i < cargo.length; i++) {
// make sure we don't relabel relabelled cargo
var q = cargo[i].quantity;
if (this._cargoLabelled.length > 0) {
for (var j = 0; j < this._cargoLabelled.length; j++) {
if (this._cargoLabelled[j].newCommodity === cargo[i].commodity) q -= this._cargoLabelled[j].quantity;
}
}
// make sure we don't relabel New Cargoes
var cteCargo = worldScripts.Smugglers_Equipment.$calcCTEcargo(cargo[i].commodity);
if (cteCargo > 0) q -= cteCargo;
if (q > 0) {
if (this._noSwitch.indexOf(cargo[i].commodity) === -1) {
list.push({
menu: "50_" + (i < 10 ? "0" : "") + i + "_CARGO~" + cargo[i].commodity,
text: cargo[i].displayName + " (" + q + cargo[i].unit + ")",
color: this._menuColor
})
}
}
}
if (list.length >= pagesize) {
pagesize -= 4;
} else {
pagesize -= 2;
}
for (var i = 0; i < pagesize; i++) {
var ref = i + (this._curPage * pagesize);
if (ref < list.length) {
curChoices[list[ref].menu] = {
text: list[ref].text,
color: list[ref].color
};
itemcount += 1;
}
}
if (list.length > pagesize) {
if (this._curPage < Math.floor(list.length / pagesize)) {
curChoices["Z_NEXT"] = {
text: "Next page",
color: this._itemColor
};
} else {
curChoices["Z_NEXT"] = {
text: "Next page",
color: this._disabledColor,
unselectable: true
};
}
if (this._curPage > 0) {
curChoices["Z_PREV"] = {
text: "Previous page",
color: this._itemColor
};
} else {
curChoices["Z_PREV"] = {
text: "Previous page",
color: this._disabledColor,
unselectable: true
};
}
}
for (var i = 0; i < ((pagesize + 1) - itemcount); i++) {
curChoices["99_SPACER_" + i] = "";
}
var opts = {
screenID: "oolite-smuggling-dockmaster-map",
title: "Dock Master",
overlay: {
name: "stgu-chat.png",
height: 546
},
allowInterrupt: false,
exitScreen: "GUI_SCREEN_INTERFACES",
choices: curChoices,
messageKey: "cargo-relabel-accept"
};
}
// display options to switch to
if (this._display === 3) {
var se = worldScripts.Smugglers_Equipment;
text = expandMissionText("cargo-relabel-question", {
cargo: displayNameForCommodity(this._tfrCargo)
});
var itemcount = 0;
var list = [];
for (var i = 0; i < se._commodityIDList.length; i++) {
if (this._noSwitch.indexOf(se._commodityIDList[i]) === -1 && se._commodityIDList != this._tfrCargo) {
list.push({
menu: "40_" + (i < 10 ? "0" : "") + i + "~" + se._commodityIDList[i],
text: displayNameForCommodity(se._commodityIDList[i]),
color: this._menuColor
})
}
}
if (list.length >= pagesize) {
pagesize -= 4;
} else {
pagesize -= 2;
}
for (var i = 0; i < pagesize; i++) {
var ref = i + (this._curPage * pagesize);
if (ref < list.length) {
curChoices[list[ref].menu] = {
text: list[ref].text,
color: list[ref].color
};
itemcount += 1;
}
}
if (list.length > pagesize) {
if (this._curPage < Math.floor(list.length / pagesize)) {
curChoices["99_NEXT"] = {
text: "Next page",
color: this._itemColor
};
} else {
curChoices["99_NEXT"] = {
text: "Next page",
color: this._disabledColor,
unselectable: true
};
}
if (this._curPage > 0) {
curChoices["99_PREV"] = {
text: "Previous page",
color: this._itemColor
};
} else {
curChoices["99_PREV"] = {
text: "Previous page",
color: this._disabledColor,
unselectable: true
};
}
}
for (var i = 0; i < ((pagesize + 1) - itemcount); i++) {
curChoices["60_SPACER_" + i] = "";
}
var opts = {
screenID: "oolite-smuggling-dockmaster-map",
title: "Dock Master",
overlay: {
name: "stgu-chat.png",
height: 546
},
allowInterrupt: false,
exitScreen: "GUI_SCREEN_INTERFACES",
choices: curChoices,
message: text
};
}
// linking bounty most wanted and SDC
if (this._display === 4) {
// display list of flagged ships
text = "Which ship are you interested in seeing the destination for?";
var itemcount = 0;
for (var i = 0; i < this._flagged.length; i++) {
// if you don't have the dough, it won't let you go
// saves having to have another response screen saying "You don't have enough cash"
if (player.credits > parseInt(this._flagged[i].cost)) {
curChoices["01_FLAGGED~" + i] = {
text: this._flagged[i].text,
color: this._menuColor,
alignment: "LEFT"
};
} else {
curChoices["01_FLAGGED~" + i] = {
text: this._flagged[i].text,
color: this._disabledColor,
alignment: "LEFT",
unselectable: true
};
}
itemcount += 1;
}
curChoices["97_SPACER"] = "";
itemcount += 1;
curChoices["98_EXIT"] = {
text: "Return",
color: this._itemColor
};
for (var i = 0; i < ((pagesize - 2) - itemcount); i++) {
curChoices["97_SPACER_" + i] = "";
}
def = "98_EXIT";
var opts = {
screenID: "oolite-smuggling-dockmaster-map",
title: "Dock Master",
allowInterrupt: true,
overlay: {
name: "stgu-chat.png",
height: 546
},
exitScreen: "GUI_SCREEN_INTERFACES",
choices: curChoices,
initialChoicesKey: def,
message: text
};
}
// ship dest unlock successful
if (this._display === 5) {
text = "The destination of the ship has been unlocked. Good hunting, commander!";
curChoices["98A_EXIT"] = {
text: "Return",
color: this._itemColor
};
def = "98A_EXIT";
var opts = {
screenID: "oolite-smuggling-dockmaster-map",
title: "Dock Master",
allowInterrupt: true,
overlay: {
name: "stgu-chat.png",
height: 546
},
exitScreen: "GUI_SCREEN_INTERFACES",
choices: curChoices,
initialChoicesKey: def,
message: text
};
}
// ship dest unlock unsuccessful
if (this._display === 6) {
text = "I'm not sure what's happened, but I can't find that ship in the dock list. It may have already launched.";
curChoices["98A_EXIT"] = {
text: "Return",
color: this._itemColor
};
def = "98A_EXIT";
var opts = {
screenID: "oolite-smuggling-dockmaster-map",
title: "Dock Master",
allowInterrupt: true,
overlay: {
name: "stgu-chat.png",
height: 546
},
exitScreen: "GUI_SCREEN_INTERFACES",
choices: curChoices,
initialChoicesKey: def,
message: text
};
}
mission.runScreen(opts, this.$screenHandler, this);
}
//-------------------------------------------------------------------------------------------------------------
this.$screenHandler = function $screenHandler(choice) {
if (choice == null) return;
switch (choice) {
case "01_MILKRUN":
this._display = 1;
break;
case "02_BRIBE":
this.$getBribeAmount("manifest");
return;
case "05_HUNTER_REQ":
this._display = 4;
break;
case "98_EXIT":
this._display = 1;
break;
case "98A_EXIT":
this._display = 0;
break;
case "99_NEXT":
this._curPage += 1;
break;
case "99_PREV":
this._curPage -= 1;
break;
}
if (choice.indexOf("01_FLAGGED") >= 0) {
var idx = parseInt(choice.substring(choice.indexOf("~") + 1));
var ref = parseInt(this._flagged[idx].index);
var shpRef = parseInt(this._flagged[idx].shipIndex);
var cost = parseInt(this._flagged[idx].cost);
var mw = worldScripts.BountySystem_MostWanted;
var found = false;
for (var i = 0; i < mw._wanted.length; i++) {
if (mw._wanted[i].index === ref) {
var sdci = worldScripts.StationDockControl_Interface;
var item = sdci._viewing[shpRef];
if (item.pilotName === mw._wanted[i].pilotName) {
player.credits -= cost;
player.consoleMessage("You have been charged " + formatCredits(cost, false, true));
item.destinationHidden = false;
this._destReleaseCount += 1;
this._flagged.splice(idx, 1);
found = true;
this._display = 5;
}
}
}
if (found === false) {
this._display = 6;
}
}
if (choice.indexOf("50_") >= 0) {
this._tfrCargo = choice.substring(choice.indexOf("~") + 1);
this._display = 3;
this._curPage = 0;
}
if (choice.indexOf("40_") >= 0) {
var newCmdty = choice.substring(choice.indexOf("~") + 1);
var p = player.ship;
var amount = p.manifest[this._tfrCargo];
// if we already have relabelled the selected cargo, get the un-relabelled portion of it
for (var i = 0; i < this._cargoLabelled.length; i++) {
if (this._cargoLabelled[i].newCommodity === this._tfrCargo) amount -= this._cargoLabelled[i].quantity;
}
// do we already have some relabelled cargo of the same type (matching old and new
var found = false;
for (var i = 0; i < this._cargoLabelled.length; i++) {
if (this._cargoLabelled[i].newCommodity === newCmdty && this._cargoLabelled[i].oldCommodity === this._tfrCargo) {
this._cargoLabelled[i].quantity += amount
found = true;
}
}
if (found === false) this._cargoLabelled.push({
oldCommodity: this._tfrCargo,
newCommodity: newCmdty,
quantity: amount
});
p.manifest[this._tfrCargo] -= amount;
p.manifest[newCmdty] += amount;
this.$initUnlabelInterface(p.dockedStation);
var extramsg = "";
var se = worldScripts.Smugglers_Equipment;
if (se.$hasSmugglingCompartment() === true) extramsg = expandMissionText("cargo-relabel-reminder");
mission.runScreen({
screenID: "oolite-smuggling-dockmaster-map",
title: "Dock Master",
overlay: {
name: "stgu-chat.png",
height: 546
},
message: expandDescription("[dockmaster-complete]") + extramsg,
exitScreen: "GUI_SCREEN_INTERFACES"
});
p.dockedStation.setInterface(this.name + "dockmaster", null);
}
if (choice != "99_EXIT" && choice.indexOf("40_") === -1) {
this.$showDockMasterOptions();
}
}
//-------------------------------------------------------------------------------------------------------------
// prompts the user for a new phase
this.$getBribeAmount = function $getBribeAmount(type) {
var text = "";
this._bribeAttempted = true;
var inttype = Math.floor((this._bribeChance[system.ID] * 4) + 1);
var inttypedesc = expandDescription("[interest-type" + inttype + "]");
var lastBribe = this.$previousBribeAmount();
if (type === "manifest") {
text = expandDescription("[dockmaster-question]", {
interesttype: inttypedesc
}) + "\n\n" +
"(" + expandDescription("[dockmaster-cost]", {
credits: formatCredits(player.credits, false, true)
}) +
(lastBribe > 0 ? expandDescription("[dockmaster-lastbribe]", {
bribeamount: formatCredits(lastBribe, false, true)
}) : "") + ")";
} else {
text = "So you want the keys to my kingdom, eh? That's a pretty serious offence. " + expandDescription("[dockmaster-question]", {
interesttype: inttypedesc
}) + "\n\n" +
"(" + expandDescription("[dockmaster-cost]", {
credits: formatCredits(player.credits, false, true)
})
}
var opts = {
screenID: "oolite-smuggling-dockmaster-map",
title: "Dock Master",
allowInterrupt: false,
overlay: {
name: "stgu-chat.png",
height: 546
},
exitScreen: "GUI_SCREEN_INTERFACES",
message: text,
textEntry: true
};
mission.runScreen(opts, this.$getBribeAmountInputManifest, this);
}
//-------------------------------------------------------------------------------------------------------------
// parses the input from the getBribeAmount screen
this.$getBribeAmountInputManifest = function $getBribeAmountInputManifest(param) {
var p = player.ship;
if (parseInt(param) >= 1 && parseInt(param) <= player.credits) {
var amount = parseInt(param);
// will this work
var chance = this._bribeChance[system.ID];
// higher amounts are more likely to be accepted
// chance of 0.5 would mean you would need to offer them 1690 credits
//if (this._debug) log(this.name, "min bribe amount = " + (Math.pow(parseInt(chance * 32), 1.8) * (1 + system.productivity / 56300) * this._bribeCount[system.ID]));
if ((Math.pow(parseInt(chance * 32), 1.8) * (1 + system.productivity / 56300) * this._bribeCount[system.ID]) <= amount) {
player.credits -= amount;
this._display = 2;
this._curPage = 0;
this.$addBribe(system.ID);
this._successfulBribes.push({
system: system.ID,
bribeAmount: amount
});
this.$showDockMasterOptions();
} else {
this._display = 0;
if (Math.random() > chance) {
mission.runScreen({
screenID: "oolite-smuggling-dockmaster-map",
title: "Dock Master",
overlay: {
name: "stgu-chat.png",
height: 546
},
message: expandDescription("[dockmaster-angry-nopenalty]"),
exitScreen: "GUI_SCREEN_INTERFACES"
});
} else {
var penalty = (this.$rand(10) + 3);
p.setBounty(player.bounty + penalty, "attempted bribe");
mission.runScreen({
screenID: "oolite-smuggling-dockmaster-map",
title: "Dock Master",
overlay: {
name: "stgu-chat.png",
height: 546
},
message: expandDescription("[dockmaster-angry-penalty]"),
exitScreen: "GUI_SCREEN_INTERFACES"
});
// send email (if installed)
var email = worldScripts.EmailSystem;
if (email) {
var ga = worldScripts.GalCopAdminServices;
email.$createEmail({
sender: "GalCop Customs",
subject: "Attempt to bribe official",
date: clock.seconds,
message: expandDescription("[smugglers-failed-bribe-email]", {
legal_penalty: penalty,
stationname: player.ship.dockedStation.displayName,
systemname: System.systemNameForID(system.ID)
}),
expiryDays: ga._defaultExpiryDays
});
}
}
p.dockedStation.setInterface(this.name + "dockmaster", null);
}
} else {
this._display = 0;
mission.runScreen({
screenID: "oolite-smuggling-dockmaster-map",
title: "Bribing Official",
overlay: {
name: "stgu-chat.png",
height: 546
},
message: expandDescription("[dockmaster-skipbribe]"),
exitScreen: "GUI_SCREEN_STATUS"
});
p.dockedStation.setInterface(this.name + "dockmaster", null);
}
}
//-------------------------------------------------------------------------------------------------------------
this.$removeLabellingList = function $removeLabellingList() {
var curChoices = {};
var se = worldScripts.Smugglers_Equipment;
var pagesize = 20;
if (this.$isBigGuiActive() === true) pagesize = 26;
for (var i = 0; i < this._cargoLabelled.length; i++) {
curChoices["01_CARGO~" + (i < 10 ? "0" : "") + i] = {
text: this._cargoLabelled[i].quantity + se.$getCommodityType(this._cargoLabelled[i].newCommodity) + " " + displayNameForCommodity(this._cargoLabelled[i].newCommodity) +
", back to " + displayNameForCommodity(this._cargoLabelled[i].oldCommodity),
color: this._menuColor
};
}
curChoices["98_SPACER_" + i] = "";
curChoices["99_EXIT"] = {
text: "Return",
color: this._itemColor
};
for (var i = 0; i < ((pagesize - 3) - this._cargoLabelled.length); i++) {
curChoices["99_SPACER_" + i] = "";
}
var def = "99_EXIT";
var opts = {
screenID: "oolite-smuggling-dockmaster-map",
title: "Remove Cargo Relabelling",
allowInterrupt: true,
overlay: {
name: "stgu-id.png",
height: 546
},
exitScreen: "GUI_SCREEN_INTERFACES",
choices: curChoices,
initialChoicesKey: def,
messageKey: "cargo-relabel-heading"
};
mission.runScreen(opts, this.$removeLabellingHandler, this);
}
//-------------------------------------------------------------------------------------------------------------
this.$removeLabellingHandler = function $removeLabellingHandler(choice) {
if (choice == null) return;
if (choice.indexOf("01_") >= 0) {
var idx = parseInt(choice.substring(choice.indexOf("~") + 1));
this.$removeLabelling(idx);
if (this._cargoLabelled.length > 0) this.$removeLabellingList();
}
}
//-------------------------------------------------------------------------------------------------------------
this.$removeLabelling = function $removeLabelling(idx) {
var p = player.ship;
// revert cargo back to original
// make sure we still have the right amount
if (p.manifest[this._cargoLabelled[idx].newCommodity] < this._cargoLabelled[idx].quantity)
this._cargoLabelled[idx].quantity = p.manifest[this._cargoLabelled[idx].newCommodity];
// deduct from the new commodity name
p.manifest[this._cargoLabelled[idx].newCommodity] -= this._cargoLabelled[idx].quantity;
// add to the old commodity name
p.manifest[this._cargoLabelled[idx].oldCommodity] += this._cargoLabelled[idx].quantity;
this._cargoLabelled.splice(idx, 1);
if (this._cargoLabelled.length === 0) {
p.dockedStation.setInterface(this.name + "unlabel", null);
}
}
//-------------------------------------------------------------------------------------------------------------
// sets up the chance a dock master can be bribed, for each of the main stations
this.$setupChance = function $setupChance() {
this._bribeChance = [];
for (var i = 0; i <= 255; i++) {
this._bribeChance.push(Math.random());
}
}
//-------------------------------------------------------------------------------------------------------------
// sets the time frame where the dock master can be called on - he doesn't work 24 hours a day!
this.$setDockMasterHours = function $setDockMasterHours() {
// set a start time between 7 and 10
this._dockMasterStartTime = 6 + this.$rand(4);
// set an end time between 7 and 10 hours later
this._dockMasterEndTime = this.$dockMasterStartTime + (this.$rand(4) + 6)
}
//-------------------------------------------------------------------------------------------------------------
// removes labelling on a specific amount of cargo
this.$removeRealCargoQuantity = function $removeRealCargoQuantity(commodity, amount) {
var p = player.ship;
var remainder = amount;
for (var i = this._cargoLabelled.length - 1; i >= 0; i--) {
if (remainder > 0 && this._cargoLabelled[i].oldCommodity === commodity) {
if (this._cargoLabelled[i].quantity >= remainder) {
if (p.manifest[this._cargoLabelled[i].newCommodity] >= remainder) {
p.manifest[this._cargoLabelled[i].newCommodity] -= remainder;
p.manifest[this._cargoLabelled[i].oldCommodity] += remainder;
this._cargoLabelled[i].quantity -= remainder;
remainder = 0;
} else {
var subamt = p.manifest[this._cargoLabelled[i].newCommodity];
p.manifest[this._cargoLabelled[i].newCommodity] = 0;
p.manifest[this._cargoLabelled[i].oldCommodity] += subamt;
this._cargoLabelled[i].quantity -= subamt;
remainder -= subamt;
}
} else {
var correction = remainder - this._cargoLabelled[i].quantity;
if (p.manifest[this._cargoLabelled[i].newCommodity] >= correction) {
p.manifest[this._cargoLabelled[i].newCommodity] -= correction;
p.manifest[this._cargoLabelled[i].oldCommodity] += correction;
this._cargoLabelled[i].quantity -= correction;
remainder -= correction;
} else {
var subamt = p.manifest[this._cargoLabelled[i].oldCommodity];
p.manifest[this._cargoLabelled[i].newCommodity] = 0;
p.manifest[this._cargoLabelled[i].oldCommodity] += subamt;
this._cargoLabelled[i].quantity = 0;
remainder -= subamt;
}
}
}
}
return remainder;
}
//-------------------------------------------------------------------------------------------------------------
// returns true if the player cargo that the dock master can relabel, otherwise false
this.$playerHasBribableCargo = function $playerHasBribableCargo() {
var p = player.ship;
var cargo = p.manifest.list;
var result = false;
for (var i = 0; i < cargo.length; i++) {
if (this._noSwitch.indexOf(cargo[i].commodity) === -1) result = true;
}
return result;
}
//-------------------------------------------------------------------------------------------------------------
// increment the number of times the dm has been bribed
this.$addBribe = function $addBribe(sysID) {
this._bribeCount[sysID] += 0.1 + (system.pseudoRandomNumber > 0.5 ? 0.1 : 0);
}
//-------------------------------------------------------------------------------------------------------------
// reset the bribecount array
this.$resetBribeCount = function $resetBribeCount() {
this._bribeCount = [];
for (var i = 0; i <= 255; i++) {
this._bribeCount.push(1);
}
}
//-------------------------------------------------------------------------------------------------------------
// returns the last successful bribe amount for the current system
this.$previousBribeAmount = function $previousBribeAmount() {
var bribeAmt = 0;
for (var i = 0; i < this._successfulBribes.length; i++) {
if (this._successfulBribes[i].system === system.ID && this._successfulBribes[i].bribeAmount > bribeAmt) {
bribeAmt = this._successfulBribes[i].bribeAmount;
}
}
return bribeAmt;
}
//-------------------------------------------------------------------------------------------------------------
// loads the mulk run array with data for the current galaxy
this.$getMilkRuns = function $getMilkRuns() {
this._milkRuns = [];
switch (galaxyNumber) {
case 0:
this._milkRuns.push({
id1: 99,
id2: 84,
rating: 70
});
this._milkRuns.push({
id1: 99,
id2: 191,
rating: 72
});
this._milkRuns.push({
id1: 12,
id2: 116,
rating: 73
});
this._milkRuns.push({
id1: 163,
id2: 192,
rating: 73
});
this._milkRuns.push({
id1: 131,
id2: 42,
rating: 73
});
this._milkRuns.push({
id1: 254,
id2: 187,
rating: 74
});
this._milkRuns.push({
id1: 158,
id2: 116,
rating: 75
});
this._milkRuns.push({
id1: 98,
id2: 84,
rating: 75
});
this._milkRuns.push({
id1: 98,
id2: 191,
rating: 75
});
this._milkRuns.push({
id1: 195,
id2: 63,
rating: 76
});
this._milkRuns.push({
id1: 254,
id2: 251,
rating: 76
});
this._milkRuns.push({
id1: 79,
id2: 174,
rating: 76
});
this._milkRuns.push({
id1: 49,
id2: 116,
rating: 76
});
this._milkRuns.push({
id1: 254,
id2: 74,
rating: 77
});
this._milkRuns.push({
id1: 100,
id2: 42,
rating: 77
});
this._milkRuns.push({
id1: 207,
id2: 116,
rating: 77
});
this._milkRuns.push({
id1: 131,
id2: 167,
rating: 78
});
this._milkRuns.push({
id1: 240,
id2: 187,
rating: 78
});
this._milkRuns.push({
id1: 79,
id2: 191,
rating: 79
});
this._milkRuns.push({
id1: 33,
id2: 123,
rating: 81
});
this._milkRuns.push({
id1: 99,
id2: 185,
rating: 81
});
this._milkRuns.push({
id1: 82,
id2: 244,
rating: 83
});
this._milkRuns.push({
id1: 227,
id2: 154,
rating: 83
});
this._milkRuns.push({
id1: 35,
id2: 186,
rating: 84
});
this._milkRuns.push({
id1: 221,
id2: 185,
rating: 84
});
this._milkRuns.push({
id1: 163,
id2: 252,
rating: 86
});
this._milkRuns.push({
id1: 141,
id2: 101,
rating: 89
});
this._milkRuns.push({
id1: 250,
id2: 101,
rating: 89
});
this._milkRuns.push({
id1: 218,
id2: 18,
rating: 90
});
this._milkRuns.push({
id1: 82,
id2: 154,
rating: 90
});
this._milkRuns.push({
id1: 246,
id2: 18,
rating: 93
});
break;
case 1:
this._milkRuns.push({
id1: 255,
id2: 37,
rating: 72
});
this._milkRuns.push({
id1: 191,
id2: 37,
rating: 74
});
this._milkRuns.push({
id1: 128,
id2: 165,
rating: 74
});
this._milkRuns.push({
id1: 57,
id2: 94,
rating: 76
});
this._milkRuns.push({
id1: 24,
id2: 20,
rating: 78
});
this._milkRuns.push({
id1: 237,
id2: 174,
rating: 79
});
this._milkRuns.push({
id1: 16,
id2: 157,
rating: 80
});
this._milkRuns.push({
id1: 81,
id2: 20,
rating: 80
});
this._milkRuns.push({
id1: 167,
id2: 94,
rating: 81
});
this._milkRuns.push({
id1: 82,
id2: 174,
rating: 82
});
this._milkRuns.push({
id1: 40,
id2: 68,
rating: 82
});
this._milkRuns.push({
id1: 106,
id2: 211,
rating: 83
});
this._milkRuns.push({
id1: 57,
id2: 19,
rating: 83
});
this._milkRuns.push({
id1: 57,
id2: 115,
rating: 84
});
this._milkRuns.push({
id1: 185,
id2: 38,
rating: 84
});
this._milkRuns.push({
id1: 92,
id2: 211,
rating: 85
});
this._milkRuns.push({
id1: 191,
id2: 83,
rating: 85
});
this._milkRuns.push({
id1: 16,
id2: 34,
rating: 87
});
this._milkRuns.push({
id1: 40,
id2: 179,
rating: 88
});
this._milkRuns.push({
id1: 209,
id2: 115,
rating: 88
});
this._milkRuns.push({
id1: 81,
id2: 97,
rating: 90
});
this._milkRuns.push({
id1: 82,
id2: 86,
rating: 92
});
this._milkRuns.push({
id1: 167,
id2: 115,
rating: 92
});
this._milkRuns.push({
id1: 231,
id2: 147,
rating: 94
});
break;
case 2:
this._milkRuns.push({
id1: 205,
id2: 168,
rating: 71
});
this._milkRuns.push({
id1: 144,
id2: 147,
rating: 73
});
this._milkRuns.push({
id1: 34,
id2: 57,
rating: 73
});
this._milkRuns.push({
id1: 64,
id2: 168,
rating: 73
});
this._milkRuns.push({
id1: 76,
id2: 152,
rating: 76
});
this._milkRuns.push({
id1: 76,
id2: 66,
rating: 76
});
this._milkRuns.push({
id1: 205,
id2: 82,
rating: 77
});
this._milkRuns.push({
id1: 155,
id2: 57,
rating: 77
});
this._milkRuns.push({
id1: 116,
id2: 152,
rating: 77
});
this._milkRuns.push({
id1: 17,
id2: 24,
rating: 77
});
this._milkRuns.push({
id1: 205,
id2: 114,
rating: 79
});
this._milkRuns.push({
id1: 17,
id2: 41,
rating: 79
});
this._milkRuns.push({
id1: 17,
id2: 147,
rating: 79
});
this._milkRuns.push({
id1: 22,
id2: 140,
rating: 79
});
this._milkRuns.push({
id1: 64,
id2: 215,
rating: 79
});
this._milkRuns.push({
id1: 58,
id2: 152,
rating: 80
});
this._milkRuns.push({
id1: 50,
id2: 65,
rating: 82
});
this._milkRuns.push({
id1: 42,
id2: 163,
rating: 83
});
this._milkRuns.push({
id1: 58,
id2: 140,
rating: 84
});
this._milkRuns.push({
id1: 205,
id2: 241,
rating: 84
});
this._milkRuns.push({
id1: 43,
id2: 98,
rating: 84
});
this._milkRuns.push({
id1: 22,
id2: 91,
rating: 84
});
this._milkRuns.push({
id1: 42,
id2: 135,
rating: 85
});
this._milkRuns.push({
id1: 54,
id2: 118,
rating: 86
});
this._milkRuns.push({
id1: 18,
id2: 100,
rating: 87
});
this._milkRuns.push({
id1: 5,
id2: 66,
rating: 87
});
this._milkRuns.push({
id1: 79,
id2: 65,
rating: 89
});
this._milkRuns.push({
id1: 10,
id2: 141,
rating: 89
});
this._milkRuns.push({
id1: 6,
id2: 180,
rating: 89
});
this._milkRuns.push({
id1: 58,
id2: 66,
rating: 89
});
this._milkRuns.push({
id1: 10,
id2: 70,
rating: 90
});
this._milkRuns.push({
id1: 5,
id2: 140,
rating: 90
});
this._milkRuns.push({
id1: 116,
id2: 122,
rating: 92
});
this._milkRuns.push({
id1: 10,
id2: 85,
rating: 94
});
break;
case 3:
this._milkRuns.push({
id1: 38,
id2: 160,
rating: 70
});
this._milkRuns.push({
id1: 25,
id2: 24,
rating: 72
});
this._milkRuns.push({
id1: 25,
id2: 62,
rating: 74
});
this._milkRuns.push({
id1: 220,
id2: 171,
rating: 75
});
this._milkRuns.push({
id1: 137,
id2: 105,
rating: 76
});
this._milkRuns.push({
id1: 209,
id2: 33,
rating: 77
});
this._milkRuns.push({
id1: 29,
id2: 168,
rating: 78
});
this._milkRuns.push({
id1: 58,
id2: 24,
rating: 78
});
this._milkRuns.push({
id1: 103,
id2: 107,
rating: 78
});
this._milkRuns.push({
id1: 65,
id2: 239,
rating: 78
});
this._milkRuns.push({
id1: 103,
id2: 105,
rating: 79
});
this._milkRuns.push({
id1: 103,
id2: 177,
rating: 79
});
this._milkRuns.push({
id1: 38,
id2: 53,
rating: 82
});
this._milkRuns.push({
id1: 42,
id2: 16,
rating: 83
});
this._milkRuns.push({
id1: 38,
id2: 74,
rating: 84
});
this._milkRuns.push({
id1: 103,
id2: 108,
rating: 84
});
this._milkRuns.push({
id1: 103,
id2: 239,
rating: 84
});
this._milkRuns.push({
id1: 220,
id2: 68,
rating: 84
});
this._milkRuns.push({
id1: 58,
id2: 109,
rating: 89
});
this._milkRuns.push({
id1: 220,
id2: 90,
rating: 90
});
break;
case 4:
this._milkRuns.push({
id1: 34,
id2: 186,
rating: 70
});
this._milkRuns.push({
id1: 34,
id2: 250,
rating: 70
});
this._milkRuns.push({
id1: 66,
id2: 58,
rating: 70
});
this._milkRuns.push({
id1: 2,
id2: 63,
rating: 71
});
this._milkRuns.push({
id1: 226,
id2: 31,
rating: 71
});
this._milkRuns.push({
id1: 130,
id2: 250,
rating: 72
});
this._milkRuns.push({
id1: 162,
id2: 250,
rating: 73
});
this._milkRuns.push({
id1: 34,
id2: 183,
rating: 74
});
this._milkRuns.push({
id1: 162,
id2: 183,
rating: 74
});
this._milkRuns.push({
id1: 137,
id2: 191,
rating: 75
});
this._milkRuns.push({
id1: 98,
id2: 123,
rating: 75
});
this._milkRuns.push({
id1: 130,
id2: 108,
rating: 76
});
this._milkRuns.push({
id1: 12,
id2: 81,
rating: 76
});
this._milkRuns.push({
id1: 213,
id2: 81,
rating: 77
});
this._milkRuns.push({
id1: 115,
id2: 150,
rating: 78
});
this._milkRuns.push({
id1: 162,
id2: 149,
rating: 78
});
this._milkRuns.push({
id1: 254,
id2: 183,
rating: 79
});
this._milkRuns.push({
id1: 212,
id2: 46,
rating: 80
});
this._milkRuns.push({
id1: 198,
id2: 31,
rating: 80
});
this._milkRuns.push({
id1: 254,
id2: 250,
rating: 82
});
this._milkRuns.push({
id1: 130,
id2: 149,
rating: 82
});
this._milkRuns.push({
id1: 194,
id2: 88,
rating: 83
});
this._milkRuns.push({
id1: 198,
id2: 63,
rating: 84
});
this._milkRuns.push({
id1: 99,
id2: 91,
rating: 84
});
this._milkRuns.push({
id1: 254,
id2: 149,
rating: 85
});
this._milkRuns.push({
id1: 99,
id2: 200,
rating: 85
});
this._milkRuns.push({
id1: 184,
id2: 150,
rating: 86
});
this._milkRuns.push({
id1: 89,
id2: 87,
rating: 88
});
this._milkRuns.push({
id1: 249,
id2: 16,
rating: 90
});
break;
case 5:
this._milkRuns.push({
id1: 243,
id2: 57,
rating: 70
});
this._milkRuns.push({
id1: 243,
id2: 228,
rating: 71
});
this._milkRuns.push({
id1: 182,
id2: 160,
rating: 71
});
this._milkRuns.push({
id1: 14,
id2: 249,
rating: 73
});
this._milkRuns.push({
id1: 240,
id2: 30,
rating: 75
});
this._milkRuns.push({
id1: 20,
id2: 57,
rating: 75
});
this._milkRuns.push({
id1: 243,
id2: 231,
rating: 75
});
this._milkRuns.push({
id1: 243,
id2: 101,
rating: 75
});
this._milkRuns.push({
id1: 243,
id2: 98,
rating: 76
});
this._milkRuns.push({
id1: 109,
id2: 57,
rating: 76
});
this._milkRuns.push({
id1: 243,
id2: 103,
rating: 77
});
this._milkRuns.push({
id1: 34,
id2: 24,
rating: 78
});
this._milkRuns.push({
id1: 69,
id2: 167,
rating: 78
});
this._milkRuns.push({
id1: 144,
id2: 61,
rating: 79
});
this._milkRuns.push({
id1: 109,
id2: 228,
rating: 79
});
this._milkRuns.push({
id1: 182,
id2: 167,
rating: 79
});
this._milkRuns.push({
id1: 240,
id2: 234,
rating: 80
});
this._milkRuns.push({
id1: 144,
id2: 253,
rating: 81
});
this._milkRuns.push({
id1: 144,
id2: 97,
rating: 81
});
this._milkRuns.push({
id1: 109,
id2: 98,
rating: 81
});
this._milkRuns.push({
id1: 20,
id2: 244,
rating: 81
});
this._milkRuns.push({
id1: 86,
id2: 131,
rating: 81
});
this._milkRuns.push({
id1: 109,
id2: 101,
rating: 82
});
this._milkRuns.push({
id1: 28,
id2: 108,
rating: 82
});
this._milkRuns.push({
id1: 1,
id2: 108,
rating: 82
});
this._milkRuns.push({
id1: 115,
id2: 215,
rating: 83
});
this._milkRuns.push({
id1: 109,
id2: 231,
rating: 83
});
this._milkRuns.push({
id1: 20,
id2: 103,
rating: 84
});
this._milkRuns.push({
id1: 1,
id2: 181,
rating: 86
});
this._milkRuns.push({
id1: 240,
id2: 140,
rating: 88
});
this._milkRuns.push({
id1: 14,
id2: 113,
rating: 88
});
this._milkRuns.push({
id1: 144,
id2: 13,
rating: 88
});
this._milkRuns.push({
id1: 102,
id2: 98,
rating: 88
});
this._milkRuns.push({
id1: 17,
id2: 108,
rating: 91
});
this._milkRuns.push({
id1: 6,
id2: 181,
rating: 92
});
this._milkRuns.push({
id1: 40,
id2: 215,
rating: 94
});
this._milkRuns.push({
id1: 17,
id2: 181,
rating: 96
});
this._milkRuns.push({
id1: 50,
id2: 232,
rating: 98
});
break;
case 6:
this._milkRuns.push({
id1: 170,
id2: 105,
rating: 75
});
this._milkRuns.push({
id1: 170,
id2: 190,
rating: 75
});
this._milkRuns.push({
id1: 64,
id2: 160,
rating: 75
});
this._milkRuns.push({
id1: 13,
id2: 160,
rating: 76
});
this._milkRuns.push({
id1: 6,
id2: 174,
rating: 77
});
this._milkRuns.push({
id1: 183,
id2: 164,
rating: 79
});
this._milkRuns.push({
id1: 28,
id2: 223,
rating: 79
});
this._milkRuns.push({
id1: 119,
id2: 190,
rating: 79
});
this._milkRuns.push({
id1: 151,
id2: 180,
rating: 80
});
this._milkRuns.push({
id1: 64,
id2: 81,
rating: 80
});
this._milkRuns.push({
id1: 55,
id2: 105,
rating: 80
});
this._milkRuns.push({
id1: 195,
id2: 159,
rating: 80
});
this._milkRuns.push({
id1: 55,
id2: 190,
rating: 80
});
this._milkRuns.push({
id1: 86,
id2: 127,
rating: 80
});
this._milkRuns.push({
id1: 172,
id2: 160,
rating: 81
});
this._milkRuns.push({
id1: 199,
id2: 233,
rating: 82
});
this._milkRuns.push({
id1: 151,
id2: 73,
rating: 82
});
this._milkRuns.push({
id1: 181,
id2: 95,
rating: 83
});
this._milkRuns.push({
id1: 103,
id2: 58,
rating: 83
});
this._milkRuns.push({
id1: 71,
id2: 160,
rating: 83
});
this._milkRuns.push({
id1: 66,
id2: 190,
rating: 84
});
this._milkRuns.push({
id1: 135,
id2: 80,
rating: 84
});
this._milkRuns.push({
id1: 23,
id2: 233,
rating: 84
});
this._milkRuns.push({
id1: 66,
id2: 105,
rating: 84
});
this._milkRuns.push({
id1: 215,
id2: 95,
rating: 86
});
this._milkRuns.push({
id1: 247,
id2: 202,
rating: 86
});
this._milkRuns.push({
id1: 82,
id2: 105,
rating: 87
});
this._milkRuns.push({
id1: 82,
id2: 190,
rating: 87
});
this._milkRuns.push({
id1: 172,
id2: 81,
rating: 88
});
this._milkRuns.push({
id1: 71,
id2: 81,
rating: 88
});
this._milkRuns.push({
id1: 67,
id2: 209,
rating: 88
});
this._milkRuns.push({
id1: 23,
id2: 246,
rating: 89
});
this._milkRuns.push({
id1: 7,
id2: 209,
rating: 89
});
this._milkRuns.push({
id1: 215,
id2: 133,
rating: 91
});
this._milkRuns.push({
id1: 183,
id2: 133,
rating: 92
});
this._milkRuns.push({
id1: 247,
id2: 133,
rating: 93
});
this._milkRuns.push({
id1: 151,
id2: 5,
rating: 95
});
break;
case 7:
this._milkRuns.push({
id1: 56,
id2: 240,
rating: 70
});
this._milkRuns.push({
id1: 56,
id2: 170,
rating: 72
});
this._milkRuns.push({
id1: 82,
id2: 100,
rating: 75
});
this._milkRuns.push({
id1: 31,
id2: 25,
rating: 77
});
this._milkRuns.push({
id1: 147,
id2: 121,
rating: 77
});
this._milkRuns.push({
id1: 41,
id2: 35,
rating: 78
});
this._milkRuns.push({
id1: 244,
id2: 138,
rating: 78
});
this._milkRuns.push({
id1: 192,
id2: 133,
rating: 78
});
this._milkRuns.push({
id1: 151,
id2: 230,
rating: 78
});
this._milkRuns.push({
id1: 137,
id2: 121,
rating: 80
});
this._milkRuns.push({
id1: 206,
id2: 25,
rating: 80
});
this._milkRuns.push({
id1: 232,
id2: 86,
rating: 81
});
this._milkRuns.push({
id1: 93,
id2: 185,
rating: 81
});
this._milkRuns.push({
id1: 93,
id2: 196,
rating: 81
});
this._milkRuns.push({
id1: 192,
id2: 35,
rating: 81
});
this._milkRuns.push({
id1: 161,
id2: 255,
rating: 82
});
this._milkRuns.push({
id1: 14,
id2: 25,
rating: 83
});
this._milkRuns.push({
id1: 110,
id2: 172,
rating: 84
});
this._milkRuns.push({
id1: 82,
id2: 179,
rating: 84
});
this._milkRuns.push({
id1: 41,
id2: 233,
rating: 85
});
this._milkRuns.push({
id1: 251,
id2: 30,
rating: 85
});
this._milkRuns.push({
id1: 218,
id2: 71,
rating: 89
});
this._milkRuns.push({
id1: 93,
id2: 186,
rating: 90
});
this._milkRuns.push({
id1: 206,
id2: 71,
rating: 90
});
this._milkRuns.push({
id1: 251,
id2: 233,
rating: 90
});
this._milkRuns.push({
id1: 93,
id2: 92,
rating: 92
});
this._milkRuns.push({
id1: 232,
id2: 81,
rating: 92
});
this._milkRuns.push({
id1: 110,
id2: 177,
rating: 93
});
this._milkRuns.push({
id1: 232,
id2: 252,
rating: 93
});
break
}
} |
Scripts/smugglers_equipment.js |
"use strict";
this.name = "Smugglers_Equipment";
this.author = "phkb";
this.description = "Looks after the smuggling compartment functions.";
this.licence = "CC BY-NC-SA 3.0";
/* TODO:
- Add very occasional messages from traders entering system ("Let hope that setting of 234 is worth the money we paid.")
- When docking with a standard contract that will be completed, but the cargo is now illegal, still give the player the opportunity to bribe
- allow non-core commodities to be put in the compartment
ISSUE:
- bribe opportunity not appearing in scenario where player docks at non-main station galcop station, with a scooped escape pod and illegal cargo (not slaves)
*/
this._disabled = false;
this._debug = false;
// array of all possible installed compartment equipment keys
this._equipmentList = ["EQ_SMUGGLING_COMPARTMENT_1", "EQ_SMUGGLING_COMPARTMENT_2", "EQ_SMUGGLING_COMPARTMENT_3", "EQ_SMUGGLING_COMPARTMENT_4",
"EQ_SMUGGLING_COMPARTMENT_5", "EQ_SMUGGLING_COMPARTMENT_6", "EQ_SMUGGLING_COMPARTMENT_7", "EQ_SMUGGLING_COMPARTMENT_8",
"EQ_SMUGGLING_COMPARTMENT_9", "EQ_SMUGGLING_COMPARTMENT_10", "EQ_SMUGGLING_COMPARTMENT_11", "EQ_SMUGGLING_COMPARTMENT_12",
"EQ_SMUGGLING_COMPARTMENT_13", "EQ_SMUGGLING_COMPARTMENT_14", "EQ_SMUGGLING_COMPARTMENT_15", "EQ_SMUGGLING_COMPARTMENT_16",
"EQ_SMUGGLING_COMPARTMENT_17", "EQ_SMUGGLING_COMPARTMENT_18", "EQ_SMUGGLING_COMPARTMENT_19", "EQ_SMUGGLING_COMPARTMENT_20"
];
this._commodityIDList = [];
// station types where the smuggling compartment can be purchased.
this._smugglingAllegiance = ["pirate", "chaotic", "neutral"];
this._maxTonnage = 20; // maximum possible size of the hold
this._doCompartmentCheck = false; // flag to indicate that a compartment check will be performed after docking
this._backdoor = false;
this._sc_Phase = 1; // the current phase setting (value between 1 and 999)
this._sc_TechVersion = 1; // the current tech level of the compartment
this._sc_VisibleAs = "food"; // string (commodity name) that the hold will display as for scanners
this._sc_Cargo = []; // array of commodities in hold (commodity:string, quantity:number, unit:t/kg/g);
this._sc_Days = 0; // number of days since the last tech upgrade
this._phaseUpdateDays = 0;
this._phaseScanDiscovery = []; // array of objects of discovered phase scan settings (from purchase or from phase scanner)
this._smugglingScreen = false; // flag to indicate that a mission screen is open
this._originalCredits = 0; // value to hold the players credits (used to refund the cost of the initial item)
this._display = 0;
this._oldday = 0;
this._phaseScannerAvailable = false; // indicates that this system has the phase scanner available
this._phaseScannerDetected = false; // indicates that the player was caught using the phase scanner
this._systemPhase = []; // array of objects (gov, tl, phase)
this._phaseUpdates = []; // stores list of governments/techLevels that have been updated
this._toRemove = []; // list of source and commodities to be removed
this._removeCompartment = false; // flag to indicate that the smuggling compartment should be removed after docking
this._playerFine = 0; // amount to fine the player
this._menuColor = "orangeColor";
this._itemColor = "yellowColor";
this._disabledColor = "darkGrayColor";
this._galJump = false;
this._policeModel = "";
this._NCInstalled = false;
this._IGTInstalled = false;
this._doCargoCheck = false;
this._dockingWithSlaves = false;
this._dockingWithSlavesCount = 0;
//-------------------------------------------------------------------------------------------------------------
this.startUp = function () {
if (this._disabled) {
delete this.playerWillSaveGame;
delete this.playerBoughtEquipment;
delete this.shipWillDockWithStation;
delete this.shipDockedWithStation;
delete this.missionScreenOpportunity;
delete this.shipExitedWitchspace;
delete this.shipLaunchedEscapePod;
delete this.guiScreenChanged;
delete this.guiScreenWillChange;
delete this.playerEnteredNewGalaxy;
delete this.playerRescuedEscapePod;
delete this.dayChanged;
delete this.equipmentDamaged;
delete this.equipmentRemoved;
delete this.startUpComplete;
delete this.startUp;
return;
}
this.$createSystemDataArray();
if (worldScripts.CargoTypeExtension) this._NCInstalled = true;
}
//-------------------------------------------------------------------------------------------------------------
this.startUpComplete = function () {
function compare(a, b) {
if (a.order < b.order) return -1;
if (a.order > b.order) return 1;
return 0;
}
// check for illegal goods tweak
if (worldScripts["illegal_goods_tweak"]) this._IGTInstalled = true;
// build a list of available commodities
var m = null;
// find a station to get market data from
if (system.mainStation) {
m = system.mainStation.market;
} else if (player.ship.dockedStation) {
m = playership.dockedStation.market;
} else if (system.stations.length > 0) {
m = system.stations[0].market;
}
if (m) {
var sbd = worldScripts.Smugglers_DockMaster;
var c = Object.keys(m);
var list = [];
for (var i = 0; i < c.length; i++) {
list.push({
commodity: c[i],
order: (m[c[i]].sort_order ? m[c[i]].sort_order : 0)
});
// add any non-t commodities (kg or g, ie gold, platinum, gemstones) to the dockmaster noswitch list
if (m[c[i]].quantity_unit != 0) sbd._noSwitch.push(c[i]);
}
list.sort(compare);
for (var i = 0; i < list.length; i++) {
this._commodityIDList.push(list[i].commodity);
}
}
var core = worldScripts.Smugglers_CoreFunctions;
this.$padTextRight = core.$padTextRight;
this.$padTextLeft = core.$padTextLeft;
this.$isBigGuiActive = core.$isBigGuiActive;
this.$rand = core.$rand;
if (missionVariables.SmugglingCompartment_Phase) this._sc_Phase = missionVariables.SmugglingCompartment_Phase;
if (missionVariables.SmugglingCompartment_TechVersion) this._sc_TechVersion = missionVariables.SmugglingCompartment_TechVersion;
if (missionVariables.SmugglingCompartment_VisibleAs) this._sc_VisibleAs = missionVariables.SmugglingCompartment_VisibleAs;
if (missionVariables.SmugglingCompartment_Cargo) this._sc_Cargo = JSON.parse(missionVariables.SmugglingCompartment_Cargo);
this.$addExtraField(); // make sure the "extra" property is added if it's not there yet
if (missionVariables.SmugglingCompartment_Days) this._sc_Days = missionVariables.SmugglingCompartment_Days;
if (missionVariables.Smuggling_SystemPhase) this._systemPhase = JSON.parse(missionVariables.Smuggling_SystemPhase);
if (missionVariables.Smuggling_PhaseScannerAvailable) this._phaseScannerAvailable = (missionVariables.Smuggling_PhaseScannerAvailable === 1 ? true : false);
if (missionVariables.Smuggling_PhaseDiscovery) this._phaseScanDiscovery = JSON.parse(missionVariables.Smuggling_PhaseDiscovery);
if (missionVariables.Smuggling_PhaseUpdates) this._phaseUpdates = JSON.parse(missionVariables.Smuggling_PhaseUpdates);
if (missionVariables.Smuggling_PhaseUpdateDays) this._phaseUpdateDays = missionVariables.Smuggling_PhaseUpdateDays;
delete missionVariables.SmugglingCompartment_Phase;
delete missionVariables.SmugglingCompartment_TechVersion;
delete missionVariables.SmugglingCompartment_VisibleAs;
delete missionVariables.SmugglingCompartment_Cargo;
if (this._systemPhase.length === 0) this.$createSystemPhase();
this._policeModel = this.$getPoliceModel();
// set up the interface screen, if required
this.$initInterface(player.ship.dockedStation);
// check that the inflight eq is given to the player if they have a smuggling compartment
if (this.$hasSmugglingCompartment() === true) {
player.ship.awardEquipment("EQ_SMUGGLING_INFLIGHT_STORAGE");
}
}
//-------------------------------------------------------------------------------------------------------------
this.playerWillSaveGame = function () {
if (this.$hasSmugglingCompartment() === true) {
missionVariables.SmugglingCompartment_Phase = this._sc_Phase;
missionVariables.SmugglingCompartment_TechVersion = this._sc_TechVersion;
missionVariables.SmugglingCompartment_VisibleAs = this._sc_VisibleAs;
missionVariables.SmugglingCompartment_Cargo = JSON.stringify(this._sc_Cargo);
missionVariables.SmugglingCompartment_Days = this._sc_Days;
} else {
delete missionVariables.SmugglingCompartment_Phase;
delete missionVariables.SmugglingCompartment_TechVersion;
delete missionVariables.SmugglingCompartment_VisibleAs;
delete missionVariables.SmugglingCompartment_Cargo;
delete missionVariables.SmugglingCompartment_Days;
}
missionVariables.Smuggling_SystemPhase = JSON.stringify(this._systemPhase);
missionVariables.Smuggling_PhaseScannerAvailable = (this._phaseScannerAvailable ? 1 : 0);
missionVariables.Smuggling_PhaseDiscovery = JSON.stringify(this._phaseScanDiscovery);
if (this._phaseUpdates.length > 0) missionVariables.Smuggling_PhaseUpdates = JSON.stringify(this._phaseUpdates);
missionVariables.Smuggling_PhaseUpdateDays = this._phaseUpdateDays;
}
//-------------------------------------------------------------------------------------------------------------
this.playerBoughtEquipment = function (equipmentKey) {
var p = player.ship;
// repairing the phase scanner
if (equipmentKey === "EQ_PHASE_SCANNER_REPAIR") {
p.removeEquipment(equipmentKey);
p.setEquipmentStatus("EQ_PHASE_SCANNER", "EQUIPMENT_OK");
return;
}
// repairing the smuggling compartment
if (equipmentKey.indexOf("EQ_SMUGGLING_COMPARTMENT_REPAIR") >= 0) {
p.removeEquipment(equipmentKey);
var eq = this.$getSmugglingCompartmentEquipment();
p.setEquipmentStatus(eq, "EQUIPMENT_OK");
return;
}
var stn = p.dockedStation;
// removing the phase scanner
if (equipmentKey === "EQ_PHASE_SCANNER_REMOVAL") {
p.removeEquipment(equipmentKey);
if (stn.allegiance != "galcop") {
// give the player a refund if we're not at a galcop station
var tradeinfactor = 1.0;
// less refund for damaged scanner
if (p.equipmentStatus("EQ_PHASE_SCANNER") != "EQUIPMENT_OK") tradinfactor = 0.3;
var oldEqInfo = EquipmentInfo.infoForKey("EQ_PHASE_SCANNER");
player.credits += ((oldEqInfo.price / 10) * stn.equipmentPriceFactor) * tradeinfactor;
}
p.removeEquipment("EQ_PHASE_SCANNER");
}
// removing the smuggling compartment
if (equipmentKey === "EQ_SMUGGLING_COMPARTMENT_REMOVAL") {
p.removeEquipment(equipmentKey);
var eqKey = this.$getSmugglingCompartmentEquipment();
// do a refund, but only if we're not at a galcop station, and only if the existing equipment is undamaged
if (stn.allegiance != "galcop" && eqKey != "") {
var tradeinfactor = 1.0;
// less refund for damaged compartment
if (p.equipmentStatus(eqKey) != "EQUIPMENT_OK") tradinfactor = 0.3;
var oldEqInfo = EquipmentInfo.infoForKey(eqKey);
player.credits += ((oldEqInfo.price / 10) * stn.equipmentPriceFactor) * tradeinfactor;
}
if (p.equipmentStatus("EQ_SMUGGLING_PHASE_ADJUSTMENT") === "EQUIPMENT_OK") {
p.removeEquipment("EQ_SMUGGLING_PHASE_ADJUSTMENT");
}
player.ship.removeEquipment("EQ_SMUGGLING_INFLIGHT_STORAGE");
this._backdoor = true;
if (eqKey != "") p.removeEquipment(eqKey);
this._backdoor = false;
this.$resetCompartmentInfo(stn);
}
// buying a new (or expanding/contracting an existing) smuggling compartment
if (equipmentKey === "EQ_SMUGGLING_COMPARTMENT") {
p.removeEquipment(equipmentKey);
// give the player back the original amount, in case they decide not to purchase
if (this._originalCredits != 0) {
player.credits = this._originalCredits;
this._originalCredits = player.credits;
}
// mission screen to ask how many TC to allocate
this._hudHidden = player.ship.hudHidden;
this.$showPurchasePage();
}
if (equipmentKey === "EQ_SMUGGLING_VERSION_UPGRADE") {
p.removeEquipment(equipmentKey);
this._sc_TechVersion += 1;
this._sc_Days = 0;
}
if (stn.allegiance === "galcop" && equipmentKey === "EQ_RENOVATION") {
// is the phase scanner on board
var msgtype = 0;
if (p.equipmentStatus("EQ_PHASE_SCANNER") === "EQUIPMENT_OK" || p.equipmentStatus("EQ_PHASE_SCANNER") === "EQUIPMENT_DAMAGED") {
// oh dear - caught!
p.setBounty(player.bounty + (this.$rand(10) + 10), "illegal equipment");
msgtype += 1;
}
// is the smuggling compartment installed?
if (this.$hasSmugglingCompartment() === true) {
msgtype += 2;
// increase bounty
p.setBounty(player.bounty + (this.$rand(10) + 10), "illegal equipment");
}
var msgBody = "";
switch (msgtype) {
case 0:
break;
case 1:
msgBody = expandDescription("[illegal-equipment-1]");
break;
case 2:
msgBody = expandDescription("[illegal-equipment-2]", {
size: this.$smugglingCompartmentSize()
});
break;
case 3:
msgBody = expandDescription("[illegal-equipment-3]", {
size: this.$smugglingCompartmentSize()
});
break;
}
if (msgBody != "") {
var curChoices = {};
if (player.credits > 0) {
curChoices["01_BRIBE"] = {
text: "[illegal-attempt-bribe]",
color: this._menuColor
};
}
curChoices["98_ACCEPT"] = {
text: "[illegal-accept-penalty]",
color: this._menuColor
};
this._bribeType = 2;
var opts = {
title: "Illegal Equipment Discovered",
message: msgBody,
model: "[" + this._policeModel + "]",
allowInterrupt: false,
exitScreen: "GUI_SCREEN_EQUIP_SHIP",
choices: curChoices,
initialChoicesKey: "98_ACCEPT"
};
mission.runScreen(opts, this.$bribeScreenHandler, this);
}
}
}
//-------------------------------------------------------------------------------------------------------------
/*this.equipmentRemoved = function(equipmentKey) {
if (this._backdoor === true) return;
if (this._equipmentList.indexOf(equipmentKey) >= 0) {
this.$resetCompartmentInfo(player.ship.dockedStation);
return;
}
}*/
//-------------------------------------------------------------------------------------------------------------
this.shipWillDockWithStation = function (station) {
this._policeModel = this.$getPoliceModel();
this._savedBounty = player.bounty;
// grab a snapshot of the players illegal cargo
this._dockIllegal = [];
this._dockingWithSlaves = false;
// if the player has slaves on board, and IGT is installed, then turn on the flag to indicate we're docking with slaves
var escapePods = 0;
if (worldScripts.EscapePodTweaks) {
// if the _escapePods array have data, what means the escape pod tweaks "shipWillDOckWithStation" function hasn't been executed yet
// in that case we need to know how many slaves to ignore
escapePods = worldScripts.EscapePodTweaks._escapePods.length;
// if its been run already, the value will be 0 anyway
}
if (player.ship.manifest["slaves"] && (player.ship.manifest["slaves"] - escapePods) > 0 && this._IGTInstalled === true) {
this._dockingWithSlaves = true;
// make a note of the slaves count, because if we dock with rescued escape pods, the number will have to be reduced during "playerRescuedEscapePod";
this._dockingWithSlavesCount = (player.ship.manifest["slaves"] - escapePods);
}
this._playerHadIllegals = false;
if (this.$playerHasIllegalCargo(station) === true) {
var p = player.ship;
var m = p.manifest;
this._dockIllegal = [];
for (var i = 0; i < m.list.length; i++) {
if (m.list[i].quantity > 0 && station.market[m.list[i].commodity].legality_import > 0) this._dockIllegal.push({
commodity: m.list[i].commodity,
quantity: m.list[i].quantity
});
}
this._playerHadIllegals = true;
}
}
//-------------------------------------------------------------------------------------------------------------
this.shipDockedWithStation = function (station) {
if (station.allegiance === "galcop") {
if (this._dockingWithSlaves === false) this._doCargoCheck = true;
}
// set up smuggling interface screen
this.$initInterface(station);
}
//-------------------------------------------------------------------------------------------------------------
this.shipLaunchedEscapePod = function (escapepod) {
// clear out smugglers compartment when escape pod is used
this._sc_Cargo = [];
}
//-------------------------------------------------------------------------------------------------------------
this.missionScreenOpportunity = function () {
// if IGT is installed, let it run first. it will call the performCargoCheck when it's finished.
if (this._doCargoCheck === true) {
this.$performCargoCheck();
}
}
//-------------------------------------------------------------------------------------------------------------
this.playerRescuedEscapePod = function (fee, reason, occupant) {
if (this._dockingWithSlavesCount > 0) {
this._dockingWithSlavesCount -= 1;
if (this._dockingWithSlavesCount === 0) this._dockingWithSlaves = false;
}
}
//-------------------------------------------------------------------------------------------------------------
this.shipExitedWitchspace = function () {
if (this._galJump === true) {
this._galJump = false;
this.$createSystemPhase();
this.$createSystemDataArray();
}
this._phaseScannerAvailable = false;
this._phaseScannerDetected = false;
if (system.government === 0 && system.info.techlevel >= 8) {
// will this system provide a phase scanner?
if (system.scrambledPseudoRandomNumber(system.ID) > 0.6) this._phaseScannerAvailable = true;
}
}
//-------------------------------------------------------------------------------------------------------------
this.guiScreenWillChange = function (to, from) {
if (to === "GUI_SCREEN_MANIFEST") this.$updateManifest();
}
//-------------------------------------------------------------------------------------------------------------
this.guiScreenChanged = function (to, from) {
if (guiScreen === "GUI_SCREEN_EQUIP_SHIP") {
this._originalCredits = player.credits;
this._savedBounty = player.bounty;
}
if (from === "GUI_SCREEN_MISSION" && this._smugglingScreen) {
this._smugglingScreen = false;
if (this._hudHidden === false && player.ship.hudHidden === true) player.ship.hudHidden = this._hudHidden;
}
}
//-------------------------------------------------------------------------------------------------------------
this.playerEnteredNewGalaxy = function (galaxyNumber) {
this._systemPhase = [];
this._phaseUpdates = [];
this._phaseScanDiscovery = [];
this._galJump = true;
}
//-------------------------------------------------------------------------------------------------------------
this.dayChanged = function (newday) {
if (newday != this._oldday) {
this._sc_Days += 1;
this._oldday = newday;
this._phaseUpdateDays += 1;
if (this._phaseUpdateDays >= 10) {
this._phaseUpdateDays = 0;
var item = this._systemData[this.$rand(this._systemData.length - 1)];
var gov = parseInt(item / 100);
var tl = item - gov;
var newPhase = this.$rand(999);
// remove from the update list
for (var i = this._phaseUpdates.length - 1; i >= 0; i--) {
if (this._phaseUpdates[i].gov === gov && this._phaseUpdates[i].tl === tl) {
this._phaseUpdates.splice(i, 1);
}
}
this.$updatePhase(gov, tl, newPhase);
}
}
}
//-------------------------------------------------------------------------------------------------------------
this.equipmentDamaged = function (equipment) {
if (this._equipmentList.indexOf(equipment) >= 0) {
// work out how many items will be damaged
var remove = this.$rand(3);
var report = [];
var count = 0;
do {
for (var i = 0; i < this._sc_Cargo.length; i++) {
if (count < remove && this._sc_Cargo[i].quantity > 0) {
// nc checks
if (this._sc_Cargo[i].extra != "") {
var dta = [];
log(this.name, "pre: " + this._sc_Cargo[i].extra);
dta = this._sc_Cargo[i].extra.split("/");
if ((this._sc_Cargo[i].quantity - dta.length) == 0) {
dta.shift();
this._sc_Cargo[i].extra = dta.join("/");
log(this.name, "post: " + this._sc_Cargo[i].extra);
}
}
this._sc_Cargo[i].quantity -= 1;
report.push(this._sc_Cargo[i].displayName + " destroyed!");
count += 1;
}
}
} while (count < remove && this._sc_Cargo.length > 0);
this.$cargoCleanUp();
// give the player the bad news
if (report.length > 0) {
for (var i = 0; i < report.length; i++) {
player.consoleMessage(report[i]);
}
}
}
}
//-------------------------------------------------------------------------------------------------------------
this.$addExtraField = function() {
if (this._sc_Cargo.length == 0) return;
for (var i = 0; i < this._sc_Cargo.length; i++) {
if (!this._sc_Cargo[i].hasOwnProperty("extra")) this._sc_Cargo[i].extra = "";
}
}
//-------------------------------------------------------------------------------------------------------------
this.$performCargoCheck = function $performCargoCheck() {
var msgtype = 0;
var p = player.ship;
this._toRemove = [];
this._removeCompartment = false;
this._playerFine = 0;
if (this._doCargoCheck === true) {
this._doCargoCheck = false;
if (this._phaseScannerDetected === true) {
if (player.credits > 1000) {
this._playerFine += 1000;
} else {
this._playerFine = player.credits;
}
// player has already had a legal penalty when the scan was detected, so we don't need to do it again here
}
// is our compartment damaged (and therefore visible?
if (this.$hasSmugglingCompartment() === true && this.$isCompartmentDamaged() === true) {
msgtype = 1;
this._removeCompartment = true;
// increase bounty
p.setBounty(player.bounty + (this.$rand(10) + 10), "illegal equipment");
if (player.credits > 1000) {
this._playerFine += 1000;
} else {
this._playerFine = player.credits;
}
}
// get the list of illegal goods for this system
var si = worldScripts.Smugglers_Illegal;
var goods = si.$illegalGoodsList(system.ID, true);
// if IGT is installed, add slaves onto the list of illegal goods
if (this._IGTInstalled) {
goods.push({
systemID: system.ID,
commodity: "slaves",
started: 0,
end: 0,
description: "",
permit: 0,
scale: 1
});
}
if (msgtype === 0) {
for (var i = 0; i < goods.length; i++) {
// if the visibleAs property equal to an illegal good on this planet? oh dear...it's not going to matter what the chance is...
if (this.$hasSmugglingCompartment() === true && goods[i].commodity.indexOf(this._sc_VisibleAs) >= 0 && si.$playerHasPermit(system.ID, goods[i].commodity, true) === false) {
msgtype = 2;
this._removeCompartment = true;
// increase bounty
p.setBounty(player.bounty + (this.$rand(10) + 10), "illegal equipment");
// fine player
if (player.credits > 1000) {
this._playerFine += 1000;
} else {
this._playerFine = player.credits;
}
}
}
}
// now, goods in the hold that are illegal to import should now automatically fine the player with a bounty increase.
// so we shouldn't have to worry about bounty from this point on.
// what we will do here is remove cargo and possibly fine the player a monetary amount
// base chance is 26% (for tech level 1), but increasing with a systems tech level, to a max of 40% for a tl 15 system
var base = 25 + system.info.techlevel;
var phase_diff = base;
// work out the chance of detection
// check for phase adjuster
if (p.equipmentStatus("EQ_SMUGGLING_PHASE_ADJUSTMENT") === "EQUIPMENT_OK") {
// if we've got the phase adjuster, there's a small boost the the base value, from 22% to 37%
base = 22 + system.info.techlevel;
phase_diff = Math.abs(this.$getSystemPhase(system.ID) - this._sc_Phase) - 3;
// if we're within +/- 3 then it's good enough
if (phase_diff < 0) phase_diff = 0;
// anything over base is considered inconsequential
if (phase_diff > base) phase_diff = base;
}
var chance = phase_diff / 100;
if (this._debug) log(this.name, "Smuggling compartment init chance: " + chance);
// now apply tech level offset. could be 0 through to an extra 12.5% (30/240 = 0.125)
chance += (this._sc_Days > 30 ? 30 : this._sc_Days) / 240;
if (this._debug) log(this.name, "Smuggling compartment final chance: " + chance);
var s_cargo = this.$getSmugglingCargo();
var msg = "";
var permit_failed = false;
var permit_list = "";
var permit_multi = 0;
var permit_ok = "";
var permit_okcount = 0;
var displaycheck = false;
var removecount = 0;
var successcount = 0;
var successmsg = "";
var smuggling_found = false;
// do this here so we only do it once
if (Math.random() < chance) smuggling_found = true;
for (var i = 0; i < goods.length; i++) {
// are there any illegal goods in our standard hold
// get a list of commodities (handles case where there are multiple commdoties in the illegal goods entry
var cmdtylist = goods[i].commodity.split(",");
var quantity_to_check = 0;
for (var j = 0; j < cmdtylist.length; j++) {
// only check if the good is actually marked as illegal
if (this.$commodityIllegalScale(cmdtylist[j]) > 0) {
if (p.manifest[cmdtylist[j]] > 0) {
quantity_to_check += p.manifest[cmdtylist[j]];
}
var hyper = this.$getHyperCargoQuantity(cmdtylist[j]);
if (hyper > 0) {
quantity_to_check += hyper;
}
for (var k = 0; k < s_cargo.length; k++) {
if (cmdtylist[j] === s_cargo[k].commodity && smuggling_found === true) {
quantity_to_check += s_cargo[k].quantity;
}
}
}
}
if (quantity_to_check > 0) {
if (si.$playerHasPermit(system.ID, goods[i].commodity, true) === false) {
// will get here if the player had a permit but it didn't work, or if they didn't have a permit at all.
// check if a permit permit failed to work
if (si.$playerHasPermit(system.ID, goods[i].commodity, false) === true) {
permit_failed = true;
permit_list += (permit_list === "" ? "" : ", ") + si.$translateCommodityList(goods[i].commodity);
permit_multi += 1;
if (goods[i].commodity.indexOf(",") >= 0) permit_multi += 1;
// remove any permit whether it worked or not
si.$removePermit(system.ID, goods[i].commodity);
}
for (var j = 0; j < cmdtylist.length; j++) {
// check the visible carge
if (p.manifest[cmdtylist[j]] > 0) {
// found!
msg += " - " + p.manifest[cmdtylist[j]] + " " + this.$getCommodityType(cmdtylist[j]) + " × " + displayNameForCommodity(cmdtylist[j]) + "\n";
this._toRemove.push({
source: "hold",
commodity: cmdtylist[j]
});
removecount += 1;
// stanndard slave bounty gets added here, because it's not set to be flagged as illegal to import by default
if (this._IGTInstalled === true && cmdtylist[j] === "slaves") {
p.setBounty(player.bounty + (p.manifest[cmdtylist[j]] * goods[i].scale), "illegal imports");
}
}
// check hypercargo
var hyper = this.$checkHyperCargo(cmdtylist[j]);
if (hyper != "") {
msg += hyper + "\n";
p.setBounty(player.bounty + (this.$getHyperCargoQuantity(cmdtylist[j]) * goods[i].scale), "illegal imports");
this._toRemove.push({
source: "hyper",
commodity: cmdtylist[j]
});
removecount += 1;
}
// try to check the smuggling compartment (but only if it hasn't already been discovered)
if (this._removeCompartment === false) {
for (var k = 0; k < s_cargo.length; k++) {
if (cmdtylist[j] === s_cargo[k].commodity) {
if (smuggling_found === true) {
// found!
msg += " - " + s_cargo[k].quantity + this.$getCommodityType(s_cargo[k].commodity) + " × " + displayNameForCommodity(s_cargo[k].commodity) + "\n";
// apply the bounty here, otherwise it won't get applied
p.setBounty(player.bounty + (s_cargo[k].quantity * goods[i].scale), "illegal imports");
//s_cargo[k].quantity = 0;
this._removeCompartment = true;
removecount += 1;
} else {
successcount += 1;
successmsg += (successmsg === "" ? "" : " and ") + displayNameForCommodity(s_cargo[k].commodity);
}
}
}
}
}
} else {
var found = false;
// for any visible cargo (ie not in the cargo hold) for which the player has a permit, we need to refund the bounty
for (var j = 0; j < cmdtylist.length; j++) {
// do we have any of this commodity in our hold?
if (p.manifest[cmdtylist[j]] > 0) {
p.setBounty(player.bounty - (p.manifest[cmdtylist[j]] * goods[i].scale), "import permit");
found = true;
} else {
// check that this cargo wasn't removed by the contracts system
for (var k = 0; k < this._dockIllegal.length; k++) {
if (this._dockIllegal[k].commodity === cmdtylist[j]) found = true;
}
}
// check hypercargo
var hyper = this.$checkHyperCargo(cmdtylist[j]);
if (hyper != "") {
found = true;
}
if (this._removeCompartment === false) {
for (var k = 0; k < s_cargo.length; k++) {
if (cmdtylist[j] === s_cargo[k].commodity && smuggling_found === true) {
// found
found = true;
}
}
}
}
// if we had permitted cargo,
if (found === true) {
permit_ok += (permit_ok === "" ? "" : ", ") + si.$translateCommodityList(goods[i].commodity);
permit_okcount += 1;
if (goods[i].commodity.indexOf(",") > 0) permit_okcount += 1;
// turn on flat to make sure a mission screen appears if we've adjusted the player's bounty
// otherwise the status screen will show an incorrect value in "Legal Status"
if (msgtype === 0) msgtype = 4;
// remove any permit whether it worked or not
si.$removePermit(system.ID, goods[i].commodity);
}
}
}
}
// special case: where we have illegal cargo just before docking, but don't now, and no permit.
// this would mean the contract system removed the cargo after docking
// we still need to give the player an opportunity to bribe their way to a clean slate.
if (msgtype === 0 && this._playerHadIllegals === true && this.$playerHasIllegalCargo(p.dockedStation) === false) {
msgtype = 6;
}
// found illegal cargo
if (msg != "") msgtype = 3;
// switch to the phase scanner message if that was detected but without any cargo
if (this._phaseScannerDetected === true) {
if (msgtype === 0 || msgtype === 4) msgtype = 5;
}
if (permit_list != "") permit_list = permit_list.replace(", ", " and ");
var msgTitle = "";
var msgBody = "";
var bigScreen = false;
switch (msgtype) {
case 0:
if (successcount > 0) {
msgTitle = "Smuggling Contraband";
msgBody = expandDescription("[smuggling-success]", {
cargo: successmsg
});
}
break;
case 1: //
msgTitle = "GalCop Customs Alert";
msgBody = expandDescription("[smuggling-fail-1]", {
size: this.$smugglingCompartmentSize()
}) +
(this._phaseScannerDetected === false ? "" : expandDescription("[phase-scanner-removal]")) +
expandDescription("[end-warning]");
break;
case 2:
msgTitle = "GalCop Customs Alert";
msgBody = expandDescription("[smuggling-fail-2]", {
size: this.$smugglingCompartmentSize(),
commodity: displayNameForCommodity(this._sc_VisibleAs)
}) +
(this._phaseScannerDetected === false ? "" : expandDescription("[phase-scanner-removal]")) +
expandDescription("[end-warning]");
break;
case 3:
var sections = 0;
if (permit_failed) sections += 1;
if (this._removeCompartment) sections += 1;
if (this._phaseScannerDetected) sections += 1;
if (sections === 3 || (sections === 2 && removecount > 4)) bigScreen = true;
msgTitle = "GalCop Customs Alert";
msgBody = expandDescription("[smuggling-fail-3]", {
insert: msg
}) +
(permit_failed === false ? "" :
"\n\nIt should be noted that the permit" + (permit_multi > 1 ? "s" : "") + " you had for " + permit_list + (permit_multi === 1 ? " was" : " were") +
" found to be " + (permit_multi > 1 ? "fabrications." : "a fabrication.")) +
(this._removeCompartment === false ? "" : expandDescription("[smuggling-compartment-removal]", {
size: this.$smugglingCompartmentSize()
})) +
(this._phaseScannerDetected === false ? "" : expandDescription("[phase-scanner-removal]")) +
expandDescription("[end-warning]");
break;
case 4:
msgTitle = "GalCop Customs";
msgBody = expandDescription("[smuggling_permit]", {
cargo: permit_ok,
permits: (permit_okcount === 1 ? "permit" : "permits")
});
break;
case 5:
msgTitle = "GalCop Customs Alert";
msgBody = expandDescription("[phase-scanner-removal-main]");
break;
case 6:
msgTitle = "GalCop Customs Alert";
msgBody = expandDescription("[smuggling-fail-4]");
break;
}
if (msgtype >= 1 && msgtype <= 6 && msgtype != 4) {
this._hudHidden = p.hudHidden;
if (bigScreen === true && this.$isBigGuiActive() === false) {
p.hudHidden = true;
this._smugglingScreen = true;
}
var curChoices = {};
curChoices["01_BRIBE"] = {
text: "[illegal-attempt-bribe]",
color: this._menuColor
};
curChoices["99_ACCEPT"] = {
text: "[illegal-accept-penalty]",
color: this._menuColor
};
this._bribeType = 1;
if (msgtype === 6) this._bribeType = 3;
var opts = {
screenID: "docking_with_illegals",
title: msgTitle,
message: msgBody,
allowInterrupt: false,
model: "[" + this._policeModel + "]",
exitScreen: "GUI_SCREEN_STATUS",
choices: curChoices,
initialChoicesKey: "99_ACCEPT"
};
mission.runScreen(opts, this.$bribeScreenHandler, this);
}
if (msgtype === 4 || (msgtype === 0 && successcount > 0)) {
mission.runScreen({
screenID: "dock_successful",
title: msgTitle,
message: msgBody,
model: "[" + this._policeModel + "]",
exitScreen: "GUI_SCREEN_STATUS"
});
}
}
}
//-------------------------------------------------------------------------------------------------------------
this.$bribeScreenHandler = function $bribeScreenHandler(choice) {
if (!choice) return;
if (choice === "99_ACCEPT") {
this.$processRemovals();
}
if (choice === "98_ACCEPT") {
this.$processEquipmentRemovals();
}
if (choice === "01_BRIBE") {
this.$getBribeAmount()
}
}
//-------------------------------------------------------------------------------------------------------------
// initialise the F4 screen entries
this.$initInterface = function $initInterface(station) {
if (this.$hasSmugglingCompartment() === true) {
station.setInterface(this.name, {
title: "Smuggling compartment configuration",
category: "Ship Systems",
summary: "Move cargo into or out of the smuggling compartment, and change the settings of the compartment",
callback: this.$showInitialSmugglingConfig.bind(this)
});
} else {
station.setInterface(this.name, null);
}
}
//-------------------------------------------------------------------------------------------------------------
// returns true if the smuggling compartment is damaged
this.$isCompartmentDamaged = function $isCompartmentDamaged() {
var eq = this.$getSmugglingCompartmentEquipment();
if (player.ship.equipmentStatus(eq) === "EQUIPMENT_DAMAGED") return true;
return false;
}
//-------------------------------------------------------------------------------------------------------------
// returns true if the smuggling compartment is installed
this.$hasSmugglingCompartment = function $hasSmugglingCompartment() {
for (var i = 1; i <= this._maxTonnage; i++) {
var check = player.ship.equipmentStatus("EQ_SMUGGLING_COMPARTMENT_" + i.toString());
if (check === "EQUIPMENT_OK" || check === "EQUIPMENT_DAMAGED") return true;
}
return false;
}
//-------------------------------------------------------------------------------------------------------------
// returns the equipment key of the installed compartment
this.$getSmugglingCompartmentEquipment = function $getSmugglingCompartmentEquipment() {
for (var i = 1; i <= this._maxTonnage; i++) {
var check = player.ship.equipmentStatus("EQ_SMUGGLING_COMPARTMENT_" + i.toString());
if (check === "EQUIPMENT_OK" || check === "EQUIPMENT_DAMAGED") return "EQ_SMUGGLING_COMPARTMENT_" + i.toString();
}
return "";
}
//-------------------------------------------------------------------------------------------------------------
// returns the max size of the current compartment
this.$smugglingCompartmentSize = function $smugglingCompartmentSize() {
for (var i = 1; i <= this._maxTonnage; i++) {
var check = player.ship.equipmentStatus("EQ_SMUGGLING_COMPARTMENT_" + i.toString());
if (check === "EQUIPMENT_OK" || check === "EQUIPMENT_DAMAGED") return i;
}
return 0;
}
//-------------------------------------------------------------------------------------------------------------
// returns true if the phase scanner is damaged, otherwise false
this.$isPhaseScannerDamaged = function $isPhaseScannerDamaged() {
if (player.ship.equipmentStatus("EQ_PHASE_SCANNER") === "EQUIPMENT_DAMAGED") return true;
return false;
}
//-------------------------------------------------------------------------------------------------------------
// returns true if the phase scanner is installed (even if damaged), otherwise false
this.$isPhaseScannerInstalled = function $isPhaseScannerInstalled() {
var check = player.ship.equipmentStatus("EQ_PHASE_SCANNER");
if (check === "EQUIPMENT_OK" || check === "EQUIPMENT_DAMAGED") return true;
return false;
}
//-------------------------------------------------------------------------------------------------------------
// resets smuggling compartment internal data after a compartment is removed
this.$resetCompartmentInfo = function $resetCompartmentInfo(station) {
var p = player.ship;
// move any cargo into the main hold
if (this._sc_Cargo.length > 0) {
for (var i = 0; i < this._sc_Cargo.length; i++) {
p.manifest[this._sc_Cargo[i].commodity] += this._sc_Cargo[i].quantity;
}
this._sc_Cargo = [];
}
this._sc_VisibleAs = "Food";
this._sc_Phase = 1;
this._sc_TechVersion = 1;
this.$initInterface(station);
}
//-------------------------------------------------------------------------------------------------------------
// returns the amount of used space in the compartment
this.$usedSpace = function $usedSpace() {
var t = 0.0;
for (var i = 0; i < this._sc_Cargo.length; i++) {
switch (this._sc_Cargo[i].unit) {
case "t":
t += this._sc_Cargo[i].quantity;
break;
case "kg":
t += (this._sc_Cargo[i].quantity / 1000);
break;
case "g":
t += (this._sc_Cargo[i].quantity / 1000000);
break;
}
}
return t;
}
//-------------------------------------------------------------------------------------------------------------
// returns the amount of available space in the compartment
this.$availableSpace = function $availableSpace() {
var total = this.$smugglingCompartmentSize();
return (total - this.$usedSpace());
}
//-------------------------------------------------------------------------------------------------------------
// clean up any zero amounts
this.$cargoCleanUp = function $cargoCleanUp() {
for (var i = this._sc_Cargo.length - 1; i >= 0; i--) {
if (this._sc_Cargo[i].quantity === 0) {
this._sc_Cargo.splice(i, 1);
}
}
}
//-------------------------------------------------------------------------------------------------------------
// shows the installation page to select a compartment size
this.$showPurchasePage = function $showPurchasePage() {
var curChoices = {};
var p = player.ship;
var stn = p.dockedStation;
var rowAdjust = 0;
var pagesize = 0;
//this._hudHidden = p.hudHidden;
if (this.$isBigGuiActive() === false) {
p.hudHidden = true;
}
this._smugglingScreen = true;
var text = expandDescription("[purchase-page-header]", {
cash: formatCredits(player.credits, true, true)
});
var curr_size = this.$smugglingCompartmentSize();
// what is the maximum allowed for this vessel (35% of available space, maxing out at 20t)
var shipmax = parseInt((p.cargoSpaceCapacity + curr_size) * 0.35);
// make sure we can get at least 1tc
if ((p.cargoSpaceCapacity + curr_size) > 0 && shipmax === 0) shipmax = 1;
// make sure we don't go over the 20 tc limit
if (shipmax > this._maxTonnage) shipmax = this._maxTonnage;
var max;
var check = (p.cargoSpaceAvailable + curr_size);
if (check < 0) {
max += check;
} else {
max = check;
}
if (max > this._maxTonnage) max = this._maxTonnage;
if (curr_size > 0) {
text += expandDescription("[downgrade-warning]");
rowAdjust += 2;
}
pagesize = 23 - rowAdjust;
var count = 0;
for (var i = 1; i <= this._maxTonnage; i++) {
var eq = EquipmentInfo.infoForKey("EQ_SMUGGLING_COMPARTMENT_" + i.toString());
var inst_time = ((600 + (eq.price * stn.equipmentPriceFactor)) / 60) / 60;
var price = (eq.price / 10) * stn.equipmentPriceFactor;
var menuitem = this.$padTextLeft(i + " t capacity", 6) + this.$padTextLeft(formatCredits(price, true, true), 7) + this.$padTextLeft(inst_time.toFixed(2) + " hours installation time", 15);
if (i <= shipmax) {
count += 1;
if (i != curr_size && i <= max && player.credits >= price) {
curChoices["01_HOLD_" + (i < 10 ? "0" : "") + i + "~" + i] = {
text: menuitem,
alignment: "LEFT",
color: this._menuColor
};
} else {
curChoices["01_HOLD_" + (i < 10 ? "0" : "") + i + "~" + i] = {
text: menuitem,
alignment: "LEFT",
color: this._disabledColor,
unselectable: true
};
}
}
}
curChoices["98_SPACER"] = "";
curChoices["99_EXIT"] = {
text: "[exit-no-change]",
color: this._itemColor
};
var def = "99_EXIT";
if ((count + 1) < pagesize) {
for (var i = (pagesize - (count + 1)); i > 0; i--) {
curChoices["99_SPACER_" + (i < 10 ? "0" : "") + i] = "";
}
}
var opts = {
screenID: "oolite-smuggling-purchase-map",
title: "Smuggling Compartment Installation",
allowInterrupt: true,
overlay: {
name: "stgu-cupboard.png",
height: 546
},
exitScreen: "GUI_SCREEN_EQUIP_SHIP",
choices: curChoices,
initialChoicesKey: def,
message: text
};
mission.runScreen(opts, this.$purchaseScreenHandler, this);
}
//-------------------------------------------------------------------------------------------------------------
this.$purchaseScreenHandler = function $purchaseScreenHandler(choice) {
if (!choice) return;
if (choice.indexOf("01_HOLD") >= 0) {
var p = player.ship;
var stn = p.dockedStation;
var newsize = parseInt(choice.substring(choice.indexOf("~") + 1));
var newEq = this._equipmentList[newsize - 1];
var oldEq = this.$getSmugglingCompartmentEquipment();
// truncate any existing cargo
if (newsize < this.$usedSpace()) {
var diff = this.$usedSpace - newsize;
do {
for (var i = this._sc_Cargo.length; i >= 0; i--) {
if (diff > 0) {
switch (this._sc_Cargo[i].unit) {
case "t":
this._sc_Cargo[i].quantity -= 1;
diff -= 1;
break;
case "kg":
if (this._sc_Cargo[i].quantity > 1000) {
this._sc_Cargo[i].quantity -= 1000;
diff -= 1;
}
break;
case "g":
if (this._sc_Cargo[i].quantity > 1000000) {
this._sc_Cargo[i].quantity -= 1000000;
diff -= 1;
}
}
}
}
} while (diff > 0);
this.$cargoCleanUp();
}
// remove the old one (if present)
if (oldEq != "") {
this._backdoor = true;
p.removeEquipment(oldEq);
this._backdoor = false;
// refund the price of the old version
var oldEqInfo = EquipmentInfo.infoForKey(oldEq);
player.credits += ((oldEqInfo.price / 10) * stn.equipmentPriceFactor);
}
// install the new one
p.awardEquipment(newEq);
p.awardEquipment("EQ_SMUGGLING_INFLIGHT_STORAGE");
var eq = EquipmentInfo.infoForKey(newEq);
var inst_time = 600 + (eq.price * stn.equipmentPriceFactor);
var price = (eq.price / 10) * stn.equipmentPriceFactor;
// charge the player
player.credits -= price;
// add the smuggler role to the player
player.setPlayerRole("trader-smuggler");
// apply the install time
clock.addSeconds(inst_time);
// if StationDockControl is installed, tell it to check for launched ships and repopulate
var sdc = worldScripts.StationDockControl;
if (sdc && sdc._disable === false) sdc.$checkForLaunchedShips();
this.$initInterface(stn);
this._sc_Days = 0;
// make sure the right email is sent to the player
var email = worldScripts.GalCopAdminServices;
if (email) {
email._boughtKey = newEq;
email.$playerBoughtEquip();
}
}
}
//-------------------------------------------------------------------------------------------------------------
// initial entry point for the smuggling compartment config screen
this.$showInitialSmugglingConfig = function $showInitialSmugglingConfig() {
this._display = 0;
this.$showSmugglingConfig();
}
//-------------------------------------------------------------------------------------------------------------
// main config screen display
this.$showSmugglingConfig = function $showSmugglingConfig() {
function compare(a, b) {
if ((a.gov * 100) + a.tl < (b.gov * 100) + b.tl) return -1;
if ((a.gov * 100) + a.tl > (b.gov * 100) + b.tl) return 1;
return 0;
}
var text = "";
var curChoices = {};
var p = player.ship;
var pagesize = 26;
var phaseSetting = false;
if (p.equipmentStatus("EQ_SMUGGLING_PHASE_ADJUSTMENT") === "EQUIPMENT_OK") phaseSetting = true;
this._hudHidden = p.hudHidden;
if (this.$isBigGuiActive() === false) p.hudHidden = true;
this._smugglingScreen = true;
if (this.$isCompartmentDamaged() === true) this._display = 10;
// main display
if (this._display === 0) {
var lines = 5;
text = expandDescription("[total-capacity-header]") + this.$smugglingCompartmentSize() + "t " + Math.floor(this.$usedSpace()) + "t used.\n";
text += expandDescription("[visible-as-header]") + displayNameForCommodity(this._sc_VisibleAs) + " ";
if (phaseSetting) text += "Phase: " + this._sc_Phase + " mHz ";
text += expandDescription("[tech-version-header]") + this._sc_TechVersion + ".0\n";
if (this._sc_Days >= 20) {
text += expandDescription("[tech-version-warning]");
lines += 1;
}
text += "\n";
lines += 6;
if (phaseSetting === false) lines -= 1;
var cargo = this.$getSmugglingCargo();
if (cargo.length > 0) {
text += expandDescription("[smuggling-current-contents]");
lines += 1;
var additem = "";
for (var i = 0; i < this._sc_Cargo.length; i++) {
if (additem === "") {
additem += " " + this.$padTextRight(this._sc_Cargo[i].quantity + this._sc_Cargo[i].unit + " × " + displayNameForCommodity(this._sc_Cargo[i].commodity) + (this._sc_Cargo[i].extra != "" ? "*" : ""), 17);
} else {
additem += this._sc_Cargo[i].quantity + this._sc_Cargo[i].unit + " × " + displayNameForCommodity(this._sc_Cargo[i].commodity) + (this._sc_Cargo[i].extra != "" ? "*" : "");
text += additem + "\n";
lines += 1;
additem = "";
}
}
if (additem != "") {
text += additem + "\n";
lines += 1;
}
} else {
text += expandDescription("[smuggling-no-contents]");
lines += 2;
}
if (phaseSetting) {
curChoices["01_SET_PHASE"] = {
text: "[smuggling-set-phase]",
color: this._menuColor
};
}
curChoices["02_VIEW_DISCOVERED"] = {
text: "[smuggling-view-phase]",
color: this._menuColor
};
curChoices["03_SET_VISIBLE"] = {
text: "[smuggling-set-visible-as]",
color: this._menuColor
};
var avail = this.$availableSpace();
var used = this.$usedSpace();
if (this.$playerHasCargo() === true && avail > 0) {
curChoices["04_MOVE_CARGO_IN"] = {
text: "[smuggling-move-in]",
color: this._menuColor
};
} else {
curChoices["04_MOVE_CARGO_IN"] = {
text: "[smuggling-move-in]",
color: this._disabledColor,
unselectable: true
};
}
if (used > 0) {
curChoices["05_MOVE_CARGO_OUT"] = {
text: "[smuggling-move-out]",
color: this._menuColor
};
} else {
curChoices["05_MOVE_CARGO_OUT"] = {
text: "[smuggling-move-out]",
color: this._disabledColor,
unselectable: true
};
}
if (used > 0) {
curChoices["06_SELL_CARGO"] = {
text: "[smuggling-sell-from]",
color: this._menuColor
};
} else {
curChoices["06_SELL_CARGO"] = {
text: "[smuggling-sell-from]",
color: this._disabledColor,
unselectable: true
};
}
if (avail > 0) {
curChoices["07_BUY_CARGO"] = {
text: "[smuggling-buy-in]",
color: this._menuColor
};
} else {
curChoices["07_BUY_CARGO"] = {
text: "[smuggling-buy-in]",
color: this._disabledColor,
unselectable: true
};
}
//curChoices["70_SPACER"] = "";
curChoices["99_EXIT"] = {
text: "[smuggling-exit-config]",
color: this._itemColor
};
pagesize = 26;
if (lines < pagesize) {
for (var i = (pagesize - lines); i > 0; i--) {
curChoices["99_SPACER_" + (i < 10 ? "0" : "") + i] = "";
}
}
var def = "99_EXIT";
var opts = {
screenID: "oolite-smuggling-config-summary",
title: "Smuggling Compartment Configuration",
allowInterrupt: true,
overlay: {
name: "stgu-cupboard.png",
height: 546
},
exitScreen: "GUI_SCREEN_INTERFACES",
choices: curChoices,
initialChoicesKey: def,
message: text
};
}
// set visible property
if (this._display === 1) {
text = expandDescription("[visible-as-property]", {
commodity: displayNameForCommodity(this._sc_VisibleAs)
});
for (var i = 0; i < this._commodityIDList.length; i++) {
if (this._sc_VisibleAs === this._commodityIDList[i]) {
curChoices["40_" + (i < 10 ? "0" : "") + i + "~" + this._commodityIDList[i]] = {
text: displayNameForCommodity(this._commodityIDList[i]),
color: this._disabledColor,
unselectable: true
};
} else {
curChoices["40_" + (i < 10 ? "0" : "") + i + "~" + this._commodityIDList[i]] = {
text: displayNameForCommodity(this._commodityIDList[i]),
color: this._menuColor
};
}
}
curChoices["97_SPACER"] = "";
curChoices["98_EXIT"] = {
text: "[exit-no-change]",
color: this._itemColor
};
def = "98_EXIT";
var opts = {
screenID: "oolite-smuggling-config-map",
title: "Smuggling Compartment Configuration",
allowInterrupt: true,
overlay: {
name: "stgu-cupboard.png",
height: 546
},
exitScreen: "GUI_SCREEN_INTERFACES",
choices: curChoices,
initialChoicesKey: def,
message: text
};
}
if (this._display === 2) { // move cargo in
// todo: deal with new cargoes
var avail = this.$availableSpace();
text = expandDescription("[move-cargo-in]", {
smuggling: Math.floor(avail),
standard: p.cargoSpaceAvailable
});
pagesize = 20;
var cargo = p.manifest.list;
var sdm = worldScripts.Smugglers_DockMaster;
var itemcount = 0;
for (var i = 0; i < cargo.length; i++) {
// only show standard (non-OXP) commodity items
if (this._commodityIDList.indexOf(cargo[i].commodity) >= 0) {
var q = cargo[i].quantity;
// make sure we don't move relabelled cargo
if (sdm._cargoLabelled.length > 0) {
for (var j = 0; j < sdm._cargoLabelled.length; j++) {
if (sdm._cargoLabelled[j].newCommodity === cargo[i].commodity) q -= sdm._cargoLabelled[j].quantity;
}
}
// don't allow scooped escape pods to be moved
if (cargo[i].commodity === "slaves" && cargo[i].quantity > 0 && worldScripts.EscapePodTweaks && worldScripts.EscapePodTweaks._heldPods.length > 0) {
q -= worldScripts.EscapePodTweaks._heldPods;
}
if (q > 0) {
curChoices["50_" + (i < 10 ? "0" : "") + i + "_CARGO~" + cargo[i].commodity] = {
text: cargo[i].displayName + " (" + q + cargo[i].unit + ")" + (this.$calcCTEcargo(cargo[i].commodity) > 0 ? "*" : ""),
color: this._menuColor
};
itemcount += 1;
}
}
}
curChoices["97_SPACER"] = "";
curChoices["98_EXIT"] = {
text: "[illegal-return]",
color: this._itemColor
};
for (var i = 1; i <= (pagesize - itemcount); i++) {
curChoices["99_SPACER_" + (i < 10 ? "0" : "") + i] = "";
}
def = "98_EXIT";
var opts = {
screenID: "oolite-smuggling-movecargoin-map",
title: "Smuggling Compartment Cargo",
allowInterrupt: true,
overlay: {
name: "stgu-cupboard.png",
height: 546
},
exitScreen: "GUI_SCREEN_INTERFACES",
choices: curChoices,
initialChoicesKey: def,
message: text
};
}
if (this._display === 3) { // move cargo out
// todo: deal with new cargoes
var avail = this.$availableSpace();
text = expandDescription("[move-cargo-out]", {
smuggling: Math.floor(avail),
standard: p.cargoSpaceAvailable
});
pagesize = 20;
var cargo = this.$getSmugglingCargo();
for (var i = 0; i < cargo.length; i++) {
if ((p.cargoSpaceAvailable === 0 && cargo[i].unit != "t") || p.cargoSpaceAvailable > 0) {
curChoices["51_" + (i < 10 ? "0" : "") + i + "_CARGO~" + cargo[i].commodity] = {
text: cargo[i].quantity + " " + cargo[i].unit + " × " + cargo[i].displayName + (cargo[i].extra != "" ? "*" : ""),
color: this._menuColor
};
}
}
curChoices["97_SPACER"] = "";
curChoices["98_EXIT"] = {
text: "[illegal-return]",
color: this._itemColor
};
for (var i = 1; i <= (pagesize - cargo.length); i++) {
curChoices["99_SPACER_" + (i < 10 ? "0" : "") + i] = "";
}
def = "98_EXIT";
var opts = {
screenID: "oolite-smuggling-movecargoout-map",
title: "Smuggling Compartment Cargo",
allowInterrupt: true,
overlay: {
name: "stgu-cupboard.png",
height: 546
},
exitScreen: "GUI_SCREEN_INTERFACES",
choices: curChoices,
initialChoicesKey: def,
message: text
};
}
if (this._display === 4) { // view discovered phase settings
// look for and remove any TL0 items in the list
// why are we doing this???
//for (var i = this._phaseScanDiscovery.length - 1; i >= 0; i--) {
// if (this._phaseScanDiscovery[i].tl === 0) {
// this._phaseScanDiscovery.splice(i, 1);
// }
//}
// sort the list by government/techlevel
this._phaseScanDiscovery.sort(compare);
var govs = new Array();
for (var i = 0; i < 8; i++)
govs.push(String.fromCharCode(i));
var spc = String.fromCharCode(31);
text = expandDescription("[discovered-phase-scans]");
if (this._phaseScanDiscovery.length === 0) {
text += " None";
} else {
for (var i = 0; i < 24; i++) {
if (this._phaseScanDiscovery.length - 1 >= i && this._phaseScanDiscovery[i].phase != 0) {
text += this.$padTextRight(govs[this._phaseScanDiscovery[i].gov] + spc + "TL" + (this._phaseScanDiscovery[i].tl + 1) + ":", 3.7) + this.$padTextRight(this._phaseScanDiscovery[i].phase, 3);
}
if (this._phaseScanDiscovery.length - 1 >= (i + 24) && this._phaseScanDiscovery[i + 24].phase != 0) {
text += this.$padTextRight(govs[this._phaseScanDiscovery[i + 24].gov] + spc + "TL" + (this._phaseScanDiscovery[i + 24].tl + 1) + ":", 3.7) + this.$padTextRight(this._phaseScanDiscovery[i + 24].phase, 3);
}
if (this._phaseScanDiscovery.length - 1 >= (i + 48) && this._phaseScanDiscovery[i + 48].phase != 0) {
text += this.$padTextRight(govs[this._phaseScanDiscovery[i + 48].gov] + spc + "TL" + (this._phaseScanDiscovery[i + 48].tl + 1) + ":", 3.7) + this.$padTextRight(this._phaseScanDiscovery[i + 48].phase, 3);
}
if (this._phaseScanDiscovery.length - 1 >= (i + 72) && this._phaseScanDiscovery[i + 72].phase != 0) {
text += this.$padTextRight(govs[this._phaseScanDiscovery[i + 72].gov] + spc + "TL" + (this._phaseScanDiscovery[i + 72].tl + 1) + ":", 3.7) + this.$padTextRight(this._phaseScanDiscovery[i + 72].phase, 3);
}
if (this._phaseScanDiscovery.length - 1 >= (i + 96) && this._phaseScanDiscovery[i + 96].phase != 0) {
text += this.$padTextRight(govs[this._phaseScanDiscovery[i + 96].gov] + spc + "TL" + (this._phaseScanDiscovery[i + 96].tl + 1) + ":", 3.7) + this._phaseScanDiscovery[i + 96].phase;
}
text += "\n";
}
}
curChoices["98_EXIT"] = {
text: "[illegal-return]",
color: this._itemColor
};
def = "98_EXIT";
var opts = {
screenID: "oolite-smuggling-discovered-map",
title: "Smuggling Compartment Configuration",
allowInterrupt: true,
overlay: {
name: "stgu-cupboard.png",
height: 546
},
exitScreen: "GUI_SCREEN_INTERFACES",
choices: curChoices,
initialChoicesKey: def,
message: text
};
}
// sell cargo from compartment
if (this._display === 5) {
// deal with new cargoes
text = expandDescription("[sell-smuggling-cargo]");
pagesize = 23;
if (this._extraMessage) {
text += "\n(Note: " + this._extraMessage + ")";
pagesize -= 1;
delete this._extraMessage;
}
var cargo = this.$getSmugglingCargo();
var mkt = p.dockedStation.market;
for (var i = 0; i < cargo.length; i++) {
curChoices["52_" + (i < 10 ? "0" : "") + i + "_CARGO~" + cargo[i].commodity] = {
text: this.$padTextRight(cargo[i].quantity + " " + cargo[i].unit + " × " + cargo[i].displayName, 12) +
(cargo[i].extra != "" ? "*" : "") +
this.$padTextLeft(formatCredits((mkt[cargo[i].commodity].price / 10), true, true), 5),
color: this._menuColor
};
}
curChoices["97_SPACER"] = "";
curChoices["98_EXIT"] = {
text: "[illegal-return]",
color: this._itemColor
};
for (var i = 1; i <= (pagesize - cargo.length); i++) {
curChoices["99_SPACER_" + (i < 10 ? "0" : "") + i] = "";
}
def = "98_EXIT";
var opts = {
screenID: "oolite-smuggling-sellcargo-map",
title: "Smuggling Compartment Sell Cargo",
allowInterrupt: true,
overlay: {
name: "stgu-cupboard.png",
height: 546
},
exitScreen: "GUI_SCREEN_INTERFACES",
choices: curChoices,
initialChoicesKey: def,
message: text
};
}
// buy cargo directly to compartment
if (this._display === 6) {
text = expandDescription("[buy-smuggling-cargo]");
pagesize = 23;
if (this._insufficientFunds && this._insufficientFunds === true) {
text += "\n(Note: Insufficient funds to purchase " + displayNameForCommodity(this._tfrCargo) + ".)";
pagesize = 22;
}
var mkt = p.dockedStation.market;
var itemorder = 0;
var itemcount = 0;
for (var i in mkt) {
if (this._commodityIDList.indexOf(i) >= 0) {
if (mkt[i].quantity > 0) {
itemorder = parseInt(mkt[i].sort_order / 100);
curChoices["53_" + (itemorder < 10 ? "0" : "") + itemorder + "_CARGO~" + i] = {
text: this.$padTextRight(displayNameForCommodity(i), 8) +
this.$padTextLeft(formatCredits((mkt[i].price / 10), true, true), 4) +
this.$padTextLeft(mkt[i].quantity, 4) + " " +
this.$padTextRight(this.$getCommodityType(i), 2),
color: this._menuColor
};
itemcount += 1;
}
}
}
curChoices["97_SPACER"] = "";
curChoices["98_EXIT"] = {
text: "[illegal-return]",
color: this._itemColor
};
for (var i = 1; i <= (pagesize - itemcount); i++) {
curChoices["99_SPACER_" + (i < 10 ? "0" : "") + i] = "";
}
def = "98_EXIT";
var opts = {
screenID: "oolite-smuggling-buycargo-map",
title: "Smuggling Compartment Buy Cargo",
allowInterrupt: true,
overlay: {
name: "stgu-cupboard.png",
height: 546
},
exitScreen: "GUI_SCREEN_INTERFACES",
choices: curChoices,
initialChoicesKey: def,
message: text
};
}
if (this._display === 10) {
text = expandDescription("[smuggling-compartment-damaged]");
curChoices["99_EXIT"] = {
text: "[smuggling-exit-config]",
color: this._itemColor
};
var opts = {
screenID: "smuggling_compartment_damaged",
title: "Smuggling Compartment Configuration",
message: text,
choices: curChoices,
overlay: {
name: "stgu-lock.png",
height: 546
},
exitScreen: "GUI_SCREEN_INTERFACES"
};
}
mission.runScreen(opts, this.$configScreenHandler, this);
}
//-------------------------------------------------------------------------------------------------------------
this.$configScreenHandler = function $configScreenHandler(choice) {
if (!choice) return;
switch (choice) {
case "01_SET_PHASE":
this.$setPhase();
break;
case "02_VIEW_DISCOVERED":
this._display = 4;
break;
case "03_SET_VISIBLE":
this._display = 1;
break;
case "04_MOVE_CARGO_IN":
this._display = 2;
break;
case "05_MOVE_CARGO_OUT":
this._display = 3;
break;
case "06_SELL_CARGO":
this._display = 5;
break;
case "07_BUY_CARGO":
this._display = 6;
break;
case "98_EXIT":
this._display = 0;
break;
}
if (choice.indexOf("40_") >= 0) {
this._sc_VisibleAs = choice.substring(choice.indexOf("~") + 1);
this._display = 0;
}
var showMain = true;
if (choice.indexOf("50_") >= 0) {
showMain = false;
this._tfrCargo = choice.substring(choice.indexOf("~") + 1);
var cargo = player.ship.manifest.list;
var sdm = worldScripts.Smugglers_DockMaster;
for (var i = 0; i < cargo.length; i++) {
if (cargo[i].commodity === this._tfrCargo) {
var q = cargo[i].quantity;
// make sure we don't move relabelled cargo
if (sdm._cargoLabelled.length > 0) {
for (var j = 0; j < sdm._cargoLabelled.length; j++) {
if (sdm._cargoLabelled[j].newCommodity === cargo[i].commodity) q -= sdm._cargoLabelled[j].quantity;
}
}
// don't allow scooped escape pods to be moved
if (cargo[i].commodity === "slaves" && cargo[i].quantity > 0 && worldScripts.EscapePodTweaks && worldScripts.EscapePodTweaks._heldPods.length > 0) {
q -= worldScripts.EscapePodTweaks._heldPods;
}
this._tfrCargoName = cargo[i].displayName;
this._tfrMaxAmount = q;
this._tfrUnit = cargo[i].unit;
this._tfrExtra = this.$calcCTEcargo(cargo[i].commodity).toString();
var avail = this.$smugglingCompartmentSize();
var used = this.$usedSpace();
// make sure our max amount set isn't greater than the cargo space limit
switch (this._tfrUnit) {
case "t":
if (this._tfrMaxAmount > (avail - used)) {
this._tfrMaxAmount = avail - used;
}
break;
case "kg":
var sub_avail = avail * 1000;
var sub_used = used * 1000;
if (this._tfrMaxAmount > (sub_avail - sub_used)) this._tfrMaxAmount = sub_avail - sub_used;
break;
case "g":
var sub_avail = avail * 1000000;
var sub_used = used * 1000000;
if (this._tfrMaxAmount > (sub_avail - sub_used)) this._tfrMaxAmount = sub_avail - sub_used;
break;
}
this.$getTransferAmount(1);
}
}
}
if (choice.indexOf("51_") >= 0) {
showMain = false;
this._tfrCargo = choice.substring(choice.indexOf("~") + 1);
var cargo = this.$getSmugglingCargo();
for (var i = 0; i < cargo.length; i++) {
if (cargo[i].commodity === this._tfrCargo) {
this._tfrCargoName = cargo[i].displayName;
this._tfrMaxAmount = cargo[i].quantity;
this._tfrUnit = cargo[i].unit;
this._tfrExtra = cargo[i].extra.split(";").length.toString();
var avail = player.ship.cargoSpaceAvailable;
// make sure our max amount set isn't greater than the cargo space limit
switch (this._tfrUnit) {
case "t":
if (this._tfrMaxAmount > avail) this._tfrMaxAmount = avail;
break;
case "kg":
var sub_avail = avail * 1000;
if (this._tfrMaxAmount > sub_avail) this._tfrMaxAmount = sub_avail;
break;
case "g":
var sub_avail = avail * 1000000;
if (this._tfrMaxAmount > sub_avail) this._tfrMaxAmount = sub_avail;
break;
}
this.$getTransferAmount(2);
}
}
}
if (choice.indexOf("52_") >= 0) {
showMain = false;
this._tfrCargo = choice.substring(choice.indexOf("~") + 1);
var cargo = this.$getSmugglingCargo();
for (var i = 0; i < cargo.length; i++) {
if (cargo[i].commodity === this._tfrCargo) {
this._tfrCargoName = cargo[i].displayName;
this._tfrMaxAmount = cargo[i].quantity;
this._tfrExtra = cargo[i].extra.split(";").length.toString();
var stn = player.ship.dockedStation;
// limit the max amount by the market capacity
var check = stn.market[this._tfrCargo].capacity - stn.market[this._tfrCargo].quantity;
if (this._tfrMaxAmount > check) this._tfrMaxAmount = check;
// if the max amount we can transfer is zero, return to the previous menu.
if (this._tfrMaxAmount === 0) {
this._extraMessage = "Market capacity reached - no more " + cargo[i].displayName + " can be sold.";
this.$showSmugglingConfig();
return;
}
this._tfrUnit = cargo[i].unit;
this.$getTransferAmount(3);
}
}
}
if (choice.indexOf("53_") >= 0) {
showMain = false;
this._insufficientFunds = false;
this._tfrCargo = choice.substring(choice.indexOf("~") + 1);
var cargoItem = player.ship.dockedStation.market[this._tfrCargo];
this._tfrCargoName = displayNameForCommodity(this._tfrCargo);
this._tfrUnit = this.$getCommodityType(this._tfrCargo);
this._tfrMaxAmount = cargoItem.quantity;
this._tfrExtra = "";
var avail = this.$availableSpace();
switch (this._tfrUnit) {
case "t":
if (avail < this._tfrMaxAmount) this._tfrMaxAmount = avail;
break;
case "kg":
var sub_avail = avail * 1000;
if (sub_avail < this._tfrMaxAmount) this._tfrMaxAmount = sub_avail;
break;
case "g":
var sub_avail = avail * 1000000;
if (sub_avail < this._tfrMaxAmount) this._tfrMaxAmount = sub_avail;
break;
}
if ((this._tfrMaxAmount * (cargoItem.price / 10)) > player.credits) {
do {
this._tfrMaxAmount -= 1;
} while ((this._tfrMaxAmount * (cargoItem.price / 10)) > player.credits)
}
if (this._tfrMaxAmount > 0) {
this.$getTransferAmount(4);
} else {
showMain = true;
this._insufficientFunds = true;
}
}
if (choice != "99_EXIT" && choice != "01_SET_PHASE" && showMain === true) {
this.$showSmugglingConfig();
}
}
//-------------------------------------------------------------------------------------------------------------
// returns true if the player has any cargo at all
this.$playerHasCargo = function $playerHasCargo() {
var m = player.ship.manifest;
for (var i = 0; i < m.list.length; i++) {
if (m.list[i].quantity > 0) return true;
}
return false;
}
//-------------------------------------------------------------------------------------------------------------
// returns true if the player has any illegal cargo in the visible cargo hold
this.$playerHasIllegalCargo = function $playerHasIllegalCargo(station) {
var m = player.ship.manifest;
for (var i = 0; i < m.list.length; i++) {
if (m.list[i].quantity > 0 && station.market[m.list[i].commodity].legality_import > 0) {
return true;
}
}
return false;
}
//-------------------------------------------------------------------------------------------------------------
// returns true if the player has any illegal cargo in their smuggling compartment
this.$playerHasHiddenIllegalCargo = function $playerHasHiddenIllegalCargo(station) {
var c = this.$getSmugglingCargo();
var found = false;
for (var i = 0; i < c.length; i++) {
if (station.market[c[i].commodity].legality_import > 0) found = true;
}
return found;
}
//-------------------------------------------------------------------------------------------------------------
// prompts the user for a new phase
this.$setPhase = function $setPhase() {
var text = "";
text = expandDescription("[set-phase]", {
current: this._sc_Phase
});
var opts = {
screenID: "oolite-smuggling-setphase-map",
title: "Smuggling Compartment Configuration",
allowInterrupt: false,
exitScreen: "GUI_SCREEN_INTERFACES",
message: text,
textEntry: true
};
mission.runScreen(opts, this.$getNewPhase, this);
}
//-------------------------------------------------------------------------------------------------------------
// parses the input from the setPhase screen
this.$getNewPhase = function $getNewPhase(param) {
if (parseInt(param) >= 1 && parseInt(param) <= 999) {
this._sc_Phase = parseInt(param);
}
this.$showSmugglingConfig();
}
//-------------------------------------------------------------------------------------------------------------
// prompts the user for the transfer amount
this.$getTransferAmount = function $getTransferAmount(type) {
var text = "";
// don't show a screen when only 1 unit is possible
if (this._tfrMaxAmount === 1) {
switch (type) {
case 1:
this.$getCargoTransferIn(1);
return;
case 2:
this.$getCargoTransferOut(1);
return;
case 3:
this.$getCargoSell(1);
return;
case 4:
this.$getCargoBuy(1);
return;
}
}
switch (type) {
case 1:
text = expandDescription("[enter-quantity-smuggling]", {
commodity: this._tfrCargoName,
quantity: parseInt(this._tfrMaxAmount),
cte_note: (this._tfrExtra != "" ? "\n\nNote: " + this._tfrExtra + " units of this cargo comes from the specialty market." : "")
});
break;
case 2:
text = expandDescription("[enter-quantity-standard]", {
commodity: this._tfrCargoName,
quantity: parseInt(this._tfrMaxAmount),
cte_note: (this._tfrExtra != "" ? "\n\nNote: " + this._tfrExtra + " units of this cargo comes from the specialty market." : "")
});
break;
case 3:
text = expandDescription("[enter-quantity-sell]", {
commodity: this._tfrCargoName,
quantity: parseInt(this._tfrMaxAmount),
cte_note: (this._tfrExtra != "" ? "\n\nNote: " + this._tfrExtra + " units of this cargo comes from the specialty market." : "")
});
break;
case 4:
text = expandDescription("[enter-quantity-buy]", {
commodity: this._tfrCargoName,
quantity: parseInt(this._tfrMaxAmount)
});
break;
}
var opts = {
screenID: "oolite-smuggling-transfer-map",
title: "Smuggling Compartment Cargo",
allowInterrupt: false,
exitScreen: "GUI_SCREEN_INTERFACES",
message: text,
textEntry: true
};
switch (type) {
case 1:
mission.runScreen(opts, this.$getCargoTransferIn, this);
break;
case 2:
mission.runScreen(opts, this.$getCargoTransferOut, this);
break;
case 3:
mission.runScreen(opts, this.$getCargoSell, this);
break;
case 4:
mission.runScreen(opts, this.$getCargoBuy, this);
break;
}
}
//-------------------------------------------------------------------------------------------------------------
// parses the input from the getTransferAmount screen
this.$getCargoTransferIn = function $getCargoTransferIn(param) {
if (!param) {
this.$showSmugglingConfig();
return;
}
if (parseInt(param) >= 1 && parseInt(param) <= this._tfrMaxAmount) {
var p = player.ship;
var max = p.manifest[this._tfrCargo];
var amount = parseInt(param);
var extra = "";
if (this._NCInstalled) {
extra = this.$extractCargoFromCTE(this._tfrCargo, amount, max);
}
this.$addCargoToCompartment(this._tfrCargo, this._tfrCargoName, amount, this._tfrUnit, extra);
// take the cargo out of the hold
var p = player.ship;
p.manifest[this._tfrCargo] -= amount;
}
this._display = 2;
if (this.$availableSpace() === 0) this._display = 0;
this.$showSmugglingConfig();
}
//-------------------------------------------------------------------------------------------------------------
this.$calcCTEcargo = function (generic) {
var cte = worldScripts.CargoTypeExtension;
// if there isn't enough generic cargo of a particular type
// throw out special cargo entries of that type until there is
var totalspecial = 0;
for (var j = 0; j < cte.specialCargoCarried[generic].length; j++) {
if (cte.specialCargoRegister[cte.specialCargoCarried[generic][j].type]) {
totalspecial += cte.specialCargoCarried[generic][j].quantity;
}
}
return totalspecial;
}
//-------------------------------------------------------------------------------------------------------------
// parses the input from the getTransferAmount screen
this.$getCargoTransferOut = function $getCargoTransferOut(param) {
if (!param) {
this.$showSmugglingConfig();
return;
}
if (parseInt(param) >= 1 && parseInt(param) <= this._tfrMaxAmount) {
var p = player.ship;
var amount = parseInt(param);
var starting = p.manifest[this._tfrCargo];
// put the cargo into the main hold
p.manifest[this._tfrCargo] += amount;
// check that the hold actually took all the amount
if (p.manifest[this._tfrCargo] != (starting + amount)) {
// if not, adjust the amount of transfer
amount = p.manifest[this._tfrCargo] - starting;
}
for (var i = 0; i < this._sc_Cargo.length; i++) {
if (this._sc_Cargo[i].commodity === this._tfrCargo) {
if (this._NCInstalled) {
var ncmanifest = this.$checkForAndRemoveCTECargo(this._tfrCargo, amount);
if (ncmanifest != "") {
var cte = worldScripts.CargoTypeExtension;
cte.mergePlayerManifest(ncmanifest);
}
}
this._sc_Cargo[i].quantity -= amount;
break;
}
}
this.$cargoCleanUp();
}
this._display = 3;
if (this.$usedSpace() === 0) this._display = 0;
this.$showSmugglingConfig();
}
//-------------------------------------------------------------------------------------------------------------
// parses the input from the getTransferAmount screen
this.$getCargoSell = function $getCargoSell(param) {
if (!param) {
this.$showSmugglingConfig();
return;
}
if (parseInt(param) >= 1 && parseInt(param) <= this._tfrMaxAmount) {
var amount = parseInt(param);
var count = 0;
var check = 0;
var p = player.ship;
var stn = p.dockedStation;
var mkt = stn.market;
for (var i = this._sc_Cargo.length - 1; i >= 0; i--) {
if (this._sc_Cargo[i].commodity === this._tfrCargo) {
check = mkt[this._tfrCargo].quantity;
var newamount = check + amount;
var actual = amount;
// check that we aren't going over the market capacity
if (newamount > mkt[this._tfrCargo].capacity) {
newamount = mkt[this._tfrCargo].capacity;
actual = newamount - check;
}
// only do an sell if the actual amount that can be sold is greater than zero
if (actual > 0) {
stn.setMarketQuantity(this._tfrCargo, newamount);
this.$checkForAndRemoveCTECargo(this._tfrCargo, actual);
this._sc_Cargo[i].quantity -= actual;
count += actual;
player.credits += (mkt[this._tfrCargo].price / 10) * actual;
this.$playSound("sell");
}
break;
}
}
this.$cargoCleanUp();
}
this._display = 5;
if (this.$usedSpace() === 0) this._display = 0;
this.$showSmugglingConfig();
}
//-------------------------------------------------------------------------------------------------------------
// parses the input from the getTransferAmount screen
this.$getCargoBuy = function $getCargoBuy(param) {
if (!param) {
this.$showSmugglingConfig();
return;
}
if (parseInt(param) >= 1 && parseInt(param) <= this._tfrMaxAmount) {
var amount = parseInt(param);
this.$addCargoToCompartment(this._tfrCargo, this._tfrCargoName, amount, this._tfrUnit, "");
// take the cargo out of the market
var stn = player.ship.dockedStation;
var mkt = stn.market;
var newamount = mkt[this._tfrCargo].quantity - amount;
stn.setMarketQuantity(this._tfrCargo, newamount);
player.credits -= (mkt[this._tfrCargo].price / 10) * amount;
this.$playSound("buy");
}
this._display = 6;
if (this.$availableSpace() === 0) this._display = 0;
this.$showSmugglingConfig();
}
//-------------------------------------------------------------------------------------------------------------
// adds cargo to smuggling compartment
this.$addCargoToCompartment = function $addCargoToCompartment(cmdty, name, amount, unit, extra) {
var found = false;
for (var i = 0; i < this._sc_Cargo.length; i++) {
if (this._sc_Cargo[i].commodity === cmdty) {
// found it
found = true;
this._sc_Cargo[i].quantity += amount;
if (extra != "") {
if (this._sc_Cargo[i].extra == "") {
this._sc_Cargo[i].extra = extra;
} else {
this._sc_Cargo[i].extra += ";" + extra;
}
}
}
}
if (found === false) {
this._sc_Cargo.push({
commodity: cmdty,
displayName: name,
quantity: amount,
unit: unit,
extra: extra
});
}
}
//-------------------------------------------------------------------------------------------------------------
// create system phases
this.$createSystemPhase = function $createSystemPhase() {
for (var i = 0; i <= 7; i++) {
for (var j = 1; j <= 15; j++) {
this._systemPhase.push({
gov: i,
tl: j,
phase: this.$rand(999)
});
}
}
}
//-------------------------------------------------------------------------------------------------------------
// updates the phase setting for a particular government/techlevel
this.$updatePhase = function $updatePhase(govType, techlevel, phase) {
for (var i = 0; i < this._systemPhase.length; i++) {
if (this._systemPhase[i].gov === govType && this._systemPhase[i].tl === techlevel) {
this._systemPhase[i].phase = phase;
this._phaseUpdates.push({
gov: govType,
tl: techlevel
});
break;
}
}
for (var i = 0; i < this._phaseScanDiscovery.length; i++) {
if (this._phaseScanDiscovery[i].gov === govType && this._phaseScanDiscovery[i].tl === techlevel && this._phaseScanDiscovery[i].source < 3) this._phaseScanDiscovery[i].source = 4;
}
}
//-------------------------------------------------------------------------------------------------------------
// returns the phase for a given system ID
this.$getSystemPhase = function $getSystemPhase(systemID) {
var sysinfo = System.infoForSystem(galaxyNumber, systemID);
var result = 0;
for (var i = 0; i < this._systemPhase.length; i++) {
if (this._systemPhase[i].gov === sysinfo.government && this._systemPhase[i].tl === sysinfo.techlevel) result = this._systemPhase[i].phase;
}
return result;
}
//-------------------------------------------------------------------------------------------------------------
// removes the current smuggling compartment and empties the cargo stored in it
this.$removeCompartment = function $removeCompartment() {
player.ship.removeEquipment("EQ_SMUGGLING_PHASE_ADJUSTMENT");
player.ship.removeEquipment("EQ_SMUGGLING_INFLIGHT_STORAGE");
var eq = this.$getSmugglingCompartmentEquipment();
if (eq === "") return;
this._backdoor = true;
player.ship.removeEquipment(eq);
this._backdoor = false;
this._sc_Cargo = [];
this._sc_VisibleAs = "Food";
this._sc_Phase = 1;
this._sc_TechVersion = 1;
}
//-------------------------------------------------------------------------------------------------------------
// returns a summarised version of the smuggling compartment cargo
this.$getSmugglingCargo = function $getSmugglingCargo() {
var cargo = [];
for (var i = 0; i < this._sc_Cargo.length; i++) {
var found = false;
for (var j = 0; j < cargo.length; j++) {
if (cargo[j].commodity === this._sc_Cargo[i].commodity) {
cargo[j].quantity += this._sc_Cargo[i].quantity;
found = true;
}
}
if (found === false) {
cargo.push({
commodity: this._sc_Cargo[i].commodity,
displayName: this._sc_Cargo[i].displayName,
quantity: this._sc_Cargo[i].quantity,
unit: this._sc_Cargo[i].unit,
extra: this._sc_Cargo[i].extra
});
}
}
return cargo;
}
//-------------------------------------------------------------------------------------------------------------
// returns how much of a particular commodity is in the smuggling compartment
this.$getCargoQuantity = function $getCargoQuantity(commodity) {
var cargo = this.$getSmugglingCargo();
var result = 0;
for (var i = 0; i < cargo.length; i++) {
if (cargo[i].commodity === commodity) result = cargo[i].quantity;
}
return result;
}
//-------------------------------------------------------------------------------------------------------------
// removes an given amount of a particular commodity
this.$removeCargo = function $removeCargo(commodity, quantity) {
var sum = quantity;
for (var i = this._sc_Cargo.length - 1; i >= 0; i--) {
if (this._sc_Cargo[i].commodity === commodity && sum > 0) {
if (this._sc_Cargo[i].quantity >= sum) {
this.$checkForAndRemoveCTECargo(commodity, sum);
this._sc_Cargo[i].quantity -= sum;
sum = 0;
} else {
sum -= this._sc_Cargo[i].quantity;
this._sc_Cargo[i].quantity = 0;
}
}
}
this.$cargoCleanUp();
// return any remainder
return sum;
}
//-------------------------------------------------------------------------------------------------------------
// extracts an certain amount of a particular commodity from new cargoes
this.$extractCargoFromCTE = function(commodity, amount, max) {
var cte = worldScripts.CargoTypeExtension;
var special = this.$calcCTEcargo(commodity);
var normal = max - special;
if (amount - normal > 0) {
// we're transferring some special cargo
var storage = [];
var ncmanifest = cte.suspendPlayerManifest(commodity);
var nc = ncmanifest.split("|");
var lst = nc[1].split("/");
var counter = 0;
for (var i = 0; i < lst.length; i++) {
if (lst[i] != "") {
var itms = lst[i].split(";");
for (var j = 0; j < itms.length; j++) {
if (itms[j] != "") {
// reduce the original
var sub = itms[j].split("=");
var removed = 0;
while (sub[1] > 0) {
sub[1]--;
counter++;
removed++;
if ((amount - normal) - counter == 0) break;
}
itms[j] = sub.join("=");
//storage.push(sub[0] + "=" + removed + "=" + sub[2]);
// make a copy of what we're taking out
// we'll store them a 1 unit items to make the return process easier
for (var k = 0; k < removed; k++) {
var st = "";
for (var m = 0; m < sub.length; m++) {
st += (st == "" ? "" : "=") + (m == 1 ? 1 : sub[m]);
}
storage.push(st);
}
}
}
lst[i] = itms.join(";");
}
if ((amount - normal) - counter == 0) break;
}
nc[1] = lst.join("/");
ncmanifest = nc.join("|");
// tell NC about what we've done
cte.mergePlayerManifest(ncmanifest);
// pull our storage data together
extra = storage.join(";");
}
return extra;
}
//-------------------------------------------------------------------------------------------------------------
this.$checkForAndRemoveCTECargo = function(commodity, quantity) {
var extra = "";
for (var i = 0; i < this._sc_Cargo.length; i++) {
if (this._sc_Cargo[i].commodity == commodity) {
if (this._sc_Cargo[i].extra != "") {
var dta = [];
dta = this._sc_Cargo[i].extra.split(";");
var normal = this._sc_Cargo[i].quantity - dta.length;
if (quantity - normal > 0) {
var diff = quantity - normal;
// compile a list of the cargo items to re-merge with nc
while (diff > 0) {
extra += (extra == "" ? "" : ";") + dta.shift();
diff--;
}
this._sc_Cargo[i].extra = dta.join(";");
}
}
}
}
// because we store everything as 1 unit items, we need to compile it back into totals so NC has good data
var hold = this.$compileCTEValues(extra);
var ncmanifest = "2|" + this.$buildMergeManifest(commodity, hold);
return ncmanifest;
}
//-------------------------------------------------------------------------------------------------------------
// compile multiple 1 unit items down to one entry with a 1+ unit count
this.$compileCTEValues = function(extra) {
var items = extra.split(";");
var list = {};
for (var i = 0; i < items.length; i++) {
if (!list[items[i]]) {
list[items[i]] = 1;
} else {
list[items[i]] = list[items[i]] + 1;
}
log(this.name, "tracking " + list[items[i]]);
}
var keys = Object.keys(list);
var final = "";
for (var i = 0; i < keys.length; i++) {
var subs = keys[i].split("=");
final = (final == "" ? "" : ";") + subs[0] + "=" + list[keys[i]] + "=" + subs[2];
}
return final;
}
//-------------------------------------------------------------------------------------------------------------
// put the manifest string together
// blank entries in all but the item we are processing the commodity for
this.$buildMergeManifest = function(commodity, extra) {
var cte = worldScripts.CargoTypeExtension;
var goodsList = cte.cargoTypes;
var serial = "";
for (var i = 0; i < goodsList.length; i++) {
if (goodsList[i] == commodity) {
serial += extra;
}
if (i + 1 < goodsList.length) {
serial += "/";
}
}
return serial;
}
//-------------------------------------------------------------------------------------------------------------
// adds a phase scan setting to our discovered list
// source 1 = from phase scanner, 2 = purchased from black market, 3 = overheard in rumours, 4 = updated after scan
this.$addPhaseScan = function $addPhaseScan(phase, systemID, source) {
//log(this.name, "checking " + system.ID);
//log(this.name, "data: " + systemID + ", " + source);
var sysinfo = System.infoForSystem(galaxyNumber, systemID);
var found = false;
for (var i = 0; i < this._phaseScanDiscovery.length; i++) {
if (this._phaseScanDiscovery[i].gov === sysinfo.government && this._phaseScanDiscovery[i].tl === sysinfo.techlevel) {
found = true;
this._phaseScanDiscovery[i].phase = phase;
// if the previous value was just a remour, or changed, update it now
if (this._phaseScanDiscovery[i].source >= 3 && source < 3) this._phaseScanDiscovery[i].source = source;
}
}
if (found === false) {
this._phaseScanDiscovery.push({
gov: sysinfo.government,
tl: sysinfo.techlevel,
phase: phase,
source: source
});
}
}
//-------------------------------------------------------------------------------------------------------------
// returns true if the player has a reliable phase scan for a given system
this.$playerHasPhaseScan = function $playerHasPhaseScan(sysID) {
var sysinfo = System.infoForSystem(galaxyNumber, sysID);
var result = false;
for (var i = 0; i < this._phaseScanDiscovery.length; i++) {
if (this._phaseScanDiscovery[i].gov === sysinfo.government && this._phaseScanDiscovery[i].tl === sysinfo.techlevel && this._phaseScanDiscovery[i].source < 3) result = true;
}
return result;
}
//-------------------------------------------------------------------------------------------------------------
// returns the number of sellable phase scans the player has
this.$sellablePhaseScans = function $sellablePhaseScans() {
var list = this.$getSellablePhaseScans();
return list.length;
}
//-------------------------------------------------------------------------------------------------------------
// get a list of sellable phase scan settings for the black market
// note: will only return scans within 7ly of current system
this.$getSellablePhaseScans = function $getSellablePhaseScans() {
function compare(a, b) {
if ((a.gov * 100) + a.tl < (b.gov * 100) + b.tl) return -1;
if ((a.gov * 100) + a.tl > (b.gov * 100) + b.tl) return 1;
return 0;
}
this._phaseScanDiscovery.sort(compare);
var govs = new Array();
for (var i = 0; i < 8; i++)
govs.push(String.fromCharCode(i));
var spc = String.fromCharCode(31);
var list = [];
var added = [];
// you can only sell phase scans for the local area
var sys = System.infoForSystem(galaxyNumber, system.ID).systemsInRange(7);
for (var i = 0; i < this._phaseScanDiscovery.length; i++) {
if (this._phaseScanDiscovery[i].source === 1) {
for (var j = 0; j < sys.length; j++) {
// does this scan match a local system, and have we already added this variation?
if (sys[j].government === this._phaseScanDiscovery[i].gov && sys[j].techlevel === this._phaseScanDiscovery[i].tl && added.indexOf((sys[j].government * 100) + sys[j].techlevel) === -1) {
list.push({
text: this.$padTextRight(govs[this._phaseScanDiscovery[i].gov] + spc + "TL" + (this._phaseScanDiscovery[i].tl + 1) + ":", 3.7) + this.$padTextRight(this._phaseScanDiscovery[i].phase, 3),
gov: this._phaseScanDiscovery[i].gov,
tl: this._phaseScanDiscovery[i].tl
});
// add the signature to the added list so we can easily check if it's there already
added.push((sys[j].government * 100) + sys[j].techlevel);
}
}
}
}
return list;
}
//-------------------------------------------------------------------------------------------------------------
// switches a source = 1 to source = 0 for a particular phase scan
this.$sellPhaseScan = function $sellPhaseScan(govrn, techlvl) {
for (var i = 0; i < this._phaseScanDiscovery.length; i++) {
if (this._phaseScanDiscovery[i].gov === govrn && this._phaseScanDiscovery[i].tl === techlvl && this._phaseScanDiscovery[i].source === 1) {
this._phaseScanDiscovery[i].source = 0;
}
}
}
//-------------------------------------------------------------------------------------------------------------
// gets the commodity type for a particular commodity (t , kg or g)
this.$getCommodityType = function $getCommodityType(good) {
if (system.isInterstellarSpace) {
var m = player.ship.manifest;
if (m[good] > 0) {
for (var i = 0; i < m.list.length; i++) {
if (m.list[i].commodity == good) return m.list[i].unit;
}
} else {
return "t";
}
}
var types = ["t", "kg", "g"];
return types[system.mainStation.market[good].quantity_unit];
}
//=============================================================================================================
// hypercargo integration routines
//-------------------------------------------------------------------------------------------------------------
// returns a list of commodity items that are illegal, based on a commodity list
this.$checkHyperCargo = function $checkHyperCargo(commodity) {
var returnData = "";
if (missionVariables.hyperCargoMemory === "EMPTY") return "";
if (!worldScripts["HyperCargo"]) return ""; // just in case hypercargo OXP was removed after being installed for a while
var hc = worldScripts["HyperCargo"];
for (var i = 0; i < 14; i++) {
var cargoItem = hc.cargoNameArray[i];
if (commodity === cargoItem && hc.storedArray[i] > 0) {
var cargoCount = hc.storedArray[i];
returnData = " - " + cargoCount + " " + this.$getCommodityType(cargoItem) + " × " + displayNameForCommodity(cargoItem) + " (stored in HyperCargo)";
}
}
return returnData;
}
//-------------------------------------------------------------------------------------------------------------
// returns the quantity of a particular commodity
this.$getHyperCargoQuantity = function $getHyperCargoQuantity(commodity) {
var returnData = "";
if (missionVariables.hyperCargoMemory === "EMPTY") return 0;
if (!worldScripts["HyperCargo"]) return 0; // just in case hypercargo OXP was removed after being installed for a while
var hc = worldScripts["HyperCargo"];
for (var i = 0; i < 14; i++) {
var cargoItem = hc.cargoNameArray[i];
if (commodity === cargoItem && hc.storedArray[i] > 0) {
return hc.storedArray[i];
}
}
return -1;
}
//-------------------------------------------------------------------------------------------------------------
// removes illegal cargo from hypercargo and applies a bounty
this.$updateHyperCargo = function $updateHyperCargo(commodity, def) {
if (missionVariables.hyperCargoMemory === "EMPTY") return;
if (!worldScripts["HyperCargo"]) return; // just in case hypercargo OXP was removed after being installed for a while
var hc = worldScripts["HyperCargo"];
var p = player.ship;
for (var i = 0; i < 14; i++) {
var cargoItem = hc.cargoNameArray[i];
if (commodity === cargoItem && hc.storedArray[i]) {
p.setBounty(player.bounty + (hc.storedArray[i] * def.scale), "illegal imports");
hc.storedArray[i] = 0;
}
}
}
//-------------------------------------------------------------------------------------------------------------
// removes an amount of cargo from hypercargo
this.$removeHyperCargo = function $removeHyperCargo(commodity, amount) {
if (missionVariables.hyperCargoMemory === "EMPTY") return 0;
if (!worldScripts["HyperCargo"]) return 0; // just in case hypercargo OXP was removed after being installed for a while
var hc = worldScripts["HyperCargo"];
for (var i = 0; i < 14; i++) {
var cargoItem = hc.cargoNameArray[i];
if (commodity === cargoItem && hc.storedArray[i] > 0) {
if (hc.storedArray[i] >= amount) {
hc.storedArray[i] -= amount;
return 0;
} else {
var remain = amount - hc.storedArray[i];
hc.storedArray[i] = 0;
return remain;
}
}
}
}
//-------------------------------------------------------------------------------------------------------------
// prompts the user for a new phase
this.$getBribeAmount = function $getBribeAmount() {
var text = "";
var sdm = worldScripts.Smugglers_DockMaster;
var inttype = Math.floor((sdm._bribeChance[system.ID] * 4) + 1);
var inttypedesc = expandDescription("[interest-type" + inttype + "]");
var lastBribe = sdm.$previousBribeAmount();
text = expandDescription("[dockmaster-question]", {
interesttype: inttypedesc
}) + "\n\n" +
"(" + expandDescription("[dockmaster-cost]", {
credits: formatCredits(player.credits, false, true)
}) +
(lastBribe > 0 ? expandDescription("[dockmaster-lastbribe]", {
bribeamount: formatCredits(lastBribe, false, true)
}) : "") + ")";
var opts = {
screenID: "smuggling_bribe",
title: "Bribing Official",
allowInterrupt: false,
model: "[" + this._policeModel + "]",
exitScreen: "GUI_SCREEN_STATUS",
message: text,
textEntry: true
};
mission.runScreen(opts, this.$getBribeAmountInput, this);
}
//-------------------------------------------------------------------------------------------------------------
// parses the input from the getBribeAmount screen
this.$getBribeAmountInput = function $getBribeAmountInput(param) {
var sdm = worldScripts.Smugglers_DockMaster;
var p = player.ship;
sdm._bribeAttempted = true;
if (parseInt(param) >= 1 && parseInt(param) <= player.credits) {
var amount = parseInt(param);
// will this work
var chance = sdm._bribeChance[system.ID];
// higher amounts are more likely to be accepted
// chance of 0.5 would mean you would need to offer them 256 credits
//if (this._debug) log(this.name, "min bribe amount = " + (Math.pow(parseInt(chance * 32), 1.8) * (1 + system.productivity / 56300) * sdm._bribeCount[system.ID]));
if ((Math.pow(parseInt(chance * 32), 1.8) * (1 + system.productivity / 56300) * sdm._bribeCount[system.ID]) <= amount) {
player.credits -= amount;
sdm.$addBribe(system.ID);
sdm._successfulBribes.push({
system: system.ID,
bribeAmount: amount
});
p.setBounty(this._savedBounty, "bribe");
mission.runScreen({
screenID: "smuggling_bribe",
title: "Bribing Official",
model: "[" + this._policeModel + "]",
message: expandDescription("[dockmaster-complete]"),
exitScreen: "GUI_SCREEN_STATUS"
});
} else {
if (this._bribeType === 1) this.$processRemovals();
if (this._bribeType === 2) this.$processEquipmentRemovals();
if (Math.random() > chance) {
mission.runScreen({
screenID: "smuggling_bribe",
title: "Bribing Official",
model: "[" + this._policeModel + "]",
message: expandDescription("[dockmaster-angry-nopenalty]"),
exitScreen: "GUI_SCREEN_STATUS"
});
} else {
var penalty = (worldScripts.Smugglers_CoreFunctions.$rand(10) + 3);
p.setBounty(player.bounty + penalty, "attempted bribe");
mission.runScreen({
screenID: "smuggling_bribe",
title: "Bribing Official",
model: "[" + this._policeModel + "]",
message: expandDescription("[dockmaster-angry-penalty]"),
exitScreen: "GUI_SCREEN_STATUS"
});
// send email (if installed)
var email = worldScripts.EmailSystem;
if (email) {
var ga = worldScripts.GalCopAdminServices;
email.$createEmail({
sender: "GalCop Customs",
subject: "Attempt to bribe official",
date: clock.seconds,
message: expandDescription("[smugglers-failed-bribe-email]", {
legal_penalty: penalty,
stationname: player.ship.dockedStation.displayName,
systemname: System.systemNameForID(system.ID)
}),
expiryDays: ga._defaultExpiryDays
});
}
}
}
} else {
if (this._bribeType === 1) this.$processRemovals();
if (this._bribeType === 2) this.$processEquipmentRemovals();
mission.runScreen({
screenID: "smuggling_bribe",
title: "Bribing Official",
model: "[" + this._policeModel + "]",
message: expandDescription("[dockmaster-skipbribe]"),
exitScreen: "GUI_SCREEN_STATUS"
});
}
}
//-------------------------------------------------------------------------------------------------------------
// processes any cargo and/or smuggling compartment removals after docking
this.$processRemovals = function $processRemovals() {
var emailText = "";
var p = player.ship;
if (this._removeCompartment === true) {
// remove smuggling compartment and contents
emailText += "- removal of scanner-resistant cargo compartment.\n";
this.$removeCompartment();
}
if (this._phaseScannerDetected === true) {
emailText += "- removal of illegal phase scanner.\n";
p.removeEquipment("EQ_PHASE_SCANNER");
}
for (var i = 0; i < this._toRemove.length; i++) {
if (this._toRemove[i].source === "hold") {
emailText += "- confiscation of " + p.manifest[this._toRemove[i].commodity] + this.$getCommodityType(this._toRemove[i].commodity) + " × " + displayNameForCommodity(this._toRemove[i].commodity) + " from your cargo hold.\n";
p.manifest[this._toRemove[i].commodity] = 0;
}
if (this._toRemove[i].source === "hyper") {
emailText += "- confiscation of " + p.manifest[this._toRemove[i].commodity] + this.$getCommodityType(this._toRemove[i].commodity) + " × " + displayNameForCommodity(this._toRemove[i].commodity) + " from your hypercargo hold.\n";
this.$removeHyperCargo(this._toRemove[i].commodity, this.$getHyperCargoQuantity(this._toRemove[i].commodity));
}
}
if (this._playerFine > 0) {
if (player.credits > this._playerFine) {
emailText += "- applied a fine of " + formatCredits(this._playerFine, true, true) + "\n";
player.credits -= this._playerFine;
} else {
emailText += "- applied a fine of " + formatCredits(player.credits, true, true) + "\n";
player.credits = 0;
}
}
this._removeCompartment = false;
this._phaseScannerDetected = false;
// send email (if installed)
if (emailText != "") {
var email = worldScripts.EmailSystem;
if (email) {
var ga = worldScripts.GalCopAdminServices;
email.$createEmail({
sender: "GalCop Customs",
subject: "Contraband removal",
date: clock.seconds,
message: expandDescription("[smugglers-removal-email]", {
contraband: emailText,
stationname: player.ship.dockedStation.displayName,
systemname: System.systemNameForID(system.ID)
}),
expiryDays: ga._defaultExpiryDays
});
}
}
}
//-------------------------------------------------------------------------------------------------------------
// processes any equipment removals after a renovation
this.$processEquipmentRemovals = function $processEquipmentRemovals() {
var p = player.ship;
var emailText = "";
if (this.$isPhaseScannerInstalled() === true) {
emailText = "- removal of illegal phase scanner.\n";
p.removeEquipment("EQ_PHASE_SCANNER");
}
if (this.$hasSmugglingCompartment() === true) {
// remove compartment and contents
emailText += "- removal of scanner-resistant cargo compartment.\n";
this.$removeCompartment();
}
// send email (if installed)
if (emailText != "") {
var email = worldScripts.EmailSystem;
if (email) {
var ga = worldScripts.GalCopAdminServices;
email.$createEmail({
sender: "GalCop Customs",
subject: "Contraband removal",
date: clock.seconds,
message: expandDescription("[smugglers-removal-email]", {
contraband: emailText,
stationname: player.ship.dockedStation.displayName,
systemname: System.systemNameForID(system.ID)
}),
expiryDays: ga._defaultExpiryDays
});
}
}
}
//-------------------------------------------------------------------------------------------------------------
// build up an array of values that can be used to determine how many government/techlevel types exist in the system
this.$createSystemDataArray = function $createSystemDataArray() {
this._systemData = [];
for (var i = 0; i <= 255; i++) {
var sys = System.infoForSystem(galaxyNumber, i);
var item = sys.government * 100 + sys.techlevel;
if (this._systemData.indexOf(item) === -1) this._systemData.push(item);
}
}
//-------------------------------------------------------------------------------------------------------------
// updates the manifest screen entry for the smuggling hold contents
this.$updateManifest = function $updateManifest() {
var list = [];
var cargo_size = this.$smugglingCompartmentSize();
if (cargo_size > 0) {
var damaged = this.$isCompartmentDamaged();
list.push("Smuggling Compartment Cargo " + this.$usedSpace().toFixed(0) + " t (" + cargo_size + " t)" + (damaged === true ? " *DAMAGED*" : "") + ":");
var additem = "";
for (var i = 0; i < this._sc_Cargo.length; i++) {
if (additem === "") {
additem += this.$padTextRight(this._sc_Cargo[i].quantity + " " + this._sc_Cargo[i].unit + " × " + displayNameForCommodity(this._sc_Cargo[i].commodity), 17);
} else {
additem += this._sc_Cargo[i].quantity + " " + this._sc_Cargo[i].unit + " × " + displayNameForCommodity(this._sc_Cargo[i].commodity);
list.push(additem);
additem = "";
}
}
if (additem != "") list.push(additem);
if (this._sc_Cargo.length > 0) {
mission.setInstructions(list, this.name);
} else {
list.push("No cargo carried.");
mission.setInstructions(list, this.name);
}
} else {
mission.setInstructions(null, this.name);
}
}
//-------------------------------------------------------------------------------------------------------------
// play the buy/sell sound effects
this.$playSound = function $playSound(soundtype) {
var mySound = new SoundSource;
switch (soundtype) {
case "buy":
mySound.sound = "[buy-commodity]";
break;
case "sell":
mySound.sound = "[sell-commodity]";
break;
case "mode":
mySound.sound = "[@click]";
break;
case "activate":
mySound.sound = "[@beep]";
break;
case "stop":
mySound.sound = "[@boop]";
break;
}
mySound.loop = false;
mySound.play();
}
//-------------------------------------------------------------------------------------------------------------
// returns the illegal scale factor for a particular commodity at the current docked station
this.$commodityIllegalScale = function $commodityIllegalScale(commodity) {
var p = player.ship;
var stn = p.dockedStation;
var scale = parseInt(stn.market[commodity].legality_import);
if (scale === 0) scale = parseInt(stn.market[commodity].legality_export);
return scale;
}
//-------------------------------------------------------------------------------------------------------------
// gets a list of all police ship models so we can use them consistently on smuggling screens
this.$getPoliceModel = function $getPoliceModel() {
var shipkeys = Ship.keysForRole("police");
if (shipkeys.length === 0) return "viper";
var key = "";
var tries = 0;
do {
key = shipkeys[Math.floor(Math.random() * shipkeys.length)];
if (this.$modelIsAllowed(key) === false) key = "";
tries += 1;
} while (key === "" && tries < 5)
if (key === "") key = "viper";
return key;
}
//-------------------------------------------------------------------------------------------------------------
this.$modelIsAllowed = function $modelIsAllowed(shipkey) {
var shipdata = Ship.shipDataForKey(shipkey);
// are we allowed to include this data key in this system? check the conditions if there are some
var include = true;
if (shipdata.conditions) {
var cond = shipdata.conditions.toString().split(",");
//1,systemGovernment_number equal 4,systemGovernment_number,0,0,4,
//1,systemEconomy_number notequal 4,systemEconomy_number,1,0,4
//1,systemEconomy_number lessthan 4,systemEconomy_number,2,0,4
//1,systemEconomy_number greaterthan 4,systemEconomy_number,3,0,4
var offset = 0;
var finish = false;
var checking = -1;
do {
// get the value we're checking
checking = -1;
if (cond[offset + 2].substring(0, 6) === "mission") {
if (missionVariables[cond[offset + 2].replace("mission_", "")]) {
checking = missionVariables[cond[offset + 2].replace("mission_", "")];
//log(this.name, "field = " + cond[offset + 2] + ", value = " + checking);
} else {
log(this.name, "!!NOTE: Condition value mission variable not set: " + cond[offset + 2]);
}
} else {
switch (cond[offset + 2]) {
case "systemGovernment_number":
checking = system.government;
break;
case "systemEconomy_number":
checking = system.economy;
break;
case "systemTechLevel_number":
checking = system.techLevel;
break;
case "score_number":
checking = player.score;
break;
case "galaxy_number":
checking = galaxyNumber;
break;
case "planet_number":
checking = system.ID;
break;
default:
log(this.name, "!!NOTE: Condition value not catered for: " + cond[offset + 2]);
break;
}
}
// in case a mission variable is a text value of some sort
if (isNaN(parseInt(checking)) && isNaN(parseFloat(checking))) {
switch (cond[offset + 3]) {
case "0": // equals
if (checking != cond[offset + 5]) include = false;
break;
case "1": // not equals
if (checking == cond[offset + 5]) include = false;
break;
default:
log(this.name, "!!NOTE: Condition comparison not catered for: " + cond[offset + 3]);
break;
}
} else {
if (checking >= 0) {
// work out the type of check, but in negative (or opposite)
switch (cond[offset + 3]) {
case "0": // equals
if (checking !== parseInt(cond[offset + 5])) include = false;
break;
case "1": // not equals
if (checking === parseInt(cond[offset + 5])) include = false;
break;
case "2": // lessthan
if (checking >= parseInt(cond[offset + 5])) include = false;
break;
case "3": // greaterthan
if (checking <= parseInt(cond[offset + 5])) include = false;
break;
default:
log(this.name, "!!NOTE: Condition comparison not catered for: " + cond[offset + 3]);
break;
// others?
}
}
}
offset += 6;
if (offset >= cond.length - 1) finish = true;
} while (finish === false);
} else if (shipdata.condition_script) {
// or the condition script
// create a dummy object to attach the script to so it can be executed
if (system.sun && system.mainPlanet) {
var temppos = system.sun.position.cross(system.mainPlanet.position).direction().multiply(4E9).subtract(system.mainPlanet.position);
var tempalloy = system.addShips("alloy", 1, temppos, 0);
tempalloy[0].setScript(shipdata.condition_script);
include = tempalloy[0].script.allowSpawnShip(shipkey);
tempalloy[0].remove(true);
} else {
include = true;
}
} else {
// otherwise we're free to play
include = true;
}
return include;
} |
Scripts/smugglers_illegal.js |
"use strict";
this.name = "Smugglers_Illegal";
this.author = "phkb";
this.description = "Looks after the new illegal goods.";
this.licence = "CC BY-NC-SA 3.0";
/* TODO:
- add more illegal trade items to the possibilities list
*/
this._disabled = false;
this._debug = false;
this._enableMarkedSystems = true;
this._markedSystemRange = 7;
this._IGTInstalled = false;
/* template: {govTypes:"", commodity:"", properties:"", permit:1, scale:1, period:n, chance:1, description:""},
govTypes: Comma-separated list of goverment types (0-7) this definition can apply to
commodity: Comma-separated list of commodity names this definition will apply to.
properties: Comma-separated list of text search strings to use against the planetary description.
For instance, "civil war" would only select planets that have "civil war" in their description.
"drink|brew" would only select planets that have "drink" or "brew" in their description.
permit: Boolean value (0 or 1) indicating whether a permit can be purchased for this commodity
scale: The legality scale to apply to this commodity. The scale will apply when calculating the bounty to apply to a player caught smuggling illegal goods as a multiplier.
Most illegal goods have a scale of 1. Slaves have 2.
period: The period (in days) this definition will be active for.
chance: A chance factor, between 0 (never) and 1 (very often), to apply when selecting this definition
description: The description to display for this definition.
*/
this._possibilities = [{
govTypes: "0,1,2",
commodity: "firearms",
properties: "",
permit: 0,
scale: 2,
period: -1,
chance: 0,
description: "Firearms have been declared illegal to reduce the proliferation of arms in dangerous systems."
},
{
govTypes: "3,4,5,6,7",
commodity: "firearms",
properties: "civil war",
permit: 0,
scale: 1,
period: -1,
chance: 0,
description: "Firearms have been declared illegal to reduce the impact of the civil war on this system."
},
{
govTypes: "0",
commodity: "computers",
properties: "",
permit: 1,
scale: 1,
period: 120,
chance: 1,
description: "Computer technology has been restricted to limit illegal hacking."
},
{
govTypes: "0,1",
commodity: "radioactives",
properties: "",
permit: 1,
scale: 1,
period: 200,
chance: 1,
description: "Recent upswing in dirty bombs and highly destructive weapons has led to strict controls on radioactives."
},
{
govTypes: "0,1",
commodity: "machinery",
properties: "",
permit: 1,
scale: 1,
period: 90,
chance: 1,
description: "GalCop has restricted the importation of machinery to apply pressure to the government."
},
{
govTypes: "1",
commodity: "food",
properties: "",
permit: 1,
scale: 1,
period: 60,
chance: 1,
description: "Food imported from outside is feared to be coming from lower classes and is inappropriate for distribution and consumption."
},
{
govTypes: "1",
commodity: "textiles",
properties: "",
permit: 1,
scale: 1,
period: 90,
chance: 1,
description: "The under classes have been purchasing cheap clothes that mimic upper class styles and fabrics via imported sources. To keep the classes distinct, all imported textiles have been banned."
},
{
govTypes: "1",
commodity: "liquor_wines",
properties: "",
permit: 1,
scale: 1,
period: 60,
chance: 1,
description: "A number of alcohol-fuelled riots in lower class cities has led to a ban on all imported liquor."
},
{
govTypes: "1",
commodity: "computers",
properties: "",
permit: 1,
scale: 1,
period: 90,
chance: 1,
description: "The priest class has declared use of the latest computers is taboo."
},
{
govTypes: "1",
commodity: "machinery",
properties: "",
permit: 1,
scale: 1,
period: 120,
chance: 1,
description: "Machinery was seen as providing a way for lower classes to rise up against their superiors, so all foreign machinery has been declared illegal."
},
{
govTypes: "1",
commodity: "furs",
properties: "",
permit: 1,
scale: 1,
period: 90,
chance: 1,
description: "Imported furs were cutting into a market monopoly held by certain members of the upper class, and so an import ban has been put in place."
},
{
govTypes: "1",
commodity: "gold,platinum",
properties: "",
permit: 1,
scale: 1,
period: 12,
chance: 0.5,
description: "Prominent Barons have decried the devaluation of their investments due to foreign influence, and have brought about a temporary ban on precious metals."
},
{
govTypes: "2",
commodity: "computers",
properties: "",
permit: 1,
scale: 1,
period: 90,
chance: 1,
description: "Computers have been declared illegal in order to, it is suspected, undermine the efficiency of an opposing factions military forces."
},
{
govTypes: "2",
commodity: "alien_items",
properties: "",
permit: 1,
scale: 1,
period: 120,
chance: 1,
description: "Reports of fake alien items has led to a ban pending authentication measures."
},
{
govTypes: "2",
commodity: "food",
properties: "",
permit: 1,
scale: 1,
period: 60,
chance: 1,
description: "Reports of contaminants in food supplies in nearby systems has prompted an embargo."
},
{
govTypes: "2",
commodity: "alloys",
properties: "",
permit: 1,
scale: 1,
period: 120,
chance: 1,
description: "A temporary embargo on imported alloys has been put in place as a way of bolstering local development."
},
{
govTypes: "2",
commodity: "liquor_wines",
properties: "",
permit: 1,
scale: 1,
period: 120,
chance: 1,
description: "All imported alcoholic beverages have been banned as a political favour to a local distributor."
},
{
govTypes: "2",
commodity: "machinery",
properties: "",
permit: 1,
scale: 1,
period: 120,
chance: 1,
description: "Imported machinery was seen to be giving a production boost to an opposing faction and have been declared illegal."
},
{
govTypes: "2",
commodity: "gold,platinum",
properties: "",
permit: 1,
scale: 1,
period: 12,
chance: 0.5,
description: "An embargo has been placed on all precious metal imports, to cripple the markets of an opposing faction."
},
{
govTypes: "2",
commodity: "firearms",
properties: "",
permit: 1,
scale: 1,
period: 90,
chance: 1,
description: "In an attempt to undermine the military strength of opposing factions, all firearm have been declared illegal."
},
{
govTypes: "3",
commodity: "luxuries",
properties: "",
permit: 1,
scale: 1,
period: 90,
chance: 1,
description: "Imported luxuries have been declared illegal as they are, according to local government representatives, 'weak and unnecessary'."
},
{
govTypes: "3",
commodity: "radioactives",
properties: "",
permit: 1,
scale: 1,
period: 120,
chance: 1,
description: "A hazardous waste scare has prompted a review of radioactives used in power stations."
},
{
govTypes: "0,3",
commodity: "food",
properties: "",
permit: 1,
scale: 1,
period: 60,
chance: 1,
description: "GalCop has put pressure on the government by restricting food imports."
},
{
govTypes: "3",
commodity: "machinery",
properties: "",
permit: 1,
scale: 1,
period: 120,
chance: 1,
description: "Imported machinery was seen to be altering the balance of power, and have been banned."
},
{
govTypes: "3",
commodity: "computers",
properties: "",
permit: 1,
scale: 1,
period: 90,
chance: 1,
description: "Technology imports have been declared illegal as they were causing the general population to become dissatisfied with their lot."
},
{
govTypes: "3",
commodity: "minerals",
properties: "",
permit: 1,
scale: 1,
period: 120,
chance: 1,
description: "The discovery of a rich mineral deposit has prompted an embargo on imported minerals."
},
{
govTypes: "3",
commodity: "alien_items",
properties: "",
permit: 1,
scale: 1,
period: 90,
chance: 1,
description: "A inter-racial dispute in political circles has led to a ban on imported alien items."
},
{
govTypes: "4",
commodity: "minerals",
properties: "",
permit: 1,
scale: 1,
period: 90,
chance: 1,
description: "Political dissidents do all internal system mining as punishment-- so foreign imports have been banned."
},
{
govTypes: "4",
commodity: "machinery",
properties: "",
permit: 1,
scale: 1,
period: 120,
chance: 1,
description: "Automation is contrary to the communist work ethic, so all foreign machinery has been declared illegal."
},
{
govTypes: "4",
commodity: "computers",
properties: "",
permit: 1,
scale: 1,
period: 120,
chance: 1,
description: "Foreign computers cannot be trusted to give good communists the right answers, and have been banned."
},
{
govTypes: "4",
commodity: "luxuries",
properties: "",
permit: 1,
scale: 1,
period: 90,
chance: 1,
description: "The system has stated that strong communists don't need the decadent luxuries from weaker systems."
},
{
govTypes: "4",
commodity: "liquor_wines",
properties: "",
permit: 1,
scale: 1,
period: 60,
chance: 1,
description: "Consumption of spirits other than locally brewed beverages have been declared to be treasonous."
},
{
govTypes: "4",
commodity: "furs",
properties: "",
permit: 1,
scale: 1,
period: 90,
chance: 1,
description: "Furs are seen to be a decadent fashion item of the enemies of the people, and have been banned."
},
{
govTypes: "4",
commodity: "food",
properties: "",
permit: 1,
scale: 1,
period: 60,
chance: 1,
description: "The system has declared that local growers will supply everything they need-- or else."
},
{
govTypes: "4",
commodity: "textiles",
properties: "",
permit: 1,
scale: 1,
period: 90,
chance: 1,
description: "Locally produced clothing is superior to imported goods, and provides political prisoners with a livelihood. All textile imports are banned."
},
{
govTypes: "4",
commodity: "gold,platinum,gem_stones",
properties: "",
permit: 1,
scale: 1,
period: 12,
chance: 0.5,
description: "The influence of foreign money has been decreed to be against the Communist ethic, leading to a ban on all precious metals and gem stones."
},
{
govTypes: "5",
commodity: "food",
properties: "",
permit: 1,
scale: 1,
period: 60,
chance: 1,
description: "Agricultural imports are barred to limit the risk of an invasive pest species that has been spreading in nearby systems."
},
{
govTypes: "5",
commodity: "gold,platinum",
properties: "",
permit: 1,
scale: 1,
period: 12,
chance: 0.5,
description: "A drop in the money market has led to temporary ban on imported precious metals."
},
{
govTypes: "5",
commodity: "computers",
properties: "",
permit: 1,
scale: 1,
period: 90,
chance: 1,
description: "A nationalist movement proclaiming the importance of local products have orchestrated a ban on imported computer technology."
},
{
govTypes: "5",
commodity: "furs",
properties: "",
permit: 1,
scale: 1,
period: 90,
chance: 1,
description: "Imported furs were competing against local tanners and furriers and have been declared illegal."
},
{
govTypes: "5",
commodity: "alien_items",
properties: "",
permit: 1,
scale: 1,
period: 120,
chance: 1,
description: "Rumours of possible negotiations with the Thargoids have led to alien items being restricted."
},
{
govTypes: "5",
commodity: "machinery",
properties: "",
permit: 1,
scale: 1,
period: 120,
chance: 1,
description: "An industrial accident blamed on imported machinery has led to a total ban on any imports, pending further investigations."
},
{
govTypes: "5",
commodity: "gem_stones",
properties: "",
permit: 1,
scale: 1,
period: 12,
chance: 0.5,
description: "A diamond cartel has bought political favours and arranged for an embargo on imported gem-stones."
},
{
govTypes: "5,6,7",
commodity: "food",
properties: "",
permit: 1,
scale: 1,
period: 90,
chance: 1,
description: "To encourage and bolster local growers, imported food has been banned."
},
{
govTypes: "6",
commodity: "alien_items",
properties: "",
permit: 1,
scale: 1,
period: 120,
chance: 1,
description: "A pro-Thargoid political movement has gained power and banned sales of war-trophies."
},
{
govTypes: "6",
commodity: "furs",
properties: "",
permit: 1,
scale: 1,
period: 90,
chance: 1,
description: "Animal rights activists have gained power and put a halt to the import of furs."
},
{
govTypes: "6",
commodity: "alloys",
properties: "",
permit: 1,
scale: 1,
period: 90,
chance: 1,
description: "Environmental extremists have demanded more use of recycled metals and supplies in system to reduce waste."
},
{
govTypes: "6",
commodity: "liquor_wines",
properties: "",
permit: 1,
scale: 1,
period: 90,
chance: 1,
description: "A temperance movement has gained political influence and issued a ban on all alcoholic beverages."
},
{
govTypes: "6",
commodity: "radioactives",
properties: "",
permit: 1,
scale: 1,
period: 90,
chance: 1,
description: "An environmentalist movement has opposed the risks of radiation for industrial uses."
},
{
govTypes: "6",
commodity: "textiles",
properties: "",
permit: 1,
scale: 1,
period: 60,
chance: 1,
description: "An embarrassing media incident has rendered imported textiles a social taboo."
},
{
govTypes: "6",
commodity: "food",
properties: "",
permit: 1,
scale: 1,
period: 90,
chance: 1,
description: "Unhealthy foreign foods have been banned by locals."
},
{
govTypes: "6",
commodity: "gold,platinum",
properties: "",
permit: 1,
scale: 1,
period: 12,
chance: 0.5,
description: "Gold and platinum imports were seen as a destabilising influence on the local money market, so they have been banned."
},
{
govTypes: "7",
commodity: "alien_items",
properties: "",
permit: 1,
scale: 1,
period: 120,
chance: 1,
description: "Collectors of rare alien items have forced the government to block the flood of 'cheap counterfeits' to the market."
},
{
govTypes: "7",
commodity: "gold,platinum",
properties: "",
permit: 1,
scale: 1,
period: 12,
chance: 0.5,
description: "In an effort to reduce inflation, the system is restricting precious metal imports."
},
{
govTypes: "7",
commodity: "alloys",
properties: "",
permit: 1,
scale: 1,
period: 90,
chance: 1,
description: "The system has negotiated an exclusive contract for a specific manufactured alloy only, others are barred."
},
{
govTypes: "7",
commodity: "computers",
properties: "",
permit: 1,
scale: 1,
period: 90,
chance: 1,
description: "New computer models from the corporation are superior to foreign imports and have been given a local monopoly."
},
{
govTypes: "7",
commodity: "radioactives",
properties: "",
permit: 1,
scale: 1,
period: 90,
chance: 1,
description: "Due to a recent radioactive accident by the corporation, imports of materials are restricted pending safety investigations."
},
{
govTypes: "7",
commodity: "food",
properties: "",
permit: 1,
scale: 1,
period: 60,
chance: 1,
description: "'Naturally grown' foods have been replaced with synthetic foods produced by the corporation."
},
{
govTypes: "7",
commodity: "furs",
properties: "",
permit: 1,
scale: 1,
period: 90,
chance: 1,
description: "Imported furs have been banned, pending an investigation into a strain of disease-bearing mites found in some imports."
},
{
govTypes: "6,7",
commodity: "gem_stones",
properties: "",
permit: 1,
scale: 1,
period: 12,
chance: 0.5,
description: "A series of fake gem-stones making their way onto the market has prompted an embargo."
},
{
govTypes: "0,1,2,3,4,5,6,7",
commodity: "textiles",
properties: "solar",
permit: 1,
scale: 1,
period: 90,
chance: 1,
description: "Imported clothing provides inadequate protection from local solar activity, and has been banned."
},
{
govTypes: "0,1,2,3,4,5,6,7",
commodity: "liquor_wines",
properties: "brandy,brew,gargle blasters",
permit: 1,
scale: 1,
period: 120,
chance: 1,
description: "Imported liquor and wines were seen to be negatively impacting producers of local specialities and have been declared illegal."
},
{
govTypes: "0,1,2,3,4,5,6,7",
commodity: "food",
properties: "cuisine,soup,burgers,meat,cutlet,steak",
permit: 1,
scale: 1,
period: 90,
chance: 1,
description: "Imported food was influencing tastes away from local specialities, prompting a temporary trade embargo."
},
{
govTypes: "3,4,5,6,7",
commodity: "firearms",
properties: "",
permit: 1,
scale: 1,
period: 120,
chance: 0.5,
description: "Due to an increased number of firearm-related crimes, firearms have been declared illegal."
}
];
// these commodities will be included when checking for illegal imports on docking, but as they are global defaults we won't add them via the normal mechanisms
// slaves are not included here, as they are being kept as illegal to export only. This is (a) because some escape pods get stored as slaves,
// and (b) to keep the Illegal Goods Tweak in the loop
this._defaultAdditions = ["narcotics"];
// extra commodityInfo
// element 0 is permit costs
// element 1 is % over base price when item is illegal
// element 2 is % over base price for the black market price
this._commodityInfo = {
"food": [2500, 6.5, 2.2],
"textiles": [3000, 4.0, 2.0],
"radioactives": [5000, 2.5, 1.3],
"slaves": [4000, 0, 0],
"liquor_wines": [5000, 2.2, 1.1],
"luxuries": [6000, 2.1, 1.1],
"narcotics": [8000, 0, 0],
"computers": [6000, 2.1, 1.1],
"machinery": [5000, 2.2, 1.1],
"alloys": [3000, 2.2, 1.1],
"firearms": [5000, 2.2, 1.1],
"furs": [7000, 2.5, 1.4],
"minerals": [3000, 6.0, 2.1],
"gold": [8000, 1.3, 0.6],
"platinum": [9000, 1.1, 0.6],
"gem_stones": [8000, 1.8, 0.8],
"alien_items": [6000, 2.8, 1.3]
};
// holds all illegal good definitions for this sector
this._illegalGoods = []; // illegal goods currently in play in sector
this._permits = []; // permits currently held by player
this._originalCredits = 0; // value to hold the players credits (used to refund the cost of the initial item)
this._display = 0;
this._curpage = 0;
this._dataLoaded = false; // flag to indicate when data has been loaded
this._initialRun = true; // flag to indicate when the initial data set has been created
this._originating = -1;
this._startUpRunning = true;
this._markedSystems = [];
this._witchspaceDestination = -1;
this._done = false;
this._menuColor = "orangeColor";
this._itemColor = "yellowColor";
this._disabledColor = "darkGrayColor";
this._trueValues = ["yes", "1", 1, "true", true];
this._markerColors = ["whiteColor", "yellowColor", "orangeColor", "greenColor", "redColor", "blueColor", "purpleColor", "cyanColor"];
this._markerShapes = ["MARKER_X", "MARKER_PLUS", "MARKER_SQUARE", "MARKER_DIAMOND"];
this._firearmsColor = 2;
this._firearmsShape = 3;
this._mixedIllegalColor = 1;
this._mixedIllegalShape = 3;
// configuration settings for use in Lib_Config
this._siConfig = {
Name: this.name,
Alias: "Smugglers",
Display: "Config",
Alive: "_siConfig",
Notify: "$markSystems",
Bool: {
B0: {
Name: "_enableMarkedSystems",
Def: true,
Desc: "Mark nearby systems"
},
Info: "Turns on option of marking nearby systems with illegal goods on the galaxy map."
},
SInt: {
S0: {
Name: "_markedSystemRange",
Def: 7,
Min: 0,
Max: 15,
Desc: "Marked sys range"
},
S1: {
Name: "_firearmsColor",
Def: 2,
Min: 0,
Max: 7,
Desc: "Firearms illegal color"
},
S2: {
Name: "_mixedIllegalColor",
Def: 2,
Min: 0,
Max: 7,
Desc: "Mixed illegal color"
},
S3: {
Name: "_firearmsShape",
Def: 3,
Min: 0,
Max: 3,
Desc: "Firearm marker shape"
},
S4: {
Name: "_mixedIllegalShape",
Def: 3,
Min: 0,
Max: 3,
Desc: "Mixed illegal marker shape"
},
Info: "0: Defines range (LY) for marking illegal systems\n1/2: Mark color for illegal firearms/mixed (0=white, 1=yellow, 2=orange, 3=green, 4=red, 5=blue, 6=purple, 7=cyan)\n3/4: Mark shape for illegal firearms/mixed (0=X, 1=+, 2=square, 3=diamond)"
},
};
//-------------------------------------------------------------------------------------------------------------
this.$updateGeneralCommodityDefinition = function (goodDefinition, station, systemID) {
var si = worldScripts.Smugglers_Illegal;
if (goodDefinition.key == "slaves") {
goodDefinition.legality_export = 1;
goodDefinition.legality_import = 0;
return goodDefinition;
}
if (goodDefinition.key == "narcotics") {
goodDefinition.legality_export = 1;
goodDefinition.legality_import = 0;
goodDefinition.comment = expandDescription("[narcotics-legality-description]");
return goodDefinition;
}
if (goodDefinition.key == "firearms") {
goodDefinition.legality_export = 0;
goodDefinition.legality_import = 0;
goodDefinition.comment = expandDescription("[oolite-commodity-no-comment]");
}
if (si) {
// initialise the data if it hasn't been already
if (si._dataLoaded === false) si.$initialiseData();
if ((station === 0 || station == null) && systemID && systemID != -1) {
if (si._dataLoaded === true) {
if (si.$isGoodIllegal(systemID, goodDefinition.key)) {
goodDefinition.legality_import = si.$goodIllegalScale(systemID, goodDefinition.key);
}
}
}
}
return goodDefinition;
}
//-------------------------------------------------------------------------------------------------------------
this.$updateLocalCommodityDefinition = function (goodDefinition, station, systemID) {
var si = worldScripts.Smugglers_Illegal;
if (si && station && station.allegiance === "galcop") {
// apply price boost
if (si.$isGoodIllegal(systemID, goodDefinition.key)) {
// calculate the new price, based on the price limits in _commodityInfo
var newprice = Math.round(goodDefinition.price * (si._commodityInfo[goodDefinition.key][1] + ((system.scrambledPseudoRandomNumber(systemID) * 0.6) - 0.3)), 2);
// adjust the price property
if (si._debug) log(this.name, "changing price on " + goodDefinition.key + " from " + goodDefinition.price + " to " + newprice);
goodDefinition.price = newprice;
}
}
return goodDefinition;
}
//-------------------------------------------------------------------------------------------------------------
this.startUp = function () {
var msi = worldScripts.MarketScriptInterface_Main;
msi.$addMarketInterface("tradegoods_general", "$updateGeneralCommodityDefinition", this.name);
msi.$addMarketInterface("system_local", "$updateLocalCommodityDefinition", this.name, "lowest");
if (this._disabled) {
delete this.shipDockedWithStation;
delete this.playerBoughtEquipment;
delete this.shipWillEnterWitchspace;
delete this.shipExitedWitchspace;
delete this.playerEnteredNewGalaxy;
delete this.playerWillSaveGame;
delete this.guiScreenWillChange;
delete this.guiScreenChanged;
delete this.updateLocalCommodityDefinition;
delete this.dayChanged;
delete this.startUpComplete;
delete this.startUp;
return;
}
var core = worldScripts.Smugglers_CoreFunctions;
this.$padTextRight = core.$padTextRight;
this.$padTextLeft = core.$padTextLeft;
this.$isBigGuiActive = core.$isBigGuiActive;
this.$rand = core.$rand;
if (missionVariables.Smuggling_Permits) {
this._permits = JSON.parse(missionVariables.Smuggling_Permits);
delete missionVariables.Smuggling_Permits;
}
this._originating = system.ID;
delete this.startUp;
}
//-------------------------------------------------------------------------------------------------------------
this.startUpComplete = function () {
// register our settings, if Lib_Config is present
if (worldScripts.Lib_Config) worldScripts.Lib_Config._registerSet(this._siConfig);
// check for illegal goods tweak
if (worldScripts["illegal_goods_tweak"]) this._IGTInstalled = true;
// set up the interface screen, if required
this.$initMainInterface(player.ship.dockedStation);
this.$correctStartEndDates();
this._startUpRunning = false;
if (missionVariables.Smuggling_InitialRun) {
this._initialRun = missionVariables.Smuggling_InitialRun;
}
if (missionVariables.Smuggling_MarkedSystems) {
this._markedSystems = JSON.parse(missionVariables.Smuggling_MarkedSystems);
delete missionVariables.Smuggling_MarkedSystems;
}
// add our repair items to the email systems list of repair equipment
var w = worldScripts.EmailSystem;
if (w) {
var ga = worldScripts.GalCopAdminServices;
for (var i = 1; i <= 20; i++) {
ga._maint_repair_equip.push("EQ_SMUGGLING_COMPARTMENT_REPAIR_" + i);
}
}
// only load these settings if Library is installed
if (worldScripts.Lib_Config) {
if (missionVariables.Smugglers_MarkSystems) this._enableMarkedSystems = (this._trueValues.indexOf(missionVariables.Smugglers_MarkSystems) >= 0 ? true : false);
if (missionVariables.Smugglers_MarkSystemsRange) this._markedSystemRange = parseInt(missionVariables.Smugglers_MarkSystemsRange);
if (missionVariables.Smugglers_FirearmsColor) this._firearmsColor = parseInt(missionVariables.Smugglers_FirearmsColor);
if (missionVariables.Smugglers_MixedIllegalColor) this._mixedIllegalColor = parseInt(missionVariables.Smugglers_MixedIllegalColor);
if (missionVariables.Smugglers_FirearmsShape) this._firearmsShape = parseInt(missionVariables.Smugglers_FirearmsShape);
if (missionVariables.Smugglers_MixedIllegalShape) this._mixedIllegalShape = parseInt(missionVariables.Smugglers_MixedIllegalShape);
}
this.$markSystems();
}
//-------------------------------------------------------------------------------------------------------------
this.playerWillSaveGame = function () {
missionVariables.Smuggling_IllegalGoods = JSON.stringify(this._illegalGoods);
missionVariables.Smuggling_Permits = JSON.stringify(this._permits);
missionVariables.Smuggling_MarkedSystems = JSON.stringify(this._markedSystems);
missionVariables.Smuggling_InitialRun = this._initialRun;
// only save these settings if Library is installed
if (worldScripts.Lib_Config) {
missionVariables.Smugglers_MarkSystems = this._enableMarkedSystems;
missionVariables.Smugglers_MarkSystemsRange = this._markedSystemRange;
missionVariables.Smugglers_FirearmsColor = this._firearmsColor;
missionVariables.Smugglers_MixedIllegalColor = this._mixedIllegalColor;
missionVariables.Smugglers_FirearmsShape = this._firearmsShape;
missionVariables.Smugglers_MixedIllegalShape = this._mixedIllegalShape;
}
}
//-------------------------------------------------------------------------------------------------------------
this.shipDockedWithStation = function (station) {
this.$initMainInterface(station);
}
//-------------------------------------------------------------------------------------------------------------
this.shipWillLaunchFromStation = function (station) {
if (missionVariables.Smuggling_IllegalGoods) delete missionVariables.Smuggling_IllegalGoods;
if (missionVariables.Smuggling_Permits) delete missionVariables.Smuggling_Permits;
if (missionVariables.Smuggling_MarkedSystems) delete missionVariables.Smuggling_MarkedSystems;
}
//-------------------------------------------------------------------------------------------------------------
this.playerBoughtEquipment = function (equipmentKey) {
var p = player.ship;
if (equipmentKey === "EQ_IMPORT_PERMIT" || equipmentKey == "EQ_IMPORT_PERMIT_NC") {
p.removeEquipment(equipmentKey);
// give the player back the original amount, in case they decide not to purchase
if (this._originalCredits != 0) {
player.credits = this._originalCredits;
this._originalCredits = 0;
}
// mission screen to ask how many TC to allocate
this.$showPurchasePage();
}
}
//-------------------------------------------------------------------------------------------------------------
this.shipWillEnterWitchspace = function (cause, destination) {
this._witchspaceDestination = destination;
this._initialRun = true;
}
//-------------------------------------------------------------------------------------------------------------
this.shipExitedWitchspace = function () {
this._originating = system.ID;
this._done = false;
this.$markSystems();
}
//-------------------------------------------------------------------------------------------------------------
this.playerEnteredNewGalaxy = function (galNumber) {
// hopefully this is early enough in the sequence to establish illegal goods for the "smugglers_illegalmarket"
this._illegalGoods = [];
this._dataLoaded = false;
}
//-------------------------------------------------------------------------------------------------------------
this.dayChanged = function (newday) {
this.$cleanup();
}
//-------------------------------------------------------------------------------------------------------------
this.guiScreenWillChange = function (to, from) {
if (to === "GUI_SCREEN_MARKET") this.$updateDescriptions();
}
//-------------------------------------------------------------------------------------------------------------
this.guiScreenChanged = function (to, from) {
if (guiScreen === "GUI_SCREEN_EQUIP_SHIP") this._originalCredits = player.credits;
// This code puts all the illegal goods on the F7 screen. However, with the description in the F8F8 screen this code is possibly unnecessary.
// However, if there is feedback that says it would be useful I'll but it back in.
if (from === "GUI_SCREEN_SYSTEM_DATA" && guiScreen != "GUI_SCREEN_SYSTEM_DATA") {
// unhide the hud, if required
if (player.ship.hudHidden != this._hudHidden) {
player.ship.hudHidden = this._hudHidden;
}
}
if (guiScreen === "GUI_SCREEN_SYSTEM_DATA" && from != "GUI_SCREEN_SYSTEM_DATA") {
if (player.ship.isInSpace === false) {
// hide the hud to give us more room for text
this._hudHidden = player.ship.hudHidden;
if (this.$isBigGuiActive() === false) {
player.ship.hudHidden = true;
// force an update in XenonUI (if installed)
var xui = worldScripts.XenonUI;
if (xui) xui.guiScreenChanged("", "");
var xrui = worldScripts.XenonReduxUI;
if (xrui) xrui.guiScreenChanged("", "");
}
}
}
if (guiScreen === "GUI_SCREEN_SYSTEM_DATA") {
// load data onto screen at the end
if (!this._dataLoadDelay) this._dataLoadDelay = new Timer(this, this.$dataLoadDelay, 0.2, 0);
}
}
//-------------------------------------------------------------------------------------------------------------
this.infoSystemChanged = function (to, from) {
if (guiScreen === "GUI_SCREEN_SYSTEM_DATA") {
// load data onto screen at the end
if (!this._dataLoadDelay) this._dataLoadDelay = new Timer(this, this.$dataLoadDelay, 0.2, 0);
}
}
//-------------------------------------------------------------------------------------------------------------
this.$dataLoadDelay = function $dataLoadDelay() {
delete this._dataLoadDelay;
// append any system-specific illegal goods to the display
if (guiScreen != "GUI_SCREEN_SYSTEM_DATA") return;
var sysID = player.ship.targetSystem;
if (player.ship.hasOwnProperty("infoSystem")) sysID = player.ship.infoSystem;
var concealment = System.infoForSystem(galaxyNumber, sysID).concealment;
// if there is some form of concealment in effect, don't show anything
if (concealment > 0) return;
var goods = this.$illegalGoodsList(sysID);
var dis_list = "";
if (this._IGTInstalled === true) {
dis_list = expandDescription("[illegal-goods-f7-igt" + (player.ship.isInSpace === false ? "" : "-inflight") + "]");
} else {
dis_list = expandDescription("[illegal-goods-f7-std" + (player.ship.isInSpace === false ? "" : "-inflight") + "]");
}
if (player.ship.isInSpace === false) {
for (var i = 0; i < goods.length; i++) {
dis_list += "\nIllegal import -- " + this.$translateCommodityList(goods[i].commodity) + ": " + goods[i].description;
}
} else {
for (var i = 0; i < goods.length; i++) {
dis_list += ", " + this.$translateCommodityList(goods[i].commodity);
}
}
mission.addMessageText(dis_list);
}
//-------------------------------------------------------------------------------------------------------------
this.$initialiseData = function $initialiseData() {
this._dataLoaded = true;
// if the initial run flag isn't yet stored in the data, but there are other definitions, reset the flag to false
// that should prevent any extreme prices.
if (!missionVariables.Smuggling_InitialRun && missionVariables.Smuggling_IllegalGoods) {
this._initialRun = false;
}
if (missionVariables.Smuggling_IllegalGoods) {
this._illegalGoods = JSON.parse(missionVariables.Smuggling_IllegalGoods);
delete missionVariables.Smuggling_IllegalGoods;
}
if (this._illegalGoods.length == 0) {
this.$initialSetup();
this.$markSystems();
}
}
//-------------------------------------------------------------------------------------------------------------
// shows the installation page to select a compartment size
this.$showPurchasePage = function $showPurchasePage() {
var curChoices = {};
var p = player.ship;
var stn = p.dockedStation;
var rowAdjust = 0;
var pagesize = 18;
if (this.$isBigGuiActive() === true) pagesize = 24;
var key = "[permit-purchase-header]";
if (worldScripts["CargoTypeExtension"]) key = "[permit-purchase-header-nc]";
var text = expandDescription(key, {cash: formatCredits(player.credits, true, true)});
text += this.$padTextRight("Item", 20) + this.$padTextLeft("Cost", 10);
var goods = this.$illegalGoodsList(system.ID);
// remove any goods for which the player either already has a permit, or that no permit is allowed
for (var i = goods.length - 1; i >= 0; i--) {
if (goods[i].permit === 1) {
// if the player already has a permit for this item, remove it.
if (this.$playerHasPermit(system.ID, goods[i].commodity, false) === true) {
goods.splice(i, 1);
}
} else {
// if the item doesn't allow permits, remove it
goods.splice(i, 1);
}
}
for (var i = 0; i < goods.length; i++) {
var list = goods[i].commodity.split(",");
var cost = 0;
for (var j = 0; j < list.length; j++) {
cost += this._commodityInfo[list[j]][0] * (1 + (system.government + 1) / 8);
}
var menuitem = this.$padTextRight(this.$translateCommodityList(goods[i].commodity), 20) + this.$padTextLeft(formatCredits(cost, true, true), 10);
curChoices["01_PERMIT~" + goods[i].commodity] = {
text: menuitem,
alignment: "LEFT",
color: this._menuColor
};
}
curChoices["97_SPACER"] = "";
curChoices["99_EXIT"] = {
text: "[exit-no-change]",
color: this._itemColor
};
var def = "99_EXIT";
for (var i = 0; i < ((pagesize - 4) - goods.length); i++) {
curChoices["99_SPACER_" + i] = "";
}
var opts = {
screenID: "oolite-smugglers-permit-map",
title: "Import Permit Purchasing",
allowInterrupt: true,
exitScreen: "GUI_SCREEN_EQUIP_SHIP",
overlay: {
name: "stgu-form.png",
height: 546
},
choices: curChoices,
initialChoicesKey: def,
message: text
};
mission.runScreen(opts, this.$purchaseScreenHandler, this);
}
//-------------------------------------------------------------------------------------------------------------
this.$purchaseScreenHandler = function $purchaseScreenHandler(choice) {
if (!choice) return;
if (choice.indexOf("01_PERMIT") >= 0) {
var cmdty = choice.substring(choice.indexOf("~") + 1);
var list = cmdty.split(",");
var cost = 0;
for (var j = 0; j < list.length; j++) {
cost += this._commodityInfo[list[j]][0] * (1 + (system.government + 1) / 8);
}
this._permits.push({
systemID: system.ID,
commodity: cmdty,
fake: 0
});
// charge the player
player.credits -= cost;
// make sure the right email is sent to the player
var email = worldScripts.EmailSystem;
if (email) {
// send a notification email
var msg = expandDescription("[permit-purchase-email]", {
commodity: this.$translateCommodityList(cmdty).replace(", ", " and "),
amount: formatCredits(cost, true, true)
});
email.$createEmail({
sender: "GalCop Permit Authority",
subject: "Purchase of import permit",
date: clock.seconds,
message: msg
});
}
// apply the install time (15 minutes)
clock.addSeconds(900);
}
}
//-------------------------------------------------------------------------------------------------------------
// initialise the illegal goods F4 screen entries
this.$initMainInterface = function $initMainInterface(station) {
station.setInterface(this.name, {
title: "Illegal goods information",
category: "Station Interfaces",
summary: "Information relating to illegal goods in this sector.",
callback: this.$initialIllegalGoodsOptions.bind(this)
});
}
//-------------------------------------------------------------------------------------------------------------
this.$initialIllegalGoodsOptions = function $initialIllegalGoodsOptions() {
this._display = 0;
this._curpage = 0;
this.$illegalGoodsOptions();
}
//-------------------------------------------------------------------------------------------------------------
this.$illegalGoodsOptions = function $illegalGoodsOptions() {
function compareDate(a, b) {
if (a.started < b.started) return -1;
if (a.started > b.started) return 1;
return 0;
}
function compareSystem(a, b) {
if (a.systemID < b.systemID) return -1;
if (a.systemID > b.systemID) return 1;
return 0;
}
function compareSystemName(a, b) {
if (a.name < b.name) return -1;
if (a.name > b.name) return 1;
return 0;
}
var curChoices = {};
var text = "";
var p = player.ship;
var def = "";
var sbm = worldScripts.Smugglers_BlackMarket;
var col1 = 6;
var col2 = 10;
var pagesize = 20;
if (this.$isBigGuiActive() === true) {
pagesize = 26;
}
var govs = new Array();
for (var i = 0; i < 8; i++)
govs.push(String.fromCharCode(i));
var spc = String.fromCharCode(31);
// main menu
if (this._display === 0) {
text = "";
var recent = [];
for (var i = 0; i < this._illegalGoods.length; i++) {
// list all new items (less that 5 days since start
if (this._illegalGoods[i].started != 0 && ((clock.adjustedSeconds - this._illegalGoods[i].started) / 86400) < 7) {
recent.push({
name: System.systemNameForID(this._illegalGoods[i].systemID),
systemID: this._illegalGoods[i].systemID,
commodity: this.$translateCommodityList(this._illegalGoods[i].commodity),
description: this._illegalGoods[i].description,
started: this._illegalGoods[i].started
});
}
}
text = expandDescription("[recent-declarations]");
var lines = 3;
if (recent.length > 0) {
recent.sort(compareDate);
for (var i = 0; i < recent.length; i++) {
var info = System.infoForSystem(galaxyNumber, recent[i].systemID);
var rt = system.info.routeToSystem(info);
if (rt) {
var dist = rt.distance;
} else {
var dist = system.info.distanceToSystem(info);
}
var textitem = recent[i].name + " (" + govs[info.government] + spc + "TL" + (info.techlevel + 1) + ", dist: " + dist.toFixed(1) + "ly) -- " + recent[i].commodity + ": " + recent[i].description;
text += textitem + "\n";
var w = defaultFont.measureString(textitem);
lines += Math.ceil(w / 32);
if (lines >= (pagesize - 6)) break;
}
} else {
text += expandDescription("[recent-declarations-none]");
lines += 1;
}
text += expandDescription("[offer-selections]");
curChoices["01_INFO"] = {
text: "[illegal-sector]",
color: this._menuColor
};
curChoices["02_INRANGE"] = {
text: "[illegal-7ly]",
color: this._menuColor
};
curChoices["03_PLOT"] = {
text: "[illegal-course]",
color: this._menuColor
};
if (this._permits.length > 0) {
curChoices["04_PERMITS"] = {
text: "[list-permits]",
color: this._menuColor
};
lines += 1;
}
if (sbm._waypoints.length > 0) {
curChoices["05_WAYPOINTS"] = {
text: "[list-waypoints]",
color: this._menuColor
};
lines += 1;
}
curChoices["99_EXIT"] = {
text: "[illegal-return]",
color: this._itemColor
};
for (var i = 0; i < ((pagesize - 5) - lines); i++) {
curChoices["99_SPACER_" + i] = "";
// text += "\n";
}
this._curpage = 0;
def = "99_EXIT";
var opts = {
screenID: "oolite-smuggling-illegal-map",
title: "Illegal Goods Information",
allowInterrupt: true,
overlay: {
name: "stgu-warning.png",
height: 546
},
exitScreen: "GUI_SCREEN_INTERFACES",
choices: curChoices,
initialChoicesKey: def,
message: text
};
}
// illegal goods in sector
if (this._display === 1) {
var list = [];
var checking = [];
for (var i = 0; i < this._illegalGoods.length; i++) {
if (checking.indexOf(this._illegalGoods[i].systemID) === -1) {
list.push({
systemID: this._illegalGoods[i].systemID,
name: System.systemNameForID(this._illegalGoods[i].systemID)
});
checking.push(this._illegalGoods[i].systemID);
}
}
list.sort(compareSystemName);
var redux = 6;
var maxpages = Math.ceil(list.length / (pagesize - redux));
var pagestart = this._curpage * (pagesize - redux);
var pageend = this._curpage * (pagesize - redux) + (pagesize - redux);
if (pageend > list.length) pageend = list.length;
text = "Illegal import notifications - Page " + (this._curpage + 1) + " of " + (maxpages > 0 ? maxpages : "1") + "\n";
if (this._IGTInstalled === true) {
text += expandDescription("[notifications-extra-igt]");
} else {
text += expandDescription("[notifications-extra-std]");
}
for (var i = pagestart; i < pageend; i++) {
var info = System.infoForSystem(galaxyNumber, list[i].systemID);
var rt = system.info.routeToSystem(info);
if (rt) {
var dist = rt.distance;
} else {
var dist = system.info.distanceToSystem(info);
}
text += this.$padTextRight(info.name, col1) + this.$padTextRight("(" + govs[info.government] + spc + "TL" + (info.techlevel + 1) + ", dist: " + dist.toFixed(1) + "ly)", col2);
var iglist = "";
var goods = this.$illegalGoodsList(list[i].systemID);
for (var j = 0; j < goods.length; j++) {
var cmdty = goods[j].commodity;
var subitems = cmdty.split(",");
for (var k = 0; k < subitems.length; k++) {
iglist += (iglist === "" ? "" : ", ") + displayNameForCommodity(subitems[k]);
if (this.$playerHasPermit(list[i].systemID, subitems[k], false) === true) iglist += " (P)";
}
}
text += iglist + "\n";
}
if (this._curpage === maxpages - 1) {
curChoices["10_NEXTPAGE"] = {
text: "[illegal-nextpage]",
color: this._disabledColor,
unselectable: true
};
} else {
curChoices["10_NEXTPAGE"] = {
text: "[illegal-nextpage]",
color: this._menuColor
};
}
if (this._curpage === 0) {
curChoices["11_PREVPAGE"] = {
text: "[illegal-prevpage]",
color: this._disabledColor,
unselectable: true
};
} else {
curChoices["11_PREVPAGE"] = {
text: "[illegal-prevpage]",
color: this._menuColor
};
}
curChoices["98_EXIT"] = {
text: "[illegal-return]",
color: this._itemColor
};
def = "98_EXIT";
var opts = {
screenID: "oolite-smuggling-illegal-map",
title: "Illegal Goods Information",
allowInterrupt: true,
overlay: {
name: "stgu-warning.png",
height: 546
},
exitScreen: "GUI_SCREEN_INTERFACES",
choices: curChoices,
initialChoicesKey: this._lastChoice ? this._lastChoice : def,
message: text
};
}
// illegal goods on course
if (this._display === 2) {
var target = p.targetSystem;
var source = system.ID;
var myRoute = null;
if (source >= 0) {
if (p.hasEquipmentProviding("EQ_ADVANCED_NAVIGATIONAL_ARRAY")) {
myRoute = System.infoForSystem(galaxyNumber, source).routeToSystem(System.infoForSystem(galaxyNumber, target), p.routeMode);
} else {
myRoute = {};
myRoute.route = [];
if (source !== target) myRoute.route.push(source);
myRoute.route.push(target);
}
}
if (myRoute != null) {
var list = myRoute.route;
var redux = 6;
var maxpages = Math.ceil(list.length / (pagesize - redux));
var pagestart = this._curpage * (pagesize - redux);
var pageend = this._curpage * (pagesize - redux) + (pagesize - redux);
if (pageend > list.length) pageend = list.length;
text = "Illegal imports on current route" + (list.length > 0 ? " - Page " + (this._curpage + 1) + " of " + maxpages : "") + "\n";
if (this._IGTInstalled === true) {
text += expandDescription("[notifications-extra-igt]");
} else {
text += expandDescription("[notifications-extra-std]");
}
for (var i = pagestart; i < pageend; i++) {
var info = System.infoForSystem(galaxyNumber, list[i]);
var rt = system.info.routeToSystem(info);
if (rt && p.hasEquipmentProviding("EQ_ADVANCED_NAVIGATIONAL_ARRAY")) {
var dist = rt.distance;
} else {
var dist = system.info.distanceToSystem(info);
}
text += this.$padTextRight(info.name, col1) + this.$padTextRight("(" + govs[info.government] + spc + "TL" + (info.techlevel + 1) + ", dist: " + dist.toFixed(1) + "ly)", col2);
var iglist = "";
var goods = this.$illegalGoodsList(list[i]);
if (goods.length > 0) {
for (var j = 0; j < goods.length; j++) {
var cmdty = goods[j].commodity;
var subitems = cmdty.split(",");
for (var k = 0; k < subitems.length; k++) {
iglist += (iglist === "" ? "" : ", ") + displayNameForCommodity(subitems[k]);
if (this.$playerHasPermit(list[i], subitems[k], false) === true) iglist += " (P)";
}
}
text += iglist;
} else {
text += "None";
}
text += "\n";
}
} else {
var maxpages = 0;
var list = [];
if (system.ID === -1) {
text = "Illegal imports on current route\n\nError: Route information unable to be calculated in interstellar space.\n";
} else {
text = "Illegal imports on current route\n\nError: Route information unable to be calculated.\n";
}
}
if (this._curpage === maxpages - 1 || list.length === 0) {
curChoices["10_NEXTPAGE"] = {
text: "[illegal-nextpage]",
color: this._disabledColor,
unselectable: true
};
} else {
curChoices["10_NEXTPAGE"] = {
text: "[illegal-nextpage]",
color: this._menuColor
};
}
if (this._curpage === 0 || list.length === 0) {
curChoices["11_PREVPAGE"] = {
text: "[illegal-prevpage]",
color: this._disabledColor,
unselectable: true
};
} else {
curChoices["11_PREVPAGE"] = {
text: "[illegal-prevpage]",
color: this._menuColor
};
}
curChoices["98_EXIT"] = {
text: "[illegal-return]",
color: this._itemColor
};
def = "98_EXIT";
var opts = {
screenID: "oolite-smuggling-illegal-map",
title: "Illegal Goods Information",
allowInterrupt: true,
overlay: {
name: "stgu-warning.png",
height: 546
},
exitScreen: "GUI_SCREEN_INTERFACES",
choices: curChoices,
initialChoicesKey: this._lastChoice ? this._lastChoice : def,
message: text
};
}
// purchased (legal or otherwise) permits
if (this._display === 3) {
var redux = 6;
var maxpages = Math.ceil(this._permits.length / (pagesize - redux));
if (maxpages === 0) maxpages = 1;
text = "Import permits acquried" + (this._permits.length > 0 ? " - Page " + (this._curpage + 1) + " of " + maxpages : "") + "\n\n";
if (this._permits.length > 0) {
var pagestart = this._curpage * (pagesize - redux);
var pageend = this._curpage * (pagesize - redux) + (pagesize - redux);
if (pageend > this._permits.length) pageend = this._permits.length;
for (var i = pagestart; i < pageend; i++) {
var info = System.infoForSystem(galaxyNumber, this._permits[i].systemID);
text += " Import " + this.$translateCommodityList(this._permits[i].commodity) + " on " + info.name + "\n";
}
} else {
text += " None";
}
if (this._curpage === maxpages - 1 || this._permits.length === 0) {
curChoices["10_NEXTPAGE"] = {
text: "[illegal-nextpage]",
color: this._disabledColor,
unselectable: true
};
} else {
curChoices["10_NEXTPAGE"] = {
text: "[illegal-nextpage]",
color: this._menuColor
};
}
if (this._curpage === 0 || this._permits.length === 0) {
curChoices["11_PREVPAGE"] = {
text: "[illegal-prevpage]",
color: this._disabledColor,
unselectable: true
};
} else {
curChoices["11_PREVPAGE"] = {
text: "[illegal-prevpage]",
color: this._menuColor
};
}
curChoices["98_EXIT"] = {
text: "[illegal-return]",
color: this._itemColor
};
def = "98_EXIT";
var opts = {
screenID: "oolite-smuggling-illegal-map",
title: "Illegal Goods Information",
allowInterrupt: true,
overlay: {
name: "stgu-form.png",
height: 546
},
exitScreen: "GUI_SCREEN_INTERFACES",
choices: curChoices,
initialChoicesKey: this._lastChoice ? this._lastChoice : def,
message: text
};
}
// illegal goods in range
if (this._display === 4) {
var list = system.info.systemsInRange(7);
var redux = 6;
var maxpages = Math.ceil(list.length / (pagesize - redux));
var pagestart = this._curpage * (pagesize - redux);
var pageend = this._curpage * (pagesize - redux) + (pagesize - redux);
if (pageend > list.length) pageend = list.length;
text = "Illegal imports in 7LY range" + (list.length > 0 ? " - Page " + (this._curpage + 1) + " of " + maxpages : "") + "\n";
if (this._IGTInstalled === true) {
text += expandDescription("[notifications-extra-igt]");
} else {
text += expandDescription("[notifications-extra-std]");
}
for (var i = pagestart; i < pageend; i++) {
var rt = system.info.routeToSystem(list[i]);
if (rt) {
var dist = rt.distance;
} else {
var dist = system.info.distanceToSystem(list[i]);
}
text += this.$padTextRight(list[i].name, col1) + this.$padTextRight("(" + govs[list[i].government] + spc + "TL" + (list[i].techlevel + 1) + ", dist: " + dist.toFixed(1) + "ly)", col2);
var iglist = "";
var goods = this.$illegalGoodsList(list[i].systemID);
if (goods.length > 0) {
for (var j = 0; j < goods.length; j++) {
var cmdty = goods[j].commodity;
var subitems = cmdty.split(",");
for (var k = 0; k < subitems.length; k++) {
iglist += (iglist === "" ? "" : ", ") + displayNameForCommodity(subitems[k]);
if (this.$playerHasPermit(list[i].systemID, subitems[k], false) === true) iglist += " (P)";
}
}
text += iglist;
} else {
text += "None";
}
text += "\n";
}
if (this._curpage === maxpages - 1 || list.length === 0) {
curChoices["10_NEXTPAGE"] = {
text: "[illegal-nextpage]",
color: this._disabledColor,
unselectable: true
};
} else {
curChoices["10_NEXTPAGE"] = {
text: "[illegal-nextpage]",
color: this._menuColor
};
}
if (this._curpage === 0 || list.length === 0) {
curChoices["11_PREVPAGE"] = {
text: "[illegal-prevpage]",
color: this._disabledColor,
unselectable: true
};
} else {
curChoices["11_PREVPAGE"] = {
text: "[illegal-prevpage]",
color: this._menuColor
};
}
curChoices["98_EXIT"] = {
text: "[illegal-return]",
color: this._itemColor
};
def = "98_EXIT";
var opts = {
screenID: "oolite-smuggling-illegal-map",
title: "Illegal Goods Information",
allowInterrupt: true,
overlay: {
name: "stgu-warning.png",
height: 546
},
exitScreen: "GUI_SCREEN_INTERFACES",
choices: curChoices,
initialChoicesKey: this._lastChoice ? this._lastChoice : def,
message: text
};
}
// rock hermit waypoints purchased
if (this._display === 5) {
var redux = 6;
var maxpages = Math.ceil(sbm._waypoints.length / (pagesize - redux));
if (maxpages === 0) maxpages = 1;
text = "Rock Hermit waypoints acquired" + (sbm._waypoints.length > 0 ? " - Page " + (this._curpage + 1) + " of " + maxpages : "") + "\n\n";
if (sbm._waypoints.length > 0) {
var pagestart = this._curpage * (pagesize - redux);
var pageend = this._curpage * (pagesize - redux) + (pagesize - redux);
if (pageend > sbm._waypoints.length) pageend = sbm._waypoints.length;
for (var i = pagestart; i < pageend; i++) {
var info = System.infoForSystem(galaxyNumber, sbm._waypoints[i]);
var rt = system.info.routeToSystem(info);
if (rt) {
var dist = rt.distance;
} else {
var dist = system.info.distanceToSystem(info);
}
text += info.name + " (" + govs[info.government] + spc + "TL" + (info.techlevel + 1) + ", dist: " + dist.toFixed(1) + "ly)\n";
}
} else {
text += " None";
}
if (this._curpage === maxpages - 1 || sbm._waypoints.length === 0) {
curChoices["10_NEXTPAGE"] = {
text: "[illegal-nextpage]",
color: this._disabledColor,
unselectable: true
};
} else {
curChoices["10_NEXTPAGE"] = {
text: "[illegal-nextpage]",
color: this._menuColor
};
}
if (this._curpage === 0 || sbm._waypoints.length === 0) {
curChoices["11_PREVPAGE"] = {
text: "[illegal-prevpage]",
color: this._disabledColor,
unselectable: true
};
} else {
curChoices["11_PREVPAGE"] = {
text: "[illegal-prevpage]",
color: this._menuColor
};
}
curChoices["98_EXIT"] = {
text: "[illegal-return]",
color: this._itemColor
};
def = "98_EXIT";
var opts = {
screenID: "oolite-smuggling-waypoints-map",
title: "Rock Hermit Waypoints",
allowInterrupt: true,
overlay: {
name: "stgu-map_marker.png",
height: 546
},
exitScreen: "GUI_SCREEN_INTERFACES",
choices: curChoices,
initialChoicesKey: this._lastChoice ? this._lastChoice : def,
message: text
};
}
mission.runScreen(opts, this.$screenHandler, this);
}
//-------------------------------------------------------------------------------------------------------------
this.$screenHandler = function $screenHandler(choice) {
delete this._lastChoice;
switch (choice) {
case "01_INFO":
this._display = 1;
break;
case "02_INRANGE":
this._display = 4;
break;
case "03_PLOT":
this._display = 2;
this._curpage = 0;
break;
case "04_PERMITS":
this._display = 3;
this._curpage = 0;
break;
case "05_WAYPOINTS":
this._display = 5;
this._curpage = 0;
break;
case "10_NEXTPAGE":
this._curpage += 1;
break;
case "11_PREVPAGE":
this._curpage -= 1;
break;
case "98_EXIT":
this._display = 0;
break;
}
this._lastChoice = choice;
if (choice != "99_EXIT") {
this.$illegalGoodsOptions();
}
}
//-------------------------------------------------------------------------------------------------------------
// returns list of illegal goods for system id
this.$illegalGoodsList = function $illegalGoodsList(sysID, include) {
var list = [];
for (var i = 0; i < this._illegalGoods.length; i++) {
if (this._illegalGoods[i].systemID === sysID) list.push(this._illegalGoods[i]);
}
// include default definitions when running a check on docking
if (include && include === true) {
for (var i = 0; i < this._defaultAdditions.length; i++) {
list.push({
systemID: sysID,
commodity: this._defaultAdditions[i],
started: 0,
end: 0,
description: "",
permit: 0,
scale: 2
});
}
}
return list;
}
//-------------------------------------------------------------------------------------------------------------
// returns list of illegal goods for system id, but just the commodity names (split out if necessary)
this.$illegalGoodsListCommodityOnly = function $illegalGoodsListCommodityOnly(sysID, include) {
var list = [];
for (var i = 0; i < this._illegalGoods.length; i++) {
if (this._illegalGoods[i].systemID === sysID) {
var splitlist = this._illegalGoods[i].commodity.split(",");
for (var j = 0; j < splitlist.length; j++) {
list.push(splitlist[j]);
}
}
}
// include default definitions when running a check on docking
if (include && include === true) {
for (var i = 0; i < this._defaultAdditions.length; i++) {
list.push(this._defaultAdditions[i]);
}
}
return list;
}
//-------------------------------------------------------------------------------------------------------------
// returns a particular illegal goods definition
this.$illegalGoodsDefinition = function $illegalGoodsDefinition(sysID, commodity) {
for (var i = 0; i < this._illegalGoods.length; i++) {
if (this._illegalGoods[i].systemID === sysID && this._illegalGoods[i].commodity.indexOf(commodity) >= 0) return this._illegalGoods[i];
}
return null;
}
//-------------------------------------------------------------------------------------------------------------
// returns true if a particular good is illegal in a particular system, otherwise false;
this.$isGoodIllegal = function $isGoodIllegal(sysID, commodity) {
for (var i = 0; i < this._illegalGoods.length; i++) {
if (this._illegalGoods[i].systemID === sysID && this._illegalGoods[i].commodity.indexOf(commodity) >= 0) return true;
}
return false;
}
//-------------------------------------------------------------------------------------------------------------
this.$goodIllegalScale = function $goodIllegalScale(sysID, commodity) {
for (var i = 0; i < this._illegalGoods.length; i++) {
if (this._illegalGoods[i].systemID === sysID && this._illegalGoods[i].commodity.indexOf(commodity) >= 0) return this._illegalGoods[i].scale;
}
return 0;
}
//-------------------------------------------------------------------------------------------------------------
// initial setup of illegal goods in sector
this.$initialSetup = function $initialSetup() {
// first, add all default/permanent items
for (var i = 0; i < this._possibilities.length; i++) {
var item = this._possibilities[i];
if (item.period === -1) {
var govs = item.govTypes.split(",");
for (var j = 0; j < govs.length; j++) {
if (govs[j] != "") {
var planetlist = this.$getSystemsByGovernment(parseInt(govs[j]), item.properties);
for (var k = 0; k < planetlist.length; k++) {
if (planetlist[k].sun_gone_nova) continue;
this.$applyDefinition(planetlist[k].systemID, item, 0);
}
}
}
}
}
// next pick a random number of planets and apply an illegal good for them
// add the definitions, between 30 and 60 ** TODO: work out if this is too much or too little
if (!this.$rand) this.$rand = worldScripts.Smugglers_CoreFunctions.$rand; // make sure our rand function is available
for (var i = 1; i <= (this.$rand(30) + 30); i++) {
this.$addNewItem(this.$rand(20));
}
}
//-------------------------------------------------------------------------------------------------------------
// add a new random item to the list
this.$addNewItem = function $addNewItem(startDays, excludeSystem) {
var planetid = -1;
var sys;
var tries = 0;
do {
// pick a random planet
planetid = this.$rand(256) - 1;
sys = System.infoForSystem(galaxyNumber, planetid);
// don't create items in nova systems
if (sys.sun_gone_nova) planetid = -1;
// don't create items in the excluded system
if (planetid === excludeSystem) planetid = -1;
if (planetid >= 0) {
// check if this planet has any existing declarations
var existing = this.$illegalGoodsList(planetid);
var count = 0;
for (var i = 0; i < existing.length; i++) {
// count all the non-default items
if (existing[i].end != 0) count += 1;
}
// if this planet already has an item, skip it.
if (count > 0) planetid = -1;
}
tries += 1;
} while (planetid === -1 && tries < 5);
if (planetid === -1 && this._debug) log(this.name, "attempt to add illegal good failed");
// if we didn't end up finding a planet, exit now
if (planetid === -1) return;
// get a list of possibilities
var poss = this.$getPossibilitiesByGovernment(sys.government, sys.description);
// pick one from the list
var pick = this.$rand(poss.length) - 1;
// add the definition
this.$applyDefinition(planetid, poss[pick], startDays);
}
//-------------------------------------------------------------------------------------------------------------
// get a list of possible illegal goods for a particular government type (0-7)
this.$getPossibilitiesByGovernment = function $getPossibilitiesByGovernment(govType, planetDescription) {
var list = [];
for (var i = 0; i < this._possibilities.length; i++) {
if (this._possibilities[i].period != -1 && this._possibilities[i].govTypes.indexOf(govType.toString()) != -1 &&
(this._possibilities[i].properties === "" || this.$checkPlanetDescription(planetDescription, this._possibilities[i].properties) === true) &&
Math.random() < this._possibilities[i].chance) {
list.push(this._possibilities[i]);
}
}
return list;
}
//-------------------------------------------------------------------------------------------------------------
// checks the planet description to see if the property text is somewhere in it.
// properties can be a single piece of text (eg "something"), or split with a "," character (eg "something,somethingelse")
this.$checkPlanetDescription = function $checkPlanetDescription(descr, properties) {
if (properties.indexOf(",") === -1) {
if (descr.indexOf(properties) >= 0) {
return true;
} else {
return false;
}
} else {
var proplist = properties.split(",");
var result = false;
for (var i = 0; i < proplist.length; i++) {
if (descr.indexOf(proplist[i]) >= 0) result = true;
}
return result;
}
}
//-------------------------------------------------------------------------------------------------------------
// returns a list of planets of a particular government type (0-7) and (optionally) with a description that contains the "option" parameter (eg "civil war")
this.$getSystemsByGovernment = function $getSystemsByGovernment(govType, options) {
var planets = SystemInfo.filteredSystems(this, function (other) {
return (other.government === govType && ((options == null || options === "") || other.description.indexOf(options) >= 0));
});
return planets;
}
//-------------------------------------------------------------------------------------------------------------
// adds a definition to the active list
// sysID = planet ID
// def = illegal goods definition
// startDays = number of days to take off the current date, to start this item in the past. This is to simulate an active galaxy, so everything doesn't start from now.
this.$applyDefinition = function $applyDefinition(sysID, def, startDays) {
//log(this.name, "adding illegal good definition for system " + sysID + " for commodity " + def.commodity);
// does this definition already exist for this planet?
for (var i = 0; i < this._illegalGoods.length; i++) {
if (this._illegalGoods[i].systemID === sysID && this._illegalGoods[i].commodity === def.commodity) return;
}
var stime = 0;
var etime = 0;
// if we haven't been passed a start time, just do it for sometime in the last day
if (def.period != -1) {
if (this._startUpRunning === false) {
if (startDays == null || startDays === 0) {
stime = clock.seconds - this.$rand(86400);
} else {
// otherwise, the starttime is subtracted from the current clock (as days), converted to seconds
stime = clock.seconds - (startDays * 86400);
}
// set up the end point
etime = stime + ((def.period + (this.$rand(10) - 5)) * 86400);
} else {
// if this is running during the startup routine, we need to reapply start and end times after it's completed
if (startDays != 0) stime = (startDays * 86400) * -1;
// set up the end point
etime = ((def.period + (this.$rand(10) - 5)) * 86400);
}
} else {
stime = 0;
etime = 0;
}
if (def.period != -1 && this._debug) log(this.name, "adding illegal good definition for system " + sysID + " for commodity " + def.commodity + ", starting " + clock.clockStringForTime(stime) + ", ending " + clock.clockStringForTime(etime));
this._illegalGoods.push({
systemID: sysID,
commodity: def.commodity,
started: stime,
end: etime,
description: def.description,
permit: def.permit,
scale: def.scale
});
}
//-------------------------------------------------------------------------------------------------------------
// update start/end times created during the startup process
this.$correctStartEndDates = function $correctStartEndDates() {
for (var i = 0; i < this._illegalGoods.length; i++) {
if (this._illegalGoods[i].started < 0) {
var stime = clock.adjustedSeconds + this._illegalGoods[i].started;
var etime = stime + this._illegalGoods[i].end;
this._illegalGoods[i].started = stime;
this._illegalGoods[i].end = etime;
}
}
}
//-------------------------------------------------------------------------------------------------------------
// look for any expired items and remove them from the array, and possibly add a new one
this.$cleanup = function $cleanup() {
// remove expired items
for (var i = this._illegalGoods.length - 1; i >= 0; i--) {
if (this._illegalGoods[i].end != 0 && clock.adjustedSeconds > this._illegalGoods[i].end) {
if (this._debug) log(this.name, "removing item: " + this._illegalGoods[i].systemID + ", " + this._illegalGoods[i].commodity + " ended: " + clock.clockStringForTime(this._illegalGoods[i].end))
// do we have a permit for this one? If so, delete it
for (var j = this._permits.length - 1; j >= 0; j--) {
if (this._permits[j].systemID === this._illegalGoods[i].systemID && this._illegalGoods[i].commodity.indexOf(this._permits[j].commodity) >= 0) {
this._permits.splice(j, 1);
}
}
this._illegalGoods.splice(i, 1);
}
}
// add new items
var total = this.$rand(5) - this.$rand(3);
if (total > 0) {
if (this._debug) log(this.name, "going to try adding " + total + " new items");
for (var i = 1; i <= total; i++) {
// add new items, but not in the current system, because the illegal market script won't pick them up until the game is reloaded
this.$addNewItem(1, system.ID);
}
}
}
//-------------------------------------------------------------------------------------------------------------
// checks if the player has a permit for the system
// todo: add newcargos permit check
this.$playerHasPermit = function $playerHasPermit(sysID, cmdty, check) {
for (var i = 0; i < this._permits.length; i++) {
if (this._permits[i].systemID === sysID && this._permits[i].commodity === cmdty) {
// are we doing a validity check
if (check === true && this._permits[i].fake != 0) {
// did it pass?
if (Math.random() > this._permits[i].fake) {
// oh dear, looks like it was discovered as fake
return false;
} else {
// phew! passed!
return true;
}
} else {
// it's a bought one (or we're not bothering with how fake it is), so it's ok
return true;
}
}
}
return false;
}
//-------------------------------------------------------------------------------------------------------------
// removes a permits from the list
this.$removePermit = function $removePermit(sysID, cmdty) {
for (var i = this._permits.length - 1; i >= 0; i--) {
if (this._permits[i].systemID === sysID && this._permits[i].commodity === cmdty) {
this._permits.splice(i, 1);
}
}
}
//-------------------------------------------------------------------------------------------------------------
// returns display version of commodity list
this.$translateCommodityList = function $translateCommodityList(cmdty_list) {
var list = cmdty_list.split(",");
var ret = "";
for (var i = 0; i < list.length; i++) {
ret += (ret === "" ? "" : ", ") + displayNameForCommodity(list[i]);
}
return ret;
}
//-------------------------------------------------------------------------------------------------------------
// adds the F8F8 comment for illegal goods
this.$updateDescriptions = function $updateDescriptions() {
// note: for some reason descriptions added via the illegal market script are not being displayed. So we're forcing the issue here.
var nocomment = expandDescription("[oolite-commodity-no-comment]");
if (player.ship.docked) {
var sMarket = player.ship.dockedStation.market;
} else {
if (player.ship.target && player.ship.target.isStation) {
var bcMarket = Ship.shipDataForKey(player.ship.target.dataKey)["market_broadcast"];
if (!bcMarket) bcMarket = true;
else {
var trues = ["1", "true", "yes"];
bcMarket = bcMarket.toLowerCase();
if (trues.indexOf(bcMarket) !== -1) bcMarket = true;
else bcMarket = false;
}
if (bcMarket) {
var sMarket = player.ship.target.market;
} else {
var sMarket = system.mainStation.market;
}
} else {
if (system.isInterstellarSpace) return;
var sMarket = system.mainStation.market;
}
}
var goods = [];
if (system.ID != -1) {
goods = this.$illegalGoodsList(system.ID, true);
} else {
return;
}
for (var cmdty in sMarket) {
// work out what the comment should be for this commodity
var cmt = nocomment;
// special cases
if (cmdty === "slaves") cmt = expandDescription("[oolite-commodity-illegal]");
if (this._defaultAdditions.indexOf(cmdty) >= 0) cmt = expandDescription("[" + cmdty + "-legality-description]");
// if this is an illegal commodity at this station go and grab the description for it from our data
if (sMarket[cmdty].legality_import != 0 || sMarket[cmdty].legality_export != 0) {
for (var i = 0; i < goods.length; i++) {
if (goods[i].commodity.indexOf(cmdty) >= 0 && goods[i].description != "") cmt = goods[i].description;
}
} else {
// if it's legal here, but not legal at the main station, put up a warning message
if (system.mainStation.market[cmdty].legality_import != 0 || system.mainStation.market[cmdty].legality_export != 0) {
cmt = expandDescription("[main-station-illegal]");
} else {
// otherwise, just use the "no comment" comment.
cmt = nocomment;
}
}
// get the current comment
var orig = manifest.comment(cmdty);
// in most cases that's all we'll need
var curr_cmt = orig;
// but if another OXP has added their own comments, we'll need to get the first line
// if the OXP adds comments without first adding a linebreak this won't work, but it should be good for most circumstances
if (orig.indexOf("\n") >= 0) curr_cmt = orig.substring(0, orig.indexOf("\n"));
// replace the current comment with our new one
orig = orig.replace(curr_cmt, cmt);
// plonk it back into the comment field for this commodity
manifest.setComment(cmdty, orig);
}
}
//-------------------------------------------------------------------------------------------------------------
// mark local systems on the galactic chart that have illegal goods
this.$markSystems = function $markSystems() {
// clear out existing marks
for (var i = 0; i < this._markedSystems.length; i++) {
mission.unmarkSystem({
system: this._markedSystems[i],
name: "illegalgoods"
});
}
// reset the array
this._markedSystems.length = 0;
if (this._enableMarkedSystems === false) return;
// get all systems in 10 ly
var list = system.info.systemsInRange(this._markedSystemRange);
// mark systems that have illegal goods (other than narcs or slaves)
// system: firearms only = orange, everything else yellow
for (var i = 0; i < list.length; i++) {
var goods = this.$illegalGoodsList(list[i].systemID);
if (goods.length > 0) {
this._markedSystems.push(list[i].systemID);
if (goods.length > 1) {
// if there's more than one illegal, mark it with yellow
mission.markSystem({
system: list[i].systemID,
name: "illegalgoods",
markerColor: this._markerColors[this._mixedIllegalColor],
markerShape: this._markerShapes[this._mixedIllegalShape]
});
} else {
// if the only illegal is firearms, mark it with orange
if (goods[0].commodity === "firearms") {
mission.markSystem({
system: list[i].systemID,
name: "illegalgoods",
markerColor: this._markerColors[this._firearmsColor],
markerShape: this._markerShapes[this._firearmsShape]
});
} else {
// otherwise mark it with yellow
mission.markSystem({
system: list[i].systemID,
name: "illegalgoods",
markerColor: this._markerColors[this._mixedIllegalColor],
markerShape: this._markerShapes[this._mixedIllegalShape]
});
}
}
}
}
} |