230 lines
7.8 KiB
Java
230 lines
7.8 KiB
Java
package net.minecraft.block;
|
|
|
|
import java.util.Random;
|
|
import net.minecraft.block.material.MapColor;
|
|
import net.minecraft.block.material.Material;
|
|
import net.minecraft.block.properties.IProperty;
|
|
import net.minecraft.block.properties.PropertyEnum;
|
|
import net.minecraft.block.state.BlockFaceShape;
|
|
import net.minecraft.block.state.IBlockState;
|
|
import net.minecraft.entity.EntityLivingBase;
|
|
import net.minecraft.init.Blocks;
|
|
import net.minecraft.item.ItemStack;
|
|
import net.minecraft.util.EnumFacing;
|
|
import net.minecraft.util.IStringSerializable;
|
|
import net.minecraft.util.math.AxisAlignedBB;
|
|
import net.minecraft.util.math.BlockPos;
|
|
import net.minecraft.world.IBlockAccess;
|
|
import net.minecraft.world.World;
|
|
import net.minecraftforge.fml.relauncher.Side;
|
|
import net.minecraftforge.fml.relauncher.SideOnly;
|
|
|
|
public abstract class BlockSlab extends Block
|
|
{
|
|
public static final PropertyEnum<BlockSlab.EnumBlockHalf> HALF = PropertyEnum.<BlockSlab.EnumBlockHalf>create("half", BlockSlab.EnumBlockHalf.class);
|
|
protected static final AxisAlignedBB AABB_BOTTOM_HALF = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 0.5D, 1.0D);
|
|
protected static final AxisAlignedBB AABB_TOP_HALF = new AxisAlignedBB(0.0D, 0.5D, 0.0D, 1.0D, 1.0D, 1.0D);
|
|
|
|
public BlockSlab(Material materialIn)
|
|
{
|
|
this(materialIn, materialIn.getMaterialMapColor());
|
|
}
|
|
|
|
public BlockSlab(Material p_i47249_1_, MapColor p_i47249_2_)
|
|
{
|
|
super(p_i47249_1_, p_i47249_2_);
|
|
this.fullBlock = this.isDouble();
|
|
this.setLightOpacity(255);
|
|
}
|
|
|
|
protected boolean canSilkHarvest()
|
|
{
|
|
return false;
|
|
}
|
|
|
|
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos)
|
|
{
|
|
if (this.isDouble())
|
|
{
|
|
return FULL_BLOCK_AABB;
|
|
}
|
|
else
|
|
{
|
|
return state.getValue(HALF) == BlockSlab.EnumBlockHalf.TOP ? AABB_TOP_HALF : AABB_BOTTOM_HALF;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Determines if the block is solid enough on the top side to support other blocks, like redstone components.
|
|
*/
|
|
public boolean isTopSolid(IBlockState state)
|
|
{
|
|
return ((BlockSlab)state.getBlock()).isDouble() || state.getValue(HALF) == BlockSlab.EnumBlockHalf.TOP;
|
|
}
|
|
|
|
/**
|
|
* Get the geometry of the queried face at the given position and state. This is used to decide whether things like
|
|
* buttons are allowed to be placed on the face, or how glass panes connect to the face, among other things.
|
|
* <p>
|
|
* Common values are {@code SOLID}, which is the default, and {@code UNDEFINED}, which represents something that
|
|
* does not fit the other descriptions and will generally cause other things not to connect to the face.
|
|
*
|
|
* @return an approximation of the form of the given face
|
|
*/
|
|
public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face)
|
|
{
|
|
if (((BlockSlab)state.getBlock()).isDouble())
|
|
{
|
|
return BlockFaceShape.SOLID;
|
|
}
|
|
else if (face == EnumFacing.UP && state.getValue(HALF) == BlockSlab.EnumBlockHalf.TOP)
|
|
{
|
|
return BlockFaceShape.SOLID;
|
|
}
|
|
else
|
|
{
|
|
return face == EnumFacing.DOWN && state.getValue(HALF) == BlockSlab.EnumBlockHalf.BOTTOM ? BlockFaceShape.SOLID : BlockFaceShape.UNDEFINED;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Used to determine ambient occlusion and culling when rebuilding chunks for render
|
|
*/
|
|
public boolean isOpaqueCube(IBlockState state)
|
|
{
|
|
return this.isDouble();
|
|
}
|
|
|
|
@Override
|
|
public boolean doesSideBlockRendering(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing face)
|
|
{
|
|
if (net.minecraftforge.common.ForgeModContainer.disableStairSlabCulling)
|
|
return super.doesSideBlockRendering(state, world, pos, face);
|
|
|
|
if ( state.isOpaqueCube() )
|
|
return true;
|
|
|
|
EnumBlockHalf side = state.getValue(HALF);
|
|
return (side == EnumBlockHalf.TOP && face == EnumFacing.UP) || (side == EnumBlockHalf.BOTTOM && face == EnumFacing.DOWN);
|
|
}
|
|
|
|
/**
|
|
* Called by ItemBlocks just before a block is actually set in the world, to allow for adjustments to the
|
|
* IBlockstate
|
|
*/
|
|
public IBlockState getStateForPlacement(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer)
|
|
{
|
|
IBlockState iblockstate = super.getStateForPlacement(worldIn, pos, facing, hitX, hitY, hitZ, meta, placer).withProperty(HALF, BlockSlab.EnumBlockHalf.BOTTOM);
|
|
|
|
if (this.isDouble())
|
|
{
|
|
return iblockstate;
|
|
}
|
|
else
|
|
{
|
|
return facing != EnumFacing.DOWN && (facing == EnumFacing.UP || (double)hitY <= 0.5D) ? iblockstate : iblockstate.withProperty(HALF, BlockSlab.EnumBlockHalf.TOP);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the quantity of items to drop on block destruction.
|
|
*/
|
|
public int quantityDropped(Random random)
|
|
{
|
|
return this.isDouble() ? 2 : 1;
|
|
}
|
|
|
|
public boolean isFullCube(IBlockState state)
|
|
{
|
|
return this.isDouble();
|
|
}
|
|
|
|
@SideOnly(Side.CLIENT)
|
|
public boolean shouldSideBeRendered(IBlockState blockState, IBlockAccess blockAccess, BlockPos pos, EnumFacing side)
|
|
{
|
|
if (this.isDouble())
|
|
{
|
|
return super.shouldSideBeRendered(blockState, blockAccess, pos, side);
|
|
}
|
|
else if (side != EnumFacing.UP && side != EnumFacing.DOWN && !super.shouldSideBeRendered(blockState, blockAccess, pos, side))
|
|
{
|
|
return false;
|
|
}
|
|
else if (false) // Forge: Additional logic breaks doesSideBlockRendering and is no longer useful.
|
|
{
|
|
IBlockState iblockstate = blockAccess.getBlockState(pos.offset(side));
|
|
boolean flag = isHalfSlab(iblockstate) && iblockstate.getValue(HALF) == BlockSlab.EnumBlockHalf.TOP;
|
|
boolean flag1 = isHalfSlab(blockState) && blockState.getValue(HALF) == BlockSlab.EnumBlockHalf.TOP;
|
|
|
|
if (flag1)
|
|
{
|
|
if (side == EnumFacing.DOWN)
|
|
{
|
|
return true;
|
|
}
|
|
else if (side == EnumFacing.UP && super.shouldSideBeRendered(blockState, blockAccess, pos, side))
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return !isHalfSlab(iblockstate) || !flag;
|
|
}
|
|
}
|
|
else if (side == EnumFacing.UP)
|
|
{
|
|
return true;
|
|
}
|
|
else if (side == EnumFacing.DOWN && super.shouldSideBeRendered(blockState, blockAccess, pos, side))
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return !isHalfSlab(iblockstate) || flag;
|
|
}
|
|
}
|
|
return super.shouldSideBeRendered(blockState, blockAccess, pos, side);
|
|
}
|
|
|
|
@SideOnly(Side.CLIENT)
|
|
protected static boolean isHalfSlab(IBlockState state)
|
|
{
|
|
Block block = state.getBlock();
|
|
return block == Blocks.STONE_SLAB || block == Blocks.WOODEN_SLAB || block == Blocks.STONE_SLAB2 || block == Blocks.PURPUR_SLAB;
|
|
}
|
|
|
|
/**
|
|
* Returns the slab block name with the type associated with it
|
|
*/
|
|
public abstract String getUnlocalizedName(int meta);
|
|
|
|
public abstract boolean isDouble();
|
|
|
|
public abstract IProperty<?> getVariantProperty();
|
|
|
|
public abstract Comparable<?> getTypeForItem(ItemStack stack);
|
|
|
|
public static enum EnumBlockHalf implements IStringSerializable
|
|
{
|
|
TOP("top"),
|
|
BOTTOM("bottom");
|
|
|
|
private final String name;
|
|
|
|
private EnumBlockHalf(String name)
|
|
{
|
|
this.name = name;
|
|
}
|
|
|
|
public String toString()
|
|
{
|
|
return this.name;
|
|
}
|
|
|
|
public String getName()
|
|
{
|
|
return this.name;
|
|
}
|
|
}
|
|
} |