延續前一天,我們今天來說明另外兩種配方的功能:
燒煉(或熔煉)可以透過熔爐將輸入的物品材料,輸出成另一個物品。
我們等等要做的是將糖作為輸入材料,可以燒煉出我們的白色小藥丸。
FMLInitializationEvent
事件處。請加上以下這段程式碼:
GameRegistry.addSmelting(
Items.sugar,
new ItemStack(pillItem, 1),
1.0f
);
第一個參數是輸入材料:可以是Item
, Block
或ItemStack
;這裡我們用糖這個物品。ItemStack
,所以我們可以指定輸出的數量;這裡我們產生1個藥丸物品。如何,很簡單吧?
釀造是我覺得三種配方中程式碼寫的最複雜的地方...但它本身的功能並不難使用。
在釀造的功能裡,我們可以透過釀造台來製作各種不同效果的藥水。
這邊我們將藥丸可以當作釀造的材料,製作加速的藥水吧!
FMLInitializationEvent
事件方法內,加上:
pillItem.setPotionEffect(PotionHelper.sugarEffect);
讓藥丸可以擁有釀造配方sugarEffect
;即可以製作出迅捷藥水。到這邊釀造的功能就講完了...一半。
還記得我們在[Day17]有一段程式碼:
// 設定藥丸的效果:食用後可以產生移動加速III的效果、持續60秒
this.setPotionEffect(Potion.moveSpeed.getId(), 60, 2, 1.0f);
上面這段程式碼與我們剛剛的程式碼:
pillItem.setPotionEffect(PotionHelper.sugarEffect);
看起來很像,但兩者是完全沒有任何關係的!
(動手試看看:可以試著將PillItem
內的setPotionEffect(Potion.moveSpeed.getId(), 60, 2, 1.0f)
改為setPotionEffect(PotionHelper.sugarEffect)
看看會發生什麼事?)
為什麼呢?
在Java內有一個功能叫做多載/重載(Overload)方法的功能:你可以定義同樣的方法名稱在同一個類別裡,只要參數的型態或個數不同就可以了。
在我們PillItem
類別內,由於我們繼承的是ItemFood
這個類別,因此我們會有兩個同名(也就是多載)方法:
public ItemFood setPotionEffect(int id, int duration, int amplifier, float probability)
public Item setPotionEffect(String potionEffect)
雖然這兩個是同名的方法,但實際的內部邏輯是不一樣的:
ItemFood
類別,並且是設定在吃下這個食物時會產生什麼樣的藥水效果
Item
類別,並且是設定這個物品可以釀造成什麼效果的藥水
不得不說,Minecraft的相關說明文件真的相當的少...
關於藥水的製作效果,還有另外幾點需要注意的:
所有的藥水效果與對應ID都會定義在net.minecraft.potion.Potion
這個類別內,以目前這邊所述的Forge版本(1.8),可以用的效果會對應官方數據值的1-23項。
在net.minecraft.potion.PotionHelper
這個類別內,有定義了各種不同的藥水效果,這些藥水效果通常會直接在變數名稱上就可以看出來它實際是對應哪一種釀造藥水的效果,比如說:
那這裡的數字又是代表什麼含意呢?
先不看特殊符號+, -, &
,
數字部分0-3
代表的是我要透過什麼樣的組合對應到特定的藥水效果;&
這個符號用來串接藥水效果與附加功能;+, -
的符號用來表示"後面接著的數字"是要增加/減少此項功能;
數字部分4-15
代表的是這個藥水效果的額外附加功能
其餘可以忽略
所以sugarEffect(-0+1-2-3&4-4+13)
表示
我要產生(-0+1-2-3)的效果,寫成Java邏輯判斷,即**!0 & 1 & !2 & !3** (這邊的驚嘆號與-
這個符號同意思 : 表示減少此功能)
回到PotionHelper
的程式碼,在最後面可以找到
potionRequirements.put(Integer.valueOf(Potion.moveSpeed.getId()), "!0 & 1 & !2 & !3 & 1+6");
後面的&1+6
不要看,前半段是不是與我們剛剛描述的一樣?所以這個sugarEffect
代表的就是Potion.moveSpeed
- 迅捷藥水
而sugarEffect剩下的&4-4+13
部分,+13
就是增加可以變成飛濺藥水的功能,4-4
這部分被忽略了,我也不清楚它的用意...
這裡舉一反三,piderEyeEffect(-0-1+2-3&4-4+13)
就是代表:
劇毒效果(potionRequirements.put(Integer.valueOf(Potion.poison.getId()), "!0 & !1 & 2 & !3 & 2+6");
),並且增加可以變成飛濺藥水。
你問我為什麼這麼無聊要去研究這段程式碼?
因為,身為工程師,凡事都要有實事求是的精神...
PS. 這邊是我參考書本與自己琢磨程式碼而來的,如果有誤歡迎指正。
同場加映:感謝看到這裡的你,如果你有興趣,這邊附上一開頭那張圖片的效果程式碼:
public class PillItem extends ItemFood {
public PillItem() {
// 藥丸造成的飢餓值補充為1,而且此食物不能為狼所食用
super(1, false);
this.setUnlocalizedName("pillItem");
// 任何情況都可以食用
this.setAlwaysEdible();
}
@Override
protected void onFoodEaten(ItemStack stack, World worldIn, EntityPlayer player)
{
if (!worldIn.isRemote) {
List<Integer> includes = new ArrayList<Integer>();
includes.addAll(Arrays.asList(1, 3, 5, 6, 8, 10, 11, 12, 13));
Potion[] potions = Potion.potionTypes;
for (Potion potion : potions) {
if(potion != null && includes.contains(potion.getId())) {
player.addPotionEffect(new PotionEffect(potion.getId(), 20 * 20, 2));
}
}
}
}
}
用datapack的自定義合成能運用在你創造的物品嗎?
PS. 這邊是我參考書本與自己琢磨程式碼……
好奇你是看那些書?
書的話只有第一天提到的O'REILLY出的「Minecraft模組設計」這本書,而剩下的部分就看Forge程式碼自己研究XD