[wizs] 成就系统

楼主: laechan (挥泪斩马云)   2015-10-27 09:59:30
我目前有想到这东西的可行的一种解法,就是用 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

Links booklink

Contact Us: admin [ a t ] ucptt.com