Queue: tend all until full

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rope 2026-10-28 14:39:21 +00:00
parent e981e89e6c
commit 9daa648017
3 changed files with 43 additions and 12 deletions

View file

@ -800,7 +800,8 @@ function queuePanel() {
const a = recipe(e.id), why = me.blocked[e.id];
return `<li class="qp-row"><span class="qp-pos">${i + 1}</span>${a.icon}
<span class="qp-name">${esc(a.name)}${why ? `<span class="why small" title="Skipped if still short when its turn comes">${esc(why)}</span>` : ""}</span>
<input type="number" min="1" max="${C.make_max}" value="${e.n}" data-qset="${i}" data-keep="qset-${i}-${e.id}" title="How many">
${fills(a) ? `<span class="muted small" title="${esc(`${item(Object.keys(a.inputs)[0]).name} until your piles are full`)}">full</span>`
: `<input type="number" min="1" max="${C.make_max}" value="${e.n}" data-qset="${i}" data-keep="qset-${i}-${e.id}" title="How many">`}
${i || !now ? `<button class="btn sm" data-queue-move="${i}" data-to="${i - 1}" ${i ? "" : "disabled"} title="Up">▲</button>`
: `<button class="btn sm" data-queue-now="0" title="Swap with current">▲</button>`}
<button class="btn sm" data-queue-move="${i}" data-to="${i + 1}" ${i < q.length - 1 ? "" : "disabled"} title="Down">▼</button>
@ -808,7 +809,7 @@ function queuePanel() {
}).join("");
return `<div class="queue-panel">
<div class="qp-head"><b>⏳ Queue</b><span class="muted small">${q.length}</span><button class="x" data-queue-menu title="Close">✕</button></div>
${now ? `<div class="qp-row now">${now.icon}<span class="qp-name">${esc(now.name)}<span class="muted small">${fmt(me.action.left)} left</span></span>
${now ? `<div class="qp-row now">${now.icon}<span class="qp-name">${esc(now.name)}<span class="muted small">${fills(now) ? "until full" : `${fmt(me.action.left)} left`}</span></span>
<button class="btn sm" data-queue-now="0" ${q.length ? "" : "disabled"} title="Swap with next">▼</button>
<button class="btn sm" data-queue-skip title="Drop this make, on to the next">Skip</button></div>` : ""}
${rows ? `<ol class="qp-list">${rows}</ol>` : `<p class="muted small">Empty. +Q on a recipe or gathering adds to it.</p>`}
@ -817,8 +818,12 @@ function queuePanel() {
</div>`;
}
// A queued tend has no count: it runs until your piles are full.
const fills = (a) => a.special === "tend";
const queueCount = (a, n) => fills(a) ? "full" : `×${fmt(n)}`;
function queueTip() {
return `Queued: ${S.me.queue.map((q) => `${C.actions.find((x) => x.id === q.id).name} ×${fmt(q.n)}`).join(" → ")}`;
return `Queued: ${S.me.queue.map((q) => { const a = C.actions.find((x) => x.id === q.id); return `${a.name} ${queueCount(a, q.n)}`; }).join(" → ")}`;
}
// Makes lined up after this one: tap ✕ to drop one.
@ -827,7 +832,7 @@ function queueRow() {
if (!q.length) return "";
return `<div class="queue small">⏳ ${q.map((e, i) => {
const a = C.actions.find((x) => x.id === e.id);
return `<span class="item-chip" title="${esc(a.name)}">${a.icon} ×${fmt(e.n)}<button class="x" data-unqueue="${i}" title="Remove">✕</button></span>`;
return `<span class="item-chip" title="${esc(a.name)}">${a.icon} ${queueCount(a, e.n)}<button class="x" data-unqueue="${i}" title="Remove">✕</button></span>`;
}).join(`<span class="arrow">→</span>`)}</div>`;
}
@ -1165,6 +1170,7 @@ function tendAllTarget() {
function firekeepingPage() {
const me = S.me, fk = me.firekeeping, pick = pickFirewood(), speed = Object.values(S.city.fires)[0].speed;
const all = `tend_all_${C.firewood[pick]}`, tendingAll = me.action?.id.startsWith("tend_all_"), allWhy = me.blocked[all];
const making = Boolean(me.action?.left), qWhy = me.queue_why[all] || (!making && allWhy);
const perLog = (tier) => +(C.tend_xp[tier] * fk.minutes).toFixed(1);
const logs = C.firewood.map((log, tier) => {
const level = tendLevel(tier), locked = me.levels.firekeeping < level;
@ -1175,7 +1181,8 @@ function firekeepingPage() {
<span class="tag" title="Fire and XP per log">${glyph("stopwatch", "#98a1b4")} ${dur(fk.minutes * 60 / speed)} · ${perLog(pick)} XP</span>
<span class="tag" title="Most fuel you can bank in a fire">${glyph("campfire", "#98a1b4")} ${dur(fk.bank * 60 / speed)}</span>
${tendingAll ? `<button class="btn danger" data-stop>Stop</button>`
: `<button class="btn primary" data-start="${all}" ${allWhy ? "disabled" : ""} title="${esc(allWhy || "Each log goes on the lowest fire with room in your pile")}">🔥 Tend all</button>`}</div>
: `<button class="btn primary" data-start="${all}" ${allWhy ? "disabled" : ""} title="${esc(allWhy || "Each log goes on the lowest fire with room in your pile")}">🔥 Tend all</button>`}
<button class="btn q" data-queue-add="${all}" ${qWhy ? "disabled" : ""} title="${esc(qWhy || (making ? "Queue: tend all until full after the current make" : "Tend all until full, then back to what you were doing"))}">+Q</button></div>
<div class="fire-grid">${Object.keys(C.fires).map((id) => fireCard(id, pick, tendAllTarget())).join("")}</div>
<div class="section-title">Kindling</div>
<div class="grid">${C.actions.filter((a) => a.skill === "firekeeping" && a.group === "Kindling").map(actionCard).join("")}</div>`;
@ -3079,6 +3086,7 @@ document.addEventListener("click", (e) => {
if (d.once) return act("/api/action", { id: d.once, once: 1 });
if ("stop" in d) return act("/api/stop", {});
if (d.unqueue) return act("/api/queue/remove", { index: Number(d.unqueue) });
if (d.queueAdd) return act("/api/queue", { id: d.queueAdd, qty: 1 });
if ("queueMenu" in d) { queueOpen = !queueOpen; return render(); }
if (d.queueMove) return act("/api/queue/move", { index: Number(d.queueMove), to: Number(d.to) });
if (d.queueNow) return act("/api/queue/now", { index: Number(d.queueNow) });