成就系統 - 聖殿英雄傳說 MUD
By Gilbert
at 2015-10-27T09:59
at 2015-10-27T09:59
Table of Contents
我目前有想到這東西的可行的一種解法,就是用 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
--
也就是說,假設 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
--
Tags:
線上
All Comments
By Kyle
at 2015-10-30T19:51
at 2015-10-30T19:51
By Kyle
at 2015-11-02T09:52
at 2015-11-02T09:52
By Ophelia
at 2015-11-06T05:08
at 2015-11-06T05:08
By Lauren
at 2015-11-08T19:38
at 2015-11-08T19:38
By Bennie
at 2015-11-09T09:09
at 2015-11-09T09:09
By Hedy
at 2015-11-13T00:49
at 2015-11-13T00:49
Related Posts
回報與建議
By Ina
at 2015-10-27T02:13
at 2015-10-27T02:13
可能的bugs...和建議
By Elma
at 2015-10-27T00:59
at 2015-10-27T00:59
回報與建議
By Zenobia
at 2015-10-27T00:54
at 2015-10-27T00:54
33.95歐資料片
By Irma
at 2015-10-26T23:48
at 2015-10-26T23:48
技能修練2倍
By Hamiltion
at 2015-10-26T21:59
at 2015-10-26T21:59