diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CAClickResultBypassEvent.java b/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CAClickResultBypassEvent.java index a27c65e..fe5e199 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CAClickResultBypassEvent.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CAClickResultBypassEvent.java @@ -17,7 +17,7 @@ import org.jetbrains.annotations.NotNull; * Most of the time you would likely need {@link CAPreAnvilBypassEvent} or {@link CAEarlyPreAnvilBypassEvent} * for this event to be useful. *
- * There is also {@link CATreatAnvilResultEvent} that may be better for some use case. + * There is also {@link CATreatAnvilResult2Event} that may be better for some use case. */ public class CAClickResultBypassEvent extends Event implements Cancellable { diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CAEarlyPreAnvilBypassEvent.java b/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CAEarlyPreAnvilBypassEvent.java index 2fbd275..e92b4cd 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CAEarlyPreAnvilBypassEvent.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CAEarlyPreAnvilBypassEvent.java @@ -15,7 +15,7 @@ import org.jetbrains.annotations.NotNull; *
* You should also use {@link CAClickResultBypassEvent} if you want to use this event for something useful. *
- * It is also recommended that you read about {@link CAPreAnvilBypassEvent} and {@link CATreatAnvilResultEvent} + * It is also recommended that you read about {@link CAPreAnvilBypassEvent} and {@link CATreatAnvilResult2Event} * as your use case may be more prone to use theses. */ public class CAEarlyPreAnvilBypassEvent extends Event implements Cancellable { diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CAPreAnvilBypassEvent.java b/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CAPreAnvilBypassEvent.java index 18334e3..9103a4b 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CAPreAnvilBypassEvent.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CAPreAnvilBypassEvent.java @@ -18,7 +18,7 @@ import org.jetbrains.annotations.NotNull; *
* You should also use {@link CAClickResultBypassEvent} if you want to use this event for something useful. *
- * It is also recommended that you read about {@link CAEarlyPreAnvilBypassEvent} and {@link CATreatAnvilResultEvent} + * It is also recommended that you read about {@link CAEarlyPreAnvilBypassEvent} and {@link CATreatAnvilResult2Event} * as your use case may be more prone to use theses. */ public class CAPreAnvilBypassEvent extends Event implements Cancellable { diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CATreatAnvilResult2Event.java b/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CATreatAnvilResult2Event.java new file mode 100644 index 0000000..aa8f8e1 --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CATreatAnvilResult2Event.java @@ -0,0 +1,196 @@ +package xyz.alexcrea.cuanvil.api.event.listener; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import xyz.alexcrea.cuanvil.anvil.AnvilUseType; +import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil; + +/** + * Called after custom anvil processed the click on the result on the anvil inventory. + * This event should be used to modify the result of an anvil use. + *
+ * You may also want to check {@link CAClickResultBypassEvent}, + * {@link CAPreAnvilBypassEvent} + * and {@link CAEarlyPreAnvilBypassEvent} for your use case + *
+ * A null result will cancel this event + */ +@SuppressWarnings("unused") +public class CATreatAnvilResult2Event extends Event { + + private static final HandlerList HANDLERS = new HandlerList(); + + public static HandlerList getHandlerList() { + return HANDLERS; + } + + @Override + public @NotNull HandlerList getHandlers() { + return HANDLERS; + } + + @NotNull + private final InventoryView view; + + private final AnvilUseType useType; + + @Nullable + private final ItemStack left; + @Nullable + private final ItemStack right; + + @Nullable + private ItemStack result; + + private final AnvilXpUtil.AnvilCost cost; + + @ApiStatus.Internal + public CATreatAnvilResult2Event( + @NotNull InventoryView view, + Inventory inv, + AnvilUseType useType, + @Nullable ItemStack result, + AnvilXpUtil.AnvilCost cost) { + this.view = view; + this.useType = useType; + + this.left = inv.getItem(0); // TODO use view here + this.right = inv.getItem(1); + this.result = result; + this.cost = cost; + } + + /** + * Get the bukkit inventory view. + *
+ * Temporarily marked as internal as it will get changed to anvil view on legacy removal + * so signature will change + * + * @return The inventory view of this event. + */ + @ApiStatus.Internal + public @NotNull InventoryView getView() { + return view; + } + + + /** + * Get the type of use source of the result. + * + * @return The craft use type. + */ + public AnvilUseType getUseType() { + return useType; + } + + /** + * Get the left item of the anvil use + * + * @return the left item + */ + public @Nullable ItemStack getLeftItem() { + return left; + } + + /** + * Get the right item of the anvil use + * + * @return the right item + */ + public @Nullable ItemStack getRightItem() { + return right; + } + + /** + * Get the current result + *
+ * note that it will not be null unless another listener previously set it to null. + * + * @return The current result. + */ + public @Nullable ItemStack getResult() { + return result; + } + + /** + * Set the current result + *
+ * note that a null result will cancel this anvil use. + * + * @param result The new result + */ + public void setResult(@Nullable ItemStack result) { + this.result = result; + } + + /** + * Get the level cost displayed on the anvil. + *
* A null result will cancel this pre anvil event * - * @deprecated Prepare anvil Event should not be provided as it can be called on result and therefor not have prepare anvil event - * TODO a replacement is necessary but not yet made + * @deprecated Prepare anvil Event cannot be provided as it can be called on result and therefore not have prepared anvil event + * use {@link CATreatAnvilResult2Event} instead */ @SuppressWarnings("unused") @Deprecated(forRemoval = true, since = "1.17.0") diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/anvil/AnvilMergeLogic.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/anvil/AnvilMergeLogic.kt index e018eff..67b9b7d 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/anvil/AnvilMergeLogic.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/anvil/AnvilMergeLogic.kt @@ -13,6 +13,7 @@ import org.bukkit.Material import org.bukkit.entity.HumanEntity import org.bukkit.entity.Player import org.bukkit.inventory.AnvilInventory +import org.bukkit.inventory.InventoryView import org.bukkit.inventory.ItemStack import org.bukkit.inventory.meta.ItemMeta import org.bukkit.persistence.PersistentDataType @@ -99,6 +100,7 @@ object AnvilMergeLogic { } fun doRenaming( + view: InventoryView, //TODO use anvil view inventory: AnvilInventory, player: Player, first: ItemStack ): AnvilResult { @@ -113,7 +115,7 @@ object AnvilMergeLogic { } cost.workPenalty = AnvilXpUtil.calculatePenalty(first, null, resultItem, AnvilUseType.RENAME_ONLY) - val result = DependencyManager.tryTreatAnvilResult(resultItem, AnvilUseType.RENAME_ONLY, cost) + val result = DependencyManager.tryTreatAnvilResult(view, inventory, player, resultItem, AnvilUseType.RENAME_ONLY, cost) return AnvilResult(result, cost) } @@ -183,6 +185,7 @@ object AnvilMergeLogic { } fun doMerge( + view: InventoryView, //TODO use anvil view instead inventory: AnvilInventory, player: Player, first: ItemStack, second: ItemStack @@ -217,7 +220,7 @@ object AnvilMergeLogic { // Calculate rename cost cost.rename = handleRename(resultItem, inventory, player) - val result = DependencyManager.tryTreatAnvilResult(resultItem, AnvilUseType.MERGE, cost) + val result = DependencyManager.tryTreatAnvilResult(view, inventory, player, resultItem, AnvilUseType.MERGE, cost) return AnvilResult(result, cost) } @@ -236,6 +239,8 @@ object AnvilMergeLogic { // return true if a custom recipe exist with these ingredients fun testCustomRecipe( + view: InventoryView, //TODO use anvil view instead + inventory: AnvilInventory, player: Player, first: ItemStack, second: ItemStack? ): CustomCraftResult { @@ -256,21 +261,23 @@ object AnvilMergeLogic { cost.recipe = if (recipe.removeExactLinearXp) AnvilXpUtil.calculateMinimumLevelForXp(xpCost) else AnvilXpUtil.calculateLevelForXp(xpCost) - val result = DependencyManager.tryTreatAnvilResult(resultItem, AnvilUseType.CUSTOM_CRAFT, cost) + val result = DependencyManager.tryTreatAnvilResult(view, inventory, player, resultItem, AnvilUseType.CUSTOM_CRAFT, cost) return CustomCraftResult(result, cost, amount, recipe) } fun testUnitRepair( + view: InventoryView, //TODO use anvil view inventory: AnvilInventory, player: Player, first: ItemStack, second: ItemStack ): UnitRepairResult { val unitRepairAmount = first.getRepair(second) ?: return UnitRepairResult.EMPTY - return testUnitRepair(inventory, player, first, second, unitRepairAmount) + return testUnitRepair(view, inventory, player, first, second, unitRepairAmount) } fun testUnitRepair( + view: InventoryView, //TODO use anvil view instead inventory: AnvilInventory, player: Player, first: ItemStack, second: ItemStack, @@ -293,7 +300,7 @@ object AnvilMergeLogic { return UnitRepairResult.EMPTY } - val result = DependencyManager.tryTreatAnvilResult(resultItem, AnvilUseType.UNIT_REPAIR, cost) + val result = DependencyManager.tryTreatAnvilResult(view, inventory, player, resultItem, AnvilUseType.UNIT_REPAIR, cost) return UnitRepairResult(result, cost, repairAmount) } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt index 4ad6c9b..0da6b30 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt @@ -12,12 +12,13 @@ import org.bukkit.event.inventory.InventoryClickEvent import org.bukkit.event.inventory.PrepareAnvilEvent import org.bukkit.inventory.AnvilInventory import org.bukkit.inventory.Inventory +import org.bukkit.inventory.InventoryView import org.bukkit.inventory.ItemStack import xyz.alexcrea.cuanvil.anvil.AnvilUseType import xyz.alexcrea.cuanvil.api.event.listener.CAClickResultBypassEvent import xyz.alexcrea.cuanvil.api.event.listener.CAEarlyPreAnvilBypassEvent import xyz.alexcrea.cuanvil.api.event.listener.CAPreAnvilBypassEvent -import xyz.alexcrea.cuanvil.api.event.listener.CATreatAnvilResultEvent +import xyz.alexcrea.cuanvil.api.event.listener.CATreatAnvilResult2Event import xyz.alexcrea.cuanvil.config.ConfigHolder import xyz.alexcrea.cuanvil.dependency.datapack.DataPackDependency import xyz.alexcrea.cuanvil.dependency.gui.GenericExternGuiTester @@ -234,23 +235,24 @@ object DependencyManager { // Return null if there was an issue fun tryTreatAnvilResult( + view: InventoryView, + inventory: Inventory, // TODO REMOVE, use view instead on legacy removal + player: HumanEntity, result: ItemStack, useType: AnvilUseType, cost: AnvilXpUtil.AnvilCost ): ItemStack? { - //TODO - /*val treatEvent = CATreatAnvilResultEvent(event, useType, result, cost) + val treatEvent = CATreatAnvilResult2Event(view, inventory, useType, result, cost) try { unsafeTryTreatAnvilResult(treatEvent) return treatEvent.result } catch (e: Exception) { - logExceptionAndClear(event.view.player, event.inventory, e) + logExceptionAndClear(player, inventory, e) return null - }*/ - return result + } } - private fun unsafeTryTreatAnvilResult(event: CATreatAnvilResultEvent) { + private fun unsafeTryTreatAnvilResult(event: CATreatAnvilResult2Event) { Bukkit.getPluginManager().callEvent(event) excellentEnchantsCompatibility?.treatAnvilResult(event) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/plugins/ExcellentEnchantsDependency.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/plugins/ExcellentEnchantsDependency.kt index 54ea2f4..39bfad7 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/plugins/ExcellentEnchantsDependency.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/plugins/ExcellentEnchantsDependency.kt @@ -8,7 +8,7 @@ import org.bukkit.event.inventory.PrepareAnvilEvent import org.bukkit.inventory.ItemStack import org.bukkit.plugin.RegisteredListener import xyz.alexcrea.cuanvil.api.EnchantmentApi -import xyz.alexcrea.cuanvil.api.event.listener.CATreatAnvilResultEvent +import xyz.alexcrea.cuanvil.api.event.listener.CATreatAnvilResult2Event import xyz.alexcrea.cuanvil.enchant.wrapped.CAEEPreV5Enchantment import xyz.alexcrea.cuanvil.enchant.wrapped.CAEEV5Enchantment import xyz.alexcrea.cuanvil.enchant.wrapped.CAEEV5_4Enchantment @@ -218,14 +218,17 @@ class ExcellentEnchantsDependency { return handleRechargeMethod.invoke(this.usedAnvilListener, event, first, second) as Boolean } - fun treatAnvilResult(event: CATreatAnvilResultEvent) { + fun treatAnvilResult(event: CATreatAnvilResult2Event) { val result = event.result if (result == null) return - val first: ItemStack = treatInput(event.event.inventory.getItem(0)) - val second: ItemStack = treatInput(event.event.inventory.getItem(1)) + val first: ItemStack = treatInput(event.leftItem) + val second: ItemStack = treatInput(event.rightItem) - handleCombineMethod.invoke(this.usedAnvilListener, event.event, first, second, result) + val fakeEvent = PrepareAnvilEvent(event.view, result) + handleCombineMethod.invoke(this.usedAnvilListener, fakeEvent, first, second, result) + + event.result = fakeEvent.result } fun testAnvilResult(event: InventoryClickEvent): Any { diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt index a232046..775a685 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt @@ -53,6 +53,7 @@ class AnvilResultListener : Listener { fun anvilExtractionCheck(event: InventoryClickEvent) { val player = event.whoClicked as? Player ?: return val inventory = event.inventory as? AnvilInventory ?: return + val view = event.view if (event.rawSlot != ANVIL_OUTPUT_SLOT) { return @@ -74,7 +75,7 @@ class AnvilResultListener : Listener { } // Test custom recipe - val customRecipeResult = AnvilMergeLogic.testCustomRecipe(player, leftItem, rightItem) + val customRecipeResult = AnvilMergeLogic.testCustomRecipe(view, inventory, player, leftItem, rightItem) if (!customRecipeResult.isEmpty()) { onCustomCraft( event, player, inventory, @@ -90,7 +91,7 @@ class AnvilResultListener : Listener { // Rename if (rightItem == null) { - val result = AnvilMergeLogic.doRenaming(inventory, player, leftItem) + val result = AnvilMergeLogic.doRenaming(view, inventory, player, leftItem) if (result.isEmpty()) return extractAnvilResult( @@ -105,7 +106,7 @@ class AnvilResultListener : Listener { // Merge val canMerge = leftItem.canMergeWith(rightItem) if (canMerge) { - val result = AnvilMergeLogic.doMerge(inventory, player, leftItem, rightItem) + val result = AnvilMergeLogic.doMerge(view, inventory, player, leftItem, rightItem) extractAnvilResult( event, player, inventory, @@ -118,7 +119,7 @@ class AnvilResultListener : Listener { // Unit repair val unitRepairResult = AnvilMergeLogic.testUnitRepair( - inventory, player, + view, inventory, player, leftItem, rightItem ) if (unitRepairResult.isEmpty()) { @@ -481,6 +482,8 @@ class AnvilResultListener : Listener { ) { val paperMeta = rightItem.itemMeta ?: return + + val paperCopy: ItemStack? if (LoreEditType.APPEND_PAPER.doConsume) { paperCopy = null diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt index 21438ae..b2f6785 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt @@ -11,6 +11,7 @@ import org.bukkit.event.EventPriority import org.bukkit.event.Listener import org.bukkit.event.inventory.PrepareAnvilEvent import org.bukkit.inventory.AnvilInventory +import org.bukkit.inventory.InventoryView import org.bukkit.inventory.ItemStack import org.bukkit.inventory.meta.EnchantmentStorageMeta import org.bukkit.inventory.meta.ItemMeta @@ -91,11 +92,12 @@ class PrepareAnvilListener : Listener { if (!player.hasPermission(CustomAnvil.affectedByPluginPermission)) return - val result = getResult(inventory, player, first, second) + val result = getResult(view, inventory, player, first, second) applyResult(event, player, result) } fun getResult( + view: InventoryView, //TODO use anvil view inventory: AnvilInventory, player: Player, first: ItemStack?, second: ItemStack?) : AnvilResult @@ -104,7 +106,7 @@ class PrepareAnvilListener : Listener { return AnvilResult.EMPTY // Test custom recipe - var result: AnvilResult = testCustomRecipe(player, first, second) + var result: AnvilResult = testCustomRecipe(view, inventory, player, first, second) if (!result.isEmpty()) return result @@ -112,14 +114,14 @@ class PrepareAnvilListener : Listener { val shouldTryRename = second.isAir CustomAnvil.verboseLog("checking air in main logic: $shouldTryRename") if (shouldTryRename) - return doRenaming(inventory, player, first) + return doRenaming(view, inventory, player, first) // Test for merge if (first.canMergeWith(second!!)) - return doMerge(inventory, player, first, second) + return doMerge(view, inventory, player, first, second) // Test for unit repair - result = testUnitRepair(inventory, player, first, second) + result = testUnitRepair(view, inventory, player, first, second) if (!result.isEmpty()) return result