Prayer: bury on the spot, retuned costs

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rope 2026-10-27 08:39:34 +00:00
parent 40e5274c4e
commit a7ff97815f
5 changed files with 106 additions and 32 deletions

72
game.py
View file

@ -1291,8 +1291,8 @@ ACTIONS = [
_action("pack_fish", "cooking", "Pack fish rations", 1, 20, 6, {"cooked_shrimp": 2}, {"provisions": 1}, group="Rations"),
_action("drill_militia", "combat", "Drill the militia", 1, 60, 12, special="drill", group="Frontier"),
_action("bury_bones", "prayer", "Bury bones", 1, 10, 4, {"bones": 1}, special="bury", pp=2, group="Bury"),
_action("bury_big_bones", "prayer", "Bury big bones", 15, 10, 15, {"big_bones": 1}, special="bury", pp=6, group="Bury"),
_action("bury_dragon_bones", "prayer", "Bury dragon bones", 40, 12, 72, {"dragon_bones": 1}, special="bury", pp=20, group="Bury"),
_action("bury_big_bones", "prayer", "Bury big bones", 15, 10, 15, {"big_bones": 1}, special="bury", pp=3, group="Bury"),
_action("bury_dragon_bones", "prayer", "Bury dragon bones", 40, 12, 72, {"dragon_bones": 1}, special="bury", pp=5, group="Bury"),
_action("offer_bones", "prayer", "Offer bones at the temple", 1, 12, 7, {"bones": 1}, special="offer",
devotion=2, city={"temple": 1}, group="Offer at the temple"),
_action("offer_big_bones", "prayer", "Offer big bones", 15, 12, 25, {"big_bones": 1}, special="offer",
@ -1452,7 +1452,7 @@ BUILDINGS = {
"base": {"stone": 700, "bricks": 200, "cut_stone": 60, "provisions": 60},
"advanced": {"beam": 15, "rope": 40, "iron_nails": 150},
"late": {"willow_logs": 80, "oak_plank": 35, "hide_glue": 40, "steel_hinges": 20},
"effect": "Per level: +1 prayer point per bone, +25% devotion",
"effect": "Per level: +25% prayer points from bones, +25% devotion",
},
"granary": {
"name": "Granary", "icon": "🌾", "max": 3, "gold": 150,
@ -1524,7 +1524,7 @@ RAID_TRAITS = ["lightly armoured, heavy on archers", "mounted and fast, few bows
# --- world ---------------------------------------------------------------
WORLD_VERSION = 32
WORLD_VERSION = 33
def new_world(now: float, speed: float = 1.0) -> dict:
@ -1775,6 +1775,11 @@ def migrate(world: dict, now: float | None = None) -> dict:
for player in world["players"].values():
player.setdefault("queue", [])
world["version"] = 32
if world["version"] < 33:
# Bury on the spot: fight bones go straight to prayer points.
for player in world["players"].values():
player.setdefault("bury", True)
world["version"] = 33
return world
@ -2030,7 +2035,7 @@ def new_player(uid: str, name: str, cls: str, now: float) -> dict:
"pp": 0, "prayers": [], "potions": {},
"hp": 44, "hp_at": now,
"action": None, "stopped": None, "queue": [],
"last_active": now, "overflow": "city",
"last_active": now, "overflow": "city", "bury": True,
"perks": {"bank_slot": 0}, "manual": [], "patterns": [], "found": [], "eat_below": EAT_BELOW,
"rented": 0, "boosts": [], "bought": None, "deeds": {}, "owned": [], "look": dict(DEFAULT_LOOK),
"garrison": False,
@ -2499,18 +2504,18 @@ def pack_xp(fight: dict, killed_only: bool = False) -> float:
MEND = 0.0004 # Rapid Heal: share of max HP mended per second of fighting
PRAYERS = [
{"id": "thick_skin", "name": "Thick Skin", "icon": "🪨", "level": 1, "cost": 1, "reduce": 0.10},
{"id": "burst_of_strength", "name": "Burst of Strength", "icon": "💪", "level": 5, "cost": 1, "power": 5},
{"id": "rapid_heal", "name": "Rapid Heal", "icon": "💗", "level": 10, "cost": 1, "mend": MEND},
{"id": "steel_skin", "name": "Steel Skin", "icon": "🛡️", "level": 20, "cost": 2, "reduce": 0.20},
{"id": "superhuman_strength", "name": "Superhuman Strength", "icon": "🦾", "level": 30, "cost": 2, "power": 12},
{"id": "second_wind", "name": "Second Wind", "icon": "🌬️", "level": 40, "cost": 1, "wind": True},
{"id": "protection", "name": "Protection", "icon": "✨", "level": 50, "cost": 3, "reduce": 0.35},
{"id": "piety", "name": "Piety", "icon": "😇", "level": 60, "cost": 4, "power": 20, "reduce": 0.20},
{"id": "thick_skin", "name": "Thick Skin", "icon": "🪨", "level": 1, "cost": 2, "reduce": 0.10},
{"id": "burst_of_strength", "name": "Burst of Strength", "icon": "💪", "level": 5, "cost": 2, "power": 5},
{"id": "rapid_heal", "name": "Rapid Heal", "icon": "💗", "level": 10, "cost": 3, "mend": MEND},
{"id": "steel_skin", "name": "Steel Skin", "icon": "🛡️", "level": 20, "cost": 4, "reduce": 0.20},
{"id": "superhuman_strength", "name": "Superhuman Strength", "icon": "🦾", "level": 30, "cost": 6, "power": 12},
{"id": "second_wind", "name": "Second Wind", "icon": "🌬️", "level": 40, "cost": 3, "wind": True},
{"id": "protection", "name": "Protection", "icon": "✨", "level": 50, "cost": 9, "reduce": 0.35},
{"id": "piety", "name": "Piety", "icon": "😇", "level": 60, "cost": 12, "power": 20, "reduce": 0.20},
]
PRAYER_BY_ID = {prayer["id"]: prayer for prayer in PRAYERS}
MAX_PRAYERS = 2
PRAYER_XP_PER_POINT = 5
PRAYER_XP_PER_POINT = 3
NO_BLESSING = {"cost": 0, "power": 0, "taken": 1.0, "mend": 0, "wind": False}
@ -2554,8 +2559,34 @@ def set_prayers(player: dict, ids: list) -> str | None:
return None
def bone_points(world: dict, action: dict) -> int:
return action["pp"] + building_level(world, "temple") + fitted(world, "carved_altar")
def bone_points(world: dict, action: dict) -> float:
return action["pp"] * (1 + 0.25 * (building_level(world, "temple") + fitted(world, "carved_altar")))
BURY_LEVEL = {bone: ACTION_BY_ID[f"bury_{bone}"]["level"] for bone in ("bones", "big_bones", "dragon_bones")}
SPOT_BURY_XP = 0.5 # burying on the spot gives half the XP of burying by hand
def bury_on_the_spot(world: dict, player: dict, drops: dict, now: float, summary: dict) -> dict:
"""A won fight's bones go straight into prayer points and half the XP of burying by hand. Bones
above the player's Prayer level, or everything with the setting off, go to the bank."""
if not player.get("bury", True):
return drops
kept = dict(drops)
for bone, level in BURY_LEVEL.items():
count = kept.get(bone, 0)
if not count or skill_level(player, "prayer") < level:
continue
del kept[bone]
action = ACTION_BY_ID[f"bury_{bone}"]
for _ in range(count):
points = bone_points(world, action) * (1 + potion_effect(player, "prayer").get("bones", 0))
player["pp"] += points
summary["pp_gained"] += points
_use_charge(player, "prayer", summary)
xp = action["xp"] * count * SPOT_BURY_XP * skill_mods(world, action)["xp"]
gain_xp(world, player, "prayer", xp, now, summary)
return kept
def ward(world: dict) -> float:
@ -2944,7 +2975,7 @@ def _complete(world: dict, player: dict, action: dict, now: float, rng: random.R
player["owned"].append(emblem)
player["gold"] += gold
summary["gold"] += gold
for item, qty in drops.items():
for item, qty in bury_on_the_spot(world, player, drops, now, summary).items():
outputs[item] = outputs.get(item, 0) + qty
if action.get("special") == "sabotage":
raid = upcoming_raid(world)
@ -4887,7 +4918,7 @@ FITTINGS = [
("bellows", "Great bellows", "smithy", 3, 50, {"maple_plank": 30, "bear_leather": 15, "mithril_brackets": 6},
"Smithing 10% faster", "bellows", "#d0663a"),
("carved_altar", "Carved altar", "temple", 2, 60, {"yew_plank": 30, "cut_stone": 60, "adamant_chain": 4},
"+1 prayer point per bone, ward +15", "star-altar", "#6f9a4a"),
"+25% prayer points from bones, ward +15", "star-altar", "#6f9a4a"),
("enchanted_chests", "Enchanted chests", "storehouse", 4, 75, {"magic_plank": 40, "rune_lock": 6},
"+500 stack size", "open-treasure-chest", "#a77be8"),
("enchanted_hearths", "Enchanted hearths", "houses", 4, 80, {"magic_plank": 50, "mammoth_leather": 5, "adamant_chain": 6},
@ -6162,6 +6193,11 @@ ORDER_RECIPES, ORDER_RAW = _order_sources()
# What changed, shown on the Patch notes page. Newest first; every shipped change adds a
# line here (new / balance / fix), and a new release a new entry on top.
PATCH_NOTES = [
{"date": "2026-10-27", "title": "Prayer", "notes": [
("new", "Bury on the spot: bones from combat turns into prayer points and 1/2 bury XP as they drop. Toggle in the Prayer menu."),
("balance", "Prayer costs adjusted."),
("balance", "Prayer potions now relevant for new costs."),
]},
{"date": "2026-10-26", "title": "Fittings", "notes": [
("new", "Guild Roster shows player activity."),
("new", "Make X: \"Make one\" takes a count (1–1,000), then back to what you were doing."),