updated armor sorting, it now happens in-browser
This commit is contained in:
parent
bdf333a2f1
commit
b1fdca555f
148
src/armor.html
148
src/armor.html
@ -37,13 +37,18 @@
|
|||||||
|
|
||||||
<li>
|
<li>
|
||||||
<label for="max-equip-load">Max. Equip Load</label>
|
<label for="max-equip-load">Max. Equip Load</label>
|
||||||
<input style="max-width: 50px" class="stat" id="max-equip-load" type="number" oninput="update()"
|
<input style="max-width: 50px" class="stat" id="max-equip-load" type="number"
|
||||||
min=0 step=0.1 value=30 name="equip-load">
|
oninput="update(false)" min=0 step=0.1 value=30 name="equip-load" lang="en">
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<label for="current-equip-load">Current Equip Load</label>
|
<label for="current-equip-load">Current Equip Load</label>
|
||||||
<input style="max-width: 50px" class="stat" id="current-equip-load" type="number"
|
<input style="max-width: 50px" class="stat" id="current-equip-load" type="number"
|
||||||
oninput="update()" min=0 step=0.1 value=0 name="equip-load">
|
oninput="update(false)" min=0 step=0.1 value=0 name="equip-load" lang="en">
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<label for="equip-load-budget">Equip Load Budget</label>
|
||||||
|
<input style="max-width: 50px" class="stat" id="equip-load-budget" type="number" value=0
|
||||||
|
name="equip-load" disabled>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
@ -54,21 +59,22 @@
|
|||||||
|
|
||||||
<li>
|
<li>
|
||||||
<div>
|
<div>
|
||||||
<input type="radio" id="fast-roll" onclick="update()" name="roll-type">
|
<input type="radio" id="fast-roll" onclick="update(false)" name="roll-type" value=0.3>
|
||||||
<label for="fast-roll">Fast Roll (up to 30% equip load)</label>
|
<label for="fast-roll">Fast Roll (up to 30% equip load)</label>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<div>
|
<div>
|
||||||
<input type="radio" id="normal-roll" onclick="update()" name="roll-type" checked>
|
<input type="radio" id="normal-roll" onclick="update(false)" name="roll-type" value=0.7
|
||||||
|
checked>
|
||||||
<label for="normal-roll">Normal Roll (up to 70% equip load)</label>
|
<label for="normal-roll">Normal Roll (up to 70% equip load)</label>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<div>
|
<div>
|
||||||
<input type="radio" id="fat-roll" onclick="update()" name="roll-type">
|
<input type="radio" id="fat-roll" onclick="update(false)" name="roll-type" value=1.0>
|
||||||
<label for="fat-roll">Fat Roll (up to 100% equip load)</label>
|
<label for="fat-roll">Fat Roll (up to 100% equip load)</label>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
@ -81,38 +87,36 @@
|
|||||||
|
|
||||||
<li>
|
<li>
|
||||||
<div>
|
<div>
|
||||||
<input type="radio" id="greatest-average" name="sorting-order" onclick="update()" disabled>
|
<input type="radio" id="sort-average" name="sorting-order" onclick="update(true)">
|
||||||
<label for="greatest-average">Greatest Average Defense</label>
|
<label for="sort-average">Greatest Average Negation</label>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<div>
|
<div>
|
||||||
<input type="radio" id="greatest-physical" name="sorting-order" onclick="update()" checked>
|
<input type="radio" id="sort-physical" name="sorting-order" onclick="update(true)">
|
||||||
<label for="greatest-physical">Greatest Physical Negation</label>
|
<label for="sort-physical">Greatest Physical Negation</label>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<div>
|
<div>
|
||||||
<input type="radio" id="greatest-elemental" name="sorting-order" onclick="update()"
|
<input type="radio" id="sort-elemental" name="sorting-order" onclick="update(true)" checked>
|
||||||
disabled>
|
<label for="sort-elemental">Greatest Elemental Negation</label>
|
||||||
<label for="greatest-elemental">Greatest Elemental Negation</label>
|
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<div>
|
<div>
|
||||||
<input type="radio" id="greatest-immunities" name="sorting-order" onclick="update()"
|
<input type="radio" id="sort-resistances" name="sorting-order" onclick="update(true)">
|
||||||
disabled>
|
<label for="sort-resistances">Greatest Resistances</label>
|
||||||
<label for="greatest-immunities">Greatest Immunities</label>
|
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<div>
|
<div>
|
||||||
<input type="radio" id="greatest-poise" name="sorting-order" onclick="update()">
|
<input type="radio" id="sort-poise" name="sorting-order" onclick="update(true)">
|
||||||
<label for="greatest-poise">Greatest Poise</label>
|
<label for="sort-poise">Greatest Poise</label>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@ -124,23 +128,67 @@
|
|||||||
|
|
||||||
<li>
|
<li>
|
||||||
<div>
|
<div>
|
||||||
<input type="checkbox" id="winged-crystal-tear" onchange="update()" disabled>
|
<input type="checkbox" id="winged-crystal-tear" onchange="update(false)" disabled>
|
||||||
<label for="winged-crystal-tear">Winged Crystal Tear (in mixed physick)</label>
|
<label for="winged-crystal-tear">Winged Crystal Tear (in mixed physick)</label>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<div>
|
<div>
|
||||||
<input type="checkbox" id="fashion" onchange="update()" disabled>
|
<input type="checkbox" id="fashion" onchange="update(false)" disabled>
|
||||||
<label for="fashion">Fashion Mode</label>
|
<label for="fashion">Fashion Mode</label>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<li><b>Filter</b></li>
|
||||||
|
<hr>
|
||||||
|
<li>
|
||||||
|
<b>Locked Items</b>
|
||||||
|
<button id="clear-equipment" onclick="reset()">Clear Locked Equipment</button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<template id="locked-option">
|
||||||
|
<option value="">Placeholder</option>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div class="select">
|
||||||
|
<div>
|
||||||
|
<label for="select-helmet">Helmet</label>
|
||||||
|
<select type="text" id="select-helmet" name="locked-items" onchange="update(true)">
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label for="select-chestpiece">Chestpiece</label>
|
||||||
|
<select type="text" id="select-chestpiece" name="locked-items" onchange="update(true)">
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label for="select-gauntlets">Gauntlets</label>
|
||||||
|
<select type=" text" id="select-gauntlets" name="locked-items" onchange="update(true)">
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label for="select-leggings">Leggings</label>
|
||||||
|
<select type="text" id="select-leggings" name="locked-items" onchange="update(true)">
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
<!-- results -->
|
<!-- sort -->
|
||||||
<article style="flex-basis: 60%; min-width: 300px">
|
<article style="flex-basis: 60%; min-width: 300px">
|
||||||
<ul id="sort-results">
|
<ul id="sort-results">
|
||||||
<li><b>Results</b></li>
|
<li><b>Sort</b></li>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
@ -154,6 +202,10 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>Total</td>
|
||||||
|
<td>Stats</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Helmet</td>
|
<td>Helmet</td>
|
||||||
<td>Stats</td>
|
<td>Stats</td>
|
||||||
@ -170,10 +222,6 @@
|
|||||||
<td>Leggings</td>
|
<td>Leggings</td>
|
||||||
<td>Stats</td>
|
<td>Stats</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<td>Total</td>
|
|
||||||
<td>Stats</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</li>
|
</li>
|
||||||
@ -184,54 +232,6 @@
|
|||||||
<!-- filter -->
|
<!-- filter -->
|
||||||
<article>
|
<article>
|
||||||
<ul>
|
<ul>
|
||||||
<li><b>Filter</b></li>
|
|
||||||
<hr>
|
|
||||||
<li>
|
|
||||||
<b>Locked Equipment</b>
|
|
||||||
<button id="clear-equipment" onclick="clearEquipment()">Clear Locked Equipment</button>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<template id="locked-option">
|
|
||||||
<option value="">Placeholder</option>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<div class="select">
|
|
||||||
<div>
|
|
||||||
<label for="select-helmet">Helmet</label>
|
|
||||||
<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()"
|
|
||||||
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()"
|
|
||||||
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()"
|
|
||||||
disabled>
|
|
||||||
<option value="none">None</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<b>Allowed Armor</b>
|
<b>Allowed Armor</b>
|
||||||
</li>
|
</li>
|
||||||
|
@ -11,30 +11,10 @@ const LEGGINGS = fetch("/data/armor/leggings.json")
|
|||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.catch(error => console.log(error));
|
.catch(error => console.log(error));
|
||||||
|
|
||||||
// armor combination lists
|
var helmets;
|
||||||
const PHYSICAL = fetch("/data/armor/combinations/physical.json")
|
var chestpieces;
|
||||||
.then(response => response.json())
|
var gauntlets;
|
||||||
.catch(error => console.log(error));
|
var leggings;
|
||||||
const POISE = fetch("/data/armor/combinations/poise.json")
|
|
||||||
.then(response => response.json())
|
|
||||||
.catch(error => console.log(error));
|
|
||||||
|
|
||||||
const DEFENSE = [
|
|
||||||
"phys.",
|
|
||||||
"strike",
|
|
||||||
"slash",
|
|
||||||
"pierce",
|
|
||||||
"magic",
|
|
||||||
"fire",
|
|
||||||
"light.",
|
|
||||||
"holy",
|
|
||||||
];
|
|
||||||
const RESISTANCES = [
|
|
||||||
"immunity",
|
|
||||||
"robustness",
|
|
||||||
"focus",
|
|
||||||
"vitality",
|
|
||||||
]
|
|
||||||
|
|
||||||
async function init() {
|
async function init() {
|
||||||
// populate filter selects
|
// populate filter selects
|
||||||
@ -43,73 +23,129 @@ async function init() {
|
|||||||
populateSelect("locked-option", "select-gauntlets", await GAUNTLETS);
|
populateSelect("locked-option", "select-gauntlets", await GAUNTLETS);
|
||||||
populateSelect("locked-option", "select-leggings", await LEGGINGS);
|
populateSelect("locked-option", "select-leggings", await LEGGINGS);
|
||||||
|
|
||||||
update();
|
update(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function update() {
|
async function update(resort) {
|
||||||
// clamp equip load values to reasonable values
|
// clamp equip load values to reasonable values
|
||||||
[...document.getElementsByName("equip-load")].forEach(el => el.value = Math.max(el.value, 0.0));
|
[...document.getElementsByName("equip-load")].forEach(el => el.value = Math.max(el.value, 0.0));
|
||||||
|
|
||||||
|
let sortBy = [...document.getElementsByName("sorting-order")].find(elem => elem.checked).id;
|
||||||
|
|
||||||
|
// get locked items
|
||||||
|
let lockedItems = await Promise.all([HELMETS, CHESTPIECES, GAUNTLETS, LEGGINGS])
|
||||||
|
.then(allItems => {
|
||||||
|
return [...document.getElementsByName("locked-items")]
|
||||||
|
.map(select => select.selectedIndex)
|
||||||
|
.map((itemIndex, i) => allItems[i][itemIndex])
|
||||||
|
.filter(item => !item.id.startsWith("no-"));
|
||||||
|
});
|
||||||
|
|
||||||
|
// if sort order has changed, sort equipment again
|
||||||
|
if (resort) {
|
||||||
|
// pre-sort and eliminate some equipment
|
||||||
|
helmets = eliminate(await HELMETS, sortBy, lockedItems);
|
||||||
|
chestpieces = eliminate(await CHESTPIECES, sortBy, lockedItems);
|
||||||
|
gauntlets = eliminate(await GAUNTLETS, sortBy, lockedItems);
|
||||||
|
leggings = eliminate(await LEGGINGS, sortBy, lockedItems);
|
||||||
|
}
|
||||||
|
|
||||||
// get budget and sorting order
|
// get budget and sorting order
|
||||||
let budget = equipLoadBudget();
|
let budget = equipLoadBudget();
|
||||||
let sortBy = currentSortBy();
|
document.getElementById("equip-load-budget").value = budget.toFixed(1);
|
||||||
|
|
||||||
// find sets under budget
|
// find best set under budget
|
||||||
let best = await findUnderBudget(budget, sortBy, 3);
|
let best = knapSack(budget, sortBy, lockedItems);
|
||||||
|
|
||||||
// show best sets under budget
|
// show best sets under budget
|
||||||
Array.from(document.getElementsByClassName("sort-result")).forEach(elem => elem.parentNode.removeChild(elem));
|
Array.from(document.getElementsByClassName("sort-result")).forEach(elem => elem.parentNode.removeChild(elem));
|
||||||
populateResults("sort-result", "sort-results", best);
|
populateResults("sort-result", "sort-results", best);
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearEquipment() {
|
function reset() {
|
||||||
[...document.getElementsByName("locked-equipment")].forEach(select => select.selectedIndex = 0);
|
[...document.getElementsByName("locked-items")].forEach(select => select.selectedIndex = 0);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
function eliminate(list, sortBy, lockedItems) {
|
||||||
|
if (lockedItems.some(item => list.includes(item))) {
|
||||||
|
return [list.find(item => lockedItems.includes(item))];
|
||||||
|
}
|
||||||
|
|
||||||
|
let sorted = [...list];
|
||||||
|
sorted.sort((a, b) => a.weight - b.weight);
|
||||||
|
|
||||||
|
let approved = []
|
||||||
|
|
||||||
|
sorted.forEach(item => {
|
||||||
|
if (!approved.some(other => fitness(item, sortBy) <= fitness(other, sortBy))) {
|
||||||
|
approved.push(item)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return approved;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function knapSack(budget, sortBy, lockedItems) {
|
||||||
|
let permutations = helmets.flatMap(h => {
|
||||||
|
return chestpieces.flatMap(c => {
|
||||||
|
return gauntlets.flatMap(g => {
|
||||||
|
return leggings
|
||||||
|
.filter(l => isAllowedSet([h, c, g, l], lockedItems))
|
||||||
|
.filter(l => budget > setWeight([h, c, g, l]))
|
||||||
|
.map(l => [h, c, g, l]);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
permutations.sort((a, b) => setFitness(b, sortBy) - setFitness(a, sortBy));
|
||||||
|
|
||||||
|
return permutations.slice(0, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
const average = (item) => item.defenses.reduce((total, n) => total + n, 0);
|
||||||
|
const physical = (item) => item.defenses.slice(0, 4).reduce((total, n) => total + n, 0);
|
||||||
|
const elemental = (item) => item.defenses.slice(4, 8).reduce((total, n) => total + n, 0);
|
||||||
|
const resistances = (item) => item.resistances.reduce((total, n) => total + n, 0);
|
||||||
|
const poise = (item) => item.poise;
|
||||||
|
|
||||||
|
function fitness(item, sortBy) {
|
||||||
|
switch (sortBy) {
|
||||||
|
case "sort-average":
|
||||||
|
break;
|
||||||
|
case "sort-physical":
|
||||||
|
return physical(item);
|
||||||
|
case "sort-elemental":
|
||||||
|
return elemental(item);
|
||||||
|
case "sort-resistances":
|
||||||
|
return resistances(item);
|
||||||
|
case "sort-poise":
|
||||||
|
return poise(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setWeight(set) {
|
||||||
|
return set.reduce((total, item) => total + item.weight, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setFitness(set, sortBy) {
|
||||||
|
return set.reduce((total, item) => total + fitness(item, sortBy), 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isAllowedSet(set, lockedItems) {
|
||||||
|
return lockedItems.every(item => set.includes(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
function equipLoadBudget() {
|
function equipLoadBudget() {
|
||||||
let rollType = [...document.getElementsByName("roll-type")].find(elem => elem.checked).id;
|
let rollModifier = parseFloat([...document.getElementsByName("roll-type")].find(elem => elem.checked).value);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
let max = document.getElementById("max-equip-load").value || 0;
|
let max = document.getElementById("max-equip-load").value || 0;
|
||||||
let current = document.getElementById("current-equip-load").value || 0;
|
let current = document.getElementById("current-equip-load").value || 0;
|
||||||
let budget = Math.max((max - current) * rollModifier, 0);
|
|
||||||
|
|
||||||
return budget;
|
|
||||||
|
|
||||||
|
return parseFloat(Math.max((max - current) * rollModifier, 0.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
function currentSortBy() {
|
// site rendering functions
|
||||||
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) {
|
function populateSelect(templateId, destinationId, items) {
|
||||||
let template = document.getElementById(templateId);
|
let template = document.getElementById(templateId);
|
||||||
let destination = document.getElementById(destinationId);
|
let destination = document.getElementById(destinationId);
|
||||||
@ -125,15 +161,10 @@ function populateSelect(templateId, destinationId, items) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function populateResults(templateId, destinationId, sets) {
|
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 template = document.getElementById(templateId);
|
||||||
let destination = document.getElementById(destinationId);
|
let destination = document.getElementById(destinationId);
|
||||||
|
|
||||||
sets.forEach(set => {
|
(await sets).forEach(set => {
|
||||||
let clone = template.content.cloneNode(true);
|
let clone = template.content.cloneNode(true);
|
||||||
|
|
||||||
let li = clone.children[0];
|
let li = clone.children[0];
|
||||||
@ -141,44 +172,48 @@ async function populateResults(templateId, destinationId, sets) {
|
|||||||
let tbody = table.children[1];
|
let tbody = table.children[1];
|
||||||
let rows = tbody.children;
|
let rows = tbody.children;
|
||||||
|
|
||||||
let helmet = helmets.find(helmet => helmet.id == set.helmet);
|
rows[1].children[0].innerText = set[0].name;
|
||||||
let chestpiece = chestpieces.find(chest => chest.id == set.chestpiece);
|
rows[2].children[0].innerText = set[1].name;
|
||||||
let gauntlet = gauntlets.find(gauntlets => gauntlets.id == set.gauntlets);
|
rows[3].children[0].innerText = set[2].name;
|
||||||
let legging = leggings.find(leggings => leggings.id == set.leggings);
|
rows[4].children[0].innerText = set[3].name;
|
||||||
|
|
||||||
rows[0].children[0].innerText = helmet.name;
|
rows[1].children[1].innerHTML = itemStatsToString(set[0]);
|
||||||
rows[1].children[0].innerText = chestpiece.name;
|
rows[2].children[1].innerHTML = itemStatsToString(set[1]);
|
||||||
rows[2].children[0].innerText = gauntlet.name;
|
rows[3].children[1].innerHTML = itemStatsToString(set[2]);
|
||||||
rows[3].children[0].innerText = legging.name;
|
rows[4].children[1].innerHTML = itemStatsToString(set[3]);
|
||||||
|
|
||||||
rows[0].children[1].innerHTML = statString(helmet);
|
rows[0].children[1].innerHTML = setStatsToString(set);
|
||||||
rows[1].children[1].innerHTML = statString(chestpiece);
|
|
||||||
rows[2].children[1].innerHTML = statString(gauntlet);
|
|
||||||
rows[3].children[1].innerHTML = statString(legging);
|
|
||||||
|
|
||||||
rows[4].children[1].innerHTML = totalStatsString(helmet, chestpiece, gauntlet, legging);
|
|
||||||
|
|
||||||
destination.appendChild(clone);
|
destination.appendChild(clone);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function statString(item) {
|
const RESISTANCE_NAMES = [
|
||||||
|
"immunity",
|
||||||
|
"robustness",
|
||||||
|
"focus",
|
||||||
|
"vitality",
|
||||||
|
]
|
||||||
|
|
||||||
|
function itemStatsToString(item) {
|
||||||
let weight = item.weight.toFixed(1) + " wgt., ";
|
let weight = item.weight.toFixed(1) + " wgt., ";
|
||||||
let poise = item.poise + " poise, ";
|
let poise = item.poise + " poise, ";
|
||||||
let physical = item.defenses.slice(0, 4).reduce((total, defense, i) => total + defense.toFixed(1) + " " + DEFENSE[i] + ", ", "");
|
let physical = item.defenses.slice(0, 4).reduce((total, defense) => total + defense, 0.0).toFixed(1) + " phys. ";
|
||||||
let elemental = item.defenses.slice(4, 8).reduce((total, defense, i) => total + defense.toFixed(1) + " " + DEFENSE[i + 4] + ", ", "");
|
let elemental = item.defenses.slice(4, 8).reduce((total, defense) => total + defense, 0.0).toFixed(1) + " elem. ";
|
||||||
let resistances = item.resistances.reduce((total, res, i) => total + res + " " + RESISTANCES[i] + ", ", "");
|
// let physical = item.defenses.slice(0, 4).reduce((total, defense, i) => total + defense.toFixed(1) + " " + DEFENSE_NAMES[i] + ", ", 0.0);
|
||||||
|
// let elemental = item.defenses.slice(4, 8).reduce((total, defense, i) => total + defense.toFixed(1) + " " + DEFENSE_NAMES[i + 4] + ", ", "");
|
||||||
|
let resistances = item.resistances.reduce((total, res, i) => total + res + " " + RESISTANCE_NAMES[i] + ", ", "");
|
||||||
|
|
||||||
return weight + poise + physical + "<br>" + elemental + "<br>" + resistances;
|
return weight + poise + physical + elemental + "<br>" + resistances;
|
||||||
}
|
}
|
||||||
|
|
||||||
function totalStatsString(helmet, chestpiece, gauntlets, leggings) {
|
function setStatsToString(set) {
|
||||||
let imaginary = {
|
let imaginary = {
|
||||||
weight: helmet.weight + chestpiece.weight + gauntlets.weight + leggings.weight,
|
weight: set[0].weight + set[1].weight + set[2].weight + set[3].weight,
|
||||||
poise: helmet.poise + chestpiece.poise + gauntlets.poise + leggings.poise,
|
poise: set[0].poise + set[1].poise + set[2].poise + set[3].poise,
|
||||||
defenses: helmet.defenses.map((stat, i) => stat + chestpiece.defenses[i] + gauntlets.defenses[i] + leggings.defenses[i]),
|
defenses: set[0].defenses.map((stat, i) => stat + set[1].defenses[i] + set[2].defenses[i] + set[3].defenses[i]),
|
||||||
resistances: helmet.resistances.map((stat, i) => stat + chestpiece.resistances[i] + gauntlets.resistances[i] + leggings.resistances[i])
|
resistances: set[0].resistances.map((stat, i) => stat + set[1].resistances[i] + set[2].resistances[i] + set[3].resistances[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
return statString(imaginary);
|
return itemStatsToString(imaginary);
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user