Scripts/contracts_on_bb.js |
"use strict";
this.name = "ContractsOnBB";
this.author = "phkb";
this.copyright = "2017 phkb";
this.description = "Converts the cargo, parcel and passenger contracts to be delivered through the BB interface";
this.licence = "CC BY-NC-SA 4.0";
this._disabled = false; // flag to quickly disable the OXP
this._turnOffF4Entries = true; // flag to indicate all F4 interface entries should be removed for applicable contract OXP's
this._bbShuffle = false; // flag to turn on/off BB list shuffle post conversion process
this._smuggling = false; // flag to indicate smuggling contracts will be converted
this._repopulate = true; // flag used to note when the first repopulate process is being run
this._performConversions = true; // flag used to determine if contracts need to be converted after docking
this._switchDefault = false; // convenience switch to make it simple to turn on or off contract conversion by default
/*
Escort contracts are offered to the player via a menu, and then player is then left to launch themselves.
This makes these contracts the easiest to convert, as we're essentially just changing one menu system for another.
*/
this._convertEscortContracts = this._switchDefault; // flag to turn on/off escort contract conversions
this._doEscortContractsConversion = false; // flag to indicate that the conversion process is going/about to be run
// used by the escort contracts conversion process
this._govTypes = ["an anarchy", "a feudal state", "a multi-government system", "a dictatorship", "a communist system", "a confederacy", "a democracy", "a corporate state"];
this._govRisk = ["very high", "high", "moderate", "moderate", "low", "low", "very low", "very low"];
/*
RRS missions are presented to the player in two steps: first a very simple overview, followed by a more detailed briefing.
Once the player has viewed the more detailed briefing, that mission can only be accepted or discarded completely.
Mission variables are only setup when the detailed briefing is displayed, including random destinations or risk factors.
Re-run initialisation phase mean new values will be established. But the BB wants the more detailed information
the initialisation phase provides, and well ahead of when the player may or may not choose to accept the mission.
This means we need to store the first set of values, and override all variables once the mission is accepted.
We are also using customised versions of the mission briefing details for RRS missions. This was purely for aesthetic reasons:
the deadlines and payment amounts are shown on the BB item details, so I removed them from the text. It was too complicated
to try and do some sort of automatic text replacement.
The upshot is, should the RRS OXP change in any way internally (eg adding new mission variables, changing variable meanings),
this OXP will break.
*/
this._convertRRSContracts = this._switchDefault; // flag to turn on/off rescue station mission conversions
this._doRRSContractsConversion = false; // flag to indicate that the conversion process is going/about to be run
this._rrsMissionList = []; // holds list of mission scenarios currently being offered
this._rrsMissionStorage = []; // storage point for all mission scenario mission variables
this._rrsMissionCurrent = {}; // storage of the current mission variables, in case a mission is already active
// lists of the mission variables in use by the different RRS scenarios
this._rrsMissionVariables = {
"Rescue Scenario 1": ["rescuestation_danger1", "rescuestation_danger2", "rescuestation_leader_home", "rescuestation_derelict_home", "rescuestation_startsystem", "rescuestation_destsystem", "rescuestation_destsystem_name", "rescuestation_destsystem_type", "rescuestation_shiprole", "rescuestation_shiprole2", "rescuestation_missionwingsize", "rescuestation_wingname", "rescuestation_reward", "rescuestation_livefire"],
"Rescue Scenario 1a": ["rescuestation_danger1", "rescuestation_danger2", "rescuestation_leader_home", "rescuestation_derelict_home", "rescuestation_startsystem", "rescuestation_destsystem", "rescuestation_destsystem_name", "rescuestation_destsystem_type", "rescuestation_shiprole", "rescuestation_shiprole2", "rescuestation_missionwingsize", "rescuestation_wingname", "rescuestation_reward", "rescuestation_livefire"],
"Rescue Scenario 1b": ["rescuestation_danger1", "rescuestation_danger2", "rescuestation_leader_home", "rescuestation_derelict_home", "rescuestation_startsystem", "rescuestation_destsystem", "rescuestation_destsystem_name", "rescuestation_destsystem_type", "rescuestation_shiprole", "rescuestation_shiprole2", "rescuestation_missionwingsize", "rescuestation_wingname", "rescuestation_reward", "rescuestation_livefire"],
"Rescue Scenario 2": ["rescuestation_reward", "rescuestation_system"],
"Rescue Scenario 2a": ["rescuestation_reward", "rescuestation_system", "rescuestation_deadline"],
"Rescue Scenario 2b": ["rescuestation_reward", "rescuestation_system", "rescuestation_deadline"],
"Rescue Scenario 3": ["rescuestation_startsystem", "rescuestation_startsystem_name", "rescuestation_destsystem", "rescuestation_destsystem_name", "rescuestation_destsystem_desc", "rescuestation_deadline", "rescuestation_deadline_text", "rescuestation_reward", "rescuestation_danger1", "rescuestation_danger2"],
"Rescue Scenario 3a": ["rescuestation_startsystem", "rescuestation_startsystem_name", "rescuestation_destsystem", "rescuestation_destsystem_name", "rescuestation_destsystem_desc", "rescuestation_deadline", "rescuestation_deadline_text", "rescuestation_reward", "rescuestation_danger1", "rescuestation_danger2"],
"Rescue Scenario 4": ["rescuestation_system", "rescuestation_system_name", "rescuestation_destsystem", "rescuestation_destsystem_name", "rescuestation_destsystem_desc", "rescuestation_deadline", "rescuestation_deadline_text", "rescuestation_pilot", "rescuestation_pilotdesc", "rescuestation_reward"],
"Rescue Scenario 4a": ["rescuestation_system", "rescuestation_system_name", "rescuestation_destsystem", "rescuestation_destsystem_name", "rescuestation_destsystem_desc", "rescuestation_deadline", "rescuestation_deadline_text", "rescuestation_pilot", "rescuestation_pilotdesc", "rescuestation_reward", "rescuestation_danger1", "rescuestation_danger2"],
"Rescue Scenario 4b": ["rescuestation_system", "rescuestation_system_name", "rescuestation_destsystem", "rescuestation_destsystem_name", "rescuestation_deadline", "rescuestation_pilot", "rescuestation_pilotdesc", "rescuestation_agent", "rescuestation_agentdesc", "rescuestation_reward"],
"Rescue Scenario 5": ["rescuestation_reward", "rescuestation_system", "rescuestation_shipname"],
"Rescue Scenario 5a": ["rescuestation_reward", "rescuestation_system", "rescuestation_shipname"],
"Rescue Scenario 6": ["rescuestation_system", "rescuestation_destsystem", "rescuestation_destsystem_name", "rescuestation_destsystem_desc", "rescuestation_deadline", "rescuestation_deadline_text", "rescuestation_reward", "rescuestation_danger"],
"Rescue Scenario 6a": ["rescuestation_system", "rescuestation_destsystem", "rescuestation_destsystem_name", "rescuestation_destsystem_desc", "rescuestation_destsystem2", "rescuestation_destsystem2_name", "rescuestation_destsystem2_desc", "rescuestation_deadline", "rescuestation_deadline_text", "rescuestation_reward", "rescuestation_danger", "rescuestation_disease"]
};
// lists the model to use on the background of the mission description for all the different RRS scenarios
this._rrsMissionShipRole = {
"Rescue Scenario 1": "shipModel",
"Rescue Scenario 1a": "shipModel",
"Rescue Scenario 1b": "shipModel",
"Rescue Scenario 2": "rescue_station",
"Rescue Scenario 2a": "rescue_station",
"Rescue Scenario 2b": "EQ_RRS_SOLAR_MINE",
"Rescue Scenario 3": "asteroidModel",
"Rescue Scenario 3a": "asteroidModel",
"Rescue Scenario 4": "rescue_station",
"Rescue Scenario 4a": "rescue_station",
"Rescue Scenario 4b": "rescue_station",
"Rescue Scenario 5": "rescue_station",
"Rescue Scenario 5a": "rescue_station",
"Rescue Scenario 6": "rescue_station",
"Rescue Scenario 6a": "rescue_station"
};
this._rrsAsteroidKeyList = [];
/*
RH stores mission data in missionVariables, like RRS does. The variables are swapped in and out with
the "readHitpage" routine. But because the "pages" array has all the variable data, so we don't need to store it ourselves,
as we do for RRS missions.
Because of some idiosyncrasies with expandMissionText, the mission variable replacement doesn't occur when it should.
Thus, we have created a routine to look for and replace all mission variable reference items in the text with the
actual mission variable content.
Again, because of the way we're doing things, should RH change any of it's mission variables, or change the variable's meanings,
this OXP will break.
*/
this._convertRHContracts = this._switchDefault; // flag to turn on/off random hits mission conversions
this._doRHContractsConversion = false; // flag to indicate that the conversion process is going/about to be run
// lists all the mission variables in use by RH
this._rhMissionVariables = [
"random_hits_mark_system",
"random_hits_mark_direction",
"random_hits_mark_gender",
"random_hits_mark_first_name",
"random_hits_mark_nick_name",
"random_hits_mark_second_name",
"random_hits_mark_race_part1",
"random_hits_mark_race_part2",
"random_hits_mark_ship_description",
"random_hits_mark_ship",
"random_hits_mark_ship_name",
"random_hits_mark_ship_ad_name",
"random_hits_mark_fee",
"random_hits_mark_ship_personality",
"random_hits_assassination_board_poster_title",
"random_hits_assassination_board_job_name",
"random_hits_assassination_board_poster_surname",
"random_hits_assassination_board_poster_name",
"random_hits_assassination_board_poster_system",
"random_hits_assassination_board_subject",
"random_hits_assassination_board_address1",
"random_hits_assassination_board_address2",
"random_hits_assassination_board_part1",
"random_hits_assassination_board_part2",
"random_hits_assassination_board_part3",
"random_hits_assassination_board_part4",
"random_hits_assassination_board_part5",
"random_hits_assassination_board_part6",
"random_hits_assassination_board_part7",
"random_hits_showship"
];
/* In-System Taxi */
this._convertTaxiContracts = this._switchDefault;
this._doTaxiContractsConversion = false;
/*
Bug in In-System Taxi: if you receive a comms-based notification of a client, then do a fast dock, launch, accept the contracts, then fast dock again,
the contract ends up with an expiry time in the past.
*/
/* mining contracts */
/*
note: because of the way mining contracts is structured, we can't reuse its internal functions for mission processing
so much of the code that exists in mining contracts has been rewritten here, with the BB system's methodologies in mind
*/
this._convertMiningContracts = this._switchDefault;
this._doMiningContractsConversion = false;
/* taxi galactica */
this._convertTaxiGalacticaContracts = this._switchDefault;
this._doTaxiGalacticaContractsConversion = false;
// configuration settings for use in Lib_Config
this._COBBConfig = {
Name: this.name,
Alias: "Contracts On BB",
Display: "Conversion Options",
Alive: "_COBBConfig",
Notify: "$changeSettings",
Bool: {
B0: {
Name: "_convertEscortContracts",
Def: false,
Desc: "Escort contracts"
},
B1: {
Name: "_convertRRSContracts",
Def: false,
Desc: "Rescue Stations"
},
B2: {
Name: "_convertRHContracts",
Def: false,
Desc: "Random Hits"
},
B3: {
Name: "_convertTaxiContracts",
Def: false,
Desc: "In-System Taxi"
},
B4: {
Name: "_convertMiningContracts",
Def: false,
Desc: "Mining contracts"
},
B5: {
Name: "_convertTaxiGalacticaContracts",
Def: false,
Desc: "Taxi Galactica contracts"
},
B6: {
Name: "_turnOffF4Entries",
Def: true,
Desc: "Remove F4 items"
},
Info: "0 - Converts Escort contracts\n1 - Converts Rescue Station missions.\n2 - Converts Random Hits missions.\n3 - Converts In-System Taxi contracts.\n4 - Converts Mining contracts.\n5 - Convert Taxi Galactica contracts.\n6 - Removes any F4 interface entries."
},
};
this._trueValues = ["yes", "1", 1, "true", true];
this._waitTimer = null;
//-------------------------------------------------------------------------------------------------------------
this.startUp = function () {
if (this._disabled === true) {
delete this.startUpComplete;
delete this.systemWillPopulate;
delete this.systemWillRepopulate;
delete this.missionScreenOpportunity;
delete this.guiScreenWillChange;
delete this.shipDockedWithStation;
delete this.shipWillDockWithStation;
delete this.shipWillEnterWitchspace;
delete this.playerCompletedContract;
delete this.playerWillSaveGame;
delete this.startUp;
return;
}
var mc = worldScripts.miningcontracts;
if (mc) {
// hide this function for the moment
mc.$cobb_ovr_startUpComplete = mc.startUpComplete;
}
}
//-------------------------------------------------------------------------------------------------------------
this.startUpComplete = function () {
var count = 0;
var bb = worldScripts.BulletinBoardSystem;
if (worldScripts.BountySystem_Core) {
var bs = worldScripts.BountySystem_Core;
bs["contract obligations"] = {
description: "Reneging on contract obligations with the Mining Association.",
severity: "2"
};
}
if (missionVariables.ContractsOnBB_ShuffleBB) this._bbShuffle = (this._trueValues.indexOf(missionVariables.ContractsOnBB_ShuffleBB) >= 0 ? true : false);
if (missionVariables.ContractsOnBB_EscortContracts) this._convertEscortContracts = (this._trueValues.indexOf(missionVariables.ContractsOnBB_EscortContracts) >= 0 ? true : false);
if (!worldScripts["Escort_Contracts"]) this._convertEscortContracts = false;
if (missionVariables.ContractsOnBB_RRSContracts) this._convertRRSContracts = (this._trueValues.indexOf(missionVariables.ContractsOnBB_RRSContracts) >= 0 ? true : false);
if (!worldScripts["Rescue Stations"]) {
this._convertRRSContracts = false;
} else {
this.$rrsGetAsteroidKeyList();
if (this._convertRRSContracts) {
// monkey patch our required changes into RSS
// this allows us to easily monitor when missions are completed
var rrs = worldScripts["Rescue Stations"];
rrs.$cobb_hold_missionSuccess = rrs.missionSuccess;
rrs.missionSuccess = this.$cobb_missionSuccess;
rrs.$cobb_hold_failMission = rrs.failMission;
rrs.failMission = this.$cobb_failMission;
}
}
if (missionVariables.ContractsOnBB_RHContracts) this._convertRHContracts = (this._trueValues.indexOf(missionVariables.ContractsOnBB_RHContracts) >= 0 ? true : false);
if (!worldScripts["Random_Hits"]) this._convertRHContracts = false;
if (missionVariables.ContractsOnBB_TaxiContracts) this._convertTaxiContracts = (this._trueValues.indexOf(missionVariables.ContractsOnBB_TaxiContracts) >= 0 ? true : false);
if (!worldScripts["in-system_taxi"]) this._convertTaxiContracts = false;
if (missionVariables.ContractsOnBB_MiningContracts) this._convertMiningContracts = (this._trueValues.indexOf(missionVariables.ContractsOnBB_MiningContracts) >= 0 ? true : false);
if (!worldScripts["miningcontracts"]) this._convertMiningContracts = false;
if (missionVariables.ContractsOnBB_TaxiGalacticaContracts) this._convertTaxiGalacticaContracts = (this._trueValues.indexOf(missionVariables.ContractsOnBB_TaxiGalacticaContracts) >= 0 ? true : false);
if (!worldScripts["taxi_galactica_main"] || worldScripts["taxi_galactica_main"].version.indexOf("1.") >= 0) this._convertTaxiGalacticaContracts = false;
if (missionVariables.ContractsOnBB_RRSMissionList) {
this._rrsMissionList = JSON.parse(missionVariables.ContractsOnBB_RRSMissionList);
delete missionVariables.ContractsOnBB_RRSMissionList;
}
if (missionVariables.ContractsOnBB_RRSMissionStorage) {
this._rrsMissionStorage = JSON.parse(missionVariables.ContractsOnBB_RRSMissionStorage);
delete missionVariables.ContractsOnBB_RRSMissionStorage;
}
// register our settings, if Lib_Config is present
if (worldScripts.Lib_Config) worldScripts.Lib_Config._registerSet(this._COBBConfig);
// cargo contracts
// we're monkey patching the validateContracts function so we can do some link re-referencing of our own
worldScripts["oolite-contracts-cargo"]._validateContracts = this.$bbovr_cargo_validateContracts;
count = worldScripts["oolite-contracts-cargo"].$contracts.length;
// are there any contracts available at the moment?
if (count > 0) {
// see if there are any unaccepted missions at ID 31000
var itm = bb.$getItem(31000);
// if there isn't, run the conversion process
if (itm == null || this.$countContracts(31000) != count) this.$convertContracts("cargo");
}
// passenger contracts
// we're monkey patching the validateContracts function so we can do some link re-referencing of our own
worldScripts["oolite-contracts-passengers"]._validateContracts = this.$bbovr_passengers_validateContracts;
count = worldScripts["oolite-contracts-passengers"].$passengers.length;
if (count > 0) {
// see if there are any unaccepted missions @ ID 32000
var itm = bb.$getItem(32000);
// if there isn't, run the conversion process
if (itm == null || this.$countContracts(32000) != count) this.$convertContracts("passengers");
}
// parcel contracts
// we're monkey patching the validateContracts function so we can do some link re-referencing of our own
worldScripts["oolite-contracts-parcels"]._validateContracts = this.$bbovr_parcels_validateContracts;
count = worldScripts["oolite-contracts-parcels"].$parcels.length;
if (count > 0) {
// see if there are any unaccepted missions @ ID 33000
var itm = bb.$getItem(33000);
// if there isn't, run the conversion process
if (itm == null || this.$countContracts(33000) != count) this.$convertContracts("parcels");
}
// register our validateContracts script to be run just before the mission list is displayed
bb.$registerBBEvent(this.name, "$validateContracts", "preListDisplay");
// register our bar bill script to be run whenever the BB is exited
bb.$registerBBEvent(this.name, "$rhBarBill", "close");
bb.$registerBBEvent(this.name, "$rhBarBill", "exit");
bb.$registerBBEvent(this.name, "$rhBarBillPostLaunch", "launchExit");
// in-system taxi
// we're monkey patching the "$acceptOffer" function to make it easier to determine when the player accepts a contract during flight
if (this._convertTaxiContracts) {
var taxi = worldScripts["in-system_taxi"];
taxi.$ccob_acceptOffer = taxi.$acceptOffer;
taxi.$acceptOffer = this.$acceptTaxiOffer_inFlight;
}
// mining contracts
bb.$registerBBEvent(this.name, "$miningContractOpen", "preItemDisplay");
bb.$registerBBEvent(this.name, "$miningContractListOpen", "preListDisplay");
var mc = worldScripts.miningcontracts;
if (this._convertMiningContracts) {
this.$checkForHermit(player.ship.dockedStation);
mc.$cobb_ovr_shipExitedWitchspace = mc.shipExitedWitchspace;
mc.shipExitedWitchspace = this.$mc_shipExitedWitchspace;
} else {
if (mc) mc.$cobb_ovr_startUpComplete();
}
var tg = worldScripts.taxi_galactica_main;
if (this._convertTaxiGalacticaContracts) {
tg.$cobb_ovr_missionScreenOpportunity = tg.missionScreenOpportunity;
delete tg.missionScreenOpportunity;
}
// do a quick check to make sure we don't have any orphaned smuggling contracts
this.$checkSmugglingContracts();
// un-accepted escort contracts are not saved between sessions - they're available when you dock,
// but if you save and reload, they disappear.
// so do a quick check to make sure we don't have any orphaned escort contracts, where the source data
// has been cleared away by a reload
this.$checkEscortContacts();
this.systemWillRepopulate();
}
//-------------------------------------------------------------------------------------------------------------
this.systemWillPopulate = function () {
// add our station key to the main station, so the contracts are only offered there
if (system.mainStation) {
worldScripts.BulletinBoardSystem.$addStationKey(this.name, system.mainStation, "mainStation");
}
}
//-------------------------------------------------------------------------------------------------------------
this.systemWillRepopulate = function () {
if (this._repopulate === true) {
this._repopulate = false;
var taxi = [];
if (worldScripts["in-system_taxi"]) {
taxi = worldScripts["in-system_taxi"].$listOfStations();
}
var sbm = worldScripts.Smugglers_BlackMarket;
var bb = worldScripts.BulletinBoardSystem;
for (var i = 0; i < system.stations.length; i++) {
var stn = system.stations[i];
if (sbm && sbm.$doesStationHaveBlackMarket) {
// add the black market station keys
if (sbm.$doesStationHaveBlackMarket(stn) === true) bb.$addStationKey(this.name, stn, "blackMarket");
}
// add rrs station keys
if (stn.hasRole("rescue_station")) bb.$addStationKey(this.name, stn, "rescueStation");
// add rh station keys
if (stn.name === "A Seedy Space Bar") bb.$addStationKey(this.name, stn, "randomHits");
// add tax station keys
if (taxi.indexOf(stn) >= 0) bb.$addStationKey(this.name, stn, "taxi");
// add rock hermit station keys
if (Ship.roleIsInCategory(stn.primaryRole, "oolite-rockhermits") === true) bb.$addStationKey(this.name, stn, "rockHermit");
// add taxi galactica station keys
if (stn.hasRole("taxi_station")) bb.$addStationKey(this.name, stn, "taxiGalactica");
}
}
}
//-------------------------------------------------------------------------------------------------------------
this.shipWillEnterWitchspace = function () {
this._repopulate = true;
if (this._convertMiningContracts) {
// remove any mining contracts from the bb
// they'll be deleted from the mining contracts data via its own script - this just saves confusion
var curr = this.$countContracts(39000);
if (curr > 0) {
var bb = worldScripts.BulletinBoardSystem;
for (var i = 0; i < curr; i++) {
bb.$removeBBMission(39000 + i);
}
}
}
}
//-------------------------------------------------------------------------------------------------------------
this.guiScreenWillChange = function (to, from) {
// if we're able to show the interfaces screen while on the main station...
if (to === "GUI_SCREEN_INTERFACES" && player.ship.dockedStation && this._turnOffF4Entries) {
// remove the interfaces from the station
if (system.mainStation) {
system.mainStation.setInterface("oolite-contracts-cargo", null);
system.mainStation.setInterface("oolite-contracts-passengers", null);
system.mainStation.setInterface("oolite-contracts-parcels", null);
}
if (this._convertEscortContracts) player.ship.dockedStation.setInterface("escort_f4contracts", null);
if (this._convertRRSContracts) player.ship.dockedStation.setInterface("rescue_station", null);
if (this._convertRHContracts) player.ship.dockedStation.setInterface("RandomHits", null);
if (this._convertTaxiContracts) player.ship.dockedStation.setInterface("in-system_taxi", null);
if (this._convertMiningContracts) player.ship.dockedStation.setInterface("MiningContracts-bm", null);
if (this._convertTaxiGalacticaContracts) player.ship.dockedStation.setInterface("taxi_galactica_main", null);
}
}
//-------------------------------------------------------------------------------------------------------------
this.missionScreenOpportunity = function () {
if (this._performConversions === true) {
this._performConversions = false;
var do_interface = false;
var bb = worldScripts.BulletinBoardSystem;
// do any contract conversion for EC, RRS and RH here
// these flags will be turned on during shipDockedWithStation
// ec
if (this._doEscortContractsConversion === true) {
this._doEscortContractsConversion = false;
if (worldScripts["Escort_Contracts"].ec_targetsystems) {
var count = worldScripts["Escort_Contracts"].ec_targetsystems.length;
if (count > 0) {
// see if there are any unaccepted missions @ ID 35000
var itm = bb.$getItem(35000);
// if there isn't, run the conversion process
if (itm == null || this.$countContracts(35000) != count) {
this.$convertContracts("escort");
do_interface = true;
}
}
}
}
// rrs
if (this._doRRSContractsConversion === true) {
this._doRRSContractsConversion = false;
var rrs = worldScripts["Rescue Stations"];
this._rrsMissionList.length = 0;
if (rrs.availablescenarios && rrs.availablescenarios.length > 0) {
this._rrsMissionList = rrs.availablescenarios.concat();
}
if (rrs.availablescenarios_save && rrs.availablescenarios_save.length > 0) {
this._rrsMissionList = rrs.availablescenarios_save.concat();
}
if (this._rrsMissionList.length > 0) {
this._rrsMissionStorage = new Array(this._rrsMissionList.length);
// see if there are any unaccepted missions @ ID 36000
var itm = bb.$getItem(36000);
// if there isn't, run the conversion process
if (itm == null || this.$countContracts(36000) != this._rrsMissionList.length) {
this.$convertContracts("rescue");
do_interface = true;
}
}
}
// rh
if (this._doRHContractsConversion === true) {
this._doRHContractsConversion = false;
var rh = worldScripts["Random_Hits"];
if (rh.pages && missionVariables.random_hits_status !== "RUNNING") {
var count = rh.pages.length;
if (count > 0) {
// see if there are any unaccepted missions @ ID 37000
var itm = bb.$getItem(37000);
// if there isn't, run the conversion process
if (itm == null || this.$countContracts(37000) != count) {
this.$convertContracts("random_hits");
do_interface = true;
}
}
}
}
// in-system taxi
if (this._doTaxiContractsConversion === true) {
this._doTaxiContractsConversion = false;
var taxi = worldScripts["in-system_taxi"];
if (taxi.$stationOffers.length > 0) {
this.$convertContracts("taxi");
do_interface = true;
}
}
// mining contracts
if (this._doMiningContractsConversion === true) {
this._doMiningContractsConversion = false;
var mining = worldScripts.miningcontracts;
var count = mining.MC_contracts.length;
if (count > 0) {
// see if there are any unaccepted missions @ ID 39000
var itm = bb.$getItem(39000);
// if there isn't, run the conversion process
if (itm == null || this.$countContracts(39000) != count) {
this.$convertContracts("mining");
do_interface = true;
}
}
}
// taxi galaxtica
if (this._doTaxiGalacticaContractsConversion === true) {
this._doTaxiGalacticaContractsConversion = false;
var tg = worldScripts.taxi_galactica_main;
// see if there are any unaccepted missions @ ID 40000
var itm = bb.$getItem(40000);
// if there isn't, run the conversion process
if (itm == null || this.$countContracts(40000) != 3) {
this.$convertContracts("taxi_galactica");
do_interface = true;
}
}
// force an update to the interface entry
if (do_interface) bb.$initInterface(player.ship.dockedStation);
}
// due to the way taxi galactica is structured, we need to recreate some of the functionality from missionScreenOpportunity
if (this._convertTaxiGalacticaContracts === true && worldScripts.taxi_galactica_main) {
var tg = worldScripts.taxi_galactica_main;
// Check if Player is currently docked at the main station:
if (player.ship.dockedStation.isMainStation) {
// Check if Player is doing a contract and is at the contract mission destination:
if (missionVariables.taxistatus === "ON_THE_JOB" && system.ID === missionVariables.taxi_dest) {
// Change variable to reflect no longer doing contract:
missionVariables.taxistatus = "NOT_ON_JOB";
// Increase variable to reflect another contract completed:
missionVariables.taxijobstotal += 1;
// Refuel Player ship:
player.ship.fuel = 7.0;
// Check if Player was doing special mission #1:
if (missionVariables.taxi_diff === 3) {
// Change variable to reflect special mission #1 complete:
missionVariables.taxi_specmiss_1 = "MISSION_COMPLETE";
// Check if Snoopers OXP is installed and if so insert news story about events of special mission #1:
if (worldScripts.snoopers) worldScripts.snoopers.insertNews({
ID: this.name,
Agency: 1,
Message: expandDescription("[taxi_snoopers_specmiss_1]")
});
if (worldScripts.GNN) worldScripts.GNN._insertNews({
ID: this.name,
Agency: 1,
Message: expandDescription("[taxi_snoopers_specmiss_1]")
});
}
}
}
// Check if Player is current docked at a Taxi Station:
if (player.ship.dockedStation.hasRole("taxi_station")) {
if (missionVariables.taxistat === "ACCEPTED") {
// Display contract accepted screen:
/*mission.runScreen(
{
title: "Taxi Galactica Contract Accepted",
screenID: "taxi_galactica_accepted",
messageKey: "mission_taxi_accepted",
model: "taxi_adder",
choicesKey: "mission_taxi_on_job_choices"
});*/
missionVariables.taxistat = "ON_THE_JOB_1";
return;
}
if (missionVariables.taxistat === "REVISIT") {
// Check if Player is currently doing a contract and if so prompt Player that they need to complete contract:
if (missionVariables.taxistatus !== "ON_THE_JOB") {
// Check if Player has completed 5 or more contracts, has not yet completed special mission #1 and has a free passenger berth:
if (missionVariables.taxijobstotal >= 5 && missionVariables.taxi_specmiss_1 !== "MISSION_COMPLETE" && player.ship.passengerCount < player.ship.passengerCapacity) {
// Generate name for ambassador for special mission #1 briefing:
missionVariables.taxi_specmis_1_ambassador = randomName() + " " + randomName();
// Generate special mission #1 destination:
missionVariables.taxi_specmis1_dest = tg._generateTaxiDest(20);
missionVariables.taxi_specmis1_dest_name = System.systemNameForID(missionVariables.taxi_specmis1_dest);
// Get special mission #1 destination government type and assign name to variable:
missionVariables.taxi_specmis1_dest_gov = System.infoForSystem(galaxyNumber, missionVariables.taxi_specmis1_dest).government;
if (missionVariables.taxi_specmis1_dest_gov === 0) missionVariables.taxi_specmis1_dest_gov_name = "Anarchy";
if (missionVariables.taxi_specmis1_dest_gov === 1) missionVariables.taxi_specmis1_dest_gov_name = "Feudal";
if (missionVariables.taxi_specmis1_dest_gov === 2) missionVariables.taxi_specmis1_dest_gov_name = "Multi-Governmental";
if (missionVariables.taxi_specmis1_dest_gov === 3) missionVariables.taxi_specmis1_dest_gov_name = "Dictatorship";
if (missionVariables.taxi_specmis1_dest_gov === 4) missionVariables.taxi_specmis1_dest_gov_name = "Communist";
if (missionVariables.taxi_specmis1_dest_gov === 5) missionVariables.taxi_specmis1_dest_gov_name = "Confederacy";
if (missionVariables.taxi_specmis1_dest_gov === 6) missionVariables.taxi_specmis1_dest_gov_name = "Democracy";
if (missionVariables.taxi_specmis1_dest_gov === 7) missionVariables.taxi_specmis1_dest_gov_name = "Corporate State";
// Generate time limit for special mission #1:
missionVariables.taxi_specmis1_time = Math.floor(Math.random() * (20 - 10 + 1) + 10);
// Determine special mission #1 destination distance and assign to variable:
missionVariables.taxi_specmis1_dist = Math.round(system.info.distanceToSystem(System.infoForSystem(galaxyNumber, missionVariables.taxi_specmis1_dest)) * 5) / 5;
// Display special mission #1 briefing screen:
mission.runScreen({
title: "Taxi Galactica Contract Offer",
screenID: "taxi_galactica_intro",
messageKey: "mission_taxi_spec_mis_1_intro",
model: "taxi_adder",
modelPersonality: tg._modelPersonality,
choicesKey: "mission_taxi_spec_mis_1_intro_choices"
},
this.$tg_choiceEvaluation);
missionVariables.taxistat = "SPEC_MIS_01_1";
return;
} else {
// Display welcome screen for Taxi Station and generate new contract destinations:
mission.runScreen({
title: "Welcome to the Taxi Galactica Station",
screenID: "taxi_galactica_mission_intro",
messageKey: "mission_taxi_intro",
model: "taxi_adder",
modelPersonality: tg._modelPersonality,
choicesKey: "mission_taxi_intro_choices"
},
this.$tg_choiceEvaluation);
tg._generateTaxiJobs();
this.$convertContracts("taxi_galactica");
worldScripts.BulletinBoardSystem.$initInterface(player.ship.dockedStation);
missionVariables.taxistat = "REVISIT_1";
return;
}
}
}
}
}
}
//-------------------------------------------------------------------------------------------------------------
this.shipWillDockWithStation = function (station) {
if (station.isMainStation) {
this.$convertContracts("cargo");
this.$convertContracts("passengers");
this.$convertContracts("parcels");
}
if (this._smuggling) {
if (worldScripts.Smugglers_BlackMarket.$doesStationHaveBlackMarket(station) === true) this.$convertContracts("smuggling");
}
var found = false;
var bb = worldScripts.BulletinBoardSystem;
// are any escort contracts going to be completed when we dock?
if (this._convertEscortContracts) {
var ecList = this.$getActiveContractsByType("escort");
var ec = worldScripts["Escort_Contracts"];
if (ecList.length > 0 && !ec.ec_currentcontract) {
// there should only ever be one, which should be index 0
bb.$removeBBMission(ecList[0].ID);
}
if ((ec.ec_currentcontract && ec.ec_currentcontract !== "success") || (ec.ec_currentcontract === "success" && system.info.systemID === ec.ec_targetsystem && player.ship.dockedStation.isMainStation)) {
// find the contract in the BB to remove it
// there should only ever be one, which should be index 0
bb.$removeBBMission(ecList[0].ID);
}
}
if (this._convertRHContracts) {
// are any rh contracts going to be completed when we dock
var rh = worldScripts["Random_Hits"];
if (missionVariables.random_hits_status && rh.hitMissionEndings.indexOf(missionVariables.random_hits_status) > -1) {
var rhList = this.$getActiveContractsByType("randomhits");
if (rhList.length > 0) {
// find the contract in the BB to remove it
// there should only ever be one, which should be index 0
bb.$removeBBMission(rhList[0].ID);
}
}
}
if (this._convertMiningContracts) this.$checkForHermit(station);
if (found === true) bb.$initInterface(player.ship.dockedStation);
// turn on the flag that will do OXP contract conversions after the player docks
this._performConversions = true;
}
//-------------------------------------------------------------------------------------------------------------
this.shipDockedWithStation = function (station) {
var bb = worldScripts.BulletinBoardSystem;
if (this._convertEscortContracts && station.isMainStation) this._doEscortContractsConversion = true;
if (this._convertRRSContracts && station.hasRole("rescue_station")) this._doRRSContractsConversion = true;
if (this._convertRHContracts && station.name === "A Seedy Space Bar") this._doRHContractsConversion = true;
// first, reset the overlay back to the default
bb.$resetOverlayDefault();
// set the default overlay to use on the main BB list
// rh board
if (this._convertRHContracts && player.ship.dockedStation.name === "A Seedy Space Bar") bb.$setOverlayDefault({
name: "cobb_rh.png",
height: 546
});
// rrs board
if (this._convertRRSContracts && player.ship.dockedStation.hasRole("rescue_station")) bb.$setOverlayDefault({
name: "cobb_rrs.png",
height: 546
});
// look for a taxi contract being completed and remove the BB item
var taxi = worldScripts["in-system_taxi"];
if (taxi && this._convertTaxiContracts) {
if (taxi.$fireMissionScreen >= 2) {
// note for screen 6, the passenger is converted into a normal passenger so the game can handle the processing
// rather than trying to keep the bb item until the final delivery, I'm removing it here as with all other
// outcomes. The passenger details will be on the F5F5 screen, just not on the BB
//
var tList = this.$getActiveContractsByType("taxi");
if (tList.length > 0) {
// find the taxi contract and delete it.
// there should only ever be one, which should be index 0
bb.$removeBBMission(tList[0].ID);
}
}
}
}
//-------------------------------------------------------------------------------------------------------------
this.shipLaunchedFromStation = function (station) {
if (this._convertMiningContracts) {
var bb = worldScripts.BulletinBoardSystem;
// turn off the always visible flag
if (Ship.roleIsInCategory(station.primaryRole, "oolite-rockhermits") === true) {
bb._alwaysShowBB = false;
// remove main menu items
bb.$removeMainMenuItem(this.name, "$miningContract_wait");
bb.$removeMainMenuItem(this.name, "$miningContract_repayDebt");
}
}
}
//-------------------------------------------------------------------------------------------------------------
this.playerCompletedContract = function (type, result, fee, contract) {
switch (type) {
case "cargo":
case "passenger":
case "parcel":
// find and remove the contract from the BB
var bb = worldScripts.BulletinBoardSystem;
for (var i = 0; i < bb._data.length; i++) {
var itm = bb._data[i];
if (itm != null && itm.accepted === true) {
// is this item the one we're dealing with?
if (itm.destination === contract.destination && itm.payment === contract.fee && itm.source === contract.start) {
bb.$removeBBMission(itm.ID);
break;
}
}
}
break;
}
}
//-------------------------------------------------------------------------------------------------------------
this.playerBoughtNewShip = function (ship, price) {
var bb = worldScripts.BulletinBoardSystem;
var d = bb._data;
var found = false;
for (var i = d.length - 1; i >= 0; i--) {
if (d[i].accepted === true && d[i].worldScript === this.name && d[i].initiateCallback === "$acceptPassengerContract") {
bb.$removeBBMission(d[i].ID);
found = true;
}
}
if (found === true) bb.$initInterface(player.ship.dockedStation);
}
//-------------------------------------------------------------------------------------------------------------
this.playerWillSaveGame = function () {
delete missionVariables.ContractsOnBB_EscortContracts;
if (worldScripts["Escort_Contracts"]) missionVariables.ContractsOnBB_EscortContracts = this._convertEscortContracts;
delete missionVariables.ContractsOnBB_RRSContracts;
if (worldScripts["Rescue Stations"]) {
missionVariables.ContractsOnBB_RRSContracts = this._convertRRSContracts;
if (this._rrsMissionList && this._rrsMissionList.length > 0) {
missionVariables.ContractsOnBB_RRSMissionList = JSON.stringify(this._rrsMissionList);
missionVariables.ContractsOnBB_RRSMissionStorage = JSON.stringify(this._rrsMissionStorage);
}
}
delete missionVariables.ContractsOnBB_RHContracts;
if (worldScripts["Random_Hits"]) missionVariables.ContractsOnBB_RHContracts = this._convertRHContracts;
delete missionVariables.ContractsOnBB_TaxiContracts;
if (worldScripts["in-system_taxi"]) missionVariables.ContractsOnBB_TaxiContracts = this._convertTaxiContracts;
delete missionVariables.ContractsOnBB_MiningContracts;
if (worldScripts["miningcontracts"]) missionVariables.ContractsOnBB_MiningContracts = this._convertMiningContracts;
delete missionVariables.ContractsOnBB_TaxiGalacticaContracts;
if (worldScripts["taxi_galactica_main"]) missionVariables.ContractsOnBB_TaxiGalacticaContracts = this._convertTaxiGalacticaContracts;
missionVariables.ContractsOnBB_ShuffleBB = this._bbShuffle;
}
//-------------------------------------------------------------------------------------------------------------
this.$changeSettings = function () {
var rrs = worldScripts["Rescue Stations"];
if (rrs) {
if (this._convertRRSContracts) {
// monkey patch rrs with our new versions
rrs.$cobb_hold_missionSuccess = rrs.missionSuccess;
rrs.missionSuccess = this.$cobb_missionSuccess;
rrs.$cobb_hold_failMission = rrs.failMission;
rrs.failMission = this.$cobb_failMission;
} else {
// remove any monkey patches from rrs
if (rrs.$cobb_hold_missionSuccess) rrs.missionSuccess = rrs.$cobb_hold_missionSuccess;
if (rrs.$cobb_hold_failMission) rrs.failMission = rrs.$cobb_hold_failMission;
delete rrs.$cobb_hold_missionSuccess;
delete rrs.$cobb_hold_failMission;
}
}
var tg = worldScripts.taxi_galactica_main;
if (tg) {
if (this._convertTaxiGalacticaContracts) {
// monkey patch tg with our new versions
tg.$cobb_ovr_missionScreenOpportunity = tg.missionScreenOpportunity;
delete tg.missionScreenOpportunity;
} else {
// remove any monkey patches from tg
tg.missionScreenOpportunity = tg.$cobb_ovr_missionScreenOpportunity;
delete tg.$cobb_ovr_missionScreenOpportunity;
}
}
}
//-------------------------------------------------------------------------------------------------------------
this.$convertContracts = function (contractType) {
var bb = worldScripts.BulletinBoardSystem;
var xui = false;
var ovr1 = "";
var ovr2 = "";
var ovr3 = "";
if (worldScripts.XenonReduxUI) {
xui = true;
ovr1 = {
name: "xrui-cargo.png",
height: 546
};
ovr2 = {
name: "xrui-boardingpass.png",
height: 546
};
ovr3 = {
name: "xrui-briefcase.png",
height: 546
};
}
if (worldScripts.XenonUI) {
xui = true;
ovr1 = {
name: "xui-cargo.png",
height: 546
};
ovr2 = {
name: "xui-boardingpass.png",
height: 546
};
ovr3 = {
name: "xui-briefcase.png",
height: 546
};
}
var curr = 0;
/* Essentially, we're making a copy of all the contracts and assigning them an in in the 31000+ range.
The ID assigned, minus the base amount, should match the index value of the contract.
Once a contract is accepted, the ID of the equivalent BB item is reset back to the normal range (0 - 30000),
excluding it from the rest of this code.
When a mission is completed, the BB item is linked to the contract based on start system, destination system, and the payment amount.
*/
switch (contractType) {
case "cargo":
// cargo contracts
var cc = worldScripts["oolite-contracts-cargo"];
// remove anything already there
curr = this.$countContracts(31000);
if (curr > 0) this.$clearMissionSet(curr, 31000);
curr = 0;
for (var i = 0; i < cc.$contracts.length; i++) {
if (system.mainStation.market[cc.$contracts[i].commodity] == undefined) continue
// make sure we only add missions that haven't passed their deadline
if (cc.$contracts[i].deadline > clock.adjustedSeconds) {
// make sure the id is clear
if (bb.$getIndex(31000 + curr) != -1) {
for (var j = 1; j < 100; j++) {
if (bb.$getIndex(31000 + curr + j) === -1) {
curr = curr + j;
break;
}
}
}
bb.$addBBMission({
ID: (31000 + curr), // cargo contracts are from 31000
source: system.ID,
destination: cc.$contracts[i].destination,
stationKey: "mainStation",
description: expandDescription("[contract-cargo-title]") + " " + cc._descriptionForGoods(cc.$contracts[i]).toLowerCase(),
details: expandDescription("[contract-cargo-description]", {
cargo: cc._descriptionForGoods(cc.$contracts[i]).toLowerCase(),
destination: System.systemNameForID(cc.$contracts[i].destination)
}),
payment: cc.$contracts[i].payment,
deposit: cc.$contracts[i].deposit,
allowTerminate: false,
completionType: "IMMEDIATE",
stopTimeAtComplete: true,
allowPartialComplete: false,
expiry: cc.$contracts[i].deadline,
disablePercentDisplay: true,
noEmails: true,
markerShape: "NONE", // marker control will be handled by contracts system
overlay: (xui === true ? ovr1 : ""),
playAcceptedSound: false,
remoteDepositProcess: true,
initiateCallback: "$acceptCargoContract",
availableCallback: "$cargoContractAvailable",
worldScript: this.name,
});
curr += 1;
}
}
break;
case "passengers":
// passenger contracts
var pc = worldScripts["oolite-contracts-passengers"];
// remove anything already there
curr = this.$countContracts(32000);
if (curr > 0) this.$clearMissionSet(curr, 32000);
curr = 0;
for (var i = 0; i < pc.$passengers.length; i++) {
// make sure we only add missions that haven't passed their deadline
if (pc.$passengers[i].deadline > clock.adjustedSeconds) {
var cust = [];
if (pc.$passengers[i].advance > 0) cust.push({
heading: expandDescription("[contract-advance]"),
value: formatCredits(pc.$passengers[i].advance, true, true)
});
cust.push({
heading: expandDescription("[contract-clientname]"),
value: pc.$passengers[i].name + ", a " + pc.$passengers[i].species
});
// make sure the id is clear
if (bb.$getIndex(32000 + curr) != -1) {
for (var j = 1; j < 100; j++) {
if (bb.$getIndex(32000 + curr + j) === -1) {
curr = curr + j;
break;
}
}
}
bb.$addBBMission({
ID: (32000 + curr), // passenger contracts are from 32000
source: system.ID,
destination: pc.$passengers[i].destination,
stationKey: "mainStation",
description: expandDescription("[contract-passenger-title]"),
details: expandDescription("[contract-passenger-description]", {
client: pc.$passengers[i].name,
destination: System.systemNameForID(pc.$passengers[i].destination)
}),
payment: pc.$passengers[i].payment,
allowTerminate: false,
completionType: "IMMEDIATE",
stopTimeAtComplete: true,
allowPartialComplete: false,
expiry: pc.$passengers[i].deadline,
disablePercentDisplay: true,
noEmails: true,
markerShape: "NONE", // marker control will be handled by contracts system
overlay: (xui === true ? ovr2 : ""),
playAcceptedSound: false,
customDisplayItems: cust,
initiateCallback: "$acceptPassengerContract",
availableCallback: "$passengerContractAvailable",
worldScript: this.name,
});
curr += 1;
}
}
break;
case "parcels":
// parcel contracts
var bc = worldScripts["oolite-contracts-parcels"];
// remove anything already there
curr = this.$countContracts(33000);
if (curr > 0) this.$clearMissionSet(curr, 33000);
curr = 0;
for (var i = 0; i < bc.$parcels.length; i++) {
// make sure we only add missions that haven't passed their deadline
if (bc.$parcels[i].deadline > clock.adjustedSeconds) {
// make sure the id is clear
if (bb.$getIndex(33000 + curr) != -1) {
for (var j = 1; j < 100; j++) {
if (bb.$getIndex(33000 + curr + j) === -1) {
curr = curr + j;
break;
}
}
}
var cust = [];
cust.push({
heading: expandDescription("[contract-clientname]"),
value: bc.$parcels[i].sender
});
bb.$addBBMission({
ID: (33000 + curr), // passenger contracts are from 33000
source: system.ID,
destination: bc.$parcels[i].destination,
stationKey: "mainStation",
description: expandDescription("[contract-parcel-title]"),
details: expandDescription("[contract-parcel-description]", {
parcel: bc.$parcels[i].description.toLowerCase(),
destination: System.systemNameForID(bc.$parcels[i].destination)
}),
payment: bc.$parcels[i].payment,
allowTerminate: false,
completionType: "IMMEDIATE",
stopTimeAtComplete: true,
allowPartialComplete: false,
expiry: bc.$parcels[i].deadline,
disablePercentDisplay: true,
noEmails: true,
markerShape: "NONE", // marker control will be handled by contracts system
overlay: (xui === true ? ovr3 : ""),
playAcceptedSound: false,
customDisplayItems: cust,
initiateCallback: "$acceptParcelContract",
availableCallback: "$parcelContractAvailable",
worldScript: this.name
});
curr += 1;
}
}
break;
case "smuggling":
if (this._smuggling) {
// smuggling contracts
var sc = worldScripts.Smugglers_Contracts;
// remove anything already there
curr = this.$countContracts(34000);
if (curr > 0) this.$clearMissionSet(curr, 34000);
curr = 0;
for (var i = 0; i < sc._contracts.length; i++) {
// make sure we only add missions that haven't passed their deadline
if (sc._contracts[i].deadline > clock.adjustedSeconds) {
// make sure the id is clear
if (bb.$getIndex(34000 + curr) != -1) {
for (var j = 1; j < 100; j++) {
if (bb.$getIndex(34000 + curr + j) === -1) {
curr = curr + j;
break;
}
}
}
bb.$addBBMission({
ID: (34000 + curr), // smuggling contracts are from 34000
source: system.ID,
destination: sc._contracts[i].destination,
stationKey: "blackMarket",
description: expandDescription("[contract-smuggling-title]") + " " + sc.$descriptionForGoods(sc._contracts[i]),
details: expandDescription("[contract-smuggling-description]", {
cargo: sc.$descriptionForGoods(sc._contracts[i]),
destination: System.systemNameForID(sc._contracts[i].destination)
}),
payment: sc._contracts[i].payment,
deposit: sc._contracts[i].deposit,
allowTerminate: false,
completionType: "IMMEDIATE",
stopTimeAtComplete: true,
allowPartialComplete: false,
expiry: sc._contracts[i].deadline,
disablePercentDisplay: true,
noEmails: true,
markerShape: "NONE", // marker control will be handled by smuggling contract system
overlay: {
name: "stgu-skull.png",
height: 546
},
playAcceptedSound: false,
remoteDepositProcess: true,
initiateCallback: "$acceptSmugglingContract",
availableCallback: "$smugglingContractAvailable",
worldScript: this.name,
});
curr += 1;
}
}
// force an update here
if (player.ship.docked) bb.$initInterface(player.ship.dockedStation);
}
break;
case "escort":
if (this._convertEscortContracts) {
var ec = worldScripts["Escort_Contracts"];
// remove anything already there
curr = this.$countContracts(35000);
if (curr > 0) this.$clearMissionSet(curr, 35000);
curr = 0;
for (var i = 0; i < ec.ec_targetsystems.length; i++) {
// make sure the id is clear;
if (bb.$getIndex(35000 + curr) != -1) {
for (var j = 1; j < 100; j++) {
if (bb.$getIndex(35000 + curr + j) === -1) {
curr = curr + j;
break;
}
}
}
var cust = [];
cust.push({
heading: expandDescription("[contract-escort-bonus]"),
value: formatCredits(ec.ec_killsbonuses[i], true, true) + " per kill"
});
var text = expandDescription("[ec_mission_details]", {
mothername: ec.ec_mothernames[i],
targetsystemname: ec.ec_targetsystemsnames[i],
dbcontractactualprice: formatCredits(ec.ec_contractactualprices[i], true, true),
dbkillsbonus: formatCredits(ec.ec_killsbonuses[i], true, true),
targetsystemgovernmentname: this._govTypes[ec.ec_targetsystemsgovernment[i]],
contractdifficultydesc: this._govRisk[ec.ec_targetsystemsgovernment[i]]
});
bb.$addBBMission({
ID: (35000 + curr), // escort contracts are from 35000
source: system.ID,
destination: ec.ec_targetsystems[i],
stationKey: "mainStation",
description: expandDescription("[contract-escort-title]"),
details: text,
payment: ec.ec_contractactualprices[i],
deposit: 0,
allowTerminate: false,
completionType: "IMMEDIATE",
stopTimeAtComplete: true,
allowPartialComplete: false,
expiry: -1,
disablePercentDisplay: true,
noEmails: false, // escort contracts don't have emails built in, so use the BB's system
markerShape: "NONE", // marker control will be handled by escort contracts
overlay: {
name: "cobb_ec.png",
height: 546
},
remoteDepositProcess: false,
customDisplayItems: cust,
initiateCallback: "$acceptEscortContract",
availableCallback: "$escortContractAvailable",
worldScript: this.name,
data: "escort"
});
curr += 1;
}
}
break;
case "rescue":
if (this._convertRRSContracts) {
var rrs = worldScripts["Rescue Stations"];
// remove anything already there
curr = this.$countContracts(36000);
if (curr > 0) this.$clearMissionSet(curr, 36000);
curr = 0;
// if we're currently running an RRS mission, then store the current variables before we start
if (rrs.missionActive()) this.$rrsStoreCurrentVariables();
for (var i = 0; i < this._rrsMissionList.length; i++) {
var cust = [];
cust.push({
heading: "Client name:",
value: "RRS Operations Manager"
});
var scen = "Rescue Scenario " + this._rrsMissionList[i];
if (!worldScripts[scen] && this._rrsMissionList[i].length > 1) scen = "Rescue Scenario " + this._rrsMissionList[i].substring(0, 1);
// load the mission variables for this scenario, either from RRS or from our saved data
if (this._rrsMissionStorage[scen]) {
this.$rrsReloadMissionVariables(scen, i);
} else {
worldScripts[scen].initMissionVariables();
this.$rrsSaveMissionVariables(scen, i);
}
// get the model for the mission type, but convert it into a shipKey so that the same model is shown every time.
// although secondary screens, displayed by RRS, might still show a different one. At least the BB will be consistent.
var mdl = this.$rrsGetKeyForShipRole(this.$rrsGetShipRoleForScenario(scen));
// make sure we only add missions that haven't passed their deadline
if (missionVariables.rescuestation_deadline > clock.adjustedSeconds) {
// make sure the id is clear
if (bb.$getIndex(36000 + curr) != -1) {
for (var j = 1; j < 100; j++) {
if (bb.$getIndex(36000 + curr + j) === -1) {
curr = curr + j;
break;
}
}
}
// add the mission to the bb
bb.$addBBMission({
ID: (36000 + curr), // rrs contracts are from 36000
source: system.ID,
destination: (missionVariables.rescuestation_destsystem ? missionVariables.rescuestation_destsystem : missionVariables.rescuestation_system),
stationKey: "rescueStation",
description: this.$rrsExtractMissionTitle(this._rrsMissionList[i]),
details: this.$rrsExtractMissionDetails(this._rrsMissionList[i]),
payment: missionVariables.rescuestation_reward,
deposit: 0,
allowTerminate: false,
completionType: "IMMEDIATE",
stopTimeAtComplete: true,
allowPartialComplete: false,
expiry: (missionVariables.rescuestation_deadline ? missionVariables.rescuestation_deadline : -1),
disablePercentDisplay: true,
noEmails: false,
markerShape: "NONE", // marker control will be handled by RRS
model: "[" + mdl + "]",
modelPersonality: Math.floor(Math.random() * 32768),
overlay: {
name: "cobb_rrs.png",
height: 546
},
remoteDepositProcess: false,
customDisplayItems: cust,
initiateCallback: "$acceptRRSContract",
availableCallback: "$rrsContractAvailable",
worldScript: this.name,
data: "rescue"
});
curr += 1;
}
this.$rrsResetMissionVariables(scen);
}
// put everything back how we found it
if (rrs.missionActive()) this.$rrsReturnCurrentVariables();
}
break;
case "random_hits":
if (this._convertRHContracts) {
var rh = worldScripts["Random_Hits"];
// remove anything already there
curr = this.$countContracts(37000);
if (curr > 0) this.$clearMissionSet(curr, 37000);
var difficultyText = ["Easy", "Challenging", "Hard"];
var page = 1;
curr = 0;
if (rh.pages && rh.pages.length > 0 && rh.pages[0] && rh.pages[0].hasOwnProperty("mark_system")) {
for (var i = 0; i < rh.pages.length; i++) {
var cust = [];
rh.readHitpage(i + 1);
//log(this.name, "rh " + missionVariables.random_hits_mark_system);
cust.push({
heading: "Client name:",
value: missionVariables.random_hits_assassination_board_poster_title + " " + missionVariables.random_hits_assassination_board_poster_name + " " + missionVariables.random_hits_assassination_board_poster_surname
});
cust.push({
heading: "Difficulty:",
value: difficultyText[page - 1]
})
cust.push({
heading: "Termination fee:",
value: formatCredits(missionVariables.random_hits_mark_fee / 10, true, true)
});
// make sure the id is clear
if (bb.$getIndex(37000 + curr) != -1) {
for (var j = 1; j < 100; j++) {
if (bb.$getIndex(37000 + curr + j) === -1) {
curr = curr + j;
break;
}
}
}
bb.$addBBMission({
ID: (37000 + curr), // rh contracts are from 37000
source: system.ID,
destination: (missionVariables.random_hits_mark_system ? System.systemIDForName(missionVariables.random_hits_mark_system) : system.ID),
stationKey: "randomHits",
description: this.$rhExtractMissionTitle(missionVariables.random_hits_assassination_board_subject),
details: this.$rhExtractMissionDetails(this.$rhReplaceMissionVariables(expandMissionText("level_" + page + "_mark_advert"))) + this.$rhDifficultyText(page),
payment: missionVariables.random_hits_mark_fee,
deposit: 0,
allowTerminate: true,
completionType: "IMMEDIATE",
stopTimeAtComplete: true,
allowPartialComplete: false,
expiry: -1,
disablePercentDisplay: true,
noEmails: false,
markerShape: "NONE", // marker control will be handled by RH
remoteDepositProcess: false,
customDisplayItems: cust,
model: "[" + missionVariables.random_hits_mark_ship + "]",
modelPersonality: missionVariables.random_hits_mark_ship_personality,
initiateCallback: "$acceptRHContract",
terminateCallback: "$terminateRHContract",
availableCallback: "$rhContractAvailable",
worldScript: this.name,
data: "randomhits"
});
curr += 1;
page += 1;
page = ((page - 1) % 3) + 1;
}
}
}
break;
case "taxi":
if (this._convertTaxiContracts) {
var taxi = worldScripts["in-system_taxi"];
// remove anything already there
curr = this.$countContracts(38000);
if (curr > 0) this.$clearMissionSet(curr, 38000);
curr = 0;
for (var i = 0; i < taxi.$stationOffers.length; i++) {
if (taxi.$stationOffers[i][0] < 2) {
var cust = [];
cust.push({
heading: expandDescription("[contract-clientname]"),
value: taxi.$stationOffers[i][5]
});
var text = "Taxi Galactica contract to transfer " + taxi.$stationOffers[i][5] + " from the " +
taxi.$stationOffers[i][1].displayName + " to the " + taxi.$stationOffers[i][2].displayName + ".\n\n" +
"Tips may be awarded for quick transfers.";
// make sure the id is clear
if (bb.$getIndex(38000 + curr) != -1) {
for (var j = 1; j < 100; j++) {
if (bb.$getIndex(38000 + curr + j) === -1) {
curr = curr + j;
break;
}
}
}
bb.$addBBMission({
ID: (38000 + curr), // escort contracts are from 35000
source: system.ID,
destination: system.ID,
stationKey: "taxi",
description: "Taxi Contract",
details: text,
payment: taxi.$stationOffers[i][4],
deposit: 0,
allowTerminate: false,
completionType: "IMMEDIATE",
stopTimeAtComplete: true,
allowPartialComplete: false,
expiry: taxi.$stationOffers[i][3],
disablePercentDisplay: true,
noEmails: false, // escort contracts don't have emails built in, so use the BB's system
markerShape: "NONE", // marker control will be handled by escort contracts
overlay: {
name: "cobb_taxi.png",
height: 546
},
remoteDepositProcess: false,
customDisplayItems: cust,
initiateCallback: "$acceptTaxiContract",
availableCallback: "$taxiContractAvailable",
worldScript: this.name,
data: "taxi"
});
curr += 1;
}
}
}
break;
case "mining":
if (this._convertMiningContracts) {
var mc = worldScripts.miningcontracts;
// remove anything already there
curr = this.$countContracts(39000);
if (curr > 0) this.$clearMissionSet(curr, 39000);
curr = 0;
for (var i = 0; i < mc.MC_contracts.length; i++) {
var contract = mc.MC_contracts[i];
var cust = [];
cust.push({
heading: "Client name:",
value: contract.company
});
cust.push({
heading: "Forfeit penalty:",
value: formatCredits(contract.penalty, true, true) + " per ton of shortage"
});
var med = "Mining Association of " + mc.MC_system;
var custMenu = [];
custMenu.push({
text: "Dispatch current cargo load",
worldScript: this.name,
callback: "$partMiningContract_process",
condition: "$partMiningContract_condition",
autoRemove: false
});
var text = expandDescription("[contract-mining-details]", {
amount: (contract.signed === 0 ? contract.amount : contract.gross),
cargo: displayNameForCommodity(contract.cargo).toLowerCase(),
mediator: med
});
// make sure the id is clear
if (bb.$getIndex(39000 + curr) != -1) {
for (var j = 1; j < 100; j++) {
if (bb.$getIndex(39000 + curr + j) === -1) {
curr = curr + j;
break;
}
}
}
bb.$addBBMission({
ID: (39000 + curr), // mining contracts are from 39000
source: system.ID,
destination: 256, // ignore the destination
stationKey: "rockHermit",
description: expandDescription("[contract-mining-title]", {
amount: (contract.signed === 0 ? contract.amount : contract.gross),
cargo: displayNameForCommodity(contract.cargo).toLowerCase()
}),
details: text,
payment: contract.reward,
deposit: 0,
allowTerminate: true,
completionType: "AT_SOURCE",
stopTimeAtComplete: false,
allowPartialComplete: false,
expiry: contract.deadline,
disablePercentDisplay: false,
percentComplete: (contract.signed === 0 ? 0.0 : (contract.gross - contract.amount) / contract.gross),
accepted: (contract.signed === 1 ? true : false),
noEmails: true, // because of the way we're re-adding these contracts all the time, we can't use the built in emailer
markerShape: "NONE", // mining contracts can only be completed in current system, so don't add any
overlay: {
name: "cobb_mining.png",
height: 546
},
remoteDepositProcess: false,
customMenuItems: custMenu,
customDisplayItems: cust,
initiateCallback: "$acceptMiningContract",
completedCallback: "$completedMiningContract",
confirmCompleteCallback: "$confirmCompleteMiningContract",
terminateCallback: "$terminateMiningContract",
manifestCallback: "$miningManifest",
worldScript: this.name,
postStatusMessages: [{
status: "completed",
return: "list",
overlay: {
name: "cobb_mining.png",
height: 546
},
text: expandDescription("[contract-mining-completed]", {
mediator: med,
amount: formatCredits(contract.reward, true, true)
})
},
{
status: "terminated",
return: "list",
overlay: {
name: "cobb_mining.png",
height: 546
},
text: expandDescription("[contract-mining-terminated-1]", {
mediator: med,
amount: 0
})
}
],
data: "mining"
});
curr += 1;
}
}
break;
case "taxi_galactica":
var tg = worldScripts.taxi_galactica_main;
// remove anything already there
curr = this.$countContracts(40000);
if (curr > 0) this.$clearMissionSet(curr, 40000);
curr = 0;
for (var i = 1; i <= 3; i++) {
var cust = [];
var s = System.infoForSystem(galaxyNumber, (Math.random() > 0.5 ? missionVariables["taxi_job_dest_" + i] : system.ID));
cust.push({
heading: expandDescription("[contract-clientname]"),
value: missionVariables["taxi_job_name_" + i] + ", a " + s.inhabitant
}, {
heading: "Difficulty",
value: missionVariables["taxi_job_diff_name_" + i]
});
// make sure the id is clear
if (bb.$getIndex(40000 + curr) != -1) {
for (var j = 1; j < 20; j++) {
if (bb.$getIndex(40000 + curr + j) === -1) {
curr = curr + j;
break;
}
}
}
bb.$addBBMission({
ID: (40000 + curr), // taxi galactica contracts are from 40000
source: system.ID,
destination: missionVariables["taxi_job_dest_" + i],
stationKey: "taxiGalactica",
description: expandDescription("[taxi-galactica-passenger-title]"),
details: expandDescription("[taxi-galactica-passenger-description]", {
client: missionVariables["taxi_job_name_" + i],
destination: System.systemNameForID(missionVariables["taxi_job_dest_" + i])
}),
payment: missionVariables["taxi_job_pay_" + i],
allowTerminate: false,
completionType: "IMMEDIATE",
stopTimeAtComplete: true,
allowPartialComplete: false,
expiry: (clock.seconds + missionVariables["taxi_job_time_" + i] * 24 * 3600),
disablePercentDisplay: true,
noEmails: true,
markerShape: "NONE", // marker control will be handled by contracts system
overlay: {
name: "cobb_taxi.png",
height: 546
},
customDisplayItems: cust,
initiateCallback: "$tg_acceptContract",
availableCallback: "$taxiGalacticaContractAvailable",
worldScript: this.name,
data: "taxi_galactica"
});
curr += 1;
}
break;
}
if (this._bbShuffle) bb.$shuffleBBList();
}
//-------------------------------------------------------------------------------------------------------------
// accept contract functions
//-------------------------------------------------------------------------------------------------------------
this.$acceptCargoContract = function (missID) {
var idx = parseInt(missID);
var cc = worldScripts["oolite-contracts-cargo"];
cc.$contractIndex = idx - 31000;
cc._acceptContract();
// reindex the bb item, because we don't need to know about the details anymore
var bb = worldScripts.BulletinBoardSystem;
var item = bb.$getItem(missID);
item.ID = bb.$nextID();
bb._selectedItem = item.ID
this.$reindexContracts(31000, idx - 31000, false);
if (this._turnOffF4Entries) system.mainStation.setInterface("oolite-contracts-cargo", null);
}
//-------------------------------------------------------------------------------------------------------------
this.$acceptPassengerContract = function (missID) {
var idx = parseInt(missID);
var pc = worldScripts["oolite-contracts-passengers"];
pc.$contractIndex = idx - 32000;
pc._acceptContract();
// reindex the bb item, because we don't need to know about the details anymore
var bb = worldScripts.BulletinBoardSystem;
var item = bb.$getItem(missID);
item.ID = bb.$nextID();
bb._selectedItem = item.ID
this.$reindexContracts(32000, idx - 32000, false);
if (this._turnOffF4Entries) system.mainStation.setInterface("oolite-contracts-passengers", null);
}
//-------------------------------------------------------------------------------------------------------------
this.$acceptParcelContract = function (missID) {
var idx = parseInt(missID);
var bc = worldScripts["oolite-contracts-parcels"];
bc.$contractIndex = idx - 33000;
bc._acceptContract();
// reindex the bb item, because we don't need to know about the details anymore
var bb = worldScripts.BulletinBoardSystem;
var item = bb.$getItem(missID);
item.ID = bb.$nextID();
bb._selectedItem = item.ID
this.$reindexContracts(33000, idx - 33000, false);
if (this._turnOffF4Entries) system.mainStation.setInterface("oolite-contracts-parcels", null);
}
//-------------------------------------------------------------------------------------------------------------
this.$acceptSmugglingContract = function (missID) {
var idx = parseInt(missID);
var sc = worldScripts.Smugglers_Contracts;
sc._contractIndex = idx - 34000;
sc.$acceptContract();
// reindex the bb item, because we don't need to know about the details anymore
var bb = worldScripts.BulletinBoardSystem;
var item = bb.$getItem(missID);
item.ID = bb.$nextID();
bb._selectedItem = item.ID
this.$reindexContracts(34000, idx - 34000, false);
}
//-------------------------------------------------------------------------------------------------------------
this.$acceptEscortContract = function (missID) {
var idx = parseInt(missID) - 35000;
var ec = worldScripts["Escort_Contracts"];
ec.ec_contractno = idx;
ec.ec_updatemissionvariables();
ec.ec_currentcontract = true;
ec.ec_contractexpiretime = clock.minutes + 180;
ec.ec_missionkills = 0;
ec.ec_payment = 0;
ec.ec_mothername = missionVariables.ec_mothername;
ec.ec_targetsystem = missionVariables.ec_targetsystem;
ec.ec_contractactualprice = missionVariables.ec_dbcontractactualprice;
ec.ec_killsbonus = missionVariables.ec_dbkillsbonus;
mission.setInstructionsKey("Contract_Details", "Escort_Contracts");
ec.ec_cleanupmissionVariables();
// theoretically we don't need to do this because you can only accept one escort mission at a time
// but to be consistent...
// reindex the bb item, because we don't need to know about the details anymore
var bb = worldScripts.BulletinBoardSystem;
var item = bb.$getItem(missID);
item.ID = bb.$nextID();
bb._selectedItem = item.ID
this.$reindexContracts(35000, idx, false);
}
//-------------------------------------------------------------------------------------------------------------
this.$acceptRRSContract = function (missID) {
var bb = worldScripts.BulletinBoardSystem;
// RRS missions have their own post-acceptance screen, but we need to exit the BB to see it
bb._displayType = -1;
// reset mission variables back to the details for the mission
var idx = parseInt(missID) - 36000;
var rrsScenario = this._rrsMissionList[idx];
// run the initMissionVariables routine, but we'll be overwriting all the values anyway.
worldScripts["Rescue Stations"].initMissionVariables(rrsScenario);
// force the stage into 2, to ensure the correct mission screen is displayed during the "missionOfferDecision" routine.
missionVariables.rescuestation_stage = 2;
// now that the mission is accepted, plug in the variables we stored
var list = this._rrsMissionVariables["Rescue Scenario " + rrsScenario];
for (var i = 0; i < list.length; i++) {
missionVariables[list[i]] = this._rrsMissionStorage[idx][list[i]];
}
// remove the mission from our holding arrays
this._rrsMissionList.splice(idx, 1);
this._rrsMissionStorage.splice(idx, 1);
// check for, and run, any post-mission acceptance routine
// this may result in the player being forcably launched
if (worldScripts["Rescue Scenario " + rrsScenario].missionOfferDecision) worldScripts["Rescue Scenario " + rrsScenario].missionOfferDecision("yes");
// theoretically we don't need to do this because you can only accept one RRS mission at a time
// but to be consistent...
// reindex the bb item, because we don't need to know about the details anymore
var item = bb.$getItem(missID);
item.ID = bb.$nextID();
bb._selectedItem = item.ID
this.$reindexContracts(36000, idx, false);
}
//-------------------------------------------------------------------------------------------------------------
this.$acceptRHContract = function (missID) {
// we're reproducing the mission acceptance code here so we can also replace the email display
//var idx = parseInt(missID) - 37000;
var idx = -1;
var bb = worldScripts.BulletinBoardSystem;
var item = bb.$getItem(missID);
var rh = worldScripts["Random_Hits"];
// find the linked RH item
for (var i = 0; i < rh.pages.length; i++) {
rh.readHitpage(i + 1);
if (item.destinationName === missionVariables.random_hits_mark_system && parseInt(item.payment) === parseInt(missionVariables.random_hits_mark_fee)) {
idx = i;
break;
}
}
if (idx === -1) {
log(this.name, "!!ERROR: Unable to link BB item to original Random Hits contract");
// un-accept the contract so we don't get confused.
item.accepted = false;
bb.$initInterface(player.ship.dockedStation);
return;
}
rh.setStoreVariables(idx + 1);
rh.$markSystem(missionVariables.random_hits_planetnumber);
// send email
if (worldScripts.EmailSystem) {
var email = worldScripts.EmailSystem;
var text = this.$rhReplaceMissionVariables(expandDescription("Thank you [assassination_board_refused2] [mission_random_hits_playertitle] [commander_name], " +
"you [assassination_board_accepted1] [assassination_board_accepted2] [assassination_board_accepted3] [assassination_board_accepted4] " +
"[assassination_board_accepted5] this [mission_random_hits_assassination_board_job_name]. " +
"[assassination_board_accepted6] [assassination_board_refused5] [assassination_board_accepted7]! " +
"[mission_random_hits_assassination_board_part5] mission_random_hits_mark_fee Credits [assassination_board_accepted7a] " +
"upon docking with any GalCop Station or Seedy Space Bar following the [assassination_board_accepted8] of [assassination_board_refused5b]. " +
"This [assassination_board_accepted9] will be in addition to any bounty paid by GalCop. [assassination_board_accepted10]\n\n" +
"You have accepted this [mission_random_hits_assassination_board_job_name]. [assassination_board_accepted11]. If you leave Galaxy " +
"[mission_random_hits_show_galaxy] you will be deemed to have abandoned the [mission_random_hits_assassination_board_job_name]."));
email.$createEmail({
sender: this.$rhReplaceMissionVariables(expandDescription("mission_random_hits_assassination_board_poster_title mission_random_hits_assassination_board_poster_name")),
subject: this.$rhReplaceMissionVariables(expandDescription("[assassination_board_refused1] mission_random_hits_mark_first_name mission_random_hits_mark_nick_name [mission_random_hits_mark_second_name]")),
date: global.clock.seconds,
message: text
});
}
//random shipnames sometimes makes very long names that don't fit in one missionline.
//if that happens we'll use plain ship name instead.
var instructions = expandMissionText("random_hits_shortdescription");
if (defaultFont.measureString(instructions) > 32) {
missionVariables.random_hits_mark_ship_short_name = Ship.shipDataForKey(missionVariables.random_hits_mark_ship)["name"];
instructions = expandMissionText("random_hits_shorterdescription");
}
mission.setInstructions(instructions, "Random_Hits");
delete missionVariables.random_hits_mark_ship_short_name;
rh.setupMarkPosition(); // sets mark position and various fees.
missionVariables.random_hits_status = "RUNNING";
// theoretically we don't need to do this because you can only accept one RH mission at a time
// but to be consistent...
// reindex the bb item, because we don't need to know about the details anymore
item.ID = bb.$nextID();
bb._selectedItem = item.ID
// we don't need to reindex this time - RH keeps 9 items in the array even if a contract has been accepted and then terminated
//this.$reindexContracts(37000, idx, false);
}
//-------------------------------------------------------------------------------------------------------------
this.$acceptTaxiContract = function (missID) {
var idx = parseInt(missID) - 38000;
var taxi = worldScripts["in-system_taxi"];
taxi.$removeOfferTimer(); //in case there is an offerTimer running from in-flight offers.
taxi.$currentOffer = taxi.$stationOffers[idx];
taxi.$currentOffer[0] = 2;
// reindex the bb item, because we don't need to know about the details anymore
var bb = worldScripts.BulletinBoardSystem;
var item = bb.$getItem(missID);
item.ID = bb.$nextID();
bb._selectedItem = item.ID
this.$reindexContracts(38000, idx, false);
taxi.$deleteMissionInstructions();
player.ship.addPassenger(taxi.$currentOffer[5] + " (going to " + taxi.$currentOffer[2].displayName + ")", system.ID, system.ID, taxi.$currentOffer[3], 0);
taxi.$currentOffer[0] = 3;
taxi.$currentOffer[7] = taxi.$currentOffer[3] - clock.seconds; //premium is based on basetime. basetime is defined when pickin up passenger.
taxi.$fireMissionScreen = 0;
}
//-------------------------------------------------------------------------------------------------------------
this.$acceptMiningContract = function (missID) {
var idx = missID - 39000;
var mc = worldScripts.miningcontracts;
var contract = mc.MC_contracts[idx];
contract.signed = 1;
contract.gross = contract.amount;
player.consoleMessage("Contract signed");
if (worldScripts.EmailSystem) {
var bb = worldScripts.BulletinBoardSystem;
var itm = bb.$getItem(missID);
itm.manifestText = "Dispatch " + contract.amount + "t × " + displayNameForCommodity(contract.cargo).toLowerCase() + " for " + contract.company;
itm.noEmails = false;
bb.$sendEmail(player.ship.dockedStation, "accepted", missID);
itm.noEmails = true;
}
this.$convertContracts("mining");
}
//-------------------------------------------------------------------------------------------------------------
this.$tg_acceptContract = function (missID) {
var idx = (missID - 40000) + 1; // should be 1, 2 or 3
var bb = worldScripts.BulletinBoardSystem;
var item = bb.$getItem(missID);
// Store passenger contract #1 details into variables and add passenger to ship & manifest:
missionVariables.taxi_passenger = missionVariables["taxi_job_name_" + idx];
missionVariables.taxi_dest = missionVariables["taxi_job_dest_" + idx];
missionVariables.taxi_dest_name = missionVariables["taxi_job_dest_name_" + idx];
missionVariables.taxi_diff = missionVariables["taxi_job_diff_" + idx];
missionVariables.taxi_pay = missionVariables["taxi_job_pay_" + idx];
missionVariables.taxi_time = missionVariables["taxi_job_time_" + idx];
missionVariables.taxistatus = "ON_THE_JOB";
var name = missionVariables.taxi_passenger;
var curloc = system.ID;
var dest = missionVariables.taxi_dest;
var time = missionVariables.taxi_time;
var pay = missionVariables.taxi_pay;
player.ship.addPassenger(name, curloc, dest, clock.seconds + time * 24 * 3600, pay);
missionVariables.taxistat = "ACCEPTED";
// reindex the bb item, because we don't need to know about the details anymore
item.ID = bb.$nextID();
bb._selectedItem = item.ID
}
//-------------------------------------------------------------------------------------------------------------
this.$acceptTaxiOffer_inFlight = function () {
// run the internal part first
if (this.$cobb_acceptOffer) this.$cobb_acceptOffer;
// now add the BB item to match
var bb = worldScripts.BulletinBoardSystem;
var text = "Taxi Galactica contract to transfer " + this.$currentOffer[5] + " from the " +
this.$currentOffer[1].displayName + " to the " + this.$currentOffer[2].displayName + ".\n\n" +
"Tips may be awarded for quick transfers.";
bb.$addBBMission({
source: system.ID,
destination: system.ID,
stationKey: "taxi",
description: "Taxi Contract",
details: text,
payment: this.$currentOffer[4],
deposit: 0,
allowTerminate: false,
completionType: "IMMEDIATE",
stopTimeAtComplete: true,
allowPartialComplete: false,
expiry: this.$currentOffer[3],
disablePercentDisplay: true,
noEmails: false,
markerShape: "NONE",
overlay: {
name: "cobb_taxi.png",
height: 546
},
remoteDepositProcess: false,
initiateCallback: "$acceptTaxiContract",
availableCallback: "$taxiContractAvailable",
worldScript: this.name,
data: "taxi"
});
}
//-------------------------------------------------------------------------------------------------------------
this.$terminateRHContract = function (missID) {
var rh = worldScripts["Random_Hits"];
rh.showScreen = "cancelMission";
rh.missionOffers();
rh.showScreen = "";
worldScripts.BulletinBoardSystem._displayType = -1;
}
//-------------------------------------------------------------------------------------------------------------
this.$completedMiningContract = function (missID) {
var idx = missID - 39000;
var mc = worldScripts.miningcontracts;
var contract = mc.MC_contracts[idx];
var reward = contract.reward - contract.amount * contract.penalty;
var repayment = Math.min(reward, mc.MC_debt);
reward -= repayment;
mc.MC_debt -= repayment;
if (reward > 0) {
player.consoleMessage(formatCredits(reward, true, true) + " received");
} else {
player.consoleMessage(formatCredits(Math.abs(reward), true, true) + " deducted");
}
player.credits += reward;
if (worldScripts.EmailSystem) {
var bb = worldScripts.BulletinBoardSystem;
var itm = bb.$getItem(missID);
var med = "Mining Association of " + mc.MC_system;
if (contract.amount === 0) {
// success result
itm.originalManifestText = "Dispatch " + contract.gross + "t × " + displayNameForCommodity(contract.cargo).toLowerCase() + " for " + contract.company + (repayment === 0 ? "" : "\n\nNote: A debt repayment amount of " + formatCredits(repayment, true, true) + " was deducted from the original payment amount.");
// move this to the event callback
itm.noEmails = false;
bb.$sendEmail(player.ship.dockedStation, "success", missID, reward);
itm.noEmails = true;
} else {
// terminated/failed result
itm.originalManifestText = "Dispatch " + contract.gross + "t × " + displayNameForCommodity(contract.cargo).toLowerCase() + " for " + contract.company;
itm.noEmails = false;
if (contract.deadline > clock.adjustedSeconds) {
// not expired, so must be a manual termination
bb.$sendEmail(player.ship.dockedStation, "terminated", missID, -reward);
} else {
// ran out of time
bb.$sendEmail(player.ship.dockedStation, "fail", missID, -reward);
}
itm.noEmails = true;
}
}
mc.MC_contracts.splice(idx, 1);
this.$convertContracts("mining");
}
//-------------------------------------------------------------------------------------------------------------
this.$confirmCompleteMiningContract = function (missID) {
var idx = missID - 39000;
var mc = worldScripts.miningcontracts;
var contract = mc.MC_contracts[idx];
if (contract.signed === 2) return "Contract terminated";
var amount = manifest[contract.cargo];
if (amount < contract.amount) return "Insufficient " + displayNameForCommodity(contract.cargo).toLowerCase() + " in cargo hold";
return "";
}
//-------------------------------------------------------------------------------------------------------------
this.$terminateMiningContract = function (missID) {
player.consoleMessage("Contract terminated");
this.$completedMiningContract(missID);
}
//-------------------------------------------------------------------------------------------------------------
// manifest functions
// There doesn't appear to be any way to override the F5F5 manifest entries for cargo, passenger or parcel contracts.
// So we'll leave them to do their thing. These next 3 functions would add entries to the "Bulletin Board" section of the F5F5 screen.
//-------------------------------------------------------------------------------------------------------------
this.$cargoManifest = function (missID) {
var bb = worldScripts.BulletinBoardSystem;
var itm = bb.$getItem(missID);
var desc = "";
for (var i = 0; i < p.contracts.length; i++) {
if (parseInt(itm.destination) === parseInt(p.contracts[i].destination) && Math.round(itm.payment, 1) === Math.round((p.contracts[i].fee + p.contracts[i].premium), 1) && parseint(itm.source) === parseInt(p.contracts[i].start)) {
var unit = "tons";
if (system.mainStation.market[p.contracts[i].commodity]["quantity_unit"] == "1") {
unit = "kilograms";
} else if (system.mainStation.market[p.contracts[i].commodity]["quantity_unit"] == "2") {
unit = "grams";
}
desc = "Deliver " + p.contracts[i].quantity + unit + " × " + displayNameForCommodity(p.contracts[i].commodity) + " to " + System.systemNameForID(p.contracts[i].destination) + " in " + bb.$getTimeRemaining(itm.expiry) + ".";
break;
}
}
bb.$updateBBManifestText(missID, desc);
}
//-------------------------------------------------------------------------------------------------------------
this.$passengerManifest = function (missID) {
var p = player.ship;
var bb = worldScripts.BulletinBoardSystem;
var itm = bb.$getItem(missID);
var desc = "";
for (var i = 0; i < p.passengers.length; i++) {
if (parseInt(itm.destination) === parseInt(p.passengers[i].destination) && Math.round(itm.payment, 1) === Math.round((p.passengers[i].fee + p.contracts[i].premium), 2) && parseInt(itm.source) === parseInt(p.passengers[i].start)) {
desc = "Transport " + p.passengers[i].name + " to " + System.systemNameForID(p.passengers[i].destination) + " in " + bb.$getTimeRemaining(itm.expiry) + ".";
break;
}
}
bb.$updateBBManifestText(missID, desc);
}
//-------------------------------------------------------------------------------------------------------------
this.$parcelManifest = function (missID) {
var p = player.ship;
var bb = worldScripts.BulletinBoardSystem;
var itm = bb.$getItem(missID);
var desc = "";
for (var i = 0; i < p.parcels.length; i++) {
if (parseInt(itm.destination) === parseInt(p.parcels[i].destination) && Math.round(itm.payment, 1) === Math.round(p.parcels[i].fee, 1) && parseInt(itm.source) === parseInt(p.parcels[i].start)) {
desc = "Deliver " + p.parcels[i].name + " to " + System.systemNameForID(p.parcels[i].destination) + " in " + bb.$getTimeRemaining(itm.expiry) + ".";
break;
}
}
bb.$updateBBManifestText(missID, desc);
}
//-------------------------------------------------------------------------------------------------------------
this.$smugglingManifest = function (missID) {
var bb = worldScripts.BulletinBoardSystem;
var sc = worldScripts.Smugglers_Contracts;
var itm = bb.$getItem(missID);
var desc = "";
for (var i = 0; i < sc._smugglingContracts.length; i++) {
if (parseInt(itm.destination) === parseInt(sc._smugglingContracts[i].destination) && Math.round(itm.payment, 1) === Math.round((sc._smugglingContracts[i].fee + sc._smugglingContracts[i].premium), 1) && parseint(itm.source) === parseInt(sc._smugglingContracts[i].start)) {
var unit = "tons";
if (system.mainStation.market[sc._smugglingContracts[i].commodity]["quantity_unit"] == "1") {
unit = "kilograms";
} else if (system.mainStation.market[sc._smugglingContracts[i].commodity]["quantity_unit"] == "2") {
unit = "grams";
}
desc = "Deliver " + sc._smugglingContracts[i].quantity + unit + " " + displayNameForCommodity(sc._smugglingContracts[i].commodity) + " to " + System.systemNameForID(sc._smugglingContracts[i].destination) + " in " + bb.$getTimeRemaining(itm.expiry) + ".";
break;
}
}
bb.$updateBBManifestText(missID, desc);
}
//-------------------------------------------------------------------------------------------------------------
this.$taxiManifest = function (missID) {
var bb = worldScripts.BulletinBoardSystem;
var item = bb.$getItem(missID);
var taxi = worldScripts["in-system_taxi"];
bb.$updateBBManifestText(
missID,
"Deliver " + taxi.$currentOffer[5] + " from " + taxi.$currentOffer[1].displayName + " to " + taxi.$currentOffer[2].displayName + " in " + Math.floor((taxi.$currentOffer[3] - clock.seconds) / 60) + " minutes."
);
// status text doesn't need expiry time, as it's shown elsewhere on the BB item
bb.$updateBBStatusText(
missID,
"Deliver " + taxi.$currentOffer[5] + " from " + taxi.$currentOffer[1].displayName + " to " + taxi.$currentOffer[2].displayName + "."
);
}
//-------------------------------------------------------------------------------------------------------------
this.$miningManifest = function (missID) {
var bb = worldScripts.BulletinBoardSystem;
var itm = bb.$getItem(missID);
var idx = missID - 39000;
var mc = worldScripts.miningcontracts;
var contract = mc.MC_contracts[idx];
var desc = "Dispatch " + contract.amount + "t " + displayNameForCommodity(contract.cargo).toLowerCase() + " for " + contract.company + " in " + bb.$getTimeRemaining(itm.expiry) + ".";
var sts = (contract.gross - contract.amount) + "t of " + contract.gross + "t " + displayNameForCommodity(contract.cargo).toLowerCase() + " " + ((contract.gross - contract.amount) === 1 ? "has" : "have") + " been dispatched";
bb.$updateBBManifestText(missID, desc);
bb.$updateBBStatusText(missID, sts)
}
//-------------------------------------------------------------------------------------------------------------
this.$getActiveContractsByType = function (type) {
var list = [];
var bb = worldScripts.BulletinBoardSystem;
// find the contract in the BB to remove it
for (var i = 0; i < bb._data.length; i++) {
if (bb._data[i].accepted === true && bb._data[i].worldScript === this.name && bb._data[i].data === type) {
list.push(bb._data[i]);
}
}
return list;
}
//-------------------------------------------------------------------------------------------------------------
// availability functions
//-------------------------------------------------------------------------------------------------------------
// perform checks to see if the cargo contract can be accepted by the player
this.$cargoContractAvailable = function (missID) {
var idx = parseInt(missID) - 31000;
var cc = worldScripts["oolite-contracts-cargo"];
if (!system.mainStation.market[cc.$contracts[idx].commodity]) return "cargo type missing";
if (!cc._hasSpaceFor(cc.$contracts[idx])) return "insufficient cargo space";
return "";
}
//-------------------------------------------------------------------------------------------------------------
// perform checks to see if the passenger contract can be accepted by the player
this.$passengerContractAvailable = function (missID) {
var idx = parseInt(missID) - 32000;
var pc = worldScripts["oolite-contracts-passengers"];
// temp variable to simplify code
var passenger = pc.$passengers[idx];
if (passenger) {
var playerrep = worldScripts["oolite-contracts-helpers"]._playerSkill(player.passengerReputationPrecise);
// if the player has a spare cabin
if (player.ship.passengerCapacity <= player.ship.passengerCount) {
return expandMissionText("oolite-contracts-passengers-command-unavailable").replace("(", "").replace(")", "");
} else if (playerrep < passenger.skill) {
var utype = "both";
if (player.passengerReputationPrecise * 10 >= passenger.skill) {
utype = "kills";
} else if (Math.sqrt(player.score) >= passenger.skill) {
utype = "rep";
}
return expandMissionText("oolite-contracts-passengers-command-unavailable-" + utype).replace("(", "").replace(")", "");
}
}
return "";
}
//-------------------------------------------------------------------------------------------------------------
// perform checks to see if the parcel contract can be accepted by the player
this.$parcelContractAvailable = function (missID) {
var idx = parseInt(missID) - 33000;
var bc = worldScripts["oolite-contracts-parcels"];
// temp variable to simplify code
var parcel = bc.$parcels[idx];
var playerrep = worldScripts["oolite-contracts-helpers"]._playerSkill(player.parcelReputationPrecise);
if (parcel.skill > playerrep) {
var utype = "both";
if (player.parcelReputationPrecise * 10 >= parcel.skill) {
utype = "kills";
} else if (Math.sqrt(player.score) >= parcel.skill) {
utype = "rep";
}
return expandMissionText("oolite-contracts-parcels-command-unavailable-" + utype).replace("(", "").replace(")", "");
}
return "";
}
//-------------------------------------------------------------------------------------------------------------
// perform checks to see if the smuggling contract can be accepted by the player
this.$smugglingContractAvailable = function (missID) {
var idx = parseInt(missID) - 34000;
var sc = worldScripts.Smugglers_Contracts;
if (!sc.$hasSpaceFor(sc._contracts[idx])) return "insufficient cargo space";
return "";
}
//-------------------------------------------------------------------------------------------------------------
// perform checks to see if the escort contract can be accepted by the player
this.$escortContractAvailable = function (missID) {
if (worldScripts["Escort_Contracts"].ec_currentcontract) {
// basically, once a contract is accepted, all other contracts become unavailable
return "unable to access multiple escort contracts";
}
return "";
}
//-------------------------------------------------------------------------------------------------------------
// perform checks to see if the rrs mission can be accepted by the player
this.$rrsContractAvailable = function (missID) {
if (worldScripts["Rescue Stations"].missionActive()) {
return "unable to access multiple RRS missions";
}
return "";
}
//-------------------------------------------------------------------------------------------------------------
this.$rhContractAvailable = function (missID) {
if (missionVariables.random_hits_status === "RUNNING") return "unable to access multiple contracts";
var idx = parseInt(missID) - 37000;
var lvl = Math.floor(idx / 3) + 1;
if ((lvl === 1 && player.score < 32) || (lvl === 2 && player.score < 128) || (lvl === 3 && player.score < 512))
return "insufficient combat experience";
return "";
}
//-------------------------------------------------------------------------------------------------------------
this.$taxiContractAvailable = function (missID) {
var taxi = worldScripts["in-system_taxi"];
var idx = missID - 38000;
if (player.ship.passengerCapacity <= player.ship.passengerCount) {
return expandMissionText("oolite-contracts-passengers-command-unavailable").replace("(", "").replace(")", "");
}
if (taxi.$currentOffer && worldScripts["in-system_taxi"].$currentOffer[0] >= 2) {
return "unable to access multiple taxi contracts";
}
var rightStartingPoint = false;
if (taxi.$stationOffers[idx][1].isPlanet) { //is it a planetary starting point?
if (worldScripts.PlanetFall.lastPlanet == taxi.$stationOffers[idx][1] && (player.ship.dockedStation.hasRole("planetFall_surface")))
rightStartingPoint = true;
} else if (player.ship.dockedStation == taxi.$stationOffers[idx][1])
rightStartingPoint = true;
if (rightStartingPoint === false) return "incorrect starting point";
return "";
}
//-------------------------------------------------------------------------------------------------------------
// perform checks to see if the taxi contract can be accepted by the player
this.$taxiGalacticaContractAvailable = function (missID) {
if (missionVariables.taxistatus == "ON_THE_JOB") {
return "unable to access multiple Taxi Galactica contracts";
}
if (player.ship.passengerCapacity <= player.ship.passengerCount) {
return expandMissionText("oolite-contracts-passengers-command-unavailable").replace("(", "").replace(")", "");
}
return "";
}
//-------------------------------------------------------------------------------------------------------------
// the various contract scripts regularly do checks to validate contracts, making sure they are still acceptable.
// any found to be out of date are removed.
this.$validateContracts = function () {
worldScripts["oolite-contracts-cargo"]._validateContracts();
worldScripts["oolite-contracts-passengers"]._validateContracts();
worldScripts["oolite-contracts-parcels"]._validateContracts();
if (this._smuggling) worldScripts.Smugglers_Contracts.$validateSmugglingContracts();
// taxi contracts recycle regularly, so we need to refresh the data each time we open the BB
if (this._convertTaxiContracts) {
var taxi = worldScripts["in-system_taxi"];
//var itm = worldScripts.BulletinBoardSystem.$getItem(38000);
taxi.$clearOldOffers();
// redo the conversion
this.$convertContracts("taxi");
}
if (this._convertMiningContracts) {
worldScripts.miningcontracts.MC_generateContracts();
this.$convertContracts("mining");
}
}
//-------------------------------------------------------------------------------------------------------------
// we're overriding the base function "validateContracts" as any change to the index could spell disaster for mission links
this.$bbovr_cargo_validateContracts = function () {
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) {
worldScripts.ContractsOnBB.$reindexContracts(31000, i, true);
// remove it
this.$contracts.splice(i, 1);
removed = true;
}
}
/*if (removed) {
// update the interface description if we removed any
this._updateMainStationInterfacesList();
}*/
}
//-------------------------------------------------------------------------------------------------------------
this.$bbovr_passengers_validateContracts = function () {
var c = this.$passengers.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.$passengers[i]) < this.$helper._timeEstimateSeconds(this.$passengers[i]) / 3) {
worldScripts.ContractsOnBB.$reindexContracts(32000, i, true);
// remove it
this.$passengers.splice(i, 1);
removed = true;
}
}
/*if (removed) {
// update the interface description if we removed any
this._updateMainStationInterfacesList();
}*/
}
//-------------------------------------------------------------------------------------------------------------
this.$bbovr_parcels_validateContracts = function () {
var c = this.$parcels.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.$parcels[i]) < this.$helper._timeEstimateSeconds(this.$parcels[i]) / 3) {
worldScripts.ContractsOnBB.$reindexContracts(33000, i, true);
// remove it
this.$parcels.splice(i, 1);
removed = true;
}
}
/*if (removed) {
// update the interface description if we removed any
this._updateMainStationInterfacesList();
}*/
}
//-------------------------------------------------------------------------------------------------------------
// counts the number of BB contracts at a particular base ref
this.$countContracts = function (baseRef) {
var done = false;
var chk = baseRef;
var count = 0;
var bb = worldScripts.BulletinBoardSystem;
do {
if (bb.$getItem(chk) == null && bb.$getItem(chk + 1) == null) {
done = true;
} else {
count += 1;
chk += 1;
}
} while (done === false);
return count;
}
//-------------------------------------------------------------------------------------------------------------
// reindexes contracts (type based on baseref), from a particular point in the array
this.$reindexContracts = function (baseRef, point, bbRemove) {
var bb = worldScripts.BulletinBoardSystem;
var idx = baseRef + point;
if (bbRemove == true || bbRemove == null) bb.$removeBBMission(idx);
var chk = idx + 1;
var done = false;
do {
var item = bb.$getItem(chk);
if (item != null) {
// reindex the bb item
item.ID = chk - 1;
chk += 1;
} else {
done = true;
}
} while (done === false);
}
//-------------------------------------------------------------------------------------------------------------
// smuggling contracts specific functions
//-------------------------------------------------------------------------------------------------------------
// removes a smuggling contract from the BB
this.$removeSmugglingContract = function (idx) {
// find and remove the contract from the BB
var bb = worldScripts.BulletinBoardSystem;
var sc = worldScripts.Smugglers_Contracts;
for (var i = 0; i < bb._data.length; i++) {
var itm = bb._data[i];
if (itm != null && itm.accepted === true) {
// is this item the one we're dealing with?
if (itm.destination === sc._smugglingContracts[idx].destination && itm.payment === sc._smugglingContracts[idx].fee && itm.source === sc._smugglingContracts[idx].start) {
bb.$removeBBMission(itm.ID);
break;
}
}
}
}
//-------------------------------------------------------------------------------------------------------------
// clean up any orphaned smuggling contracts
this.$checkSmugglingContracts = function () {
var bb = worldScripts.BulletinBoardSystem;
var sc = worldScripts.Smugglers_Contracts;
if (!sc) return;
for (var i = bb._data.length - 1; i >= 0; i--) {
var itm = bb._data[i];
// is this a smuggling contract
if (itm.stationKey === "blackMarket" && itm.availableCallback === "$smugglingContractAvailable") {
var found = false;
// see if this contract is still active
for (var j = 0; j < sc._smugglingContracts.length; j++) {
// is this item the one we're dealing with?
if (itm.destination === sc._smugglingContracts[j].destination && itm.payment === sc._smugglingContracts[j].fee && itm.source === sc._smugglingContracts[j].start) {
found = true;
break;
}
}
// if it doesn't exist we need to remove the BB item as well
if (found === false) {
bb.$removeBBMission(itm.ID);
//bb._data.splice(i, 1);
}
}
}
}
//-------------------------------------------------------------------------------------------------------------
// called by smugglers contracts, to ensure the contracts have been restored before we try to convert them
this.$convertSmugglingContracts = function () {
var count = 0;
// smuggling contracts
if (worldScripts.Smugglers_Contracts) {
this._smuggling = true;
count = worldScripts.Smugglers_Contracts._contracts.length;
if (count > 0) {
// see if there are any unaccepted missions @ ID 34000
var itm = worldScripts.BulletinBoardSystem.$getItem(34000);
// if there isn't, run the conversion process
if (itm == null || this.$countContracts(34000) != count) this.$convertContracts("smuggling");
}
}
}
//-------------------------------------------------------------------------------------------------------------
// Escort Contracts specific functions
//-------------------------------------------------------------------------------------------------------------
this.$checkEscortContacts = function () {
var bb = worldScripts.BulletinBoardSystem;
var ec = worldScripts.Escort_Contracts;
if (!ec) return;
for (var i = bb._data.length - 1; i >= 0; i--) {
var itm = bb._data[i];
if (itm.accepted === false && itm.data && itm.data === "escort") {
// is this item still active?
if (!ec.ec_targetsystems) {
//log(this.bame, "no ec data - removing bb item id " + itm.ID);
bb.$removeBBMission(itm.ID);
} else {
var found = false;
for (var j = 0; j < ec.ec_targetsystems.length - 1; j++) {
if (ec.ec_targetsystems[j] === itm.destination && itm.payment === ec.ec_contractactualprices[j]) found = true;
}
if (found === false) {
//log(this.bame, "no ec data match - removing bb item id " + itm.ID);
bb.$removeBBMission(itm.ID);
}
}
}
}
}
//-------------------------------------------------------------------------------------------------------------
// Rescue Station specific functions
//-------------------------------------------------------------------------------------------------------------
this.$rrsExtractMissionTitle = function (ref) {
var text = expandMissionText("rescue_scenario_" + ref + "_synopsis");
var title = text.substring(0, text.indexOf("\n"));
return title;
}
//-------------------------------------------------------------------------------------------------------------
this.$rrsExtractMissionDetails = function (ref) {
var text = expandMissionText("cobb_rescue_scenario_" + ref + "_mission_available");
if (!text && ref.length > 1) text = expandMissionText("cobb_rescue_scenario_" + ref.substring(0, 1) + "_mission_available");
if (!text) text = "<<Error: mission details for scenario " + ref + " not found>>";
return text;
}
//-------------------------------------------------------------------------------------------------------------
this.$rrsStoreCurrentVariables = function () {
var sc = "Rescue Scenario " + missionVariables.rescuestation_scenario;
var list = this._rrsMissionVariables[sc];
this._rrsMissionCurrent = {};
for (var i = 0; i < list.length; i++) {
this._rrsMissionCurrent[list[i]] = missionVariables[list[i]];
}
}
//-------------------------------------------------------------------------------------------------------------
this.$rrsReturnCurrentVariables = function () {
var sc = "Rescue Scenario " + missionVariables.rescuestation_scenario;
var list = this._rrsMissionVariables[sc];
this._rrsMissionCurrent = {};
for (var i = 0; i < list.length; i++) {
missionVariables[list[i]] = this._rrsMissionCurrent[list[i]];
}
}
//-------------------------------------------------------------------------------------------------------------
this.$rrsReloadMissionVariables = function (scen, idx) {
var list = this._rrsMissionVariables[scen];
for (var i = 0; i < list.length; i++) {
missionVariables[list[i]] = this._rrsMissionStorage[idx][list[i]];
}
}
//-------------------------------------------------------------------------------------------------------------
this.$rrsSaveMissionVariables = function (scen, idx) {
var list = this._rrsMissionVariables[scen];
this._rrsMissionStorage[idx] = {};
for (var i = 0; i < list.length; i++) {
// look for any expansion items in the mission variable content
if (typeof missionVariables[list[i]] === "string" && missionVariables[list[i]].indexOf("[") >= 0) {
missionVariables[list[i]] = expandDescription(missionVariables[list[i]]);
}
this._rrsMissionStorage[idx][list[i]] = missionVariables[list[i]];
}
}
//-------------------------------------------------------------------------------------------------------------
this.$rrsResetMissionVariables = function (scen) {
var list = this._rrsMissionVariables[scen];
for (var i = 0; i < list.length; i++) {
delete missionVariables[list[i]];
}
}
//-------------------------------------------------------------------------------------------------------------
this.$rrsGetShipRoleForScenario = function (scen) {
var role = this._rrsMissionShipRole[scen];
if (role === "shipModel") role = missionVariables.rescuestation_shiprole;
return role;
}
//-------------------------------------------------------------------------------------------------------------
this.$rrsGetKeyForShipRole = function (shiprole) {
var key = "";
if (shiprole === "asteroidModel") {
key = this._rrsAsteroidKeyList[Math.floor(Math.random() * this._rrsAsteroidKeyList.length)];
} else {
var dataKeys = Ship.keysForRole(shiprole);
var index = Math.floor(Math.random() * dataKeys.length);
key = dataKeys[index];
}
return key;
}
//-------------------------------------------------------------------------------------------------------------
// replacement for the standard RRS mission success routine. Allows us to hook in.
this.$cobb_missionSuccess = function () {
worldScripts.ContractsOnBB.$rrsCompleteMission();
var sckey = missionVariables.rescuestation_scenario;
if (!this.missionlog[sckey + "_complete"]) {
this.missionlog[sckey + "_complete"] = 1;
} else {
this.missionlog[sckey + "_complete"]++;
}
this.syncMissionLog();
worldScripts["Rescue Scenario " + missionVariables.rescuestation_scenario].missionSuccess();
this.cleanupMission();
this.fillMissionBoard();
}
//-------------------------------------------------------------------------------------------------------------
// replacement for the standard RRS mission failue routine. Allows us to hook in.
this.$cobb_failMission = function () {
worldScripts.ContractsOnBB.$rrsCompleteMission();
var sckey = missionVariables.rescuestation_scenario;
if (!this.missionlog[sckey + "_failed"]) {
this.missionlog[sckey + "_failed"] = 1;
} else {
this.missionlog[sckey + "_failed"]++;
}
this.syncMissionLog();
worldScripts["Rescue Scenario " + missionVariables.rescuestation_scenario].failMission();
this.cleanupMission(); // all for now
}
//-------------------------------------------------------------------------------------------------------------
this.$rrsCompleteMission = function () {
// find the contract in the BB to remove it. There should only be one accepted mission
var bb = worldScripts.BulletinBoardSystem;
var rrsList = this.$getActiveContractsByType("rescue");
if (rrsList.length > 0) {
var found = false;
bb.$removeBBMission(rrsList[0].ID);
/*for (var i = 0; i < bb._data.length; i++) {
if (bb._data[i].data === "rescue" && bb._data[i].accepted === true) {
found = true;
bb._data.splice(i, 1);
break;
}
}*/
//if (found === true)
bb.$initInterface(player.ship.dockedStation);
}
}
//-------------------------------------------------------------------------------------------------------------
this.$rrsGetAsteroidKeyList = function () {
// these asteroid models don't work on a mission screen, so exclude them
var exclude = ["Casteroid1", "Casteroid2", "Casteroid3", "Casteroid4", "Casteroid5", "Casteroid6", "Casteroid7",
"Casteroid8", "Casteroid9", "Casteroid10", "Casteroid11", "Casteroid12"
];
var keys = Ship.keysForRole("asteroid");
this._rrsAsteroidKeyList.length = 0;
for (var i = 0; i < keys.length; i++) {
// and exclude any of the yah billboards as well
if (keys[i].indexOf("billboard") === -1 && exclude.indexOf(keys[i]) === -1) this._rrsAsteroidKeyList.push(keys[i]);
}
}
//-------------------------------------------------------------------------------------------------------------
// Random Hits specific functions
//-------------------------------------------------------------------------------------------------------------
this.$rhReplaceMissionVariables = function (text) {
if (text == null) return "";
for (var i = 0; i < this._rhMissionVariables.length; i++) {
if (text.indexOf(this._rhMissionVariables[i]) >= 0) {
do {
text = text.replace("mission_" + this._rhMissionVariables[i], missionVariables[this._rhMissionVariables[i]]);
} while (text.indexOf(this._rhMissionVariables[i]) >= 0);
}
}
return text;
}
//-------------------------------------------------------------------------------------------------------------
this.$rhExtractMissionDetails = function (text) {
var point1 = text.indexOf("\n\n") + 2;
var point2 = text.indexOf("REPLIES TO");
return text.substring(point1, point2);
}
//-------------------------------------------------------------------------------------------------------------
this.$rhExtractMissionTitle = function (text) {
return text.substring(0, text.length - 1);
}
//-------------------------------------------------------------------------------------------------------------
this.$rhDifficultyText = function (diff) {
var text = "";
switch (diff) {
case 1:
text = expandDescription("This is [random_hits_makeoffer3_start_levelone] [mission_random_hits_assassination_board_job_name]. [assassination_board_easykill]");
break;
case 2:
text = expandDescription("This is [random_hits_makeoffer3_start_leveltwo] [mission_random_hits_assassination_board_job_name]. [assassination_board_mediumkill]");
break;
case 3:
text = expandDescription("This is [random_hits_makeoffer3_start_levelthree] [mission_random_hits_assassination_board_job_name]. [assassination_board_hardkill]");
break;
}
return text;
}
//-------------------------------------------------------------------------------------------------------------
this.$rhBarBill = function () {
if (this._convertRHContracts && player.ship.dockedStation.name === "A Seedy Space Bar" && player.credits > 0) {
var rh = worldScripts["Random_Hits"];
if (rh.random_hits_billdue > player.credits) rh.random_hits_billdue = player.credits;
rh.showScreen = "barBill";
rh.missionOffers();
rh.showScreen = "";
}
}
//-------------------------------------------------------------------------------------------------------------
this.$rhBarBillPostLaunch = function (station) {
if (this._convertRHContracts && station.name === "A Seedy Space Bar" && player.credits > 0) {
var rh = worldScripts["Random_Hits"];
if (rh.random_hits_billdue > player.credits) rh.random_hits_billdue = player.credits;
var text = expandMissionText("cobb_random_hits_barbill_postlaunch", {
barbill: formatCredits(parseFloat(rh.random_hits_billdue), true, true)
});
player.credits -= rh.random_hits_billdue;
station.commsMessage(text, player.ship);
}
}
//-------------------------------------------------------------------------------------------------------------
// mining contract specific functions
//-------------------------------------------------------------------------------------------------------------
this.$partMiningContract_process = function (missID) {
var bb = worldScripts.BulletinBoardSystem;
var itm = bb.$getItem(missID);
var idx = missID - 39000;
var mc = worldScripts.miningcontracts;
var contract = mc.MC_contracts[idx];
var amount = Math.min(contract.amount, manifest[contract.cargo]);
player.consoleMessage(amount + "t of " + displayNameForCommodity(contract.cargo).toLowerCase() + " dispatched");
contract.amount -= amount;
manifest[contract.cargo] -= amount;
mc.MC_subscr = Math.max(mc.MC_subscr, 900 * Math.floor(clock.seconds / 900)) + amount * 900;
this.$convertContracts("mining");
}
//-------------------------------------------------------------------------------------------------------------
this.$partMiningContract_condition = function (missID) {
var idx = missID - 39000;
var mc = worldScripts.miningcontracts;
var contract = mc.MC_contracts[idx];
var amount = manifest[contract.cargo];
if (contract.signed === 2) return "Contract terminated";
if (contract.amount === 0) return "Contract can be completed";
if (amount === 0) return "No " + displayNameForCommodity(contract.cargo).toLowerCase() + " in cargo hold";
return "";
}
//-------------------------------------------------------------------------------------------------------------
this.$miningContract_wait = function () {
var mc = worldScripts.miningcontracts;
if (player.credits < mc.MC_waitPrice) {
player.consoleMessage("Insufficient credits");
return;
}
player.consoleMessage(formatCredits(mc.MC_waitPrice, true, true) + " deducted");
player.credits -= mc.MC_waitPrice;
mc.MC_waitForContract();
this.$convertContracts("mining");
}
//-------------------------------------------------------------------------------------------------------------
this.$miningContract_repayDebt = function () {
var mc = worldScripts.miningcontracts;
if (mc.MC_debt > player.credits) {
player.consoleMessage("Insufficient credits");
} else {
player.consoleMessage(formatCredits(mc.MC_debt, true, true) + " deducted");
player.credits -= mc.MC_debt;
mc.MC_debt = 0;
worldScripts.BulletinBoardSystem.$removeMainMenuItem(this.name, "$miningContract_repayDebt");
}
mc.MC_generateContracts();
this.$convertContracts("mining");
}
//-------------------------------------------------------------------------------------------------------------
this.$miningContractOpen = function (missID) {
if (this._convertMiningContracts) {
if (missID >= 39000) {
var bb = worldScripts.BulletinBoardSystem;
var itm = bb.$getItem(missID);
var idx = missID - 39000;
var mc = worldScripts.miningcontracts;
var contract = mc.MC_contracts[idx];
if (manifest[contract.cargo] > 0 && contract.amount > 0) {
itm.customMenuItems[0].text = "Dispatch current cargo load (" + Math.min(contract.amount, manifest[contract.cargo]) + "t × " + displayNameForCommodity(contract.cargo).toLowerCase() + ")";
} else {
itm.customMenuItems[0].text = "Dispatch current cargo load";
}
// keep these details up to date whenever a mining contract is opened
var med = "Mining Association of " + mc.MC_system;
var reward = contract.reward - contract.amount * contract.penalty;
var repayment = Math.min(reward, mc.MC_debt);
reward -= repayment;
var balance = contract.reward - contract.amount * contract.penalty;
itm.postStatusMessages[0].text = expandDescription("[contract-mining-completed]", {
mediator: med,
amount: formatCredits(reward, true, true)
});
if (balance < 0) {
itm.postStatusMessages[1].text = expandDescription("[contract-mining-terminated-1]", {
mediator: med,
amount: formatCredits(-balance, true, true)
});
} else {
itm.postStatusMessages[1].text = expandDescription("[contract-mining-terminated-2]", {
mediator: med,
amount: formatCredits(balance, true, true)
}) +
((mc.MC_debt - repayment) > 0 ? expandDescription("[contract-mining-debt]", {
mediator: med,
amount: formatCredits(Math.min(reward, (mc.MC_debt - repayment)), true, true)
}) : "");
}
}
}
}
//-------------------------------------------------------------------------------------------------------------
this.$miningContractListOpen = function () {
if (this._convertMiningContracts) {
if (Ship.roleIsInCategory(player.ship.dockedStation.primaryRole, "oolite-rockhermits") === true) {
var bb = worldScripts.BulletinBoardSystem;
var mc = worldScripts.miningcontracts;
if (mc.MC_debt > 0) {
bb.$removeMainMenuItem(this.name, "$miningContract_repayDebt");
bb.$addMainMenuItem({
text: "Repay debt (" + formatCredits(mc.MC_debt, true, true) + ")",
worldScript: this.name,
menuCallback: "$miningContract_repayDebt"
});
} else {
bb.$removeMainMenuItem(this.name, "$miningContract_repayDebt");
}
}
}
}
//-------------------------------------------------------------------------------------------------------------
this.$checkForHermit = function (station) {
// turn on the always visible flag at hermits
if (Ship.roleIsInCategory(station.primaryRole, "oolite-rockhermits") === true) {
var bb = worldScripts.BulletinBoardSystem;
var mc = worldScripts.miningcontracts;
bb._alwaysShowBB = true;
bb.$removeMainMenuItem(this.name, "$miningContract_wait");
bb.$addMainMenuItem({
text: "Wait for new mining contracts (" + formatCredits(mc.MC_waitPrice, true, true) + ")",
worldScript: this.name,
menuCallback: "$miningContract_wait"
});
}
}
//-------------------------------------------------------------------------------------------------------------
// small adjustment to the shipExitedWitchspace routine, to eliminate some unneccessary functions
this.$mc_shipExitedWitchspace = function () {
this.MC_countAsteroids();
var number = this.MC_contracts.length;
var total = this.MC_debt;
for (var i = 0; i < number; i++) {
var contract = this.MC_contracts[i];
if (contract.signed) total += contract.amount * contract.penalty - contract.reward;
}
this.MC_contracts.length = 0;
this.MC_debt = 0;
this.MC_clock = 0;
if (total > 0) {
player.ship.setBounty(player.bounty + 50, "contract obligations");
var targets = system.shipsWithPrimaryRole("buoy-witchpoint");
if (targets.length > 0) {
targets[0].commsMessage("The Mining Association of " + this.MC_system + " has put a bounty of " + formatCredits(50, true, true) + " on your head.", player.ship);
}
}
}
//-------------------------------------------------------------------------------------------------------------
// taxi galactica specific functions
//-------------------------------------------------------------------------------------------------------------
this.$tg_choiceEvaluation = function (choice) {
// Mission text screen choices are below:
// Welcome screen choices:
if (missionVariables.taxistat === "REVISIT_1") {
if (choice === "1BOARD") {
worldScripts.BulletinBoardSystem.$showBB();
return;
} else if (choice === "2EXPLORE") {
// Return to the manifest screen:
missionVariables.taxistat = "EXPLORE";
}
}
// Special Mission #1 screen choices:
if (missionVariables.taxistat === "SPEC_MIS_01_1") {
if (choice === "1ACCEPT") {
this.$tg_acceptSpecialMission();
}
}
return;
}
//-------------------------------------------------------------------------------------------------------------
this.$tg_acceptSpecialMission = function () {
// Store special mission #1 details into variables and add passenger to ship & manifest:
missionVariables.taxi_passenger = missionVariables.taxi_specmis_1_ambassador;
missionVariables.taxi_dest = missionVariables.taxi_specmis1_dest;
missionVariables.taxi_dest_name = missionVariables.taxi_specmis1_dest_name;
missionVariables.taxi_diff = 3;
missionVariables.taxi_pay = 10000;
missionVariables.taxi_time = missionVariables.taxi_specmis1_time;
missionVariables.taxistatus = "ON_THE_JOB";
var name = missionVariables.taxi_passenger;
var curloc = system.ID;
var dest = missionVariables.taxi_dest;
var time = missionVariables.taxi_time;
var pay = missionVariables.taxi_pay;
player.ship.addPassenger(name, curloc, dest, clock.seconds + time * 24 * 3600, pay);
missionVariables.taxistat = "ACCEPTED";
// add this mission to the bulletin board
var bb = worldScripts.BulletinBoardSystem;
bb.$addBBMission({
source: system.ID,
destination: missionVariables.taxi_specmis1_dest,
stationKey: "mainStation",
description: expandDescription("[taxi-galactica-passenger-title]"),
details: expandDescription("[taxi-galactica-passenger-description]", {
client: missionVariables.taxi_specmis_1_ambassador,
destination: System.systemNameForID(missionVariables.taxi_specmis1_dest)
}),
payment: 10000,
accepted: true,
allowTerminate: false,
completionType: "IMMEDIATE",
stopTimeAtComplete: true,
allowPartialComplete: false,
expiry: (clock.seconds + missionVariables.taxi_specmis1_time * 24 * 3600),
disablePercentDisplay: true,
noEmails: true,
markerShape: "NONE", // marker control will be handled by contracts system
overlay: {
name: "cobb_taxi.png",
height: 546
},
customDisplayItems: cust,
initiateCallback: "$tg_acceptContract",
availableCallback: "$taxiGalacticaContractAvailable",
worldScript: this.name,
});
}
//-------------------------------------------------------------------------------------------------------------
this.$clearMissionSet = function $clearMissionSet(curr, range) {
var bb = worldScripts.BulletinBoardSystem;
var chk = 0;
var found = 0;
do {
if (bb.$getIndex(range + chk) >= 0) {
bb.$removeBBMission(range + chk);
found += 1;
}
// failsafe in case we don't find one
if (chk >= (range + 100)) found = curr + 1;
chk += 1;
} while (found < curr);
} |