示例#1
0
    def func(self):
        "implements the command."

        caller = self.caller
        args = self.args.strip()
        wield = self.wield

        # reset flag, this should stay at the beginning of the command
        if wield:
            self.wield = False

        if not args:
            caller.msg("Wear what?")
            return

        # this will search for a target
        obj = caller.search(args)

        if not obj:
            return

        if not obj in caller.contents:
            caller.msg("You don't have %s in your inventory." % obj)

        slots = utils.make_iter(obj.db.slot)

        if wield:
            if not caller.equip.primary_hand in slots     \
              and not caller.equip.secondary_hand in slots:
                caller.msg("You can't wield %s." % obj)
                return

        # equip primary and secondary hands with the proper feedback
        if caller.equip.primary_hand in slots  \
           or caller.equip.secondary_hand in slots:
            action = 'wield'
        else:
            action = 'wear'

        if not obj.db.slot or not obj.access(caller, 'equip'):
            caller.msg("You can't equip %s." % obj)
            return

        if obj in caller.equip.items:
            caller.msg("You're already %sing %s." % (action, obj.name))
            return

        if not caller.equip.add(obj):
            string = "You can't equip %s." % obj
            if [slot for slot in slots if slot in caller.equip.slots]:
                string += " You already have something there."
            caller.msg(string)
            return

        # call hook
        if hasattr(obj, "at_equip"):
            obj.at_equip(caller)
        caller.msg("You %s %s." % (action, obj))
        caller.location.msg_contents("%s %ss %s." % (caller.name.capitalize(), action, obj),
                                     exclude=caller)
示例#2
0
    def func(self):
        """
        Handle the looking - add fallback to details.
        """
        caller = self.caller
        args = self.args
        if args:
            looking_at_obj = caller.search(args, use_nicks=True, quiet=True)
            if not looking_at_obj:
                # no object found. Check if there is a matching
                # detail at location.
                location = caller.location
                if location and hasattr(location, "return_detail") and callable(location.return_detail):
                    detail = location.return_detail(args)
                    if detail:
                        # we found a detail instead. Show that.
                        caller.msg("{y%s{n\n" % args + detail)
                        return
                # no detail found. Trigger delayed error messages
                _AT_SEARCH_RESULT(caller, args, looking_at_obj, False)
                return
            else:
                if len(looking_at_obj) >1:
                    caller.msg("Есть несколько объектов с таким именем(укажи нужный):")
                    i=1
                    for item in looking_at_obj:
                        if item.has_player:
                            caller.msg("%s-%s (Игрок)" % (i,item.key))
                        elif item.db.is_corpse:
                            caller.msg("%s-%s (Труп)" % (i,item.key))
                        elif item.db.npc:
                            caller.msg("%s-%s (NPC)" % (i,item.key))
                        elif item.db.is_weapon:
                            caller.msg("%s-%s (Оружие)" % (i,item.key))
                        else:
                            caller.msg("%s-%s (Объект)" % (i,item.key))
                        i = i +1
                    return
                else:                
                    # we need to extract the match manually.
                    looking_at_obj = utils.make_iter(looking_at_obj)[0]
        else:
            looking_at_obj = caller.location
            if not looking_at_obj:
                caller.msg("Тебе некуда смотреть!")
                return

        if not hasattr(looking_at_obj, 'return_appearance'):
            # this is likely due to us having a player instead
            looking_at_obj = looking_at_obj.character
        if not looking_at_obj.access(caller, "view"):
            caller.msg("Не могу найти '%s'." % args)
            return
        # get object's appearance
        caller.msg(looking_at_obj.return_appearance(caller))
        # the object's at_desc() method.
        looking_at_obj.at_desc(looker=caller)
示例#3
0
    def combat_msg(self, message, actor, target=None, exclude=(), **kwargs):
        """Sends messaging to combat participants and vicinity.

        Args:
          message (str): Message string in director stance to be
                delivered. Contains string format keys matching
                the other arguments as described below.

          exclude (tuple, optional): Not substituted into the message string;
                a tuple or list of objects to exclude from receiving the message.

          actor (Character): the character taking the action, keyed
                in messages as {actor}.
          target (Character, optional): the character or object being
                targeted in the action, keyed in messages as {target}.
          kwargs: any other format substitution keys should be passed
                in as kwargs.

        Example:
            ch.combat_msg("{actor} attacks {target} with {weapon}.",
                          actor=attacker,
                          target=defender,
                          weapon=weapon)
        """
        exclude = make_iter(exclude) if exclude else []

        kwargs.update(dict(actor=actor, target=target))

        for character in self.db.characters.values():
            if character == actor:
                cbt_prefix = '|b->|n '
            elif character == target:
                cbt_prefix = '|m<-|n '
            else:
                cbt_prefix = '|x..|n '

            if character not in exclude:
                mapping = {token: val.get_display_name(character)
                                   if hasattr(val, 'get_display_name')
                                   else str(val)
                           for token, val in kwargs.items()}

                character.msg(
                    (cbt_prefix + message).format(**mapping),
                    prompt=_COMBAT_PROMPT.format(tr=character.traits))

        # send messaging to others in the same room but not in combat
        actor.location.msg_contents(
            text=message,
            mapping=kwargs,
            exclude=exclude + self.db.characters.values()
        )
示例#4
0
文件: equip.py 项目: knoxx093/ainneve
 def add(self, obj):
     """ 
     Add an object to character's equip.
     """
     slots = utils.make_iter(obj.db.slot)
     free_slots = [sl for sl in slots if sl in self.empty_slots]
     if not free_slots:
         return False
     if obj.db.slot_operator == 'AND':
         if len(free_slots) != len(slots):
             return False
         for slot in free_slots:
             self._set(slot, obj)
         return True
     slot = free_slots[0]
     self._set(slot, obj)
     return True
示例#5
0
文件: mail.py 项目: BlauFeuer/evennia
    def search_targets(self, namelist):
        """
        Search a list of targets of the same type as caller.

        Args:
            caller (Object or Account): The type of object to search.
            namelist (list): List of strings for objects to search for.

        Returns:
            targetlist (list): List of matches, if any.

        """
        nameregex = r"|".join(r"^%s$" % re.escape(name) for name in make_iter(namelist))
        if hasattr(self.caller, "account") and self.caller.account:
            matches = list(ObjectDB.objects.filter(db_key__iregex=nameregex))
        else:
            matches = list(AccountDB.objects.filter(username__iregex=nameregex))
        return matches
示例#6
0
    def func(self):
        """
        Handle the looking - add fallback to details.
        """
        caller = self.caller
        args = self.args
        if args:
            looking_at_obj = caller.search(args,
                                           candidates=caller.location.contents + caller.contents,
                                           use_nicks=True,
                                           quiet=True)
            if not looking_at_obj:
                # no object found. Check if there is a matching
                # detail at location.
                location = caller.location
                if location and hasattr(location, "return_detail") and callable(location.return_detail):
                    detail = location.return_detail(args)
                    if detail:
                        # we found a detail instead. Show that.
                        caller.msg(detail)
                        return
                # no detail found. Trigger delayed error messages
                _AT_SEARCH_RESULT(looking_at_obj, caller, args, quiet=False)
                return
            else:
                # we need to extract the match manually.
                looking_at_obj = utils.make_iter(looking_at_obj)[0]
        else:
            looking_at_obj = caller.location
            if not looking_at_obj:
                caller.msg("You have no location to look at!")
                return

        if not hasattr(looking_at_obj, 'return_appearance'):
            # this is likely due to us having a player instead
            looking_at_obj = looking_at_obj.character
        if not looking_at_obj.access(caller, "view"):
            caller.msg("Could not find '%s'." % args)
            return
        # get object's appearance
        caller.msg(looking_at_obj.return_appearance(caller))
        # the object's at_desc() method.
        looking_at_obj.at_desc(looker=caller)
示例#7
0
    def func(self):
        """
        Handle the looking - add fallback to details.
        """
        caller = self.caller
        args = self.args
        if args:
            looking_at_obj = caller.search(args,
                                           candidates=caller.location.contents + caller.contents,
                                           use_nicks=True,
                                           quiet=True)
            if not looking_at_obj:
                # no object found. Check if there is a matching
                # detail at location.
                location = caller.location
                if location and hasattr(location, "return_detail") and callable(location.return_detail):
                    detail = location.return_detail(args)
                    if detail:
                        # we found a detail instead. Show that.
                        caller.msg(detail)
                        return
                # no detail found. Trigger delayed error messages
                _AT_SEARCH_RESULT(looking_at_obj, caller, args, quiet=False)
                return
            else:
                # we need to extract the match manually.
                looking_at_obj = utils.make_iter(looking_at_obj)[0]
        else:
            looking_at_obj = caller.location
            if not looking_at_obj:
                caller.msg("You have no location to look at!")
                return

        if not hasattr(looking_at_obj, 'return_appearance'):
            # this is likely due to us having a player instead
            looking_at_obj = looking_at_obj.character
        if not looking_at_obj.access(caller, "view"):
            caller.msg("Could not find '%s'." % args)
            return
        # get object's appearance
        caller.msg(looking_at_obj.return_appearance(caller))
        # the object's at_desc() method.
        looking_at_obj.at_desc(looker=caller)
示例#8
0
    def search_targets(self, namelist):
        """
        Search a list of targets of the same type as caller.

        Args:
            caller (Object or Account): The type of object to search.
            namelist (list): List of strings for objects to search for.

        Returns:
            targetlist (list): List of matches, if any.

        """
        nameregex = r"|".join(r"^%s$" % re.escape(name)
                              for name in make_iter(namelist))
        if hasattr(self.caller, "account") and self.caller.account:
            matches = list(ObjectDB.objects.filter(db_key__iregex=nameregex))
        else:
            matches = list(
                AccountDB.objects.filter(username__iregex=nameregex))
        return matches
示例#9
0
    def setup_home(self, owners=None, sethomespace=True):
        owners = utils.make_iter(owners)
        for owner in owners:
            self.add_homeowner(owner, sethomespace)
        self.tags.add("home")
        for ent in self.entrances:
            ent.locks.add("usekey: perm(builders) or roomkey(%s)" % self.id)
        if "HomeCmdSet" not in [ob.key for ob in self.cmdset.all()]:
            self.cmdset.add(HOMECMD, permanent=True)
        from world.dominion.models import AssetOwner

        try:
            # add our room owner as a homeowner if they're a player
            aowner = AssetOwner.objects.get(id=self.db.room_owner)
            char = aowner.player.player.char_ob
            if char not in owners:
                self.add_homeowner(char, False)
        except (AttributeError, AssetOwner.DoesNotExist, ValueError,
                TypeError):
            pass
示例#10
0
    def func(self):
        """Handle sensing objects in different ways. WIP: Expanding to handle other senses."""
        char = self.character
        # player = self.player
        args = self.args.strip()
        cmd = self.cmdstring

        if cmd != 'l' and 'look' not in cmd:
            if 'sense' in cmd:
                if char and char.location:
                    obj_list = char.search(args,
                                           candidates=[char.location] +
                                           char.location.contents +
                                           char.contents) if args else char
                    if obj_list and obj_list.db.senses:
                        char.msg('You can sense %s in the following ways: %s' %
                                 (obj_list, obj_list.db.senses.keys()))
                        obj = obj_list
                        verb_msg = "You can interact with %s: " % obj_list.get_display_name(
                            self.session)
                    else:
                        obj = char
                        verb_msg = "You can be interacted with by: "
                    verbs = obj.locks
                    collector = ''
                    show_red = True if obj.access(char, 'examine') else False
                    for verb in ("%s" % verbs).split(';'):
                        element = verb.split(':')[0]
                        if element == 'call':
                            continue
                        name = element[2:] if element[:2] == 'v-' else element
                        if obj.access(
                                char,
                                element):  # obj lock checked against actor
                            collector += "|lctry %s #%s|lt|g%s|n|le " % (
                                name, obj.id, name)
                        elif show_red:
                            collector += "|r%s|n " % name
                    char.msg(verb_msg + "%s" % collector)
            elif 'taste' in cmd or 'touch' in cmd or 'smell' in cmd or 'listen' in cmd:  # Specific sense (not look)
                obj_list = char.search(args, candidates=[char.location] + char.location.contents + char.contents)\
                    if args else char
                char.msg('You try to sense %s.' %
                         (obj_list if obj_list else 'something'))
                # Object to sense might have been found. Check the senses dictionary.
                if obj_list and obj_list.db.senses and cmd in obj_list.db.senses:
                    senses_of = obj_list.db.senses[cmd]
                    if None in senses_of:
                        details_of = obj_list.db.details
                        if details_of and senses_of[None] in details_of:
                            entry = details_of[senses_of[None]]
                            char.msg('You sense %s from %s.' %
                                     (entry, obj_list))
                # First case: look for an object in room, inventory, room contents, their contents,
                # and their contents contents with tagged restrictions, then if no match is found
                # in their name or alias, look at the senses tables in each of these objects: The
                # Senses attribute is a dictionary of senses that point to the details dictionary
                # entries. Senses dictionary allows for aliases in the details and pointing
                # specific senses to specific entries.
                #
                # If not looking for a specific object or entry, list objects and aspects of the particular
                # sense. Start with that first, and start with the char's own self and inventory.
                # when the /self;me and /inv;inventory switch is used?
            return
        if args:
            # Parsing for object/aspect/detail:
            # Box's wheel = Red spinners lit with pyrotechnics.
            # object, aspect = args.rsplit("'s ", 1)
            # detail = self.rhs.strip()

            obj = char.search(args,
                              candidates=char.location.contents +
                              char.contents,
                              use_nicks=True,
                              quiet=True)
            if not obj:
                # no object found. Check if there is a matching detail around the location.
                # TODO: Restrict search for details by possessive parse:  [object]'s [aspect]
                candidates = [char.location
                              ] + char.location.contents + char.contents
                for location in candidates:
                    # TODO: Continue if look location is not visible to looker.
                    if location and hasattr(location,
                                            "return_detail") and callable(
                                                location.return_detail):
                        detail = location.return_detail(args)
                        if detail:
                            # Show found detail.
                            char.msg(detail)
                            return  # TODO: Add /all switch to override return here to view all details.
                # no detail found. Trigger delayed error messages
                _AT_SEARCH_RESULT(obj, char, args, quiet=False)
                return
            else:
                # we need to extract the match manually.
                obj = utils.make_iter(obj)[0]
        else:
            obj = char.location
            if not obj:
                char.msg("There is nothing to sense here.")
                return
        if not hasattr(obj, 'return_appearance'):
            # this is likely due to a player calling the command.
            obj = obj.character
        if not obj.access(char, 'view'):
            char.msg("You are unable to sense '%s'." % args)
            return
        # get object's appearance
        char.msg(obj.return_appearance(char))
        # the object's at_desc() method.
        obj.at_desc(looker=char)
示例#11
0
def prompt_choice(caller, question="", prompts=None, choicefunc=None, force_choose=False):
    """
    This sets up a simple choice questionnaire. Question will be
    asked, followed by a series of prompts. Note that this isn't
    making use of the menu node system but uses the MenuCmdSet.

    Args:
        caller (object): The object calling and being offered the choice
        question (str, optional): Text describing the offered choice
        prompts (list, optional): List of strings defining the available choises.
        choicefunc (function, optional): A function called as
            `choicefunc(self)` when a choice is made. Inside this function,
            `self.caller` is available and `self.prompt_index` is the index
            (starting with 0) matching the chosen prompt in the `prompts` list.
        force_choose - force user to make a choice

    Examples:

        ```python
            def mychoice(self):
                self.caller.msg("Index of choice is %s." % self.prompt_index)

            prompt_choice(caller, "Make a choice:", prompts=["A","B","C"], choicefunc=mychoice)
        ```

        When triggering the above from a command or @py prompt you get the following options:

        >>> Make a choice:
            [1] A
            [2] B
            [3] C
        <<< 2
        >>> Index of choice is 1.

    """

    # creating and defining commands
    count = 0
    choices = ""
    commands = []

    for choice in utils.make_iter(prompts):
        # create the available choice-commands
        count += 1
        choices += "\n{lc%d{lt[%d]{le %s" % (count, count, choice)

        cmdfunc = CmdMenuNode(key="%d" % count)
        cmdfunc.prompt_index = count-1
        if choicefunc:
            cmdfunc.choicefunc = choicefunc
            def _choicefunc(self):
                self.caller.cmdset.delete('menucmdset')
                del self.caller.db._menu_data
                self.choicefunc(self)
            # set a new method "callback" on cmdfunc
            cmdfunc.callback = MethodType(_choicefunc, cmdfunc, CmdMenuNode)

        commands.append(cmdfunc)

    if not force_choose:
        choices += "\n{lc{lt[No choice]{le"

    prompt = question + choices + "\nPlease choose one."

    # create the error-reporting command
    errorcmd = CmdMenuNode(key=CMD_NOMATCH)
    if force_choose:
        def _errorcmd(self):
            self.caller.msg("You can only choose given choices.")
    else:
        if choicefunc:
            errorcmd.choicefunc = choicefunc
            def _errorcmd(self):
                self.caller.msg("No choice.")
                self.caller.cmdset.delete('menucmdset')
                del self.caller.db._menu_data
                self.choicefunc(self)
    errorcmd.callback = MethodType(_errorcmd, errorcmd, CmdMenuNode)

    # create the fallback command
    defaultcmd = CmdMenuNode(key=CMD_NOINPUT)
    if force_choose:
        def _defaultcmd(self):
            caller.msg(prompt)
    else:
        if choicefunc:
            defaultcmd.choicefunc = choicefunc
            def _defaultcmd(self):
                self.caller.msg("No choice.")
                self.caller.cmdset.delete('menucmdset')
                del self.caller.db._menu_data
                self.choicefunc(self)
    defaultcmd.callback = MethodType(_defaultcmd, defaultcmd, CmdMenuNode)

    # creating cmdset (this will already have look/help commands)
    choicecmdset = MenuCmdSet()
    for cmdfunc in commands:
        choicecmdset.add(cmdfunc)
    choicecmdset.add(errorcmd)
    choicecmdset.add(defaultcmd)
    choicecmdset.add(CmdMenuLook())
    choicecmdset.add(CmdMenuHelp())

    # assigning menu data flags to caller.
    caller.db._menu_data = {"help": "Please select.",
                            "look": prompt}

    # assign cmdset and ask question
    caller.cmdset.add(choicecmdset)
    caller.msg(prompt)
示例#12
0
文件: utils.py 项目: ChrisLR/scrolls
def match_string(criteria, string):
    string = make_iter(string)
    return True if string_partial_matching(string, criteria) else False
示例#13
0
def prompt_choice(caller, question="", prompts=None, choicefunc=None, force_choose=False):
    """
    This sets up a simple choice questionnaire. Question will be
    asked, followed by a series of prompts. Note that this isn't
    making use of the menu node system.

    caller - the object calling and being offered the choice
    question - text describing the offered choice
    prompts - list of choices
    choicefunc - functions callback to be called as func(self) when
                 make choice (self.caller is available) The function's definition
                 should be like func(self, menu_node), and menu_node.key is user's
                 choice.
    force_choose - force user to make a choice or not
    """

    # creating and defining commands
    count = 0
    choices = ""
    commands = []
    for choice in utils.make_iter(prompts):
        count += 1
        choices += "\n{lc%d{lt[%d]{le %s" % (count, count, choice)

        cmdfunc = CmdMenuNode(key="%d" % count)
        if choicefunc:
            cmdfunc.choicefunc = choicefunc
            def _choicefunc(self):
                self.caller.cmdset.delete('menucmdset')
                del self.caller.db._menu_data
                self.choicefunc(self)
            cmdfunc.callback = MethodType(_choicefunc, cmdfunc, CmdMenuNode)

        commands.append(cmdfunc)

    if not force_choose:
        choices += "\n{lc{lt[No choice]{le"

    prompt = question + choices + "\nPlease choose one."

    errorcmd = CmdMenuNode(key=CMD_NOMATCH)
    if force_choose:
        def _errorcmd(self):
            self.caller.msg("You can only choose given choices.")
    else:
        if choicefunc:
            errorcmd.choicefunc = choicefunc
            def _errorcmd(self):
                self.caller.msg("No choice.")
                self.caller.cmdset.delete('menucmdset')
                del self.caller.db._menu_data
                self.choicefunc(self)
    errorcmd.callback = MethodType(_errorcmd, errorcmd, CmdMenuNode)

    defaultcmd = CmdMenuNode(key=CMD_NOINPUT)
    if force_choose:
        def _defaultcmd(self):
            caller.msg(prompt)
    else:
        if choicefunc:
            defaultcmd.choicefunc = choicefunc
            def _defaultcmd(self):
                self.caller.msg("No choice.")
                self.caller.cmdset.delete('menucmdset')
                del self.caller.db._menu_data
                self.choicefunc(self)
    defaultcmd.callback = MethodType(_defaultcmd, defaultcmd, CmdMenuNode)

    # creating cmdset (this will already have look/help commands)
    choicecmdset = MenuCmdSet()
    for cmdfunc in commands: choicecmdset.add(cmdfunc)
    choicecmdset.add(errorcmd)
    choicecmdset.add(defaultcmd)
    choicecmdset.add(CmdMenuLook())
    choicecmdset.add(CmdMenuHelp())

    # assigning menu data flags to caller.
    caller.db._menu_data = {"help": "Please select.",
                            "look": prompt}

    # assign cmdset and ask question
    caller.cmdset.add(choicecmdset)
    caller.msg(prompt)
示例#14
0
    def func(self):
        """Create the nickname"""
        def _cy(string):
            "add color to the special markers"
            return re.sub(r"(\$[0-9]+|\*|\?|\[.+?\])", r"|Y\1|n", string)

        caller = self.caller
        switches = self.switches
        nicktypes = [
            switch for switch in switches
            if switch in ("object", "account", "inputline")
        ]
        specified_nicktype = bool(nicktypes)
        nicktypes = nicktypes if specified_nicktype else ["inputline"]

        nicklist = (
            utils.make_iter(
                caller.nicks.get(category="inputline", return_obj=True) or [])
            + utils.make_iter(
                caller.nicks.get(category="object", return_obj=True) or []) +
            utils.make_iter(
                caller.nicks.get(category="account", return_obj=True) or []))

        if "list" in switches or self.cmdstring in ("nicks", ):

            if not nicklist:
                string = "|wNessun alias definito.|n"
            else:
                table = self.styled_table("#", "Type", "Nick match",
                                          "Replacement")
                for inum, nickobj in enumerate(nicklist):
                    _, _, nickvalue, replacement = nickobj.value
                    table.add_row(
                        str(inum + 1),
                        nickobj.db_category,
                        _cy(nickvalue),
                        _cy(replacement),
                    )
                string = "|wAlias definiti:|n\n%s" % table
            caller.msg(string)
            return

        if "clearall" in switches:
            caller.nicks.clear()
            caller.account.nicks.clear()
            caller.msg("Rimossi tutti gli alias.")
            return

        if "delete" in switches or "del" in switches:
            if not self.args or not self.lhs:
                caller.msg(
                    "Uso: nick/delete <nick> OPPURE <#num> ('alias' per la lista)"
                )
                return
            # see if a number was given
            arg = self.args.lstrip("#")
            oldnicks = []
            if arg.isdigit():
                # we are given a index in nicklist
                delindex = int(arg)
                if 0 < delindex <= len(nicklist):
                    oldnicks.append(nicklist[delindex - 1])
                else:
                    caller.msg(
                        "Non è un alias valido. Vedi 'alias' per la lista.")
                    return
            else:
                if not specified_nicktype:
                    nicktypes = ("object", "account", "inputline")
                for nicktype in nicktypes:
                    oldnicks.append(
                        caller.nicks.get(arg,
                                         category=nicktype,
                                         return_obj=True))

            oldnicks = [oldnick for oldnick in oldnicks if oldnick]
            if oldnicks:
                for oldnick in oldnicks:
                    nicktype = oldnick.category
                    nicktypestr = "%s-nick" % nicktype.capitalize()
                    _, _, old_nickstring, old_replstring = oldnick.value
                    caller.nicks.remove(old_nickstring, category=nicktype)
                    caller.msg("%s rimosso: '|w%s|n' -> |w%s|n." %
                               (nicktypestr, old_nickstring, old_replstring))
            else:
                caller.msg("Nessun alias corrispondente da rimuovere.")
            return

        if not self.rhs and self.lhs:
            # check what a nick is set to
            strings = []
            if not specified_nicktype:
                nicktypes = ("object", "account", "inputline")
            for nicktype in nicktypes:
                nicks = [
                    nick for nick in utils.make_iter(
                        caller.nicks.get(category=nicktype, return_obj=True))
                    if nick
                ]
                for nick in nicks:
                    _, _, nick, repl = nick.value
                    if nick.startswith(self.lhs):
                        strings.append("{}-nick: '{}' -> '{}'".format(
                            nicktype.capitalize(), nick, repl))
            if strings:
                caller.msg("\n".join(strings))
            else:
                caller.msg("Non è stato trovato nessun alias per '{}'".format(
                    self.lhs))
            return

        if not self.rhs and self.lhs:
            # check what a nick is set to
            strings = []
            if not specified_nicktype:
                nicktypes = ("object", "account", "inputline")
            for nicktype in nicktypes:
                if nicktype == "account":
                    obj = account
                else:
                    obj = caller
                nicks = utils.make_iter(
                    obj.nicks.get(category=nicktype, return_obj=True))
                for nick in nicks:
                    _, _, nick, repl = nick.value
                    if nick.startswith(self.lhs):
                        strings.append("{}-nick: '{}' -> '{}'".format(
                            nicktype.capitalize(), nick, repl))
            if strings:
                caller.msg("\n".join(strings))
            else:
                caller.msg("Non è stato trovato nessun alias per '{}'".format(
                    self.lhs))
            return

        if not self.rhs and self.lhs:
            # check what a nick is set to
            strings = []
            if not specified_nicktype:
                nicktypes = ("object", "account", "inputline")
            for nicktype in nicktypes:
                if nicktype == "account":
                    obj = account
                else:
                    obj = caller
                nicks = utils.make_iter(
                    obj.nicks.get(category=nicktype, return_obj=True))
                for nick in nicks:
                    _, _, nick, repl = nick.value
                    if nick.startswith(self.lhs):
                        strings.append("{}-nick: '{}' -> '{}'".format(
                            nicktype.capitalize(), nick, repl))
            if strings:
                caller.msg("\n".join(strings))
            else:
                caller.msg("Non è stato trovato nessun alias per '{}'".format(
                    self.lhs))
            return

        if not self.args or not self.lhs:
            caller.msg("Uso: nick[/switches] <alias> = [nome completo]")
            return

        # setting new nicks

        nickstring = self.lhs
        replstring = self.rhs

        if replstring == nickstring:
            caller.msg(
                "Non ha senso settare un alias uguale al nome da rimpiazzare..."
            )
            return

        # check so we have a suitable nick type
        errstring = ""
        string = ""
        for nicktype in nicktypes:
            nicktypestr = "%s-nick" % nicktype.capitalize()
            old_nickstring = None
            old_replstring = None

            oldnick = caller.nicks.get(key=nickstring,
                                       category=nicktype,
                                       return_obj=True)
            if oldnick:
                _, _, old_nickstring, old_replstring = oldnick.value
            if replstring:
                # creating new nick
                errstring = ""
                if oldnick:
                    if replstring == old_replstring:
                        string += "\nGià presente: %s." % nicktypestr.lower()
                    else:
                        string += "\n%s '|w%s|n' aggiornato: '|w%s|n'." % (
                            nicktypestr,
                            old_nickstring,
                            replstring,
                        )
                else:
                    string += "\n%s '|w%s|n' impostato: '|w%s|n'." % (
                        nicktypestr,
                        nickstring,
                        replstring,
                    )
                try:
                    caller.nicks.add(nickstring, replstring, category=nicktype)
                except NickTemplateInvalid:
                    caller.msg(
                        "È necessario usare gli stessi $-markers sia nell'alias che nel testo da rimpiazzare."
                    )
                    return
            elif old_nickstring and old_replstring:
                # just looking at the nick
                string += "\n%s '|w%s|n' sostituisce: '|w%s|n'." % (
                    nicktypestr,
                    old_nickstring,
                    old_replstring,
                )
                errstring = ""
        string = errstring if errstring else string
        caller.msg(_cy(string))
示例#15
0
def prompt_choice(caller,
                  question="",
                  prompts=None,
                  choicefunc=None,
                  force_choose=False):
    """
    This sets up a simple choice questionnaire. Question will be
    asked, followed by a series of prompts. Note that this isn't
    making use of the menu node system.

    caller - the object calling and being offered the choice
    question - text describing the offered choice
    prompts - list of choices
    choicefunc - functions callback to be called as func(self) when
                 make choice (self.caller is available) The function's definition
                 should be like func(self, menu_node), and menu_node.key is user's
                 choice.
    force_choose - force user to make a choice or not
    """

    # creating and defining commands
    count = 0
    choices = ""
    commands = []
    for choice in utils.make_iter(prompts):
        count += 1
        choices += "\n{lc%d{lt[%d]{le %s" % (count, count, choice)

        cmdfunc = CmdMenuNode(key="%d" % count)
        if choicefunc:
            cmdfunc.choicefunc = choicefunc

            def _choicefunc(self):
                self.caller.cmdset.delete('menucmdset')
                del self.caller.db._menu_data
                self.choicefunc(self)

            cmdfunc.callback = MethodType(_choicefunc, cmdfunc, CmdMenuNode)

        commands.append(cmdfunc)

    if not force_choose:
        choices += "\n{lc{lt[No choice]{le"

    prompt = question + choices + "\nPlease choose one."

    errorcmd = CmdMenuNode(key=CMD_NOMATCH)
    if force_choose:

        def _errorcmd(self):
            self.caller.msg("You can only choose given choices.")
    else:
        if choicefunc:
            errorcmd.choicefunc = choicefunc

            def _errorcmd(self):
                self.caller.msg("No choice.")
                self.caller.cmdset.delete('menucmdset')
                del self.caller.db._menu_data
                self.choicefunc(self)

    errorcmd.callback = MethodType(_errorcmd, errorcmd, CmdMenuNode)

    defaultcmd = CmdMenuNode(key=CMD_NOINPUT)
    if force_choose:

        def _defaultcmd(self):
            caller.msg(prompt)
    else:
        if choicefunc:
            defaultcmd.choicefunc = choicefunc

            def _defaultcmd(self):
                self.caller.msg("No choice.")
                self.caller.cmdset.delete('menucmdset')
                del self.caller.db._menu_data
                self.choicefunc(self)

    defaultcmd.callback = MethodType(_defaultcmd, defaultcmd, CmdMenuNode)

    # creating cmdset (this will already have look/help commands)
    choicecmdset = MenuCmdSet()
    for cmdfunc in commands:
        choicecmdset.add(cmdfunc)
    choicecmdset.add(errorcmd)
    choicecmdset.add(defaultcmd)
    choicecmdset.add(CmdMenuLook())
    choicecmdset.add(CmdMenuHelp())

    # assigning menu data flags to caller.
    caller.db._menu_data = {"help": "Please select.", "look": prompt}

    # assign cmdset and ask question
    caller.cmdset.add(choicecmdset)
    caller.msg(prompt)
示例#16
0
    def func(self):
        """Handle sensing objects in different ways, including look."""
        char = self.character
        here = char.location if char else None
        account = self.account
        if not (char and here):
            account.msg('You sense only |222Nothingness|n.')
            message = '|gback|n or |ghome' if char else '|g@ic'
            account.msg('(Type %s|n to return to the NOW.)' % message)
            return
        args = self.args.strip()
        cmd = self.cmdstring
        lhs = self.lhs.strip()
        rhs = self.rhs
        obj_string, aspect = [lhs, None] if "'s " not in lhs else lhs.rsplit("'s ", 1)

        if obj_string and obj_string.lower() in ('outside', 'out') and here and here.location:
            char.msg('From within {}, you see:'.format(here.get_display_name(char)))
            obj = [here.location]
        else:
            obj = char.search(obj_string, quiet=True,
                              candidates=[here] + here.contents + char.contents) if args else [char]
        if obj:
            obj = obj[0]
            obj_string = obj.key
        else:
            _AT_SEARCH_RESULT(obj, char, args, quiet=False)
            return  # Trying to sense something that isn't there. "Could not find ''."
        style = obj.STYLE if obj and hasattr(obj, 'STYLE') else '|g'
        if cmd == 'glance':
            if here and not args:
                obj = here
            sights = obj.return_glance(char)
            if sights:
                account.msg('|/You glance at %s and see: %s ' % (obj.get_display_name(char), sights))
            else:
                account.msg('|/You glance at %s, but see nothing.' % obj.get_display_name(char))
            return
        # senses = obj.db.senses
        # details = obj.db.details
        if self.rhs is not None:  # Equals sign exists.
            if not self.rhs:  # Nothing on the right side
                # TODO: Delete and verify intent with switches. Mock-up command without switches.
                # Scan senses before deleting details - make sure not to remove detail if another sense uses it.
                account.msg('Functionality to delete aspects and details is not yet implemented.' % self.switches)

                if aspect:
                    account.msg("|w%s|n (object) %s%s|n's |g%s|n (aspect)  =  |r (detail removed)" %
                               (cmd, style, obj_string, aspect))
                else:
                    account.msg("|w%s|n (object) %s%s|n  =  |r (detail removed)" %
                               (cmd, style, obj_string))
            else:
                # TODO: Add and verify intent with switches. Mock-up command without switches.
                account.msg('Functionality to add aspects and details is not yet implemented.' % self.switches)
                if aspect:
                    account.msg("|w%s|n (object) %s%s|n's |g%s|n (aspect)  =  |c%s|n (detail)" %
                               (cmd, style, obj_string, aspect, rhs))
                else:
                    account.msg("|w%s|n (object) %s%s|n  =  |c%s|n (detail)" %
                               (cmd, style, obj_string, rhs))
            return
        if cmd != 'l' and 'look' not in cmd:  # Doing non-LOOK stuff in here.
            if 'sense' in cmd:
                char.msg('|wSensing...')
                if obj:
                    if obj.db.senses:  # Object must be database object to be sensed.
                        string = '* Senses available for %s: ' % obj.get_display_name(account)
                        string += ", ".join('|lc%s %s|lt|g%s|n|le'
                                            % (element, obj.get_display_name(char, plain=True), element)
                                            for element in obj.db.senses.keys())
                        char.msg(string)
                        aspect_list = []  # list aspects.
                        for element in obj.db.senses.keys():
                            for aspect in obj.db.senses[element].keys():
                                aspect_list.append("|lc%s %s's %s|lt|g%s|n|le " % (element, obj.key, aspect, aspect)
                                                   if aspect else '')
                        if len(aspect_list) > 0:
                            char.msg(obj.get_display_name(account) + ' has the following aspects that can be sensed: ' +
                                     ''.join(aspect_list))
                    if obj != char:
                        verb_msg = "%s responds to: " % obj.get_display_name(account)
                    else:
                        verb_msg = "%sYou|n respond to: " % char.STYLE
                    verbs = obj.locks
                    collector_list = []
                    show_red = True if obj.access(char, 'examine') else False
                    for verb in ("%s" % verbs).split(';'):
                        element = verb.split(':')[0]
                        if element == 'call':
                            continue
                        name = element[2:] if element[:2] == 'v-' else element
                        if obj.access(char, element):  # obj lock checked against actor
                            collector_list.append("|lctry %s %s|lt|g%s|n|le " %
                                                  (name, obj.get_display_name(char, plain=True), name))
                        elif show_red:
                            collector_list.append("|r%s|n " % name)
                    char.msg(verb_msg + ''.join(collector_list))
            elif 'taste' in cmd or 'touch' in cmd or 'smell' in cmd or 'listen' in cmd:  # Specific sense (not look)
                if not obj:
                    return
                # Object to sense might have been found. Check the senses dictionary.
                if obj.db.senses and cmd in obj.db.senses:
                    senses_of = obj.db.senses[cmd]  # senses_of is the sense dictionary for current sense.
                    if aspect in senses_of:
                        details_of = obj.db.details
                        if details_of and senses_of[aspect] in details_of:
                            entry = details_of[senses_of[aspect]]
                            char.msg('%sYou|n sense %s from %s.' % (char.STYLE, entry, obj.get_display_name(account)))
                        else:
                            if aspect:
                                char.msg("%sYou|n try to %s %s's %s, but can not."
                                         % (char.STYLE, cmd, obj.get_display_name(account), aspect))
                            else:
                                char.msg("%sYou|n try to %s %s, but can not."
                                         % (char.STYLE, cmd, obj.get_display_name(account)))
                    else:
                        if aspect:
                            char.msg("%sYou|n try to %s %s's %s, but can not."
                                     % (char.STYLE, cmd, obj.get_display_name(account), aspect))
                        else:
                            char.msg("%sYou|n try to %s %s, but can not."
                                     % (char.STYLE, cmd, obj.get_display_name(account)))
                else:
                    char.msg('%sYou|n try to %s %s, but can not.' % (char.STYLE, cmd, obj.get_display_name(account)))
                # First case: look for an object in room, inventory, room contents, their contents,
                # and their contents contents with tagged restrictions, then if no match is found
                # in their name or alias, look at the senses tables in each of these objects: The
                # Senses attribute is a dictionary of senses that point to the details dictionary
                # entries. Senses dictionary allows for aliases in the details and pointing
                # specific senses to specific entries.
                #
                # If not looking for a specific object or entry, list objects and aspects of the particular
                # sense. Start with that first, and start with the char's own self and inventory.
                # when the /self;me and /inv;inventory switch is used?
            return
        if args:  # < LOOK begins here. ------------------------------------------- >
            if not obj:  # If no object was found, then look for a detail on the object.
                # no object found. Check if there is a matching detail around the location.
                # TODO: Restrict search for details by possessive parse:  [object]'s [aspect]
                candidates = [here] + here.contents + char.contents
                for location in candidates:
                    # TODO: Continue if look location is not visible to looker.
                    if location and hasattr(location, "return_detail") and callable(location.return_detail):
                        detail = location.return_detail(args)
                        if detail:
                            char.msg(detail)  # Show found detail.
                            return  # TODO: Add /all switch to override return here to view all details.
                _AT_SEARCH_RESULT(obj, char, args, quiet=False)  # no detail found. Trigger delayed error messages
                return
            else:
                obj = utils.make_iter(obj)[0]  # Use the first match in the list.
        else:
            obj = here
        if not obj.access(char, 'view'):
            char.msg("You are unable to sense '%s'." % args)
            return
        account.msg(obj.return_appearance(char))  # get object's appearance as seen by char
        obj.at_desc(looker=char)  # the object's at_desc() method - includes look-notify.
示例#17
0
    def search(
        self,
        searchdata,
        global_search=False,
        use_nicks=True,
        typeclass=None,
        location=None,
        attribute_name=None,
        quiet=False,
        exact=False,
        candidates=None,
        nofound_string=None,
        multimatch_string=None,
        use_dbref=None,
    ):
        """
        Returns an Object matching a search string/condition

        Perform a standard object search in the database, handling
        multiple results and lack thereof gracefully. By default, only
        objects in the current `location` of `self` or its inventory are searched for.

        Args:
            searchdata (str or obj): Primary search criterion. Will be matched
                against `object.key` (with `object.aliases` second) unless
                the keyword attribute_name specifies otherwise.
                **Special strings:**
                - `#<num>`: search by unique dbref. This is always
                   a global search.
                - `me,self`: self-reference to this object
                - `<num>-<string>` - can be used to differentiate
                   between multiple same-named matches. The exact form of this input
                   is given by `settings.SEARCH_MULTIMATCH_REGEX`.
            global_search (bool): Search all objects globally. This overrules 'location' data.
            use_nicks (bool): Use nickname-replace (nicktype "object") on `searchdata`.
            typeclass (str or Typeclass, or list of either): Limit search only
                to `Objects` with this typeclass. May be a list of typeclasses
                for a broader search.
            location (Object or list): Specify a location or multiple locations
                to search. Note that this is used to query the *contents* of a
                location and will not match for the location itself -
                if you want that, don't set this or use `candidates` to specify
                exactly which objects should be searched.
            attribute_name (str): Define which property to search. If set, no
                key+alias search will be performed. This can be used
                to search database fields (db_ will be automatically
                prepended), and if that fails, it will try to return
                objects having Attributes with this name and value
                equal to searchdata. A special use is to search for
                "key" here if you want to do a key-search without
                including aliases.
            quiet (bool): don't display default error messages - this tells the
                search method that the user wants to handle all errors
                themselves. It also changes the return value type, see
                below.
            exact (bool): if unset (default) - prefers to match to beginning of
                string rather than not matching at all. If set, requires
                exact matching of entire string.
            candidates (list of objects): this is an optional custom list of objects
                to search (filter) between. It is ignored if `global_search`
                is given. If not set, this list will automatically be defined
                to include the location, the contents of location and the
                caller's contents (inventory).
            nofound_string (str):  optional custom string for not-found error message.
            multimatch_string (str): optional custom string for multimatch error header.
            use_dbref (bool or None, optional): If `True`, allow to enter e.g. a query "#123"
                to find an object (globally) by its database-id 123. If `False`, the string "#123"
                will be treated like a normal string. If `None` (default), the ability to query by
                #dbref is turned on if `self` has the permission 'Builder' and is turned off
                otherwise.

        Returns:
            match (Object, None or list): will return an Object/None if `quiet=False`,
                otherwise it will return a list of 0, 1 or more matches.

        Notes:
            To find Accounts, use eg. `evennia.account_search`. If
            `quiet=False`, error messages will be handled by
            `settings.SEARCH_AT_RESULT` and echoed automatically (on
            error, return will be `None`). If `quiet=True`, the error
            messaging is assumed to be handled by the caller.

        """
        is_string = isinstance(searchdata, str)

        if is_string:
            # searchdata is a string; wrap some common self-references
            if searchdata.lower() in ("here", ):
                return [self.location] if quiet else self.location
            if searchdata.lower() in ("me", "self"):
                return [self] if quiet else self

        if use_dbref is None:
            use_dbref = self.locks.check_lockstring(self,
                                                    "_dummy:perm(Builder)")

        if use_nicks:
            # do nick-replacement on search
            searchdata = self.nicks.nickreplace(searchdata,
                                                categories=("objet",
                                                            "account"),
                                                include_account=True)

        if global_search or (is_string and searchdata.startswith("#")
                             and len(searchdata) > 1
                             and searchdata[1:].isdigit()):
            # only allow exact matching if searching the entire database
            # or unique #dbrefs
            exact = True
            candidates = None

        elif candidates is None:
            # no custom candidates given - get them automatically
            if location:
                # location(s) were given
                candidates = []
                for obj in make_iter(location):
                    candidates.extend(obj.contents)
            else:
                # local search. Candidates are taken from
                # self.contents, self.location and
                # self.location.contents
                location = self.location
                candidates = self.contents
                if location:
                    candidates = candidates + [location] + location.contents
                else:
                    # normally we don't need this since we are
                    # included in location.contents
                    candidates.append(self)

        results = ObjectDB.objects.object_search(
            searchdata,
            attribute_name=attribute_name,
            typeclass=typeclass,
            candidates=candidates,
            exact=exact,
            use_dbref=use_dbref,
        )

        if quiet:
            return list(results)
        return _AT_SEARCH_RESULT(
            results,
            self,
            query=searchdata,
            nofound_string=nofound_string,
            multimatch_string=multimatch_string,
        )
示例#18
0
    def func(self):
        """
        Handle the looking - add fallback to details.
        """
        caller = self.caller
        args = self.args
        looking_at_obj = None
        if args:
            alist = args.split("'s ")
            if len(alist) == 2:
                obj = caller.search(alist[0], use_nicks=True, quiet=True)
                if obj:
                    obj = utils.make_iter(obj)
                    looking_at_obj = caller.search(alist[1],
                                                   location=obj[0],
                                                   use_nicks=True,
                                                   quiet=True)
            else:
                looking_at_obj = caller.search(args,
                                               use_nicks=True,
                                               quiet=True)
            # originally called search with invalid arg of no_error or something instead of quiet
            if not looking_at_obj:
                # no object found. Check if there is a matching
                # detail at location.
                if self.check_detail():
                    return
                # no detail found. Trigger delayed error messages
                _AT_SEARCH_RESULT(looking_at_obj, caller, args, False)
                return
            else:
                # we need to extract the match manually.
                if len(utils.make_iter(looking_at_obj)) > 1:
                    _AT_SEARCH_RESULT(looking_at_obj, caller, args, False)
                    self.check_detail()
                    return
                looking_at_obj = utils.make_iter(looking_at_obj)[0]
        else:
            looking_at_obj = caller.location
            if not looking_at_obj:
                caller.msg("You have no location to look at!")
                return

        if not hasattr(looking_at_obj, "return_appearance"):
            # this is likely due to us having a player instead
            looking_at_obj = looking_at_obj.character
        if not looking_at_obj.access(caller, "view"):
            caller.msg("Could not find '%s'." % args)
            self.check_detail()
            return
        # get object's appearance
        desc = looking_at_obj.return_appearance(caller, detailed=False)
        # if it's a written object, we'll paginate the description
        if looking_at_obj.db.written:
            from server.utils import arx_more

            desc = desc.replace("%r", "\n")
            arx_more.msg(caller, desc, pages_by_char=True)
        else:
            caller.msg(desc)
        # the object's at_desc() method.
        looking_at_obj.at_desc(looker=caller)
        self.check_detail()
示例#19
0
    def func(self):
        """Handle sensing objects in different ways. WIP: Expanding to handle other senses."""
        char = self.character
        # player = self.player
        args = self.args.strip()
        cmd = self.cmdstring

        if cmd != 'l' and 'look' not in cmd:
            if 'sense' in cmd:
                if char and char.location:
                    obj_list = char.search(args, candidates=[char.location] + char.location.contents +
                                           char.contents) if args else char
                    if obj_list and obj_list.db.senses:
                        char.msg('You can sense %s in the following ways: %s' % (obj_list, obj_list.db.senses.keys()))
                        obj = obj_list
                        verb_msg = "You can interact with %s: " % obj_list.get_display_name(self.session)
                    else:
                        obj = char
                        verb_msg = "You can be interacted with by: "
                    verbs = obj.locks
                    collector = ''
                    show_red = True if obj.access(char, 'examine') else False
                    for verb in ("%s" % verbs).split(';'):
                        element = verb.split(':')[0]
                        if element == 'call':
                            continue
                        name = element[2:] if element[:2] == 'v-' else element
                        if obj.access(char, element):  # obj lock checked against actor
                            collector += "|lctry %s #%s|lt|g%s|n|le " % (name, obj.id, name)
                        elif show_red:
                            collector += "|r%s|n " % name
                    char.msg(verb_msg + "%s" % collector)
            elif 'taste' in cmd or 'touch' in cmd or 'smell' in cmd or 'listen' in cmd:  # Specific sense (not look)
                obj_list = char.search(args, candidates=[char.location] + char.location.contents + char.contents)\
                    if args else char
                char.msg('You try to sense %s.' % (obj_list if obj_list else 'something'))
                # Object to sense might have been found. Check the senses dictionary.
                if obj_list and obj_list.db.senses and cmd in obj_list.db.senses:
                    senses_of = obj_list.db.senses[cmd]
                    if None in senses_of:
                            details_of = obj_list.db.details
                            if details_of and senses_of[None] in details_of:
                                entry = details_of[senses_of[None]]
                                char.msg('You sense %s from %s.' % (entry, obj_list))
                # First case: look for an object in room, inventory, room contents, their contents,
                # and their contents contents with tagged restrictions, then if no match is found
                # in their name or alias, look at the senses tables in each of these objects: The
                # Senses attribute is a dictionary of senses that point to the details dictionary
                # entries. Senses dictionary allows for aliases in the details and pointing
                # specific senses to specific entries.
                #
                # If not looking for a specific object or entry, list objects and aspects of the particular
                # sense. Start with that first, and start with the char's own self and inventory.
                # when the /self;me and /inv;inventory switch is used?
            return
        if args:
            # Parsing for object/aspect/detail:
            # Box's wheel = Red spinners lit with pyrotechnics.
            # object, aspect = args.rsplit("'s ", 1)
            # detail = self.rhs.strip()

            obj = char.search(args,
                              candidates=char.location.contents + char.contents,
                              use_nicks=True,
                              quiet=True)
            if not obj:
                # no object found. Check if there is a matching detail around the location.
                # TODO: Restrict search for details by possessive parse:  [object]'s [aspect]
                candidates = [char.location] + char.location.contents + char.contents
                for location in candidates:
                    # TODO: Continue if look location is not visible to looker.
                    if location and hasattr(location, "return_detail") and callable(location.return_detail):
                        detail = location.return_detail(args)
                        if detail:
                            # Show found detail.
                            char.msg(detail)
                            return  # TODO: Add /all switch to override return here to view all details.
                # no detail found. Trigger delayed error messages
                _AT_SEARCH_RESULT(obj, char, args, quiet=False)
                return
            else:
                # we need to extract the match manually.
                obj = utils.make_iter(obj)[0]
        else:
            obj = char.location
            if not obj:
                char.msg("There is nothing to sense here.")
                return
        if not hasattr(obj, 'return_appearance'):
            # this is likely due to a player calling the command.
            obj = obj.character
        if not obj.access(char, 'view'):
            char.msg("You are unable to sense '%s'." % args)
            return
        # get object's appearance
        char.msg(obj.return_appearance(char))
        # the object's at_desc() method.
        obj.at_desc(looker=char)
示例#20
0
def prompt_choice(caller,
                  question="",
                  prompts=None,
                  choicefunc=None,
                  force_choose=False):
    """
    This sets up a simple choice questionnaire. Question will be
    asked, followed by a series of prompts. Note that this isn't
    making use of the menu node system but uses the MenuCmdSet.

    Args:
        caller (object): The object calling and being offered the choice
        question (str, optional): Text describing the offered choice
        prompts (list, optional): List of strings defining the available choises.
        choicefunc (function, optional): A function called as
            `choicefunc(self)` when a choice is made. Inside this function,
            `self.caller` is available and `self.prompt_index` is the index
            (starting with 0) matching the chosen prompt in the `prompts` list.
        force_choose - force user to make a choice

    Examples:

        ```python
            def mychoice(self):
                self.caller.msg("Index of choice is %s." % self.prompt_index)

            prompt_choice(caller, "Make a choice:", prompts=["A","B","C"], choicefunc=mychoice)
        ```

        When triggering the above from a command or @py prompt you get the following options:

        >>> Make a choice:
            [1] A
            [2] B
            [3] C
        <<< 2
        >>> Index of choice is 1.

    """

    # creating and defining commands
    count = 0
    choices = ""
    commands = []

    for choice in utils.make_iter(prompts):
        # create the available choice-commands
        count += 1
        choices += "\n{lc%d{lt[%d]{le %s" % (count, count, choice)

        cmdfunc = CmdMenuNode(key="%d" % count)
        cmdfunc.prompt_index = count - 1
        if choicefunc:
            cmdfunc.choicefunc = choicefunc

            def _choicefunc(self):
                self.caller.cmdset.delete('menucmdset')
                del self.caller.db._menu_data
                self.choicefunc(self)

            # set a new method "callback" on cmdfunc
            cmdfunc.callback = MethodType(_choicefunc, cmdfunc, CmdMenuNode)

        commands.append(cmdfunc)

    if not force_choose:
        choices += "\n{lc{lt[No choice]{le"

    prompt = question + choices + "\nPlease choose one."

    # create the error-reporting command
    errorcmd = CmdMenuNode(key=CMD_NOMATCH)
    if force_choose:

        def _errorcmd(self):
            self.caller.msg("You can only choose given choices.")
    else:
        if choicefunc:
            errorcmd.choicefunc = choicefunc

            def _errorcmd(self):
                self.caller.msg("No choice.")
                self.caller.cmdset.delete('menucmdset')
                del self.caller.db._menu_data
                self.choicefunc(self)

    errorcmd.callback = MethodType(_errorcmd, errorcmd, CmdMenuNode)

    # create the fallback command
    defaultcmd = CmdMenuNode(key=CMD_NOINPUT)
    if force_choose:

        def _defaultcmd(self):
            caller.msg(prompt)
    else:
        if choicefunc:
            defaultcmd.choicefunc = choicefunc

            def _defaultcmd(self):
                self.caller.msg("No choice.")
                self.caller.cmdset.delete('menucmdset')
                del self.caller.db._menu_data
                self.choicefunc(self)

    defaultcmd.callback = MethodType(_defaultcmd, defaultcmd, CmdMenuNode)

    # creating cmdset (this will already have look/help commands)
    choicecmdset = MenuCmdSet()
    for cmdfunc in commands:
        choicecmdset.add(cmdfunc)
    choicecmdset.add(errorcmd)
    choicecmdset.add(defaultcmd)
    choicecmdset.add(CmdMenuLook())
    choicecmdset.add(CmdMenuHelp())

    # assigning menu data flags to caller.
    caller.db._menu_data = {"help": "Please select.", "look": prompt}

    # assign cmdset and ask question
    caller.cmdset.add(choicecmdset)
    caller.msg(prompt)
示例#21
0
    def func(self):
        """
        Handle the looking - add fallback to details.
        """
        caller = self.caller
        args = self.args
        if args:
            looking_at_obj = caller.search(args, use_nicks=True, quiet=True)
            if not looking_at_obj:
                # no object found. Check if there is a matching
                # detail at location.
                location = caller.location
                if location and hasattr(location,
                                        "return_detail") and callable(
                                            location.return_detail):
                    detail = location.return_detail(args)
                    if detail:
                        # we found a detail instead. Show that.
                        caller.msg("{y%s{n\n" % args + detail)
                        return
                # no detail found. Trigger delayed error messages
                _AT_SEARCH_RESULT(caller, args, looking_at_obj, False)
                return
            else:
                if len(looking_at_obj) > 1:
                    caller.msg(
                        "Есть несколько объектов с таким именем(укажи нужный):"
                    )
                    i = 1
                    for item in looking_at_obj:
                        if item.has_player:
                            caller.msg("%s-%s (Игрок)" % (i, item.key))
                        elif item.db.is_corpse:
                            caller.msg("%s-%s (Труп)" % (i, item.key))
                        elif item.db.npc:
                            caller.msg("%s-%s (NPC)" % (i, item.key))
                        elif item.db.is_weapon:
                            caller.msg("%s-%s (Оружие)" % (i, item.key))
                        else:
                            caller.msg("%s-%s (Объект)" % (i, item.key))
                        i = i + 1
                    return
                else:
                    # we need to extract the match manually.
                    looking_at_obj = utils.make_iter(looking_at_obj)[0]
        else:
            looking_at_obj = caller.location
            if not looking_at_obj:
                caller.msg("Тебе некуда смотреть!")
                return

        if not hasattr(looking_at_obj, 'return_appearance'):
            # this is likely due to us having a player instead
            looking_at_obj = looking_at_obj.character
        if not looking_at_obj.access(caller, "view"):
            caller.msg("Не могу найти '%s'." % args)
            return
        # get object's appearance
        caller.msg(looking_at_obj.return_appearance(caller))
        # the object's at_desc() method.
        looking_at_obj.at_desc(looker=caller)