public class BlockAshroom extends BlockTBPlant {

	public BlockAshroom(int stages, int delay, boolean isCrop) {
		super(stages, delay, isCrop);
	}
	
	@Override
	public void grow(World worldIn, Random r, BlockPos pos, IBlockState state)
	{
		worldIn.setBlockState(pos, this.getStateFromMeta(Math.min(growthStages-1, BlockStateMetadata.getBlockMetadata(worldIn, pos)+1)));
	}
	
    public boolean canBlockStay(World worldIn, BlockPos pos, IBlockState state)
    {
        if (!this.canPlaceBlockAt(worldIn, pos.up()))
        {
        	this.dropBlockAsItem(worldIn, pos, state, 0);
        	worldIn.setBlockToAir(pos);
            return false;
        }
        
		return true;
    }

    @Override
    public List<ItemStack> getDrops(IBlockAccess world, BlockPos pos, IBlockState state, int fortune)
    {
    	if(world instanceof World)
    	{
	    	World w = World.class.cast(world);
	    	int metadata = BlockStateMetadata.getMetaFromState(state);
	    	if(metadata >= this.growthStages - 1)
	    	{
	    		for(int i = 0; i < 8 + w.rand.nextInt(32); ++i) //Nerf for the shrooms
	    		{
	    			Aspect primal = Aspect.getPrimalAspects().get(w.rand.nextInt(Aspect.getPrimalAspects().size()));
					EntityAspectOrb orb = new EntityAspectOrb(w, pos.getX(),pos.getY(),pos.getZ(), primal, 1);
					if(!w.isRemote)
						w.spawnEntityInWorld(orb);
	    		}
	    	}
    	}
        return super.getDrops(world, pos, state, fortune);
    }
} public class BlockAuraLinker extends BlockContainer implements IOldCubicBlock{
	
	public BlockAuraLinker()
	{
		super(Material.rock);
	}
	
    public boolean isOpaqueCube()
    {
        return false;
    }
    
	public int getRenderType()
	{
		return 3;
	}
	
	@Override
	public TileEntity createNewTileEntity(World w, int meta) {
		return new TileAuraLinker();
	}

	@Override
	public Icon getIcon(int side, int meta) {
		return Icon.fromBlock(BlocksTC.stone);
	}

	@Override
	public Icon getIcon(IBlockAccess world, int x, int y, int z, int side) {
		return Icon.fromBlock(BlocksTC.stone);
	}

	@Override
	public List<IBlockState> listPossibleStates(Block b) {
		return Arrays.asList(getDefaultState());
	}

	@Override
	public void registerBlockIcons(IconRegister ir) {
	}

	@Override
	public int getDCRenderID() {
		return RenderAccessLibrary.RENDER_ID_NONE;
	}
} public class BlockAureliaLeaf extends Block implements IOldCubicBlock{

	Icon icon;
	String texture;
	
	public BlockAureliaLeaf() 
	{
		super(Material.plants);
		this.setBlockBounds(0.25F, 0, 0.25F, 0.75F, 0.25F, 0.75F);
		this.setLightLevel(0.3F);
	}
	
	public BlockAureliaLeaf setBlockName(String name)
	{
		this.setUnlocalizedName(name);
		return this;
	}

    public EnumWorldBlockLayer getBlockLayer()
    {
    	return EnumWorldBlockLayer.CUTOUT_MIPPED;
    }
    
	public BlockAureliaLeaf setBlockTextureName(String tex)
	{
		texture = tex;
		return this;
	}
	
    public int damageDropped(IBlockState state)
    {
    	return 5;
    }
    
    @Override
    public Item getItemDropped(IBlockState state, Random rnd, int fort)
    {
    	return TBItems.resource;
    }
    
    @Override
    public AxisAlignedBB getCollisionBoundingBox(World w, BlockPos pos,IBlockState state)
    {
        return null;
    }

    public boolean isOpaqueCube()
    {
        return false;
    }

	@Override
	public Icon getIcon(int side, int meta) {
		return icon;
	}

	@Override
	public Icon getIcon(IBlockAccess world, int x, int y, int z, int side) {
		return getIcon(side,this.getMetaFromState(world.getBlockState(new BlockPos(x,y,z))));
	}

	@Override
	public List<IBlockState> listPossibleStates(Block b) {
		return Arrays.asList(this.getDefaultState());
	}

	@Override
	public void registerBlockIcons(IconRegister ir) {
		icon = ir.registerBlockIcon(texture);
	}

	@Override
	public int getDCRenderID() {
		return RenderAccessLibrary.RENDER_ID_CROSSES;
	}

} public class BlockAureliaPlant extends Block implements IOldCubicBlock{

	String textureName;
	
	public BlockAureliaPlant() 
	{
		super(Material.plants);
		this.setTickRandomly(true);
		this.setBlockBounds(0.25F, 0, 0.25F, 0.75F, 0.85F, 0.75F);
		this.setLightLevel(0.5F);
	}
	
	public BlockAureliaPlant setBlockName(String name)
	{
		this.setUnlocalizedName(name);
		return this;
	}

    public EnumWorldBlockLayer getBlockLayer()
    {
    	return EnumWorldBlockLayer.CUTOUT_MIPPED;
    }
    
	public BlockAureliaPlant setBlockTextureName(String tex)
	{
		textureName = tex;
		return this;
	}
	
	public static Icon[] icons = new Icon[2];
	
    public void registerBlockIcons(IconRegister reg)
    {
    	icons[0] = reg.registerBlockIcon(textureName+"closed");
    	icons[1] = reg.registerBlockIcon(textureName+"open");
    }
    
    @SideOnly(Side.CLIENT)
    public Icon getIcon(int side, int meta)
    {
    	return icons[meta];
    }
	
    public void updateTick(World w, BlockPos pos, IBlockState state, Random rnd)
	{
		checkForMoonlight(w,pos);
		if(BlockStateMetadata.getMetaFromState(state) == 1)
		{
			int rndX = pos.getX() + rnd.nextInt(8) - rnd.nextInt(8);
			int rndZ = pos.getZ() + rnd.nextInt(8) - rnd.nextInt(8);
			int rndY = findSutableGround(w,rndX,pos.getY()+2,rndZ)+1;
			if(rndY > 2)
				w.setBlockState(new BlockPos(rndX, rndY, rndZ), TBBlocks.aureliaPetal.getDefaultState());
		}
	}
	
	public int findSutableGround(World w, int x, int y, int z)
	{
		while(w.isAirBlock(new BlockPos(x,y,z)) && y > 0 && !w.isSideSolid(new BlockPos(x, y, z), EnumFacing.UP))
			--y;
		
		return y;
	}
	
    public int tickRate(World w)
    {
    	return 10;
    }
	
	public void onNeighborBlockChange(World worldIn, BlockPos pos, IBlockState state, Block neighborBlock)
	{
		if(!canGrowOn(worldIn,pos.down()))
			worldIn.setBlockToAir(pos);
		else
			checkForMoonlight(worldIn,pos);
		
	}
	
    public int damageDropped(int meta)
    {
    	return 0;
    }
    
    @Override
    public AxisAlignedBB getCollisionBoundingBox(World w, BlockPos pos,IBlockState state)
    {
        return null;
    }

    public boolean isOpaqueCube()
    {
        return false;
    }

    public boolean renderAsNormalBlock()
    {
        return false;
    }
    
	public void checkForMoonlight(World w, BlockPos pos)
	{
		boolean underSky = w.canBlockSeeSky(pos.up());
		boolean night = !w.isDaytime();
		boolean isFullMoon = w.provider.getMoonPhase(w.getWorldTime()) == 0;
		boolean isOpen = BlockStateMetadata.getBlockMetadata(w, pos) == 1;
		
		if(underSky && night && isFullMoon)
		{
			if(!isOpen)
			{
				w.setBlockState(pos, getStateFromMeta(1));
				w.markBlockRangeForRenderUpdate(pos.down().west().north(), pos.up().east().south());
			}
		}else
		{
			if(isOpen)
			{
				w.setBlockState(pos, getStateFromMeta(0));
				w.markBlockRangeForRenderUpdate(pos.down().west().north(), pos.up().east().south());
			}
		}
	}

	public static boolean canGrowOn(World w, BlockPos pos)
	{
		return !w.isAirBlock(pos) && (w.getBlockState(pos).getBlock().isReplaceableOreGen(w, pos,BlockHelper.forBlock(Blocks.grass)) || w.getBlockState(pos).getBlock().isReplaceableOreGen(w, pos, BlockHelper.forBlock(Blocks.dirt)));
	}

	@Override
	public Icon getIcon(IBlockAccess world, int x, int y, int z, int side) {
		return this.getIcon(side, BlockStateMetadata.getBlockMetadata(world, x, y, z));
	}
	
    public IBlockState getStateFromMeta(int meta)
    {
    	return this.getDefaultState().withProperty(BlockStateMetadata.METADATA, meta);
    }
    
    public int getMetaFromState(IBlockState state)
    {
    	return BlockStateMetadata.getMetaFromState(state);
    }

    protected BlockState createBlockState()
    {
    	return new BlockState(this,BlockStateMetadata.METADATA);
    }

	@Override
	public List<IBlockState> listPossibleStates(Block b) {
		return Arrays.asList(getStateFromMeta(0),getStateFromMeta(1));
	}

	@Override
	public int getDCRenderID() {
		return RenderAccessLibrary.RENDER_ID_CROSSES;
	}
} public class BlockBraizer extends BlockContainer implements IOldCubicBlock
{

	public BlockBraizer()
	{
		super(Material.rock);
		setHardness(1F);
		setResistance(1F);
	}

	@Override
	public TileEntity createNewTileEntity(World w, int meta) 
	{
		return new TileBraizer();
	}
	
    public boolean isOpaqueCube()
    {
        return false;
    }
	
	public int getRenderType()
	{
		return 3;
	}
	
    public IBlockState getStateFromMeta(int meta)
    {
    	return this.getDefaultState().withProperty(BlockStateMetadata.METADATA, meta);
    }
    
    public int getMetaFromState(IBlockState state)
    {
    	return BlockStateMetadata.getMetaFromState(state);
    }

    protected BlockState createBlockState()
    {
    	return new BlockState(this,BlockStateMetadata.METADATA);
    }
    
    public EnumWorldBlockLayer getBlockLayer()
    {
    	return EnumWorldBlockLayer.CUTOUT_MIPPED;
    }

    public void randomDisplayTick(World w, BlockPos pos, IBlockState state, Random r)
    {
    	if(BlockStateMetadata.getMetaFromState(state) > 0)
    	{
    		int x = pos.getX();
    		int y = pos.getY();
    		int z = pos.getZ();
    		
    		w.spawnParticle(EnumParticleTypes.FLAME, x+0.5D+MathUtils.randomDouble(r)/4, y+0.6D, z+0.5D+MathUtils.randomDouble(r)/4, 0, 0.04D, 0);
    		for(int i = 0; i < 2; ++i)
    			w.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, x+0.5D+MathUtils.randomDouble(r)/4, y+0.7D, z+0.5D+MathUtils.randomDouble(r)/4, 0, r.nextDouble()/20, 0);
    		
    		w.playSound(x+0.5D, y+0.5D, z+0.5D, "thaumicbases:fire.loop", 0.1F, 0.1F, false);
    	}
    }
    
	@Override
	public Icon getIcon(int side, int meta) {
		return Icon.fromBlock(BlocksTC.stone);
	}

	@Override
	public Icon getIcon(IBlockAccess world, int x, int y, int z, int side) {
		return Icon.fromBlock(BlocksTC.stone);
	}

	@Override
	public List<IBlockState> listPossibleStates(Block b) {
		return Arrays.asList(this.getStateFromMeta(0),this.getStateFromMeta(1));
	}

	@Override
	public void registerBlockIcons(IconRegister ir) {
	}

	@Override
	public int getDCRenderID() {
		return 0x1242fd;
	}
} public class BlockBriar extends BlockBush implements IGrowable,IOldCubicBlock{
    private Icon[] doublePlantBottomIcons;
    private Icon[] doublePlantTopIcons;
    public int growthStages;
    public int growthDelay;
    
    String textureName;
    
    public BlockBriar(int stages, int g)
    {
        super(Material.plants);
        this.setHardness(0.0F);
        this.setStepSound(soundTypeGrass);
        growthStages = stages;
        growthDelay = g;
    }
    
	public BlockBriar setBlockName(String name)
	{
		this.setUnlocalizedName(name);
		return this;
	}

    public EnumWorldBlockLayer getBlockLayer()
    {
    	return EnumWorldBlockLayer.CUTOUT_MIPPED;
    }
    
	public BlockBriar setBlockTextureName(String tex)
	{
		textureName = tex;
		return this;
	}
	
    public IBlockState getStateFromMeta(int meta)
    {
    	return this.getDefaultState().withProperty(BlockStateMetadata.METADATA, meta);
    }
    
    public int getMetaFromState(IBlockState state)
    {
    	return BlockStateMetadata.getMetaFromState(state);
    }

    protected BlockState createBlockState()
    {
    	return new BlockState(this,BlockStateMetadata.METADATA);
    }

    
    public void updateTick(World w, BlockPos pos, IBlockState state, Random rnd)
    {
    	super.updateTick(w, pos, state, rnd);
    	
    	if(w.getBlockState(pos).getBlock()==this)
    	{
    		int meta = BlockStateMetadata.getMetaFromState(state);
    		if(isTopBlock(meta))
    		{
    			if(meta-8 < growthStages-1 && w.rand.nextInt(growthDelay) == 0)
    			{
    				w.setBlockState(pos, this.getStateFromMeta(meta+1));
    				w.setBlockState(pos.down(), this.getStateFromMeta(meta-7));
    			}
    		}else
    		{
    			if(meta < growthStages-1 && w.rand.nextInt(growthDelay) == 0)
    			{
    				w.setBlockState(pos, this.getStateFromMeta(meta+1));
    				w.setBlockState(pos.up(), this.getStateFromMeta(meta+9));
    			}
    		}
    	}
    }
    
    public void setBlockBoundsBasedOnState(IBlockAccess w, int x, int y, int z)
    {
        this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
    }
    
    public boolean canPlaceBlockAt(World w, BlockPos pos)
    {
        return super.canPlaceBlockAt(w, pos) && w.isAirBlock(pos.up());
    }
    
    protected void checkAndDropBlock(World worldIn, BlockPos pos, IBlockState state)
    {
    	int meta = BlockStateMetadata.getMetaFromState(state);
    	if(isTopBlock(meta))
    	{
    		if(worldIn.getBlockState(pos.down()).getBlock() != this)
    		{
    			dropBlockAsItem(worldIn, pos, state, 0);
    			worldIn.setBlockToAir(pos);
    		}
    	}else
    	{
    		if(worldIn.getBlockState(pos.up()).getBlock() != this)
    		{
    			dropBlockAsItem(worldIn, pos, state, 0);
    			worldIn.setBlockToAir(pos);
    			return;
    		}
    		if(!canBlockStay(worldIn, pos, state))
    		{
    			dropBlockAsItem(worldIn, pos.up(), state, 0);
    			worldIn.setBlockToAir(pos.up());
    			dropBlockAsItem(worldIn, pos, state, 0);
    			worldIn.setBlockToAir(pos);
    		}
    	}
    }
    
    @Override
    public List<ItemStack> getDrops(IBlockAccess w, BlockPos pos, IBlockState state, int fortune)
    {
    	if(w instanceof World)
    	{
	    	World world = World.class.cast(w);
	    	int metadata = BlockStateMetadata.getMetaFromState(state);
	    	ArrayList<ItemStack> ret = new ArrayList<ItemStack>();
	    	
	    	if(!isTopBlock(metadata))
	    	{
	    		ret.add(new ItemStack(this,1,0));
	    		return ret;
	    	}
	    	
			metadata -= 8;
			if(metadata >= this.growthStages - 1)
			{
				ret.add(new ItemStack(TBItems.resource,1+world.rand.nextInt(4),6));
				return ret;
			}
			return ret;
    	}
    	return super.getDrops(w, pos, state, fortune);
    }
    
	@Override
    public boolean canBlockStay(World w, BlockPos pos, IBlockState state)
    {
    	return !w.isAirBlock(pos) && (w.getBlockState(pos.down()).getBlock().isReplaceableOreGen(w, pos.down(), BlockHelper.forBlock(Blocks.grass)) || w.getBlockState(pos.down()).getBlock().isReplaceableOreGen(w, pos.down(), BlockHelper.forBlock(Blocks.dirt)) || w.getBlockState(pos.down()).getBlock().canSustainPlant(w, pos.down(), EnumFacing.UP, this));
    }
    
    public boolean isTopBlock(int meta)
    {
    	return meta > 7;
    }
    
    public void onBlockPlacedBy(World worldIn, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack)
    {
    	worldIn.setBlockState(pos.up(), this.getStateFromMeta(8));
    }
    
    public void registerBlockIcons(IconRegister reg)
    {
    	doublePlantBottomIcons = new Icon[growthStages];
    	doublePlantTopIcons = new Icon[growthStages];
    	
    	for(int i = 0; i < growthStages; ++i)
    	{
    		doublePlantBottomIcons[i] = reg.registerBlockIcon(textureName+"stage_"+i+"_bot");
    		doublePlantTopIcons[i] = reg.registerBlockIcon(textureName+"stage_"+i+"_top");
    	}
    }
    
    @Override
    public Icon getIcon(int side, int meta)
    {
    	return isTopBlock(meta) ? doublePlantTopIcons[meta-8] : doublePlantBottomIcons[meta];
    }

	@Override
	public Icon getIcon(IBlockAccess world, int x, int y, int z, int side) {
		return getIcon(side,BlockStateMetadata.getBlockMetadata(world, x, y, z));
	}

	@Override
	public List<IBlockState> listPossibleStates(Block b) {
		ArrayList<IBlockState> retLst = new ArrayList<IBlockState>();
		for(int i = 0; i < growthStages; ++i)
		{
			retLst.add(getStateFromMeta(i));
			retLst.add(getStateFromMeta(i+8));
		}
		return retLst;
	}

	@Override
	public int getDCRenderID() {
		return RenderAccessLibrary.RENDER_ID_CROPS;
	}

	@Override
	public boolean canGrow(World worldIn, BlockPos pos, IBlockState state, boolean isClient) {
		return worldIn.getLight(pos.up()) >= 9;
	}

	@Override
	public boolean canUseBonemeal(World worldIn, Random rand, BlockPos pos, IBlockState state) {
		return BlockStateMetadata.getMetaFromState(state) % 8 < growthStages-1;
	}

	@Override
	public void grow(World w, Random rand, BlockPos pos, IBlockState state) {
    	if(w.getBlockState(pos).getBlock()==this)
    	{
    		int meta = BlockStateMetadata.getMetaFromState(state);
    		if(isTopBlock(meta))
    		{
    			if(meta-8 < growthStages-1 && w.rand.nextInt(growthDelay) == 0)
    			{
    				w.setBlockState(pos, this.getStateFromMeta(meta+1));
    				w.setBlockState(pos.down(), this.getStateFromMeta(meta-7));
    			}
    		}else
    		{
    			if(meta < growthStages-1 && w.rand.nextInt(growthDelay) == 0)
    			{
    				w.setBlockState(pos, this.getStateFromMeta(meta+1));
    				w.setBlockState(pos.up(), this.getStateFromMeta(meta+9));
    			}
    		}
    	}
	}
} public class BlockCampfire extends BlockContainer implements IOldCubicBlock
{

	public BlockCampfire()
	{
		super(Material.wood);
		setHardness(1F);
		setResistance(1F);
		setStepSound(soundTypeWood);
	}

	@Override
	public TileEntity createNewTileEntity(World w, int meta) 
	{
		return new TileCampfire();
	}
	
    public boolean isOpaqueCube()
    {
        return false;
    }
	
	public int getRenderType()
	{
		return 3;
	}
	
    public IBlockState getStateFromMeta(int meta)
    {
    	return this.getDefaultState().withProperty(BlockStateMetadata.METADATA, meta);
    }
    
    public int getMetaFromState(IBlockState state)
    {
    	return BlockStateMetadata.getMetaFromState(state);
    }

    protected BlockState createBlockState()
    {
    	return new BlockState(this,BlockStateMetadata.METADATA);
    }
    
    public EnumWorldBlockLayer getBlockLayer()
    {
    	return EnumWorldBlockLayer.CUTOUT_MIPPED;
    }

    public void randomDisplayTick(World w, BlockPos pos, IBlockState state, Random r)
    {
    	if(BlockStateMetadata.getMetaFromState(state) > 1)
    	{
    		int x = pos.getX();
    		int y = pos.getY();
    		int z = pos.getZ();
    		TileCampfire tc = (TileCampfire) w.getTileEntity(pos);
    		if(tc.tainted)
    			Thaumcraft.proxy.getFX().drawPollutionParticles(pos);
    		
    		w.spawnParticle(EnumParticleTypes.FLAME, x+0.5D+MathUtils.randomDouble(r)/4, y, z+0.5D+MathUtils.randomDouble(r)/4, 0, 0.04D, 0);
    		for(int i = 0; i < 10; ++i)
    			w.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, x+0.5D+MathUtils.randomDouble(r)/4, y+0.1D, z+0.5D+MathUtils.randomDouble(r)/4, 0, r.nextDouble()/20, 0);
    		
    		w.playSound(x+0.5D, y+0.5D, z+0.5D, "thaumicbases:fire.loop", 0.1F, 0.1F, false);
    	}
    }
    
    public boolean onBlockActivated(World w, BlockPos pos, IBlockState state, EntityPlayer p, EnumFacing side, float hitX, float hitY, float hitZ)
    {
    	if(w.isRemote)
    		return true;
    	
    	TileCampfire fire = (TileCampfire) w.getTileEntity(pos);
    	ItemStack stk = p.getCurrentEquippedItem();
    	boolean added = fire.addLog(stk);
    	if(!added)
    		added = fire.addFuel(stk);
    	
    	if(added)
    	{
    		p.inventory.decrStackSize(p.inventory.currentItem, 1);
    		if(p.openContainer != null)
    			p.openContainer.detectAndSendChanges();
    		p.inventory.markDirty();
    		return true;
    	}
    	
    	return false;
    }
    
    Icon icon;
    String textureName;

	public BlockCampfire setBlockTextureName(String tex)
	{
		textureName = tex;
		return this;
	}
    
	@Override
	public Icon getIcon(int side, int meta) {
		return icon;
	}

	@Override
	public Icon getIcon(IBlockAccess world, int x, int y, int z, int side) {
		return icon;
	}

	@Override
	public List<IBlockState> listPossibleStates(Block b) {
		return Arrays.asList(this.getStateFromMeta(0),this.getStateFromMeta(1),this.getStateFromMeta(2));
	}

	@Override
	public void registerBlockIcons(IconRegister ir) {
		icon = ir.registerBlockIcon(textureName);
	}

	@Override
	public int getDCRenderID() {
		return 0x1242fe;
	}
} public class BlockCryingObelisk extends Block implements IOldCubicBlock{

	public Icon topbotIcon;
	public Icon genericIcon;
	public Icon topSide;
	public Icon botSide;
	String texture;
	
	public BlockCryingObelisk() 
	{
		super(Material.rock);
	}
	
	public BlockCryingObelisk setBlockName(String name)
	{
		this.setUnlocalizedName(name);
		return this;
	}
    
	public BlockCryingObelisk setBlockTextureName(String tex)
	{
		texture = tex;
		return this;
	}
	
	public String getTextureName()
	{
		return texture;
	}
	
    public Icon getIcon(IBlockAccess w, int x, int y, int z, int side)
    {
    	if(w.getBlockState(new BlockPos(x,y+1,z)).getBlock() == this && w.getBlockState(new BlockPos(x,y+2,z)).getBlock() != this && w.getBlockState(new BlockPos(x,y-1,z)).getBlock() != this)
    		return side == 0 || side == 1 ? topbotIcon : botSide;
    	
    	if(w.getBlockState(new BlockPos(x,y-1,z)).getBlock() == this && w.getBlockState(new BlockPos(x,y-2,z)).getBlock() != this && w.getBlockState(new BlockPos(x,y+1,z)).getBlock() != this)
    		return side == 0 || side == 1 ? topbotIcon : topSide;
    	
    	return genericIcon;
    }
    
    public Icon getIcon(int side, int metadata)
    {
    	return genericIcon;
    }

    public void randomDisplayTick(World w, BlockPos pos, IBlockState state, Random rnd)
    {
    	if((w.getBlockState(pos.up()).getBlock() == this && w.getBlockState(pos.up().up()).getBlock() != this && w.getBlockState(pos.down()).getBlock() != this) || (w.getBlockState(pos.down()).getBlock() == this && w.getBlockState(pos.down().down()).getBlock() != this && w.getBlockState(pos.up()).getBlock() != this))
    	{
    		int x = pos.getX();
    		int y = pos.getY();
    		int z = pos.getZ();
    		for(int i = 0; i < 10; ++i)
    		{
    			double rndY = rnd.nextDouble()*3;
    			w.spawnParticle(EnumParticleTypes.PORTAL, x+0.5D+MathUtils.randomDouble(rnd), y-3+rndY, z+0.5D+MathUtils.randomDouble(rnd), 0, rndY, 0);
    		}
    	}
    }
    
    public boolean isBed(IBlockAccess world, BlockPos pos, Entity player)
    {
    	return ((world.getBlockState(pos.up()).getBlock() == this && world.getBlockState(pos.up(2)).getBlock() != this && world.getBlockState(pos.down()).getBlock() != this) || (world.getBlockState(pos.down()).getBlock() == this && world.getBlockState(pos.down(2)).getBlock() != this && world.getBlockState(pos.up()).getBlock() != this));
    }
    
    public boolean onBlockActivated(World w, BlockPos pos, IBlockState state, EntityPlayer p, EnumFacing side, float hitX, float hitY, float hitZ)
    {
    	if((w.getBlockState(pos.up()).getBlock() == this && w.getBlockState(pos.up(2)).getBlock() != this && w.getBlockState(pos.down()).getBlock() != this) || (w.getBlockState(pos.down()).getBlock() == this && w.getBlockState(pos.down(2)).getBlock() != this && w.getBlockState(pos.up()).getBlock() != this))
    	{
    		int x = pos.getX();
    		int y = pos.getY();
    		int z = pos.getZ();
    		w.playSound(x+0.5D, y+0.5D, z+0.5D, "portal.travel", 1, 2, false);
    		p.setSpawnChunk(new BlockPos(x,y,z), false,p.dimension);
    		if(p.worldObj.isRemote)
    			p.addChatMessage(new ChatComponentText(StatCollector.translateToLocal("tb.txt.spawnSet")).setChatStyle(new ChatStyle().setItalic(true).setColor(EnumChatFormatting.AQUA)));
    		return true;
    	}
    	return false;
    }
    
    public BlockPos getBedSpawnPosition(IBlockAccess world, BlockPos pos, EntityPlayer player)
    {
    	int x = pos.getX();
    	int y = pos.getY();
    	int z = pos.getZ();
    	for(int dy = 0; dy > -3; --dy)
	    	for(int dx = -2; dx <= 2; ++dx)
	    	{
	        	for(int dz = -2; dz <= 2; ++dz)
	        	{
                    if (World.doesBlockHaveSolidTopSurface(world,new BlockPos(x+dx, y+dy, z+dz)) && !world.getBlockState(new BlockPos(x+dx, y+dy, z+dz)).getBlock().getMaterial().isOpaque() && !world.getBlockState(new BlockPos(x+dx, y+dy+1, z+dz)).getBlock().getMaterial().isOpaque())
                    {
                    	return new BlockPos(x+dx, y+dy+1,z+dz);
                    }
	        	}
	    	}
    	return BlockBed.getSafeExitLocation((World) world, pos, 9);
    }
    
    public void registerBlockIcons(IconRegister reg)
    {
    	genericIcon = reg.registerBlockIcon(this.getTextureName()+"cryingObsidian");
    	topbotIcon = reg.registerBlockIcon(this.getTextureName()+"cryingObelisk_TB");
    	topSide = reg.registerBlockIcon(this.getTextureName()+"cryingObelisk_sideT");
    	botSide = reg.registerBlockIcon(this.getTextureName()+"cryingObelisk_sideB");
    }

	@Override
	public List<IBlockState> listPossibleStates(Block b) {
		return Arrays.asList(this.getDefaultState());
	}

	@Override
	public int getDCRenderID() {
		return RenderAccessLibrary.RENDER_ID_CUBE;
	}

} public class BlockCrystalBlock extends Block implements IInfusionStabiliser, IOldCubicBlock{
	
	public static Icon[] icons = new Icon[8];
	public static final String[] names = new String[]{"air","fire","water","earth","order","entropy","mixed","tainted"};
	
	public BlockCrystalBlock()
	{
		super(Material.glass);
		setHardness(0.7F);
		setResistance(1.0F);
		setLightLevel(0.5F);
		setStepSound(new CustomStepSound("crystal", 1.0F, 1.0F));
		this.setDefaultState(BlockStateMetadata.createDefaultBlockState(this));
	}
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List)
	{
		for(int i = 0; i < 8; ++i)
			par3List.add(new ItemStack(par1,1,i));
	}
	
	public void registerBlockIcons(IconRegister ir)
	{
		for(int i = 0; i < 8; ++i)
			icons[i] = ir.registerBlockIcon("thaumicbases:crystal/"+names[i]);
	}
	
    public int damageDropped(IBlockState state)
    {
    	return BlockStateMetadata.getMetaFromState(state);
    }
    
    public IBlockState getStateFromMeta(int meta)
    {
    	return this.getDefaultState().withProperty(BlockStateMetadata.METADATA, meta);
    }
    
    public int getMetaFromState(IBlockState state)
    {
    	return BlockStateMetadata.getMetaFromState(state);
    }

    protected BlockState createBlockState()
    {
    	return new BlockState(this,BlockStateMetadata.METADATA);
    }

	@Override
	public boolean canStabaliseInfusion(World paramWorld, BlockPos paramBlockPos) {
		return true;
	}
	
    @SideOnly(Side.CLIENT)
    public Icon getIcon(int side, int meta)
    {
    	if(meta >= 8)
    		meta = 7;
    	return icons[meta];
    }

	@Override
	public Icon getIcon(IBlockAccess world, int x, int y, int z, int side) {
		return getIcon(side,BlockStateMetadata.getBlockMetadata(world, x, y, z));
	}

	@Override
	public List<IBlockState> listPossibleStates(Block b) {
		ArrayList<IBlockState> retLst = new ArrayList<IBlockState>();
		for(int i = 0; i < 8; ++i)
			retLst.add(getStateFromMeta(i));
		return retLst;
	}

	@Override
	public int getDCRenderID() {
		return RenderAccessLibrary.RENDER_ID_CUBE;
	}
	
} public class BlockCrystalSlab extends BlockTBSlab{

	public BlockCrystalSlab(boolean fullBlock, Material material) 
	{
		super(material, fullBlock);
		setHardness(0.7F);
		setResistance(1.0F);
		setLightLevel(0.5F);
		setStepSound(new CustomStepSound("crystal", 1.0F, 1.0F));
		this.isAStabiliser = true;
	}
	
    public Item getItemDropped(IBlockState state, Random rand, int fortune)
    {
        return Item.getItemFromBlock(TBBlocks.crystalSlab);
    }

    protected ItemStack createStackedBlock(IBlockState state)
    {
        return new ItemStack(Item.getItemFromBlock(TBBlocks.crystalSlab), 2, BlockStateMetadata.getMetaFromState(state) % 7);
    }
	
    @SideOnly(Side.CLIENT)
    public Item getItem(World worldIn, BlockPos pos)
    {
    	return Item.getItemFromBlock(TBBlocks.crystalSlab);
    }

	@Override
	public String getUnlocalizedName(int meta) {
		return super.getUnlocalizedName()+BlockCrystalBlock.names[meta & 7];
	}
	
    @SideOnly(Side.CLIENT)
    public Icon getIcon(int side, int meta)
    {
    	return IOldCubicBlock.class.cast(TBBlocks.crystalBlock).getIcon(side, meta & 7);
    }
	
    @SuppressWarnings({ "unchecked", "rawtypes" })
	@SideOnly(Side.CLIENT)
    public void getSubBlocks(Item itm, CreativeTabs tab, List lst)
    {
    	for(int i = 0; i < 8; ++i)
    	{
    		lst.add(new ItemStack(itm,1,i));
    	}
    }

	@Override
	public Icon getIcon(IBlockAccess world, int x, int y, int z, int side) {
		return this.getIcon(side, BlockStateMetadata.getBlockMetadata(world, x,y,z));
	}

	@Override
	public List<IBlockState> listPossibleStates(Block b) {
		ArrayList<IBlockState> retLst = new ArrayList<IBlockState>();
		for(int i = 0; i < 16; ++i)
			retLst.add(getStateFromMeta(i));
		return retLst;
	}

	@Override
	public void registerBlockIcons(IconRegister ir) {
		
	}

} public class BlockFlaxium extends BlockBush implements IOldCubicBlock{

	public BlockFlaxium() {
		super(Material.plants);
		this.setTickRandomly(true);
		this.setBlockBounds(0.25F, 0, 0.25F, 0.75F, 0.85F, 0.75F);
	}
	
	Icon icon;
	String texture;
	
	public BlockFlaxium setBlockName(String name)
	{
		this.setUnlocalizedName(name);
		return this;
	}

    public EnumWorldBlockLayer getBlockLayer()
    {
    	return EnumWorldBlockLayer.CUTOUT_MIPPED;
    }
    
	public BlockFlaxium setBlockTextureName(String tex)
	{
		texture = tex;
		return this;
	}
	
	@Override
	public Icon getIcon(int side, int meta) {
		return icon;
	}

	@Override
	public Icon getIcon(IBlockAccess world, int x, int y, int z, int side) {
		return getIcon(side,this.getMetaFromState(world.getBlockState(new BlockPos(x,y,z))));
	}

	@Override
	public List<IBlockState> listPossibleStates(Block b) {
		return Arrays.asList(this.getDefaultState());
	}
	
	@Override
	public void registerBlockIcons(IconRegister ir) {
		icon = ir.registerBlockIcon(texture);
	}

	@Override
	public int getDCRenderID() {
		return RenderAccessLibrary.RENDER_ID_CROSSES;
	}
	
	public void updateTick(World w, BlockPos pos, IBlockState state, Random rnd)
	{
		super.updateTick(w, pos, state, rnd);
		if(w.isAirBlock(pos.up()))
			AuraHelper.pollute(w, pos, 1, true);
		
		if(!canGrowOn(w,pos.down()))
			w.setBlockToAir(pos);
	}
	
	public void onNeighborBlockChange(World worldIn, BlockPos pos, IBlockState state, Block neighborBlock)
	{
		if(!canGrowOn(worldIn,pos.down()))
			worldIn.setBlockToAir(pos);
	}
	
    @Override
    public AxisAlignedBB getCollisionBoundingBox(World w, BlockPos pos,IBlockState state)
    {
        return null;
    }

    public boolean isOpaqueCube()
    {
        return false;
    }
    
	public static boolean canGrowOn(World w, BlockPos pos)
	{
		return !w.isAirBlock(pos) && (w.getBlockState(pos).getBlock().isReplaceableOreGen(w, pos,BlockHelper.forBlock(Blocks.grass)) || w.getBlockState(pos).getBlock().isReplaceableOreGen(w, pos, BlockHelper.forBlock(Blocks.dirt)));
	}

} public class BlockHalfSlab extends BlockTBSlab{
	
	public static Block[] parents = new Block[]{
		TBBlocks.eldritchArk,
		TBBlocks.oldBrick,
		TBBlocks.oldCobble,
		TBBlocks.oldCobbleMossy,
		TBBlocks.oldDiamond,
		TBBlocks.oldGold,
		TBBlocks.oldIron,
		TBBlocks.oldLapis
	};

	public BlockHalfSlab(boolean fullBlock, Material material) 
	{
		super(material, fullBlock);
	}
	
    public Item getItemDropped(IBlockState state, Random rand, int fortune)
    {
        return Item.getItemFromBlock(TBBlocks.genericSlab);
    }

    protected ItemStack createStackedBlock(IBlockState state)
    {
        return new ItemStack(Item.getItemFromBlock(TBBlocks.genericSlab), 2, BlockStateMetadata.getMetaFromState(state) & 7);
    }
	
    @SideOnly(Side.CLIENT)
    public Item getItem(World worldIn, BlockPos pos)
    {
    	return Item.getItemFromBlock(TBBlocks.genericSlab);
    }

	@Override
	public String getUnlocalizedName(int meta) {
		return super.getUnlocalizedName()+parents[meta].getUnlocalizedName();
	}
	
    @SideOnly(Side.CLIENT)
    public Icon getIcon(int side, int meta)
    {
    	return IOldCubicBlock.class.cast(parents[meta & 7]).getIcon(side, 0);
    }
	
    @SuppressWarnings({ "unchecked", "rawtypes" })
	@SideOnly(Side.CLIENT)
    public void getSubBlocks(Item itm, CreativeTabs tab, List lst)
    {
    	for(int i = 0; i < parents.length; ++i)
    	{
    		lst.add(new ItemStack(itm,1,i));
    	}
    }

	@Override
	public boolean canStabaliseInfusion(World world, BlockPos pos) {
		int meta = BlockStateMetadata.getBlockMetadata(world, pos) & 7;
		return parents[meta] instanceof IInfusionStabiliser ? IInfusionStabiliser.class.cast(parents[meta]).canStabaliseInfusion(world, pos) : false;
	}

	@Override
	public Icon getIcon(IBlockAccess world, int x, int y, int z, int side) {
		return this.getIcon(side, BlockStateMetadata.getBlockMetadata(world, x,y,z));
	}

	@Override
	public List<IBlockState> listPossibleStates(Block b) {
		ArrayList<IBlockState> retLst = new ArrayList<IBlockState>();
		for(int i = 0; i < 16; ++i)
			retLst.add(getStateFromMeta(i));
		return retLst;
	}

	@Override
	public void registerBlockIcons(IconRegister ir) {
		
	}

} public class BlockKnose extends BlockTBPlant {

	public BlockKnose(int stages, int delay, boolean isCrop) {
		super(stages, delay, isCrop);
	}
	
    public boolean canBlockStay(World w, BlockPos pos, IBlockState state)
    {
    	return !w.isAirBlock(pos) && canPlaceBlockOn(w.getBlockState(pos.down()).getBlock());
    }

    protected boolean canPlaceBlockOn(Block b)
    {
    	return b == TBBlocks.crystalBlock;
    }
    
    @Override
    public List<ItemStack> getDrops(IBlockAccess w, BlockPos pos, IBlockState state, int fortune)
    {
    	 ArrayList<ItemStack> ret = new ArrayList<ItemStack>();
    	 int metadata = BlockStateMetadata.getMetaFromState(state);
    	 
         if (metadata >= growthStages-1)
         {
        	 if(dropSeed != null)
        		 ret.add(dropSeed.copy());
        	 Block b = w.getBlockState(pos.down()).getBlock();
        	 if(b == TBBlocks.crystalBlock)
        	 {
        		 int md = BlockStateMetadata.getBlockMetadata(w, pos.down());
        		 ret.add(new ItemStack(TBItems.knoseFragment,1,md));
        	 }
         }else
         {
        	 if(dropSeed != null)
        		 ret.add(dropSeed.copy());
         }
    	 
    	 return ret;
    }
} public class BlockLucritePlant extends BlockTBPlant {

	public BlockLucritePlant(int stages, int delay, boolean isCrop) {
		super(stages, delay, isCrop);
	}
	
	@Override
	public void grow(World worldIn, Random r, BlockPos pos, IBlockState state)
	{
		int meta = BlockStateMetadata.getMetaFromState(state);
		worldIn.setBlockState(pos, this.getStateFromMeta(Math.min(growthStages,meta+1)));
	}

	@Override
    public boolean canBlockStay(World worldIn, BlockPos pos, IBlockState state)
    {
        return super.canBlockStay(worldIn,pos,state) && worldIn.getBlockState(pos.down(2)).getBlock() == TBBlocks.dustBlock;
    }
	
    @Override
    public List<ItemStack> getDrops(IBlockAccess world, BlockPos pos, IBlockState state, int fortune)
    {
        List<ItemStack> ret = super.getDrops(world, pos, state, fortune);

        if(world instanceof World)
        {
        	World w = World.class.cast(world);
        	int metadata = BlockStateMetadata.getMetaFromState(state);
	        if (metadata >= growthStages-1)
	            if (w.rand.nextInt(16) == 0)
	            	ret.add(new ItemStack(Items.golden_carrot,1,0));
        }
        
        return ret;
    }
} public class BlockNodeManipulator extends BlockContainer implements IOldCubicBlock{
	
	public BlockNodeManipulator()
	{
		super(Material.rock);
	}
	
    public boolean isOpaqueCube()
    {
        return false;
    }
    
	public int getRenderType()
	{
		return 3;
	}
	
    public IBlockState getStateFromMeta(int meta)
    {
    	return this.getDefaultState().withProperty(BlockStateMetadata.METADATA, meta);
    }
    
    public int getMetaFromState(IBlockState state)
    {
    	return BlockStateMetadata.getMetaFromState(state);
    }
    
    protected BlockState createBlockState()
    {
    	return new BlockState(this,BlockStateMetadata.METADATA);
    }
	
	@Override
	public TileEntity createNewTileEntity(World w, int meta) {
		return new TileNodeManipulator();
	}

	@Override
	public Icon getIcon(int side, int meta) {
		return Icon.fromBlock(BlocksTC.stone);
	}

	@Override
	public Icon getIcon(IBlockAccess world, int x, int y, int z, int side) {
		return Icon.fromBlock(BlocksTC.stone);
	}

	@Override
	public List<IBlockState> listPossibleStates(Block b) {
		return Arrays.asList(getStateFromMeta(0),getStateFromMeta(1),getStateFromMeta(2),getStateFromMeta(3),getStateFromMeta(4),getStateFromMeta(5),getStateFromMeta(6),getStateFromMeta(7),getStateFromMeta(8),getStateFromMeta(9),getStateFromMeta(10));
	}

	@Override
	public void registerBlockIcons(IconRegister ir) {
	}

	@Override
	public int getDCRenderID() {
		return RenderAccessLibrary.RENDER_ID_NONE;
	}
	
    public boolean onBlockActivated(World w, BlockPos pos, IBlockState state, EntityPlayer p, EnumFacing side, float hitX, float hitY, float hitZ)
    {
    	if(p.getCurrentEquippedItem() != null)
    	{
    		ItemStack current = p.getCurrentEquippedItem();
    		if(current.getItem() instanceof ItemNodeFoci)
    		{
    			if(BlockStateMetadata.getMetaFromState(state) != 0)
    			{
    				int meta = BlockStateMetadata.getMetaFromState(state);
    				ItemStack stk = new ItemStack(TBItems.nodeFoci,1,meta-1);
    				EntityItem itm = new EntityItem(w,pos.getX()+0.5D,pos.getY(),pos.getZ()+0.5D,stk);
    				if(!w.isRemote)
    					w.spawnEntityInWorld(itm);
    			}
    			w.setBlockState(pos, getStateFromMeta(current.getMetadata()+1));
    			p.destroyCurrentEquippedItem();
    			
    			return true;
    		}
    	}else
    	{
			if(BlockStateMetadata.getMetaFromState(state) != 0)
			{
				int meta = BlockStateMetadata.getMetaFromState(state);
				ItemStack stk = new ItemStack(TBItems.nodeFoci,1,meta-1);
				EntityItem itm = new EntityItem(w,pos.getX()+0.5D,pos.getY(),pos.getZ()+0.5D,stk);
				if(!w.isRemote)
					w.spawnEntityInWorld(itm);
			}
			w.setBlockState(pos, getStateFromMeta(0));
    	}
    	return true;
    }
    
    @Override
    public void breakBlock(World w, BlockPos pos, IBlockState state)
    {
    	int meta = BlockStateMetadata.getMetaFromState(state);
    	if(meta > 0) //Fix for the manipulator not dropping the foci.
    	{
    		ItemStack foci = new ItemStack(TBItems.nodeFoci,1,meta-1);
    		EntityItem itm = new EntityItem(w,pos.getX()+0.5D,pos.getY()+0.5D,pos.getZ()+0.5D,foci);
    		if(!w.isRemote)
    			w.spawnEntityInWorld(itm);
    	}
    	super.breakBlock(w, pos, state);
    }
} public class BlockOverchanter extends BlockContainer implements IOldCubicBlock{
	
	public Icon topIcon;
	public Icon botIcon;
	public Icon sideIcon;

	public BlockOverchanter() 
	{
		super(Material.rock);
		this.setHarvestLevel("pickaxe", 3);
        this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.75F, 1.0F);
        this.setLightOpacity(0);
	}
	
    public int getRenderType()
    {
        return 3;
    }
    
    public boolean isOpaqueCube()
    {
        return false;
    }
    
    public Icon getIcon(int side, int meta)
    {
    	return side == 0 ? botIcon : side == 1 ? topIcon : sideIcon;
    }
    
    public void registerBlockIcons(IconRegister reg)
    {
    	topIcon = reg.registerBlockIcon("thaumicbases:overchanter/top");
    	botIcon = reg.registerBlockIcon("thaumicbases:overchanter/bottom");
    	sideIcon = reg.registerBlockIcon("thaumicbases:overchanter/side");
    }

	@Override
	public TileEntity createNewTileEntity(World w, int meta) {
		return new TileOverchanter();
	}
	
    public boolean onBlockActivated(World w, BlockPos pos, IBlockState state, EntityPlayer p, EnumFacing side, float hitX, float hitY, float hitZ)
    {
    	if(!p.isSneaking())
    	{
    		if(!w.isRemote)
    		{
    			p.openGui(TBCore.instance, 0x421922, w, pos.getX(),pos.getY(),pos.getZ());
    			return true;
    		}
			return true;
    	}
    	return false;
    }

	@Override
	public Icon getIcon(IBlockAccess world, int x, int y, int z, int side) {
		return getIcon(side,0);
	}

	@Override
	public List<IBlockState> listPossibleStates(Block b) {
		return Arrays.asList(getDefaultState());
	}

	@Override
	public int getDCRenderID() {
		return RenderAccessLibrary.RENDER_ID_CUBE;
	}
} public class BlockPyrofluid extends Block implements IOldCubicBlock{
	
	public static Icon fluidIcon;
	public static Icon staticIcon;

	public BlockPyrofluid()
	{
		super(Material.rock);
        float f = 0.0F;
        float f1 = 0.0F;
        this.setBlockBounds(0.0F + f1, 0.0F + f, 0.0F + f1, 1.0F + f1, 1.0F + f, 1.0F + f1);
        this.setTickRandomly(true);
	}
	
	public void setBlockBoundsBasedOnState(IBlockAccess worldIn, BlockPos pos)
	{
		int meta = BlockStateMetadata.getBlockMetadata(worldIn, pos);
		double removed = 0;
		if(meta == 15)
			removed = 0.99D;
		else
			removed = 1-((8D - meta)/8D);
		
		if(removed < 0)
			removed = 0.95D;
		
		this.setBlockBounds(0, 0, 0, 1, (float) (1-removed), 1);
	}
	
    public IBlockState getStateFromMeta(int meta)
    {
    	return this.getDefaultState().withProperty(BlockStateMetadata.METADATA, meta);
    }
    
    public int getMetaFromState(IBlockState state)
    {
    	return BlockStateMetadata.getMetaFromState(state);
    }
    
    protected BlockState createBlockState()
    {
    	return new BlockState(this,BlockStateMetadata.METADATA);
    }
	
    @Override
    public boolean isPassable(IBlockAccess world, BlockPos pos)
    {
        return true;
    }
    
    public boolean isOpaqueCube()
    {
        return false;
    }
    
    @Override
    public AxisAlignedBB getCollisionBoundingBox(World world, BlockPos pos, IBlockState state)
    {
        return super.getCollisionBoundingBox(world, pos, state);
    }
    
    public void onEntityCollidedWithBlock(World worldIn, BlockPos pos, Entity entityIn) 
    {
    	entityIn.attackEntityFrom(DamageSource.lava, 5);
    	entityIn.setFire(10);
    }
    
    @Override
    public Item getItemDropped(IBlockState state, Random rand, int fortune)
    {
        return null;
    }
    
    @Override
    public boolean isFullCube()
    {
        return false;
    }
    
    @Override
    @SideOnly(Side.CLIENT)
    public EnumWorldBlockLayer getBlockLayer()
    {
        return EnumWorldBlockLayer.CUTOUT;
    }

    public int quantityDropped(Random par1Random)
    {
        return 0;
    }
    
    public int tickRate(World par1World)
    {
        return 5;
    }
    
    @SideOnly(Side.CLIENT)
    public void randomDisplayTick(World worldIn, BlockPos pos, IBlockState state, Random rand)
    {
        double d0 = pos.getX();
        double d1 = pos.getY();
        double d2 = pos.getZ();

        if (worldIn.getBlockState(pos.up()).getBlock().getMaterial() == Material.air && !worldIn.getBlockState(pos.up()).getBlock().isOpaqueCube())
        {
            if (rand.nextInt(100) == 0)
            {
                double d8 = d0 + rand.nextFloat();
                double d4 = d1 + this.maxY;
                double d6 = d2 + rand.nextFloat();
                worldIn.spawnParticle(EnumParticleTypes.LAVA, d8, d4, d6, 0.0D, 0.0D, 0.0D, new int[0]);
                worldIn.playSound(d8, d4, d6, "liquid.lavapop", 0.2F + rand.nextFloat() * 0.2F, 0.9F + rand.nextFloat() * 0.15F, false);
            }

            if (rand.nextInt(200) == 0)
            {
                worldIn.playSound(d0, d1, d2, "liquid.lava", 0.2F + rand.nextFloat() * 0.2F, 0.9F + rand.nextFloat() * 0.15F, false);
            }
        }

        if (rand.nextInt(10) == 0 && World.doesBlockHaveSolidTopSurface(worldIn, pos.down()))
        {
            Material material = worldIn.getBlockState(pos.down(2)).getBlock().getMaterial();

            if (!material.blocksMovement() && !material.isLiquid())
            {
                double d3 = d0 + rand.nextFloat();
                double d5 = d1 - 1.05D;
                double d7 = d2 + rand.nextFloat();

                if (this.blockMaterial == Material.water)
                {
                    worldIn.spawnParticle(EnumParticleTypes.DRIP_WATER, d3, d5, d7, 0.0D, 0.0D, 0.0D, new int[0]);
                }
                else
                {
                    worldIn.spawnParticle(EnumParticleTypes.DRIP_LAVA, d3, d5, d7, 0.0D, 0.0D, 0.0D, new int[0]);
                }
            }
        }
    }
    
    public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand)
    {
    	int meta = BlockStateMetadata.getMetaFromState(state) + 1;
    	if(meta > 15)
    		return;
    	
    	if(meta >= 8)
    		meta = 15;
    	
    	worldIn.setBlockState(pos, this.getStateFromMeta(meta));
    }
    
	public void registerBlockIcons(IconRegister ir)
	{
		fluidIcon = ir.registerBlockIcon("thaumicbases:blazingFluid/block");
		staticIcon = ir.registerBlockIcon("thaumicbases:blazingFluid/leftovers");
	}
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List)
	{
		for(int i = 0; i < 8; ++i)
			par3List.add(new ItemStack(par1,1,i));
		
		par3List.add(new ItemStack(par1,1,15));
	}
	
    @SideOnly(Side.CLIENT)
    public Icon getIcon(int side, int meta)
    {
    	return meta == 15 ? staticIcon : fluidIcon;
    }
    
    @Override
    public float getBlockHardness(World w, BlockPos pos)
    {
    	return BlockStateMetadata.getBlockMetadata(w, pos) == 15 ? 5 : -1;
    }
    
    public ArrayList<ItemStack> getDrops(IBlockAccess world, BlockPos pos, IBlockState state, int fortune)
    {
    	ArrayList<ItemStack> retLst = new ArrayList<ItemStack>();
    	
    	retLst.add(new ItemStack(Items.blaze_powder,TBConfig.minBlazePowderFromPyrofluid+RANDOM.nextInt(TBConfig.maxBlazePowderFromPyrofluid-TBConfig.minBlazePowderFromPyrofluid),0));
    	
    	return retLst;
    }

	@Override
	public Icon getIcon(IBlockAccess world, int x, int y, int z, int side) {
		return this.getIcon(side, BlockStateMetadata.getBlockMetadata(world, x,y,z));
	}

	@Override
	public List<IBlockState> listPossibleStates(Block b) {
		ArrayList<IBlockState> retLst = new ArrayList<IBlockState>();
		for(int i = 0; i < 9; ++i)
			retLst.add(getStateFromMeta(i));
		
		retLst.add(getStateFromMeta(15));
		
		return retLst;
	}

	@Override
	public int getDCRenderID() {
		return RenderAccessLibrary.RENDER_ID_CUBE;
	}
} public class BlockRainbowCactus extends BlockCactus implements IOldCubicBlock{

    public Icon top;
    public Icon bot;
    public Icon side;
    String texture;
	
	public BlockRainbowCactus()
	{
		super();
	}
	
	public BlockRainbowCactus setBlockName(String name)
	{
		this.setUnlocalizedName(name);
		return this;
	}
    
	public BlockRainbowCactus setBlockTextureName(String tex)
	{
		texture = tex;
		return this;
	}
	
	public String getTextureName()
	{
		return texture;
	}
	
	public void onEntityCollidedWithBlock(World worldIn, BlockPos pos, IBlockState state, Entity entityIn)
    {
        
    }
    
    @Override
    public List<ItemStack> getDrops(IBlockAccess w, BlockPos pos, IBlockState state, int fortune)
    {
        ArrayList<ItemStack> ret = new ArrayList<ItemStack>();
        if(w instanceof World)
        {
        	World world = World.class.cast(w);
	        if(world.getBlockState(pos.down()).getBlock() != this)
	        {
	        	ret.add(new ItemStack(this,1,0));
	        	return ret;
	        }
	        	
	        for(int i = 0; i < 3+world.rand.nextInt(8); ++i)
	        	ret.add(new ItemStack(Items.dye,1,allowedDyes[world.rand.nextInt(allowedDyes.length)]));
        }
        return ret;
    }
    
    public static final int[] allowedDyes = new int[]{1,2,5,2,6,7,2,8,9,10,2,11,12,13,14,2};
    
    public void registerBlockIcons(IconRegister ir)
    {
        side = ir.registerBlockIcon(this.getTextureName() + "side");
        top = ir.registerBlockIcon(this.getTextureName() + "top");
        bot = ir.registerBlockIcon(this.getTextureName() + "bottom");
    }

    public Icon getIcon(int side, int meta)
    {
        return side == 1 ? top : side == 0 ? bot : this.side;
    }
	
    @Override
    public boolean canSustainPlant(IBlockAccess world, BlockPos pos, EnumFacing direction, IPlantable plantable)
    {
        Block plant = plantable.getPlant(world, pos.up()).getBlock();
        
        if (plant == this)
            return true;
        
        return super.canSustainPlant(world, pos, direction, plantable);
    }

	@Override
	public Icon getIcon(IBlockAccess world, int x, int y, int z, int side) {
		return getIcon(side,this.getMetaFromState(world.getBlockState(new BlockPos(x,y,z))));
	}

	@Override
	public List<IBlockState> listPossibleStates(Block b) {
		ArrayList<IBlockState> ret = new ArrayList<IBlockState>();
		for(int i = 0; i < 15; ++i)
			ret.add(this.getStateFromMeta(i));
		return ret;
	}

	@Override
	public int getDCRenderID() {
		return RenderAccessLibrary.RENDER_ID_FACES_WITH_HORIZONTAL_OFFSET;
	}
} public class BlockRedlonStem extends BlockBush implements IGrowable,IBlockConnector{

	public Icon connected;
	public Icon disconnected;
	String textureName;
	public Block crop;
	
    public BlockRedlonStem(Block crop)
    {
    	super();
    	this.crop = crop;
        this.setTickRandomly(true);
        float f = 0.125F;
        this.setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, 0.25F, 0.5F + f);
    }
    
    protected boolean canPlaceBlockOn(Block ground)
    {
        return ground == Blocks.farmland;
    }
    
    @SideOnly(Side.CLIENT)
    public void randomDisplayTick(World worldIn, BlockPos pos, IBlockState state, Random rand)
    {
    	worldIn.spawnParticle(EnumParticleTypes.REDSTONE, pos.getX()+rand.nextDouble(), pos.getY()+rand.nextDouble(), pos.getZ()+rand.nextDouble(), 0, 0, 0);
    }
    
    @SuppressWarnings("rawtypes")
	public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand)
    {
        super.updateTick(worldIn, pos, state, rand);
        if (worldIn.getLight(pos.up()) >= 9)
        {
            float f = MiscUtils.getGrowthChance(this, worldIn, pos);
            if (rand.nextInt((int)(25F / f) + 1) == 0)
            {
                int i = BlockStateMetadata.getMetaFromState(state);

                if (i < 7)
                {
                    state = this.getStateFromMeta(i+1);
                    worldIn.setBlockState(pos, state, 2);
                }
                else
                {
                    Iterator iterator = EnumFacing.Plane.HORIZONTAL.iterator();

                    while (iterator.hasNext())
                    {
                        EnumFacing enumfacing = (EnumFacing)iterator.next();

                        if (worldIn.getBlockState(pos.offset(enumfacing)).getBlock() == this.crop)
                            return;
                    }

                    pos = pos.offset(EnumFacing.Plane.HORIZONTAL.random(rand));

                    if (worldIn.isAirBlock(pos))
                        worldIn.setBlockState(pos, this.crop.getDefaultState());
                }
            }
        }
    }
    
    public void growStem(World worldIn, BlockPos pos, IBlockState state)
    {
        int i = BlockStateMetadata.getMetaFromState(state) + MathHelper.getRandomIntegerInRange(worldIn.rand, 2, 5);
        worldIn.setBlockState(pos, this.getStateFromMeta(Integer.valueOf(Math.min(7, i))), 2);
    }
    
    public void setBlockBoundsBasedOnState(IBlockAccess worldIn, BlockPos pos)
    {
        this.maxY = (BlockStateMetadata.getBlockMetadata(worldIn, pos) * 2 + 2) / 16.0F;
        float f = 0.125F;
        this.setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, (float)this.maxY, 0.5F + f);
    }
    
    public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, IBlockState state, float chance, int fortune)
    {
        super.dropBlockAsItemWithChance(worldIn, pos, state, chance, fortune);
    }
    
    protected Item getSeedItem()
    {
    	return Items.wheat_seeds;
    }
    
    @Override
    public List<ItemStack> getDrops(IBlockAccess world, BlockPos pos, IBlockState state, int fortune)
    {
        List<ItemStack> ret = new java.util.ArrayList<ItemStack>();
        {
            Item item = this.getSeedItem();

            if (item != null)
            {
                int j = BlockStateMetadata.getMetaFromState(state);

                for (int k = 0; k < 3; ++k)
                    if (RANDOM.nextInt(15) <= j)
                        ret.add(new ItemStack(item));
            }
        }
        return ret;
    }
    
    public Item getItemDropped(IBlockState state, Random rand, int fortune)
    {
        return null;
    }
    
    public boolean canGrow(World worldIn, BlockPos pos, IBlockState state, boolean isClient)
    {
        return BlockStateMetadata.getMetaFromState(state) < 7;
    }
    
    @SideOnly(Side.CLIENT)
    public Item getItem(World worldIn, BlockPos pos)
    {
        Item item = this.getSeedItem();
        return item != null ? item : null;
    }
    
    public void grow(World worldIn, Random rand, BlockPos pos, IBlockState state)
    {
        this.growStem(worldIn, pos, state);
    }

    public boolean canUseBonemeal(World worldIn, Random rand, BlockPos pos, IBlockState state)
    {
        return true;
    }
    
    public IBlockState getStateFromMeta(int meta)
    {
    	return this.getDefaultState().withProperty(BlockStateMetadata.METADATA, meta);
    }
    
    public int getMetaFromState(IBlockState state)
    {
    	return BlockStateMetadata.getMetaFromState(state);
    }

    protected BlockState createBlockState()
    {
    	return new BlockState(this,BlockStateMetadata.METADATA);
    }

	
	public String getTextureName()
	{
		return textureName;
	}
	
	public BlockRedlonStem setBlockName(String name)
	{
		this.setUnlocalizedName(name);
		return this;
	}
	
	public BlockRedlonStem setBlockTextureName(String tex)
	{
		textureName = tex;
		return this;
	}
	
	@Override
	public Icon getIcon(int side, int meta) {
		return disconnected;
	}

	@Override
	public Icon getIcon(IBlockAccess world, int x, int y, int z, int side) {
		return disconnected;
	}

	@Override
	public List<IBlockState> listPossibleStates(Block b) {
		ArrayList<IBlockState> lst = new ArrayList<IBlockState>();
		for(int i = 0; i < 8; ++i)
			lst.add(this.getStateFromMeta(i));
		return lst;
	}

	@Override
	public void registerBlockIcons(IconRegister ir) {
		disconnected = ir.registerBlockIcon(this.getTextureName()+"_disconnected");
		connected = ir.registerBlockIcon(this.getTextureName()+"_connected");
	}

	@Override
	public int getDCRenderID() {
		return RenderAccessLibrary.RENDER_ID_CONNECTED_TO_BLOCK;
	}

	@Override
	public boolean connectsTo(IBlockAccess world, BlockPos pos, BlockPos originalPos, EnumFacing face,IBlockState state) {
		return world.getBlockState(pos).getBlock()==this.crop;
	}

	@Override
	public Icon getConnectionIcon(IBlockAccess world, int x, int y, int z) {
		return connected;
	}
	
} public class BlockSpike extends Block implements IOldCubicBlock{

	public static final String[] spikeNames = new String[]{
		"iron",
		"iron_bloody",
		"thaumic",
		"thaumic_bloody",
		"void",
		"void_bloody"
	};
	
	public static Icon[] icons = new Icon[spikeNames.length];
	
	public BlockSpike() 
	{
		super(Material.iron);
		float f = 0.0625F;
		this.setBlockBounds(0, 0, 0, 1, 1-f, 1);
		this.setLightOpacity(0);
	}
	
    public boolean shouldSideBeRendered(IBlockAccess worldIn, BlockPos pos, EnumFacing side)
    {
    	return true;
    }

    public boolean isOpaqueCube()
    {
        return false;
    }
    
    public int damageDropped(IBlockState state)
    {
        return this.damageDropped(BlockStateMetadata.getMetaFromState(state));
    }
    
    public IBlockState getStateFromMeta(int meta)
    {
    	return this.getDefaultState().withProperty(BlockStateMetadata.METADATA, meta);
    }
    
    public int getMetaFromState(IBlockState state)
    {
    	return BlockStateMetadata.getMetaFromState(state);
    }
    
    protected BlockState createBlockState()
    {
    	return new BlockState(this,BlockStateMetadata.METADATA);
    }
    
	@Override
	public int getDCRenderID() {
		return RenderAccessLibrary.RENDER_ID_CROSS;
	}
	
    @SideOnly(Side.CLIENT)
    public EnumWorldBlockLayer getBlockLayer()
    {
        return EnumWorldBlockLayer.CUTOUT;
    }
    
    public void onNeighborBlockChange(World worldIn, BlockPos pos, IBlockState state, Block neighborBlock)
    {
    	if(worldIn.isAirBlock(pos.down()))
    	{
    		this.dropBlockAsItem(worldIn, pos, state, 0);
    		worldIn.setBlockToAir(pos);
    	}
    }
    
    public Icon getIcon(int side, int meta)
    {
    	return icons[meta];
    }
    
    public void registerBlockIcons(IconRegister reg)
    {
    	for(int i = 0; i < icons.length; ++i)
    		icons[i] = reg.registerBlockIcon("thaumicbases:spike/"+spikeNames[i]);
    }
    
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List)
	{
		par3List.add(new ItemStack(par1,1,0));
		par3List.add(new ItemStack(par1,1,2));
		par3List.add(new ItemStack(par1,1,4));
	}
	
	public void onEntityCollidedWithBlock(World w, BlockPos pos, Entity collider)
	{
		int meta = BlockStateMetadata.getBlockMetadata(w, pos);
		if(meta == 0 || meta == 1)
		{
			collider.attackEntityFrom(DamageSource.cactus, 8);
			
			if(meta == 0 && collider instanceof EntityLivingBase && ((EntityLivingBase) collider).getHealth() <= 0)
				w.setBlockState(pos, this.getStateFromMeta(1));
		}
		if(meta == 2 || meta == 3)
		{
			if(w.isBlockIndirectlyGettingPowered(pos) > 0 || w.isBlockIndirectlyGettingPowered(pos.down()) > 0 || w.isBlockPowered(pos))
				return;
			
			if(!(collider instanceof EntityItem))
				collider.attackEntityFrom(DamageSource.cactus, 14);
			
			if(meta == 2 && collider instanceof EntityLivingBase && ((EntityLivingBase) collider).getHealth() <= 0)
				w.setBlockState(pos, this.getStateFromMeta(3));
		}
		if(meta == 4 || meta == 5)
		{
			if(w.isBlockIndirectlyGettingPowered(pos) > 0 || w.isBlockIndirectlyGettingPowered(pos.down()) > 0 || w.isBlockPowered(pos))
				return;
			
			if(collider instanceof EntityPlayer)
			{
				ItemStack boots = ((EntityPlayer) collider).inventory.armorInventory[0];
				if(boots != null && boots.getItem() instanceof ItemVoidArmor)
					return;
			}
			
			if(!(collider instanceof EntityItem) && !(collider instanceof EntityXPOrb))
			{
				if(!w.isRemote)
				{
					FakePlayer fake = FakePlayerFactory.get((WorldServer) w, fakeSpikeProfile);
					collider.attackEntityFrom(DamageSource.causePlayerDamage(fake), 20);
					fake.setDead();
					fake = null;
				}
			}
			
			if(meta == 4 && collider instanceof EntityLivingBase && ((EntityLivingBase) collider).getHealth() <= 0)
				w.setBlockState(pos, this.getStateFromMeta(5));
		}
	}
	
    public boolean onBlockActivated(World w, BlockPos pos, IBlockState state, EntityPlayer player, EnumFacing side, float hitX, float hitY, float hitZ)
    {
    	int meta = BlockStateMetadata.getMetaFromState(state);
    	if(meta != 1 && meta != 3 && meta != 5)
    		return false;
    	
    	ItemStack cI = player.getCurrentEquippedItem();
    	if(cI == null)
    		return false;
    	
    	if(cI.getItem() != ItemsTC.fabric)
    		return false;
    	
    	player.inventory.decrStackSize(player.inventory.currentItem, 1);
    	if(!player.inventory.addItemStackToInventory(new ItemStack(TBItems.resource,1,8)))
    		player.dropPlayerItemWithRandomChoice(new ItemStack(TBItems.resource,1,8), false);
    	
    	w.setBlockState(pos, this.getStateFromMeta(meta-1));
    	
        return true;
    }
	
	public int damageDropped(int par1)
	{
		return par1 == 1 ? 0 : par1 == 3 ? 2 : par1 == 5 ? 4 : par1;
	}
	
	public static final GameProfile fakeSpikeProfile = new GameProfile(UUID.randomUUID(),"[TB]Spikes");

	@Override
	public Icon getIcon(IBlockAccess world, int x, int y, int z, int side) {
		return this.getIcon(side, BlockStateMetadata.getBlockMetadata(world, x,y,z));
	}

	@Override
	public List<IBlockState> listPossibleStates(Block b) {
		ArrayList<IBlockState> lst = new ArrayList<IBlockState>();
		for(int i = 0; i < 6; ++i)
			lst.add(this.getStateFromMeta(i));
		return lst;
	}
} public class BlockSweed extends BlockTBPlant {

	public BlockSweed(int stages, int delay, boolean isCrop) {
		super(stages, delay, isCrop);
	}

    protected boolean canPlaceBlockOn(Block b)
    {
    	return b != null && (b == Blocks.grass || b == Blocks.dirt || b instanceof BlockGrass || b instanceof BlockDirt);
    }
    
    public void updateTick(World w, BlockPos pos, IBlockState state, Random rnd)
    {
        super.updateTick(w,pos, state, rnd);
        if(BlockStateMetadata.getMetaFromState(state) == growthStages-1 && !w.isRemote)
        {
        	EnumFacing dir = EnumFacing.getFront(2+w.rand.nextInt(4));
        	
        	int newX = pos.getX()+dir.getFrontOffsetX();
        	int newZ = pos.getZ()+dir.getFrontOffsetY();
        	int newY = findSutableY(w,newX,pos.getY(),newZ);
        	if(canPlaceBlockOn(w.getBlockState(new BlockPos(newX, newY-1, newZ)).getBlock()) && w.isAirBlock(new BlockPos(newX, newY, newZ))) //fix for the Sweeds destroying blocks
        		w.setBlockState(new BlockPos(newX, newY, newZ), this.getDefaultState());
        }
    }
    
    public int findSutableY(World w, int x, int y, int z)
    {
    	int bY = y;
    	y += 1;
    	while(!canPlaceBlockOn(w.getBlockState(new BlockPos(x, y, z)).getBlock()) && y > bY - 2)
    		--y;
    	
    	return y+1;
    }
    
    @Override
    public List<ItemStack> getDrops(IBlockAccess w, BlockPos pos, IBlockState state, int fortune)
    {
        ArrayList<ItemStack> ret = new ArrayList<ItemStack>();

        if(w instanceof World)
        {
        	World world = World.class.cast(w);
        	int metadata = BlockStateMetadata.getMetaFromState(state);
	        if (metadata >= growthStages-1)
	        {
	            for (int i = 0; i < 1 + fortune; ++i)
	                if (world.rand.nextInt(growthStages) <= metadata)
	                	if(dropSeed != null)
	                		ret.add(dropSeed.copy());
	            
	            for (int i = 0; i < 3 + fortune; ++i)
	                if (world.rand.nextBoolean())
	                	ret.add(new ItemStack(Items.sugar));
	
	            if (world.rand.nextBoolean())
	                ret.add(new ItemStack(Items.reeds));
	            
	        }else
	        	if(dropSeed != null)
	        		ret.add(dropSeed.copy());
        }
        return ret;
    }
} public class BlockTBLeaves extends Block implements IOldCubicBlock, IShearable{

	public static final String[] names = new String[]{
		"goldenOakLeaves",
		"peacefullTreeLeaves",
		"netherTreeLeaves",
		"enderTreeLeaves"
	};
		
	public static final String[] textures = new String[]{
		"goldenOak/leaves",
		"peacefullTree/leaves",
		"netherTree/leaves",
		"enderTree/leaves"
	};
	
	public static Icon[] icons = new Icon[names.length];
	
	public BlockTBLeaves() {
		super(Material.leaves);
		this.setLightOpacity(1);
        this.setTickRandomly(true);
        this.setHardness(0.2F);
        this.setStepSound(soundTypeGrass);
	}
	
    public boolean canEntityDestroy(IBlockAccess world, BlockPos pos, Entity entity)
    {
	    if(BlockStateMetadata.getBlockMetadata(world, pos)%8==3)
	    	if(entity instanceof EntityDragon)
	    		return false;
    	
    	return super.canEntityDestroy(world, pos, entity);
    }
    
    public boolean isFlammable(IBlockAccess world, BlockPos pos, EnumFacing face)
    {
    	if(BlockStateMetadata.getBlockMetadata(world, pos)%8==2)
    		return true;
    	
    	return super.isFlammable(world, pos, face);
    }
    
    public int getFlammability(IBlockAccess world, BlockPos pos, EnumFacing face)
    {
    	if(BlockStateMetadata.getBlockMetadata(world, pos)%8==2)
    		return 0;
    	
    	return super.getFlammability(world, pos, face);
    }
    
    public int getFireSpreadSpeed(IBlockAccess world, BlockPos pos, EnumFacing face)
    {
    	if(BlockStateMetadata.getBlockMetadata(world, pos)%8==2)
    		return 0;
    	
    	return super.getFlammability(world, pos, face);
    }
    
    public boolean isFireSource(World world, BlockPos pos, EnumFacing side)
    {
    	if(BlockStateMetadata.getBlockMetadata(world, pos)%8==2)
    		return true;
    	
    	return super.isFireSource(world, pos, side);
    }
	
    public boolean isFullCube()
    {
        return false;
    }
    
    public boolean isOpaqueCube()
    {
        return false;
    }
    
    public EnumWorldBlockLayer getBlockLayer()
    {
    	return EnumWorldBlockLayer.CUTOUT_MIPPED;
    }
    
    @SideOnly(Side.CLIENT)
    public boolean shouldSideBeRendered(IBlockAccess worldIn, BlockPos pos, EnumFacing side)
    {
    	return true;
    }

	@Override
	public Icon getIcon(int side, int meta) {
		return icons[Math.min(icons.length-1, meta % 8)];
	}
	
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public void getSubBlocks(Item i, CreativeTabs p_149666_2_, List p_149666_3_)
    {
    	for(int f = 0; f < names.length; ++f)
    		p_149666_3_.add(new ItemStack(i,1,f));
    }
    
	@Override
	public Icon getIcon(IBlockAccess world, int x, int y, int z, int side) {
		return getIcon(side,BlockStateMetadata.getBlockMetadata(world, x, y, z));
	}
	
	
    public int damageDropped(IBlockState state)
    {
    	return BlockStateMetadata.getMetaFromState(state) % 8;
    }
	
    public IBlockState getStateFromMeta(int meta)
    {
    	return this.getDefaultState().withProperty(BlockStateMetadata.METADATA, meta);
    }
    
    public int getMetaFromState(IBlockState state)
    {
    	return BlockStateMetadata.getMetaFromState(state);
    }

    protected BlockState createBlockState()
    {
    	return new BlockState(this,BlockStateMetadata.METADATA);
    }

	@Override
	public List<IBlockState> listPossibleStates(Block b) {
		ArrayList<IBlockState> retLst = new ArrayList<IBlockState>();
		for(int i = 0; i < names.length; ++i)
		{
			retLst.add(getStateFromMeta(i));
			retLst.add(getStateFromMeta(i+8));
		}
		return retLst;
	}

	@Override
	public void registerBlockIcons(IconRegister ir) {
    	for(int i = 0; i < icons.length; ++i)
    		icons[i] = ir.registerBlockIcon(TBCore.modid+":"+textures[i]);
	}

	@Override
	public int getDCRenderID() {
		return RenderAccessLibrary.RENDER_ID_CUBE_AND_CROSS;
	}
	
    public void dropApple(World worldIn, BlockPos pos, IBlockState state, int chance)
    {
        if (BlockStateMetadata.getMetaFromState(state) == 0 && worldIn.rand.nextInt(chance) == 0)
            spawnAsEntity(worldIn, pos, new ItemStack(Items.golden_apple, 1, 0));
    }
    
    public int getSaplingDropChance(IBlockState state)
    {
    	return BlockStateMetadata.getMetaFromState(state) == 0 ? 50 : 30;
    }

    public ItemStack createStackedBlock(IBlockState state)
    {
    	return new ItemStack(state.getBlock(),1,BlockStateMetadata.getMetaFromState(state)%8);
    }
    
    public void harvestBlock(World worldIn, EntityPlayer player, BlockPos pos, IBlockState state, TileEntity te)
    {
        if (!worldIn.isRemote && player.getCurrentEquippedItem() != null && player.getCurrentEquippedItem().getItem() == Items.shears)
            player.triggerAchievement(StatList.mineBlockStatArray[Block.getIdFromBlock(this)]);
        else
            super.harvestBlock(worldIn, player, pos, state, te);
    }
    
    @SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
    public List<ItemStack> onSheared(ItemStack item, IBlockAccess world, BlockPos pos, int fortune)
    {
        return new ArrayList(Arrays.asList(new ItemStack(this, 1, BlockStateMetadata.getBlockMetadata(world, pos) % 8)));
    }

	@Override
	public boolean isShearable(ItemStack item, IBlockAccess world, BlockPos pos) {
		return true;
	}
	
	@Override
	public boolean isLeaves(IBlockAccess world, BlockPos pos)
	{
		return true; 
	}
	
    @Override
    public void beginLeavesDecay(World world, BlockPos pos)
    {
    	int meta = BlockStateMetadata.getBlockMetadata(world, pos) % 8;
    	world.setBlockState(pos, getStateFromMeta(meta + 8));
    }
    
    public void breakBlock(World worldIn, BlockPos pos, IBlockState state)
    {
    	MetadataBasedMethodsHelper.breakLeaves(worldIn, pos, state);
    }
    
    @SideOnly(Side.CLIENT)
    public void randomDisplayTick(World worldIn, BlockPos pos, IBlockState state, Random rand)
    {
        if (worldIn.canLightningStrike(pos.up()) && !World.doesBlockHaveSolidTopSurface(worldIn, pos.down()) && rand.nextInt(15) == 1)
        {
            double d0 = pos.getX() + rand.nextFloat();
            double d1 = pos.getY() - 0.05D;
            double d2 = pos.getZ() + rand.nextFloat();
            worldIn.spawnParticle(EnumParticleTypes.DRIP_WATER, d0, d1, d2, 0.0D, 0.0D, 0.0D, new int[0]);
        }
        
        World w = worldIn;
        int x = pos.getX();
        int y = pos.getY();
        int z = pos.getZ();
        Random rnd = rand;
    	
    	if(BlockStateMetadata.getBlockMetadata(worldIn, pos)%8 == 0)
    		w.spawnParticle(EnumParticleTypes.REDSTONE, x+rnd.nextDouble(), y+rnd.nextDouble(), z+rnd.nextDouble(), 1, 1, 0);
    	
    	if(BlockStateMetadata.getBlockMetadata(worldIn, pos)%8 == 1 && rnd.nextFloat() <= 0.01F)
    		w.spawnParticle(EnumParticleTypes.HEART, x+rnd.nextDouble(), y+rnd.nextDouble(), z+rnd.nextDouble(), 0, 10, 0);
    	
    	if(BlockStateMetadata.getBlockMetadata(worldIn, pos)%8 == 2)
    	{
    		if(w.isAirBlock(new BlockPos(x, y-1, z)))
    			w.spawnParticle(EnumParticleTypes.DRIP_LAVA, x+rnd.nextDouble(), y, z+rnd.nextDouble(), 0, 0, 0);
    	}
    	
    	if(BlockStateMetadata.getBlockMetadata(worldIn, pos)%8 == 3)
    		w.spawnParticle(EnumParticleTypes.PORTAL, x+rnd.nextDouble(), y+rnd.nextDouble(), z+rnd.nextDouble(), MathUtils.randomDouble(rnd), MathUtils.randomDouble(rnd), MathUtils.randomDouble(rnd));
    }
    
    public void spawnAction(World w, Random rnd, BlockPos pos)
    {
    	int x = pos.getX();
    	int y = pos.getY();
    	int z = pos.getZ();
    	if(BlockStateMetadata.getBlockMetadata(w,pos)%8 == 1)
    	{
    		if(rnd.nextDouble() > 0.03D)
    			return;
    		
    		int dy = y;
    		BiomeGenBase base = w.getBiomeGenForCoords(new BlockPos(x,0, z));
    		if(base != null)
    		{
    			List<SpawnListEntry> l = base.getSpawnableList(EnumCreatureType.CREATURE);
    			if(l != null && !l.isEmpty())
    			{
    				SpawnListEntry entry = l.get(rnd.nextInt(l.size()));
    				if(entry != null && entry.entityClass != null)
    				{
    					Class<?> c = entry.entityClass;
    					if(EntityLiving.class.isAssignableFrom(c))
    					{
    						try
    						{
	    						EntityLiving el = EntityLiving.class.cast(c.getConstructor(World.class).newInstance(w));
	    			    		while(--y >= dy-6)
	    			    		{
	    			    			el.setPositionAndRotation(x+0.5D, y, z+0.5D, 0, 0);
	    			    			if(el.getCanSpawnHere())
	    			    			{
	    			    				w.spawnEntityInWorld(el);
	    			    				break;
	    			    			}
									continue;
	    			    		}
    						}catch(Exception e)
    						{
    							FMLLog.warning("[TB]Tried to create an entity of class "+c+" but failed! The exception is listed below:",new Object[0]);
    							e.printStackTrace();
    						}
    					}
    				}
    			}
    		}
    	}
    	if(BlockStateMetadata.getBlockMetadata(w,pos)%8 == 2)
    	{
    		int dy = y;
    		while(--y >= dy-8)
    		{
    			Block b = w.getBlockState(new BlockPos(x,y,z)).getBlock();
    			if(!b.isAir(w, new BlockPos(x, y, z)))
    			{
    				boolean netheric = b instanceof BlockNetherrack || b instanceof BlockSoulSand || b == Blocks.quartz_ore;
    				if(netheric && rnd.nextDouble() <= 0.05D)
    				{
    					BiomeGenBase hellBiome = BiomeGenBase.hell;
    	    			List<SpawnListEntry> l = rnd.nextBoolean() ? hellBiome.getSpawnableList(EnumCreatureType.CREATURE) : hellBiome.getSpawnableList(EnumCreatureType.MONSTER);
    	    			if(l != null && !l.isEmpty())
    	    			{
    	    				SpawnListEntry entry = l.get(rnd.nextInt(l.size()));
    	    				if(entry != null && entry.entityClass != null)
    	    				{
    	    					Class<?> c = entry.entityClass;
    	    					if(EntityLiving.class.isAssignableFrom(c))
    	    					{
    	    						try
    	    						{
    		    						EntityLiving el = EntityLiving.class.cast(c.getConstructor(World.class).newInstance(w));
    		    						
    		    			    		el.setPositionAndRotation(x+0.5D, y+1, z+0.5D, 0, 0);
    		    			    		el.onInitialSpawn(w.getDifficultyForLocation(new BlockPos(el)), null);
    		    			    		
    		    			    		if(el.getCanSpawnHere())
    		    			    		{
    		    			    			w.spawnEntityInWorld(el);
    		    			    			break;
    		    			    		}
    		    			    		
    	    						}catch(Exception e)
    	    						{
    	    							FMLLog.warning("[TB]Tried to create an entity of class "+c+" but failed! The exception is listed below:",new Object[0]);
    	    							e.printStackTrace();
    	    						}
    	    					}
    	    				}
    	    			}
    	    			
    					break;
    				}
					boolean flag = b instanceof BlockDirt || b instanceof BlockGrass || b instanceof BlockGravel || b instanceof BlockSand || b instanceof BlockStone;
					if(!flag)
					{
						ItemStack stk = new ItemStack(b,1,BlockStateMetadata.getBlockMetadata(w,pos));
						if(stk!=null&&stk.getItem()!=null)
							if(OreDictionary.getOreIDs(stk) != null && OreDictionary.getOreIDs(stk).length > 0)
							{
								OreDict:for(int i = 0; i < OreDictionary.getOreIDs(stk).length; ++i)
								{
									int id = OreDictionary.getOreIDs(stk)[i];
									if(id != -1)
									{
										String ore = OreDictionary.getOreName(id);
										if(ore != null && ! ore.isEmpty())
										{
											flag = ore.contains("dirt") || ore.contains("grass") || ore.contains("sand") || ore.contains("gravel") || ore.contains("stone");
											if(flag)
												break OreDict;
										}
									}
								}
							}
					}
					if(flag)
					{
						double random = rnd.nextDouble();
						Block setTo = random <= 0.6D ? Blocks.netherrack : random <= 0.9D ? Blocks.soul_sand : Blocks.quartz_ore;
						w.setBlockState(new BlockPos(x, y, z), setTo.getDefaultState());
						break;
					}
    			}
    		}
    	}
    	if(BlockStateMetadata.getBlockMetadata(w,pos)%8 == 3)
    	{
    		int dy = y;
    		while(--y >= dy-11)
    		{
    			Block b = w.getBlockState(new BlockPos(x, y, z)).getBlock();
    			if(!b.isAir(w, new BlockPos(x, y, z)))
    			{
    				boolean end = b == Blocks.end_stone || b instanceof BlockObsidian;
    				if(end && rnd.nextDouble() <= 0.02D)
    				{
    					BiomeGenBase hellBiome = BiomeGenBase.sky;
    	    			List<SpawnListEntry> l = rnd.nextBoolean() ? hellBiome.getSpawnableList(EnumCreatureType.CREATURE) : hellBiome.getSpawnableList(EnumCreatureType.MONSTER);
    					if(l != null && !l.isEmpty())
    	    			{
    	    				SpawnListEntry entry = l.get(rnd.nextInt(l.size()));
    	    				if(entry != null && entry.entityClass != null)
    	    				{
    	    					Class<?> c = entry.entityClass;
    	    					if(EntityLiving.class.isAssignableFrom(c))
    	    					{
    	    						try
    	    						{
    		    						EntityLiving el = EntityLiving.class.cast(c.getConstructor(World.class).newInstance(w));
    		    						
    		    			    		el.setPositionAndRotation(x+0.5D, y+1, z+0.5D, 0, 0);
    		    			    		el.onInitialSpawn(w.getDifficultyForLocation(new BlockPos(el)), null);
    		    			    		
    		    			    		if(w.isAirBlock(new BlockPos(x, y+1, z)))
    		    			    		{
    		    			    			w.spawnEntityInWorld(el);
    		    			    			break;
    		    			    		}
    		    			    		
    	    						}catch(Exception e)
    	    						{
    	    							FMLLog.warning("[TB]Tried to create an entity of class "+c+" but failed! The exception is listed below:",new Object[0]);
    	    							e.printStackTrace();
    	    						}
    	    					}
    	    				}
    	    			}
    	    			
    					break;
    				}
					boolean flag = b instanceof BlockDirt || b instanceof BlockGrass || b instanceof BlockGravel || b instanceof BlockSand || b instanceof BlockStone && !(b instanceof BlockObsidian) && !(b == Blocks.end_stone);
					if(!flag)
					{
						ItemStack stk = new ItemStack(b,1,BlockStateMetadata.getBlockMetadata(w,pos));
						if(stk!=null&&stk.getItem()!=null)
							if(OreDictionary.getOreIDs(stk) != null && OreDictionary.getOreIDs(stk).length > 0)
							{
								OreDict:for(int i = 0; i < OreDictionary.getOreIDs(stk).length; ++i)
								{
									int id = OreDictionary.getOreIDs(stk)[i];
									if(id != -1)
									{
										String ore = OreDictionary.getOreName(id);
										if(ore != null && ! ore.isEmpty())
										{
											flag = ore.contains("dirt") || ore.contains("grass") || ore.contains("sand") || ore.contains("gravel") || ore.contains("stone");
											if(flag)
												break OreDict;
										}
									}
								}
							}
					}
					if(flag)
					{
						double random = rnd.nextDouble();
						Block setTo = random <= 0.9D ? Blocks.end_stone : Blocks.obsidian;
						w.setBlockState(new BlockPos(x, y, z), setTo.getDefaultState());
						break;
					}
    			}
    		}
    	}
    }
    
    public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand)
    {
    	MetadataBasedMethodsHelper.leavesDecayTick(worldIn, pos, state, rand);
    	spawnAction(worldIn, rand, pos);
    }
    
    public int quantityDropped(Random random)
    {
        return random.nextInt(20) == 0 ? 1 : 0;
    }
    
    public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, IBlockState state, float chance, int fortune)
    {
        super.dropBlockAsItemWithChance(worldIn, pos, state, chance, fortune);
    }
    
    public Item getItemDropped(IBlockState state, Random rand, int fortune)
    {
        return Item.getItemFromBlock(TBBlocks.sapling);
    }
    
    @Override
    public List<ItemStack> getDrops(IBlockAccess world, BlockPos pos, IBlockState state, int fortune)
    {
        List<ItemStack> ret = new ArrayList<ItemStack>();
        Random rand = world instanceof World ? ((World)world).rand : new Random();
        int chance = this.getSaplingDropChance(state);

        if (fortune > 0)
        {
            chance -= 2 << fortune;
            if (chance < 10) chance = 10;
        }

        if (rand.nextInt(chance) == 0)
            ret.add(new ItemStack(getItemDropped(state, rand, fortune), 1, damageDropped(state)));

        chance = 200;
        if (fortune > 0)
        {
            chance -= 10 << fortune;
            if (chance < 40) chance = 40;
        }

        this.captureDrops(true);
        if (world instanceof World)
            this.dropApple((World)world, pos, state, chance); // Dammet mojang
        ret.addAll(this.captureDrops(false));
        return ret;
    }
} public class BlockTBLog extends Block implements IOldCubicBlock{

	public static final String[] names = new String[]{
		"peacefullTreeLog",
		"netherTreeLog",
		"enderTreeLog",
		"goldenTreeLog"
	};
		
	public static final String[] textures = new String[]{
		"peacefullTree/log",
		"netherTree/log",
		"enderTree/log",
		"goldenOak/log"
	};
	
	@Override
    public boolean canEntityDestroy(IBlockAccess world, BlockPos pos, Entity entity)
    {
	    if(BlockStateMetadata.getBlockMetadata(world, pos)%4==2)
	    	if(entity instanceof EntityDragon)
	    		return false;
    	
    	return super.canEntityDestroy(world, pos, entity);
    }
	
	@Override
    public boolean isFlammable(IBlockAccess world, BlockPos pos, EnumFacing face)
    {
    	if(BlockStateMetadata.getBlockMetadata(world, pos)%4==1)
    		return true;
    	
    	return super.isFlammable(world, pos, face);
    }
	
    public int getFlammability(IBlockAccess world, BlockPos pos, EnumFacing face)
    {
    	if(BlockStateMetadata.getBlockMetadata(world, pos)%4==1)
    		return 0;
    	
    	return super.getFlammability(world, pos, face);
    }
    
    public int getFireSpreadSpeed(IBlockAccess world, BlockPos pos, EnumFacing face)
    {
    	if(BlockStateMetadata.getBlockMetadata(world, pos)%4==1)
    		return 0;
    	
    	return super.getFlammability(world, pos, face);
    }
    
    public boolean isFireSource(World world, BlockPos pos, EnumFacing side)
    {
    	if(BlockStateMetadata.getBlockMetadata(world, pos)%4==1)
    		return true;
    	
    	return super.isFireSource(world, pos, side);
    }
    
    protected ItemStack createStackedBlock(IBlockState state)
    {
    	return new ItemStack(state.getBlock(),1,BlockStateMetadata.getMetaFromState(state) % 4);
    }
    
	public void breakBlock(World worldIn, BlockPos pos, IBlockState state)
    {
		MetadataBasedMethodsHelper.breakLog(worldIn, pos, state);
    }
	
    @Override 
    public boolean canSustainLeaves(IBlockAccess world, BlockPos pos)
    { 
    	return true; 
    }
    
    @Override 
    public boolean isWood(IBlockAccess world, BlockPos pos)
    {
    	return true; 
    }
    
    public boolean rotateBlock(World world, BlockPos pos, EnumFacing axis)
    {
        IBlockState state = world.getBlockState(pos);
        int meta = BlockStateMetadata.getMetaFromState(state);
        int mv = getMetaFromAxis(axis.getAxis(),meta % 4);
        world.setBlockState(pos, getStateFromMeta(mv));
        return false;
    }
    
    public int damageDropped(IBlockState state)
    {
    	return BlockStateMetadata.getMetaFromState(state) % 4;
    }
    
    public IBlockState onBlockPlaced(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer)
    {
        return super.onBlockPlaced(worldIn, pos, facing, hitX, hitY, hitZ, meta, placer).withProperty(BlockStateMetadata.METADATA, getMetaFromAxis(facing.getAxis(),meta));
    }
    
    public int getMetaFromAxis(EnumFacing.Axis axis, int originalMeta)
    {
    	int addedMeta = 0;
    	switch(axis)
    	{
	    	case Y:
	    	{
	    		addedMeta = 0;
	    		break;
	    	}
	    	case X:
	    	{
	    		addedMeta = 1;
	    		break;
	    	}
	    	case Z:
	    	{
	    		addedMeta = 2;
	    		break;
	    	}
		default:
			break;
    	}
    	
    	return originalMeta+addedMeta*4;
    }
    
    public IBlockState getStateFromMeta(int meta)
    {
    	return this.getDefaultState().withProperty(BlockStateMetadata.METADATA, meta);
    }
    
    public int getMetaFromState(IBlockState state)
    {
    	return BlockStateMetadata.getMetaFromState(state);
    }

    protected BlockState createBlockState()
    {
    	return new BlockState(this,BlockStateMetadata.METADATA);
    }
	
	public Icon[][] bIcons = new Icon[names.length][2];
	
	public BlockTBLog() {
		super(Material.wood);
		this.setHarvestLevel("axe", 0);
        this.setHardness(2.0F);
        this.setStepSound(soundTypeWood);
	}

	@Override
	public Icon getIcon(int side, int meta) {
		int subMeta = meta / 4;
		int aIndex = 0;
		if(subMeta == 0 && (side == 1 || side == 0))
			aIndex = 1;
		if(subMeta == 1 && (side == 4 || side == 5))
			aIndex = 1;
		if(subMeta == 2 && (side == 2 || side == 3))
			aIndex = 1;
		return bIcons[meta % 4][aIndex];
	}

	@Override
	public Icon getIcon(IBlockAccess world, int x, int y, int z, int side) {
		return getIcon(side,BlockStateMetadata.getBlockMetadata(world, x, y, z));
	}

	@Override
	public List<IBlockState> listPossibleStates(Block b) {
		ArrayList<IBlockState> retLst = new ArrayList<IBlockState>();
		for(int i = 0; i < names.length*3; ++i)
			retLst.add(getStateFromMeta(i));
		return retLst;
	}

	@Override
	public void registerBlockIcons(IconRegister ir) {
		for(int i = 0; i < names.length; ++i)
			for(int j = 0; j < 2; ++j)
				bIcons[i][j] = ir.registerBlockIcon("thaumicbases",textures[i]+(j == 0 ? "" : "_top"));
	}
	
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public void getSubBlocks(Item itm, CreativeTabs tab, List lst)
    {
    	for(int i = 0; i < names.length; ++i)
    		lst.add(new ItemStack(itm,1,i));
    }

	@Override
	public int getDCRenderID() {
		return RenderAccessLibrary.RENDER_ID_CUBE;
	}

} public class BlockTBPlanks extends Block implements IOldCubicBlock
{

	public static final String[] names = new String[]{
		"enderTreePlanks",
		"goldenOakPlanks",
		"peacefullTreePlanks",
		"netherTreePlanks"
	};
	
	public static final String[] textures = new String[]{
		"enderTree/planks",
		"goldenOak/planks",
		"peacefullTree/planks",
		"netherTree/planks"
	};
	
	public Icon[] icons = new Icon[textures.length];
	
	public BlockTBPlanks() 
	{
		super(Material.wood);
		this.setHardness(2);
		this.setResistance(45);
		this.setStepSound(Block.soundTypeWood);
	}
	
    protected ItemStack createStackedBlock(IBlockState state)
    {
    	return new ItemStack(state.getBlock(),1,BlockStateMetadata.getMetaFromState(state));
    }
	
    public boolean canEntityDestroy(IBlockAccess world, BlockPos pos, Entity entity)
    {
	    if(BlockStateMetadata.getBlockMetadata(world, pos)==0)
	    	if(entity instanceof EntityDragon)
	    		return false;
    	
    	return super.canEntityDestroy(world, pos, entity);
    }
    
    public boolean isFlammable(IBlockAccess world, BlockPos pos, EnumFacing face)
    {
    	if(BlockStateMetadata.getBlockMetadata(world, pos)==3)
    		return true;
    	
    	return super.isFlammable(world, pos, face);
    }
    
    public int getFlammability(IBlockAccess world, BlockPos pos, EnumFacing face)
    {
    	if(BlockStateMetadata.getBlockMetadata(world, pos)==0)
    		return 0;
    	
    	return super.getFlammability(world, pos, face);
    }
    
    public int getFireSpreadSpeed(IBlockAccess world, BlockPos pos, EnumFacing face)
    {
    	if(BlockStateMetadata.getBlockMetadata(world, pos)==0)
    		return 0;
    	
    	return super.getFlammability(world, pos, face);
    }
    public boolean isFireSource(World world, BlockPos pos, EnumFacing side)
    {
    	if(BlockStateMetadata.getBlockMetadata(world, pos)==0)
    		return true;
    	
    	return super.isFireSource(world, pos, side);
    }
    
    public Icon getIcon(int side, int meta)
    {
    	return icons[Math.min(meta,icons.length-1)];
    }
    
    public int damageDropped(int meta)
    {
    	return meta;
    }
    
    @SideOnly(Side.CLIENT)
    public void registerBlockIcons(IconRegister reg)
    {
    	for(int i = 0; i < names.length; ++i)
    		icons[i] = reg.registerBlockIcon("thaumicbases:"+textures[i]);
    }
    
    @SuppressWarnings({ "unchecked", "rawtypes" })
	@SideOnly(Side.CLIENT)
    public void getSubBlocks(Item p_149666_1_, CreativeTabs p_149666_2_, List p_149666_3_)
    {
    	for(int i = 0; i < names.length; ++i)
    		p_149666_3_.add(new ItemStack(p_149666_1_, 1, i));
    }
    
    public IBlockState getStateFromMeta(int meta)
    {
    	return this.getDefaultState().withProperty(BlockStateMetadata.METADATA, meta);
    }
    
    public int getMetaFromState(IBlockState state)
    {
    	return BlockStateMetadata.getMetaFromState(state);
    }

    
    public int damageDropped(IBlockState state)
    {
        return this.damageDropped(BlockStateMetadata.getMetaFromState(state));
    }
    
    protected BlockState createBlockState()
    {
    	return new BlockState(this,BlockStateMetadata.METADATA);
    }

	@Override
	public Icon getIcon(IBlockAccess world, int x, int y, int z, int side) {
		return getIcon(side,BlockStateMetadata.getBlockMetadata(world, x, y, z));
	}
	
	@Override
	public List<IBlockState> listPossibleStates(Block b) {
		ArrayList<IBlockState> retLst = new ArrayList<IBlockState>();
		for(int i = 0; i < names.length; ++i)
			retLst.add(getStateFromMeta(i));
		
		return retLst;
	}

	@Override
	public int getDCRenderID() {
		return RenderAccessLibrary.RENDER_ID_CUBE;
	}

} public class BlockTBPlant extends BlockBush implements IGrowable, IOldCubicBlock
{
	
	public int growthStages;
	public int growthDelay;
	public boolean requiresFarmland;
	public Icon[] growthIcons;
	public ItemStack dropItem;
	public ItemStack dropSeed;
	String textureName;

	public BlockTBPlant(int stages, int delay, boolean isCrop)
	{
		super();
		growthStages = stages;
		growthDelay = delay;
		requiresFarmland = isCrop;
        this.setTickRandomly(true);
        float f = 0.5F;
        if(isCrop)
        	this.setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, 0.25F, 0.5F + f);
        else
        	this.setBlockBounds(0.25F, 0.0F, 0.25F, 0.75F, 0.75F, 0.75F);
        
        this.setHardness(0.0F);
        this.setStepSound(soundTypeGrass);
        this.disableStats();
	}
	
	public String getTextureName()
	{
		return textureName;
	}
	
	public BlockTBPlant setBlockName(String name)
	{
		this.setUnlocalizedName(name);
		return this;
	}
	
	public BlockTBPlant setBlockTextureName(String tex)
	{
		textureName = tex;
		return this;
	}
	
	@Override
    public Item getItem(World w, BlockPos pos)
    {
        return dropSeed != null ? dropSeed.getItem() : Item.getItemFromBlock(this);
    }
	
    protected boolean canPlaceBlockOn(Block b)
    {
        return requiresFarmland ? b == Blocks.farmland : true;
    }
    
    public void updateTick(World w, BlockPos pos, IBlockState state, Random rnd)
    {
        super.updateTick(w, pos,state, rnd);

        if (w.getLight(pos.up()) >= 9)
        {
            int l = BlockStateMetadata.getMetaFromState(state);

            if (l < growthStages)
            {
                float f = this.calculateGrowth(w, pos);

                if (rnd.nextInt((int)(growthDelay / f) + 1) == 0)
                {
                    ++l;
                    if(l >= growthStages)
                    	l = growthStages-1;
                    w.setBlockState(pos, this.getStateFromMeta(l));
                }
            }
        }
    }
    
    @Override
    public EnumPlantType getPlantType(IBlockAccess world, BlockPos pos)
    {
    	return this.requiresFarmland ? EnumPlantType.Crop : EnumPlantType.Plains;
    }
    
    private float calculateGrowth(World w, BlockPos pos)
    {
        float f = 1.0F;
        Block block = w.getBlockState(pos.north()).getBlock();
        Block block1 = w.getBlockState(pos.south()).getBlock();
        Block block2 = w.getBlockState(pos.west()).getBlock();
        Block block3 = w.getBlockState(pos.east()).getBlock();
        Block block4 = w.getBlockState(pos.east().north()).getBlock();
        Block block5 = w.getBlockState(pos.east().south()).getBlock();
        Block block6 = w.getBlockState(pos.west().north()).getBlock();
        Block block7 = w.getBlockState(pos.west().south()).getBlock();
        boolean flag = block2 == this || block3 == this;
        boolean flag1 = block == this || block1 == this;
        boolean flag2 = block4 == this || block5 == this || block6 == this || block7 == this;

        int x = pos.getX();
        int y = pos.getY();
        int z = pos.getZ();
        
        for (int l = x - 1; l <= x + 1; ++l)
        {
            for (int i1 = z - 1; i1 <= z + 1; ++i1)
            {
                float f1 = 0.0F;

                if (w.getBlockState(new BlockPos(l, y - 1, i1)).getBlock().canSustainPlant(w, new BlockPos(l, y - 1, i1), EnumFacing.UP, this))
                {
                    f1 = 1.0F;

                    if (w.getBlockState(new BlockPos(l, y - 1, i1)).getBlock().isFertile(w, new BlockPos(l, y - 1, i1)))
                    {
                        f1 = 3.0F;
                    }
                }

                if (l != x || i1 != z)
                {
                    f1 /= 4.0F;
                }

                f += f1;
            }
        }

        if (flag2 || flag && flag1)
        {
            f /= 2.0F;
        }

        return f;
    }
	
	//canApplyBonemeal
	@Override
	public boolean canUseBonemeal(World worldIn, Random rand, BlockPos pos, IBlockState state) {
		return BlockStateMetadata.getBlockMetadata(worldIn, pos) < growthStages-1;
	}

	//canGrowPlant
	@Override
	public boolean canGrow(World worldIn, BlockPos pos, IBlockState state, boolean isClient) {
		return worldIn.getLight(pos.up()) >= 9;
	}

	//growPlant
	@Override
	public void grow(World worldIn, Random r, BlockPos pos, IBlockState state)
	{
		worldIn.setBlockState(pos, this.getStateFromMeta(Math.min(growthStages-1, BlockStateMetadata.getBlockMetadata(worldIn, pos)+r.nextInt(3)+1)));
	}
	
    @SideOnly(Side.CLIENT)
    public void registerBlockIcons(IconRegister reg)
    {
    	growthIcons = new Icon[growthStages];
    	for(int i = 0; i < growthStages; ++i)
    		growthIcons[i] = reg.registerBlockIcon(textureName+"stage_"+i);
    }
    
    @SideOnly(Side.CLIENT)
    public Icon getIcon(int side, int meta)
    {
    	return growthIcons[meta >= growthIcons.length ? growthIcons.length-1 : meta];
    }

    @Override
    public List<ItemStack> getDrops(IBlockAccess world, BlockPos pos, IBlockState state, int fortune)
    {
    	Random rand = new Random(System.currentTimeMillis());
    	int metadata = BlockStateMetadata.getMetaFromState(state);
        ArrayList<ItemStack> ret = new ArrayList<ItemStack>();

        if (metadata >= growthStages-1)
        {
            for (int i = 0; i < (rand.nextDouble()*(fortune) > 0.75D ? 2 : 1); ++i) //Fix for the seed duplication
            {
                if (rand.nextInt(growthStages) <= metadata)
                {
                	if(dropSeed != null)
                	{
                		ret.add(dropSeed.copy());
                		if(dropSeed.getItem() instanceof ItemBlock) //Fix for the primal shroom duplication
                			break;
                	}
                }
            }
            
            for (int i = 0; i < 1 + rand.nextInt(fortune+1); ++i) //Change for the resource drop
            {
                if (rand.nextInt(growthStages) <= metadata)
                {
                	if(dropItem != null)
                		ret.add(dropItem.copy());
                }
            }
        }else
        	if(dropSeed != null)
        		ret.add(dropSeed.copy());

        return ret;
    }
    
    public IBlockState getStateFromMeta(int meta)
    {
    	return this.getDefaultState().withProperty(BlockStateMetadata.METADATA, meta);
    }
    
    public int getMetaFromState(IBlockState state)
    {
    	return BlockStateMetadata.getMetaFromState(state);
    }

    protected BlockState createBlockState()
    {
    	return new BlockState(this,BlockStateMetadata.METADATA);
    }

	@Override
	public Icon getIcon(IBlockAccess world, int x, int y, int z, int side) {
		return this.getIcon(side, BlockStateMetadata.getBlockMetadata(world, x,y,z));
	}

	@Override
	public List<IBlockState> listPossibleStates(Block b) {
		ArrayList<IBlockState> retLst = new ArrayList<IBlockState>();
		for(int i = 0; i < growthStages; ++i)
			retLst.add(getStateFromMeta(i));
		return retLst;
	}

	@Override
	public int getDCRenderID() {
		return requiresFarmland ? RenderAccessLibrary.RENDER_ID_CROPS : RenderAccessLibrary.RENDER_ID_CROSS;
	}
    
    public EnumWorldBlockLayer getBlockLayer()
    {
    	return EnumWorldBlockLayer.CUTOUT_MIPPED;
    }
} public class BlockTBSapling extends BlockBush implements IGrowable,IOldCubicBlock{

	public Icon[] icons = new Icon[8];
	public static final String[] names = new String[]{
		"goldenOakSapling",
		"peacefullTreeSapling",
		"netherTreeSapling",
		"enderTreeSapling"
	};
	
	public static final String[] textures = new String[]{
		"thaumicbases:goldenOak/sapling",
		"thaumicbases:peacefullTree/sapling",
		"thaumicbases:netherTree/sapling",
		"thaumicbases:enderTree/sapling"
	};
	
	public BlockTBSapling()
	{
		super();
        float f = 0.4F;
        this.setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, f * 2.0F, 0.5F + f);
	}
	
    public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand)
    {
        if (!worldIn.isRemote)
        {
            super.updateTick(worldIn, pos, state, rand);
            if (worldIn.getLightFromNeighbors(pos.up()) >= 9 && rand.nextInt(7) == 0)
            {
                this.grow(worldIn, pos, state, rand);
            }
        }
    }
    
    public void grow(World worldIn, BlockPos pos, IBlockState state, Random rand)
    {
        if (BlockStateMetadata.getBlockMetadata(worldIn, pos) < 8)
            worldIn.setBlockState(pos, this.getStateFromMeta(BlockStateMetadata.getBlockMetadata(worldIn, pos)+8), 4);
        else
            this.generateTree(worldIn, pos, state, rand);
    }
    
    public void generateTree(World worldIn, BlockPos pos, IBlockState state, Random rand)
    {
    	int meta = BlockStateMetadata.getBlockMetadata(worldIn, pos)%8;
    	if(BlockStateMetadata.getBlockMetadata(worldIn, pos)%8 == 0)
    	{
	    	if (!net.minecraftforge.event.terraingen.TerrainGen.saplingGrowTree(worldIn, rand, pos))
	    		return;
	    	 
	    	worldIn.setBlockToAir(pos);
	    	 
	    	new WorldGenOak(true, 5, 3, 0, false, TBBlocks.genLogs, TBBlocks.genLeaves).generate(worldIn, rand, pos);
	    	return;
    	}
    	if(BlockStateMetadata.getBlockMetadata(worldIn, pos)%8 == 1)
    	{
	    	if (!net.minecraftforge.event.terraingen.TerrainGen.saplingGrowTree(worldIn, rand, pos))
	    		return;
	    	 
	    	worldIn.setBlockToAir(pos);
	    	 
	    	new WorldGenOak(true, 6, 0, 1, false, TBBlocks.genLogs, TBBlocks.genLeaves).generate(worldIn, rand, pos);
	    	
	    	return;
    	}
    	if(BlockStateMetadata.getBlockMetadata(worldIn, pos)%8 == 2)
    	{
    		WorldGenBigOak tree = new WorldGenBigOak(true,6,1,2,1,TBBlocks.genLogs,TBBlocks.genLeaves);
    		
    		worldIn.setBlockToAir(pos);
    		
    		if(!tree.generate(worldIn, rand, pos))
    			worldIn.setBlockState(pos, this.getStateFromMeta(meta), 4);
    		
    		return;
    	}
    	if(BlockStateMetadata.getBlockMetadata(worldIn, pos)%8 == 3)
    	{
    		WorldGenBigOak tree = new WorldGenBigOak(true,4,2,3,3,TBBlocks.genLogs,TBBlocks.genLeaves);
    		
    		worldIn.setBlockToAir(pos);
    		
    		if(!tree.generate(worldIn, rand, pos))
    			worldIn.setBlockState(pos, this.getStateFromMeta(meta), 4);
    		
    		return;
    	}
    }
    
    public int damageDropped(IBlockState state)
    {
        return BlockStateMetadata.getMetaFromState(state) % 8;
    }
    
    public IBlockState getStateFromMeta(int meta)
    {
    	return this.getDefaultState().withProperty(BlockStateMetadata.METADATA, meta);
    }
    
    public int getMetaFromState(IBlockState state)
    {
    	return BlockStateMetadata.getMetaFromState(state);
    }

    protected BlockState createBlockState()
    {
    	return new BlockState(this,BlockStateMetadata.METADATA);
    }
	
	@Override
	public boolean canGrow(World worldIn, BlockPos pos, IBlockState state, boolean isClient) {
		return true;
	}

	@Override
	public boolean canUseBonemeal(World worldIn, Random rand, BlockPos pos, IBlockState state) {
		return true;
	}

	@Override
	public void grow(World worldIn, Random rand, BlockPos pos, IBlockState state) {
		this.grow(worldIn, pos, state, rand);
	}

	@Override
	public Icon getIcon(int side, int meta) {
		return icons[meta%8];
	}

	@Override
	public Icon getIcon(IBlockAccess world, int x, int y, int z, int side) {
		return getIcon(side,BlockStateMetadata.getBlockMetadata(world, x, y, z));
	}

	@Override
	public List<IBlockState> listPossibleStates(Block b) {
		ArrayList<IBlockState> retLst = new ArrayList<IBlockState>();
		for(int i = 0; i < names.length; ++i)
		{
			retLst.add(getStateFromMeta(i));
			retLst.add(getStateFromMeta(i+8));
		}
		return retLst;
	}

	@Override
	public void registerBlockIcons(IconRegister ir) {
    	for(int i = 0; i < names.length; ++i)
    		icons[i] = ir.registerBlockIcon(textures[i]);
	}
	
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public void getSubBlocks(Item p_149666_1_, CreativeTabs p_149666_2_, List p_149666_3_)
    {
    	for(int i = 0; i < names.length; ++i)
    		p_149666_3_.add(new ItemStack(p_149666_1_, 1, i));
    }

	@Override
	public int getDCRenderID() {
		return RenderAccessLibrary.RENDER_ID_CROSS;
	}

} public class BlockThaumicAnvil extends Block implements IInfusionStabiliser, IRotationProvider
{
    public BlockThaumicAnvil() {
		super(Material.iron);
		this.setLightOpacity(0);
	}

	public static final String[] anvilDamageNames = new String[] {"intact", "slightlyDamaged", "veryDamaged"};
    private static final String[] anvilIconNames = new String[] {"top_damaged_0", "top_damaged_1", "top_damaged_2"};
    public Icon[] anvilIcons;
    public Icon blockIcon;
    public String texture;
    
	public BlockThaumicAnvil setBlockName(String name)
	{
		this.setUnlocalizedName(name);
		return this;
	}
	
    public IBlockState onBlockPlaced(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer)
    {
        EnumFacing enumfacing1 = placer.getHorizontalFacing().rotateY();
        if(enumfacing1 == EnumFacing.NORTH || enumfacing1 == EnumFacing.SOUTH)
        	return getStateFromMeta(meta);
        
        return getStateFromMeta(3+meta);
    }
    
	public BlockThaumicAnvil setBlockTextureName(String tex)
	{
		texture = tex;
		return this;
	}
	
	public String getTextureName()
	{
		return texture;
	}
    
    public Icon getIcon(int side, int meta)
    {
    	if(side == 1)
    		return anvilIcons[meta % 3];
    	
    	return blockIcon;
    }
    
    public void registerBlockIcons(IconRegister p_149651_1_)
    {
        this.blockIcon = p_149651_1_.registerBlockIcon(this.getTextureName()+"base");
        this.anvilIcons = new Icon[anvilIconNames.length];

        for (int i = 0; i < this.anvilIcons.length; ++i)
        {
            this.anvilIcons[i] = p_149651_1_.registerBlockIcon(this.getTextureName()+anvilIconNames[i]);
        }
    }
    
    public boolean isFullCube()
    {
        return false;
    }

    public boolean isOpaqueCube()
    {
        return false;
    }
    
    public int damageDropped(IBlockState state)
    {
    	int meta = BlockStateMetadata.getMetaFromState(state);
    	return meta >= 3 ? meta - 3 : meta;
    }
    
    @SuppressWarnings({ "unchecked", "rawtypes" })
	@SideOnly(Side.CLIENT)
    public void getSubBlocks(Item itemIn, CreativeTabs tab, List list)
    {
        list.add(new ItemStack(itemIn, 1, 0));
        list.add(new ItemStack(itemIn, 1, 1));
        list.add(new ItemStack(itemIn, 1, 2));
    }
    
	@Override
	public boolean canStabaliseInfusion(World w, BlockPos pos) 
	{
		return true;
	}

	@Override
	public Icon getIcon(IBlockAccess world, int x, int y, int z, int side) {
		return this.getIcon(side, BlockStateMetadata.getBlockMetadata(world, x, y, z));
	}

	@Override
	public List<IBlockState> listPossibleStates(Block b) {
		ArrayList<IBlockState> retLst = new ArrayList<IBlockState>();
		for(int i = 0; i < 6; ++i)
			retLst.add(getStateFromMeta(i));
		
		return retLst;
	}

	@Override
	public int getDCRenderID() {
		return RenderAccessLibrary.RENDER_ID_ANVIL;
	}

	@Override
	public EnumFacing getRotation(IBlockAccess world, int x, int y, int z, IBlockState state) {
		return BlockStateMetadata.getBlockMetadata(world, x, y, z) < 3 ? EnumFacing.NORTH : EnumFacing.WEST;
	}
	
    public IBlockState getStateFromMeta(int meta)
    {
    	return this.getDefaultState().withProperty(BlockStateMetadata.METADATA, meta);
    }
    
    public int getMetaFromState(IBlockState state)
    {
    	return BlockStateMetadata.getMetaFromState(state);
    }
    
    protected BlockState createBlockState()
    {
    	return new BlockState(this,BlockStateMetadata.METADATA);
    }
    
    public boolean onBlockActivated(World w, BlockPos pos, IBlockState state, EntityPlayer p, EnumFacing side, float hitX, float hitY, float hitZ)
    {
    	if(w.isRemote)
    		return true;
    	
    	p.openGui(TBCore.instance, 0x421921, w, pos.getX(),pos.getY(),pos.getZ());
    	
    	return true;
    }
	
} public class BlockVoidAnvil extends Block implements IInfusionStabiliser, IRotationProvider
{
    public BlockVoidAnvil() {
		super(Material.iron);
		this.setLightOpacity(0);
    	this.setHardness(12);
    	this.setResistance(Float.MAX_VALUE);
    	this.setTickRandomly(true);
    	this.setStepSound(Block.soundTypeAnvil);
    	this.setHarvestLevel("pickaxe", 3);
	}
    
    public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand) 
    {
    	int meta = BlockStateMetadata.getMetaFromState(state);
    	int aMeta = meta % 3;
    	if(aMeta > 0)
    		worldIn.setBlockState(pos, this.getStateFromMeta(meta-1));
    }
    
    public void randomDisplayTick(World worldIn, BlockPos pos, IBlockState state, Random r) 
    {
    	int x = pos.getX();
    	int y = pos.getY();
    	int z = pos.getZ();
    	Thaumcraft.proxy.getFX().sparkle(x+r.nextFloat(), y+r.nextFloat(), z+r.nextFloat(), 2, 5, -0.1F);
    }

	public static final String[] anvilDamageNames = new String[] {"intact", "slightlyDamaged", "veryDamaged"};
    private static final String[] anvilIconNames = new String[] {"top_damaged_0", "top_damaged_1", "top_damaged_2"};
    public Icon[] anvilIcons;
    public Icon blockIcon;
    public String texture;
    
	public BlockVoidAnvil setBlockName(String name)
	{
		this.setUnlocalizedName(name);
		return this;
	}
	
    public IBlockState onBlockPlaced(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer)
    {
        EnumFacing enumfacing1 = placer.getHorizontalFacing().rotateY();
        if(enumfacing1 == EnumFacing.NORTH || enumfacing1 == EnumFacing.SOUTH)
        	return getStateFromMeta(meta);
        
        return getStateFromMeta(3+meta);
    }
    
	public BlockVoidAnvil setBlockTextureName(String tex)
	{
		texture = tex;
		return this;
	}
	
	public String getTextureName()
	{
		return texture;
	}
    
    public Icon getIcon(int side, int meta)
    {
    	if(side == 1)
    		return anvilIcons[meta % 3];
    	
    	return blockIcon;
    }
    
    public void registerBlockIcons(IconRegister p_149651_1_)
    {
        this.blockIcon = p_149651_1_.registerBlockIcon(this.getTextureName()+"base");
        this.anvilIcons = new Icon[anvilIconNames.length];

        for (int i = 0; i < this.anvilIcons.length; ++i)
        {
            this.anvilIcons[i] = p_149651_1_.registerBlockIcon(this.getTextureName()+anvilIconNames[i]);
        }
    }
    
    public boolean isFullCube()
    {
        return false;
    }

    public boolean isOpaqueCube()
    {
        return false;
    }
    
    public int damageDropped(IBlockState state)
    {
    	int meta = BlockStateMetadata.getMetaFromState(state);
    	return meta >= 3 ? meta - 3 : meta;
    }
    
    @SuppressWarnings({ "unchecked", "rawtypes" })
	@SideOnly(Side.CLIENT)
    public void getSubBlocks(Item itemIn, CreativeTabs tab, List list)
    {
        list.add(new ItemStack(itemIn, 1, 0));
        list.add(new ItemStack(itemIn, 1, 1));
        list.add(new ItemStack(itemIn, 1, 2));
    }
    
	@Override
	public boolean canStabaliseInfusion(World w, BlockPos pos) 
	{
		return true;
	}

	@Override
	public Icon getIcon(IBlockAccess world, int x, int y, int z, int side) {
		return this.getIcon(side, BlockStateMetadata.getBlockMetadata(world, x, y, z));
	}

	@Override
	public List<IBlockState> listPossibleStates(Block b) {
		ArrayList<IBlockState> retLst = new ArrayList<IBlockState>();
		for(int i = 0; i < 6; ++i)
			retLst.add(getStateFromMeta(i));
		
		return retLst;
	}

	@Override
	public int getDCRenderID() {
		return RenderAccessLibrary.RENDER_ID_ANVIL;
	}

	@Override
	public EnumFacing getRotation(IBlockAccess world, int x, int y, int z, IBlockState state) {
		return BlockStateMetadata.getBlockMetadata(world, x, y, z) < 3 ? EnumFacing.NORTH : EnumFacing.WEST;
	}
	
    public IBlockState getStateFromMeta(int meta)
    {
    	return this.getDefaultState().withProperty(BlockStateMetadata.METADATA, meta);
    }
    
    public int getMetaFromState(IBlockState state)
    {
    	return BlockStateMetadata.getMetaFromState(state);
    }
    
    protected BlockState createBlockState()
    {
    	return new BlockState(this,BlockStateMetadata.METADATA);
    }
    
    public boolean onBlockActivated(World w, BlockPos pos, IBlockState state, EntityPlayer p, EnumFacing side, float hitX, float hitY, float hitZ)
    {
    	if(w.isRemote)
    		return true;
    	
    	p.openGui(TBCore.instance, 0x421920, w, pos.getX(),pos.getY(),pos.getZ());
    	
    	return true;
    }
	
} public class BlockWoodSlab extends BlockTBSlab{

	public BlockWoodSlab(boolean fullBlock, Material material) 
	{
		super(material, fullBlock);
		setHardness(2.0F);
		setResistance(1.0F);
		setStepSound(Block.soundTypeWood);
	}
	
    public Item getItemDropped(IBlockState state, Random rand, int fortune)
    {
        return Item.getItemFromBlock(TBBlocks.woodSlab);
    }

    protected ItemStack createStackedBlock(IBlockState state)
    {
        return new ItemStack(Item.getItemFromBlock(TBBlocks.woodSlab), 2, BlockStateMetadata.getMetaFromState(state) % 7);
    }
	
    @SideOnly(Side.CLIENT)
    public Item getItem(World worldIn, BlockPos pos)
    {
    	return Item.getItemFromBlock(TBBlocks.woodSlab);
    }

	@Override
	public String getUnlocalizedName(int meta) {
		return super.getUnlocalizedName()+BlockTBPlanks.names[meta & 7];
	}
	
    public Icon getIcon(int side, int meta)
    {
    	return IOldCubicBlock.class.cast(TBBlocks.planks).getIcon(side, meta & 7);
    }
	
    @SuppressWarnings({ "unchecked", "rawtypes" })
	@SideOnly(Side.CLIENT)
    public void getSubBlocks(Item itm, CreativeTabs tab, List lst)
    {
    	for(int i = 0; i < 4; ++i)
    	{
    		lst.add(new ItemStack(itm,1,i));
    	}
    }

	@Override
	public Icon getIcon(IBlockAccess world, int x, int y, int z, int side) {
		return this.getIcon(side, BlockStateMetadata.getBlockMetadata(world, x,y,z));
	}

	@Override
	public List<IBlockState> listPossibleStates(Block b) {
		ArrayList<IBlockState> retLst = new ArrayList<IBlockState>();
		for(int i = 0; i < 16; ++i)
			retLst.add(getStateFromMeta(i));
		return retLst;
	}

	@Override
	public void registerBlockIcons(IconRegister ir) {
		
	}

} public class TBBlock extends Block implements IInfusionStabiliser,IOldCubicBlock{
	
	boolean isGlass;
	boolean stabilise;
	Icon blockIcon;
	String iconName;
	
	public TBBlock(Material m,boolean b)
	{
		super(m);
		isGlass = b;
	}
	
	public String getTextureName()
	{
		return iconName;
	}
	
	public TBBlock setBlockName(String name)
	{
		this.setUnlocalizedName(name);
		return this;
	}

	public TBBlock stabilise()
	{
		stabilise = true;
		return this;
	}
	
    public boolean isOpaqueCube()
    {
        return !isGlass;
    }
    
    public int getLightOpacity()
    {
        return isGlass ? 7 : 15;
    }
    
    public int getRenderBlockPass()
    {
        return isGlass ? 1 : 0;
    }
    
    public EnumWorldBlockLayer getBlockLayer()
    {
    	return isGlass ? EnumWorldBlockLayer.TRANSLUCENT : EnumWorldBlockLayer.SOLID;
    }

	@Override
	public boolean canStabaliseInfusion(World world, BlockPos paramBlockPos) {
		return stabilise;
	}

	@Override
	public Icon getIcon(int side, int meta) {
		return blockIcon;
	}

	@Override
	public Icon getIcon(IBlockAccess world, int x, int y, int z, int side) {
		return getIcon(side,this.getMetaFromState(world.getBlockState(new BlockPos(x,y,z))));
	}

	@Override
	public List<IBlockState> listPossibleStates(Block b) {
		return Arrays.asList(this.getDefaultState());
	}

	@Override
	public void registerBlockIcons(IconRegister ir) {
		blockIcon = ir.registerBlockIcon(iconName);
	}

	@Override
	public int getDCRenderID() {
		return RenderAccessLibrary.RENDER_ID_CUBE;
	}
	
	public TBBlock setBlockTextureName(String tex)
	{
		iconName = tex;
		return this;
	}
} public class TBSidedBlock extends TBBlock {

	public Icon sideIcon;
	
	public TBSidedBlock(Material m, boolean b) {
		super(m, b);
	}
	
    public Icon getIcon(int side, int meta)
    {
    	return side == 0 || side == 1 ? super.getIcon(side, meta) : sideIcon;
    }

    public void registerBlockIcons(IconRegister reg)
    {
    	super.registerBlockIcons(reg);
    	sideIcon = reg.registerBlockIcon(getTextureName()+"_side");
    }
} public class ItemAnvilBlock extends ItemMultiTexture
{
    public ItemAnvilBlock(Block block)
    {
        super(block, block, new String[] {"intact", "slightlyDamaged", "veryDamaged"});
    }

    public int getMetadata(int damage)
    {
        return damage % 3;
    }
} public class ItemBlockCrystalSlab extends ItemTBSlab{

	public ItemBlockCrystalSlab(Block b){
		this(b,(BlockTBSlab)TBBlocks.crystalSlab,(BlockTBSlab)TBBlocks.crystalSlab_full);
	}
	
	public ItemBlockCrystalSlab(Block block, BlockTBSlab singleSlab, BlockTBSlab doubleSlab) {
		super(block, singleSlab, doubleSlab);
	}

} public class ItemBlockHalfSlab extends ItemTBSlab{

	public ItemBlockHalfSlab(Block b){
		this(b,(BlockTBSlab)TBBlocks.genericSlab,(BlockTBSlab)TBBlocks.genericSlab_full);
	}
	
	public ItemBlockHalfSlab(Block block, BlockTBSlab singleSlab, BlockTBSlab doubleSlab) {
		super(block, singleSlab, doubleSlab);
	}

} public class ItemBlockSpike extends ItemBlock{

	public ItemBlockSpike(Block b) {
		super(b);
		this.setHasSubtypes(true);
	}
	
    public String getUnlocalizedName(ItemStack stk)
    {
    	return super.getUnlocalizedName(stk)+ (stk.getItemDamage() >= 6 ? BlockSpike.spikeNames[5] : BlockSpike.spikeNames[stk.getItemDamage()]);
    }
    
    public int getMetadata(int meta)
    {
        return meta;
    }

} public class ItemBlockTBPlanks extends ItemBlock{

	public ItemBlockTBPlanks(Block b) {
		super(b);
		this.setHasSubtypes(true);
	}
	
    public String getUnlocalizedName(ItemStack stk)
    {
    	return "tile."+BlockTBPlanks.names[Math.min(BlockTBPlanks.names.length-1,stk.getItemDamage())];
    }
    
    public int getMetadata(int meta)
    {
        return meta;
    }

} public class ItemBlockTBSapling extends ItemBlock{

	public ItemBlockTBSapling(Block b) {
		super(b);
		this.setHasSubtypes(true);
	}
	
    public String getUnlocalizedName(ItemStack stk)
    {
    	return "tile."+BlockTBSapling.names[Math.min(BlockTBSapling.names.length-1,stk.getItemDamage()%8)];
    }
    
    public int getMetadata(int meta)
    {
        return meta;
    }

} public class ItemBlockWoodSlab extends ItemTBSlab{

	public ItemBlockWoodSlab(Block b){
		this(b,(BlockTBSlab)TBBlocks.woodSlab,(BlockTBSlab)TBBlocks.woodSlab_full);
	}
	
	public ItemBlockWoodSlab(Block block, BlockTBSlab singleSlab, BlockTBSlab doubleSlab) {
		super(block, singleSlab, doubleSlab);
	}

} @Mod(modid = modid, version = version, name = name,dependencies=dependencies)
public class TBCore {
	
	public static final String modid = "thaumicbases";
	public static final String version = "2.1.189.32";
	public static final String name = "Thaumic Bases";
	public static final String serverProxy = "tb.network.proxy.TBServer";
	public static final String clientProxy = "tb.network.proxy.TBClient";
	public static final String dependencies = "required-after:Thaumcraft@[5.1.6,);required-after:Baubles@[1.1.1.0,);required-after:DummyCore@[2.2.189.0,);";

	@SidedProxy(serverSide = serverProxy,clientSide = clientProxy)
	public static TBServer proxy;
	public static SimpleNetworkWrapper network;
	
	public static TBCore instance;
	public static final TBConfig cfg = new TBConfig();
	
	@EventHandler
	public void preInit(FMLPreInitializationEvent event)
	{
		instance = this;
		Core.registerModAbsolute(getClass(), name, event.getModConfigurationDirectory().getAbsolutePath(), cfg);
		setupModInfo(event.getModMetadata());
		TBBlocks.setup();
		TBItems.setup();
		TBEnchant.setup();
		TBTiles.setup();
		FMLInterModComms.sendMessage("Waila", "register", "tb.utils.WAILACompat.callbackRegister");	
	}
	
	@EventHandler
	public void init(FMLInitializationEvent event)
	{
		MinecraftForge.EVENT_BUS.register(new EnchantmentHandler());
		MinecraftForge.EVENT_BUS.register(new TBEventHandler());
		//FMLCommonHandler.instance().bus().register(new TBEventHandler());
		NetworkRegistry.INSTANCE.registerGuiHandler(instance, proxy);
		
		EntityRegistry.registerModEntity(EntityAspectOrb.class, "tb.old.tc.aspectOrb", 0, this, 32, 1, true);
		EntityRegistry.registerModEntity(EntityRevolverBullet.class, "tb.bullet", 1, this, 32, 1, true);
		
		//TBFociUpgrades.init();
		proxy.registerRenderInformation();
		RevolverUpgrade.initConflictingMappings();
		
		network = NetworkRegistry.INSTANCE.newSimpleChannel("thaumbases");
		network.registerMessage(TBNetworkManager.class, PacketTB.class, 0, Side.SERVER);
		network.registerMessage(TBNetworkManager.class, PacketTB.class, 0, Side.CLIENT);
		
	}
	
	@EventHandler
	public void postInit(FMLPostInitializationEvent event)
	{
		TBRecipes.setup();
		TBThaumonomicon.setup();
		CraftingManager.getInstance().addRecipe(new RecipesFragmentAdditions());
	}
	
	public void setupModInfo(ModMetadata meta)
	{
		meta.autogenerated = false;
		meta.modId = modid;
		meta.name = name;
		meta.version = version;
		meta.description = "A huge addon to an amazing mod named Thaumcraft by Azanor";
		ArrayList<String> authors = new ArrayList<String>();
		authors.add("Modbder");
		meta.authorList = authors;
	}
}
import DummyCore.Blocks.BlocksRegistry;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraftforge.oredict.OreDictionary;
import tb.common.block.BlockAshroom;
import tb.common.block.BlockAuraLinker;
import tb.common.block.BlockAureliaLeaf;
import tb.common.block.BlockAureliaPlant;
import tb.common.block.BlockBraizer;
import tb.common.block.BlockBriar;
import tb.common.block.BlockCampfire;
import tb.common.block.BlockCryingObelisk;
import tb.common.block.BlockCrystalBlock;
import tb.common.block.BlockCrystalSlab;
import tb.common.block.BlockFlaxium;
import tb.common.block.BlockHalfSlab;
import tb.common.block.BlockKnose;
import tb.common.block.BlockLucritePlant;
import tb.common.block.BlockNodeManipulator;
import tb.common.block.BlockOverchanter;
import tb.common.block.BlockPyrofluid;
import tb.common.block.BlockRainbowCactus;
import tb.common.block.BlockRedlonStem;
import tb.common.block.BlockSpike;
import tb.common.block.BlockSweed;
import tb.common.block.BlockTBLeaves;
import tb.common.block.BlockTBLog;
import tb.common.block.BlockTBPlanks;
import tb.common.block.BlockTBPlant;
import tb.common.block.BlockTBSapling;
import tb.common.block.BlockThaumicAnvil;
import tb.common.block.BlockVoidAnvil;
import tb.common.block.BlockWoodSlab;
import tb.common.block.TBBlock;
import tb.common.block.TBSidedBlock;
import tb.common.itemblock.ItemAnvilBlock;
import tb.common.itemblock.ItemBlockCrystal;
import tb.common.itemblock.ItemBlockCrystalSlab;
import tb.common.itemblock.ItemBlockHalfSlab;
import tb.common.itemblock.ItemBlockPyrofluid;
import tb.common.itemblock.ItemBlockSpike;
import tb.common.itemblock.ItemBlockTBLeaves;
import tb.common.itemblock.ItemBlockTBLogs;
import tb.common.itemblock.ItemBlockTBPlanks;
import tb.common.itemblock.ItemBlockTBSapling;
import tb.common.itemblock.ItemBlockWoodSlab;
import tb.core.TBCore;
package tb.init;


public class TBBlocks {
	
	public static void setup()
	{
		BlocksRegistry.registerBlock(crystalBlock,"crystalBlock",core, ItemBlockCrystal.class);
		OreDictionary.registerOre("blockCrystalCluster", new ItemStack(crystalBlock,1,OreDictionary.WILDCARD_VALUE));
		BlocksRegistry.registerBlock(genLogs, "genLogs",core,ItemBlockTBLogs.class);
		OreDictionary.registerOre("logWood", new ItemStack(genLogs,1,OreDictionary.WILDCARD_VALUE));
		BlocksRegistry.registerBlock(genLeaves, "genLeaves",core,ItemBlockTBLeaves.class);
		BlocksRegistry.registerBlock(sapling, "goldenOakSapling",core,ItemBlockTBSapling.class);
		OreDictionary.registerOre("treeSapling", sapling);
		BlocksRegistry.registerBlock(planks, "planks",core,ItemBlockTBPlanks.class);
		OreDictionary.registerOre("plankWood", new ItemStack(planks,1,OreDictionary.WILDCARD_VALUE));
		
		BlocksRegistry.registerBlock(quicksilverBlock, "quicksilverBlock",core,ItemBlock.class);
		OreDictionary.registerOre("blockQuicksilver", quicksilverBlock);
		BlocksRegistry.registerBlock(quicksilverBrick, "quicksilverBrick",core,ItemBlock.class);
		OreDictionary.registerOre("blockQuicksilver", quicksilverBrick);
		BlocksRegistry.registerBlock(dustBlock, "blockSalisMundus",core,ItemBlock.class);
		OreDictionary.registerOre("blockSalisMundus", dustBlock);
		BlocksRegistry.registerBlock(thauminiteBlock, "thauminiteBlock",core,ItemBlock.class);
		OreDictionary.registerOre("blockThauminite", thauminiteBlock);
		BlocksRegistry.registerBlock(eldritchArk, "eldritchArk",core,ItemBlock.class);
		BlocksRegistry.registerBlock(ironGreatwood, "ironGreatwood",core,ItemBlock.class);
		
		BlocksRegistry.registerBlock(oldCobble, "oldCobble",core,ItemBlock.class);
		oldCobble.setHarvestLevel("pickaxe", 0);
		OreDictionary.registerOre("cobblestone", oldCobble);
		BlocksRegistry.registerBlock(oldCobbleMossy, "oldCobbleMossy",core,ItemBlock.class);
		oldCobbleMossy.setHarvestLevel("pickaxe", 0);
		OreDictionary.registerOre("cobblestone", oldCobbleMossy);
		OreDictionary.registerOre("mossyCobblestone", oldCobbleMossy);
		BlocksRegistry.registerBlock(oldGravel, "oldGravel",core,ItemBlock.class);
		oldGravel.setHarvestLevel("shovel", 0);
		OreDictionary.registerOre("gravel", oldGravel);
		BlocksRegistry.registerBlock(oldBrick, "oldBrick",core,ItemBlock.class);
		oldBrick.setHarvestLevel("pickaxe", 0);
		OreDictionary.registerOre("brick", oldBrick);
		BlocksRegistry.registerBlock(oldLapis, "oldLapis",core,ItemBlock.class);
		oldLapis.setHarvestLevel("pickaxe", 0);
		OreDictionary.registerOre("blockLapis", oldLapis);
		BlocksRegistry.registerBlock(oldIron, "oldIron",core,ItemBlock.class);
		oldIron.setHarvestLevel("pickaxe", 0);
		OreDictionary.registerOre("blockIron", oldIron);
		BlocksRegistry.registerBlock(oldGold, "oldGold",core,ItemBlock.class);
		oldGold.setHarvestLevel("pickaxe", 0);
		OreDictionary.registerOre("blockGold", oldGold);
		BlocksRegistry.registerBlock(oldDiamond, "oldDiamond",core,ItemBlock.class);
		oldDiamond.setHarvestLevel("pickaxe", 0);
		OreDictionary.registerOre("blockDiamond", oldDiamond);
		
		BlocksRegistry.registerBlock(plax, "plax",core,ItemBlock.class);
		BlocksRegistry.registerBlock(aureliaPetal, "aureliaPetal",core,ItemBlock.class);
		BlocksRegistry.registerBlock(aurelia, "aurelia",core,ItemBlock.class);
		BlocksRegistry.registerBlock(metalleat, "metalleat",core,ItemBlock.class);
		BlocksRegistry.registerBlock(lucrite, "lucrite",core,ItemBlock.class);
		BlocksRegistry.registerBlock(knose, "knose",core,ItemBlock.class);
		BlocksRegistry.registerBlock(sweed, "sweed",core,ItemBlock.class);
		BlocksRegistry.registerBlock(lazullia, "lazullia",core,ItemBlock.class);
		BlocksRegistry.registerBlock(ashroom, "ashroom",core,ItemBlock.class);
		BlocksRegistry.registerBlock(flaxium, "flaxium",core,ItemBlock.class);
		BlocksRegistry.registerBlock(glieonia, "glieonia",core,ItemBlock.class);
		BlocksRegistry.registerBlock(briar, "briar",core,ItemBlock.class);
		BlocksRegistry.registerBlock(tobacco, "tobacco",core,ItemBlock.class);
		BlocksRegistry.registerBlock(voidPlant, "voidPlant",core,ItemBlock.class);
		BlocksRegistry.registerBlock(rainbowCactus, "rainbowCactus",core,ItemBlock.class);
		BlocksRegistry.registerBlock(redlonStem, "redlonStem",core,ItemBlock.class);
		
		BlocksRegistry.registerBlock(spike, "spike",core,ItemBlockSpike.class);
		BlocksRegistry.registerBlock(cryingObsidian, "cryingObsidian",core,ItemBlock.class);
		BlocksRegistry.registerBlock(pyrofluid,"pyrofluid",core, ItemBlockPyrofluid.class);
		BlocksRegistry.registerBlock(thaumicAnvil, "thaumicAnvil",core,ItemAnvilBlock.class);
		BlocksRegistry.registerBlock(voidAnvil, "voidAnvil",core,ItemAnvilBlock.class);
		
		BlocksRegistry.registerBlock(crystalSlab, "crystalSlab",core,ItemBlockCrystalSlab.class);
		BlocksRegistry.registerBlock(crystalSlab_full, "crystalSlab_full",core,ItemBlockCrystalSlab.class);
		BlocksRegistry.registerBlock(genericSlab, "genericSlab",core,ItemBlockHalfSlab.class);