用戶:Luoboju0/Sandbox

出自Minecraft Wiki
跳至導覽 跳至搜尋

數據儲存[編輯 | 編輯原始碼]

本章將討論或解決如下問題:

  • 取得任意命令的回饋參數。
  • 在退出遊戲或卸載數據包後數據仍然存在並可恢復。
  • 加入自訂的數據。

對於任意命令,都可以使用/execute store儲存其某個回饋參數值。但要注意,對於同一個命令,並不是其所有參數都能被取得。具體能夠被儲存的參數內容應該參考相應命令頁面的「輸出」章節。

比如,對於命令/random,你可以通過execute store儲存其抽取的隨機值。取得參數值後,你可以儲存到某個實體或虛擬玩家的計分板目標中,也可以儲存到命令容器中。

  • 如果你接下來即將對取得的值進行大量運算,一般選擇儲存到計分板目標中。
  • 如果是為了備用或者傳遞到巨集函數中,則應儲存到命令容器。

值得注意的是,所回饋的參數值將先被向下取整後再進行儲存——這將導致浮點數的小數位丟失。比如,對於以下的命令容器:

{test: 123.123456d, v: 0}

以下命令執行後:

execute store result storage generic:test v double 1.0 run data get storage generic:test test

命令容器將變為:

{test: 123.123456d, v: 123.0d}

顯然,如果想保留數據的完整形式,最好直接使用/data modify命令:

data modify storage generic:test v set from storage generic:test test
{test: 123.123456d, v: 123.123456d}

你可能想到,/execute store可以對取得的結果數據按倍數放大或縮小,那麼為何不能執行如下命令:

execute store result storage generic:test v double 0.000001 run data get storage generic:test test 1000000

如上所示,表面上看起來是:先放大到原來的1000000倍,這樣能夠取到整數123123456,然後再縮小相應倍數,理應得到123.123456,但是由於浮點數再電腦內的儲存並非是精確的,其總是可能在尾數部分產生誤差,所以實際得到的結果可能為:

{test: 123.123456d, v: 123.12345599999999d}

總的來説,對於浮點數,如果希望保留原始精度,最好使用data命令。當然,如果你希望使用一條命令對取得的NBT數據進行縮放並儲存,那麼用execute store也沒什麼問題。

其實,如果你認真接觸過data ... storage命令,你會發現命令容器很容易實現我們開頭提到的第二個問題。對於命令容器中的數據,你可以將其當成屬於存檔的「全局數據」。在儲存遊戲後,它將以.dat檔案的形式儲存在存檔的data目錄中,你也可以使用一些軟件來查看其中的數據。

有時候,我們在一個命令容器中儲存了大量數據,想要全部刪除,那麼你可以通過打開存檔的.dat檔案並直接刪除對應命令容器的子標籤。具體的檔案格式可以參考命令容器儲存格式。只要存檔是完整的,那麼你就可以通過/data ... storage命令來訪問命令容器的數據。

全局數據是容易操作的,但是如果把全部數據都存在命令容器中,這無疑會造成空間浪費以及數據管理上的困難。很多時候,我們希望對指定的遊戲對象加入數據,比如,我們在遊戲中使用鐵錠模擬一個特殊的貨幣,但存在一個問題:玩家可以直接合成鐵錠。為了讓原版的鐵錠特殊化,我們可以利用custom_data元件來儲存一系列自訂的數據。

比如,執行如下命令後:

/give @s minecraft:iron_ingot[minecraft:custom_data={id:"test:iron_twist_egg_coin"}]

該鐵錠的minecraft:custom_data元件中便擁有一個新增的字串id字段。

在數據包中,可以使用物品修飾器將數據定義分離出來:

[
  {
    "function": "set_components",
    "components": {
      "custom_data": {
        "custom_item": true,
        "id": "lbj:straw_hat"
      },
      "item_model": "lbj:straw_hat",
      "item_name": "草帽",
      "equippable": {
        "slot": "head"
      }
    }
  }
]

數據傳遞[編輯 | 編輯原始碼]

巨集函數的參數傳遞

巨集函數允許接收傳入的數據,並直接轉換為命令的影響和作用。從這個方面來説,巨集函數中的命令也可以被稱為「動態命令」。

在1.21.5引入SNBT的16進制等新形式後,其實傳遞到巨集函數的結果並沒有改變——數值型數據依然以十進制數被傳遞到宏行參數。

比如,有以下巨集函數:

File file.png:Minecraft中file的精靈圖 test:test
mcfunction
$say $(value)

執行以下命令:

/function test:test {value:0xABCL}

輸出的結果為2748,非所期望的十六進制形式。

對於新手,需要注意所傳遞的數據並非是所看到的SNBT形式(例如上例中並沒有保留長整型類型尾綴)。以下為傳遞字串和傳遞複合標籤結構的例子。先執行如下命令:

/function test:test {value:"test"}

字串的左右引號並不會被保留。而如果改為:

/function test:test {value:{a: 1, b:"hi"}}

則會保留左右花括號,輸出「{a: 1, b:"hi"}」。

傳遞物品數據資訊到資源包

物品模型映射類型range_dispatch可以為custom_model_data中的不同值分配不同的模型,這可以用來實現物品模型動畫幀。

物品模型映射也可呼叫數據元件述詞來條件性地篩選元件數據並顯示不同模型。

另外,對於一些命令無法操作和訪問的數據(比如物品的模型變換位置)也能通過物品模型映射進行判斷和選定。

傳遞物品資訊到實體

生成蛋、生物桶等能夠生成實體的物品,會在被使用時複製一些數據到所生成的生物。利用這個特點,我們可以將物品的自訂數據複製到實體的自訂數據中,隨後通過其他方式變換到實體上下文,並在函數中繼承該上下文。

數據操縱[編輯 | 編輯原始碼]

數據的基本操作:增加、修改、可以通過命令/data modify/data merge實現,數據的刪除可以通過/data remove實現。

從數據結構的角度來説,這些操作無非是對於SNBT背後的抽象NBT結構樹的節點的修改的刪除。

對於2類基本的數據操縱對象:實體、物品,有不同的數據操縱方式。

實體

實體可以大致分為

  • 玩家實體。
  • 除玩家實體以外的實體。

玩家實體的特殊性在於,玩家本身的NBT操作是受限的,一般只能通過其他命令來間接實現數據操縱。以下列出幾種常見情況:

  • /tp/rotate命令可以實現類似於對玩家雙精確度浮點數Pos單精確度浮點數Rotation的直接修改操作。
  • 在玩家腳部創造爆炸可以模擬對玩家雙精確度浮點數Motion的修改操作。
  • /item命令可以實現對玩家背包數據NBT複合標籤/JSON物件Inventory的修改。
物品

一般地,無論是存在於實體還是方塊容器內的物品,都可以通過/item進行修改。

  • 可以呼叫提前制定的物品修飾器進行修改。
  • 也可以配合巨集函數,呼叫內聯SNBT形式的物品修飾器,傳入需要動態修改的數據。

由於物品的很多行為都由數據元件定義,所以對於物品數據的動態操作,也可歸結為使用巨集函數動態執行set_components物品修飾器的過程:

File file.png:Minecraft中file的精靈圖 generic:data/set_slot_components
mcfunction
$item modify entity @s $(slot) {function:"set_components", components:$(components)}

可用物品堆疊元件[編輯 | 編輯原始碼]

在遊戲中總共定義了下列物品堆疊元件:

基本
外觀
附魔
使用
物品損傷、物品修復
雜項
數據儲存
生成蛋、桶裝生物
非持久化元件

creative_slot_lock:不可以匯出和載入,僅網絡同步

  • 應用對象:所有物品。
  • 在創造模式儲存的物品欄中擁有此元件的物品將無法互動,但仍可通過快捷鍵儲存或載入到快捷欄,除此之外與正常物品沒有區別
    預設附加到「已儲存的快捷欄」中代表沒有快捷欄資訊的

map_post_processing:不可以匯出和載入,僅網絡同步

  • 應用對象:地圖。
  • 同步地圖的縮放等級和鎖定資訊。