iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 19
2

https://ithelp.ithome.com.tw/upload/images/20191002/20115823Y7DEiFpd2o.png

延續前一天,我們今天來說明另外兩種配方的功能:

  • 燒煉(Smelting):將一個物品或方塊變成另一個物品或方塊
  • 釀造(Brewing):用來製作藥水

燒煉

燒煉(或熔煉)可以透過熔爐將輸入的物品材料,輸出成另一個物品。

我們等等要做的是將糖作為輸入材料,可以燒煉出我們的白色小藥丸。

  1. 一樣,凡是要增加配方一定都是到主程式的FMLInitializationEvent事件處。請加上以下這段程式碼:
    GameRegistry.addSmelting(
        Items.sugar,
        new ItemStack(pillItem, 1),
        1.0f
    );
    
    第一個參數是輸入材料:可以是Item, BlockItemStack;這裡我們用糖這個物品。
    第二個參數是輸出物品:必須是ItemStack,所以我們可以指定輸出的數量;這裡我們產生1個藥丸物品。
    第三個是經驗值:燒煉可以獲得的經驗值;這裡我們設定為1經驗值。
  2. 存檔進入遊戲,現在煉製糖也可以獲得藥丸啦!
    https://ithelp.ithome.com.tw/upload/images/20191002/20115823BMvpxXbozO.png

如何,很簡單吧?

釀造

釀造是我覺得三種配方中程式碼寫的最複雜的地方...但它本身的功能並不難使用。

釀造的功能裡,我們可以透過釀造台來製作各種不同效果的藥水。

這邊我們將藥丸可以當作釀造的材料,製作加速的藥水吧!

  1. 請直接到主程式的FMLInitializationEvent事件方法內,加上:
    pillItem.setPotionEffect(PotionHelper.sugarEffect);
    
    讓藥丸可以擁有釀造配方sugarEffect;即可以製作出迅捷藥水。
  2. 存檔進入遊戲,現在藥丸跟糖一樣,都可以製作出迅捷藥水了!
    https://ithelp.ithome.com.tw/upload/images/20191002/20115823mSmD97Qbaq.png

到這邊釀造的功能就講完了...一半。


setPotionEffect()方法

還記得我們在[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這個類別,因此我們會有兩個同名(也就是多載)方法:

  1. public ItemFood setPotionEffect(int id, int duration, int amplifier, float probability)
  2. public Item setPotionEffect(String potionEffect)

雖然這兩個是同名的方法,但實際的內部邏輯是不一樣的:

  1. 這個方法是只有繼承ItemFood類別,並且是設定在吃下這個食物時會產生什麼樣的藥水效果
  2. 這個方法是繼承Item類別,並且是設定這個物品可以釀造成什麼效果的藥水

不得不說,Minecraft的相關說明文件真的相當的少...

PotionHelper類別

關於藥水的製作效果,還有另外幾點需要注意的:

  1. 所有的藥水效果與對應ID都會定義在net.minecraft.potion.Potion這個類別內,以目前這邊所述的Forge版本(1.8),可以用的效果會對應官方數據值的1-23項。

  2. net.minecraft.potion.PotionHelper這個類別內,有定義了各種不同的藥水效果,這些藥水效果通常會直接在變數名稱上就可以看出來它實際是對應哪一種釀造藥水的效果,比如說:

    • sugarEffect(-0+1-2-3&4-4+13) : 糖的效果,對應的就是透過糖 + 藥水瓶釀造來取得迅捷藥水。
    • spiderEyeEffect(-0-1+2-3&4-4+13) : 蜘蛛眼效果,對應的就是蜘蛛眼 + 藥水瓶釀造來取得的劇毒藥水。

    那這裡的數字又是代表什麼含意呢?

    先不看特殊符號+, -, &
    數字部分0-3代表的是我要透過什麼樣的組合對應到特定的藥水效果
    &這個符號用來串接藥水效果與附加功能;
    +, -的符號用來表示"後面接著的數字"是要增加/減少此項功能;
    數字部分4-15代表的是這個藥水效果的額外附加功能

    • 5 : 提升1等級
    • 6 : 延長時間
    • 13 : 可以變成飛濺藥水
    • 14 : 這個是飛濺藥水
    • 其餘可以忽略

    所以
    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));
                }
            }
        }
    }
}

上一篇
[Day18] Minecraft玩家一定要會的 - 合成
下一篇
[Day20] 重新開始
系列文
[Minecraft - 當個創世神] 從玩遊戲到設計遊戲30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
b4106702
iT邦新手 5 級 ‧ 2019-10-05 23:10:54

用datapack的自定義合成能運用在你創造的物品嗎?

PS. 這邊是我參考書本與自己琢磨程式碼……

好奇你是看那些書?

書的話只有第一天提到的O'REILLY出的「Minecraft模組設計」這本書,而剩下的部分就看Forge程式碼自己研究XD

我要留言

立即登入留言