Presses count until you're really down, not forecast down
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
387f4c201b
commit
e6702871ff
3 changed files with 25 additions and 6 deletions
|
|
@ -257,7 +257,7 @@ VULNERABLE, RESISTANT = 1.25, 0.75
|
|||
def _member_unit(member: dict) -> dict:
|
||||
me = member["fighter"]
|
||||
return {"id": member["id"], "side": "party", "name": member["name"], "top": member["top"], "hp": member["hp_in"],
|
||||
"at": member["at"], "left": member["left"], "in": False, "out": None, "role": me["role"],
|
||||
"at": member["at"], "left": member["left"], "in": False, "out": None, "out_at": None, "role": me["role"],
|
||||
"damage": me["damage"], "interval": me["interval"], "accuracy": me["accuracy"], "evasion": me["evasion"],
|
||||
"crit": me["crit"], "block": me["block"], "taken": me["taken"], "base": me["base"],
|
||||
"abilities": list(me["abilities"]), "cds": {}, "busy": 0.0, "cast": None, "auras": [],
|
||||
|
|
@ -306,7 +306,7 @@ def run(fight: dict) -> dict:
|
|||
unit = units[member["id"]]
|
||||
won = result == "won" and unit["out"] in (None, "down") and unit["in"]
|
||||
member.update(hp=max(0, unit["hp"]), damage=unit["hurt"], dealt=unit["dealt"], wind_used=unit["wind_used"],
|
||||
drank=unit["drank"], down=unit["down"],
|
||||
drank=unit["drank"], down=unit["down"], out_at=unit["out_at"],
|
||||
result="won" if won else unit["out"] or ("left" if not unit["in"] else result))
|
||||
fight.update(events=state["events"], kills=state["kills"], result=result,
|
||||
end=_real(state, t), duration=(fight["rest"] + t) / fight["pace"])
|
||||
|
|
@ -906,7 +906,7 @@ def _fall(state: dict, unit: dict, t: float) -> None:
|
|||
|
||||
|
||||
def _out(state: dict, unit: dict, why: str, t: float) -> None:
|
||||
unit["out"], unit["cast"], unit["auras"] = why, None, []
|
||||
unit["out"], unit["out_at"], unit["cast"], unit["auras"] = why, t, None, []
|
||||
_event(state, t, unit["id"], unit["id"], why)
|
||||
for enemy in _enemies(state):
|
||||
enemy["threat"].pop(unit["id"], None)
|
||||
|
|
|
|||
7
game.py
7
game.py
|
|
@ -2375,10 +2375,10 @@ def _my_fight(world: dict, player: dict, now: float) -> tuple[dict, dict, float]
|
|||
fight, start = fight_clock(world, player)
|
||||
if not fight or now >= start + fight["duration"] or not any(m["id"] == player["id"] for m in fight["members"]):
|
||||
return "You're not fighting"
|
||||
member = member_of(fight, player["id"])
|
||||
if member["result"] in ("down", "left"):
|
||||
member, t = member_of(fight, player["id"]), fight_time(fight, start, now)
|
||||
if member.get("out_at") is not None and t >= member["out_at"]: # out by now, not just forecast to be
|
||||
return "You're out of this fight"
|
||||
return fight, member, fight_time(fight, start, now)
|
||||
return fight, member, t
|
||||
|
||||
|
||||
def watch_fight(world: dict, player: dict, now: float) -> None:
|
||||
|
|
@ -6094,6 +6094,7 @@ PATCH_NOTES = [
|
|||
("new", "DPS meter under the combat log: damage per second and total for each fighter, live. Shows the last fight while resting."),
|
||||
("new", "Improved raid UI"),
|
||||
("fix", "Bugfix: Combats started using \"Fight once\" can now be joined."),
|
||||
("fix", "Your buttons work until you're knocked out. A fight heading for a loss no longer locks you out early with \"You're out of this fight\" while you're still standing."),
|
||||
]},
|
||||
{"date": "2026-10-24", "title": "Dungeon loot", "notes": [
|
||||
("new", "Masterwork patterns: every dungeon boss can drop one of 7 (15% from a mini-boss, 35% from the last boss, "
|
||||
|
|
|
|||
|
|
@ -846,6 +846,24 @@ class ActivePlayTest(unittest.TestCase):
|
|||
self.p["action"] = None
|
||||
self.assertEqual(game.press(self.world, self.p, "crushing_blow", later), "You're not fighting")
|
||||
|
||||
def test_a_forecast_loss_can_still_be_turned(self):
|
||||
world = world_with(("ash", "miner"))
|
||||
p = world["players"]["ash"]
|
||||
p["xp"]["combat"] = game.XP_TABLE[20]
|
||||
p["equip"].update(weapon="steel_warhammer")
|
||||
p["hp"], p["last_active"] = game.max_hp(p), T0
|
||||
game.start_action(world, p, "fight_clay_golems", T0)
|
||||
game.process_player(world, p, T0, random.Random(2))
|
||||
fight = p["action"]["fight"]
|
||||
at = lambda t: T0 + (fight["rest"] + t) / fight["pace"]
|
||||
game.set_manual(world, p, "find_the_seam", True, T0)
|
||||
mine = game.member_of(fight, "ash")
|
||||
self.assertEqual(mine["result"], "down") # on auto from here, ash goes down...
|
||||
self.assertIsNone(game.press(world, p, "find_the_seam", at(38))) # ...but hasn't yet
|
||||
self.assertEqual(game.member_of(fight, "ash")["result"], "won")
|
||||
game.member_of(fight, "ash")["out_at"] = 30 # down for real (a party fights on)
|
||||
self.assertEqual(game.press(world, p, "find_the_seam", at(31)), "You're out of this fight")
|
||||
|
||||
def test_old_worlds_get_manual(self):
|
||||
del self.p["manual"]
|
||||
self.world["version"] = 27
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue