diff --git a/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java b/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java
index 0e7cb76279a..988d179a882 100644
--- a/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java
+++ b/src/main/java/ch/njol/skript/classes/data/BukkitClasses.java
@@ -24,8 +24,6 @@
import org.bukkit.block.banner.PatternType;
import org.bukkit.block.data.BlockData;
import org.bukkit.command.CommandSender;
-import org.bukkit.enchantments.Enchantment;
-import org.bukkit.enchantments.EnchantmentOffer;
import org.bukkit.entity.*;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
@@ -424,17 +422,6 @@ public boolean mustSyncDeserialization() {
}
}));
- Classes.registerClass(new RegistryClassInfo<>(Enchantment.class, Registry.ENCHANTMENT, "enchantment", "enchantments")
- .user("enchantments?")
- .name("Enchantment")
- .description("An enchantment, e.g. 'sharpness' or 'fortune'. Unlike enchantment type " +
- "this type has no level, but you usually don't need to use this type anyway.",
- "NOTE: Minecraft namespaces are supported, ex: 'minecraft:basalt_deltas'.",
- "As of Minecraft 1.21 this will also support custom enchantments using namespaces, ex: 'myenchants:explosive'.")
- .examples("")
- .since("1.4.6")
- .before("enchantmenttype"));
-
Material[] allMaterials = Material.values();
Classes.registerClass(new ClassInfo<>(Material.class, "material")
.name(ClassInfo.NO_DOC)
@@ -615,31 +602,6 @@ public String[] getPatterns() {
ExpressionPropertyHandler.of(GameRule::getName, String.class)
));
- Classes.registerClass(new ClassInfo<>(EnchantmentOffer.class, "enchantmentoffer")
- .user("enchant[ment][ ]offers?")
- .name("Enchantment Offer")
- .description("The enchantmentoffer in an enchant prepare event.")
- .examples("on enchant prepare:",
- "\tset enchant offer 1 to sharpness 1",
- "\tset the cost of enchant offer 1 to 10 levels")
- .since("2.5")
- .parser(new Parser<>() {
- @Override
- public boolean canParse(ParseContext context) {
- return false;
- }
-
- @Override
- public String toString(EnchantmentOffer eo, int flags) {
- return Classes.toString(eo.getEnchantment()) + " " + eo.getEnchantmentLevel();
- }
-
- @Override
- public String toVariableNameString(EnchantmentOffer eo) {
- return "offer:" + Classes.toString(eo.getEnchantment()) + "=" + eo.getEnchantmentLevel();
- }
- }));
-
Classes.registerClass(new RegistryClassInfo<>(Attribute.class, Registry.ATTRIBUTE, "attributetype", "attribute types")
.user("attribute ?types?")
.name("Attribute Type")
diff --git a/src/main/java/ch/njol/skript/classes/data/DefaultComparators.java b/src/main/java/ch/njol/skript/classes/data/DefaultComparators.java
index 1fa65336b20..9dee9a86b63 100644
--- a/src/main/java/ch/njol/skript/classes/data/DefaultComparators.java
+++ b/src/main/java/ch/njol/skript/classes/data/DefaultComparators.java
@@ -545,35 +545,6 @@ public boolean supportsOrdering() {
}
});
- // EnchantmentOffer Comparators
- // EnchantmentOffer - EnchantmentType
- Comparators.registerComparator(EnchantmentOffer.class, EnchantmentType.class, new Comparator() {
- @Override
- public Relation compare(EnchantmentOffer eo, EnchantmentType et) {
- return Relation.get(eo.getEnchantment() == et.getType() && eo.getEnchantmentLevel() == et.getLevel());
- }
-
- @Override
- public boolean supportsOrdering() {
- return false;
- }
- });
- // EnchantmentOffer - Experience
- Comparators.registerComparator(EnchantmentOffer.class, Experience.class, new Comparator() {
- @Override
- public Relation compare(EnchantmentOffer eo, Experience exp) {
- return Relation.get(eo.getCost() == exp.getXP());
- }
-
- @Override public boolean supportsOrdering() {
- return false;
- }
- });
-
- //EnchantmentType - Enchantment
- Comparators.registerComparator(EnchantmentType.class, Enchantment.class, ((enchantmentType, enchantment) ->
- Relation.get(enchantmentType.getType().equals(enchantment))));
-
Comparators.registerComparator(Inventory.class, InventoryType.class, new Comparator() {
@Override
public Relation compare(Inventory inventory, InventoryType inventoryType) {
diff --git a/src/main/java/ch/njol/skript/classes/data/DefaultConverters.java b/src/main/java/ch/njol/skript/classes/data/DefaultConverters.java
index d27fbf7fd6e..577ab1b52b9 100644
--- a/src/main/java/ch/njol/skript/classes/data/DefaultConverters.java
+++ b/src/main/java/ch/njol/skript/classes/data/DefaultConverters.java
@@ -21,8 +21,6 @@
import org.bukkit.block.DoubleChest;
import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.CommandSender;
-import org.bukkit.enchantments.Enchantment;
-import org.bukkit.enchantments.EnchantmentOffer;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntitySnapshot;
import org.bukkit.entity.LivingEntity;
@@ -304,15 +302,9 @@ public void setAmount(Number amount) {
return null;
});
- // Enchantment - EnchantmentType
- Converters.registerConverter(Enchantment.class, EnchantmentType.class, e -> new EnchantmentType(e, -1));
-
// Vector - Direction
Converters.registerConverter(Vector.class, Direction.class, Direction::new);
- // EnchantmentOffer - EnchantmentType
- Converters.registerConverter(EnchantmentOffer.class, EnchantmentType.class, eo -> new EnchantmentType(eo.getEnchantment(), eo.getEnchantmentLevel()));
-
Converters.registerConverter(String.class, World.class, Bukkit::getWorld);
if (Skript.classExists("org.bukkit.entity.EntitySnapshot"))
diff --git a/src/main/java/ch/njol/skript/classes/data/SkriptClasses.java b/src/main/java/ch/njol/skript/classes/data/SkriptClasses.java
index 4fd2d2de791..a5e5f69c269 100644
--- a/src/main/java/ch/njol/skript/classes/data/SkriptClasses.java
+++ b/src/main/java/ch/njol/skript/classes/data/SkriptClasses.java
@@ -382,33 +382,6 @@ public String toVariableNameString(Color color) {
"grow a huge red mushroom above the block")
.since("1.0"));
- Classes.registerClass(new ClassInfo<>(EnchantmentType.class, "enchantmenttype")
- .user("enchant(ing|ment) types?")
- .name("Enchantment Type")
- .description("An enchantment with an optional level, e.g. 'sharpness 2' or 'fortune'.")
- .usage(" []")
- .examples("enchant the player's tool with sharpness 5",
- "helmet is enchanted with waterbreathing")
- .since("1.4.6")
- .parser(new Parser() {
- @Override
- @Nullable
- public EnchantmentType parse(final String s, final ParseContext context) {
- return EnchantmentType.parse(s);
- }
-
- @Override
- public String toString(final EnchantmentType t, final int flags) {
- return t.toString();
- }
-
- @Override
- public String toVariableNameString(final EnchantmentType o) {
- return o.toString();
- }
- })
- .serializer(new YggdrasilSerializer<>()));
-
Classes.registerClass(new ClassInfo<>(Experience.class, "experience")
.user("experience ?(points?)?")
.name("Experience")
diff --git a/src/main/java/ch/njol/skript/expressions/ExprEnchantItem.java b/src/main/java/ch/njol/skript/expressions/ExprEnchantItem.java
deleted file mode 100644
index b76aeccad44..00000000000
--- a/src/main/java/ch/njol/skript/expressions/ExprEnchantItem.java
+++ /dev/null
@@ -1,116 +0,0 @@
-package ch.njol.skript.expressions;
-
-import ch.njol.skript.lang.EventRestrictedSyntax;
-import org.bukkit.event.Event;
-import org.bukkit.event.enchantment.EnchantItemEvent;
-import org.bukkit.event.enchantment.PrepareItemEnchantEvent;
-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.Events;
-import ch.njol.skript.doc.Example;
-import ch.njol.skript.doc.Name;
-import ch.njol.skript.doc.Since;
-import ch.njol.skript.lang.Expression;
-import ch.njol.skript.lang.ExpressionType;
-import ch.njol.skript.lang.SkriptParser.ParseResult;
-import ch.njol.skript.lang.util.SimpleExpression;
-import ch.njol.skript.log.ErrorQuality;
-import ch.njol.util.Kleenean;
-import ch.njol.util.coll.CollectionUtils;
-
-@Name("Enchant Item")
-@Description({"The enchant item in an enchant prepare event or enchant event.",
- "It can be modified, but enchantments will still be applied in the enchant event."})
-@Example("""
- on enchant:
- set the enchanted item to a diamond chestplate
- """)
-@Example("""
- on enchant prepare:
- set the enchant item to a wooden sword
- """)
-@Events({"enchant prepare", "enchant"})
-@Since("2.5")
-public class ExprEnchantItem extends SimpleExpression implements EventRestrictedSyntax {
-
- static {
- Skript.registerExpression(ExprEnchantItem.class, ItemType.class, ExpressionType.SIMPLE, "[the] enchant[ed] item");
- }
-
- @Override
- public boolean init(Expression>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
- return true;
- }
-
- @Override
- public Class extends Event>[] supportedEvents() {
- return CollectionUtils.array(EnchantItemEvent.class, PrepareItemEnchantEvent.class);
- }
-
- @Override
- @Nullable
- protected ItemType[] get(Event e) {
- if (e instanceof PrepareItemEnchantEvent)
- return new ItemType[]{new ItemType(((PrepareItemEnchantEvent) e).getItem())};
- else if (e instanceof EnchantItemEvent)
- return new ItemType[]{new ItemType(((EnchantItemEvent) e).getItem())};
- else
- return null;
- }
-
- @Override
- @Nullable
- public Class>[] acceptChange(ChangeMode mode) {
- if (mode == ChangeMode.SET)
- return CollectionUtils.array(ItemType.class);
- return null;
- }
-
- @Override
- public void change(Event event, @Nullable Object[] delta, ChangeMode mode) {
- if (delta == null)
- return;
- ItemType item = ((ItemType) delta[0]);
- switch (mode) {
- case SET:
- if (event instanceof PrepareItemEnchantEvent) {
- PrepareItemEnchantEvent e = (PrepareItemEnchantEvent) event;
- e.getItem().setType(item.getMaterial());
- e.getItem().setItemMeta(item.getItemMeta());
- e.getItem().setAmount(item.getAmount());
- } else if (event instanceof EnchantItemEvent) {
- EnchantItemEvent e = (EnchantItemEvent) event;
- e.getItem().setType(item.getMaterial());
- e.getItem().setItemMeta(item.getItemMeta());
- e.getItem().setAmount(item.getAmount());
- }
- break;
- case ADD:
- case REMOVE:
- case RESET:
- case DELETE:
- case REMOVE_ALL:
- assert false;
- }
- }
-
- @Override
- public boolean isSingle() {
- return true;
- }
-
- @Override
- public Class extends ItemType> getReturnType() {
- return ItemType.class;
- }
-
- @Override
- public String toString(@Nullable Event e, boolean debug) {
- return "enchanted item";
- }
-
-}
diff --git a/src/main/java/ch/njol/skript/expressions/ExprEnchantingExpCost.java b/src/main/java/ch/njol/skript/expressions/ExprEnchantingExpCost.java
deleted file mode 100644
index 97d0d4f2f0e..00000000000
--- a/src/main/java/ch/njol/skript/expressions/ExprEnchantingExpCost.java
+++ /dev/null
@@ -1,105 +0,0 @@
-package ch.njol.skript.expressions;
-
-import ch.njol.skript.lang.EventRestrictedSyntax;
-import org.bukkit.event.Event;
-import org.bukkit.event.enchantment.EnchantItemEvent;
-import org.jetbrains.annotations.Nullable;
-
-import ch.njol.skript.Skript;
-import ch.njol.skript.classes.Changer.ChangeMode;
-import ch.njol.skript.doc.Description;
-import ch.njol.skript.doc.Events;
-import ch.njol.skript.doc.Example;
-import ch.njol.skript.doc.Name;
-import ch.njol.skript.doc.Since;
-import ch.njol.skript.lang.Expression;
-import ch.njol.skript.lang.ExpressionType;
-import ch.njol.skript.lang.SkriptParser.ParseResult;
-import ch.njol.skript.lang.util.SimpleExpression;
-import ch.njol.skript.log.ErrorQuality;
-import ch.njol.skript.util.Experience;
-import ch.njol.util.Kleenean;
-import ch.njol.util.coll.CollectionUtils;
-
-@Name("Enchanting Experience Cost")
-@Description({"The cost of enchanting in an enchant event.",
- "This is number that was displayed in the enchantment table, not the actual number of levels removed."})
-@Example("""
- on enchant:
- send "Cost: %the displayed enchanting cost%" to player
- """)
-@Events("enchant")
-@Since("2.5")
-public class ExprEnchantingExpCost extends SimpleExpression implements EventRestrictedSyntax {
-
- static {
- Skript.registerExpression(ExprEnchantingExpCost.class, Long.class, ExpressionType.SIMPLE,
- "[the] [displayed] ([e]xp[erience]|enchanting) cost");
- }
-
- @Override
- public boolean init(Expression>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
- return true;
- }
-
- @Override
- public Class extends Event>[] supportedEvents() {
- return CollectionUtils.array(EnchantItemEvent.class);
- }
-
- @Override
- @Nullable
- protected Long[] get(Event e) {
- return new Long[]{(long) ((EnchantItemEvent) e).getExpLevelCost()};
- }
-
- @Override
- @Nullable
- public Class>[] acceptChange(ChangeMode mode) {
- if (mode == ChangeMode.RESET || mode == ChangeMode.DELETE || mode == ChangeMode.REMOVE_ALL)
- return null;
- return CollectionUtils.array(Number.class, Experience.class);
- }
-
- @Override
- public void change(Event event, @Nullable Object[] delta, ChangeMode mode) {
- if (delta == null)
- return;
- Object c = delta[0];
- int cost = c instanceof Number ? ((Number) c).intValue() : ((Experience) c).getXP();
- EnchantItemEvent e = (EnchantItemEvent) event;
- switch (mode) {
- case SET:
- e.setExpLevelCost(cost);
- break;
- case ADD:
- int add = e.getExpLevelCost() + cost;
- e.setExpLevelCost(add);
- break;
- case REMOVE:
- int subtract = e.getExpLevelCost() - cost;
- e.setExpLevelCost(subtract);
- break;
- case RESET:
- case DELETE:
- case REMOVE_ALL:
- assert false;
- }
- }
-
- @Override
- public boolean isSingle() {
- return true;
- }
-
- @Override
- public Class extends Long> getReturnType() {
- return Long.class;
- }
-
- @Override
- public String toString(@Nullable Event e, boolean debug) {
- return "the displayed cost of enchanting";
- }
-
-}
diff --git a/src/main/java/org/skriptlang/skript/bukkit/BukkitModule.java b/src/main/java/org/skriptlang/skript/bukkit/BukkitModule.java
index b1e42eadc10..470df36b3bc 100644
--- a/src/main/java/org/skriptlang/skript/bukkit/BukkitModule.java
+++ b/src/main/java/org/skriptlang/skript/bukkit/BukkitModule.java
@@ -9,6 +9,7 @@
import org.skriptlang.skript.bukkit.breeding.BreedingModule;
import org.skriptlang.skript.bukkit.brewing.BrewingModule;
import org.skriptlang.skript.bukkit.damagesource.DamageSourceModule;
+import org.skriptlang.skript.bukkit.enchantments.EnchantmentModule;
import org.skriptlang.skript.bukkit.entity.EntityModule;
import org.skriptlang.skript.bukkit.fishing.FishingModule;
import org.skriptlang.skript.bukkit.input.InputModule;
@@ -50,7 +51,8 @@ public Iterable children() {
new PDCModule(this),
new PotionModule(this),
new TagModule(this),
- new TextModule(this)
+ new TextModule(this),
+ new EnchantmentModule(this)
);
}
diff --git a/src/main/java/org/skriptlang/skript/bukkit/enchantments/EnchantmentModule.java b/src/main/java/org/skriptlang/skript/bukkit/enchantments/EnchantmentModule.java
new file mode 100644
index 00000000000..86a3abe6b81
--- /dev/null
+++ b/src/main/java/org/skriptlang/skript/bukkit/enchantments/EnchantmentModule.java
@@ -0,0 +1,150 @@
+package org.skriptlang.skript.bukkit.enchantments;
+
+import ch.njol.skript.classes.ClassInfo;
+import ch.njol.skript.classes.Parser;
+import ch.njol.skript.classes.YggdrasilSerializer;
+import ch.njol.skript.classes.registry.RegistryClassInfo;
+import ch.njol.skript.lang.ParseContext;
+import ch.njol.skript.registrations.Classes;
+import ch.njol.skript.util.EnchantmentType;
+import ch.njol.skript.util.Experience;
+import io.papermc.paper.registry.RegistryAccess;
+import io.papermc.paper.registry.RegistryKey;
+import org.bukkit.enchantments.Enchantment;
+import org.bukkit.enchantments.EnchantmentOffer;
+import org.jetbrains.annotations.Nullable;
+import org.skriptlang.skript.addon.AddonModule;
+import org.skriptlang.skript.addon.HierarchicalAddonModule;
+import org.skriptlang.skript.addon.SkriptAddon;
+import org.skriptlang.skript.bukkit.enchantments.elements.conditions.CondIsEnchanted;
+import org.skriptlang.skript.bukkit.enchantments.elements.conditions.CondItemEnchantmentGlint;
+import org.skriptlang.skript.bukkit.enchantments.elements.effects.EffEnchant;
+import org.skriptlang.skript.bukkit.enchantments.elements.effects.EffForceEnchantmentGlint;
+import org.skriptlang.skript.bukkit.enchantments.elements.expressions.*;
+import org.skriptlang.skript.lang.comparator.Comparators;
+import org.skriptlang.skript.lang.comparator.Relation;
+import org.skriptlang.skript.lang.converter.Converters;
+
+public class EnchantmentModule extends HierarchicalAddonModule {
+
+ public EnchantmentModule(AddonModule parentModule) {
+ super(parentModule);
+ }
+
+ @Override
+ protected void initSelf(SkriptAddon addon) {
+ initClasses();
+ initComparators();
+ initConverters();
+ }
+
+ private void initClasses() {
+ Classes.registerClass(new RegistryClassInfo<>(
+ Enchantment.class, RegistryAccess.registryAccess().getRegistry(RegistryKey.ENCHANTMENT),
+ "enchantment", "enchantments")
+ .user("enchantments?")
+ .name("Enchantment")
+ .description("An enchantment, e.g. 'sharpness' or 'fortune'. Unlike enchantment type " +
+ "this type has no level, but you usually don't need to use this type anyway.",
+ "NOTE: Minecraft namespaces are supported, ex: 'minecraft:basalt_deltas'.",
+ "This also supports custom enchantments using namespaces, ex: 'myenchants:explosive'.")
+ .examples("")
+ .since("1.4.6")
+ .before("enchantmenttype"));
+
+ Classes.registerClass(new ClassInfo<>(EnchantmentType.class, "enchantmenttype")
+ .user("enchant(ing|ment) ?types?")
+ .name("Enchantment Type")
+ .description("An enchantment with an optional level, e.g. 'sharpness 2' or 'fortune'.")
+ .usage(" []")
+ .examples("enchant the player's tool with sharpness 5",
+ "helmet is enchanted with waterbreathing")
+ .since("1.4.6")
+ .parser(new Parser<>() {
+ @Override
+ public @Nullable EnchantmentType parse(String string, ParseContext context) {
+ return EnchantmentType.parse(string);
+ }
+
+ @Override
+ public String toString(EnchantmentType type, int flags) {
+ return type.toString();
+ }
+
+ @Override
+ public String toVariableNameString(EnchantmentType type) {
+ return type.toString();
+ }
+ })
+ .serializer(new YggdrasilSerializer<>()));
+
+ Classes.registerClass(new ClassInfo<>(EnchantmentOffer.class, "enchantmentoffer")
+ .user("enchant[ment][ ]offers?")
+ .name("Enchantment Offer")
+ .description("The enchantmentoffer in an enchant prepare event.")
+ .examples("""
+ on enchant prepare:
+ set enchant offer 1 to sharpness 1
+ set the cost of enchant offer 1 to 10 levels
+ """)
+ .since("2.5")
+ .parser(new Parser<>() {
+ @Override
+ public boolean canParse(ParseContext context) {
+ return false;
+ }
+
+ @Override
+ public String toString(EnchantmentOffer eo, int flags) {
+ return Classes.toString(eo.getEnchantment()) + " " + eo.getEnchantmentLevel();
+ }
+
+ @Override
+ public String toVariableNameString(EnchantmentOffer eo) {
+ return "offer:" + Classes.toString(eo.getEnchantment()) + "=" + eo.getEnchantmentLevel();
+ }
+ }));
+ }
+
+ private void initComparators() {
+ Comparators.registerComparator(EnchantmentOffer.class, EnchantmentType.class, (offer, enchantmentType) ->
+ Relation.get(offer.getEnchantment() == enchantmentType.getType() && offer.getEnchantmentLevel() == enchantmentType.getLevel()));
+ Comparators.registerComparator(EnchantmentOffer.class, Experience.class, (offer, experience) ->
+ Relation.get(offer.getCost() == experience.getXP()));
+ Comparators.registerComparator(EnchantmentType.class, Enchantment.class, ((enchantmentType, enchantment) ->
+ Relation.get(enchantmentType.getType().equals(enchantment))));
+ }
+
+ private void initConverters() {
+ Converters.registerConverter(Enchantment.class, EnchantmentType.class, e -> new EnchantmentType(e, -1));
+ Converters.registerConverter(EnchantmentOffer.class, EnchantmentType.class, eo -> new EnchantmentType(eo.getEnchantment(), eo.getEnchantmentLevel()));
+ }
+
+ @Override
+ protected void loadSelf(SkriptAddon addon) {
+ register(addon,
+ CondIsEnchanted::register,
+ CondItemEnchantmentGlint::register,
+ EffEnchant::register,
+ EffForceEnchantmentGlint::register,
+ ExprAppliedEnchantments::register,
+ ExprEnchantmentLevel::register,
+ ExprEnchantmentOffer::register,
+ ExprEnchantmentBonus::register,
+ ExprEnchantmentOfferCost::register,
+ ExprEnchantments::register,
+ ExprEnchantingExpCost::register,
+ ExprEnchantItem::register,
+ ExprItemWithEnchantmentGlint::register,
+ ExprMaximumEnchantmentLevel::register,
+ ExprMinimumEnchantmentLevel::register,
+ ExprStoredEnchantments::register
+ );
+ }
+
+ @Override
+ public String name() {
+ return "enchantment";
+ }
+
+}
diff --git a/src/main/java/ch/njol/skript/conditions/CondIsEnchanted.java b/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/conditions/CondIsEnchanted.java
similarity index 85%
rename from src/main/java/ch/njol/skript/conditions/CondIsEnchanted.java
rename to src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/conditions/CondIsEnchanted.java
index bc3fad378c1..8ccd96e4abd 100644
--- a/src/main/java/ch/njol/skript/conditions/CondIsEnchanted.java
+++ b/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/conditions/CondIsEnchanted.java
@@ -1,4 +1,4 @@
-package ch.njol.skript.conditions;
+package org.skriptlang.skript.bukkit.enchantments.elements.conditions;
import ch.njol.skript.aliases.ItemType;
import ch.njol.skript.conditions.base.PropertyCondition;
@@ -14,6 +14,7 @@
import ch.njol.util.Kleenean;
import org.bukkit.event.Event;
import org.jetbrains.annotations.Nullable;
+import org.skriptlang.skript.registration.SyntaxRegistry;
@Name("Is Enchanted")
@Description("Checks whether an item is enchanted. Enchants must match the exact level by default, unless 'or better' or 'or worse' are used.")
@@ -39,8 +40,10 @@ public String toSkriptString() {
}
}
- static {
- PropertyCondition.register(CondIsEnchanted.class, "enchanted [with %-enchantmenttypes% [or (1:(better|greater|higher|above)|2:(worse|lesser|lower|below))]]", "itemtypes");
+ public static void register(SyntaxRegistry registry) {
+ registry.register(SyntaxRegistry.CONDITION, PropertyCondition.infoBuilder(CondIsEnchanted.class, PropertyType.BE,
+ "enchanted [with %-enchantmenttypes% [or (1:(better|greater|higher|above)" +
+ "|2:(worse|lesser|lower|below))]]", "itemtypes").build());
}
private Expression items;
diff --git a/src/main/java/ch/njol/skript/conditions/CondItemEnchantmentGlint.java b/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/conditions/CondItemEnchantmentGlint.java
similarity index 55%
rename from src/main/java/ch/njol/skript/conditions/CondItemEnchantmentGlint.java
rename to src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/conditions/CondItemEnchantmentGlint.java
index aa93247cf8c..41cff18e34b 100644
--- a/src/main/java/ch/njol/skript/conditions/CondItemEnchantmentGlint.java
+++ b/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/conditions/CondItemEnchantmentGlint.java
@@ -1,14 +1,14 @@
-package ch.njol.skript.conditions;
+package org.skriptlang.skript.bukkit.enchantments.elements.conditions;
import org.bukkit.inventory.meta.ItemMeta;
-import ch.njol.skript.Skript;
import ch.njol.skript.aliases.ItemType;
import ch.njol.skript.conditions.base.PropertyCondition;
import ch.njol.skript.doc.*;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.util.Kleenean;
+import org.skriptlang.skript.registration.SyntaxRegistry;
@Name("Item Has Enchantment Glint Override")
@Description("Checks whether an item has the enchantment glint overridden, or is forced to glint or not.")
@@ -24,44 +24,48 @@
else:
send "This item does not have any glint override." to player
""")
-@RequiredPlugins("Spigot 1.20.5+")
@Since("2.10")
public class CondItemEnchantmentGlint extends PropertyCondition {
- static {
- if (Skript.methodExists(ItemMeta.class, "getEnchantmentGlintOverride")) {
- register(CondItemEnchantmentGlint.class, PropertyType.HAVE, "enchantment glint overrid(den|e)", "itemtypes");
- register(CondItemEnchantmentGlint.class, PropertyType.BE, "forced to [:not] glint", "itemtypes");
- }
+ public static void register(SyntaxRegistry registry) {
+ registry.register(SyntaxRegistry.CONDITION, PropertyCondition
+ .infoBuilder(CondItemEnchantmentGlint.class, PropertyType.HAVE, "enchantment glint (override:overrid(den|e))", "itemtypes")
+ .addPatterns(getPatterns(PropertyType.BE, "forced to [:not] glint", "itemtypes"))
+ .supplier(CondItemEnchantmentGlint::new).build());
}
- private int matchedPattern;
- private boolean glint;
+ private boolean expectedGlintOverride;
+ private boolean override;
@Override
public boolean init(Expression>[] expressions, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
- this.matchedPattern = matchedPattern;
- glint = !parseResult.hasTag("not");
- return super.init(expressions, matchedPattern, isDelayed, parseResult);
+ if (!super.init(expressions, matchedPattern, isDelayed, parseResult)) return false;
+ override = parseResult.hasTag("override");
+ expectedGlintOverride = !parseResult.hasTag("not");
+
+ // We override setNegated to correctly handle multiple patterns. Note that the [:not] parse tag is not negating.
+ setNegated(matchedPattern % 2 != 0);
+ return true;
}
@Override
public boolean check(ItemType itemType) {
ItemMeta meta = itemType.getItemMeta();
- // enchantment glint override
- if (matchedPattern == 0)
+
+ if (override)
return meta.hasEnchantmentGlintOverride();
- // forced to glint
+
if (!meta.hasEnchantmentGlintOverride())
return false;
- return meta.getEnchantmentGlintOverride();
+
+ return meta.getEnchantmentGlintOverride() == expectedGlintOverride;
}
@Override
protected String getPropertyName() {
- if (matchedPattern == 0)
+ if (override)
return "enchantment glint overridden";
- return "forced to " + (glint ? "" : "not ") + "glint";
+ return "forced to " + (expectedGlintOverride ? "" : "not ") + "glint";
}
}
diff --git a/src/main/java/ch/njol/skript/effects/EffEnchant.java b/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/effects/EffEnchant.java
similarity index 82%
rename from src/main/java/ch/njol/skript/effects/EffEnchant.java
rename to src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/effects/EffEnchant.java
index f9021d64605..164744fa6d2 100644
--- a/src/main/java/ch/njol/skript/effects/EffEnchant.java
+++ b/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/effects/EffEnchant.java
@@ -1,4 +1,4 @@
-package ch.njol.skript.effects;
+package org.skriptlang.skript.bukkit.enchantments.elements.effects;
import ch.njol.skript.Skript;
import ch.njol.skript.aliases.ItemType;
@@ -16,6 +16,8 @@
import org.bukkit.inventory.ItemFactory;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;
+import org.skriptlang.skript.registration.SyntaxInfo;
+import org.skriptlang.skript.registration.SyntaxRegistry;
import java.util.concurrent.ThreadLocalRandom;
import java.util.function.Function;
@@ -37,16 +39,17 @@ private enum Operation {
DISENCHANT
}
- private static final Patterns patterns;
+ private static final Patterns PATTERNS = new Patterns<>(new Object[][]{
+ {"enchant %~itemtypes% with %enchantmenttypes%", Operation.ENCHANT},
+ {"[naturally|randomly] enchant %~itemtypes% at level %number%[treasure:[,] allowing treasure enchant[ment]s]",
+ Operation.ENCHANT_AT_LEVEL},
+ {"disenchant %~itemtypes%", Operation.DISENCHANT}
+ });
- static {
- patterns = new Patterns<>(new Object[][]{
- {"enchant %~itemtypes% with %enchantmenttypes%", Operation.ENCHANT},
- {"[naturally|randomly] enchant %~itemtypes% at level %number%[treasure:[,] allowing treasure enchant[ment]s]",
- Operation.ENCHANT_AT_LEVEL},
- {"disenchant %~itemtypes%", Operation.DISENCHANT}
- });
- Skript.registerEffect(EffEnchant.class, patterns.getPatterns());
+ public static void register(SyntaxRegistry registry) {
+ registry.register(SyntaxRegistry.EFFECT, SyntaxInfo.builder(EffEnchant.class)
+ .addPatterns(PATTERNS.getPatterns())
+ .supplier(EffEnchant::new).build());
}
private Expression items;
@@ -69,7 +72,7 @@ public boolean init(Expression>[] exprs, int matchedPattern, Kleenean isDelaye
level = (Expression) exprs[1];
treasure = parseResult.hasTag("treasure");
}
- operation = patterns.getInfo(matchedPattern);
+ operation = PATTERNS.getInfo(matchedPattern);
return true;
}
diff --git a/src/main/java/ch/njol/skript/effects/EffForceEnchantmentGlint.java b/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/effects/EffForceEnchantmentGlint.java
similarity index 64%
rename from src/main/java/ch/njol/skript/effects/EffForceEnchantmentGlint.java
rename to src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/effects/EffForceEnchantmentGlint.java
index 956e4302344..e626b378086 100644
--- a/src/main/java/ch/njol/skript/effects/EffForceEnchantmentGlint.java
+++ b/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/effects/EffForceEnchantmentGlint.java
@@ -1,32 +1,33 @@
-package ch.njol.skript.effects;
+package org.skriptlang.skript.bukkit.enchantments.elements.effects;
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.*;
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.skriptlang.skript.registration.SyntaxInfo;
+import org.skriptlang.skript.registration.SyntaxRegistry;
@Name("Force Enchantment Glint")
@Description("Forces the items to glint or not, or removes its existing enchantment glint enforcement.")
@Example("force {_items::*} to glint")
@Example("force the player's tool to stop glinting")
-@RequiredPlugins("Spigot 1.20.5+")
@Since("2.10")
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|reset) [the] enchantment glint override of %itemtypes%",
- "(clear|delete|reset) %itemtypes%'s enchantment glint override");
+ public static void register(SyntaxRegistry registry) {
+ registry.register(SyntaxRegistry.EFFECT, SyntaxInfo.builder(EffForceEnchantmentGlint.class)
+ .addPatterns(
+ "(force|make) %itemtypes% [to] [start] glint[ing]",
+ "(force|make) %itemtypes% [to] (not|stop) glint[ing]",
+ "(clear|delete|reset) [the] enchantment glint override of %itemtypes%",
+ "(clear|delete|reset) %itemtypes%'s enchantment glint override"
+ ).supplier(EffForceEnchantmentGlint::new).build());
}
private Expression itemTypes;
@@ -44,17 +45,11 @@ public boolean init(Expression>[] expressions, int matchedPattern, Kleenean is
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;
- }
+ Boolean glint = switch (pattern) {
+ case 0 -> true; // Pattern: forced to glint
+ case 1 -> false; // Pattern: forced to not glint
+ default -> null; // Pattern: Clear glint override
+ };
meta.setEnchantmentGlintOverride(glint);
itemType.setItemMeta(meta);
}
diff --git a/src/main/java/ch/njol/skript/expressions/ExprAppliedEnchantments.java b/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprAppliedEnchantments.java
similarity index 53%
rename from src/main/java/ch/njol/skript/expressions/ExprAppliedEnchantments.java
rename to src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprAppliedEnchantments.java
index 85885ddcc9f..cf59cda5445 100644
--- a/src/main/java/ch/njol/skript/expressions/ExprAppliedEnchantments.java
+++ b/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprAppliedEnchantments.java
@@ -1,12 +1,10 @@
-package ch.njol.skript.expressions;
+package org.skriptlang.skript.bukkit.enchantments.elements.expressions;
import ch.njol.skript.lang.EventRestrictedSyntax;
-import org.bukkit.enchantments.Enchantment;
import org.bukkit.event.Event;
import org.bukkit.event.enchantment.EnchantItemEvent;
import org.jetbrains.annotations.Nullable;
-import ch.njol.skript.Skript;
import ch.njol.skript.classes.Changer.ChangeMode;
import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Events;
@@ -14,17 +12,20 @@
import ch.njol.skript.doc.Name;
import ch.njol.skript.doc.Since;
import ch.njol.skript.lang.Expression;
-import ch.njol.skript.lang.ExpressionType;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.lang.util.SimpleExpression;
-import ch.njol.skript.log.ErrorQuality;
import ch.njol.skript.util.EnchantmentType;
import ch.njol.util.Kleenean;
import ch.njol.util.coll.CollectionUtils;
+import org.skriptlang.skript.registration.SyntaxRegistry;
+
+import static org.skriptlang.skript.registration.DefaultSyntaxInfos.Expression.builder;
@Name("Applied Enchantments")
-@Description({"The applied enchantments in an enchant event.",
- " Deleting or removing the applied enchantments will prevent the item's enchantment."})
+@Description("""
+ The applied enchantments in an enchant event.
+ Deleting or removing the applied enchantments will prevent the item's enchantment.
+ """)
@Example("""
on enchant:
set the applied enchantments to sharpness 10 and fire aspect 5
@@ -33,8 +34,11 @@
@Since("2.5")
public class ExprAppliedEnchantments extends SimpleExpression implements EventRestrictedSyntax {
- static {
- Skript.registerExpression(ExprAppliedEnchantments.class, EnchantmentType.class, ExpressionType.SIMPLE, "[the] applied enchant[ment]s");
+ public static void register(SyntaxRegistry registry) {
+ registry.register(SyntaxRegistry.EXPRESSION,
+ builder(ExprAppliedEnchantments.class, EnchantmentType.class)
+ .addPattern("[the] applied enchant[ment]s")
+ .supplier(ExprAppliedEnchantments::new).build());
}
@Override
@@ -47,58 +51,54 @@ public Class extends Event>[] supportedEvents() {
return CollectionUtils.array(EnchantItemEvent.class);
}
- @SuppressWarnings("null")
@Override
- @Nullable
- protected EnchantmentType[] get(Event e) {
- if (!(e instanceof EnchantItemEvent))
+ @SuppressWarnings("null")
+ protected EnchantmentType @Nullable [] get(Event event) {
+ if (!(event instanceof EnchantItemEvent))
return null;
- return ((EnchantItemEvent) e).getEnchantsToAdd().entrySet().stream()
- .map(entry -> new EnchantmentType(entry.getKey(), entry.getValue()))
- .toArray(EnchantmentType[]::new);
+ return ((EnchantItemEvent) event).getEnchantsToAdd().entrySet().stream()
+ .map(entry -> new EnchantmentType(entry.getKey(), entry.getValue()))
+ .toArray(EnchantmentType[]::new);
}
@Override
- @Nullable
- public Class>[] acceptChange(ChangeMode mode) {
- if (mode == ChangeMode.REMOVE_ALL || mode == ChangeMode.RESET)
- return null;
- return CollectionUtils.array(Enchantment[].class, EnchantmentType[].class);
+ public Class> @Nullable [] acceptChange(ChangeMode mode) {
+ return switch (mode) {
+ case ADD, SET, DELETE, REMOVE -> CollectionUtils.array(EnchantmentType[].class);
+ default -> null;
+ };
}
@SuppressWarnings("null")
@Override
- public void change(Event event, @Nullable Object[] delta, ChangeMode mode) {
- if (!(event instanceof EnchantItemEvent))
+ public void change(Event event, Object @Nullable [] delta, ChangeMode mode) {
+ if (!(event instanceof EnchantItemEvent enchantEvent))
return;
EnchantmentType[] enchants = new EnchantmentType[delta != null ? delta.length : 0];
if (delta != null && delta.length != 0) {
for (int i = 0; i < delta.length; i++) {
- if (delta[i] instanceof EnchantmentType)
- enchants[i] = (EnchantmentType) delta[i];
- else
- enchants[i] = new EnchantmentType((Enchantment) delta[i]);
+ enchants[i] = (EnchantmentType) delta[i];
}
}
- EnchantItemEvent e = (EnchantItemEvent) event;
+
+ if (mode == ChangeMode.SET || mode == ChangeMode.DELETE)
+ enchantEvent.getEnchantsToAdd().clear();
+
switch (mode) {
- case SET:
- e.getEnchantsToAdd().clear();
- case ADD:
+ case DELETE -> {}
+ case SET, ADD -> {
for (EnchantmentType enchant : enchants)
- e.getEnchantsToAdd().put(enchant.getType(), enchant.getLevel());
- break;
- case REMOVE:
+ enchantEvent.getEnchantsToAdd().put(enchant.getType(), enchant.getLevel());
+ }
+ case REMOVE -> {
for (EnchantmentType enchant : enchants)
- e.getEnchantsToAdd().remove(enchant.getType(), enchant.getLevel());
- break;
- case DELETE:
- e.getEnchantsToAdd().clear();
- case REMOVE_ALL:
- case RESET:
+ enchantEvent.getEnchantsToAdd().remove(enchant.getType(), enchant.getLevel());
+ }
+ default -> {
assert false;
+ }
}
}
@@ -113,7 +113,7 @@ public Class extends EnchantmentType> getReturnType() {
}
@Override
- public String toString(@Nullable Event e, boolean debug) {
+ public String toString(@Nullable Event event, boolean debug) {
return "applied enchantments";
}
diff --git a/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprEnchantItem.java b/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprEnchantItem.java
new file mode 100644
index 00000000000..690324d1eb0
--- /dev/null
+++ b/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprEnchantItem.java
@@ -0,0 +1,116 @@
+package org.skriptlang.skript.bukkit.enchantments.elements.expressions;
+
+import ch.njol.skript.aliases.ItemType;
+import ch.njol.skript.lang.EventRestrictedSyntax;
+import org.bukkit.event.Event;
+import org.bukkit.event.enchantment.EnchantItemEvent;
+import org.bukkit.event.enchantment.PrepareItemEnchantEvent;
+import org.bukkit.inventory.ItemStack;
+import org.jetbrains.annotations.Nullable;
+
+import ch.njol.skript.classes.Changer.ChangeMode;
+import ch.njol.skript.doc.Description;
+import ch.njol.skript.doc.Events;
+import ch.njol.skript.doc.Example;
+import ch.njol.skript.doc.Name;
+import ch.njol.skript.doc.Since;
+import ch.njol.skript.lang.Expression;
+import ch.njol.skript.lang.SkriptParser.ParseResult;
+import ch.njol.skript.lang.util.SimpleExpression;
+import ch.njol.util.Kleenean;
+import ch.njol.util.coll.CollectionUtils;
+import org.skriptlang.skript.lang.script.ScriptWarning;
+import org.skriptlang.skript.registration.SyntaxRegistry;
+
+import static org.skriptlang.skript.registration.DefaultSyntaxInfos.Expression.builder;
+
+@Name("Enchant Item")
+@Description("""
+ The enchant item in an enchant prepare event or enchant event.
+ It can be modified, but enchantments will still be applied in the enchant event.
+ """)
+@Example("""
+ on enchant:
+ set the enchanted item to a diamond chestplate
+ """)
+@Example("""
+ on enchant prepare:
+ set the enchant item to a wooden sword
+ """)
+@Events({"enchant prepare", "enchant"})
+@Since("2.5")
+public class ExprEnchantItem extends SimpleExpression implements EventRestrictedSyntax {
+
+ public static void register(SyntaxRegistry registry) {
+ registry.register(SyntaxRegistry.EXPRESSION, builder(ExprEnchantItem.class, ItemType.class)
+ .addPatterns("[the] enchant[:ed] item")
+ .supplier(ExprEnchantItem::new).build());
+ }
+
+ @Override
+ public boolean init(Expression>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
+ if (!parseResult.hasTag("ed"))
+ ScriptWarning.printDeprecationWarning("The 'enchant item' form of the enchanted item expression is deprecated, please use 'enchanted 'item'!");
+ return true;
+ }
+
+ @Override
+ public Class extends Event>[] supportedEvents() {
+ return CollectionUtils.array(EnchantItemEvent.class, PrepareItemEnchantEvent.class);
+ }
+
+ @Override
+ protected ItemType[] get(Event event) {
+ return new ItemType[]{new ItemType(switch (event) {
+ case PrepareItemEnchantEvent prepare -> prepare.getItem();
+ case EnchantItemEvent enchant -> enchant.getItem();
+ case null, default -> throw new IllegalStateException("Unsupported event " + event);
+ })};
+ }
+
+ @Override
+ public Class> @Nullable [] acceptChange(ChangeMode mode) {
+ if (mode == ChangeMode.SET)
+ return CollectionUtils.array(ItemType.class);
+ return null;
+ }
+
+ @Override
+ public void change(Event event, Object @Nullable [] delta, ChangeMode mode) {
+ if (delta == null)
+ return;
+ ItemType item = ((ItemType) delta[0]);
+ switch (mode) {
+ case SET -> {
+ ItemStack existing = switch (event) {
+ case PrepareItemEnchantEvent prepare -> prepare.getItem();
+ case EnchantItemEvent enchant -> enchant.getItem();
+ default -> throw new AssertionError("unreachable");
+ };
+ //noinspection deprecation back-compat; danger danger !!
+ existing.setType(item.getMaterial());
+ existing.setItemMeta(item.getItemMeta());
+ existing.setAmount(item.getAmount());
+ }
+ case null, default -> {
+ assert false;
+ }
+ }
+ }
+
+ @Override
+ public boolean isSingle() {
+ return true;
+ }
+
+ @Override
+ public Class extends ItemType> getReturnType() {
+ return ItemType.class;
+ }
+
+ @Override
+ public String toString(@Nullable Event event, boolean debug) {
+ return "enchanted item";
+ }
+
+}
diff --git a/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprEnchantingExpCost.java b/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprEnchantingExpCost.java
new file mode 100644
index 00000000000..714c1051995
--- /dev/null
+++ b/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprEnchantingExpCost.java
@@ -0,0 +1,104 @@
+package org.skriptlang.skript.bukkit.enchantments.elements.expressions;
+
+import ch.njol.skript.lang.EventRestrictedSyntax;
+import org.bukkit.event.Event;
+import org.bukkit.event.enchantment.EnchantItemEvent;
+import org.jetbrains.annotations.Nullable;
+
+import ch.njol.skript.classes.Changer.ChangeMode;
+import ch.njol.skript.doc.Description;
+import ch.njol.skript.doc.Events;
+import ch.njol.skript.doc.Example;
+import ch.njol.skript.doc.Name;
+import ch.njol.skript.doc.Since;
+import ch.njol.skript.lang.Expression;
+import ch.njol.skript.lang.SkriptParser.ParseResult;
+import ch.njol.skript.lang.util.SimpleExpression;
+import ch.njol.util.Kleenean;
+import ch.njol.util.coll.CollectionUtils;
+import org.skriptlang.skript.registration.SyntaxRegistry;
+
+import static org.skriptlang.skript.registration.DefaultSyntaxInfos.Expression.builder;
+
+@Name("Enchanting Experience Cost")
+@Description("""
+ The cost of enchanting in an enchant event.
+ This is number that was displayed in the enchantment table, not the actual number of levels removed.
+ """)
+@Example("""
+ on enchant:
+ send "Cost: %the displayed enchanting cost%" to player
+ """)
+@Events("enchant")
+@Since("2.5")
+public class ExprEnchantingExpCost extends SimpleExpression implements EventRestrictedSyntax {
+
+ public static void register(SyntaxRegistry registry) {
+ registry.register(SyntaxRegistry.EXPRESSION, builder(ExprEnchantingExpCost.class, Integer.class)
+ .addPattern("[the] [displayed] ([e]xp[erience]|enchanting) cost")
+ .supplier(ExprEnchantingExpCost::new).build());
+ }
+
+ @Override
+ public boolean init(Expression>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
+ return true;
+ }
+
+ @Override
+ public Class extends Event>[] supportedEvents() {
+ return CollectionUtils.array(EnchantItemEvent.class);
+ }
+
+ @Override
+ protected Integer @Nullable [] get(Event event) {
+ if (!(event instanceof EnchantItemEvent enchantEvent))
+ return null;
+
+ return new Integer[]{enchantEvent.getExpLevelCost()};
+ }
+
+ @Override
+ public Class> @Nullable [] acceptChange(ChangeMode mode) {
+ return switch (mode) {
+ case SET, ADD, REMOVE -> CollectionUtils.array(Number.class);
+ default -> null;
+ };
+ }
+
+ @Override
+ public void change(Event event, Object @Nullable [] delta, ChangeMode mode) {
+ if (delta == null || delta.length == 0 || !(event instanceof EnchantItemEvent enchantEvent))
+ return;
+ int cost = ((Number) delta[0]).intValue();
+ switch (mode) {
+ case SET -> enchantEvent.setExpLevelCost(cost);
+ case ADD -> {
+ int add = enchantEvent.getExpLevelCost() + cost;
+ enchantEvent.setExpLevelCost(add);
+ }
+ case REMOVE -> {
+ int subtract = enchantEvent.getExpLevelCost() - cost;
+ enchantEvent.setExpLevelCost(subtract);
+ }
+ case RESET, DELETE, REMOVE_ALL -> {
+ assert false;
+ }
+ }
+ }
+
+ @Override
+ public boolean isSingle() {
+ return true;
+ }
+
+ @Override
+ public Class extends Integer> getReturnType() {
+ return Integer.class;
+ }
+
+ @Override
+ public String toString(@Nullable Event event, boolean debug) {
+ return "the displayed cost of enchanting";
+ }
+
+}
diff --git a/src/main/java/ch/njol/skript/expressions/ExprEnchantmentBonus.java b/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprEnchantmentBonus.java
similarity index 50%
rename from src/main/java/ch/njol/skript/expressions/ExprEnchantmentBonus.java
rename to src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprEnchantmentBonus.java
index 42b53e16623..abf3c5e5286 100644
--- a/src/main/java/ch/njol/skript/expressions/ExprEnchantmentBonus.java
+++ b/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprEnchantmentBonus.java
@@ -1,23 +1,21 @@
-package ch.njol.skript.expressions;
+package org.skriptlang.skript.bukkit.enchantments.elements.expressions;
-import ch.njol.skript.lang.EventRestrictedSyntax;
-import ch.njol.util.coll.CollectionUtils;
-import org.bukkit.event.Event;
-import org.bukkit.event.enchantment.PrepareItemEnchantEvent;
-import org.jetbrains.annotations.Nullable;
-
-import ch.njol.skript.Skript;
import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Events;
import ch.njol.skript.doc.Example;
import ch.njol.skript.doc.Name;
import ch.njol.skript.doc.Since;
+import ch.njol.skript.lang.EventRestrictedSyntax;
import ch.njol.skript.lang.Expression;
-import ch.njol.skript.lang.ExpressionType;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.lang.util.SimpleExpression;
-import ch.njol.skript.log.ErrorQuality;
import ch.njol.util.Kleenean;
+import org.bukkit.event.Event;
+import org.bukkit.event.enchantment.PrepareItemEnchantEvent;
+import org.jetbrains.annotations.Nullable;
+import org.skriptlang.skript.registration.SyntaxRegistry;
+
+import static org.skriptlang.skript.registration.DefaultSyntaxInfos.Expression.builder;
@Name("Enchantment Bonus")
@Description("The enchantment bonus in an enchant prepare event. This represents the number of bookshelves affecting/surrounding the enchantment table.")
@@ -27,26 +25,31 @@
""")
@Events("enchant prepare")
@Since("2.5")
-public class ExprEnchantmentBonus extends SimpleExpression implements EventRestrictedSyntax {
-
- static {
- Skript.registerExpression(ExprEnchantmentBonus.class, Long.class, ExpressionType.SIMPLE, "[the] enchantment bonus");
+public class ExprEnchantmentBonus extends SimpleExpression implements EventRestrictedSyntax {
+
+ public static void register(SyntaxRegistry registry) {
+ registry.register(SyntaxRegistry.EXPRESSION, builder(ExprEnchantmentBonus.class, Integer.class)
+ .addPattern("[the] enchant[ment] bonus")
+ .supplier(ExprEnchantmentBonus::new).build());
}
@Override
- public boolean init(Expression>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
+ public boolean init(Expression>[] expressions, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
return true;
}
@Override
+ @SuppressWarnings("unchecked") /* hard-coded event type */
public Class extends Event>[] supportedEvents() {
- return CollectionUtils.array(PrepareItemEnchantEvent.class);
+ return new Class[]{PrepareItemEnchantEvent.class};
}
@Override
- @Nullable
- protected Long[] get(Event e) {
- return new Long[]{(long) ((PrepareItemEnchantEvent) e).getEnchantmentBonus()};
+ protected Integer @Nullable [] get(Event event) {
+ if (!(event instanceof PrepareItemEnchantEvent prepare))
+ return null;
+
+ return new Integer[]{prepare.getEnchantmentBonus()};
}
@Override
@@ -54,14 +57,13 @@ public boolean isSingle() {
return true;
}
-
@Override
- public Class extends Long> getReturnType() {
- return Long.class;
+ public Class extends Integer> getReturnType() {
+ return Integer.class;
}
@Override
- public String toString(@Nullable Event e, boolean debug) {
+ public String toString(@Nullable Event event, boolean debug) {
return "enchantment bonus";
}
diff --git a/src/main/java/ch/njol/skript/expressions/ExprEnchantmentLevel.java b/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprEnchantmentLevel.java
similarity index 58%
rename from src/main/java/ch/njol/skript/expressions/ExprEnchantmentLevel.java
rename to src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprEnchantmentLevel.java
index 9fa8ffd771f..33d69e93f06 100644
--- a/src/main/java/ch/njol/skript/expressions/ExprEnchantmentLevel.java
+++ b/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprEnchantmentLevel.java
@@ -1,14 +1,13 @@
-package ch.njol.skript.expressions;
+package org.skriptlang.skript.bukkit.enchantments.elements.expressions;
-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.Example;
import ch.njol.skript.doc.Name;
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.skript.lang.util.SimpleExpression;
import ch.njol.skript.util.EnchantmentType;
@@ -17,9 +16,12 @@
import org.bukkit.enchantments.Enchantment;
import org.bukkit.event.Event;
import org.jetbrains.annotations.Nullable;
+import org.skriptlang.skript.registration.SyntaxRegistry;
import java.util.stream.Stream;
+import static org.skriptlang.skript.registration.DefaultSyntaxInfos.Expression.builder;
+
@Name("Enchantment Level")
@Description("The level of a particular enchantment on an item.")
@Example("""
@@ -29,18 +31,19 @@
@Since("2.0")
public class ExprEnchantmentLevel extends SimpleExpression {
- static {
- Skript.registerExpression(ExprEnchantmentLevel.class, Long.class, ExpressionType.PROPERTY,
- "[the] [enchant[ment]] level[s] of %enchantments% (on|of) %itemtypes%",
- "[the] %enchantments% [enchant[ment]] level[s] (on|of) %itemtypes%",
- "%itemtypes%'[s] %enchantments% [enchant[ment]] level[s]",
- "%itemtypes%'[s] [enchant[ment]] level[s] of %enchantments%");
+ public static void register(SyntaxRegistry registry) {
+ registry.register(SyntaxRegistry.EXPRESSION, builder(ExprEnchantmentLevel.class, Long.class)
+ .addPatterns(
+ "[the] [enchant[ment]] level[s] of %enchantments% (on|of) %itemtypes%",
+ "[the] %enchantments% [enchant[ment]] level[s] (on|of) %itemtypes%",
+ "%itemtypes%'[s] %enchantments% [enchant[ment]] level[s]",
+ "%itemtypes%'[s] [enchant[ment]] level[s] of %enchantments%")
+ .supplier(ExprEnchantmentLevel::new)
+ .priority(PropertyExpression.DEFAULT_PRIORITY).build());
}
- @SuppressWarnings("NotNullFieldNotInitialized")
private Expression items;
- @SuppressWarnings("NotNullFieldNotInitialized")
private Expression enchants;
@Override
@@ -53,9 +56,9 @@ public boolean init(Expression>[] exprs, int matchedPattern, Kleenean isDelaye
}
@Override
- protected Long[] get(Event e) {
- Enchantment[] enchantments = enchants.getArray(e);
- return Stream.of(items.getArray(e))
+ protected Long[] get(Event event) {
+ Enchantment[] enchantments = enchants.getArray(event);
+ return Stream.of(items.getArray(event))
.map(ItemType::getEnchantmentTypes)
.flatMap(Stream::of)
.filter(enchantment -> CollectionUtils.contains(enchantments, enchantment.getType()))
@@ -65,22 +68,19 @@ protected Long[] get(Event e) {
}
@Override
- @Nullable
- public Class>[] acceptChange(ChangeMode mode) {
- switch (mode) {
- case SET:
- case REMOVE:
- case ADD:
- return CollectionUtils.array(Number.class);
- default:
- return null;
- }
+ public Class> @Nullable [] acceptChange(ChangeMode mode) {
+ return switch (mode) {
+ case SET, REMOVE, ADD -> CollectionUtils.array(Number.class);
+ default -> null;
+ };
}
@Override
- public void change(Event e, @Nullable Object[] delta, ChangeMode mode) {
- ItemType[] itemTypes = items.getArray(e);
- Enchantment[] enchantments = enchants.getArray(e);
+ public void change(Event event, Object @Nullable [] delta, ChangeMode mode) {
+ ItemType[] itemTypes = items.getArray(event);
+ Enchantment[] enchantments = enchants.getArray(event);
+ if (delta == null || delta.length == 0)
+ return;
int changeValue = ((Number) delta[0]).intValue();
for (ItemType itemType : itemTypes) {
@@ -90,18 +90,13 @@ public void change(Event e, @Nullable Object[] delta, ChangeMode mode) {
int newItemLevel;
switch (mode) {
- case ADD:
- newItemLevel = oldLevel + changeValue;
- break;
- case REMOVE:
- newItemLevel = oldLevel - changeValue;
- break;
- case SET:
- newItemLevel = changeValue;
- break;
- default:
+ case ADD -> newItemLevel = oldLevel + changeValue;
+ case REMOVE -> newItemLevel = oldLevel - changeValue;
+ case SET -> newItemLevel = changeValue;
+ default -> {
assert false;
return;
+ }
}
if (newItemLevel <= 0) {
@@ -124,8 +119,8 @@ public Class extends Long> getReturnType() {
}
@Override
- public String toString(@Nullable Event e, boolean debug) {
- return "the level of " + enchants.toString(e, debug) + " of " + items.toString(e, debug);
+ public String toString(@Nullable Event event, boolean debug) {
+ return "the level of " + enchants.toString(event, debug) + " of " + items.toString(event, debug);
}
}
diff --git a/src/main/java/ch/njol/skript/expressions/ExprEnchantmentOffer.java b/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprEnchantmentOffer.java
similarity index 53%
rename from src/main/java/ch/njol/skript/expressions/ExprEnchantmentOffer.java
rename to src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprEnchantmentOffer.java
index d574d0c8e31..f529c4dcfd4 100644
--- a/src/main/java/ch/njol/skript/expressions/ExprEnchantmentOffer.java
+++ b/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprEnchantmentOffer.java
@@ -1,4 +1,4 @@
-package ch.njol.skript.expressions;
+package org.skriptlang.skript.bukkit.enchantments.elements.expressions;
import java.util.ArrayList;
import java.util.Arrays;
@@ -11,22 +11,22 @@
import org.bukkit.event.enchantment.PrepareItemEnchantEvent;
import org.jetbrains.annotations.Nullable;
-import ch.njol.skript.Skript;
import ch.njol.skript.classes.Changer.ChangeMode;
import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Events;
import ch.njol.skript.doc.Example;
import ch.njol.skript.doc.Name;
-import ch.njol.skript.doc.RequiredPlugins;
import ch.njol.skript.doc.Since;
import ch.njol.skript.lang.Expression;
-import ch.njol.skript.lang.ExpressionType;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.lang.util.SimpleExpression;
-import ch.njol.skript.log.ErrorQuality;
import ch.njol.skript.util.EnchantmentType;
import ch.njol.util.Kleenean;
import ch.njol.util.coll.CollectionUtils;
+import org.skriptlang.skript.registration.SyntaxInfo;
+import org.skriptlang.skript.registration.SyntaxRegistry;
+
+import static org.skriptlang.skript.registration.DefaultSyntaxInfos.Expression.builder;
@Name("Enchantment Offer")
@Description("The enchantment offer in enchant prepare events.")
@@ -36,16 +36,20 @@
""")
@Since("2.5")
@Events("enchant prepare")
-@RequiredPlugins("1.11 or newer")
public class ExprEnchantmentOffer extends SimpleExpression implements EventRestrictedSyntax {
- static {
- if (Skript.classExists("org.bukkit.enchantments.EnchantmentOffer")) {
- Skript.registerExpression(ExprEnchantmentOffer.class, EnchantmentOffer.class, ExpressionType.SIMPLE,
- "[all [of]] [the] enchant[ment] offers",
- "enchant[ment] offer[s] %numbers%",
- "[the] %number%(st|nd|rd|th) enchant[ment] offer");
- }
+ /*
+ * This should probably be an event value, but ExprElement doesn't support the %number%(st|nd|rd|th) %classinfo% syntax,
+ * and we have to keep it for backward compatibility, so for now it's best to just keep it as an expression
+ * */
+ public static void register(SyntaxRegistry registry) {
+ registry.register(SyntaxRegistry.EXPRESSION, builder(ExprEnchantmentOffer.class, EnchantmentOffer.class)
+ .addPatterns(
+ "[all [of]] [the] enchant[ment] offers",
+ "enchant[ment] offer[s] %numbers%",
+ "[the] %number%(st|nd|rd|th) enchant[ment] offer")
+ .supplier(ExprEnchantmentOffer::new)
+ .priority(SyntaxInfo.SIMPLE).build());
}
@SuppressWarnings("null")
@@ -56,8 +60,8 @@ public class ExprEnchantmentOffer extends SimpleExpression imp
// Used for getCost()
private final Random rand = new Random();
- @SuppressWarnings({"null", "unchecked"})
@Override
+ @SuppressWarnings({"null", "unchecked"})
public boolean init(Expression>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
if (matchedPattern == 0) {
all = true;
@@ -75,83 +79,70 @@ public Class extends Event>[] supportedEvents() {
@SuppressWarnings({"null", "unused"})
@Override
- @Nullable
- protected EnchantmentOffer[] get(Event e) {
- if (!(e instanceof PrepareItemEnchantEvent))
+ protected EnchantmentOffer @Nullable [] get(Event event) {
+ if (!(event instanceof PrepareItemEnchantEvent))
return null;
if (all)
- return ((PrepareItemEnchantEvent) e).getOffers();
+ return ((PrepareItemEnchantEvent) event).getOffers();
if (exprOfferNumber == null)
return new EnchantmentOffer[0];
if (exprOfferNumber.isSingle()) {
- Number offerNumber = exprOfferNumber.getSingle(e);
+ Number offerNumber = exprOfferNumber.getSingle(event);
if (offerNumber == null)
return new EnchantmentOffer[0];
int offer = offerNumber.intValue();
- if (offer < 1 || offer > ((PrepareItemEnchantEvent) e).getOffers().length)
+ if (offer < 1 || offer > ((PrepareItemEnchantEvent) event).getOffers().length)
return new EnchantmentOffer[0];
- return new EnchantmentOffer[]{((PrepareItemEnchantEvent) e).getOffers()[offer - 1]};
+ return new EnchantmentOffer[]{((PrepareItemEnchantEvent) event).getOffers()[offer - 1]};
}
List offers = new ArrayList<>();
- int i;
- for (Number n : exprOfferNumber.getArray(e)) {
- i = n.intValue();
- if (i >= 1 || i <= ((PrepareItemEnchantEvent) e).getOffers().length)
- offers.add(((PrepareItemEnchantEvent) e).getOffers()[i - 1]);
+ int intIndex;
+ for (Number index : exprOfferNumber.getArray(event)) {
+ intIndex = index.intValue();
+ if (intIndex >= 1 && intIndex <= ((PrepareItemEnchantEvent) event).getOffers().length)
+ offers.add(((PrepareItemEnchantEvent) event).getOffers()[intIndex - 1]);
}
return offers.toArray(new EnchantmentOffer[0]);
}
@Override
- @Nullable
- public Class>[] acceptChange(ChangeMode mode) {
+ public Class> @Nullable [] acceptChange(ChangeMode mode) {
if (mode == ChangeMode.SET || mode == ChangeMode.DELETE)
return CollectionUtils.array(EnchantmentType.class);
return null;
}
- @SuppressWarnings("null")
@Override
- public void change(Event event, @Nullable Object[] delta, ChangeMode mode) {
+ @SuppressWarnings("null")
+ public void change(Event event, Object @Nullable [] delta, ChangeMode mode) {
if (delta == null && mode != ChangeMode.DELETE)
return;
- EnchantmentType et = mode != ChangeMode.DELETE ? (EnchantmentType) delta[0] : null;
- if (event instanceof PrepareItemEnchantEvent) {
- PrepareItemEnchantEvent e = (PrepareItemEnchantEvent) event;
+ EnchantmentType type = mode != ChangeMode.DELETE ? (EnchantmentType) delta[0] : null;
+ if (event instanceof PrepareItemEnchantEvent prepareEvent) {
switch (mode) {
case SET:
- if (all) {
- for (int i = 0; i <= 2; i++) {
- EnchantmentOffer eo = e.getOffers()[i];
- if (eo == null) {
- eo = new EnchantmentOffer(et.getType(), et.getLevel(), getCost(i + 1, e.getEnchantmentBonus()));
- e.getOffers()[i] = eo;
- } else {
- eo.setEnchantment(et.getType());
- eo.setEnchantmentLevel(et.getLevel());
- }
- }
- } else {
- for (Number n : exprOfferNumber.getArray(e)) {
- int slot = n.intValue() - 1;
- EnchantmentOffer eo = e.getOffers()[slot];
- if (eo == null) {
- eo = new EnchantmentOffer(et.getType(), et.getLevel(), getCost(slot + 1, e.getEnchantmentBonus()));
- e.getOffers()[slot] = eo;
- } else {
- eo.setEnchantment(et.getType());
- eo.setEnchantmentLevel(et.getLevel());
- }
+ assert type != null;
+ Number[] indices = all ? new Number[]{1, 2, 3} : exprOfferNumber.getArray(prepareEvent);
+ for (Number index : indices) {
+ int slot = index.intValue() - 1;
+ EnchantmentOffer offer = prepareEvent.getOffers()[slot];
+ if (offer == null) {
+ offer = new EnchantmentOffer(type.getType(), type.getLevel(),
+ getCost(slot + 1, prepareEvent.getEnchantmentBonus()));
+ prepareEvent.getOffers()[slot] = offer;
+ } else {
+ offer.setEnchantment(type.getType());
+ offer.setEnchantmentLevel(type.getLevel());
}
}
break;
case DELETE:
if (all) {
- Arrays.fill(e.getOffers(), null);
+ Arrays.fill(prepareEvent.getOffers(), null);
} else {
- for (Number n : exprOfferNumber.getArray(e))
- e.getOffers()[n.intValue() - 1] = null;
+ for (Number index : exprOfferNumber.getArray(prepareEvent))
+ prepareEvent.getOffers()[index.intValue() - 1] = null;
}
break;
case ADD:
@@ -174,8 +165,8 @@ public Class extends EnchantmentOffer> getReturnType() {
}
@Override
- public String toString(@Nullable Event e, boolean debug) {
- return all ? "the enchantment offers" : "enchantment offer(s) " + exprOfferNumber.toString(e, debug);
+ public String toString(@Nullable Event event, boolean debug) {
+ return all ? "the enchantment offers" : "enchantment offer(s) " + exprOfferNumber.toString(event, debug);
}
/**
@@ -186,13 +177,13 @@ public String toString(@Nullable Event e, boolean debug) {
*/
public int getCost(int slot, int bookshelves) {
// (from 1 to 8) + floor(bookshelves / 2) + (from 0 to bookshelves)
- int base = (int) ((rand.nextInt(7) + 1) + Math.floor(bookshelves / 2) + (rand.nextInt(bookshelves + 1)));
- switch (slot) {
- case 1: return Math.max(base / 3, 1);
- case 2: return (base * 2) / 3 + 1;
- case 3: return Math.max(base, bookshelves * 2);
- default: return 1;
- }
+ int base = (rand.nextInt(7) + 1) + (bookshelves / 2) + (rand.nextInt(bookshelves + 1));
+ return switch (slot) {
+ case 1 -> Math.max(base / 3, 1);
+ case 2 -> (base * 2) / 3 + 1;
+ case 3 -> Math.max(base, bookshelves * 2);
+ default -> 1;
+ };
}
}
diff --git a/src/main/java/ch/njol/skript/expressions/ExprEnchantmentOfferCost.java b/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprEnchantmentOfferCost.java
similarity index 62%
rename from src/main/java/ch/njol/skript/expressions/ExprEnchantmentOfferCost.java
rename to src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprEnchantmentOfferCost.java
index 1aa1844b024..1730b763c01 100644
--- a/src/main/java/ch/njol/skript/expressions/ExprEnchantmentOfferCost.java
+++ b/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprEnchantmentOfferCost.java
@@ -1,19 +1,17 @@
-package ch.njol.skript.expressions;
+package org.skriptlang.skript.bukkit.enchantments.elements.expressions;
import org.bukkit.enchantments.EnchantmentOffer;
import org.bukkit.event.Event;
import org.jetbrains.annotations.Nullable;
-import ch.njol.skript.Skript;
import ch.njol.skript.classes.Changer.ChangeMode;
import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Example;
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.skript.util.Experience;
import ch.njol.util.coll.CollectionUtils;
+import org.skriptlang.skript.registration.SyntaxRegistry;
@Name("Enchantment Offer Cost")
@Description({
@@ -24,12 +22,12 @@
})
@Example("set cost of enchantment offer 1 to 50")
@Since("2.5")
-@RequiredPlugins("1.11 or newer")
public class ExprEnchantmentOfferCost extends SimplePropertyExpression {
- static {
- if (Skript.classExists("org.bukkit.enchantments.EnchantmentOffer"))
- register(ExprEnchantmentOfferCost.class, Long.class, "[enchant[ment]] cost", "enchantmentoffers");
+ public static void register(SyntaxRegistry registry) {
+ registry.register(SyntaxRegistry.EXPRESSION, infoBuilder(
+ ExprEnchantmentOfferCost.class, Long.class, "[enchant[ment]] cost", "enchantmentoffers", false)
+ .supplier(ExprEnchantmentOfferCost::new).build());
}
@Override
@@ -38,48 +36,42 @@ public Long convert(final EnchantmentOffer offer) {
}
@Override
- @Nullable
- public Class>[] acceptChange(ChangeMode mode) {
+ public Class> @Nullable [] acceptChange(ChangeMode mode) {
if (mode == ChangeMode.REMOVE || mode == ChangeMode.REMOVE_ALL || mode == ChangeMode.RESET)
return null;
- return CollectionUtils.array(Number.class, Experience.class);
+ return CollectionUtils.array(Number.class);
}
@Override
- public void change(Event event, @Nullable Object[] delta, ChangeMode mode) {
+ public void change(Event event, Object @Nullable [] delta, ChangeMode mode) {
EnchantmentOffer[] offers = getExpr().getArray(event);
if (offers.length == 0 || delta == null)
return;
- Object c = delta[0];
- int cost = c instanceof Number ? ((Number) c).intValue() : ((Experience) c).getXP();
+ if (delta[0] == null)
+ return;
+ int cost = ((Number) delta[0]).intValue();
if (cost < 1)
return;
int change;
- switch (mode) {
- case SET:
- for (EnchantmentOffer offer : offers)
- offer.setCost(cost);
- break;
- case ADD:
- for (EnchantmentOffer offer : offers) {
+ for (EnchantmentOffer offer : offers) {
+ switch (mode) {
+ case SET -> offer.setCost(cost);
+ case ADD -> {
change = offer.getCost() + cost;
- if (change < 1)
+ if (change < 1)
return;
offer.setCost(change);
}
- break;
- case REMOVE:
- for (EnchantmentOffer offer : offers) {
+ case REMOVE -> {
change = offer.getCost() - cost;
- if (change < 1)
+ if (change < 1)
return;
offer.setCost(change);
}
- break;
- case RESET:
- case DELETE:
- case REMOVE_ALL:
- assert false;
+ case RESET, DELETE, REMOVE_ALL -> {
+ assert false;
+ }
+ }
}
}
diff --git a/src/main/java/ch/njol/skript/expressions/ExprEnchantments.java b/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprEnchantments.java
similarity index 64%
rename from src/main/java/ch/njol/skript/expressions/ExprEnchantments.java
rename to src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprEnchantments.java
index 2df74875524..ed6e030113a 100644
--- a/src/main/java/ch/njol/skript/expressions/ExprEnchantments.java
+++ b/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprEnchantments.java
@@ -1,4 +1,4 @@
-package ch.njol.skript.expressions;
+package org.skriptlang.skript.bukkit.enchantments.elements.expressions;
import java.util.ArrayList;
import java.util.Collections;
@@ -18,28 +18,27 @@
import ch.njol.skript.expressions.base.PropertyExpression;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.SkriptParser.ParseResult;
-import ch.njol.skript.lang.util.SimpleExpression;
import ch.njol.skript.util.EnchantmentType;
import ch.njol.util.Kleenean;
import ch.njol.util.coll.CollectionUtils;
+import org.skriptlang.skript.registration.SyntaxRegistry;
@Name("Item Enchantments")
@Description("All the enchantments an item type has.")
@Example("clear enchantments of event-item")
@Since("2.2-dev36")
-public class ExprEnchantments extends SimpleExpression {
+public class ExprEnchantments extends PropertyExpression {
- static {
- PropertyExpression.register(ExprEnchantments.class, EnchantmentType.class, "enchantments", "itemtypes");
+ public static void register(SyntaxRegistry registry) {
+ registry.register(SyntaxRegistry.EXPRESSION,
+ infoBuilder(ExprEnchantments.class, EnchantmentType.class, "enchantments", "itemtypes", false)
+ .supplier(ExprEnchantments::new).build());
}
- @SuppressWarnings("null")
- private Expression items;
-
- @SuppressWarnings({"null","unchecked"})
@Override
+ @SuppressWarnings({"null","unchecked"})
public boolean init(Expression>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
- items = (Expression) exprs[0];
+ setExpr((Expression) exprs[0]);
return true;
}
@@ -49,11 +48,9 @@ public boolean isSingle() {
}
@Override
- @Nullable
- protected EnchantmentType[] get(Event e) {
+ protected EnchantmentType[] get(Event event, ItemType[] source) {
List enchantments = new ArrayList<>();
-
- for (ItemType item : items.getArray(e)) {
+ for (ItemType item : source) {
EnchantmentType[] enchants = item.getEnchantmentTypes();
if (enchants == null)
@@ -65,27 +62,23 @@ protected EnchantmentType[] get(Event e) {
}
@Override
- @Nullable
- public Class>[] acceptChange(ChangeMode mode) {
- // Enchantment doesn't get automatically converted to EnchantmentType if you give it more than a one.
- // Meaning you can transform an Enchantment array to an EnchantmentType array automatically,
- // So, we gotta do it manually.
- return CollectionUtils.array(Enchantment[].class, EnchantmentType[].class);
+ public Class> @Nullable [] acceptChange(ChangeMode mode) {
+ return switch (mode) {
+ case ADD, SET, REMOVE, REMOVE_ALL, DELETE, RESET -> CollectionUtils.array(EnchantmentType[].class);
+ default -> null;
+ };
}
@Override
- public void change(Event e, @Nullable Object[] delta, ChangeMode mode) {
- ItemType[] source = items.getArray(e);
-
+ public void change(Event event, Object @Nullable [] delta, ChangeMode mode) {
+ ItemType[] source = getExpr().getArray(event);
+
EnchantmentType[] enchants = new EnchantmentType[delta != null ? delta.length : 0];
-
- if (delta != null && delta.length != 0) {
- for (int i = 0; i getReturnType() {
}
@Override
- public String toString(@Nullable Event e, boolean debug) {
- return "the enchantments of " + items.toString(e, debug);
+ public String toString(@Nullable Event event, boolean debug) {
+ return "the enchantments of " + getExpr().toString(event, debug);
}
}
diff --git a/src/main/java/ch/njol/skript/expressions/ExprItemWithEnchantmentGlint.java b/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprItemWithEnchantmentGlint.java
similarity index 74%
rename from src/main/java/ch/njol/skript/expressions/ExprItemWithEnchantmentGlint.java
rename to src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprItemWithEnchantmentGlint.java
index e763798f487..1f2c73f42a5 100644
--- a/src/main/java/ch/njol/skript/expressions/ExprItemWithEnchantmentGlint.java
+++ b/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprItemWithEnchantmentGlint.java
@@ -1,29 +1,31 @@
-package ch.njol.skript.expressions;
+package org.skriptlang.skript.bukkit.enchantments.elements.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.*;
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;
+import org.skriptlang.skript.registration.SyntaxRegistry;
+
+import static org.skriptlang.skript.registration.DefaultSyntaxInfos.Expression.builder;
@Name("Item with Enchantment Glint")
@Description("Get an item with or without enchantment glint.")
@Example("set {_item with glint} to diamond with enchantment glint")
@Example("set {_item without glint} to diamond without enchantment glint")
-@RequiredPlugins("Spigot 1.20.5+")
@Since("2.10")
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");
+ public static void register(SyntaxRegistry registry) {
+ registry.register(SyntaxRegistry.EXPRESSION, builder(ExprItemWithEnchantmentGlint.class, ItemType.class)
+ .addPattern("%itemtypes% with[:out] [enchant[ment]] glint")
+ .supplier(ExprItemWithEnchantmentGlint::new)
+ .priority(PropertyExpression.DEFAULT_PRIORITY).build());
}
private boolean glint;
diff --git a/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprMaximumEnchantmentLevel.java b/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprMaximumEnchantmentLevel.java
new file mode 100644
index 00000000000..eee48b96504
--- /dev/null
+++ b/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprMaximumEnchantmentLevel.java
@@ -0,0 +1,45 @@
+package org.skriptlang.skript.bukkit.enchantments.elements.expressions;
+
+import ch.njol.skript.doc.Description;
+import ch.njol.skript.doc.Example;
+import ch.njol.skript.doc.Name;
+import ch.njol.skript.doc.Since;
+import ch.njol.skript.expressions.base.SimplePropertyExpression;
+import org.bukkit.enchantments.Enchantment;
+import org.jetbrains.annotations.Nullable;
+import org.skriptlang.skript.registration.SyntaxRegistry;
+
+@Name("Maximum Enchantment Level")
+@Description("The maximum allowed level in Minecraft of a particular enchantment")
+@Example("""
+ set {_maximum} to the maximum enchantment level of sharpness
+ if the level of sharpness of the player's tool is greater than {_maximum}:
+ send "Your tool's sharpness level was capped out at the maximum allowed level."
+ set the level of sharpness of the player's tool to {_maximum}
+ """)
+@Since("INSERT VERSION")
+public class ExprMaximumEnchantmentLevel extends SimplePropertyExpression {
+
+ public static void register(SyntaxRegistry registry) {
+ registry.register(SyntaxRegistry.EXPRESSION, infoBuilder(
+ ExprMaximumEnchantmentLevel.class, Integer.class,
+ "max[imum] enchant[ment] level", "enchantments", true)
+ .supplier(ExprMaximumEnchantmentLevel::new).build());
+ }
+
+ @Override
+ public @Nullable Integer convert(Enchantment from) {
+ return from.getMaxLevel();
+ }
+
+ @Override
+ public Class extends Integer> getReturnType() {
+ return Integer.class;
+ }
+
+ @Override
+ protected String getPropertyName() {
+ return "maximum enchantment level";
+ }
+
+}
diff --git a/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprMinimumEnchantmentLevel.java b/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprMinimumEnchantmentLevel.java
new file mode 100644
index 00000000000..b2fb9859926
--- /dev/null
+++ b/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprMinimumEnchantmentLevel.java
@@ -0,0 +1,48 @@
+package org.skriptlang.skript.bukkit.enchantments.elements.expressions;
+
+import ch.njol.skript.doc.Description;
+import ch.njol.skript.doc.Example;
+import ch.njol.skript.doc.Name;
+import ch.njol.skript.doc.Since;
+import ch.njol.skript.expressions.base.SimplePropertyExpression;
+import org.bukkit.enchantments.Enchantment;
+import org.jetbrains.annotations.Nullable;
+import org.skriptlang.skript.registration.SyntaxRegistry;
+
+@Name("Minimum Enchantment Level")
+@Description("""
+ The minimum starting level in Minecraft of a particular enchantment.
+ This is 1 for all existing enchantments as of 26.1.2.
+ """)
+@Example("""
+ set {_min} to the minimum enchantment level of sharpness
+ set {_max} to the maximum enchantment level of sharpness
+ loop integers between {_min} and {_max}:
+ set slot loop-counter of {_gui} to enchanted book named "Sharpness %loop-value%" with lore "Click to enchant!"
+ """)
+@Since("INSERT VERSION")
+public class ExprMinimumEnchantmentLevel extends SimplePropertyExpression {
+
+ public static void register(SyntaxRegistry registry) {
+ registry.register(SyntaxRegistry.EXPRESSION, infoBuilder(
+ ExprMinimumEnchantmentLevel.class, Integer.class,
+ "(min[imum]|start[ing]) enchant[ment] level", "enchantments", true)
+ .supplier(ExprMinimumEnchantmentLevel::new).build());
+ }
+
+ @Override
+ public @Nullable Integer convert(Enchantment from) {
+ return from.getStartLevel();
+ }
+
+ @Override
+ public Class extends Integer> getReturnType() {
+ return Integer.class;
+ }
+
+ @Override
+ protected String getPropertyName() {
+ return "minimum enchantment level";
+ }
+
+}
diff --git a/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprStoredEnchantments.java b/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprStoredEnchantments.java
new file mode 100644
index 00000000000..66f9eae5eb6
--- /dev/null
+++ b/src/main/java/org/skriptlang/skript/bukkit/enchantments/elements/expressions/ExprStoredEnchantments.java
@@ -0,0 +1,145 @@
+package org.skriptlang.skript.bukkit.enchantments.elements.expressions;
+
+import ch.njol.skript.aliases.ItemType;
+import ch.njol.skript.classes.Changer.ChangeMode;
+import ch.njol.skript.doc.Description;
+import ch.njol.skript.doc.Example;
+import ch.njol.skript.doc.Name;
+import ch.njol.skript.doc.Since;
+import ch.njol.skript.expressions.base.PropertyExpression;
+import ch.njol.skript.lang.Expression;
+import ch.njol.skript.lang.SkriptParser.ParseResult;
+import ch.njol.skript.util.EnchantmentType;
+import ch.njol.util.Kleenean;
+import ch.njol.util.coll.CollectionUtils;
+import org.bukkit.enchantments.Enchantment;
+import org.bukkit.event.Event;
+import org.bukkit.inventory.meta.EnchantmentStorageMeta;
+import org.bukkit.inventory.meta.ItemMeta;
+import org.jetbrains.annotations.Nullable;
+import org.skriptlang.skript.registration.SyntaxRegistry;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Name("Stored Enchantments")
+@Description("""
+ The enchantments stored inside an enchanted book. This is different from enchanting the book, as for example a book
+ of sharpness does not deal more damage when used as a weapon. Corresponds to the minecraft:stored_enchantments data component.
+ Note that for example resetting the stored enchantments of an enchanted book of Sharpness III removes the sharpness enchantment, since
+ it is impossible to know what the original enchantments of the item were. Note also that only one entry can exist per enchantment type;
+ adding Sharpness III to a book with Sharpness V will convert it to a book of Sharpness III.
+ """)
+@Example("""
+ command /godbook:
+ trigger:
+ set {_item} to minecraft:enchanted_book
+ add mending to stored enchants of {_item} # adds mending 1
+ add knockback 12 to stored enchants of {_item}
+ add fire aspect 3 to stored enchants of {_item}
+ give {_item} to player
+ """)
+@Since("INSERT VERSION")
+public class ExprStoredEnchantments extends PropertyExpression {
+
+ public static void register(SyntaxRegistry registry) {
+ registry.register(SyntaxRegistry.EXPRESSION, infoBuilder(
+ ExprStoredEnchantments.class, EnchantmentType.class, "stored enchant[ment]s", "itemtypes", false)
+ .supplier(ExprStoredEnchantments::new).build());
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public boolean init(Expression>[] expressions, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
+ setExpr((Expression extends ItemType>) expressions[0]);
+ return true;
+ }
+
+ @Override
+ protected EnchantmentType[] get(Event event, ItemType[] source) {
+ List types = new ArrayList<>();
+ for (ItemType type : source) {
+ ItemMeta meta = type.getItemMeta();
+ if (!(meta instanceof EnchantmentStorageMeta storageMeta))
+ continue;
+
+ for (Map.Entry entry : storageMeta.getStoredEnchants().entrySet()) {
+ types.add(new EnchantmentType(entry.getKey(), entry.getValue()));
+ }
+ }
+
+ return types.toArray(EnchantmentType[]::new);
+ }
+
+ @Override
+ public Class> @Nullable [] acceptChange(ChangeMode mode) {
+ return switch (mode) {
+ case ADD, SET, DELETE, REMOVE, REMOVE_ALL -> CollectionUtils.array(EnchantmentType[].class);
+ default -> null;
+ };
+ }
+
+ @Override
+ public void change(Event event, Object @Nullable [] delta, ChangeMode mode) {
+ ItemType[] targets = getExpr().getArray(event);
+ for (ItemType target : targets) {
+ ItemMeta rawMeta = target.getItemMeta();
+ if (!(rawMeta instanceof EnchantmentStorageMeta meta))
+ continue;
+ Map adjusted = new HashMap<>(meta.getStoredEnchants());
+ if (mode == ChangeMode.SET || mode == ChangeMode.DELETE)
+ adjusted.clear();
+
+ switch (mode) {
+ case DELETE -> {}
+ case ADD, SET -> {
+ assert delta != null;
+ for (Object change : delta) {
+ if (!(change instanceof EnchantmentType type))
+ continue;
+ adjusted.put(type.getType(), type.getLevel());
+ }
+ }
+ case REMOVE, REMOVE_ALL -> {
+ assert delta != null;
+ for (Object change : delta) {
+ if (!(change instanceof EnchantmentType type))
+ continue;
+ if (type.getInternalLevel() == -1) {
+ adjusted.remove(type.getType());
+ } else {
+ adjusted.remove(type.getType(), type.getLevel());
+ }
+ }
+ }
+ default -> throw new IllegalArgumentException("Invalid change mode " + mode);
+ }
+
+ for (Enchantment existing : meta.getStoredEnchants().keySet())
+ meta.removeStoredEnchant(existing);
+
+ for (Map.Entry adjustedEntry : adjusted.entrySet())
+ meta.addStoredEnchant(adjustedEntry.getKey(), adjustedEntry.getValue(), true);
+
+ target.setItemMeta(meta);
+ }
+ }
+
+ @Override
+ public boolean isSingle() {
+ return false;
+ }
+
+ @Override
+ public Class extends EnchantmentType> getReturnType() {
+ return EnchantmentType.class;
+ }
+
+ @Override
+ public String toString(@Nullable Event event, boolean debug) {
+ return "stored enchantments of " + getExpr().toString(event, debug);
+ }
+
+}
diff --git a/src/test/skript/tests/syntaxes/expressions/ExprStoredEnchantments.sk b/src/test/skript/tests/syntaxes/expressions/ExprStoredEnchantments.sk
new file mode 100644
index 00000000000..4fda929099f
--- /dev/null
+++ b/src/test/skript/tests/syntaxes/expressions/ExprStoredEnchantments.sk
@@ -0,0 +1,19 @@
+test "stored enchantments":
+ set {_item} to 3 of minecraft:enchanted_book
+
+ add efficiency 7 to stored enchantments of {_item}
+ add fire aspect 0 to stored enchantments of {_item}
+ assert size of stored enchantments of {_item} is 2 with "did not add 2 stored enchantments"
+ assert stored enchantments of {_item} contain fire aspect 0 with "fire aspect 0 couldn't be added"
+
+ add sharpness to stored enchantments of {_item}
+ assert stored enchantments of {_item} contain sharpness 1 with "sharpness was not added"
+
+ remove fire aspect 2 and efficiency from stored enchants of {_item}
+ assert stored enchantments of {_item} contain fire aspect 0 and sharpness 1 with "did not remove properly"
+
+ clear stored enchantments of {_item}
+ assert stored enchantments of {_item} is not set with "did not clear enchantments properly"
+
+ add sharpness and efficiency to stored enchantments of {_item}
+ assert stored enchantments of {_item} contain sharpness 1 and efficiency 1 with "did not convert properly"