[wizs] 成就系統
看板mud_sanc (Sanctuary - 聖殿)作者laechan (小太保)時間10年前 (2015/10/27 09:59)推噓2(2推 0噓 5→)留言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
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
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
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
討論串 (同標題文章)
完整討論串 (本文為第 1 之 2 篇):
2
7
mud_sanc 近期熱門文章
PTT遊戲區 即時熱門文章
48
63
64
103
13
24