NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Alternative Map Plotter // @version 2024-08-25 // @author Mario // @license MIT // @match https://*.atmoburn.com/map_plotter.php // @grant unsafeWindow // ==/UserScript== createButtons() // set defaults eval(unsafeWindow.byId.toString()); unsafeWindow.eval(renderMap2.toString()); unsafeWindow.eval(createButtons.toString()); unsafeWindow.eval(checkCoords.toString()); unsafeWindow.eval("var classToColor = {O: [221, 100, 79], B: [221, 100, 82], A: [224, 100, 92], F: [264, 100, 98], G: [21, 100, 95], K: [30, 100, 85], M: [30, 100, 71]};"); byId("orientation").value = "V"; // topdown byId("mapType").value = "known"; byId("tactical").checked = true; // Check tactical view byId("resolution").value = "8640"; // 16k byId("empireMapData").checked = true; byId("empireRallyPoints").checked = true; byId("colonies").checked = true; byId("fleet").checked = true; byId("rally").checked = true; byId("mapbm").checked = false; byId("unexploredSize").value = 5; // render script starts here var classToColor = {O: [221, 100, 79], B: [221, 100, 82], A: [224, 100, 92], F: [264, 100, 98], G: [21, 100, 95], K: [30, 100, 85], M: [30, 100, 71]}; function renderMap2() { var renderedCoords = []; var color1, color2, color3, size, x, y; var orientation = byId('orientation').value; var aspectRatio = orientation == 'P' ? 16/9 : 4/3; var resolutionY = resolutionX = byId('resolution').value; var resolutionX = aspectRatio * resolutionY; var plotterScale = 20000; var modX = resolutionX / plotterScale; var modY = resolutionY / plotterScale; var tactical = byId('tactical').checked ? true : false; var focusXmin = parseInt(byId('focusXmin').value)/100 var focusYmin = parseInt(byId('focusYmin').value)/100 var focusXmax = parseInt(byId('focusXmax').value)/100 var focusYmax = parseInt(byId('focusYmax').value)/100 var focusScalerX = 1/(focusXmax-focusXmin) var focusScalerY = 1/(focusYmax-focusYmin) loadingAnimation('mapSettings', 'on'); var canvas = document.createElement('canvas'); canvas.height = resolutionY; canvas.width = resolutionX; var context = canvas.getContext('2d'); context.beginPath(); context.fillStyle = 'rgb(0,0,0)'; context.fillRect(0, 0, resolutionX, resolutionY); context.font = "12px 'Rubik'"; context.textAlign = 'center'; context.textBaseline = 'top'; context.lineWidth = 3; var tsize = byId("unexploredSize").value; // start sensornet stuff var scannerCanvas = document.createElement('canvas'); scannerCanvas.height = resolutionY; scannerCanvas.width = resolutionX; var scannerContext = scannerCanvas.getContext('2d'); scannerContext.globalCompositeOperation = 'xor'; // end sensornet stuff let requestArguments = "orientation=" + orientation + "&color=" + byId('mapType').value + "&galaxy=" + byId('galaxy').value + "&empireMapData=" + (byId('empireMapData') && byId('empireMapData').checked ? 1 : 0) + "&empireRallyPoints=" + (byId('empireRallyPoints') && byId('empireRallyPoints').checked ? 1 : 0) + "&colonies=" + (byId('colonies').checked ? 1 : 0) + "&fleet=" + (byId('fleet').checked ? 1 : 0) + "&rally=" + (byId('rally').checked ? 1 : 0) + "&mapbm=" + (byId('mapbm').checked ? 1 : 0); if (!document.domain.includes("beta3")) { requestArguments += "&sensors=" + (byId('sensors').checked ? 1 : 0) } loadContent('/ajax/map_plotter.php', function(mapData) { if (mapData == "FAIL" || !mapData) { genericPopup({content: "Plotter is busy. Please try again later."}); } else { try { var mapItems = mapData.split('\n'); let xValues = []; let yValues = []; mapItems.forEach(mapItem => { if (parseInt(mapItem.split('\t')[1]) && parseInt(mapItem.split('\t')[2])) { xValues.push(parseInt(mapItem.split('\t')[1])); yValues.push(parseInt(mapItem.split('\t')[2])); } }) // First we crop the image to only the content. var minX = Math.min(...xValues); var maxX = Math.max(...xValues) + minX; var minY = Math.min(...yValues); var maxY = Math.max(...yValues) + minY; var filterTerm = byId("filterID").value; mapItems.forEach(function(mapItem) { var item = mapItem.split('\t'); if (item[1] > focusXmin*maxX && item[1] < focusXmax*maxX && item[2] > focusYmin*maxY && item[2] < focusYmax*maxY) { // only render things in the core x = Math.round((item[1] - focusXmin*maxX) * modX * focusScalerX); // -focusXmin*max puts it in the top left corner, prevents rendering out of frame y = Math.round((item[2] - focusYmin*maxY) * modY * focusScalerY); if (item[0] == 's') { if (tactical) [color1, color2, color3] = [0, 100, 70]; else [color1, color2, color3] = classToColor[item[6]]; if (!parseInt(item[7])) { color2 = color2 / 5; color3 = color3 / 2; tsize = byId("unexploredSize").value; } else { tsize = 1 } size = Math.pow(item[5], 0.1) / 3; context.beginPath(); context.fillStyle = "hsl("+color1+","+color2+"%, "+color3+"%)"; if (tactical || size < 0.5) { if (byId('circles').checked) { context.arc(x, y, tsize * Math.max(focusScalerY, focusScalerX), 0, 2 * Math.PI, false); } else { context.fillRect(x, y, tsize * Math.max(focusScalerY, focusScalerX), tsize * Math.max(focusScalerY, focusScalerX)); } } else { context.arc(x, y, size * Math.min(5,Math.max(focusScalerY, focusScalerX)), 0, 2 * Math.PI, false); } if (!tactical) { context.shadowBlur = size; context.shadowColor = "hsl("+color1+","+color2+"%, "+color3+"%)"; } context.fill(); } else if (item[0] == 'n') { // sensorNet ship console.log(item); if (item[5] == 'global') { x = Math.round((item[1] - focusXmin*maxX) * modX * focusScalerX); // -focusXmin*max puts it in the top left corner, prevents rendering out of frame y = Math.round((item[2] - focusYmin*maxY) * modY * focusScalerY); let xRange = Math.round(item[6] * modX * focusScalerX); // -focusXmin*max puts it in the top left corner, prevents rendering out of frame let yRange = Math.round(item[7] * modY * focusScalerY); console.log([x,y,xRange,yRange]); scannerContext.beginPath(); scannerContext.strokeStyle = 'white'; scannerContext.fillStyle = "rgba(0,0,0,0)"; scannerContext.ellipse(x, y, xRange, yRange, 0, 0, 2 * Math.PI); scannerContext.stroke(); } } else { if (item[4]) { if (filterTerm === "" || item[4].startsWith(filterTerm)) { if (!byId('empireRallyPoints').checked || item[0] != 'r') { // if empire rally points is checked we need to ignore the player rally points y = checkCoords(renderedCoords, x, y) renderedCoords.push(String(x)+String(y)); context.strokeStyle = '#000000'; if (item[0] == 'r' || item[0] == 'e') { // red for rally points //console.log(item); context.fillStyle = '#ff0000'; //#ff0000 is pure red } else if (item[0] == 'c') { // green for colonies context.fillStyle = '#00ff00'; //#00ff00 is pure green } else if (item[0] == 'f') { // blue for fleets context.fillStyle = '#0077ff'; //#0000ff is pure blue } else { // white for possible other stuff context.fillStyle = '#ffffff'; } context.strokeText(item[4], x, y + 6); context.fillText(item[4], x, y + 6); } } } } } }); } catch(e) { console.log(e); genericPopup({content: "Your browser does not support this image size. Try a lower resolution."}); loadingAnimation('mapSettings', 'off'); return; } context.drawImage(scannerContext.canvas,0,0); var png = canvas.toDataURL('image/png'); if (png.length < 1024) { genericPopup({content: "Your browser does not support this image size. Try a lower resolution."}); } else { var link = document.createElement('a'); link.href = png; link.download = "Atmoburn-"+String(window.location).split("//")[1].split(".")[0]+"-"+byId('galaxy').value+".png"; link.target = "_blank"; link.click(); } } loadingAnimation('mapSettings', 'off'); }, requestArguments, "POST"); } function checkCoords(renderedCoords, x, y) { if (renderedCoords.includes(String(x)+String(y))) { return checkCoords(renderedCoords, x, y+14) } else { return y } } function createButtons() { let unexploredSize = document.createElement('div'); unexploredSize.class = "inlineblock alignright"; unexploredSize.innerHTML = "Unexplored size <br>"; unexploredSize.title = "Render size for unexplored systems.\nUse with tactical plot."; byId("galaxy").parentElement.append(unexploredSize) let unexploredSizeInput = document.createElement('input'); unexploredSizeInput.type = "text"; unexploredSizeInput.className = "darkinput"; unexploredSizeInput.id = "unexploredSize"; unexploredSizeInput.size = "4"; unexploredSizeInput.maxlength = "2"; unexploredSizeInput.value = "2"; unexploredSize.append(unexploredSizeInput) let focusSettings = document.createElement('div'); focusSettings.class = "inlineblock alignright"; focusSettings.innerHTML = "Focus Settings X-min, X-max, Y-min, Y-max <br>"; focusSettings.title = "Settings that allow you to focus a part of the galaxy\nUse with tactical plot."; byId("galaxy").parentElement.append(focusSettings) let focusXmin = document.createElement('input'); focusXmin.type = "text"; focusXmin.className = "darkinput"; focusXmin.id = "focusXmin"; focusXmin.size = "4"; focusXmin.maxlength = "3"; focusXmin.value = "0"; focusSettings.append(focusXmin) let focusXmax = document.createElement('input'); focusXmax.type = "text"; focusXmax.className = "darkinput"; focusXmax.id = "focusXmax"; focusXmax.size = "4"; focusXmax.maxlength = "3"; focusXmax.value = "100"; focusSettings.append(focusXmax) let focusYmin = document.createElement('input'); focusYmin.type = "text"; focusYmin.className = "darkinput"; focusYmin.id = "focusYmin"; focusYmin.size = "4"; focusYmin.maxlength = "3"; focusYmin.value = "0"; focusSettings.append(focusYmin) let focusYmax = document.createElement('input'); focusYmax.type = "text"; focusYmax.className = "darkinput"; focusYmax.id = "focusYmax"; focusYmax.size = "4"; focusYmax.maxlength = "3"; focusYmax.value = "100"; focusSettings.append(focusYmax) let circlesLabel = document.createElement('label'); circlesLabel.className = "pointer"; let circlesQuestion = document.createElement('input'); circlesQuestion.type = "checkbox"; circlesQuestion.className = "darkcheckbox"; circlesQuestion.id = "circles"; circlesQuestion.value = "1"; circlesLabel.append(circlesQuestion); circlesLabel.append("Circles?"); byId('colonies').parentElement.parentElement.append(circlesLabel); let higherRes = document.createElement('option'); higherRes.value = 12960; higherRes.innerHTML = "24k"; byId('resolution').append(higherRes); let altRender = document.createElement('button'); altRender.innerHTML = "Better Tactical Render"; altRender.id = "altRender"; altRender.className = "darkbutton"; altRender.addEventListener("click", renderMap2); altRender.title = "Makes it CLEAR which systems are unexplored."; document.getElementsByClassName("block padding5 light aligncenter")[0].append(altRender); let filterSettings = document.createElement('div'); filterSettings.class = "inlineblock alignright"; filterSettings.innerHTML = "Filter Settings<br>"; filterSettings.title = "Settings that allow you only render names starting with the input value."; byId("galaxy").parentElement.append(filterSettings) let filterNames = document.createElement('input'); filterNames.type = "text"; filterNames.className = "darkinput"; filterNames.id = "filterID"; filterNames.size = "7"; filterNames.maxlength = "7"; filterNames.value = ""; filterNames.style.marginLeft = "5px"; filterSettings.append(filterNames); }