| Scripts/system_map.js |
"use strict";
this.name = "Lib_SystemMap";
this.author = "phkb";
this.copyright = "2026 phkb";
this.description = "Adds a system map, accessible from the F7 screen.";
this.licence = "CC BY-NC-SA 4.0";
this._exitScreen = "GUI_SCREEN_SYSTEM_DATA";
this._custom = [];
this._hint = false;
this._distanceUnits = ["[systemmap_distance_ou]", "[systemmap_distance_km]", "[systemmap_distance_m]", "[systemmap_distance_cz]"];
this._unitSelected = 1;
this._libSettings = {
Name: this.name,
Display: expandDescription("[systemmap_display]"),
Alias: expandDescription("[systemmap_alias]"),
Alive: "_libSettings",
SInt: {
S0: { Name: "_unitSelected", Def: 1, Min: 0, Max: 3, Desc: expandDescription("[systemmap_units]") },
Info: expandDescription("[systemmap_sint_info]")
},
};
//-------------------------------------------------------------------------------------------------------------
this.$addCustomMarker = function (obj) {
if (!obj.ent && !obj.pos) {
log(this.name, "No entity (obj.ent) or position (obj.pos) specified. Unable to add marker.");
return;
}
if (!obj.map || obj.map == "") obj.map = "map_station.png";
if (obj.hasOwnProperty("col") && isNaN(obj.col)) {
log(this.name, "Invalid color (obj.col) value. Must be an integer between 0 and 12.");
return;
}
obj._updated = false;
if (obj.hasOwnProperty("displayName")) {
obj._orig_displayName = obj.displayName;
obj._updated = true;
}
this._custom.push(obj);
}
//-------------------------------------------------------------------------------------------------------------
this.startUpComplete = function () {
if (oolite.compareVersion("1.91") <= 0) {
setExtraGuiScreenKeys(this.name, {
guiScreen: "GUI_SCREEN_SYSTEM_DATA",
registerKeys: { "systemkey": [{ key: "s" }] },
callback: this.$localSystemMap.bind(this)
});
if (worldScripts.ContextualHelp) {
worldScripts.ContextualHelp.$addHelpTextToGuiScreen(this.name, "GUI_SCREEN_SYSTEM_DATA", "\n" + expandDescription("[systemmap_helper]"));
}
} else {
this.$initInterface(player.ship.dockedStation);
this._exitScreen = "GUI_SCREEN_INTERFACES";
}
if (missionVariables.SystemMap_Units) this._unitSelected = parseInt(missionVariables.SystemMap_Units);
// register our settings
worldScripts.Lib_Config._registerSet(this._libSettings);
// if the tianve pulsar isn't installed, delete the function that would otherwise run every jump
if (!worldScripts["oolite-tianve"]) {
delete this.shipExitedWitchspace;
}
}
//-------------------------------------------------------------------------------------------------------------
this.playerWillSaveGame = function () {
missionVariables.SystemMap_Units = this._unitSelected;
}
//-------------------------------------------------------------------------------------------------------------
this.shipWillEnterWitchspace = function () {
this._custom.length = 0;
}
//-------------------------------------------------------------------------------------------------------------
this.shipExitedWitchspace = function () {
// add in the tianve pulsar, if installed
if (galaxyNumber == 0 && system.ID == 246 && worldScripts["oolite-tianve"]) {
var ve = system.allVisualEffects;
for (var i = 0; i < ve.length; i++) {
if (ve[i].dataKey == "tianve_pulsar_flashers") {
this.$addCustomMarker({ map: "lib_starmap_i8.png", pos: ve[i].position, col: 6, displayName: expandDescription("[systemmap_pulsar]") + this.$getDistance(ve[i].position) });
break;
}
}
}
}
//-------------------------------------------------------------------------------------------------------------
this.shipDockedWithStation = function (station) {
if (oolite.compareVersion("1.91") > 0) {
this.$initInterface(station);
}
}
//-------------------------------------------------------------------------------------------------------------
this.guiScreenChanged = function (to, from) {
if (guiScreen == "GUI_SCREEN_SYSTEM_DATA" && oolite.compareVersion("1.91") <= 0 && !this._hint) {
this._hint = true;
player.consoleMessage(expandDescription("[systemmap_helper]"))
}
}
//-------------------------------------------------------------------------------------------------------------
this.$initInterface = function $initInterface(station) {
station.setInterface(this.name, {
title: expandDescription("[systemmap_title]"),
category: expandDescription("[systemmap_category]"),
summary: expandDescription("[systemmap_summary]"),
callback: this.$localSystemMap.bind(this)
});
}
//-------------------------------------------------------------------------------------------------------------
this.$localSystemMap = function () {
var p = player.ship;
if (!p.docked) return; // only while docked
if (system.isInterstellarSpace) {
// inform player you can't access screen in interstellar space
mission.runScreen({
title: expandDescription("[systemmap_title]"),
message: expandDescription("[systemmap_interstellar]"),
exitScreen: this._exitScreen
});
return;
}
// make sure the planetary compass names have been run.
if (worldScripts["planetaryCompass_worldScript.js"]) {
worldScripts["planetaryCompass_worldScript.js"].$setUpNames();
}
// if xenon installed and active, pick the appropriate background
var xenon = null;
if (worldScripts.XenonUI) {
var found = true;
var lib = worldScripts.Lib_GUI;
if (lib.$cur != "XenonUI") found = false;
if (found) {
var xui = worldScripts.XenonUI;
xenon = { name: "xenon_" + xui._ratio + (xui._amber ? "_amber" : "") + ".png", height: 546 };
}
}
var stn_found = false;
if (p.docked && p.dockedStation.isMainStation) stn_found = true;
// create array and add the sun
var name = "";
//if (system)
var sini = [{ map: "lib_starmap_0.png", ent: system.sun, col: 12, displayName: this.$getName(system.sun) + this.$getDistance(system.sun.position) }];
// add in the witchpoint
var wp = system.shipsWithRole("buoy-witchpoint")[0];
if (wp) {
sini.push({ map: "lib_starmap_2.png", ent: wp, displayName: expandDescription("[systemmap_witchpoint]") + this.$getDistance(wp.position) });
}
// add in the players location
if (p.docked && p.dockedStation.hasRole("planetFall2_surface")) {
sini.push({ map: "map_point.png", pos: p.dockedStation.linkedVE.position, col: 1, displayName: expandDescription("[systemmap_yourlocation]") });
} else {
sini.push({ map: "map_point.png", ent: p, col: 1, displayName: expandDescription("[systemmap_yourlocation]") })
}
// add the main planet
var pf = this.$planetHasLandingSpots(system.mainPlanet);
if (system.mainPlanet.isGasGiant || system.mainPlanet.solarGasGiant) {
sini.push({ map: "map_planet_1.png", ent: system.mainPlanet, col: 4, displayName: this.$getName(system.mainPlanet) + this.$getDistance(system.mainPlanet.position) });
} else {
sini.push({ map: "map_planet_" + (pf ? "pf" : "") + "1.png", ent: system.mainPlanet, col: 2, displayName: this.$getName(system.mainPlanet) + this.$getDistance(system.mainPlanet.position) });
}
// add all the planets and moons (except for the main planet)
function plfn(entity) { return entity.isPlanet && !entity.isMainPlanet; }
var pl = system.filteredEntities(this, plfn, system.sun);
var p_count = 2;
for (var i = 0; i < pl.length; i++) {
pf = this.$planetHasLandingSpots(pl[i]);
if (!pl[i].hasAtmosphere) {
sini.push({ map: "map_moon" + (pf ? "_pf" : "") + ".png", ent: pl[i], col: 10, displayName: this.$getName(pl[i]) + this.$getDistance(pl[i].position) });
} else {
if (p_count > 9) {
if (pl[i].solarGasGiant || pl[i].isGasGiant) {
sini.push({ map: "map_planet.png", ent: pl[i], col: 4, displayName: this.$getName(pl[i]) + this.$getDistance(pl[i].position) });
} else {
sini.push({ map: "map_planet" + (pf ? "_pf" : "") + ".png", ent: pl[i], col: 2, displayName: this.$getName(pl[i]) + this.$getDistance(pl[i].position) });
}
} else {
if (pl[i].solarGasGiant || pl[i].isGasGiant) {
sini.push({ map: "map_planet_" + p_count + ".png", ent: pl[i], col: 4, displayName: this.$getName(pl[i]) + this.$getDistance(pl[i].position) });
} else {
sini.push({ map: "map_planet_" + (pf ? "pf" : "") + p_count + ".png", ent: pl[i], col: 2, displayName: this.$getName(pl[i]) + this.$getDistance(pl[i].position) });
}
}
p_count += 1;
}
}
// add the main station
sini.push({ map: "map_station.png", ent: system.mainStation, col: 3, displayName: this.$getName(system.mainStation) + this.$getDistance(system.mainStation.position) });
// add all the main stations (except for the actual main station)
function stfn(entity) {
return entity.isShip &&
entity.hasNPCTraffic && // only stations with traffic
(entity.scanClass != "CLASS_ROCK" || entity.beaconCode != null) && // only rock hermits with a beacon
(["hunter", "neutral", "private"].indexOf(entity.allegiance) == -1 || entity.beaconCode != null) && // only hunter/neutral/private stations with a beacon
!entity.hasRole("planetFall2_surface") && // not planetfall locations
!entity.isMainStation && // not the main station
entity.maxSpeed == 0; // must not be moving
}
var stns = system.filteredEntities(this, stfn, system.mainPlanet);
for (var i = 0; i < stns.length; i++) {
if (p.docked && stns[i] == p.dockedStation) stn_found = true;
sini.push({ map: "map_station.png", ent: stns[i], displayName: this.$getName(stns[i]) + this.$getDistance(stns[i].position) });
}
// make sure the players current station is on the map.
if (stn_found == false) {
if (p.docked && !p.dockedStation.hasRole("planetFall2_surface")) {
sini.push({ map: "map_station.png", ent: p.dockedStation, col: 5, displayName: this.$getName(p.dockedStation) });
}
}
// add any custom items
if (this._custom.length > 0) {
for (var i = 0; i < this._custom.length; i++) {
var pos = p.position;
if (this._custom[i].hasOwnProperty("ent")) pos = this._custom[i].ent.position;
if (this._custom[i].hasOwnProperty("pos")) pos = this._custom[i].pos;
if (this._custom[i]._updated == false) {
this._custom[i].displayName = this.$getName(this._custom[i].ent) + this.$getDistance(pos);
} else {
this._custom[i].displayName = this._custom[i]._orig_displayName + this.$getDistance(pos);
}
sini.push(this._custom[i]);
}
}
worldScripts.Lib_Starmap._start({
ini: sini,
title: expandDescription("[systemmap_screen_title]"),
exit: this._exitScreen,
viewControls: true,
background: xenon,
exitText: expandDescription("[systemmap_close]")
});
}
//-------------------------------------------------------------------------------------------------------------
this.$getDistance = function (pos) {
var dist = player.ship.position.distanceTo(pos);
if (Math.round(dist) == 0) return "";
return expandDescription(this._distanceUnits[this._unitSelected], { dist: dist });
}
//-------------------------------------------------------------------------------------------------------------
this.$getName = function (entity) {
if (entity.isPlanet && !entity.isMainPlanet) {
var beacon = this.$checkForBeacon(entity);
if (beacon && beacon.beaconLabel && beacon.beaconLabel != "") {
return beacon.beaconLabel;
}
}
if (entity.displayName && entity.displayName != "") {
return entity.displayName;
} else if (entity.name && entity.name != "") {
return entity.name;
}
return "";
}
//-------------------------------------------------------------------------------------------------------------
this.$checkForBeacon = function (entity) {
var beacons = this.$findEntitiesWithBeacons(entity);
if (beacons.length == 0) return null;
return beacons[0];
}
//-------------------------------------------------------------------------------------------------------------
this.$findEntitiesWithBeacons = function (entity) {
function _beacons(ent) {
return !(ent.isPlayer) &&
(ent.beaconCode != "" && ent.beaconCode != null) &&
(ent.displayName != "Jump Marker") &&
(ent.AI != "EscortDeck_AI.plist");
}
return system.filteredEntities(this, _beacons, entity, 1000);
}
//-------------------------------------------------------------------------------------------------------------
this.$planetHasLandingSpots = function (planet) {
if (!worldScripts.PlanetFall2 && !worldScripts.PlanetFall) return false;
if (worldScripts.PlanetFall) {
return !(planet.hasOwnProperty("PFNoLand") || planet.hasOwnProperty("solarGasGiant") || planet.hasOwnProperty("isGasGiant"));
}
return (worldScripts.PlanetFall2.$getPlanetLandingSites(planet).length > 0);
}
|