[閒聊] 關於武防精鍊的做法評估

作者: laechan (揮淚斬馬雲)   2020-05-21 11:15:46
灌個水。(真物理灌水,咕嚕咕嚕...
sanc 還沒真正實裝這個東西,想說來研究看看,或許打著打著,
sanc 那邊就給它實裝了也說不定。
在部份 mud,玩家資料檔的 obj_data 欄位可以做如下儲存:
obj_data ([
"/weapon/lodoos/sword1#123456":(["improve_lv":5, ...]),
.
.
])
也就是以物品的檔名做為 key 值,後面接這個物品的額外儲存資
料,當玩家 login 時,依照 key 值 clone_object 物品出來的
同時,再做以下的動作:
ob=clone_object(files);
foreach(str in keys(obj_data[files]))
ob->set(str,obj_data[files][str]);
例如把上述的 improve_lv 值 5 設定到該 clone_object 出來的
物品上面,再把該物品 move 到玩家身上。
這類關於額外儲存的資料,需滿足以下條件:
一、最少設定(儲存)項目
二、最簡設定(儲存)原則
比方也有人是用 refine 做為精鍊的意思,我個人的評估思維是,
如果指令敲起來好敲(refine蠻好敲的),意思也有點兒到了,長度
沒有很長....這裡的長度指的是
refine_lv 精鍊等級
refine_stat 精鍊所提升的屬性質
.
.
做為儲存欄位來說看起來還 ok,那我多半就會用了。
那首先就 refine_lv 即精鍊等級來說,像 RO 可以精練到 1x 等
,而且是武器防具都可以,而且還有套裝及插卡方面的設定,還會
有依精鍊值做額外屬性加成的設定,因此我會一併考慮精鍊是否額
外儲存 refine_stat 的問題。
我的思維是,假設做額外儲存,那直覺上會有幾個問題:
1.如果我改變精鍊規則,我很難去更動之前已被玩家精鍊的物品
2.若不存這個欄位,我怎麼解決載入時的 loading 問題
3.我將來要怎麼去統一管理這些已經被精鍊的物品的refine_stat
儲存值
1 的部份就是說,比方我原先訂 +1 就是該武防各屬性 +5,那後來
我覺得 +5 太多了想改 +3 時,玩家之前已精鍊的東西我就得做額
外的處理(把那些 +5 改成 +3)。
而既然以後可能會有這個問題,那還不如在 loading 時就處理:
ob=clone_object(files);
foreach(str in keys(obj_data[files]))
{
ob->set(str,obj_data[files][str]);
switch(str)
{
case "refine_lv":
lv=obj_data[files][str];
ob->set("refine_stat",lv*5);
.
.
上面的意思就是說我只儲存 refine_lv,而當玩家登入時,我再依該
物品的 refine_lv 值,來設定 refine_stat 的值是多少;玩家save
或是把該物品儲放進倉庫時,只存 refine_lv 不存 refine_stat,也
就是上述的最少設定(儲存)項目,而上面的 switch..case.. 用來做
為額外的處理。
那麼 coding 常遇到的情況就是
當我們儲存的項目越多時 就可以減少很多額外的處理
當我們儲存的項目很少時 就需要很多其它額外的處理
例如我們只單存一個 refine_lv 時,就可以想見在很多地方都需要先
讀取出這個值,然後再做額外的運算來得到其它我們想要的東西,例
如 refine_stat、refine_name、.... 等等。
通常根據均值定理,可得出一個適當的儲存項目數量,使得儲存的項
目不至於過多,且不會增加很多需做的額外處理。
但是根據經驗,其實還有另一種做法,就是 RO 所採取的額外描述法
例如 RO 的蛇披,它的 Special DEX 部份是這麼說的
https://upload.8591.com.tw/ware/201905/1557133186868273AY.png
Dex+1
精鍊值+8時Dex+3
當精鍊值+9時MATK+1%
當精練值+12時ASPD+1,固定詠唱時間-7%
也就是說,玩家登入或從倉庫拿出此物品時,只載入 refine_lv 的設
定值,但是當玩家做 wear 或 wield 時,才做以下的動作:
lv=ob->query("refine_lv");
switch(lv)
{
case 1..7: ob->add("stat/dex",1);
case 8 : ob->add("stat/dex",3);
.
.
}
而其它時候,比方玩家 view 該物品時,只會看到上面的「描述」,以
及該物品的精鍊值,既然玩家只有在做 wear 及 wield 時,該精鍊值才
會有作用,那自然只需在玩家 wear 及 wield 時做相關的處理就好。
我相信 RO 也是這樣做的,所以它們才會規定物品在手持或穿戴時無法
精鍊,必須先脫下來才行。
因此理論上,只儲存 refine_lv 值應該是可以的。
而這可以帶來幾個好處:
一、refine_lv 這個儲存欄位的變動性不高,應該確定就是這個欄位,
連同精鍊指令也可以順便定為 refine。
二、之後可以只先處理 wield/wear 指令,馬上就能進行相關測試,例
如穿脫時的玩家屬性變化、quit/login 時是否正常載入等。
三、再之後才是其它與觀看該物品相關的指令,例如 inventory、look
、view、auc、.....等。
精鍊名稱的部份,最直覺是以下的顯示:
+0時: 羅德斯長劍(lodoos sword)
+9時: +9羅德斯長劍(lodoos sword)
然後最優先考量是戰鬥時,是否希望+9出現:
你以手中的羅德斯長劍刺向小麻雀
你以手中的+9羅德斯長劍刺向小麻雀
看起來好像讓 +9 出現也不錯?當然這與各家 mud 風格有關且因人而
異。
其它的話問題就小一點,如果希望到處都能帶 +9,那麼在載入時就做
處理是比較好的:
foreach(str in keys(obj_data[files]))
{
ob->set(str,obj_data[files][str]);
switch(str)
{
case "refine_lv":
lv=obj_data[files][str];
if(lv>0)
{
shorts=ob->query("short");
ob->set("short",sprintf(HIG"+%d"NOR"%-s",lv,shorts));
.
.
這樣它就到處帶 +9 時,那萬一玩家將 +9 精鍊成 +10 呢,也很簡單
因為它格式是固定的:
shorts=ob->query("short");
lv=ob->query("refine_lv");
shorts=replace_string(shorts,"+"+lv,"+"+(lv+1));
因為 +n 這個東西在物品的 short 只會出現在精鍊識別名稱區塊,平
常不可能有精鍊值為 0 的物品,其名稱會帶 +n 的,就容易做名稱上
的取代。
有時間再打點別的回在下篇。
作者: tsetsethatha (吉星麥造~~~我來了)   2020-05-21 12:20:00
感謝發文 !!

Links booklink

Contact Us: admin [ a t ] ucptt.com