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

Expansion Life In The Frontier - Revival

Content

Manifest

from Expansion Manager's OXP list from Expansion Manifest
Description (Phase 1) Creates a system BBS where the player can read and accept missions. Generates missions depending on system governments. Reward the player with credits and feedback, that in turn generates longer missions with better rewards. (Phase 1) Creates a system BBS where the player can read and accept missions. Generates missions depending on system governments. Reward the player with credits and feedback, that in turn generates longer missions with better rewards.
Identifier oolite.oxp.BeeTLeBeTHLeHeM.Life-In-The-Frontier-Revival oolite.oxp.BeeTLeBeTHLeHeM.Life-In-The-Frontier-Revival
Title Life In The Frontier - Revival Life In The Frontier - Revival
Category Activities Activities
Author BeeTLe BeTHLeHeM BeeTLe BeTHLeHeM
Version 0.10.0 0.10.0
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/5/5a/Oolite.oxp.BeeTLeBeTHLeHeM.Life-In-The-Frontier-Revival.oxz n/a
License CC BY-NC-SA 4 CC BY-NC-SA 4
File Size n/a
Upload date 1610873303

Documentation

Also read http://wiki.alioth.net/index.php/Life%20In%20The%20Frontier%20-%20Revival

LITF_readme.txt

LIFE IN THE FRONTIER - REVIVAL
------------------------------

Equipment

This expansion declares no equipment.

Ships

This expansion declares no ships.

Models

This expansion declares no models.

Scripts

Path
Scripts/LITF.js
/* eslint-disable semi, no-multi-spaces, quotes, indent, no-tabs, yoda */
/* global worldScripts, system, missionVariables, player, mission, clock, randomName */

"use strict";

this.name	     = "LITF";
this.author	     = "BeeTLe BeTHLeHeM";
this.copyright	 = "2018 BeeTLe BeTHLeHeM";
this.description = "Main OSP file";
this.version	 = "0.10.0";
this.licence	 = "CC BY-NC-SA 4.0";

var _co  = null;
var _mi  = null;
var _bbs = null;
var _nav = null;

this.startUp = function () {
    _co = worldScripts.LITF_Common;
    _co.$init();

    _mi = worldScripts.LITF_Missions;
    _mi.$init();

    _bbs = worldScripts.LITF_BBS;

    _nav = worldScripts.LITF_Station_ALPHA;

    _co.$log("[LITF] startup - [LIFE IN THE FRONTIER v" + this.version + "]");

    this.$initOXPVariables();

    this.$checkOtherOXP();

    // Starting up
    if (this.litfVars.starting === true) {
        _co.$log("creating initial BBS items");
        _bbs.$createBBSItems();
        this.litfVars.starting = false;
    }

    this.$LITFinterface();
}

this.playerWillSaveGame = function () {
    _co.$log("[LITF] playerWillSaveGame");

    // Store variables in savegame
    missionVariables.litfCommander = JSON.stringify(this.litfCommander);
    missionVariables.litfVars = JSON.stringify(this.litfVars);
}

this.shipWillDockWithStation = function (station) {
    _co.$log("[LITF] shipWillDockWithStation");

    // Player is going to dock with a station
}

this.shipDockedWithStation = function () {
    _co.$log("[LITF] shipDockedWithStation");

    // Player has just docked with a station

    // Store system data for BBS generation - only if player has changed system
    if (this.litfVars.stationParams.id !== system.ID) {
        var stationParams = {
            systemId: system.ID,
            government: _co.$systemGovernment(),
            economy: _co.$systemEconomy(),
            techLevel: _co.$systemTechLevel()
        };

        this.litfVars.stationParams = stationParams;
    }

    this.$checkExpiredMissions();

    if (this.litfVars.config.debug === true) {
        this.$checkMissingPerson();
    }

    // BBS item generation
    if (this.litfVars.refreshBBS === true) {
        _bbs.$createBBSItems();
        this.litfVars.refreshBBS = false;
        this.litfVars.bbsItems = this.litfVars.bbsData.bbsItemsArr;
    } else {
        this.litfVars.bbsData.bbsItemsArr = this.litfVars.bbsItems;
    }

    this.$LITFinterface();
}

this.shipExitedWitchspace = function () {
    _co.$log("[LITF] shipExitedWitchspace");

    // Player has just exited a witchspace jump

    // New messages when changing system
    this.litfVars.refreshBBS = true;
    this.litfVars.bbsItems = null;

    // Console message if there is a mission to complete in the present system.
    if (this.litfCommander.activeMissions.length > 0) {
        var missionsHere = 0;

        for (var m = 0; m < this.litfCommander.activeMissions.length; m++) {
            var mObj = this.litfCommander.activeMissions[m];

            var mSystems = _bbs.$getMissionTask(mObj, mObj.currentTask).info.systems;
            _co.$log("system.ID = " + system.ID + " mSystems = " + JSON.stringify(mSystems));

            for (var s = 0; s < mSystems.length; s++) {
                if (mSystems[s].id === system.ID) {
                    missionsHere = missionsHere + 1;
                }
            }
        }

        _co.$log(missionsHere + " tasks can be completed in this system.");

        if (missionsHere > 0) {
            var pl = missionsHere > 1 ? "s" : "";
            player.commsMessage("You have " + missionsHere + " active BBS mission" + pl + " in this system.");
        }
    }
}

this.playerEnteredNewGalaxy = function (galaxyNumber) {
    _co.$log("[LITF] playerEnteredNewGalaxy");

    // Player changed galaxy

    // Re-Initializing

    this.litfCommander = {
        feedback: 0,
        activeMissions: [],
        busyCargo: false,
        busyPassenger: false,
        busyParcel: false,
        statistics: {
            missionAccepted: [],
            missionCompleted: [],
            missionFailed: [],
            feedbackGained: [],
            feedbackLost: []
            // creditsGained: []
        }
    };

    for (var g = 0; g < _co.groupsLabels.length; g++) {
        this.litfCommander.statistics.missionAccepted.push(0);
        this.litfCommander.statistics.missionCompleted.push(0);
        this.litfCommander.statistics.missionFailed.push(0);
        this.litfCommander.statistics.feedbackGained.push(0);
        this.litfCommander.statistics.feedbackLost.push(0);
        // this.litfCommander.statistics.creditsGained.push(0);
    }
}

// Add OXP interfaces to station screen (F4)
this.$LITFinterface = function () {
    _co.$log("[LITF] LITFinterface");

	player.ship.dockedStation.setInterface("LITF_bbs",
		{
			title: "Login to BBS",
			category: "Activity",
			summary: "Connect to local Bulletin Board System",
			callback: this.$accessBBS.bind(this)
		}
    );

	player.ship.dockedStation.setInterface("LITF_profile",
		{
			title: "Your online status",
			category: "Activity",
			summary: "Check your online feedback and accepted missions.",
			callback: this.$displayOnlineStatus.bind(this)
		}
	);

    if (this.litfVars.config.debug === true) {
        player.ship.dockedStation.setInterface("LITF_navigation",
            {
                title: "Disembark from your ship",
                category: "Activity",
                summary: "Go roaming through the station.",
                callback: this.$navigateStation.bind(this)
            }
        );
    }
}

this.$navigateStation = function () {
    _co.$log("[LITF] navigateStation");

    _nav.$init();
    _nav.$start();
}

// Open the BBS message list screen
this.$accessBBS = function () {
    _co.$log("[LITF] accessBBS");

    this.$checkExpiredMissions();

    var _bbs = worldScripts.LITF_BBS;

    this.litfVars.enterBBSFlag = true;

    _bbs.$run();
}

// Open the Online Profile screen
this.$displayOnlineStatus = function () {
    _co.$log("[LITF] displayOnlineStatus");

    var displayText = null;
    var opts = null;
    var choices = null;

    if (this.litfVars.statusPage === 0) {
        this.$checkExpiredMissions();

        displayText = "NAME: " + player.name;
        displayText += "                                        ";
        displayText += "FEEDBACK: " + _co.$getFeedbackRanking(this.litfCommander.feedback) + " (" + this.litfCommander.feedback + ")";
        displayText += "\n\n";

        var maxActiveMissions = parseInt(Math.abs(this.litfCommander.feedback) / 25) + 1;

        displayText += "-- ACTIVE MISSIONS (" + this.litfCommander.activeMissions.length + " / " + maxActiveMissions + ") --";
        displayText += "\n\n";

        if (this.litfCommander.activeMissions.length === 0) {
            displayText += ">> No active missions at the moment <<";
        } else {
            for (var m = 0; m < this.litfCommander.activeMissions.length; m++) {
                var mObj = this.litfCommander.activeMissions[m];

                var deadline = parseInt(mObj.startTime) + parseInt(mObj.timeAllowed);
                var timeText = _co.$formatTime(deadline, true);

                var missionText = "> ";

                if (this.litfVars.config.debug === true) {
                    missionText += "(" + mObj.groupId + "." + mObj.tasks[0].typeId + "." + mObj.index + ") ";
                }

                missionText += _bbs.$getMissionTask(mObj, mObj.currentTask).description;
                missionText += " Mission expires in " + timeText + ".";

                if (mObj.reward > 0) {
                    missionText += " Payment: " + mObj.reward + " credits.";
                }

                displayText += missionText + "\n\n";
            }
        }

        choices = {
            "QUIT": "Exit the profile page."
        };

        if (this.litfVars.config.debug === true) {
            choices["NEXTPAGE"] = "Go to the Statistics screen.";
        }

        opts = {
            title: "Online Profile Data",
            exitScreen: "GUI_SCREEN_INTERFACES",
            message: displayText,
            choices: choices
        };
    } else if (this.litfVars.statusPage === 1) {
        displayText = "";

        for (var g = 0; g < _co.groupsLabels.length; g++) {
            displayText += _co.groupsLabels[g] + ": ";

            displayText += "Accepted: " + this.litfCommander.statistics.missionAccepted[g] + ", ";
            displayText += "Completed: " + this.litfCommander.statistics.missionCompleted[g] + ", ";
            displayText += "Failed: " + this.litfCommander.statistics.missionFailed[g] + ", ";

            displayText += " Feedback: ";
            if (this.litfCommander.statistics.feedbackGained[g] > 0) {
                displayText += "+" + this.litfCommander.statistics.feedbackGained[g];
            } else {
                displayText += this.litfCommander.statistics.feedbackGained[g];
            }

            displayText += " / ";
            if (this.litfCommander.statistics.feedbackLost[g] > 0) {
                displayText += "-" + this.litfCommander.statistics.feedbackLost[g];
            } else {
                displayText += this.litfCommander.statistics.feedbackLost[g];
            }

            displayText += "\n";
        }

        choices = {
            "NEXTPAGE": "Go to the Profile screen.",
            "QUIT": "Exit the profile page."
        };

        opts = {
            title: "Online Statistics",
            exitScreen: "GUI_SCREEN_INTERFACES",
            message: displayText,
            choices: choices
        };
    }

    mission.runScreen(opts, this.$executeStatusAction);
}

this.$executeStatusAction = function (choice) {
    if (choice === "QUIT") {
        this.litfVars.statusPage = 0;
        this.$LITFinterface();
    } else if (choice === "NEXTPAGE") {
        this.litfVars.statusPage = this.litfVars.statusPage + 1;
        if (this.litfVars.statusPage > 1) { this.litfVars.statusPage = 0; }
        this.$displayOnlineStatus();
    }
}

// Check expired missions and delete them
this.$checkExpiredMissions = function () {
    var failed = [];

    if (this.litfCommander.activeMissions) {
        for (var am = 0; am < this.litfCommander.activeMissions.length; am++) {
            var amItem = this.litfCommander.activeMissions[am];

            var deadline = parseInt(amItem.startTime) + parseInt(amItem.timeAllowed) - clock.seconds;

            if (deadline < 0) { failed.push(amItem.missionId); }
        }

        _co.$log("failed = " + JSON.stringify(failed));

        if (failed.length > 0) {
            var pl = null;

            pl = failed.length > 1 ? "s" : "";
            player.commsMessage("Time expired: " + failed.length + " mission" + pl + " failed.");
            _co.$log("Time expired: " + failed.length + " mission" + pl + " failed.");

            // var removedPassengers = 0;
            // var deadPassengers = 0;

            // Delete failed missions from active missions list
            for (var fm = 0; fm < failed.length; fm++) {
                var ret = _bbs.$deleteActiveMission(failed[fm]);

                // removedPassengers = removedPassengers + ret.removedPassengers;
                // deadPassengers = deadPassengers + ret.deadPassengers;

                if (ret.cargo !== null) {
                    player.ship.removeAllCargo();
                    player.commsMessage("A shipment of " + ret.cargo + " has been removed from your ship.");
                }

                if (ret.parcel !== null) {
                    player.ship.removeParcel(ret.parcel);
                    var parcelDesc = ret.parcel.substring(ret.parcel.indexOf(" ") + 1);
                    player.commsMessage(parcelDesc + " has been removed from your ship.");
                }

                _co.$updateStatistics("missionFailed", ret.groupId, 1);

                // Get feedback penalty
                if (ret.groupId !== 3) {
                    _co.$setPlayerFeedback(-ret.feedback.lost);
                }
                _co.$updateStatistics("feedbackLost", ret.groupId, ret.feedback.lost);

                if (ret.removedPassengers > 0) {
                    pl = ret.removedPassengers > 1 ? "s" : "";
                    player.commsMessage("" + ret.removedPassengers + " passenger" + pl + " have left your ship!");

                    // Get feedback penalty (1 point per passenger)
                    if (ret.groupId !== 3) {
                        _co.$setPlayerFeedback(-ret.removedPassengers);
                    }
                    _co.$updateStatistics("feedbackLost", ret.groupId, ret.removedPassengers);
                }

                if (ret.deadPassengers > 0) {
                    pl = ret.deadPassengers > 1 ? "s" : "";
                    player.commsMessage("" + ret.deadPassengers + " dead passenger" + pl + " has been removed from your ship!");

                    // Get feedback penalty (3 point per passenger)
                    if (ret.groupId !== 3) {
                        _co.$setPlayerFeedback(-ret.deadPassengers * 3);
                    }
                    _co.$updateStatistics("feedbackLost", ret.groupId, ret.deadPassengers * 3);
                }
            }
        }
    }
}

this.$initOXPVariables = function () {
    // OXP player commander data

    if (missionVariables.litfCommander) {
        // Loading from savegame
        _co.$log("Loading litfCommander object");
        this.litfCommander = JSON.parse(missionVariables.litfCommander);
    } else {
        // Initializing
        this.litfCommander = {
            feedback: 0,
            activeMissions: [],
            busyCargo: false,
            busyPassenger: false,
            busyParcel: false,
            statistics: {
                missionAccepted: [],
                missionCompleted: [],
                missionFailed: [],
                feedbackGained: [],
                feedbackLost: []
                // creditsGained: []
            }
        };

        for (var g = 0; g < _co.groupsLabels.length; g++) {
            this.litfCommander.statistics.missionAccepted.push(0);
            this.litfCommander.statistics.missionCompleted.push(0);
            this.litfCommander.statistics.missionFailed.push(0);
            this.litfCommander.statistics.feedbackGained.push(0);
            this.litfCommander.statistics.feedbackLost.push(0);
            // this.litfCommander.statistics.creditsGained.push(0);
        }
    }

    // OXP variables and flags

    if (missionVariables.litfVars) {
        // Loading from savegame
        _co.$log("Loading litfVars object");
        this.litfVars = JSON.parse(missionVariables.litfVars);
    } else {
        this.litfVars = {
            starting: true,
            config: {
                enableLog: false,
                debug: false,
                disableMissionBackground: true
            },
            stationParams: {
                systemId: system.ID,
                government: _co.$systemGovernment(),
                economy: _co.$systemEconomy(),
                techLevel: _co.$systemTechLevel()
            },
            refreshBBS: true,
            bbsItems: null,
            enterBBSFlag: false,
            generalId: 1,
            bbsData: {
                bbsItemsArr: [],
                checkDuplicatesArr: [],
                selectedItem: 0,
                lastChoice: "02_NEXT_ITEM",
                firstItemIdx: 0,
                totalItems: 0,
                rowsSize: 14,
                bbsMode: 0, // 0 - item list, 1 - item details
                selectedItemObj: null
            },
            statusPage: 0,
            oxp: {}
        };
    }

    this.litfVars.config.debug = false;
    this.litfVars.config.enableLog = false;
}

this.$checkMissingPerson = function () {
    _co.$log("[LITF] checkMissingPerson");

    if (!this.litfVars.missingPerson || this.litfVars.missingPerson === null) {
        var mPerson = {};

        mPerson.name = randomName() + " " + randomName();
        mPerson.currentPos = 0;
        mPerson.active = false;

        mPerson.posArr = this.$defineMissingPersonTravel();
        mPerson.nextMove = clock.seconds + (_co.$roll(4, 16) * 3600);

        _co.$log("missingPerson = " + JSON.stringify(mPerson));

        this.litfVars.missingPerson = mPerson;
    }
}

this.$defineMissingPersonTravel = function () {
    _co.$log("[LITF] defineMissingPersonTravel");

    var posArr = [];
    var jumps = 0;

    var firstSystem = _co.$randomSystem(-1);
    posArr.push(firstSystem.id);

    var enough = false;
    while (enough === false) {
        var startSystem = posArr[posArr.length - 1];
        var endSystem = null;

        var valid = false;
        while (valid === false) {
            valid = true;
            endSystem = _co.$randomSystem(-1);
            for (var s = 0; s < posArr.length; s++) {
                if (posArr[s].id === endSystem.id) {
                    valid = false;
                }
            }
        }

        _co.$log("startSystem[" + startSystem + "] endSystem[" + endSystem + "]");

        var systemRoute = _co.$getSystemRoute(startSystem, endSystem.id);
        jumps += systemRoute.route.length;

        _co.$log("jumps = " + jumps);

        for (var sr = 1; sr < systemRoute.route.length; sr++) {
            posArr.push(systemRoute.route[sr]);
        }

        if (jumps >= 10) {
            enough = true;
        }
    }

    return posArr;
}

this.$checkOtherOXP = function () {
    // Check OXPs main files (look into the OXZs) and set associate flags

    // Examples:
    // this.litfVars.oxp.fuelStation = worldScripts["FuelStation-Setup"] ? 1 : 0;
    // this.litfVars.oxp.hoopyCasino = worldScripts["hoopy_casino"] ? 1 : 0;

    // _co.$log("[LITF] checkOtherOXP = " + JSON.stringify(this.litfVars.oxp));
}
Scripts/LITF_BBS.js
/* eslint-disable semi, no-multi-spaces, quotes, indent, no-tabs, yoda */
/* global worldScripts, system, mission, player, clock, randomName, setScreenBackground  */

"use strict";

this.name        = "LITF_BBS";
this.author      = "BeeTLe BeTHLeHeM";
this.copyright   = "2018 BeeTLe BeTHLeHeM";
this.description = "Code for BBS management - message list, mission creation, mission details";
this.version     = "0.10.0";
this.licence     = "CC BY-NC-SA 4.0";

// Feedback requirements defaults

// Currently not used
this.minFeedbackDefault = -10; // Default minimum feedback required for missions (except GalShady ones)
this.maxFeedbackDefault = 24; // Default maximum feedback required for missions (only GalShady ones)

this.halfAdvanceMinFeedbackDefault = 10; // Default minimum feedback required for obtaining half advance reward
this.fullAdvanceMinFeedbackDefault = 50; // Default minimum feedback required for obtaining full advance reward
this.moreMoneyMinFeedbackDefault   = 25; // Default minimum feedback required for obtaining more reward (10-25% more)

this.bbsData = null;

var _litf    = null;
var _co      = null;
var _md      = null;
var _mi      = null;

// Local var reference for callback methods

var $display = this.$display;
var $executeCharityActions = this.$executeCharityActions;
var $executeMissionActions = this.$executeMissionActions;
var $executePlayerWaitingActions = this.$executePlayerWaitingActions;

this.$run = function () {
    _co.$log("[LITF_BBS] run");

    _litf = worldScripts.LITF;

    this.bbsData = _litf.litfVars.bbsData;

    _co   = worldScripts.LITF_Common;
    _md   = worldScripts.LITF_MissionData;
    _mi   = worldScripts.LITF_Missions;

    // Load the BBS list
    this.$init();

    // Display the BBS page
    this.$display();
}

this.$init = function () {
    _co.$log("[LITF_BBS] init");

    // What to do with this?
    if (_litf.litfVars.enterBBSFlag === true) {
        _litf.litfVars.enterBBSFlag = false;
    }
}

this.$createBBSItems = function () {
    _co.$log("[LITF_BBS] createBBSItems");

    var bbsData = _litf.litfVars.bbsData;

    bbsData.bbsItemsArr = [];
    bbsData.checkDuplicatesArr = [];

    // From the system government we get the active groups
    var stationData = _litf.litfVars.stationParams;
    var activeGroups = _mi.groupsByGov[stationData.government];

    // Cycle the active groups and eventually set some mission each group
    var totGroupMissions = 5 + _co.$roll(0, activeGroups.length / 2);
    for (var g = 0; g < totGroupMissions; g++) {
        var mObj = _mi.$generateMission(activeGroups);
        if (mObj != null) {
            mObj.missionId = _co.$getGeneralId();
            bbsData.bbsItemsArr.push(mObj);
        }
    }

    // Waiting mission generation (dummy)
    var totWaitingMissions = _co.$roll(1, 4);
    for (var w = 0; w < totWaitingMissions; w++) {
        var wObj = _mi.$generateRandomItem(_md.waitingStore);
        wObj.missionId = _co.$getGeneralId();
        bbsData.bbsItemsArr.push(wObj);
    }

    // Government specific messages
    var totGovItems = _co.$roll(3, 6);
    for (var go = 0; go < totGovItems; go++) {
        var gObj = _mi.$generateGovernmentItem();
        gObj.missionId = _co.$getGeneralId();
        bbsData.bbsItemsArr.push(gObj);
    }

    // Advertising messages generation
    var totAdItems = activeGroups.length + _co.$roll(0, 4);
    for (var a = 0; a < totAdItems; a++) {
        var aObj = _mi.$generateRandomItem(_md.adStore);
        aObj.missionId = _co.$getGeneralId();
        bbsData.bbsItemsArr.push(aObj);
    }

    // Charity request messages generation
    var totCharityItems = _co.$roll(1, 1);
    for (var c = 0; c < totCharityItems; c++) {
        var cObj = _mi.$generateRandomItem(_md.charityStore);
        cObj.missionId = _co.$getGeneralId();
        bbsData.bbsItemsArr.push(cObj);
    }

    // Debug //
    if (_litf.litfVars.config.debubg === true) {
        _co.$log("generate debug items");
        var dObj = null;
        for (var d = 0; d < 2; d++) {
            // dObj = _mi.$generateMission(["debug"], 1);
            // bbsData.bbsItemsArr.push(dObj);

            // dObj = _mi.$generateMission(["debug"], 2);
            // bbsData.bbsItemsArr.push(dObj);

            // dObj = _mi.$generateMission(["debug"], 3);
            // bbsData.bbsItemsArr.push(dObj);

            dObj = _mi.$generateMission(["debug"], 4);
            if (dObj !== null) {
                bbsData.bbsItemsArr.push(dObj);
            }
        }
    }
    // Debug //

    _co.$log("generate player waiting items")

    // Check if there's a mission to complete in this system - create BBS message accordingly.
    var activeMissions = _litf.litfCommander.activeMissions;
    _co.$log("activeMissions length = " + activeMissions.length);

    if (activeMissions.length > 0) {
        for (var am = 0; am < activeMissions.length; am++) {
            var amItem = activeMissions[am];

            if (this.$checkActiveMissionHere(amItem) === true) {
                var pwObj = _mi.$generatePlayerWaitingMission(amItem);

                bbsData.bbsItemsArr.push(pwObj);
                _co.$log("pwObj = " + JSON.stringify(pwObj));
            }
        }
    }

    _co.$log("shuffleArray");

    // Shuffle the list
    bbsData.bbsItemsArr = _co.$shuffleArray(bbsData.bbsItemsArr);
}

this.$checkActiveMissionHere = function (amItem) {
    _co.$log("[LITF_BBS] checkActiveMissionHere");
    _co.$log("amItem = " + JSON.stringify(amItem));

    var cTask = this.$getMissionTask(amItem, amItem.currentTask);
    _co.$log("cTask = " + JSON.stringify(cTask));

    var systems = cTask.info.systems;
    var amHere = false;

    for (var sy = 0; sy < systems.length; sy++) {
        if (this.$isSystems(systems) === true) {
            amHere = true;
            break;
        }
    }

    return amHere;
}

// Check if the player is in one of the systems of the input array
this.$isSystems = function (systemArr) {
    _co.$log("[LITF_BBS] isSystem");

    var isSystems = false;

    for (var s = 0; s < systemArr.length; s++) {
        // System exists and its not already "completed" (visit + talk)

        _co.$log("system.ID = " + system.ID + " systemArr[" + s + "] = " + JSON.stringify(systemArr[s]));

        if (!systemArr[s].hidden || systemArr[s].hidden === false) {
            if (systemArr[s].id === system.ID) {
                isSystems = true;
            }
        }
    }

    return isSystems;
}

this.$display = function () {
    var bbsData = _litf.litfVars.bbsData;

    _co.$log("[LITF_BBS] display");
    _co.$log("bbsMode = " + bbsData.bbsMode);

    var displayText = "";
    var opts = null;
    var curChoices = null;

    if (bbsData.bbsMode === 0) {
        // BBS message list
        displayText = "(" + (bbsData.selectedItem + 1) + " / " + bbsData.bbsItemsArr.length + ")\n\n";

        this.$setPageListEdges();

        var lastItemIdx = bbsData.firstItemIdx + bbsData.rowsSize;
        if (lastItemIdx > bbsData.bbsItemsArr.length) {
            lastItemIdx = bbsData.bbsItemsArr.length;
        }

        for (var r = bbsData.firstItemIdx; r < lastItemIdx; r++) {
            var iObj = bbsData.bbsItemsArr[r];

            if (r === bbsData.selectedItem) {
                displayText += "> ";
            } else {
                displayText += "    ";
            }

            var iTitle = iObj.title;
            if (iTitle.length > 70) {
                iTitle = iTitle.substring(0, 70) + "...";
            }

            displayText += iTitle + "\n";
        }

        curChoices = this.$definePageListChoices();

        opts = {
            title: system.name + " Bulletin Board",
            exitScreen: "GUI_SCREEN_INTERFACES",
            message: displayText,
            choices: curChoices,
            initialChoicesKey: bbsData.lastChoice
        };

        mission.runScreen(opts, this.$updateMissionList);
    } else if (bbsData.bbsMode === 1) {
        // BBS item details
        var selItemObj = bbsData.selectedItemObj;

        displayText += "// " + selItemObj.title + "\n\n";

        _co.$log("mission details: " + JSON.stringify(selItemObj));

        if (selItemObj.groupId === 97) {
            // Player waiting message item

            var stepObj = this.$getCurrentStep(selItemObj);
            displayText += stepObj.description + "\n";

            curChoices = stepObj.choice;
        } else {
            displayText += selItemObj.description + "\n";

            if (selItemObj.showCredits === true) {
                displayText += "\nYOUR CREDITS: " + player.credits;
            } else if (selItemObj.choices !== "hangup") {
                var etaTime = _co.$formatTime(selItemObj.timeAllowed, false);
                displayText += "\nDEADLINE: " + etaTime + ".";
            }

            if (selItemObj.choices !== "hangup") {
                for (var t = 0; t < selItemObj.tasks.length; t++) {
                    var task = selItemObj.tasks[t];
                    if (!task.hideSystemData) {
                        for (var s = 0; s < task.info.systems.length; s++) {
                            var sItem = task.info.systems[s];
                            if (sItem.distance > 0) {
                                displayText += "\nSYSTEM DATA: " + sItem.name + " (distance: " + sItem.distance + " ly)";
                            }
                        }
                    }
                }

                _co.$log("response = " + selItemObj.response);
                if (selItemObj.response && selItemObj.response !== null) {
                    displayText += "\n\n> " + selItemObj.response;
                }
            }

            curChoices = this.$getChoices(selItemObj.choices);
        }

        opts = {
            title: system.name + " Bulletin Board",
            exitScreen: "GUI_SCREEN_INTERFACES",
            message: displayText,
            choices: curChoices
        };

        mission.runScreen(opts, this.$updateMissionDetails);

        // Frontier: Elite face backgrounds - disabled because I am afraid are copyrighted.
        if (_litf.litfVars.config.disableMissionBackground && _litf.litfVars.config.disableMissionBackground === false) {
            if (selItemObj.faceBackground) {
                setScreenBackground(selItemObj.faceBackground);
            }
        }
    }
}

this.$getCurrentStep = function (pwObj) {
    _co.$log("[LITF_BBS] getCurrentStep");

    var steps = pwObj.steps;
    var currentStep = pwObj.currentStep;
    var sObj = {};

    for (var s = 0; s < steps.length; s++) {
        var sItem = steps[s];
        if (sItem.index === currentStep) {
            sObj = sItem;
            break;
        }
    }

    _co.$log("step[" + currentStep + "] = " + JSON.stringify(sObj));

    return sObj;
}

this.$getChoices = function (cLabel) {
    var choices = null;

    if (cLabel === "mission") {
        choices = _md.missionChoices;
    } else if (cLabel === "transport") {
        choices = _md.transportChoices;
    } else if (cLabel === "cargo") {
        choices = _md.cargoChoices;
    } else if (cLabel === "hangup") {
        choices = _md.hangupChoices;
    } else if (cLabel === "charity") {
        choices = _md.charityChoices;
    } else {
        choices = _md.hangupChoices;
    }

    return choices;
}

this.$setPageListEdges = function () {
    var bbsData = _litf.litfVars.bbsData;

    if (bbsData.selectedItem < bbsData.firstItemIdx) {
        bbsData.firstItemIdx = bbsData.selectedItem;
    }

    if (bbsData.selectedItem > (bbsData.firstItemIdx + bbsData.rowsSize - 1)) {
        bbsData.firstItemIdx = (bbsData.selectedItem - bbsData.rowsSize + 1);
    }
}

this.$updateMissionDetails = function (choice) {
    _co.$log("[LITF_BBS] updateMissionDetails");

    var bbsData = _litf.litfVars.bbsData;

    var cLabel = bbsData.selectedItemObj.choices;

    _co.$log("choice = " + choice);

    if (!choice) {
        _co.$log("NULL choice? What's happened there?");
        return;
    } else if (choice.indexOf("_QUIT") > -1) {
        bbsData.bbsMode = 0;
        $display();
    } else if (cLabel === "mission") {
        $executeMissionActions(choice);
        $display();
    } else if (cLabel === "transport") {
        $executeMissionActions(choice);
        $display();
    } else if (cLabel === "cargo") {
        $executeMissionActions(choice);
        $display();
    } else if (cLabel === "charity") {
        $executeCharityActions(choice);
        $display();
    } else if (cLabel === "waiting") {
        $executePlayerWaitingActions(choice);
        $display();
    }
}

this.$updateMissionList = function (choice) {
    var bbsData = _litf.litfVars.bbsData;

    if (!choice) {
        _co.$log("NULL choice? What's happened there?");
        return;
    } else if (choice === "99_DISCONNECT") {
        bbsData.firstItemIdx = 0;
        bbsData.selectedItem = 0;
        _litf.$LITFinterface();
    } else {
        if (choice === "01_PREV_ITEM") {
            if (bbsData.selectedItem > 0) {
                bbsData.selectedItem = bbsData.selectedItem - 1;
            }
        } else if (choice === "02_NEXT_ITEM") {
            if (bbsData.selectedItem < bbsData.bbsItemsArr.length - 1) {
                bbsData.selectedItem = bbsData.selectedItem + 1;
            }
        } else if (choice === "03_SELECT_ITEM") {
            // Open the details screen

            bbsData.selectedItemObj = bbsData.bbsItemsArr[bbsData.selectedItem];
            bbsData.selectedItemObj.response = null;

            bbsData.bbsMode = 1;
        }

        bbsData.lastChoice = choice;

        $display();
    }
}

this.$definePageListChoices = function () {
    _co.$log("[LITF_BBS] definePageListChoices");

    var bbsData = _litf.litfVars.bbsData;

    var choices = {};

    if (bbsData.selectedItem > 0) {
        choices["01_PREV_ITEM"] = { text: "Select previous item", color: "yellowColor" };
    } else {
        choices["01_PREV_ITEM"] = { text: "Select previous item", color: "darkGrayColor", unselectable: true };
    }

    if (bbsData.selectedItem < bbsData.bbsItemsArr.length - 1) {
        choices["02_NEXT_ITEM"] = { text: "Select next item", color: "yellowColor" };
    } else {
        choices["02_NEXT_ITEM"] = { text: "Select next item", color: "darkGrayColor", unselectable: true };
    }

    // Check mission object to see if it allows for a detail screen

    var sObj = bbsData.bbsItemsArr[bbsData.selectedItem];
    _co.$log("selectedItem = " + bbsData.selectedItem + " sObj = " + JSON.stringify(sObj));

    if (sObj.choices) {
        choices["03_SELECT_ITEM"] = { text: "Contact Sender", color: "yellowColor" };
    } else {
        choices["03_SELECT_ITEM"] = { text: "Contact Sender", color: "darkGrayColor", unselectable: true };
    }

    choices["99_DISCONNECT"] = { text: "Disconnect from BBS", color: "yellowColor" };

    return choices;
}

this.$getParentMissionObject = function (pwObj) {
    var pmObj = null;

    for (var am = 0; am < _litf.litfCommander.activeMissions.length; am++) {
        var amItem = _litf.litfCommander.activeMissions[am];

        if (amItem.missionId === pwObj.parentMissionId) {
            pmObj = amItem;
            break;
        }
    }

    return pmObj;
}

this.$executePlayerWaitingActions = function (choice) {
    _co.$log("[LITF_BBS] executePlayerWaitingActions");

    var bbsData = _litf.litfVars.bbsData;

    var pwObj = bbsData.selectedItemObj; // Player wwaiting BBS item

    var pmObj = this.$getParentMissionObject(pwObj); // Original active mission item
    _co.$log("pmObj = " + JSON.stringify(pmObj));

    var currentTask = this.$getMissionTask(pmObj, pmObj.currentTask);
    var nextTask = this.$getMissionTask(pmObj, pmObj.currentTask + 1);
    _co.$log("currentTask = " + JSON.stringify(currentTask));

    var start = -1;
    var destination = -1;
    var arrivalTime = -1;
    var risk = -1;
    var parcel = null;
    //

    if (choice.indexOf("_GOTO_") > -1) {
        var choiceSplit = choice.split("_");
        pwObj.currentStep = parseInt(choiceSplit[2]);
        _co.$log("go to step = " + pwObj.currentStep);
    } else if (choice.indexOf("_NEXTTASK") > -1) {
        var advance = true;

        // Parcel Contracts
        if (currentTask.parcel) {
            parcel = "(BBS) " + currentTask.parcel;

            var newParcel = false;

            start = currentTask.info.systems[0].id;
            destination = nextTask.info.systems[0].id;

            arrivalTime = clock.seconds + pmObj.timeAllowed + 5;

            risk = 0;
            if (pmObj.risk) { risk = pmObj.risk; }

            newParcel = player.ship.addParcel(parcel, start, destination, arrivalTime, 0, 0, risk);
            _co.$log("newParcel = " + newParcel);

            advance = newParcel;
        }

        if (currentTask.passengers) {
            var passengers = currentTask.passengers; // Number of passengers
            _co.$log("passengerCapacity = " + player.ship.passengerCapacity + " passengerCount = " + player.ship.passengerCount);

            var availableCabins = player.ship.passengerCapacity - player.ship.passengerCount;
            _co.$log("availableCabins = " + availableCabins + " for Passengers = " + passengers);

            if (availableCabins < passengers) {
                var choiceStr = pwObj.steps[pwObj.currentStep].choices[choice];
                if (passengers === 1) {
                    pwObj.response = choiceStr + "\nI'm sorry, but we can't leave! You haven't an available cabin for me!"
                } else {
                    pwObj.response = choiceStr + "\nI'm sorry, but we can't leave! You haven't enough available cabins for all of us!"
                }

                advance = false;
            } else {
                // Create a contract for every passenger

                if (!pmObj.passengerList) { pmObj.passengerList = []; }

                start = currentTask.info.systems[0].id;
                destination = nextTask.info.systems[0].id;
                // _co.$log("transport from [" + currentTask.info.systems[0].name + "] to [" + nextTask.info.systems[0].name + "]");

                arrivalTime = clock.seconds + pmObj.timeAllowed + 5;

                risk = 0;
                if (pmObj.risk) { risk = pmObj.risk; }

                for (var p = 0; p < passengers; p++) {
                    if (p < currentTask.info.names.length) {
                        var pName = "(BBS) " + currentTask.info.names[p];
                        pmObj.passengerList.push(pName);

                        var newPassenger = player.ship.addPassenger(pName, start, destination, arrivalTime, 0, 0, risk);
                        _co.$log("addPassenger(" + pName + ", " + start + ", " + destination + ", " + arrivalTime + ", 0, " + risk + ") == " + newPassenger);
                    }
                }
            }
        }

        if (currentTask.typeId === 5) {
            // Cargo mission
            if (player.ship.cargoSpaceUsed > 0) {
                pwObj.response = choiceStr + "\nI'm sorry, but we need all your ship space for this shipment. Empty your cargo before accepting the job."
                advance = false;
            } else {
                var cargoGoods = currentTask.info.goods[0];
                _co.$log("Cargo mission for " + cargoGoods);

                player.ship.useSpecialCargo("(BBS) A shipment of " + cargoGoods);
            }
        }

        //

        if (advance === true) {
            this.$advanceActiveMissionTask(pwObj.parentMissionId);

            // Delete player waiting item from BBS
            this.$deleteBBSItem(pwObj.missionId);

            player.consoleMessage("Mission advanced to next task.");

            bbsData.bbsMode = 0;
        }

        $display();
    } else if (choice.indexOf("_COMPLETE") > -1) {
        if (currentTask.typeId < 4) {
            // Remove parcel contract

            parcel = null;
            if (pmObj.parcel) {
                parcel = "(BBS) " + pmObj.parcel;
            } else {
                for (var t = 0; t < pmObj.tasks.length; t++) {
                    var task = pmObj.tasks[t];
                    if (task.parcel) {
                        parcel = "(BBS) " + task.parcel;
                    }
                }
            }

            player.ship.removeParcel(parcel);
            _co.$log("removing parcel: " + parcel);
        } else if (currentTask.typeId === 4) {
            // Remove every passenger contract

            if (pmObj.passengerList) {
                for (var pa = 0; pa < pmObj.passengerList.length; pa++) {
                    player.ship.removePassenger(pmObj.passengerList[pa]);
                    _co.$log("removePassenger(" + pmObj.passengerList[pa] + ")");
                }
            }
        } else if (currentTask.typeId === 5) {
            // Cargo mission

            player.ship.removeAllCargo();
            _co.$log("removing special cargo (I hope)");
        }

        // Mission completed
        var consText = "Mission complete.";

        // Get credits award
        if (pwObj.reward > 0) {
            player.credits = player.credits + pwObj.reward;
            consText += " " + pwObj.reward + "cr received.";
        }

        // Get feedback award
        if (pmObj.groupId === 3) {
            _co.$setPlayerFeedback(-pwObj.feedbackSuccess);
        } else {
            _co.$setPlayerFeedback(pwObj.feedbackSuccess);
        }

        // Delete active mission
        this.$deleteActiveMission(pwObj.parentMissionId);

        // Delete player waiting item from BBS
        this.$deleteBBSItem(pwObj.missionId);

        _co.$updateStatistics("missionCompleted", pmObj.groupId, 1);
        _co.$updateStatistics("feedbackGained", pmObj.groupId, pwObj.feedbackSuccess);

        player.consoleMessage(consText);

        bbsData.bbsMode = 0;
        $display();
    }
}

this.$advanceActiveMissionTask = function (advanceMissionId) {
    _co.$log("[LITF_BBS] deleteActiveMission");

    var updated = false;

    for (var am = 0; am < _litf.litfCommander.activeMissions.length; am++) {
        var amItem = _litf.litfCommander.activeMissions[am];

        _co.$log("[" + am + "] item.missionId[" + amItem.missionId + "] advanceMissionId = " + advanceMissionId);

        if (amItem.missionId === advanceMissionId) {
            amItem.currentTask = amItem.currentTask + 1;
            updated = true;
            break;
        }
    }

    _co.$log("updated = " + updated);
}

this.$deleteActiveMission = function (deleteMissionId) {
    _co.$log("[LITF_BBS] deleteActiveMission");

    var ret = {
        groupId: -1,
        deleted: false,
        removedPassengers: 0,
        deadPassengers: 0,
        cargo: null,
        parcel: null,
        feedback: {}
    }

    var removedPassengers = 0;
    var deadPassengers = 0;

    for (var am = 0; am < _litf.litfCommander.activeMissions.length; am++) {
        var amItem = _litf.litfCommander.activeMissions[am];

        _co.$log("[" + am + "] item.missionId[" + amItem.missionId + "] deleteMissionId = " + deleteMissionId);

        if (amItem.tasks[0].typeId === 5) {
            // Cargo contract
            ret.cargo = amItem.tasks[0].info.goods[0];
        }

        if (amItem.tasks[0].typeId < 4) {
            // Parcel contract
            if (amItem.parcel) {
                ret.parcel = amItem.parcel;
            } else {
                for (var t = 0; t < amItem.tasks.length; t++) {
                    var task = amItem.tasks[t];
                    if (task.parcel) {
                        ret.parcel = task.parcel;
                    }
                }
            }
        }

        if (amItem.missionId === deleteMissionId) {
            // Remove passengers, if any
            if (amItem.passengerList) {
                if (amItem.failureDead === true) {
                    deadPassengers = deadPassengers + amItem.passengerList.length;
                } else {
                    removedPassengers = removedPassengers + amItem.passengerList.length;
                }

                for (var pa = 0; pa < amItem.passengerList.length; pa++) {
                    player.ship.removePassenger(amItem.passengerList[pa]);
                    _co.$log("removePassenger(" + amItem.passengerList[pa] + ")");
                }

                ret.groupId = amItem.groupId;

                ret.feedback.gained = amItem.feedbackSuccess;
                ret.feedback.lost = amItem.feedbackFailure;
            }

            _litf.litfCommander.activeMissions.splice(am, 1);
            ret.deleted = true;
            break;
        }
    }

    ret.removedPassengers = removedPassengers;
    ret.deadPassengers = deadPassengers;

    _co.$log("ret = " + JSON.stringify(ret));

    return ret;
}

this.$executeMissionActions = function (choice) {
    _co.$log("[LITF_BBS] executeMissionActions");

    var bbsData = _litf.litfVars.bbsData;

    var mObj = bbsData.selectedItemObj;
    var currentTask = this.$getMissionTask(mObj, mObj.currentTask);

    var choiceStr = this.$getChoices(mObj.choices)[choice];
    var pFeedback = _litf.litfCommander.feedback;
    var minFeedback = 0;

    var start = -1;
    var destination = -1;
    var arrivalTime = -1;
    var risk = -1;

    if (choice === "01_OK") {
        // "Ok - agreed."

        var agree = true;

        // Parcel Contracts
        if (mObj.parcel) {
            var parcel = "(BBS) " + mObj.parcel;

            var newParcel = false;

            start = mObj.startingSystem.id;
            destination = currentTask.info.systems[0].id;

            arrivalTime = clock.seconds + mObj.timeAllowed + 5;

            risk = 0;
            if (mObj.risk) { risk = mObj.risk; }

            newParcel = player.ship.addParcel(parcel, start, destination, arrivalTime, 0, 0, risk);
            _co.$log("newParcel = " + newParcel);

            agree = newParcel;
        }

        // Passengers contracts
        if (mObj.passengers) {
            var passengers = mObj.passengers; // Number of passengers

            // _co.$log("passengerCapacity = " + player.ship.passengerCapacity + " passengerCount = " + player.ship.passengerCount);

            var availableCabins = player.ship.passengerCapacity - player.ship.passengerCount;
            // _co.$log("availableCabins = " + availableCabins + " for Passengers = " + passengers);

            if (availableCabins < passengers) {
                if (passengers === 1) {
                    if (mObj.firstPassenger && mObj.firstPassenger === 0) {
                        mObj.response = choiceStr + "\nI'm sorry, but we can't leave! You haven't an available cabin for me!"
                    } else {
                        mObj.response = choiceStr + "\nI'm sorry, but we can't leave! You haven't an available cabin for the passenger!"
                    }
                } else {
                    if (mObj.firstPassenger && mObj.firstPassenger === 0) {
                        mObj.response = choiceStr + "\nI'm sorry, but we can't leave! You haven't enough available cabins for all of us!"
                    } else {
                        mObj.response = choiceStr + "\nI'm sorry, but we can't leave! You haven't an available cabin for all the passengers!"
                    }
                }
                agree = false;
            } else {
                // Create a contract for every passenger

                if (!mObj.passengerList) { mObj.passengerList = []; }

                start = mObj.startingSystem.id;
                destination = currentTask.info.systems[0].id;

                _co.$log("transport from [" + mObj.startingSystem.name + "] to [" + currentTask.info.systems[0].name + "]");

                arrivalTime = clock.seconds + mObj.timeAllowed + 5;

                risk = 0;
                if (mObj.risk) { risk = mObj.risk; }

                var newPassenger = false;

                if (mObj.firstPassenger) {
                    var passenger1 = null;
                    if (mObj.firstPassenger === 0) {
                        passenger1 = mObj.contractor;
                    } else if (mObj.firstPassenger > 0) {
                        var pTask = this.$getMissionTask(mObj, mObj.firstPassenger);
                        passenger1 = pTask.info.names[0];
                    }
                    newPassenger = player.ship.addPassenger(passenger1, start, destination, arrivalTime, 0, 0, risk);
                    _co.$log("addPassenger(" + passenger1 + ", " + start + ", " + destination + ", " + arrivalTime + ", 0, " + risk + ") == " + newPassenger);
                    passengers = passengers - 1;
                }

                for (var p = 0; p < passengers; p++) {
                    var pName = "(BBS) " + randomName() + " " + randomName();
                    mObj.passengerList.push(pName);

                    newPassenger = player.ship.addPassenger(pName, start, destination, arrivalTime, 0, 0, risk);
                    _co.$log("addPassenger(" + mObj.contractor + ", " + start + ", " + destination + ", " + arrivalTime + ", 0, " + risk + ") == " + newPassenger);
                }
            }
        } else if (currentTask.typeId === 4) {
            var pCapacity = player.ship.passengerCapacity
            if (pCapacity === 0) {
                mObj.response = choiceStr + "\nI'm sorry, but you haven't a single cabin on your ship!"
                agree = false;
            }
        }

        // Cargo contracts
        if (currentTask.typeId === 5) {
            if (player.ship.cargoSpaceUsed > 0) {
                mObj.response = choiceStr + "\nI'm sorry, but we need all your ship space for this shipment. Empty your cargo before accepting the job."
                agree = false;
            } else {
                var cargoGoods = currentTask.info.goods[0];
                _co.$log("Cargo mission for " + cargoGoods);

                player.ship.useSpecialCargo("(BBS) A shipment of " + cargoGoods);
            }
        }

        // Check max active missions limit
        if (agree === true) {
            var maxActiveMissions = parseInt(Math.abs(pFeedback) / 25) + 1;
            if (_litf.litfCommander.activeMissions.length === maxActiveMissions) {
                mObj.response = choiceStr + "\nI'm sorry, your feedback doesn't allow you to accept more missions. Increasing the feedback you'll be able to accept more missions at the same time."
                agree = false;
            }
            _co.$log("active missions: " + _litf.litfCommander.activeMissions.length + " max: " + maxActiveMissions + " agree = " + agree);
        }

        //

        if (agree === true) {
            var advance = 0;

            // Accept mission
            if (mObj.rewardAdvanceObtained !== null) {
                if (mObj.rewardAdvanceObtained === "half") {
                    advance = mObj.reward / 2;
                    player.credits = player.credits + advance;
                    mObj.reward = mObj.reward / 2;
                } else if (mObj.rewardAdvanceObtained === "full") {
                    advance = mObj.reward;
                    player.credits = player.credits + advance;
                    mObj.reward = 0;
                }
            }

            // define reputation success and failure score
            mObj.feedbackSuccess = this.$feedbackSuccessScore(mObj);
            mObj.feedbackFailure = this.$feedbackFailureScore(mObj);

            //

            mObj.startTime = clock.seconds;

            _litf.litfCommander.activeMissions.push(mObj);

            this.$deleteBBSItem(mObj.missionId);

            _co.$updateStatistics("missionAccepted", mObj.groupId, 1);

            player.consoleMessage("Mission has been accepted.");
            if (advance > 0) {
                player.consoleMessage("Received " + advance + "cr as advance.");
            }

            bbsData.bbsMode = 0;
        }

        $display();
    } else if (choice === "02_HOWMANY") {
        // "How many of you are there?"
        var totPassengers = this.$howManyPassengers(mObj);
        if (totPassengers === 1) {
            mObj.response = choiceStr + "\nOnly one person.";
        } else if (totPassengers > 1) {
            mObj.response = choiceStr + "\nA group of " + totPassengers + " persons.";
        }
    } else if (choice === "03_MONEY") {
        // "Why so much money?"
        mObj.response = choiceStr + "\n" + mObj.responses.money;
    } else if (choice === "04_PROBLEMS") {
        // "Will there be any problems?"
        mObj.response = choiceStr + "\n" + mObj.responses.problems;
    } else if (choice === "05_PERMIT") {
        // "Do I need a permit, and if so can I have one?"
        mObj.response = choiceStr + "\nDon't be silly - you don't need a permit.";
    } else if (choice === "05_UNAWARE") {
        // "Do the recipient will know of my arrival?"
        if (currentTask.unaware === false) {
            mObj.response = choiceStr + "\n" + mObj.responses.unaware[0];
        } else {
            mObj.response = choiceStr + "\n" + mObj.responses.unaware[1];
        }
    } else if (choice === "06_MOREMONEY") {
        // "I want more money."
        minFeedback = mObj.moreMoneyMinFeedback ? mObj.moreMoneyMinFeedback : this.moreMoneyMinFeedbackDefault;
        if (pFeedback < minFeedback) {
            mObj.response = choiceStr + "\n" + mObj.reward + "cr is all I can pay.";
        } else if (mObj.moreMoneyObtained === false) {
            var percentMore = (_co.$roll(0, 3) * 5) + 10;
            var newReward = mObj.reward + (mObj.reward / 100 * percentMore);

            mObj.reward = newReward;
            mObj.response = choiceStr + "\nOk. Considering your feedback I can increase the reward to " + mObj.reward + " credits.";
            mObj.moreMoneyObtained = true;
        } else {
            mObj.response = choiceStr + "\nWe've agreed on payment of " + mObj.reward + " credits.";
        }
    } else if (choice === "07_HALFADVANCE") {
        // "I want half the money now."
        minFeedback = mObj.halfAdvanceMinFeedback ? mObj.halfAdvanceMinFeedback : this.halfAdvanceMinFeedbackDefault;
        if (pFeedback < minFeedback) {
            mObj.response = choiceStr + "\nWhat sort of fool do you take me for?";
        } else if (mObj.rewardAdvanceObtained === null) {
            mObj.response = choiceStr + "\nOk. I'll pay half once you agree, and half on arrival.";
            mObj.rewardAdvanceObtained = "half";
        } else {
            mObj.response = choiceStr + "\nWe've agreed on payment.";
        }
    } else if (choice === "08_FULLADVANCE") {
        // "I want all the money now."
        minFeedback = mObj.fullAdvanceMinFeedback ? mObj.fullAdvanceMinFeedback : this.fullAdvanceMinFeedbackDefault;
        if (pFeedback < minFeedback) {
            mObj.response = choiceStr + "\nWhat sort of fool do you take me for?";
        } else if (mObj.rewardAdvanceObtained === null) {
            mObj.response = choiceStr + "\nOk. I'll pay the full reward once you agree.";
            mObj.rewardAdvanceObtained = "full";
        } else {
            mObj.response = choiceStr + "\nWe've agreed on payment.";
        }
    }
}

this.$howManyPassengers = function (mObj) {
    _co.$log("[LITF_BBS] howManyPassengers");
    var totalPassengers = 0;

    if (mObj.passengers) {
        totalPassengers = totalPassengers + mObj.passengers;
    }

    for (var ta = 0; ta < mObj.tasks.length; ta++) {
        var task = mObj.tasks[ta];
        if (task.passengers) {
            totalPassengers = totalPassengers + task.passengers;
        }
    }

    _co.$log("totalPassengers = " + totalPassengers);
    return totalPassengers;
}

this.$deleteBBSItem = function (itemId) {
    var deleted = false;

    var bbsData = _litf.litfVars.bbsData;

    for (var i = 0; i < bbsData.bbsItemsArr.length; i++) {
        var item = bbsData.bbsItemsArr[i];

        if (item.missionId === itemId) {
            bbsData.bbsItemsArr.splice(i, 1);
            deleted = true;
            break;
        }
    }

    if (deleted === true) {
        while (bbsData.selectedItem >= bbsData.bbsItemsArr.length) {
            bbsData.selectedItem = bbsData.selectedItem - 1;
        }
    }
}

this.$executeCharityActions = function (choice) {
    _co.$log("[LITF_BBS] executeCharityActions");

    if (choice === "01_DONATE01") {
        this.$actionDonate(choice, 0.1);
    } else if (choice === "02_DONATE1") {
        this.$actionDonate(choice, 1);
    } else if (choice === "03_DONATE10") {
        this.$actionDonate(choice, 10);
    } else if (choice === "04_DONATE100") {
        this.$actionDonate(choice, 100);
    } else if (choice === "05_DONATE1000") {
        this.$actionDonate(choice, 1000);
    } else if (choice === "06_DONATE10000") {
        this.$actionDonate(choice, 10000);
    }
}

this.$actionDonate = function (choice, amount) {
    _co.$log("[LITF_BBS] actionDonate");

    var bbsData = _litf.litfVars.bbsData;

    var choiceStr = this.$getChoices(bbsData.selectedItemObj.choices)[choice];

    if (player.credits < amount) {
        bbsData.selectedItemObj.response = choiceStr + "\nYou don't have enough cash.";
    } else {
        player.credits = player.credits - amount;
        bbsData.selectedItemObj.response = choiceStr + "\nThank you. All donations are gratefully received.";

        // Feedback reward

        if (amount === 0.1) {
            // No feedback reward
        } else if (amount === 1) {
            if (_co.$roll(1, 100) < 5) {
                _co.$setPlayerFeedback(1);
            }
        } else if (amount === 10) {
            if (_co.$roll(1, 100) < 20) {
                _co.$setPlayerFeedback(1);
            }
        } else if (amount === 100) {
            _co.$setPlayerFeedback(1);
        } else if (amount === 1000) {
            _co.$setPlayerFeedback(5);
        } else if (amount === 10000) {
            _co.$setPlayerFeedback(10);
        }
    }
}

this.$feedbackSuccessScore = function (mObj) {
    _co.$log("[LITF_BBS] feedbackSuccessScore");

    var score = 2;

    if (mObj.local === false) {
        if (mObj.moreMoneyObtained === false) {
            score = score + 1;
        }

        if (mObj.rewardAdvanceObtained === null) {
            score = score + 1;
        }
    }

    return score;
}

this.$feedbackFailureScore = function (mObj) {
    _co.$log("[LITF_BBS] feedbackFailureScore");

    var score = 2;

    if (mObj.local === false) {
        if (mObj.moreMoneyObtained === true) {
            score = score + 2;
        }

        if (mObj.rewardAdvanceObtained === "half") {
            score = score + 1;
        } else if (mObj.rewardAdvanceObtained === "full") {
            score = score + 2;
        }
    }

    return score;
}

this.$getMissionTask = function (mObj, taskIndex) {
    _co.$log("[LITF_BBS] getCurrentTask");

    var tasks = mObj.tasks;
    var tObj = {};

    for (var t = 0; t < tasks.length; t++) {
        var tItem = tasks[t];
        if (tItem.index === taskIndex) {
            tObj = tItem;
            break;
        }
    }

    _co.$log("task[" + taskIndex + "] = " + JSON.stringify(tObj));

    return tObj;
}
Scripts/LITF_Common.js
/* eslint-disable semi, no-multi-spaces, quotes, indent, no-tabs, yoda */
/* global worldScripts, player, log, system, clock, galaxyNumber */

"use strict";

this.name        = "LITF_Common";
this.author      = "BeeTLe BeTHLeHeM";
this.copyright   = "2018 BeeTLe BeTHLeHeM";
this.description = "Library of common methods";
this.version     = "0.10.0";
this.licence     = "CC BY-NC-SA 4.0";

// Groups labels

this.groupsLabels = ["GalCop", "GalBook", "GalChurch", "GalShady", "GalMedical", "GalCivic", "GalTourism", "GalShopping", "GalNature", "GalCulture", "GalGovernment", "GalDebug"];

// Sub-commodity and associated commodity (for reference price)

this.commodityReference = {
	"food": [ "Grain", "Generic Foods", "Food Dispensers", "Medicines", "Farm Animals", "Colture Plants", "Junk Foods" ],
	"textiles": [ "Textiles" ],
	"machinery": [ "Factory Equipment", "Mining Equipment", "Robo-Servants", "Robo-Workers", "Robo-Fighters", "Robo-Pleasures", "Robo-Medics" ],
	"gem_stones": [ "Industrial Gems" ],
	"luxuries": [ "Luxury Foods", "Electric Pets", "Artwork", "Games", "Movies", "Holographics", "Home Entertainment", "Books", "Furniture", "Paleo-Arts", "Archeo-Sims", "Relics", "Religious Texts", "Wood", "Dream Cards", "Hacked Dream Cards" ],
	"firearms": [ "Weaponry", "Combat Drones", "Recon Drones" ],
	"platinum": [],
	"slaves": [ "Slaves", "Black Market Organs", "Altered Embryos", "Counterfeit DNA Sequences" ],
	"furs": [ "Furs" ],
	"radioactives": [ "Plutonium", "Uranium", "Advanced Fuels", "Radium", "Thorium", "Hazardous Waste" ],
	"alien_items": [ "Holy Symbols", "Prayer Books", "Fossils", "Stolen Cargos" ],
	"alloys": [ "Construction Materials", "Pre-Fabs", "Space Salvage", "Plastics", "Synthetics" ],
	"liquor_wines": [ "Liquors" ],
	"narcotics": [ "Brilliance", "Tobacco", "Cheap Spice", "Unlicensed Pharmaceuticals", "Contaminated Products" ],
	"minerals": [ "Iron", "Tungsten", "Nickel", "Quartz" ],
	"computers": [ "Communication Equipment", "Computers", "Home Appliances", "Medical Equipment", "Music Equipment", "Industrial Capacitors", "Artificial Limbs", "Artificial Organs", "Neural Interfaces", "Spy Microchips" ],
	"gold": [ "Gold" ]
};

// Sub-commodity list by group

this.commodityGroups = [
	[ "Weaponry", "Robo-Servants", "Communication Equipment", "Combat Drones", "Recon Drones" ], // GalCop
	[ "Books" ], // GalBook
	[ "Relics", "Religious Texts", "Prayer Books", "Holy Symbols" ], // GalChurch
	[ "Plutonium", "Uranium", "Radium", "Thorium", "Slaves", "Brilliance", "Tobacco", "Cheap Spice", "Liquors", "Weaponry", "Industrial Gems", "Gold", "Platinum", "Robo-Fighters", "Robo-Pleasures", "Hacked Dream Cards", "Space Salvage", "Combat Drones", "Recon Drones", "Black Market Organs", "Altered Embryos", "Counterfeit DNA Sequences", "Stolen Cargos", "Spy Microchips", "Unlicensed Pharmaceuticals", "Hazardous Waste", "Contaminated Products" ], // GalShady
	[ "Medicines", "Robo-Medics", "Medical Equipment", "Artificial Limbs", "Artificial Organs", "Neural Interfaces" ], // GalMedical
	[ "Generic Foods", "Luxury Foods", "Textiles", "Liquors", "Electric Pets", "Games", "Holographics", "Home Entertainment", "Furs", "Furniture", "Robo-Servants" ], // GalCivic
	[ "Plants", "Robo-Servants", "Luxury Foods", "Electric Pets", "Movies", "Holographics", "Furniture", "Liquors", "Tobacco" ], // GalTourism
	[ "Junk Foods", "Grain", "Food Dispensers", "Textiles", "Liquors", "Luxury Foods", "Wood", "Computers", "Home Appliances", "Furs", "Dream Cards" ], // GalShopping
	[ "Farm Animals", "Colture Plants", "Paleo-Arts", "Archeo-Sims" ], // GalNature
	[ "Paleo-Arts", "Archeo-Sims", "Fossils", "Artwork", "Movies", "Holographics", "Music Equipment" ], // GalCulture,
	[ "Generic Foods", "Factory Equipment", "Mining Equipment", "Weaponry", "Construction Materials", "Communication Equipment" ], // GalGovernment
	[ "Books", "Relics", "Liquors", "Medicines", "Electric Pets", "Computers" ], // GalDebug
	[ "Grain", "Generic Foods", "Food Dispensers", "Medicines", "Farm Animals", "Colture Plants", "Junk Foods", "Textiles", "Factory Equipment", "Mining Equipment", "Robo-Servants", "Robo-Workers", "Robo-Fighters", "Robo-Pleasures", "Robo-Medics", "Industrial Gems", "Luxury Foods", "Electric Pets", "Artwork", "Games", "Movies", "Holographics", "Home Entertainment", "Books", "Furniture", "Paleo-Arts", "Archeo-Sims", "Relics", "Religious Texts", "Wood", "Dream Cards", "Hacked Dream Cards", "Weaponry", "Slaves", "Furs", "Plutonium", "Uranium", "Radium", "Thorium", "Advanced Fuels", "Holy Symbols", "Prayer Books", "Fossils", "Construction Materials", "Pre-Fabs", "Space Salvage", "Synthetics", "Plastics", "Liquors", "Brilliance", "Tobacco", "Spice", "Iron", "Tungsten", "Nickel", "Quartz", "Communication Equipment", "Computers", "Home Appliances", "Medical Equipment", "Music Equipment", "Gold", "Industrial Capacitors" ] // EVERYTHING
];

// System governments labels

this.govLabels = ["Anarchy", "Feudal", "Multigovernmental", "Dictatorship", "Communist", "Confederacy", "Democracy", "Corporate"];

var _litf = null;

this.$init = function () {
	_litf = worldScripts.LITF;

	this.$log("[LITF_Common] init");
}

// Print a text message on the Oolite log file
this.$log = function (msg) {
	if (!_litf.litfVars || _litf.litfVars.config.enableLog === true) {
		log(this.name, msg);
	}
};

this.$decodeGroup = function (groupId) {
	var groupLabel = this.groupsLabels[groupId];
	return groupLabel;
}

this.$encodeGroup = function (groupLabel) {
	var groupId = this.groupsLabels.indexOf(groupLabel);
	return groupId;
}

this.$systemEconomy = function () {
	this.$log("[LITF_Common] systemEconomy");

	var economy = system.economy;
	return economy;
}

this.$systemTechLevel = function () {
	this.$log("[LITF_Common] systemTechLevel");

	var tl = system.techLevel;
	return tl;
}

this.$systemGovernment = function () {
	this.$log("[LITF_Common] systemGovernment");

	var gov = system.government;
	return gov;
}

// Replace all occurences of a string in a text
this.$replaceAll = function (find, replace, str) {
	this.$log("[LITF_Common] replaceAll");

	return str.split(find).join(replace);
};

// Generates a random number between two limits
this.$roll = function (min, max) {
	this.$log("[LITF_Common] roll");

	if (min > max) {
		var buf = min;
		min = max;
		max = buf;
	}

	var rv = Math.floor(Math.random() * (max - min + 1)) + min;
	return rv;
};

// // Replace constants in a mission title text
// this.$replaceConstants = function (text, groupId, maxSystemDistance) {
// 	this.$log("[LITF_Common] replaceConstants");

// 	var result = {};
// 	var rtext = null;

// 	if (text.indexOf("%BOOK%") > -1) {
// 		rtext = expandDescription("[litf_Books]");
// 		text = text.replace("%BOOK%", rtext);
// 		if (!result.randBook) { result.randBook = []; }
// 		result.randBook.push(rtext);
// 	}

// 	if (text.indexOf("%ITEM%") > -1) {
// 		rtext = expandDescription("[litf_Items]");
// 		text = text.replace("%ITEM%", rtext);
// 		if (!result.randItem) { result.randItem = []; }
// 		result.randItem.push(rtext);
// 	}

// 	if (text.indexOf("%JOB%") > -1) {
// 		rtext = expandDescription("[litf_Jobs]");
// 		text = text.replace("%JOB%", rtext);
// 		if (!result.randJob) { result.randJob = []; }
// 		result.randJob.push(rtext);
// 	}

// 	if (text.indexOf("%CHARITY%") > -1) {
// 		rtext = expandDescription("[litf_Charity]");
// 		text = text.replace("%CHARITY%", rtext);
// 		if (!result.randCharity) { result.randCharity = []; }
// 		result.randCharity.push(rtext);
// 	}

// 	if (text.indexOf("%PLAYERNAME%") > -1) {
// 		text = text.replace("%PLAYERNAME%", player.name);
// 	}

// 	if (text.indexOf("%NAME%") > -1) {
// 		rtext = randomName() + " " + randomName();
// 		text = text.replace("%NAME%", rtext);
// 		if (!result.randName) { result.randName = []; }
// 		result.randName.push(rtext);
// 	}

// 	if (text.indexOf("%SYSTEM%") > -1) {
// 		var rObj = this.$randomSystem(maxSystemDistance);
// 		text = text.replace("%SYSTEM%", rObj.name);
// 		if (!result.randSystem) { result.randSystem = []; }
// 		result.randSystem.push(rObj);
// 	}

// 	if (text.indexOf("%ART%") > -1) {
// 		rtext = expandDescription("[litf_Art1]") + " " + expandDescription("[litf_Art2]");
// 		text = text.replace("%ART%", rtext);
// 		if (!result.randArt) { result.randArt = []; }
// 		result.randArt.push(rtext);
// 	}

// 	if (text.indexOf("%MUSIC%") > -1) {
// 		rtext = expandDescription("[litf_Music1]") + " " + expandDescription("[litf_Music2]") + " " + expandDescription("[litf_Music3]");
// 		text = text.replace("%MUSIC%", rtext);
// 		if (!result.randMusic) { result.randMusic = []; }
// 		result.randMusic.push(rtext);
// 	}

// 	if (text.indexOf("%MOVIE%") > -1) {
// 		rtext = expandDescription("[litf_Movie1]") + " " + expandDescription("[litf_Movie2]");
// 		text = text.replace("%MOVIE%", rtext);
// 		if (!result.randMovies) { result.randMovies = []; }
// 		result.randMovies.push(rtext);
// 	}

// 	if (text.indexOf("%GOODS%") > -1) {
// 		var goodArrByGroup = this.commodityGroups[12]; // Choose from EVERYTHING
// 		var goodIdx = this.$roll(0, goodArrByGroup.length - 1);

// 		text = text.replace("%GOODS%", goodArrByGroup[goodIdx]);
// 		result.randGood = goodArrByGroup[goodIdx];
// 	}

// 	if (text.indexOf("%RACE%") > -1) {
// 		rtext = randomInhabitantsDescription(true);
// 		text = text.replace("%RACE%", rtext);
// 		if (!result.randRaces) { result.randRaces = []; }
// 		result.randRaces.push(rtext);
// 	}

// 	result.text = text;

// 	this.$log("[replaceConstants] " + JSON.stringify(result));

// 	return result;
// }

// Choose a random system in the input range, that it isn't the current player system
this.$randomSystem = function (maxSystemDistance) {
	this.$log("[LITF_Common] randomSystem");

	var valid   = 0;
	var counter = 0;

	var sysObj    = null; // System object

	while (valid === 0) {
		var rand = Math.floor(Math.random() * 256);

		var distance = this.$getSystemRoute(system.ID, rand).distance;

		if (maxSystemDistance === -1 || distance < maxSystemDistance) {
			var sName = System.systemNameForID(rand);
			if (sName !== system.name) {
				sysObj = {
					id: rand,
					name: sName,
					distance: distance.toFixed(2)
				};
				valid = 1;
			}
		}

		counter++;

		if (counter % 50 === 0 && maxSystemDistance !== -1) {
			maxSystemDistance += 0.5;
		}
	}

	this.$log("randomSystem << " + JSON.stringify(sysObj));

	return sysObj;
};

// Check if a specific time has still to come or not
this.$isTimeExpired = function (startingTime, duration) {
	this.$log("[LITF_Common] isTimeExpired");

	var expired = false;

	var deadline = startingTime + duration;

	if (clock.seconds > deadline) {
		expired = true;
	}

	return expired;
}

// Calculate time from "now" to the specified time, and format the resulting text
this.$formatTime = function (time, remaining) {
	this.$log("[LITF_Common] formatTime");

	if (remaining === true) {
		time = time - clock.seconds;
	}

	var dataTime = this.$secondsData(time);

	var formattedTime = "";

	formattedTime += dataTime.onlyHours + " hours, ";
	formattedTime += dataTime.minutes + " minutes, ";
	formattedTime += dataTime.seconds + " seconds"

    return formattedTime;
}

// Convert a value in seconds in day/hours/only hours/minute/seconds
this.$secondsData = function (seconds) {
	this.$log("[LITF_Common] secondsData");

	var minute = 60;
    var hour = 60 * minute;
    var day = 24 * hour;

    var dd = 0;
    var hh = 0;
    var mm = 0;

	while (seconds > day) {
        dd++;
        seconds -= day;
    }

    while (seconds > hour) {
        hh++;
        seconds -= hour;
    }

    while (seconds > minute) {
        mm++;
        seconds -= minute;
    }

	var obj = {
		days: dd,
		hours: hh,
		onlyHours: hh + (dd * 24),
		minutes: mm,
		seconds: Math.round(seconds)
	}

	this.$log("obj = " + JSON.stringify(obj));

	return obj;
}

// Fisher-Yates Shuffle algorithm for arrays
this.$shuffleArray = function (array) {
	this.$log("[LITF_Common] shuffleArray");

	var currentIndex = array.length;
	var temporaryValue;
	var randomIndex;

	// While there remain elements to shuffle...
	while (0 !== currentIndex) {
		// Pick a remaining element...
		randomIndex = Math.floor(Math.random() * currentIndex);
		currentIndex -= 1;

		// And swap it with the current element.
		temporaryValue      = array[currentIndex];
		array[currentIndex] = array[randomIndex];
		array[randomIndex]  = temporaryValue;
	}

	return array;
}

this.$getSubCommodityPrice = function (subCommodity) {
	var scBasePrice = -1;
	var market = player.ship.dockedStation.market;
	var crKeys = this.$getObjectKeys(this.commodityReference);
	for (var k = 0; k < crKeys.length; k++) {
		var scArr = this.commodityReference[crKeys[k]];
		if (scArr.indexOf(subCommodity) !== -1) {
			scBasePrice = market[crKeys[k]].price;
			break;
		}
	}
	return scBasePrice;
}

// Returns an array with all the keys in an associative object
this.$getObjectKeys = function (object) {
	this.$log("[LITF_Common] getObjectKeys");

	var keys = [];
	for (var key in object) {
		if (object.hasOwnProperty(key)) {
			keys.push(key);
		}
	}

	return keys;
}

// Get a literal ranking from a feedback value
this.$getFeedbackRanking = function (feedback) {
	this.$log("[LITF_Common] getFeedbackRanking");

	var rank = "";

	if (feedback < -100) {
		rank = "Outcast"; // -101 or less
	} else if (feedback < -50) {
		rank = "Criminal"; // -51 to -100
	} else if (feedback < -25) {
		rank = "Unlawful"; // -26 to -50
	} else if (feedback < -10) {
		rank = "Untrusted"; // -11 to -25
	} else if (feedback < 10) {
		rank = "Neutral"; // 9 to -10
	} else if (feedback < 25) {
		rank = "Appreciated"; // 24 to 10
	} else if (feedback < 50) {
		rank = "Helpful"; // 49 to 25
	} else if (feedback < 100) {
		rank = "Trusted"; // 99 to 50
	} else {
		rank = "Renowned"; // 100 or more
	}

	return rank;
}

// Information about a route between two systems
this.$getSystemRoute = function (system1, system2) {
	var infoS1 = System.infoForSystem(galaxyNumber, system1);
	var infoS2 = System.infoForSystem(galaxyNumber, system2);

	var route = infoS1.routeToSystem(infoS2); // route, distance, time
	return route;
}

// Get the general id and increase its value to avoi duplicates
this.$getGeneralId = function () {
	this.$log("[LITF_Common] getGeneralId");

	var generalId = _litf.litfVars.generalId;

	_litf.litfVars.generalId = _litf.litfVars.generalId + 1;

	return generalId;
}

this.$setPlayerFeedback = function (add) {
	this.$log("[LITF_Common] setPlayerFeedback");

	var pFeedback = _litf.litfCommander.feedback;

	pFeedback = pFeedback + add;

	// Check limits

	if (pFeedback > 150) { pFeedback = 150; }
	if (pFeedback < -150) { pFeedback = -150; }

	_litf.litfCommander.feedback = pFeedback;
}

this.$updateStatistics = function (property, groupId, value) {
	this.$log("[LITF_Common] updateStatistics :: " + property + "[" + groupId + "] << " + value);

	var sProperty = _litf.litfCommander.statistics[property];
	_litf.litfCommander.statistics[property][groupId] = sProperty[groupId] + value;
}

this.$padLeft = function (padNumber, padLength, padChar) {
	var numStr = "" + padNumber;

	while (numStr.length < padLength) {
		numStr = padChar + numStr;
	}

	return numStr;
}

// Debug //
this.$exportMissionData = function () {
	this.$log("[LITF] exportMissionData");

	var _md = worldScripts.MissionData;

    var csv = "";
    var separator = "#";

    var k, m, mObj;

    var keyArr = [ "groupId", "typeId" ];

    // First reading - get every key
    for (m = 0; m < _md.missionStore.length; m++) {
        mObj = _md.missionStore[m];
        var mKeys = this.$getObjectKeys(mObj);

        for (k = 0; k < mKeys.length; k++) {
            if (keyArr.indexOf(mKeys[k]) === -1) {
                keyArr.push(mKeys[k]);
            }
        }
    }

    // Header row
    for (k = 0; k < keyArr.length; k++) {
        csv += keyArr[k];
        if (k < keyArr.length - 1) { csv += separator; }
    }
    csv += "\n";

    // Second reading - all the data
    for (m = 0; m < _md.missionStore.length; m++) {
        mObj = _md.missionStore[m];

        // var mRef = _co.$getMissionReference(mObj.type);
        csv += mObj.type.groupId + separator + mObj.type.typeId + separator;

        for (k = 0; k < keyArr.length; k++) {
            var value = mObj[keyArr[k]];
            if (value) {
                csv += value;
            }
            if (k < keyArr.length - 1) { csv += separator; }
        }
        csv += "\n";
    }

    this.$log("--------------------------------------------------\n\n" + csv + "\n\n--------------------------------------------------");
}
Scripts/LITF_MissionData.js
/* eslint-disable semi, no-multi-spaces, quotes, indent, no-tabs, yoda */

"use strict";

this.name = "LITF_MissionData";
this.author = "BeeTLe BeTHLeHeM";
this.copyright = "2018 BeeTLe BeTHLeHeM";
this.description = "Variables and arrays for BBS items and missions data";
this.version = "0.10.0";
this.licence = "CC BY-NC-SA 4.0";

//

// Mission types

this.missionTypes = [ "LOCAL", "CONTACT", "TRANSFER", "RETRIEVE", "TRANSPORT", "CARGO", "SEARCH", "INFO", "TOUR", "KILL" ];

//

this.debugStore = [
    // {
    //     groupId: 11,
    //     index: 0,
    //     local: true,
    //     title: "(TRAINING) This is a mission of type LOCAL",
    //     description: "TBD",
    //     choices: null
    // },
    {
        groupId: 11,
        index: 1,
        title: "(TRAINING) This is a mission of type TRANSPORT from %SYSTEM1% to %SYSTEM2%.",
        description: "Hello. I'm %NAME0%. You have to pick %NAME1% in the %SYSTEM1% system and bring him to the %SYSTEM2% system. For the completion of this task we'll pay you %REWARD% credits.",
        choices: "transport",
        currentTask: 1,
        customResponses: {
            money: [ "[litf_missionResponseMoneyGroup]" ] // this.litf_missionResponseMoneyGroup
        },
        tasks: [
            {
                index: 1,
                typeId: 4,
                description: "Go to the %SYSTEM1% system, meet %NAME1% and carry him to %SYSTEM2%. Remember to check the BBS to get your payment.",
                generate: { systems: 1, names: 1 },
                waitingMission: "W000",
                passengers: [ 1 ]
            },
            {
                index: 2,
                typeId: 4,
                description: "Carry %NAME1% to the %SYSTEM2% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1 },
                waitingMission: "W001"
            }
        ]
    },
    {
        groupId: 11,
        index: 2,
        title: "(TRAINING) This is a mission of type TRANSPORT from here to %SYSTEM1%.",
        description: "Hello. I'm %NAME0%. I need a ship to go to the %SYSTEM1% system. For the completion of this task I'll pay you %REWARD% credits.",
        choices: "transport",
        currentTask: 1,
        passengers: [ 1 ],
        firstPassenger: 0,
        customResponses: {
            money: [ "[litf_missionResponseMoneyPassenger]" ] // this.litf_missionResponseMoneyPassenger
        },
        tasks: [
            {
                index: 1,
                typeId: 4,
                description: "Bring %NAME0% to the %SYSTEM1% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1 },
                waitingMission: "W001"
            }
        ]
    },
    {
        groupId: 11,
        index: 3,
        title: "(TRAINING) This is a mission of type TRANSPORT (group) from here to %SYSTEM1%.",
        description: "Hello. I'm %NAME0%. Me and my friends need a ship to go to the %SYSTEM1% system. For the completion of this task I'll pay you %REWARD% credits.",
        choices: "transport",
        currentTask: 1,
        passengers: [ 2, 7 ],
        firstPassenger: 0,
        customResponses: {
            money: [ "[litf_missionResponseMoneyGroup]" ] // this.litf_missionResponseMoneyGroup
        },
        tasks: [
            {
                index: 1,
                typeId: 4,
                description: "Bring %PASSENGERS% people to the %SYSTEM1% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1 },
                waitingMission: "W001"
            }
        ]
    },
    {
        groupId: 11,
        index: 4,
        title: "(TRAINING) This is a mission of type CARGO from here to %SYSTEM1%.",
        description: "Hello. I'm %NAME0%. I need to send a shipment of %GOODS% to the %SYSTEM1% system. For the completion of this task I'll pay you %REWARD% credits.",
        choices: "cargo",
        currentTask: 1,
        customResponses: {
            money: [ "It's a simple commercial trip." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 5,
                description: "Bring a shipment of %GOODS% to the %SYSTEM1% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1, goods: 1 },
                waitingMission: "W002"
            }
        ]
    }
];

this.missionWaitingStore = [
    // Debug ------------------------------------------------------------------
    {
        label: "W000",
        title: "(TRAINING) Commander %PLAYERNAME%, I'm waiting for you to leave this system.",
        steps: [
            {
                index: 1,
                description: "Hello. I'm %NAME1%. If you're ready we can leave immediately.",
                choice: {
                    "01_NEXTTASK": "\"Ok, go to the hangar and we go.\"",
                    "99_QUIT": "Hang up."
                }
            }
        ]
    },
    {
        label: "W001",
        title: "(TRAINING) Commander %PLAYERNAME%, get your payment.",
        steps: [
            {
                index: 1,
                description: "-- Closing transaction --",
                choice: {
                    "01_COMPLETE": "Accept and hang up."
                }
            }
        ]
    },
    {
        label: "W002",
        title: "(TRAINING) Commander %PLAYERNAME%, we are offloading the cargo from your ship. You can get your payment.",
        steps: [
            {
                index: 1,
                description: "-- Closing transaction --",
                choice: {
                    "01_COMPLETE": "Accept and hang up."
                }
            }
        ]
    },
    // Generic ----------------------------------------------------------------
    {
        label: "G1",
        title: "REWARD: Commander %PLAYERNAME%, get your payment.",
        steps: [
            {
                index: 1,
                description: "<Please accept the transaction to close the deal.>",
                choice: {
                    "01_COMPLETE": "Accept and hang up."
                }
            }
        ]
    },
    {
        label: "G2",
        title: "LOOK HERE: Commander %PLAYERNAME%.",
        steps: [
            {
                index: 1,
                description: "Hello Commander %PLAYERNAME%, I'm glad you're here. Can we leave for our destination?",
                choice: {
                    "01_GOTO_2": "\"Yes, we can leave now.\" and hang up.",
                    "99_QUIT": "\"Hold on while I make room.\" then hang up."
                }
            }
        ]
    },
    {
        label: "G3",
        title: "HANGAR: Commander %PLAYERNAME%, we are offloading the cargo from your ship. You can get your payment.",
        steps: [
            {
                index: 1,
                description: "-- Closing transaction --",
                choice: {
                    "01_COMPLETE": "Accept and hang up."
                }
            }
        ]
    },
    {
        label: "G3.1",
        title: "HANGAR: Waiting Commander %PLAYERNAME% to load cargo onto the ship.",
        steps: [
            {
                index: 1,
                description: "Hi. We're going to load a shipment of %GOODS% on you ship, as agreed.",
                choice: {
                    "01_GOTO_2": "\"Yes, proceed.\"",
                    "99_QUIT": "\"Hold on while I make room.\" then hang up."
                }
            },
            {
                index: 2,
                description: "We have loaded the cargo. You can leave when you want. Goodbye.",
                choice: {
                    "01_COMPLETE": "Hang up."
                }
            }
        ]
    },
    {
        label: "G4",
        title: "LOOK HERE: Waiting for Commander %PLAYERNAME%.",
        steps: [
            {
                index: 1,
                description: "Hello, I'm %NAME1%. Can we leave to our destination now?",
                choice: {
                    "01_COMPLETE": "\"Yes, we can leave now.\" and hang up.",
                    "99_QUIT": "\"Hold on while I make room.\" then hang up."
                }
            }
        ]
    },

    // GalCop -----------------------------------------------------------------
    {
        label: "W0.1.1",
        title: null,
        steps: [
            {
                index: 1,
                description: "Hi, I'm %NAME1%. There's something I can do for you? I'm pretty busy at the moment.",
                choice: {
                    "01_GOTO_2": "\"I come from %SYSTEM0% with some informations for you. GalCop is the sender.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Can you trasmit me these info?",
                choice: {
                    "01_GOTO_3": "\"Here they are.\" and send the info."
                }
            },
            {
                index: 3,
                description: "Yes, I was awaiting this. Good service citizen. Thank you.",
                choice: {
                    "01_COMPLETE": "Hang up."
                }
            }
        ]
    },
    {
        label: "W0.1.2",
        title: null,
        steps: [
            {
                index: 1,
                description: "Hi, I'm %NAME1%. There's something I can do for you? I'm pretty busy at the moment.",
                choice: {
                    "01_GOTO_2": "\"I come from %SYSTEM0%, I have some equipment for you. GalCop is the sender.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Oh yes, I was awaiting that. Are you sending me the package?",
                choice: {
                    "01_GOTO_3": "\"Yes, just sent through the station network.\""
                }
            },
            {
                index: 3,
                description: "Good service citizen. Thank you.",
                choice: {
                    "01_COMPLETE": "Hang up."
                }
            }
        ]
    },
    {
        label: "W0.2.5.1",
        title: "MEETING: Waiting Commander %PLAYERNAME% for a chat.",
        steps: [
            {
                index: 1,
                description: "Hello citizen. You have to report the following info to agent %NAME2%.",
                choice: {
                    "01_GOTO_2": "\"Ok, I'm listening.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "...and that's all. Do your work. Goodbye.",
                choice: {
                    "01_NEXTTASK": "Hang up."
                }
            }
        ]
    },
    {
        label: "W0.2.5.2",
        title: "GALCOP: Waiting for Commander %PLAYERNAME%.",
        steps: [
            {
                index: 1,
                description: "Citizen, you can give me the info you gathered.",
                choice: {
                    "01_GOTO_2": "Report the data.",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Good service citizen. Thank you.",
                choice: {
                    "01_COMPLETE": "Hang up."
                }
            }
        ]
    },
    {
        label: "W0.3.3.1",
        title: "MEETING: Waiting Commander %PLAYERNAME% for a chat.",
        steps: [
            {
                index: 1,
                description: "I suppose you are here to pick the data I gathered.",
                choice: {
                    "01_GOTO_2": "\"Yes, GalCop sent me. They said it's an urgent matter.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Yes. I have sent you the data. Hurry and bring them back. Farewell.",
                choice: {
                    "01_NEXTTASK": "Take the data and hang up."
                }
            }
        ]
    },
    {
        label: "W0.3.3.2",
        title: "GALCOP: Waiting for Commander %PLAYERNAME%.",
        steps: [
            {
                index: 1,
                description: "Citizen, give us the data you obtained.",
                choice: {
                    "01_GOTO_2": "\"I'm just sending it to you.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "The data isn't corrupted. Good service citizen. Thank you.",
                choice: {
                    "01_COMPLETE": "Hang up."
                }
            }
        ]
    },
    {
        label: "W0.3.4.1",
        title: "MEETING: Waiting Commander %PLAYERNAME% for a chat.",
        steps: [
            {
                index: 1,
                description: "Hello citizen. Listen to me and report to the GalCop officer who sent you.",
                choice: {
                    "01_GOTO_2": "\"Ok, I'm listening.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "...and that's all. Do your work. Goodbye.",
                choice: {
                    "01_NEXTTASK": "Hang up."
                }
            }
        ]
    },
    {
        label: "W0.3.4.2",
        title: "GALCOP: Waiting for Commander %PLAYERNAME%.",
        steps: [
            {
                index: 1,
                description: "Citizen, give us the data you obtained.",
                choice: {
                    "01_GOTO_2": "Report the data.",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Good service citizen. Thank you.",
                choice: {
                    "01_COMPLETE": "Hang up."
                }
            }
        ]
    },
    {
        label: "W0.4",
        title: "GALCOP: Commander %PLAYERNAME%, get your payment.",
        steps: [
            {
                index: 1,
                description: "<Please accept the transaction to close the deal.>",
                choice: {
                    "01_COMPLETE": "Accept and hang up."
                }
            }
        ]
    },
    {
        label: "W0.4.7",
        title: "GALCOP: Commander %PLAYERNAME%, waiting to proceed.",
        steps: [
            {
                index: 1,
                description: "Hello citizen, can we proceed with the transfer?",
                choice: {
                    "01_NEXTTASK": "\"Yes, we can leave right now.\" and hang up.",
                    "99_QUIT": "\"Hold on while I make room.\" then hang up."
                }
            }
        ]
    },
    {
        label: "W0.4.8",
        title: "GALCOP: Looking for Commander %PLAYERNAME%.",
        steps: [
            {
                index: 1,
                description: "Hello, I'm %NAME1%, can we proceed with the transfer?",
                choice: {
                    "01_NEXTTASK": "\"We can leave now.\" and hang up.",
                    "99_QUIT": "\"Hold on while I make room.\" then hang up."
                }
            }
        ]
    },
    {
        label: "W0.4.12.1",
        title: "WAITING: Commander %PLAYERNAME%.",
        steps: [
            {
                index: 1,
                description: "Here you are. Let's get out of here NOW!",
                choice: {
                    "01_NEXTTASK": "\"Ok let's go.\" and hang up.",
                    "99_QUIT": "\"Hold on while I make room.\" then hang up."
                }
            }
        ]
    },
    // GalBook ----------------------------------------------------------------
    {
        label: "W1.1.1",
        title: "LOOK HERE: Commander %PLAYERNAME%, where is my book?",
        steps: [
            {
                index: 1,
                description: "Here we are. Do you have my book?",
                choice: {
                    "01_GOTO_2": "\"Yes, I have it right here.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Can you send it to me via the station network?",
                choice: {
                    "01_GOTO_3": "\"Done.\""
                }
            },
            {
                index: 3,
                description: "At last! '%BOOK%! I looked forward to this moment! Take your payment! Goodbye!",
                choice: {
                    "01_COMPLETE": "Hang up."
                }
            }
        ]
    },
    {
        label: "W1.2.3.1",
        title: "DELIVER: I have a book for Commander %PLAYERNAME%.",
        steps: [
            {
                index: 1,
                description: "Hello. I'm %NAME1%. I have a book for you.",
                choice: {
                    "01_GOTO_2": "\"Yes, please, send it to me.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Done. Please, keep it safe. It's a valuable copy.",
                choice: {
                    "01_NEXTTASK": "Hang up."
                }
            }
        ]
    },
    {
        label: "W1.2.3.2",
        title: "WAITING: Commander %PLAYERNAME% with my book.",
        steps: [
            {
                index: 1,
                description: "Here we are. Where's the book?",
                choice: {
                    "01_GOTO_2": "Send the book.",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Ah, perfect. Very good conditions - near mint. Thank you.",
                choice: {
                    "01_COMPLETE": "Hang up."
                }
            }
        ]
    },
    {
        label: "W1.3.2.1",
        title: "DELIVER: I have a book for Commander %PLAYERNAME%.",
        steps: [
            {
                index: 1,
                description: "Hello. I'm %NAME1%. I have a book for you.",
                choice: {
                    "01_GOTO_2": "\"Yes, please, send it to me.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Done. Bring my salutes to %NAME0%. Goodbye.",
                choice: {
                    "01_NEXTTASK": "Hang up."
                }
            }
        ]
    },
    {
        label: "W1.3.2.2",
        title: "WAITING: Commander %PLAYERNAME% with my book.",
        steps: [
            {
                index: 1,
                description: "You have returned at last. Where's the book?",
                choice: {
                    "01_GOTO_2": "Send the book.",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Ah, perfect. Thank you.",
                choice: {
                    "01_COMPLETE": "Hang up."
                }
            }
        ]
    },
    // GalChurch --------------------------------------------------------------
    {
        label: "W2.1.2",
        title: null,
        steps: [
            {
                index: 1,
                description: "Hi, I'm %NAME1%. What do you want?",
                choice: {
                    "01_GOTO_2": "\"Hmm... the Church of %SYSTEM1% wants you to read this sacred text and join them.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Ah.",
                choice: {
                    "01_GOTO_3": "\"I'm sending you the text.\""
                }
            },
            {
                index: 3,
                description: "Ok. Bye.",
                choice: {
                    "01_COMPLETE": "Hang up."
                }
            }
        ]
    },
    {
        label: "W2.2.3.1",
        title: "WAITING: Church envoy %PLAYERNAME%.",
        steps: [
            {
                index: 1,
                description: "Hello. I'm Acolyte %NAME1%. I will bring to your ship the holy alien artifacts for the transport.",
                choice: {
                    "01_GOTO_2": "\"Yes, thank you.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Done. My blessing to you and Acolyte %NAME2%. Goodbye.",
                choice: {
                    "01_NEXTTASK": "Hang up."
                }
            }
        ]
    },
    {
        label: "W2.2.3.2",
        title: "WAITING: Gentle %PLAYERNAME% with our sacred materials.",
        steps: [
            {
                index: 1,
                description: "I thank you, %PLAYERNAME%, for your service.",
                choice: {
                    "01_GOTO_2": "\"You're welcome. You can pick up the artifacts.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Holy alien artifacts, to be precise. Thank you. The Church bless you.",
                choice: {
                    "01_COMPLETE": "Hang up."
                }
            }
        ]
    },
    {
        label: "W2.3.1.1",
        title: "WAITING: Church envoy %PLAYERNAME%.",
        steps: [
            {
                index: 1,
                description: "Hello. I'm Acolyte %NAME1%. Can I send you the materials for Acolyte %NAME0%?.",
                choice: {
                    "01_GOTO_2": "\"Yes, thank you.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Done. My blessing to you and Acolyte %NAME0%. Goodbye.",
                choice: {
                    "01_NEXTTASK": "Hang up."
                }
            }
        ]
    },
    {
        label: "W2.3.1.2",
        title: "WAITING: Looking forward to encounter %PLAYERNAME% again.",
        steps: [
            {
                index: 1,
                description: "I thank you, %PLAYERNAME%, for your service.",
                choice: {
                    "01_GOTO_2": "\"You're welcome. Here are your materials.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Thank you. The church bless you.",
                choice: {
                    "01_COMPLETE": "Hang up."
                }
            }
        ]
    },
    {
        label: "W2.4",
        title: "CHURCH: Commander %PLAYERNAME%, get your payment.",
        steps: [
            {
                index: 1,
                description: "<Please accept the transaction to close the deal.>",
                choice: {
                    "01_COMPLETE": "Accept and hang up."
                }
            }
        ]
    },
    {
        label: "W2.4.6",
        title: "CHURCH: Commander %PLAYERNAME%, ready to leave.",
        steps: [
            {
                index: 1,
                description: "Hello kindred soul, I'm Priest %NAME1%. Can we proceed with the transfer?",
                choice: {
                    "01_NEXTTASK": "\"We can leave now.\" and hang up.",
                    "99_QUIT": "\"Hold on while I make room.\" then hang up."
                }
            }
        ]
    },
    {
        label: "W2.4.8",
        title: "CHURCH: Church followers eagerly waiting for Commander %PLAYERNAME%.",
        steps: [
            {
                index: 1,
                description: "Hello kindred soul, We are ready to start our pilgrimage.",
                choice: {
                    "01_NEXTTASK": "\"We can leave now.\" and hang up.",
                    "99_QUIT": "\"Hold on while I make room.\" then hang up."
                }
            }
        ]
    },
    // GalShady ---------------------------------------------------------------
    {
        label: "W3.1.1",
        title: "HELP: Dear friend %PLAYERNAME%, I'm waiting for you.",
        steps: [
            {
                index: 1,
                description: "Good day, friend. Do you have something for me?",
                choice: {
                    "01_GOTO_2": "\"Yes, some... 'useful data'.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Perfect. It's the data I like most!",
                choice: {
                    "01_GOTO_3": "\"Here you are.\""
                }
            },
            {
                index: 3,
                description: "Thank you, friend.",
                choice: {
                    "01_COMPLETE": "Hang up."
                }
            }
        ]
    },
    {
        label: "W3.2.3.1",
        title: "HURRY: %PLAYERNAME%, take away this thing.",
        steps: [
            {
                index: 1,
                description: "Hi, I'm %NAME1%, and you must pick up this thing. Deliver it to %NAME2% in the %SYSTEM2%.",
                choice: {
                    "01_GOTO_2": "\"Ok... but what is it?\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "The thing? It's... a thing. It seems a box but... Doesn't matter. I almost forgot! It's a surprise! %NAME2% doesn't know of the thing.",
                choice: {
                    "01_GOTO_3": "\"Ah... ok.\""
                }
            },
            {
                index: 3,
                description: "Do what you got to do. Goodbye.",
                choice: {
                    "01_NEXTTASK": "Hang up."
                }
            }
        ]
    },
    {
        label: "W3.2.3.2",
        title: null,
        steps: [
            {
                index: 1,
                description: "Hello, %NAME2% here, what do you want?",
                choice: {
                    "01_GOTO_2": "\"A th... box for you. A present.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "A present? Mh. Ok, send it to me.",
                choice: {
                    "01_GOTO_3": "\"Sent just now.\""
                }
            },
            {
                index: 3,
                description: "Bye.",
                choice: {
                    "01_COMPLETE": "Hang up."
                }
            }
        ]
    },
    {
        label: "W3.3.2.1",
        title: null,
        steps: [
            {
                index: 1,
                description: "Hello, I'm %NAME1%. What can I do for you?",
                choice: {
                    "01_GOTO_2": "\"%NAME0% wants some package back.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "%NAME0%? Hmm... yes I understand. Please wait a moment...",
                choice: {
                    "01_GOTO_3": "Wait."
                }
            },
            {
                index: 3,
                description: "I've sent you the package. Goodbye.",
                choice: {
                    "01_NEXTTASK": "Hang up."
                }
            }
        ]
    },
    {
        label: "W3.3.2.2",
        title: "WAITING: %PLAYERNAME% with my package.",
        steps: [
            {
                index: 1,
                description: "You have brought my package, right?",
                choice: {
                    "01_GOTO_2": "Send the package via the station network.",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Bye.",
                choice: {
                    "01_COMPLETE": "Hang up."
                }
            }
        ]
    },
    {
        label: "W3.4.4",
        title: "NOW: Commander %PLAYERNAME%, ready to leave.",
        steps: [
            {
                index: 1,
                description: "Let's get out of there.",
                choice: {
                    "01_NEXTTASK": "\"Ok.\" and hang up.",
                    "99_QUIT": "\"Hold on while I make room.\" then hang up."
                }
            }
        ]
    },
    {
        label: "W3.4.4",
        title: "WAITING: Commander %PLAYERNAME%, we are ready to leave.",
        steps: [
            {
                index: 1,
                description: "We can go now.",
                choice: {
                    "01_NEXTTASK": "\"Ok.\" and hang up.",
                    "99_QUIT": "\"Hold on while I make room.\" then hang up."
                }
            }
        ]
    },
    {
        label: "W3.4.9.1",
        title: "PASSAGE: Commander %PLAYERNAME%, I'm ready to leave.",
        steps: [
            {
                index: 1,
                description: "They send you to bring me to safety, right? Let's go now, I don't feel safe here.",
                choice: {
                    "01_NEXTTASK": "\"Ok.\" and hang up.",
                    "99_QUIT": "\"Hold on while I make room.\" then hang up."
                }
            }
        ]
    },
    // GalMedical -------------------------------------------------------------
    {
        label: "W4.1.1",
        title: "PSA: Medical team available here!",
        steps: [
            {
                index: 1,
                description: "Hello, I'm Doctor %NAME1%. There's something I can do for you?",
                choice: {
                    "01_GOTO_2": "\"Your colleagues from %SYSTEM0% want to know how goes the work.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Oh right. We're very busy and I forgot to update them. Thank you. I'll answer to them right now.",
                choice: {
                    "01_COMPLETE": "\"Perfect. Goodbye.\""
                }
            }
        ]
    },
    {
        label: "W4.1.2",
        title: "SCIENCE: Looking for professionals for medical research.",
        steps: [
            {
                index: 1,
                description: "Hello, I'm Doctor %NAME1%. There's something I can do for you?",
                choice: {
                    "01_GOTO_2": "\"Your colleagues from %SYSTEM0% want to know how goes the work.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Yes, I must update them on the stage of our research. It's going pretty well but the work is very intensive and leave us little time for other. Thanks for your reminding.",
                choice: {
                    "01_COMPLETE": "\"Ok then. Goodbye.\""
                }
            }
        ]
    },
    {
        label: "W4.2.5.1",
        title: "URGENT: Doctor %NAME1% looking for Commander %PLAYERNAME%.",
        steps: [
            {
                index: 1,
                description: "Hello. I'm Doctor %NAME1%. Are you here to take the donor blood?",
                choice: {
                    "01_GOTO_2": "\"Yes, you can do it now.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Ok, done. Thank you. Please hurry.",
                choice: {
                    "01_NEXTTASK": "Hang up."
                }
            }
        ]
    },
    {
        label: "W4.2.5.2",
        title: "HOSPITAL: Emergency!! Donor blood needed. Do your part.",
        steps: [
            {
                index: 1,
                description: "Do you have the donor blood we need?",
                choice: {
                    "01_GOTO_2": "\"Yes, taken from %NAME1%. You can pick it up now.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "This is a relief. Thank you. Goodbye.",
                choice: {
                    "01_COMPLETE": "Hang up."
                }
            }
        ]
    },
    {
        label: "W4.3.4.1",
        title: "PICK-UP: I'm Doctor %NAME1% and I'm looking for Commander %PLAYERNAME%",
        steps: [
            {
                index: 1,
                description: "Hello. I'm Doctor %NAME1%. I have a box of documents for you.",
                choice: {
                    "01_GOTO_2": "\"Yes, please, send it to me.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Done. Thank you. Goodbye.",
                choice: {
                    "01_NEXTTASK": "Hang up."
                }
            }
        ]
    },
    {
        label: "W4.3.4.2",
        title: "DOCUMENTS: Commander %PLAYERNAME% answer here when you return.",
        steps: [
            {
                index: 1,
                description: "Have you taken the documents I need?",
                choice: {
                    "01_GOTO_2": "Send all the documents.",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Thank you.",
                choice: {
                    "01_COMPLETE": "Hang up."
                }
            }
        ]
    },
    {
        label: "W4.4.11.1",
        title: "PICK-UP: Commander %PLAYERNAME% for ship-ambulance job.",
        steps: [
            {
                index: 1,
                description: "Hello, we have the passenger. Can we bring him into your ship?",
                choice: {
                    "01_GOTO_2": "\"Yes, please.\"",
                    "99_QUIT": "\"Hold on while I make room.\" then hang up."
                }
            },
            {
                index: 2,
                description: "Done. Please leave quickly. Goodbye.",
                choice: {
                    "01_NEXTTASK": "Hang up."
                }
            }
        ]
    },
    {
        label: "W4.4.11.2",
        title: "HOSPITAL: Waiting for Commander %PLAYERNAME% with a sick passenger.",
        steps: [
            {
                index: 1,
                description: "We are bringing the passenger to the hospital. Thanks for your service.",
                choice: {
                    "01_COMPLETE": "Hang up."
                }
            }
        ]
    },
    // GalCivic ---------------------------------------------------------------
    {
        label: "W5.1.1",
        title: null,
        steps: [
            {
                index: 1,
                description: "Hello, I'm %NAME1%. Do you have a package for me?",
                choice: {
                    "01_GOTO_2": "\"Yes, exactly.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Can you send it to me, please?",
                choice: {
                    "01_GOTO_3": "\"Just done.\""
                }
            },
            {
                index: 3,
                description: "Thank you, friend.",
                choice: {
                    "01_COMPLETE": "Hang up."
                }
            }
        ]
    },
    {
        label: "W5.1.2",
        title: null,
        steps: [
            {
                index: 1,
                description: "Hi, I'm %NAME1%. Can I do something for you?",
                choice: {
                    "01_GOTO_2": "\"I come from %SYSTEM0%. %NAME0% is worried about you and the family.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Oh! We had a lot of problem with the communication network here. We'll try to make contact again soon. Things aren't too bad. Thanks for your interest.",
                choice: {
                    "01_COMPLETE": "Hang up."
                }
            }
        ]
    },
    {
        label: "W5.3.3.1",
        title: "LOOK HERE: Commander %PLAYERNAME%, I have %ITEM% for you.",
        steps: [
            {
                index: 1,
                description: "Hello. I'm %NAME1%. Can I send you the stuff %NAME0% has forgotten here?",
                choice: {
                    "01_GOTO_2": "\"Yes, please, send it to me.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Thank you. Goodbye.",
                choice: {
                    "01_NEXTTASK": "Hang up."
                }
            }
        ]
    },
    {
        label: "W5.3.3.2",
        title: "ITEMS: Commander %PLAYERNAME%, bring back my stuff please!",
        steps: [
            {
                index: 1,
                description: "Where is my stuff?",
                choice: {
                    "01_GOTO_2": "\"Right here, I'll going to send it to you.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Thank you. I was desperate without.",
                choice: {
                    "01_COMPLETE": "(\"Go figure.\") Hang up."
                }
            }
        ]
    },
    {
        label: "W5.4.8.1",
        title: "HEY YOU: Commander %PLAYERNAME%, I'm waiting for you.",
        steps: [
            {
                index: 1,
                description: "Hi, I'm %NAME1%. Can we leave now? I have a bad feeling...",
                choice: {
                    "01_NEXTTASK": "\"Ok, let's leave.\" and hang up.",
                    "99_QUIT": "\"Hold on while I make room.\" then hang up."
                }
            }
        ]
    },
    // GalTourism missions ----------------------------------------------------
    {
        label: "W6.1.1",
        title: "DELUXOR HOTELS: Exaggerate luxury for a deluxe holiday!",
        steps: [
            {
                index: 1,
                description: "Hi, this is the DeLuxor hotels reception. What can I do for you?",
                choice: {
                    "01_GOTO_2": "\"I need to cancel a room reservation for %NAME0% from the %SYSTEM0% system.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Are you %NAME0%?",
                choice: {
                    "01_GOTO_3": "\"No. %NAME0% has employed me to attend this because he can't contact you. I'm sending you the documents I was given.\""
                }
            },
            {
                index: 3,
                description: "Hm. I see. We'll need a further confirmation from %NAME0%, though. Thanks, DeLuxor hotels wishes you a good day.",
                choice: {
                    "01_COMPLETE": "Hang up."
                }
            }
        ]
    },
    {
        label: "W6.2.2.1",
        title: "SPACEPORT: Baggage reclamation office open for service.",
        steps: [
            {
                index: 1,
                description: "Hi, I'm %NAME1%. Do you wish to collect your baggage?",
                choice: {
                    "01_GOTO_2": "\"Not mine, but %NAME2% baggage. Here's the documents.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Ok, I see. All right, you can collect the baggage. Good day.",
                choice: {
                    "01_NEXTTASK": "Hang up."
                }
            }
        ]
    },
    {
        label: "W6.2.2.2",
        title: "WAITING: Commander %PLAYERNAME% and my baggage.",
        steps: [
            {
                index: 1,
                description: "Hello, I'm %NAME2%. Do you have my baggage?",
                choice: {
                    "01_GOTO_2": "\"Yes, I've collected it from the %SYSTEM1% spaceport. I'm sending it to you.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Ooh thank you. I was very worried. Thanks again. Goodbye.",
                choice: {
                    "01_COMPLETE": "Hang up."
                }
            }
        ]
    },
    {
        label: "W6.3.3.1",
        title: "SPACEPORT: Baggage reclamation office open for service.",
        steps: [
            {
                index: 1,
                description: "Hi, I'm %NAME1%. Do you wish to collect your baggage?",
                choice: {
                    "01_GOTO_2": "\"Not mine, but %NAME0% baggage. Here's the documents.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Ok, I see. All right, you can collect the baggage. Good day.",
                choice: {
                    "01_NEXTTASK": "Hang up."
                }
            }
        ]
    },
    {
        label: "W6.3.3.2",
        title: "WAITING: Commander %PLAYERNAME% and my baggage.",
        steps: [
            {
                index: 1,
                description: "Welcome back, Commander. Do you have my baggage?",
                choice: {
                    "01_GOTO_2": "\"Yes, it's here. I'm sending it to you.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Thanks for your service. Goodbye.",
                choice: {
                    "01_COMPLETE": "Hang up."
                }
            }
        ]
    },
    {
        label: "W6.4",
        title: "DELUXOR: Commander %PLAYERNAME%, get your payment.",
        steps: [
            {
                index: 1,
                description: "<Please accept the transaction to close the deal.>",
                choice: {
                    "01_COMPLETE": "Accept and hang up."
                }
            }
        ]
    },
    // GalShopping missions ---------------------------------------------------

    // GalNature --------------------------------------------------------------
    {
        label: "W8.3.1.1",
        title: "BOTANICAL: Commander %PLAYERNAME%, plants specimens are ready for transport.",
        steps: [
            {
                index: 1,
                description: "I'm %NAME1%, a botanist. We have the specimens that you must return to %NAME0%.",
                choice: {
                    "01_GOTO_2": "\"Ok, bring them to my ship.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "We are going to the hangar. Hurry up.",
                choice: {
                    "01_NEXTTASK": "Hang up."
                }
            }
        ]
    },
    {
        label: "W8.3.1.2",
        title: "BOTANICAL: Commander %PLAYERNAME%, answer here to deliver the specimens.",
        steps: [
            {
                index: 1,
                description: "Can we take the plants specimens now?",
                choice: {
                    "01_GOTO_2": "\"Yes, you can take them.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Thank you. We'll provide better conditions for these plants. Goodbye.",
                choice: {
                    "01_COMPLETE": "Hang up."
                }
            }
        ]
    },
    // GalCulture -------------------------------------------------------------
    {
        label: "W9.1.1",
        title: "LOOK HERE: I'm waiting for Commander %PLAYERNAME%.",
        steps: [
            {
                index: 1,
                description: "Hello, I'm %NAME1% and you should have a painting for me.",
                choice: {
                    "01_GOTO_2": "\"Yes. '%PAINTING%'. I'm sending it to you.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "I can't wait to put it in my collection! Thank you, Commander.",
                choice: {
                    "01_COMPLETE": "Hang up."
                }
            }
        ]
    },
    {
        label: "W9.2.2.1",
        title: "RELOCATION: Waiting for appointee Commander %PLAYERNAME%.",
        steps: [
            {
                index: 1,
                description: "Hi, I'm %NAME1%. I believe you must transport '%PAINTING%' to the art gallery in %SYSTEM2%, right?",
                choice: {
                    "01_GOTO_2": "\"Yes, exactly. %NAME0% has sent me here.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Ok, I see. I'm taking the painting to your ship. Please be careful.",
                choice: {
                    "01_NEXTTASK": "Hang up."
                }
            }
        ]
    },
    {
        label: "W9.2.2.2",
        title: "OPENING SOON: Art gallery currently preparing next big painting exposition.",
        steps: [
            {
                index: 1,
                description: "Hello, I'm %NAME2%, what can I do for you?",
                choice: {
                    "01_GOTO_2": "\"I have a painting from %NAME1%, '%PAINTING%', for the gallery.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Oh yes, great! We are going to pick it up from your ship. Thanks for your work.",
                choice: {
                    "01_COMPLETE": "Hang up."
                }
            }
        ]
    },
    {
        label: "W9.3.3.1",
        title: "ART RESTORER: We'll give a new life to your old precious.",
        steps: [
            {
                index: 1,
                description: "Hi, I'm %NAME1%. Do you have something you want repaired?",
                choice: {
                    "01_GOTO_2": "\"No, thanks. %NAME1% has sent me to pick up a painting: '%PAINTING%'.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Oh yes, one of my better works. I'll take it to your ship. Thanks and goodbye.",
                choice: {
                    "01_NEXTTASK": "Hang up."
                }
            }
        ]
    },
    {
        label: "W9.3.3.2",
        title: "REMINDER: A painting from Commander %PLAYERNAME%",
        steps: [
            {
                index: 1,
                description: "Welcome back, Commander. Do you have my painting?",
                choice: {
                    "01_GOTO_2": "\"Yes, it's here. I'm sending it to you.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Ah, a very fine job. Thank you Commander. Goodbye.",
                choice: {
                    "01_COMPLETE": "Hang up."
                }
            }
        ]
    },
    // GalGovernment ----------------------------------------------------------
    {
        label: "W10.1.1",
        title: null,
        steps: [
            {
                index: 1,
                description: "Yes?",
                choice: {
                    "01_GOTO_2": "\"I come from %SYSTEM0%.\" Tell the given passcode.",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "I understand. I know I'm late with my report, but they always think everything is so easy... I'll send a detailed message very soon. No need to report back. Farewell.",
                choice: {
                    "01_COMPLETE": "Hang up."
                }
            }
        ]
    },
    {
        label: "W10.2.3.1",
        title: "DIPLOMACY: %SYSTEM0% consulate currently open to the public.",
        steps: [
            {
                index: 1,
                description: "Hello citizen. What can we do for you?",
                choice: {
                    "01_GOTO_2": "\"I was appointed by %SYSTEM0% government to transfer some diplomatic documents to %SYSTEM2%.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Yes, we received communication. We are sending the documents to you. Thanks citizen. Goodbye.",
                choice: {
                    "01_NEXTTASK": "Hang up."
                }
            }
        ]
    },
    {
        label: "W10.2.3.2",
        title: "DIPLOMACY: %SYSTEM0% consulate currently open to the public.",
        steps: [
            {
                index: 1,
                description: "Hello citizen. What can we do for you?",
                choice: {
                    "01_GOTO_2": "\"I was appointed by %SYSTEM0% government to transfer some diplomatic documents from %SYSTEM1%.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Yes, we received communication.",
                choice: {
                    "01_GOTO_3": "\"I'm sending the documents to you right now.\""
                }
            },
            {
                index: 3,
                description: "Thanks citizen. Goodbye.",
                choice: {
                    "01_COMPLETE": "Hang up."
                }
            }
        ]
    },
    {
        label: "W10.3.2.1",
        title: null,
        steps: [
            {
                index: 1,
                description: "I'm %NAME1% Can I do something for you?",
                choice: {
                    "01_GOTO_2": "\"The %SYSTEM0% government has sent me here.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "I understand. I'm sending you the documents. Keep them safe.",
                choice: {
                    "01_NEXTTASK": "Hang up."
                }
            }
        ]
    },
    {
        label: "W10.3.2.2",
        title: "GOVERNMENT: Front office open for Commander %PLAYERNAME%.",
        steps: [
            {
                index: 1,
                description: "The stolen dossiers?",
                choice: {
                    "01_GOTO_2": "\"Here they are, I'm sending them to you.\"",
                    "99_QUIT": "Hang up."
                }
            },
            {
                index: 2,
                description: "Good service citizen. Your government is proud of you.",
                choice: {
                    "01_COMPLETE": "Hang up."
                }
            }
        ]
    },
    {
        label: "W10.4.8.1",
        title: "DIPLOMATIC: Waiting for Commander %PLAYERNAME% for the trip back home.",
        steps: [
            {
                index: 1,
                description: "Hello citizen. We are escorting glorious officer %NAME1% to your ship. We can leave just after.",
                choice: {
                    "01_NEXTTASK": "\"Ok.\" and hang up.",
                    "99_QUIT": "\"Hold on while I make room.\" then hang up."
                }
            }
        ]
    },
    {
        label: "W10.4.9.1",
        title: "NOSTALGIC: Commander %PLAYERNAME%, let's get back home.",
        steps: [
            {
                index: 1,
                description: "Hello citizen. I'm %NAME1%. I'm ready to left for %SYSTEM0%, when you're ready.",
                choice: {
                    "01_NEXTTASK": "\"Ok, let's go.\" and hang up.",
                    "99_QUIT": "\"Hold on while I make room.\" then hang up."
                }
            }
        ]
    }
];

this.missionStore = [
    // GalCop Missions --------------------------------------------------------
    // CONTACT
    {
        groupId: 0,
        index: 1,
        title: "GALCOP: Deliver sensitive info to an agent.",
        description: "Hello citizen. We need a pilot for the delivery of sensitive informations to our agent %NAME1%, currently in the %SYSTEM1% system. GalCop will pay %REWARD% credits.",
        choices: "mission",
        currentTask: 1,
        parcel: "A GalCop information drive",
        customResponses: {
            money: [ "Just the ordinary GalCop payment." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 1, // CONTACT
                description: "Go to the %SYSTEM1% system, and deliver sensitive informations to agent %NAME1%.",
                generate: { systems: 1, names: 1 },
                waitingMission: "W0.1.1",
                unaware: true
            }
        ]
    },
    {
        groupId: 0,
        index: 2,
        title: "GALCOP: Deliver equipment to an agent.",
        description: "Hello citizen. Our agent %NAME1%, currently in the %SYSTEM1% system, need some equipment. We do not have transport going that way. GalCop will pay %REWARD% credits.",
        choices: "mission",
        currentTask: 1,
        parcel: "A GalCop equipment kit",
        customResponses: {
            money: [ "Just the ordinary GalCop payment." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 1, // CONTACT
                description: "Go to the %SYSTEM1% system, and deliver equipment to agent %NAME1%.",
                generate: { systems: 1, names: 1 },
                waitingMission: "W0.1.2",
                unaware: true

            }
        ]
    },
    // TRANSFER
    {
        groupId: 0,
        index: 5,
        title: "GALCOP: Courier needed.",
        description: "Hello citizen, we have agent %NAME1% in the %SYSTEM1% that must transmit important info to agent %NAME2% in %SYSTEM2%. We don't trust normal comm channels this time, so we resort to a courier. GalCop will pay %REWARD% credits.",
        choices: "mission",
        currentTask: 1,
        customResponses: {
            money: [ "Just the ordinary GalCop payment." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 2, // TRANSFER
                description: "Go to the %SYSTEM1% system and meet with agent %NAME1%. Bring the info to %SYSTEM2%.",
                generate: { systems: 1, names: 1 },
                parcel: "A GalCop information drive",
                waitingMission: "W0.2.5.1"
            },
            {
                index: 2,
                typeId: 2, // TRANSFER
                description: "Bring the info to agent %NAME2%, in the %SYSTEM2% system.",
                generate: { systems: 1, names: 1 },
                waitingMission: "W0.2.5.2"
            }
        ]
    },
    // RETRIEVE
    {
        groupId: 0,
        index: 3,
        title: "GALCOP: A fast ship to retrieve data from an agent.",
        description: "Hello citizen, we need someone to go to the %SYSTEM1% system and meet our agent %NAME1%. We need the data that will be delivered to you. GalCop will pay %REWARD% credits.",
        choices: "mission",
        currentTask: 1,
        customResponses: {
            money: [ "Just the ordinary GalCop payment." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 3, // RETRIEVE
                description: "Go to the %SYSTEM1% system, meet with agent %NAME1% to pick up the data, and return to %SYSTEM0%.",
                generate: { systems: 1, names: 1 },
                parcel: "A GalCop information drive",
                waitingMission: "W0.3.3.1",
                urgent: true
            },
            {
                index: 2,
                typeId: 3, // RETRIEVE
                description: "Bring back the data to the GalCop officer in the %SYSTEM0% system.",
                generate: {
                    retrieve: true
                },
                waitingMission: "W0.3.3.2"
            }
        ]
    },
    {
        groupId: 0,
        index: 4,
        title: "GALCOP: Contact an agent and report info.",
        description: "Hello citizen, we need someone to report us the last informations from our agent %NAME1% in the to the %SYSTEM1% system. GalCop will pay %REWARD% credits.",
        choices: "mission",
        currentTask: 1,
        customResponses: {
            money: [ "Just the ordinary GalCop payment." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 3, // RETRIEVE
                description: "Go to the %SYSTEM1% system and meet with agent %NAME1%. Report to the GalCop officer in the %SYSTEM0% system.",
                generate: { systems: 1, names: 1 },
                parcel: "A GalCop information drive",
                waitingMission: "W0.3.4.1",
                urgent: true
            },
            {
                index: 2,
                typeId: 3, // RETRIEVE
                description: "Report to the GalCop officer in the %SYSTEM0% system.",
                generate: {
                    retrieve: true
                },
                waitingMission: "W0.3.4.2"
            }
        ]
    },
    // TRANSPORT
    {
        groupId: 0,
        index: 6,
        title: "GALCOP: Transport an agent to another system.",
        description: "Hello citizen, I need a ship to transport me to the GalCop center in the %SYSTEM1%. GalCop will pay %REWARD% credits.",
        choices: "transport",
        currentTask: 1,
        passengers: [ 1 ],
        firstPassenger: 0,
        customResponses: {
            money: [ "Just the ordinary GalCop payment." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring agent %NAME0% to the %SYSTEM1% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1 },
                waitingMission: "W0.4"
            }
        ]
    },
    {
        groupId: 0,
        index: 7,
        title: "GALCOP: A ship for an agent relocation.",
        description: "Hello citizen, we need someone to transport an agent from the GalCop center in the %SYSTEM1% to the one in %SYSTEM2%. GalCop will pay %REWARD% credits.",
        choices: "transport",
        currentTask: 1,
        customResponses: {
            money: [ "Just the ordinary GalCop payment." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring GalCop agent from the %SYSTEM1% system to %SYSTEM2%. Remember to check the BBS to get your payment.",
                generate: { systems: 1, names: 1 },
                waitingMission: "W0.4.7",
                passengers: [ 1 ]
            },
            {
                index: 2,
                typeId: 4, // TRANSPORT
                description: "Bring GalCop agent to the %SYSTEM2% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1 },
                waitingMission: "W0.4"
            }
        ]
    },
    {
        groupId: 0,
        index: 8,
        title: "GALCOP: Bring back an agent to this station.",
        description: "Hello citizen, we need someone to transport an agent here from the GalCop center in the %SYSTEM1%. GalCop will pay %REWARD% credits.",
        choices: "transport",
        currentTask: 1,
        customResponses: {
            money: [ "Just the ordinary GalCop payment." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring GalCop agent from the %SYSTEM1% system to %SYSTEM0%. Remember to check the BBS to get your payment.",
                generate: { systems: 1, names: 1 },
                waitingMission: "W0.4.7",
                passengers: [ 1 ]
            },
            {
                index: 2,
                typeId: 4, // TRANSPORT
                description: "Bring GalCop agent to the %SYSTEM0% system. Remember to check the BBS to get your payment.",
                generate: {
                    retrieve: true
                },
                waitingMission: "W0.4"
            }
        ]
    },
    {
        groupId: 0,
        index: 9,
        title: "GALCOP: Transport a witness to a trial.",
        description: "Hello citizen, we need someone to transport an important witness to a trial to be held in the %SYSTEM1%. GalCop will pay %REWARD% credits.",
        choices: "transport",
        currentTask: 1,
        passengers: [ 1 ],
        risk: 1,
        customResponses: {
            money: [ "Just the ordinary GalCop payment." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring witness %NAME0% to the trial in the %SYSTEM1% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1 },
                waitingMission: "W0.4"
            }
        ]
    },
    {
        groupId: 0,
        index: 10,
        title: "GALCOP: Transport a witness to a trial.",
        description: "Hello citizen, we need someone to transport an important witness in the %SYSTEM1% system to a trial to be held in %SYSTEM2%. GalCop will pay %REWARD% credits.",
        choices: "transport",
        currentTask: 1,
        risk: 1,
        customResponses: {
            money: [ "Just the ordinary GalCop payment." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Go to the %SYSTEM1% system to pickup a witness, and bring him to a trial in %SYSTEM2%. Remember to check the BBS to get your payment.",
                generate: { systems: 1, names: 1 },
                waitingMission: "W0.4.8",
                passengers: [ 1 ]
            },
            {
                index: 2,
                typeId: 4, // TRANSPORT
                description: "Bring witness %NAME1% to a trial in the %SYSTEM2% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1 },
                waitingMission: "W0.4"
            }
        ]
    },
    {
        groupId: 0,
        index: 12,
        title: "GALCOP: Emergency transport for an agent.",
        description: "Hello citizen. An agent needs to be extracted ASAP from the %SYSTEM1% system. You have to transport here where we will transfer him in a secure location. GalCop will pay %REWARD% credits.",
        choices: "transport",
        currentTask: 1,
        risk: 2,
        customResponses: {
            money: [ "This is an emergency situation." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring GalCop agent from the %SYSTEM1% system to %SYSTEM0%. Remember to check the BBS to get your payment.",
                generate: { systems: 1, names: 1 },
                waitingMission: "W0.4.12.1",
                urgent: true,
                passengers: [ 1 ]
            },
            {
                index: 2,
                typeId: 4, // TRANSPORT
                description: "Bring GalCop agent to the %SYSTEM0% system. Remember to check the BBS to get your payment.",
                generate: {
                    retrieve: true
                },
                urgent: true,
                waitingMission: "W0.4"
            }
        ]
    },
    {
        groupId: 0,
        index: 13,
        title: "GALCOP: Help for a political personality.",
        description: "Hello citizen. We need someone to pick up a dissident politician, %NAME1%, from the %SYSTEM1% system and transport him to %SYSTEM2%. This is an urgent mission, as his government is still searching for him.",
        choices: "transport",
        currentTask: 1,
        risk: 1,
        customResponses: {
            money: [ "This is an emergency situation." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring dissident %NAME1% from the %SYSTEM1% system to %SYSTEM0%. Remember to check the BBS to get your payment.",
                generate: { systems: 1, names: 1 },
                waitingMission: "W0.4.7",
                urgent: true,
                passengers: [ 1 ]
            },
            {
                index: 2,
                typeId: 4, // TRANSPORT
                description: "Bring dissident %NAME1% to the %SYSTEM0% system. Remember to check the BBS to get your payment.",
                generate: {
                    retrieve: true
                },
                urgent: true,
                waitingMission: "W0.4"
            }
        ]
    },
    // CARGO
    {
        groupId: 0,
        index: 11,
        title: "GALCOP: Looking for a ship to transport cargo.",
        description: "Hello citizen, we need someone to transport a shipment of %GOODS% to the %SYSTEM1% system. GalCop will pay %REWARD% credits.",
        choices: "cargo",
        currentTask: 1,
        risk: 1,
        customResponses: {
            money: [ "Just the ordinary GalCop payment." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 5, // CARGO
                description: "Bring a shipment of %GOODS% to the %SYSTEM1% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1, goods: 1 },
                waitingMission: "G3"
            }
        ]
    },
    // GalBook Missions -------------------------------------------------------
    // CONTACT
    {
        groupId: 1,
        index: 1,
        title: "NOTICE: Book delivery to another system.",
        description: "Hi, I'm %NAME0% and I sold '%BOOK%' to %NAME1%, but I have no way to hand over the book. Could you help me? I will pay %REWARD% credits.",
        choices: "mission",
        currentTask: 1,
        parcel: "A copy of '%BOOK%'",
        customResponses: {
            money: [ "These are old books - ancient, I could say." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 1, // CONTACT
                description: "Go to the %SYSTEM1% system, and deliver '%BOOK%' to %NAME1%.",
                generate: { systems: 1, names: 1, books: 1 },
                waitingMission: "W1.1.1"
            }
        ]
    },
    // TRANSFER
    {
        groupId: 1,
        index: 3,
        title: "SHIP REQUESTED: A safe transfer for a book.",
        description: "Hello, I'm %NAME0% and I received a request for a transfer job. %NAME1% in the %SYSTEM1% wants a safe passage for a copy of '%BOOK%' to %NAME2% in %SYSTEM2%. What do you think? I pay %REWARD% credits.",
        choices: "mission",
        currentTask: 1,
        customResponses: {
            money: [ "These are old books - ancient, I could say." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 2, // TRANSFER
                description: "Go to the %SYSTEM1% system and get '%BOOK%' from %NAME1%. Bring the book to %SYSTEM2%.",
                generate: { systems: 1, names: 1, books: 1 },
                parcel: "A copy of '%BOOK%'",
                waitingMission: "W1.2.3.1"
            },
            {
                index: 2,
                typeId: 2, // TRANSFER
                description: "Deliver '%BOOK%' to %NAME2% in the %SYSTEM2% system.",
                generate: { systems: 1, names: 1 },
                waitingMission: "W1.2.3.2"
            }
        ]
    },
    // RETRIEVE
    {
        groupId: 1,
        index: 2,
        title: "SHIP REQUESTED: I need to get back a book.",
        description: "Hi, I'm %NAME0% and I have bought '%BOOK%' from %NAME1% in the %SYSTEM1% system, but I have no way to get the book. Can you help me? I pay %REWARD% credits.",
        choices: "mission",
        currentTask: 1,
        customResponses: {
            money: [ "These are old books - ancient, I could say." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 3, // RETRIEVE
                description: "Go to the %SYSTEM1% system and get '%BOOK%' from %NAME1%. Return to the %SYSTEM0% system.",
                generate: { systems: 1, names: 1, books: 1 },
                parcel: "A copy of '%BOOK%'",
                waitingMission: "W1.3.2.1"
            },
            {
                index: 2,
                typeId: 3, // RETRIEVE
                description: "Bring '%BOOK%' to %NAME0% in the %SYSTEM0% system.",
                generate: {
                    retrieve: true
                },
                waitingMission: "W1.3.2.2"
            }
        ]
    },
    // CARGO
    {
        groupId: 1,
        index: 4,
        title: "SHIPMENT: Can you transport some stuff?",
        description: "Hello. I'm %NAME0%. My business needs to send a shipment of %GOODS% to the %SYSTEM1% system. We will pay %REWARD% credits.",
        choices: "cargo",
        currentTask: 1,
        customResponses: {
            money: [ "We're talking about valuable books." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 5, // CARGO
                description: "Bring a shipment of %GOODS% to the %SYSTEM1% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1, goods: 1 },
                waitingMission: "G3"
            }
        ]
    },
    // GalChurch Missions -----------------------------------------------------
    // CONTACT
    {
        groupId: 2,
        index: 2,
        title: "INSPIRATION: Contact a wise man to join our Church.",
        description: "Hello, kindred soul. We know that there is a wise being in the %SYSTEM1% system, under the name %NAME1%. Could you bring our sacred text to him? We would like to invite him to our Church. We will pay you %REWARD% credits for this service.",
        choices: "mission",
        currentTask: 1,
        parcel: "A sacred text",
        customResponses: {
            money: [ "The Church is generous." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 1, // CONTACT
                description: "Go to the %SYSTEM1% system, and talk to the wise %NAME1%.",
                generate: { systems: 1, names: 1 },
                waitingMission: "W2.1.2",
                unaware: true
            }
        ]
    },
    // TRANSFER
    {
        groupId: 2,
        index: 3,
        title: "SACRED: We need a ship to transfer some holy alien artifacts.",
        description: "Hello, kindred soul. I'm Acolyte %NAME0% and in behalf of the Church I need someone to pickup some holy alien artifacts from Acolyte %NAME1% of the Church of %SYSTEM1%, artifacts that will be transported to Acolyte %NAME2% of the Church of %SYSTEM2%. The church will pay %REWARD% credits.",
        choices: "mission",
        currentTask: 1,
        customResponses: {
            money: [ "The Church is generous." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 2, // TRANSFER
                description: "Go to the %SYSTEM1% system and get the holy alien artifacts from Acolyte %NAME1%. Bring the artifacts to the %SYSTEM2% system.",
                generate: { systems: 1, names: 1 },
                parcel: "Some alien artifacts",
                waitingMission: "W2.2.3.1"
            },
            {
                index: 2,
                typeId: 2, // TRANSFER
                description: "Bring the artifacts to Acolyte %NAME2% in the %SYSTEM2% system.",
                generate: { systems: 1, names: 1 },
                waitingMission: "W2.2.3.2"
            }
        ]
    },
    // RETRIEVE
    {
        groupId: 2,
        index: 1,
        title: "HOLY: We need to transport back some Church material.",
        description: "Hello, kindred soul. I'm Acolyte %NAME0% and in behalf of the Church I need someone to bring here various materials currently in possession of Acolyte %NAME1% od the Church of %SYSTEM1%. The Church will pay %REWARD% credits for your service.",
        choices: "mission",
        currentTask: 1,
        customResponses: {
            money: [ "The Church is generous." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 3, // RETRIEVE
                description: "Go to the %SYSTEM1% system and get the Church materials from Acolyte %NAME1%. Return to the %SYSTEM0% system.",
                generate: { systems: 1, names: 1 },
                parcel: "Boxes of religious materials",
                waitingMission: "W2.3.1.1"
            },
            {
                index: 2,
                typeId: 3, // RETRIEVE
                description: "Bring the Church materials to Acolyte %NAME0% in the %SYSTEM0% system.",
                generate: {
                    retrieve: true
                },
                waitingMission: "W2.3.1.2"
            }
        ]
    },
    // TRANSPORT
    {
        groupId: 2,
        index: 4,
        title: "SPIRITUAL: An eminent priest is awaited for a religious service.",
        description: "Hello, kindred soul. I'm Acolyte %NAME0% and in behalf of the Church I need someone to bring Priest %NAME1% to the Church of %SYSTEM1%. The Church will pay %REWARD% credits for your service.",
        choices: "transport",
        currentTask: 1,
        passengers: [ 1 ],
        firstPassenger: 1,
        customResponses: {
            money: [ "The Church is generous." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring Priest %NAME1% to the %SYSTEM1% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1, names: 1 },
                waitingMission: "W2.4"
            }
        ]
    },
    {
        groupId: 2,
        index: 5,
        title: "SHIP WANTED: A group of missionaries is leaving for another system.",
        description: "Hello, kindred soul. I'm Acolyte %NAME0% and in behalf of the Church I need someone to bring a group of missionaries to the %SYSTEM1% system. The Church will pay %REWARD% credits for your service.",
        choices: "transport",
        currentTask: 1,
        passengers: [ 3, 7 ],
        customResponses: {
            money: [ "The Church is generous." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring a group of %PASSENGERS% missionaries to the %SYSTEM1% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1 },
                waitingMission: "W2.4"
            }
        ]
    },
    {
        groupId: 2,
        index: 6,
        title: "SPIRITUAL: An eminent priest is awaited for a religious service.",
        description: "Hello, kindred soul. I'm Acolyte %NAME0% and in behalf of the Church I need someone to bring Priest %NAME1% from the %SYSTEM1% system to the Church of %SYSTEM2%. The Church will pay %REWARD% credits for your service.",
        choices: "transport",
        currentTask: 1,
        customResponses: {
            money: [ "The Church is generous." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring Priest %NAME1% from the %SYSTEM1% system to %SYSTEM2%. Remember to check the BBS to get your payment.",
                generate: { systems: 1, names: 1 },
                waitingMission: "W2.4.6",
                passengers: [ 1 ]
            },
            {
                index: 2,
                typeId: 4, // TRANSPORT
                description: "Bring Priest %NAME1% to the %SYSTEM2% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1 },
                waitingMission: "W2.4"
            }
        ]
    },
    {
        groupId: 2,
        index: 7,
        title: "TRANSFER: Moving a priest from one church to another.",
        description: "Hello, kindred soul. I'm Acolyte %NAME0% and in behalf of the Church I need someone to bring Priest %NAME1% from the Church of %SYSTEM1% to the %SYSTEM2% system. The Church will pay %REWARD% credits for your service.",
        choices: "transport",
        currentTask: 1,
        customResponses: {
            money: [ "The Church is generous." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring Priest %NAME1% from the %SYSTEM1% system to %SYSTEM2%. Remember to check the BBS to get your payment.",
                generate: { systems: 1, names: 1 },
                waitingMission: "W2.4.6",
                passengers: [ 1 ]
            },
            {
                index: 2,
                typeId: 4, // TRANSPORT
                description: "Bring Priest %NAME1% to the %SYSTEM2% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1 },
                waitingMission: "W2.4"
            }
        ]
    },
    {
        groupId: 2,
        index: 8,
        title: "PILGRIMAGE: A group of faithful followers needs help.",
        description: "Hello, kindred soul. I'm Acolyte %NAME0% and in behalf of the Church I need someone to bring a group of followers from the %SYSTEM1% system to a sanctuary in %SYSTEM2%. The Church will pay %REWARD% credits for your service.",
        choices: "transport",
        currentTask: 1,
        customResponses: {
            money: [ "The Church is generous." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring a group of followers from the %SYSTEM1% system to %SYSTEM2%. Remember to check the BBS to get your payment.",
                generate: { systems: 1, names: 7 },
                waitingMission: "W2.4.8",
                passengers: [ 3, 7 ]
            },
            {
                index: 2,
                typeId: 4, // TRANSPORT
                description: "Bring a group of followers to the %SYSTEM2% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1 },
                waitingMission: "W2.4"
            }
        ]
    },
    // GalShady Missions ------------------------------------------------------
    // CONTACT
    {
        groupId: 3,
        index: 1,
        title: "URGENT: We need someone to deliver important data to an affiliate.",
        description: "Hi. I'm %NAME0%. I need a ship to deliver some... useful data to %NAME1% in the %SYSTEM1% system. The pay is %REWARD% credits.",
        choices: "mission",
        parcel: "A unlabeled data drive",
        currentTask: 1,
        tasks: [
            {
                index: 1,
                typeId: 1, // CONTACT
                description: "Go to the %SYSTEM1% system, and deliver 'useful data' to %NAME1%.",
                generate: { systems: 1, names: 1 },
                waitingMission: "W3.1.1",
                urgent: true
            }
        ]
    },
    // TRANSFER
    {
        groupId: 3,
        index: 3,
        title: "SWITCH: We need to move something from a system to another.",
        description: "Hi. I'm %NAME0%. There's a thing in the %SYSTEM1% that has to be moved somewhere else... Talk to %NAME1% for the details. If you accept, the payment is %REWARD% credits.",
        choices: "mission",
        currentTask: 1,
        customResponses: {
            money: [ "It's better if we do it fast." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 2, // TRANSFER
                description: "Go to the %SYSTEM1% system and get 'the thing' from %NAME1%.",
                generate: { systems: 1, names: 1 },
                parcel: "A strange package",
                waitingMission: "W3.2.3.1",
                urgent: true
            },
            {
                index: 2,
                typeId: 2, // TRANSFER
                description: "Bring 'the thing' to %NAME2% in the %SYSTEM2% system.",
                hideSystemData: true,
                generate: { systems: 1, names: 1 },
                waitingMission: "W3.2.3.2",
                unaware: true
            }
        ]
    },
    // RETRIEVE
    {
        groupId: 3,
        index: 2,
        title: "JOB OFFER: We need to retrieve a package.",
        description: "Hi. I'm %NAME0%. There's a person in the %SYSTEM1% system that must give me something. The name is %NAME1%. Can you retrieve the package for me? I pay %REWARD% credits.",
        choices: "mission",
        currentTask: 1,
        customResponses: {
            money: [ "I must have that package back." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 3, // RETRIEVE
                description: "Go to the %SYSTEM1% system and get the package from %NAME1%. Return to the %SYSTEM0% system.",
                generate: { systems: 1, names: 1 },
                parcel: "A somewhat trivial package",
                waitingMission: "W3.3.2.1",
                unaware: true
            },
            {
                index: 2,
                typeId: 3, // RETRIEVE
                description: "Bring the package to %NAME0% in the %SYSTEM0% system.",
                generate: {
                    retrieve: true
                },
                waitingMission: "W3.3.2.2"
            }
        ]
    },
    // TRANSPORT
    {
        groupId: 3,
        index: 4,
        title: "URGENT: We need to quickly transport an affiliate away from a system.",
        description: "Hi. %NAME1% is actually in the %SYSTEM1% system, but he's in danger and he needs to move away as soon as possible. Destination is %SYSTEM2%. The payment is %REWARD% credits.",
        choices: "transport",
        currentTask: 1,
        risk: 2,
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring %NAME1% from the %SYSTEM1% system to %SYSTEM2%. Remember to check the BBS to get your payment.",
                generate: { systems: 1, names: 1 },
                urgent: true,
                waitingMission: "W3.4.4",
                passengers: [ 1 ]
            },
            {
                index: 2,
                typeId: 4, // TRANSPORT
                description: "Bring %NAME1% to the %SYSTEM2% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1 },
                urgent: true,
                waitingMission: "G1"
            }
        ]
    },
    {
        groupId: 3,
        index: 5,
        title: "SHIP REQUESTED: A business trip.",
        description: "Hi. A group of traders needs a passage from the %SYSTEM1% system to %SYSTEM2%. We will pay %REWARD% credits.",
        choices: "transport",
        currentTask: 1,
        risk: 1,
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring a group of traders from the %SYSTEM1% system to %SYSTEM2%. Remember to check the BBS to get your payment.",
                generate: { systems: 1, names: 7 },
                urgent: true,
                waitingMission: "W3.4.5",
                passengers: [ 3, 7 ]
            },
            {
                index: 2,
                typeId: 4, // TRANSPORT
                description: "Bring a group of trader to the %SYSTEM2% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1 },
                urgent: true,
                waitingMission: "G1"
            }
        ]
    },
    {
        groupId: 3,
        index: 9,
        title: "RESCUE: Bring here an affiliate.",
        description: "Hi, we lost contact with %NAME1% a long ago, but recently he reappeared in the %SYSTEM1%. Could you bring him here? Payment is %REWARD% credits.",
        choices: "transport",
        currentTask: 1,
        risk: 1,
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring %NAME1% from the %SYSTEM1% system to %SYSTEM0%. Remember to check the BBS to get your payment.",
                generate: { systems: 1, names: 1 },
                waitingMission: "W3.4.9.1",
                passengers: [ 1 ]
            },
            {
                index: 2,
                typeId: 4, // TRANSPORT
                description: "Bring %NAME1% to the %SYSTEM0% system. Remember to check the BBS to get your payment.",
                generate: {
                    retrieve: true
                },
                waitingMission: "G1"
            }
        ]
    },
    // CARGO
    {
        groupId: 3,
        index: 6,
        title: "SHIP REQUESTED: I need to move stuff.",
        description: "Hi. I needs to deliver a shipment of %GOODS% to the %SYSTEM1% system. The pay is %REWARD% credits.",
        choices: "cargo",
        currentTask: 1,
        risk: 2,
        tasks: [
            {
                index: 1,
                typeId: 5, // CARGO
                description: "Bring a shipment of %GOODS% to the %SYSTEM1% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1, goods: 1 },
                waitingMission: "G3"
            }
        ]
    },
    {
        groupId: 3,
        index: 7,
        title: "URGENT: I need to regain my goods.",
        description: "Hi, I have a shipment of %GOODS% in the %SYSTEM1% system and I need someone who will take it here. Are you interested? Payment is %REWARD% credits.",
        choices: "cargo",
        currentTask: 1,
        risk: 1,
        tasks: [
            {
                index: 1,
                typeId: 5, // CARGO
                description: "Bring a shipment of %GOODS% from the %SYSTEM1% system to %SYSTEM0%. Remember to check the BBS to get your payment.",
                generate: { systems: 1, goods: 1 },
                waitingMission: "G3.1",
                urgent: true
            },
            {
                index: 1,
                typeId: 5, // CARGO
                description: "Bring a shipment of %GOODS% to the %SYSTEM0% system. Remember to check the BBS to get your payment.",
                generate: { retrieve: true },
                waitingMission: "G3",
                urgent: true
            }
        ]
    },
    {
        groupId: 3,
        index: 8,
        title: "ONLY INTERESTED: Discreet goods relocation.",
        description: "Hi, we need someone to relocate a shipment of %GOODS% from the %SYSTEM1% system to %SYSTEM2%. Payment is %REWARD% credits.",
        choices: "cargo",
        currentTask: 1,
        customResponses: {
            money: [ "Commercial stuff, we can say." ]
        },
        risk: 1,
        tasks: [
            {
                index: 1,
                typeId: 5, // CARGO
                description: "Bring a shipment of %GOODS% from the %SYSTEM1% system to %SYSTEM2%. Remember to check the BBS to get your payment.",
                generate: { systems: 1, goods: 1 },
                waitingMission: "G3.1"
            },
            {
                index: 1,
                typeId: 5, // CARGO
                description: "Bring a shipment of %GOODS% to the %SYSTEM2% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1 },
                waitingMission: "G3"
            }
        ]
    },
    // GalMedical missions ----------------------------------------------------
    // CONTACT
    {
        groupId: 4,
        index: 1,
        title: "MISSING: Someone to give updates about a medical team.",
        description: "Hello, I'm %NAME0%. We have no news from our medical team in the %SYSTEM1% system. Could you get in touch with them? Doctor %NAME1% is the team leader. The pay is %REWARD% credits.",
        choices: "mission",
        currentTask: 1,
        parcel: "A holomessage drive",
        customResponses: {
            money: [ "Communication with our teams is essential." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 1, // CONTACT
                description: "Go to the %SYSTEM1% system, and find Doctor %NAME1%.",
                generate: { systems: 1, names: 1 },
                waitingMission: "W4.1.1",
                unaware: true
            }
        ]
    },
    {
        groupId: 4,
        index: 2,
        title: "MISSING: Someone to give updates about a research group.",
        description: "Hello, I'm %NAME0%. We have no news from our research group in the %SYSTEM1% system. Could you get in touch with them? %NAME1% is the lead researcher. The pay is %REWARD% credits.",
        choices: "mission",
        currentTask: 1,
        parcel: "A holomessage drive",
        customResponses: {
            money: [ "Communication with our teams is essential." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 1, // CONTACT
                description: "Go to the %SYSTEM1% system, and find the lead researcher %NAME1%.",
                generate: { systems: 1, names: 1 },
                waitingMission: "W4.1.2",
                unaware: true
            }
        ]
    },
    {
        groupId: 4,
        index: 3,
        title: "MISSING: Someone to give updates about an emergency team.",
        description: "Hello, I'm %NAME0%. We have no news from our emergency team in the %SYSTEM1% system. Could you get in touch with them? Doctor %NAME1% is the head of the team. The pay is %REWARD% credits.",
        choices: "mission",
        currentTask: 1,
        customResponses: {
            money: [ "Communication with our teams is essential." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 1, // CONTACT
                description: "Go to the %SYSTEM1% system, and find the Doctor %NAME1%.",
                generate: { systems: 1, names: 1 },
                waitingMission: "W4.1.1",
                unaware: true
            }
        ]
    },
    // TRANSFER
    {
        groupId: 4,
        index: 5,
        title: "URGENT: A fast ship for transport of rare donor blood.",
        description: "Hi, I'm Doctor %NAME1%. We have an emergency at a hospital on %SYSTEM2%. We need someone who can pick up a special donor blood type from %SYSTEM1% and bring to the hospital. The pay is %REWARD% credits.",
        choices: "mission",
        currentTask: 1,
        customResponses: {
            money: [ "It's an urgent matter." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 2, // TRANSFER
                description: "Go to the %SYSTEM1% system and get the donor blood from Doctor %NAME1%. Transport the blood to %SYSTEM2%.",
                generate: { systems: 1, names: 1 },
                parcel: "Special donor blood bags",
                waitingMission: "W4.2.5.1",
                urgent: true
            },
            {
                index: 2,
                typeId: 2, // TRANSFER
                description: "Bring the donor blood to Doctor %NAME2% in the %SYSTEM2% system.",
                generate: { systems: 1, names: 1 },
                waitingMission: "W4.2.5.2",
                urgent: true
            }
        ]
    },
    // RETRIEVE
    {
        groupId: 4,
        index: 4,
        title: "SHIP REQUESTED: We need clinical records from another system.",
        description: "Hello, I'm Doctor %NAME0% and I need someone to bring me back some boxes of documents that have been left to Doctor %NAME1% in the %SYSTEM1% system. I will pay %REWARD% credits.",
        choices: "mission",
        currentTask: 1,
        customResponses: {
            money: [ "It's nothing special, really." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 3, // RETRIEVE
                description: "Go to the %SYSTEM1% system and get the documents from Doctor %NAME1%. Return to the %SYSTEM0% system.",
                generate: { systems: 1, names: 1 },
                parcel: "Boxes full of medical papers",
                waitingMission: "W4.3.4.1"
            },
            {
                index: 2,
                typeId: 3, // RETRIEVE
                description: "Bring the documents to Doctor %NAME0% in the %SYSTEM0% system.",
                generate: {
                    retrieve: true
                },
                waitingMission: "W4.3.4.2"
            }
        ]
    },
    // TRANSPORT
    {
        groupId: 4,
        index: 6,
        title: "EMERGENCY: Fast travel for a medic.",
        description: "Hello, I'm Doctor %NAME0% and I need to go quickly to the %SYSTEM1% system. I have to help other teams to contain a viral epidemic. I will pay %REWARD% credits.",
        choices: "transport",
        currentTask: 1,
        passengers: [ 1 ],
        firstPassenger: 0,
        customResponses: {
            money: [ "It's an urgent matter." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring Doctor %NAME0% to the %SYSTEM1% system as quickly as you can. Remember to check the BBS to get your payment.",
                generate: { systems: 1 },
                urgent: true,
                waitingMission: "G1"
            }
        ]
    },
    {
        groupId: 4,
        index: 7,
        title: "SHIP REQUESTED: Transport for a medical team.",
        description: "Hello, I'm Doctor %NAME0%. I'm looking for someone to transport me and my team to the %SYSTEM1% system. I will pay %REWARD% credits.",
        choices: "transport",
        currentTask: 1,
        passengers: [ 3, 7 ],
        firstPassenger: 0,
        customResponses: {
            money: [ "The soon we go, the better." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring Doctor %NAME0% and his team (%PASSENGERS% people) to the %SYSTEM1% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1 },
                waitingMission: "G1"
            }
        ]
    },
    {
        groupId: 4,
        index: 8,
        title: "SHIP REQUESTED: Transport for a research team.",
        description: "Hello, I'm Doctor %NAME0%. I'm looking for someone to transport me and my team to the %SYSTEM1% system. I will pay %REWARD% credits.",
        choices: "transport",
        currentTask: 1,
        passengers: [ 3, 7 ],
        firstPassenger: 0,
        customResponses: {
            money: [ "The soon we go, the better." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring Doctor %NAME0% and his team (%PASSENGERS% people) to the %SYSTEM1% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1 },
                waitingMission: "G1"
            }
        ]
    },
    {
        groupId: 4,
        index: 11,
        title: "EMERGENCY: Need transport for a sick %RACE%.",
        description: "Hello citizen, I'm Doctor %NAME0%. There's a sick %RACE% in the %SYSTEM1% that needs vital cures that we only can provide in our structures. You must pick him up and return back here as fast as possible. His sickness isn't contagious. We will pay you %REWARD% credits.",
        choices: "transport",
        currentTask: 1,
        failureDead: true,
        customResponses: {
            money: [ "It's an emergency." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring thw sick %RACE% from the %SYSTEM1% system to %SYSTEM0%. Remember to check the BBS to get your payment.",
                generate: { systems: 1, names: 1, races: 1 },
                waitingMission: "W4.4.11.1",
                urgent: true,
                passengers: [ 1 ]
            },
            {
                index: 2,
                typeId: 4, // TRANSPORT
                description: "Bring the sick %RACE% to the %SYSTEM0% system. Remember to check the BBS to get your payment.",
                generate: {
                    retrieve: true
                },
                urgent: true,
                waitingMission: "W4.4.11.2"
            }
        ]
    },
    {
        groupId: 4,
        index: 12,
        title: "EMERGENCY: Need transport for a sick %RACE%.",
        description: "Hello citizen, I'm Doctor %NAME0%. We have a sick %RACE% that we need to move in a specialized hospital in the %SYSTEM1%. His sickness isn't contagious. We will pay you %REWARD% credits.",
        choices: "transport",
        currentTask: 1,
        passengers: [ 1 ],
        firstPassenger: 1,
        customResponses: {
            money: [ "It's an emergency." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring thw sick %RACE% to the %SYSTEM1% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1, races: 1 },
                urgent: true,
                waitingMission: "W4.4.11.2"
            }
        ]
    },
    {
        groupId: 4,
        index: 13,
        title: "SHIP REQUESTED: Bring back a medic.",
        description: "Hello, I'm Doctor %NAME0%. Doctor %NAME1% has completed a series of emergency visits and needs someone to get back on %SYSTEM0%. I will pay %REWARD% credits.",
        choices: "transport",
        currentTask: 1,
        customResponses: {
            money: [ "Nothing special, really." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Go to the %SYSTEM1% system and bring back Doctor %NAME% to %SYSTEM0%. Remember to check the BBS to get your payment.",
                generate: { systems: 1, names: 1 },
                waitingMission: "G4",
                passengers: [ 1 ]
            },
            {
                index: 2,
                typeId: 4, // TRANSPORT
                description: "Bring back Doctor %NAME% to the %SYSTEM0% system. Remember to check the BBS to get your payment.",
                generate: {
                    retrieve: true
                },
                waitingMission: "G1"
            }
        ]
    },
    {
        groupId: 4,
        index: 14,
        title: "SHIP REQUESTED: Bring back a medical team.",
        description: "Hello, I'm Doctor %NAME0%. I'm looking for someone to transport here a medical team from the %SYSTEM1% system. Doctor %NAME1% is the team leader. I will pay %REWARD% credits.",
        choices: "transport",
        currentTask: 1,
        customResponses: {
            money: [ "The team has completed its work, and needs to get back home." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring Doctor %NAME1% and his medical team (%PASSENGERS% people) from the %SYSTEM1% system to %SYSTEM0%. Remember to check the BBS to get your payment.",
                generate: { systems: 1, names: 7 },
                waitingMission: "G4",
                passengers: [ 3, 7 ]
            },
            {
                index: 2,
                typeId: 4, // TRANSPORT
                description: "Bring Doctor %NAME1% and his medical team (%PASSENGERS% people) to the %SYSTEM0% system. Remember to check the BBS to get your payment.",
                generate: {
                    retrieve: true
                },
                waitingMission: "G1"
            }
        ]
    },
    {
        groupId: 4,
        index: 15,
        title: "SHIP REQUESTED: Bring back a research team.",
        description: "Hello, I'm Doctor %NAME0%. I'm looking for someone to transport here the research team of Doctor %NAME1% from the %SYSTEM1% system. I will pay %REWARD% credits.",
        choices: "transport",
        currentTask: 1,
        customResponses: {
            money: [ "The team has completed its studies and we need the data." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring Doctor %NAME1% and his research team (%PASSENGERS% people) from the %SYSTEM1% system to %SYSTEM0%. Remember to check the BBS to get your payment.",
                generate: { systems: 1, names: 7 },
                waitingMission: "G4",
                passengers: [ 3, 7 ]
            },
            {
                index: 2,
                typeId: 4, // TRANSPORT
                description: "Bring Doctor %NAME1% and his research team (%PASSENGERS% people) to the %SYSTEM0% system. Remember to check the BBS to get your payment.",
                generate: {
                    retrieve: true
                },
                waitingMission: "G1"
            }
        ]
    },
    // CARGO
    {
        groupId: 4,
        index: 9,
        title: "SHIPMENT: Need ship for transporting medical equipment.",
        description: "Hello. I'm %NAME0%. We are going to deliver a shipment of %GOODS% to the %SYSTEM1% system. We will pay %REWARD% credits.",
        choices: "cargo",
        currentTask: 1,
        customResponses: {
            money: [ "People lives depend on this." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 5, // CARGO
                description: "Bring a shipment of %GOODS% to the %SYSTEM1% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1, goods: 1 },
                waitingMission: "G3"
            }
        ]
    },
    {
        groupId: 4,
        index: 10,
        title: "URGENT: We need this stuff as soon as possible!",
        description: "Hello, I'm Doctor %NAME0%. There's shipment of %GOODS% from the %SYSTEM1% that we need quickly. If you accept, we will pay you %REWARD% credits.",
        choices: "cargo",
        currentTask: 1,
        customResponses: {
            money: [ "Timing is essential." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 5, // CARGO
                description: "Bring a shipment of %GOODS% from the %SYSTEM1% system to %SYSTEM0%. Remember to check the BBS to get your payment.",
                generate: { systems: 1, goods: 1 },
                urgent: true,
                waitingMission: "G3.1"
            },
            {
                index: 1,
                typeId: 5, // CARGO
                description: "Bring a shipment of %GOODS% to the %SYSTEM0% system. Remember to check the BBS to get your payment.",
                generate: { retrieve: true },
                urgent: true,
                waitingMission: "G3"
            }
        ]
    },
    // GalCivic missions ------------------------------------------------------
    // CONTACT
    {
        groupId: 5,
        index: 1,
        title: "WANTED: A ship to deliver a package.",
        description: "Hello, I'm %NAME0%. I need a ship to deliver a package to %NAME1% in the %SYSTEM1% system. The pay is %REWARD% credits.",
        choices: "mission",
        currentTask: 1,
        parcel: "A package",
        customResponses: {
            money: [ "[litf_missionResponseMoneyParcel]" ] // this.litf_missionResponseMoneyParcel
        },
        tasks: [
            {
                index: 1,
                typeId: 1, // CONTACT
                description: "Go to the %SYSTEM1% system, and deliver a package to %NAME1%.",
                generate: { systems: 1, names: 1 },
                waitingMission: "W5.1.1"
            }
        ]
    },
    {
        groupId: 5,
        index: 2,
        title: "NEED HELP: I wish for some news from my family.",
        description: "Hi, I'm %NAME0% and I had no news of my family lately. Can you help me? You should looking for %NAME1%, a relative of mine. I'll pay %REWARD% credits for this.",
        choices: "mission",
        parcel: "A holomessage player",
        currentTask: 1,
        tasks: [
            {
                index: 1,
                typeId: 1, // CONTACT
                description: "Go to the %SYSTEM1% system, and look for %NAME1%.",
                generate: { systems: 1, names: 1 },
                waitingMission: "W5.1.2",
                unaware: true
            }
        ]
    },
    // TRANSFER

    // RETRIEVE
    {
        groupId: 5,
        index: 3,
        title: "TAKE BACK: I forgotten %ITEM% in another system.",
        description: "Hi, I'm %NAME0%, and I left %ITEM% in the %SYSTEM1% system. You can ask to my friend %NAME1% there. I'll pay %REWARD% credits.",
        choices: "mission",
        currentTask: 1,
        customResponses: {
            money: [ "Sentimental value." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 3, // RETRIEVE
                description: "Go to the %SYSTEM1% system and get %ITEM% from %NAME1%. Return to the %SYSTEM0% system.",
                generate: { systems: 1, names: 1, items: 1 },
                parcel: "%ITEM%",
                waitingMission: "W5.3.3.1"
            },
            {
                index: 2,
                typeId: 3, // RETRIEVE
                description: "Return %ITEM% to %NAME0% in the %SYSTEM0% system.",
                generate: {
                    retrieve: true
                },
                waitingMission: "W5.3.3.2"
            }
        ]
    },
    // TRANSPORT
    {
        groupId: 5,
        index: 4,
        title: "TAXI JOB: Ship for one.",
        description: "Hello, I'm %NAME0%. I need to go to the %SYSTEM1% system. I will pay %REWARD% credits.",
        choices: "transport",
        currentTask: 1,
        passengers: [ 1 ],
        firstPassenger: 0,
        customResponses: {
            money: [ "[litf_missionResponseMoneyPassenger]" ]
        },
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring %NAME0% to the %SYSTEM1% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1 },
                waitingMission: "G1"
            }
        ]
    },
    {
        groupId: 5,
        index: 5,
        title: "TAXI JOB: Ship for a group.",
        description: "Hello, I'm %NAME0%. Me and my friends need to go to the %SYSTEM1% system. I will pay %REWARD% credits.",
        choices: "transport",
        currentTask: 1,
        passengers: [ 3, 7 ],
        firstPassenger: 0,
        customResponses: {
            money: [ "[litf_missionResponseMoneyGroup]" ]
        },
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring %PASSENGERS% people to the %SYSTEM1% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1 },
                waitingMission: "G1"
            }
        ]
    },
    {
        groupId: 5,
        index: 8,
        title: "DISCRETION: Need a passage for a person.",
        description: "Hello, I'm %NAME0%. My friend %NAME1% needs a ship to go from the %SYSTEM1% system to %SYSTEM2%. He is a little paranoid about someone following him. If you accept, the payment is %REWARD%.",
        choices: "transport",
        currentTask: 1,
        risk: 1,
        customResponses: {
            money: [ "I hope this guarantee a safe passage." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring %NAME1% from the %SYSTEM1% system to %SYSTEM2%. Remember to check the BBS to get your payment.",
                generate: { systems: 1, names: 1 },
                waitingMission: "W5.4.8.1",
                passengers: [ 1 ]
            },
            {
                index: 2,
                typeId: 4, // TRANSPORT
                description: "Bring %NAME1% to the %SYSTEM2% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1 },
                waitingMission: "G1"
            }
        ]
    },
    {
        groupId: 5,
        index: 9,
        title: "DISCRETION: Need to transport someone here.",
        description: "Hello, I'm %NAME0%. My friend %NAME1% needs a ship to come here from the %SYSTEM1% system. He is a little paranoid about someone following him. If you accept, the payment is %REWARD%.",
        choices: "transport",
        currentTask: 1,
        risk: 1,
        customResponses: {
            money: [ "I hope this guarantee a safe passage." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring %NAME1% from the %SYSTEM1% system to %SYSTEM0%. Remember to check the BBS to get your payment.",
                generate: { systems: 1, names: 1 },
                waitingMission: "W5.4.8.1",
                passengers: [ 1 ]
            },
            {
                index: 2,
                typeId: 4, // TRANSPORT
                description: "Bring %NAME1% to the %SYSTEM0% system. Remember to check the BBS to get your payment.",
                generate: {
                    retrieve: true
                },
                waitingMission: "G1"
            }
        ]
    },
    // CARGO
    {
        groupId: 5,
        index: 6,
        title: "CARGO: Help me moving stuff.",
        description: "Hello. I'm %NAME0%. I need to deliver a shipment of %GOODS% to the %SYSTEM1% system. We will pay %REWARD% credits.",
        choices: "cargo",
        currentTask: 1,
        customResponses: {
            money: [ "Nothing special, really." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 5, // CARGO
                description: "Bring a shipment of %GOODS% to the %SYSTEM1% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1, goods: 1 },
                waitingMission: "G3"
            }
        ]
    },
    {
        groupId: 5,
        index: 7,
        title: "HELP: I need someone to regain a bunch of stuff.",
        description: "Hello, I'm %NAME0%. I had a shipment of %GOODS% that has been blocked in the %SYSTEM1% system. Now I can retake it but I don't have a ship. Can you do it for me? I'll pay you %REWARD% credits.",
        choices: "cargo",
        currentTask: 1,
        customResponses: {
            money: [ "I don't want to lose more credits." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 5, // CARGO
                description: "Bring a shipment of %GOODS% from the %SYSTEM1% system to %SYSTEM0%. Remember to check the BBS to get your payment.",
                generate: { systems: 1, goods: 1 },
                waitingMission: "G3.1"
            },
            {
                index: 1,
                typeId: 5, // CARGO
                description: "Bring a shipment of %GOODS% to the %SYSTEM0% system. Remember to check the BBS to get your payment.",
                generate: { retrieve: true },
                waitingMission: "G3"
            }
        ]
    },
    // GalTourism missions ----------------------------------------------------
    // CONTACT
    {
        groupId: 6,
        index: 1,
        title: "URGENT: Need to cancel a booking.",
        description: "Hello, I'm %NAME0%. I had some issue and I have to cancel a booking for a room at the DeLuxor hotel in %SYSTEM1%, but I can't reach the customer care. Can you go and cancel the booking at the hotel reception? I'll give you the necessary documents. %REWARD% credits for the job.",
        choices: "mission",
        currentTask: 1,
        parcel: "A folder of documents",
        customResponses: {
            money: [ "We want to attend this matter without wasting other time." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 1, // CONTACT
                description: "Go to the %SYSTEM1% system, and cancel %NAME0% booking to the DeLuxor hotel.",
                generate: { systems: 1, names: 1 },
                waitingMission: "W6.1.1",
                unaware: true
            }
        ]
    },
    // TRANSFER
    {
        groupId: 6,
        index: 2,
        title: "HELP NEEDED: Someone to transfer baggage misdirected at another system.",
        description: "Hi, I'm %NAME1%. Because of a travel agency mistake, my friend %NAME2% baggage is currently at the wrong system. You should go to the %SYSTEM1% system and bring the baggage to %SYSTEM2%. I'll give you my friend documents for the reclamation process. The pay is %REWARD% credits.",
        choices: "mission",
        currentTask: 1,
        customResponses: {
            money: [ "My friend wants to recover his things as soon as possible." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 2, // TRANSFER
                description: "Go to the %SYSTEM1% system, get %NAME2% baggage and bring it to %SYSTEM2%.",
                generate: { systems: 1, names: 1 },
                parcel: "A bunch of baggages and trolleys",
                waitingMission: "W6.2.2.1",
                unaware: true
            },
            {
                index: 2,
                typeId: 2, // TRANSFER
                description: "Bring %NAME2% baggage to the %SYSTEM2% system.",
                generate: { systems: 1, names: 1 },
                waitingMission: "W6.2.2.2"
            }
        ]
    },
    // RETRIEVE
    {
        groupId: 6,
        index: 3,
        title: "HELP NEEDED: Someone to recover baggage misdirected at another system.",
        description: "Hi, I'm %NAME1%. Because of a travel agency mistake, my baggage is currently at the wrong system. You should go to the %SYSTEM1% system and bring back the baggage to me. I'll give you the documents for the reclamation process. The pay is %REWARD% credits.",
        choices: "mission",
        currentTask: 1,
        customResponses: {
            money: [ "I want to recover my things as soon as possible." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 3, // RETRIEVE
                description: "Go to the %SYSTEM1% system, get %NAME0% baggage and bring it back to %SYSTEM0%.",
                generate: { systems: 1, names: 1 },
                parcel: "A bunch of baggages and trolleys",
                waitingMission: "W6.3.3.1",
                unaware: true
            },
            {
                index: 2,
                typeId: 3, // RETRIEVE
                description: "Bring %NAME0% baggage back to the %SYSTEM0% system.",
                generate: {
                    retrieve: true
                },
                waitingMission: "W6.3.3.2"
            }
        ]
    },
    // TRANSPORT
    {
        groupId: 6,
        index: 4,
        title: "HELP US: Group of stranded tourists without passage.",
        description: "Hello, we are a group of tourist and we have lost the travel agency ship for our Hotel in the %SYSTEM1% system. Can you bring us there? I will pay %REWARD% credits.",
        choices: "transport",
        currentTask: 1,
        passengers: [ 3, 7 ],
        firstPassenger: 0,
        customResponses: {
            money: [ "[litf_missionResponseMoneyGroup]" ]
        },
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring %PASSENGERS% people to the %SYSTEM1% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1 },
                waitingMission: "W6.4"
            }
        ]
    },
    // CARGO
    {
        groupId: 6,
        index: 5,
        title: "DELUXOR: We need to deliver materials.",
        description: "Hello. I'm %NAME0%. We are going to deliver a shipment of %GOODS% to the %SYSTEM1% system. We will pay %REWARD% credits.",
        choices: "cargo",
        currentTask: 1,
        customResponses: {
            money: [ "This stuff goes to a DeLuxor hotel." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 5, // CARGO
                description: "Bring a shipment of %GOODS% to the %SYSTEM1% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1, goods: 1 },
                waitingMission: "G3"
            }
        ]
    },
    {
        groupId: 6,
        index: 6,
        title: "DELUXOR: Someone to deliver us materials.",
        description: "Hello, I'm %NAME0%. We need a shipment of %GOODS% from the %SYSTEM1%. We pay %REWARD% credits.",
        choices: "cargo",
        currentTask: 1,
        customResponses: {
            money: [ "We need this shipment for a DeLuxor hotel." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 5, // CARGO
                description: "Bring a shipment of %GOODS% from the %SYSTEM1% system to %SYSTEM0%. Remember to check the BBS to get your payment.",
                generate: { systems: 1, goods: 1 },
                waitingMission: "G3.1"
            },
            {
                index: 1,
                typeId: 5, // CARGO
                description: "Bring a shipment of %GOODS% to the %SYSTEM0% system. Remember to check the BBS to get your payment.",
                generate: { retrieve: true },
                waitingMission: "G3"
            }
        ]
    },
    // GalShopping missions ---------------------------------------------------
    // CONTACT

    // TRANSFER

    // RETRIEVE

    // TRANSPORT

    // CARGO
    {
        groupId: 7,
        index: 1,
        title: "COMMERCIAL: Need a ship to deliver cargo to another system.",
        description: "Hello. I'm %NAME0%. My business needs to send a shipment of %GOODS% to the %SYSTEM1% system. We will pay %REWARD% credits.",
        choices: "cargo",
        currentTask: 1,
        customResponses: {
            money: [ "It's a simple commercial trip." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 5, // CARGO
                description: "Bring a shipment of %GOODS% to the %SYSTEM1% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1, goods: 1 },
                waitingMission: "G3"
            }
        ]
    },
    {
        groupId: 7,
        index: 2,
        title: "COMMERCIAL: Need a ship to deliver cargo.",
        description: "Hello. I'm %NAME0%. My business needs to send a shipment of %GOODS% from the %SYSTEM1% system to %SYSTEM2%. We will pay %REWARD% credits.",
        choices: "cargo",
        currentTask: 1,
        customResponses: {
            money: [ "It's a simple commercial trip." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 5, // CARGO
                description: "Bring a shipment of %GOODS% from the %SYSTEM1% system to %SYSTEM2%. Remember to check the BBS to get your payment.",
                generate: { systems: 1, goods: 1 },
                waitingMission: "G3.1"
            },
            {
                index: 1,
                typeId: 5, // CARGO
                description: "Bring a shipment of %GOODS% to the %SYSTEM2% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1 },
                waitingMission: "G3"
            }
        ]
    },
    {
        groupId: 7,
        index: 3,
        title: "COMMERCIAL: Need a ship to bring cargo here.",
        description: "Hello. I'm %NAME0%. My business needs to bring here a shipment of %GOODS% from the %SYSTEM1% system. We will pay %REWARD% credits.",
        choices: "cargo",
        currentTask: 1,
        customResponses: {
            money: [ "It's a simple commercial trip." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 5, // CARGO
                description: "Bring a shipment of %GOODS% from the %SYSTEM1% system to %SYSTEM0%. Remember to check the BBS to get your payment.",
                generate: { systems: 1, goods: 1 },
                waitingMission: "G3.1"
            },
            {
                index: 1,
                typeId: 5, // CARGO
                description: "Bring a shipment of %GOODS% to the %SYSTEM0% system. Remember to check the BBS to get your payment.",
                generate: { retrieve: true },
                waitingMission: "G3"
            }
        ]
    },
    // GalNature missions -----------------------------------------------------
    // CONTACT

    // TRANSFER

    // RETRIEVE
    {
        groupId: 8,
        index: 1,
        title: "IMPORTANT: Someone with a ship to recover plants specimens.",
        description: "Hello, A botanical facility on %SYSTEM1% has broken down and we need to store some plants specimens. We'll warning of your arrive if you accept. We will pay %REWARD% credits.",
        choices: "mission",
        currentTask: 1,
        customResponses: {
            money: [ "It's an important matter for us." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 3, // RETRIEVE
                description: "Go to the %SYSTEM1% system and get the plants specimens. Return to the %SYSTEM0% system.",
                generate: { systems: 1, names: 1 },
                parcel: "A insulated box of plants specimen",
                waitingMission: "W8.3.1.1"
            },
            {
                index: 2,
                typeId: 3, // RETRIEVE
                description: "Bring the plants specimens to %NAME0% in the %SYSTEM0% system.",
                generate: {
                    retrieve: true
                },
                waitingMission: "W8.3.1.2"
            }
        ]
    },
    // TRANSPORT
    {
        groupId: 8,
        index: 2,
        title: "JOB OFFER: Need ship for transport.",
        description: "Hi, I'm %NAME0%. I need a ship to go to the %SYSTEM1% system. Are you interested? I will pay %REWARD% credits.",
        choices: "transport",
        currentTask: 1,
        passengers: [ 1 ],
        firstPassenger: 0,
        customResponses: {
            money: [ "I'm completing a thesis in [litf_missionResponseMoneyNatureJob]." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring naturalist %NAME1% to the %SYSTEM1% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1, names: 1 },
                waitingMission: "G1"
            }
        ]
    },
    {
        groupId: 8,
        index: 3,
        title: "JOB OFFER: Need ship for transport.",
        description: "Hello, I'm %NAME0%. A naturalist in the %SYSTEM1% needs a passage to %SYSTEM2%. The payment is %REWARD% credits.",
        choices: "transport",
        currentTask: 1,
        customResponses: {
            money: [ "He's a [litf_missionResponseMoneyNatureJob] expert." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring naturalist %NAME1% from the %SYSTEM1% system to %SYSTEM2%. Remember to check the BBS to get your payment.",
                generate: { systems: 1, names: 1 },
                waitingMission: "G2",
                passengers: [ 1 ]
            },
            {
                index: 2,
                typeId: 4, // TRANSPORT
                description: "Bring naturalist %NAME1% to the %SYSTEM2% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1 },
                waitingMission: "G1"
            }
        ]
    },
    {
        groupId: 8,
        index: 4,
        title: "JOB OFFER: Need ship for transport.",
        description: "Hi, I'm %NAME0%. We need to bring back a naturalist from the %SYSTEM1% system. We will pay %REWARD% credits.",
        choices: "transport",
        currentTask: 1,
        customResponses: {
            money: [ "He's a [litf_missionResponseMoneyNatureJob] scholar." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring naturalist %NAME1% from the %SYSTEM1% system to %SYSTEM0%. Remember to check the BBS to get your payment.",
                generate: { systems: 1, names: 1 },
                waitingMission: "G2",
                passengers: [ 1 ]
            },
            {
                index: 2,
                typeId: 4, // TRANSPORT
                description: "Bring naturalist to the %SYSTEM0% system. Remember to check the BBS to get your payment.",
                generate: {
                    retrieve: true
                },
                waitingMission: "G1"
            }
        ]
    },
    // CARGO
    {
        groupId: 8,
        index: 5,
        title: "SHIP REQUESTED: Deliver materials to another system.",
        description: "Hi, I'm %NAME0%. We need to deliver a shipment of %GOODS% to the %SYSTEM1% system. Payment is %REWARD% credits.",
        choices: "cargo",
        currentTask: 1,
        customResponses: {
            money: [ "Normal scientific stuff." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 5, // CARGO
                description: "Bring a shipment of %GOODS% to the %SYSTEM1% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1, goods: 1 },
                waitingMission: "G3"
            }
        ]
    },
    {
        groupId: 8,
        index: 6,
        title: "STUDY: Looking for a ship to transport materials here.",
        description: "Hello, I'm %NAME0%, and I need the %GOODS% we left in the %SYSTEM1% system. Are you interested? We pay %REWARD% credits.",
        choices: "cargo",
        currentTask: 1,
        customResponses: {
            money: [ "Normal scientific stuff." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 5, // CARGO
                description: "Bring a shipment of %GOODS% from the %SYSTEM1% system to %SYSTEM0%. Remember to check the BBS to get your payment.",
                generate: { systems: 1, goods: 1 },
                waitingMission: "G3.1"
            },
            {
                index: 1,
                typeId: 5, // CARGO
                description: "Bring a shipment of %GOODS% to the %SYSTEM0% system. Remember to check the BBS to get your payment.",
                generate: { retrieve: true },
                waitingMission: "G3"
            }
        ]
    },
    // GalCulture missions ----------------------------------------------------
    // CONTACT
    {
        groupId: 9,
        index: 1,
        title: "DELIVER: A painting to a buyer.",
        description: "Hello, I'm %NAME0%. I need a ship to transport the '%PAINTING%' painting to a buyer in the %SYSTEM1% system. The buyer name is %NAME1%. I'll pay you %REWARD% credits.",
        choices: "mission",
        currentTask: 1,
        parcel: "The '%PAINTING% painting",
        customResponses: {
            money: [ "It's a really good painting." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 1, // CONTACT
                description: "Go to the %SYSTEM1% system, and give the '%PAINTING%' painting to %NAME1%.",
                generate: { systems: 1, names: 1, paintings: 1 },
                waitingMission: "W9.1.1"
            }
        ]
    },
    // TRANSFER
    {
        groupId: 9,
        index: 2,
        title: "TRANSFER: Move a painting to its new location.",
        description: "Hello, I'm %NAME0%. We are preparing a new art gallery in the %SYSTEM2% system where we want to display the '%PAINTING%' painting, actually owned by %NAME1% in %SYSTEM1%. Do you mind to proceed to its relocation? We'll pay %REWARD% credits.",
        choices: "mission",
        currentTask: 1,
        customResponses: {
            money: [ "It's a really good painting." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 2, // TRANSFER
                description: "Go to the %SYSTEM1% system, get the '%PAINTING%' painting and bring it to %SYSTEM2%.",
                generate: { systems: 1, names: 1, paintings: 1 },
                parcel: "The '%PAINTING% painting",
                waitingMission: "W9.2.2.1"
            },
            {
                index: 2,
                typeId: 2, // TRANSFER
                description: "Bring the '%PAINTING%' to the %SYSTEM2% system.",
                generate: { systems: 1, names: 1 },
                waitingMission: "W9.2.2.2"
            }
        ]
    },
    // RETRIEVE
    {
        groupId: 9,
        index: 3,
        title: "RECOVER: A painting from an art restorer.",
        description: "Hello, I'm %NAME0% and I have to retrieve the '%PAINTING%' painting from an art restorer in %SYSTEM1%. I need someone who'll pickup the painting because in this moment I have no way to do it. Interested? The pay is %REWARD% credits.",
        choices: "mission",
        currentTask: 1,
        customResponses: {
            money: [ "It's a really good painting." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 3, // RETRIEVE
                description: "Go to the %SYSTEM1% system, get the '%PAINTING%' painting and return to the %SYSTEM0% system.",
                generate: { systems: 1, names: 1, paintings: 1 },
                parcel: "The '%PAINTING% painting",
                waitingMission: "W9.3.3.1",
                unaware: true
            },
            {
                index: 2,
                typeId: 3, // RETRIEVE
                description: "Bring the '%PAINTING%' painting to %NAME0% in the %SYSTEM0% system.",
                generate: {
                    retrieve: true
                },
                waitingMission: "W9.3.3.2"
            }
        ]
    },
    // TRANSPORT
    {
        groupId: 9,
        index: 4,
        title: "ART: Transport a famous artist to an event.",
        description: "Hello, I'm %NAME1% and I must go to the %SYSTEM1% system for an important artistic event. If you're in, the pay is %REWARD% credits.",
        choices: "transport",
        currentTask: 1,
        passengers: [ 1 ],
        firstPassenger: 1,
        customResponses: {
            money: [ "I'm [litf_missionResponseMoneyArtist]" ]
        },
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring artist %NAME1% to the %SYSTEM1% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1, names: 1 },
                waitingMission: "G1"
            }
        ]
    },
    {
        groupId: 9,
        index: 5,
        title: "ART: Transport a famous artist to an event.",
        description: "There will be an important art festival in the %SYSTEM2% system, and we need to transport there the controversial %NAME1% from %SYSTEM1%. We can pay %REWARD% credits.",
        choices: "transport",
        currentTask: 1,
        customResponses: {
            money: [ "He's [litf_missionResponseMoneyArtist]." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring artist %NAME1% from the %SYSTEM1% system to %SYSTEM2%. Remember to check the BBS to get your payment.",
                generate: { systems: 1, names: 1 },
                waitingMission: "G2",
                passengers: [ 1 ]
            },
            {
                index: 2,
                typeId: 4, // TRANSPORT
                description: "Bring artist %NAME1% to the %SYSTEM2% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1 },
                waitingMission: "G1"
            }
        ]
    },
    // CARGO
    {
        groupId: 9,
        index: 6,
        title: "HELP NEEDED: Deliver materials to organize an event in another system.",
        description: "Hello, we are organizing a festival in the %SYSTEM1% system and we need to transport a shipment of %GOODS% there. Payment is %REWARD% credits.",
        choices: "cargo",
        currentTask: 1,
        customResponses: {
            money: [ "Nothing special, really." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 5, // CARGO
                description: "Bring a shipment of %GOODS% to the %SYSTEM1% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1, goods: 1 },
                waitingMission: "G3"
            }
        ]
    },
    {
        groupId: 9,
        index: 7,
        title: "ORGANIZING: We need a ship to transport equipment.",
        description: "Hello, I'm %NAME0%. We are organizing an event on this system but we need someone to bring here a load of %GOODS% from the %SYSTEM1% system. If you agree, the payment is %REWARD% credits.",
        choices: "cargo",
        currentTask: 1,
        customResponses: {
            money: [ "We need the equipment." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 5, // CARGO
                description: "Bring a shipment of %GOODS% from the %SYSTEM1% system to %SYSTEM0%. Remember to check the BBS to get your payment.",
                generate: { systems: 1, goods: 1 },
                waitingMission: "G3.1"
            },
            {
                index: 1,
                typeId: 5, // CARGO
                description: "Bring a shipment of %GOODS% to the %SYSTEM0% system. Remember to check the BBS to get your payment.",
                generate: { retrieve: true },
                waitingMission: "G3"
            }
        ]
    },
    // GalGovernment missions -------------------------------------------------
    // CONTACT
    {
        groupId: 10,
        index: 1,
        title: "GOVERNMENT DUTY: Meeting a government agent.",
        description: "Citizen, you're candidate for an important task: meeting a government agent hidden in the %SYSTEM1% system, going with the alias '%NAME1%'. He is requested for reporting duties. We'll give you a safety passcode for the meeting. Government will cover the expenses with %REWARD% credits.",
        choices: "mission",
        currentTask: 1,
        parcel: "An encrypted data drive",
        customResponses: {
            money: [ "It's the regulatory government pay." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 1, // CONTACT
                description: "Go to the %SYSTEM1% system, and meet the hidden government agent '%NAME1%'.",
                generate: { systems: 1, names: 1 },
                waitingMission: "W10.1.1",
                unaware: true
            }
        ]
    },
    // TRANSFER
    {
        groupId: 10,
        index: 3,
        title: "GOVERNMENT DUTY: Moving papers between two government consulates.",
        description: "Citizen, you're candidate for an important task: to transfer a set of diplomatic papers from our consulate in the %SYSTEM1% to our consulate in %SYSTEM2%. Government will cover the expenses with %REWARD% credits.",
        choices: "mission",
        currentTask: 1,
        customResponses: {
            money: [ "It's the regulatory government pay." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 2, // TRANSFER
                description: "Go to the %SYSTEM1% consulate, get the diplomatic papers and bring them to the %SYSTEM2% consulate.",
                generate: { systems: 1, names: 1 },
                parcel: "A folder of diplomatic papers",
                waitingMission: "W10.2.3.1"
            },
            {
                index: 2,
                typeId: 2, // TRANSFER
                description: "Bring the diplomatic papers to the %SYSTEM2% consulate.",
                generate: { systems: 1, names: 1 },
                waitingMission: "W10.2.3.2"
            }
        ]
    },
    // RETRIEVE
    {
        groupId: 10,
        index: 2,
        title: "GOVERNMENT DUTY: Recover papers from another system.",
        description: "Citizen, you're candidate for an important task: to retrieve some dossiers that were stolen by hostile forces! Go to the %SYSTEM1% system, our agent %NAME1% is there waiting for someone to pick up the dossiers. Government will cover the expenses with %REWARD% credits.",
        choices: "mission",
        currentTask: 1,
        customResponses: {
            money: [ "No questions." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 3, // RETRIEVE
                description: "Go to the %SYSTEM1% system and get the dossiers from %NAME1%. Return to the %SYSTEM0% system.",
                generate: { systems: 1, names: 1 },
                parcel: "A box full of government dossiers",
                waitingMission: "W10.3.2.1",
                unaware: true
            },
            {
                index: 2,
                typeId: 3, // RETRIEVE
                description: "Bring the dossiers to the governemnt officials in the %SYSTEM0% system.",
                generate: {
                    retrieve: true
                },
                waitingMission: "W10.3.2.2"
            }
        ]
    },
    // TRANSPORT
    {
        groupId: 10,
        index: 4,
        title: "GOVERNMENT DUTY: Transport a government officer to a meeting.",
        description: "Citizen, you're candidate for an important task: to transport officer %NAME1% and his bodyguards to the %SYSTEM1% system, where he has to attend a diplomatic meeting. Government will cover the expenses with %REWARD% credits.",
        choices: "transport",
        currentTask: 1,
        passengers: [ 3, 7 ],
        firstPassenger: 1,
        risk: 1,
        customResponses: {
            money: [ "No questions." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring officer %NAME1% and his bodyguards to the %SYSTEM1% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1, names: 1 },
                waitingMission: "G1"
            }
        ]
    },
    {
        groupId: 10,
        index: 5,
        title: "GOVERNMENT DUTY: Transport an agent to its destination.",
        description: "Citizen, you're candidate for an important task: to transport agent %NAME1% to the %SYSTEM1% system. Government will cover the expenses with %REWARD% credits.",
        choices: "transport",
        currentTask: 1,
        passengers: [ 1 ],
        firstPassenger: 1,
        risk: 1,
        customResponses: {
            money: [ "No questions." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring agent %NAME1% to the %SYSTEM1% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1, names: 1 },
                waitingMission: "G1"
            }
        ]
    },
    {
        groupId: 10,
        index: 8,
        title: "GOVERNMENT DUTY: Transport a government officer.",
        description: "Citizen, you're candidate for an important task: to transport officer %NAME1% and his bodyguards back from a diplomatic meeting in the %SYSTEM1% system. Government will cover the expenses with %REWARD% credits.",
        choices: "transport",
        currentTask: 1,
        risk: 1,
        customResponses: {
            money: [ "No questions." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring back officer %NAME1% and his bodyguards from the %SYSTEM1% system to %SYSTEM0%. Remember to check the BBS to get your payment.",
                generate: { systems: 1, names: 7 },
                waitingMission: "W10.4.8.1",
                passengers: [ 3, 7 ]
            },
            {
                index: 2,
                typeId: 4, // TRANSPORT
                description: "Bring back officer %NAME1% and his bodyguards to the %SYSTEM0% system. Remember to check the BBS to get your payment.",
                generate: {
                    retrieve: true
                },
                waitingMission: "G1"
            }
        ]
    },
    {
        groupId: 10,
        index: 9,
        title: "GOVERNMENT DUTY: Return trip for a government agent.",
        description: "Citizen, you're candidate for an important task: to transport back agent %NAME1% from the %SYSTEM1% system. Government will cover the expenses with %REWARD% credits.",
        choices: "transport",
        currentTask: 1,
        risk: 1,
        customResponses: {
            money: [ "No questions." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 4, // TRANSPORT
                description: "Bring back agent %NAME1% from the %SYSTEM1% system to %SYSTEM0%. Remember to check the BBS to get your payment.",
                generate: { systems: 1, names: 1 },
                waitingMission: "W10.4.9.1",
                passengers: [ 1 ]
            },
            {
                index: 2,
                typeId: 4, // TRANSPORT
                description: "Bring back agent %NAME1% to the %SYSTEM0% system. Remember to check the BBS to get your payment.",
                generate: {
                    retrieve: true
                },
                waitingMission: "G1"
            }
        ]
    },
    // CARGO
    {
        groupId: 10,
        index: 6,
        title: "GOVERNMENT DUTY: Deliver a shipment to destination.",
        description: "Citizen, you're candidate for an important task: to deliver a shipment of %GOODS% to the %SYSTEM1% system. Government will cover the expenses with %REWARD% credits.",
        choices: "cargo",
        currentTask: 1,
        customResponses: {
            money: [ "No questions." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 5, // CARGO
                description: "Bring a shipment of %GOODS% to the %SYSTEM1% system. Remember to check the BBS to get your payment.",
                generate: { systems: 1, goods: 1 },
                waitingMission: "G3"
            }
        ]
    },
    {
        groupId: 10,
        index: 7,
        title: "GOVERNMENT DUTY: Bring here a shipment from another system.",
        description: "Citizen, you're candidate for an important task: to load and bring here a shipment of %GOODS% from the %SYSTEM1% system. Government will cover the expenses with %REWARD% credits.",
        choices: "cargo",
        currentTask: 1,
        customResponses: {
            money: [ "No questions." ]
        },
        tasks: [
            {
                index: 1,
                typeId: 5, // CARGO
                description: "Bring a shipment of %GOODS% from the %SYSTEM1% system to %SYSTEM0%. Remember to check the BBS to get your payment.",
                generate: { systems: 1, goods: 1 },
                waitingMission: "G3.1"
            },
            {
                index: 1,
                typeId: 5, // CARGO
                description: "Bring a shipment of %GOODS% to the %SYSTEM0% system. Remember to check the BBS to get your payment.",
                generate: { retrieve: true },
                waitingMission: "G3"
            }
        ]
    }
];

// ----------------------------------------------------------------------------

// Waiting messages - BBS items

this.waitingStore = [
    { groupId: 99, index: 0, title: "LOOK HERE: %NAME1%! I'm awaiting your arrival!", description: "Hello, I'm sorry but you're not the person I'm waiting for. Goodbye.", choices: "hangup" },
    { groupId: 99, index: 0, title: "NOTICE: Please %NAME1% contact me ASAP for completing your work.", description: "Hello, I'm sorry but you're not the person I'm waiting for. Goodbye.", choices: "hangup" },
    { groupId: 99, index: 0, title: "HEY COMMANDER: Are you %NAME1%? I'm awaiting for you!", description: "Hello, I'm sorry but you're not the person I'm waiting for. Goodbye.", choices: "hangup" },
    { groupId: 99, index: 0, title: "ANSWER ME: %NAME1%.", description: "Hello, I'm sorry but you're not the person I'm waiting for. Goodbye.", choices: "hangup" },
    { groupId: 99, index: 0, title: "WAITING: I must to talk to %NAME1%.", description: "Hello, I'm sorry but you're not the person I'm waiting for. Goodbye.", choices: "hangup" },
    { groupId: 99, index: 0, title: "NOTICE: XXXXX Read here %NAME1% XXXXX.", description: "Hello, I'm sorry but you're not the person I'm waiting for. Goodbye.", choices: "hangup" }
];

// Charities - BBS Items

this.charityStore = [
    { groupId: 98, index: 0, title: "FEELING GENEROUS? '%CHARITY%' is here for your unwanted money!", description: "Please select an amount to give to '%CHARITY%'.", showCredits: true, choices: "charity" },
    { groupId: 98, index: 0, title: "GIVE MONEY: Make a good action. Support '%CHARITY%' now!", description: "Please select an amount to give to '%CHARITY%'.", showCredits: true, choices: "charity" },
    { groupId: 98, index: 0, title: "DONATE: '%CHARITY%'. We accept your money. Thanks.", description: "Please select an amount to give to '%CHARITY%'.", showCredits: true, choices: "charity" }
];

// Ads - BBS Items

this.adStore = [
    // 101 - Generic messages and spam
    { groupId: 101, index: 0, title: "NEED HOME: I'm searching for a low-cost apartment. Contact me. Rent only.", description: "Hi, I'm %NAME0%. I'm sorry but this ad is reserved to residents only.", choices: "hangup" },
    { groupId: 101, index: 0, title: "FREE ROOM: Want to share my room with another person - expenses too.", description: "Hi, I'm %NAME0%. I'm sorry but this ad is reserved to residents only.", choices: "hangup" },
    { groupId: 101, index: 0, title: "CURIOUS: Do you want to see a real Thargoid? I can help you with that.", description: "Hi, I'm %NAME0%. I'm sorry but this ad is reserved to residents only.", choices: "hangup" },
    { groupId: 101, index: 0, title: "FORGIVE ME: %NAME1%, are you reading this? Please, please answer me!", description: "Hi, I'm %NAME0%. I'm sorry but this ad is reserved to residents only.", choices: "hangup" },
    { groupId: 101, index: 0, title: "LONELY? Do you want to share a bottle of %LIQUOR%? I'm here if you want.", description: "Hi, I'm %NAME0%. I'm sorry but this ad is reserved to residents only.", choices: "hangup" },
    { groupId: 101, index: 0, title: "HELLO: Hello to everybody! Have a good day!", description: "" },
    { groupId: 101, index: 0, title: "BREATHE: It's important. Don't underestimate gases.", description: "" },
    { groupId: 101, index: 0, title: "HELP: Stasis field. My friend is inside. How to turn off?", description: "" },
    { groupId: 101, index: 0, title: "WARNING: USERS WITH FAKE NAMES WILL BE BANNED FOREVER!", description: "" },
    { groupId: 101, index: 0, title: "IMPORTANT: If you are a time traveler or have the technology I need your help!", description: "" },
    { groupId: 101, index: 0, title: "IT WORKS: Write this message 10 times or you'll get bad luck in 10 days.", description: "" },
    { groupId: 101, index: 0, title: "HINT: How %NAME0% Saved 3000cr Using This Simple Trick", description: "" },
    // 102 - Items messages
    { groupId: 102, index: 0, title: "FOR SALE: I want to give away %ITEM%. Come and pick up.", description: "Hi, I'm %NAME0%. I'm sorry but this ad is reserved to residents only.", choices: "hangup" },
    { groupId: 102, index: 0, title: "NEED HELP: Someone has seen %ITEM% around here?", description: "Hi, I'm %NAME0%. I'm sorry but this ad is reserved to residents only.", choices: "hangup" },
    { groupId: 102, index: 0, title: "WANTED: Searching for %ITEM%. Contact me if you have info.", description: "Hi, I'm %NAME0%. I'm sorry but this ad is reserved to residents only.", choices: "hangup" },
    { groupId: 102, index: 0, title: "LOST ITEM: Need replacement for %ITEM%. Can you help me?", description: "Hi, I'm %NAME0%. I'm sorry but this ad is reserved to residents only.", choices: "hangup" },
    { groupId: 102, index: 0, title: "SELLING: Interested in %ITEM%. Contact me.", description: "Hi, I'm %NAME0%. I'm sorry but this ad is reserved to residents only.", choices: "hangup" },
    // 103 - Job messages
    { groupId: 103, index: 0, title: "NEED WORK? Open offer for %JOB%. Good position, decent pay. Please contact me.", description: "Hi, I'm %NAME0%. I'm sorry but this ad is reserved to residents only.", choices: "hangup" },
    { groupId: 103, index: 0, title: "AVAILABLE JOB: We have a free position for %JOB%. Are you interested?", description: "Hi, I'm %NAME0%. I'm sorry but this ad is reserved to residents only.", choices: "hangup" },
    { groupId: 103, index: 0, title: "NOW HIRING: Unexpected events force us to search for %JOB%. Contact us if you're available.", description: "Hi, I'm %NAME0%. I'm sorry but this ad is reserved to residents only.", choices: "hangup" },
    { groupId: 103, index: 0, title: "JOB HERE: Awesome position for %JOB%. Don't miss this opportunity!", description: "Hi, I'm %NAME0%. I'm sorry but this ad is reserved to residents only.", choices: "hangup" },
    { groupId: 103, index: 0, title: "AVAILABLE: I'm %JOB%. Currently unemployed, searching for small jobs. Contact me.", description: "Hi, I'm %NAME0%. I'm sorry but this ad is reserved to residents only.", choices: "hangup" },
    { groupId: 103, index: 0, title: "JOB WANTED: Need job to feed disabled spouse and starving family.", description: "" },
    { groupId: 103, index: 0, title: "UNEMPLOYED CREW: Need work on a starship. Anything considered.", description: "" },
    { groupId: 103, index: 0, title: "NEED WORK: Recently fired for external causes. Looking for any job available.", description: "" },
    { groupId: 103, index: 0, title: "VACANCY REQUIRED: as a crew member on a starship.", description: "" },
    { groupId: 103, index: 0, title: "WANTED: Position on a reputable starship.", description: "" },
    // 104 - Racial messages
    { groupId: 104, index: 0, title: "EVOLUTION: It's time for the %RACE% to change diet?", description: "" },
    { groupId: 104, index: 0, title: "QUESTION: Isn't a %RACE% entitled to the sweat of its brow?", description: "" },
    { groupId: 104, index: 0, title: "CONTEST: Vote the most beautiful %RACE% of the system!!", description: "" },
    { groupId: 104, index: 0, title: "DANGER: Birth race in decline for %RACE%?", description: "" },
    { groupId: 104, index: 0, title: "POLL: What people think when talking about %RACE%?", description: "" },
    { groupId: 104, index: 0, title: "DISCOVER: 42 Life-Changing Style Tips Every %RACE% Should Know", description: "" },
    { groupId: 104, index: 0, title: "INCREDIBLE: This %RACE% will change your life.", description: "" }
];

// Government Specific BBS Items

// 0 - Anarchy, 1 - Feudal, 2 - Multigovernmental, 3 - Dictatorship, 4 - Communist, 5 - Confederacy, 6 - Democracy, 7 - Corporate

this.governmentStore = [
    // Anarchy Specifics
    { groupId: 105, gov: [ 0 ], index: 0, title: "R3M3MB3R: Property is theft!!!", description: "" },
    { groupId: 105, gov: [ 0 ], index: 0, title: "W4R: State bigger health system.", description: "" },
    { groupId: 105, gov: [ 0 ], index: 0, title: "V0T3: Bigger cages! Longer chains!", description: "" },
    { groupId: 105, gov: [ 0 ], index: 0, title: "TH1NK: We are the crisis!", description: "" },
    { groupId: 105, gov: [ 0 ], index: 0, title: "P30PL3: N07 PR0F175!!!", description: "" },
    { groupId: 105, gov: [ 0 ], index: 0, title: "TH3M: Whom the system work for???", description: "" },
    { groupId: 105, gov: [ 0 ], index: 0, title: "****: G4LC0P!", description: "" },
    { groupId: 105, gov: [ 0 ], index: 0, title: "DEBATE: Someone interested - not screaming slogans?", description: "" },
    { groupId: 105, gov: [ 0 ], index: 0, title: "PROPOSAL: Organize something. Use your imagination.", description: "" },
    { groupId: 105, gov: [ 0 ], index: 0, title: "WAHT: Who enabled strong language censorship HERE? **** ****!!!", description: "" },
    { groupId: 105, gov: [ 0 ], index: 0, title: "HINT: How to cope with GalCop officials.", description: "" },
    { groupId: 105, gov: [ 0 ], index: 0, title: "GUIDE: Ten ways to avoid uncomfortable space encounters.", description: "" },
    { groupId: 105, gov: [ 0 ], index: 0, title: "OPEN: Alternative botanical growing laboratory course.", description: "" },
    { groupId: 105, gov: [ 0 ], index: 0, title: "MARKET: Updated listing for unwanted merchandising.", description: "" },
    { groupId: 105, gov: [ 0 ], index: 0, title: "SOCIAL: Learning to lie in a believable way.", description: "" },
    { groupId: 105, gov: [ 0 ], index: 0, title: "HELP: A friend of mine has been arrested.", description: "" },
    { groupId: 105, gov: [ 0 ], index: 0, title: "NET: New and interesting contacts. Free and open.", description: "" },
    { groupId: 105, gov: [ 0 ], index: 0, title: "DARK-BBS: It doesn't exists.", description: "" },
    // Feudal Specifics
    { groupId: 105, gov: [ 1 ], index: 0, title: "EMPIRE: Your effort grows our strength.", description: "" },
    { groupId: 105, gov: [ 1 ], index: 0, title: "HAIL: For the glory of the King!", description: "" },
    { groupId: 105, gov: [ 1 ], index: 0, title: "LORD: Blessed are the meeks.", description: "" },
    { groupId: 105, gov: [ 1 ], index: 0, title: "HERESY: Pagan rituals are BANNED from the Empire!", description: "" },
    { groupId: 105, gov: [ 1 ], index: 0, title: "TAXES: Remember the dates, pay your dues.", description: "" },
    { groupId: 105, gov: [ 1 ], index: 0, title: "KNIGHTS: No more invaders in OUR sacred lands!", description: "" },
    { groupId: 105, gov: [ 1 ], index: 0, title: "PEASANT: You work the land, we protect the land.", description: "" },
    { groupId: 105, gov: [ 1 ], index: 0, title: "TOURNAMENT: Join the festivities and celebrate our englightened monarch.", description: "" },
    // Dictatorship Specifics
    { groupId: 105, gov: [ 3 ], index: 0, title: "WAKE UP: End corruption and immorality.", description: "" },
    { groupId: 105, gov: [ 3 ], index: 0, title: "TRAITORS: They don't love our system!", description: "" },
    { groupId: 105, gov: [ 3 ], index: 0, title: "YOUTH: Join the Revolutionary Forces.", description: "" },
    { groupId: 105, gov: [ 3 ], index: 0, title: "TRUST: Have faith in your government officials!", description: "" },
    { groupId: 105, gov: [ 3 ], index: 0, title: "THINK: What can you do for your system?", description: "" },
    { groupId: 105, gov: [ 3 ], index: 0, title: "WORK: Give a future to your children.", description: "" },
    { groupId: 105, gov: [ 3 ], index: 0, title: "ENEMIES: They could be among us.", description: "" },
    { groupId: 105, gov: [ 3 ], index: 0, title: "PRIDE: You live in the cradle of civilization!", description: "" },
    { groupId: 105, gov: [ 3 ], index: 0, title: "LOOKING FOR: Evicted from communal sector. Searching arrangement.", description: "" },
    { groupId: 105, gov: [ 3 ], index: 0, title: "MEETING: A civil debate about minor local issues.", description: "" },
    { groupId: 105, gov: [ 3 ], index: 0, title: "RAID: Last night. Someone heard something?", description: "" },
    { groupId: 105, gov: [ 3 ], index: 0, title: "MISSING: I can't find a person anymore.", description: "" },
    { groupId: 105, gov: [ 3 ], index: 0, title: "CONFORM: There's no need to dissent.", description: "" },
    { groupId: 105, gov: [ 3 ], index: 0, title: "MISSING: Someone has seen...", description: "" },
    { groupId: 105, gov: [ 3 ], index: 0, title: "NO PROBLEM: They say. You're happy and it's all okay.", description: "" },
    // Communist Specifics
    { groupId: 105, gov: [ 4 ], index: 0, title: "KOMM: To have more we have to produce more!", description: "" },
    { groupId: 105, gov: [ 4 ], index: 0, title: "KOMM: For the Industrial Plan!", description: "" },
    { groupId: 105, gov: [ 4 ], index: 0, title: "KOMM: Long live to the Party!", description: "" },
    { groupId: 105, gov: [ 4 ], index: 0, title: "KOMM: All power to the Party. Peace to the People. Land to the peasants.", description: "" },
    { groupId: 105, gov: [ 4 ], index: 0, title: "KOMM: With great labor we will fulfill the plan.", description: "" },
    { groupId: 105, gov: [ 4 ], index: 0, title: "KOMM: All workers choose the Party!", description: "" },
    { groupId: 105, gov: [ 4 ], index: 0, title: "KOMM: We grow under the sun of our system.", description: "" },
    { groupId: 105, gov: [ 4 ], index: 0, title: "KOMM: Follow the true path, comrades!", description: "" },
    { groupId: 105, gov: [ 4 ], index: 0, title: "KOMM: Come to us on the collective farm, comrade!", description: "" },
    { groupId: 105, gov: [ 4 ], index: 0, title: "KOMM: Proletarians of all countries, unite!", description: "" },
    { groupId: 105, gov: [ 4 ], index: 0, title: "KOMM: Have you signed up with the volunteers?", description: "" },
    { groupId: 105, gov: [ 4 ], index: 0, title: "WORK: Reaching the monthly production level.", description: "" },
    { groupId: 105, gov: [ 4 ], index: 0, title: "WORK: Are we allowed to start a strike?", description: "" },
    { groupId: 105, gov: [ 4 ], index: 0, title: "WORK: Who control the industry?", description: "" },
    { groupId: 105, gov: [ 4 ], index: 0, title: "WORK: Requiring new machinery - existing one break too often.", description: "" },
    { groupId: 105, gov: [ 4 ], index: 0, title: "SOCIAL: Weekly political debates.", description: "" },
    { groupId: 105, gov: [ 4 ], index: 0, title: "SOCIAL: Capitalism is bad. You should know.", description: "" },
    { groupId: 105, gov: [ 4 ], index: 0, title: "SOCIAL: How much space for innovation?", description: "" },
    { groupId: 105, gov: [ 4 ], index: 0, title: "SOCIAL: Discussion on global economic models.", description: "" },
    { groupId: 105, gov: [ 4 ], index: 0, title: "POLICE: I heard a lot of noise in the near apartments...", description: "" },
    { groupId: 105, gov: [ 4 ], index: 0, title: "MISSING: I can't find a person anymore.", description: "" },
    { groupId: 105, gov: [ 4 ], index: 0, title: "MISSING: Someone has seen...", description: "" },
    // Corporate Specifics
    { groupId: 105, gov: [ 7 ], index: 0, title: "AD: You should do it now!", description: "" },
    { groupId: 105, gov: [ 7 ], index: 0, title: "AD: Imagine something original!", description: "" },
    { groupId: 105, gov: [ 7 ], index: 0, title: "AD: Buy it, you deserve it!", description: "" },
    { groupId: 105, gov: [ 7 ], index: 0, title: "AD: There aren't things credits can't buy!", description: "" },
    { groupId: 105, gov: [ 7 ], index: 0, title: "AD: All is designed for your comfort!", description: "" },
    { groupId: 105, gov: [ 7 ], index: 0, title: "AD: Tastes so good! You can't live without!", description: "" },
    { groupId: 105, gov: [ 7 ], index: 0, title: "AD: Have a break! Do shopping!", description: "" },
    { groupId: 105, gov: [ 7 ], index: 0, title: "AD: Buy, break, replace!", description: "" },
    { groupId: 105, gov: [ 7 ], index: 0, title: "AD: Buy it, you need it!", description: "" },
    { groupId: 105, gov: [ 7 ], index: 0, title: "AD: You're never spending enough!", description: "" },
    { groupId: 105, gov: [ 7 ], index: 0, title: "AD: BUY, CONSUME, REPEAT.", description: "" },
    { groupId: 105, gov: [ 7 ], index: 0, title: "AD: Work until expensive become cheap!", description: "" },
    { groupId: 105, gov: [ 7 ], index: 0, title: "HELP: Credit expired on my credit card. What can I do?", description: "" },
    { groupId: 105, gov: [ 7 ], index: 0, title: "POLL: The best debit card on the market today.", description: "" },
    { groupId: 105, gov: [ 7 ], index: 0, title: "ASKING: How to do more overtime without risking your life.", description: "" },
    { groupId: 105, gov: [ 7 ], index: 0, title: "THERAPY: I cannot stop working. Too stressed.", description: "" },
    { groupId: 105, gov: [ 7 ], index: 0, title: "MEDS: Ten products to ease your psychological discomfort.", description: "" },
    { groupId: 105, gov: [ 7 ], index: 0, title: "MARKET: Global Funds Daily Updates.", description: "" },
    { groupId: 105, gov: [ 7 ], index: 0, title: "INVESTMENT: What is better? Long term.", description: "" },
    { groupId: 105, gov: [ 7 ], index: 0, title: "POLL: Can We Guess Your Favourite Product Based On Random Questions?", description: "" },
    // Various
    { groupId: 105, gov: [ 0, 2, 5, 6, 7 ], index: 0, title: "ANSWER NOW: You have just won 999999 credits!!! Talk to me to get your money!!!", description: "" },
    { groupId: 105, gov: [ 0, 2, 5, 6, 7 ], index: 0, title: "IMPORTANT: You could be entitled up to 15340 credits in compensation.", description: "" },
    { groupId: 105, gov: [ 2, 5, 6, 7 ], index: 0, title: "SPACEPORT: Baggage reclamation office open for service.", description: "" },
    { groupId: 105, gov: [ 2, 5, 6, 7 ], index: 0, title: "DELUXOR HOTELS: Exaggerate luxury for a deluxe holiday!", description: "" },
    { groupId: 105, gov: [ 2, 5, 6, 7 ], index: 0, title: "HOSPITAL: Donor blood needed. Do your part.", description: "" },
    { groupId: 105, gov: [ 2, 5, 6 ], index: 0, title: "ART GALLERY: We are closed, but stay updated for our next events!", description: "" },
    { groupId: 105, gov: [ 0, 6, 7 ], index: 0, title: "CITIZEN: Do you trust your government?", description: "" },
    { groupId: 105, gov: [ 1, 2, 5, 7 ], index: 0, title: "PETITION: Ban Low Quality %GOODS% - they're hurting the economy!", description: "Hi, I'm %NAME0%. I'm sorry but this ad is reserved to residents only.", choices: "hangup" },
    { groupId: 105, gov: [ 1, 2, 5 ], index: 0, title: "CONCERNED: Don't trust every %GOODS% Vendor. Stay alert.", description: "Hi, I'm %NAME0%. I'm sorry but this ad is reserved to residents only.", choices: "hangup" },
    { groupId: 105, gov: [ 1, 2, 5, 7 ], index: 0, title: "PROTEST: Lower taxes for %GOODS%!", description: "Hi, I'm %NAME0%. I'm sorry but this ad is reserved to residents only.", choices: "hangup" },
    { groupId: 105, gov: [ 2, 5, 6, 7 ], index: 0, title: "SOON: The new %MOVIE% movie from the acclaimed director %NAME1%.", description: "Good day. If you're interested in this event, we suggest to ask for more information at the local cultural center. Thanks for your attention.", choices: "hangup" },
    { groupId: 105, gov: [ 2, 5, 6, 7 ], index: 0, title: "IN STORES NOW: The last masterpiece in %MUSIC% by %NAME1%.", description: "Good day. If you're interested in this event, we suggest to ask for more information at the local cultural center. Thanks for your attention.", choices: "hangup" },
    { groupId: 105, gov: [ 2, 5, 6 ], index: 0, title: "ADMIRE: The last collection of %ART% paintings by %NAME1%, now in tour across the galaxy.", description: "Good day. If you're interested in this event, we suggest to ask for more information at the local cultural center. Thanks for your attention.", choices: "hangup" },
    { groupId: 105, gov: [ 0, 2, 3, 4, 5, 6 ], index: 0, title: "ENJOY: Come at the bar, and try our %LIQUOR%! Unforgettable experiences guaranteed!", description: "" },
    { groupId: 105, gov: [ 0, 2, 3, 4, 5, 6 ], index: 0, title: "THE BEST: We have the best %LIQUOR% in the system. Why don't you try it?", description: "" },
    { groupId: 105, gov: [ 2, 5, 6, 7 ], index: 0, title: "COOPER CAFE': Come and taste: we serve a damn good coffee!", description: "" },
    { groupId: 105, gov: [ 6, 7 ], index: 0, title: "WEYLAND-YUTANI CORPORATION: Building better worlds.", description: "" },
    { groupId: 105, gov: [ 7 ], index: 0, title: "ARES MACROTECHNOLGY: Making the world a safer place.", description: "" },
    { groupId: 105, gov: [ 7 ], index: 0, title: "RENRAKU: Today's solutions to tomorrow's problems.", description: "" },
    { groupId: 105, gov: [ 7 ], index: 0, title: "WUXING: We're behind everything you do.", description: "" },
    { groupId: 105, gov: [ 5, 6, 7 ], index: 0, title: "OMNICORP: We got the future under control.", description: "" },
    { groupId: 105, gov: [ 5, 6, 7 ], index: 0, title: "TYRELL CORP: More Human Than Human.", description: "" },
    { groupId: 105, gov: [ 7 ], index: 0, title: "AURITECH SURVEILLANCE: We're keeping an eye out, for you.", description: "" },
    { groupId: 105, gov: [ 7 ], index: 0, title: "WORLDCOM: For the Greater Good.", description: "" },
    { groupId: 105, gov: [ 2, 5, 6, 7 ], index: 0, title: "CENTRAL SERVICES: We do the work! You do the pleasure.", description: "" },
    { groupId: 105, gov: [ 7 ], index: 0, title: "RENAUTAS: Doing good is good business.", description: "" },
    { groupId: 105, gov: [ 5, 6, 7 ], index: 0, title: "CYBERDYNE SYSTEMS: We are the future.", description: "" },
    { groupId: 105, gov: [ 7 ], index: 0, title: "YOYODINE: The future begins tomorrow.", description: "" },
    { groupId: 105, gov: [ 2, 5, 6, 7 ], index: 0, title: "SOYLENT CORPORATION: Today is Soylent Green day!", description: "" },
    { groupId: 105, gov: [ 7 ], index: 0, title: "MULTI-NATIONAL UNITED: Paving the way to unity.", description: "" },
    { groupId: 105, gov: [ 2, 5, 6, 7 ], index: 0, title: "ECORP: Together we can change the world.", description: "" },
    { groupId: 105, gov: [ 7 ], index: 0, title: "MASSIVE DYNAMIC: What do we do? What don't we do.", description: "" }
]

// ----------------------------------------------------------------------------

// Player interaction options arrays

this.hangupChoices = {
    "99_QUIT": "Hang up."
};

this.charityChoices = {
    "01_DONAATE01": "Donate 0.1 credits.",
    "02_DONATE1": "Donate 1 credit.",
    "03_DONATE10": "Donate 10 credits.",
    "04_DONATE100": "Donate 100 credits.",
    "05_DONATE1000": "Donate 1000 credits.",
    "06_DONATE10000": "Donate 10000 credits.",
    "99_QUIT": "Hang up."
};

this.missionChoices = {
    "01_OK": "Ok - agreed.",
    // "02_HOWMANY": "How many of you are there?",
    "03_MONEY": "Why so much money?",
    "04_PROBLEMS": "Will there be any problems?",
    // "05_PERMIT": "Do I need a permit, and if so can I have one?",
    "05_UNAWARE": "Do the recipient will know of my arrival?",
    // "REPEAT": "Could you repeat your original request.",
    "06_MOREMONEY": "I want more money.",
    "07_HALFADVANCE": "I want half the money now.",
    "08_FULLADVANCE": "I want all the money now.",
    // "96_QUIT": "'Hold on while I make room.' then hang up.",
    // "97_QUIT": "'I haven't enough room in my ship' then hang up",
    // "98_QUIT": "'Sorry, I'm not going that way' then hang up",
    "99_QUIT": "Hang up."
};

this.transportChoices = {
    "01_OK": "Ok - agreed.",
    "02_HOWMANY": "How many of you are there?",
    "03_MONEY": "Why so much money?",
    "04_PROBLEMS": "Will there be any problems?",
    // "05_PERMIT": "Do I need a permit, and if so can I have one?",
    // "05_UNAWARE": "Do the recipient will know of my arrival?",
    // "REPEAT": "Could you repeat your original request.",
    "06_MOREMONEY": "I want more money.",
    "07_HALFADVANCE": "I want half the money now.",
    "08_FULLADVANCE": "I want all the money now.",
    // "96_QUIT": "'Hold on while I make room.' then hang up.",
    // "97_QUIT": "'I haven't enough room in my ship' then hang up",
    // "98_QUIT": "'Sorry, I'm not going that way' then hang up",
    "99_QUIT": "Hang up."
};

this.cargoChoices = {
    "01_OK": "Ok - agreed.",
    // "02_HOWMANY": "How many of you are there?",
    "03_MONEY": "Why so much money?",
    "04_PROBLEMS": "Will there be any problems?",
    // "05_PERMIT": "Do I need a permit, and if so can I have one?",
    // "05_UNAWARE": "Do the recipient will know of my arrival?",
    // "REPEAT": "Could you repeat your original request.",
    "06_MOREMONEY": "I want more money.",
    "07_HALFADVANCE": "I want half the money now.",
    "08_FULLADVANCE": "I want all the money now.",
    // "96_QUIT": "'Hold on while I make room.' then hang up.",
    // "97_QUIT": "'I haven't enough room in my ship' then hang up",
    // "98_QUIT": "'Sorry, I'm not going that way' then hang up",
    "99_QUIT": "Hang up."
};
Scripts/LITF_Missions.js
/* eslint-disable semi, no-multi-spaces, quotes, indent, no-tabs, yoda */
/* global worldScripts, randomName, system, player, expandDescription, randomInhabitantsDescription */

"use strict";

this.name = "LITF_Missions";
this.author = "BeeTLe BeTHLeHeM";
this.copyright = "2018 BeeTLe BeTHLeHeM";
this.description = "Mission generation methods";
this.version = "0.10.0";
this.licence = "CC BY-NC-SA 4.0";

// Active groups index, by system government type

this.groupsByGov = [
    [3, 5], // Anarchy
    [2, 3, 5], // Feudal
    [0, 1, 2, 4, 5, 6, 7, 8, 9], // Multigovernmental
    [2, 5, 10], // Dictatorship
    [5, 10], // Communist
    [0, 1, 2, 4, 5, 6, 7, 8, 9], // Confederacy
    [0, 1, 2, 4, 5, 6, 7, 8, 9], // Democracy
    [3, 4, 6, 7] // Corporate
];

var _co   = null;
var _md   = null;
var _litf = null;
var _bbs  = null;

this.$init = function () {
    _co   = worldScripts.LITF_Common;
    _md   = worldScripts.LITF_MissionData;
    _litf = worldScripts.LITF;
    _bbs  = worldScripts.LITF_BBS;
}

// Main method
this.$generateMission = function (activeGroupsArr, debugMissionIdx) {
    _co.$log("[LITF_BBS] generateMission");

    var storeItem = null; // Store object
    var mObj      = null; // Mission object
    var passArr   = null; // Passengers array

    if (activeGroupsArr[0] === "debug") {
        // Get debug mission object
        for (var m = 0; m < _md.debugStore.length; m++) {
            storeItem = _md.debugStore[m];
            if (storeItem.index === debugMissionIdx) {
                _co.$log("Clone store object");
                mObj = JSON.parse(JSON.stringify(storeItem));
                break;
            }
        }
    } else {
        // Get mission object

        var counter = 0;
        while (counter < 50) {
            counter++;

            var mIdx = _co.$roll(0, _md.missionStore.length - 1);
            storeItem = _md.missionStore[mIdx];

            if (activeGroupsArr.indexOf(storeItem.groupId) > -1) {
                _co.$log("Clone store object");
                mObj = JSON.parse(JSON.stringify(storeItem));
                break;
            }
        }

        if (mObj === null) {
            return null;
        }
    }

    // Define mission details
    _co.$log("Define mission details :: mObj = " + JSON.stringify(mObj));

    var pFeedback = _litf.litfCommander.feedback;
    var maxSystemDistance = 10 + (Math.abs(pFeedback) / 5);

    mObj.missionId      = _co.$getGeneralId(); // Unique id
    mObj.contractor     = randomName() + " " + randomName();
    mObj.startingSystem = { index: 0, id: system.ID, name: System.systemNameForID(system.ID), distance: 0 };
    mObj.rewardAdvanceObtained = null; // Player has obtained a reward advance
    mObj.moreMoneyObtained     = false; // Player has obtained a reward increase

    // Face
    mObj.faceBackground = this.$getFaceBackground(mObj);

    // Defaults
    if (!mObj.local) {  mObj.local = false; }
    if (!mObj.showCredits) { mObj.showCredits = false; }
    if (!mObj.noReward) { mObj.noReward = false; }
    if (!mObj.failureDead) { mObj.failureDead = false; }

    // Feedback checks
    _co.$log("Feedback checks");

    if (mObj.groupId === 3) {
        // GalShady
        var maxFeedback = mObj.maxFeedback ? mObj.maxFeedback : this.maxFeedbackDefault;
        if (pFeedback > maxFeedback) {
            mObj.description = "You smell too clean for this. Return when your hands will be dirtier.";
            mObj.choices = "hangup";
        }
    } else {
        // Not GalShady
        var minFeedback = mObj.minFeedback ? mObj.minFeedback : this.minFeedbackDefault;
        if (pFeedback < minFeedback) {
            mObj.description = "Hello, thanks for contacting us, but we want someone with a higher feedback rating.";
            mObj.choices = "hangup";
        }
    }

    // Define number of passengers (at the start of the mission, if any)
    if (mObj.passengers) {
        passArr = mObj.passengers;
        if (passArr.length === 1) {
            mObj.passengers = passArr[0]; // Fixed number
        } else if (passArr.length === 2) {
            mObj.passengers = _co.$roll(passArr[0], passArr[1]); // Random number
        }
    }

    // Define tasks

    var ta = 0;
    var task = {};

    var maxRisk = 0;

    if (mObj.risk) { maxRisk = mObj.risk; }

    var generatedSystems = [];

    for (ta = 0; ta < mObj.tasks.length; ta++) {
        task = mObj.tasks[ta];

        // Defaults
        if (!task.unaware) { task.unaware = false; }
        if (!task.urgent) { task.urgent = false; }
        // if (!task.risk) { task.risk = 0; }

        // Define number of passengers (during a task)
        if (task.passengers) {
            passArr = task.passengers;
            if (passArr.length === 1) {
                task.passengers = passArr[0]; // Fixed number
            } else if (passArr.length === 2) {
                task.passengers = _co.$roll(passArr[0], passArr[1]); // Random number
            }
        }

        // Procedural generation
        var generate = task.generate;
        task.info = this.$generateInfo(generate, mObj.groupId, maxSystemDistance, generatedSystems);

        if (task.info.systems === null) {
            _co.$log("-- WARNING -- Error generating random systems! Aborting mission generation!");
            return null;
        } else {
            for (var s = 0; s < task.info.systems.length; s++) {
                generatedSystems.push(task.info.systems[s]);
            }

            // Special generation properties
            if (generate.retrieve && generate.retrieve === true) {
                task.info.systems.push(mObj.startingSystem);
                task.info.names.push(mObj.contractor);
            }
        }
    }

    // Time for completing the mission
    mObj.timeAllowed = this.$missionAllocatedTime(mObj);
    if (mObj.timeAllowed === 0) {
        _co.$log("-- WARNING -- Error generating mission deadline! Aborting mission generation!");
        return null;
    }

    // Mission reward
    mObj.reward = this.$missionReward(mObj);

    // Tweak mission risk factor is payment is high
    if (mObj.reward > 1000) {
        if (!mObj.risk || mObj.risk < 1) {
            mObj.risk = 1;
        }
    } else if (mObj.reward > 3000) {
        if (!mObj.risk || mObj.risk < 2) {
            mObj.risk = 2;
        }
    }

    if (maxRisk < mObj.risk) { maxRisk = mObj.risk; }

    // Responses
    _co.$log("Responses");

    mObj.responses = {};
    mObj.responses.howmany = "There is only me here - what do you mean?";
    mObj.responses.money = "Sorry, that's none of your business.";
    mObj.responses.problems = "No.";

    // Custom responses
    _co.$log("Custom responses");

    var crIdx = 0;
    if (mObj.customResponses) {
        _co.$log("customResponses esiste");
        if (mObj.customResponses.money) {
            var money = mObj.customResponses.money;
            _co.$log("customResponses.money = " + money);

            if (money[0].indexOf("[litf_missionResponseMoneyGroup]") > -1) {
                money[0] = money[0].replace("[litf_missionResponseMoneyGroup]", expandDescription("[litf_missionResponseMoneyGroup]"));
                mObj.responses.money = money[0];
            } else if (money[0].indexOf("[litf_missionResponseMoneyPassenger]") > -1) {
                money[0] = money[0].replace("[litf_missionResponseMoneyPassenger]", expandDescription("[litf_missionResponseMoneyPassenger]"));
                mObj.responses.money = money[0];
            } else if (money[0].indexOf("[litf_missionResponseMoneyParcel]") > -1) {
                money[0] = money[0].replace("[litf_missionResponseMoneyParcel]", expandDescription("[litf_missionResponseMoneyParcel]"));
                mObj.responses.money = money[0];
            } else if (money[0].indexOf("[litf_missionResponseMoneyArtist]") > -1) {
                money[0] = money[0].replace("[litf_missionResponseMoneyArtist]", expandDescription("[litf_missionResponseMoneyArtist]"));
                mObj.responses.money = money[0];
            } else if (money[0].indexOf("[litf_missionResponseMoneyNatureJob]") > -1) {
                money[0] = money[0].replace("[litf_missionResponseMoneyNatureJob]", expandDescription("[litf_missionResponseMoneyNatureJob]"));
                mObj.responses.money = money[0];
            } else {
                _co.$log("4");
                crIdx = _co.$roll(0, money.length - 1);
                mObj.responses.money = money[crIdx];
            }
            _co.$log("responses.money = " + mObj.responses.money);
        }
    }

    if (maxRisk === 1) {
        mObj.responses.problems = expandDescription("[litf_missionResponseRisk01]");
    } else if (maxRisk === 2) {
        mObj.responses.problems = expandDescription("[litf_missionResponseRisk02]");
    }

    mObj.responses.unaware = [ expandDescription("[litf_missionResponseUnawareFalse]"), expandDescription("[litf_missionResponseUnawareTrue]") ];

    //

    mObj.title = this.$replaceKeys(mObj.title, mObj);
    mObj.description = this.$replaceKeys(mObj.description, mObj);

    if (mObj.parcel) {
        mObj.parcel = this.$replaceKeys(mObj.parcel, mObj);
        mObj.parcel = mObj.parcel[0].charAt(0).toUpperCase() + mObj.parcel[0].substring(1);
    }

    for (ta = 0; ta < mObj.tasks.length; ta++) {
        task = mObj.tasks[ta];
        task.description = this.$replaceKeys(task.description, mObj);

        if (task.parcel) {
            task.parcel = this.$replaceKeys(task.parcel, mObj);
            task.parcel = task.parcel[0].charAt(0).toUpperCase() + task.parcel[0].substring(1);
        }
    }

    _co.$log("mission object " + JSON.stringify(mObj));

    return mObj;
}

this.$getFaceBackground = function (mObj) {
    var roll = 0;
    var filename = null;

    if (mObj.groupId === 0) {
        // GalCop
        roll = _co.$roll(1, 5);
        filename = (roll < 10 ? "0" : "") + roll + "-galcop.png";
    } else if (mObj.groupId === 3) {
        // GalShady
        roll = _co.$roll(1, 5);
        filename = (roll < 10 ? "0" : "") + roll + "-galshady.png";
    } else if (mObj.groupId === 10) {
        // GalGovernment
        roll = _co.$roll(1, 5);
        filename = (roll < 10 ? "0" : "") + roll + "-galgov.png";
    // } else if (mObj.choices === "hangup") {
    //     filename = "connrfsd.png";
    } else {
        roll = _co.$roll(1, 21);
        filename = (roll < 10 ? "0" : "") + roll + "-casual.png";
    }

    _co.$log("[LITF_Missions] getFaceBackground :: " + filename);

    return filename;
}

this.$generatePlayerWaitingMission = function (amItem) {
    var pwObj = this.$getPlayerWaitingMission(amItem);

    pwObj.title = this.$replaceKeys(pwObj.title, amItem);

    for (var s = 0; s < pwObj.steps.length; s++) {
        var step = pwObj.steps[s];

        step.description = this.$replaceKeys(step.description, amItem);

        var choice = step.choice;
        var cKeys = _co.$getObjectKeys(choice);
        for (var ch = 0; ch < cKeys.length; ch++) {
            choice[cKeys[ch]] = this.$replaceKeys(choice[cKeys[ch]], amItem);
        }
    }

    pwObj.parentMissionId = amItem.missionId; // original mission reference id
    pwObj.missionId = _co.$getGeneralId();

    pwObj.reward = amItem.reward;  // mission reward
    pwObj.feedbackSuccess = amItem.feedbackSuccess; // feedback reward

    return pwObj;
}

this.$getPlayerWaitingMission = function (mItem) {
    _co.$log("[LITF_BBS] getPlayerWaitingMission");

    var pwObj = null;

    var cTask = _bbs.$getMissionTask(mItem, mItem.currentTask);

    var pwLabel = cTask.waitingMission;

    _co.$log("pwLabel = " + pwLabel);

    for (var pw = 0; pw < _md.missionWaitingStore.length; pw++) {
        var pwItem = _md.missionWaitingStore[pw];

        _co.$log("pwItem[" + pw + "] " + JSON.stringify(pwItem));

        if (pwItem.label === pwLabel) {
            pwObj = {};

            pwObj = JSON.parse(JSON.stringify(pwItem));

            // These properties are always the same
            pwObj.groupId = 97;
            pwObj.typeId = 0;
            pwObj.index = 0;
            pwObj.currentStep = 1;
            pwObj.choices = "waiting";

            break;
        }
    }

    // Use the title already present or generate a random one for the waiting item

    if (pwObj.title === null) {
        var idx = -1;
        var tObj = null;

        if (cTask.unaware === false) {
            idx = _co.$roll(0, _md.waitingStore.length - 1);
            tObj = _md.waitingStore[idx];
        } else {
            var valid = false;
            while (valid === false) {
                idx = _co.$roll(0, _md.adStore.length - 1);
                tObj = _md.adStore[idx];
                if (tObj.groupId === 101) {
                    valid = true;
                }
            }
        }

        pwObj.title = tObj.title;
        pwObj.title = pwObj.title.replace("%NAME1%", "%PLAYERNAME%");
    }

    return pwObj;
}

this.$generateInfo = function (gObj, groupId, maxSystemDistance, generatedSystems) {
    _co.$log("[LITF_Mission] generateInfo");

    var info = {
        systems: [],
        names: [],
        books: [],
        charities: [],
        items: [],
        jobs: [],
        goods: [],
        races: [],
        liquors: [],
        movies: [],
        music: [],
        art: [],
        paintings: []
    };

    var i = 0;
    var gkeyArr = _co.$getObjectKeys(gObj);

    for (var gk = 0; gk < gkeyArr.length; gk++) {
        var gkey = gkeyArr[gk];
        if (gkey === "systems") {
            for (i = 0; i < gObj[gkey]; i++) {
                var valid = false;
                var rsys = null;
                var counter = 0;
                while (valid === false && counter < 100) {
                    rsys = _co.$randomSystem(maxSystemDistance);

                    valid = true;
                    for (var sy = 0; sy < info.systems.length; sy++) {
                        // _co.$log("rsys.id = " + rsys.id + " info.systems[" + sy + "].name = " + info.systems[sy].id);
                        // _co.$log("rsys.name = " + rsys.id + " info.systems[" + sy + "].name = " + info.systems[sy].name);
                        if (info.systems[sy].id === rsys.id) {
                            valid = false;
                        }
                    }

                    for (var gs = 0; gs < generatedSystems.length; gs++) {
                        if (generatedSystems[gs].id === rsys.id) {
                            valid = false;
                        }
                    }

                    counter++;
                }

                if (counter < 100) {
                    info.systems.push(rsys);
                } else {
                    info.systems = null;
                }
            }
        } else if (gkey === "names") {
            for (i = 0; i < gObj[gkey]; i++) {
                info.names.push(randomName() + " " + randomName());
            }
        } else if (gkey === "books") {
            for (i = 0; i < gObj[gkey]; i++) {
                info.books.push(expandDescription("[litf_Books]"));
            }
        } else if (gkey === "charities") {
            for (i = 0; i < gObj[gkey]; i++) {
                info.charities.push(expandDescription("[litf_Charity]"));
            }
        } else if (gkey === "items") {
            for (i = 0; i < gObj[gkey]; i++) {
                info.items.push(expandDescription("[litf_Items]"));
            }
        } else if (gkey === "jobs") {
            for (i = 0; i < gObj[gkey]; i++) {
                info.jobs.push(expandDescription("[litf_Jobs]"));
            }
        } else if (gkey === "goods") {
            for (i = 0; i < gObj[gkey]; i++) {
                var goodArrByGroup = _co.commodityGroups[groupId];
                var goodIdx = _co.$roll(0, goodArrByGroup.length - 1);
                info.goods.push(goodArrByGroup[goodIdx]);
            }
        } else if (gkey === "races") {
            for (i = 0; i < gObj[gkey]; i++) {
                info.races.push(randomInhabitantsDescription(true));
            }
        } else if (gkey === "liquors") {
            for (i = 0; i < gObj[gkey]; i++) {
                info.liquors.push(expandDescription("[litf_Liquors]"));
            }
        } else if (gkey === "movies") {
            for (i = 0; i < gObj[gkey]; i++) {
                info.movies.push(expandDescription("[litf_Movie1]") + " " + expandDescription("[litf_Movie2]") + " " + expandDescription("[litf_Movie3]"));
            }
        } else if (gkey === "music") {
            for (i = 0; i < gObj[gkey]; i++) {
                info.music.push(expandDescription("[litf_Music1]") + " " + expandDescription("[litf_Music2]") + " " + expandDescription("[litf_Music3]"));
            }
        } else if (gkey === "art") {
            for (i = 0; i < gObj[gkey]; i++) {
                info.art.push(expandDescription("[litf_Art1]") + " " + expandDescription("[litf_Art2]"));
            }
        } else if (gkey === "paintings") {
            for (i = 0; i < gObj[gkey]; i++) {
                info.paintings.push(expandDescription("[litf_Painting1]") + " " + expandDescription("[litf_Painting2]"));
            }
        }
    }

    return info;
}

this.$generateGovernmentItem = function () {
    _co.$log("[LITF_Mission] generateGovernmentItem");

    var storeObj = null;

    var stationData = _litf.litfVars.stationParams;
    var government = stationData.government;

    var valid = false;
    while (valid === false) {
        var idx = _co.$roll(0, _md.governmentStore.length - 1);
        storeObj = _md.governmentStore[idx];

        valid = true;
        if (storeObj.gov.indexOf(government) === -1) {
            valid = false;
        }
    }

    // Clone store object
    _co.$log("Clone store object");
    var obj = JSON.parse(JSON.stringify(storeObj));

    obj.missionId = -1;

    // Procedural generation
    var generate = {
        systems: 0,
        names: 0,
        books: 0,
        charities: 0,
        items: 0,
        jobs: 0,
        goods: 0,
        races: 0,
        liquors: 0,
        movies: 0,
        music: 0,
        art: 0,
        paintings: 0
    };

    if (obj.title.indexOf("%SYSTEM1%") > -1 || obj.description.indexOf("%SYSTEM1%") > -1) {
        generate.systems = generate.systems + 1;
    }

    if (obj.title.indexOf("%NAME1%") > -1 || obj.description.indexOf("%NAME1%") > -1) {
        generate.names = generate.names + 1;
    }

    if (obj.title.indexOf("%BOOK%") > -1 || obj.description.indexOf("%BOOK%") > -1) {
        generate.books = generate.books + 1;
    }

    if (obj.title.indexOf("%CHARITY%") > -1 || obj.description.indexOf("%CHARITY%") > -1) {
        generate.charities = generate.charities + 1;
    }

    if (obj.title.indexOf("%ITEM%") > -1 || obj.description.indexOf("%ITEM%") > -1) {
        generate.items = generate.items + 1;
    }

    if (obj.title.indexOf("%JOB%") > -1 || obj.description.indexOf("%JOB%") > -1) {
        generate.jobs = generate.jobs + 1;
    }

    if (obj.title.indexOf("%GOODS%") > -1 || obj.description.indexOf("%GOODS%") > -1) {
        generate.goods = generate.goods + 1;
    }

    if (obj.title.indexOf("%RACE%") > -1 || obj.description.indexOf("%RACE%") > -1) {
        generate.races = generate.races + 1;
    }

    if (obj.title.indexOf("%LIQUOR%") > -1 || obj.description.indexOf("%LIQUOR%") > -1) {
        generate.liquors = generate.liquors + 1;
    }

    if (obj.title.indexOf("%MOVIE%") > -1 || obj.description.indexOf("%MOVIE%") > -1) {
        generate.movies = generate.movies + 1;
    }

    if (obj.title.indexOf("%MUSIC%") > -1 || obj.description.indexOf("%MUSIC%") > -1) {
        generate.music = generate.music + 1;
    }

    if (obj.title.indexOf("%ART%") > -1 || obj.description.indexOf("%ART%") > -1) {
        generate.art = generate.art + 1;
    }

    if (obj.title.indexOf("%PAINTING%") > -1 || obj.description.indexOf("%PAINTING%") > -1) {
        generate.paintings = generate.paintings + 1;
    }

    //

    obj.tasks = [{}];

    // Procedural generation
    obj.tasks[0].info = this.$generateInfo(generate, 10, 20, []);

    //

    obj.title = this.$replaceKeys(obj.title, obj);

    return obj;
}

this.$generateRandomItem = function (store) {
    _co.$log("[LITF_Mission] generateRandomItem");

    var pFeedback = _litf.litfCommander.feedback;
    var maxSystemDistance = 10 + (Math.abs(pFeedback) / 5);

    var idx = _co.$roll(0, store.length - 1);
    var storeObj = store[idx];

    // Clone store object
    _co.$log("Clone store object");
    var obj = JSON.parse(JSON.stringify(storeObj));

    obj.missionId = -1;
    obj.contractor = randomName() + " " + randomName();

    // Face
    obj.faceBackground = this.$getFaceBackground(obj);

    // Procedural generation
    var generate = {
        systems: 0,
        names: 0,
        books: 0,
        charities: 0,
        items: 0,
        jobs: 0,
        goods: 0,
        races: 0,
        liquors: 0,
        movies: 0,
        music: 0,
        art: 0,
        paintings: 0
    };

    if (obj.title.indexOf("%SYSTEM1%") > -1 || obj.description.indexOf("%SYSTEM1%") > -1) {
        generate.systems = generate.systems + 1;
    }

    if (obj.title.indexOf("%NAME1%") > -1 || obj.description.indexOf("%NAME1%") > -1) {
        generate.names = generate.names + 1;
    }

    if (obj.title.indexOf("%BOOK%") > -1 || obj.description.indexOf("%BOOK%") > -1) {
        generate.books = generate.books + 1;
    }

    if (obj.title.indexOf("%CHARITY%") > -1 || obj.description.indexOf("%CHARITY%") > -1) {
        generate.charities = generate.charities + 1;
    }

    if (obj.title.indexOf("%ITEM%") > -1 || obj.description.indexOf("%ITEM%") > -1) {
        generate.items = generate.items + 1;
    }

    if (obj.title.indexOf("%JOB%") > -1 || obj.description.indexOf("%JOB%") > -1) {
        generate.jobs = generate.jobs + 1;
    }

    if (obj.title.indexOf("%GOODS%") > -1 || obj.description.indexOf("%GOODS%") > -1) {
        generate.goods = generate.goods + 1;
    }

    if (obj.title.indexOf("%RACE%") > -1 || obj.description.indexOf("%RACE%") > -1) {
        generate.races = generate.races + 1;
    }

    if (obj.title.indexOf("%LIQUOR%") > -1 || obj.description.indexOf("%LIQUOR%") > -1) {
        generate.liquors = generate.liquors + 1;
    }

    if (obj.title.indexOf("%MOVIE%") > -1 || obj.description.indexOf("%MOVIE%") > -1) {
        generate.movies = generate.movies + 1;
    }

    if (obj.title.indexOf("%MUSIC%") > -1 || obj.description.indexOf("%MUSIC%") > -1) {
        generate.music = generate.music + 1;
    }

    if (obj.title.indexOf("%ART%") > -1 || obj.description.indexOf("%ART%") > -1) {
        generate.art = generate.art + 1;
    }

    if (obj.title.indexOf("%PAINTING%") > -1 || obj.description.indexOf("%PAINTING%") > -1) {
        generate.paintings = generate.paintings + 1;
    }

    //

    obj.tasks = [{}];

    // Procedural generation
    obj.tasks[0].info = this.$generateInfo(generate, 12, maxSystemDistance, []);

    //

    obj.title = this.$replaceKeys(obj.title, obj);
    obj.description = this.$replaceKeys(obj.description, obj);

    _co.$log("obj.title = " + obj.title);

    return obj;
}

this.$replaceKeys = function (text, mObj) {
    _co.$log("[LITF_Mission] replaceKeys");

    while (text.indexOf("%SYSTEM0%") > -1) { text = text.replace("%SYSTEM0%", mObj.startingSystem.name); }
    while (text.indexOf("%SYSTEM1%") > -1) { text = text.replace("%SYSTEM1%", mObj.tasks[0].info.systems[0].name); }
    while (text.indexOf("%SYSTEM2%") > -1) { text = text.replace("%SYSTEM2%", mObj.tasks[1].info.systems[0].name); }

    while (text.indexOf("%NAME0%") > -1) { text = text.replace("%NAME0%", mObj.contractor); }
    while (text.indexOf("%NAME1%") > -1) { text = text.replace("%NAME1%", mObj.tasks[0].info.names[0]); }
    while (text.indexOf("%NAME2%") > -1) { text = text.replace("%NAME2%", mObj.tasks[1].info.names[0]); }

    while (text.indexOf("%PLAYERNAME%") > -1) { text = text.replace("%PLAYERNAME%", player.name); }

    while (text.indexOf("%REWARD%") > -1) { text = text.replace("%REWARD%", mObj.reward); }

    while (text.indexOf("%BOOK%") > -1) { text = text.replace("%BOOK%", mObj.tasks[0].info.books[0]); }
    while (text.indexOf("%CHARITY%") > -1) { text = text.replace("%CHARITY%", mObj.tasks[0].info.charities[0]); }
    while (text.indexOf("%ITEM%") > -1) { text = text.replace("%ITEM%", mObj.tasks[0].info.items[0]); }
    while (text.indexOf("%JOB%") > -1) { text = text.replace("%JOB%", mObj.tasks[0].info.jobs[0]); }
    while (text.indexOf("%GOODS%") > -1) { text = text.replace("%GOODS%", mObj.tasks[0].info.goods[0]); }
    while (text.indexOf("%RACE%") > -1) { text = text.replace("%RACE%", mObj.tasks[0].info.races[0]); }
    while (text.indexOf("%LIQUOR%") > -1) { text = text.replace("%LIQUOR%", mObj.tasks[0].info.liquors[0]); }
    while (text.indexOf("%MOVIE%") > -1) { text = text.replace("%MOVIE%", mObj.tasks[0].info.movies[0]); }
    while (text.indexOf("%MUSIC%") > -1) { text = text.replace("%MUSIC%", mObj.tasks[0].info.music[0]); }
    while (text.indexOf("%ART%") > -1) { text = text.replace("%ART%", mObj.tasks[0].info.art[0]); }
    while (text.indexOf("%PAINTING%") > -1) { text = text.replace("%PAINTING%", mObj.tasks[0].info.paintings[0]); }

    while (text.indexOf("%PASSENGERS%") > -1) { text = text.replace("%PASSENGERS%", _bbs.$howManyPassengers(mObj)); }

    return text;
}

this.$missionAllocatedTime = function (mObj) {
    _co.$log("[LITF_Mission] missionAllocatedTime");

    var time = 0;
    var totalTime = 0;
    var route = null;
    var multi = 0;

    if (mObj.local === false) {
        var tasks = mObj.tasks.length;

        if (tasks === 1) {
            route = _co.$getSystemRoute(mObj.startingSystem.id, mObj.tasks[0].info.systems[0].id);

            if (mObj.tasks[0].urgent === true) {
                multi = 1.2;
            } else {
                multi = 1.5
            }
            totalTime = route.time * multi;
        } else if (tasks > 1) {
            for (var ta = 0; ta < mObj.tasks.length; ta++) {
                if (ta === 0) {
                    route = _co.$getSystemRoute(mObj.startingSystem.id, mObj.tasks[0].info.systems[0].id);
                } else {
                    route = _co.$getSystemRoute(mObj.tasks[ta - 1].info.systems[0].id, mObj.tasks[ta].info.systems[0].id);
                }

                if (mObj.tasks[ta].urgent === true) {
                    multi = 1 + parseInt(_co.$roll(1, 3) / 10);
                } else {
                    multi = 1 + parseInt(_co.$roll(3, 6) / 10);
                }

                totalTime = totalTime + (route.time * multi);
            }
        }
        time = totalTime * 3600; // seconds
    } else {
        time = 0;
    }

    // Debug //
    if (_litf.litfVars.config.debug === true) {
        // time = 30;
    }

    return Math.round(time);
}

this.$missionReward = function (mObj) {
    _co.$log("[LITF_Mission] missionReward2");

    var baseReward = 50;

    var passengers = 0;
    var urgentTask = false;
    var risk = 0;

    var reward = 0;
    var partialReward = 0;
    var multi = 1;

    // Missions without rewards
    if (mObj.noReward === true) {
        return -1;
    }

    // Local missions
    if (mObj.local === true) {
        _co.$log("local missions not implemented.")
        return 0;
    }

    // Non-local missions

    var taskNum = mObj.tasks.length;
    _co.$log("tasks = " + taskNum);

    var absFeedback = Math.abs(_litf.litfCommander.feedback); // Absolute value player feedback
    multi = parseInt(absFeedback / 30);

    var groupMissionCompleted = _litf.litfCommander.statistics.missionCompleted[mObj.groupId];
    if (groupMissionCompleted > 0 && groupMissionCompleted <= 50) {
        multi += parseInt(groupMissionCompleted / 10);
    }

    //

    if (taskNum === 1) {
        if (mObj.tasks[0].typeId === 5) {
            var cargoGoods = mObj.tasks[0].info.goods[0];
            var scPrice = _co.$getSubCommodityPrice(cargoGoods);
            var cargoTotal = _co.$roll(1, player.ship.cargoSpaceAvailable);

            var subPrice = parseInt((scPrice * cargoTotal) / 3);
            baseReward = baseReward + subPrice;

            _co.$log("cargoGoods[" + cargoGoods + "] scPrice[" + scPrice + "] cargoTotal[" + cargoTotal + "] subPrice = " + subPrice);
        }

        if (mObj.passengers) { passengers = mObj.passengers; }
        if (passengers > 2) { multi = multi + 1; } // Small groups
        if (passengers > 4) { multi = multi + 1; } // Large groups

        if (mObj.tasks[0].urgent) { urgentTask = mObj.tasks[0].urgent; }
        if (urgentTask === true) { multi = multi + 1; }

        if (mObj.risk) { risk = mObj.risk; }
        multi = multi + risk;

        partialReward = baseReward * multi;
    } else {
        for (var ta = 0; ta < taskNum; ta++) {
            var task = mObj.tasks[ta];

            multi = parseInt(absFeedback / 10);
            if (mObj.risk) { risk = mObj.risk; }
            multi = multi + risk;

            passengers = 0;
            if (task.passengers) { passengers = task.passengers; }
            if (passengers > 2) { multi = multi + 1; } // Small groups
            if (passengers > 4) { multi = multi + 1; } // Large groups

            urgentTask = false;
            if (task.urgent) { urgentTask = task.urgent; }
            if (urgentTask === true) { multi = multi + 1; }

            partialReward = partialReward + (baseReward * multi);
        }
    }

    var missionTimeHours = parseInt(mObj.timeAllowed / 3600);
    var multiTime = 11 - parseInt(missionTimeHours / 10);
    if (multiTime < 1) { multiTime = 1; }
    var timeReward = multiTime * 100;
    reward = partialReward + timeReward;

    // // var pricePerHour = 10;
    // reward = partialReward + (missionTimeHours * pricePerHour);
    _co.$log("reward = " + reward);

    // Adjust by system economy
    var econDesc = system.economyDescription;
    if (econDesc.indexOf("Rich") !== -1) {
        reward = parseInt(reward / 100 * 110);
    } else if (econDesc.indexOf("Poor") !== -1) {
        reward = parseInt(reward / 100 * 75);
    } else if (econDesc.indexOf("Mainly")) {
        reward = parseInt(reward / 100 * 90);
    }

    return reward;
}
Scripts/LITF_Station_alpha.js
/* eslint-disable semi, no-multi-spaces, quotes, indent, no-tabs, yoda */
/* global worldScripts, mission, setScreenBackground, system */

"use strict";

this.name	     = "LITF_Station_ALPHA";
this.author	     = "BeeTLe BeTHLeHeM";
this.copyright	 = "2018 BeeTLe BeTHLeHeM";
this.description = "Experimental Station Navigation (ALPHA)";
this.version	 = "0.10.0";
this.licence	 = "CC BY-NC-SA 4.0";

var _co  = null;
var _mi = null;
var _litf = null;

var $goPlace = this.$goPlace;

this.litfNavigation = null;

this.$init = function () {
    _co = worldScripts.LITF_Common;
    _mi = worldScripts.LITF_Missions;
    _litf = worldScripts.LITF;

    var stationData = _litf.litfVars.stationParams;
    var sGroups = _mi.groupsByGov[stationData.government];

    this.litfNavigation = {
        currentLocation: null,
        lastLocation: null,
        stationMapTemplate: this.testStationMap,
        systemTL: system.techLevel,
        stationData: stationData,
        stationGroups: sGroups
    };
}

this.$start = function () {
	this.$goPlace("hangar");
};

this.$goPlace = function (location) {
    var title = "Roaming Around the Station";

    this.litfNavigation.lastLocation = this.litfNavigation.currentLocation;
    this.litfNavigation.currentLocation = location;

    var locationData = this.$getLocation(location);

    var text = "LOCATION: " + locationData.name + "\n\n" + locationData.description;

    var choices = this.$checkChoices(locationData.choices);

    var opts = {
        title: title,
        exitScreen: "GUI_SCREEN_INTERFACES",
        message: text,
        choices: choices
    };

    mission.runScreen(opts, this.$executeChoice);

    if (locationData.background) {
        // setScreenBackground(locationData.background);
        setScreenBackground({ name: "images/" + locationData.background, height: 480 });
    }
};

this.$checkChoices = function (choiceArr) {
    var choices = {};
    var value = -1;

    for (var c = 0; c < choiceArr.length; c++) {
        var cObj = choiceArr[c];

        var valid = true;
        if (cObj.requires) {
            var crSplit = cObj.requires.split(",");
            for (var cr = 0; cr < crSplit.length; cr++) {
                var requires = crSplit[cr];
                var rSplit = requires.split(" ");

                if (rSplit[0] === "TL") {
                    if (rSplit[1] === "low") {
                        if (this.litfNavigation.systemTL > 5) {
                            valid = false;
                        }
                    } else if (rSplit[1] === "notlow") {
                        if (this.litfNavigation.systemTL < 6) {
                            valid = false;
                        }
                    } else if (rSplit[1] === "medium") {
                        if (this.litfNavigation.systemTL < 6 || this.litfNavigation.systemTL > 9) {
                            valid = false;
                        }
                    } else if (rSplit[1] === "high") {
                        if (this.litfNavigation.systemTL < 10) {
                            valid = false;
                        }
                    }
                } else if (rSplit[0] === "group") {
                    value = parseInt(rSplit[1]);

                    if (this.litfNavigation.stationGroups.indexOf(value) === -1) {
                        valid = false;
                    }
                }
            }
        }

        if (valid === true) {
            choices[cObj.label] = cObj.text;
        }
    }

    return choices;
}

this.$getLocation = function (locationId) {
    locationId = locationId.toLowerCase();

    _co.$log("[LITF_Station_alpha] getLocation : " + locationId);

    var stationMap = this.litfNavigation.stationMapTemplate;
    for (var l = 0; l < stationMap.locations.length; l++) {
        var loc = stationMap.locations[l];
        _co.$log("[" + l + "] " + loc.id);
        if (loc.id === locationId) {
            return loc;
        }
    }

    return null;
}

this.$executeChoice = function (choice) {
    var cSplit = choice.split("_"); // choice index _ command _ parameters...

    var command = cSplit[1];
    if (command === "QUIT") {
        _litf.$LITFinterface();
    } else if (command === "GOTO") {
        $goPlace(cSplit[2]);
    }
}

// -----------------------------------------------------------------------------

this.testStationMap = {
    locations: [
        {
            id: "hangar",
            name: "Hangar",
            description: "You see your ship, parked. There are other ships, in different conditions. You see a few of them being examined by the station droids, floating slowly around the hull detecting breaches.",
            background: "bg_hangar.png",
            choices: [
                { label: "01_QUIT", text: "Embark your ship." },
                { label: "02_GOTO_DOCKS", text: "Go to the Docks." }
            ]
        },
        {
            id: "docks",
            name: "Docks",
            description: "There's a lot of movement. You see droids moving crates and containers around, loading and offloading ships.",
            // background: "bg_docks.png",
            choices: [
                { label: "01_GOTO_LIFT", text: "Go to the Station Lift" },
                { label: "02_GOTO_HANGAR", text: "Enter the Hangar." },
                { label: "03_GOTO_STORAGE", text: "Enter the Storage Area.", requires: "TL medium" },
                { label: "04_GOTO_REPAIR", text: "Enter the Maintenance Area.", requires: "TL high" }
            ]
        },
        {
            id: "storage",
            name: "Storage Area",
            description: "You see an endless row of containers of various colors and size.",
            // background: "bg_storage.png",
            choices: [
                { label: "01_GOTO_DOCKS", text: "Go to the Docks." }
            ]
        },
        {
            id: "repair",
            name: "Maintenance Area",
            description: "Several crews of people are repairing different ships.",
            // background: "bg_repair.png",
            choices: [
                { label: "01_GOTO_DOCKS", text: "Go to the Docks." }
            ]
        },
        {
            id: "lift",
            name: "Station Lift Tube",
            description: "The lift tube has several cabins going up and down to different levels. People come and go, alone and in groups. There's a continuous activity here, and a constant background noise.",
            // background: "bg_lift.png",
            choices: [
                { label: "01_GOTO_DOCKS", text: "Take a cabin to the Docks Level." },
                { label: "02_GOTO_AGRINDUSTRIAL", text: "Take a cabin to the AgrIndustrial Level.", requires: "group 10" },
                { label: "03_GOTO_CIVIC", text: "Take a cabin to the Civic Level." },
                { label: "04_GOTO_ENTERTAINMENT", text: "Take a cabin to the Entertainment Level." },
                { label: "05_GOTO_TOURISM", text: "Take a cabin to the Tourism Level.", requires: "group 6" },
                { label: "06_GOTO_ADMIN", text: "Take a cabin to the Administrative Level." }
            ]
        },
        {
            id: "civic",
            name: "Civic Level Hub",
            description: "You're at the entrance of the civic level, where the station permanent and semi-permanent population resides outside of work.",
            // background: "bg_civic.png",
            choices: [
                { label: "01_GOTO_LIFT", text: "Go to the Station Lift" },
                { label: "02_GOTO_HIVES", text: "Go to the Common Hives", requires: "TL low" },
                { label: "03_GOTO_APARTMENTS", text: "Go to the Apartments Complex", requires: "TL notlow" },
                { label: "04_GOTO_LIBRARY", text: "Go to the Public Library", requires: "group 1" },
                { label: "05_GOTO_SQUARE", text: "Go to the Public Square", requires: "group 5" },
                { label: "06_GOTO_MEGAMALL", text: "Go to the MEGAMall", requires: "group 7,TL notlow" }
            ]
        }
    ]
}