diff --git a/src/api/java/appeng/api/config/ItemSubstitution.java b/src/api/java/appeng/api/config/ItemSubstitution.java new file mode 100644 index 00000000..330dba7d --- /dev/null +++ b/src/api/java/appeng/api/config/ItemSubstitution.java @@ -0,0 +1,30 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 AlgorithmX2 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package appeng.api.config; + + +public enum ItemSubstitution +{ + ENABLED, DISABLED; +} diff --git a/src/main/java/appeng/client/gui/implementations/GuiPatternTerm.java b/src/main/java/appeng/client/gui/implementations/GuiPatternTerm.java index db16bdfe..0efc688d 100644 --- a/src/main/java/appeng/client/gui/implementations/GuiPatternTerm.java +++ b/src/main/java/appeng/client/gui/implementations/GuiPatternTerm.java @@ -27,6 +27,7 @@ import net.minecraft.init.Blocks; import net.minecraft.item.ItemStack; import appeng.api.config.ActionItems; +import appeng.api.config.ItemSubstitution; import appeng.api.config.Settings; import appeng.api.storage.ITerminalHost; import appeng.client.gui.widgets.GuiImgButton; @@ -41,13 +42,20 @@ import appeng.core.sync.packets.PacketValueConfig; public class GuiPatternTerm extends GuiMEMonitorable { - final ContainerPatternTerm container; + private static final String SUBSITUTION_DISABLE = "0"; + private static final String SUBSITUTION_ENABLE = "1"; - GuiTabButton tabCraftButton; - GuiTabButton tabProcessButton; - // GuiImgButton substitutionsBtn; - GuiImgButton encodeBtn; - GuiImgButton clearBtn; + private static final String CRAFTMODE_CRFTING = "1"; + private static final String CRAFTMODE_PROCESSING = "0"; + + private final ContainerPatternTerm container; + + private GuiTabButton tabCraftButton; + private GuiTabButton tabProcessButton; + private GuiImgButton substitutionsEnabledBtn; + private GuiImgButton substitutionsDisabledBtn; + private GuiImgButton encodeBtn; + private GuiImgButton clearBtn; public GuiPatternTerm( final InventoryPlayer inventoryPlayer, final ITerminalHost te ) { @@ -66,7 +74,7 @@ public class GuiPatternTerm extends GuiMEMonitorable if( this.tabCraftButton == btn || this.tabProcessButton == btn ) { - NetworkHandler.instance.sendToServer( new PacketValueConfig( "PatternTerminal.CraftMode", this.tabProcessButton == btn ? "1" : "0" ) ); + NetworkHandler.instance.sendToServer( new PacketValueConfig( "PatternTerminal.CraftMode", this.tabProcessButton == btn ? CRAFTMODE_CRFTING : CRAFTMODE_PROCESSING ) ); } if( this.encodeBtn == btn ) @@ -78,34 +86,43 @@ public class GuiPatternTerm extends GuiMEMonitorable { NetworkHandler.instance.sendToServer( new PacketValueConfig( "PatternTerminal.Clear", "1" ) ); } + + if( this.substitutionsEnabledBtn == btn || this.substitutionsDisabledBtn == btn ) + { + NetworkHandler.instance.sendToServer( new PacketValueConfig( "PatternTerminal.Substitute", this.substitutionsEnabledBtn == btn ? SUBSITUTION_DISABLE : SUBSITUTION_ENABLE ) ); + } } catch( final IOException e ) { // TODO Auto-generated catch block e.printStackTrace(); } - - // if ( substitutionsBtn == btn ) - // { - - // } } @Override public void initGui() { super.initGui(); - this.buttonList.add( this.tabCraftButton = new GuiTabButton( this.guiLeft + 173, this.guiTop + this.ySize - 177, new ItemStack( Blocks.crafting_table ), GuiText.CraftingPattern.getLocal(), itemRender ) ); - this.buttonList.add( this.tabProcessButton = new GuiTabButton( this.guiLeft + 173, this.guiTop + this.ySize - 177, new ItemStack( Blocks.furnace ), GuiText.ProcessingPattern.getLocal(), itemRender ) ); + this.tabCraftButton = new GuiTabButton( this.guiLeft + 173, this.guiTop + this.ySize - 177, new ItemStack( Blocks.crafting_table ), GuiText.CraftingPattern.getLocal(), itemRender ); + this.buttonList.add( this.tabCraftButton ); - // buttonList.add( substitutionsBtn = new GuiImgButton( this.guiLeft + 84, this.guiTop + this.ySize - 163, - // Settings.ACTIONS, ActionItems.SUBSTITUTION ) ); - // substitutionsBtn.halfSize = true; + this.tabProcessButton = new GuiTabButton( this.guiLeft + 173, this.guiTop + this.ySize - 177, new ItemStack( Blocks.furnace ), GuiText.ProcessingPattern.getLocal(), itemRender ); + this.buttonList.add( this.tabProcessButton ); - this.buttonList.add( this.clearBtn = new GuiImgButton( this.guiLeft + 74, this.guiTop + this.ySize - 163, Settings.ACTIONS, ActionItems.CLOSE ) ); + this.substitutionsEnabledBtn = new GuiImgButton( this.guiLeft + 84, this.guiTop + this.ySize - 163, Settings.ACTIONS, ItemSubstitution.ENABLED ); + this.substitutionsEnabledBtn.halfSize = true; + this.buttonList.add( this.substitutionsEnabledBtn ); + + this.substitutionsDisabledBtn = new GuiImgButton( this.guiLeft + 84, this.guiTop + this.ySize - 163, Settings.ACTIONS, ItemSubstitution.DISABLED ); + this.substitutionsDisabledBtn.halfSize = true; + this.buttonList.add( this.substitutionsDisabledBtn ); + + this.clearBtn = new GuiImgButton( this.guiLeft + 74, this.guiTop + this.ySize - 163, Settings.ACTIONS, ActionItems.CLOSE ); this.clearBtn.halfSize = true; + this.buttonList.add( this.clearBtn ); - this.buttonList.add( this.encodeBtn = new GuiImgButton( this.guiLeft + 147, this.guiTop + this.ySize - 142, Settings.ACTIONS, ActionItems.ENCODE ) ); + this.encodeBtn = new GuiImgButton( this.guiLeft + 147, this.guiTop + this.ySize - 142, Settings.ACTIONS, ActionItems.ENCODE ); + this.buttonList.add( this.encodeBtn ); } @Override @@ -122,6 +139,17 @@ public class GuiPatternTerm extends GuiMEMonitorable this.tabProcessButton.visible = false; } + if( this.container.substitute ) + { + this.substitutionsEnabledBtn.visible = true; + this.substitutionsDisabledBtn.visible = false; + } + else + { + this.substitutionsEnabledBtn.visible = false; + this.substitutionsDisabledBtn.visible = true; + } + super.drawFG( offsetX, offsetY, mouseX, mouseY ); this.fontRendererObj.drawString( GuiText.PatternTerminal.getLocal(), 8, this.ySize - 96 + 2 - this.reservedSpace, 4210752 ); } diff --git a/src/main/java/appeng/client/gui/widgets/GuiImgButton.java b/src/main/java/appeng/client/gui/widgets/GuiImgButton.java index 45e9bd3d..529c3142 100644 --- a/src/main/java/appeng/client/gui/widgets/GuiImgButton.java +++ b/src/main/java/appeng/client/gui/widgets/GuiImgButton.java @@ -34,6 +34,7 @@ import appeng.api.config.ActionItems; import appeng.api.config.CondenserOutput; import appeng.api.config.FullnessMode; import appeng.api.config.FuzzyMode; +import appeng.api.config.ItemSubstitution; import appeng.api.config.LevelType; import appeng.api.config.OperationMode; import appeng.api.config.PowerUnits; @@ -129,7 +130,8 @@ public class GuiImgButton extends GuiButton implements ITooltip this.registerApp( 6, Settings.ACTIONS, ActionItems.STASH, ButtonToolTips.Stash, ButtonToolTips.StashDesc ); this.registerApp( 8, Settings.ACTIONS, ActionItems.ENCODE, ButtonToolTips.Encode, ButtonToolTips.EncodeDescription ); - this.registerApp( 4 + 3 * 16, Settings.ACTIONS, ActionItems.SUBSTITUTION, ButtonToolTips.Substitutions, ButtonToolTips.SubstitutionsDesc ); + this.registerApp( 4 + 3 * 16, Settings.ACTIONS, ItemSubstitution.ENABLED, ButtonToolTips.Substitutions, ButtonToolTips.SubstitutionsDescEnabled ); + this.registerApp( 7 + 3 * 16, Settings.ACTIONS, ItemSubstitution.DISABLED, ButtonToolTips.Substitutions, ButtonToolTips.SubstitutionsDescDisabled ); this.registerApp( 16, Settings.VIEW_MODE, ViewItems.STORED, ButtonToolTips.View, ButtonToolTips.StoredItems ); this.registerApp( 18, Settings.VIEW_MODE, ViewItems.ALL, ButtonToolTips.View, ButtonToolTips.StoredCraftable ); diff --git a/src/main/java/appeng/container/implementations/ContainerPatternTerm.java b/src/main/java/appeng/container/implementations/ContainerPatternTerm.java index 07ceda66..fd56633c 100644 --- a/src/main/java/appeng/container/implementations/ContainerPatternTerm.java +++ b/src/main/java/appeng/container/implementations/ContainerPatternTerm.java @@ -71,15 +71,17 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA { public final PartPatternTerminal ct; - final AppEngInternalInventory cOut = new AppEngInternalInventory( null, 1 ); - final IInventory crafting; - final SlotFakeCraftingMatrix[] craftingSlots = new SlotFakeCraftingMatrix[9]; - final OptionalSlotFake[] outputSlots = new OptionalSlotFake[3]; - final SlotPatternTerm craftSlot; - final SlotRestrictedInput patternSlotIN; - final SlotRestrictedInput patternSlotOUT; + private final AppEngInternalInventory cOut = new AppEngInternalInventory( null, 1 ); + private final IInventory crafting; + private final SlotFakeCraftingMatrix[] craftingSlots = new SlotFakeCraftingMatrix[9]; + private final OptionalSlotFake[] outputSlots = new OptionalSlotFake[3]; + private final SlotPatternTerm craftSlot; + private final SlotRestrictedInput patternSlotIN; + private final SlotRestrictedInput patternSlotOUT; @GuiSync( 97 ) public boolean craftingMode = true; + @GuiSync( 96 ) + public boolean substitute = false; public ContainerPatternTerm( final InventoryPlayer ip, final ITerminalHost monitorable ) { @@ -88,6 +90,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA final IInventory patternInv = this.ct.getInventoryByName( "pattern" ); final IInventory output = this.ct.getInventoryByName( "output" ); + this.crafting = this.ct.getInventoryByName( "crafting" ); for( int y = 0; y < 3; y++ ) @@ -156,6 +159,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA public ItemStack getAndUpdateOutput() { final InventoryCrafting ic = new InventoryCrafting( this, 3, 3 ); + for( int x = 0; x < ic.getSizeInventory(); x++ ) { ic.setInventorySlotContents( x, this.crafting.getStackInSlot( x ) ); @@ -238,6 +242,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA encodedValue.setTag( "in", tagIn ); encodedValue.setTag( "out", tagOut ); encodedValue.setBoolean( "crafting", this.craftingMode ); + encodedValue.setBoolean( "substitute", this.substitute ); output.setTagCompound( encodedValue ); } @@ -269,6 +274,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA if( this.craftingMode ) { final ItemStack out = this.getAndUpdateOutput(); + if( out != null && out.stackSize > 0 ) { return new ItemStack[] { out }; @@ -282,6 +288,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA for( final OptionalSlotFake outputSlot : this.outputSlots ) { final ItemStack out = outputSlot.getStack(); + if( out != null && out.stackSize > 0 ) { list.add( out ); @@ -347,9 +354,9 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA if( packetPatternSlot.slotItem != null && this.cellInv != null ) { final IAEItemStack out = packetPatternSlot.slotItem.copy(); - InventoryAdaptor inv = new AdaptorPlayerHand( this.getPlayerInv().player ); final InventoryAdaptor playerInv = InventoryAdaptor.getAdaptor( this.getPlayerInv().player, ForgeDirection.UNKNOWN ); + if( packetPatternSlot.shift ) { inv = playerInv; @@ -376,6 +383,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA final InventoryCrafting ic = new InventoryCrafting( new ContainerNull(), 3, 3 ); final InventoryCrafting real = new InventoryCrafting( new ContainerNull(), 3, 3 ); + for( int x = 0; x < 9; x++ ) { ic.setInventorySlotContents( x, packetPatternSlot.pattern[x] == null ? null : packetPatternSlot.pattern[x].getItemStack() ); @@ -412,6 +420,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA for( int x = 0; x < real.getSizeInventory(); x++ ) { final ItemStack failed = playerInv.addItems( real.getStackInSlot( x ) ); + if( failed != null ) { p.dropPlayerItemWithRandomChoice( failed, false ); @@ -450,6 +459,8 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA this.craftingMode = this.ct.isCraftingRecipe(); this.updateOrderOfOutputSlots(); } + + this.substitute = this.ct.isSubstitution(); } } @@ -519,4 +530,12 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA { return false; } + + public void toggleSubstitute() + { + this.substitute = !this.substitute; + + this.detectAndSendChanges(); + this.getAndUpdateOutput(); + } } diff --git a/src/main/java/appeng/core/localization/ButtonToolTips.java b/src/main/java/appeng/core/localization/ButtonToolTips.java index b740b969..9384ee8b 100644 --- a/src/main/java/appeng/core/localization/ButtonToolTips.java +++ b/src/main/java/appeng/core/localization/ButtonToolTips.java @@ -54,7 +54,7 @@ public enum ButtonToolTips LevelType, LevelType_Energy, LevelType_Item, InventoryTweaks, TerminalStyle, TerminalStyle_Full, TerminalStyle_Tall, TerminalStyle_Small, - Stash, StashDesc, Encode, EncodeDescription, Substitutions, SubstitutionsOn, SubstitutionsOff, SubstitutionsDesc, CraftOnly, CraftEither, + Stash, StashDesc, Encode, EncodeDescription, Substitutions, SubstitutionsOn, SubstitutionsOff, SubstitutionsDescEnabled, SubstitutionsDescDisabled, CraftOnly, CraftEither, Craft, Mod, DoesntDespawn, EmitterMode, CraftViaRedstone, EmitWhenCrafting, ReportInaccessibleItems, ReportInaccessibleItemsYes, ReportInaccessibleItemsNo, diff --git a/src/main/java/appeng/core/localization/GuiText.java b/src/main/java/appeng/core/localization/GuiText.java index 4d251ed7..fd7d0ce5 100644 --- a/src/main/java/appeng/core/localization/GuiText.java +++ b/src/main/java/appeng/core/localization/GuiText.java @@ -47,9 +47,20 @@ public enum GuiText // tunnel names METunnel, ItemTunnel, RedstoneTunnel, EUTunnel, FluidTunnel, OCTunnel, LightTunnel, RFTunnel, PressureTunnel, - StoredSize, CopyMode, CopyModeDesc, PatternTerminal, CraftingPattern, + StoredSize, CopyMode, CopyModeDesc, PatternTerminal, - ProcessingPattern, Crafts, Creates, And, With, MolecularAssembler, + // Pattern tooltips + CraftingPattern, + ProcessingPattern, + Crafts, + Creates, + And, + With, + Substitute, + Yes, + No, + + MolecularAssembler, StoredPower, MaxPower, RequiredPower, Efficiency, InWorldCrafting, diff --git a/src/main/java/appeng/core/sync/packets/PacketValueConfig.java b/src/main/java/appeng/core/sync/packets/PacketValueConfig.java index a1cb07d2..762aeb73 100644 --- a/src/main/java/appeng/core/sync/packets/PacketValueConfig.java +++ b/src/main/java/appeng/core/sync/packets/PacketValueConfig.java @@ -59,8 +59,8 @@ import appeng.helpers.IMouseWheelItem; public class PacketValueConfig extends AppEngPacket { - public final String Name; - public final String Value; + private final String Name; + private final String Value; // automatic. public PacketValueConfig( final ByteBuf stream ) throws IOException @@ -158,6 +158,10 @@ public class PacketValueConfig extends AppEngPacket { cpt.clear(); } + else if( this.Name.equals( "PatternTerminal.Substitute" ) ) + { + cpt.ct.setSubstitution( this.Value.equals( "1" ) ); + } } else if( this.Name.startsWith( "StorageBus." ) && c instanceof ContainerStorageBus ) { diff --git a/src/main/java/appeng/crafting/CraftingTreeNode.java b/src/main/java/appeng/crafting/CraftingTreeNode.java index 40431271..06672d16 100644 --- a/src/main/java/appeng/crafting/CraftingTreeNode.java +++ b/src/main/java/appeng/crafting/CraftingTreeNode.java @@ -20,9 +20,12 @@ package appeng.crafting; import java.util.ArrayList; +import java.util.Collection; import java.util.LinkedList; import java.util.List; +import com.google.common.collect.Lists; + import net.minecraft.world.World; import appeng.api.AEApi; @@ -41,8 +44,8 @@ public class CraftingTreeNode // what slot! final int slot; - final CraftingJob job; - final IItemList used = AEApi.instance().storage().createItemList(); + private final CraftingJob job; + private final IItemList used = AEApi.instance().storage().createItemList(); // parent node. private final CraftingTreeProcess parent; private final World world; @@ -50,14 +53,13 @@ public class CraftingTreeNode private final IAEItemStack what; // what are the crafting patterns for this? private final ArrayList nodes = new ArrayList(); - int bytes = 0; - boolean canEmit = false; - boolean cannotUse = false; - long missing = 0; - long howManyEmitted = 0; - boolean exhausted = false; - - boolean sim; + private int bytes = 0; + private boolean canEmit = false; + private boolean cannotUse = false; + private long missing = 0; + private long howManyEmitted = 0; + private boolean exhausted = false; + private boolean sim; public CraftingTreeNode( final ICraftingGrid cc, final CraftingJob job, final IAEItemStack wat, final CraftingTreeProcess par, final int slot, final int depth ) { @@ -69,6 +71,7 @@ public class CraftingTreeNode this.sim = false; this.canEmit = cc.canEmitFor( this.what ); + if( this.canEmit ) { return; // if you can emit for something, you can't make it with patterns. @@ -87,6 +90,7 @@ public class CraftingTreeNode boolean notRecursive( final ICraftingPatternDetails details ) { IAEItemStack[] o = details.getCondensedOutputs(); + for( final IAEItemStack i : o ) { if( i.equals( this.what ) ) @@ -96,6 +100,7 @@ public class CraftingTreeNode } o = details.getCondensedInputs(); + for( final IAEItemStack i : o ) { if( i.equals( this.what ) ) @@ -121,12 +126,32 @@ public class CraftingTreeNode this.what.setStackSize( l ); if( this.slot >= 0 && this.parent != null && this.parent.details.isCraftable() ) { - for( IAEItemStack fuzz : inv.getItemList().findFuzzy( this.what, FuzzyMode.IGNORE_ALL ) ) + final Collection itemList; + final IItemList inventoryList = inv.getItemList(); + + if( this.parent.details.canSubstitute() ) + { + itemList = inventoryList.findFuzzy( this.what, FuzzyMode.IGNORE_ALL ); + } + else + { + itemList = Lists.newArrayList(); + + final IAEItemStack item = inventoryList.findPrecise( this.what ); + + if( item != null ) + { + itemList.add( item ); + } + } + + for( IAEItemStack fuzz : itemList ) { if( this.parent.details.isValidItemForSlot( this.slot, fuzz.getItemStack(), this.world ) ) { fuzz = fuzz.copy(); fuzz.setStackSize( l ); + final IAEItemStack available = inv.extractItems( fuzz, Actionable.MODULATE, src ); if( available != null ) @@ -134,6 +159,7 @@ public class CraftingTreeNode if( !this.exhausted ) { final IAEItemStack is = this.job.checkUse( available ); + if( is != null ) { thingsUsed.add( is.copy() ); @@ -161,6 +187,7 @@ public class CraftingTreeNode if( !this.exhausted ) { final IAEItemStack is = this.job.checkUse( available ); + if( is != null ) { thingsUsed.add( is.copy() ); @@ -202,6 +229,7 @@ public class CraftingTreeNode pro.request( inv, pro.getTimes( l, madeWhat.getStackSize() ), src ); madeWhat.setStackSize( l ); + final IAEItemStack available = inv.extractItems( madeWhat, Actionable.MODULATE, src ); if( available != null ) diff --git a/src/main/java/appeng/helpers/PatternHelper.java b/src/main/java/appeng/helpers/PatternHelper.java index ba70508f..a08e603e 100644 --- a/src/main/java/appeng/helpers/PatternHelper.java +++ b/src/main/java/appeng/helpers/PatternHelper.java @@ -23,6 +23,8 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Set; import net.minecraft.inventory.InventoryCrafting; import net.minecraft.item.Item; @@ -45,20 +47,21 @@ import appeng.util.item.AEItemStack; public class PatternHelper implements ICraftingPatternDetails, Comparable { - final ItemStack patternItem; - final InventoryCrafting crafting = new InventoryCrafting( new ContainerNull(), 3, 3 ); - final InventoryCrafting testFrame = new InventoryCrafting( new ContainerNull(), 3, 3 ); - final ItemStack correctOutput; - final IRecipe standardRecipe; - final IAEItemStack[] condensedInputs; - final IAEItemStack[] condensedOutputs; - final IAEItemStack[] inputs; - final IAEItemStack[] outputs; - final boolean isCrafting; - final HashSet failCache = new HashSet(); - final HashSet passCache = new HashSet(); + private final ItemStack patternItem; + private final InventoryCrafting crafting = new InventoryCrafting( new ContainerNull(), 3, 3 ); + private final InventoryCrafting testFrame = new InventoryCrafting( new ContainerNull(), 3, 3 ); + private final ItemStack correctOutput; + private final IRecipe standardRecipe; + private final IAEItemStack[] condensedInputs; + private final IAEItemStack[] condensedOutputs; + private final IAEItemStack[] inputs; + private final IAEItemStack[] outputs; + private final boolean isCrafting; + private final boolean canSubstitute; + private final Set failCache = new HashSet(); + private final Set passCache = new HashSet(); private final IAEItemStack pattern; - public int priority = 0; + private int priority = 0; public PatternHelper( final ItemStack is, final World w ) { @@ -72,6 +75,8 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable tmpOutputs = new HashMap(); + final Map tmpOutputs = new HashMap(); + for( final IAEItemStack io : this.outputs ) { if( io == null ) @@ -132,6 +141,7 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable tmpInputs = new HashMap(); + final Map tmpInputs = new HashMap(); + for( final IAEItemStack io : this.inputs ) { if( io == null ) @@ -151,6 +162,7 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable