package net.glowstone.inventory;
import net.glowstone.GlowServer;
import net.glowstone.entity.GlowPlayer;
import net.glowstone.inventory.crafting.CraftingManager;
import org.bukkit.Bukkit;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.inventory.InventoryType.SlotType;
import org.bukkit.inventory.*;
import java.util.Arrays;
/**
* Represents a crafting grid inventory, both workbench and per-player.
*/
public class GlowCraftingInventory extends GlowInventory implements CraftingInventory {
private static final int RESULT_SLOT = 0;
private static final int MATRIX_START = 1;
public GlowCraftingInventory(InventoryHolder owner, InventoryType type) {
super(owner, type);
if (type != InventoryType.CRAFTING && type != InventoryType.WORKBENCH) {
throw new IllegalArgumentException("GlowCraftingInventory cannot be " + type + ", only CRAFTING or WORKBENCH.");
}
getSlot(RESULT_SLOT).setType(InventoryType.SlotType.RESULT);
for (int i = MATRIX_START; i < getSize(); i++) {
getSlot(i).setType(InventoryType.SlotType.CRAFTING);
}
}
@Override
public void setItem(int index, ItemStack item) {
super.setItem(index, item);
if (index != RESULT_SLOT) {
Recipe recipe = getRecipe();
if (recipe == null) {
super.setItem(RESULT_SLOT, null);
} else {
super.setItem(RESULT_SLOT, recipe.getResult());
}
}
}
@Override
public boolean itemShiftClickAllowed(int slot, ItemStack stack) {
// cannot ever shift-click into a crafting inventory
return false;
}
@Override
public void handleShiftClick(GlowPlayer player, InventoryView view, int clickedSlot, ItemStack clickedItem) {
if (getSlotType(view.convertSlot(clickedSlot)) == SlotType.RESULT) {
// If the player clicked on the result give it to them
Recipe recipe = getRecipe();
if (recipe == null) {
return; // No complete recipe in crafting grid
}
// Set to correct amount (tricking the client and click handler)
int recipeAmount = ((GlowServer) Bukkit.getServer()).getCraftingManager().getLayers(getMatrix());
clickedItem.setAmount(clickedItem.getAmount() * recipeAmount);
// Place the items in the player's inventory (right to left)
player.getInventory().tryToFillSlots(clickedItem, 8, -1, 35, 8);
// Craft the items, removing the ingredients from the crafting matrix
for (int i = 0; i < recipeAmount; i++) {
craft();
}
} else {
// Clicked in the crafting grid, no special handling required (just place them left to right)
clickedItem = player.getInventory().tryToFillSlots(clickedItem, 9, 36, 0, 9);
view.setItem(clickedSlot, clickedItem);
}
}
@Override
public int getRawSlots() {
return 0;
}
/**
* Remove a layer of items from the inventory.
*/
public void craft() {
ItemStack[] matrix = getMatrix();
CraftingManager cm = ((GlowServer) Bukkit.getServer()).getCraftingManager();
Recipe recipe = cm.getCraftingRecipe(matrix);
if (recipe != null) {
craft(cm);
}
}
/**
* Remove a layer of items from the inventory.
*/
protected void craft(CraftingManager cm) {
ItemStack[] matrix = getMatrix();
cm.removeItems(matrix, this);
}
@Override
public ItemStack getResult() {
return getItem(RESULT_SLOT);
}
@Override
public ItemStack[] getMatrix() {
return Arrays.copyOfRange(getContents(), MATRIX_START, getSize());
}
@Override
public void setResult(ItemStack newResult) {
setItem(RESULT_SLOT, newResult);
}
@Override
public void setMatrix(ItemStack[] contents) {
if (contents.length != getSize() - 1) {
throw new IllegalArgumentException("Length must be " + (getSize() - 1));
}
for (int i = 0; i < contents.length; ++i) {
// Call super method, so we only calculate the result once
super.setItem(MATRIX_START + i, contents[i]);
}
// Update result
Recipe recipe = getRecipe();
if (recipe == null) {
super.setItem(RESULT_SLOT, null);
} else {
super.setItem(RESULT_SLOT, recipe.getResult());
}
}
@Override
public Recipe getRecipe() {
return ((GlowServer) Bukkit.getServer()).getCraftingManager().getCraftingRecipe(getMatrix());
}
}