From aa29998340191d66e8d358750431aaea23a67f01 Mon Sep 17 00:00:00 2001 From: b Date: Fri, 8 Jan 2021 18:56:07 -0600 Subject: [PATCH] Adding powdering and general spell calc framework --- build.js | 83 +++++++++++++++--------------------------------- damage_calc.js | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++ display.js | 24 +++++++++++--- index.html | 38 ++++++++++++---------- skillpoints.js | 18 +++++------ test.js | 62 +++++++++++++++++++++--------------- 6 files changed, 196 insertions(+), 114 deletions(-) create mode 100644 damage_calc.js diff --git a/build.js b/build.js index 11416cd..cb87ae8 100644 --- a/build.js +++ b/build.js @@ -55,50 +55,50 @@ class Build{ if(helmet.type.valueOf() != "helmet".valueOf()){ throw new TypeError("No such helmet named ", helmet.name); }else{ - this.helmet = helmet; this.powders[0] = this.powders[0].slice(0,helmet.slots); + this.helmet = expandItem(helmet, this.powders[0]); } if(chestplate.type.valueOf() != "chestplate"){ throw new TypeError("No such chestplate named ", chestplate.name); }else{ - this.chestplate = chestplate; this.powders[1] = this.powders[1].slice(0,chestplate.slots); + this.chestplate = expandItem(chestplate, this.powders[1]); } if(leggings.type.valueOf() != "leggings"){ throw new TypeError("No such leggings named ", leggings.name); }else{ - this.leggings = leggings; this.powders[2] = this.powders[2].slice(0,leggings.slots); + this.leggings = expandItem(leggings, this.powders[2]); } if(boots.type.valueOf() != "boots"){ throw new TypeError("No such boots named ", boots.name); }else{ - this.boots = boots; this.powders[3] = this.powders[3].slice(0,boots.slots); + this.boots = expandItem(boots, this.powders[3]); } if(ring1.type.valueOf() != "ring"){ throw new TypeError("No such ring named ", ring1.name); }else{ - this.ring1 = ring1; + this.ring1 = expandItem(ring1, []); } if(ring2.type.valueOf() != "ring"){ throw new TypeError("No such ring named ", ring2.name); }else{ - this.ring2 = ring2; + this.ring2 = expandItem(ring2, []); } if(bracelet.type.valueOf() != "bracelet"){ throw new TypeError("No such bracelet named ", bracelet.name); }else{ - this.bracelet = bracelet; + this.bracelet = expandItem(bracelet, []); } if(necklace.type.valueOf() != "necklace"){ throw new TypeError("No such necklace named ", necklace.name); }else{ - this.necklace = necklace; + this.necklace = expandItem(necklace, []); } if(weapon.type.valueOf() == "wand" || weapon.type.valueOf() == "bow" || weapon.type.valueOf() == "dagger" || weapon.type.valueOf() == "spear" || weapon.type.valueOf() == "relik"){ - this.weapon = weapon; this.powders[4] = this.powders[4].slice(0,weapon.slots); + this.weapon = expandItem(weapon, this.powders[4]); }else{ throw new TypeError("No such weapon named ", weapon.name); } @@ -110,17 +110,17 @@ class Build{ this.level = level; } this.availableSkillpoints = levelToSkillPoints(this.level); - this.equipment = [ helmet, chestplate, leggings, boots, ring1, ring2, bracelet, necklace ]; - this.items = this.equipment.concat([weapon]); + 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, weapon); + let result = calculate_skillpoints(this.equipment, this.weapon); this.equip_order = result[0]; this.base_skillpoints = result[1]; this.total_skillpoints = result[2]; this.assigned_skillpoints = result[3]; // For strength boosts like warscream, vanish, etc. - this.damage_multiplier = 1.0; + this.damageMultiplier = 1.0; this.initBuildStats(); } @@ -128,7 +128,7 @@ class Build{ /*Returns build in string format */ toString(){ - return this.helmet.name + ", " + this.chestplate.name + ", " + this.leggings.name + ", " + this.boots.name + ", " + this.ring1.name + ", " + this.ring2.name + ", " + this.bracelet.name + ", " + this.necklace.name + ", " + this.weapon.name; + return this.helmet.get("name") + ", " + this.chestplate.get("name") + ", " + this.leggings.get("name") + ", " + this.boots.get("name") + ", " + this.ring1.get("name") + ", " + this.ring2.get("name") + ", " + this.bracelet.get("name") + ", " + this.necklace.get("name") + ", " + this.weapon.get("name"); } /* Getters */ @@ -147,67 +147,37 @@ class Build{ return health; } } + + /* Get melee stats for build. Returns an array in the order: */ getMeleeStats(){ const stats = this.statMap; - // Array of neutral + ewtfa damages. Each entry is a pair (min, max). - let damages = []; - for (const damage_string of stats.get("damageRaw")) { - const damage_vals = damage_string.split("-").map(Number); - damages.push(damage_vals); - } - let mdRaw = stats.get("mdRaw"); - - let mdPct = stats.get("mdPct"); - let adjAtkSpd = attackSpeeds.indexOf(stats.get("atkSpd")) + stats.get("atkTier"); if(adjAtkSpd > 6){ adjAtkSpd = 6; }else if(adjAtkSpd < 0){ adjAtkSpd = 0; } - let poison = stats.get("poison"); - let totalDamNorm = [mdRaw, mdRaw]; - let totalDamCrit = [mdRaw, mdRaw]; - let damages_results = []; - // 0th skillpoint is strength, 1st is dex. - let str = this.total_skillpoints[0]; + // 0 for melee damage. + let results = calculateSpellDamage(stats, [100, 0, 0, 0, 0, 0], stats.get("mdRaw"), stats.get("mdPct"), 0, this.weapon, this.damageMultiplier, this.total_skillpoints); + let totalDamNorm = results[0]; + let totalDamCrit = results[1]; + let damages_results = results[2]; + let dex = this.total_skillpoints[1]; - let staticBoost = (mdPct / 100.) + skillPointsToPercentage(str); - let skillBoost = [0]; - for (let i in this.total_skillpoints) { - skillBoost.push(skillPointsToPercentage(this.total_skillpoints[i]) + stats.get("damageBonus")[i] / 100.); - } - for (let i in damages) { - let damageBoost = 1 + skillBoost[i] + staticBoost; - damages_results.push([ - Math.max(damages[i][0] * damageBoost * this.damage_multiplier, 0), // Normal min - Math.max(damages[i][1] * damageBoost * this.damage_multiplier, 0), // Normal max - Math.max(damages[i][0] * (1 + damageBoost) * this.damage_multiplier, 0), // Crit min - Math.max(damages[i][1] * (1 + damageBoost) * this.damage_multiplier, 0), // Crit max - ]); - totalDamNorm[0] += damages_results[i][0]; - totalDamNorm[1] += damages_results[i][1]; - totalDamCrit[0] += damages_results[i][2]; - totalDamCrit[1] += damages_results[i][3]; - } - for (let i in damages_results[0]) { - damages_results[0][i] += mdRaw * this.damage_multiplier; - } //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))) + (poison / 3.0 * (1 + skillPointsToPercentage(str))); + let avgDPS = (normDPS * (1 - skillPointsToPercentage(dex))) + (critDPS * (skillPointsToPercentage(dex))); //console.log([nDamAdj,eDamAdj,tDamAdj,wDamAdj,fDamAdj,aDamAdj,totalDamNorm,totalDamCrit,normDPS,critDPS,avgDPS]); return damages_results.concat([totalDamNorm,totalDamCrit,normDPS,critDPS,avgDPS,adjAtkSpd]); } /* Get all stats for this build. Stores in this.statMap. - @dep test.js.expandItem() @pre The build itself should be valid. No checking of validity of pieces is done here. */ initBuildStats(){ @@ -223,8 +193,7 @@ class Build{ } statMap.set("hp", levelToHPBase(this.level)); //TODO: Add player base health - for (const _item of this.items){ - let item = expandItem(_item); + for (const item of this.items){ for (let [id, value] of item.get("maxRolls")) { statMap.set(id,(statMap.get(id) || 0)+value); } @@ -234,8 +203,8 @@ class Build{ } // The stuff relevant for damage calculation!!! @ferricles - statMap.set("atkSpd", this.weapon["atkSpd"]); - statMap.set("damageRaw", [this.weapon["nDam"], this.weapon["eDam"], this.weapon["tDam"], this.weapon["wDam"], this.weapon["fDam"], this.weapon["aDam"]]); + statMap.set("atkSpd", this.weapon.get("atkSpd")); + 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("eDam"), statMap.get("tDef"), statMap.get("wDef"), statMap.get("fDef"), statMap.get("aDef")]); statMap.set("defBonus", [statMap.get("eDamPct"), statMap.get("tDefPct"), statMap.get("wDefPct"), statMap.get("fDefPct"), statMap.get("aDefPct")]); diff --git a/damage_calc.js b/damage_calc.js new file mode 100644 index 0000000..18f6958 --- /dev/null +++ b/damage_calc.js @@ -0,0 +1,85 @@ +// 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, damageMultiplier, total_skillpoints) { + // Array of neutral + ewtfa damages. Each entry is a pair (min, max). + let damages = []; + for (const damage_string of stats.get("damageRaw")) { + const damage_vals = damage_string.split("-").map(Number); + damages.push(damage_vals); + } + + // Applying powder. + let neutralRemaining = spellConversions[0]; + let neutralBase = damages[0].slice(); + let neutralRemainingRaw = damages[0]; + 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(damages[i+1][0] + min_diff); + damages[i+1][1] = Math.floor(damages[i+1][1] + max_diff); + neutralRemainingRaw[0] = Math.floor(neutralRemainingRaw[0] - min_diff); + neutralRemainingRaw[1] = Math.floor(neutralRemainingRaw[1] - max_diff); + } + let rawBoosts = [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]]; + for (const powderID of weapon.get("powders")) { + const powder = powderStats[powderID]; + // Bitwise to force conversion to integer (integer division). + const element = (powderID/6) | 0; + let conversionRatio = powder.convert/100; + if (neutralRemainingRaw[0] > 0) { + let min_diff = Math.min(neutralRemainingRaw[0], conversionRatio * neutralBase[0]); + let max_diff = Math.min(neutralRemainingRaw[1], conversionRatio * neutralBase[1]); + damages[element+1][0] = Math.floor(damages[element+1][0] + min_diff); + damages[element+1][1] = Math.floor(damages[element+1][1] + max_diff); + neutralRemainingRaw[0] = Math.floor(neutralRemainingRaw[0] - min_diff); + neutralRemainingRaw[1] = Math.floor(neutralRemainingRaw[1] - max_diff); + } + damages[element+1][0] += powder.min; + damages[element+1][1] += powder.max; + } + damages[0][0] *= neutralRemaining / 100; + damages[0][1] *= neutralRemaining / 100; + console.log(damages); + + let damageMult = damageMultiplier; + // If we are doing melee calculations: + if (spellMultiplier == 0) { + spellMultiplier = 1; + } + else { + damageMult *= spellMultiplier * baseDamageMultiplier[attackSpeeds.indexOf(stats.get("atkSpd"))]; + } + + rawModifier *= spellMultiplier; + + let totalDamNorm = [rawModifier, rawModifier]; + let totalDamCrit = [rawModifier, rawModifier]; + let damages_results = []; + // 0th skillpoint is strength, 1st is dex. + let str = total_skillpoints[0]; + let staticBoost = (pctModifier / 100.) + skillPointsToPercentage(str); + let skillBoost = [0]; + for (let i in total_skillpoints) { + skillBoost.push(skillPointsToPercentage(total_skillpoints[i]) + stats.get("damageBonus")[i] / 100.); + } + + for (let i in damages) { + let damageBoost = 1 + skillBoost[i] + staticBoost; + damages_results.push([ + Math.max(damages[i][0] * damageBoost * damageMult, 0), // Normal min + Math.max(damages[i][1] * damageBoost * damageMult, 0), // Normal max + Math.max(damages[i][0] * (1 + damageBoost) * damageMult, 0), // Crit min + Math.max(damages[i][1] * (1 + damageBoost) * damageMult, 0), // Crit max + ]); + totalDamNorm[0] += damages_results[i][0]; + totalDamNorm[1] += damages_results[i][1]; + totalDamCrit[0] += damages_results[i][2]; + totalDamCrit[1] += damages_results[i][3]; + } + for (let i in damages_results[0]) { + // Never account for attack speed. + damages_results[0][i] += rawModifier * damageMultiplier; + } + return [totalDamNorm, totalDamCrit, damages_results]; +} diff --git a/display.js b/display.js index d7f5f13..2008c7d 100644 --- a/display.js +++ b/display.js @@ -1,7 +1,7 @@ -let nonRolledIDs = ["name", "displayName", "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","str", "dex", "int", "agi", "def", "fixID", "category", "id"]; +let nonRolledIDs = ["name", "displayName", "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","str", "dex", "int", "agi", "def", "fixID", "category", "id", "skillpoints", "reqs", "nDam_", "fDam_", "wDam_", "aDam_", "tDam_", "eDam_"]; let rolledIDs = ["hprPct", "mr", "sdPct", "mdPct", "ls", "ms", "xpb", "lb", "ref", "thorns", "exploding", "spd", "atkTier", "poison", "hpBonus", "spRegen", "eSteal", "hprRaw", "sdRaw", "mdRaw", "fDamPct", "wDamPct", "aDamPct", "tDamPct", "eDamPct", "fDefPct", "wDefPct", "aDefPct", "tDefPct", "eDefPct", "spPct1", "spRaw1", "spPct2", "spRaw2", "spPct3", "spRaw3", "spPct4", "spRaw4", "rainbowRaw", "sprint", "sprintReg", "jh", "lq", "gXp", "gSpd"]; -function expandItem(item){ +function expandItem(item, powders){ let minRolls = new Map(); let maxRolls = new Map(); let expandedItem = new Map(); @@ -36,6 +36,7 @@ function expandItem(item){ } expandedItem.set("minRolls",minRolls); expandedItem.set("maxRolls",maxRolls); + expandedItem.set("powders", powders); return expandedItem; } /*An independent helper function that rounds a rolled ID to the nearest integer OR brings the roll away from 0. @@ -54,6 +55,19 @@ function displayExpandedItem(item, parent_id){ // #commands create a new element. // !elemental is some janky hack for elemental damage. // normals just display a thing. + if (item.get("category") === "weapon") { + let stats = new Map(); + stats.set("atkSpd", item.get("atkSpd")); + stats.set("damageBonus", [0, 0, 0, 0, 0]); + 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, 1, [0, 0, 0, 0, 0]); + let damages = results[2]; + let damage_keys = [ "nDam_", "eDam_", "tDam_", "wDam_", "fDam_", "aDam_" ]; + for (const i in damage_keys) { + item.set(damage_keys[i], damages[i][0]+"-"+damages[i][1]); + } + } + let display_commands = [ "#cdiv", "displayName", @@ -62,7 +76,7 @@ function displayExpandedItem(item, parent_id){ "#ldiv", "!elemental", "hp", - "nDam", "eDam", "tDam", "wDam", "fDam", "aDam", + "nDam_", "eDam_", "tDam_", "wDam_", "fDam_", "aDam_", "eDef", "tDef", "wDef", "fDef", "aDef", "!elemental", "#ldiv", @@ -101,8 +115,8 @@ function displayExpandedItem(item, parent_id){ "quest", "restrict"]; - let idPrefixes = {"displayName": "", "lvl":"Combat Level Min: ", "classReq":"Class Req: ","strReq":"Strength Min: ","dexReq":"Dexterity Min: ","intReq":"Intelligence Min: ","defReq":"Defense Min: ","agiReq":"Agility Min: ", "nDam":"Neutral Damage: ", "eDam":"Earth Damage: ", "tDam":"Thunder Damage: ", "wDam":"Water Damage: ", "fDam":"Fire Damage: ", "aDam":"Air Damage: ", "atkSpd":"Attack Speed: ", "hp":"Health : ", "eDef":"Earth Defense: ", "tDef":"Thunder Defense: ", "wDef":"Water Defense: ", "fDef":"Fire Defense: ", "aDef":"Air Defense: ", "str":"Strength: ", "dex":"Dexterity: ", "int":"Intelligence: ", "def":"Defense: ","agi":"Agility: ", "hpBonus":"Health Bonus: ", "hprRaw":"Health Regen Raw: ", "hprPct":"Health Regen %: ", "sdRaw":"Raw Spell Damage: ", "sdPct":"Spell Damage %: ", "mdRaw":"Main Attack Neutral Damage: ", "mdPct":"Main Attack Damage %: ", "mr":"Mana Regen: ", "ms":"Mana Steal: ", "ref":"Reflection: ", "ls":"Life Steal: ", "poison":"Poison: ", "thorns":"Thorns: ", "exploding":"Expoding: ", "spd":"Walk Speed Bonus: ", "atkTier":"Attack Speed Bonus: ", "eDamPct":"Earth Damage %: ", "tDamPct":"Thunder Damage %: ", "wDamPct":"Water Damage %: ", "fDamPct":"Fire Damage %: ", "aDamPct":"Air Damage %: ", "eDefPct":"Earth Defense %: ", "tDefPct":"Thunder Defense %: ", "wDefPct":"Water Defense %: ", "fDefPct":"Fire Defense %: ", "aDefPct":"Air Defense %: ", "spPct1":"1st Spell Cost %: ", "spRaw1":"1st Spell Cost Raw: ", "spPct2":"2nd Spell Cost %: ", "spRaw2":"2nd Spell Cost Raw: ", "spPct3":"3rd Spell Cost %: ", "spRaw3":"3rd Spell Cost Raw: ", "spPct4":"4th Spell Cost %: ", "spRaw4":"4th Spell Cost Raw: ", "rainbowRaw":"Rainbow Spell Damage Raw: ", "sprint":"Sprint Bonus: ", "sprintReg":"Sprint Regen Bonus: ", "jh":"Jump Height: ", "xpb":"Combat XP Bonus: ", "lb":"Loot Bonus: ", "lq":"Loot Quality: ", "spRegen":"Soul Point Regen: ", "eSteal":"Stealing: ", "gXp":"Gathering XP Bonus: ", "gSpd":"Gathering Speed Bonus: ", "slots":"Powder Slots: ", "set":"Set: ", "quest":"Quest Req: ", "restrict":""}; - let idSuffixes = {"displayName": "", "lvl":"", "classReq":"","strReq":"","dexReq":"","intReq":"","defReq":"","agiReq":"", "nDam":"", "eDam":"", "tDam":"", "wDam":"", "fDam":"", "aDam":"", "atkSpd":"", "hp":"", "eDef":"", "tDef":"", "wDef":"", "fDef":"", "aDef":"", "str":"", "dex":"", "int":"", "def":"","agi":"", "hpBonus":"", "hprRaw":"", "hprPct":"%", "sdRaw":"", "sdPct":"%", "mdRaw":"", "mdPct":"%", "mr":"/4s", "ms":"/4s", "ref":"%", "ls":"/4s", "poison":"/3s", "thorns":"%", "exploding":"%", "spd":"%", "atkTier":" tier", "eDamPct":"%", "tDamPct":"%", "wDamPct":"%", "fDamPct":"%", "aDamPct":"%", "eDefPct":"%", "tDefPct":"%", "wDefPct":"%", "fDefPct":"%", "aDefPct":"%", "spPct1":"%", "spRaw1":"", "spPct2":"%", "spRaw2":"", "spPct3":"%", "spRaw3":"", "spPct4":"%", "spRaw4":"", "rainbowRaw":"", "sprint":"%", "sprintReg":"%", "jh":"", "xpb":"%", "lb":"%", "lq":"%", "spRegen":"%", "eSteal":"%", "gXp":"%", "gSpd":"%", "slots":"", "set":" set.", "quest":"", "restrict":""}; + let idPrefixes = {"displayName": "", "lvl":"Combat Level Min: ", "classReq":"Class Req: ","strReq":"Strength Min: ","dexReq":"Dexterity Min: ","intReq":"Intelligence Min: ","defReq":"Defense Min: ","agiReq":"Agility Min: ", "nDam_":"Neutral Damage: ", "eDam_":"Earth Damage: ", "tDam_":"Thunder Damage: ", "wDam_":"Water Damage: ", "fDam_":"Fire Damage: ", "aDam_":"Air Damage: ", "atkSpd":"Attack Speed: ", "hp":"Health : ", "eDef":"Earth Defense: ", "tDef":"Thunder Defense: ", "wDef":"Water Defense: ", "fDef":"Fire Defense: ", "aDef":"Air Defense: ", "str":"Strength: ", "dex":"Dexterity: ", "int":"Intelligence: ", "def":"Defense: ","agi":"Agility: ", "hpBonus":"Health Bonus: ", "hprRaw":"Health Regen Raw: ", "hprPct":"Health Regen %: ", "sdRaw":"Raw Spell Damage: ", "sdPct":"Spell Damage %: ", "mdRaw":"Main Attack Neutral Damage: ", "mdPct":"Main Attack Damage %: ", "mr":"Mana Regen: ", "ms":"Mana Steal: ", "ref":"Reflection: ", "ls":"Life Steal: ", "poison":"Poison: ", "thorns":"Thorns: ", "exploding":"Expoding: ", "spd":"Walk Speed Bonus: ", "atkTier":"Attack Speed Bonus: ", "eDamPct":"Earth Damage %: ", "tDamPct":"Thunder Damage %: ", "wDamPct":"Water Damage %: ", "fDamPct":"Fire Damage %: ", "aDamPct":"Air Damage %: ", "eDefPct":"Earth Defense %: ", "tDefPct":"Thunder Defense %: ", "wDefPct":"Water Defense %: ", "fDefPct":"Fire Defense %: ", "aDefPct":"Air Defense %: ", "spPct1":"1st Spell Cost %: ", "spRaw1":"1st Spell Cost Raw: ", "spPct2":"2nd Spell Cost %: ", "spRaw2":"2nd Spell Cost Raw: ", "spPct3":"3rd Spell Cost %: ", "spRaw3":"3rd Spell Cost Raw: ", "spPct4":"4th Spell Cost %: ", "spRaw4":"4th Spell Cost Raw: ", "rainbowRaw":"Rainbow Spell Damage Raw: ", "sprint":"Sprint Bonus: ", "sprintReg":"Sprint Regen Bonus: ", "jh":"Jump Height: ", "xpb":"Combat XP Bonus: ", "lb":"Loot Bonus: ", "lq":"Loot Quality: ", "spRegen":"Soul Point Regen: ", "eSteal":"Stealing: ", "gXp":"Gathering XP Bonus: ", "gSpd":"Gathering Speed Bonus: ", "slots":"Powder Slots: ", "set":"Set: ", "quest":"Quest Req: ", "restrict":""}; + let idSuffixes = {"displayName": "", "lvl":"", "classReq":"","strReq":"","dexReq":"","intReq":"","defReq":"","agiReq":"", "nDam_":"", "eDam_":"", "tDam_":"", "wDam_":"", "fDam_":"", "aDam_":"", "atkSpd":"", "hp":"", "eDef":"", "tDef":"", "wDef":"", "fDef":"", "aDef":"", "str":"", "dex":"", "int":"", "def":"","agi":"", "hpBonus":"", "hprRaw":"", "hprPct":"%", "sdRaw":"", "sdPct":"%", "mdRaw":"", "mdPct":"%", "mr":"/4s", "ms":"/4s", "ref":"%", "ls":"/4s", "poison":"/3s", "thorns":"%", "exploding":"%", "spd":"%", "atkTier":" tier", "eDamPct":"%", "tDamPct":"%", "wDamPct":"%", "fDamPct":"%", "aDamPct":"%", "eDefPct":"%", "tDefPct":"%", "wDefPct":"%", "fDefPct":"%", "aDefPct":"%", "spPct1":"%", "spRaw1":"", "spPct2":"%", "spRaw2":"", "spPct3":"%", "spRaw3":"", "spPct4":"%", "spRaw4":"", "rainbowRaw":"", "sprint":"%", "sprintReg":"%", "jh":"", "xpb":"%", "lb":"%", "lq":"%", "spRegen":"%", "eSteal":"%", "gXp":"%", "gSpd":"%", "slots":"", "set":" set.", "quest":"", "restrict":""}; function apply_elemental_format(p_elem, id, suffix) { suffix = (typeof suffix !== 'undefined') ? suffix : ""; diff --git a/index.html b/index.html index a391cc7..ab62eda 100644 --- a/index.html +++ b/index.html @@ -14,8 +14,11 @@ -
-
- Before Boosts: 0 -
+
+ Before Boosts: 0 +
Original Value: 0
@@ -189,13 +192,13 @@
-
- Before Boosts: 0 -
+
+ Before Boosts: 0 +
Original Value: 0
@@ -241,6 +244,7 @@ + diff --git a/skillpoints.js b/skillpoints.js index 51a614d..e529a44 100644 --- a/skillpoints.js +++ b/skillpoints.js @@ -7,10 +7,10 @@ function calculate_skillpoints(equipment, weapon) { let noboost = []; console.log(equipment); for (const item of equipment) { - if (item.reqs.every(x => x === 0)) { + if (item.get("reqs").every(x => x === 0)) { fixed.push(item); } - else if (item.skillpoints.every(x => x === 0)) { + else if (item.get("skillpoints").every(x => x === 0)) { noboost.push(item); } else { @@ -19,13 +19,13 @@ function calculate_skillpoints(equipment, weapon) { } function apply_skillpoints(skillpoints, item) { for (let i = 0; i < 5; i++) { - skillpoints[i] += item.skillpoints[i]; + skillpoints[i] += item.get("skillpoints")[i]; } } function remove_skillpoints(skillpoints, item) { for (let i = 0; i < 5; i++) { - skillpoints[i] -= item.skillpoints[i]; + skillpoints[i] -= item.get("skillpoints")[i]; } } @@ -35,13 +35,13 @@ function calculate_skillpoints(equipment, weapon) { let applied = [0, 0, 0, 0, 0]; let total = 0; for (let i = 0; i < 5; i++) { - if (item.skillpoints[i] < 0 && skillpoint_filter[i]) { - applied[i] -= item.skillpoints[i]; - total -= item.skillpoints[i]; + if (item.get("skillpoints")[i] < 0 && skillpoint_filter[i]) { + applied[i] -= item.get("skillpoints")[i]; + total -= item.get("skillpoints")[i]; } - if (item.reqs[i] == 0) continue; + if (item.get("reqs")[i] == 0) continue; if (skillpoint_filter) skillpoint_filter[i] = true; - const req = item.reqs[i]; + const req = item.get("reqs")[i]; const cur = skillpoints[i]; if (req > cur) { const diff = req - cur; diff --git a/test.js b/test.js index f00f71c..0d741bc 100644 --- a/test.js +++ b/test.js @@ -11,7 +11,7 @@ console.log(url_tag); * END testing section */ -const BUILD_VERSION = "1.3"; +const BUILD_VERSION = "1.4"; document.getElementById("header").textContent = "Wynn build calculator "+BUILD_VERSION+" (db version "+DB_VERSION+")"; @@ -43,12 +43,23 @@ let powderInputs = [ "weapon-powder", ]; // Ordering: [dmgMin, dmgMax, convert, defPlus, defMinus (+6 mod 5)] +class Powder { + constructor(min, max, convert, defPlus, defMinus) { + this.min = min; + this.max = max; + this.convert = convert; + this.defPlus = defPlus; + this.defMinus = defMinus; + } +} +function _p(a,b,c,d,e) { return new Powder(a,b,c,d,e); } + let powderStats = [ - [3,6,17,2,1], [6,9,21,4,2], [8,14,25,8,3], [11,16,31,14,5], [15,18,38,22,9], [18,22,46,30,13], - [1,8,9,3,1], [1,13,11,5,1], [2,18,14,9,2], [3,24,17,14,4], [3,32,22,20,7], [5,40,28,28,10], - [3,4,13,3,1], [4,7,15,6,1], [6,10,17,11,2], [8,12,21,18,4], [11,14,26,28,7], [13,17,32,40,10], - [2,5,14,3,1], [4,8,16,5,2], [6,10,19,9,3], [9,13,24,16,5], [12,16,30,25,9], [15,19,37,36,13], - [2,6,11,3,1], [4,9,14,6,2], [7,10,17,10,3], [9,13,22,16,5], [13,18,28,24,9], [16,18,35,34,13] + _p(3,6,17,2,1), _p(6,9,21,4,2), _p(8,14,25,8,3), _p(11,16,31,14,5), _p(15,18,38,22,9), _p(18,22,46,30,13), + _p(1,8,9,3,1), _p(1,13,11,5,1), _p(2,18,14,9,2), _p(3,24,17,14,4), _p(3,32,22,20,7), _p(5,40,28,28,10), + _p(3,4,13,3,1), _p(4,7,15,6,1), _p(6,10,17,11,2), _p(8,12,21,18,4), _p(11,14,26,28,7), _p(13,17,32,40,10), + _p(2,5,14,3,1), _p(4,8,16,5,2), _p(6,10,19,9,3), _p(9,13,24,16,5), _p(12,16,30,25,9), _p(15,19,37,36,13), + _p(2,6,11,3,1), _p(4,9,14,6,2), _p(7,10,17,10,3), _p(9,13,22,16,5), _p(13,18,28,24,9), _p(16,18,35,34,13) ]; let itemTypes = armorTypes.concat(accessoryTypes).concat(weaponTypes); @@ -262,15 +273,15 @@ function encodeBuild() { // Base64.fromIntN(player_build.bracelet.id, 3) + // Base64.fromIntN(player_build.necklace.id, 3) + // Base64.fromIntN(player_build.weapon.id, 3); - let build_string = "1_" + Base64.fromIntN(player_build.helmet.id, 3) + - Base64.fromIntN(player_build.chestplate.id, 3) + - Base64.fromIntN(player_build.leggings.id, 3) + - Base64.fromIntN(player_build.boots.id, 3) + - Base64.fromIntN(player_build.ring1.id, 3) + - Base64.fromIntN(player_build.ring2.id, 3) + - Base64.fromIntN(player_build.bracelet.id, 3) + - Base64.fromIntN(player_build.necklace.id, 3) + - Base64.fromIntN(player_build.weapon.id, 3); + let build_string = "1_" + Base64.fromIntN(player_build.helmet.get("id"), 3) + + Base64.fromIntN(player_build.chestplate.get("id"), 3) + + Base64.fromIntN(player_build.leggings.get("id"), 3) + + Base64.fromIntN(player_build.boots.get("id"), 3) + + Base64.fromIntN(player_build.ring1.get("id"), 3) + + Base64.fromIntN(player_build.ring2.get("id"), 3) + + Base64.fromIntN(player_build.bracelet.get("id"), 3) + + Base64.fromIntN(player_build.necklace.get("id"), 3) + + Base64.fromIntN(player_build.weapon.get("id"), 3); for (const _powderset of player_build.powders) { let n_bits = Math.ceil(_powderset.length / 6); @@ -363,7 +374,7 @@ function calculateBuild(){ let equip_order_text = "Equip order:
"; for (const item of player_build.equip_order) { - equip_order_text += item.displayName + "
"; + equip_order_text += item.get("displayName") + "
"; } setHTML("build-order", equip_order_text); @@ -382,22 +393,21 @@ function calculateBuild(){ } setText(skp_order[i] + "-skp-pct", (skillPointsToPercentage(skillpoints[i])*100).toFixed(1).concat(skp_effects[i])); } - console.log(skillpoints); if(player_build.assigned_skillpoints > levelToSkillPoints(player_build.level)){ setHTML("summary-box", "Summary: Assigned "+player_build.assigned_skillpoints+" skillpoints.
" + "WARNING: Too many skillpoints need to be assigned!
For level " + player_build.level + ", there are only " + levelToSkillPoints(player_build.level) + " skill points available."); }else{ setText("summary-box", "Summary: Assigned "+player_build.assigned_skillpoints+" skillpoints."); } - displayExpandedItem(expandItem(player_build.helmet), "build-helmet"); - displayExpandedItem(expandItem(player_build.chestplate), "build-chestplate"); - displayExpandedItem(expandItem(player_build.leggings), "build-leggings"); - displayExpandedItem(expandItem(player_build.boots), "build-boots"); - displayExpandedItem(expandItem(player_build.ring1), "build-ring1"); - displayExpandedItem(expandItem(player_build.ring2), "build-ring2"); - displayExpandedItem(expandItem(player_build.bracelet), "build-bracelet"); - displayExpandedItem(expandItem(player_build.necklace), "build-necklace"); - displayExpandedItem(expandItem(player_build.weapon), "build-weapon"); + displayExpandedItem(player_build.helmet, "build-helmet"); + displayExpandedItem(player_build.chestplate, "build-chestplate"); + displayExpandedItem(player_build.leggings, "build-leggings"); + displayExpandedItem(player_build.boots, "build-boots"); + displayExpandedItem(player_build.ring1, "build-ring1"); + displayExpandedItem(player_build.ring2, "build-ring2"); + displayExpandedItem(player_build.bracelet, "build-bracelet"); + displayExpandedItem(player_build.necklace, "build-necklace"); + displayExpandedItem(player_build.weapon, "build-weapon"); calculateBuildStats(); }