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);
}