Фантомный результат крафта.

Версия Minecraft
1.7.10
API
Forge
Доброе время суток, форум.
Проблема чётко видна на видео:

Вот исходники:
Некоторые классы брал из мод BiggerCraftingTable.
Container:
package ru.mrtenfan.utc.container;

import javax.annotation.Nonnull;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.inventory.Slot;
import net.minecraft.inventory.SlotCrafting;
import net.minecraft.item.ItemStack;
import ru.mrtenfan.utc.crafting.EngineeringTableRecipe;
import ru.mrtenfan.utc.crafting.EngineeringTableRecipe.EngineeringRecipe;
import ru.mrtenfan.utc.tileentity.TileEntityEngineeringTable;

public class ContainerEngineeringTable extends Container {
    
    private TileEntityEngineeringTable entity;
    private InventoryCrafting craftMatrix;
    private IInventory craftResult;
    
    public ContainerEngineeringTable(InventoryPlayer playerInv, @Nonnull TileEntityEngineeringTable tile) {
        this.entity = tile;
        
        craftMatrix = new CraftingEngineeringTable(this, entity);
        craftResult = new CraftResultEngineeringTable(entity, 6);
        
        for(int i = 0; i < 2; i++)
            for(int j = 0; j < 3; j++)
                this.addSlotToContainer(new Slot(craftMatrix, i + j * 2, 31 + j * 18, 26 + i * 18));
        
        this.addSlotToContainer(new SlotCrafting(playerInv.player, craftMatrix, craftResult, 6, 124, 35));

        for (int i = 0; i < 3; ++i)
            for (int j = 0; j < 9; ++j)
                this.addSlotToContainer(new Slot(playerInv, j + i * 9 + 9, 8 + j * 18, 84 + i * 18));
        for (int i = 0; i < 9; ++i)
            this.addSlotToContainer(new Slot(playerInv, i, 8 + i * 18, 142));
        onCraftMatrixChanged(craftMatrix);
    }

    @Override
    public boolean canInteractWith(EntityPlayer player) {
        return entity.isUseableByPlayer(player);
    }
    
    @Override
    public ItemStack transferStackInSlot(EntityPlayer player, int slotIn) {
        return null;
    }
    
    @Override
    public void onCraftMatrixChanged(IInventory matrix) {
        EngineeringRecipe recipe = EngineeringTableRecipe.getRecipe(craftMatrix);
        craftResult.setInventorySlotContents(6, recipe != null ? recipe.getResult() : null);
    }
}
CraftingEngineeringTable:
package ru.mrtenfan.utc.container;

import javax.annotation.Nonnull;

import net.minecraft.inventory.Container;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.ItemStack;
import ru.mrtenfan.utc.tileentity.TileEntityEngineeringTable;

public class CraftingEngineeringTable extends InventoryCrafting {
    
    private TileEntityEngineeringTable entity;
    private Container container;

    public CraftingEngineeringTable(@Nonnull Container container, @Nonnull  TileEntityEngineeringTable tile) {
        super(container, 3, 2);
        this.entity = tile;
        this.container = container;
    }
    
    @Override
    public ItemStack getStackInSlot(int slot) {
        return slot >= getSizeInventory() ? null : entity.getStackInSlot(slot);
    }
    
    @Override
    public ItemStack getStackInRowAndColumn(int row, int column) {
        int i = row * 2 + column;
        return i < 6 ? getStackInSlot(i) : null;
    }
    
    @Override
    public ItemStack decrStackSize(int slot, int i) {
        ItemStack is = getStackInSlot(slot);
        if(is != null) {
            ItemStack itemStack;
            if(is.stackSize <= i) {
                itemStack = is.copy();
                entity.setInventorySlotContents(slot, null);
                container.onCraftMatrixChanged(this);
                return itemStack;
            } else {
                itemStack = is.splitStack(i);
                container.onCraftMatrixChanged(this);
                return itemStack;
            }
        } else {
            return null;
        }
    }
    
    @Override
    public void setInventorySlotContents(int i, ItemStack itemStack) {
        entity.setInventorySlotContents(i, itemStack);
        container.onCraftMatrixChanged(this);
    }
    
    public ItemStack[] getSlots() {
        return entity.getSlotsCraft();
    }
}
CraftResultEngineeringTable:
package ru.mrtenfan.utc.container;

import javax.annotation.Nonnull;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import ru.mrtenfan.utc.tileentity.TileEntityEngineeringTable;

public class CraftResultEngineeringTable implements IInventory {
    
    private TileEntityEngineeringTable entity;
    private int slot;
    
    public CraftResultEngineeringTable(@Nonnull TileEntityEngineeringTable tile, int slot) {
        this.entity = tile;
        this.slot = slot;
    }

    @Override
    public int getSizeInventory() {
        return 1;
    }

    @Override
    public ItemStack getStackInSlot(int i) {
        return entity.getStackInSlot(this.slot);
    }

    @Override
    public ItemStack decrStackSize(int slot, int i) {
        return entity.decrStackSize(this.slot, i);
    }

    @Override
    public ItemStack getStackInSlotOnClosing(int slot) {
        return null;
    }

    @Override
    public void setInventorySlotContents(int slot, ItemStack itemStack) {
        entity.setInventorySlotContents(this.slot, itemStack);
    }

    @Override
    public String getInventoryName() {
        return null;
    }

    @Override
    public boolean hasCustomInventoryName() {
        return false;
    }

    @Override
    public int getInventoryStackLimit() {
        return 64;
    }

    @Override
    public void markDirty() {
        entity.markDirty();
    }

    @Override
    public boolean isUseableByPlayer(EntityPlayer player) {
        return true;
    }

    @Override
    public void openInventory() {}

    @Override
    public void closeInventory() {}

    @Override
    public boolean isItemValidForSlot(int slot, ItemStack is) {
        return entity.isItemValidForSlot(this.slot, is);
    }
}
Рецепты:
package ru.mrtenfan.utc.crafting;

import java.util.ArrayList;
import java.util.Collections;

import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.ItemStack;
import ru.mrtenfan.utc.container.CraftingEngineeringTable;

public class EngineeringTableRecipe {

    public static ArrayList<EngineeringRecipe> recipes = new ArrayList<EngineeringRecipe>();
    
    public static void addRecipe(EngineeringRecipe recipe) {
        recipes.add(recipe);
    }
    
    public static void addEngineeringRecipe(ItemStack[] inputs, ItemStack output, boolean isod) {
        if(inputs.length > 6)
            throw new RuntimeException("Engineering Recipe: Input can't be more than 6!");
        
        recipes.add(new EngineeringRecipe(inputs, output, isod));
    }
    
    public static EngineeringRecipe getRecipe(ItemStack[] inputs) {
        for(EngineeringRecipe r : recipes)
            if(getOutput(r.getInputs(), r.isOreDictionary(), inputs))
                return r;
        return null;
    }

    public static EngineeringRecipe getRecipe(InventoryCrafting craftMatrix) {
        return getRecipe(((CraftingEngineeringTable) craftMatrix).getSlots());
    }
    
    public static boolean getOutput(ItemStack[] inputs, boolean isod, ItemStack[] inputs2) {
        if(inputs.length < inputs2.length) return false;
        ArrayList<ItemStack> itemStacks = new ArrayList<ItemStack>();
        Collections.addAll(itemStacks, inputs);
        int i = 0;
        for(ItemStack is : inputs)
            if(is != null) {
                for(ItemStack is2 : inputs2)
                    if(is2 != null) {
                        if(ItemStack.areItemStacksEqual(is, is2) && is.stackSize >= is2.stackSize) {
                            i += 1;
                        }
                    }
            } else
                i += 1;
//        System.out.println(i);
        return i == 6;
    }

//    private static boolean areOreDictEqual(ItemStack is, ItemStack is2) {
//        for(int intItem1 : OreDictionary.getOreIDs(is))
//            for(int intItem2 : OreDictionary.getOreIDs(is2))
//                if(intItem1 == intItem2)
//                    return true;
//        return false;
//    }

    public static class EngineeringRecipe {
        
        private final ItemStack[] inputs = new ItemStack[6];
        private final ItemStack result;
        private final boolean isOreDict;
        
        public EngineeringRecipe(ItemStack[] inputs, ItemStack output, boolean isod) {
            for(int i = 0; i < inputs.length; i++) {
                this.inputs[i] = inputs[i];
            }
            this.result = output;
            this.isOreDict = isod;
        }
        
        public ItemStack[] getInputs() {
            return inputs;
        }
        
        public ItemStack getInput(int i) {
            return inputs[i];
        }

        public ItemStack getResult() {
            return result;
        }

        public boolean isOreDictionary() {
            return isOreDict;
        }
        
        public int[] getArrayInputNumbers() {
            int[] ret = new int[6];
            for(int i = 0; i < 6; i++)
                ret[i] = inputs[i].stackSize;
            return ret;
        }
    }
}
Заранее спасибо!
 
Сверху