Back to Index Page generated: May 8, 2024, 6:16:03 AM

Expansion Escape Pod Tweaks

Content

Warnings

  1. Information URL mismatch between OXP Manifest and Expansion Manager string length at character position 0

Manifest

from Expansion Manager's OXP list from Expansion Manifest
Description Adjusts how escape pods are processed at stations, particularly Rock Hermits. Adjusts how escape pods are processed at stations, particularly Rock Hermits.
Identifier oolite.oxp.phkb.EscapePodTweaks oolite.oxp.phkb.EscapePodTweaks
Title Escape Pod Tweaks Escape Pod Tweaks
Category Mechanics Mechanics
Author phkb phkb
Version 0.8 0.8
Tags
Required Oolite Version
Maximum Oolite Version
Required Expansions
Optional Expansions
Conflict Expansions
Information URL n/a
Download URL https://wiki.alioth.net/img_auth.php/0/02/EscapePodTweaks.oxz n/a
License CC-BY-NC-SA 4.0 CC-BY-NC-SA 4.0
File Size n/a
Upload date 1610873210

Documentation

Also read http://wiki.alioth.net/index.php/Escape%20Pod%20Tweaks

readme.txt

Escape Pod Tweaks
By Nick Rogers

Overview
========
This OXP aims to make the processing of escape pods a little more logical. In the core game, if the player docks at a Rock Hermit while carrying a scooped escape pod, the bounty for this pod will be given to the player immediately, even though the Rock Hermit has no police to escort the felon away. Neither would there be any way to process an insurance claim for a non-bounty escape pod.

What this OXP does is to check the station at which the player is about to dock for the number of docked police, and the allegiance of the station. If there are no police, or the allegiance of the station is not "galcop", then escape pods won't be processed. They will remain as "slaves" on the F8 cargo manifest screen. The player will not be able to sell these slaves, and the player will be notified by a status message if they attempt it.

Also, to maintain some realism, the default number of police docked at all Rock Hermits (standard, "chaotic" and "pirate" Hermitages) has been set to 0. This will also apply to any OXP station that uses "like_ship" to replicate "rock-hermit" (or "oolite_template_rock-hermit"), "rock-hermit-chaotic" (or "oolite_template_rock-hermit-chaotic"), or "rock-hermit-pirate" (or "oolite_template_rock-hermit-pirate"). The number of docked defenders has been increased for each of these station types: 4 for standard hermits, 7 for chaotic, and 10 for pirate.

Some visibility of the occupants of scooped escape pods is now provided on the F5F5 Manifest screen.

License
=======
This work is licensed under the Creative Commons Attribution-Noncommercial-Share Alike 4.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/

Version History
===============
0.8
- Removed debug message.
- Added code to prevent overriding the pilot if the escape pod shipdata entry includes a pilot definition.

0.7
- After launching, held escape pods were not being added back into the active array correctly.

0.6
- shipdata-overrides.plist was overriding the wrong ship keys, meaning rock hermits could still have police.

0.5
- Corrected error that occurs if rescued escape pod has no crew defined (which can happen with mission OXP's).

0.4
- Corrections to manifest.plist file.

0.3
- Better integration with Market Observer.

0.2
- Bug fixes.
- Code refactoring.

0.1
- Initial release.

Equipment

This expansion declares no equipment. This may be related to warnings.

Ships

This expansion declares no ships. This may be related to warnings.

Models

This expansion declares no models. This may be related to warnings.

Scripts

Path
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], false);
        }
    }
    // 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("You cannot sell the escape pods on the market.");
            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]"));
    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 ? "Fugitive" : pilot.legalStatus > 0 ? "Offender" : "Clean") + ")");
            }
        }
    } 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 ? "Fugitive" : pilot.pilotLegalStatus > 0 ? "Offender" : "Clean") + ")");
        }
    }
    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() });
}