Back to Index Page generated: Dec 20, 2024, 7:22:09 AM

Expansion Laser Arrangement

Content

Warnings

  1. 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 Allows lasers to be moved between the different laser mounts available on the ship, when docked. Allows lasers to be moved between the different laser mounts available on the ship, when docked.
Identifier oolite.oxp.phkb.LaserArrangement oolite.oxp.phkb.LaserArrangement
Title Laser Arrangement Laser Arrangement
Category Equipment Equipment
Author phkb phkb
Version 1.3 1.3
Tags Equipment, Weapons Equipment, Weapons
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/6/68/LaserArrangement.oxz n/a
License CC-BY-NC-SA 4.0 CC-BY-NC-SA 4.0
File Size n/a
Upload date 1610873324

Documentation

Also read http://wiki.alioth.net/index.php/Laser%20Arrangement

readme.txt

Laser Arrangement
by Nick Rogers

Overview
========
This OXP allows for lasers to be moved from one position to another, when docked. This allows commanders to quickly customise their ship, without needing to visit the F3 screen and fiddling about with selling and then repurchasing lasers.

Operations
==========
A new F4 Interface page will be available in all stations, called "Laser arrangement", under "Ship Systems". When you select this option, the current set of installed lasers will be shown in each of their respective positions. A menu will be shown allowing for one of these lasers to be selected.

After selecting a laser, the destination position can be chosen. This can either be an empty laser position, or a position with an existing laser. In the case where a laser is already installed in the desired destination, the two lasers will be swapped.

Note: The interface will only be available if there is more than one laser mount available in the current ship.

License
=======
This work is licensed under the Creative Commons Attribution-Noncommercial-Share Alike 4.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/

Version History
===============
1.3
- Code tweaks for integration with planned OXP's.

1.2
- Unable to move a laser into the aft position.

1.1
- Restricted movement of multiple laser installations to only those positions with the same number of laser installations.

1.0
- Initial release.

Equipment

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

Ships

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

Models

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

Scripts

Path
Config/script.js
"use strict";
this.author = "phkb";
this.copyright = "2018 phkb";
this.description = "Allows lasers to be moved to different mounts, when docked";
this.name = "LaserArrangement";
this.licence = "CC BY-NC-SA 4.0";

this._page = 0;
this._selected = "";
this._selectedName = "";
this._multiple = 1;

//-------------------------------------------------------------------------------------------------------------
this.startUpComplete = function () {
    this.$initInterface(player.ship.dockedStation);
}

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

//-------------------------------------------------------------------------------------------------------------
this.playerBoughtNewShip = function (ship, price) {
    this.$initInterface(player.ship.dockedStation);
}

//-------------------------------------------------------------------------------------------------------------
// establishes the F4 interface for switching laser mounts while docked
this.$initInterface = function $initInterface(station) {
    // can only move lasers if there is more than one mount to move them between
    // 0 = none, 1 = forward only
    if (player.ship.weaponFacings > 1) {
        station.setInterface(this.name, {
            title: "Laser arrangement",
            category: "Ship Systems",
            summary: "Allows lasers to be moved between the different mounts available on the ship.",
            callback: this.$showInitial.bind(this)
        });
    } else {
        station.setInterface(this.name, null);
    }
}

//-------------------------------------------------------------------------------------------------------------
this.$showInitial = function $showInitial() {
    this._page = 0;
    this._selected = "";
    this.$showPage();
}

//-------------------------------------------------------------------------------------------------------------
this.$showPage = function $showPage() {
	var p = player.ship;
	var curChoices = {};
    var text = "";
    var col1 = 10;    
	var def = "99_EXIT";
    var laserName = "";
    var laserEq = "";

    var bl = worldScripts.BreakableLasers_Main;

    if (this._page === 0) {
        text = "Select the laser you want to move:\n\n";

        if (worldScripts.LMSS_Core && (p.equipmentStatus("EQ_LMSS_ACTIVATOR") === "EQUIPMENT_OK")) {
            curChoices["00_LMSS"] = {
                text: "LMSS dockside services"
            };
        }

        if (" 1 3 5 7 9 11 13 15 ".indexOf(" " + p.weaponFacings.toString() + " ") >= 0) {
            text += this.$padTextRight("Forward: ", col1);
            laserEq = p.forwardWeapon.equipmentKey;
            laserName = p.forwardWeapon.name;
            if (bl && laserEq == bl._damagedEq) laserName = EquipmentInfo.infoForKey(bl._holdDamage["FORWARD"].primary).name + " (Damaged)";

            text += (laserEq === "EQ_WEAPON_NONE" ? "--None--" : laserName + (p.weaponPositionForward.length > 1 ? " x " + p.weaponPositionForward.length : "")) + "\n";
            curChoices["01_FORWARD"] = {
                text: "Select forward lasers",
                color: (laserEq === "EQ_WEAPON_NONE" ? "grayColor" : "orangeColor"),
                unselectable: (laserEq === "EQ_WEAPON_NONE" ? true : false)
            };
        }
        if (" 2 3 6 7 10 11 14 15 ".indexOf(" " + p.weaponFacings.toString() + " ") >= 0) {
            text += this.$padTextRight("Aft: ", col1);
            laserEq = p.aftWeapon.equipmentKey;
            laserName = p.aftWeapon.name;
            if (bl && laserEq == bl._damagedEq) laserName = EquipmentInfo.infoForKey(bl._holdDamage["AFT"].primary).name + " (Damaged)";

            text += (laserEq === "EQ_WEAPON_NONE" ? "--None--" : laserName + (p.weaponPositionAft.length > 1 ? " x " + p.weaponPositionAft.length : "")) + "\n";
            curChoices["02_AFT"] = {
                text: "Select aft lasers",
                color: (laserEq === "EQ_WEAPON_NONE" ? "grayColor" : "orangeColor"),
                unselectable: (laserEq === "EQ_WEAPON_NONE" ? true : false)
            };
        }
        if (" 4 5 6 7 12 13 14 15 ".indexOf(" " + p.weaponFacings.toString() + " ") >= 0) {
            text += this.$padTextRight("Port: ", col1);
            laserEq = p.portWeapon.equipmentKey;
            laserName = p.portWeapon.name;
            if (bl && laserEq == bl._damagedEq) laserName = EquipmentInfo.infoForKey(bl._holdDamage["PORT"].primary).name + " (Damaged)";
            
            text += (laserEq === "EQ_WEAPON_NONE" ? "--None--" : laserName + (p.weaponPositionPort.length > 1 ? " x " + p.weaponPositionPort.length : "")) + "\n";
            curChoices["03_PORT"] = {
                text: "Select port lasers",
                color: (laserEq === "EQ_WEAPON_NONE" ? "grayColor" : "orangeColor"),
                unselectable: (laserEq === "EQ_WEAPON_NONE" ? true : false)
            };
        }
        if (" 8 9 10 11 12 13 14 15 ".indexOf(" " + p.weaponFacings.toString() + " ") >= 0) {
            text += this.$padTextRight("Starboard: ", col1);
            laserEq = p.starboardWeapon.equipmentKey;
            laserName = p.starboardWeapon.name;
            if (bl && laserEq == bl._damagedEq) laserName = EquipmentInfo.infoForKey(bl._holdDamage["STARBOARD"].primary).name + " (Damaged)";
            
            text += (laserEq === "EQ_WEAPON_NONE" ? "--None--" : laserName + (p.weaponPositionStarboard.length > 1 ? " x " + p.weaponPositionStarboard.length : "")) + "\n";
            curChoices["04_STARBOARD"] = {
                text: "Select starboard lasers",
                color: (laserEq === "EQ_WEAPON_NONE" ? "grayColor" : "orangeColor"),
                unselectable: (laserEq === "EQ_WEAPON_NONE" ? true : false)
            };
        }

        curChoices["99_EXIT"] = "Exit";
    }

    if (this._page === 1) {
        text = "Select destination for " + this._selected.toLowerCase() + " laser '" + this._selectedName + "':";
        if (" 1 3 5 7 9 11 13 15 ".indexOf(" " + p.weaponFacings.toString() + " ") >= 0 && p.weaponPositionForward.length === this._multiple) {
            laserEq = p.forwardWeapon.equipmentKey;
            laserName = p.forwardWeapon.name;
            if (bl && laserEq == bl._damagedEq) laserName = EquipmentInfo.infoForKey(bl._holdDamage[this._selected].primary).name + " (Damaged)";

            if (this._selected !== "FORWARD") {
                curChoices["11_FORWARD"] = {
                    text: "Forward position" + (laserEq !== "EQ_WEAPON_NONE" ? " (Swap with " + laserName + (p.weaponPositionForward.length > 1 ? " x " + p.weaponPositionForward.length : "") + ")" : ""),
                    color: "orangeColor"
                }
            } else {
                curChoices["11_FORWARD"] = {
                    text: "Forward position (selected)",
                    color: "grayColor",
                    unselectable: true
                }
            }
        }
        if (" 2 3 6 7 10 11 14 15 ".indexOf(" " + p.weaponFacings.toString() + " ") >= 0 && p.weaponPositionAft.length === this._multiple) {
            laserEq = p.aftWeapon.equipmentKey;
            laserName = p.aftWeapon.name;
            if (bl && laserEq == bl._damagedEq) laserName = EquipmentInfo.infoForKey(bl._holdDamage[this._selected].primary).name + " (Damaged)";

            if (this._selected !== "AFT") {
                curChoices["12_AFT"] = {
                    text: "Aft position" + (laserEq !== "EQ_WEAPON_NONE" ? " (Swap with " + p.aftWeapon.name + (p.weaponPositionAft.length > 1 ? " x " + p.weaponPositionAft.length : "") + ")" : ""),
                    color: "orangeColor"
                };
            } else {
                curChoices["12_AFT"] = {
                    text: "Aft position (selected)",
                    color: "grayColor",
                    unselectable: true
                };
            }
        }
        if (" 4 5 6 7 12 13 14 15 ".indexOf(" " + p.weaponFacings.toString() + " ") >= 0 && p.weaponPositionPort.length === this._multiple) {
            laserEq = p.portWeapon.equipmentKey;
            laserName = p.portWeapon.name;
            if (bl && laserEq == bl._damagedEq) laserName = EquipmentInfo.infoForKey(bl._holdDamage[this._selected].primary).name + " (Damaged)";

            if (this._selected !== "PORT") {
                curChoices["13_PORT"] = {
                    text: "Port position" + (laserEq !== "EQ_WEAPON_NONE" ? " (Swap with " + laserName + (p.weaponPositionPort.length > 1 ? " x " + p.weaponPositionPort.length : "") + ")" : ""),
                    color: "orangeColor"
                };
            } else {
                curChoices["13_PORT"] = {
                    text: "Port position (selected)",
                    color: "grayColor",
                    unselectable: true
                };
            }
        }
        if (" 8 9 10 11 12 13 14 15 ".indexOf(" " + p.weaponFacings.toString() + " ") >= 0 && p.weaponPositionStarboard.length === this._multiple) {
            laserEq = p.starboardWeapon.equipmentKey;
            laserName = p.starboardWeapon.name;
            if (bl && laserEq == bl._damagedEq) laserName = EquipmentInfo.infoForKey(bl._holdDamage[this._selected].primary).name + " (Damaged)";

            if (this._selected !== "STARBOARD") {
                curChoices["14_STARBOARD"] = {
                    text: "Starboard position" + (laserEq !== "EQ_WEAPON_NONE" ? " (Swap with " + laserName + (p.weaponPositionStarboard.length > 1 ? " x " + p.weaponPositionStarboard.length : "") + ")" : ""),
                    color: "orangeColor"
                };
            } else {
                curChoices["14_STARBOARD"] = {
                    text: "Starboard position (selected)",
                    color: "grayColor",
                    unselectable: true
                };
            }
        }
        curChoices["98_CANCEL"] = "Cancel";
        curChoices["99_EXIT"] = "Exit";
    }

	var opts = {
		screenID: "oolite-la-dockside-map",
		title: "Laser Arrangement",
		allowInterrupt: true,
		exitScreen: "GUI_SCREEN_INTERFACES",
		overlay: {
			name: "la-arrow.png",
			height: 546
		},
		choices: curChoices,
		initialChoicesKey: def,
		message: text
	};
	mission.runScreen(opts, this.$screenHandler, this);
}

//-------------------------------------------------------------------------------------------------------------
this.$screenHandler = function $screenHandler(choice) {
    if (choice == null) return;

    var p = player.ship;
    var bl = worldScripts.BreakableLasers_Main;

    switch (choice) {
        case "00_LMSS":
            worldScripts.LMSS_Core.$showLMSSList();
            return;
        case "01_FORWARD":
            this._selected = "FORWARD";
            this._selectedName = p.forwardWeapon.name;
            if (bl && this._selectedName == bl._damagedEq) this._selectedName = EquipmentInfo.infoForKey(bl._holdDamage[this._selected].primary).name;
            this._multiple = p.weaponPositionForward.length;
            this._page = 1;
            break;
        case "02_AFT":
            this._selected = "AFT";
            this._selectedName = p.aftWeapon.name;
            if (bl && this._selectedName == bl._damagedEq) this._selectedName = EquipmentInfo.infoForKey(bl._holdDamage[this._selected].primary).name;
            this._multiple = p.weaponPositionAft.length;
            this._page = 1;
            break;
        case "03_PORT":
            this._selected = "PORT";
            this._selectedName = p.portWeapon.name;
            if (bl && this._selectedName == bl._damagedEq) this._selectedName = EquipmentInfo.infoForKey(bl._holdDamage[this._selected].primary).name;
            this._multiple = p.weaponPositionPort.length;
            this._page = 1;
            break;
        case "04_STARBOARD":
            this._selected = "STARBOARD";
            this._selectedName = p.starboardWeapon.name;
            if (bl && this._selectedName == bl._damagedEq) this._selectedName = EquipmentInfo.infoForKey(bl._holdDamage[this._selected].primary).name;
            this._multiple = p.weaponPositionStarboard.length;
            this._page = 1;
            break;
        case "11_FORWARD":
            var hold = "EQ_WEAPON_NONE";
            var from = "FORWARD";
            if (worldScripts.LMSS_Core) worldScripts.LMSS_Core._switching = true;
            if (p.forwardWeapon.equipmentKey !== "EQ_WEAPON_NONE") hold = p.forwardWeapon.equipmentKey;
            switch (this._selected) {
                case "AFT":
                    p.forwardWeapon = p.aftWeapon.equipmentKey;
                    p.aftWeapon = hold;
                    break;
                case "PORT":
                    p.forwardWeapon = p.portWeapon.equipmentKey;
                    p.portWeapon = hold;
                    break;
                case "STARBOARD":
                    p.forwardWeapon = p.starboardWeapon.equipmentKey;
                    p.starboardWeapon = hold;
                    break;
            }
            if (bl) bl.$transferPrimaryLaser(this._selected, from);
            if (worldScripts.LMSS_Core) worldScripts.LMSS_Core._switching = false;
            this._selected = "";
            this._page = 0;
            break;
        case "12_AFT":
            var hold = "EQ_WEAPON_NONE";
            var from = "AFT";
            if (worldScripts.LMSS_Core) worldScripts.LMSS_Core._switching = true;
            if (p.aftWeapon.equipmentKey !== "EQ_WEAPON_NONE") hold = p.aftWeapon.equipmentKey;
            switch (this._selected) {
                case "FORWARD":
                    p.aftWeapon = p.forwardWeapon.equipmentKey;
                    p.forwardWeapon = hold;
                    break;
                case "PORT":
                    p.aftWeapon = p.portWeapon.equipmentKey;
                    p.portWeapon = hold;
                    break;
                case "STARBOARD":
                    p.aftWeapon = p.starboardWeapon.equipmentKey;
                    p.starboardWeapon = hold;
                    break;
            }
            if (bl) bl.$transferPrimaryLaser(this._selected, from);
            if (worldScripts.LMSS_Core) worldScripts.LMSS_Core._switching = false;
            this._selected = "";
            this._page = 0;
            break;
        case "13_PORT":
            var hold = "EQ_WEAPON_NONE";
            var from = "PORT";
            if (worldScripts.LMSS_Core) worldScripts.LMSS_Core._switching = true;
            if (p.portWeapon.equipmentKey !== "EQ_WEAPON_NONE") hold = p.portWeapon.equipmentKey;
            switch (this._selected) {
                case "FORWARD":
                    p.portWeapon = p.forwardWeapon.equipmentKey;
                    p.forwardWeapon = hold;
                    break;
                case "AFT":
                    p.portWeapon = p.aftWeapon.equipmentKey;
                    p.aftWeapon = hold;
                    break;
                case "STARBOARD":
                    p.portWeapon = p.starboardWeapon.equipmentKey;
                    p.starboardWeapon = hold;
                    break;
            }
            if (bl) bl.$transferPrimaryLaser(this._selected, from);
            if (worldScripts.LMSS_Core) worldScripts.LMSS_Core._switching = false;
            this._selected = "";
            this._page = 0;
            break;
        case "14_STARBOARD":
            var hold = "EQ_WEAPON_NONE";
            var from = "AFT";
            if (worldScripts.LMSS_Core) worldScripts.LMSS_Core._switching = true;
            if (p.starboardWeapon.equipmentKey !== "EQ_WEAPON_NONE") hold = p.starboardWeapon.equipmentKey;
            switch (this._selected) {
                case "FORWARD":
                    p.starboardWeapon = p.forwardWeapon.equipmentKey;
                    p.forwardWeapon = hold;
                    break;
                case "AFT":
                    p.starboardWeapon = p.aftWeapon.equipmentKey;
                    p.aftWeapon = hold;
                    break;
                case "PORT":
                    p.starboardWeapon = p.portWeapon.equipmentKey;
                    p.portWeapon = hold;
                    break;
            }
            if (bl) bl.$transferPrimaryLaser(this._selected, from);
            if (worldScripts.LMSS_Core) worldScripts.LMSS_Core._switching = false;
            this._selected = "";
            this._page = 0;
            break;
        case "98_CANCEL":
            this._selected = "";
            this._page = 0;
            break;
    }

	if (choice != "99_EXIT") {
		this.$showPage();
	}
}

//-------------------------------------------------------------------------------------------------------------
// appends space to currentText to the specified length in 'em'
this.$padTextRight = function $padTextRight(currentText, desiredLength, leftSwitch) {
	if (currentText == null) currentText = "";
	var hairSpace = String.fromCharCode(31);
	var ellip = "…";
	var currentLength = defaultFont.measureString(currentText.replace(/%%/g, "%"));
	var hairSpaceLength = defaultFont.measureString(hairSpace);
	// calculate number needed to fill remaining length
	var padsNeeded = Math.floor((desiredLength - currentLength) / hairSpaceLength);
	if (padsNeeded < 1) {
		// text is too long for column, so start pulling characters off
		var tmp = currentText;
		do {
			tmp = tmp.substring(0, tmp.length - 2) + ellip;
			if (tmp === ellip) break;
		} while (defaultFont.measureString(tmp.replace(/%%/g, "%")) > desiredLength);
		currentLength = defaultFont.measureString(tmp.replace(/%%/g, "%"));
		padsNeeded = Math.floor((desiredLength - currentLength) / hairSpaceLength);
		currentText = tmp;
	}
	// quick way of generating a repeated string of that number
	if (!leftSwitch || leftSwitch === false) {
		return currentText + new Array(padsNeeded).join(hairSpace);
	} else {
		return new Array(padsNeeded).join(hairSpace) + currentText;
	}
}