diff --git a/core/src/main/java/tc/oc/pgm/itemmeta/ItemModifyModule.java b/core/src/main/java/tc/oc/pgm/itemmeta/ItemModifyModule.java index e79c85c759..1458968c70 100644 --- a/core/src/main/java/tc/oc/pgm/itemmeta/ItemModifyModule.java +++ b/core/src/main/java/tc/oc/pgm/itemmeta/ItemModifyModule.java @@ -14,6 +14,7 @@ import tc.oc.pgm.api.map.factory.MapFactory; import tc.oc.pgm.api.map.factory.MapModuleFactory; import tc.oc.pgm.api.match.Match; +import tc.oc.pgm.util.inventory.ItemMatcher; import tc.oc.pgm.util.inventory.tag.ItemTag; import tc.oc.pgm.util.material.MaterialMatcher; import tc.oc.pgm.util.xml.InvalidXMLException; @@ -21,24 +22,30 @@ public class ItemModifyModule implements MapModule { private static final ItemTag APPLIED = ItemTag.newBoolean("custom-meta-applied"); + private final MaterialMatcher matcher; private final List rules; public ItemModifyModule(List rules) { this.rules = rules; + var builder = MaterialMatcher.builder(); + rules.forEach(r -> builder.add(r.items)); + this.matcher = builder.build(); } public boolean applyRules(ItemStack stack) { - if (stack == null || stack.getType() == Material.AIR || APPLIED.has(stack)) { + if (stack == null + || stack.getType() == Material.AIR + || !matcher.matches(stack) + || APPLIED.has(stack)) { return false; - } else { - APPLIED.set(stack, true); - for (ItemRule rule : rules) { - if (rule.matches(stack)) { - rule.apply(stack); - } + } + APPLIED.set(stack, true); + for (ItemRule rule : rules) { + if (rule.matches(stack)) { + rule.apply(stack); } - return true; } + return true; } @Override @@ -52,15 +59,23 @@ public static class Factory implements MapModuleFactory { throws InvalidXMLException { List rules = new ArrayList<>(); for (Element elRule : XMLUtils.flattenElements(doc.getRootElement(), "item-mods", "rule")) { - MaterialMatcher items = - XMLUtils.parseMaterialMatcher(XMLUtils.getRequiredUniqueChild(elRule, "match")); + var match = XMLUtils.getRequiredUniqueChild(elRule, "match"); + ItemMatcher itemMatcher; + MaterialMatcher materialMatcher; + if (match.getChild("matcher") != null) { + itemMatcher = factory.getKits().parseItemMatcher(match, "matcher"); + materialMatcher = itemMatcher.getMaterialMatcher(); + } else { + itemMatcher = null; + materialMatcher = XMLUtils.parseMaterialMatcher(match); + } // Always use a PotionMeta so the rule can have potion effects, though it will only apply // those to potion items PotionMeta meta = (PotionMeta) Bukkit.getItemFactory().getItemMeta(Material.POTION); factory.getKits().parseItemMeta(XMLUtils.getRequiredUniqueChild(elRule, "modify"), meta); - ItemRule rule = new ItemRule(items, meta); + ItemRule rule = new ItemRule(materialMatcher, itemMatcher, meta); rules.add(rule); } diff --git a/core/src/main/java/tc/oc/pgm/itemmeta/ItemRule.java b/core/src/main/java/tc/oc/pgm/itemmeta/ItemRule.java index 616f408c0d..1166d1e5e3 100644 --- a/core/src/main/java/tc/oc/pgm/itemmeta/ItemRule.java +++ b/core/src/main/java/tc/oc/pgm/itemmeta/ItemRule.java @@ -10,20 +10,24 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.PotionMeta; +import org.jetbrains.annotations.Nullable; import tc.oc.pgm.util.inventory.InventoryUtils; +import tc.oc.pgm.util.inventory.ItemMatcher; import tc.oc.pgm.util.material.MaterialMatcher; public class ItemRule { final MaterialMatcher items; + final @Nullable ItemMatcher matcher; final PotionMeta meta; - public ItemRule(MaterialMatcher items, PotionMeta meta) { + public ItemRule(MaterialMatcher items, @Nullable ItemMatcher matcher, PotionMeta meta) { this.items = items; + this.matcher = matcher; this.meta = meta; } public boolean matches(ItemStack stack) { - return items.matches(stack); + return items.matches(stack) && (matcher == null || matcher.matches(stack)); } public void apply(ItemStack stack) { @@ -40,7 +44,7 @@ public void apply(ItemStack stack) { } Set flags = this.meta.getItemFlags(); - meta.addItemFlags(flags.toArray(new ItemFlag[flags.size()])); + meta.addItemFlags(flags.toArray(new ItemFlag[0])); InventoryUtils.addEnchantments(meta, this.meta.getEnchants()); diff --git a/util/src/main/java/tc/oc/pgm/util/inventory/ItemMatcher.java b/util/src/main/java/tc/oc/pgm/util/inventory/ItemMatcher.java index fec4951ce0..aa5374612d 100644 --- a/util/src/main/java/tc/oc/pgm/util/inventory/ItemMatcher.java +++ b/util/src/main/java/tc/oc/pgm/util/inventory/ItemMatcher.java @@ -3,6 +3,7 @@ import com.google.common.collect.Range; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; +import tc.oc.pgm.util.material.MaterialMatcher; import tc.oc.pgm.util.material.Materials; public class ItemMatcher { @@ -33,6 +34,10 @@ public ItemMatcher( this.base = stripMeta(base); } + public MaterialMatcher getMaterialMatcher() { + return MaterialMatcher.builder().add(base, ignoreDurability).build(); + } + private ItemStack stripMeta(final ItemStack item) { // No modification needed if (!item.hasItemMeta() || (!ignoreMetadata && !ignoreName && !ignoreEnchantments)) return item; diff --git a/util/src/main/java/tc/oc/pgm/util/material/MaterialMatcher.java b/util/src/main/java/tc/oc/pgm/util/material/MaterialMatcher.java index 571b128aea..bf758d6ebc 100644 --- a/util/src/main/java/tc/oc/pgm/util/material/MaterialMatcher.java +++ b/util/src/main/java/tc/oc/pgm/util/material/MaterialMatcher.java @@ -64,10 +64,6 @@ static MaterialMatcher of(Predicate materials) { return builder().addAll(materials).build(); } - static MaterialMatcher ofMatchers(Collection matchers) { - return CompoundMaterialMatcher.of(matchers); - } - static MaterialMatcher parse(Element el) throws InvalidXMLException { return MaterialMatcher.builder().parse(new Node(el)).build(); } @@ -239,7 +235,7 @@ public MaterialMatcher build() { List materialMatchers = new ArrayList<>(materials.size() + matchers.size()); if (!materials.isEmpty()) materialMatchers.add(MaterialMatcher.of(materials)); if (!matchers.isEmpty()) materialMatchers.addAll(matchers); - return MaterialMatcher.ofMatchers(materialMatchers); + return CompoundMaterialMatcher.of(materialMatchers); } } }