看板 mud_sanc 關於我們 聯絡資訊
所謂的任務物件,例如 n000 這個任務,其任務物件假設也 叫 n000,基本說明如下.. 一、每一個任務物件都會 inherit quest_d.c 二、每一個任務物件都有宣告一個 mapping quest_data,   但依據我的寫法,你並不需要去知道其結構如何,只要   知道讀取各項 key 值的方法(函數)即可。 三、每一個任務物件還有宣告 void create(),這代表這個   任務物件是可以暫存東西用的,例如.. n000->set("tmp_data/"+ppl->query("name"), bla bla...); 比方說我們有需要暫存一些東西時就可以這樣做,在該   物件 reborn 或是系統 shutdown 後其值就會消失。 ==================================================== 因此關鍵在 quest_d.c,這篇其實就是在講這個。 int check_nonseq(string names,string qq,int s,object ob); 這個函數的主要用途是做 nonseq 的相關判斷,其關鍵參數 就是 s(names 已把 qq 這個任務解到第幾步驟) 1.它判斷到該任務有 nonseq 時,會自動在玩家的任務資料 上新增 quest_temp,使用 quest query 指令可以看到這 個 quest_temp 的結構。 2.nonseq允許設定兩組以上。換言之,你可以設定這個任務 的第 a1~b1 步驟是 nonseq、然後第 a2~b2 步也是nonseq ,我沒有實測,不過理論上是可行的。不過建議nonseq之  間至少隔一個任務步驟(如 2~5,7~10) 3.這個函數可以傳回玩家在 nonseq 裡面的未解部份,例如  說當 nonseq=2~7,玩家已解第 2,4,6 步驟時,它就傳回 ({3,5,7}) 這個陣列。若玩家把第 2~7 都解過了(不用照  順序),就傳回 ({-7}) 這個值(用負的代表都解過了)。 int check_max_nonseq(int n); 比方 n000 設定 2~7 是 nonseq,它的意思就是玩家解完第 一步驟後,到第 7 步驟為止其順序是可以隨意的。 而比方你已經解到第 5 步驟了,這個函數可以傳回 7 這個 值(也就是 nonseq 範圍的最大值, 2~7, 那自然是 7) 而如果給定的範圍不在 2~7 之間,就傳回 0。換言之這個 函數就是用來判斷你是不是已經解到了 nonseq 所包含的範 圍。 (是的話,就不能要求你必須照順序來解的意思) int check_test(); 這個函數是判斷該任務物件是不是 wiz 測試用任務物件,它 主要是判斷 test 這個參數,比方 l003 的 test 就設成 1 ,就代表它是任務物件。 其實 test 只要有設(不管設 0 設 1),它就會判斷為測試用 ,這點要特別注意,判斷為測試用時它會傳 1 回來。 然後底下以 n000 為例,來說明一些簡短的函數 // 取得 quest_data.c 這個物件(它會去讀特定目錄的檔案) // 這東西就是用來存取玩家的任務已解/未解資料用的 object get_quest_data_ob(); // 取得 quest_data 這個 mapping 參數, 就是讀取所有的 // 任務設定資料的意思, 通常不建議這樣做 mapping query_quest_data(); // 傳回這個任務物件設定的 keyword。當設定兩組以上的 // keyword 時就傳回陣列, 例如 n000 的 key 是 // ({"newbie quest","新手任務"}) // 其對映的值是 key mixed query_quest_key(); // 傳回這個任務的「前置任務」,這個設定也很重要,可 // 以讓 wiz 設定要解哪些任務前,必須先解哪些前置任務 // 其對映的值是 front,比方 front=n001;n002,代表要 // 解 n000 前要先解 n001 及 n002。玩家在 quest n000 // 時自動顯示玩家需先解什麼任務。 mixed query_quest_front(); // 傳回該任務總共設定了幾個步驟,其對映值是 steps。 int query_quest_steps(); // 傳回這個任務總共可以被玩家解幾次,其對映值是 times. // 有設的話就傳回它可被解幾次, 沒設的話就傳回 1(只能解一次) // times 參數在任務有設 repeat 時是無效的(代表可解無限多次) int query_quest_times(); // 傳回這個任務有沒有設定可解無限多次,其對映值是 repeat。 // 有設的話就傳回其設定的值(所以設 0 代表沒設),沒設傳回 0 int query_quest_repeat(); // 這東西跟上面的 check_test 是類似的 int query_quest_test(); // 傳回任務的正式名稱. n000 是代號, "在新手村生活的第一步" // 就是 title,其對映值是 title。 string query_quest_title(); // 傳回任務的作者. 若沒有作者就會傳回「無名氏」。 // 其對映的參數是 author string query_quest_author(); // 傳回該任務的 date 標記。它可以當成「需重置的標記」,例 // 如說該任務在 2012/04/25 開放玩家解,但是 04/26 時你發現 // 該任務必須更動,且更動後玩家必須重解時,就更動 date 這 // 個標記,例如改成 2012/04/26,這樣玩家就必須重解該任務。 // 換言之這個 date 不一定只能設成日期格式。 string query_quest_date(); // 傳回該任務第 s 步驟的對映 npc 或物件,例如 n000 這個任 // 務的第 1 步驟是找 musi 對話,這時就傳回 musi 的完整路徑 // 檔名。其對映值就是 stepX_npc,X 代表第幾步驟。 string query_quest_npc(int s); // 傳回該任務第 s 步驟的相關訊息 // 其對映值就是 stepX_msg,X 代表第幾步驟。 mixed query_quest_msg(int s); // 這個設定的用意是,比方某任務設定最多可解三次, // 你可以設定解到第 3 次時顯示不同的訊息跟領取不同 // 的報酬之類的, 這個函數主要是讀取訊息 mixed query_time_msg(int s,int times); void show_quest(object quest_ob,string qq); void shows_quest(object quest_ob,string qq); 兩種不同的任務資料顯示格式,shows 顯示的是原始資料 ,wiz 可透過 quest shows 去觀看原始設定,然後再對照 原始腳本,就可以知道腳本跟設定的差異。 show 則是顯示編譯過的資料。 string query_quest_chat_npc(int s); string query_quest_chat_msg(int s); 這個函數的對映參數是 chatX_npc 及 chatX_msg,它的設 定意義是,比方某 npc 沒有在某個任務的 n 個任務裡頭 ,但是你覺得玩家有可能會去 quest 他時,就可以把他設 進 chatX_npc 裡頭,任務系統會根據玩家目前已經解到第 幾步驟,去讀出該步驟對應的 chat_npc,若玩家在此時去 quest 他,可以得到「額外的訊息=chat_msg」。 例如說,某 npc 可能在任務 a 而不在任務 b,而任務 a 是任務 b 的前置,這時在解任務 b 時,該 npc 就不必然 是「不相干的人」。 check_quest(int s,string f,mixed tmp,mapping quest_temp,object npc) 這個函數就是任務物件的核心函數,本來應該更名的但我 忘記了(只好將錯就錯,原則上它不應該被叫這名字)。 這個函數是用來處理「當玩家解某個任務到第 n 個步驟 時,下一步該做什麼」。 其詳細的內容就自行 more quest_d.c 觀看即可。 (大部份我都有在程式內註解了) 其它自訂函數的部份 這個我目前是傾向將這些自訂函數另外收集起來寫成一個 xxx.c 檔,然後再讓 quest_d.c 去 inherit 它。 (這樣 quest_d.c 才不會太過肥大) 自訂函數就是用來讓任務腳本撰寫者可以呼叫用的,它將 一呼叫格式化,例如.. ppl->set("up",500); 簡化後就變成 set_v(ppl,"up",500); 格式化的用意在於「方便編譯」,例如 set_v 就是設定值 ,ppl 就是玩家,up 就是學習點數,500 就是值,因此而 可以有底下的結果.. > quest show l001 ┌────────────────────────────────┐ │任務獎勵: │ │ │ │ 學習點數 500 點。 │ └────────────────────────────────┘ 格式化的好處就是方便編譯,不過這並不是編譯的唯一手段 LAechan -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 111.81.173.167 ※ 編輯: laechan 來自: 111.81.173.167 (04/26 13:44)
hlead :意思是無限多次解時要寫times=repeat## ?.... 04/26 18:56
laechan :repeat=1## (此時似乎就無視time) 04/27 01:36
hlead :soga.. 04/27 06:57