diff --git a/src/main/java/ch/njol/skript/conditions/CondItemEnchantmentGlint.java b/src/main/java/ch/njol/skript/conditions/CondItemEnchantmentGlint.java new file mode 100644 index 00000000000..96c6e26de69 --- /dev/null +++ b/src/main/java/ch/njol/skript/conditions/CondItemEnchantmentGlint.java @@ -0,0 +1,83 @@ +package ch.njol.skript.conditions; + +import org.bukkit.event.Event; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.Nullable; + +import ch.njol.skript.Skript; +import ch.njol.skript.aliases.ItemType; +import ch.njol.skript.doc.Description; +import ch.njol.skript.doc.Examples; +import ch.njol.skript.doc.Name; +import ch.njol.skript.doc.RequiredPlugins; +import ch.njol.skript.doc.Since; +import ch.njol.skript.lang.Condition; +import ch.njol.skript.lang.Expression; +import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.util.Kleenean; + +@Name("Item Has Enchantment Glint Override") +@Description("Checks whether an item has the enchantment glint overridden, or is forced to glint or not.") +@Examples({ + "if the player's tool has the enchantment glint override", + "\tsend \"Your tool has the enchantment glint override.\" to player", + "", + "if {_item} is forced to glint:", + "\tsend \"This item is forced to glint.\" to player", + "else if {_item} is forced to not glint:", + "\tsend \"This item is forced to not glint.\" to player", + "else:", + "\tsend \"This item does not have any glint override.\" to player" +}) +@RequiredPlugins("Spigot 1.20.5+") +@Since("INSERT VERSION") +public class CondItemEnchantmentGlint extends Condition { + + static { + if (Skript.isRunningMinecraft(1, 20, 5)) + Skript.registerCondition(CondItemEnchantmentGlint.class, + "%itemtypes% (has|have) [the] enchantment glint overrid(den|e)", + "%itemtypes% (doesn't|does not|do not|don't) have [the] enchantment glint overrid(den|e)", + "%itemtypes% (is|are) forced (to [:not]|[:not] to) glint"); + } + + private Expression itemtypes; + private int pattern; + + @Override + @SuppressWarnings("unchecked") + public boolean init(Expression[] expressions, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + itemtypes = (Expression) expressions[0]; + pattern = matchedPattern; + if (matchedPattern == 2) { + // Pattern 'is forced to glint' + setNegated(parseResult.hasTag("not")); + } else { + // Pattern 'has enchantment glint override' + setNegated(matchedPattern == 1); + } + return true; + } + + @Override + public boolean check(Event event) { + return itemtypes.check(event, itemType -> { + ItemMeta meta = itemType.getItemMeta(); + // Pattern 'is forced to glint' + if (pattern == 2) { + if (!meta.hasEnchantmentGlintOverride()) + return isNegated(); + return meta.getEnchantmentGlintOverride(); + // Pattern 'has enchantment glint override' + } else { + return meta.hasEnchantmentGlintOverride(); + } + }, isNegated()); + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + return null; + } + +} diff --git a/src/main/java/ch/njol/skript/effects/EffForceEnchantmentGlint.java b/src/main/java/ch/njol/skript/effects/EffForceEnchantmentGlint.java new file mode 100644 index 00000000000..62fcb30300c --- /dev/null +++ b/src/main/java/ch/njol/skript/effects/EffForceEnchantmentGlint.java @@ -0,0 +1,77 @@ +package ch.njol.skript.effects; + +import ch.njol.skript.Skript; +import ch.njol.skript.aliases.ItemType; +import ch.njol.skript.doc.Description; +import ch.njol.skript.doc.Examples; +import ch.njol.skript.doc.Name; +import ch.njol.skript.doc.RequiredPlugins; +import ch.njol.skript.doc.Since; +import ch.njol.skript.lang.Effect; +import ch.njol.skript.lang.Expression; +import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.util.Kleenean; +import org.bukkit.event.Event; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.Nullable; + +@Name("Force Enchantment Glint") +@Description("Forces the items to glint or not, or removes its existing enchantment glint enforcement.") +@Examples({ + "force {_items::*} to glint", + "force the player's tool to stop glinting" +}) +@RequiredPlugins("Spigot 1.20.5+") +@Since("INSERT VERSION") +public class EffForceEnchantmentGlint extends Effect { + + static { + if (Skript.methodExists(ItemMeta.class, "setEnchantmentGlintOverride", Boolean.class)) + Skript.registerEffect(EffForceEnchantmentGlint.class, + "(force|make) %itemtypes% [to] [start] glint[ing]", + "(force|make) %itemtypes% [to] (not|stop) glint[ing]", + "(clear|delete) [the] enchantment glint override of %itemtypes%", + "(clear|delete) %itemtypes%'s enchantment glint override"); + } + + @SuppressWarnings("NotNullFieldNotInitialized") + private Expression itemtypes; + private int pattern; + + @Override + @SuppressWarnings("unchecked") + public boolean init(Expression[] expressions, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + itemtypes = (Expression) expressions[0]; + pattern = matchedPattern; + return true; + } + + @Override + protected void execute(Event event) { + for (ItemType itemType : itemtypes.getArray(event)) { + ItemMeta meta = itemType.getItemMeta(); + Boolean glint; + if (pattern == 0) { + // Pattern: forced to glint + glint = true; + } else if (pattern == 1) { + // Pattern: forced to not glint + glint = false; + } else { + // Pattern: Clear glint override + glint = null; + } + meta.setEnchantmentGlintOverride(glint); + itemType.setItemMeta(meta); + } + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + // Pattern: Clear glint override + if (pattern > 1) + return "clear the enchantment glint override of " + itemtypes.toString(event, debug); + return "force the " + itemtypes.toString(event, debug) + " to " + (pattern == 0 ? "start" : "stop") + " glinting"; + } + +} diff --git a/src/main/java/ch/njol/skript/expressions/ExprEnchantmentGlint.java b/src/main/java/ch/njol/skript/expressions/ExprEnchantmentGlint.java new file mode 100644 index 00000000000..c7a46bc892a --- /dev/null +++ b/src/main/java/ch/njol/skript/expressions/ExprEnchantmentGlint.java @@ -0,0 +1,94 @@ +package ch.njol.skript.expressions; + +import org.bukkit.event.Event; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.Nullable; + +import ch.njol.skript.Skript; +import ch.njol.skript.aliases.ItemType; +import ch.njol.skript.classes.Changer.ChangeMode; +import ch.njol.skript.doc.Description; +import ch.njol.skript.doc.Examples; +import ch.njol.skript.doc.Name; +import ch.njol.skript.doc.RequiredPlugins; +import ch.njol.skript.doc.Since; +import ch.njol.skript.expressions.base.SimplePropertyExpression; +import ch.njol.util.coll.CollectionUtils; + +@Name("Enchantment Glint") +@Description({ + "Sets the 'enchantment_glint_override' on items.", + "If true, the item will glint, even without enchantments.", + "if false, the item will not glint, even with enchantments.", + "If cleared, the glint enforcement will be cleared." +}) +@Examples({ + "set the enchantment glint of player's tool to true", + "set the enchantment glint of {_items::*} to false", + "clear the enchantment glint of player's tool" +}) +@RequiredPlugins("Spigot 1.20.5+") +@Since("INSERT VERSION") +public class ExprEnchantmentGlint extends SimplePropertyExpression { + + static { + if (Skript.isRunningMinecraft(1, 20, 5)) + register(ExprEnchantmentGlint.class, Boolean.class, "enchantment glint", "itemtypes"); + } + + @Override + @Nullable + public Boolean convert(ItemType item) { + ItemMeta meta = item.getItemMeta(); + if (!meta.hasEnchantmentGlintOverride()) + return null; + // Spigot claims this does not return null, hence we return null ourselves + return meta.getEnchantmentGlintOverride(); + } + + @Override + @Nullable + public Class[] acceptChange(ChangeMode mode) { + switch (mode) { + case SET: + case DELETE: + case RESET: + return CollectionUtils.array(Boolean.class); + default: + return null; + } + } + + @Override + public void change(Event event, @Nullable Object[] delta, ChangeMode mode) { + switch (mode) { + case SET: + if (!(delta[0] instanceof Boolean)) + return; + for (ItemType itemType : getExpr().getArray(event)) { + ItemMeta meta = itemType.getItemMeta(); + meta.setEnchantmentGlintOverride((Boolean) delta[0]); + itemType.setItemMeta(meta); + } + break; + case DELETE: + case RESET: + for (ItemType itemType : getExpr().getArray(event)) { + ItemMeta meta = itemType.getItemMeta(); + meta.setEnchantmentGlintOverride(null); + itemType.setItemMeta(meta); + } + } + } + + @Override + public Class getReturnType() { + return Boolean.class; + } + + @Override + protected String getPropertyName() { + return "enchantment glint"; + } + +} diff --git a/src/main/java/ch/njol/skript/expressions/ExprItemWithEnchantmentGlint.java b/src/main/java/ch/njol/skript/expressions/ExprItemWithEnchantmentGlint.java new file mode 100644 index 00000000000..cf412ffad71 --- /dev/null +++ b/src/main/java/ch/njol/skript/expressions/ExprItemWithEnchantmentGlint.java @@ -0,0 +1,66 @@ +package ch.njol.skript.expressions; + +import org.bukkit.event.Event; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.Nullable; + +import ch.njol.skript.Skript; +import ch.njol.skript.aliases.ItemType; +import ch.njol.skript.doc.Description; +import ch.njol.skript.doc.Examples; +import ch.njol.skript.doc.Name; +import ch.njol.skript.doc.RequiredPlugins; +import ch.njol.skript.doc.Since; +import ch.njol.skript.expressions.base.PropertyExpression; +import ch.njol.skript.lang.Expression; +import ch.njol.skript.lang.ExpressionType; +import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.util.Kleenean; + +@Name("Item with Enchantment Glint") +@Description("Get an item with or without enchantment glint.") +@Examples({ + "set {_item with glint} to diamond with enchantment glint", + "set {_item without glint} to diamond without enchantment glint" +}) +@RequiredPlugins("Spigot 1.20.5+") +@Since("INSERT VERSION") +public class ExprItemWithEnchantmentGlint extends PropertyExpression { + + static { + if (Skript.methodExists(ItemMeta.class, "getEnchantmentGlintOverride")) + Skript.registerExpression(ExprItemWithEnchantmentGlint.class, ItemType.class, ExpressionType.PROPERTY, "%itemtypes% with[:out] [enchant[ment]] glint"); + } + + private boolean glint; + + @Override + @SuppressWarnings("unchecked") + public boolean init(Expression[] expressions, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + setExpr((Expression) expressions[0]); + glint = !parseResult.hasTag("out"); + return true; + } + + @Override + protected ItemType[] get(Event event, ItemType[] source) { + return get(source, itemType -> { + itemType = itemType.clone(); + ItemMeta meta = itemType.getItemMeta(); + meta.setEnchantmentGlintOverride(glint); + itemType.setItemMeta(meta); + return itemType; + }); + } + + @Override + public Class getReturnType() { + return ItemType.class; + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + return getExpr().toString(event, debug) + (glint ? " with" : " without") + " enchantment glint"; + } + +} diff --git a/src/test/skript/tests/syntaxes/expressions/ExprItemWithEnchantmentGlint.sk b/src/test/skript/tests/syntaxes/expressions/ExprItemWithEnchantmentGlint.sk new file mode 100644 index 00000000000..975535e9bcd --- /dev/null +++ b/src/test/skript/tests/syntaxes/expressions/ExprItemWithEnchantmentGlint.sk @@ -0,0 +1,43 @@ +test "item with enchantment glint" when running minecraft "1.20.5": + + # with enchantment glint + loop 2 times: + if loop-number = 1: + set {_item} to diamond with enchantment glint + else: + set {_item} to diamond + make {_item} glint + assert {_item} is forced to glint with "Item is expected to be forced to glint" + assert {_item} has enchantment glint override with "Item is expected to have enchantment glint override set ##1" + assert {_item} does not have enchantment glint override to fail with "Item is expected to have enchantment glint override set ##2" + delete {_item} + + # without enchantment glint + loop 2 times: + if loop-number = 1: + set {_item} to diamond without enchantment glint + else: + set {_item} to diamond + make {_item} to not glint + assert {_item} is forced to not glint with "Item is expected to be forced to not glint" + assert {_item} has enchantment glint override with "Item is expected to have enchantment glint override set ##3" + assert {_item} does not have enchantment glint override to fail with "Item is expected to have enchantment glint override set ##4" + + # clear enchantment glint override + clear enchantment glint override of {_item} + assert {_item} is forced to glint to fail with "Item is expected to not have enchantment override set ##1" + assert {_item} is forced to not glint to fail with "Item is expected to not have enchantment override set ##2" + assert {_item} has enchantment glint override to fail with "Item is expected to not have enchantment override set ##3" + assert {_item} does not have enchantment glint override with "Item is expected to have enchantment glint override set ##4" + + # edge cases + assert {_null} is forced to glint to fail with "Condition 'item is forced to glint' expected to fail with non itemtypes ##1" + assert {_null} has enchantment glint override to fail with "Condition 'item has enchantment glint override' expected to fail with non itemtypes ##1" + + assert diamond with enchantment glint and stone with enchantment glint is forced to glint with "Both items expected to be forced to glint ##1" + assert diamond without enchantment glint and stone without enchantment glint is forced to not glint with "Both items expected to be forced to glint ##2" + assert diamond with enchantment glint and stone without enchantment glint have enchantment glint override with "Both items expected to have enchantment glint override set" + + # Skript's long term negation related issue + # assert {_null} is forced to not glint to fail with "Condition 'item is forced to glint' expected to fail with non itemtypes ##2" + # assert {_null} does not have enchantment glint override to fail with "Condition 'item has enchantment glint override' expected to fail with non itemtypes ##2"