Small refactor to prepare for atree; fix reset health/lvl
This commit is contained in:
parent
6620d011e5
commit
651ae9f3d5
7 changed files with 51 additions and 595 deletions
|
@ -211,9 +211,5 @@ class Build{
|
||||||
let statMap = this.statMap;
|
let statMap = this.statMap;
|
||||||
let weapon_stats = this.weapon.statMap;
|
let weapon_stats = this.weapon.statMap;
|
||||||
statMap.set("damageRaw", [weapon_stats.get("nDam"), weapon_stats.get("eDam"), weapon_stats.get("tDam"), weapon_stats.get("wDam"), weapon_stats.get("fDam"), weapon_stats.get("aDam")]);
|
statMap.set("damageRaw", [weapon_stats.get("nDam"), weapon_stats.get("eDam"), weapon_stats.get("tDam"), weapon_stats.get("wDam"), weapon_stats.get("fDam"), weapon_stats.get("aDam")]);
|
||||||
statMap.set("damageBonus", [statMap.get("eDamPct"), statMap.get("tDamPct"), statMap.get("wDamPct"), statMap.get("fDamPct"), statMap.get("aDamPct")]);
|
|
||||||
statMap.set("defRaw", [statMap.get("eDef"), statMap.get("tDef"), statMap.get("wDef"), statMap.get("fDef"), statMap.get("aDef")]);
|
|
||||||
statMap.set("defBonus", [statMap.get("eDefPct"), statMap.get("tDefPct"), statMap.get("wDefPct"), statMap.get("fDefPct"), statMap.get("aDefPct")]);
|
|
||||||
statMap.set("defMult", classDefenseMultipliers.get(weapon_stats.get("type")));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
550
js/build2.js
550
js/build2.js
|
@ -1,550 +0,0 @@
|
||||||
|
|
||||||
|
|
||||||
const classDefenseMultipliers = new Map([ ["relik",0.50], ["bow",0.60], ["wand", 0.80], ["dagger", 1.0], ["spear",1.20] ]);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description Error to catch items that don't exist.
|
|
||||||
* @module ItemNotFound
|
|
||||||
*/
|
|
||||||
class ItemNotFound {
|
|
||||||
/**
|
|
||||||
* @class
|
|
||||||
* @param {String} item the item name entered
|
|
||||||
* @param {String} type the type of item
|
|
||||||
* @param {Boolean} genElement whether to generate an element from inputs
|
|
||||||
* @param {String} override override for item type
|
|
||||||
*/
|
|
||||||
constructor(item, type, genElement, override) {
|
|
||||||
/**
|
|
||||||
* @public
|
|
||||||
* @type {String}
|
|
||||||
*/
|
|
||||||
this.message = `Cannot find ${override||type} named ${item}`;
|
|
||||||
if (genElement)
|
|
||||||
/**
|
|
||||||
* @public
|
|
||||||
* @type {Element}
|
|
||||||
*/
|
|
||||||
this.element = document.getElementById(`${type}-choice`).parentElement.querySelectorAll("p.error")[0];
|
|
||||||
else
|
|
||||||
this.element = document.createElement("div");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description Error to catch incorrect input.
|
|
||||||
* @module IncorrectInput
|
|
||||||
*/
|
|
||||||
class IncorrectInput {
|
|
||||||
/**
|
|
||||||
* @class
|
|
||||||
* @param {String} input the inputted text
|
|
||||||
* @param {String} format the correct format
|
|
||||||
* @param {String} sibling the id of the error node's sibling
|
|
||||||
*/
|
|
||||||
constructor(input, format, sibling) {
|
|
||||||
/**
|
|
||||||
* @public
|
|
||||||
* @type {String}
|
|
||||||
*/
|
|
||||||
this.message = `${input} is incorrect. Example: ${format}`;
|
|
||||||
/**
|
|
||||||
* @public
|
|
||||||
* @type {String}
|
|
||||||
*/
|
|
||||||
this.id = sibling;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description Error that inputs an array of items to generate errors of.
|
|
||||||
* @module ListError
|
|
||||||
* @extends Error
|
|
||||||
*/
|
|
||||||
class ListError extends Error {
|
|
||||||
/**
|
|
||||||
* @class
|
|
||||||
* @param {Array} errors array of errors
|
|
||||||
*/
|
|
||||||
constructor(errors) {
|
|
||||||
let ret = [];
|
|
||||||
if (typeof errors[0] == "string") {
|
|
||||||
super(errors[0]);
|
|
||||||
} else {
|
|
||||||
super(errors[0].message);
|
|
||||||
}
|
|
||||||
for (let i of errors) {
|
|
||||||
if (typeof i == "string") {
|
|
||||||
ret.push(new Error(i));
|
|
||||||
} else {
|
|
||||||
ret.push(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @public
|
|
||||||
* @type {Object[]}
|
|
||||||
*/
|
|
||||||
this.errors = ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Class that represents a wynn player's build.
|
|
||||||
*/
|
|
||||||
class Build{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description Construct a build.
|
|
||||||
* @param {Number} level : Level of the player.
|
|
||||||
* @param {String[]} equipment : List of equipment names that make up the build.
|
|
||||||
* In order: boots, Chestplate, Leggings, Boots, Ring1, Ring2, Brace, Neck, Weapon.
|
|
||||||
* @param {Number[]} powders : Powder application. List of lists of integers (powder IDs).
|
|
||||||
* In order: boots, Chestplate, Leggings, Boots, Weapon.
|
|
||||||
* @param {Object[]} inputerrors : List of instances of error-like classes.
|
|
||||||
*/
|
|
||||||
constructor(level,equipment, powders, externalStats, inputerrors=[]){
|
|
||||||
|
|
||||||
let errors = inputerrors;
|
|
||||||
//this contains the Craft objects, if there are any crafted items. this.boots, etc. will contain the statMap of the Craft (which is built to be an expandedItem).
|
|
||||||
this.craftedItems = [];
|
|
||||||
this.customItems = [];
|
|
||||||
// NOTE: powders is just an array of arrays of powder IDs. Not powder objects.
|
|
||||||
this.powders = powders;
|
|
||||||
if(itemMap.get(equipment[0]) && itemMap.get(equipment[0]).type === "helmet") {
|
|
||||||
const helmet = itemMap.get(equipment[0]);
|
|
||||||
this.powders[0] = this.powders[0].slice(0,helmet.slots);
|
|
||||||
this.helmet = expandItem(helmet, this.powders[0]);
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
//let boots = getCraftFromHash(equipment[0]) ? getCraftFromHash(equipment[0]) : (getCustomFromHash(equipment[0])? getCustomFromHash(equipment[0]) : undefined);
|
|
||||||
let helmet = getCustomFromHash(equipment[0]) ? getCustomFromHash(equipment[0]) : (getCraftFromHash(equipment[0]) ? getCraftFromHash(equipment[0]) : undefined);
|
|
||||||
if (helmet.statMap.get("type") !== "helmet") {
|
|
||||||
throw new Error("Not a helmet");
|
|
||||||
}
|
|
||||||
this.powders[0] = this.powders[0].slice(0,helmet.statMap.get("slots"));
|
|
||||||
helmet.statMap.set("powders",this.powders[0].slice());
|
|
||||||
helmet.applyPowders();
|
|
||||||
this.helmet = helmet.statMap;
|
|
||||||
if (this.helmet.get("custom")) {
|
|
||||||
this.customItems.push(helmet);
|
|
||||||
} else if (this.helmet.get("crafted")) { //customs can also be crafted, but custom takes priority.
|
|
||||||
this.craftedItems.push(helmet);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Error) {
|
|
||||||
//console.log(Error); //fix
|
|
||||||
const helmet = itemMap.get("No Helmet");
|
|
||||||
this.powders[0] = this.powders[0].slice(0,helmet.slots);
|
|
||||||
this.helmet = expandItem(helmet, this.powders[0]);
|
|
||||||
errors.push(new ItemNotFound(equipment[0], "helmet", true));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(itemMap.get(equipment[1]) && itemMap.get(equipment[1]).type === "chestplate") {
|
|
||||||
const chestplate = itemMap.get(equipment[1]);
|
|
||||||
this.powders[1] = this.powders[1].slice(0,chestplate.slots);
|
|
||||||
this.chestplate = expandItem(chestplate, this.powders[1]);
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
let chestplate = getCustomFromHash(equipment[1]) ? getCustomFromHash(equipment[1]) : (getCraftFromHash(equipment[1]) ? getCraftFromHash(equipment[1]) : undefined);
|
|
||||||
if (chestplate.statMap.get("type") !== "chestplate") {
|
|
||||||
throw new Error("Not a chestplate");
|
|
||||||
}
|
|
||||||
this.powders[1] = this.powders[1].slice(0,chestplate.statMap.get("slots"));
|
|
||||||
chestplate.statMap.set("powders",this.powders[1].slice());
|
|
||||||
chestplate.applyPowders();
|
|
||||||
this.chestplate = chestplate.statMap;
|
|
||||||
if (this.chestplate.get("custom")) {
|
|
||||||
this.customItems.push(chestplate);
|
|
||||||
} else if (this.chestplate.get("crafted")) { //customs can also be crafted, but custom takes priority.
|
|
||||||
this.craftedItems.push(chestplate);
|
|
||||||
}
|
|
||||||
} catch (Error) {
|
|
||||||
const chestplate = itemMap.get("No Chestplate");
|
|
||||||
this.powders[1] = this.powders[1].slice(0,chestplate.slots);
|
|
||||||
this.chestplate = expandItem(chestplate, this.powders[1]);
|
|
||||||
errors.push(new ItemNotFound(equipment[1], "chestplate", true));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (itemMap.get(equipment[2]) && itemMap.get(equipment[2]).type === "leggings") {
|
|
||||||
const leggings = itemMap.get(equipment[2]);
|
|
||||||
this.powders[2] = this.powders[2].slice(0,leggings.slots);
|
|
||||||
this.leggings = expandItem(leggings, this.powders[2]);
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
let leggings = getCustomFromHash(equipment[2]) ? getCustomFromHash(equipment[2]) : (getCraftFromHash(equipment[2]) ? getCraftFromHash(equipment[2]) : undefined);
|
|
||||||
if (leggings.statMap.get("type") !== "leggings") {
|
|
||||||
throw new Error("Not a leggings");
|
|
||||||
}
|
|
||||||
this.powders[2] = this.powders[2].slice(0,leggings.statMap.get("slots"));
|
|
||||||
leggings.statMap.set("powders",this.powders[2].slice());
|
|
||||||
leggings.applyPowders();
|
|
||||||
this.leggings = leggings.statMap;
|
|
||||||
if (this.leggings.get("custom")) {
|
|
||||||
this.customItems.push(leggings);
|
|
||||||
} else if (this.leggings.get("crafted")) { //customs can also be crafted, but custom takes priority.
|
|
||||||
this.craftedItems.push(leggings);
|
|
||||||
}
|
|
||||||
} catch (Error) {
|
|
||||||
const leggings = itemMap.get("No Leggings");
|
|
||||||
this.powders[2] = this.powders[2].slice(0,leggings.slots);
|
|
||||||
this.leggings = expandItem(leggings, this.powders[2]);
|
|
||||||
errors.push(new ItemNotFound(equipment[2], "leggings", true));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (itemMap.get(equipment[3]) && itemMap.get(equipment[3]).type === "boots") {
|
|
||||||
const boots = itemMap.get(equipment[3]);
|
|
||||||
this.powders[3] = this.powders[3].slice(0,boots.slots);
|
|
||||||
this.boots = expandItem(boots, this.powders[3]);
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
let boots = getCustomFromHash(equipment[3]) ? getCustomFromHash(equipment[3]) : (getCraftFromHash(equipment[3]) ? getCraftFromHash(equipment[3]) : undefined);
|
|
||||||
if (boots.statMap.get("type") !== "boots") {
|
|
||||||
throw new Error("Not a boots");
|
|
||||||
}
|
|
||||||
this.powders[3] = this.powders[3].slice(0,boots.statMap.get("slots"));
|
|
||||||
boots.statMap.set("powders",this.powders[3].slice());
|
|
||||||
boots.applyPowders();
|
|
||||||
this.boots = boots.statMap;
|
|
||||||
console.log(boots);
|
|
||||||
if (this.boots.get("custom")) {
|
|
||||||
this.customItems.push(boots);
|
|
||||||
} else if (this.boots.get("crafted")) { //customs can also be crafted, but custom takes priority.
|
|
||||||
this.craftedItems.push(boots);
|
|
||||||
}
|
|
||||||
} catch (Error) {
|
|
||||||
const boots = itemMap.get("No Boots");
|
|
||||||
this.powders[3] = this.powders[3].slice(0,boots.slots);
|
|
||||||
this.boots = expandItem(boots, this.powders[3]);
|
|
||||||
errors.push(new ItemNotFound(equipment[3], "boots", true));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(itemMap.get(equipment[4]) && itemMap.get(equipment[4]).type === "ring") {
|
|
||||||
const ring = itemMap.get(equipment[4]);
|
|
||||||
this.ring1 = expandItem(ring, []);
|
|
||||||
}else{
|
|
||||||
try {
|
|
||||||
let ring = getCustomFromHash(equipment[4]) ? getCustomFromHash(equipment[4]) : (getCraftFromHash(equipment[4]) ? getCraftFromHash(equipment[4]) : undefined);
|
|
||||||
if (ring.statMap.get("type") !== "ring") {
|
|
||||||
throw new Error("Not a ring");
|
|
||||||
}
|
|
||||||
this.ring1 = ring.statMap;
|
|
||||||
if (this.ring1.get("custom")) {
|
|
||||||
this.customItems.push(ring);
|
|
||||||
} else if (this.ring1.get("crafted")) { //customs can also be crafted, but custom takes priority.
|
|
||||||
this.craftedItems.push(ring);
|
|
||||||
}
|
|
||||||
} catch (Error) {
|
|
||||||
const ring = itemMap.get("No Ring 1");
|
|
||||||
this.ring1 = expandItem(ring, []);
|
|
||||||
errors.push(new ItemNotFound(equipment[4], "ring1", true, "ring"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(itemMap.get(equipment[5]) && itemMap.get(equipment[5]).type === "ring") {
|
|
||||||
const ring = itemMap.get(equipment[5]);
|
|
||||||
this.ring2 = expandItem(ring, []);
|
|
||||||
}else{
|
|
||||||
try {
|
|
||||||
let ring = getCustomFromHash(equipment[5]) ? getCustomFromHash(equipment[5]) : (getCraftFromHash(equipment[5]) ? getCraftFromHash(equipment[5]) : undefined);
|
|
||||||
if (ring.statMap.get("type") !== "ring") {
|
|
||||||
throw new Error("Not a ring");
|
|
||||||
}
|
|
||||||
this.ring2 = ring.statMap;
|
|
||||||
if (this.ring2.get("custom")) {
|
|
||||||
this.customItems.push(ring);
|
|
||||||
} else if (this.ring2.get("crafted")) { //customs can also be crafted, but custom takes priority.
|
|
||||||
this.craftedItems.push(ring);
|
|
||||||
}
|
|
||||||
} catch (Error) {
|
|
||||||
const ring = itemMap.get("No Ring 2");
|
|
||||||
this.ring2 = expandItem(ring, []);
|
|
||||||
errors.push(new ItemNotFound(equipment[5], "ring2", true, "ring"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(itemMap.get(equipment[6]) && itemMap.get(equipment[6]).type === "bracelet") {
|
|
||||||
const bracelet = itemMap.get(equipment[6]);
|
|
||||||
this.bracelet = expandItem(bracelet, []);
|
|
||||||
}else{
|
|
||||||
try {
|
|
||||||
let bracelet = getCustomFromHash(equipment[6]) ? getCustomFromHash(equipment[6]) : (getCraftFromHash(equipment[6]) ? getCraftFromHash(equipment[6]) : undefined);
|
|
||||||
if (bracelet.statMap.get("type") !== "bracelet") {
|
|
||||||
throw new Error("Not a bracelet");
|
|
||||||
}
|
|
||||||
this.bracelet = bracelet.statMap;
|
|
||||||
if (this.bracelet.get("custom")) {
|
|
||||||
this.customItems.push(bracelet);
|
|
||||||
} else if (this.bracelet.get("crafted")) { //customs can also be crafted, but custom takes priority.
|
|
||||||
this.craftedItems.push(bracelet);
|
|
||||||
}
|
|
||||||
} catch (Error) {
|
|
||||||
const bracelet = itemMap.get("No Bracelet");
|
|
||||||
this.bracelet = expandItem(bracelet, []);
|
|
||||||
errors.push(new ItemNotFound(equipment[6], "bracelet", true));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(itemMap.get(equipment[7]) && itemMap.get(equipment[7]).type === "necklace") {
|
|
||||||
const necklace = itemMap.get(equipment[7]);
|
|
||||||
this.necklace = expandItem(necklace, []);
|
|
||||||
}else{
|
|
||||||
try {
|
|
||||||
let necklace = getCustomFromHash(equipment[7]) ? getCustomFromHash(equipment[7]) : (getCraftFromHash(equipment[7]) ? getCraftFromHash(equipment[7]) : undefined);
|
|
||||||
if (necklace.statMap.get("type") !== "necklace") {
|
|
||||||
throw new Error("Not a necklace");
|
|
||||||
}
|
|
||||||
this.necklace = necklace.statMap;
|
|
||||||
if (this.necklace.get("custom")) {
|
|
||||||
this.customItems.push(necklace);
|
|
||||||
} else if (this.necklace.get("crafted")) { //customs can also be crafted, but custom takes priority.
|
|
||||||
this.craftedItems.push(necklace);
|
|
||||||
}
|
|
||||||
} catch (Error) {
|
|
||||||
const necklace = itemMap.get("No Necklace");
|
|
||||||
this.necklace = expandItem(necklace, []);
|
|
||||||
errors.push(new ItemNotFound(equipment[7], "necklace", true));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(itemMap.get(equipment[8]) && itemMap.get(equipment[8]).category === "weapon") {
|
|
||||||
const weapon = itemMap.get(equipment[8]);
|
|
||||||
this.powders[4] = this.powders[4].slice(0,weapon.slots);
|
|
||||||
this.weapon = expandItem(weapon, this.powders[4]);
|
|
||||||
if (equipment[8] !== "No Weapon") {
|
|
||||||
document.getElementsByClassName("powder-specials")[0].style.display = "grid";
|
|
||||||
} else {
|
|
||||||
document.getElementsByClassName("powder-specials")[0].style.display = "none";
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
try {
|
|
||||||
let weapon = getCustomFromHash(equipment[8]) ? getCustomFromHash(equipment[8]) : (getCraftFromHash(equipment[8]) ? getCraftFromHash(equipment[8]) : undefined);
|
|
||||||
if (weapon.statMap.get("category") !== "weapon") {
|
|
||||||
throw new Error("Not a weapon");
|
|
||||||
}
|
|
||||||
this.weapon = weapon.statMap;
|
|
||||||
if (this.weapon.get("custom")) {
|
|
||||||
this.customItems.push(weapon);
|
|
||||||
} else if (this.weapon.get("crafted")) { //customs can also be crafted, but custom takes priority.
|
|
||||||
this.craftedItems.push(weapon);
|
|
||||||
}
|
|
||||||
this.powders[4] = this.powders[4].slice(0,this.weapon.get("slots"));
|
|
||||||
this.weapon.set("powders",this.powders[4].slice());
|
|
||||||
document.getElementsByClassName("powder-specials")[0].style.display = "grid";
|
|
||||||
} catch (Error) {
|
|
||||||
const weapon = itemMap.get("No Weapon");
|
|
||||||
this.powders[4] = this.powders[4].slice(0,weapon.slots);
|
|
||||||
this.weapon = expandItem(weapon, this.powders[4]);
|
|
||||||
document.getElementsByClassName("powder-specials")[0].style.display = "none";
|
|
||||||
errors.push(new ItemNotFound(equipment[8], "weapon", true));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//console.log(this.craftedItems)
|
|
||||||
|
|
||||||
if (level < 1) { //Should these be constants?
|
|
||||||
this.level = 1;
|
|
||||||
} else if (level > 106) {
|
|
||||||
this.level = 106;
|
|
||||||
} else if (level <= 106 && level >= 1) {
|
|
||||||
this.level = level;
|
|
||||||
} else if (typeof level === "string") {
|
|
||||||
this.level = level;
|
|
||||||
errors.push(new IncorrectInput(level, "a number", "level-choice"));
|
|
||||||
} else {
|
|
||||||
errors.push("Level is not a string or number.");
|
|
||||||
}
|
|
||||||
document.getElementById("level-choice").value = this.level;
|
|
||||||
|
|
||||||
this.availableSkillpoints = levelToSkillPoints(this.level);
|
|
||||||
this.equipment = [ this.helmet, this.chestplate, this.leggings, this.boots, this.ring1, this.ring2, this.bracelet, this.necklace ];
|
|
||||||
this.items = this.equipment.concat([this.weapon]);
|
|
||||||
// return [equip_order, best_skillpoints, final_skillpoints, best_total];
|
|
||||||
let result = calculate_skillpoints(this.equipment, this.weapon);
|
|
||||||
console.log(result);
|
|
||||||
this.equip_order = result[0];
|
|
||||||
this.base_skillpoints = result[1];
|
|
||||||
this.total_skillpoints = result[2];
|
|
||||||
this.assigned_skillpoints = result[3];
|
|
||||||
this.activeSetCounts = result[4];
|
|
||||||
|
|
||||||
// For strength boosts like warscream, vanish, etc.
|
|
||||||
this.damageMultiplier = 1.0;
|
|
||||||
this.defenseMultiplier = 1.0;
|
|
||||||
|
|
||||||
// For other external boosts ;-;
|
|
||||||
this.externalStats = externalStats;
|
|
||||||
|
|
||||||
this.initBuildStats();
|
|
||||||
|
|
||||||
// Remove every error before adding specific ones
|
|
||||||
for (let i of document.getElementsByClassName("error")) {
|
|
||||||
i.textContent = "";
|
|
||||||
}
|
|
||||||
this.errors = errors;
|
|
||||||
if (errors.length > 0) this.errored = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Returns build in string format
|
|
||||||
*/
|
|
||||||
toString(){
|
|
||||||
return [this.equipment,this.weapon].flat();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Getters */
|
|
||||||
|
|
||||||
/* Get total health for build.
|
|
||||||
*/
|
|
||||||
|
|
||||||
getSpellCost(spellIdx, cost) {
|
|
||||||
cost = Math.ceil(cost * (1 - skillPointsToPercentage(this.total_skillpoints[2])));
|
|
||||||
cost = Math.max(0, Math.floor(cost * (1 + this.statMap.get("spPct"+spellIdx) / 100)));
|
|
||||||
return Math.max(1, cost + this.statMap.get("spRaw"+spellIdx));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Get melee stats for build.
|
|
||||||
Returns an array in the order:
|
|
||||||
*/
|
|
||||||
getMeleeStats(){
|
|
||||||
const stats = this.statMap;
|
|
||||||
if (this.weapon.get("tier") === "Crafted") {
|
|
||||||
stats.set("damageBases", [this.weapon.get("nDamBaseHigh"),this.weapon.get("eDamBaseHigh"),this.weapon.get("tDamBaseHigh"),this.weapon.get("wDamBaseHigh"),this.weapon.get("fDamBaseHigh"),this.weapon.get("aDamBaseHigh")]);
|
|
||||||
}
|
|
||||||
let adjAtkSpd = attackSpeeds.indexOf(stats.get("atkSpd")) + stats.get("atkTier");
|
|
||||||
if(adjAtkSpd > 6){
|
|
||||||
adjAtkSpd = 6;
|
|
||||||
}else if(adjAtkSpd < 0){
|
|
||||||
adjAtkSpd = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
let damage_mult = 1;
|
|
||||||
if (this.weapon.get("type") === "relik") {
|
|
||||||
damage_mult = 0.99; // CURSE YOU WYNNCRAFT
|
|
||||||
//One day we will create WynnWynn and no longer have shaman 99% melee injustice.
|
|
||||||
//In all seriousness 99% is because wynn uses 0.33 to estimate dividing the damage by 3 to split damage between 3 beams.
|
|
||||||
}
|
|
||||||
// 0spellmult for melee damage.
|
|
||||||
let results = calculateSpellDamage(stats, [100, 0, 0, 0, 0, 0], stats.get("mdRaw"), stats.get("mdPct") + this.externalStats.get("mdPct"), 0, this.weapon, this.total_skillpoints, damage_mult * this.damageMultiplier, this.externalStats);
|
|
||||||
|
|
||||||
let dex = this.total_skillpoints[1];
|
|
||||||
|
|
||||||
let totalDamNorm = results[0];
|
|
||||||
let totalDamCrit = results[1];
|
|
||||||
totalDamNorm.push(1-skillPointsToPercentage(dex));
|
|
||||||
totalDamCrit.push(skillPointsToPercentage(dex));
|
|
||||||
let damages_results = results[2];
|
|
||||||
|
|
||||||
let singleHitTotal = ((totalDamNorm[0]+totalDamNorm[1])*(totalDamNorm[2])
|
|
||||||
+(totalDamCrit[0]+totalDamCrit[1])*(totalDamCrit[2]))/2;
|
|
||||||
|
|
||||||
//Now do math
|
|
||||||
let normDPS = (totalDamNorm[0]+totalDamNorm[1])/2 * baseDamageMultiplier[adjAtkSpd];
|
|
||||||
let critDPS = (totalDamCrit[0]+totalDamCrit[1])/2 * baseDamageMultiplier[adjAtkSpd];
|
|
||||||
let avgDPS = (normDPS * (1 - skillPointsToPercentage(dex))) + (critDPS * (skillPointsToPercentage(dex)));
|
|
||||||
//[[n n n n] [e e e e] [t t t t] [w w w w] [f f f f] [a a a a] [lowtotal hightotal normalChance] [critlowtotal crithightotal critChance] normalDPS critCPS averageDPS adjAttackSpeed, singleHit]
|
|
||||||
return damages_results.concat([totalDamNorm,totalDamCrit,normDPS,critDPS,avgDPS,adjAtkSpd, singleHitTotal]).concat(results[3]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Get all defensive stats for this build.
|
|
||||||
*/
|
|
||||||
getDefenseStats(){
|
|
||||||
const stats = this.statMap;
|
|
||||||
let defenseStats = [];
|
|
||||||
let def_pct = skillPointsToPercentage(this.total_skillpoints[3]);
|
|
||||||
let agi_pct = skillPointsToPercentage(this.total_skillpoints[4]);
|
|
||||||
//total hp
|
|
||||||
let totalHp = stats.get("hp") + stats.get("hpBonus");
|
|
||||||
if (totalHp < 5) totalHp = 5;
|
|
||||||
defenseStats.push(totalHp);
|
|
||||||
//EHP
|
|
||||||
let ehp = [totalHp, totalHp];
|
|
||||||
let defMult = classDefenseMultipliers.get(this.weapon.get("type"));
|
|
||||||
ehp[0] /= ((1-def_pct)*(1-agi_pct)*(2-defMult)*(2-this.defenseMultiplier));
|
|
||||||
ehp[1] /= ((1-def_pct)*(2-defMult)*(2-this.defenseMultiplier));
|
|
||||||
defenseStats.push(ehp);
|
|
||||||
//HPR
|
|
||||||
let totalHpr = rawToPct(stats.get("hprRaw"), stats.get("hprPct")/100.);
|
|
||||||
defenseStats.push(totalHpr);
|
|
||||||
//EHPR
|
|
||||||
let ehpr = [totalHpr, totalHpr];
|
|
||||||
ehpr[0] /= ((1-def_pct)*(1-agi_pct)*(2-defMult)*(2-this.defenseMultiplier));
|
|
||||||
ehpr[1] /= ((1-def_pct)*(2-defMult)*(2-this.defenseMultiplier));
|
|
||||||
defenseStats.push(ehpr);
|
|
||||||
//skp stats
|
|
||||||
defenseStats.push([ (1 - ((1-def_pct) * (2 - this.defenseMultiplier)))*100, agi_pct*100]);
|
|
||||||
//eledefs - TODO POWDERS
|
|
||||||
let eledefs = [0, 0, 0, 0, 0];
|
|
||||||
for(const i in skp_elements){ //kinda jank but ok
|
|
||||||
eledefs[i] = rawToPct(stats.get(skp_elements[i] + "Def"), stats.get(skp_elements[i] + "DefPct")/100.);
|
|
||||||
}
|
|
||||||
defenseStats.push(eledefs);
|
|
||||||
|
|
||||||
//[total hp, [ehp w/ agi, ehp w/o agi], total hpr, [ehpr w/ agi, ehpr w/o agi], [def%, agi%], [edef,tdef,wdef,fdef,adef]]
|
|
||||||
return defenseStats;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get all stats for this build. Stores in this.statMap.
|
|
||||||
@pre The build itself should be valid. No checking of validity of pieces is done here.
|
|
||||||
*/
|
|
||||||
initBuildStats(){
|
|
||||||
|
|
||||||
let staticIDs = ["hp", "eDef", "tDef", "wDef", "fDef", "aDef"];
|
|
||||||
|
|
||||||
//Create a map of this build's stats
|
|
||||||
let statMap = new Map();
|
|
||||||
|
|
||||||
for (const staticID of staticIDs) {
|
|
||||||
statMap.set(staticID, 0);
|
|
||||||
}
|
|
||||||
statMap.set("hp", levelToHPBase(this.level));
|
|
||||||
|
|
||||||
let major_ids = new Set();
|
|
||||||
for (const item of this.items){
|
|
||||||
for (let [id, value] of item.get("maxRolls")) {
|
|
||||||
statMap.set(id,(statMap.get(id) || 0)+value);
|
|
||||||
}
|
|
||||||
for (const staticID of staticIDs) {
|
|
||||||
if (item.get(staticID)) {
|
|
||||||
statMap.set(staticID, statMap.get(staticID) + item.get(staticID));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (item.get("majorIds")) {
|
|
||||||
for (const majorID of item.get("majorIds")) {
|
|
||||||
major_ids.add(majorID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
statMap.set("activeMajorIDs", major_ids);
|
|
||||||
for (const [setName, count] of this.activeSetCounts) {
|
|
||||||
const bonus = sets[setName].bonuses[count-1];
|
|
||||||
for (const id in bonus) {
|
|
||||||
if (skp_order.includes(id)) {
|
|
||||||
// pass. Don't include skillpoints in ids
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
statMap.set(id,(statMap.get(id) || 0)+bonus[id]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
statMap.set("poisonPct", 100);
|
|
||||||
|
|
||||||
// The stuff relevant for damage calculation!!! @ferricles
|
|
||||||
statMap.set("atkSpd", this.weapon.get("atkSpd"));
|
|
||||||
|
|
||||||
for (const x of skp_elements) {
|
|
||||||
this.externalStats.set(x + "DamPct", 0);
|
|
||||||
}
|
|
||||||
this.externalStats.set("mdPct", 0);
|
|
||||||
this.externalStats.set("sdPct", 0);
|
|
||||||
this.externalStats.set("damageBonus", [0, 0, 0, 0, 0]);
|
|
||||||
this.externalStats.set("defBonus",[0, 0, 0, 0, 0]);
|
|
||||||
this.externalStats.set("poisonPct", 0);
|
|
||||||
this.statMap = statMap;
|
|
||||||
|
|
||||||
this.aggregateStats();
|
|
||||||
}
|
|
||||||
|
|
||||||
aggregateStats() {
|
|
||||||
let statMap = this.statMap;
|
|
||||||
statMap.set("damageRaw", [this.weapon.get("nDam"), this.weapon.get("eDam"), this.weapon.get("tDam"), this.weapon.get("wDam"), this.weapon.get("fDam"), this.weapon.get("aDam")]);
|
|
||||||
statMap.set("damageBonus", [statMap.get("eDamPct"), statMap.get("tDamPct"), statMap.get("wDamPct"), statMap.get("fDamPct"), statMap.get("aDamPct")]);
|
|
||||||
statMap.set("defRaw", [statMap.get("eDef"), statMap.get("tDef"), statMap.get("wDef"), statMap.get("fDef"), statMap.get("aDef")]);
|
|
||||||
statMap.set("defBonus", [statMap.get("eDefPct"), statMap.get("tDefPct"), statMap.get("wDefPct"), statMap.get("fDefPct"), statMap.get("aDefPct")]);
|
|
||||||
statMap.set("defMult", classDefenseMultipliers.get(this.weapon.get("type")));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -202,15 +202,15 @@ function shareBuild(build) {
|
||||||
if (build) {
|
if (build) {
|
||||||
let text = url_base+location.hash+"\n"+
|
let text = url_base+location.hash+"\n"+
|
||||||
"WynnBuilder build:\n"+
|
"WynnBuilder build:\n"+
|
||||||
"> "+build.helmet.statMap.get("displayName")+"\n"+
|
"> "+build.items[0].statMap.get("displayName")+"\n"+
|
||||||
"> "+build.chestplate.statMap.get("displayName")+"\n"+
|
"> "+build.items[1].statMap.get("displayName")+"\n"+
|
||||||
"> "+build.leggings.statMap.get("displayName")+"\n"+
|
"> "+build.items[2].statMap.get("displayName")+"\n"+
|
||||||
"> "+build.boots.statMap.get("displayName")+"\n"+
|
"> "+build.items[3].statMap.get("displayName")+"\n"+
|
||||||
"> "+build.ring1.statMap.get("displayName")+"\n"+
|
"> "+build.items[4].statMap.get("displayName")+"\n"+
|
||||||
"> "+build.ring2.statMap.get("displayName")+"\n"+
|
"> "+build.items[5].statMap.get("displayName")+"\n"+
|
||||||
"> "+build.bracelet.statMap.get("displayName")+"\n"+
|
"> "+build.items[6].statMap.get("displayName")+"\n"+
|
||||||
"> "+build.necklace.statMap.get("displayName")+"\n"+
|
"> "+build.items[7].statMap.get("displayName")+"\n"+
|
||||||
"> "+build.weapon.statMap.get("displayName")+" ["+build_powders[4].map(x => powderNames.get(x)).join("")+"]";
|
"> "+build.items[8].statMap.get("displayName")+" ["+build_powders[4].map(x => powderNames.get(x)).join("")+"]";
|
||||||
copyTextToClipboard(text);
|
copyTextToClipboard(text);
|
||||||
document.getElementById("share-button").textContent = "Copied!";
|
document.getElementById("share-button").textContent = "Copied!";
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,18 +96,14 @@ function resetFields(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const nodes_to_reset = item_nodes.concat(powder_nodes.concat(edit_input_nodes));
|
const nodes_to_reset = item_nodes.concat(powder_nodes).concat(edit_input_nodes).concat([powder_special_input, boosts_node]);
|
||||||
for (const node of nodes_to_reset) {
|
for (const node of nodes_to_reset) {
|
||||||
node.mark_dirty();
|
node.mark_dirty();
|
||||||
}
|
}
|
||||||
powder_special_input.mark_dirty();
|
|
||||||
boosts_node.mark_dirty();
|
|
||||||
|
|
||||||
for (const node of nodes_to_reset) {
|
for (const node of nodes_to_reset) {
|
||||||
node.update();
|
node.update();
|
||||||
}
|
}
|
||||||
powder_special_input.update();
|
|
||||||
boosts_node.update();
|
|
||||||
|
|
||||||
setValue("level-choice", "106");
|
setValue("level-choice", "106");
|
||||||
location.hash = "";
|
location.hash = "";
|
||||||
|
|
|
@ -206,6 +206,11 @@ class ItemInputDisplayNode extends ComputeNode {
|
||||||
this.input_field.classList.add("text-light");
|
this.input_field.classList.add("text-light");
|
||||||
this.image.classList.remove('Normal-shadow', 'Unique-shadow', 'Rare-shadow', 'Legendary-shadow', 'Fabled-shadow', 'Mythic-shadow', 'Set-shadow', 'Crafted-shadow', 'Custom-shadow');
|
this.image.classList.remove('Normal-shadow', 'Unique-shadow', 'Rare-shadow', 'Legendary-shadow', 'Fabled-shadow', 'Mythic-shadow', 'Set-shadow', 'Crafted-shadow', 'Custom-shadow');
|
||||||
|
|
||||||
|
if (this.health_field) {
|
||||||
|
// Doesn't exist for weapons.
|
||||||
|
this.health_field.textContent = "0";
|
||||||
|
}
|
||||||
|
this.level_field.textContent = "0";
|
||||||
if (!item) {
|
if (!item) {
|
||||||
this.input_field.classList.add("is-invalid");
|
this.input_field.classList.add("is-invalid");
|
||||||
return null;
|
return null;
|
||||||
|
@ -443,7 +448,7 @@ function getDefenseStats(stats) {
|
||||||
defenseStats.push(totalHp);
|
defenseStats.push(totalHp);
|
||||||
//EHP
|
//EHP
|
||||||
let ehp = [totalHp, totalHp];
|
let ehp = [totalHp, totalHp];
|
||||||
let defMult = (2 - stats.get("classDef")) * (1 - stats.get("defBonus"));
|
let defMult = (2 - stats.get("classDef")) * (2 - stats.get("defMultiplier"));
|
||||||
ehp[0] /= (1-def_pct)*(1-agi_pct)*defMult;
|
ehp[0] /= (1-def_pct)*(1-agi_pct)*defMult;
|
||||||
ehp[1] /= (1-def_pct)*defMult;
|
ehp[1] /= (1-def_pct)*defMult;
|
||||||
defenseStats.push(ehp);
|
defenseStats.push(ehp);
|
||||||
|
@ -725,33 +730,47 @@ class DisplayBuildWarningsNode extends ComputeNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Aggregate stats from the build and from inputs.
|
* Aggregate stats from all inputs (merges statmaps).
|
||||||
*
|
*
|
||||||
* Signature: AggregateStatsNode(build: Build, *args) => StatMap
|
* Signature: AggregateStatsNode(*args) => StatMap
|
||||||
*/
|
*/
|
||||||
class AggregateStatsNode extends ComputeNode {
|
class AggregateStatsNode extends ComputeNode {
|
||||||
constructor() { super("builder-aggregate-stats"); }
|
constructor() { super("builder-aggregate-stats"); }
|
||||||
|
|
||||||
|
compute_func(input_map) {
|
||||||
|
const output_stats = new Map();
|
||||||
|
for (const [k, v] of input_map.entries()) {
|
||||||
|
for (const [k2, v2] of v.entries()) {
|
||||||
|
if (output_stats.has(k2)) {
|
||||||
|
output_stats.set(k2, v2 + output_stats.get(k2));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
output_stats.set(k2, v2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output_stats;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aggregate editable ID stats with build and weapon type.
|
||||||
|
*
|
||||||
|
* Signature: AggregateEditableIDNode(build: Build, weapon: Item, *args) => StatMap
|
||||||
|
*/
|
||||||
|
class AggregateEditableIDNode extends ComputeNode {
|
||||||
|
constructor() { super("builder-aggregate-inputs"); }
|
||||||
|
|
||||||
compute_func(input_map) {
|
compute_func(input_map) {
|
||||||
const build = input_map.get('build'); input_map.delete('build');
|
const build = input_map.get('build'); input_map.delete('build');
|
||||||
const powder_boost = input_map.get('powder-boost'); input_map.delete('powder-boost');
|
|
||||||
const potion_boost = input_map.get('potion-boost'); input_map.delete('potion-boost');
|
|
||||||
const weapon = input_map.get('weapon'); input_map.delete('weapon');
|
const weapon = input_map.get('weapon'); input_map.delete('weapon');
|
||||||
|
|
||||||
const output_stats = new Map(build.statMap);
|
const output_stats = new Map(build.statMap);
|
||||||
output_stats.set("damageMultiplier", 1 + potion_boost[0]);
|
output_stats.set("damageMultiplier", 1);
|
||||||
output_stats.set("defBonus", potion_boost[1]);
|
output_stats.set("defMultiplier", 1);
|
||||||
for (const [k, v] of input_map.entries()) {
|
for (const [k, v] of input_map.entries()) {
|
||||||
output_stats.set(k, v);
|
output_stats.set(k, v);
|
||||||
}
|
}
|
||||||
for (const [k, v] of powder_boost.entries()) {
|
|
||||||
if (output_stats.has(k)) {
|
|
||||||
output_stats.set(k, v + output_stats.get(k));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
output_stats.set(k, v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
output_stats.set('classDef', classDefenseMultipliers.get(weapon.statMap.get("type")));
|
output_stats.set('classDef', classDefenseMultipliers.get(weapon.statMap.get("type")));
|
||||||
return output_stats;
|
return output_stats;
|
||||||
|
@ -919,13 +938,14 @@ function builder_graph_init() {
|
||||||
|
|
||||||
// Create one node that will be the "aggregator node" (listen to all the editable id nodes, as well as the build_node (for non editable stats) and collect them into one statmap)
|
// Create one node that will be the "aggregator node" (listen to all the editable id nodes, as well as the build_node (for non editable stats) and collect them into one statmap)
|
||||||
let stat_agg_node = new AggregateStatsNode();
|
let stat_agg_node = new AggregateStatsNode();
|
||||||
stat_agg_node.link_to(build_node, 'build').link_to(item_nodes[8], 'weapon');
|
let edit_agg_node = new AggregateEditableIDNode();
|
||||||
|
edit_agg_node.link_to(build_node, 'build').link_to(item_nodes[8], 'weapon');
|
||||||
for (const field of editable_item_fields) {
|
for (const field of editable_item_fields) {
|
||||||
// Create nodes that listens to each editable id input, the node name should match the "id"
|
// Create nodes that listens to each editable id input, the node name should match the "id"
|
||||||
const elem = document.getElementById(field);
|
const elem = document.getElementById(field);
|
||||||
const node = new SumNumberInputNode('builder-'+field+'-input', elem);
|
const node = new SumNumberInputNode('builder-'+field+'-input', elem);
|
||||||
|
|
||||||
stat_agg_node.link_to(node, field);
|
edit_agg_node.link_to(node, field);
|
||||||
edit_input_nodes.push(node);
|
edit_input_nodes.push(node);
|
||||||
}
|
}
|
||||||
// Edit IDs setter declared up here to set ids so they will be populated by default.
|
// Edit IDs setter declared up here to set ids so they will be populated by default.
|
||||||
|
@ -936,11 +956,12 @@ function builder_graph_init() {
|
||||||
const elem = document.getElementById(skp+'-skp');
|
const elem = document.getElementById(skp+'-skp');
|
||||||
const node = new SumNumberInputNode('builder-'+skp+'-input', elem);
|
const node = new SumNumberInputNode('builder-'+skp+'-input', elem);
|
||||||
|
|
||||||
stat_agg_node.link_to(node, skp);
|
edit_agg_node.link_to(node, skp);
|
||||||
build_encode_node.link_to(node, skp);
|
build_encode_node.link_to(node, skp);
|
||||||
build_warnings_node.link_to(node, skp);
|
build_warnings_node.link_to(node, skp);
|
||||||
edit_input_nodes.push(node);
|
edit_input_nodes.push(node);
|
||||||
}
|
}
|
||||||
|
stat_agg_node.link_to(edit_agg_node);
|
||||||
build_disp_node.link_to(stat_agg_node, 'stats');
|
build_disp_node.link_to(stat_agg_node, 'stats');
|
||||||
|
|
||||||
for (const input_node of item_nodes.concat(powder_nodes)) {
|
for (const input_node of item_nodes.concat(powder_nodes)) {
|
||||||
|
|
|
@ -170,7 +170,6 @@ class Craft{
|
||||||
statMap.set(e + "Dam", "0-0");
|
statMap.set(e + "Dam", "0-0");
|
||||||
statMap.set(e + "DamLow", "0-0");
|
statMap.set(e + "DamLow", "0-0");
|
||||||
}
|
}
|
||||||
//statMap.set("damageBonus", [statMap.get("eDamPct"), statMap.get("tDamPct"), statMap.get("wDamPct"), statMap.get("fDamPct"), statMap.get("aDamPct")]);
|
|
||||||
statMap.set("category","weapon");
|
statMap.set("category","weapon");
|
||||||
statMap.set("atkSpd",this.atkSpd);
|
statMap.set("atkSpd",this.atkSpd);
|
||||||
}
|
}
|
||||||
|
@ -381,12 +380,10 @@ class Craft{
|
||||||
|
|
||||||
statMap.set("reqs",[0,0,0,0,0]);
|
statMap.set("reqs",[0,0,0,0,0]);
|
||||||
statMap.set("skillpoints", [0,0,0,0,0]);
|
statMap.set("skillpoints", [0,0,0,0,0]);
|
||||||
statMap.set("damageBonus",[0,0,0,0,0]);
|
|
||||||
for (const e in skp_order) {
|
for (const e in skp_order) {
|
||||||
statMap.set(skp_order[e], statMap.get("maxRolls").has(skp_order[e]) ? statMap.get("maxRolls").get(skp_order[e]) : 0);
|
statMap.set(skp_order[e], statMap.get("maxRolls").has(skp_order[e]) ? statMap.get("maxRolls").get(skp_order[e]) : 0);
|
||||||
statMap.get("skillpoints")[e] = statMap.get("maxRolls").has(skp_order[e]) ? statMap.get("maxRolls").get(skp_order[e]) : 0;
|
statMap.get("skillpoints")[e] = statMap.get("maxRolls").has(skp_order[e]) ? statMap.get("maxRolls").get(skp_order[e]) : 0;
|
||||||
statMap.get("reqs")[e] = statMap.has(skp_order[e]+"Req") && !consumableTypes.includes(statMap.get("type"))? statMap.get(skp_order[e]+"Req") : 0;
|
statMap.get("reqs")[e] = statMap.has(skp_order[e]+"Req") && !consumableTypes.includes(statMap.get("type"))? statMap.get(skp_order[e]+"Req") : 0;
|
||||||
statMap.get("damageBonus")[e] = statMap.has(skp_order[e]+"DamPct") ? statMap.get(skp_order[e]+"DamPct") : 0;
|
|
||||||
}
|
}
|
||||||
for (const id of rolledIDs) {
|
for (const id of rolledIDs) {
|
||||||
if (statMap.get("minRolls").has(id)) {
|
if (statMap.get("minRolls").has(id)) {
|
||||||
|
|
|
@ -182,7 +182,6 @@ function displayExpandedItem(item, parent_id){
|
||||||
stats.set("wDamPct", 0);
|
stats.set("wDamPct", 0);
|
||||||
stats.set("fDamPct", 0);
|
stats.set("fDamPct", 0);
|
||||||
stats.set("aDamPct", 0);
|
stats.set("aDamPct", 0);
|
||||||
stats.set("damageBonus", [0, 0, 0, 0, 0]);
|
|
||||||
|
|
||||||
//SUPER JANK @HPP PLS FIX
|
//SUPER JANK @HPP PLS FIX
|
||||||
let damage_keys = [ "nDam_", "eDam_", "tDam_", "wDam_", "fDam_", "aDam_" ];
|
let damage_keys = [ "nDam_", "eDam_", "tDam_", "wDam_", "fDam_", "aDam_" ];
|
||||||
|
@ -1293,9 +1292,6 @@ function displayDefenseStats(parent_elem, statMap, insertSummary){
|
||||||
statsTable.appendChild(hpRow);
|
statsTable.appendChild(hpRow);
|
||||||
}
|
}
|
||||||
|
|
||||||
let defMult = statMap.get("defMult");
|
|
||||||
if (!defMult) {defMult = 1}
|
|
||||||
|
|
||||||
//EHP
|
//EHP
|
||||||
let ehpRow = document.createElement("div");
|
let ehpRow = document.createElement("div");
|
||||||
ehpRow.classList.add("row");
|
ehpRow.classList.add("row");
|
||||||
|
@ -1405,8 +1401,8 @@ function displayDefenseStats(parent_elem, statMap, insertSummary){
|
||||||
boost.classList.add("col");
|
boost.classList.add("col");
|
||||||
boost.classList.add("text-end");
|
boost.classList.add("text-end");
|
||||||
|
|
||||||
let defRaw = statMap.get("defRaw")[i];
|
let defRaw = statMap.get(skp_elements[i]+"Def");
|
||||||
let defPct = statMap.get("defBonus")[i]/100;
|
let defPct = statMap.get(skp_elements[i]+"DefPct")/100;
|
||||||
if (defRaw < 0) {
|
if (defRaw < 0) {
|
||||||
defPct >= 0 ? defPct = "- " + defPct: defPct = "+ " + defPct;
|
defPct >= 0 ? defPct = "- " + defPct: defPct = "+ " + defPct;
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in a new issue