|
42 | 42 | import java.lang.reflect.Field; |
43 | 43 | import java.util.*; |
44 | 44 | import java.util.Map.Entry; |
| 45 | +import java.util.function.BiPredicate; |
| 46 | +import java.util.function.Predicate; |
45 | 47 | import java.util.stream.Collectors; |
46 | 48 |
|
47 | 49 | @ContainerType(ItemStack.class) |
@@ -564,6 +566,30 @@ public Iterator<ItemStack> iterator() { |
564 | 566 | }; |
565 | 567 | } |
566 | 568 |
|
| 569 | + /** |
| 570 | + * Determines whether this ItemType satisfies the given predicate. |
| 571 | + * If {@link #isAll()} is true, this will return true if the predicate is satisfied by all ItemDatas. |
| 572 | + * If {@link #isAll()} is false, this will return true if the predicate is satisfied by any ItemData. |
| 573 | + * @param predicate A predicate to test items against |
| 574 | + * @return Whether this ItemType satisfies the predicate |
| 575 | + */ |
| 576 | + public boolean satisfies(Predicate<ItemStack> predicate) { |
| 577 | + if (isAll()) { |
| 578 | + for (Iterator<ItemStack> it = containerIterator(); it.hasNext(); ) { |
| 579 | + ItemStack stack = it.next(); |
| 580 | + if (!predicate.test(stack)) |
| 581 | + return false; |
| 582 | + } |
| 583 | + return true; |
| 584 | + } |
| 585 | + for (Iterator<ItemStack> it = containerIterator(); it.hasNext(); ) { |
| 586 | + ItemStack stack = it.next(); |
| 587 | + if (predicate.test(stack)) |
| 588 | + return true; |
| 589 | + } |
| 590 | + return false; |
| 591 | + } |
| 592 | + |
567 | 593 | @Nullable |
568 | 594 | public ItemStack removeAll(@Nullable ItemStack item) { |
569 | 595 | boolean wasAll = all; |
@@ -1262,7 +1288,7 @@ public Map<Enchantment,Integer> getEnchantments() { |
1262 | 1288 | public void addEnchantments(Map<Enchantment,Integer> enchantments) { |
1263 | 1289 | if (globalMeta == null) |
1264 | 1290 | globalMeta = ItemData.itemFactory.getItemMeta(Material.STONE); |
1265 | | - for (Map.Entry<Enchantment,Integer> entry : enchantments.entrySet()) { |
| 1291 | + for (Entry<Enchantment,Integer> entry : enchantments.entrySet()) { |
1266 | 1292 | assert globalMeta != null; |
1267 | 1293 | globalMeta.addEnchant(entry.getKey(), entry.getValue(), true); |
1268 | 1294 | } |
@@ -1339,23 +1365,111 @@ public boolean hasAnyEnchantments(Enchantment... enchantments) { |
1339 | 1365 | } |
1340 | 1366 |
|
1341 | 1367 | /** |
1342 | | - * Checks whether this item type contains the given enchantments. |
1343 | | - * Also checks the enchantment level. |
| 1368 | + * Checks whether this item type contains all the given enchantments. |
| 1369 | + * Also checks the enchantment level, where any level equal or lesser than the item's level is accepted. |
1344 | 1370 | * @param enchantments The enchantments to be checked. |
| 1371 | + * @deprecated Use {@link #hasEnchantmentsOrBetter(EnchantmentType...)} |
1345 | 1372 | */ |
| 1373 | + @Deprecated(since="INSERT VERSION") |
1346 | 1374 | public boolean hasEnchantments(EnchantmentType... enchantments) { |
| 1375 | + return hasEnchantmentsOrBetter(true, enchantments); |
| 1376 | + } |
| 1377 | + |
| 1378 | + /** |
| 1379 | + * Checks whether this item type contains the given enchantments. |
| 1380 | + * Also checks the enchantment level, where any level equal or lesser than the item's level is accepted. |
| 1381 | + * @param all Whether to check all enchantments or any enchantment. |
| 1382 | + * @param enchantments The enchantments to be checked. |
| 1383 | + * @deprecated Use {@link #hasEnchantmentsOrBetter(boolean, EnchantmentType...)} |
| 1384 | + */ |
| 1385 | + @Deprecated(since="INSERT VERSION") |
| 1386 | + public boolean hasEnchantments(boolean all, EnchantmentType... enchantments) { |
| 1387 | + return hasEnchantmentsOrBetter(all, enchantments); |
| 1388 | + } |
| 1389 | + |
| 1390 | + /** |
| 1391 | + * Checks whether this item type contains all the given enchantments. |
| 1392 | + * Also checks the enchantment level, where any level equal or lesser than the item's level is accepted. |
| 1393 | + * @param enchantments The enchantments to be checked. |
| 1394 | + */ |
| 1395 | + public boolean hasEnchantmentsOrBetter(EnchantmentType... enchantments) { |
| 1396 | + return hasEnchantmentsOrBetter(true, enchantments); |
| 1397 | + } |
| 1398 | + |
| 1399 | + /** |
| 1400 | + * Checks whether this item type contains the given enchantments. |
| 1401 | + * Also checks the enchantment level, where any level equal or lesser than the item's level is accepted. |
| 1402 | + * @param all Whether to check all enchantments or any enchantment. |
| 1403 | + * @param enchantments The enchantments to be checked. |
| 1404 | + */ |
| 1405 | + public boolean hasEnchantmentsOrBetter(boolean all, EnchantmentType... enchantments) { |
| 1406 | + return hasEnchantments((itemLevel, typeLevel) -> itemLevel >= typeLevel, all, enchantments); |
| 1407 | + } |
| 1408 | + |
| 1409 | + /** |
| 1410 | + * Checks whether this item type contains all the given enchantments. |
| 1411 | + * Also checks the enchantment level, where any level equal or greater than the item's level is accepted. |
| 1412 | + * @param enchantments The enchantments to be checked. |
| 1413 | + */ |
| 1414 | + public boolean hasEnchantmentsOrWorse(EnchantmentType... enchantments) { |
| 1415 | + return hasEnchantmentsOrWorse(true, enchantments); |
| 1416 | + } |
| 1417 | + |
| 1418 | + /** |
| 1419 | + * Checks whether this item type contains the given enchantments. |
| 1420 | + * Also checks the enchantment level, where any level equal or greater than the item's level is accepted. |
| 1421 | + * @param all Whether to check all enchantments or any enchantment. |
| 1422 | + * @param enchantments The enchantments to be checked. |
| 1423 | + */ |
| 1424 | + public boolean hasEnchantmentsOrWorse(boolean all, EnchantmentType... enchantments) { |
| 1425 | + return hasEnchantments((itemLevel, typeLevel) -> itemLevel <= typeLevel, all, enchantments); |
| 1426 | + } |
| 1427 | + |
| 1428 | + /** |
| 1429 | + * Checks whether this item type contains all the given enchantments with the given level. |
| 1430 | + * EnchantmentTypes that do not specify a level match any level. |
| 1431 | + * @param enchantments The enchantments to be checked. |
| 1432 | + */ |
| 1433 | + public boolean hasExactEnchantments(EnchantmentType... enchantments) { |
| 1434 | + return hasExactEnchantments(true, enchantments); |
| 1435 | + } |
| 1436 | + |
| 1437 | + /** |
| 1438 | + * Checks whether this item type contains the given enchantments with the given level. |
| 1439 | + * EnchantmentTypes that do not specify a level match any level. |
| 1440 | + * @param all Whether to check all enchantments or any enchantment. |
| 1441 | + * @param enchantments The enchantments to be checked. |
| 1442 | + */ |
| 1443 | + public boolean hasExactEnchantments(boolean all, EnchantmentType... enchantments) { |
| 1444 | + return hasEnchantments(Integer::equals, all, enchantments); |
| 1445 | + } |
| 1446 | + |
| 1447 | + /** |
| 1448 | + * Checks whether this item type contains the given enchantments. |
| 1449 | + * Also checks the enchantment level, with behavior depending on the {@code exact} parameter. |
| 1450 | + * @param levelMatchingCondition A predicate used to tell whether the item's level (first param) matches a type's level (second param). |
| 1451 | + * Types with no specified level will always match, regardless of this predicate. |
| 1452 | + * @param all Whether to check all enchantments or any enchantment. |
| 1453 | + * @param enchantments The enchantments to be checked. |
| 1454 | + */ |
| 1455 | + private boolean hasEnchantments(BiPredicate<@NotNull Integer, @NotNull Integer> levelMatchingCondition, boolean all, EnchantmentType... enchantments) { |
1347 | 1456 | if (!hasEnchantments()) |
1348 | 1457 | return false; |
1349 | 1458 | ItemMeta meta = getItemMeta(); |
1350 | 1459 | for (EnchantmentType enchantment : enchantments) { |
1351 | 1460 | Enchantment type = enchantment.getType(); |
1352 | 1461 | assert type != null; // Bukkit working different than we expect |
1353 | | - if (!meta.hasEnchant(type)) |
| 1462 | + if (!meta.hasEnchant(type) && all) |
1354 | 1463 | return false; |
1355 | | - if (enchantment.getInternalLevel() != -1 && meta.getEnchantLevel(type) < enchantment.getLevel()) |
| 1464 | + if (enchantment.getInternalLevel() == -1 || levelMatchingCondition.test(meta.getEnchantLevel(type), enchantment.getLevel())) { |
| 1465 | + if (!all) |
| 1466 | + return true; |
| 1467 | + } else if (all) { |
1356 | 1468 | return false; |
| 1469 | + } |
1357 | 1470 | } |
1358 | | - return true; |
| 1471 | + return all; |
| 1472 | + |
1359 | 1473 | } |
1360 | 1474 |
|
1361 | 1475 | /** |
|
0 commit comments