523 lines
No EOL
19 KiB
JavaScript
523 lines
No EOL
19 KiB
JavaScript
/*
|
|
* TESTING SECTION
|
|
*/
|
|
|
|
|
|
const map_url_base = location.href.split("#")[0];
|
|
const map_url_tag = location.hash.slice(1);
|
|
console.log(map_url_base);
|
|
console.log(map_url_tag);
|
|
|
|
const MAP_BUILD_VERSION = "6.9.42.0";
|
|
|
|
function setTitle() {
|
|
let text = "WynnGPS version "+MAP_BUILD_VERSION;
|
|
document.getElementById("header").classList.add("funnynumber");
|
|
document.getElementById("header").textContent = text;
|
|
}
|
|
|
|
setTitle();
|
|
|
|
|
|
|
|
|
|
/*
|
|
* END testing section
|
|
*/
|
|
|
|
var map;
|
|
var image;
|
|
|
|
|
|
var marker;
|
|
var guilds = [];
|
|
var guildTags = new Map(); //guild name : guild tag. Ex: Atlas Inc : AIn
|
|
var guildColors = new Map();
|
|
|
|
let terrObjs = [];
|
|
let claimObjs = [];
|
|
//let guildObjs = [];
|
|
let routeObjs = [];
|
|
let resourceObjs = [];
|
|
|
|
let drawterrs = false;
|
|
let drawclaims = false;
|
|
let drawroutes = false;
|
|
let drawresources = false;
|
|
let drawmerchants = false;
|
|
|
|
//latitude, longitude is y, x!!!!
|
|
const bounds = [[0,0], [6484, 4090]];
|
|
const resourceColors = new Map([
|
|
["Emeralds","#4ae024"],
|
|
["Ore","#7d7b74"],
|
|
["Wood","#855E42"],
|
|
["Crops","#e3cea6"],
|
|
["Fish","#a6d8e3"]
|
|
]);
|
|
|
|
/** Thanks to kristofbolyai's github page for showing me how to do all of this.
|
|
*
|
|
*/
|
|
function init(){ //async just in case we need async stuff
|
|
map_elem = document.getElementById("mapdiv");
|
|
let coordx_elem = document.getElementById("coord-x");
|
|
let coordz_elem = document.getElementById("coord-z");
|
|
|
|
map = L.map("mapdiv", {
|
|
crs: L.CRS.Simple,
|
|
minZoom: -4,
|
|
maxZoom: 2,
|
|
zoomControl: false,
|
|
zoom: 1
|
|
}).setView([0,0], 1);
|
|
L.imageOverlay("/media/maps/world-map.png", bounds).addTo(map);
|
|
|
|
map.fitBounds(bounds);
|
|
|
|
L.control.zoom({
|
|
position: 'topleft'
|
|
}).addTo(map);
|
|
|
|
|
|
if (map_url_tag) {
|
|
let coords = map_url_tag.split(",");
|
|
let x = parseFloat(coords[0]);
|
|
let y = parseFloat(coords[1]);
|
|
if (parseFloat(coords[0]) && parseFloat(coords[1])) {
|
|
placeMarker(xytolatlng(x,y)[0], xytolatlng(x,y)[1]);
|
|
}
|
|
}
|
|
|
|
map.addEventListener('mousemove', function(ev) {
|
|
lat = Math.round(ev.latlng.lat);
|
|
lng = Math.round(ev.latlng.lng);
|
|
let coords = latlngtoxy(lat,lng);
|
|
coordx_elem.textContent = coords[0];
|
|
coordz_elem.textContent = coords[1];
|
|
});
|
|
|
|
map.on('contextmenu', function(ev) {
|
|
if (ev.originalEvent.which == 3) {
|
|
lat = Math.round(ev.latlng.lat);
|
|
lng = Math.round(ev.latlng.lng);
|
|
console.log([lat,lng]);
|
|
placeMarker(lat, lng);
|
|
}
|
|
|
|
});
|
|
map_elem.style.background = "#121516";
|
|
|
|
try {
|
|
pullguilds();
|
|
} catch (error) {
|
|
console.log(error);
|
|
let header = document.getElementsById("header");
|
|
let warning = document.createElement("p");
|
|
warning.classList.add("center");
|
|
warning.style.color = "red";
|
|
warning.textContent = "";
|
|
header.append(warning);
|
|
}
|
|
console.log("Territory locations:", terrs);
|
|
console.log("Claims:", claims);
|
|
console.log("Territory Neighbors:", neighbors);
|
|
console.log("Territory Resources", resources);
|
|
console.log("List of guilds on the map:", guilds);
|
|
console.log("Guilds and their guild tags:", guildTags);
|
|
}
|
|
|
|
/** Places the marker at x, y.
|
|
*
|
|
* @param {Number} lng - longitude
|
|
* @param {Number} lat - latitude
|
|
*/
|
|
function placeMarker(lat, lng) {
|
|
let coords = latlngtoxy(lat,lng);
|
|
if (marker) {
|
|
map.removeLayer(marker);
|
|
}
|
|
|
|
marker = L.marker([lat, lng], {icon: L.icon({
|
|
iconUrl: '/media/icons/' + (newIcons ? "new/" : "old/" ) + 'marker.png',
|
|
iconSize: [32, 32],
|
|
iconAnchor: [16, 32],
|
|
shadowUrl: '/media/icons/' + (newIcons ? "new/" : "old/" ) + 'shadow.png',
|
|
shadowSize: [1,1],
|
|
shadowAnchor: [16, 32],
|
|
className: "marker"
|
|
})});
|
|
|
|
let mcdx = document.getElementById("marker-coord-x");
|
|
mcdx.textContent = coords[0];
|
|
mcdx.style.display = "grid-item-7";
|
|
let mcdi = document.getElementById("marker-coord-img");
|
|
mcdi.style.display = "grid-item-8";
|
|
let mcdz = document.getElementById("marker-coord-z");
|
|
mcdz.textContent = coords[1];
|
|
mcdz.style.display = "grid-item-9";
|
|
location.hash = coords[0] + "," + coords[1];
|
|
marker.addTo(map);
|
|
}
|
|
|
|
|
|
//Wynn coordinates: down right = ++
|
|
//Leaflet coordinates: up right = ++
|
|
//may not be 100% accurate, but "close enough."
|
|
function xytolatlng(x, y) {
|
|
return [-y-123, x+2392]; //lat, lng
|
|
}
|
|
|
|
function latlngtoxy(lat, lng) {
|
|
return [lng-2392, -lat-123]; //x, y
|
|
}
|
|
|
|
/** Toggles a button on and off
|
|
*
|
|
* @param {String} elemID - element ID of button
|
|
*/
|
|
function toggleButton(elemID) {
|
|
let elem = document.getElementById(elemID);
|
|
if (elem.classList.contains("toggleOn")) {
|
|
elem.classList.remove("toggleOn");
|
|
elem.textContent = elem.textContent.replace("Hide","Show");
|
|
} else {
|
|
elem.classList.add("toggleOn");
|
|
elem.textContent = elem.textContent.replace("Show","Hide");
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Pulls data from the API and overrides all of the current stuff with it. Do NOT call this too often. Called once, upon initialization.
|
|
*
|
|
*/
|
|
async function refreshData() { //async just in case we need async stuff
|
|
terrs = new Map();
|
|
claims = new Map();
|
|
guilds = [];
|
|
|
|
|
|
const url='https://api.wynncraft.com/public_api.php?action=territoryList';
|
|
fetch(url)
|
|
.then(data => {return data.json()})
|
|
.then(res => { //success
|
|
terrdata = Object.entries(res['territories']);
|
|
console.log(terrdata);
|
|
for (const terr of terrdata) {
|
|
//terrs.set(terr[0], terr[1].location) //bounds shouldnt change
|
|
claims.set(terr[0], terr[1].guild)
|
|
if (!guilds.includes(terr[1].guild)) {
|
|
guilds.push(terr[1].guild);
|
|
}
|
|
}
|
|
pullguilds();
|
|
console.log("Succesfully pulled and loaded territory data.")
|
|
})
|
|
.catch(error => { //failure
|
|
console.log(error)
|
|
console.log("Something went wrong pulling and loading territory data. Attempting to load from file...")
|
|
/* @hpp could we eventually get something that writes to local cache on success and attempts to pull from local cache if fails
|
|
*/
|
|
})
|
|
}
|
|
|
|
|
|
function pullguilds() {
|
|
let guild_url_base = "https://api.wynncraft.com/public_api.php?action=guildStats&command=";
|
|
for (const guild of guilds) {
|
|
fetch(guild_url_base + guild.replaceAll(" ", "%20"))
|
|
.then(data => {return data.json()})
|
|
.then(res => {
|
|
guildTags.set(guild, res.prefix);
|
|
guildColors.set(guild, randomColorHSL([0,1],[0,1],[0.4,1]));
|
|
console.log("Succesfully pulled guild data for " + guild + ".");
|
|
})
|
|
.catch(error => {
|
|
console.log(error);
|
|
console.log("Something went wrong pulling guild data for " + guild + ".");
|
|
})
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/** These functions toggle drawing of their related objects
|
|
*
|
|
*/
|
|
|
|
function toggleTerritories() {
|
|
function drawTerritories() {
|
|
for (const [terr,terrbounds] of terrs) {
|
|
let coords = [xytolatlng(terrbounds.startX,terrbounds.startY), xytolatlng(terrbounds.startX,terrbounds.endY), xytolatlng(terrbounds.endX,terrbounds.endY), xytolatlng(terrbounds.endX,terrbounds.startY)];
|
|
let terrObj = L.polygon(coords, {color: '#f6c328'}).on('mouseover',function(e){displayTerritoryStats(terr)}).on('mouseoff',function(e){eraseTerritoryStats()}).addTo(map);
|
|
terrObj.bindTooltip(`<p class = 'labelp' style = "color:#f6c328">${terr}</p>`, {sticky: true, className:"labelp", interactive: false, permanent: true, direction: 'center'});
|
|
terrObjs.push(terrObj);
|
|
}
|
|
console.log("Drew all territories");
|
|
}
|
|
function deleteTerritories() {
|
|
for (const terr of terrObjs) {
|
|
map.removeLayer(terr);
|
|
}
|
|
terrObjs = [];
|
|
console.log("Erased all territories");
|
|
}
|
|
|
|
drawterrs = !drawterrs;
|
|
|
|
if (drawterrs) {drawTerritories()}
|
|
else {deleteTerritories()}
|
|
}
|
|
|
|
function toggleClaims() {
|
|
if(drawterrs) {toggleTerritories(); toggleButton("territories-button")}
|
|
let guildkey = document.getElementById("guild-key");
|
|
let guildkeylist = document.getElementById("guildkeylist");
|
|
|
|
function drawClaims() {
|
|
for (const [terr,terrbounds] of terrs) {
|
|
let guild = claims.get(terr);
|
|
let coords = [xytolatlng(terrbounds.startX,terrbounds.startY), xytolatlng(terrbounds.startX,terrbounds.endY), xytolatlng(terrbounds.endX,terrbounds.endY), xytolatlng(terrbounds.endX,terrbounds.startY)];
|
|
let claimObj = L.polygon(coords, {color: `${guildColors.get(guild)}`}).on('mouseover',function(e){displayTerritoryStats(terr)}).on('mouseoff',function(e){eraseTerritoryStats()}).addTo(map);
|
|
claimObj.bindTooltip(`<p class = 'labelp' style = "color:${guildColors.get(guild)}"><b>${terr}</b><br><b>${guildTags.get(guild)}</b></p>`, {sticky: true, className:"labelp", interactive: false, permanent: true, direction: 'center'});
|
|
|
|
claimObjs.push(claimObj);
|
|
}
|
|
guildkey.style.display = "";
|
|
for (const guild of guilds) {
|
|
let guildLI = document.createElement("li");
|
|
guildLI.style.color = guildColors.get(guild);
|
|
guildLI.textContent = guildTags.get(guild) + " | " + guild;
|
|
guildkeylist.appendChild(guildLI);
|
|
}
|
|
console.log("Drew all claims")
|
|
}
|
|
function deleteClaims() {
|
|
for (const claim of claimObjs) {
|
|
map.removeLayer(claim);
|
|
}
|
|
claimObjs = [];
|
|
guildkeylist.innerHTML = "";
|
|
guildkey.style.display = "none";
|
|
console.log("Erased all claims");
|
|
}
|
|
|
|
drawclaims = !drawclaims;
|
|
if (drawclaims) {drawClaims()}
|
|
else {deleteClaims()}
|
|
}
|
|
|
|
function toggleRoutes() {
|
|
function drawRoutes() {
|
|
let drawnRoutes = [];
|
|
for (const [terr,terrbounds] of terrs) {
|
|
for (const neighbor of neighbors.get(terr)) {
|
|
if (!drawnRoutes.includes([neighbor,terr])) {
|
|
let coords = [xytolatlng( (terrbounds.startX + terrbounds.endX)/2,(terrbounds.startY + terrbounds.endY)/2 ),xytolatlng( (terrs.get(neighbor).startX + terrs.get(neighbor).endX)/2, (terrs.get(neighbor).startY + terrs.get(neighbor).endY)/2)];
|
|
let routeObj = L.polyline(coords, {color: '#990000'}).addTo(map);
|
|
drawnRoutes.push([terr,neighbor]);
|
|
routeObjs.push(routeObj);
|
|
}
|
|
}
|
|
}
|
|
console.log("Drew all territories");
|
|
}
|
|
function deleteRoutes() {
|
|
for (const route of routeObjs) {
|
|
map.removeLayer(route);
|
|
}
|
|
routeObjs = [];
|
|
console.log("Erased all routes");
|
|
}
|
|
|
|
drawroutes = !drawroutes;
|
|
if (!drawterrs && !drawclaims && drawroutes) {
|
|
toggleTerritories();
|
|
toggleButton("territories-button");
|
|
} else if (drawterrs && drawclaims && drawroutes) { //this shouldn't happen
|
|
toggleClaims();
|
|
toggleButton("claims-button");
|
|
}
|
|
|
|
if (drawroutes) {drawRoutes()}
|
|
else {deleteRoutes()}
|
|
}
|
|
|
|
function toggleResources() {
|
|
let resourcekeyelem = document.getElementById("resources-key");
|
|
function drawResources() {
|
|
|
|
for (const terr of terrs.keys()) {
|
|
//get resources of territory, dupe if doubleresources
|
|
let terr_resources = resources.get(terr).resources.slice();
|
|
let terr_storage = resources.get(terr).storage.slice();
|
|
if (resources.get(terr).doubleresource) {
|
|
let temp = [];
|
|
for (const resource of terr_resources) {
|
|
temp.push(resource);
|
|
temp.push(resource);
|
|
}
|
|
terr_resources = temp.slice();
|
|
}
|
|
if (resources.get(terr).emeralds) {
|
|
terr_resources.push("Emeralds");
|
|
if (resources.get(terr).doubleemeralds) {
|
|
terr_resources.push("Emeralds");
|
|
}
|
|
}
|
|
|
|
//territory bounds from bottom left to top right
|
|
let bounds = [ [terrs.get(terr).startX, terrs.get(terr).startY], [terrs.get(terr).endX, terrs.get(terr).endY] ];
|
|
if (bounds[0][0] > bounds[1][0]) {
|
|
let temp = bounds[1][0];
|
|
bounds[1][0] = bounds[0][0];
|
|
bounds[0][0] = temp;
|
|
}
|
|
if (bounds[0][1] < bounds[1][1]) {
|
|
let temp = bounds[1][1];
|
|
bounds[1][1] = bounds[0][1];
|
|
bounds[0][1] = temp;
|
|
}
|
|
let TRcorner = bounds[1];
|
|
let DRcorner = [bounds[1][0],bounds[0][1]];
|
|
let gap = 3;
|
|
|
|
//draw resource generation
|
|
for (const n in terr_resources) {
|
|
let resource = terr_resources[n];
|
|
|
|
let imgBounds = [ [ TRcorner[0]-(16*n)-20-gap*n,TRcorner[1]+4], [ TRcorner[0]-(16*n)-4-gap*n,TRcorner[1]+20] ];
|
|
imgBounds = [xytolatlng(imgBounds[0][0],imgBounds[0][1]), xytolatlng(imgBounds[1][0],imgBounds[1][1])];
|
|
|
|
let resourceObj = L.imageOverlay("/media/icons/" + (newIcons ? "new/" : "old/" ) +resource+".png", imgBounds, {className: `${resource} resourceimg`}).addTo(map);
|
|
resourceObjs.push(resourceObj);
|
|
}
|
|
let gearObj = L.imageOverlay("/media/icons/" + (newIcons ? "new/" : "old/" ) + "Gears.png", [xytolatlng(TRcorner[0]-(16*terr_resources.length)-20-gap*terr_resources.length,TRcorner[1]+4), xytolatlng(TRcorner[0]-(16*terr_resources.length)-4-gap*terr_resources.length,TRcorner[1]+20)], {className: `Ore resourceimg`}).addTo(map);
|
|
resourceObjs.push(gearObj);
|
|
//draw resource storage
|
|
for (const n in terr_storage) {
|
|
let storage = terr_storage[n];
|
|
|
|
let imgBounds = [ [ DRcorner[0]-(16*n)-20-gap*n,DRcorner[1]-20], [ DRcorner[0]-(16*n)-4-gap*n,DRcorner[1]-4] ];
|
|
imgBounds = [xytolatlng(imgBounds[0][0],imgBounds[0][1]), xytolatlng(imgBounds[1][0],imgBounds[1][1])];
|
|
|
|
let resourceObj = L.imageOverlay("/media/icons/" + (newIcons ? "new/" : "old/" ) +storage+".png", imgBounds, {alt: `${storage}`, className: `${storage} resourceimg`}).addTo(map);
|
|
resourceObjs.push(resourceObj);
|
|
}
|
|
let chestObj = L.imageOverlay("/media/icons/" + (newIcons ? "new/" : "old/" ) + "Chest.png", [xytolatlng(DRcorner[0]-(16*terr_storage.length)-20-gap*terr_storage.length,DRcorner[1]-20), xytolatlng(DRcorner[0]-(16*terr_storage.length)-4-gap*terr_storage.length,DRcorner[1]-4)], {className: `Wood resourceimg`}).addTo(map);
|
|
resourceObjs.push(chestObj);
|
|
}
|
|
|
|
resourcekeyelem.style.display = "";
|
|
console.log("Drew all resources");
|
|
}
|
|
function deleteResources() {
|
|
for (const resourceObj of resourceObjs) {
|
|
console.log(resourceObj);
|
|
map.removeLayer(resourceObj);
|
|
}
|
|
resourceObjs = [];
|
|
resourcekeyelem.style.display = "none";
|
|
console.log("Erased all resources")
|
|
}
|
|
|
|
drawresources = !drawresources;
|
|
if (!drawterrs && !drawclaims && drawresources) {
|
|
toggleTerritories();
|
|
toggleButton("territories-button");
|
|
} else if (drawterrs && drawclaims && drawresources) { //this shouldn't happen
|
|
toggleClaims();
|
|
toggleButton("claims-button");
|
|
}
|
|
|
|
if (drawresources) {drawResources()}
|
|
else {deleteResources()}
|
|
}
|
|
|
|
/** Displays the territory stats in the territory stats div.
|
|
*
|
|
* @param {String} terr - the territory name
|
|
*/
|
|
function displayTerritoryStats(terr) {
|
|
let terr_stats_elem = document.getElementById("territory-stats");
|
|
terr_stats_elem.innerHTML = ""; //jank
|
|
|
|
let terr_resource_stats = resources.get(terr);
|
|
let terr_resources = terr_resource_stats.resources.slice();
|
|
let terr_storage = terr_resource_stats.storage.slice();
|
|
let doubleemeralds = terr_resource_stats.doubleemeralds;
|
|
let emeralds = terr_resource_stats.emeralds;
|
|
let doubleresource = terr_resource_stats.doubleresource;
|
|
|
|
if (drawterrs || drawclaims || drawresources) {
|
|
let stats_title = document.createElement("p");
|
|
stats_title.classList.add("smalltitle");
|
|
stats_title.style.maxWidth = "95%";
|
|
stats_title.style.wordBreak = "break-word";
|
|
stats_title.textContent = terr;
|
|
terr_stats_elem.appendChild(stats_title);
|
|
|
|
let bounds = terrs.get(terr);
|
|
let p = document.createElement("p");
|
|
p.classList.add("left");
|
|
p.textContent = "(" + bounds.startX + ", " + bounds.startY + ") \u279C (" + bounds.endX + ", " + bounds.endY + ")";
|
|
terr_stats_elem.appendChild(p);
|
|
|
|
p = document.createElement("p");
|
|
p.classList.add("left");
|
|
p.textContent = claims.get(terr) + " (" + guildTags.get(claims.get(terr)) + ")";
|
|
terr_stats_elem.appendChild(p);
|
|
|
|
let neighbors_elem = document.createElement("p");
|
|
neighbors_elem.classList.add("left");
|
|
neighbors_elem.style.maxWidth = "95%";
|
|
neighbors_elem.style.wordBreak = "break-word";
|
|
neighbors_elem.textContent = "Neighbors: "
|
|
for (const neighbor of neighbors.get(terr)) {
|
|
neighbors_elem.textContent += neighbor + ", "
|
|
}
|
|
neighbors_elem.textContent = neighbors_elem.textContent.slice(0,-2);
|
|
terr_stats_elem.appendChild(neighbors_elem);
|
|
|
|
let produce_elem = document.createElement("p");
|
|
produce_elem.classList.add("left");
|
|
produce_elem.style.maxWidth = "95%";
|
|
produce_elem.style.wordBreak = "break-word";
|
|
produce_elem.textContent = "Produces: "
|
|
for (const resource of terr_resources) {
|
|
produce_elem.textContent += resource + (doubleresource ? " x2" : "") + ", ";
|
|
}
|
|
if (emeralds) {
|
|
produce_elem.textContent += "Emeralds" + (doubleemeralds ? " x2" : "") + ", ";
|
|
}
|
|
produce_elem.textContent = produce_elem.textContent.slice(0,-2);
|
|
terr_stats_elem.appendChild(produce_elem);
|
|
|
|
let storage_elem = document.createElement("p");
|
|
storage_elem.classList.add("left");
|
|
storage_elem.style.maxWidth = "95%";
|
|
storage_elem.style.wordBreak = "break-word";
|
|
storage_elem.textContent = "Stores: "
|
|
for (const resource of terr_storage) {
|
|
storage_elem.textContent += resource + ", ";
|
|
}
|
|
storage_elem.textContent = storage_elem.textContent.slice(0,-2);
|
|
terr_stats_elem.appendChild(storage_elem);
|
|
|
|
}
|
|
}
|
|
function eraseTerritoryStats() {
|
|
let terr_stats_elem = document.getElementById("territory-stats");
|
|
terr_stats_elem.innerHTML = ""; //jank
|
|
}
|
|
|
|
/** Toggles all merchant icons/markers on the map. TODO.
|
|
*
|
|
*/
|
|
function toggleMerchants() {
|
|
|
|
}
|
|
|
|
load_map_init(init); |