Workbench - Display recipes

This commit is contained in:
Emmanuel BENOîT 2016-07-16 16:13:50 +02:00
parent 8361ecb417
commit 982dc9b25d
8 changed files with 278 additions and 15 deletions

View file

@ -8,6 +8,8 @@ import net.minecraft.item.ItemStack;
public interface I_CraftingRecipeWrapper
{
public String getIdentifier( );
public String getName( );

View file

@ -3,6 +3,7 @@ package mmm.recipes;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import mmm.core.api.recipes.I_CraftingRecipeWrapper;
import mmm.core.api.recipes.I_CraftingRecipeWrapperFactory;
@ -14,7 +15,8 @@ import net.minecraft.item.crafting.IRecipe;
public class RCraftingWrappers
{
private static final HashMap< Class< ? > , I_CraftingRecipeWrapperFactory > FACTORIES = new HashMap<>( );
private static final ArrayList< I_CraftingRecipeWrapper > RECIPES = new ArrayList<>( );
public static final ArrayList< I_CraftingRecipeWrapper > RECIPES = new ArrayList<>( );
public static final HashMap< String , I_CraftingRecipeWrapper > IDENTIFIERS = new HashMap<>( );
public static void register( final I_CraftingRecipeWrapperFactory factory )
@ -39,10 +41,18 @@ public class RCraftingWrappers
System.err.println( "unsupported recipe class " + recipe.getClass( ) );
continue;
}
RCraftingWrappers.RECIPES.addAll( factory.createWrappers( recipe ) );
final List< I_CraftingRecipeWrapper > wrappers = factory.createWrappers( recipe );
for ( final I_CraftingRecipeWrapper wrapper : wrappers ) {
final String identifier = wrapper.getIdentifier( );
if ( RCraftingWrappers.IDENTIFIERS.containsKey( identifier ) ) {
throw new IllegalStateException( "duplicate wrapper ID " + identifier );
}
RCraftingWrappers.IDENTIFIERS.put( identifier , wrapper );
}
RCraftingWrappers.RECIPES.addAll( wrappers );
}
System.err.println( "wrapped " + RCraftingWrappers.RECIPES.size( ) + " recipes" );
System.err.println( "generated " + RCraftingWrappers.RECIPES.size( ) + " recipe wrappers" );
}

View file

@ -7,6 +7,7 @@ import mmm.core.api.recipes.I_CraftingRecipeWrapper;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
import net.minecraftforge.oredict.OreDictionary;
import net.minecraftforge.oredict.ShapedOreRecipe;
@ -27,6 +28,31 @@ public class RShapedOreRecipeWrapper
}
@Override
public String getIdentifier( )
{
final StringBuilder sb = new StringBuilder( "SHAPED_ORE;" );
final ItemStack recipeOutput = this.recipe.getRecipeOutput( );
sb.append( recipeOutput.getItem( ).getRegistryName( ) ).append( ',' ).append( recipeOutput.getMetadata( ) );
final Object[] input = this.recipe.getInput( );
for ( final Object inObject : input ) {
ItemStack stack;
sb.append( ';' );
if ( inObject instanceof ItemStack ) {
stack = (ItemStack) inObject;
} else if ( inObject instanceof List && ! ( (List< ? >) inObject ).isEmpty( ) ) {
stack = (ItemStack) ( (List< ? >) inObject ).get( 0 );
} else {
stack = null;
}
if ( stack != null ) {
sb.append( stack.getItem( ).getRegistryName( ) ).append( ',' ).append( stack.getMetadata( ) );
}
}
return sb.toString( );
}
@Override
public String getName( )
{
@ -50,7 +76,7 @@ public class RShapedOreRecipeWrapper
final Object inObj = input[ i + j * this.width ];
if ( inObj instanceof ItemStack ) {
displayInventory.setInventorySlotContents( i + j * 3 , ( (ItemStack) inObj ).copy( ) );
RShapedOreRecipeWrapper.setSlot( displayInventory , i + j * 3 , (ItemStack) inObj );
} else if ( inObj instanceof List ) {
@SuppressWarnings( "unchecked" )
@ -58,13 +84,24 @@ public class RShapedOreRecipeWrapper
if ( oreList.isEmpty( ) ) {
continue;
}
displayInventory.setInventorySlotContents( i + j * 3 , oreList.get( 0 ).copy( ) );
RShapedOreRecipeWrapper.setSlot( displayInventory , i + j * 3 , oreList.get( 0 ) );
}
}
}
}
private static void setSlot( final IInventory inventory , final int index , ItemStack stack )
{
if ( stack.getMetadata( ) == OreDictionary.WILDCARD_VALUE ) {
stack = new ItemStack( stack.getItem( ) , 1 , 0 );
} else {
stack = stack.copy( );
}
inventory.setInventorySlotContents( index , stack );
}
@Override
public boolean canCraft( final IInventory inventory )
{

View file

@ -5,6 +5,7 @@ import mmm.core.api.recipes.I_CraftingRecipeWrapper;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.ShapedRecipes;
import net.minecraftforge.oredict.OreDictionary;
@ -20,6 +21,22 @@ public class RShapedRecipeWrapper
}
@Override
public String getIdentifier( )
{
final StringBuilder sb = new StringBuilder( "SHAPED;" );
final ItemStack recipeOutput = this.recipe.getRecipeOutput( );
sb.append( recipeOutput.getItem( ).getRegistryName( ) ).append( ',' ).append( recipeOutput.getMetadata( ) );
for ( final ItemStack stack : this.recipe.recipeItems ) {
sb.append( ';' );
if ( stack != null ) {
sb.append( stack.getItem( ).getRegistryName( ) ).append( ',' ).append( stack.getMetadata( ) );
}
}
return sb.toString( );
}
@Override
public String getName( )
{
@ -39,15 +56,26 @@ public class RShapedRecipeWrapper
{
for ( int i = 0 ; i < this.recipe.recipeWidth ; i++ ) {
for ( int j = 0 ; j < this.recipe.recipeHeight ; j++ ) {
ItemStack itemStack = this.recipe.recipeItems[ i + j * this.recipe.recipeWidth ];
final ItemStack itemStack = this.recipe.recipeItems[ i + j * this.recipe.recipeWidth ];
if ( itemStack != null ) {
displayInventory.setInventorySlotContents( i + j * 3 , itemStack.copy( ) );
RShapedRecipeWrapper.setSlot( displayInventory , i + 3 * j , itemStack );
}
}
}
}
private static void setSlot( final IInventory inventory , final int index , ItemStack stack )
{
if ( stack.getMetadata( ) == OreDictionary.WILDCARD_VALUE ) {
stack = new ItemStack( stack.getItem( ) , 1 , 0 );
} else {
stack = stack.copy( );
}
inventory.setInventorySlotContents( index , stack );
}
@Override
public boolean canCraft( final IInventory inventory )
{

View file

@ -50,6 +50,31 @@ public class RShapelessOreRecipeWrapper
}
@Override
public String getIdentifier( )
{
final StringBuilder sb = new StringBuilder( "SHAPELESS_ORE;" );
final ItemStack recipeOutput = this.recipe.getRecipeOutput( );
sb.append( recipeOutput.getItem( ).getRegistryName( ) ).append( ',' ).append( recipeOutput.getMetadata( ) );
final ArrayList< Object > input = this.recipe.getInput( );
for ( final Object inObject : input ) {
ItemStack stack;
sb.append( ';' );
if ( inObject instanceof ItemStack ) {
stack = (ItemStack) inObject;
} else if ( inObject instanceof List && ! ( (List< ? >) inObject ).isEmpty( ) ) {
stack = (ItemStack) ( (List< ? >) inObject ).get( 0 );
} else {
stack = null;
}
if ( stack != null ) {
sb.append( stack.getItem( ).getRegistryName( ) ).append( ',' ).append( stack.getMetadata( ) );
}
}
return sb.toString( );
}
@Override
public String getName( )
{
@ -69,19 +94,32 @@ public class RShapelessOreRecipeWrapper
{
int i = 0;
for ( final ItemStack stack : this.combinedInputStacks ) {
displayInventory.setInventorySlotContents( i++ , stack.copy( ) );
RShapelessOreRecipeWrapper.setSlot( displayInventory , i++ , stack , stack.stackSize );
}
for ( final List< ItemStack > oreList : this.combinedInputOreLists.keySet( ) ) {
if ( oreList.isEmpty( ) ) {
continue;
}
final ItemStack stack = oreList.get( 0 ).copy( );
stack.stackSize = this.combinedInputOreLists.get( oreList );
displayInventory.setInventorySlotContents( i++ , stack );
final ItemStack stack = oreList.get( 0 );
RShapelessOreRecipeWrapper.setSlot( displayInventory , i++ , stack ,
this.combinedInputOreLists.get( oreList ) );
}
}
private static void setSlot( final IInventory inventory , final int index , ItemStack stack , final int size )
{
if ( stack.getMetadata( ) == OreDictionary.WILDCARD_VALUE ) {
stack = new ItemStack( stack.getItem( ) , 1 , 0 );
} else {
stack = stack.copy( );
}
stack.stackSize = size;
inventory.setInventorySlotContents( index , stack );
}
@Override
public boolean canCraft( final IInventory inventory )
{

View file

@ -37,6 +37,22 @@ public class RShapelessRecipeWrapper
}
@Override
public String getIdentifier( )
{
final StringBuilder sb = new StringBuilder( "SHAPELESS;" );
final ItemStack recipeOutput = this.recipe.getRecipeOutput( );
sb.append( recipeOutput.getItem( ).getRegistryName( ) ).append( ',' ).append( recipeOutput.getMetadata( ) );
for ( final ItemStack stack : this.recipe.recipeItems ) {
sb.append( ';' );
if ( stack != null ) {
sb.append( stack.getItem( ).getRegistryName( ) ).append( ',' ).append( stack.getMetadata( ) );
}
}
return sb.toString( );
}
@Override
public String getName( )
{
@ -55,9 +71,25 @@ public class RShapelessRecipeWrapper
public void addInputsToDisplay( final IInventory displayInventory )
{
int i = 0;
for ( final ItemStack stack : this.combinedInputs ) {
displayInventory.setInventorySlotContents( i++ , stack.copy( ) );
for ( ItemStack stack : this.combinedInputs ) {
if ( stack.getMetadata( ) == OreDictionary.WILDCARD_VALUE ) {
stack = new ItemStack( stack.getItem( ) , 1 , 0 );
} else {
stack = stack.copy( );
}
RShapelessRecipeWrapper.setSlot( displayInventory , i++ , stack );
}
}
private static void setSlot( final IInventory inventory , final int index , ItemStack stack )
{
if ( stack.getMetadata( ) == OreDictionary.WILDCARD_VALUE ) {
stack = new ItemStack( stack.getItem( ) , 1 , 0 );
} else {
stack = stack.copy( );
}
inventory.setInventorySlotContents( index , stack );
}

View file

@ -2,7 +2,10 @@ package mmm.tech.base.workbench;
import mmm.MmmTech;
import mmm.core.api.recipes.I_CraftingRecipeWrapper;
import mmm.utils.UInventoryDisplay;
import mmm.utils.gui.UGContainer;
import mmm.utils.gui.UGSlotDisplay;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Slot;
@ -17,6 +20,7 @@ public class TBWBContainer
public final TBWBTileEntity tileEntity;
public final World world;
public final BlockPos position;
public final UInventoryDisplay recipe;
public TBWBContainer( final InventoryPlayer playerInv , final TBWBTileEntity tileEntity )
@ -26,8 +30,16 @@ public class TBWBContainer
this.position = tileEntity.getPos( );
this.addPlayerInventory( Slot::new , playerInv , 28 , 119 );
this.slotGroups.nextGroup( );
this.addGrid( Slot::new , tileEntity.storage , 8 , 15 );
this.slotGroups.nextGroup( );
this.recipe = new UInventoryDisplay( "Recipe" , 10 );
this.addGrid( UGSlotDisplay::new , this.recipe , //
3 , 3 , 0 , 86 , 32 );
this.addSlotToContainer( new UGSlotDisplay( this.recipe , 9 , 174 , 50 ) );
this.slotGroups.endGroups( );
}
@ -40,4 +52,21 @@ public class TBWBContainer
this.position.getZ( ) + .5 ) <= 64.;
}
public void setCurrentRecipe( final I_CraftingRecipeWrapper wrapper , final boolean setDefault )
{
this.recipe.clear( );
if ( wrapper == null ) {
// XXX log if confirm is set
return;
}
wrapper.addInputsToDisplay( this.recipe );
this.recipe.setInventorySlotContents( 9 , wrapper.getOutput( ) );
if ( setDefault ) {
// this.tileEntity.setDefaultRecipe( wrapper.getIdentifier( ) );
}
}
}

View file

@ -2,8 +2,12 @@ package mmm.tech.base.workbench;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import mmm.Mmm;
import mmm.core.api.recipes.I_CraftingRecipeWrapper;
import mmm.recipes.RCraftingWrappers;
import mmm.utils.gui.A_UGContainerScreen;
import mmm.utils.gui.UGArrowButton;
import net.minecraft.client.gui.GuiButton;
@ -27,6 +31,10 @@ public class TBWBGui
private UGArrowButton bNext;
private GuiButton bSetDefault;
private String searchString;
private List< I_CraftingRecipeWrapper > recipes;
private int currentRecipe;
public TBWBGui( final InventoryPlayer inventoryPlayer , final TBWBTileEntity tileEntity )
{
@ -34,6 +42,10 @@ public class TBWBGui
this.container.slotGroups.showAll( );
this.xSize = 216;
this.ySize = 200;
this.searchString = "";
this.recipes = RCraftingWrappers.RECIPES;
this.setRecipe( -1 );
}
@ -60,6 +72,8 @@ public class TBWBGui
this.buttonList.add( this.bPrevious );
this.buttonList.add( this.bNext );
this.buttonList.add( this.bSetDefault );
this.enableButtons( );
}
@ -90,7 +104,9 @@ public class TBWBGui
protected void keyTyped( final char typedChar , final int keyCode )
throws IOException
{
if ( !this.tfSearch.textboxKeyTyped( typedChar , keyCode ) ) {
if ( this.tfSearch.textboxKeyTyped( typedChar , keyCode ) ) {
this.handleFiltering( this.tfSearch.getText( ) );
} else {
super.keyTyped( typedChar , keyCode );
}
}
@ -100,7 +116,78 @@ public class TBWBGui
protected void actionPerformed( final GuiButton button )
throws IOException
{
// TODO
if ( button == this.bNext && this.currentRecipe < this.recipes.size( ) - 1 ) {
this.setRecipe( this.currentRecipe + 1 );
} else if ( button == this.bPrevious && this.currentRecipe > 0 ) {
this.setRecipe( this.currentRecipe - 1 );
}
}
private void setRecipe( int index )
{
if ( index == -1 && !this.recipes.isEmpty( ) ) {
index = 0;
}
this.currentRecipe = index;
this.container.setCurrentRecipe( index == -1 ? null : this.recipes.get( index ) , false );
// CNetwork.sendToServer( new TBAFMessage( rName , false ) );
this.enableButtons( );
}
private void enableButtons( )
{
if ( this.bNext != null ) {
this.bNext.enabled = !this.recipes.isEmpty( ) && this.currentRecipe < this.recipes.size( ) - 1;
this.bPrevious.enabled = !this.recipes.isEmpty( ) && this.currentRecipe > 0;
}
}
private void handleFiltering( final String input )
{
final String newText = input.trim( ).toLowerCase( );
if ( this.searchString.equals( newText ) ) {
return;
}
final I_CraftingRecipeWrapper selected = this.currentRecipe == -1
? null
: this.recipes.get( this.currentRecipe );
final ArrayList< I_CraftingRecipeWrapper > fullList = RCraftingWrappers.RECIPES;
this.searchString = newText;
if ( "".equals( newText ) ) {
this.recipes = fullList;
} else {
if ( this.recipes == fullList ) {
this.recipes = new ArrayList<>( );
} else {
this.recipes.clear( );
}
final int nRecipes = fullList.size( );
for ( int i = 0 ; i < nRecipes ; i++ ) {
final I_CraftingRecipeWrapper recipe = fullList.get( i );
if ( I18n.format( recipe.getName( ) ).toLowerCase( ).contains( newText ) ) {
this.recipes.add( recipe );
}
}
}
if ( selected == null && !this.recipes.isEmpty( ) ) {
this.setRecipe( 0 );
} else if ( selected != null ) {
this.setRecipe( this.getRecipeIndex( selected ) );
} else {
this.setRecipe( -1 );
}
}
private int getRecipeIndex( I_CraftingRecipeWrapper selected )
{
return this.recipes.indexOf( selected );
}
}