def handle_verb(self, parsed: ParseResult, actor: Living) -> bool: pills = self.search_item("pills", include_location=False) if parsed.verb in ("bargain", "haggle"): if not parsed.args: raise ParseError("For how much money do you want to haggle?") if not pills: raise ActionRefused("It is no longer available for sale.") amount = mud_context.driver.moneyfmt.parse(parsed.args) price = mud_context.driver.moneyfmt.display(self.pills_price) if amount < self.pills_price / 2: actor.tell( "%s glares angrily at you and says, \"No way! I want at least half the original price! " "Did't I tell you? They were %s!\"" % (lang.capital(self.title), price)) raise ActionRefused() self.do_buy_pills(actor, pills, amount) return True if parsed.verb == "buy": if not parsed.args: raise ParseError("Buy what?") if "pills" in parsed.args or "bottle" in parsed.args or "medicine" in parsed.args: if not pills: raise ActionRefused("It is no longer available for sale.") self.do_buy_pills(actor, pills, self.pills_price) return True if pills: raise ParseError( "There's nothing left to buy in the shop, except for the pills the apothecary is holding." ) else: raise ParseError("There's nothing left to buy.") return False
def process_typed_command(self, command: str, doorname: str, actor: Living) -> None: if command == "help": message = "KNOWN COMMANDS: LOCK, UNLOCK" elif command in ("hi", "hello"): message = "GREETINGS, PROFESSOR FALKEN." elif command in ("unlock", "lock"): try: door = self.location.exits[doorname] except KeyError: message = "UNKNOWN DOOR" else: if not isinstance(door, Door): message = "THAT IS NOT THE NAME OF A DOOR" else: if command == "unlock": if door.locked: door.locked = False message = doorname.upper() + " UNLOCKED" else: message = "COMMAND INVALID - DOOR ALREADY UNLOCKED" else: if door.locked: message = "COMMAND INVALID - DOOR ALREADY LOCKED" else: door.locked = True message = doorname.upper() + " LOCKED" else: message = "INVALID COMMAND" actor.tell("The computer beeps quietly. The screen shows: \"%s\"" % message)
def handle_verb(self, parsed: ParseResult, actor: Living) -> bool: if parsed.verb == "hack": if self in parsed.who_info: actor.tell("It doesn't need to be hacked, you can just type commands on it.") return True elif parsed.who_info: raise ActionRefused("You can't hack that.") else: raise ActionRefused("What do you want to hack?") if parsed.verb in ("type", "enter"): if parsed.who_info and self not in parsed.who_info: raise ActionRefused("You need to type it on the computer.") if parsed.message: # type "bla bla" on computer (message between quotes) action, _, door = parsed.message.partition(" ") self.process_typed_command(action, door, actor) return True args = list(parsed.args) if self.name in args: args.remove(self.name) for name in self.aliases: if name in args: args.remove(name) if args: args.append("") self.process_typed_command(args[0], args[1], actor) return True return False
def handle_verb(self, parsed: ParseResult, actor: Living) -> bool: if parsed.verb == "hack": if self in parsed.who_info: actor.tell( "It doesn't need to be hacked, you can just type commands on it." ) return True elif parsed.who_info: raise ActionRefused("You can't hack that.") else: raise ActionRefused("What do you want to hack?") if parsed.verb in ("type", "enter"): if parsed.who_info and self not in parsed.who_info: raise ActionRefused("You need to type it on the computer.") if parsed.message: # type "bla bla" on computer (message between quotes) action, _, door = parsed.message.partition(" ") self.process_typed_command(action, door, actor) return True args = list(parsed.args) if self.name in args: args.remove(self.name) for name in self.aliases: if name in args: args.remove(name) if args: args.append("") self.process_typed_command(args[0], args[1], actor) return True return False
def notify_moved(self, source_container: ContainingType, target_container: ContainingType, actor: Living) -> None: if isinstance(actor, Player): actor.tell( "You try to pick up the orb, but as soon as you touch it it ends this game!" ) raise StoryCompleted
def test_move(self): hall = Location("hall") attic = Location("attic") rat = Living("rat", "n", race="rodent") hall.init_inventory([rat]) wiretap_hall = Wiretap(hall) wiretap_attic = Wiretap(attic) self.assertTrue(rat in hall.livings) self.assertFalse(rat in attic.livings) self.assertEqual(hall, rat.location) rat.move(attic) self.assertTrue(rat in attic.livings) self.assertFalse(rat in hall.livings) self.assertEqual(attic, rat.location) self.assertEqual([("hall", "Rat leaves.")], wiretap_hall.msgs) self.assertEqual([("attic", "Rat arrives.")], wiretap_attic.msgs) # now try silent wiretap_hall.clear() wiretap_attic.clear() rat.move(hall, silent=True) self.assertTrue(rat in hall.livings) self.assertFalse(rat in attic.livings) self.assertEqual(hall, rat.location) self.assertEqual([], wiretap_hall.msgs) self.assertEqual([], wiretap_attic.msgs)
def test_show_inventory(self): class Ctx(object): class Config(object): pass config = Config() class MoneyDriverDummy(object): pass ctx = Ctx() ctx.config.money_type = "modern" ctx.driver = MoneyDriverDummy() ctx.driver.moneyfmt = MoneyFormatter(ctx.config.money_type) julie = Living("julie", "f", race="human") tap = julie.get_wiretap() collector = PubsubCollector() tap.subscribe(collector) item1 = Item("key") julie.init_inventory([item1]) julie.money = 9.23 julie.show_inventory(julie, ctx) pubsub.sync() text = " ".join(msg.strip() for msg in collector.messages) self.assertEqual( "Julie is carrying: key Money in possession: 9 dollars and 23 cents.", text) ctx.config.money_type = None ctx.driver.moneyfmt = None collector.clear() julie.show_inventory(julie, ctx) pubsub.sync() text = " ".join(msg.strip() for msg in collector.messages) self.assertEqual("Julie is carrying: key", text)
def test_ban(self): dbfile = pathlib.Path( tempfile.gettempdir()) / "tale_test_accdb_{0:f}.sqlite".format( time.time()) actor = Living("normal", gender="f") wizard = Living("wizz", gender="f") wizard.privileges.add("wizard") try: accounts = MudAccounts(str(dbfile)) stats = Stats.from_race("elf", gender='f') accounts.create("testname", "s3cr3t", "test@invalid", stats, {"wizard"}) account = accounts.get("testname") self.assertFalse(account.banned) with self.assertRaises(ActionRefused): accounts.ban("testname", actor) with self.assertRaises(LookupError): accounts.ban("zerp", wizard) accounts.ban("testname", wizard) account = accounts.get("testname") self.assertTrue(account.banned) with self.assertRaises(LookupError): accounts.unban("zerp", wizard) accounts.unban("testname", wizard) account = accounts.get("testname") self.assertFalse(account.banned) finally: dbfile.unlink()
def handle_verb(self, parsed: ParseResult, actor: Living) -> bool: pills = self.search_item("pills", include_location=False) if parsed.verb in ("bargain", "haggle"): if not parsed.args: raise ParseError("For how much money do you want to haggle?") if not pills: raise ActionRefused("It is no longer available for sale.") amount = mud_context.driver.moneyfmt.parse(parsed.args) price = mud_context.driver.moneyfmt.display(self.pills_price) if amount < self.pills_price / 2: actor.tell("%s glares angrily at you and says, \"No way! I want at least half the original price! " "Did't I tell you? They were %s!\"" % (lang.capital(self.title), price)) raise ActionRefused() self.do_buy_pills(actor, pills, amount) return True if parsed.verb == "buy": if not parsed.args: raise ParseError("Buy what?") if "pills" in parsed.args or "bottle" in parsed.args or "medicine" in parsed.args: if not pills: raise ActionRefused("It is no longer available for sale.") self.do_buy_pills(actor, pills, self.pills_price) return True if pills: raise ParseError("There's nothing left to buy in the shop, except for the pills the apothecary is holding.") else: raise ParseError("There's nothing left to buy.") return False
def test_contains(self): orc = Living("orc", "m", race="orc") axe = Weapon("axe") orc.insert(axe, orc) self.assertTrue(axe in orc) self.assertTrue(axe in orc.inventory) self.assertEqual(1, orc.inventory_size) self.assertEqual(1, len(orc.inventory))
def do_buy_pills(self, actor: Living, pills: Item, price: float) -> None: if actor.money < price: raise ActionRefused("You don't have enough money!") actor.money -= price self.money += price pills.move(actor, self) price_str = mud_context.driver.moneyfmt.display(price) actor.tell("After handing %s the %s, %s gives you the %s." % (self.objective, price_str, self.subjective, pills.title)) self.tell_others("{Actor} says: \"Here's your medicine, now get out of here!\"")
def do_buy_ammo(self, actor: Living, ammo: Item, price: float) -> None: if actor.money < price: raise ActionRefused("You don't have enough money!") actor.money -= price self.money += price ammo.move(actor, self) price_str = mud_context.driver.moneyfmt.display(price) actor.tell("After handing %s the %s, %s gives you the %s." % (self.objective, price_str, self.subjective, ammo.title)) self.tell_others("{Actor} says: \"Here's your ammo, now get out of here!\"")
def unlock(self, actor: Living, item: Item = None) -> None: super().unlock(actor, item) if not self.locked: if isinstance(actor, Player): # remember a hint about unlocking this door if actor.hints.checkpoint( "unlocked_enddoor", "The way to freedom lies before you!"): actor.tell_later("<dim>(You will remember this event.)</>")
def test_show_inventory(self): class Ctx(object): class Config(object): pass config = Config() class MoneyDriverDummy(object): pass ctx=Ctx() ctx.config.money_type = "modern" ctx.driver = MoneyDriverDummy() ctx.driver.moneyfmt = MoneyFormatter(ctx.config.money_type) julie = Living("julie", "f", race="human") tap = julie.get_wiretap() collector = PubsubCollector() tap.subscribe(collector) item1 = Item("key") julie.init_inventory([item1]) julie.money = 9.23 julie.show_inventory(julie, ctx) text = " ".join(msg.strip() for msg in collector.messages) self.assertEqual("Julie is carrying: key Money in possession: 9 dollar and 23 cent.", text) ctx.config.money_type = None ctx.driver.moneyfmt = None collector.clear() julie.show_inventory(julie, ctx) text = " ".join(msg.strip() for msg in collector.messages) self.assertEqual("Julie is carrying: key", text)
def notify_action(self, parsed: ParseResult, actor: Living) -> None: if actor is self or parsed.verb in self.verbs: return # avoid reacting to ourselves, or reacting to verbs we already have a handler for if parsed.verb in ("hello", "hi"): self.process_typed_command("hello", "", actor) elif parsed.verb in ("say", "yell"): if "hi" in parsed.args or "hello" in parsed.args: self.process_typed_command("hello", "", actor) else: actor.tell("The computer beeps quietly. The screen shows: " "\"I CAN'T HEAR YOU. PLEASE TYPE COMMANDS INSTEAD OF SPEAKING.\" How odd.")
def test_lifecycle(self): orc = Living("orc", "m", race="orc") axe = Weapon("axe") orc.insert(axe, orc) self.assertIsNotNone(orc.soul) self.assertIsNotNone(orc.location) self.assertGreater(orc.inventory_size, 0) orc.destroy(Context(TestDriver(), None, None, None)) self.assertIsNone(orc.soul) self.assertIsNone(orc.location) self.assertEqual(orc.inventory_size, 0)
def notify_moved(self, source_container: ContainingType, target_container: ContainingType, actor: Living) -> None: # check if a player picked up this key player = None if isinstance(target_container, Player): player = target_container elif isinstance(self.contained_in, Player): player = self.contained_in if player: if player.hints.checkpoint( "got_doorkey", "You've found something that might open the exit."): actor.tell_later("<dim>(You will remember this event.)</>")
def notify_action(self, parsed: ParseResult, actor: Living) -> None: if actor is self or parsed.verb in self.verbs: return # avoid reacting to ourselves, or reacting to verbs we already have a handler for # react on mentioning the medicine if "medicine" in parsed.unparsed or "pills" in parsed.unparsed or "bottle" in parsed.unparsed: if self.search_item("pills", include_location=False): # do we still have the pills? price = mud_context.driver.moneyfmt.display(self.pills_price) self.tell_others("{Actor} clenches the bottle %s's holding even tighter. %s says: " "\"You won't get them for free! They will cost you %s!\"" % (self.subjective, lang.capital(self.subjective), price)) else: self.tell_others("{Actor} says: \"Good luck with it!\"") if random.random() < 0.5: actor.tell("%s glares at you." % lang.capital(self.title))
def notify_action(self, parsed: ParseResult, actor: Living) -> None: if actor is self or parsed.verb in self.verbs: return # avoid reacting to ourselves, or reacting to verbs we already have a handler for # react on mentioning the medicine if "bullets" in parsed.unparsed or "ammo" in parsed.unparsed: if self.search_item("ammo", include_location=False): # do we still have the ammo? price = mud_context.driver.moneyfmt.display(self.ammo_price) self.tell_others("{Actor} clenches bof of %s's holding even tighter. %s says: " "\"You won't get them for free! They will cost you %s!\"" % (self.subjective, lang.capital(self.subjective), price)) else: self.tell_others("{Actor} says: \"Good luck with it!\"") if random.random() < 0.5: actor.tell("%s glares at you." % lang.capital(self.title))
def handle_verb(self, parsed: ParseResult, actor: Living) -> bool: if parsed.verb == "list": pets = self.get_pets() actor.tell("Available pets at the moment are:", end=True) txt = ["<ul> pet <dim>|</><ul> price </>"] for i, (pet, price) in enumerate(pets.items(), start=1): txt.append(" %-15s %s" % (pet.name, mud_context.driver.moneyfmt.display(price))) actor.tell("\n".join(txt), format=False) return True elif parsed.verb == "buy": if not parsed.args: raise ActionRefused("Buy which pet? Don't forget to name it as well (optional).") pets = self.get_pets() for pet, price in pets.items(): if pet.name == parsed.args[0].lower(): pet = make_mob(pet.circle_vnum, type(pet)) if price > actor.money: raise ActionRefused("You can't afford that pet.") if len(parsed.args) == 2: name = parsed.args[1].lower() pet.title = "%s %s" % (pet.name, lang.capital(name)) pet.description += " A small sign on a chain around the neck says 'My name is %s'." % lang.capital(name) pet.aliases.add(pet.name) pet.name = name pet.following = actor # @todo make pet charmed as well (see circle doc/src) pet.is_pet = True actor.money -= price actor.tell_others("{Actor} buys %s as a pet." % pet.title) actor.tell("You paid %s and received %s as your new pet. Happy times!" % (mud_context.driver.moneyfmt.display(price), pet.title)) pet.move(actor.location, pet) return True raise ActionRefused("There is no such pet!") else: return super().handle_verb(parsed, actor)
def handle_verb(self, parsed: ParseResult, actor: Living) -> bool: if parsed.verb in ("drive", "open", "enter", "sit", "use", "start"): if not parsed.args: raise ParseError("%s what?" % parsed.verb) if "yellow" not in parsed.args and "convertible" not in parsed.args: if "car" in parsed.args or "engine" in parsed.args: raise ActionRefused("Most of the cars are locked. You should look for one that isn't.") raise ActionRefused("You cannot do that.") # check if Peter is with you if not self.search_living("Peter"): raise ActionRefused("Surely you wouldn't leave the town without your friend Peter! " "You should find him and get out here together!") # player drives the yellow car away from here together with her friend Peter, and thus the story ends! actor.tell_text_file(mud_context.resources["messages/completion_success.txt"]) # type: ignore raise StoryCompleted return False
def test_lang(self): living = Living("julie", "f", race="human") self.assertEqual("her", living.objective) self.assertEqual("her", living.possessive) self.assertEqual("she", living.subjective) self.assertEqual("f", living.gender) living = Living("max", "m", race="human") self.assertEqual("him", living.objective) self.assertEqual("his", living.possessive) self.assertEqual("he", living.subjective) self.assertEqual("m", living.gender) living = Living("herp", "n", race="human") self.assertEqual("it", living.objective) self.assertEqual("its", living.possessive) self.assertEqual("it", living.subjective) self.assertEqual("n", living.gender)
def test_move(self): hall = Location("hall") person = Living("person", "m", race="human") monster = NPC("dragon", "f", race="dragon") monster.aggressive = True key = Item("key") stone = Item("stone") hall.init_inventory([person, key]) stone.move(hall, person) wiretap = Wiretap(hall) self.assertTrue(person in hall) self.assertTrue(key in hall) key.contained_in = person # hack to force move to actually check the source container with self.assertRaises(KeyError): key.move(person, person) key.contained_in = hall # put it back as it was key.move(person, person) self.assertFalse(key in hall) self.assertTrue(key in person) self.assertEqual([], wiretap.msgs, "item.move() should be silent") with self.assertRaises(ActionRefused) as x: key.move(monster, person) # aggressive monster should fail self.assertTrue("not a good idea" in str(x.exception)) monster.aggressive = False key.move(monster, person) # non-aggressive should be ok
def handle_verb(self, parsed: ParseResult, actor: Living) -> bool: if parsed.verb in ("drive", "open", "enter", "sit", "use", "start"): if not parsed.args: raise ParseError("%s what?" % parsed.verb) if "yellow" not in parsed.args and "convertible" not in parsed.args: if "car" in parsed.args or "engine" in parsed.args: raise ActionRefused("Most of the cars are locked. You should look for one that isn't.") raise ActionRefused("You cannot do that.") # check if Peter is with you if not self.search_living("Peter"): raise ActionRefused("Surely you wouldn't leave the town without your friend Peter! " "You should find him and get out here together!") # player drives the yellow car away from here together with her friend Peter, and thus the story ends! actor.tell_text_file(mud_context.resources["messages/completion_success.txt"]) raise StoryCompleted return False
def test_look(self): player = Player("fritz", "m") attic = Location("Attic", "A dark attic.") player.look() self.assertEqual([ "[Limbo]\n", "The intermediate or transitional place or state. There's only nothingness. " "Living beings end up here if they're not in a proper location yet.\n" ], player.test_get_output_paragraphs()) player.move(attic, silent=True) player.look(short=True) self.assertEqual(["[Attic]\n"], player.test_get_output_paragraphs()) julie = Living("julie", "f") julie.move(attic, silent=True) player.look(short=True) self.assertEqual(["[Attic]\n", "Present here: julie\n"], player.test_get_output_paragraphs())
def test_allowance(self): orc = Living("orc", "m", race="half-orc") axe = Weapon("axe") orc.insert(axe, orc) self.assertTrue(axe in orc) with self.assertRaises(ActionRefused) as x: orc.remove(axe, None) self.assertTrue("can't take" in str(x.exception)) orc.remove(axe, orc) self.assertFalse(axe in orc)
def test_tell(self): julie = Living("julie", "f", race="human") tap = julie.get_wiretap() collector = PubsubCollector() tap.subscribe(collector) julie.tell("msg1", "msg2") julie.tell("msg3", "msg4", ignored_arg=42) pubsub.sync() self.assertEqual(["msg1 msg2", "msg3 msg4"], collector.messages)
def test_look_brief(self): player = Player("fritz", "m") attic = Location("Attic", "A dark attic.") cellar = Location("Cellar", "A gloomy cellar.") julie = Living("julie", "f") julie.move(attic, silent=True) player.move(attic, silent=True) player.brief = 0 # default setting: always long descriptions player.look() self.assertEqual(["[Attic]\n", "A dark attic.\n", "Julie is here.\n"], player.test_get_output_paragraphs()) player.look() self.assertEqual(["[Attic]\n", "A dark attic.\n", "Julie is here.\n"], player.test_get_output_paragraphs()) player.look(short=True) # override self.assertEqual(["[Attic]\n", "Present here: julie\n"], player.test_get_output_paragraphs()) player.brief = 1 # short for known, long for new locations player.look() self.assertEqual(["[Attic]\n", "Present here: julie\n"], player.test_get_output_paragraphs()) player.move(cellar, silent=True) player.look() self.assertEqual(["[Cellar]\n", "A gloomy cellar.\n"], player.test_get_output_paragraphs()) player.look() self.assertEqual(["[Cellar]\n"], player.test_get_output_paragraphs()) player.brief = 2 # short always player.known_locations.clear() player.look() self.assertEqual(["[Cellar]\n"], player.test_get_output_paragraphs()) player.move(attic, silent=True) player.look() self.assertEqual(["[Attic]\n", "Present here: julie\n"], player.test_get_output_paragraphs()) player.look(short=True) # override self.assertEqual(["[Attic]\n", "Present here: julie\n"], player.test_get_output_paragraphs()) player.look(short=False) # override self.assertEqual(["[Attic]\n", "A dark attic.\n", "Julie is here.\n"], player.test_get_output_paragraphs())
def test_socialize(self): player = Player("fritz", "m") attic = Location("Attic", "A dark attic.") julie = Living("julie", "f") julie.move(attic) player.move(attic) parsed = player.parse("wave all") self.assertEqual("wave", parsed.verb) self.assertEqual(1, parsed.who_count) self.assertEqual(julie, parsed.who_1) self.assertEqual((julie, None, None), parsed.who_123) self.assertEqual(julie, parsed.who_last) self.assertEqual([julie], list(parsed.who_info)) who, playermsg, roommsg, targetmsg = player.soul.process_verb_parsed( player, parsed) self.assertEqual({julie}, who) self.assertEqual("You wave happily at julie.", playermsg) with self.assertRaises(tale.errors.UnknownVerbException): player.parse("befrotzificate all and me") with self.assertRaises(NonSoulVerb) as x: player.parse("befrotzificate all and me", external_verbs={"befrotzificate"}) parsed = x.exception.parsed self.assertEqual("befrotzificate", parsed.verb) self.assertEqual(2, parsed.who_count) self.assertEqual(julie, parsed.who_1) self.assertEqual((julie, player, None), parsed.who_123) self.assertEqual([julie, player], list(parsed.who_info)) self.assertEqual(player, parsed.who_last) attic.add_exits([Exit("south", "target", "door")]) try: player.parse("push south") self.fail( "push south should throw a parse error because of the exit that is used" ) except ParseError: pass with self.assertRaises(NonSoulVerb): player.parse("fart south") parsed = player.parse("hug julie") player.validate_socialize_targets(parsed)
def test_move(self): hall = Location("hall") attic = Location("attic") rat = Living("rat", "n", race="rodent") hall.init_inventory([rat]) wiretap_hall = Wiretap(hall) wiretap_attic = Wiretap(attic) self.assertTrue(rat in hall.livings) self.assertFalse(rat in attic.livings) self.assertEqual(hall, rat.location) rat.move(attic) self.assertTrue(rat in attic.livings) self.assertFalse(rat in hall.livings) self.assertEqual(attic, rat.location) pubsub.sync() self.assertEqual([("hall", "Rat leaves.")], wiretap_hall.msgs) self.assertEqual([("attic", "Rat arrives.")], wiretap_attic.msgs) # now try silent wiretap_hall.clear() wiretap_attic.clear() rat.move(hall, silent=True) pubsub.sync() self.assertTrue(rat in hall.livings) self.assertFalse(rat in attic.livings) self.assertEqual(hall, rat.location) self.assertEqual([], wiretap_hall.msgs) self.assertEqual([], wiretap_attic.msgs)
def test_open_hours(self): self.shopkeeper.validate_open_hours(current_time=datetime.time(9, 0)) self.shopkeeper.validate_open_hours(current_time=datetime.time(9, 1)) self.shopkeeper.validate_open_hours(current_time=datetime.time(13, 0)) self.shopkeeper.validate_open_hours(current_time=datetime.time(16, 59)) self.shopkeeper.validate_open_hours(current_time=datetime.time(22, 0)) self.shopkeeper.validate_open_hours(current_time=datetime.time(23, 59)) self.shopkeeper.validate_open_hours(current_time=datetime.time(0, 0)) self.shopkeeper.validate_open_hours(current_time=datetime.time(0, 1)) self.shopkeeper.validate_open_hours(current_time=datetime.time(2, 59)) wiz = Living("wizard", "m") wiz.privileges.add("wizard") self.shopkeeper.validate_open_hours(wiz, current_time=datetime.time(2, 59))
def test_tell(self): julie = Living("julie", "f", race="human") tap = julie.get_wiretap() collector = PubsubCollector() tap.subscribe(collector) julie.tell("msg1", "msg2") julie.tell("msg3", "msg4", ignored_arg=42) self.assertEqual(["msg1", "msg2", "msg3", "msg4"], collector.messages)
def test_wiretap(self): attic = Location("Attic", "A dark attic.") player = Player("fritz", "m") io = ConsoleIo(None) io.supports_smartquotes = False pc = PlayerConnection(player, io) player.set_screen_sizes(0, 100) julie = Living("julie", "f") julie.move(attic) player.move(attic) julie.tell("message for julie") attic.tell("message for room") self.assertEqual(["message for room\n"], player.test_get_output_paragraphs()) with self.assertRaises(ActionRefused): player.create_wiretap(julie) player.privileges = {"wizard"} player.create_wiretap(julie) player.create_wiretap(attic) julie.tell("message for julie") attic.tell("message for room") pubsub.sync() output = pc.get_output() self.assertTrue( "[wiretapped from `Attic': message for room]" in output) self.assertTrue( "[wiretapped from `julie': message for julie]" in output) self.assertTrue( "[wiretapped from `julie': message for room]" in output) self.assertTrue("message for room " in output) # test removing the wiretaps player.clear_wiretaps() import gc gc.collect() julie.tell("message for julie") attic.tell("message for room") self.assertEqual(["message for room\n"], player.test_get_output_paragraphs())
def test_closed_hours(self): with self.assertRaises(ActionRefused): self.shopkeeper.validate_open_hours(current_time=datetime.time(6, 30)) with self.assertRaises(ActionRefused): self.shopkeeper.validate_open_hours(current_time=datetime.time(8, 59)) with self.assertRaises(ActionRefused): self.shopkeeper.validate_open_hours(current_time=datetime.time(17, 0)) with self.assertRaises(ActionRefused): self.shopkeeper.validate_open_hours(current_time=datetime.time(21, 59)) with self.assertRaises(ActionRefused): self.shopkeeper.validate_open_hours(current_time=datetime.time(3, 0)) wiz = Living("wizard", "m") wiz.privileges.add("wizard") self.shopkeeper.validate_open_hours(wiz, current_time=datetime.time(21, 59))
def test_location(self): thingy = Item("thing") with self.assertRaises(TypeError): thingy.location = "foobar" hall = Location("hall") thingy.location = hall self.assertEqual(hall, thingy.contained_in) self.assertEqual(hall, thingy.location) person = Living("person", "m", race="human") key = Item("key") backpack = Container("backpack") person.insert(backpack, person) self.assertIsNone(key.contained_in) self.assertIsNone(key.location) self.assertTrue(backpack in person) self.assertEqual(person, backpack.contained_in) self.assertEqual(_Limbo, backpack.location) hall.init_inventory([person, key]) self.assertEqual(hall, key.contained_in) self.assertEqual(hall, key.location) self.assertEqual(hall, backpack.location) key.move(backpack, person) self.assertEqual(backpack, key.contained_in) self.assertEqual(hall, key.location)
def test_location(self): thingy = Item("thing") with self.assertRaises(TypeError): thingy.location = "foobar" hall = Location("hall") thingy.location = hall self.assertEqual(hall, thingy.contained_in) self.assertEqual(hall, thingy.location) person = Living("person", "m", race="human") key = Item("key") backpack = Container("backpack") person.insert(backpack, person) self.assertIsNone(key.contained_in) self.assertIsNone(key.location) self.assertTrue(backpack in person) self.assertEqual(person, backpack.contained_in) self.assertEqual(_limbo, backpack.location) hall.init_inventory([person, key]) self.assertEqual(hall, key.contained_in) self.assertEqual(hall, key.location) self.assertEqual(hall, backpack.location) key.move(backpack, person) self.assertEqual(backpack, key.contained_in) self.assertEqual(hall, key.location)
def test_door_pair(self): loc1 = Location("room1", "room one") loc2 = Location("room2", "room two") key = Key("key") door_one_two = Door("two", loc2, "door to room two", locked=True, opened=False) door_two_one = door_one_two.reverse_door( "one", loc1, "door to room one", reverse_open_msg="door one open", reverse_close_msg="door one close", this_open_msg="door two open", this_close_msg="door two close") loc1.add_exits([door_one_two]) loc2.add_exits([door_two_one]) door_one_two.key_code = 555 key.key_for(door_one_two) pubsub1 = PubsubCollector() pubsub2 = PubsubCollector() loc1.get_wiretap().subscribe(pubsub1) loc2.get_wiretap().subscribe(pubsub2) self.assertTrue(door_two_one.locked) self.assertFalse(door_two_one.opened) lucy = Living("lucy", "f") door_two_one.unlock(lucy, item=key) self.assertFalse(door_one_two.locked) door_two_one.open(lucy) self.assertTrue(door_one_two.opened) pubsub.sync() self.assertEqual(["door one open"], pubsub1.messages) self.assertEqual([], pubsub2.messages) door_one_two.close(lucy) door_one_two.lock(lucy, item=key) self.assertTrue(door_two_one.locked) self.assertFalse(door_two_one.opened) pubsub1.clear() pubsub2.clear() pubsub.sync() self.assertEqual([], pubsub1.messages) self.assertEqual(["door two close"], pubsub2.messages)
def test_destroy_loc(self): ctx = Context(None, None, None, None) loc = Location("loc") i = Item("item") liv = Living("rat", "n", race="rodent") loc.add_exits([Exit("north", "somewhere", "exit to somewhere")]) player = Player("julie", "f") player.privileges = {"wizard"} player.create_wiretap(loc) loc.init_inventory([i, liv, player]) self.assertTrue(len(loc.exits) > 0) self.assertTrue(len(loc.items) > 0) self.assertTrue(len(loc.livings) > 0) self.assertEqual(loc, player.location) self.assertEqual(loc, liv.location) loc.destroy(ctx) self.assertTrue(len(loc.exits) == 0) self.assertTrue(len(loc.items) == 0) self.assertTrue(len(loc.livings) == 0) self.assertEqual(_limbo, player.location) self.assertEqual(_limbo, liv.location)
def read(self, actor: Living) -> None: actor.tell(self.screen_text())
def allow_passage(self, actor: Living) -> None: if "wizard" in actor.privileges: actor.tell("You pass through the force-field.", end=True) else: raise ActionRefused("You can't go that way, the force-field is impenetrable.")
def test_nonitem_insert_fail(self): something = MudObject("thing that is not an Item") orc = Living("orc", "m", race="half-orc") with self.assertRaises(ActionRefused): orc.insert(something, orc)
def __init__(self, target: base.Living) -> None: self.msgs = [] # type: List[Any] self.senders = [] # type: List[Any] tap = target.get_wiretap() tap.subscribe(self)