wynnbuilder-forked-for-changes/build.js

544 lines
24 KiB
JavaScript
Raw Normal View History

2021-01-10 10:02:23 +00:00
const baseDamageMultiplier = [ 0.51, 0.83, 1.5, 2.05, 2.5, 3.1, 4.3 ];
2021-01-12 22:49:57 +00:00
const classDefenseMultipliers = new Map([ ["relik",0.50], ["bow",0.60], ["wand", 0.80], ["dagger", 1.0], ["spear",1.20] ]);
2021-01-10 10:02:23 +00:00
2021-01-17 21:01:20 +00:00
/**
* @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");
}
2021-01-07 00:08:19 +00:00
}
2021-01-17 21:01:20 +00:00
/**
* @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;
2021-01-07 00:08:19 +00:00
}
}
2021-01-17 21:01:20 +00:00
/**
* @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;
2021-01-07 00:08:19 +00:00
}
}
2021-01-07 00:02:10 +00:00
/*Class that represents a wynn player's build.
*/
class Build{
2021-01-17 21:01:20 +00:00
/**
* @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.
2021-01-17 21:01:20 +00:00
* @param {Number[]} powders : Powder application. List of lists of integers (powder IDs).
* In order: boots, Chestplate, Leggings, Boots, Weapon.
2021-01-17 21:01:20 +00:00
* @param {Object[]} inputerrors : List of instances of error-like classes.
2021-01-09 08:52:58 +00:00
*/
constructor(level,equipment, powders, externalStats, inputerrors=[]){
2021-01-17 21:01:20 +00:00
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 = [];
2021-01-08 20:17:37 +00:00
// NOTE: powders is just an array of arrays of powder IDs. Not powder objects.
2021-01-09 19:50:36 +00:00
this.powders = powders;
if(itemMap.get(equipment[0]) && itemMap.get(equipment[0]).type === "helmet") {
const helmet = itemMap.get(equipment[0]);
2021-01-08 20:17:37 +00:00
this.powders[0] = this.powders[0].slice(0,helmet.slots);
this.helmet = expandItem(helmet, this.powders[0]);
2021-01-30 11:06:16 +00:00
} 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);
2021-01-30 11:15:31 +00:00
if (helmet.statMap.get("type") !== "helmet") {
throw new Error("Not a helmet");
}
this.powders[0] = this.powders[0].slice(0,helmet.statMap.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]);
2021-01-08 20:17:37 +00:00
this.powders[1] = this.powders[1].slice(0,chestplate.slots);
this.chestplate = expandItem(chestplate, this.powders[1]);
2021-01-30 11:06:16 +00:00
} else {
try {
let chestplate = getCustomFromHash(equipment[1]) ? getCustomFromHash(equipment[1]) : (getCraftFromHash(equipment[1]) ? getCraftFromHash(equipment[1]) : undefined);
2021-01-30 11:15:31 +00:00
if (chestplate.statMap.get("type") !== "chestplate") {
throw new Error("Not a chestplate");
}
this.powders[1] = this.powders[1].slice(0,chestplate.statMap.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));
}
}
2021-01-30 11:06:16 +00:00
if (itemMap.get(equipment[2]) && itemMap.get(equipment[2]).type === "leggings") {
const leggings = itemMap.get(equipment[2]);
2021-01-08 20:17:37 +00:00
this.powders[2] = this.powders[2].slice(0,leggings.slots);
this.leggings = expandItem(leggings, this.powders[2]);
2021-01-30 11:06:16 +00:00
} else {
try {
let leggings = getCustomFromHash(equipment[2]) ? getCustomFromHash(equipment[2]) : (getCraftFromHash(equipment[2]) ? getCraftFromHash(equipment[2]) : undefined);
2021-01-30 11:15:31 +00:00
if (leggings.statMap.get("type") !== "leggings") {
throw new Error("Not a leggings");
}
this.powders[2] = this.powders[2].slice(0,leggings.statMap.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));
}
}
2021-01-30 11:06:16 +00:00
if (itemMap.get(equipment[3]) && itemMap.get(equipment[3]).type === "boots") {
const boots = itemMap.get(equipment[3]);
2021-01-08 20:17:37 +00:00
this.powders[3] = this.powders[3].slice(0,boots.slots);
this.boots = expandItem(boots, this.powders[3]);
2021-01-30 11:06:16 +00:00
} else {
try {
let boots = getCustomFromHash(equipment[3]) ? getCustomFromHash(equipment[3]) : (getCraftFromHash(equipment[3]) ? getCraftFromHash(equipment[3]) : undefined);
2021-01-30 11:15:31 +00:00
if (boots.statMap.get("type") !== "boots") {
throw new Error("Not a boots");
}
this.powders[3] = this.powders[3].slice(0,boots.statMap.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));
}
2021-01-07 00:02:10 +00:00
}
if(itemMap.get(equipment[4]) && itemMap.get(equipment[4]).type === "ring") {
const ring = itemMap.get(equipment[4]);
2021-01-09 19:50:36 +00:00
this.ring1 = expandItem(ring, []);
2021-01-07 00:02:10 +00:00
}else{
try {
let ring = getCustomFromHash(equipment[4]) ? getCustomFromHash(equipment[4]) : (getCraftFromHash(equipment[4]) ? getCraftFromHash(equipment[4]) : undefined);
2021-01-30 11:15:31 +00:00
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"));
}
2021-01-07 00:02:10 +00:00
}
if(itemMap.get(equipment[5]) && itemMap.get(equipment[5]).type === "ring") {
const ring = itemMap.get(equipment[5]);
2021-01-09 19:50:36 +00:00
this.ring2 = expandItem(ring, []);
2021-01-07 00:02:10 +00:00
}else{
try {
let ring = getCustomFromHash(equipment[5]) ? getCustomFromHash(equipment[5]) : (getCraftFromHash(equipment[5]) ? getCraftFromHash(equipment[5]) : undefined);
2021-01-30 11:15:31 +00:00
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"));
}
2021-01-07 00:02:10 +00:00
}
if(itemMap.get(equipment[6]) && itemMap.get(equipment[6]).type === "bracelet") {
const bracelet = itemMap.get(equipment[6]);
2021-01-09 19:50:36 +00:00
this.bracelet = expandItem(bracelet, []);
2021-01-07 00:02:10 +00:00
}else{
try {
let bracelet = getCustomFromHash(equipment[6]) ? getCustomFromHash(equipment[6]) : (getCraftFromHash(equipment[6]) ? getCraftFromHash(equipment[6]) : undefined);
2021-01-30 11:15:31 +00:00
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));
}
2021-01-07 00:02:10 +00:00
}
if(itemMap.get(equipment[7]) && itemMap.get(equipment[7]).type === "necklace") {
const necklace = itemMap.get(equipment[7]);
2021-01-09 19:50:36 +00:00
this.necklace = expandItem(necklace, []);
2021-01-07 00:02:10 +00:00
}else{
try {
let necklace = getCustomFromHash(equipment[7]) ? getCustomFromHash(equipment[7]) : (getCraftFromHash(equipment[7]) ? getCraftFromHash(equipment[7]) : undefined);
2021-01-30 11:15:31 +00:00
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));
}
2021-01-07 00:02:10 +00:00
}
if(itemMap.get(equipment[8]) && itemMap.get(equipment[8]).category === "weapon") {
const weapon = itemMap.get(equipment[8]);
2021-01-08 20:17:37 +00:00
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";
}
2021-01-07 00:02:10 +00:00
}else{
try {
let weapon = getCustomFromHash(equipment[8]) ? getCustomFromHash(equipment[8]) : (getCraftFromHash(equipment[8]) ? getCraftFromHash(equipment[8]) : undefined);
2021-01-30 11:15:31 +00:00
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.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));
}
2021-01-07 00:02:10 +00:00
}
//console.log(this.craftedItems)
2021-01-17 21:01:20 +00:00
if (level < 1) { //Should these be constants?
2021-01-07 00:02:10 +00:00
this.level = 1;
2021-01-17 21:01:20 +00:00
} else if (level > 106) {
2021-01-07 00:02:10 +00:00
this.level = 106;
2021-01-17 21:01:20 +00:00
} else if (level <= 106 && level >= 1) {
2021-01-07 00:02:10 +00:00
this.level = level;
2021-01-17 21:01:20 +00:00
} 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.");
2021-01-07 00:02:10 +00:00
}
2021-01-17 21:01:20 +00:00
document.getElementById("level-choice").value = this.level;
2021-01-07 06:41:41 +00:00
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]);
2021-01-07 06:41:41 +00:00
// return [equip_order, best_skillpoints, final_skillpoints, best_total];
let result = calculate_skillpoints(this.equipment, this.weapon);
console.log(result);
2021-01-07 06:41:41 +00:00
this.equip_order = result[0];
this.base_skillpoints = result[1];
this.total_skillpoints = result[2];
this.assigned_skillpoints = result[3];
this.activeSetCounts = result[4];
2021-01-08 20:17:37 +00:00
// For strength boosts like warscream, vanish, etc.
this.damageMultiplier = 1.0;
this.defenseMultiplier = 1.0;
2021-01-08 20:17:37 +00:00
// For other external boosts ;-;
this.externalStats = externalStats;
2021-01-08 04:31:29 +00:00
this.initBuildStats();
2021-01-17 21:01:20 +00:00
// 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;
2021-01-07 00:02:10 +00:00
}
/*Returns build in string format
2021-01-07 06:41:41 +00:00
*/
2021-01-07 00:02:10 +00:00
toString(){
2021-01-19 17:32:27 +00:00
return [this.equipment,this.weapon].flat();
2021-01-07 00:02:10 +00:00
}
2021-01-07 06:41:41 +00:00
/* Getters */
2021-01-07 21:32:36 +00:00
/* Get total health for build.
*/
2021-01-09 08:52:58 +00:00
getSpellCost(spellIdx, cost) {
cost = Math.ceil(cost * (1 - skillPointsToPercentage(this.total_skillpoints[2])));
cost += this.statMap.get("spRaw"+spellIdx);
return Math.max(1, Math.floor(cost * (1 + this.statMap.get("spPct"+spellIdx) / 100)));
2021-01-09 08:52:58 +00:00
}
/* Get melee stats for build.
Returns an array in the order:
2021-01-07 21:32:36 +00:00
*/
getMeleeStats(){
2021-01-08 05:36:57 +00:00
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")]);
}
2021-01-08 05:36:57 +00:00
let adjAtkSpd = attackSpeeds.indexOf(stats.get("atkSpd")) + stats.get("atkTier");
if(adjAtkSpd > 6){
adjAtkSpd = 6;
}else if(adjAtkSpd < 0){
adjAtkSpd = 0;
}
// 0 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, this.damageMultiplier, this.externalStats);
2021-01-11 02:58:39 +00:00
let dex = this.total_skillpoints[1];
let totalDamNorm = results[0];
let totalDamCrit = results[1];
2021-01-11 02:58:39 +00:00
totalDamNorm.push(1-skillPointsToPercentage(dex));
totalDamCrit.push(skillPointsToPercentage(dex));
let damages_results = results[2];
2021-01-11 02:58:39 +00:00
2021-01-12 22:49:57 +00:00
let singleHitTotal = ((totalDamNorm[0]+totalDamNorm[1])*(totalDamNorm[2])
+(totalDamCrit[0]+totalDamCrit[1])*(totalDamCrit[2]))/2;
2021-01-08 04:31:29 +00:00
//Now do math
2021-01-08 05:36:57 +00:00
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)));
2021-01-12 22:49:57 +00:00
//[[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]);
2021-01-07 21:32:36 +00:00
}
2021-01-10 10:02:23 +00:00
/*
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");
2021-01-10 12:54:25 +00:00
if (totalHp < 5) totalHp = 5;
2021-01-10 10:02:23 +00:00
defenseStats.push(totalHp);
//EHP
2021-01-11 00:46:30 +00:00
let ehp = [totalHp, totalHp];
2021-01-10 10:02:23 +00:00
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));
2021-01-10 10:02:23 +00:00
defenseStats.push(ehp);
//HPR
let totalHpr = rawToPct(stats.get("hprRaw"), stats.get("hprPct")/100.);
defenseStats.push(totalHpr);
//EHPR
2021-01-11 00:46:30 +00:00
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));
2021-01-10 10:02:23 +00:00
defenseStats.push(ehpr);
//skp stats
defenseStats.push([ (1 - ((1-def_pct) * (2 - this.defenseMultiplier)))*100, agi_pct*100]);
2021-01-10 10:02:23 +00:00
//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);
2021-01-11 00:46:30 +00:00
//[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]]
2021-01-10 10:02:23 +00:00
return defenseStats;
}
2021-01-08 05:36:57 +00:00
/* Get all stats for this build. Stores in this.statMap.
2021-01-07 21:32:36 +00:00
@pre The build itself should be valid. No checking of validity of pieces is done here.
*/
2021-01-08 04:31:29 +00:00
initBuildStats(){
let staticIDs = ["hp", "eDef", "tDef", "wDef", "fDef", "aDef"];
2021-01-07 21:32:36 +00:00
//Create a map of this build's stats
let statMap = new Map();
2021-01-08 04:31:29 +00:00
for (const staticID of staticIDs) {
statMap.set(staticID, 0);
2021-01-07 21:32:36 +00:00
}
statMap.set("hp", levelToHPBase(this.level));
2021-01-30 12:03:40 +00:00
let major_ids = new Set();
for (const item of this.items){
2021-01-08 04:31:29 +00:00
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));
}
2021-01-07 21:32:36 +00:00
}
2021-01-30 12:03:40 +00:00
if (item.get("majorIds")) {
for (const majorID of item.get("majorIds")) {
major_ids.add(majorID);
}
}
2021-01-07 21:32:36 +00:00
}
2021-01-30 12:03:40 +00:00
statMap.set("activeMajorIDs", major_ids);
for (const [setName, count] of this.activeSetCounts) {
2021-01-10 03:40:15 +00:00
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]);
}
2021-01-10 03:40:15 +00:00
}
}
statMap.set("poisonPct", 100);
2021-01-07 06:41:41 +00:00
2021-01-08 04:31:29 +00:00
// 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);
2021-01-08 04:31:29 +00:00
this.statMap = statMap;
this.aggregateStats();
2021-01-08 04:31:29 +00:00
}
2021-01-07 00:02:10 +00:00
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")]);
}
2021-01-07 00:02:10 +00:00
}