物品属性覆盖

物品属性覆盖(Item Property Override)是一个Minecraft原版的机制,用来实现比如弓箭根据不同的拉弓时间显示不同的弓的模型。我们用原版bow.json的模型文件,来解释一下什么是物品属性覆盖,更多的内容请参照原版的WIKi中的「overrides」。

bow.json

{ 
    ……省略内容……
    "overrides": [
        {
            "predicate": {
                "pulling": 1
            },
            "model": "item/bow_pulling_0"
        },
        {
            "predicate": {
                "pulling": 1,
                "pull": 0.65
            },
            "model": "item/bow_pulling_1"
        },
        {
            "predicate": {
                "pulling": 1,
                "pull": 0.9
            },
            "model": "item/bow_pulling_2"
        }
    ]
}

可以看到在bow.json中出现了一个叫做overrides的配置项,在这个配置项里出现了一对对的:

{
  "predicate": {
    "pulling": 1
  },
  "model": "item/bow_pulling_0"
}

这里的内容非常容易理解。其中的predicate就是「条件」,当条件里的predicate(在游戏中定义会动态变化)的值大于等于1时,加载对应的模型,也就是item/bow_pulling_0

而我们也正要实现一个类似的功能,在这节中我们要实现一个「魔法锭」会根据物品堆叠的数量动态的改变模型。

首先是物品,非常的简单。

public class MagicIngot extends Item {
    public MagicIngot() {
        super(new Properties().group(ModGroup.itemGroup));
    }
}

注册物品:

public static final RegistryObject<Item> magicIngot = ITEMS.register("magic_ingot", MagicIngot::new);

接下来就是重头戏,给我们创建的物品添加「Item Property Override」。

@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD, value = Dist.CLIENT)
public class PropertyRegistry {
    @SubscribeEvent
    public static void propertyOverrideRegistry(FMLClientSetupEvent event) {
        event.enqueueWork(() -> {
            ItemModelsProperties.registerProperty(ItemRegistry.magicIngot.get(), new ResourceLocation(Utils.MOD_ID, "size"), (itemStack, clientWorld, livingEntity) -> itemStack.getCount());
        });
    }
}

可以看到,我们在FMLClientSetupEvent事件中,调用了ItemModelsProperties.registerProperty方法给我们的物品添加了一个overrides,这里的三个参数意义是,第一个是你要添加overrides的物品,第二个是这个overrides的名字,也就是你之后你要在模型文件的predicate里写的名字,第三个就是动态变化的值,这里我们直接调用了itemStack.getCount()函数返回了物品堆叠的数量。

接下去看我们的模型文件:magic_ingot.json

{
  "parent": "item/generated",
  "textures": {
    "layer0": "item/iron_ingot"
  },
  "overrides": [
    {
      "predicate": {
        "boson:size": 16
      },
      "model": "item/gold_ingot"
    }
  ]
}

可以看到这里我们设置了,在默认的时候显示铁锭的贴图,然后当物品的数量大于等于16之后显示金锭的贴图。

打开游戏你就能看见这个「魔法锭」了。

image-20201009195911814

image-20201009195924247

源代码