From c3156977b0720f8e31ffbb9c0c4b8cedac8b1312 Mon Sep 17 00:00:00 2001 From: Pablete1234 Date: Sun, 25 Sep 2022 12:23:45 +0200 Subject: [PATCH 1/3] Add item replace action Signed-off-by: Pablete1234 --- .../java/tc/oc/pgm/action/ActionParser.java | 14 +++++++ .../pgm/action/actions/ReplaceItemAction.java | 38 +++++++++++++++++++ .../main/java/tc/oc/pgm/kits/KitParser.java | 9 ++++- 3 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 core/src/main/java/tc/oc/pgm/action/actions/ReplaceItemAction.java diff --git a/core/src/main/java/tc/oc/pgm/action/ActionParser.java b/core/src/main/java/tc/oc/pgm/action/ActionParser.java index f62837b9ab..e1e270a078 100644 --- a/core/src/main/java/tc/oc/pgm/action/ActionParser.java +++ b/core/src/main/java/tc/oc/pgm/action/ActionParser.java @@ -3,11 +3,13 @@ import com.google.common.collect.ImmutableList; import java.lang.reflect.Method; import java.util.Map; +import org.bukkit.inventory.ItemStack; import org.jdom2.Element; import org.jetbrains.annotations.Nullable; import tc.oc.pgm.action.actions.ActionNode; import tc.oc.pgm.action.actions.ChatMessageAction; import tc.oc.pgm.action.actions.KillEntitiesAction; +import tc.oc.pgm.action.actions.ReplaceItemAction; import tc.oc.pgm.action.actions.ScopeSwitchAction; import tc.oc.pgm.action.actions.SetVariableAction; import tc.oc.pgm.api.feature.FeatureValidation; @@ -22,6 +24,7 @@ import tc.oc.pgm.kits.Kit; import tc.oc.pgm.util.MethodParser; import tc.oc.pgm.util.MethodParsers; +import tc.oc.pgm.util.inventory.ItemMatcher; import tc.oc.pgm.util.math.Formula; import tc.oc.pgm.util.xml.InvalidXMLException; import tc.oc.pgm.util.xml.Node; @@ -211,4 +214,15 @@ public KillEntitiesAction parseKillEntities(Element el, Class scope) throws InvalidXMLException { return new KillEntitiesAction(factory.getFilters().parseFilterProperty(el, "filter")); } + + @MethodParser("replace-item") + public ReplaceItemAction parseReplaceItem(Element el, Class scope) throws InvalidXMLException { + ItemMatcher matcher = factory.getKits().parseItemMatcher(el, "find"); + ItemStack item = factory.getKits().parseItem(el.getChild("replace"), true); + + boolean keepAmount = XMLUtils.parseBoolean(el.getAttribute("keep-amount"), false); + boolean keepEnchants = XMLUtils.parseBoolean(el.getAttribute("keep-enchants"), false); + + return new ReplaceItemAction(matcher, item, keepAmount, keepEnchants); + } } diff --git a/core/src/main/java/tc/oc/pgm/action/actions/ReplaceItemAction.java b/core/src/main/java/tc/oc/pgm/action/actions/ReplaceItemAction.java new file mode 100644 index 0000000000..f87d5e82c4 --- /dev/null +++ b/core/src/main/java/tc/oc/pgm/action/actions/ReplaceItemAction.java @@ -0,0 +1,38 @@ +package tc.oc.pgm.action.actions; + +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import tc.oc.pgm.api.player.MatchPlayer; +import tc.oc.pgm.util.inventory.ItemMatcher; + +public class ReplaceItemAction extends AbstractAction { + + private final ItemMatcher matcher; + private final ItemStack item; + private final boolean keepAmount; + private final boolean keepEnchants; + + public ReplaceItemAction( + ItemMatcher matcher, ItemStack item, boolean keepAmount, boolean keepEnchants) { + super(MatchPlayer.class); + this.matcher = matcher; + this.item = item; + this.keepAmount = keepAmount; + this.keepEnchants = keepEnchants; + } + + @Override + public void trigger(MatchPlayer matchPlayer) { + Inventory inv = matchPlayer.getInventory(); + for (int i = 0; i < inv.getSize(); i++) { + ItemStack current = inv.getItem(i); + if (current == null || !matcher.matches(current)) continue; + + ItemStack newItem = item.clone(); + if (keepAmount) newItem.setAmount(current.getAmount()); + if (keepEnchants) newItem.addEnchantments(current.getEnchantments()); + + inv.setItem(i, newItem); + } + } +} diff --git a/core/src/main/java/tc/oc/pgm/kits/KitParser.java b/core/src/main/java/tc/oc/pgm/kits/KitParser.java index 01b60638fa..9d7eb84677 100644 --- a/core/src/main/java/tc/oc/pgm/kits/KitParser.java +++ b/core/src/main/java/tc/oc/pgm/kits/KitParser.java @@ -400,8 +400,13 @@ public ItemStack parseHead(Element el) throws InvalidXMLException { } public ItemMatcher parseItemMatcher(Element parent) throws InvalidXMLException { - ItemStack stack = parseItem(parent.getChild("item"), false); - if (stack == null) throw new InvalidXMLException("Item expected", parent); + return parseItemMatcher(parent, "item"); + } + + public ItemMatcher parseItemMatcher(Element parent, String childName) throws InvalidXMLException { + ItemStack stack = parseItem(parent.getChild(childName), false); + if (stack == null) + throw new InvalidXMLException("Child " + childName + " element expected", parent); Range amount = XMLUtils.parseNumericRange(Node.fromAttr(parent, "amount"), Integer.class, null); From b6d8732eaca6565fb5b6f4f122c449b98a186f2f Mon Sep 17 00:00:00 2001 From: applenick Date: Wed, 28 Sep 2022 11:33:44 -0700 Subject: [PATCH 2/3] Check armor slots when replacing item Signed-off-by: applenick --- .../pgm/action/actions/ReplaceItemAction.java | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/tc/oc/pgm/action/actions/ReplaceItemAction.java b/core/src/main/java/tc/oc/pgm/action/actions/ReplaceItemAction.java index f87d5e82c4..e93d6eae1d 100644 --- a/core/src/main/java/tc/oc/pgm/action/actions/ReplaceItemAction.java +++ b/core/src/main/java/tc/oc/pgm/action/actions/ReplaceItemAction.java @@ -1,7 +1,7 @@ package tc.oc.pgm.action.actions; -import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; import tc.oc.pgm.api.player.MatchPlayer; import tc.oc.pgm.util.inventory.ItemMatcher; @@ -23,16 +23,29 @@ public ReplaceItemAction( @Override public void trigger(MatchPlayer matchPlayer) { - Inventory inv = matchPlayer.getInventory(); + PlayerInventory inv = matchPlayer.getInventory(); + + ItemStack[] armor = inv.getArmorContents(); + for (int i = 0; i < armor.length; i++) { + ItemStack current = armor[i]; + if (current == null || !matcher.matches(current)) continue; + armor[i] = replaceItem(current); + } + inv.setArmorContents(armor); + for (int i = 0; i < inv.getSize(); i++) { ItemStack current = inv.getItem(i); if (current == null || !matcher.matches(current)) continue; - ItemStack newItem = item.clone(); - if (keepAmount) newItem.setAmount(current.getAmount()); - if (keepEnchants) newItem.addEnchantments(current.getEnchantments()); - + ItemStack newItem = replaceItem(current); inv.setItem(i, newItem); } } + + private ItemStack replaceItem(ItemStack current) { + ItemStack newItem = item.clone(); + if (keepAmount) newItem.setAmount(current.getAmount()); + if (keepEnchants) newItem.addEnchantments(current.getEnchantments()); + return newItem; + } } From ab7dc32948a6a219b8a0c6fa896aa3b3266f8699 Mon Sep 17 00:00:00 2001 From: Pablete1234 Date: Sun, 2 Oct 2022 13:52:21 +0200 Subject: [PATCH 3/3] Add wider support for team colors Signed-off-by: Pablete1234 --- .../pgm/action/actions/ReplaceItemAction.java | 14 +++--- .../pgm/controlpoint/ControlPointParser.java | 9 ++-- .../tc/oc/pgm/filters/operator/AllFilter.java | 4 +- .../tc/oc/pgm/filters/operator/AnyFilter.java | 4 +- .../tc/oc/pgm/filters/operator/OneFilter.java | 4 +- .../pgm/killreward/KillRewardMatchModule.java | 2 + .../main/java/tc/oc/pgm/kits/ArmorKit.java | 13 ++--- .../src/main/java/tc/oc/pgm/kits/ItemKit.java | 6 +++ .../main/java/tc/oc/pgm/kits/KitParser.java | 9 ++-- .../java/tc/oc/pgm/kits/tag/ItemModifier.java | 47 +++++++++++++++++++ .../java/tc/oc/pgm/shops/menu/ShopMenu.java | 2 + 11 files changed, 81 insertions(+), 33 deletions(-) create mode 100644 core/src/main/java/tc/oc/pgm/kits/tag/ItemModifier.java diff --git a/core/src/main/java/tc/oc/pgm/action/actions/ReplaceItemAction.java b/core/src/main/java/tc/oc/pgm/action/actions/ReplaceItemAction.java index e93d6eae1d..309b0c53a8 100644 --- a/core/src/main/java/tc/oc/pgm/action/actions/ReplaceItemAction.java +++ b/core/src/main/java/tc/oc/pgm/action/actions/ReplaceItemAction.java @@ -3,6 +3,7 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; import tc.oc.pgm.api.player.MatchPlayer; +import tc.oc.pgm.kits.tag.ItemModifier; import tc.oc.pgm.util.inventory.ItemMatcher; public class ReplaceItemAction extends AbstractAction { @@ -22,30 +23,29 @@ public ReplaceItemAction( } @Override - public void trigger(MatchPlayer matchPlayer) { - PlayerInventory inv = matchPlayer.getInventory(); + public void trigger(MatchPlayer player) { + PlayerInventory inv = player.getInventory(); ItemStack[] armor = inv.getArmorContents(); for (int i = 0; i < armor.length; i++) { ItemStack current = armor[i]; if (current == null || !matcher.matches(current)) continue; - armor[i] = replaceItem(current); + armor[i] = replaceItem(current, player); } inv.setArmorContents(armor); for (int i = 0; i < inv.getSize(); i++) { ItemStack current = inv.getItem(i); if (current == null || !matcher.matches(current)) continue; - - ItemStack newItem = replaceItem(current); - inv.setItem(i, newItem); + inv.setItem(i, replaceItem(current, player)); } } - private ItemStack replaceItem(ItemStack current) { + private ItemStack replaceItem(ItemStack current, MatchPlayer player) { ItemStack newItem = item.clone(); if (keepAmount) newItem.setAmount(current.getAmount()); if (keepEnchants) newItem.addEnchantments(current.getEnchantments()); + ItemModifier.apply(newItem, player); return newItem; } } diff --git a/core/src/main/java/tc/oc/pgm/controlpoint/ControlPointParser.java b/core/src/main/java/tc/oc/pgm/controlpoint/ControlPointParser.java index 654c28e013..6081736a95 100644 --- a/core/src/main/java/tc/oc/pgm/controlpoint/ControlPointParser.java +++ b/core/src/main/java/tc/oc/pgm/controlpoint/ControlPointParser.java @@ -3,7 +3,7 @@ import java.time.Duration; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; -import org.bukkit.Material; +import java.util.stream.Collectors; import org.bukkit.util.BlockVector; import org.bukkit.util.Vector; import org.jdom2.Attribute; @@ -16,6 +16,7 @@ import tc.oc.pgm.filters.operator.AnyFilter; import tc.oc.pgm.filters.parse.FilterParser; import tc.oc.pgm.goals.ShowOptions; +import tc.oc.pgm.kits.tag.ItemModifier; import tc.oc.pgm.payload.PayloadDefinition; import tc.oc.pgm.regions.BlockBoundedValidation; import tc.oc.pgm.regions.EverywhereRegion; @@ -30,11 +31,7 @@ public abstract class ControlPointParser { private static final Filter VISUAL_MATERIALS = AnyFilter.of( - new BlockFilter(Material.WOOL), - new BlockFilter(Material.CARPET), - new BlockFilter(Material.STAINED_CLAY), - new BlockFilter(Material.STAINED_GLASS), - new BlockFilter(Material.STAINED_GLASS_PANE)); + ItemModifier.COLOR_AFFECTED.stream().map(BlockFilter::new).collect(Collectors.toList())); public enum Type { HILL, diff --git a/core/src/main/java/tc/oc/pgm/filters/operator/AllFilter.java b/core/src/main/java/tc/oc/pgm/filters/operator/AllFilter.java index cb795be566..d7be9e4102 100644 --- a/core/src/main/java/tc/oc/pgm/filters/operator/AllFilter.java +++ b/core/src/main/java/tc/oc/pgm/filters/operator/AllFilter.java @@ -1,6 +1,6 @@ package tc.oc.pgm.filters.operator; -import java.util.List; +import java.util.Collection; import tc.oc.pgm.api.filter.Filter; import tc.oc.pgm.api.filter.query.Query; @@ -29,7 +29,7 @@ public static Filter of(Filter... filters) { return MultiFilterFunction.of(AllFilter::new, filters); } - public static Filter of(List filters) { + public static Filter of(Collection filters) { return MultiFilterFunction.of(AllFilter::new, filters); } } diff --git a/core/src/main/java/tc/oc/pgm/filters/operator/AnyFilter.java b/core/src/main/java/tc/oc/pgm/filters/operator/AnyFilter.java index 0049969cd5..7921569b3c 100644 --- a/core/src/main/java/tc/oc/pgm/filters/operator/AnyFilter.java +++ b/core/src/main/java/tc/oc/pgm/filters/operator/AnyFilter.java @@ -1,6 +1,6 @@ package tc.oc.pgm.filters.operator; -import java.util.List; +import java.util.Collection; import tc.oc.pgm.api.filter.Filter; import tc.oc.pgm.api.filter.query.Query; @@ -29,7 +29,7 @@ public static Filter of(Filter... filters) { return MultiFilterFunction.of(AnyFilter::new, filters); } - public static Filter of(List filters) { + public static Filter of(Collection filters) { return MultiFilterFunction.of(AnyFilter::new, filters); } } diff --git a/core/src/main/java/tc/oc/pgm/filters/operator/OneFilter.java b/core/src/main/java/tc/oc/pgm/filters/operator/OneFilter.java index 7be195f379..ef48ce83ba 100644 --- a/core/src/main/java/tc/oc/pgm/filters/operator/OneFilter.java +++ b/core/src/main/java/tc/oc/pgm/filters/operator/OneFilter.java @@ -1,6 +1,6 @@ package tc.oc.pgm.filters.operator; -import java.util.List; +import java.util.Collection; import tc.oc.pgm.api.filter.Filter; import tc.oc.pgm.api.filter.query.Query; @@ -32,7 +32,7 @@ public static Filter of(Filter... filters) { return MultiFilterFunction.of(OneFilter::new, filters); } - public static Filter of(List filters) { + public static Filter of(Collection filters) { return MultiFilterFunction.of(OneFilter::new, filters); } } diff --git a/core/src/main/java/tc/oc/pgm/killreward/KillRewardMatchModule.java b/core/src/main/java/tc/oc/pgm/killreward/KillRewardMatchModule.java index 9a98817ed9..7e60c596bf 100644 --- a/core/src/main/java/tc/oc/pgm/killreward/KillRewardMatchModule.java +++ b/core/src/main/java/tc/oc/pgm/killreward/KillRewardMatchModule.java @@ -27,6 +27,7 @@ import tc.oc.pgm.events.ListenerScope; import tc.oc.pgm.events.PlayerPartyChangeEvent; import tc.oc.pgm.filters.query.DamageQuery; +import tc.oc.pgm.kits.tag.ItemModifier; import tc.oc.pgm.util.collection.DefaultMapAdapter; import tc.oc.pgm.util.event.ItemTransferEvent; import tc.oc.pgm.util.event.PlayerItemTransferEvent; @@ -75,6 +76,7 @@ private void giveRewards(MatchPlayer killer, Collection rewards) { for (ItemStack stack : items) { ItemStack clone = stack.clone(); + ItemModifier.apply(clone, killer); PlayerItemTransferEvent event = new PlayerItemTransferEvent( null, diff --git a/core/src/main/java/tc/oc/pgm/kits/ArmorKit.java b/core/src/main/java/tc/oc/pgm/kits/ArmorKit.java index 971b93a7a9..e5f545d164 100644 --- a/core/src/main/java/tc/oc/pgm/kits/ArmorKit.java +++ b/core/src/main/java/tc/oc/pgm/kits/ArmorKit.java @@ -4,19 +4,17 @@ import java.util.Map; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.LeatherArmorMeta; import tc.oc.pgm.api.player.MatchPlayer; +import tc.oc.pgm.kits.tag.ItemModifier; public class ArmorKit extends AbstractKit { public static class ArmorItem { public final ItemStack stack; public final boolean locked; - public final boolean teamColor; - public ArmorItem(ItemStack stack, boolean locked, boolean teamColor) { + public ArmorItem(ItemStack stack, boolean locked) { this.stack = stack; this.locked = locked; - this.teamColor = teamColor; } } @@ -41,12 +39,7 @@ public void applyPostEvent(MatchPlayer player, boolean force, List di int slot = entry.getKey().ordinal(); if (force || wearing[slot] == null || wearing[slot].getType() == Material.AIR) { wearing[slot] = entry.getValue().stack.clone(); - - if (entry.getValue().teamColor) { - LeatherArmorMeta meta = (LeatherArmorMeta) wearing[slot].getItemMeta(); - meta.setColor(player.getParty().getFullColor()); - wearing[slot].setItemMeta(meta); - } + ItemModifier.apply(wearing[slot], player); KitMatchModule kitMatchModule = player.getMatch().getModule(KitMatchModule.class); if (kitMatchModule != null) { diff --git a/core/src/main/java/tc/oc/pgm/kits/ItemKit.java b/core/src/main/java/tc/oc/pgm/kits/ItemKit.java index 3daf154a95..7883a21fd5 100644 --- a/core/src/main/java/tc/oc/pgm/kits/ItemKit.java +++ b/core/src/main/java/tc/oc/pgm/kits/ItemKit.java @@ -10,6 +10,7 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; import tc.oc.pgm.api.player.MatchPlayer; +import tc.oc.pgm.kits.tag.ItemModifier; import tc.oc.pgm.util.inventory.InventoryUtils; public class ItemKit implements KitDefinition { @@ -70,6 +71,11 @@ public void apply(MatchPlayer player, boolean force, List displacedIt final HumanEntity holder = player.getBukkit(); final PlayerInventory inv = player.getBukkit().getInventory(); + // Apply all item modifications (eg: team-colors) + for (ItemStack item : event.getItems()) { + ItemModifier.apply(item, player); + } + if (force) { for (Entry kitEntry : event.getSlotItems().entrySet()) { kitEntry.getKey().putItem(holder, kitEntry.getValue().clone()); diff --git a/core/src/main/java/tc/oc/pgm/kits/KitParser.java b/core/src/main/java/tc/oc/pgm/kits/KitParser.java index 9d7eb84677..9e564d4cd9 100644 --- a/core/src/main/java/tc/oc/pgm/kits/KitParser.java +++ b/core/src/main/java/tc/oc/pgm/kits/KitParser.java @@ -43,6 +43,7 @@ import tc.oc.pgm.doublejump.DoubleJumpKit; import tc.oc.pgm.filters.matcher.StaticFilter; import tc.oc.pgm.kits.tag.Grenade; +import tc.oc.pgm.kits.tag.ItemModifier; import tc.oc.pgm.kits.tag.ItemTags; import tc.oc.pgm.projectile.ProjectileDefinition; import tc.oc.pgm.shield.ShieldKit; @@ -219,10 +220,7 @@ private ArmorKit.ArmorItem parseArmorItem(Element el) throws InvalidXMLException ItemStack stack = parseItem(el, true); boolean locked = XMLUtils.parseBoolean(el.getAttribute("locked"), false); - boolean teamColor = - stack.getItemMeta() instanceof LeatherArmorMeta - && XMLUtils.parseBoolean(el.getAttribute("team-color"), false); - return new ArmorKit.ArmorItem(stack, locked, teamColor); + return new ArmorKit.ArmorItem(stack, locked); } public ArmorKit parseArmorKit(Element el) throws InvalidXMLException { @@ -571,6 +569,9 @@ String itemFlagName(ItemFlag flag) { } public void parseCustomNBT(Element el, ItemStack itemStack) throws InvalidXMLException { + if (XMLUtils.parseBoolean(el.getAttribute("team-color"), false)) + ItemModifier.TEAM_COLOR.set(itemStack, true); + if (XMLUtils.parseBoolean(el.getAttribute("grenade"), false)) { Grenade.ITEM_TAG.set( itemStack, diff --git a/core/src/main/java/tc/oc/pgm/kits/tag/ItemModifier.java b/core/src/main/java/tc/oc/pgm/kits/tag/ItemModifier.java new file mode 100644 index 0000000000..2465840809 --- /dev/null +++ b/core/src/main/java/tc/oc/pgm/kits/tag/ItemModifier.java @@ -0,0 +1,47 @@ +package tc.oc.pgm.kits.tag; + +import com.google.common.collect.ImmutableSet; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.LeatherArmorMeta; +import tc.oc.pgm.api.player.MatchPlayer; +import tc.oc.pgm.util.bukkit.BukkitUtils; +import tc.oc.pgm.util.inventory.tag.ItemTag; + +public class ItemModifier { + + public static final ItemTag TEAM_COLOR = ItemTag.newBoolean("team-color"); + + public static final ImmutableSet COLOR_AFFECTED = + ImmutableSet.of( + Material.WOOL, + Material.CARPET, + Material.STAINED_CLAY, + Material.STAINED_GLASS, + Material.STAINED_GLASS_PANE); + + // Apply per-player customizations of items. + // This may be expanded on the future but currently only handles coloring armor & blocks. + // The method is explicitly mutate-only, if you don't want side effects pass a clone. + public static void apply(ItemStack item, MatchPlayer player) { + if (!TEAM_COLOR.has(item)) return; + TEAM_COLOR.clear(item); + + ItemMeta meta = item.getItemMeta(); + + if (meta instanceof LeatherArmorMeta) { + LeatherArmorMeta leather = (LeatherArmorMeta) meta; + leather.setColor(player.getParty().getFullColor()); + item.setItemMeta(meta); + } else if (COLOR_AFFECTED.contains(item.getType())) { + item.setDurability(getWoolColor(player.getParty().getColor())); + } + } + + @SuppressWarnings("deprecation") + private static byte getWoolColor(ChatColor color) { + return BukkitUtils.chatColorToDyeColor(color).getWoolData(); + } +} diff --git a/core/src/main/java/tc/oc/pgm/shops/menu/ShopMenu.java b/core/src/main/java/tc/oc/pgm/shops/menu/ShopMenu.java index d195e04be5..c42fb5f62a 100644 --- a/core/src/main/java/tc/oc/pgm/shops/menu/ShopMenu.java +++ b/core/src/main/java/tc/oc/pgm/shops/menu/ShopMenu.java @@ -24,6 +24,7 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import tc.oc.pgm.api.player.MatchPlayer; +import tc.oc.pgm.kits.tag.ItemModifier; import tc.oc.pgm.menu.InventoryMenu; import tc.oc.pgm.shops.Shop; import tc.oc.pgm.util.inventory.ItemBuilder; @@ -221,6 +222,7 @@ private ClickableItem getPurchasableItem(Icon icon) { String clickLore = TextTranslations.translateLegacy(click, getBukkit()); ItemStack item = icon.getItem().clone(); + ItemModifier.apply(item, getViewer()); ItemMeta meta = item.getItemMeta(); List lore = Lists.newArrayList(); if (meta.getLore() != null) {