package com.jaquadro.minecraft.gardenstuff.block;
import com.jaquadro.minecraft.gardenapi.api.GardenAPI;
import com.jaquadro.minecraft.gardenapi.api.connect.IAttachable;
import com.jaquadro.minecraft.gardenapi.api.connect.IChainSingleAttachable;
import com.jaquadro.minecraft.gardencore.core.ModCreativeTabs;
import com.jaquadro.minecraft.gardenstuff.GardenStuff;
import com.jaquadro.minecraft.gardenstuff.block.tile.TileEntityLattice;
import com.jaquadro.minecraft.gardenstuff.core.ClientProxy;
import com.jaquadro.minecraft.gardentrees.block.BlockThinLog;
import net.minecraft.block.Block;
import net.minecraft.block.BlockContainer;
import net.minecraft.block.material.Material;
import net.minecraft.entity.Entity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.Vec3;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import java.util.ArrayList;
import java.util.List;
public abstract class BlockLattice extends BlockContainer implements IChainSingleAttachable
{
private static final float UN4 = .0625f * -4;
private static final float U7 = .0625f * 7;
private static final float U8 = .0625f * 8;
private static final float U9 = .0625f * 9;
private static final float U20 = .0625f * 20;
public BlockLattice (String blockName, Material material) {
super(material);
setBlockName(blockName);
setHardness(2.5f);
setResistance(5);
setBlockTextureName(GardenStuff.MOD_ID + ":lattice_iron");
setCreativeTab(ModCreativeTabs.tabGardenCore);
setBlockBoundsForItemRender();
}
@Override
public boolean isOpaqueCube () {
return false;
}
@Override
public boolean renderAsNormalBlock () {
return false;
}
@Override
public int getRenderType () {
return ClientProxy.latticeRenderID;
}
@Override
public int damageDropped (int meta) {
return meta;
}
@Override
public void setBlockBoundsBasedOnState (IBlockAccess world, int x, int y, int z) {
int connectFlags = calcConnectionFlags(world, x, y, z);
float margin = .0625f * 6;
float ys = (connectFlags & 1) != 0 ? 0 : margin;
float ye = (connectFlags & 2) != 0 ? 1 : 1 - margin;
float zs = (connectFlags & 4) != 0 ? 0 : margin;
float ze = (connectFlags & 8) != 0 ? 1 : 1 - margin;
float xs = (connectFlags & 16) != 0 ? 0 : margin;
float xe = (connectFlags & 32) != 0 ? 1 : 1 - margin;
setBlockBounds(xs, ys, zs, xe, ye, ze);
}
@Override
public void addCollisionBoxesToList (World world, int x, int y, int z, AxisAlignedBB mask, List list, Entity colliding) {
int connectFlags = calcConnectionFlags(world, x, y, z);
boolean connectYNeg = (connectFlags & 1) != 0;
boolean connectYPos = (connectFlags & 2) != 0;
boolean connectZNeg = (connectFlags & 4) != 0;
boolean connectZPos = (connectFlags & 8) != 0;
boolean connectXNeg = (connectFlags & 16) != 0;
boolean connectXPos = (connectFlags & 32) != 0;
boolean extYNeg = (connectFlags & 64) != 0;
boolean extYPos = (connectFlags & 128) != 0;
boolean extZNeg = (connectFlags & 256) != 0;
boolean extZPos = (connectFlags & 512) != 0;
boolean extXNeg = (connectFlags & 1024) != 0;
boolean extXPos = (connectFlags & 2048) != 0;
float yMin = extYNeg ? UN4 : (connectYNeg ? 0 : U7);
float yMax = extYPos ? U20 : (connectYPos ? 1 : U9);
IAttachable attachableYN = GardenAPI.instance().registries().attachable().getAttachable(world.getBlock(x, y - 1, z), world.getBlockMetadata(x, y - 1, z));
if (attachableYN != null && attachableYN.isAttachable(world, x, y - 1, z, 1))
yMin = (float)attachableYN.getAttachDepth(world, x, y - 1, z, 1) - 1;
IAttachable attachableYP = GardenAPI.instance().registries().attachable().getAttachable(world.getBlock(x, y + 1, z), world.getBlockMetadata(x, y + 1, z));
if (attachableYP != null && attachableYP.isAttachable(world, x, y + 1, z, 0))
yMax = (float)attachableYP.getAttachDepth(world, x, y + 1, z, 0) + 1;
float zMin = extZNeg ? UN4 : (connectZNeg ? 0 : U7);
float zMax = extZPos ? U20 : (connectZPos ? 1 : U9);
float xMin = extXNeg ? UN4 : (connectXNeg ? 0 : U7);
float xMax = extXPos ? U20 : (connectXPos ? 1 : U9);
setBlockBounds(U7, yMin, U7, U9, yMax, U9);
super.addCollisionBoxesToList(world, x, y, z, mask, list, colliding);
setBlockBounds(xMin, U7, U7, xMax, U9, U9);
super.addCollisionBoxesToList(world, x, y, z, mask, list, colliding);
setBlockBounds(U7, U7, zMin, U9, U9, zMax);
super.addCollisionBoxesToList(world, x, y, z, mask, list, colliding);
setBlockBoundsBasedOnState(world, x, y, z);
}
@Override
public ArrayList<ItemStack> getDrops (World world, int x, int y, int z, int metadata, int fortune) {
ArrayList<ItemStack> ret = new ArrayList<ItemStack>();
int count = quantityDropped(metadata, fortune, world.rand);
for(int i = 0; i < count; i++)
{
Item item = getItemDropped(metadata, world.rand, fortune);
if (item != null)
{
ret.add(new ItemStack(item, 1, damageDropped(metadata)));
}
}
return ret;
}
public int calcConnectionFlags (IBlockAccess world, int x, int y, int z) {
Block blockYNeg = world.getBlock(x, y - 1, z);
Block blockYPos = world.getBlock(x, y + 1, z);
Block blockZNeg = world.getBlock(x, y, z - 1);
Block blockZPos = world.getBlock(x, y, z + 1);
Block blockXNeg = world.getBlock(x - 1, y, z);
Block blockXPos = world.getBlock(x + 1, y, z);
boolean hardYNeg = isNeighborHardConnection(world, x, y - 1, z, blockYNeg, ForgeDirection.DOWN);
boolean hardYPos = isNeighborHardConnection(world, x, y + 1, z, blockYPos, ForgeDirection.UP);
boolean hardZNeg = isNeighborHardConnection(world, x, y, z - 1, blockZNeg, ForgeDirection.NORTH);
boolean hardZPos = isNeighborHardConnection(world, x, y, z + 1, blockZPos, ForgeDirection.SOUTH);
boolean hardXNeg = isNeighborHardConnection(world, x - 1, y, z, blockXNeg, ForgeDirection.WEST);
boolean hardXPos = isNeighborHardConnection(world, x + 1, y, z, blockXPos, ForgeDirection.EAST);
boolean extYNeg = isNeighborExtConnection(world, x, y - 1, z, blockYNeg, ForgeDirection.DOWN);
boolean extYPos = isNeighborExtConnection(world, x, y + 1, z, blockYPos, ForgeDirection.UP);
boolean extZNeg = isNeighborExtConnection(world, x, y, z - 1, blockZNeg, ForgeDirection.NORTH);
boolean extZPos = isNeighborExtConnection(world, x, y, z + 1, blockZPos, ForgeDirection.SOUTH);
boolean extXNeg = isNeighborExtConnection(world, x - 1, y, z, blockXNeg, ForgeDirection.WEST);
boolean extXPos = isNeighborExtConnection(world, x + 1, y, z, blockXPos, ForgeDirection.EAST);
return (hardYNeg ? 1 : 0) | (hardYPos ? 2 : 0) | (hardZNeg ? 4 : 0) | (hardZPos ? 8 : 0) | (hardXNeg ? 16 : 0) | (hardXPos ? 32 : 0)
| (extYNeg ? 64 : 0) | (extYPos ? 128 : 0) | (extZNeg ? 256 : 0) | (extZPos ? 512 : 0) | (extXNeg ? 1024 : 0) | (extXPos ? 2048 : 0);
}
private boolean isNeighborHardConnection (IBlockAccess world, int x, int y, int z, Block block, ForgeDirection side) {
if (block.getMaterial().isOpaque() && block.renderAsNormalBlock())
return true;
if (block.isSideSolid(world, x, y, z, side.getOpposite()))
return true;
if (block == this)
return true;
if (side == ForgeDirection.DOWN || side == ForgeDirection.UP) {
if (block instanceof BlockFence || block instanceof net.minecraft.block.BlockFence)
return true;
}
return false;
}
private boolean isNeighborExtConnection (IBlockAccess world, int x, int y, int z, Block block, ForgeDirection side) {
if (block instanceof BlockThinLog)
return true;
return false;
}
protected TileEntityLattice getTileEntity (IBlockAccess blockAccess, int x, int y, int z) {
TileEntity te = blockAccess.getTileEntity(x, y, z);
if (te != null && te instanceof TileEntityLattice)
return (TileEntityLattice) te;
return null;
}
private final Vec3[] attachPoints = new Vec3[] {
Vec3.createVectorHelper(.5, .5, .5),
Vec3.createVectorHelper(.5, .5, .5),
Vec3.createVectorHelper(.5, .5, .5),
Vec3.createVectorHelper(.5, .5, .5),
Vec3.createVectorHelper(.5, .5, .5),
Vec3.createVectorHelper(.5, .5, .5),
};
@Override
public Vec3 getChainAttachPoint (IBlockAccess blockAccess, int x, int y, int z, int side) {
int connectFlags = calcConnectionFlags(blockAccess, x, y, z);
switch (side) {
case 0: return (connectFlags & 1) == 0 ? attachPoints[0] : null;
case 1: return (connectFlags & 2) == 0 ? attachPoints[1] : null;
case 2: return (connectFlags & 4) == 0 ? attachPoints[2] : null;
case 3: return (connectFlags & 8) == 0 ? attachPoints[3] : null;
case 4: return (connectFlags & 16) == 0 ? attachPoints[4] : null;
case 5: return (connectFlags & 32) == 0 ? attachPoints[5] : null;
}
return null;
}
}