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

Expansion Tionisla Chronicle Array

Content

Warnings

  1. Syntax Error Config/missiontext.plist[2:4] token recognition error at: '/**** Intros ****/\n\t"tca_intro" = "When you disembark, you find that there is a security cordon blocking entrance to the 'business' parts of the Array station. You may, however, still access the ship's outfitters, a cafe, a museum and the rest rooms. The museum has a section on the building of this array and another on the history of the Tionisla Chronicle.";\n\n\t/**** For Tionisla Reporter OXP ****/\n\t// Mission screen that appears once per save upon docking with Tionisla main station if mission has not been started/declined yet\n\t"tca_erehwonReconnaissance_lure" = "When you leave your ship, you bump into an old Lave Academy classmate - [nom] - who greets you - and then offers some local information: \n\n\"Do you know that the Tionisla Chronicle Array is on the darkside of this planet? The Chronicle newsrooms are based there too. Sometimes they have jobs on offer for inexperienced pilots - they are supposed to pay well, but you would need the spare time to do whatever the job involves. You have to visit the Tionisla Chronicle Array on the other side of this planet to find out what they have. Oh! I'd better go - they are calling me\"";\n\n\t// Entries with "tca_erehwonReconnaissance_*" alter original "erehwonReconnaissance_*"\n\t"tca_erehwonReconnaissance_preamble" = "When you leave your ship, you find a tall blue-feathered avian waiting by the airlock.\n\n\"Greetings Commander [commander_name]... I'm Havel Burquist, a correspondent of the %J124 Chronicle. Would you care to accompany me to my office? Our science editor has an offer which might be of interest to you.\"";\n\n\t"tca_erehwonReconnaissance_choice0" = {\n\t\t"OFFER_ACCEPTED" = "Accompany Havel Burquist";\n\t\t"OFFER_DECLINED" = "Decline";\n\t};\n\n\t// The briefing is split into 3 parts because it too long for one screen\n\t"tca_erehwonReconnaissance_briefing_p1" = "You are taken through the security cordon and move into a long gleaming corridor lined with doors, and with various people hurrying from one room to another. At the end you walk through large double doors into a brightly-lit newsroom full of bustling reporters, desks and broadcasting equipment. Is that the famous newscaster Anna Mereso over on the right? She is busy talking with a group of masked lizards. Burquist rushes you through the room to some stairs on the other side and then up to a glass-walled office overlooking the newsroom.";\n\n\t"tca_erehwonReconnaissance_briefing_p2" = "In the office you find a fat furry feline sitting at a desk. He rises and shakes your hand.\n\n\"Welcome to the Tionisla Chronicle! I am Kaleb Quequeg, the senior science editor. Please take a seat. May I offer you a drink? There is whisky, lethal brandy, vicious brew, even some Oo-lite - if you drink the stuff!\n\nSo, what do you think of our Array? Built at great expense, you know - there are dozens of those hexagonal high-intensity transmitter panels - each of them are massive and each cost over 10 million credits to fabricate. And that's before we start talking about how much energy they gobble up! Or the never-ending task of keeping them all clean and functioning.\"";\n\n\t"tca_erehwonReconnaissance_briefing_p3" = \t"\"As you will know, we are the biggest, most respected news organisation in the Galaxy.\n\nWe have heard some interesting rumours of a hidden planet, deep in interstellar space, three light years to the west of %J144.\n\nWe are looking for an adventurous pilot to try and find the planet. You would need to take some pictures of the station that apparently orbits it - as well as dock there and interview someone on the station. And then you would need to come back here to deliver the photographs - and the interview information - to me.\n\nWould you be interested in accepting this assignment?\"";\n\t\n\n\t"tca_erehwonReconnaissance_debriefing" = "After disembarking from your ship you are met by a raucous red rodent who greets you and ushers you through the security cordon, the corridors and the newsroom to Kaleb Quequeg's office. \n\n\"Well done Commander [commander_name]!\" he says, his feline features forming into a grin. \"We've removed the special camera from your ship... you managed to get some very nice pics indeed. Now tell me, did you get to talk to anyone on the station? What were they like? Are the locals human? Were there other ships?\"\n\nYou relate the barkeep's tale about Erehwon, describing the interior of the station, and telling him about the other ships that you saw arriving and leaving. He records your words on his compad, and seems very excited by your tale.\n\n\"Thank you Commander [commander_name], the %J124 Chronicle is very pleased and we have transferred the amount of 500 credits to your account, as promised.\"";\n\n\t"tca_erehwonReconnaissance_failure" = "As soon as you disembark you are met by a timid turquoise toad and ushered through the security cordon, the corridors and the newsroom to Kaleb Quequeg's office. You spend a few moments describing what you found at Erehwon, which he records onto his compad.\n\n\"A very interesting voyage you describe, Commander [commander_name]! We've removed the special camera from your ship... we could not find any useful pics.\n\n We are especially interested in pictures of the station orbiting the planet... There were no suitable ones on your film... maybe you would like to have a second chance with a new camera and another 10 shots?\"";\n\n\t"tca_erehwonReconnaissance_damaged" = "As soon as you disembark you are met by a bombacious blue beetle and ushered through the security cordon, the corridors and the newsroom to Kaleb Quequeg's office. You spend a few moments describing what you found at Erehwon, which he records onto his compad.\n\n\"A very interesting voyage you describe, Commander [commander_name]! We've removed the special camera from your ship... we could not find any useful pics because the photo camera was damaged... maybe you would like to have a second chance with a new camera and another 10 shots?\"";\n\n\t"tca_erehwonReconnaissance_missioninfo2" = "Deliver your article at the %J124 Chronicle Array.";\n}\n'
  2. Syntax Error Config/missiontext.plist[33:0] mismatched input '<EOF>' expecting {'}', STRING}
  3. Found 2 issues in Config/missiontext.plist
  4. Information URL mismatch between OXP Manifest and Expansion Manager string length at character position 0

Manifest

from Expansion Manager's OXP list from Expansion Manifest
Description Adds the Tionisla Chronicle array to the Tionisla system. An array is also added to one system in each galactic sector. Adds the Tionisla Chronicle array to the Tionisla system. An array is also added to one system in each galactic sector.
Identifier oolite.oxp.Storm.TionislaChronicleArray oolite.oxp.Storm.TionislaChronicleArray
Title Tionisla Chronicle Array Tionisla Chronicle Array
Category Dockables Dockables
Author Storm Storm
Version 1.05 1.05
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/4/49/TionislaChronicleArray.oxz n/a
License CC-BY-NC-SA 3.0 CC-BY-NC-SA 3.0
File Size n/a
Upload date 1686145539

Documentation

Also read http://wiki.alioth.net/index.php/Tionisla%20Chronicle%20Array

Readme.txt

TIONISLA CHRONICLE ARRAY OXP (Version 1.04)

This OXP will add a few new broadcast arrays throughout the eight galactic charts.

The famous Tionisla Chronicle Array can be found in orbit on the dark side of Tionisla (Chart 1)

You will also be able to find:

The Views of the Worlds Array   (Xeabiti, Chart 2)
The GNN Array                   (Geusdi, Chart 3)
The Daily Wail Array            (Quonzo, Chart 4)
The G5TVN Array                 (Maeser, Chart 5)
The Rooters Array               (Tiregees, Chart 6)
The StarSports Array            (Zarausxe, Chart 7)
The Snoopers Array              (Maabile, Chart 8)

(StarSports being my own 'channel' creation)

Please Note that:

Broadcast Arrays have a hexagon icon for the Advanced Space Compass to help you locate them.
No market or extra equipment (except fuel) are available at the TCA (though other OXP's might effect this)

In future versions, you can expect*
- Texturing / shaders / lighting improvements
- Missions

(*as authors free time allows)

This OXP is requires Oolite v1.79

Author: Storm

To install this OXP the '.oxp' folder should be moved to your Oolite AddOns folder. Consult the Wiki or BB if you are not sure where this is. 

This work is licensed under the Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.

My thanks to:
Drew for letting me use the TCA from his stories!
DaddyHoggy, Svengali, Drew and Disembodied for GNN, Rooters and Snoopers
DaddyHoggy again for Views of the Worlds and the Daily Wail
Smivs for G5TVN
Arhuman, Griff and Thargoid for the various shader and script snippets (large and small) I borrowed from their own OXP's to get this one working!
Okti for the assistance in putting the TCA into orbit in the right position and getting this Beta properly in order for initial release!
Cim for the workaround script advice for the logo changing on the docking display screen
Fatleaf and Commander McLane for the help in bugfixing shader scripts
... and various others for the bug reports!

Version History:
V1.01 - 18/03/12: Slight fix to shader .fragment files for older OpenGL issues
V1.02 - 18/03/12: Another slight fix, hoping to get more of those .fragment issues resolved
V1.03 - 19/03/12: The docking display 'billboards' should now be correctly scrolling for older OpenGL versions
V1.04 - 08/11/17: (phkb) Updated populator to allow for saving at stations. Texture update. Packaged as OXZ.
V1.05 - 03/06/23: (Alnivel) Moved Tionisla Reporter mission to the station. Added limited shipyard and a few LibPAD entries.

Equipment

Name Visible Cost [deci-credits] Tech-Level
Advanced Navigational Array yes 22500 1+
Remove Broadcast Comms MFD no 500 1+
Broadcast Comms MFD yes 2000 1+
Electronic Thumb yes 9850 1+
Witchdrive Fuel Injectors yes 6000 1+
Range Finder Extender yes 26500 1+
Remove Range Finder MFD yes 15000 1+
Range Finder MFD yes 2500 1+
Remove Range Finder MFD yes 1000 1+
Mining Beacon Descrambler yes 500 1+
Scanner Alerting Enhancement yes 7500 1+
Ship's Library Flight Interface yes 2000 1+
Express Tea Maker yes 1000 1+
Tracker yes 25000 1+
Target Mod yes 15000 1+
Target Mod yes 25000 1+
Travel Mod yes 10000 1+
Wormhole Scanner yes 23950 1+

Ships

Name
Broadcast Array
Broadcast Array Arm
Broadcast Array Navbouy
Broadcast Array Display Screen
Broadcast Array Docking Port

Models

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

Scripts

Path
Scripts/tca_conditions.js
"use strict";
this.name = "Tionisla Chronicle Array - Equipment Conditions";


this.$oxpPostfix = "_TCA";
this.$oxpEqPostfixOffset = -this.$oxpPostfix.length;

this.allowAwardEquipment = function(equipmentKey, ship, _context)
{
    const station = player.ship.dockedStation;
    if(!station || station.dataKey !== "broadcast_array") {
        return false;
    }

    const tail = equipmentKey.slice(this.$oxpEqPostfixOffset);
    if(tail !== this.$oxpPostfix) {
        log("Tionisla Chronicle Array", "Equipment key doesn't have correct postfix.");
        return false; // or true?
    }

    const originalEquipmentKey = equipmentKey.slice(0, this.$oxpEqPostfixOffset);
    
    return ship.canAwardEquipment(originalEquipmentKey);
}

this.updateEquipmentPrice = function(equipmentKey, currentPrice)
{
    const originalEquipmentKey = equipmentKey.slice(0, this.$oxpEqPostfixOffset);
    const equipmentInfo = EquipmentInfo.infoForKey(originalEquipmentKey);
    if(!equipmentInfo) {
        log("Tionisla Chronicle Array", "There is no \"" + originalEquipmentKey + "\" key");
        return currentPrice;
    }

    const employeeDiscount = galaxyNumber === 0 && missionVariables.tionisla_tr_finale === "SUCCESS";
    const priceMult = 1 - (employeeDiscount? 0.25 : 0.1)

    return equipmentInfo.calculatedPrice * priceMult;
}
Scripts/tca_conditions_removal.js
"use strict";
this.name = "Tionisla Chronicle Array - Equipment Removal Conditions";


this.allowAwardEquipment = function(_equipmentKey, _ship, _context) 
{
    const station = player.ship.dockedStation;

    return station && station.dataKey === "broadcast_array";
}
Scripts/tca_script.js
"use strict";
this.name			= "Tionisla Chronicle Array OXP";
this.author			= "Storm";
this.copyright		= "Creative Commons Attribution - Non-Commercial - Share Alike 3.0 license";
this.description	= "Addition of a Broadcast Array station to each galactic chart";

// Arrays for the Broadcast Arrays locations by planet, their shipdata.plist names, and 'channel' name 
this.broadcastArrayPlanet = [124, 103, 197, 58, 211, 225, 184, 206];
this.broadcastArrayName = ["Tionisla Chronicle", "Views of the Worlds", "GNN", "Daily Wail", "G5TVN", "Rooters", "StarSports", "Snoopers"];
this.broadcastChannel = ["tca", "votw", "gnn", "dailywail", "g5tvn", "rooters", "starsports", "snoopers"];
this._debug = false;

this.systemWillPopulate = function() {
	// Check if in a system where a Broadcast Array is based, and add if so...
	if(system.ID == this.broadcastArrayPlanet[galaxyNumber] || this._debug === true) {
		if(system.countShipsWithRole("broadcast_array") == 0) {
			// Work out the location for placement of the Broadcast Array and it's beacon...
			var vector = system.mainPlanet.position.subtract(system.sun.position).direction();
			var arraypos = system.mainPlanet.position.add(vector.multiply(system.mainPlanet.radius * 4));

			system.setPopulator("tca", {
				priority: 200,
				location: "COORDINATES",
				groupCount: 1,
				callback: function(pos) {
					var tca = worldScripts["Tionisla Chronicle Array OXP"];
					// Add Broadcast Array to system...
					var broadcastArray = system.addShips("broadcast_array", 1, pos, 0)[0];
					broadcastArray.orientation = system.mainPlanet.position.subtract(broadcastArray.position).direction().rotationTo([0, 0, 1]);
					broadcastArray.scannerDisplayColor1 = "25 100 175";
					broadcastArray.scannerDisplayColor2 = "50 150 255";

					var vect = system.mainPlanet.position.subtract(system.sun.position).direction();
							
					// Add the Broadcast Array's Beacon to system...
					var buoyPos = system.mainPlanet.position.add(vect.multiply((system.mainPlanet.radius * 4) - 10000));
					var navbuoy = system.addShips("broadcast_array_beacon", 1, buoyPos, 0)[0];
					navbuoy.orientation = system.mainPlanet.position.subtract(broadcastArray.position).direction().rotationTo([0,0,1]);
					// Change the Broadcast Array's docking display / beacon to match the appropriate 'channel'...
					broadcastArray.displayName = (tca.broadcastArrayName[galaxyNumber] + " Array");
					broadcastArray.beaconLabel = (tca.broadcastArrayName[galaxyNumber] + " Array");
					var broadcastDisplayEmissionPng = (tca.broadcastChannel[galaxyNumber] + "_display_emission_map.png");
					broadcastArray.subEntities[4].setMaterials(
						{"broadcast_array_display.png":{diffuse_map: "broadcast_array_display.png", emission_map: broadcastDisplayEmissionPng}}
					);
					// Can't pass galaxy number to shader so hack to pass it via 'fuel' instead... this will allow
					// the broadcast arrays scrolling display in dock to 'change channel' to appropriate galaxy
					broadcastArray.fuel = galaxyNumber / 10;
					navbuoy.displayName = (tca.broadcastArrayName[galaxyNumber] + " Navigation Buoy");
					var navbuoyPng = (tca.broadcastChannel[galaxyNumber] + "_beacon.png");
					navbuoy.setMaterials({"broadcast_array_beacon.png": { diffuse_map: navbuoyPng }});

				},
				coordinates:arraypos,
				deterministic:true
			});
		}		
	}
}

this.shipWillLaunchFromStation = function(station) {
	if(station.hasRole("broadcast_array")) {
		missionVariables.trumbles = missionVariables.broadcastArray_storeTrumble; 
		// reactivate offer of trumble mission if it was available before docking
		missionVariables.broadcastArray_storeTrumble = null;
	}
}

this.shipWillDockWithStation = function(station) {
	if(station.hasRole("broadcast_array")) {
		// delay offer of trumble mission whilst docked at a broadcast array
		missionVariables.broadcastArray_storeTrumble = missionVariables.trumbles;
		missionVariables.trumbles = null;
	} 
}

/* Monkey-patch for TR - added by Alnivel and therefore and therefore all the blame on him */

this.startUp = function startUp() {
    const tr = worldScripts["Tionisla Reporter"];
    if (tr) {
        tr.$TCA_addErewhonPADPages = this.$TCA_addErewhonPADPages;
        tr.$TCA_missionOffers_original = tr.missionOffers;
        tr.missionOffers = this.$TCA_missionOffers_replacement;
        tr.$TCA_choiceEvaluation_preamble = this.$TCA_choiceEvaluation_preamble;
    }

    this.$trScript = tr;
};

this.startUpComplete = function startUpComplete() {
	if (this.$trScript) {
        if (!missionVariables.tca_tr_erehwonVisited) {
            missionVariables.tca_tr_erehwonVisited = +(
                missionVariables.tca_tr_finale === "SUCCESS" ||
                missionVariables.erehwonGotStory === "YES"
            );
        }        
    }

    const Lib_PAD = this.$Lib_PAD = worldScripts.Lib_PAD;

	if(Lib_PAD) {
		Lib_PAD._addPageInCategory("SYSTEMS.Tionisla G1",
			{
				name: "Tionisla G1",
				info: [
					"Located in the south-west of Galaxy 1.",
					"The Lizards of Tionisla wears mechanical masks in public.",
					"Home of the Tionisla Orbital GraveYard (TOGY).",
					"Home of the Tionisla Chronicle and its Array (TCA)."
				]
			});
		if (missionVariables.tca_tr_erehwonVisited) {
			this.$TCA_addErewhonPADPages();
		}
        if(missionVariables.tca_intro) {
            this.$addTCAPADPages();
        }
	}    
};

this.$addTCAPADPages = function $addTCAPADPages() {
    const Lib_PAD = this.$Lib_PAD;
    if (!Lib_PAD)
        return;

    Lib_PAD._addPageInCategory("INFOS.Tionisla Chronicle Array",
        { // Page content
            name: "Tionisla Chronicle Array",
            beacon: "Tionisla Chronicle Array",
            location: "In high orbit on the dark side of Tionisla",
            purpose: "Massive communications platform",
            special: [
                // Results of the missions?
            ],
            t1: "tca_lib_pad_tca.png"
        }, 
        [ // Page parents
            "SYSTEMS.Tionisla G1"
        ]);
}

this.missionScreenOpportunity = function missionScreenOpportunity() {
    if (galaxyNumber === 0 && system.ID == 124) {
        const dockedStation = player.ship.dockedStation;

        if (dockedStation.dataKey === "broadcast_array" && !missionVariables.tca_intro) {
            missionVariables.tca_intro = 1;
            mission.runScreen({
                screenID: "tca_intro",
                title: "Tionisla Chronicle Array",
                messageKey: "tca_intro"
            });
            this.$addTCAPADPages();
        }
    }
};


this.shipDockedWithStation = function (station) {
    if (station.displayName === "Erehwon Station") {
        missionVariables.tca_tr_erehwonVisited = 1;
        this.$TCA_addErewhonPADPages();
    }
};

this.$TCA_addErewhonPADPages = function $TCA_addErewhonPADPages() {
	const Lib_PAD = worldScripts.Lib_PAD;
	if(!Lib_PAD)
		return

	Lib_PAD._addPageInCategory("SYSTEMS.Erewhon G1",
        {
            name: "Erewhon G1",
            info: [
                "Located in the centre-west of Galaxy 1.",
                "rare metals etc. Imports food, liquor, narcotics & slaves.",
                "Planet is inhabited by lizards & rich in mineral deposits,",
                "'Lost' planet in interstellar space between Biorle & Usle."
            ]
        });
};


this.$TCA_missionOffers_replacement = function missionOffers_TionislaChronicleArray() {
    // this === worldScripts["Tionisla Reporter"]
    const dockedStation = player.ship.dockedStation;
    const erehwonReconnaissance = missionVariables.erehwonReconnaissance;

    let passToOriginalHandler = true;

    if (system.ID == 124) { // Tionisla
        passToOriginalHandler = false;

        
        if (dockedStation.isMainStation &&
            erehwonReconnaissance === "START" &&
            !missionVariables.tca_tr_lureWasShown) {

            mission.runScreen({
                screenID: "tionisla_reporter",
                title: "Tionisla Chronicle",
                messageKey: "tca_erehwonReconnaissance_lure"
            });
            missionVariables.tca_tr_lureWasShown = 1;
        }
        else if (dockedStation.dataKey === "broadcast_array") {
            // Do not show scene on main station if we already was at broadcast array
            missionVariables.tca_tr_lureWasShown = 1;

            if (erehwonReconnaissance === "START") {
                mission.runScreen({
                    screenID: "tionisla_reporter",
                    title: "Tionisla Chronicle",
                    messageKey: "tca_erehwonReconnaissance_preamble",
                    choicesKey: "tca_erehwonReconnaissance_choice0"
                }, this.$TCA_choiceEvaluation_preamble
                );
            }
            else if (erehwonReconnaissance === "SUCCESS") {
                mission.runScreen({
                    screenID: "tionisla_reporter",
                    title: "Tionisla Chronicle",
                    messageKey: "tca_erehwonReconnaissance_debriefing",
                    model: "erehwonStation"
                }
                );
                mission.displayModel.orientation = [0.75, 0, -0.6, 0];
                delete missionVariables.erehwonGotStory;
                delete missionVariables.erehwonFotoShot;
                delete missionVariables.erehwonPictureCount;

                delete missionVariables.erehwomMisJumpInfo;
                missionVariables.erehwonReconnaissance = "EPILOGUE";
                missionVariables.erehwonEpilogue = 1;
                missionVariables.erehwonActiontime = clock.days + 30;
                player.ship.removeEquipment("EQ_EREHWON_PHOTOCAMERA");
                mission.setInstructionsKey(null);
                this.$unmarkSystem(124);
                player.credits += 500;

                // 
                missionVariables.tca_tr_finale = "SUCCESS";
                //
            }
            else if (erehwonReconnaissance === "ACCEPTED" &&
                missionVariables.erehwonPictureCount == 0 && missionVariables.erehwonFotoShot === "NO") {
                mission.runScreen({
                    screenID: "tionisla_reporter",
                    title: "Tionisla Chronicle",
                    messageKey: "tca_erehwonReconnaissance_failure",
                    choicesKey: "erehwonReconnaissance_choice2"
                }, this.choiceEvaluation
                );
            }
            else if (erehwonReconnaissance === "ACCEPTED" &&
                player.ship.equipmentStatus("EQ_EREHWON_PHOTOCAMERA") === "EQUIPMENT_DAMAGED") {
                mission.runScreen({
                    screenID: "tionisla_reporter",
                    title: "Tionisla Chronicle",
                    messageKey: "tca_erehwonReconnaissance_damaged",
                    choicesKey: "erehwonReconnaissance_choice2"
                }, this.choiceEvaluation
                );
            }
        }
        else if(erehwonReconnaissance === "FINISHED" || erehwonReconnaissance === "EPILOGUE"){
            passToOriginalHandler = true;
        }
    }

    if(passToOriginalHandler) {
        // "DECLINED" is set in mission screen callback, so check at next mission screen opportunity
        if (missionVariables.erehwonReconnaissance === "DECLINED") {
            missionVariables.tca_tr_finale = "DECLINED";
        }

        this.$TCA_missionOffers_original();

        if (dockedStation.displayName === "Erehwon Station" && missionVariables.erehwonReconnaissance === "SUCCESS") {
            mission.setInstructionsKey("tca_erehwonReconnaissance_missioninfo2");
        }
    }


};

this.$TCA_choiceEvaluation_preamble = function (choice) {
    switch (choice) {
        case "OFFER_ACCEPTED":
            // If the mission screen has no choices then the callback's choice argument is null
            // Can (and should) I somehow distinguish if screen was ended with Space or interupted with F1?
            // If yes, then F1 == OFFER_DECLINED?

            let runPart3Callback = function (choice) {
                mission.runScreen({
                    screenID: "tionisla_reporter",
                    title: "Tionisla Chronicle",
                    messageKey: "tca_erehwonReconnaissance_briefing_p3",
                    choicesKey: "erehwonReconnaissance_choice"
                }, this.choiceEvaluation
                );
            };

            let runPart2Callback = function (choice) {
                mission.runScreen({
                    screenID: "tionisla_reporter",
                    title: "Tionisla Chronicle",
                    messageKey: "tca_erehwonReconnaissance_briefing_p2"
                }, runPart3Callback
                );
            };

            mission.runScreen({
                screenID: "tionisla_reporter",
                title: "Tionisla Chronicle",
                messageKey: "tca_erehwonReconnaissance_briefing_p1"
            }, runPart2Callback
            );

            break;
        case "OFFER_DECLINED":
            missionVariables.erehwonReconnaissance = "DECLINED";
            missionVariables.erehwonActiontime = clock.days + 30;
            break;
    }
};

/*** Limited shipyard with discount ***/
this.$oxpEqPostfix = "_TCA";
this.$oxpEqPostfixOffset = -this.$oxpEqPostfix.length;

this.$removalEqInfix = "_REMOVAL";
this.$removalEqInfixOffset = -this.$removalEqInfix.length + this.$oxpEqPostfixOffset;

this.playerBoughtEquipment = function playerBoughtEquipment(equipmentKey) {
    const postfix = equipmentKey.slice(this.$oxpEqPostfixOffset);
    if (postfix !== this.$oxpEqPostfix) {
        return;
    }

    const infix = equipmentKey.slice(this.$removalEqInfixOffset, this.$oxpEqPostfixOffset);
    if (infix === this.$removalEqInfix) {
        let originalEquipmentKey = equipmentKey.slice(0, this.$removalEqInfixOffset);
        let removalEquipmentKey = equipmentKey.slice(0, this.$oxpEqPostfixOffset);
        let ps = player.ship;

        switch (originalEquipmentKey) { // there may be some nontrivial cases
            case "EQ_GCM_RANGE_FINDER":
                originalEquipmentKey = "EQ_GCM_RANGE_FINDER_MFD";
            case "EQ_GCM_RANGE_FINDER_EXT":
                let ws = worldScripts.GalCopBB_RangeFinder_MFD;
                ps.removeEquipment(equipmentKey);
                ws.playerBoughtEquipment(removalEquipmentKey);
                break;
            default:
                ps.removeEquipment(equipmentKey);
                ps.removeEquipment(originalEquipmentKey);
                // No money back?
                break;
        }

    }
    else {
        let originalEquipmentKey = equipmentKey.slice(0, this.$oxpEqPostfixOffset);

        let success = false;
        switch (originalEquipmentKey) { // there may be some nontrivial cases
            default:
                player.ship.removeEquipment(equipmentKey);
                success = player.ship.awardEquipment(originalEquipmentKey);
                break;
        }

        if (!success) {
            log("Tionisla Chronicle Array", "Failed to award player with \"" + originalEquipmentKey + "\" when processing \"" + equipmentKey + "\'");
        }
    }

};