Scripts/taxi_worldscript.js |
"use strict";
this.name = "in-system_taxi";
this.description = "In-system passenger contracts";
this.startUp = function() {
//USER TOGGLEABLE VARIABLES START
this.$availableOnLaunch = true;
//true sets taxi to available on launch, false sets taxi to unavailable on launch
this.$maxDistance = 1000000; //maximum distance of pickup point (in meters)
//USER TOGGLEABLE VARIABLES END
// this.$currentOffer = [offer_status, from_name, to_name, deadline, base_fare, passenger_name, system.ID, whole_time]
// status = 0 no offer or offer declined
// status = 1 offer waiting for approval
// status = 2 offer accepted
// status = 3 passenger on board
this.$currentOffer = [0];
if (missionVariables.inSystemTaxi != null) {//remove possible passenger
player.ship.removePassenger(missionVariables.inSystemTaxi);
}
this.$deleteMissionInstructions() //remove possible mission instructions
this.$stationOffers = []; //array for station offers
this.$fireMissionScreen = 0; //flag for selecting different mission screens
this.$readyToOffer = false; //start offering only after first launch
this.$refTime = clock.seconds;//time keeping for refreshing station contracts
this.$addedBeacon = [false, false];//flags for temporary beacons
this.$premium = 0;//needed in different functions, thus global variable
this.$offerFrequency = 90;//frequency at which new in-flight offers are generated and possibly offered. min 60
this.$taxiAvailable = this.$availableOnLaunch; //status of availability
}
//fare, based on distance
this.$fare = function(distance) {
return Math.floor(5 + 0.000005 * distance); //5 cr + 0.5 cr/100 km
}
this.playerWillSaveGame = function () {
if (this.$currentOffer[0] == 3)//mark in-system passenger to be removed on load
missionVariables.inSystemTaxi = this.$currentOffer[5]+" (going to "+this.$currentOffer[2].displayName+")";
else
missionVariables.inSystemTaxi = null;
}
//Taxi Comms comes through this function
this.$commsMessage = function(message) {
var notifySound = new SoundSource;
notifySound.sound = "beep.ogg";
notifySound.play();
player.commsMessage("Taxi Galactica's In-System Service:\n"+message, 6);
}
//find suitable stations
this.$listOfStations = function() {
function $isAllowed(entity) {
if (entity.scanClass == "CLASS_STATION") {
//excludes that have scanClass CLASS_STATION
if (entity.hasRole("gates_jumpGate")) return false;
if (entity.hasRole("fuelStation_satellite")) return false;
if (entity.hasRole("fuelStation_station")) return false;
if (entity.hasRole("jaguar_company_base")) return false;
return true;
}
if (entity.isStation) {
//includes that have isStation but not scanClass CLASS_STATION
if (entity.hasRole("liners_liner")) return true;
if (entity.hasRole("casinoship")) return true;
if (entity.hasRole("random_hits_any_spacebar")) return true;
}
if (entity.isPlanet && entity.displayName != null) {
//planetfall && planetary compass
if (!entity.isSun && !entity.hasOwnProperty("solarGasGiant") && !entity.hasOwnProperty("isGasGiant") && !entity.hasOwnProperty("PFNoLand") && !entity.hasOwnProperty("PFNoLandQuiet") && player.ship.equipmentStatus("EQ_PLANETFALL") == "EQUIPMENT_OK") return true;
}
return false;
}
return system.filteredEntities(this, $isAllowed);
}
//IN-FLIGHT OFFERING FUNCTIONS START HERE
//set taxi to not available on condition red
this.alertConditionChanged = function(newCondition, oldCondition) {
if (newCondition == 3) {
//worldScripts["in-system_taxi"].$commsMessage("Taxi Comms switched off");
this.$stopInFlightTimer();
}
}
//start in-flight offer timer
this.$startOfferTimer = this.playerCancelledJumpCountdown = function() {
//show in-flight contract offers
if (this.$taxiAvailable && this.$currentOffer[0] < 2 && (player.ship.passengerCapacity - player.ship.passengerCount) > 0 && player.ship.equipmentStatus("EQ_IN_SYSTEM_TAXI_LICENCE") == "EQUIPMENT_OK") {
this.$startInFlightTimer();
return true;
}
return false;
}
//start in-flight offer timer on launch only if available on launch is set.
this.shipLaunchedFromStation = function(station) {
if (this.$availableOnLaunch)
this.$taxiAvailable = true;
this.$startOfferTimer();
}
//stop in-flight offer timer
this.playerStartedJumpCountdown = function() {
this.$stopInFlightTimer();
}
//remove in-system contract when exiting system
this.shipWillEnterWitchspace = function() {
if (this.$currentOffer[0] == 3) {//make in-system passenger regular passenger
if (player.ship.removePassenger(this.$currentOffer[5]+" (going to "+this.$currentOffer[2].displayName+")"))//try to rename passenger
player.ship.addPassenger(this.$currentOffer[5], system.ID, system.ID, clock.seconds+10, this.$currentOffer[4]);
var message = "Taxi passenger "+this.$currentOffer[5]+" is very disappointed having missed the deadline. Return passenger to the main station of "+System.infoForSystem(system.info.galaxyID, this.$currentOffer[6]).name+".";
var delayedMessage = new Timer(this, function(){this.$commsMessage(message)}, 10);
}
if (this.$availableOnLaunch)
this.$taxiAvailable = true;
this.$endContract();
}
//create new in-flight offers
this.$taxiOffer = function() {
if (system.isInterstellarSpace) return;//sanity check;
var listOfStations = this.$listOfStations();
var probability = 0.05 * listOfStations.length; //0.05 * number of stations => 0.10 for 2 stations ... 1 for 20 stations
if (Math.random() < probability && listOfStations.length > 1) {
var to = listOfStations.splice(Math.floor(Math.random() * listOfStations.length), 1)[0];
var from = to;
var found = false;
while (listOfStations.length > 0 && !found) {//select suitable pickup point
from = listOfStations.splice(Math.floor(Math.random() * listOfStations.length), 1)[0];
if (player.ship.position.distanceTo(from) < this.$maxDistance)
found = true;
}
if (!found) return;//no suitable pickup points
if (to.isPlanet && from.isPlanet)
var distance = from.position.distanceTo(to) - to.radius - from.radius;
else if (to.isPlanet)
var distance = from.position.distanceTo(to) - to.radius;
else if (from.isPlanet)
var distance = from.position.distanceTo(to) - from.radius;
else
var distance = from.position.distanceTo(to);
var baseTime = 0.0002 * distance + 1200; //20 secs per 100 km + 20 mins for reach, launch and incidents.
var time = clock.seconds + baseTime;
var fee = this.$fare(distance);
var name = global.randomName() +" "+ global.randomName();
this.$commsMessage("Name: "+name+"\nFrom: "+from.displayName + "\nTo: " + to.displayName + "\nTime: "+ Math.floor((time - clock.seconds)/60) +" minutes\nBase fare: " + formatCredits(fee, true, true) + "\nAccept contract in 60 seconds");
this.$removeOfferTimer();
this.$offerTimer = new Timer(this, function(){this.$currentOffer = [0];}, 60);//offer ends in 60 secs
//time contract, so it can be removed if deadline is met before picking the passenger up.
this.$removeContractTimer();
this.$contractTimer = new Timer(this, this.$endContract, time - clock.seconds);
this.$currentOffer = [1, from, to, time, fee, name, system.ID, baseTime];
}
}
//accept offer
this.$acceptOffer = function() {
this.$stopInFlightTimer();
this.$removeOfferTimer();
this.$currentOffer[0] = 2;
this.$addMissionInstructions();
this.$commsMessage("Contract accepted. Pick up passenger at "+this.$currentOffer[1].displayName);
this.$addBeacon();
}
//cancel contract
this.$cancelContract = function() {
this.$endContract();
this.$commsMessage("Contract cancelled");
}
//cancel contract before picking passenger up.
this.$endContract = function() {
if (this.$currentOffer[0] < 3) {//passenger not on board yet.
this.$removeBeacon();
this.$deleteMissionInstructions();
this.$currentOffer = [0];
this.$removeContractTimer();
this.$startOfferTimer();
}
}
//add mission instructions when accepting contract
this.$addMissionInstructions = function() {
var deadline = new Date(0, 0, 0, 0, 0, this.$currentOffer[3]);
var instructionText = "Taxi: "+this.$currentOffer[5]+" from " + this.$currentOffer[1].displayName + " to " + this.$currentOffer[2].displayName + " before " + deadline.toLocaleTimeString() +".";
mission.setInstructions(instructionText, this.name);
}
//delete mission instructions when cancelling contract
this.$deleteMissionInstructions = function() {
mission.setInstructions(null, this.name);
}
//IN-FLIGHT OFFERING FUNCTIONS END HERE
//STATION OFFERING FUNCTIONS START HERE
//create new station offers
this.$createStationOffers = function() {
if (system.isInterstellarSpace) return;//sanity check;
var i;
var listOfStations = this.$listOfStations();
for (i = 0; i < listOfStations.length; i++) {
if (listOfStations[i] != player.ship.dockedStation && Math.random() < 0.1) {//contract probability of 0.1 per station in system.
var from = player.ship.dockedStation;
var to = listOfStations[i];
if (to.isplanet)
var distance = from.position.distanceTo(to) - to.radius;
else
var distance = from.position.distanceTo(to);
var baseTime = 0.0002 * distance + 900; //20 secs per 100 km + 15 mins for launch and incidents.
var time = clock.seconds + baseTime;
var fee = this.$fare(distance);
var name = global.randomName() +" "+ global.randomName();
this.$stationOffers.push([1, from, to, time, fee, name, system.ID, baseTime]);
if (this.$stationOffers.length == 8) break; //cap possible offers to 8
}
}
}
//create station offers when docking
this.shipDockedWithStation = function(station) {
this.$stationOffers = [];
this.$createStationOffers();
this.$stationOffersInterface();
this.$refTime = clock.seconds;
}
//handle f4-screen
this.$stationOffersInterface = function() {
//show interface if no contract accepted, no room or no offers
if (this.$readyToOffer && this.$stationOffers.length > 0 && this.$currentOffer[0] < 2 && player.ship.passengerCapacity - player.ship.passengerCount > 0) {
player.ship.dockedStation.setInterface("in-system_taxi",{
title: "In-system taxi deliveries (" +this.$stationOffers.length+" available)",
category: "Deliveries",
summary: "Taxi Galactica's in-system taxi contracts. Pick a passenger from this station and make a fast transport to another station in-system.",
callback: this.$showStationOffers.bind(this)
});
}
else {
player.ship.dockedStation.setInterface("in-system_taxi",null);//remove interface if contract accepted, no room or no offers
}
}
//clean old offers and add new offers time to time
this.guiScreenChanged = function(to, from) {
if (player.ship.docked && !system.isInterstellarSpace && clock.seconds - this.$refTime > 600) {//refresh every 10 mins of game time
this.$createStationOffers();
this.$clearOldOffers();
this.$refTime = clock.seconds;
}
}
this.$clearOldOffers = function() {
var i;
var validOffers = [];
for (i = 0; i < this.$stationOffers.length; i++) {
//leave only ones that have at least 5 mins of fly time left, 10 goes to launching
if ((Math.floor((this.$stationOffers[i][3] - clock.seconds))) > 900) {
validOffers.push(this.$stationOffers[i]);
}
}
this.$stationOffers = validOffers;
this.$stationOffersInterface();
}
//mission screen for showing offers
this.$showStationOffers = function() {
var options = {};
var emptyMessage = "";
this.$clearOldOffers();
if (this.$stationOffers.length == 0) {
emptyMessage = "\n\nToo late. You just missed the last passenger. Come back later."
}
else {
var i;
for (i = 0; i < this.$stationOffers.length; i++) {
options[i+"_TAXI"] = this.$stationOffers[i][5] +" to "+ this.$stationOffers[i][2].displayName +" in " + Math.floor((this.$stationOffers[i][3] - clock.seconds)/60) +" minutes. Fare: "+ formatCredits(this.$stationOffers[i][4], true, true);
}
}
options["99_NO_THANKS"] = "Exit in-system contracts";
mission.runScreen({
title: "Taxi Galactica's In-System Contracts",
message: "Welcome to Taxi Galactica's in-system taxi services of "+system.name+". We have busy customers waiting for a fast in-system transportation. For a fast delivery, you will get a tip. The faster you go, the bigger tip you'll get."+emptyMessage,
choices: options,
exitScreen: "GUI_SCREEN_INTERFACES",
background: "tg_is_background.png"
},
function (choice) {
if (!choice || choice == "99_NO_THANKS") return;
else {
this.$removeOfferTimer();//in case there is an offerTimer running from in-flight offers.
this.$currentOffer = this.$stationOffers[choice.charAt(0)];
this.$currentOffer[0] = 2;
player.ship.dockedStation.setInterface("in-system_taxi",null);//remove station interface after accepting contract.
}
});
}
//STATION OFFERING FUNCTIONS END HERE
//CONTRACT HANDLING
//add temporary beacons
this.$addBeacon = function() {
//add temporary from beacon
if (this.$currentOffer[0] == 2 && !this.$currentOffer[1].beaconCode) {
this.$currentOffer[1].beaconCode = "Taxi beacon";
this.$addedBeacon[0] = true;
}
//add temporary to beacon
if (this.$currentOffer[0] == 3 && !this.$currentOffer[2].beaconCode) {
this.$currentOffer[2].beaconCode = "Taxi beacon";
this.$addedBeacon[1] = true;
}
}
//remove temporary beacons
this.$removeBeacon = function() {
//remove temporary from beacon
if (this.$addedBeacon[0]) {
this.$currentOffer[1].beaconCode = null;
this.$addedBeacon[0] = false;
}
//remove temporary to beacon
if (this.$addedBeacon[1]) {
this.$currentOffer[2].beaconCode = null;
this.$addedBeacon[1] = false;
}
}
this.shipWillLaunchFromStation = function(station) {
this.$readyToOffer = true;//after frist launch, allow offering
this.$addBeacon();//add temporary beacons
}
//handle passenger when docking
this.shipWillDockWithStation = function(station) {
this.$removeBeacon();//remove temporary beacons
this.$stopInFlightTimer();//stop in-flight offering
//is there a passenger on board?
if (this.$currentOffer[0] == 3) {
//over 15 minutes (15*60 = 900 secs) late, cancel contract if possible.
if (this.$currentOffer[3] - clock.seconds < -900) {
if (player.ship.removePassenger(this.$currentOffer[5]+" (going to "+this.$currentOffer[2].displayName+")")) {
//switch taxi passenger to a game passenger and let the game handle rest
if (station != this.$currentOffer[2]) {
player.ship.addPassenger(this.$currentOffer[5], system.ID, system.ID, clock.seconds+10, this.$currentOffer[4]);
this.$fireMissionScreen = 6;
this.$currentOffer[0] = 0;
}
//if we're already at home, no switching is required, just fire mission screen
else {
this.$fireMissionScreen = 5;
this.$currentOffer[0] = 0;
}
}
return;
}
//destination check
var rightDestination = false;
if (this.$currentOffer[2].isPlanet) {
if (worldScripts.PlanetFall.lastPlanet == this.$currentOffer[2] && (station.hasRole("planetFall_surface")))
rightDestination = true;
}
else if (station == this.$currentOffer[2])
rightDestination = true;
//right destination, 0 - 15 mins late, remove passenger, pay fare
if (this.$currentOffer[3] - clock.seconds < 0 && rightDestination) {
player.ship.removePassenger(this.$currentOffer[5]+" (going to "+this.$currentOffer[2].displayName+")");
player.credits = player.credits + this.$currentOffer[4];
this.$fireMissionScreen = 4;
this.$currentOffer[0] = 0;
return;
}
//right destination in time, remove passenger, pay fare and possibly premium
if (rightDestination) {
player.ship.removePassenger(this.$currentOffer[5]+" (going to "+this.$currentOffer[2].displayName+")");
this.$premium = 30 * ((this.$currentOffer[3] - clock.seconds) / this.$currentOffer[7]);//tip 30*proportion
player.credits = player.credits + this.$currentOffer[4] + this.$premium;
this.$fireMissionScreen = 2;
this.$currentOffer[0] = 0;
return;
}
//docking main station
if (station.isMainStation) {
//if late, can't swap passengers at main station. Passenger just leaves.
if (this.$currentOffer[3] - clock.seconds < 0) {
player.ship.removePassenger(this.$currentOffer[5]+" (going to "+this.$currentOffer[2].displayName+")");
this.$fireMissionScreen = 5;
this.$currentOffer[0] = 0;
}
//if time remaining, replace real passenger with bogus passenger
else if (player.ship.removePassenger(this.$currentOffer[5]+" (going to "+this.$currentOffer[2].displayName+")"))
player.ship.addPassenger("Taxi temp stand in", ((system.ID+2) % 256 - 1), ((system.ID+2) % 256 - 1), clock.seconds+3600, 0);
}
}
}
//handle unhiding the passenger and passenger picking. show mission screens, when there's something to show.
this.missionScreenOpportunity= function() {
//check berth status when passenger on board and docked at main station.
if (player.ship.docked && player.ship.dockedStation.isMainStation && this.$currentOffer[0] == 3) {
//unhide passenger, if hidden.
if (player.ship.removePassenger("Taxi temp stand in")) {//remove bogus
if (!player.ship.addPassenger(this.$currentOffer[5]+" (going to "+this.$currentOffer[2].displayName+")", system.ID, system.ID, this.$currentOffer[3], 0)) { //put passenger back
this.$fireMissionScreen = 5;//very rare case, where passenger has vanished while docking.
}
}
else {//has passenger contract has been removed by game?
var passengers = player.ship.passengers;
var i;
var passengerInBerth = false;
for (i = 0; i < passengers.length; i++) {
if (passengers[i].name == this.$currentOffer[5]+" (going to "+this.$currentOffer[2].displayName+")") {
passengerInBerth = true;
break;
}
}
if (!passengerInBerth)//passenger has vanished, fire mission screen
this.$fireMissionScreen = 5;
}
}
//If we are at the right starting point, let's pick the passenger on board.
else if (player.ship.docked && this.$currentOffer[0] == 2) {
var rightStartingPoint = false;
if (this.$currentOffer[1].isPlanet) {//is it a planetary starting point?
if (worldScripts.PlanetFall.lastPlanet == this.$currentOffer[1] && (player.ship.dockedStation.hasRole("planetFall_surface")))
rightStartingPoint = true;
}
else if (player.ship.dockedStation == this.$currentOffer[1])
rightStartingPoint = true;
if (rightStartingPoint) {//right starting point
this.$deleteMissionInstructions();
//is there room for the passenger?
if (player.ship.passengerCapacity - player.ship.passengerCount == 0) {
this.$fireMissionScreen = 3;
}
//all is probably well, let's add new contract
else {
player.ship.addPassenger(this.$currentOffer[5]+" (going to "+this.$currentOffer[2].displayName+")", system.ID, system.ID, this.$currentOffer[3], 0);
this.$currentOffer[0] = 3;
this.$currentOffer[7] = this.$currentOffer[3] - clock.seconds;//premium is based on basetime. basetime is defined when pickin up passenger.
this.$fireMissionScreen = 1;
}
}
}
switch(this.$fireMissionScreen) {
case 1:
mission.runScreen({
title: "Passenger boarding",
message: "Taxi passenger "+this.$currentOffer[5]+" has boarded and is expecting to arrive "+ this.$currentOffer[2].displayName + " in " + Math.floor((this.$currentOffer[3] - clock.seconds)/60) +" minutes. Will pay you a fare of "+formatCredits(this.$currentOffer[4], true, true)+" for reaching the destination in time and a tip, if you're fast enough.",
background: "tg_is_background.png"
});
this.$fireMissionScreen = 0;
break;
case 2:
var tipTalk = "";
if (this.$premium > 0.05)
tipTalk = " For fast delivery, you receive a tip of "+formatCredits(this.$premium, true, true) +".";
mission.runScreen({
title: "Satisfied customer",
message: "Taxi passenger "+this.$currentOffer[5]+" has arrived the destination in time. Fare of "+formatCredits(this.$currentOffer[4], true, true)+ " has been paid to your account." + tipTalk,
background: "tg_is_background.png"
});
this.$currentOffer = [0];
this.$fireMissionScreen = 0;
break;
case 3:
mission.runScreen({
title: "No room for passenger",
message: "Taxi passenger "+this.$currentOffer[5]+" is very disappointed after finding that there is no room in your ship. The contract is cancelled.",
background: "tg_is_background.png"
});
this.$currentOffer = [0];
this.$fireMissionScreen = 0;
break;
case 4:
mission.runScreen({
title: "Missed deadline",
message: "Taxi passenger "+this.$currentOffer[5]+" is not happy at all as you missed the deadline. You get your fare of "+formatCredits(this.$currentOffer[4], true, true)+ ", but no tip.",
background: "tg_is_background.png"
});
this.$currentOffer = [0];
this.$fireMissionScreen = 0;
break;
case 5:
mission.runScreen({
title: "Unhappy customer",
message: "Taxi passenger "+this.$currentOffer[5]+" was not pleased with your service and promises never to set foot on your ship again.",
background: "tg_is_background.png"
});
this.$currentOffer = [0];
this.$fireMissionScreen = 0;
break;
case 6:
mission.runScreen({
title: "Demanding customer",
message: "Taxi passenger "+this.$currentOffer[5]+" is very disappointed having missed the deadline and demands to be taken to the main station of "+System.infoForSystem(system.info.galaxyID, this.$currentOffer[6]).name+".",
background: "tg_is_background.png"
});
this.$fireMissionScreen = 0;
break;
}
}
//Timer functions
this.$startInFlightTimer = function() {
if (this.$showOfferTimer == null)
this.$showOfferTimer = new Timer(this, this.$taxiOffer, 60, this.$offerFrequency);
else this.$showOfferTimer.start();
};
this.$stopInFlightTimer = function() {
if (this.$showOfferTimer != null)
this.$showOfferTimer.stop();
};
this.$removeInFlightTimer = function() {
if (this.$showOfferTimer != null) {
this.$showOfferTimer.stop();
delete this.$showOfferTimer;
}
};
this.$removeOfferTimer = function() {
if (this.$offerTimer != null) {
this.$offerTimer.stop();
delete this.$offerTimer;
}
};
this.$removeContractTimer = function() {
if (this.$contractTimer != null) {
this.$contractTimer.stop();
delete this.$contractTimer;
}
};
this.playerBoughtEquipment = function(equipment) {
if (equipment === "EQ_IN_SYSTEM_TAXI_LICENCE_REMOVAL") {
player.ship.removeEquipment("EQ_IN_SYSTEM_TAXI_LICENCE");
player.ship.removeEquipment("EQ_IN_SYSTEM_TAXI_LICENCE_REMOVAL");
}
}
|