def do(self, player, line, target): if target is player: raise eimaginary.ActionFailure( events.ThatDoesntMakeSense(u"Hit yourself? Stupid.", actor=player.thing)) cost = random.randrange(1, 5) if player.stamina < cost: raise eimaginary.ActionFailure( events.ThatDoesntWork(u"You're too tired!", actor=player.thing)) damage = random.randrange(1, 5) player.stamina.decrease(cost) thp = target.hitpoints.decrease(damage) events.Success( actor=player.thing, target=target.thing, targetMessage=language.Sentence([player.thing, " hits you for ", damage, " hitpoints."]), actorMessage=language.Sentence(["You hit ", language.Noun(target.thing).definiteNounPhrase(), " for ", damage, " hitpoints."]), otherMessage=language.Sentence([player.thing, " hits ", target.thing, "."])).broadcast() if thp <= 0: xp = target.experience / 2 + 1 player.gainExperience(xp) # I LOVE IT targetIsDead = [target.thing, " is dead!", "\n"] events.Success( actor=player.thing, target=target.thing, actorMessage=["\n", targetIsDead, "You gain ", xp, " experience"], targetMessage=["You are dead!"], otherMessage=targetIsDead).broadcast() target.thing.destroy()
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 obtainOrReportWhyNot(self, retriever): """ Invoke L{Idea.obtain} on C{self.idea} with the given C{retriever}. If no results are yielded, then investigate the reasons why no results have been yielded, and raise an exception describing one of them. Objections may be registered by: - an L{iimaginary.IWhyNot} annotation on any link traversed in the attempt to discover results, or, - an L{iimaginary.IWhyNot} yielded by the given C{retriever}'s L{iimaginary.IRetriever.objectionsTo} method. @return: a list of objects returned by C{retriever.retrieve} @rtype: C{list} @raise eimaginary.ActionFailure: if no results are available, and an objection has been registered. """ obt = self.idea.obtain(retriever) results = list(obt) if not results: reasons = list(obt.reasonsWhyNot) if reasons: raise eimaginary.ActionFailure(events.ThatDoesntWork( actor=self, actorMessage=reasons[0].tellMeWhyNot())) return results
def do(self, player, line, target): from imaginary import garments try: player.putOn(target) except garments.TooBulky as e: raise eimaginary.ActionFailure( events.ThatDoesntWork( actor=player.thing, target=target.thing, actorMessage=language.Sentence([ language.Noun( e.wornGarment.thing).definiteNounPhrase(), u" you are already wearing is too bulky for you to do" u" that." ]), otherMessage=language.Sentence([ player.thing, u" wrestles with basic personal problems." ]))) events.Success(actor=player.thing, target=target.thing, actorMessage=(u"You put on ", language.Noun( target.thing).definiteNounPhrase(), "."), otherMessage=language.Sentence( [player.thing, " puts on ", target.thing, "."])).broadcast()
def cantFind(self, player, actor, slot, name): """ This hook is invoked when a target cannot be found. This will delegate to a method like C{self.cantFind_<slot>(actor, name)} if one exists, to determine the error message to show to the actor. It will then raise L{eimaginary.ActionFailure} to stop processing of this action. @param player: The L{Thing} doing the searching. @type player: L{IThing} @param actor: The L{IActor} doing the searching. @type actor: L{IActor} @param slot: The slot in question. @type slot: C{str} @param name: The name of the object being searched for. @type name: C{unicode} @raise eimaginary.ActionFailure: always. """ func = getattr(self, "cantFind_" + slot, None) if func: msg = func(actor, name) else: msg = "Who's that?" raise eimaginary.ActionFailure( events.ThatDoesntWork(actorMessage=msg, actor=player))
def set_PROPER(self, player, line, target, value): """ Attempt to change the name of a thing from a proper noun to a common noun or the other way around. @param target: The thing to change. @param value: The string C{"true"} or C{"false"}. """ if value == "true": target.proper = True phrase = '" a proper noun.' elif value == "false": target.proper = False phrase = '" a common noun.' else: raise eimaginary.ActionFailure( events.ThatDoesntMakeSense( actor=player.thing, actorMessage=("Only true and false are valid settings " "for proper."))) events.Success( actor=player.thing, actorMessage=('You make the name of "', language.Noun(target).shortName(), phrase)).broadcast()
def set_GENDER(self, player, line, target, value): """ Attempt to change the gender of a thing. @param target: The thing to change the gender of. @param value: A string naming a gender on L{language.Gender}. """ try: target.gender = getattr(language.Gender, value.upper()) except AttributeError: gender = {language.Gender.MALE: "male", language.Gender.FEMALE: "female", language.Gender.NEUTER: "neuter"}.get(target.gender) raise eimaginary.ActionFailure(events.ThatDoesntMakeSense( actor=player.thing, actorMessage=("Only male, female, and neuter are valid " "genders. You remain ", gender, "."))) else: if player.thing is target: # XXX Why can't I do something with Noun to collapse these # cases? event = events.Success( actor=player.thing, actorMessage=(u"You set your gender to ", value, ".")) else: event = events.Success( actor=player.thing, target=target, actorMessage=("You set ", language.Noun(target).hisHer(), " gender to ", value, "."), targetMessage=(player.thing, " set your gender to ", value, ".")) event.broadcast()
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 tooHeavy(player, target): return eimaginary.ActionFailure( events.ThatDoesntWork( actor=player, target=target, actorMessage=(target, " is too heavy to pick up."), otherMessage=(player, " struggles to lift ", target, ", but fails."), targetMessage=(player, " tries to pick you up, but fails.")))
def do(self, player, line, target): if target in (player.thing, player.thing.location) or target.location is player.thing: raise eimaginary.ActionFailure(events.ThatDoesntMakeSense( actor=player.thing, actorMessage=("You cannot take ", target, "."))) targetTaken(player.thing, target).broadcast() try: target.moveTo(player.thing) except eimaginary.DoesntFit: raise tooHeavy(player.thing, target)
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 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 do(self, player, line, target): dnf = language.Noun(target.thing).definiteNounPhrase() if target.closed: raise eimaginary.ActionFailure(events.ThatDoesntWork( actor=player.thing, target=target.thing, actorMessage=language.Sentence([dnf, " is already closed."]))) target.closed = True evt = events.Success( actor=player.thing, target=target.thing, actorMessage=("You close ", dnf, "."), targetMessage=language.Sentence([player.thing, " closes you."]), otherMessage=language.Sentence([player.thing, " closes ", target.thing, "."])) evt.broadcast()
def do(self, player, line, target): from imaginary import garments try: player.takeOff(target) except garments.InaccessibleGarment, e: raise eimaginary.ActionFailure(events.ThatDoesntWork( actor=player.thing, target=target.thing, actorMessage=(u"You cannot take off ", language.Noun(target.thing).definiteNounPhrase(), u" because you are wearing ", e.obscuringGarment.thing, u"."), otherMessage=language.Sentence([ player.thing, u" gets a dumb look on ", language.Noun(player.thing).hisHer(), u" face."])))
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 do(self, player, line, target): if target.location is not player.thing: raise eimaginary.ActionFailure( events.ThatDoesntMakeSense( actor=player.thing, actorMessage="You can't drop that.")) try: target.moveTo( player.thing.location, arrivalEventFactory=lambda target: events.ArrivalEvent( actor=player.thing, actorMessage=("You drop ", language.Noun(target). definiteNounPhrase(), "."), target=target, targetMessage=(player.thing, " drops you."), otherMessage=(player.thing, " drops ", target, "."))) except eimaginary.DoesntFit: raise insufficientSpace(player.thing)
def do(self, player, line, direction): location = player.location evt = events.Success( location=location, actor=player, otherMessage=(player, " leaves ", direction.name, ".")) evt.broadcast() try: direction.traverse(player) except eimaginary.DoesntFit: raise eimaginary.ActionFailure(events.ThatDoesntWork( actor=player, actorMessage=language.ExpressString( u"There's no room for you there."))) # This is subtly incorrect: see http://divmod.org/trac/ticket/2917 lookAroundActor = iimaginary.IActor(player) LookAround().do(lookAroundActor, "look")
def do(self, player, line, attribute, target, value): """ Dispatch handling to an attribute-specific method. @type attribute: C{unicode} @param attribute: The model-level attribute of which to manipulate the value. Handling of each attribute will be dispatched to a C{set_}-prefixed method for that attribute based on this value. @type target: L{Thing} @param target: The model object to manipulate. @type value: C{unicode} @param value: The new value for the specified attribute. """ try: method = getattr(self, "set_" + attribute.upper()) except AttributeError: raise eimaginary.ActionFailure( events.ThatDoesntMakeSense( actor=player.thing, actorMessage="You cannot set that.")) else: method(player, line, target, value)
def insufficientSpace(player): return eimaginary.ActionFailure( events.ThatDoesntWork( actor=player, actorMessage="There's not enough space for that."))