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 @@
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);