Jump to content

Recommended Posts

Posted

Okay, erm, What... the... ?! Either I'm a massive derp (as always), or something isn't right here!

So my container broke (for a 7x7 crafting station), and I have no idea how, since it WAS working relatively fine, apart from a serious bug that I was about to get down to fixing that was causing ItemStacks to go up into the tens of

thousands upon shift-clicking a crafting result.

 

Take a look at the attached image.

 

So apparently, when I try to open the GUI for my crafting station, and it does a little check to make sure the TileEntity at the given position is indeed the right one (to prevent bugs / TileEntity mix-ups which do apparently happen from time to time)...

it fails on checking that the TileEntity is of the type TileEntityStation, but then when it prints the error into the console, and I have it print the class type for the TileEntity that was found at that position, it says that it IS indeed a TileEntityStation.

I am made of questions right now.

 

Am I missing something glaringly obvious here, or is this actually a bug?

 

wtf.png

Posted

You're comparing a TileEntity to a Class, the two will never be equal. Use instanceof to check if a value is an instance of a class or other type.

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Posted

I fixed the problem... strangely enough the GUI wasn't opening because of a botched crafting recipe. I mean, there was nothing wrong with the formatting of the recipe, and all the items and blocks

needed were surely initialized and registered etc before the recipe was registered (because it registers them the first time you click the station (IDK why, but it works so I'll leave it for now))

 

Strange stuff. I wish this could all be written in one of the C languages, makes SO much more sense ;)

Regardless though, I now have to face the dreaded problem of shift-clicking the crafting result, only to get all the remaining items in the crafting matrix area cranking their stack size to over 9000... like, literally.

I don't want to have to disable shift-clicking recipes. I was using an old 1.7 tutorial for some of this, and altering Minecraft's "Workbench" code for the rest. But I don't know where to even start looking for this weird bug. I don't even think it gives me the right amount of items either. It's fine when you remove the resulting item manually without holding shift. It should give 5 per craft (these will be slightly more expensive recipes, eventually... so it seems only fair to give a few machines out of it :P)

 

I suspect it has something to do with the getRemainingItems() function in the crafting manager

 

Here's some of the codes:

 

Container

public class ContainerStation extends Container
{
	private World worldRef;
	private TileEntityStation tileEntityRef;
	public InventoryCrafting craftMatrix;
	public IInventory craftResult;
	private IItemHandler handler;
	
	public ContainerStation(EntityPlayer player, TileEntityStation te, World worldReference)
	{
		this.tileEntityRef = te;
		this.tileEntityRef.container = this;
		this.worldRef = worldReference;
		this.handler = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null);
		
		this.craftMatrix = new InventoryCrafting(this, 7, 7);
        this.craftResult = new InventoryCraftResult();
        
        // Output slot
     	this.addSlotToContainer(new SlotCrafting(player, this.craftMatrix, this.craftResult, 0, 152, 74));
		
		// Crafting Slots
		int xStart = 8;
		int yStart = 20;
		
			// Row 1
			this.addSlotToContainer(new Slot(this.craftMatrix, 0, xStart, yStart));
			this.addSlotToContainer(new Slot(this.craftMatrix, 1, xStart + 18, yStart));
			this.addSlotToContainer(new Slot(this.craftMatrix, 2, xStart + (18 * 2), yStart));
			this.addSlotToContainer(new Slot(this.craftMatrix, 3, xStart + (18 * 3), yStart));
			this.addSlotToContainer(new Slot(this.craftMatrix, 4, xStart + (18 * 4), yStart));
			this.addSlotToContainer(new Slot(this.craftMatrix, 5, xStart + (18 * 5), yStart));
			this.addSlotToContainer(new Slot(this.craftMatrix, 6, xStart + (18 * 6), yStart));
			// Row 2
			 ... You get the picture
			
			// Row 3
			 ...
			// Row 4
			 ...
			// Row 5
			 ...
			// Row 6
			 ...
			// Row 7
			 ... All the way to:
			this.addSlotToContainer(new Slot(this.craftMatrix, 48, xStart + (18 * 6), yStart + (18 * 6)));
		
		// Player Inventory
        xStart = 8;
		yStart = 150;
        for (int l = 0; l < 3; ++l)
        {
            for (int k = 0; k < 9; ++k)
            {
                this.addSlotToContainer(new Slot(player.inventory, k + l * 9 + 9, xStart + k * 18, l * 18 + yStart));
            }
        }

        // Player Hotbar
        xStart = 8;
        yStart = 208;
        for (int i1 = 0; i1 < 9; ++i1)
        {
            this.addSlotToContainer(new Slot(player.inventory, i1, xStart + i1 * 18, yStart));
        }
      
        this.onCraftMatrixChanged(this.craftMatrix);
	}
	
	@Override
	public void onCraftMatrixChanged(IInventory inventoryIn)
	{
		craftResult.setInventorySlotContents(0, StationCraftingManager.INSTANCE.findMatchingRecipe(craftMatrix, worldRef));
	}
	
	@Override
	public ItemStack transferStackInSlot(EntityPlayer playerIn, int index)
	{
		ItemStack previous = ItemStack.EMPTY;
	    Slot slot = (Slot) this.inventorySlots.get(index);

	    if (slot != null && slot.getHasStack())
	    {
	        ItemStack current = slot.getStack();
	        previous = current.copy();

	        if (index < this.handler.getSlots())
	        {
	            // From the conveyor's inventory to player's inventory
	            if (!this.mergeItemStack(current, handler.getSlots(), handler.getSlots() + 36, true)) return ItemStack.EMPTY;
	        }
	        else
	        {
	            // From the player's inventory to conveyor's inventory
	            if (!this.mergeItemStack(current, 0, handler.getSlots(), false)) return ItemStack.EMPTY;
	        }

	        if (current.getCount() == 0)
	            slot.putStack(ItemStack.EMPTY);
	        else slot.onSlotChanged();

	        if (current.getCount() == previous.getCount()) return null;
	        slot.onTake(playerIn, current);
	    }
	    return previous;
	}
	
	public void onContainerClosed(EntityPlayer playerIn)
    {
        super.onContainerClosed(playerIn);

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

                if (!itemstack.isEmpty())
                {
                    playerIn.dropItem(itemstack, false);
                }
            }
        }
    }
	
	@Override
	public boolean canInteractWith(EntityPlayer playerIn)
	{
		return !playerIn.isSpectator();
	}
}

 

Crafting Manager

public class StationCraftingManager
{
    public static final StationCraftingManager INSTANCE = new StationCraftingManager();
    private final List<IRecipe> recipes = Lists.<IRecipe>newArrayList();

    public static StationCraftingManager getInstance()
    {
        return INSTANCE;
    }

    public StationCraftingManager()
    {
    	FactoriCraftingRecipes.InitializeStationRecipes(this);    	
        Collections.sort(this.recipes, new StationRecipeSorter<IRecipe>(this));
    }

    // Copied from vanilla
    public StationShapedRecipes 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 (String s2 : astring)
            {
                ++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 = ItemStack.EMPTY;

            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 l = 0; l < j * k; ++l)
        {
            char c0 = s.charAt(l);

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

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

    // Copied from vanilla
    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));
    }

    public void addRecipe(IRecipe recipe)
    {
        this.recipes.add(recipe);
    }

    public ItemStack findMatchingRecipe(InventoryCrafting craftMatrix, World worldIn)
    {
        for (IRecipe irecipe : this.recipes)
        {
            if (irecipe.matches(craftMatrix, worldIn))
            {
                return irecipe.getCraftingResult(craftMatrix);
            }
        }

        return ItemStack.EMPTY;
    }

    // Copied from vanilla
    // Could this be the problem?
    public NonNullList<ItemStack> getRemainingItems(InventoryCrafting craftMatrix, World worldIn)
    {
        for (IRecipe irecipe : this.recipes)
        {
            if (irecipe.matches(craftMatrix, worldIn))
            {
                return irecipe.getRemainingItems(craftMatrix);
            }
        }

        NonNullList<ItemStack> nonnulllist = NonNullList.<ItemStack>withSize(craftMatrix.getSizeInventory(), ItemStack.EMPTY);

        for (int i = 0; i < nonnulllist.size(); ++i)
        {
            nonnulllist.set(i, craftMatrix.getStackInSlot(i));
        }

        return nonnulllist;
    }

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

 

The shaped and shapeless recipe classes are just copied from vanilla too, but altered to accommodate for a 7x7 recipe size. In case you're wondering WHY 7x7? It's that or wormhole crafting and I have plans to make it easier using blueprints, but that's a whole other matter and shouldn't be too difficult. It's figuring out why all the stack size numbers randomly multiply by like 10,000 that's the problem. I seriously do appreciate any help that can be given.

Posted

SlotCrafting#onTake is hardcoded to call getRemainingItems from the vanilla CraftingManager. To use your custom crafting manager, you'll need to make your own crafting slot implementation (it can be mostly the same as vanilla).

Posted (edited)

Ah thank you Jay, I will try that now.

 

Edit: Works like an absolute treat! Thank you, you're a legend. That's the 7x7 crafting station complete, now just to make the TileEntity store the contents of the craftmatrix when you close the GUI and restore it when you open, so it stores its contents like the Tinker's construct one does, because let's face it... crafting is so much easier when you can leave things in the crafting bench :P

Edited by DrLogiq
It worked :D

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.