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

Expansion Clippers

Content

Manifest

from Expansion Manager's OXP list from Expansion Manifest
Description Long-legged variants of the Python and Boa Class Cruiser - faster but with less cargo space. Player buyable and NPC. Long-legged variants of the Python and Boa Class Cruiser - faster but with less cargo space. Player buyable and NPC.
Identifier oolite.oxp.smivs.Clippers oolite.oxp.smivs.Clippers
Title Clippers Clippers
Category Ships Ships
Author Smivs Smivs
Version 1.4.4 1.4.4
Tags
Required Oolite Version
Maximum Oolite Version
Required Expansions
Optional Expansions
Conflict Expansions
Dependent Expansions
  • olite.oxp.smivs.ClassicOoniverse:1.0
  • Information URL http://wiki.alioth.net/index.php/Clippers n/a
    Download URL https://wiki.alioth.net/img_auth.php/6/6d/Clippers_v1.4.4.oxz http://wiki.alioth.net/img_auth.php/a/aa/Clippers_v1.4.4.oxz
    License CC-BY-NC-SA 4.0 CC-BY-NC-SA 4.0
    File Size n/a
    Upload date 1610873329

    Relationships Diagram

    Documentation

    Also read http://wiki.alioth.net/index.php/Clippers

    readme.rtf

    Clippers v1.4.4 OXZ by Smivs
    
    ==Python Clipper==
    The Python Clipper has two Drive units with a reduction in cargo capacity of 25TC over the original Python, leaving a hold of 75TC capacity. The original Python was also noted for its lack of modern equipment options and poor armaments and these issues have been addressed in the Clipper. The Python Clipper has one less energy bank than the original Python (six rather than seven) and no cargo expansion option, but the space freed-up has allowed much more powerful rechargers to be fitted and also allows for four missile pylons, double that of the Python. Military Shield Boosters can also be fitted to the Clipper. Performance, handling and top speed are all noticeably better than a standard Python.
    
    ==Boa Clipper==
    The Boa Clipper has three Stardrives and a cargo capacity of 150TC. Top speed and handling is improved over the Boa 2 but all other specifications are the same. With a full range of equipment options available and eight energy banks with efficient rechargers already included, there was not a lot of room for improvement over the standard Boa 2.
    
    ==Special features==
    In keeping with their role as long distance express transports, both Clipper models are equipped as standard with Fuel Scoops and Heat Shielding, and with the introduction of the Python variant external secondary fuel tanks were introduced across the range. These hold 3LY of fuel and this can be moved into the main tanks when they are empty. These External Fuel Tanks are primeable equipment. To prime the tanks, press 'shift -n' and to transfer the fuel to your main tanks, press 'n'.
    Both Clipper variants also feature a custom HUD.
    If an NPC is severely damaged in battle and the pilot ejects the ship will progressively become derelict. The ship loses power and the lights fade, followed by the engine glow, and finally the navigation strobes will stop, leaving the derelict gently tumbling in space.
    
    ==Compatibility==
    This OXP is compatible with ExtraFuelTanks OXP. Both OXPs can be installed together. If you fly a Boa or Python Clipper with External Fuel Tanks you will not see ExtraFuelTanks offered, but if you have several Commanders flying various ships and use ExtraFuelTanks these will continue to work normally.
    
    ==Credits== 
    Many thanks to Griff for allowing me to 'borrow' the engine model from his 'Boa'.
    
    ==License==
    This work is licensed under the Creative Commons Attribution-Noncommercial-Share Alike 4.0Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/ or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
    
    
    

    Equipment

    Name Visible Cost [deci-credits] Tech-Level
    Refill external fuel tank no 400 1+
    External Fuel Tanks - Full yes 1 16+
    External Fuel Tanks - Empty yes 1 16+

    Ships

    Name
    Boa Clipper
    Boa Clipper
    Boa Clipper
    boaclipper-player
    Python Clipper
    Python Clipper
    Python Clipper
    Python Clipper
    smivs-clipper-engine
    smivs-clipper-gun
    smivs-clipper-tank

    Models

    This expansion declares no models.

    Scripts

    Path
    Scripts/clipper_tanks_script.js
    "use strict";
    
    // Standard attributes 
    this.name           = "clipper_tanks_script.js"; 
    this.author         = "Smivs"; 
    this.copyright      = "(C) Smivs";
    this.licence        = "Creative Commons Attribution - Non-Commercial - Share Alike 4.0";
    this.version        = "1.4.3"; 
    this.description    = "Script to control external fuel tanks for player 'Clipper' ships."; 
    
    
    
    //The first two functions are concerned with updating existing users - check for old version at start
    this.startUp = function()
    {
      if (missionVariables.TL_FOR_EQ_LQG_TANK_EMPTY)
        {
    // set mission flag
          this.missionFlag = "NO";
          this.startUpComplete;
          delete this.startUp;
      }
    }
    this.missionScreenOpportunity = function()
    {
      if (missionVariables.TL_FOR_EQ_LQG_TANK_EMPTY)
        {
    // Do nothing now if tank is damaged
          if (player.ship.docked && player.ship.equipmentStatus("EQ_LQG_TANK_EMPTY") == "EQUIPMENT_DAMAGED") 
            {
              return;
            }
    // otherwise clean up and replace old status variables from previous versions and run mission screen
          if (player.ship.docked && player.ship.equipmentStatus("EQ_LQG_TANK") == "EQUIPMENT_OK"  && this.missionFlag && this.missionFlag === "NO")
            {
              delete missionVariables.TL_FOR_EQ_LQG_TANK_EMPTY;
              missionVariables.clipper_tank_status = "LQG_TANK_FULL";
              mission.runScreen({title: "!!! Fuel Tank Safety Notice !!!", messageKey: "clipperTank_v1.6_Update"}); 
              this.missionFlag = "DONE";
            }
          if (player.ship.docked && player.ship.equipmentStatus("EQ_LQG_TANK_EMPTY") == "EQUIPMENT_OK"  && this.missionFlag && this.missionFlag === "NO")
            {
              delete missionVariables.TL_FOR_EQ_LQG_TANK_EMPTY;
              missionVariables.clipper_tank_status = "LQG_TANK_EMPTY";
              mission.runScreen({title: "!!! Fuel Tank Safety Notice !!!", messageKey: "clipperTank_v1.6_Update"}); 
              this.missionFlag = "DONE";
            }
        } 
    }
    // handle purchase of new ship
    this.playerBoughtNewShip = function()
    {
      missionVariables.clipper_tank_status = "LQG_TANK_FULL";
    }
    // handle purchase of refills
    this.playerBoughtEquipment = function(equipment)
    {
      if (equipment == "EQ_LQG_CHARGE")
        {
          player.ship.removeEquipment("EQ_LQG_CHARGE");
          player.ship.removeEquipment("EQ_LQG_TANK_EMPTY");
          player.ship.awardEquipment("EQ_LQG_TANK");
          missionVariables.clipper_tank_status = "LQG_TANK_FULL";
        }
    }
    // if tank activated
    this.activated = function()
    {
      if (player.ship.fuel === 0 && player.ship.equipmentStatus ("EQ_LQG_TANK") == "EQUIPMENT_OK" && missionVariables.clipper_tank_status == "LQG_TANK_FULL")
         {
           this.ship.fuel += 3.0;
           player.ship.removeEquipment("EQ_LQG_TANK");
           player.ship.awardEquipment("EQ_LQG_TANK_EMPTY");
           missionVariables.clipper_tank_status = "LQG_TANK_EMPTY";
           player.consoleMessage("Fuel transferred to Main Tank");
         }
    // unless the main tank is not empty
      else if (player.ship.fuel > 0 && player.ship.equipmentStatus ("EQ_LQG_TANK") == "EQUIPMENT_OK" && missionVariables.clipper_tank_status == "LQG_TANK_FULL")
         {
           player.consoleMessage("Fuel transfer cancelled - Main Tank must be empty");
           return;
         }
    // or the external tank is empty - this shouldn't be necessary as the empty tank cannot be primed
      else if (player.ship.fuel > 0 && player.ship.equipmentStatus ("EQ_LQG_TANK_EMPTY") == "EQUIPMENT_OK" && missionVariables.clipper_tank_status == "LQG_TANK_EMPTY")
         {
           player.consoleMessage("Fuel transfer un-available - External Tanks are empty.");
           return;
         }
    }
    // condition scripting to control availability of refills
    this.allowAwardEquipment = function(equipment, ship, context)
    {
      if (equipment == "EQ_LQG_CHARGE")
        {
          if (context == "purchase" && player.ship.equipmentStatus("EQ_LQG_TANK_EMPTY") == "EQUIPMENT_OK" && missionVariables.clipper_tank_status == "LQG_TANK_EMPTY")
    	{
    	  return true;
    	}
        }
    }
    
    Scripts/clippersScript.js
    "use strict"; 
    
    // Standard attributes 
    this.name           = "clippersScript.js"; 
    this.author         = "Smivs"; 
    this.copyright	    = "© Smivs"; 
    this.licence        = "Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License"; 
    this.version        = "1.4.3"; 
    this.description    = "Script to render ship derelict upon ejection of pilot." 
    
    
    this.shipLaunchedEscapePod = function()
    {
      this.switchFlashersAITimer = new Timer(this, this.$switchFlashersOff,8); // timer to switch off flashers after 8 seconds
      this.switchHullTexTimer = new Timer(this, this.$switchHullTex,12); // timer to switch off hull lights emission map after 12 seconds
      this.rotateDerelictTimer = new Timer(this, this.$rotateDerelict,25); // timer to start derelict rotation after 25 seconds
      this.switchEngineTexTimer = new Timer(this, this.$switchEngineTex,35); // timer to switch engines textures to derelict version after 35 seconds
    }
    this.$switchFlashersOff = function()
    {
      this.ship.lightsActive = false; // turns flashers off
    }
    this.$switchHullTex = function()
    {
      var $clippersTexture = this.ship.scriptInfo.clippersTexture; // uses scriptInfo key to build ship's default texture name
      var $clippersDiffuse = this.ship.scriptInfo.clippersDiffuse; // uses scriptInfo key to build ship's diffuse_map name
      var $clippersLighting = this.ship.scriptInfo.clippersLighting; // uses scriptInfo key to build ship's emission_map name
      var $clippersDerelict = this.ship.scriptInfo.clippersDerelict; // uses scriptInfo key to build derelict emission_map name
      var $clippersNormal = this.ship.scriptInfo.clippersNormal; // uses scriptInfo key to build ship's normal_map name
      var $clippersSpecular = this.ship.scriptInfo.clippersSpecular; // uses scriptInfo key to build ship's specular_map name
      var material = new Object(); // declare variable
      material[$clippersTexture] = {diffuse_map:$clippersDiffuse, emission_map:$clippersDerelict, normal_map:$clippersNormal, specular_map:$clippersSpecular}; // set up material entry
      this.ship.setMaterials(material); // apply material
    }
    this.$rotateDerelict = function()
    {
      this.rotateVector = Vector3D.randomDirection(); // creates a random axis of rotation.
      this.rotateSpeedFactor = (Math.random() * (0.05) + 0.05); // creates a random rotate speed factor between 0.05 and 0.1 - 0.1 will result in a rotation speed of approx 1 full rotation every 63 seconds, 0.05 in a rotation speed of approx 1 full rotation every 126 seconds.
      this.rotateDerelictCallBack = addFrameCallback(this.rotateFunction.bind(this)); // create FrameCallback
    }
    this.rotateFunction = function(delta) // delta is the time in game seconds since the last frame.
    {
      if (!this.ship.isValid){removeFrameCallback(this.rotateDerelictCallback);delete this.rotateDerelictCallback;return;} // end FrameCallback is ship has died;
      if (delta === 0){return;} // do nothing if game is paused;
      var newOrientation = this.ship.orientation.rotate(this.rotateVector,delta*this.rotateSpeedFactor); // calculates new orientation, using delta as a factor so that rotation speed is constant across varying frame rates. delta*this.rotateSpeedFactor is a value in radians. There are approx 6.3 radians in a full rotation.
      this.ship.orientation = newOrientation; // applies new orientation;
    }
    this.$switchEngineTex = function()
    {
      var $onTexture; // declare variable
      var $offTexture; //declare variable
      var material = new Object(); // declare variable
      var subents = this.ship.subEntities; // create array of subents
      var counter = 0; // set up loop to check if subent is an engine and if so change texture to derelict version
      var subentsLength = subents.length;
      for (counter = 0; counter < subentsLength;counter++)
        {
          if (subents[counter].scriptInfo.engineOnTexture)
    	{
    	  $onTexture = subents[counter].scriptInfo.engineOnTexture; // uses scriptInfo key to build engine texture name
    	  $offTexture = subents[counter].scriptInfo.engineOffTexture; // uses scriptInfo key to build derelict engine texture name
    	  material[$onTexture] = {diffuse_map:$offTexture}; // set up material entry
    	  subents[counter].setMaterials(material); // sets material
    	}
        }
    }
    this.entityDestroyed = function()
    // stop timers
    {
      if(this.switchFlashersAITimer)
        {
          if (this.switchFlashersAITimer.isRunning) 
            {
              this.switchFlashersAITimer.stop();
              delete this.switchFlashersAITimer;
            }
         }
      if(this.switchHullTexTimer)
         {
           if (this.switchHullTexTimer.isRunning) 
             {
               this.switchHullTexTimer.stop();
               delete this.switchHullTexTimer;
             }
         }
      if(this.rotateDerelictTimer)
         {
           if (this.rotateDerelictTimer.isRunning) 
             {
               this.rotateDerelictTimer.stop();
               delete this.rotateDerelictTimer;
             }
          }
      if(this.switchEngineTexTimer)
         {
           if (this.switchEngineTexTimer.isRunning) 
             {
               this.switchEngineTexTimer.stop();
               delete this.switchEngineTexTimer;
             }
          }
    }