前往
大廳
主題

【資料包工具箱】「獲得N種指定道具」的成就

| 2024-02-21 13:15:24 | 巴幣 12 | 人氣 172

最近想想好像該來開個工具箱系列,放一些資料包的實際應用。
以前寫那些都偏理論,沒有用根本沒有用

前提知識
自訂進度檔案 (wiki)
自訂函數檔案 (wiki)
計分板基礎操作 (wiki)
※ 這是內容比較完整的英文wiki連結,有語言選單能自己調成中文。

簡介
遊戲中偶爾會設計收集類的成就。
像是原版的「獲得鑽石」(鑽石!)、「馴服所有種類的貓」(貓科全書)。
或是做迷宮地圖的人會想放類似「收集3種寶石」的成就。

獲得一種物品
原版「獲得鑽石」這樣的基本款。
關鍵是設定inventory_changed條件,偵測玩家背包中有沒有指定物品。
實在不會的話,可以去拆原版的「鑽石!」進度檔來參考。

所有指定種類的物品
例如「收集3種寶石」,而且寶石剛好有3種,也就是需要全拿的成就。
一般而言,收集類成就的機制會是圖鑑制度的「曾經分別取得過每種物品」。
但是也有少數時候會想要「所有物品同時放在背包裡」。
兩個機制各自有適合的場合,設計的時候可以思考看看哪一個比較合理。

◆ 「所有物品同時在背包裡」
和單一物品的設定很像,只要微調conditions中的items清單,列舉每一個物品就完成了。
注意事項

"conditions": {
  "items": [ 這個清單 ]
}

而不是
"conditions": {
  "items": [
    { "items": [ 這個清單 ] }
  ]
}

◆ 「曾經分別取得過」
需要為每一個物品分別設定一個條件
條件的概念類似「隱藏的小成就」,當所有小成就解鎖之後,玩家就會解鎖進度。

條件的設定寫在criteria,幫每一個物品各自設定一個inventory_changed條件。
這些條件的ID可以隨便取,但為了幾個月後修改檔案的自己著想,建議用有意義的詞,像是每個成就道具的名字。
進度檔的requirements會決定條件之間的關係,可以完全不設定,讓遊戲用預設的「每一個條件都要完成」。
注意事項
「完全不設定」的意思是requirements不存在,
而不是像這樣的空清單:
"requirements": []

補充資料
「完成所有條件」也可以明確指定,例如:
"requirements": [ ["diamond"], ["emerald"], ["ruby"] ]

部分指定種類的物品
例如「收集3種寶石」,但寶石有5種,也就是只要拿一部分就能解的成就。
有兩種不同的方法可以做到,一般來說會用計分板輔助,不過也存在用單一進度檔寫的方法。

◆ 計分板輔助的進度
上面說過進度條件的概念類似「隱藏的小成就」。
這裡要把這些「隱藏的小成就」實際寫出來,從條件變成一整批獨立的進度檔。
原本的進度剩下單純的顯示作用,只需要設定一個impossible條件留給指令觸發。

每一個隱藏進度負責偵測一種物品,所以會回歸到「鑽石!」那種基礎的設定。
隱藏進度不需要對玩家展示,所以不設定display資料。
接著,把每一個隱藏進度的rewards設定成同一個指令函數。

進度獎勵函數負責把玩家的收集分數加1,並且在收集分數達標後,用advancement指令觸發顯示用的主要進度。
在進度獎勵函數中,可以用@s指定獲得進度的玩家,所以加分和給予主進度都很容易達成。
補充資料
參考答案:
scoreboard players add @s gem_collection 1
execute if score @s gem_collection matches 3.. \
run advancement grant @s only custom:collect_3_gems

後兩行是分行語法,避免一條指令看起來太寬,對執行沒有影響。
從1.20.2開始有這個語法,可以善加利用。

◆ 用單一進度檔硬凹
進度的requrements是兩層清單,外層執行And邏輯,內層執行Or邏輯。
例如[[A], [B, C]]代表「一定要達成A,且B和C要達成至少一個」。

5選3要寫在這個結構內,比較方便的思考方式是先列舉不符進度條件的狀況,也就是「至少有3個還沒拿到」。
列舉的結果會是「外層Or、內層And」的結構,像是:
「沒有A、B和C」或「沒有A、B和D」或…
這就是答案了,直接把這個組合原狀填進requirements裡面。
補充資料
5選3會讓人混淆(剛好排除掉的數量也是3),
所以下面是5選4的條件設定範例。
"requirements": [
  ["onyx", "pearl"],
  ["onyx", "topaz"],
  ["onyx", "sapphire"],
  ["onyx", "ruby"],
  ["pearl", "topaz"],
  ["pearl", "sapphire"],
  ["pearl", "ruby"],
  ["topaz", "sapphire"],
  ["topaz", "ruby"],
  ["sapphire", "ruby"]
]

不太好看,也不算很好維護。
沒有什麼特殊堅持的話,拜託改用計分板。
原理是把不符條件反轉成符合條件,然後用笛摩根定理調整條件邏輯。
無法理解原理也沒關係,總之這麼做有用。

修理一下計分板輔助進度
讓And邏輯在requirements外層是有理由的。
遊戲內會顯示進度的完成度,例如「貓科全書 (0/11)」,偵測的就是這堆And條件的完成度。
但是上面「收集部分物品」的兩種做法都沒有正確顯示完成度。
排除掉沒救的單檔案版本,有計分板輔助的版本應該要補上完成度才對。

做法是把唯一一個impossible條件改成「用數字編號的很多個impossible條件」,像是c_1c_2等。
然後在加分之後,用function macro給予對應的條件。
補充資料
實際寫起來會像是這樣:
execute store result storage custom:gem_count progress int 1 \
run scoreboard players add @s gem_collection 1
function custom:gem_advancement with storage custom:gem_count

被呼叫的檔案:
$advancement grant @s only custom:collect_3_gems c_$(progress)
會有分數破表導致找不到條件的情況,不過沒關係,那行指令執行失敗不會怎樣。

創作回應

更多創作