package com.carpentersblocks.block;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.MathHelper;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import com.carpentersblocks.data.Barrier;
import com.carpentersblocks.data.Gate;
import com.carpentersblocks.tileentity.TEBase;
import com.carpentersblocks.util.registry.BlockRegistry;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class BlockCarpentersGate extends BlockCoverable {
public BlockCarpentersGate(Material material)
{
super(material);
}
@Override
/**
* Alters gate type or sub-type and returns result.
*/
protected boolean onHammerRightClick(TEBase TE, EntityPlayer entityPlayer)
{
int type = Gate.getType(TE);
if (entityPlayer.isSneaking()) {
/*
* Cycle through sub-types
*/
if (type <= Gate.TYPE_VANILLA_X3) {
if (++type > Gate.TYPE_VANILLA_X3) {
type = Gate.TYPE_VANILLA;
}
}
} else {
/*
* Cycle through barrier types
*/
if (type <= Gate.TYPE_VANILLA_X3) {
type = Gate.TYPE_PICKET;
} else if (++type > Gate.TYPE_WALL) {
type = Gate.TYPE_VANILLA;
}
}
Gate.setType(TE, type);
return true;
}
@Override
/**
* Opens or closes gate on right click.
*/
protected void postOnBlockActivated(TEBase TE, EntityPlayer entityPlayer, int side, float hitX, float hitY, float hitZ, ActionResult actionResult)
{
if (Gate.getState(TE) == Gate.STATE_OPEN) {
Gate.setState(TE, Gate.STATE_CLOSED, true);
cycleNeighborGate(TE, TE.getWorldObj(), TE.xCoord, TE.yCoord, TE.zCoord);
} else {
int facing = (MathHelper.floor_double(entityPlayer.rotationYaw * 4.0F / 360.0F + 0.5D) & 3) % 4;
Gate.setState(TE, Gate.STATE_OPEN, true);
if (Gate.getFacing(TE) == Gate.FACING_ON_X) {
Gate.setDirOpen(TE, facing == 0 ? Gate.DIR_POS : Gate.DIR_NEG);
} else {
Gate.setDirOpen(TE, facing == 3 ? Gate.DIR_POS : Gate.DIR_NEG);
}
cycleNeighborGate(TE, TE.getWorldObj(), TE.xCoord, TE.yCoord, TE.zCoord);
}
actionResult.setAltered().setNoSound();
}
@Override
/**
* Checks to see if its valid to put this block at the specified coordinates. Args: world, x, y, z
*/
public boolean canPlaceBlockAt(World world, int x, int y, int z)
{
return !world.getBlock(x, y - 1, z).getMaterial().isSolid() ? false : super.canPlaceBlockAt(world, x, y, z);
}
@Override
/**
* Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been
* cleared to be reused)
*/
public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z)
{
TEBase TE = getTileEntity(world, x, y, z);
if (TE != null) {
if (Gate.getState(TE) == Gate.STATE_OPEN) {
return null;
} else if (Gate.getFacing(TE) == Gate.FACING_ON_Z) {
if (Gate.getType(TE) == Gate.TYPE_VANILLA || Gate.getType(TE) == Gate.TYPE_WALL) {
return AxisAlignedBB.getBoundingBox(x + 0.4375F, y, z, x + 0.5625F, y + 1.5F, z + 1.0F);
} else {
return AxisAlignedBB.getBoundingBox(x + 0.375F, y, z, x + 0.625F, y + 1.5F, z + 1.0F);
}
} else {
if (Gate.getType(TE) == Gate.TYPE_VANILLA || Gate.getType(TE) == Gate.TYPE_WALL) {
return AxisAlignedBB.getBoundingBox(x, y, z + 0.4375F, x + 1.0F, y + 1.5F, z + 0.5625F);
} else {
return AxisAlignedBB.getBoundingBox(x, y, z + 0.375F, x + 1.0F, y + 1.5F, z + 0.625F);
}
}
}
return null;
}
@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) {
if (Gate.getFacing(TE) == Gate.FACING_ON_Z) {
if (Gate.getType(TE) == Gate.TYPE_VANILLA || Gate.getType(TE) == Gate.TYPE_WALL) {
setBlockBounds(0.4375F, 0.0F, 0.0F, 0.5625F, 1.0F, 1.0F);
} else {
setBlockBounds(0.375F, 0.0F, 0.0F, 0.625F, 1.0F, 1.0F);
}
} else {
if (Gate.getType(TE) == Gate.TYPE_VANILLA || Gate.getType(TE) == Gate.TYPE_WALL) {
setBlockBounds(0.0F, 0.0F, 0.4375F, 1.0F, 1.0F, 0.5625F);
} else {
setBlockBounds(0.0F, 0.0F, 0.375F, 1.0F, 1.0F, 0.625F);
}
}
}
}
/**
* Opens or closes one neighboring gate above or below block.
*/
private void cycleNeighborGate(TEBase TE, World world, int x, int y, int z)
{
boolean isGateBelow = world.getBlock(x, y - 1, z).equals(this);
boolean isGateAbove = world.getBlock(x, y + 1, z).equals(this);
/*
* Will only check for gate above or below, and limit to only activating a single stacked gate.
* It is done this way intentionally.
*/
if (isGateBelow) {
TEBase TE_YN = getTileEntity(world, x, y - 1, z);
if (Gate.getFacing(TE_YN) == Gate.getFacing(TE)) {
Gate.setDirOpen(TE_YN, Gate.getDirOpen(TE));
Gate.setState(TE_YN, Gate.getState(TE), false);
}
} else if (isGateAbove) {
TEBase TE_YP = getTileEntity(world, x, y + 1, z);
if (Gate.getFacing(TE_YP) == Gate.getFacing(TE)) {
Gate.setDirOpen(TE_YP, Gate.getDirOpen(TE));
Gate.setState(TE_YP, Gate.getState(TE), false);
}
}
}
@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 facing = (MathHelper.floor_double(entityLiving.rotationYaw * 4.0F / 360.0F + 0.5D) & 3) % 4;
Gate.setFacing(TE, facing == 3 || facing == 1 ? Gate.FACING_ON_Z : Gate.FACING_ON_X);
/* 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) {
Block block = TE_current.getBlockType();
if (block.equals(this)) {
Gate.setType(TE, Gate.getType(TE_current));
} else if (block.equals(BlockRegistry.blockCarpentersGate)) {
Gate.setType(TE, Barrier.getType(TE_current));
}
}
}
}
}
@Override
/**
* Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are
* their own) Args: x, y, z, neighbor blockID
*/
public void onNeighborBlockChange(World world, int x, int y, int z, Block block)
{
if (!world.isRemote) {
TEBase TE = getTileEntity(world, x, y, z);
if (TE != null) {
boolean isPowered = world.isBlockIndirectlyGettingPowered(x, y, z);
if (isPowered || block != null && block.canProvidePower())
{
int state = Gate.getState(TE);
if (isPowered && state == Gate.STATE_CLOSED) {
Gate.setState(TE, Gate.STATE_OPEN, true);
cycleNeighborGate(TE, world, x, y, z);
} else if (!isPowered && state == Gate.STATE_OPEN) {
Gate.setState(TE, Gate.STATE_CLOSED, true);
cycleNeighborGate(TE, world, x, y, z);
}
}
}
}
super.onNeighborBlockChange(world, x, y, z, block);
}
@Override
@SideOnly(Side.CLIENT)
/**
* Returns true if the given side of this block type should be rendered, if the adjacent block is at the given
* coordinates. Args: world, x, y, z, side
*/
public boolean shouldSideBeRendered(IBlockAccess blockAccess, int x, int y, int z, int side)
{
return true;
}
@Override
/**
* The type of render function that is called for this block
*/
public int getRenderType()
{
return BlockRegistry.carpentersGateRenderID;
}
@Override
public ForgeDirection[] getValidRotations(World worldObj, int x, int y,int z)
{
ForgeDirection[] axises = {ForgeDirection.UP, ForgeDirection.DOWN};
return axises;
}
@Override
public boolean rotateBlock(World world, int x, int y, int z, ForgeDirection axis)
{
// to correctly support archimedes' ships mod:
// if Axis is DOWN, block rotates to the left, north -> west -> south -> east
// if Axis is UP, block rotates to the right: north -> east -> south -> west
TileEntity tile = world.getTileEntity(x, y, z);
if (tile != null && tile instanceof TEBase)
{
TEBase cbTile = (TEBase)tile;
int facing = Gate.getFacing(cbTile);
switch (facing)
{
case 0:{Gate.setFacing(cbTile, 1); break;}
case 1:{Gate.setFacing(cbTile, 0); break;}
default: return false;
}
return true;
}
return false;
}
}