Jump to content

[1.12.2] How do I create Blockstates and howto register them


Bertrahm

Recommended Posts

Hey, I'm currently planning on adding blockstates to my mod, but I couldn't figure out how. I've tried following a tutorial for 1.11.2 but I got stuck at the point of registering them. Heres the code for the block I wrote and my registry code.

 

Block

Spoiler

package com.linesix.akhaten.common.blocks.building;

import com.linesix.akhaten.common.Reference;
import com.linesix.akhaten.common.blocks.BlockTypes;
import com.linesix.akhaten.common.blocks.BuildingBlocks;
import com.linesix.akhaten.common.blocks.Names;
import com.linesix.akhaten.util.Misc;
import net.minecraft.block.Block;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.PropertyEnum;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.ItemStack;
import net.minecraft.util.NonNullList;

import com.linesix.akhaten.common.blocks.item.IMetaBlockName;
import net.minecraft.block.state.IBlockState;
import net.minecraft.block.properties.IProperty;

public class HartnellRoundel extends Block implements IMetaBlockName {

    public static final PropertyEnum TYPE = PropertyEnum.create("type", BlockTypes.HartnellRoundelTypes.class);

    public HartnellRoundel() { // Hartnell Roundel constructor

        super(Material.IRON);

        setUnlocalizedName(getUnlocalizedName());
        setRegistryName(Reference.RESOURCE_PREFIX + Names.Machines.Tardis.Roundels.hartnell_roundels);
        setCreativeTab(BuildingBlocks.buildblocktab);
        setSoundType(SoundType.METAL);
        //setDefaultState(this.blockState.getBaseState().withProperty(TYPE, BlockTypes.HartnellRoundelTypes.NORMAL));

    }

    @Override
    public String getUnlocalizedName() {

        return "tile." + Reference.RESOURCE_PREFIX + Names.Machines.Tardis.Roundels.hartnell_roundels;

    }

    // Block State related code below \/

    @Override
    protected BlockStateContainer createBlockState() {

        return new BlockStateContainer(this, new IProperty[] {TYPE});

    }

    @Override
    public int getMetaFromState(IBlockState state) {

        BlockTypes.HartnellRoundelTypes type = (BlockTypes.HartnellRoundelTypes) state.getValue(TYPE);

        return type.getID();

    }

    @Override
    public IBlockState getStateFromMeta(int meta) {

        return this.getDefaultState().withProperty(TYPE, BlockTypes.HartnellRoundelTypes.values()[meta]);

    }

    @Override
    public void getSubBlocks(CreativeTabs itemIn, NonNullList<ItemStack> items) {

        for(int i = 0; i < BlockTypes.HartnellRoundelTypes.values().length; i++) {

            items.add(new ItemStack(this, 1, i));

        }

    }

    @Override
    public String getSpecialName(ItemStack stack) {
        String unlocName = stack.getUnlocalizedName();
        int index = Misc.getIndexByVal(unlocName, BlockTypes.HartnellRoundelTypes.unlocNames);
        System.out.println(unlocName); // DEBUG
        return BlockTypes.HartnellRoundelTypes.values()[index].getName();
    }

}

 

 

Registry

Spoiler

package com.linesix.akhaten.common.blocks;

import com.google.common.base.Preconditions;
import com.linesix.akhaten.common.Reference;
import com.linesix.akhaten.common.blocks.building.HartnellRoundel;
import com.linesix.akhaten.common.blocks.building.Door;
import com.linesix.akhaten.tabs.TabBuilding;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.registries.IForgeRegistry;

import java.util.HashSet;
import java.util.Set;

@Mod.EventBusSubscriber(modid = Reference.MODID)
public class BuildingBlocks {

    /*
     * Registration Handler of all Building Blocks
     *
     * Author: Felix Eckert (TheBertrahmPlays / Angry German)
     *
     */

    public static final Set<ItemBlock> ITEM_BLOCKS = new HashSet<>(); // Create a set for all item blocks

    public static CreativeTabs buildblocktab = new TabBuilding();

    private static Block[] blocks; // Create an array for all blocks

    // Creation of all Block-Variables below
    public static HartnellRoundel block_roundel;
    public static Door block_door;
    // End Creation of all Block-Variables

    public static void init() {

        Reference.logger.info("Initializing building-block-variables...");

        // Initialization of Block-Variables below
        try {

            block_roundel = new HartnellRoundel();
            block_door = new Door();

        } catch (Exception e) { // If theres an error whilst initializing any of the Variables, execute the code below

            throw e;

        } finally { // When everything is done, execute the code below

            Reference.logger.info("DONE!");

        }

        // End Initialization of Block-Variables

    }

    @SubscribeEvent
    public static void RegisterBlocks(final RegistryEvent.Register<Block> event) {

        final IForgeRegistry<Block> registry = event.getRegistry(); // Put the registry in a variable

        blocks = new Block[] { // Add all block vars in this array

                block_roundel,
                block_door

        };

        registry.registerAll(blocks); // Register all blocks at once

    }

    @SubscribeEvent
    public static void registerItemBlocks(final RegistryEvent.Register<Item> event) {

        final IForgeRegistry<Item> registry = event.getRegistry();

        final ItemBlock[] items = { // Put the registry in a variable

                new ItemBlock(block_roundel),
                new ItemBlock(block_door)

        };

        for (final ItemBlock item : items) {

            final Block block = item.getBlock(); // Get the ItemBlock

            final ResourceLocation registryName = Preconditions.checkNotNull(block.getRegistryName(),
                    "Block %s gas null registry name", block); // Get the registry name of the block (if it's not null)
            registry.register(item.setRegistryName(registryName)); // Set the registry name to content of variable
            // "registryName"

            ITEM_BLOCKS.add(item); // Finally add the item to The ITEM_BLOCKS set

        }

    }

    @SubscribeEvent
    public static void registerRenders(ModelRegistryEvent event) {

        for (final Block block : blocks) {

            registerRender(Item.getItemFromBlock(block));

        }

    }

    public static void registerRender(Item item) {

        ModelLoader.setCustomModelResourceLocation(item, 0,
                new ModelResourceLocation(item.getRegistryName(), "inventory"));

    }

}

 

If there is a newer / better way todo this, I'd be happy to use it

Link to comment
Share on other sites

2 hours ago, Bertrahm said:

    @Override
    protected BlockStateContainer createBlockState() {

        return new BlockStateContainer(this, new IProperty[] {TYPE});

    }

Congratulations! You made a block with block states!

 

Now all you need to do is create a blockstate json file that tells the game what model to use for each state. It has the same file name as the registry name of the block (minus mod ID) that goes inside assets/modid/blockstates

 

Quote

        try {

            block_roundel = new HartnellRoundel();
            block_door = new Door();

        } catch (Exception e) { // If theres an error whilst initializing any of the Variables, execute the code below

            throw e;

        }

What? Why? If you're going to do fuckall with an error, why even catch it? Just let the game die. Further more, there should never BE errors here, if there are, you need to FIX THEM because THEY ARE BUGS. Exceptions are for things you cannot anticipate, such as trying to read a file off the disk and, oops, another process deleted it.

 

Quote

ITEM_BLOCKS.add(item); // Finally add the item to The ITEM_BLOCKS set

Why though? Why do you need this list? Do you ever do anything with it? Of course not because you can (and do) call Item.getItemFromBlock(block) later on.

Edited by Draco18s

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

6 hours ago, Bertrahm said:

Thanks for your answer! So now I just have to create the blockstate JSON and the registration stays the same (I wasn't sure because I followed an outdated tutorial).

Yes, its handled automatically because of createBlockState(). Whatever it returns is what gets looked for in the blockstate file. Note that even a block without states still has a state. Its just an unnamed state with no properties, but the blockstate json file still has to map that block to a model. eg:

 

https://github.com/Draco18s/ReasonableRealism/blob/1.12.1/src/main/resources/assets/harderores/blockstates/sifter.json

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Ok, got another problem: My second blockstate is called

high_res

but in the blockstate JSON I don't get a inventory model nor the textures ( inventory and placed).

Here's my JSON and the Blocktype class:

Spoiler

package com.linesix.akhaten.common.blocks;

import com.linesix.akhaten.common.Reference;
import net.minecraft.util.IStringSerializable;

public class BlockTypes {

   /* This class contains sub-classes (enums) for Blocktypes
    *
    * Author: Felix Eckert ( TheBertrahmPlays / Angry German )
    *
    */

    public enum HartnellRoundelTypes implements IStringSerializable {

        // This enum contains different block-types
        // of the 1963 / William Hartnell Roundels

        NORMAL("normal", 0),
        HIGHRES("high_res", 1);

        private int ID;
        private String name;

        HartnellRoundelTypes(String name, int ID) {
        	
            this.ID = ID;
            this.name = name;
        	
        }
        
        @Override
        public String getName() {
            return this.name;
        }
        
        public int getID() {
            return this.ID;
        }

        @Override
        public String toString() {
            return getName();
        }
        
    }

}

 

Spoiler

{
  "forge_marker":"1",
  "defaults": {
	"textures": {
		"all":"akhaten:blocks/block_roundelhartnell"
	}
	"model":"akhaten:blocks/block_roundelhartnell",
	"uvlock":"false"
  }
  "variants": {
    "normal": [
      { "model": "akhaten:block_roundelhartnell" }
    ],
	"high_res":[
	  { "model": "akhaten:block_roundelhartnellhr" }
	]
  }
}

 

 

Link to comment
Share on other sites

8 hours ago, Bertrahm said:

I don't get a inventory model nor the textures ( inventory and placed).

You have to register an item mode in the ModelRegistryEvent.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

28 minutes ago, Draco18s said:

You have to register an item mode in the ModelRegistryEvent.

Here’s a simple event subscriber that replicated the automated 1.13 style of model registration for 1.12.2 https://gist.github.com/Cadiboo/3f5cdb785affc069af2fa5fdf2d70358

About Me

Spoiler

My Discord - Cadiboo#8887

My WebsiteCadiboo.github.io

My ModsCadiboo.github.io/projects

My TutorialsCadiboo.github.io/tutorials

Versions below 1.14.4 are no longer supported on this forum. Use the latest version to receive support.

When asking support remember to include all relevant log files (logs are found in .minecraft/logs/), code if applicable and screenshots if possible.

Only download mods from trusted sites like CurseForge (minecraft.curseforge.com). A list of bad sites can be found here, with more information available at stopmodreposts.org

Edit your own signature at www.minecraftforge.net/forum/settings/signature/ (Make sure to check its compatibility with the Dark Theme)

Link to comment
Share on other sites

3 hours ago, Cadiboo said:

Here’s a simple event subscriber that replicated the automated 1.13 style of model registration for 1.12.2 https://gist.github.com/Cadiboo/3f5cdb785affc069af2fa5fdf2d70358

Thanks, but it didn't help... I think I should make myself more clear:

For the default state I get an Inventory model with textures but no textures when I place it, for my second state (high_res) I don't get a model in the inventory nor textures when I place it. I will show you the relevant part of the log (regarding the model registry). I've also fixed errors with my blockstate JSON, which also didn't fix anything (visible)...

 

Spoiler

[10:05:27] [Client thread/ERROR] [FML]: Exception loading model for variant akhaten:block_roundelhartnell#type=normal for blockstate "akhaten:block_roundelhartnell[type=normal]"
net.minecraftforge.client.model.ModelLoaderRegistry$LoaderException: Exception loading model akhaten:block_roundelhartnell#type=normal with loader VariantLoader.INSTANCE, skipping
	at net.minecraftforge.client.model.ModelLoaderRegistry.getModel(ModelLoaderRegistry.java:161) ~[ModelLoaderRegistry.class:?]
	at net.minecraftforge.client.model.ModelLoader.registerVariant(ModelLoader.java:235) ~[ModelLoader.class:?]
	at net.minecraft.client.renderer.block.model.ModelBakery.loadBlock(ModelBakery.java:153) ~[ModelBakery.class:?]
	at net.minecraftforge.client.model.ModelLoader.loadBlocks(ModelLoader.java:223) ~[ModelLoader.class:?]
	at net.minecraftforge.client.model.ModelLoader.setupModelRegistry(ModelLoader.java:150) ~[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:560) [Minecraft.class:?]
	at net.minecraft.client.Minecraft.run(Minecraft.java:422) [Minecraft.class:?]
	at net.minecraft.client.main.Main.main(Main.java:118) [Main.class:?]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_211]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_211]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_211]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_211]
	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_211]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_211]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_211]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_211]
	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:?]
	... 21 more

 

 

Link to comment
Share on other sites

Show more of the error. MissingVariantException is an exception caused by another exception that prints out below it.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...

Important Information

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