Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
    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.")
Ejemplo n.º 3
0
    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.")
Ejemplo n.º 4
0
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)
Ejemplo n.º 5
0
    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
Ejemplo n.º 6
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.")
Ejemplo n.º 7
0
    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))
Ejemplo n.º 8
0
    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
Ejemplo n.º 9
0
    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