wip armor optimizer
This commit is contained in:
parent
07b7321ec9
commit
054dfbe1c4
230
src/armor.html
Normal file
230
src/armor.html
Normal file
@ -0,0 +1,230 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="language" content="english">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<link rel="stylesheet" href="style/main.css">
|
||||
|
||||
<title>Erdtree - Class Optimizer</title>
|
||||
<meta name="description" content="">
|
||||
|
||||
<script src="/script/armor.js"></script>
|
||||
</head>
|
||||
|
||||
<body onload="init();">
|
||||
<nav>
|
||||
<h1><a href="/index.html">Elden Ring Build Planner</a></h1>
|
||||
<ul>
|
||||
<li><a href="/planner.html">Build Planner</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<header>
|
||||
<h1>Armor Optimizer</h1>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<div class="app">
|
||||
<!-- settings -->
|
||||
<article style="flex-basis: 30%">
|
||||
<ul>
|
||||
<li><b>Settings</b></li>
|
||||
|
||||
<hr>
|
||||
|
||||
<li>
|
||||
<label for="equip-load"><b>Max. Equip Load</b></label>
|
||||
<input style="max-width: 50px" class="stat" id="equip-load" type="number" onchange="update()"
|
||||
min=0 step=0.1 value="30">
|
||||
</li>
|
||||
|
||||
<hr>
|
||||
|
||||
<li>
|
||||
<b>Breakpoints</b>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<div>
|
||||
<input type="radio" id="fast-roll" onclick="update()" name="burden">
|
||||
<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>
|
||||
<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">
|
||||
<label for="fat-roll">Fat Roll (up to 100% equip load)</label>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<hr>
|
||||
|
||||
<li>
|
||||
<b>Sorting</b>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<div>
|
||||
<input type="radio" id="greatest-physical" name="sorting-order" onclick="update()" checked>
|
||||
<label for="avg-physical">Greatest Physical Negation</label>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<div>
|
||||
<input type="radio" id="greatest-elemental" name="sorting-order" onclick="update()">
|
||||
<label for="avg-elemental">Greatest Elemental Negation</label>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<div>
|
||||
<input type="radio" id="greatest-immunities" name="sorting-order" onclick="update()">
|
||||
<label for="avg-immunities">Greatest Immunities</label>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<div>
|
||||
<input type="radio" id="greatest-average" name="sorting-order" onclick="update()">
|
||||
<label for="greatest-average">Greatest Weighted Average Defense</label>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<hr>
|
||||
|
||||
<li>
|
||||
<b>Extras</b>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<div>
|
||||
<input type="checkbox" id="winged-crystal-tear" onchange="update()">
|
||||
<label for="winged-crystal-tear">Winged Crystal Tear (in mixed physick)</label>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div>
|
||||
<input type="checkbox" id="fashion" onchange="update()">
|
||||
<label for="fashion">Fashion Mode</label>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</article>
|
||||
|
||||
<!-- results -->
|
||||
<article style="flex-basis: 60%; min-width: 300px">
|
||||
<ul>
|
||||
<li><b>Results</b></li>
|
||||
<hr>
|
||||
|
||||
<template id="sort-result">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Items</th>
|
||||
<th>Stats</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Helmet</td>
|
||||
<td>Stats</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Chestpiece</td>
|
||||
<td>Stats</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Gaunlets</td>
|
||||
<td>Stats</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Leggings</td>
|
||||
<td>Stats</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</template>
|
||||
</ul>
|
||||
</article>
|
||||
|
||||
<!-- filter -->
|
||||
<article>
|
||||
<ul>
|
||||
<li><b>Filter</b></li>
|
||||
<hr>
|
||||
<li>
|
||||
<b>Locked Equipment</b>
|
||||
<button id="clear-equipment" onclick="update()">Clear Locked Equipment</button>
|
||||
</li>
|
||||
<li>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Headgear</th>
|
||||
<th>Chestpiece</th>
|
||||
<th>Gauntlets</th>
|
||||
<th>Leggings</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<select type="text" id="select-head" name="locked-equipment"
|
||||
onchange="update()">
|
||||
<option>None</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<select type="text" id="select-chest" name="locked-equipment"
|
||||
onchange="update()">
|
||||
<option>None</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<select type=" text" id="select-hands" name="locked-equipment"
|
||||
onchange="update()">
|
||||
<option>None</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<select type="text" id="select-legs" name="locked-equipment"
|
||||
onchange="update()">
|
||||
<option>None</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</li>
|
||||
|
||||
<hr>
|
||||
|
||||
<li>
|
||||
<b>Allowed Armor</b>
|
||||
</li>
|
||||
</ul>
|
||||
</article>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<h5>Erdtree Planner (<a href="https://git.palmoe.dk/vodofrede/erdtree">available under BSD-3-Clause license</a>)
|
||||
</h5>
|
||||
<h5>Copyright 2022 vodofrede</h5>
|
||||
</footer>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"helms": [
|
||||
"helmets": [
|
||||
{
|
||||
"id": "albinauric-mask",
|
||||
"name": "Albinauric Mask",
|
14
src/data/sets.json
Normal file
14
src/data/sets.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"sets": [
|
||||
{
|
||||
"id": "alberichs-set",
|
||||
"name": "Alberich's Set",
|
||||
"pieces": [
|
||||
"alberichs-pointed-hat",
|
||||
"alberichs-robe",
|
||||
"alberichs-bracers",
|
||||
"alberichs-trousers"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -17,7 +17,6 @@
|
||||
<h1><a href="/index.html">Elden Ring Build Planner</a></h1>
|
||||
<ul>
|
||||
<li><a href="/planner.html">Build Planner</a></li>
|
||||
<li><a href="/optimizer.html">Class Optimizer</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
@ -29,7 +28,7 @@
|
||||
<div class="cards">
|
||||
<article>
|
||||
<a href="/planner.html">
|
||||
<h3>Build Planner</h3>
|
||||
<h3>Build Planner (todo)</h3>
|
||||
<br>
|
||||
<p>Create a new build.</p>
|
||||
</a>
|
||||
@ -43,9 +42,17 @@
|
||||
</a>
|
||||
</article>
|
||||
|
||||
<article>
|
||||
<a href="/armor.html">
|
||||
<h3>Armor Optimizer (in progress)</h3>
|
||||
<br>
|
||||
<p>Maximize defensive stats.</p>
|
||||
</a>
|
||||
</article>
|
||||
|
||||
<article>
|
||||
<a href="/attack.html">
|
||||
<h3>Attack Rating Calculator</h3>
|
||||
<h3>Attack Rating Calculator (todo)</h3>
|
||||
<br>
|
||||
<p>Calculate attack rating for a weapon.</p>
|
||||
</a>
|
||||
@ -53,23 +60,15 @@
|
||||
|
||||
<article>
|
||||
<a href="/censor.html">
|
||||
<h3>Censor Checker</h3>
|
||||
<h3>Censor Checker (todo)</h3>
|
||||
<br>
|
||||
<p>Detect censored names.</p>
|
||||
</a>
|
||||
</article>
|
||||
|
||||
<article>
|
||||
<a href="/armor.html">
|
||||
<h3>Armor Optimizer</h3>
|
||||
<br>
|
||||
<p>Maximize defensive stats.</p>
|
||||
</a>
|
||||
</article>
|
||||
|
||||
<article>
|
||||
<a href="/finder.html">
|
||||
<h3>Weapon Finder</h3>
|
||||
<h3>Weapon Finder (todo)</h3>
|
||||
<br>
|
||||
<p>Get suggestions for usable weapons.</p>
|
||||
</a>
|
||||
|
@ -19,7 +19,6 @@
|
||||
<h1><a href="/index.html">Elden Ring Build Planner</a></h1>
|
||||
<ul>
|
||||
<li><a href="/planner.html">Build Planner</a></li>
|
||||
<li><a href="/optimizer.html">Class Optimizer</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
@ -203,8 +202,6 @@
|
||||
|
||||
<hr>
|
||||
|
||||
|
||||
|
||||
<template id="talisman">
|
||||
<li>
|
||||
<div>
|
||||
@ -221,17 +218,17 @@
|
||||
<article>
|
||||
<ul>
|
||||
<li>
|
||||
<b>Helms</b>
|
||||
<b>Helmets</b>
|
||||
</li>
|
||||
|
||||
<hr>
|
||||
|
||||
<details id="helms">
|
||||
<summary>Click to show helms</summary>
|
||||
<details id="helmets">
|
||||
<summary>Click to show helmets</summary>
|
||||
|
||||
<li>
|
||||
<div>
|
||||
<input type="radio" name="equipment" id="helmNone" onclick="update()" checked>
|
||||
<input type="radio" name="equipment" id="helm-none" onclick="update()" checked>
|
||||
<label for="">None</label>
|
||||
</div>
|
||||
<aside></aside>
|
||||
@ -255,10 +252,10 @@
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<td>Skill</td>
|
||||
<td>Stat</td>
|
||||
<td>Softcaps</td>
|
||||
<td>Notes</td>
|
||||
<th>Skill</th>
|
||||
<th>Stat</th>
|
||||
<th>Softcaps</th>
|
||||
<th>Notes</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -17,7 +17,6 @@
|
||||
<h1><a href="/index.html">Elden Ring Build Planner</a></h1>
|
||||
<ul>
|
||||
<li><a href="/planner.html">Build Planner</a></li>
|
||||
<li><a href="/optimizer.html">Class Optimizer</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
|
@ -0,0 +1,39 @@
|
||||
const HELMETS = fetch("/data/armor.json")
|
||||
.then(response => response.json())
|
||||
.then(data => data.helmets)
|
||||
.catch(error => console.log(error));
|
||||
const CHESTPIECES = fetch("/data/armor.json")
|
||||
.then(response => response.json())
|
||||
.then(data => data.chestpieces)
|
||||
.catch(error => console.log(error));
|
||||
const GAUNTLETS = fetch("/data/armor.json")
|
||||
.then(response => response.json())
|
||||
.then(data => data.gauntlets)
|
||||
.catch(error => console.log(error));
|
||||
const LEGGINGS = fetch("/data/armor.json")
|
||||
.then(response => response.json())
|
||||
.then(data => data.leggings)
|
||||
.catch(error => console.log(error));
|
||||
|
||||
async function init() {
|
||||
|
||||
}
|
||||
|
||||
async function update() {
|
||||
let sorted = sortedCandidates();
|
||||
}
|
||||
|
||||
function sortedCandidates() {
|
||||
// determine how to sort
|
||||
|
||||
// get most likely candidates
|
||||
let candidates = findCandidates();
|
||||
|
||||
// sort candidates
|
||||
|
||||
return candidates;
|
||||
}
|
||||
|
||||
function findCandidates() {
|
||||
return [];
|
||||
}
|
@ -6,9 +6,9 @@ const TALISMANS = fetch("/data/talismans.json")
|
||||
.then(response => response.json())
|
||||
.then(data => data.talismans)
|
||||
.catch(error => console.log(error));
|
||||
const HELMS = fetch("data/armor.json")
|
||||
const HELMETS = fetch("/data/helmets.json")
|
||||
.then(response => response.json())
|
||||
.then(data => data.helms)
|
||||
.then(data => data.helmets)
|
||||
.catch(error => console.log(error));
|
||||
|
||||
const STAT_SHORT_NAMES = [
|
||||
@ -23,17 +23,17 @@ const STAT_SHORT_NAMES = [
|
||||
]
|
||||
|
||||
async function init() {
|
||||
// load and show helms
|
||||
let helms = await HELMS;
|
||||
helms = helms.filter(helm => helm.stats != null && helm.stats != undefined);
|
||||
// populate helmet list
|
||||
let helmets = await HELMETS;
|
||||
helmets = helmets.filter(helmet => helmet.stats != null && helmet.stats != undefined);
|
||||
|
||||
let helmTemplate = document.getElementById("helm");
|
||||
let helmList = document.getElementById("helms");
|
||||
helms.forEach(helm => {
|
||||
cloneTemplate(helmTemplate, helmList, helm);
|
||||
let helmetTemplate = document.getElementById("helm");
|
||||
let helmetList = document.getElementById("helmets");
|
||||
helmets.forEach(helmet => {
|
||||
cloneTemplate(helmetTemplate, helmetList, helmet);
|
||||
});
|
||||
|
||||
// load and show talismans
|
||||
// populate talisman list
|
||||
let talismans = await TALISMANS;
|
||||
talismans = talismans.filter(talisman => talisman.stats != null && talisman.stats != undefined);
|
||||
|
||||
@ -60,7 +60,7 @@ async function update() {
|
||||
let best = sorted[0];
|
||||
|
||||
// get added stats from items
|
||||
let items = itemStats((await TALISMANS).concat(await HELMS));
|
||||
let items = itemStats((await TALISMANS).concat(await HELMETS));
|
||||
|
||||
// update document
|
||||
document.getElementsByName("option").forEach((elem, i) => {
|
||||
@ -91,12 +91,6 @@ async function update() {
|
||||
}
|
||||
}
|
||||
|
||||
function statDelta(classStats, desiredStats) {
|
||||
return classStats
|
||||
.map((e, i) => e < desiredStats[i] ? desiredStats[i] - e : 0)
|
||||
.reduce((total, n) => total + n);
|
||||
}
|
||||
|
||||
function sortClasses(classes, desiredStats) {
|
||||
let deltas = classes.map(c => {
|
||||
c.total = c.level + statDelta(c.stats, desiredStats);
|
||||
@ -106,6 +100,12 @@ function sortClasses(classes, desiredStats) {
|
||||
return deltas;
|
||||
}
|
||||
|
||||
function statDelta(classStats, desiredStats) {
|
||||
return classStats
|
||||
.map((e, i) => e < desiredStats[i] ? desiredStats[i] - e : 0)
|
||||
.reduce((total, n) => total + n);
|
||||
}
|
||||
|
||||
function itemStats(relevantItems) {
|
||||
let ids = [...document.getElementsByName("equipment")]
|
||||
.filter(elem => elem.checked)
|
||||
@ -118,7 +118,7 @@ function itemStats(relevantItems) {
|
||||
function clearAll() {
|
||||
document.getElementsByName("desired-stat").forEach(elem => elem.value = null);
|
||||
[...document.getElementsByName("equipment")].forEach(elem => elem.checked = false);
|
||||
document.getElementById("helmNone").checked = true;
|
||||
document.getElementById("helm-none").checked = true;
|
||||
|
||||
update();
|
||||
}
|
||||
|
@ -175,21 +175,17 @@ table {
|
||||
margin-bottom: 10px;
|
||||
|
||||
border: 1px solid var(--border);
|
||||
background-color: var(--secondary);
|
||||
|
||||
background-color: var(--primary);
|
||||
}
|
||||
|
||||
td,
|
||||
th {
|
||||
padding: 0.5em;
|
||||
border-bottom: 1px solid var(--primary);
|
||||
}
|
||||
|
||||
thead {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
tbody:first-child {
|
||||
font-weight: bold;
|
||||
th {
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
|
||||
/* buttons & input */
|
||||
@ -212,6 +208,7 @@ button {
|
||||
text-align: center;
|
||||
|
||||
flex-grow: 1;
|
||||
flex-basis: 25%;
|
||||
min-width: 200px;
|
||||
|
||||
border: 1px solid var(--outline);
|
||||
@ -273,19 +270,23 @@ button {
|
||||
flex-grow: 50%;
|
||||
}
|
||||
|
||||
.app .stat {
|
||||
.app input {
|
||||
text-align: center;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: textfield;
|
||||
margin-left: 10px;
|
||||
max-width: 40px;
|
||||
align-self: flex-end;
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.app input:is([disabled]) {
|
||||
text-align: center;
|
||||
background-color: var(--primary);
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.app .stat {
|
||||
align-self: flex-end;
|
||||
max-width: 40px;
|
||||
|
||||
margin-left: 10px;
|
||||
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
|
||||
.app .stat:not([disabled]) {
|
||||
@ -296,3 +297,7 @@ button {
|
||||
margin-top: 2px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.app select {
|
||||
width: 100%;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user