Wynn2 damage calculation
This commit is contained in:
parent
14ab20c446
commit
2b18774395
6 changed files with 267 additions and 160 deletions
22
js/build.js
22
js/build.js
|
@ -155,6 +155,17 @@ class Build{
|
||||||
|
|
||||||
let staticIDs = ["hp", "eDef", "tDef", "wDef", "fDef", "aDef", "str", "dex", "int", "def", "agi", "dmgMobs", "defMobs"];
|
let staticIDs = ["hp", "eDef", "tDef", "wDef", "fDef", "aDef", "str", "dex", "int", "def", "agi", "dmgMobs", "defMobs"];
|
||||||
|
|
||||||
|
let must_ids = [
|
||||||
|
"eMdPct","eMdRaw","eSdPct","eSdRaw","eDamPct","eDamRaw","eDamAddMin","eDamAddMax",
|
||||||
|
"tMdPct","tMdRaw","tSdPct","tSdRaw","tDamPct","tDamRaw","tDamAddMin","tDamAddMax",
|
||||||
|
"wMdPct","wMdRaw","wSdPct","wSdRaw","wDamPct","wDamRaw","wDamAddMin","wDamAddMax",
|
||||||
|
"fMdPct","fMdRaw","fSdPct","fSdRaw","fDamPct","fDamRaw","fDamAddMin","fDamAddMax",
|
||||||
|
"aMdPct","aMdRaw","aSdPct","aSdRaw","aDamPct","aDamRaw","aDamAddMin","aDamAddMax",
|
||||||
|
"nMdPct","nMdRaw","nSdPct","nSdRaw","nDamPct","nDamRaw","nDamAddMin","nDamAddMax", // neutral which is now an element
|
||||||
|
"mdPct","mdRaw","sdPct","sdRaw","damPct","damRaw","damAddMin","damAddMax", // These are the old ids. Become proportional.
|
||||||
|
"rMdPct","rMdRaw","rSdPct","rSdRaw","rDamPct","rDamRaw","rDamAddMin","rDamAddMax" // rainbow (the "element" of all minus neutral). rSdRaw is rainraw
|
||||||
|
]
|
||||||
|
|
||||||
//Create a map of this build's stats
|
//Create a map of this build's stats
|
||||||
let statMap = new Map();
|
let statMap = new Map();
|
||||||
statMap.set("damageMultiplier", 1);
|
statMap.set("damageMultiplier", 1);
|
||||||
|
@ -163,6 +174,9 @@ class Build{
|
||||||
for (const staticID of staticIDs) {
|
for (const staticID of staticIDs) {
|
||||||
statMap.set(staticID, 0);
|
statMap.set(staticID, 0);
|
||||||
}
|
}
|
||||||
|
for (const staticID of must_ids) {
|
||||||
|
statMap.set(staticID, 0);
|
||||||
|
}
|
||||||
statMap.set("hp", levelToHPBase(this.level));
|
statMap.set("hp", levelToHPBase(this.level));
|
||||||
|
|
||||||
let major_ids = new Set();
|
let major_ids = new Set();
|
||||||
|
@ -211,13 +225,5 @@ class Build{
|
||||||
statMap.set("atkSpd", this.weapon.statMap.get("atkSpd"));
|
statMap.set("atkSpd", this.weapon.statMap.get("atkSpd"));
|
||||||
|
|
||||||
this.statMap = statMap;
|
this.statMap = statMap;
|
||||||
|
|
||||||
this.aggregateStats();
|
|
||||||
}
|
|
||||||
|
|
||||||
aggregateStats() {
|
|
||||||
let statMap = this.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")]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,12 +66,23 @@ let itemTypes = armorTypes.concat(accessoryTypes).concat(weaponTypes).concat(tom
|
||||||
let elementIcons = ["\u2724","\u2726", "\u2749", "\u2739", "\u274b" ];
|
let elementIcons = ["\u2724","\u2726", "\u2749", "\u2739", "\u274b" ];
|
||||||
let skpReqs = skp_order.map(x => x + "Req");
|
let skpReqs = skp_order.map(x => x + "Req");
|
||||||
|
|
||||||
let item_fields = [ "name", "displayName", "lore", "color", "tier", "set", "slots", "type", "material", "drop", "quest", "restrict", "nDam", "fDam", "wDam", "aDam", "tDam", "eDam", "atkSpd", "hp", "fDef", "wDef", "aDef", "tDef", "eDef", "lvl", "classReq", "strReq", "dexReq", "intReq", "defReq", "agiReq", "hprPct", "mr", "sdPct", "mdPct", "ls", "ms", "xpb", "lb", "ref", "str", "dex", "int", "agi", "def", "thorns", "expd", "spd", "atkTier", "poison", "hpBonus", "spRegen", "eSteal", "hprRaw", "sdRaw", "mdRaw", "fDamPct", "wDamPct", "aDamPct", "tDamPct", "eDamPct", "fDefPct", "wDefPct", "aDefPct", "tDefPct", "eDefPct", "fixID", "category", "spPct1", "spRaw1", "spPct2", "spRaw2", "spPct3", "spRaw3", "spPct4", "spRaw4", "rainbowRaw", "sprint", "sprintReg", "jh", "lq", "gXp", "gSpd", "id", "majorIds", "dmgMobs", "defMobs"];
|
let item_fields = [ "name", "displayName", "lore", "color", "tier", "set", "slots", "type", "material", "drop", "quest", "restrict", "nDam", "fDam", "wDam", "aDam", "tDam", "eDam", "atkSpd", "hp", "fDef", "wDef", "aDef", "tDef", "eDef", "lvl", "classReq", "strReq", "dexReq", "intReq", "defReq", "agiReq", "hprPct", "mr", "sdPct", "mdPct", "ls", "ms", "xpb", "lb", "ref", "str", "dex", "int", "agi", "def", "thorns", "expd", "spd", "atkTier", "poison", "hpBonus", "spRegen", "eSteal", "hprRaw", "sdRaw", "mdRaw", "fDamPct", "wDamPct", "aDamPct", "tDamPct", "eDamPct", "fDefPct", "wDefPct", "aDefPct", "tDefPct", "eDefPct", "fixID", "category", "spPct1", "spRaw1", "spPct2", "spRaw2", "spPct3", "spRaw3", "spPct4", "spRaw4", "rSdRaw", "sprint", "sprintReg", "jh", "lq", "gXp", "gSpd", "id", "majorIds", "damMobs", "defMobs",
|
||||||
|
|
||||||
|
// wynn2 damages.
|
||||||
|
"eMdPct","eMdRaw","eSdPct","eSdRaw",/*"eDamPct"*/,"eDamRaw","eDamAddMin","eDamAddMax",
|
||||||
|
"tMdPct","tMdRaw","tSdPct","tSdRaw",/*"tDamPct"*/,"tDamRaw","tDamAddMin","tDamAddMax",
|
||||||
|
"wMdPct","wMdRaw","wSdPct","wSdRaw",/*"wDamPct"*/,"wDamRaw","wDamAddMin","wDamAddMax",
|
||||||
|
"fMdPct","fMdRaw","fSdPct","fSdRaw",/*"fDamPct"*/,"fDamRaw","fDamAddMin","fDamAddMax",
|
||||||
|
"aMdPct","aMdRaw","aSdPct","aSdRaw",/*"aDamPct"*/,"aDamRaw","aDamAddMin","aDamAddMax",
|
||||||
|
"nMdPct","nMdRaw","nSdPct","nSdRaw","nDamPct","nDamRaw","nDamAddMin","nDamAddMax", // neutral which is now an element
|
||||||
|
/*"mdPct","mdRaw","sdPct","sdRaw",*/"damPct","damRaw","damAddMin","damAddMax", // These are the old ids. Become proportional.
|
||||||
|
"rMdPct","rMdRaw","rSdPct",/*"rSdRaw",*/"rDamPct","rDamRaw","rDamAddMin","rDamAddMax" // rainbow (the "element" of all minus neutral). rSdRaw is rainraw
|
||||||
|
];
|
||||||
let str_item_fields = [ "name", "displayName", "lore", "color", "tier", "set", "type", "material", "drop", "quest", "restrict", "category", "atkSpd" ]
|
let str_item_fields = [ "name", "displayName", "lore", "color", "tier", "set", "type", "material", "drop", "quest", "restrict", "category", "atkSpd" ]
|
||||||
|
|
||||||
//File reading for ID translations for JSON purposes
|
//File reading for ID translations for JSON purposes
|
||||||
let reversetranslations = new Map();
|
let reversetranslations = new Map();
|
||||||
let translations = new Map([["name", "name"], ["displayName", "displayName"], ["tier", "tier"], ["set", "set"], ["sockets", "slots"], ["type", "type"], ["dropType", "drop"], ["quest", "quest"], ["restrictions", "restrict"], ["damage", "nDam"], ["fireDamage", "fDam"], ["waterDamage", "wDam"], ["airDamage", "aDam"], ["thunderDamage", "tDam"], ["earthDamage", "eDam"], ["attackSpeed", "atkSpd"], ["health", "hp"], ["fireDefense", "fDef"], ["waterDefense", "wDef"], ["airDefense", "aDef"], ["thunderDefense", "tDef"], ["earthDefense", "eDef"], ["level", "lvl"], ["classRequirement", "classReq"], ["strength", "strReq"], ["dexterity", "dexReq"], ["intelligence", "intReq"], ["agility", "agiReq"], ["defense", "defReq"], ["healthRegen", "hprPct"], ["manaRegen", "mr"], ["spellDamage", "sdPct"], ["damageBonus", "mdPct"], ["lifeSteal", "ls"], ["manaSteal", "ms"], ["xpBonus", "xpb"], ["lootBonus", "lb"], ["reflection", "ref"], ["strengthPoints", "str"], ["dexterityPoints", "dex"], ["intelligencePoints", "int"], ["agilityPoints", "agi"], ["defensePoints", "def"], ["thorns", "thorns"], ["exploding", "expd"], ["speed", "spd"], ["attackSpeedBonus", "atkTier"], ["poison", "poison"], ["healthBonus", "hpBonus"], ["soulPoints", "spRegen"], ["emeraldStealing", "eSteal"], ["healthRegenRaw", "hprRaw"], ["spellDamageRaw", "sdRaw"], ["damageBonusRaw", "mdRaw"], ["bonusFireDamage", "fDamPct"], ["bonusWaterDamage", "wDamPct"], ["bonusAirDamage", "aDamPct"], ["bonusThunderDamage", "tDamPct"], ["bonusEarthDamage", "eDamPct"], ["bonusFireDefense", "fDefPct"], ["bonusWaterDefense", "wDefPct"], ["bonusAirDefense", "aDefPct"], ["bonusThunderDefense", "tDefPct"], ["bonusEarthDefense", "eDefPct"], ["type", "type"], ["identified", "fixID"], ["skin", "skin"], ["category", "category"], ["spellCostPct1", "spPct1"], ["spellCostRaw1", "spRaw1"], ["spellCostPct2", "spPct2"], ["spellCostRaw2", "spRaw2"], ["spellCostPct3", "spPct3"], ["spellCostRaw3", "spRaw3"], ["spellCostPct4", "spPct4"], ["spellCostRaw4", "spRaw4"], ["rainbowSpellDamageRaw", "rainbowRaw"], ["sprint", "sprint"], ["sprintRegen", "sprintReg"], ["jumpHeight", "jh"], ["lootQuality", "lq"], ["gatherXpBonus", "gXp"], ["gatherSpeed", "gSpd"]]);
|
let translations = new Map([["name", "name"], ["displayName", "displayName"], ["tier", "tier"], ["set", "set"], ["sockets", "slots"], ["type", "type"], ["dropType", "drop"], ["quest", "quest"], ["restrictions", "restrict"], ["damage", "nDam"], ["fireDamage", "fDam"], ["waterDamage", "wDam"], ["airDamage", "aDam"], ["thunderDamage", "tDam"], ["earthDamage", "eDam"], ["attackSpeed", "atkSpd"], ["health", "hp"], ["fireDefense", "fDef"], ["waterDefense", "wDef"], ["airDefense", "aDef"], ["thunderDefense", "tDef"], ["earthDefense", "eDef"], ["level", "lvl"], ["classRequirement", "classReq"], ["strength", "strReq"], ["dexterity", "dexReq"], ["intelligence", "intReq"], ["agility", "agiReq"], ["defense", "defReq"], ["healthRegen", "hprPct"], ["manaRegen", "mr"], ["spellDamage", "sdPct"], ["damageBonus", "mdPct"], ["lifeSteal", "ls"], ["manaSteal", "ms"], ["xpBonus", "xpb"], ["lootBonus", "lb"], ["reflection", "ref"], ["strengthPoints", "str"], ["dexterityPoints", "dex"], ["intelligencePoints", "int"], ["agilityPoints", "agi"], ["defensePoints", "def"], ["thorns", "thorns"], ["exploding", "expd"], ["speed", "spd"], ["attackSpeedBonus", "atkTier"], ["poison", "poison"], ["healthBonus", "hpBonus"], ["soulPoints", "spRegen"], ["emeraldStealing", "eSteal"], ["healthRegenRaw", "hprRaw"], ["spellDamageRaw", "sdRaw"], ["damageBonusRaw", "mdRaw"], ["bonusFireDamage", "fDamPct"], ["bonusWaterDamage", "wDamPct"], ["bonusAirDamage", "aDamPct"], ["bonusThunderDamage", "tDamPct"], ["bonusEarthDamage", "eDamPct"], ["bonusFireDefense", "fDefPct"], ["bonusWaterDefense", "wDefPct"], ["bonusAirDefense", "aDefPct"], ["bonusThunderDefense", "tDefPct"], ["bonusEarthDefense", "eDefPct"], ["type", "type"], ["identified", "fixID"], ["skin", "skin"], ["category", "category"], ["spellCostPct1", "spPct1"], ["spellCostRaw1", "spRaw1"], ["spellCostPct2", "spPct2"], ["spellCostRaw2", "spRaw2"], ["spellCostPct3", "spPct3"], ["spellCostRaw3", "spRaw3"], ["spellCostPct4", "spPct4"], ["spellCostRaw4", "spRaw4"], ["rainbowSpellDamageRaw", "rSdRaw"], ["sprint", "sprint"], ["sprintRegen", "sprintReg"], ["jumpHeight", "jh"], ["lootQuality", "lq"], ["gatherXpBonus", "gXp"], ["gatherSpeed", "gSpd"]]);
|
||||||
//does not include dmgMobs (wep tomes) and defMobs (armor tomes)
|
//does not include dmgMobs (wep tomes) and defMobs (armor tomes)
|
||||||
for (const [k, v] of translations) {
|
for (const [k, v] of translations) {
|
||||||
reversetranslations.set(v, k);
|
reversetranslations.set(v, k);
|
||||||
|
@ -103,7 +114,17 @@ let nonRolledIDs = [
|
||||||
"skillpoints",
|
"skillpoints",
|
||||||
"reqs",
|
"reqs",
|
||||||
"nDam_", "fDam_", "wDam_", "aDam_", "tDam_", "eDam_",
|
"nDam_", "fDam_", "wDam_", "aDam_", "tDam_", "eDam_",
|
||||||
"majorIds"];
|
"majorIds",
|
||||||
|
// wynn2 damages.
|
||||||
|
"eDamAddMin","eDamAddMax",
|
||||||
|
"tDamAddMin","tDamAddMax",
|
||||||
|
"wDamAddMin","wDamAddMax",
|
||||||
|
"fDamAddMin","fDamAddMax",
|
||||||
|
"aDamAddMin","aDamAddMax",
|
||||||
|
"nDamAddMin","nDamAddMax", // neutral which is now an element
|
||||||
|
"damAddMin","damAddMax", // all
|
||||||
|
"rDamAddMin","rDamAddMax" // rainbow (the "element" of all minus neutral).
|
||||||
|
];
|
||||||
let rolledIDs = [
|
let rolledIDs = [
|
||||||
"hprPct",
|
"hprPct",
|
||||||
"mr",
|
"mr",
|
||||||
|
@ -131,13 +152,22 @@ let rolledIDs = [
|
||||||
"spPct2", "spRaw2",
|
"spPct2", "spRaw2",
|
||||||
"spPct3", "spRaw3",
|
"spPct3", "spRaw3",
|
||||||
"spPct4", "spRaw4",
|
"spPct4", "spRaw4",
|
||||||
"rainbowRaw",
|
"pDamRaw",
|
||||||
"sprint",
|
"sprint",
|
||||||
"sprintReg",
|
"sprintReg",
|
||||||
"jh",
|
"jh",
|
||||||
"lq",
|
"lq",
|
||||||
"gXp",
|
"gXp",
|
||||||
"gSpd"
|
"gSpd",
|
||||||
|
// wynn2 damages.
|
||||||
|
"eMdPct","eMdRaw","eSdPct","eSdRaw",/*"eDamPct"*/,"eDamRaw","eDamAddMin","eDamAddMax",
|
||||||
|
"tMdPct","tMdRaw","tSdPct","tSdRaw",/*"tDamPct"*/,"tDamRaw","tDamAddMin","tDamAddMax",
|
||||||
|
"wMdPct","wMdRaw","wSdPct","wSdRaw",/*"wDamPct"*/,"wDamRaw","wDamAddMin","wDamAddMax",
|
||||||
|
"fMdPct","fMdRaw","fSdPct","fSdRaw",/*"fDamPct"*/,"fDamRaw","fDamAddMin","fDamAddMax",
|
||||||
|
"aMdPct","aMdRaw","aSdPct","aSdRaw",/*"aDamPct"*/,"aDamRaw","aDamAddMin","aDamAddMax",
|
||||||
|
"nMdPct","nMdRaw","nSdPct","nSdRaw","nDamPct","nDamRaw","nDamAddMin","nDamAddMax", // neutral which is now an element
|
||||||
|
/*"mdPct","mdRaw","sdPct","sdRaw",*/"damPct","damRaw","damAddMin","damAddMax", // These are the old ids. Become proportional.
|
||||||
|
"rMdPct","rMdRaw","rSdPct",/*"rSdRaw",*/"rDamPct","rDamRaw","rDamAddMin","rDamAddMax" // rainbow (the "element" of all minus neutral). rSdRaw is rainraw
|
||||||
];
|
];
|
||||||
let reversedIDs = [ "spPct1", "spRaw1", "spPct2", "spRaw2", "spPct3", "spRaw3", "spPct4", "spRaw4" ];
|
let reversedIDs = [ "spPct1", "spRaw1", "spPct2", "spRaw2", "spPct3", "spRaw3", "spPct4", "spRaw4" ];
|
||||||
|
|
||||||
|
|
|
@ -313,9 +313,10 @@ class ItemDisplayNode extends ComputeNode {
|
||||||
*/
|
*/
|
||||||
class WeaponInputDisplayNode extends ComputeNode {
|
class WeaponInputDisplayNode extends ComputeNode {
|
||||||
|
|
||||||
constructor(name, image_field) {
|
constructor(name, image_field, dps_field) {
|
||||||
super(name);
|
super(name);
|
||||||
this.image = image_field;
|
this.image = image_field;
|
||||||
|
this.dps_field = dps_field;
|
||||||
}
|
}
|
||||||
|
|
||||||
compute_func(input_map) {
|
compute_func(input_map) {
|
||||||
|
@ -324,6 +325,12 @@ class WeaponInputDisplayNode extends ComputeNode {
|
||||||
|
|
||||||
const type = item.statMap.get('type');
|
const type = item.statMap.get('type');
|
||||||
this.image.setAttribute('src', '../media/items/new/generic-'+type+'.png');
|
this.image.setAttribute('src', '../media/items/new/generic-'+type+'.png');
|
||||||
|
let dps = get_base_dps(item.statMap);
|
||||||
|
if (isNaN(dps)) {
|
||||||
|
dps = dps[1];
|
||||||
|
if (isNaN(dps)) dps = 0;
|
||||||
|
}
|
||||||
|
this.dps_field.textContent = dps;
|
||||||
|
|
||||||
//as of now, we NEED to have the dropdown tab visible/not hidden in order to properly display atree stuff.
|
//as of now, we NEED to have the dropdown tab visible/not hidden in order to properly display atree stuff.
|
||||||
if (!document.getElementById("toggle-atree").classList.contains("toggleOn")) {
|
if (!document.getElementById("toggle-atree").classList.contains("toggleOn")) {
|
||||||
|
@ -577,9 +584,11 @@ class SpellDamageCalcNode extends ComputeNode {
|
||||||
|
|
||||||
for (const part of spell_parts) {
|
for (const part of spell_parts) {
|
||||||
if (part.type === "damage") {
|
if (part.type === "damage") {
|
||||||
let results = calculateSpellDamage(stats, part.conversion,
|
let tmp_conv = [];
|
||||||
stats.get("sdRaw") + stats.get("rainbowRaw"), stats.get("sdPct"),
|
for (let i in part.conversion) {
|
||||||
part.multiplier / 100, weapon, skillpoints, damage_mult);
|
tmp_conv.push(part.conversion[i] * part.multiplier/100);
|
||||||
|
}
|
||||||
|
let results = calculateSpellDamage(stats, weapon, tmp_conv, true);
|
||||||
spell_results.push(results);
|
spell_results.push(results);
|
||||||
} else if (part.type === "heal") {
|
} else if (part.type === "heal") {
|
||||||
// TODO: wynn2 formula
|
// TODO: wynn2 formula
|
||||||
|
@ -651,8 +660,7 @@ function getMeleeStats(stats, weapon) {
|
||||||
//One day we will create WynnWynn and no longer have shaman 99% melee injustice.
|
//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.
|
//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, weapon_stats, [100, 0, 0, 0, 0, 0], false, true);
|
||||||
let results = calculateSpellDamage(stats, [100, 0, 0, 0, 0, 0], stats.get("mdRaw"), stats.get("mdPct"), 0, weapon_stats, skillpoints, damage_mult);
|
|
||||||
|
|
||||||
let dex = skillpoints[1];
|
let dex = skillpoints[1];
|
||||||
|
|
||||||
|
@ -973,7 +981,6 @@ function builder_graph_init() {
|
||||||
//new PrintNode(eq+'-debug').link_to(item_input);
|
//new PrintNode(eq+'-debug').link_to(item_input);
|
||||||
//document.querySelector("#"+eq+"-tooltip").setAttribute("onclick", "collapse_element('#"+ eq +"-tooltip');"); //toggle_plus_minus('" + eq + "-pm');
|
//document.querySelector("#"+eq+"-tooltip").setAttribute("onclick", "collapse_element('#"+ eq +"-tooltip');"); //toggle_plus_minus('" + eq + "-pm');
|
||||||
}
|
}
|
||||||
console.log(none_tomes);
|
|
||||||
for (const [eq, none_item] of zip2(tome_fields, [none_tomes[0], none_tomes[0], none_tomes[1], none_tomes[1], none_tomes[1], none_tomes[1], none_tomes[2]])) {
|
for (const [eq, none_item] of zip2(tome_fields, [none_tomes[0], none_tomes[0], none_tomes[1], none_tomes[1], none_tomes[1], none_tomes[1], none_tomes[2]])) {
|
||||||
let input_field = document.getElementById(eq+"-choice");
|
let input_field = document.getElementById(eq+"-choice");
|
||||||
let item_image = document.getElementById(eq+"-img");
|
let item_image = document.getElementById(eq+"-img");
|
||||||
|
@ -985,7 +992,8 @@ function builder_graph_init() {
|
||||||
|
|
||||||
// weapon image changer node.
|
// weapon image changer node.
|
||||||
let weapon_image = document.getElementById("weapon-img");
|
let weapon_image = document.getElementById("weapon-img");
|
||||||
new WeaponInputDisplayNode('weapon-type', weapon_image).link_to(item_nodes[8]);
|
let weapon_dps = document.getElementById("weapon-dps");
|
||||||
|
new WeaponInputDisplayNode('weapon-type', weapon_image, weapon_dps).link_to(item_nodes[8]);
|
||||||
|
|
||||||
// Level input node.
|
// Level input node.
|
||||||
let level_input = new InputNode('level-input', document.getElementById('level-choice'));
|
let level_input = new InputNode('level-input', document.getElementById('level-choice'));
|
||||||
|
|
|
@ -1,31 +1,67 @@
|
||||||
const damageMultipliers = new Map([ ["allytotem", .15], ["yourtotem", .35], ["vanish", 0.80], ["warscream", 0.10], ["bash", 0.50] ]);
|
const damageMultipliers = new Map([ ["allytotem", .15], ["yourtotem", .35], ["vanish", 0.80], ["warscream", 0.10], ["bash", 0.50] ]);
|
||||||
// Calculate spell damage given a spell elemental conversion table, and a spell multiplier.
|
|
||||||
// If spell mult is 0, its melee damage and we don't multiply by attack speed.
|
|
||||||
function calculateSpellDamage(stats, spellConversions, rawModifier, pctModifier, spellMultiplier, weapon, total_skillpoints, damageMultiplier) {
|
|
||||||
let buildStats = new Map(stats);
|
|
||||||
//6x for damages, normal min normal max crit min crit max
|
|
||||||
|
|
||||||
let powders = weapon.get("powders").slice();
|
// GRR THIS MUTATES THE ITEM
|
||||||
|
function get_base_dps(item) {
|
||||||
// Array of neutral + ewtfa damages. Each entry is a pair (min, max).
|
const attack_speed_mult = baseDamageMultiplier[attackSpeeds.indexOf(item.get("atkSpd"))];
|
||||||
let damages = [];
|
//SUPER JANK @HPP PLS FIX
|
||||||
const rawDamages = buildStats.get("damageRaw");
|
let damage_keys = [ "nDam_", "eDam_", "tDam_", "wDam_", "fDam_", "aDam_" ];
|
||||||
for (let i = 0; i < rawDamages.length; i++) {
|
if (item.get("tier") !== "Crafted") {
|
||||||
const damage_vals = rawDamages[i].split("-").map(Number);
|
let weapon_result = apply_weapon_powder(item);
|
||||||
damages.push(damage_vals);
|
let damages = weapon_result[0];
|
||||||
|
let total_damage = 0;
|
||||||
|
for (const i in damage_keys) {
|
||||||
|
total_damage += damages[i][0] + damages[i][1];
|
||||||
|
item.set(damage_keys[i], damages[i][0]+"-"+damages[i][1]);
|
||||||
|
}
|
||||||
|
total_damage = total_damage / 2;
|
||||||
|
return total_damage * attack_speed_mult;
|
||||||
|
} else {
|
||||||
|
let base_low = [item.get("nDamBaseLow"),item.get("eDamBaseLow"),item.get("tDamBaseLow"),item.get("wDamBaseLow"),item.get("fDamBaseLow"),item.get("aDamBaseLow")];
|
||||||
|
let results_low = apply_weapon_powder(item, base_low);
|
||||||
|
let damage_low = results_low[2];
|
||||||
|
let base_high = [item.get("nDamBaseHigh"),item.get("eDamBaseHigh"),item.get("tDamBaseHigh"),item.get("wDamBaseHigh"),item.get("fDamBaseHigh"),item.get("aDamBaseHigh")];
|
||||||
|
let results_high = apply_weapon_powder(item, base_high);
|
||||||
|
let damage_high = results_high[2];
|
||||||
|
|
||||||
|
let total_damage_min = 0;
|
||||||
|
let total_damage_max = 0;
|
||||||
|
for (const i in damage_keys) {
|
||||||
|
total_damage_min += damage_low[i][0] + damage_low[i][1];
|
||||||
|
total_damage_max += damage_high[i][0] + damage_high[i][1];
|
||||||
|
item.set(damage_keys[i], damage_low[i][0]+"-"+damage_low[i][1]+"\u279c"+damage_high[i][0]+"-"+damage_high[i][1]);
|
||||||
|
}
|
||||||
|
total_damage_min = attack_speed_mult * total_damage_min / 2;
|
||||||
|
total_damage_max = attack_speed_mult * total_damage_max / 2;
|
||||||
|
return [total_damage_min, total_damage_max];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* weapon: Weapon to apply powder to
|
||||||
|
* damageBases: used by crafted
|
||||||
|
*/
|
||||||
|
function apply_weapon_powder(weapon, damageBases) {
|
||||||
|
let powders = weapon.get("powders").slice();
|
||||||
|
|
||||||
|
// Array of neutral + ewtfa damages. Each entry is a pair (min, max).
|
||||||
|
let damages = [
|
||||||
|
weapon.get('nDam').split('-').map(Number),
|
||||||
|
weapon.get('eDam').split('-').map(Number),
|
||||||
|
weapon.get('tDam').split('-').map(Number),
|
||||||
|
weapon.get('wDam').split('-').map(Number),
|
||||||
|
weapon.get('fDam').split('-').map(Number),
|
||||||
|
weapon.get('aDam').split('-').map(Number)
|
||||||
|
];
|
||||||
|
|
||||||
// Applying spell conversions
|
// Applying spell conversions
|
||||||
let neutralBase = damages[0].slice();
|
let neutralBase = damages[0].slice();
|
||||||
let neutralRemainingRaw = damages[0].slice();
|
let neutralRemainingRaw = damages[0].slice();
|
||||||
|
|
||||||
|
|
||||||
//powder application for custom crafted weapons is inherently fucked because there is no base. Unsure what to do.
|
//powder application for custom crafted weapons is inherently fucked because there is no base. Unsure what to do.
|
||||||
|
|
||||||
//Powder application for Crafted weapons - this implementation is RIGHT YEAAAAAAAAA
|
//Powder application for Crafted weapons - this implementation is RIGHT YEAAAAAAAAA
|
||||||
//1st round - apply each as ingred, 2nd round - apply as normal
|
//1st round - apply each as ingred, 2nd round - apply as normal
|
||||||
if (weapon.get("tier") === "Crafted") {
|
if (weapon.get("tier") === "Crafted" && !weapon.get("custom")) {
|
||||||
let damageBases = buildStats.get("damageBases").slice();
|
|
||||||
for (const p of powders.concat(weapon.get("ingredPowders"))) {
|
for (const p of powders.concat(weapon.get("ingredPowders"))) {
|
||||||
let powder = powderStats[p]; //use min, max, and convert
|
let powder = powderStats[p]; //use min, max, and convert
|
||||||
let element = Math.floor((p+0.01)/6); //[0,4], the +0.01 attempts to prevent division error
|
let element = Math.floor((p+0.01)/6); //[0,4], the +0.01 attempts to prevent division error
|
||||||
|
@ -34,26 +70,13 @@ function calculateSpellDamage(stats, spellConversions, rawModifier, pctModifier,
|
||||||
damageBases[element+1] += diff + Math.floor( (powder.min + powder.max) / 2 );
|
damageBases[element+1] += diff + Math.floor( (powder.min + powder.max) / 2 );
|
||||||
}
|
}
|
||||||
//update all damages
|
//update all damages
|
||||||
if(!weapon.get("custom")) {
|
for (let i = 0; i < damages.length; i++) {
|
||||||
for (let i = 0; i < damages.length; i++) {
|
damages[i] = [Math.floor(damageBases[i] * 0.9), Math.floor(damageBases[i] * 1.1)];
|
||||||
damages[i] = [Math.floor(damageBases[i] * 0.9), Math.floor(damageBases[i] * 1.1)];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
neutralRemainingRaw = damages[0].slice();
|
neutralRemainingRaw = damages[0].slice();
|
||||||
neutralBase = damages[0].slice();
|
neutralBase = damages[0].slice();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < 5; ++i) {
|
|
||||||
let conversionRatio = spellConversions[i+1]/100;
|
|
||||||
let min_diff = Math.min(neutralRemainingRaw[0], conversionRatio * neutralBase[0]);
|
|
||||||
let max_diff = Math.min(neutralRemainingRaw[1], conversionRatio * neutralBase[1]);
|
|
||||||
damages[i+1][0] = Math.floor(round_near(damages[i+1][0] + min_diff));
|
|
||||||
damages[i+1][1] = Math.floor(round_near(damages[i+1][1] + max_diff));
|
|
||||||
neutralRemainingRaw[0] = Math.floor(round_near(neutralRemainingRaw[0] - min_diff));
|
|
||||||
neutralRemainingRaw[1] = Math.floor(round_near(neutralRemainingRaw[1] - max_diff));
|
|
||||||
}
|
|
||||||
|
|
||||||
//apply powders to weapon
|
//apply powders to weapon
|
||||||
for (const powderID of powders) {
|
for (const powderID of powders) {
|
||||||
const powder = powderStats[powderID];
|
const powder = powderStats[powderID];
|
||||||
|
@ -72,69 +95,148 @@ function calculateSpellDamage(stats, spellConversions, rawModifier, pctModifier,
|
||||||
damages[element+1][1] += powder.max;
|
damages[element+1][1] += powder.max;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The ordering of these two blocks decides whether neutral is present when converted away or not.
|
||||||
|
let present_elements = []
|
||||||
|
for (const damage of damages) {
|
||||||
|
present_elements.push(damage[1] > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The ordering of these two blocks decides whether neutral is present when converted away or not.
|
||||||
damages[0] = neutralRemainingRaw;
|
damages[0] = neutralRemainingRaw;
|
||||||
|
return [damages, present_elements];
|
||||||
|
}
|
||||||
|
|
||||||
let damageMult = damageMultiplier;
|
function calculateSpellDamage(stats, weapon, conversions, use_spell_damage, ignore_speed=false) {
|
||||||
let melee = false;
|
// TODO: Roll all the loops together maybe
|
||||||
// If we are doing melee calculations:
|
|
||||||
if (spellMultiplier == 0) {
|
// Array of neutral + ewtfa damages. Each entry is a pair (min, max).
|
||||||
spellMultiplier = 1;
|
// 1. Get weapon damage (with powders).
|
||||||
melee = true;
|
let weapon_result = apply_weapon_powder(weapon);
|
||||||
}
|
let weapon_damages = weapon_result[0];
|
||||||
else {
|
let present = weapon_result[1];
|
||||||
damageMult *= spellMultiplier * baseDamageMultiplier[attackSpeeds.indexOf(buildStats.get("atkSpd"))];
|
|
||||||
}
|
// 2. Conversions.
|
||||||
//console.log(damages);
|
// 2.1. First, apply neutral conversion (scale weapon damage). Keep track of total weapon damage here.
|
||||||
//console.log(damageMult);
|
let damages = [];
|
||||||
rawModifier *= spellMultiplier * damageMultiplier;
|
const neutral_convert = conversions[0] / 100;
|
||||||
let totalDamNorm = [0, 0];
|
let weapon_min = 0;
|
||||||
let totalDamCrit = [0, 0];
|
let weapon_max = 0;
|
||||||
let damages_results = [];
|
for (const damage of weapon_damages) {
|
||||||
// 0th skillpoint is strength, 1st is dex.
|
let min_dmg = damage[0] * neutral_convert;
|
||||||
let str = total_skillpoints[0];
|
let max_dmg = damage[1] * neutral_convert;
|
||||||
let strBoost = 1 + skillPointsToPercentage(str);
|
damages.push([min_dmg, max_dmg]);
|
||||||
if(!melee){
|
weapon_min += damage[0];
|
||||||
let baseDam = rawModifier * strBoost;
|
weapon_max += damage[1];
|
||||||
let baseDamCrit = rawModifier * (1 + strBoost);
|
|
||||||
totalDamNorm = [baseDam, baseDam];
|
|
||||||
totalDamCrit = [baseDamCrit, baseDamCrit];
|
|
||||||
}
|
|
||||||
let staticBoost = (pctModifier / 100.);
|
|
||||||
let skillBoost = [0];
|
|
||||||
for (let i in total_skillpoints) {
|
|
||||||
skillBoost.push(skillPointsToPercentage(total_skillpoints[i]) + buildStats.get(skp_elements[i]+"DamPct") / 100.);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 2.2. Next, apply elemental conversions using damage computed in step 1.1.
|
||||||
|
// Also, track which elements are present. (Add onto those present in the weapon itself.)
|
||||||
|
for (let i = 1; i <= 5; ++i) {
|
||||||
|
if (conversions[i] > 0) {
|
||||||
|
damages[i][0] += conversions[i]/100 * weapon_min;
|
||||||
|
damages[i][1] += conversions[i]/100 * weapon_max;
|
||||||
|
present[i] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also theres prop and rainbow!!
|
||||||
|
const damage_elements = ['n'].concat(skp_elements); // netwfa
|
||||||
|
|
||||||
|
if (!ignore_speed) {
|
||||||
|
// 3. Apply attack speed multiplier. Ignored for melee single hit
|
||||||
|
const attack_speed_mult = baseDamageMultiplier[attackSpeeds.indexOf(weapon.get("atkSpd"))];
|
||||||
|
for (let i = 0; i < 6; ++i) {
|
||||||
|
damages[i][0] *= attack_speed_mult;
|
||||||
|
damages[i][1] *= attack_speed_mult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Add additive damage. TODO: Is there separate additive damage?
|
||||||
|
for (let i = 0; i < 6; ++i) {
|
||||||
|
if (present[i]) {
|
||||||
|
damages[i][0] += stats.get(damage_elements[i]+'DamAddMin');
|
||||||
|
damages[i][1] += stats.get(damage_elements[i]+'DamAddMax');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. ID bonus.
|
||||||
|
let specific_boost_str = 'Md';
|
||||||
|
if (use_spell_damage) {
|
||||||
|
specific_boost_str = 'Sd';
|
||||||
|
}
|
||||||
|
// 5.1: %boost application
|
||||||
|
let skill_boost = [0]; // no neutral skillpoint booster
|
||||||
|
for (const skp of skp_order) {
|
||||||
|
skill_boost.push(skillPointsToPercentage(stats.get(skp)));
|
||||||
|
}
|
||||||
|
let static_boost = (stats.get(specific_boost_str.toLowerCase()+'Pct') + stats.get('damPct')) / 100;
|
||||||
|
|
||||||
|
// These do not count raw damage. I think. Easy enough to change
|
||||||
|
let total_min = 0;
|
||||||
|
let total_max = 0;
|
||||||
for (let i in damages) {
|
for (let i in damages) {
|
||||||
let damageBoost = 1 + skillBoost[i] + staticBoost;
|
let damage_prefix = damage_elements[i] + specific_boost_str;
|
||||||
damages_results.push([
|
let damageBoost = 1 + skill_boost[i] + static_boost + (stats.get(damage_prefix+'Pct')/100);
|
||||||
Math.max(damages[i][0] * strBoost * Math.max(damageBoost,0) * damageMult, 0), // Normal min
|
damages[i][0] *= Math.max(damageBoost, 0);
|
||||||
Math.max(damages[i][1] * strBoost * Math.max(damageBoost,0) * damageMult, 0), // Normal max
|
damages[i][1] *= Math.max(damageBoost, 0);
|
||||||
Math.max(damages[i][0] * (strBoost + 1) * Math.max(damageBoost,0) * damageMult, 0), // Crit min
|
// Collect total damage post %boost
|
||||||
Math.max(damages[i][1] * (strBoost + 1) * Math.max(damageBoost,0) * damageMult, 0), // Crit max
|
total_min += damages[i][0];
|
||||||
]);
|
total_max += damages[i][1];
|
||||||
totalDamNorm[0] += damages_results[i][0];
|
|
||||||
totalDamNorm[1] += damages_results[i][1];
|
|
||||||
totalDamCrit[0] += damages_results[i][2];
|
|
||||||
totalDamCrit[1] += damages_results[i][3];
|
|
||||||
}
|
}
|
||||||
if (melee) {
|
|
||||||
totalDamNorm[0] += Math.max(strBoost*rawModifier, -damages_results[0][0]);
|
let total_elem_min = total_min - damages[0][0];
|
||||||
totalDamNorm[1] += Math.max(strBoost*rawModifier, -damages_results[0][1]);
|
let total_elem_max = total_max - damages[0][1];
|
||||||
totalDamCrit[0] += Math.max((strBoost+1)*rawModifier, -damages_results[0][2]);
|
|
||||||
totalDamCrit[1] += Math.max((strBoost+1)*rawModifier, -damages_results[0][3]);
|
// 5.2: Raw application.
|
||||||
|
let prop_raw = stats.get(specific_boost_str.toLowerCase()+'Raw') + stats.get('damRaw');
|
||||||
|
let rainbow_raw = stats.get('r'+specific_boost_str+'Raw') + stats.get('rDamRaw');
|
||||||
|
for (let i in damages) {
|
||||||
|
let damages_obj = damages[i];
|
||||||
|
let damage_prefix = damage_elements[i] + specific_boost_str;
|
||||||
|
// Normie raw
|
||||||
|
let raw_boost = 0;
|
||||||
|
if (present[i]) {
|
||||||
|
raw_boost += stats.get(damage_prefix+'Raw') + stats.get(damage_elements[i]+'DamRaw');
|
||||||
|
}
|
||||||
|
// Next, rainraw and propRaw
|
||||||
|
let new_min = damages_obj[0] + raw_boost + (damages_obj[0] / total_min) * prop_raw;
|
||||||
|
let new_max = damages_obj[1] + raw_boost + (damages_obj[1] / total_max) * prop_raw;
|
||||||
|
if (i != 0) { // rainraw
|
||||||
|
new_min += (damages_obj[0] / total_elem_min) * rainbow_raw;
|
||||||
|
new_max += (damages_obj[1] / total_elem_max) * rainbow_raw;
|
||||||
|
}
|
||||||
|
damages_obj[0] = new_min;
|
||||||
|
damages_obj[1] = new_max;
|
||||||
}
|
}
|
||||||
damages_results[0][0] += strBoost*rawModifier;
|
|
||||||
damages_results[0][1] += strBoost*rawModifier;
|
|
||||||
damages_results[0][2] += (strBoost + 1)*rawModifier;
|
|
||||||
damages_results[0][3] += (strBoost + 1)*rawModifier;
|
|
||||||
|
|
||||||
if (totalDamNorm[0] < 0) totalDamNorm[0] = 0;
|
// 6. Strength boosters
|
||||||
if (totalDamNorm[1] < 0) totalDamNorm[1] = 0;
|
// str/dex, as well as any other mutually multiplicative effects
|
||||||
if (totalDamCrit[0] < 0) totalDamCrit[0] = 0;
|
let strBoost = 1 + skill_boost[1];
|
||||||
if (totalDamCrit[1] < 0) totalDamCrit[1] = 0;
|
let total_dam_norm = [0, 0];
|
||||||
|
let total_dam_crit = [0, 0];
|
||||||
|
let damages_results = [];
|
||||||
|
const damage_mult = stats.get("damageMultiplier");
|
||||||
|
|
||||||
return [totalDamNorm, totalDamCrit, damages_results];
|
for (const damage of damages) {
|
||||||
|
const res = [
|
||||||
|
damage[0] * strBoost * damage_mult, // Normal min
|
||||||
|
damage[1] * strBoost * damage_mult, // Normal max
|
||||||
|
damage[0] * (strBoost + 1) * damage_mult, // Crit min
|
||||||
|
damage[1] * (strBoost + 1) * damage_mult, // Crit max
|
||||||
|
];
|
||||||
|
damages_results.push(res);
|
||||||
|
total_dam_norm[0] += res[0];
|
||||||
|
total_dam_norm[1] += res[1];
|
||||||
|
total_dam_crit[0] += res[2];
|
||||||
|
total_dam_crit[1] += res[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (total_dam_norm[0] < 0) total_dam_norm[0] = 0;
|
||||||
|
if (total_dam_norm[1] < 0) total_dam_norm[1] = 0;
|
||||||
|
if (total_dam_crit[0] < 0) total_dam_crit[0] = 0;
|
||||||
|
if (total_dam_crit[1] < 0) total_dam_crit[1] = 0;
|
||||||
|
|
||||||
|
return [total_dam_norm, total_dam_crit, damages_results];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -174,50 +174,7 @@ function displayExpandedItem(item, parent_id){
|
||||||
// !elemental is some janky hack for elemental damage.
|
// !elemental is some janky hack for elemental damage.
|
||||||
// normals just display a thing.
|
// normals just display a thing.
|
||||||
if (item.get("category") === "weapon") {
|
if (item.get("category") === "weapon") {
|
||||||
let stats = new Map();
|
item.set('basedps', get_base_dps(item));
|
||||||
stats.set("atkSpd", item.get("atkSpd"));
|
|
||||||
stats.set("eDamPct", 0);
|
|
||||||
stats.set("tDamPct", 0);
|
|
||||||
stats.set("wDamPct", 0);
|
|
||||||
stats.set("fDamPct", 0);
|
|
||||||
stats.set("aDamPct", 0);
|
|
||||||
|
|
||||||
//SUPER JANK @HPP PLS FIX
|
|
||||||
let damage_keys = [ "nDam_", "eDam_", "tDam_", "wDam_", "fDam_", "aDam_" ];
|
|
||||||
if (item.get("tier") !== "Crafted") {
|
|
||||||
stats.set("damageRaw", [item.get("nDam"), item.get("eDam"), item.get("tDam"), item.get("wDam"), item.get("fDam"), item.get("aDam")]);
|
|
||||||
let results = calculateSpellDamage(stats, [100, 0, 0, 0, 0, 0], 0, 0, 0, item, [0, 0, 0, 0, 0], 1, undefined);
|
|
||||||
let damages = results[2];
|
|
||||||
let total_damage = 0;
|
|
||||||
for (const i in damage_keys) {
|
|
||||||
total_damage += damages[i][0] + damages[i][1];
|
|
||||||
item.set(damage_keys[i], damages[i][0]+"-"+damages[i][1]);
|
|
||||||
}
|
|
||||||
total_damage = total_damage / 2;
|
|
||||||
item.set("basedps", total_damage);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
stats.set("damageRaw", [item.get("nDamLow"), item.get("eDamLow"), item.get("tDamLow"), item.get("wDamLow"), item.get("fDamLow"), item.get("aDamLow")]);
|
|
||||||
stats.set("damageBases", [item.get("nDamBaseLow"),item.get("eDamBaseLow"),item.get("tDamBaseLow"),item.get("wDamBaseLow"),item.get("fDamBaseLow"),item.get("aDamBaseLow")]);
|
|
||||||
let resultsLow = calculateSpellDamage(stats, [100, 0, 0, 0, 0, 0], 0, 0, 0, item, [0, 0, 0, 0, 0], 1, undefined);
|
|
||||||
let damagesLow = resultsLow[2];
|
|
||||||
stats.set("damageRaw", [item.get("nDam"), item.get("eDam"), item.get("tDam"), item.get("wDam"), item.get("fDam"), item.get("aDam")]);
|
|
||||||
stats.set("damageBases", [item.get("nDamBaseHigh"),item.get("eDamBaseHigh"),item.get("tDamBaseHigh"),item.get("wDamBaseHigh"),item.get("fDamBaseHigh"),item.get("aDamBaseHigh")]);
|
|
||||||
let results = calculateSpellDamage(stats, [100, 0, 0, 0, 0, 0], 0, 0, 0, item, [0, 0, 0, 0, 0], 1, undefined);
|
|
||||||
let damages = results[2];
|
|
||||||
console.log(damages);
|
|
||||||
|
|
||||||
let total_damage_min = 0;
|
|
||||||
let total_damage_max = 0;
|
|
||||||
for (const i in damage_keys) {
|
|
||||||
total_damage_min += damagesLow[i][0] + damagesLow[i][1];
|
|
||||||
total_damage_max += damages[i][0] + damages[i][1];
|
|
||||||
item.set(damage_keys[i], damagesLow[i][0]+"-"+damagesLow[i][1]+"\u279c"+damages[i][0]+"-"+damages[i][1]);
|
|
||||||
}
|
|
||||||
total_damage_min = total_damage_min / 2;
|
|
||||||
total_damage_max = total_damage_max / 2;
|
|
||||||
item.set("basedps", [total_damage_min, total_damage_max]);
|
|
||||||
}
|
|
||||||
} else if (item.get("category") === "armor") {
|
} else if (item.get("category") === "armor") {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -555,19 +512,18 @@ function displayExpandedItem(item, parent_id){
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.get("category") === "weapon") {
|
if (item.get("category") === "weapon") {
|
||||||
let damage_mult = baseDamageMultiplier[attackSpeeds.indexOf(item.get("atkSpd"))];
|
|
||||||
let total_damages = item.get("basedps");
|
let total_damages = item.get("basedps");
|
||||||
let base_dps_elem = document.createElement("p");
|
let base_dps_elem = document.createElement("p");
|
||||||
base_dps_elem.classList.add("left");
|
base_dps_elem.classList.add("left");
|
||||||
base_dps_elem.classList.add("itemp");
|
base_dps_elem.classList.add("itemp");
|
||||||
if (item.get("tier") === "Crafted") {
|
if (item.get("tier") === "Crafted") {
|
||||||
let base_dps_min = total_damages[0] * damage_mult;
|
let base_dps_min = total_damages[0];
|
||||||
let base_dps_max = total_damages[1] * damage_mult;
|
let base_dps_max = total_damages[1];
|
||||||
|
|
||||||
base_dps_elem.textContent = "Base DPS: "+base_dps_min.toFixed(3)+"\u279c"+base_dps_max.toFixed(3);
|
base_dps_elem.textContent = "Base DPS: "+base_dps_min.toFixed(3)+"\u279c"+base_dps_max.toFixed(3);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
base_dps_elem.textContent = "Base DPS: "+(total_damages * damage_mult);
|
base_dps_elem.textContent = "Base DPS: "+(total_damages);
|
||||||
}
|
}
|
||||||
parent_div.appendChild(document.createElement("p"));
|
parent_div.appendChild(document.createElement("p"));
|
||||||
parent_div.appendChild(base_dps_elem);
|
parent_div.appendChild(base_dps_elem);
|
||||||
|
@ -1502,9 +1458,12 @@ function displayPowderSpecials(parent_elem, powderSpecials, stats, weapon, overa
|
||||||
if (powderSpecialStats.indexOf(special[0]) == 0 || powderSpecialStats.indexOf(special[0]) == 1 || powderSpecialStats.indexOf(special[0]) == 3) { //Quake, Chain Lightning, or Courage
|
if (powderSpecialStats.indexOf(special[0]) == 0 || powderSpecialStats.indexOf(special[0]) == 1 || powderSpecialStats.indexOf(special[0]) == 3) { //Quake, Chain Lightning, or Courage
|
||||||
let spell = (powderSpecialStats.indexOf(special[0]) == 3 ? spells[2] : spells[powderSpecialStats.indexOf(special[0])]);
|
let spell = (powderSpecialStats.indexOf(special[0]) == 3 ? spells[2] : spells[powderSpecialStats.indexOf(special[0])]);
|
||||||
let part = spell["parts"][0];
|
let part = spell["parts"][0];
|
||||||
let _results = calculateSpellDamage(stats, part.conversion,
|
|
||||||
stats.get("mdRaw"), stats.get("mdPct"),
|
let tmp_conv = [];
|
||||||
0, weapon, skillpoints, stats.get('damageMultiplier') * ((part.multiplier[power-1] / 100)));//part.multiplier[power] / 100
|
for (let i in part.conversion) {
|
||||||
|
tmp_conv.push(part.conversion[i] * part.multiplier[power-1]);
|
||||||
|
}
|
||||||
|
let _results = calculateSpellDamage(stats, weapon, tmp_conv, false);
|
||||||
|
|
||||||
let critChance = skillPointsToPercentage(skillpoints[1]);
|
let critChance = skillPointsToPercentage(skillpoints[1]);
|
||||||
let save_damages = [];
|
let save_damages = [];
|
||||||
|
|
|
@ -39,9 +39,11 @@ function optimizeStrDex() {
|
||||||
let total_damage = 0;
|
let total_damage = 0;
|
||||||
for (const part of spell_parts) {
|
for (const part of spell_parts) {
|
||||||
if (part.type === "damage") {
|
if (part.type === "damage") {
|
||||||
let _results = calculateSpellDamage(stats, part.conversion,
|
let tmp_conv = [];
|
||||||
stats.get("sdRaw"), stats.get("sdPct"),
|
for (let i in part.conversion) {
|
||||||
part.multiplier / 100, player_build.weapon.statMap, total_skillpoints, 1);
|
tmp_conv.push(part.conversion[i] * part.multiplier);
|
||||||
|
}
|
||||||
|
let _results = calculateSpellDamage(stats, player_build.weapon.statMap, tmp_conv, true);
|
||||||
let totalDamNormal = _results[0];
|
let totalDamNormal = _results[0];
|
||||||
let totalDamCrit = _results[1];
|
let totalDamCrit = _results[1];
|
||||||
let results = _results[2];
|
let results = _results[2];
|
||||||
|
|
Loading…
Reference in a new issue