def testGet(self): # Try to get something that does not exist self._test( "get foobar", ["Nothing like that around here."]) # Try to get yourself self._test( "get self", ["You cannot take Test Player."]) self.assertEquals(self.player.location, self.location) # Try to get the location self._test( "get here", ["You cannot take Test Location."]) self.assertEquals(self.location.location, None) # Make an object and try to get it o = objects.Thing(store=self.store, name=u"foo") iimaginary.IContainer(self.location).add(o) self._test( "get foo", ["You take a foo."], ["Test Player takes a foo."]) self.assertEquals(o.location, self.player) # Try to get the observer self._test( "get 'Observer Player'", ["Observer Player is too heavy to pick up."], ["Test Player tries to pick you up, but fails."]) self.assertEquals(self.observer.location, self.location) # Container stuff self._test( "get baz from bar", ["Nothing like that around here."]) c = objects.Thing(store=self.store, name=u"bar") cContainer = objects.Container.createFor(c, capacity=1) iimaginary.IContainer(self.location).add(c) o = objects.Thing(store=self.store, name=u"baz") cContainer.add(o) self._test( "get baz from bar", ["You take a baz from the bar."], ["Test Player takes a baz from the bar."]) self.assertEquals(o.location, self.player) # Can't get things from a closed container o.moveTo(c) cContainer.closed = True self._test( "get baz from bar", ["Nothing like that around here."], []) self.assertEquals(o.location, c) self.assertEquals(list(cContainer.getContents()), [o])
def testBury(self): self._test("bury south", ["There isn't an exit in that direction."]) self.assertEquals( list(iimaginary.IContainer(self.location).getExits()), []) room = objects.Thing(store=self.store, name=u"destination", proper=True) objects.Container.createFor(room, capacity=1000) objects.Exit.link(room, self.location, u'north') self._test("bury south", ["It's gone."], ["Test Player destroyed the exit to destination."]) self.assertEquals( list(iimaginary.IContainer(self.location).getExits()), []) self.assertEquals(list(iimaginary.IContainer(room).getExits()), []) objects.Exit.link(self.location, room, u'south') self.observer.moveTo(room) self._test("bury south", ["It's gone."], ["The exit to Test Location crumbles and disappears."]) self.assertEquals( list(iimaginary.IContainer(self.location).getExits()), []) self.assertEquals(list(iimaginary.IContainer(room).getExits()), [])
def test_digWithDirectionAliases(self): """ The I{dig} action creates a new location connected to the current location through an exit in the specified direction even when that direction is an alias. """ self._test( "dig w dark tunnel", ["You create an exit."], ["Test Player created an exit to the west."]) room = iimaginary.IContainer(self.location).getExitNamed(u'west').toLocation self.assertEquals(room.name, u"dark tunnel") self.assertEquals(room.description, u'') self.assertIdentical(iimaginary.IContainer(room).getExitNamed(u'east').toLocation, self.location) self._test( "dig e bright tunnel", ["You create an exit."], ["Test Player created an exit to the east."]) room = iimaginary.IContainer(self.location).getExitNamed(u'east').toLocation self.assertEquals(room.name, u"bright tunnel") self.assertEquals(room.description, u'') self.assertIdentical(iimaginary.IContainer(room).getExitNamed(u'west').toLocation, self.location) self._test( "dig w boring tunnel", ["There is already an exit in that direction."])
def setUp(self): """ Set up a store with a location, a player and an observer. """ self.store = store.Store() locContainer = createLocation( self.store, u"Test Location", u"Location for testing.") self.location = locContainer.thing self.world = ImaginaryWorld(store=self.store, origin=self.location) self.player = self.world.create( u"Test Player", gender=self.genderForTest) self.playerContainer = iimaginary.IContainer(self.player) self.playerWrapper = player.Player(self.player) self.playerWrapper.useColors = False locContainer.add(self.player) self.transport = StringTransport() self.playerWrapper.setProtocol(PlayerProtocol(self.transport)) self.observer = self.world.create( u"Observer Player", gender=language.Gender.FEMALE) self.observerWrapper = player.Player(self.observer) locContainer.add(self.observer) self.otransport = StringTransport() self.observerWrapper.setProtocol(PlayerProtocol(self.otransport)) # Clear the transport, since we don't care about the observer # arrival event. self.transport.clear()
def test_cousinObject(self): o = objects.Thing(store=self.store, name=u"foo") iimaginary.IContainer(self.observer).add(o) self._test("look", [ E(u"[ Test Location ]"), u"Location for testing.", u"Here, you see Observer Player." ])
def reify(self): """ Determine which objects should receive this event and return a callable object which will deliver it to them. Note that this occurs during event propagation, and you probably don't need to call it directly. @see: L{iimaginary.IEventObserver.prepare} and L{TransactionalEventBroadcaster} for a more thorough description of how this method is used to interact with transactions. @return: a 0-arg callable object which, when called, will call the results of all L{IEventObserver}s which were contained within this L{Event}'s location when this method, L{Event.reify}, was called. """ L = [] for ob in iimaginary.IContainer(self.location).getContents(): observer = iimaginary.IEventObserver(ob, None) if observer: sender = observer.prepare(self) if not callable(sender): raise TypeError("Senders must be callable", sender) L.append(sender) return lambda: map(apply, L)
def testLook(self): self._test("look", [ E("[ Test Location ]"), "Location for testing.", "Observer Player" ]) self._test("look here", [ E("[ Test Location ]"), "Location for testing.", "Observer Player" ]) objects.Exit.link(self.location, self.location, u"north") self._test("look here", [ E("[ Test Location ]"), E("( north south )"), "Location for testing.", "Observer Player" ]) self._test( "look me", [E("[ Test Player ]"), "Test Player is great.", "She is naked."]) self._test( "look at me", [E("[ Test Player ]"), "Test Player is great.", "She is naked."]) self._test("look at Observer Player", [ E("[ Observer Player ]"), "Observer Player is great.", "She is naked." ], ["Test Player looks at you."]) o = objects.Thing(store=self.store, name=u"foo") iimaginary.IContainer(self.location).add(o) self._test("look at foo", [E("[ foo ]")]) self._test("look at bar", ["You don't see that."])
def do(self, player, line, direction): for exit in iimaginary.IContainer(player.thing.location).getExits(): if exit.name == direction: if exit.sibling is not None: evt = events.Success(location=exit.toLocation, otherMessage=language.Sentence([ exit.sibling, " crumbles and disappears." ])) evt.broadcast() evt = events.Success(actor=player.thing, actorMessage="It's gone.", otherMessage=language.Sentence([ language.Noun( player.thing).nounPhrase(), " destroyed ", exit, "." ])) evt.broadcast() exit.destroy() return raise eimaginary.ActionFailure( events.ThatDoesntMakeSense( actor=player.thing, actorMessage="There isn't an exit in that direction."))
def setUp(self): """ Set up a store with a location, a player and an observer. """ self.store = store.Store() self.location = objects.Thing(store=self.store, name=u"Test Location", description=u"Location for testing.", proper=True) locContainer = objects.Container.createFor(self.location, capacity=1000) self.world = ImaginaryWorld(store=self.store, origin=self.location) self.player = self.world.create(u"Test Player", gender=language.Gender.FEMALE) self.playerContainer = iimaginary.IContainer(self.player) self.playerWrapper = player.Player(self.player) self.playerWrapper.useColors = False locContainer.add(self.player) self.transport = StringTransport() self.playerWrapper.setProtocol(PlayerProtocol(self.transport)) self.observer = self.world.create(u"Observer Player", gender=language.Gender.FEMALE) self.observerWrapper = player.Player(self.observer) locContainer.add(self.observer) self.otransport = StringTransport() self.observerWrapper.setProtocol(PlayerProtocol(self.otransport)) # Clear the transport, since we don't care about the observer # arrival event. self.transport.clear()
def testFindContainersOutward(self): """ Combination of testFindOutward and testFindContainers. """ self.assertEquals( list(self.obj.findProviders(iimaginary.IContainer, 1)), [iimaginary.IContainer(self.room)])
def testInventory(self): # There ain't no stuff self._test( "inventory", ["Inventory:"]) playerContainer = iimaginary.IContainer(self.player) # Give 'em something and make sure # they show up playerContainer.add(objects.Thing(store=self.store, name=u"foobar")) self._test( "inventory", ["Inventory:", "foobar"]) # Give 'em a couple more things playerContainer.add(objects.Thing(store=self.store, name=u"barbaz")) playerContainer.add(objects.Thing(store=self.store, name=u"barbaz")) self._test( "inventory", ["Inventory:", "foobar", "barbaz", "barbaz"])
def testDrop(self): self._test("drop foo", ["Nothing like that around here."]) o = objects.Thing(store=self.store, name=u"bar") iimaginary.IContainer(self.player).add(o) self._test("drop bar", ["You drop the bar."], ["Test Player drops a bar."]) self.assertEquals(o.location, self.location)
def contains(self, other): for child in self.getContents(): if other is child: return True cchild = iimaginary.IContainer(child, None) if cchild is not None and cchild.contains(other): return True return False
def moveTo(self, where, arrivalEventFactory=None): """ Implement L{iimaginary.IThing.moveTo} to change the C{location} of this L{Thing} to a new L{Thing}, broadcasting an L{events.DepartureEvent} to note this object's departure from its current C{location}. Before moving it, invoke each L{IMovementRestriction} powerup on this L{Thing} to allow them to prevent this movement. """ whereContainer = iimaginary.IContainer(where, None) if (whereContainer is iimaginary.IContainer(self.location, None)): # Early out if I'm being moved to the same location that I was # already in. return if whereContainer is None: whereThing = None else: whereThing = whereContainer.thing if whereThing is not None and whereThing.location is self: # XXX should be checked against _all_ locations of whereThing, not # just the proximate one. # XXX actor= here is wrong, who knows who is moving this thing. raise eimaginary.ActionFailure( events.ThatDoesntWork(actor=self, actorMessage=[ language.Noun( where.thing).definiteNounPhrase( ).capitalizeConcept(), " won't fit inside itself." ])) oldLocation = self.location for restriction in self.powerupsFor(iimaginary.IMovementRestriction): restriction.movementImminent(self, where) if oldLocation is not None: events.DepartureEvent(oldLocation, self).broadcast() if where is not None: where = iimaginary.IContainer(where) if oldLocation is not None and not self.portable: raise eimaginary.CannotMove(self, where) where.add(self) if arrivalEventFactory is not None: arrivalEventFactory(self).broadcast() if oldLocation is not None: iimaginary.IContainer(oldLocation).remove(self)
def moveTo(self, where, arrivalEventFactory=None): """ @see: L{iimaginary.IThing.moveTo}. """ if where is self.location: return oldLocation = self.location if oldLocation is not None: events.DepartureEvent(oldLocation, self).broadcast() if where is not None: where = iimaginary.IContainer(where) if oldLocation is not None and not self.portable: raise eimaginary.CannotMove(self, where) where.add(self) if arrivalEventFactory is not None: arrivalEventFactory(self).broadcast() if oldLocation is not None: iimaginary.IContainer(oldLocation).remove(self)
def testFindContainers(self): """ Very much like testFindObjects, but searching for L{IContainer}, which only the location provides, and so only the location should be returned. """ self.assertEquals( list(self.room.findProviders(iimaginary.IContainer, 1)), [iimaginary.IContainer(self.room)])
def vt102(self, observer): return [ [T.fg.yellow, "Inventory:\n"], [ T.fg.green, [(language.Noun(o).shortName().vt102(observer), '\n') for o in iimaginary.IContainer(self.original).getContents()] ] ]
def testOpenClose(self): container = objects.Thing(store=self.store, name=u"container") objects.Container.createFor(container, capacity=1) iimaginary.IContainer(self.location).add(container) self._test("close container", ["You close the container."], ["Test Player closes a container."]) self._test("close container", ["The container is already closed."], []) self._test("open container", ["You open the container."], ["Test Player opens a container."]) self._test("open container", ["The container is already open."], [])
def visualize(self): container = iimaginary.IContainer(self.thing, None) if container is not None: exits = list(container.getExits()) else: exits = () return language.DescriptionConcept( self.name, self.description, exits, self.powerupsFor(iimaginary.IDescriptionContributor))
def do(self, player, line, target): v = dict((k, getattr(target, k)) for (k, ign) in target.getSchema() if hasattr(target, k)) targetContainer = iimaginary.IContainer(target, None) if targetContainer is not None: v['contents'] = list(targetContainer.getContents()) exits = list(targetContainer.getExits()) if exits: v['exits'] = exits s = pprint.pformat((target.__class__.__name__, v)) # XXX FIXME Send a real Concept player.send(s, '\n')
def testDig(self): self._test("dig west dark tunnel", ["You create an exit."], ["Test Player created an exit to the west."]) room = iimaginary.IContainer( self.location).getExitNamed(u'west').toLocation self.assertEquals(room.name, u"dark tunnel") self.assertEquals(room.description, u'') self.assertIdentical( iimaginary.IContainer(room).getExitNamed(u'east').toLocation, self.location) self._test("dig east bright tunnel", ["You create an exit."], ["Test Player created an exit to the east."]) room = iimaginary.IContainer( self.location).getExitNamed(u'east').toLocation self.assertEquals(room.name, u"bright tunnel") self.assertEquals(room.description, u'') self.assertIdentical( iimaginary.IContainer(room).getExitNamed(u'west').toLocation, self.location) self._test("dig west boring tunnel", ["There is already an exit in that direction."])
def search(self, distance, interface, name): """ Retrieve game objects answering to the given name which provide the given interface and are within the given distance. @type distance: C{int} @param distance: How many steps to traverse (note: this is wrong, it will become a real distance-y thing with real game-meaning someday). @param interface: The interface which objects within the required range must be adaptable to in order to be returned. @type name: C{str} @param name: The name of the stuff. @return: An iterable of L{iimaginary.IThing} providers which are found. """ # TODO - Move this into the action system. It is about finding things # using strings, which isn't what the action system is all about, but # the action system is where we do that sort of thing now. -exarkun extras = [] container = iimaginary.IContainer(self.location, None) if container is not None: potentialExit = container.getExitNamed(name, None) if potentialExit is not None: try: potentialThing = self.proxiedThing( potentialExit.toLocation, interface, distance) except eimaginary.ThingNotFound: pass else: yield potentialThing if name == "me" or name == "self": facet = interface(self, None) if facet is not None: extras.append(self) if name == "here" and self.location is not None: facet = interface(self.location, None) if facet is not None: extras.append(self.location) for res in self.findProviders(interface, distance): if res.thing in extras: yield res elif res.thing.knownAs(name): yield res
def do(self, player, line, tool, target): ctool = iimaginary.IContainer(tool, None) targetObject = target.thing if ctool is not None and (ctool.contains(targetObject) or ctool is target): raise eimaginary.ActionFailure( events.ThatDoesntWork( actor=player.thing, target=targetObject, tool=tool, actorMessage= "A thing cannot contain itself in euclidean space.")) dnf = language.Noun(targetObject).definiteNounPhrase() evt = events.Success( actor=player.thing, target=targetObject, tool=tool, actorMessage=("You put ", language.Noun(tool).definiteNounPhrase(), " in ", dnf, "."), targetMessage=language.Sentence( [player.thing, " puts ", " tool in you."]), toolMessage=language.Sentence( [player.thing, " puts you in ", targetObject, "."]), otherMessage=language.Sentence( [player.thing, " puts ", tool, " in ", targetObject, "."])) evt.broadcast() try: tool.moveTo(target) except eimaginary.DoesntFit: # <allexpro> dash: put me in a tent and give it to moshez! raise eimaginary.ActionFailure( events.ThatDoesntWork( actor=player.thing, target=targetObject, tool=tool, actorMessage=language.Sentence([ language.Noun(tool).definiteNounPhrase(), u" does not fit in ", dnf, u"." ]))) except eimaginary.Closed: raise eimaginary.ActionFailure( events.ThatDoesntWork(actor=player.thing, target=targetObject, tool=tool, actorMessage=language.Sentence( [dnf, " is closed."])))
def do(self, player, line, direction, name): direction = expandDirection(direction) if iimaginary.IContainer(player.thing.location).getExitNamed(direction, None) is not None: raise eimaginary.ActionFailure(events.ThatDoesntMakeSense( actor=player.thing, actorMessage="There is already an exit in that direction.")) room = objects.Thing(store=player.store, name=name) objects.Container.createFor(room, capacity=1000) objects.Exit.link(player.thing.location, room, direction) evt = events.Success( actor=player.thing, actorMessage="You create an exit.", otherMessage=language.Sentence([player.thing, " created an exit to the ", direction, "."])) evt.broadcast()
def testNonPortable(self): """ Test that the C{portable} flag is respected and prevents movement between locations. """ obj = objects.Thing(store=self.store, name=u"mountain") obj.portable = False room = objects.Thing(store=self.store, name=u"place") objects.Container.createFor(room, capacity=1000) obj.moveTo(room) elsewhere = objects.Thing(store=self.store, name=u"different place") container = objects.Container.createFor(elsewhere, capacity=1000) self.assertRaises(eimaginary.CannotMove, obj.moveTo, elsewhere) self.assertIdentical(obj.location, room) self.assertEquals(list(iimaginary.IContainer(room).getContents()), [obj]) self.assertEquals(list(container.getContents()), [])
def _applyProxies(self, locationProxies, proxies, obj, interface): # Extremely pathetic algorithm - loop over all location proxies we have # seen and apply any which belong to the location of the target object. # This could do with some serious optimization. for proxy in locationProxies: if iimaginary.IContainer(proxy.thing).contains( obj.thing) or proxy.thing is obj.thing: obj = proxy.proxy(obj, interface) if obj is None: return None # Loop over the other proxies and simply apply them in turn, giving up # as soon as one eliminates the object entirely. for proxy in proxies: obj = proxy.proxy(obj, interface) if obj is None: return None return obj
def test_scrutinizeNonContainer(self): """ The scrutinize action produces results for a thing which is not a container. """ o = objects.Thing(store=self.store, name=u"foo") iimaginary.IContainer(self.location).add(o) self._test( "scrutinize foo", [E(u"('Thing',"), E(u" {'description': u'',"), E(u" 'gender': 3,"), E(u" 'location': Thing(description=u'Location for testing.', " "gender=3, location=None, name=u'Test Location', portable=" "True, proper=True, weight=1, storeID=") + STOREID + E(")@0x") + PTR + E(","), E(u" 'name': u'foo',"), E(u" 'portable': True,"), E(u" 'proper': False,"), E(u" 'weight': 1})")])
def do(self, player, line, direction): try: exit = iimaginary.IContainer( player.thing.location).getExitNamed(direction) except KeyError: raise eimaginary.ActionFailure( events.ThatDoesntWork(actor=player.thing, actorMessage=u"You can't go that way.")) dest = exit.toLocation location = player.thing.location evt = events.Success(location=location, actor=player.thing, otherMessage=(player.thing, " leaves ", direction, ".")) evt.broadcast() if exit.sibling is not None: arriveDirection = exit.sibling.name else: arriveDirection = object.OPPOSITE_DIRECTIONS[exit.name] try: player.thing.moveTo( dest, arrivalEventFactory=lambda player: events.MovementArrivalEvent( thing=player, origin=None, direction=arriveDirection)) except eimaginary.DoesntFit: raise eimaginary.ActionFailure( events.ThatDoesntWork(actor=player.thing, actorMessage=language.ExpressString( u"There's no room for you there."))) # XXX A convention for programmatically invoked actions? # None as the line? LookAround().do(player, "look")
def testProgrammaticQuichePurchase(self): location = objects.Thing(store=self.store, name=u"room") icloc = objects.Container.createFor(location, capacity=500) vm = quiche.createVendingMachine(store=self.store, name=u"Vendy", description=u"VEEEENDYYYYY") vm.moveTo(location) icvm = iimaginary.IContainer(vm) icvm.closed = False theQuiche = quiche.createQuiche(store=self.store, name=u"quiche") icvm.add(theQuiche) icvm.closed = True for i in range(4): quarter = quiche.createCoin(store=self.store, name=u"quarter%s" % (i, )) icvm.add(quarter) quarter = quiche.createCoin(store=self.store, name=u"quarter4") icvm.add(quarter) self.failUnless(icloc.contains(theQuiche))
def test_emptyLocation(self): iimaginary.IContainer(self.location).remove(self.observer) self._test(u"look", [ E(u"[ Test Location ]"), u"Location for testing.", ])