package slimeknights.tconstruct.tools.common.inventory;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.ClickType;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.InventoryCraftResult;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.apache.commons.lang3.tuple.Pair;
import javax.annotation.Nonnull;
import slimeknights.mantle.inventory.IContainerCraftingCustom;
import slimeknights.mantle.inventory.SlotCraftingCustom;
import slimeknights.mantle.inventory.SlotOut;
import slimeknights.tconstruct.library.Util;
import slimeknights.tconstruct.library.modifiers.TinkerGuiException;
import slimeknights.tconstruct.library.utils.ToolBuilder;
import slimeknights.tconstruct.shared.inventory.InventoryCraftingPersistent;
import slimeknights.tconstruct.tools.common.block.BlockToolTable;
import slimeknights.tconstruct.tools.common.client.GuiPartBuilder;
import slimeknights.tconstruct.tools.common.tileentity.TilePartBuilder;
import slimeknights.tconstruct.tools.common.tileentity.TilePatternChest;
public class ContainerPartBuilder extends ContainerTinkerStation<TilePartBuilder> implements IContainerCraftingCustom {
public IInventory craftResult;
//public IInventory craftResultSecondary;
private final Slot patternSlot;
private final Slot secondarySlot;
private final Slot input1;
private final Slot input2;
private final boolean partCrafter;
public final IInventory patternChest;
public ContainerPartBuilder(InventoryPlayer playerInventory, TilePartBuilder tile) {
super(tile);
InventoryCraftingPersistent craftMatrix = new InventoryCraftingPersistent(this, tile, 1, 3);
this.craftResult = new InventoryCraftResult();
//InventoryCrafting craftMatrixSecondary = new InventoryCrafting(this, 1, 1);
//this.craftResultSecondary = new InventoryCrafting(this, 1, 1);
// output slots
this.addSlotToContainer(new SlotCraftingCustom(this, playerInventory.player, craftMatrix, craftResult, 0, 106, 35));
this.addSlotToContainer(secondarySlot = new SlotOut(tile, 3, 132, 35));
// pattern slot
this.addSlotToContainer(patternSlot = new SlotStencil(craftMatrix, 2, 26, 35, false));
// material slots
this.addSlotToContainer(input1 = new Slot(craftMatrix, 0, 48, 26));
this.addSlotToContainer(input2 = new Slot(craftMatrix, 1, 48, 44));
TilePatternChest chest = detectTE(TilePatternChest.class);
// TE present?
if(chest != null) {
// crafting station and stencil table also present?
boolean hasCraftingStation = false;
boolean hasStencilTable = false;
for(Pair<BlockPos, IBlockState> pair : tinkerStationBlocks) {
if(!pair.getRight().getProperties().containsKey(BlockToolTable.TABLES)) {
continue;
}
BlockToolTable.TableTypes type = pair.getRight().getValue(BlockToolTable.TABLES);
if(type != null) {
if(type == BlockToolTable.TableTypes.CraftingStation) {
hasCraftingStation = true;
}
else if(type == BlockToolTable.TableTypes.StencilTable) {
hasStencilTable = true;
}
}
}
// are we a PartCrafter?
partCrafter = hasStencilTable && hasCraftingStation;
Container sideInventory = new ContainerPatternChest.DynamicChestInventory(chest, chest, -6, 8, 6);
addSubContainer(sideInventory, true);
patternChest = chest;
}
else {
partCrafter = false;
patternChest = null;
}
this.addPlayerInventory(playerInventory, 8, 84);
onCraftMatrixChanged(null);
}
public boolean isPartCrafter() {
return partCrafter;
}
@Override
public void onCraftMatrixChanged(IInventory inventoryIn) {
updateResult();
}
// Sets the result in the output slot depending on the input!
public void updateResult() {
// no pattern -> no output
if(!patternSlot.getHasStack() || (!input1.getHasStack() && !input2.getHasStack() && !secondarySlot.getHasStack())) {
craftResult.setInventorySlotContents(0, null);
updateGUI();
}
else {
Throwable throwable = null;
ItemStack[] toolPart;
try {
toolPart = ToolBuilder.tryBuildToolPart(patternSlot.getStack(), new ItemStack[]{input1.getStack(),
input2.getStack()}, false);
} catch(TinkerGuiException e) {
toolPart = null;
throwable = e;
}
ItemStack secondary = secondarySlot.getStack();
// got output?
if(toolPart != null &&
// got no secondary output or does it stack with the current one?
(secondary == null || toolPart[1] == null || ItemStack.areItemsEqual(secondary, toolPart[1]) && ItemStack.areItemStackTagsEqual(secondary, toolPart[1]))) {
craftResult.setInventorySlotContents(0, toolPart[0]);
}
else {
craftResult.setInventorySlotContents(0, null);
}
if(throwable != null) {
error(throwable.getMessage());
}
else {
updateGUI();
}
}
}
/** Looks for a pattern that matches the given one in the PatternChest and exchanges it with the pattern slot */
public void setPattern(ItemStack wanted) {
if(patternChest == null) {
return;
}
// check chest contents for wanted
for(int i = 0; i < patternChest.getSizeInventory(); i++) {
if(ItemStack.areItemStacksEqual(wanted, patternChest.getStackInSlot(i))) {
// found it! exchange it with the pattern slot!
ItemStack slotStack = patternSlot.getStack();
patternSlot.putStack(patternChest.getStackInSlot(i));
patternChest.setInventorySlotContents(i, slotStack);
break;
}
}
}
@Override
public void onCrafting(EntityPlayer player, ItemStack output, IInventory craftMatrix) {
ItemStack[] toolPart = new ItemStack[0];
try {
toolPart = ToolBuilder.tryBuildToolPart(patternSlot.getStack(), new ItemStack[]{input1.getStack(),
input2.getStack()}, true);
} catch(TinkerGuiException e) {
// don't need any user information at this stage
}
if(toolPart == null) {
// undefined :I
return;
}
ItemStack secondary = secondarySlot.getStack();
if(secondary == null) {
putStackInSlot(secondarySlot.slotNumber, toolPart[1]);
}
else if(toolPart[1] != null && ItemStack.areItemsEqual(secondary, toolPart[1]) && ItemStack.areItemStackTagsEqual(secondary, toolPart[1])) {
secondary.stackSize += toolPart[1].stackSize;
}
// clean up 0 size stacks
for(int i = 0; i < craftMatrix.getSizeInventory(); i++) {
if(craftMatrix.getStackInSlot(i) != null && craftMatrix.getStackInSlot(i).stackSize == 0) {
craftMatrix.setInventorySlotContents(i, null);
}
}
updateResult();
}
@Override
public boolean canMergeSlot(ItemStack p_94530_1_, Slot p_94530_2_) {
// prevents that doubleclicking on an item pulls the same out of the crafting slot
return p_94530_2_.inventory != this.craftResult && super.canMergeSlot(p_94530_1_, p_94530_2_);
}
@Override
public String getInventoryDisplayName() {
if(partCrafter) {
return Util.translate("gui.partcrafter.name");
}
return super.getInventoryDisplayName();
}
@Override
@SideOnly(Side.CLIENT)
public void putStackInSlot(int p_75141_1_, @Nonnull ItemStack p_75141_2_) {
super.putStackInSlot(p_75141_1_, p_75141_2_);
// this is called solely to update the gui buttons
Minecraft mc = Minecraft.getMinecraft();
if(mc.currentScreen instanceof GuiPartBuilder) {
((GuiPartBuilder) mc.currentScreen).updateButtons();
}
}
@Override
@SideOnly(Side.CLIENT)
public ItemStack slotClick(int slotId, int dragType, ClickType type, EntityPlayer player) {
ItemStack ret = super.slotClick(slotId, dragType, type, player);
// this is called solely to update the gui buttons
Minecraft mc = Minecraft.getMinecraft();
if(mc.currentScreen instanceof GuiPartBuilder) {
((GuiPartBuilder) mc.currentScreen).updateButtons();
}
return ret;
}
}