v1 of weapon finder

This commit is contained in:
Frederik Palmø 2022-04-07 01:35:26 +02:00
parent 8b8d5a9226
commit 2fb981ccdd
17 changed files with 3188 additions and 2795 deletions

File diff suppressed because it is too large Load Diff

BIN
src/resource/icon/blood.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
src/resource/icon/cold.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
src/resource/icon/fire.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/resource/icon/heavy.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
src/resource/icon/keen.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
src/resource/icon/magic.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -2,54 +2,91 @@ let WEAPONS;
let INFUSIONS;
let CORRECTIONS;
let sort = "max";
let ascending = true;
async function init() {
WEAPONS = await fetch("/data/weapons.json").then((response) => response.json());
INFUSIONS = await fetch("/data/infusions.json").then((response) => response.json());
CORRECTIONS = await fetch("/data/damage.json").then((response) => response.json());
WEAPONS = await fetch("/data/weapons.json").then(response => response.json());
INFUSIONS = await fetch("/data/infusions.json").then(response => response.json());
CORRECTIONS = await fetch("/data/damage.json").then(response => response.json());
update();
}
function update() {
// get information from document
let allowedInfusions = [
"standard",
...[...document.getElementsByName("infusion")].filter((elem) => elem.checked).map((elem) => elem.id),
];
// get all parameters
let categories = [...document.getElementsByName("category")].filter(el => el.checked).map(el => el.id);
let upgraded = document.getElementById("max-upgrade").checked;
let requireStats = document.getElementById("requirements").checked;
let damageTypes = [...document.getElementsByName("damage-type")].map((el) => el.checked);
let stats = [...document.getElementsByName("stat")].map((el) => parseInt(el.value));
let infIndex = Object.values(INFUSIONS).findIndex(inf => inf.id == sort);
let allowedInfusions = [...document.getElementsByName("infusion")]
.filter(elem => elem.checked)
.map(elem => elem.value);
let stats = [...document.getElementsByName("stat")].map(el => parseInt(el.value));
let twoHanding = document.getElementById("2handing").checked;
if (twoHanding) {
stats[0] = Math.floor(stats[0] * 1.5);
}
let filtered = filterWeapons(stats, requireStats, allowedInfusions, damageTypes);
let sorted = sortWeapons(filtered, "standard", upgraded, stats);
// show sorted list
// fill table
let destination = document.getElementById("weapons");
let template = document.getElementById("weaponTemplate");
sorted.forEach((weapon) => {
let clone = template.content.cloneNode(true);
destination.innerHTML = ""; // clear table
let template = document.getElementById("weapon");
Object.values(WEAPONS)
.filter(weapon => {
return (
(weapon.requirements.every((stat, i) => stat <= stats[i]) || !requireStats) &&
categories.includes(weapon.category) &&
allowedInfusions.some(id => weapon.infusions[id] != undefined)
);
})
.map(weapon => {
let attackRatings = Object.values(INFUSIONS)
.filter(inf => allowedInfusions.includes(inf.id))
.map(inf => {
return weapon.infusions[inf.id] != null ? damage(weapon, inf.id, upgraded, stats) : 0;
});
let max = Math.max(0, ...attackRatings);
let tr = clone.children[0];
tr.children[0].innerHTML = weapon.name;
tr.children[1].innerHTML = weapon.damage;
return [weapon, attackRatings, max];
})
.sort(([_w1, ar1, m1], [_w2, ar2, m2]) => {
if (infIndex == -1) {
// sort by max
return ascending ? m2 - m1 : m1 - m2;
} else {
return ascending ? ar2[infIndex] - ar1[infIndex] : ar1[infIndex] - ar2[infIndex];
}
})
.forEach(([weapon, attackRatings, max]) => {
let clone = template.content.cloneNode(true);
let tr = clone.children[0];
destination.appendChild(clone);
tr.children[0].children[0].innerHTML = weapon.name;
tr.children[0].children[0].href =
weapon.id != "unarmed"
? "https://eldenring.wiki.fextralife.com/" + weapon.name.replaceAll(" ", "+")
: "https://cdn.discordapp.com/attachments/410786957426163725/961366807460057158/unknown.png";
tr.children[1].innerHTML = max || "-";
attackRatings.forEach((ar, i) => {
tr.children[i + 2].innerHTML = attackRatings[i] || "-";
});
destination.appendChild(clone);
});
// update result table header to only include allowed infusions
[...document.getElementsByName("damage-result")].forEach(ty => {
ty.hidden = !allowedInfusions.includes(ty.id);
});
console.log(sorted);
}
function filterWeapons(stats, requireStats, allowedInfusions, damageTypes) {
let weapons = Object.values(WEAPONS).filter((weapon) => {
return allowedInfusions.some((inf) => Object.values(weapon.infusions).includes(inf));
let weapons = Object.values(WEAPONS).filter(weapon => {
return allowedInfusions.some(inf => Object.values(weapon.infusions).includes(inf));
});
if (requireStats) {
weapons = weapons.filter((weapon) => weapon.requirements.every((stat, i) => stat <= stats[i]));
weapons = weapons.filter(weapon => weapon.requirements.every((stat, i) => stat <= stats[i]));
}
return weapons;
@ -60,51 +97,44 @@ function sortWeapons(weapons, infusionId, upgraded, stats) {
}
function damage(weapon, infusionId, upgraded, stats) {
if (weapon.damage != undefined) {
return weapon.damage;
}
let weaponInfusion = weapon.infusions[infusionId];
let infusion = INFUSIONS[infusionId];
let upgradeLevel = upgraded ? (weapon.unique ? 10 : 25) : 0;
let bases = infusion.damage.map(
(amount, ty) => weaponInfusion.damage[ty] * (amount + infusion.upgrade[ty] * upgradeLevel)
let base = infusion.damage.map(
(amount, ty) => weaponInfusion.damage[ty] * (amount + infusion.upgrade[ty] * upgradeLevel),
);
let extras;
if (stats.some((stat, i) => stat <= weapon.requirements[i])) {
extras = bases.map((dmg) => dmg * -0.4);
} else {
extras = bases.map((amount, ty) => {
let calc = CORRECTIONS[weaponInfusion.corrections[ty]];
let correction = typeCorrections(calc, stats, weaponInfusion.masks[ty]);
let scalings = weaponInfusion.scaling.map((itemScaling) => {
return (
itemScaling * infusion.scaling[ty] +
itemScaling * infusion.scaling[ty] * infusion.growth[ty] * upgradeLevel
);
});
let extras = scalings.map((statScaling, statIndex) => {
return (amount * statScaling * correction[statIndex]) / 100.0;
});
return extras.reduce((sum, n) => sum + n);
});
}
let scaling = stats.some((stat, i) => stat < weapon.requirements[i])
? base.map(dmg => dmg * -0.4)
: base.map((amount, ty) => {
let statCorrection = corrections(
CORRECTIONS[weaponInfusion.corrections[ty]],
stats,
weaponInfusion.masks[ty],
);
let statScaling = weaponInfusion.scaling.map(itemScaling => {
return (
itemScaling * infusion.scaling[ty] +
itemScaling * infusion.scaling[ty] * infusion.growth[ty] * upgradeLevel
);
});
let scaling = statScaling.map((statScaling, statIndex) => {
return (amount * statScaling * statCorrection[statIndex]) / 100.0;
});
return scaling.reduce((sum, n) => sum + n);
});
let damage = Math.floor(bases.reduce((sum, n) => sum + n) + extras.reduce((sum, n) => sum + n));
weapon.damage = damage;
return damage;
return Math.floor(base.reduce((sum, n) => sum + n) + scaling.reduce((sum, n) => sum + n));
}
function typeCorrections(calc, stats, masks) {
function corrections(calc, stats, masks) {
return stats.map((stat, ty) => {
let mask = masks[ty];
if (mask == 0) {
if (masks[ty] == 0) {
return 0.0;
}
let capIndex = calc.softcaps[ty].findIndex((cap) => cap >= stat) - 1;
let capIndex = calc.softcaps[ty].findIndex(cap => cap >= stat) - 1;
let cap = calc.softcaps[ty][capIndex];
let capDelta = (calc.softcaps[ty][capIndex + 1] || cap) - cap;
let growth = calc.growth[ty][capIndex];
@ -118,3 +148,18 @@ function typeCorrections(calc, stats, masks) {
}
});
}
function setAll(name, state) {
[...document.getElementsByName(name), ...document.getElementsByClassName(name)].forEach(el => (el.checked = state));
update();
}
function changeSort(newSort) {
if (sort == newSort) {
ascending = !ascending;
} else {
ascending = true;
}
sort = newSort;
update();
}

View File

@ -3,7 +3,7 @@
:root {
--primary: white;
--lighter: #f8f8ff;
--darker: #f3f3f3;
--darker: #f8f8ff;
--border: grey;
--font-color: black;
--font-inverted: white;
@ -79,6 +79,7 @@ header {
main {
display: flex;
flex-direction: column;
margin-bottom: 1rem;
}
footer {
@ -177,25 +178,32 @@ li {
table {
text-align: center;
width: 100%;
height: 100%;
border-collapse: collapse;
margin-bottom: 10px;
border: 1px solid var(--border);
border-radius: 5px;
outline: 1px solid var(--border);
border-radius: 2px;
background-color: var(--lighter);
background-color: var(--primary);
}
td,
th {
padding: 0.5em;
padding: 0.4rem;
}
thead,
tbody {
margin: 0;
padding: 0;
}
/* buttons & input */
button {
/* border: var(--border);
border-radius: 3px;*/
margin: 0rem 0rem 0.2rem 0rem;
padding: 0.1rem 0.3rem 0.2rem 0.3rem;
margin: 0rem 0rem 0.3rem 0rem;
padding: 0rem 0.3rem 0.1rem 0.3rem;
color: black;
}
@ -204,7 +212,7 @@ label {
}
input {
margin: 0rem 0rem 0.2rem 0rem;
margin: 0rem 0rem 0rem 0rem;
color: black;
}
@ -255,6 +263,7 @@ select * {
flex-flow: column nowrap;
flex-basis: 320px;
flex-grow: 1;
gap: 1px;
padding: 10px;
border: 1px solid var(--border);

View File

@ -5,27 +5,22 @@
<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 and description -->
<title>Erdtree - Weapon Finder</title>
<meta
name="description"
content="Erdtree - Elden Ring build planner, armor optimizer, weapon finder and more!"
/>
<meta property="og:title" content="Erdtree Build Planner" />
<meta
property="og:description"
content="Erdtree - Elden Ring build planner, armor optimizer, weapon finder and more!"
/>
<meta property="og:url" content="https://erdtree.palmoe.dk" />
<!-- scripts -->
<script src="/script/weapons.js"></script>
</head>
<body onload="init();">
<nav>
<h1><a href="/">Elden Ring Build Planner</a></h1>
@ -33,19 +28,15 @@
<li><a href="/planner.html">Build Planner</a></li>
</ul>
</nav>
<header>
<h1>Weapon Finder</h1>
</header>
<main>
<div class="app">
<!-- parameters -->
<article style="flex-basis: 40%">
<article style="flex-basis: 20%">
<b>Parameters</b>
<hr />
<div>
<label for="str">Strength</label>
<input id="str" type="number" name="stat" value="10" min="0" max="99" onchange="update()" />
@ -66,7 +57,6 @@
<label for="arc">Arcane</label>
<input id="arc" type="number" name="stat" value="10" min="0" max="99" onchange="update()" />
</div>
<hr />
<div>
<span>
@ -80,7 +70,6 @@
<label for="min-upgrade">Not Reinforced (+0)</label>
</span>
</div>
<hr />
<div>
<span>
@ -88,173 +77,810 @@
<label for="requirements">Requirements Met</label>
</span>
</div>
<div>
<span>
<input id="2handing" type="checkbox" onchange="update()" />
<label for="2handing">2-handing (1.5x strength)</label>
</span>
</div>
<hr />
<div>
<b>Infusions</b>
<span>
<button>Any</button>
<button>None</button>
</span>
</div>
<div>
<span>
<input id="standard" type="checkbox" name="infusion" checked />
<label for="standard">Standard</label>
<button onclick="setAll('infusion', true)">Any</button>
<button onclick="setAll('infusion', false)">None</button>
</span>
</div>
<div>
<span>
<input id="heavy" type="checkbox" name="infusion" checked />
<label for="heavy">Heavy</label>
<input
id="standard-infusion"
value="standard"
type="checkbox"
name="infusion"
onchange="update()"
checked
/>
<label for="standard-infusion">Standard</label>
</span>
</div>
<div>
<span>
<input id="keen" type="checkbox" name="infusion" checked />
<label for="keen">Keen</label>
<input
id="heavy-infusion"
value="heavy"
type="checkbox"
name="infusion"
onchange="update()"
checked
/>
<label for="heavy-infusion">Heavy</label>
</span>
</div>
<div>
<span>
<input id="quality" type="checkbox" name="infusion" checked />
<label for="quality">Quality</label>
<input
id="keen-infusion"
value="keen"
type="checkbox"
name="infusion"
onchange="update()"
checked
/>
<label for="keen-infusion">Keen</label>
</span>
</div>
<div>
<span>
<input id="fire" type="checkbox" name="infusion" checked />
<label for="fire">Fire</label>
<input
id="quality-infusion"
value="quality"
type="checkbox"
name="infusion"
onchange="update()"
checked
/>
<label for="quality-infusion">Quality</label>
</span>
</div>
<div>
<span>
<input id="flame-art" type="checkbox" name="infusion" checked />
<label for="flame-art">Flame Art</label>
<input
id="fire-infusion"
value="fire"
type="checkbox"
name="infusion"
onchange="update()"
checked
/>
<label for="fire-infusion">Fire</label>
</span>
</div>
<div>
<span>
<input id="lightning" type="checkbox" name="infusion" checked />
<label for="lightning">Lightning</label>
<input
id="flame-art-infusion"
value="flame-art"
type="checkbox"
name="infusion"
onchange="update()"
checked
/>
<label for="flame-art-infusion">Flame Art</label>
</span>
</div>
<div>
<span>
<input id="sacred" type="checkbox" name="infusion" checked />
<label for="sacred">Sacred</label>
<input
id="lightning-infusion"
value="lightning"
type="checkbox"
name="infusion"
onchange="update()"
checked
/>
<label for="lightning-infusion">Lightning</label>
</span>
</div>
<div>
<span>
<input id="magic" type="checkbox" name="infusion" checked />
<label for="magic">Magic</label>
<input
id="sacred-infusion"
value="sacred"
type="checkbox"
name="infusion"
onchange="update()"
checked
/>
<label for="sacred-infusion">Sacred</label>
</span>
</div>
<div>
<span>
<input id="cold" type="checkbox" name="infusion" checked />
<label for="cold">Cold</label>
<input
id="magic-infusion"
value="magic"
type="checkbox"
name="infusion"
onchange="update()"
checked
/>
<label for="magic-infusion">Magic</label>
</span>
</div>
<div>
<span>
<input id="poison" type="checkbox" name="infusion" checked />
<label for="poison">Poison</label>
<input
id="cold-infusion"
value="cold"
type="checkbox"
name="infusion"
onchange="update()"
checked
/>
<label for="cold-infusion">Cold</label>
</span>
</div>
<div>
<span>
<input id="blood" type="checkbox" name="infusion" checked />
<label for="blood">Blood</label>
<input
id="poison-infusion"
value="poison"
type="checkbox"
name="infusion"
onchange="update()"
checked
/>
<label for="poison-infusion">Poison</label>
</span>
</div>
<div>
<span>
<input id="occult" type="checkbox" name="infusion" checked />
<label for="occult">Occult</label>
<input
id="blood-infusion"
value="blood"
type="checkbox"
name="infusion"
onchange="update()"
checked
/>
<label for="blood-infusion">Blood</label>
</span>
</div>
<div>
<span>
<input
id="occult-infusion"
value="occult"
type="checkbox"
name="infusion"
onchange="update()"
checked
/>
<label for="occult-infusion">Occult</label>
</span>
</div>
<hr />
<!-- damage types -->
<b>Damage Types</b>
<div>
<span>
<input id="physical" type="checkbox" name="damage-type" checked />
<label for="physical">Physical Damage</label>
<input id="physical-type" type="checkbox" name="damage-type" disabled />
<label for="physical-type">Physical Damage</label>
</span>
</div>
<div>
<span>
<input id="magic" type="checkbox" name="damage-type" checked />
<label for="magic">Magic Damage</label>
<input id="magic-type" type="checkbox" name="damage-type" disabled />
<label for="magic-type">Magic Damage</label>
</span>
</div>
<div>
<span>
<input id="fire" type="checkbox" name="damage-type" checked />
<label for="fire">Fire Damage</label>
<input id="fire-type" type="checkbox" name="damage-type" disabled />
<label for="fire-type">Fire Damage</label>
</span>
</div>
<div>
<span>
<input id="lightning" type="checkbox" name="damage-type" checked />
<label for="lightning">Lightning Damage</label>
<input id="lightning-type" type="checkbox" name="damage-type" disabled />
<label for="lightning-type">Lightning Damage</label>
</span>
</div>
<div>
<span>
<input id="Holy" type="checkbox" name="damage-type" checked />
<label for="Holy">Holy Damage</label>
<input id="holy-type" type="checkbox" name="damage-type" disabled />
<label for="holy-type">Holy Damage</label>
</span>
</div>
</article>
<article style="flex-basis: 40%">
<b>Categories</b>
<hr />
</article>
<!-- results -->
<article style="flex-basis: 55%">
<article style="flex-basis: 55%; min-width: 700px">
<b>Results</b>
<hr />
<template id="weaponTemplate">
<template id="weapon">
<tr>
<td>
<a target="_blank"></a>
</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</template>
<div>
<table>
<thead>
<tr>
<th>Weapon</th>
<th name="standard">Attack Rating</th>
<th style="min-width: 2rem">
<b style="user-select: none">Weapon</b>
</th>
<th>
<b
onclick="changeSort('max')"
onmouseover="this.style.cursor = 'pointer'"
style="user-select: none"
>
Max
</b>
</th>
<th id="standard" name="damage-result">
<input
type="image"
src="/resource/icon/standard.jpg"
width="25px"
title="Standard"
alt="Standard"
onclick="changeSort('standard')"
/>
</th>
<th id="heavy" name="damage-result">
<input
type="image"
src="/resource/icon/heavy.jpg"
width="25px"
title="Heavy"
alt="Heavy"
onclick="changeSort('heavy')"
/>
</th>
<th id="keen" name="damage-result">
<input
type="image"
src="/resource/icon/keen.jpg"
width="25px"
title="Keen"
alt="Keen"
onclick="changeSort('keen')"
/>
</th>
<th id="quality" name="damage-result">
<input
type="image"
src="/resource/icon/quality.jpg"
width="25px"
title="Quality"
alt="Quality"
onclick="changeSort('quality')"
/>
</th>
<th id="fire" name="damage-result">
<input
type="image"
src="/resource/icon/fire.jpg"
width="25px"
title="Fire"
alt="Fire"
onclick="changeSort('fire')"
/>
</th>
<th id="flame-art" name="damage-result">
<input
type="image"
src="/resource/icon/flame-art.jpg"
width="25px"
title="Flame Art"
alt="Flame Art"
onclick="changeSort('flame-art')"
/>
</th>
<th id="lightning" name="damage-result">
<input
type="image"
src="/resource/icon/lightning.jpg"
width="25px"
title="Lightning"
alt="Lightning"
onclick="changeSort('lightning')"
/>
</th>
<th id="sacred" name="damage-result">
<input
type="image"
src="/resource/icon/sacred.jpg"
width="25px"
title="Sacred"
alt="Sacred"
onclick="changeSort('sacred')"
/>
</th>
<th id="magic" name="damage-result">
<input
type="image"
src="/resource/icon/magic.jpg"
width="25px"
title="Magic"
alt="Magic"
onclick="changeSort('magic')"
/>
</th>
<th id="cold" name="damage-result">
<input
type="image"
src="/resource/icon/cold.jpg"
width="25px"
title="Cold"
alt="Cold"
onclick="changeSort('cold')"
/>
</th>
<th id="poison" name="damage-result">
<input
type="image"
src="/resource/icon/poison.jpg"
width="25px"
title="Poison"
alt="Poison"
onclick="changeSort('poison')"
/>
</th>
<th id="blood" name="damage-result">
<input
type="image"
src="/resource/icon/blood.jpg"
width="25px"
title="Blood"
alt="Blood"
onclick="changeSort('blood')"
/>
</th>
<th id="occult" name="damage-result">
<input
type="image"
src="/resource/icon/occult.jpg"
width="25px"
title="Occult"
alt="Occult"
onclick="changeSort('occult')"
/>
</th>
</tr>
</thead>
<tbody id="weapons"></tbody>
</table>
</div>
</article>
<!-- categories -->
<article style="flex-basis: 20%">
<div>
<b>Categories</b>
<span>
<button onclick="setAll('category', true)">Any</button>
<button onclick="setAll('category', false)">None</button>
</span>
</div>
<hr />
<div>
<b>Weapons</b>
<span>
<button onclick="setAll('weapon', true)">Any</button>
<button onclick="setAll('weapon', false)">None</button>
</span>
</div>
<div>
<span>
<input
type="checkbox"
id="dagger"
name="category"
class="weapon"
onchange="update()"
checked
/>
<label for="dagger">Daggers</label>
</span>
</div>
<div>
<span>
<input
type="checkbox"
id="straight-sword"
name="category"
class="weapon"
onchange="update()"
checked
/>
<label for="straight-sword">Straight Swords</label>
</span>
</div>
<div>
<span>
<input
type="checkbox"
id="greatsword"
name="category"
class="weapon"
onchange="update()"
checked
/>
<label for="greatsword">Greatswords</label>
</span>
</div>
<div>
<span>
<input
type="checkbox"
id="colossal-sword"
name="category"
class="weapon"
onchange="update()"
checked
/>
<label for="colossal-sword">Colossal Swords</label>
</span>
</div>
<div>
<span>
<input
type="checkbox"
id="thrusting-sword"
name="category"
class="weapon"
onchange="update()"
checked
/>
<label for="thrusting-sword">Thrusting Swords</label>
</span>
</div>
<div>
<span>
<input
type="checkbox"
id="heavy-thrusting-sword"
name="category"
class="weapon"
onchange="update()"
checked
/>
<label for="heavy-thrusting-sword">Heavy Thrusting Swords</label>
</span>
</div>
<div>
<span>
<input
type="checkbox"
id="curved-sword"
name="category"
class="weapon"
onchange="update()"
checked
/>
<label for="curved-sword">Curved Swords</label>
</span>
</div>
<div>
<span>
<input
type="checkbox"
id="curved-greatsword"
name="category"
class="weapon"
onchange="update()"
checked
/>
<label for="curved-greatsword">Curved Greatswords</label>
</span>
</div>
<div>
<span>
<input
type="checkbox"
id="katana"
name="category"
class="weapon"
onchange="update()"
checked
/>
<label for="katana">Katanas</label>
</span>
</div>
<div>
<span>
<input
type="checkbox"
id="twinblade"
name="category"
class="weapon"
onchange="update()"
checked
/>
<label for="twinblade">Twinblades</label>
</span>
</div>
<div>
<span>
<input
type="checkbox"
id="hammer"
name="category"
class="weapon"
onchange="update()"
checked
/>
<label for="hammer">Hammers</label>
</span>
</div>
<div>
<span>
<input
type="checkbox"
id="great-hammer"
name="category"
class="weapon"
onchange="update()"
checked
/>
<label for="great-hammer">Great Hammers</label>
</span>
</div>
<div>
<span>
<input
type="checkbox"
id="flail"
name="category"
class="weapon"
onchange="update()"
checked
/>
<label for="flail">Flails</label>
</span>
</div>
<div>
<span>
<input
type="checkbox"
id="axe"
name="category"
class="weapon"
onchange="update()"
checked
/>
<label for="axe">Axes</label>
</span>
</div>
<div>
<span>
<input
type="checkbox"
id="greataxe"
name="category"
class="weapon"
onchange="update()"
checked
/>
<label for="greataxe">Greataxes</label>
</span>
</div>
<div>
<span>
<input
type="checkbox"
id="spear"
name="category"
class="weapon"
onchange="update()"
checked
/>
<label for="spear">Spears</label>
</span>
</div>
<div>
<span>
<input
type="checkbox"
id="great-spear"
name="category"
class="weapon"
onchange="update()"
checked
/>
<label for="great-spear">Great Spears</label>
</span>
</div>
<div>
<span>
<input
type="checkbox"
id="halberd"
name="category"
class="weapon"
onchange="update()"
checked
/>
<label for="halberd">Halberds</label>
</span>
</div>
<div>
<span>
<input
type="checkbox"
id="scythe"
name="category"
class="weapon"
onchange="update()"
checked
/>
<label for="scythe">Scythes</label>
</span>
</div>
<div>
<span>
<input
type="checkbox"
id="whip"
name="category"
class="weapon"
onchange="update()"
checked
/>
<label for="whip">Whips</label>
</span>
</div>
<div>
<span>
<input
type="checkbox"
id="fist"
name="category"
class="weapon"
onchange="update()"
checked
/>
<label for="fist">Fists</label>
</span>
</div>
<div>
<span>
<input
type="checkbox"
id="claw"
name="category"
class="weapon"
onchange="update()"
checked
/>
<label for="claw">Claws</label>
</span>
</div>
<div>
<span>
<input
type="checkbox"
id="colossal-weapon"
name="category"
class="weapon"
onchange="update()"
checked
/>
<label for="colossal-weapon">Colossal Weapons</label>
</span>
</div>
<div>
<span>
<input
type="checkbox"
id="torch"
name="category"
class="weapon"
onchange="update()"
checked
/>
<label for="torch">Torches</label>
</span>
</div>
<hr />
<div>
<b>Ranged</b>
</div>
<div>
<span>
<input type="checkbox" id="light-bow" name="category" />
<label for="light-bow">Light Bows</label>
</span>
</div>
<div>
<span>
<input type="checkbox" id="bow" name="category" />
<label for="bow">Bows</label>
</span>
</div>
<div>
<span>
<input type="checkbox" id="greatbow" name="category" />
<label for="greatbow">Greatbows</label>
</span>
</div>
<div>
<span>
<input type="checkbox" id="crossbow" name="category" />
<label for="crossbow">Crossbows</label>
</span>
</div>
<div>
<span>
<input type="checkbox" id="ballistas" name="category" />
<label for="ballistas">Ballistas</label>
</span>
</div>
<hr />
<div>
<b>Shields</b>
</div>
<div>
<span>
<input type="checkbox" id="small-shield" name="category" />
<label for="small-shield">Small Shields</label>
</span>
</div>
<div>
<span>
<input type="checkbox" id="medium-shield" name="category" />
<label for="medium-shield">Medium Shields</label>
</span>
</div>
<div>
<span>
<input type="checkbox" id="greatshield" name="category" />
<label for="greatshield">Greatshields</label>
</span>
</div>
<hr />
<div>
<b>Catalysts</b>
</div>
<div>
<span>
<input type="checkbox" id="glintstone-staff" name="category" />
<label for="glintstone-staff">Glintstone Staves</label>
</span>
</div>
<div>
<span>
<input type="checkbox" id="sacred-seal" name="category" />
<label for="sacred-seal">Sacred Seals</label>
</span>
</div>
</article>
</div>
</main>
<footer>
<h5>
Erdtree Planner (<a href="https://git.palmoe.dk/vodofrede/erdtree"
>available under BSD-3-Clause license</a
>)
Erdtree Planner (
<a href="https://git.palmoe.dk/vodofrede/erdtree">available under BSD-3-Clause license</a>
)
</h5>
<h5>Copyright 2022 vodofrede</h5>
</footer>