From c2f046b9a5315edbf0c436d970cfa42b27ef5dd6 Mon Sep 17 00:00:00 2001 From: Supremist Date: Thu, 12 Mar 2026 00:15:04 +0200 Subject: Check Twin Takedown vs Double slice --- main.py | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 62 insertions(+), 13 deletions(-) (limited to 'main.py') diff --git a/main.py b/main.py index 65c9c45..3d4e154 100644 --- a/main.py +++ b/main.py @@ -1,4 +1,6 @@ import math + +from numpy._core import multiarray from character import CharacterPlan from distribution import Distribution from game import Difficulty, Roll, d @@ -62,22 +64,27 @@ def main(): show_stat("Treat Wounds 20 +1", treat) class StatsTest: - def __init__(self) -> None: + def __init__(self, difficulty = Difficulty.Moderate) -> None: # self.char_js = pb2e.download_character(pfb_id=160180) self.char_js = pb2e.open_character("quizrel2") self.char_plan = CharacterPlan(self.char_js) - self.creature_plan = CreaturePlan(default_difficulty=Difficulty.Moderate) + self.creature_plan = CreaturePlan(default_difficulty=difficulty) # self.creature_plan["reflex"] = Difficulty.High # self.creature_plan["ac"] = Difficulty.High self.char = self.char_plan.build(1) def add_weapons(self): - falcata = Weapon("falcata", "martial", "sword", 8, fatal=12) - sword = Weapon("pick", "martial", "pick", 6, fatal=10) - rapier = Weapon("rapier", "martial", "sword", 6, finesse=True, deadly=8) - urumi = Weapon("urumi", "martial", "flail", 6, deadly=10) - sword2 = Weapon("tricky pick", "martial", "pick", 6, fatal=10, backstabber=True) - self.char.weapons.extend([sword, falcata, rapier, sword2, urumi]) + wps = [Weapon("falcata", "martial", "sword", 8, fatal=12), + Weapon("trident", "martial", "spear", 8), + Weapon("pick", "martial", "pick", 6, fatal=10), + Weapon("rapier", "martial", "sword", 6, finesse=True, deadly=8), + Weapon("urumi", "martial", "flail", 6, deadly=10), + Weapon("tricky pick", "martial", "pick", 6, fatal=10, backstabber=True), + Weapon("shortsword", "simple", "sword", 6, agile=True), + Weapon("gauntlet", "simple", "brawling", 4, agile=True), + Weapon("light pick", "martial", "pick", 6, agile=True, fatal=8) + ] + self.char.weapons.extend(wps) def get_weapon(self, name): for wp in self.char.weapons: @@ -110,7 +117,7 @@ def make_check(name, bonus, dc): if isinstance(bonus, Distribution): bonus = bonus.expected() print(f"{name} {bonus:+} vs DC {dc}:", - Roll.short_str(roll), f"Total: {dc-bonus-10:+}") + Roll.short_str(roll), f"Total: {10+bonus-dc:+}") return roll def demoralize_test(): @@ -139,7 +146,7 @@ def demoralize_test(): frightened = roll.apply(lambda x: x if x >= Roll.Success else 0).expected() print("Frightened:", frightened) -def test3(): +def weapon_damage(): t = StatsTest() def calc_damage(level): t.set_level(level) @@ -152,15 +159,55 @@ def test3(): res = dict() for weapon in t.char.weapons: - attack = Attack(t.char, t.creature, weapon) + attack = Attack(t.char, t.creature, weapon, sneak=False) res[weapon.name] = attack.strike().expected() # res["hp"] = creature["hp"] return res # calc_damage(20) + levelup_view("Weapons Comparison", "Expected Damage", calc_damage) + +def twin_takedown_test(): + t = StatsTest() + # t.creature_plan["ac"] = Difficulty.Extreme + def calc_damage(level): + t.set_level(level) + res = dict() + wp1 = t.get_weapon("tricky pick") + wp2 = t.get_weapon("gauntlet") + + # Twin takedown + attack = Attack(t.char, t.creature, wp1, sneak=True) + dmg = attack.strike().expected() + attack.previous_attacks += 1 + attack.weapon = wp2 + dmg += attack.strike().expected() + res["Twin Takedown"] = dmg + + # Double slice + attack = Attack(t.char, t.creature, wp1, sneak=True) + dmg = attack.strike().expected() + attack.sneak = False + attack.weapon = wp2 + dmg += attack.strike().expected() + res["Double Slice"] = dmg + + return res levelup_view("Weapons Comparison", "Expected Damage", calc_damage) +def multiple_attacks(): + t = StatsTest() + t.set_level(5) + wp = t.get_weapon("Shortsword") + wp.agile = False + # t.creature["ac"] -= 1 + attack = Attack(t.char, t.creature, wp, sneak=True) + print(attack) + for _ in range(4): + attack.previous_attacks += 1 + print(attack) + def levelup_view(title, ylabel, fn): @@ -192,5 +239,7 @@ def levelup_view(title, ylabel, fn): if __name__ == '__main__': - # test4() - demoralize_test() + # weapon_damage() + twin_takedown_test() + # multiple_attacks() + # demoralize_test() -- cgit v1.2.3