Equipment: pick a slot to swap gear from the bank; plain totals

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rope 2026-10-20 15:20:56 +01:00
parent 648272bdd9
commit 2f2681ba17
4 changed files with 52 additions and 23 deletions

View file

@ -1244,32 +1244,46 @@ function dollSlot(p, slot, label, outline, picked) {
}
function paperDoll(p, mine) {
const worn = DOLL.filter(([slot]) => p.equip[slot]).map(([slot]) => slot);
const pick = (dollPick && slot2(dollPick, p)) || (worn.includes("weapon") ? "weapon" : worn[0]) || "weapon";
const label = DOLL.find(([slot]) => slot === pick)[1];
const two = pick === "shield" && p.equip.weapon && item(p.equip.weapon).two_handed;
const id = two ? p.equip.weapon : p.equip[pick], it = id && item(id);
const detail = it ? `<div class="worn-head"><span class="ico">${it.icon}</span><span><b>${esc(it.name)}</b>
<span class="muted small">${label}${two ? " (two-handed weapon)" : ""}</span></span>
${mine && !two ? `<button class="btn sm" data-unequip="${pick}" title="Back to the bank">✕</button>` : ""}</div>
${gearChips(it, p)}`
: `<div class="muted small">${label}: nothing worn.${mine ? ` Equip from the <button class="linkish" data-nav="bank">bank</button>.` : ""}</div>`;
const st = C.styles[(p.equip.weapon && item(p.equip.weapon).style) || "sword"], dt = C.damage_types[st.damage];
const pick = dollPick && slot2(dollPick, p);
const totals = `<div class="doll-stats">
<span class="muted">${glyph("biceps", "#e06a6a")} Power</span><b>${p.power}</b>
<span class="muted">${glyph("checked-shield", "#d4dae2")} Armour</span><b>${p.armour}</b>
<span class="muted">${glyph("magic-shield", "#a77be8")} Ward</span><b>${p.ward}</b>
</div>`;
let side = totals;
if (pick) {
const label = DOLL.find(([slot]) => slot === pick)[1];
const two = pick === "shield" && p.equip.weapon && item(p.equip.weapon).two_handed;
const id = two ? p.equip.weapon : p.equip[pick], it = id && item(id);
side = `<div class="worn-head">${it ? `<span class="ico">${it.icon}</span><b>${esc(it.name)}</b>` : `<b>${label}</b><span class="muted small">empty</span>`}</div>
${it ? gearChips(it, p) : ""}${mine ? swapGrid(p, pick, two) : ""}${totals}`;
}
return `<div class="doll-wrap">
<div class="doll"><span class="doll-figure">${glyph("swordman", "#e6e8ee")}</span>
${DOLL.map(([slot, name, outline]) => dollSlot(p, slot, name, outline, slot === pick)).join("")}</div>
<div class="doll-side">
<div class="doll-detail">${detail}</div>
<div class="doll-stats">
<span>${glyph(dt.glyph, dt.tint)} ${dt.name}, a swing every ${st.interval}s</span>
<span class="muted">Power</span><b>${p.power}</b>
<span class="muted">${glyph("checked-shield", "#d4dae2")} Armour</span><b>${p.armour} <span class="muted small">-${Math.round(p.reduction * 100)}% physical</span></b>
<span class="muted">${glyph("magic-shield", "#a77be8")} Ward</span><b>${p.ward} <span class="muted small">-${Math.round(p.ward_reduction * 100)}% magic</span></b>
</div>
</div>
<div class="doll-side">${side}</div>
</div>`;
}
// What else in the bank fits the picked slot, best first: click one to put it on. For weapons the
// corner shows the damage type, so you can pick one for what you're about to fight.
function swapGrid(p, slot, two) {
const fits = Object.keys(p.bank).filter((id) => item(id).slot === slot)
.sort((a, b) => (item(b).tier ?? 0) - (item(a).tier ?? 0) || (item(b).power ?? 0) - (item(a).power ?? 0));
const tiles = fits.map((id) => {
const it = item(id), [skill, level] = it.req || [];
const why = two ? `Your ${item(p.equip.weapon).name.toLowerCase()} takes both hands`
: skill && p.levels[skill] < level ? `Needs ${skillOf(skill).name.toLowerCase()} ${level}` : "";
const corner = it.style ? dmgIcon(C.styles[it.style].damage) : "";
const tip = [it.name, gearStats(it), it.style ? (it.two_handed ? "two-handed" : "one-handed") : "", why].filter(Boolean).join(" · ");
return `<button class="doll-slot swap" data-equip="${id}" ${why ? "disabled" : ""} title="${esc(tip)}">${it.icon}
${corner ? `<span class="swap-type">${corner}</span>` : ""}${it.two_handed ? `<span class="hands">2H</span>` : ""}${p.bank[id] > 1 ? `<span class="swap-qty">${p.bank[id]}</span>` : ""}</button>`;
});
const off = p.equip[slot] && !two ? `<button class="doll-slot swap off" data-unequip="${slot}" title="Take it off, back to the bank">${glyph("cancel", "#98a1b4")}</button>` : "";
if (!tiles.length && !off) return `<div class="muted small">Nothing else in your bank fits here.</div>`;
return `<div class="swap-head muted small">Swap for</div><div class="swap-grid">${tiles.join("")}${off}</div>`;
}
// A picked slot only counts if it's one this character has.
function slot2(slot, p) {
return slot in p.equip ? slot : null;
@ -1380,7 +1394,7 @@ document.addEventListener("click", (e) => {
if (d.once) return act("/api/action", { id: d.once, once: true });
if ("stop" in d) return act("/api/stop", {});
if (d.doll) {
dollPick = d.doll;
dollPick = dollPick === d.doll ? null : d.doll;
return render();
}
if ("select" in d) {