Weapon styles: warhammer, sword and shield, staff, bow; trophies in recipes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
19ccab4ac3
commit
4cb6ff5ec0
6 changed files with 244 additions and 24 deletions
|
|
@ -708,9 +708,10 @@ class TierTest(unittest.TestCase):
|
|||
|
||||
def test_every_tier_has_full_kit(self):
|
||||
for key, *_ in game.METALS:
|
||||
for piece in ("sword", "shield", "helmet", "legs", "body", "pickaxe", "axe", "hoe", "fishing_rod", "hunting_knife"):
|
||||
for piece in ("sword", "warhammer", "helmet", "legs", "body", "pickaxe", "axe", "hoe", "fishing_rod", "hunting_knife"):
|
||||
self.assertIn(f"{key}_{piece}", game.ITEMS)
|
||||
self.assertIn(f"smith_{key}_{piece}", game.ACTION_BY_ID)
|
||||
self.assertIn(f"make_{key}_shield", game.ACTION_BY_ID) # builders make shields
|
||||
for *_, prefix, _label, _level, _armour in game.LEATHERS:
|
||||
for piece in ("cap", "legs", "body"):
|
||||
self.assertIn(f"{prefix}_{piece}", game.ITEMS)
|
||||
|
|
@ -1317,6 +1318,62 @@ class TradeSkillsTest(unittest.TestCase):
|
|||
self.assertNotIn("plot2", h["action"])
|
||||
|
||||
|
||||
class WeaponStyleTest(unittest.TestCase):
|
||||
def armed(self, cls, weapon, shield=None, level=12):
|
||||
world = world_with(("pat", cls))
|
||||
p = world["players"]["pat"]
|
||||
p["xp"]["combat"] = game.XP_TABLE[level]
|
||||
p["hp"] = game.max_hp(p)
|
||||
p["equip"].update(weapon=weapon, shield=shield, body="iron_body", helmet="iron_helmet", legs="iron_legs")
|
||||
return world, p
|
||||
|
||||
def test_each_trade_fights_its_own_monster_best(self):
|
||||
styles = {"miner": "iron_warhammer", "builder": "iron_sword", "homesteader": "oak_staff", "ranger": "oak_bow"}
|
||||
prey = {"miner": "fight_clay_golem", "builder": "fight_cave_troll", "homesteader": "fight_will_o_wisp",
|
||||
"ranger": "fight_giant_bat"}
|
||||
for cls, weapon in styles.items():
|
||||
_world, p = self.armed(cls, weapon, "iron_shield" if cls == "builder" else None)
|
||||
times = {target: game.fight_odds(p, game.ACTION_BY_ID[target])["kill_time"] for target in prey.values()}
|
||||
self.assertEqual(min(times, key=times.get), prey[cls], cls)
|
||||
|
||||
def test_style_traits(self):
|
||||
_w, swordsman = self.armed("builder", "iron_sword", "iron_shield")
|
||||
_w, smith = self.armed("miner", "iron_warhammer")
|
||||
_w, archer = self.armed("ranger", "oak_bow")
|
||||
spec = lambda p: game.fighter(p, game.NO_BLESSING, {}, game.ACTION_BY_ID["fight_clay_golem"]["enemy"])
|
||||
self.assertEqual(spec(swordsman)["block"], game.BLOCK_CHANCE)
|
||||
self.assertEqual(spec(smith)["crit"], 0.10)
|
||||
self.assertEqual(spec(smith)["weakness"], 1.5)
|
||||
self.assertEqual(spec(archer)["weakness"], 0.5)
|
||||
_w, other = self.armed("builder", "iron_warhammer")
|
||||
self.assertGreater(spec(smith)["max_hit"], spec(other)["max_hit"]) # the trade's own weapon hits harder
|
||||
world, archer = self.armed("ranger", "oak_bow")
|
||||
fight = game.simulate_fight(world, archer, game.ACTION_BY_ID["fight_giant_bat"], random.Random(1))
|
||||
self.assertEqual(fight["events"][0][1], "you") # the bow strikes first
|
||||
|
||||
def test_two_handed_weapons_leave_no_room_for_a_shield(self):
|
||||
_w, p = self.armed("miner", "iron_warhammer")
|
||||
self.assertEqual(game.equip_problem(p, "iron_shield"), "Your iron warhammer takes both hands")
|
||||
self.assertTrue(game.ITEMS["oak_staff"]["two_handed"])
|
||||
self.assertIsNone(game.equip_problem(self.armed("builder", "iron_sword")[1], "iron_shield"))
|
||||
|
||||
def test_weapons_past_copper_need_trophies(self):
|
||||
for action_id, trophy in (("smith_iron_warhammer", "clay_core"), ("smith_iron_sword", "cave_troll_hide"),
|
||||
("make_iron_shield", "cave_troll_hide"), ("brew_oak_staff", "wisp_essence"),
|
||||
("lw_oak_bow", "bat_sinew"), ("smith_rune_warhammer", "runic_core")):
|
||||
self.assertIn(trophy, game.ACTION_BY_ID[action_id]["inputs"], action_id)
|
||||
for action_id in ("smith_copper_warhammer", "smith_copper_sword", "make_copper_shield",
|
||||
"brew_wooden_staff", "lw_wooden_bow"):
|
||||
self.assertFalse(any(item in game.TROPHIES for item in game.ACTION_BY_ID[action_id]["inputs"]), action_id)
|
||||
|
||||
def test_shield_smiths_stop_after_the_move(self):
|
||||
world = world_with(("kay", "miner"))
|
||||
world["version"] = 13
|
||||
world["players"]["kay"]["action"] = {"id": "smith_iron_shield", "start": T0}
|
||||
game.migrate(world, T0)
|
||||
self.assertIsNone(world["players"]["kay"]["action"])
|
||||
|
||||
|
||||
class FittingTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.world = world_with(("fred", "miner"))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue