From 8174b0209167100a1df011270f5c40d8c0300361 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= <tseeker@nocternity.net>
Date: Tue, 28 Jun 2016 15:04:46 +0200
Subject: [PATCH] Alloy furnace - More clean-up + activation configuration

---
 graphics/alloy-furnace-gui-3.xcf              | Bin 0 -> 11681 bytes
 src/java/mmm/materials/Materials.java         |  12 ++-
 .../mmm/tech/base/E_TBActivationMode.java     |  24 ++++++
 .../tech/base/I_TBConfigurableActivation.java |  12 +++
 .../tech/base/TBActivationModeMessage.java    |  67 +++++++++++++++
 .../tech/base/TBAlloyFurnaceGuiHandler.java   |  11 ++-
 src/java/mmm/tech/base/TechBase.java          |  29 +------
 .../tech/base/alloy_furnace/AlloyFurnace.java |  41 ++++++++++
 .../TBAFBlock.java}                           |  67 ++++++++-------
 .../TBAFContainer.java}                       |  42 ++++++++--
 .../TBAFGui.java}                             |  76 +++++++++++++-----
 .../TBAFMessage.java}                         |  12 +--
 .../TBAFOutputHopper.java}                    |   8 +-
 .../TBAFTileEntity.java}                      |  65 +++++++++++++--
 src/java/mmm/utils/gui/A_UGTab.java           |  29 ++++---
 .../utils/gui/A_UGTabbedContainerScreen.java  |   6 +-
 src/resources/assets/mmm/lang/en_US.lang      |   5 ++
 .../mmm/textures/gui/alloy_furnace_3.png      | Bin 0 -> 792 bytes
 18 files changed, 385 insertions(+), 121 deletions(-)
 create mode 100644 graphics/alloy-furnace-gui-3.xcf
 create mode 100644 src/java/mmm/tech/base/E_TBActivationMode.java
 create mode 100644 src/java/mmm/tech/base/I_TBConfigurableActivation.java
 create mode 100644 src/java/mmm/tech/base/TBActivationModeMessage.java
 create mode 100644 src/java/mmm/tech/base/alloy_furnace/AlloyFurnace.java
 rename src/java/mmm/tech/base/{TBAlloyFurnaceBlock.java => alloy_furnace/TBAFBlock.java} (84%)
 rename src/java/mmm/tech/base/{TBAlloyFurnaceContainer.java => alloy_furnace/TBAFContainer.java} (78%)
 rename src/java/mmm/tech/base/{TBAlloyFurnaceGui.java => alloy_furnace/TBAFGui.java} (78%)
 rename src/java/mmm/tech/base/{TBAlloyFurnaceMessage.java => alloy_furnace/TBAFMessage.java} (82%)
 rename src/java/mmm/tech/base/{TBAlloyFurnaceOutputHopper.java => alloy_furnace/TBAFOutputHopper.java} (93%)
 rename src/java/mmm/tech/base/{TBAlloyFurnaceTileEntity.java => alloy_furnace/TBAFTileEntity.java} (88%)
 create mode 100644 src/resources/assets/mmm/textures/gui/alloy_furnace_3.png

diff --git a/graphics/alloy-furnace-gui-3.xcf b/graphics/alloy-furnace-gui-3.xcf
new file mode 100644
index 0000000000000000000000000000000000000000..ed6c344caef5f1475aa4f0cada35fa1ae8424b6e
GIT binary patch
literal 11681
zcmeHN&2G~`5FRI0TT)V|<wre$WW<3K>d>A5wJ3oz5)zV6oYK@W7HLu?L26Ep#0mL^
zgv6B>fH$C=EZ%}UPXH2lnQ_*Mt-4T&5T|5T`gXtUU+iyZcgOZx_Wpr(SgUJwyI}%=
zB7q6O3jLs*3y8&sM_;ZHkY7a1A=VI=C8v6qu>KWH3l?^(+xu0^)UCF?hgsCK0>w_Z
z*D$qCt6}f0=ZbZ!)@rocS}{oUwzXT;HcOj9NFZCXXdRpGCNvGpwUY@oJ?tD*Yj)Gp
zw!;6y%wAHa%+p^q?XG4wYtPIMwQtqy9kV;UKx%zFYmgIfN;=4(ybM_&O(1*_%|EL4
z%r+HfWQ}=DNo|2xl$_K)CpjiSs#6^bIYh{pBK&-W=ObK2PW^^q0ZG_C9O-OWh?jM5
z!08eQR5xP)=&ulO;$@k401KZHUjgz@5zhfuKOm0Kc*=;!09W54-UD1OBJKj*=mFfs
zd)6@pcmVf>4<d*ZvF-f;Av{i|S^^%ksUDuhDa2!T_Qp&Ztc{NPQIx@fzHrovm&BX`
zV2us2its%sz=o$798XFCmOeFuW9d_qo|YS3tUyT=;I>d_4!Gz-6p7m|XR=4nPcvuF
z_2PLu@p(&5EW(RGupi3`umY?=S_;gfUmLyWsDDeGx5bHXi{p`80pByWjq!BGy-eH+
zc>E?V`B<%7j-R7`8hq_S;+2h9jP7q*+uSVw?=3HbugXjOx;zyHSp76V)Qr@RI(@Uq
z6C7QT{u1nfBC?);$6a=Ric$Oxxl5-NGP7Og3RU>S=({V#Z;o)teJ}$%hO<<m=Lwei
zbY?VEIMAA9{ztR!Z)B$L^=R4nnZ6HYqYU}jdO>T)+SKRd+~vq@MqA4XN5Pk}&<`do
z-&SM?NPk5CFj|8%BYn`(7<~g&$j0o?r@f2(kN+%tE@Hvi6Hda6Tpt|``w2^Q{27oX
d8g2%swIVtTq2v1hI(9OEoJ$OS3E~wA_yx_8X%zqf

literal 0
HcmV?d00001

diff --git a/src/java/mmm/materials/Materials.java b/src/java/mmm/materials/Materials.java
index 7b44532..0f206dc 100644
--- a/src/java/mmm/materials/Materials.java
+++ b/src/java/mmm/materials/Materials.java
@@ -21,6 +21,7 @@ public class Materials
 	public static final MMetal GOLD;
 	public static final MMetal IRON;
 	public static final MMetal COPPER;
+	//public static final MMetal RED_COPPER;
 
 	public static final Item ITEM_SLAG;
 	public static final Item ITEM_MALACHITE;
@@ -39,6 +40,7 @@ public class Materials
 
 		// Custom metals
 		COPPER = new MMetal( "copper" , 0.4f , 4f , 1 , MapColor.DIRT );
+		//RED_COPPER = new MMetal( "red_copper" , 0f , 2f , 1 , MapColor.RED );
 
 		// Items that do not correspond to metals or ores
 		URegistry.addItem( ITEM_SLAG = Materials.makeItem( "slag" ) );
@@ -56,9 +58,9 @@ public class Materials
 	}
 
 
-	public static Item makeFuel( String name , int burnTime )
+	public static Item makeFuel( final String name , final int burnTime )
 	{
-		Item fuel = makeItem( name );
+		final Item fuel = Materials.makeItem( name );
 		URegistry.setFuel( fuel , burnTime );
 		return fuel;
 	}
@@ -89,8 +91,12 @@ public class Materials
 	public void registerRecipes( )
 	{
 		// Alloy recipes
+		// MAlloyRecipe.build( ).setName( "materials/red_copper" ).setBurnTime( 800 )
+		//		.addInput( Materials.COPPER.INGOT , 1 ).addInput( Items.REDSTONE , 2 )
+		//		.setOutput( Materials.RED_COPPER.INGOT ).setSlag( 1 ).register( );
+		// XXX coke is not an alloy
 		MAlloyRecipe.build( ).setName( "materials/coke" ).setBurnTime( 3200 ).addInput( Items.COAL , 2 )
-				.setOutput( ITEM_COKE ).setSlag( 1 ).register( );
+				.setOutput( Materials.ITEM_COKE ).setSlag( 1 ).register( );
 	}
 
 }
diff --git a/src/java/mmm/tech/base/E_TBActivationMode.java b/src/java/mmm/tech/base/E_TBActivationMode.java
new file mode 100644
index 0000000..cdf2118
--- /dev/null
+++ b/src/java/mmm/tech/base/E_TBActivationMode.java
@@ -0,0 +1,24 @@
+package mmm.tech.base;
+
+
+public enum E_TBActivationMode {
+
+	ALWAYS_ACTIVE ,
+	POWERED ,
+	UNPOWERED ,
+	DISABLED;
+
+	private static final E_TBActivationMode[] VALUES = E_TBActivationMode.values( );
+
+
+	public String getDisplayName( )
+	{
+		return "gui.mmm.tech.base.am." + this.toString( ).toLowerCase( );
+	}
+
+
+	public E_TBActivationMode next( )
+	{
+		return E_TBActivationMode.VALUES[ ( this.ordinal( ) + 1 ) % E_TBActivationMode.VALUES.length ];
+	}
+}
diff --git a/src/java/mmm/tech/base/I_TBConfigurableActivation.java b/src/java/mmm/tech/base/I_TBConfigurableActivation.java
new file mode 100644
index 0000000..da68d52
--- /dev/null
+++ b/src/java/mmm/tech/base/I_TBConfigurableActivation.java
@@ -0,0 +1,12 @@
+package mmm.tech.base;
+
+
+public interface I_TBConfigurableActivation
+{
+
+	public E_TBActivationMode getActivationMode( );
+
+
+	public void setActivationMode( E_TBActivationMode mode );
+
+}
diff --git a/src/java/mmm/tech/base/TBActivationModeMessage.java b/src/java/mmm/tech/base/TBActivationModeMessage.java
new file mode 100644
index 0000000..f3c9650
--- /dev/null
+++ b/src/java/mmm/tech/base/TBActivationModeMessage.java
@@ -0,0 +1,67 @@
+package mmm.tech.base;
+
+
+import io.netty.buffer.ByteBuf;
+import mmm.utils.I_UMessage;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.inventory.Container;
+
+
+
+public class TBActivationModeMessage
+		implements I_UMessage
+{
+	private E_TBActivationMode mode;
+
+
+	public TBActivationModeMessage( )
+	{
+		// EMPTY
+	}
+
+
+	public TBActivationModeMessage( final E_TBActivationMode mode )
+	{
+		this.mode = mode;
+	}
+
+
+	@Override
+	public void fromBytes( final ByteBuf buf )
+	{
+		switch ( buf.readByte( ) ) {
+			default:
+				// XXX warning
+			case 0:
+				this.mode = E_TBActivationMode.ALWAYS_ACTIVE;
+				break;
+			case 1:
+				this.mode = E_TBActivationMode.POWERED;
+				break;
+			case 2:
+				this.mode = E_TBActivationMode.UNPOWERED;
+				break;
+			case 3:
+				this.mode = E_TBActivationMode.DISABLED;
+				break;
+		}
+	}
+
+
+	@Override
+	public void toBytes( final ByteBuf buf )
+	{
+		buf.writeByte( this.mode.ordinal( ) );
+	}
+
+
+	@Override
+	public void handleOnServer( final EntityPlayerMP player )
+	{
+		final Container curCont = player.openContainer;
+		if ( curCont instanceof I_TBConfigurableActivation ) {
+			( (I_TBConfigurableActivation) curCont ).setActivationMode( this.mode );
+		}
+	}
+
+}
diff --git a/src/java/mmm/tech/base/TBAlloyFurnaceGuiHandler.java b/src/java/mmm/tech/base/TBAlloyFurnaceGuiHandler.java
index c6dea30..b844952 100644
--- a/src/java/mmm/tech/base/TBAlloyFurnaceGuiHandler.java
+++ b/src/java/mmm/tech/base/TBAlloyFurnaceGuiHandler.java
@@ -1,6 +1,9 @@
 package mmm.tech.base;
 
 
+import mmm.tech.base.alloy_furnace.TBAFContainer;
+import mmm.tech.base.alloy_furnace.TBAFGui;
+import mmm.tech.base.alloy_furnace.TBAFTileEntity;
 import net.minecraft.entity.player.EntityPlayer;
 import net.minecraft.tileentity.TileEntity;
 import net.minecraft.util.math.BlockPos;
@@ -21,8 +24,8 @@ public class TBAlloyFurnaceGuiHandler
 	{
 		final BlockPos pos = new BlockPos( x , y , z );
 		final TileEntity tileEntity = world.getTileEntity( pos );
-		if ( tileEntity instanceof TBAlloyFurnaceTileEntity ) {
-			return new TBAlloyFurnaceContainer( player.inventory , (TBAlloyFurnaceTileEntity) tileEntity );
+		if ( tileEntity instanceof TBAFTileEntity ) {
+			return new TBAFContainer( player.inventory , (TBAFTileEntity) tileEntity );
 		}
 		return null;
 	}
@@ -34,8 +37,8 @@ public class TBAlloyFurnaceGuiHandler
 			final int y , final int z )
 	{
 		final TileEntity tileEntity = world.getTileEntity( new BlockPos( x , y , z ) );
-		if ( tileEntity instanceof TBAlloyFurnaceTileEntity ) {
-			return new TBAlloyFurnaceGui( player.inventory , (TBAlloyFurnaceTileEntity) tileEntity );
+		if ( tileEntity instanceof TBAFTileEntity ) {
+			return new TBAFGui( player.inventory , (TBAFTileEntity) tileEntity );
 		}
 		return null;
 	}
diff --git a/src/java/mmm/tech/base/TechBase.java b/src/java/mmm/tech/base/TechBase.java
index 9e480d1..adb742c 100644
--- a/src/java/mmm/tech/base/TechBase.java
+++ b/src/java/mmm/tech/base/TechBase.java
@@ -1,39 +1,18 @@
 package mmm.tech.base;
 
 
-import mmm.Mmm;
-import mmm.materials.MAlloyRecipe;
+import mmm.tech.base.alloy_furnace.AlloyFurnace;
 import mmm.utils.URegistry;
-import net.minecraft.init.Items;
-import net.minecraft.item.Item;
-import net.minecraft.item.ItemBlockSpecial;
-import net.minecraftforge.fml.common.network.NetworkRegistry;
-import net.minecraftforge.fml.common.registry.GameRegistry;
 
 
 
 public class TechBase
 {
-	public static final TBAlloyFurnaceBlock ALLOY_FURNACE_BLOCK_INACTIVE;
-	public static final TBAlloyFurnaceBlock ALLOY_FURNACE_BLOCK_ACTIVE;
-	public static final Item ALLOY_FURNACE_ITEM;
+	public static final AlloyFurnace ALLOY_FURNACE;
 
 	static {
-		ALLOY_FURNACE_BLOCK_INACTIVE = new TBAlloyFurnaceBlock( false );
-		ALLOY_FURNACE_BLOCK_ACTIVE = new TBAlloyFurnaceBlock( true );
-		ALLOY_FURNACE_ITEM = new ItemBlockSpecial( TechBase.ALLOY_FURNACE_BLOCK_INACTIVE )//
-				.setMaxStackSize( 16 )//
-				.setCreativeTab( TechBase.ALLOY_FURNACE_BLOCK_INACTIVE.getCreativeTabToDisplayOn( ) );
-		URegistry.setIdentifiers( TechBase.ALLOY_FURNACE_ITEM , "tech" , "base" , "alloy_furnace" );
-		URegistry.addBlock( TechBase.ALLOY_FURNACE_BLOCK_INACTIVE , TechBase.ALLOY_FURNACE_ITEM );
-		URegistry.addBlock( TechBase.ALLOY_FURNACE_BLOCK_ACTIVE , null );
-		GameRegistry.registerTileEntity( TBAlloyFurnaceTileEntity.class , "mmm:tech/base/alloy_furnace" );
-		NetworkRegistry.INSTANCE.registerGuiHandler( Mmm.get( ) , new TBAlloyFurnaceGuiHandler( ) );
-		URegistry.addServerMessage( TBAlloyFurnaceMessage.class );
-
-		// FIXME test, remove this later
-		MAlloyRecipe.build( ).setName( "test" ).setBurnTime( 50 ).setSlag( 1 ).setOutput( Items.COOKED_CHICKEN , 10 )
-				.addInput( Items.COOKED_BEEF ).addInput( Items.COOKED_PORKCHOP ).register( );
+		URegistry.addServerMessage( TBActivationModeMessage.class );
+		ALLOY_FURNACE = AlloyFurnace.INSTANCE;
 	}
 
 
diff --git a/src/java/mmm/tech/base/alloy_furnace/AlloyFurnace.java b/src/java/mmm/tech/base/alloy_furnace/AlloyFurnace.java
new file mode 100644
index 0000000..e4ac24b
--- /dev/null
+++ b/src/java/mmm/tech/base/alloy_furnace/AlloyFurnace.java
@@ -0,0 +1,41 @@
+package mmm.tech.base.alloy_furnace;
+
+
+import mmm.Mmm;
+import mmm.tech.base.TBAlloyFurnaceGuiHandler;
+import mmm.utils.URegistry;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemBlockSpecial;
+import net.minecraftforge.fml.common.network.NetworkRegistry;
+import net.minecraftforge.fml.common.registry.GameRegistry;
+
+
+
+public enum AlloyFurnace {
+
+	INSTANCE;
+
+	public final TBAFBlock INACTIVE;
+	public final TBAFBlock ACTIVE;
+	public final Item ITEM;
+
+
+	private AlloyFurnace( )
+	{
+		this.INACTIVE = new TBAFBlock( false );
+		this.ACTIVE = new TBAFBlock( true );
+
+		this.ITEM = new ItemBlockSpecial( this.INACTIVE )//
+				.setMaxStackSize( 16 )//
+				.setCreativeTab( this.INACTIVE.getCreativeTabToDisplayOn( ) );
+		URegistry.setIdentifiers( this.ITEM , "tech" , "base" , "alloy_furnace" );
+
+		URegistry.addBlock( this.INACTIVE , this.ITEM );
+		URegistry.addBlock( this.ACTIVE , null );
+		GameRegistry.registerTileEntity( TBAFTileEntity.class , "mmm:tech/base/alloy_furnace" );
+		// FIXME
+		NetworkRegistry.INSTANCE.registerGuiHandler( Mmm.get( ) , new TBAlloyFurnaceGuiHandler( ) );
+		URegistry.addServerMessage( TBAFMessage.class );
+	}
+
+}
diff --git a/src/java/mmm/tech/base/TBAlloyFurnaceBlock.java b/src/java/mmm/tech/base/alloy_furnace/TBAFBlock.java
similarity index 84%
rename from src/java/mmm/tech/base/TBAlloyFurnaceBlock.java
rename to src/java/mmm/tech/base/alloy_furnace/TBAFBlock.java
index a3826ba..895d66f 100644
--- a/src/java/mmm/tech/base/TBAlloyFurnaceBlock.java
+++ b/src/java/mmm/tech/base/alloy_furnace/TBAFBlock.java
@@ -1,4 +1,4 @@
-package mmm.tech.base;
+package mmm.tech.base.alloy_furnace;
 
 
 import java.util.List;
@@ -48,7 +48,7 @@ import net.minecraftforge.fml.relauncher.SideOnly;
 
 
 
-public class TBAlloyFurnaceBlock
+public class TBAFBlock
 		extends BlockContainer
 		implements I_URecipeRegistrar
 {
@@ -63,7 +63,7 @@ public class TBAlloyFurnaceBlock
 	public final boolean active;
 
 
-	public TBAlloyFurnaceBlock( final boolean active )
+	public TBAFBlock( final boolean active )
 	{
 		super( Material.ROCK );
 		this.active = active;
@@ -80,8 +80,8 @@ public class TBAlloyFurnaceBlock
 		this.lightValue = active ? 13 : 0;
 
 		this.setDefaultState( this.blockState.getBaseState( ) //
-				.withProperty( TBAlloyFurnaceBlock.FACING , EnumFacing.NORTH ) //
-				.withProperty( TBAlloyFurnaceBlock.POWERED , Boolean.valueOf( false ) ) );
+				.withProperty( TBAFBlock.FACING , EnumFacing.NORTH ) //
+				.withProperty( TBAFBlock.POWERED , Boolean.valueOf( false ) ) );
 
 		URegistry.setIdentifiers( this , "tech" , "base" , "alloy_furnace" , active ? "active" : "inactive" );
 	}
@@ -91,7 +91,7 @@ public class TBAlloyFurnaceBlock
 	public void registerRecipes( )
 	{
 		if ( !this.active ) {
-			GameRegistry.addShapedRecipe( new ItemStack( TechBase.ALLOY_FURNACE_ITEM ) , //
+			GameRegistry.addShapedRecipe( new ItemStack( AlloyFurnace.INSTANCE.ITEM ) , //
 					"BBB" , //
 					"BFB" , //
 					"BBB" , //
@@ -108,7 +108,7 @@ public class TBAlloyFurnaceBlock
 	@Override
 	public TileEntity createNewTileEntity( final World worldIn , final int meta )
 	{
-		return new TBAlloyFurnaceTileEntity( );
+		return new TBAFTileEntity( );
 	}
 
 
@@ -117,19 +117,19 @@ public class TBAlloyFurnaceBlock
 		final IBlockState iblockstate = world.getBlockState( pos );
 		final TileEntity tileentity = world.getTileEntity( pos );
 
-		TBAlloyFurnaceBlock.keepInventory = true;
+		TBAFBlock.keepInventory = true;
 		IBlockState nState;
 		Block nBlock;
 		if ( burning ) {
-			nBlock = TechBase.ALLOY_FURNACE_BLOCK_ACTIVE;
+			nBlock = AlloyFurnace.INSTANCE.ACTIVE;
 		} else {
-			nBlock = TechBase.ALLOY_FURNACE_BLOCK_INACTIVE;
+			nBlock = AlloyFurnace.INSTANCE.INACTIVE;
 		}
 		nState = nBlock.getDefaultState( ) //
-				.withProperty( TBAlloyFurnaceBlock.FACING , iblockstate.getValue( TBAlloyFurnaceBlock.FACING ) ) //
-				.withProperty( TBAlloyFurnaceBlock.POWERED , iblockstate.getValue( TBAlloyFurnaceBlock.POWERED ) );
+				.withProperty( TBAFBlock.FACING , iblockstate.getValue( TBAFBlock.FACING ) ) //
+				.withProperty( TBAFBlock.POWERED , iblockstate.getValue( TBAFBlock.POWERED ) );
 		world.setBlockState( pos , nState , 3 );
-		TBAlloyFurnaceBlock.keepInventory = false;
+		TBAFBlock.keepInventory = false;
 
 		if ( tileentity != null ) {
 			tileentity.validate( );
@@ -214,7 +214,7 @@ public class TBAlloyFurnaceBlock
 		final double pSide = ( rand.nextDouble( ) - .5 ) * 10. / 16.;
 
 		double spawnX , spawnZ;
-		switch ( stateIn.getValue( TBAlloyFurnaceBlock.FACING ) ) {
+		switch ( stateIn.getValue( TBAFBlock.FACING ) ) {
 			case WEST:
 				spawnX = cx - frontOffset;
 				spawnZ = cz + pSide;
@@ -251,8 +251,8 @@ public class TBAlloyFurnaceBlock
 	public void addCollisionBoxToList( final IBlockState state , final World worldIn , final BlockPos pos ,
 			final AxisAlignedBB entityBox , final List< AxisAlignedBB > collidingBoxes , final Entity entityIn )
 	{
-		Block.addCollisionBoxToList( pos , entityBox , collidingBoxes , TBAlloyFurnaceBlock.AABB_TOP );
-		Block.addCollisionBoxToList( pos , entityBox , collidingBoxes , TBAlloyFurnaceBlock.AABB_BOTTOM );
+		Block.addCollisionBoxToList( pos , entityBox , collidingBoxes , TBAFBlock.AABB_TOP );
+		Block.addCollisionBoxToList( pos , entityBox , collidingBoxes , TBAFBlock.AABB_BOTTOM );
 	}
 
 
@@ -264,7 +264,7 @@ public class TBAlloyFurnaceBlock
 	@Nullable
 	public Item getItemDropped( final IBlockState state , final Random rand , final int fortune )
 	{
-		return TechBase.ALLOY_FURNACE_ITEM;
+		return AlloyFurnace.INSTANCE.ITEM;
 	}
 
 
@@ -276,7 +276,7 @@ public class TBAlloyFurnaceBlock
 	protected BlockStateContainer createBlockState( )
 	{
 		return new BlockStateContainer( this , new IProperty[] {
-				TBAlloyFurnaceBlock.FACING , TBAlloyFurnaceBlock.POWERED
+				TBAFBlock.FACING , TBAFBlock.POWERED
 		} );
 	}
 
@@ -292,16 +292,16 @@ public class TBAlloyFurnaceBlock
 		}
 
 		return this.getDefaultState( ) //
-				.withProperty( TBAlloyFurnaceBlock.FACING , enumfacing ) //
-				.withProperty( TBAlloyFurnaceBlock.POWERED , powered );
+				.withProperty( TBAFBlock.FACING , enumfacing ) //
+				.withProperty( TBAFBlock.POWERED , powered );
 	}
 
 
 	@Override
 	public int getMetaFromState( final IBlockState state )
 	{
-		return state.getValue( TBAlloyFurnaceBlock.FACING ).getIndex( ) //
-				| ( state.getValue( TBAlloyFurnaceBlock.POWERED ) ? 8 : 0 );
+		return state.getValue( TBAFBlock.FACING ).getIndex( ) //
+				| ( state.getValue( TBAFBlock.POWERED ) ? 8 : 0 );
 	}
 
 
@@ -310,22 +310,21 @@ public class TBAlloyFurnaceBlock
 			final float hitX , final float hitY , final float hitZ , final int meta , final EntityLivingBase placer )
 	{
 		return this.getDefaultState( ).withProperty( //
-				TBAlloyFurnaceBlock.FACING , placer.getHorizontalFacing( ).getOpposite( ) );
+				TBAFBlock.FACING , placer.getHorizontalFacing( ).getOpposite( ) );
 	}
 
 
 	@Override
 	public IBlockState withRotation( final IBlockState state , final Rotation rot )
 	{
-		return state.withProperty( TBAlloyFurnaceBlock.FACING ,
-				rot.rotate( state.getValue( TBAlloyFurnaceBlock.FACING ) ) );
+		return state.withProperty( TBAFBlock.FACING , rot.rotate( state.getValue( TBAFBlock.FACING ) ) );
 	}
 
 
 	@Override
 	public IBlockState withMirror( final IBlockState state , final Mirror mirrorIn )
 	{
-		return state.withRotation( mirrorIn.toRotation( state.getValue( TBAlloyFurnaceBlock.FACING ) ) );
+		return state.withRotation( mirrorIn.toRotation( state.getValue( TBAFBlock.FACING ) ) );
 	}
 
 
@@ -351,7 +350,7 @@ public class TBAlloyFurnaceBlock
 			final float hitX , final float hitY , final float hitZ )
 	{
 		final TileEntity te = worldIn.getTileEntity( pos );
-		if ( ! ( te instanceof TBAlloyFurnaceTileEntity ) || playerIn.isSneaking( ) ) {
+		if ( ! ( te instanceof TBAFTileEntity ) || playerIn.isSneaking( ) ) {
 			return false;
 		}
 		playerIn.openGui( Mmm.get( ) , 0 , worldIn , pos.getX( ) , pos.getY( ) , pos.getZ( ) );
@@ -362,10 +361,10 @@ public class TBAlloyFurnaceBlock
 	@Override
 	public void breakBlock( final World worldIn , final BlockPos pos , final IBlockState state )
 	{
-		if ( !TBAlloyFurnaceBlock.keepInventory ) {
+		if ( !TBAFBlock.keepInventory ) {
 			final TileEntity tileEntity = worldIn.getTileEntity( pos );
-			if ( tileEntity instanceof TBAlloyFurnaceTileEntity ) {
-				final TBAlloyFurnaceTileEntity afte = (TBAlloyFurnaceTileEntity) tileEntity;
+			if ( tileEntity instanceof TBAFTileEntity ) {
+				final TBAFTileEntity afte = (TBAFTileEntity) tileEntity;
 				afte.cancelAlloying( );
 				InventoryHelper.dropInventoryItems( worldIn , pos , afte.input );
 				InventoryHelper.dropInventoryItems( worldIn , pos , afte.fuel );
@@ -393,10 +392,10 @@ public class TBAlloyFurnaceBlock
 	public int getComparatorInputOverride( final IBlockState blockState , final World worldIn , final BlockPos pos )
 	{
 		final TileEntity te = worldIn.getTileEntity( pos );
-		if ( ! ( te instanceof TBAlloyFurnaceTileEntity ) ) {
+		if ( ! ( te instanceof TBAFTileEntity ) ) {
 			return 0;
 		}
-		return Container.calcRedstoneFromInventory( ( (TBAlloyFurnaceTileEntity) te ).output );
+		return Container.calcRedstoneFromInventory( ( (TBAFTileEntity) te ).output );
 	}
 
 
@@ -418,8 +417,8 @@ public class TBAlloyFurnaceBlock
 	private void checkIfPowered( final IBlockState state , final World worldIn , final BlockPos pos )
 	{
 		final boolean powered = worldIn.isBlockPowered( pos );
-		if ( powered != state.getValue( TBAlloyFurnaceBlock.POWERED ).booleanValue( ) ) {
-			worldIn.setBlockState( pos , state.withProperty( TBAlloyFurnaceBlock.POWERED , powered ) , 4 );
+		if ( powered != state.getValue( TBAFBlock.POWERED ).booleanValue( ) ) {
+			worldIn.setBlockState( pos , state.withProperty( TBAFBlock.POWERED , powered ) , 4 );
 		}
 	}
 
diff --git a/src/java/mmm/tech/base/TBAlloyFurnaceContainer.java b/src/java/mmm/tech/base/alloy_furnace/TBAFContainer.java
similarity index 78%
rename from src/java/mmm/tech/base/TBAlloyFurnaceContainer.java
rename to src/java/mmm/tech/base/alloy_furnace/TBAFContainer.java
index d3c9de7..83c61d3 100644
--- a/src/java/mmm/tech/base/TBAlloyFurnaceContainer.java
+++ b/src/java/mmm/tech/base/alloy_furnace/TBAFContainer.java
@@ -1,9 +1,13 @@
-package mmm.tech.base;
+package mmm.tech.base.alloy_furnace;
 
 
 import mmm.materials.MAlloyRecipe;
+import mmm.tech.base.E_TBActivationMode;
+import mmm.tech.base.I_TBConfigurableActivation;
+import mmm.tech.base.TBActivationModeMessage;
 import mmm.utils.UInventoryDisplay;
 import mmm.utils.UInventoryGrid;
+import mmm.utils.URegistry;
 import mmm.utils.gui.UGContainer;
 import mmm.utils.gui.UGSlotDisplay;
 import mmm.utils.gui.UGSlotFuel;
@@ -12,6 +16,7 @@ import net.minecraft.entity.player.EntityPlayer;
 import net.minecraft.entity.player.InventoryPlayer;
 import net.minecraft.inventory.Slot;
 import net.minecraft.item.ItemStack;
+import net.minecraft.tileentity.TileEntity;
 import net.minecraft.tileentity.TileEntityFurnace;
 import net.minecraft.util.ResourceLocation;
 import net.minecraft.util.math.BlockPos;
@@ -19,10 +24,11 @@ import net.minecraft.world.World;
 
 
 
-public class TBAlloyFurnaceContainer
+public class TBAFContainer
 		extends UGContainer
+		implements I_TBConfigurableActivation
 {
-	public final TBAlloyFurnaceTileEntity tileEntity;
+	public final TBAFTileEntity tileEntity;
 	public final World world;
 	public final BlockPos position;
 
@@ -32,7 +38,7 @@ public class TBAlloyFurnaceContainer
 	public final UInventoryDisplay recipe;
 
 
-	public TBAlloyFurnaceContainer( final InventoryPlayer playerInv , final TBAlloyFurnaceTileEntity tileEntity )
+	public TBAFContainer( final InventoryPlayer playerInv , final TBAFTileEntity tileEntity )
 	{
 		this.tileEntity = tileEntity;
 		this.world = tileEntity.getWorld( );
@@ -59,15 +65,13 @@ public class TBAlloyFurnaceContainer
 		this.addSlotToContainer( new UGSlotDisplay( this.recipe , 6 , 131 , 49 ) );
 
 		this.slotGroups.endGroups( );
-		this.slotGroups.showGroup( 0 ); // FIXME remove this
-		this.slotGroups.showGroup( 1 );
 	}
 
 
 	@Override
 	public boolean canInteractWith( final EntityPlayer player )
 	{
-		return this.world.getBlockState( this.position ).getBlock( ) instanceof TBAlloyFurnaceBlock
+		return this.world.getBlockState( this.position ).getBlock( ) instanceof TBAFBlock
 				&& player.getDistanceSq( this.position.getX( ) + .5 , this.position.getY( ) + .5 ,
 						this.position.getZ( ) + .5 ) <= 64.;
 	}
@@ -148,4 +152,28 @@ public class TBAlloyFurnaceContainer
 		}
 	}
 
+
+	@Override
+	public E_TBActivationMode getActivationMode( )
+	{
+		final TileEntity te = this.world.getTileEntity( this.position );
+		if ( te instanceof TBAFTileEntity ) {
+			return ( (TBAFTileEntity) te ).getActivationMode( );
+		}
+		return E_TBActivationMode.DISABLED;
+	}
+
+
+	@Override
+	public void setActivationMode( final E_TBActivationMode mode )
+	{
+		final TileEntity te = this.world.getTileEntity( this.position );
+		if ( te instanceof TBAFTileEntity ) {
+			( (TBAFTileEntity) te ).setActivationMode( mode );
+		}
+		if ( this.world.isRemote ) {
+			URegistry.network.sendToServer( new TBActivationModeMessage( mode ) );
+		}
+	}
+
 }
diff --git a/src/java/mmm/tech/base/TBAlloyFurnaceGui.java b/src/java/mmm/tech/base/alloy_furnace/TBAFGui.java
similarity index 78%
rename from src/java/mmm/tech/base/TBAlloyFurnaceGui.java
rename to src/java/mmm/tech/base/alloy_furnace/TBAFGui.java
index 256843f..ca89205 100644
--- a/src/java/mmm/tech/base/TBAlloyFurnaceGui.java
+++ b/src/java/mmm/tech/base/alloy_furnace/TBAFGui.java
@@ -1,4 +1,4 @@
-package mmm.tech.base;
+package mmm.tech.base.alloy_furnace;
 
 
 import java.util.ArrayList;
@@ -22,8 +22,8 @@ import net.minecraftforge.fml.relauncher.SideOnly;
 
 
 @SideOnly( Side.CLIENT )
-public class TBAlloyFurnaceGui
-		extends A_UGTabbedContainerScreen< TBAlloyFurnaceContainer >
+public class TBAFGui
+		extends A_UGTabbedContainerScreen< TBAFContainer >
 {
 	private static final ResourceLocation TEXTURES[] = {
 			new ResourceLocation( Mmm.ID , "textures/gui/alloy_furnace_1.png" ) ,
@@ -39,7 +39,7 @@ public class TBAlloyFurnaceGui
 		private MainTab( )
 		{
 			super( );
-			this.setBackground( TBAlloyFurnaceGui.TEXTURES[ 0 ] ) //
+			this.setBackground( TBAFGui.TEXTURES[ 0 ] ) //
 					.setHeight( 194 ) //
 					.setIconPosition( 191 , 0 )//
 					.setSlotGroups( 0 , 1 ) //
@@ -55,10 +55,10 @@ public class TBAlloyFurnaceGui
 			final int x = ( this.parent.width - this.parent.getXSize( ) ) / 2;
 			final int y = ( this.parent.height - this.height ) / 2;
 
-			final TBAlloyFurnaceContainer container = (TBAlloyFurnaceContainer) this.parent.container;
+			final TBAFContainer container = (TBAFContainer) this.parent.container;
 			final TileEntity atPos = container.world.getTileEntity( container.position );
-			if ( atPos instanceof TBAlloyFurnaceTileEntity ) {
-				final TBAlloyFurnaceTileEntity te = (TBAlloyFurnaceTileEntity) atPos;
+			if ( atPos instanceof TBAFTileEntity ) {
+				final TBAFTileEntity te = (TBAFTileEntity) atPos;
 				// Burn
 				if ( te.isBurning( ) ) {
 					final int burn = te.getBurnProgress( 13 );
@@ -89,7 +89,7 @@ public class TBAlloyFurnaceGui
 		private RecipeTab( )
 		{
 			super( );
-			this.setBackground( TBAlloyFurnaceGui.TEXTURES[ 1 ] ) //
+			this.setBackground( TBAFGui.TEXTURES[ 1 ] ) //
 					.setHeight( 194 ) //
 					.setIconPosition( 207 , 0 )//
 					.setSlotGroups( 0 , 2 ) //
@@ -112,9 +112,7 @@ public class TBAlloyFurnaceGui
 			this.tfSearch.setDisabledTextColour( 0x7f7f7f );
 			this.tfSearch.setEnableBackgroundDrawing( true );
 			this.tfSearch.setMaxStringLength( 30 );
-
-			this.bPrevious.visible = this.bNext.visible = this.bConfirm.visible = false;
-			this.tfSearch.setVisible( false );
+			this.tfSearch.setVisible( this.isSelected( ) );
 
 			this.buttons.add( this.bNext );
 			this.buttons.add( this.bPrevious );
@@ -161,7 +159,7 @@ public class TBAlloyFurnaceGui
 		public boolean onKeyTyped( final char typedChar , final int keyCode )
 		{
 			if ( this.tfSearch.textboxKeyTyped( typedChar , keyCode ) ) {
-				( (TBAlloyFurnaceGui) this.parent ).handleFiltering( this.tfSearch.getText( ) );
+				( (TBAFGui) this.parent ).handleFiltering( this.tfSearch.getText( ) );
 				return true;
 			}
 			return false;
@@ -171,7 +169,7 @@ public class TBAlloyFurnaceGui
 		@Override
 		public boolean onActionPerformed( final GuiButton button )
 		{
-			final TBAlloyFurnaceGui gui = (TBAlloyFurnaceGui) this.parent;
+			final TBAFGui gui = (TBAFGui) this.parent;
 			if ( button == this.bNext ) {
 				gui.setRecipe( gui.currentRecipe + 1 );
 			} else if ( button == this.bPrevious ) {
@@ -179,7 +177,7 @@ public class TBAlloyFurnaceGui
 			} else if ( button == this.bConfirm ) {
 				final MAlloyRecipe recipe = gui.recipes.get( gui.currentRecipe );
 				URegistry.network.sendToServer( //
-						new TBAlloyFurnaceMessage( gui.container.position , recipe.name , true ) );
+						new TBAFMessage( gui.container.position , recipe.name , true ) );
 				gui.container.tileEntity.recipe = recipe;
 			} else {
 				return false;
@@ -196,7 +194,7 @@ public class TBAlloyFurnaceGui
 				return;
 			}
 
-			final TBAlloyFurnaceGui gui = (TBAlloyFurnaceGui) this.parent;
+			final TBAFGui gui = (TBAFGui) this.parent;
 			if ( gui.recipes.isEmpty( ) ) {
 				this.bNext.enabled = this.bPrevious.enabled = this.bConfirm.enabled = false;
 			} else {
@@ -212,16 +210,56 @@ public class TBAlloyFurnaceGui
 	private static class ConfigTab
 			extends A_UGTab
 	{
+		private GuiButton bActivationMode;
+
 
 		private ConfigTab( )
 		{
 			super( );
-			this.setBackground( TBAlloyFurnaceGui.TEXTURES[ 2 ] ) //
+			this.setBackground( TBAFGui.TEXTURES[ 2 ] ) //
 					.setHeight( 194 ) //
 					.setIconPosition( 223 , 0 )//
 					.setSlotGroups( ) //
 					.setTooltip( "gui.mmm.configure" );
 		}
+
+
+		@Override
+		public void initGui( final int x , final int y )
+		{
+			super.initGui( x , y );
+
+			this.bActivationMode = new GuiButton( 100 , x + 10 , y + 10 , this.parent.getXSize( ) - 20 , 20 ,
+					this.getActivationText( ) );
+			this.buttons.add( this.bActivationMode );
+		}
+
+
+		@Override
+		public void drawBackground( final float partialTicks , final int mouseX , final int mouseY )
+		{
+			this.bActivationMode.displayString = this.getActivationText( );
+			super.drawBackground( partialTicks , mouseX , mouseY );
+		}
+
+
+		@Override
+		public boolean onActionPerformed( final GuiButton button )
+		{
+			if ( button == this.bActivationMode ) {
+				final TBAFContainer cont = (TBAFContainer) this.parent.container;
+				cont.setActivationMode( cont.getActivationMode( ).next( ) );
+				return true;
+			}
+			return super.onActionPerformed( button );
+		}
+
+
+		private String getActivationText( )
+		{
+			return I18n.format( ( (TBAFContainer) this.parent.container ).getActivationMode( ).getDisplayName( ) );
+		}
+
 	}
 
 	private ArrayList< MAlloyRecipe > recipes;
@@ -229,9 +267,9 @@ public class TBAlloyFurnaceGui
 	private String searchString = "";
 
 
-	public TBAlloyFurnaceGui( final InventoryPlayer inventoryPlayer , final TBAlloyFurnaceTileEntity tileEntity )
+	public TBAFGui( final InventoryPlayer inventoryPlayer , final TBAFTileEntity tileEntity )
 	{
-		super( new TBAlloyFurnaceContainer( inventoryPlayer , tileEntity ) , TBAlloyFurnaceGui.TEXTURES[ 0 ] , //
+		super( new TBAFContainer( inventoryPlayer , tileEntity ) , TBAFGui.TEXTURES[ 0 ] , //
 				new MainTab( ) , //
 				new RecipeTab( ) , //
 				new ConfigTab( ) );
@@ -258,7 +296,7 @@ public class TBAlloyFurnaceGui
 
 		this.container.setCurrentRecipe( rName , false );
 		URegistry.network.sendToServer( //
-				new TBAlloyFurnaceMessage( this.container.position , rName , false ) );
+				new TBAFMessage( this.container.position , rName , false ) );
 		( (RecipeTab) this.tabs[ 1 ] ).enableButtons( );
 	}
 
diff --git a/src/java/mmm/tech/base/TBAlloyFurnaceMessage.java b/src/java/mmm/tech/base/alloy_furnace/TBAFMessage.java
similarity index 82%
rename from src/java/mmm/tech/base/TBAlloyFurnaceMessage.java
rename to src/java/mmm/tech/base/alloy_furnace/TBAFMessage.java
index 8f85e45..4a32d4f 100644
--- a/src/java/mmm/tech/base/TBAlloyFurnaceMessage.java
+++ b/src/java/mmm/tech/base/alloy_furnace/TBAFMessage.java
@@ -1,4 +1,4 @@
-package mmm.tech.base;
+package mmm.tech.base.alloy_furnace;
 
 
 import io.netty.buffer.ByteBuf;
@@ -11,7 +11,7 @@ import net.minecraftforge.fml.common.network.ByteBufUtils;
 
 
 
-public class TBAlloyFurnaceMessage
+public class TBAFMessage
 		implements I_UMessage
 {
 	private BlockPos blockPos;
@@ -19,13 +19,13 @@ public class TBAlloyFurnaceMessage
 	private boolean confirm;
 
 
-	public TBAlloyFurnaceMessage( )
+	public TBAFMessage( )
 	{
 		// EMPTY
 	}
 
 
-	public TBAlloyFurnaceMessage( final BlockPos blockPos , final ResourceLocation selected , final boolean confirm )
+	public TBAFMessage( final BlockPos blockPos , final ResourceLocation selected , final boolean confirm )
 	{
 		this.blockPos = blockPos;
 		this.selected = selected;
@@ -66,8 +66,8 @@ public class TBAlloyFurnaceMessage
 	public void handleOnServer( final EntityPlayerMP player )
 	{
 		final Container curCont = player.openContainer;
-		if ( curCont instanceof TBAlloyFurnaceContainer ) {
-			final TBAlloyFurnaceContainer container = (TBAlloyFurnaceContainer) curCont;
+		if ( curCont instanceof TBAFContainer ) {
+			final TBAFContainer container = (TBAFContainer) curCont;
 			container.setCurrentRecipe( this.selected , this.confirm );
 		}
 	}
diff --git a/src/java/mmm/tech/base/TBAlloyFurnaceOutputHopper.java b/src/java/mmm/tech/base/alloy_furnace/TBAFOutputHopper.java
similarity index 93%
rename from src/java/mmm/tech/base/TBAlloyFurnaceOutputHopper.java
rename to src/java/mmm/tech/base/alloy_furnace/TBAFOutputHopper.java
index 2e59702..d36109b 100644
--- a/src/java/mmm/tech/base/TBAlloyFurnaceOutputHopper.java
+++ b/src/java/mmm/tech/base/alloy_furnace/TBAFOutputHopper.java
@@ -1,4 +1,4 @@
-package mmm.tech.base;
+package mmm.tech.base.alloy_furnace;
 
 
 import mmm.utils.UInventoryGrid;
@@ -8,14 +8,14 @@ import net.minecraftforge.items.IItemHandler;
 
 
 
-public class TBAlloyFurnaceOutputHopper
+public class TBAFOutputHopper
 		implements IItemHandler
 {
-	private final TBAlloyFurnaceTileEntity tileEntity;
+	private final TBAFTileEntity tileEntity;
 	private final int nSlots;
 
 
-	public TBAlloyFurnaceOutputHopper( final TBAlloyFurnaceTileEntity tileEntity )
+	public TBAFOutputHopper( final TBAFTileEntity tileEntity )
 	{
 		this.tileEntity = tileEntity;
 		this.nSlots = this.tileEntity.input.getSizeInventory( ) + this.tileEntity.fuel.getSizeInventory( )
diff --git a/src/java/mmm/tech/base/TBAlloyFurnaceTileEntity.java b/src/java/mmm/tech/base/alloy_furnace/TBAFTileEntity.java
similarity index 88%
rename from src/java/mmm/tech/base/TBAlloyFurnaceTileEntity.java
rename to src/java/mmm/tech/base/alloy_furnace/TBAFTileEntity.java
index 936b8cf..76bcfdd 100644
--- a/src/java/mmm/tech/base/TBAlloyFurnaceTileEntity.java
+++ b/src/java/mmm/tech/base/alloy_furnace/TBAFTileEntity.java
@@ -1,8 +1,10 @@
-package mmm.tech.base;
+package mmm.tech.base.alloy_furnace;
 
 
 import mmm.materials.MAlloyRecipe;
 import mmm.materials.Materials;
+import mmm.tech.base.E_TBActivationMode;
+import mmm.tech.base.I_TBConfigurableActivation;
 import mmm.utils.UInventoryGrid;
 import net.minecraft.block.state.IBlockState;
 import net.minecraft.item.ItemStack;
@@ -24,9 +26,9 @@ import net.minecraftforge.items.wrapper.InvWrapper;
 
 
 
-public class TBAlloyFurnaceTileEntity
+public class TBAFTileEntity
 		extends TileEntity
-		implements ITickable
+		implements ITickable , I_TBConfigurableActivation
 {
 
 	public final UInventoryGrid input;
@@ -39,22 +41,24 @@ public class TBAlloyFurnaceTileEntity
 	private int alloyCurrent;
 	private int burnCurrent;
 	private int burnTotal;
+	private E_TBActivationMode activationMode;
 
 	private final IItemHandler inputHopper;
 	private final IItemHandler fuelHopper;
 	private final IItemHandler outputHopper;
 
 
-	public TBAlloyFurnaceTileEntity( )
+	public TBAFTileEntity( )
 	{
 		this.input = new UInventoryGrid( "Input" , 3 , 5 );
 		this.fuel = new UInventoryGrid( "Fuel" , 2 , 2 );
 		this.output = new UInventoryGrid( "Output" , 2 , 5 );
 		this.recipe = MAlloyRecipe.REGISTRY.getRecipes( ).get( 0 );
+		this.activationMode = E_TBActivationMode.ALWAYS_ACTIVE;
 
 		this.inputHopper = new InvWrapper( this.input );
 		this.fuelHopper = new InvWrapper( this.fuel );
-		this.outputHopper = new TBAlloyFurnaceOutputHopper( this );
+		this.outputHopper = new TBAFOutputHopper( this );
 	}
 
 
@@ -62,7 +66,7 @@ public class TBAlloyFurnaceTileEntity
 	public boolean shouldRefresh( final World world , final BlockPos pos , final IBlockState oldState ,
 			final IBlockState newSate )
 	{
-		return ! ( newSate.getBlock( ) instanceof TBAlloyFurnaceBlock );
+		return ! ( newSate.getBlock( ) instanceof TBAFBlock );
 	}
 
 
@@ -163,7 +167,7 @@ public class TBAlloyFurnaceTileEntity
 		}
 
 		if ( this.isBurning( ) != wasBurning ) {
-			TBAlloyFurnaceBlock.setState( this.isBurning( ) , this.worldObj , this.pos );
+			TBAFBlock.setState( this.isBurning( ) , this.worldObj , this.pos );
 		}
 
 		if ( dirty ) {
@@ -176,7 +180,19 @@ public class TBAlloyFurnaceTileEntity
 
 	public boolean isEnabled( )
 	{
-		return !TBAlloyFurnaceBlock.isPowered( this.getBlockMetadata( ) );
+		final boolean powered = TBAFBlock.isPowered( this.getBlockMetadata( ) );
+		switch ( this.activationMode ) {
+			case ALWAYS_ACTIVE:
+				return true;
+			case POWERED:
+				return powered;
+			case UNPOWERED:
+				return !powered;
+			case DISABLED:
+				return false;
+		}
+		System.err.println( "Warning: unsupported activation mode" );
+		return false;
 	}
 
 
@@ -205,6 +221,20 @@ public class TBAlloyFurnaceTileEntity
 	}
 
 
+	@Override
+	public E_TBActivationMode getActivationMode( )
+	{
+		return this.activationMode;
+	}
+
+
+	@Override
+	public void setActivationMode( final E_TBActivationMode mode )
+	{
+		this.activationMode = mode;
+	}
+
+
 	public void cancelAlloying( )
 	{
 		if ( this.alloying != null ) {
@@ -431,6 +461,24 @@ public class TBAlloyFurnaceTileEntity
 			this.recipe = MAlloyRecipe.REGISTRY.getRecipes( ).get( 0 );
 		}
 
+		byte am = compound.getByte( "ActivationMode" );
+		switch ( am ) {
+			default:
+				// XXX log
+			case 0:
+				this.activationMode = E_TBActivationMode.ALWAYS_ACTIVE;
+				break;
+			case 1:
+				this.activationMode = E_TBActivationMode.POWERED;
+				break;
+			case 2:
+				this.activationMode = E_TBActivationMode.UNPOWERED;
+				break;
+			case 3:
+				this.activationMode = E_TBActivationMode.DISABLED;
+				break;
+		}
+
 		this.burnCurrent = compound.getInteger( "BurnCurrent" );
 		this.burnTotal = compound.getInteger( "BurnTotal" );
 
@@ -451,6 +499,7 @@ public class TBAlloyFurnaceTileEntity
 	private void writeSyncData( final NBTTagCompound compound )
 	{
 		compound.setString( "Recipe" , this.recipe.name.toString( ) );
+		compound.setByte( "ActivationMode" , (byte) this.activationMode.ordinal( ) );
 		if ( this.alloying != null ) {
 			compound.setString( "AlloyRecipe" , this.alloying.name.toString( ) );
 			compound.setInteger( "AlloyCurrent" , this.alloyCurrent );
diff --git a/src/java/mmm/utils/gui/A_UGTab.java b/src/java/mmm/utils/gui/A_UGTab.java
index f5dadb8..e2a160a 100644
--- a/src/java/mmm/utils/gui/A_UGTab.java
+++ b/src/java/mmm/utils/gui/A_UGTab.java
@@ -27,9 +27,10 @@ public abstract class A_UGTab
 	protected int iconY;
 	protected String tooltip;
 	protected List< GuiButton > buttons = Lists.< GuiButton > newArrayList( );
+	private boolean selected;
 
 
-	A_UGTab setParent( final A_UGTabbedContainerScreen< ? > parent , int ordinal )
+	A_UGTab setParent( final A_UGTabbedContainerScreen< ? > parent , final int ordinal )
 	{
 		this.parent = parent;
 		this.ordinal = ordinal;
@@ -43,7 +44,7 @@ public abstract class A_UGTab
 	}
 
 
-	public A_UGTab setBackground( ResourceLocation background )
+	public A_UGTab setBackground( final ResourceLocation background )
 	{
 		this.background = background;
 		return this;
@@ -56,7 +57,7 @@ public abstract class A_UGTab
 	}
 
 
-	public A_UGTab setHeight( int height )
+	public A_UGTab setHeight( final int height )
 	{
 		this.height = height;
 		return this;
@@ -75,7 +76,7 @@ public abstract class A_UGTab
 	}
 
 
-	public A_UGTab setIconPosition( int x , int y )
+	public A_UGTab setIconPosition( final int x , final int y )
 	{
 		this.iconX = x;
 		this.iconY = y;
@@ -89,27 +90,27 @@ public abstract class A_UGTab
 	}
 
 
-	public A_UGTab setTooltip( String tooltip )
+	public A_UGTab setTooltip( final String tooltip )
 	{
 		this.tooltip = tooltip;
 		return this;
 	}
 
 
-	public A_UGTab setSlotGroups( int... slotGroups )
+	public A_UGTab setSlotGroups( final int... slotGroups )
 	{
 		this.slotGroups = slotGroups;
 		return this;
 	}
 
 
-	public void initGui( int x , int y )
+	public void initGui( final int x , final int y )
 	{
 		// EMPTY
 	}
 
 
-	public void drawBackground( float partialTicks , int mouseX , int mouseY )
+	public void drawBackground( final float partialTicks , final int mouseX , final int mouseY )
 	{
 		GlStateManager.color( 1f , 1f , 1f , 1f );
 		GlStateManager.enableBlend( );
@@ -125,6 +126,7 @@ public abstract class A_UGTab
 		for ( int i = 0 ; i < this.buttons.size( ) ; i++ ) {
 			this.buttons.get( i ).visible = true;
 		}
+		this.selected = true;
 	}
 
 
@@ -133,10 +135,17 @@ public abstract class A_UGTab
 		for ( int i = 0 ; i < this.buttons.size( ) ; i++ ) {
 			this.buttons.get( i ).visible = false;
 		}
+		this.selected = false;
 	}
 
 
-	public void onMouseClicked( int mouseX , int mouseY , int mouseButton )
+	public boolean isSelected( )
+	{
+		return this.selected;
+	}
+
+
+	public void onMouseClicked( final int mouseX , final int mouseY , final int mouseButton )
 	{
 		// EMPTY
 	}
@@ -148,7 +157,7 @@ public abstract class A_UGTab
 	}
 
 
-	public boolean onActionPerformed( GuiButton button )
+	public boolean onActionPerformed( final GuiButton button )
 	{
 		return false;
 	}
diff --git a/src/java/mmm/utils/gui/A_UGTabbedContainerScreen.java b/src/java/mmm/utils/gui/A_UGTabbedContainerScreen.java
index eaab8c1..93ac686 100644
--- a/src/java/mmm/utils/gui/A_UGTabbedContainerScreen.java
+++ b/src/java/mmm/utils/gui/A_UGTabbedContainerScreen.java
@@ -54,9 +54,13 @@ public abstract class A_UGTabbedContainerScreen< CTYPE extends UGContainer >
 		final int x = ( this.width - this.xSize ) / 2;
 		final int y = ( this.height - this.ySize ) / 2;
 
-		for ( final A_UGTab tab : this.tabs ) {
+		for ( int tabIndex = 0 ; tabIndex < this.tabs.length ; tabIndex ++ ) {
+			A_UGTab tab = this.tabs[ tabIndex ];
 			tab.buttons.clear( );
 			tab.initGui( x , y );
+			for ( int i = 0 ; i < tab.buttons.size( ) ; i ++ ) {
+				tab.buttons.get( i ).visible = ( this.currentTab == tabIndex );
+			}
 			this.buttonList.addAll( tab.buttons );
 		}
 	}
diff --git a/src/resources/assets/mmm/lang/en_US.lang b/src/resources/assets/mmm/lang/en_US.lang
index 7f205d2..3d2e8f8 100644
--- a/src/resources/assets/mmm/lang/en_US.lang
+++ b/src/resources/assets/mmm/lang/en_US.lang
@@ -16,6 +16,11 @@ item.mmm.materials.stone.cuprite.name=Cuprite
 tile.mmm.materials.ore.cuprite.name=Cuprite Ore
 
 
+gui.mmm.tech.base.am.always_active=Always Active
+gui.mmm.tech.base.am.powered=Redstone Activates
+gui.mmm.tech.base.am.unpowered=Redstone Disables
+gui.mmm.tech.base.am.disabled=Deactivated
+
 item.mmm.tech.base.alloy_furnace.name=Alloy Furnace
 container.mmm.alloy_furnace.contents=Furnace Contents
 container.mmm.alloy_furnace.recipe=Alloy Selection
diff --git a/src/resources/assets/mmm/textures/gui/alloy_furnace_3.png b/src/resources/assets/mmm/textures/gui/alloy_furnace_3.png
new file mode 100644
index 0000000000000000000000000000000000000000..e314d0404bde4ce62a6a3efab971d88eedfcbff5
GIT binary patch
literal 792
zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|GzJEy`<^b2Ar-gY-np20*g&H7
z;_68Yot_o2aaQp2KeBzY@!viZ-Gvw0-B@>9vi}j8;OHX1Y2)2bOPP*e@Hu#+bB)&P
z`OSYaqlFtC@9EU_E&HB#+^T^6gFr*>?K51vx9NCKN{J1(Ze+A(=$2<;5MXcs*-kA6
z^-O}hXb2eTz~IBk!Jxp<0E{~ZYB3-tZOA^oX+}$<pJ!C|+N$?z;&FxS0ikb;cFy4C
zOOCy+l9`s&u*xe`)zebO-D2JK)veYqgdPOH|GRL-_S?FbO>9e>D(4m3&F@W~6W_l%
zclK|F`bthLE|j_ba=HBS%u_b!{pTOCIF>j+YSQm&hWm0mTWojPbN%_~B%sF#N+k{d
z_y0}r37)j&+M{lV4~MK7;#nSf+ySN@5`f$uX3lDbYQA|-|ABOQy85}Sb4q9e086@<
AT>t<8

literal 0
HcmV?d00001