From 0f21d8abe230c6cc556a830be8d5f2026d2f0fcb Mon Sep 17 00:00:00 2001 From: hppeng Date: Wed, 3 Aug 2022 00:28:54 -0700 Subject: [PATCH] Port crafter back to advanced search backend --- crafter/index.html | 3 - items/index.html | 3 +- items_adv/index.html | 2 +- js/build_utils.js | 2 +- js/items.js | 121 +++++++++++++++----- js/load.js | 2 +- js/query.js | 115 ------------------- js/sq2items.js | 264 ------------------------------------------- 8 files changed, 99 insertions(+), 413 deletions(-) delete mode 100644 js/query.js delete mode 100644 js/sq2items.js diff --git a/crafter/index.html b/crafter/index.html index 29b3d84..1a8b072 100644 --- a/crafter/index.html +++ b/crafter/index.html @@ -279,8 +279,6 @@ - - @@ -293,6 +291,5 @@ - diff --git a/items/index.html b/items/index.html index 183b479..6fc3e7c 100644 --- a/items/index.html +++ b/items/index.html @@ -141,10 +141,9 @@ - - + diff --git a/items_adv/index.html b/items_adv/index.html index 2926bf2..3d21a58 100644 --- a/items_adv/index.html +++ b/items_adv/index.html @@ -80,7 +80,7 @@ - + diff --git a/js/build_utils.js b/js/build_utils.js index 7cb86db..5ff115d 100644 --- a/js/build_utils.js +++ b/js/build_utils.js @@ -70,7 +70,7 @@ const tiers = ["Normal", "Unique", "Rare", "Legendary", "Fabled", "Mythic", "Set const all_types = armorTypes.concat(accessoryTypes).concat(weaponTypes).concat(consumableTypes).concat(tome_types).map(x => x.substring(0,1).toUpperCase() + x.substring(1)); //weaponTypes.push("sword"); //console.log(types) -let itemTypes = armorTypes.concat(accessoryTypes).concat(weaponTypes).concat(tome_types); +let item_types = armorTypes.concat(accessoryTypes).concat(weaponTypes).concat(tome_types); let elementIcons = ["\u2724","\u2726", "\u2749", "\u2739", "\u274b" ]; let skpReqs = skp_order.map(x => x + "Req"); diff --git a/js/items.js b/js/items.js index 2e1de9d..e6fd7b9 100644 --- a/js/items.js +++ b/js/items.js @@ -102,35 +102,40 @@ const special_mappings = { "No Defense Req": "f:defReq=0", }; -let itemFilters = document.getElementById("filter-items"); -if (itemFilters) { - 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 item_filters = [] +for (let x in translate_mappings) { + item_filters.push(x); +} +for (let x in special_mappings) { + item_filters.push(x); } -let itemCategories = [ "armor", "accessory", "weapon" ]; +let item_categories = [ "armor", "accessory", "weapon" ]; function applyQuery(items, query) { return items.filter(query.filter, query).sort(query.compare); } -function displayItems(results) { - let items_parent = document.getElementById("main"); - for (let i in results) { - let item = results[i].itemExp; +function displayItems(items_copy) { + let items_parent = document.getElementById("search-results"); + for (let i in items_copy) { + if (i > 200) {break;} + let item = items_copy[i].itemExp; let box = document.createElement("div"); - box.classList.add("box"); + box.classList.add("col-lg-3", "col-sm-6", "p-2"); box.id = "item"+i; + //box.addEventListener("dblclick", function() {set_item(item);}); TODO: ?? + + let bckgrdbox = document.createElement("div"); + bckgrdbox.classList.add("dark-7", "rounded", "px-2", "col-auto"); + box.appendChild(bckgrdbox); + bckgrdbox.id = "item"+i+"b"; items_parent.appendChild(box); - displayExpandedItem(item, box.id); + item.set("powders", []); + if (item.get("category") == "weapon") { + apply_weapon_powders(item); + } + displayExpandedItem(item, bckgrdbox.id, true); } } @@ -142,10 +147,10 @@ function doItemSearch() { queries.push('f:name?="'+document.getElementById("item-name-choice").value.trim()+'"'); let categoryOrType = document.getElementById("item-category-choice").value; - if (itemTypes.includes(categoryOrType)) { + if (item_types.includes(categoryOrType)) { queries.push('f:type="'+categoryOrType+'"'); } - else if (itemCategories.includes(categoryOrType)) { + else if (item_categories.includes(categoryOrType)) { queries.push('f:cat="'+categoryOrType+'"'); } @@ -162,7 +167,9 @@ function doItemSearch() { } } - let level_dat = document.getElementById("item-level-choice").value.split("-"); + let level_raw = document.getElementById("item-level-choice").value; + if (!level_raw) { level_raw = '1-106'; }; + const level_dat = level_raw.split("-"); queries.push('f:(lvl>='+parseInt(level_dat[0])+'&lvl<='+parseInt(level_dat[1])+')'); for (let i = 1; i <= 4; ++i) { @@ -191,8 +198,7 @@ function doItemSearch() { filterQuery = filterQuery + "&" + query.slice(2); } } - console.log(filterQuery); - console.log(sortQueries); + document.getElementById("search-results").textContent = ""; let results = []; try { const filterExpr = exprParser.parse(filterQuery); @@ -211,13 +217,76 @@ function doItemSearch() { document.getElementById("summary").textContent = e.message; return; } - document.getElementById("summary").textContent = results.length + " results." + document.getElementById("summary").textContent = results.length + " results:" displayItems(results); } +function resetItemSearch() { + resetFields = ["item-name-choice", "item-category-choice", "item-rarity-choice", "item-level-choice", "filter1-choice", "filter2-choice", "filter3-choice", "filter4-choice"] + for (const field of resetFields) { + document.getElementById(field).value = ""; + } +} + function init_items() { searchDb = items.filter( i => ! i.remapID ).map( i => [i, expandItem(i, [])] ); exprParser = new ExprParser(itemQueryProps, itemQueryFuncs); } -load_init(init_items); +(async function() { + await Promise.resolve(load_init()); + init_items(); + //init dropdowns + let filterInputs = new Map([["item-category", ["ALL", "armor", "helmet", "chestplate", "leggings", "boots", "accessory", "ring", "bracelet", "necklace", "weapon", "wand", "spear", "bow", "dagger", "relik"]], + ["item-rarity", ["ANY", "Normal", "Unique", "Set", "Rare", "Legendary", "Fabled", "Mythic", "Sane"]], + ["filter1", item_filters], + ["filter2", item_filters], + ["filter3", item_filters], + ["filter4", item_filters]]); + for (const [field, data] of filterInputs) { + let field_choice = document.getElementById(field+"-choice"); + // show dropdown on click + field_choice.onclick = function() {field_choice.dispatchEvent(new Event('input', {bubbles:true}));}; + filterInputs.set(field, new autoComplete({ + data: { + src: data, + }, + threshold: 0, + selector: "#"+ field +"-choice", + wrapper: false, + resultsList: { + maxResults: 100, + tabSelect: true, + noResults: true, + class: "search-box dark-7 rounded-bottom px-2 fw-bold dark-shadow-sm", + element: (list, data) => { + let position = document.getElementById(field+'-choice').getBoundingClientRect(); + list.style.top = position.bottom + window.scrollY +"px"; + list.style.left = position.x+"px"; + list.style.width = position.width+"px"; + list.style.maxHeight = position.height * 4 +"px"; + + if (!data.results.length) { + message = document.createElement('li'); + message.classList.add('scaled-font'); + message.textContent = "No results found!"; + list.prepend(message); + }; + }, + }, + resultItem: { + class: "scaled-font search-item", + selected: "dark-5", + }, + events: { + input: { + selection: (event) => { + if (event.detail.selection.value) { + event.target.value = event.detail.selection.value; + }; + }, + }, + } + })); + } +})(); diff --git a/js/load.js b/js/load.js index f276f21..aa39af4 100644 --- a/js/load.js +++ b/js/load.js @@ -190,7 +190,7 @@ async function load_init() { } // List of 'raw' "none" items (No Helmet, etc), in order helmet, chestplate... ring1, ring2, brace, neck, weapon. -for (const it of itemTypes) { +for (const it of item_types) { itemLists.set(it, []); } diff --git a/js/query.js b/js/query.js deleted file mode 100644 index 3519853..0000000 --- a/js/query.js +++ /dev/null @@ -1,115 +0,0 @@ -let queryTypeMap = new Map(); - -class NameQuery { - constructor(string) { this.queryString = string.toLowerCase(); } - - filter(item) { - if (item.get("restrict") && item.get("restrict") === "DEPRECATED") { - return false; - } - return (item.get("displayName").toLowerCase().includes(this.queryString)); - } - - compare(a, b) { return a < b; } -} -queryTypeMap.set("name", function(s) { return new NameQuery(s); } ); - -class LevelRangeQuery { - constructor(min, max) { this.min = min; this.max = max; } - - filter(item) { - if (item.get("remapID") === undefined) { - return (item.get("lvl") <= this.max && item.get("lvl") >= this.min); - } - return false; - } - - compare(a, b) { return a > b; } -} - -class NegateQuery { - constructor(id) { - this.id = id; - this.compare = function(a, b) { return 0; }; - } - - filter(item) { - return (!item.get(this.id)) || (item.get(this.id) == 0); - } -} -queryTypeMap.set("null", function(s) { return new IdQuery(s); } ); - -class IdQuery { - constructor(id) { - this.id = id; - if (nonRolledIDs.includes(id)) { - this.compare = function(a, b) { - return b.get(id) - a.get(id); - }; - this.filter = function(a) { - return a.get(this.id); - } - console.log("QUERY: ID, NONROLL"); - } - else if (reversedIDs.includes(id)) { - this.compare = function(a, b) { - return a.get("maxRolls").get(id) - b.get("maxRolls").get(id); - }; - this.filter = function(a) { - return a.get("maxRolls").get(this.id); - } - console.log("QUERY: ID, REVERSE"); - } - else { - this.compare = function(a, b) { - return b.get("maxRolls").get(id) - a.get("maxRolls").get(id); - }; - this.filter = function(a) { - return a.get("maxRolls").get(this.id); - } - console.log("QUERY: ID, ,,,"); - } - } -} -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 item.get(this.id) && (item.get(this.id) == this.value); - } -} - -class SumQuery { - constructor(ids) { - let getters = []; - for (const id of ids) { - if (nonRolledIDs.includes(id)) { - getters.push(a => a.get(id)); - } - else { - getters.push(a => a.get("maxRolls").get(id)); - } - - } - this.compare = function(a, b) { - let balance = 0; - for (const getter of getters) { - if (getter(a)) { balance -= getter(a); } - if (getter(b)) { balance += getter(b); } - } - return balance; - }; - } - - filter(item) { - return true; - } -} diff --git a/js/sq2items.js b/js/sq2items.js deleted file mode 100644 index 6d62c63..0000000 --- a/js/sq2items.js +++ /dev/null @@ -1,264 +0,0 @@ -let itemCategories = [ "armor", "accessory", "weapon" ]; - -const sq2_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 sq2_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 Strength Req": new NegateQuery("strReq"), - "No Dexterity Req": new NegateQuery("dexReq"), - "No Intelligence Req": new NegateQuery("intReq"), - "No Agility Req": new NegateQuery("agiReq"), - "No Defense Req": new NegateQuery("defReq"), -}; - -let sq2ItemFilters = [] -for (let x in sq2_translate_mappings) { - sq2ItemFilters.push(x); -} -for (let x in sq2_special_mappings) { - sq2ItemFilters.push(x); -} - -function applyQuery(items, query) { - return items.filter(query.filter, query).sort(query.compare); -} - -function displayItems(items_copy) { - let items_parent = document.getElementById("search-results"); - for (let i in items_copy) { - if (i > 200) {break;} - let item = items_copy[i]; - let box = document.createElement("div"); - box.classList.add("col-lg-3", "col-sm-6", "p-2"); - box.id = "item"+i; - box.addEventListener("dblclick", function() {set_item(item);}); - - let bckgrdbox = document.createElement("div"); - bckgrdbox.classList.add("dark-7", "rounded", "px-2", "col-auto"); - box.appendChild(bckgrdbox); - bckgrdbox.id = "item"+i+"b"; - items_parent.appendChild(box); - item.set("powders", []); - if (item.get("category") == "weapon") { - apply_weapon_powders(item); - } - displayExpandedItem(item, bckgrdbox.id, true); - } -} - -let items_expanded; - -function doItemSearch() { - // window.scrollTo(0, 0); - let queries = []; - queries.push(new NameQuery(document.getElementById("item-name-choice").value.trim())); - - let categoryOrType = document.getElementById("item-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("item-rarity-choice").value; - if (rarity) { - if (rarity === "ANY") { - - } - else { - queries.push(new IdMatchQuery("tier", rarity)); - } - } - - let level_dat = document.getElementById("item-level-choice").value ? document.getElementById("item-level-choice").value.split("-") : [1, 106]; - 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 = sq2_translate_mappings[raw_dat]; - if (filter_dat !== undefined) { - queries.push(new IdQuery(filter_dat)); - continue; - } - filter_dat = sq2_special_mappings[raw_dat]; - if (filter_dat !== undefined) { - queries.push(filter_dat); - continue; - } - } - - let items_copy = items_expanded.slice(); - document.getElementById("search-results").textContent = ""; - for (const query of queries) { - console.log(items_copy.length); - console.log(query, query.filter); - items_copy = applyQuery(items_copy, query); - console.log(items_copy.length); - } - document.getElementById("summary").textContent = items_copy.length + " results:" - displayItems(items_copy); -} - -function resetItemSearch() { - resetFields = ["item-name-choice", "item-category-choice", "item-rarity-choice", "item-level-choice", "filter1-choice", "filter2-choice", "filter3-choice", "filter4-choice"] - for (const field of resetFields) { - document.getElementById(field).value = ""; - } -} - -function init_items() { - items_expanded = items.filter( (i) => !("remapID" in i) ).map( (i) => expandItem(i) ); - - //init dropdowns - let filterInputs = new Map([["item-category", ["ALL", "armor", "helmet", "chestplate", "leggings", "boots", "accessory", "ring", "bracelet", "necklace", "weapon", "wand", "spear", "bow", "dagger", "relik"]], - ["item-rarity", ["ANY", "Normal", "Unique", "Set", "Rare", "Legendary", "Fabled", "Mythic", "Sane"]], - ["filter1", sq2ItemFilters], - ["filter2", sq2ItemFilters], - ["filter3", sq2ItemFilters], - ["filter4", sq2ItemFilters]]); - for (const [field, data] of filterInputs) { - let field_choice = document.getElementById(field+"-choice"); - // show dropdown on click - field_choice.onclick = function() {field_choice.dispatchEvent(new Event('input', {bubbles:true}));}; - filterInputs.set(field, new autoComplete({ - data: { - src: data, - }, - threshold: 0, - selector: "#"+ field +"-choice", - wrapper: false, - resultsList: { - maxResults: 100, - tabSelect: true, - noResults: true, - class: "search-box dark-7 rounded-bottom px-2 fw-bold dark-shadow-sm", - element: (list, data) => { - let position = document.getElementById(field+'-choice').getBoundingClientRect(); - list.style.top = position.bottom + window.scrollY +"px"; - list.style.left = position.x+"px"; - list.style.width = position.width+"px"; - list.style.maxHeight = position.height * 4 +"px"; - - if (!data.results.length) { - message = document.createElement('li'); - message.classList.add('scaled-font'); - message.textContent = "No results found!"; - list.prepend(message); - }; - }, - }, - resultItem: { - class: "scaled-font search-item", - selected: "dark-5", - }, - events: { - input: { - selection: (event) => { - if (event.detail.selection.value) { - event.target.value = event.detail.selection.value; - }; - }, - }, - } - })); - }; -} - -(async function() { - await Promise.resolve(load_init()); - init_items(); -})();