mirror of
https://github.com/alexcrea/CustomAnvil.git
synced 2026-06-23 16:16:17 +02:00
add listener api events (#73)
This commit is contained in:
commit
f740248a85
12 changed files with 536 additions and 37 deletions
|
|
@ -3,6 +3,23 @@ package xyz.alexcrea.cuanvil.api.event;
|
||||||
import org.bukkit.event.Event;
|
import org.bukkit.event.Event;
|
||||||
import org.bukkit.event.HandlerList;
|
import org.bukkit.event.HandlerList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the configuration of CustomAnvil is ready.
|
||||||
|
* It is called either on the plugin startup or on the plugin config reload.
|
||||||
|
* <p>
|
||||||
|
* If you want to listen to the first trigger of this event (first configuration load. aka plugin load)
|
||||||
|
* you will need to register the listener on your plugin onEnable or earlier
|
||||||
|
* <p>
|
||||||
|
* This event indicate that can start to register your recipes, item groups and conflicts.
|
||||||
|
* The vanilla and custom enchantments should already have been provided to CustomAnvil.
|
||||||
|
* Configuration can be changed any time after this event is triggered but never before.
|
||||||
|
* <p>
|
||||||
|
* use {@link xyz.alexcrea.cuanvil.api.ConflictAPI ConflictApi},
|
||||||
|
* {@link xyz.alexcrea.cuanvil.gui.config.global.CustomRecipeConfigGui CustomRecipeConfigGui},
|
||||||
|
* {@link xyz.alexcrea.cuanvil.api.MaterialGroupApi MaterialGroupApi}
|
||||||
|
* and {@link xyz.alexcrea.cuanvil.api.UnitRepairApi UnitRepairApi}
|
||||||
|
* to add/remove/edit configurations
|
||||||
|
*/
|
||||||
public class CAConfigReadyEvent extends Event {
|
public class CAConfigReadyEvent extends Event {
|
||||||
|
|
||||||
private static final HandlerList HANDLERS = new HandlerList();
|
private static final HandlerList HANDLERS = new HandlerList();
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,17 @@ package xyz.alexcrea.cuanvil.api.event;
|
||||||
import org.bukkit.event.Event;
|
import org.bukkit.event.Event;
|
||||||
import org.bukkit.event.HandlerList;
|
import org.bukkit.event.HandlerList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when custom anvil is ready to accept registration on custom enchantment.
|
||||||
|
* <p>
|
||||||
|
* If you want to listen this event
|
||||||
|
* you will need to register the listener on your plugin onEnable or earlier
|
||||||
|
* <p>
|
||||||
|
* Custom enchantments may be registered later but may cause issue if registered too later
|
||||||
|
* (after configuration loading phase. see {@link CAConfigReadyEvent})
|
||||||
|
* <p>
|
||||||
|
* use {@link xyz.alexcrea.cuanvil.api.EnchantmentApi EnchantmentApi} to register and unregister your custom enchantments
|
||||||
|
*/
|
||||||
public class CAEnchantRegistryReadyEvent extends Event {
|
public class CAEnchantRegistryReadyEvent extends Event {
|
||||||
|
|
||||||
private static final HandlerList HANDLERS = new HandlerList();
|
private static final HandlerList HANDLERS = new HandlerList();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
package xyz.alexcrea.cuanvil.api.event.listener;
|
||||||
|
|
||||||
|
import org.bukkit.event.Cancellable;
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called before custom anvil process the click on the result on the anvil inventory.
|
||||||
|
* <p>
|
||||||
|
* This event is called after checking that the inventory is an anvil inventory and that the click is on the result slot
|
||||||
|
* but before checking if the player has the custom anvil affected permission.
|
||||||
|
* <p>
|
||||||
|
* This event being cancelled will make CustomAnvil abort the click on result process.
|
||||||
|
* <p>
|
||||||
|
* Most of the time you would likely need {@link CAPreAnvilBypassEvent} or {@link CAEarlyPreAnvilBypassEvent}
|
||||||
|
* for this event to be useful.
|
||||||
|
* <p>
|
||||||
|
* There is also {@link CATreatAnvilResultEvent} that may be better for some use case.
|
||||||
|
*/
|
||||||
|
public class CAClickResultBypassEvent extends Event implements Cancellable {
|
||||||
|
|
||||||
|
private static final HandlerList HANDLERS = new HandlerList();
|
||||||
|
|
||||||
|
public static HandlerList getHandlerList() {
|
||||||
|
return HANDLERS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull HandlerList getHandlers() {
|
||||||
|
return HANDLERS;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean cancelled = false;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCancelled() {
|
||||||
|
return cancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCancelled(boolean cancel) {
|
||||||
|
this.cancelled = cancel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final InventoryClickEvent event;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the bukkit inventory click event causing to this event
|
||||||
|
*
|
||||||
|
* @return The click event causing to this event
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public InventoryClickEvent getEvent() {
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CAClickResultBypassEvent(@NotNull InventoryClickEvent event) {
|
||||||
|
this.event = event;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
package xyz.alexcrea.cuanvil.api.event.listener;
|
||||||
|
|
||||||
|
import org.bukkit.event.Cancellable;
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.bukkit.event.inventory.PrepareAnvilEvent;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called before custom anvil process the prepare anvil event.
|
||||||
|
* <p>
|
||||||
|
* This event will always get called when CustomAnvil need to handle
|
||||||
|
* <p>
|
||||||
|
* This event being cancelled will make CustomAnvil abort the anvil process.
|
||||||
|
* <p>
|
||||||
|
* You should also use {@link CAClickResultBypassEvent} if you want to use this event for something useful.
|
||||||
|
* <p>
|
||||||
|
* It is also recommended that you read about {@link CAPreAnvilBypassEvent} and {@link CATreatAnvilResultEvent}
|
||||||
|
* as your use case may be more prone to use theses.
|
||||||
|
*/
|
||||||
|
public class CAEarlyPreAnvilBypassEvent extends Event implements Cancellable {
|
||||||
|
|
||||||
|
private static final HandlerList HANDLERS = new HandlerList();
|
||||||
|
|
||||||
|
public static HandlerList getHandlerList() {
|
||||||
|
return HANDLERS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull HandlerList getHandlers() {
|
||||||
|
return HANDLERS;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean cancelled = false;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCancelled() {
|
||||||
|
return cancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCancelled(boolean cancel) {
|
||||||
|
this.cancelled = cancel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final PrepareAnvilEvent event;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the bukkit pre anvil event causing this event
|
||||||
|
*
|
||||||
|
* @return The pre anvil event causing to this event
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public PrepareAnvilEvent getEvent() {
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CAEarlyPreAnvilBypassEvent(@NotNull PrepareAnvilEvent event) {
|
||||||
|
this.event = event;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
package xyz.alexcrea.cuanvil.api.event.listener;
|
||||||
|
|
||||||
|
import org.bukkit.event.Cancellable;
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.bukkit.event.inventory.PrepareAnvilEvent;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called before custom anvil process the prepare anvil event.
|
||||||
|
* <p>
|
||||||
|
* This event is called after {@link CAEarlyPreAnvilBypassEvent},
|
||||||
|
* after checking that there is at least an item on the left slot
|
||||||
|
* and after checking if any of the 2 item is marked as immutable
|
||||||
|
* but before checking if the player has the custom anvil affected permission.
|
||||||
|
* <p>
|
||||||
|
* This event being cancelled will make CustomAnvil abort the anvil process.
|
||||||
|
* <p>
|
||||||
|
* You should also use {@link CAClickResultBypassEvent} if you want to use this event for something useful.
|
||||||
|
* <p>
|
||||||
|
* It is also recommended that you read about {@link CAEarlyPreAnvilBypassEvent} and {@link CATreatAnvilResultEvent}
|
||||||
|
* as your use case may be more prone to use theses.
|
||||||
|
*/
|
||||||
|
public class CAPreAnvilBypassEvent extends Event implements Cancellable {
|
||||||
|
|
||||||
|
private static final HandlerList HANDLERS = new HandlerList();
|
||||||
|
|
||||||
|
public static HandlerList getHandlerList() {
|
||||||
|
return HANDLERS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull HandlerList getHandlers() {
|
||||||
|
return HANDLERS;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean cancelled = false;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCancelled() {
|
||||||
|
return cancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCancelled(boolean cancel) {
|
||||||
|
this.cancelled = cancel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final PrepareAnvilEvent event;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the bukkit pre anvil event causing this event
|
||||||
|
*
|
||||||
|
* @return The pre anvil event causing this event
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public PrepareAnvilEvent getEvent() {
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CAPreAnvilBypassEvent(@NotNull PrepareAnvilEvent event) {
|
||||||
|
this.event = event;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,131 @@
|
||||||
|
package xyz.alexcrea.cuanvil.api.event.listener;
|
||||||
|
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.bukkit.event.inventory.PrepareAnvilEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import xyz.alexcrea.cuanvil.util.AnvilUseType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
* <p>
|
||||||
|
* You may also want to check {@link CAClickResultBypassEvent},
|
||||||
|
* {@link CAPreAnvilBypassEvent}
|
||||||
|
* and {@link CAEarlyPreAnvilBypassEvent} for your use case
|
||||||
|
* <p>
|
||||||
|
* A null result will cancel this pre anvil event
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class CATreatAnvilResultEvent 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 PrepareAnvilEvent event;
|
||||||
|
|
||||||
|
private final AnvilUseType useType;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private ItemStack result;
|
||||||
|
|
||||||
|
private int levelCost;
|
||||||
|
|
||||||
|
public CATreatAnvilResultEvent(@NotNull PrepareAnvilEvent event, AnvilUseType useType, @Nullable ItemStack result, int levelCost) {
|
||||||
|
this.event = event;
|
||||||
|
this.useType = useType;
|
||||||
|
this.result = result;
|
||||||
|
this.levelCost = levelCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the bukkit inventory click event causing to this event.
|
||||||
|
*
|
||||||
|
* @return The click event causing to this event.
|
||||||
|
*/
|
||||||
|
public @NotNull PrepareAnvilEvent getEvent() {
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the type of use source of the result.
|
||||||
|
*
|
||||||
|
* @return The craft use type.
|
||||||
|
*/
|
||||||
|
public AnvilUseType getUseType() {
|
||||||
|
return useType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current result
|
||||||
|
* <p>
|
||||||
|
* 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
|
||||||
|
* <p>
|
||||||
|
* 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.
|
||||||
|
* <h3>Important note:</h3>
|
||||||
|
* the final price are re calculated on click for the following use case:
|
||||||
|
* <ul>
|
||||||
|
* <li>Custom craft</li>
|
||||||
|
* <li>Unit repair</li>
|
||||||
|
* <li>Lore edit</li>
|
||||||
|
* </ul>
|
||||||
|
* This value will be used as final price for:
|
||||||
|
* <li>Item merge</li>
|
||||||
|
* <li>Item rename</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @return The current cost.
|
||||||
|
*/
|
||||||
|
public int getLevelCost() {
|
||||||
|
return levelCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the level cost displayed on the anvil.
|
||||||
|
* <h3>Important note:</h3>
|
||||||
|
* the final price are re calculated on click for the following use case:
|
||||||
|
* <ul>
|
||||||
|
* <li>Custom craft</li>
|
||||||
|
* <li>Unit repair</li>
|
||||||
|
* <li>Lore edit</li>
|
||||||
|
* </ul>
|
||||||
|
* This value will be used as final price for:
|
||||||
|
* <li>Item merge</li>
|
||||||
|
* <li>Item rename</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @param levelCost The new cost.
|
||||||
|
*/
|
||||||
|
public void setLevelCost(int levelCost) {
|
||||||
|
this.levelCost = levelCost;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -8,6 +8,10 @@ import org.bukkit.event.inventory.InventoryClickEvent
|
||||||
import org.bukkit.event.inventory.PrepareAnvilEvent
|
import org.bukkit.event.inventory.PrepareAnvilEvent
|
||||||
import org.bukkit.inventory.AnvilInventory
|
import org.bukkit.inventory.AnvilInventory
|
||||||
import org.bukkit.inventory.ItemStack
|
import org.bukkit.inventory.ItemStack
|
||||||
|
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.config.ConfigHolder
|
import xyz.alexcrea.cuanvil.config.ConfigHolder
|
||||||
import xyz.alexcrea.cuanvil.dependency.datapack.DataPackDependency
|
import xyz.alexcrea.cuanvil.dependency.datapack.DataPackDependency
|
||||||
import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester
|
import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester
|
||||||
|
|
@ -19,6 +23,7 @@ import xyz.alexcrea.cuanvil.dependency.scheduler.BukkitScheduler
|
||||||
import xyz.alexcrea.cuanvil.dependency.scheduler.FoliaScheduler
|
import xyz.alexcrea.cuanvil.dependency.scheduler.FoliaScheduler
|
||||||
import xyz.alexcrea.cuanvil.dependency.scheduler.TaskScheduler
|
import xyz.alexcrea.cuanvil.dependency.scheduler.TaskScheduler
|
||||||
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_OUTPUT_SLOT
|
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_OUTPUT_SLOT
|
||||||
|
import xyz.alexcrea.cuanvil.util.AnvilUseType
|
||||||
import java.util.logging.Level
|
import java.util.logging.Level
|
||||||
|
|
||||||
object DependencyManager {
|
object DependencyManager {
|
||||||
|
|
@ -139,10 +144,14 @@ object DependencyManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun earlyUnsafeTryEventPreAnvilBypass(event: PrepareAnvilEvent, player: HumanEntity): Boolean {
|
private fun earlyUnsafeTryEventPreAnvilBypass(event: PrepareAnvilEvent, player: HumanEntity): Boolean {
|
||||||
var bypass = false
|
// Run the event
|
||||||
|
val bypassEvent = CAEarlyPreAnvilBypassEvent(event)
|
||||||
|
Bukkit.getPluginManager().callEvent(bypassEvent)
|
||||||
|
|
||||||
|
var bypass = bypassEvent.isCancelled
|
||||||
|
|
||||||
// Test if the inventory is a gui(version specific)
|
// Test if the inventory is a gui(version specific)
|
||||||
if (externGuiTester?.testIfGui(event.view) == true) bypass = true
|
if (!bypass && (externGuiTester?.testIfGui(event.view) == true)) bypass = true
|
||||||
|
|
||||||
return bypass
|
return bypass
|
||||||
}
|
}
|
||||||
|
|
@ -171,10 +180,14 @@ object DependencyManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun unsafeTryEventPreAnvilBypass(event: PrepareAnvilEvent, player: HumanEntity): Boolean {
|
private fun unsafeTryEventPreAnvilBypass(event: PrepareAnvilEvent, player: HumanEntity): Boolean {
|
||||||
var bypass = false
|
// Run the event
|
||||||
|
val bypassEvent = CAPreAnvilBypassEvent(event)
|
||||||
|
Bukkit.getPluginManager().callEvent(bypassEvent)
|
||||||
|
|
||||||
|
var bypass = bypassEvent.isCancelled
|
||||||
|
|
||||||
// Test if disenchantment used prepare anvil
|
// Test if disenchantment used prepare anvil
|
||||||
if (disenchantmentCompatibility?.testPrepareAnvil(event, player) == true) bypass = true
|
if (!bypass && (disenchantmentCompatibility?.testPrepareAnvil(event, player) == true)) bypass = true
|
||||||
|
|
||||||
// Test heaven bags used prepare anvil
|
// Test heaven bags used prepare anvil
|
||||||
if (!bypass && (havenBagsCompatibility?.testPrepareAnvil(event, player) == true)) bypass = true
|
if (!bypass && (havenBagsCompatibility?.testPrepareAnvil(event, player) == true)) bypass = true
|
||||||
|
|
@ -189,11 +202,12 @@ object DependencyManager {
|
||||||
return bypass
|
return bypass
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return true only if error occurred (and so should bypass rest)
|
// Return null if there was an issue
|
||||||
fun tryTreatAnvilResult(event: PrepareAnvilEvent, result: ItemStack): Boolean {
|
fun tryTreatAnvilResult(event: PrepareAnvilEvent, result: ItemStack, useType: AnvilUseType, cost: Int): CATreatAnvilResultEvent? {
|
||||||
|
val treatEvent = CATreatAnvilResultEvent(event, useType, result, cost)
|
||||||
try {
|
try {
|
||||||
unsafeTryTreatAnvilResult(event, result)
|
unsafeTryTreatAnvilResult(treatEvent)
|
||||||
return false
|
return treatEvent;
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
CustomAnvil.instance.logger.log(
|
CustomAnvil.instance.logger.log(
|
||||||
Level.SEVERE,
|
Level.SEVERE,
|
||||||
|
|
@ -209,12 +223,14 @@ object DependencyManager {
|
||||||
"[" + ChatColor.YELLOW.toString() + "CustomAnvil" + ChatColor.WHITE.toString() + "] " +
|
"[" + ChatColor.YELLOW.toString() + "CustomAnvil" + ChatColor.WHITE.toString() + "] " +
|
||||||
ChatColor.RED.toString() + "Error while handling the anvil."
|
ChatColor.RED.toString() + "Error while handling the anvil."
|
||||||
)
|
)
|
||||||
return true
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun unsafeTryTreatAnvilResult(event: PrepareAnvilEvent, result: ItemStack) {
|
private fun unsafeTryTreatAnvilResult(event: CATreatAnvilResultEvent) {
|
||||||
excellentEnchantsCompatibility?.treatAnvilResult(event, result)
|
Bukkit.getPluginManager().callEvent(event)
|
||||||
|
|
||||||
|
excellentEnchantsCompatibility?.treatAnvilResult(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return true if should bypass (either by a dependency or error)
|
// Return true if should bypass (either by a dependency or error)
|
||||||
|
|
@ -241,10 +257,14 @@ object DependencyManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun unsafeTryClickAnvilResultBypass(event: InventoryClickEvent, inventory: AnvilInventory): Boolean {
|
private fun unsafeTryClickAnvilResultBypass(event: InventoryClickEvent, inventory: AnvilInventory): Boolean {
|
||||||
var bypass = false
|
// Run the event
|
||||||
|
val bypassEvent = CAClickResultBypassEvent(event)
|
||||||
|
Bukkit.getPluginManager().callEvent(bypassEvent)
|
||||||
|
|
||||||
|
var bypass = bypassEvent.isCancelled
|
||||||
|
|
||||||
// Test if disenchantment used event click
|
// Test if disenchantment used event click
|
||||||
if (disenchantmentCompatibility?.testAnvilResult(event, inventory) == true) bypass = true
|
if (!bypass && (disenchantmentCompatibility?.testAnvilResult(event, inventory) == true)) bypass = true
|
||||||
|
|
||||||
// Test if haven bag used event click
|
// Test if haven bag used event click
|
||||||
if (!bypass && (havenBagsCompatibility?.testAnvilResult(event, inventory) == true)) bypass = true
|
if (!bypass && (havenBagsCompatibility?.testAnvilResult(event, inventory) == true)) bypass = true
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import org.bukkit.event.inventory.PrepareAnvilEvent
|
||||||
import org.bukkit.inventory.ItemStack
|
import org.bukkit.inventory.ItemStack
|
||||||
import org.bukkit.plugin.RegisteredListener
|
import org.bukkit.plugin.RegisteredListener
|
||||||
import xyz.alexcrea.cuanvil.api.EnchantmentApi
|
import xyz.alexcrea.cuanvil.api.EnchantmentApi
|
||||||
|
import xyz.alexcrea.cuanvil.api.event.listener.CATreatAnvilResultEvent
|
||||||
import xyz.alexcrea.cuanvil.enchant.wrapped.CAEEPreV5Enchantment
|
import xyz.alexcrea.cuanvil.enchant.wrapped.CAEEPreV5Enchantment
|
||||||
import xyz.alexcrea.cuanvil.enchant.wrapped.CAEEV5Enchantment
|
import xyz.alexcrea.cuanvil.enchant.wrapped.CAEEV5Enchantment
|
||||||
import xyz.alexcrea.cuanvil.enchant.wrapped.CALegacyEEEnchantment
|
import xyz.alexcrea.cuanvil.enchant.wrapped.CALegacyEEEnchantment
|
||||||
|
|
@ -124,18 +125,21 @@ class ExcellentEnchantsDependency {
|
||||||
toUnregister.add(registeredListener)
|
toUnregister.add(registeredListener)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ListenerVersion.PRE_V5 -> {
|
ListenerVersion.PRE_V5 -> {
|
||||||
if (listener is PreV5AnvilListener) {
|
if (listener is PreV5AnvilListener) {
|
||||||
this.preV5AnvilListener = listener
|
this.preV5AnvilListener = listener
|
||||||
toUnregister.add(registeredListener)
|
toUnregister.add(registeredListener)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ListenerVersion.LEGACY -> {
|
ListenerVersion.LEGACY -> {
|
||||||
if (listener is LegacyAnvilListener) {
|
if (listener is LegacyAnvilListener) {
|
||||||
this.legacyAnvilListener = listener
|
this.legacyAnvilListener = listener
|
||||||
toUnregister.add(registeredListener)
|
toUnregister.add(registeredListener)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
null -> {
|
null -> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -188,11 +192,14 @@ class ExcellentEnchantsDependency {
|
||||||
return handleRechargeMethod.invoke(this.usedAnvilListener, event, first, second) as Boolean
|
return handleRechargeMethod.invoke(this.usedAnvilListener, event, first, second) as Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
fun treatAnvilResult(event: PrepareAnvilEvent, result: ItemStack) {
|
fun treatAnvilResult(event: CATreatAnvilResultEvent) {
|
||||||
val first: ItemStack = treatInput(event.inventory.getItem(0))
|
val result = event.result
|
||||||
val second: ItemStack = treatInput(event.inventory.getItem(1))
|
if (result == null) return
|
||||||
|
|
||||||
handleCombineMethod.invoke(this.usedAnvilListener, event, first, second, result)
|
val first: ItemStack = treatInput(event.event.inventory.getItem(0))
|
||||||
|
val second: ItemStack = treatInput(event.event.inventory.getItem(1))
|
||||||
|
|
||||||
|
handleCombineMethod.invoke(this.usedAnvilListener, event.event, first, second, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testAnvilResult(event: InventoryClickEvent): Any {
|
fun testAnvilResult(event: InventoryClickEvent): Any {
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,6 @@ class AnvilResultListener : Listener {
|
||||||
@EventHandler(ignoreCancelled = true)
|
@EventHandler(ignoreCancelled = true)
|
||||||
fun anvilExtractionCheck(event: InventoryClickEvent) {
|
fun anvilExtractionCheck(event: InventoryClickEvent) {
|
||||||
val player = event.whoClicked as? Player ?: return
|
val player = event.whoClicked as? Player ?: return
|
||||||
if (!player.hasPermission(CustomAnvil.affectedByPluginPermission)) return
|
|
||||||
val inventory = event.inventory as? AnvilInventory ?: return
|
val inventory = event.inventory as? AnvilInventory ?: return
|
||||||
|
|
||||||
if (event.rawSlot != ANVIL_OUTPUT_SLOT) {
|
if (event.rawSlot != ANVIL_OUTPUT_SLOT) {
|
||||||
|
|
@ -56,6 +55,8 @@ class AnvilResultListener : Listener {
|
||||||
// Test if the event should bypass custom anvil.
|
// Test if the event should bypass custom anvil.
|
||||||
if (DependencyManager.tryClickAnvilResultBypass(event, inventory)) return
|
if (DependencyManager.tryClickAnvilResultBypass(event, inventory)) return
|
||||||
|
|
||||||
|
if (!player.hasPermission(CustomAnvil.affectedByPluginPermission)) return
|
||||||
|
|
||||||
val output = inventory.getItem(ANVIL_OUTPUT_SLOT) ?: return
|
val output = inventory.getItem(ANVIL_OUTPUT_SLOT) ?: return
|
||||||
val leftItem = inventory.getItem(ANVIL_INPUT_LEFT) ?: return
|
val leftItem = inventory.getItem(ANVIL_INPUT_LEFT) ?: return
|
||||||
val rightItem = inventory.getItem(ANVIL_INPUT_RIGHT)
|
val rightItem = inventory.getItem(ANVIL_INPUT_RIGHT)
|
||||||
|
|
|
||||||
|
|
@ -46,11 +46,15 @@ class PrepareAnvilListener : Listener {
|
||||||
fun anvilCombineCheck(event: PrepareAnvilEvent) {
|
fun anvilCombineCheck(event: PrepareAnvilEvent) {
|
||||||
// Should find player
|
// Should find player
|
||||||
val player: HumanEntity = InventoryViewUtil.getInstance().getPlayer(event.view)
|
val player: HumanEntity = InventoryViewUtil.getInstance().getPlayer(event.view)
|
||||||
|
val inventory = event.inventory
|
||||||
|
|
||||||
// Test if custom anvil is bypassed before immutability test
|
// Test if custom anvil is bypassed before immutability test
|
||||||
if (DependencyManager.earlyTryEventPreAnvilBypass(event, player)) return
|
if (DependencyManager.earlyTryEventPreAnvilBypass(event, player)) {
|
||||||
|
// even if we got bypassed we still want to set price
|
||||||
|
AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, event.inventory.repairCost)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val inventory = event.inventory
|
|
||||||
val first = inventory.getItem(ANVIL_INPUT_LEFT) ?: return
|
val first = inventory.getItem(ANVIL_INPUT_LEFT) ?: return
|
||||||
val second = inventory.getItem(ANVIL_INPUT_RIGHT)
|
val second = inventory.getItem(ANVIL_INPUT_RIGHT)
|
||||||
|
|
||||||
|
|
@ -62,7 +66,11 @@ class PrepareAnvilListener : Listener {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test if the event should bypass custom anvil.
|
// Test if the event should bypass custom anvil.
|
||||||
if (DependencyManager.tryEventPreAnvilBypass(event, player)) return
|
if (DependencyManager.tryEventPreAnvilBypass(event, player)) {
|
||||||
|
// even if we got bypassed we still want to set price
|
||||||
|
AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, event.inventory.repairCost)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (!player.hasPermission(CustomAnvil.affectedByPluginPermission)) return
|
if (!player.hasPermission(CustomAnvil.affectedByPluginPermission)) return
|
||||||
|
|
||||||
|
|
@ -133,16 +141,20 @@ class PrepareAnvilListener : Listener {
|
||||||
val resultItem: ItemStack = recipe.resultItem!!.clone()
|
val resultItem: ItemStack = recipe.resultItem!!.clone()
|
||||||
resultItem.amount *= amount
|
resultItem.amount *= amount
|
||||||
|
|
||||||
event.result = resultItem
|
// Maybe add an option on custom craft to ignore/not ignore penalty ??
|
||||||
if (DependencyManager.tryTreatAnvilResult(event, resultItem)) return true
|
|
||||||
|
|
||||||
val xpCost = recipe.determineCost(amount, first, resultItem)
|
val xpCost = recipe.determineCost(amount, first, resultItem)
|
||||||
|
|
||||||
val levelCost =
|
val levelCost =
|
||||||
if (recipe.removeExactLinearXp) AnvilXpUtil.calculateMinimumLevelForXp(xpCost)
|
if (recipe.removeExactLinearXp) AnvilXpUtil.calculateMinimumLevelForXp(xpCost)
|
||||||
else AnvilXpUtil.calculateLevelForXp(xpCost)
|
else AnvilXpUtil.calculateLevelForXp(xpCost)
|
||||||
|
|
||||||
AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, levelCost, true)
|
val finalResult = DependencyManager.tryTreatAnvilResult(event, resultItem, AnvilUseType.CUSTOM_CRAFT, levelCost)
|
||||||
|
if (finalResult == null) return false
|
||||||
|
|
||||||
|
event.result = finalResult.result
|
||||||
|
if (finalResult.result == null) return false
|
||||||
|
|
||||||
|
AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, finalResult.levelCost, true)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -160,12 +172,15 @@ class PrepareAnvilListener : Listener {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
event.result = resultItem
|
|
||||||
if (DependencyManager.tryTreatAnvilResult(event, resultItem)) return
|
|
||||||
|
|
||||||
anvilCost += AnvilXpUtil.calculatePenalty(first, null, resultItem, AnvilUseType.RENAME_ONLY)
|
anvilCost += AnvilXpUtil.calculatePenalty(first, null, resultItem, AnvilUseType.RENAME_ONLY)
|
||||||
|
|
||||||
AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, anvilCost)
|
val finalResult = DependencyManager.tryTreatAnvilResult(event, resultItem, AnvilUseType.RENAME_ONLY, anvilCost)
|
||||||
|
if (finalResult == null) return
|
||||||
|
|
||||||
|
event.result = finalResult.result
|
||||||
|
if (finalResult.result == null) return
|
||||||
|
|
||||||
|
AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, finalResult.levelCost)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleRename(resultItem: ItemStack, inventory: AnvilInventory, player: HumanEntity): Int {
|
private fun handleRename(resultItem: ItemStack, inventory: AnvilInventory, player: HumanEntity): Int {
|
||||||
|
|
@ -241,10 +256,13 @@ class PrepareAnvilListener : Listener {
|
||||||
anvilCost += handleRename(resultItem, inventory, player)
|
anvilCost += handleRename(resultItem, inventory, player)
|
||||||
|
|
||||||
// Finally, we set result
|
// Finally, we set result
|
||||||
event.result = resultItem
|
val finalResult = DependencyManager.tryTreatAnvilResult(event, resultItem, AnvilUseType.MERGE, anvilCost)
|
||||||
if (DependencyManager.tryTreatAnvilResult(event, resultItem)) return
|
if (finalResult == null) return
|
||||||
|
|
||||||
AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, anvilCost)
|
event.result = finalResult.result
|
||||||
|
if (finalResult.result == null) return
|
||||||
|
|
||||||
|
AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, finalResult.levelCost)
|
||||||
}
|
}
|
||||||
|
|
||||||
// return true if there is a valid unit repair with these ingredients
|
// return true if there is a valid unit repair with these ingredients
|
||||||
|
|
@ -270,10 +288,14 @@ class PrepareAnvilListener : Listener {
|
||||||
event.result = null
|
event.result = null
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
event.result = resultItem
|
|
||||||
if (DependencyManager.tryTreatAnvilResult(event, resultItem)) return true
|
|
||||||
|
|
||||||
AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, anvilCost)
|
val finalResult = DependencyManager.tryTreatAnvilResult(event, resultItem, AnvilUseType.UNIT_REPAIR, anvilCost)
|
||||||
|
if (finalResult == null) return false
|
||||||
|
|
||||||
|
event.result = finalResult.result
|
||||||
|
if (finalResult.result == null) return false
|
||||||
|
|
||||||
|
AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, finalResult.levelCost)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
package xyz.alexcrea.cuanvil.api.event;
|
||||||
|
|
||||||
|
import io.delilaheve.CustomAnvil;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockbukkit.mockbukkit.MockBukkit;
|
||||||
|
import org.mockbukkit.mockbukkit.matcher.plugin.PluginManagerFiredEventClassMatcher;
|
||||||
|
import xyz.alexcrea.cuanvil.tests.SharedOnlyMockBukkit;
|
||||||
|
|
||||||
|
public class CAConfigReadyEventTest extends SharedOnlyMockBukkit {
|
||||||
|
|
||||||
|
private CustomAnvil plugin;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void startup() {
|
||||||
|
boolean beforeStart = PluginManagerFiredEventClassMatcher
|
||||||
|
.hasNotFiredEventInstance(CAConfigReadyEvent.class)
|
||||||
|
.matches(server.getPluginManager());
|
||||||
|
|
||||||
|
Assertions.assertTrue(beforeStart, "Somehow, event fired before plugin being loaded ?");
|
||||||
|
|
||||||
|
// Load the plugin
|
||||||
|
plugin = MockBukkit.load(CustomAnvil.class);
|
||||||
|
|
||||||
|
boolean postStart = PluginManagerFiredEventClassMatcher
|
||||||
|
.hasNotFiredEventInstance(CAConfigReadyEvent.class)
|
||||||
|
.matches(server.getPluginManager());
|
||||||
|
|
||||||
|
Assertions.assertTrue(postStart, "Event fired before plugin finished being loaded");
|
||||||
|
|
||||||
|
// Config load phase
|
||||||
|
server.getScheduler().performOneTick();
|
||||||
|
boolean postConfig = PluginManagerFiredEventClassMatcher
|
||||||
|
.hasFiredEventInstance(CAConfigReadyEvent.class)
|
||||||
|
.matches(server.getPluginManager());
|
||||||
|
|
||||||
|
Assertions.assertTrue(postConfig, "Event did not fire after the config phase");
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void pluginTeardown() {
|
||||||
|
if (plugin != null) {
|
||||||
|
server.getPluginManager().disablePlugin(plugin);
|
||||||
|
plugin = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
package xyz.alexcrea.cuanvil.api.event;
|
||||||
|
|
||||||
|
import io.delilaheve.CustomAnvil;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockbukkit.mockbukkit.MockBukkit;
|
||||||
|
import org.mockbukkit.mockbukkit.matcher.plugin.PluginManagerFiredEventClassMatcher;
|
||||||
|
import xyz.alexcrea.cuanvil.tests.SharedOnlyMockBukkit;
|
||||||
|
|
||||||
|
public class CAEnchantRegistryReadyEventTest extends SharedOnlyMockBukkit {
|
||||||
|
|
||||||
|
private CustomAnvil plugin;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void startup() {
|
||||||
|
boolean beforeStart = PluginManagerFiredEventClassMatcher
|
||||||
|
.hasNotFiredEventInstance(CAEnchantRegistryReadyEvent.class)
|
||||||
|
.matches(server.getPluginManager());
|
||||||
|
|
||||||
|
Assertions.assertTrue(beforeStart, "Somehow, event fired before plugin being loaded ?");
|
||||||
|
|
||||||
|
// Load the plugin
|
||||||
|
plugin = MockBukkit.load(CustomAnvil.class);
|
||||||
|
|
||||||
|
boolean postStart = PluginManagerFiredEventClassMatcher
|
||||||
|
.hasNotFiredEventInstance(CAEnchantRegistryReadyEvent.class)
|
||||||
|
.matches(server.getPluginManager());
|
||||||
|
|
||||||
|
Assertions.assertTrue(postStart, "Event fired before plugin finished being loaded");
|
||||||
|
|
||||||
|
// Config load phase
|
||||||
|
server.getScheduler().performOneTick();
|
||||||
|
boolean postConfig = PluginManagerFiredEventClassMatcher
|
||||||
|
.hasFiredEventInstance(CAEnchantRegistryReadyEvent.class)
|
||||||
|
.matches(server.getPluginManager());
|
||||||
|
|
||||||
|
Assertions.assertTrue(postConfig, "Event did not fire after the config phase");
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void pluginTeardown() {
|
||||||
|
if (plugin != null) {
|
||||||
|
server.getPluginManager().disablePlugin(plugin);
|
||||||
|
plugin = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue