mvp armor optimizer

This commit is contained in:
Frederik Palmø 2022-03-21 20:06:45 +01:00
parent b295123b4a
commit 0a45bb25d0
10 changed files with 2455 additions and 81 deletions

View File

@ -54,21 +54,21 @@
<li>
<div>
<input type="radio" id="fast-roll" onclick="update()" name="burden">
<input type="radio" id="fast-roll" onclick="update()" name="roll-type">
<label for="fast-roll">Fast Roll (up to 30% equip load)</label>
</div>
</li>
<li>
<div>
<input type="radio" id="normal-roll" onclick="update()" name="burden" checked>
<input type="radio" id="normal-roll" onclick="update()" name="roll-type" checked>
<label for="normal-roll">Normal Roll (up to 70% equip load)</label>
</div>
</li>
<li>
<div>
<input type="radio" id="fast-roll" onclick="update()" name="burden">
<input type="radio" id="fat-roll" onclick="update()" name="roll-type">
<label for="fat-roll">Fat Roll (up to 100% equip load)</label>
</div>
</li>
@ -81,7 +81,7 @@
<li>
<div>
<input type="radio" id="greatest-average" name="sorting-order" onclick="update()">
<input type="radio" id="greatest-average" name="sorting-order" onclick="update()" disabled>
<label for="greatest-average">Greatest Average Defense</label>
</div>
</li>
@ -95,14 +95,16 @@
<li>
<div>
<input type="radio" id="greatest-elemental" name="sorting-order" onclick="update()">
<input type="radio" id="greatest-elemental" name="sorting-order" onclick="update()"
disabled>
<label for="greatest-elemental">Greatest Elemental Negation</label>
</div>
</li>
<li>
<div>
<input type="radio" id="greatest-immunities" name="sorting-order" onclick="update()">
<input type="radio" id="greatest-immunities" name="sorting-order" onclick="update()"
disabled>
<label for="greatest-immunities">Greatest Immunities</label>
</div>
</li>
@ -122,13 +124,13 @@
<li>
<div>
<input type="checkbox" id="winged-crystal-tear" onchange="update()">
<input type="checkbox" id="winged-crystal-tear" onchange="update()" disabled>
<label for="winged-crystal-tear">Winged Crystal Tear (in mixed physick)</label>
</div>
</li>
<li>
<div>
<input type="checkbox" id="fashion" onchange="update()">
<input type="checkbox" id="fashion" onchange="update()" disabled>
<label for="fashion">Fashion Mode</label>
</div>
</li>
@ -137,11 +139,13 @@
<!-- results -->
<article style="flex-basis: 60%; min-width: 300px">
<ul>
<ul id="sort-results">
<li><b>Results</b></li>
<hr>
<template id="sort-result">
<li class="sort-result">
<table>
<thead>
<tr>
@ -168,6 +172,7 @@
</tr>
</tbody>
</table>
</li>
</template>
</ul>
</article>
@ -189,28 +194,32 @@
<div class="select">
<div>
<label for="select-helmet">Helmet</label>
<select type="text" id="select-helmet" name="locked-equipment" onchange="update()">
<select type="text" id="select-helmet" name="locked-equipment" onchange="update()"
disabled>
<option value="none">None</option>
</select>
</div>
<div>
<label for="select-chestpiece">Chestpiece</label>
<select type="text" id="select-chestpiece" name="locked-equipment" onchange="update()">
<select type="text" id="select-chestpiece" name="locked-equipment" onchange="update()"
disabled>
<option value="none">None</option>
</select>
</div>
<div>
<label for="select-gauntlets">Gauntlets</label>
<select type=" text" id="select-gauntlets" name="locked-equipment" onchange="update()">
<select type=" text" id="select-gauntlets" name="locked-equipment" onchange="update()"
disabled>
<option value="none">None</option>
</select>
</div>
<div>
<label for="select-leggings">Leggings</label>
<select type="text" id="select-leggings" name="locked-equipment" onchange="update()">
<select type="text" id="select-leggings" name="locked-equipment" onchange="update()"
disabled>
<option value="none">None</option>
</select>
</div>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,443 @@
[
{
"helmet": "bull-goat-helm",
"chestpiece": "bull-goat-armor",
"gauntlets": "bull-goat-gauntlets",
"leggings": "bull-goat-greaves",
"weight": 63.0,
"poise": 100.0,
"physical": 45.0
},
{
"helmet": "bull-goat-helm",
"chestpiece": "bull-goat-armor",
"gauntlets": "omen-gauntlets",
"leggings": "bull-goat-greaves",
"weight": 61.9,
"poise": 99.0,
"physical": 44.4
},
{
"helmet": "bull-goat-helm",
"chestpiece": "bull-goat-armor",
"gauntlets": "veterans-gauntlets",
"leggings": "bull-goat-greaves",
"weight": 60.5,
"poise": 98.0,
"physical": 44.5
},
{
"helmet": "veterans-helm",
"chestpiece": "bull-goat-armor",
"gauntlets": "bull-goat-gauntlets",
"leggings": "bull-goat-greaves",
"weight": 59.8,
"poise": 97.0,
"physical": 44.3
},
{
"helmet": "veterans-helm",
"chestpiece": "bull-goat-armor",
"gauntlets": "omen-gauntlets",
"leggings": "bull-goat-greaves",
"weight": 58.7,
"poise": 96.0,
"physical": 43.7
},
{
"helmet": "veterans-helm",
"chestpiece": "bull-goat-armor",
"gauntlets": "veterans-gauntlets",
"leggings": "bull-goat-greaves",
"weight": 57.3,
"poise": 95.0,
"physical": 43.8
},
{
"helmet": "veterans-helm",
"chestpiece": "bull-goat-armor",
"gauntlets": "banished-knight-gauntlets",
"leggings": "bull-goat-greaves",
"weight": 56.8,
"poise": 93.0,
"physical": 43.8
},
{
"helmet": "crucible-tree-helm",
"chestpiece": "bull-goat-armor",
"gauntlets": "lionels-gauntlets",
"leggings": "bull-goat-greaves",
"weight": 56.6,
"poise": 92.0,
"physical": 43.2
},
{
"helmet": "jar",
"chestpiece": "bull-goat-armor",
"gauntlets": "veterans-gauntlets",
"leggings": "bull-goat-greaves",
"weight": 56.0,
"poise": 91.0,
"physical": 43.8
},
{
"helmet": "crucible-tree-helm",
"chestpiece": "bull-goat-armor",
"gauntlets": "crucible-gauntlets",
"leggings": "bull-goat-greaves",
"weight": 54.7,
"poise": 90.0,
"physical": 43.2
},
{
"helmet": "bull-goat-helm",
"chestpiece": "veterans-armor",
"gauntlets": "omen-gauntlets",
"leggings": "bull-goat-greaves",
"weight": 54.3,
"poise": 89.0,
"physical": 42.7
},
{
"helmet": "jar",
"chestpiece": "bull-goat-armor",
"gauntlets": "bull-goat-gauntlets",
"leggings": "veterans-greaves",
"weight": 53.8,
"poise": 87.0,
"physical": 43.2
},
{
"helmet": "banished-knight-helm-altered",
"chestpiece": "bull-goat-armor",
"gauntlets": "fire-prelate-gauntlets",
"leggings": "veterans-greaves",
"weight": 53.5,
"poise": 86.0,
"physical": 42.8
},
{
"helmet": "veterans-helm",
"chestpiece": "bull-goat-armor",
"gauntlets": "veterans-gauntlets",
"leggings": "radahns-greaves",
"weight": 51.7,
"poise": 84.0,
"physical": 42.7
},
{
"helmet": "jar",
"chestpiece": "bull-goat-armor",
"gauntlets": "banished-knight-gauntlets",
"leggings": "veterans-greaves",
"weight": 50.8,
"poise": 83.0,
"physical": 42.7
},
{
"helmet": "radahns-redmane-helm",
"chestpiece": "veterans-armor",
"gauntlets": "banished-knight-gauntlets",
"leggings": "bull-goat-greaves",
"weight": 48.6,
"poise": 80.0,
"physical": 42.1
},
{
"helmet": "crucible-tree-helm",
"chestpiece": "banished-knight-armor",
"gauntlets": "banished-knight-gauntlets",
"leggings": "bull-goat-greaves",
"weight": 46.3,
"poise": 71.0,
"physical": 41.8
},
{
"helmet": "jar",
"chestpiece": "banished-knight-armor-altered",
"gauntlets": "veterans-gauntlets",
"leggings": "bull-goat-greaves",
"weight": 46.0,
"poise": 69.0,
"physical": 41.9
},
{
"helmet": "jar",
"chestpiece": "veterans-armor",
"gauntlets": "banished-knight-gauntlets",
"leggings": "radahns-greaves",
"weight": 42.3,
"poise": 68.0,
"physical": 41.0
},
{
"helmet": "veterans-helm",
"chestpiece": "radahns-lion-armor-altered",
"gauntlets": "banished-knight-gauntlets",
"leggings": "veterans-greaves",
"weight": 42.0,
"poise": 64.0,
"physical": 40.8
},
{
"helmet": "jar",
"chestpiece": "banished-knight-armor-altered",
"gauntlets": "tree-sentinel-gauntlets",
"leggings": "veterans-greaves",
"weight": 41.3,
"poise": 61.0,
"physical": 40.8
},
{
"helmet": "jar",
"chestpiece": "radahns-lion-armor",
"gauntlets": "radahns-gauntlets",
"leggings": "banished-knight-greaves",
"weight": 40.9,
"poise": 59.0,
"physical": 41.0
},
{
"helmet": "jar",
"chestpiece": "crucible-tree-armor",
"gauntlets": "radahns-gauntlets",
"leggings": "banished-knight-greaves",
"weight": 38.9,
"poise": 58.0,
"physical": 40.0
},
{
"helmet": "jar",
"chestpiece": "crucible-tree-armor",
"gauntlets": "radahns-gauntlets",
"leggings": "crucible-greaves",
"weight": 37.7,
"poise": 57.0,
"physical": 39.3
},
{
"helmet": "crucible-tree-helm",
"chestpiece": "crucible-tree-armor",
"gauntlets": "chain-gauntlets",
"leggings": "crucible-greaves",
"weight": 34.6,
"poise": 55.0,
"physical": 37.2
},
{
"helmet": "crucible-tree-helm",
"chestpiece": "crucible-tree-armor",
"gauntlets": "blue-silver-bracelets",
"leggings": "crucible-greaves",
"weight": 33.8,
"poise": 53.0,
"physical": 36.6
},
{
"helmet": "marionette-soldier-birdhelm",
"chestpiece": "banished-knight-armor-altered",
"gauntlets": "malenias-gauntlet",
"leggings": "crucible-greaves",
"weight": 33.0,
"poise": 49.0,
"physical": 36.1
},
{
"helmet": "crucible-tree-helm",
"chestpiece": "crucible-tree-armor",
"gauntlets": "zamor-bracelets",
"leggings": "vagabond-knight-greaves",
"weight": 30.6,
"poise": 47.0,
"physical": 34.4
},
{
"helmet": "crucible-tree-helm",
"chestpiece": "crucible-tree-armor",
"gauntlets": "blue-silver-bracelets",
"leggings": "vagabond-knight-greaves",
"weight": 29.9,
"poise": 45.0,
"physical": 33.9
},
{
"helmet": "marionette-soldier-birdhelm",
"chestpiece": "crucible-tree-armor",
"gauntlets": "zamor-bracelets",
"leggings": "vagabond-knight-greaves",
"weight": 27.8,
"poise": 43.0,
"physical": 32.3
},
{
"helmet": "marionette-soldier-helm",
"chestpiece": "crucible-tree-armor",
"gauntlets": "blue-silver-bracelets",
"leggings": "vagabond-knight-greaves",
"weight": 27.1,
"poise": 40.0,
"physical": 31.8
},
{
"helmet": "radahn-soldier-helm",
"chestpiece": "tree-surcoat",
"gauntlets": "malenias-gauntlet",
"leggings": "crucible-greaves",
"weight": 25.9,
"poise": 39.0,
"physical": 30.7
},
{
"helmet": "jar",
"chestpiece": "blue-silver-mail-armor-altered",
"gauntlets": "blue-silver-bracelets",
"leggings": "vagabond-knight-greaves",
"weight": 23.1,
"poise": 36.0,
"physical": 28.6
},
{
"helmet": "radahn-soldier-helm",
"chestpiece": "blue-silver-mail-armor-altered",
"gauntlets": "chain-gauntlets",
"leggings": "vagabond-knight-greaves",
"weight": 21.1,
"poise": 35.0,
"physical": 27.0
},
{
"helmet": "marionette-soldier-helm",
"chestpiece": "blue-silver-mail-armor-altered",
"gauntlets": "eccentrics-manchettes",
"leggings": "vagabond-knight-greaves",
"weight": 20.9,
"poise": 34.0,
"physical": 26.8
},
{
"helmet": "fire-monk-hood",
"chestpiece": "blue-silver-mail-armor-altered",
"gauntlets": "blue-silver-bracelets",
"leggings": "vagabond-knight-greaves",
"weight": 20.3,
"poise": 32.0,
"physical": 26.4
},
{
"helmet": "marionette-soldier-helm",
"chestpiece": "blue-silver-mail-armor-altered",
"gauntlets": "lusats-manchettes",
"leggings": "vagabond-knight-greaves",
"weight": 19.1,
"poise": 31.0,
"physical": 25.2
},
{
"helmet": "aristocrat-headband",
"chestpiece": "blue-silver-mail-armor-altered",
"gauntlets": "chain-gauntlets",
"leggings": "vagabond-knight-greaves",
"weight": 18.3,
"poise": 30.0,
"physical": 24.3
},
{
"helmet": "aristocrat-headband",
"chestpiece": "blue-silver-mail-armor-altered",
"gauntlets": "blue-silver-bracelets",
"leggings": "vagabond-knight-greaves",
"weight": 17.5,
"poise": 28.0,
"physical": 23.7
},
{
"helmet": "aristocrat-headband",
"chestpiece": "blue-silver-mail-armor-altered",
"gauntlets": "gold-bracelets",
"leggings": "vagabond-knight-greaves",
"weight": 16.2,
"poise": 27.0,
"physical": 22.4
},
{
"helmet": "aristocrat-headband",
"chestpiece": "blue-silver-mail-armor-altered",
"gauntlets": "blue-silver-bracelets",
"leggings": "old-aristocrat-shoes",
"weight": 13.8,
"poise": 21.0,
"physical": 19.7
},
{
"helmet": "no-helmet",
"chestpiece": "blue-silver-mail-armor-altered",
"gauntlets": "gold-bracelets",
"leggings": "old-aristocrat-shoes",
"weight": 11.3,
"poise": 20.0,
"physical": 16.5
},
{
"helmet": "aristocrat-headband",
"chestpiece": "malenias-armor",
"gauntlets": "no-gauntlets",
"leggings": "old-aristocrat-shoes",
"weight": 10.9,
"poise": 10.0,
"physical": 16.2
},
{
"helmet": "no-helmet",
"chestpiece": "aristocrat-garb-altered",
"gauntlets": "gold-bracelets",
"leggings": "vagabond-knight-greaves",
"weight": 10.6,
"poise": 9.0,
"physical": 15.5
},
{
"helmet": "no-helmet",
"chestpiece": "malenias-armor-altered",
"gauntlets": "no-gauntlets",
"leggings": "old-aristocrat-shoes",
"weight": 8.8,
"poise": 8.0,
"physical": 13.4
},
{
"helmet": "no-helmet",
"chestpiece": "aristocrat-garb",
"gauntlets": "gold-bracelets",
"leggings": "old-aristocrat-shoes",
"weight": 7.7,
"poise": 3.0,
"physical": 12.2
},
{
"helmet": "no-helmet",
"chestpiece": "goldmasks-rags",
"gauntlets": "no-gauntlets",
"leggings": "old-aristocrat-shoes",
"weight": 4.4,
"poise": 2.0,
"physical": 7.6
},
{
"helmet": "traveling-maiden-hood",
"chestpiece": "no-chestpiece",
"gauntlets": "no-gauntlets",
"leggings": "no-leggings",
"weight": 1.6,
"poise": 1.0,
"physical": 1.4
},
{
"helmet": "no-helmet",
"chestpiece": "no-chestpiece",
"gauntlets": "no-gauntlets",
"leggings": "no-leggings",
"weight": 0.0,
"poise": 0.0,
"physical": 0.0
}
]

View File

@ -1,32 +1,27 @@
const HELMETS = fetch("/data/helmets.json")
const HELMETS = fetch("/data/armor/helmets.json")
.then(response => response.json())
.then(data => data.helmets)
.catch(error => console.log(error));
const CHESTPIECES = fetch("/data/chestpieces.json")
const CHESTPIECES = fetch("/data/armor/chestpieces.json")
.then(response => response.json())
.then(data => data.chestpieces)
.catch(error => console.log(error));
const GAUNTLETS = fetch("/data/gauntlets.json")
const GAUNTLETS = fetch("/data/armor/gauntlets.json")
.then(response => response.json())
.then(data => data.gauntlets)
.catch(error => console.log(error));
const LEGGINGS = fetch("/data/leggings.json")
const LEGGINGS = fetch("/data/armor/leggings.json")
.then(response => response.json())
.then(data => data.leggings)
.catch(error => console.log(error));
let sortedHelmets;
let sortedChestplates;
let sortedGauntlets;
let sortedLeggings;
// const SortingMethod = {
// AVERAGE,
// POISE,
// PHYSICAL,
// ELEMENTAL,
// IMMUNITIES,
// };
// armor combination lists
const PHYSICAL = fetch("/data/armor/combinations/physical.json")
.then(response => response.json())
.catch(error => console.log(error));
const POISE = fetch("/data/armor/combinations/poise.json")
.then(response => response.json())
.catch(error => console.log(error));
async function init() {
// populate filter selects
@ -35,32 +30,63 @@ async function init() {
populateSelect("locked-option", "select-gauntlets", await GAUNTLETS);
populateSelect("locked-option", "select-leggings", await LEGGINGS);
// precompute and sort list of armor pieces
}
async function update() {
// let sorted = sortedCombinations();
}
function updateSortingMethod() {
update();
}
function fitness(item, order) {
// return fitness of item based on given order
// switch (order) {
// case SortingMethod.AVERAGE:
// return item.defenses.reduce((total, value) => total + value, 0) / item.defenses.length;
// case SortingMethod.PHYSICAL:
// break;
// case SortingMethod.ELEMENTAL:
// break;
// case SortingMethod.IMMUNITIES:
// break;
// default:
// console.log("error pls fix");
// }
async function update() {
// get budget and sorting order
let budget = equipLoadBudget();
let sortBy = currentSortBy();
// find sets under budget
let best = await findUnderBudget(budget, sortBy, 3);
// show best sets under budget
Array.from(document.getElementsByClassName("sort-result")).forEach(elem => elem.parentNode.removeChild(elem));
populateResults("sort-result", "sort-results", best);
}
function clearEquipment() {
[...document.getElementsByName("locked-equipment")].forEach(select => select.selectedIndex = 0);
}
function equipLoadBudget() {
let rollType = [...document.getElementsByName("roll-type")].find(elem => elem.checked).id;
let rollModifier;
switch (rollType) {
case "fast-roll":
rollModifier = 0.3;
break;
case "normal-roll":
rollModifier = 0.7;
break;
case "fat-roll":
rollModifier = 1.0;
break;
}
return (parseInt(document.getElementById("max-equip-load").value) - parseInt(document.getElementById("current-equip-load").value)) * rollModifier;
}
function currentSortBy() {
return [...document.getElementsByName("sorting-order")].find(elem => elem.checked).id;
}
async function findUnderBudget(budget, sortBy, amount) {
let sets;
switch (sortBy) {
case "greatest-physical":
sets = (await PHYSICAL);
break;
case "greatest-poise":
sets = (await POISE);
break;
}
let first = sets.findIndex(set => set.weight <= budget);
return sets.slice(first, first + amount);
}
function populateSelect(templateId, destinationId, items) {
@ -77,6 +103,28 @@ function populateSelect(templateId, destinationId, items) {
});
}
function clearEquipment() {
[...document.getElementsByName("locked-equipment")].forEach(select => select.selectedIndex = 0);
async function populateResults(templateId, destinationId, sets) {
let helmets = await HELMETS;
let chestpieces = await CHESTPIECES;
let gauntlets = await GAUNTLETS;
let leggings = await LEGGINGS;
let template = document.getElementById(templateId);
let destination = document.getElementById(destinationId);
sets.forEach(set => {
let clone = template.content.cloneNode(true);
let li = clone.children[0];
let table = li.children[0];
let tbody = table.children[1];
let rows = tbody.children;
rows[0].children[1].innerText = helmets.find(helmet => helmet.id == set.helmet).name;
rows[1].children[1].innerText = chestpieces.find(chest => chest.id == set.chestpiece).name;
rows[2].children[1].innerText = gauntlets.find(gauntlets => gauntlets.id == set.gauntlets).name
rows[3].children[1].innerText = leggings.find(leggings => leggings.id == set.leggings).name
destination.appendChild(clone);
});
}

View File

@ -6,7 +6,7 @@ const TALISMANS = fetch("/data/talismans.json")
.then(response => response.json())
.then(data => data.talismans)
.catch(error => console.log(error));
const HELMETS = fetch("/data/helmets.json")
const HELMETS = fetch("/data/armor/helmets.json")
.then(response => response.json())
.then(data => data.helmets)
.catch(error => console.log(error));