package com.projectzed.mod.integration.jei;
import com.projectzed.mod.ProjectZed;
import com.projectzed.mod.container.ContainerStoneCraftingTable;
import mezz.jei.api.IModRegistry;
import mezz.jei.api.gui.IGuiIngredient;
import mezz.jei.api.gui.IGuiItemStackGroup;
import mezz.jei.api.gui.IRecipeLayout;
import mezz.jei.api.recipe.VanillaRecipeCategoryUid;
import mezz.jei.api.recipe.transfer.IRecipeTransferError;
import mezz.jei.api.recipe.transfer.IRecipeTransferHandler;
import mezz.jei.api.recipe.transfer.IRecipeTransferRegistry;
import mezz.jei.transfer.BasicRecipeTransferInfo;
import mezz.jei.util.StackHelper;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.ContainerPlayer;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @author hockeyhurd
* @version 10/26/2016.
*/
public final class StoneCraftingTableRecipeTransferHandler implements IRecipeTransferHandler {
private final IModRegistry registry;
private final @Nonnull BasicRecipeTransferInfo transferInfo;
private StoneCraftingTableRecipeTransferHandler(IModRegistry registry) {
this.registry = registry;
// transferInfo = new BasicRecipeTransferInfo<ContainerStoneCraftingTable>(ContainerStoneCraftingTable.class, VanillaRecipeCategoryUid.CRAFTING, 0, 9, 10, 36);
transferInfo = new BasicRecipeTransferInfo<ContainerPlayer>(ContainerPlayer.class, VanillaRecipeCategoryUid.CRAFTING, 0, 9, 10, 36);
}
public static void register(IModRegistry registry) {
final IRecipeTransferRegistry recipeTransferRegistry = registry.getRecipeTransferRegistry();
recipeTransferRegistry.addRecipeTransferHandler(new StoneCraftingTableRecipeTransferHandler(registry));
registry.addRecipeCategoryCraftingItem(new ItemStack(ProjectZed.stoneCraftingTable), VanillaRecipeCategoryUid.CRAFTING);
}
@Override
public Class getContainerClass() {
return ContainerStoneCraftingTable.class;
}
@Override
public String getRecipeCategoryUid() {
return VanillaRecipeCategoryUid.CRAFTING;
}
@Nullable
@Override
public IRecipeTransferError transferRecipe(Container container, IRecipeLayout recipeLayout, EntityPlayer player, boolean maxTransfer,
boolean doTransfer) {
if (!(container instanceof ContainerStoneCraftingTable))
return registry.getJeiHelpers().recipeTransferHandlerHelper().createInternalError();
final ContainerStoneCraftingTable containerStoneCraftingTable = (ContainerStoneCraftingTable) container;
if (doTransfer) containerStoneCraftingTable.clearCraftingGrid();
List<Integer> missingItemSlots = new ArrayList<Integer>();
ItemStack[][] ingredients = new ItemStack[9][];
IGuiItemStackGroup itemStacks = recipeLayout.getItemStacks();
Map<Integer, ? extends IGuiIngredient<ItemStack>> guiIngredients = itemStacks.getGuiIngredients();
for (int i = 0; i < 9; i++) {
final int slotOffset = i + 1;
if (guiIngredients.containsKey(slotOffset)) {
final List<ItemStack> allIngredients = guiIngredients.get(slotOffset).getAllIngredients();
if (!allIngredients.isEmpty()) {
if (containerContainsIngredient(containerStoneCraftingTable, allIngredients))
ingredients[i] = allIngredients.toArray(new ItemStack[allIngredients.size()]);
else missingItemSlots.add(slotOffset);
}
}
}
if (missingItemSlots.isEmpty()) {
if (doTransfer) {
containerStoneCraftingTable.fillCraftingGrid(ingredients, maxTransfer ? 0x40 : 1);
/*for (int i = 0; i < player.inventory.getSizeInventory(); i++) {
ItemStack stackInSlot = player.inventory.getStackInSlot(i);
if (stackInSlot == null) continue;
boolean canEscape = false;
for (int index = 0; index < ingredients.length; index++) {
if (ingredients[index] == null) continue;
for (int type = 0; type < ingredients[index].length; type++) {
if (stackInSlot.isItemEqual(ingredients[index][type])) {
stackInSlot.stackSize -= ingredients[index][type].stackSize;
if (stackInSlot.stackSize == 0) {
player.inventory.setInventorySlotContents(i, null);
canEscape = true;
break;
}
player.inventory.setInventorySlotContents(i, stackInSlot);
}
}
if (canEscape) break;
}
}
player.inventory.markDirty();*/
}
return null;
}
return registry.getJeiHelpers().recipeTransferHandlerHelper().createUserErrorForSlots("Recipe transfer error!", missingItemSlots);
}
/*@Nullable
@Override
public IRecipeTransferError transferRecipe(ContainerPlayer container, IRecipeLayout recipeLayout, EntityPlayer player, boolean maxTransfer, boolean doTransfer) {
if (!SessionData.isJeiOnServer()) {
String tooltipMessage = Translator.translateToLocal("jei.tooltip.error.recipe.transfer.no.server");
return handlerHelper.createUserErrorWithTooltip(tooltipMessage);
}
if (!transferHelper.canHandle(container)) {
return handlerHelper.createInternalError();
}
Map<Integer, Slot> inventorySlots = new HashMap<Integer, Slot>();
for (Slot slot : transferHelper.getInventorySlots(container)) {
inventorySlots.put(slot.slotNumber, slot);
}
Map<Integer, Slot> craftingSlots = new HashMap<Integer, Slot>();
for (Slot slot : transferHelper.getRecipeSlots(container)) {
craftingSlots.put(slot.slotNumber, slot);
}
IGuiItemStackGroup itemStackGroup = recipeLayout.getItemStacks();
int inputCount = 0;
{
// indexes that do not fit into the player crafting grid
Set<Integer> badIndexes = ImmutableSet.of(2, 5, 6, 7, 8);
int inputIndex = 0;
for (IGuiIngredient<ItemStack> ingredient : itemStackGroup.getGuiIngredients().values()) {
if (ingredient.isInput()) {
if (!ingredient.getAllIngredients().isEmpty()) {
inputCount++;
if (badIndexes.contains(inputIndex)) {
String tooltipMessage = Translator.translateToLocal("jei.tooltip.error.recipe.transfer.too.large.player.inventory");
return handlerHelper.createUserErrorWithTooltip(tooltipMessage);
}
}
inputIndex++;
}
}
}
// compact the crafting grid into a 2x2 area
List<IGuiIngredient<ItemStack>> guiIngredients = new ArrayList<IGuiIngredient<ItemStack>>();
for (IGuiIngredient<ItemStack> guiIngredient : itemStackGroup.getGuiIngredients().values()) {
if (guiIngredient.isInput()) {
guiIngredients.add(guiIngredient);
}
}
IGuiItemStackGroup playerInvItemStackGroup = new GuiItemStackGroup(null);
int[] playerGridIndexes = {0, 1, 3, 4};
for (int i = 0; i < 4; i++) {
IGuiIngredient<ItemStack> ingredient = guiIngredients.get(playerGridIndexes[i]);
playerInvItemStackGroup.init(i, true, 0, 0);
playerInvItemStackGroup.set(i, ingredient.getAllIngredients());
}
Map<Integer, ItemStack> availableItemStacks = new HashMap<Integer, ItemStack>();
int filledCraftSlotCount = 0;
int emptySlotCount = 0;
for (Slot slot : craftingSlots.values()) {
final ItemStack stack = slot.getStack();
if (!stack.isEmpty()) {
if (!slot.canTakeStack(player)) {
ProjectZed.logHelper.severe("Recipe Transfer helper {} does not work for container {}. Player can't move item out of Crafting Slot number {}", transferHelper.getClass(), container.getClass(), slot.slotNumber);
return handlerHelper.createInternalError();
}
filledCraftSlotCount++;
availableItemStacks.put(slot.slotNumber, stack.copy());
}
}
for (Slot slot : inventorySlots.values()) {
final ItemStack stack = slot.getStack();
if (!stack.isEmpty()) {
availableItemStacks.put(slot.slotNumber, stack.copy());
} else {
emptySlotCount++;
}
}
// check if we have enough inventory space to shuffle items around to their final locations
if (filledCraftSlotCount - inputCount > emptySlotCount) {
String message = Translator.translateToLocal("jei.tooltip.error.recipe.transfer.inventory.full");
return handlerHelper.createUserErrorWithTooltip(message);
}
StackHelper.MatchingItemsResult matchingItemsResult = stackHelper.getMatchingItems(availableItemStacks, playerInvItemStackGroup.getGuiIngredients());
if (matchingItemsResult.missingItems.size() > 0) {
String message = Translator.translateToLocal("jei.tooltip.error.recipe.transfer.missing");
matchingItemsResult = stackHelper.getMatchingItems(availableItemStacks, itemStackGroup.getGuiIngredients());
return handlerHelper.createUserErrorForSlots(message, matchingItemsResult.missingItems);
}
List<Integer> craftingSlotIndexes = new ArrayList<Integer>(craftingSlots.keySet());
Collections.sort(craftingSlotIndexes);
List<Integer> inventorySlotIndexes = new ArrayList<Integer>(inventorySlots.keySet());
Collections.sort(inventorySlotIndexes);
// check that the slots exist and can be altered
for (Map.Entry<Integer, Integer> entry : matchingItemsResult.matchingItems.entrySet()) {
int craftNumber = entry.getKey();
int slotNumber = craftingSlotIndexes.get(craftNumber);
if (slotNumber < 0 || slotNumber >= container.inventorySlots.size()) {
ProjectZed.logHelper.severe("Recipes Transfer Helper {} references slot {} outside of the inventory's size {}", transferHelper.getClass(), slotNumber, container.inventorySlots.size());
return handlerHelper.createInternalError();
}
}
if (doTransfer) {
PacketRecipeTransfer packet = new PacketRecipeTransfer(matchingItemsResult.matchingItems, craftingSlotIndexes, inventorySlotIndexes, maxTransfer);
JustEnoughItems.getProxy().sendPacketToServer(packet);
}
return null;
}*/
private boolean containerContainsIngredient(ContainerStoneCraftingTable container, List<ItemStack> ingredientList) {
List<Slot> slots = transferInfo.getInventorySlots(container);
List<ItemStack> availableItems = new ArrayList<ItemStack>(slots.size() << 1);
for (Slot slot : slots) {
if (slot.getHasStack()) availableItems.add(slot.getStack());
}
final StackHelper stackHelper = (StackHelper) registry.getJeiHelpers().getStackHelper();
return stackHelper.containsAnyStack(availableItems, ingredientList) != null;
}
}