Some changes for this version:
- Tried to make compatible with some legacy version of eco enchant (not assumed to work)
- Fix some enchantment test from other plugin not being taken into account. 
Should work as expected now, but that mean it may not work as currently.
- Made Heaven bag works
- Updated Disenchantment, should work with disenchantment version >= 6.1.0. But break support for previous versions
This commit is contained in:
alexcrea 2025-01-20 18:20:46 +01:00 committed by GitHub
parent 4147f018a9
commit 5f557e3d49
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
31 changed files with 503 additions and 102 deletions

View file

@ -64,7 +64,10 @@ Officially supported but still experimental. use ExcellentEnchants item type.
Here is a list of supported anvil mechanic plugins with support status: Here is a list of supported anvil mechanic plugins with support status:
- [Disenchantment](https://www.spigotmc.org/resources/disenchantment-1-21-1-1-20-6-new-book-splitting-mechanics.110741/) - [Disenchantment](https://www.spigotmc.org/resources/disenchantment-1-21-1-1-20-6-new-book-splitting-mechanics.110741/)
Officially supported by Custom Anvil but still experimental. Mostly use Custom Anvil basic XP settings. (version >= 5.4.0) Officially supported by Custom Anvil but still experimental. Mostly use Custom Anvil basic XP settings. (version >= 6.1.0)
- [HavenBags](https://www.spigotmc.org/resources/havenbags-shulker-like-player-bound-bags-1-17-1-21-4.110420/)
Officially supported by Custom Anvil. Not really enchantment related but CustomAnvil should not impact bag upgrade and skin via anvil.
If you like Custom Anvil to support a specific plugin (custom enchant or anvil mechanic). If you like Custom Anvil to support a specific plugin (custom enchant or anvil mechanic).
You can ask, but please note implementing compatibility will be considered You can ask, but please note implementing compatibility will be considered

View file

@ -3,20 +3,20 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins { plugins {
kotlin("jvm") version "2.0.21" kotlin("jvm") version "2.1.0"
java java
id("org.jetbrains.dokka").version("1.9.20") id("org.jetbrains.dokka").version("1.9.20")
id("com.gradleup.shadow").version("8.3.3") id("com.gradleup.shadow").version("8.3.5")
// Maven publish // Maven publish
`maven-publish` `maven-publish`
signing signing
id("cn.lalaki.central").version("1.2.5") id("cn.lalaki.central").version("1.2.5")
// Paper // Paper
id("io.papermc.paperweight.userdev") version "1.7.3" apply false id("io.papermc.paperweight.userdev") version "2.0.0-beta.14" apply false
} }
group = "xyz.alexcrea" group = "xyz.alexcrea"
version = "1.6.13" version = "1.7.0"
repositories { repositories {
// EcoEnchants // EcoEnchants
@ -37,16 +37,20 @@ dependencies {
compileOnly(files("libs/EnchantsSquared.jar")) compileOnly(files("libs/EnchantsSquared.jar"))
// EcoEnchants // EcoEnchants
compileOnly("com.willfp:EcoEnchants:12.5.1") compileOnly("com.willfp:EcoEnchants:12.11.1")
compileOnly("com.willfp:eco:6.70.1") compileOnly("com.willfp:eco:6.74.5")
compileOnly(project(":impl:LegacyEcoEnchant"))
// ExcellentEnchants // ExcellentEnchants
compileOnly(files("libs/nightcore-2.6.4.jar")) compileOnly(files("libs/nightcore-2.7.3.jar"))
compileOnly(files("libs/ExcellentEnchants-4.2.2.jar")) compileOnly(files("libs/ExcellentEnchants-4.3.1.jar"))
compileOnly(files("libs/ExcellentEnchants 4.1.0-striped.jar")) compileOnly(files("libs/ExcellentEnchants 4.1.0-striped.jar")) // For legacy excellent enchants
// Disenchantment // Disenchantment
compileOnly("cz.kominekjan:Disenchantment:v5.4.0") compileOnly(files("libs/Disenchantment-6.1.0.jar"))
// HavenBags
compileOnly(files("libs/HavenBags-1.30.1.1729.jar"))
// Include nms // Include nms
implementation(project(":nms:nms-common")) implementation(project(":nms:nms-common"))
@ -62,13 +66,13 @@ dependencies {
implementation(project(":nms:v1_20R4", configuration = "reobf")) implementation(project(":nms:v1_20R4", configuration = "reobf"))
implementation(project(":nms:v1_21R1", configuration = "reobf")) implementation(project(":nms:v1_21R1", configuration = "reobf"))
implementation(project(":nms:v1_21R2", configuration = "reobf")) implementation(project(":nms:v1_21R2", configuration = "reobf"))
implementation(project(":nms:v1_21R3"))//, configuration = "reobf")) // TODO add again when paperweigh 1.21.4 update implementation(project(":nms:v1_21R3", configuration = "reobf"))
// include kotlin for the offline jar // include kotlin for the offline jar
implementation(kotlin("stdlib")) implementation(kotlin("stdlib"))
// Test dependency // Test dependency
testImplementation("org.mockbukkit.mockbukkit:mockbukkit-v1.21:4.9.3") //lower bound: 4.9.2 upper bound: 4.9.3 testImplementation("org.mockbukkit.mockbukkit:mockbukkit-v1.21:4.21.0")
testRuntimeOnly("commons-lang:commons-lang:2.6") testRuntimeOnly("commons-lang:commons-lang:2.6")
} }
@ -150,7 +154,7 @@ tasks {
filesMatching("plugin.yml") { filesMatching("plugin.yml") {
expand( expand(
"version" to project.version, "version" to project.version,
"libraries" to " \"org.jetbrains.kotlin:kotlin-stdlib:2.0.21\" " "libraries" to " \"org.jetbrains.kotlin:kotlin-stdlib:2.1.0\" "
) )
} }
@ -159,27 +163,34 @@ tasks {
} }
// Offline jar (include kotlin std in the final jar fine) // Offline jar (include kotlin std in the final jar fine)
val offlineJar by creating(ShadowJar::class) { val offlineJar by // Shadow necessary dependency
archiveClassifier.set("offline") registering(
// Shadow necessary dependency
relocate("com.github.stefvanschie.inventoryframework", "xyz.alexcrea.inventoryframework")
filesMatching("plugin.yml") {
expand(
"version" to "${project.version}-offline",
"libraries" to ""
)
}
// Include all project other dependencies // Include all project other dependencies
from(project.configurations.runtimeClasspath) ShadowJar
// Add custom anvil compiled // Add custom anvil compiled
from(sourceSets.main.get().output) ::class, fun ShadowJar.() {
archiveClassifier.set("offline")
dependsOn(processResources) // Shadow necessary dependency
} relocate("com.github.stefvanschie.inventoryframework", "xyz.alexcrea.inventoryframework")
filesMatching("plugin.yml") {
expand(
"version" to "${project.version}-offline",
"libraries" to ""
)
}
// Include all project other dependencies
from(project.configurations.runtimeClasspath)
// Add custom anvil compiled
from(sourceSets.main.get().output)
dependsOn(processResources)
})
// Make the online and offline jar on build // Make the online and offline jar on build
named("build") { named("build") {
@ -193,12 +204,12 @@ val sourcesJar by tasks.registering(Jar::class) {
from(kotlin.sourceSets.main.get().kotlin) from(kotlin.sourceSets.main.get().kotlin)
} }
val javadocJar by tasks.creating(Jar::class) { val javadocJar by tasks.registering(Jar::class, fun Jar.() {
group = JavaBasePlugin.DOCUMENTATION_GROUP group = JavaBasePlugin.DOCUMENTATION_GROUP
description = "Assembles Javadoc JAR" description = "Assembles Javadoc JAR"
archiveClassifier.set("javadoc") archiveClassifier.set("javadoc")
from(tasks.named("dokkaHtml")) from(tasks.named("dokkaHtml"))
} })
signing { signing {
useGpgCmd() useGpgCmd()

View file

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View file

@ -0,0 +1,15 @@
group = rootProject.group
version = rootProject.version
plugins {
kotlin("jvm") version "2.1.0"
}
// Imitate needed class and method to support legacy version of EcoEnchant
dependencies {
// Spigot api
compileOnly("org.spigotmc:spigot-api:1.18-R0.1-SNAPSHOT")
}

View file

@ -0,0 +1,26 @@
package com.willfp.ecoenchants.enchantments;
import com.willfp.ecoenchants.enchantments.meta.EnchantmentTarget;
import com.willfp.ecoenchants.enchantments.meta.EnchantmentType;
import org.bukkit.enchantments.Enchantment;
import org.jetbrains.annotations.NotNull;
import java.util.Set;
/**
* Mock class for legacy package of eco enchants
*/
public class EcoEnchant {
public boolean conflictsWith(@NotNull Enchantment enchant) {
return false;
}
public Set<EnchantmentTarget> getTargets() {
return null;
}
public EnchantmentType getType() {
return null;
}
}

View file

@ -0,0 +1,14 @@
package com.willfp.ecoenchants.enchantments;
import java.util.List;
/**
* Mock class for legacy package of eco enchants
*/
public class EcoEnchants {
public static List<EcoEnchant> values(){
return null; // We don't care here.
}
}

View file

@ -0,0 +1,16 @@
package com.willfp.ecoenchants.enchantments.meta;
import org.bukkit.Material;
import java.util.Set;
/**
* Mock class for legacy package of eco enchants
*/
public class EnchantmentTarget {
public Set<Material> getMaterials() {
return null;
}
}

View file

@ -0,0 +1,9 @@
package com.willfp.ecoenchants.enchantments.meta;
public class EnchantmentType {
public boolean isSingular() {
return false;
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
libs/nightcore-2.7.3.jar Normal file

Binary file not shown.

View file

@ -24,7 +24,7 @@ repositories {
// Configure used version of kotlin and java // Configure used version of kotlin and java
java { java {
disableAutoTargetJvm() disableAutoTargetJvm()
toolchain.languageVersion.set(JavaLanguageVersion.of(16)) toolchain.languageVersion.set(JavaLanguageVersion.of(17))
} }
// Set target version // Set target version

View file

@ -1,14 +1,5 @@
import java.net.URI
rootProject.name = "CustomAnvil" rootProject.name = "CustomAnvil"
// for Disenchantment dependency
sourceControl {
gitRepository(URI.create("https://github.com/H7KZ/Disenchantment.git")) {
producesModule("cz.kominekjan:Disenchantment")
}
}
// NMS subproject // NMS subproject
include("nms:nms-common") include("nms:nms-common")
findProject(":nms:nms-common")?.name = "nms-common" findProject(":nms:nms-common")?.name = "nms-common"
@ -38,3 +29,6 @@ include("nms:v1_21R2")
findProject(":nms:v1_21R2")?.name = "v1_21R2" findProject(":nms:v1_21R2")?.name = "v1_21R2"
include("nms:v1_21R3") include("nms:v1_21R3")
findProject(":nms:v1_21R3")?.name = "v1_21R3" findProject(":nms:v1_21R3")?.name = "v1_21R3"
include(":impl:LegacyEcoEnchant")
findProject(":impl:LegacyEcoEnchant")?.name = "LegacyEcoEnchant"

View file

@ -5,6 +5,7 @@ import org.bukkit.NamespacedKey;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.enchant.bulk.BukkitEnchantBulkOperation; import xyz.alexcrea.cuanvil.enchant.bulk.BukkitEnchantBulkOperation;
import xyz.alexcrea.cuanvil.enchant.bulk.BulkCleanEnchantOperation; import xyz.alexcrea.cuanvil.enchant.bulk.BulkCleanEnchantOperation;
import xyz.alexcrea.cuanvil.enchant.bulk.BulkGetEnchantOperation; import xyz.alexcrea.cuanvil.enchant.bulk.BulkGetEnchantOperation;
@ -16,6 +17,7 @@ import java.util.logging.Level;
public class CAEnchantmentRegistry { public class CAEnchantmentRegistry {
private static final CAEnchantmentRegistry instance = new CAEnchantmentRegistry(); private static final CAEnchantmentRegistry instance = new CAEnchantmentRegistry();
public static CAEnchantmentRegistry getInstance() { public static CAEnchantmentRegistry getInstance() {
return instance; return instance;
} }
@ -49,7 +51,7 @@ public class CAEnchantmentRegistry {
* This should only be called on main of custom anvil. * This should only be called on main of custom anvil.
* If called more than one time, chance of thing being broken will be high. * If called more than one time, chance of thing being broken will be high.
*/ */
public void registerBukkit(){ public void registerBukkit() {
// Register enchantment // Register enchantment
for (Enchantment enchantment : Enchantment.values()) { for (Enchantment enchantment : Enchantment.values()) {
register(new CABukkitEnchantment(enchantment)); register(new CABukkitEnchantment(enchantment));
@ -59,7 +61,6 @@ public class CAEnchantmentRegistry {
BukkitEnchantBulkOperation bukkitOperation = new BukkitEnchantBulkOperation(); BukkitEnchantBulkOperation bukkitOperation = new BukkitEnchantBulkOperation();
optimisedGetOperators.add(bukkitOperation); optimisedGetOperators.add(bukkitOperation);
optimisedCleanOperators.add(bukkitOperation); optimisedCleanOperators.add(bukkitOperation);
} }
private static boolean hasWarnedRegistering = false; private static boolean hasWarnedRegistering = false;
@ -69,20 +70,30 @@ public class CAEnchantmentRegistry {
* <p> * <p>
* No guarantee that the enchantment will be present on the config gui if registered late. * No guarantee that the enchantment will be present on the config gui if registered late.
* (By late I mean after custom anvil startup.) * (By late I mean after custom anvil startup.)
*
* @param enchantment The enchantment to be registered. * @param enchantment The enchantment to be registered.
* @return If the operation was successful. * @return If the operation was successful.
*/ */
public boolean register(@NotNull CAEnchantment enchantment){ public boolean register(@NotNull CAEnchantment enchantment) {
if(byKeyMap.containsKey(enchantment.getKey())){ if (byKeyMap.containsKey(enchantment.getKey())) {
if (!enchantment.equals(byKeyMap.get(enchantment.getKey()))) {
// We are trying to register the exact same enchantment. so we just skip it.
return false;
}
if(ConfigHolder.DEFAULT_CONFIG.getConfig().getBoolean("caution_secret_do_not_log_duplicated_registered_key", false)){
return false;
}
CustomAnvil.instance.getLogger().log(Level.WARNING, CustomAnvil.instance.getLogger().log(Level.WARNING,
"Duplicate registered enchantment. This should NOT happen any time.\n" + "Duplicate distinct registered enchantment. This should NOT happen any time.\n" +
"If you are a custom anvil developer. You maybe custom anvil detected your enchantment as a bukkit enchantment. " + "If you are a custom anvil developer: Maybe custom anvil detected your enchantment as a bukkit enchantment. " +
"maybe remove enchantment with the same key before registering yours", "you should maybe remove enchantment with the same key before registering yours",
new IllegalStateException(enchantment.getKey()+" enchantment was already registered")); new IllegalStateException("enchantment " + enchantment.getKey() + " was already registered"));
return false; return false;
} }
if((!hasWarnedRegistering) && byNameMap.containsKey(enchantment.getName())){ if ((!hasWarnedRegistering) && byNameMap.containsKey(enchantment.getName())) {
hasWarnedRegistering = true; hasWarnedRegistering = true;
CustomAnvil.instance.getLogger().log(Level.WARNING, CustomAnvil.instance.getLogger().log(Level.WARNING,
@ -96,10 +107,10 @@ public class CAEnchantmentRegistry {
nameSortedEnchantments.add(enchantment); nameSortedEnchantments.add(enchantment);
if(!enchantment.isGetOptimised()){ if (!enchantment.isGetOptimised()) {
unoptimisedGetValues.add(enchantment); unoptimisedGetValues.add(enchantment);
} }
if(!enchantment.isCleanOptimised()){ if (!enchantment.isCleanOptimised()) {
unoptimisedCleanValues.add(enchantment); unoptimisedCleanValues.add(enchantment);
} }
@ -113,12 +124,13 @@ public class CAEnchantmentRegistry {
* <p> * <p>
* No guarantee that the enchantment will absent if the config guis if unregistered late. * No guarantee that the enchantment will absent if the config guis if unregistered late.
* (By late I mean after custom anvil startup.) * (By late I mean after custom anvil startup.)
*
* @param enchantment The enchantment to be unregistered. * @param enchantment The enchantment to be unregistered.
* @return If the operation was successful. * @return If the operation was successful.
*/ */
public boolean unregister(@Nullable CAEnchantment enchantment){ public boolean unregister(@Nullable CAEnchantment enchantment) {
if(enchantment == null) return false; if (enchantment == null) return false;
byKeyMap.remove(enchantment.getKey()); byKeyMap.remove(enchantment.getKey());
byNameMap.get(enchantment.getName()).remove(enchantment); byNameMap.get(enchantment.getName()).remove(enchantment);
@ -131,42 +143,45 @@ public class CAEnchantmentRegistry {
/** /**
* Gets the enchantment by the provided key. * Gets the enchantment by the provided key.
*
* @param key Key to fetch. * @param key Key to fetch.
* @return Registered enchantment. null if absent. * @return Registered enchantment. null if absent.
*/ */
@Nullable @Nullable
public CAEnchantment getByKey(@NotNull NamespacedKey key){ public CAEnchantment getByKey(@NotNull NamespacedKey key) {
return byKeyMap.get(key); return byKeyMap.get(key);
} }
/** /**
* Gets the enchantment by the provided name. * Gets the enchantment by the provided name.
*
* @param name Name to fetch. * @param name Name to fetch.
* @return Registered enchantment. null if absent. * @return Registered enchantment. null if absent.
*
* @deprecated use {@link #getListByName(String)} * @deprecated use {@link #getListByName(String)}
*/ */
@Deprecated(since = "1.6.3") @Deprecated(since = "1.6.3")
@Nullable @Nullable
public CAEnchantment getByName(@NotNull String name){ public CAEnchantment getByName(@NotNull String name) {
List<CAEnchantment> enchantments = getListByName(name); List<CAEnchantment> enchantments = getListByName(name);
if(enchantments.isEmpty()) return null; if (enchantments.isEmpty()) return null;
return enchantments.get(0); return enchantments.get(0);
} }
/** /**
* Gets list of enchantment using the provided name. * Gets list of enchantment using the provided name.
*
* @param name Name to fetch. * @param name Name to fetch.
* @return List of registered enchantment. * @return List of registered enchantment.
*/ */
@NotNull @NotNull
public List<CAEnchantment> getListByName(@NotNull String name){ public List<CAEnchantment> getListByName(@NotNull String name) {
return byNameMap.getOrDefault(name, Collections.emptyList()); return byNameMap.getOrDefault(name, Collections.emptyList());
} }
/** /**
* Gets an array of all the registered enchantments. * Gets an array of all the registered enchantments.
*
* @return Array of enchantments. * @return Array of enchantments.
*/ */
@NotNull @NotNull
@ -176,6 +191,7 @@ public class CAEnchantmentRegistry {
/** /**
* Gets a map of all the registered enchantments. * Gets a map of all the registered enchantments.
*
* @return Immutable map of enchantments. * @return Immutable map of enchantments.
*/ */
public Map<NamespacedKey, CAEnchantment> registeredEnchantments() { public Map<NamespacedKey, CAEnchantment> registeredEnchantments() {
@ -184,6 +200,7 @@ public class CAEnchantmentRegistry {
/** /**
* Gets a list of all the unoptimised get operation enchantments. * Gets a list of all the unoptimised get operation enchantments.
*
* @return List of unoptimised enchantments. * @return List of unoptimised enchantments.
*/ */
@NotNull @NotNull
@ -193,6 +210,7 @@ public class CAEnchantmentRegistry {
/** /**
* Gets a list of all the unoptimised clean operation enchantments. * Gets a list of all the unoptimised clean operation enchantments.
*
* @return List of unoptimised enchantments. * @return List of unoptimised enchantments.
*/ */
@NotNull @NotNull
@ -202,6 +220,7 @@ public class CAEnchantmentRegistry {
/** /**
* Get "clean optimised operation" for get enchantments. * Get "clean optimised operation" for get enchantments.
*
* @return Mutable "clean enchantments optimised operation" list. * @return Mutable "clean enchantments optimised operation" list.
*/ */
public List<BulkCleanEnchantOperation> getOptimisedCleanOperators() { public List<BulkCleanEnchantOperation> getOptimisedCleanOperators() {
@ -210,6 +229,7 @@ public class CAEnchantmentRegistry {
/** /**
* Get "get optimised operation" for get enchantments. * Get "get optimised operation" for get enchantments.
*
* @return Mutable "get enchantments optimised operation" list. * @return Mutable "get enchantments optimised operation" list.
*/ */
public List<BulkGetEnchantOperation> getOptimisedGetOperators() { public List<BulkGetEnchantOperation> getOptimisedGetOperators() {
@ -218,6 +238,7 @@ public class CAEnchantmentRegistry {
/** /**
* Get custom anvil enchantment sorted by name. * Get custom anvil enchantment sorted by name.
*
* @return An immutable sorted set of every registered enchantment sorted by name. * @return An immutable sorted set of every registered enchantment sorted by name.
*/ */
public SortedSet<CAEnchantment> getNameSortedEnchantments() { public SortedSet<CAEnchantment> getNameSortedEnchantments() {

View file

@ -1,7 +1,9 @@
package xyz.alexcrea.cuanvil.enchant.bulk; package xyz.alexcrea.cuanvil.enchant.bulk;
import io.delilaheve.CustomAnvil;
import io.delilaheve.util.ItemUtil; import io.delilaheve.util.ItemUtil;
import org.bukkit.Material; import org.bukkit.Material;
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;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
@ -14,18 +16,29 @@ import java.util.Map;
public class BukkitEnchantBulkOperation implements BulkGetEnchantOperation, BulkCleanEnchantOperation { public class BukkitEnchantBulkOperation implements BulkGetEnchantOperation, BulkCleanEnchantOperation {
@Override @Override
public void bulkGet(@NotNull Map<CAEnchantment, Integer> enchantmentList, @NotNull ItemStack item, @NotNull ItemMeta meta) { public void bulkGet(@NotNull Map<CAEnchantment, Integer> enchantmentMap, @NotNull ItemStack item, @NotNull ItemMeta meta) {
if (ItemUtil.INSTANCE.isEnchantedBook(item)) { if (ItemUtil.INSTANCE.isEnchantedBook(item)) {
((EnchantmentStorageMeta)meta).getStoredEnchants().forEach((enchantment, level) -> ((EnchantmentStorageMeta) meta).getStoredEnchants().forEach((enchantment, level) ->
enchantmentList.put(EnchantmentApi.getByKey(enchantment.getKey()), level) addEnchantment(enchantmentMap, enchantment, level)
); );
} else { } else {
item.getEnchantments().forEach((enchantment, level) -> item.getEnchantments().forEach((enchantment, level) ->
enchantmentList.put(EnchantmentApi.getByKey(enchantment.getKey()), level) addEnchantment(enchantmentMap, enchantment, level)
); );
} }
} }
public void addEnchantment(@NotNull Map<CAEnchantment, Integer> enchantmentMap, @NotNull Enchantment enchantment, int level) {
CAEnchantment enchant = EnchantmentApi.getByKey(enchantment.getKey());
if (enchant == null) {
CustomAnvil.instance.getLogger().warning("Enchantment of key " + enchantment.getKey() +
" somehow not found in CustomAnvil ?");
return;
}
enchantmentMap.put(enchant, level);
}
@Override @Override
public void bulkClear(@NotNull ItemStack item) { public void bulkClear(@NotNull ItemStack item) {
if (item.getType() != Material.ENCHANTED_BOOK) { if (item.getType() != Material.ENCHANTED_BOOK) {

View file

@ -14,10 +14,10 @@ public interface BulkGetEnchantOperation {
/** /**
* Bulk get part of the stored enchantment of this item. * Bulk get part of the stored enchantment of this item.
* @param enchantmentList Mutable map of collected enchantment. should b * @param enchantmentMap Mutable map of collected enchantment. should b
* @param item The item to get enchantment from. Should not get edited. * @param item The item to get enchantment from. Should not get edited.
* @param meta The item meta to get enchantment from. Should not get edited. * @param meta The item meta to get enchantment from. Should not get edited.
*/ */
void bulkGet(@NotNull Map<CAEnchantment, Integer> enchantmentList, @NotNull ItemStack item, @NotNull ItemMeta meta); void bulkGet(@NotNull Map<CAEnchantment, Integer> enchantmentMap, @NotNull ItemStack item, @NotNull ItemMeta meta);
} }

View file

@ -14,10 +14,10 @@ import java.util.Map;
public class EnchantSquaredBulkOperation implements BulkGetEnchantOperation, BulkCleanEnchantOperation { public class EnchantSquaredBulkOperation implements BulkGetEnchantOperation, BulkCleanEnchantOperation {
@Override @Override
public void bulkGet(@NotNull Map<CAEnchantment, Integer> enchantmentList, @NotNull ItemStack item, @NotNull ItemMeta meta) { public void bulkGet(@NotNull Map<CAEnchantment, Integer> enchantmentMap, @NotNull ItemStack item, @NotNull ItemMeta meta) {
EnchantmentSquaredDependency enchantmentSquared = DependencyManager.INSTANCE.getEnchantmentSquaredCompatibility(); EnchantmentSquaredDependency enchantmentSquared = DependencyManager.INSTANCE.getEnchantmentSquaredCompatibility();
if(enchantmentSquared != null){ if(enchantmentSquared != null){
enchantmentSquared.getEnchantmentsSquared(item, enchantmentList); enchantmentSquared.getEnchantmentsSquared(item, enchantmentMap);
} }
} }

View file

@ -157,4 +157,13 @@ public class CABukkitEnchantment extends CAEnchantmentBase {
} }
@Override
public boolean equals(Object obj) {
if(!(obj instanceof CABukkitEnchantment other)){
return false;
}
return this.enchantment.equals(other.getEnchant());
}
} }

View file

@ -2,6 +2,7 @@ package xyz.alexcrea.cuanvil.enchant.wrapped;
import com.willfp.ecoenchants.enchant.EcoEnchant; import com.willfp.ecoenchants.enchant.EcoEnchant;
import com.willfp.ecoenchants.target.EnchantmentTarget; import com.willfp.ecoenchants.target.EnchantmentTarget;
import com.willfp.ecoenchants.type.EnchantmentType;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -9,6 +10,7 @@ import xyz.alexcrea.cuanvil.enchant.AdditionalTestEnchantment;
import xyz.alexcrea.cuanvil.enchant.CAEnchantment; import xyz.alexcrea.cuanvil.enchant.CAEnchantment;
import xyz.alexcrea.cuanvil.enchant.EnchantmentRarity; import xyz.alexcrea.cuanvil.enchant.EnchantmentRarity;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class CAEcoEnchant extends CABukkitEnchantment implements AdditionalTestEnchantment { public class CAEcoEnchant extends CABukkitEnchantment implements AdditionalTestEnchantment {
@ -22,19 +24,34 @@ public class CAEcoEnchant extends CABukkitEnchantment implements AdditionalTestE
@Override @Override
public boolean isEnchantConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull Material itemMat) { public boolean isEnchantConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull Material itemMat) {
if(!enchantments.isEmpty()) { if (enchantments.isEmpty()) return false;
if (this.ecoEnchant.getConflictsWithEverything()) {
if (this.ecoEnchant.getConflictsWithEverything()) {
return true;
}
HashMap<EnchantmentType, Integer> typeAmountMap = new HashMap<>();
for (CAEnchantment other : enchantments.keySet()) {
if (other instanceof CABukkitEnchantment otherVanilla
&& this.ecoEnchant.conflictsWith(otherVanilla.getEnchant())) {
return true; return true;
} }
for (CAEnchantment other : enchantments.keySet()) { if (other instanceof CAEcoEnchant ecoOther) {
if(other instanceof CABukkitEnchantment otherVanilla EnchantmentType type = ecoOther.ecoEnchant.getType();
&& this.ecoEnchant.conflictsWith(otherVanilla.getEnchant())){ typeAmountMap.putIfAbsent(type, 0);
int amount = typeAmountMap.get(type) + 1;
if (amount > type.getLimit()) {
return true; return true;
} }
typeAmountMap.put(type, amount);
} }
} }
return false; return false;
} }
@ -42,12 +59,12 @@ public class CAEcoEnchant extends CABukkitEnchantment implements AdditionalTestE
public boolean isItemConflict(@NotNull Map<CAEnchantment, Integer> enchantments, public boolean isItemConflict(@NotNull Map<CAEnchantment, Integer> enchantments,
@NotNull Material itemMat, @NotNull Material itemMat,
@NotNull ItemStack item) { @NotNull ItemStack item) {
if(Material.ENCHANTED_BOOK.equals(itemMat)){ if (Material.ENCHANTED_BOOK.equals(itemMat)) {
return false; return false;
} }
for (EnchantmentTarget target : this.ecoEnchant.getTargets()) { for (EnchantmentTarget target : this.ecoEnchant.getTargets()) {
if(target.matches(item)){ if (target.matches(item)) {
return false; return false;
} }
} }

View file

@ -16,15 +16,20 @@ import java.util.Objects;
public class CAEnchantSquaredEnchantment extends CAEnchantmentBase { public class CAEnchantSquaredEnchantment extends CAEnchantmentBase {
public final @NotNull CustomEnchant enchant; public final @NotNull CustomEnchant enchant;
public CAEnchantSquaredEnchantment(@NotNull CustomEnchant enchant) { public CAEnchantSquaredEnchantment(@NotNull CustomEnchant enchant) {
super(Objects.requireNonNull( super(Objects.requireNonNull(
Objects.requireNonNull(DependencyManager.INSTANCE.getEnchantmentSquaredCompatibility()).getKeyFromEnchant(enchant)), Objects.requireNonNull(DependencyManager.INSTANCE.getEnchantmentSquaredCompatibility()).getKeyFromEnchant(enchant)),
EnchantmentRarity.COMMON, EnchantmentRarity.COMMON,
enchant.getMaxLevel()); enchant.getMaxLevel());
this.enchant = enchant; this.enchant = enchant;
} }
public @NotNull CustomEnchant getEnchant() {
return enchant;
}
@Override @Override
public boolean isGetOptimised() { public boolean isGetOptimised() {
return true; return true;
@ -61,4 +66,14 @@ public class CAEnchantSquaredEnchantment extends CAEnchantmentBase {
CustomEnchantManager.getInstance().removeEnchant(item, this.enchant.getType()); CustomEnchantManager.getInstance().removeEnchant(item, this.enchant.getType());
} }
@Override
public boolean equals(Object obj) {
if (!(obj instanceof CAEnchantSquaredEnchantment other)) {
return false;
}
return this.enchant.equals(other.getEnchant());
}
} }

View file

@ -0,0 +1,65 @@
package xyz.alexcrea.cuanvil.enchant.wrapped;
import com.willfp.ecoenchants.enchantments.EcoEnchant;
import com.willfp.ecoenchants.enchantments.meta.EnchantmentTarget;
import com.willfp.ecoenchants.enchantments.meta.EnchantmentType;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.enchant.AdditionalTestEnchantment;
import xyz.alexcrea.cuanvil.enchant.CAEnchantment;
import xyz.alexcrea.cuanvil.enchant.EnchantmentRarity;
import java.util.Map;
public class CALegacyEcoEnchant extends CABukkitEnchantment implements AdditionalTestEnchantment {
private final @NotNull EcoEnchant ecoEnchant;
public CALegacyEcoEnchant(@NotNull EcoEnchant ecoEnchant, @NotNull Enchantment enchantment) {
super(enchantment, EnchantmentRarity.COMMON);
this.ecoEnchant = ecoEnchant;
}
@Override
public boolean isEnchantConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull Material itemMat) {
if (enchantments.isEmpty()) return false;
EnchantmentType type = this.ecoEnchant.getType();
boolean isSingular = type.isSingular();
for (CAEnchantment other : enchantments.keySet()) {
if (other instanceof CABukkitEnchantment otherVanilla
&& this.ecoEnchant.conflictsWith(otherVanilla.getEnchant())) {
return true;
}
if (isSingular &&
other != this &&
(other instanceof CALegacyEcoEnchant otherEco) &&
type.equals(otherEco.ecoEnchant.getType())) {
return true;
}
}
return false;
}
@Override
public boolean isItemConflict(@NotNull Map<CAEnchantment, Integer> enchantments,
@NotNull Material itemMat,
@NotNull ItemStack item) {
if (Material.ENCHANTED_BOOK.equals(itemMat)) {
return false;
}
for (EnchantmentTarget target : this.ecoEnchant.getTargets()) {
if (target.getMaterials().contains(itemMat)) {
return false;
}
}
return true;
}
}

View file

@ -28,13 +28,14 @@ object DependencyManager {
var excellentEnchantsCompatibility: ExcellentEnchantsDependency? = null var excellentEnchantsCompatibility: ExcellentEnchantsDependency? = null
var disenchantmentCompatibility: DisenchantmentDependency? = null var disenchantmentCompatibility: DisenchantmentDependency? = null
var havenBagsCompatibility: HavenBagsDependency? = null
fun loadDependency(){ fun loadDependency() {
val pluginManager = Bukkit.getPluginManager() val pluginManager = Bukkit.getPluginManager()
// Bukkit or Paper scheduler ? // Bukkit or Paper scheduler ?
isFolia = testIsFolia() isFolia = testIsFolia()
scheduler = if(isFolia) { scheduler = if (isFolia) {
CustomAnvil.instance.logger.info("Folia detected... Custom Anvil Folia support is experimental. issues are more likely to happens.") CustomAnvil.instance.logger.info("Folia detected... Custom Anvil Folia support is experimental. issues are more likely to happens.")
FoliaScheduler() FoliaScheduler()
@ -46,29 +47,35 @@ object DependencyManager {
externGuiTester = GuiTesterSelector.selectGuiTester externGuiTester = GuiTesterSelector.selectGuiTester
// Enchantment Squared dependency // Enchantment Squared dependency
if(pluginManager.isPluginEnabled("EnchantsSquared")){ if (pluginManager.isPluginEnabled("EnchantsSquared")) {
enchantmentSquaredCompatibility = EnchantmentSquaredDependency(pluginManager.getPlugin("EnchantsSquared")!!) enchantmentSquaredCompatibility = EnchantmentSquaredDependency(pluginManager.getPlugin("EnchantsSquared")!!)
enchantmentSquaredCompatibility!!.disableAnvilListener() enchantmentSquaredCompatibility!!.disableAnvilListener()
} }
// EcoEnchants dependency // EcoEnchants dependency
if(pluginManager.isPluginEnabled("EcoEnchants")){ if (pluginManager.isPluginEnabled("EcoEnchants")) {
ecoEnchantCompatibility = EcoEnchantDependency(pluginManager.getPlugin("EcoEnchants")!!) ecoEnchantCompatibility = EcoEnchantDependency(pluginManager.getPlugin("EcoEnchants")!!)
ecoEnchantCompatibility!!.disableAnvilListener() ecoEnchantCompatibility!!.disableAnvilListener()
} }
// Excellent Enchants dependency // Excellent Enchants dependency
if(pluginManager.isPluginEnabled("ExcellentEnchants")){ if (pluginManager.isPluginEnabled("ExcellentEnchants")) {
excellentEnchantsCompatibility = ExcellentEnchantsDependency() excellentEnchantsCompatibility = ExcellentEnchantsDependency()
excellentEnchantsCompatibility!!.redirectListeners() excellentEnchantsCompatibility!!.redirectListeners()
} }
// Disenchantment dependency // Disenchantment dependency
if(pluginManager.isPluginEnabled("Disenchantment")){ if (pluginManager.isPluginEnabled("Disenchantment")) {
disenchantmentCompatibility = DisenchantmentDependency() disenchantmentCompatibility = DisenchantmentDependency()
disenchantmentCompatibility!!.redirectListeners() disenchantmentCompatibility!!.redirectListeners()
} }
// HavenBags dependency
if (pluginManager.isPluginEnabled("HavenBags")) {
havenBagsCompatibility = HavenBagsDependency()
havenBagsCompatibility!!.redirectListeners()
}
} }
fun handleCompatibilityConfig() { fun handleCompatibilityConfig() {
@ -83,7 +90,7 @@ object DependencyManager {
} }
fun handleConfigReload(){ fun handleConfigReload() {
// Register enchantment of compatible plugin and load configuration change. // Register enchantment of compatible plugin and load configuration change.
handleCompatibilityConfig() handleCompatibilityConfig()
@ -95,14 +102,18 @@ object DependencyManager {
fun tryEventPreAnvilBypass(event: PrepareAnvilEvent, player: HumanEntity): Boolean { fun tryEventPreAnvilBypass(event: PrepareAnvilEvent, player: HumanEntity): Boolean {
var bypass = false var bypass = false
// Test if disenchantment used special prepare anvil // Test if disenchantment used prepare anvil
if(disenchantmentCompatibility?.testPrepareAnvil(event, player) == true) bypass = true if (disenchantmentCompatibility?.testPrepareAnvil(event, player) == true) bypass = true
// Test excellent enchantments used special prepare anvil // Test heaven bags used prepare anvil
if(!bypass && (excellentEnchantsCompatibility?.testPrepareAnvil(event) == true)) bypass = true if (!bypass && (havenBagsCompatibility?.testPrepareAnvil(event, player) == true)) bypass = true
// Test excellent enchantments used prepare anvil
if (!bypass && (excellentEnchantsCompatibility?.testPrepareAnvil(event) == true)) bypass = true
// Test if the inventory is a gui(version specific) // Test if the inventory is a gui(version specific)
if(!bypass && (externGuiTester?.testIfGui(event.view) == true)) bypass = true if (!bypass && (externGuiTester?.testIfGui(event.view) == true)) bypass = true
return bypass return bypass
} }
@ -114,14 +125,17 @@ object DependencyManager {
fun tryClickAnvilResultBypass(event: InventoryClickEvent, inventory: AnvilInventory): Boolean { fun tryClickAnvilResultBypass(event: InventoryClickEvent, inventory: AnvilInventory): Boolean {
var bypass = false var bypass = false
// Test if disenchantment used special event click // Test if disenchantment used event click
if(disenchantmentCompatibility?.testAnvilResult(event, inventory) == true) bypass = true if (disenchantmentCompatibility?.testAnvilResult(event, inventory) == true) bypass = true
// Test if disenchantment used special event click // Test if haven bag used event click
if(!bypass && (excellentEnchantsCompatibility?.testAnvilResult(event) == true)) bypass = true if (!bypass && (havenBagsCompatibility?.testAnvilResult(event, inventory) == true)) bypass = true
// Test if disenchantment used event click
if (!bypass && (excellentEnchantsCompatibility?.testAnvilResult(event) == true)) bypass = true
// Test if the inventory is a gui(version specific) // Test if the inventory is a gui(version specific)
if(!bypass && (externGuiTester?.testIfGui(event.view) == true)) bypass = true if (!bypass && (externGuiTester?.testIfGui(event.view) == true)) bypass = true
return bypass return bypass
} }

View file

@ -1,9 +1,9 @@
package xyz.alexcrea.cuanvil.dependency package xyz.alexcrea.cuanvil.dependency
import cz.kominekjan.disenchantment.events.DisenchantClickEvent import com.jankominek.disenchantment.events.DisenchantClickEvent
import cz.kominekjan.disenchantment.events.DisenchantEvent import com.jankominek.disenchantment.events.DisenchantEvent
import cz.kominekjan.disenchantment.events.ShatterClickEvent import com.jankominek.disenchantment.events.ShatterClickEvent
import cz.kominekjan.disenchantment.events.ShatterEvent import com.jankominek.disenchantment.events.ShatterEvent
import io.delilaheve.CustomAnvil import io.delilaheve.CustomAnvil
import org.bukkit.entity.HumanEntity import org.bukkit.entity.HumanEntity
import org.bukkit.event.inventory.InventoryClickEvent import org.bukkit.event.inventory.InventoryClickEvent

View file

@ -10,11 +10,29 @@ import xyz.alexcrea.cuanvil.enchant.wrapped.CAEcoEnchant
class EcoEnchantDependency(private val ecoEnchantPlugin: Plugin) { class EcoEnchantDependency(private val ecoEnchantPlugin: Plugin) {
private val isLegacy: Boolean
private val legacyDependency: LegacyEcoEnchantDependency?
init { init {
CustomAnvil.instance.logger.info("Eco Enchant Detected !") CustomAnvil.instance.logger.info("Eco Enchant Detected !")
var isLegacy = true
try {
Class.forName("com.willfp.ecoenchants.enchant.EcoEnchants")
isLegacy = false
} catch (_: ClassNotFoundException) {
}
this.isLegacy = isLegacy;
if (isLegacy) {
this.legacyDependency = LegacyEcoEnchantDependency()
} else {
this.legacyDependency = null
}
} }
fun disableAnvilListener(){ fun disableAnvilListener() {
PrepareAnvilEvent.getHandlerList().unregister(this.ecoEnchantPlugin) PrepareAnvilEvent.getHandlerList().unregister(this.ecoEnchantPlugin)
} }
@ -22,6 +40,11 @@ class EcoEnchantDependency(private val ecoEnchantPlugin: Plugin) {
fun registerEnchantments() { fun registerEnchantments() {
CustomAnvil.instance.logger.info("Preparing Eco Enchant compatibility...") CustomAnvil.instance.logger.info("Preparing Eco Enchant compatibility...")
if (isLegacy) {
legacyDependency!!.registerEnchantments();
return
}
val enchantments = EcoEnchants.values() val enchantments = EcoEnchants.values()
for (ecoEnchant in enchantments) { for (ecoEnchant in enchantments) {
EnchantmentApi.unregisterEnchantment(ecoEnchant.enchantment) // As eco enchants is loaded before custom anvil and register enchantment to registry, we need to unregister old "vanilla" enchant. EnchantmentApi.unregisterEnchantment(ecoEnchant.enchantment) // As eco enchants is loaded before custom anvil and register enchantment to registry, we need to unregister old "vanilla" enchant.
@ -34,14 +57,19 @@ class EcoEnchantDependency(private val ecoEnchantPlugin: Plugin) {
} }
fun handleConfigReload() { fun handleConfigReload() {
if (isLegacy) {
legacyDependency!!.handleConfigReload()
return
}
// Should not happen in known case. // Should not happen in known case.
if(this.ecoEnchantOldEnchantments == null) return if (this.ecoEnchantOldEnchantments == null) return
val newEnchantments = EcoEnchants.values() val newEnchantments = EcoEnchants.values()
// Add new enchantments // Add new enchantments
for (ecoEnchant in newEnchantments) for (ecoEnchant in newEnchantments)
if(!this.ecoEnchantOldEnchantments!!.contains(ecoEnchant)) if (!this.ecoEnchantOldEnchantments!!.contains(ecoEnchant))
EnchantmentApi.registerEnchantment(CAEcoEnchant(ecoEnchant)) EnchantmentApi.registerEnchantment(CAEcoEnchant(ecoEnchant))
// Remove old enchantments that not now currently used // Remove old enchantments that not now currently used

View file

@ -0,0 +1,84 @@
package xyz.alexcrea.cuanvil.dependency
import io.delilaheve.CustomAnvil
import org.bukkit.entity.HumanEntity
import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.event.inventory.PrepareAnvilEvent
import org.bukkit.inventory.AnvilInventory
import org.bukkit.plugin.RegisteredListener
import valorless.havenbags.BagSkin
import valorless.havenbags.BagUpgrade
import valorless.havenbags.HavenBags
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener
import xyz.alexcrea.cuanvil.util.AnvilXpUtil
class HavenBagsDependency {
init {
CustomAnvil.instance.logger.info("Heaven Bags Detected !")
}
private lateinit var bagUpgrade: BagUpgrade
private lateinit var bagSkin: BagSkin
fun redirectListeners() {
val toUnregister = ArrayList<RegisteredListener>()
// get required PrepareAnvilEvent listener
for (registeredListener in PrepareAnvilEvent.getHandlerList().registeredListeners) {
val listener = registeredListener.listener
if (listener is BagUpgrade) {
bagUpgrade = listener
toUnregister.add(registeredListener)
}
if (listener is BagSkin) {
bagSkin = listener
toUnregister.add(registeredListener)
}
}
for (listener in toUnregister) {
PrepareAnvilEvent.getHandlerList().unregister(listener)
InventoryClickEvent.getHandlerList().unregister(listener)
}
}
fun testPrepareAnvil(event: PrepareAnvilEvent, player: HumanEntity): Boolean {
val previousResult = event.result
event.result = null
// Test if event change the result
bagSkin.onPrepareAnvil(event)
if (event.result != null) {
CustomAnvil.log("Detected pre anvil heaven bag anvil skin.")
AnvilXpUtil.setAnvilInvXp(event.inventory, event.view, player, event.inventory.repairCost)
return true
}
bagUpgrade.onPrepareAnvil(event)
if (event.result != null) {
CustomAnvil.log("Detected pre anvil heaven bag anvil upgrade.")
AnvilXpUtil.setAnvilInvXp(event.inventory, event.view, player, event.inventory.repairCost)
return true
}
event.result = previousResult
return false
}
fun testAnvilResult(event: InventoryClickEvent, inventory: AnvilInventory): Boolean {
val result = inventory.getItem(PrepareAnvilListener.ANVIL_OUTPUT_SLOT)?.clone()
if (HavenBags.IsBag(result)) {
CustomAnvil.log("Detected anvil click haven bag bypass.")
bagUpgrade.onInventoryClick(event)
bagSkin.onInventoryClick(event)
return true
}
return false
}
}

View file

@ -0,0 +1,46 @@
package xyz.alexcrea.cuanvil.dependency
import com.willfp.ecoenchants.enchantments.EcoEnchant
import com.willfp.ecoenchants.enchantments.EcoEnchants
import org.bukkit.enchantments.Enchantment
import xyz.alexcrea.cuanvil.api.EnchantmentApi
import xyz.alexcrea.cuanvil.enchant.wrapped.CALegacyEcoEnchant
class LegacyEcoEnchantDependency {
private var ecoEnchantOldEnchantments: MutableSet<EcoEnchant>? = null
fun registerEnchantments() {
val enchantments = EcoEnchants.values()
for (ecoEnchant in enchantments) {
ecoEnchant as Enchantment
EnchantmentApi.unregisterEnchantment(ecoEnchant) // As eco enchants is loaded before custom anvil and register enchantment to registry, we need to unregister old "vanilla" enchant.
EnchantmentApi.registerEnchantment(CALegacyEcoEnchant(ecoEnchant, ecoEnchant))
}
ecoEnchantOldEnchantments = HashSet(enchantments)
}
fun handleConfigReload() {
// Should not happen in known case.
if (this.ecoEnchantOldEnchantments == null) return
val newEnchantments = EcoEnchants.values()
// Add new enchantments
for (ecoEnchant in newEnchantments)
if (!this.ecoEnchantOldEnchantments!!.contains(ecoEnchant))
EnchantmentApi.registerEnchantment(CALegacyEcoEnchant(ecoEnchant, ecoEnchant as Enchantment))
// Remove old enchantments that not now currently used
this.ecoEnchantOldEnchantments!!.removeAll(newEnchantments)
for (oldEnchantment in this.ecoEnchantOldEnchantments!!) {
EnchantmentApi.unregisterEnchantment(oldEnchantment as Enchantment)
}
this.ecoEnchantOldEnchantments = HashSet(newEnchantments)
}
}

View file

@ -191,7 +191,7 @@ class EnchantConflictManager {
} }
val immutableEnchants = Collections.unmodifiableMap(appliedEnchants) val immutableEnchants = Collections.unmodifiableMap(appliedEnchants)
for (appliedEnchant in appliedEnchants) { for (appliedEnchant in appliedEnchants.keys) {
if(appliedEnchant is AdditionalTestEnchantment){ if(appliedEnchant is AdditionalTestEnchantment){
val doConflict = appliedEnchant.isEnchantConflict(immutableEnchants, mat) val doConflict = appliedEnchant.isEnchantConflict(immutableEnchants, mat)
if(doConflict){ if(doConflict){

View file

@ -58,3 +58,4 @@ softdepend:
- EcoEnchants - EcoEnchants
- eco - eco
- ExcellentEnchants - ExcellentEnchants
- HavenBags