ProjectAres/PGM/src/main/java/tc/oc/pgm/itemmeta/ItemModifyModule.java

115 lines
4.4 KiB
Java

package tc.oc.pgm.itemmeta;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import javax.annotation.Nullable;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.attribute.ItemAttributeModifier;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.PotionMeta;
import org.jdom2.Document;
import org.jdom2.Element;
import tc.oc.commons.bukkit.item.BooleanItemTag;
import tc.oc.pgm.kits.ItemParser;
import tc.oc.pgm.map.MapModule;
import tc.oc.pgm.map.MapModuleContext;
import tc.oc.pgm.map.MapModuleFactory;
import tc.oc.pgm.match.Match;
import tc.oc.pgm.match.MatchModuleFactory;
import tc.oc.pgm.module.ModuleDescription;
import tc.oc.pgm.utils.MaterialMatcher;
import tc.oc.pgm.utils.XMLUtils;
import tc.oc.pgm.xml.InvalidXMLException;
@ModuleDescription(name = "Item Modify")
public class ItemModifyModule implements MapModule, MatchModuleFactory<ItemModifyMatchModule> {
private static final BooleanItemTag APPLIED = new BooleanItemTag("custom-meta-applied", false);
private final List<ItemRule> rules;
public ItemModifyModule(List<ItemRule> rules) {
this.rules = rules;
}
public boolean shouldApply(ItemStack stack) {
return stack != null &&
stack.getType() != Material.AIR &&
!APPLIED.get(stack);
}
public ItemStack applyToCopy(ItemStack stack) {
if(shouldApply(stack)) {
final boolean immutable = stack.isImmutable();
stack = stack.clone();
applyRules(stack);
if(immutable) {
stack = stack.immutableCopy();
}
}
return stack;
}
public boolean applyRules(ItemStack stack) {
if(!shouldApply(stack)) {
return false;
} else {
boolean defaultAttributes = false;
boolean attributesModified = false;
for(ItemRule rule : rules) {
if(rule.matches(stack)) {
rule.apply(stack);
APPLIED.set(stack, true);
attributesModified |= rule.meta.hasAttributeModifiers();
defaultAttributes |= rule.defaultAttributes;
}
}
// If any rule had the defaultAttributes flag, and any custom attributes were added,
// add the default attributes now. We do this here so it only happens once.
if(defaultAttributes && attributesModified) {
final ItemMeta meta = stack.getItemMeta();
for(Map.Entry<String, List<ItemAttributeModifier>> entry : Bukkit.getItemFactory().getAttributeModifiers(stack.getData()).entrySet()) {
for(ItemAttributeModifier mod : entry.getValue()) {
meta.addAttributeModifier(entry.getKey(), mod);
}
}
stack.setItemMeta(meta);
}
return true;
}
}
@Override
public ItemModifyMatchModule createMatchModule(Match match) {
return new ItemModifyMatchModule(match);
}
public static class Factory extends MapModuleFactory<ItemModifyModule> {
@Override
public @Nullable ItemModifyModule parse(MapModuleContext context, Logger logger, Document doc) 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"));
// Always use a PotionMeta so the rule can have potion effects, though it will only apply those to potion items
final Element elModify = XMLUtils.getRequiredUniqueChild(elRule, "modify");
final PotionMeta meta = (PotionMeta) Bukkit.getItemFactory().getItemMeta(Material.POTION);
context.needModule(ItemParser.class).parseItemMeta(elModify, meta);
final boolean defaultAttributes = XMLUtils.parseBoolean(elModify.getAttribute("default-attributes"), false);
ItemRule rule = new ItemRule(items, meta, defaultAttributes);
rules.add(rule);
}
return rules.isEmpty() ? null : new ItemModifyModule(rules);
}
}
}