NPCs 表示聽話¶
> say hi
You say, "hi"
The troll under the bridge answers, "well, well. Hello."
本指南解釋如何製作一個 NPC 對角色在當前位置說話做出反應。此原則適用於其他情況,例如敵人加入戰鬥或對角色拔出武器做出反應。
# mygame/typeclasses/npc.py
from characters import Character
class Npc(Character):
"""
A NPC typeclass which extends the character class.
"""
def at_heard_say(self, message, from_obj):
"""
A simple listener and response. This makes it easy to change for
subclasses of NPCs reacting differently to says.
"""
# message will be on the form `<Person> says, "say_text"`
# we want to get only say_text without the quotes and any spaces
message = message.split('says, ')[1].strip(' "')
# we'll make use of this in .msg() below
return f"{from_obj} said: '{message}'"
我們加入一個簡單的方法 at_heard_say 來格式化它聽到的內容。我們假設輸入的訊息採用 Someone says, "Hello" 的形式,並且我們確保在該範例中僅獲取 Hello。
我們實際上還沒有呼叫at_heard_say。接下來我們會處理這個問題。
當房間裡有人對這個 NPC 說話時,它的 msg 方法將會被呼叫。我們將修改
NPCs .msg 捕獲方法表示 NPC 可以回應。
1# mygame/typeclasses/npc.py
2
3from characters import Character
4class Npc(Character):
5
6 # [at_heard_say() goes here]
7
8 def msg(self, text=None, from_obj=None, **kwargs):
9 "Custom msg() method reacting to say."
10
11 if from_obj != self:
12 # make sure to not repeat what we ourselves said or we'll create a loop
13 try:
14 # if text comes from a say, `text` is `('say_text', {'type': 'say'})`
15 say_text, is_say = text[0], text[1]['type'] == 'say'
16 except Exception:
17 is_say = False
18 if is_say:
19 # First get the response (if any)
20 response = self.at_heard_say(say_text, from_obj)
21 # If there is a response
22 if response != None:
23 # speak ourselves, using the return
24 self.execute_cmd(f"say {response}")
25
26 # this is needed if anyone ever puppets this NPC - without it you would never
27 # get any feedback from the server (not even the results of look)
28 super().msg(text=text, from_obj=from_obj, **kwargs)
因此,如果 NPC 獲得發言權,並且該發言權不是來自 NPC 本身,它將使用
at_heard_say 鉤子。上面的例子中有一些值得注意的地方:
第 15 行
text輸入可以採用多種不同的形式,取決於呼叫msg的位置。如果您檢視“say”指令的程式碼,您會發現它將使用("Hello", {"type": "say"})呼叫.msg。 我們利用這些知識來確定這是否來自say。第 24 行:我們使用
execute_cmd觸發 NPCs 自己的say指令。這是有效的,因為 NPC 實際上是DefaultCharacter的子級 - 所以它上面有CharacterCmdSet! 通常你應該謹慎使用execute_cmd;直接呼叫指令使用的實際程式碼通常更有效。對於本教學,呼叫指令的編寫時間較短,同時確保呼叫所有掛鉤第26行:注意最後關於
super的註解。這也將觸發“預設”msg(在父類別中)。只要沒有人傀儡NPC(@ic <npcname>),這並不是真的必要,但明智的做法是留在那兒,因為如果msg()從不向他們返回任何東西,傀儡玩家將完全失明!
現在已經完成了,讓我們建立一個 NPC 並看看它本身有什麼含義。
reload
create/drop Guild Master:npc.Npc
(您也可以將路徑指定為 typeclasses.npc.Npc,但 Evennia 將檢視 typeclasses
自動資料夾,所以這有點短)。
> say hi
You say, "hi"
Guild Master says, "Anna said: 'hi'"
什錦筆記¶
有很多方法可以實現這種功能。覆蓋的替代範例
msg 將改為修改 Character 上的 at_say 掛鉤。它可以檢測到它是
傳送到 NPC 並直接呼叫 at_heard_say 掛鉤。
雖然教學解決方案的優點是僅包含在 NPC 類別中, 將此與使用 Character 類別結合可以更直接地控制 NPC 將如何反應。選擇哪種方式取決於特定遊戲的設計要求。