Instant targeting, damage on bars, interrupted casts, no arrows
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
bc99a1e0c5
commit
049e2c771a
6 changed files with 85 additions and 41 deletions
20
combat.py
20
combat.py
|
|
@ -99,9 +99,9 @@ ABILITIES = {
|
|||
"barbed_arrow": {"name": "Barbed Arrow", "target": "enemy", "cd": 12,
|
||||
"effects": [_dmg(0.4), {"t": "dot", "c": 0.25, "every": 2, "dur": 12}], "auto": {"r": "dot"},
|
||||
"tip": "Hit, then bleeds 6× 0.25 over 12s."},
|
||||
"volley": {"name": "Volley", "target": "aoe", "cd": 10, "cost": 5,
|
||||
"volley": {"name": "Volley", "target": "aoe", "cd": 10,
|
||||
"effects": [{"t": "aoe", "c": 0.9}], "auto": {"r": "aoe", "n": 2},
|
||||
"tip": "Hits every enemy. 5 arrows."},
|
||||
"tip": "Hits every enemy."},
|
||||
# Trades: one each, whatever the weapon.
|
||||
"find_the_seam": {"name": "Find the Seam", "target": "enemy", "cd": 30, "offgcd": True,
|
||||
"effects": [_aura("seam", 8, "target")], "auto": {"r": "debuff", "pct": 0.6},
|
||||
|
|
@ -147,16 +147,13 @@ def known_abilities(style: str, cls: str, level: int, shield: bool) -> list[str]
|
|||
|
||||
def modded(ab: dict, mod: dict | None) -> dict:
|
||||
"""An ability as something you wear changes it: `cd` and `cast` multiply, `c` multiplies every
|
||||
effect's size, `dur` adds seconds to every effect that lasts, `cost` replaces the arrows it takes,
|
||||
and `extra` adds effects."""
|
||||
effect's size, `dur` adds seconds to every effect that lasts, and `extra` adds effects."""
|
||||
if not mod:
|
||||
return ab
|
||||
ab = {**ab, "effects": [dict(eff) for eff in ab["effects"]]}
|
||||
for key in ("cd", "cast"):
|
||||
if key in mod and ab.get(key):
|
||||
ab[key] = ab[key] * mod[key]
|
||||
if "cost" in mod:
|
||||
ab["cost"] = mod["cost"]
|
||||
for eff in ab["effects"]:
|
||||
if "c" in eff and "c" in mod:
|
||||
eff["c"] *= mod["c"]
|
||||
|
|
@ -267,7 +264,7 @@ def _member_unit(member: dict) -> dict:
|
|||
"kit": {a: modded(ABILITIES[a], me.get("mods", {}).get(a)) for a in me["abilities"]},
|
||||
"next": member["at"] + (0.5 if me["first"] else me["interval"]), "stun": 0.0, "target": None,
|
||||
"mend": member["mend"], "wind": member["wind"], "wind_used": False,
|
||||
"potion": member.get("potion") or 0, "drank": False, "arrows": member.get("arrows", 0), "shot": 0,
|
||||
"potion": member.get("potion") or 0, "drank": False,
|
||||
"dealt": 0, "hurt": 0, "down": False, "manual": set(member.get("manual", [])),
|
||||
"watch": member.get("watch", -1.0), "inputs": sorted(member.get("inputs", []), key=lambda i: i[0]),
|
||||
"seen": 0, "queued": None, "picked": False, "ftarget": None}
|
||||
|
|
@ -309,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"], shot=unit["shot"], down=unit["down"],
|
||||
drank=unit["drank"], down=unit["down"],
|
||||
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"])
|
||||
|
|
@ -453,8 +450,6 @@ def _ready(unit: dict, ab: dict, t: float, manual: bool) -> str | None:
|
|||
return "cooldown"
|
||||
if not ab.get("offgcd") and unit["busy"] + (0 if manual else AUTO_DELAY) > t + 1e-9:
|
||||
return "gcd"
|
||||
if ab.get("cost", 0) > unit["arrows"]:
|
||||
return "arrows"
|
||||
return None
|
||||
|
||||
|
||||
|
|
@ -477,7 +472,7 @@ def _think(state: dict, unit: dict, t: float, rng: random.Random) -> None:
|
|||
_use(state, unit, ab, target, t, rng, manual=True)
|
||||
if unit["cast"] or not ab.get("offgcd"):
|
||||
return
|
||||
elif why == "arrows" or t - queued["at"] > QUEUE:
|
||||
elif t - queued["at"] > QUEUE:
|
||||
unit["queued"] = None
|
||||
for ab_id in unit["abilities"]:
|
||||
ab = unit["kit"][ab_id]
|
||||
|
|
@ -516,9 +511,6 @@ def _manual_target(state: dict, unit: dict, ab: dict, given: str | None, t: floa
|
|||
|
||||
def _use(state: dict, unit: dict, ab: dict, target, t: float, rng: random.Random, manual: bool = False) -> None:
|
||||
unit["cds"][ab["id"]] = t + ab.get("cd", 0) * (1 if manual else AUTO_CD)
|
||||
if ab.get("cost"):
|
||||
unit["arrows"] -= ab["cost"]
|
||||
unit["shot"] += ab["cost"]
|
||||
if not ab.get("offgcd"):
|
||||
unit["busy"] = t + max(GCD, ab.get("cast", 0))
|
||||
if ab.get("cast"):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue