wynnbuilder-forked-for-changes/js/display.js

1461 lines
58 KiB
JavaScript
Raw Permalink Normal View History

/**
* File containing generic display code, ex. for displaying items and spell damage.
* TODO: split this file into separate parts for each "component".
*/
2022-07-24 21:31:23 +00:00
const itemBGPositions = {"bow": "0 0", "spear": "9.090909090909088% 0", "wand": "18.181818181818183% 0", "dagger": "27.27272727272727% 0", "relik": "36.36363636363637% 0",
"helmet": "45.45454545454546% 0", "chestplate": "54.54545454545454% 0", "leggings": "63.63636363636363% 0", "boots": "72.72727272727272% 0",
"ring": "81.81818181818181% 0", "bracelet": "90.90909090909092% 0", "necklace": "100% 0",
"potion": "25% 0", "scroll": "50% 0", "food": "75% 0"};
2021-01-10 21:31:29 +00:00
2021-01-09 12:47:25 +00:00
function apply_elemental_format(p_elem, id, suffix) {
suffix = (typeof suffix !== 'undefined') ? suffix : "";
// THIS IS SO JANK BUT IM TOO LAZY TO FIX IT TODO
let parts = idPrefixes[id].split(/ (.*)/);
let element_prefix = parts[0];
let desc = parts[1];
let i_elem = make_elem('span', [element_prefix], {textContent: element_prefix});
2021-01-09 12:47:25 +00:00
p_elem.appendChild(i_elem);
let i_elem2 = make_elem('span', [], {textContent: " "+desc+suffix});
2021-01-09 12:47:25 +00:00
p_elem.appendChild(i_elem2);
}
function displaySetBonuses(parent_id,build) {
2021-01-10 21:01:59 +00:00
setHTML(parent_id, "");
let parent_div = document.getElementById(parent_id);
let set_summary_elem = make_elem('p', ['text-center'], {textContent: "Set Bonuses"});
2021-01-10 21:01:59 +00:00
parent_div.append(set_summary_elem);
for (const [setName, count] of build.activeSetCounts) {
const active_set = sets.get(setName);
2021-02-04 10:55:15 +00:00
if (active_set["hidden"]) { continue; }
let set_elem = make_elem('p', [], {id: "set-"+setName});
2021-01-10 21:01:59 +00:00
set_summary_elem.append(set_elem);
2021-02-04 10:55:15 +00:00
const bonus = active_set.bonuses[count-1];
let mock_item = new Map([["fixID", true],
["displayName", setName+" Set: "+count+"/"+sets.get(setName).items.length]]);
2021-01-10 21:01:59 +00:00
let mock_minRolls = new Map();
2021-03-16 22:43:44 +00:00
let mock_maxRolls = new Map();
2021-01-10 21:01:59 +00:00
mock_item.set("minRolls", mock_minRolls);
2021-03-16 22:43:44 +00:00
mock_item.set("maxRolls", mock_maxRolls);
2021-01-10 21:01:59 +00:00
for (const id in bonus) {
if (rolledIDs.includes(id)) {
mock_minRolls.set(id, bonus[id]);
2021-03-16 22:43:44 +00:00
mock_maxRolls.set(id, bonus[id]);
2021-01-10 21:01:59 +00:00
}
else {
mock_item.set(id, bonus[id]);
}
}
2021-01-11 12:19:15 +00:00
mock_item.set("powders", []);
2021-01-10 21:01:59 +00:00
displayExpandedItem(mock_item, set_elem.id);
}
}
2022-06-20 13:12:22 +00:00
function displayBuildStats(parent_id,build,command_group,stats){
2021-01-09 12:47:25 +00:00
// Commands to "script" the creation of nice formatting.
// #commands create a new element.
// !elemental is some janky hack for elemental damage.
// normals just display a thing.
let display_commands = command_group;
2021-01-09 12:47:25 +00:00
let parent_div = document.getElementById(parent_id);
// Clear the parent div.
if (parent_div != null) {
setHTML(parent_id, "");
2021-01-10 21:01:59 +00:00
}
2021-01-09 12:47:25 +00:00
let active_elem;
let elemental_format = false;
//TODO this is put here for readability, consolidate with definition in `builder/build.js`
// TODO amend: uuhhhhh these two constants have diverged too far...
2021-01-09 12:47:25 +00:00
let staticIDs = ["hp", "eDef", "tDef", "wDef", "fDef", "aDef"];
for (const command of display_commands) {
// style instructions
2021-01-09 12:47:25 +00:00
if (command.charAt(0) === "#") {
if (command === "#defense-stats") {
2022-06-20 13:12:22 +00:00
displayDefenseStats(parent_div, stats, true);
2021-01-09 12:47:25 +00:00
}
}
if (command.charAt(0) === "!") {
2021-01-09 12:47:25 +00:00
// TODO: This is sooo incredibly janky.....
if (command === "!elemental") {
elemental_format = !elemental_format;
}
}
// id instruction
2021-01-09 12:47:25 +00:00
else {
let id = command;
if (stats.get(id)) {
let style = null;
// TODO: add pos and neg style
2021-01-09 12:47:25 +00:00
if (!staticIDs.includes(id)) {
style = "positive";
if (stats.get(id) < 0) {
style = "negative";
}
}
// ignore
2021-01-11 07:05:23 +00:00
let id_val = stats.get(id);
if (reversedIDs.includes(id)) {
style === "positive" ? style = "negative" : style = "positive";
}
displayFixedID(parent_div, id, id_val, elemental_format, style);
if (id === "ls" && id_val != 0) {
let row = make_elem('div', ['row']);
let value_elem = make_elem('div', ['col', 'text-end']);
let prefix_elem = make_elem('b', [], {textContent: "\u279C Effective LS: "});
2021-01-11 07:05:23 +00:00
2022-06-20 13:12:22 +00:00
let defStats = getDefenseStats(stats);
let number_elem = make_elem('b', [style], {
textContent: Math.round(defStats[1][0]*id_val/defStats[0]) + "/3s"
});
value_elem.append(prefix_elem);
value_elem.append(number_elem);
row.appendChild(value_elem);
parent_div.appendChild(row);
2021-01-11 07:05:23 +00:00
}
}
// sp thingy (WHY IS THIS HANDLED SEPARATELY TODO
else if (skp_order.includes(id)) {
let total_assigned = build.total_skillpoints[skp_order.indexOf(id)];
let base_assigned = build.base_skillpoints[skp_order.indexOf(id)];
let diff = total_assigned - base_assigned;
let style;
if (diff > 0) {
style = "positive";
} else if (diff < 0) {
style = "negative";
}
if (diff != 0) {
displayFixedID(parent_div, id, diff, false, style);
}
2021-01-09 12:47:25 +00:00
}
}
}
}
2021-01-07 22:44:52 +00:00
function displayExpandedItem(item, parent_id){
// Commands to "script" the creation of nice formatting.
// #commands create a new element.
2021-01-08 01:02:12 +00:00
// !elemental is some janky hack for elemental damage.
2021-01-07 22:44:52 +00:00
// normals just display a thing.
item = new Map(item); // shallow copy
if (item.get("category") === "weapon") {
2022-06-24 10:35:03 +00:00
item.set('basedps', get_base_dps(item));
} else if (item.get("category") === "armor") {
}
let display_commands = sq2_item_display_commands;
2021-01-07 22:44:52 +00:00
// Clear the parent div.
setHTML(parent_id, "");
let parent_div = document.getElementById(parent_id);
parent_div.classList.add("border", "border-2", "border-dark");
2021-01-07 22:44:52 +00:00
2021-01-08 01:02:12 +00:00
let fix_id = item.has("fixID") && item.get("fixID");
let elemental_format = false;
for (let i = 0; i < display_commands.length; i++) {
const command = display_commands[i];
if (command.charAt(0) === "!") {
2021-01-08 01:02:12 +00:00
// TODO: This is sooo incredibly janky.....
if (command === "!elemental") {
elemental_format = !elemental_format;
}
else if (command === "!spacer") {
2022-07-18 06:46:23 +00:00
let spacer = make_elem('div', ["row", "my-2"], {});
parent_div.appendChild(spacer);
continue;
}
2021-01-08 01:02:12 +00:00
}
2021-01-07 22:44:52 +00:00
else {
let id = command;
2021-09-06 05:45:01 +00:00
if(nonRolledIDs.includes(id)){//nonRolledID & non-0/non-null/non-und ID
if (!item.get(id)) {
2022-07-18 06:46:23 +00:00
if (!(item.get("crafted") && skp_order.includes(id) &&
2021-09-06 05:45:01 +00:00
(item.get("maxRolls").get(id) || item.get("minRolls").get(id)))) {
continue;
}
}
if (id === "slots") {
2022-07-18 06:46:23 +00:00
let p_elem = make_elem("div", ["col"]);
2021-01-28 00:52:34 +00:00
// PROPER POWDER DISPLAYING
let numerals = new Map([[1, "I"], [2, "II"], [3, "III"], [4, "IV"], [5, "V"], [6, "VI"]]);
2021-01-10 21:31:29 +00:00
p_elem.appendChild(make_elem("b", [], {
2022-07-18 06:46:23 +00:00
textContent: "Powder Slots: " + item.get(id) + " ["
}));
2021-01-11 01:47:13 +00:00
let powders = item.get("powders");
for (let i = 0; i < powders.length; i++) {
p_elem.appendChild(make_elem("b", [damageClasses[Math.floor(powders[i]/6)+1]+"_powder"], {
textContent: numerals.get((powders[i]%6)+1)+" "
}));
2021-01-10 21:31:29 +00:00
}
p_elem.appendChild(make_elem("b", [], { textContent: "]" }));
parent_div.appendChild(p_elem);
2021-02-04 10:55:15 +00:00
} else if (id === "set") {
if (item.get("hideSet")) { continue; }
parent_div.appendChild(make_elem("div", ["col"], { textContent: "Set: " + item.get(id).toString() }));
2021-01-30 12:09:32 +00:00
} else if (id === "majorIds") {
//console.log(item.get(id));
2.0.3 update (#260) * Mage atree changes * Bump version to 2.0.3.1 just tree for now * Warrior tree :pray: * Shaman tree WIP some things are too jank to stay * Fixes to bamboozle behavior also echo was -60% instead of -65% in the file??? wtf * Shurikens damage boost by echo meme * Fix description text in echo, update old version atree file * Fix shaman tree thanks spegg! * Spegg atree changes assassin tree fixed many of my shaman mistakes and other changes we missed over the months somehow? * Updated archer ability tree Thanks @mr_me! All credit to them. * Fixes to spegg's fixes implement beast lore * Change how Chant of the Lunatic is calculated coursing restraints ingame is 15% damage bonus * Updated ingredients manually thanks @watermelon (snownlite)! * Forgor to bump ing db version * Fix ingredient display jank * 2.0.3 items (#259) * API update also add new IDs to a bunch of places... tech debt whyyy * Forgot to update ingreds... * Change heal power ID name to stack with tree abils, fix multi totem effect on totemic shatter and req for mana traps * Forgot to bump item db version * Implement major IDs not implemented: Gentle Glow, and Forest's Blessing damage increase (since I don't know the exact numbers) and radiance boost is not implemented (radiance is currently handled way too jank) might wait for buffs rework to handle radiance. * patch item searcher TODO: make this not disgusting... build_encode_decode file has gotten too big --------- Co-authored-by: hppeng <hppeng> Co-authored-by: RawFish69 <108964215+RawFish69@users.noreply.github.com>
2023-07-15 01:34:30 +00:00
for (let major_id_str of item.get(id)) {
if (major_id_str in major_ids) {
let major_id_info = major_ids[major_id_str];
major_id_str = `+${major_id_info.displayName}: ${major_id_info.description}`;
}
2022-07-18 06:46:23 +00:00
let p_elem = make_elem("div", ['col']);
let title_elem = make_elem("b");
let b_elem = make_elem("b");
2.0.3 update (#260) * Mage atree changes * Bump version to 2.0.3.1 just tree for now * Warrior tree :pray: * Shaman tree WIP some things are too jank to stay * Fixes to bamboozle behavior also echo was -60% instead of -65% in the file??? wtf * Shurikens damage boost by echo meme * Fix description text in echo, update old version atree file * Fix shaman tree thanks spegg! * Spegg atree changes assassin tree fixed many of my shaman mistakes and other changes we missed over the months somehow? * Updated archer ability tree Thanks @mr_me! All credit to them. * Fixes to spegg's fixes implement beast lore * Change how Chant of the Lunatic is calculated coursing restraints ingame is 15% damage bonus * Updated ingredients manually thanks @watermelon (snownlite)! * Forgor to bump ing db version * Fix ingredient display jank * 2.0.3 items (#259) * API update also add new IDs to a bunch of places... tech debt whyyy * Forgot to update ingreds... * Change heal power ID name to stack with tree abils, fix multi totem effect on totemic shatter and req for mana traps * Forgot to bump item db version * Implement major IDs not implemented: Gentle Glow, and Forest's Blessing damage increase (since I don't know the exact numbers) and radiance boost is not implemented (radiance is currently handled way too jank) might wait for buffs rework to handle radiance. * patch item searcher TODO: make this not disgusting... build_encode_decode file has gotten too big --------- Co-authored-by: hppeng <hppeng> Co-authored-by: RawFish69 <108964215+RawFish69@users.noreply.github.com>
2023-07-15 01:34:30 +00:00
if (major_id_str.includes(":")) {
let name = major_id_str.substring(0, major_id_str.indexOf(":")+1);
let mid = major_id_str.substring(major_id_str.indexOf(":")+1);
if (name.charAt(0) !== "+") {name = "+" + name}
title_elem.classList.add("Legendary");
title_elem.textContent = name;
b_elem.classList.add("Crafted");
b_elem.textContent = mid;
p_elem.appendChild(title_elem);
p_elem.appendChild(b_elem);
} else {
2.0.3 update (#260) * Mage atree changes * Bump version to 2.0.3.1 just tree for now * Warrior tree :pray: * Shaman tree WIP some things are too jank to stay * Fixes to bamboozle behavior also echo was -60% instead of -65% in the file??? wtf * Shurikens damage boost by echo meme * Fix description text in echo, update old version atree file * Fix shaman tree thanks spegg! * Spegg atree changes assassin tree fixed many of my shaman mistakes and other changes we missed over the months somehow? * Updated archer ability tree Thanks @mr_me! All credit to them. * Fixes to spegg's fixes implement beast lore * Change how Chant of the Lunatic is calculated coursing restraints ingame is 15% damage bonus * Updated ingredients manually thanks @watermelon (snownlite)! * Forgor to bump ing db version * Fix ingredient display jank * 2.0.3 items (#259) * API update also add new IDs to a bunch of places... tech debt whyyy * Forgot to update ingreds... * Change heal power ID name to stack with tree abils, fix multi totem effect on totemic shatter and req for mana traps * Forgot to bump item db version * Implement major IDs not implemented: Gentle Glow, and Forest's Blessing damage increase (since I don't know the exact numbers) and radiance boost is not implemented (radiance is currently handled way too jank) might wait for buffs rework to handle radiance. * patch item searcher TODO: make this not disgusting... build_encode_decode file has gotten too big --------- Co-authored-by: hppeng <hppeng> Co-authored-by: RawFish69 <108964215+RawFish69@users.noreply.github.com>
2023-07-15 01:34:30 +00:00
if (major_id_str.charAt(0) !== "+") {major_id_str = "+" + major_id_str}
b_elem.classList.add("Legendary");
2.0.3 update (#260) * Mage atree changes * Bump version to 2.0.3.1 just tree for now * Warrior tree :pray: * Shaman tree WIP some things are too jank to stay * Fixes to bamboozle behavior also echo was -60% instead of -65% in the file??? wtf * Shurikens damage boost by echo meme * Fix description text in echo, update old version atree file * Fix shaman tree thanks spegg! * Spegg atree changes assassin tree fixed many of my shaman mistakes and other changes we missed over the months somehow? * Updated archer ability tree Thanks @mr_me! All credit to them. * Fixes to spegg's fixes implement beast lore * Change how Chant of the Lunatic is calculated coursing restraints ingame is 15% damage bonus * Updated ingredients manually thanks @watermelon (snownlite)! * Forgor to bump ing db version * Fix ingredient display jank * 2.0.3 items (#259) * API update also add new IDs to a bunch of places... tech debt whyyy * Forgot to update ingreds... * Change heal power ID name to stack with tree abils, fix multi totem effect on totemic shatter and req for mana traps * Forgot to bump item db version * Implement major IDs not implemented: Gentle Glow, and Forest's Blessing damage increase (since I don't know the exact numbers) and radiance boost is not implemented (radiance is currently handled way too jank) might wait for buffs rework to handle radiance. * patch item searcher TODO: make this not disgusting... build_encode_decode file has gotten too big --------- Co-authored-by: hppeng <hppeng> Co-authored-by: RawFish69 <108964215+RawFish69@users.noreply.github.com>
2023-07-15 01:34:30 +00:00
b_elem.textContent = major_id_str;
p_elem.appendChild(b_elem);
}
parent_div.appendChild(p_elem);
}
} else if (id === "lvl" && item.get("tier") === "Crafted") {
parent_div.appendChild(make_elem("div", ["col"], {
textContent: "Combat Level Min: " + item.get("lvlLow") + "-" + item.get(id)
}));
2021-09-25 18:57:57 +00:00
} else if (id === "displayName") {
let row = make_elem("div", ["row", "justify-content-center"]);
let nolink_row = make_elem("div", ["row", "justify-content-center"]);
nolink_row.style.display = "none";
const tier_class = item.has("tier") ? item.get("tier").replace(" ","") : "Normal";
let item_link;
if (item.get("custom")) {
item_link = "../custom/#" + item.get("hash");
} else if (item.get("crafted")) {
item_link = "../crafter/#" + item.get("hash");
} else {
item_link = "../item/#" + item.get("displayName");
}
const item_name_elem = make_elem("a", ["col-auto", "text-center", "item-title", "p-0", tier_class], {
textContent: item.get('displayName')
});
nolink_row.appendChild(item_name_elem.cloneNode(true));
item_name_elem.href = item_link;
row.appendChild(item_name_elem);
/*
FUNCTIONALITY FOR THIS FEATURE HAS SINCE BEEN REMOVED (WITH SQ2).
IF WE WANT TO USE IT IN THE FUTURE, I'VE LEFT THE CODE TO ADD IT IN HERE
*/
//allow the plus minus element to toggle upon click:
//let plusminus = document.createElement("div");
//plusminus.id = parent_div.id.split("-")[0] + "-pm";
//plusminus.classList.add("col", "plus_minus", "text_end");
//plusminus.style.flexGrow = 0;
//plusminus.textContent = "\u2795";
//row.appendChild(plusminus);
parent_div.appendChild(row);
parent_div.appendChild(nolink_row);
2021-09-25 18:57:57 +00:00
if (item.has("type")) {
2022-07-24 21:31:23 +00:00
let img = make_elem("div", [], {
alt: item.get("type"),
2022-07-24 21:31:23 +00:00
style: "z-index: 1; position: relative; image-rendering: pixelated; width: 50%; height: 50%; background-position: " + itemBGPositions[item.get("type")] + ";"
});
2022-07-24 21:31:23 +00:00
if (["potion", "scroll", "food"].includes(item.get("type"))) {
img.style.backgroundImage = "url('../media/items/common.png')";
img.style.backgroundSize = "500% 100%";
} else {
img.style.backgroundImage = "url('../media/items/" + (newIcons ? "new.png')" : "old.png')");
img.style.backgroundSize = "1200% 100%";
}
let container = make_elem("div");
let bckgrd = make_elem("div", ["col", "px-0", "d-flex", "align-items-center", "justify-content-center", 'scaled-bckgrd'], { // , "no-collapse"
style: "border-radius: 50%;background-image: radial-gradient(closest-side, " + colorMap.get(item.get("tier")) + " 20%," + "hsl(0, 0%, 16%) 80%); margin-left: auto; margin-right: auto;"
});
2021-09-25 18:57:57 +00:00
bckgrd.appendChild(img);
container.appendChild(bckgrd);
parent_div.appendChild(container);
2021-09-25 18:57:57 +00:00
}
2021-01-19 17:32:27 +00:00
} else {
if (id.endsWith('Dam_')) {
// TODO: kinda jank but replacing lists with txt at this step
let damages = item.get(id);
if (item.get("tier") !== "Crafted") {
parent 3e725eded882cb6d353ca9b37931cb959dcdf9dc author hppeng <hppeng> 1699417872 -0800 committer hppeng <hppeng> 1720354753 -0700 parent 3e725eded882cb6d353ca9b37931cb959dcdf9dc author hppeng <hppeng> 1699417872 -0800 committer hppeng <hppeng> 1720354749 -0700 parent 3e725eded882cb6d353ca9b37931cb959dcdf9dc author hppeng <hppeng> 1699417872 -0800 committer hppeng <hppeng> 1720354744 -0700 parent 3e725eded882cb6d353ca9b37931cb959dcdf9dc author hppeng <hppeng> 1699417872 -0800 committer hppeng <hppeng> 1720354739 -0700 parent 3e725eded882cb6d353ca9b37931cb959dcdf9dc author hppeng <hppeng> 1699417872 -0800 committer hppeng <hppeng> 1720354735 -0700 parent 3e725eded882cb6d353ca9b37931cb959dcdf9dc author hppeng <hppeng> 1699417872 -0800 committer hppeng <hppeng> 1720354730 -0700 parent 3e725eded882cb6d353ca9b37931cb959dcdf9dc author hppeng <hppeng> 1699417872 -0800 committer hppeng <hppeng> 1720354688 -0700 Update recipes.json (#265) Change ratio of gems to oil as it has been updated in 2.0.4 > Updated the Jeweling Recipe Changes (Bracelet- 2:1 gems:oil, Necklaces- 3:1 gems:oil) https://forums.wynncraft.com/threads/2-0-4-full-changelog-new-bank-lootruns-more.310535/ Finish updating recipes.json why are there 4 versions of this file active at any given time Fix damage calculation for rainbow raw wow this bug has been here for a LONG time also bump version for ing db Bunch of bugfixes - new major ID - divine honor: reduce earth damage - radiance: don't boost tomes, xp/loot bonuses atree: - parry: minor typo - death magnet: marked dep - nightcloak knife: 15s desc Api v3 (#267) * Tweak ordering to be consistent internally * v3 items (#266) * item_wrapper script for updating item data with v3 endpoint * metadata from v3 * v3 item format For the purpose of wynnbuilder, additional mapping might be needed. * v3 item format additional mapping might be needed for wb * v3 compressed item json * clean item json v3 format * Update translate map to api v3 partially... we will need to redo scripts to flatmap all the items * Fix items for 2.0.4.3 finally * New ingredients (and parse script update) just realized I forgot to commit the parse script this whole time * Forgot to commit data files, and bump ing db version * Sketchily reverse translate major ids internalname and separate lookup table lol * Forgot to update data files todo: script should update all files at once * Bump wynn version number already outdated... * Forgot to update 2.0.4.3 major ids --------- Co-authored-by: hppeng <hppeng> Co-authored-by: RawFish69 <108964215+RawFish69@users.noreply.github.com> Add missing fields to ingreds missing ids and consumableIDs tags in some ingreds Fix missing properties in item search setup these should be unified maybe to avoid duplicated code Fix sacshrine dependency on fluid healing also: fix ": " in item searcher I managed to mess up all major ids note: major ids min file is generated along with atree. it uses numeric ids, not just json compress 2.0.4.4 update (#269) * 2.0.4.4 update Fix v3 item api debug script Implement hellfire (discombob disallow not happening yet) * Fix boiling blood implementation slightly more intuitive also, janky first pass implementation for hellfire * Atree default update Allow sliders to specify a default value, for puppet and boiling blood for now * Fix rainbow def display on items and build stats Calculate into raw def correctly * Atree backend improvements Allow major ids to have dependencies Implement cherry bomb new ver. (wooo replace_spell just works out of the box!) Add comments to atree.js * Fix name of normal items don't you love it when wynn api makes breaking changes for no reason * Misc bugfix Reckless abandon req Tempest new damage ID in search * Fix major id search and temblor desc * Fix blockers on mage * Fix flaming uppercut implementation * Force base dps display to display less digits * Tomes finally pulling from the API but still with alias feature enabled! * Lootrun tomes (finally?) cool? maybe? * Fix beachside set set bonus --------- Co-authored-by: hppeng <hppeng> Fix rainbow def display on items and build stats Calculate into raw def correctly Fix major id search and temblor desc Force base dps display to display less digits Fix beachside set set bonus Fix build decode error reading only 7 tome fields no matter what Give NONE tomes correct ids in load_tome i hate this system so much Allow searching for max/min of ranges Fix crafted item damage display in the process, also update powder calculation logic! Should be fully correct now... TL;DR: Weapon damage is floating point; item display is wrong; ingame displays (damage floaters and compass) are floored. Fluid healing now multiplicative with heal efficiency ID NOTE: this breaks backwards compatibility with older atree jsons. Do we care about this? Realizing how much of a nightmare it will be (and already is) to keep atree fully backwards compatible. Maybe that will be something left to `git clone` instead. fix (#274)
2023-11-08 04:31:12 +00:00
damages = damages.map(x => Math.floor(x));
item.set(id, damages[0]+"-"+damages[1]);
}
else {
parent 3e725eded882cb6d353ca9b37931cb959dcdf9dc author hppeng <hppeng> 1699417872 -0800 committer hppeng <hppeng> 1720354753 -0700 parent 3e725eded882cb6d353ca9b37931cb959dcdf9dc author hppeng <hppeng> 1699417872 -0800 committer hppeng <hppeng> 1720354749 -0700 parent 3e725eded882cb6d353ca9b37931cb959dcdf9dc author hppeng <hppeng> 1699417872 -0800 committer hppeng <hppeng> 1720354744 -0700 parent 3e725eded882cb6d353ca9b37931cb959dcdf9dc author hppeng <hppeng> 1699417872 -0800 committer hppeng <hppeng> 1720354739 -0700 parent 3e725eded882cb6d353ca9b37931cb959dcdf9dc author hppeng <hppeng> 1699417872 -0800 committer hppeng <hppeng> 1720354735 -0700 parent 3e725eded882cb6d353ca9b37931cb959dcdf9dc author hppeng <hppeng> 1699417872 -0800 committer hppeng <hppeng> 1720354730 -0700 parent 3e725eded882cb6d353ca9b37931cb959dcdf9dc author hppeng <hppeng> 1699417872 -0800 committer hppeng <hppeng> 1720354688 -0700 Update recipes.json (#265) Change ratio of gems to oil as it has been updated in 2.0.4 > Updated the Jeweling Recipe Changes (Bracelet- 2:1 gems:oil, Necklaces- 3:1 gems:oil) https://forums.wynncraft.com/threads/2-0-4-full-changelog-new-bank-lootruns-more.310535/ Finish updating recipes.json why are there 4 versions of this file active at any given time Fix damage calculation for rainbow raw wow this bug has been here for a LONG time also bump version for ing db Bunch of bugfixes - new major ID - divine honor: reduce earth damage - radiance: don't boost tomes, xp/loot bonuses atree: - parry: minor typo - death magnet: marked dep - nightcloak knife: 15s desc Api v3 (#267) * Tweak ordering to be consistent internally * v3 items (#266) * item_wrapper script for updating item data with v3 endpoint * metadata from v3 * v3 item format For the purpose of wynnbuilder, additional mapping might be needed. * v3 item format additional mapping might be needed for wb * v3 compressed item json * clean item json v3 format * Update translate map to api v3 partially... we will need to redo scripts to flatmap all the items * Fix items for 2.0.4.3 finally * New ingredients (and parse script update) just realized I forgot to commit the parse script this whole time * Forgot to commit data files, and bump ing db version * Sketchily reverse translate major ids internalname and separate lookup table lol * Forgot to update data files todo: script should update all files at once * Bump wynn version number already outdated... * Forgot to update 2.0.4.3 major ids --------- Co-authored-by: hppeng <hppeng> Co-authored-by: RawFish69 <108964215+RawFish69@users.noreply.github.com> Add missing fields to ingreds missing ids and consumableIDs tags in some ingreds Fix missing properties in item search setup these should be unified maybe to avoid duplicated code Fix sacshrine dependency on fluid healing also: fix ": " in item searcher I managed to mess up all major ids note: major ids min file is generated along with atree. it uses numeric ids, not just json compress 2.0.4.4 update (#269) * 2.0.4.4 update Fix v3 item api debug script Implement hellfire (discombob disallow not happening yet) * Fix boiling blood implementation slightly more intuitive also, janky first pass implementation for hellfire * Atree default update Allow sliders to specify a default value, for puppet and boiling blood for now * Fix rainbow def display on items and build stats Calculate into raw def correctly * Atree backend improvements Allow major ids to have dependencies Implement cherry bomb new ver. (wooo replace_spell just works out of the box!) Add comments to atree.js * Fix name of normal items don't you love it when wynn api makes breaking changes for no reason * Misc bugfix Reckless abandon req Tempest new damage ID in search * Fix major id search and temblor desc * Fix blockers on mage * Fix flaming uppercut implementation * Force base dps display to display less digits * Tomes finally pulling from the API but still with alias feature enabled! * Lootrun tomes (finally?) cool? maybe? * Fix beachside set set bonus --------- Co-authored-by: hppeng <hppeng> Fix rainbow def display on items and build stats Calculate into raw def correctly Fix major id search and temblor desc Force base dps display to display less digits Fix beachside set set bonus Fix build decode error reading only 7 tome fields no matter what Give NONE tomes correct ids in load_tome i hate this system so much Allow searching for max/min of ranges Fix crafted item damage display in the process, also update powder calculation logic! Should be fully correct now... TL;DR: Weapon damage is floating point; item display is wrong; ingame displays (damage floaters and compass) are floored. Fluid healing now multiplicative with heal efficiency ID NOTE: this breaks backwards compatibility with older atree jsons. Do we care about this? Realizing how much of a nightmare it will be (and already is) to keep atree fully backwards compatible. Maybe that will be something left to `git clone` instead. fix (#274)
2023-11-08 04:31:12 +00:00
damages = damages.map(x => x.map(y => Math.floor(y)));
item.set(id, damages[0][0]+"-"+damages[0][1]+"\u279c"+damages[1][0]+"-"+damages[1][1]);
}
}
2021-01-19 17:32:27 +00:00
let p_elem;
// TODO: wtf is this if statement
if ( !(item.get("tier") === "Crafted" && item.get("category") === "armor" && id === "hp") && (!skp_order.includes(id)) || (skp_order.includes(id) && item.get("tier") !== "Crafted" && parent_div.nodeName === "table") ) { //skp warp
p_elem = displayFixedID(parent_div, id, item.get(id), elemental_format);
} else if (item.get("tier") === "Crafted" && item.get("category") === "armor" && id === "hp") {
p_elem = displayFixedID(parent_div, id, item.get(id+"Low")+"-"+item.get(id), elemental_format);
2021-09-25 18:57:57 +00:00
}
if (id === "lore") {
p_elem.style = "font-style: italic";
2021-01-11 07:05:23 +00:00
} else if (skp_order.includes(id)) { //id = str, dex, int, def, or agi
if ( item.get("tier") !== "Crafted") {
row = make_elem("div", ["col"]);
2021-01-19 17:32:27 +00:00
let title = document.createElement("b");
title.textContent = idPrefixes[id] + " ";
let boost = document.createElement("b");
if (item.get(id) < 0) {
boost.classList.add("negative");
} else { //boost = 0 SHOULD not come up
boost.classList.add("positive");
}
boost.textContent = item.get(id);
row.appendChild(title);
row.appendChild(boost);
parent_div.appendChild(row);
} else if ( item.get("tier") === "Crafted") {
2021-09-25 18:57:57 +00:00
let row = displayRolledID(item, id, elemental_format);
parent_div.appendChild(row);
2021-01-11 07:05:23 +00:00
}
} else if (id === "restrict") {
2021-01-11 07:05:23 +00:00
p_elem.classList.add("restrict");
}
}
2021-01-07 22:44:52 +00:00
}
2021-09-06 05:45:01 +00:00
else if ( rolledIDs.includes(id) &&
((item.get("maxRolls") && item.get("maxRolls").get(id))
|| (item.get("minRolls") && item.get("minRolls").get(id)))) {
2021-01-08 01:02:12 +00:00
let style = "positive";
if (item.get("minRolls").get(id) < 0) {
style = "negative";
}
if(reversedIDs.includes(id)){
2021-01-10 21:31:29 +00:00
style === "positive" ? style = "negative" : style = "positive";
}
2021-01-08 01:02:12 +00:00
if (fix_id) {
p_elem = document.createElement("div");
p_elem.classList.add("col", "text-nowrap");
if (id == "dex") {
console.log("dex activated at fix_id")
}
displayFixedID(p_elem, id, item.get("minRolls").get(id), elemental_format, style);
parent_div.appendChild(p_elem);
2021-01-08 01:02:12 +00:00
}
else {
2021-09-25 18:57:57 +00:00
let row = displayRolledID(item, id, elemental_format);
parent_div.appendChild(row);
2021-01-08 01:02:12 +00:00
}
2021-01-19 17:32:27 +00:00
}else{
// :/
}
2021-01-07 22:44:52 +00:00
}
}
//Show powder specials ;-;
let powder_specials_check = ["relik", "wand", "bow", "spear", "dagger", "chestplate", "helmet", "leggings", "boots"];
if(powder_specials_check.includes(item.get("type"))) {
let powder_special = make_elem("div", ['col']);
2021-01-19 17:32:27 +00:00
let powders = item.get("powders");
let element;
let power_index;
2021-01-19 17:32:27 +00:00
for (let i = 0; i < powders.length; i++) {
const firstPowderType = skp_elements[Math.floor(powders[i]/6)];
const powder1_power = powders[i] % 6;
if (powder1_power > 2) { //t4+
2021-01-19 17:32:27 +00:00
for (let j = i+1; j < powders.length; j++) {
const currentPowderType = skp_elements[Math.floor(powders[j]/6)]
const powder2_power = powders[j] % 6;
if (powder2_power > 2 && firstPowderType === currentPowderType) {
2021-01-19 17:32:27 +00:00
element = currentPowderType;
power_index = powder1_power + powder2_power - 6;
2021-01-19 17:32:27 +00:00
break;
}
}
}
if (element) { break; } // terminate early if already found.
}
if (element) {//powder special is "[e,t,w,f,a]+[0,1,2,3,4]"
const powderSpecial = powderSpecialStats[skp_elements.indexOf(element)];
const specialSuffixes = new Map([ ["Duration", " sec"], ["Radius", " blocks"], ["Chains", ""], ["Damage", "%"], ["Damage Boost", "%"], ["Knockback", " blocks"] ]);
const specialTitle = make_elem("span", [damageClasses[skp_elements.indexOf(element) + 1]]);
const specialEffects = document.createElement("span");
2021-01-19 17:32:27 +00:00
let effects;
if (item.get("category") === "weapon") {//weapon
effects = powderSpecial["weaponSpecialEffects"];
specialTitle.textContent = powderSpecial["weaponSpecialName"];
} else if (item.get("category") === "armor") {//armor
2021-01-19 17:32:27 +00:00
effects = powderSpecial["armorSpecialEffects"];
specialTitle.textContent += powderSpecial["armorSpecialName"] + ": ";
}
2021-02-03 17:47:48 +00:00
for (const [key,value] of effects.entries()) {
if (key !== "Description") {
let effect = make_elem("p", ["m-0"], {
textContent: key + ": " + value[power_index] + specialSuffixes.get(key)
});
2021-02-03 17:47:48 +00:00
if(key === "Damage"){
2021-01-19 17:32:27 +00:00
effect.textContent += elementIcons[skp_elements.indexOf(element)];
}
if (element === "w" && item.get("category") === "armor") {
2021-01-19 17:32:27 +00:00
effect.textContent += " / Mana Used";
}
specialEffects.appendChild(effect);
} else {
2021-01-19 17:32:27 +00:00
specialTitle.textContent += "[ " + effects.get("Description") + " ]";
}
}
powder_special.append(specialTitle, specialEffects);
2021-02-03 17:47:48 +00:00
parent_div.appendChild(powder_special);
}
}
2021-01-19 17:32:27 +00:00
let nonConsumables = ["relik", "wand", "bow", "spear", "dagger", "chestplate", "helmet", "leggings", "boots", "ring", "bracelet", "necklace"];
2021-01-19 17:32:27 +00:00
if(item.get("tier") && item.get("tier") === "Crafted") {
let dura_elem = make_elem("div", ["col"]);
let dura;
2021-01-19 17:32:27 +00:00
let suffix = "";
if(nonConsumables.includes(item.get("type"))) {
dura = item.get("durability");
dura_elem.textContent = "Durability: "
} else {
dura = item.get("duration");
dura_elem.textContent = "Duration: "
suffix = " sec."
parent_div.appendChild(make_elem('b', [], {
textContent: "Charges: " + item.get("charges")
}));
2021-01-19 17:32:27 +00:00
}
if (typeof(dura) === "string") {
dura_elem.textContent += dura + suffix;
} else {
dura_elem.textContent += dura[0]+"-"+dura[1] + suffix;
}
parent_div.append(dura_elem);
2021-01-28 00:52:34 +00:00
2021-01-19 17:32:27 +00:00
}
//Show item tier
if (item.get("tier") && item.get("tier") !== " ") {
let item_desc_elem = make_elem("div", ["col", item.get("tier")]);
if (tome_types.includes(item.get("type"))) {
item_desc_elem.textContent = item.get("tier")+" "+tome_type_map.get(item.get("type"));
} else {
item_desc_elem.textContent = item.get("tier")+" "+item.get("type");
}
parent_div.append(item_desc_elem);
2021-01-10 21:01:59 +00:00
}
//Show item hash if applicable
if (item.get("crafted") || item.get("custom")) {
parent_div.append(make_elem('p', ['itemp'], {
style: {
maxWidth: '100%',
wordWrap: 'break-word',
wordBreak: 'break-word'
},
textContent: item.get('hash')
}));
2021-04-17 09:54:44 +00:00
}
if (item.get("category") === "weapon") {
let total_damages = item.get("basedps");
let base_dps_elem = make_elem("p", ["left", "itemp"]);
2021-04-17 09:54:44 +00:00
if (item.get("tier") === "Crafted") {
2022-06-24 10:35:03 +00:00
let base_dps_min = total_damages[0];
let base_dps_max = total_damages[1];
2021-04-17 09:54:44 +00:00
base_dps_elem.textContent = "Base DPS: "+base_dps_min.toFixed(3)+"\u279c"+base_dps_max.toFixed(3);
2021-04-17 09:54:44 +00:00
}
else {
parent 3e725eded882cb6d353ca9b37931cb959dcdf9dc author hppeng <hppeng> 1699417872 -0800 committer hppeng <hppeng> 1720354753 -0700 parent 3e725eded882cb6d353ca9b37931cb959dcdf9dc author hppeng <hppeng> 1699417872 -0800 committer hppeng <hppeng> 1720354749 -0700 parent 3e725eded882cb6d353ca9b37931cb959dcdf9dc author hppeng <hppeng> 1699417872 -0800 committer hppeng <hppeng> 1720354744 -0700 parent 3e725eded882cb6d353ca9b37931cb959dcdf9dc author hppeng <hppeng> 1699417872 -0800 committer hppeng <hppeng> 1720354739 -0700 parent 3e725eded882cb6d353ca9b37931cb959dcdf9dc author hppeng <hppeng> 1699417872 -0800 committer hppeng <hppeng> 1720354735 -0700 parent 3e725eded882cb6d353ca9b37931cb959dcdf9dc author hppeng <hppeng> 1699417872 -0800 committer hppeng <hppeng> 1720354730 -0700 parent 3e725eded882cb6d353ca9b37931cb959dcdf9dc author hppeng <hppeng> 1699417872 -0800 committer hppeng <hppeng> 1720354688 -0700 Update recipes.json (#265) Change ratio of gems to oil as it has been updated in 2.0.4 > Updated the Jeweling Recipe Changes (Bracelet- 2:1 gems:oil, Necklaces- 3:1 gems:oil) https://forums.wynncraft.com/threads/2-0-4-full-changelog-new-bank-lootruns-more.310535/ Finish updating recipes.json why are there 4 versions of this file active at any given time Fix damage calculation for rainbow raw wow this bug has been here for a LONG time also bump version for ing db Bunch of bugfixes - new major ID - divine honor: reduce earth damage - radiance: don't boost tomes, xp/loot bonuses atree: - parry: minor typo - death magnet: marked dep - nightcloak knife: 15s desc Api v3 (#267) * Tweak ordering to be consistent internally * v3 items (#266) * item_wrapper script for updating item data with v3 endpoint * metadata from v3 * v3 item format For the purpose of wynnbuilder, additional mapping might be needed. * v3 item format additional mapping might be needed for wb * v3 compressed item json * clean item json v3 format * Update translate map to api v3 partially... we will need to redo scripts to flatmap all the items * Fix items for 2.0.4.3 finally * New ingredients (and parse script update) just realized I forgot to commit the parse script this whole time * Forgot to commit data files, and bump ing db version * Sketchily reverse translate major ids internalname and separate lookup table lol * Forgot to update data files todo: script should update all files at once * Bump wynn version number already outdated... * Forgot to update 2.0.4.3 major ids --------- Co-authored-by: hppeng <hppeng> Co-authored-by: RawFish69 <108964215+RawFish69@users.noreply.github.com> Add missing fields to ingreds missing ids and consumableIDs tags in some ingreds Fix missing properties in item search setup these should be unified maybe to avoid duplicated code Fix sacshrine dependency on fluid healing also: fix ": " in item searcher I managed to mess up all major ids note: major ids min file is generated along with atree. it uses numeric ids, not just json compress 2.0.4.4 update (#269) * 2.0.4.4 update Fix v3 item api debug script Implement hellfire (discombob disallow not happening yet) * Fix boiling blood implementation slightly more intuitive also, janky first pass implementation for hellfire * Atree default update Allow sliders to specify a default value, for puppet and boiling blood for now * Fix rainbow def display on items and build stats Calculate into raw def correctly * Atree backend improvements Allow major ids to have dependencies Implement cherry bomb new ver. (wooo replace_spell just works out of the box!) Add comments to atree.js * Fix name of normal items don't you love it when wynn api makes breaking changes for no reason * Misc bugfix Reckless abandon req Tempest new damage ID in search * Fix major id search and temblor desc * Fix blockers on mage * Fix flaming uppercut implementation * Force base dps display to display less digits * Tomes finally pulling from the API but still with alias feature enabled! * Lootrun tomes (finally?) cool? maybe? * Fix beachside set set bonus --------- Co-authored-by: hppeng <hppeng> Fix rainbow def display on items and build stats Calculate into raw def correctly Fix major id search and temblor desc Force base dps display to display less digits Fix beachside set set bonus Fix build decode error reading only 7 tome fields no matter what Give NONE tomes correct ids in load_tome i hate this system so much Allow searching for max/min of ranges Fix crafted item damage display in the process, also update powder calculation logic! Should be fully correct now... TL;DR: Weapon damage is floating point; item display is wrong; ingame displays (damage floaters and compass) are floored. Fluid healing now multiplicative with heal efficiency ID NOTE: this breaks backwards compatibility with older atree jsons. Do we care about this? Realizing how much of a nightmare it will be (and already is) to keep atree fully backwards compatible. Maybe that will be something left to `git clone` instead. fix (#274)
2023-11-08 04:31:12 +00:00
base_dps_elem.textContent = "Base DPS: "+(total_damages.toFixed(3));
2021-04-17 09:54:44 +00:00
}
parent_div.append(make_elem("p"), base_dps_elem);
}
2021-01-07 22:44:52 +00:00
}
/*
* Displays stats about a recipe that are NOT displayed in the craft stats.
* Includes: mat name and amounts, ingred names in an "array" with ingred effectiveness
*/
function displayRecipeStats(craft, parent_id) {
let elem = document.getElementById(parent_id);
//local vars
elem.textContent = "";
recipe = craft["recipe"];
mat_tiers = craft["mat_tiers"];
ingreds = [];
for (const n of craft["ingreds"]) {
ingreds.push(n.get("name"));
}
let effectiveness = craft["statMap"].get("ingredEffectiveness");
let title = document.createElement("div");
2022-07-12 05:10:55 +00:00
title.classList.add("col", "box-title", "fw-bold", "justify-content-center", "scaled-font");
title.textContent = "Recipe Stats";
elem.appendChild(title);
let mats = document.createElement("div");
2022-07-12 05:10:55 +00:00
mats.classList.add("col");
mats.textContent = "Crafting Materials: ";
elem.appendChild(mats);
for (let i = 0; i < 2; i++) {
let tier = mat_tiers[i];
2022-07-12 05:10:55 +00:00
let col = document.createElement("div");
col.classList.add("col", "ps-4");
let b = document.createElement("span");
let mat = recipe.get("materials")[i];
b.textContent = "- " + mat.get("amount") + "x " + mat.get("item").split(" ").slice(1).join(" ");
b.classList.add("col");
2022-07-12 05:10:55 +00:00
col.appendChild(b);
2022-07-12 05:10:55 +00:00
let starsContainer = document.createElement("span");
let starsB = document.createElement("span");
starsB.classList.add("T1-bracket", "px-0");
starsB.textContent = "[";
2022-07-12 05:10:55 +00:00
starsContainer.appendChild(starsB);
for(let j = 0; j < 3; j ++) {
2022-07-12 05:10:55 +00:00
let star = document.createElement("span");
star.classList.add("px-0");
star.textContent = "\u272B";
if(j < tier) {
star.classList.add("T1");
} else {
star.classList.add("T0");
}
2022-07-12 05:10:55 +00:00
starsContainer.append(star);
}
2022-07-12 05:10:55 +00:00
let starsE = document.createElement("span");
starsE.classList.add("T1-bracket", "px-0");
starsE.textContent = "]";
2022-07-12 05:10:55 +00:00
starsContainer.appendChild(starsE);
col.appendChild(starsContainer);
2022-07-12 05:10:55 +00:00
elem.appendChild(col);
}
let ingredTable = document.createElement("div");
2022-07-12 05:10:55 +00:00
ingredTable.classList.add("col", "mt-2");
let ingredContainer = document.createElement("div");
ingredContainer.classList.add("row", "row-cols-2", "g-3");
for (let i = 0; i < 6; i++) {
let ingredCell = document.createElement("div");
ingredCell.classList.add("col");
let ingredTextContainer = document.createElement("div");
ingredTextContainer.classList.add("border", "border-3", "rounded")
let ingredName = ingreds[i];
let ingred_text = document.createElement("p");
ingred_text.classList.add("mb-2", "ps-2");
ingred_text.textContent = ingredName;
ingredTextContainer.appendChild(ingred_text);
let eff_div = document.createElement("p");
eff_div.classList.add("mb-2", "ps-2");
let e = effectiveness[i];
if (e > 0) {
eff_div.classList.add("positive");
} else if (e < 0) {
eff_div.classList.add("negative");
}
eff_div.textContent = "[" + e + "%]";
ingredTextContainer.appendChild(eff_div);
2022-07-12 05:10:55 +00:00
ingredCell.appendChild(ingredTextContainer);
2022-07-12 05:10:55 +00:00
ingredContainer.appendChild(ingredCell);
}
2022-07-12 05:10:55 +00:00
ingredTable.appendChild(ingredContainer);
elem.appendChild(ingredTable);
}
//Displays a craft. If things change, this function should be modified.
function displayCraftStats(craft, parent_id) {
2021-01-19 17:32:27 +00:00
let mock_item = craft.statMap;
displayExpandedItem(mock_item,parent_id);
}
/*
* Displays an ingredient in item format.
* However, an ingredient is too far from a normal item to display as one.
*/
function displayExpandedIngredient(ingred, parent_id) {
2021-01-18 20:23:37 +00:00
let parent_elem = document.getElementById(parent_id);
parent_elem.textContent = "";
2021-01-18 20:23:37 +00:00
let item_order = [
"dura",
"strReq",
"dexReq",
"intReq",
"defReq",
"agiReq"
]
let consumable_order = [
"dura",
"charges"
]
let posMods_order = [
"above",
2021-01-19 17:32:27 +00:00
"under",
2021-01-18 20:23:37 +00:00
"left",
"right",
"touching",
"notTouching"
];
let id_display_order = [
"eDefPct",
"tDefPct",
"wDefPct",
"fDefPct",
"aDefPct",
"eDamPct",
"tDamPct",
"wDamPct",
"fDamPct",
"aDamPct",
"str",
"dex",
"int",
"agi",
"def",
"hpBonus",
"mr",
"ms",
"ls",
"hprRaw",
"hprPct",
"sdRaw",
"sdPct",
"mdRaw",
"mdPct",
"xpb",
"lb",
"lq",
"ref",
"thorns",
"expd",
"spd",
"atkTier",
"poison",
"spRegen",
"eSteal",
"spRaw1",
"spRaw2",
"spRaw3",
"spRaw4",
"spPct1",
"spPct2",
"spPct3",
"spPct4",
"jh",
"sprint",
"sprintReg",
"gXp",
"gSpd",
];
2021-01-18 20:23:37 +00:00
let active_elem;
let elemental_format = false;
let style;
for (const command of sq2_ing_display_order) {
if (command.charAt(0) === "!") {
// TODO: This is sooo incredibly janky.....
if (command === "!elemental") {
elemental_format = !elemental_format;
2021-01-18 20:23:37 +00:00
}
else if (command === "!spacer") {
let spacer = document.createElement('div');
spacer.classList.add("row", "my-2");
parent_elem.appendChild(spacer);
continue;
2021-01-18 20:23:37 +00:00
}
} else {
let div = document.createElement("div");
div.classList.add("row");
2021-03-04 13:48:10 +00:00
if (command === "displayName") {
div.classList.add("box-title");
let title_elem = document.createElement("div");
title_elem.classList.add("col-auto", "justify-content-center", "pr-1");
2021-03-04 13:48:10 +00:00
title_elem.textContent = ingred.get("displayName");
div.appendChild(title_elem);
2021-01-18 20:23:37 +00:00
let tier = ingred.get("tier"); //tier in [0,3]
let begin = document.createElement("b");
begin.classList.add("T"+tier+"-bracket", "col-auto", "px-0");
2021-01-18 20:23:37 +00:00
begin.textContent = "[";
div.appendChild(begin);
2021-01-18 20:23:37 +00:00
for (let i = 0; i < 3; i++) {
let tier_elem = document.createElement("b");
if (i < tier) {
tier_elem.classList.add("T"+tier);
} else {
tier_elem.classList.add("T0");
}
tier_elem.classList.add("px-0", "col-auto");
2021-01-18 20:23:37 +00:00
tier_elem.textContent = "\u272B";
div.appendChild(tier_elem);
2021-01-18 20:23:37 +00:00
}
let end = document.createElement("b");
end.classList.add("T"+tier+"-bracket", "px-0", "col-auto");
2021-01-18 20:23:37 +00:00
end.textContent = "]";
div.appendChild(end);
2021-01-18 20:23:37 +00:00
}else if (command === "lvl") {
div.textContent = "Crafting Lvl Min: " + ingred.get("lvl");
2021-01-18 20:23:37 +00:00
}else if (command === "posMods") {
for (const [key,value] of ingred.get("posMods")) {
let posModRow = document.createElement("div");
posModRow.classList.add("row");
2021-01-18 20:23:37 +00:00
if (value != 0) {
let posMod = document.createElement("div");
posMod.classList.add("col-auto");
posMod.textContent = posModPrefixes[key];
posModRow.appendChild(posMod);
let val = document.createElement("div");
val.classList.add("col-auto", "px-0");
2021-01-18 20:23:37 +00:00
val.textContent = value + posModSuffixes[key];
if(value > 0) {
val.classList.add("positive");
} else {
val.classList.add("negative");
}
posModRow.appendChild(val);
div.appendChild(posModRow);
2021-01-18 20:23:37 +00:00
}
}
} else if (command === "itemIDs") { //dura, reqs
for (const [key,value] of ingred.get("itemIDs")) {
let idRow = document.createElement("div");
idRow.classList.add("row");
2021-01-18 20:23:37 +00:00
if (value != 0) {
let title = document.createElement("div");
title.classList.add("col-auto");
2021-01-18 20:23:37 +00:00
title.textContent = itemIDPrefixes[key];
idRow.appendChild(title);
2021-01-18 20:23:37 +00:00
}
let desc = document.createElement("div");
desc.classList.add("col-auto");
2021-01-18 20:23:37 +00:00
if(value > 0) {
if(key !== "dura") {
desc.classList.add("negative");
} else{
desc.classList.add("positive");
}
desc.textContent = "+"+value;
} else if (value < 0){
if(key !== "dura") {
desc.classList.add("positive");
} else{
desc.classList.add("negative");
}
desc.textContent = value;
}
if(value != 0){
idRow.appendChild(desc);
2021-01-18 20:23:37 +00:00
}
div.appendChild(idRow);
2021-01-18 20:23:37 +00:00
}
} else if (command === "consumableIDs") { //dura, charges
for (const [key,value] of ingred.get("consumableIDs")) {
let idRow = document.createElement("div");
idRow.classList.add("row");
2021-01-18 20:23:37 +00:00
if (value != 0) {
let title = document.createElement("div");
title.classList.add("col-auto");
2021-01-18 20:23:37 +00:00
title.textContent = consumableIDPrefixes[key];
idRow.appendChild(title);
2021-01-18 20:23:37 +00:00
}
let desc = document.createElement("div");
desc.classList.add("col-auto");
2021-01-18 20:23:37 +00:00
if(value > 0) {
desc.classList.add("positive");
desc.textContent = "+"+value;
} else if (value < 0){
desc.classList.add("negative");
desc.textContent = value;
}
if(value != 0){
idRow.appendChild(desc);
let suffix = document.createElement("div");
suffix.classList.add("col-auto");
2021-01-18 20:23:37 +00:00
suffix.textContent = consumableIDSuffixes[key];
idRow.appendChild(suffix);
2021-01-18 20:23:37 +00:00
}
div.appendChild(idRow);
2021-01-18 20:23:37 +00:00
}
}else if (command === "skills") {
let row = document.createElement("div");
row.classList.add("row");
let title = document.createElement("div");
title.classList.add("row");
title.textContent = "Used in:";
row.appendChild(title);
2021-01-18 20:23:37 +00:00
for(const skill of ingred.get("skills")) {
let skill_div = document.createElement("div");
2022-07-12 05:10:55 +00:00
skill_div.classList.add("row", "ps-4");
skill_div.textContent = skill.charAt(0) + skill.substring(1).toLowerCase();
row.appendChild(skill_div);
2021-01-18 20:23:37 +00:00
}
div.appendChild(row);
2021-01-18 20:23:37 +00:00
} else if (command === "ids") { //warp
for (let [key,value] of ingred.get("ids").get("maxRolls")) {
if (value !== undefined && value != 0) {
let row = displayRolledID(ingred.get("ids"), key, elemental_format);
row.classList.remove("col");
row.classList.remove("col-12");
div.appendChild(row);
2021-01-18 20:23:37 +00:00
}
}
} else {//this shouldn't be happening
}
parent_elem.appendChild(div);
2021-01-18 20:23:37 +00:00
}
}
}
2021-01-09 08:52:58 +00:00
function displayNextCosts(_stats, spell, spellIdx) {
let stats = new Map(_stats);
let intel = stats.get('int');
let row = document.createElement("div");
row.classList.add("spellcost-tooltip");
let init_cost = document.createElement("b");
init_cost.textContent = getSpellCost(stats, spellIdx, spell.cost);
init_cost.classList.add("Mana");
let arrow = document.createElement("b");
arrow.textContent = "\u279C";
let next_cost = document.createElement("b");
next_cost.textContent = (init_cost.textContent === "1" ? 1 : getSpellCost(stats, spellIdx, spell.cost) - 1);
next_cost.classList.add("Mana");
let int_needed = document.createElement("b");
if (init_cost.textContent === "1") {
int_needed.textContent = ": n/a (+0)";
} else { //do math
let target = getSpellCost(stats, spellIdx, spell.cost) - 1;
let needed = intel;
let noUpdate = false;
//forgive me... I couldn't inverse ceil, floor, and max.
while (getSpellCost(stats, spellIdx, spell.cost) > target) {
if(needed > 150) {
noUpdate = true;
break;
2021-01-15 20:36:12 +00:00
}
needed++;
stats.set('int', stats.get('int') + 1);
}
let missing = needed - intel;
//in rare circumstances, the next spell cost can jump.
if (noUpdate) {
next_cost.textContent = (init_cost.textContent === "1" ? 1 : getSpellCost(stats, spellIdx, spell.cost)-1);
}else {
next_cost.textContent = (init_cost.textContent === "1" ? 1 : getSpellCost(stats, spellIdx, spell.cost));
}
int_needed.textContent = ": " + (needed > 150 ? ">150" : needed) + " int (+" + (needed > 150 ? "n/a" : missing) + ")";
}
// row.appendChild(init_cost);
row.appendChild(arrow);
row.appendChild(next_cost);
row.appendChild(int_needed);
return row;
}
2021-09-25 18:57:57 +00:00
function displayRolledID(item, id, elemental_format) {
2022-06-20 17:51:17 +00:00
let row = document.createElement('div');
row.classList.add('col');
let item_div = document.createElement('div');
item_div.classList.add('row');
let min_elem = document.createElement('div');
min_elem.classList.add('col', 'text-start');
min_elem.style.cssText += "flex-grow: 0";
2021-09-25 18:57:57 +00:00
let id_min = item.get("minRolls").get(id)
let style = id_min < 0 ? "negative" : "positive";
if(reversedIDs.includes(id)){
style === "positive" ? style = "negative" : style = "positive";
}
min_elem.classList.add(style);
min_elem.textContent = id_min + idSuffixes[id];
2022-06-20 17:51:17 +00:00
item_div.appendChild(min_elem);
2021-09-25 18:57:57 +00:00
2022-06-20 17:51:17 +00:00
let desc_elem = document.createElement('div');
desc_elem.classList.add('col', 'text-center');//, 'text-nowrap');
desc_elem.style.cssText += "flex-grow: 1";
2021-09-25 18:57:57 +00:00
//TODO elemental format jank
if (elemental_format) {
apply_elemental_format(desc_elem, id);
}
else {
desc_elem.textContent = idPrefixes[id];
}
2022-06-20 17:51:17 +00:00
item_div.appendChild(desc_elem);
2021-09-25 18:57:57 +00:00
2022-06-20 17:51:17 +00:00
let max_elem = document.createElement('div');
2021-09-25 18:57:57 +00:00
let id_max = item.get("maxRolls").get(id)
2022-06-20 17:51:17 +00:00
max_elem.classList.add('col', 'text-end');
max_elem.style.cssText += "flex-grow: 0";
2021-09-25 18:57:57 +00:00
style = id_max < 0 ? "negative" : "positive";
2022-06-20 17:51:17 +00:00
if (reversedIDs.includes(id)) {
2021-09-25 18:57:57 +00:00
style === "positive" ? style = "negative" : style = "positive";
}
max_elem.classList.add(style);
max_elem.textContent = id_max + idSuffixes[id];
2022-06-20 17:51:17 +00:00
item_div.appendChild(max_elem);
row.appendChild(item_div);
2021-09-25 18:57:57 +00:00
return row;
}
2021-01-09 12:47:25 +00:00
function displayFixedID(active, id, value, elemental_format, style) {
if (style) {
let row = document.createElement('div');
row.classList.add("row");
let desc_elem = document.createElement('div');
desc_elem.classList.add('col');
desc_elem.classList.add('text-start');
2021-01-09 12:47:25 +00:00
if (elemental_format) {
apply_elemental_format(desc_elem, id);
}
else {
desc_elem.textContent = idPrefixes[id];
}
row.appendChild(desc_elem);
2021-01-09 11:56:10 +00:00
let value_elem = document.createElement('div');
value_elem.classList.add('col');
value_elem.classList.add('text-end');
2021-01-09 12:47:25 +00:00
value_elem.classList.add(style);
value_elem.textContent = value + idSuffixes[id];
row.appendChild(value_elem);
active.appendChild(row);
return row;
}
else {
// HACK TO AVOID DISPLAYING ZERO DAMAGE! TODO
2021-01-28 00:52:34 +00:00
if (value === "0-0" || value === "0-0\u279c0-0") {
2021-01-09 12:47:25 +00:00
return;
}
let p_elem = document.createElement('div');
p_elem.classList.add('col');
2021-01-09 12:47:25 +00:00
if (elemental_format) {
apply_elemental_format(p_elem, id, value);
}
else {
p_elem.textContent = idPrefixes[id].concat(value, idSuffixes[id]);
}
active.appendChild(p_elem);
return p_elem;
}
2021-01-09 11:56:10 +00:00
}
function displayPoisonDamage(overallparent_elem, statMap) {
overallparent_elem.textContent = "";
if (statMap.get('poison') <= 0) {
overallparent_elem.style = "display: none";
return;
}
overallparent_elem.style = "";
let container = make_elem('div', ['col', 'pe-0']);
let spell_summary = make_elem('div', ["col", "spell-display", "dark-5", "rounded", "dark-shadow", "py-2", "border", "border-dark"]);
//Title
let title_elemavg = make_elem("b");
title_elemavg.append(make_elem('span', [], { textContent: "Poison Stats" }));
spell_summary.append(title_elemavg);
let poison_tick = Math.floor(statMap.get("poison")/3);
//let poison_tick = Math.ceil(statMap.get("poison") * (1+skillPointsToPercentage(statMap.get('str'))) * (statMap.get("poisonPct"))/100 /3);
let overallpoisonDamage = make_elem("p");
overallpoisonDamage.append(
make_elem("span", [], { textContent: "Poison Tick: " }),
make_elem("span", ["Damage"], { textContent: Math.max(poison_tick,0) })
);
spell_summary.append(overallpoisonDamage);
container.append(spell_summary);
overallparent_elem.append(container);
}
function displayEquipOrder(parent_elem, buildOrder){
2021-01-10 21:01:59 +00:00
parent_elem.textContent = "";
const order = buildOrder.slice();
let title_elem = document.createElement("b");
2021-01-10 21:01:59 +00:00
title_elem.textContent = "Equip order ";
title_elem.classList.add("Normal", "text-center");
2021-01-10 21:01:59 +00:00
parent_elem.append(title_elem);
for (const item of order) {
let p_elem = document.createElement("b");
2021-01-10 21:01:59 +00:00
p_elem.textContent = item.get("displayName");
parent_elem.append(p_elem);
}
}
2021-01-10 22:38:17 +00:00
2022-06-20 13:12:22 +00:00
function displayDefenseStats(parent_elem, statMap, insertSummary){
let defenseStats = getDefenseStats(statMap);
2021-01-11 22:25:55 +00:00
insertSummary = (typeof insertSummary !== 'undefined') ? insertSummary : false;
if (!insertSummary) {
parent_elem.textContent = "";
}
2021-01-10 21:01:59 +00:00
const stats = defenseStats.slice();
2021-01-11 22:25:55 +00:00
// parent_elem.append(document.createElement("br"));
let statsTable = document.createElement("div");
2021-01-10 21:01:59 +00:00
//[total hp, ehp, total hpr, ehpr, [def%, agi%], [edef,tdef,wdef,fdef,adef]]
for(const i in stats){
if(typeof stats[i] === "number"){
stats[i] = stats[i].toFixed(2);
}else{
for(const j in stats[i]){
stats[i][j] = stats[i][j].toFixed(2);
}
}
}
2021-01-11 22:25:55 +00:00
2021-01-10 21:01:59 +00:00
//total HP
let hpRow = document.createElement("div");
hpRow.classList.add('row');
let hp = document.createElement("div");
hp.classList.add('col');
2021-01-10 21:31:29 +00:00
hp.classList.add("Health");
hp.classList.add("text-start");
2021-01-11 22:25:55 +00:00
hp.textContent = "Total HP:";
let boost = document.createElement("div");
boost.classList.add('col');
2021-01-10 21:31:29 +00:00
boost.textContent = stats[0];
boost.classList.add("text-end");
2021-01-10 21:31:29 +00:00
hpRow.appendChild(hp);
hpRow.append(boost);
if (insertSummary) {
parent_elem.appendChild(hpRow);
} else {
statsTable.appendChild(hpRow);
}
2021-01-11 22:25:55 +00:00
2021-01-10 21:01:59 +00:00
//EHP
let ehpRow = document.createElement("div");
ehpRow.classList.add("row");
let ehp = document.createElement("div");
ehp.classList.add("col");
ehp.classList.add("text-start");
2021-01-10 21:31:29 +00:00
ehp.textContent = "Effective HP:";
boost = document.createElement("div");
2021-01-11 00:46:30 +00:00
boost.textContent = stats[1][0];
boost.classList.add("col");
boost.classList.add("text-end");
2021-01-10 21:31:29 +00:00
ehpRow.appendChild(ehp);
ehpRow.append(boost);
2021-01-11 00:46:30 +00:00
if (insertSummary) {
parent_elem.appendChild(ehpRow)
} else {
statsTable.append(ehpRow);
}
ehpRow = document.createElement("div");
ehpRow.classList.add("row");
ehp = document.createElement("div");
ehp.classList.add("col");
ehp.classList.add("text-start");
2021-01-11 00:46:30 +00:00
ehp.textContent = "Effective HP (no agi):";
boost = document.createElement("div");
2021-01-11 00:46:30 +00:00
boost.textContent = stats[1][1];
boost.classList.add("col");
boost.classList.add("text-end");
2021-01-11 00:46:30 +00:00
ehpRow.appendChild(ehp);
ehpRow.append(boost);
if (insertSummary) {
parent_elem.appendChild(ehpRow)
} else {
statsTable.append(ehpRow);
}
2021-01-11 00:46:30 +00:00
2021-01-10 21:01:59 +00:00
//total HPR
let hprRow = document.createElement("div");
hprRow.classList.add("row")
let hpr = document.createElement("div");
2021-01-10 21:31:29 +00:00
hpr.classList.add("Health");
hpr.classList.add("col");
hpr.classList.add("text-start");
2021-01-11 22:25:55 +00:00
hpr.textContent = "HP Regen (Total):";
boost = document.createElement("div");
2021-01-10 22:38:17 +00:00
boost.textContent = stats[2];
boost.classList.add("col");
boost.classList.add("text-end");
2021-01-10 22:38:17 +00:00
2021-01-10 21:31:29 +00:00
hprRow.appendChild(hpr);
hprRow.appendChild(boost);
if (insertSummary) {
parent_elem.appendChild(hprRow);
} else {
statsTable.appendChild(hprRow);
}
2021-01-19 10:12:36 +00:00
//EHPR
let ehprRow = document.createElement("div");
ehprRow.classList.add("row")
let ehpr = document.createElement("div");
ehpr.classList.add("col");
ehpr.classList.add("text-start");
2021-01-10 21:31:29 +00:00
ehpr.textContent = "Effective HP Regen:";
boost = document.createElement("div");
2021-01-11 00:46:30 +00:00
boost.textContent = stats[3][0];
boost.classList.add("col");
boost.classList.add("text-end");
2021-01-11 00:46:30 +00:00
ehprRow.appendChild(ehpr);
ehprRow.append(boost);
if (insertSummary) {
parent_elem.appendChild(ehprRow);
} else {
statsTable.appendChild(ehprRow);
}
2021-01-11 22:25:55 +00:00
2021-01-10 21:01:59 +00:00
//eledefs
let eledefs = stats[5];
for (let i = 0; i < eledefs.length; i++){
let eledefElemRow = document.createElement("div");
eledefElemRow.classList.add("row")
2021-01-10 21:31:29 +00:00
let eledef = document.createElement("div");
eledef.classList.add("col");
eledef.classList.add("text-start");
let eledefTitle = document.createElement("span");
2021-01-10 21:31:29 +00:00
eledefTitle.textContent = damageClasses[i+1];
eledefTitle.classList.add(damageClasses[i+1]);
let defense = document.createElement("span");
2021-01-11 22:25:55 +00:00
defense.textContent = " Def (Total): ";
eledef.appendChild(eledefTitle);
eledef.appendChild(defense);
eledefElemRow.appendChild(eledef);
2021-01-10 21:31:29 +00:00
let boost = document.createElement("div");
2021-01-10 21:31:29 +00:00
boost.textContent = eledefs[i];
boost.classList.add(eledefs[i] >= 0 ? "positive" : "negative");
boost.classList.add("col");
boost.classList.add("text-end");
eledefElemRow.appendChild(boost);
if (insertSummary) {
parent_elem.appendChild(eledefElemRow);
} else {
statsTable.appendChild(eledefElemRow);
}
2021-01-10 21:01:59 +00:00
}
2021-01-11 22:25:55 +00:00
if (!insertSummary) {
//skp
let defRow = document.createElement("div");
defRow.classList.add("row");
let defElem = document.createElement("div");
defElem.classList.add("col");
defElem.classList.add("text-start");
2021-01-11 22:25:55 +00:00
defElem.textContent = "Damage Absorbed %:";
boost = document.createElement("div");
boost.classList.add("col");
boost.classList.add("text-end");
2021-01-11 22:25:55 +00:00
boost.textContent = stats[4][0] + "%";
defRow.appendChild(defElem);
defRow.appendChild(boost);
statsTable.append(defRow);
let agiRow = document.createElement("div");
agiRow.classList.add("row");
let agiElem = document.createElement("div");
agiElem.classList.add("col");
agiElem.classList.add("text-start");
2021-01-11 22:25:55 +00:00
agiElem.textContent = "Dodge Chance %:";
boost = document.createElement("div");
boost.classList.add("col");
boost.classList.add("text-end");
2021-01-11 22:25:55 +00:00
boost.textContent = stats[4][1] + "%";
agiRow.appendChild(agiElem);
agiRow.appendChild(boost);
statsTable.append(agiRow);
}
2021-01-10 21:31:29 +00:00
if (!insertSummary) {
parent_elem.append(statsTable);
}
2021-01-09 23:30:05 +00:00
}
function displayPowderSpecials(parent_elem, powderSpecials, stats, weapon) {
parent_elem.textContent = "";
if (powderSpecials.length === 0) {
parent_elem.style = "display: none";
return;
}
parent_elem.style = "";
2022-06-20 17:51:17 +00:00
const skillpoints = [
stats.get('str'),
stats.get('dex'),
stats.get('int'),
stats.get('def'),
stats.get('agi')
];
parent_elem.append(make_elem("b", [], { textContent: "Powder Specials" }));
2021-01-12 21:07:03 +00:00
let specials = powderSpecials.slice();
let expandedStats = new Map();
2021-01-12 21:07:03 +00:00
//each entry of powderSpecials is [ps, power]
for (special of specials) {
2021-01-13 06:57:07 +00:00
//iterate through the special and display its effects.
let powder_special_elem = make_elem("p", ["pt-3"]);
2021-01-12 21:07:03 +00:00
let specialSuffixes = new Map([ ["Duration", " sec"], ["Radius", " blocks"], ["Chains", ""], ["Damage", "%"], ["Damage Boost", "%"], ["Knockback", " blocks"] ]);
let specialTitle = make_elem("p");
let specialEffects = make_elem("p");
// TODO janky and depends on the order of powder specials being ETWFA. This should be encoded in the powder special object.
let element_num = powderSpecialStats.indexOf(special[0]) + 1;
specialTitle.classList.add(damageClasses[element_num]);
let powder_special = special[0];
let power = special[1];
specialTitle.textContent = powder_special.weaponSpecialName + " " + Math.floor((power-1)*0.5 + 4) + (power % 2 == 0 ? ".5" : "");
for (const [key,value] of powder_special.weaponSpecialEffects) {
if(key === "Damage"){
//if this special is an instant-damage special (Quake, Chain Lightning, Courage Burst), display the damage.
let specialDamage = document.createElement("p");
// specialDamage.classList.add("item-margin");
let conversions = [0, 0, 0, 0, 0, 0];
conversions[element_num] = powder_special.weaponSpecialEffects.get("Damage")[power-1];
let _results = calculateSpellDamage(stats, weapon, conversions, false, true, "0.Powder Special");
let critChance = skillPointsToPercentage(skillpoints[1]);
let save_damages = [];
2022-06-20 17:51:17 +00:00
let totalDamNormal = _results[0];
let totalDamCrit = _results[1];
let results = _results[2];
for (let i = 0; i < 6; ++i) {
for (let j in results[i]) {
results[i][j] = results[i][j].toFixed(2);
2022-06-20 17:51:17 +00:00
}
}
let nonCritAverage = (totalDamNormal[0]+totalDamNormal[1])/2 || 0;
let critAverage = (totalDamCrit[0]+totalDamCrit[1])/2 || 0;
let averageDamage = (1-critChance)*nonCritAverage+critChance*critAverage || 0;
2021-01-12 21:07:03 +00:00
let averageWrap = document.createElement("p");
let averageLabel = document.createElement("span");
averageLabel.textContent = "Average: ";
let averageLabelDmg = document.createElement("span");
averageLabelDmg.classList.add("Damage");
averageLabelDmg.textContent = averageDamage.toFixed(2);
averageWrap.appendChild(averageLabel);
averageWrap.appendChild(averageLabelDmg);
specialDamage.appendChild(averageWrap);
specialEffects.append(specialDamage);
2022-06-20 17:51:17 +00:00
}
else {
let effect = document.createElement("p");
effect.textContent += key + ": " + value[power-1] + specialSuffixes.get(key);
specialEffects.appendChild(effect);
}
}
powder_special_elem.appendChild(specialTitle);
powder_special_elem.appendChild(specialEffects);
2021-01-12 21:07:03 +00:00
parent_elem.appendChild(powder_special_elem);
2021-01-13 06:57:07 +00:00
}
2021-01-12 21:07:03 +00:00
}
function getSpellCost(stats, spell) {
return Math.max(1, getBaseSpellCost(stats, spell) * (1 + stats.get('spPct'+spell.base_spell+'Final')/100));
}
function getBaseSpellCost(stats, spell) {
let cost = spell.cost * (1 - skillPointsToPercentage(stats.get('int')) * skillpoint_final_mult[2]);
cost += stats.get("spRaw"+spell.base_spell);
return cost * (1 + stats.get("spPct"+spell.base_spell) / 100);
}
function displaySpellDamage(parent_elem, _overallparent_elem, stats, spell, spellIdx, spell_results) {
// TODO: remove spellIdx (just used to flag melee and cost)
// TODO: move cost calc out
2021-01-09 08:52:58 +00:00
parent_elem.textContent = "";
let title_elem = make_elem("p");
2021-01-10 21:01:59 +00:00
_overallparent_elem.textContent = "";
const overallparent_elem = make_elem("div", ['col'])
let title_elemavg = document.createElement("b");
2021-01-10 21:31:29 +00:00
if ('cost' in spell) {
let first = make_elem("span", [], { textContent: spell.name + " (" });
2021-01-16 07:30:19 +00:00
title_elem.appendChild(first.cloneNode(true)); //cloneNode is needed here.
title_elemavg.appendChild(first);
let second = make_elem("span", ["Mana"], { textContent: getSpellCost(stats, spell).toFixed(2) });
2021-01-16 07:30:19 +00:00
title_elem.appendChild(second.cloneNode(true));
title_elemavg.appendChild(second);
let third = make_elem("span", [], { textContent: ")" });// " + getBaseSpellCost(stats, spellIdx, spell.cost) + " ]";
title_elem.appendChild(third.cloneNode(true));
title_elemavg.appendChild(third);
2021-01-09 08:52:58 +00:00
}
else {
title_elem.textContent = spell.name;
title_elemavg.textContent = spell.name;
2021-01-09 08:52:58 +00:00
}
parent_elem.append(title_elem);
2021-01-10 21:01:59 +00:00
overallparent_elem.append(title_elemavg);
// if ('cost' in spell) {
// overallparent_elem.append(displayNextCosts(stats, spell, spellIdx));
// }
let critChance = skillPointsToPercentage(stats.get('dex'));
2021-01-09 08:52:58 +00:00
let part_divavg = make_elem("p");
2021-01-19 01:57:26 +00:00
overallparent_elem.append(part_divavg);
2022-07-20 07:35:20 +00:00
function add_summary(text, val, fmt) {
if (typeof(val) === 'number') { val = val.toFixed(2); }
2022-07-20 07:35:20 +00:00
let summary_elem = make_elem("p");
summary_elem.append(
make_elem("span", [], { textContent: text }),
make_elem("span", [fmt], { textContent: val })
);
part_divavg.append(summary_elem);
2022-06-27 06:54:05 +00:00
}
for (let i = 0; i < spell_results.length; ++i) {
2022-06-28 05:16:23 +00:00
const spell_info = spell_results[i];
if (!spell_info.display) { continue; }
2021-01-30 12:03:40 +00:00
let part_div = make_elem("p", ["pt-3"]);
2021-01-09 08:52:58 +00:00
parent_elem.append(part_div);
part_div.append(make_elem("p", [], { textContent: spell_info.name }));
2021-01-10 21:01:59 +00:00
2022-06-28 05:16:23 +00:00
if (spell_info.type === "damage") {
let totalDamNormal = spell_info.normal_total;
let totalDamCrit = spell_info.crit_total;
let nonCritAverage = (totalDamNormal[0]+totalDamNormal[1])/2 || 0;
let critAverage = (totalDamCrit[0]+totalDamCrit[1])/2 || 0;
let averageDamage = (1-critChance)*nonCritAverage+critChance*critAverage || 0;
2021-01-09 08:52:58 +00:00
let averageLabel = make_elem("p", [], { textContent: "Average: "+averageDamage.toFixed(2) });
// averageLabel.classList.add("damageSubtitle");
2021-01-09 09:35:18 +00:00
part_div.append(averageLabel);
2021-01-09 08:52:58 +00:00
2022-06-28 05:16:23 +00:00
if (spell_info.name === spell.display) {
if (spellIdx === 0) {
let display_attack_speeds = ["Super Slow", "Very Slow", "Slow", "Normal", "Fast", "Very Fast", "Super Fast"];
let adjAtkSpd = attackSpeeds.indexOf(stats.get("atkSpd")) + stats.get("atkTier");
if(adjAtkSpd > 6) {
adjAtkSpd = 6;
} else if(adjAtkSpd < 0) {
adjAtkSpd = 0;
}
2022-07-20 07:35:20 +00:00
add_summary("Average DPS: ", averageDamage * baseDamageMultiplier[adjAtkSpd], "Damage");
add_summary("Attack Speed: ", display_attack_speeds[adjAtkSpd], "Damage");
2022-07-20 07:35:20 +00:00
add_summary("Per Attack: ", averageDamage, "Damage");
}
else {
2022-07-20 07:35:20 +00:00
add_summary(spell_info.name+ ": ", averageDamage, "Damage");
}
2021-01-10 22:16:22 +00:00
}
2021-01-10 21:31:29 +00:00
function _damage_display(label_text, average, dmg_min, dmg_max) {
let label = document.createElement("p");
label.textContent = label_text+average.toFixed(2);
part_div.append(label);
for (let i = 0; i < 6; i++){
if (dmg_max[i] != 0){
let p = document.createElement("p");
p.classList.add(damageClasses[i]);
p.textContent = dmg_min[i].toFixed(2)+" \u2013 "+dmg_max[i].toFixed(2);
part_div.append(p);
}
2021-01-09 08:52:58 +00:00
}
}
2022-06-28 05:16:23 +00:00
_damage_display("Non-Crit Average: ", nonCritAverage, spell_info.normal_min, spell_info.normal_max);
_damage_display("Crit Average: ", critAverage, spell_info.crit_min, spell_info.crit_max);
} else if (spell_info.type === "heal") {
let heal_amount = spell_info.heal_amount;
let healLabel = make_elem("p", ["Set"], {textContent: heal_amount.toFixed(2)});
2021-01-09 11:56:10 +00:00
part_div.append(healLabel);
2022-06-28 05:16:23 +00:00
if (spell_info.name === spell.display) {
2022-07-20 07:35:20 +00:00
add_summary(spell_info.name+ ": ", heal_amount, "Set");
2021-01-10 22:16:22 +00:00
}
2021-01-09 08:52:58 +00:00
}
}
addClickableArrow(overallparent_elem, parent_elem);
_overallparent_elem.append(overallparent_elem);
2021-01-09 08:52:58 +00:00
}
function addClickableArrow(elem, target) {
//up and down arrow - done ugly
2022-07-19 07:39:01 +00:00
let arrow = make_elem("img", [], { id: "arrow_" + elem.id, src: "../media/icons/" + (newIcons ? "new" : "old") + "/toggle_down.png" });
arrow.style.maxWidth = document.body.clientWidth > 900 ? "3rem" : "10rem";
2022-07-20 17:25:32 +00:00
elem.appendChild(arrow);
elem.addEventListener("click", () => toggle_spell_tab(arrow, target));
}
// toggle arrow thinger
function toggle_spell_tab(arrow_img, target) {
if (target.style.display == "none") {
target.style.display = "";
arrow_img.src = arrow_img.src.replace("down", "up");
} else {
target.style.display = "none";
arrow_img.src = arrow_img.src.replace("up", "down");
}
}