Dungeon loot: patterns, masterworks, relics, uniques
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
60b446acfd
commit
8afcba79fc
8 changed files with 358 additions and 18 deletions
|
|
@ -944,6 +944,104 @@ class DungeonTest(unittest.TestCase):
|
|||
self.assertGreaterEqual(joined[0][0], yell[0])
|
||||
|
||||
|
||||
class LootTest(unittest.TestCase):
|
||||
def smith(self, level=30):
|
||||
world = world_with(("sam", "miner"))
|
||||
p = world["players"]["sam"]
|
||||
p["xp"]["smithing"] = game.XP_TABLE[level]
|
||||
return world, p
|
||||
|
||||
def test_every_dungeon_has_relic_patterns_and_a_unique(self):
|
||||
for key in game.DUNGEONS:
|
||||
loot = game.ACTION_BY_ID[key]["loot"]
|
||||
self.assertEqual(len(loot["patterns"]), 7)
|
||||
self.assertTrue(game.ITEMS[loot["unique"]]["mods"])
|
||||
for pattern in loot["patterns"]:
|
||||
made = game.ITEMS[game.ITEMS[pattern]["pattern"]]
|
||||
self.assertEqual(made["req"], ["combat", game.DUNGEONS[key]["level"]])
|
||||
base = game.ITEMS[made["base"]]
|
||||
for stat in ("power", "armour"):
|
||||
if base.get(stat):
|
||||
self.assertGreater(made[stat], base[stat])
|
||||
|
||||
def test_bosses_drop_relics_and_patterns(self):
|
||||
ogre = game.DUNGEONS["dungeon_watchtower"]["pulls"][7][1]
|
||||
fight = {"pack": [dict(ogre[0])], "kills": ["e0"]}
|
||||
found = {}
|
||||
for seed in range(200):
|
||||
for item, qty in game.pack_loot(game.ACTION_BY_ID["dungeon_watchtower"], fight, random.Random(seed))[1].items():
|
||||
found[item] = found.get(item, 0) + qty
|
||||
self.assertEqual(found["watchtower_relic"], 400) # two, every time
|
||||
patterns = sum(qty for item, qty in found.items() if item.startswith("pattern_"))
|
||||
self.assertTrue(40 < patterns < 100) # about 35%
|
||||
self.assertGreater(found.get("ogres_knuckle", 0), 0)
|
||||
|
||||
def test_learn_a_pattern_and_reforge(self):
|
||||
world, p = self.smith()
|
||||
reforge = game.ACTION_BY_ID["reforge_ogre_forged_warhammer"]
|
||||
p["bank"] = {"iron_warhammer": 1, "watchtower_relic": 3}
|
||||
self.assertEqual(game.can_start(world, p, reforge), "Learn its pattern first")
|
||||
self.assertEqual(game.learn_pattern(p, "pattern_ogre_forged_warhammer"), "You don't have it")
|
||||
p["bank"]["pattern_ogre_forged_warhammer"] = 1
|
||||
p["xp"]["smithing"] = game.XP_TABLE[20]
|
||||
self.assertEqual(game.learn_pattern(p, "pattern_ogre_forged_warhammer"), "Needs smithing level 29")
|
||||
p["xp"]["smithing"] = game.XP_TABLE[30]
|
||||
self.assertIsNone(game.learn_pattern(p, "pattern_ogre_forged_warhammer"))
|
||||
self.assertNotIn("pattern_ogre_forged_warhammer", p["bank"])
|
||||
self.assertEqual(game.learn_pattern(p, "pattern_ogre_forged_warhammer"), "You don't have it")
|
||||
world["city"]["buildings"]["smithy"]["level"] = 5
|
||||
self.assertIsNone(game.start_action(world, p, "reforge_ogre_forged_warhammer", T0, once=True))
|
||||
game.process_player(world, p, T0 + 3600, random.Random(1))
|
||||
self.assertEqual(p["bank"].get("ogre_forged_warhammer"), 1)
|
||||
self.assertNotIn("watchtower_relic", p["bank"])
|
||||
|
||||
def ranger(self, *uniques):
|
||||
world = world_with(("ash", "ranger"))
|
||||
p = world["players"]["ash"]
|
||||
p["xp"]["combat"] = game.XP_TABLE[85]
|
||||
p["equip"].update(weapon="magic_bow", helmet="mammoth_leather_cap", body="mammoth_leather_body",
|
||||
legs="mammoth_leather_legs")
|
||||
for unique in uniques:
|
||||
p["equip"][game.ITEMS[unique]["slot"]] = unique
|
||||
p["hp"] = game.max_hp(p)
|
||||
p["bank"] = {"arrows": 1000}
|
||||
return world, p
|
||||
|
||||
def test_a_unique_changes_an_ability(self):
|
||||
world, p = self.ranger()
|
||||
self.assertEqual(game.fighter(p, game.NO_BLESSING, {})["mods"], {})
|
||||
plain = game.simulate_fight(world, p, game.ACTION_BY_ID["fight_scouts"], random.Random(4))
|
||||
world, p = self.ranger("wyrmscale_quiver")
|
||||
mods = game.fighter(p, game.NO_BLESSING, {})["mods"]
|
||||
self.assertEqual(mods["volley"], {"cost": 0, "c": 1.4})
|
||||
quivered = game.simulate_fight(world, p, game.ACTION_BY_ID["fight_scouts"], random.Random(4))
|
||||
self.assertGreater(game.member_of(plain, "ash")["shot"], 0)
|
||||
self.assertEqual(game.member_of(quivered, "ash")["shot"], 0) # no arrows
|
||||
|
||||
def test_a_pendant_mends_a_second_ally(self):
|
||||
world = world_with(("kay", "homesteader"), ("wil", "builder"), ("bo", "miner"))
|
||||
players = list(world["players"].values())
|
||||
for p in players:
|
||||
p["xp"]["combat"] = game.XP_TABLE[40]
|
||||
p["hp"] = game.max_hp(p)
|
||||
kay = world["players"]["kay"]
|
||||
kay["equip"].update(weapon="willow_staff", amulet="barrow_kings_pendant")
|
||||
ogre = game.ACTION_BY_ID["fight_ruins"]
|
||||
heals = 0
|
||||
for seed in range(5):
|
||||
fight = game.draw_fight(world, players, ogre, random.Random(seed))
|
||||
mends = [e for e in fight["events"] if e[1] == "kay" and e[3] == "heal" and e[6] == "mend"]
|
||||
heals += sum(1 for a, b in zip(mends, mends[1:]) if a[0] == b[0] and a[2] != b[2])
|
||||
self.assertGreater(heals, 0) # one cast, two people healed
|
||||
|
||||
def test_old_worlds_get_patterns(self):
|
||||
world, p = self.smith()
|
||||
del p["patterns"]
|
||||
world["version"] = 29
|
||||
game.migrate(world, T0)
|
||||
self.assertEqual(p["patterns"], [])
|
||||
|
||||
|
||||
class NewSkillsTest(unittest.TestCase):
|
||||
def test_tools_speed_up_gathering(self):
|
||||
world = world_with(("pia", "commoner"))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue