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

Scripters cove

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

Moderators: another_commander, winston

Anonymissimus
---- E L I T E ----
---- E L I T E ----
Posts: 299
Joined: Mon Apr 27, 2015 9:03 pm

Re: Scripters cove

Post by Anonymissimus »

Fritz wrote:
Is it "officially" recommended to supply a dummy script containing nothing else than this.name or would this create unnecessary overhead?
I guess it would create some. Imagine that all of the world scripts of an oolite installation appear be stored in some container, probably in a set-like structure. It is printed into latest.log upon start. Looking up worldScripts["name"] should then cause log(count of loaded worldscripts) operations.
Norby wrote:
Fritz wrote:
is there any way to control which of the functions is called first?
Unfortunately is not, only the manually installed OXPs comes later than managed OXZs. The order between packages in the same folder is determined by the filesystem, in Windows this is the order of installation but random under Linux.
Are you sure ? Why should it be random, that feels strange...normally things in software are not random, unless they are either intended to be, or there is a bug. And it does not match my experience so far. I assume you are on windows ?
warning sound if a missile is inbound: Missile warning
Fritz
---- E L I T E ----
---- E L I T E ----
Posts: 591
Joined: Sun Jul 12, 2015 2:30 pm
Location: Bavaria, Germany
Contact:

Re: Scripters cove

Post by Fritz »

Windows file order is not random, but it seems random. Usually it is displayed in some order (name, date) but actually the order is defined by creation time. If you copy a folder, the order can change. And (I would almost call it a bug!) if you mark and copy several files by drag&drop, the last file will become the first (or vice versa, I'm not sure). I learned this when I copied mp3 files on an USB stick for my car radio, which simply plays the files in the "physical" order and not by file name.
"You wouldn't kill me just for a few credits, would you?" – "No, I'll do it just for the fun!"
User avatar
Wildeblood
---- E L I T E ----
---- E L I T E ----
Posts: 2290
Joined: Sat Jun 11, 2011 6:07 am
Location: Western Australia

Re: Scripters cove

Post by Wildeblood »

Fritz wrote:
Windows file order... if you mark and copy several files by drag&drop, the last file will become the first (or vice versa, I'm not sure)...
The one you are actually holding with the mouse pointer is copied first, that might be the first, last or one in the middle.
"So anti-globalist, he's practically a flat-earther."
User avatar
Wildeblood
---- E L I T E ----
---- E L I T E ----
Posts: 2290
Joined: Sat Jun 11, 2011 6:07 am
Location: Western Australia

Re: Scripters cove

Post by Wildeblood »

Fritz wrote:
If there are two (or more) OXPs containing a "shipSpawned" function, let's say, one for naming the ship and one for adjusting other properties (weapons, equipment, textures), is there any way to control which of the functions is called first? Is the calling sequence determined by the installation order of the OXPs or by something else, or is it completely random?

I want to create an OXP defining "company freighters" having different textures and other properties. I also want these ships to have special names based on company-specific naming schemes. So far, so good, but what about the OXP "Random Ship Names"? Luckily its "shipSpawned" function actually checks if the ship already has a name, but that would only be useful if my "shipSpawned" function is called first. In the other case, my OXP would have to rename a ship that already has been given a name. This would work of course, but it wouldn't be very elegant from a programmers perspective (and the name would be 'wasted', i.e. deleted from the name lists of Random Ship Names).
Never think about that, you'll just become a bitter ex-OXPer. If you're making a naming script for particular ships you use a ship-script, not a world-script, and it just works. Don't worry too much how it works. :D
"So anti-globalist, he's practically a flat-earther."
User avatar
phkb
Impressively Grand Sub-Admiral
Impressively Grand Sub-Admiral
Posts: 4657
Joined: Tue Jan 21, 2014 10:37 pm
Location: Writing more OXPs, because the world needs more OXPs.

Re: Scripters cove

Post by phkb »

Fritz wrote:
Is it "officially" recommended to supply a dummy script containing nothing else than this.name or would this create unnecessary overhead?
If you want to check if a particular ship is available you could do this:

Code: Select all

var shipdata = Ship.shipDataForKey("myship_data_key");
if (shipdata) {
    log(this.name, "Found it!");
}
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 »

Fritz wrote:
If there are two (or more) OXPs containing a "shipSpawned" function, let's say, one for naming the ship and one for adjusting other properties (weapons, equipment, textures), is there any way to control which of the functions is called first? Is the calling sequence determined by the installation order of the OXPs or by something else, or is it completely random?

I want to create an OXP defining "company freighters" having different textures and other properties. I also want these ships to have special names based on company-specific naming schemes. So far, so good, but what about the OXP "Random Ship Names"? Luckily its "shipSpawned" function actually checks if the ship already has a name, but that would only be useful if my "shipSpawned" function is called first. In the other case, my OXP would have to rename a ship that already has been given a name. This would work of course, but it wouldn't be very elegant from a programmers perspective (and the name would be 'wasted', i.e. deleted from the name lists of Random Ship Names).
Are you using your own shipdata? If so, use

Code: Select all

"script_info" =         {
    "randomshipnames" = "no";
};
to forbid randomshipnames from naming your ship. And as Wildeblood says, use a ship-script to name your ship.

If you're going to tap into "trader" ships created by core using shipSpawned event, you need to be extra careful as there are OXPs out there that let the core game create their ships as "trader" and then change the behavior of the ship by switching AIs. If you've got that covered (check randomshipnames as an example) and it's just randomshipnames you need to tackle with, you can create your own shipSpawned event, copy shipSpawned function from randomshipnames to a different name, delete shipSpawned function from randomshipnames and finally call the copied shipSpawned function in the end of your own shipSpawned function.
User avatar
Norby
---- E L I T E ----
---- E L I T E ----
Posts: 2577
Joined: Mon May 20, 2013 9:53 pm
Location: Budapest, Hungary (Mainly Agricultural Democracy, TL10)
Contact:

Re: Scripters cove

Post by Norby »

Anonymissimus wrote:
Why should it be random, that feels strange...normally things in software are not random
Oolite ask for the file list of AddOns folder from the opsystem without ordering, this cause different results depending on the used filesystem. I am using Linux and somebody said in another topic also that the order can change depending on the allocation of inodes which can be modified while you are working on the same box (like installing other programs) so suffer random changes from Oolite's viewpoint.
User avatar
Smivs
Retired Assassin
Retired Assassin
Posts: 8408
Joined: Tue Feb 09, 2010 11:31 am
Location: Lost in space
Contact:

Re: Scripters cove

Post by Smivs »

The current system, whilst apparently chaotic, does have one advantage.
If OXPs were loaded in a specific order, this would almost certainly be alphabetical. The potential exploit of this would be that unscrupulous authors would name their OXPs to gain advantage - The 'Aardvark OXP' would overide averything!
Commander Smivs, the friendliest Gourd this side of Riedquat.
Anonymissimus
---- E L I T E ----
---- E L I T E ----
Posts: 299
Joined: Mon Apr 27, 2015 9:03 pm

Re: Scripters cove

Post by Anonymissimus »

Smivs wrote:
The 'Aardvark OXP' would overide averything!
That should be a ZZ Top OXP, shouldn't it ?
warning sound if a missile is inbound: Missile warning
User avatar
Smivs
Retired Assassin
Retired Assassin
Posts: 8408
Joined: Tue Feb 09, 2010 11:31 am
Location: Lost in space
Contact:

Re: Scripters cove

Post by Smivs »

Haha, no, because it's first loaded takes priority.
Mind you a ZZ Top OXP sounds pretty good to me. :)
<Smivs wonders if a ship with a long beard would look too silly.>
Commander Smivs, the friendliest Gourd this side of Riedquat.
Fritz
---- E L I T E ----
---- E L I T E ----
Posts: 591
Joined: Sun Jul 12, 2015 2:30 pm
Location: Bavaria, Germany
Contact:

Re: Scripters cove

Post by Fritz »

Wildeblood wrote:
The one you are actually holding with the mouse pointer is copied first, that might be the first, last or one in the middle.
Are you sure? I'm quite sure that I usually hold the first file first. Perhaps my "problem" is that I use the cursor keys for marking further files. But it's not so important that I'll start a big testing project right now! :lol:
Wildeblood wrote:
If you're making a naming script for particular ships you use a ship-script, not a world-script, and it just works. Don't worry too much how it works. :D
spara wrote:
Are you using your own shipdata?
I have written a separate naming OXP (technically based on "Random Ship Names", but using other naming schemes). This was, apart from a little tinkering, my first OXP project (and the first time I wrote anything with JavaScript!). My version, like the original version, uses shipSpawned, so it's a world script. My current project uses shipSpawned too because it doesn't introduce new ships (so it has no shipdata) and only changes the looks and names of certain standard ships. It should be independent of any naming script, so I want to include the naming part there (and remove it from my naming OXP).
spara wrote:
If you're going to tap into "trader" ships created by core using shipSpawned event, you need to be extra careful as there are OXPs out there that let the core game create their ships as "trader" and then change the behavior of the ship by switching AIs. If you've got that covered (check randomshipnames as an example) and it's just randomshipnames you need to tackle with, you can create your own shipSpawned event, copy shipSpawned function from randomshipnames to a different name, delete shipSpawned function from randomshipnames and finally call the copied shipSpawned function in the end of your own shipSpawned function.
Hmm... I don't think I'm understanding this completely, but I'm just starting with OXPs and I am glad when they run on my computer! :D Technically, at least the first version of my OXP just changes the looks of the ships and gives them a name, so this shouldn't interfere with any AI changes, and the coexisting with my naming OXP already works (just by overwriting the random ship name). Also, my OXP would never affect non-core ships, simply because that would need new textures.

-----

Currently I'm only stuck at one rather crucial point: I can read the materials list with ship.getMaterials() and write it with ship.setMaterials(). But I haven't found out how I can change this list (only the png file names "oolite_xxxxx_diffuse.png" and "oolite_xxxxx_subents.png", the rest should remain unchanged). It would be easy if materialsList was a string, but it is some kind of object, and the wiki isn't very specific in how to deal with it (or I haven't found it yet).

So my code is like

Code: Select all

var materialList = ship.getMaterials(); 
// Replace texture file names
// ?????
ship.setMaterials(materialList);
"You wouldn't kill me just for a few credits, would you?" – "No, I'll do it just for the fun!"
User avatar
Smivs
Retired Assassin
Retired Assassin
Posts: 8408
Joined: Tue Feb 09, 2010 11:31 am
Location: Lost in space
Contact:

Re: Scripters cove

Post by Smivs »

setmaterials will change all the materials used for any given ship, so if you change the diffuse map, you also have to tell it to change the ships' other materials as well (emission, normal maps etc) otherwise it just ignores them. In other words if you have a simple material set (say just a diffuse and emission map) and change the diffuse map, the emission map will be removed on setMaterials. It needs to be specified in the setMaterials list if you want it to stay in place after setMaterials has done its stuff. You have to re-set it.
I recently had no end of fun with the Python Class Cruiser as this has three diffuse maps, so when I wanted to change something I had to set all three materials, each of which has three maps - diffuse, emission and a combined normal and specular map.
Got it working eventually 8)
Commander Smivs, the friendliest Gourd this side of Riedquat.
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 »

Fritz wrote:
spara wrote:
If you're going to tap into "trader" ships created by core using shipSpawned event, you need to be extra careful as there are OXPs out there that let the core game create their ships as "trader" and then change the behavior of the ship by switching AIs. If you've got that covered (check randomshipnames as an example) and it's just randomshipnames you need to tackle with, you can create your own shipSpawned event, copy shipSpawned function from randomshipnames to a different name, delete shipSpawned function from randomshipnames and finally call the copied shipSpawned function in the end of your own shipSpawned function.
Hmm... I don't think I'm understanding this completely...
In your startUpComplete() do something like:

Code: Select all

worldScripts["randomshipnames"]._fritzShipSpawned = worldScripts["randomshipnames"].shipSpawned;
delete worldScripts["randomshipnames"].shipSpawned;
And in you shipSpawned(ship) do

Code: Select all

worldScripts["randomshipnames"]._fritzShipSpawned(ship)
Totally untested, but should clarify the idea.
Fritz
---- E L I T E ----
---- E L I T E ----
Posts: 591
Joined: Sun Jul 12, 2015 2:30 pm
Location: Bavaria, Germany
Contact:

Re: Scripters cove

Post by Fritz »

Sorry, no, I don't even know what you are trying to do or what problem you are trying to solve. :oops: I don't want to combine two OXPs, and my OXP should work even if no naming OXP is installed (I suppose there are more than one of them). In this case, only "my" ships would have names. The only problem I had with this was more of a theoretical nature, that I'm kind of wasting cpu time for renaming a ship that already has been named by another OXP. Ignoring this, it just works fine (apart from the texture changing part).
"You wouldn't kill me just for a few credits, would you?" – "No, I'll do it just for the fun!"
Fritz
---- E L I T E ----
---- E L I T E ----
Posts: 591
Joined: Sun Jul 12, 2015 2:30 pm
Location: Bavaria, Germany
Contact:

Re: Scripters cove

Post by Fritz »

Smivs wrote:
setmaterials will change all the materials used for any given ship, so if you change the diffuse map, you also have to tell it to change the ships' other materials as well (emission, normal maps etc) otherwise it just ignores them. In other words if you have a simple material set (say just a diffuse and emission map) and change the diffuse map, the emission map will be removed on setMaterials. It needs to be specified in the setMaterials list if you want it to stay in place after setMaterials has done its stuff. You have to re-set it.
I recently had no end of fun with the Python Class Cruiser as this has three diffuse maps, so when I wanted to change something I had to set all three materials, each of which has three maps - diffuse, emission and a combined normal and specular map.
Hmm. That's what I intuitively expected, and that's why I try to read the complete set, change it, and rewrite it. But I don't know how to address the different parts (or sub-objects), and part of my problem is probably that the JavaScript syntax for defining the object (or list) is new to me.

So far I've only seen one example doing something like this, the Station Ads OXP, and there it says

Code: Select all

 ... .setMaterials({"yah_griff_no_shader_screen.png": {diffuse_map: newAd, emission_map: newAd}});
where newAd is a string containing the new texture file name. The shipdata is quite simple in this case:

Code: Select all

materials = {
			"yah_griff_no_shader_screen.png" = {
				diffuse_map = "station_ads_dock_frame.png";
			};
		};
"yah_griff_no_shader_screen.png" is, as I understand it, not a filename but kind of a key, corresponding to "Hull" and "Engines" in the core shipdata.plist. But in this case, there aren't any properties that remain unchanged, so it isn't necessary to read the material list before changing it.

So my thinking is that I have to read the existing material list with ship.getMaterials(), store it in a object variable, then change the parts of the object I need to change, and then rewrite the complete object with ship.setMaterials(). But how is the syntax for making these changes?

Another solution would be to hard-code the parts that remain unchanged. But why is there something like getMaterials() if it can't be used?
"You wouldn't kill me just for a few credits, would you?" – "No, I'll do it just for the fun!"
Post Reply