strdex optimizer button, also code cleanup episode -1
This commit is contained in:
parent
d27a025b8e
commit
8689ee60ec
10 changed files with 195 additions and 132 deletions
5
build.js
5
build.js
|
@ -115,7 +115,6 @@ class Build{
|
|||
this.helmet = expandItem(helmet, this.powders[0]);
|
||||
} else {
|
||||
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);
|
||||
if (helmet.statMap.get("type") !== "helmet") {
|
||||
throw new Error("Not a helmet");
|
||||
|
@ -131,7 +130,6 @@ class Build{
|
|||
}
|
||||
|
||||
} catch (Error) {
|
||||
//console.log(Error); //fix
|
||||
const helmet = itemMap.get("No Helmet");
|
||||
this.powders[0] = this.powders[0].slice(0,helmet.slots);
|
||||
this.helmet = expandItem(helmet, this.powders[0]);
|
||||
|
@ -357,8 +355,11 @@ class Build{
|
|||
let result = calculate_skillpoints(this.equipment, this.weapon);
|
||||
console.log(result);
|
||||
this.equip_order = result[0];
|
||||
// How many skillpoints the player had to assign (5 number)
|
||||
this.base_skillpoints = result[1];
|
||||
// How many skillpoints the build ended up with (5 number)
|
||||
this.total_skillpoints = result[2];
|
||||
// How many skillpoints assigned (1 number, sum of base_skillpoints)
|
||||
this.assigned_skillpoints = result[3];
|
||||
this.activeSetCounts = result[4];
|
||||
|
||||
|
|
|
@ -42,15 +42,15 @@ function levelToHPBase(level){
|
|||
}
|
||||
}
|
||||
|
||||
let skp_order = ["str","dex","int","def","agi"];
|
||||
let skill = ["Strength", "Dexterity", "Intelligence", "Defense", "Agility"];
|
||||
let skp_elements = ["e","t","w","f","a"];
|
||||
let damageClasses = ["Neutral","Earth","Thunder","Water","Fire","Air"];
|
||||
const skp_order = ["str","dex","int","def","agi"];
|
||||
const skill = ["Strength", "Dexterity", "Intelligence", "Defense", "Agility"];
|
||||
const skp_elements = ["e","t","w","f","a"];
|
||||
const damageClasses = ["Neutral","Earth","Thunder","Water","Fire","Air"];
|
||||
// Set up item lists for quick access later.
|
||||
let armorTypes = [ "helmet", "chestplate", "leggings", "boots" ];
|
||||
let accessoryTypes = [ "ring", "bracelet", "necklace" ];
|
||||
let weaponTypes = [ "wand", "spear", "bow", "dagger", "relik" ];
|
||||
let consumableTypes = [ "potion", "scroll", "food"];
|
||||
const armorTypes = [ "helmet", "chestplate", "leggings", "boots" ];
|
||||
const accessoryTypes = [ "ring", "bracelet", "necklace" ];
|
||||
const weaponTypes = [ "wand", "spear", "bow", "dagger", "relik" ];
|
||||
const consumableTypes = [ "potion", "scroll", "food"];
|
||||
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 ];
|
||||
//0.51, 0.82, 1.50, 2.05, 2.50, 3.11, 4.27
|
||||
|
|
126
builder.js
126
builder.js
|
@ -506,6 +506,11 @@ function calculateBuild(save_skp, skp){
|
|||
|
||||
}
|
||||
catch (error) {
|
||||
handleBuilderError(error);
|
||||
}
|
||||
}
|
||||
|
||||
function handleBuilderError(error) {
|
||||
if (error instanceof ListError) {
|
||||
for (let i of error.errors) {
|
||||
if (i instanceof ItemNotFound) {
|
||||
|
@ -545,7 +550,6 @@ function calculateBuild(save_skp, skp){
|
|||
p2.textContent = "If you believe this is an error, contact hppeng on forums or discord.";
|
||||
header.appendChild(p2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Updates all build statistics based on (for now) the skillpoint input fields and then calculates build stats.
|
||||
|
@ -762,30 +766,7 @@ function calculateBuildStats() {
|
|||
let summarybox = document.getElementById("summary-box");
|
||||
summarybox.textContent = "";
|
||||
let skpRow = document.createElement("p");
|
||||
//skpRow.classList.add("left");
|
||||
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");
|
||||
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
|
||||
function init2() {
|
||||
load_ing_init(init);
|
||||
|
|
|
@ -27915,6 +27915,7 @@
|
|||
"spRaw1": -1,
|
||||
"spRaw3": -1,
|
||||
"spRaw4": -1,
|
||||
"set": "Master Hive",
|
||||
"id": 1249
|
||||
},
|
||||
{
|
||||
|
|
File diff suppressed because one or more lines are too long
69
display.js
69
display.js
|
@ -101,7 +101,6 @@ function expandIngredient(ing) {
|
|||
idMap.get("maxRolls").set(field, val['maximum']);
|
||||
}
|
||||
expandedIng.set("ids",idMap);
|
||||
//console.log(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'] ] ]) ]);
|
||||
//console.log(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 powderPrefix = document.createElement("b");
|
||||
powderPrefix.classList.add("powderLeft");
|
||||
powderPrefix.classList.add("left");
|
||||
powderPrefix.classList.add("powderLeft"); powderPrefix.classList.add("left");
|
||||
powderPrefix.textContent = "Powder Slots: " + item.get(id) + " [";
|
||||
p_elem.appendChild(powderPrefix);
|
||||
|
||||
|
@ -583,8 +580,7 @@ function displayExpandedItem(item, parent_id){
|
|||
}
|
||||
|
||||
let powderSuffix = document.createElement("b");
|
||||
powderSuffix.classList.add("powderRight");
|
||||
powderSuffix.classList.add("left");
|
||||
powderSuffix.classList.add("powderRight"); powderSuffix.classList.add("left");
|
||||
powderSuffix.textContent = "]";
|
||||
p_elem.appendChild(powderSuffix);
|
||||
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 specialTitle = document.createElement("p");
|
||||
let specialEffects = document.createElement("p");
|
||||
specialTitle.classList.add("left");
|
||||
specialTitle.classList.add("itemp");
|
||||
specialTitle.classList.add(damageClasses[skp_elements.indexOf(element) + 1]);
|
||||
specialEffects.classList.add("left");
|
||||
specialEffects.classList.add("itemp");
|
||||
specialEffects.classList.add("nocolor");
|
||||
addClasses(specialTitle, ["left", "itemp", damageClasses[skp_elements.indexOf(element) + 1]]);
|
||||
addClasses(specialEffects, ["left", "itemp", "nocolor"]);
|
||||
let effects;
|
||||
if (item.get("category") === "weapon") {//weapon
|
||||
effects = powderSpecial["weaponSpecialEffects"];
|
||||
|
@ -810,7 +802,6 @@ function displayExpandedItem(item, parent_id){
|
|||
effects = powderSpecial["armorSpecialEffects"];
|
||||
specialTitle.textContent += powderSpecial["armorSpecialName"] + ": ";
|
||||
}
|
||||
// console.log(effects);
|
||||
for (const [key,value] of effects.entries()) {
|
||||
if (key !== "Description") {
|
||||
let effect = document.createElement("p");
|
||||
|
@ -827,11 +818,8 @@ function displayExpandedItem(item, parent_id){
|
|||
specialTitle.textContent += "[ " + effects.get("Description") + " ]";
|
||||
}
|
||||
}
|
||||
//specialTitle.append(specialEffects);
|
||||
powder_special.appendChild(specialTitle);
|
||||
powder_special.appendChild(specialEffects);
|
||||
|
||||
|
||||
parent_div.appendChild(powder_special);
|
||||
}
|
||||
}
|
||||
|
@ -2028,7 +2016,6 @@ function displaySpellDamage(parent_elem, overallparent_elem, build, spell, spell
|
|||
third.textContent = ")";
|
||||
title_elem.appendChild(third.cloneNode(true));
|
||||
title_elemavg.appendChild(third);
|
||||
|
||||
}
|
||||
else {
|
||||
title_elem.textContent = spell.title;
|
||||
|
@ -2112,52 +2099,32 @@ function displaySpellDamage(parent_elem, overallparent_elem, build, spell, spell
|
|||
part_divavg.append(overallaverageLabel);
|
||||
}
|
||||
|
||||
let nonCritLabel = document.createElement("p");
|
||||
nonCritLabel.textContent = "Non-Crit Average: "+nonCritAverage.toFixed(2);
|
||||
nonCritLabel.classList.add("damageSubtitle");
|
||||
part_div.append(nonCritLabel);
|
||||
function _damage_display(label_text, average, result_idx) {
|
||||
let label = document.createElement("p");
|
||||
label.textContent = label_text+average.toFixed(2);
|
||||
label.classList.add("damageSubtitle");
|
||||
part_div.append(label);
|
||||
|
||||
let noncritarrmin = [];
|
||||
let noncritarrmax = [];
|
||||
let arrmin = [];
|
||||
let arrmax = [];
|
||||
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][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");
|
||||
tooltip = createTooltip(tooltip, "p", tooltiptext, p, ["spell-tooltip"]);
|
||||
noncritarrmin.push(results[i][0]);
|
||||
noncritarrmax.push(results[i][1]);
|
||||
arrmin.push(results[i][result_idx]);
|
||||
arrmax.push(results[i][result_idx + 1]);
|
||||
part_div.append(p);
|
||||
}
|
||||
}
|
||||
tooltiptext = ` = ((${noncritarrmin.join(" + ")}) + (${noncritarrmax.join(" + ")})) / 2`;
|
||||
tooltip = createTooltip(tooltip, "p", tooltiptext, nonCritLabel, ["spell-tooltip"]);
|
||||
|
||||
//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 = ` = ((${arrmin.join(" + ")}) + (${arrmax.join(" + ")})) / 2`;
|
||||
tooltip = createTooltip(tooltip, "p", tooltiptext, label, ["spell-tooltip"]);
|
||||
}
|
||||
}
|
||||
tooltiptext = ` = ((${critarrmin.join(" + ")}) + (${critarrmax.join(" + ")})) / 2`;
|
||||
tooltip = createTooltip(tooltip, "p", tooltiptext, critLabel, ["spell-tooltip"]);
|
||||
_damage_display("Non-Crit Average: ", nonCritAverage, 0);
|
||||
_damage_display("Crit Average: ", critAverage, 2);
|
||||
|
||||
save_damages.push(averageDamage);
|
||||
} else if (part.type === "heal") {
|
||||
|
|
|
@ -267,6 +267,9 @@
|
|||
<button class = "button" id = "show-id-button" onclick = "toggleID()" tabindex="23">
|
||||
Edit IDs
|
||||
</button>
|
||||
<button class = "button" id = "optimize-strdex" onclick = "optimizeStrDex()" tabindex="24">
|
||||
Optimize Str/Dex
|
||||
</button>
|
||||
</div>
|
||||
<div class="id-box fade-in" id="id-edit" style="display: none">
|
||||
<div class="id-edit1">
|
||||
|
|
|
@ -203,5 +203,8 @@ function calculate_skillpoints(equipment, weapon) {
|
|||
best_total += total_diff;
|
||||
}
|
||||
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];
|
||||
}
|
||||
|
|
10
utils.js
10
utils.js
|
@ -363,6 +363,16 @@ function matchType(object, target) {
|
|||
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.
|
||||
*
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue