Join us at the Oolite Anniversary Party -- London, 7th July 2024, 1pm
More details in this thread.

Split: Deployable subentities

Discussion and information relevant to creating special missions, new ships, skins etc.

Moderators: winston, another_commander

User avatar
spara
---- E L I T E ----
---- E L I T E ----
Posts: 2676
Joined: Wed Aug 15, 2012 4:19 am
Location: Finland

Re: Scripters cove

Post by spara »

To my understanding, when used in a shipscript, shipScoopedOther triggers when the ship that it's attched to scoops something.

If it's in a worldscript, then it triggers when the player scoops something.
User avatar
Tricky
---- E L I T E ----
---- E L I T E ----
Posts: 821
Joined: Sun May 13, 2012 11:12 pm
Location: Bradford, UK. (Anarchic)

Re: Scripters cove

Post by Tricky »

spara wrote:
To my understanding, when used in a shipscript, shipScoopedOther triggers when the ship that it's attched to scoops something.

If it's in a worldscript, then it triggers when the player scoops something.
To be more precise, when used in a shipscript, shipScoopedOther triggers when an NPC scoops something. Not the player.
User avatar
cim
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 4072
Joined: Fri Nov 11, 2011 6:19 pm

Re: Scripters cove

Post by cim »

Tricky wrote:
To be more precise, when used in a shipscript, shipScoopedOther triggers when an NPC scoops something. Not the player.
No, spara was correct.

If a ship scoops something (whether that ship is player or NPC), the shipScoopedOther event will be sent to its ship script and its AI script. In general the player ship will have a blank AI script and the default (almost blank) ship script - but it's possible that it has a special ship script either defined in shipdata.plist or applied to it later.

If the player ship scoops something, then in addition to the above, the shipScoopedOther event is also sent to all world scripts after being sent to the ship scripts.

There are also world-script only events which are not related to any particular ship (e.g. startUp).
User avatar
Tricky
---- E L I T E ----
---- E L I T E ----
Posts: 821
Joined: Sun May 13, 2012 11:12 pm
Location: Bradford, UK. (Anarchic)

Re: Scripters cove

Post by Tricky »

Interesting. I didn't think a shipscript could be applied to a player. What happens if you attach an AI script via the shipscript to the player. Is that possible.
User avatar
cim
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 4072
Joined: Fri Nov 11, 2011 6:19 pm

Re: Scripters cove

Post by cim »

You can't set the player AI. You can define additional methods on to the existing oolite-nullAI.js AI script which is attached by default - e.g. player.ship.AIScript.shipWillEnterWitchspace = .... There's little point in doing so, though - they'll be lost any time the player activates or deactivates the docking computer, and it can't do anything that the normal ship script or a world script can't do.
User avatar
spara
---- E L I T E ----
---- E L I T E ----
Posts: 2676
Joined: Wed Aug 15, 2012 4:19 am
Location: Finland

Re: Scripters cove

Post by spara »

I'm spawning ships with the role "trader" and trying to filter out those that have the standard trader ai attached to them. Filtering works ok, but when I remove a just spawned ship with a custom ai to spawn a new one the game throws this:
19:39:10.327 [general.error.inconsistentState]: DEBUG: Universe removeEntity:<ShipEntity 0x1ff9c90>{"Hognose" position: (0, 0, 0) scanClass: CLASS_NEUTRAL status: STATUS_DEAD} ENTITY IS NOT IN THE RIGHT PLACE IN THE ZERO_DISTANCE SORTED LIST -- FIXING...
19:39:10.327 [general.error.inconsistentState]: DEBUG: Universe removeEntity:<ShipEntity 0x1ff9c90>{"Hognose" position: (0, 0, 0) scanClass: CLASS_NEUTRAL status: STATUS_DEAD} ENTITY IS NOT IN THE ZERO_DISTANCE SORTED LIST -- CONTINUING...
Ships are added with this:

Code: Select all

var ship = station.launchShipWithRole("trader")
And right after the ai check removed with this:

Code: Select all

if (ship.isValid) ship.remove(true);
What goes wrong here?
User avatar
Pleb
---- E L I T E ----
---- E L I T E ----
Posts: 908
Joined: Sun Apr 29, 2012 2:23 pm
Location: United Kingdom

Re: Scripters cove

Post by Pleb »

Ah, I hadn't read spara's original reply properly... It's been a long day! :oops:

This now works using a worldscript, thank you spara and cim! :mrgreen:
Desktop PC: CPU: Intel i7-4790K Quad Core 4.4GHz (Turbo-Charged) GPU: Nvidia GeForce GTX 1080Ti RAM: 32GB DDR3

Laptop PC: CPU: Intel i5-10300H Quad Core 4.5GHz (Turbo-Charged) GPU: Nvidia GeForce GTX 1650 RAM: 32GB DDR4
dertien
---- E L I T E ----
---- E L I T E ----
Posts: 471
Joined: Sun Jan 23, 2011 9:27 pm
Location: Belgium, Monarchy, Feudal, Overtaxed system

Re: Scripters cove

Post by dertien »

cim wrote:
dertien wrote:
using something like this in javascript

actuators.position = [0,-5,0,1,0,0,0];

That would really be handy.
It's possible, but it needs two steps.

Code: Select all

actuators.position = [0,-5,0];
actuators.orientation = [1,0,0,0];
Obviously, a subentity as large as the LCB on the Cobra Mk3 cannot be repositioned to be hidden it in the model. (unless I cut it up in a few pieces that will fit in there :wink: )

So, regarding the use of subentities on player ships this time, Is it possible using similar code as above to resize a subentity on the fly instead of removing it like on the NPC's where the overhaul is a non issue ?

In a few steps for the cargo bay:

- So lets say an the subentity gets destroyed by laser fire (removed from model ingame)
- subentity is removed, and so is the "attached equipment" which will need to be repaired (using the code you posted earlier Cim)
- Subentity on the player ship is restored, but resized and put in the model (no overhaul)
- Player docks and purchases a "cargo bay repair".
- game detects if EQ_CARGO_BAY is on the ship or not, in either case resizing/relocating the restored subent.

Here's a little video I made today of the working landing gear script:

https://www.youtube.com/watch?v=WpJ9YKJ ... e=youtu.be
Alpha Backer of Elite Dangerous
With 250 GBP :D
User avatar
cim
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 4072
Joined: Fri Nov 11, 2011 6:19 pm

Re: Scripters cove

Post by cim »

spara wrote:
I'm spawning ships with the role "trader" and trying to filter out those that have the standard trader ai attached to them. Filtering works ok, but when I remove a just spawned ship with a custom ai to spawn a new one the game throws this:
Essentially you're removing the ship before it's been added to the universe (because it currently only exists in the station launch queue) and that's not expected.

Tonight's nightly should have a fix for the logged error, but I still wouldn't recommend doing it: add a trader with four escorts, then remove it, and the four escorts stay in the launch queue.
User avatar
cim
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 4072
Joined: Fri Nov 11, 2011 6:19 pm

Re: Scripters cove

Post by cim »

dertien wrote:
So, regarding the use of subentities on player ships this time, Is it possible using similar code as above to resize a subentity on the fly
No. Object size is fixed, for various reasons to do with how Oolite generates 3-D objects in the first place.
User avatar
spara
---- E L I T E ----
---- E L I T E ----
Posts: 2676
Joined: Wed Aug 15, 2012 4:19 am
Location: Finland

Re: Scripters cove

Post by spara »

cim wrote:
spara wrote:
I'm spawning ships with the role "trader" and trying to filter out those that have the standard trader ai attached to them. Filtering works ok, but when I remove a just spawned ship with a custom ai to spawn a new one the game throws this:
Essentially you're removing the ship before it's been added to the universe (because it currently only exists in the station launch queue) and that's not expected.

Tonight's nightly should have a fix for the logged error, but I still wouldn't recommend doing it: add a trader with four escorts, then remove it, and the four escorts stay in the launch queue.
I figured something like that. And yes, I removed the escorts too. I'll probably just keep on launching traders, till I get a good one. These launches will happen quite rarely anyway and usually I get a good one on the first try.
dertien
---- E L I T E ----
---- E L I T E ----
Posts: 471
Joined: Sun Jan 23, 2011 9:27 pm
Location: Belgium, Monarchy, Feudal, Overtaxed system

Re: Scripters cove

Post by dertien »

Eric Walch wrote:
dertien wrote:
So basically I want to show the landing gear subentities when the docking sequence is going on, or when the ship launches, (which shows the landing rear extended or retracted at its place) and remove them and show them in their retracted state when the ship is not in its docking/undocking sequence.
When you really want to do it good, you don't just remove it but move/rotate the gear inwards. A script that does something similar are the tug ships in Buoy Repair.oxp. (in the buoyRepairShip.js script) They collaps the buoy before docking and unfold it again after launch. This is because the buoy is to big to fit through the docking slid. :)
Sorry, missed your post yesterday Eric, will have a look at that Buoy Repair.oxp


@ Cim, shame that they cannot be resized, will have to tackle the problem differently, its do-able thus by cutting the LCB up in a few pieces ah, well...so be it.
Alpha Backer of Elite Dangerous
With 250 GBP :D
User avatar
Eric Walch
Slightly Grand Rear Admiral
Slightly Grand Rear Admiral
Posts: 5536
Joined: Sat Jun 16, 2007 3:48 pm
Location: Netherlands

Re: Scripters cove

Post by Eric Walch »

dertien wrote:
Sorry, missed your post yesterday Eric, will have a look at that Buoy Repair.oxp
I just filtered out the essential lines for you:

Code: Select all

this.buoy = new Array();
this.segmentName = "Navigation Buoy Segment";

this.shipSpawned = function ()
{
	if (this.ship.subEntities.length > 3) // has a segmented buoy.
	{
		this.position = 0; // means segments in folded position.
		var j = 0;
		for (var i = 0; i < this.ship.subEntities.length; i++)
		{
			// copy all buoy parts into a new array to avoid problems with changing subEntity ordering.
			if (this.ship.subEntities[i].name == this.segmentName) this.buoy[j++] = this.ship.subEntities[i];
		}
	}

	// This version starts with folded buoy to allow launches with it.
	this.unfoldTimer = new Timer(this, this.unfoldBuoy, 5.0);
}


this.entityDestroyed = function ()
{
    this.$cleanupTimers();
}

this.foldBuoy = function ()
{
    if (this.buoy.length == 3)
    {
        // the ship still has all the segments, so proceed with folding.
        this.movement = -0.02;
        if (!isValidFrameCallback(this.$callbackID)) this.$callbackID = addFrameCallback(this.moveBuoySegments.bind(this));
    }
}

this.unfoldBuoy = function ()
{
    if (this.buoy.length == 3)
    {
        // the ship still has all the segments, so proceed with unfolding.
        this.movement = 0.02;
        if (!isValidFrameCallback(this.$callbackID)) this.$callbackID = addFrameCallback(this.moveBuoySegments.bind(this));
    }
}

this.moveBuoySegments = function (delta)
{
    if (!delta) delta = 0.25;
    if (!this.ship || !this.ship.isValid || !this.ship.status || this.buoy.length < 3) {this.$cleanupTimers();return;};
    this.position += this.movement * delta;
    if (this.position >= 1) // buoy is unfolded
    {
        this.$cleanupTimers();
        this.position = 1;
    }
    if (this.position <= 0) // buoy is folded
    {
        this.$cleanupTimers();
        this.position = 0;
    }
    this.buoy[1].orientation = [1, this.position, 0, 0]; // Oolite wil normalise the quaternion for us on assignment.
    this.buoy[2].orientation = [1, 0, 0, this.position];
}

this.$cleanupTimers = function ()
{
	if (this.$callbackID && isValidFrameCallback(this.$callbackID))
	{ 
		removeFrameCallback(this.$callbackID);
        delete this.$callbackID;
	}
    if (this.unfoldTimer)
    {
        this.unfoldTimer.stop();
        delete this.unfoldTimer;
    }
}
On launch a timer is started and the timer starts the unfolding proces.
On docking, the AI starts the folding process. (That part is not clear from just looking at above JS script)
dertien
---- E L I T E ----
---- E L I T E ----
Posts: 471
Joined: Sun Jan 23, 2011 9:27 pm
Location: Belgium, Monarchy, Feudal, Overtaxed system

Re: Scripters cove

Post by dertien »

@ Eric,

Dank U, maar dit is echt wel chinees voor mij. :D

I can follow the stuff that Cim pointed out, but this is beyond me. However, I got it to work fairly well like this, using the code that Cim posted, and tried to construct my first function on my own:

Code: Select all

this.name      = "landing_gear"; 
this.author    = "griff"; 
this.copyright = "� 2008 griff."; 
this.version   = "1.01";

this._findSubEntity = function(key)
					{
					for (var i = this.ship.subEntities.length - 1 ; i >=0 ; --i)
						{
						if (this.ship.subEntities[i].dataKey == key)
							{
							return this.ship.subEntities[i];
							}
						}
						return null; // couldn't find it.
					}

this.retractGear = function()

{
   this.ship.commsMessage("retracted");

   var actuatorsR = this._findSubEntity("HPC_actuatorR"); 
               if (actuatorsR)
               {
                  actuatorsR.position = [0, 6.155206, 2.648078];
               }
	var actuatorsF = this._findSubEntity("HPC_actuatorF");
               if (actuatorsF)
               {
                  actuatorsF.position = [0, 3.80, -21.3];
               }
   var reargearextendPRT = this._findSubEntity("HPC_reargearPRT");
                  if (reargearextendPRT)
               {
               reargearextendPRT.position = [-17.392771, -8.961073, 2.796213];
			   reargearextendPRT.orientation = [0.9953, 0.0908, 0, 0];
               }
   var reargearextendSTB = this._findSubEntity("HPC_reargearSTB");
                  if (reargearextendSTB)
               {
               reargearextendSTB.position = [17.552752, -8.847222, 3.028129];
			   reargearextendPRT.orientation = [-0.9953, -0.0908, 0, 0];
               }
	var frontgearextendPRT = this._findSubEntity("HPC_frontgearPRT");
                  if (frontgearextendPRT)
               {
               frontgearextendPRT.position = [-13.038872, -5.954015, 25.049587];
			   reargearextendPRT.orientation = [0, 0, 0.9959, -0.0905];
               }
	var frontgearextendSTB = this._findSubEntity("HPC_frontgearSTB");
                  if (frontgearextendSTB)
               {
               frontgearextendSTB.position = [13.038872, -5.954015, 25.049587];
			   reargearextendPRT.orientation = [0.9959, 0.0905, 0, 0];
               }
	   
}

this.extendGear = function()
{

		var actuatorsR = this._findSubEntity("HPC_actuatorR"); 
               if (actuatorsR)
               {
                  actuatorsR.position = [0,0,0];
               }
		var actuatorsF = this._findSubEntity("HPC_actuatorF"); 
               if (actuatorsF)
               {
                  actuatorsF.position = [0,0,0];
               }
		var reargearextendPRT = this._findSubEntity("HPC_reargearPRT");
                  if (reargearextendPRT)
               {
               reargearextendPRT.position = [-17.351349,-17.408951,-3.749173];
               }
		var reargearextendSTB = this._findSubEntity("HPC_reargearSTB");
                  if (reargearextendSTB)
               {
               reargearextendSTB.position = [17.435233,-17.338642,-3.50929];
               }
		var frontgearextendPRT = this._findSubEntity("HPC_frontgearPRT");
                  if (frontgearextendPRT)
               {
               frontgearextendPRT.position = [-12.765342,-11.194131,27.818142];
               }
		var frontgearextendSTB = this._findSubEntity("HPC_frontgearSTB");
                  if (frontgearextendSTB)
               {
               frontgearextendSTB.position = [12.765342,-11.194131,27.818142];
               }
}					

this.playerStartedAutoPilot = function() //make LDG visible when pressing autopilot key

{
	this.ship.commsMessage("Autopilot ON");
	this.ship.commsMessage("GEAR DOWN & LOCKED");
	this.retractGear();
	this.extendGear();
	   
}

this.shipLaunchedFromStation = function(station) //make LDG invisible during startup sequence
{
	this.extendGear();
	this.tenSecTimer = new Timer(this, this.retractGear,10);
	this.ship.commsMessage("GEAR UP");
}


this.playerCancelledAutoPilot = function() 

{
	this.extendGear();
	this.retractGear();
	this.ship.commsMessage("Autopilot OFF");
	this.ship.commsMessage("GEAR UP");
	this.ship.AIState = "LIGHTS_OFF";
}

this.stationWithdrewDockingClearance = function()
{
     this.extendGear();
	 this.retractGear();
}

this.shipWillLaunchFromStation = function(station)
{
      this.retractGear();
	  this.extendGear();
}

this.shipDockedWithStation = function(station)
{
     this.retractGear();
	 this.extendGear();
}

this.shipApproachingPlanetSurface = function(planet)
{
	 this.retractGear();
	 this.extendGear();
	 this.ship.commsMessage("GEAR DOWN & LOCKED");
}

this.shipLeavingPlanetSurface = function(planet)
{
    this.extendGear(); 
	this.tenSecTimer = new Timer(this, this.retractGear,10);
	this.ship.commsMessage("GEAR UP");
}


Some bits work, some don't, and I am trying to add code, so a ship will extend its gear as well when it is targeting the main station and a certain distance away from it.

a bit like this, but it doesnt work yet:

Code: Select all

if(this.ship.target == system.mainStation && this.ship.position.distanceTo(this.ship.target) < 11000)
    {
		this.retractGear();
		this.extendGear();
    }
At the moment these three work as they should:

this.playerStartedAutoPilot = function()
this.shipLaunchedFromStation = function(station) NPC and Player
this.playerCancelledAutoPilot = function()

I would also like to know how to run a function depending on the ai.plist or even AIstate that the ship has loaded, if that is at all possible. This way I could hide/show the guns and close/open gunbay doors according to tis state.

I am trying to get ships that have this AIState to drop their gear, but it also has an influence on the playership, which I would like to avoid.

Code: Select all

if(this.ship.AIState = "GO_TO_STATION")
      {
      this.ship.commsMessage("debug message: GEAR DOWN & LOCKED");
		this.retractGear();
		this.extendGear();
      }
Alpha Backer of Elite Dangerous
With 250 GBP :D
User avatar
Eric Walch
Slightly Grand Rear Admiral
Slightly Grand Rear Admiral
Posts: 5536
Joined: Sat Jun 16, 2007 3:48 pm
Location: Netherlands

Re: Scripters cove

Post by Eric Walch »

dertien wrote:
I can follow the stuff that Cim pointed out, but this is beyond me.
Okay, leve it for later. The difference with your code is that the subentities don't jump between two positions, but change animated frame-by-frame from one position to the other, by the use of a frameCallback function. :)
Post Reply