Choose when you eat between fights

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rope 2026-10-24 14:02:24 +01:00
parent 8afcba79fc
commit bc99a1e0c5
5 changed files with 43 additions and 5 deletions

22
game.py
View file

@ -26,6 +26,8 @@ MAX_LOG = 200
REGEN_PER_HOUR = 0.25 # share of max HP recovered per game hour
REST_RATE = 0.01 # share of max HP back per game second resting between fights...
BITE = 2.0 # ...and each bite of food takes this long, so food rests you faster
EAT_BELOW = 0.5 # unless you choose otherwise, you only eat while under this share of your HP...
EAT_CHOICES = (0, 0.25, 0.5, 0.75, 1.0) # ...and these are the choices (never, up to always)
KNOCKED_OUT_HP = 0.3 # share of max HP you come round with after being knocked out
KNOCKOUTS_TO_STOP = 3 # in a row, and you stop fighting
@ -2018,7 +2020,7 @@ def new_player(uid: str, name: str, cls: str, now: float) -> dict:
"hp": 44, "hp_at": now,
"action": None, "stopped": None,
"last_active": now, "overflow": "city",
"perks": {"bank_slot": 0}, "manual": [], "patterns": [],
"perks": {"bank_slot": 0}, "manual": [], "patterns": [], "eat_below": EAT_BELOW,
"rented": 0, "boosts": [], "bought": None, "deeds": {}, "owned": [], "look": dict(DEFAULT_LOOK),
"garrison": False,
"donated": 0,
@ -2211,14 +2213,16 @@ def _average_hit(max_hit: float, crit: float = CRIT_CHANCE) -> float:
def rest_plan(world: dict | None, player: dict, hp: float | None = None) -> tuple[float, dict]:
"""Resting back to full before a fight: how many game seconds, and the food eaten on the way.
A bite is only taken when it's quicker than resting, so better food makes for shorter rests."""
You eat while you're under the share of your HP you chose, and only when a bite is quicker than
resting, so better food makes for shorter rests. The rest of the way you rest."""
top = max_hp(player)
missing = top - (player["hp"] if hp is None else hp)
rate = top * REST_RATE * regen_boost(world, player) / ware(player, "rest", "combat")
hungry = top * (1 - player.get("eat_below", EAT_BELOW)) # eat while more than this is missing
seconds, eaten = 0.0, {}
for food in edible(player):
heal, left = ITEMS[food]["heal"], player["bank"].get(food, 0)
while missing > 0 and left and min(heal, missing) / rate > BITE:
while missing > hungry and missing > 0 and left and min(heal, missing) / rate > BITE:
eaten[food] = eaten.get(food, 0) + 1
left -= 1
missing -= heal
@ -2398,6 +2402,14 @@ def _input(world: dict, player: dict, now: float, kind: str, *args) -> str | Non
return None
def set_eat_below(player: dict, share) -> str | None:
"""Below what share of your HP you eat between fights (0: never, 1: whenever it's quicker)."""
if share not in EAT_CHOICES:
return "Pick one of the choices"
player["eat_below"] = share
return None
def learn_pattern(player: dict, item: str) -> str | None:
"""Read a pattern: from then on you can reforge its masterwork. The pattern's used up."""
spec = ITEMS.get(item, {})
@ -5964,6 +5976,8 @@ PATCH_NOTES = [
("new", "One unique per dungeon from its last boss (8% each), worn as a ring, amulet or trinket, that changes an "
"ability: One-Eye's fang, Ogre's knuckle, Barrow king's pendant, Warlord's whistle, Forgeheart, Rimeglass "
"lens, Wyrmscale quiver. Abilities it changes get a ✦."),
("new", "Choose when you eat between fights: below 25 / 50 / 75% of your HP, always, or never (the food slot, "
"under \"Eat below\"). Default 50%: above it you just rest, so a scratch doesn't cost food."),
]},
{"date": "2026-10-24", "title": "A dungeon in every area", "notes": [
("new", "Six more dungeons for 2–4, seven pulls each with two mini-bosses and a final boss: Goblin Warren "
@ -6081,7 +6095,7 @@ def content() -> dict:
"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, "order_max": ORDER_MAX, "input_share": INPUT_SHARE, "problems": PROBLEMS, "fittings": list(FITTING_BY_ID.values()),
"equip_slots": EQUIP_SLOTS, "class_speed": CLASS_SPEED, "rest_rate": REST_RATE, "bite": BITE,
"equip_slots": EQUIP_SLOTS, "class_speed": CLASS_SPEED, "rest_rate": REST_RATE, "bite": BITE, "eat_below": EAT_BELOW, "eat_choices": EAT_CHOICES,
"abilities": combat.ABILITIES, "enemy_abilities": combat.ENEMY_ABILITIES, "unlock": combat.UNLOCK, "auto_cd": combat.AUTO_CD, "watch": combat.WATCH, "gcd": combat.GCD,
"weapon_kits": combat.WEAPON_KITS, "group_size": GROUP_SIZE, "dungeon_size": DUNGEON_SIZE, "dungeon_wipes": DUNGEON_WIPES, "trade_ability": combat.TRADE_ABILITY, "potion_below": combat.POTION_BELOW,
"styles": STYLES, "damage_types": DAMAGE_TYPES, "weights": WEIGHTS, "vulnerable": VULNERABLE,