MudOS里面以物件(objects)來稱呼一個.c
文件。其實跟其他語言中class
的概念很像,不過與之相比會有一些特殊的地方。
MudOS中的物件,統一繼承一個"object"物件,代表了這是一個具體的實體。這個具體的實體可以是:房子(room)、怪物(monster)、用戶(user)等東西。
下面先來看看物件的通用函數(每個物件都可以定義的函數)。
通用函數
create
void create( void );
用法:
每一個物件中, 都應定義一個 create() 函數. 在 create() 函數中, 要完成一個物件的初始條件設定. 所有的物件都會調用 create() 函數.
clean_up
int clean_up( int inherited );
用法:
驅動程序 (driver) 為在一段時間之內沒有活動 (inactive) 的物件調用 clean_up() 函數. 此段時間的長短, 定義在執行時段組態檔 (rumtime configuration file) 中。clean_up() 會收到一個標志 (flag) , 指出此物件是否有別的物件繼承 (inherit) 它. 如果clean_up() 返回 0, 則此物件將永遠不再調用 clean_up(). 如果返回 1, 則在指定的 clean_up() 延遲時間之后物件仍沒有活動的話, 再調用一次 clean_up().
通常一個物件在 clean_up() 中所作的事, 是摧毀自己以節省內存.
reset
void reset( void );
用法:
在每次重新設定 (reset) 之后 (實際的重新設定周期取決于該 mud 的設定, 平均大約是每兩個小時一次) , 所有游戲中現存的物件都會調用 reset() 函數. 如果編譯驅動程序時, 于 options.h 中定義了 LAZY_RESET, 只有玩家接觸到的物件才會調用 reset(). 如此一來, 沒用到的物件就不會從交換檔 (swap file) 中載入并進行重新設定. reset() 常用于檢查寶物或怪物是否還在某個房間, 以判斷要不要重新產生一份.
上面講的比較模糊。reset其實用于房間重新生成怪物,也是是游戲里面的刷怪。
move_or_destruct
int move_or_destruct( object dest );
用法:
如果一個物件的環境 (environment) 物件被摧毀了, 就調用此函數, 并用于它的內容物件. dest 是正要被摧毀的物件. 如果 dest 不存在, 則 dest 為 0. 如果 dest 中的物件沒有把自己移出被摧毀的物件, 則也會被一起摧毀.
每個object都有屬于自己的environment。最直觀的概念,就是玩家打副本地圖。如果玩家通關一個臨時副本,副本地圖的銷毀會導致所有處于這個環境下的object調用自身的move_or_destruct。副本內的怪物destruct,玩家move到其他地圖。
init
void init( void );
用法:
當 mudlib 把物件 A放入(move)物件 B時, 驅動程序 (即 move_object() 函數) 會做以下的動作:
1. 如果 A 是活的 (living), 讓 A 在 B里面調用 A 的 init() 函數.
2. 不管 A是否為活的物件, 讓 B的內容物 (inventory) 里面, 所有活的物件調用 A 的 init().
3. 如果 A是活的, 讓 A調用位于 B 的內容物里面所有物件的 init().
請注意: 一個物件必須曾調用過 enable_command(3) 才視為活的物件.
一般來說, 一個物件的 init(4) 函數用來調用 add_command(3), 添加此物件提供的動詞命令 (command).
舉個例子,當來到一個新的地圖時,玩家和地圖各自的init被調用,玩家可能會得到某種buf或message,地圖要做一些初始化的工作,比如通知其他玩家有人來了。這體現了一種互相影響的關系。(太哲學了)
id
int id( string an_id );
用法:
present(3)外部函數調用 id() 以判斷一個指定的物件是否以字符串 an_id為識別名稱 (id) . 如果 an_id 是此物件的識別名稱之一, 就返回 1, 不是則返回 0.
其實就是詢問一個object:你是那誰誰誰嗎?
互動物件(interactive)
互動物件一般是指玩家物件。
logon
object logon( void );
主控物件 (master) 中的 connect() 函數返回的物件會調用 logon(). 此函數將新的使用者設定好.
也就是初始化使用者。一般來說會在這里彈個消息歡迎用戶。
net_dead
void net_dead( void );
如果一個可互動的物件 (即玩家物件) 突然斷線 (即成了「網路死亡」(net dead) 狀態) , 則驅動程序對此物件調用 net_dead() , 讓此物件稍后有機會被清理掉 (clean up)、將斷線狀態告知環境物件等等. 請小心, 在物件處于可互動狀態時才有作用的函數, 將不會如您預料般地工作.
一般要在這里停止心跳,并告知environment,這個player掉線了。
process_input
string process_input( string );
用法:
如果玩家物件中有 process_input(), 則 MudOS 驅動程序則會將玩家所輸入的每行數據傳遞給 process_input(). process_input() 使得像命令回溯 (command history) 和防止 wizcuffs. process_input() 可以在分析 (parse) 命令前, 修改玩家輸入的數據. 如果 process_input() 返回一個非零字符串, 則此字符串就代替玩家輸入的內容.
很容易理解,用戶所有的命令都要經過這個函數的處理,處理過后的返回值就會代替用戶輸入的命令進入下一個流程。
receive_message
void receive_message( string class, string message );
用法:
message() 這一類的外部函數調用在玩家物件中的 receive_message(). 參數 parameter通常用于指示消息的種類 (說話 say, 傾訴 tell, 表情 emote, 戰斗 combat, 房間語句 room description). receive_message() 和 message() 的外部函數結合在一起, 可以提供一個「聰明的」消息處理程序介面.
就是反饋信息用的。
還有一個receive_snoop函數:
void receive_snoop( string message) ;
用法:
如果驅動程序編譯時, 在 options.h 中定義 RECEIVE_SNOOP, 則一個使用者窺視另一個使用者時, 所有窺視的文字會傳遞給玩家物件中的 receive_snoop() 函數. 在此函數中, 您可以處理這些文字. receive_snoop() 程序的內容, 通常把這些文字再傳遞給 receive() 函數.
主控物件(master)
主控物件只有一個,負責整個程序的調度。舉個例子,每當新用戶連接到服務器的時候,driver會調用master的connect方法。一般來說,connect方法負責生成一個login對象并返回,login負責處理與新用戶的所有交互。