def give_all(player, items, target_name, target=None): if not target: target = player.location.search_creature(target_name) if not target: raise ActionRefused("%s isn't here with you." % target_name) if target is player: raise ActionRefused("Giving something to yourself doesn't make much sense.") # Actually try to give the items... items = list(items) refused = [] for item in items: try: item.move(target, player) except ActionRefused as x: refused.append((item, str(x))) # Let the player know why giving a particular item failed for item, message in refused: player.tell(message) items.remove(item) if items: items_str = Lang.join(Lang.a(item.title) for item in items) player_str = Lang.capital(player.title) room_msg = "<player>%s</player> gives <item>%s</item> to <creature>%s</creature>." % (player_str, items_str, target.title) target_msg = "<player>%s</player> gives you <item>%s</item>." % (player_str, items_str) player.location.tell(room_msg, exclude_creature=player, specific_targets=[target], specific_target_msg=target_msg) player.tell("You give <creature>%s</creature> <item>%s</item>." % (target.title, items_str)) else: player.tell("You weren't able to give <creature>%s</creature> anything." % target.title)
def match_previously_parsed(self, player, pronoun): # Plural that can match any items or creatures if pronoun == "them": matches = list(self.previously_parsed.obj_order) for obj in matches: if not player.search_item( obj.name) and obj not in player.location.creatures: player.tell("(By '%s' I assume you mean %s.)" % (pronoun, obj.title)) raise ParseError("%s is no longer nearby." % Lang.capital(obj.subjective)) if matches: player.tell("(By '%s' I assume you mean %s.)" % (pronoun, Lang.join(who.title for who in matches))) return [(who, who.name) for who in matches] else: raise ParseError("It is not clear to whom you are referring.") for obj in self.previously_parsed.obj_order: # Are we dealing with an exit? if pronoun == "it": for direction, exit in player.location.exits.items(): if exit is obj: player.tell("(By '%s' I assume you mean '%s'.)" % (pronoun, direction)) return [(obj, direction)] # If not, are we dealing with an item or creature? if pronoun == obj.objective: if player.search_item( obj.name) or obj in player.location.creatures: player.tell("(By '%s' I assume you mean %s.)" % (pronoun, obj.title)) return [(obj, obj.name)] player.tell("(By '%s' I assume you mean %s.)" % (pronoun, obj.title)) raise ParseError("%s is no longer nearby." % Lang.capital(obj.subjective)) raise ParseError("It is not clear who you're referring to.")
def func(player, parsed, ctx): if len(parsed.args) < 2: raise ParseError("You must specify what to give and whom to give it to.") if parsed.unrecognized or player.inventory_size == 0: raise ParseError("You don't have %s to give." % Lang.join(parsed.unrecognized)) # Does the player want to give everything they have? if "all" in parsed.args: if len(parsed.args) != 2: raise ParseError("You must specify who you want to give the items to.") what = player.inventory if parsed.args[0] == "all": Give.give_all(player, what, parsed.args[1]) return else: Give.give_all(player, what, parsed.args[0]) return # Player wants to give just a single item if len([who for who in parsed.obj_order if isinstance(who, Creature)]) > 1: # if there's more than one creature, it's not clear who to give stuff to raise ActionRefused("It's not clear who you want to give things to.") # if the first parsed word is a creature assume the syntax "give creature [the] thing(s)" if isinstance(parsed.obj_order[0], Creature): what = parsed.obj_order[1:] Give.give_all(player, what, None, target=parsed.obj_order[0]) return # if the last parsed word is a creature assume the syntax "give thing(s) [to] creature" elif isinstance(parsed.obj_order[-1], Creature): what = parsed.obj_order[:-1] Give.give_all(player, what, None, target=parsed.obj_order[-1]) return else: raise ActionRefused("It's not clear to who you want to give the item.")
def duration_display(duration): secs = duration.total_seconds() if secs == 0: return "no time at all" hours, secs = divmod(secs, 3600) minutes, secs = divmod(secs, 60) result = [] if hours == 1: result.append("1 hour") elif hours > 1: result.append("%d hours" % hours) if minutes == 1: result.append("1 minute") elif minutes > 1: result.append("%d minutes" % minutes) if secs == 1: result.append("1 second") elif secs > 1: result.append("%d seconds" % secs) return Lang.join(result)
def take_all(player, items, container, where_str=None): # No items were specified if not items: return 0 # Is player taking something from a container? if where_str: player_msg = "You take <item>{items}</item> from the <item>%s</item>" % where_str room_msg = "<player>{{Title}}</player> takes <item>{items}</item> from the <item>%s</item>" % where_str # If not, they must be taking it from the room else: player_msg = "You take <item>{items}</item>" room_msg = "<player>{{Title}}</player> takes <item>{items}</item>" items = list(items) refused = [] # Try to move items one by one. If there are special rules against taking them the item should # raise an ActionRefused exception. for item in items: try: item.move(player, player, verb="take") except ActionRefused as x: refused.append((item, str(x))) # Tell player if any items refused to budge for item, message in refused: player.tell(message) items.remove(item) # Tell player about any items that were moved into their inventory # and tell nearby players and NPCs abou it too! if items: items_str = Lang.join(Lang.a(item.title) for item in items) player.tell(player_msg.format(items=items_str)) player.tell_others(room_msg.format(items=items_str)) return len(items) else: return 0
def drop(items, container): items = list(items) refused = [] for item in items: try: item.move(player.location, player, verb="drop") if container is not player and container in player: Drop.notify_item_removal(player, item, container) except ActionRefused as x: refused.append((item, str(x))) for item, message in refused: items.remove(item) player.tell(message) if items: strItems = Lang.join(Lang.a(item.title) for item in items) player.tell("You discard <item>%s</item>." % strItems) player.tell_others("{Title} drops %s." % strItems) else: player.tell("Nothing was dropped.")
def func(player, parsed, ctx): if len(parsed.args) < 2: raise ParseError( "You need to tell me what to put and where you'd like to put it." ) # If player specified all they want to put their entire inventory into the container if parsed.args[0] == "all": # Does the player have anything in their inventory if player.inventory_size == 0: raise ActionRefused("You don't seem to be carrying anything.") if len(parsed.args) != 2: raise ParseError( "You need to tell me what to put and where you'd like to put it." ) what = list(player.inventory) where = parsed.obj_order[ -1] # The last item represents the "where" elif parsed.unrecognized: raise ActionRefused("I don't see %s here." % Lang.join(parsed.unrecognized)) else: what = parsed.obj_order[:-1] where = parsed.obj_order[-1] if isinstance(where, Creature): raise ActionRefused( "You can't do that but you might be able to give it to them..." ) inventory_items = [] refused = [] word_before = parsed.obj_info[where].previous_word or "in" if word_before != "in" and word_before != "into": raise ActionRefused( "You can only put an item 'in' or 'into' a container of some sort." ) for item in what: if item is where: player.tell("You can't put something inside of itself.") continue try: # Are they using an item they are already carrying? if item in player: item.move(where, player) inventory_items.append(item) # If the item is in the room then we'll take it first and then put it into the container # TODO: We need to handle in a linguistic stylish way the situation where one part of this two-step operation fails elif item in player.location: item.move(player, player) item.move(where, player) player.tell("You take %s and put it in the %s." % (item.title, where.name)) player.tell_others( "{Title} takes %s and puts it in the %s." % (item.title, where.name)) except ActionRefused as x: refused.append((item, str(x))) # The item refused to move at some point so inform the player for item, message in refused: player.tell(message) if inventory_items: items_msg = Lang.join( Lang.a(item.title) for item in inventory_items) player.tell_others("{Title} puts %s in the %s." % (items_msg, where.name)) player.tell( "You put <item>{items}</item> in the <item>{where}</item>.". format(items=items_msg, where=where.name))
def func(player, parsed, ctx): # Did the player specify something to be taken? if len(parsed.args) == 0: raise ParseError("What would you like to take?") # Player is taking a single item if len(parsed.args) == 1: obj_names = parsed.args where = None # Player wants to try something more complicated... else: if parsed.obj_order: last_obj = parsed.obj_order[-1] # Player is trying to take one or more (comma separated) items from something or someone if parsed.obj_info[last_obj].previous_word == "from": obj_names = parsed.args[:-1] where = last_obj # Player is trying to take one or more (comma separated) items else: # take x[,y and z] obj_names = parsed.args where = None else: # take x[,y and z] - unrecognised names obj_names = parsed.args where = None # Basic sanity check if where is player: raise ActionRefused("You can't take items from yourself.") # Notify others in the room that something is creature taken if isinstance(where, Creature): player.tell_others("{Title} takes something from %s." % where.title) # Player wants to take all teh things if obj_names == ["all"]: # Are we taking items from a container? if where: # Is the container on the player's person or in the room with the player? if where in player or where in player.location: # Is there anything in it? if where.inventory_size > 0: Get.take_all(player, where.inventory, where, where.title) return else: raise ActionRefused("It appears to be empty.") raise ActionRefused("What are you trying to take?") # We're taking items from the room the player is in else: # Anything here to take? if not player.location.items: raise ActionRefused( "There appears to be nothing here you can carry.") # Yes, so dump everything into the player's inventory. else: Get.take_all(player, player.location.items, player.location) return # Player is trying to take one or more specific items else: # Are we taking items from a container? if where: # Yes, is the container on the player's person or in the room? if where in player or where in player.location: # Take each item from the specified container items_by_name = { item.name: item for item in where.inventory } items_to_take = [] for name in obj_names: # If it's there let's take it... if name in items_by_name: items_to_take.append(items_by_name[name]) # ...otherwise tell the player their action is misguided. else: player.tell("There's no %s in there." % name) Get.take_all(player, items_to_take, where, where.title) return else: # Looks like the player is trying to take items from the room itself if parsed.unrecognized: player.tell("You don't see %s here." % Lang.join(parsed.unrecognized)) creatures = [ item for item in parsed.obj_order if item in player.location.creatures ] for creature in creatures: player.tell("You can not pick up other living creatures.") if not player.location.items: raise ActionRefused( "There appears to be nothing here you can carry.") else: items_to_take = [] for item in parsed.obj_order: # If item is here let the player take it! if item in player.location.items: items_to_take.append(item) # If the item is an exit let's remind the user it can't be taken elif isinstance(item, Exit): raise ActionRefused( "That is not something you can carry.") elif item not in player.location.creatures: if item in player: player.tell("You already have that item.") else: player.tell( "There's no <item>%s</item> here." % item.name) Get.take_all(player, items_to_take, player.location) return
def look(self, exclude_creature=None, short=False): paragraphs = ["<location>[" + self.name + "]</location>"] # Construct the short version of a location description. if short: if self.exits and context.config.show_exits_in_look: paragraphs.append("<exit>Exits</exit>: " + ", ".join(sorted(set(self.exits.keys())))) if self.items: item_names = sorted(item.name for item in self.items) paragraphs.append("<item>You see</item>: " + Lang.join(item_names)) if self.creatures: creature_names = sorted(creature.name for creature in self.creatures if creature != exclude_creature) if creature_names: paragraphs.append("<creature>Present</creature>: " + Lang.join(creature_names)) return paragraphs # # Construct the long version of a location description. # if self.description: paragraphs.append(self.description) if self.exits and context.config.show_exits_in_look: # Keep track of exits we've already described exits_seen = set() exit_paragraph = [] for exit_name in sorted(self.exits): exit = self.exits[exit_name] if exit not in exits_seen: exits_seen.add(exit) exit_paragraph.append(exit.short_description) paragraphs.append(" ".join(exit_paragraph)) items_and_creatures = [] # We'll preferentially use item short descriptions if provided and resort to the item's title if necessary items_with_short_descr = [item for item in self.items if item.short_description] items_without_short_descr = [item for item in self.items if not item.short_description] uniq_descriptions = set() # If there's a short description for an item use it preferentially if items_with_short_descr: for item in items_with_short_descr: uniq_descriptions.add(item.short_description) # Add unique item description to our running list of things to describe items_and_creatures.extend(uniq_descriptions) # If there's no short description for an item we'll just use the item's title if items_without_short_descr: titles = sorted([Lang.a(item.title) for item in items_without_short_descr]) items_and_creatures.append("You see " + Lang.join(titles) + ".") # We'll preferentially use creature short descriptions if provided and resort to the title if necessary creatures_with_short_descr = [creature for creature in self.creatures if creature != exclude_creature and creature.short_description] creatures_without_short_descr = [creature for creature in self.creatures if creature != exclude_creature and not creature.short_description] # If there's a short descriptions for a creature use it preferentially if creatures_without_short_descr: titles = sorted(creature.title for creature in creatures_without_short_descr) if titles: titles_str = Lang.join(titles) if len(titles) > 1: titles_str += " are here." else: titles_str += " is here." items_and_creatures.append(Lang.capital(titles_str)) uniq_descriptions = set() # If there's no short description for a creature we'll just use the item's title if creatures_with_short_descr: for creature in creatures_with_short_descr: uniq_descriptions.add(creature.short_description) # Add unique creature descriptions to our running list of things to describe items_and_creatures.extend(uniq_descriptions) if items_and_creatures: paragraphs.append(" ".join(items_and_creatures)) return paragraphs