| Scripts/ept_bounties.js | "use strict";
this.name        = "EscapePodTweaks_Bounties";
this.author      = "phkb";
this.copyright   = "2019 phkb";
this.description = "Bounties expansion for Escape Pod Tweaks";
this.licence     = "CC BY-NC-SA 4.0";
this._licencePurchaseDate = 0;			// date hunter licence was purchased
this._prisoners = [];
this._processing = [];
this._disabled = true;
//-------------------------------------------------------------------------------------------------------------
this.startUp = function() {
    if (worldScripts.BountySystem_MostWanted) {
        delete this.dayChanged;
    }
    if (this._disabled === true) {
        delete this.shipWillDockWithStation;
        delete this.playerBoughtEquipment;
        delete this.startUp;
    }
}
//-------------------------------------------------------------------------------------------------------------
this.shipWillDockWithStation = function() {
}
//-------------------------------------------------------------------------------------------------------------
this.playerBoughtEquipment = function(equipment) {
    if (equipment === "EQ_PRISONER_CELL_BAY_REMOVAL") {
        player.ship.removeEquipment(equipment);
        player.ship.removeEquipment("EQ_PRISONER_CELL_BAY");
        // refund the cost of the prisoner bay
        player.credits += 1500;
    }
    // do our core function if most wanted isn't installed.
    if (!worldScripts.BountySystem_MostWanted) {
        this.playerBoughtEquipment_core(equipment);
    }
}
//-------------------------------------------------------------------------------------------------------------
this.playerBoughtEquipment_core = function(equipment) {
	if (equipment === "EQ_EPT_HUNTER_LICENCE_RENEWAL") {
		player.ship.removeEquipment(equipment);
		player.ship.awardEquipment("EQ_EPT_HUNTER_LICENCE");
		this._licencePurchaseDate = clock.adjustedSeconds;
	}
	if (equipment === "EQ_EPT_HUNTER_LICENCE") {
		this._licencePurchaseDate = clock.adjustedSeconds;
	}
}
//-------------------------------------------------------------------------------------------------------------
this.dayChanged = function(newday) {
	var lic_exp = (clock.adjustedSeconds - this._licencePurchaseDate) / 86400;
	if (lic_exp >= 25 && lic_exp < 30 && player.ship.equipmentStatus("EQ_HUNTER_LICENCE") === "EQUIPMENT_OK") {
		if (player.ship.docked === false && this._renewalDockMessage === false) {
			// add docking message (if in space)
			player.addMessageToArrivalReport(expandDescription("[ept-licence-renewal-docknotice]"));
			this._renewalDockMessage = true;
		} else {
			// add console message (if docked)
			player.consoleMessage(expandDescription("[ept-licence-renewal-docknotice]"));
		}
	}
	if (lic_exp >= 30 && player.ship.equipmentStatus("EQ_EPT_HUNTER_LICENCE") === "EQUIPMENT_OK") {
		player.ship.removeEquipment("EQ_EPT_HUNTER_LICENCE");
		// send email (if installed)
		var w = worldScripts.EmailSystem;
		if (w) {
			var ga = worldScripts.GalCopAdminServices;
			w.$createEmail({sender:"GalCop Security Office",
				subject:"Bounty Hunter Licence Expiration Notice",
				date:global.clock.adjustedSeconds,
				message:expandDescription("[ept-licence-expired]"),
				expiryDays:ga._defaultExpiryDays
			});
		}
		if (player.ship.docked === false) {
			// add docking message (if in space)
			player.addMessageToArrivalReport(expandDescription("[ept-licence-expiry-docknotice]"));
		} else {
			// add console message (if docked)
			player.consoleMessage(expandDescription("[ept-licence-expiry-docknotice]"));
		}
	}
}
//-------------------------------------------------------------------------------------------------------------
/*
    for this to work, we would have to monitor incoming escape pods
    when one is found that has a bounty, we would need to remove that entity and replace it with a standard cargo pod 
    with 1 slave aboard, and attach a shipWasDumped script to the new entity. then, if the pod is dumped, we swap it
    out again with the correct ship model
    can't do this for ships with characters or attached scripts - core code change required?
*/
this.$checkForProcessing = function $checkForProcessing() {
    var p = player.ship;
    // no prisoner cell -- no processing
    if (p.hasEquipmentProviding("EQ_PRISONER_CELL_BAY") === false) return;
    var ept = worldScripts.EscapePodTweaks;
    var epList = ept._escapePods;
    // no captured escape pods -- no processing
    if (epList.length === 0) return;
    var switched = 0;
    var heldPods = [];
    for (var i = 0; i < epList.length; i++) {
        var ep = epList[i];
        if (ep.crew[0].legalStatus > 0) {
            // ok, found one. grab the details
            this._processing.push({
                "pilotName": ep.crew[0].name,
                "pilotHomeSystem": ep.crew[0].homeSystem,
                "pilotDescription": ep.crew[0].description,
                "pilotInsurance": ep.crew[0].insuranceCredits,
                "pilotLegalStatus": ep.crew[0].legalStatus}
            );
            // and remove it from the main tweaks array - we'll handle this one here
            switched += 1;
        } else {
            heldPods.push({
                "dataKey": ep.dataKey,
                "entityPersonality": ep.entityPersonality,
                "AI": ep.AI,
                "AIScript": ep.AIScript.name,
                "pilotName": ep.crew[0].name,
                "pilotHomeSystem": ep.crew[0].homeSystem,
                "pilotDescription": ep.crew[0].description,
                "pilotInsurance": ep.crew[0].insuranceCredits,
                "pilotLegalStatus": ep.crew[0].legalStatus,
                "madeOffer": ep.script._ept_madeOffer
            });
        }
    }
    // if we switched one, we're going to have to pull a swifty - remove all pods, reset slave numbers, re-add pods
    // so when we hand back to EPT, it's ready to process
    if (switched > 0) {
        var remaining = heldPods.length;
        p.manifest["slaves"] = 0;
        if (heldPods.length > 0) {
            for (var i = 0; i < heldPods.length; i++) {
                // add the pod back
                ept.$addPodToShip(heldPods[i]);
            }
        }
    }
}
 | 
                
                    | Scripts/escapepodtweaks.js | "use strict";
this.name = "EscapePodTweaks";
this.author = "phkb";
this.copyright = "2017 phkb";
this.description = "Changes the way escape pods are processed to make it more logical";
this.licence = "CC BY-NC-SA 4.0";
/*
    This OXP makes the processing of escape pods a bit more realistic. When docking with escape pods, a check is made on the 
    type of station the player is docking at, and also of the number of docked police there are in the station. If the station
    is not a galcop-aligned station, or there are no police present, then escape pods will not be offloaded at the station.
*/
this._escapePods = []; // array of scooped escape pods
this._heldPods = []; // array of escape pods that will be added back to the player ship after launch
this._addBackTimer = null; // timer to monitor when Smugglers has finished it's processing
this._doAddBack = false; // flag to indicate that a count of slaves needs to be added after docking has completed
this._mo_timer = null;
this._sale = {};
//-------------------------------------------------------------------------------------------------------------
this.startUpComplete = function () {
    if (missionVariables.EscapePodsHeld) {
        this._heldPods = JSON.parse(missionVariables.EscapePodsHeld);
        delete missionVariables.EscapePodsHeld;
    }
}
//-------------------------------------------------------------------------------------------------------------
this.playerWillSaveGame = function () {
    // store the details of any escape pods we are holding
    if (this._heldPods.length > 0) {
        missionVariables.EscapePodsHeld = JSON.stringify(this._heldPods);
    } else {
        delete missionVariables.EscapePodsHeld;
    }
}
//-------------------------------------------------------------------------------------------------------------
this.shipScoopedOther = function (cargo) {
    // make a note of any escape pods we scoop
    // note: escape pods with no crew are treated as 1t slaves cargo pods, not as escape pods
    if (cargo.crew && cargo.crew.length > 0) {
        // add a shipWasDumped event monitor to check for the player dumping this pod
        if (cargo.script.shipWasDumped && !cargo.script.$eptovr_shipWasDumped) {
            cargo.script.$eptovr_shipWasDumped = cargo.script.shipWasDumped;
        }
        cargo.script.shipWasDumped = this.$ept_shipWasDumped;
        this._escapePods.push(cargo);
        this.$updateManifest();
    }
}
//-------------------------------------------------------------------------------------------------------------
this.shipWillDockWithStation = function (station) {
    if (this._escapePods.length > 0) {
        // look for a non-galcop station with no police
        if (station.dockedPolice === 0 && station.allegiance !== "galcop") {
            // go through the list of pods we've scooped to check they are still with the player
            for (var i = 0; i < this._escapePods.length; i++) {
                var ep = this._escapePods[i];
                // if the pod is with the player, copy enough info to be able to recreate this pod later
                if (ep.isValid && ep.status === "STATUS_IN_HOLD") {
                    this._doAddBack = true;
                    // grab enough info of rescued escape pods to allow us to recreate them later
                    this._heldPods.push({
                        "dataKey": ep.dataKey,
                        "entityPersonality": ep.entityPersonality,
                        "AI": ep.AI,
                        "AIScript": ep.AIScript.name,
                        "pilotName": ep.crew[0].name,
                        "pilotHomeSystem": ep.crew[0].homeSystem,
                        "pilotDescription": ep.crew[0].description,
                        "pilotInsurance": ep.crew[0].insuranceCredits,
                        "pilotLegalStatus": ep.crew[0].legalStatus,
                        "madeOffer": ep.script._ept_madeOffer
                    });
                }
            }
            // null out the slave count to essentially "dump" the escape pods so they don't get processed
            var remaining = player.ship.manifest["slaves"] - this._heldPods.length;
            player.ship.manifest["slaves"] = 0;
            player.ship.manifest["slaves"] = remaining;
        }
        // clear out the escapepod array - we don't need this anymore
        this._escapePods = [];
    }
}
//-------------------------------------------------------------------------------------------------------------
this.$ept_shipWasDumped = function $ept_shipWasDumped(dumper) {
    if (this.ship.script.$eptovr_shipWasDumped) this.ship.script.$eptovr_shipWasDumped(dumper);
    if (dumper.isPlayer) {
        var ept = worldScripts.EscapePodTweaks;
        for (var i = 0; i < ept._escapePods.length; i++) {
            if (ept._escapePods[i] == this.ship) {
                ept._escapePods.splice(i, 1);
                break;
            }
        }
    }
    // detach our custom script
    delete this.ship.script.shipWasDumped;
    if (this.ship.script.$eptovr_shipWasDumped) {
        this.ship.script.shipWasDumped = this.ship.script.$eptovr_shipWasDumped;
        delete this.ship.script.$eptovr_shipWasDumped;
    }
}
//-------------------------------------------------------------------------------------------------------------
this.missionScreenOpportunity = function () {
    if (this._doAddBack === true) {
        // don't call the addback until after Smugglers finishes
        if (worldScripts.Smugglers_Illegal && worldScripts.Smugglers_Illegal._doCargoCheck === true) {
            // start a timer to monitor for Smugglers being complete
            this._addBackTimer = new Timer(this, this.$waitForFreeTime, 0.25, 0);
            return;
        }
        // we should only get here if we're confident smugglers has finished
        this._doAddBack = false;
        if (this._heldPods.length > 0) player.ship.manifest["slaves"] += this._heldPods.length;
    }
    this.$updateManifest();
}
//-------------------------------------------------------------------------------------------------------------
this.shipLaunchedFromStation = function (station) {
    // puts escape pods back in the player's hold as real escape pods
    // do we have any held pods?
    if (this._heldPods.length > 0) {
        for (var i = 0; i < this._heldPods.length; i++) {
            // remove one of the slaves from the player's cargo hold
            player.ship.manifest["slaves"] -= 1;
            // add the pod back
            this.$addPodToShip(this._heldPods[i]);
        }
    }
    // clear out the array - we don't need this any more
    this._heldPods = [];
}
//-------------------------------------------------------------------------------------------------------------
// stop the player from selling cargo pods
this.playerSoldCargo = function (commodity, units, price) {
    var p = player.ship;
    var stn = p.dockedStation;
    if (commodity === "slaves") {
        var curamt = p.manifest[commodity];
        if (worldScripts.Smugglers_DockMaster) {
            curamt = p.manifest[commodity] - worldScripts.Smugglers_DockMaster.$getTotalRelabelled(commodity);
        }
        if (curamt < this._heldPods.length) {
            var refund = units;
            if (units > this._heldPods.length) refund = this._heldPods.length;
            if (units < this._heldPods.length) refund = this._heldPods.length - units;
            player.credits -= ((price / 10) * refund);
            p.manifest[commodity] += refund;
            stn.setMarketQuantity(commodity, stn.market[commodity].quantity - refund);
            player.consoleMessage(expandDescription("[ept-sell-pod]"));
            if (worldScripts.market_observer3) {
                this._mo_timer = new Timer(this, this.$reverseMOSale, 0.5, 0);
                this._sale = {
                    commodity: commodity,
                    units: units,
                    price: price
                };
            }
            return;
        }
    }
}
//-------------------------------------------------------------------------------------------------------------
this.$reverseMOSale = function $reverseMOSale() {
    var mo = worldScripts.market_observer3;
    mo.playerBoughtCargo(this._sale.commodity, this._sale.units, this._sale.price);
    this._sale = {};
}
//-------------------------------------------------------------------------------------------------------------
this.$addPodToShip = function $addPodToShip(details) {
    // create the pod
    var p = player.ship;
    var ep = system.addShips("[" + details.dataKey + "]", 1, p.position.add(p.vectorForward.multiply(1000000)), 1)[0];
    ep.entityPersonality = details.entityPersonality;
    if (details.AI !== "nullAI.plist") ep.setAI(details.AI);
    if (details.AIScript.name !== "Null AI") {
        var aiName = "oolite-shuttleAI.js";
        if (details.AIScript !== "Oolite Shuttle AI") {
            log(this.name, "!!ERROR: Unrecognised escape pod AI type: " + details.AIScript + " - using default");
        }
        ep.setAI(aiName);
    }
    // don't add a pilot if the escape pod is defined with a character - the pod should be recreated with the pilot already defined
    var check = Ship.shipDataForKey(details.dataKey);
    if (!check.pilot || check.pilot === "") {
        // add the pilot
        // set the seed values so that the pilot's species can be defined by their home system
        var seed = "0 0 0 0 " + details.pilotHomeSystem.toString() + " 2";
        ep.setCrew({
            name: details.pilotName,
            origin: details.pilotHomeSystem,
            insurance: details.pilotInsurance,
            bounty: details.pilotLegalStatus,
            short_description: details.pilotDescription,
            random_seed: seed
        });
    }
    // force a scoop event process to add the ship back to the standard array, and to add custom events
    this.shipScoopedOther(ep);
    ep.script._ept_madeOffer = details.madeOffer;
    // add the pod to the player ship
    p.addCargoEntity(ep);
}
//-------------------------------------------------------------------------------------------------------------
this.$waitForFreeTime = function $waitForFreeTime() {
    if (worldScripts.Smugglers_Illegal && worldScripts.Smugglers_Illegal._doCargoCheck === true) {
        // keep running this timer until Smugglers is cleared
        this._addBackTimer = new Timer(this, this.$waitForFreeTime, 0.25, 0);
    } else {
        this.missionScreenOpportunity();
    }
}
//-------------------------------------------------------------------------------------------------------------
this.$updateManifest = function $updateManifest() {
    var textData = [];
    textData.push(expandDescription("[escapepods-manifest-header]"));
    var legal = expandDescription("[ept-legal]").split("|");
    if (player.ship.isInSpace) {
        for (var i = 0; i < this._escapePods.length; i++) {
            if (this._escapePods[i].crew) {
                var pilot = this._escapePods[i].crew[0];
                textData.push(" " + this.$cleanPilotName(pilot.name) + ", " + pilot.description + " (" + (pilot.legalStatus >= 50 ? legal[2] : pilot.legalStatus > 0 ? legal[1] : legal[0]) + ")");
            }
        }
    } else {
        for (var i = 0; i < this._heldPods.length; i++) {
            var pilot = this._heldPods[i];
            textData.push(" " + this.$cleanPilotName(pilot.pilotName) + ", " + pilot.pilotDescription + " (" + (pilot.pilotLegalStatus >= 50 ? legal[2] : pilot.pilotLegalStatus > 0 ? legal[1] : legal[0]) + ")");
        }
    }
    if (textData.length === 1) {
        mission.setInstructions(null, this.name);
    } else {
        mission.setInstructions(textData, this.name);
    }
}
//-------------------------------------------------------------------------------------------------------------
this.$cleanPilotName = function $cleanPilotName(pilotName) {
    pilotName = pilotName.replace(/[!.,?]/g, ""); // remove any punctuation
    return pilotName.replace(/\b\S/g, function(t) { return t.toUpperCase() });
}
this.$findShipdataWithPilots = function() {
    var keys = Ship.keys(); 
    var ignore = ["oolite-pirate", "oolite-hunter", "oolite-miner", "oolite-passenger", "oolite-police", "oolite-slave", "oolite-trader"];
    for (var i = 0; i < keys.length; i++) {
        var sd = Ship.shipDataForKey(keys[i]);
        if (sd && sd.pilot && ignore.indexOf(sd.pilot) == -1) log(this.name, keys[i] + " -- " + sd.pilot);
    }    
} |