public class CraftItemHandler implements Listener {
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onCraftItem(CraftItemEvent e) {
Player p = (Player) e.getWhoClicked();
ItemStack result = e.getRecipe().getResult();
ItemStack cursor = e.getCursor();
if(cursor != null && cursor.getType() != Material.AIR) {
if(!result.isSimilar(cursor))
return; // l'on ne peut pas stacker ensemble le curseur et le résultat
if((cursor.getAmount() + result.getAmount()) > cursor.getMaxStackSize())
return; // impossible de réunir le curseur et le résultat
// ex.: prendre 4 torches alors qu'on en a 62 dans notre main
}
if(e.getResult() == Event.Result.DENY)
return; // un autre plugin refuse le craft
int count = result.getAmount();
switch(e.getClick()) {
case NUMBER_KEY:
if(p.getInventory().getItem(e.getHotbarButton()) != null)
count = 0; // il y a déjà un item dans cet emplacement de la hotbar
// le comportement vanilla ne vérifie pas s'il peut éventuellement réunir les deux
break;
case DROP:
case CONTROL_DROP:
if(cursor != null && cursor.getType() != Material.AIR)
count = 0; // on ne peut pas faire du craft-and-drop avec un item en main
break;
case SHIFT_RIGHT:
case SHIFT_LEFT:
int maxCraftable = getMaxCraftableQuantity(e.getInventory());
int maxAddable = getMaxFillableQuantity(result, e.getView().getBottomInventory());
if(maxAddable < maxCraftable)
// pas assez de place dans l'inventaire
maxCraftable = ((maxAddable + count - 1) / count) * count;
count = maxCraftable;
break;
default:
break;
}
if(count == 0)
return;
p.sendMessage("Craft réussi, recette utilisée " + count + " fois");
}
// renvoit la quantité maximale craftable à partir des ingrédients de l'inventaire
public static int getMaxCraftableQuantity(CraftingInventory inventory) {
if(inventory.getResult() == null)
return 0;
int resultQuantity = inventory.getResult().getAmount();
int materialQuantity = Integer.MAX_VALUE;
for(ItemStack stack : inventory.getMatrix())
//noinspection ConstantConditions
if(stack != null)
materialQuantity = Math.min(materialQuantity, stack.getAmount());
return resultQuantity * materialQuantity;
}
// renvoit la quantité maximale d'objets que l'on peut stocker dans l'inventaire spécifié
public static int getMaxFillableQuantity(ItemStack stack, Inventory inventory) {
int quantity = 0;
for(ItemStack slot : inventory.getContents()) {
//noinspection ConstantConditions
if(slot == null)
quantity += stack.getMaxStackSize();
else if(slot.isSimilar(stack))
quantity += Math.max(stack.getMaxStackSize() - slot.getAmount(), 0);
}
return quantity;
}
}