Suppressing commands

68 views
Skip to first unread message

Marcus Bell

unread,
Feb 5, 2015, 8:25:52 AM2/5/15
to eve...@googlegroups.com
I don't want players to be able to do account maintenance functions such as create/delete characters unless they go @ooc. So I'm trying to selectively suppress commands in the default command sets using the key_mergetypes with no luck.

class ACmdSet(CmdSet):
    key
="ACmdSet"
    priority
= -10
   
def at_cmdset_creation(self):
       
self.add(CmdKill()) # permanently deletes existing character
       
self.add(CmdChars()) # lists characters for this account
       
class BCmdSet(CmdSet):
    key
="BCmdSet"
    priority
= -5
    key_mergetypes
= {"ACmdSet":"Remove"}
   
def at_cmdset_creation(self):
       
self.add(CmdKill())
       
self.add(CmdChars())
       
class CCmdSet(CmdSet):
    key
="CCmdSet"
    priority
= 0
    key_mergetypes
= {"ACmdSet":"Remove"}
   
def at_cmdset_creation(self):
       
self.add(CmdKill())
       
self.add(CmdChars())
       
class DCmdSet(CmdSet):
    key
="DCmdSet"
    priority
= 5
    key_mergetypes
= {"ACmdSet":"Remove"}
   
def at_cmdset_creation(self):
       
self.add(CmdKill())
       
self.add(CmdChars())
       
class ECmdSet(CmdSet):
    key
="ECmdSet"
    priority
= 15
    key_mergetypes
= {"ACmdSet":"Remove"}
   
def at_cmdset_creation(self):
       
self.add(CmdKill())
       
self.add(CmdChars())


class FCmdSet(CmdSet):
    key
="FCmdSet"
    priority
= 150
    key_mergetypes
= {"ACmdSet":"Remove"}
   
def at_cmdset_creation(self):
       
self.add(CmdKill())
       
self.add(CmdChars())


class PlayerCmdSet(default_cmds.PlayerCmdSet):
   
"""
    This is set is available to the player when they have no
    character connected to them (i.e. they are out-of-character, ooc).
    """

    key
= "PlayerCmdSet"
    priority
= -10
   
   
def at_cmdset_creation(self):
       
"""
        Populates the cmdset
        """

       
# calling setup in src.commands.default.cmdset_ooc
       
super(PlayerCmdSet, self).at_cmdset_creation()
       
print "creating player cmdset..."
       
self.add(UCmdReload()) # allow non super to reload until beta
       
self.add(ACmdSet) # these commands should be removed when @ic


class CharacterCmdSet(default_cmds.CharacterCmdSet):
   
...
    key
= "CharacterCmdSet"
    priority
= 0


   
def at_cmdset_creation(self):
       
"""
        Populates the cmdset
        """

       
super(CharacterCmdSet, self).at_cmdset_creation()
       
print "creating character cmdset..."
       
self.add(BCmdSet) # these commands should remove @ooc commands in command set A


I followed the tutorial on using key_mergetypes but it doesn't seem to work the way described. ACmdSet adds to the Player command set correctly but once they are in, they stay. None of the other command sets (B - F) remove the commands no matter where I put them. I've tried adding B - F to the higher priority default command sets, to characters, to objects, changing the priorities... There are no tracebacks, no errors in console. It's very frustrating. What am I doing wrong?


Griatch Art

unread,
Feb 5, 2015, 11:29:43 AM2/5/15
to eve...@googlegroups.com
Hi,

I think there is some confusion as to how cmdset merging works here.

With this setup you are not actually adding BCmdSet on top of your ACmdSet. You are adding CharacterCmdSet (which happens to contain the commands from BCmdSet) on top of ACmdSet. But CharacterCmdSet has no mergetype. It cannot have. If it had the mergetype "Remove" then no commands from the CharacterCmdset would be available (Remove doesn't add any cmds of its own, only filters others). When you add BCmdSet to CharacterCmdSet in at_cmdset_creation(), all it does is to copy the commands of BCmdSet into CharacterCmdset, you are not actually merging two cmdsets together (this would be done via merged_set = BCmdSet + CharacterCmdSet or more commonly via the character's cmdsethandler: character.cmdset.add(BCmdSet).)

Manipulating the player cmdset with the character cmdset like this is a rather tricky proposition overall, since you want to keep most of CharacterCmdset and only filter out a few things from PlayerCmdset. There are two ways I can think of to do this (apart from the non-cmdset solution of changing the relevant commands to check if their caller is ic or ooc):
  1. Make the entire CharacterCmdset use merge_type "Replace" and put two dummy commands in there to overload the Player-level versions.
  2. Once the puppeting is done (in the character.at_post_puppet() hook), call character.cmdset.add(BCmdSet), where BCmdSet.mergetype="Remove" and its priority was bigger than that of CharacterCmdSet. If we wanted to to use key_mergetype, we would need to set key_mergetype={"CharacterCmdSet":"Remove"} here, since at the point we want to merge in BCmdSet, CharacterCmdSet is already a merger of PlayerCmdSet (lowest prio at -10) and CharacterCmdSet (prio 0).
Hope that is understandable. The confusion here, I think, is that cmdsets are merged together one by one in order of priority and gradually builds up a conglomerate of sets. The name of this merged set is inherited from the highest-prio set that was last merged in. This is what the next set in the merge-queue have to work with - its mergetype (and the key_mergetype) can only be compared to the currently merged set's name. This is why merge order (priorities) are so important when wanting to filter commands with other sets and why so many different possibilities can be achieved with a limited number of sets.
.
Griatch

Marcus Bell

unread,
Feb 5, 2015, 12:33:24 PM2/5/15
to eve...@googlegroups.com
at_post_puppet gives me tracebacks, it can't decide if it wants exactly 3 or at least 3 parameters...
No matter how many arguments I allow, it always says only one was given (self, I imagine)
at_post_puppet(self)
at_post_puppet(self, sessid)
at_post_puppet(self, sessid, character)
at_post_puppet(self, sessid, character, normal_mode=True)


Traceback (most recent call last):
  File "C:\mushdev\evennia\src\commands\cmdhandler.py", line 412, in cmdhandler
    ret = yield cmd.func()
  File "C:\mushdev\evennia\game\gamesrc\commands\player_cmds.py", line 122, in func
    self.player.puppet_object(self.sessid, char[0], normal_mode=True)
  File "C:\mushdev\evennia\src\players\models.py", line 335, in puppet_object
    _GA(obj.typeclass, "at_post_puppet")()
TypeError: at_post_puppet() takes exactly 3 arguments (1 given)

Above traceback is from an untrapped error. Please file a bug report.
Command '@reload' is not available. Type "help" for help.
Server restarting ...
... Server restarted.
Traceback (most recent call last):
  File "C:\mushdev\evennia\src\commands\cmdhandler.py", line 412, in cmdhandler
    ret = yield cmd.func()
  File "C:\mushdev\evennia\game\gamesrc\commands\player_cmds.py", line 122, in func
    self.player.puppet_object(self.sessid, char[0], normal_mode=True)
  File "C:\mushdev\evennia\src\players\models.py", line 335, in puppet_object
    _GA(obj.typeclass, "at_post_puppet")()
TypeError: at_post_puppet() takes at least 3 arguments (1 given)

--
--
You received this message because you are subscribed to the "Evennia" MU* server mailing list.
To post to this group, send email to eve...@googlegroups.com (or use the web interface).
To unsubscribe from this group, send email to evennia+u...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/evennia?hl=en

---
You received this message because you are subscribed to a topic in the Google Groups "Evennia" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/evennia/z7wOmN_Wtl8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to evennia+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Griatch Art

unread,
Feb 5, 2015, 1:03:35 PM2/5/15
to eve...@googlegroups.com
Hi,

As seen in the default Object definition:

def at_post_puppet(self):
    ...

This is called all the time as part of doing @ic/@ooc (on the character it is responsible for the "You become ..." messages etc), so there is nothing wrong with the call per se. The hook does not exist anywhere but on the Object class so there cannot be a confusion there. So did you correctly add the hook to your own object class? And did you reload the server after you set the right number of arguments?
.
Griatch

Marcus Bell

unread,
Feb 5, 2015, 2:52:03 PM2/5/15
to eve...@googlegroups.com
It works as expected if I call @ooc from the session, like this: self.session.execute_cmd("@ooc")
That allows me to hook the post_puppet but now the code is dependent on using @ooc... I don't want to hang game mechanics on default commands. In fact, I want to replace or eliminate as many as possible and have those that remain be context sensitive, eg. having the character maintenance commands go away when playing a character and reappear when out of character. 

Do you know of a good Python IDE for Windows? It would really help to be able to step through code while executing instead of guessing what is happening.




Kelketek Rritaa

unread,
Feb 5, 2015, 2:52:53 PM2/5/15
to eve...@googlegroups.com
Check out PyCharm. It has a very nice step-through debugging interface.

You received this message because you are subscribed to the Google Groups "Evennia" group.
To unsubscribe from this group and stop receiving emails from it, send an email to evennia+u...@googlegroups.com.

Marcus Bell

unread,
Feb 5, 2015, 3:09:49 PM2/5/15
to eve...@googlegroups.com
Oh my god, yes, that is much better!

Griatch Art

unread,
Feb 6, 2015, 3:48:05 AM2/6/15
to eve...@googlegroups.com
Hi,

Please look at the @ooc command's source code and you will find this is a wrong assumption. No hooks in Evennia depend solely on a default command - default commands are intended to be replaced. The at_pre/post_unpuppet() hooks are called by the PlayerDB.unpuppet_object(sessid) method as part of the unpuppeting process. @ooc calls this method on its caller (which is a player) - it must do so in order to unpuppet from the character. But you can call unpuppet_object(sessid) from anywhere in your code, there is no need to go via @ooc.
.
Griatch
Reply all
Reply to author
Forward
0 new messages