diff --git a/game.py b/game.py index f323ef4..5a2ddad 100644 --- a/game.py +++ b/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, diff --git a/static/app.js b/static/app.js index 1ef21fe..07d341b 100644 --- a/static/app.js +++ b/static/app.js @@ -1259,23 +1259,27 @@ function orderComposer() { const need = per * runs, have = S.me.bank[id] || 0, on = d.provide.includes(id); return `
- ${fmt(have)}
`; + ${item(id).icon}${on ? `✓` : ""} + ${fmt(have)} / ${fmt(need)}`; }).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 `
${a ? `
${item(d.item).icon}
${esc(item(d.item).name)}${maker}
` : ""} -
×
+
× + max ${fmt(C.order_max[d.kind])}
${slots ? `
${slots}
` : ""}
${COIN} ${d.kind === "gather" ? `each · ${fmt(gold)}` : ""}
-
+
+ ${why ? `${esc(why)}` : ""}
`; } @@ -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]); diff --git a/static/styles.css b/static/styles.css index 13c0ace..ee5d4a3 100644 --- a/static/styles.css +++ b/static/styles.css @@ -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; }