custom craft logic deduplication

This commit is contained in:
alexcrea 2026-06-02 16:18:16 +02:00
parent 106bc724a1
commit edceba879f
Signed by: alexcrea
GPG key ID: E346CD16413450E3
5 changed files with 51 additions and 40 deletions

View file

@ -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(

View file

@ -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,

View file

@ -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

View file

@ -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 )
*/

View file

@ -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) {