| Scripts/combo_F7_layout.js | "use strict";
this.name        = "CompboF7Layout";
this.author      = "phkb @ stranger";
this.copyright   = "2022 stranger";
this.description = "Moves all standard F7 data to the top of the screen. Tightly based on phkb's Compressed G7 Layout. Adopted to use with Sun Gear";
this.licence     = "CC BY-NC-SA 4.0";
//-------------------------------------------------------------------------------------------------------------
this.startUpComplete = function()
    {
	var sd = worldScripts["oolite-system-data-config"];
    sd.setSystemDataLine(1, "[sysdata-eco]\t[economy_desc]", "system");
    sd.setSystemDataLine(2, "[sysdata-govt]\t[government_desc]", "system");
    sd.setSystemDataLine(3, "[sysdata-tl]\t[sysdata-tl-value]", "system");
    sd.setSystemDataLine(4, "[sysdata-pop]\t[sysdata-pop-value]", "system");
    sd.setSystemDataLine(5, "\t([inhabitants])", "system");
    sd.setSystemDataLine(6, "[sysdata-prod]\t[sysdata-prod-value]", "system");
    sd.setSystemDataLine(7, "[sysdata-radius]\t[sysdata-radius-value]", "system");
    sd.setSystemDataLine(8, "[sysdata-distance]\t[distanceInfo]", "system");
    sd.resetSystemDataLine(9);
    sd.resetSystemDataLine(10);
    sd.resetSystemDataLine(11);
    sd.resetSystemDataLine(12);
    sd.resetSystemDataLine(13);
    sd.resetSystemDataLine(14);
    sd.resetSystemDataLine(15);
    sd.resetSystemDataLine(16);
	if (worldScripts["SunSpectralAnalyzer"])
        {
		// we're overriding Sun Gear's guiScreenChanged so it doesn't add text to the bottom part of the F7 screen
		worldScripts["SunSpectralAnalyzer"].$overrideGUI = worldScripts["SunSpectralAnalyzer"].guiScreenChanged;
		delete worldScripts["SunSpectralAnalyzer"].guiScreenChanged;
		// instead, we'll add a callback to do the update
		sd.addChangeCallback(this.name, "$stars_updateData");
        }
	if (worldScripts["Explorers Club"])
        {
		// we're overriding EC's guiScreenChanged so we can capture and ignore any change to GUI_SCREEN_SYSTEM_DATA
		worldScripts["Explorers Club"].$ovr_guiScreenChanged = worldScripts["Explorers Club"].guiScreenChanged;
		delete worldScripts["Explorers Club"].guiScreenChanged;
		// we'll also add a callback to do the update
		sd.addChangeCallback(this.name, "$explorersClub_updateData");
        }
    }
//-------------------------------------------------------------------------------------------------------------
this.guiScreenChanged = function(to, from) {
	// for anything other than GUI_SCREEN_SYSTEM_DATA fire EC's original guiScreenChanged event
	if (guiScreen !== "GUI_SCREEN_SYSTEM_DATA" && worldScripts["Explorers Club"]) worldScripts["Explorers Club"].$ovr_guiScreenChanged(to, from);
}
//-------------------------------------------------------------------------------------------------------------
this.$explorersClub_updateData = function(ctype, to, from) {
	var ec = worldScripts["Explorers Club"];
	var sd = worldScripts["oolite-system-data-config"];
	// find the first free slot (or the one we're currently using)
	for (var i = 1; i <= 16; i++) {
		if (sd.systemDataLineOwner(i) === "" || sd.systemDataLineOwner(i) === "explorers_club") {
			// found it! now work out what system we're looking at
			var sysID = -1;
			if (ctype === "guiScreenWillChange") {
				// for this event, we need to check out the infoSystem or targetSystem of the player ship
				var sysID = player.ship.targetSystem;
				if (player.ship.hasOwnProperty("infoSystem")) sysID = player.ship.infoSystem;
			} else {
				// for an infoSystemWillChange, the "to" property has the value we need
				sysID = to;
			}
			// make sure we have a valid system ID
			if (isNaN(sysID) === false && sysID >=0 && sysID <= 255) {
				// extract the correct text from missionText
				var text = "";
				if (ec.$xc_record[galaxyNumber].indexOf(sysID) === -1) {
					text = expandMissionText("explorers_club_never_visited");
				} else if (player.ship.targetSystem === system.ID) {
					text = expandMissionText("explorers_club_here_now");
				} else {
					text = expandMissionText("explorers_club_already_visited");
				}
				// and update the data line
				sd.setSystemDataLine(i, text, "explorers_club");
			} else {
				// if we have an invalid system ID, reset the line
				if (sd.systemDataLineOwner(i) === "explorers_club") sd.resetSystemDataLine(i);
			}
			break;
		}
	}
}
//-------------------------------------------------------------------------------------------------------------
this.$stars_updateData = function(ctype, to, from) {
	var sd = worldScripts["oolite-system-data-config"];
	// find the first free slot (or the one we're currently using)
	for (var i = 1; i <= 16; i++) {
		if (sd.systemDataLineOwner(i) === "" || sd.systemDataLineOwner(i) === "stars") {
			// found it! now work out what system we're looking at
			var sysID = -1;
			if (ctype === "guiScreenWillChange") {
				// for this event, we need to check out the infoSystem or targetSystem of the player ship
				var sysID = player.ship.targetSystem;
				if (player.ship.hasOwnProperty("infoSystem")) sysID = player.ship.infoSystem;
			} else {
				// for an infoSystemWillChange, the "to" property has the value we need
				sysID = to;
			}
			// make sure we have a valid system ID
			if (isNaN(sysID) === false && sysID >=0 && sysID <= 255) {
				// and update the data line
				sd.setSystemDataLine(i, this.$starInfo(sysID), "stars");
			} else {
				// if we have an invalid system ID, reset the line
				if (sd.systemDataLineOwner(i) === "stars") sd.resetSystemDataLine(i);
			}
			break;
		}
	}
}
//-------------------------------------------------------------------------------------------------------------
// slightly modified from Sun Gear's original code
this.$starInfo = function(sysID)
    {
	var info = System.infoForSystem(galaxyNumber, sysID);
	if (info.sun_gone_nova) return "";
    var w = worldScripts.AstroLibrary;
    var name = info.name;
    var sunName = info.sun_name;
    var sunRadius = info.sun_radius;
    var spectrumText = w.$astroLib_sunSpectrum(sunRadius);
    var text = "";
    if (spectrumText && sunName) text += "The planet " + name + " orbits the " + spectrumText + " " + sunName + ".";
    else if (spectrumText) text += "The planet " + name + " orbits a " + spectrumText + " " + "star.";
    else if (sunName) text += "The planet " + name + " orbits the star " + sunName + ".";
	
	return text;
    }
 | 
                
                    | Scripts/oolite-system-data-config.js | "use strict";
this.name        = "oolite-system-data-config";
this.author      = "phkb & stranger";
this.copyright   = "2022 stranger";
this.description = "Provides an interface for configuring the layout of the System Data (F7) screen.";
this.licence     = "CC BY-NC-SA 3.0";
// set up our configuration dictionary with the default settings
this._config = {
    1: {owner:"system", text:"[sysdata-eco]\t[economy_desc]"},
    2: {owner:"", text:""},
    3: {owner:"system", text:"[sysdata-govt]\t[government_desc]"},
    4: {owner:"", text:""},
    5: {owner:"system", text:"[sysdata-tl]\t[sysdata-tl-value]"},
    6: {owner:"", text:""},
    7: {owner:"system", text:"[sysdata-pop]\t[sysdata-pop-value]"},
    8: {owner:"system", text:"\t([inhabitants])"},
    9: {owner:"", text:""},
    10: {owner:"system", text:"[sysdata-prod]\t\t[sysdata-prod-value]"},
    11: {owner:"", text:""},
    12: {owner:"system", text:"[sysdata-radius]\t\t[sysdata-radius-value]"},
    13: {owner:"", text:""},
    14: {owner:"system", text:"[sysdata-distance]\t[distanceInfo]"},
    15: {owner:"", text:""},
    16: {owner:"", text:""},
};
this._governmentList = ["Anarchy","Feudal","Multi-Government","Dictatorship","Communist","Confederacy",
    "Democracy","Corporate State"];
this._economyList = ["Extreme Industrial","Strong Industrial","Common Industrial","Mainly Industrial",
    "Mainly Agricultural","Common Agricultural","Strong Agricultural","Extreme Agricultural"];
this._callbacks = [];
//-------------------------------------------------------------------------------------------------------------
this.startUp = function() {
    this.$updateData();
}
//-------------------------------------------------------------------------------------------------------------
this.guiScreenWillChange = function(to, from) {
    if (to === "GUI_SCREEN_SYSTEM_DATA") {
        this.$performCallbacks("guiScreenWillChange", to, from);
        this.$updateData();
    }
}
//-------------------------------------------------------------------------------------------------------------
this.infoSystemWillChange = function(to, from) {
    this.$performCallbacks("infoSystemWillChange", to, from);
    this.$updateData();
}
//-------------------------------------------------------------------------------------------------------------
// returns the current owner of a particular data line
this.systemDataLineOwner = function(ln) {
    if (isNaN(ln) || ln < 1 || ln > 16) {
        throw "Invalid line number specified: " + ln + " - must be number between 1 and 16";
    }
    return this._config[ln].owner;
}
//-------------------------------------------------------------------------------------------------------------
// returns the current text of a particular data line
this.systemDataLineText = function(ln) {
    if (isNaN(ln) || ln < 1 || ln > 16) {
        throw "Invalid line number specified: " + ln + " - must be number between 1 and 16";
    }
    return this._config[ln].text;
}
//-------------------------------------------------------------------------------------------------------------
// sets the text and optionally the owner of a particular data line
this.setSystemDataLine = function(ln, text, owner) {
    if (isNaN(ln) || ln < 1 || ln > 16) {
        throw "Invalid line number specified: " + ln + " - must be number between 1 and 16";
    }
    if (owner) {
        // if we've been passed an owner, update the whole entry
        this._config[ln] = {owner:owner, text:text};
    } else {
        // otherwise just update the text element
        this._config[ln].text = text;
    }
    this.$updateData(ln);
}
//-------------------------------------------------------------------------------------------------------------
// resets a particular data line to being blank with no owner
this.resetSystemDataLine = function(ln) {
    if (isNaN(ln) || ln < 1 || ln > 16) {
        throw "Invalid line number specified: " + ln + " - must be number between 1 and 16";
    }
    this._config[ln] = {owner:"", text:""};
    this.$updateData(ln);
}
//-------------------------------------------------------------------------------------------------------------
// adds a worldscript/callback function name to the list of callbacks to execute whenever the information
// on the F7 screen is about to change
this.addChangeCallback = function(ws, cb) {
    var found = false;
    if (this._callbacks.length > 0) {
        for (var i = 0; i < this._callbacks.length; i++) {
            if (this._callbacks[i].worldScript === ws && this._callbacks[i].callback === cb) {
                found = true;
                break;
            }
        }
    }
    if (found === false) {
        this._callbacks.push({worldScript:ws, callback:cb});
    }
}
//-------------------------------------------------------------------------------------------------------------
// removes a worldscript/callback function name from the list of callbacks
this.removeChangeCallback = function(ws, cb) {
    for (var i = this._callbacks.length - 1; i >= 0; i--) {
        if (this._callbacks[i].worldScript === ws && this._callbacks[i].callback === cb) {
            this._callbacks.splice(i, 1);
            break;
        }
    }
}
//-------------------------------------------------------------------------------------------------------------
// executes all the callbacks
this.$performCallbacks = function(c_type, to, from) {
    if (this._callbacks.length > 0) {
        for (var i = 0; i < this._callbacks.length; i++) {
            worldScripts[this._callbacks[i].worldScript][this._callbacks[i].callback](c_type, to, from);
        }
    }
}
//-------------------------------------------------------------------------------------------------------------
// updats the data for all lines (if no line number is passed) or for a specific line
this.$updateData = function(ln) {
    // if we've been passed a line number, just update that line
    var data = this.$getSystemData(player.ship.infoSystem);
    if (ln) {
        missionVariables["oolite_sysdata_line_" + ln] = expandDescription(this._config[ln].text, data);
        return;
    }
    // otherwise update all the lines with the latest config
    for (var i = 1; i <= 16; i++) {
        missionVariables["oolite_sysdata_line_" + i] = expandDescription(this._config[i].text, data);
    }
}
//-------------------------------------------------------------------------------------------------------------
// returns a dictionary object containing the details of a particular system
this.$getSystemData = function(sysID) {
    var sys = System.infoForSystem(galaxyNumber, sysID);
    var rt = system.info.routeToSystem(sys, player.ship.routeMode);
    var data = {};
    if (sys.sun_gone_nova) {
        data["economy_desc"] = expandDescription("[nova-system-economy]");
        data["government_desc"] = expandDescription("[nova-system-government]");;
        data["sysdata-tl-value"] = 0;
        data["population"] = 0;
        data["inhabitants"] = expandDescription("[nova-system-inhabitants]");
        data["productivity"] = 0;
        data["radius"] = 0;
    } else {
        data["economy_desc"] = this._economyList[sys.economy];
        data["government_desc"] = this._governmentList[sys.government];
        data["sysdata-tl-value"] = sys.techlevel + 1;
        data["population"] = sys.population;
        data["inhabitants"] = sys.inhabitants;
        data["productivity"] = sys.productivity;
        data["radius"] = sys.radius;
    } 
    if (rt) {
        data["distanceInfo"] = rt.distance.toFixed(1) + " LY / " + 
            rt.time.toFixed(1) + " " + (rt.time > 0.95 && rt.time < 1.05 ? expandDescription("[sysdata-route-hours%0]") : expandDescription("[sysdata-route-hours%1]"))  + " / " + 
            (rt.route.length - 1) + " " + (rt.route.length === 2 ? expandDescription("[sysdata-route-jumps%0]") : expandDescription("[sysdata-route-jumps%1]"));
    } else {
        data["distanceInfo"] = system.info.distanceToSystem(sys).toFixed(1) + " LY";
    }
    return data;
}
 |