Firekeeping: tend all fires

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rope 2026-10-27 20:11:40 +00:00
parent 6e48c72d95
commit fd85580466
3 changed files with 45 additions and 7 deletions

19
game.py
View file

@ -1318,6 +1318,10 @@ ACTIONS = [
*[_action(f"tend_{fire}_{log}", "firekeeping", f"Tend the {spec['name'].lower()}", TIER_LEVELS[tier], 30, 0,
{log: 1}, special="tend", tend=fire, tier=tier, group=spec["name"])
for fire, spec in FIRES.items() for tier, log in enumerate(FIREWOOD)],
# Tending all: each log goes on the lowest fire with room in your pile.
*[_action(f"tend_all_{log}", "firekeeping", "Tend all fires", TIER_LEVELS[tier], 30, 0,
{log: 1}, special="tend", tend=None, tier=tier, group="All fires")
for tier, log in enumerate(FIREWOOD)],
]
# --- dungeon loot --------------------------------------------------------------
@ -2768,6 +2772,14 @@ def _room(fire: dict, player: dict, tier: int) -> float:
return -1 if short > cheaper + 1e-6 else max(0.0, short)
def tend_target(world: dict, player: dict, action: dict) -> str | None:
"""The fire a tend feeds, or None if the log won't fit: its own fire, or when tending
all, the one with the least fuel left among those with room in your pile."""
fires, tier = world["city"]["fires"], action["tier"]
room = [key for key in ([action["tend"]] if action["tend"] else FIRES) if _room(fires[key], player, tier) >= 0]
return min(room, key=lambda key: sum(chunk["left"] for chunk in fires[key]["fuel"]), default=None)
def feed_fire(world: dict, player: dict, fire_id: str, tier: int) -> float:
"""Put one log on your pile in a fire, pushing out your cheapest fuel if it's full. Returns the minutes added."""
fire, level = world["city"]["fires"][fire_id], skill_level(player, "firekeeping")
@ -2860,8 +2872,8 @@ def can_start(world: dict, player: dict, action: dict) -> str | None:
pooled = order["provided"].get(item, 0) if order else 0
if pooled + player["bank"].get(item, 0) < qty:
return f"Out of {ITEMS[item]['name'].lower()}"
if action.get("special") == "tend" and _room(world["city"]["fires"][action["tend"]], player, action["tier"]) < 0:
return f"Your pile in the {FIRES[action['tend']]['name'].lower()} is full"
if action.get("special") == "tend" and not tend_target(world, player, action):
return f"Your pile in the {FIRES[action['tend']]['name'].lower()} is full" if action["tend"] else "Your piles are all full"
if action.get("special") == "sabotage":
raid = upcoming_raid(world)
if not raid or intel_level(world, raid) < 3:
@ -3018,7 +3030,7 @@ def _complete(world: dict, player: dict, action: dict, now: float, rng: random.R
xp = DRILL_XP * (gain + boost) * mods["xp"]
threat["drilled"] = min(drill_needed(threat), threat.get("drilled", 0) + gain + boost)
if action.get("special") == "tend":
xp = TEND_XP[action["tier"]] * feed_fire(world, player, action["tend"], action["tier"]) * mods["xp"]
xp = TEND_XP[action["tier"]] * feed_fire(world, player, tend_target(world, player, action), action["tier"]) * mods["xp"]
if warmed:
_warm(world, player, action, xp, now)
if action.get("special") == "labour":
@ -6258,6 +6270,7 @@ ORDER_RECIPES, ORDER_RAW = _order_sources()
# line here (new / balance / fix), and a new release a new entry on top.
PATCH_NOTES = [
{"date": "2026-10-27", "title": "Prayer", "notes": [
("new", "Firekeeping: Tend all fires. Each log goes on the lowest fire with room in your pile."),
("new", "Added resource dumps for Leatherworking: Guard Jerkins"),
("fix", "+Q button: rounded corners."),
("fix", "Make box: number field sits in front of +Q."),