傳回缺少退出時的自訂錯誤¶
> north
Ouch! You bump into a wall!
> out
But you are already outside ...?
Evennia 允許出口具有任何名稱。指令“kitchen”以及“jump out of the window”或“north”都是有效的出口名稱。退出實際上由兩部分組成:退出物件 和 儲存在所述退出物件上的退出指令。該指令與以下指令具有相同的金鑰和別名 exit-object,這就是為什麼你可以看到房間裡的出口,只需寫下它的名字就可以遍歷它。
因此,如果您嘗試輸入不存在的退出的名稱,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"?
由於我們對於我們的特定遊戲“知道”西是出口方向,因此如果錯誤訊息只是告訴我們不能去那裡,那就更好了。
> west
You cannot move west.
做到這一點的方法是給 Evennia 一個_alternative_ Command,以便在房間中找不到退出指令時使用。有關將新指令新增到 Evennia 的過程的詳細資訊,請參閱新增指令。
在這個例子中,我們只會回顯一條錯誤訊息,但你可以做任何事情(如果你撞到牆上,也許你會失去健康?)
# for example in a file mygame/commands/movecommands.py
from evennia import default_cmds, CmdSet
class CmdExitError(default_cmds.MuxCommand):
"""Parent class for all exit-errors."""
locks = "cmd:all()"
arg_regex = r"\s|$"
auto_help = False
def func(self):
"""Returns error based on key"""
self.caller.msg(f"You cannot move {self.key}.")
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"]
# you could add each command on its own to the default cmdset,
# but putting them all in a cmdset here allows you to
# just add this and makes it easier to expand with more
# exit-errors in the future
class MovementFailCmdSet(CmdSet):
def at_cmdset_creation(self):
self.add(CmdExitErrorNorth())
self.add(CmdExitErrorEast())
self.add(CmdExitErrorWest())
self.add(CmdExitErrorSouth())
我們將指令打包在一個新的小cmdset中;如果我們將其新增至 CharacterCmdSet 中,則稍後可以將更多錯誤新增至 MovementFailCmdSet 中,而無需在兩個位置變更程式碼。
# in mygame/commands/default_cmdsets.py
from commands import movecommands
# [...]
class CharacterCmdSet(default_cmds.CharacterCmdSet):
# [...]
def at_cmdset_creation(self):
# [...]
# this adds all the commands at once
self.add(movecommands.MovementFailCmdSet)
reload 伺服器。今後發生的情況是,如果您在一個帶有 Exit 物件的房間中(假設它是“北”),正確的退出指令將_overload_您的錯誤指令(也稱為“北”)。但是,如果您輸入方向而沒有符合的出口,您將退回到預設的錯誤指令:
> east
You cannot move east.
退出系統的進一步擴充套件(包括操作 Exit 指令本身的建立方式)可以透過直接修改 Exit typeclass 來完成。
為什麼不是一個指令?¶
那為什麼我們不在上面建立一個錯誤指令呢?像這樣的東西:
class CmdExitError(default_cmds.MuxCommand):
"Handles all exit-errors."
key = "error_cmd"
aliases = ["north", "n",
"east", "e",
"south", "s",
"west", "w"]
#[...]
這不會按照我們想要的方式工作。瞭解原因很重要。
Evennia 的指令系統 按鍵和/或別名比較指令。如果_任何_鍵或別名匹配,則這兩個指令被視為_相同_。當 cmdsets 合併時,優先順序將決定這些「相同」指令中的哪個指令取代哪個指令。
因此,只要房間裡沒有出口,上面的例子就可以正常運作。但當我們進入一個出口為「北」的房間時,它的退出指令(具有更高的優先順序)將覆蓋單一CmdExitError及其別名「北」。因此 CmdExitError 將消失,而「向北」將起作用,我們將再次收到其他方向的正常「指令無法識別」錯誤。