Work order composer: have / need on reagents, max quantity, reason by Post
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
d03f0035eb
commit
79740d9a86
3 changed files with 13 additions and 7 deletions
6
game.py
6
game.py
|
|
@ -2060,7 +2060,7 @@ def stop(player: dict, reason: str | None = None) -> None:
|
|||
|
||||
ORDER_LIMIT = 5 # open orders per player
|
||||
ORDER_DAYS = 3 # before an order expires and is refunded
|
||||
ORDER_MAX = {"craft": 50, "gather": 2000}
|
||||
ORDER_MAX = {"craft": 500, "gather": 2000}
|
||||
|
||||
|
||||
def _order_sources() -> tuple[dict, dict]:
|
||||
|
|
@ -2094,7 +2094,7 @@ def post_order(world: dict, player: dict, kind: str, item: str, qty, provide, re
|
|||
if not source:
|
||||
return "Nobody can make that" if kind == "craft" else "Nobody gathers that"
|
||||
if not isinstance(qty, int) or not 1 <= qty <= ORDER_MAX[kind]:
|
||||
return "Bad quantity"
|
||||
return f"1 to {ORDER_MAX[kind]}"
|
||||
if not isinstance(reward, int) or reward < 0:
|
||||
return "Bad reward"
|
||||
if sum(o["by"] == player["id"] and o["status"] == "open" for o in world["orders"]) >= ORDER_LIMIT:
|
||||
|
|
@ -3887,7 +3887,7 @@ def content() -> dict:
|
|||
"city_uses": {item: city_uses(item) for item in ITEMS},
|
||||
"prayers": [{**prayer, "text": describe_prayer(prayer)} for prayer in PRAYERS], "max_prayers": MAX_PRAYERS,
|
||||
"potion_charges": POTION_CHARGES, "order_recipes": ORDER_RECIPES, "order_raw": ORDER_RAW,
|
||||
"order_limit": ORDER_LIMIT, "problems": PROBLEMS, "fittings": list(FITTING_BY_ID.values()),
|
||||
"order_limit": ORDER_LIMIT, "order_max": ORDER_MAX, "problems": PROBLEMS, "fittings": list(FITTING_BY_ID.values()),
|
||||
"equip_slots": EQUIP_SLOTS, "eat_below": EAT_BELOW, "class_speed": CLASS_SPEED,
|
||||
"styles": STYLES, "damage_types": DAMAGE_TYPES, "weights": WEIGHTS, "vulnerable": VULNERABLE,
|
||||
"resistant": RESISTANT, "class_style": CLASS_STYLE, "block_chance": BLOCK_CHANCE,
|
||||
|
|
|
|||
|
|
@ -1259,23 +1259,27 @@ function orderComposer() {
|
|||
const need = per * runs, have = S.me.bank[id] || 0, on = d.provide.includes(id);
|
||||
return `<div class="ro-slot ${on ? "filled" : "open"}"><button class="doll-slot ${on ? "on" : "empty-req"}" data-provide="${id}"
|
||||
${!on && have < need ? `disabled title="${esc(`${item(id).name}: ${fmt(have)} / ${fmt(need)}`)}"` : `title="${esc(item(id).name)}"`}>
|
||||
${item(id).icon}<span class="swap-qty">${fmt(need)}</span>${on ? `<span class="tick">✓</span>` : ""}</button>
|
||||
<span class="ro-have ${have < need ? "bad" : "muted"}">${fmt(have)}</span></div>`;
|
||||
${item(id).icon}${on ? `<span class="tick">✓</span>` : ""}</button>
|
||||
<span class="ro-have ${have < need ? "bad" : "good"}">${fmt(have)} / ${fmt(need)}</span></div>`;
|
||||
}).join("");
|
||||
}
|
||||
}
|
||||
const gold = d.kind === "craft" ? d.reward : d.reward * d.qty;
|
||||
const why = !a ? "" : d.qty > C.order_max[d.kind] ? `Max ${fmt(C.order_max[d.kind])}`
|
||||
: gold > S.me.gold ? `Gold ${fmt(S.me.gold)} / ${fmt(gold)}` : "";
|
||||
return `<div class="panel compose">
|
||||
<div class="tabs" style="margin:0 0 14px"><button class="tab ${d.kind === "craft" ? "on" : ""}" data-draft-kind="craft">Craft</button>
|
||||
<button class="tab ${d.kind === "gather" ? "on" : ""}" data-draft-kind="gather">Materials</button></div>
|
||||
<div class="compose-grid">
|
||||
<div><select data-draft="item"><option value="">Item…</option>${options}</select>
|
||||
${a ? `<div class="ro-pick"><span class="doll-slot on">${item(d.item).icon}</span><div><b>${esc(item(d.item).name)}</b>${maker}</div></div>` : ""}
|
||||
<div class="stepper">×<input type="number" min="1" value="${d.qty}" data-draft="qty"></div></div>
|
||||
<div class="stepper">×<input type="number" min="1" max="${C.order_max[d.kind]}" value="${d.qty}" data-draft="qty">
|
||||
<span class="muted small">max ${fmt(C.order_max[d.kind])}</span></div></div>
|
||||
<div>${slots ? `<div class="ro-slots big">${slots}</div>` : ""}</div>
|
||||
<div><div class="reward-input">${COIN}<input type="number" min="0" value="${d.reward}" data-draft="reward">
|
||||
${d.kind === "gather" ? `<span class="muted small">each · ${fmt(gold)}</span>` : ""}</div>
|
||||
<button class="btn primary" data-order-post ${a && gold <= S.me.gold ? "" : "disabled"}>Post</button></div>
|
||||
<div class="btns"><button class="btn primary" data-order-post ${a && !why ? "" : "disabled"}>Post</button>
|
||||
${why ? `<span class="why">${esc(why)}</span>` : ""}</div></div>
|
||||
</div></div>`;
|
||||
}
|
||||
|
||||
|
|
@ -1667,6 +1671,7 @@ document.addEventListener("change", (e) => {
|
|||
if (!list[draft.item]) draft.item = "";
|
||||
} else {
|
||||
draft[key] = Math.max(key === "qty" ? 1 : 0, Math.floor(Number(e.target.value) || 0));
|
||||
if (key === "qty") draft.qty = Math.min(draft.qty, C.order_max[draft.kind]);
|
||||
if (key === "qty" && draft.kind === "craft" && draft.item) {
|
||||
// Drop provided reagents the bank can no longer cover at the new quantity.
|
||||
const a = C.actions.find((x) => x.id === C.order_recipes[draft.item]), runs = Math.ceil(draft.qty / a.outputs[draft.item]);
|
||||
|
|
|
|||
|
|
@ -602,3 +602,4 @@ button.sheet-skill:hover { background: var(--panel-2); }
|
|||
.reward-input { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
|
||||
.reward-input input { width: 110px; }
|
||||
@media (max-width: 900px) { .compose-grid { grid-template-columns: 1fr; gap: 14px; } }
|
||||
.compose .why { color: var(--warn); font-weight: 600; font-size: 13px; }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue