default icons added, crafter disclaimer added, item icons display w/ radial-gradient background w/ tier color

This commit is contained in:
ferricles 2021-01-24 12:33:00 -08:00
commit d9ab1b1ff7
24 changed files with 333 additions and 53 deletions

View file

@ -16,21 +16,25 @@
<div class="center"> <div class="center">
<header class = "header nomarginp"> <header class = "header nomarginp">
<div class = "headerleft"> <div class = "headerleft">
<a href = "." class = "nomarginp iconlink tooltip"> <a href = "./" class = "nomarginp iconlink tooltip">
<img src = "/media/icons/builder.png" class = "left linkoptions headericon"/> <img src = "/media/icons/builder.png" class = "left linkoptions headericon">
</img>
<div class = "tooltiptext center">WynnBuilder</div> <div class = "tooltiptext center">WynnBuilder</div>
</a> </a>
<a href = "./crafter.html" class = "nomarginp iconlink tooltip"> <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> <div class = "tooltiptext center">WynnCrafter</div>
</a> </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>
<div class = "headercenter"> <div class = "headercenter">
<div > <div >
<p class = "itemp" id = "header">Wynn build calculator</p> <p class = "itemp" id = "header">WynnCrafter</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>
</div> </div>
</div> </div>
<div class = "headerright"> <div class = "headerright">

View file

@ -16,7 +16,6 @@ const BUILD_VERSION = "6.9.9";
/* TODO: /* TODO:
Make it craft
Make material tier do something Make material tier do something
Double powders Double powders
Integrate to normal builder Integrate to normal builder
@ -27,8 +26,11 @@ let ingFields = ["fDefPct", "wDefPct", "aDefPct", "tDefPct", "eDefPct", "hprPct"
let player_craft; let player_craft;
function setTitle() { 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"); 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(); setTitle();

View file

@ -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 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 damageClasses = ["Neutral","Earth","Thunder","Water","Fire","Air"];
let reversedIDs = [ "spPct1", "spRaw1", "spPct2", "spRaw2", "spPct3", "spRaw3", "spPct4", "spRaw4" ]; 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){ function expandItem(item, powders){
let minRolls = new Map(); let minRolls = new Map();
@ -546,13 +558,23 @@ function displayExpandedItem(item, parent_id){
if (item.get("tier") !== " ") { if (item.get("tier") !== " ") {
p_elem.classList.add(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"); let b = document.createElement("b");
b.textContent = "[" + item.get("charges") + "/" + item.get("charges") + "]"; b.textContent = "[" + item.get("charges") + "/" + item.get("charges") + "]";
b.classList.add("spaceleft"); b.classList.add("spaceleft");
p_elem.appendChild(b); 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"]; /*let validTypes = ["helmet", "chestplate", "leggings", "boots", "relik", "wand", "bow", "spear", "dagger", "ring", "bracelet", "necklace"];
if (item.has("type") && validTypes.includes(item.get("type"))) { if (item.has("type") && validTypes.includes(item.get("type"))) {
p = document.createElement("p"); p = document.createElement("p");

View file

@ -29,6 +29,11 @@
</img> </img>
<div class = "tooltiptext center">WynnCrafter</div> <div class = "tooltiptext center">WynnCrafter</div>
</a> </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>
<div class = "headercenter"> <div class = "headercenter">
<div > <div >

21
items-narrow.css Normal file
View 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
View 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;
}

View file

@ -1,35 +1,79 @@
<!DOCTYPE html> <!DOCTYPE html>
<html scroll-behavior="smooth"> <html scroll-behavior="smooth">
<head> <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 --> <!-- nunito font, copying wynndata -->
<link rel="preconnect" href="https://fonts.gstatic.com"> <link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Nunito&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Nunito&display=swap" rel="stylesheet">
<link rel="stylesheet" href="styles.css"> <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="icon" href="favicon.png">
<link rel="manifest" href="manifest.json"> <link rel="manifest" href="manifest.json">
<title>Wynn Clientside</title> <title>Wynn Clientside</title>
</head> </head>
<body class="all"> <body class="all">
<div class="header" id="header"> <div class="center">
WynnAtlas <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>
<div class="center" id="header2"> <div class = "headercenter">
Made by: hppeng and ferricles <div >
<p class = "itemp" id = "header">WynnAtlas</p>
</div> </div>
</div>
<div class = "headerright">
</div>
</header>
</div>
<br>
<br>
<div class="itemsearch">
<div class="search">
<div class="center" id="credits"> <div class="center" id="credits">
<a href="credits.txt">Additional credits</a> <a href="translations.txt" class="link">CLICK FOR ID mapping</a>
</div> </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> <button class = "button" id = "search-button" onclick = "doItemSearch()" tabindex="2">
<br> Search Items
<br> </button>
<div class="center" id="main"> <p id="summary">hello</p>
<div class="box" id="test" style="width: 25vw; margin: auto"> </div>
<div class="center" id="test-inner">item</div> <div class="center items" id="main">
</div> </div>
</div> </div>
<script type="text/javascript" src="/utils.js"></script> <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="/damage_calc.js"></script>
<script type="text/javascript" src="/display.js"></script> <script type="text/javascript" src="/display.js"></script>
<script type="text/javascript" src="/query.js"></script> <script type="text/javascript" src="/query.js"></script>

View file

@ -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() { function init() {
return;
let items_copy = items.slice(); let items_copy = items.slice();
let query = new NameQuery("Bob's"); //let query = new NameQuery("Bob's");
items_copy = items_copy.filter(query.filter, query).sort(query.compare); let query1 = new IdQuery("sdRaw");
let item = items_copy[0]; items_copy = applyQuery(items_copy, query1);
console.log(item);
displayExpandedItem(expandItem(item, []), "test"); let query2 = new TypeQuery("helmet");
items_copy = applyQuery(items_copy, query2);
displayItems(items_copy);
} }
load_init(init); load_init(init);

View file

@ -64,7 +64,7 @@ function clean_item(item) {
async function load(init_func) { async function load(init_func) {
let getUrl = window.location; 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 url = baseUrl + "/compress.json";
let result = await (await fetch(url)).json(); let result = await (await fetch(url)).json();
items = result.items; items = result.items;

BIN
media/icons/atlas64.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 750 B

After

Width:  |  Height:  |  Size: 924 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 B

After

Width:  |  Height:  |  Size: 588 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 582 B

After

Width:  |  Height:  |  Size: 590 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 484 B

After

Width:  |  Height:  |  Size: 484 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 B

After

Width:  |  Height:  |  Size: 559 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 B

After

Width:  |  Height:  |  Size: 646 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 B

After

Width:  |  Height:  |  Size: 713 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 435 B

After

Width:  |  Height:  |  Size: 563 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 B

After

Width:  |  Height:  |  Size: 596 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 B

After

Width:  |  Height:  |  Size: 568 B

View file

@ -1,21 +1,57 @@
let queryTypeMap = new Map();
/**
* @description A query into the item
* @module ItemNotFound
*/
class NameQuery { class NameQuery {
constructor(string) { constructor(string) { this.queryString = string.toLowerCase(); }
this.queryString = string;
}
filter(item) { filter(item) {
if (item.remapID === undefined) { if (item.remapID === undefined) {
return (item.displayName.includes(this.queryString)); return (item.displayName.toLowerCase().includes(this.queryString));
} }
return false; return false;
} }
compare(a, b) { compare(a, b) { return 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
View 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",

View file

@ -257086,7 +257086,7 @@
"tier": "Fabled", "tier": "Fabled",
"type": "spear", "type": "spear",
"name": "Rhythm of Seasons", "name": "Rhythm of Seasons",
"displayName": "Rhythm of Seasons", "displayName": "Rhythm of the Seasons",
"set": null, "set": null,
"quest": null, "quest": null,
"classReq": null, "classReq": null,

View file

@ -15,7 +15,7 @@
} }
.sticky-box { .sticky-box {
position: sticky; position: sticky;
top: 0; top: 10px;
} }
.summary { .summary {
padding: 2% 2% 0%; padding: 2% 2% 0%;