Add comment and Finish test of conflict for CAEnchant.

This commit is contained in:
alexcrea 2024-06-20 13:42:39 +02:00
parent dafe595c5b
commit 3c60e157e4
No known key found for this signature in database
GPG key ID: 43FD265DB0DBF91F
5 changed files with 71 additions and 23 deletions

View file

@ -1,6 +1,7 @@
package xyz.alexcrea.cuanvil.enchant; package xyz.alexcrea.cuanvil.enchant;
import io.delilaheve.util.ItemUtil; import io.delilaheve.util.ItemUtil;
import org.bukkit.Material;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.entity.HumanEntity; import org.bukkit.entity.HumanEntity;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@ -16,7 +17,7 @@ import xyz.alexcrea.cuanvil.group.EnchantConflictGroup;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.function.Supplier;
/** /**
* Represent an enchantment compatible with Custom Anvil. * Represent an enchantment compatible with Custom Anvil.
@ -65,14 +66,40 @@ public interface CAEnchantment {
*/ */
boolean isAllowed(@NotNull HumanEntity player); boolean isAllowed(@NotNull HumanEntity player);
/**
* Add a conflict to this enchantment conflict list.
* @param conflict The conflict to add.
*/
void addConflict(@NotNull EnchantConflictGroup conflict); void addConflict(@NotNull EnchantConflictGroup conflict);
/**
* Remove a conflict from the conflict list of this enchantment.
* @param conflict The conflict to remove from this enchantment.
*/
void removeConflict(@NotNull EnchantConflictGroup conflict); void removeConflict(@NotNull EnchantConflictGroup conflict);
/**
* Clear Custom Anvil conflicts for this enchantment.
*/
void clearConflict(); void clearConflict();
@NotNull Set<EnchantConflictGroup> getConflicts(); /**
* Get a collection of Custom Anvil conflict containing this enchantment.
* @return A collection of Custom Anvil conflict containing this enchantment.
*/
@NotNull Collection<EnchantConflictGroup> getConflicts();
@NotNull ConflictType testConflict(); /**
* Test if the provided item can be compatible with this
* @param baseEnchantments Validated enchantments for the item.
* @param itemMat Material of the tested item.
* @param itemSupply Provide a new instance of used item stack but with baseEnchantments as enchantments.
* @return Type of conflict this enchantment has with the provided item.
*/
@NotNull
ConflictType testConflict(@NotNull Map<CAEnchantment, Integer> baseEnchantments,
@NotNull Material itemMat,
@NotNull Supplier<ItemStack> itemSupply);
/** /**
* Get current level of the enchantment. * Get current level of the enchantment.

View file

@ -1,5 +1,6 @@
package xyz.alexcrea.cuanvil.enchant; package xyz.alexcrea.cuanvil.enchant;
import org.bukkit.Material;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.entity.HumanEntity; import org.bukkit.entity.HumanEntity;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@ -9,8 +10,11 @@ import org.jetbrains.annotations.Nullable;
import xyz.alexcrea.cuanvil.group.ConflictType; import xyz.alexcrea.cuanvil.group.ConflictType;
import xyz.alexcrea.cuanvil.group.EnchantConflictGroup; import xyz.alexcrea.cuanvil.group.EnchantConflictGroup;
import java.util.HashSet; import java.util.ArrayList;
import java.util.Set; import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Supplier;
public abstract class CAEnchantmentBase implements CAEnchantment { public abstract class CAEnchantmentBase implements CAEnchantment {
@ -22,7 +26,7 @@ public abstract class CAEnchantmentBase implements CAEnchantment {
private final EnchantmentRarity defaultRarity; private final EnchantmentRarity defaultRarity;
private final int defaultMaxLevel; private final int defaultMaxLevel;
private final Set<EnchantConflictGroup> conflicts; private final List<EnchantConflictGroup> conflicts;
/** /**
* Constructor of Wrapped Enchantment. * Constructor of Wrapped Enchantment.
@ -38,10 +42,9 @@ public abstract class CAEnchantmentBase implements CAEnchantment {
this.name = key.getKey(); this.name = key.getKey();
this.defaultMaxLevel = defaultMaxLevel; this.defaultMaxLevel = defaultMaxLevel;
if(defaultRarity == null) this.defaultRarity = EnchantmentRarity.COMMON; this.defaultRarity = Objects.requireNonNullElse(defaultRarity, EnchantmentRarity.COMMON);
else this.defaultRarity = defaultRarity;
this.conflicts = new HashSet<>(); this.conflicts = new ArrayList<>();
} }
@NotNull @NotNull
@ -105,12 +108,14 @@ public abstract class CAEnchantmentBase implements CAEnchantment {
} }
@Override @Override
public @NotNull Set<EnchantConflictGroup> getConflicts() { public @NotNull List<EnchantConflictGroup> getConflicts() {
return conflicts; return conflicts;
} }
@Override @Override
public @NotNull ConflictType testConflict() { public @NotNull ConflictType testConflict(@NotNull Map<CAEnchantment, Integer> baseEnchantments,
@NotNull Material itemMat,
@NotNull Supplier<ItemStack> itemSupply) {
return ConflictType.NO_CONFLICT; return ConflictType.NO_CONFLICT;
} }

View file

@ -99,7 +99,7 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener {
// Test for merge // Test for merge
if (first.canMergeWith(second)) { if (first.canMergeWith(second)) {
val newEnchants = first.findEnchantments() val newEnchants = first.findEnchantments()
.combineWith(second.findEnchantments(), first.type, player) .combineWith(second.findEnchantments(), first, player)
val resultItem = first.clone() val resultItem = first.clone()
resultItem.setEnchantmentsUnsafe(newEnchants) resultItem.setEnchantmentsUnsafe(newEnchants)
@ -436,15 +436,15 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener {
val rightIsFormBook = right.isEnchantedBook() val rightIsFormBook = right.isEnchantedBook()
val resultEnchs = result.findEnchantments() val resultEnchs = result.findEnchantments()
val resultEnchsKeys = HashSet(resultEnchs.keys) val resultEnchsKeys = HashMap(resultEnchs)
for (enchantment in right.findEnchantments()) { for (enchantment in right.findEnchantments()) {
// count enchant as illegal enchant if it conflicts with another enchant or not in result // count enchant as illegal enchant if it conflicts with another enchant or not in result
if ((enchantment.key !in resultEnchsKeys)) { if ((enchantment.key !in resultEnchsKeys)) {
resultEnchsKeys.add(enchantment.key) resultEnchsKeys[enchantment.key] = enchantment.value
val conflictType = ConfigHolder.CONFLICT_HOLDER.conflictManager.isConflicting( val conflictType = ConfigHolder.CONFLICT_HOLDER.conflictManager.isConflicting(
resultEnchsKeys, resultEnchsKeys,
result.type, result,
enchantment.key enchantment.key
) )
resultEnchsKeys.remove(enchantment.key) resultEnchsKeys.remove(enchantment.key)

View file

@ -1,8 +1,8 @@
package io.delilaheve.util package io.delilaheve.util
import io.delilaheve.CustomAnvil import io.delilaheve.CustomAnvil
import org.bukkit.Material
import org.bukkit.entity.HumanEntity import org.bukkit.entity.HumanEntity
import org.bukkit.inventory.ItemStack
import xyz.alexcrea.cuanvil.config.ConfigHolder import xyz.alexcrea.cuanvil.config.ConfigHolder
import xyz.alexcrea.cuanvil.enchant.CAEnchantment import xyz.alexcrea.cuanvil.enchant.CAEnchantment
import xyz.alexcrea.cuanvil.group.ConflictType import xyz.alexcrea.cuanvil.group.ConflictType
@ -25,10 +25,11 @@ object EnchantmentUtil {
*/ */
fun Map<CAEnchantment, Int>.combineWith( fun Map<CAEnchantment, Int>.combineWith(
other: Map<CAEnchantment, Int>, other: Map<CAEnchantment, Int>,
mat: Material, item: ItemStack,
player: HumanEntity player: HumanEntity
) = mutableMapOf<CAEnchantment, Int>().apply { ) = mutableMapOf<CAEnchantment, Int>().apply {
putAll(this@combineWith) putAll(this@combineWith)
other.forEach { (enchantment, level) -> other.forEach { (enchantment, level) ->
if(!enchantment.isAllowed(player)) return@forEach if(!enchantment.isAllowed(player)) return@forEach
@ -44,7 +45,7 @@ object EnchantmentUtil {
// Add the enchantment if it doesn't have conflicts, or if player is allowed to bypass enchantment restrictions // Add the enchantment if it doesn't have conflicts, or if player is allowed to bypass enchantment restrictions
this[enchantment] = cappedLevel this[enchantment] = cappedLevel
val conflictType = val conflictType =
ConfigHolder.CONFLICT_HOLDER.conflictManager.isConflicting(this.keys, mat, enchantment) ConfigHolder.CONFLICT_HOLDER.conflictManager.isConflicting(this, item, enchantment)
if (!player.hasPermission(CustomAnvil.bypassFusePermission) && if (!player.hasPermission(CustomAnvil.bypassFusePermission) &&
(conflictType != ConflictType.NO_CONFLICT) (conflictType != ConflictType.NO_CONFLICT)
) { ) {
@ -59,7 +60,7 @@ object EnchantmentUtil {
// ... and they are conflicting // ... and they are conflicting
val conflictType = val conflictType =
ConfigHolder.CONFLICT_HOLDER.conflictManager.isConflicting(this.keys, mat, enchantment) ConfigHolder.CONFLICT_HOLDER.conflictManager.isConflicting(this, item, enchantment)
if ((conflictType != ConflictType.NO_CONFLICT) if ((conflictType != ConflictType.NO_CONFLICT)
&& !player.hasPermission(CustomAnvil.bypassFusePermission) && !player.hasPermission(CustomAnvil.bypassFusePermission)
) { ) {

View file

@ -1,12 +1,13 @@
package xyz.alexcrea.cuanvil.group package xyz.alexcrea.cuanvil.group
import io.delilaheve.CustomAnvil import io.delilaheve.CustomAnvil
import org.bukkit.Material
import org.bukkit.NamespacedKey import org.bukkit.NamespacedKey
import org.bukkit.configuration.ConfigurationSection import org.bukkit.configuration.ConfigurationSection
import org.bukkit.enchantments.Enchantment import org.bukkit.enchantments.Enchantment
import org.bukkit.inventory.ItemStack
import xyz.alexcrea.cuanvil.enchant.CAEnchantment import xyz.alexcrea.cuanvil.enchant.CAEnchantment
import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry
import java.util.function.Supplier
class EnchantConflictManager { class EnchantConflictManager {
@ -144,14 +145,15 @@ class EnchantConflictManager {
return group return group
} }
fun isConflicting(base: Set<CAEnchantment>, mat: Material, newEnchant: CAEnchantment): ConflictType { fun isConflicting(appliedEnchants: Map<CAEnchantment, Int>, item: ItemStack, newEnchant: CAEnchantment): ConflictType {
val mat = item.type
CustomAnvil.verboseLog("Testing conflict for ${newEnchant.key} on ${mat.key}") CustomAnvil.verboseLog("Testing conflict for ${newEnchant.key} on ${mat.key}")
val conflictList = newEnchant.conflicts; val conflictList = newEnchant.conflicts;
var result = ConflictType.NO_CONFLICT var result = ConflictType.NO_CONFLICT
for (conflict in conflictList) { for (conflict in conflictList) {
CustomAnvil.verboseLog("Is against $conflict") CustomAnvil.verboseLog("Is against $conflict")
val allowed = conflict.allowed(base, mat) val allowed = conflict.allowed(appliedEnchants.keys, mat)
CustomAnvil.verboseLog("Was against $conflict and conflicting: ${!allowed} ") CustomAnvil.verboseLog("Was against $conflict and conflicting: ${!allowed} ")
if (!allowed) { if (!allowed) {
if (conflict.getEnchants().size <= 1) { if (conflict.getEnchants().size <= 1) {
@ -165,11 +167,24 @@ class EnchantConflictManager {
} }
// Test conflict with other conflict system. // Test conflict with other conflict system.
val otherConflict = newEnchant.testConflict() val otherConflict = newEnchant.testConflict(appliedEnchants, mat, reEnchantSupplier(item, appliedEnchants))
return result.getWorstConflict(otherConflict) return result.getWorstConflict(otherConflict)
} }
private fun reEnchantSupplier(item: ItemStack, enchantments: Map<CAEnchantment, Int>): Supplier<ItemStack> {
return Supplier {
val newItem = item.clone()
CAEnchantment.clearEnchants(newItem)
enchantments.forEach{//TODO maybe bulk add if possible
enchantment -> enchantment.key.addEnchantmentUnsafe(item, enchantment.value)
}
return@Supplier newItem;
}
}
} }
/** /**