diff --git a/graphics/alloy-furnace-gui-1.xcf b/graphics/alloy-furnace-gui-1.xcf index 96351a8..616d444 100644 Binary files a/graphics/alloy-furnace-gui-1.xcf and b/graphics/alloy-furnace-gui-1.xcf differ diff --git a/graphics/gui-common.xcf b/graphics/gui-common.xcf index 53d8627..26b7fb4 100644 Binary files a/graphics/gui-common.xcf and b/graphics/gui-common.xcf differ diff --git a/src/java/mmm/core/api/recipes/I_CraftingRecipeWrapper.java b/src/java/mmm/core/api/recipes/I_CraftingRecipeWrapper.java index 57471ee..92438e7 100644 --- a/src/java/mmm/core/api/recipes/I_CraftingRecipeWrapper.java +++ b/src/java/mmm/core/api/recipes/I_CraftingRecipeWrapper.java @@ -20,9 +20,6 @@ public interface I_CraftingRecipeWrapper public void addInputsToDisplay( IInventory displayInventory ); - public boolean canCraft( IInventory inventory ); - - - public void craft( IInventory input , IInventory output , int quantity ); + public I_RecipeRequirements getRequirements( ); } diff --git a/src/java/mmm/core/api/recipes/I_RecipeRequirements.java b/src/java/mmm/core/api/recipes/I_RecipeRequirements.java new file mode 100644 index 0000000..f365b01 --- /dev/null +++ b/src/java/mmm/core/api/recipes/I_RecipeRequirements.java @@ -0,0 +1,28 @@ +package mmm.core.api.recipes; + + +import java.util.List; + +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; + + + +public interface I_RecipeRequirements +{ + + int size( ); + + + int getQuantity( int pos ); + + + List< ItemStack > getItemTypes( int pos ); + + + boolean checkItemStack( int pos , ItemStack stack ); + + + boolean checkInventory( IInventory inventory ); + +} \ No newline at end of file diff --git a/src/java/mmm/recipes/ROreRecipeHelper.java b/src/java/mmm/recipes/ROreRecipeHelper.java new file mode 100644 index 0000000..38f5e68 --- /dev/null +++ b/src/java/mmm/recipes/ROreRecipeHelper.java @@ -0,0 +1,65 @@ +package mmm.recipes; + + +import java.util.ArrayList; +import java.util.IdentityHashMap; +import java.util.List; +import java.util.Map; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.oredict.OreDictionary; + + + +class ROreRecipeHelper +{ + + static RRequirements extractRequirements( final Object[] recipe ) + { + final List< ItemStack > combinedInputStacks = new ArrayList<>( ); + final IdentityHashMap< List< ItemStack > , Integer > combinedInputOreLists = new IdentityHashMap<>( ); + + ROreRecipeHelper.extractInputs( recipe , combinedInputStacks , combinedInputOreLists ); + + final RRequirements reqs = new RRequirements( combinedInputStacks.size( ) + combinedInputOreLists.size( ) ); + int i; + for ( i = 0 ; i < combinedInputStacks.size( ) ; i++ ) { + final ItemStack stack = combinedInputStacks.get( i ); + reqs.put( i , stack , stack.stackSize ); + } + for ( final Map.Entry< List< ItemStack > , Integer > entry : combinedInputOreLists.entrySet( ) ) { + reqs.put( i++ , entry.getKey( ) , entry.getValue( ) ); + } + return reqs; + } + + + private static void extractInputs( final Object[] recipe , final List< ItemStack > combinedInputStacks , + final IdentityHashMap< List< ItemStack > , Integer > combinedInputOreLists ) + { + OUTER: for ( final Object input : recipe ) { + if ( input instanceof ItemStack ) { + final ItemStack invStack = (ItemStack) input; + for ( final ItemStack ciStack : combinedInputStacks ) { + if ( OreDictionary.itemMatches( ciStack , invStack , true ) ) { + ciStack.stackSize ++; + continue OUTER; + } + } + ItemStack ciStack = invStack.copy( ); + ciStack.stackSize = 1; + combinedInputStacks.add( ciStack ); + + } else if ( input instanceof List ) { + @SuppressWarnings( "unchecked" ) + final List< ItemStack > oreList = (List< ItemStack >) input; + if ( combinedInputOreLists.containsKey( oreList ) ) { + combinedInputOreLists.put( oreList , combinedInputOreLists.get( oreList ) + 1 ); + } else { + combinedInputOreLists.put( oreList , 1 ); + } + } + } + } + +} diff --git a/src/java/mmm/recipes/RRequirements.java b/src/java/mmm/recipes/RRequirements.java new file mode 100644 index 0000000..ee8ee14 --- /dev/null +++ b/src/java/mmm/recipes/RRequirements.java @@ -0,0 +1,111 @@ +package mmm.recipes; + + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import mmm.core.api.recipes.I_RecipeRequirements; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraftforge.oredict.OreDictionary; + + + +class RRequirements + implements I_RecipeRequirements +{ + + private final List< ItemStack >[] itemTypes; + private final int[] quantities; + + + @SuppressWarnings( "unchecked" ) + RRequirements( final int nInputs ) + { + this.itemTypes = new List[ nInputs ]; + this.quantities = new int[ nInputs ]; + } + + + RRequirements( final ArrayList< ItemStack > inputs ) + { + this( inputs.size( ) ); + for ( int i = 0 ; i < this.quantities.length ; i++ ) { + final ItemStack input = inputs.get( i ); + this.put( i , input , input.stackSize ); + } + } + + + void put( final int pos , final ItemStack stack , final int quantity ) + { + this.itemTypes[ pos ] = Arrays.asList( stack ); + this.quantities[ pos ] = quantity; + } + + + void put( final int pos , final List< ItemStack > stacks , final int quantity ) + { + assert stacks != null; + this.itemTypes[ pos ] = stacks; + this.quantities[ pos ] = quantity; + } + + + @Override + public int size( ) + { + return this.quantities.length; + } + + + @Override + public int getQuantity( final int pos ) + { + return this.quantities[ pos ]; + } + + + @Override + public List< ItemStack > getItemTypes( final int pos ) + { + return this.itemTypes[ pos ]; + } + + + @Override + public boolean checkItemStack( final int pos , final ItemStack stack ) + { + if ( stack != null ) { + for ( final ItemStack target : this.getItemTypes( pos ) ) { + if ( OreDictionary.itemMatches( target , stack , false ) ) { + return true; + } + } + } + return false; + } + + + @Override + public boolean checkInventory( final IInventory inventory ) + { + final int nInvItems = inventory.getSizeInventory( ); + for ( int i = 0 ; i < this.quantities.length ; i++ ) { + int nLeft = this.quantities[ i ]; + + for ( int j = 0 ; j < nInvItems && nLeft > 0 ; j++ ) { + final ItemStack invStack = inventory.getStackInSlot( j ); + if ( this.checkItemStack( i , invStack ) ) { + nLeft -= invStack.stackSize; + } + } + + if ( nLeft > 0 ) { + return false; + } + } + return true; + } +} diff --git a/src/java/mmm/recipes/RShapedOreRecipeWrapper.java b/src/java/mmm/recipes/RShapedOreRecipeWrapper.java index 3f6efdb..9fc2007 100644 --- a/src/java/mmm/recipes/RShapedOreRecipeWrapper.java +++ b/src/java/mmm/recipes/RShapedOreRecipeWrapper.java @@ -4,6 +4,7 @@ package mmm.recipes; import java.util.List; import mmm.core.api.recipes.I_CraftingRecipeWrapper; +import mmm.core.api.recipes.I_RecipeRequirements; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraftforge.fml.common.ObfuscationReflectionHelper; @@ -18,6 +19,7 @@ public class RShapedOreRecipeWrapper private final ShapedOreRecipe recipe; private final int width; private final int height; + private final RRequirements requirements; public RShapedOreRecipeWrapper( final ShapedOreRecipe recipe ) @@ -25,6 +27,7 @@ public class RShapedOreRecipeWrapper this.recipe = recipe; this.width = ObfuscationReflectionHelper.getPrivateValue( ShapedOreRecipe.class , this.recipe , "width" ); this.height = ObfuscationReflectionHelper.getPrivateValue( ShapedOreRecipe.class , this.recipe , "height" ); + this.requirements = ROreRecipeHelper.extractRequirements( recipe.getInput( ) ); } @@ -103,18 +106,9 @@ public class RShapedOreRecipeWrapper @Override - public boolean canCraft( final IInventory inventory ) + public I_RecipeRequirements getRequirements( ) { - // TODO Auto-generated method stub - return false; - } - - - @Override - public void craft( final IInventory input , final IInventory output , final int quantity ) - { - // TODO Auto-generated method stub - + return this.requirements; } } diff --git a/src/java/mmm/recipes/RShapedRecipeWrapper.java b/src/java/mmm/recipes/RShapedRecipeWrapper.java index 0852660..4b9b382 100644 --- a/src/java/mmm/recipes/RShapedRecipeWrapper.java +++ b/src/java/mmm/recipes/RShapedRecipeWrapper.java @@ -1,7 +1,10 @@ package mmm.recipes; +import java.util.ArrayList; + import mmm.core.api.recipes.I_CraftingRecipeWrapper; +import mmm.core.api.recipes.I_RecipeRequirements; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.ShapedRecipes; @@ -13,11 +16,40 @@ public class RShapedRecipeWrapper implements I_CraftingRecipeWrapper { private final ShapedRecipes recipe; + private final RRequirements requirements; public RShapedRecipeWrapper( final ShapedRecipes recipe ) { this.recipe = recipe; + this.requirements = new RRequirements( extractInputs( recipe ) ); + } + + + private static ArrayList< ItemStack > extractInputs( final ShapedRecipes recipe ) + { + ArrayList< ItemStack > inputs = new ArrayList<>( ); + for ( int i = 0 ; i < recipe.recipeWidth ; i++ ) { + RECIPE: for ( int j = 0 ; j < recipe.recipeHeight ; j++ ) { + ItemStack itemStack = recipe.recipeItems[ i + j * recipe.recipeWidth ]; + if ( itemStack == null ) { + continue; + } + + for ( int k = 0 ; k < inputs.size( ) ; k++ ) { + ItemStack input = inputs.get( k ); + if ( OreDictionary.itemMatches( input , itemStack , true ) ) { + input.stackSize++; + continue RECIPE; + } + } + + itemStack = itemStack.copy( ); + itemStack.stackSize = 1; + inputs.add( itemStack ); + } + } + return inputs; } @@ -72,23 +104,17 @@ public class RShapedRecipeWrapper } else { stack = stack.copy( ); } + stack.stackSize = 1; inventory.setInventorySlotContents( index , stack ); } - @Override - public boolean canCraft( final IInventory inventory ) - { - // TODO Auto-generated method stub - return false; - } - @Override - public void craft( final IInventory input , final IInventory output , final int quantity ) + public I_RecipeRequirements getRequirements( ) { - // TODO Auto-generated method stub - + return this.requirements; } + } diff --git a/src/java/mmm/recipes/RShapelessOreRecipeWrapper.java b/src/java/mmm/recipes/RShapelessOreRecipeWrapper.java index 59d0560..af69ef5 100644 --- a/src/java/mmm/recipes/RShapelessOreRecipeWrapper.java +++ b/src/java/mmm/recipes/RShapelessOreRecipeWrapper.java @@ -2,10 +2,10 @@ package mmm.recipes; import java.util.ArrayList; -import java.util.IdentityHashMap; import java.util.List; import mmm.core.api.recipes.I_CraftingRecipeWrapper; +import mmm.core.api.recipes.I_RecipeRequirements; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraftforge.oredict.OreDictionary; @@ -17,36 +17,13 @@ public class RShapelessOreRecipeWrapper implements I_CraftingRecipeWrapper { private final ShapelessOreRecipe recipe; - private final List< ItemStack > combinedInputStacks; - private final IdentityHashMap< List< ItemStack > , Integer > combinedInputOreLists; + private final RRequirements requirements; public RShapelessOreRecipeWrapper( final ShapelessOreRecipe recipe ) { this.recipe = recipe; - this.combinedInputStacks = new ArrayList<>( ); - this.combinedInputOreLists = new IdentityHashMap<>( ); - - OUTER: for ( final Object input : this.recipe.getInput( ) ) { - if ( input instanceof ItemStack ) { - final ItemStack invStack = (ItemStack) input; - for ( final ItemStack ciStack : this.combinedInputStacks ) { - if ( OreDictionary.itemMatches( ciStack , invStack , true ) ) { - ciStack.stackSize += invStack.stackSize; - continue OUTER; - } - } - this.combinedInputStacks.add( invStack.copy( ) ); - } else if ( input instanceof List ) { - @SuppressWarnings( "unchecked" ) - final List< ItemStack > oreList = (List< ItemStack >) input; - if ( this.combinedInputOreLists.containsKey( oreList ) ) { - this.combinedInputOreLists.put( oreList , this.combinedInputOreLists.get( oreList ) + 1 ); - } else { - this.combinedInputOreLists.put( oreList , 1 ); - } - } - } + this.requirements = ROreRecipeHelper.extractRequirements( recipe.getInput( ).toArray( ) ); } @@ -92,47 +69,23 @@ public class RShapelessOreRecipeWrapper @Override public void addInputsToDisplay( final IInventory displayInventory ) { - int i = 0; - for ( final ItemStack stack : this.combinedInputStacks ) { - RShapelessOreRecipeWrapper.setSlot( displayInventory , i++ , stack , stack.stackSize ); - } - for ( final List< ItemStack > oreList : this.combinedInputOreLists.keySet( ) ) { - if ( oreList.isEmpty( ) ) { - continue; + for ( int i = 0 ; i < this.requirements.size( ) ; i++ ) { + ItemStack stack = this.requirements.getItemTypes( i ).get( 0 ); + if ( stack.getMetadata( ) == OreDictionary.WILDCARD_VALUE ) { + stack = new ItemStack( stack.getItem( ) , 1 , 0 ); + } else { + stack = stack.copy( ); } - - final ItemStack stack = oreList.get( 0 ); - RShapelessOreRecipeWrapper.setSlot( displayInventory , i++ , stack , - this.combinedInputOreLists.get( oreList ) ); + stack.stackSize = this.requirements.getQuantity( i ); + displayInventory.setInventorySlotContents( i , stack ); } } - 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 ) + public I_RecipeRequirements getRequirements( ) { - // TODO Auto-generated method stub - return false; - } - - - @Override - public void craft( final IInventory input , final IInventory output , final int quantity ) - { - // TODO Auto-generated method stub - + return this.requirements; } } diff --git a/src/java/mmm/recipes/RShapelessRecipeWrapper.java b/src/java/mmm/recipes/RShapelessRecipeWrapper.java index e7b5bf1..ced3170 100644 --- a/src/java/mmm/recipes/RShapelessRecipeWrapper.java +++ b/src/java/mmm/recipes/RShapelessRecipeWrapper.java @@ -2,9 +2,9 @@ package mmm.recipes; import java.util.ArrayList; -import java.util.List; import mmm.core.api.recipes.I_CraftingRecipeWrapper; +import mmm.core.api.recipes.I_RecipeRequirements; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.ShapelessRecipes; @@ -17,23 +17,29 @@ public class RShapelessRecipeWrapper { private final ShapelessRecipes recipe; - private final List< ItemStack > combinedInputs; + private final RRequirements requirements; public RShapelessRecipeWrapper( final ShapelessRecipes recipe ) { this.recipe = recipe; + this.requirements = new RRequirements( RShapelessRecipeWrapper.extractInputs( recipe ) ); + } - this.combinedInputs = new ArrayList<>( ); - OUTER: for ( final ItemStack invStack : this.recipe.recipeItems ) { - for ( final ItemStack ciStack : this.combinedInputs ) { + + private static ArrayList< ItemStack > extractInputs( final ShapelessRecipes recipe ) + { + final ArrayList< ItemStack > combinedInputs = new ArrayList<>( ); + OUTER: for ( final ItemStack invStack : recipe.recipeItems ) { + for ( final ItemStack ciStack : combinedInputs ) { if ( OreDictionary.itemMatches( ciStack , invStack , true ) ) { ciStack.stackSize += invStack.stackSize; continue OUTER; } } - this.combinedInputs.add( invStack.copy( ) ); + combinedInputs.add( invStack.copy( ) ); } + return combinedInputs; } @@ -70,58 +76,23 @@ public class RShapelessRecipeWrapper @Override public void addInputsToDisplay( final IInventory displayInventory ) { - int i = 0; - for ( ItemStack stack : this.combinedInputs ) { + for ( int i = 0 ; i < this.requirements.size( ) ; i++ ) { + ItemStack stack = this.requirements.getItemTypes( i ).get( 0 ); if ( stack.getMetadata( ) == OreDictionary.WILDCARD_VALUE ) { stack = new ItemStack( stack.getItem( ) , 1 , 0 ); } else { stack = stack.copy( ); } - RShapelessRecipeWrapper.setSlot( displayInventory , i++ , stack ); + stack.stackSize = this.requirements.getQuantity( i ); + displayInventory.setInventorySlotContents( 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 ); - } - - @Override - public boolean canCraft( final IInventory inventory ) + public I_RecipeRequirements getRequirements( ) { - final int nInputs = this.combinedInputs.size( ); - final int nInvItems = inventory.getSizeInventory( ); - for ( int i = 0 ; i < nInputs ; i++ ) { - final ItemStack rStack = this.combinedInputs.get( i ); - int nLeft = rStack.stackSize; - - for ( int j = 0 ; j < nInvItems && nLeft > 0 ; j++ ) { - final ItemStack invStack = inventory.getStackInSlot( j ); - if ( OreDictionary.itemMatches( rStack , invStack , false ) ) { - nLeft -= invStack.stackSize; - } - } - - if ( nLeft > 0 ) { - return false; - } - } - return true; - } - - - @Override - public void craft( final IInventory input , final IInventory output , final int quantity ) - { - // TODO Auto-generated method stub - + return this.requirements; } } diff --git a/src/java/mmm/tech/base/workbench/TBWBGui.java b/src/java/mmm/tech/base/workbench/TBWBGui.java index fe8e25d..3384e32 100644 --- a/src/java/mmm/tech/base/workbench/TBWBGui.java +++ b/src/java/mmm/tech/base/workbench/TBWBGui.java @@ -8,14 +8,18 @@ import java.util.List; import mmm.Mmm; import mmm.core.CNetwork; import mmm.core.api.recipes.I_CraftingRecipeWrapper; +import mmm.core.api.recipes.I_RecipeRequirements; import mmm.recipes.RCraftingWrappers; import mmm.utils.gui.A_UGContainerScreen; import mmm.utils.gui.UGArrowButton; +import mmm.utils.gui.UGui; +import mmm.utils.gui.UGui.E_Icon; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiTextField; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -87,6 +91,18 @@ public class TBWBGui this.mc.getTextureManager( ).bindTexture( TBWBGui.BACKGROUND ); this.drawTexturedModalRect( this.guiLeft , this.guiTop , 0 , 0 , this.xSize , this.ySize ); + boolean canCraft; + if ( this.currentRecipe == -1 ) { + canCraft = false; + } else { + TileEntity te = this.container.world.getTileEntity( this.container.position ); + I_RecipeRequirements requirements = this.recipes.get( this.currentRecipe ).getRequirements( ); + canCraft = te instanceof TBWBTileEntity && requirements.checkInventory( ( (TBWBTileEntity) te ).storage ); + } + if ( !canCraft ) { + UGui.drawIcon( this , this.guiLeft + 147 , this.guiTop + 51 , E_Icon.RED_CROSS ); + } + GlStateManager.disableBlend( ); this.tfSearch.drawTextBox( ); } diff --git a/src/java/mmm/utils/gui/UGui.java b/src/java/mmm/utils/gui/UGui.java index 374b895..173be1f 100644 --- a/src/java/mmm/utils/gui/UGui.java +++ b/src/java/mmm/utils/gui/UGui.java @@ -1,12 +1,35 @@ package mmm.utils.gui; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; -public enum UGui { - INSTANCE; +public class UGui +{ + public static enum E_Icon { + RED_CROSS( 26 , 30 , 13 , 13 ), + // + ; + + public final int x; + public final int y; + public final int width; + public final int height; + + + private E_Icon( final int x , final int y , final int w , final int h ) + { + this.x = x; + this.y = y; + this.width = w; + this.height = h; + } + } public static final int TAB_TEXTURE_X = 0; public static final int TAB_TEXTURE_Y = 0; @@ -26,4 +49,11 @@ public enum UGui { public static final ResourceLocation GUI_TEXTURE = new ResourceLocation( "mmm" , "textures/gui/gui-common.png" ); + + @SideOnly( Side.CLIENT ) + public static void drawIcon( final Gui gui , final int x , final int y , final E_Icon icon ) + { + Minecraft.getMinecraft( ).getTextureManager( ).bindTexture( UGui.GUI_TEXTURE ); + gui.drawTexturedModalRect( x , y , icon.x , icon.y , icon.width , icon.height ); + } } diff --git a/src/resources/assets/mmm/textures/gui/gui-common.png b/src/resources/assets/mmm/textures/gui/gui-common.png index 37da863..86a5fc4 100644 Binary files a/src/resources/assets/mmm/textures/gui/gui-common.png and b/src/resources/assets/mmm/textures/gui/gui-common.png differ