From 9508ab81ad03b6fd90e21c7b99d1b4fc96863d20 Mon Sep 17 00:00:00 2001 From: b Date: Sat, 9 Jan 2021 22:29:07 -0600 Subject: [PATCH] Apply set bonuses during skillpoint calculation --- build.js | 28 +++++---------- credits.txt | 2 ++ index.html | 8 ++--- skillpoints.js | 94 ++++++++++++++++++++++++++++---------------------- test.js | 8 ----- 5 files changed, 65 insertions(+), 75 deletions(-) diff --git a/build.js b/build.js index 9b0c220..78f6b95 100644 --- a/build.js +++ b/build.js @@ -133,6 +133,7 @@ class Build{ this.base_skillpoints = result[1]; this.total_skillpoints = result[2]; this.assigned_skillpoints = result[3]; + this.activeSetCounts = result[4]; // For strength boosts like warscream, vanish, etc. this.damageMultiplier = 1.0; @@ -197,29 +198,11 @@ class Build{ return damages_results.concat([totalDamNorm,totalDamCrit,normDPS,critDPS,avgDPS,adjAtkSpd]); } - /* - * Gets a list of active sets and set counts. - */ - getSetBonuses() { - let activeSetCounts = new Map() - for (const item of this.items) { - console.log(item.get("name")); - const setName = setMap.get(item.get("name")); - if (setName) { // undefined/null means no set. - activeSetCounts.set(setName, (activeSetCounts.get(setName) || 0) + 1); - } - } - return activeSetCounts; - } - /* Get all stats for this build. Stores in this.statMap. @pre The build itself should be valid. No checking of validity of pieces is done here. */ initBuildStats(){ - let activeSetCounts = this.getSetBonuses(); - this.activeSetCounts = activeSetCounts; - let staticIDs = ["hp", "eDef", "tDef", "wDef", "fDef", "aDef"]; //Create a map of this build's stats @@ -239,10 +222,15 @@ class Build{ if (item.get(staticID)) { statMap.set(staticID, statMap.get(staticID) + item.get(staticID)); } } } - for (const [setName, count] of activeSetCounts) { + for (const [setName, count] of this.activeSetCounts) { const bonus = sets[setName].bonuses[count-1]; for (const id in bonus) { - statMap.set(id,(statMap.get(id) || 0)+bonus[id]); + if (skp_order.includes(id)) { + // pass. Don't include skillpoints in ids + } + else { + statMap.set(id,(statMap.get(id) || 0)+bonus[id]); + } } } diff --git a/credits.txt b/credits.txt index 3f67f1a..e487303 100644 --- a/credits.txt +++ b/credits.txt @@ -3,3 +3,5 @@ Damage calculator checking: https://its0x7.cf/build/ Theme and overall inspiration: Wynndata (Dukio) - https://wynndata.tk +Additional Contributors: + - QuantumNep (Layout code/layout ideas) diff --git a/index.html b/index.html index 3daf1ee..ca886b3 100644 --- a/index.html +++ b/index.html @@ -250,16 +250,12 @@
-
-

Overall Build Stats:

-

-
- +
+
diff --git a/skillpoints.js b/skillpoints.js index f783807..5e02fd1 100644 --- a/skillpoints.js +++ b/skillpoints.js @@ -10,32 +10,47 @@ function calculate_skillpoints(equipment, weapon) { if (item.get("reqs").every(x => x === 0)) { fixed.push(item); } - else if (item.get("skillpoints").every(x => x === 0)) { + // TODO hack: We will treat ALL set items as unsafe :( + else if (item.get("skillpoints").every(x => x === 0) && item.get("set") === null) { noboost.push(item); } else { consider.push(item); } } - function apply_skillpoints(skillpoints, item) { + function apply_skillpoints(skillpoints, item, activeSetCounts) { for (let i = 0; i < 5; i++) { skillpoints[i] += item.get("skillpoints")[i]; } - } - function remove_skillpoints(skillpoints, item) { - for (let i = 0; i < 5; i++) { - skillpoints[i] -= item.get("skillpoints")[i]; + const setName = item.get("set"); + if (setName) { // undefined/null means no set. + let setCount = activeSetCounts.get(setName); + let old_bonus = {}; + if (setCount) { + old_bonus = sets[setName].bonuses[setCount-1]; + activeSetCounts.set(setName, setCount + 1); + } + else { + setCount = 0; + activeSetCounts.set(setName, 1); + } + const new_bonus = sets[setName].bonuses[setCount]; + //let skp_order = ["str","dex","int","def","agi"]; + for (const i in skp_order) { + const delta = (new_bonus[skp_order[i]] || 0) - (old_bonus[skp_order[i]] || 0); + skillpoints[i] += delta; + } } } // Figure out (naively) how many skillpoints need to be applied to get the current item to fit. // Doesn't handle -skp. - function apply_to_fit(skillpoints, item, skillpoint_filter) { + function apply_to_fit(skillpoints, item, skillpoint_filter, activeSetCounts) { let applied = [0, 0, 0, 0, 0]; let total = 0; for (let i = 0; i < 5; i++) { - if (item.get("skillpoints")[i] < 0 && skillpoint_filter[i] === true) { + if (item.get("skillpoints")[i] < 0 && skillpoint_filter[i]) { applied[i] -= item.get("skillpoints")[i]; total -= item.get("skillpoints")[i]; } @@ -49,24 +64,46 @@ function calculate_skillpoints(equipment, weapon) { total += diff; } } + + const setName = item.get("set"); + if (setName) { // undefined/null means no set. + const setCount = activeSetCounts.get(setName); + if (setCount) { + const old_bonus = sets[setName].bonuses[setCount-1]; + const new_bonus = sets[setName].bonuses[setCount]; + //let skp_order = ["str","dex","int","def","agi"]; + for (const i in skp_order) { + const delta = (new_bonus[skp_order[i]] || 0) - (old_bonus[skp_order[i]] || 0); + if (delta < 0 && skillpoint_filter[i]) { + applied[i] -= delta; + total -= delta; + } + } + } + } + return [applied, total]; } // Separate out the no req items and add them to the static skillpoint base. let static_skillpoints_base = [0, 0, 0, 0, 0] + let static_activeSetCounts = new Map() for (const item of fixed) { - apply_skillpoints(static_skillpoints_base, item); + apply_skillpoints(static_skillpoints_base, item, static_activeSetCounts); } let best = consider.concat(noboost); let final_skillpoints = static_skillpoints_base.slice(); let best_skillpoints = [0, 0, 0, 0, 0]; let best_total = Infinity; + let best_activeSetCounts = static_activeSetCounts; let allFalse = [false, false, false, false, false]; if (consider.length > 0 || noboost.length > 0) { // Try every combination and pick the best one. for (let permutation of perm(consider)) { + let activeSetCounts = new Map(static_activeSetCounts); + let has_skillpoint = allFalse.slice(); permutation = permutation.concat(noboost); @@ -81,7 +118,7 @@ function calculate_skillpoints(equipment, weapon) { let needed_skillpoints; let total_diff; for (const item of permutation) { - result = apply_to_fit(skillpoints, item, has_skillpoint); + result = apply_to_fit(skillpoints, item, has_skillpoint, activeSetCounts); needed_skillpoints = result[0]; total_diff = result[1]; @@ -89,40 +126,14 @@ function calculate_skillpoints(equipment, weapon) { skillpoints_applied[i] += needed_skillpoints[i]; skillpoints[i] += needed_skillpoints[i]; } - apply_skillpoints(skillpoints, item); + apply_skillpoints(skillpoints, item, activeSetCounts); total_applied += total_diff; if (total_applied >= best_total) { break; } } -// if (total_applied < best_total) { -// console.log(total_applied); -// console.log(skillpoints_applied); -// console.log("Iteration 2"); -// for (const item of permutation) { -// console.log(item); -// -// remove_skillpoints(skillpoints, item); -// console.log(skillpoints); -// result = apply_to_fit(skillpoints, item, has_skillpoint); -// needed_skillpoints = result[0]; -// total_diff = result[1]; -// for (let i = 0; i < 5; ++i) { -// skillpoints_applied[i] += needed_skillpoints[i]; -// skillpoints[i] += needed_skillpoints[i]; -// } -// -// apply_skillpoints(skillpoints, item); -// console.log(skillpoints); -// console.log(total_diff); -// total_applied += total_diff; -// if (total_applied >= best_total) { -// break; -// } -// } -// } let pre = skillpoints.slice(); - result = apply_to_fit(skillpoints, weapon, allFalse.slice()); + result = apply_to_fit(skillpoints, weapon, allFalse.slice(), activeSetCounts); needed_skillpoints = result[0]; total_diff = result[1]; for (let i = 0; i < 5; ++i) { @@ -130,7 +141,7 @@ function calculate_skillpoints(equipment, weapon) { skillpoints[i] += needed_skillpoints[i]; } - apply_skillpoints(skillpoints, weapon); + apply_skillpoints(skillpoints, weapon, activeSetCounts); total_applied += total_diff; if (total_applied < best_total) { @@ -140,13 +151,14 @@ function calculate_skillpoints(equipment, weapon) { final_skillpoints = skillpoints; best_skillpoints = skillpoints_applied; best_total = total_applied; + best_activeSetCounts = activeSetCounts; } } } else { best_total = 0; - result = apply_to_fit(final_skillpoints, weapon, allFalse.slice()); + result = apply_to_fit(final_skillpoints, weapon, allFalse.slice(), best_activeSetCounts); needed_skillpoints = result[0]; total_diff = result[1]; for (let i = 0; i < 5; ++i) { @@ -157,5 +169,5 @@ function calculate_skillpoints(equipment, weapon) { best_total += total_diff; } let equip_order = fixed.concat(best); - return [equip_order, best_skillpoints, final_skillpoints, best_total]; + return [equip_order, best_skillpoints, final_skillpoints, best_total, best_activeSetCounts]; } diff --git a/test.js b/test.js index 41a30e0..adfb316 100644 --- a/test.js +++ b/test.js @@ -97,7 +97,6 @@ for (const it of itemTypes) { } let itemMap = new Map(); /* Mapping from item names to set names. */ -let setMap = new Map(); let idMap = new Map(); /* @@ -161,13 +160,6 @@ function init() { itemMap.set(item.displayName, item); idMap.set(item.id, item.displayName); } - - for (const setName in sets) { - const set = sets[setName]; - for (const itemName of set.items) { - setMap.set(itemName, setName); - } - } for (const armorType of armorTypes) { populateItemList(armorType);