Page 1 of 1

Javascript inside ships - problems, problems?

Posted: Fri Feb 01, 2008 11:36 am
by Kaks
First of all, I've discovered that if you put

script = "myShipScript.js"

inside shipdata.plist, the old style scripting - like death_actions - will not be used by that ship. Quite puzzling for a while until I figured that out.

I've now got two questions:

- is there a list of all js events that apply to ships? I looked on the wiki, but couldn't find it.

- is there a way to access the individual ship one particular script is attached to? I wanted to access some of the ship properties using this.ship.propertyname, but - of course - it didn't work.

Cheers,

Kaks

Posted: Fri Feb 01, 2008 11:48 am
by another_commander
Kaks wrote:
I've discovered that if you put

script = "myShipScript.js"

inside shipdata.plist, the old style scripting - like death_actions - will not be used by that ship
Are you referring to version 1.70 vanilla? This should have been already fixed in the trunk. If you are using the trunk version, can you post the problematic shipdata and js script files?

Posted: Fri Feb 01, 2008 12:05 pm
by Kaks
yes, 1.70 vanilla. I'm trying to get a simple script to run for people who've downloaded 1.70-test

I haven't actually tested the last svn, but I'm pretty sure that this problem won't be there. (will test & let you know)

Before I forget, it looks like Log & LogWithClass don't actually do anything from inside a ship script in 1.70 vanilla either...

Posted: Fri Feb 01, 2008 1:36 pm
by JensAyton
another_commander wrote:
Kaks wrote:
I've discovered that if you put

script = "myShipScript.js"

inside shipdata.plist, the old style scripting - like death_actions - will not be used by that ship
Are you referring to version 1.70 vanilla? This should have been already fixed in the trunk.
Er, should it? This is the intended behaviour. *looks at code*
Have you actually tested that change? The actions set up this way won’t actually be called, unless the script calls them using runLegacyScriptActions(), which it shouldn’t since using runLegacyScriptActions() in user scripts is explicitly not supported.
- is there a way to access the individual ship one particular script is attached to? I wanted to access some of the ship properties using this.ship.propertyname, but - of course - it didn't work.
Hmm. That should work.
Before I forget, it looks like Log & LogWithClass don't actually do anything from inside a ship script in 1.70 vanilla either...
As should that. Bah, humbug.

Posted: Fri Feb 01, 2008 2:03 pm
by another_commander
Ahruman wrote:
another_commander wrote:
Are you referring to version 1.70 vanilla? This should have been already fixed in the trunk.
Er, should it? This is the intended behaviour. *looks at code*
Have you actually tested that change? The actions set up this way won’t actually be called, unless the script calls them using runLegacyScriptActions(), which it shouldn’t since using runLegacyScriptActions() in user scripts is explicitly not supported.
I tested using this modified treasuroid from cargo wrecks oxp:

Code: Select all

<key>treasure</key>
	<dict>
		<key>like_ship</key>
		<string>asteroid</string>
		<key>cargo_type</key>
		<string>CARGO_NOT_CARGO</string>
		<key>likely_cargo</key>
		<integer>15</integer>
		<key>max_cargo</key>
		<integer>150</integer>
		<key>model</key>
		<string>asteroid1.dat</string>
		<key>name</key>
		<string>Treasuroid</string>
		<key>roles</key>
		<string>piratestash pirate(0.000001)</string>
		<key>death_actions</key>
		<array>
			<string>commsMessage: [stash-message]</string>
			<string>spawn: Gem-stones 5</string>
			<string>awardCargo: 10 Gold</string>
		</array>
		<key>script</key>
		<string>treasuroid-script.js</string>
		<key>scanClass</key>
		<string>CLASS_NOT_SET</string>
	</dict>
The script used to test was this:

Code: Select all

this.name			= "treasuroid-script";
this.author			= "Test";
this.copyright		= "© 2007 the Oolite team.";
this.description	= "Standard script for Treasuroid.";
this.version		= "1.71";


// launch_actions handled on didSpawn().
if (this.legacy_launchActions != undefined)
{
	this.shipSpawned = function()
	{
		this.ship.runLegacyScriptActions(this.ship, this.legacy_launchActions);
		
		// These can only be used once; keeping them around after that is pointless.
		delete this.didSpawn;
		delete this.legacy_launchActions;
	}
}


// script_actions handled on shipDidDock() and wasScooped().
if (this.legacy_scriptActions != undefined)
{
	/*	legacy script_actions should be called for stations when the player
		docks, and for cargo pods when they are is scooped. No sane vessel can
		be scooped _and_ docked with. Non-sane vessels are certified insane.
	*/
	this.otherShipDocked = function(docker)
	{
		if (docker == player)
		{
			this.ship.runLegacyScriptActions(docker, this.legacy_scriptActions);
		}
	}
	this.shipWasScooped = function(scooper)
	{
		// Note "backwards" call, allowing awardEquipment: and similar to affect the scooper rather than the scoopee.
		scooper.runLegacyScriptActions(this.ship, this.legacy_scriptActions);
	}
}


// setup_actions handled on script initialization.
if (this.legacy_setupActions != undefined)
{
	this.ship.runLegacyScriptActions(this.ship, this.legacy_setupActions);
	delete this.legacy_setupActions;
}


this.shipDied = function(whom, why)
{
	LogWithClass("treasuroidTest.died", "Ship " + this.ship.shipDescription + " killed by " + whom + " by means of " + why);
	if (this.legacy_deathActions != undefined)
	{
		this.ship.runLegacyScriptActions(this.ship, this.legacy_deathActions);
	}
}


this.beingAttacked = function(whom)
{
	LogWithClass("treasuroidTest.beingAttacked", "Treasuroid is being attacked by " + whom);
}
Indeed, I am using runLegacyScriptActions to make deathActions work. I was not aware that this is unsupported for user scripts. Honestly, I thought this was a bug and not the intended behavior. Apologies, Ahurman. Will revert to the pre-existing code asap.

Posted: Fri Feb 01, 2008 4:55 pm
by Kaks
I found out what was happening:

All the global variables/objects get dereferenced from within the ship script after a kill & reload from save, as per what happened to Littlebear with re-spawning in here

As he says, the first time round everything works ok, then player, system missionVariables, etc get lost somewhere.

If you exit Oolite, then reload, the problem disappears.

I found a kludge for this problem, by creating custom properties to the ship & referencing the globals via them. What I did:

Code: Select all

	let b=system.shipsWithRole('myownbaddie')[0];
	b.vars=missionVariables;
	b.sys=system;
	b.plr=player;
	b.log=LogWithClass;
then from within myownbaddie's script:

Code: Select all


this.ship.plr.commsMessage('we meet again...');
this.ship.sys.legacy_addSystemShips('adder',1,'pwm', 1);
this.ship.log=('script.myownbaddie','can you read this?');
etc...



When I posted earlier, I only tried this method with 'sys' but was still using player, Log, etc.. inside the ship's script.
My guess is that when the other objects got dereferenced, this.ship got dereferenced too. Probably. Maybe. I just don't know.

Thing is, I've reloaded without exiting oolite for about 4 times now, and everything seems to work.

this.ship is still recognised as an object and everything that depends on it doesn't give me any more error messages.

I'm getting an odd result with missionVariables, but maybe it's a bug in my own script. Wouldn't be the first one!

Cheers,

Kaks

Posted: Fri Feb 01, 2008 6:22 pm
by JensAyton
another_commander wrote:
Indeed, I am using runLegacyScriptActions to make deathActions work. I was not aware that this is unsupported for user scripts. Honestly, I thought this was a bug and not the intended behavior. Apologies, Ahurman. Will revert to the pre-existing code asap.
This should probably obviouly be mentioned in oolite-default-ship-script.js. I was uncertain about exposing it as official functionality, but decided against it because I don’t want to be tied to the current mechanism for handling legacy scripts.

Posted: Fri Feb 01, 2008 8:32 pm
by Arexack_Heretic
...don't remember the treasuroid working...ever.

did you fix it?

good work you're doing kaks. :)

Posted: Sat Feb 02, 2008 9:43 am
by another_commander
Arexack_Heretic wrote:
...don't remember the treasuroid working...ever.

did you fix it?
If you mean having it send a message when it explodes and releasing cargo pods, then yes, I guess so, but only by using unsupported functionality.

If you mean something else, then I need some more specific information as to what is wrong with it and what exactly it is supposed to do.

Posted: Sat Feb 02, 2008 2:37 pm
by Arexack_Heretic
that's it basically. ;)

there also was an ambush rock, that was supposed to launch 3 kraits when blownup/approached.