新的附魔
我們試着給劍創建一個叫引爆的附魔。
在 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 產物