Scripters cove
Moderators: winston, another_commander
Well, we could possibly have read-only properties for the player settings. Could also be useful to know if the music is off, on, or set to iTunes.
Other stuff, like if Oolite is being played in full screen, if growl or speech are enabled, wireframe mode, detailed(procedurally textured) planets enabled, etc.. might also be of some usefulness too.
The oxp could then use different code for different settings, I suppose.
Svengali, did you have anything specific in mind?
Other stuff, like if Oolite is being played in full screen, if growl or speech are enabled, wireframe mode, detailed(procedurally textured) planets enabled, etc.. might also be of some usefulness too.
The oxp could then use different code for different settings, I suppose.
Svengali, did you have anything specific in mind?
Hey, free OXPs: farsun v1.05 & tty v0.5! :0)
I'm afraid - expected this answer. Even if I wasn't thinking about Oolite-Class, more along the line of [[shaderEffectLevel]] or [[shadersAvailable]].Frame wrote:NoSvengali wrote:Is it possible for a script to determine if a machine has shader support and if the player has enabled it?
We cannot access information in regard to a graphics card abilities from Oolite Java scripting
No .-) I'm trying to avoid the creation of helper objects at all if no shader support is available. These helper objects are only there to display additional infos - via shader. And if a script could check it then it would be possible to switch between display or commsMessage.zevans wrote:would that fix whatever it is you're trying to do?
In that case, a read-only oolite.settings (or oolite.gameSettings) object - similar to the read-write system.info - should be what you're looking for. I think it's doable for 1.74.Svengali wrote:No .-) I'm trying to avoid the creation of helper objects at all if no shader support is available. These helper objects are only there to display additional infos - via shader. And if a script could check it then it would be possible to switch between display or commsMessage.
Hey, free OXPs: farsun v1.05 & tty v0.5! :0)
Sorry Kaks, haven't seen this.
Yupp. My 'problem' is specially that creating entities takes time and if I can avoid it...Kaks wrote:The oxp could then use different code for different settings, I suppose.
This would be great (even if it wasn't a suggestion) :-)Kaks wrote:In that case, a read-only oolite.settings (or oolite.gameSettings) object - similar to the read-write system.info - should be what you're looking for.
- PhantorGorth
- ---- E L I T E ----
- Posts: 647
- Joined: Wed May 20, 2009 6:48 pm
- Location: Somewhere off the top left of Galaxy 1 map
A fix for the arbitrary OXP loading order problem
I have been working on my own oxp (Visas.oxp) for a while now and as it is an engine oxp (injection system only with no content of it's own) I hit this rather well known issue of requiring an oxp to load after a particular one or set of the other oxps. But I think I have found a nifty way to do this. I have tested it with my visas oxp and the oxp I am using to test it with, and it works.
There is a limitation to this system and that is that it only works between oxps that are written in a particular way. It will not work with oxps that require their startUp function to be called after the startUp function of old oxps, but but I believe I have also found a way around this that will require a modification to the Oolite script loading and event system.
First here is a template that shows how to get this to work for new oxps:
Assuming that both Oxp_A and Oxp_B are written using the above template this then works by having Oxp_A checking if Oxp_B's startUp function has been called by checking Oxp_B's "loaded" flag and if has been called it then skips it, but if it hasn't been called it calls Oxp_B's startUp function early, before Oxp_A's code gets called, and then sets Oxp_B's "loaded" flag to "true". Now when Oolite comes to call Oxp_B's startUp function itself the "loaded" flag is now "true" so the body of the code is skipped and acts as if the startUp function wasn't called in the first place.
This now just a standard depency tree. The problem of circular references is averted because the currently executing startUp function sets the "loaded" flag to true before calling any startUp functions.
Resetting the loaded flags to "false" during shipDied functions allows the startUp functions to be called again when you restart the game.
You should also put the dependent oxps in your oxp's requires.plist. The above code may also need minor modification for when the dependent oxp is not installed.
Hopefully if everyone agrees this method should become part of Oxp development best practice.
Getting this to work for Old Oxps
Now to make this also work with old oxps we would need to change the way Oolite loads and calls functions:
Currently, as far as I can tell:
Instead of:
you do this:
You can mix as many of these two code snippets as required. Which you use would depend on the nature of the dependent oxp. (i.e. is it built use this new template or not)
As I don't full understand the way Oolite loads the oxps and how it would work with concept of the cache, I can not be sure that the old oxps method would work. I will leave that to someone with better knowledge than I.
Even is it doesn't work the template for new oxps should make things easier for oxp developers.
I have been working on my own oxp (Visas.oxp) for a while now and as it is an engine oxp (injection system only with no content of it's own) I hit this rather well known issue of requiring an oxp to load after a particular one or set of the other oxps. But I think I have found a nifty way to do this. I have tested it with my visas oxp and the oxp I am using to test it with, and it works.
There is a limitation to this system and that is that it only works between oxps that are written in a particular way. It will not work with oxps that require their startUp function to be called after the startUp function of old oxps, but but I believe I have also found a way around this that will require a modification to the Oolite script loading and event system.
First here is a template that shows how to get this to work for new oxps:
Code: Select all
this.name = "Oxp_A";
this.author = "Author";
this.copyright = "license";
this.description = "Some Description";
this.version = "1.0 alpha 1";
this.loaded = false;
this.startUp = function()
{
if (this.loaded != true)
{
this.loaded = true; // Must be done straight away to prevent loops and circular references.
// For handling oxps that are written using this template:
if (worldScripts.Oxp_B.loaded != true) worldScripts.Oxp_B.startUp(); // Calls Oxp_B.startUp as it is required to load before your Oxp_A.
// Repeat above for each OXP that this OXP depends on.
// Test for existence of an OXP that isn't required but effects the way this OXP works.
if (worldScripts["Oxp_X"])
{
this.Oxp_X_Exists = true;
}
else
{
this.Oxp_X_Exists = false;
}
// Repeat above for other similar OXP checks.
// Do other stuff here as required
log(this.name + " " + this.version +" loaded."); // This goes last so the load messages appear in a sensible order.
}
}
this.shipDied = function(whom, why)
{
if (whom == Player)
{
// Do other stuff here as required
this.loaded = false; // As this.startUp is called afterward (this.reset is deprecated).
}
// Do other stuff here as required
}
// Do other stuff here as required
Assuming that both Oxp_A and Oxp_B are written using the above template this then works by having Oxp_A checking if Oxp_B's startUp function has been called by checking Oxp_B's "loaded" flag and if has been called it then skips it, but if it hasn't been called it calls Oxp_B's startUp function early, before Oxp_A's code gets called, and then sets Oxp_B's "loaded" flag to "true". Now when Oolite comes to call Oxp_B's startUp function itself the "loaded" flag is now "true" so the body of the code is skipped and acts as if the startUp function wasn't called in the first place.
This now just a standard depency tree. The problem of circular references is averted because the currently executing startUp function sets the "loaded" flag to true before calling any startUp functions.
Resetting the loaded flags to "false" during shipDied functions allows the startUp functions to be called again when you restart the game.
You should also put the dependent oxps in your oxp's requires.plist. The above code may also need minor modification for when the dependent oxp is not installed.
Hopefully if everyone agrees this method should become part of Oxp development best practice.
Getting this to work for Old Oxps
Now to make this also work with old oxps we would need to change the way Oolite loads and calls functions:
Currently, as far as I can tell:
- 1) Oolite loads (if the shift key is pressed during starting) all the javascript scripts into memory. (if you don't press shift this is just loaded from cache instead.)
2) Then each startUp function is called in turn in some unspecified order.
3) Later when the player dies all existing shipDied functions are called, again in some unspecified order.
- a) If during 1) Oolite checks for which oxps do not have "loaded" defined and makes a list of these oxps called say "old_Oxps" and then defines the loaded variable for these oxp with the value "true".
b) At 2) for an oxp that is in that list, just before calling it's startUp function, Oolite checks the value of oxp.loaded and skips it if it is set to "true". If it is set to "false" then Oolite sets oxp.loaded to true and calls oxp.startUp.
c) When the player dies set all the "loaded"s for the oxps in the list "old_Oxps" to "false".
Instead of:
Code: Select all
// For handling oxps that are written using this template:
if (worldScripts.Oxp_B.loaded != true) worldScripts.Oxp_B.startUp(); // Calls Oxp_B.startUp as it is required to load before your Oxp_A.
// Repeat above for each OXP that this OXP depends on.
Code: Select all
// For handling old oxps that are NOT written using this template:
if (worldScripts.Oxp_Old.loaded != true)
{
worldScripts.Oxp_Old.loaded = true; // You do this as Oxp_Old can't.
worldScripts.Oxp_Old.startUp(); // Calls Oxp_Old.startUp as it is required to load before your Oxp_A.
}
// Repeat above for each old OXP that this OXP depends on.
As I don't full understand the way Oolite loads the oxps and how it would work with concept of the cache, I can not be sure that the old oxps method would work. I will leave that to someone with better knowledge than I.
Even is it doesn't work the template for new oxps should make things easier for oxp developers.
- Eric Walch
- Slightly Grand Rear Admiral
- Posts: 5536
- Joined: Sat Jun 16, 2007 3:48 pm
- Location: Netherlands
Nice options. And as you write: restart is deprecated. In 1.74 all scripts are restarted from scratch so things might get easier in future. Instead of setting a true value, the script can delete its startUp handled after use. That way you are sure it can't be called again.
But as you say, it only works for scripts that are specific written for each other. To be sure a script runs as last, you also can use timers. A zero value is often enough. The rock hermit locator uses this for example as it must run as last to be sure there are no stations added after it has ran.
And in BuoyRepair the reset handler contains a timer. When you for some reason must be sure that your startup handler runs last, you can execute the code with a timer. I an almost sure that timercode is only executed after finishing of all startUp handlers.
But as you say, it only works for scripts that are specific written for each other. To be sure a script runs as last, you also can use timers. A zero value is often enough. The rock hermit locator uses this for example as it must run as last to be sure there are no stations added after it has ran.
And in BuoyRepair the reset handler contains a timer. When you for some reason must be sure that your startup handler runs last, you can execute the code with a timer. I an almost sure that timercode is only executed after finishing of all startUp handlers.
UPS-Courier & DeepSpacePirates & others at the box and some older versions
- PhantorGorth
- ---- E L I T E ----
- Posts: 647
- Joined: Wed May 20, 2009 6:48 pm
- Location: Somewhere off the top left of Galaxy 1 map
I take it that you mean setting the this.startUp = undefined. And that in 1.74 as soon as the player dies the whole JavaScript setup is reloaded from cache. So there is no need to redefine this.startUp for each oxp. Am I correct here?Eric Walch wrote:Nice options. And as you write: restart is deprecated. In 1.74 all scripts are restarted from scratch so things might get easier in future. Instead of setting a true value, the script can delete its startUp handled after use. That way you are sure it can't be called again.
If that is the case the template would become:
Code: Select all
this.name = "Oxp_A";
this.author = "Author";
this.copyright = "license";
this.description = "Some Description";
this.version = "1.0 alpha 1";
this.loaded = false;
this.startUp = function()
{
if (this.startUp)
{
this.startUp = undefined // Must be done straight away to prevent loops. It doesn't stop this function from working.
// For handling oxps that are written using this template:
if (worldScripts.Oxp_B.startUp) worldScripts.Oxp_B.startUp(); // Calls Oxp_B.startUp as it is required to load before your Oxp_A.
// Repeat above for each OXP that this OXP depends on.
// For handling old oxps that are NOT written using this template:
if (worldScripts.Oxp_Old.startUp)
{
worldScripts.Oxp_Old.startUp(); // Calls Oxp_Old.startUp as it is required to load before your Oxp_A.
worldScripts.Oxp_Old.startUp = undefined; // You do this as Oxp_Old can't.
}
// Repeat above for each old OXP that this OXP depends on.
// Test for existence of an OXP that isn't required but effects the way this OXP works.
if (worldScripts["Oxp_X"])
{
this.Oxp_X_Exists = true;
}
else
{
this.Oxp_X_Exists = false;
}
// Repeat above for other similar OXP checks.
// Do other stuff here as required
log(this.name + " " + this.version +" loaded."); // This goes last so the load messages appear the sensible order.
}
}
// Do other stuff here as required
I will work on a combined version that works for both and post it here.
I am aware of the timer method but I find that rather inelegant.Eric Walch wrote:But as you say, it only works for scripts that are specific written for each other. To be sure a script runs as last, you also can use timers. A zero value is often enough. The rock hermit locator uses this for example as it must run as last to be sure there are no stations added after it has ran.
And in BuoyRepair the reset handler contains a timer. When you for some reason must be sure that your startup handler runs last, you can execute the code with a timer. I an almost sure that timercode is only executed after finishing of all startUp handlers.
I think he means
On restart / reload all scripts are reloaded from scratch, so any deleted this.startUp function will be back there, ready to be deleted again.
Code: Select all
delete this.startUp;
Hey, free OXPs: farsun v1.05 & tty v0.5! :0)
- PhantorGorth
- ---- E L I T E ----
- Posts: 647
- Joined: Wed May 20, 2009 6:48 pm
- Location: Somewhere off the top left of Galaxy 1 map
Kaks you are right but I thought that both ways are identical.Kaks wrote:I think he meansCode: Select all
delete this.startUp;
Here is the version using delete instead:
Code: Select all
this.name = "Oxp_A";
this.author = "Author";
this.copyright = "license";
this.description = "Some Description";
this.version = "1.0 alpha 1";
this.startUp = function()
{
delete this.startUp; // Must be done straight away to prevent loops. It doesn't stop this function from working.
// For handling oxps that are written using this template:
if (worldScripts.Oxp_B.startUp) worldScripts.Oxp_B.startUp(); // Calls Oxp_B.startUp as it is required to load before your Oxp_A.
// Repeat above for each OXP that this OXP depends on.
// For handling old oxps that are NOT written using this template:
if (worldScripts.Oxp_Old.startUp)
{
worldScripts.Oxp_Old.startUp(); // Calls Oxp_Old.startUp as it is required to load before your Oxp_A.
delete worldScripts.Oxp_Old.startUp; // You do this as Oxp_Old can't.
}
// Repeat above for each old OXP that this OXP depends on.
// Test for existence of an OXP that isn't required but effects the way this OXP works.
if (worldScripts["Oxp_X"])
{
this.Oxp_X_Exists = true;
}
else
{
this.Oxp_X_Exists = false;
}
// Repeat above for other similar OXP checks.
// Do other stuff here as required
log(this.name + " " + this.version +" loaded."); // This goes last so the load messages appear the sensible order.
}
// Do other stuff here as required
That's what I thought.Kaks wrote:On restart / reload all scripts are reloaded from scratch, so any deleted this.startUp function will be back there, ready to be deleted again.
- JensAyton
- Grand Admiral Emeritus
- Posts: 6657
- Joined: Sat Apr 02, 2005 2:43 pm
- Location: Sweden
- Contact:
This isn’t quite true, but it’s also not relevant. The compiled scripts Oolite caches are effectively a processed version of the text in the script file. The cache doesn’t affect script behaviour in any way, so it’s best not to think about it.PhantorGorth wrote:1) Oolite loads (if the shift key is pressed during starting) all the javascript scripts into memory. (if you don't press shift this is just loaded from cache instead.)
Eric is correct in that timers can’t fire between different scripts’ startup timers. Of course, timers are still limited in that they don’t allow for dependency chains.
E-mail: [email protected]
- PhantorGorth
- ---- E L I T E ----
- Posts: 647
- Joined: Wed May 20, 2009 6:48 pm
- Location: Somewhere off the top left of Galaxy 1 map
That's useful to know. I wasn't 100% sure of the mechanism. I was mostly concern about it for my suggestion for getting my original dependency mechanism to work for dependencies on old oxps but with the changes that are coming with 1.74 that suggestion is now irrelevant.Ahruman wrote:This isn’t quite true, but it’s also not relevant. The compiled scripts Oolite caches are effectively a processed version of the text in the script file. The cache doesn’t affect script behaviour in any way, so it’s best not to think about it.
I now have a method that works for newly written oxps for pre version 1.74 and a method that works for new and old oxps in 1.74. All I need to do is put them together for oxp that are compatible in both sets of versions. For dependencies on old oxps in pre 1.74 you would have to depend on other methods such as the timer method.
That's why I find the method less elegant.Eric is correct in that timers can’t fire between different scripts’ startup timers. Of course, timers are still limited in that they don’t allow for dependency chains.
hej,
list-reading is still new to me and I need help to learn if I understood this correctly/ all wrong.
So I wanted a prettier but not uber ship and found me a suitable OXP containing two ships, mostly faithful to the Cobra 3 they are modded from.
Now I only ever see the one of them. Looking into the shipyard.plist I see ... this
- every 10,000th TL>=10 shipyard I visit will offer this ship ? (on average)
or
- every 10,000th ship I see offered at TL>=10 shipyards will be such ship ? So, maybe every ~400th or 500th TL>=10 shipyard ?
Leading to the next question : How many TL>=10 systems are there, at all ? I would think certainly no 10,000, but if my 2nd interpretation idea is correct, then there may actually be 1 or even 2 ships of these available in all Ooniverse ?
In the end, what this means to me, if I ever find it, expensive as it is, I must buy it.
[stubborn-mode] And no, I do not want to"hack" / "cheat". If the author planned it this way - fine. Will only make it more special, should I really ever see it. [/stubborn-mode]
list-reading is still new to me and I need help to learn if I understood this correctly/ all wrong.
So I wanted a prettier but not uber ship and found me a suitable OXP containing two ships, mostly faithful to the Cobra 3 they are modded from.
Now I only ever see the one of them. Looking into the shipyard.plist I see ... this
Now, does this mean, that<key>price</key>
<integer>470000</integer>
...
<key>techlevel</key>
<integer>10</integer>
...
<key>chance</key>
<real>0.0001</real>
- every 10,000th TL>=10 shipyard I visit will offer this ship ? (on average)
or
- every 10,000th ship I see offered at TL>=10 shipyards will be such ship ? So, maybe every ~400th or 500th TL>=10 shipyard ?
Leading to the next question : How many TL>=10 systems are there, at all ? I would think certainly no 10,000, but if my 2nd interpretation idea is correct, then there may actually be 1 or even 2 ships of these available in all Ooniverse ?
Should this raise my hopes ? Significantly, I mean ?wiki wrote:The difference between the local tech level and the ship’s tech level also factor into this.
In the end, what this means to me, if I ever find it, expensive as it is, I must buy it.
[stubborn-mode] And no, I do not want to"hack" / "cheat". If the author planned it this way - fine. Will only make it more special, should I really ever see it. [/stubborn-mode]
- Lestradae
- ---- E L I T E ----
- Posts: 3095
- Joined: Tue Apr 17, 2007 10:30 pm
- Location: Vienna, Austria
..
How do I translate the legacy "Spawn *role* *number*" into a java script?
I tried "system.legacy_spawn" as a logical option, but to no avail.
So how to spawn something with a java script?
Help is much appreciated.
I tried "system.legacy_spawn" as a logical option, but to no avail.
So how to spawn something with a java script?
Help is much appreciated.
Re: ..
Lestradae wrote:How do I translate the legacy "Spawn *role* *number*" into a java script?
Code: Select all
targetShip.spawn("role",number);
or
targetShip.spawnOne("role");
http://wiki.alioth.net/index.php/Oolite ... ence:_Ship tells you more about it...
Last edited by Svengali on Tue Feb 23, 2010 3:47 pm, edited 1 time in total.
- Cmd. Cheyd
- ---- E L I T E ----
- Posts: 934
- Joined: Tue Dec 16, 2008 2:52 pm
- Location: Deep Horizon Industries Manufacturing & Research Site somewhere in G8...
1.73.4 Code
Specific Example :
For Trunk See:
http://wiki.alioth.net/index.php/Oolite ... m#addShips
Specific Example :
Code: Select all
system.legacy_addShipsWithinRadius('pirate',Num_Pirates,'abs',player.ship.position,25600);
For Trunk See:
http://wiki.alioth.net/index.php/Oolite ... m#addShips
Find my OXP's at:
Deep Horizon Industries - Your Planet Our Design
Deep Horizon Industries - Your Planet Our Design