Site icon May's Notes

Minecraft 1.21 Fabric 模組開發(6)-新增盔甲

Minecraft 1.21 Fabric 模組開發(6)-新增盔甲

Minecraft 1.21 Fabric 模組開發(1)-前置準備
Minecraft 1.21 Fabric 模組開發(2)-新增物品
Minecraft 1.21 Fabric 模組開發(3)-新增方塊
Minecraft 1.21 Fabric 模組開發(4)-資料產生(Data Generation)
Minecraft 1.21 Fabric 模組開發(5)-新增挖掘工具

寫在前頭
1.不是JAVA教學所以不解釋程式碼為何這樣寫,想知道為什麼這麼寫可以在 Fabric docs 或 Fabric wiki 裡面找到。
2.我的模組名稱為 mays-mod,程式碼中看到 mays-mod 的地方請自行換成你的 mod 名稱。
3.圖片看不清的話可以點擊放大看。

創建盔甲材料類

如果要新增盔甲,需要先實現 ModArmorMaterial 類,類別中還會需要建立一個靜態方法用於註冊盔甲材料。

/java/com/item/ModArmorMaterial.java

package com.may.firstmod.item;

import com.may.firstmod.MaysMod;
import net.minecraft.item.ArmorItem;
import net.minecraft.item.ArmorMaterial;
import net.minecraft.recipe.Ingredient;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.sound.SoundEvent;
import net.minecraft.sound.SoundEvents;
import net.minecraft.util.Identifier;

import java.util.List;
import java.util.Map;
import java.util.function.Supplier;

public class ModArmorMaterial {
    public static final RegistryEntry<ArmorMaterial> CREEPER = registerMaterial(
            "creeper",
            Map.of(
                    ArmorItem.Type.HELMET, 3,
                    ArmorItem.Type.CHESTPLATE, 8,
                    ArmorItem.Type.LEGGINGS, 6,
                    ArmorItem.Type.BOOTS, 3
            ),
            15,
            SoundEvents.ITEM_ARMOR_EQUIP_IRON,
            () -> Ingredient.ofItems(ModItems.CREEPER_INGOT),
            3.0F,
            0.1F,
            true
    );

    /**
     * 註冊盔甲材質
     *
     * @param id
     * @param defensePoints            - 護甲值
     * @param enchantability           - 附魔能力, 數字越高可以接受更高的附魔
     * @param equipSound               - 裝備時的聲音
     * @param repairIngredientSupplier - 修復材料
     * @param toughness                - 盔甲吸收的傷害, 數字越高吸收的傷害越多
     * @param knockbackResistance      - 擊退抗性, 數字越高玩家接收的擊退越少
     * @param dyeable                  - 是否可以染色
     * @return
     */
    public static RegistryEntry<ArmorMaterial> registerMaterial(String id, Map<ArmorItem.Type, Integer> defensePoints, int enchantability, RegistryEntry<SoundEvent> equipSound, Supplier<Ingredient> repairIngredientSupplier, float toughness, float knockbackResistance, boolean dyeable) {
        // Get the supported layers for the armor material
        List<ArmorMaterial.Layer> layers = List.of(
                new ArmorMaterial.Layer(Identifier.of(MaysMod.MOD_ID, id), "", dyeable)
        );

        ArmorMaterial material = new ArmorMaterial(defensePoints, enchantability, equipSound, repairIngredientSupplier, layers, toughness, knockbackResistance);
        // Register the material within the ArmorMaterials registry.
        material = Registry.register(Registries.ARMOR_MATERIAL, Identifier.of(MaysMod.MOD_ID, id), material);

        // The majority of the time, you'll want the RegistryEntry of the material - especially for the ArmorItem constructor.
        return RegistryEntry.of(material);
    }

    public static void initialize() {
    }

    ;
}

可以參考 net/minecraft/item/ArmorMaterials 是怎麼註冊盔甲材質的:

public static final RegistryEntry<ArmorMaterial> NETHERITE = register("netherite", 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);
        map.put(ArmorItem.Type.BODY, 11);
    }), 15, SoundEvents.ITEM_ARMOR_EQUIP_NETHERITE, 3.0F, 0.1F, () -> Ingredient.ofItems(Items.NETHERITE_INGOT));

創建盔甲物品

/java/com/item/ModItems.java

public static final Item CREEPER_HELMET = registerItem(
            "creeper_helmet",
            new ArmorItem(ModArmorMaterial.CREEPER, ArmorItem.Type.HELMET, new Item.Settings().maxDamage(ArmorItem.Type.BOOTS.getMaxDamage(15))),
            CREEPER_GROUP_KEY
    );
    public static final Item CREEPER_CHESTPLATE = registerItem(
            "creeper_chestplate",
            new ArmorItem(ModArmorMaterial.CREEPER, ArmorItem.Type.CHESTPLATE, new Item.Settings().maxDamage(ArmorItem.Type.BOOTS.getMaxDamage(15))),
            CREEPER_GROUP_KEY
    );
    public static final Item CREEPER_LEGGINGS = registerItem(
            "creeper_leggings",
            new ArmorItem(ModArmorMaterial.CREEPER, ArmorItem.Type.LEGGINGS, new Item.Settings().maxDamage(ArmorItem.Type.BOOTS.getMaxDamage(15))),
            CREEPER_GROUP_KEY
    );
    public static final Item CREEPER_BOOTS = registerItem(
            "creeper_boots",
            new ArmorItem(ModArmorMaterial.CREEPER, ArmorItem.Type.BOOTS, new Item.Settings().maxDamage(ArmorItem.Type.BOOTS.getMaxDamage(15))),
            CREEPER_GROUP_KEY
    );

修改 Providers

ModItemTagProvider

為了讓自訂盔甲也能使用鍛造模板和附魔,需要向 TRIMMABLE_ARMOR, ARMOR_ENCHANTABLE 添加我們的盔甲:

package com.may.firstmod.datagen;

import com.may.firstmod.item.ModItems;
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.registry.tag.ItemTags;

import java.util.concurrent.CompletableFuture;

public class ModItemTagProvider extends FabricTagProvider.ItemTagProvider {
    // ...

    @Override
    protected void configure(RegistryWrapper.WrapperLookup wrapperLookup) {
        // ...
        getOrCreateTagBuilder(ItemTags.TRIMMABLE_ARMOR)
                .add(ModItems.CREEPER_BOOTS, ModItems.CREEPER_CHESTPLATE, ModItems.CREEPER_LEGGINGS, ModItems.CREEPER_HELMET);
        getOrCreateTagBuilder(ItemTags.ARMOR_ENCHANTABLE)
                .add(ModItems.CREEPER_BOOTS, ModItems.CREEPER_CHESTPLATE, ModItems.CREEPER_LEGGINGS, ModItems.CREEPER_HELMET);
    }
}

ModModelsProvider

/java/com/datagen/ModModelsProvider.java

package com.may.firstmod.datagen;

import com.may.firstmod.block.ModBlocks;
import com.may.firstmod.item.ModItems;
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricModelProvider;
import net.minecraft.data.client.BlockStateModelGenerator;
import net.minecraft.data.client.ItemModelGenerator;
import net.minecraft.data.client.Models;
import net.minecraft.item.ArmorItem;

public class ModModelsProvider extends FabricModelProvider {
    // ...

    @Override
    public void generateItemModels(ItemModelGenerator itemModelGenerator) {
        // ...
        // 盔甲
        itemModelGenerator.registerArmor((ArmorItem) ModItems.CREEPER_HELMET);
        itemModelGenerator.registerArmor((ArmorItem) ModItems.CREEPER_CHESTPLATE);
        itemModelGenerator.registerArmor((ArmorItem) ModItems.CREEPER_BOOTS);
        itemModelGenerator.registerArmor((ArmorItem) ModItems.CREEPER_LEGGINGS);
    }
}

ModRecipesProvider

/java/com/datagen/ModRecipesProvider.java

package com.may.firstmod.datagen;

import com.may.firstmod.block.ModBlocks;
import com.may.firstmod.item.ModItems;
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder;
import net.minecraft.item.ItemConvertible;
import net.minecraft.item.Items;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.registry.RegistryWrapper;

import java.util.List;
import java.util.concurrent.CompletableFuture;

public class ModRecipesProvider extends FabricRecipeProvider {
    // ...

    @Override
    public void generate(RecipeExporter exporter) {
        // ...
        // 苦力怕盔甲合成
        ShapedRecipeJsonBuilder.create(RecipeCategory.TOOLS, ModItems.CREEPER_HELMET)
                .input('X', ModItems.CREEPER_INGOT)
                .pattern("XXX")
                .pattern("X X")
                .pattern("   ")
                .criterion("has_creeper_ingot", conditionsFromItem(ModItems.CREEPER_INGOT))
                .offerTo(exporter);
        ShapedRecipeJsonBuilder.create(RecipeCategory.TOOLS, ModItems.CREEPER_BOOTS)
                .input('X', ModItems.CREEPER_INGOT)
                .pattern("   ")
                .pattern("X X")
                .pattern("X X")
                .criterion("has_creeper_ingot", conditionsFromItem(ModItems.CREEPER_INGOT))
                .offerTo(exporter);
        ShapedRecipeJsonBuilder.create(RecipeCategory.TOOLS, ModItems.CREEPER_CHESTPLATE)
                .input('X', ModItems.CREEPER_INGOT)
                .pattern("X X")
                .pattern("XXX")
                .pattern("XXX")
                .criterion("has_creeper_ingot", conditionsFromItem(ModItems.CREEPER_INGOT))
                .offerTo(exporter);
        ShapedRecipeJsonBuilder.create(RecipeCategory.TOOLS, ModItems.CREEPER_LEGGINGS)
                .input('X', ModItems.CREEPER_INGOT)
                .pattern("XXX")
                .pattern("X X")
                .pattern("X X")
                .criterion("has_creeper_ingot", conditionsFromItem(ModItems.CREEPER_INGOT))
                .offerTo(exporter);
    }
}

記得語系檔也要加上。

註冊盔甲材質

盔甲的材質有兩層,一種是物品材質,一種是模型材質:

圖可以參考官方的拿來修改。

我使用的圖片:https://imgur.com/a/eLiEuvh

Exit mobile version