新的合成表
在這之前,合成表使用 GameRegistry.addShapedRecipe()
創建,但從 1.12 開始,Minecraft 使用 json 文件創建合成表。Forge 會自動加載在 resources/assets/mymod/recipes/ 下的 json 合成表文件。現在我們來給之前的 Cross Block 創建合成表。
有序合成表
新建目錄 resources/assets/mymod/recipes/,新建文件 cross_block.json,文件名無所謂,使用對應產物的名字比較方便。里面寫入:
{
"type": "minecraft:crafting_shaped",
"group": "mymod:cross",
"pattern": [
"A B",
" C ",
"B A"
],
"key": {
"A": {"item": "minecraft:redstone"},
"B": {"item": "minecraft:sugar"},
"C": {"item": "minecraft:dirt","data": 0}
},
"result": {"item": "mymod:cross_block","count": 1}
}
-
type 分為有序合成
minecraft:crafting_shaped
和無序合成minecraft:crafting_shapeless
-
group 合成分組,比如各種顏色的床屬於同一組,它們的合成表會合並在一起,可省略
-
pattern 有序合成時的材料順序,排成兩行或三行,用空格表示空,隨便一種字母/符號表示一種材料
-
key 規定 pattern 中自定義字母代表的材料,如果限定 meta 信息,需要使用 data 鍵。例如,原版的各種台階是一個方塊的不同 meta 信息的結果,設置了 data 鍵后,只有特定的台階才能參與這個合成,否則任何台階均可參與合成。
-
如果有替代材料,使用列表形式,如:
"key": { "A": [{"item": "minecraft:redstone"}, {"item": "minecraft:sugar"}] }
-
result 產物,但有 meta 信息的產物 data 鍵是必須的
-
count 產物數量,默認為1,可省略
無序合成表
我們再給鐵板添加無序合成表:
新建文件 iron_plate.json,寫入:
{
"type": "minecraft:crafting_shapeless",
"result": { "item": "mymod:iron_plate", "count": 18 },
"ingredients": [
{ "item": "minecraft:iron_block" },
{ "item": "minecraft:iron_block" }
]
}
- ingredients 用於無序合成的原料設置
- 其他比如 result/type/group/count 同上
新的燒煉規則
Forge 並沒有統一的把各種 recipe 整合到一起,燒煉規則仍然使用 GameRegistry 來添加。在 common 包中新建 Recipes.java,統一管理燒煉和燃料:
public class Recipes {
public Recipes(){
GameRegistry.addSmelting(BlockLoader.cross, new ItemStack(Items.IRON_AXE), 0.5F);
}
}
這里我們設置了一個奇怪的規則:Cross Block 燃燒生成鐵斧。
CommonPorxy.java 的 init()
中添加:
new Recipes();
在 GameRegistry.addSmelting(input, output, exp)
中
- input 可以是 Block/Item/ItemStack
- output 是一個 ItemStack
- exp 是燒煉后獲得的經驗值。具體數值大概沒必要計較,原版的數值設定參照 net/minecraft/item/crafting/FurnaceRecipes.java
新的燃料
之前,燃料需要使用 FurnaceRecipes 類管理,不過現在,Forge 將燃料問題整合成了一個事件,修改 Recipes.java 為:
@Mod.EventBusSubscriber
public class Recipes {
public Recipes(){
GameRegistry.addSmelting(BlockLoader.cross, new ItemStack(Items.IRON_AXE), 0.5F);
}
@SubscribeEvent
public static void getVanillaFurnaceFuelValue(FurnaceFuelBurnTimeEvent event) {
if(event.getItemStack().getItem() == Item.getItemFromBlock(BlockLoader.cross)){
event.setBurnTime(200);
}
}
}
- 當有物品嘗試放進燃料槽時觸發這個事件
event.getItemStack().getItem()
放進去的物品,物品可以直接使用 instanceof 判斷物品種類,方塊可以用Item.getItemFromBlock()
來判斷event.setBurnTime()
用於設置燃燒時間,設置0表示不是燃料,設置為-1表示根據原版內容判斷(默認)- 經查看源碼發現,Minecraft 設定的值中,原版的煤是16000,燒8個物品,也就是說燒1個物品為200,這樣就可以根據需要進行設置了。
- 當然也提供了
event.getBurnTime()
獲取當前設置的燃燒時間 - 原版的燃料燃燒時間參照 net/minecraft/tileentity/TileEntityFurnace.java 的
getItemBurnTime()
(353行)