[wizs] 成就系統

看板mud_sanc (Sanctuary - 聖殿)作者 (小太保)時間10年前 (2015/10/27 09:59), 10年前編輯推噓2(205)
留言7則, 3人參與, 最新討論串1/2 (看更多)
我目前有想到這東西的可行的一種解法,就是用 questing 來做, 也就是說,假設 sanc 有 n 種成就,在假設 n<1000 的情況下, 就可以用 a001~a999 來代表這 999 種成就。 > quest set laechan a001 laechan 的 a001 任務資料目前狀態: 資料區:({ "a001", 0, 0, "", 0 }) 暫存區:UNDEFINED ================================================= 1 to n 變更已解步驟(目前步驟值為 0). 2 to n 變更已解次數(目前次數值為 0). 3 to date 變更已解標記(目前標記值為 ). 4 to quit 離開本設定選單. ================================================= 請輸入指令: 2 to 1 quest set 2: 你將 laechan 任務資料的已解次數值設為 1 了。 laechan 的 a001 任務資料目前狀態: 資料區:({ "a001", 0, 1, "", 1445906263 }) 暫存區:UNDEFINED ================================================= 1 to n 變更已解步驟(目前步驟值為 0). 2 to n 變更已解次數(目前次數值為 1). 3 to date 變更已解標記(目前標記值為 ). 4 to quit 離開本設定選單. ================================================= 請輸入指令: 4 quest: 感謝你的使用. 執行 running code: write(questing("check","laechan","a001",({"times",1}))+"\n"); ========== 程式執行區 ========== 1 ========== 程式執行區 ========== 也就是說,假設把 "a" 標記設定為成就系統專用,一開始我們可以 先劃出 a001~a900(真的有 a 開頭 wiz 要寫任務,就從 a901 開 始寫)。 接下來,任務標記有幾個欄位可使用 > quest query laechan a001 quest: ({ "a001", 0, 1, "", 1445906481 }) ^^^^^^^ ^^^^^^ ^^^^^^^^^^ 成就編號 達成次數 達成第n次時的時間 從上面可看出「steps」欄位就是可以利用的地方,例如說假設我設 定一個任務叫做「徒步前往泰帕依城」,並假設它的必要條件是必須 依序通過房間 A、B、C、D... 那麼在第 n 個必須依序通過的房間就可以做如下判斷 void init() { object ppl=this_player(); string names; ::init(); if(!userp(ppl)) return ; names=ppl->query("name"); if(questing("check",names,"a001",({"steps",n-1}))!=1) // 或使用 if(questing("check",names,"a001",({"steps"}))!=n-1) return ; // 設定玩家完成該成就的第 n 步驟 questing("set",names,"a001",({"steps",n})); // 然後假設玩家此時已達成最後一個步驟 if(questing("check",names,"a001",({"times"}))==1) return ; questing("set",names,"a001",({"times",1})); shout("【成就系統】恭喜 "+names+" 獲得 "+achieve_name("a001")+" 成就!\n"); } 從以上可看出,關鍵在於 achieve_name 或類似的函數要怎麼寫, quest list 會讀已註冊的任務,所以可以想成 aXXX 是「虛擬任 務=成就」,它只會存在標記,因此必定要有個成就資料庫可以 讀取它的資料。 那怎麼做比較好呢?個人思考的方式是 一、建立 achieve 指令,如同 quest,既是給玩家查看自己已達   成哪些成就之用,也給 wiz 用以做設定之用。 二、利用 chinese 指令,目前 chinese.o 檔才 13K 大小,可以   新增底下語法 chinese a001=achieve=徒步前往泰帕依城 這樣在 chinesed.c 及 chinese.c 就可新增 achieve_name 全域函數。 三、在上面 quest achieve 裡頭還有一個 date 參數未使用,這 個參數就可以用來做成就上的分類,例如「徒步前往....」   就使用 "xxx" 這個分類,... 這樣在做 achieve list 時,就可以依分類(而不是依任務編   號)來做格式化的已達成成就列表 因此剩下三種未解決項目 一、要先訂出「哪些分類」,以及它們的分類名稱 例如「玩家達成了幾個技能練到 9900 的成就」(技能類), 「玩家第一次打到未鑑定防具」(打寶類),「玩家第一次使用 鑑定指令」(初體驗類),.... 但是在鑑定方面又可細分為「玩家第一次鑑定出完整防具」,   「玩家第一次鑑定出無瑕防具」,「玩家第一次鑑定出完整無   瑕防具」,.... 在 achieve list 時,如何讓它做底下的顯示順序 玩家第一次使用鑑定指令 玩家第一次鑑定出完整防具 玩家第一次鑑定出無瑕防具 玩家第一次鑑定出完整無瑕防具 . . 也就是說,如何讓該成就是可具備事後給予順序性的,有一種 做法,例如初體驗的成就編號是 "first",然後假設「玩家第 一次使用鑑定指令」這個成就是 first_01,之後我們又將該 成就做了細分時,細分的成就編號就類似 first_01_01、first_01_02、.... 也就是說,我們必須儲存 a001 這個成就的 name 之外,還要   儲存它的成就編號,甚至可能還要儲存其它的資訊,例如達成   成就可獲得哪些報酬等。 (那就不能單純以 chinese 來做為儲存資料用) 二、要如何判斷玩家達成某項成就? 例如技能類,玩家達成第一個技能 9900、第二個技能 9900、 ....,這些要怎麼判斷?例如說 sanc 目前已經有針對玩家達   成某技能 9900 時的 shout,所以可以寫在該 shout 所在的   程式段裡面。 但問題是,在我們設定該成就之前,就已經有玩家擁有 n 個 9900 技能了(甚至所有可以 9900 的技能都已經滿了),這就   會造成這類的玩家無法取得這樣的成就。 因此像這類的成就要寫在什麼地方做判斷,就是一個問題。 三、達成成就獲得的報酬? 這個才是成就系統的核心。比方我設定「徒步走到泰帕依城」 這個成就,那可能我給定的報酬是「獲得一件已鑑定的泰帕依   城 necklace 類防具」.. 1.該項報酬怎麼放在資料庫中做描述? 2.該項報酬的給予有可能制式化嗎? 例如 reward: ({"give_obj","/std/new_ob/necklace","tapay",... 光是這樣寫就可能會有問題。 通常報酬有幾種可以給,但是它們跟任務報酬是高度重疊的, 也就是說我們必須要思考的是,「獲得成就的報酬」至少要與   「達成任務的報酬」是分開的,凡是可做為達成任務的報酬,   就應該給任務;一旦決定某一類報酬給成就系統,就不應把這   項報酬給任務系統。 目前確定「獲得某一種 buff 類」的報酬是可以給成就系統的   ,另外,像上面的「獲得該區域相關的未鑑定防具」也可以。 然後有一種例外就是「小額報酬」或「與利益無關的報酬」, 這也是可以給成就系統的,像 D3 獲得獨特的旗幟就是一種與   利益無關的報酬,而像是獲得經驗值這類的也可以算是,雖然   某些任務解完了也能獲得經驗值,但是經驗值改%之後,獲得   經驗值的報酬相對就是屬於比較小額的報酬。 但無論如何,還是必須思考獨特的報酬。 LAechan -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 210.61.157.53 ※ 文章網址: https://www.ptt.cc/bbs/mud_sanc/M.1445911174.A.7C4.html

10/27 10:02, , 1F
我最近會先從新手可達成的成就開始規劃起
10/27 10:02, 1F
※ 編輯: laechan (210.61.157.53), 10/27/2015 10:02:47

10/27 17:13, , 2F
可以學pso2,去[成就區]就會設定那些已完成的
10/27 17:13, 2F
有些我是判斷在完成的當下就廣播出來,會比較有成就感。 倒是「成就區」可當成一種補遺的做法。 (我原先還有考慮在玩家 login 時、或是在 a_heal_up 每 30 秒判斷區、 甚至交給 times_check 來做) ※ 編輯: laechan (122.117.106.224), 10/27/2015 18:32:37

10/27 19:53, , 3F
我覺得可以,達到9900就去重新全部計算一次。
10/27 19:53, 3F

10/27 19:53, , 4F
成就區好像也不錯,靠玩家自己去更新就好。
10/27 19:53, 4F
我今晚試著想看看有沒有什麼比較可行的實作方式。 現在的 mudos 新增 simul_efun 很麻煩,所以 achieve_name 這種全域函數基本上不可行。 但是 chinese.c 裡面有一個 title_name 的全域函數,倒是 可以拿來用: //laechan@sanc abort follows 2011/10/11 減少使用 simul_efun string title_name(string str) { return ""; return CHINESE_D->title_name(str); } 也就是說該函數目前實際上是沒在使用的,就可以當 achieve 的專屬函數使用。 在 chinesed.c 裡面 title 被宣告為 mapping: > call chinesed;dump_title 房間(/adm/daemons/chinesed)-> dump_title() = UNDEFINED 剩下的,就是如何做列表。其實我也有想過自訂列表順序這樣 的做法,但它的問題是一旦成就多達幾百個時,要排序就會變 得困難,因此前提還是「必須先分類」,這樣成就至少可以依 類別列表(類似天空城農場 list -xxx 的分類列表),每一類別 要各自定義排序就會變得簡單。 這個東西很重要是因為,這樣就不需從最初的成就(新手成就) 開始寫,比方我們都準備好了之後,我就可以把「徒步走到泰 帕依城」設為 a001,而當往後隨著該類別成就的新增時,我可 以透過自定義順序的方式,讓玩家在 list 時所看到的是照我 定義的順序。 我想應該不困難啦,最後就是實裝前大家討論一下成就報酬, 通常我有設未鑑定防具的區域,「徒步走到..」的成就多半都 是給一件該區域所屬的未鑑定防具。 接著就是像這樣: 第[120]級 男性龍人勇者--摳頂機器(Laechan:進階牧師) 你目前是單身,技能總數:154,成就總數:197,國王效忠值:0。 [男性龍人勇者]摳頂機器(Laechan:進階牧師),等級 120 級,6624 歲。 道德:509 點,戰功聲望:468126 點,挪布幣:521,總財產:103126696 影特幣。 技能數:154,成就總數:197,他已經玩了:1年 42週 3天 20 小時 33分 36秒。 這樣就差不多了。 關於成就的報酬部份,我以前也有寫過一個東西: // who -l if(!undefinedp(obj->query("record_data/titles"))) titles=(mixed)obj->query("record_data/titles"); 這個 "title" 可以跟 achieve 的 title 混用,比方玩家達成了 所有 skill 類的相關成就時,想要給他一個「聖殿技能大師」的 title 時: chinese skillmaster=achieve=聖殿技能大師 這樣存在 record_data/titles 的東西就是 "skillmaster" 而不 是 "聖殿技能大師"。 這東西的用意是「玩家在某一類成就上面達到一定的成就,就給予 稱號」,這東西會顯示在 who -l 上面。達到的成就規模越豐富, title 就越多,例如底下就成為可能: > who -l (第120級男性龍人勇者) 「聖殿技能大師 <= 練出 10 個 9900 技能 防具鑑定專家 <= 鑑定出完整無瑕防具 屠龍勇者 <= 殺過聖殿所有的龍類怪物 我終於擺脫單身了 <= 已婚成就 11月要考試了」摳頂機器(Laechan) <= 自訂 title 以上是概要。 (不過我是認為給制式的 title 不太好,讓玩家能自訂較 ok) ※ 編輯: laechan (1.165.178.185), 10/27/2015 22:03:33

10/28 09:02, , 5F
沒法子重現的才需要補..例如:技能9900的數量..
10/28 09:02, 5F

10/28 09:03, , 6F
[鑑定出完整]那個就新開始就好了.....
10/28 09:03, 6F

10/28 12:19, , 7F
對啊有些可當下,有些事後補,但要注意過度分散的問題
10/28 12:19, 7F
文章代碼(AID): #1MBjg6V4 (mud_sanc)
討論串 (同標題文章)
文章代碼(AID): #1MBjg6V4 (mud_sanc)