I can't seem to find any help on this matter at hand. I can't get custom slabs to be able to be stacked into one block as well as work with meta data, such as the vanilla slabs. When I try the meta data, the first 8 slabs are only able to be placed at the bottom part of a block, where as the other 8 are only able to be placed at the top. When I place one of the slabs that only works on the bottom, to the top, the texture changes to a different slab. There seems to be little to absolutely no tutorials on this, or how to get them to work properly.
package com.ProfitOrange.moshiz;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import java.util.List;
import java.util.Random;
import net.minecraft.block.BlockSlab;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.IIcon;
public class ColoredSlab extends BlockSlab
{
public static final String[] blockList = new String[] {"black", "red", "green", "brown", "blue", "purple", "cyan", "lightgrey", "grey", "pink", "limegreen", "yellow", "lightblue", "magenta", "orange", "white"};
private static final String __OBFID = "CL_00000337";
public ColoredSlab(boolean isFullBlock, Material material)
{
super(isFullBlock, Material.wood);
this.setCreativeTab(MoShizMain.tabDecor);
}
/**
* Gets the block's texture. Args: side, meta
*/
@SideOnly(Side.CLIENT)
public IIcon getIcon(int side, int meta)
{
return MoShizMain.coloredplank.getIcon(side, meta);
}
public Item getItemDropped(int par1, Random random2, int par3)
{
return Item.getItemFromBlock(MoShizMain.coloredhalfslab);
}
/**
* Returns an item stack containing a single instance of the current block type. 'i' is the block's subtype/damage
* and is ignored for blocks which do not support subtypes. Blocks which cannot be harvested should return null.
*/
public ItemStack createStackedBlock(int par1)
{
return new ItemStack(Item.getItemFromBlock(MoShizMain.coloredhalfslab), 2, par1);
}
public String func_150002_b(int par1)
{
if (par1 < 0 || par1 >= blockList.length)
{
par1 = 0;
}
return super.getUnlocalizedName() + "." + blockList[par1];
}
/**
* returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks)
*/
@SideOnly(Side.CLIENT)
public void getSubBlocks(Item item, CreativeTabs tab, List list)
{
if (item != Item.getItemFromBlock(MoShizMain.coloredDoubleSlab))
{
for (int i = 0; i < blockList.length; ++i)
{
list.add(new ItemStack(item, 1, i));
}
}
}
@SideOnly(Side.CLIENT)
public void registerBlockIcons(IIconRegister p_149651_1_) {}
}
The way to register the blocks has changed since 1.6.4. The way I have them registered now is: GameRegistry.registerBlock(coloredslabs, ItemColoredSlabs.class, "coloredslabs");
Well, I have some experience with slabs because I use them for my mod. First of all, you can't use 16 slabs in the same block because Minecraft manages already the metadata to position the lower and the upper slabs. Anyway you can still use metadata but you're limited to 8 slabs in the same block, because the first 8 (from 0 to 7) will represent the lower position and the second 8 (from 8 to 15) will represent the upper position.
You'll have to create 2 separate blocks to manage an amount of 16 slabs.
This is the code to manage the creation of a slab:
public class MyCustomSlabs extends BlockSlab{
private boolean isDoubleSlab;
private int numSubBlocks;
private Block singleSlab;
private Block textureBlock;
private int textureStartCounter;
/**
* Creates a new custom slab
* @param _isDoubleSlab determines if the slab represents the half block or the full block
* @param material is the material of the slabs
* @param _numSubBlocks is the number of metadata sub blocks (can't be more than 8)
* @param _singleSlab the block representing the half slab and also the block to drop when harvesting a full slab block
* @param _textureBlock the block from which to retrieve the texture
* @param _textureStartCounter the starting index from which to retrieve a texture from a metadata block
*/
public MyCustomSlabs(boolean _isDoubleSlab, Material material, int _numSubBlocks, Block _singleSlab, Block _textureBlock, int _textureStartCounter) {
super(_isDoubleSlab, material);
setHardness(2.0F);
setResistance(5.0F);
setStepSound(Block.soundTypeStone);
useNeighborBrightness = true;
if(_isDoubleSlab)
setCreativeTab(null); //Set the creative tab to null so that the double slab blocks will not appear in the creative tabs
else
setCreativeTab(YOURTAB); //Set your creative tab, for example: setCreativeTab(MyModName.tabBlocks)
isDoubleSlab = _isDoubleSlab;
numSubBlocks = _numSubBlocks;
singleSlab = _singleSlab;
textureBlock = _textureBlock;
textureStartCounter = _textureStartCounter;
}
@Override
@SideOnly(Side.CLIENT)
public void getSubBlocks(Item par1, CreativeTabs tab, List subItems)
{
for (int ix = 0; ix < 0) || (par1 >= numSubBlocks))
{
par1 = 0;
}
return super.getUnlocalizedName() + "." + (par1+1);
}
}
You need also a custom ItemSlab, that should be something like this:
public class MyCustomItemSlab extends ItemBlock
{
private final boolean field_150948_b;
private final BlockSlab singleSlab;
private final BlockSlab doubleSlab;
private static final String __OBFID = "CL_00000071";
public MyCustomItemSlab(Block block)
{
super(block);
this.singleSlab = (BlockSlab) MyModName.mySlabSingle; //Here you have to set your single slab
this.doubleSlab = (BlockSlab) MyModName.mySlabDouble; //And here your double slab
this.field_150948_b = false;
this.setMaxDamage(0);
this.setHasSubtypes(true);
}
/**
* Gets an icon index based on an item's damage value
*/
@SideOnly(Side.CLIENT)
public IIcon getIconFromDamage(int par1)
{
return Block.getBlockFromItem(this).getIcon(2, par1);
}
/**
* Returns the metadata of the block which this Item (ItemBlock) can place
*/
public int getMetadata(int par1)
{
return par1;
}
/**
* Returns the unlocalized name of this item. This version accepts an ItemStack so different stacks can have
* different names based on their damage or NBT.
*/
public String getUnlocalizedName(ItemStack par1ItemStack)
{
return this.singleSlab.func_150002_b(par1ItemStack.getItemDamage());
}
/**
* Callback for item usage. If the item does something special on right clicking, he will have one of those. Return
* True if something happen and false if it don't. This is for ITEMS, not BLOCKS
*/
public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10)
{
if (this.field_150948_B)
{
return super.onItemUse(par1ItemStack, par2EntityPlayer, par3World, par4, par5, par6, par7, par8, par9, par10);
}
else if (par1ItemStack.stackSize == 0)
{
return false;
}
else if (!par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack))
{
return false;
}
else
{
Block block = par3World.getBlock(par4, par5, par6);
int i1 = par3World.getBlockMetadata(par4, par5, par6);
int j1 = i1 & 7;
boolean flag = (i1 & 8) != 0;
if ((par7 == 1 && !flag || par7 == 0 && flag) && block == this.singleSlab && j1 == par1ItemStack.getItemDamage())
{
if (par3World.checkNoEntityCollision(this.doubleSlab.getCollisionBoundingBoxFromPool(par3World, par4, par5, par6)) && par3World.setBlock(par4, par5, par6, this.doubleSlab, j1, 3))
{
par3World.playSoundEffect((double)((float)par4 + 0.5F), (double)((float)par5 + 0.5F), (double)((float)par6 + 0.5F), this.doubleSlab.stepSound.func_150496_b(), (this.doubleSlab.stepSound.getVolume() + 1.0F) / 2.0F, this.doubleSlab.stepSound.getPitch() * 0.8F);
--par1ItemStack.stackSize;
}
return true;
}
else
{
return this.func_150946_a(par1ItemStack, par2EntityPlayer, par3World, par4, par5, par6, par7) ? true : super.onItemUse(par1ItemStack, par2EntityPlayer, par3World, par4, par5, par6, par7, par8, par9, par10);
}
}
}
@SideOnly(Side.CLIENT)
public boolean func_150936_a(World p_150936_1_, int p_150936_2_, int p_150936_3_, int p_150936_4_, int p_150936_5_, EntityPlayer p_150936_6_, ItemStack p_150936_7_)
{
int i1 = p_150936_2_;
int j1 = p_150936_3_;
int k1 = p_150936_4_;
Block block = p_150936_1_.getBlock(p_150936_2_, p_150936_3_, p_150936_4_);
int l1 = p_150936_1_.getBlockMetadata(p_150936_2_, p_150936_3_, p_150936_4_);
int i2 = l1 & 7;
boolean flag = (l1 & 8) != 0;
if ((p_150936_5_ == 1 && !flag || p_150936_5_ == 0 && flag) && block == this.singleSlab && i2 == p_150936_7_.getItemDamage())
{
return true;
}
else
{
if (p_150936_5_ == 0)
{
--p_150936_3_;
}
if (p_150936_5_ == 1)
{
++p_150936_3_;
}
if (p_150936_5_ == 2)
{
--p_150936_4_;
}
if (p_150936_5_ == 3)
{
++p_150936_4_;
}
if (p_150936_5_ == 4)
{
--p_150936_2_;
}
if (p_150936_5_ == 5)
{
++p_150936_2_;
}
Block block1 = p_150936_1_.getBlock(p_150936_2_, p_150936_3_, p_150936_4_);
int j2 = p_150936_1_.getBlockMetadata(p_150936_2_, p_150936_3_, p_150936_4_);
i2 = j2 & 7;
return block1 == this.singleSlab && i2 == p_150936_7_.getItemDamage() ? true : super.func_150936_a(p_150936_1_, i1, j1, k1, p_150936_5_, p_150936_6_, p_150936_7_);
}
}
private boolean func_150946_a(ItemStack p_150946_1_, EntityPlayer p_150946_2_, World p_150946_3_, int p_150946_4_, int p_150946_5_, int p_150946_6_, int p_150946_7_)
{
if (p_150946_7_ == 0)
{
--p_150946_5_;
}
if (p_150946_7_ == 1)
{
++p_150946_5_;
}
if (p_150946_7_ == 2)
{
--p_150946_6_;
}
if (p_150946_7_ == 3)
{
++p_150946_6_;
}
if (p_150946_7_ == 4)
{
--p_150946_4_;
}
if (p_150946_7_ == 5)
{
++p_150946_4_;
}
Block block = p_150946_3_.getBlock(p_150946_4_, p_150946_5_, p_150946_6_);
int i1 = p_150946_3_.getBlockMetadata(p_150946_4_, p_150946_5_, p_150946_6_);
int j1 = i1 & 7;
if (block == this.singleSlab && j1 == p_150946_1_.getItemDamage())
{
if (p_150946_3_.checkNoEntityCollision(this.doubleSlab.getCollisionBoundingBoxFromPool(p_150946_3_, p_150946_4_, p_150946_5_, p_150946_6_)) && p_150946_3_.setBlock(p_150946_4_, p_150946_5_, p_150946_6_, this.doubleSlab, j1, 3))
{
p_150946_3_.playSoundEffect((double)((float)p_150946_4_ + 0.5F), (double)((float)p_150946_5_ + 0.5F), (double)((float)p_150946_6_ + 0.5F), this.doubleSlab.stepSound.func_150496_b(), (this.doubleSlab.stepSound.getVolume() + 1.0F) / 2.0F, this.doubleSlab.stepSound.getPitch() * 0.8F);
--p_150946_1_.stackSize;
}
return true;
}
else
{
return false;
}
}
}
Finally you have to register your blocks in the main class of your mod, within the PreInit method. For example if you want to create some wool slabs you would do something like this:
Note: in this way you'll obtain only the first 8 color of wool in your slabs. If you want to implement also the other remaining 8 colors, you will have to create another couple of single and double slabs blocks and they will need another ItemSlab class in which they are referenced. You will also have to set the last parameter of MyCustomSlabs to 8, so that your slabs will retrieve the textures from the wool starting at metadata = 8.
I hope this could help you and good luck with the creation of your mod!
Would you mind taking a look at my code I used your code above and changed it to my code but when I try to stack a slab on another slab it crashes out.
I think my problem might lay in the custom ItemSlab.class where you said to use modName.SlabName I could get that to work so i changed it to modclass.slabName. and i also tried where it says (BlockSlab) to (ObsidianSlab)
Thank you so much for this. Very informative. I'm happy that you have also commented the code. I like to actually know whats going on VS "Well, it just works". Thanks!
Would you mind taking a look at my code I used your code above and changed it to my code but when I try to stack a slab on another slab it crashes out.
Crash Report: http://pastebin.com/Xw6WRWBs
ModBloscksSlabs: http://pastebin.com/HFP9ELzv
ObsidianItemSlab: http://pastebin.com/ayMpvG5f
ObsidianSlab: http://pastebin.com/RQfE4LDL
Thank you so much for this. Very informative. I'm happy that you have also commented the code. I like to actually know whats going on VS "Well, it just works". Thanks!
Twitter
Blog
YouTube