Scripts/home_system.js |
(
function(){
"use strict";
this.name = "HomeSystem";
this.author = "phkb";
this.copyright = "2017 phkb";
this.description = "Controls the output of home system messages to the player, as well as applying home system benefits to the player.";
this.license = "CC BY-NC-SA 4.0";
/*
TODO:
Areas to add text to:
- Traders? probably not
Additional expenses:
- ongoing maintenance if visits per month is less than X?
slugging the player at random intervals seems cheap
- or reduce loyalty value if it doesn't increase steadily? (ie degrade reputation)
- sponsoring convoys heading to system by providing seed capital
force player to be involved or decline with a mission screen, or leave it as a mission via BB?
random/semi-random result?
could player be employed as an escort to ensure mission success
-
Special missions
Collect specialty from another system and bring it back?
Transport trade delegation to nearby system
Passenger cabin?
Additional benefits:
bonus equipment
?
*/
this._maxHomeSystems = 3;
this._homeSystems = [[],[],[],[],[],[],[],[]];
this._dockCounts = [{},{},{},{},{},{},{},{}];
this._investCounts = [{},{},{},{},{},{},{},{}];
this._messageNotification = {};
this._messageTime = {};
this._dockingStation = null;
this._messageTimer = null;
this._dockTimer = null;
this._dockAvail = false;
this._dockMessage = 0;
this._systemCounted = false;
this._playerRoles = [];
this._purchasePrice = 0;
this._simulator = false;
this._stationTypes = ["galcop"]; // just for galcop stations, or for any non-pirate station?
// this controls how many times the player must visit the system (and dock at one of the station types above) in order to get that benefit
this._levels = {
base: 0,
police: 2,
missions: 5,
pirate: 6,
dock_fee: 10,
dock_priority: 15,
clear_offender: 20,
fuel: 25,
trade: 30,
equip_rebate: 40,
ship_rebate: 50,
contracts: 60,
missions_2: 75,
equip_rebate_2: 100,
ship_rebate_2: 150
};
this._trueValues = ["yes", "1", 1, "true", true];
//-------------------------------------------------------------------------------------------------------------
this.startUpComplete = function() {
if (worldScripts["oolite-system-data-config"] && worldScripts["CommpressedF7Layout"]) {
worldScripts["oolite-system-data-config"].addChangeCallback(this.name, "$addInfoToSystemDataScreen");
delete this.guiScreenWillChange;
delete this.guiScreenChanged;
delete this.infoSystemWillChange;
}
if (missionVariables.HomeSystems) this._homeSystems = JSON.parse(missionVariables.HomeSystems);
if (missionVariables.HomeSystem_DockCounts) this._dockCounts = JSON.parse(missionVariables.HomeSystem_DockCounts);
if (missionVariables.HomeSystem_InvestCounts) this._investCounts = JSON.parse(missionVariables.HomeSystem_InvestCounts);
if (missionVariables.HomeSystem_Messages) this._messageNotification = JSON.parse(missionVariables.HomeSystem_Messages);
if (missionVariables.HomeSystem_Counted) this._systemCounted = (this._trueValues.indexOf(missionVariables.HomeSystem_Counted) >= 0 ? true : false);
if (missionVariables.HomeSystem_PlayerRoles) this._playerRoles = JSON.parse(missionVariables.HomeSystem_PlayerRoles);
// testing
//this._homeSystems[galaxyNumber].push(240);
//this._dockCounts[galaxyNumber][240] = 20;
//this._investCounts[galaxyNumber][240] = 4;
//this._homeSystems[galaxyNumber].push(1);
//this._homeSystems[galaxyNumber].push(2);
//this._homeSystems[galaxyNumber].push(3);
//player.ship.fuel = 0;
//this._homeSystems[galaxyNumber].push(system.ID);
//this._dockCounts[galaxyNumber][2] = 10;
//this._dockCounts[galaxyNumber][3] = 20;
//this._dockCounts[galaxyNumber][system.ID] = 100;
//this._dockCounts[galaxyNumber] = {};
//for (let i = 0; i < 256; i++) {
// this._dockCounts[galaxyNumber][i] = Math.floor(Math.random() * 1000 + 100);
//}
// make sure the current system gets logged if this is the first time we've been run
this.shipDockedWithStation(player.ship.dockedStation);
if (worldScripts.EmailSystem) {
// stop the normal purchase emails from being sent for these items
worldScripts.GalCopAdminServices._purchase_ignore_equip.push("EQ_HOMESYSTEM_CLEAN");
worldScripts.GalCopAdminServices._purchase_ignore_equip.push("EQ_HOMESYSTEM_OFFENDER");
worldScripts.GalCopAdminServices._purchase_ignore_equip.push("EQ_HOMESYSTEM_FUGITIVE");
worldScripts.GalCopAdminServices._purchase_ignore_equip.push("EQ_HOMESYSTEM_REMOVE");
worldScripts.GalCopAdminServices._purchase_ignore_equip.push("EQ_HOMESYSTEM_INVEST");
}
this.$checkForMarkedSystems();
this.$addInvestmentLevelToGalCopReputations();
this.$initInterface(player.ship.dockedStation);
}
//-------------------------------------------------------------------------------------------------------------
this.playerWillSaveGame = function() {
missionVariables.HomeSystems = JSON.stringify(this._homeSystems);
missionVariables.HomeSystem_DockCounts = JSON.stringify(this._dockCounts);
missionVariables.HomeSystem_InvestCounts = JSON.stringify(this._investCounts);
missionVariables.HomeSystem_Messages = JSON.stringify(this._messageNotification);
missionVariables.HomeSystem_Counted = this._systemCounted;
missionVariables.HomeSystem_PlayerRoles = JSON.stringify(this._playerRoles);
}
//-------------------------------------------------------------------------------------------------------------
this.playerBoughtEquipment = function(equipmentKey) {
let equip = null;
let stn = player.ship.dockedStation;
if (equipmentKey === "EQ_HOMESYSTEM_CLEAN" || equipmentKey === "EQ_HOMESYSTEM_OFFENDER" || equipmentKey === "EQ_HOMESYSTEM_FUGITIVE") {
player.ship.removeEquipment(equipmentKey);
let tot = this.$homeSystemCount();
if (tot >= this._maxHomeSystems) {
equip = EquipmentInfo.infoForKey(equipmentKey);
this._purchaseEquipKey = equipmentKey
stn = player.ship.dockedStation;
this._purchasePrice = ((parseInt(equip.price) / 10) * stn.equipmentPriceFactor).toFixed(1);
this.$askPlayerAboutRemoval();
} else {
this.$setHomeSystem(equipmentKey);
}
return;
}
if (equipmentKey === "EQ_HOMESYSTEM_REMOVE") {
this.$removeHomeSystem(system.ID);
this.$sendGoodbyeEmail(system.ID);
this.$swapRoles(false);
player.ship.removeEquipment(equipmentKey);
// send email
return;
}
if (equipmentKey === "EQ_HOMESYSTEM_INVEST") {
player.ship.removeEquipment(equipmentKey);
this.$askPlayerAboutInvestment();
return;
}
// equipment rebate?
if (this.$isHomeSystem(system.ID) === true && this.$checkLevel(system.ID, "equip_rebate") === true) {
if (this._stationTypes.indexOf(stn.allegiance) === -1) return;
let pct = 0.05;
if (this.$checkLevel(system.ID, "equip_rebate_2") === true) pct = 0.1;
equip = EquipmentInfo.infoForKey(equipmentKey);
if (parseInt(equip.price) <= 0) return;
let cost = (parseInt(equip.price) / 10) * stn.equipmentPriceFactor;
let refund = Math.floor(cost * pct);
if (refund > 0) {
player.credits += refund;
player.consoleMessage("You have been given a rebate of " + formatCredits(refund, false, true) + ".");
}
}
}
//-------------------------------------------------------------------------------------------------------------
this.playerBoughtNewShip = function(ship, price) {
if (this.$isHomeSystem(system.ID) === true && this.$checkLevel(system.ID, "ship_rebate") === true) {
let stn = player.ship.dockedStation;
if (this._stationTypes.indexOf(stn.allegiance) === -1) return;
let pct = 0.05;
if (this.$checkLevel(system.ID, "ship_rebate_2") === true) pct = 0.1;
let refund = Math.floor(price * pct);
if (refund > 0) {
player.credits += refund;
player.consoleMessage("You have been given a rebate of " + formatCredits(refund, false, true) + ".");
}
}
}
//-------------------------------------------------------------------------------------------------------------
this.shipWillEnterWitchspace = function() {
// clear out any message info
this._messageNotification = {};
this._systemCounted = false;
this.$stopTimers();
}
//-------------------------------------------------------------------------------------------------------------
this.playerEnteredNewGalaxy = function() {
if (this._homeSystems[galaxyNumber].length > 0) {
let hs = this._homeSystems[galaxyNumber];
for (let i = 0; i < hs.length; i++) {
mission.markSystem({system:hs[i], name:this.name, markerShape:"MARKER_DIAMOND", markerColor:"purpleColor", markerScale:2});
}
}
}
//-------------------------------------------------------------------------------------------------------------
this.shipExitedWitchspace = function() {
if (!this._dockCounts[galaxyNumber][system.ID]) this._dockCounts[galaxyNumber][system.ID] = 0;
if (this.$isHomeSystem(system.ID) === true && this.$checkLevel(system.ID, "contracts") === true && !system.isInterstellarSpace && !system.sun.hasGoneNova && system.mainStation) {
// must be a regular system with a main station
this.$addSpecialParcelContracts();
worldScripts["oolite-contracts-parcels"]._updateMainStationInterfacesList();
this.$addSpecialPassengerContracts();
worldScripts["oolite-contracts-passengers"]._updateMainStationInterfacesList();
}
this.$startTimer();
this.$swapRoles(this.$isHomeSystem(system.ID));
}
//-------------------------------------------------------------------------------------------------------------
this.escapePodSequenceOver = function() {
this._simulator = true;
}
//-------------------------------------------------------------------------------------------------------------
this.shipWillDockWithStation = function(station) {
if (this._simulator === true) return;
this.$stopTimers();
this._dockAvail = false;
if (this.$isHomeSystem(system.ID) === true) {
if (this.$checkLevel(system.ID, "dock_fee") === true) {
let df = worldScripts["Docking Fees"];
// turn off the docking fees for stations in home system
if (df) df._simulator = true;
}
if (this._stationTypes.indexOf(station.allegiance) >= 0 && player.ship.bounty < 50) {
let txt = expandDescription("[homesystem_dockingreport]"); // *** expansions required
if (this.$checkLevel(system.ID, "clear_offender") === true && player.ship.bounty > 0) {
txt += expandDescription("[homesystem_clearoffender]");
player.bounty = 0;
}
player.addMessageToArrivalReport(txt);
}
}
this._dockingStation = null;
// add the f4 interface
this.$initInterface(station);
}
//-------------------------------------------------------------------------------------------------------------
this.shipDockedWithStation = function(station) {
this._tellPlayerAboutFuel = false;
if (this._simulator === true) return;
if (this._stationTypes.indexOf(station.allegiance) >= 0) {
if (this._systemCounted === false) {
let oldLevel = this.$baseLevel(system.ID);
let current = 0;
if (!this._dockCounts[galaxyNumber]) this._dockCounts[galaxyNumber] = {};
if (this._dockCounts[galaxyNumber][system.ID]) current = parseInt(this._dockCounts[galaxyNumber][system.ID]);
current += 1;
this._dockCounts[galaxyNumber][system.ID] = current;
if (this.$isHomeSystem(system.ID) === true) this.$newBenefitEmail(system.ID, oldLevel, false);
this._systemCounted = true;
}
if (this.$isHomeSystem(system.ID) && this.$checkLevel(system.ID, "fuel") === true && player.ship.fuel < 7) {
player.ship.fuel = 7;
player.consoleMessage("You have received a complimentary refuelling, courtesy of your home system.");
let fe = worldScripts.FuelTweaks_FuelEconomy
if (fe && (fe.$isFuelAvailable(system.ID) === false || fe.$fuelRationsInUse(system.ID) === true)) {
this._tellPlayerAboutFuel = true;
}
}
}
this.$initInterface(station);
}
//-------------------------------------------------------------------------------------------------------------
this.missionScreenOpportunity = function() {
if (this._tellPlayerAboutFuel === true) {
this._tellPlayerAboutFuel = false;
mission.runScreen({
screenID:"oolite-homesystem-fuel-map",
title: "Complimentary Refuelling",
overlay: {name:"hs-home.png", height:546},
message: expandDescription("[homesystem_fuelmessage]"),
exitScreen: "GUI_SCREEN_INTERFACES"
});
}
}
//-------------------------------------------------------------------------------------------------------------
this.shipWillLaunchFromStation = function(station) {
this.$startTimer();
}
//-------------------------------------------------------------------------------------------------------------
this.shipLaunchedFromStation = function(station) {
if (this.$simulatorRunning()) {this._simulator = true; this.$stopTimers(); return;}
this._simulator = false;
if (this.$isHomeSystem(system.ID) === true) {
if (this._stationTypes.indexOf(station.allegiance) >= 0 && player.ship.bounty < 50 && (!this._messageNotification[station.displayName + "_departure"] || this._messageNotification[station.displayName + "_departure"] === false)) {
let txt = expandDescription("[homesystem_departurecomms]");
station.commsMessage(txt, player.ship);
this._messageNotification[station.displayName + "_departure"] = true;
}
}
}
//-------------------------------------------------------------------------------------------------------------
this.playerRequestedDockingClearance = function(message) {
/*switch (message) {
case "DOCKING_CLEARANCE_DENIED_TRAFFIC_OUTBOUND":
case "DOCKING_CLEARANCE_DENIED_TRAFFIC_INBOUND":
if (this.$isHomeSystem(system.ID) === true && this.$checkLevel(system.ID, "dock_priority") === true) {
this._dockTimer = new Timer(this, this.$autoDock, 5, 5);
}
case "DOCKING_CLEARANCE_GRANTED":
case "DOCKING_CLEARANCE_NOT_REQUIRED":
this._dockAvail = true;
let stn = player.ship.target;
if (stn.isStation && this._dockingStation == null) this._dockingStation = stn;
break;
case "DOCKING_CLEARANCE_DENIED_SHIP_FUGITIVE":
case "DOCKING_CLEARANCE_CANCELLED":
this._dockingStation = null;
break;
}*/
// Rather than try to get linter to ignore the use of the switch statement above, i've re-written the routine
// to hopefully make it easier to understand
// if we've been told we have to wait for incoming or outgoing ships, then start a timer for an autodock
if (message === "DOCKING_CLEARANCE_DENIED_TRAFFIC_OUTBOUND" ||
message === "DOCKING_CLEARANCE_DENIED_TRAFFIC_INBOUND") {
this._dockAvail = false;
if (this.$isHomeSystem(system.ID) === true && this.$checkLevel(system.ID, "dock_priority") === true) {
this._dockTimer = new Timer(this, this.$autoDock, 5, 5);
}
}
// what station is this?
if (message === "DOCKING_CLEARANCE_DENIED_TRAFFIC_OUTBOUND" ||
message === "DOCKING_CLEARANCE_DENIED_TRAFFIC_INBOUND" ||
message === "DOCKING_CLEARANCE_GRANTED" ||
message === "DOCKING_CLEARANCE_NOT_REQUIRED") {
let stn = player.ship.target;
if (stn.isStation && this._dockingStation == null) this._dockingStation = stn;
}
// clear out the stored station reference
if (message === "DOCKING_CLEARANCE_DENIED_SHIP_FUGITIVE" ||
message === "DOCKING_CLEARANCE_CANCELLED") {
this._dockingStation = null;
}
}
//-------------------------------------------------------------------------------------------------------------
this.playerDockingClearanceGranted = function() {
if (this.$isHomeSystem(system.ID) === true) {
this._dockAvail = true;
if (!this._messageNotification[this._dockingStation.displayName + "_docking"] || this._messageNotification[this._dockingStation.displayName + "_docking"] === false) {
let txt = expandDescription("[homesystem_dockcomms]");
this._dockingStation.commsMessage(txt, player.ship); // *** expansions required
this._messageNotification[this._dockingStation.displayName + "_docking"] = true;
}
}
}
//-------------------------------------------------------------------------------------------------------------
this.playerBoughtCargo = function(commodity, units, price) {
if (this.$isHomeSystem(system.ID) === true && this.$checkLevel(system.ID, "trade") === true && units > 0 && this._stationTypes.indexOf(player.ship.dockedStation.allegiance) >= 0) {
let tot = 0;
if (this._messageNotification["cargo_bought"]) tot = parseInt(this._messageNotification["cargo_bought"]);
let start = tot;
tot += units;
this._messageNotification["cargo_bought"] = tot;
let bonus = 0;
if (tot >= 10 && start < 10) bonus = 5;
if (tot >= 50 && start < 50) bonus = 10;
if (tot >= 100 && start < 100) bonus = 20;
if (tot >= 200 && start < 200) bonus = 50;
if (tot >= 500 && start < 500) bonus = 100;
if (bonus > 0) {
player.credits += bonus;
player.consoleMessage("You receive a trading bonus of " + formatCredits(bonus, true, false));
}
// apply this to the sold setting, so the player doesn't get awarded twice
//this._messageNotification["cargo_sold"] = tot;
}
}
//-------------------------------------------------------------------------------------------------------------
this.playerSoldCargo = function(commodity, units, price) {
if (this.$isHomeSystem(system.ID) === true && this.$checkLevel(system.ID, "trade") === true && units > 0 && this._stationTypes.indexOf(player.ship.dockedStation.allegiance) >= 0) {
let tot = 0;
if (this._messageNotification["cargo_bought"]) tot = parseInt(this._messageNotification["cargo_bought"]);
let start = tot;
tot -= units;
// mke sure the player can't just ossillate across one of the bonus points by buying and selling without moving
if (tot < 500 && start >= 500) tot = 500;
if (tot < 200 && start >= 200) tot = 200;
if (tot < 100 && start >= 100) tot = 100;
if (tot < 50 && start >= 50) tot = 50;
if (tot < 10 && start >= 10) tot = 10;
if (tot < 0) tot = 0;
this._messageNotification["cargo_bought"] = tot;
}
}
//-------------------------------------------------------------------------------------------------------------
this.shipBountyChanged = function(delta, reason) {
// remove any home system link if the player does something bad to make themselves a fugitive in the system
switch (reason) {
case "killed innocent":
case "killed police":
case "attacked police":
case "attacked main station":
if (delta > 0 && player.ship.bounty > 50 && this.$isHomeSystem(system.ID) === true) {
player.consoleMessage("Your home system privileges have been revoked.");
this.$removeHomeSystem(system.ID);
}
// reset the player's reputation
this._dockCounts[galaxyNumber][system.ID] = 0
this._investCounts[galaxyNumber][system.ID] = 0;
break;
}
}
//-------------------------------------------------------------------------------------------------------------
this.shipDied = function(whom, why) {
this.$stopTimers();
}
//-------------------------------------------------------------------------------------------------------------
this.guiScreenWillChange = function(to, from) {
if (to === "GUI_SCREEN_SYSTEM_DATA") this.$addInfoToSystemDataScreen();
}
//-------------------------------------------------------------------------------------------------------------
this.guiScreenChanged = function(to, from) {
if (to === "GUI_SCREEN_SYSTEM_DATA") this.$addInfoToSystemDataScreen();
}
//-------------------------------------------------------------------------------------------------------------
this.infoSystemWillChange = function(to, from) {
if (guiScreen === "GUI_SCREEN_SYSTEM_DATA") this.$addInfoToSystemDataScreen();
}
//-------------------------------------------------------------------------------------------------------------
this.$askPlayerAboutRemoval = function() {
let curChoices = {};
let txt = "";
let count = this.$homeSystemCount();
if (count >= this._maxHomeSystems) {
if (count === 1) {
txt = "In order to make this system your home, you must relinquish your home system privileges on " + System.systemNameForID(this._homeSystems[galaxyNumber][0]) + ". Do you wish to proceed?";
curChoices["0_UNSET"] = "Yes";
curChoices["9_NO"] = "No";
} else {
txt = "In order to make this system your home, you must relinquish your home system privileges on one of these systems:";
let set = this._homeSystems[galaxyNumber];
for (let i = 0; i < set.length; i++) {
curChoices[i + "_UNSET"] = System.systemNameForID(set[i]);
}
curChoices["9_NO"] = "Cancel purchase";
}
let opts = {
screenID: "oolite-homesystem-question-map",
title: "Home System",
overlay: {name:"hs-question.png", height:546},
allowInterrupt: false,
exitScreen: "GUI_SCREEN_EQUIP_SHIP",
choices: curChoices,
initialChoicesKey: "9_NO",
message: txt
};
mission.runScreen(opts, this.$questionHandler, this);
} else {
return;
}
}
//-------------------------------------------------------------------------------------------------------------
this.$questionHandler = function(choice) {
if (choice == null) return;
if (choice === "9_NO") {
// refund the player
player.credits += Math.floor(parseFloat(this._purchasePrice) * 10) / 10;
return;
}
if (choice.indexOf("_UNSET") >= 0) {
// unset the system
let idx = parseInt(choice.substring(0, 1), 10);
let sys = this._homeSystems[galaxyNumber][idx];
this.$removeHomeSystem(sys);
this.$sendGoodbyeEmail(sys);
player.consoleMessage("Home system privileges have been removed from " + System.systemNameForID(sys) + ".");
// check the count again -- if we're still over, go back and ask again
let count = this.$homeSystemCount();
if (count >= this._maxHomeSystems) {
this.$askPlayerAboutRemoval();
return;
}
this.$setHomeSystem(this._purchaseEquipKey);
}
}
//-------------------------------------------------------------------------------------------------------------
this.$askPlayerAboutInvestment = function() {
// if there's only one home system to invest in, force that choice
if (this.$homeSystemCount() === 1) {
this.$questionHandler2("0_INVEST");
return;
}
let curChoices = {};
let txt = "";
txt = "Select the system to which you wish to transfer your investment:";
let set = this._homeSystems[galaxyNumber];
for (let i = 0; i < set.length; i++) {
curChoices[i + "_INVEST"] = System.systemNameForID(set[i]);
}
curChoices["9_NO"] = "Cancel purchase";
let opts = {
screenID: "oolite-homesystem-question-map",
title: "Home System",
overlay: {name:"hs-question.png", height:546},
allowInterrupt: false,
exitScreen: "GUI_SCREEN_EQUIP_SHIP",
choices: curChoices,
initialChoicesKey: "9_NO",
message: txt
};
mission.runScreen(opts, this.$questionHandler2, this);
}
//-------------------------------------------------------------------------------------------------------------
this.$questionHandler2 = function(choice) {
if (choice == null) return;
if (choice === "9_NO") {
// refund the player
player.credits += 10000;
return;
}
if (choice.indexOf("_INVEST") >= 0) {
let idx = parseInt(choice.substring(0, 1), 10);
let sys = this._homeSystems[galaxyNumber][idx];
player.consoleMessage("Investment amount transferred to home system in " + System.systemNameForID(sys), 5);
if (!this._investCounts[galaxyNumber]) this._investCounts[galaxyNumber] = {};
let oldLevel = this.$baseLevel(sys);
let current = this.$investmentCount(galaxyNumber, sys);
current += 1;
this._investCounts[galaxyNumber][sys] = current;
// only send a new benefit email if the player is at that system
this.$newBenefitEmail(sys, oldLevel, false);
if (worldScripts.DayDiplomacy_060_Citizenships) {
let c = worldScripts.DayDiplomacy_060_Citizenships;
let s = System.infoForSystem(galaxyNumber, sys);
/*
According to the Diplomacy OXP, a citizenship costs somewhere between 900cr and 9000cr.
By contrast investment package costs 10000cr.
To bring these values into some form of alignment, I'm taking the number of investment packages purchased
and multiplying it by 500, then comparing that to the citizenship price for that system.
For example: if I've purchased 3 investment options, my equivalent amount would be 3 * 500 = 1500cr
That's enough to get you citizenship in some of the lower productivity systems, but not the higher ones.
The explanation for this is that the investment purchase is largely a commercial transaction, whereas
"citizenship" is more of a governmental transaction. However, a portion of the commercial transaction
is allocated to government, so, over time, the government will recognise the value of your commercial
input and award the citizenship.
Note: this is mucking around with the internals of Diplomacy and is liable to break in future versions
Note: the citizenship option will only be awarded once (when the equivalent investment amount surpasses
the citizenship price). Subsequent investment purchases will not award the citizenship, and if the
player revokes their citizenship, it will not be re-awarded. Also, if the player has previously had
citizenship, then revokes it, then purchases investment options that ultimately grant citizenship,
the previous revoking will not be remembered and citizenship will get purchased again.
*/
let inv = current * 500;
let oldinv = (current - 1) * 500;
let price = c.$getCitizenshipPrice(s);
if (c.$hasPlayerCitizenship(galaxyNumber, sys) === false && (oldinv < price && inv >= price)) {
// make sure we have enough credits to buy the citizenship
player.credits += price;
c._buyCitizenship(galaxyNumber, sys);
player.consoleMessage("You have been awarded citizenship in " + System.systemNameForID(sys), 5);
}
}
}
}
//-------------------------------------------------------------------------------------------------------------
this.$checkForShips = function $checkForShips() {
// after transmitting message, turn off "Greet ship" message in BroadcastComms, and add a "Reply" message instead
let ships = player.ship.checkScanner(true);
let rnd = Math.random;
let pirateLevel = this.$checkLevel(system.ID, "pirate");
if (ships && ships.length > 0) {
for (let i = 0; i < ships.length; i++) {
let shp = ships[i];
// police ship
if (shp.isPolice && shp.isStation === false && player.ship.bounty === 0 && shp.hasHostileTarget === false && (!shp.script._welcomed || shp.script._welcomed === false)) {
// only send a police welcome message every 10 minutes at most
if (rnd() > 0.5 && (!this._messageNotification["police"] || clock.adjustedSeconds - this._messageNotification["police"] > 600)) {
let txt = expandDescription("[homesystem_policegreeting]");
shp.commsMessage(txt, player.ship); // ** expansions required
shp.script._welcomed = true;
// note the time we did this, so we can avoid spamming the player
this._messageNotification["police"] = clock.adjustedSeconds;
let bcc = worldScripts.BroadcastCommsMFD;
if (bcc) {
// turn off the greet ship message
bcc.$addShipToArray(shp, bcc._greeted);
// add a reply option
bcc.$createMessage({
messageName:"hs_transmit_police_reply_" + shp.entityPersonality.toString(),
displayText:"Send reply",
messageText:expandDescription("[homesystem_policereply]"), // ** expansions required
ship:shp,
transmissionType:"target",
callbackFunction:this.$messageReplyPolice,
deleteOnTransmit:true,
delayCallback:0,
hideOnConditionRed:true}
);
}
break;
}
}
// trader
// pirate
if (pirateLevel === true && shp.bounty >= 0 && shp.hasHostileTarget === false && (Ship.roleIsInCategory(shp.primaryRole, "oolite-pirate") || (shp.AI && shp.AI.toLowerCase().indexOf("pirate") >= 0) || (shp.AIScript && shp.AIScript.name.toLowerCase().indexOf("pirate") >= 0))) {
// only send a pirate "welcome" message every 5 minutes at most
if ((!shp.script._welcomed || shp.script._welcomed === false) && rnd() > 0.5 && (!this._messageNotification["pirate"] || clock.adjustedSeconds - this._messageNotification["pirate"] > 300)) {
let txt = expandDescription("[homesystem_pirategreeting]");
shp.commsMessage(txt, player.ship); // ** expansions required
shp.script._welcomed = true;
// note the time we did this, so we can avoid spamming the player
this._messageNotification["pirate"] = clock.adjustedSeconds;
let bcc = worldScripts.BroadcastCommsMFD;
if (bcc) {
// turn off the greet ship message
bcc.$addShipToArray(shp, bcc._greeted);
// add a reply option
bcc.$createMessage({
messageName:"hs_transmit_pirate_reply_" + shp.entityPersonality.toString(),
displayText:"Send reply",
messageText:expandDescription("[homesystem_piratereply]"), // ** expansions required
ship:shp,
transmissionType:"target",
callbackFunction:this.$messageReplyPirate,
deleteOnTransmit:true,
delayCallback:0,
hideOnConditionRed:true}
);
// ideally, we need a way of disabling this response if any other type is sent by the player to this ship
}
break;
}
}
}
}
}
//-------------------------------------------------------------------------------------------------------------
this.$messageReplyPolice = function() {
}
//-------------------------------------------------------------------------------------------------------------
this.$messageReplyPirate = function() {
}
//-------------------------------------------------------------------------------------------------------------
this.$startTimer = function() {
if (this.$isHomeSystem(system.ID) === true && this.$checkLevel(system.ID, "police") === true) {
// start a timer to being monitoring the scanner for ships that might want to say hi to the player
this._messageTimer = new Timer(this, this.$checkForShips, 10, 10);
}
}
//-------------------------------------------------------------------------------------------------------------
this.$stopTimers = function() {
if (this._messageTimer && this._messageTimer.isRunning) this._messageTimer.stop();
if (this._dockTimer && this._dockTimer.isRunning) this._dockTimer.stop();
}
//-------------------------------------------------------------------------------------------------------------
this.$autoDock = function() {
if (this._dockingStation == null) return;
if (this._dockAvail === true) {
if (this._dockMessage >= 3) {
this._dockingStation.commsMessage("Sorry for the delay, commander.", player.ship);
}
this._dockTimer.stop();
return;
}
this._dockMessage += 1;
switch (this._dockMessage) {
case 1:
this._dockingStation.commsMessage("We're trying to clear a slot for you, Commander [commander_name].", player.ship);
break;
case 3:
this._dockingStation.commsMessage("We may have to auto-dock you to skip the queue. Stand by.", player.ship);
break;
case 7:
this._dockingStation.commsMessage("Starting auto-dock process, commander. Stand-by.", player.ship);
break;
case 8:
this._dockingStation.dockPlayer();
// only a 5 minute time delay
clock.addSeconds(300);
}
}
//-------------------------------------------------------------------------------------------------------------
this.$setHomeSystem = function(equipmentKey) {
this._homeSystems[galaxyNumber].push(system.ID);
mission.markSystem({system:system.ID, name:this.name, markerShape:"MARKER_DIAMOND", markerColor:"purpleColor", markerScale:2});
this.$swapRoles(true);
// send email welcoming the player "home"
if (worldScripts.EmailSystem) {
let ga = worldScripts.GalCopAdminServices;
let e = worldScripts.EmailSystem;
e.$createEmail(
{sender:"Station Manager",
subject:"Home system privileges",
date:clock.adjustedSeconds,
sentFrom:system.ID,
message:expandDescription("[homesystem_email_" + equipmentKey + "]"),
expiryDays:ga._defaultExpiryDays
});
this.$newBenefitEmail(system.ID, this.$baseLevel(system.ID) - 1, true);
}
this.$addInvestmentLevelToGalCopReputations();
}
//-------------------------------------------------------------------------------------------------------------
this.$isHomeSystem = function(sysID) {
return (parseInt(sysID) >= 0 && this._homeSystems[galaxyNumber].indexOf(parseInt(sysID)) >= 0);
}
//-------------------------------------------------------------------------------------------------------------
this.$homeSystemCount = function() {
return this._homeSystems[galaxyNumber].length;
}
//-------------------------------------------------------------------------------------------------------------
this.$baseLevel = function(sysID) {
return (parseInt(this._dockCounts[galaxyNumber][parseInt(sysID)]) + (this.$investmentCount(galaxyNumber, parseInt(sysID)) * 2));
}
//-------------------------------------------------------------------------------------------------------------
this.$checkLevel = function(sysID, lvl) {
let min = this.$levelCalc(sysID, lvl);
return (this.$baseLevel(sysID) >= min);
}
//-------------------------------------------------------------------------------------------------------------
this.$checkLevelValue = function(sysID, lvl, value) {
let min = this.$levelCalc(sysID, lvl);
return (value >= min);
}
//-------------------------------------------------------------------------------------------------------------
this.$levelCalc = function(sysID, lvl) {
let min = this._levels[lvl];
let sys = (parseInt(sysID) === system.ID ? system.info : System.infoForSystem(galaxyNumber, parseInt(sysID)));
let factor = 1 + (sys.government + (7 - sys.economy) * 2 + sys.techlevel * 2) / 55;
return parseInt(min * factor);
}
//-------------------------------------------------------------------------------------------------------------
this.$removeHomeSystem = function(sysID) {
let set = this._homeSystems[galaxyNumber];
let idx = set.indexOf(parseInt(sysID));
if (idx >= 0) set.splice(idx, 1);
this._investCounts[galaxyNumber][parseInt(sysID)] = 0;
mission.unmarkSystem({system:sysID, name:this.name});
this.$removeGalCopReputation(sysID);
}
//-------------------------------------------------------------------------------------------------------------
// make all the player's roles "player-home" (or swap them back to what they were originally)
// by doing this we can ensure a consistent view of the player while they're "home"
this.$swapRoles = function(swapIn) {
if (swapIn === true) {
// copy all existing roles to holding array
if (player.roleWeights[0] === "player-home" || player.roleWeights[1] === "player-home" || player.roleWeights[2] === "player-home") return; // looks like we've already swapped things in
this._playerRoles.length = 0;
for (let i = 0; i < player.roleWeights.length; i++) {
this._playerRoles.push(player.roleWeights[i]);
player.setPlayerRole("player-home", i);
}
} else {
if (this._playerRoles.length === 0) return; // no data to swap back
if (player.roleWeights[0] !== "player-home" || player.roleWeights[1] !== "player-home" || player.roleWeights[2] !== "player-home") return; // looks like we haven't swapped anything out yet
for (let i = 0; i < this._playerRoles.length; i++) {
// only update the ones that are still "player-home"
// just in case any player action insystem causes a change.
if (player.roleWeights[i] === "player-home") player.setPlayerRole(this._playerRoles[i], i);
}
this._playerRoles.length = 0;
}
}
//-------------------------------------------------------------------------------------------------------------
this.$newBenefitEmail = function(sysID, oldLevel, initial) {
let txt = "";
let types = "a new benefit";
let count = 0;
let e = worldScripts.EmailSystem;
if (!e) return;
if (this.$checkLevelValue(sysID, "dock_fee", oldLevel) === false && this.$checkLevel(sysID, "dock_fee") === true && worldScripts["Docking Fee"]) {
txt += "\n" + expandDescription("[homesystem_benefit_dock_fee]");
count += 1;
}
if (this.$checkLevelValue(sysID, "dock_priority", oldLevel) === false && this.$checkLevel(sysID, "dock_priority") === true) {
txt += "\n" + expandDescription("[homesystem_benefit_dock_priority]");
count += 1;
}
if (this.$checkLevelValue(sysID, "clear_offender", oldLevel) === false && this.$checkLevel(sysID, "clear_offender") === true) {
txt += "\n" + expandDescription("[homesystem_benefit_clear_offender]");
count += 1;
}
if (this.$checkLevelValue(sysID, "missions", oldLevel) === false && this.$checkLevel(sysID, "missions") === true && worldScripts.GalCopBB_Missions) {
txt += "\n" + expandDescription("[homesystem_benefit_missions]");
count += 1;
}
if (this.$checkLevelValue(sysID, "missions_2", oldLevel) === false && this.$checkLevel(sysID, "missions_2") === true && worldScripts.GalCopBB_Missions) {
txt += "\n" + expandDescription("[homesystem_benefit_missions_2]");
count += 1;
}
if (this.$checkLevelValue(sysID, "contracts", oldLevel) === false && this.$checkLevel(sysID, "contracts") === true) {
txt += "\n" + expandDescription("[homesystem_benefit_contracts]");
count += 1;
}
if (this.$checkLevelValue(sysID, "fuel", oldLevel) === false && this.$checkLevel(sysID, "fuel") === true) {
txt += "\n" + expandDescription("[homesystem_benefit_fuel]");
count += 1;
}
if (this.$checkLevelValue(sysID, "trade", oldLevel) === false && this.$checkLevel(sysID, "trade") === true) {
txt += "\n" + expandDescription("[homesystem_benefit_trade]");
count += 1;
}
if (this.$checkLevelValue(sysID, "equip_rebate", oldLevel) === false && this.$checkLevel(sysID, "equip_rebate") === true) {
txt += "\n" + expandDescription("[homesystem_benefit_equip_rebate]");
count += 1;
}
if (this.$checkLevelValue(sysID, "ship_rebate", oldLevel) === false && this.$checkLevel(sysID, "ship_rebate") === true) {
txt += "\n" + expandDescription("[homesystem_benefit_ship_rebate]");
count += 1;
}
if (this.$checkLevelValue(sysID, "equip_rebate_2", oldLevel) === false && this.$checkLevel(sysID, "equip_rebate_2") === true) {
txt += "\n" + expandDescription("[homesystem_benefit_equip_rebate_2]");
count += 1;
}
if (this.$checkLevelValue(sysID, "ship_rebate_2", oldLevel) === false && this.$checkLevel(sysID, "ship_rebate_2") === true) {
txt += "\n" + expandDescription("[homesystem_benefit_ship_rebate_2]");
count += 1;
}
if (txt !== "") {
if (count > 1) types = "some new benefits";
// something's changed, so send the email
let ga = worldScripts.GalCopAdminServices;
let msg = expandDescription("[homesystem_benefit_email]", {benefits:txt, types:types, display_initial:(initial === true ? "We're so glad you're continuing to visit our station and make use of our facilities. " : "")});
let sndr = "Station Manager";
let delay = 0;
if (system.ID != parseInt(sysID)) {
sndr = System.systemNameForID(sysID) + " Station Manager";
msg = expandDescription("[homesystem_benefit_remote_email]", {benefits:txt, types:types, system:System.systemNameForID(sysID)});
let dist = system.info.distanceToSystem(System.infoForSystem(galaxyNumber, sysID));
delay = dist * 3600; // 1 hour for every ly
}
e.$createEmail({
sender:sndr,
subject:"Home system privileges",
date:clock.adjustedSeconds + delay,
sentFrom:sysID,
message:msg,
expiryDays:ga._defaultExpiryDays
});
}
}
//-------------------------------------------------------------------------------------------------------------
this.$sendGoodbyeEmail = function(sysID) {
let sysname = System.systemNameForID(sysID);
let ga = worldScripts.GalCopAdminServices;
let e = worldScripts.EmailSystem;
if (!e) return;
e.$createEmail(
{sender:sysname + " Station Manager",
subject:"Home system privileges",
date:clock.adjustedSeconds,
sentFrom:sysID,
message:expandDescription("[homesystem_leaving_email]", {system_name:sysname}),
expiryDays:ga._defaultExpiryDays
});
}
//-------------------------------------------------------------------------------------------------------------
this.$addSpecialParcelContracts = function() {
// possibly add some high-value contracts
let numContracts = Math.floor(Math.random() * 3);
for (let i = 0; i < numContracts; i++) {
let parcel = {};
// pick a random system to take the parcel to
let destination = Math.floor(Math.random()*256);
// discard if chose the current system
if (destination === system.ID) continue;
// get the SystemInfo object for the destination
let destinationInfo = System.infoForSystem(galaxyNumber,destination);
if (destinationInfo.sun_gone_nova) continue;
// check that a route to the destination exists
let routeToDestination = system.info.routeToSystem(destinationInfo);
// if the system cannot be reached, discard the parcel
if (!routeToDestination) continue;
// we now have a valid destination, so generate the rest of
// the parcel details
parcel.destination = destination;
// we'll need this again later, and route calculation is slow
parcel.route = routeToDestination;
parcel.sender = randomName() + " " + randomName();
// time allowed for delivery is time taken by "fewest jumps"
// route, plus 10-110%, plus four hours to make sure all routes
// are "in time" for a reasonable-length journey in-system.
let dtime = Math.floor((routeToDestination.time * 3600 * (1.1 + (Math.random())))) + 14400;
parcel.deadline = clock.adjustedSeconds + dtime;
parcel.risk = Math.floor(Math.random() * 3);
if (parcel.risk < 2 && destinationInfo.government <= 1 && Math.random() < 0.5) parcel.risk++;
parcel.description = expandDescription("[hs_parcel-description-risk" + parcel.risk + "]");
// total payment is small for these items.
parcel.payment = Math.floor(
// 2-3 credits per LY of route
(routeToDestination.distance * (2 + Math.random())) +
// additional income for route length based on reputation
(Math.pow(routeToDestination.route.length, 1 + (parcel.risk * 0.4) + (0.2 * player.parcelReputationPrecise))) +
// small premium for delivery to more dangerous systems
(2 * Math.pow(7 - destinationInfo.government, 1.5))
);
parcel.payment *= (Math.random() + Math.random() + Math.random() + Math.random()) / 2;
let prudence = (2 * Math.random()) - 1;
let desperation = (Math.random() * (0.5 + parcel.risk)) * (1 + 1 / (Math.max(0.5, dtime - (routeToDestination.time * 3600))));
let competency = Math.max(50, (routeToDestination.route.length - 1) * (0.5 + (parcel.risk * 2)));
if (parcel.risk == 0) competency -= 30;
parcel.payment = Math.floor(parcel.payment * (1 + (0.4 * prudence)));
parcel.payment += (parcel.risk * 200);
// anywhere from 2 to 5 times the normal payment
parcel.payment *= Math.floor(Math.random() * (parcel.risk + 1) + 2);
// paying this little probably can't ask for anyone good
if (parcel.payment < 100) competency -= 15;
parcel.skill = competency + 20 * (prudence - desperation);
// upper limit on skill
if (parcel.skill > 60) parcel.skill = 60;
//log(this.name, "parcel " + parcel.payment, parcel.skill, parcel.risk);
// add parcel to contract list
worldScripts["oolite-contracts-parcels"]._addParcelToSystem(parcel);
}
}
//-------------------------------------------------------------------------------------------------------------
this.$addSpecialPassengerContracts = function() {
let numContracts = Math.floor(Math.random * 4 - 1);
if (numContracts < 0) numContracts = 0;
// some of these possible contracts may be discarded later on
for (let i = 0; i < numContracts; i++) {
let passenger = {};
// pick a random system to take the passenger to
let destination = Math.floor(Math.random() * 256);
// discard if chose the current system
if (destination === system.ID) continue;
// get the SystemInfo object for the destination
let destinationInfo = System.infoForSystem(galaxyNumber,destination);
if (destinationInfo.sun_gone_nova) continue;
let daysUntilDeparture = 1 + (Math.random() * (7 + player.passengerReputationPrecise - destinationInfo.government));
// loses some more contracts if reputation negative
if (daysUntilDeparture <= 0) continue;
// check that a route to the destination exists
let 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 passenger details
passenger.destination = destination;
// we'll need this again later, and route calculation is slow
passenger.route = routeToDestination;
// 50% local inhabitant
if (Math.random() < 0.5) {
passenger.species = system.info.inhabitant;
} else {
// 50% random species (which will be 50%ish human)
passenger.species = System.infoForSystem(galaxyNumber, Math.floor(Math.random() * 256)).inhabitant;
}
if (passenger.species.match(new RegExp(expandDescription("[human-word]"), "i"))) {
passenger.name = expandDescription("%N ") + expandDescription("[nom]");
} else {
passenger.name = randomName() + " " + randomName();
}
/* Because passengers with duplicate names won't be accepted,
* check for name duplication with either other passengers
* here or other passengers carried by the player, and adjust
* this passenger's name a little if there's a match */
do {
let okay = true;
for (let j = 0; j < player.ship.passengers.length; j++) {
if (player.ship.passengers[j].name == passenger.name) {
okay = false;
break;
}
}
if (okay) {
for (let j = 0; j < worldScripts["oolite-contracts-passengers"].$passengers.length; j++) {
if (worldScripts["oolite-contracts-passengers"].$passengers[j].name == passenger.name) {
okay = false;
break;
}
}
}
if (!okay) passenger.name += "a";
} while (!okay);
passenger.risk = Math.floor(Math.random() * 3);
passenger.species = expandDescription("[passenger-description-risk" + passenger.risk + "]") + " " + passenger.species;
// time allowed for delivery is time taken by "fewest jumps"
// route, plus timer above. Higher reputation makes longer
// times available.
let dtime = Math.floor(daysUntilDeparture * 86400) + (passenger.route.time * 3600);
passenger.deadline = clock.adjustedSeconds + dtime;
if (passenger.risk < 2 && destinationInfo.government <= 1 && Math.random() < 0.5) passenger.risk++;
// total payment is:
passenger.payment = Math.floor(
// payment per hop (higher at rep > 5)
5 * Math.pow(routeToDestination.route.length-1, (passenger.risk * 0.2) + (player.passengerReputationPrecise > 5 ? 2.45 : 2.3)) +
// payment by route length
routeToDestination.distance * (8 + (Math.random() * 8)) +
// premium for delivery to more dangerous systems
(5 * (7 - destinationInfo.government) * (7 - destinationInfo.government))
);
passenger.payment *= (Math.random() + Math.random() + Math.random() + Math.random()) / 2;
let prudence = (2 * Math.random()) - 1;
let desperation = (Math.random() * (0.5 + passenger.risk)) * (1 + 1 / (Math.max(0.5, dtime - (routeToDestination.time * 3600))));
let competency = Math.max(50, (routeToDestination.route.length - 1) * (0.5 + (passenger.risk * 2)));
if(passenger.risk == 0) competency -= 30;
passenger.payment = Math.floor(passenger.payment * (1 + (0.4 * prudence)));
passenger.payment += (passenger.risk * 200);
passenger.skill = Math.min(60, competency + 20 * (prudence-desperation));
// anywhere from 2 to 5 times the normal payment
passenger.payment *= Math.floor(Math.random() * (passenger.risk + 1) + 2);
passenger.advance = Math.min(passenger.payment * 0.9, Math.max(0, Math.floor(passenger.payment * (0.05 + (0.1 * desperation) + (0.02 * player.passengerReputationPrecise))))); // some% up front
passenger.payment -= passenger.advance;
log(this.name, "pass " + passenger.payment, passenger.skill, passenger.risk);
// add passenger to contract list
worldScripts["oolite-contracts-passengers"]._addPassengerToSystem(passenger);
}
}
//-------------------------------------------------------------------------------------------------------------
// makes sure all our home systems are marked on the chart
this.$checkForMarkedSystems = function() {
let hs = this._homeSystems[galaxyNumber];
let ms = mission.markedSystems;
if (hs.length > 0) {
// look for any marked system matches
if (ms.length > 0) {
for (let i = 0; i < hs.length; i++) {
let found = false;
// loop through all the marked systems
for (let j = 0; j < ms.length; j++) {
if (ms[j].system === hs[i] && ms[j] === this.name) found = true;
}
// if we didn't get a match, mark this one
if (found === false) {
mission.markSystem({system:hs[i], name:this.name, markerShape:"MARKER_DIAMOND", markerColor:"purpleColor", markerScale:2});
}
}
} else {
// if there aren't any marked systems at all, just add all our home systems
for (let i = 0; i < hs.length; i++) {
mission.markSystem({system:hs[i], name:this.name, markerShape:"MARKER_DIAMOND", markerColor:"purpleColor", markerScale:2});
}
}
}
}
//-------------------------------------------------------------------------------------------------------------
this.$addInvestmentLevelToGalCopReputations = function $addInvestmentLevelToGalCopReputations() {
if (!worldScripts.GalCopBB_Reputation) return
for (let gal = 0; gal <= 7; gal++) {
let hs = this._homeSystems[gal];
for (let i = 0; i < hs.length; i++) {
let hsID = parseInt(hs[i]);
// make sure we don't already have the custom function
if (this["$returnInvestmentLevel_" + gal + "_" + hsID]) continue;
let sysname = System.infoForSystem(gal, hsID).name;
let rep = worldScripts.GalCopBB_Reputation;
rep._entities[sysname + " (G" + (gal + 1) + ") Investment Level"] = {
name: sysname + " Investment Level",
scope: "system",
display: true,
regionSystems: [hsID],
regionGalaxy: gal,
getValueWS: "HomeSystem",
getValueFN: "$returnInvestmentLevel_" + gal + "_" + hsID,
rewardGrid: [{
value: 0,
description: ""
},
{
value: 1,
description: expandDescription("[hs_investment_level_1]")
},
{
value: 2,
description: expandDescription("[hs_investment_level_2]")
},
{
value: 3,
description: expandDescription("[hs_investment_level_3]")
},
{
value: 4,
description: expandDescription("[hs_investment_level_4]")
},
{
value: 5,
description: expandDescription("[hs_investment_level_5]")
},
{
value: 6,
description: expandDescription("[hs_investment_level_6]")
},
{
value: 7,
description: expandDescription("[hs_investment_level_7]")
},
{
value: 8,
description: expandDescription("[hs_investment_level_8]")
}]
};
eval("this.$returnInvestmentLevel_" + gal + "_" + hsID + " = function() { return this.$investmentLevel(" + gal + ", " + hsID + "); }");
rep._reputations.push({
entity: sysname + " (G" + (gal + 1) + " Investment Level",
galaxy: galaxyNumber,
system: hsID,
reputation: this.$investmentLevel(gal, hsID)
});
}
}
}
//-------------------------------------------------------------------------------------------------------------
this.$removeGalCopReputation = function $removeGalCopReputation(sysID) {
if (!worldScripts.GalCopBB_Reputation) return;
let rep = worldScripts.GalCopBB_Reputation;
let arr = rep._reputations;
for (let i = arr.length - 1; i >= 0; i++) {
if (arr[i].galaxy === galaxyNumber && arr[i].system === parseInt(sysID)) {
arr.splice(i, 1);
return;
}
}
delete this["$returnInvestmentLevel_" + galaxyNumber + "_" + sysID];
}
//-------------------------------------------------------------------------------------------------------------
this.$getInvestmentLevelDescription = function $getInvestmentLevelDescription(sysID) {
return " Your investment level has reached '" + expandDescription("[hs_investment_level_" + this.$investmentLevel(sysID).toString() + "]") + "'."
}
//-------------------------------------------------------------------------------------------------------------
this.$investmentLevel = function $investmentLevel(galID, sysID) {
let ic = this.$investmentCount(galID, sysID);
let result = 0;
if (ic > 0) {
if (ic == 1) result = 1;
else if (ic >= 2 && ic <= 3) result = 2;
else if (ic >= 4 && ic <= 5) result = 3;
else if (ic >= 6 && ic <= 8) result = 4;
else if (ic >= 9 && ic <= 11) result = 5;
else if (ic >= 12 && ic <= 14) result = 6;
else if (ic >= 15 && ic <= 18) result = 7;
else if (ic >= 19) result = 8;
}
return result;
}
//-------------------------------------------------------------------------------------------------------------
this.$addInfoToSystemDataScreen = function $addInfoToSystemDataScreen() {
let sysID = player.ship.targetSystem;
if (player.ship.hasOwnProperty("infoSystem")) sysID = player.ship.infoSystem;
// build message
let msg = "";
// add the investment level
if (this.$isHomeSystem(sysID) === true) {
msg = "You have made this system home.";
let result = this.$investmentLevel(sysID);
if (result > 0) msg += " Your investment level has reached '" + expandDescription("[hs_investment_level_" + result.toString() + "]") + "'.";
}
// add message to top part of screen, if possible
let added = false;
if (worldScripts["oolite-system-data-config"] && worldScripts["CompressedF7Layout"]) {
let ln = 0;
let dc = worldScripts["oolite-system-data-config"];
for (let i = 16; i >= 1; i--) {
if (ln === 0 && dc.systemDataLineText(i) != "") {
ln = i + 1;
}
if (dc.systemDataLineOwner(i) === this.name) {
ln = i;
break;
}
}
if (ln <= 16 && ln > 0) {
added = true;
dc.setSystemDataLine(ln, msg, (msg != "" ? this.name : ""));
}
}
// if none of the above worked, then just add the message to the bottom part of the screen
if (added === false && msg != "") mission.addMessageText(msg);
}
//-------------------------------------------------------------------------------------------------------------
// routine to check the combat simulator worldscript, to see if it's running or not
this.$simulatorRunning = function() {
let w = worldScripts["Combat Simulator"];
if (w && w.$checkFight && w.$checkFight.isRunning) return true;
return false;
}
//-------------------------------------------------------------------------------------------------------------
this.$initInterface = function(station) {
if (this._stationTypes.indexOf(station.allegiance) >= 0) {
station.setInterface(this.name,{
title:"View GalCop station docking counts",
category:"Logs",
summary:"Views the number of times you have docked at GalCop stations.",
callback:this.$displayDockCountList.bind(this)
});
} else {
station.setInterface(this.name, null);
}
}
//-------------------------------------------------------------------------------------------------------------
this.$displayDockCountList = function() {
function compare(a, b) {
if (a.count < b.count) return 1;
if (a.count > b.count) return -1;
if (a.name < b.name) return -1;
if (a.name > b.name) return 1;
return 0;
}
this._pageLength = 19;
if (this.$isBigGuiActive() === true) this._pageLength = 25;
// build sortable dataset
let src = this._dockCounts[galaxyNumber];
let keys = Object.keys(src);
let data = [];
for (let i = 0; i < keys.length; i++) {
data.push({
id:keys[i],
name:(this.$isHomeSystem(keys[i]) ? "•" : "") + System.systemNameForID(keys[i]),
count:src[keys[i]]}
);
}
data.sort(compare);
let text = this.$formatSystemList(data);
mission.runScreen({
screenID:"oolite-homesystem-dockcounts-map",
title: "GalCop Station Docking Counts",
overlay: {name:"hs-home.png", height:546},
message: text,
exitScreen: "GUI_SCREEN_INTERFACES"
});
}
//-------------------------------------------------------------------------------------------------------------
// appends space to currentText to the specified length in 'em'
this.$padTextRight = function(currentText, desiredLength, leftSwitch) {
if (currentText == null) currentText = "";
let hairSpace = String.fromCharCode(31);
let ellip = "…";
let currentLength = defaultFont.measureString(currentText.replace(/%%/g, "%"));
let hairSpaceLength = defaultFont.measureString(hairSpace);
// calculate number needed to fill remaining length
let padsNeeded = Math.floor((desiredLength - currentLength) / hairSpaceLength);
if (padsNeeded < 1) {
// text is too long for column, so start pulling characters off
let tmp = currentText;
do {
tmp = tmp.substring(0, tmp.length - 2) + ellip;
if (tmp === ellip) break;
} while (defaultFont.measureString(tmp.replace(/%%/g, "%")) > desiredLength);
currentLength = defaultFont.measureString(tmp.replace(/%%/g, "%"));
padsNeeded = Math.floor((desiredLength - currentLength) / hairSpaceLength);
currentText = tmp;
}
// quick way of generating a repeated string of that number
if (!leftSwitch || leftSwitch === false) {
return currentText + new Array(padsNeeded).join(hairSpace);
} else {
return new Array(padsNeeded).join(hairSpace) + currentText;
}
}
//-------------------------------------------------------------------------------------------------------------
// appends space to currentText to the specified length in 'em'
this.$padTextLeft = function(currentText, desiredLength) {
return this.$padTextRight(currentText, desiredLength, true);
}
//-------------------------------------------------------------------------------------------------------------
// returns true if a HUD with allowBigGUI is enabled, otherwise false
this.$isBigGuiActive = function() {
if (oolite.compareVersion("1.83") <= 0) {
return player.ship.hudAllowsBigGui;
} else {
let bigGuiHUD = ["XenonHUD.plist", "coluber_hud_ch01-dock.plist"]; // until there is a property we can check, I'll be listing HUD's that have the allow_big_gui property set here
if (bigGuiHUD.indexOf(player.ship.hud) >= 0) {
return true;
} else {
return false;
}
}
}
//-------------------------------------------------------------------------------------------------------------
// returns a 4-column list of planets, formatted for display
this.$formatSystemList = function(list) {
let lines = [];
for (let i = 0; i < this._pageLength; i++) lines.push("");
let point = 0;
let colwidth = 32;
let colcount = 1;
if (list.length > this._pageLength) {colwidth = 16; colcount = 2;}
if (list.length > (this._pageLength * 2)) {colwidth = 10.3; colcount = 3;}
if (list.length > (this._pageLength * 3)) {colwidth = 8; colcount = 4;}
for (let i = 0; i < list.length; i++) {
lines[point] += this.$padTextRight(list[i].name, colwidth - 3) +
this.$padTextLeft((list[i].count <= 999 ? list[i].count.toString() : "999"), 2) +
this.$padTextRight(" ", 1);
point += 1;
if (point === lines.length) point = 0;
if ((i + 1) >= (this._pageLength * colcount)) break;
}
let result = "";
for (let i = 0; i < lines.length; i++) {
result += lines[i] + "\n";
}
return result;
}
//-------------------------------------------------------------------------------------------------------------
this.$investmentCount = function(galID, sysID) {
let amt = 0;
if (this._investCounts[galID][sysID]) amt = parseInt(this._investCounts[galID][sysID]);
return amt;
}
}).call(this);
|