XYZgrid

Gratch 2021 的貢獻

將 Evennia 的遊戲世界放置在 xy(z 是不同的地圖)座標網格上。 網格是透過繪製和解析 2D ASCII 地圖在外部建立和維護的, 包括傳送、地圖轉換和幫助尋路的特殊標記。 支援在每個地圖上非常快速的最短路徑尋路。還包括一個 快速檢視功能,僅檢視距離您有限的步數 目前位置(對於將網格顯示為遊戲中的更新地圖很有用)。

網格管理是在遊戲外使用新的evennia啟動器完成的 選項。

範例

#-#-#-#   #
|  /      d
#-#       |   #
   \      u   |\
o---#-----#---+-#-#
|         ^   |/
|         |   #
v         |    \
#-#-#-#-#-# #---#
    |x|x|     /
    #-#-#    #-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                     #---#
                                    /
                                   @-
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Dungeon Entrance
To the east, a narrow opening leads into darkness.
Exits: northeast and east

安裝

  1. XYZGrid 需要 scipy 函式庫。最簡單的就是獲得“額外” Evennia 的依賴關係

    pip install evennia[extra]
    

如果您使用git安裝,還可以

   (cd to evennia/ folder)
   pip install --upgrade -e .[extra]

這將安裝 Evennia 的所有可選要求。 2. 匯入並將 evennia.contrib.grid.xyzgrid.commands.XYZGridCmdSet 新增到 CharacterCmdset cmdset 在 mygame/commands.default_cmds.py 中。重新載入 伺服器。這使得 mapgoto/path 和修改後的 teleportopen 遊戲中可用指令。

  1. 編輯mygame/server/conf/settings.py並新增

    EXTRA_LAUNCHER_COMMANDS['xyzgrid'] = 'evennia.contrib.grid.xyzgrid.launchcmd.xyzcommand'
    PROTOTYPE_MODULES += ['evennia.contrib.grid.xyzgrid.prototypes']
    

這將新增在 evennia xyzgrid <option> 上輸入的新功能 指令列。 它還將製作 xyz_roomxyz_exit 原型 在生成網格時可用作原型父母。

  1. 執行 evennia xyzgrid help 以獲取可用選項。

  2. (可選):預設情況下,xyzgrid 將僅產生基於模組的 [原型]。這是一種最佳化,通常是有意義的 因為無論如何,網格完全是在遊戲之外定義的。如果你想 也利用遊戲中(db-)建立的原型,新增 XYZGRID_USE_DB_PROTOTYPES = True 到設定。

概述

網格contrib由多個元件組成。

  1. XYMap - 該類別使用特殊的 Map strings 解析模組 和 Map legends 到一個 Python 物件中。它有尋路助手和 視覺範圍處理。

  2. XYZGrid - 這是一個單例 Script 儲存遊戲中的所有XYMaps。它是管理“網格”的中心點 遊戲的。

  3. XYZRoomXYZExit 是使用的自訂 typeclasses Tags 知道它們位於哪個 X、Y、Z 座標。 XYZGrid 是 抽象化直到它被用來_spawn_這些資料庫實體到 您可以在遊戲中實際互動的東西。 XYZRoom typeclass 正在使用其 return_appearance 掛鉤來顯示遊戲中的地圖。

  4. 已新增自訂_指令_用於與XYZ-感知位置進行互動。

  5. 新的自訂_啟動器指令_,evennia xyzgrid <options> 用於 從終端管理網格(無需登入遊戲)。

我們將透過一個範例開始探索這些元件。

第一個範例用法

安裝後,從指令列執行以下操作(其中 evennia 指令可用):

$ evennia xyzgrid init

使用evennia xyzgrid help檢視所有選項) 如果尚不存在,這將建立一個新的 XYZGrid Scriptevennia xyzgrid 僅為此 contrib 新增的自訂啟動選項。

xyzgrid-contrib 有完整的網格範例。讓我們新增它:

$ evennia xyzgrid add evennia.contrib.grid.xyzgrid.example

現在您可以在網格上列出地圖:

$ evennia xyzgrid list

您會發現新增了兩張新地圖。你可以找到很多額外的資訊 使用 show 子指令檢視每個地圖:

$ evennia xyzgrid show "the large tree"
$ evennia xyzgrid show "the small cave"

如果您想檢視網格的程式碼,請開啟 evennia/contrib/grid/xyzgrid/example.py。 (我們將在後面的部分中解釋詳細資訊)。

到目前為止,網格是“抽象的”,並且在遊戲中沒有實際存在。讓我們 產生實際的房間/出口。這需要一些時間。

$ evennia xyzgrid spawn

這將採用與每個地圖的_地圖圖例_一起儲存的原型並使用它 在那裡建造XYZ-感知房間。它還會解析所有連結以做出合適的 在位置之間退出。如果您修改過,您應該重新執行此指令 網格的佈局/原型。多次執行它是安全的。

$ evennia reload

(如果伺服器未執行,則為 evennia start)。這很重要 每次產生操作,因為 evennia xyzgrid 在 常規 evennia 程式。重新載入可確保重新整理所有快取。

現在您可以登入伺服器了。您應該可以使用一些新指令。

teleport (3,0,the large tree)

teleport 指令現在接受可選的(X、Y、Z)座標。傳送 房間名稱或 #dbref 的作用仍然相同。這會將你傳送到 網格。您應該會看到地圖顯示。嘗試四處走走。

map

這個新的僅限建構器的指令以完整形式顯示當前地圖(也 顯示使用者通常不可見的「不可見」標記。

teleport (3, 0)

一旦你進入一個網格房間,你可以傳送到另一個網格房間_在同一房間 map_ 不指定 Z 座標/地圖名稱。

您可以使用 open 退出回到“非網格”,但請記住您 不得使用基本方向來執行此操作 - 如果這樣做,evennia xyzgrid spawn 下次執行它時可能會刪除它。

open To limbo;limbo = #2
limbo

你回到了 Limbo(它不知道關於 XYZ 座標的任何資訊)。你 但是可以將永久連結返回到網格地圖:

open To grid;grid = (3,0,the large tree)
grid

這就是將非網格位置和網格位置連結在一起的方式。例如你可以 以這種方式將房屋嵌入網格“內部”。

(3,0,the large tree) 是「地下城入口」。如果你向東走你會 _過渡_進入「小洞穴」地圖。這是一個小型的地下迷宮 能見度有限。再次回到外面(回到「大樹」地圖)。

path view

這找到了通往“A beautiful view”房間的最短路徑,該房間位於大房間的高處 樹。如果你的用戶端有顏色,你應該會看到路徑的起點 以黃色顯示。

goto view

這將開始自動帶您前往檢視。在路上你們都會進步 進入樹並穿越地圖內的傳送器。單獨使用 goto 中止自動行走。

完成探索後,再次開啟終端(在遊戲外)並 刪除所有內容:

$ evennia xyzgrid delete

系統將要求您確認刪除網格並解除安裝 XYZGrid Script。之後重新載入伺服器。如果你在一張地圖上 刪除後,您將被移回您的家庭位置。

定義XYMap

對於適合傳遞到 evennia xyzgrid add <module> 的模組, 模組必須包含以下變數之一:

  • XYMAP_DATA - 包含完全定義 XYMap 的資料的字典

  • XYMAP_DATA_LIST - XYMAP_DATA 字典的列表。如果存在,則需要 優先。這允許在一個模組中儲存多個地圖。

XYMAP_DATA 字典有以下形式:

XYMAP_DATA = {
    "zcoord": <str>
    "map": <str>,
    "legend": <dict, optional>,
    "prototypes": <dict, optional>
    "options": <dict, optional>
}

  • "zcoord" (str):地圖的 Z 座標/地圖名稱。

  • "map" (str):描述地圖拓樸的_地圖字串_。

  • "legend"(字典,可選):將地圖上的每個符號對應到Python程式碼。這 dict 可以省略或僅部分填充 - 任何未指定的符號都會 而是使用 contrib 中的預設圖例。

  • "prototypes"(字典,可選):這是對映地圖座標的字典 自訂原型覆蓋。當地圖生成到 實際的房間/出口。

  • "options"(字典,可選):這些被傳遞到return_appearance 房間的掛鉤並允許自訂地圖的顯示方式, 尋路應該如何進行等等。

這是整個設定的最小範例:

# In, say, a module gamedir/world/mymap.py

MAPSTR = r"""

+ 0 1 2

2 #-#-#
     /
1 #-#
  |  \
0 #---#

+ 0 1 2


"""
# use only defaults
LEGEND = {}

# tweak only one room. The 'xyz_room/exit' parents are made available
# by adding the xyzgrid prototypes to settings during installation.
# the '*' are wildcards and allows for giving defaults on this map.
PROTOTYPES = {
    (0, 0): {
        "prototype_parent": "xyz_room",
        "key": "A nice glade",
        "desc": "Sun shines through the branches above.",
    },
    (0, 0, 'e'): {
        "prototype_parent": "xyz_exit",
        "desc": "A quiet path through the foilage",
    },
    ('*', '*'): {
        "prototype_parent": "xyz_room",
        "key": "In a bright forest",
        "desc": "There is green all around.",
    },
    ('*', '*', '*'): {
        "prototype_parent": "xyz_exit",
        "desc": "The path leads further into the forest.",
    },
}

# collect all info for this one map
XYMAP_DATA = {
    "zcoord": "mymap",  # important!
    "map": MAPSTR,
    "legend": LEGEND,
    "prototypes": PROTOTYPES,
    "options": {}
}

# this can be skipped if there is only one map in module
XYMAP_DATA_LIST = [
    XYMAP_DATA
]

上面的地圖將會被加入到網格中

$ evennia xyzgrid add world.mymap

在下面的部分中,我們將依次討論每個元件。

Z座標

網格上的每個 XYMap 都有一個 Z 座標,通常可以視為 地圖的名稱。 Z 座標可以是字串或整數,且必須 在整個網格中是唯一的。它作為鍵“zcoord”新增到XYMAP_DATA

大多數使用者只想將每張地圖視為一個位置,並為其命名 “Z 座標”,例如 Dungeon of DoomThe ice queen's palace 或“城市” 布萊克黑文`。但如果您願意,也可以將其命名為 -1, 0, 1, 2, 3。

請注意,在中搜尋 Zcoord 不區分大小寫

尋路僅在每個 XYMap 內發生(上/下通常是透過移動來「偽造」的) 橫向到 XY 平面的新區域)。

真正的 3D 地圖

即使是最硬派的科幻太空遊戲,也可以考慮堅持 2D 運動。對玩家來說,用圖形來視覺化 3D 體積已經夠困難的了。 在文字中就更難了。

也就是說,如果您想建立一個真正的 X、Y、Z 3D 座標系(其中 您可以從每個點向上/向下移動),您也可以這樣做。

這contrib提供了一個範例指令commands.CmdFlyAndDive,該指令為玩家提供了 能夠使用 flydive 在 Z 之間直接向上/向下移動 座標。只需將其(或其 cmdset commands.XYZGridFlyDiveCmdSet)新增到您的 角色cmdset並重新載入來嘗試。

為了使飛行/潛水工作,您需要將網格建構成 XY-網格地圖的“堆疊” 並透過它們的 Z 座標作為整數命名它們。飛行/俯衝動作將 僅當上方/下方確實有匹配的房間時才有效。

請注意,由於尋路僅在每個 XY 地圖內有效,因此玩家不會 能夠在自動行走中包含飛行/潛水 - 這始終是手冊 行動。

作為範例,我們假設座標 (1, 1, -3) 是通往地面的深井底部(0 級)

LEVEL_MINUS_3 = r"""
+ 0 1

1   #
    |
0 #-#

+ 0 1
"""

LEVEL_MINUS_2 = r"""
+ 0 1

1   #

0

+ 0 1
"""

LEVEL_MINUS_1 = r"""
+ 0 1

1   #

0

+ 0 1
"""

LEVEL_0 = r"""
+ 0 1

1 #-#
  |x|
0 #-#

+ 0 1
"""

XYMAP_DATA_LIST = [
    {"zcoord": -3, "map": LEVEL_MINUS_3},
    {"zcoord": -2, "map": LEVEL_MINUS_2},
    {"zcoord": -1, "map": LEVEL_MINUS_1},
    {"zcoord": 0, "map": LEVEL_0},
]

在此範例中,如果我們在 (1, 1, -3) 到達井底,我們 fly 直上三層,直到到達轉角處的 (1, 1, 0) 某種開放領域。

我們可以從(1, 1, 0)跳下去。在預設實作中,您必須 dive 3 次 追根究底。如果你願意,你可以調整指令,這樣你 自動落到底部並受到傷害等。

我們無法從任何其他 XY 位置飛行/俯衝/俯衝,因為該位置沒有開放房間 相鄰的 Z 座標。

地圖字串

新地圖的建立從_地圖字串_開始。這可以讓你“畫畫” 您的地圖,描述房間在 X、Y 座標系中的位置。 它透過鍵“map”新增到XYMAP_DATA

MAPSTR = r"""

+ 0 1 2

2 #-#-#
     /
1 #-#
  |  \
0 #---#

+ 0 1 2

"""

在座標軸上,只有兩個 + 是有意義的 - 數字是 可選,所以這是等效的:

MAPSTR = r"""

+

  #-#-#
     /
  #-#
  | \
  #---#

+

"""

儘管它是可選的,但強烈建議您新增數字 你的斧頭——如果只是為了你自己的理智。

座標區開始_向右兩格_和_兩格 下面/上面_強制+標誌(標記地圖區域的角落)。 Origo (0,0) 位於左下角(因此 X 座標向右增加, Y 座標向頂部增加)。高度/寬度沒有限制 地圖可以,但是將一個大世界分成多個地圖可以更容易 組織。

網格上的位置很重要。每隔_秒_放置完整座標 沿所有軸的空間。這些「完整」座標之間是 .5 座標。 請注意,遊戲中產生了 no .5 座標;它們只被使用 在地圖字串中留出空間來描述房間/節點如何相互連結。

+ 0 1 2 3 4 5

4           E
   B
3

2         D

1    C

0 A

+ 0 1 2 3 4 5
  • A 位於原點,(0, 0)(「完整」座標)

  • B 位於 (0.5, 3.5)

  • C 位於 (1.5, 1)

  • D 位於 (4, 2)(「完整」座標)。

  • E 是地圖的右上角,位於 (5, 4)(「完整」座標)

地圖字串由兩個主要的實體類別組成 - nodeslinks

  • node 通常代表遊戲中的_room_(但並非總是如此)。節點必須 _始終_放置在「完整」座標上。

  • link 描述兩個節點之間的連線。在遊戲中,連結通常是 由_exits_表示。可以放一個連結 座標空間中的任何位置(全座標和 0.5 座標)。多個 連結通常「連結」在一起,但鏈必須始終以節點結束 兩側。

即使連結鏈可能由多個步驟組成,例如 #-----#, 在遊戲中它仍然只代表一個「步驟」(e.g。你只往「東」走一次 從最左邊移動到最右邊的節點/房間)。

地圖圖例

可以有許多不同型別的_節點_和_連結_。而地圖 字串描述它們所在的位置,_地圖圖例_連線每個符號 在Python程式碼的地圖上。


LEGEND = {
    '#': xymap_legend.MapNode,
    '-': xymap_legende.EWMapLink
}

# added to XYMAP_DATA dict as 'legend': LEGEND below

圖例是可選的,圖例中未明確給出的任何符號都將 回退到預設圖例中的值如下所述

  • MapNode 是所有節點的基底類別。

  • MapLink 是所有連結的基底類別。

當解析 Map String 時,會在圖例中尋找每個找到的符號並 初始化到對應的MapNode/Link例項。

預設圖例

下面是預設的地圖圖例。 symbol 是應該放在地圖中的內容 字串。它必須始終是單一字元。 display-symbol 是什麼 在遊戲中向玩家顯示地圖時實際上是視覺化的。這可能有 顏色等。所有類別都可以在 evennia.contrib.grid.xyzgrid.xymap_legend 中找到並且 包含它們的名稱是為了方便了解要涵蓋的內容。

symbol

display-symbol

type

class

description

#

#

node

BasicMapNode

A basic node/room.

T

node

MapTransitionNode

Transition-target for links between maps (see below)

I (letter I)

#

node

InterruptMapNode

Point of interest, auto-step will always stop here (see below).

|

|

link

NSMapLink

North-South two-way

-

-

link

EWMapLink

East-West two-way

/

/

link

NESWMapLink

NorthEast-SouthWest two-way

\

\

link

SENWMapLink

NorthWest two-way

u

u

link

UpMapLink

Up, one or two-way (see below)

d

d

link

DownMapLink

Down, one or two-way (see below)

x

x

link

CrossMapLink

SW-NE and SE-NW two-way

+

+

link

PlusMapLink

Crossing N-S and E-W two-way

v

v

link

NSOneWayMapLink

North-South one-way

^

^

link

SNOneWayMapLink

South-North one-way

<

<

link

EWOneWayMapLink

East-West one-way

>

>

link

WEOneWayMapLink

West-East one-way

o

o

link

RouterMapLink

Routerlink, used for making link ‘knees’ and non-orthogonal crosses (see below)

b

(varies)

link

BlockedMapLink

Block pathfinder from using this link. Will appear as logically placed normal link (see below).

i

(varies)

link

InterruptMapLink

Interrupt-link; auto-step will never cross this link (must move manually, see below)

t

link

TeleporterMapLink

Inter-map teleporter; will teleport to same-symbol teleporter on the same map. (see below)

地圖節點

基本地圖節點(#)通常代表遊戲世界中的一個「房間」。友情連結 可以從 8 個基本方向中的任何一個連線到節點,但由於節點 必須_僅_存在於完整座標上,它們永遠不能直接出現在 彼此。

\|/
-#-
/|\

##     invalid!

所有連結或連結鏈_必須_以兩側的節點結束。

#-#-----#

#-#-----   invalid!

中斷節點

中斷節點(IInterruptMapNode)是像其他節點一樣運作的節點。 節點,除非它被認為是“興趣點”並且該節點的自動行走 goto 指令將始終在此位置停止自動步進。

#-#-我-#-#

因此,如果從左到右自動行走,自動行走將正確地繪製路徑 到最後的房間,但總是停在I節點。如果使用者_開始_於 I 房間,他們會不間斷地離開它(所以你可以 再次手動執行 goto 以恢復自動步驟)。

這個房間的用途是預測地圖未涵蓋的街區。例如 這個房間裡可能有一名警衛會逮捕你,除非你 向他們展示正確的檔案——試圖自動走過他們是很糟糕的!

預設情況下,這個節點對玩家來說就像一個普通的#

地圖轉換節點

地圖轉換 (MapTransitionNode) 在 XYMaps(a Z 座標過渡,如果你願意的話),就像從「Dungeon」地圖步行到 「城堡」地圖。與其他節點不同,MapTransitionNode 永遠不會生成 進入一個實際的房間(它沒有原型)。它只持有XYZ 座標指向另一張地圖上的某個位置。通往 to 的連結 節點將使用這些座標來建立指向那裡的出口。只有一張 連結可能會導致這種型別的節點。

TeleporterMapLink 不同,不需要匹配 MapTransitionNode 在另一張地圖上 - 過渡可以選擇傳送 玩家到另一張地圖上的_任何_有效座標。

每個 MapTransitionNode 都有一個屬性 target_map_xyz 儲存 XYZ 玩家走向這個節點時應該到達的座標。這個 必須在子類別中為每次轉換進行自訂。

如果有多個轉換,則應設定單獨的轉換類 新增了不同的地圖圖例符號:

# in your map definition module (let's say this is mapB)

from evennia.contrib.grid.xyzgrid import xymap_legend

MAPSTR = r"""

+ 0 1 2

2   #-C
    |
1 #-#-#
     \
0 A-#-#

+ 0 1 2


"""

class TransitionToMapA(xymap_legend.MapTransitionNode):
    """Transition to MapA"""
    target_map_xyz = (1, 4, "mapA")

class TransitionToMapC(xymap_legend.MapTransitionNode):
    """Transition to MapB"""
    target_map_xyz = (12, 14, "mapC")

LEGEND = {
    'A': TransitionToMapA
    'C': TransitionToMapC

}

XYMAP_DATA = {
    # ...
    "map": MAPSTR,
    "legend": LEGEND
    # ...
}

(1,0) 向西移動將到達 MapA 的 (1,4),從 (1,2) 會將您帶到 MapC 上的 (12,14)(假設這些地圖存在)。

地圖轉換總是單向的,並且可以導致 any 的座標 另一張地圖上的現有節點:

地圖1 地圖2

#-T#-#—#-#-#-#

例如,向東向 T 移動的玩家最終可能會到達從 # 開始的第 4 個位置 如果需要的話,可以在map2的左邊(即使它在視覺上沒有意義)。 無法從那裡返回map1。

若要創造雙向過渡的效果,可以設定映象 另一張地圖上的轉換節點:

城市地圖 地下城地圖

#-T T-#

上面每張地圖的轉換節點都有 target_map_xyz 指向 其他地圖的 # 節點的座標(_不是_其他 T,即不是 產生並導致出口找不到目的地!)。結果是 可以向東進入地牢,然後立即向西返回城市 跨越地圖邊界。

原型

原型 是描述如何_產生_新例項的字典 一個物體的。上面的每個_節點_和_連結_都有一個預設原型 允許 evennia xyzgrid spawn 指令將它們轉換為 XYZRoom 或分別為 XYZExit

預設原型位於evennia.contrib.grid.xyzgrid.prototypes(已新增 在安裝此 contrib) 期間,prototype_keys "xyz_room""xyz_exit" - 使用這些作為 prototype_parent 新增您自己的自訂原型。

XYMap-data 字典的 "prototypes" 鍵可讓您自訂 原型用於 XYMap 中的每個座標。坐標給出為 (X, Y) 用於節點/房間,(X, Y, direction) 用於連結/出口,其中 方向是「n」、「ne」、「e」、「se」、「s」、「sw」、「w」、「nw」、「u」或「d」之一。對於 退出,建議_不_設定 key,因為這是產生的 自動由網格產生器按預期進行(“north”,別名“n”,對於 範例)。

特殊座標是*。這充當該座標的萬用字元並且 允許您新增用於房間的“預設”原型。


MAPSTR = r"""

+ 0 1

1 #-#
   \
0 #-#

+ 0 1


"""


PROTOTYPES = {
    (0,0): {
	"prototype_parent": "xyz_room",
	"key": "End of a the tunnel",
	"desc": "This is is the end of the dark tunnel. It smells of sewage."
    },
    (0,0, 'e') : {
	"prototype_parent": "xyz_exit",
	"desc": "The tunnel continues into darkness to the east"
    },
    (1,1): {
	"prototype_parent": "xyz_room",
	"key": "Other end of the tunnel",
	"desc": The other end of the dark tunnel. It smells better here."
    }
    # defaults
    ('*', '*'): {
    	"prototype_parent": "xyz_room",
	"key": "A dark tunnel",
	"desc": "It is dark here."
    },
    ('*', '*', '*'): {
	"prototype_parent": "xyz_exit",
	"desc": "The tunnel stretches into darkness."
    }
}

XYMAP_DATA = {
    # ...
    "map": MAPSTR,
    "prototypes": PROTOTYPES
    # ...
}

當產生上面的地圖時,位於地圖左下角和右上角的房間 地圖將獲得自訂描述和名稱,而其他地圖將具有預設描述和名稱 價值觀。一個出口(左下房間的東出口會有一個 自訂描述。

如果您習慣使用原型,您可能會注意到我們沒有新增 prototype_key 對於上述原型。這通常是每個人都需要的 原型。這是為了方便 - 如果 你不加prototype_key,網格會自動產生一個 you - 基於要產生的節點/連結的當前 XYZ(+ 方向)的雜湊值。

如果您發現自己在生成後更改了原型 網格/地圖,您可以再次重新執行evennia xyzgrid spawn;變化將是 拾取並應用於現有物件。

擴充套件基礎原型

預設原型位於 evennia.contrib.grid.xyzgrid.prototypes 和 對於地圖上的原型,應包含為 prototype_parents。會嗎 能夠更改這些並將更改應用到所有 網格?您可以透過將以下內容新增至 mygame/server/conf/settings.py

XYZROOM_PROTOTYPE_OVERRIDE = {"typeclass": "myxyzroom.MyXYZRoom"}
XYZEXIT_PROTOTYPE_OVERRIDE = {...}

如果您涵蓋原型中的 typeclass,則 typeclass 使用 MUSTXYZRoom 和/或 XYZExit 繼承。 BASE_ROOM_TYPECLASSBASE_EXIT_TYPECLASS 設定不會有幫助 - 這些仍然有用 但非 xyzgrid 房間/出口。

僅新增您想要更改的內容 - 這些字典將_擴充套件_預設父級 原型而不是取代它們。只要您定義地圖的原型 要使用 "xyz_room" 和/或 "xyz_exit"prototype_parent,您的更改 現在將被應用。您可能需要重新生成網格並重新載入伺服器 經過這樣的改變之後。

選項

例如,XYMAP_DATA 字典的最後一個元素是 "options"

XYMAP_DATA = {
    # ...
    "options": {
	"map_visual_range": 2
    }
}

options 字典作為 **kwargs 傳遞到 XYZRoom.return_appearance 在遊戲中視覺化地圖時。它允許顯示不同的地圖 彼此不同(請注意,雖然這些選項很方便,但 當然也可以透過繼承來完全涵蓋 return_appearance XYZRoom 然後在你的原型中指向它)。

預設的視覺化是這樣的:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                     #---#
                                    /
                                   @-
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Dungeon Entrance
To the east, a narrow opening leads into darkness.
Exits: northeast and east

  • map_display(布林值):這將完全關閉該地圖的顯示。

  • map_character_symbol (str):用於在地圖上顯示「您」的符號。它可以 有顏色,但只能佔用一個字元空間。預設情況下這是一個 綠色@

  • map_visual_range (int): 這是距離你目前位置的距離 看。

  • map_mode (str):這是“節點”或“掃描”,影響視覺效果 計算範圍。 在「節點」模式下,範圍顯示距離您可以看到的_節點_數量。在“掃描”中 在模式下,您可以看到許多_螢幕上的角色_遠離您的角色。 為了視覺化,假設這是完整的地圖(其中“@”是字元位置):

    #----------------#
    |                |
    |                |
    # @------------#-#
    |                |
    #----------------#
    

這是玩家在「節點」模式下看到的 map_visual_range=2 的內容:

  @------------#-#

…並且在“掃描”模式下:

  |
  |
  # @--
  |
  #----

“節點”模式的優點是僅顯示連線的連結,並且 非常適合導航,但根據地圖,它可以包含相當多的節點 視覺上離你很遠。 「掃描」模式可能會意外顯示未連線的情況 地圖的一部分(請參閱上面的範例),但限制範圍可以用作 隱藏訊息的方式。

這是玩家在「節點」模式下看到的 map_visual_range=1 的內容:

  @------------#

…並且在“掃描”模式下:

  @-

例如,可以使用“節點”來繪製戶外/城鎮地圖,並使用“掃描”來繪製 探索地牢。

  • map_align (str):「r」、「c」或「l」之一。這會相對於地圖移動 房間文字。預設情況下它是居中的。

  • map_target_path_style:如何視覺化到達目標的路徑。這是一個 採用 {display_symbol} 格式 tag 的字串。這將被替換 路徑中每個地圖元素的display_symbol。預設情況下這是 "|y{display_symbol}|n",即路徑為黃色。

  • map_fill_all (bool): 地圖區域是否應填滿整個用戶端寬度 (預設)或變更為始終僅與房間描述一樣寬。注意事項 在後一種情況下,地圖最終可能會在用戶端視窗中“跳舞” 如果描述的寬度差異很大。

  • map_separator_char (str):用於地圖之間分隔線的字元 以及房間描述。預設為 "|x~|n" - 深灰色波浪線。

更改已生成的地圖的選項不需要重新生成 地圖,但你_確實_需要重新載入伺服器!

關於探路者

新的 goto 指令舉例說明瞭 Pathfinder 的使用。這個 是一種計算節點(房間)之間最短路徑的演演算法 XY-任意大小和複雜度的地圖。可以讓玩家快速移動到 某個位置(如果他們知道該位置的名稱)。以下是一些有關的詳細資訊

  • 探路器解析節點和連結以建立距離矩陣 從每個節點移動到 XYMap 上的_所有_其他節點。路徑 使用以下方法解決 Dijkstra演演算法

  • 對於非常大的地圖,探路者的矩陣可能需要很長時間才能建造。 因此它們被快取為 pickled 二進位檔案 mygame/server/.cache/ 並且僅在地圖更改時才重建。他們可以安全地 刪除(您也可以使用 evennia xyzgrid initpath 強制建立/重建快取檔案)。

  • 一旦被快取,探路器就會很快(在上面找到 500 步的最短路徑) 20 000 個節點/房間耗時低於 0.1 秒)。

  • 重要的是要記住,探路器只能在 one XYMap 內工作。 它不會找到跨越地圖轉換的路徑。如果這是一個問題,可以考慮 使遊戲的所有區域成為一個XYMap。這可能工作得很好,但使它 更難向網格新增新地圖或從網格中刪除新地圖。

  • 探路器實際上會總結每個連結的「權重」來確定哪個是 「最便宜」(最短)的路線。預設情況下,除阻止連結之外的每個連結都有 成本為 1(因此成本等於在節點之間移動的步數)。 然而,單一連結可以將其更改為更高/更低的權重(必須 >=1)。 權重越高意味著探路者使用該路線的可能性就越小 與其他相比(這也可能讓使用者感到困惑,因此請小心使用)。

  • 探路者將_平均_長鏈條的重量。由於所有連結 預設具有相同的權重 (=1),這意味著 #-##----# 具有相同的移動成本,儘管它在視覺上「更短」。 可以透過使用連結來更改每個連結的此行為 average_long_link_weights = False

XYZGrid

XYZGrid 是一個 全域 Script,它儲存了所有 XYMap 物件 網格。任何時候都只能創造一個 XYZGrid。

要在程式碼中存取網格,有多種方法:

  • 您可以像搜尋其他Script 一樣搜尋網格。它被命名為“XYZGrid”。

網格 = evennia.search_script(“XYZGrid”)[0]

search_script 總是回傳一個清單)

  • 你可以用evennia.contrib.grid.xyzgrid.xyzgrid.get_xyzgrid得到它

從evennia.contrib.grid.xyzgrid.xyzgrid匯入get_xyzgrid 網格=get_xyzgrid()

這將“總是”返回一個網格,如果沒有,則建立一個空網格 以前存在。所以這也是建立新網格的建議方法 在程式碼中。

  • 您可以透過造訪現有的 XYZRoom/Exit 的 .xyzgrid 來取得它 財產

grid = self.caller.location.xyzgrid # 如果目前在網格房間

網格類別上的大多數工具都與載入/新增和刪除地圖有關, 您應該使用 evennia xyzgrid 指令來執行某些操作。但有 還有幾種普遍有用的方法:

  • .get_room(xyz) - 在特定座標(X, Y, Z)處取得房間。這將 僅當地圖實際上首先生成時才有效。例如 .get_room((0,4,"the dark castle))。使用 '*' 作為萬用字元,所以 .get_room(('*','*',"the dark castle)) 會讓你在黑暗中產生所有房間 城堡地圖。

  • .get_exit(xyz, name) - 獲得特定出口,e.g。 .get_exit((0,4,"the dark castle", "north")。您也可以使用 '*' 作為 萬用字元。

也可以直接存取 XYZGrid 上特定的已解析 XYMap 物件:

  • .grid - 這是所有 XYMaps 的實際(快取)儲存,如 {zcoord: XYMap,...}

  • .get_map(zcoord) - 取得特定的XYMap。

  • .all_maps() - 取得所有 XYMaps 的清單。

除非您想大幅改變地圖的工作方式(或瞭解它的作用),否則您 可能永遠不需要修改 XYZMap 物件本身。你可能想要 但知道如何呼叫 find 探路者:

  • xymap.get_shortest_path(start_xy, end_xy)

  • xymap.get_visual_range(xy, dist=2, **kwargs)

請參閱 XYMap 檔案瞭解 詳細資訊。

XYZRoom 和 XYZExit

這些是新的自訂 Typeclasses,位於 evennia.contrib.xyzgrid.xyzroom。他們擴充套件了基礎DefaultRoom並且 DefaultExit 瞭解它們的 XYZ 座標。

Warning

You should usually **not** create XYZRooms/Exits manually. They are intended
to be created/deleted based on the layout of the grid. So to add a new room, add
a new node to your map. To delete it, you remove it. Then rerun
**evennia xyzgrid spawn**. Having manually created XYZRooms/exits in the mix
can lead to them getting deleted or the system getting confused.

If you **still** want to create XYZRoom/Exits manually (don't say we didn't
warn you!), you should do it with their `XYZRoom.create()` and
`XYZExit.create()` methods. This makes sure the XYZ they use are unique.

XYZRoomXYZExit 上有用的(額外)屬性:

  • xyz 實體的(X, Y, Z)座標,例如(23, 1, "greenforest")

  • xyzmap 這屬於XYMap

  • get_display_name(looker) - 這已修改為顯示座標 如果您具有 Builder 或更高許可權,則實體以及 #dbref

  • return_appearance(looker, **kwargs) - 這已被廣泛修改為 XYZRoom,顯示地圖。將出現 XYMAP_DATA 中給出的 options 作為此方法的**kwargs,如果您覆寫此方法,您可以自訂 深度地圖顯示。

  • xyz_destination(僅適用於XYZExits) - 這給出了 xyz 座標 出口的目的地。

座標儲存為 Tags,其中房間和出口均為 tag 類別 room_x_coordinateroom_y_coordinateroom_z_coordinate 而出口除了 tags 之外還使用相同的內容作為其目的地,並使用 tag 類別 exit_dest_x_coordinateexit_dest_y_coordinateexit_dest_z_coordinate

這使得透過座標查詢資料庫變得更容易,每個typeclass提供 自訂管理器方法。過濾器方法允許使用 '*' 作為萬用字元。


# find a list of all rooms in map foo
rooms = XYZRoom.objects.filter_xyz(('*', '*', 'foo'))

# find list of all rooms with name "Tunnel" on map foo
rooms = XYZRoom.objects.filter_xyz(('*', '*', 'foo'), db_key="Tunnel")

# find all rooms in the first column of map footer
rooms = XYZRoom.objects.filter_xyz((0, '*', 'foo'))

# find exactly one room at given coordinate (no wildcards allowed)
room = XYZRoom.objects.get_xyz((13, 2, foo))

# find all exits in a given room
exits = XYZExit.objects.filter_xyz((10, 4, foo))

# find all exits pointing to a specific destination (from all maps)
exits = XYZExit.objects.filter_xyz_exit(xyz_destination=(13,5,'bar'))

# find exits from a room to anywhere on another map
exits = XYZExit.objects.filter_xyz_exit(xyz=(1, 5, 'foo'), xyz_destination=('*', '*', 'bar'))

# find exactly one exit to specific destination (no wildcards allowed)
exit = XYZExit.objects.get_xyz_exit(xyz=(0, 12, 'foo'), xyz_destination=(5, 2, 'foo'))

您可以透過讓網格產生您自己的子類別來自訂 XYZRoom/Exit 其中。為此,您需要覆蓋用於生成房間的原型 網格。最簡單的方法是修改設定中的基本原型父母(請參閱 XYZRoom 和 XYZExit 以上部分)。

使用網格

使用網格的工作流程通常如下:

  1. 準備一個有_Map String_、Map Legend、_Prototypes_和的模組 Options 打包成字典XYMAP_DATA。每個模組包含多個地圖 透過將幾個 XYMAP_DATA 加到變數 XYMAP_DATA_LIST 來代替。

  2. 如果您的地圖包含TransitionMapNodes,則目標地圖也必須是 新增或已存在於網格中。如果沒有,您應該跳過該節點 現在(否則在生成時你會遇到錯誤,因為退出目的地 不存在)。

  3. 執行 evennia xyzgrid add <module> 將地圖註冊到網格中。如果沒有 網格已經存在,它將由此建立。修復報告的任何錯誤 解析器。

  4. 使用 evennia xyzgrid show <zcoord> 檢查已解析的對映並確保 他們看起來還不錯。

  5. 執行 evennia xyzgrid spawn 將地圖產生/更新為實際的 XYZRooms 並且 XYZExits。

  6. 如果您願意,現在可以透過常用的建置指令手動調整網格。 您可以在網格原型中執行_未_指定的任何操作 在遊戲中本地修改 - 只要整個房間/出口不被刪除, evennia xyzgrid spawn 不會影響這些。 您也可以挖掘/開啟 退出到「嵌入」網格中的其他房間。這些出口不得命名 網格方向之一(北、東北等,也不是上/下)或網格 將在下一次 evennia xyzgrid spawn 執行中刪除它(因為它不在地圖上)。

  7. 如果您想新增新的網格房間/出口,您應該_始終_這樣做 修改 Map String 然後重新執行 evennia xyzgrid spawn 到 應用更改。

細節

預設 Evennia 的房間是非歐幾裡得的 - 他們可以連線 彼此之間可以有任何型別的退出,而不必有明確的 相對於彼此的位置。這提供了最大的靈活性,但許多遊戲 想要使用基本運動(向北、向東等)以及尋找等功能 兩點之間的最短路徑。

這 contrib 強制每個房間存在於 3 維 XYZ 網格上,並且 實現非常有效率的尋路以及顯示工具 您目前的視覺範圍和許多相關功能。

網格的房間完全由遊戲外部控制,使用 python 模組,帶有定義遊戲地圖的字串和字典。這是 可以將網格房間與非網格房間結合起來,並且您可以裝飾 網格房間在遊戲中隨心所欲,但不能產生新的網格 房間,無需在遊戲外編輯地圖檔。

安裝

  1. 如果您以前沒有安裝過,請安裝額外的 contrib 要求。 您可以透過執行 pip install evennia[extra] 來執行此操作,或者如果您使用 git 來執行此操作 安裝,從 evennia/ 儲存庫執行 pip install --upgrade -e.[extra] 資料夾。

  2. 匯入並將 evennia.contrib.grid.xyzgrid.commands.XYZGridCmdSet 新增到 CharacterCmdset cmdset 在 mygame/commands.default_cmds.py 中。重新載入 伺服器。這使得 mapgoto/path 和修改後的 teleportopen 遊戲中可用指令。

  3. 編輯mygame/server/conf/settings.py並設定

     EXTRA_LAUNCHER_COMMANDS['xyzgrid'] = 'evennia.contrib.grid.xyzgrid.launchcmd.xyzcommand'
    
  4. 執行新的 evennia xyzgrid help 以取得有關如何產生網格的說明。

用法範例

安裝後,執行以下操作(從指令列,其中 evennia 指令可用)來安裝範例網格:

evennia xyzgrid init
evennia xyzgrid add evennia.contrib.grid.xyzgrid.example
evennia xyzgrid list
evennia xyzgrid show "the large tree"
evennia xyzgrid show "the small cave"
evennia xyzgrid spawn
evennia reload

(記住在生成操作後重新載入伺服器)。

現在您可以登入 伺服器並執行 teleport (3,0,the large tree) 傳送到地圖中。

您可以使用open togrid = (3, 0, the large tree)開啟永久(單向) 從目前位置退出到網格中。回到無網格狀態 位置只需站在網格房間中並開啟一個新的出口即可: open tolimbo = #2

嘗試 goto view 到樹頂,goto dungeon 到樹下 地牢入口在樹的底部。


此檔案頁面是從evennia\contrib\grid\xyzgrid\README.md產生的。對此的更改 檔案將被覆蓋,因此請編輯該檔案而不是此檔案。