Jump to content

[1.8][SOLVED] Custom Crafting Table doesn't remove Items after crafting


Recommended Posts

Posted

So the title should say most of it but basically I am updating my mod from 1.7.10 to 1.8 and I have ran into a problem that I didn't have in 1.7.10. When I craft an Item in the table, it doesn't remove the Items from the craftMatrix allowing infinite items to be made.

 

Here is the container code:

 

 

/** The crafting matrix inventory (5x5). */

public InventoryCrafting craftMatrix = new InventoryCrafting(this, 5, 5);

public IInventory craftResult = new InventoryCraftResult();

private World worldObj;

private BlockPos pos;

 

public ContainerCraftingTable(InventoryPlayer playerInventory, World world, BlockPos pos)

{

this.worldObj = world;

this.pos = pos;

this.addSlotToContainer(new SlotCrafting(playerInventory.player, this.craftMatrix, this.craftResult, 0, 141, 35));

 

for (int i = 0; i < 5; ++i)

{

for (int k = 0; k < 5; ++k)

{

this.addSlotToContainer(new Slot(this.craftMatrix, k + i * 5, 8 + k * 18, 7 + i * 18));

}

}

 

for (int i = 0; i < 3; ++i)

{

for (int k = 0; k < 9; ++k)

{

this.addSlotToContainer(new Slot(playerInventory, k + i * 9 + 9, 8 + k * 18, 106 + i * 18));

}

}

 

for (int i = 0; i < 9; ++i)

{

this.addSlotToContainer(new Slot(playerInventory, i, 8 + i * 18, 164));

}

 

this.onCraftMatrixChanged(this.craftMatrix);

}

 

/**

* Callback for when the crafting matrix is changed.

*/

public void onCraftMatrixChanged(IInventory iiventory)

{

this.craftResult.setInventorySlotContents(0, CraftingTableManager.getInstance().findMatchingRecipe(this.craftMatrix, this.worldObj));

}

 

/**

* Called when the container is closed.

*/

public void onContainerClosed(EntityPlayer player)

{

super.onContainerClosed(player);

 

if (!this.worldObj.isRemote)

{

for (int i = 0; i < 25; ++i)

{

ItemStack itemstack = this.craftMatrix.getStackInSlotOnClosing(i);

 

if (itemstack != null)

{

player.dropPlayerItemWithRandomChoice(itemstack, false);

}

}

}

}

 

public boolean canInteractWith(EntityPlayer player)

{

return this.worldObj.getBlockState(this.pos).getBlock() != Blocks_and_Items.crafting_table ? false : player.getDistanceSq((double) this.pos.getX() + 0.5D,

(double) this.pos.getY() + 0.5D, (double) this.pos.getZ() + 0.5D) <= 64.0D;

}

 

/**

* Take a stack from the specified inventory slot.

*/

public ItemStack transferStackInSlot(EntityPlayer player, int slots)

{

ItemStack stack = null;

Slot slot = (Slot) this.inventorySlots.get(slots);

 

if (slot != null && slot.getHasStack())

{

ItemStack stack1 = slot.getStack();

stack = stack1.copy();

 

if (slots == 0)

{

if (!this.mergeItemStack(stack1, 26, 62, true))

{

return null;

}

 

slot.onSlotChange(stack1, stack);

}

else if (slots >= 26 && slots < 53)

{

if (!this.mergeItemStack(stack1, 53, 62, false))

{

return null;

}

}

else if (slots >= 53 && slots < 62)

{

if (!this.mergeItemStack(stack1, 26, 53, false))

{

return null;

}

}

else if (!this.mergeItemStack(stack1, 26, 62, false))

{

return null;

}

 

if (stack1.stackSize == 0)

{

slot.putStack((ItemStack) null);

}

else

{

slot.onSlotChanged();

}

 

if (stack1.stackSize == stack.stackSize)

{

return null;

}

 

slot.onPickupFromSlot(player, stack1);

}

 

return stack;

}

 

/**

* Called to determine if the current slot is valid for the stack merging (double-click) code. The stack passed in

* is null for the initial slot that was double-clicked.

*/

public boolean canMergeSlot(ItemStack stack, Slot slot)

{

return slot.inventory != this.craftResult && super.canMergeSlot(stack, slot);

}

 

 

 

Block code:

 

 

public class BlockCraftingTable extends Block

{

public BlockCraftingTable()

{

super(Material.iron);

this.setHardness(1.0F);

this.setResistance(5.0F);

this.setStepSound(soundTypeMetal);

}

 

public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumFacing side, float hitX, float hitY, float hitZ)

{

if (world.isRemote && !player.isSneaking())

{

return true;

}

else

{

FMLNetworkHandler.openGui(player, Strings.MOD_ID, GuiIDs.guiIDCraftingTable, world, pos.getX(), pos.getY(), pos.getZ());

return true;

}

}

}

 

 

 

Crafting Manager:

 

 

public class CraftingTableManager

{

/** The static instance of this class. */

private static final CraftingTableManager instance = new CraftingTableManager();

/** A list of all the recipes added. */

private final List recipes = Lists.newArrayList();

 

/**

* Returns the static instance of this class

*/

public static CraftingTableManagergetInstance()

{

/** The static instance of this class */

return instance;

}

 

private CraftingTableManager()

{

Collections.sort(this.recipes, new Comparator()

{

public int compare(IRecipe irecipe1, IRecipe irecipe2)

{

return irecipe1 instanceof CraftingTableShapelessRecipes && irecipe2 instanceof CraftingTableShapedRecipes ? 1 : (irecipe2 instanceof

                                CraftingTableShapelessRecipes && irecipe1 instanceof CraftingTableShapedRecipes ? -1 : (irecipe2.getRecipeSize() < irecipe1.getRecipeSize() ? -1 :

                                (irecipe2.getRecipeSize() > irecipe1.getRecipeSize() ? 1 : 0)));

}

public int compare(Object object1, Object object2)

{

return this.compare((IRecipe) object1, (IRecipe) object2);

}

});

}

 

/**

* Adds a shaped recipe to the games recipe list.

*/

public CraftingTableShapedRecipes addRecipe(ItemStack stack, Object... recipeComponents)

{

String s = "";

int i = 0;

int j = 0;

int k = 0;

 

if (recipeComponents instanceof String[])

{

String[] astring = (String[]) ((String[]) recipeComponents[i++]);

 

for (int l = 0; l < astring.length; ++l)

{

String s1 = astring[l];

++k;

j = s1.length();

s = s + s1;

}

}

else

{

while (recipeComponents instanceof String)

{

String s2 = (String) recipeComponents[i++];

++k;

j = s2.length();

s = s + s2;

}

}

 

HashMap hashmap;

 

for (hashmap = Maps.newHashMap(); i < recipeComponents.length; i += 2)

{

Character character = (Character) recipeComponents;

ItemStack stack1 = null;

 

if (recipeComponents[i + 1] instanceof Item)

{

stack1 = new ItemStack((Item) recipeComponents[i + 1]);

}

else if (recipeComponents[i + 1] instanceof Block)

{

stack1 = new ItemStack((Block) recipeComponents[i + 1], 1, 32767);

}

else if (recipeComponents[i + 1] instanceof ItemStack)

{

stack1 = (ItemStack) recipeComponents[i + 1];

}

 

hashmap.put(character, stack1);

}

 

ItemStack[] aitemstack = new ItemStack[j * k];

 

for (int i1 = 0; i1 < j * k; ++i1)

{

char c0 = s.charAt(i1);

 

if (hashmap.containsKey(Character.valueOf(c0)))

{

aitemstack[i1] = ((ItemStack) hashmap.get(Character.valueOf(c0))).copy();

}

else

{

aitemstack[i1] = null;

}

}

 

CraftingTableShapedRecipes shapedrecipes = new CraftingTableShapedRecipes(j, k, aitemstack, stack);

this.recipes.add(shapedrecipes);

return shapedrecipes;

}

 

/**

* Adds a shapeless crafting recipe to the game.

*

* @param recipeComponents An array of ItemStack's Item's and Block's that make up the recipe.

*/

public void addShapelessRecipe(ItemStack stack, Object... recipeComponents)

{

ArrayList arraylist = Lists.newArrayList();

Object[] aobject = recipeComponents;

int i = recipeComponents.length;

 

for (int j = 0; j < i; ++j)

{

Object object1 = aobject[j];

 

if (object1 instanceof ItemStack)

{

arraylist.add(((ItemStack) object1).copy());

}

else if (object1 instanceof Item)

{

arraylist.add(new ItemStack((Item) object1));

}

else

{

if (!(object1 instanceof Block))

{

throw new IllegalArgumentException("Invalid shapeless recipe: unknown type " + object1.getClass().getName() + "!");

}

 

arraylist.add(new ItemStack((Block) object1));

}

}

 

this.recipes.add(new CraftingTableShapelessRecipes(stack, arraylist));

}

 

/**

* Adds an IRecipe to the list of crafting recipes.

*

* @param recipe A recipe that will be added to the recipe list.

*/

public void addRecipe(IRecipe recipe)

{

this.recipes.add(recipe);

}

 

/**

* Retrieves an ItemStack that has multiple recipes for it.

*/

public ItemStack findMatchingRecipe(InventoryCrafting inventoryCrafting, World world)

{

Iterator iterator = this.recipes.iterator();

IRecipe irecipe;

 

do

{

if (!iterator.hasNext())

{

return null;

}

 

irecipe = (IRecipe) iterator.next();

}

while (!irecipe.matches(inventoryCrafting, world));

 

return irecipe.getCraftingResult(inventoryCrafting);

}

 

public ItemStack[] func_180303_b(InventoryCrafting inventoryCrafting, World world)

{

Iterator iterator = this.recipes.iterator();

 

while (iterator.hasNext())

{

IRecipe irecipe = (IRecipe) iterator.next();

 

if (irecipe.matches(inventoryCrafting, world))

{

return irecipe.getRemainingItems(inventoryCrafting);

}

}

 

ItemStack[] aitemstack = new ItemStack[inventoryCrafting.getSizeInventory()];

 

for (int i = 0; i < aitemstack.length; ++i)

{

aitemstack = inventoryCrafting.getStackInSlot(i);

}

 

return aitemstack;

}

 

/**

* Returns the List<> of all recipes

*/

public List getRecipeList()

{

return this.recipes;

}

}

 

 

 

Shaped Recipes:

 

 

public class CraftingTableShapedRecipes implements IRecipe

{

/** How many horizontal slots this recipe is wide. */

public final int recipeWidth;

/** How many vertical slots this recipe uses. */

public final int recipeHeight;

/** Is an array of ItemStack that composes the recipe. */

public final ItemStack[] recipeItems;

/** Is the ItemStack that you get when you craft the recipe. */

private final ItemStack recipeOutput;

private boolean field_92101_f;

 

public CraftingTableShapedRecipes(int width, int height, ItemStack[] items, ItemStack output)

{

this.recipeWidth = width;

this.recipeHeight = height;

this.recipeItems = items;

this.recipeOutput = output;

}

 

public ItemStack getRecipeOutput()

{

return this.recipeOutput;

}

 

public ItemStack[] getRemainingItems(InventoryCrafting inventoryCrafting)

{

ItemStack[] aitemstack = new ItemStack[inventoryCrafting.getSizeInventory()];

 

for (int i = 0; i < aitemstack.length; ++i)

{

ItemStack stack = inventoryCrafting.getStackInSlot(i);

aitemstack = ForgeHooks.getContainerItem(stack);

}

 

return aitemstack;

}

 

/**

* Use to check if a recipe matches current crafting inventory.

*/

public boolean matches(InventoryCrafting inventoryCrafting, World world)

{

for (int i = 0; i <= 5 - this.recipeWidth; ++i)

{

for (int j = 0; j <= 5 - this.recipeHeight; ++j)

{

if (this.checkMatch(inventoryCrafting, i, j, true))

{

return true;

}

 

if (this.checkMatch(inventoryCrafting, i, j, false))

{

return true;

}

}

}

 

return false;

}

 

/**

* Checks if the region of a crafting inventory is a match for the recipe.

*/

private boolean checkMatch(InventoryCrafting inventoryCrafting, int width, int height, boolean b)

{

for (int k = 0; k < 5; ++k)

{

for (int l = 0; l < 5; ++l)

{

int i1 = k - width;

int j1 = l - height;

ItemStack itemstack = null;

 

if (i1 >= 0 && j1 >= 0 && i1 < this.recipeWidth && j1 < this.recipeHeight)

{

if (b)

{

itemstack = this.recipeItems[this.recipeWidth - i1 - 1 + j1 * this.recipeWidth];

}

else

{

itemstack = this.recipeItems[i1 + j1 * this.recipeWidth];

}

}

 

ItemStack itemstack1 = inventoryCrafting.getStackInRowAndColumn(k, l);

 

if (itemstack1 != null || itemstack != null)

{

if (itemstack1 == null && itemstack != null || itemstack1 != null && itemstack == null)

{

return false;

}

 

if (itemstack.getItem() != itemstack1.getItem())

{

return false;

}

 

if (itemstack.getMetadata() != 32767 && itemstack.getMetadata() != itemstack1.getMetadata())

{

return false;

}

}

}

}

 

return true;

}

 

/**

* Returns an Item that is the result of this recipe.

*/

public ItemStack getCraftingResult(InventoryCrafting inventoryCrafting)

{

ItemStack stack = this.getRecipeOutput().copy();

 

if (this.field_92101_f)

{

for (int i = 0; i < inventoryCrafting.getSizeInventory(); ++i)

{

ItemStack stack1 = inventoryCrafting.getStackInSlot(i);

 

if (stack1 != null && stack1.hasTagCompound())

{

stack.setTagCompound((NBTTagCompound) stack1.getTagCompound().copy());

}

}

}

 

return stack;

}

 

/**

* Returns the size of the recipe area.

*/

public int getRecipeSize()

{

return this.recipeWidth * this.recipeHeight;

}

 

public CraftingTableShapedRecipes func_92100_c()

{

this.field_92101_f = true;

return this;

}

}

 

 

 

Shapeless Recipes

 

 

public class CraftingTableShapelessRecipes implements IRecipe

{

/** Is the ItemStack that you get when craft the recipe. */

private final ItemStack recipeOutput;

/** Is a List of ItemStack that composes the recipe. */

public final List recipeItems;

 

public CraftingTableShapelessRecipes(ItemStack output, List inputList)

{

this.recipeOutput = output;

this.recipeItems = inputList;

}

 

public ItemStack getRecipeOutput()

{

return this.recipeOutput;

}

 

public ItemStack[] getRemainingItems(InventoryCrafting inventoryCrafting)

{

ItemStack[] aitemstack = new ItemStack[inventoryCrafting.getSizeInventory()];

 

for (int i = 0; i < aitemstack.length; ++i)

{

ItemStack stack = inventoryCrafting.getStackInSlot(i);

aitemstack = ForgeHooks.getContainerItem(stack);

}

 

return aitemstack;

}

 

/**

* Used to check if a recipe matches current crafting inventory.

*/

public boolean matches(InventoryCrafting inventoryCrafting, World world)

{

ArrayList arraylist = Lists.newArrayList(this.recipeItems);

 

for (int i = 0; i < inventoryCrafting.getHeight(); ++i)

{

for (int j = 0; j < inventoryCrafting.getWidth(); ++j)

{

ItemStack stack = inventoryCrafting.getStackInRowAndColumn(j, i);

 

if (stack != null)

{

boolean flag = false;

Iterator iterator = arraylist.iterator();

 

while (iterator.hasNext())

{

ItemStack stack1 = (ItemStack) iterator.next();

 

if (stack.getItem() == stack1.getItem() && (stack1.getMetadata() == 32767 || stack.getMetadata() == stack1.getMetadata()))

{

flag = true;

arraylist.remove(stack1);

break;

}

}

 

if (!flag)

{

return false;

}

}

}

}

 

return arraylist.isEmpty();

}

 

/**

* Returns an Item that is the result of this recipe

*/

public ItemStack getCraftingResult(InventoryCrafting inventoryCrafting)

{

return this.recipeOutput.copy();

}

 

/**

* Returns the size of the recipe area

*/

public int getRecipeSize()

{

return this.recipeItems.size();

}

}

 

 

Posted

Hi

 

The vanilla CraftingManager has a function to remove the items (in conjunction with SlotCrafting.onPickupFromSlot())

func_180303_b

 

Your crafting manager doesn't appear to have any code which does the same thing.  Are you using a SlotCrafting equivalent in your container? Perhaps responsibility for removing the items has moved during the upgrade from 1.7.10 to 1.8?

 

-TGG

Posted

Most of my code is from the Vanilla Crafting Table so I would assume most of it except for the parts I changed for my crafting table would be the same because I'm sure I use the func_180303_b, would I require to create my own SlotCrafting for it to work?

Posted

So I have figured it, in order to fix this you must create your own SlotCrafting and edit the onPickupFromSlot method. You can copy the entire method from vanilla but you have to change this one line of code:

 

ItemStack[] aitemstack = CraftingManager.getInstance().func_180303_b(this.craftMatrix, player.worldObj)

 

Change the CraftingManager.getInstance() to YourCraftingManager.getInstance()

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.