Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 26 additions & 11 deletions core/src/main/java/tc/oc/pgm/itemmeta/ItemModifyModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,38 @@
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;
import tc.oc.pgm.util.xml.XMLUtils;

public class ItemModifyModule implements MapModule<ItemModifyMatchModule> {
private static final ItemTag<Boolean> APPLIED = ItemTag.newBoolean("custom-meta-applied");
private final MaterialMatcher matcher;
private final List<ItemRule> rules;

public ItemModifyModule(List<ItemRule> 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
Expand All @@ -52,15 +59,23 @@ public static class Factory implements MapModuleFactory<ItemModifyModule> {
throws InvalidXMLException {
List<ItemRule> 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);
}

Expand Down
10 changes: 7 additions & 3 deletions core/src/main/java/tc/oc/pgm/itemmeta/ItemRule.java
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -40,7 +44,7 @@ public void apply(ItemStack stack) {
}

Set<ItemFlag> 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());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,6 @@ static MaterialMatcher of(Predicate<Material> materials) {
return builder().addAll(materials).build();
}

static MaterialMatcher ofMatchers(Collection<? extends MaterialMatcher> matchers) {
return CompoundMaterialMatcher.of(matchers);
}

static MaterialMatcher parse(Element el) throws InvalidXMLException {
return MaterialMatcher.builder().parse(new Node(el)).build();
}
Expand Down Expand Up @@ -239,7 +235,7 @@ public MaterialMatcher build() {
List<MaterialMatcher> 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);
}
}
}