map guild functionality complete

This commit is contained in:
ferricles 2021-03-15 22:40:05 -07:00
parent 8905d949fb
commit aa89a43c12
28 changed files with 15638 additions and 37 deletions

View file

@ -34,8 +34,25 @@ function atlasClick() {
atlas_img.src = "favicon.png";
atlas_img.style.width = "100%";
atlas_img.style.height = "100%";
atlas_img.style.maxWidth = "48px";
atlas_img.style.maxHeight = "48px";
atlas_img.style.zIndex = 1;
atlas.classList.add("atlas");
let roll = Math.random();
let rollchance = 0.03;
if (roll < rollchance) {
atlas_img.src = "/media/memes/lmoa.png";
} else if (roll < 2*rollchance) {
atlas_img.src = "/media/memes/doom.png";
} else if (roll < 3*rollchance) {
atlas_img.src = "/media/memes/agony.png";
} else if (roll < 4*rollchance) {
atlas_img.src = "/media/memes/enraged.png";
} else if (roll < 5*rollchance) {
atlas_img.src = "/media/memes/sunglaso.png";
} else if (roll < 6*rollchance) {
atlas_img.src = "/media/memes/thonk.png";
}
atlas.appendChild(atlas_img);
atlas.style = "background-image: radial-gradient(closest-side, #" + Math.round(255*Math.random()).toString(16)+Math.round(255*Math.random()).toString(16)+Math.round(255*Math.random()).toString(16) + " 0%," + "#121516 120%);";

View file

@ -115,7 +115,6 @@ for (let x in special_mappings) {
itemFilters.appendChild(el);
}
let itemTypes = [ "helmet", "chestplate", "leggings", "boots", "ring", "bracelet", "necklace", "wand", "spear", "bow", "dagger", "relik" ];
let itemCategories = [ "armor", "accessory", "weapon" ];
function applyQuery(items, query) {

View file

@ -8,7 +8,6 @@ let sets;
let itemMap;
let idMap;
let redirectMap;
let itemTypes = armorTypes.concat(accessoryTypes).concat(weaponTypes);
let itemLists = new Map();
/*
* Load item set from local DB. Calls init() on success.

View file

@ -61,7 +61,7 @@ async function load_ings(init_func) {
let getUrl = window.location;
let baseUrl = getUrl.protocol + "//" + getUrl.host + "/" + getUrl.pathname.split('/')[1];
let url = baseUrl + "/ingreds_compress.json";
url = url.replace("/crafter.html", ""); //JANK
url = url.replace(/\w+.html/, "") ;
let result = await (await fetch(url)).json();
result = await (await fetch(url)).json();

123
load_map.js Normal file
View file

@ -0,0 +1,123 @@
const MAP_DB_VERSION = 1;
// @See https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/indexeddb/video-store/index.js
let mdb;
let mreload = false;
var terrs = new Map(); //terr name : location: rectangle def {startX, startY, endX, endY
var claims = new Map(); //terr name: guild name
var neighbors = new Map(); //terr name: [neighbor names]
var resources = new Map(); //terr name: Map({emeralds: bool, doubleemeralds: bool, doubleresource: bool, resources: [], storage: []})
var terrdata;
/*
* Load item set from local DB. Calls init() on success.
*/
async function map_load_local(init_func) {
let get_tx = mdb.transaction(['map_db'], 'readonly');
let map_store = get_tx.objectStore('map_db');
let request5 = map_store.getAll();
request5.onerror = function(event) {
console.log("Could not read local map db...");
}
request5.onsuccess = function(event) {
console.log("Successfully read local map db.");
terrdata = request5.result;
init_map_maps();
init_func();
}
await get_tx.complete;
mdb.close();
}
/*
* Load item set from remote DB (aka a big json file). Calls init() on success.
*/
async function load_map(init_func) {
let getUrl = window.location;
let baseUrl = getUrl.protocol + "//" + getUrl.host + "/" + getUrl.pathname.split('/')[1];
let url = baseUrl + "/terrs_compress.json";
url = url.replace(/\w+.html/, "") ;
let result = await (await fetch(url)).json();
result = await (await fetch(url)).json();
terrdata = result;
console.log(terrdata);
// https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore/clear
/*let clear_tx2 = db.transaction(['ing_db'], 'readwrite');
let clear_ings = clear_tx2.objectStore('ing_db');
let clear_tx3 = db.transaction(['recipe_db'], 'readwrite');
let clear_recipes = clear_tx3.objectStore('recipe_db');
await clear_ings.clear();
await clear_recipes.clear();
await clear_tx2.complete;
await clear_tx3.complete;*/
let add_promises = [];
let add_tx2 = mdb.transaction(['map_db'], 'readwrite');
let map_store = add_tx2.objectStore('map_db');
console.log(map_store);
for (const terr of Object.entries(terrdata)) {
add_promises.push(map_store.add(terr[1],terr[0])); //WHY? WHY WOULD YOU STORE AS VALUE, KEY? WHY NOT KEEP THE NORMAL KEY, VALUE CONVENTION?
}
add_promises.push(add_tx2.complete);
Promise.all(add_promises).then((values) => {
mdb.close();
init_map_maps();
init_func();
});
}
function load_map_init(init_func) {
//uncomment below line to force reload
//window.indexedDB.deleteDatabase("map_db", MAP_DB_VERSION)
let request = window.indexedDB.open("map_db", MAP_DB_VERSION)
request.onerror = function() {
console.log("DB failed to open...");
}
request.onsuccess = function() {
mdb = request.result;
if (!mreload) {
console.log("Using stored data...")
map_load_local(init_func);
}
else {
console.log("Using new data...")
load_map(init_func);
}
}
request.onupgradeneeded = function(e) {
mreload = true;
let mdb = e.target.result;
try {
mdb.deleteObjectStore('map_db');
}
catch (error) {
console.log("Could not delete map DB. This is probably fine");
}
mdb.createObjectStore('map_db');
console.log("DB setup complete...");
}
}
function init_map_maps() {
for (const [terr,data] of Object.entries(terrdata)) {
terrs.set(data.territory,data.location);
claims.set(data.territory,data.guild);
if (!guilds.includes(data.guild)) {
guilds.push(data.guild);
}
neighbors.set(data.territory,data.neighbors);
resources.set(data.territory,{"resources":data.resources,"storage":data.storage,"emeralds":data.emeralds,"doubleemeralds":data.doubleemeralds,"doubleresource":data.doubleresource});
}
}

View file

@ -1,6 +1,10 @@
.mapdiv{
height: 100vh;
height: 99vh;
background: #121516;
width: 90vw;
}
.overall-container{
margin-bottom: 10px;
}
.container{
width: 95%;
@ -12,5 +16,59 @@
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-column-gap: 5px;
grid-auto-rows: minmax(60px, auto);
grid-auto-rows: minmax(32px, auto);
}
.leaflet-tooltip.labelp {
font-family: 'Nunito', sans-serif;
white-space: nowrap;
border: 0;
margin: 0;
padding: 0;
border-radius: 0;
border: rgba(0,0,0,0);
background-color: rgba(0,0,0,0);
display: block;
box-sizing: border-box;
box-shadow: none;
text-align: center;
text-shadow: 1px 1px 0 #000, -1px 1px 0 #000, -1px -1px 0 #000, 1px -1px 0 #000, 0 0 1px #000;
}
.labelp {
position: relative;
word-break: break-word;
overflow-wrap: break-word;
}
.leaflet-tooltip-left {
border-left-color: transparent;
}
.leaflet-tooltip-right{
border-right-color: transparent;
}
.Emeralds{
border:2px solid #4ae024;
}
.Ore{
border:2px solid #7d7b74;
}
.Wood{
border:2px solid #855E42;
}
.Crops{
border:2px solid #e3cea6;
}
.Fish{
border:2px solid #a6d8e3;
}
.resourceimg {
border-radius: 2px;
z-index: 20000000;
}
.marker {
z-index: 200000000;
}
.nomargin{
margin-top: 2px;
margin-bottom: 2px;
}

View file

@ -1,5 +1,5 @@
.mapdiv{
height: 100vh;
height: 99vh;
background: #121516;
}
.overall-container {
@ -7,16 +7,70 @@
grid-template-columns: 80% 20%;
grid-column-gap: 5px;
grid-auto-rows: minmax(60px, auto);
margin-bottom: 10px;
}
.coord-container {
display: grid;
grid-template-columns: 30% 30% 30%;
grid-column-gap: 5px;
grid-auto-rows: minmax(60px, auto);
grid-auto-rows: minmax(32px, auto);
}
.container{
width: 95%;
border: 3px solid #BCBCBC;
border-radius: 3px;
border-radius: 3px;
}
.leaflet-tooltip.labelp {
font-family: 'Nunito', sans-serif;
font-size: 1.1em;
white-space: nowrap;
border: 0;
margin: 0;
padding: 0;
border-radius: 0;
border: rgba(0,0,0,0);
background-color: rgba(0,0,0,0);
box-sizing: border-box;
box-shadow: none;
text-align: center;
text-shadow: 1px 1px 0 #000, -1px 1px 0 #000, -1px -1px 0 #000, 1px -1px 0 #000, 0 0 1px #000;
}
.labelp {
position: relative;
overflow-wrap: break-word;
}
.leaflet-tooltip-left {
border-left-color: transparent;
}
.leaflet-tooltip-right{
border-right-color: transparent;
}
.Emeralds{
border:2px solid #4ae024;
}
.Ore{
border:2px solid #7d7b74;
}
.Wood{
border:2px solid #855E42;
}
.Crops{
border:2px solid #e3cea6;
}
.Fish{
border:2px solid #a6d8e3;
}
.resourceimg {
border-radius: 2px;
z-index: 20000000;
}
.marker{
z-index: 200000000;
}
.nomargin{
margin-top: 2px;
margin-bottom: 2px;
}

View file

@ -11,9 +11,9 @@
<link rel="stylesheet" href="styles.css">
<link rel="stylesheet" media="screen and (min-width: 1100px)" href="map-wide.css"/>
<link rel="stylesheet" media="screen and (max-width: 1099px)" href="map-narrow.css"/>
<link rel="icon" href="./favicon.png">
<link rel="stylesheet" media="screen and (min-width: 900px)" href="map-wide.css"/>
<link rel="stylesheet" media="screen and (max-width: 899px)" href="map-narrow.css"/>
<link rel="icon" href="./media/icons/compass2.png">
<link rel="manifest" href="manifest.json">
<!--Leaflet for map-->
@ -74,27 +74,75 @@
</div>
<div id = "mapoptions-container" class = "container" display = "grid-item-2">
<div id = "coord-container" class = "center coord-container" display = "grid">
<div></div>
<p class = "title center">Options</p>
<div></div>
<div display = "grid-item-1">X</div>
<div display = "grid-item-2"></div>
<div display = "grid-item-3">Z</div>
<div id = "coord-x" display = "grid-item-4"></div>
<div id = "coord-img" display = "grid-item-5">
<p class = "nomargin"></p>
<p class = "title center nomargin">Options</p>
<p class = "nomargin"></p>
<p class = "nomargin" display = "grid-item-1">X</p>
<p class = "nomargin" display = "grid-item-2"></p>
<p class = "nomargin" display = "grid-item-3">Z</p>
<p class = "nomargin" id = "coord-x" display = "grid-item-4"></p>
<p class = "nomargin" id = "coord-img" display = "grid-item-5">
<img src = "/media/icons/compass2.png" alt style = "max-width:32px; max-height:32px"/>
</div>
<div id = "coord-z" display = "grid-item-6"></div>
<div id = "marker-coord-x" display = "none"></div>
<div id = "marker-coord-img" display = "none">
</p>
<p class = "nomargin" id = "coord-z" display = "grid-item-6"></p>
<p class = "nomargin" id = "marker-coord-x" display = "none"></p>
<p class = "nomargin" id = "marker-coord-img" display = "none">
<img src = "/media/icons/marker.png" alt style = "max-width:32px; max-height:32px"/>
</div>
<div id = "marker-coord-z" display = "none"></div>
</p>
<p class = "nomargin" id = "marker-coord-z" display = "none"></p>
</div>
<div id = "button-choices container">
<button class = "left" id = "territories-button" onclick = "toggleButton('territories-button'); toggleTerritories()">Show Territories</button>
<button class = "left" id = "claims-button" onclick = "toggleButton('claims-button'); toggleClaims()">Show Claims</button>
<button class = "left" id = "routes-button" onclick = "toggleButton('routes-button'); toggleRoutes()">Show Routes</button>
<button class = "left" id = "resources-button" onclick = "toggleButton('resources-button'); toggleResources()">Show Resources</button>
<!--button id = "merchants-button" onclick = "toggleButton('merchants-button'); toggleMerchants()">Show Merchants</button-->
<button class = "left" id = "pull-button" onclick = "refreshData()">Refresh Data</button>
<p class = "left" style = "color:red">Do NOT refresh too often.</p>
</div>
<div id ="territory-stats">
</div>
</div>
</div>
<div id = "key-container" class = "container">
<div id = "key-title" class = "center">
<p class = "center title"> All Keys </p>
</div>
<table>
<tr>
<td>
<div id = "guild-key" style = "display:none">
<p class = "left">Guild Key:</p>
<ul id = "guildkeylist">
</ul>
</div>
</td>
<td>
<div id = "resources-key" style = "display:none">
<p class = "left">Resource Key:</p>
<ul id = "resourcelist">
<li><img src= "media/icons/Emeralds.png" style ="max-width:16px;max-height:16px" class = "Emeralds"/> Emeralds</li>
<li><img src= "media/icons/Ore.png" style ="max-width:16px;max-height:16px" class = "Ore"/> Ore</li>
<li><img src= "media/icons/Wood.png" style ="max-width:16px;max-height:16px" class = "Wood"/> Wood</li>
<li><img src= "media/icons/Crops.png" style ="max-width:16px;max-height:16px" class = "Crops"/> Crops</li>
<li><img src= "media/icons/Fish.png" style ="max-width:16px;max-height:16px" class = "Fish"/> Fish</li>
<li><img src= "media/icons/Chest.png" style ="max-width:16px;max-height:16px" class = "Wood"/> Storage</li>
<li><img src= "media/icons/Gears.png" style ="max-width:16px;max-height:16px" class = "Ore"/> Production</li>
<li>Double image means double generation</li>
</ul>
</div>
</td>
</tr>
</table>
</div>
<script type = "text/javascript" src="utils.js"></script>
<script type = "text/javascript" src="load_map.js"></script>
<script type = "text/javascript" src="map.js"></script>
</body>
</html>

406
map.js
View file

@ -27,18 +27,39 @@ setTitle();
var map;
var image;
let terrs = [];
let claims = [];
var marker;
let markers = [];
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(){
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");
@ -85,9 +106,25 @@ function init(){
}
});
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.
@ -108,17 +145,18 @@ function placeMarker(lat, lng) {
shadowUrl: '/media/icons/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");
mcdx.style.display = "grid-item-8";
mcdi.style.display = "grid-item-8";
let mcdz = document.getElementById("marker-coord-z");
mcdz.textContent = coords[1];
mcdx.style.display = "grid-item-9";
location.hash = coords[0] + "," + coords[1]
mcdz.style.display = "grid-item-9";
location.hash = coords[0] + "," + coords[1];
marker.addTo(map);
}
@ -134,4 +172,352 @@ function latlngtoxy(lat, lng) {
return [lng-2392, -lat-123]; //x, y
}
init();
/** 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/"+resource+".png", imgBounds, {className: `${resource} resourceimg`}).addTo(map);
resourceObjs.push(resourceObj);
}
let gearObj = L.imageOverlay("/media/icons/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/"+storage+".png", imgBounds, {alt: `${storage}`, className: `${storage} resourceimg`}).addTo(map);
resourceObjs.push(resourceObj);
}
let chestObj = L.imageOverlay("/media/icons/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);

BIN
media/icons/Chest.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
media/icons/Crops.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
media/icons/Emeralds.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 478 B

BIN
media/icons/Fish.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
media/icons/Gears.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
media/icons/Ore.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 470 B

BIN
media/icons/Wood.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
media/memes/agony.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
media/memes/doom.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
media/memes/enraged.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
media/memes/lmoa.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

BIN
media/memes/sunglaso.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4 KiB

BIN
media/memes/thonk.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

1
terrs.json Normal file

File diff suppressed because one or more lines are too long

53
terrs.py Normal file
View file

@ -0,0 +1,53 @@
import requests
import json
import time
#used for requesting the api
'''response = requests.get("https://api.wynncraft.com/public_api.php?action=territoryList")
with open("terrs.json", "w") as outfile:
outfile.write(json.dumps(response.json()))'''
#used for cleaning the data
'''with open("terrs.json", "r") as infile:
data = json.load(infile)
data = data["territories"]
delkeys = ["territory","acquired","attacker"]
for t in data:
for key in delkeys:
del data[t][key]
data[t]["neighbors"] = []
with open("terrs_compress.json", "w") as outfile:
json.dump(data,outfile)
with open("terrs_clean.json", "w") as outfile:
json.dump(data,outfile,indent = 2)'''
#used for pushing data to compress (edit in clean, move to compress)
'''with open("terrs.json", "r") as infile:
data = json.load(infile)["territories"]'''
with open("terrs_clean.json", "r") as infile:
newdata = json.load(infile)
'''for t in newdata:
del newdata[t]["attacker"]
del newdata[t]["acquired"]'''
'''response = requests.get("https://gist.githubusercontent.com/kristofbolyai/87ae828ecc740424c0f4b3749b2287ed/raw/0735f2e8bb2d2177ba0e7e96ade421621070a236/territories.json").json()
for t in data:
data[t]["neighbors"] = response[t]["Routes"]
data[t]["resources"] = response[t]["Resources"]
data[t]["storage"] = response[t]["Storage"]
data[t]["emeralds"] = response[t]["Emeralds"]
data[t]["doubleemeralds"] = response[t]["DoubleEmerald"]
data[t]["doubleresource"] = response[t]["DoubleResource"]'''
with open("terrs_clean.json", "w") as outfile:
json.dump(newdata,outfile,indent=2)
with open("terrs_compress.json", "w") as outfile:
json.dump(newdata,outfile)

10727
terrs_clean.json Normal file

File diff suppressed because it is too large Load diff

4062
terrs_clean_backup.json Normal file

File diff suppressed because it is too large Load diff

1
terrs_compress.json Normal file

File diff suppressed because one or more lines are too long

View file

@ -14,6 +14,7 @@ const attackSpeeds = ["SUPER_SLOW", "VERY_SLOW", "SLOW", "NORMAL", "FAST", "VERY
const classes = ["Warrior", "Assassin", "Mage", "Archer", "Shaman"];
const tiers = ["Normal", "Unique", "Rare", "Legendary", "Fabled", "Mythic", "Set", "Crafted"] //I'm not sure why you would make a custom crafted but if you do you should be able to use it w/ the correct powder formula
const types = armorTypes.concat(accessoryTypes).concat(weaponTypes).concat(consumableTypes).map(x => x.substring(0,1).toUpperCase() + x.substring(1));
let itemTypes = armorTypes.concat(accessoryTypes).concat(weaponTypes);
let elementIcons = ["\u2724","\u2726", "\u2749", "\u2739", "\u274b" ];
let skpReqs = skp_order.map(x => x + "Req");
@ -235,3 +236,75 @@ function copyTextToClipboard(text) {
});
}
/** Generates a random color using the #(R)(G)(B) format. Not written by wynnbuilder devs.
*
*/
function randomColor() {
var letters = '0123456789abcdef';
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
/** Generates a random color, but lightning must be relatively high (>0.5).
*
* @returns a random color in RGB 6-bit form.
*/
function randomColorLight() {
return randomColorHSL([0,1],[0,1],[0.5,1]);
}
/** Generates a random color given HSL restrictions.
*
* @returns a random color in RGB 6-bit form.
*/
function randomColorHSL(h,s,l) {
var letters = '0123456789abcdef';
let h_var = h[0] + (h[1]-h[0])*Math.random(); //hue
let s_var = s[0] + (s[1]-s[0])*Math.random(); //saturation
let l_var = l[0] + (l[1]-l[0])*Math.random(); //lightness
let rgb = hslToRgb(h_var,s_var,l_var);
let color = "#";
for (const c of rgb) {
color += letters[Math.floor(c/16)] + letters[c%16];
}
return color;
}
/**
* Converts an HSL color value to RGB. Conversion formula
* adapted from http://en.wikipedia.org/wiki/HSL_color_space.
* Assumes h, s, and l are contained in the set [0, 1] and
* returns r, g, and b in the set [0, 255]. Not written by wynnbuilder devs.
*
* @param {number} h The hue
* @param {number} s The saturation
* @param {number} l The lightness
* @return {Array} The RGB representation
*/
function hslToRgb(h, s, l){
var r, g, b;
if(s == 0){
r = g = b = l; // achromatic
}else{
var hue2rgb = function hue2rgb(p, q, t){
if(t < 0) t += 1;
if(t > 1) t -= 1;
if(t < 1/6) return p + (q - p) * 6 * t;
if(t < 1/2) return q;
if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
return p;
}
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = hue2rgb(p, q, h + 1/3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1/3);
}
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
}