ES2 MUD LIB :: 東方故事二(ES2) 天朝帝國 mudlib 瀏覽展示

/doc/build/item

HOME :: doc :: build :: item
□ 如何寫一個物品

在 es2 mudlib 所定義的世界裡﹐除了房間跟生物以外﹐所有使用者看得見摸得到
的物品都會繼承 ITEM 這個標準物件﹐包括你身上攜帶的所有東西跟房間裡看得到
的東西。事實上所有的生物也具有一切 ITEM 所具有的特性跟函數﹐但是因為生物
在許多方面的特性和其它物品不同﹐因此獨立開來﹐而房間是因為它是一個「假想
」的容器﹐用來容納生物跟物品﹐不像生物跟物品可以到處移動和被檢視。

說到移動被檢視﹐我們可以從這裡引導出「物品」的定義了﹐es2 mudlib 定義「
凡是可以被移動和被檢視的物件」稱為「物品」﹐什麼意思呢﹖請你用 ilist 觀
察 ITEM 這個標準物件( 通常是 /std/item.c﹐見 /include/globals.h )﹐你可
以看到它繼承了 F_NAME (/feature/name.c) 跟 F_MOVE (/feature/move.c) 兩個
特性。

F_NAME 定義一個物件的 name()、short()、long() 跟提供 present() 這個 efun
辨認一個物品的介面﹐並且也處理物品的隱形和其他有關「名稱」的雜務。

F_MOVE 定義 move() 這個函數使得物件可以被放入另一個物件中( 這裡指的是由
MudOS 所提供的 mud 世界中物品位置關係﹐而不是資料結構上的關係 )﹐並且合
併處理所有物品移動之後重量和負重量的計算。

□ 物品範例

// An example item

inherit ITEM;

void create()
{
    set_name("石塊", ({ "stone rock", "stone", "rock" }));
    set_weight(500);
    if( !clonep() ) {
        set("unit", "塊");
        set("long", "一塊毫不起眼的石塊。\n");
    }
    setup();
}

上面就是一個簡單的物品範例﹐不要小看這個簡單的物件﹐讓我一行一行地解釋每
一道敘述的意義後你就知道為什麼。

inherit ITEM;

這一行表示我們寫的這個物件要繼承 ITEM 這個標準物件﹐事實上 ITEM 是我們定
義在 globals.h 的巨集﹐可是我們明明沒有 #include  啊﹖ 是的﹐
globals.h 是我們執行 MudOS 時設定的 default include file﹐MudOS 在編譯所
有的物件時會自動引含他的內容﹐es2 mudlib 將一些常用的標準物件定義成巨集
放在這個檔案裡﹐讓巫師寫的程式看起來簡潔一些﹐並且預防萬一以後更動了標準
物件的路徑時﹐不必一個一個修改所有繼承他的物件。

你可以看到這個物件只有一個 create() 函數﹐這個函數有點類似 C++ 中 class
的 constructor﹐用來做一個物件的初始化工作﹐不過 create() 不會傳入任何參
數﹐詳細細艇i以參考 help create。

create() 函數所要做的工作就是將物件初始化﹐在 create() return 之後這個物
件就會被放在它該在的地方﹐並且在該被呼叫的時候被呼叫適當的函數﹐這種程式
設計的方法和 Windows 環境下所謂的事件驅動程式設計很像﹐只不過我們可以直
接定義對應某一事件的函數( 因為 LPC 的函數是 runtime linking )﹐上面講的
如果你看不懂﹐沒有關係﹐只是提供修過程式語言的人做參考。

set_name() 這個函數是 F_NAME 所提供的用來快速設定一個物品名稱的介面﹐第一
個參數是物品的中文名稱﹐在大部份跟物品有關的指令產生的訊息中﹐用的就是這
個名稱﹐第二個參數是一個陣列﹐裡面列出的是所有可以用來指定這項物品的英文
名稱﹐而且陣列的第一個元素會成為這個物品的英文 id﹐常常被放在中文名稱後面
的括號中。

set_weight() 是 F_MOVE 所提供用來設定一個物品的重量﹐es2 所用的單位是公克
﹐如果你改寫整個遊戲制度的話﹐用其它單位也無妨﹐只要一致就好了。

if( !clonep() ) ... 這一行是 es2 mudlib 用來節省記憶體的一種方法﹐當物件
的 create() 在物件被複製時被呼叫( clonep() 傳回非零值 )時﹐我們假設記憶體
中已經存有一份相同的物件﹐並且已經在第一次載入的時候設定好接下來我們將要
設定的東西﹐因此我們讓這個被複製的物件和先前載入的物件去共用這些資料﹐在
概念上類似 Java 的 static final 常數﹐但是因為 LPC 的支援不夠﹐因此我們
用函數自己摹擬﹐這項功能由 F_DBASE 提供﹐所以只能共用 set() 所設定的東西
﹐有興趣的話可以參考 F_DBASE 的文件。

在 if( !clonep() ) { ..... 的部份我們設定了一些物品的屬性﹐上面的範例中只
設定了 unit 跟 long﹐unit 是這個物品的計數單位﹐long 是物品的詳細外觀﹐
想必不難猜得出來。

最後一行的 setup() 定義在 ITEM 裡﹐用來幫你補足你忘了設定的東西跟檢查錯誤
﹐不管你寫任何物品﹐記得加上這一行就對了。

By Annihilator(04/06/96)
HOME :: doc :: build :: item