diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/solderer/ISoldererRecipe.java b/src/main/java/com/raoulvdberge/refinedstorage/api/solderer/ISoldererRecipe.java index e6eb42bc0..e4c55aac5 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/api/solderer/ISoldererRecipe.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/solderer/ISoldererRecipe.java @@ -3,7 +3,6 @@ package com.raoulvdberge.refinedstorage.api.solderer; import net.minecraft.item.ItemStack; import javax.annotation.Nonnull; -import javax.annotation.Nullable; /** * Represents a recipe in the solderer. @@ -11,9 +10,9 @@ import javax.annotation.Nullable; public interface ISoldererRecipe { /** * @param row the row in the solderer that we want the stack for (between 0 - 2) - * @return a stack for the given row, or null for no stack + * @return a stack for the given row, or empty stack for no stack */ - @Nullable + @Nonnull ItemStack getRow(int row); /** diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/solderer/ISoldererRegistry.java b/src/main/java/com/raoulvdberge/refinedstorage/api/solderer/ISoldererRegistry.java index 64f1b5dad..c404898a9 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/api/solderer/ISoldererRegistry.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/solderer/ISoldererRegistry.java @@ -37,7 +37,7 @@ public interface ISoldererRegistry { * * @param result the result * @param duration the duration in ticks - * @param rows the rows of this recipe, has to be 3 rows (null for an empty row) + * @param rows the rows of this recipe, has to be 3 rows (empty item stack for empty row) * @return a solderer recipe */ @Nonnull diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/util/IComparer.java b/src/main/java/com/raoulvdberge/refinedstorage/api/util/IComparer.java index b7f9ffbec..3ff6cc712 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/api/util/IComparer.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/util/IComparer.java @@ -3,6 +3,8 @@ package com.raoulvdberge.refinedstorage.api.util; import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.FluidStack; +import javax.annotation.Nullable; + /** * Utilities for comparing item and fluid stacks. */ @@ -20,7 +22,7 @@ public interface IComparer { * @param flags the flags to compare with * @return true if the left and right stack are the same, false otherwise */ - boolean isEqual(ItemStack left, ItemStack right, int flags); + boolean isEqual(@Nullable ItemStack left, @Nullable ItemStack right, int flags); /** * Compares two stacks by NBT, damage and quantity. @@ -29,7 +31,7 @@ public interface IComparer { * @param right the right stack * @return true if the left and right stack are the same, false otherwise */ - default boolean isEqual(ItemStack left, ItemStack right) { + default boolean isEqual(@Nullable ItemStack left, @Nullable ItemStack right) { return isEqual(left, right, COMPARE_NBT | COMPARE_DAMAGE | COMPARE_QUANTITY); } @@ -40,7 +42,7 @@ public interface IComparer { * @param right the right stack * @return true if the left and right stack are the same, false otherwise */ - default boolean isEqualNoQuantity(ItemStack left, ItemStack right) { + default boolean isEqualNoQuantity(@Nullable ItemStack left, @Nullable ItemStack right) { return isEqual(left, right, COMPARE_NBT | COMPARE_DAMAGE); } @@ -52,7 +54,7 @@ public interface IComparer { * @param flags the flags to compare with * @return true if the left and right stack are the same, false otherwise */ - boolean isEqual(FluidStack left, FluidStack right, int flags); + boolean isEqual(@Nullable FluidStack left, @Nullable FluidStack right, int flags); /** * Compares the NBT tags of two stacks. @@ -61,7 +63,7 @@ public interface IComparer { * @param right the right stack * @return true if the NBT tags of the two stacks are the same, false otherwise */ - boolean isEqualNBT(ItemStack left, ItemStack right); + boolean isEqualNBT(@Nullable ItemStack left, @Nullable ItemStack right); /** * Compares two stacks and checks if they share the same ore dictionary entry. @@ -70,5 +72,5 @@ public interface IComparer { * @param right the right stack * @return true if the two stacks share the same ore dictionary entry */ - boolean isEqualOredict(ItemStack left, ItemStack right); + boolean isEqualOredict(@Nullable ItemStack left, @Nullable ItemStack right); } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/solderer/SoldererRecipeFluidStorage.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/solderer/SoldererRecipeFluidStorage.java index f8904d3fc..9a03c9674 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/solderer/SoldererRecipeFluidStorage.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/solderer/SoldererRecipeFluidStorage.java @@ -7,27 +7,26 @@ import com.raoulvdberge.refinedstorage.block.EnumFluidStorageType; import com.raoulvdberge.refinedstorage.item.ItemBlockFluidStorage; import com.raoulvdberge.refinedstorage.item.ItemProcessor; import net.minecraft.item.ItemStack; +import net.minecraft.util.NonNullList; import javax.annotation.Nonnull; -import javax.annotation.Nullable; public class SoldererRecipeFluidStorage implements ISoldererRecipe { private EnumFluidStorageType type; - private ItemStack[] rows; + private NonNullList rows = NonNullList.create(); public SoldererRecipeFluidStorage(EnumFluidStorageType type, int storagePart) { this.type = type; - this.rows = new ItemStack[]{ - new ItemStack(RSItems.PROCESSOR, 1, ItemProcessor.TYPE_BASIC), - new ItemStack(RSBlocks.MACHINE_CASING), - new ItemStack(RSItems.FLUID_STORAGE_PART, 1, storagePart) - }; + + this.rows.add(new ItemStack(RSItems.PROCESSOR, 1, ItemProcessor.TYPE_BASIC)); + this.rows.add(new ItemStack(RSBlocks.MACHINE_CASING)); + this.rows.add(new ItemStack(RSItems.FLUID_STORAGE_PART, 1, storagePart)); } @Override - @Nullable + @Nonnull public ItemStack getRow(int row) { - return rows[row]; + return rows.get(row); } @Override diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/solderer/SoldererRecipePrintedProcessor.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/solderer/SoldererRecipePrintedProcessor.java index 7470bd016..3b26e8acc 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/solderer/SoldererRecipePrintedProcessor.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/solderer/SoldererRecipePrintedProcessor.java @@ -7,12 +7,11 @@ import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import javax.annotation.Nonnull; -import javax.annotation.Nullable; public class SoldererRecipePrintedProcessor implements ISoldererRecipe { private int type; - private ItemStack requirement; private ItemStack result; + private ItemStack requirement; public SoldererRecipePrintedProcessor(int type) { this.type = type; @@ -35,13 +34,9 @@ public class SoldererRecipePrintedProcessor implements ISoldererRecipe { } @Override - @Nullable + @Nonnull public ItemStack getRow(int row) { - if (row == 1) { - return requirement; - } - - return null; + return row == 1 ? requirement : ItemStack.EMPTY; } @Override diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/solderer/SoldererRecipeProcessor.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/solderer/SoldererRecipeProcessor.java index b88cb419f..d2be51e6b 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/solderer/SoldererRecipeProcessor.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/solderer/SoldererRecipeProcessor.java @@ -5,44 +5,42 @@ import com.raoulvdberge.refinedstorage.api.solderer.ISoldererRecipe; import com.raoulvdberge.refinedstorage.item.ItemProcessor; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; +import net.minecraft.util.NonNullList; import javax.annotation.Nonnull; -import javax.annotation.Nullable; public class SoldererRecipeProcessor implements ISoldererRecipe { private int type; - private ItemStack[] rows; private ItemStack result; + private NonNullList rows = NonNullList.create(); public SoldererRecipeProcessor(int type) { this.type = type; - ItemStack printedProcessor = null; + this.result = new ItemStack(RSItems.PROCESSOR, 1, type); + this.rows.add(createPrintedProcessor()); + this.rows.add(new ItemStack(Items.REDSTONE)); + this.rows.add(new ItemStack(RSItems.PROCESSOR, 1, ItemProcessor.TYPE_PRINTED_SILICON)); + } + + private ItemStack createPrintedProcessor() { switch (type) { case ItemProcessor.TYPE_BASIC: - printedProcessor = new ItemStack(RSItems.PROCESSOR, 1, ItemProcessor.TYPE_PRINTED_BASIC); - break; + return new ItemStack(RSItems.PROCESSOR, 1, ItemProcessor.TYPE_PRINTED_BASIC); case ItemProcessor.TYPE_IMPROVED: - printedProcessor = new ItemStack(RSItems.PROCESSOR, 1, ItemProcessor.TYPE_PRINTED_IMPROVED); - break; + return new ItemStack(RSItems.PROCESSOR, 1, ItemProcessor.TYPE_PRINTED_IMPROVED); case ItemProcessor.TYPE_ADVANCED: - printedProcessor = new ItemStack(RSItems.PROCESSOR, 1, ItemProcessor.TYPE_PRINTED_ADVANCED); - break; + return new ItemStack(RSItems.PROCESSOR, 1, ItemProcessor.TYPE_PRINTED_ADVANCED); + default: + return ItemStack.EMPTY; } - - this.result = new ItemStack(RSItems.PROCESSOR, 1, type); - this.rows = new ItemStack[]{ - printedProcessor, - new ItemStack(Items.REDSTONE), - new ItemStack(RSItems.PROCESSOR, 1, ItemProcessor.TYPE_PRINTED_SILICON) - }; } @Override - @Nullable + @Nonnull public ItemStack getRow(int row) { - return rows[row]; + return rows.get(row); } @Override diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/solderer/SoldererRecipeStorage.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/solderer/SoldererRecipeStorage.java index 893ae3276..f950d6ddb 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/solderer/SoldererRecipeStorage.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/solderer/SoldererRecipeStorage.java @@ -7,27 +7,26 @@ import com.raoulvdberge.refinedstorage.block.EnumItemStorageType; import com.raoulvdberge.refinedstorage.item.ItemBlockStorage; import com.raoulvdberge.refinedstorage.item.ItemProcessor; import net.minecraft.item.ItemStack; +import net.minecraft.util.NonNullList; import javax.annotation.Nonnull; -import javax.annotation.Nullable; public class SoldererRecipeStorage implements ISoldererRecipe { private EnumItemStorageType type; - private ItemStack[] rows; + private NonNullList rows = NonNullList.create(); public SoldererRecipeStorage(EnumItemStorageType type, int storagePart) { this.type = type; - this.rows = new ItemStack[]{ - new ItemStack(RSItems.PROCESSOR, 1, ItemProcessor.TYPE_BASIC), - new ItemStack(RSBlocks.MACHINE_CASING), - new ItemStack(RSItems.STORAGE_PART, 1, storagePart) - }; + + this.rows.add(new ItemStack(RSItems.PROCESSOR, 1, ItemProcessor.TYPE_BASIC)); + this.rows.add(new ItemStack(RSBlocks.MACHINE_CASING)); + this.rows.add(new ItemStack(RSItems.STORAGE_PART, 1, storagePart)); } @Override - @Nullable + @Nonnull public ItemStack getRow(int row) { - return rows[row]; + return rows.get(row); } @Override diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/solderer/SoldererRecipeUpgrade.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/solderer/SoldererRecipeUpgrade.java index 8d934ee28..8a47897d6 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/solderer/SoldererRecipeUpgrade.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/solderer/SoldererRecipeUpgrade.java @@ -5,36 +5,34 @@ import com.raoulvdberge.refinedstorage.api.solderer.ISoldererRecipe; import com.raoulvdberge.refinedstorage.item.ItemUpgrade; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; +import net.minecraft.util.NonNullList; import javax.annotation.Nonnull; -import javax.annotation.Nullable; public class SoldererRecipeUpgrade implements ISoldererRecipe { - private ItemStack[] rows; private ItemStack result; + private NonNullList rows = NonNullList.create(); public SoldererRecipeUpgrade(int type) { this.result = new ItemStack(RSItems.UPGRADE, 1, type); - this.rows = new ItemStack[]{ - ItemUpgrade.getRequirement(result), - new ItemStack(RSItems.UPGRADE, 1, 0), - new ItemStack(Items.REDSTONE) - }; + + this.rows.add(ItemUpgrade.getRequirement(result)); + this.rows.add(new ItemStack(RSItems.UPGRADE, 1, 0)); + this.rows.add(new ItemStack(Items.REDSTONE)); } public SoldererRecipeUpgrade(ItemStack result) { this.result = result; - this.rows = new ItemStack[]{ - ItemUpgrade.getRequirement(result), - new ItemStack(RSItems.UPGRADE, 1, 0), - new ItemStack(Items.REDSTONE) - }; + + this.rows.add(ItemUpgrade.getRequirement(result)); + this.rows.add(new ItemStack(RSItems.UPGRADE, 1, 0)); + this.rows.add(new ItemStack(Items.REDSTONE)); } @Override - @Nullable + @Nonnull public ItemStack getRow(int row) { - return rows[row]; + return rows.get(row); } @Override diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/solderer/SoldererRegistry.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/solderer/SoldererRegistry.java index 97ceb70eb..129879aa7 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/solderer/SoldererRegistry.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/solderer/SoldererRegistry.java @@ -34,10 +34,8 @@ public class SoldererRegistry implements ISoldererRegistry { ItemStack row = recipe.getRow(i); - if (rows.getStackInSlot(i) != null && row != null) { - if (rows.getStackInSlot(i).getCount() < row.getCount()) { - found = false; - } + if (rows.getStackInSlot(i).getCount() < row.getCount()) { + found = false; } } @@ -61,8 +59,14 @@ public class SoldererRegistry implements ISoldererRegistry { throw new IllegalArgumentException("Solderer recipe expects 3 rows, got " + rows.length + " rows"); } + for (ItemStack row : rows) { + if (row == null) { + throw new IllegalArgumentException("Found a null item stack in recipe creation!"); + } + } + return new ISoldererRecipe() { - @Nullable + @Nonnull @Override public ItemStack getRow(int row) { return rows[row]; @@ -102,7 +106,7 @@ public class SoldererRegistry implements ISoldererRegistry { private boolean compareRows(ISoldererRecipe recipe, ItemStack[] rows) { for (int i = 0; i < 3; ++i) { - if(!API.instance().getComparer().isEqualNoQuantity(recipe.getRow(i), rows[i])) { + if (!API.instance().getComparer().isEqualNoQuantity(recipe.getRow(i), rows[i])) { return false; } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/storage/item/ItemStorageNBT.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/storage/item/ItemStorageNBT.java index 29f01edcc..de3b37a5a 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/storage/item/ItemStorageNBT.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/storage/item/ItemStorageNBT.java @@ -9,6 +9,7 @@ import net.minecraft.nbt.NBTTagList; import net.minecraft.tileentity.TileEntity; import net.minecraftforge.items.ItemHandlerHelper; +import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.ArrayList; import java.util.List; @@ -68,19 +69,12 @@ public abstract class ItemStorageNBT implements IItemStorage { stack.setTagCompound(tag.hasKey(NBT_ITEM_NBT) ? tag.getCompoundTag(NBT_ITEM_NBT) : null); - if (stack.getItem() != null) { + if (!stack.isEmpty()) { stacks.add(stack); } } } - // ItemHandlerHelper#copyStackWithSize is not null-safe! - private ItemStack safeCopy(ItemStack stack, int size) { - ItemStack newStack = stack.copy(); - newStack.setCount(size); - return newStack; - } - /** * Writes the items to the NBT tag. */ @@ -122,7 +116,7 @@ public abstract class ItemStorageNBT implements IItemStorage { } @Override - public synchronized ItemStack insertItem(ItemStack stack, int size, boolean simulate) { + public synchronized ItemStack insertItem(@Nonnull ItemStack stack, int size, boolean simulate) { for (ItemStack otherStack : stacks) { if (API.instance().getComparer().isEqualNoQuantity(otherStack, stack)) { if (getCapacity() != -1 && getStored() + size > getCapacity()) { @@ -165,7 +159,7 @@ public abstract class ItemStorageNBT implements IItemStorage { if (!simulate) { tag.setInteger(NBT_STORED, getStored() + remainingSpace); - stacks.add(safeCopy(stack, remainingSpace)); + stacks.add(ItemHandlerHelper.copyStackWithSize(stack, remainingSpace)); onStorageChanged(); } @@ -175,7 +169,7 @@ public abstract class ItemStorageNBT implements IItemStorage { if (!simulate) { tag.setInteger(NBT_STORED, getStored() + size); - stacks.add(safeCopy(stack, size)); + stacks.add(ItemHandlerHelper.copyStackWithSize(stack, size)); onStorageChanged(); } @@ -185,7 +179,7 @@ public abstract class ItemStorageNBT implements IItemStorage { } @Override - public synchronized ItemStack extractItem(ItemStack stack, int size, int flags, boolean simulate) { + public synchronized ItemStack extractItem(@Nonnull ItemStack stack, int size, int flags, boolean simulate) { for (ItemStack otherStack : stacks) { if (API.instance().getComparer().isEqual(otherStack, stack, flags)) { if (size > otherStack.getCount()) { @@ -196,7 +190,7 @@ public abstract class ItemStorageNBT implements IItemStorage { if (otherStack.getCount() - size == 0) { stacks.remove(otherStack); } else { - otherStack.grow(size); + otherStack.shrink(size); } tag.setInteger(NBT_STORED, getStored() - size); diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/util/Comparer.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/util/Comparer.java index 21e17dbea..4dc2562f5 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/util/Comparer.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/util/Comparer.java @@ -3,22 +3,24 @@ package com.raoulvdberge.refinedstorage.apiimpl.util; import com.raoulvdberge.refinedstorage.api.util.IComparer; import com.raoulvdberge.refinedstorage.apiimpl.API; import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumActionResult; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.oredict.OreDictionary; import org.apache.commons.lang3.ArrayUtils; +import javax.annotation.Nullable; import java.util.HashMap; import java.util.Map; public class Comparer implements IComparer { - @Override - public boolean isEqual(ItemStack left, ItemStack right, int flags) { - if (left == null && right == null) { - return true; - } + private Map oredictCache = new HashMap<>(); - if ((left == null && right != null) || (left != null && right == null)) { - return false; + @Override + public boolean isEqual(@Nullable ItemStack left, @Nullable ItemStack right, int flags) { + EnumActionResult validity = validityCheck(left, right); + + if (validity == EnumActionResult.FAIL || validity == EnumActionResult.SUCCESS) { + return validity == EnumActionResult.SUCCESS; } if ((flags & COMPARE_OREDICT) == COMPARE_OREDICT) { @@ -53,7 +55,7 @@ public class Comparer implements IComparer { } @Override - public boolean isEqual(FluidStack left, FluidStack right, int flags) { + public boolean isEqual(@Nullable FluidStack left, @Nullable FluidStack right, int flags) { if (left == null && right == null) { return true; } @@ -82,7 +84,13 @@ public class Comparer implements IComparer { } @Override - public boolean isEqualNBT(ItemStack left, ItemStack right) { + public boolean isEqualNBT(@Nullable ItemStack left, @Nullable ItemStack right) { + EnumActionResult validity = validityCheck(left, right); + + if (validity == EnumActionResult.FAIL || validity == EnumActionResult.SUCCESS) { + return validity == EnumActionResult.SUCCESS; + } + if (!ItemStack.areItemStackTagsEqual(left, right)) { if (left.hasTagCompound() && !right.hasTagCompound() && left.getTagCompound().hasNoTags()) { return true; @@ -96,16 +104,12 @@ public class Comparer implements IComparer { return true; } - private Map oredictCache = new HashMap<>(); - @Override - public boolean isEqualOredict(ItemStack left, ItemStack right) { - if (left == null && right == null) { - return true; - } + public boolean isEqualOredict(@Nullable ItemStack left, @Nullable ItemStack right) { + EnumActionResult validity = validityCheck(left, right); - if ((left == null && right != null) || (left != null && right == null)) { - return false; + if (validity == EnumActionResult.FAIL || validity == EnumActionResult.SUCCESS) { + return validity == EnumActionResult.SUCCESS; } int code = API.instance().getItemStackHashCode(left); @@ -130,4 +134,24 @@ public class Comparer implements IComparer { return false; } + + private EnumActionResult validityCheck(@Nullable ItemStack left, @Nullable ItemStack right) { + if (left == null && right == null) { + return EnumActionResult.SUCCESS; + } + + if ((left == null && right != null) || (left != null && right == null)) { + return EnumActionResult.FAIL; + } + + if (left.isEmpty() && right.isEmpty()) { + return EnumActionResult.SUCCESS; + } + + if ((left.isEmpty() && !right.isEmpty()) || (!left.isEmpty() && right.isEmpty())) { + return EnumActionResult.FAIL; + } + + return EnumActionResult.PASS; + } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/TileGrid.java b/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/TileGrid.java index 7d4cea73b..3a97d0037 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/TileGrid.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/TileGrid.java @@ -291,7 +291,7 @@ public class TileGrid extends TileNode implements IGrid { } } else if (!slot.isEmpty()) { if (slot.getCount() == 1 && isConnected()) { - matrix.setInventorySlotContents(i, network.extractItem(slot, 1, false)); + matrix.setInventorySlotContents(i, RSUtils.getStack(network.extractItem(slot, 1, false))); } else { matrix.decrStackSize(i, 1); } @@ -352,7 +352,7 @@ public class TileGrid extends TileNode implements IGrid { } public boolean canCreatePattern() { - return !result.getStackInSlot(0).isEmpty() && patterns.getStackInSlot(1).isEmpty() && patterns.getStackInSlot(0) != null; + return !result.getStackInSlot(0).isEmpty() && patterns.getStackInSlot(1).isEmpty() && !patterns.getStackInSlot(0).isEmpty(); } public void onRecipeTransfer(EntityPlayer player, ItemStack[][] recipe) {