添加命令教程


这是与命令文档相关的快速初级教程。

假定你刚刚下载了Evennia,想试着添加一个新的命令。以下是最快的做法。


告诉Evennia到哪里寻找自定义的命令和命令集

我们要告诉Evennia你想重载默认的命令集,加上自己的新命令。
  1. 前往 game/gamesrc/commands。
  2. 那里有名为 examples 的子文件夹。将文件 examples/command.py 和 examples/cmdset.py 复制到当前目录(game/gamesrc/commands)。你可以按自己的意愿重命名它们,但在本例中我们假定你没有这么做。
  3. 编辑 game/settings.py,添加以下内容:
    CMDSET_CHARACTER="game.gamesrc.commands.cmdset.CharacterCmdSet"
    

现在Evennia会在你新复制模块中的 CharacterCmdSet 类里搜索默认的命令。你只需要这样做一次。


创建自定义命令

  1. 编辑你新复制的 game/gamesrc/commands/command.py。该模板已经导入你所需的所有东西了。
  2. 在 command.py 中创建一个继承自 MuxCommand 的新类。在这个例子中我们把它命名为 CmdEcho 。
  3. 将起好的命令名字,如 echo,赋给类成员变量 key。
  4. 给命令的 locks 属性设置合适的锁字符串。如果你无法确定该怎么设置,可以用“cmd:all()”。
  5. 给你的类添加有用的文档字符串,这会成为该命令的帮助条目。
  6. 定义类方法 func() 来执行事务。以下是完整的例子。
        # file game/gamesrc/commands/command.py
        #[...]
        from ev import default_cmds
        class CmdEcho(default_cmds.MuxCommand):
            """
            Simple command example

            Usage: 
              echo 

            This command simply echoes text back to the caller.
            """

            key = "echo"
            locks = "cmd:all()"

            def func(self):
                "This actually does things" 
                if not self.args:
                    self.caller.msg("You didn't enter anything!")           
                else:
                    self.caller.msg("You gave the string: '%s'" % self.args)


将命令添加到默认命令集

命令在加入命令集之前是不可用的。在这个例子中,我们要用最简单的方法,把它添加到已经准备好了的默认的角色命令集中。
  1. 编辑你新复制的 game/gamesrc/commands/cmdset.py 。
  2. 在这个复制的模块中,你会发现 DefaultCmdSet 类已经为你导入好了。用 from game.gamesrc.commands.command import CmdEcho 将你的新命令也导入进来。
  3. 在 CharacterCmdSet 的 at_cmdset_creation 方法中添加一行 self.add(CmdEcho()) (模板会告诉你添加在哪里)。现在,它看上去差不多是这样的:
            # file gamesrc/commands/cmdset.py
            #[...]
            from game.gamesrc.commands.command import CmdEcho
            #[...]
            class CharacterCmdSet(default_cmds.CharacterCmdSet):
    
                key = DefaultCharacter
    
                def at_cmdset_creation(self):
    
                    # this first adds all default commands
                    super(DefaultSet, self).at_cmdset_creation()
    
                    # all commands added after this point will extend or 
                    # overwrite the default commands.       
                    self.add(CmdEcho())
    
  4. 重新启动Evennia(在游戏中执行 @reload),没有人会因此断开连接。现在你应该可以在游戏中使用新的 echo 命令了。使用 help echo 可以查看该命令的文档。

如果你遇到了问题,一定要检查日志中的错误消息(很可能是因为在你的命令定义中存在语法错误)。

之后如果再要在默认命令集中添加新命令,就只需要创建功能函数,然后将它添加到命令集的相同位置就行了。如果你想重载现有的默认命令(如 look 或 get),只需要加入新命令并将 key 设成与旧命令一样,它会自动覆盖旧命令的。但要记住,你必须用 @reload 重启服务器,然后才能看到变化。

关于定义命令和使用命令集的更多方式和更详细信息,请见命令文档


给特定对象类型添加命令

其实你不必扩展 CharacterCmdSet,前面给出的只是最简单的例子。命令集系统的通用性很强,你可以创建自己的命令集并将它添加到你想加的对象上(它们与现有命令集的合并方式在命令集文档中有详细描述)。
    # file gamesrc/commands/cmdset.py
    #[...]
    from game.gamesrc.commands.command import CmdEcho
    #[...]
    class MyCmdSet(default_cmds.CmdSet):

        key = MyCmdSet

        def at_cmdset_creation(self):     
            self.add(CmdEcho())

现在你只需要将它添加到对象上。想要测试,(作为超级用户)你可以这么做
 @py self.cmdset.add("cmdset.MyCmdSet")
这会将命令集(和echo命令)添加到你自己身上,这样你就可以测试它了。但这不是永久性的,如果你执行了 @reload 合并上去的命令就会消失。你可以在调用 cmdset.add 时添加关键字参数 permanent=True。这可以让新合并的命令集永久添加到指定对象上,而不会影响该类型的其他对象,这通常是你所希望的。

要确保所有新建对象都合并上新的命令集,可以把对 cmdset.add 的调用添加到你自定义类型类的 at_object_creation 方法中:
    from ev import Object
    class MyObject(Object):

        def at_object_creation(self):
            "called when the object is first created"
            self.cmdset.add("cmdset.MyCmdSet")

现在该类型类的所有新对象都会自动带上这个命令集了。

注:这个 at_object_creation 方法只会在对象初次创建时调用一次。也就是说,如果在数据库中已经有了该类型类的对象,那这些旧对象的初始化方式和新对象是不一样的。有许多办法可以更新它们,由于这只是一次性的更新,通常你可以简单地通过循环更新它们。作为超级用户,你可以这样做:
 @py [obj.cmdset.add("cmdset.MyCmdSet") for obj in 
    ev.managers.typeclass_search("game.gamesrc.objects.objects.mytypeclass.MyTypeClass")]

这会遍历数据库中所有具有指定类型类的对象,逐个添加新的命令集。好消息是,只有在添加新命令集时才需要这么做,如果只是增加新的命令,你只需要将命令添加到命令集的 at_cmdset_creation 方法中并执 @reload 就行了。