Re: [wizs] 請教 .h 檔

作者: laechan (揮淚斬馬雲)   2014-05-22 13:43:30
※ 引述《caselook (幸福要懂得耕耘)》之銘言:
: 全域繼承檔是不是定義在 /include/globals.h 裡面?
不是,是被寫在 mudos 所使用的 config 檔,如果你曾抓過
tmi2-mudlib+fluffos 包裹壓縮檔,可打開其 mudos 目錄下
bin/config.tmi2 檔查看
(如果解壓縮在 D 槽就是 D:\tmi2_fluffos_v3\bin\config.tmi2)
最底下那幾行就如下
maximum buffer size : 100000
debug log file : debug.log
global include file : <mudlib.h>
而 sanc 的 mudlib.h 裡面又有一行 #include "ansi.h",
所以這兩個 .h 檔才會變成 sanc 今天的 global .h 檔。
: : void create()
: : {
: : ::create();
: : seteuid(getuid(this_object())); // 到這裡為止都是固定的
: : // seteuid: 設定一個物件的有效識別名稱
: : // 有這一行, 房間才被允許做一些
: : // 載入或複製物件的動作
: : // getuid : 傳回一個物件的有效識別名稱
: : // this_object(): 這個物件本身
: 上面這一段應該就是標準寫法了。似乎是與mudos設定物件的權限有關。
: 所以,是不是所有的 void create(){}都要加上這一行?
通常一個最單純的房間(沒有特殊用途等),是不需要 seteuid 的,
反過來說不單純的房間你就想成最好都 seteuid 過比較沒問題。
這跟 valid_xxx 相關函數有關,透過這個房間去做載入物件或是執
行一些特殊函數、動作時,它會要求房間要先有 uid。
所以 uid「有設」比「沒設」保險,這是首先可瞭解的。
其次就是「它不一定要設,看情況」,這也接著要瞭解的。
(::create(); 那行則幾乎都是要的)
: : set("light",1); // 房間維持光亮
: : set("short","工作室"); // 設定房間名稱
: 我看 wizhelp 的 basic 說明檔,提到 set()的標準寫法是
: this_object->set() ,這個「->」符號的意思是?
那個不要看了有些東西是舊的。
-> 你可以理解為 物件 呼叫(->) 函數(參數)
mud 會有像是物件導向的東西,指的就是這一方面,任何已
被載入到記憶體的東西幾乎都能稱為是一個物件,而我們將
它載入到記憶體的目的就是希望這個物件能為我們提供什麼
服務,它的最基礎語法就是 物件->。
以上面來說 this_object()->set 就是要求「this_object()」
這個函數回傳回來的「物件」,去呼叫 set() 這個函數。
那麼為什麼寫房間卻是用 set 而不用 this_object()->set
呢,因為 this_object() 就是「傳回這個房間本身」,則
既然 this_object() 可呼叫 set(),那寫在這個房間裡面
的函數本來就可以呼叫本地的 set,也就是說以這個 case
this_object()->set("light",1);

set("light",1);
是同義的。而在執行速度上自然是後者較快,因為它屬於本
地呼叫,而沒有透過 this_object() 函數先取得一個物件
,再令它做 set 的動作。
: 在 create room 的set(),除了設定 exits,hide_exits,objects....之外,
: 還有那些資料可以參考 set()函數的功能?
你先知道基礎的這幾個就可,因為這些幾乎是 LPmud 通用的設定。
然後理論上房間的 set 語法是
set("設定項目",設定內容);
只要設定項目符合「字串」就幾乎都可以設,重點就在於你設了這
個字串,就需賦予它「意義」。例如說我們今天設定 "short" 這
個資料串,那為什麼玩家下 look 時可看到我們設定的 short 呢
?這是因為我們在 look 這個動作裡有加上相對應的程式段例如
if(room->query("short"))
write(room->query("short")+"\n");
則玩家下 look → 程式執行到上面的段落 → 讓玩家看到 short
所以一開始瞭解最基本的房間大概包含哪些設定即可,這樣就足
夠寫簡單的區域了,然後一開始需做的就是試著寫幾個簡單的物
件,而不要把它想得太複雜。
: : reset(); // 有 set("object") 就要有這一行 reset()
: : // 被設定的物件才會被 load 到房間
: : }
: : 你所參考的房間,有一些寫法是錯誤的,那是非常早期版本的
: : mudos 可相容的寫法,現在是不相容的,這只要 update 那個
: : 房間馬上就會知道。
: update 還沒用過。主要是因為覺得 edit 不習慣。
: 所以我 cp 了 workroom,c workroom.bak 之後,不知道怎麼 edit workroom.c
: 有沒有辦法在 local 端用 npp 編輯好,再上傳到 sanc?
sanc 目前不開放 ftp 上傳,我比較建議先在自己電腦的文書編
輯軟體將檔案編好,再用 edit 把檔案寫入,這樣有錯誤時,只
要改自己電腦下的檔案,改好再重新 edit 進去就可。
因為你一開始編輯的東西並不會太複雜,所以我才建議這樣的方
式。
edit 跟 vi 一樣都分為命令模式(即最前面有 : 號)跟編輯模式
,命令模式可下的指令最常用的有底下幾個
a : 往後添加 1 至數行
i : 從所在行開始添加 1 至數行
d : 刪除所在行
w : 存檔
q : 離開
Q : 不存檔離開
數字 : 直接跳往某一行
在編輯模式要跳回命令模式,則是在行首輸入 . 符號按 enter
即可。
: : 如果你真的要自己研究,那你應該先問的是一開始要知道哪些
: : 事情,包括有哪些指令(工具)可使用、可先參考哪幾個區域、
: : 然後怎麼設定自己的 workroom 去快速連結這些區域等。
: 這個很需要知道,我原以為直接在 caselook 的工作目錄下先寫區域,
: 包含 room 及各種 objcet後,再考慮連結其他的區域的說。
這也是可以的,但是我覺得對你來說,現在更應該做的不是急著寫
區域,而是先「多看看別人怎麼寫」,然後看一看後你想寫,就先
「試著寫」而不是「就開始寫」,把基礎盡量打穩,看久了你就會
發現一個東西叫做「框架」,在你看過足夠多的樣本後,你就會知
道你想寫的東西,它的框架其實跟現存的許多樣本都大同小異,你
會在無形中自然理解:
1.要寫一個東西,會需要用到哪些框架
2.每一個框架的各種組成要素有哪些是常用的
例如說要寫房間,我們需要 void create() { } 這個框架;要在
房間裡面設定讓玩家可執行一些指令,需要 void init() { } 這
個框架;......
: : 有哪些 wiz 的指令可用
: : update - 更新(編譯, compile)一個 .c 檔並將其載入到記憶體
: : invis player - 讓自己隱形, 在調查主動怪區域時可使自己不被攻擊
: : more [目標] - 如 more lodao、more here、more ~/workroom.c、..
: : clone [目標] - 叫出一個物件,如 clone /d/wiz/mob/lodao
: : dest [目標] - 消滅一個物件,如 dest lodao、dest cloth、...
: : goto [目標] - 如 goto laechan、goto ~/workroom.c、..
: : home - 回自己的工作室,預設為 /u/c/caselook/workroom.c
: : 也可以 home 其它 wiz 的工作室如 home laechan
: : cp - 拷貝檔案
: : rm - 刪除檔案, 目錄
: : mv - 搬移檔案, 目錄
: : md - 建立目錄
: : da [目標] - 觀看一個被載入物件的設定資料。如 da me、da laechan、
: : da here、da ~/workroom、...
: sanc 好像沒有 cat指令,打 cat 呼叫的是妙喵的哀嚎....
: sanc有沒有類似於 cat 的指令呢?
: 我用的 pietty只有「複製全部」的功能,用 more 分段顯示是很方便,
: 但比較不容易截錄畫面文字。
cat 有它的極限(跟字串長度有關),不過我可以寫一個給你,順便跟你說
一下最簡單的 cat 指令寫法
// /cmds/file/_cat.c
inherit DAEMON;
int cmd_cat(string str,object me)
{
string files;
if(!str || str=="")
return notify_fail("語法: cat [檔案名稱].\n");
if(ob=present(str,me))
files=base_name(ob)+".c";
else if(ob=present(str,environment(me)))
files=base_name(ob)+".c";
else if(str=="me")
files=base_name(me)+".c";
else
files=resolv_path(me->query("cwd"),str);
if(!file_exists(files))
return notify_fail("cat: "+files+" 檔案不存在.\n");
str=read_file(files);
return notify_fail(str);
}
cat 指令已實裝於 5003。
: : 可先參考哪幾個區域
: : 基本上 /d/ppl/ 目錄下的區域就是一開始可以參考的。
: /d/ppl/我會好好觀摩,有問題再在板上請益^^
嗯嗯,可以多看,有問題亦可盡量問。

Links booklink

Contact Us: admin [ a t ] ucptt.com