Rapid Heal mends during fights
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
8425989df3
commit
636123e454
2 changed files with 24 additions and 8 deletions
20
game.py
20
game.py
|
|
@ -1567,11 +1567,11 @@ def max_hp(player: dict) -> int:
|
|||
return 40 + 4 * skill_level(player, "combat") + int(gear_bonus(player, "hp"))
|
||||
|
||||
|
||||
def regen(world: dict, player: dict, now: float, boost: float = 1) -> None:
|
||||
def regen(world: dict, player: dict, now: float) -> None:
|
||||
"""Heal for the time since HP was last settled."""
|
||||
if now > player["hp_at"]:
|
||||
top = max_hp(player)
|
||||
boost *= 2 if fitted(world, "enchanted_hearths") else 1
|
||||
boost = 2 if fitted(world, "enchanted_hearths") else 1
|
||||
boost *= 1 + gear_bonus(player, "regen") / 100
|
||||
per_second = top * REGEN_PER_HOUR * boost * speed(world) / HOUR
|
||||
player["hp"] = min(top, player["hp"] + (now - player["hp_at"]) * per_second)
|
||||
|
|
@ -1627,6 +1627,7 @@ def _variant_odds(player: dict, foe: dict, blessed: dict, brew: dict) -> dict:
|
|||
kill = foe["hp"] / (hit * _average_hit(me["max_hit"], me["crit"]) / me["interval"])
|
||||
taken = sum(_taken(me, kind) for kind in foe["attack"]) / len(foe["attack"])
|
||||
hurt = their_hit * (1 - me["block"]) * _average_hit(foe["max_hit"]) * taken / foe["interval"] * kill
|
||||
hurt = max(0, hurt - blessed["mend"] * max_hp(player) * kill)
|
||||
return {"hit": hit, "their_hit": their_hit, "max_hit": me["max_hit"], "affinity": me["affinity"],
|
||||
"their_max": max(1, round(foe["max_hit"] * max(_taken(me, kind) for kind in foe["attack"]))),
|
||||
"kill_time": kill, "damage": hurt}
|
||||
|
|
@ -1669,6 +1670,7 @@ def simulate_fight(world: dict, player: dict, action: dict, rng: random.Random)
|
|||
break
|
||||
if mine <= theirs:
|
||||
mine += me["interval"]
|
||||
hp = min(top, hp + blessed["mend"] * top * me["interval"]) # Rapid Heal mends a little each swing
|
||||
crit = rng.random() < me["crit"]
|
||||
landed = rng.random() < hit
|
||||
dealt = max(1, round(me["max_hit"] * CRIT_MULT if crit else rng.randint(1, me["max_hit"]))) if landed else 0
|
||||
|
|
@ -1720,10 +1722,12 @@ def simulate_fight(world: dict, player: dict, action: dict, rng: random.Random)
|
|||
# Melvor-style: bones become prayer points, active prayers cost points each
|
||||
# fight and give boosts while they last, and praying in a fight trains Prayer.
|
||||
|
||||
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, "regen": 2},
|
||||
{"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},
|
||||
|
|
@ -1733,7 +1737,7 @@ PRAYERS = [
|
|||
PRAYER_BY_ID = {prayer["id"]: prayer for prayer in PRAYERS}
|
||||
MAX_PRAYERS = 2
|
||||
PRAYER_XP_PER_POINT = 5
|
||||
NO_BLESSING = {"cost": 0, "power": 0, "taken": 1.0, "regen": 1, "wind": False}
|
||||
NO_BLESSING = {"cost": 0, "power": 0, "taken": 1.0, "mend": 0, "wind": False}
|
||||
|
||||
|
||||
def describe_prayer(prayer: dict) -> str:
|
||||
|
|
@ -1742,8 +1746,8 @@ def describe_prayer(prayer: dict) -> str:
|
|||
parts.append(f"-{round(prayer['reduce'] * 100)}% damage taken")
|
||||
if prayer.get("power"):
|
||||
parts.append(f"+{prayer['power']} power")
|
||||
if prayer.get("regen"):
|
||||
parts.append("HP recovers twice as fast")
|
||||
if prayer.get("mend"):
|
||||
parts.append(f"+{prayer['mend'] * 6000:g}% HP / min in fights")
|
||||
if prayer.get("wind"):
|
||||
parts.append("once per outing, revive at half HP")
|
||||
return ", ".join(parts)
|
||||
|
|
@ -1759,7 +1763,7 @@ def blessing(player: dict) -> dict:
|
|||
for prayer in active:
|
||||
taken *= 1 - prayer.get("reduce", 0)
|
||||
return {"cost": cost, "power": sum(p.get("power", 0) for p in active), "taken": taken,
|
||||
"regen": max([p.get("regen", 1) for p in active]), "wind": any(p.get("wind") for p in active)}
|
||||
"mend": sum(p.get("mend", 0) for p in active), "wind": any(p.get("wind") for p in active)}
|
||||
|
||||
|
||||
def set_prayers(player: dict, ids: list) -> str | None:
|
||||
|
|
@ -2132,7 +2136,7 @@ def process_player(world: dict, player: dict, now: float, rng: random.Random | N
|
|||
action = growing(player)
|
||||
if "enemy" in action and not can_start(world, player, action):
|
||||
if not current.get("fight"):
|
||||
regen(world, player, current["start"], blessing(player)["regen"])
|
||||
regen(world, player, current["start"])
|
||||
current["fight"] = simulate_fight(world, player, action, rng)
|
||||
duration = current["fight"]["duration"]
|
||||
else:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue