class FireStaff(item.Equippable): """a staff that enables people to craft weapons""" target = inventory.EquipTarget("right hand") # interestingly, a staff uses can vary by class @character.Command.with_traits(filter=character.Filter( character.Filter.WHITELIST, [Wizard] )) def fireball(self, char, args): """Cast a fireball at a target.""" target = find_player(char, args[1:]) if target is not None: target.message(f"{char} hit you with a fireball.") char.message(f"You hit {target} with a fireball.") @character.Command.with_traits(filter=character.Filter( character.Filter.WHITELIST, [Brute] )) def hit(self, char, args): """Hit target with this staff.""" target = find_player(char, args[1:]) if target is not None: target.message(f"{char} hit you with a staff.") char.message(f"You hit {target} with a staff.")
def test_cmd_unequip(self): """test that the unequip command works properly""" self.bill.inv.add_item(Sword()) self.bill.inv.add_item(Hat()) # equip the sword and hat self.bill.equip(Sword(), from_inv=True) self.bill.equip(Hat(), from_inv=True) # purge the equip messages self.bill.msgs.clear() # create a reference copy of the equip_dict for testing ref = self.bill.equip_dict.copy() # try to unequip a non-existent item self.bill.command("unequip flesh") self.assertEqual(self.bill.msgs.pop(), "Could not find equipped item 'flesh'.") # equipped items should be unaffected self.assertEqual(ref, self.bill.equip_dict) # now try unequipping the hat self.bill.command("unequip hat") self.assertEqual(self.bill.msgs.pop(), "unequip Hat") # hat should be removed from our equip_dict ref[inv.EquipTarget("head")] = None self.assertEqual(self.bill.equip_dict, ref) # hat should be added back to inventory self.assertEqual(self.bill.inv, inv.Inventory((Hat(), 1))) # now try unequipping the hat again self.bill.command("unequip hat") self.assertEqual(self.bill.msgs.pop(), "Could not find equipped item 'hat'.") self.assertEqual(ref, self.bill.equip_dict) # try unequipping the sword (should be case-insensitive) self.bill.command("unequip SwOrD") self.assertEqual(self.bill.msgs.pop(), "unequip Sword") # sword should be removed from our equip_dict ref[inv.EquipTarget("right hand")] = None self.assertEqual(self.bill.equip_dict, ref) # sword should be added back to inventory inv_items = [(Hat(), 1), (Sword(), 1)] self.assertEqual(self.bill.inv, inv.Inventory(*inv_items))
def test_cmd_equip(self): """test that the equip command works properly""" self.bill.inv.add_item(Mace()) self.bill.inv.add_item(Sword()) # try a nonexistant item self.bill.command("equip fwwrsd") self.assertEqual(self.bill.msgs.pop(), "Could not find item 'fwwrsd'.") self.bill.command("equip mace") # mace should be equipped self.assertEqual(self.bill.msgs.pop(), "equip Mace") mace, from_inv = self.bill.equip_dict[inv.EquipTarget("Right Hand")] self.assertTrue(isinstance(mace, Mace)) self.assertTrue(from_inv) # now we cannot equip the mace again, because it cannot be found self.bill.command("equip mace") self.assertEqual(self.bill.msgs.pop(), "Could not find item 'mace'.") # mace should still be equipped mace, from_inv = self.bill.equip_dict[inv.EquipTarget("Right Hand")] self.assertTrue(isinstance(mace, Mace)) self.assertTrue(from_inv) # try equipping a sword self.bill.command("equip sword") self.assertEqual(self.bill.msgs, [ "unequip Mace", "equip Sword" ]) self.bill.msgs.clear() sword, from_inv = self.bill.equip_dict[inv.EquipTarget("Right Hand")] self.assertTrue(isinstance(sword, Sword)) self.assertTrue(from_inv) # we should be messaged if we equip an item we don't have a slot for self.bill.inv.add_item(Bow()) self.bill.command("equip Bow") self.assertEqual(self.bill.msgs.pop(), "Cannot equip item Bow to Left hand.") # equipping an un-equippable item should give us a message self.bill.inv.add_item(Coin()) self.bill.command("equip Coin") self.assertEqual(self.bill.msgs.pop(), "Coin cannot be equipped.")
class TestApparel(item.Equippable): """a base class for other test equippables""" target = inv.EquipTarget("Head") def on_equip(self, char): char.message(f"equip {self}") def on_unequip(self, char): char.message(f"unequip {self}")
class Sword(item.Equippable): target = inv.EquipTarget("right") @char.Command def swing(self, char, args): pass @char.Command def poke(self, char, args): pass
def test_fire_staff(self): brute, seller, wizard = self.brute, self.seller, self.wizard # put down three fire staffs tavern.add_item(FireStaff()) tavern.add_item(FireStaff()) tavern.add_item(FireStaff()) # each character picks one up brute.command("pickup fire staff") seller.command("pickup fire staff") wizard.command("pickup fire staff") inv_with_staff = inventory.Inventory( (FireStaff(), 1) ) self.assertEqual(brute.inv, inv_with_staff) self.assertEqual(seller.inv, inv_with_staff) self.assertEqual(wizard.inv, inv_with_staff) # each player should be able to equip the staff brute.command("equip fire staff") seller.command("equip fire staff") wizard.command("equip fire staff") rh = inventory.EquipTarget("Right hand") self.assertTrue(isinstance(brute.equip_dict[rh][0], FireStaff)) self.assertTrue(isinstance(seller.equip_dict[rh][0], FireStaff)) self.assertTrue(isinstance(wizard.equip_dict[rh][0], FireStaff)) # now brute and wizard should have updated commands self.assertTrue("hit" in brute.cmd_dict and "fireball" not in brute.cmd_dict) self.assertTrue("hit" not in seller.cmd_dict and "fireball" not in seller.cmd_dict) self.assertTrue("hit" not in wizard.cmd_dict and "fireball" in wizard.cmd_dict) # test that the commands can be used brute.command("hit adam") self.assertEqual(brute.msgs.get_nowait(), f"You hit {seller} with a staff.") self.assertEqual(seller.msgs.get_nowait(), f"{brute} hit you with a staff.") wizard.command("fireball adam") self.assertEqual(wizard.msgs.get_nowait(), f"You hit {seller} with a fireball.") self.assertEqual(seller.msgs.get_nowait(), f"{wizard} hit you with a fireball.")
def test_unequip(self): """test that the Character.unequip method performs proper error checking and works as expected""" # TODO test that all EquipCommands are removed! # manually equip the hat and the mace # we mark the hat as from_inv=False, so it should not be returned # while the mace should be added back to inventory hat = Hat() mace = Mace() self.finn.equip_dict[hat.target] = hat, False self.finn.equip_dict[mace.target] = mace, True # copy a reference for comparisons ref = self.finn.equip_dict.copy() # clear finn's inventory for convenience self.finn.inv = inv.Inventory() # try unequipping a slot that does not exist self.finn.unequip(inv.EquipTarget("Foo")) self.assertEqual(self.finn.msgs.pop(), "Human does not possess equip slot 'Foo'.") # unequip the item in the "Head" slot self.finn.unequip(inv.EquipTarget("head")) # hat should not be added to inventory since from_inv=False self.assertEqual(self.finn.inv, inv.Inventory()) # equip dict should be updated ref[inv.EquipTarget("head")] = None self.assertEqual(self.finn.equip_dict, ref) # item's equip method should be called self.assertEqual(self.finn.msgs[-1], "unequip Hat") # unequip the item in the "Right Hand" slot self.finn.unequip(inv.EquipTarget("right hand")) # mace should be added to inventory since from_inv=False self.assertEqual(self.finn.inv, inv.Inventory((Mace(), 1))) # equip dict should be updated ref[inv.EquipTarget("right hand")] = None self.assertEqual(self.finn.equip_dict, ref) # item's equip method should be called self.assertEqual(self.finn.msgs[-1], "unequip Mace") # try to unequip from an empty slot self.finn.unequip(inv.EquipTarget("hEAD")) self.assertEqual(self.finn.msgs.pop(), "No item equipped on target Head.")
class Sword(Equippable): target = inv.EquipTarget("hand") def __init__(self, dmg, material): self.dmg = dmg self.material = material def equip(self, char): pass def unequip(self, char): pass @classmethod def load(types, data): """load Sword with [data]""" return types(data["dmg"], data["material"]) def save(self): """provide a pythonic representation of this Sword""" return {"dmg": self.dmg, "material": self.material} def __repr__(self): return "Sword(%s, %r)" % (self.dmg, self.material)
def test_equip(self): """test that the equip method throws proper exceptions and works as expected""" #TODO: test that all equip_commands are added! # Finn's equip dict should be empty to start with self.assertEqual(self.finn.equip_dict, self.ref) # equip Sword without removing one from the inventory sword = Sword() self.finn.equip(sword, from_inv=False) # sword should not be removed from inventory self.assertEqual(self.finn.inv, inv.Inventory( (Sword(), 1), (Coin(), 5), (HealthPotion(10), 3) )) # equip dict should be updated self.ref[inv.EquipTarget("Right Hand")] = sword, False self.assertEqual(self.finn.equip_dict, self.ref) # item's equip method should be called self.assertEqual(self.finn.msgs[-1], "equip Sword") # try to equip an item that cannot be equipped self.finn.equip(HealthPotion(5), False) self.assertEqual(self.finn.msgs.pop(), "Health Potion cannot be equipped.") # try to equip an item for which we don't have proper slots self.finn.equip(Bow(), False) self.assertEqual(self.finn.msgs[-1], "Cannot equip item Bow to Left hand.") # try to equip a hat, but this time pull it from the inventory hat = Hat() self.finn.equip(hat, True) self.assertEqual(self.finn.msgs.pop(), "Cannot equip Hat-not found in inventory.") # give finn a hat and try again self.finn.add_item(Hat()) self.finn.equip(hat) # hat should be removed from inventory self.assertEqual(self.finn.inv, inv.Inventory( (Sword(), 1), (Coin(), 5), (HealthPotion(10), 3) )) # equip dict should be updated self.ref[inv.EquipTarget("Head")] = hat, True self.assertEqual(self.finn.equip_dict, self.ref) # item's equip method should be called self.assertEqual(self.finn.msgs[-1], "equip Hat") # try to equip a Mace, which implicitly unequips the Sword mace = Mace() self.finn.equip(mace, from_inv=False) # mace should not be removed from inventory and # old sword should NOT be returned since from_inv=False self.assertEqual(self.finn.inv, inv.Inventory( (Sword(), 1), (Coin(), 5), (HealthPotion(10), 3) )) # equip dict should be updated self.ref[inv.EquipTarget("Right Hand")] = mace, False self.assertEqual(self.finn.equip_dict, self.ref) # item's equip method should be called self.assertEqual(self.finn.msgs[-1], "equip Mace")
class Bow(TestApparel): target = inv.EquipTarget("Left hand")
class Mace(TestApparel): target = inv.EquipTarget("Right Hand")
class Sword(TestApparel): target = inv.EquipTarget("Right Hand")
class Helmet(TestApparel): target = inv.EquipTarget("Head")
class Sword(item.Equippable): """An equippable sword Here's another line """ target = inv.EquipTarget("hand")
class Headwear(item.Equippable): target = inv.EquipTarget("Head")