Jump to content

Recommended Posts

Posted

UPDATE 5-8-2016: I have now figured out how to get my slabs working, and I have updated this post with the working code. The original post can be seen in the spoiler at the bottom. Thanks for the help, everyone! If you have any questions about certain parts of my code or suggestions on how to do it better let me know!

 

Working Code for slabs with additional blockstates/metadata in Minecraft 1.8.9:

 

 

My code package structure (for reference):

colore

-client

--render

-common

--blocks

--creativeTabs

--init

--items

--worldGeneration

-proxy

-utility

 

//common.blocks package//

 

BlockColoreSlab.java

package com.supergeniuszeb.colore.common.blocks;

import java.util.Random;

import net.minecraft.block.BlockSlab;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.properties.PropertyEnum;
import net.minecraft.block.state.BlockState;
import net.minecraft.block.state.IBlockState;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.BlockPos;
import net.minecraft.util.IStringSerializable;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.world.World;

//An abstract class for both half-slabs and full/double slabs.
public abstract class BlockColoreSlab extends BlockSlab implements IMetaBlockName{

public BlockColoreSlab(String unlocalizedName) {
	super(Material.rock);
	this.setHardness(1.5f);
	this.setHarvestLevel("pickaxe", 0);
	this.setResistance(10.0f);
	this.setUnlocalizedName(unlocalizedName);
	this.useNeighborBrightness = !this.isDouble();

	//Sets default state depending on whether block is a half-slab or double-slab.
	IBlockState blockState = this.blockState.getBaseState();
        blockState = blockState.withProperty(SHADE, EnumShade.NORMAL);
        if (!this.isDouble()) {
            blockState = blockState.withProperty(HALF, EnumBlockHalf.BOTTOM);
        }

        this.setDefaultState(blockState);
}

public enum EnumShade implements IStringSerializable {
	NORMAL(0, "normal"),
	LIGHT(1, "light"),
	LIGHTER(2, "lighter"),
	DARK(3, "dark"),
	DARKER(4, "darker");

	private int ID;
	private String name;

	private EnumShade(int ID, String name) {
		this.ID = ID;
		this.name = name;
	}

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

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

	public int getID() {
        return ID;
    }

}

//The shade ("light", "dark", etc.) of the slab. The "HALF" property is defined in the vanilla BlockSlab class so I don't need to make my own.
public static final PropertyEnum SHADE = PropertyEnum.create("shade", BlockColoreSlab.EnumShade.class);

//Function to get the variant property created above based on the item.
@Override
public final Object getVariant(final ItemStack itemstack) {
	return getStateFromMeta(itemstack.getMetadata()).getValue(SHADE);
}

//Function to get the variant property.
@Override
public final IProperty getVariantProperty() {
	return SHADE;
}

//I feel like there must be a simpler way to do this, but here's how I make the
//double slabs drop their corresponding half slabs. Note my use of the getHalfSlab()
//method I created for indirectly obtaining the value of ItemSlab's singleSlab
//param, which is private.
@Override
public Item getItemDropped(IBlockState state, Random rand, int fortune){
	int meta = this.getMetaFromState(state);
	Item item = Item.getItemFromBlock(((ItemBlockColoreSlab) Item.getItemFromBlock(this)).getHalfSlab());
	switch (meta) {
		case 0:
		case 5:
			return new ItemStack(item, 2, 0).getItem();
		case 1:
		case 6:
			return new ItemStack(item, 2, 1).getItem();
		case 2:
		case 7:
			return new ItemStack(item, 2, 2).getItem();
		case 3:
		case 8:
			return new ItemStack(item, 2, 3).getItem();
		case 4:
		case 9:
			return new ItemStack(item, 2, 4).getItem();
		default:
			return new ItemStack(item, 2, 0).getItem();
	}
}

@Override
protected BlockState createBlockState() {
	return new BlockState(this, new IProperty[] {SHADE, HALF});
}

//Converts an IBlockState into metadata.
@Override
public IBlockState getStateFromMeta(int meta) {

	//A blockState is created, which is assigned the SHADE property depending on its metadata, as well as the HALF property, if it is a half-slab.
	IBlockState blockState = this.getDefaultState();

	if (!this.isDouble()) { //If the block is a BlockColoreHalfSlab
		switch (meta) {
			case 0:
				blockState = blockState.withProperty(SHADE, EnumShade.NORMAL).withProperty(HALF, EnumBlockHalf.BOTTOM);
				break; //Note-to-self: DON'T FORGET TO USE THIS IN SWITCH STATEMENTS IF RETURN STATEMENTS AREN'T INVOLVED!
			case 1:
				blockState = blockState.withProperty(SHADE, EnumShade.LIGHT).withProperty(HALF, EnumBlockHalf.BOTTOM);
				break;
			case 2:
				blockState = blockState.withProperty(SHADE, EnumShade.LIGHTER).withProperty(HALF, EnumBlockHalf.BOTTOM);
				break;
			case 3:
				blockState = blockState.withProperty(SHADE, EnumShade.DARK).withProperty(HALF, EnumBlockHalf.BOTTOM);
				break;
			case 4:
				blockState = blockState.withProperty(SHADE, EnumShade.DARKER).withProperty(HALF, EnumBlockHalf.BOTTOM);
				break;
			case 5:
				blockState = blockState.withProperty(SHADE, EnumShade.NORMAL).withProperty(HALF, EnumBlockHalf.TOP);
				break;
			case 6:
				blockState = blockState.withProperty(SHADE, EnumShade.LIGHT).withProperty(HALF, EnumBlockHalf.TOP);
				break;
			case 7:
				blockState = blockState.withProperty(SHADE, EnumShade.LIGHTER).withProperty(HALF, EnumBlockHalf.TOP);
				break;
			case 8:
				blockState = blockState.withProperty(SHADE, EnumShade.DARK).withProperty(HALF, EnumBlockHalf.TOP);
				break;
			case 9:
				blockState = blockState.withProperty(SHADE, EnumShade.DARKER).withProperty(HALF, EnumBlockHalf.TOP);
				break;
			default:
				blockState = blockState.withProperty(SHADE, EnumShade.NORMAL).withProperty(HALF, EnumBlockHalf.BOTTOM);
				break;
		}
	} else { //If the block is a BlockColoreDoubleSlab
		switch (meta) {
			case 0:
				blockState = blockState.withProperty(SHADE, EnumShade.NORMAL);
				break;
			case 1:
				blockState = blockState.withProperty(SHADE, EnumShade.LIGHT);
				break;
			case 2:
				blockState = blockState.withProperty(SHADE, EnumShade.LIGHTER);
				break;
			case 3:
				blockState = blockState.withProperty(SHADE, EnumShade.DARK);
				break;
			case 4:
				blockState = blockState.withProperty(SHADE, EnumShade.DARKER);
				break;
			default:
				blockState = blockState.withProperty(SHADE, EnumShade.NORMAL);
				break;
		}
	}

	return blockState;
}

//Converts metadata into an IBlockState.
@Override
public int getMetaFromState(IBlockState state) {

    EnumShade shade = (EnumShade) state.getValue(SHADE);
    
    if (!this.isDouble()) {
    	EnumBlockHalf half = (EnumBlockHalf) state.getValue(HALF);
    	
    	//0-4 are bottom slabs, and 5-9 are the top slabs, so if the HALF property = top,
    	//then 5 is added to the ID integer assigned to the SHADE property. This is done
    	//to match up with how I've assigned the 10 different metadata values. (I hope
    	//this comment made sense so I don't come back later trying to find out why I did
    	//this and get disappointed with my former self's explanatory skills...)
    	if (half == EnumBlockHalf.TOP) {
    		return shade.getID() + 5; 
    	}
    }
    
    return shade.getID();
}

//This insures that  the meta block drops an item-block with the correct metadata when mined. This is
//somewhat trickier than with a regular block since you don't want to drop a "top" or "bottom" half slab.
//You only want to drop... well, just a slab! (Or more technically, a default, or bottom, half slab.
//Of course, if you're breaking a double-slab, it shouldn't drop a block with the HALF property at all.
@Override
public int damageDropped(IBlockState state) {
	if (!this.isDouble()) {
		//Using my neat math tricks in conjuction with how I've set up the 9 metadata values so that
		//0-4 are bottom slabs and 5-9 are top slabs.
		if (getMetaFromState(state) > 4) { //If the block is a top slab, then drop a bottom slab.
			return getMetaFromState(state) - 5;
		}
	}
	//If the block is a bottom slab or double slab, then drop a block with a metadata between 0-4.
	//The value of the SHADE property is assigned to the same 5 integers for both bottom half slabs
	//and double slabs, so this works. Hooray for clever metadata-blockstate-math-stuff!
    return getMetaFromState(state);
}

//Used to get the last part of the unlocalized name for the item-block.
//The structure of the unlocalized name is: tile.blockname.specialname.name
@Override
public String getSpecialName(ItemStack stack) {
	switch (stack.getItemDamage()) {
		case 0:
			return "normal";
		case 1:
			return "light";
		case 2:
			return "lighter";
		case 3:
			return "dark";
		case 4:
			return "darker";
		default:
			return "normal";
	}
}

@Override
    public final String getUnlocalizedName(final int meta) {
        return this.getUnlocalizedName();
    }

//This ensures that the pick-block button (normally middle-click) will give
//an item-block with the correct metadata. Top & bottom half slabs will both
//return bottom slabs, and double slabs will return themselves.
@Override
public ItemStack getPickBlock(MovingObjectPosition target, World world, BlockPos pos) {
	int meta = this.getMetaFromState(world.getBlockState(pos));
	if (meta > 4) { //If the block is a top half slab
		meta = meta - 5; //Pick-block should return a bottom half slab...
	}
    return new ItemStack(Item.getItemFromBlock(this), 1, meta);
}
}

 

BlockColoreSlabHalf.java

package com.supergeniuszeb.colore.common.blocks;

public class BlockColoreSlabHalf extends BlockColoreSlab {

public BlockColoreSlabHalf(String unlocalizedName) {
	super(unlocalizedName);
}

@Override
public boolean isDouble() {
	return false;
}

}

 

BlockColoreSlabDouble.java

package com.supergeniuszeb.colore.common.blocks;

public class BlockColoreSlabDouble extends BlockColoreSlab {

public BlockColoreSlabDouble(String unlocalizedName) {
	super(unlocalizedName);
}

@Override
public boolean isDouble() {
	return true;
}

}

 

ItemBlockColoreSlab.java

package com.supergeniuszeb.colore.common.blocks;

import java.util.ArrayList;
import java.util.List;

import net.minecraft.block.Block;
import net.minecraft.block.BlockSlab;
import net.minecraft.item.Item;
import net.minecraft.item.ItemSlab;
import net.minecraft.item.ItemStack;

/*
* Wrapper class to make sure that GameRegistry.registerBlock() calls the right constructor.
*/
public class ItemBlockColoreSlab extends ItemSlab {

public ItemBlockColoreSlab(final Block block, final BlockColoreSlabHalf singleSlab, final BlockColoreSlabDouble doubleSlab) {
	super(block, singleSlab, doubleSlab);
	this.setHasSubtypes(true);
        this.getSubBlocks(slabList, this, 5);
        this.setHalfSlab(singleSlab);
}

//This variable and the setter & getter that follow were made by me to get the value of the private
//param this.singleSlab from ItemSlab's constructor. This is my indirect and probably inefficient
//way to make my double slabs drop their half slab counterparts. See usage in BlockColoreSlab.getItemDropped().
private BlockSlab halfSlab;

public void setHalfSlab(BlockSlab slab) {
	this.halfSlab = slab;
}

public BlockSlab getHalfSlab() {
	return this.halfSlab;
}

@Override
    public String getUnlocalizedName(ItemStack stack) {
	//If the block is a double slab, "double_" will be added to the unlocalized name.
	//Note how "tile." is removed via .substring after "tile.double_" is added so that
	//"double_" can be effectively added to the unlocalizedName after the "tile."
	//It's kind of messy, but at least it works.
	if (((BlockColoreSlab) this.getBlock()).isDouble()) {
		return "tile.double_" + super.getUnlocalizedName(stack).substring(5) + "." + ((IMetaBlockName)this.block).getSpecialName(stack);
	}
        return super.getUnlocalizedName(stack) + "." + ((IMetaBlockName)this.block).getSpecialName(stack);
}

public static List slabList = new ArrayList<Item>(5) {};

	//This will add all the different metadata variations of the slabs
	//as "ItemStack"s to the slabList list. Used when adding metadata
	//blocks to the creative tabs.
	public void getSubBlocks(List slabList, Item item, int range) {
		//This prevents any double slabs from showing up in the creative tab.
		if (!((BlockColoreSlab) Block.getBlockFromItem(item)).isDouble()) {
			for (int i = 0; i < range; ++i) {
	            slabList.add(new ItemStack(item, 1, i));
	        }
		}
	}

}

 

 

//common.init package//

 

ModBlocks.java (renamed from BlockRegistry.java)

package com.supergeniuszeb.colore.common.init;

import com.supergeniuszeb.colore.common.blocks.BlockColore;
import com.supergeniuszeb.colore.common.blocks.BlockColoreOre;
import com.supergeniuszeb.colore.common.blocks.BlockColoreSlab;
import com.supergeniuszeb.colore.common.blocks.BlockColoreSlabDouble;
import com.supergeniuszeb.colore.common.blocks.BlockColoreSlabHalf;
import com.supergeniuszeb.colore.common.blocks.ItemBlockColore;
import com.supergeniuszeb.colore.common.blocks.ItemBlockColoreSlab;

import net.minecraftforge.fml.common.registry.GameRegistry;

public class ModBlocks {

//regular blocks
public static BlockColore block_of_red;
public static BlockColore block_of_reddish_orange;
public static BlockColore block_of_orange;
public static BlockColore block_of_orangish_yellow;
public static BlockColore block_of_yellow;
public static BlockColore block_of_yellowish_green;
public static BlockColore block_of_green;
public static BlockColore block_of_cyan;
public static BlockColore block_of_blue;
public static BlockColore block_of_indigo;
public static BlockColore block_of_purple;
public static BlockColore block_of_magenta;
public static BlockColore block_of_brown;
public static BlockColore block_of_grayscale;

//half slabs
public static BlockColoreSlab slab_of_red = new BlockColoreSlabHalf("slab_of_red");
public static BlockColoreSlab slab_of_reddish_orange = new BlockColoreSlabHalf("slab_of_reddish_orange");
public static BlockColoreSlab slab_of_orange = new BlockColoreSlabHalf("slab_of_orange");
public static BlockColoreSlab slab_of_orangish_yellow = new BlockColoreSlabHalf("slab_of_orangish_yellow");
public static BlockColoreSlab slab_of_yellow = new BlockColoreSlabHalf("slab_of_yellow");
public static BlockColoreSlab slab_of_yellowish_green = new BlockColoreSlabHalf("slab_of_yellowish_green");
public static BlockColoreSlab slab_of_green = new BlockColoreSlabHalf("slab_of_green");
public static BlockColoreSlab slab_of_cyan = new BlockColoreSlabHalf("slab_of_cyan");
public static BlockColoreSlab slab_of_blue = new BlockColoreSlabHalf("slab_of_blue");
public static BlockColoreSlab slab_of_indigo = new BlockColoreSlabHalf("slab_of_indigo");
public static BlockColoreSlab slab_of_purple = new BlockColoreSlabHalf("slab_of_purple");
public static BlockColoreSlab slab_of_magenta = new BlockColoreSlabHalf("slab_of_magenta");
public static BlockColoreSlab slab_of_brown = new BlockColoreSlabHalf("slab_of_brown");
public static BlockColoreSlab slab_of_grayscale = new BlockColoreSlabHalf("slab_of_grayscale");

//double slabs
public static BlockColoreSlab double_slab_of_red = new BlockColoreSlabDouble("double_slab_of_red");
public static BlockColoreSlab double_slab_of_reddish_orange = new BlockColoreSlabDouble("double_slab_of_reddish_orange");
public static BlockColoreSlab double_slab_of_orange = new BlockColoreSlabDouble("double_slab_of_orange");
public static BlockColoreSlab double_slab_of_orangish_yellow = new BlockColoreSlabDouble("double_slab_of_orangish_yellow");
public static BlockColoreSlab double_slab_of_yellow = new BlockColoreSlabDouble("double_slab_of_yellow");
public static BlockColoreSlab double_slab_of_yellowish_green = new BlockColoreSlabDouble("double_slab_of_yellowish_green");
public static BlockColoreSlab double_slab_of_green = new BlockColoreSlabDouble("double_slab_of_green");
public static BlockColoreSlab double_slab_of_cyan = new BlockColoreSlabDouble("double_slab_of_cyan");
public static BlockColoreSlab double_slab_of_blue = new BlockColoreSlabDouble("double_slab_of_blue");
public static BlockColoreSlab double_slab_of_indigo = new BlockColoreSlabDouble("double_slab_of_indigo");
public static BlockColoreSlab double_slab_of_purple = new BlockColoreSlabDouble("double_slab_of_purple");
public static BlockColoreSlab double_slab_of_magenta = new BlockColoreSlabDouble("double_slab_of_magenta");
public static BlockColoreSlab double_slab_of_brown = new BlockColoreSlabDouble("double_slab_of_brown");
public static BlockColoreSlab double_slab_of_grayscale = new BlockColoreSlabDouble("double_slab_of_grayscale");

//ore blocks	
public static BlockColoreOre essence_ore;

public static void registerBlocks() {
	//regular blocks
	GameRegistry.registerBlock(block_of_red = new BlockColore("block_of_red"), ItemBlockColore.class, "block_of_red");
	GameRegistry.registerBlock(block_of_reddish_orange = new BlockColore("block_of_reddish_orange"), ItemBlockColore.class, "block_of_reddish_orange");
	GameRegistry.registerBlock(block_of_orange = new BlockColore("block_of_orange"), ItemBlockColore.class, "block_of_orange");
	GameRegistry.registerBlock(block_of_orangish_yellow = new BlockColore("block_of_orangish_yellow"), ItemBlockColore.class, "block_of_orangish_yellow");
	GameRegistry.registerBlock(block_of_yellow = new BlockColore("block_of_yellow"), ItemBlockColore.class, "block_of_yellow");
	GameRegistry.registerBlock(block_of_yellowish_green = new BlockColore("block_of_yellowish_green"), ItemBlockColore.class, "block_of_yellowish_green");
	GameRegistry.registerBlock(block_of_green = new BlockColore("block_of_green"), ItemBlockColore.class, "block_of_green");
	GameRegistry.registerBlock(block_of_cyan = new BlockColore("block_of_cyan"), ItemBlockColore.class, "block_of_cyan");
	GameRegistry.registerBlock(block_of_blue = new BlockColore("block_of_blue"), ItemBlockColore.class, "block_of_blue");
	GameRegistry.registerBlock(block_of_indigo = new BlockColore("block_of_indigo"), ItemBlockColore.class, "block_of_indigo");
	GameRegistry.registerBlock(block_of_purple = new BlockColore("block_of_purple"), ItemBlockColore.class, "block_of_purple");
	GameRegistry.registerBlock(block_of_magenta = new BlockColore("block_of_magenta"), ItemBlockColore.class, "block_of_magenta");
	GameRegistry.registerBlock(block_of_brown = new BlockColore("block_of_brown"), ItemBlockColore.class, "block_of_brown");
	GameRegistry.registerBlock(block_of_grayscale = new BlockColore("block_of_grayscale"), ItemBlockColore.class, "block_of_grayscale");

	//half slabs
	GameRegistry.registerBlock(slab_of_red, ItemBlockColoreSlab.class, "slab_of_red", slab_of_red, double_slab_of_red);
	GameRegistry.registerBlock(slab_of_reddish_orange, ItemBlockColoreSlab.class, "slab_of_reddish_orange", slab_of_reddish_orange, double_slab_of_reddish_orange);
	GameRegistry.registerBlock(slab_of_orange, ItemBlockColoreSlab.class, "slab_of_orange", slab_of_orange, double_slab_of_orange);
	GameRegistry.registerBlock(slab_of_orangish_yellow, ItemBlockColoreSlab.class, "slab_of_orangish_yellow", slab_of_orangish_yellow, double_slab_of_orangish_yellow);
	GameRegistry.registerBlock(slab_of_yellow, ItemBlockColoreSlab.class, "slab_of_yellow", slab_of_yellow, double_slab_of_yellow);
	GameRegistry.registerBlock(slab_of_yellowish_green, ItemBlockColoreSlab.class, "slab_of_yellowish_green", slab_of_yellowish_green, double_slab_of_yellowish_green);
	GameRegistry.registerBlock(slab_of_green, ItemBlockColoreSlab.class, "slab_of_green", slab_of_green, double_slab_of_green);
	GameRegistry.registerBlock(slab_of_cyan, ItemBlockColoreSlab.class, "slab_of_cyan", slab_of_cyan, double_slab_of_cyan);
	GameRegistry.registerBlock(slab_of_blue, ItemBlockColoreSlab.class, "slab_of_blue", slab_of_blue, double_slab_of_blue);
	GameRegistry.registerBlock(slab_of_indigo, ItemBlockColoreSlab.class, "slab_of_indigo", slab_of_indigo, double_slab_of_indigo);
	GameRegistry.registerBlock(slab_of_purple, ItemBlockColoreSlab.class, "slab_of_purple", slab_of_purple, double_slab_of_purple);
	GameRegistry.registerBlock(slab_of_magenta, ItemBlockColoreSlab.class, "slab_of_magenta", slab_of_magenta, double_slab_of_magenta);
	GameRegistry.registerBlock(slab_of_brown, ItemBlockColoreSlab.class, "slab_of_brown", slab_of_brown, double_slab_of_brown);
	GameRegistry.registerBlock(slab_of_grayscale, ItemBlockColoreSlab.class, "slab_of_grayscale", slab_of_grayscale, double_slab_of_grayscale);

	//double slabs
	GameRegistry.registerBlock(double_slab_of_red, ItemBlockColoreSlab.class, "double_slab_of_red", slab_of_red, double_slab_of_red);
	GameRegistry.registerBlock(double_slab_of_reddish_orange, ItemBlockColoreSlab.class, "double_slab_of_reddish_orange", slab_of_reddish_orange, double_slab_of_reddish_orange);
	GameRegistry.registerBlock(double_slab_of_orange, ItemBlockColoreSlab.class, "double_slab_of_orange", slab_of_orange, double_slab_of_orange);
	GameRegistry.registerBlock(double_slab_of_orangish_yellow, ItemBlockColoreSlab.class, "double_slab_of_orangish_yellow", slab_of_orangish_yellow, double_slab_of_orangish_yellow);
	GameRegistry.registerBlock(double_slab_of_yellow, ItemBlockColoreSlab.class, "double_slab_of_yellow", slab_of_yellow, double_slab_of_yellow);
	GameRegistry.registerBlock(double_slab_of_yellowish_green, ItemBlockColoreSlab.class, "double_slab_of_yellowish_green", slab_of_yellowish_green, double_slab_of_yellowish_green);
	GameRegistry.registerBlock(double_slab_of_green, ItemBlockColoreSlab.class, "double_slab_of_green", slab_of_green, double_slab_of_green);
	GameRegistry.registerBlock(double_slab_of_cyan, ItemBlockColoreSlab.class, "double_slab_of_cyan", slab_of_cyan, double_slab_of_cyan);
	GameRegistry.registerBlock(double_slab_of_blue, ItemBlockColoreSlab.class, "double_slab_of_blue", slab_of_blue, double_slab_of_blue);
	GameRegistry.registerBlock(double_slab_of_indigo, ItemBlockColoreSlab.class, "double_slab_of_indigo", slab_of_indigo, double_slab_of_indigo);
	GameRegistry.registerBlock(double_slab_of_purple, ItemBlockColoreSlab.class, "double_slab_of_purple", slab_of_purple, double_slab_of_purple);
	GameRegistry.registerBlock(double_slab_of_magenta, ItemBlockColoreSlab.class, "double_slab_of_magenta", slab_of_magenta, double_slab_of_magenta);
	GameRegistry.registerBlock(double_slab_of_brown, ItemBlockColoreSlab.class, "double_slab_of_brown", slab_of_brown, double_slab_of_brown);
	GameRegistry.registerBlock(double_slab_of_grayscale, ItemBlockColoreSlab.class, "double_slab_of_grayscale", slab_of_grayscale, double_slab_of_grayscale);

	GameRegistry.registerBlock(essence_ore = new BlockColoreOre("essence_ore"), ItemBlockColore.class, "essence_ore");
}
}

 

 

//client.render package//

 

BlockRenders.java (renamed from BlockRenderRegistry.java)

	package com.supergeniuszeb.colore.client.render;

import com.supergeniuszeb.colore.Reference;
import com.supergeniuszeb.colore.common.init.ModBlocks;
import com.supergeniuszeb.colore.utility.ModUtilities;

import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.model.ModelBakery;
import net.minecraft.client.resources.model.ModelResourceLocation;
import net.minecraft.item.Item;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.common.registry.GameRegistry;

//All this handles are the item-block models, not the actual block models, which are
//defined in the .json files.
public class BlockRenders {

//This method is called by the registerRenders method every time it adds an item-block model without metadata specified.
public static void registerRender(Block block) {
	Item item = Item.getItemFromBlock(block);
	Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(Item.getItemFromBlock(block), 0, new ModelResourceLocation(block.getRegistryName(), "inventory"));
}

//This method is called by the init method every time it adds an item-block model with metadata specified.
public static void registerRender(Block block, int meta, String metaName) {
	Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(Item.getItemFromBlock(block), meta, new ModelResourceLocation(block.getRegistryName() + "_" + metaName, "inventory"));
}

public static void preInit() {
	for (String color : ModUtilities.colorList) {
		for (String shade : ModUtilities.shadeList) {
			for (String blockType : ModUtilities.blockTypeList) {
				//standard blocks, half slabs, & double slabs
				ModelBakery.registerItemVariants(Item.getItemFromBlock(GameRegistry.findBlock(Reference.MOD_ID, blockType + "_of_" + color)), new ResourceLocation(Reference.MOD_ID, blockType + "_of_" + color + "_" + shade));
			}
		}
	}
	for (String color : ModUtilities.baseColorList) {
		//ore blocks
		ModelBakery.registerItemVariants(Item.getItemFromBlock(ModBlocks.essence_ore), new ResourceLocation(Reference.MOD_ID, "essence_ore_" + color));
	}
}

public static void init() {
	int i = 0;
	for (String shade : ModUtilities.shadeList) {
		for (String color : ModUtilities.colorList) {
			for (String blockType : ModUtilities.blockTypeList) {
				//standard blocks, half slabs, & double slabs
				registerRender(GameRegistry.findBlock(Reference.MOD_ID, blockType + "_of_" + color), i, shade);
			}
		}
		i++;
	}
	i = 0;
	for (String color : ModUtilities.baseColorList) {
		//ore blocks
		registerRender(ModBlocks.essence_ore, i, color);
		i++;
	}
}

}

 

 

//utility package//

 

ModUtilities.java

package com.supergeniuszeb.colore.utility;

/*
* A class used for storing various arrays and such that are convenient for things
* like iterating through the list of block colors in a for each loop to reduce the
* size of code when performing various functions.
*/
public class ModUtilities {

/*
 * The list of block types in the mod.
 */
public static String[] blockTypeList = new String[] {
	"block", "slab", "double_slab"
};

/*
 * A simple list of the half slab types.
 * Currently unused.
 */
public static String[] halfSlabTypeList = new String[] {
	"bottom", "top"
};

/*
 * The list of shades for the blocks and items in the mod.
 */
public static String[] shadeList = new String[] {
	"normal", "light", "lighter", "dark", "darker"
};

/*
 * The list of colors for the blocks and items in the mod.
 */
public static String[] colorList = new String[] {
	"red", "reddish_orange", "orange", "orangish_yellow", "yellow",
	"yellowish_green", "green", "cyan", "blue", "indigo", "purple",
	"magenta", "brown", "grayscale"
};

/*
 * The list of base (or ore) colors in the mod.
 */
public static String[] baseColorList = new String[] {
	"red", "yellow", "blue", "brown", "white", "black"
};
}

 

 

 

 

Original Post:

 

I'm trying to add slabs with metadata to my mod, but so far I'm not having too much success. I know how slabs work in game (they're 2 different blocks: a half-slab block with at least 2 blockstates and a double slab block that's basically just a normal block that drops 2 of the former) and that you're supposed to have an abstract slab class (BlockColoreSlab), a half slab class (BlockColoreSlabHalf), a double slab class (BlockColoreSlabDouble), and an item-block class (ItemBlockColoreSlab), but I have no idea how to get them working right. I have the metadata on the slabs set up with 2 properties: "SHADE" and "HALF". "SHADE" has 5 different values: normal, light, lighter, dark, and darker, and "HALF" has, of course, just 2 values and determines whether the block is a top slab of bottom slab (if it is even a half slab.) So for example I'm trying to add a Slab of Red that uses the metadata to determine both the color and which type of slab it is. (Values 0-4 are bottom slabs and 5-9 are top slabs. Double slabs just have values 0-4.) At this point I haven't created any model, texture, or other .json files for any of the slabs, and neither have I put them in the .lang file, as I'm just trying to get them functional right now.

 

Here's what happens when I launch the game:

The game doesn't crash, and the half-slabs can be placed like regular slabs, and have the same hitboxes. However, they can't be stacked into double slabs. Both the regular and the double slabs show up in the creative tab I have created for them, though the double slabs shouldn't be there. Both the half and double variants of the slabs have the same name in the creative menu. (For example, the slab_of_red with a SHADE state of "NORMAL" shows as tile.slab_of_red.normal.name, and its double variant shows with the exact same name, but when viewed in F3+H mode, you can see their actual code names of colore:slab_of_red and colore:slab_of_red_double... I'm not sure if this is normal or not, as I have not tried to create any .json files or textures yet.)

 

Anyway, here are the slab classes and the classes I use to register my blocks. If you need to see any more, just let me know. See the top of the post for the current state of how things are working. (I'll update it as I fix things and make progress...)

 

BlockColoreSlab (abstract slab class):

package com.supergeniuszeb.colore.common.blocks;

import net.minecraft.block.Block;
import net.minecraft.block.BlockSlab;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.properties.PropertyEnum;
import net.minecraft.block.state.BlockState;
import net.minecraft.block.state.IBlockState;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.BlockPos;
import net.minecraft.util.IStringSerializable;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;

import com.supergeniuszeb.colore.common.registry.CreativeTabRegistry;

//An abstract class for both half-slabs and full/double slabs.
public abstract class BlockColoreSlab extends BlockSlab implements IMetaBlockName{

public BlockColoreSlab(String unlocalizedName) {
	super(Material.rock);
	this.setHardness(1.5f);
	this.setHarvestLevel("pickaxe", 0);
	this.setResistance(10.0f);
	this.setUnlocalizedName(unlocalizedName);
	this.useNeighborBrightness = !this.isDouble();
	if (!this.isDouble()) {
            this.setCreativeTab(CreativeTabRegistry.slabTab);
        }

	//Sets default state depending on whether block is a half-slab or double-slab.
	IBlockState blockState = this.blockState.getBaseState();
        blockState = blockState.withProperty(SHADE, EnumShade.NORMAL);
        if (!this.isDouble()) {
            blockState = blockState.withProperty(HALF, EnumBlockHalf.BOTTOM);
        }

        this.setDefaultState(blockState);
}

public enum EnumShade implements IStringSerializable {
	NORMAL(0, "normal"),
	LIGHT(1, "light"),
	LIGHTER(2, "lighter"),
	DARK(3, "dark"),
	DARKER(4, "darker");

	private int ID;
	private String name;

	private EnumShade(int ID, String name) {
		this.ID = ID;
		this.name = name;
	}

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

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

	public int getID() {
        return ID;
    }

}

//The shade ("light", "dark", etc.) of the slab. The "HALF" property is defined in the vanilla BlockSlab class so I don't need to make my own.
public static final PropertyEnum SHADE = PropertyEnum.create("shade", BlockColoreSlab.EnumShade.class);

//Function to get the variant property created above based on the item.
@Override
public final Object getVariant(final ItemStack itemstack) {
	return itemstack.getMetadata();
}

//Function to get the variant property.
@Override
public final IProperty getVariantProperty() {
	return SHADE;
}

@SideOnly(Side.CLIENT)
    @Override
    public final net.minecraft.item.Item getItem(
        final net.minecraft.world.World world,
        final net.minecraft.util.BlockPos blockPos) {
        String blockId = this.getUnlocalizedName();
        return Item.getItemFromBlock(Block.getBlockFromName(blockId));
    }

@Override
protected BlockState createBlockState() {
	return new BlockState(this, new IProperty[] {SHADE, HALF});
}

//Converts an IBlockState into metadata.
@Override
public IBlockState getStateFromMeta(int meta) {

	//A blockState is created, which is assigned the SHADE property depending on its metadata, as well as the HALF property, if it is a half-slab.
	IBlockState blockState = this.getDefaultState();

	if (!this.isDouble()) { //If the block is a BlockColoreHalfSlab
		switch (meta) {
			case 0:
				blockState = blockState.withProperty(SHADE, EnumShade.NORMAL).withProperty(HALF, EnumBlockHalf.BOTTOM);
				break; //Note-to-self: NEVER EVER FORGET TO USE THIS IF RETURN STATEMENTS AREN'T INVOLVED!
			case 1:
				blockState = blockState.withProperty(SHADE, EnumShade.LIGHT).withProperty(HALF, EnumBlockHalf.BOTTOM);
				break;
			case 2:
				blockState = blockState.withProperty(SHADE, EnumShade.LIGHTER).withProperty(HALF, EnumBlockHalf.BOTTOM);
				break;
			case 3:
				blockState = blockState.withProperty(SHADE, EnumShade.DARK).withProperty(HALF, EnumBlockHalf.BOTTOM);
				break;
			case 4:
				blockState = blockState.withProperty(SHADE, EnumShade.DARKER).withProperty(HALF, EnumBlockHalf.BOTTOM);
				break;
			case 5:
				blockState = blockState.withProperty(SHADE, EnumShade.NORMAL).withProperty(HALF, EnumBlockHalf.TOP);
				break;
			case 6:
				blockState = blockState.withProperty(SHADE, EnumShade.LIGHT).withProperty(HALF, EnumBlockHalf.TOP);
				break;
			case 7:
				blockState = blockState.withProperty(SHADE, EnumShade.LIGHTER).withProperty(HALF, EnumBlockHalf.TOP);
				break;
			case 8:
				blockState = blockState.withProperty(SHADE, EnumShade.DARK).withProperty(HALF, EnumBlockHalf.TOP);
				break;
			case 9:
				blockState = blockState.withProperty(SHADE, EnumShade.DARKER).withProperty(HALF, EnumBlockHalf.TOP);
				break;
			default:
				blockState = blockState.withProperty(SHADE, EnumShade.NORMAL).withProperty(HALF, EnumBlockHalf.BOTTOM);
				break;
		}
	} else { //If the block is a BlockColoreDoubleSlab
		switch (meta) {
			case 0:
				blockState = blockState.withProperty(SHADE, EnumShade.NORMAL);
				break;
			case 1:
				blockState = blockState.withProperty(SHADE, EnumShade.LIGHT);
				break;
			case 2:
				blockState = blockState.withProperty(SHADE, EnumShade.LIGHTER);
				break;
			case 3:
				blockState = blockState.withProperty(SHADE, EnumShade.DARK);
				break;
			case 4:
				blockState = blockState.withProperty(SHADE, EnumShade.DARKER);
				break;
			default:
				blockState = blockState.withProperty(SHADE, EnumShade.NORMAL);
				break;
		}
	}

	return blockState;
}

//Converts metadata into an IBlockState.
@Override
public int getMetaFromState(IBlockState state) {

    EnumShade shade = (EnumShade) state.getValue(SHADE);
    
    if (!this.isDouble()) {
    	EnumBlockHalf half = (EnumBlockHalf) state.getValue(HALF);
    	
    	//0-4 are bottom slabs, and 5-9 are the top slabs, so if the HALF property = top,
    	//then 5 is added to the ID integer assigned to the SHADE property. This is done
    	//to match up with how I've assigned the 9 different metadata values. (I hope
    	//this comment made sense so I don't come back later trying to find out why I did
    	//this and get disappointed with my former self's explanatory skills...)
    	if (half == EnumBlockHalf.TOP) {
    		return shade.getID() + 5; 
    	}
    }
    
    return shade.getID();
}

//This insures that  the meta block drops an item-block with the correct metadata when mined. This is
//somewhat trickier than with a regular block since you don't want to drop a "top" or "bottom" half slab.
//You only want to drop... well, just a slab! (Or more technically, a default, or bottom, half slab.
//Of course, if you're breaking a double-slab, it shouldn't drop a block with the HALF property at all.
@Override
public int damageDropped(IBlockState state) {
	if (!this.isDouble()) {
		//Using my neat math tricks in conjuction with how I've set up the 9 metadata values so that
		//0-4 are bottom slabs and 5-9 are top slabs.
		if (getMetaFromState(state) > 5) { //If the block is a top slab, then drop a bottom slab.
			return getMetaFromState(state) - 5;
		}
	}
	//If the block is a bottom slab or double slab, then drop a block with a metadata between 0-4.
	//The value of the SHADE property is assigned to the same 5 integers for both bottom half slabs
	//and double slabs, so this works. Hooray for clever metadata-blockstate-math-stuff!
    return getMetaFromState(state);
}

//Used to get the last part of the unlocalized name for the item-block.
//The structure of the unlocalized name is: tile.blockname.specialname.name
@Override
public String getSpecialName(ItemStack stack) {
	switch (stack.getItemDamage()) {
		case 0:
			return "normal";
		case 1:
			return "light";
		case 2:
			return "lighter";
		case 3:
			return "dark";
		case 4:
			return "darker";
		default:
			return "normal";
	}
}

@Override
    public final String getUnlocalizedName(final int metadata) {
        return this.getUnlocalizedName();
    }

//This ensures that the pick-block button (normally middle-click) will give
//an item-block with the correct metadata.
@Override
public ItemStack getPickBlock(MovingObjectPosition target, World world, BlockPos pos) {
    return new ItemStack(Item.getItemFromBlock(this), 1, this.getMetaFromState(world.getBlockState(pos)));
}

//WIP BEYOND THIS POINT

}

 

BlockColoreSlabHalf:

package com.supergeniuszeb.colore.common.blocks;

import net.minecraft.block.properties.IProperty;
import net.minecraft.item.ItemStack;

public class BlockColoreSlabHalf extends BlockColoreSlab {

public BlockColoreSlabHalf(String unlocalizedName) {
	super(unlocalizedName);
}

@Override
public boolean isDouble() {
	return false;
}

}

 

BlockColoreSlabDouble:

package com.supergeniuszeb.colore.common.blocks;

public class BlockColoreSlabDouble extends BlockColoreSlab {

public BlockColoreSlabDouble(String unlocalizedName) {
	super(unlocalizedName);
}

@Override
public boolean isDouble() {
	return true;
}
}

 

ItemBlockColoreSlab:

package com.supergeniuszeb.colore.common.blocks;

import java.util.ArrayList;
import java.util.List;

import com.supergeniuszeb.colore.common.registry.BlockRegistry;

import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraft.item.ItemSlab;
import net.minecraft.item.ItemStack;

/*
* Wrapper class to make sure that GameRegistry.registerBlock() calls the right constructor.
*/
public class ItemBlockColoreSlab extends ItemSlab {

public ItemBlockColoreSlab(final Block block, final BlockColoreSlabHalf slab, final BlockColoreSlabDouble doubleSlab, final Boolean stacked) {
	super(block, slab, doubleSlab);
	this.setHasSubtypes(true);
        this.getSubBlocks(slabList, this, 5);
}

public int getMetadata(int damage)
    {
        return damage;
    }

@Override
    public String getUnlocalizedName(ItemStack stack) {
        return super.getUnlocalizedName(stack) + "." + ((IMetaBlockName)this.block).getSpecialName(stack);
    }

public static List slabList = new ArrayList<Item>(5) {};

	//This will add all the different metadata variations of the slabs
	//as "ItemStack"s to the slabList list. Used when adding metadata
	//blocks to the creative tabs.
	public void getSubBlocks(List slabList, Item item, int range) {
		for (int i = 0; i < range; ++i) {
            slabList.add(new ItemStack(item, 1, i));
        }
	}

}

 

(I've commented out the other slabs, since all I really need is to get the red slab working, and then I can just do copying-and-pasting for all the others.)

BlockRegistry (used to register instances of blocks):

package com.supergeniuszeb.colore.common.registry;

import net.minecraftforge.fml.common.registry.GameRegistry;

import com.supergeniuszeb.colore.common.blocks.BlockColore;
import com.supergeniuszeb.colore.common.blocks.BlockColoreOre;
import com.supergeniuszeb.colore.common.blocks.BlockColoreSlab;
import com.supergeniuszeb.colore.common.blocks.BlockColoreSlabDouble;
import com.supergeniuszeb.colore.common.blocks.BlockColoreSlabHalf;
import com.supergeniuszeb.colore.common.blocks.ItemBlockColore;
import com.supergeniuszeb.colore.common.blocks.ItemBlockColoreSlab;

public class BlockRegistry {

//regular blocks
public static BlockColore block_of_red;
public static BlockColore block_of_reddish_orange;
public static BlockColore block_of_orange;
public static BlockColore block_of_orangish_yellow;
public static BlockColore block_of_yellow;
public static BlockColore block_of_yellowish_green;
public static BlockColore block_of_green;
public static BlockColore block_of_cyan;
public static BlockColore block_of_blue;
public static BlockColore block_of_indigo;
public static BlockColore block_of_purple;
public static BlockColore block_of_magenta;
public static BlockColore block_of_brown;
public static BlockColore block_of_grayscale;

//half slabs
public static BlockColoreSlab slab_of_red = new BlockColoreSlabHalf("slab_of_red");
/*	public static BlockColoreSlabHalf slab_of_reddish_orange;
public static BlockColoreSlabHalf slab_of_orange;
public static BlockColoreSlabHalf slab_of_orangish_yellow;
public static BlockColoreSlabHalf slab_of_yellow;
public static BlockColoreSlabHalf slab_of_yellowish_green;
public static BlockColoreSlabHalf slab_of_green;
public static BlockColoreSlabHalf slab_of_cyan;
public static BlockColoreSlabHalf slab_of_blue;
public static BlockColoreSlabHalf slab_of_indigo;
public static BlockColoreSlabHalf slab_of_purple;
public static BlockColoreSlabHalf slab_of_magenta;
public static BlockColoreSlabHalf slab_of_brown;
public static BlockColoreSlabHalf slab_of_grayscale;
*/
//double slabs
public static BlockColoreSlab slab_of_red_double = new BlockColoreSlabDouble("slab_of_red_double");
/*public static BlockColoreSlabDouble slab_of_reddish_orange_double;
public static BlockColoreSlabDouble slab_of_orange_double;
public static BlockColoreSlabDouble slab_of_orangish_yellow_double;
public static BlockColoreSlabDouble slab_of_yellow_double;
public static BlockColoreSlabDouble slab_of_yellowish_green_double;
public static BlockColoreSlabDouble slab_of_green_double;
public static BlockColoreSlabDouble slab_of_cyan_double;
public static BlockColoreSlabDouble slab_of_blue_double;
public static BlockColoreSlabDouble slab_of_indigo_double;
public static BlockColoreSlabDouble slab_of_purple_double;
public static BlockColoreSlabDouble slab_of_magenta_double;
public static BlockColoreSlabDouble slab_of_brown_double;
public static BlockColoreSlabDouble slab_of_grayscale_double;*/

//ore blocks	
public static BlockColoreOre essence_ore;

public static void registerBlocks() {
	//regular blocks
	GameRegistry.registerBlock(block_of_red = new BlockColore("block_of_red"), ItemBlockColore.class, "block_of_red");
	GameRegistry.registerBlock(block_of_reddish_orange = new BlockColore("block_of_reddish_orange"), ItemBlockColore.class, "block_of_reddish_orange");
	GameRegistry.registerBlock(block_of_orange = new BlockColore("block_of_orange"), ItemBlockColore.class, "block_of_orange");
	GameRegistry.registerBlock(block_of_orangish_yellow = new BlockColore("block_of_orangish_yellow"), ItemBlockColore.class, "block_of_orangish_yellow");
	GameRegistry.registerBlock(block_of_yellow = new BlockColore("block_of_yellow"), ItemBlockColore.class, "block_of_yellow");
	GameRegistry.registerBlock(block_of_yellowish_green = new BlockColore("block_of_yellowish_green"), ItemBlockColore.class, "block_of_yellowish_green");
	GameRegistry.registerBlock(block_of_green = new BlockColore("block_of_green"), ItemBlockColore.class, "block_of_green");
	GameRegistry.registerBlock(block_of_cyan = new BlockColore("block_of_cyan"), ItemBlockColore.class, "block_of_cyan");
	GameRegistry.registerBlock(block_of_blue = new BlockColore("block_of_blue"), ItemBlockColore.class, "block_of_blue");
	GameRegistry.registerBlock(block_of_indigo = new BlockColore("block_of_indigo"), ItemBlockColore.class, "block_of_indigo");
	GameRegistry.registerBlock(block_of_purple = new BlockColore("block_of_purple"), ItemBlockColore.class, "block_of_purple");
	GameRegistry.registerBlock(block_of_magenta = new BlockColore("block_of_magenta"), ItemBlockColore.class, "block_of_magenta");
	GameRegistry.registerBlock(block_of_brown = new BlockColore("block_of_brown"), ItemBlockColore.class, "block_of_brown");
	GameRegistry.registerBlock(block_of_grayscale = new BlockColore("block_of_grayscale"), ItemBlockColore.class, "block_of_grayscale");

	//half slabs
	GameRegistry.registerBlock(slab_of_red, ItemBlockColoreSlab.class, "slab_of_red", slab_of_red, slab_of_red_double, false);
	/*GameRegistry.registerBlock(slab_of_reddish_orange = new BlockColoreSlabHalf("slab_of_reddish_orange"), ItemBlockColoreSlab.class, "slab_of_reddish_orange");
	GameRegistry.registerBlock(slab_of_orange = new BlockColoreSlabHalf("slab_of_orange"), ItemBlockColoreSlab.class, "slab_of_orange");
	GameRegistry.registerBlock(slab_of_orangish_yellow = new BlockColoreSlabHalf("slab_of_orangish_yellow"), ItemBlockColoreSlab.class, "slab_of_orangish_yellow");
	GameRegistry.registerBlock(slab_of_yellow = new BlockColoreSlabHalf("slab_of_yellow"), ItemBlockColoreSlab.class, "slab_of_yellow");
	GameRegistry.registerBlock(slab_of_yellowish_green = new BlockColoreSlabHalf("slab_of_yellowish_green"), ItemBlockColoreSlab.class, "slab_of_yellowish_green");
	GameRegistry.registerBlock(slab_of_green = new BlockColoreSlabHalf("slab_of_green"), ItemBlockColoreSlab.class, "slab_of_green");
	GameRegistry.registerBlock(slab_of_cyan = new BlockColoreSlabHalf("slab_of_cyan"), ItemBlockColoreSlab.class, "slab_of_cyan");
	GameRegistry.registerBlock(slab_of_blue = new BlockColoreSlabHalf("slab_of_blue"), ItemBlockColoreSlab.class, "slab_of_blue");
	GameRegistry.registerBlock(slab_of_indigo = new BlockColoreSlabHalf("slab_of_indigo"), ItemBlockColoreSlab.class, "slab_of_indigo");
	GameRegistry.registerBlock(slab_of_purple = new BlockColoreSlabHalf("slab_of_purple"), ItemBlockColoreSlab.class, "slab_of_purple");
	GameRegistry.registerBlock(slab_of_magenta = new BlockColoreSlabHalf("slab_of_magenta"), ItemBlockColoreSlab.class, "slab_of_magenta");
	GameRegistry.registerBlock(slab_of_brown = new BlockColoreSlabHalf("slab_of_brown"), ItemBlockColoreSlab.class, "slab_of_brown");
	GameRegistry.registerBlock(slab_of_grayscale = new BlockColoreSlabHalf("slab_of_grayscale"), ItemBlockColoreSlab.class, "slab_of_grayscale");
	*/
	//double slabs
	GameRegistry.registerBlock(slab_of_red_double, ItemBlockColoreSlab.class, "slab_of_red_double", slab_of_red, slab_of_red_double, true);
	/*GameRegistry.registerBlock(slab_of_reddish_orange_double = new BlockColoreSlabDouble("slab_of_reddish_orange_double"), ItemBlockColoreSlab.class, "slab_of_reddish_orange_double");
	GameRegistry.registerBlock(slab_of_orange_double = new BlockColoreSlabDouble("slab_of_orange_double"), ItemBlockColoreSlab.class, "slab_of_orange_double");
	GameRegistry.registerBlock(slab_of_orangish_yellow_double = new BlockColoreSlabDouble("slab_of_orangish_yellow_double"), ItemBlockColoreSlab.class, "slab_of_orangish_yellow_double");
	GameRegistry.registerBlock(slab_of_yellow_double = new BlockColoreSlabDouble("slab_of_yellow_double"), ItemBlockColoreSlab.class, "slab_of_yellow_double");
	GameRegistry.registerBlock(slab_of_yellowish_green_double = new BlockColoreSlabDouble("slab_of_yellowish_green_double"), ItemBlockColoreSlab.class, "slab_of_yellowish_green_double");
	GameRegistry.registerBlock(slab_of_green_double = new BlockColoreSlabDouble("slab_of_green_double"), ItemBlockColoreSlab.class, "slab_of_green_double");
	GameRegistry.registerBlock(slab_of_cyan_double = new BlockColoreSlabDouble("slab_of_cyan_double"), ItemBlockColoreSlab.class, "slab_of_cyan_double");
	GameRegistry.registerBlock(slab_of_blue_double = new BlockColoreSlabDouble("slab_of_blue_double"), ItemBlockColoreSlab.class, "slab_of_blue_double");
	GameRegistry.registerBlock(slab_of_indigo_double = new BlockColoreSlabDouble("slab_of_indigo_double"), ItemBlockColoreSlab.class, "slab_of_indigo_double");
	GameRegistry.registerBlock(slab_of_purple_double = new BlockColoreSlabDouble("slab_of_purple_double"), ItemBlockColoreSlab.class, "slab_of_purple_double");
	GameRegistry.registerBlock(slab_of_magenta_double = new BlockColoreSlabDouble("slab_of_magenta_double"), ItemBlockColoreSlab.class, "slab_of_magenta_double");
	GameRegistry.registerBlock(slab_of_brown_double = new BlockColoreSlabDouble("slab_of_brown_double"), ItemBlockColoreSlab.class, "slab_of_brown_double");
	GameRegistry.registerBlock(slab_of_grayscale_double = new BlockColoreSlabDouble("slab_of_grayscale_double"), ItemBlockColoreSlab.class, "slab_of_grayscale_double");
*/
	GameRegistry.registerBlock(essence_ore = new BlockColoreOre("essence_ore"), ItemBlockColore.class, "essence_ore");
}
}

 

BlockRenderRegistry (used to register block models and item-block models... I am aware I haven't registered the slab models or anything yet, but nothing in this class affects the functionality of the blocks, so I'm not going to add anything here until the slabs work as intended and all that's left is the rendering side of things.):

	package com.supergeniuszeb.colore.client.render;

import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.model.ModelBakery;
import net.minecraft.client.resources.model.ModelResourceLocation;
import net.minecraft.item.Item;
import net.minecraft.util.ResourceLocation;

import com.supergeniuszeb.colore.Reference;
import com.supergeniuszeb.colore.common.registry.BlockRegistry;
import com.supergeniuszeb.colore.utility.ModUtilities;

//All this handles are the item-block models, not the actual block models, which are
//defined in the .json files.
public class BlockRenderRegistry {

//This method is called by the registerRenders method every time it adds an item-block model.
public static void registerRender(Block block) {
	Item item = Item.getItemFromBlock(block);
	Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(Item.getItemFromBlock(block), 0, new ModelResourceLocation(Reference.MOD_ID + ":" + item.getUnlocalizedName().substring(5), "inventory"));
}

//This method is called by the init method every time it adds a meta item-block model.
public static void registerRender(Block block, int meta, String fileName) {
	Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(Item.getItemFromBlock(block), meta, new ModelResourceLocation(Reference.MOD_ID + ":" + fileName, "inventory"));
}

public static void preInit() {

	for (String shade : ModUtilities.shadeList) {
		ModelBakery.registerItemVariants(Item.getItemFromBlock(BlockRegistry.block_of_red), new ResourceLocation(Reference.MOD_ID, "block_of_red_" + shade));
		ModelBakery.registerItemVariants(Item.getItemFromBlock(BlockRegistry.block_of_reddish_orange), new ResourceLocation(Reference.MOD_ID, "block_of_reddish_orange_" + shade));
		ModelBakery.registerItemVariants(Item.getItemFromBlock(BlockRegistry.block_of_orange), new ResourceLocation(Reference.MOD_ID, "block_of_orange_" + shade));
		ModelBakery.registerItemVariants(Item.getItemFromBlock(BlockRegistry.block_of_orangish_yellow), new ResourceLocation(Reference.MOD_ID, "block_of_orangish_yellow_" + shade));
		ModelBakery.registerItemVariants(Item.getItemFromBlock(BlockRegistry.block_of_yellow), new ResourceLocation(Reference.MOD_ID, "block_of_yellow_" + shade));
		ModelBakery.registerItemVariants(Item.getItemFromBlock(BlockRegistry.block_of_yellowish_green), new ResourceLocation(Reference.MOD_ID, "block_of_yellowish_green_" + shade));
		ModelBakery.registerItemVariants(Item.getItemFromBlock(BlockRegistry.block_of_green), new ResourceLocation(Reference.MOD_ID, "block_of_green_" + shade));
		ModelBakery.registerItemVariants(Item.getItemFromBlock(BlockRegistry.block_of_cyan), new ResourceLocation(Reference.MOD_ID, "block_of_cyan_" + shade));
		ModelBakery.registerItemVariants(Item.getItemFromBlock(BlockRegistry.block_of_blue), new ResourceLocation(Reference.MOD_ID, "block_of_blue_" + shade));
		ModelBakery.registerItemVariants(Item.getItemFromBlock(BlockRegistry.block_of_indigo), new ResourceLocation(Reference.MOD_ID, "block_of_indigo_" + shade));
		ModelBakery.registerItemVariants(Item.getItemFromBlock(BlockRegistry.block_of_purple), new ResourceLocation(Reference.MOD_ID, "block_of_purple_" + shade));
		ModelBakery.registerItemVariants(Item.getItemFromBlock(BlockRegistry.block_of_magenta), new ResourceLocation(Reference.MOD_ID, "block_of_magenta_" + shade));
		ModelBakery.registerItemVariants(Item.getItemFromBlock(BlockRegistry.block_of_brown), new ResourceLocation(Reference.MOD_ID, "block_of_brown_" + shade));
		ModelBakery.registerItemVariants(Item.getItemFromBlock(BlockRegistry.block_of_grayscale), new ResourceLocation(Reference.MOD_ID, "block_of_grayscale_" + shade));
	}

	for (String color : ModUtilities.baseColorList) {
		ModelBakery.registerItemVariants(Item.getItemFromBlock(BlockRegistry.essence_ore), new ResourceLocation(Reference.MOD_ID, "essence_ore_" + color));
	}
}

public static void init() {

	int i = 0;
	for (String shade : ModUtilities.shadeList) {
		registerRender(BlockRegistry.block_of_red, i, "block_of_red_" + shade);
		registerRender(BlockRegistry.block_of_reddish_orange, i, "block_of_reddish_orange_" + shade);
		registerRender(BlockRegistry.block_of_orange, i, "block_of_orange_" + shade);
		registerRender(BlockRegistry.block_of_orangish_yellow, i, "block_of_orangish_yellow_" + shade);
		registerRender(BlockRegistry.block_of_yellow, i, "block_of_yellow_" + shade);
		registerRender(BlockRegistry.block_of_yellowish_green, i, "block_of_yellowish_green_" + shade);
		registerRender(BlockRegistry.block_of_green, i, "block_of_green_" + shade);
		registerRender(BlockRegistry.block_of_cyan, i, "block_of_cyan_" + shade);
		registerRender(BlockRegistry.block_of_blue, i, "block_of_blue_" + shade);
		registerRender(BlockRegistry.block_of_indigo, i, "block_of_indigo_" + shade);
		registerRender(BlockRegistry.block_of_purple, i, "block_of_purple_" + shade);
		registerRender(BlockRegistry.block_of_magenta, i, "block_of_magenta_" + shade);
		registerRender(BlockRegistry.block_of_brown, i, "block_of_brown_" + shade);
		registerRender(BlockRegistry.block_of_grayscale, i, "block_of_grayscale_" + shade);
		i++;
	}

	i = 0;
	for (String color : ModUtilities.baseColorList) {
		registerRender(BlockRegistry.essence_ore, i, "essence_ore_" + color);
		i++;
	}
}

}

 

If you need to see any other classes, just let me know and I'll update this post.

 

Colore - The mod that adds monochrome blocks in every color of the rainbow!

http://www.minecraftforge.net/forum/index.php?topic=35149

 

If you're looking to learn how to make mods for 1.9.4, I wrote a helpful article with links to a lot of useful resources for learning Minecraft 1.9.4 modding!

 

http://supergeniuszeb.com/mods/a-helpful-list-of-minecraft-1-9-4-modding-resources/

Posted

Are you sure that you need BlockSlabHalf and BlockSlabDouble? I'm not seeing such an arrangement in Vanilla slabs. It sounds like your mechanism for changing one into the other is incomplete.

The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.

  • 1 month later...
Posted

...And, 2 months later, after a lot of time being busy and being unable to work on my mod, I have recently been able to get my slabs working! Yay! ;D

 

Are you sure that you need BlockSlabHalf and BlockSlabDouble? I'm not seeing such an arrangement in Vanilla slabs. It sounds like your mechanism for changing one into the other is incomplete.

Vanilla does have similar classes... see BlockHalfStoneSlab and BlockDoubleStoneSlab.

Hi

 

Look in ItemSlab.onItemUse() to see how vanilla turns two half-slabs into a whole slab

 

-TGG

 

Thanks for the suggestion! After looking around in the ItemSlab class I was able to figure out how to get the half-slabs and double-slabs to be associated with each other, and I also learned quite a bit about how the slabs and a lot of other Minecraft code works in the process. (Discovered ItemSlab's this.singleSlab, which I had to indirectly access the values by creating a private variable in my ItemBlockColoreSlab class which I assigned the value of this.singleSlab, and then created setter & getter methods so I could easily-ish convert between a double slab as input in a method to its single slab counterpart.) I also cleaned up and simplified a lot of my code (thanks for adding the getRegistryName() & findBlock() methods, Forge team) and have a much better (but still not yet perfect) understanding of the Minecraft/Forge code.

 

For those who are having the same problem as me, I will update the main post with my new code, which I think would work as a better template for slabs with additional metadata/blockstates than the current 1.8 slabs tutorial on these forums. Note that I have renamed BlockRegistry.java & BlockRenderRegistry.java to ModBlocks.java & BlockRenders respectively, since those are more in line with the standard naming conventions and I think they make more sense than what I had before.

 

I would like to note that I am not fully satisfied with how I handle getting the name of a double slab's single/half slab counterpart. (See my comments in the updated code.) It feels a little indirect & hacky to me, and if anyone has any suggestions for a better way, please let me know. I really want my code to be clean and not use hacky, indirect ways of getting things to work.

Colore - The mod that adds monochrome blocks in every color of the rainbow!

http://www.minecraftforge.net/forum/index.php?topic=35149

 

If you're looking to learn how to make mods for 1.9.4, I wrote a helpful article with links to a lot of useful resources for learning Minecraft 1.9.4 modding!

 

http://supergeniuszeb.com/mods/a-helpful-list-of-minecraft-1-9-4-modding-resources/

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.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Ready to unlock unbeatable savings on Temu? Our exclusive Temu code [ald244107] is your ultimate secret weapon for a $100 OFF discount, plus so much more this year! Whether you're making your first purchase or returning for another shopping spree, this verified promo code gives you an instant boost, with up to 50% off your next order and even deeper discounts on clearance items. With Temu coupon code [ald244107], you're not just getting a flat $100 discount; you're stacking it on top of already fantastic sales! New users can grab an extra 100% off selected products, while loyal customers automatically qualify for that sweet $100 OFF when they apply the code at checkout. Imagine slashing prices by up to 90% on everything from trending electronics and stylish fashion to essential home goods and top-rated beauty products, all available across the USA, Canada, UK, and countless other countries! 🔥 Top Temu Code [ald244107] Benefits:  * For New Users: Use ald244107 for 50% off your first order + an additional $100 OFF.  * For Existing Customers: Apply ald244107 to get an instant $100 OFF on your next purchase.  * Global Reach: Valid across the USA, UK, Canada, Germany, France, Japan, Chile, Colombia, Malaysia, Mexico, South Korea, Philippines, Saudi Arabia, Qatar, Pakistan, and many more.  * Best of 2025: Secure up to $200 OFF plus incredible bonus discounts with ald244107. Maximize Your Savings: Featured Temu Deals for 2025 (Code: ald244107)  * ✅ Temu Flash Sales: Don't miss out! Score $100 off during limited-time offers with ald244107.  * ✅ Temu First Order Bonanza: Use ald244107 for a powerful 50% + $100 OFF on your initial purchase.  * ✅ Temu US Shopper Advantage: Instantly save $100 on your orders with ald244107.  * ✅ International Temu Discounts: ald244107 works seamlessly to give you savings in Japan, Germany, Chile, and beyond.  * ✅ Temu Community Favorite: Enjoy $100 OFF for both new and old users, a widely praised deal!  * ✅ Temu Coupon Bundles 2025: Combine $100 OFF with up to 50% slash deals for ultimate savings.  * ✅ 100% OFF Free Gift Code: Use ald244107 to claim a free gift – no invitation or referral needed!  * ✅ Temu Welcome Bonus: Get a delightful $100 OFF instantly upon signing up for an account.  * ✅ Free Temu Code for New Accounts: Apply ald244107 for immediate, hassle-free savings.  * ✅ Temu Clearance Blowout 2025: Use ald244107 for jaw-dropping 85–100% discounts on clearance items. This Temu code [ald244107] is more than just a discount; it's your all-access pass to complimentary shipping, exclusive first-order perks, and stackable coupon bundles across an immense selection of electronics, trendy fashion, essential home goods, and premium beauty products. Truly unlock up to 90% OFF plus an additional $100 OFF on eligible orders! 💡 Pro Tip: Always remember to apply ald244107 during checkout on the Temu app or website. Your instant $100 discount activates automatically, even if you're a returning customer! Where Does Temu Code [ald244107] Work? (Global Availability)  * 🇺🇸 Temu USA – ald244107  * 🇯🇵 Temu Japan – ald244107  * 🇲🇽 Temu Mexico – ald244107  * 🇨🇱 Temu Chile – ald244107  * 🇨🇴 Temu Colombia – ald244107  * 🇲🇾 Temu Malaysia – ald244107  * 🇵🇭 Temu Philippines – ald244107  * 🇰🇷 Temu Korea – ald244107  * 🇵🇰 Temu Pakistan – ald244107  * 🇫🇮 Temu Finland – ald244107  * 🇸🇦 Temu Saudi Arabia – ald244107  * 🇶🇦 Temu Qatar – ald244107  * 🇫🇷 Temu France – ald244107  * 🇩🇪 Temu Germany – ald244107 Hear From Happy Shoppers: User Reviews We love hearing about your experiences! Here's what some satisfied customers are saying about using the Temu code [ald244107]:  * Alice W., USA ⭐️⭐️⭐️⭐️⭐️ (5/5) "Great experience! Temu's promo code {ald244107} saved me a lot on my first order. Highly recommend this offer!"  * James T., UK ⭐️⭐️⭐️⭐️ (4/5) "Very happy with the quality and prices on Temu. The $100 credits offer was a nice bonus using {ald244107}. Will shop again."  * Sara M., Canada ⭐️⭐️⭐️ (3/5) "Got some decent deals with the {ald244107} code, though shipping took a bit longer than expected. Overall satisfied with the credits." Trending Verified Temu Deals for 2025 Stay ahead of the curve with the most popular and verified Temu deals for 2025. Our community consistently confirms the effectiveness of Temu code [ald244107] for maximum savings across a wide range of products. Don't miss out on these trending opportunities to save big! FAQs: Everything You Need to Know About Temu Code [ald244107] Q: What is Temu code [ald244107] and what does it offer? A: Temu code [ald244107] is a verified promo code that provides users with a $100 discount, plus additional savings of up to 50% or even 90% on various items. It's valid for both new and existing customers on the Temu platform. Q: How do I apply Temu code [ald244107]? A: Simply enter [ald244107] in the coupon or promo code field during checkout on the Temu app or website to apply your discounts automatically. Q: Does Temu code [ald244107] benefit new users specifically? A: Yes, ald244107 offers fantastic benefits for new users, including an exclusive 50% off their very first order in addition to the $100 discount. Q: Is Temu code [ald244107] also valid for existing customers? A: Absolutely! Loyal Temu customers can also enjoy a flat $100 OFF discount by seamlessly applying ald244107 at checkout. Q: In which countries can I use Temu code [ald244107]? A: This code boasts widespread global availability, working in numerous countries including the USA, UK, Canada, Germany, France, Japan, Saudi Arabia, Qatar, and many more listed above. Q: Can Temu code [ald244107] be combined with other offers? A: Temu code [ald244107] is strategically designed to provide savings on top of existing deals, making it often stackable with other promotions for truly maximizing your discounts. Unlock Huge Savings with Temu Code [ald244107] – Your Best Bet for 2025! Don't let these incredible savings slip away! Whether you're exploring Temu for the first time or returning for more great finds, the Temu code [ald244107] is your ultimate tool for significant discounts, exciting free gifts, and unbeatable deals. Apply it today and see how much you can save! Happy shopping! [ald244107]  
    • I've tried the java version you linked to and got a new exit code of 127 Here is the new console log I also tried making sure that I had Java 8 selected with the version of Java 8 I already had installed and got the same exit code Here is the console log with that installation in case it has any differences I do notice both say 'Java checker returned some invalid data we don't understand:' followed by 'Minecraft might not start properly.' which could be some issues.  
    • Thank you so much! I didnt see it in the log😭😭  
    • So im completely new to modding in general, i have some experience in Behavior packs in minecraft bedrock and i would like to modify entities stats and attributes like in a behavior pack (health, damage, speed, xp drop...). The problem is that i cant find any information online on how to do that, and I have no clue on what to do and where to start. I am currently modding in 1.20.4 with IntelliJ if that helps. My final objective is to buff mobs health and damage (double it for exemple), but since there is no entity file anywhere i don't know how to change it... 😢
    • Hey there, nothing to do with the code, I am just suggesting you use Intelij IDEA. Trust me, it is the best.
  • Topics

  • Who's Online (See full list)

×
×
  • Create New...

Important Information

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