    001package net.minecraft.block;
    002
    003import cpw.mods.fml.relauncher.Side;
    004import cpw.mods.fml.relauncher.SideOnly;
    005import java.util.List;
    006import java.util.Random;
    007import net.minecraft.block.material.Material;
    008import net.minecraft.entity.Entity;
    009import net.minecraft.util.AxisAlignedBB;
    010import net.minecraft.util.Facing;
    011import net.minecraft.world.IBlockAccess;
    012import net.minecraft.world.World;
    013
    014public abstract class BlockHalfSlab extends Block
    015{
    016    private final boolean isDoubleSlab;
    017
    018    public BlockHalfSlab(int par1, boolean par2, Material par3Material)
    019    {
    020        super(par1, 6, par3Material);
    021        this.isDoubleSlab = par2;
    022
    023        if (par2)
    024        {
    025            opaqueCubeLookup[par1] = true;
    026        }
    027        else
    028        {
    029            this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5F, 1.0F);
    030        }
    031
    032        this.setLightOpacity(255);
    033    }
    034
    035    /**
    036     * Updates the blocks bounds based on its current state. Args: world, x, y, z
    037     */
    038    public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
    039    {
    040        if (this.isDoubleSlab)
    041        {
    042            this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
    043        }
    044        else
    045        {
    046            boolean var5 = (par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 8) != 0;
    047
    048            if (var5)
    049            {
    050                this.setBlockBounds(0.0F, 0.5F, 0.0F, 1.0F, 1.0F, 1.0F);
    051            }
    052            else
    053            {
    054                this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5F, 1.0F);
    055            }
    056        }
    057    }
    058
    059    /**
    060     * Sets the block's bounds for rendering it as an item
    061     */
    062    public void setBlockBoundsForItemRender()
    063    {
    064        if (this.isDoubleSlab)
    065        {
    066            this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
    067        }
    068        else
    069        {
    070            this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5F, 1.0F);
    071        }
    072    }
    073
    074    /**
    075     * if the specified block is in the given AABB, add its collision bounding box to the given list
    076     */
    077    public void addCollidingBlockToList(World par1World, int par2, int par3, int par4, AxisAlignedBB par5AxisAlignedBB, List par6List, Entity par7Entity)
    078    {
    079        this.setBlockBoundsBasedOnState(par1World, par2, par3, par4);
    080        super.addCollidingBlockToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity);
    081    }
    082
    083    /**
    084     * Returns the block texture based on the side being looked at.  Args: side
    085     */
    086    public int getBlockTextureFromSide(int par1)
    087    {
    088        return this.getBlockTextureFromSideAndMetadata(par1, 0);
    089    }
    090
    091    /**
    092     * Is this block (a) opaque and (b) a full 1m cube?  This determines whether or not to render the shared face of two
    093     * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block.
    094     */
    095    public boolean isOpaqueCube()
    096    {
    097        return this.isDoubleSlab;
    098    }
    099
    100    /**
    101     * Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, side, hitX, hitY, hitZ, block metadata
    102     */
    103    public int onBlockPlaced(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, float par8, int par9)
    104    {
    105        return this.isDoubleSlab ? par9 : (par5 != 0 && (par5 == 1 || (double)par7 <= 0.5D) ? par9 : par9 | 8);
    106    }
    107
    108    /**
    109     * Returns the quantity of items to drop on block destruction.
    110     */
    111    public int quantityDropped(Random par1Random)
    112    {
    113        return this.isDoubleSlab ? 2 : 1;
    114    }
    115
    116    /**
    117     * Determines the damage on the item the block drops. Used in cloth and wood.
    118     */
    119    public int damageDropped(int par1)
    120    {
    121        return par1 & 7;
    122    }
    123
    124    /**
    125     * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc)
    126     */
    127    public boolean renderAsNormalBlock()
    128    {
    129        return this.isDoubleSlab;
    130    }
    131
    132    @SideOnly(Side.CLIENT)
    133
    134    /**
    135     * Returns true if the given side of this block type should be rendered, if the adjacent block is at the given
    136     * coordinates.  Args: blockAccess, x, y, z, side
    137     */
    138    public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5)
    139    {
    140        if (this.isDoubleSlab)
    141        {
    142            return super.shouldSideBeRendered(par1IBlockAccess, par2, par3, par4, par5);
    143        }
    144        else if (par5 != 1 && par5 != 0 && !super.shouldSideBeRendered(par1IBlockAccess, par2, par3, par4, par5))
    145        {
    146            return false;
    147        }
    148        else
    149        {
    150            int var6 = par2 + Facing.offsetsXForSide[Facing.faceToSide[par5]];
    151            int var7 = par3 + Facing.offsetsYForSide[Facing.faceToSide[par5]];
    152            int var8 = par4 + Facing.offsetsZForSide[Facing.faceToSide[par5]];
    153            boolean var9 = (par1IBlockAccess.getBlockMetadata(var6, var7, var8) & 8) != 0;
    154            return var9 ? (par5 == 0 ? true : (par5 == 1 && super.shouldSideBeRendered(par1IBlockAccess, par2, par3, par4, par5) ? true : !isBlockSingleSlab(par1IBlockAccess.getBlockId(par2, par3, par4)) || (par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 8) == 0)) : (par5 == 1 ? true : (par5 == 0 && super.shouldSideBeRendered(par1IBlockAccess, par2, par3, par4, par5) ? true : !isBlockSingleSlab(par1IBlockAccess.getBlockId(par2, par3, par4)) || (par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 8) != 0));
    155        }
    156    }
    157
    158    @SideOnly(Side.CLIENT)
    159
    160    /**
    161     * Takes a block ID, returns true if it's the same as the ID for a stone or wooden single slab.
    162     */
    163    private static boolean isBlockSingleSlab(int par0)
    164    {
    165        return par0 == Block.stoneSingleSlab.blockID || par0 == Block.woodSingleSlab.blockID;
    166    }
    167
    168    /**
    169     * Returns the slab block name with step type.
    170     */
    171    public abstract String getFullSlabName(int var1);
    172
    173    /**
    174     * Get the block's damage value (for use with pick block).
    175     */
    176    public int getDamageValue(World par1World, int par2, int par3, int par4)
    177    {
    178        return super.getDamageValue(par1World, par2, par3, par4) & 7;
    179    }
    180
    181    @SideOnly(Side.CLIENT)
    182
    183    /**
    184     * only called by clickMiddleMouseButton , and passed to inventory.setCurrentItem (along with isCreative)
    185     */
    186    public int idPicked(World par1World, int par2, int par3, int par4)
    187    {
    188        return isBlockSingleSlab(this.blockID) ? this.blockID : (this.blockID == Block.stoneDoubleSlab.blockID ? Block.stoneSingleSlab.blockID : (this.blockID == Block.woodDoubleSlab.blockID ? Block.woodSingleSlab.blockID : Block.stoneSingleSlab.blockID));
    189    }
    190}