package com.carpentersblocks.block; import java.util.List; import net.minecraft.block.material.Material; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.IIcon; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; import com.carpentersblocks.data.Slab; import com.carpentersblocks.tileentity.TEBase; import com.carpentersblocks.util.handler.EventHandler; import com.carpentersblocks.util.registry.BlockRegistry; import com.carpentersblocks.util.registry.IconRegistry; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; public class BlockCarpentersBlock extends BlockSided { private static Slab data = new Slab(); private static float[][] bounds = { { 0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F }, // FULL BLOCK { 0.0F, 0.0F, 0.0F, 0.5F, 1.0F, 1.0F }, // SLAB WEST { 0.5F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F }, // SLAB EAST { 0.0F, 0.0F, 0.0F, 1.0F, 0.5F, 1.0F }, // SLAB DOWN { 0.0F, 0.5F, 0.0F, 1.0F, 1.0F, 1.0F }, // SLAB UP { 0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 0.5F }, // SLAB NORTH { 0.0F, 0.0F, 0.5F, 1.0F, 1.0F, 1.0F } // SLAB SOUTH }; public BlockCarpentersBlock(Material material) { super(material, data); } @Override @SideOnly(Side.CLIENT) /** * Returns a base icon that doesn't rely on blockIcon, which * is set prior to texture stitch events. */ public IIcon getIcon() { return IconRegistry.icon_uncovered_quartered; } private boolean onHammerInteraction(TEBase TE) { if (data.isFullCube(TE)) { ForgeDirection side = ForgeDirection.getOrientation(EventHandler.eventFace).getOpposite(); data.setDirection(TE, side); } else { data.setFullCube(TE); } return true; } @Override /** * Alter type. */ protected boolean onHammerLeftClick(TEBase TE, EntityPlayer entityPlayer) { return onHammerInteraction(TE); } @Override /** * Alter type. */ protected boolean onHammerRightClick(TEBase TE, EntityPlayer entityPlayer) { return onHammerInteraction(TE); } @Override /** * Updates the blocks bounds based on its current state. Args: world, x, y, z */ public void setBlockBoundsBasedOnState(IBlockAccess blockAccess, int x, int y, int z) { TEBase TE = getTileEntity(blockAccess, x, y, z); if (TE != null) { int data = TE.getData(); if (data < bounds.length) { setBlockBounds(bounds[data][0], bounds[data][1], bounds[data][2], bounds[data][3], bounds[data][4], bounds[data][5]); } } } @Override /** * Adds all intersecting collision boxes to a list. (Be sure to only add boxes to the list if they intersect the * mask.) Parameters: World, X, Y, Z, mask, list, colliding entity */ public void addCollisionBoxesToList(World world, int x, int y, int z, AxisAlignedBB axisAlignedBB, List list, Entity entity) { setBlockBoundsBasedOnState(world, x, y, z); super.addCollisionBoxesToList(world, x, y, z, axisAlignedBB, list, entity); } @Override /** * Called when the block is placed in the world. */ public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase entityLiving, ItemStack itemStack) { super.onBlockPlacedBy(world, x, y, z, entityLiving, itemStack); TEBase TE = getTileEntity(world, x, y, z); if (TE != null) { int data = Slab.BLOCK_FULL; if (!entityLiving.isSneaking()) { /* Match block type with adjacent type if possible. */ TEBase[] TE_list = getAdjacentTileEntities(world, x, y, z); for (TEBase TE_current : TE_list) { if (TE_current != null) { if (TE_current.getBlockType().equals(this)) { data = TE_current.getData(); } } } } TE.setData(data); } } @Override /** * Checks to see if you can place this block can be placed on that side of a block: BlockLever overrides */ public boolean canPlaceBlockOnSide(World world, int x, int y, int z, int side) { return canPlaceBlockAt(world, x, y, z); } @Override /** * Checks if the block is a solid face on the given side, used by placement logic. */ public boolean isSideSolid(IBlockAccess blockAccess, int x, int y, int z, ForgeDirection side) { TEBase TE = getTileEntity(blockAccess, x, y, z); if (TE != null) { if (isBlockSolid(blockAccess, x, y, z)) { int data = TE.getData(); if (data == Slab.BLOCK_FULL) { return true; } else if (data == Slab.SLAB_Y_NEG && side == ForgeDirection.DOWN) { return true; } else if (data == Slab.SLAB_Y_POS && side == ForgeDirection.UP) { return true; } else if (data == Slab.SLAB_Z_NEG && side == ForgeDirection.NORTH) { return true; } else if (data == Slab.SLAB_Z_POS && side == ForgeDirection.SOUTH) { return true; } else if (data == Slab.SLAB_X_NEG && side == ForgeDirection.WEST) { return true; } else if (data == Slab.SLAB_X_POS && side == ForgeDirection.EAST) { return true; } } } return false; } /** * Called to determine whether to allow the a block to handle its own indirect power rather than using the default rules. * @param world The world * @param x The x position of this block instance * @param y The y position of this block instance * @param z The z position of this block instance * @param side The INPUT side of the block to be powered - ie the opposite of this block's output side * @return Whether Block#isProvidingWeakPower should be called when determining indirect power */ @Override public boolean shouldCheckWeakPower(IBlockAccess blockAccess, int x, int y, int z, int side) { TEBase TE = getTileEntity(blockAccess, x, y, z); if (TE != null) { int data = TE.getData(); return data == Slab.BLOCK_FULL; } return super.shouldCheckWeakPower(blockAccess, x, y, z, side); } @Override /** * Compares dimensions and coordinates of two opposite * sides to determine whether they share faces. */ protected boolean shareFaces(TEBase TE_adj, TEBase TE_src, ForgeDirection side_adj, ForgeDirection side_src) { if (TE_adj.getBlockType() == this) { setBlockBoundsBasedOnState(TE_src.getWorldObj(), TE_src.xCoord, TE_src.yCoord, TE_src.zCoord); double[] bnds_src = { getBlockBoundsMinX(), getBlockBoundsMinY(), getBlockBoundsMinZ(), getBlockBoundsMaxX(), getBlockBoundsMaxY(), getBlockBoundsMaxZ() }; setBlockBoundsBasedOnState(TE_adj.getWorldObj(), TE_adj.xCoord, TE_adj.yCoord, TE_adj.zCoord); switch (side_src) { case DOWN: return maxY == 1.0D && bnds_src[1] == 0.0D && minX == bnds_src[0] && maxX == bnds_src[3] && minZ == bnds_src[2] && maxZ == bnds_src[5]; case UP: return minY == 0.0D && bnds_src[4] == 1.0D && minX == bnds_src[0] && maxX == bnds_src[3] && minZ == bnds_src[2] && maxZ == bnds_src[5]; case NORTH: return maxZ == 1.0D && bnds_src[2] == 0.0D && minX == bnds_src[0] && maxX == bnds_src[3] && minY == bnds_src[1] && maxY == bnds_src[4]; case SOUTH: return minZ == 0.0D && bnds_src[5] == 1.0D && minX == bnds_src[0] && maxX == bnds_src[3] && minY == bnds_src[1] && maxY == bnds_src[4]; case WEST: return maxX == 1.0D && bnds_src[0] == 0.0D && minY == bnds_src[1] && maxY == bnds_src[4] && minZ == bnds_src[2] && maxZ == bnds_src[5]; case EAST: return minX == 0.0D && bnds_src[3] == 1.0D && minY == bnds_src[1] && maxY == bnds_src[4] && minZ == bnds_src[2] && maxZ == bnds_src[5]; default: return false; } } return super.shareFaces(TE_adj, TE_src, side_adj, side_src); } @Override /** * Returns whether block can support cover on side. */ public boolean canCoverSide(TEBase TE, World world, int x, int y, int z, int side) { return true; } @Override /** * Whether block requires an adjacent block with solid side for support. * * @return whether block can float freely */ public boolean canFloat() { return true; } /** * Whether side block placed against influences initial direction of block. * * @return <code>true</code> if initial placement direction ignored */ @Override protected boolean ignoreSidePlacement() { return true; } @Override /** * The type of render function that is called for this block */ public int getRenderType() { return BlockRegistry.carpentersBlockRenderID; } }