[閒聊] 任務「腳本」的設計原則

看板mud_sanc (Sanctuary - 聖殿)作者 (小太保)時間13年前 (2012/12/18 09:48), 編輯推噓4(4011)
留言15則, 2人參與, 最新討論串1/1
基本上,我本身比較不樂見看到「腳本」裡面有自訂函數的 程式段,因為這並不符合「腳本」的意義。 既然是「腳本」: 1.其構成必然簡單,不複雜 2.不應存在程式段落 換言之,現行的腳本,其實是「腳本」+「自訂函數」的綜 合體,簡單的任務就只有腳本,複雜一點的任務則再搭配自 訂函數這樣。 這是必須接受的事實。 然後一般任務進行時必然具備四個條件: 1.quest 的對象 stepX_npc 2.quest 前判斷 stepX_check 3.quest 中訊息 stepX_msg 4.quest 後結果 stepX_end 然後還需要知道一個函數:questing 所以 justin 你應根據上面,先判斷: 1.這四個條件以及該函數是否為基本足夠? 2.為何你的任務,無法使用現行的 quest 來做? 比方說,你希望玩家在任務步驟 2 跟 3 可以隨意決定順序 、並只需完成它們其中一個即可: 問題:nonseq 需不需要寫? 解答:需要。所以你建議了,我才會寫。因為根據內定流程    ,你要接任務 3 就必須先接任務 2。    它是比 stepX_check 更優先的內定判斷。 將它作為內定判斷是因為大部份的任務都是如此。 問題:anyone 需不需要寫? 解答:不一定需要。因為它可以先用 nonseq 及 stepX_end 去模擬「你只要接了它們其中一個就代表接完全部」 那我為什麼寫?因為我評估無風險。 然後,「自定函數」其實是很簡單的東西,我們隨便 more 一個有自定函數的任務檔 :::::::::::::: /open/cmds/quest/l/l002.c :::::::::::::: inherit "/open/cmds/quest/quest_d.c"; int step5_end(object ppl,object npc,string key); int step4_check(object ppl,object npc,string key); . . 你需要瞭解的就是,stepX_check 函數就是「任務步驟結 束前的插斷判斷」,stepX_end 函數就是「任務步驟結束 後的附加執行」。結束前跟結束後的差異,就在於 steps 參數是否已經變更(玩家身上的),有變更就代表玩家已結 束該任務。 other= int step1_check(object ppl,object npc,string key) { if(ppl->query("level")<120) { write("你的等級要滿 120 級才能接這個任務喔。\n"); return 1; } return 0; // 代表可接 } int step1_end(object ppl,object npc,string key) { // 設定玩家接該任務的時間 ppl->set_temp("time_record/l002_times",time()); return 1; } ## 比方你要設定任務步驟第 4-7 的各個接取條件,我認為, 用 stepX_check 及 stepX_end 及一些附加判斷即可具現 最後我要講的東西就是,比方某一個 stepX_check.. int stepX_check(object ppl,object npc,string key) { if(ppl->query("race")=="human" || ((ppl->query("race")=="elf" && ppl->query("pri_guild")=="mage")) || (ppl->query("race")=="devil" && ppl->query("pri_guild")=="fister")))) { write("你的 bla bla ... 必須滿足條件喔,抱歉,我必須將你踢出。\n"); ppl->move_player("/d/wiz/room/disc","SNEAK"); return 1; } return 0; // 代表可接 } 為什麼我不將上面的東西用「腳本式設定」來處理? 因為沒效率。假設真的存在一種設定可以滿足上面,那麼 可以預知兩個結果: 一、腳本的該部份段落「會很像程式」,例如.. stepX_check= race=human or bla bla bla## 那腳本化有何意義? 二、程式為了配合這樣的東西,「必須把所有的可能都納   入」,結果卻只是給極少數的任務設定極少樣性的條 件使用,何必呢? 我的意思就是,在「腳本」跟「程式」之間,我們實際上 需要取得的是一個有效率的平衡點。我並不反對將 quest 改的更理想,只是我要先讓你知道我在想什麼,這樣我們 改良的方向才會正確,這其中亦包含了 debug 的部份。 Laechan -- ※ 發信站: 批踢踢實業坊(ptt.cc) ※ 編輯: laechan 來自: 210.61.157.53 (12/18 10:09)

12/18 10:38, , 1F
那我再提幾個好了...一個是剛剛發現的..另一個還沒找
12/18 10:38, 1F

12/18 10:38, , 2F
到方法...
12/18 10:38, 2F

12/18 10:40, , 3F
1.我原本設定 macro #define AA MM"CCC"後,然後在
12/18 10:40, 3F

12/18 10:42, , 4F
step_npc時用=$AA$TTTT##的寫法好像沒法子用marco..
12/18 10:42, 4F
你可以把 quest read xxxx 後的 xxxx.c 檔內容前半貼 出來。規則是「跟 xxx.h 的定義法一樣」。

12/18 10:43, , 5F
2.我比較喜歡任務裡有失敗的條件,所以我會將最後一步
12/18 10:43, 5F

12/18 10:44, , 6F
設定成fail...然後可能會這樣走1->2->4->7(fail)
12/18 10:44, 6F

12/18 10:45, , 7F
或者是1->2->5->6(成功)...這樣..也許裡面有寫..所以
12/18 10:45, 7F

12/18 10:46, , 8F
我還要再找找有沒有這種用法..)
12/18 10:46, 8F
就我說的:用自定函數的做法。 我上面提過,如果玩家走 1,2,4,7,那你就在 stepX_end (X=1,2,4,7) 都自訂,例如.. step1_end= ppl->set_temp("time_record/xxxx_1",1)## step2_end= ppl->set_temp("time_record/xxxx_2",1)## step4_end= ppl->set_temp("time_record/xxxx_4",1)## other= int step7_end(object ppl,object npc,string key) { if(ppl->query_temp("time_record/xxxx_1") && ppl->query_temp("time_record/xxxx_2") && ppl->query_temp("time_record/xxxx_4")) { write("任務失敗。\n"); // 將任務移除要玩家重接 // 使其造成的結果相當於 quest del justin xxxx questing("相關功能",bla bla...); // 若該功能沒有就自己寫,或提出需求由我來改 quest_data_d.c return 1; } return 1; }## ※ 編輯: laechan 來自: 210.61.157.53 (12/18 10:56)

12/18 13:13, , 9F
果然看內容可以找到用法..step1_npc="+ROOT"child##
12/18 13:13, 9F

12/18 13:14, , 10F
用這樣寫就可以設定代碼了..(雖然看起來怪怪的...)
12/18 13:14, 10F
喔,這樣實在沒必要,不過也是可以... 這是因為 str = "路徑+檔名", 它是沒有 " " 的, 這時候 ROOT 就變成字串而不是代號。 如果你那時就舉這個例子,我就知道你的意思,我就可以配 合修改。 不過話說回來,它也不是那麼好改的,這時就變成,我會建 議你,在你移目錄時,腳本檔目錄的部份就跟著改掉,或者 就像你上面那樣的變通做法亦可。 還有,腳本檔的讀入你可以想成有做底下這行.. sscanf(str,"%s=%s##",s1,s2); 這是非常直覺的。然後它最終的結果則是 quest_data["s1"] = "s2"; 從這裡就可推測若 s2 = "ROOT"child##, 上面就會變成 quest_data["s1"] = ""ROOT"child"; 這個在以前用 change 去寫房間檔時也用過, 如.. short: "HIG"大草原"NOR"## 也就是說,你可以把 "ROOT" 當成 #define 變數的引用語 法,我希望大家也都可以這樣子想。

12/18 13:38, , 11F
你可以試試 "ROOT"child## 看是不是也可以
12/18 13:38, 11F
※ 編輯: laechan 來自: 210.61.157.53 (12/18 13:39)

12/18 16:33, , 12F
問一下哦...要怎麼跳步驟...不會跳..唉
12/18 16:33, 12F

12/18 16:55, , 13F
可以看 #1Gq2zkva 這篇
12/18 16:55, 13F

12/19 09:59, , 14F
測試的結果...anyone是只能執行任何一個...
12/19 09:59, 14F

12/19 10:00, , 15F
我是想要這樣..2->3->4或3->2->4或2->4,3->4...
12/19 10:00, 15F
文章代碼(AID): #1GpyjbVx (mud_sanc)
文章代碼(AID): #1GpyjbVx (mud_sanc)