strdex optimizer button, also code cleanup episode -1

This commit is contained in:
b 2021-07-27 03:04:12 -07:00
parent d27a025b8e
commit 8689ee60ec
10 changed files with 195 additions and 132 deletions

View file

@ -115,7 +115,6 @@ class Build{
this.helmet = expandItem(helmet, this.powders[0]); this.helmet = expandItem(helmet, this.powders[0]);
} else { } else {
try { 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); let helmet = getCustomFromHash(equipment[0]) ? getCustomFromHash(equipment[0]) : (getCraftFromHash(equipment[0]) ? getCraftFromHash(equipment[0]) : undefined);
if (helmet.statMap.get("type") !== "helmet") { if (helmet.statMap.get("type") !== "helmet") {
throw new Error("Not a helmet"); throw new Error("Not a helmet");
@ -131,7 +130,6 @@ class Build{
} }
} catch (Error) { } catch (Error) {
//console.log(Error); //fix
const helmet = itemMap.get("No Helmet"); const helmet = itemMap.get("No Helmet");
this.powders[0] = this.powders[0].slice(0,helmet.slots); this.powders[0] = this.powders[0].slice(0,helmet.slots);
this.helmet = expandItem(helmet, this.powders[0]); this.helmet = expandItem(helmet, this.powders[0]);
@ -357,8 +355,11 @@ class Build{
let result = calculate_skillpoints(this.equipment, this.weapon); let result = calculate_skillpoints(this.equipment, this.weapon);
console.log(result); console.log(result);
this.equip_order = result[0]; this.equip_order = result[0];
// How many skillpoints the player had to assign (5 number)
this.base_skillpoints = result[1]; this.base_skillpoints = result[1];
// How many skillpoints the build ended up with (5 number)
this.total_skillpoints = result[2]; this.total_skillpoints = result[2];
// How many skillpoints assigned (1 number, sum of base_skillpoints)
this.assigned_skillpoints = result[3]; this.assigned_skillpoints = result[3];
this.activeSetCounts = result[4]; this.activeSetCounts = result[4];

View file

@ -42,15 +42,15 @@ function levelToHPBase(level){
} }
} }
let skp_order = ["str","dex","int","def","agi"]; const skp_order = ["str","dex","int","def","agi"];
let skill = ["Strength", "Dexterity", "Intelligence", "Defense", "Agility"]; const skill = ["Strength", "Dexterity", "Intelligence", "Defense", "Agility"];
let skp_elements = ["e","t","w","f","a"]; const skp_elements = ["e","t","w","f","a"];
let damageClasses = ["Neutral","Earth","Thunder","Water","Fire","Air"]; const damageClasses = ["Neutral","Earth","Thunder","Water","Fire","Air"];
// Set up item lists for quick access later. // Set up item lists for quick access later.
let armorTypes = [ "helmet", "chestplate", "leggings", "boots" ]; const armorTypes = [ "helmet", "chestplate", "leggings", "boots" ];
let accessoryTypes = [ "ring", "bracelet", "necklace" ]; const accessoryTypes = [ "ring", "bracelet", "necklace" ];
let weaponTypes = [ "wand", "spear", "bow", "dagger", "relik" ]; const weaponTypes = [ "wand", "spear", "bow", "dagger", "relik" ];
let consumableTypes = [ "potion", "scroll", "food"]; const consumableTypes = [ "potion", "scroll", "food"];
const attackSpeeds = ["SUPER_SLOW", "VERY_SLOW", "SLOW", "NORMAL", "FAST", "VERY_FAST", "SUPER_FAST"]; const attackSpeeds = ["SUPER_SLOW", "VERY_SLOW", "SLOW", "NORMAL", "FAST", "VERY_FAST", "SUPER_FAST"];
const baseDamageMultiplier = [ 0.51, 0.83, 1.5, 2.05, 2.5, 3.1, 4.3 ]; const baseDamageMultiplier = [ 0.51, 0.83, 1.5, 2.05, 2.5, 3.1, 4.3 ];
//0.51, 0.82, 1.50, 2.05, 2.50, 3.11, 4.27 //0.51, 0.82, 1.50, 2.05, 2.50, 3.11, 4.27

View file

@ -506,45 +506,49 @@ function calculateBuild(save_skp, skp){
} }
catch (error) { catch (error) {
if (error instanceof ListError) { handleBuilderError(error);
for (let i of error.errors) { }
if (i instanceof ItemNotFound) { }
i.element.textContent = i.message;
} else if (i instanceof IncorrectInput) { function handleBuilderError(error) {
if (document.getElementById(i.id) !== null) { if (error instanceof ListError) {
document.getElementById(i.id).parentElement.querySelectorAll("p.error")[0].textContent = i.message; for (let i of error.errors) {
} if (i instanceof ItemNotFound) {
} else { i.element.textContent = i.message;
let msg = i.stack; } else if (i instanceof IncorrectInput) {
let lines = msg.split("\n"); if (document.getElementById(i.id) !== null) {
let header = document.getElementById("header"); document.getElementById(i.id).parentElement.querySelectorAll("p.error")[0].textContent = i.message;
header.textContent = "";
for (const line of lines) {
let p = document.createElement("p");
p.classList.add("itemp");
p.textContent = line;
header.appendChild(p);
}
let p2 = document.createElement("p");
p2.textContent = "If you believe this is an error, contact hppeng on forums or discord.";
header.appendChild(p2);
} }
} else {
let msg = i.stack;
let lines = msg.split("\n");
let header = document.getElementById("header");
header.textContent = "";
for (const line of lines) {
let p = document.createElement("p");
p.classList.add("itemp");
p.textContent = line;
header.appendChild(p);
}
let p2 = document.createElement("p");
p2.textContent = "If you believe this is an error, contact hppeng on forums or discord.";
header.appendChild(p2);
} }
} else {
let msg = error.stack;
let lines = msg.split("\n");
let header = document.getElementById("header");
header.textContent = "";
for (const line of lines) {
let p = document.createElement("p");
p.classList.add("itemp");
p.textContent = line;
header.appendChild(p);
}
let p2 = document.createElement("p");
p2.textContent = "If you believe this is an error, contact hppeng on forums or discord.";
header.appendChild(p2);
} }
} else {
let msg = error.stack;
let lines = msg.split("\n");
let header = document.getElementById("header");
header.textContent = "";
for (const line of lines) {
let p = document.createElement("p");
p.classList.add("itemp");
p.textContent = line;
header.appendChild(p);
}
let p2 = document.createElement("p");
p2.textContent = "If you believe this is an error, contact hppeng on forums or discord.";
header.appendChild(p2);
} }
} }
@ -762,30 +766,7 @@ function calculateBuildStats() {
let summarybox = document.getElementById("summary-box"); let summarybox = document.getElementById("summary-box");
summarybox.textContent = ""; summarybox.textContent = "";
let skpRow = document.createElement("p"); let skpRow = document.createElement("p");
//skpRow.classList.add("left");
let td = document.createElement("p"); let td = document.createElement("p");
//td.classList.add("left");
/* let skpSummary = document.createElement("b");
skpSummary.textContent = "Assigned " + player_build.assigned_skillpoints + " skillpoints. Total: (";
//skpSummary.classList.add("itemp");
td.appendChild(skpSummary);
for (let i = 0; i < skp_order.length; i++){
let skp = document.createElement("b");
let boost = document.createElement("b");
skp.classList.add(damageClasses[i+1]);
boost.textContent = player_build.total_skillpoints[i];
if (i < 4) {
boost.classList.add("space");
}
td.appendChild(skp);
td.appendChild(boost);
}
let skpEnd = document.createElement("b");
skpEnd.textContent = ")";
td.appendChild(skpEnd);
skpRow.append(td); */
let remainingSkp = document.createElement("p"); let remainingSkp = document.createElement("p");
remainingSkp.classList.add("center"); remainingSkp.classList.add("center");
@ -934,6 +915,103 @@ function toggleID() {
} }
} }
function optimizeStrDex() {
const remaining = levelToSkillPoints(player_build.level) - player_build.assigned_skillpoints;
const base_skillpoints = player_build.base_skillpoints;
const max_str_boost = 100 - base_skillpoints[0];
const max_dex_boost = 100 - base_skillpoints[1];
const base_total_skillpoints = player_build.total_skillpoints;
let str_bonus = remaining;
let dex_bonus = 0;
let best_skillpoints = player_build.total_skillpoints;
let best_damage = 0;
for (let i = 0; i <= remaining; ++i) {
let total_skillpoints = base_total_skillpoints.slice();
total_skillpoints[0] += Math.min(max_str_boost, str_bonus);
total_skillpoints[1] += Math.min(max_dex_boost, dex_bonus);
// Calculate total 3rd spell damage
let spell = spell_table[player_build.weapon.get("type")][2];
const stats = player_build.statMap;
let critChance = skillPointsToPercentage(total_skillpoints[1]);
let save_damages = [];
let spell_parts;
if (spell.parts) {
spell_parts = spell.parts;
}
else {
spell_parts = spell.variants.DEFAULT;
for (const majorID of stats.get("activeMajorIDs")) {
if (majorID in spell.variants) {
spell_parts = spell.variants[majorID];
break;
}
}
}
let total_damage = 0;
for (const part of spell_parts) {
if (part.type === "damage") {
let _results = calculateSpellDamage(stats, part.conversion,
stats.get("sdRaw"), stats.get("sdPct") + player_build.externalStats.get("sdPct"),
part.multiplier / 100, player_build.weapon, total_skillpoints,
player_build.damageMultiplier, player_build.externalStats);
let totalDamNormal = _results[0];
let totalDamCrit = _results[1];
let results = _results[2];
let tooltipinfo = _results[3];
for (let i = 0; i < 6; ++i) {
for (let j in results[i]) {
results[i][j] = results[i][j].toFixed(2);
}
}
let nonCritAverage = (totalDamNormal[0]+totalDamNormal[1])/2 || 0;
let critAverage = (totalDamCrit[0]+totalDamCrit[1])/2 || 0;
let averageDamage = (1-critChance)*nonCritAverage+critChance*critAverage || 0;
save_damages.push(averageDamage);
if (part.summary == true) {
total_damage = averageDamage;
}
} else if (part.type === "total") {
total_damage = 0;
for (let i in part.factors) {
total_damage += save_damages[i] * part.factors[i];
}
}
} // END Calculate total 3rd spell damage (total_damage)
if (total_damage > best_damage) {
best_damage = total_damage;
best_skillpoints = total_skillpoints.slice();
}
str_bonus -= 1;
dex_bonus += 1;
}
// TODO: reduce duplicated code, @calculateBuild
let skillpoints = player_build.total_skillpoints;
let delta_total = 0;
for (let i in skp_order) {
let manual_assigned = best_skillpoints[i];
let delta = manual_assigned - skillpoints[i];
skillpoints[i] = manual_assigned;
player_build.base_skillpoints[i] += delta;
delta_total += delta;
}
player_build.assigned_skillpoints += delta_total;
try {
calculateBuildStats();
setTitle();
if (player_build.errored)
throw new ListError(player_build.errors);
}
catch (error) {
handleBuilderError(error);
}
}
// TODO: Learn and use await // TODO: Learn and use await
function init2() { function init2() {
load_ing_init(init); load_ing_init(init);

View file

@ -27915,6 +27915,7 @@
"spRaw1": -1, "spRaw1": -1,
"spRaw3": -1, "spRaw3": -1,
"spRaw4": -1, "spRaw4": -1,
"set": "Master Hive",
"id": 1249 "id": 1249
}, },
{ {

File diff suppressed because one or more lines are too long

View file

@ -101,7 +101,6 @@ function expandIngredient(ing) {
idMap.get("maxRolls").set(field, val['maximum']); idMap.get("maxRolls").set(field, val['maximum']);
} }
expandedIng.set("ids",idMap); expandedIng.set("ids",idMap);
//console.log(expandedIng);
return expandedIng; return expandedIng;
} }
@ -122,7 +121,6 @@ function expandRecipe(recipe) {
} }
} }
expandedRecipe.set("materials", [ new Map([ ["item", recipe['materials'][0]['item']], ["amount", recipe['materials'][0]['amount']] ]) , new Map([ ["item", recipe['materials'][1]['item']], ["amount",recipe['materials'][1]['amount'] ] ]) ]); expandedRecipe.set("materials", [ new Map([ ["item", recipe['materials'][0]['item']], ["amount", recipe['materials'][0]['amount']] ]) , new Map([ ["item", recipe['materials'][1]['item']], ["amount",recipe['materials'][1]['amount'] ] ]) ]);
//console.log(expandedRecipe);
return expandedRecipe; return expandedRecipe;
} }
@ -569,8 +567,7 @@ function displayExpandedItem(item, parent_id){
let numerals = new Map([[1, "I"], [2, "II"], [3, "III"], [4, "IV"], [5, "V"], [6, "VI"]]); let numerals = new Map([[1, "I"], [2, "II"], [3, "III"], [4, "IV"], [5, "V"], [6, "VI"]]);
let powderPrefix = document.createElement("b"); let powderPrefix = document.createElement("b");
powderPrefix.classList.add("powderLeft"); powderPrefix.classList.add("powderLeft"); powderPrefix.classList.add("left");
powderPrefix.classList.add("left");
powderPrefix.textContent = "Powder Slots: " + item.get(id) + " ["; powderPrefix.textContent = "Powder Slots: " + item.get(id) + " [";
p_elem.appendChild(powderPrefix); p_elem.appendChild(powderPrefix);
@ -583,8 +580,7 @@ function displayExpandedItem(item, parent_id){
} }
let powderSuffix = document.createElement("b"); let powderSuffix = document.createElement("b");
powderSuffix.classList.add("powderRight"); powderSuffix.classList.add("powderRight"); powderSuffix.classList.add("left");
powderSuffix.classList.add("left");
powderSuffix.textContent = "]"; powderSuffix.textContent = "]";
p_elem.appendChild(powderSuffix); p_elem.appendChild(powderSuffix);
active_elem.appendChild(p_elem); active_elem.appendChild(p_elem);
@ -796,12 +792,8 @@ function displayExpandedItem(item, parent_id){
let specialSuffixes = new Map([ ["Duration", " sec"], ["Radius", " blocks"], ["Chains", ""], ["Damage", "%"], ["Damage Boost", "%"], ["Knockback", " blocks"] ]); let specialSuffixes = new Map([ ["Duration", " sec"], ["Radius", " blocks"], ["Chains", ""], ["Damage", "%"], ["Damage Boost", "%"], ["Knockback", " blocks"] ]);
let specialTitle = document.createElement("p"); let specialTitle = document.createElement("p");
let specialEffects = document.createElement("p"); let specialEffects = document.createElement("p");
specialTitle.classList.add("left"); addClasses(specialTitle, ["left", "itemp", damageClasses[skp_elements.indexOf(element) + 1]]);
specialTitle.classList.add("itemp"); addClasses(specialEffects, ["left", "itemp", "nocolor"]);
specialTitle.classList.add(damageClasses[skp_elements.indexOf(element) + 1]);
specialEffects.classList.add("left");
specialEffects.classList.add("itemp");
specialEffects.classList.add("nocolor");
let effects; let effects;
if (item.get("category") === "weapon") {//weapon if (item.get("category") === "weapon") {//weapon
effects = powderSpecial["weaponSpecialEffects"]; effects = powderSpecial["weaponSpecialEffects"];
@ -810,7 +802,6 @@ function displayExpandedItem(item, parent_id){
effects = powderSpecial["armorSpecialEffects"]; effects = powderSpecial["armorSpecialEffects"];
specialTitle.textContent += powderSpecial["armorSpecialName"] + ": "; specialTitle.textContent += powderSpecial["armorSpecialName"] + ": ";
} }
// console.log(effects);
for (const [key,value] of effects.entries()) { for (const [key,value] of effects.entries()) {
if (key !== "Description") { if (key !== "Description") {
let effect = document.createElement("p"); let effect = document.createElement("p");
@ -827,11 +818,8 @@ function displayExpandedItem(item, parent_id){
specialTitle.textContent += "[ " + effects.get("Description") + " ]"; specialTitle.textContent += "[ " + effects.get("Description") + " ]";
} }
} }
//specialTitle.append(specialEffects);
powder_special.appendChild(specialTitle); powder_special.appendChild(specialTitle);
powder_special.appendChild(specialEffects); powder_special.appendChild(specialEffects);
parent_div.appendChild(powder_special); parent_div.appendChild(powder_special);
} }
} }
@ -2028,7 +2016,6 @@ function displaySpellDamage(parent_elem, overallparent_elem, build, spell, spell
third.textContent = ")"; third.textContent = ")";
title_elem.appendChild(third.cloneNode(true)); title_elem.appendChild(third.cloneNode(true));
title_elemavg.appendChild(third); title_elemavg.appendChild(third);
} }
else { else {
title_elem.textContent = spell.title; title_elem.textContent = spell.title;
@ -2112,52 +2099,32 @@ function displaySpellDamage(parent_elem, overallparent_elem, build, spell, spell
part_divavg.append(overallaverageLabel); part_divavg.append(overallaverageLabel);
} }
let nonCritLabel = document.createElement("p"); function _damage_display(label_text, average, result_idx) {
nonCritLabel.textContent = "Non-Crit Average: "+nonCritAverage.toFixed(2); let label = document.createElement("p");
nonCritLabel.classList.add("damageSubtitle"); label.textContent = label_text+average.toFixed(2);
part_div.append(nonCritLabel); label.classList.add("damageSubtitle");
part_div.append(label);
let noncritarrmin = []; let arrmin = [];
let noncritarrmax = []; let arrmax = [];
for (let i = 0; i < 6; i++){ for (let i = 0; i < 6; i++){
if (results[i][1] != 0){ if (results[i][1] != 0){
let p = document.createElement("p"); let p = document.createElement("p");
p.classList.add("damagep"); p.classList.add("damagep");
p.classList.add(damageClasses[i]); p.classList.add(damageClasses[i]);
p.textContent = results[i][0] + " \u2013 " + results[i][1]; p.textContent = results[i][result_idx] + " \u2013 " + results[i][result_idx + 1];
tooltiptext = tooltipinfo.get("damageformulas")[i].slice(0,2).join("\n"); tooltiptext = tooltipinfo.get("damageformulas")[i].slice(0,2).join("\n");
tooltip = createTooltip(tooltip, "p", tooltiptext, p, ["spell-tooltip"]); tooltip = createTooltip(tooltip, "p", tooltiptext, p, ["spell-tooltip"]);
noncritarrmin.push(results[i][0]); arrmin.push(results[i][result_idx]);
noncritarrmax.push(results[i][1]); arrmax.push(results[i][result_idx + 1]);
part_div.append(p); part_div.append(p);
}
} }
tooltiptext = ` = ((${arrmin.join(" + ")}) + (${arrmax.join(" + ")})) / 2`;
tooltip = createTooltip(tooltip, "p", tooltiptext, label, ["spell-tooltip"]);
} }
tooltiptext = ` = ((${noncritarrmin.join(" + ")}) + (${noncritarrmax.join(" + ")})) / 2`; _damage_display("Non-Crit Average: ", nonCritAverage, 0);
tooltip = createTooltip(tooltip, "p", tooltiptext, nonCritLabel, ["spell-tooltip"]); _damage_display("Crit Average: ", critAverage, 2);
//part_div.append(document.createElement("br"));
let critLabel = document.createElement("p");
critLabel.textContent = "Crit Average: "+critAverage.toFixed(2);
critLabel.classList.add("damageSubtitle");
part_div.append(critLabel);
let critarrmin = [];
let critarrmax = [];
for (let i = 0; i < 6; i++){
if (results[i][1] != 0){
let p = document.createElement("p");
p.classList.add("damagep");
p.classList.add(damageClasses[i]);
p.textContent = results[i][2]+" \u2013 "+results[i][3];
tooltiptext = tooltipinfo.get("damageformulas")[i].slice(2,4).join("\n");
tooltip = createTooltip(tooltip, "p", tooltiptext, p, ["spell-tooltip"]);
critarrmin.push(results[i][2]);
critarrmax.push(results[i][3]);
part_div.append(p);
}
}
tooltiptext = ` = ((${critarrmin.join(" + ")}) + (${critarrmax.join(" + ")})) / 2`;
tooltip = createTooltip(tooltip, "p", tooltiptext, critLabel, ["spell-tooltip"]);
save_damages.push(averageDamage); save_damages.push(averageDamage);
} else if (part.type === "heal") { } else if (part.type === "heal") {

View file

@ -267,6 +267,9 @@
<button class = "button" id = "show-id-button" onclick = "toggleID()" tabindex="23"> <button class = "button" id = "show-id-button" onclick = "toggleID()" tabindex="23">
Edit IDs Edit IDs
</button> </button>
<button class = "button" id = "optimize-strdex" onclick = "optimizeStrDex()" tabindex="24">
Optimize Str/Dex
</button>
</div> </div>
<div class="id-box fade-in" id="id-edit" style="display: none"> <div class="id-box fade-in" id="id-edit" style="display: none">
<div class="id-edit1"> <div class="id-edit1">

View file

@ -203,5 +203,8 @@ function calculate_skillpoints(equipment, weapon) {
best_total += total_diff; best_total += total_diff;
} }
let equip_order = fixed.concat(best).concat(crafted); let equip_order = fixed.concat(best).concat(crafted);
// best_skillpoints: manually assigned (before any gear)
// final_skillpoints: final totals (5 individ)
// best_total: total skillpoints assigned (number)
return [equip_order, best_skillpoints, final_skillpoints, best_total, best_activeSetCounts]; return [equip_order, best_skillpoints, final_skillpoints, best_total, best_activeSetCounts];
} }

View file

@ -363,6 +363,16 @@ function matchType(object, target) {
return object; return object;
} }
/**
* Add multiple classes to a html element
*/
function addClasses(elem, classes) {
for (let _class of classes) {
elem.classList.add(_class);
}
return elem;
}
/** A utility function that reloads the page forcefully. /** A utility function that reloads the page forcefully.
* *
*/ */