NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name WF2 Fleet Helper // @namespace sk.seko // @description Adds some controls to fleet navigation screen (relative to current position, specify o'clock direction and distance) // @updateURL https://openuserjs.org/meta/rsenderak/wf2-fleet-helper.meta.js // @downloadURL https://openuserjs.org/install/rsenderak/wf2-fleet-helper.user.js // @license MIT // @match https://*.atmoburn.com/fleet.php* // @match https://*.atmoburn.com/fleet/* // @grant none // @version 4.0.2 // ==/UserScript== // version 1.0 - init // version 1.1 - fix for UI changes // version 1.2 - added directional move (custom h.direction, distance and z variance) // version 1.3 - added "(fleet command)" link to fleet global coordinates; works best with "WF Fleet Command Helper" // version 1.4 - fixed @include after server protocol change from http to https // version 2.0 - support to "new" WF (WF2) // version 2.1 - systems in "Near Systems" now have color, and calculate vertical direction as well // version 2.2 - fixed GM_xmlhttpRequest vs GM.xmlHttpRequest incompatibility for some *monkey implementations // version 3.0 - atmoburn // version 4.0 - atmoburn changed // version 4.0.1 - fixed "local targets"; fixed Up and Down distances // version 4.0.2 - esversion set to 11 /* jshint esversion: 11 */ /* jshint node: true */ "use strict"; // regex pattern to match and capture x,y,z coordinates (plain text) const XYZ_REGEX = /^\s*(\-*\d+)[,\s]+(\-*\d+)[,\s]+(\-*\d+)/; var mCoordinates; var cNode; var fleetInfo; // x, y, z var xyzNode; var xyzposNode; var localTarget; var globalTarget; var targetTable; var targetTableContent; function xlog(msg) { console.log(`FH: ${msg}`); } function xerror(msg, error) { console.error(`FH: ${msg}`, error); } function byId(ele) { return document.getElementById(ele); } function fixDistance(d) { return d ? Number(d.trim().replace(/[mM]$/, '000000')) : d; } function rad2deg(angle) { return angle * 57.29577951308232; // angle / Math.PI * 180 } function deg2rad(angle) { return angle / 57.29577951308232; // angle / Math.PI * 180 } function clock(x1, y1, x2, y2) { const dx = x2 - x1; const dy = y2 - y1; if (dx == 0 && dy == 0) { return '-'; } let horiz = Math.round((rad2deg(Math.atan2(-dy, dx)) - 90 + 180) / 360 * 12); if (horiz < 0) { horiz += 12; } else if (horiz < 1) { horiz = 12; } return horiz; } function vert(x1, y1, z1, x2, y2, z2) { const dz = z2 - z1; if (dz == 0) { return 0; } const dx = x2 - x1; const dy = y2 - y1; const dxy = Math.round(Math.sqrt(dx*dx + dy*dy)); if (dxy == 0) { return dz > 0 ? 90 : -90; } let vert = Math.round(rad2deg(Math.atan2(dz, dxy))); if (vert < -90) { vert = -180 - vert; } else if (vert > 90) { vert = 180 - vert; } return vert; } function parseXYZ(s) { const m = s.match(XYZ_REGEX); return m ? {'x': parseInt(m[1]), 'y':parseInt(m[2]), 'z': parseInt(m[3])} : null; } function select_changed() { const val = byId("wfsCtrl").value; switch (val) { case "": { // label; do nothing hide_target_table(1); break; } case "1up": { // set coordinates to x,y,z+1 global hide_target_table(1); xyzNode.value = `${fleetInfo.x},${fleetInfo.y},${fleetInfo.z + 1}`; xyzposNode.value = "global"; break; } case "1down": { // set coordinates to x,y,z-1 global hide_target_table(1); xyzNode.value = `${fleetInfo.x},${fleetInfo.y},${fleetInfo.z - 1}`; xyzposNode.value = "global"; break; } case "dm": { // directional movement hide_target_table(1); let clock = null; while (clock == null) { clock = prompt("o'Clock (1-12):", "12"); } let distance = null; while (!distance) { distance = prompt("Distance in km (or mkm if suffix 'm' is used):", ""); } distance = fixDistance(distance); let z = null; while (z == null) { z = prompt("Z axis variance in km (or mkm is suffix 'm' is used); optional:", "0"); } const angle = clock_to_angle_rad(clock.trim()); const x = fleetInfo.x + Math.round(distance*Math.cos(angle)/4000); const y = fleetInfo.y + Math.round(distance*Math.sin(angle)/4000); xyzNode.value = `${x},${y},${Math.round(fleetInfo.z + fixDistance(z)/4000)}`; break; } default: { hide_target_table(1); if (val.startsWith("net|")) { const vals = val.split('|'); const x = fleetInfo.x + parseInt(vals[1]); const y = fleetInfo.y + parseInt(vals[2]); const z = fleetInfo.z + parseInt(vals[3]); xyzNode.value = `${x},${y},${z}`; } else { alert("Unhandled option: " + val); } break; } } } function hide_target_table(onoff) { targetTable.style.display = onoff ? "none" : ""; } function create_target_table() { const table = document.createElement("div"); table.setAttribute("class", "fullwidth padding5 tbborder light"); table.setAttribute("align", "left"); table.setAttribute("colspan", "2"); table.setAttribute("id", "wfsTable"); table.style.display = "none"; const tt = document.createElement('table'); tt.setAttribute('id', 'wfsTableContent'); tt.setAttribute('class', "margintop width100 box"); tt.setAttribute('width', '80%'); table.appendChild(tt); mCoordinates.parentNode.appendChild(table); targetTable = table; targetTableContent = tt; } function create_option_net(parent, name, dx, dy, dz) { const opt = document.createElement("option"); opt.setAttribute("value", "net|" + dx + "|" + dy + "|" + dz); opt.appendChild(document.createTextNode(name)); parent.appendChild(opt); } function clock_to_angle_rad(hour) { return deg2rad(360.0 *((3 - hour + 48) % 12) / 12.0); } function create_option_net_polar(parent, name, hour, distance) { const angle = clock_to_angle_rad(hour); const dx = Math.round(distance*Math.cos(angle)/4000); const dy = Math.round(distance*Math.sin(angle)/4000); create_option_net(parent, name, dx, dy, 0); } function parseFleetInfo() { const p = byId("navData").querySelector("div#positionRight > div > a"); if (p && p.textContent) { return parseXYZ(p.textContent); } return null; } function createUI() { // already done if (byId("wfsCtrl")) { return; } // initialize global variables xyzposNode = byId("xyzpos"); localTarget = byId("mLocalTargets").querySelector("option"); globalTarget = byId("missionSelectionGlobal"); // something is wrong, quit if (!xyzposNode || !globalTarget) { xerror("No xyzposNode or globalTarget"); return; } // get coordinates and fleet ID fleetInfo = parseFleetInfo(); if (!fleetInfo) { xerror("No fleet info"); return; } // create combo const sel = document.createElement("select"); sel.setAttribute("class", "darkselect"); sel.setAttribute("id", "wfsCtrl"); sel.addEventListener("change", select_changed, false); // opt0 const opt0 = document.createElement("option"); opt0.setAttribute("value", ""); opt0.appendChild(document.createTextNode("Select coordinates")); sel.appendChild(opt0); // opt1 if (localTarget) { const opt1 = document.createElement("option"); opt1.setAttribute("value", "1up"); opt1.appendChild(document.createTextNode("Above this system")); sel.appendChild(opt1); } // opt2 if (localTarget) { const opt2 = document.createElement("option"); opt2.setAttribute("value", "1down"); opt2.appendChild(document.createTextNode("Below this system")); sel.appendChild(opt2); } // opt3 if (globalTarget) { const opt3 = document.createElement("option"); opt3.setAttribute("value", "dm"); opt3.appendChild(document.createTextNode("Directional move")); sel.appendChild(opt3); } const optg1 = document.createElement("optgroup"); const dist = 3000000; const distStr = Math.round(dist/1000000).toString() + "mkm"; optg1.setAttribute("label", "Scanner network 8+2"); create_option_net(optg1, distStr + " Up", 0, 0, Math.round(dist/4000)); create_option_net(optg1, distStr + " Down", 0, 0, -Math.round(dist/4000)); create_option_net_polar(optg1, distStr + " 01'o", 1, dist); create_option_net_polar(optg1, distStr + " 02'o", 2, dist); create_option_net_polar(optg1, distStr + " 03'o", 3, dist); create_option_net_polar(optg1, distStr + " 04'o", 4, dist); create_option_net_polar(optg1, distStr + " 05'o", 5, dist); create_option_net_polar(optg1, distStr + " 06'o", 6, dist); create_option_net_polar(optg1, distStr + " 07'o", 7, dist); create_option_net_polar(optg1, distStr + " 08'o", 8, dist); create_option_net_polar(optg1, distStr + " 09'o", 9, dist); create_option_net_polar(optg1, distStr + " 10'o", 10, dist); create_option_net_polar(optg1, distStr + " 11'o", 11, dist); create_option_net_polar(optg1, distStr + " 12'o", 12, dist); sel.appendChild(optg1); xyzposNode.parentNode.insertBefore(sel, xyzposNode.nextSibling.nextSibling); // create target table (hidden) create_target_table(); } function startFleetHelper() { xyzNode = byId("xyz"); if (xyzNode) { mCoordinates = xyzNode.parentNode.parentNode; createUI(); xlog("Initialized"); } else { xerror("NOT Initialized"); } } setTimeout(startFleetHelper, 500);