Back to Index Page generated: Jul 27, 2025, 4:28:31 AM

Expansion Bulk Cargo Processor

Content

Manifest

from Expansion Manager's OXP list from Expansion Manifest
Description Allows players to dump or destroy all of a particular type of cargo in their hold while in flight. Allows players to dump or destroy all of a particular type of cargo in their hold while in flight.
Identifier oolite.oxp.phkb.BulkCargoProcessor oolite.oxp.phkb.BulkCargoProcessor
Title Bulk Cargo Processor Bulk Cargo Processor
Category Equipment Equipment
Author phkb phkb
Version 1.6 1.6
Tags
Required Oolite Version
Maximum Oolite Version
Required Expansions
Optional Expansions
Conflict Expansions
Information URL https://wiki.alioth.net/index.php/Bulk_Cargo_Processor n/a
Download URL https://wiki.alioth.net/img_auth.php/9/9c/BulkCargoProcessor.oxz n/a
License CC BY-NC-SA 4.0 CC BY-NC-SA 4.0
File Size n/a
Upload date 1753243843

Documentation

Also read http://wiki.alioth.net/index.php/Bulk%20Cargo%20Processor

readme.txt

Bulk Cargo Processing
By phkb

Overview
========
This OXP provides a piece of primable equipment the player can use during flight to automatically dump or destroy all of a particular type of cargo.

Usage
=====
After priming the equipment, pressing the "b" key will cycle through all the possibilties. If you have 10t of food plus 15t of textiles, the options will be 
    "Dump 10t Food"
    "Destroy 10t Food"
    "Dump 15t Textiles"
    "Destroy 15t Textiles"

When the desired option is selected, pressing "n" will prime the processing unit, and a confirmation message will be displayed, based on the option selected (eg "Ready to dump 10t food"). Pressing "n" again will perform the action. An additional confirmation will be displayed when attempting to destroy slaves.

To stop the process before it finishes, press the "n" key again.

Energy is used when destroying cargo. If the energy of your ship drops too low, the destruction process will pause until the available energy has risen to a sufficient level.

The destruction process will generate alloys which will be automatically ejected.

Availability
============
The Bulk Cargo Processor is available from all TL3 systems and above, at a cost of 50cr.

Licence
=======
This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International Public License. To view a copy of this license, visit http://http://creativecommons.org/licenses/by-sa/4.0/ or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.

Version History
===============
1.6
- Moved all text into descriptions.plist for easier localisation.
- Fixed spelling mistake.

1.5
- Made it easier to stop a bulk process, by just pressing the "n" key again.
- Prevented invalid data conditions by preventing the mode from being changed while cargo processing is in progress.

1.4
- Code refactoring.

1.3
- Fixed bug that would cause the destruction process to continue after all the cargo has been destroyed, meaning any additional cargo of that type would also be destroyed.

1.2
- Additional confirmation message before destroying slaves now works as it should.

1.1
- Destroying cargo will now take up some time (rather than being instantaneous). Energy will be used for the destruction process, and alloys will be dumped after each 10t of cargo destroyed.

1.0
- Initial release

Equipment

Name Visible Cost [deci-credits] Tech-Level
Bulk Cargo Processor yes 500 3+
Remove Bulk Cargo Processor no 100 1+

Ships

This expansion declares no ships.

Models

This expansion declares no models.

Scripts

Path
Scripts/bulkcargoprocessor.js
"use strict";
this.name = "BulkCargoProcessor";
this.author = "phkb";
this.copyright = "2017 phkb";
this.description = "Allows quick dumping or destruction of all of a particular cargo type currently in the hold.";
this.licence = "CC BY-NC-SA 4.0";

/*
    todo: consider what happens with scooped escape pods, differentiation to standard slaves cargo
*/

this._currentOption = {};
this._currentIndex = -1;
this._confirm = 0;
this._dumpTimer = null;
this._dumpList = [];
this._destroyTimer = null;
this._destroyList = [];
this._destroyLowEnergyMessage = false;
this._destroyCounter = 0;
this._preferredCargoPods = [];
this._energyReduction = 20;

//-------------------------------------------------------------------------------------------------------------
this.startUpComplete = function () {
    this.$getPreferredCargoPodList();
}

//-------------------------------------------------------------------------------------------------------------
this.mode = function () {
    var bcp = worldScripts.BulkCargoProcessor;
    if ((bcp._dumpTimer && bcp._dumpTimer.isRunning) || bcp._destroyTimer && bcp._destroyTimer.isRunning) {
        player.consoleMessage(expandDescriptions("[bcp_unable_change]"));
        return;
    }
    var list = [];
    var cargo = player.ship.manifest.list;
    for (var i = 0; i < cargo.length; i++) {
        if (cargo[i].quantity > 0) {
            list.push({ text: expandDescriptions("[bcp_dump_item]", { amount: cargo[i].quantity, unit: cargo[i].unit, commodity: displayNameForCommodity(cargo[i].commodity) }), action: "dump", quantity: cargo[i].quantity, commodity: cargo[i].commodity, unit: cargo[i].unit });
            list.push({ text: expandDescriptions("[bcp_destroy_item]", { amount: cargo[i].quantity, unit: cargo[i].unit, commodity: displayNameForCommodity(cargo[i].commodity) }), action: "destroy", quantity: cargo[i].quantity, commodity: cargo[i].commodity, unit: cargo[i].unit });
        }
    }
    bcp._currentIndex += 1;
    if (bcp._currentIndex >= list.length) bcp._currentIndex = 0;
    bcp._currentOption = list[bcp._currentIndex];
    bcp._confirm = 0;
    player.consoleMessage(bcp._currentOption.text);
}

//-------------------------------------------------------------------------------------------------------------
this.activated = function () {
    var bcp = worldScripts.BulkCargoProcessor;
    if (bcp._currentOption.hasOwnProperty("text") === false) {
        player.consoleMessage(expandDescriptions("[bcp_invalid_option]"));
        return;
    }
    bcp._confirm += 1;
    switch (bcp._confirm) {
        case 1:
            player.consoleMessage(expandDescriptions("[bcp_confirm]") + bcp._currentOption.text);
            break;
        case 2:
        case 3: // special confirmation for destroying slaves
            // do it
            bcp.$performAction();
            break;
        case 4:
            player.consoleMessage(expandDescriptions("[bcp_action_terminated]"));
            if (bcp._dumpTimer && bcp._dumpList.isRunning) bcp._dumpTimer.stop();
            if (bcp._destroyTimer && bcp._destroyTimer.isRunning) bcp._destroyTimer.stop();
            bcp._dumpList = [];
            bcp._destroyList = [];
            bcp._confirm = 0;
            bcp._currentIndex = -1;
            bcp._currentOption = {};
            break;
    }
}

//-------------------------------------------------------------------------------------------------------------
this.$performAction = function () {
    if (!this._currentOption) return;
    switch (this._currentOption.action) {
        case "dump":
            player.consoleMessage(expandDescriptions("[bcp_dump_item_action]", { amount: this._currentOption.quantity, unit: this._currentOption.unit, commodity: this._currentOption.commodity }));
            var amt = player.ship.manifest[this._currentOption.commodity];
            if (this._currentOption.unit !== "t") {
                var base = 1000;
                if (this._currentOption.unit === "g") base = 1000000;
                do {
                    var d = base;
                    if (d > amt) d = amt;
                    amt -= d;
                    this._dumpList.push({ commodity: this._currentOption.commodity, quantity: d });
                } while (amt > 0);
            } else {
                for (var i = 1; i <= amt; i++) {
                    this._dumpList.push({ commodity: this._currentOption.commodity, quantity: 1 });
                }
            }
            if (!this._dumpTimer || this._dumpTimer.isRunning === false) {
                this._dumpTimer = new Timer(this, this.$dumpCargo, 0.75, 0.75);
            }
            break;
        case "destroy":
            if (this._currentOption.commodity === "slaves" && this._confirm === 2) {
                player.consoleMessage(expandDescriptions("[bcp_confirm_slaves]"));
                return;
            }
            if (this._currentOption.commodity === "slaves" && this._confirm === 3) {
                // force the confirm counter back one so that it will match a normal destroy sequence 
                this._confirm -= 1;
            }
            player.consoleMessage(expandDescriptions("[bcp_destroy_item_action]", { amount: this._currentOption.quantity, unit: this._currentOption.unit, commodity: this._currentOption.commodity }));
            //player.ship.manifest[this._currentOption.commodity] = 0;
            var amt = player.ship.manifest[this._currentOption.commodity];
            if (this._currentOption.unit !== "t") {
                var base = 1000;
                if (this._currentOption.unit === "g") base = 1000000;
                do {
                    var d = base;
                    if (d > amt) d = amt;
                    amt -= d;
                    this._destroyList.push({ commodity: this._currentOption.commodity, quantity: d });
                } while (amt > 0);
            } else {
                for (var i = 1; i <= amt; i++) {
                    this._destroyList.push({ commodity: this._currentOption.commodity, quantity: 1 });
                }
            }
            if (!this._destroyTimer || this._destroyTimer.isRunning === false) {
                this._destroyTimer = new Timer(this, this.$destroyCargo, 1, 1);
            }
            break;
    }
    //this._currentOption = {};
    //this._currentIndex = -1;
    this._confirm += 1;
}

//-------------------------------------------------------------------------------------------------------------
this.playerBoughtEquipment = function (equipmentKey) {
    if (equipmentKey === "EQ_BULK_CARGO_PROCESSOR_REMOVAL") {
        player.ship.removeEquipment("EQ_BULK_CARGO_PROCESSOR_REMOVAL");
        player.ship.removeEquipment("EQ_BULK_CARGO_PROCESSOR");
    }
}

//-------------------------------------------------------------------------------------------------------------
this.shipDied = function (whom, why) {
    this.$stopTimers();
}

//-------------------------------------------------------------------------------------------------------------
this.shipWillDockWithStation = function (station) {
    this.$stopTimers();
}

//-------------------------------------------------------------------------------------------------------------
this.shipWillEnterWitchspace = function (cause, destination) {
    this.$stopTimers();
}

//-------------------------------------------------------------------------------------------------------------
this.$stopTimers = function () {
    if (this._dumpTimer && this._dumpTimer.isRunning) this._dumpTimer.stop();
    this._dumpList = [];
    if (this._destroyTimer && this._destroyTimer.isRunning) this._destroyTimer.stop();
    this._destroyList = [];
}

//-------------------------------------------------------------------------------------------------------------
this.$dumpCargo = function $dumpCargo() {
    if (this._dumpList.length === 0) {
        this._currentOption = {};
        this._currentIndex = -1;
        this._confirm = 0;
        this._dumpTimer.stop();
        return;
    }
    var c = this._dumpList[0];
    if (player.ship.manifest[c.commodity] > 0) {
        if (c.quantity > 0) {
            // this is a "g" or "kg" item - we can have more than 1 unit in the pod
            var pd = this._preferredCargoPods[Math.floor(Math.random() * this._preferredCargoPods.length)];
            var cg = player.ship.ejectItem("[" + pd + "]");
            cg.setCargo(c.commodity, c.quantity);
            player.ship.manifest[c.commodity] -= c.quantity;
        } else {
            // otherwise, it's a straight dump of 1t
            player.ship.dumpCargo(1, c.commodity);
        }
    }
    this._dumpList.splice(0, 1);
}

//--------------------------------------------------------------------------------------------------------------
this.$destroyCargo = function $destroyCargo() {
    if (this._destroyList.length === 0) {
        this._currentOption = {};
        this._currentIndex = -1;
        this._confirm = 0;
        this._destroyTimer.stop();
        return;
    }
    if (player.ship.energy < 64) {
        if (this._destroyLowEnergyMessage === false) {
            player.consoleMessage(expandDescriptions("[bcp_destruction_hold]"));
        }
        this._destroyLowEnergyMessage = true;
        return;
    }
    this._destroyLowEnergyMessage = false;
    var c = this._destroyList[0];
    if (player.ship.manifest[c.commodity] >= c.quantity) {
        // this is a "g" or "kg" item - we can have more than 1 unit in the pod
        player.ship.manifest[c.commodity] -= c.quantity;
        player.ship.energy -= this._energyReduction;
        this._destroyCounter += 1;
        // eject alloys
        if (this._destroyCounter >= 10) {
            var pd = this._preferredCargoPods[Math.floor(Math.random() * this._preferredCargoPods.length)];
            var cg = player.ship.ejectItem("[" + pd + "]");
            cg.setCargo("alloys", 1);
            this._destroyCounter = 0;
        }
    }
    this._destroyList.splice(0, 1);
}

//--------------------------------------------------------------------------------------------------------------
// populates the list of possible cargopods that can be spawned and aren't related to a scripted item
this.$getPreferredCargoPodList = function () {
    this._preferredCargoPods = [];
    var shipkeys = Ship.keysForRole("cargopod");
    for (var i = 0; i < shipkeys.length; i++) {
        var shipspec = Ship.shipDataForKey(shipkeys[i]);
        if (shipspec.cargo_type != "CARGO_SCRIPTED_ITEM") this._preferredCargoPods.push(shipkeys[i]);
    }
}