Add optimisation for vanilla enchantment.

This commit is contained in:
alexcrea 2024-06-16 10:44:24 +02:00
parent 27e8fb5719
commit db6cace261
No known key found for this signature in database
GPG key ID: 43FD265DB0DBF91F
2 changed files with 88 additions and 16 deletions

View file

@ -1,16 +1,17 @@
package xyz.alexcrea.cuanvil.enchant; package xyz.alexcrea.cuanvil.enchant;
import io.delilaheve.CustomAnvil; import io.delilaheve.CustomAnvil;
import io.delilaheve.util.ItemUtil;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import xyz.alexcrea.cuanvil.enchant.wrapped.VanillaEnchant; import xyz.alexcrea.cuanvil.enchant.wrapped.VanillaEnchant;
import java.util.HashMap; import java.util.*;
import java.util.Map;
import java.util.logging.Level; import java.util.logging.Level;
/** /**
@ -77,6 +78,14 @@ public abstract class WrappedEnchantment {
*/ */
public final int defaultMaxLevel(){return defaultMaxLevel;} public final int defaultMaxLevel(){return defaultMaxLevel;}
/**
* If the enchantment have specialised group operation.
* @return If the enchantment is optimised for group operation.
*/
protected boolean isOptimised(){
return false;
}
/** /**
* Get current level of the enchantment. * Get current level of the enchantment.
* @param item Item to search the level for. * @param item Item to search the level for.
@ -133,17 +142,35 @@ public abstract class WrappedEnchantment {
* Clear every enchantment from this item. * Clear every enchantment from this item.
* @param item Item to be cleared from enchantments. * @param item Item to be cleared from enchantments.
*/ */
public static void clearEnchants(@NotNull ItemStack item){ //TODO faster method to clear vanilla enchantment public static void clearEnchants(@NotNull ItemStack item){
for (WrappedEnchantment enchant : getEnchants(item).keySet()) { ItemMeta meta = item.getItemMeta();
enchant.removeFrom(item); if(meta == null) return;
// Clean Vanilla enchants
if (ItemUtil.INSTANCE.isEnchantedBook(item)) {
EnchantmentStorageMeta bookMeta = (EnchantmentStorageMeta) meta;
bookMeta.getStoredEnchants().forEach(
(enchantment, leve) -> bookMeta.removeStoredEnchant(enchantment)
);
} else {
item.getEnchantments().forEach(
(enchantment, leve) -> item.removeEnchantment(enchantment)
);
}
// Clean unoptimised enchants
for (WrappedEnchantment enchant : unoptimisedValues()) {
if(enchant.isEnchantmentPresent(item)){
enchant.removeFrom(item);
}
} }
} }
/** /**
* Get enchantments of an item. * Get enchantments of an item.
* @param item item to get enchantment from. * @param item Item to get enchantment from.
* @return a map of the set enchantments and there's respective levels. * @return A map of the set enchantments and there's respective levels.
*/ */
public static Map<WrappedEnchantment, Integer> getEnchants(@NotNull ItemStack item){ //TODO faster method to find vanilla enchantment public static Map<WrappedEnchantment, Integer> getEnchants(@NotNull ItemStack item){ //TODO faster method to find vanilla enchantment
Map<WrappedEnchantment, Integer> enchantments = new HashMap<>(); Map<WrappedEnchantment, Integer> enchantments = new HashMap<>();
@ -151,18 +178,50 @@ public abstract class WrappedEnchantment {
ItemMeta meta = item.getItemMeta(); ItemMeta meta = item.getItemMeta();
if(meta == null) return enchantments; if(meta == null) return enchantments;
for (WrappedEnchantment enchantment : WrappedEnchantment.values()) { // Vanilla optimised get
if (ItemUtil.INSTANCE.isEnchantedBook(item)) {
((EnchantmentStorageMeta)meta).getStoredEnchants().forEach(
(enchantment, level) -> enchantments.put(getByKey(enchantment.getKey()), level)
);
} else {
item.getEnchantments().forEach(
(enchantment, level) -> enchantments.put(getByKey(enchantment.getKey()), level)
);
}
// Unoptimised enchantment get
findEnchantsFromSelectedList(item, meta, enchantments, unoptimisedValues());
return enchantments;
}
/**
* Find enchantments of an item. only test the enchantment from the list.
* @param item Item to get enchantment from.
* @param meta Meta of the provided item.
* @param enchantments Map of enchantment to complete.
* @param enchantmentToTest Enchantment to test
*/
private static void findEnchantsFromSelectedList(
@NotNull ItemStack item,
@NotNull ItemMeta meta,
@NotNull Map<WrappedEnchantment, Integer> enchantments,
@NotNull Collection<WrappedEnchantment> enchantmentToTest){
for (WrappedEnchantment enchantment : enchantmentToTest) {
if(enchantment.isEnchantmentPresent(item, meta)){ if(enchantment.isEnchantmentPresent(item, meta)){
enchantments.put(enchantment, enchantment.getLevel(item, meta)); enchantments.put(enchantment, enchantment.getLevel(item, meta));
} }
} }
return enchantments;
} }
// Register enchantment functions // Register enchantment functions
private static final HashMap<NamespacedKey, WrappedEnchantment> BY_KEY = new HashMap<>(); private static final HashMap<NamespacedKey, WrappedEnchantment> BY_KEY = new HashMap<>();
private static final HashMap<String, WrappedEnchantment> BY_NAME = new HashMap<>(); private static final HashMap<String, WrappedEnchantment> BY_NAME = new HashMap<>();
private static final List<WrappedEnchantment> UNOPTIMISED_ENCHANTMENT = new ArrayList<>();
/** /**
* This should only be called on main of custom anvil. * This should only be called on main of custom anvil.
@ -198,6 +257,10 @@ public abstract class WrappedEnchantment {
BY_KEY.put(enchantment.getKey(), enchantment); BY_KEY.put(enchantment.getKey(), enchantment);
BY_NAME.put(enchantment.getName(), enchantment); BY_NAME.put(enchantment.getName(), enchantment);
if(!enchantment.isOptimised()){
UNOPTIMISED_ENCHANTMENT.add(enchantment);
}
} }
/** /**
@ -241,4 +304,13 @@ public abstract class WrappedEnchantment {
return BY_KEY.values().toArray(new WrappedEnchantment[0]); return BY_KEY.values().toArray(new WrappedEnchantment[0]);
} }
/**
* Gets a list of all the unoptimised enchantments.
* @return List of enchantment.
*/
@NotNull
private static List<WrappedEnchantment> unoptimisedValues() {
return UNOPTIMISED_ENCHANTMENT;
}
} }

View file

@ -1,7 +1,6 @@
package xyz.alexcrea.cuanvil.enchant.wrapped; package xyz.alexcrea.cuanvil.enchant.wrapped;
import io.delilaheve.util.ItemUtil; import io.delilaheve.util.ItemUtil;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.EnchantmentStorageMeta; import org.bukkit.inventory.meta.EnchantmentStorageMeta;
@ -25,9 +24,14 @@ public class VanillaEnchant extends WrappedEnchantment {
} }
@Override
protected boolean isOptimised() {
return true;
}
@Override @Override
public int getLevel(@NotNull ItemStack item, @NotNull ItemMeta meta) { public int getLevel(@NotNull ItemStack item, @NotNull ItemMeta meta) {
if (isEnchantedBook(item)) { if (ItemUtil.INSTANCE.isEnchantedBook(item)) {
return ((EnchantmentStorageMeta)meta).getStoredEnchantLevel(this.enchantment); return ((EnchantmentStorageMeta)meta).getStoredEnchantLevel(this.enchantment);
} else { } else {
return meta.getEnchantLevel(this.enchantment); return meta.getEnchantLevel(this.enchantment);
@ -47,7 +51,7 @@ public class VanillaEnchant extends WrappedEnchantment {
@Override @Override
public void addEnchantmentUnsafe(@NotNull ItemStack item, int level) { public void addEnchantmentUnsafe(@NotNull ItemStack item, int level) {
if (isEnchantedBook(item)) { if (ItemUtil.INSTANCE.isEnchantedBook(item)) {
EnchantmentStorageMeta bookMeta = ((EnchantmentStorageMeta)item.getItemMeta()); EnchantmentStorageMeta bookMeta = ((EnchantmentStorageMeta)item.getItemMeta());
assert bookMeta != null; assert bookMeta != null;
@ -73,10 +77,6 @@ public class VanillaEnchant extends WrappedEnchantment {
} }
public static boolean isEnchantedBook(@NotNull ItemStack item){
return Material.ENCHANTED_BOOK.equals(item.getType());
}
public static EnchantmentRarity getRarity(Enchantment enchantment){ public static EnchantmentRarity getRarity(Enchantment enchantment){
try {return EnchantmentProperties.valueOf(enchantment.getKey().getKey().toUpperCase(Locale.ENGLISH)).getRarity();} try {return EnchantmentProperties.valueOf(enchantment.getKey().getKey().toUpperCase(Locale.ENGLISH)).getRarity();}
catch (IllegalArgumentException ignored) {} catch (IllegalArgumentException ignored) {}