data, boolean matchPartialLists) {
+ return _matchesData(itemData, data, matchPartialLists);
+ }
+
+ private static boolean _matchesData(Object target, Object data, boolean matchPartialLists) {
+ if (target == data) return true;
+ if (data == null) return true;
+ if (target == null) return false;
+
+ // check if map contains given data:
+ if (data instanceof Map) {
+ if (!(target instanceof Map)) return false;
+ Map, ?> targetMap = (Map, ?>) target;
+ Map, ?> dataMap = (Map, ?>) data;
+ for (Entry, ?> entry : dataMap.entrySet()) {
+ Object targetValue = targetMap.get(entry.getKey());
+ if (!_matchesData(targetValue, entry.getValue(), matchPartialLists)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ // check if list contains given data:
+ if (matchPartialLists && data instanceof List) {
+ if (!(target instanceof List)) return false;
+ List> targetList = (List>) target;
+ List> dataList = (List>) data;
+ // if empty list is explicitly specified, then target list has to be empty as well:
+ /*if (dataList.isEmpty()) {
+ return targetList.isEmpty();
+ }*/
+ // Avoid loop (TODO: only works if dataList doesn't contain duplicate entries):
+ if (dataList.size() > targetList.size()) {
+ return false;
+ }
+ for (Object dataEntry : dataList) {
+ boolean dataContained = false;
+ for (Object targetEntry : targetList) {
+ if (_matchesData(targetEntry, dataEntry, matchPartialLists)) {
+ dataContained = true;
+ break;
+ }
+ }
+ if (!dataContained) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ // check if objects are equal:
+ return data.equals(target);
+ }
+
+ //
+
/**
* Increases the amount of the given {@link ItemStack}.
*
@@ -346,25 +466,23 @@ public final class ItemUtils {
}
/**
- * Checks if the given contents contains at least the specified amount of items matching the specified attributes.
+ * Checks if the given contents contains at least the specified amount of items matching the specified
+ * {@link ItemData}.
*
* @param contents
* the contents to search through
- * @param type
- * the item type
- * @param displayName
- * the displayName, or null
to ignore it
- * @param lore
- * the item lore, or null
or empty to ignore it
+ * @param itemData
+ * the item data to match, null
will not match any item
* @param amount
* the amount of items to look for
* @return true
if the at least specified amount of matching items was found
*/
- public static boolean containsAtLeast(ItemStack[] contents, Material type, String displayName, List lore, int amount) {
+ public static boolean containsAtLeast(ItemStack[] contents, ItemData itemData, int amount) {
if (contents == null) return false;
+ if (itemData == null) return false; // consider null to match no item here
int remainingAmount = amount;
for (ItemStack itemStack : contents) {
- if (!isSimilar(itemStack, type, displayName, lore)) continue;
+ if (!itemData.matches(itemStack)) continue;
int currentAmount = itemStack.getAmount() - remainingAmount;
if (currentAmount >= 0) {
return true;
@@ -376,26 +494,23 @@ public final class ItemUtils {
}
/**
- * Removes the specified amount of items which match the specified attributes from the given contents.
+ * Removes the specified amount of items which match the specified {@link ItemData} from the given contents.
*
* @param contents
* the contents
- * @param type
- * the item type
- * @param displayName
- * the display name, or null
to ignore it
- * @param lore
- * the item lore, or null
or empty to ignore it
+ * @param itemData
+ * the item data to match, null
will not match any item
* @param amount
* the amount of matching items to remove
* @return the amount of items that couldn't be removed (0
on full success)
*/
- public static int removeItems(ItemStack[] contents, Material type, String displayName, List lore, int amount) {
+ public static int removeItems(ItemStack[] contents, ItemData itemData, int amount) {
if (contents == null) return amount;
+ if (itemData == null) return amount;
int remainingAmount = amount;
for (int slotId = 0; slotId < contents.length; slotId++) {
ItemStack itemStack = contents[slotId];
- if (!isSimilar(itemStack, type, displayName, lore)) continue;
+ if (!itemData.matches(itemStack)) continue;
int newAmount = itemStack.getAmount() - remainingAmount;
if (newAmount > 0) {
itemStack.setAmount(newAmount);
diff --git a/src/main/java/com/nisovin/shopkeepers/util/Utils.java b/src/main/java/com/nisovin/shopkeepers/util/Utils.java
index 63042306..5a06c22b 100644
--- a/src/main/java/com/nisovin/shopkeepers/util/Utils.java
+++ b/src/main/java/com/nisovin/shopkeepers/util/Utils.java
@@ -576,6 +576,20 @@ public final class Utils {
return decolored;
}
+ // decolorizes string entries, otherwise adopts them as they are
+ public static List