default icons added, crafter disclaimer added, item icons display w/ radial-gradient background w/ tier color
18
crafter.html
|
@ -16,21 +16,25 @@
|
|||
<div class="center">
|
||||
<header class = "header nomarginp">
|
||||
<div class = "headerleft">
|
||||
<a href = "." class = "nomarginp iconlink tooltip">
|
||||
<img src = "/media/icons/builder.png" class = "left linkoptions headericon"/>
|
||||
<a href = "./" class = "nomarginp iconlink tooltip">
|
||||
<img src = "/media/icons/builder.png" class = "left linkoptions headericon">
|
||||
</img>
|
||||
<div class = "tooltiptext center">WynnBuilder</div>
|
||||
</a>
|
||||
<a href = "./crafter.html" class = "nomarginp iconlink tooltip">
|
||||
<img src = "/media/icons/crafter.png" class = "left linkoptions headericon"/>
|
||||
<img src = "/media/icons/crafter.png" class = "left linkoptions headericon">
|
||||
</img>
|
||||
<div class = "tooltiptext center">WynnCrafter</div>
|
||||
</a>
|
||||
<a href = "./items.html" class = "nomarginp iconlink tooltip">
|
||||
<img src = "/media/icons/searcher.png" class = "left linkoptions headericon">
|
||||
</img>
|
||||
<div class = "tooltiptext center">WynnAtlas</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class = "headercenter">
|
||||
<div >
|
||||
<p class = "itemp" id = "header">Wynn build calculator</p>
|
||||
<p class="itemp" id="help">
|
||||
<a class = "link" href="https://forums.wynncraft.com/threads/wynnbuilder-release-thread-and-some-damage-calculation-updates.281438">Forum thread (instructions/help)</a>
|
||||
</p>
|
||||
<p class = "itemp" id = "header">WynnCrafter</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class = "headerright">
|
||||
|
|
|
@ -16,7 +16,6 @@ const BUILD_VERSION = "6.9.9";
|
|||
|
||||
|
||||
/* TODO:
|
||||
Make it craft
|
||||
Make material tier do something
|
||||
Double powders
|
||||
Integrate to normal builder
|
||||
|
@ -27,8 +26,11 @@ let ingFields = ["fDefPct", "wDefPct", "aDefPct", "tDefPct", "eDefPct", "hprPct"
|
|||
let player_craft;
|
||||
|
||||
function setTitle() {
|
||||
document.getElementById("header").textContent = "WynnBuilder version "+BUILD_VERSION+" (ingredient db version "+ING_DB_VERSION+")";
|
||||
document.getElementById("header").textContent = "WynnCrafter version "+BUILD_VERSION+" (ingredient db version "+ING_DB_VERSION+")";
|
||||
document.getElementById("header").classList.add("funnynumber");
|
||||
let disclaimer = document.createElement("p");
|
||||
disclaimer.textContent = "THIS CRAFTER IS INCOMPLETE. The effect of material tiers on crated items is not accurate yet. If you know how the math behind it works, please contact ferricles on forums, discord, or ingame.";
|
||||
document.getElementById("header").append(disclaimer);
|
||||
}
|
||||
setTitle();
|
||||
|
||||
|
|
28
display.js
|
@ -2,7 +2,19 @@ let nonRolledIDs = ["name", "displayName", "tier", "set", "slots", "type", "mate
|
|||
let rolledIDs = ["hprPct", "mr", "sdPct", "mdPct", "ls", "ms", "xpb", "lb", "ref", "thorns", "expd", "spd", "atkTier", "poison", "hpBonus", "spRegen", "eSteal", "hprRaw", "sdRaw", "mdRaw", "fDamPct", "wDamPct", "aDamPct", "tDamPct", "eDamPct", "fDefPct", "wDefPct", "aDefPct", "tDefPct", "eDefPct", "spPct1", "spRaw1", "spPct2", "spRaw2", "spPct3", "spRaw3", "spPct4", "spRaw4", "rainbowRaw", "sprint", "sprintReg", "jh", "lq", "gXp", "gSpd"];
|
||||
let damageClasses = ["Neutral","Earth","Thunder","Water","Fire","Air"];
|
||||
let reversedIDs = [ "spPct1", "spRaw1", "spPct2", "spRaw2", "spPct3", "spRaw3", "spPct4", "spRaw4" ];
|
||||
|
||||
let colorMap = new Map(
|
||||
[
|
||||
["Normal", "#fff"],
|
||||
["Unique", "#ff5"],
|
||||
["Rare","#f5f"],
|
||||
["Legendary","#5ff"],
|
||||
["Fabled","#f55"],
|
||||
["Mythic","#a0a"],
|
||||
["Crafted","#0aa"],
|
||||
["Custom","#0aa"],
|
||||
["Set","#5f5"]
|
||||
]
|
||||
);
|
||||
|
||||
function expandItem(item, powders){
|
||||
let minRolls = new Map();
|
||||
|
@ -546,13 +558,23 @@ function displayExpandedItem(item, parent_id){
|
|||
if (item.get("tier") !== " ") {
|
||||
p_elem.classList.add(item.get("tier"));
|
||||
}
|
||||
if (["potion", "scroll", "food"].includes(item.get("type"))){ //must have access to craft.js
|
||||
if (["potion", "scroll", "food"].includes(item.get("type"))){
|
||||
let b = document.createElement("b");
|
||||
b.textContent = "[" + item.get("charges") + "/" + item.get("charges") + "]";
|
||||
b.classList.add("spaceleft");
|
||||
p_elem.appendChild(b);
|
||||
}
|
||||
|
||||
p_elem.append(document.createElement("br"));
|
||||
let img = document.createElement("img");
|
||||
img.src = "/media/items/generic-" + item.get("type") + ".png";
|
||||
img.alt = item.get("type");
|
||||
img.style = " z=index: 1;max-width: 64px; max-height: 64px; position: relative; top: 50%; transform: translateY(-50%);";
|
||||
let bckgrd = document.createElement("p");
|
||||
bckgrd.style = "width: 96px; height: 96px; border-radius: 50%;background-image: radial-gradient(closest-side, " + colorMap.get(item.get("tier")) + " 20%," + "#121516 80%); margin-left: auto; margin-right: auto;"
|
||||
bckgrd.classList.add("center");
|
||||
bckgrd.classList.add("itemp");
|
||||
active_elem.appendChild(bckgrd);
|
||||
bckgrd.appendChild(img);
|
||||
/*let validTypes = ["helmet", "chestplate", "leggings", "boots", "relik", "wand", "bow", "spear", "dagger", "ring", "bracelet", "necklace"];
|
||||
if (item.has("type") && validTypes.includes(item.get("type"))) {
|
||||
p = document.createElement("p");
|
||||
|
|
|
@ -29,6 +29,11 @@
|
|||
</img>
|
||||
<div class = "tooltiptext center">WynnCrafter</div>
|
||||
</a>
|
||||
<a href = "./items.html" class = "nomarginp iconlink tooltip">
|
||||
<img src = "/media/icons/searcher.png" class = "left linkoptions headericon">
|
||||
</img>
|
||||
<div class = "tooltiptext center">WynnAtlas</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class = "headercenter">
|
||||
<div >
|
||||
|
|
21
items-narrow.css
Normal file
|
@ -0,0 +1,21 @@
|
|||
.items {
|
||||
grid-column: 1;
|
||||
padding: 0%;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, 1fr);
|
||||
width: 100%;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.itemsearch {
|
||||
padding: 0%;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
width: 100%;
|
||||
gap: 5px;
|
||||
grid-template-rows: masonry;
|
||||
}
|
||||
|
||||
.search {
|
||||
grid-column: 1;
|
||||
}
|
24
items-wide.css
Normal file
|
@ -0,0 +1,24 @@
|
|||
.items {
|
||||
grid-column: 2;
|
||||
padding: 0%;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||
width: 100%;
|
||||
gap: 5px;
|
||||
grid-template-rows: masonry;
|
||||
}
|
||||
|
||||
.itemsearch {
|
||||
padding: 0%;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 4fr;
|
||||
width: 100%;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.search {
|
||||
grid-column: 1;
|
||||
position: sticky;
|
||||
margin-bottom: auto;
|
||||
top: 10px;
|
||||
}
|
66
items.html
|
@ -1,35 +1,79 @@
|
|||
<!DOCTYPE html>
|
||||
<html scroll-behavior="smooth">
|
||||
<head>
|
||||
<meta name="HandheldFriendly" content="true" />
|
||||
<meta name="MobileOptimized" content="320" />
|
||||
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, width=device-width, user-scalable=no" />
|
||||
<!-- nunito font, copying wynndata -->
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Nunito&display=swap" rel="stylesheet">
|
||||
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
<link rel="stylesheet" media="screen and (min-width: 1100px)" href="items-wide.css"/>
|
||||
<link rel="stylesheet" media="screen and (max-width: 1099px)" href="items-narrow.css"/>
|
||||
<link rel="icon" href="favicon.png">
|
||||
<link rel="manifest" href="manifest.json">
|
||||
<title>Wynn Clientside</title>
|
||||
</head>
|
||||
<body class="all">
|
||||
<div class="header" id="header">
|
||||
WynnAtlas
|
||||
<div class="center">
|
||||
<header class = "header nomarginp">
|
||||
<div class = "headerleft">
|
||||
<a href = "./" class = "nomarginp iconlink tooltip">
|
||||
<img src = "/media/icons/builder.png" class = "left linkoptions headericon">
|
||||
</img>
|
||||
<div class = "tooltiptext center">WynnBuilder</div>
|
||||
</a>
|
||||
<a href = "./crafter.html" class = "nomarginp iconlink tooltip">
|
||||
<img src = "/media/icons/crafter.png" class = "left linkoptions headericon">
|
||||
</img>
|
||||
<div class = "tooltiptext center">WynnCrafter</div>
|
||||
</a>
|
||||
<a href = "./items.html" class = "nomarginp iconlink tooltip">
|
||||
<img src = "/media/icons/searcher.png" class = "left linkoptions headericon">
|
||||
</img>
|
||||
<div class = "tooltiptext center">WynnAtlas</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="center" id="header2">
|
||||
Made by: hppeng and ferricles
|
||||
<div class = "headercenter">
|
||||
<div >
|
||||
<p class = "itemp" id = "header">WynnAtlas</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class = "headerright">
|
||||
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
<br>
|
||||
<br>
|
||||
<div class="itemsearch">
|
||||
<div class="search">
|
||||
<div class="center" id="credits">
|
||||
<a href="credits.txt">Additional credits</a>
|
||||
<a href="translations.txt" class="link">CLICK FOR ID mapping</a>
|
||||
</div>
|
||||
<p>Basic Dumb JSON search</p>
|
||||
<p>Query types:</p>
|
||||
<p>name, type, category, stat</p>
|
||||
<textarea name="query-json" id="query-json" cols="25" rows="25" tabindex="1">
|
||||
[
|
||||
{
|
||||
"queryType": "name",
|
||||
"value": ""
|
||||
}
|
||||
]
|
||||
</textarea>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<div class="center" id="main">
|
||||
<div class="box" id="test" style="width: 25vw; margin: auto">
|
||||
<div class="center" id="test-inner">item</div>
|
||||
<button class = "button" id = "search-button" onclick = "doItemSearch()" tabindex="2">
|
||||
Search Items
|
||||
</button>
|
||||
<p id="summary">hello</p>
|
||||
</div>
|
||||
<div class="center items" id="main">
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="/utils.js"></script>
|
||||
<script type="text/javascript" src="/build_utils.js"></script>
|
||||
<script type="text/javascript" src="/damage_calc.js"></script>
|
||||
<script type="text/javascript" src="/display.js"></script>
|
||||
<script type="text/javascript" src="/query.js"></script>
|
||||
|
|
44
items.js
|
@ -1,11 +1,45 @@
|
|||
|
||||
function applyQuery(items, query) {
|
||||
return items.filter(query.filter, query).sort(query.compare);
|
||||
}
|
||||
|
||||
function displayItems(items_copy) {
|
||||
let items_parent = document.getElementById("main");
|
||||
for (let i in items_copy) {
|
||||
let item = items_copy[i];
|
||||
let box = document.createElement("div");
|
||||
box.classList.add("box");
|
||||
box.id = "item"+i;
|
||||
items_parent.appendChild(box);
|
||||
displayExpandedItem(expandItem(item, []), box.id);
|
||||
}
|
||||
}
|
||||
|
||||
function doItemSearch() {
|
||||
window.scrollTo(0, 0);
|
||||
let input_json = document.getElementById("query-json").value;
|
||||
let input = JSON.parse(input_json);
|
||||
let items_copy = items.slice();
|
||||
document.getElementById("main").textContent = "";
|
||||
for (const _query of input) {
|
||||
const query = queryTypeMap.get(_query.queryType)(_query.value);
|
||||
items_copy = applyQuery(items_copy, query);
|
||||
}
|
||||
document.getElementById("summary").textContent = items_copy.length + " results."
|
||||
displayItems(items_copy);
|
||||
}
|
||||
|
||||
function init() {
|
||||
return;
|
||||
let items_copy = items.slice();
|
||||
let query = new NameQuery("Bob's");
|
||||
items_copy = items_copy.filter(query.filter, query).sort(query.compare);
|
||||
let item = items_copy[0];
|
||||
console.log(item);
|
||||
displayExpandedItem(expandItem(item, []), "test");
|
||||
//let query = new NameQuery("Bob's");
|
||||
let query1 = new IdQuery("sdRaw");
|
||||
items_copy = applyQuery(items_copy, query1);
|
||||
|
||||
let query2 = new TypeQuery("helmet");
|
||||
items_copy = applyQuery(items_copy, query2);
|
||||
|
||||
displayItems(items_copy);
|
||||
}
|
||||
|
||||
load_init(init);
|
||||
|
|
2
load.js
|
@ -64,7 +64,7 @@ function clean_item(item) {
|
|||
async function load(init_func) {
|
||||
|
||||
let getUrl = window.location;
|
||||
let baseUrl = getUrl.protocol + "//" + getUrl.host + "/" + getUrl.pathname.split('/')[1];
|
||||
let baseUrl = getUrl.protocol + "//" + getUrl.host + "/";// + getUrl.pathname.split('/')[1];
|
||||
let url = baseUrl + "/compress.json";
|
||||
let result = await (await fetch(url)).json();
|
||||
items = result.items;
|
||||
|
|
BIN
media/icons/atlas64.png
Executable file
After Width: | Height: | Size: 358 B |
Before Width: | Height: | Size: 750 B After Width: | Height: | Size: 924 B |
Before Width: | Height: | Size: 109 B After Width: | Height: | Size: 588 B |
Before Width: | Height: | Size: 582 B After Width: | Height: | Size: 590 B |
Before Width: | Height: | Size: 484 B After Width: | Height: | Size: 484 B |
Before Width: | Height: | Size: 109 B After Width: | Height: | Size: 559 B |
Before Width: | Height: | Size: 88 B After Width: | Height: | Size: 646 B |
Before Width: | Height: | Size: 109 B After Width: | Height: | Size: 713 B |
Before Width: | Height: | Size: 435 B After Width: | Height: | Size: 563 B |
Before Width: | Height: | Size: 109 B After Width: | Height: | Size: 596 B |
Before Width: | Height: | Size: 109 B After Width: | Height: | Size: 568 B |
56
query.js
|
@ -1,21 +1,57 @@
|
|||
let queryTypeMap = new Map();
|
||||
|
||||
/**
|
||||
* @description A query into the item
|
||||
* @module ItemNotFound
|
||||
*/
|
||||
class NameQuery {
|
||||
constructor(string) {
|
||||
this.queryString = string;
|
||||
}
|
||||
constructor(string) { this.queryString = string.toLowerCase(); }
|
||||
|
||||
filter(item) {
|
||||
if (item.remapID === undefined) {
|
||||
return (item.displayName.includes(this.queryString));
|
||||
return (item.displayName.toLowerCase().includes(this.queryString));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
compare(a, b) {
|
||||
return a < b;
|
||||
compare(a, b) { return a < b; }
|
||||
}
|
||||
queryTypeMap.set("name", function(s) { return new NameQuery(s); } );
|
||||
|
||||
class TypeQuery {
|
||||
constructor(type) { this.type = type; }
|
||||
|
||||
filter(item) {
|
||||
if (item.remapID === undefined) {
|
||||
return (item.type === this.type);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
compare(a, b) { return a < b; }
|
||||
}
|
||||
queryTypeMap.set("type", function(s) { return new TypeQuery(s); } );
|
||||
|
||||
class CategoryQuery {
|
||||
constructor(category) { this.category = category; }
|
||||
|
||||
filter(item) {
|
||||
if (item.remapID === undefined) {
|
||||
return (item.category === this.category);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
compare(a, b) { return a < b; }
|
||||
}
|
||||
queryTypeMap.set("category", function(s) { return new CategoryQuery(s); } );
|
||||
|
||||
class IdQuery {
|
||||
constructor(id) {
|
||||
this.id = id;
|
||||
this.compare = function(a, b) {
|
||||
return b[id] - a[id];
|
||||
};
|
||||
}
|
||||
|
||||
filter(item) {
|
||||
return (this.id in item) && (item[this.id]);
|
||||
}
|
||||
}
|
||||
queryTypeMap.set("stat", function(s) { return new IdQuery(s); } );
|
||||
|
|
88
translations.txt
Normal file
|
@ -0,0 +1,88 @@
|
|||
Mapping from API name to shortened names
|
||||
|
||||
"name": "name",
|
||||
"displayName": "displayName",
|
||||
"tier": "tier",
|
||||
"set": "set",
|
||||
"sockets": "slots",
|
||||
"type": "type",
|
||||
"dropType": "drop",
|
||||
"quest": "quest",
|
||||
"restrictions": "restrict",
|
||||
"damage": "nDam",
|
||||
"fireDamage": "fDam",
|
||||
"waterDamage": "wDam",
|
||||
"airDamage": "aDam",
|
||||
"thunderDamage": "tDam",
|
||||
"earthDamage": "eDam",
|
||||
"attackSpeed": "atkSpd",
|
||||
"health": "hp",
|
||||
"fireDefense": "fDef",
|
||||
"waterDefense": "wDef",
|
||||
"airDefense": "aDef",
|
||||
"thunderDefense": "tDef",
|
||||
"earthDefense": "eDef",
|
||||
"level": "lvl",
|
||||
"classRequirement": "classReq",
|
||||
"strength": "strReq",
|
||||
"dexterity": "dexReq",
|
||||
"intelligence": "intReq",
|
||||
"agility": "agiReq",
|
||||
"defense": "defReq",
|
||||
"healthRegen": "hprPct",
|
||||
"manaRegen": "mr",
|
||||
"spellDamage": "sdPct",
|
||||
"damageBonus": "mdPct",
|
||||
"lifeSteal": "ls",
|
||||
"manaSteal": "ms",
|
||||
"xpBonus": "xpb",
|
||||
"lootBonus": "lb",
|
||||
"reflection": "ref",
|
||||
"strengthPoints": "str",
|
||||
"dexterityPoints": "dex",
|
||||
"intelligencePoints": "int",
|
||||
"agilityPoints": "agi",
|
||||
"defensePoints": "def",
|
||||
"thorns": "thorns",
|
||||
"exploding": "expd",
|
||||
"speed": "spd",
|
||||
"attackSpeedBonus": "atkTier",
|
||||
"poison": "poison",
|
||||
"healthBonus": "hpBonus",
|
||||
"soulPoints": "spRegen",
|
||||
"emeraldStealing": "eSteal",
|
||||
"healthRegenRaw": "hprRaw",
|
||||
"spellDamageRaw": "sdRaw",
|
||||
"damageBonusRaw": "mdRaw",
|
||||
"bonusFireDamage": "fDamPct",
|
||||
"bonusWaterDamage": "wDamPct",
|
||||
"bonusAirDamage": "aDamPct",
|
||||
"bonusThunderDamage": "tDamPct",
|
||||
"bonusEarthDamage": "eDamPct",
|
||||
"bonusFireDefense": "fDefPct",
|
||||
"bonusWaterDefense": "wDefPct",
|
||||
"bonusAirDefense": "aDefPct",
|
||||
"bonusThunderDefense": "tDefPct",
|
||||
"bonusEarthDefense": "eDefPct",
|
||||
"accessoryType": "type",
|
||||
"identified": "fixID",
|
||||
"skin": "skin",
|
||||
"category": "category",
|
||||
|
||||
"spellCostPct1": "spPct1",
|
||||
"spellCostRaw1": "spRaw1",
|
||||
"spellCostPct2": "spPct2",
|
||||
"spellCostRaw2": "spRaw2",
|
||||
"spellCostPct3": "spPct3",
|
||||
"spellCostRaw3": "spRaw3",
|
||||
"spellCostPct4": "spPct4",
|
||||
"spellCostRaw4": "spRaw4",
|
||||
|
||||
"rainbowSpellDamageRaw": "rainbowRaw",
|
||||
"sprint": "sprint",
|
||||
"sprintRegen": "sprintReg",
|
||||
"jumpHeight": "jh",
|
||||
"lootQuality": "lq",
|
||||
|
||||
"gatherXpBonus": "gXp",
|
||||
"gatherSpeed": "gSpd",
|
|
@ -257086,7 +257086,7 @@
|
|||
"tier": "Fabled",
|
||||
"type": "spear",
|
||||
"name": "Rhythm of Seasons",
|
||||
"displayName": "Rhythm of Seasons",
|
||||
"displayName": "Rhythm of the Seasons",
|
||||
"set": null,
|
||||
"quest": null,
|
||||
"classReq": null,
|
||||
|
|
2
wide.css
|
@ -15,7 +15,7 @@
|
|||
}
|
||||
.sticky-box {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
top: 10px;
|
||||
}
|
||||
.summary {
|
||||
padding: 2% 2% 0%;
|
||||
|
|