Minecraft 1.12.2 Mod開發筆記——新的附魔類型和狀態效果(葯水)


總目錄:Minecraft 1.12.2 開發筆記

新的附魔

我們試着給劍創建一個叫引爆的附魔。

在 moonfan.mymod.enchantment 包下新建類 EnchantmentIgnite.java

public class EnchantmentIgnite extends Enchantment {
    protected EnchantmentIgnite() {
        super(Rarity.COMMON, EnumEnchantmentType.WEAPON, new EntityEquipmentSlot[]{EntityEquipmentSlot.MAINHAND});
        // 設置非本地化名稱
        this.setName("ignite_enchantment");
    }
}

來看構造器

protected Enchantment(Enchantment.Rarity rarityIn, EnumEnchantmentType typeIn, EntityEquipmentSlot[] slots)

  • rarityIn 枚舉類,表示附魔的稀有程度,有 COMMON、UNCOMMON、RARE 和 VERY_RARE 四種。
  • typeIn 枚舉類,表示可以接收該附魔的物品種類,有 ALL、WEAPON、ARMOR 等多種類型。
  • slots 枚舉類數組,表示被附魔的物品處於何種狀態時附魔生效,有 MAINHAND、OFFHAND、FEET、LEGS、CHEST、HEAD 六種。

附魔和物品一樣需要注冊:

public class EnchantmentLoader {
    public static Enchantment ignite = new EnchantmentIgnite();

    @SubscribeEvent
    public static void registerEnchantment(RegistryEvent.Register<Enchantment> event){
        event.getRegistry().register(ignite.setRegistryName("mymod:ignite_enchantment"));
    }
}

en_us.lang:

enchantment.ignite_enchantment=Ignite

現在,可以通過 /give 命令或者附魔台得到帶有這個附魔的劍了。但附魔本身只規定種類,並不規定其效果,效果的實現需要在需要的地方添加,比如時運和精准采集的效果其實是在 Block 類里判斷方塊掉落的時候添加的。在進階部分再作說明。

新的狀態效果(葯水)

Minecraft 中,狀態效果和葯水是兩個概念,喝了葯水可以出現狀態效果,而有狀態效果不一定要有對應的葯水,比如飢餓效果、凋零效果。

我們先創建一個叫類似於中毒的持續扣血效果。

在 moonfan.mymod.potion 包下新建類 PotionInjure.java

public class PotionInjure extends Potion {
    protected PotionInjure() {
        super(true, 0xffffff);
        // 這里是設置的是實際的名稱,不是非本地化名稱
        setPotionName("injured");
    }
}

構造器 protected Potion(boolean isBadEffectIn, int liquidColorIn)

  • isBadEffectIn 是否是負面效果
  • liquidColorIn 狀態效果的氣泡以及葯水瓶(如果有)的RGB顏色值,比如0xffffff

狀態效果和物品一樣需要注冊:

@Mod.EventBusSubscriber
public class PotionLoader {
    public static Potion injure = new PotionInjure();
    @SubscribeEvent
    public static void registerPotion(RegistryEvent.Register<Potion> event){
        event.getRegistry().register(injure.setRegistryName("mymod:injure"));
    }
}

現在,我們可以用命令 /effect 玩家名 mymod:injure 120 0 來給自己加上Ⅰ級,持續時間120s的 injured 效果了,不知道 harbinger 的教程里是不是把命令打錯了。。

葯水類型

前面說過,狀態效果和葯水是兩回事,當創建了葯水類型后,創造模式葯水欄里將會自動添加該葯水類型的普通型/噴濺型/滯留型的葯水瓶武器欄里會自動添加對應效果的弓箭。喝下一種葯水可以獲得多種狀態效果,因此葯水類型可以接收多個狀態效果參數:

在PotionLoader里添加事件:

@SubscribeEvent
public static void registerPotionType(RegistryEvent.Register<PotionType> event){
    event.getRegistry().register(new PotionType(new PotionEffect(injure, 600, 0)).setRegistryName("mymod:injuring"));
}

其中葯水類型的構造器,亂七八糟的變量名大概是MCP項目沒有翻譯出來?

public PotionType(@Nullable String p_i46740_1_, PotionEffect... p_i46740_2_)
public PotionType(PotionEffect... p_i46739_1_)
  • String 類型的參數可以省略,相當於非本地化名稱,如果省略或者填 null,自動用注冊名作為非本地化名稱。
  • PotionEffect 類型的參數是一個可變長參數,代表葯水觸發的一個或多個狀態效果。

狀態效果實例的構造器 public PotionEffect(Potion potionIn, int durationIn, int amplifierIn)

分別表示狀態效果類型、持續游戲刻數、葯水等級(0為Ⅰ級),可省略后兩個參數(默認為0)。其中 Minecraft 中每秒20刻。

由於有普通型/噴濺型/滯留型三種葯水瓶以及葯水效果的弓箭,非本地化鍵也相應的有 potion.effect./splash_potion.effect./ingering_potion.effect./tipped_arrow.effect. 四個前綴,也就是說創建一個葯水類型,在.lang語言文件里要寫四條翻譯文本。

添加狀態效果的實際作用

和附魔不太一樣的地方,狀態效果並不全都需要在需要的事件監聽里獨立寫邏輯。總結一下,狀態效果有三大類:

  • 修改狀態屬性類,比如遲緩/失明/挖掘疲勞/急迫等等,這些是一種對生物自身屬性的更改,在構造器里使用 this.registerPotionAttributeModifier()

    public Potion registerPotionAttributeModifier(IAttribute attribute, String uniqueId, double ammount, int operation)
    
    • attribute 修改的生物自身屬性,可使用 SharedMonsterAttributes 類中的字段
    • uniqueId UUID,暫不清楚,參考原版 net/minecraft/potion/Potion.java (432行) 中寫的的參數。
    • ammount 調整數量,比如-1.0D
    • operation 暫不清楚,參考原版 Potion 類中寫的的參數。
  • 周期性效果類,比如中毒/凋零,這樣的狀態效果通過重寫 performEffect()isReady() 實現:

    @Override
    public void performEffect(EntityLivingBase entityLivingBaseIn, int amplifier) {
        entityLivingBaseIn.attackEntityFrom(DamageSource.MAGIC, 6.0f);
    }
    @Override
    public boolean isReady(int duration, int amplifier) {
        int j = 25 >> amplifier;
        if (j > 0) { return duration % j == 0;} 
        else { return true;}
    }
    
    • performEffect() 中寫你想周期性觸發的任何事情。這里寫的意思是生物受到6點魔法(葯水)傷害。除了上面寫的掉血,你還可以觸發爆炸來實現人肉轟炸等等。
    • amplifier 指的是葯水等級,0為Ⅰ級
    • isReady() 中控制觸發周期,比如上面就是原版的中毒狀態的代碼
  • 其他效果類,比如 ustc_zzzz 教程中的摔落保護效果,屬於事件觸發,需要監聽事件,這里就不展開了,之后再說。

葯水合成表

使用 BrewingRecipeRegistry.addRecipe() 創建,同樣可以把這個寫在上一篇的 Recipes 類構造器里。

public static boolean addRecipe(ItemStack input, ItemStack ingredient, ItemStack output)
  • input 葯水瓶的位置
  • ingredient 地獄疣/火葯等配方的位置
  • output 產物


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM