手工配置色彩


这是一个自定义角色对象的小教程,允许用户启用和关闭ANSI色彩解析。

在建造者指南的色彩页面,你可以学到如何利用特殊标记为游戏添加色彩。色彩增强了游戏体验,但并非所有用户都需要它。比如用户的客户端不支持,或者需要借助屏幕阅读器玩游戏的各位视力缺陷者。此外,尽管Evennia通常会自动检测客户端是否支持色彩,它可能误判。由确信色彩能正常工作的用户手工启用它,会是个不错的特色。

因此下面给出如何允许相关用户移除色彩。这基本上意味着实现一个简单的角色配置系统。基本步骤如下:
  1. 从Evennia默认类继承并定义你自己的默认角色类型类。
  2. 为角色设置一个控制开/关状态的属性。
  3. 将你的自定义角色类设为新用户的默认类。
  4. 重载类型类的 msg() 方法并修改它使用标记的方式。
  5. 创建一个自定义命令,允许用户改变设置。

设置自定义类型类

在 mygame/typeclasses/objects 创建一个新模块,起个名字,比如 mycharacter.py。

在你的新模块中创建一个继承自 evennia.DefaultCharacter 的新类型类
    from ev import Character

    class ColourableCharacter(Character):
        at_object_creation(self):              
            # set a colour config value
            self.db.config_colour = True 
以上我们利用属性值设置了一个简单的配置值。

让我们确保新角色按照该类型创建。编辑你的 mygame/server/conf/settings.py 文件并添加/修改 BASE_CHARACTER_TYPECLASS 指向你的新角色类。注意到这仅仅影响角色,而非已创建的角色。你需要使用 @typeclass命令将已创建的角色转换为新类型类。(话虽如此,先找个二流角色试试,确保一切正常——你不想把root账号鼓捣坏了吧!)
 @typeclass/reset/force Bob = mycharacter.ColourableCharacter
@typeclass 改变Bob的类型类并把生成期的全部钩子函数重新执行一遍。开关 /reset 把全部属性和属性值恢复到新类型类的默认值——在本例中这很有用,避免最后弄出一个“掺杂”着新旧类型类属性的对象。编辑类型类并更新对象时可能需要 /force 开关,尽管当前类型类名称并未改变。

重载 msg()方法

接下来我们需要重载 msg() 方法。要做的是在调用主函数前检查配置值。msg 方法的调用原型见 evennia/objects/objects.py,看起来像这样:
    msg(self, text=None, from_obj=None, session=None, **kwargs):

只要我们在自定义对象上定义一个同名方法且保持数量相等的实参/关键字,就重载该原型了。它看起来就是这样:
    class ColourableCharacter(Character):
        # [...]
        msg(self, text=None, from_obj=None, session=None, **kwargs):
            "our custom msg()"        
            if self.db.config_colour is not None: # this would mean it was not set
                kwargs["ansi"] = self.db.config_colour
            super(MyCharacter, self).msg(text=text, from_obj=from_obj, session=session, **kwargs)
以上我们创建了一个自定义版本的 msg() 方法。当设置属性值时,它添加“ansi”实参关键字,然后照常调用父对象的 msg()。不论Evennia认为客户端支持什么,这个关键字将重载它。(因此即使你的客户端支持色彩,你也能关闭它)。需要 @reload 使改变生效。

这就成了!只要改变属性值 config_colour 为 False,你的用户将不会再看到任何色彩。作为超级用户(假定你使用 ColourableCharacter 类型类),可以通过 @py 命令测试:
 @py self.db.config_colour = False

自定义色彩配置命令

完整起见,让我们添加一个自定义命令,这样用户需要时能自己关闭色彩显示。

在 mygame/commands 路径创建一个新文件,比如叫 configcmds.py(很可能后续你还想添加其他配置命令)。也可以复制/重命名命令模板:
    from evennia import default_cmds

    class CmdConfigColour(default_cmds.MuxCommand):
        """
        Configures your colour

        Usage:
          @setcolour on|off

        This turns ansii-colours on/off. 
        Default is on. 
        """

        key = "@setcolour"
        aliases = ["@setcolor"]

        def func(self):
            "Implements the command" 
            if not self.args or not self.args in ("on", "off"):
                self.caller.msg("Usage: @setcolour on|off") 
                return
            if self.args == "on":
                self.caller.db.config_colour = True
            else:
                self.caller.db.config_colour = False  
            self.caller.msg("Colour was turned %s." % self.args)
最后,为了让该命令对用户可见,我们把它添加到 mygame/commands/default_cmdsets.py 中的 CharacterCmdSet 默认类并重载服务器。

更多色彩

除了ANSI色彩,Evennia还支持Xterm256色彩(见色彩)。msg() 方法支持 xterm256 关键字来手动激活/撤销 xterm256。应该不难把上例扩展到支持用户自定义 xterm256,不论Evennia认为他们的客户端是否支持。

为更好地理解 msg() 如何借助关键字工作,你可以用超级用户运行以下指令:
@py self.msg("|123Dark blue with xterm256, bright blue with ANSI", xterm256=True)
@py self.msg("|gThis should be uncoloured", nomarkup=True)