4242import java .lang .reflect .Field ;
4343import java .util .*;
4444import java .util .Map .Entry ;
45+ import java .util .function .BiPredicate ;
4546import java .util .stream .Collectors ;
4647
4748@ ContainerType (ItemStack .class )
@@ -1342,34 +1343,61 @@ public boolean hasAnyEnchantments(Enchantment... enchantments) {
13421343 * Checks whether this item type contains all the given enchantments.
13431344 * Also checks the enchantment level, where any level equal or lesser than the item's level is accepted.
13441345 * @param enchantments The enchantments to be checked.
1346+ * @deprecated Use {@link #hasEnchantmentsOrBetter(EnchantmentType...)}
13451347 */
1348+ @ Deprecated (since ="INSERT VERSION" )
13461349 public boolean hasEnchantments (EnchantmentType ... enchantments ) {
1347- return hasEnchantments (true , enchantments );
1350+ return hasEnchantmentsOrBetter (true , enchantments );
13481351 }
13491352
13501353 /**
13511354 * Checks whether this item type contains the given enchantments.
13521355 * Also checks the enchantment level, where any level equal or lesser than the item's level is accepted.
13531356 * @param all Whether to check all enchantments or any enchantment.
13541357 * @param enchantments The enchantments to be checked.
1358+ * @deprecated Use {@link #hasEnchantmentsOrBetter(boolean, EnchantmentType...)}
13551359 */
1360+ @ Deprecated (since ="INSERT VERSION" )
13561361 public boolean hasEnchantments (boolean all , EnchantmentType ... enchantments ) {
1357- if (!hasEnchantments ())
1358- return false ;
1359- ItemMeta meta = getItemMeta ();
1360- for (EnchantmentType enchantment : enchantments ) {
1361- Enchantment type = enchantment .getType ();
1362- assert type != null ; // Bukkit working different than we expect
1363- if (!meta .hasEnchant (type ) && all )
1364- return false ;
1365- if (enchantment .getInternalLevel () == -1 || meta .getEnchantLevel (type ) >= enchantment .getLevel ()) {
1366- if (!all )
1367- return true ;
1368- } else if (all ) {
1369- return false ;
1370- }
1371- }
1372- return all ;
1362+ return hasEnchantmentsOrBetter (all , enchantments );
1363+ }
1364+
1365+ /**
1366+ * Checks whether this item type contains all the given enchantments.
1367+ * Also checks the enchantment level, where any level equal or lesser than the item's level is accepted.
1368+ * @param enchantments The enchantments to be checked.
1369+ */
1370+ public boolean hasEnchantmentsOrBetter (EnchantmentType ... enchantments ) {
1371+ return hasEnchantmentsOrBetter (true , enchantments );
1372+ }
1373+
1374+ /**
1375+ * Checks whether this item type contains the given enchantments.
1376+ * Also checks the enchantment level, where any level equal or lesser than the item's level is accepted.
1377+ * @param all Whether to check all enchantments or any enchantment.
1378+ * @param enchantments The enchantments to be checked.
1379+ */
1380+ public boolean hasEnchantmentsOrBetter (boolean all , EnchantmentType ... enchantments ) {
1381+ return hasEnchantments ((itemLevel , typeLevel ) -> itemLevel >= typeLevel , all , enchantments );
1382+ }
1383+
1384+ /**
1385+ * Checks whether this item type contains all the given enchantments.
1386+ * Also checks the enchantment level, where any level equal or greater than the item's level is accepted.
1387+ * @param enchantments The enchantments to be checked.
1388+ */
1389+ public boolean hasEnchantmentsOrWorse (EnchantmentType ... enchantments ) {
1390+ return hasEnchantmentsOrWorse (true , enchantments );
1391+ }
1392+
1393+ /**
1394+ * Checks whether this item type contains the given enchantments.
1395+ * Also checks the enchantment level, where any level equal or greater than the item's level is accepted.
1396+ * @param all Whether to check all enchantments or any enchantment.
1397+ * @param enchantments The enchantments to be checked.
1398+ */
1399+ public boolean hasEnchantmentsOrWorse (boolean all , EnchantmentType ... enchantments ) {
1400+ return hasEnchantments ((itemLevel , typeLevel ) -> itemLevel <= typeLevel , all , enchantments );
13731401 }
13741402
13751403 /**
@@ -1388,6 +1416,18 @@ public boolean hasExactEnchantments(EnchantmentType... enchantments) {
13881416 * @param enchantments The enchantments to be checked.
13891417 */
13901418 public boolean hasExactEnchantments (boolean all , EnchantmentType ... enchantments ) {
1419+ return hasEnchantments (Integer ::equals , all , enchantments );
1420+ }
1421+
1422+ /**
1423+ * Checks whether this item type contains the given enchantments.
1424+ * Also checks the enchantment level, with behavior depending on the {@code exact} parameter.
1425+ * @param levelMatchingCondition A predicate used to tell whether the item's level (first param) matches a type's level (second param).
1426+ * Types with no specified level will always match, regardless of this predicate.
1427+ * @param all Whether to check all enchantments or any enchantment.
1428+ * @param enchantments The enchantments to be checked.
1429+ */
1430+ private boolean hasEnchantments (BiPredicate <@ NotNull Integer , @ NotNull Integer > levelMatchingCondition , boolean all , EnchantmentType ... enchantments ) {
13911431 if (!hasEnchantments ())
13921432 return false ;
13931433 ItemMeta meta = getItemMeta ();
@@ -1396,14 +1436,15 @@ public boolean hasExactEnchantments(boolean all, EnchantmentType... enchantments
13961436 assert type != null ; // Bukkit working different than we expect
13971437 if (!meta .hasEnchant (type ) && all )
13981438 return false ;
1399- if (enchantment .getInternalLevel () == -1 || meta .getEnchantLevel (type ) == enchantment .getLevel ()) {
1439+ if (enchantment .getInternalLevel () == -1 || levelMatchingCondition . test ( meta .getEnchantLevel (type ), enchantment .getLevel () )) {
14001440 if (!all )
14011441 return true ;
14021442 } else if (all ) {
14031443 return false ;
14041444 }
14051445 }
14061446 return all ;
1447+
14071448 }
14081449
14091450 /**
0 commit comments