diff --git a/api/src/main/java/lol/pyr/znpcsplus/api/event/NpcDespawnEvent.java b/api/src/main/java/lol/pyr/znpcsplus/api/event/NpcDespawnEvent.java index 89c91ad..904c0c0 100644 --- a/api/src/main/java/lol/pyr/znpcsplus/api/event/NpcDespawnEvent.java +++ b/api/src/main/java/lol/pyr/znpcsplus/api/event/NpcDespawnEvent.java @@ -1,4 +1,20 @@ package lol.pyr.znpcsplus.api.event; -public class NpcDespawnEvent { +import lol.pyr.znpcsplus.api.event.util.CancellableNpcEvent; +import lol.pyr.znpcsplus.api.npc.NpcEntry; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +public class NpcDespawnEvent extends CancellableNpcEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + + public NpcDespawnEvent(Player player, NpcEntry entry) { + super(player, entry); + } + + @Override + public HandlerList getHandlers() { + return handlers; + } } diff --git a/api/src/main/java/lol/pyr/znpcsplus/api/event/NpcInteractEvent.java b/api/src/main/java/lol/pyr/znpcsplus/api/event/NpcInteractEvent.java new file mode 100644 index 0000000..3c83649 --- /dev/null +++ b/api/src/main/java/lol/pyr/znpcsplus/api/event/NpcInteractEvent.java @@ -0,0 +1,28 @@ +package lol.pyr.znpcsplus.api.event; + +import lol.pyr.znpcsplus.api.event.util.CancellableNpcEvent; +import lol.pyr.znpcsplus.api.interaction.InteractionType; +import lol.pyr.znpcsplus.api.npc.NpcEntry; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +public class NpcInteractEvent extends CancellableNpcEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + + private final InteractionType clickType; + + public NpcInteractEvent(Player player, NpcEntry entry, InteractionType clickType) { + super(player, entry); + this.clickType = clickType; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public InteractionType getClickType() { + return clickType; + } +} diff --git a/api/src/main/java/lol/pyr/znpcsplus/api/event/NpcSpawnEvent.java b/api/src/main/java/lol/pyr/znpcsplus/api/event/NpcSpawnEvent.java index 4fab38b..e83cb8f 100644 --- a/api/src/main/java/lol/pyr/znpcsplus/api/event/NpcSpawnEvent.java +++ b/api/src/main/java/lol/pyr/znpcsplus/api/event/NpcSpawnEvent.java @@ -1,4 +1,20 @@ package lol.pyr.znpcsplus.api.event; -public class NpcSpawnEvent { +import lol.pyr.znpcsplus.api.event.util.CancellableNpcEvent; +import lol.pyr.znpcsplus.api.npc.NpcEntry; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +public class NpcSpawnEvent extends CancellableNpcEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + + public NpcSpawnEvent(Player player, NpcEntry entry) { + super(player, entry); + } + + @Override + public HandlerList getHandlers() { + return handlers; + } } diff --git a/api/src/main/java/lol/pyr/znpcsplus/api/event/util/CancellableNpcEvent.java b/api/src/main/java/lol/pyr/znpcsplus/api/event/util/CancellableNpcEvent.java new file mode 100644 index 0000000..1eeba55 --- /dev/null +++ b/api/src/main/java/lol/pyr/znpcsplus/api/event/util/CancellableNpcEvent.java @@ -0,0 +1,23 @@ +package lol.pyr.znpcsplus.api.event.util; + +import lol.pyr.znpcsplus.api.npc.NpcEntry; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; + +public abstract class CancellableNpcEvent extends NpcEvent implements Cancellable { + private boolean cancelled = false; + + public CancellableNpcEvent(Player player, NpcEntry entry) { + super(player, entry); + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancel) { + cancelled = cancel; + } +} diff --git a/api/src/main/java/lol/pyr/znpcsplus/api/event/util/NpcEvent.java b/api/src/main/java/lol/pyr/znpcsplus/api/event/util/NpcEvent.java new file mode 100644 index 0000000..9e2f7d3 --- /dev/null +++ b/api/src/main/java/lol/pyr/znpcsplus/api/event/util/NpcEvent.java @@ -0,0 +1,29 @@ +package lol.pyr.znpcsplus.api.event.util; + +import lol.pyr.znpcsplus.api.npc.Npc; +import lol.pyr.znpcsplus.api.npc.NpcEntry; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; + +public abstract class NpcEvent extends Event { + private final NpcEntry entry; + private final Player player; + + public NpcEvent(Player player, NpcEntry entry) { + super(true); // All events are async since 95% of the plugin is async + this.entry = entry; + this.player = player; + } + + public Player getPlayer() { + return player; + } + + public NpcEntry getEntry() { + return entry; + } + + public Npc getNpc() { + return entry.getNpc(); + } +} diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/interaction/InteractionType.java b/api/src/main/java/lol/pyr/znpcsplus/api/interaction/InteractionType.java similarity index 65% rename from plugin/src/main/java/lol/pyr/znpcsplus/interaction/InteractionType.java rename to api/src/main/java/lol/pyr/znpcsplus/api/interaction/InteractionType.java index 801f2a1..4c88f8f 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/interaction/InteractionType.java +++ b/api/src/main/java/lol/pyr/znpcsplus/api/interaction/InteractionType.java @@ -1,4 +1,4 @@ -package lol.pyr.znpcsplus.interaction; +package lol.pyr.znpcsplus.api.interaction; public enum InteractionType { ANY_CLICK, diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java b/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java index 7f03be8..288d014 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java @@ -25,7 +25,7 @@ import lol.pyr.znpcsplus.entity.EntityPropertyImpl; import lol.pyr.znpcsplus.entity.EntityPropertyRegistryImpl; import lol.pyr.znpcsplus.interaction.ActionRegistry; import lol.pyr.znpcsplus.interaction.InteractionPacketListener; -import lol.pyr.znpcsplus.interaction.InteractionType; +import lol.pyr.znpcsplus.api.interaction.InteractionType; import lol.pyr.znpcsplus.metadata.*; import lol.pyr.znpcsplus.npc.*; import lol.pyr.znpcsplus.packets.*; diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/interaction/InteractionAction.java b/plugin/src/main/java/lol/pyr/znpcsplus/interaction/InteractionAction.java index 3d4867d..6837a04 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/interaction/InteractionAction.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/interaction/InteractionAction.java @@ -1,5 +1,6 @@ package lol.pyr.znpcsplus.interaction; +import lol.pyr.znpcsplus.api.interaction.InteractionType; import org.bukkit.entity.Player; import java.util.UUID; diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/interaction/InteractionPacketListener.java b/plugin/src/main/java/lol/pyr/znpcsplus/interaction/InteractionPacketListener.java index 0aee012..513f566 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/interaction/InteractionPacketListener.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/interaction/InteractionPacketListener.java @@ -4,11 +4,14 @@ import com.github.retrooper.packetevents.event.PacketListener; import com.github.retrooper.packetevents.event.PacketReceiveEvent; import com.github.retrooper.packetevents.protocol.packettype.PacketType; import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity; +import lol.pyr.znpcsplus.api.event.NpcInteractEvent; +import lol.pyr.znpcsplus.api.interaction.InteractionType; import lol.pyr.znpcsplus.npc.NpcEntryImpl; import lol.pyr.znpcsplus.npc.NpcImpl; import lol.pyr.znpcsplus.npc.NpcRegistryImpl; import lol.pyr.znpcsplus.user.User; import lol.pyr.znpcsplus.user.UserManager; +import org.bukkit.Bukkit; import org.bukkit.entity.Player; public class InteractionPacketListener implements PacketListener { @@ -32,23 +35,27 @@ public class InteractionPacketListener implements PacketListener { NpcEntryImpl entry = npcRegistry.getByEntityId(packet.getEntityId()); if (entry == null || !entry.isProcessed()) return; NpcImpl npc = entry.getNpc(); + InteractionType type = wrapClickType(packet.getAction()); + + NpcInteractEvent interactEvent = new NpcInteractEvent(player, entry, type); + Bukkit.getPluginManager().callEvent(interactEvent); + if (interactEvent.isCancelled()) return; for (InteractionAction action : npc.getActions()) { - if (!isAllowed(action.getInteractionType(), packet.getAction())) continue; + if (action.getInteractionType() != InteractionType.ANY_CLICK && action.getInteractionType() != type) continue; if (action.getCooldown() > 0 && !user.actionCooldownCheck(action)) continue; action.run(player); } } - private boolean isAllowed(InteractionType type, WrapperPlayClientInteractEntity.InteractAction action) { - switch (type) { - case ANY_CLICK: - return true; - case LEFT_CLICK: - return action == WrapperPlayClientInteractEntity.InteractAction.ATTACK; - case RIGHT_CLICK: - return action == WrapperPlayClientInteractEntity.InteractAction.INTERACT || action == WrapperPlayClientInteractEntity.InteractAction.INTERACT_AT; + private InteractionType wrapClickType(WrapperPlayClientInteractEntity.InteractAction action) { + switch (action) { + case ATTACK: + return InteractionType.LEFT_CLICK; + case INTERACT: + case INTERACT_AT: + return InteractionType.RIGHT_CLICK; } - return false; + throw new IllegalStateException(); } } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/interaction/consolecommand/ConsoleCommandAction.java b/plugin/src/main/java/lol/pyr/znpcsplus/interaction/consolecommand/ConsoleCommandAction.java index a5a9090..0bbdded 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/interaction/consolecommand/ConsoleCommandAction.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/interaction/consolecommand/ConsoleCommandAction.java @@ -1,7 +1,7 @@ package lol.pyr.znpcsplus.interaction.consolecommand; import lol.pyr.znpcsplus.interaction.InteractionAction; -import lol.pyr.znpcsplus.interaction.InteractionType; +import lol.pyr.znpcsplus.api.interaction.InteractionType; import lol.pyr.znpcsplus.scheduling.TaskScheduler; import lol.pyr.znpcsplus.util.PapiUtil; import org.bukkit.Bukkit; diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/interaction/consolecommand/ConsoleCommandActionType.java b/plugin/src/main/java/lol/pyr/znpcsplus/interaction/consolecommand/ConsoleCommandActionType.java index 70ef3f9..23f7f86 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/interaction/consolecommand/ConsoleCommandActionType.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/interaction/consolecommand/ConsoleCommandActionType.java @@ -4,7 +4,7 @@ import lol.pyr.director.adventure.command.CommandContext; import lol.pyr.director.common.command.CommandExecutionException; import lol.pyr.znpcsplus.interaction.InteractionActionType; import lol.pyr.znpcsplus.interaction.InteractionCommandHandler; -import lol.pyr.znpcsplus.interaction.InteractionType; +import lol.pyr.znpcsplus.api.interaction.InteractionType; import lol.pyr.znpcsplus.npc.NpcEntryImpl; import lol.pyr.znpcsplus.npc.NpcRegistryImpl; import lol.pyr.znpcsplus.scheduling.TaskScheduler; diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/interaction/message/MessageAction.java b/plugin/src/main/java/lol/pyr/znpcsplus/interaction/message/MessageAction.java index 3b9205d..daa411f 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/interaction/message/MessageAction.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/interaction/message/MessageAction.java @@ -1,7 +1,7 @@ package lol.pyr.znpcsplus.interaction.message; import lol.pyr.znpcsplus.interaction.InteractionAction; -import lol.pyr.znpcsplus.interaction.InteractionType; +import lol.pyr.znpcsplus.api.interaction.InteractionType; import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.text.Component; import org.bukkit.entity.Player; diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/interaction/message/MessageActionType.java b/plugin/src/main/java/lol/pyr/znpcsplus/interaction/message/MessageActionType.java index f968fac..c6438d6 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/interaction/message/MessageActionType.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/interaction/message/MessageActionType.java @@ -4,7 +4,7 @@ import lol.pyr.director.adventure.command.CommandContext; import lol.pyr.director.common.command.CommandExecutionException; import lol.pyr.znpcsplus.interaction.InteractionActionType; import lol.pyr.znpcsplus.interaction.InteractionCommandHandler; -import lol.pyr.znpcsplus.interaction.InteractionType; +import lol.pyr.znpcsplus.api.interaction.InteractionType; import lol.pyr.znpcsplus.npc.NpcEntryImpl; import lol.pyr.znpcsplus.npc.NpcRegistryImpl; import net.kyori.adventure.platform.bukkit.BukkitAudiences; diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/interaction/playercommand/PlayerCommandAction.java b/plugin/src/main/java/lol/pyr/znpcsplus/interaction/playercommand/PlayerCommandAction.java index cf65df9..19a29b8 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/interaction/playercommand/PlayerCommandAction.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/interaction/playercommand/PlayerCommandAction.java @@ -1,7 +1,7 @@ package lol.pyr.znpcsplus.interaction.playercommand; import lol.pyr.znpcsplus.interaction.InteractionAction; -import lol.pyr.znpcsplus.interaction.InteractionType; +import lol.pyr.znpcsplus.api.interaction.InteractionType; import lol.pyr.znpcsplus.scheduling.TaskScheduler; import lol.pyr.znpcsplus.util.PapiUtil; import org.bukkit.Bukkit; diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/interaction/playercommand/PlayerCommandActionType.java b/plugin/src/main/java/lol/pyr/znpcsplus/interaction/playercommand/PlayerCommandActionType.java index 0e4a7c2..8684c69 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/interaction/playercommand/PlayerCommandActionType.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/interaction/playercommand/PlayerCommandActionType.java @@ -4,7 +4,7 @@ import lol.pyr.director.adventure.command.CommandContext; import lol.pyr.director.common.command.CommandExecutionException; import lol.pyr.znpcsplus.interaction.InteractionActionType; import lol.pyr.znpcsplus.interaction.InteractionCommandHandler; -import lol.pyr.znpcsplus.interaction.InteractionType; +import lol.pyr.znpcsplus.api.interaction.InteractionType; import lol.pyr.znpcsplus.npc.NpcEntryImpl; import lol.pyr.znpcsplus.npc.NpcRegistryImpl; import lol.pyr.znpcsplus.scheduling.TaskScheduler; diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/interaction/switchserver/SwitchServerAction.java b/plugin/src/main/java/lol/pyr/znpcsplus/interaction/switchserver/SwitchServerAction.java index 4cac69b..3c4cccb 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/interaction/switchserver/SwitchServerAction.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/interaction/switchserver/SwitchServerAction.java @@ -1,7 +1,7 @@ package lol.pyr.znpcsplus.interaction.switchserver; import lol.pyr.znpcsplus.interaction.InteractionAction; -import lol.pyr.znpcsplus.interaction.InteractionType; +import lol.pyr.znpcsplus.api.interaction.InteractionType; import lol.pyr.znpcsplus.util.BungeeConnector; import org.bukkit.entity.Player; diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/interaction/switchserver/SwitchServerActionType.java b/plugin/src/main/java/lol/pyr/znpcsplus/interaction/switchserver/SwitchServerActionType.java index 69929cf..7c598e4 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/interaction/switchserver/SwitchServerActionType.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/interaction/switchserver/SwitchServerActionType.java @@ -4,7 +4,7 @@ import lol.pyr.director.adventure.command.CommandContext; import lol.pyr.director.common.command.CommandExecutionException; import lol.pyr.znpcsplus.interaction.InteractionActionType; import lol.pyr.znpcsplus.interaction.InteractionCommandHandler; -import lol.pyr.znpcsplus.interaction.InteractionType; +import lol.pyr.znpcsplus.api.interaction.InteractionType; import lol.pyr.znpcsplus.npc.NpcEntryImpl; import lol.pyr.znpcsplus.npc.NpcRegistryImpl; import lol.pyr.znpcsplus.util.BungeeConnector; diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/parsers/InteractionTypeParser.java b/plugin/src/main/java/lol/pyr/znpcsplus/parsers/InteractionTypeParser.java index a5dbcce..68adcaa 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/parsers/InteractionTypeParser.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/parsers/InteractionTypeParser.java @@ -4,7 +4,7 @@ import lol.pyr.director.adventure.command.CommandContext; import lol.pyr.director.adventure.parse.ParserType; import lol.pyr.director.common.command.CommandExecutionException; import lol.pyr.director.common.message.Message; -import lol.pyr.znpcsplus.interaction.InteractionType; +import lol.pyr.znpcsplus.api.interaction.InteractionType; import java.util.Deque; diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/tasks/NpcProcessorTask.java b/plugin/src/main/java/lol/pyr/znpcsplus/tasks/NpcProcessorTask.java index 43b4b05..67efca9 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/tasks/NpcProcessorTask.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/tasks/NpcProcessorTask.java @@ -1,5 +1,7 @@ package lol.pyr.znpcsplus.tasks; +import lol.pyr.znpcsplus.api.event.NpcDespawnEvent; +import lol.pyr.znpcsplus.api.event.NpcSpawnEvent; import lol.pyr.znpcsplus.config.ConfigManager; import lol.pyr.znpcsplus.entity.EntityPropertyImpl; import lol.pyr.znpcsplus.entity.EntityPropertyRegistryImpl; @@ -38,9 +40,19 @@ public class NpcProcessorTask extends BukkitRunnable { // visibility boolean inRange = distance <= distSq; - if (!inRange && npc.isShown(player)) npc.hide(player); + if (!inRange && npc.isShown(player)) { + NpcDespawnEvent event = new NpcDespawnEvent(player, entry); + Bukkit.getPluginManager().callEvent(event); + if (!event.isCancelled()) npc.hide(player); + } if (inRange) { - if (!npc.isShown(player)) npc.show(player); + if (!npc.isShown(player)) { + NpcSpawnEvent event = new NpcSpawnEvent(player, entry); + Bukkit.getPluginManager().callEvent(event); + if (event.isCancelled()) continue; + + npc.show(player); + } if (distance < closestDist) { closestDist = distance; closest = player;