Implemented a proper GUI factory

This commit is contained in:
Emmanuel BENOîT 2016-06-28 21:38:54 +02:00
parent ebfc4c6da6
commit 67d6f34fcc
5 changed files with 150 additions and 59 deletions

View file

@ -47,7 +47,6 @@ tech.base No Alloy furnace
-> comparator signal configuration
(inventory mode w/ combinations, valid ingredients, burn time,
alloying time)
-> code clean-up
tech.base No Coke oven
-------------------------------------------------------------------------------------------------------
animals ??? Goats

View file

@ -1,46 +0,0 @@
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;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.network.IGuiHandler;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class TBAlloyFurnaceGuiHandler
implements IGuiHandler
{
@Override
public Object getServerGuiElement( final int ID , final EntityPlayer player , final World world , final int x ,
final int y , final int z )
{
final BlockPos pos = new BlockPos( x , y , z );
final TileEntity tileEntity = world.getTileEntity( pos );
if ( tileEntity instanceof TBAFTileEntity ) {
return new TBAFContainer( player.inventory , (TBAFTileEntity) tileEntity );
}
return null;
}
@Override
@SideOnly( Side.CLIENT )
public Object getClientGuiElement( final int ID , final EntityPlayer player , final World world , final int x ,
final int y , final int z )
{
final TileEntity tileEntity = world.getTileEntity( new BlockPos( x , y , z ) );
if ( tileEntity instanceof TBAFTileEntity ) {
return new TBAFGui( player.inventory , (TBAFTileEntity) tileEntity );
}
return null;
}
}

View file

@ -1,13 +1,11 @@
package mmm.tech.base.alloy_furnace;
import mmm.Mmm;
import mmm.tech.base.TBAlloyFurnaceGuiHandler;
import mmm.utils.UNetwork;
import mmm.utils.URegistry;
import mmm.utils.gui.GUIUtils;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlockSpecial;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.common.registry.GameRegistry;
@ -33,9 +31,10 @@ public enum AlloyFurnace {
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( ) );
GUIUtils.registerTileEntityGUI( TBAFTileEntity.class , "mmm.tech.base.alloy_furnace.TBAFContainer" ,
"mmm.tech.base.alloy_furnace.TBAFGui" );
UNetwork.addServerMessage( TBAFMessage.class );
}

View file

@ -6,10 +6,10 @@ import java.util.Random;
import javax.annotation.Nullable;
import mmm.Mmm;
import mmm.utils.I_URecipeRegistrar;
import mmm.utils.UMaths;
import mmm.utils.URegistry;
import mmm.utils.gui.GUIUtils;
import net.minecraft.block.Block;
import net.minecraft.block.BlockContainer;
import net.minecraft.block.BlockHorizontal;
@ -353,7 +353,7 @@ public class TBAFBlock
if ( ! ( te instanceof TBAFTileEntity ) || playerIn.isSneaking( ) ) {
return false;
}
playerIn.openGui( Mmm.get( ) , 0 , worldIn , pos.getX( ) , pos.getY( ) , pos.getZ( ) );
GUIUtils.openTileEntityGUI( playerIn , worldIn , pos );
return true;
}

View file

@ -1,18 +1,35 @@
package mmm.utils.gui;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.google.common.collect.Maps;
import mmm.Mmm;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper;
import net.minecraftforge.fml.common.network.IGuiHandler;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.relauncher.FMLLaunchHandler;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class GUIUtils
{
static final Logger LOGGER = LogManager.getLogger( );
public static final ResourceLocation GUI_TEXTURE = new ResourceLocation( "mmm" , "textures/gui/gui-common.png" );
public enum GUIUtils
implements IGuiHandler {
INSTANCE;
public static final int TAB_TEXTURE_X = 0;
public static final int TAB_TEXTURE_Y = 0;
@ -30,4 +47,126 @@ public class GUIUtils
public static final int TAB_ICON_WIDTH = 16;
public static final int TAB_ICON_HEIGHT = 16;
private static final HashMap< Class< ? extends TileEntity > , Constructor< ? > > SERVER_SIDE //
= Maps.newHashMap( );
private static final HashMap< Class< ? extends TileEntity > , Constructor< ? > > CLIENT_SIDE //
= Maps.newHashMap( );
static final Logger LOGGER = LogManager.getLogger( );
public static final ResourceLocation GUI_TEXTURE = new ResourceLocation( "mmm" , "textures/gui/gui-common.png" );
public static void registerTileEntityGUI( final Class< ? extends TileEntity > teClass ,
final String containerClassName , final String guiClassName )
{
if ( GUIUtils.SERVER_SIDE.containsKey( teClass ) ) {
throw new IllegalArgumentException( "duplicate GUI registration for tile entity class " + teClass );
}
GUIUtils.addTileEntityConstructor( GUIUtils.SERVER_SIDE , teClass , Container.class , containerClassName ,
"container" );
if ( FMLLaunchHandler.side( ) == Side.CLIENT ) {
String clsName = "net.minecraft.client.gui.inventory.GuiContainer";
if ( FMLDeobfuscatingRemapper.INSTANCE.isRemappedClass( clsName ) ) {
clsName = FMLDeobfuscatingRemapper.INSTANCE.map( clsName );
}
Class< ? > guiClass;
try {
guiClass = Class.forName( clsName );
} catch ( final ClassNotFoundException e ) {
throw new IllegalArgumentException( "couldn't find GUI class" , e );
}
GUIUtils.addTileEntityConstructor( GUIUtils.CLIENT_SIDE , teClass , guiClass , guiClassName , "GUI" );
}
}
public static void openTileEntityGUI( final EntityPlayer player , final World world , final BlockPos pos )
{
player.openGui( Mmm.get( ) , 0 , world , pos.getX( ) , pos.getY( ) , pos.getZ( ) );
}
private static void addTileEntityConstructor(
final HashMap< Class< ? extends TileEntity > , Constructor< ? > > output ,
final Class< ? extends TileEntity > teClass , final Class< ? > parent , final String className ,
final String designation )
{
Class< ? > klass;
try {
klass = Class.forName( className );
} catch ( final ClassNotFoundException e ) {
throw new IllegalArgumentException( "bad " + designation + " class name" , e );
}
if ( !parent.isAssignableFrom( klass ) ) {
throw new IllegalArgumentException( "class " + className + " is not a " + designation + " sub-class" );
}
output.put( teClass , GUIUtils.findConstructor( teClass , klass ) );
}
private static Constructor< ? > findConstructor( final Class< ? > teClass , final Class< ? > klass )
{
final Constructor< ? >[] allCons = klass.getConstructors( );
for ( final Constructor< ? > cons : allCons ) {
final Class< ? >[] types = cons.getParameterTypes( );
if ( ! ( types.length == 2 && types[ 0 ].isAssignableFrom( InventoryPlayer.class )
&& types[ 1 ].isAssignableFrom( teClass ) ) ) {
continue;
}
return cons;
}
throw new IllegalArgumentException( "class " + klass.getName( ) + " does not have a supported constructor" );
}
private GUIUtils( )
{
NetworkRegistry.INSTANCE.registerGuiHandler( Mmm.get( ) , this );
}
@Override
public Object getServerGuiElement( final int ID , final EntityPlayer player , final World world , final int x ,
final int y , final int z )
{
if ( ID == 0 ) {
return this.getObjectForTE( player , world , x , y , z , GUIUtils.SERVER_SIDE , "container" );
}
return null;
}
@Override
@SideOnly( Side.CLIENT )
public Object getClientGuiElement( final int ID , final EntityPlayer player , final World world , final int x ,
final int y , final int z )
{
if ( ID == 0 ) {
return this.getObjectForTE( player , world , x , y , z , GUIUtils.CLIENT_SIDE , "GUI" );
}
return null;
}
private Object getObjectForTE( final EntityPlayer player , final World world , final int x , final int y ,
final int z , final HashMap< Class< ? extends TileEntity > , Constructor< ? > > constructors ,
final String designation )
{
final BlockPos pos = new BlockPos( x , y , z );
final TileEntity tileEntity = world.getTileEntity( pos );
final Constructor< ? > cns = constructors.get( tileEntity.getClass( ) );
if ( cns == null ) {
return null;
}
try {
return cns.newInstance( player.inventory , tileEntity );
} catch ( InstantiationException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException e ) {
throw new RuntimeException( "couldn't create tile entity " + designation //
+ " for " + tileEntity.getClass( ) );
}
}
}