本篇教程的视频
本篇教程的源代码
本篇教程目标
- 理解原版盔甲材料的添加、盔甲物品的注册
- 学会创建盔甲材料、注册盔甲物品
查看源代码
这里我们也还是先来看源代码,找到Items
类中的盔甲相关的内容
盔甲注册
1 2 3 4
| public static final Item IRON_HELMET = register("iron_helmet", new ArmorItem(ArmorMaterials.IRON, ArmorItem.Type.HELMET, new Item.Settings())); public static final Item IRON_CHESTPLATE = register("iron_chestplate", new ArmorItem(ArmorMaterials.IRON, ArmorItem.Type.CHESTPLATE, new Item.Settings())); public static final Item IRON_LEGGINGS = register("iron_leggings", new ArmorItem(ArmorMaterials.IRON, ArmorItem.Type.LEGGINGS, new Item.Settings())); public static final Item IRON_BOOTS = register("iron_boots", new ArmorItem(ArmorMaterials.IRON, ArmorItem.Type.BOOTS, new Item.Settings()));
|
盔甲的话一共是4
个部分,分别是头盔
、胸甲
、护腿
、靴子
,每个盔甲物品都是实例化ArmorItem
的,
ArmorItem
的第一个参数是ArmorMaterials
,这是盔甲材料,这个倒是和我们之前写的工具差不多
第二个参数是盔甲的类型
,分头盔
、胸甲
、护腿
、靴子
最后一个参数则是物品的设置
盔甲材料
我们到ArmorMaterials
类中来看看,同样这个类也是一个枚举类
,罗列了原版所有的盔甲材料
和前面工具材料一样,我们直接看其中一个盔甲材料和构造函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| IRON("iron", 15, Util.make(new EnumMap(ArmorItem.Type.class), map -> { map.put(ArmorItem.Type.BOOTS, 2); map.put(ArmorItem.Type.LEGGINGS, 5); map.put(ArmorItem.Type.CHESTPLATE, 6); map.put(ArmorItem.Type.HELMET, 2); }), 9, SoundEvents.ITEM_ARMOR_EQUIP_IRON, 0.0F, 0.0F, () -> Ingredient.ofItems(Items.IRON_INGOT)) ...
private ArmorMaterials( String name, int durabilityMultiplier, EnumMap<ArmorItem.Type, Integer> protectionAmounts, int enchantability, SoundEvent equipSound, float toughness, float knockbackResistance, Supplier<Ingredient> repairIngredientSupplier ) { this.name = name; this.durabilityMultiplier = durabilityMultiplier; this.protectionAmounts = protectionAmounts; this.enchantability = enchantability; this.equipSound = equipSound; this.toughness = toughness; this.knockbackResistance = knockbackResistance; this.repairIngredientSupplier = new Lazy<>(repairIngredientSupplier); }
|
name
是盔甲材料的名称
durabilityMultiplier
是盔甲的耐久倍数
protectionAmounts
是盔甲提供的护甲值,是决定减伤比例区间的属性,每1点护甲值使伤害减少4%、至多被伤害降低至下限0.8%(Wiki)
equipSound
是盔甲装备时的音效
toughness
是盔甲的韧性,是决定降低护甲值减伤比例需要的伤害的属性(Wiki)
knockbackResistance
是盔甲的击退抗性,原版只有下界合金有击退抗性
repairIngredientSupplier
是盔甲的修复材料
1 2 3 4 5 6 7 8 9 10 11
| private static final EnumMap<ArmorItem.Type, Integer> BASE_DURABILITY = Util.make(new EnumMap(ArmorItem.Type.class), map -> { map.put(ArmorItem.Type.BOOTS, 13); map.put(ArmorItem.Type.LEGGINGS, 15); map.put(ArmorItem.Type.CHESTPLATE, 16); map.put(ArmorItem.Type.HELMET, 11); });
@Override public int getDurability(ArmorItem.Type type) { return (Integer)BASE_DURABILITY.get(type) * this.durabilityMultiplier; }
|
结合下面重写的getDurability
方法,我们可以看到每个部位盔甲的最终耐久度
是怎么计算的
它是由一个BASE_DURABILITY
提供的每个部位的基础耐久度,乘以盔甲材料的耐久倍数得到的
再后面,我们看看protectionAmounts
这个EnumMap
类型的参数,
这里就是将4
个部位提供的不同护甲值给罗列出来
注意一下护甲值这个东西,原版能够在HUD
显示出来的最大护甲值只有20
,下界合金正好是20,超过的部分虽然有效,但不会在HUD显示出来
注册物品
创建盔甲材料
这里我们先来创建自己的盔甲材料,我们创建一个ModArmorMaterials
类,实现StringIdentifiable
,ArmorMaterial
这两个接口
1 2 3
| public class ModArmorMaterials implements StringIdentifiable, ArmorMaterial { ; }
|
然后是要重写一些方法的,但我们还是先从原版搬一些变量过来
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| private static final EnumMap<ArmorItem.Type, Integer> BASE_DURABILITY = Util.make(new EnumMap(ArmorItem.Type.class), map -> { map.put(ArmorItem.Type.BOOTS, 13); map.put(ArmorItem.Type.LEGGINGS, 15); map.put(ArmorItem.Type.CHESTPLATE, 16); map.put(ArmorItem.Type.HELMET, 11); });
private final String name; private final int durabilityMultiplier; private final EnumMap<ArmorItem.Type, Integer> protectionAmounts; private final int enchantability; private final SoundEvent equipSound; private final float toughness; private final float knockbackResistance; private final Supplier<Ingredient> repairIngredientSupplier;
|
这里我们把BASE_DURABILITY
和另外的一堆变量给拿过来,注意最后的修复材料,我们也改成Supplier
类型的
然后是构造函数,这里我们直接把原版盔甲材料的构造函数搬过来,改一下就可以了
1 2 3 4 5 6 7 8 9 10
| ModArmorMaterials(String name, int durabilityMultiplier, EnumMap<ArmorItem.Type, Integer> protectionAmounts, int enchantability, SoundEvent equipSound, float toughness, float knockbackResistance, Supplier<Ingredient> repairIngredientSupplier) { this.name = name; this.durabilityMultiplier = durabilityMultiplier; this.protectionAmounts = protectionAmounts; this.enchantability = enchantability; this.equipSound = equipSound; this.toughness = toughness; this.knockbackResistance = knockbackResistance; this.repairIngredientSupplier = repairIngredientSupplier; }
|
那么重写的方法就可以补全了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| @Override public int getDurability(ArmorItem.Type type) { return (Integer)BASE_DURABILITY.get(type) * this.durabilityMultiplier; }
@Override public int getProtection(ArmorItem.Type type) { return (Integer)this.protectionAmounts.get(type); }
@Override public int getEnchantability() { return this.enchantability; }
@Override public SoundEvent getEquipSound() { return this.equipSound; }
@Override public Ingredient getRepairIngredient() { return this.repairIngredientSupplier.get(); }
@Override public String getName() { return TutorialMod.MOD_ID + ":" + this.name; }
@Override public float getToughness() { return this.toughness; }
@Override public float getKnockbackResistance() { return this.knockbackResistance; }
@Override public String asString() { return this.name; }
|
注意,其中的getName
方法,我们要加上我们模组的modid
,因为这个关乎资源文件的定位,
没有我们模组的命名空间
的话,就又找到MC这个命名空间下去了
那么最后,我们就可以编写盔甲材料了
1 2 3 4 5 6
| ICE_ETHER("ice_ether", 40, Util.make(new EnumMap(ArmorItem.Type.class), map -> { map.put(ArmorItem.Type.BOOTS, 3); map.put(ArmorItem.Type.LEGGINGS, 6); map.put(ArmorItem.Type.CHESTPLATE, 8); map.put(ArmorItem.Type.HELMET, 3); }), 30, SoundEvents.ITEM_ARMOR_EQUIP_NETHERITE, 3.0F, 0.1F, () -> Ingredient.ofItems(ModItems.ICE_ETHER));
|
按照原版的写法就好了,不过是会有一些警告的,不用管他,因为原版这么写的,我们也这么写,自然没问题
这个穿戴盔甲的声音我们还没有自己的声音事件,所以就拿原版的好了
注册盔甲
随后那就是盔甲的注册
1 2 3 4 5 6 7 8
| public static final Item ICE_ETHER_HELMET = registerItems("ice_ether_helmet", new ArmorItem(ModArmorMaterials.ICE_ETHER, ArmorItem.Type.HELMET, new Item.Settings())); public static final Item ICE_ETHER_CHESTPLATE = registerItems("ice_ether_chestplate", new ArmorItem(ModArmorMaterials.ICE_ETHER, ArmorItem.Type.CHESTPLATE, new Item.Settings())); public static final Item ICE_ETHER_LEGGINGS = registerItems("ice_ether_leggings", new ArmorItem(ModArmorMaterials.ICE_ETHER, ArmorItem.Type.LEGGINGS, new Item.Settings())); public static final Item ICE_ETHER_BOOTS = registerItems("ice_ether_boots", new ArmorItem(ModArmorMaterials.ICE_ETHER, ArmorItem.Type.BOOTS, new Item.Settings()));
|
实例化ArmorItem
,然后指定对应的盔甲材料
和盔甲类型
加入物品栏
最后,我们还要把盔甲加入到物品栏
中,这里我们直接在注册物品栏的方法中添加
1 2 3 4
| entries.add(ModItems.ICE_ETHER_HELMET); entries.add(ModItems.ICE_ETHER_CHESTPLATE); entries.add(ModItems.ICE_ETHER_LEGGINGS); entries.add(ModItems.ICE_ETHER_BOOTS);
|
数据文件
物品标签
高版本中,加入了锻造模板
,盔甲可以使用锻造模板,在锻造台
进行加工
但要让我们的盔甲可以锻造,需要写对应的物品标签
1 2
| getOrCreateTagBuilder(ItemTags.TRIMMABLE_ARMOR) .add(ModItems.ICE_ETHER_HELMET, ModItems.ICE_ETHER_CHESTPLATE, ModItems.ICE_ETHER_LEGGINGS, ModItems.ICE_ETHER_BOOTS);
|
TRIMMABLE_ARMOR
即为可锻造盔甲的标签,我们将注册好的盔甲物品加入即可
语言文件
1 2 3 4
| translationBuilder.add(ModItems.ICE_ETHER_HELMET, "Ice Ether Helmet"); translationBuilder.add(ModItems.ICE_ETHER_CHESTPLATE, "Ice Ether Chestplate"); translationBuilder.add(ModItems.ICE_ETHER_LEGGINGS, "Ice Ether Leggings"); translationBuilder.add(ModItems.ICE_ETHER_BOOTS, "Ice Ether Boots");
|
模型文件
1 2 3 4
| itemModelGenerator.registerArmor((ArmorItem) ModItems.ICE_ETHER_HELMET); itemModelGenerator.registerArmor((ArmorItem) ModItems.ICE_ETHER_CHESTPLATE); itemModelGenerator.registerArmor((ArmorItem) ModItems.ICE_ETHER_LEGGINGS); itemModelGenerator.registerArmor((ArmorItem) ModItems.ICE_ETHER_BOOTS);
|
盔甲的模型文件有单独的方法,这里我们要调用registerArmor
方法,传入我们的盔甲物品
贴图
盔甲的材质贴图是与一般物品不一样的,它是除了物品栏中的物品图标的材质文件
还有一类是模型类的文件
我们要将贴图放在textures/models/armor
文件夹下
注意,贴图文件分为2
个,其中的1
和2
有是用_
分开的,可参见原版的贴图文件
测试
数据生成跑完之后,我们就可以进入游戏进行测试了