Page 5 of 8
Re: Random Station Names OXP (Development Thread)
Posted: Mon Jun 07, 2021 10:54 pm
by phkb
LittleBear wrote: ↑Mon Jun 07, 2021 8:41 pm
Is there a way to tweak this function from another OXP?
The technique is called "monkey patching" and should be used with extreme caution.
Compressed F7 Layout probably isn't the best example to use in this case - it's turning off an internal function of Distant Stars so a slightly adjusted version can be run using a completely different method. A better example is, say, in Station Dock Control, in the "systemWillRepopulate" function (see file stationdockcontrol.js, around line 655), where I'm looking for stations that have a script with the "otherShipDocked" function in play. What I then do is:
1. Save the original script into a new location (in this example, to "station.script.$sdc_hold_otherShipDocked")
2. Give the station script a new "otherShipDocked" function, which will call the original script I saved in step 1, and then do any additional work I need done.
That keeps the integrity of the original author, and allows new code to be applied.
The "$" symbol is not important. It's purely my way of prefixing a function. Other coders use "_" as the prefix. Having a prefix like this ensures there is no chance of accidentally interfering with a core worldScript function.
The difficulty we run into with monkey patching is where you have multiple script using this technique on the same entry points - it can become a mess of spaghetti code that is a nightmare to unravel. So, the technique is available, and can work wonders, but use with caution. If there's another solution that can avoid this technique, it's better to pursue that one, if possible. For instance, working with the authors of the original OXP's to incorporate some changes to work with your OXP. If the author's are no longer around, there might be someone willing to take on maintenance of the OXP in order to implement the change.
If there's no opportunity to get the original OXP updated, then there may be no option but to use this technique, but hopefully this will provide some clarity on the dangers involved.
Re: Random Station Names OXP (Development Thread)
Posted: Tue Jun 08, 2021 12:26 pm
by LittleBear
Thanks. That seems complex and as I've got this far into the OXP without having to change the code from any other OXP I don't really want to start now.
Would you mind adding this code to your Compressed F7 screen OXZ under the this.$starInfo function?
Code: Select all
if (missionVariables.random_station_names_stars === "On") {
if (galaxyNumber === 0) var starGrid = Math.floor(player.ship.targetSystem+0);
if (galaxyNumber === 1) var starGrid = Math.floor(player.ship.targetSystem+256);
if (galaxyNumber === 2) var starGrid = Math.floor(player.ship.targetSystem+512);
if (galaxyNumber === 3) var starGrid = Math.floor(player.ship.targetSystem+768);
if (galaxyNumber === 4) var starGrid = Math.floor(player.ship.targetSystem+1024);
if (galaxyNumber === 5) var starGrid = Math.floor(player.ship.targetSystem+1280);
if (galaxyNumber === 6) var starGrid = Math.floor(player.ship.targetSystem+1536);
if (galaxyNumber === 7) var starGrid = Math.floor(player.ship.targetSystem+1792);
var sunName = ""+starpool[starGrid&2047];
}
I can then do a check in my OXP to see if the Compressed F7 Screen OXZ is installed. If it is then my OXP will do nothing with the F7 screen.
To avoid having to overwrite anything or store anything in the player's save file (apart from the mission variables for the Options settings), all the names used in Random Station names are stored in arrays of 2,048 in the script file. The OXP loads the names for the system the player is currently in and for stations adds the name to the display name and for stars, planets or moons changes the display name to the Random Station Names one if the naming option is on and the Object is not already named by another OXP. This way, it is a clean uninstall as if removed (or turned off in Options) all names return to normal as I haven't changed the unique name of anything in the game, just the display name shown on the ASC, ID computer and the Almanac Screen. Once removed the code to change the display name is no longer present and so my OXP makes no permenant changes to any other OXP.
Re: Random Station Names OXP (Development Thread)
Posted: Tue Jun 08, 2021 9:02 pm
by hiran
LittleBear wrote: ↑Tue Jun 08, 2021 12:26 pm
I can then do a check in my OXP to see if the Compressed F7 Screen OXZ is installed. If it is then my OXP will do nothing with the F7 screen.
Sounds feasible for exactly the combination of these two OXPs, and any other 'screen adding OXP' is still incompatible.
Would it make sense to somehow 'register' screens, and Oolite or the player would simply assign numbers? After all F7 is not the only function key available. At least my keyboard also has F8, F9, F10, F11 and F12 which is pretty standard.
Such a mechanism would allow users to install multiple screen adding OXPs and then to choose the preferred way of utilizing them.
Re: Random Station Names OXP (Development Thread)
Posted: Tue Jun 08, 2021 11:24 pm
by phkb
hiran wrote: ↑Tue Jun 08, 2021 9:02 pm
Would it make sense to somehow 'register' screens, and Oolite or the player would simply assign numbers? After all F7 is not the only function key available. At least my keyboard also has F8, F9, F10, F11 and F12 which is pretty standard.
That would be venturing into the whole keyboard configuration/layout issue, which would need a whole other thread.
The Compressed F7 screen OXZ makes use of features added to Oolite to allow all the space on that screen (and that screen only) to be accessed in a particular way. This is less to do with the key you press to get to the screen, and more to do with the layout of what is seen on that screen.
Re: Random Station Names OXP (Development Thread)
Posted: Tue Jun 08, 2021 11:50 pm
by phkb
LittleBear wrote: ↑Tue Jun 08, 2021 12:26 pm
Would you mind adding this code to your Compressed F7 screen OXZ under the this.$starInfo function?
Can do. Quick question:
Is there are reason for the blank string before the
starpool
variable?
Re: Random Station Names OXP (Development Thread)
Posted: Wed Jun 09, 2021 1:12 am
by LittleBear
Don't think its needed. In some parts of the OXZ this has words in front of it, so I'd got into the habit of C&Ping a blank line with "" so I could fill it in when needed. Should also really do a check as well that the Random Station Names Script is running. If Random Station Names had been installed but then removed, the mission variable would still be in the player's save file but without the OXZ still installed starpool would be undefined and so the name would appear as Undefined on the F7 Screen. Tested it with the script test added.
Whole function (tested) would be:-
Code: Select all
//-------------------------------------------------------------------------------------------------------------
// slightly modified from Distant Sun's original code
this.$starInfo = function(sysID) {
var info = System.infoForSystem(galaxyNumber, sysID);
if (info.sun_gone_nova) return "";
var name = info.name;
var sunName = info.sun_name;
var colour = info.sun_color;
if (colour) var colourText = worldScripts.Stars.$spectroscope(colour);
var text = "";
if (missionVariables.random_station_names_stars === "On" && worldScripts.RandomStationNames) {
if (galaxyNumber === 0) var starGrid = Math.floor(player.ship.targetSystem+0);
if (galaxyNumber === 1) var starGrid = Math.floor(player.ship.targetSystem+256);
if (galaxyNumber === 2) var starGrid = Math.floor(player.ship.targetSystem+512);
if (galaxyNumber === 3) var starGrid = Math.floor(player.ship.targetSystem+768);
if (galaxyNumber === 4) var starGrid = Math.floor(player.ship.targetSystem+1024);
if (galaxyNumber === 5) var starGrid = Math.floor(player.ship.targetSystem+1280);
if (galaxyNumber === 6) var starGrid = Math.floor(player.ship.targetSystem+1536);
if (galaxyNumber === 7) var starGrid = Math.floor(player.ship.targetSystem+1792);
var sunName = starpool[starGrid&2047];
}
if (colourText && sunName) text += "" + name + " orbits the " + colourText + " " + sunName + ".";
else if (colourText) text += "" + name + " orbits a " + colourText + ".";
else if (sunName) text += "" + name + " orbits the star " + sunName + ".";
return text;
}
F7 Screen with Compressed F7, Distant Suns and Random Station Names installed (Name Stars Option turned On) - Name from Random Station Names used.
F7 Screen with Compressed F7, Distant Suns and Random Station Names installed (Name Stars Option turned Off). - Name from Distant Suns used.
BTW. Is it possible to move the description text up? There is room for it and with famous planets installed the text normally runs off the bottom of the screen.
Re: Random Station Names OXP (Development Thread)
Posted: Wed Jun 09, 2021 1:32 am
by phkb
Small code tweak, to avoid all those IF statements:
Code: Select all
var starGrid = Math.floor(player.ship.targetSystem+(256 * galaxyNumber));
That should give you the same result I think.
LittleBear wrote: ↑Wed Jun 09, 2021 1:12 am
Is it possible to move the description text up?
Hmm. Not sure, but I don't think so. Because the length of the description is variable, as is the width of the font in use, getting the description into the upper section would require quite a bit of fiddling (working out line lengths, splitting etc). And then it may not be possible to remove the description from the bottom part of the screen anyway.
Re: Random Station Names OXP (Development Thread)
Posted: Wed Jun 09, 2021 1:37 am
by phkb
Another question: where is
starpool
defined? It's not local to the Compressed F7 layout OXP, so I assume it must be your Station Names OXP. But in that case, it should have a worldScript reference, kind of like:
Code: Select all
worldScripts.RandomStationNames.starpool[starGrid&2047];
Re: Random Station Names OXP (Development Thread)
Posted: Wed Jun 09, 2021 6:06 am
by hiran
phkb wrote: ↑Tue Jun 08, 2021 11:24 pm
hiran wrote: ↑Tue Jun 08, 2021 9:02 pm
Would it make sense to somehow 'register' screens, and Oolite or the player would simply assign numbers? After all F7 is not the only function key available. At least my keyboard also has F8, F9, F10, F11 and F12 which is pretty standard.
That would be venturing into the whole keyboard configuration/layout issue, which would need a whole other thread.
The Compressed F7 screen OXZ makes use of features added to Oolite to allow all the space on that screen (and that screen only) to be accessed in a particular way. This is less to do with the key you press to get to the screen, and more to do with the layout of what is seen on that screen.
Oh I see. Then maybe it could be interesting for future versions to allow multiple expansions contribute code to a single screen?
Sounds like Portal functionality in web applications. An exciting topic.
Re: Random Station Names OXP (Development Thread)
Posted: Wed Jun 09, 2021 1:35 pm
by LittleBear
The pools used by the OXP are all stored in the randomstationnames.js script file in Scripts. Basically this OXP is one masssive Script file storing about 200,000 names and a great big Descriptions file that was used to procedurally generate the names. All the names are stored in var arrays like this:-
Code: Select all
"use strict";
this.name = "RandomStationNames";
this.author = "LittleBear";
this.copyright = "This script is hereby placed in the public domain.";
this.description = "World Script for Random Station Names OXP";
this.version = "1.00";
this.licence = "CC BY-NC-SA 4.0";
var main = ["Hand of Glory", "Technological Magic", "Petrified Cockatrice", "and so on with 2,048 names for Main stations", }
var starpool = ["Civitas Temulentus", "Apus Candidus", "Rotanev Auriolus", "and so on with 2,048 names for stars",]
Different arrays are used for different types of stations, planets, moons and stars. For planets, moons and stations where more than one station is present in the same system multiple pools are used with a loop to count off the number of that type of object in the system. I do a count up objects loop with a for i = -1 to number of objects. The first opject is named by the name at position 0 in its array, second by the name at position 1 and so on. As each object is named by systemID + i so each object in the system gets a unique name that stays consitant.
For Stars and Main Stations where there is just one per system I just read the array by system.ID so the Main Station / star at Galaxy 1 Planet 0 is named "Hand of Glory", / "Civitas Temulentus" Galaxy 1 Planet 1 is "Technological Magic" / "Apus Candidus" and so on. The Star Pool works in the same way. I tested with Compressed F7 running as an extrated OXP and it worked although the starpool variable is defined in Random Station Names Script.
Re: Random Station Names OXP (Development Thread)
Posted: Sat Jun 12, 2021 4:46 am
by phkb
OK, here's version 1.3 for you to try:
CompressedF7Layout.oxz. Have a go with this, and if everything is working as expected, I'll upload it to the manager.
Re: Random Station Names OXP (Development Thread)
Posted: Sun Jun 13, 2021 11:28 am
by LittleBear
Tried that version. It didn't display the Random Station Names version only the Distrant Stars one. Sorry, I don't know how to extract it to look at the code. But below (in full) is the script I've been running which worked to add the Distant Stars version if installed and Random Station Names Star Naming feature turned off and the Random Station Names version if installed and Random Station Names Naming option turned on.
As a C&P this is the Compressed f7 Screen script with the change I made to detect the Random Station names name:-
Code: Select all
"use strict";
this.name = "CompressedF7Layout";
this.author = "phkb";
this.copyright = "2017 phkb";
this.description = "Moves all standard F7 data to the top of the screen, leaving no blank lines between data elements, including details from 'Distant Suns' and 'Explorers Club', if installed.";
this.licence = "CC BY-NC-SA 4.0";
//-------------------------------------------------------------------------------------------------------------
this.startUpComplete = function() {
var sd = worldScripts["oolite-system-data-config"];
sd.setSystemDataLine(1, "[sysdata-eco]\t[economy_desc]", "system");
sd.setSystemDataLine(2, "[sysdata-govt]\t[government_desc]", "system");
sd.setSystemDataLine(3, "[sysdata-tl]\t[sysdata-tl-value]", "system");
sd.setSystemDataLine(4, "[sysdata-pop]\t[sysdata-pop-value]", "system");
sd.setSystemDataLine(5, "\t([inhabitants])", "system");
sd.setSystemDataLine(6, "[sysdata-prod]\t\t[sysdata-prod-value]", "system");
sd.setSystemDataLine(7, "[sysdata-radius]\t\t[sysdata-radius-value]", "system");
sd.setSystemDataLine(8, "[sysdata-distance]\t[distanceInfo]", "system");
sd.resetSystemDataLine(9);
sd.resetSystemDataLine(10);
sd.resetSystemDataLine(11);
sd.resetSystemDataLine(12);
sd.resetSystemDataLine(13);
sd.resetSystemDataLine(14);
sd.resetSystemDataLine(15);
sd.resetSystemDataLine(16);
if (worldScripts.Stars) {
// we're overriding distant Sun's guiScreenChanged so it doesn't add text to the bottom part of the F7 screen
worldScripts.Stars.$overrideGUI = worldScripts.Stars.guiScreenChanged;
delete worldScripts.Stars.guiScreenChanged;
// instead, we'll add a callback to do the update
sd.addChangeCallback(this.name, "$stars_updateData");
}
if (worldScripts["Explorers Club"]) {
// we're overriding EC's guiScreenChanged so we can capture and ignore any change to GUI_SCREEN_SYSTEM_DATA
worldScripts["Explorers Club"].$ovr_guiScreenChanged = worldScripts["Explorers Club"].guiScreenChanged;
delete worldScripts["Explorers Club"].guiScreenChanged;
// we'll also add a callback to do the update
sd.addChangeCallback(this.name, "$explorersClub_updateData");
}
}
//-------------------------------------------------------------------------------------------------------------
this.guiScreenChanged = function(to, from) {
// for anything other than GUI_SCREEN_SYSTEM_DATA fire EC's original guiScreenChanged event
if (guiScreen !== "GUI_SCREEN_SYSTEM_DATA" && worldScripts["Explorers Club"]) worldScripts["Explorers Club"].$ovr_guiScreenChanged(to, from);
}
//-------------------------------------------------------------------------------------------------------------
this.$explorersClub_updateData = function(ctype, to, from) {
var ec = worldScripts["Explorers Club"];
var sd = worldScripts["oolite-system-data-config"];
// find the first free slot (or the one we're currently using)
for (var i = 1; i <= 16; i++) {
if (sd.systemDataLineOwner(i) === "" || sd.systemDataLineOwner(i) === "explorers_club") {
// found it! now work out what system we're looking at
var sysID = -1;
if (ctype === "guiScreenWillChange") {
// for this event, we need to check out the infoSystem or targetSystem of the player ship
var sysID = player.ship.targetSystem;
if (player.ship.hasOwnProperty("infoSystem")) sysID = player.ship.infoSystem;
} else {
// for an infoSystemWillChange, the "to" property has the value we need
sysID = to;
}
// make sure we have a valid system ID
if (isNaN(sysID) === false && sysID >=0 && sysID <= 255) {
// extract the correct text from missionText
var text = "";
if (ec.$xc_record[galaxyNumber].indexOf(sysID) === -1) {
text = expandMissionText("explorers_club_never_visited");
} else if (player.ship.targetSystem === system.ID) {
text = expandMissionText("explorers_club_here_now");
} else {
text = expandMissionText("explorers_club_already_visited");
}
// and update the data line
sd.setSystemDataLine(i, text, "explorers_club");
} else {
// if we have an invalid system ID, reset the line
if (sd.systemDataLineOwner(i) === "explorers_club") sd.resetSystemDataLine(i);
}
break;
}
}
}
//-------------------------------------------------------------------------------------------------------------
this.$stars_updateData = function(ctype, to, from) {
var sd = worldScripts["oolite-system-data-config"];
// find the first free slot (or the one we're currently using)
for (var i = 1; i <= 16; i++) {
if (sd.systemDataLineOwner(i) === "" || sd.systemDataLineOwner(i) === "stars") {
// found it! now work out what system we're looking at
var sysID = -1;
if (ctype === "guiScreenWillChange") {
// for this event, we need to check out the infoSystem or targetSystem of the player ship
var sysID = player.ship.targetSystem;
if (player.ship.hasOwnProperty("infoSystem")) sysID = player.ship.infoSystem;
} else {
// for an infoSystemWillChange, the "to" property has the value we need
sysID = to;
}
// make sure we have a valid system ID
if (isNaN(sysID) === false && sysID >=0 && sysID <= 255) {
// and update the data line
sd.setSystemDataLine(i, this.$starInfo(sysID), "stars");
} else {
// if we have an invalid system ID, reset the line
if (sd.systemDataLineOwner(i) === "stars") sd.resetSystemDataLine(i);
}
break;
}
}
}
//-------------------------------------------------------------------------------------------------------------
// slightly modified from Distant Sun's original code
this.$starInfo = function(sysID) {
var info = System.infoForSystem(galaxyNumber, sysID);
if (info.sun_gone_nova) return "";
var name = info.name;
var sunName = info.sun_name;
var colour = info.sun_color;
if (colour) var colourText = worldScripts.Stars.$spectroscope(colour);
var text = "";
if (missionVariables.random_station_names_stars === "On" && worldScripts.RandomStationNames) {
if (galaxyNumber === 0) var starGrid = Math.floor(player.ship.targetSystem+0);
if (galaxyNumber === 1) var starGrid = Math.floor(player.ship.targetSystem+256);
if (galaxyNumber === 2) var starGrid = Math.floor(player.ship.targetSystem+512);
if (galaxyNumber === 3) var starGrid = Math.floor(player.ship.targetSystem+768);
if (galaxyNumber === 4) var starGrid = Math.floor(player.ship.targetSystem+1024);
if (galaxyNumber === 5) var starGrid = Math.floor(player.ship.targetSystem+1280);
if (galaxyNumber === 6) var starGrid = Math.floor(player.ship.targetSystem+1536);
if (galaxyNumber === 7) var starGrid = Math.floor(player.ship.targetSystem+1792);
var sunName = starpool[starGrid&2047];
}
if (colourText && sunName) text += "" + name + " orbits the " + colourText + " " + sunName + ".";
else if (colourText) text += "" + name + " orbits a " + colourText + ".";
else if (sunName) text += "" + name + " orbits the star " + sunName + ".";
return text;
}
Added naming to Planet Fall's Landing Sites. Each has a name depending on the type of place it is. When making a rough landing you also get a short description of your Landing Site. Almanac Screen now shows that you have Landed and where you have Landed. Also now shows the type of star if distant suns is installed. If not installed then stars are just descriped as "Star".
Touched Down on the surface of a Moon. Facilities at the GalCop Penal Colony were rather basic:
Much Better services offed on the surface of an OXP Planet:-
Landed at the Capital City of the Main Planet
Re: Random Station Names OXP (Development Thread)
Posted: Sun Jun 13, 2021 12:26 pm
by Cholmondely
My goodness!
How utterly superb...
Thank you for going to all this trouble. I am really looking forwards to this one!
Re: Random Station Names OXP (Development Thread)
Posted: Sun Jun 13, 2021 1:54 pm
by montana05
I do agree with Cholmondely, it will certainly be a must for me once it's finished.
Re: Random Station Names OXP (Development Thread)
Posted: Sun Jun 13, 2021 2:17 pm
by phkb
LittleBear wrote: ↑Sun Jun 13, 2021 11:28 am
Tried that version. It didn't display the Random Station Names version only the Distrant Stars one.
I think the reason this version didn't work is that I overlooked the fact that you've put the
starpool
and
main
arrays into the global namespace. This is generally considered to be a bad programming practice and should be (at best) eliminated where possible, or at the very least, minimised as much as possible if there is no other way around it.
In your code, where you've defined these two arrays:
Code: Select all
var main = ["Hand of Glory", "Technological Magic", "Petrified Cockatrice", "and so on with 2,048 names for Main stations", }
var starpool = ["Civitas Temulentus", "Apus Candidus", "Rotanev Auriolus", "and so on with 2,048 names for stars",]
You should change the declarations to be:
Code: Select all
this.main = ["Hand of Glory", "Technological Magic", "Petrified Cockatrice", "and so on with 2,048 names for Main stations", }
this.starpool = ["Civitas Temulentus", "Apus Candidus", "Rotanev Auriolus", "and so on with 2,048 names for stars",]
For any code in your main script, this should make no difference. If you have additional script files that reference these variables, you'll need to change the references to include a prefix of
worldScripts.RandomStationNames.
For example, change something like this
to this
Code: Select all
var temp = worldScripts.RandomStationNames.starpool[123];
With that change, the version of Compressed F7 Layout I released should work.