123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892 |
- package com.gmail.nossr50.util;
- import com.gmail.nossr50.api.ItemSpawnReason;
- import com.gmail.nossr50.config.experience.ExperienceConfig;
- import com.gmail.nossr50.config.party.ItemWeightConfig;
- import com.gmail.nossr50.datatypes.treasure.EnchantmentWrapper;
- import com.gmail.nossr50.datatypes.treasure.FishingTreasureBook;
- import com.gmail.nossr50.events.items.McMMOItemSpawnEvent;
- import com.gmail.nossr50.locale.LocaleLoader;
- import com.gmail.nossr50.mcMMO;
- import com.gmail.nossr50.skills.smelting.Smelting;
- import org.bukkit.ChatColor;
- import org.bukkit.Location;
- import org.bukkit.Material;
- import org.bukkit.NamespacedKey;
- import org.bukkit.enchantments.Enchantment;
- import org.bukkit.entity.Item;
- import org.bukkit.entity.Player;
- import org.bukkit.inventory.FurnaceRecipe;
- import org.bukkit.inventory.ItemStack;
- import org.bukkit.inventory.Recipe;
- import org.bukkit.inventory.meta.EnchantmentStorageMeta;
- import org.bukkit.inventory.meta.ItemMeta;
- import org.bukkit.util.Vector;
- import org.jetbrains.annotations.NotNull;
- import org.jetbrains.annotations.Nullable;
- import java.lang.reflect.InvocationTargetException;
- import java.lang.reflect.Method;
- import java.util.Collection;
- import java.util.Collections;
- import java.util.List;
- import java.util.function.Predicate;
- import static java.util.Objects.requireNonNull;
- public final class ItemUtils {
- // Reflection for setItemName only available in newer APIs
- private static final Method setItemName;
- static {
- setItemName = getSetItemName();
- }
- private ItemUtils() {
- // private constructor
- }
- private static Method getSetItemName() {
- try {
- return ItemMeta.class.getMethod("setItemName", String.class);
- } catch (NoSuchMethodException e) {
- return null;
- }
- }
- /**
- * Sets the item name using the new API if available
- * or falls back to the old API.
- *
- * @param itemMeta The item meta to set the name on
- * @param name The name to set
- */
- public static void setItemName(ItemMeta itemMeta, String name) {
- if (setItemName != null) {
- setItemNameModern(itemMeta, name);
- } else {
- itemMeta.setDisplayName(ChatColor.RESET + name);
- }
- }
- private static void setItemNameModern(ItemMeta itemMeta, String name) {
- try {
- setItemName.invoke(itemMeta, name);
- } catch (IllegalAccessException | InvocationTargetException e) {
- mcMMO.p.getLogger().severe("Failed to set item name: " + e.getMessage());
- throw new RuntimeException(e);
- }
- }
- /**
- * Checks if the item is a bow.
- *
- * @param item Item to check
- * @return true if the item is a bow, false otherwise
- */
- // TODO: Unit tests
- public static boolean isBow(@NotNull ItemStack item) {
- return mcMMO.getMaterialMapStore().isBow(item.getType().getKey().getKey());
- }
- /**
- * Exhaustive lookup for a Material by name.
- * <p>
- * This method will first try a normal lookup, then a legacy lookup, then a lookup by ENUM name,
- * and finally a lookup by ENUM name with legacy name.
- *
- * @param materialName The name of the material to lookup
- * @return The Material if found, or null if not found
- */
- public static @Nullable Material exhaustiveMaterialLookup(@NotNull String materialName) {
- requireNonNull(materialName, "materialName cannot be null");
- // First try a normal lookup
- Material material = Material.matchMaterial(materialName);
- // If that fails, try a legacy lookup
- if (material == null) {
- material = Material.matchMaterial(materialName, true);
- }
- // try to match to Material ENUM
- if (material == null) {
- material = Material.getMaterial(materialName.toUpperCase());
- }
- // try to match to Material ENUM with legacy name
- if (material == null) {
- material = Material.getMaterial(materialName.toUpperCase(), true);
- }
- return material;
- }
- /**
- * Checks if a player has an item in their inventory or offhand.
- *
- * @param player Player to check
- * @param material Material to check for
- * @return true if the player has the item in their inventory or offhand, false otherwise
- */
- public static boolean hasItemIncludingOffHand(Player player, Material material) {
- // Checks main inventory / item bar
- boolean containsInMain = player.getInventory().contains(material);
- if (containsInMain) {
- return true;
- }
- return player.getInventory().getItemInOffHand().getType() == material;
- }
- /**
- * Removes an item from a player's inventory, including their offhand.
- *
- * @param player Player to remove the item from
- * @param material Material to remove
- * @param amount Amount of the material to remove
- */
- public static void removeItemIncludingOffHand(@NotNull Player player, @NotNull Material material, int amount) {
- // Checks main inventory / item bar
- if (player.getInventory().contains(material)) {
- player.getInventory().removeItem(new ItemStack(material, amount));
- return;
- }
- // Check off-hand
- final ItemStack offHandItem = player.getInventory().getItemInOffHand();
- if (offHandItem.getType() == material) {
- int newAmount = offHandItem.getAmount() - amount;
- if (newAmount > 0) {
- offHandItem.setAmount(newAmount);
- } else {
- player.getInventory().setItemInOffHand(new ItemStack(Material.AIR));
- }
- }
- }
- // TODO: Unit tests
- public static boolean isCrossbow(@NotNull ItemStack item) {
- return mcMMO.getMaterialMapStore().isCrossbow(item.getType().getKey().getKey());
- }
- // TODO: Unit tests
- public static boolean isTrident(@NotNull ItemStack item) {
- return mcMMO.getMaterialMapStore().isTrident(item.getType().getKey().getKey());
- }
- public static boolean isMace(@NotNull ItemStack item) {
- return mcMMO.getMaterialMapStore().isMace(item.getType().getKey().getKey());
- }
- public static boolean hasItemInEitherHand(@NotNull Player player, Material material) {
- return player.getInventory().getItemInMainHand().getType() == material
- || player.getInventory().getItemInOffHand().getType() == material;
- }
- public static boolean doesPlayerHaveEnchantmentOnArmor(@NotNull Player player, @NotNull String enchantmentByName) {
- Enchantment enchantment = getEnchantment(enchantmentByName);
- if (enchantment == null)
- return false;
- return doesPlayerHaveEnchantmentOnArmor(player, enchantment);
- }
- public static boolean doesPlayerHaveEnchantmentOnArmor(@NotNull Player player, @NotNull Enchantment enchantment) {
- for (ItemStack itemStack : player.getInventory().getArmorContents()) {
- if (itemStack != null) {
- if (hasEnchantment(itemStack, enchantment))
- return true;
- }
- }
- return false;
- }
- public static boolean doesPlayerHaveEnchantmentOnArmorOrHands(@NotNull Player player, @NotNull String enchantmentName) {
- Enchantment enchantment = getEnchantment(enchantmentName);
- if (enchantment == null)
- return false;
- return doesPlayerHaveEnchantmentOnArmorOrHands(player, enchantment);
- }
- public static boolean doesPlayerHaveEnchantmentOnArmorOrHands(@NotNull Player player, @NotNull Enchantment enchantment) {
- if (doesPlayerHaveEnchantmentOnArmor(player, enchantment))
- return true;
- if (doesPlayerHaveEnchantmentInHands(player, enchantment))
- return true;
- return false;
- }
- public static boolean doesPlayerHaveEnchantmentInHands(@NotNull Player player, @NotNull NamespacedKey enchantmentNameKey) {
- Enchantment enchantment = Enchantment.getByKey(enchantmentNameKey);
- if (enchantment == null)
- return false;
- return doesPlayerHaveEnchantmentInHands(player, enchantment);
- }
- public static boolean doesPlayerHaveEnchantmentInHands(@NotNull Player player, @NotNull String enchantmentName) {
- Enchantment enchantment = getEnchantment(enchantmentName);
- if (enchantment == null)
- return false;
- return doesPlayerHaveEnchantmentInHands(player, enchantment);
- }
- public static boolean doesPlayerHaveEnchantmentInHands(@NotNull Player player, @NotNull Enchantment enchantment) {
- return hasEnchantment(player.getInventory().getItemInMainHand(), enchantment) ||
- hasEnchantment(player.getInventory().getItemInOffHand(), enchantment);
- }
- public static boolean hasEnchantment(@NotNull ItemStack itemStack, @NotNull Enchantment enchantment) {
- if (itemStack.getItemMeta() != null) {
- return itemStack.getItemMeta().hasEnchant(enchantment);
- }
- return false;
- }
- public static @Nullable Enchantment getEnchantment(@NotNull String enchantmentName) {
- for (Enchantment enchantment : Enchantment.values()) {
- if (enchantment.getKey().getKey().equalsIgnoreCase(enchantmentName)) {
- return enchantment;
- }
- }
- return null;
- }
- /**
- * Checks if the item is a sword.
- *
- * @param item Item to check
- * @return true if the item is a sword, false otherwise
- */
- public static boolean isSword(@NotNull ItemStack item) {
- return mcMMO.getMaterialMapStore().isSword(item.getType().getKey().getKey());
- }
- /**
- * Checks if the item is a hoe.
- *
- * @param item Item to check
- * @return true if the item is a hoe, false otherwise
- */
- public static boolean isHoe(@NotNull ItemStack item) {
- return mcMMO.getMaterialMapStore().isHoe(item.getType().getKey().getKey());
- }
- /**
- * Checks if the item is a shovel.
- *
- * @param item Item to check
- * @return true if the item is a shovel, false otherwise
- */
- public static boolean isShovel(@NotNull ItemStack item) {
- return mcMMO.getMaterialMapStore().isShovel(item.getType().getKey().getKey());
- }
- /**
- * Checks if the item is an axe.
- *
- * @param item Item to check
- * @return true if the item is an axe, false otherwise
- */
- public static boolean isAxe(@NotNull ItemStack item) {
- return mcMMO.getMaterialMapStore().isAxe(item.getType().getKey().getKey());
- }
- /**
- * Checks if the item is a pickaxe.
- *
- * @param item Item to check
- * @return true if the item is a pickaxe, false otherwise
- */
- public static boolean isPickaxe(@NotNull ItemStack item) {
- return mcMMO.getMaterialMapStore().isPickAxe(item.getType().getKey().getKey());
- }
- /**
- * Checks if the item counts as unarmed.
- *
- * @param item Item to check
- * @return true if the item counts as unarmed, false otherwise
- */
- public static boolean isUnarmed(ItemStack item) {
- if (mcMMO.p.getGeneralConfig().getUnarmedItemsAsUnarmed()) {
- return !isMinecraftTool(item);
- }
- return item.getType() == Material.AIR;
- }
- /**
- * Checks to see if an item is a wearable armor piece.
- *
- * @param item Item to check
- * @return true if the item is armor, false otherwise
- */
- public static boolean isArmor(ItemStack item) {
- return mcMMO.getMaterialMapStore().isArmor(item.getType());
- }
- /**
- * Checks to see if an item is a leather armor piece.
- *
- * @param item Item to check
- * @return true if the item is leather armor, false otherwise
- */
- public static boolean isLeatherArmor(ItemStack item) {
- return mcMMO.getMaterialMapStore().isLeatherArmor(item.getType());
- }
- /**
- * Checks to see if an item is a gold armor piece.
- *
- * @param item Item to check
- * @return true if the item is gold armor, false otherwise
- */
- public static boolean isGoldArmor(ItemStack item) {
- return mcMMO.getMaterialMapStore().isGoldArmor(item.getType().getKey().getKey());
- }
- /**
- * Checks to see if an item is an iron armor piece.
- *
- * @param item Item to check
- * @return true if the item is iron armor, false otherwise
- */
- public static boolean isIronArmor(ItemStack item) {
- return mcMMO.getMaterialMapStore().isIronArmor(item.getType().getKey().getKey());
- }
- /**
- * Checks to see if an item is a diamond armor piece.
- *
- * @param item Item to check
- * @return true if the item is diamond armor, false otherwise
- */
- public static boolean isDiamondArmor(ItemStack item) {
- return mcMMO.getMaterialMapStore().isDiamondArmor(item.getType().getKey().getKey());
- }
- public static boolean isNetheriteArmor(ItemStack itemStack) {
- return mcMMO.getMaterialMapStore().isNetheriteArmor(itemStack.getType().getKey().getKey());
- }
- public static boolean isNetheriteTool(ItemStack itemStack) {
- return mcMMO.getMaterialMapStore().isNetheriteTool(itemStack.getType().getKey().getKey());
- }
- /**
- * Checks to see if an item is a chainmail armor piece.
- *
- * @param item Item to check
- * @return true if the item is chainmail armor, false otherwise
- */
- public static boolean isChainmailArmor(ItemStack item) {
- return mcMMO.getMaterialMapStore().isChainmailArmor(item.getType().getKey().getKey());
- }
- /**
- * Checks to see if an item is a *vanilla* tool.
- *
- * @param item Item to check
- * @return true if the item is a tool, false otherwise
- */
- public static boolean isMinecraftTool(ItemStack item) {
- return mcMMO.getMaterialMapStore().isTool(item.getType().getKey().getKey());
- }
- /**
- * Checks to see if an item is a stone tool.
- *
- * @param item Item to check
- * @return true if the item is a stone tool, false otherwise
- */
- public static boolean isStoneTool(ItemStack item) {
- return mcMMO.getMaterialMapStore().isStoneTool(item.getType().getKey().getKey());
- }
- /**
- * Checks to see if an item is a wooden tool.
- *
- * @param item Item to check
- * @return true if the item is a wooden tool, false otherwise
- */
- public static boolean isWoodTool(ItemStack item) {
- return mcMMO.getMaterialMapStore().isWoodTool(item.getType().getKey().getKey());
- }
- /**
- * Checks to see if an item is a string tool.
- *
- * @param item Item to check
- * @return true if the item is a string tool, false otherwise
- */
- public static boolean isStringTool(ItemStack item) {
- return mcMMO.getMaterialMapStore().isStringTool(item.getType().getKey().getKey());
- }
- /**
- * Checks to see if an item is a gold tool.
- *
- * @param item Item to check
- * @return true if the item is a stone tool, false otherwise
- */
- public static boolean isGoldTool(ItemStack item) {
- return mcMMO.getMaterialMapStore().isGoldTool(item.getType().getKey().getKey());
- }
- /**
- * Checks to see if an item is an iron tool.
- *
- * @param item Item to check
- * @return true if the item is an iron tool, false otherwise
- */
- public static boolean isIronTool(ItemStack item) {
- return mcMMO.getMaterialMapStore().isIronTool(item.getType().getKey().getKey());
- }
- /**
- * Checks to see if an item is a diamond tool.
- *
- * @param item Item to check
- * @return true if the item is a diamond tool, false otherwise
- */
- public static boolean isDiamondTool(ItemStack item) {
- return mcMMO.getMaterialMapStore().isDiamondTool(item.getType().getKey().getKey());
- }
- /**
- * Checks to see if an item is enchantable.
- *
- * @param item Item to check
- * @return true if the item is enchantable, false otherwise
- */
- public static boolean isEnchantable(ItemStack item) {
- return mcMMO.getMaterialMapStore().isEnchantable(item.getType().getKey().getKey());
- }
- public static boolean isSmeltable(ItemStack item) {
- return item != null && Smelting.getSmeltXP(item) >= 1;
- }
- public static boolean isSmelted(ItemStack item) {
- if (item == null) {
- return false;
- }
- for (Recipe recipe : mcMMO.p.getServer().getRecipesFor(item)) {
- if (recipe instanceof FurnaceRecipe
- && ((FurnaceRecipe) recipe).getInput().getType().isBlock()
- && MaterialUtils.isOre(((FurnaceRecipe) recipe).getInput().getType())) {
- return true;
- }
- }
- return false;
- }
- /**
- * Check if an item is sharable.
- *
- * @param item Item that will get shared
- * @return True if the item can be shared.
- */
- public static boolean isSharable(ItemStack item) {
- if (item == null || item.getType() == Material.AIR) {
- return false;
- }
- return isMiningDrop(item)
- || isWoodcuttingDrop(item)
- || isMobDrop(item)
- || isHerbalismDrop(item)
- || isMiscDrop(item);
- }
- /**
- * Checks to see if an item is a mining drop.
- *
- * @param item Item to check
- * @return true if the item is a mining drop, false otherwise
- */
- public static boolean isMiningDrop(ItemStack item) {
- //TODO: 1.14 This needs to be updated
- return switch (item.getType()) { // Should we also have Glowing Redstone Ore here?
- // Should we also have Glowstone here?
- case COAL, COAL_ORE, DIAMOND, DIAMOND_ORE, EMERALD, EMERALD_ORE, GOLD_ORE, IRON_ORE, LAPIS_ORE,
- REDSTONE_ORE, REDSTONE, GLOWSTONE_DUST, QUARTZ, NETHER_QUARTZ_ORE, LAPIS_LAZULI -> true;
- default -> false;
- };
- }
- /**
- * Checks to see if an item is a herbalism drop.
- *
- * @param item Item to check
- * @return true if the item is a herbalism drop, false otherwise
- */
- public static boolean isHerbalismDrop(ItemStack item) {
- //TODO: 1.14 This needs to be updated
- return switch (item.getType().getKey().getKey().toLowerCase()) {
- case "wheat", "wheat_seeds", "carrot", "chorus_fruit", "chorus_flower", "potato", "beetroot", "beetroots",
- "beetroot_seeds", "nether_wart", "brown_mushroom", "red_mushroom", "rose_bush", "dandelion", "cactus",
- "sugar_cane", "melon", "melon_seeds", "pumpkin", "pumpkin_seeds", "lily_pad", "vine", "tall_grass",
- "cocoa_beans" -> true;
- default -> false;
- };
- }
- /**
- * Checks to see if an item is a mob drop.
- *
- * @param item Item to check
- * @return true if the item is a mob drop, false otherwise
- */
- public static boolean isMobDrop(ItemStack item) {
- //TODO: 1.14 This needs to be updated
- return switch (item.getType()) {
- case STRING, FEATHER, CHICKEN, COOKED_CHICKEN, LEATHER, BEEF, COOKED_BEEF, PORKCHOP, COOKED_PORKCHOP,
- WHITE_WOOL, BLACK_WOOL, BLUE_WOOL, BROWN_WOOL, CYAN_WOOL, GRAY_WOOL, GREEN_WOOL, LIGHT_BLUE_WOOL,
- LIGHT_GRAY_WOOL, LIME_WOOL, MAGENTA_WOOL, ORANGE_WOOL, PINK_WOOL, PURPLE_WOOL, RED_WOOL, YELLOW_WOOL,
- IRON_INGOT, SNOWBALL, BLAZE_ROD, SPIDER_EYE, GUNPOWDER, ENDER_PEARL, GHAST_TEAR, MAGMA_CREAM, BONE,
- ARROW, SLIME_BALL, NETHER_STAR, ROTTEN_FLESH, GOLD_NUGGET, EGG, ROSE_BUSH, COAL -> true;
- default -> false;
- };
- }
- /**
- * Checks to see if an item is a woodcutting drop.
- *
- * @param item Item to check
- * @return true if the item is a woodcutting drop, false otherwise
- */
- public static boolean isWoodcuttingDrop(ItemStack item) {
- return switch (item.getType().toString()) {
- case "ACACIA_LOG", "BIRCH_LOG", "DARK_OAK_LOG", "JUNGLE_LOG", "OAK_LOG", "SPRUCE_LOG",
- "STRIPPED_ACACIA_LOG", "STRIPPED_BIRCH_LOG", "STRIPPED_DARK_OAK_LOG", "STRIPPED_JUNGLE_LOG",
- "STRIPPED_OAK_LOG", "STRIPPED_SPRUCE_LOG", "STRIPPED_MANGROVE_LOG", "ACACIA_SAPLING", "SPRUCE_SAPLING",
- "BIRCH_SAPLING", "DARK_OAK_SAPLING", "JUNGLE_SAPLING", "OAK_SAPLING", "ACACIA_LEAVES", "BIRCH_LEAVES",
- "DARK_OAK_LEAVES", "JUNGLE_LEAVES", "OAK_LEAVES", "SPRUCE_LEAVES", "BEE_NEST", "APPLE" -> true;
- default -> false;
- };
- }
- /**
- * Checks to see if an item is a miscellaneous drop. These items are read from the config file
- *
- * @param item Item to check
- * @return true if the item is a miscellaneous drop, false otherwise
- */
- public static boolean isMiscDrop(ItemStack item) {
- return ItemWeightConfig.getInstance().getMiscItems().contains(item.getType());
- }
- public static boolean isMcMMOItem(ItemStack item) {
- if (!item.hasItemMeta()) {
- return false;
- }
- ItemMeta itemMeta = item.getItemMeta();
- if (itemMeta == null)
- return false;
- return itemMeta.getLore() != null
- && itemMeta.getLore().contains("mcMMO Item");
- }
- public static boolean isChimaeraWing(ItemStack item) {
- if (!isMcMMOItem(item)) {
- return false;
- }
- ItemMeta itemMeta = item.getItemMeta();
- if (itemMeta == null)
- return false;
- return itemMeta.hasDisplayName() && itemMeta.getDisplayName().equals(ChatColor.GOLD + LocaleLoader.getString("Item.ChimaeraWing.Name"));
- }
- public static void removeAbilityLore(@NotNull ItemStack itemStack) {
- ItemMeta itemMeta = itemStack.getItemMeta();
- if (itemMeta == null)
- return;
- if (itemMeta.hasLore()) {
- List<String> itemLore = itemMeta.getLore();
- if (itemLore == null)
- return;
- if (itemLore.remove("mcMMO Ability Tool")) {
- itemMeta.setLore(itemLore);
- itemStack.setItemMeta(itemMeta);
- }
- }
- }
- public static void addDigSpeedToItem(@NotNull ItemStack itemStack,
- int existingEnchantLevel) {
- ItemMeta itemMeta = itemStack.getItemMeta();
- if (itemMeta == null)
- return;
- itemMeta.addEnchant(mcMMO.p.getEnchantmentMapper().getEfficiency(),
- existingEnchantLevel + mcMMO.p.getAdvancedConfig().getEnchantBuff(), true);
- itemStack.setItemMeta(itemMeta);
- }
- public static boolean canBeSuperAbilityDigBoosted(@NotNull ItemStack itemStack) {
- return isShovel(itemStack) || isPickaxe(itemStack);
- }
- public static @NotNull ItemStack createEnchantBook(@NotNull FishingTreasureBook fishingTreasureBook) {
- ItemStack itemStack = fishingTreasureBook.getDrop().clone();
- EnchantmentWrapper enchantmentWrapper = getRandomEnchantment(fishingTreasureBook.getLegalEnchantments());
- ItemMeta itemMeta = itemStack.getItemMeta();
- if (itemMeta == null) {
- return itemStack;
- }
- EnchantmentStorageMeta enchantmentStorageMeta = (EnchantmentStorageMeta) itemMeta;
- enchantmentStorageMeta.addStoredEnchant(
- enchantmentWrapper.getEnchantment(),
- enchantmentWrapper.getEnchantmentLevel(),
- ExperienceConfig.getInstance().allowUnsafeEnchantments());
- itemStack.setItemMeta(enchantmentStorageMeta);
- return itemStack;
- }
- public static @NotNull EnchantmentWrapper getRandomEnchantment(
- @NotNull List<EnchantmentWrapper> enchantmentWrappers) {
- Collections.shuffle(enchantmentWrappers, Misc.getRandom());
- int randomIndex = Misc.getRandom().nextInt(enchantmentWrappers.size());
- return enchantmentWrappers.get(randomIndex);
- }
- /**
- * Drop items at a given location.
- *
- * @param location The location to drop the items at
- * @param itemStacks The items to drop
- */
- public static void spawnItems(@Nullable Player player,
- @NotNull Location location,
- @NotNull Collection<ItemStack> itemStacks,
- @NotNull ItemSpawnReason itemSpawnReason) {
- for (ItemStack is : itemStacks) {
- spawnItem(player, location, is, itemSpawnReason);
- }
- }
- /**
- * Drop items at a given location.
- *
- * @param location The location to drop the items at
- * @param is The items to drop
- * @param quantity The amount of items to drop
- */
- public static void spawnItems(@Nullable Player player,
- @NotNull Location location,
- @NotNull ItemStack is,
- int quantity,
- @NotNull ItemSpawnReason itemSpawnReason) {
- for (int i = 0; i < quantity; i++) {
- spawnItem(player, location, is, itemSpawnReason);
- }
- }
- /**
- * Drop an item at a given location.
- *
- * @param location The location to drop the item at
- * @param itemStack The item to drop
- * @param itemSpawnReason the reason for the item drop
- * @return Dropped Item entity or null if invalid or cancelled
- */
- public static @Nullable Item spawnItem(@Nullable Player player,
- @NotNull Location location,
- @NotNull ItemStack itemStack,
- @NotNull ItemSpawnReason itemSpawnReason) {
- if (itemStack.getType() == Material.AIR || location.getWorld() == null) {
- return null;
- }
- // We can't get the item until we spawn it and we want to make it cancellable, so we have a custom event.
- McMMOItemSpawnEvent event = new McMMOItemSpawnEvent(location, itemStack, itemSpawnReason, player);
- mcMMO.p.getServer().getPluginManager().callEvent(event);
- if (event.isCancelled()) {
- return null;
- }
- return location.getWorld().dropItem(location, itemStack);
- }
- /**
- * Drop an item at a given location.
- *
- * @param location The location to drop the item at
- * @param itemStack The item to drop
- * @param itemSpawnReason the reason for the item drop
- * @return Dropped Item entity or null if invalid or cancelled
- */
- public static @Nullable Item spawnItemNaturally(@Nullable Player player,
- @NotNull Location location,
- @NotNull ItemStack itemStack,
- @NotNull ItemSpawnReason itemSpawnReason) {
- if (itemStack.getType() == Material.AIR || location.getWorld() == null) {
- return null;
- }
- // We can't get the item until we spawn it and we want to make it cancellable, so we have a custom event.
- McMMOItemSpawnEvent event = new McMMOItemSpawnEvent(location, itemStack, itemSpawnReason, player);
- mcMMO.p.getServer().getPluginManager().callEvent(event);
- if (event.isCancelled()) {
- return null;
- }
- return location.getWorld().dropItemNaturally(location, itemStack);
- }
- /**
- * Drop items at a given location.
- *
- * @param fromLocation The location to drop the items at
- * @param is The items to drop
- * @param speed the speed that the item should travel
- * @param quantity The amount of items to drop
- */
- public static void spawnItemsTowardsLocation(@Nullable Player player,
- @NotNull Location fromLocation,
- @NotNull Location toLocation,
- @NotNull ItemStack is,
- int quantity,
- double speed,
- @NotNull ItemSpawnReason itemSpawnReason) {
- for (int i = 0; i < quantity; i++) {
- spawnItemTowardsLocation(player, fromLocation, toLocation, is, speed, itemSpawnReason);
- }
- }
- /**
- * Drop an item at a given location.
- * This method is fairly expensive as it creates clones of everything passed to itself since they are mutable objects
- *
- * @param fromLocation The location to drop the item at
- * @param toLocation The location the item will travel towards
- * @param itemToSpawn The item to spawn
- * @param speed the speed that the item should travel
- * @return Dropped Item entity or null if invalid or cancelled
- */
- public static @Nullable Item spawnItemTowardsLocation(@Nullable Player player,
- @NotNull Location fromLocation,
- @NotNull Location toLocation,
- @NotNull ItemStack itemToSpawn,
- double speed,
- @NotNull ItemSpawnReason itemSpawnReason) {
- if (itemToSpawn.getType() == Material.AIR) {
- return null;
- }
- //Work with fresh copies of everything
- ItemStack clonedItem = itemToSpawn.clone();
- Location spawnLocation = fromLocation.clone();
- Location targetLocation = toLocation.clone();
- if (spawnLocation.getWorld() == null)
- return null;
- // We can't get the item until we spawn it and we want to make it cancellable, so we have a custom event.
- McMMOItemSpawnEvent event = new McMMOItemSpawnEvent(spawnLocation, clonedItem, itemSpawnReason, player);
- mcMMO.p.getServer().getPluginManager().callEvent(event);
- //Something cancelled the event so back out
- if (event.isCancelled()) {
- return null;
- }
- //Use the item from the event
- Item spawnedItem = spawnLocation.getWorld().dropItem(spawnLocation, clonedItem);
- Vector vecFrom = spawnLocation.clone().toVector().clone();
- Vector vecTo = targetLocation.clone().toVector().clone();
- //Vector which is pointing towards out target location
- Vector direction = vecTo.subtract(vecFrom).normalize();
- //Modify the speed of the vector
- direction = direction.multiply(speed);
- spawnedItem.setVelocity(direction);
- return spawnedItem;
- }
- public static void spawnItemsFromCollection(@NotNull Player player,
- @NotNull Location location,
- @NotNull Collection<ItemStack> drops,
- @NotNull ItemSpawnReason itemSpawnReason) {
- requireNonNull(drops, "drops cannot be null");
- for (ItemStack drop : drops) {
- spawnItem(player, location, drop, itemSpawnReason);
- }
- }
- /**
- * Drops only the first n items in a collection
- * Size should always be a positive integer above 0
- *
- * @param location target drop location
- * @param drops collection to iterate over
- * @param sizeLimit the number of drops to process
- */
- public static void spawnItemsFromCollection(@Nullable Player player,
- @NotNull Location location,
- @NotNull Collection<ItemStack> drops,
- @NotNull ItemSpawnReason itemSpawnReason,
- int sizeLimit) {
- // TODO: This doesn't make much sense, unit test time?
- final ItemStack[] arrayDrops = drops.toArray(new ItemStack[0]);
- for (int i = 0; i < sizeLimit - 1; i++) {
- spawnItem(player, location, arrayDrops[i], itemSpawnReason);
- }
- }
- /**
- * Spawn items form a collection if conditions are met.
- * Each item is tested against the condition and spawned if it passes.
- *
- * @param potentialItemDrops The collection of items to iterate over, each one is tested and spawned if the
- * predicate is true
- * @param predicate The predicate to test the item against
- * @param itemSpawnReason The reason for the item drop
- * @param spawnLocation The location to spawn the item at
- * @param player The player to spawn the item for
- */
- public static void spawnItemsConditionally(@NotNull Collection<ItemStack> potentialItemDrops,
- @NotNull Predicate<ItemStack> predicate,
- @NotNull ItemSpawnReason itemSpawnReason,
- @NotNull Location spawnLocation,
- @NotNull Player player) {
- potentialItemDrops.stream()
- .filter(predicate)
- .forEach(itemStack -> spawnItem(player, spawnLocation, itemStack, itemSpawnReason));
- }
- }
|