115 lines
4.4 KiB
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);
|
|
}
|
|
}
|
|
}
|