Page 3 of 7

Re: Scripters cove

Posted: Thu Aug 14, 2014 8:30 pm
by cim
dertien wrote:
actuators.add();
There are two problems with this.
A) There isn't a ".add()" method to counter ".remove()". To put a subentity back onto a ship, you have to:
1 - remember which subentities you currently have
2 - call ship.restoreSubEntities() to reset the ship back to its factory default
3 - remove any subentities, except the one you meant to add, which aren't on the list you made in step 1

Unfortunately with the way Oolite specifies subentities at the moment, writing a built-in method to only restore a specific subentity is difficult (for those about to ask: because there's no unambiguous way to specify which subentity to restore given that you want the restore to fail if it's already on the ship)

B) Because the subentity isn't already on the ship when you want to add it, _findSubEntity will return null, so "if (actuators)" will be false, so it'll never run the actuators.add() line anyway - and if it did, it would run null.add(), which wouldn't help you.


An easier way to handle this, assuming the subentities are relatively small compared with the main hull, is rather than removing them, reposition them.

Code: Select all

var actuators = this._findSubEntity("HPC_actuatorR"); //make actuator visible during  station launch sequence
               if (actuators)
               {
                  actuators.position = [0,-30,0];
               }
   var reargearextendPRT = this._findSubEntity("HPC_reargearPRT");
                  if (reargearextendPRT)
               {
               reargearextendPRT.position = [0,0,0];
               }
   var reargearextendSTB = this._findSubEntity("HPC_reargearSTB");
                  if (reargearextendSTB)
               {
               reargearextendSTB.position = [0,0,0];
               }
Subentity positions in script are measured relative to the main entity - same as they are in shipdata.plist - so rather than adding or removing the subentities, you hide them inside the centre of the ship when they're not in use, and return them to their normal positions when they are needed again.


As far as the lasers go, that should work (assuming you were watching an NPC try to shoot, that is)

Re: Scripters cove

Posted: Thu Aug 14, 2014 8:39 pm
by dertien
Yes, I should be able to hide them inside the hull, without too much problems I believe. I will have a go at that, thank you.

I tested this with the player ship :oops: but not having bought another laser I assumed that would have worked since the subentity carries the laser and not the ship itself. My bad.

Re: Scripters cove

Posted: Thu Aug 14, 2014 8:54 pm
by cim
Only NPCs can have subentity lasers (and subentity lasers can only be forward lasers)

Re: Scripters cove

Posted: Thu Aug 14, 2014 9:14 pm
by dertien
Hm,

the

Code: Select all

this.ship.dataKey;
is at the right place ? or does it need anything else to make it work, all the other code seems to be correct, and I checked for typos.

I cannot see the subentities moved...

I am testing this with the player ship leaving the station, that should work ?

Re: Scripters cove

Posted: Thu Aug 14, 2014 9:20 pm
by dertien
cim wrote:
Only NPCs can have subentity lasers (and subentity lasers can only be forward lasers)
ok

Re: Scripters cove

Posted: Thu Aug 14, 2014 9:42 pm
by cim
dertien wrote:

Code: Select all

this.ship.dataKey;
is at the right place ?
Probably not - I think that line is entirely unnecessary (though harmless).

The problem is slightly different, reading the script again. I'll add some comments

Code: Select all

this.shipLaunchedFromStation = function(station)
{
  if(this.ship.isValid) // CIM: this will always be true at this point
    {
   this.ship.commsMessage("Hello world");
   this.ship.dataKey;
   var actuators = this._findSubEntity("HPC_actuatorR"); //make actuator visible during  station launch sequence
               if (actuators)
               {
                  actuators.add();
               }
   var reargearextendPRT = this._findSubEntity("HPC_reargearPRT");
                  if (reargearextendPRT)
               {
               reargearextendPRT.remove();
               }
   var reargearextendSTB = this._findSubEntity("HPC_reargearSTB");
                  if (reargearextendSTB)
               {
               reargearextendSTB.remove();
               }
   
    }
   else
// CIM: There should be an opening brace here after the else.
   var actuators = this._findSubEntity("HPC_actuatorR"); //make actuator visible during  station launch sequence
               if (actuators)
               {
                  actuators.remove();
               }
   var reargearextendPRT = this._findSubEntity("HPC_reargearPRT"); // remove subentity "rear gear up PRT"
                  if (reargearextendPRT)
               {
               reargearextendPRT.add();
               }
   var reargearextendSTB = this._findSubEntity("HPC_reargearSTB"); // remove subentity "rear gear up PRT"
                  if (reargearextendSTB)
               {
               reargearextendSTB.add();
               }
// CIM: and presumably the closing brace of it here.
}
So ... here's another bit of tricky syntax.

Code: Select all

if (a) 
{
  this();
  that();
}
else
{
  the();
  other();
}
means if 'a' is true, do this and that, otherwise do the and other. Whereas,

Code: Select all

if (a) 
{
  this();
  that();
}
else
  the();
  other();
means if 'a' is true, do this and that, otherwise do the - and then in either case do other. Javascript places some braces in implicitly in this case, like this.

Code: Select all

if (a) 
{
  this();
  that();
}
else
{ // here
  the();
} // and here
  other();
So what your script is currently doing is checking that the ship is valid (it is), putting the actuators out and the landing gear in, and then... this bit

Code: Select all

  else
   var actuators = this._findSubEntity("HPC_actuatorR"); //make actuator visible during  station launch sequence
               if (actuators)
               {
                  actuators.remove();
               }
gets read as

Code: Select all

  else
{ // Javascript assumes this
   var actuators = this._findSubEntity("HPC_actuatorR"); //make actuator visible during  station launch sequence
} // and assumes this
               if (actuators) // and now this is outside the previous if/else, so it happens too.
               {
                  actuators.remove();
               }
...so your code then goes on to reset the actuators and landing gear to what they were before.

I would trim the entire function down to just

Code: Select all

this.shipLaunchedFromStation = function(station)
{
   this.ship.commsMessage("Hello world");

   var actuators = this._findSubEntity("HPC_actuatorR"); //make actuator visible during  station launch sequence
               if (actuators)
               {
                  actuators.add();
               }
   var reargearextendPRT = this._findSubEntity("HPC_reargearPRT");
                  if (reargearextendPRT)
               {
               reargearextendPRT.remove();
               }
   var reargearextendSTB = this._findSubEntity("HPC_reargearSTB");
                  if (reargearextendSTB)
               {
               reargearextendSTB.remove();
               }
}
Replacing .add() and .remove() with the position changes you've previously set up, of course.

The other half of the code, which sets the subentities the other way, could go inside the this.shipWillDockWithStation function (though on anything other than the player ship, it doesn't matter)

Re: Scripters cove

Posted: Thu Aug 14, 2014 10:07 pm
by dertien
Thanks for the lesson Cim,


And it does indeed work now, so I should be able to make a few more changes now to other parts like the gunbaydoors and position of the guns as well, being able to have an aggressive and a passive stance for both NPC's and Player. Meaning guns and weapon launcher would be "deployed" or "retracted" depending on the state.

Thanks again you' re my hero. :D

Is it possible to also rotate the subentities using the Quaternion data instead of moving subentities like it is done in the shipdata.plist ?:

Code: Select all

"HPC_reargearPRT -17.392771 -8.961073 2.796213 0.9953 0.0908 0 0",


using something like this in javascript

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

That would really be handy.

Re: Scripters cove

Posted: Thu Aug 14, 2014 10:09 pm
by cim
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];

Re: Scripters cove

Posted: Thu Aug 14, 2014 10:17 pm
by dertien
Thank you ! exactly what I needed
:lol:

Re: Scripters cove

Posted: Thu Aug 14, 2014 11:04 pm
by Pleb
I still can't get this to work. I have set up the following as a script:

this.shipScoopedOther = function(whom)
{
log(this.name, "Scooped!");
}


But it still doesn't do anything! Is there something I'm missing?

Re: Scripters cove

Posted: Fri Aug 15, 2014 12:05 am
by Norby
I have set up the following as a script:
I guess you mean ship script under script, but you must put this into a worldscript and the "whom" is what the player is scooped.

Re: Scripters cove

Posted: Fri Aug 15, 2014 7:32 am
by Eric Walch
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. :)

Re: Scripters cove

Posted: Fri Aug 15, 2014 10:02 am
by Pleb
Norby wrote:
I guess you mean ship script under script, but you must put this into a worldscript and the "whom" is what the player is scooped.
Sorry I was falling asleep when I wrote this last night! Essentially I wrote a test script to see if the shipScoopedOther would enable me to run a scripted event every time an escape pod was scooped. So I created a ship script with the following:

Code: Select all

this.shipScoopedOther = function(whom)
{
   log(this.name, "Scooped!");
}
I took this example from the wiki and inserted a line in the middle to test if it worked by sending a message to the log. However this hasn't worked as nothing came up in the log but the escape pod works fine...

Basically I just want to be able to run a scripted event every time an escape pod is scooped. Is this possible, and if so, how as I've now tried using shipScoopedOther and shipWasScooped following the wiki but neither has worked... :cry:

Re: Scripters cove

Posted: Fri Aug 15, 2014 1:28 pm
by Neelix
Pleb wrote:
Norby wrote:
I guess you mean ship script under script, but you must put this into a worldscript and the "whom" is what the player is scooped.
Sorry I was falling asleep when I wrote this last night! Essentially I wrote a test script to see if the shipScoopedOther would enable me to run a scripted event every time an escape pod was scooped. So I created a ship script with the following:

Code: Select all

this.shipScoopedOther = function(whom)
{
   log(this.name, "Scooped!");
}
I took this example from the wiki and inserted a line in the middle to test if it worked by sending a message to the log. However this hasn't worked as nothing came up in the log but the escape pod works fine...

Basically I just want to be able to run a scripted event every time an escape pod is scooped. Is this possible, and if so, how as I've now tried using shipScoopedOther and shipWasScooped following the wiki but neither has worked... :cry:
Just a thought but have you confirmed it was actually registered as a worldscript?
As I understand it, if it's not called script.js it needs to be referenced in world-scripts.plist or it won't be loaded as a world script.
If it has been loaded as a world script it's this.name should be listed in Latest.log.

- Neelix

Re: Scripters cove

Posted: Fri Aug 15, 2014 1:30 pm
by Pleb
No its a ship script they aren't referenced as world scripts and are called from shipdata.plist.