Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🚀 Enchantment Improvements #4366

Closed
Closed
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
a672464
🚀 Support stored enchantments
AyhamAl-Ali Oct 15, 2021
bc52165
Fix #1836
AyhamAl-Ali Oct 15, 2021
4564525
Add has conflicting enchantments condition (#4245)
AyhamAl-Ali Oct 16, 2021
782ce15
Added null checker
AyhamAl-Ali Oct 19, 2021
e8b83b3
Fix return type of ItemWithEnchantments Expr
AyhamAl-Ali Oct 19, 2021
9189377
Merge branch 'master' into ench/stored-ench
AyhamAl-Ali Nov 4, 2021
029720e
Merge branch 'master' into ench/stored-ench
AyhamAl-Ali Dec 12, 2021
11e0e8e
Add disenchant specific enchantments
AyhamAl-Ali Dec 12, 2021
c6b7cf9
Merge branch 'master' into ench/stored-ench
AyhamAl-Ali Jan 27, 2022
de7e9dd
Apply suggestions from code review
AyhamAl-Ali Mar 5, 2022
e616818
Merge branch 'master' into ench/stored-ench
AyhamAl-Ali Mar 5, 2022
eaf7f57
Update src/main/java/ch/njol/skript/conditions/CondHasConflictingEnch…
AyhamAl-Ali Jan 1, 2023
cfe81d2
Requested changes - Improvements
AyhamAl-Ali Mar 17, 2023
429a6df
EffEnchant pattern improvement
AyhamAl-Ali Mar 17, 2023
8643058
Apply suggestions from code review
AyhamAl-Ali Mar 17, 2023
48f75ba
Update src/main/java/ch/njol/skript/aliases/ItemType.java
AyhamAl-Ali Mar 17, 2023
2398bde
Requested changes
AyhamAl-Ali Mar 17, 2023
eddd8b6
Merge remote-tracking branch 'AyhamAl-Ali/ench/stored-ench' into ench…
AyhamAl-Ali Mar 17, 2023
7078f60
Indentations
AyhamAl-Ali Mar 17, 2023
a139e22
Fix EffEnchant pattern
AyhamAl-Ali Apr 5, 2024
1cc0840
Update toString
AyhamAl-Ali Apr 5, 2024
d0e6451
Merge remote-tracking branch 'origin/dev/feature' into ench/stored-ench
AyhamAl-Ali Apr 5, 2024
fd4c257
add useful comments
AyhamAl-Ali Apr 5, 2024
e52049e
fix building
AyhamAl-Ali Apr 5, 2024
0560dc1
Updated submodule skript-aliases
AyhamAl-Ali Apr 5, 2024
581813e
Add tests
AyhamAl-Ali Apr 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 119 additions & 1 deletion src/main/java/ch/njol/skript/aliases/ItemType.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
import org.bukkit.inventory.meta.ItemMeta;
import org.eclipse.jdt.annotation.Nullable;

Expand Down Expand Up @@ -1200,7 +1201,7 @@ public boolean hasEnchantments(EnchantmentType... enchantments) {
assert type != null; // Bukkit working different than we expect
if (!meta.hasEnchant(type))
return false;
if (enchantment.getInternalLevel() != -1 && meta.getEnchantLevel(type) < enchantment.getLevel())
if (enchantment.getInternalLevel() != -1 && meta.getEnchantLevel(type) != enchantment.getLevel())
return false;
}
return true;
Expand Down Expand Up @@ -1250,6 +1251,109 @@ public void clearEnchantments() {
}
setItemMeta(meta);
}

/**
* Gets all stored enchantments of this item.
* @return the stored enchantments of this item type.
*/
@Nullable
public EnchantmentType[] getStoredEnchantmentTypes() {
EnchantmentStorageMeta meta = getEnchantmentStorageMeta();
if (meta == null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this also check !meta.hasStoredEnchants()?

return new EnchantmentType[0];
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved

Set<Entry<Enchantment, Integer>> enchants = meta.getStoredEnchants().entrySet();
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved

return enchants.stream()
.map(enchant -> new EnchantmentType(enchant.getKey(), enchant.getValue()))
.toArray(EnchantmentType[]::new);
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* Checks whether this item type has stored enchantments.
* Used for materials such as {@link Material#ENCHANTED_BOOK}
*/
public boolean hasStoredEnchantments() {
ItemType type = getBaseType();
ItemMeta meta = type.getItemMeta();
if (meta instanceof EnchantmentStorageMeta)
return ((EnchantmentStorageMeta) meta).hasStoredEnchants();
else
return false;
}

/**
* Checks whether this item type contains the given stored enchantments.
* Also checks the enchantment level.
* @param enchantments The enchantments to be checked.
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
*/
public boolean hasStoredEnchantments(EnchantmentType... enchantments) {
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
EnchantmentStorageMeta meta = getEnchantmentStorageMeta();
if (meta == null)
return false;
if (!hasStoredEnchantments())
return false;

for (EnchantmentType enchantment : enchantments) {
Enchantment type = enchantment.getType();
assert type != null; // Bukkit working different than we expect
if (!meta.hasStoredEnchant(type))
return false;
if (enchantment.getInternalLevel() != -1 && meta.getStoredEnchantLevel(type) != enchantment.getLevel())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-1 represents an enchantment type without a specific level (e.g. it has any level of X stored) right?

Maybe we should move this into a public field on EnchantmentType with docs. Or maybe better, a method like representsAnyLevel (we could come up with a better name lol)

return false;
}
return true;
}

/**
* Adds the given enchantments to the stored enchantments of this item type.
* @param enchantments The enchantments to be added.
*/
public void addStoredEnchantments(EnchantmentType... enchantments) {
EnchantmentStorageMeta meta = getEnchantmentStorageMeta();
if (meta == null)
return;

for (EnchantmentType enchantment : enchantments) {
Enchantment type = enchantment.getType();
assert type != null; // Bukkit working different than we expect
meta.addStoredEnchant(type, enchantment.getLevel(), true);
}
setItemMeta(meta);
}

/**
* Removes the given enchantments from the stored enchantments of this item type.
* @param enchantments The enchantments to be removed.
*/
public void removeStoredEnchantments(EnchantmentType... enchantments) {
EnchantmentStorageMeta meta = getEnchantmentStorageMeta();
if (meta == null)
return;

for (EnchantmentType enchantment : enchantments) {
Enchantment type = enchantment.getType();
assert type != null; // Bukkit working different than we expect
meta.removeStoredEnchant(type);
}
setItemMeta(meta);
}

/**
* Clears all stored enchantments from this item type
*/
public void clearStoredEnchantments() {
EnchantmentStorageMeta meta = getEnchantmentStorageMeta();
if (meta == null)
return;

Set<Enchantment> enchants = meta.getStoredEnchants().keySet();
for (Enchantment ench : enchants) {
assert ench != null;
meta.removeStoredEnchant(ench);
}
setItemMeta(meta);
}

/**
* Gets item meta that applies to all items represented by this type.
Expand All @@ -1259,6 +1363,20 @@ public ItemMeta getItemMeta() {
return globalMeta != null ? globalMeta : types.get(0).getItemMeta();
}

/**
* Gets {@link EnchantmentStorageMeta} that applies to all items represented by this type if possible.
* @return Item meta.
*/
@Nullable
public EnchantmentStorageMeta getEnchantmentStorageMeta() {
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
if (globalMeta != null && globalMeta instanceof EnchantmentStorageMeta)
return (EnchantmentStorageMeta) globalMeta;
else if (types.get(0).getItemMeta() instanceof EnchantmentStorageMeta)
return (EnchantmentStorageMeta) types.get(0).getItemMeta();
else
return null;
}

/**
* Sets item meta that is applied for everything this type represents.
* Note that previous item meta is overridden if it exists.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/**
* This file is part of Skript.
*
* Skript is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Skript is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Skript. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright Peter Güttinger, SkriptLang team and contributors
*/
package ch.njol.skript.conditions;

import ch.njol.skript.aliases.ItemType;
import ch.njol.skript.conditions.base.PropertyCondition;
import ch.njol.skript.conditions.base.PropertyCondition.PropertyType;
import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Examples;
import ch.njol.skript.doc.Name;
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;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.event.Event;
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
import org.bukkit.inventory.meta.ItemMeta;
import org.eclipse.jdt.annotation.Nullable;

@Name("Has Conflicting Enchantments")
@Description("Checks whether an item has conflicting enchantments with the given enchantment.")
@Examples({"player's tool has conflicting enchantments with efficiency",
"event-item has conflicting stored enchantments with power"})
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
@Since("INSERT VERSION")
public class CondHasConflictingEnchantments extends Condition {

static {
PropertyCondition.register(CondHasConflictingEnchantments.class, PropertyType.HAVE,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about a "can be enchanted with" condition? Do you think that reflects the property well?

"conflicting [(1¦stored)] enchant[ment]s with %enchantment%", "itemtypes");
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
}

@SuppressWarnings("NotNullFieldNotInitialized")
private Expression<ItemType> items;
@SuppressWarnings("NotNullFieldNotInitialized")
private Expression<Enchantment> ench;
private boolean isStored;

@Override
@SuppressWarnings({"unchecked", "null"})
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
items = (Expression<ItemType>) exprs[0];
ench = (Expression<Enchantment>) exprs[1];
isStored = parseResult.mark > 0;
setNegated(matchedPattern == 1);
return true;
}

@Override
public boolean check(Event e) {
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
Enchantment ench = this.ench.getSingle(e);
if (ench == null)
return false;

return items.check(e, item ->
{
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
ItemMeta meta = item.getItemMeta();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you could use the method added to ItemType right?

if ((isStored && meta instanceof EnchantmentStorageMeta)) {
return ((EnchantmentStorageMeta) meta).hasConflictingStoredEnchant(ench);
Comment on lines +76 to +77
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if ((isStored && meta instanceof EnchantmentStorageMeta)) {
return ((EnchantmentStorageMeta) meta).hasConflictingStoredEnchant(ench);
if (isStored && meta instanceof EnchantmentStorageMeta enchantmentStorageMeta) {
return enchantmentStorageMeta.hasConflictingStoredEnchant(ench);

} else {
return meta.hasConflictingEnchant(ench);
}
}, isNegated());
}

@Override
public String toString(@Nullable Event e, boolean debug) {
return PropertyCondition.toString(this, PropertyType.HAVE, e, debug, items,
"conflicting " + (isStored ? "stored " : "") + "enchantments with " + ench.toString(e, debug));
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
}

}
37 changes: 21 additions & 16 deletions src/main/java/ch/njol/skript/conditions/CondIsEnchanted.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package ch.njol.skript.conditions;

import org.bukkit.event.Event;
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
import org.eclipse.jdt.annotation.Nullable;

import ch.njol.skript.aliases.ItemType;
Expand All @@ -34,49 +35,53 @@
import ch.njol.skript.util.EnchantmentType;
import ch.njol.util.Kleenean;

/**
* @author Peter Güttinger
*/
@Name("Is Enchanted")
@Description("Checks whether an item is enchanted.")
@Examples({"tool of the player is enchanted with efficiency 2",
"helm, chestplate, leggings or boots are enchanted"})
@Since("1.4.6")
"helm, chestplate, leggings or boots are enchanted",
"",
"# For enchanted books",
"player's tool is stored enchanted",
"event-item is enchanted with stored power 2"})
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
@Since("1.4.6, INSERT VERSION (stored enchantments)")
public class CondIsEnchanted extends Condition {
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved

static {
PropertyCondition.register(CondIsEnchanted.class, "enchanted [with %-enchantmenttype%]", "itemtypes");
PropertyCondition.register(CondIsEnchanted.class,
"[(1¦stored[ly])] enchanted [with %-enchantmenttype%]", "itemtypes");
}

@SuppressWarnings("NotNullFieldNotInitialized")
private Expression<ItemType> items;
@Nullable
private Expression<EnchantmentType> enchs;
private boolean isStored;

@SuppressWarnings({"unchecked", "null"})
@Override
public boolean init(final Expression<?>[] exprs, final int matchedPattern, final Kleenean isDelayed, final ParseResult parseResult) {
@SuppressWarnings({"unchecked", "null"})
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
items = (Expression<ItemType>) exprs[0];
enchs = (Expression<EnchantmentType>) exprs[1];
isStored = parseResult.mark > 0;
setNegated(matchedPattern == 1);
return true;
}

@Override
public boolean check(final Event e) {
public boolean check(Event e) {
if (enchs != null)
return items.check(e, item -> enchs.check(e, item::hasEnchantments), isNegated());
return items.check(e, item ->
(isStored && item.getItemMeta() instanceof EnchantmentStorageMeta) ? enchs.check(e, item::hasStoredEnchantments) : enchs.check(e, item::hasEnchantments), isNegated());
else
return items.check(e, ItemType::hasEnchantments, isNegated());

return items.check(e, item ->
(isStored && item.getItemMeta() instanceof EnchantmentStorageMeta) ? item.hasStoredEnchantments() : item.hasEnchantments(), isNegated());

}

@Override
public String toString(final @Nullable Event e, final boolean debug) {
final Expression<EnchantmentType> es = enchs;

public String toString(@Nullable Event e, boolean debug) {
return PropertyCondition.toString(this, PropertyType.BE, e, debug, items,
"enchanted" + (es == null ? "" : " with " + es.toString(e, debug)));
(isStored ? "stored " : "") + "enchanted" + (enchs == null ? "" : " with " + enchs.toString(e, debug)));
}

}
Loading