用户:MashKJo/1.21.1模组开发教程/5.1.第一个物品

为模组添加新物品可以说是Modder最常见也是最简单的需求了。对于没有什么额外行为的物品,直接用Item类即可;如果需要有额外的逻辑,则需要先继承Item类,并覆写相应的方法。读者可以自行翻阅Item和IItemExtension的源码。

Item的构造方法接受一个Item.Properties,这个对象指定了物品的一些基本属性,如最大堆叠数、耐久值等等。

注册物品当然是用延迟注册机制:

public static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(TutorialMod.MODID);

//一个最简单的物品注册。
//这个物品的注册名是<modid>:one_example_item。
public static final DeferredItem<Item> ONE_EXAMPLE_ITEM = ITEMS.registerSimpleItem("one_example_item");

//registerSimpleItem的另一个重载,第2个参数传入该物品的属性。
public static final DeferredItem<Item> ANOTHER_EXAMPLE_ITEM = ITEMS.registerSimpleItem("another_example_item", new Item.Properties(). ...);

//对于复杂的物品(表现为先继承Item类再实例化),调用registerItem。
public static final DeferredItem<ItemSubClass> ONE_SUBCLASS_ITEM = ITEMS.registerItem("one_subclass_item", ItemSubClass::new, new Item.Properties(). ...);

//别忘了在你的入口类构造方法中调用它!
public static void register(IEventBus bus) {
   ITEMS.register(bus);
}

运行runClient进入游戏,用/give命令就可以得到你注册进游戏的物品了。

模型文件和纹理

为了让我们的物品的外观不是紫黑块,我们需要给物品指定模型文件和纹理。

物品的模型文件位于路径assets/<modid>/models/item下,新建一个名为你的物品的注册名的path的JSON文件(如对示例代码中的ONE_EXAMPLE_ITEM而言,模型文件名就是one_example_item.json)。物品模型文件的格式在中文 Minecraft Wiki上有详尽的说明,这里只做简要示例:

{
   "parent": "minecraft:item/generated",
   "textures": {
       "layer0": "tutorialmod:item/one_example_item"
   }
}

parent父模型我们设定为minecraft:item/generated,这是物品的通用父模型;再在textures下指定该物品模型的第0层纹理为assets/<modid>/textures/item/<your_item_name>.png

将准备好的纹理PNG文件放入指定的位置,runClient打开游戏,你应该能看到你的新物品不是紫黑块了。

数据生成

物品模型的对应的DataProvider实现类是ItemModelProvider,其提供了一些辅助方法来简化物品模型的datagen。

public class MyItemModelProvider extends ItemModelProvider {
   public MyItemModelProvider(PackOutput output, ExistingFileHelper existingFileHelper) {
       super(output, TutorialMod.MODID, existingFileHelper);
   }

   @Override
   protected void registerModels() {
       basicItem(ModItems.EXAMPLE_ITEM.get());
       //最简单的一个物品模型。
       withExistingParent(ModItems.ANOTHER_EXAMPLE_ITEM.getId().toString(), mcLoc("item/generated"))
               .texture("layer0", ResourceLocation.fromNamespaceAndPath(...))
       //通用的datagen代码,可以通过继续调用#texture增加更多层的纹理。
   }
}

简单的物品模型可以这样datagen出来。至于复杂的物品模型(如涉及到不同视角的自定义变换),一般是通过Blockbench做出来的,能直接导出为JSON文件,因此一般不通过datagen生成(虽然也确实可以)。

语言文件

你可能会注意到你的物品的名称是类似于item.<modid>.xxx这种形式,这是物品的本地化键名,代表我们还没有对物品进行本地化。

语言文件在assets/<modid>/lang下,也是JSON文件,我们先创建英文语言文件: en_us.json:

{
   "item.tutorialmod.one_example_item": "One Example Item"
}

英文语言文件在其他语言文件缺失时会被使用,就以本系列教程的受众来说,我们还应该添加简体中文(zh_cn.json)的语言文件:

{
   "item.tutorialmod.one_example_item": "一个示例物品"
}

好了,现在这个物品看上去真的没什么问题了。

数据生成

public class ENLanguageProvider extends LanguageProvider {

   public ENLanguageProvider(PackOutput output) {
       super(output, TutorialMod.MODID, "en_us");
       //第二个参数是你的MODID,第三个参数是生成的语言文件的对应语言的代码。
   }

   @Override
   protected void addTranslations() {
       addItem(ModItems.EXAMPLE_ITEM, "Example Item");
       //添加某物品的本地化名。
       //还有其他一些辅助方法,如addBlock、addDimension之类的。
       //还可以直接调用add方法,用于自定义本地化键名的本地化。
   }
}

最后不要忘了在GatherDataEvent监听器中添加你的LanguageProvider!