diff --git a/game.py b/game.py index a3fa585..5187793 100644 --- a/game.py +++ b/game.py @@ -539,13 +539,31 @@ def bank_room(world: dict, player: dict, item: str) -> int: return max(0, stack_size(world) - have) -def bank_add(world: dict, player: dict, item: str, qty: int, now: float, overflow: dict) -> int: - """Store what fits; the rest goes to the city (or is lost). Returns qty kept.""" +def city_uses(item: str) -> list[str]: + """What the city does with an item: the buildings that need it, the granary, the armoury.""" + uses = [spec["name"] for spec in BUILDINGS.values() + if any(item in spec.get(key, {}) for key in ("base", "advanced", "late", "final"))] + spec = ITEMS[item] + if "food" in spec: + uses.append("the granary") + if spec.get("slot") in ("weapon", "shield") or item == "arrows": + uses.append("the armoury") + return uses + + +def bank_add(world: dict, player: dict, item: str, qty: int, now: float, summary: dict) -> int: + """Store what fits; the rest goes to the city if it has a use, else is sold. Returns qty kept.""" keep = min(qty, bank_room(world, player, item)) if keep: player["bank"][item] = player["bank"].get(item, 0) + keep spill = qty - keep - if spill and player["overflow"] == "city": + if spill and player["overflow"] == "city" and not city_uses(item): + gold = int(spill * sell_price(world, item, now)) + player["gold"] += gold + summary["sold"][item] = summary["sold"].get(item, 0) + spill + summary["sold_gold"] += gold + elif spill and player["overflow"] == "city": + overflow = summary["overflow"] stockpile = world["city"]["stockpile"] stockpile[item] = stockpile.get(item, 0) + spill gain = spill * ITEMS[item]["value"] @@ -717,7 +735,7 @@ def _complete(world: dict, player: dict, action: dict, now: float, rng: random.R event["recon"] += action["recon"] for item, qty in outputs.items(): - kept = bank_add(world, player, item, qty, now, summary["overflow"]) + kept = bank_add(world, player, item, qty, now, summary) if kept: summary["items"][item] = summary["items"].get(item, 0) + kept gain_xp(world, player, action["skill"], xp, now, summary) @@ -739,7 +757,8 @@ def gain_xp(world: dict, player: dict, skill: str, xp: float, now: float, summar def empty_summary() -> dict: return {"done": 0, "items": {}, "overflow": {}, "xp": {}, "levels": [], "eaten": {}, "damage": 0, - "gold": 0, "wins": 0, "losses": 0, "lucky": 0, "stopped": None, "resumed": None} + "gold": 0, "wins": 0, "losses": 0, "lucky": 0, "stopped": None, "resumed": None, + "sold": {}, "sold_gold": 0} def process_player(world: dict, player: dict, now: float, rng: random.Random | None = None) -> dict: @@ -828,6 +847,8 @@ def donate(world: dict, player: dict, item: str, qty: int, now: float) -> str | gain = qty label = f"{qty:,} gold" else: + if not city_uses(item): + return "The city has no use for that" if player["bank"].get(item, 0) < qty: return "You don't have that many" bank_take(player, item, qty) @@ -1411,5 +1432,6 @@ def content() -> dict: return { "items": ITEMS, "skills": SKILLS, "classes": CLASSES, "actions": ACTIONS, "buildings": buildings, "xp_table": XP_TABLE, "offline_cap": OFFLINE_CAP, "tiers": TIERS, + "city_uses": {item: city_uses(item) for item in ITEMS}, "equip_slots": EQUIP_SLOTS, "eat_below": EAT_BELOW, "regen_per_hour": REGEN_PER_HOUR, } diff --git a/static/app.js b/static/app.js index a32adde..16ecacb 100644 --- a/static/app.js +++ b/static/app.js @@ -133,6 +133,8 @@ function showSummary(sum) { if (sum.lucky) toast(sum.lucky === 1 ? "โจ Double yield!" : `โจ ${sum.lucky} double yields!`, "level"); const spilled = Object.entries(sum.overflow); if (spilled.length) toast(`๐ฆ Bank full: ${spilled.map(([id, q]) => `${fmt(q)} ${item(id).name.toLowerCase()}`).join(", ")} went to the city`); + const sold = Object.entries(sum.sold || {}); + if (sold.length) toast(`๐ฆ Bank full: sold ${sold.map(([id, q]) => `${fmt(q)} ${item(id).name.toLowerCase()}`).join(", ")} for ${fmt(sum.sold_gold)} gold`); for (const [skill, level] of sum.levels) toast(`๐ ${skillOf(skill).name} level ${level}!`, "level"); if (sum.stopped) toast(`Stopped: ${sum.stopped}`, "bad"); if (sum.resumed) toast(`Back to ${C.actions.find((x) => x.id === sum.resumed).name.toLowerCase()}`); @@ -143,6 +145,7 @@ function awayModal(sum) { const xp = Object.entries(sum.xp).map(([id, q]) => `
You completed ${fmt(sum.done)} actions${sum.wins || sum.losses ? ` (${sum.wins} fights won, ${sum.losses} lost)` : ""}.
@@ -151,6 +154,7 @@ function awayModal(sum) { ${sum.gold ? `+${fmt(sum.gold)} gold
` : ""} ${xp ? `Your bank was full, so this was sold for ${fmt(sum.sold_gold)} gold:
Your bank was full, so this went to the city stockpile (for half the favour of giving it yourself):
Stopped: ${esc(sum.stopped)}
` : ""} `); @@ -453,7 +457,8 @@ function bank() {When an item doesn't fit:
-
Raids never touch your bank. Overflow sent to the city earns half the favour of giving it yourself.