コード例 #1
0
 def is_valid_inheritance(obj):
     valid = (not inherits_from(obj, DefaultCharacter)
              and not inherits_from(obj, DefaultRoom)
              and not inherits_from(obj, DefaultExit))
     if not valid:
         caller.msg("Invalid typeclass for %s" % (obj))
     return valid
コード例 #2
0
ファイル: driving.py プロジェクト: vincent-lg/Avenew
    def func(self):
        """Execute the command."""
        room = self.caller.location
        if not inherits_from(room, "typeclasses.rooms.VehicleRoom"):
            self.msg("|rIt seems you are not in a vehicle.|n")
            return

        vehicle = room.location

        # A VehicleRoom should be contained in a vehicle... but let's check
        if not inherits_from(vehicle, "typeclasses.vehicles.Vehicle"):
            self.msg("|rAre you, or are you not, in a vehicle?  Hard to say.|n..")
            return

        # Make sure we are currently driving
        if vehicle.db.driver is not self.caller:
            self.msg("|gYou aren't driving {}.|n".format(vehicle.key))
            return

        # Proceed to turn
        name = self.raw_string.strip().lower()
        if name.startswith("turn "):
            name = name[5:]

        direction = vehicle.db.direction
        infos = get_direction(name)
        if infos is None or infos["direction"] in (8, 9):
            self.msg("|gThe direction you specified is unknown.|n")
            return

        vehicle.db.expected_direction = infos["direction"]
        self.msg("You prepare to turn {} on the next open crossroad.".format(infos["name"]))
コード例 #3
0
ファイル: objects.py プロジェクト: kovitikus/hecate
    def find_location(self):
        #Check to see if the torch is in the hands (inventory) of player
        # or if the torch is in a a room.
        held_by = self.location
        room = None

        if inherits_from(held_by, 'characters.characters.Character'):
            room = held_by.location
        elif inherits_from(held_by, 'rooms.rooms.Room'):
            room = held_by
        return room, held_by
コード例 #4
0
ファイル: command.py プロジェクト: daiimus/arxcode
 def parse(self):
     super(JsonPlayerCommand, self).parse()
     if utils.inherits_from(self.caller, "evennia.objects.objects.DefaultObject"):
         # caller is an Object/Character
         self.character = self.caller
         self.caller = self.caller.player
     elif utils.inherits_from(self.caller, "evennia.players.players.DefaultPlayer"):
         # caller was already a Player
         self.character = self.caller.get_puppet(self.session)
     else:
         self.character = None
コード例 #5
0
ファイル: typeclasses.py プロジェクト: Henddher/evennia
    def at_say(self, message, **kwargs):
        """
        Display the actual say (or whisper) of self.

        This hook should display the actual say/whisper of the object in its
        location.  It should both alert the object (self) and its
        location that some text is spoken.  The overriding of messages or
        `mapping` allows for simple customization of the hook without
        re-writing it completely.

        Args:
            message (str): The text to be conveyed by self.
            msg_self (str, optional): The message to echo to self.
            msg_location (str, optional): The message to echo to self's location.
            receiver (Object, optional): An eventual receiver of the message
                (by default only used by whispers).
            msg_receiver(str, optional): Specific message for receiver only.
            mapping (dict, optional): Additional mapping in messages.
        Kwargs:
            whisper (bool): If this is a whisper rather than a say. Kwargs
                can be used by other verbal commands in a similar way.

        Notes:

            Messages can contain {} markers, which must
            If used, `msg_self`, `msg_receiver`  and `msg_location` should contain
            references to other objects between braces, the way `location.msg_contents`
            would allow.  For instance:
                msg_self = 'You say: "{speech}"'
                msg_location = '{object} says: "{speech}"'
                msg_receiver = '{object} whispers: "{speech}"'

            The following mappings can be used in both messages:
                object: the object speaking.
                location: the location where object is.
                speech: the text spoken by self.

            You can use additional mappings if you want to add other
            information in your messages.

        """

        super(EventCharacter, self).at_say(message, **kwargs)
        location = getattr(self, "location", None)
        location = location if location and inherits_from(location, "evennia.objects.objects.DefaultRoom") else None

        if location and not kwargs.get("whisper", False):
            location.callbacks.call("say", self, location, message,
                  parameters=message)

            # Call the other characters' "say" event
            presents = [obj for obj in location.contents if obj is not self and inherits_from(obj, "evennia.objects.objects.DefaultCharacter")]
            for present in presents:
                present.callbacks.call("say", self, present, message, parameters=message)
コード例 #6
0
ファイル: driving.py プロジェクト: vincent-lg/Avenew
    def func(self):
        """Execute the command."""
        room = self.caller.location
        if not inherits_from(room, "typeclasses.rooms.VehicleRoom"):
            self.msg("It seems you are not in a vehicle.")
            return

        vehicle = room.location
        # A VehicleRoom should be contained in a vehicle... but let's check
        if not inherits_from(vehicle, "typeclasses.vehicles.Vehicle"):
            self.msg(
                    "Are you, or are you not, in a vehicle?  Hard to say...")
            return

        # We can only control the steering wheel from the front seat
        if room is not vehicle.contents[0]:
            self.msg("You aren't in the front seat of {}.".format(
                    vehicle.key))
            return

        # Are we already driving this vehicle
        if vehicle.db.driver is self.caller:
            vehicle.db.driver = None
            self.msg("You let go of the steering wheel.")
            room.msg_contents("{driver} lets go of the streering wheel.",
                    exclude=[self.caller], mapping=dict(driver=self.caller))
            self.caller.cmdset.remove("commands.driving.DrivingCmdSet")
            return

        # Or someone else could be riving
        if vehicle.db.driver:
            self.msg("Someone else is at the wheel.")
            return

        # All is good, allow 'self.caller' to drive
        vehicle.db.driver = self.caller
        self.msg("You grip the steering wheel and stretch your legs " \
                "to reach the pedals.")
        room.msg_contents("{driver} grips the steering wheel and stretches " \
                "his legs to reach the pedals.", exclude=[self.caller],
                mapping=dict(driver=self.caller))

        # If the vehicle is in a room, leave it.
        if vehicle.location is not None:
            vehicle.location = None
            self.msg("You start the engine and begin to drive {} " \
                    "on the street.".format(vehicle.key))
            vehicle.msg_contents("The engine of {vehicle} starts.",
                    exclude=[self.caller], mapping=dict(vehicle=vehicle))

        self.caller.cmdset.add("commands.driving.DrivingCmdSet",
                permanent=True)
コード例 #7
0
ファイル: typeclasses.py プロジェクト: zero9k/evennia
    def at_before_say(self, message, **kwargs):
        """
        Before the object says something.

        This hook is by default used by the 'say' and 'whisper'
        commands as used by this command it is called before the text
        is said/whispered and can be used to customize the outgoing
        text from the object. Returning `None` aborts the command.

        Args:
            message (str): The suggested say/whisper text spoken by self.
        Keyword Args:
            whisper (bool): If True, this is a whisper rather than
                a say. This is sent by the whisper command by default.
                Other verbal commands could use this hook in similar
                ways.
            receiver (Object): If set, this is a target for the say/whisper.

        Returns:
            message (str): The (possibly modified) text to be spoken.

        """
        # First, try the location
        location = getattr(self, "location", None)
        location = (location if location and inherits_from(
            location, "evennia.objects.objects.DefaultRoom") else None)
        if location and not kwargs.get("whisper", False):
            allow = location.callbacks.call("can_say",
                                            self,
                                            location,
                                            message,
                                            parameters=message)
            message = location.callbacks.get_variable("message")
            if not allow or not message:
                return

            # Browse all the room's other characters
            for obj in location.contents:
                if obj is self or not inherits_from(
                        obj, "evennia.objects.objects.DefaultCharacter"):
                    continue

                allow = obj.callbacks.call("can_say",
                                           self,
                                           obj,
                                           message,
                                           parameters=message)
                message = obj.callbacks.get_variable("message")
                if not allow or not message:
                    return

        return message
コード例 #8
0
def isguest(accessing_obj, accessed_obj):
    """
    a called lockstring with no args.
    This lock function will check if the caller is a guest or Helper+
    """
    if utils.inherits_from(
            accessing_obj,
            "typeclasses.characters.Character") and utils.inherits_from(
                accessing_obj.account,
                "evennia.accounts.accounts.DefaultGuest"):
        return True
    else:
        return False
コード例 #9
0
    def parse(self):
        """
        We run the parent parser as usual, then fix the result
        """
        super(MuxPlayerCommand, self).parse()

        if utils.inherits_from(self.caller, "evennia.objects.objects.DefaultObject"):
            # caller is an Object/Character
            self.character = self.caller
            self.caller = self.caller.player
        elif utils.inherits_from(self.caller, "evennia.players.players.DefaultPlayer"):
            # caller was already a Player
            self.character = self.caller.get_puppet(self.session)
        else:
            self.character = None
コード例 #10
0
    def location_summary(self):
        """
        You arrive at <location name>. <Person/Sentient> <is/are> here. You see <exit name> to the 
        <exit direction>, and <exit name> to the <exit direction>.
        """
        owner = self.owner
        location = owner.location
        characters = []
        exits = []
        char_str = ''
        exit_str = ''
        msg = ''

        if location is None:
            return "You have arrive nowhere."

        # Generate lists of characters and exits in the room.
        for i in location.contents:
            if inherits_from(i, 'characters.characters.Character') and i is not owner:
                characters.append(i)
            elif inherits_from(i, 'travel.exits.Exit'):
                exits.append(i)

        # Parse list of characters.
        if len(characters) > 1:
            char_list = gen_mec.objects_to_display_names(characters, owner)
            temp_list = []
            for i in char_list:
                temp_list.append(f"|c{i}|n")
            char_str = gen_mec.comma_separated_string_list(temp_list)
            char_str = f"{char_str} are here. "
        elif len(characters) == 1:
            char_str = f'|c{characters[0].get_display_name(owner)}|n'
            char_str = f"{char_str} is here. "
        else:
            char_str = False

        # Parse list of exits.
        exit_str = self.exits_to_string(exits)

        # Generate final outgoing message.
        msg = f"You arrive at |310{location.get_display_name(owner)}|n. "
        msg = f"{msg}{'' if char_str == False else char_str}" # Characters string addition.
        if exit_str:
            msg = f"{msg}You see {exit_str}."
        else:
            msg = f"{msg}{self.no_exit_str}"
        return msg
コード例 #11
0
ファイル: simpledoor.py プロジェクト: helix-0311/evennia
    def func(self):
        "implement the door functionality"
        if not self.args:
            self.caller.msg("Usage: open||close <door>")
            return

        door = self.caller.search(self.args)
        if not door:
            return
        if not inherits_from(door, SimpleDoor):
            self.caller.msg("This is not a door.")
            return

        if self.cmdstring == "open":
            if door.locks.check(self.caller, "traverse"):
                self.caller.msg("%s is already open." % door.key)
            else:
                door.setlock("traverse:true()")
                self.caller.msg("You open %s." % door.key)
        else: # close
            if not door.locks.check(self.caller, "traverse"):
                self.caller.msg("%s is already closed." % door.key)
            else:
                door.setlock("traverse:false()")
                self.caller.msg("You close %s." % door.key)
コード例 #12
0
ファイル: lockfuncs.py プロジェクト: wty0512/evennia
def _to_player(accessing_obj):
    "Helper function. Makes sure an accessing object is a player object"
    if utils.inherits_from(accessing_obj,
                           "evennia.objects.objects.DefaultObject"):
        # an object. Convert to player.
        accessing_obj = accessing_obj.player
    return accessing_obj
コード例 #13
0
ファイル: evmore.py プロジェクト: shadowlack/evennia
    def parse_input(self, inp):
        """
        Parse the input to figure out the size of the data, how many pages it
        consist of and pick the correct paginator mechanism. Override this if
        you want to support a new type of input.

        Each initializer should set self._paginator and optionally self._page_formatter
        for properly handling the input data.

        """
        if inherits_from(inp, "evennia.utils.evtable.EvTable"):
            # an EvTable
            self.init_evtable(inp)
        elif isinstance(inp, QuerySet):
            # a queryset
            self.init_queryset(inp)
        elif isinstance(inp, Paginator):
            self.init_django_paginator(inp)
        elif not isinstance(inp, str):
            # anything else not a str
            self.init_iterable(inp)
        elif "\f" in inp:
            # string with \f line-break markers in it
            self.init_f_str(inp)
        else:
            # a string
            self.init_str(inp)
コード例 #14
0
    def func(self):
        caller = self.caller

        if self.args is None or not utils.dbref(self.args):
            caller.msg("A puzzle recipe's #dbref must be specified")
            return

        puzzle = search.search_script(self.args)
        if not puzzle or not inherits_from(puzzle[0], PuzzleRecipe):
            caller.msg("Invalid puzzle %r" % (self.args))
            return

        puzzle = puzzle[0]
        caller.msg("Puzzle Recipe %s(%s) '%s' found.\nSpawning %d parts ..." %
                   (puzzle.name, puzzle.dbref, puzzle.db.puzzle_name,
                    len(puzzle.db.parts)))

        for proto_part in puzzle.db.parts:
            part = spawn(proto_part)[0]
            caller.msg(
                "Part %s(%s) spawned and placed at %s(%s)" %
                (part.name, part.dbref, part.location, part.location.dbref))
            part.tags.add(puzzle.db.puzzle_name,
                          category=_PUZZLES_TAG_CATEGORY)
            part.db.puzzle_name = puzzle.db.puzzle_name

        caller.msg("Puzzle armed |gsuccessfully|n.")
コード例 #15
0
ファイル: typeclasses.py プロジェクト: zero9k/evennia
    def at_traverse(self, traversing_object, target_location):
        """
        This hook is responsible for handling the actual traversal,
        normally by calling
        `traversing_object.move_to(target_location)`. It is normally
        only implemented by Exit objects. If it returns False (usually
        because `move_to` returned False), `at_after_traverse` below
        should not be called and instead `at_failed_traverse` should be
        called.

        Args:
            traversing_object (Object): Object traversing us.
            target_location (Object): Where target is going.

        """
        is_character = inherits_from(traversing_object, DefaultCharacter)
        if is_character:
            allow = self.callbacks.call("can_traverse", traversing_object,
                                        self, self.location)
            if not allow:
                return

        super().at_traverse(traversing_object, target_location)

        # After traversing
        if is_character:
            self.callbacks.call("traverse", traversing_object, self,
                                self.location, self.destination)
コード例 #16
0
ファイル: simpledoor.py プロジェクト: two-first-names/evennia
    def func(self):
        "implement the door functionality"
        if not self.args:
            self.caller.msg("Usage: open||close <door>")
            return

        door = self.caller.search(self.args)
        if not door:
            return
        if not inherits_from(door, SimpleDoor):
            self.caller.msg("This is not a door.")
            return

        if self.cmdstring == "open":
            if door.locks.check(self.caller, "traverse"):
                self.caller.msg("%s is already open." % door.key)
            else:
                door.setlock("traverse:true()")
                self.caller.msg("You open %s." % door.key)
        else:  # close
            if not door.locks.check(self.caller, "traverse"):
                self.caller.msg("%s is already closed." % door.key)
            else:
                door.setlock("traverse:false()")
                self.caller.msg("You close %s." % door.key)
コード例 #17
0
ファイル: simpledoor.py プロジェクト: two-first-names/evennia
 def create_exit(self,
                 exit_name,
                 location,
                 destination,
                 exit_aliases=None,
                 typeclass=None):
     """
     Simple wrapper for the default CmdOpen.create_exit
     """
     # create a new exit as normal
     new_exit = super(CmdOpen, self).create_exit(exit_name,
                                                 location,
                                                 destination,
                                                 exit_aliases=exit_aliases,
                                                 typeclass=typeclass)
     if hasattr(self, "return_exit_already_created"):
         # we don't create a return exit if it was already created (because
         # we created a door)
         del self.return_exit_already_created
         return new_exit
     if inherits_from(new_exit, SimpleDoor):
         # a door - create its counterpart and make sure to turn off the default
         # return-exit creation of CmdOpen
         self.caller.msg(
             "Note: A door-type exit was created - ignored eventual custom return-exit type."
         )
         self.return_exit_already_created = True
         back_exit = self.create_exit(exit_name,
                                      destination,
                                      location,
                                      exit_aliases=exit_aliases,
                                      typeclass=typeclass)
         new_exit.db.return_exit = back_exit
         back_exit.db.return_exit = new_exit
     return new_exit
コード例 #18
0
ファイル: characters.py プロジェクト: ChrisLR/scrolls
    def change_vital(self, attr_type, by=0, update=True):
        """
        helper function to change current vital value 
        based on max and current value. attr_type supplied must be
        valid key that points to attributes on AttributeHandler, and must
        be a valid VitalAttribute object
        """
        attr = self.__getattr__(attr_type)
        if not inherits_from(attr, 'world.attributes.VitalAttribute'):
            raise NotImplementedError(
                'change_vital function doesnt support changing attribute that are NOT VitalAttributes'
            )

        if attr.cur == attr.max:
            return

        cur = attr.cur

        cur += int((by * attr.rate))  # apply rate
        if cur < 0:
            cur = 0
        if cur > attr.max:
            cur = attr.max
        attr.cur = cur
        self.__setattr__(attr_type, attr)
        if update:
            self.update()
コード例 #19
0
ファイル: disguises.py プロジェクト: nirvana-game/arxcode
    def check_target(self, target, caller):
        """
        Determines if a target is valid.
        """
        from evennia.utils.utils import inherits_from

        return inherits_from(target, self.valid_typeclass_path)
コード例 #20
0
ファイル: utils.py プロジェクト: ChrisLR/scrolls
def delete_contents(obj, exclude=[], do_not_delete_chars=True):
    """ 
    DANGEROUS OPERATION

    recursively delete objs contained within itself 
    make sure to put appropriate typeclasses in exclude,
    you can delete yourself if you are not careful..
    for example. 
    
    By default this skips over character typeclasses,
    but this can be overwritten. 

    # bad!!
    delete_contents(self.caller.location, do_not_delete_chars=False) # whoopsie.. doooh

    # good!!
    delete_contents(self.caller.location)
    """

    for o in obj.contents:
        if o in exclude or (do_not_delete_chars and inherits_from(
                o, 'typeclasses.characters.Character')):
            continue
        if o.contents:
            delete_contents(obj=o)
        o.delete()
コード例 #21
0
ファイル: lockfuncs.py プロジェクト: g33kcub/evennia-1
def _to_account(accessing_obj):
    "Helper function. Makes sure an accessing object is an account object"
    if utils.inherits_from(accessing_obj,
                           "evennia.objects.objects.DefaultObject"):
        # an object. Convert to account.
        accessing_obj = accessing_obj.account
    return accessing_obj
コード例 #22
0
ファイル: npcshop.py プロジェクト: evennia/ainneve
 def func(self):
     try:
         item_name, value = self.args.split()
     except:
         self.caller.msg("Syntax: price <item> <value>")
         return
     sellable_items = [ware for ware in self.caller.location.contents if inherits_from(ware, Item)]
     item = self.caller.search(item_name, location=self.caller.location, candidates=sellable_items, quiet=True)
     if len(item) > 1:
         self.caller.msg("Which '{}' did you mean?".format(item_name))
         return
     elif len(item):
         item = item[0]
         try:
             value = int(value)
         except:
             self.caller.msg("Your price can only be an integer.")
             return
         item.db.value = value
         self.caller.msg("You set the price of {} to {}.".format(
             item,
             as_price(value)
         ))
     else:
         self.caller.msg("There is no '{}' available here to sell.".format(item_name))
コード例 #23
0
ファイル: typeclasses.py プロジェクト: Henddher/evennia
    def at_traverse(self, traversing_object, target_location):
        """
        This hook is responsible for handling the actual traversal,
        normally by calling
        `traversing_object.move_to(target_location)`. It is normally
        only implemented by Exit objects. If it returns False (usually
        because `move_to` returned False), `at_after_traverse` below
        should not be called and instead `at_failed_traverse` should be
        called.

        Args:
            traversing_object (Object): Object traversing us.
            target_location (Object): Where target is going.

        """
        is_character = inherits_from(traversing_object, DefaultCharacter)
        if is_character:
            allow = self.callbacks.call("can_traverse", traversing_object,
                                        self, self.location)
            if not allow:
                return

        super(EventExit, self).at_traverse(traversing_object, target_location)

        # After traversing
        if is_character:
            self.callbacks.call("traverse", traversing_object,
                                self, self.location, self.destination)
コード例 #24
0
ファイル: npcshop.py プロジェクト: asurvivor/BeyondTheVeil
 def func(self):
     try:
         item_name, value = self.args.split()
     except:
         self.caller.msg("Syntax: price <item> <value>")
         return
     sellable_items = [
         ware for ware in self.caller.location.contents
         if inherits_from(ware, Item)
     ]
     item = self.caller.search(item_name,
                               location=self.caller.location,
                               candidates=sellable_items,
                               quiet=True)
     if len(item) > 1:
         self.caller.msg("Which '{}' did you mean?".format(item_name))
         return
     elif len(item):
         item = item[0]
         try:
             value = int(value)
         except:
             self.caller.msg("Your price can only be an integer.")
             return
         item.db.value = value
         self.caller.msg("You set the price of {} to {}.".format(
             item, as_price(value)))
     else:
         self.caller.msg(
             "There is no '{}' available here to sell.".format(item_name))
コード例 #25
0
ファイル: cmdset.py プロジェクト: ReidLiu/text-world-fantasy
    def add(self, cmd):
        """
        Add a command, a list of commands or a cmdset to this cmdset.

        Note that if cmd already exists in set,
        it will replace the old one (no priority checking etc
        at this point; this is often used to overload
        default commands).

        If cmd is another cmdset class or -instance, the commands
        of that command set is added to this one, as if they were part
        of the original cmdset definition. No merging or priority checks
        are made, rather later added commands will simply replace
        existing ones to make a unique set.
        """

        if inherits_from(cmd, "evennia.commands.cmdset.CmdSet"):
            # cmd is a command set so merge all commands in that set
            # to this one. We raise a visible error if we created
            # an infinite loop (adding cmdset to itself somehow)
            try:
                cmd = self._instantiate(cmd)
            except RuntimeError:
                string = "Adding cmdset %(cmd)s to %(class)s lead to an "
                string += "infinite loop. When adding a cmdset to another, "
                string += "make sure they are not themself cyclically added to "
                string += "the new cmdset somewhere in the chain."
                raise RuntimeError(
                    _(string) % {
                        "cmd": cmd,
                        "class": self.__class__
                    })
            cmds = cmd.commands
        elif is_iter(cmd):
            cmds = [self._instantiate(c) for c in cmd]
        else:
            cmds = [self._instantiate(cmd)]
        commands = self.commands
        system_commands = self.system_commands
        for cmd in cmds:
            # add all commands
            if not hasattr(cmd, 'obj'):
                cmd.obj = self.cmdsetobj
            try:
                ic = commands.index(cmd)
                commands[ic] = cmd  # replace
            except ValueError:
                commands.append(cmd)
            # extra run to make sure to avoid doublets
            self.commands = list(set(commands))
            #print "In cmdset.add(cmd):", self.key, cmd
            # add system_command to separate list as well,
            # for quick look-up
            if cmd.key.startswith("__"):
                try:
                    ic = system_commands.index(cmd)
                    system_commands[ic] = cmd  # replace
                except ValueError:
                    system_commands.append(cmd)
コード例 #26
0
ファイル: command.py プロジェクト: trhr/evennia-barx
 def parse(self):
     if not self.args:
         self.msg("Who would you like to sniff? Usage: 'sniff <character>'")
     else:
         self.target = self.caller.search(self.args.strip())
         if not inherits_from(self.target, Character):
             self.target = None
             self.msg("You can only sniff characters!")
コード例 #27
0
ファイル: command.py プロジェクト: trhr/evennia-barx
 def parse(self):
     if not self.args:
         self.msg("What would you like to bury? Usage: 'bury <bones>'")
     else:
         self.target = self.caller.search(self.args.strip())
         if not inherits_from(self.target, Bones):
             self.target = None
             self.msg("You can only bury bones!")
コード例 #28
0
ファイル: npcshop.py プロジェクト: asurvivor/BeyondTheVeil
def get_wares(caller):
    """
    Gets items located in the designated storeroom of the caller's location with a price assigned
    Only descendants of the Item typeclass are eligible for sale
    """
    return [
        ware for ware in caller.location.db.storeroom.contents
        if inherits_from(ware, Item) and ware.db.value
    ]
コード例 #29
0
ファイル: cmdset.py プロジェクト: Antraeus/evennia
    def add(self, cmd):
        """
        Add a command, a list of commands or a cmdset to this cmdset.

        Note that if cmd already exists in set,
        it will replace the old one (no priority checking etc
        at this point; this is often used to overload
        default commands).

        If cmd is another cmdset class or -instance, the commands
        of that command set is added to this one, as if they were part
        of the original cmdset definition. No merging or priority checks
        are made, rather later added commands will simply replace
        existing ones to make a unique set.
        """

        if inherits_from(cmd, "evennia.commands.cmdset.CmdSet"):
            # cmd is a command set so merge all commands in that set
            # to this one. We raise a visible error if we created
            # an infinite loop (adding cmdset to itself somehow)
            try:
                cmd = self._instantiate(cmd)
            except RuntimeError:
                string = "Adding cmdset %(cmd)s to %(class)s lead to an "
                string += "infinite loop. When adding a cmdset to another, "
                string += "make sure they are not themself cyclically added to "
                string += "the new cmdset somewhere in the chain."
                raise RuntimeError(_(string) % {"cmd": cmd,
                                                "class": self.__class__})
            cmds = cmd.commands
        elif is_iter(cmd):
            cmds = [self._instantiate(c) for c in cmd]
        else:
            cmds = [self._instantiate(cmd)]
        commands = self.commands
        system_commands = self.system_commands
        for cmd in cmds:
            # add all commands
            if not hasattr(cmd, 'obj'):
                cmd.obj = self.cmdsetobj
            try:
                ic = commands.index(cmd)
                commands[ic] = cmd  # replace
            except ValueError:
                commands.append(cmd)
            # extra run to make sure to avoid doublets
            self.commands = list(set(commands))
            #print "In cmdset.add(cmd):", self.key, cmd
            # add system_command to separate list as well,
            # for quick look-up
            if cmd.key.startswith("__"):
                try:
                    ic = system_commands.index(cmd)
                    system_commands[ic] = cmd  # replace
                except ValueError:
                    system_commands.append(cmd)
コード例 #30
0
ファイル: building.py プロジェクト: vincent-lg/Avenew
    def create_obj(self, args):
        """
        Create an object, given its new key.

        When using the |w@new obj|n command, you have to specify the name of
        the object to create.  This is a mandatory argument.

        Other options:
            |y-p|n (|y--prototype|n): the object prototype.
            |y-l|n (|y--location|n): the object's location.

        Examples:
          |w@new obj an apple|n
          |w@new obj an apple -p red_apple|n
          |w@new obj a lovely apple -t red_apple -l #2|n

        Objects don't necessarily have a prototype, even though it is very common.
        You can set their prototype by the |y-p|n option.

        Using the optional location, you can easily spawn an object in a container
        (owned by a player, for instance) or on the ground of a distant
        room.  If you don't specify this option, the object will be
        spawned at your feet.

        """
        key = " ".join(args.key).strip().lower()

        if not key:
            self.msg("|rSpecify at least a name for this object prototype.|n")
            return

        # Search for the optional prototype
        prototype = None
        if args.prototype:
            prototype = self.caller.search(args.prototype, global_search=True, use_dbref=True)
            if not prototype:
                return
            elif not inherits_from(prototype, "typeclasses.prototypes.PObj"):
                self.msg("{} isn't a valid object prototype.".format(prototype.get_display_name(self.caller)))
                return

        # Search for the optional location
        location = self.caller.location
        if args.location:
            location = self.caller.search(args.location, global_search=True, use_dbref=True)
            if not location:
                return

        # Create the new Obj
        if prototype:
            obj = prototype.create(key=key, location=location)
            self.msg("The object {} was created on prototype {}.".format(obj.get_display_name(self.caller), prototype.key))
        else:
            obj = create_object("typeclasses.objects.Object", key=key, location=location)
            self.msg("The object {} was successfully created without a prototype.".format(obj.get_display_name(self.caller)))
        self.msg("It was spawned in: {}.".format(location.get_display_name(self.caller)))
コード例 #31
0
ファイル: views.py プロジェクト: taishan90/evennia
def sheet(request, object_id):
    object_id = '#' + object_id
    try:
        character = object_search(object_id)[0]
    except IndexError:
        raise Http404("I couldn't find a character with that ID.")
    if not inherits_from(character, settings.BASE_CHARACTER_TYPECLASS):
        raise Http404("I couldn't find a character with that ID. "
                      "Found something else instead.")
    return render(request, 'character/sheet.html', {'character': character})
コード例 #32
0
ファイル: views.py プロジェクト: Cloudxtreme/cMUD
def sheet(request, char_name):
    name = char_name
    try:
        character = search_object(name)[0]
    except IndexError:
        raise Http404("I couldn't find a character with that name.")
    if not inherits_from(character, settings.BASE_CHARACTER_TYPECLASS):
        raise Http404("I couldn't find a character with that name."
                      "Found something else instead.")
    return render(request, 'charinfo/sheet.html', {'character': character})
コード例 #33
0
ファイル: driving.py プロジェクト: vincent-lg/Avenew
    def func(self):
        """Execute the command."""
        room = self.caller.location
        if not inherits_from(room, "typeclasses.rooms.VehicleRoom"):
            self.msg("|rIt seems you are not in a vehicle.|n")
            return

        vehicle = room.location

        # A VehicleRoom should be contained in a vehicle... but let's check
        if not inherits_from(vehicle, "typeclasses.vehicles.Vehicle"):
            self.msg("|rAre you, or are you not, in a vehicle?  Hard to say.|n..")
            return

        # Make sure we are currently driving
        if vehicle.db.driver is not self.caller:
            self.msg("|gYou aren't driving {}|n.".format(vehicle.key))
            return

        # If the vehicle is parked, un-park it
        if vehicle.location is not None:
            vehicle.location = None

        # Change the speed
        current = vehicle.db.speed
        desired = self.args.strip()

        try:
            desired = int(desired)
            assert desired >= 0
        except (ValueError, AssertionError):
            self.msg("|rSorry, this is not a valid speed.|n")
        else:
            vehicle.db.desired_speed = desired
            self.msg("You're now planning to drive at {} MPH.".format(desired))

            # Display a message to the vehicle if the speed changes
            if current < desired:
                vehicle.msg_contents("{} begins to speed up.".format(
                        vehicle.key))
            elif current > desired:
                vehicle.msg_contents("{} begins to slow down.".format(
                        vehicle.key))
コード例 #34
0
ファイル: views.py プロジェクト: Treatz/crash
def sheet(request, object_id):
    object_id = '#' + object_id
    try:
        character = object_search(object_id)[0]
    except IndexError:
        raise Http404("I couldn't find a character with that ID.")
    if not inherits_from(character, settings.BASE_CHARACTER_TYPECLASS):
        raise Http404("I couldn't find a character with that ID. "
                      "Found something else instead.")
    return render(request, 'character/sheet.html', {'character': character})
コード例 #35
0
    def add(self,
            cmdset,
            emit_to_obj=None,
            permanent=False,
            default_cmdset=False):
        """
        Add a cmdset to the handler, on top of the old ones, unless it
        is set as the default one (it will then end up at the bottom of the stack)

        Args:
            cmdset (CmdSet or str): Can be a cmdset object or the python path
                to such an object.
            emit_to_obj (Object, optional): An object to receive error messages.
            permanent (bool, optional): This cmdset will remain across a server reboot.
            default_cmdset (Cmdset, optional): Insert this to replace the
                default cmdset position (there is only one such position,
                always at the bottom of the stack).

        Notes:
          An interesting feature of this method is if you were to send
          it an *already instantiated cmdset* (i.e. not a class), the
          current cmdsethandler's obj attribute will then *not* be
          transferred over to this already instantiated set (this is
          because it might be used elsewhere and can cause strange
          effects).  This means you could in principle have the
          handler launch command sets tied to a *different* object
          than the handler. Not sure when this would be useful, but
          it's a 'quirk' that has to be documented.

        """
        if not (isinstance(cmdset, str)
                or utils.inherits_from(cmdset, CmdSet)):
            string = _("Only CmdSets can be added to the cmdsethandler!")
            raise Exception(string)

        if callable(cmdset):
            cmdset = cmdset(self.obj)
        elif isinstance(cmdset, str):
            # this is (maybe) a python path. Try to import from cache.
            cmdset = self._import_cmdset(cmdset)
        if cmdset and cmdset.key != "_CMDSET_ERROR":
            cmdset.permanent = permanent
            if permanent and cmdset.key != "_CMDSET_ERROR":
                # store the path permanently
                storage = self.obj.cmdset_storage or [""]
                if default_cmdset:
                    storage[0] = cmdset.path
                else:
                    storage.append(cmdset.path)
                self.obj.cmdset_storage = storage
            if default_cmdset:
                self.cmdset_stack[0] = cmdset
            else:
                self.cmdset_stack.append(cmdset)
            self.update()
コード例 #36
0
ファイル: typeclasses.py プロジェクト: Henddher/evennia
    def at_before_say(self, message, **kwargs):
        """
        Before the object says something.

        This hook is by default used by the 'say' and 'whisper'
        commands as used by this command it is called before the text
        is said/whispered and can be used to customize the outgoing
        text from the object. Returning `None` aborts the command.

        Args:
            message (str): The suggested say/whisper text spoken by self.
        Kwargs:
            whisper (bool): If True, this is a whisper rather than
                a say. This is sent by the whisper command by default.
                Other verbal commands could use this hook in similar
                ways.
            receiver (Object): If set, this is a target for the say/whisper.

        Returns:
            message (str): The (possibly modified) text to be spoken.

        """
        # First, try the location
        location = getattr(self, "location", None)
        location = location if location and inherits_from(location, "evennia.objects.objects.DefaultRoom") else None
        if location and not kwargs.get("whisper", False):
            allow = location.callbacks.call("can_say", self, location, message, parameters=message)
            message = location.callbacks.get_variable("message")
            if not allow or not message:
                return

            # Browse all the room's other characters
            for obj in location.contents:
                if obj is self or not inherits_from(obj, "evennia.objects.objects.DefaultCharacter"):
                    continue

                allow = obj.callbacks.call("can_say", self, obj, message, parameters=message)
                message = obj.callbacks.get_variable("message")
                if not allow or not message:
                    return

        return message
コード例 #37
0
ファイル: characters.py プロジェクト: ChrisLR/scrolls
    def modify_vital(self, attr_type, by=0):
        """
        same as change_vital except  adds it to modifier list
        attr_type must be a vald key on AttributeHandler
        """

        attr = self.__getattr__(attr_type)
        if not inherits_from(attr, 'world.attributes.VitalAttribute'):
            raise NotImplementedError(
                'modify_vital function doesnt support changing attribute that are NOT VitalAttributes'
            )

        #
        # Nifty piece of code  here, instead of tracking individual
        # objects that modify vitals, instead I turned it into a math
        # game. If your mod list looks like this:
        #
        # mod = [1,1,-2,5], your a cum modifier of 5
        #
        # when you add a modifer to the list, instead of it growing
        # forever, it will first try to find the oppositve value
        # and attempt to remove that, if it can't find it, it will a
        # add it. For example
        #
        # health_mod = [2,2,-3,5,10] (16)
        # modify_vital('health', by=3) # adding three to modifer
        #
        # results would be:
        #
        # health_mod = [2,2,5,10] (19)
        # it found a opposite of 3 (-3)
        # and removed that.

        # modify_vital('health', by=-10) # deduct 10 from mod
        # health_mod = [2,2,5] (9)

        # doing it again though: modify_vital('health', by=-10)
        # health_mod = [2,2,5,-10] (-1)
        #
        #

        if by != 0:
            # attempt to remove a positive equiv
            # mod, if it doesn't exist add it
            tmp = -by
            try:
                idx = attr.mod.index(tmp)
                attr.mod.remove(attr.mod[idx])
            except ValueError:
                # it doesn't exist, just add it to list
                attr.mod.append(by)
        self.__setattr__(attr_type, attr)
        self.update()
コード例 #38
0
ファイル: combat.py プロジェクト: evennia/ainneve
    def func(self):
        caller = self.caller
        if not self.args:
            caller.msg("Usage: attack <target>")
            return

        target = caller.search(self.args)
        if not target:
            return

        # for combat against yourself
        if target.id == caller.id:
            caller.msg("Combat against yourself is not supported.")
            return

        if not inherits_from(target, 'typeclasses.characters.Character'):
            caller.msg("Combat against {target} is not supported.".format(
                target=target.get_display_name(caller)))
            return

        if target.ndb.no_attack:
            caller.msg("You cannot attack {target} at this time.".format(
                target=target.get_display_name(caller)
            ))
            return

        if caller.location.tags.get('no_attack', None, category='flags'):
            caller.msg("Combat is not allowed in this location.")
            return

        # set up combat
        if target.ndb.combat_handler:
            # target is already in combat - join it
            target.ndb.combat_handler.add_character(caller)
            target.ndb.combat_handler.combat_msg(
                "{actor} joins combat!" ,
                actor=caller
            )
        else:
            # create a new combat handler
            chandler = create_script("typeclasses.combat_handler.CombatHandler")
            chandler.add_character(caller)
            chandler.add_character(target)
            caller.msg("You attack {}!".format(
                target.get_display_name(caller)))
            target.msg("{} attacks you!".format(
                caller.get_display_name(target)))
            for char in chandler.db.characters.values():
                char.execute_cmd("look")
            chandler.msg_all("The turn begins. Declare your actions!")
コード例 #39
0
ファイル: player.py プロジェクト: Antraeus/evennia
 def func(self):
     "implement the ooc look command"
     if MULTISESSION_MODE < 2:
         # only one character allowed
         string = "You are out-of-character (OOC).\nUse {w@ic{n to get back into the game."
         self.msg(string)
         return
     if utils.inherits_from(self.caller, "evennia.objects.objects.Object"):
         # An object of some type is calling. Use default look instead.
         super(CmdOOCLook, self).func()
     elif self.args:
         self.look_target()
     else:
         self.no_look_target()
コード例 #40
0
ファイル: cmdsethandler.py プロジェクト: 0rchard/evennia
    def add(self, cmdset, emit_to_obj=None, permanent=False, default_cmdset=False):
        """
        Add a cmdset to the handler, on top of the old ones, unless it
        is set as the default one (it will then end up at the bottom of the stack)

        Args:
            cmdset (CmdSet or str): Can be a cmdset object or the python path
                to such an object.
            emit_to_obj (Object, optional): An object to receive error messages.
            permanent (bool, optional): This cmdset will remain across a server reboot.
            default_cmdset (Cmdset, optional): Insert this to replace the
                default cmdset position (there is only one such position,
                always at the bottom of the stack).

        Notes:
          An interesting feature of this method is if you were to send
          it an *already instantiated cmdset* (i.e. not a class), the
          current cmdsethandler's obj attribute will then *not* be
          transferred over to this already instantiated set (this is
          because it might be used elsewhere and can cause strange
          effects).  This means you could in principle have the
          handler launch command sets tied to a *different* object
          than the handler. Not sure when this would be useful, but
          it's a 'quirk' that has to be documented.

        """
        if not (isinstance(cmdset, basestring) or utils.inherits_from(cmdset, CmdSet)):
            string = _("Only CmdSets can be added to the cmdsethandler!")
            raise Exception(string)

        if callable(cmdset):
            cmdset = cmdset(self.obj)
        elif isinstance(cmdset, basestring):
            # this is (maybe) a python path. Try to import from cache.
            cmdset = self._import_cmdset(cmdset)
        if cmdset and cmdset.key != '_CMDSET_ERROR':
            cmdset.permanent = permanent
            if permanent and cmdset.key != '_CMDSET_ERROR':
                # store the path permanently
                storage = self.obj.cmdset_storage or [""]
                if default_cmdset:
                    storage[0] = cmdset.path
                else:
                    storage.append(cmdset.path)
                self.obj.cmdset_storage = storage
            if default_cmdset:
                self.cmdset_stack[0] = cmdset
            else:
                self.cmdset_stack.append(cmdset)
            self.update()
コード例 #41
0
ファイル: exitdirections.py プロジェクト: Pinacolada64/NOW
        def find_by_name(search):
            search = search.strip().split(';', 1)[0]
            keyquery = Q(db_key__istartswith=search)
            aliasquery = Q(db_tags__db_key__istartswith=search,
                           db_tags__db_tagtype__iexact='alias')

            results = ObjectDB.objects.filter(keyquery | aliasquery).distinct()
            nresults = results.count()

            if nresults:  # convert multiple results to typeclasses.
                results = [result for result in results]
                room_typeclass = settings.BASE_ROOM_TYPECLASS  # Narrow results to only room types.
                results = [obj for obj in results if inherits_from(obj, room_typeclass)]
            return results
コード例 #42
0
ファイル: pathfinder.py プロジェクト: Pinacolada64/NOW
 def _searcher(self, room, depth):
     """Searches surrounding rooms recursively for an object"""
     if not room or len(self.visited) >= self.maxrooms:  # Stop search if the search has ...
         return False  # ... visited too many rooms or has come across a bad room.
     loc = self.caller.location
     this = self.obj.get_display_name(self.caller)
     target = self.target.get_display_name(self.caller)
     # first, record searching here
     self.visited.append(room)
     # End search either when the item is found...
     if self.target in ([room] + room.contents + sum([each.contents for each in room.contents], [])):
         if depth == 0:
             here = loc.get_display_name(self.caller)
             loc.msg_contents("{} finds {} right here in {}!".format(this, target, here))
         else:
             way = self.direction.get_display_name(self.caller, mxp=self.direction.key)
             plural = 's' if depth != 1 else ''
             if inherits_from(self.direction, 'typeclasses.rooms.Room'):
                 dir_convert = {'n': 'north', 's': 'south', 'e': 'east', 'w': 'west',
                                'nw': 'northwest', 'se': 'southeast',
                                'ne': 'northeast', 'sw': 'southwest', 'u': 'up', 'd': 'down'}
                 directions = {k: v for k, v in loc.db.exits.items() if v == self.direction}
                 way = '|lc{0}|lt|530{1}|n|le'.format(directions.keys()[0], dir_convert[directions.keys()[0]])
             loc.msg_contents("{} detects {} {} step{} away. Go {}".format(this, target, depth, plural, way))
             print('Depth and Number of rooms searched: ', depth, len(self.visited))
         return True
     # or searched to `maxdepth` distance
     if depth >= self.maxdepth:
         return False
     # Target not in the current room, scan through the exits and check them,
     # skipping rooms we've already visited
     exits = [exit for exit in room.exits if exit.destination not in self.visited]
     orange_destinations = [room.db.exits[exit] for exit in room.db.exits.keys()
                            if room.db.exits[exit] not in self.visited] if room.db.exits else []
     for next in exits:
         if depth == 0:  # we only want to return the exit out of the current room
             self.direction = next
         if self._searcher(next.destination, depth + 1):  # if we found the object, stop searching
             return True
     for next in orange_destinations:
         if depth == 0:  # we only want to return the orange exit out of the current room
             self.direction = next
         if self._searcher(next, depth + 1):  # if we found the object, stop searching
             return True
     # Check all the exits, no result
     return False
コード例 #43
0
ファイル: cmdsethandler.py プロジェクト: G-Wang/text-world
    def add(self, cmdset, emit_to_obj=None, permanent=False):
        """
        Add a cmdset to the handler, on top of the old ones.
        Default is to not make this permanent, i.e. the set
        will not survive a server reset.

        cmdset - can be a cmdset object or the python path to
                 such an object.
        emit_to_obj - an object to receive error messages.
        permanent - this cmdset will remain across a server reboot

        Note: An interesting feature of this method is if you were to
        send it an *already instantiated cmdset* (i.e. not a class),
        the current cmdsethandler's obj attribute will then *not* be
        transferred over to this already instantiated set (this is
        because it might be used elsewhere and can cause strange effects).
        This means you could in principle have the handler
        launch command sets tied to a *different* object than the
        handler. Not sure when this would be useful, but it's a 'quirk'
        that has to be documented.
        """
        if not (isinstance(cmdset, basestring) or utils.inherits_from(cmdset, CmdSet)):
            string = _("Only CmdSets can be added to the cmdsethandler!")
            raise Exception(string)

        if callable(cmdset):
            cmdset = cmdset(self.obj)
        elif isinstance(cmdset, basestring):
            # this is (maybe) a python path. Try to import from cache.
            cmdset = self._import_cmdset(cmdset)
        if cmdset and cmdset.key != "_CMDSET_ERROR":
            if permanent and cmdset.key != "_CMDSET_ERROR":
                # store the path permanently
                cmdset.permanent = True
                storage = self.obj.cmdset_storage
                if not storage:
                    storage = ["", cmdset.path]
                else:
                    storage.append(cmdset.path)
                self.obj.cmdset_storage = storage
            else:
                cmdset.permanent = False
            self.cmdset_stack.append(cmdset)
            self.update()
コード例 #44
0
ファイル: command.py プロジェクト: Gazzilow/mu2ch
    def func(self):
        caller = self.caller
        args = self.args

        if (not len(args)):
            caller.msg(u"Не указано какое вещество употребить.")
            return False
            
        substance = caller.search(args, location=caller, global_search = False, nofound_string = u"Такого вещества у тебя нет") 

        if (not substance):
            return False

        if (utils.inherits_from(substance, 'typeclasses.substance.Substance')):
            caller.msg(u"Ты употребил %s" % substance.name)
            substance.use(caller) 
        else:
            # TODO переработать, использовать можно не только вещества
            caller.msg(u"Ты не можешь употребить %s" % substance.name) 


        return True
コード例 #45
0
ファイル: simpledoor.py プロジェクト: helix-0311/evennia
 def create_exit(self, exit_name, location, destination,
                 exit_aliases=None, typeclass=None):
     """
     Simple wrapper for the default CmdOpen.create_exit
     """
     # create a new exit as normal
     new_exit = super(CmdOpen, self).create_exit(exit_name, location, destination,
                                                 exit_aliases=exit_aliases, typeclass=typeclass)
     if hasattr(self, "return_exit_already_created"):
         # we don't create a return exit if it was already created (because
         # we created a door)
         del self.return_exit_already_created
         return new_exit
     if inherits_from(new_exit, SimpleDoor):
         # a door - create its counterpart and make sure to turn off the default
         # return-exit creation of CmdOpen
         self.caller.msg("Note: A door-type exit was created - ignored eventual custom return-exit type.")
         self.return_exit_already_created = True
         back_exit = self.create_exit(exit_name, destination, location,
                                                      exit_aliases=exit_aliases, typeclass=typeclass)
         new_exit.db.return_exit = back_exit
         back_exit.db.return_exit = new_exit
     return new_exit
コード例 #46
0
ファイル: cmdsethandler.py プロジェクト: G-Wang/text-world
    def add_default(self, cmdset, emit_to_obj=None, permanent=True):
        """
        Add a new default cmdset. If an old default existed,
        it is replaced. If permanent is set, the set will survive a reboot.
        cmdset - can be a cmdset object or the python path to
                 an instance of such an object.
        emit_to_obj - an object to receive error messages.
        permanent - save cmdset across reboots
        See also the notes for self.add(), which applies here too.
        """
        if callable(cmdset):
            if not utils.inherits_from(cmdset, CmdSet):
                string = _("Only CmdSets can be added to the cmdsethandler!")
                raise Exception(string)
            cmdset = cmdset(self.obj)
        elif isinstance(cmdset, basestring):
            # this is (maybe) a python path. Try to import from cache.
            cmdset = self._import_cmdset(cmdset)
        if cmdset and cmdset.key != "_CMDSET_ERROR":
            if self.cmdset_stack:
                self.cmdset_stack[0] = cmdset
                self.mergetype_stack[0] = cmdset.mergetype
            else:
                self.cmdset_stack = [cmdset]
                self.mergetype_stack = [cmdset.mergetype]

            if permanent and cmdset.key != "_CMDSET_ERROR":
                cmdset.permanent = True
                storage = self.obj.cmdset_storage
                if storage:
                    storage[0] = cmdset.path
                else:
                    storage = [cmdset.path]
                self.obj.cmdset_storage = storage
            else:
                cmdset.permanent = False
            self.update()
コード例 #47
0
ファイル: lockfuncs.py プロジェクト: RyanStein/evennia
def perm(accessing_obj, accessed_obj, *args, **kwargs):
    """
    The basic permission-checker. Ignores case.

    Usage:
       perm(<permission>)

    where <permission> is the permission accessing_obj must
    have in order to pass the lock.

    If the given permission is part of settings.PERMISSION_HIERARCHY,
    permission is also granted to all ranks higher up in the hierarchy.

    If accessing_object is an Object controlled by an Account, the
    permissions of the Account is used unless the Attribute _quell
    is set to True on the Object. In this case however, the
    LOWEST hieararcy-permission of the Account/Object-pair will be used
    (this is order to avoid Accounts potentially escalating their own permissions
    by use of a higher-level Object)

    """
    # this allows the perm_above lockfunc to make use of this function too
    gtmode = kwargs.pop("_greater_than", False)

    try:
        permission = args[0].lower()
        perms_object = [p.lower() for p in accessing_obj.permissions.all()]
    except (AttributeError, IndexError):
        return False

    if utils.inherits_from(accessing_obj, "evennia.objects.objects.DefaultObject") and accessing_obj.account:
        account = accessing_obj.account
        # we strip eventual plural forms, so Builders == Builder
        perms_account = [p.lower().rstrip("s") for p in account.permissions.all()]
        is_quell = account.attributes.get("_quell")

        if permission in _PERMISSION_HIERARCHY:
            # check hierarchy without allowing escalation obj->account
            hpos_target = _PERMISSION_HIERARCHY.index(permission)
            hpos_account = [hpos for hpos, hperm in enumerate(_PERMISSION_HIERARCHY) if hperm in perms_account]
            hpos_account = hpos_account and hpos_account[-1] or -1
            if is_quell:
                hpos_object = [hpos for hpos, hperm in enumerate(_PERMISSION_HIERARCHY) if hperm in perms_object]
                hpos_object = hpos_object and hpos_object[-1] or -1
                if gtmode:
                    return hpos_target < min(hpos_account, hpos_object)
                else:
                    return hpos_target <= min(hpos_account, hpos_object)
            elif gtmode:
                return hpos_target < hpos_account
            else:
                return hpos_target <= hpos_account
        elif not is_quell and permission in perms_account:
            # if we get here, check account perms first, otherwise
            # continue as normal
            return True

    if permission in perms_object:
        # simplest case - we have direct match
        return True
    if permission in _PERMISSION_HIERARCHY:
        # check if we have a higher hierarchy position
        hpos_target = _PERMISSION_HIERARCHY.index(permission)
        return any(1 for hpos, hperm in enumerate(_PERMISSION_HIERARCHY)
                   if hperm in perms_object and hpos_target < hpos)
    return False
コード例 #48
0
ファイル: lockfuncs.py プロジェクト: Antraeus/evennia
def _to_player(accessing_obj):
    "Helper function. Makes sure an accessing object is a player object"
    if utils.inherits_from(accessing_obj, "evennia.objects.objects.DefaultObject"):
        # an object. Convert to player.
        accessing_obj = accessing_obj.player
    return accessing_obj
コード例 #49
0
ファイル: lockfuncs.py プロジェクト: BlauFeuer/evennia
def perm(accessing_obj, accessed_obj, *args, **kwargs):
    """
    The basic permission-checker. Ignores case.

    Usage:
       perm(<permission>)

    where <permission> is the permission accessing_obj must
    have in order to pass the lock.

    If the given permission is part of settings.PERMISSION_HIERARCHY,
    permission is also granted to all ranks higher up in the hierarchy.

    If accessing_object is an Object controlled by an Account, the
    permissions of the Account is used unless the Attribute _quell
    is set to True on the Object. In this case however, the
    LOWEST hieararcy-permission of the Account/Object-pair will be used
    (this is order to avoid Accounts potentially escalating their own permissions
    by use of a higher-level Object)

    """
    # this allows the perm_above lockfunc to make use of this function too
    try:
        permission = args[0].lower()
        perms_object = accessing_obj.permissions.all()
    except (AttributeError, IndexError):
        return False

    gtmode = kwargs.pop("_greater_than", False)
    is_quell = False

    account = (utils.inherits_from(accessing_obj, "evennia.objects.objects.DefaultObject") and
               accessing_obj.account)
    # check object perms (note that accessing_obj could be an Account too)
    perms_account = []
    if account:
        perms_account = account.permissions.all()
        is_quell = account.attributes.get("_quell")

    # Check hirarchy matches; handle both singular/plural forms in hierarchy
    hpos_target = None
    if permission in _PERMISSION_HIERARCHY:
        hpos_target = _PERMISSION_HIERARCHY.index(permission)
    if permission.endswith('s') and permission[:-1] in _PERMISSION_HIERARCHY:
        hpos_target = _PERMISSION_HIERARCHY.index(permission[:-1])
    if hpos_target is not None:
        # hieratchy match
        hpos_account = -1
        hpos_object = -1

        if account:
            # we have an account puppeting this object. We must check what perms it has
            perms_account_single = [p[:-1] if p.endswith('s') else p for p in perms_account]
            hpos_account = [hpos for hpos, hperm in enumerate(_PERMISSION_HIERARCHY)
                            if hperm in perms_account_single]
            hpos_account = hpos_account and hpos_account[-1] or -1

        if not account or is_quell:
            # only get the object-level perms if there is no account or quelling
            perms_object_single = [p[:-1] if p.endswith('s') else p for p in perms_object]
            hpos_object = [hpos for hpos, hperm in enumerate(_PERMISSION_HIERARCHY)
                           if hperm in perms_object_single]
            hpos_object = hpos_object and hpos_object[-1] or -1

        if account and is_quell:
            # quell mode: use smallest perm from account and object
            if gtmode:
                return hpos_target < min(hpos_account, hpos_object)
            else:
                return hpos_target <= min(hpos_account, hpos_object)
        elif account:
            # use account perm
            if gtmode:
                return hpos_target < hpos_account
            else:
                return hpos_target <= hpos_account
        else:
            # use object perm
            if gtmode:
                return hpos_target < hpos_object
            else:
                return hpos_target <= hpos_object
    else:
        # no hierarchy match - check direct matches
        if account:
            # account exists, check it first unless quelled
            if is_quell and permission in perms_object:
                return True
            elif permission in perms_account:
                return True
        elif permission in perms_object:
            return True

    return False
コード例 #50
0
ファイル: building.py プロジェクト: evennia/ainneve
    def func(self):
        caller = self.caller

        if not self.args:
            self._usage()
            return

        # split the target off from the first list argument
        targs = tuple(self.lhslist[0].rsplit(' ', 1))
        if len(targs) == 1 or \
                (len(targs) > 1 and targs[1].lower() not in ALL_SKILLS):
            target, self.lhslist[0] = self.lhslist[0], ''
        else:
            target, self.lhslist[0] = targs

        char = caller.search(target,
                             location=caller.location,
                             typeclass='typeclasses.characters.NPC')

        if not char:
            return

        # the inherits_from check below is necessary due to an issue
        # with search() on the ContripRPObject class
        if not inherits_from(char, 'typeclasses.characters.NPC'):
            caller.msg("Could not find NPC: '{}'".format(target))
            return

        if self.rhs:  # handle assignments
            if not all((x.isdigit() for x in self.rhslist)):
                caller.msg('Assignment values must be numeric.')
                return
            if len(self.lhslist) != len(self.rhslist):
                caller.msg('Incorrect number of assignment values.')
                return
            for i in xrange(len(self.lhslist)):
                if self.lhslist[i].lower() in char.skills.all:
                    char.skills[self.lhslist[i].lower()].base = \
                        min(max(int(self.rhslist[i]), 0), 10)  # enforce {0, 10} bounds
                    caller.msg('Skill "{}" set to {} for {}'.format(
                        self.lhslist[i].lower(),
                        min(max(int(self.rhslist[i]), 0), 10),
                        char.sdesc.get()))
                else:
                    caller.msg('Invalid skill: "{}"'.format(self.lhslist[i]))

        # display traits
        data = []
        if any(self.lhslist):
            skills = [s.lower() for s in self.lhslist
                      if s.lower() in char.skills.all]
        else:
            skills = char.skills.all

        if len(skills) < 3:
            [data.append([self._format_skill_3col(char.skills[s])])
             for s in skills]
        else:
            [data.append([self._format_skill_3col(char.skills[s])
                          for s in skills[i::3]])
             for i in xrange(3)]
        table = EvTable(header=False, table=data)
        caller.msg(unicode(table))
コード例 #51
0
ファイル: building.py プロジェクト: evennia/ainneve
    def func(self):
        caller = self.caller

        if not self.args:
            self._usage()
            return

        # split off the target from the first item of lhslist
        targs = tuple(self.lhslist[0].rsplit(' ', 1))
        if len(targs) == 1 or \
                (len(targs) > 1 and targs[1].upper() not in ALL_TRAITS):
            target, self.lhslist[0] = self.lhslist[0], ''
        else:
            target, self.lhslist[0] = targs

        # search for the target NPC
        char = caller.search(target,
                             location=caller.location,
                             typeclass='typeclasses.characters.NPC')

        if not char:
            return

        # the inherits_from check below is necessary due to an issue
        # with search() on the ContripRPObject class
        if not inherits_from(char, 'typeclasses.characters.NPC'):
            caller.msg("Could not find NPC: '{}'".format(target))
            return

        if self.rhs:
            if not all((x.isdigit() for x in self.rhslist)):
                caller.msg('Assignment values must be numeric.')
                return
            if len(self.lhslist) != len(self.rhslist):
                caller.msg('Incorrect number of assignment values.')
                return
            for i in xrange(len(self.lhslist)):
                if self.lhslist[i].upper() in char.traits.all:
                    char.traits[self.lhslist[i].upper()].base = \
                        min(max(int(self.rhslist[i]), 0), 10)
                    caller.msg('Trait "{}" set to {} for {}'.format(
                        self.lhslist[i].upper(),
                        min(max(int(self.rhslist[i]), 0), 10),
                        char.sdesc.get()))
                else:
                    caller.msg('Invalid trait: "{}"'.format(self.lhslist[i]))

        # display traits
        data = []
        if any(self.lhslist):
            traits = [t.upper() for t in self.lhslist
                      if t.upper() in char.traits.all]
        else:
            traits = char.traits.all

        if len(traits) == 0:
            return
        elif 0 < len(traits) < 3:
            [data.append([self._format_trait_3col(char.traits[t])])
             for t in traits]
        else:
            [data.append([self._format_trait_3col(char.traits[t])
                          for t in traits[i::3]])
             for i in xrange(3)]
        table = EvTable(header=False, table=data)
        caller.msg(unicode(table))
コード例 #52
0
ファイル: npcshop.py プロジェクト: evennia/ainneve
def get_wares(caller):
    """
    Gets items located in the designated storeroom of the caller's location with a price assigned
    Only descendants of the Item typeclass are eligible for sale
    """
    return [ware for ware in caller.location.db.storeroom.contents if inherits_from(ware, Item) and ware.db.value]
コード例 #53
0
ファイル: muxcommand.py プロジェクト: helix-0311/evennia
    def parse(self):
        """
        This method is called by the cmdhandler once the command name
        has been identified. It creates a new set of member variables
        that can be later accessed from self.func() (see below)

        The following variables are available for our use when entering this
        method (from the command definition, and assigned on the fly by the
        cmdhandler):
           self.key - the name of this command ('look')
           self.aliases - the aliases of this cmd ('l')
           self.permissions - permission string for this command
           self.help_category - overall category of command

           self.caller - the object calling this command
           self.cmdstring - the actual command name used to call this
                            (this allows you to know which alias was used,
                             for example)
           self.args - the raw input; everything following self.cmdstring.
           self.cmdset - the cmdset from which this command was picked. Not
                         often used (useful for commands like 'help' or to
                         list all available commands etc)
           self.obj - the object on which this command was defined. It is often
                         the same as self.caller.

        A MUX command has the following possible syntax:

          name[ with several words][/switch[/switch..]] arg1[,arg2,...] [[=|,] arg[,..]]

        The 'name[ with several words]' part is already dealt with by the
        cmdhandler at this point, and stored in self.cmdname (we don't use
        it here). The rest of the command is stored in self.args, which can
        start with the switch indicator /.

        This parser breaks self.args into its constituents and stores them in the
        following variables:
          self.switches = [list of /switches (without the /)]
          self.raw = This is the raw argument input, including switches
          self.args = This is re-defined to be everything *except* the switches
          self.lhs = Everything to the left of = (lhs:'left-hand side'). If
                     no = is found, this is identical to self.args.
          self.rhs: Everything to the right of = (rhs:'right-hand side').
                    If no '=' is found, this is None.
          self.lhslist - [self.lhs split into a list by comma]
          self.rhslist - [list of self.rhs split into a list by comma]
          self.arglist = [list of space-separated args (stripped, including '=' if it exists)]

          All args and list members are stripped of excess whitespace around the
          strings, but case is preserved.
        """
        raw = self.args
        args = raw.strip()

        # split out switches
        switches = []
        if args and len(args) > 1 and raw[0] == "/":
            # we have a switch, or a set of switches. These end with a space.
            switches = args[1:].split(None, 1)
            if len(switches) > 1:
                switches, args = switches
                switches = switches.split('/')
            else:
                args = ""
                switches = switches[0].split('/')
        arglist = [arg.strip() for arg in args.split()]

        # check for arg1, arg2, ... = argA, argB, ... constructs
        lhs, rhs = args, None
        lhslist, rhslist = [arg.strip() for arg in args.split(',')], []
        if args and '=' in args:
            lhs, rhs = [arg.strip() for arg in args.split('=', 1)]
            lhslist = [arg.strip() for arg in lhs.split(',')]
            rhslist = [arg.strip() for arg in rhs.split(',')]

        # save to object properties:
        self.raw = raw
        self.switches = switches
        self.args = args.strip()
        self.arglist = arglist
        self.lhs = lhs
        self.lhslist = lhslist
        self.rhs = rhs
        self.rhslist = rhslist

        # if the class has the player_caller property set on itself, we make
        # sure that self.caller is always the player if possible. We also create
        # a special property "character" for the puppeted object, if any. This
        # is convenient for commands defined on the Player only.
        if hasattr(self, "player_caller") and self.player_caller:
            if utils.inherits_from(self.caller, "evennia.objects.objects.DefaultObject"):
                # caller is an Object/Character
                self.character = self.caller
                self.caller = self.caller.player
            elif utils.inherits_from(self.caller, "evennia.players.players.DefaultPlayer"):
                # caller was already a Player
                self.character = self.caller.get_puppet(self.session)
            else:
                self.character = None
コード例 #54
0
ファイル: models.py プロジェクト: ESPADACAGE/evennia
    def swap_typeclass(self, new_typeclass, clean_attributes=False,
                       run_start_hooks=True, no_default=True):
        """
        This performs an in-situ swap of the typeclass. This means
        that in-game, this object will suddenly be something else.
        Player will not be affected. To 'move' a player to a different
        object entirely (while retaining this object's type), use
        self.player.swap_object().

        Note that this might be an error prone operation if the
        old/new typeclass was heavily customized - your code
        might expect one and not the other, so be careful to
        bug test your code if using this feature! Often its easiest
        to create a new object and just swap the player over to
        that one instead.

        Args:
            new_typeclass (str or classobj): Type to switch to.
            clean_attributes (bool or list, optional): Will delete all
                attributes stored on this object (but not any of the
                database fields such as name or location). You can't get
                attributes back, but this is often the safest bet to make
                sure nothing in the new typeclass clashes with the old
                one. If you supply a list, only those named attributes
                will be cleared.
            run_start_hooks (bool, optional): Trigger the start hooks
                of the object, as if it was created for the first time.
            no_default (bool, optiona): If set, the swapper will not
                allow for swapping to a default typeclass in case the
                given one fails for some reason. Instead the old one will
                be preserved.
        Returns:
            result (bool): True/False depending on if the swap worked
                or not.

        """

        if not callable(new_typeclass):
            # this is an actual class object - build the path
            new_typeclass = class_from_module(new_typeclass, defaultpaths=settings.TYPECLASS_PATHS)

        # if we get to this point, the class is ok.


        if inherits_from(self, "evennia.scripts.models.ScriptDB"):
            if self.interval > 0:
                raise RuntimeError("Cannot use swap_typeclass on time-dependent " \
                                   "Script '%s'.\nStop and start a new Script of the " \
                                   "right type instead." % self.key)

        self.typeclass_path = new_typeclass.path
        self.__class__ = new_typeclass

        if clean_attributes:
            # Clean out old attributes
            if is_iter(clean_attributes):
                for attr in clean_attributes:
                    self.attributes.remove(attr)
                for nattr in clean_attributes:
                    if hasattr(self.ndb, nattr):
                        self.nattributes.remove(nattr)
            else:
                self.attributes.clear()
                self.nattributes.clear()

        if run_start_hooks:
            # fake this call to mimic the first save
            self.at_first_save()
コード例 #55
0
ファイル: muxcommand.py プロジェクト: Henddher/evennia
    def parse(self):
        """
        This method is called by the cmdhandler once the command name
        has been identified. It creates a new set of member variables
        that can be later accessed from self.func() (see below)

        The following variables are available for our use when entering this
        method (from the command definition, and assigned on the fly by the
        cmdhandler):
           self.key - the name of this command ('look')
           self.aliases - the aliases of this cmd ('l')
           self.permissions - permission string for this command
           self.help_category - overall category of command

           self.caller - the object calling this command
           self.cmdstring - the actual command name used to call this
                            (this allows you to know which alias was used,
                             for example)
           self.args - the raw input; everything following self.cmdstring.
           self.cmdset - the cmdset from which this command was picked. Not
                         often used (useful for commands like 'help' or to
                         list all available commands etc)
           self.obj - the object on which this command was defined. It is often
                         the same as self.caller.

        A MUX command has the following possible syntax:

          name[ with several words][/switch[/switch..]] arg1[,arg2,...] [[=|,] arg[,..]]

        The 'name[ with several words]' part is already dealt with by the
        cmdhandler at this point, and stored in self.cmdname (we don't use
        it here). The rest of the command is stored in self.args, which can
        start with the switch indicator /.

        Optional variables to aid in parsing, if set:
          self.switch_options  - (tuple of valid /switches expected by this
                                  command (without the /))
          self.rhs_split       - Alternate string delimiter or tuple of strings
                                 to separate left/right hand sides. tuple form
                                 gives priority split to first string delimiter.

        This parser breaks self.args into its constituents and stores them in the
        following variables:
          self.switches = [list of /switches (without the /)]
          self.raw = This is the raw argument input, including switches
          self.args = This is re-defined to be everything *except* the switches
          self.lhs = Everything to the left of = (lhs:'left-hand side'). If
                     no = is found, this is identical to self.args.
          self.rhs: Everything to the right of = (rhs:'right-hand side').
                    If no '=' is found, this is None.
          self.lhslist - [self.lhs split into a list by comma]
          self.rhslist - [list of self.rhs split into a list by comma]
          self.arglist = [list of space-separated args (stripped, including '=' if it exists)]

          All args and list members are stripped of excess whitespace around the
          strings, but case is preserved.
        """
        raw = self.args
        args = raw.strip()
        # Without explicitly setting these attributes, they assume default values:
        if not hasattr(self, "switch_options"):
            self.switch_options = None
        if not hasattr(self, "rhs_split"):
            self.rhs_split = "="
        if not hasattr(self, "account_caller"):
            self.account_caller = False

        # split out switches
        switches, delimiters = [], self.rhs_split
        if self.switch_options:
            self.switch_options = [opt.lower() for opt in self.switch_options]
        if args and len(args) > 1 and raw[0] == "/":
            # we have a switch, or a set of switches. These end with a space.
            switches = args[1:].split(None, 1)
            if len(switches) > 1:
                switches, args = switches
                switches = switches.split('/')
            else:
                args = ""
                switches = switches[0].split('/')
            # If user-provides switches, parse them with parser switch options.
            if switches and self.switch_options:
                valid_switches, unused_switches, extra_switches = [], [], []
                for element in switches:
                    option_check = [opt for opt in self.switch_options if opt == element]
                    if not option_check:
                        option_check = [opt for opt in self.switch_options if opt.startswith(element)]
                    match_count = len(option_check)
                    if match_count > 1:
                        extra_switches.extend(option_check)  # Either the option provided is ambiguous,
                    elif match_count == 1:
                        valid_switches.extend(option_check)  # or it is a valid option abbreviation,
                    elif match_count == 0:
                        unused_switches.append(element)  # or an extraneous option to be ignored.
                if extra_switches:  # User provided switches
                    self.msg('|g%s|n: |wAmbiguous switch supplied: Did you mean /|C%s|w?' %
                             (self.cmdstring, ' |nor /|C'.join(extra_switches)))
                if unused_switches:
                    plural = '' if len(unused_switches) == 1 else 'es'
                    self.msg('|g%s|n: |wExtra switch%s "/|C%s|w" ignored.' %
                             (self.cmdstring, plural, '|n, /|C'.join(unused_switches)))
                switches = valid_switches  # Only include valid_switches in command function call
        arglist = [arg.strip() for arg in args.split()]

        # check for arg1, arg2, ... = argA, argB, ... constructs
        lhs, rhs = args.strip(), None
        if lhs:
            if delimiters and hasattr(delimiters, '__iter__'):  # If delimiter is iterable,
                best_split = delimiters[0]  # (default to first delimiter)
                for this_split in delimiters:  # try each delimiter
                    if this_split in lhs:  # to find first successful split
                        best_split = this_split  # to be the best split.
                        break
            else:
                best_split = delimiters
            # Parse to separate left into left/right sides using best_split delimiter string
            if best_split in lhs:
                lhs, rhs = lhs.split(best_split, 1)
        # Trim user-injected whitespace
        rhs = rhs.strip() if rhs is not None else None
        lhs = lhs.strip()
        # Further split left/right sides by comma delimiter
        lhslist = [arg.strip() for arg in lhs.split(',')] if lhs is not None else ""
        rhslist = [arg.strip() for arg in rhs.split(',')] if rhs is not None else ""
        # save to object properties:
        self.raw = raw
        self.switches = switches
        self.args = args.strip()
        self.arglist = arglist
        self.lhs = lhs
        self.lhslist = lhslist
        self.rhs = rhs
        self.rhslist = rhslist

        # if the class has the account_caller property set on itself, we make
        # sure that self.caller is always the account if possible. We also create
        # a special property "character" for the puppeted object, if any. This
        # is convenient for commands defined on the Account only.
        if self.account_caller:
            if utils.inherits_from(self.caller, "evennia.objects.objects.DefaultObject"):
                # caller is an Object/Character
                self.character = self.caller
                self.caller = self.caller.account
            elif utils.inherits_from(self.caller, "evennia.accounts.accounts.DefaultAccount"):
                # caller was already an Account
                self.character = self.caller.get_puppet(self.session)
            else:
                self.character = None
コード例 #56
0
ファイル: lockfuncs.py プロジェクト: RyanStein/evennia
def _to_account(accessing_obj):
    "Helper function. Makes sure an accessing object is an account object"
    if utils.inherits_from(accessing_obj, "evennia.objects.objects.DefaultObject"):
        # an object. Convert to account.
        accessing_obj = accessing_obj.account
    return accessing_obj