/* * 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); /* * 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 locationObjs = []; let drawterrs = false; let drawclaims = false; let drawroutes = false; let drawresources = false; let drawlocations = 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_map(){ //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 { refreshData(); pullguilds(); //save_map_data(); } catch (error) { console.log(error); let header = document.getElementById("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); console.log("Map locations:", maplocs); } /** 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() { //terrs = new Map(); claims = new Map(); terrdata; 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']); guilds = []; 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); } } console.log("terrdata \n", terrdata); console.log("claims \n", claims); console.log("guilds \n", guilds); pullguilds(); console.log("Succesfully pulled and loaded territory data.") //save_guild_data(); console.log("Succesfully saved 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 + "."); }) } } /** Toggles all location icons/markers on the map. * */ function toggleLocations() { let key_elem = document.getElementById("locationlist"); function drawLocations() { let imgs = ["Content_Dungeon.png", "Content_CorruptedDungeon.png", "Content_Quest.png", "Merchant_Emerald.png", "NPC_Blacksmith.png", "NPC_ItemIdentifier.png", "NPC_PowderMaster.png", "Merchant_Potion.png", "Merchant_Armour.png", "Merchant_Weapon.png", "Merchant_Liquid.png", "Merchant_Other.png", "Merchant_Scroll.png", "Merchant_Accessory.png", "Merchant_Tool.png", "painting.png", "Profession_Weaponsmithing.png", "Profession_Armouring.png", "Profession_Alchemism.png", "Profession_Jeweling.png", "Profession_Tailoring.png", "Profession_Scribing.png", "Profession_Cooking.png", "Profession_Woodworking.png", "Content_Miniquest.png", "Special_RootsOfCorruption.png", "Special_FastTravel.png", "Special_LightRealm.png", "Special_Rune.png", "Content_UltimateDiscovery.png", "Merchant_KeyForge.png", "NPC_GuildMaster.png", "Content_GrindSpot.png", "Content_Cave.png", "NPC_TradeMarket.png", "Content_BossAltar.png", "Content_Raid.png", "Merchant_Dungeon.png", "tnt.png", "Merchant_Seasail.png", "Merchant_Horse.png"]; for (const loc of maplocs) { //loc has name, icon, x, y, z. don't care about y if (loc.icon) { let latlng = xytolatlng(loc.x,loc.z); let locObj = L.marker(latlng, {icon: L.icon({ //iconUrl: '/media/icons/' + (newIcons ? "new/" : "old/" ) + loc.icon, iconUrl: '/media/icons/locations/' + loc.icon, iconSize: [24,24], iconAnchor: [12,12], shadowUrl: '/media/icons/' + (newIcons ? "new/" : "old/" ) + 'shadow.png', shadowSize: [1,1], shadowAnchor: [12,12], className: "marker" })}); locObj.addTo(map); locationObjs.push(locObj); } } document.getElementById("locations-key").style.display = ""; for (const img of imgs) { let li = document.createElement("li"); let i = document.createElement("img"); i.src = "../media/icons/locations/" + img; i.style.maxWidth = "32px"; i.style.maxHeight = "32px"; li.appendChild(i); let name = img.replace(".png",""); let type = ""; if (name.includes("_")) {type = name.split("_")[0]; name = name.split("_")[1]} name = name.replaceAll(/([A-Z])/g, ` $1`).trim() + (type ? " (" + type + ") ": ""); li.innerHTML = li.innerHTML + name; key_elem.appendChild(li); } console.log("Drew all map locations"); } function deleteLocations() { for (const location of locationObjs) { map.removeLayer(location); } locationObjs = []; key_elem.innerHTML = ""; document.getElementById("locations-key").style.display = "none"; console.log("Erased all map locations"); } drawlocations = !drawlocations; if (drawlocations) {drawLocations()} else {deleteLocations()} } /** 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(`
${terr}
`, {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(`${terr}
${guildTags.get(guild)}