Item search kinda
This commit is contained in:
parent
151e847c81
commit
f84d8b5958
9 changed files with 318 additions and 177 deletions
File diff suppressed because one or more lines are too long
|
@ -1,21 +0,0 @@
|
|||
.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;
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
.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;
|
||||
}
|
99
items.html
99
items.html
|
@ -9,6 +9,7 @@
|
|||
<link href="https://fonts.googleapis.com/css2?family=Nunito&display=swap" rel="stylesheet">
|
||||
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
<link rel="stylesheet" href="items.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">
|
||||
|
@ -48,26 +49,86 @@
|
|||
<br>
|
||||
<br>
|
||||
<div class="itemsearch">
|
||||
<div class="search">
|
||||
<div class="center" id="credits">
|
||||
<a href="translations.txt" class="link">CLICK FOR ID mapping</a>
|
||||
<div class="searchbox">
|
||||
<div class="left">
|
||||
<label for="name-choice">Name:</label><br>
|
||||
<input class="searchinput" type="text" id="name-choice" name="name-choice" placeholder="Item name (case insensitive)" tabindex="1"/>
|
||||
<p class="error"></p>
|
||||
</div>
|
||||
<div class="left">
|
||||
<label for="category-choice">Category:</label><br>
|
||||
<input class="searchinput" list="category-items" id="category-choice" name="category-choice" placeholder="ALL" tabindex="2"/>
|
||||
<datalist id="category-items">
|
||||
<option value="ALL">
|
||||
<option value="armor">
|
||||
<option value="helmet">
|
||||
<option value="chestplate">
|
||||
<option value="leggings">
|
||||
<option value="boots">
|
||||
<option value="accessory">
|
||||
<option value="ring">
|
||||
<option value="bracelet">
|
||||
<option value="necklace">
|
||||
<option value="weapon">
|
||||
<option value="wand">
|
||||
<option value="spear">
|
||||
<option value="bow">
|
||||
<option value="dagger">
|
||||
<option value="relik">
|
||||
</datalist>
|
||||
<p class="error"></p>
|
||||
</div>
|
||||
<div class="left">
|
||||
<label for="rarity-choice">Rarity:</label><br>
|
||||
<input class="searchinput" list="rarity-items" id="rarity-choice" name="rarity-choice" placeholder="ANY" tabindex="3"/>
|
||||
<datalist id="rarity-items">
|
||||
<option value="ANY">
|
||||
<option value="Normal">
|
||||
<option value="Unique">
|
||||
<option value="Rare">
|
||||
<option value="Legendary">
|
||||
<option value="Fabled">
|
||||
<option value="Mythic">
|
||||
<option value="Sane">
|
||||
</datalist>
|
||||
<p class="error"></p>
|
||||
</div>
|
||||
<div class="left">
|
||||
<label for="level-choice">Level:</label><br>
|
||||
<input class="searchinput" type="text" id="level-choice" name="level-choice" value="1-106" tabindex="4"/>
|
||||
<p class="error"></p>
|
||||
</div>
|
||||
|
||||
<datalist id="filter-items">
|
||||
</datalist>
|
||||
<div class="left">
|
||||
<label for="filter1-choice">Filter 1:</label><br>
|
||||
<input class="searchinput" list="filter-items" id="filter1-choice" name="filter1-choice" placeholder="ANY" tabindex="5"/>
|
||||
<p class="error"></p>
|
||||
</div>
|
||||
<div class="left">
|
||||
<label for="filter2-choice">Filter 2:</label><br>
|
||||
<input class="searchinput" list="filter-items" id="filter2-choice" name="filter2-choice" placeholder="ANY" tabindex="6"/>
|
||||
<p class="error"></p>
|
||||
</div>
|
||||
<div class="left">
|
||||
<label for="filter3-choice">Filter 3:</label><br>
|
||||
<input class="searchinput" list="filter-items" id="filter3-choice" name="filter3-choice" placeholder="ANY" tabindex="7"/>
|
||||
<p class="error"></p>
|
||||
</div>
|
||||
<div class="left">
|
||||
<label for="filter4-choice">Filter 4:</label><br>
|
||||
<input class="searchinput" list="filter-items" id="filter4-choice" name="filter4-choice" placeholder="ANY" tabindex="8"/>
|
||||
<p class="error"></p>
|
||||
</div>
|
||||
<div class="right" style="grid-column:1/span 2">
|
||||
<button class = "button" id = "search-button" onclick = "doItemSearch()" tabindex="9">
|
||||
Search!
|
||||
</button>
|
||||
</div>
|
||||
<div id="summary" class="left" style="grid-column:3/span 2">
|
||||
Hello!
|
||||
</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>
|
||||
<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>
|
||||
|
|
162
items.js
162
items.js
|
@ -1,4 +1,123 @@
|
|||
|
||||
const translate_mappings = {
|
||||
//"Name": "name",
|
||||
//"Display Name": "displayName",
|
||||
//"tier"Tier": ",
|
||||
//"Set": "set",
|
||||
"Powder Slots": "slots",
|
||||
//"Type": "type",
|
||||
//"armorType", (deleted)
|
||||
//"color", (deleted)
|
||||
//"lore", (deleted)
|
||||
//"material", (deleted)
|
||||
"Drop type": "drop",
|
||||
"Quest requirement": "quest",
|
||||
"Restriction": "restrict",
|
||||
//"Base Neutral Damage": "nDam",
|
||||
//"Base Fire Damage": "fDam",
|
||||
//"Base Water Damage": "wDam",
|
||||
//"Base Air Damage": "aDam",
|
||||
//"Base Thunder Damage": "tDam",
|
||||
//"Base Earth Damage": "eDam",
|
||||
//"Base Attack Speed": "atkSpd",
|
||||
"Health": "hp",
|
||||
"Raw Fire Defense": "fDef",
|
||||
"Raw Water Defense": "wDef",
|
||||
"Raw Air Defense": "aDef",
|
||||
"Raw Thunder Defense": "tDef",
|
||||
"Raw Earth Defense": "eDef",
|
||||
"Combat Level": "lvl",
|
||||
//"Class Requirement": "classReq",
|
||||
"Req Strength": "strReq",
|
||||
"Req Dexterity": "dexReq",
|
||||
"Req Intelligence": "intReq",
|
||||
"Req Agility": "agiReq",
|
||||
"Req Defense": "defReq",
|
||||
"% Health Regen": "hprPct",
|
||||
"Mana Regen": "mr",
|
||||
"% Spell Damage": "sdPct",
|
||||
"% Melee Damage": "mdPct",
|
||||
"Life Steal": "ls",
|
||||
"Mana Steal": "ms",
|
||||
"XP Bonus": "xpb",
|
||||
"Loot Bonus": "lb",
|
||||
"Reflection": "ref",
|
||||
"Strength": "str",
|
||||
"Dexterity": "dex",
|
||||
"Intelligence": "int",
|
||||
"Agility": "agi",
|
||||
"Defense": "def",
|
||||
"Thorns": "thorns",
|
||||
"Exploding": "expd",
|
||||
"Walk Speed": "spd",
|
||||
"Attack Speed Bonus": "atkTier",
|
||||
"Poison": "poison",
|
||||
"Health Bonus": "hpBonus",
|
||||
"Soul Point Regen": "spRegen",
|
||||
"Stealing": "eSteal",
|
||||
"Raw Health Regen": "hprRaw",
|
||||
"Raw Spell": "sdRaw",
|
||||
"Raw Melee": "mdRaw",
|
||||
"% Fire Damage": "fDamPct",
|
||||
"% Water Damage": "wDamPct",
|
||||
"% Air Damage": "aDamPct",
|
||||
"% Thunder Damage": "tDamPct",
|
||||
"% Earth Damage": "eDamPct",
|
||||
"% Fire Defense": "fDefPct",
|
||||
"% Water Defense": "wDefPct",
|
||||
"% Air Defense": "aDefPct",
|
||||
"% Thunder Defense": "tDefPct",
|
||||
"% Earth Defense": "eDefPct",
|
||||
"Fixed IDs": "fixID",
|
||||
"Custom Skin": "skin",
|
||||
//"Item Category": "category",
|
||||
|
||||
"1st Spell Cost %": "spPct1",
|
||||
"1st Spell Cost Raw": "spRaw1",
|
||||
"2nd Spell Cost %": "spPct2",
|
||||
"2nd Spell Cost Raw": "spRaw2",
|
||||
"3rd Spell Cost %": "spPct3",
|
||||
"3rd Spell Cost Raw": "spRaw3",
|
||||
"4th Spell Cost %": "spPct4",
|
||||
"4th Spell Cost Raw": "spRaw4",
|
||||
|
||||
"Rainbow Spell Damage": "rainbowRaw",
|
||||
"Sprint": "sprint",
|
||||
"Sprint Regen": "sprintReg",
|
||||
"Jump Height": "jh",
|
||||
"Loot Quality": "lq",
|
||||
|
||||
"Gather XP Bonus": "gXp",
|
||||
"Gather Speed Bonus": "gSpd",
|
||||
};
|
||||
|
||||
const special_mappings = {
|
||||
"Sum (skill points)": new SumQuery(["str", "dex", "int", "def", "agi"]),
|
||||
"Sum (Mana Sustain)": new SumQuery(["mr", "ms"]),
|
||||
"Sum (Life Sustain)": new SumQuery(["hpr", "ls"]),
|
||||
"Sum (Health + Health Bonus)": new SumQuery(["hp", "hpBonus"]),
|
||||
"No Req Strength": new NegateQuery("strReq"),
|
||||
"No Req Dexterity": new NegateQuery("dexReq"),
|
||||
"No Req Intelligence": new NegateQuery("intReq"),
|
||||
"No Req Agility": new NegateQuery("agiReq"),
|
||||
"No Req Defense": new NegateQuery("defReq"),
|
||||
};
|
||||
|
||||
let itemFilters = document.getElementById("filter-items");
|
||||
for (let x in translate_mappings) {
|
||||
let el = document.createElement("option");
|
||||
el.value = x;
|
||||
itemFilters.appendChild(el);
|
||||
}
|
||||
for (let x in special_mappings) {
|
||||
let el = document.createElement("option");
|
||||
el.value = x;
|
||||
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) {
|
||||
return items.filter(query.filter, query).sort(query.compare);
|
||||
}
|
||||
|
@ -17,12 +136,47 @@ function displayItems(items_copy) {
|
|||
|
||||
function doItemSearch() {
|
||||
window.scrollTo(0, 0);
|
||||
let input_json = document.getElementById("query-json").value;
|
||||
let input = JSON.parse(input_json);
|
||||
let queries = [];
|
||||
queries.push(new NameQuery(document.getElementById("name-choice").value));
|
||||
|
||||
let categoryOrType = document.getElementById("category-choice").value;
|
||||
if (itemTypes.includes(categoryOrType)) {
|
||||
queries.push(new IdMatchQuery("type", categoryOrType));
|
||||
}
|
||||
else if (itemCategories.includes(categoryOrType)) {
|
||||
queries.push(new IdMatchQuery("category", categoryOrType));
|
||||
}
|
||||
|
||||
let rarity = document.getElementById("rarity-choice").value;
|
||||
if (rarity) {
|
||||
if (rarity === "ANY") {
|
||||
|
||||
}
|
||||
else {
|
||||
queries.push(new IdMatchQuery("tier", rarity));
|
||||
}
|
||||
}
|
||||
|
||||
let level_dat = document.getElementById("level-choice").value.split("-");
|
||||
queries.push(new LevelRangeQuery(parseInt(level_dat[0]), parseInt(level_dat[1])));
|
||||
|
||||
for (let i = 1; i <= 4; ++i) {
|
||||
let raw_dat = document.getElementById("filter"+i+"-choice").value;
|
||||
let filter_dat = translate_mappings[raw_dat];
|
||||
if (filter_dat !== undefined) {
|
||||
queries.push(new IdQuery(filter_dat));
|
||||
continue;
|
||||
}
|
||||
filter_dat = special_mappings[raw_dat];
|
||||
if (filter_dat !== undefined) {
|
||||
queries.push(filter_dat);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
let items_copy = items.slice();
|
||||
document.getElementById("main").textContent = "";
|
||||
for (const _query of input) {
|
||||
const query = queryTypeMap.get(_query.queryType)(_query.value, _query.value2);
|
||||
for (const query of queries) {
|
||||
items_copy = applyQuery(items_copy, query);
|
||||
}
|
||||
document.getElementById("summary").textContent = items_copy.length + " results."
|
||||
|
|
2
load.js
2
load.js
|
@ -1,4 +1,4 @@
|
|||
const DB_VERSION = 28;
|
||||
const DB_VERSION = 29;
|
||||
// @See https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/indexeddb/video-store/index.js
|
||||
|
||||
let db;
|
||||
|
|
58
query.js
58
query.js
|
@ -14,33 +14,30 @@ class NameQuery {
|
|||
}
|
||||
queryTypeMap.set("name", function(s) { return new NameQuery(s); } );
|
||||
|
||||
class TypeQuery {
|
||||
constructor(type) { this.type = type; }
|
||||
class LevelRangeQuery {
|
||||
constructor(min, max) { this.min = min; this.max = max; }
|
||||
|
||||
filter(item) {
|
||||
if (item.remapID === undefined) {
|
||||
return (item.type === this.type);
|
||||
return (item.lvl <= this.max && item.lvl >= this.min);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
compare(a, b) { return a < b; }
|
||||
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;
|
||||
class NegateQuery {
|
||||
constructor(id) {
|
||||
this.id = id;
|
||||
this.compare = function(a, b) { return 0; };
|
||||
}
|
||||
|
||||
compare(a, b) { return a < b; }
|
||||
filter(item) {
|
||||
return (!(this.id in item)) || (item[this.id] == 0);
|
||||
}
|
||||
}
|
||||
queryTypeMap.set("category", function(s) { return new CategoryQuery(s); } );
|
||||
queryTypeMap.set("null", function(s) { return new IdQuery(s); } );
|
||||
|
||||
class IdQuery {
|
||||
constructor(id) {
|
||||
|
@ -55,3 +52,34 @@ class IdQuery {
|
|||
}
|
||||
}
|
||||
queryTypeMap.set("stat", function(s) { return new IdQuery(s); } );
|
||||
|
||||
class IdMatchQuery {
|
||||
constructor(id, value) {
|
||||
this.id = id;
|
||||
this.value = value;
|
||||
this.compare = function(a, b) {
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
|
||||
filter(item) {
|
||||
return (this.id in item) && (item[this.id] == this.value);
|
||||
}
|
||||
}
|
||||
|
||||
class SumQuery {
|
||||
constructor(ids) {
|
||||
this.compare = function(a, b) {
|
||||
let balance = 0;
|
||||
for (const id of ids) {
|
||||
if (a[id]) { balance -= a[id]; }
|
||||
if (b[id]) { balance += b[id]; }
|
||||
}
|
||||
return balance;
|
||||
};
|
||||
}
|
||||
|
||||
filter(item) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
12
styles.css
12
styles.css
|
@ -5,6 +5,18 @@
|
|||
flex-direction: row;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: red;
|
||||
top: 30px;
|
||||
font-size: 10px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
height: 5px;
|
||||
font-family: 'Nunito', sans-serif;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.headericon {
|
||||
/* JANK FIX IF CAN */
|
||||
max-height: 48px;
|
||||
|
|
115
updated.json
115
updated.json
|
@ -70943,77 +70943,37 @@
|
|||
"drop": "NORMAL"
|
||||
},
|
||||
{
|
||||
"name": "Enduzskam",
|
||||
"tier": "Unique",
|
||||
"type": "boots",
|
||||
"name": "Enduzskam",
|
||||
"displayName": "Enduzskam",
|
||||
"set": null,
|
||||
"quest": null,
|
||||
"poison": 0,
|
||||
"thorns": 0,
|
||||
"sprint": 0,
|
||||
"category": "armor",
|
||||
"slots": 2,
|
||||
"drop": "NORMAL",
|
||||
"hp": 1950,
|
||||
"fDef": 0,
|
||||
"wDef": 50,
|
||||
"aDef": 0,
|
||||
"tDef": 80,
|
||||
"eDef": -90,
|
||||
"lvl": 83,
|
||||
"classReq": null,
|
||||
"fixID": false,
|
||||
"strReq": 0,
|
||||
"dexReq": 45,
|
||||
"intReq": 45,
|
||||
"agiReq": 0,
|
||||
"dexReq": 35,
|
||||
"intReq": 35,
|
||||
"defReq": 0,
|
||||
"hprPct": 0,
|
||||
"mr": 1,
|
||||
"sdPct": 7,
|
||||
"mdPct": 0,
|
||||
"ls": 0,
|
||||
"ms": 0,
|
||||
"xpb": 0,
|
||||
"lb": 0,
|
||||
"ref": 0,
|
||||
"agiReq": 0,
|
||||
"category": "armor",
|
||||
"lvl": 83,
|
||||
"hp": 1950,
|
||||
"eDef": -90,
|
||||
"tDef": 80,
|
||||
"wDef": 50,
|
||||
"slots": 2,
|
||||
"str": 0,
|
||||
"dex": 4,
|
||||
"dex": 9,
|
||||
"int": 0,
|
||||
"agi": 0,
|
||||
"def": 0,
|
||||
"expd": 0,
|
||||
"spd": 0,
|
||||
"atkTier": 0,
|
||||
"hpBonus": 0,
|
||||
"spRegen": 0,
|
||||
"eSteal": 0,
|
||||
"hprRaw": 0,
|
||||
"sdRaw": 0,
|
||||
"mdRaw": 0,
|
||||
"fDamPct": 0,
|
||||
"wDamPct": 12,
|
||||
"aDamPct": 0,
|
||||
"tDamPct": 16,
|
||||
"agi": 0,
|
||||
"mr": 1,
|
||||
"sdPct": 14,
|
||||
"eDamPct": -14,
|
||||
"fDefPct": 0,
|
||||
"wDefPct": 0,
|
||||
"aDefPct": 0,
|
||||
"tDefPct": 0,
|
||||
"tDamPct": 16,
|
||||
"wDamPct": 12,
|
||||
"eDefPct": -10,
|
||||
"spPct1": 0,
|
||||
"spRaw1": 0,
|
||||
"spPct2": 0,
|
||||
"spRaw2": 0,
|
||||
"spPct3": 0,
|
||||
"spRaw3": 0,
|
||||
"spPct4": 0,
|
||||
"spRaw4": 0,
|
||||
"rainbowRaw": 0,
|
||||
"sprintReg": 0,
|
||||
"jh": 0,
|
||||
"lq": 0,
|
||||
"gXp": 0,
|
||||
"gSpd": 0,
|
||||
"id": 986
|
||||
},
|
||||
{
|
||||
|
@ -256754,38 +256714,9 @@
|
|||
"remapID": 586
|
||||
},
|
||||
{
|
||||
"tier": "Unique",
|
||||
"type": "boots",
|
||||
"name": "Enduzkam",
|
||||
"displayName": "Enduzkam",
|
||||
"set": null,
|
||||
"quest": null,
|
||||
"classReq": null,
|
||||
"fixID": false,
|
||||
"strReq": 0,
|
||||
"dexReq": 35,
|
||||
"intReq": 35,
|
||||
"defReq": 0,
|
||||
"agiReq": 0,
|
||||
"category": "armor",
|
||||
"lvl": 83,
|
||||
"hp": 1950,
|
||||
"eDef": -90,
|
||||
"tDef": 80,
|
||||
"wDef": 50,
|
||||
"slots": 2,
|
||||
"str": 0,
|
||||
"dex": 9,
|
||||
"int": 0,
|
||||
"def": 0,
|
||||
"agi": 0,
|
||||
"mr": 1,
|
||||
"sdPct": 14,
|
||||
"eDamPct": -14,
|
||||
"tDamPct": 16,
|
||||
"wDamPct": 12,
|
||||
"eDefPct": -10,
|
||||
"id": 3592
|
||||
"id": 3592,
|
||||
"name": "3592",
|
||||
"remapID": 986
|
||||
},
|
||||
{
|
||||
"tier": "Unique",
|
||||
|
@ -258891,7 +258822,7 @@
|
|||
"displayName": "Cursed Jackboots"
|
||||
},
|
||||
{
|
||||
"displayName": "Cinfras Souvenir T-Shirt",
|
||||
"name": "Cinfras Souvenir T-Shirt",
|
||||
"tier": "Normal",
|
||||
"type": "chestplate",
|
||||
"set": null,
|
||||
|
|
Loading…
Reference in a new issue