Back to Index Page generated: Jun 13, 2026, 7:54:51 PM

Expansion Small Ships

Content

Warnings

  1. http://wiki.alioth.net/index.php/Small%20Ships -> 404 Not Found
  2. Low hanging fuit: Information URL exists...

Manifest

from Expansion Manager's OXP list from Expansion Manifest
Description Flyable and essentially unaltered versions of the Asp, Fer-de-Lance, Gecko, Krait, Mamba, Sidewinder, Constrictor, Viper, Viper Interceptor, Worm, and Transporter. Those ships originally sans Hyperdrive now have one; those without cargo space remain without. Newly rationalized price-adjustments applied. Flyable and essentially unaltered versions of the Asp, Fer-de-Lance, Gecko, Krait, Mamba, Sidewinder, Constrictor, Viper, Viper Interceptor, Worm, and Transporter. Those ships originally sans Hyperdrive now have one; those without cargo space remain without. Newly rationalized price-adjustments applied.
Identifier oolite.oxp.Reval.Small_Ships oolite.oxp.Reval.Small_Ships
Title Small Ships Small Ships
Category Ships Ships
Author Reval Reval
Version 1.2 1.2
Tags
Required Oolite Version
Maximum Oolite Version
Required Expansions
Optional Expansions
Conflict Expansions
Information URL https://wiki.alioth.net/index.php/Small_Ships_OXZ n/a
Download URL https://wiki.alioth.net/img_auth.php/1/1f/Small_Ships.oxz https://wiki.alioth.net/img_auth.php/1/1f/Small_Ships.oxz
License CC-BY-NC-SA 4.0 CC-BY-NC-SA 4.0
File Size n/a
Upload date 1778181017

Relationships Diagram

Documentation

Equipment

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

Ships

Name
constrictor-player
gecko-player
krait-player
mamba-player
shuttle-player
Sidewinder
transporter-miner-player
transporter-player
viper-interceptor-player
viper-player
viper-pursuit-player
worm-miner-player
worm-player

Models

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

Scripts

Path
Scripts/ss-script.js
"use strict";
this.name = "Small Ships";
this.version = "1.2";
this.author = "Reval";
this.description = "Ensure the chosen initial shipyard - Lave, Tionisla, or Anarlaqu - has at least an Adder, an Asp, a Cobra Mk I, a Fer-de-Lance, a Gecko, a Krait, a Mamba, a Sidewinder, and Vipers for sale. Prices newly rationalized around the Cobra Mk III.";
this.licence = "CC BY-NC-SA 4.0";


this.startUpComplete = function () {
  // only proceed if we're at an initial shipyard (Lave/Tionisla/Anarlaqu)
    if ((galaxyNumber==0) && ((system.ID==7) || (system.ID==124) || (system.ID==42))) {
        
		var bAdder = false;
        var bAsp   = false;
		var bCobra = false;
		var bFer   = false;
		var bGecko = false;
		var bKrait = false;
		var bMamba = false;
		var bSidew = false;
		var bViper = false;
        var bVipInt= false;
		
		if (system.mainStation.shipyard && system.mainStation.shipyard.length > 0) {
            var sy = system.mainStation.shipyard;
            // are all the small ships in the initial shipyard already?
            for (var i = 0; i < sy.length; i++) {
                let syk = sy[i].shipdata_key;
				let syp = sy[i].price;
				if ((syk == "adder-player") && (syp == 60696)) bAdder = true;
                if ((syk == "asp-player") && (syp == 95981)) bAsp = true;
                if ((syk == "cobramk1-player") && (syp == 84936)) bCobra = true;
                if ((syk == "ferdelance-player") && (syp == 96369)) bGecko = true;
                if ((syk == "gecko-player") && (syp == 71432)) bGecko = true;
                if ((syk == "krait-player") && (syp == 87562)) bKrait = true;
                if ((syk == "mamba-player") && (syp == 80498)) bMamba = true;
                if ((syk == "sidewinder-player") && (syp == 77352)) bSidew = true;
                if ((syk == "viper-player") && (syp == 70460)) bViper = true;
                if ((syk == "viper-interceptor-player") && (syp == 109032)) bVipInt = true;
            }
        }
        
		if (bAdder == false) {
            var keyList = ["adder-player", "griff_adder-PLAYER"];
            var idx = 0;
            var done = false;
            do {
                if (Ship.shipDataForKey(keyList[idx]).roles == "player") {
                    system.mainStation.addShipToShipyard({
                        short_description: "Adder standard customer model.",
                        shipdata_key: keyList[idx],
                        price: 60696,
                        personality: Math.floor(Math.random() * 32768),
                        extras: ["EQ_ADVANCED_COMPASS"]
                    });
                    done = true;
                } else {
                    idx += 1;
                }
            } while (done == false && idx < keyList.length);
        }
        
		if (bCobra == false) {
            var keyList = ["cobramk1-player", "griff_cobra_Mk1-PLAYER"];
            var idx = 0;
            var done = false;
            do {
                if (Ship.shipDataForKey(keyList[idx]).roles == "player") {
                    system.mainStation.addShipToShipyard({
                        short_description: "Cobra Mk I standard customer model.",
                        shipdata_key: keyList[idx],
                        price: 84936,
                        personality: Math.floor(Math.random() * 32768),
                        extras: ["EQ_ADVANCED_COMPASS"]
                    });
                    done = true;
                } else {
                    idx += 1;
                }
            } while (done == false && idx < keyList.length);
        }
        
		if (bAsp == false) {
            var keyList = ["asp-player"];
            var idx = 0;
            var done = false;
            do {
                if (Ship.shipDataForKey(keyList[idx]).roles == "player") {
                    system.mainStation.addShipToShipyard({
                        name: "Asp II",
						short_description: "Asp II standard customer model.",
                        shipdata_key: keyList[idx],
                        price: 95981,
                        personality: Math.floor(Math.random() * 32768),
                        extras: ["EQ_ADVANCED_COMPASS"]
                    });
                    done = true;
                } else {
                    idx += 1;
                }
            } while (done == false && idx < keyList.length);
        }

		if (bFer == false) {
            var keyList = ["ferdelance-player"];
            var idx = 0;
            var done = false;
            do {
                if (Ship.shipDataForKey(keyList[idx]).roles == "player") {
                    system.mainStation.addShipToShipyard({
						short_description: "Fer-de-Lance standard customer model.",
                        shipdata_key: keyList[idx],
                        price: 96369,
                        personality: Math.floor(Math.random() * 32768),
                        extras: ["EQ_ADVANCED_COMPASS"]
                    });
                    done = true;
                } else {
                    idx += 1;
                }
            } while (done == false && idx < keyList.length);
        }
		
		if (bGecko == false) {
            var keyList = ["gecko-player"];
            var idx = 0;
            var done = false;
            do {
                if (Ship.shipDataForKey(keyList[idx]).roles == "player") {
                    system.mainStation.addShipToShipyard({
                        short_description: "Gecko standard customer model.",
                        shipdata_key: keyList[idx],
                        price: 71432,
                        personality: Math.floor(Math.random() * 32768),
                        extras: ["EQ_ADVANCED_COMPASS"]
                    });
                    done = true;
                } else {
                    idx += 1;
                }
            } while (done == false && idx < keyList.length);
        }
    
		if (bKrait == false) {
            var keyList = ["krait-player"];
            var idx = 0;
            var done = false;
            do {
                if (Ship.shipDataForKey(keyList[idx]).roles == "player") {
                    system.mainStation.addShipToShipyard({
                        short_description: "Krait standard customer model.",
                        shipdata_key: keyList[idx],
                        price: 87562,
                        personality: Math.floor(Math.random() * 32768),
                        extras: ["EQ_ADVANCED_COMPASS"]
                    });
                    done = true;
                } else {
                    idx += 1;
                }
            } while (done == false && idx < keyList.length);
        }
    
		if (bMamba == false) {
            var keyList = ["mamba-player"];
            var idx = 0;
            var done = false;
            do {
                if (Ship.shipDataForKey(keyList[idx]).roles == "player") {
                    system.mainStation.addShipToShipyard({
                        short_description: "Mamba standard customer model.",
                        shipdata_key: keyList[idx],
                        price: 80498,
                        personality: Math.floor(Math.random() * 32768),
                        extras: ["EQ_ADVANCED_COMPASS"]
                    });
                    done = true;
                } else {
                    idx += 1;
                }
            } while (done == false && idx < keyList.length);
        }
    
		if (bSidew == false) {
            var keyList = ["sidewinder-player"];
            var idx = 0;
            var done = false;
            do {
                if (Ship.shipDataForKey(keyList[idx]).roles == "player") {
                    system.mainStation.addShipToShipyard({
                        short_description: "Sidewinder standard customer model.",
                        shipdata_key: keyList[idx],
                        price: 77352,
                        personality: Math.floor(Math.random() * 32768),
                        extras: ["EQ_ADVANCED_COMPASS"]
                    });
                    done = true;
                } else {
                    idx += 1;
                }
            } while (done == false && idx < keyList.length);
        }
	
		if (bViper == false) {
            var keyList = ["viper-player"];
            var idx = 0;
            var done = false;
            do {
                if (Ship.shipDataForKey(keyList[idx]).roles == "player") {
                    system.mainStation.addShipToShipyard({
                        short_description: "Viper standard customer model.",
                        shipdata_key: keyList[idx],
                        price: 70460,
                        personality: Math.floor(Math.random() * 32768),
                        extras: ["EQ_ADVANCED_COMPASS"]
                    });
                    done = true;
                } else {
                    idx += 1;
                }
            } while (done == false && idx < keyList.length);
        }
	
		if (bVipInt == false) {
            var keyList = ["viper-interceptor-player"];
            var idx = 0;
            var done = false;
            do {
                if (Ship.shipDataForKey(keyList[idx]).roles == "player") {
                    system.mainStation.addShipToShipyard({
                        short_description: "Viper Interceptor standard customer model.",
                        shipdata_key: keyList[idx],
                        price: 109032,
                        personality: Math.floor(Math.random() * 32768),
                        extras: ["EQ_ADVANCED_COMPASS"]
                    });
                    done = true;
                } else {
                    idx += 1;
                }
            } while (done == false && idx < keyList.length);
        }
	
	} 
	    
	// Calculate and log rationalized prices with cobra3 as a baseline
	
    var coreShips = ["adder", "anaconda", "asp", "boa", "cobramk1", "cobra3-trader", "constrictor", "ferdelance", "gecko", "krait", "mamba", "moray", "morayMED", "python", "sidewinder", "shuttle", "transporter", "viper", "viper-interceptor"];

    for (var i = 0; i < coreShips.length; i++) {
        var key = "["+coreShips[i]+"]";
		var ships = system.addShips(key, 1, [0, 0, 0], 0);   
		if (ships && ships.length > 0) {
			var tempShip = ships[0];
            var size = tempShip.boundingBox;
            var cargo = tempShip.cargoSpaceCapacity || 0;
            var speed = tempShip.maxSpeed || 0;
            var price = this._rationalizedPrice(size, cargo, speed);
            log("Rationalized Price", key + ": " + price + " Cr");
            tempShip.remove(); // Clean up
        }
    }
   	
	// make sure we don't do this again.
    delete this.startUpComplete;
}


// Calculate a rationalized price for any ship, using cobra3 as a baseline
this._rationalizedPrice = function(shipSize, cargoCapacity, shipMaxSpeed) {
	const COBRA_SIZE = { x: 130, y: 30, z: 65 };   
    const COBRA_CARGO = 20;
    const COBRA_MAX_SPEED = 350; // LS
    const COBRA_PRICE = 150000;

    const shipVolume = shipSize.x * shipSize.y * shipSize.z;
    const cobraVolume = COBRA_SIZE.x * COBRA_SIZE.y * COBRA_SIZE.z;

    const volumeMultiplier = shipVolume / cobraVolume;
    const cargoMultiplier = cargoCapacity / COBRA_CARGO;
    const speedMultiplier = shipMaxSpeed / COBRA_MAX_SPEED;

    // Current weighting: 25% volume, 30% cargo, 45% speed
    const combinedMultiplier = (volumeMultiplier * 0.25) + (cargoMultiplier * 0.3) + (speedMultiplier * 0.45);

    return Math.round(COBRA_PRICE * combinedMultiplier);
}