Jump to content

JimiIT92

Members
  • Posts

    866
  • Joined

  • Last visited

  • Days Won

    3

Posts posted by JimiIT92

  1. The most complete furnace recipes works like this:

    • an ItemStack as an input (what will be smelted)
    • an ItemStack as output (the result of the smelting)
    • a float amount of xp

    Using these 3 parameters you can pretty much smelt everything and get everything in result. So, if you want to smelt a certain variant of a block you can use something like this where you register your smelting recipes

     

    ItemStack input = new ItemStack(MyBlockOrItem, 1, metadata);
    ItemStack output = new ItemStack(MySmeltedBlockOrItem );
    float xp = 0.0F;
    
    GameRegistry.addSmelting(input, output, xp);

     

    About the parameters 

    • MyBlockOrItem is the block/item you want to smelt. This must be changed to what your block/item is called in the source code.
    • metadata is the numeric variant that you want to smelt. For example: if you have a block/item that has 3 variants and you want to smelt the second one, then you have to type 1 assuming that variants numbers starts to 0. If you want to know what the numeric variant of your block/item is, just press F3+H in game and have a look at your block/item in inventory. You'll notice the block id followed by / and a number. That number is the metadata value
    • MySmeltedBlockOrItem is the block/item you get as result of the smelting. Now, here you can go further using this 
      ItemStack output = new ItemStack(MySmeltedBlockOrItem, quantity, metadata);

      so you can even return a specific variant of a block/item as result too in the quantity you prefer.

    • xp is the amount of experience you get when you take the smelt result from the furnace. You can get an idea of what value type in by looking at the vanilla values here https://minecraft.gamepedia.com/Smelting

     

  2. The json hasn't changed, but i post it again so there's everything in one place. This is the method i use to register a block with variants. It takes the block itself, the variant name and the enum class corresponding to the variant values

     

    Spoiler

    public static <E extends Enum<?>> void registerMetadataBlockModel(Block block, String variantName, Class<E> variants) {
            for(int i = 0; i < variants.getEnumConstants().length; i++) {
                ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(block), i, new ModelResourceLocation(block.getRegistryName(),  variantName + "=" + variants.getEnumConstants().name().toLowerCase()));
            }
        }

     

    The enum i'm using to give the slab a variant is this

     

    Spoiler

    package com.mineworld.block.enums;

    import com.mineworld.block.BlockMarble;

    import net.minecraft.block.material.MapColor;
    import net.minecraft.util.IStringSerializable;

    public enum EnumOre implements IStringSerializable {
        RUBY(0, "ruby", MapColor.RED, 2, 0),
        SAPPHIRE(1, "sapphire", MapColor.BLUE, 2, 0),
        COPPER(2, "copper", MapColor.TNT, 1, 10),
        BRONZE(3, "bronze", MapColor.BROWN, 1, 5),
        SILVER(4, "silver", MapColor.LIGHT_BLUE, 1, 0),
        ALUMINIUM(5, "aluminium", MapColor.SILVER, 1, 0),
        PYRITE(6, "pyrite", MapColor.YELLOW, 0, 0);

        private static final EnumOre[] META_LOOKUP = new EnumOre[values().length];
        private final int meta;
        private final String name;
        private final MapColor mapColor;
        private final int harvestLevel;
        private final int powerLevel;
        
        private EnumOre(int metaIn, String nameIn, MapColor mapColorIn, int harvestLevel, int powerLevel)
        {
            this.meta = metaIn;
            this.name = nameIn;
            this.mapColor = mapColorIn;
            this.harvestLevel = harvestLevel;
            this.powerLevel = powerLevel;
        }
        
        static
        {
            for (EnumOre value : values())
            {
                META_LOOKUP[value.getMetadata()] = value;
            }
        }
        
        public static EnumOre byMetadata(int meta)
        {
            if (meta < 0 || meta >= META_LOOKUP.length)
            {
                meta = 0;
            }

            return META_LOOKUP[meta];
        }
        
        @Override
        public String getName() {
            return this.name;
        }

        public int getMetadata() {
            return this.meta;
        }

        public MapColor getMapColor() {
            return this.mapColor;
        }
        
        public int getHarvestLevel() {
            return this.harvestLevel;
        }
        
        public int getPowerLevel() {
            return this.powerLevel;
        }

        public String toString() {
            return this.name;
        }
    }
     

     

    and this is the slab base class 

     

    Spoiler

    package com.mineworld.block.slab;

    import java.util.Arrays;
    import java.util.Random;

    import javax.annotation.Nullable;

    import com.google.common.base.Predicate;
    import com.mineworld.block.enums.EnumMarble;
    import com.mineworld.core.MWBlocks;
    import com.mineworld.core.MWTabs;
    import com.mineworld.settings.ModSettings;

    import net.minecraft.block.BlockSlab;
    import net.minecraft.block.SoundType;
    import net.minecraft.block.material.MapColor;
    import net.minecraft.block.material.Material;
    import net.minecraft.block.properties.IProperty;
    import net.minecraft.block.properties.PropertyEnum;
    import net.minecraft.block.state.BlockStateContainer;
    import net.minecraft.block.state.IBlockState;
    import net.minecraft.creativetab.CreativeTabs;
    import net.minecraft.init.Blocks;
    import net.minecraft.item.Item;
    import net.minecraft.item.ItemStack;
    import net.minecraft.util.EnumFacing;
    import net.minecraft.util.NonNullList;
    import net.minecraft.util.math.BlockPos;
    import net.minecraft.world.IBlockAccess;
    import net.minecraft.world.World;

    public abstract class BlockMarbleSlab extends BlockSlab
    {
        public static final PropertyEnum<EnumMarble> COLOR = PropertyEnum.<EnumMarble>create("color", EnumMarble.class);

        public BlockMarbleSlab(String name)
        {
            super(Material.ROCK);
            setUnlocalizedName(ModSettings.MODID + "." + name);
            setRegistryName(name);
            setSoundType(SoundType.METAL);
            IBlockState iblockstate = this.blockState.getBaseState();

            if (!this.isDouble())
            {
                iblockstate = iblockstate.withProperty(HALF, BlockSlab.EnumBlockHalf.BOTTOM);
            }

            this.setDefaultState(iblockstate.withProperty(COLOR, EnumMarble.WHITE));
            this.setCreativeTab(MWTabs.BUILDING_BLOCKS);
            this.setHardness(1.5F);
            this.setResistance(10.0F);
        }

        /**
         * Get the MapColor for this Block and the given BlockState
         */
        public MapColor getMapColor(IBlockState state, IBlockAccess worldIn, BlockPos pos)
        {
            return ((EnumMarble)state.getValue(COLOR)).getMapColor();
        }

        /**
         * Get the Item that this Block should drop when harvested.
         */
        public Item getItemDropped(IBlockState state, Random rand, int fortune)
        {
            return Item.getItemFromBlock(MWBlocks.MARBLE_SLAB);
        }

        public ItemStack getItem(World worldIn, BlockPos pos, IBlockState state)
        {
            return new ItemStack(MWBlocks.MARBLE_SLAB, 1, ((EnumMarble)state.getValue(COLOR)).getMetadata());
        }

        /**
         * Returns the slab block name with the type associated with it
         */
        public String getUnlocalizedName(int meta)
        {
            return super.getUnlocalizedName() + "." + EnumMarble.byMetadata(meta).getName();
        }

        public IProperty<?> getVariantProperty()
        {
            return COLOR;
        }

        public Comparable<?> getTypeForItem(ItemStack stack)
        {
            return EnumMarble.byMetadata(stack.getMetadata() & 7);
        }

        /**
         * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks)
         */
        public void getSubBlocks(CreativeTabs itemIn, NonNullList<ItemStack> items)
        {
            for(EnumMarble ore : COLOR.getAllowedValues()) {
                items.add(new ItemStack(this, 1, ore.getMetadata()));
            }
        }

        /**
         * Convert the given metadata into a BlockState for this Block
         */
        public IBlockState getStateFromMeta(int meta)
        {
            IBlockState iblockstate = this.getDefaultState().withProperty(COLOR, EnumMarble.byMetadata(meta & 7));

            if (!this.isDouble())
            {
                iblockstate = iblockstate.withProperty(HALF, (meta & 8) == 0 ? BlockSlab.EnumBlockHalf.BOTTOM : BlockSlab.EnumBlockHalf.TOP);
            }

            return iblockstate;
        }

        /**
         * Convert the BlockState into the correct metadata value
         */
        public int getMetaFromState(IBlockState state)
        {
            int i = 0;
            i = i | ((EnumMarble)state.getValue(COLOR)).getMetadata();

            if (!this.isDouble() && state.getValue(HALF) == BlockSlab.EnumBlockHalf.TOP)
            {
                i |= 8;
            }

            return i;
        }

        protected BlockStateContainer createBlockState()
        {
            return this.isDouble() ? new BlockStateContainer(this, new IProperty[] {COLOR}) : new BlockStateContainer(this, new IProperty[] {HALF, COLOR});
        }

        /**
         * Gets the metadata of the item this Block can drop. This method is called when the block gets destroyed. It
         * returns the metadata of the dropped item based on the old metadata of the block.
         */
        public int damageDropped(IBlockState state)
        {
            return ((EnumMarble)state.getValue(COLOR)).getMetadata();
        }
    }

     

    In the register block event i register the half slab and the double slab block like this

     

    Spoiler

    event.getRegistry().registerAll(new BlockHalfMarbleSlab("marble_slab"),
                    new BlockDoubleMarbleSlab("marble_double_slab"))

     

    As well as the item block in the register item event

     

    Spoiler

    event.getRegistry().registerAll(new ItemSlab(MARBLE_SLAB, MARBLE_SLAB, MARBLE_DOUBLE_SLAB).setRegistryName(MARBLE_SLAB.getRegistryName()))

     

    And finally i register the model using the ModelRegistryEvent like this

     

    Spoiler

    registerMetadataBlockModel(MARBLE_SLAB, "color", EnumMarble.class);
    registerMetadataBlockModel(MARBLE_DOUBLE_SLAB, "color", EnumMarble.class);

     

    The blockstates json file i use for the half slab is this

     

    Spoiler

    {
        "forge_marker": 1,
        "variants": {
            "normal": [{

            }],
            "inventory": [{

            }],
            "half": {
                "top": {
                    "model": "upper_slab"
                },
                "bottom": {
                    "model": "half_slab"
                }
            },
            "color": {
                "white":  { "textures": { "bottom": "mineworld:blocks/marble_white", 
                    "side": "mineworld:blocks/marble_white", 
                    "top": "mineworld:blocks/marble_white"

                } },
                "black":  { "textures": { "bottom": "mineworld:blocks/marble_black", 
                    "side": "mineworld:blocks/marble_black", 
                    "top": "mineworld:blocks/marble_black"

                } },
                "red":  { "textures": { "bottom": "mineworld:blocks/marble_red", 
                    "side": "mineworld:blocks/marble_red", 
                    "top": "mineworld:blocks/marble_red"

                } },
                "brown":  { "textures": { "bottom": "mineworld:blocks/marble_brown", 
                    "side": "mineworld:blocks/marble_brown", 
                    "top": "mineworld:blocks/marble_brown"

                } },
                "pink":  { "textures": { "bottom": "mineworld:blocks/marble_pink", 
                    "side": "mineworld:blocks/marble_pink", 
                    "top": "mineworld:blocks/marble_pink"

                } },
                "yellow":  { "textures": { "bottom": "mineworld:blocks/marble_yellow", 
                    "side": "mineworld:blocks/marble_yellow", 
                    "top": "mineworld:blocks/marble_yellow"

                } },
                "green":  { "textures": { "bottom": "mineworld:blocks/marble_green", 
                    "side": "mineworld:blocks/marble_green", 
                    "top": "mineworld:blocks/marble_green"

                } }
            }
        }
    }

     

    While for the double slab i use this json file

     

    Spoiler

    {
        "forge_marker": 1,
        "defaults": {
            "model": "cube_all"
        },
        "variants": {
            "normal": [{

            }],
            "inventory": [{

            }],
            "color": {
                "white":  { "textures": { "all": "mineworld:blocks/marble_white"
                } },
                "black":  { "textures": { "all": "mineworld:blocks/marble_black"
                } },
                "red":  { "textures": { "all": "mineworld:blocks/marble_red"
                } },
                "brown":  { "textures": { "all": "mineworld:blocks/marble_brown"
                } },
                "pink":  { "textures": { "all": "mineworld:blocks/marble_pink"
                } },
                "yellow":  { "textures": { "all": "mineworld:blocks/marble_yellow"
                } },
                "green":  { "textures": { "all": "mineworld:blocks/marble_green"
                } }
            }
        }
    }

     

    If i place the block on the ground it works fine, both for half slabs and double slabs, is just in inventory that i get no icon and model, just a plain black/purple texture

  3. Maybe there's an issue on how i register it? I use this method to register the slab

     

    public static <E extends Enum<?>> void registerMetadataBlockModel(Block block, String variantName, Class<E> variants) {
    		for(int i = 0; i < variants.getEnumConstants().length; i++) {
    			ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(block), i, new ModelResourceLocation(block.getRegistryName(),  variantName + "=" + variants.getEnumConstants()[i].name()));
    		}
    	}

    And from the model registry event i call it like this
     

    BlockUtils.registerMetadataBlockModel(MARBLE_SLAB, "color", EnumMarble.class);
    BlockUtils.registerMetadataBlockModel(MARBLE_DOUBLE_SLAB, "color", EnumMarble.class);

     

  4. I use that base class just for blocks that don't have any particular feature (like ores, mineral blocks or colored blocks) :) Anyway i changed the registration part to "color=white" instead of just white and it worked. Except it isn't for slabs, wich i did the same thing. It says it can't found a variant for slab#color=yellow but in the model registration i specified the variant like the normal block ("color=yellow"). In this case the error could be in the json file? Here's the one i'm using

     

    {
        "forge_marker": 1,
        "variants": {
            "normal": [{
    
            }],
            "inventory": [{
    
            }],
            "half": {
                "top": {
                    "model": "upper_slab"
                },
                "bottom": {
                    "model": "half_slab"
                }
            },
            "color": {
                "white":  { "textures": { "bottom": "mineworld:blocks/marble_white", 
                    "side": "mineworld:blocks/marble_white", 
                    "top": "mineworld:blocks/marble_white"
    
                } },
                "black":  { "textures": { "bottom": "mineworld:blocks/marble_black", 
                    "side": "mineworld:blocks/marble_black", 
                    "top": "mineworld:blocks/marble_black"
    
                } },
                "red":  { "textures": { "bottom": "mineworld:blocks/marble_red", 
                    "side": "mineworld:blocks/marble_red", 
                    "top": "mineworld:blocks/marble_red"
    
                } },
                "brown":  { "textures": { "bottom": "mineworld:blocks/marble_brown", 
                    "side": "mineworld:blocks/marble_brown", 
                    "top": "mineworld:blocks/marble_brown"
    
                } },
                "pink":  { "textures": { "bottom": "mineworld:blocks/marble_pink", 
                    "side": "mineworld:blocks/marble_pink", 
                    "top": "mineworld:blocks/marble_pink"
    
                } },
                "yellow":  { "textures": { "bottom": "mineworld:blocks/marble_yellow", 
                    "side": "mineworld:blocks/marble_yellow", 
                    "top": "mineworld:blocks/marble_yellow"
    
                } },
                "green":  { "textures": { "bottom": "mineworld:blocks/marble_green", 
                    "side": "mineworld:blocks/marble_green", 
                    "top": "mineworld:blocks/marble_green"
    
                } }
            }
        }
    }

     

  5. Ok, i thought it was some error in the json file since it's the first time i use the forge blockstate format. Anyway this is the class i'm using to create the block with the variants
     

    package com.mineworld.block;
    
    import com.mineworld.block.enums.EnumMarble;
    import com.mineworld.core.MWTabs;
    
    import net.minecraft.block.BlockPlanks;
    import net.minecraft.block.SoundType;
    import net.minecraft.block.material.MapColor;
    import net.minecraft.block.material.Material;
    import net.minecraft.block.properties.IProperty;
    import net.minecraft.block.properties.PropertyEnum;
    import net.minecraft.block.state.BlockStateContainer;
    import net.minecraft.block.state.IBlockState;
    import net.minecraft.creativetab.CreativeTabs;
    import net.minecraft.item.ItemStack;
    import net.minecraft.util.NonNullList;
    import net.minecraft.util.math.BlockPos;
    import net.minecraft.world.IBlockAccess;
    
    public class BlockMarble extends BlockMW {
    	private static final PropertyEnum<EnumMarble> COLOR = PropertyEnum.<EnumMarble>create("color", EnumMarble.class);
    
    	public BlockMarble(String name) {
    		super(name, Material.ROCK, MapColor.QUARTZ, SoundType.STONE, MWTabs.BUILDING_BLOCKS);
    		this.setDefaultState(this.blockState.getBaseState().withProperty(COLOR, EnumMarble.WHITE));
    		setHardness(1.5F);
    		setResistance(10.0F);
    	}
    
    	/**
    	 * Gets the metadata of the item this Block can drop. This method is called when
    	 * the block gets destroyed. It returns the metadata of the dropped item based
    	 * on the old metadata of the block.
    	 */
    	public int damageDropped(IBlockState state) {
    		return ((EnumMarble) state.getValue(COLOR)).getMetadata();
    	}
    
    	/**
    	 * returns a list of blocks with the same ID, but different meta (eg: wood
    	 * returns 4 blocks)
    	 */
    	public void getSubBlocks(CreativeTabs itemIn, NonNullList<ItemStack> items) {
    		for (EnumMarble value : EnumMarble.values()) {
    			items.add(new ItemStack(this, 1, value.getMetadata()));
    		}
    	}
    
    	/**
    	 * Get the MapColor for this Block and the given BlockState
    	 */
    	public MapColor getMapColor(IBlockState state, IBlockAccess worldIn, BlockPos pos) {
    		return ((EnumMarble) state.getValue(COLOR)).getMapColor();
    	}
    
    	/**
    	 * Convert the BlockState into the correct metadata value
    	 */
    	public int getMetaFromState(IBlockState state) {
    		return ((EnumMarble) state.getValue(COLOR)).getMetadata();
    	}
    
    	protected BlockStateContainer createBlockState() {
    		return new BlockStateContainer(this, new IProperty[] { COLOR });
    	}
    
    	/**
    	 * Convert the given metadata into a BlockState for this Block
    	 */
    	public IBlockState getStateFromMeta(int meta) {
    		return this.getDefaultState().withProperty(COLOR, EnumMarble.byMetadata(meta));
    	}
    }

    BlockMW just sets the registry name, the unlocalized name and the creative tab

     

    This is the enum i use to create the variants
     

    package com.mineworld.block.enums;
    
    import net.minecraft.block.material.MapColor;
    import net.minecraft.util.IStringSerializable;
    
    public enum EnumMarble implements IStringSerializable {
    	WHITE(0, "white", MapColor.QUARTZ),
    	BLACK(1, "black", MapColor.BLACK),
    	RED(2, "red", MapColor.RED),
    	BROWN(3, "brown", MapColor.BROWN),
    	PINK(4, "pink", MapColor.PINK),
    	YELLOW(5, "yellow", MapColor.YELLOW),
    	GREEN(6, "green", MapColor.GREEN);
    
    	private static final EnumMarble[] META_LOOKUP = new EnumMarble[values().length];
    	private final int meta;
        private final String name;
        private final MapColor mapColor;
    	
        private EnumMarble(int metaIn, String nameIn, MapColor mapColorIn)
        {
            this.meta = metaIn;
            this.name = nameIn;
            this.mapColor = mapColorIn;
        }
        
        static
        {
            for (EnumMarble value : values())
            {
                META_LOOKUP[value.getMetadata()] = value;
            }
        }
        
        public static EnumMarble byMetadata(int meta)
        {
            if (meta < 0 || meta >= META_LOOKUP.length)
            {
                meta = 0;
            }
    
            return META_LOOKUP[meta];
        }
        
    	@Override
    	public String getName() {
    		return this.name;
    	}
    
    	public int getMetadata() {
    		return this.meta;
    	}
    
    	public MapColor getMapColor() {
    		return this.mapColor;
    	}
    
    	public String toString() {
            return this.name;
        }
    }

     I looked at the vanilla code for planks but i can't find any difference that makes the variant incorrect

  6. If i change to this

     

    {
        "forge_marker": 1,
        "defaults": {
            "textures": {
            },
            "model": "cube_all"
        },
        "variants": {
            "normal": [{
    
            }],
            "inventory": [{
    
            }],
            "color": {
                "color=white":  { "textures": { "all": "mineworld:blocks/marble_white"} },
                "color=black":  { "textures": { "all": "mineworld:blocks/marble_black"} },
                "color=red":  { "textures": { "all": "mineworld:blocks/marble_red"} },
                "color=brown":  { "textures": { "all": "mineworld:blocks/marble_brown"} },
                "color=pink":  { "textures": { "all": "mineworld:blocks/marble_pink"} },
                "color=yellow":  { "textures": { "all": "mineworld:blocks/marble_yellow"} },
                "color=green":  { "textures": { "all": "mineworld:blocks/marble_green"} }
            }
        }
    }

    or to this
     

    {
        "forge_marker": 1,
        "defaults": {
            "textures": {
            },
            "model": "cube_all"
        },
        "variants": {
            "normal": [{
    
            }],
            "inventory": [{
    
            }],
            "color=white":  { "textures": { "all": "mineworld:blocks/marble_white"} },
            "color=black":  { "textures": { "all": "mineworld:blocks/marble_black"} },
            "color=red":  { "textures": { "all": "mineworld:blocks/marble_red"} },
            "color=brown":  { "textures": { "all": "mineworld:blocks/marble_brown"} },
            "color=pink":  { "textures": { "all": "mineworld:blocks/marble_pink"} },
            "color=yellow":  { "textures": { "all": "mineworld:blocks/marble_yellow"} },
            "color=green":  { "textures": { "all": "mineworld:blocks/marble_green"} }
        }
    }

    then the placed block has no texture too :/ Also i don't understand where the difference comes from and how to tell the game to use the one without "color=" instead

  7. I removed that color part but nothing changed. My log throws this error

     

    [15:40:30] [main/ERROR] [FML]: Exception loading model for variant mineworld:marble#white for item "mineworld:marble", blockstate location exception: 
    net.minecraftforge.client.model.ModelLoaderRegistry$LoaderException: Exception loading model mineworld:marble#white with loader VariantLoader.INSTANCE, skipping
    	at net.minecraftforge.client.model.ModelLoaderRegistry.getModel(ModelLoaderRegistry.java:161) ~[ModelLoaderRegistry.class:?]
    	at net.minecraftforge.client.model.ModelLoader.loadItemModels(ModelLoader.java:296) ~[ModelLoader.class:?]
    	at net.minecraft.client.renderer.block.model.ModelBakery.loadVariantItemModels(ModelBakery.java:175) ~[ModelBakery.class:?]
    	at net.minecraftforge.client.model.ModelLoader.setupModelRegistry(ModelLoader.java:151) ~[ModelLoader.class:?]
    	at net.minecraft.client.renderer.block.model.ModelManager.onResourceManagerReload(ModelManager.java:28) [ModelManager.class:?]
    	at net.minecraft.client.resources.SimpleReloadableResourceManager.registerReloadListener(SimpleReloadableResourceManager.java:121) [SimpleReloadableResourceManager.class:?]
    	at net.minecraft.client.Minecraft.init(Minecraft.java:559) [Minecraft.class:?]
    	at net.minecraft.client.Minecraft.run(Minecraft.java:421) [Minecraft.class:?]
    	at net.minecraft.client.main.Main.main(Main.java:118) [Main.class:?]
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_181]
    	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_181]
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_181]
    	at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_181]
    	at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.12.jar:?]
    	at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.12.jar:?]
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_181]
    	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_181]
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_181]
    	at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_181]
    	at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97) [start/:?]
    	at GradleStart.main(GradleStart.java:25) [start/:?]
    Caused by: net.minecraft.client.renderer.block.model.ModelBlockDefinition$MissingVariantException
    	at net.minecraft.client.renderer.block.model.ModelBlockDefinition.getVariant(ModelBlockDefinition.java:83) ~[ModelBlockDefinition.class:?]
    	at net.minecraftforge.client.model.ModelLoader$VariantLoader.loadModel(ModelLoader.java:1175) ~[ModelLoader$VariantLoader.class:?]
    	at net.minecraftforge.client.model.ModelLoaderRegistry.getModel(ModelLoaderRegistry.java:157) ~[ModelLoaderRegistry.class:?]
    	... 20 more

     

  8. Hi everyone :D I'm trying to make metadata blocks in 1.12.2 using the forge_marker blockstates system. Now, the block itself works fine, if i place them down i get different textures based on their variant. But in inventory i get the black/purple texture :/ This is my json blockstate file
     

    {
        "forge_marker": 1,
        "defaults": {
            "textures": {
            },
            "model": "cube_all"
        },
        "variants": {
            "normal": [{
    
            }],
            "inventory": [{
    
            }],
             "color": {
                "white":  { "textures": { "all": "mineworld:blocks/marble_white"} },
                "black":  { "textures": { "all": "mineworld:blocks/marble_black"} },
                "red":  { "textures": { "all": "mineworld:blocks/marble_red"} },
                "brown":  { "textures": { "all": "mineworld:blocks/marble_brown"} },
                "pink":  { "textures": { "all": "mineworld:blocks/marble_pink"} },
                "yellow":  { "textures": { "all": "mineworld:blocks/marble_yellow"} },
                "green":  { "textures": { "all": "mineworld:blocks/marble_green"} }
            }
        }
    }

    And this is how i register them
     

    ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(MARBLE), 0, new ModelResourceLocation(MARBLE.getRegistryName() + "_white", "white"));
    ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(MARBLE), 1, new ModelResourceLocation(MARBLE.getRegistryName() + "_black", "black"));
    ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(MARBLE), 2, new ModelResourceLocation(MARBLE.getRegistryName() + "_red", "red"));
    ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(MARBLE), 3, new ModelResourceLocation(MARBLE.getRegistryName() + "_brown", "brown"));
    ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(MARBLE), 4, new ModelResourceLocation(MARBLE.getRegistryName() + "_pink", "pink"));
    ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(MARBLE), 5, new ModelResourceLocation(MARBLE.getRegistryName() + "_yellow", "yellow"));
    ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(MARBLE), 6, new ModelResourceLocation(MARBLE.getRegistryName() + "_green", "green"));

     

    What am i missing here? :/ 

     

  9. Kinda, i now have a different problem :/ Items shows up correctly in the creative tab, however the tab itself is missing the icon. I now use this to register my items
     

    @SubscribeEvent
    public static void registerItems(Register<Item> event) {
      final Item[] items = MWItems.createItems();
      event.getRegistry().registerAll(items);
    }
    
    -- In MWItems
    public static ArrayList<Item> ITEMS = new ArrayList<Item>();
    
    public static Item RUBY = null;
    public static Item SAPPHIRE = null;
    public static Item BRONZE_INGOT = null;
    public static Item COPPER_INGOT = null;
    public static Item SILVER_INGOT = null;
    public static Item ALUMINIUM_INGOT = null;
    public static Item PYRITE = null;
    
    public static Item[] createItems() {
      RUBY = new ItemMW("ruby").register();
      SAPPHIRE = new ItemMW("sapphire").register();
      BRONZE_INGOT = new ItemMW("bronze_ingot").register();
      COPPER_INGOT = new ItemMW("copper_ingot").register();
      SILVER_INGOT = new ItemMW("silver_ingot").register();
      ALUMINIUM_INGOT = new ItemMW("aluminium_ingot").register();
      PYRITE = new ItemMW("pyrite").register();
      return ITEMS.toArray(new Item[ITEMS.size()]);
    }
    
    -- ItemMW class
    public class ItemMW extends ItemBasicMW {
    	public ItemMW(String registryName) {
    		this(registryName, MWTabs.MISC);
    	}
    }
    
    -- ItemBasicMW class
      
    public class ItemBasicMW extends Item {
    	private String registryName;
    	
    	public ItemBasicMW(String registryName, CreativeTabs Tab) {
    		super();
    		this.registryName = registryName;
    		setCreativeTab(Tab);
    	}
    	
    	public Item register() {
    		setUnlocalizedName(ModSettings.MODID + "." + this.registryName);
    		setRegistryName(this.registryName);
    		MWItems.ITEMS.add(this);
    		return this;
    	}
    }

     EDIT:

     

    I use this class to create my tabs

     

    public class CreativeTabMW extends CreativeTabs {
    
    	private ItemStack icon;
    	
    	public CreativeTabMW(String name, Item item) {
    		super(ModSettings.MODID + "." + name);
    		icon = new ItemStack(item);
    	}
    	
    	public CreativeTabMW(String name, Block block) {
    		super(ModSettings.MODID + "." + name);
    		icon = new ItemStack(block);
    	}
    
    	@SideOnly(Side.CLIENT)
    	@Override
    	public ItemStack getTabIconItem() {
    		return icon;
    	}
    }

     If i change the getTabIcon and set there the item, the icon shows up, but if i use the parameter passed from the constructor it won't. Why is this happening?

  10. Ok i got it, i've seen a tutorial about the new registry system that essentialy does something like this
     

    Item[] items = { new ItemTest1(), new ItemTest2() }

     I guess that if i call a method somewhere that does this
     

    Item1 = new Item1();
    Item2 = new Item2();

    and then add the items to the list should be the same, right? 
    For the reflection part, i guess adding manually each item to the registry is the good practice here :/ As i said the mod adds a really big amount of items and blocks and with this in previous versions i was able to add many features really quick since i don't have to worry about registering the item and the model. But as i said i guess the good practice is to use a list that holds every single item of the mod and use that as a "register holder", so i'll swap to that :) On the exception: you are totally right. I use to do it in my code, don't know why i didn't here (probably because is unlikely that the item won't be registered) :)

  11. Hi everyone! I have a bit strange problem with my mod's blocks and items. Essentially they are not showing up in the creative tabs even if they are registered correctly and the tab is set. This is the code for my item

    package com.mineworld.item;
    
    import com.mineworld.core.MWTabs;
    
    import net.minecraft.item.Item;
    
    public class ItemMW extends Item {
    
    	public ItemMW() {
    		setCreativeTab(MWTabs.MISC);
    	}
    }

    Nothing special as you can see. And this is how i create my items

    package com.mineworld.core;
    
    import com.mineworld.item.ItemMW;
    import com.mineworld.settings.ModSettings;
    
    import net.minecraft.creativetab.CreativeTabs;
    import net.minecraft.init.Items;
    import net.minecraft.item.Item;
    import net.minecraftforge.fml.common.registry.GameRegistry.ObjectHolder;
    
    @ObjectHolder(ModSettings.MODID)
    public class MWItems {
    
    	public static final Item RUBY = new ItemMW();
    	public static final Item SAPPHIRE = new ItemMW();
    	public static final Item BRONZE_INGOT = new ItemMW();
    	public static final Item COPPER_INGOT = new ItemMW();
    	public static final Item SILVER_INGOT = new ItemMW();
    	public static final Item ALUMINIUM_INGOT = new ItemMW();
    	public static final Item PYRITE = new ItemMW();
    }

    And finally how i register them. I use reflection because i'm lazy and don't want to type any single item or block into the registration method (since the mod itself adds really tons of stuff)
     

    @EventBusSubscriber
    public class RegistryHandler {
      
    	@SubscribeEvent
    	public static void registerItems(Register<Item> event) {
    		ArrayList<Item> items = new ArrayList<Item>();
    		
    		for (Field itemField : MWItems.class.getFields()) {
    			try {
    				Object obj = itemField.get(MWItems.class);
    				if (obj != null && obj instanceof Item) {
    					Item item = (Item)obj;
    					item.setUnlocalizedName(itemField.getName().toLowerCase());
    					item.setRegistryName(itemField.getName().toLowerCase());
    					items.add(item);
    				}
    			} catch (IllegalArgumentException | IllegalAccessException e) {
    				LogUtils.Exception(e, "RegistryHandler - Register Items");
    			}
    		}
    		
    		event.getRegistry().registerAll(items.toArray(new Item[items.size()]));
    		
    	}
    }

    Both the tab and the items works correctly, i can get them via commands and models/textures show up correctly. If i set the creative tab inside this method they will show up inside the tab, is just when i set the tab into the constructor that they don't :/ Any idea of why this is not working? By the way if you have any idea to improve the registration method, so it keeps register items just by instantiating them from the item class, it would be appreciated :) 

  12. Me too has no problem with the keys itself, it's just that if i have exactly 2 keys of the same category (not more) the Controls screen crash the game. And it looks like it's a bug in the Control GUI, because it doesn't make any sense that more keys within the same category doesn't give the same crash

  13. Yes in the first iteration the keys with the same category was not one after the other, meaning that when the game adds the second key the previous category was a different one and so it adds the duplicate. Fun fact: i've added more keys in the same category and now the controls screen appear and in the gui init the check on s and s1 is correct O_O 

  14. Changing the registration method didn't solved the error, but i've noticed going into debug mode when i enter the controls screen that the key category for KEY_SKILLS and KEY_SKILL_1, wich is the same, is added twice in the key list, while other categories like normal vanilla keybinds categories are added once. Infact, if i move one of them to a new category everything works fine. This is how i register the key binds now

    public static void registerKeys() {
            ClientRegistry.registerKeyBinding(KEY_GUILD);
            ClientRegistry.registerKeyBinding(KEY_SHOP);
            ClientRegistry.registerKeyBinding(KEY_SKILLS);
            ClientRegistry.registerKeyBinding(KEY_SKILL_1);
        }
    

    So am i doing something wrong? And if so how can i register 2 keys within the same category? Or it's a Forge bug? 

  15. Yes, the addKeys is called (as i said the keys itself works normally, if i press one of them they do what they've been registered for). I used the reflection method because i plan to add more keybinds and with this i just have to register it, but i'll try to register them manually and see what happens :/

  16. In my mod i'm registering different key bindings. However for some reason if i go to the Controls screen, to view the keys and re-map them, the game crashes with this error

    java.lang.ArrayIndexOutOfBoundsException: 42
        at net.minecraft.client.gui.GuiKeyBindingList.<init>(GuiKeyBindingList.java:49)
        at net.minecraft.client.gui.GuiControls.initGui(GuiControls.java:38)
        at net.minecraft.client.gui.GuiScreen.setWorldAndResolution(GuiScreen.java:553)
        at net.minecraft.client.Minecraft.displayGuiScreen(Minecraft.java:1018)
        at net.minecraft.client.gui.GuiOptions.actionPerformed(GuiOptions.java:152)
        at net.minecraft.client.gui.GuiScreen.mouseClicked(GuiScreen.java:504)
        at net.minecraft.client.gui.GuiScreen.handleMouseInput(GuiScreen.java:619)
        at net.minecraft.client.gui.GuiScreen.handleInput(GuiScreen.java:585)
        at net.minecraft.client.Minecraft.runTick(Minecraft.java:1797)
        at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1118)
        at net.minecraft.client.Minecraft.run(Minecraft.java:406)
        at net.minecraft.client.main.Main.main(Main.java:118)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at net.minecraft.launchwrapper.Launch.launch(Launch.java:135)
        at net.minecraft.launchwrapper.Launch.main(Launch.java:28)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97)
        at GradleStart.main(GradleStart.java:26)
    


    These are my key bindings

    	package com.rpg.core;
    	import java.lang.reflect.Field;
    	import org.lwjgl.input.Keyboard;
    	import net.minecraft.client.settings.KeyBinding;
    import net.minecraftforge.fml.client.registry.ClientRegistry;
    	public class RPGKeys {
        public static KeyBinding KEY_GUILD;
        public static KeyBinding KEY_SHOP;
        public static KeyBinding KEY_SKILL_1;
        public static KeyBinding KEY_SKILLS;
        
        public static void addKeys() {
            KEY_GUILD = new KeyBinding("keys.guilds.description", Keyboard.KEY_G, "keys.guilds.category");
            KEY_SHOP = new KeyBinding("keys.shop.description", Keyboard.KEY_K, "keys.shop.category");
            KEY_SKILL_1 = new KeyBinding("keys.skills.description", Keyboard.KEY_Z, "keys.skills.category");
            KEY_SKILLS = new KeyBinding("keys.skills.skills", Keyboard.KEY_O, "keys.skills.category");
        }
        
        public static void registerKeys() {
            Field[] fields = RPGKeys.class.getFields();
            for (Field field : fields) {
                try {
                    if (field.get(RPGKeys.class) != null) {
                        ClientRegistry.registerKeyBinding((KeyBinding) field.get(RPGKeys.class));
                    }
                } catch (IllegalArgumentException | IllegalAccessException exception) {
                    exception.printStackTrace();
                }
            }
        }
    }
    

    The keys works as intended, if i remove one key from here everything works fine. It's just in the Controls screen that the crash happen. What could be the cause of this? :/

  17. I tried that event, but i get some issues: the event is fired when the mouse is moved, not only when it's clicked, and if there are two GUI's opened, like the chat gui and the notification, it will take the chat gui because it's a GuiScreen. I also didn't get a way to check where the click happened :/ I guess i'll move on and discard this idea :/

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.