Jump to content

[1.8.9] Custom Crafting Table Not Removing Items


nxwhitney

Recommended Posts

Hello all!  I have working on a customer 4x4 crafting table that I am working on updating to 1.8 from 1.7.  Everything seems to be order with the exception that when I craft an items it does not remove the source items once the item is crafted.  I have included my container and crafting manager class below.  Any direction on where I should proceed would be greatly appreciated.

 

Container:

package com.tiredguy.mod.container;

import com.tiredguy.mod.blocks.TGBlocks;
import com.tiredguy.mod.crafting.DraftingBoardCraftingManager;
import com.tiredguy.mod.slot.TGSlotDraftingBoard;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.InventoryCraftResult;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.inventory.Slot;
import net.minecraft.inventory.SlotCrafting;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.CraftingManager;
import net.minecraft.util.BlockPos;
import net.minecraft.world.World;

public class ContainerDraftingBoard extends Container
{
    /** The crafting matrix inventory (3x3). */
    public InventoryCrafting craftMatrix = new InventoryCrafting(this, 4, 4);
    public IInventory craftResult = new InventoryCraftResult();
    private World worldObj;
    /** Position of the workbench */
    private BlockPos pos;

    public ContainerDraftingBoard(InventoryPlayer invPlayer, World worldIn, BlockPos pos) {
    	
        this.worldObj = worldIn;
        
        this.addSlotToContainer(new SlotCrafting(invPlayer.player, this.craftMatrix, this.craftResult, 0, 141, 43));


	for (int i = 0; i < 4; i++) {
		for(int k = 0; k < 4; k++) {
			this.addSlotToContainer(new Slot(craftMatrix, k + i * 4, 8 + k * 18, 7 + i * 18));
		}
	}

	for (int i = 0; i < 3; i++) {
		for(int k = 0; k < 9; k++) {
			this.addSlotToContainer(new Slot(invPlayer, k + i * 9 + 9, 8 + k * 18, 106 + i * 18));
		}
	}

	for (int i = 0; i < 9; i++) {
		this.addSlotToContainer(new Slot(invPlayer, i, 8 + i * 18, 164));
	}

	onCraftMatrixChanged(craftMatrix);
    }
    
    public ContainerDraftingBoard(InventoryPlayer invPlayer, World worldIn, int x, int y, int z) {
	this.worldObj = worldIn;

	this.addSlotToContainer(new SlotCrafting(invPlayer.player, this.craftMatrix, this.craftResult, 0, 141, 43));

	for (int i = 0; i < 4; i++) {
		for(int k = 0; k < 4; k++) {
			this.addSlotToContainer(new Slot(craftMatrix, k + i * 4, 8 + k * 18, 7 + i * 18));
		}
	}

	for (int i = 0; i < 3; i++) {
		for(int k = 0; k < 9; k++) {
			this.addSlotToContainer(new Slot(invPlayer, k + i * 9 + 9, 8 + k * 18, 106 + i * 18));
		}
	}

	for (int i = 0; i < 9; i++) {
		this.addSlotToContainer(new Slot(invPlayer, i, 8 + i * 18, 164));
	}

	onCraftMatrixChanged(craftMatrix);
}

public void onCraftMatrixChanged(IInventory inventoryIn)
    {
        this.craftResult.setInventorySlotContents(0, DraftingBoardCraftingManager.getInstance().findMatchingRecipe(this.craftMatrix, this.worldObj));
    }


public void onContainerClosed(EntityPlayer playerIn) {
        super.onContainerClosed(playerIn);

        if (!this.worldObj.isRemote)
        {
            for (int i = 0; i < 9; ++i)
            {
                ItemStack itemstack = this.craftMatrix.removeStackFromSlot(i);

                if (itemstack != null)
                {
                    playerIn.dropPlayerItemWithRandomChoice(itemstack, false);
                }
            }
        }
    }

    @Override
    public boolean canInteractWith(EntityPlayer playerIn)
    {
    	return this.craftResult.isUseableByPlayer(playerIn);
    	//return this.worldObj.getBlockState(this.pos).getBlock() != NGBlocks.draftingTable ? false : playerIn.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 playerIn, int index)
    {
        ItemStack itemstack = null;
        Slot slot = (Slot)this.inventorySlots.get(index);

        if (slot != null && slot.getHasStack())
        {
            ItemStack itemstack1 = slot.getStack();
            itemstack = itemstack1.copy();

            if (index == 0)
            {
                if (!this.mergeItemStack(itemstack1, 10, 46, true))
                {
                    return null;
                }

                slot.onSlotChange(itemstack1, itemstack);
            }
            else if (index >= 10 && index < 37)
            {
                if (!this.mergeItemStack(itemstack1, 37, 46, false))
                {
                    return null;
                }
            }
            else if (index >= 37 && index < 46)
            {
                if (!this.mergeItemStack(itemstack1, 10, 37, false))
                {
                    return null;
                }
            }
            else if (!this.mergeItemStack(itemstack1, 10, 46, false))
            {
                return null;
            }

            if (itemstack1.stackSize == 0)
            {
                slot.putStack((ItemStack)null);
            }
            else
            {
                slot.onSlotChanged();
            }

            if (itemstack1.stackSize == itemstack.stackSize)
            {
                return null;
            }

            slot.onPickupFromSlot(playerIn, itemstack1);
        }

        return itemstack;
    }

    /**
     * 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 p_94530_2_)
    {
        return p_94530_2_.inventory != this.craftResult && super.canMergeSlot(stack, p_94530_2_);
    }
}

 

CraftingManager:

package com.tiredguy.mod.crafting;

import java.util.Collections;
import java.util.List;
import java.util.Map;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.tiredguy.mod.items.TGItems;

import net.minecraft.block.Block;
import net.minecraft.init.Items;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.CraftingManager;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.item.crafting.ShapedRecipes;
import net.minecraft.item.crafting.ShapelessRecipes;
import net.minecraft.world.World;

public class DraftingBoardCraftingManager 
{
    /** The static instance of this class */
    private static final DraftingBoardCraftingManager instance = new DraftingBoardCraftingManager();
    private final List<IRecipe> recipes = Lists.<IRecipe>newArrayList();

    /**
     * Returns the static instance of this class
     */
    public static DraftingBoardCraftingManager getInstance()
    {
        /** The static instance of this class */
        return instance;
    }

    public DraftingBoardCraftingManager()
    {
        
    	this.addRecipe(new ItemStack(TGItems.ironHammer, 1), new Object[] {
    			"IIII", 
    			"IZZI", 
    			" ZZ ", 
    			" ZZ ", 
    			'I', Items.iron_ingot,
    			'Z', TGItems.zincIngot});
    	
        Collections.sort(this.recipes, new DraftingBoardRecipeSorter(this));
    }

    /**
     * Adds a shaped recipe to the games recipe list.
     */
    public DraftingBoardShapedRecipes addRecipe(ItemStack stack, Object... recipeComponents)
    {
        String s = "";
        int i = 0;
        int j = 0;
        int k = 0;

        if (recipeComponents[i] instanceof String[])
        {
            String[] astring = (String[])((String[])recipeComponents[i++]);

            for (int l = 0; l < astring.length; ++l)
            {
                String s2 = astring[l];
                ++k;
                j = s2.length();
                s = s + s2;
            }
        }
        else
        {
            while (recipeComponents[i] instanceof String)
            {
                String s1 = (String)recipeComponents[i++];
                ++k;
                j = s1.length();
                s = s + s1;
            }
        }

        Map<Character, ItemStack> map;

        for (map = Maps.<Character, ItemStack>newHashMap(); i < recipeComponents.length; i += 2)
        {
            Character character = (Character)recipeComponents[i];
            ItemStack itemstack = null;

            if (recipeComponents[i + 1] instanceof Item)
            {
                itemstack = new ItemStack((Item)recipeComponents[i + 1]);
            }
            else if (recipeComponents[i + 1] instanceof Block)
            {
                itemstack = new ItemStack((Block)recipeComponents[i + 1], 1, 32767);
            }
            else if (recipeComponents[i + 1] instanceof ItemStack)
            {
                itemstack = (ItemStack)recipeComponents[i + 1];
            }

            map.put(character, itemstack);
        }

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

        for (int i1 = 0; i1 < j * k; ++i1)
        {
            char c0 = s.charAt(i1);

            if (map.containsKey(Character.valueOf(c0)))
            {
                aitemstack[i1] = ((ItemStack)map.get(Character.valueOf(c0))).copy();
            }
            else
            {
                aitemstack[i1] = null;
            }
        }

        DraftingBoardShapedRecipes shapedrecipes = new DraftingBoardShapedRecipes(j, k, aitemstack, stack);
        this.recipes.add(shapedrecipes);
        return shapedrecipes;
    }

    /**
     * Adds a shapeless crafting recipe to the the game.
     */
    public void addShapelessRecipe(ItemStack stack, Object... recipeComponents)
    {
        List<ItemStack> list = Lists.<ItemStack>newArrayList();

        for (Object object : recipeComponents)
        {
            if (object instanceof ItemStack)
            {
                list.add(((ItemStack)object).copy());
            }
            else if (object instanceof Item)
            {
                list.add(new ItemStack((Item)object));
            }
            else
            {
                if (!(object instanceof Block))
                {
                    throw new IllegalArgumentException("Invalid shapeless recipe: unknown type " + object.getClass().getName() + "!");
                }

                list.add(new ItemStack((Block)object));
            }
        }

        this.recipes.add(new ShapelessRecipes(stack, list));
    }

    /**
     * Adds an IRecipe to the list of crafting recipes.
     */
    public void addRecipe(IRecipe recipe)
    {
        this.recipes.add(recipe);
    }

    /**
     * Retrieves an ItemStack that has multiple recipes for it.
     */
    public ItemStack findMatchingRecipe(InventoryCrafting p_82787_1_, World worldIn)
    {
        for (IRecipe irecipe : this.recipes)
        {
            if (irecipe.matches(p_82787_1_, worldIn))
            {
                return irecipe.getCraftingResult(p_82787_1_);
            }
        }

        return null;
    }

    public ItemStack[] func_180303_b(InventoryCrafting p_180303_1_, World worldIn)
    {
        for (IRecipe irecipe : this.recipes)
        {
            if (irecipe.matches(p_180303_1_, worldIn))
            {
                return irecipe.getRemainingItems(p_180303_1_);
            }
        }

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

        for (int i = 0; i < aitemstack.length; ++i)
        {
            aitemstack[i] = p_180303_1_.getStackInSlot(i);
        }

        return aitemstack;
    }

    public List<IRecipe> getRecipeList()
    {
        return this.recipes;
    }
}

Link to comment
Share on other sites

I updated the Crafting Manager and I am getting a different behavior now.

 

Error Log:

Description: Updating screen events

java.lang.NullPointerException: Updating screen events
at com.nealegaming.mod.slot.NGSlotDraftingBoard.onPickupFromSlot(NGSlotDraftingBoard.java:88)
at net.minecraft.inventory.Container.slotClick(Container.java:334)
at net.minecraft.client.multiplayer.PlayerControllerMP.windowClick(PlayerControllerMP.java:535)
at net.minecraft.client.gui.inventory.GuiContainer.handleMouseClick(GuiContainer.java:679)
at net.minecraft.client.gui.inventory.GuiContainer.mouseClicked(GuiContainer.java:421)
at net.minecraft.client.gui.GuiScreen.handleMouseInput(GuiScreen.java:620)
at net.minecraft.client.gui.GuiScreen.handleInput(GuiScreen.java:586)
at net.minecraft.client.Minecraft.runTick(Minecraft.java:1761)
at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1080)
at net.minecraft.client.Minecraft.run(Minecraft.java:380)
at net.minecraft.client.main.Main.main(Main.java:116)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at net.minecraft.launchwrapper.Launch.launch(Launch.java:135)
at net.minecraft.launchwrapper.Launch.main(Launch.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97)
at GradleStart.main(GradleStart.java:26)

 

NGSlotDraftingBoard:

 

package com.tiredguy.mod.slot;

import com.tiredguy.mod.crafting.DraftingBoardCraftingManager;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.inventory.Slot;
import net.minecraft.item.Item;
import net.minecraft.item.ItemHoe;
import net.minecraft.item.ItemPickaxe;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemSword;
import net.minecraft.stats.AchievementList;

public class NGSlotDraftingBoard extends Slot
{
    /** The craft matrix inventory linked to this result slot. */
    private final InventoryCrafting craftMatrix;
    /** The player that is using the GUI where this slot resides. */
    private final EntityPlayer thePlayer;
    /** The number of items that have been crafted so far. Gets passed to ItemStack.onCrafting before being reset. */
    private int amountCrafted;

    public NGSlotDraftingBoard(EntityPlayer player, InventoryCrafting craftingInventory, IInventory p_i45790_3_, int slotIndex, int xPosition, int yPosition)
    {
        super(p_i45790_3_, slotIndex, xPosition, yPosition);
        this.thePlayer = player;
        this.craftMatrix = craftingInventory;
    }

    /**
     * Check if the stack is a valid item for this slot. Always true beside for the armor slots.
     */
    public boolean isItemValid(ItemStack stack)
    {
        return false;
    }

    /**
     * Decrease the size of the stack in slot (first int arg) by the amount of the second int arg. Returns the new
     * stack.
     */
    public ItemStack decrStackSize(int amount)
    {
        if (this.getHasStack())
        {
            this.amountCrafted += Math.min(amount, this.getStack().stackSize);
        }

        return super.decrStackSize(amount);
    }

    /**
     * the itemStack passed in is the output - ie, iron ingots, and pickaxes, not ore and wood. Typically increases an
     * internal count then calls onCrafting(item).
     */
    public void onCrafting(ItemStack stack, int amount)
    {
        this.amountCrafted += amount;
        this.onCrafting(stack);
    }

    /**
     * the itemStack passed in is the output - ie, iron ingots, and pickaxes, not ore and wood.
     */
    public void onCrafting(ItemStack stack)
    {
        if (this.amountCrafted > 0)
        {
            stack.onCrafting(this.thePlayer.worldObj, this.thePlayer, this.amountCrafted);
        }

        this.amountCrafted = 0;
    }

    public void onPickupFromSlot(EntityPlayer playerIn, ItemStack stack)
    {
        net.minecraftforge.fml.common.FMLCommonHandler.instance().firePlayerCraftingEvent(playerIn, stack, craftMatrix);
        this.onCrafting(stack);
        net.minecraftforge.common.ForgeHooks.setCraftingPlayer(playerIn);
        ItemStack[] aitemstack = DraftingBoardCraftingManager.getInstance().func_180303_b(craftMatrix, playerIn.worldObj);
        net.minecraftforge.common.ForgeHooks.setCraftingPlayer(null);

        for (int i = 0; i < aitemstack.length; ++i)
        {
            ItemStack itemstack = this.craftMatrix.getStackInSlot(i);
            ItemStack itemstack1 = aitemstack[i];

            if (itemstack != null)
            {
                this.craftMatrix.decrStackSize(i, 1);
            }

            if (itemstack1 != null)
            {
                if (this.craftMatrix.getStackInSlot(i) == null)
                {
                    this.craftMatrix.setInventorySlotContents(i, itemstack1);
                }
                else if (!this.thePlayer.inventory.addItemStackToInventory(itemstack1))
                {
                    this.thePlayer.dropPlayerItemWithRandomChoice(itemstack1, false);
                }
            }
        }
    }
}

 

I can't seem to figure out what is null.

Link to comment
Share on other sites

Your

DraftingBoardCraftingManager#func_180303_b

returns

null

, which returns in a

NullPointerException[code] when trying to call [code][code]aitemstack.length

.

 

BTW, you could've figured this out yourself by looking at the things which can be null on line 88.

Don't PM me with questions. They will be ignored! Make a thread on the appropriate board for support.

 

1.12 -> 1.13 primer by williewillus.

 

1.7.10 and older versions of Minecraft are no longer supported due to it's age! Update to the latest version for support.

 

http://www.howoldisminecraft1710.today/

Link to comment
Share on other sites

I ran a breakpoint and I can see where the aitemstack is coming up empty, but I can't figure out why.  Is there something wrong in my crafting manager that isn't adding the recipe?  I backtracked func_180303_b and the best I can guess is that it's empty.

 

 

 

 

Link to comment
Share on other sites

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



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • I had an amazing experience with The Hack Angels. I had given up hope, but they managed to recover my bitcoins from an online scammer. I was able to retrieve what I had thought was lost forever because of their knowledge and commitment. I heartily endorse the services of The Hack Angels to anyone in need of help recovering cryptocurrency. They really are authorities in their domain.  (Web: https://thehackangels.com)     Whats Ap; +1 520) - 200, 23  20 ) ,  Mail Box; support@thehackangels. com
    • I got my model to render from the models renderToBuffer method. But still not quite what I want. I want to render the model from my renderer's render method. I feel that having access to the renderer and it's methods will open some doors for me later down the line. //EntityRendererProvider.Context pContext = ; I want this //ToaPlayerRenderer render = new ToaPlayerRenderer(pContext, false); // if I can get the above line to work, having the methods from the renderer class would be incredibly helpful down the line RenderType rendertype = model.renderType(p.getSkinTextureLocation()); // this should be something like render.getTextureLocation() VertexConsumer vertexconsumer = buffer.getBuffer(rendertype); model.renderToBuffer(stack, vertexconsumer, paLights, 1, 1, 1, 1, 1); // I don't want the render to happen here since it doesn't use the renderer //model.render(p, 1f, pTicks, stack, buffer, paLights); I want to render the model using this It is certainly getting closer though. Probably. I am still worried that even if pContext is initialized this new instance of the renderer class will still hit me with the classic and all too familiar "can't use static method in non-static context"
    • Hello, I am learning how to create Multipart Entities and I tried creating a PartEntity based on the EnderDragonPart code. However, when I tested summoning the entity in the game, the PartEntity appeared at position x 0, y 0, z 0 within the game. I tried to make it follow the main entity, and after testing again, the part entity followed the main entity but seemed to teleport back to x 0, y 0, z 0 every tick (I'm just guessing). I don't know how to fix this can someone help me? My github https://github.com/SteveKK666/Forge-NewWorld-1.20.1/tree/master/src/main/java/net/kk/newworldmod/entity/custom Illustration  https://drive.google.com/file/d/157SPvyQCE8GcsRXyQQkD4Dyhalz6LjBn/view?usp=drive_link Sorry for my English; I’m not very good at it. 
    • its still crashing with the same message
  • Topics

  • Who's Online (See full list)

    • There are no registered users currently online
×
×
  • Create New...

Important Information

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