| Config/script.js | "use strict";
this.name = "LoadoutCategories";
this.author = "phkb";
this.copyright = "(C) 2023 phkb.";
this.license = "CC-NC-by-SA 4.0";
this.description = "Controls the header items in the equipment lists";
this._useAstrogation = false;
this._eqSort = {};
this._missionScreen = false;
// configuration settings for use in Lib_Config
this._libSettings = {
	Name: this.name,
	Alias: expandDescription("[loadout_alias]"),
	Display: expandDescription("[loadout_display]"),
	Alive: "_libSettings",
	Bool: {
		B0: {
			Name: "_useAstrogation",
			Def: false,
			Desc: expandDescription("[loadout_use_astro]")
		},
		Info: expandDescription("[loadout_use_astro_desc]")
	},
};
// headers for the F3 Ship Outfitting screen
this._headers = ["EQ_REORDERING_REFUELING", "EQ_REORDERING_GENERAL", "EQ_REORDERING_LASERS", "EQ_REORDERING_MISSILES", "EQ_REORDERING_LMSS", 
    "EQ_REORDERING_TRACTORBEAM", "EQ_REORDERING_DEFENSIVE", "EQ_REORDERING_TARGETING", "EQ_REORDERING_SHIELDS", "EQ_REORDERING_CARGO", 
    "EQ_REORDERING_ENERGY", "EQ_REORDERING_REPAIRBOTS", "EQ_REORDERING_SCANNERS", "EQ_REORDERING_MFD", "EQ_REORDERING_LICENSES", "EQ_REORDERING_ILLICIT", 
    "EQ_REORDERING_NAVIGATION", "EQ_REORDERING_ASTROGATION", "EQ_REORDERING_SALVAGE", "EQ_REORDERING_ARMOUR", "EQ_REORDERING_ESCORTS"];
// headers for the F5 Status screen
this._headersAlt = ["EQ_REORDERING_REFUELING_F5", "EQ_REORDERING_GENERAL_F5", "EQ_REORDERING_LASERS_F5", "EQ_REORDERING_MISSILES_F5", "EQ_REORDERING_LMSS_F5", 
    "EQ_REORDERING_TRACTORBEAM_F5", "EQ_REORDERING_DEFENSIVE_F5", "EQ_REORDERING_TARGETING_F5", "EQ_REORDERING_SHIELDS_F5", "EQ_REORDERING_CARGO_F5", 
    "EQ_REORDERING_ENERGY_F5", "EQ_REORDERING_REPAIRBOTS_F5", "EQ_REORDERING_SCANNERS_F5", "EQ_REORDERING_MFD_F5", "EQ_REORDERING_LICENSES_F5", "EQ_REORDERING_ILLICIT_F5", 
    "EQ_REORDERING_NAVIGATION_F5", "EQ_REORDERING_ASTROGATION_F5", "EQ_REORDERING_SALVAGE_F5", "EQ_REORDERING_ARMOUR_F5", "EQ_REORDERING_ESCORTS_F5"];
//-------------------------------------------------------------------------------------------------------------
this.startUpComplete = function () {
	// register our settings, if Lib_Config is present
	if (worldScripts.Lib_Config) worldScripts.Lib_Config._registerSet(this._libSettings);
    if (missionVariables.LoadoutCategories_UseAstro) this._useAstrogation = (missionVariables.LoadoutCategories_UseAstro == "y" ? true : false);
	if (worldScripts.ShipConfiguration_Core) {
		var sc = worldScripts.ShipConfiguration_Core;
		for (var i = 0; i < this._headersAlt.length; i++) {
			sc._ignoreEquip.push(this._headersAlt[i]);
			sc._ignoreEquip.push(this._headers[i]);
		}
		sc._ignoreEquip.push("EQ_REORDERING_WEAPONONLY_F5");
		sc._ignoreEquip.push("EQ_REORDERING_BERTHWEAPON_F5");
	}
	this.$buildEquipmentSortOrderDict();
}
//-------------------------------------------------------------------------------------------------------------
this.playerWillSaveGame = function() {
    missionVariables.LoadoutCategories_UseAstro = (this._useAstrogation == true ? "y" : "n");
}
//-------------------------------------------------------------------------------------------------------------
this.playerBoughtEquipment = function(equipment, paid) {
    var p = player.ship;
    if (this._headers.indexOf(equipment) >= 0) p.removeEquipment(equipment);
}
/*
	Notes: By default, Oolite sorts the equipment items on the F5 Status screen in reverse order.
	So, the alphabetical list we've applied via the equipment-overrides.plist file ends up reversed.
	When it comes to adding headers to the F5 Status page, it means we add the header at the *end* of
	the list of equipment items (ie. making the order of the header item at the end of the section,
	rather than at the beginning).
	The solution that has been implemented in 1.91 is to separate the sort order property used for the
	F3 screen (it now uses purchase_sort_order). However, the process to produce the overrides file
	can't really be reworked to allow for a 1.90 configuration, so this OXP has been flagged as
	requiring 1.91 or later.
*/
//-------------------------------------------------------------------------------------------------------------
this.guiScreenChanged = function(to, from) {
	var p = player.ship;
	if (to == "GUI_SCREEN_STATUS") {
		this._sum = 0;
		/*
			mods like Hyperspace Hangar and ShipVersion are intercepting the playerBoughtNewShip process to
			bring up a mission screen immediately after purchasing a ship to ask addition questions.
			behind the scenes, guiScreen changes from GUI_SCREEN_SHIPYARD to GUI_SCREEN_STATUS
			before the mission screen can be shown. Timing issues result in some of the header equipment 
			items being visible on Ship Version's display screen.
			To counter this, I've added a brief delay before adding the header equipment items, via a 
			frame callback . That way, if guiScreen changes to GUI_SCREEN_MISSION I can react and 
			not add the headers.
		*/
		if (worldScripts.shipversion) {
			if (isValidFrameCallback(this._delay)) removeFrameCallback(this._delay);
			this._delay = addFrameCallback(this.$fcbDelay.bind(this));
		} else {
			this.$fcbDelay(1);
		}
	}
	if (from == "GUI_SCREEN_STATUS") {
		var i = this._headersAlt.length;
		while (i--) {
			player.ship.removeEquipment(this._headersAlt[i]);
		}
		player.ship.removeEquipment("EQ_REORDERING_BERTHWEAPON_F5");
		player.ship.removeEquipment("EQ_REORDERING_WEAPONONLY_F5");
	}
}
//-------------------------------------------------------------------------------------------------------------
this.$fcbDelay = function $fcbDelay(delta) {
	this._sum += delta;
	if (guiScreen != "GUI_SCREEN_STATUS") return;
	if (this._sum < 0.1) return;
	var p = player.ship;
	var eq = p.equipment;
	var i = this._headersAlt.length;
	while (i--) {
		var hdr = this._headersAlt[i];
		if (hdr.indexOf("EQ_REORDERING_LASERS") >= 0) {
			var found = false;
			if (p.forwardWeapon.equipmentKey != "EQ_WEAPON_NONE" || p.aftWeapon.equipmentKey != "EQ_WEAPON_NONE" || 
				p.portWeapon.equipmentKey != "EQ_WEAPON_NONE" || p.starboardWeapon.equipmentKey != "EQ_WEAPON_NONE") {
				if (p.passengerCapacity == 0) {
					p.awardEquipment("EQ_REORDERING_WEAPONONLY_F5");
				} else {
					p.awardEquipment("EQ_REORDERING_BERTHWEAPON_F5");
				}
			}
		} else {
			var item = EquipmentInfo.infoForKey(this._headersAlt[i]);
			var num1 = parseInt(item.scriptInfo.sortOrder) - 990;
			var num2 = parseInt(item.scriptInfo.sortOrder);
			var found = false;
			var eql = eq.length;
			while (eql--) {
				var item = eq[eql];
				var so = this._eqSort[item.equipmentKey];
				if (so && so > 0) {
					if (so > num1 && so < num2) {
						found = true;
						break;
					}
				}
			}
			if (found == true) {
				switch (this._headersAlt[i]) {
					case "EQ_REORDERING_NAVIGATION_F5":
						if (this._useAstrogation == false) p.awardEquipment(hdr);
						break;
					case "EQ_REORDERING_ASTROGATION_F5":
						if (this._useAstrogation == true) p.awardEquipment(hdr);
						break;
					default:
						p.awardEquipment(hdr);
				}
			}
		}
	}
	if (isValidFrameCallback(this._delay)) removeFrameCallback(this._delay);
}
//-------------------------------------------------------------------------------------------------------------
this.$buildEquipmentSortOrderDict = function() {
	var eq = EquipmentInfo.allEquipment;
	var i = eq.length;
	while (i--) {
		var item = eq[i];
		if (item.equipmentKey.indexOf("_F5") == -1 && item.hasOwnProperty("scriptInfo") && item.scriptInfo.hasOwnProperty("sortOrder")) {
			this._eqSort[item.equipmentKey] = parseInt(item.scriptInfo.sortOrder);
		}
	}
} |