Combat engine: swing-by-swing fights, Frontier and expeditions, trophies
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
2ca90c43c0
commit
19ccab4ac3
7 changed files with 395 additions and 115 deletions
|
|
@ -160,9 +160,9 @@ class ActionTest(unittest.TestCase):
|
|||
p = world["players"]["wil"]
|
||||
p["bank"] = {"bread": 500}
|
||||
game.start_action(world, p, "fight_wolves", T0)
|
||||
summary = game.process_player(world, p, T0 + 60 * 100, random.Random(5))
|
||||
self.assertEqual(summary["done"], 100)
|
||||
self.assertEqual(summary["wins"] + summary["losses"], 100)
|
||||
summary = game.process_player(world, p, T0 + 3600, random.Random(5))
|
||||
self.assertGreater(summary["done"], 50) # a fight lasts as long as it takes
|
||||
self.assertEqual(summary["wins"] + summary["losses"], summary["done"])
|
||||
self.assertEqual(p["gold"], summary["wins"] * 2)
|
||||
|
||||
|
||||
|
|
@ -490,7 +490,7 @@ class CombatTest(unittest.TestCase):
|
|||
summary = game.process_player(world, p, T0 + 60 * 60, random.Random(4))
|
||||
self.assertGreater(summary["damage"], 0)
|
||||
self.assertGreater(summary["eaten"].get("bread", 0), 0)
|
||||
self.assertEqual(p["bank"]["bread"], 100 - summary["eaten"]["bread"])
|
||||
self.assertEqual(p["bank"].get("bread", 0), 100 - summary["eaten"]["bread"])
|
||||
self.assertGreaterEqual(p["hp"], 1)
|
||||
|
||||
def test_out_of_food_means_retreat_and_nothing_lost(self):
|
||||
|
|
@ -515,9 +515,25 @@ class CombatTest(unittest.TestCase):
|
|||
world, bare = self.fighter(level=10)
|
||||
_, armoured = self.fighter(level=10, helmet="iron_helmet", body="iron_body", legs="iron_legs")
|
||||
_, veteran = self.fighter(level=60)
|
||||
wolves = game.ACTION_BY_ID["fight_scouts"]
|
||||
self.assertLess(game.fight_damage(armoured, wolves), game.fight_damage(bare, wolves) * 0.7)
|
||||
self.assertLess(game.fight_damage(veteran, wolves), game.fight_damage(bare, wolves))
|
||||
scouts = game.ACTION_BY_ID["fight_scouts"]
|
||||
hurt = lambda p: game.fight_odds(p, scouts)["damage"]
|
||||
self.assertLess(hurt(armoured), hurt(bare) * 0.7)
|
||||
self.assertLess(hurt(veteran), hurt(bare))
|
||||
self.assertGreater(game.fight_odds(veteran, scouts)["hit"], game.fight_odds(bare, scouts)["hit"])
|
||||
|
||||
def test_a_fight_is_played_out_swing_by_swing(self):
|
||||
world, p = self.fighter(level=10, weapon="iron_sword")
|
||||
p["bank"] = {"bread": 50}
|
||||
game.start_action(world, p, "fight_scouts", T0)
|
||||
game.process_player(world, p, T0 + 1, random.Random(2))
|
||||
fight = p["action"]["fight"] # simulated, waiting to finish, for the page to replay
|
||||
self.assertEqual(fight["result"], "won")
|
||||
self.assertTrue(all(e[1] in ("you", "foe") and e[2] in ("hit", "crit", "miss", "eat", "wind") for e in fight["events"]))
|
||||
self.assertEqual(fight["events"][-1][5], 0) # the last swing finished it
|
||||
self.assertAlmostEqual(fight["duration"], fight["end"] + game.RESPAWN, places=1)
|
||||
summary = game.process_player(world, p, T0 + fight["duration"] + 0.5, random.Random(2))
|
||||
self.assertEqual(summary["wins"], 1)
|
||||
self.assertEqual(p["hp"], fight["hp"])
|
||||
|
||||
def test_preferred_food_is_eaten_first(self):
|
||||
world, p = self.fighter()
|
||||
|
|
@ -764,12 +780,12 @@ class PrayerTest(unittest.TestCase):
|
|||
def test_prayers_cost_points_cut_damage_and_train_prayer(self):
|
||||
world, p = self.priest(level=10)
|
||||
scouts = game.ACTION_BY_ID["fight_scouts"]
|
||||
plain = game.fight_damage(p, scouts)
|
||||
plain = game.fight_odds(p, scouts)["damage"]
|
||||
game.set_prayers(p, ["thick_skin", "burst_of_strength"])
|
||||
p["pp"] = 4
|
||||
blessed = game.blessing(p)
|
||||
self.assertEqual(blessed["cost"], 2)
|
||||
self.assertLess(game.fight_damage(p, scouts, blessed), plain * 0.9)
|
||||
self.assertLess(game.fight_odds(p, scouts)["damage"], plain * 0.9)
|
||||
p["bank"] = {"bread": 200}
|
||||
game.start_action(world, p, "fight_scouts", T0)
|
||||
summary = game.process_player(world, p, T0 + 600, random.Random(1))
|
||||
|
|
@ -884,8 +900,10 @@ class HerbloreTest(unittest.TestCase):
|
|||
game.use_potion(p, "defence_potion_6")
|
||||
game.start_action(world, p, "fight_scouts", T0)
|
||||
scouts = game.ACTION_BY_ID["fight_scouts"]
|
||||
brewed = game.with_potion(game.NO_BLESSING, game.potion_effect(p, "combat"))
|
||||
self.assertAlmostEqual(game.fight_damage(p, scouts, brewed), game.fight_damage(p, scouts) * 0.70)
|
||||
brewed = game.fight_odds(p, scouts)["damage"]
|
||||
active = p["potions"].pop("combat")
|
||||
self.assertAlmostEqual(brewed, game.fight_odds(p, scouts)["damage"] * 0.70, delta=0.2)
|
||||
p["potions"]["combat"] = active
|
||||
summary = game.process_player(world, p, T0 + 75 * 10, random.Random(1))
|
||||
self.assertEqual(p["potions"]["combat"]["charges"], game.POTION_CHARGES - summary["done"])
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue