默认出口错误信息


Evennia允许给出口任意起名。命令“厨房”、“跳出窗外”和“北方”都是有效的。一个出口事实上由两部分构成:出口对象和它存储的出口命令。出口命令是出口对象的别名,它们有相同的关键字,这就是为什么写下在房间中看到的出口名就可以穿过它。

键入一个不存在的出口等于是尝试执行一个不存在的命令;Evennia并不认为它们有不同:
 > jump out the window
 Command 'jump out the window' is not available. Type "help" for help.
然而许多游戏并不需要这种类型的自由度。它们仅把基本方向定义为有效的出口名称(Evennia的@tunnel命令同样支持该功能)。这种情况下,报错看起来就有点不合逻辑了:
 > west
 Command 'west' is not available. Maybe you meant "@set" or "@reset"?
因为在这类游戏中,我们明确知道西方是出口,如果报错只简单告诉我们不可达就合理多了。

添加默认报错命令

为解决该问题,你得知道如何编写和添加新命令。你要做的是为游戏支持的各个方向创建新命令。本例我们所做的只是显示一个报错,当然你可以考虑更高级应用。把这些命令添加到默认命令集中。这里有个添加它们的例子:
    from evennia import default_cmds

    class CmdExitError(default_cmds.MuxCommand):
        "Parent class for all exit-errors."
        locks = "cmd:all()"
        auto_help = False
        def func(self):
            "returns the error"
            self.caller.msg("You cannot move in that direction.")   

    class CmdExitErrorNorth(CmdExitError):
        key = "north"
        aliases = ["n"]

    class CmdExitErrorEast(CmdExitError):
        key = "east"
        aliases = ["e"]

    class CmdExitErrorSouth(CmdExitError):
        key = "south"
        aliases = ["s"]

    class CmdExitErrorWest(CmdExitError):
        key = "west"
        aliases = ["w"]
确保把它们添加加到 mygame/commands/default_cmdsets.py 的 CharacterCmdSet 类中。此后每当你位于一个有出口对象(比如说“北方”)的房间中,正确的出口命令将重载默认的报错命令“北方”。但是假如你输入的方向无法匹配任何出口,你仍然是在执行默认的报错命令:
 > east
 You cannot move in that direction.
出口系统的更进一步扩展(包括控制出口命令自身的创建方式)可通过直接修改出口类型类实现。

备注

那么以上我们为什么不创建一个单一的报错命令呢?比如说这样的:
     class CmdExitError(default_cmds.MuxCommand):
        "Handles all exit-errors."
        key = "error_cmd"
        aliases = ["north", "n", 
                   "east", "e",
                   "south", "s",
                   "west", "w"]
         #[...]
答案是它不会起作用,而且理解这一点非常重要,防止你在处理命令和命令集时陷入混乱。

不起作用的原因是Evennia的命令系统在比较命令时既考虑关键字又考虑别名。就命令集合并系统而言,只要二者任何一个匹配成功,两条命令就被认为完全相同。

因此只要房间中完全没有出口,上述例子就正常工作。但是如果我们进入有“北方”出口的房间会发生什么呢?出口的命令集会与默认集合并,由于别名匹配成功,系统认为我们的 CmdExitError 命令与默认出口命令完全相同,因此被重载(默认出口命令被恰当地预设为一个高优先级)。结果是该出口可以正常穿过,但其余方向的报错无法显示,因为单一报错命令彻底被它所匹配的“北方”命令给重载了。