hxyzg
本帖最后由 hxyzg 于 2022-4-1 15:21 编辑

就像是石头跟染料,物品id都是石头,但是用data区分开来了。

如何用forge实现?或者说有其它方法?


因囸
没太明白你的意思。

无敌三脚猫
还是MCr吗?
如果你的mod新注册了什么物品,那你应该能在某个地方找到setCustomModelResourceLocation函数,这个函数的第二个参数就是meta(你也可以叫它metadata,但那不叫data)

Yuri南城
CustomModelData 在 1.14 引入

https://pack.imipet.com/grasp/file/optifineoldpack
http://sqwatermark.com/resguide/optifinedoc/
https://www.mcbbs.net/thread-803870-1-1.html
或许可以使用 Optifine 的功能

无敌三脚猫
还能怎么用呢,把默认值0换成你要改的值呗,比如改成1,然后第3个参数是模型(或者说是ModelResourceLocation),换成别的模型,这样你就做到了让这个物品的meta值为1的时候有不同的材质
你现在知道了这么设定特定meta值的材质,但如果你不知道怎么让物品有meta值,那就要找到注册物品的时候,也就是有一个registerItems,可能不叫这个名字但它的参数类型是RegistryEvent.Register<Item>,这里面可能会有写这样的
  1. Item 某某= (new Item()).setUnlocalizedName("xx")
复制代码
改成
  1. Item 某某= (new Item()).setHasSubtype(true).setMaxDamage(0).setNoRepair().setUnlocalizedName("xx")
复制代码
这样你的物品就有meta值可以用了

hxyzg
无敌三脚猫 发表于 2022-4-1 15:32
还能怎么用呢,把默认值0换成你要改的值呗,比如改成1,然后第3个参数是模型(或者说是ModelResourceLocatio ...

谢谢大佬,但以我的所见所闻,以及我铸币的智商得研究好久

hxyzg
无敌三脚猫 发表于 2022-4-1 15:32
还能怎么用呢,把默认值0换成你要改的值呗,比如改成1,然后第3个参数是模型(或者说是ModelResourceLocatio ...

这是mcr方块生成的源码

  1. package net.mcreator.funmod.block;

  2. import net.minecraftforge.fml.relauncher.SideOnly;
  3. import net.minecraftforge.fml.relauncher.Side;
  4. import net.minecraftforge.fml.common.registry.GameRegistry;
  5. import net.minecraftforge.client.model.ModelLoader;
  6. import net.minecraftforge.client.event.ModelRegistryEvent;

  7. import net.minecraft.item.ItemBlock;
  8. import net.minecraft.item.Item;
  9. import net.minecraft.creativetab.CreativeTabs;
  10. import net.minecraft.client.renderer.block.model.ModelResourceLocation;
  11. import net.minecraft.block.material.Material;
  12. import net.minecraft.block.SoundType;
  13. import net.minecraft.block.Block;

  14. import net.mcreator.funmod.ElementsFunmodMod;

  15. @ElementsFunmodMod.ModElement.Tag
  16. public class BlockTest extends ElementsFunmodMod.ModElement {
  17.         @GameRegistry.ObjectHolder("funmod:test")
  18.         public static final Block block = null;
  19.         public BlockTest(ElementsFunmodMod instance) {
  20.                 super(instance, 1);
  21.         }

  22.         @Override
  23.         public void initElements() {
  24.                 elements.blocks.add(() -> new BlockCustom().setRegistryName("test"));
  25.                 elements.items.add(() -> new ItemBlock(block).setRegistryName(block.getRegistryName()));
  26.         }

  27.         @SideOnly(Side.CLIENT)
  28.         @Override
  29.         public void registerModels(ModelRegistryEvent event) {
  30.                 ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(block), 0, new ModelResourceLocation("funmod:test", "inventory"));
  31.         }
  32.         public static class BlockCustom extends Block {
  33.                 public BlockCustom() {
  34.                         super(Material.ROCK);
  35.                         setUnlocalizedName("test");
  36.                         setSoundType(SoundType.GROUND);
  37.                         setHardness(1F);
  38.                         setResistance(10F);
  39.                         setLightLevel(0F);
  40.                         setLightOpacity(255);
  41.                         setCreativeTab(CreativeTabs.BUILDING_BLOCKS);
  42.                 }
  43.         }
  44. }
复制代码

无敌三脚猫
hxyzg 发表于 2022-4-1 15:52
这是mcr方块生成的源码

啊对,我刚刚都说了些什么啊,你要写的是方块,我说物品去了
再看看你注册这个方块时的代码呢?
就是有用到RegistryEvent.Register<Block>和RegistryEvent.Register<Item>的那部分

无敌三脚猫
我想看看你注册物品和方块的那块儿代码啊 哦没事了,我看到了,原来mcr会把这些代码写在一起啊
正常来说应该把所有继承Block类的类放在同一个包里,另外有一个类里写事件,注册所有的方块和物品,然后在mod主类里注册所有事件
注册了方块的同时一般也会注册这个方块对应的物品,是一个ItemBlock对象,调用了它的构造函数,里面填的是方块,也就是new ItemBlock(方块),这样注册出来的物品是和方块自动关联的,但你也可以注册一个新的Block,并且随便注册一个ItemBlock,加上我前面说的setHasSubtype等内容,让这个物品有meta值,并使用net.minecraftforge.registries.GameData.getBlockItemMap.put(那个新的Block,这个新的ItemBlock)来让它俩建立关联,不失为一种投机取巧的办法
正经一点的话,得给这个方块实现一套方块状态,这样写进你的代码我不知道行不行,如果行的话你就把我写的加上static,如果不行的话就把你的public static class BlockCustom extends Block这部分拿出去单独写一个类吧
注册方块的部分,不变
注册物品的部分……为啥mcr里会写成这种奇怪的样子?我都没看懂那个block是什么时候赋的值(如果你知道的话告诉我一声),正常来说方块物品在注册的时候会跟注册方块用到同一个对象,既然你这里有public static final Block block,那我觉得注册那部分应该写成
  1. block = new BlockCustom().setRegistryName("test")
  2. elements.blocks.add(() -> block);
  3. elements.items.add(() -> (new ItemMultiTexture(block, block, new ItemMultiTexture.Mapper()
  4.         {
  5.             public String apply(ItemStack apply)
  6.             {
  7.                 return wdblock.EnumMaterial.values()[apply.getMetadata()].getName();
  8.             }
  9.         })).setRegistryName(block.getRegistryName())));
复制代码
这样两个地方用着同一个block看着才对
setCustomModelResourceLocation那部分,就写两行(当然,优秀的代码应该根据meta的数量来决定执行次数)
  1. ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(block), 0, new ModelResourceLocation("funmod:test", "inventory"));
  2. ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(block), 1, new ModelResourceLocation("funmod:test1", "inventory"));
复制代码
这样你在游戏里能能得到funmod:test和meta值为1的funmod:test,两种不同材质的物品了
物品对应的方块不是一定跟物品使用相同材质的,要到src/main/resources/assets/funmod/blockstates/test.json里写
  1. {
  2.     "variants": {
  3.         "material=111": { "model": "funmod:test" },
  4.         "material=222": { "model": "funmod:test1" }
  5.     }
  6. }
复制代码
那个名叫test1的model也要你去src/main/resources/assets/funmod/models/block/test1.json里,就……随便你写什么了