package net.knarcraft.blacksmith.util; import net.knarcraft.blacksmith.BlacksmithPlugin; import net.knarcraft.blacksmith.config.SmithPreset; import org.bukkit.Material; import org.bukkit.Server; import org.bukkit.inventory.CraftingRecipe; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.Recipe; import org.bukkit.inventory.meta.Damageable; import org.bukkit.inventory.meta.ItemMeta; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.logging.Level; /** * A helper class for getting information about items */ public final class ItemHelper { private ItemHelper() { } /** * Gets whether the given item is repairable * * @param item
The item to check
* @returnTrue if the item is repairable
*/ public static boolean isRepairable(@NotNull ItemStack item) { return item.getItemMeta() instanceof Damageable && getMaxDurability(item) > 0; } /** * Gets the max durability of an item * * @param itemStackThe item to get the durability of
* @returnThe max durability of the item
*/ public static short getMaxDurability(@NotNull ItemStack itemStack) { if (itemStack.getItemMeta() instanceof Damageable) { return itemStack.getType().getMaxDurability(); } else { return 0; } } /** * Gets the current durability of the given item * * @param itemStackThe item to get the durability of
* @returnThe durability of the item
*/ public static short getDurability(@NotNull ItemStack itemStack) { if (itemStack.getItemMeta() instanceof Damageable damageable) { int maxDurability = getMaxDurability(itemStack); return (short) (maxDurability - damageable.getDamage()); } else { return 0; } } /** * Gets the damage done to the given item * * @param itemStackThe damage done to the item
* @returnThe damage done to the item
*/ public static short getDamage(@NotNull ItemStack itemStack) { if (itemStack.getItemMeta() instanceof Damageable damageable) { return (short) damageable.getDamage(); } else { return 0; } } /** * Updates the damage done to an item * * @param itemThe item to update damage for
* @param newDamageThe new damage done
* @returnTrue if the damage was updated. False if not damageable.
*/ public static boolean updateDamage(@NotNull ItemStack item, int newDamage) { ItemMeta meta = item.getItemMeta(); if (!(meta instanceof Damageable damageable)) { return false; } damageable.setDamage(newDamage); item.setItemMeta(meta); return true; } /** * Gets a complete list of all reforge-able materials * *Note: As this loops through all materials, the result should be cached
* * @returnA complete list of reforge-able materials
*/ public static @NotNull SetThe material to check
* @param requireDamagedWhether only a damaged anvil should count
* @returnTrue if the given material is an anvil
*/ public static boolean isAnvil(@NotNull Material material, boolean requireDamaged) { boolean isDamagedAnvil = material == Material.CHIPPED_ANVIL || material == Material.DAMAGED_ANVIL; boolean isAnvil = isDamagedAnvil || material == Material.ANVIL; return (requireDamaged && isDamagedAnvil) || (!requireDamaged && isAnvil); } /** * Checks whether the given inventory is able to fit the given item * * @param inventoryThe inventory to check
* @param itemThe item to check
* @returnTrue if the inventory can fit the item
*/ public static boolean canFitItem(@NotNull Inventory inventory, @NotNull ItemStack item) { // If a slot is available, there is no problem if (inventory.firstEmpty() != -1) { return true; } // If the inventory doesn't contain the correct type of item, stacking is impossible if (!inventory.contains(item.getType())) { return false; } // Check if the item stack can fit in the inventory if stacked with existing items int availableSlots = 0; for (ItemStack itemStack : inventory.getStorageContents()) { ItemMeta itemMeta = itemStack.getItemMeta(); ItemMeta targetMeta = item.getItemMeta(); // Skip items of a different type, or with metadata that would prevent stacking if (itemStack.getType() != item.getType() || (itemMeta != null && targetMeta != null && !itemMeta.equals(targetMeta))) { continue; } availableSlots += itemStack.getMaxStackSize() - itemStack.getAmount(); if (availableSlots < item.getAmount()) { return true; } } return false; } /** * Checks whether the given item can be salvaged, assuming no restrictions apply * * @param serverThe server to get recipes from
* @param itemThe item to check
* @returnTrue if the item can be salvaged
*/ public static boolean isSalvageable(@NotNull Server server, @NotNull ItemStack item) { for (Recipe recipe : server.getRecipesFor(new ItemStack(item.getType(), item.getAmount()))) { // Only crafting recipes are allowed. if ((recipe instanceof CraftingRecipe) && item.getAmount() >= recipe.getResult().getAmount()) { return true; } } return false; } /** * Gets the amount of an item that's required to salvage that item * * @param serverThe server to get recipes from
* @param itemThe item to check
* @returnThe number of items required for salvage, or -1 if the recipe was not found
*/ public static int getRequiredAmountForSalvage(@NotNull Server server, @NotNull ItemStack item) { for (Recipe recipe : server.getRecipesFor(new ItemStack(item.getType(), item.getAmount()))) { // Only crafting recipes are allowed. if (recipe instanceof CraftingRecipe) { return recipe.getResult().getAmount(); } } return -1; } /** * Gets all materials matching the given material wildcard * * @param materialNameThe material name or material wildcard to match
* @param extendedWhether to use an extended match, allowing any material
* @returnThe matched material(s)
*/ public static @NotNull SetThe list of items defined by the user
* @param requireRepairableWhether a material must be repairable to be valid.
* @returnThe materials contained in the item list
*/ public static ListThe value specified by a user
* @returnThe value with smith presets replaced
*/ private static @NotNull List