package universalteam.universalcore.block;
import com.google.common.collect.Lists;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IIconRegister;
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.IIcon;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import universalteam.universalcore.client.render.block.BlockAdvancedRenderingHandler;
import universalteam.universalcore.tile.TileAdvanced;
import universalteam.universalcore.tile.implement.IActivateAware;
import universalteam.universalcore.tile.implement.IBreakAware;
import universalteam.universalcore.tile.implement.IClickAware;
import universalteam.universalcore.tile.implement.IHasDrops;
import universalteam.universalcore.tile.implement.IHasGUI;
import universalteam.universalcore.tile.implement.INeighbourChangeAware;
import universalteam.universalcore.tile.implement.IPlaceAware;
import universalteam.universalcore.utils.RotationUtil;
import java.util.ArrayList;
import java.util.List;
abstract public class BlockAdvanced extends Block
{
protected BlockRotation blockRotation = BlockRotation.NONE;
protected ForgeDirection inventoryRenderDirection = ForgeDirection.WEST;
protected Class<? extends TileEntity> tileClass = null;
protected String modID;
protected int guiID = -1;
protected String blockName;
public IIcon[] icons = new IIcon[6];
protected BlockAdvanced(Material material)
{
super(material);
this.tileClass = getAdvancedTile();
this.modID = getModID();
this.blockName = blockName;
}
protected BlockAdvanced setBlockRotation(BlockRotation blockRotation)
{
this.blockRotation = blockRotation;
return this;
}
protected BlockAdvanced setInventoryRenderDirection(ForgeDirection inventoryRenderDirection)
{
this.inventoryRenderDirection = inventoryRenderDirection;
return this;
}
protected BlockAdvanced setDefaultIcon(IIcon icon)
{
this.blockIcon = icon;
return this;
}
public BlockRotation getBlockRotation()
{
return blockRotation;
}
public ForgeDirection getInventoryRenderDirection()
{
return inventoryRenderDirection;
}
public abstract String getModID();
public abstract Object getModInstace();
public abstract String getBlockName();
public abstract Class<? extends TileAdvanced> getAdvancedTile();
@Override
public boolean hasTileEntity(int metadata)
{
return tileClass != null;
}
@Override
public TileEntity createTileEntity(World world, int meta)
{
return createTile();
}
public TileEntity getTileForRendering()
{
TileEntity tile = createTile();
tile.blockType = this;
tile.blockMetadata = 0;
return tile;
}
public TileEntity createTile()
{
if (tileClass == null)
return null;
try
{
return tileClass.newInstance();
}
catch (Exception e)
{
return null;
}
}
@Override
public void registerBlockIcons(IIconRegister register)
{
this.blockIcon = register.registerIcon(modID + ":" + blockName);
}
public void setIcon(IIcon icon, ForgeDirection... dirs)
{
for (ForgeDirection dir : dirs)
icons[dir.ordinal()] = icon;
}
public IIcon getUnmodifiedIcon(ForgeDirection dir)
{
if (dir != ForgeDirection.UNKNOWN)
if (icons[dir.ordinal()] != null)
return icons[dir.ordinal()];
return blockIcon;
}
public IIcon getUnmodifiedIcon(ForgeDirection dir, IBlockAccess world, int x, int y, int z)
{
return getUnmodifiedIcon(dir);
}
@Override
public IIcon getIcon(IBlockAccess world, int x, int y, int z, int side)
{
return getUnmodifiedIcon(rotateSideByMetadata(side, world.getBlockMetadata(x, y, z)), world, x, y, z);
}
@Override
public IIcon getIcon(int side, int meta)
{
return getUnmodifiedIcon(rotateSideByMetadata(side, meta));
}
@Override
public boolean renderAsNormalBlock()
{
return isOpaqueCube();
}
@Override
public int getRenderType()
{
return rotateSideIcons() ? BlockAdvancedRenderingHandler.RENDER_ID : 0;
}
@Override
public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase entity, ItemStack stack)
{
int meta;
switch (blockRotation)
{
case FOUR_DIRECTIONS:
meta = RotationUtil.get4SidedOrientation(entity).ordinal();
break;
case SIX_DIRECTIONS:
meta = RotationUtil.get6SidedOrientation(entity).ordinal();
break;
default:
meta = 0;
}
world.setBlockMetadataWithNotify(x, y, z, meta, 3);
TileAdvanced tile = getTile(world, x, y, z);
if (tile instanceof IPlaceAware)
((IPlaceAware) tile).onPlace(entity, stack);
}
@Override
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ)
{
TileAdvanced tile = getTile(world, x, y, z);
if (tile instanceof IHasGUI && ((IHasGUI) tile).canPlayerOpenGUI(player, side, hitX, hitY, hitZ) && !world.isRemote)
openGUI(player, world, x, y, z);
if (tile instanceof IActivateAware)
return ((IActivateAware) tile).onActivate(player, side, hitX, hitY, hitZ);
return false;
}
@Override
public void onBlockClicked(World world, int x, int y, int z, EntityPlayer player)
{
TileAdvanced tile = getTile(world, x, y, z);
if (tile instanceof IClickAware)
((IClickAware) tile).onClicked(player);
}
@Override
public void onNeighborBlockChange(World world, int x, int y, int z, Block block)
{
TileAdvanced tile = getTile(world, x, y, z);
if (tile instanceof INeighbourChangeAware)
((INeighbourChangeAware) tile).onNeigbourChange(block);
}
@Override
public void breakBlock(World world, int x, int y, int z, Block block, int meta)
{
TileAdvanced tile = getTile(world, x, y, z);
if (tile instanceof IBreakAware)
((IBreakAware) tile).onBreak();
world.removeTileEntity(x, y, z);
super.breakBlock(world, x, y, z, block, meta);
}
@Override
public boolean removedByPlayer(World world, EntityPlayer player, int x, int y, int z)
{
if (!player.capabilities.isCreativeMode)
{
TileAdvanced tile = getTile(world, x, y, z);
List<ItemStack> drops = Lists.newArrayList();
for (ItemStack drop : drops)
dropBlockAsItem(world, x, y, z, drop);
}
return super.removedByPlayer(world, player, x, y, z);
}
@Override
public ArrayList<ItemStack> getDrops(World world, int x, int y, int z, int meta, int fortune)
{
ArrayList<ItemStack> drops = Lists.newArrayList();
drops.addAll(super.getDrops(world, x, y, z, meta, fortune));
TileAdvanced tile = getTile(world, x, y, z);
if (tile instanceof IHasDrops)
((IHasDrops) tile).addDrops(drops, fortune);
return drops;
}
public void getTileDrops(TileAdvanced tile, List<ItemStack> drops, int fortune)
{
if (tile instanceof IHasDrops)
((IHasDrops) tile).addDrops(drops, fortune);
}
public void openGUI(EntityPlayer player, World world, int x, int y, int z)
{
if (guiID == -1)
return;
player.openGui(getModInstace(), guiID, world, x, y, z);
}
public boolean rotateSideIcons()
{
return false;
}
//Credits to OpenModsLib
public ForgeDirection rotateSideByMetadata(int side, int metadata)
{
ForgeDirection rotation = ForgeDirection.getOrientation(metadata);
ForgeDirection dir = ForgeDirection.getOrientation(side);
switch (getBlockRotation())
{
case FOUR_DIRECTIONS:
case NONE:
switch (rotation)
{
case EAST:
dir = dir.getRotation(ForgeDirection.DOWN);
break;
case SOUTH:
dir = dir.getRotation(ForgeDirection.UP);
dir = dir.getRotation(ForgeDirection.UP);
break;
case WEST:
dir = dir.getRotation(ForgeDirection.UP);
break;
default:
break;
}
return dir;
default:
switch (rotation)
{
case DOWN:
dir = dir.getRotation(ForgeDirection.SOUTH);
dir = dir.getRotation(ForgeDirection.SOUTH);
break;
case EAST:
dir = dir.getRotation(ForgeDirection.NORTH);
break;
case NORTH:
dir = dir.getRotation(ForgeDirection.WEST);
break;
case SOUTH:
dir = dir.getRotation(ForgeDirection.EAST);
break;
case WEST:
dir = dir.getRotation(ForgeDirection.SOUTH);
break;
default:
break;
}
}
return dir;
}
public <T> T getTile(World world, int x, int y, int z, Class<T> clazz)
{
TileAdvanced tile = getTile(world, x, y, z);
return !clazz.isInstance(tile) ? null : (T)tile;
}
public TileAdvanced getTile(World world, int x, int y, int z)
{
return (TileAdvanced) world.getTileEntity(x, y, z);
}
public enum BlockRotation
{
NONE(),
FOUR_DIRECTIONS(ForgeDirection.NORTH, ForgeDirection.EAST, ForgeDirection.SOUTH, ForgeDirection.WEST),
SIX_DIRECTIONS(ForgeDirection.VALID_DIRECTIONS);
private BlockRotation(ForgeDirection... directions)
{
this.directions = directions;
}
private ForgeDirection[] directions;
}
}