Page 4 of 7

Re: Scripters cove

Posted: Fri Aug 15, 2014 2:17 pm
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.

Re: Scripters cove

Posted: Fri Aug 15, 2014 2:46 pm
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.

Re: Scripters cove

Posted: Fri Aug 15, 2014 4:33 pm
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).

Re: Scripters cove

Posted: Fri Aug 15, 2014 4:44 pm
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.

Re: Scripters cove

Posted: Fri Aug 15, 2014 4:54 pm
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.

Re: Scripters cove

Posted: Fri Aug 15, 2014 5:09 pm
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?

Re: Scripters cove

Posted: Fri Aug 15, 2014 5:14 pm
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:

Re: Scripters cove

Posted: Fri Aug 15, 2014 7:06 pm
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

Re: Scripters cove

Posted: Fri Aug 15, 2014 7:19 pm
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.

Re: Scripters cove

Posted: Fri Aug 15, 2014 7:25 pm
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.

Re: Scripters cove

Posted: Fri Aug 15, 2014 7:41 pm
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.

Re: Scripters cove

Posted: Fri Aug 15, 2014 9:15 pm
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.

Re: Scripters cove

Posted: Fri Aug 15, 2014 10:53 pm
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)

Re: Scripters cove

Posted: Sat Aug 16, 2014 12:19 am
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();
      }

Re: Scripters cove

Posted: Sat Aug 16, 2014 7:58 am
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. :)