even more drop stuff

This commit is contained in:
Your Name
2026-06-13 17:24:19 -04:00
parent 1367eab480
commit 32df06f583
3 changed files with 129 additions and 3 deletions
+92 -1
View File
@@ -16,6 +16,8 @@
},
};
const RARE_MODIFIER_VERSIONS = new Set(["v2", "bb"]);
function esc(value) {
return String(value ?? "")
.replaceAll("&", "&")
@@ -38,6 +40,88 @@
box.innerHTML = `<div class="drops-status ${kind ? `drops-status--${kind}` : ""}">${esc(message)}</div>`;
}
function currentVersion() {
return qs("#drops-version")?.value || "v1";
}
function rareModifierEnabled() {
return RARE_MODIFIER_VERSIONS.has(currentVersion());
}
function currentRareModifier() {
const select = qs("#drops-rare-modifier");
const pct = rareModifierEnabled() ? Number(select?.value || 0) : 0;
const label = select?.selectedOptions?.[0]?.textContent || "No modifier";
return { pct, label, multiplier: 1 + (pct / 100) };
}
function modifierMultiplierLabel(modifier) {
return `x${modifier.multiplier.toFixed(3).replace(/0+$/, "").replace(/\.$/, "")}`;
}
function updateRareModifierControls() {
const wrap = qs("#drops-rare-modifier-wrap");
const v2Note = qs("#drops-v2-note");
const select = qs("#drops-rare-modifier");
const enabled = rareModifierEnabled();
if (wrap) wrap.hidden = !enabled;
if (v2Note) v2Note.hidden = currentVersion() !== "v2";
if (!enabled && select) {
select.value = "0";
}
}
function formatOddsDenominator(value) {
if (!Number.isFinite(value) || value <= 0) return "—";
if (value >= 1000) {
return Math.round(value).toLocaleString();
}
if (value >= 100) {
return value.toFixed(1).replace(/\.0$/, "");
}
return value.toFixed(2).replace(/0+$/, "").replace(/\.$/, "");
}
function adjustedRate(rate) {
const text = String(rate || "");
const match = text.match(/^(\d+)\/(\d+)$/);
if (!match) return text || "—";
const num = Number(match[1]);
const den = Number(match[2]);
const modifier = currentRareModifier();
if (!rareModifierEnabled() || modifier.pct <= 0) {
return text;
}
const baseProbability = num / den;
const adjustedProbability = Math.min(1, baseProbability * modifier.multiplier);
if (adjustedProbability >= 1) {
return "1/1";
}
return `1/${formatOddsDenominator(1 / adjustedProbability)}`;
}
function rateCellHtml(rate) {
const base = String(rate || "—");
const adjusted = adjustedRate(base);
const modifier = currentRareModifier();
if (!rareModifierEnabled() || modifier.pct <= 0 || adjusted === base) {
return esc(base);
}
return esc(adjusted);
}
async function fetchJson(path) {
const res = await fetch(path, { cache: "no-store" });
if (!res.ok) throw new Error(`${path}: HTTP ${res.status}`);
@@ -149,7 +233,7 @@
<td data-label="Source">${esc(labelValue(row.source || "—"))}</td>
<td data-label="Item">${esc(item)}</td>
<td data-label="Item Code">${esc(itemCode)}</td>
<td data-label="Rate">${esc(row.rate || "—")}</td>
<td data-label="Rate">${rateCellHtml(row.rate || "—")}</td>
</tr>
`;
}).join("");
@@ -157,12 +241,17 @@
const truncation = rows.length > shown.length
? ` Showing first ${shown.length.toLocaleString()}.`
: "";
const modifier = currentRareModifier();
const modifierNote = rareModifierEnabled() && modifier.pct > 0
? `<span>Rate modifier: ${esc(modifier.label)} / ${esc(modifierMultiplierLabel(modifier))}</span>`
: "";
box.innerHTML = `
<div class="drops-summary">
<div>
<strong>Peeps ${esc(tableLabel)} drop table</strong>
<span>${rows.length.toLocaleString()} matching rows.${truncation}</span>
${modifierNote}
</div>
<span>${state.rows.length.toLocaleString()} total rows</span>
</div>
@@ -214,6 +303,7 @@
if (qs("#drops-search")) qs("#drops-search").value = "";
populateFilters(state.rows);
updateRareModifierControls();
if (qs("#drops-rare-mode")) qs("#drops-rare-mode").value = "";
if (qs("#drops-episode")) qs("#drops-episode").value = "";
@@ -245,6 +335,7 @@
document.addEventListener("DOMContentLoaded", () => {
qs("#drops-mode")?.addEventListener("change", updateMode);
qs("#drops-version")?.addEventListener("change", loadPeeps);
qs("#drops-rare-modifier")?.addEventListener("change", renderTable);
qs("#drops-rare-mode")?.addEventListener("change", (event) => {
state.filters.mode = event.target.value;
+22 -2
View File
@@ -8,7 +8,7 @@
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<link rel="stylesheet" href="style.css?v=drops-peeps-table-viewer-20260613-2">
<link rel="stylesheet" href="style.css?v=drops-peeps-table-viewer-20260613-3">
<script src="app.js?v=saves-synced-20260609-2" defer></script>
</head>
<body>
@@ -45,6 +45,26 @@
<option value="v3">V3</option>
<option value="bb">BB</option>
</select>
<p class="drops-field-note" id="drops-v2-note" hidden>V2 drop tables apply to PSO PC only.</p>
<div id="drops-rare-modifier-wrap" hidden>
<label for="drops-rare-modifier">Rare bonus modifier</label>
<select id="drops-rare-modifier">
<option value="0">No modifier</option>
<option value="0.1">Brutal Peeps +1 (+0.1%)</option>
<option value="0.2">Brutal Peeps +2 (+0.2%)</option>
<option value="0.5">Brutal Peeps +3 (+0.5%)</option>
<option value="0.6">Brutal Peeps +4 (+0.6%)</option>
<option value="0.8">Brutal Peeps +5 (+0.8%)</option>
<option value="0.9">Brutal Peeps +6 (+0.9%)</option>
<option value="1.0">Brutal Peeps +7 (+1.0%)</option>
<option value="2.0">Brutal Peeps +8 (+2.0%)</option>
<option value="3.0">Brutal Peeps +9 (+3.0%)</option>
<option value="4.0">Brutal Peeps +10 (+4.0%)</option>
<option value="5.0">Brutal Peeps +11 (+5.0%)</option>
</select>
<p class="drops-field-note">Applies to the Rate column for V2 PC and BB/V4.</p>
</div>
<label for="drops-rare-mode">Mode</label>
<select id="drops-rare-mode">
@@ -106,6 +126,6 @@
</div>
</footer>
</div>
<script src="drop-tables.js?v=drops-peeps-table-viewer-20260613-2" defer></script>
<script src="drop-tables.js?v=drops-peeps-table-viewer-20260613-6" defer></script>
</body>
</html>
+15
View File
@@ -2824,3 +2824,18 @@ button.inline-link,
}
}
.drops-field-note {
margin: 0.35rem 0 0.75rem;
color: rgba(255, 255, 255, 0.62);
font-size: 0.82rem;
}
.drops-rate-base {
display: block;
margin-top: 0.15rem;
color: rgba(255, 255, 255, 0.58);
font-size: 0.72rem;
white-space: nowrap;
}