From edceba879fc34f733cd4c61eeb5b0f0f4bedf618 Mon Sep 17 00:00:00 2001 From: alexcrea Date: Tue, 2 Jun 2026 16:18:16 +0200 Subject: [PATCH] custom craft logic deduplication --- .../alexcrea/cuanvil/anvil/AnvilMergeLogic.kt | 27 ++++++++-- .../cuanvil/listener/AnvilResultListener.kt | 54 ++++++++----------- .../cuanvil/listener/PrepareAnvilListener.kt | 2 +- .../cuanvil/util/anvil/AnvilXpUtil.kt | 4 +- .../cuanvil/util/AnvilFuseTestUtil.java | 4 +- 5 files changed, 51 insertions(+), 40 deletions(-) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/anvil/AnvilMergeLogic.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/anvil/AnvilMergeLogic.kt index b7d8bdb..8699285 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/anvil/AnvilMergeLogic.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/anvil/AnvilMergeLogic.kt @@ -19,6 +19,7 @@ import org.bukkit.persistence.PersistentDataType import xyz.alexcrea.cuanvil.dependency.DependencyManager import xyz.alexcrea.cuanvil.dialog.AnvilRenameDialog import xyz.alexcrea.cuanvil.enchant.CAEnchantment +import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe import xyz.alexcrea.cuanvil.util.CasedStringUtil import xyz.alexcrea.cuanvil.util.CustomRecipeUtil import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir @@ -28,6 +29,7 @@ import xyz.alexcrea.cuanvil.util.anvil.AnvilColorUtil import xyz.alexcrea.cuanvil.util.anvil.AnvilLoreEditUtil import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil.AnvilCost +import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil.CustomCraftCost import xyz.alexcrea.cuanvil.util.config.LoreEditType import xyz.alexcrea.cuanvil.util.dialog.AnvilRenameDialogUtil @@ -65,6 +67,22 @@ object AnvilMergeLogic { } } + class CustomCraftResult: AnvilResult { + companion object { + val EMPTY = CustomCraftResult(null, CustomCraftCost(0), 0, null) + } + + val customCraftCost: CustomCraftCost + val amount: Int + val recipe: AnvilCustomRecipe? + + constructor(item: ItemStack?, cost: CustomCraftCost, + amount: Int, recipe: AnvilCustomRecipe?) : super(item, cost, true) { + this.customCraftCost = cost + this.amount = amount + this.recipe = recipe + } + } class LoreEditResult: AnvilResult { companion object { @@ -211,10 +229,10 @@ object AnvilMergeLogic { fun testCustomRecipe( player: Player, first: ItemStack, second: ItemStack? - ): AnvilResult { + ): CustomCraftResult { val recipe = CustomRecipeUtil.getCustomRecipe(first, second) CustomAnvil.verboseLog("custom recipe not null? ${recipe != null}") - if (recipe == null) return AnvilResult.EMPTY + if (recipe == null) return CustomCraftResult.EMPTY val amount = CustomRecipeUtil.getCustomRecipeAmount(recipe, first, second) @@ -224,12 +242,13 @@ object AnvilMergeLogic { // Maybe add an option on custom craft to ignore/not ignore penalty ?? val xpCost = recipe.determineCost(amount, first, resultItem) - val cost = AnvilCost() + val cost = CustomCraftCost(xpCost) + // This is for displayed cost cost.recipe = if (recipe.removeExactLinearXp) AnvilXpUtil.calculateMinimumLevelForXp(xpCost) else AnvilXpUtil.calculateLevelForXp(xpCost) val result = DependencyManager.tryTreatAnvilResult(resultItem, AnvilUseType.CUSTOM_CRAFT, cost) - return AnvilResult(result, cost, true) + return CustomCraftResult(result, cost, amount, recipe) } fun testUnitRepair( diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt index 3e0371a..d63e2a6 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt @@ -17,7 +17,9 @@ import org.bukkit.inventory.ItemStack import org.bukkit.inventory.meta.BookMeta import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic.AnvilResult +import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic.CustomCraftResult import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic.LoreEditResult +import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic.UnitRepairResult import xyz.alexcrea.cuanvil.dependency.DependencyManager import xyz.alexcrea.cuanvil.dependency.economy.EconomyManager import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.setComponentDisplayName @@ -27,7 +29,6 @@ import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_OUTPUT import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe import xyz.alexcrea.cuanvil.util.CustomRecipeUtil import xyz.alexcrea.cuanvil.util.MiniMessageUtil -import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair import xyz.alexcrea.cuanvil.util.anvil.AnvilLoreEditUtil import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil.AnvilCost @@ -73,12 +74,11 @@ class AnvilResultListener : Listener { } // Test custom recipe - val recipe = CustomRecipeUtil.getCustomRecipe(leftItem, rightItem) - if (recipe != null) { - event.result = Event.Result.ALLOW + val customRecipeResult = AnvilMergeLogic.testCustomRecipe(player, leftItem, rightItem) + if (!customRecipeResult.isEmpty()) { onCustomCraft( - event, recipe, player, - leftItem, rightItem, output, inventory + event, player, inventory, + leftItem, rightItem, customRecipeResult ) return } @@ -103,11 +103,13 @@ class AnvilResultListener : Listener { } // Unit repair - val unitRepairResult = leftItem.getRepair(rightItem) // Maybe this should be handlded "above" and like prepare result - if (unitRepairResult != null) { + val unitRepairResult = AnvilMergeLogic.testUnitRepair( + inventory, player, + leftItem, rightItem) + if (unitRepairResult.isEmpty()) { onUnitRepairExtract( - leftItem, rightItem, - unitRepairResult, event, player, inventory + rightItem, event, player, inventory, + unitRepairResult ) return } @@ -125,19 +127,14 @@ class AnvilResultListener : Listener { private fun onCustomCraft( event: InventoryClickEvent, - recipe: AnvilCustomRecipe, player: Player, + inventory: AnvilInventory, leftItem: ItemStack, rightItem: ItemStack?, - output: ItemStack, - inventory: AnvilInventory + result: CustomCraftResult, ) { - event.result = Event.Result.DENY - - if (recipe.leftItem == null) return // in case it changed - - val amount = CustomRecipeUtil.getCustomRecipeAmount(recipe, leftItem, rightItem) - val xpCost = recipe.determineCost(amount, leftItem, output) + val recipe = result.recipe!! + val xpCost = result.customCraftCost.rawCost val finalCost = if (recipe.removeExactLinearXp) xpCost else AnvilXpUtil.calculateLevelForXp(xpCost) @@ -166,7 +163,7 @@ class AnvilResultListener : Listener { player, leftItem, rightItem, - amount, + result.amount, finalCost, recipe.removeExactLinearXp ) @@ -174,9 +171,9 @@ class AnvilResultListener : Listener { // Finally, we add the item to the player if (slotDestination.type == SlotType.CURSOR) { - player.setItemOnCursor(output) + player.setItemOnCursor(result.item) } else {// We assume SlotType == SlotType.INVENTORY - player.inventory.setItem(slotDestination.slot, output) + player.inventory.setItem(slotDestination.slot, result.item) } } @@ -335,20 +332,13 @@ class AnvilResultListener : Listener { } private fun onUnitRepairExtract( - leftItem: ItemStack, rightItem: ItemStack, - unitRepairResult: Double, event: InventoryClickEvent, player: Player, - inventory: AnvilInventory + inventory: AnvilInventory, + result: UnitRepairResult, ) { - val result = AnvilMergeLogic.testUnitRepair(inventory, player, - leftItem.clone(), rightItem, - unitRepairResult) - - if(result.isEmpty()) return - - // And then we give the item manually + // We give the item manually extractAnvilResult( event, player, inventory, null, 0, diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt index 0c7121f..00a2053 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt @@ -104,7 +104,7 @@ class PrepareAnvilListener : Listener { return AnvilResult.EMPTY // Test custom recipe - var result = testCustomRecipe(player, first, second) + var result: AnvilResult = testCustomRecipe(player, first, second) if (!result.isEmpty()) return result diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/anvil/AnvilXpUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/anvil/AnvilXpUtil.kt index 0f94661..997b260 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/anvil/AnvilXpUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/anvil/AnvilXpUtil.kt @@ -29,7 +29,7 @@ object AnvilXpUtil { const val EXCLUSIVE_PENALTY_PREFIX = "repair_cost" - class AnvilCost { + open class AnvilCost { private val isAlone: Boolean var valid = true // Get set as invalid if cost can be satisfied var isMonetary = false @@ -71,6 +71,8 @@ object AnvilXpUtil { } } + class CustomCraftCost(val rawCost: Int): AnvilCost() + /** * Display the required cost (either as xp or as ) */ diff --git a/src/test/java/xyz/alexcrea/cuanvil/util/AnvilFuseTestUtil.java b/src/test/java/xyz/alexcrea/cuanvil/util/AnvilFuseTestUtil.java index 1d3c5f4..6f5c7bb 100644 --- a/src/test/java/xyz/alexcrea/cuanvil/util/AnvilFuseTestUtil.java +++ b/src/test/java/xyz/alexcrea/cuanvil/util/AnvilFuseTestUtil.java @@ -195,7 +195,7 @@ public class AnvilFuseTestUtil { simulateClick(anvil, player, data.expectedResult()); - // Should have similated the click + // Should have simulated the click assertEqual(data.leftItem(), anvil.getFirstItem()); assertEqual(data.rightItem(), anvil.getSecondItem()); assertEqual(data.resultSlotItem(), anvil.getResult()); @@ -260,7 +260,7 @@ public class AnvilFuseTestUtil { } public static boolean isAir(@Nullable ItemStack item) { - return item == null || item.isEmpty(); + return item == null || item.isEmpty() || item.getAmount() == 0; } public static void assertPriceEqual(Integer expectedPrice, int price) {