package com.bioxx.tfc2.blocks;
import java.util.List;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.block.BlockStairs;
import net.minecraft.block.BlockStairs.EnumHalf;
import net.minecraft.block.BlockStairs.EnumShape;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.MapColor;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.creativetab.CreativeTabs;
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.BlockRenderLayer;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.Explosion;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import com.bioxx.tfc2.Core;
import com.bioxx.tfc2.api.interfaces.ISupportBlock;
import com.bioxx.tfc2.blocks.terrain.BlockCollapsible;
import com.google.common.collect.Lists;
public class BlockStairsTFC extends BlockCollapsible
{
protected static final AxisAlignedBB AABB_SLAB_TOP = new AxisAlignedBB(0.0D, 0.5D, 0.0D, 1.0D, 1.0D, 1.0D);
protected static final AxisAlignedBB AABB_QTR_TOP_WEST = new AxisAlignedBB(0.0D, 0.5D, 0.0D, 0.5D, 1.0D, 1.0D);
protected static final AxisAlignedBB AABB_QTR_TOP_EAST = new AxisAlignedBB(0.5D, 0.5D, 0.0D, 1.0D, 1.0D, 1.0D);
protected static final AxisAlignedBB AABB_QTR_TOP_NORTH = new AxisAlignedBB(0.0D, 0.5D, 0.0D, 1.0D, 1.0D, 0.5D);
protected static final AxisAlignedBB AABB_QTR_TOP_SOUTH = new AxisAlignedBB(0.0D, 0.5D, 0.5D, 1.0D, 1.0D, 1.0D);
protected static final AxisAlignedBB AABB_OCT_TOP_NW = new AxisAlignedBB(0.0D, 0.5D, 0.0D, 0.5D, 1.0D, 0.5D);
protected static final AxisAlignedBB AABB_OCT_TOP_NE = new AxisAlignedBB(0.5D, 0.5D, 0.0D, 1.0D, 1.0D, 0.5D);
protected static final AxisAlignedBB AABB_OCT_TOP_SW = new AxisAlignedBB(0.0D, 0.5D, 0.5D, 0.5D, 1.0D, 1.0D);
protected static final AxisAlignedBB AABB_OCT_TOP_SE = new AxisAlignedBB(0.5D, 0.5D, 0.5D, 1.0D, 1.0D, 1.0D);
protected static final AxisAlignedBB AABB_SLAB_BOTTOM = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 0.5D, 1.0D);
protected static final AxisAlignedBB AABB_QTR_BOT_WEST = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 0.5D, 0.5D, 1.0D);
protected static final AxisAlignedBB AABB_QTR_BOT_EAST = new AxisAlignedBB(0.5D, 0.0D, 0.0D, 1.0D, 0.5D, 1.0D);
protected static final AxisAlignedBB AABB_QTR_BOT_NORTH = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 0.5D, 0.5D);
protected static final AxisAlignedBB AABB_QTR_BOT_SOUTH = new AxisAlignedBB(0.0D, 0.0D, 0.5D, 1.0D, 0.5D, 1.0D);
protected static final AxisAlignedBB AABB_OCT_BOT_NW = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 0.5D, 0.5D, 0.5D);
protected static final AxisAlignedBB AABB_OCT_BOT_NE = new AxisAlignedBB(0.5D, 0.0D, 0.0D, 1.0D, 0.5D, 0.5D);
protected static final AxisAlignedBB AABB_OCT_BOT_SW = new AxisAlignedBB(0.0D, 0.0D, 0.5D, 0.5D, 0.5D, 1.0D);
protected static final AxisAlignedBB AABB_OCT_BOT_SE = new AxisAlignedBB(0.5D, 0.0D, 0.5D, 1.0D, 0.5D, 1.0D);
private static final int[][] field_150150_a = { { 4, 5 }, { 5, 7 }, { 6, 7 }, { 4, 6 }, { 0, 1 }, { 1, 3 }, { 2, 3 }, { 0, 2 } };
private final Block modelBlock;
private final IBlockState modelState;
private boolean hasRaytraced;
private int rayTracePass;
public BlockStairsTFC(IBlockState modelState)
{
super(modelState.getBlock().getMaterial(modelState), null);
setDefaultState(this.blockState.getBaseState().withProperty(BlockStairs.FACING, EnumFacing.NORTH).withProperty(BlockStairs.HALF, EnumHalf.BOTTOM).withProperty(BlockStairs.SHAPE, EnumShape.STRAIGHT));
this.modelBlock = modelState.getBlock();
this.modelState = modelState;
//setHardness(this.modelBlock.blockHardness);
//setResistance(this.modelBlock.blockResistance / 3.0F);
this.setSoundType(SoundType.WOOD);
setLightOpacity(255);
setCreativeTab(CreativeTabs.BUILDING_BLOCKS);
}
@Override
public void createFallingEntity(World world, BlockPos pos, IBlockState state)
{
/*world.setBlockToAir(pos);
EntityItem ei = new EntityItem(world, pos.getX(), pos.getY(), pos.getZ(), new ItemStack(Items.STICK, 1+world.rand.nextInt(3)));
world.spawnEntityInWorld(ei);*/
if(modelBlock instanceof BlockCollapsible)
{
((BlockCollapsible)modelBlock).createFallingEntity(world, pos, modelState);
}
else super.createFallingEntity(world, pos, state);
}
@Override
public int getNaturalSupportRange(IBlockAccess world, BlockPos pos, IBlockState myState)
{
if(modelBlock instanceof BlockCollapsible)
{
((BlockCollapsible)modelBlock).getNaturalSupportRange(world, pos, modelState);
}
return 5;
}
@Override
public boolean canBeSupportedBy(IBlockState myState, IBlockState otherState)
{
if(modelBlock instanceof BlockCollapsible)
{
((BlockCollapsible)modelBlock).canBeSupportedBy(modelState, otherState);
}
if(otherState.getBlock() == this || Core.isSoil(otherState) || Core.isStone(otherState) || otherState.getBlock() instanceof ISupportBlock)
return true;
return false;
}
@Override
public boolean isSideSolid(IBlockState state,IBlockAccess world, BlockPos pos, EnumFacing side)
{
boolean flipped = state.getValue(BlockStairs.HALF) == EnumHalf.TOP;
EnumShape shape = (EnumShape)state.getValue(BlockStairs.SHAPE);
EnumFacing facing = (EnumFacing)state.getValue(BlockStairs.FACING);
if (side == EnumFacing.UP) return flipped;
if (side == EnumFacing.DOWN) return !flipped;
if (facing == side) return true;
if (flipped)
{
if (shape == EnumShape.INNER_LEFT) return side == facing.rotateYCCW();
if (shape == EnumShape.INNER_RIGHT) return side == facing.rotateY();
}
else
{
if (shape == EnumShape.INNER_LEFT) return side == facing.rotateY();
if (shape == EnumShape.INNER_RIGHT) return side == facing.rotateYCCW();
}
return false;
}
@Override
public boolean isOpaqueCube(IBlockState state)
{
return false;
}
@Override
public boolean doesSideBlockRendering(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing face)
{
if (isOpaqueCube(state)) {
return true;
}
IBlockState iblockstate = world.getBlockState(pos);
EnumHalf half = (EnumHalf)iblockstate.getValue(BlockStairs.HALF);
EnumFacing side = (EnumFacing)iblockstate.getValue(BlockStairs.FACING);
return (side == face.getOpposite()) || ((half == EnumHalf.TOP) && (face == EnumFacing.DOWN)) || ((half == EnumHalf.BOTTOM) && (face == EnumFacing.UP));
}
@Override
public boolean isFullCube(IBlockState state)
{
return false;
}
public void setBaseCollisionBounds(IBlockAccess worldIn, BlockPos pos)
{
if (worldIn.getBlockState(pos).getValue(BlockStairs.HALF) == EnumHalf.TOP)
{
setBlockBounds(0.0F, 0.5F, 0.0F, 1.0F, 1.0F, 1.0F);
}
else
{
setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5F, 1.0F);
}
}
@Override
public void addCollisionBoxToList(IBlockState state, World worldIn, BlockPos pos, AxisAlignedBB entityBox, List<AxisAlignedBB> collidingBoxes, Entity entityIn)
{
state = this.getActualState(state, worldIn, pos);
for (AxisAlignedBB axisalignedbb : getCollisionBoxList(state))
{
addCollisionBoxToList(pos, entityBox, collidingBoxes, axisalignedbb);
}
}
private static List<AxisAlignedBB> getCollisionBoxList(IBlockState bstate)
{
List<AxisAlignedBB> list = Lists.<AxisAlignedBB>newArrayList();
boolean flag = bstate.getValue(BlockStairs.HALF) == BlockStairs.EnumHalf.TOP;
list.add(flag ? AABB_SLAB_TOP : AABB_SLAB_BOTTOM);
BlockStairs.EnumShape blockstairs$enumshape = (BlockStairs.EnumShape)bstate.getValue(BlockStairs.SHAPE);
if (blockstairs$enumshape == BlockStairs.EnumShape.STRAIGHT || blockstairs$enumshape == BlockStairs.EnumShape.INNER_LEFT || blockstairs$enumshape == BlockStairs.EnumShape.INNER_RIGHT)
{
list.add(getCollQuarterBlock(bstate));
}
if (blockstairs$enumshape != BlockStairs.EnumShape.STRAIGHT)
{
list.add(getCollEighthBlock(bstate));
}
return list;
}
private static AxisAlignedBB getCollQuarterBlock(IBlockState bstate)
{
boolean flag = bstate.getValue(BlockStairs.HALF) == BlockStairs.EnumHalf.TOP;
switch ((EnumFacing)bstate.getValue(BlockStairs.FACING))
{
case NORTH:
default:
return flag ? AABB_QTR_BOT_NORTH : AABB_QTR_TOP_NORTH;
case SOUTH:
return flag ? AABB_QTR_BOT_SOUTH : AABB_QTR_TOP_SOUTH;
case WEST:
return flag ? AABB_QTR_BOT_WEST : AABB_QTR_TOP_WEST;
case EAST:
return flag ? AABB_QTR_BOT_EAST : AABB_QTR_TOP_EAST;
}
}
/**
* Returns a bounding box representing an eighth of a block (a block whose three dimensions are halved).
* Used in all stair shapes except STRAIGHT (gets added alone in the case of OUTER; alone with a quarter block in
* case of INSIDE).
*/
private static AxisAlignedBB getCollEighthBlock(IBlockState bstate)
{
EnumFacing enumfacing = (EnumFacing)bstate.getValue(BlockStairs.FACING);
EnumFacing enumfacing1;
switch ((BlockStairs.EnumShape)bstate.getValue(BlockStairs.SHAPE))
{
case OUTER_LEFT:
default:
enumfacing1 = enumfacing;
break;
case OUTER_RIGHT:
enumfacing1 = enumfacing.rotateY();
break;
case INNER_RIGHT:
enumfacing1 = enumfacing.getOpposite();
break;
case INNER_LEFT:
enumfacing1 = enumfacing.rotateYCCW();
}
boolean flag = bstate.getValue(BlockStairs.HALF) == BlockStairs.EnumHalf.TOP;
switch (enumfacing1)
{
case NORTH:
default:
return flag ? AABB_OCT_BOT_NW : AABB_OCT_TOP_NW;
case SOUTH:
return flag ? AABB_OCT_BOT_SE : AABB_OCT_TOP_SE;
case WEST:
return flag ? AABB_OCT_BOT_SW : AABB_OCT_TOP_SW;
case EAST:
return flag ? AABB_OCT_BOT_NE : AABB_OCT_TOP_NE;
}
}
@Override
public void onBlockClicked(World worldIn, BlockPos pos, EntityPlayer playerIn)
{
this.modelBlock.onBlockClicked(worldIn, pos, playerIn);
}
@Override
@SideOnly(Side.CLIENT)
public void randomDisplayTick(IBlockState state, World worldIn, BlockPos pos, Random rand)
{
this.modelBlock.randomDisplayTick(state, worldIn, pos, rand);
}
@Override
public void onBlockDestroyedByPlayer(World worldIn, BlockPos pos, IBlockState state)
{
this.modelBlock.onBlockDestroyedByPlayer(worldIn, pos, state);
}
/*@Override
@SideOnly(Side.CLIENT)
public int getMixedBrightnessForBlock(IBlockAccess worldIn, BlockPos pos)
{
return this.modelBlock.getMixedBrightnessForBlock(worldIn, pos);
}*/
@Override
public float getExplosionResistance(Entity exploder)
{
return this.modelBlock.getExplosionResistance(exploder);
}
@Override
public int tickRate(World worldIn)
{
return this.modelBlock.tickRate(worldIn);
}
@Override
public Vec3d modifyAcceleration(World worldIn, BlockPos pos, Entity entityIn, Vec3d motion)
{
return this.modelBlock.modifyAcceleration(worldIn, pos, entityIn, motion);
}
@Override
@SideOnly(Side.CLIENT)
public BlockRenderLayer getBlockLayer()
{
return this.modelBlock.getBlockLayer();
}
@Override
@SideOnly(Side.CLIENT)
public AxisAlignedBB getSelectedBoundingBox(IBlockState state, World worldIn, BlockPos pos)
{
return this.modelBlock.getSelectedBoundingBox(state, worldIn, pos);
}
@Override
public boolean isCollidable()
{
return this.modelBlock.isCollidable();
}
@Override
public boolean canCollideCheck(IBlockState state, boolean hitIfLiquid)
{
return this.modelBlock.canCollideCheck(state, hitIfLiquid);
}
@Override
public boolean canPlaceBlockAt(World worldIn, BlockPos pos)
{
return this.modelBlock.canPlaceBlockAt(worldIn, pos);
}
@Override
public void onBlockAdded(World worldIn, BlockPos pos, IBlockState state)
{
neighborChanged(this.modelState, worldIn, pos, net.minecraft.init.Blocks.AIR);
this.modelBlock.onBlockAdded(worldIn, pos, this.modelState);
}
@Override
public void breakBlock(World worldIn, BlockPos pos, IBlockState state)
{
this.modelBlock.breakBlock(worldIn, pos, this.modelState);
}
@Override
public void onEntityCollidedWithBlock(World worldIn, BlockPos pos, IBlockState state, Entity entityIn)
{
this.modelBlock.onEntityCollidedWithBlock(worldIn, pos, state, entityIn);
}
@Override
public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand)
{
this.modelBlock.updateTick(worldIn, pos, state, rand);
}
@Override
public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, net.minecraft.util.EnumHand hand, ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ)
{
return this.modelBlock.onBlockActivated(worldIn, pos, this.modelState, playerIn, hand, heldItem, EnumFacing.DOWN, 0.0F, 0.0F, 0.0F);
}
@Override
public void onBlockDestroyedByExplosion(World worldIn, BlockPos pos, Explosion explosionIn)
{
this.modelBlock.onBlockDestroyedByExplosion(worldIn, pos, explosionIn);
}
@Override
public MapColor getMapColor(IBlockState state)
{
return this.modelBlock.getMapColor(this.modelState);
}
@Override
public IBlockState onBlockPlaced(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer)
{
IBlockState iblockstate = super.onBlockPlaced(worldIn, pos, facing, hitX, hitY, hitZ, meta, placer);
iblockstate = iblockstate.withProperty(BlockStairs.FACING, placer.getHorizontalFacing()).withProperty(BlockStairs.SHAPE, EnumShape.STRAIGHT);
return (facing != EnumFacing.DOWN) && ((facing == EnumFacing.UP) || (hitY <= 0.5D)) ? iblockstate.withProperty(BlockStairs.HALF, EnumHalf.BOTTOM) : iblockstate.withProperty(BlockStairs.HALF, EnumHalf.TOP);
}
@Override
public RayTraceResult collisionRayTrace(IBlockState blockState, World worldIn, BlockPos pos, Vec3d start, Vec3d end)
{
List<RayTraceResult> list = Lists.<RayTraceResult>newArrayList();
for (AxisAlignedBB axisalignedbb : getCollisionBoxList(this.getActualState(blockState, worldIn, pos)))
{
list.add(this.rayTrace(pos, start, end, axisalignedbb));
}
RayTraceResult raytraceresult1 = null;
double d1 = 0.0D;
for (RayTraceResult raytraceresult : list)
{
if (raytraceresult != null)
{
double d0 = raytraceresult.hitVec.squareDistanceTo(end);
if (d0 > d1)
{
raytraceresult1 = raytraceresult;
d1 = d0;
}
}
}
return raytraceresult1;
}
private static BlockStairs.EnumShape func_185706_d(IBlockState p_185706_0_, IBlockAccess p_185706_1_, BlockPos p_185706_2_)
{
EnumFacing enumfacing = (EnumFacing)p_185706_0_.getValue(BlockStairs.FACING);
IBlockState iblockstate = p_185706_1_.getBlockState(p_185706_2_.offset(enumfacing));
if (isBlockStairs(iblockstate) && p_185706_0_.getValue(BlockStairs.HALF) == iblockstate.getValue(BlockStairs.HALF))
{
EnumFacing enumfacing1 = (EnumFacing)iblockstate.getValue(BlockStairs.FACING);
if (enumfacing1.getAxis() != ((EnumFacing)p_185706_0_.getValue(BlockStairs.FACING)).getAxis() && isDifferentStairs(p_185706_0_, p_185706_1_, p_185706_2_, enumfacing1.getOpposite()))
{
if (enumfacing1 == enumfacing.rotateYCCW())
{
return BlockStairs.EnumShape.OUTER_LEFT;
}
return BlockStairs.EnumShape.OUTER_RIGHT;
}
}
IBlockState iblockstate1 = p_185706_1_.getBlockState(p_185706_2_.offset(enumfacing.getOpposite()));
if (isBlockStairs(iblockstate1) && p_185706_0_.getValue(BlockStairs.HALF) == iblockstate1.getValue(BlockStairs.HALF))
{
EnumFacing enumfacing2 = (EnumFacing)iblockstate1.getValue(BlockStairs.FACING);
if (enumfacing2.getAxis() != ((EnumFacing)p_185706_0_.getValue(BlockStairs.FACING)).getAxis() && isDifferentStairs(p_185706_0_, p_185706_1_, p_185706_2_, enumfacing2))
{
if (enumfacing2 == enumfacing.rotateYCCW())
{
return BlockStairs.EnumShape.INNER_LEFT;
}
return BlockStairs.EnumShape.INNER_RIGHT;
}
}
return BlockStairs.EnumShape.STRAIGHT;
}
private static boolean isDifferentStairs(IBlockState p_185704_0_, IBlockAccess p_185704_1_, BlockPos p_185704_2_, EnumFacing p_185704_3_)
{
IBlockState iblockstate = p_185704_1_.getBlockState(p_185704_2_.offset(p_185704_3_));
return !isBlockStairs(iblockstate) || iblockstate.getValue(BlockStairs.FACING) != p_185704_0_.getValue(BlockStairs.FACING) || iblockstate.getValue(BlockStairs.HALF) != p_185704_0_.getValue(BlockStairs.HALF);
}
public static boolean isBlockStairs(IBlockState p_185709_0_)
{
return p_185709_0_.getBlock() instanceof BlockStairs || p_185709_0_.getBlock() instanceof BlockStairsTFC;
}
@Override
public IBlockState getStateFromMeta(int meta)
{
IBlockState iblockstate = getDefaultState().withProperty(BlockStairs.HALF, (meta & 0x4) > 0 ? EnumHalf.TOP : EnumHalf.BOTTOM);
iblockstate = iblockstate.withProperty(BlockStairs.FACING, EnumFacing.getFront(5 - (meta & 0x3)));
return iblockstate;
}
@Override
public int getMetaFromState(IBlockState state)
{
int i = 0;
if (state.getValue(BlockStairs.HALF) == EnumHalf.TOP)
{
i |= 0x4;
}
i |= 5 - ((EnumFacing)state.getValue(BlockStairs.FACING)).getIndex();
return i;
}
@Override
public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos)
{
return state.withProperty(BlockStairs.SHAPE, func_185706_d(state, worldIn, pos));
}
@Override
protected BlockStateContainer createBlockState()
{
return new BlockStateContainer(this, new IProperty[] { BlockStairs.FACING, BlockStairs.HALF, BlockStairs.SHAPE });
}
}