Skip to content

Commit

Permalink
Merge pull request #76 from Arim-Minecraft/master
Browse files Browse the repository at this point in the history
Allow Omitting PlayerMoveEvent
  • Loading branch information
Jitse Boonstra authored Apr 23, 2020
2 parents 54330aa + b4ce4fb commit 3a99792
Show file tree
Hide file tree
Showing 6 changed files with 195 additions and 43 deletions.
19 changes: 18 additions & 1 deletion api/src/main/java/net/jitse/npclib/NPCLib.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@

package net.jitse.npclib;

import net.jitse.npclib.NPCLibOptions.MovementHandling;
import net.jitse.npclib.api.NPC;
import net.jitse.npclib.api.utilities.Logger;
import net.jitse.npclib.listeners.ChunkListener;
import net.jitse.npclib.listeners.PacketListener;
import net.jitse.npclib.listeners.PeriodicMoveListener;
import net.jitse.npclib.listeners.PlayerListener;
import net.jitse.npclib.listeners.PlayerMoveEventListener;
import net.jitse.npclib.metrics.NPCLibMetrics;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
Expand All @@ -23,7 +26,7 @@ public final class NPCLib {

private double autoHideDistance = 50.0;

public NPCLib(JavaPlugin plugin) {
private NPCLib(JavaPlugin plugin, MovementHandling moveHandling) {
this.plugin = plugin;
this.logger = new Logger("NPCLib");

Expand All @@ -49,6 +52,12 @@ public NPCLib(JavaPlugin plugin) {
pluginManager.registerEvents(new PlayerListener(this), plugin);
pluginManager.registerEvents(new ChunkListener(this), plugin);

if (moveHandling.usePme) {
pluginManager.registerEvents(new PlayerMoveEventListener(), plugin);
} else {
pluginManager.registerEvents(new PeriodicMoveListener(this, moveHandling.updateInterval), plugin);
}

// Boot the according packet listener.
new PacketListener().start(this);

Expand All @@ -59,6 +68,14 @@ public NPCLib(JavaPlugin plugin) {
logger.info("Enabled for Minecraft " + versionName);
}

public NPCLib(JavaPlugin plugin) {
this(plugin, MovementHandling.playerMoveEvent());
}

public NPCLib(JavaPlugin plugin, NPCLibOptions options) {
this(plugin, options.moveHandling);
}

/**
* @return The JavaPlugin instance.
*/
Expand Down
77 changes: 77 additions & 0 deletions api/src/main/java/net/jitse/npclib/NPCLibOptions.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package net.jitse.npclib;

/**
* Mutable preferences for library usage
*
* @author A248
*
*/
public class NPCLibOptions {

MovementHandling moveHandling;

/**
* Creates the default options
*
*/
public NPCLibOptions() {
moveHandling = MovementHandling.playerMoveEvent();
}

/**
* Specifies the motion handling which will be used for the library. <br>
* Programmers may choose between using the PlayerMoveEvent or
* a periodic task. <br>
* <br>
* Note that NPCLib will always use events such as the PlayerTeleportEvent
* and PlayerChangedWorldEvent in addition to the specified option.
*
* @param moveHandling the movement handling
* @return the same NPCLibOptions
*/
public NPCLibOptions setMovementHandling(MovementHandling moveHandling) {
this.moveHandling = moveHandling;
return this;
}

/**
* Options relating to movement handling
*
* @author A248
*
*/
public static class MovementHandling {

final boolean usePme;
final long updateInterval;

private MovementHandling(boolean usePme, long updateInterval) {
this.usePme = usePme;
this.updateInterval = updateInterval;
}

/**
* Gets movement handling using the PlayerMoveEvent
*
* @return movement handling
*/
public static MovementHandling playerMoveEvent() {
return new MovementHandling(false, 0);
}

/**
* Gets movement handling using a periodic update interval in ticks.
*
* @param updateInterval the update interval in ticks
* @return movement handling
*/
public static MovementHandling repeatingTask(long updateInterval) {
if (updateInterval <= 0) {
throw new IllegalArgumentException("Negative update interval");
}
return new MovementHandling(true, updateInterval);
}

}

}
26 changes: 26 additions & 0 deletions api/src/main/java/net/jitse/npclib/listeners/HandleMoveBase.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package net.jitse.npclib.listeners;

import org.bukkit.entity.Player;

import net.jitse.npclib.internal.NPCBase;
import net.jitse.npclib.internal.NPCManager;

public class HandleMoveBase {

void handleMove(Player player) {
for (NPCBase npc : NPCManager.getAllNPCs()) {
if (!npc.getShown().contains(player.getUniqueId())) {
continue; // NPC was never supposed to be shown to the player.
}

if (!npc.isShown(player) && npc.inRangeOf(player) && npc.inViewOf(player)) {
// The player is in range and can see the NPC, auto-show it.
npc.show(player, true);
} else if (npc.isShown(player) && !npc.inRangeOf(player)) {
// The player is not in range of the NPC anymore, auto-hide it.
npc.hide(player, true);
}
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package net.jitse.npclib.listeners;

import java.util.HashMap;
import java.util.UUID;

import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.scheduler.BukkitTask;

import net.jitse.npclib.NPCLib;

public class PeriodicMoveListener extends HandleMoveBase implements Listener {

private final NPCLib instance;
private final long updateInterval;

private final HashMap<UUID, BukkitTask> tasks = new HashMap<>();

public PeriodicMoveListener(NPCLib instance, long updateInterval) {
this.instance = instance;
this.updateInterval = updateInterval;
}

private void startTask(UUID uuid) {
// purposefully using UUIDs and not holding player references
tasks.put(uuid, Bukkit.getScheduler().runTaskTimer(instance.getPlugin(), () -> {
Player player = Bukkit.getPlayer(uuid);
if (player != null) { // safety check
handleMove(player);
}
}, 1L, updateInterval));
}

@EventHandler
public void onPlayerJoin(PlayerJoinEvent evt) {
startTask(evt.getPlayer().getUniqueId());
}

@EventHandler
public void onPlayerQuit(PlayerQuitEvent evt) {
tasks.remove(evt.getPlayer().getUniqueId()).cancel();
}

}
46 changes: 4 additions & 42 deletions api/src/main/java/net/jitse/npclib/listeners/PlayerListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.*;
Expand All @@ -20,7 +19,7 @@
/**
* @author Jitse Boonstra
*/
public class PlayerListener implements Listener {
public class PlayerListener extends HandleMoveBase implements Listener {

private final NPCLib instance;

Expand All @@ -30,17 +29,8 @@ public PlayerListener(NPCLib instance) {

@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
onPlayerLeave(event.getPlayer());
}

@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
public void onPlayerKick(PlayerKickEvent event) {
onPlayerLeave(event.getPlayer());
}

private void onPlayerLeave(Player player) {
for (NPCBase npc : NPCManager.getAllNPCs())
npc.onLogout(player);
for (NPCBase npc : NPCManager.getAllNPCs())
npc.onLogout(event.getPlayer());
}

@EventHandler
Expand Down Expand Up @@ -74,7 +64,7 @@ public void run() {
this.cancel();
}
}
}.runTaskTimerAsynchronously(instance.getPlugin(), 0, 1);
}.runTaskTimer(instance.getPlugin(), 0L, 1L);
}
}

Expand All @@ -91,36 +81,8 @@ public void onPlayerChangedWorld(PlayerChangedWorldEvent event) {
}
}

@EventHandler
public void onPlayerMove(PlayerMoveEvent event) {
Location from = event.getFrom();
Location to = event.getTo();
// Only check movement when the player moves from one block to another. The event is called often
// as it is also called when the pitch or yaw change. This is worth it from a performance view.
if (to == null || from.getBlockX() != to.getBlockX()
|| from.getBlockY() != to.getBlockY()
|| from.getBlockZ() != to.getBlockZ())
handleMove(event.getPlayer());
}

@EventHandler
public void onPlayerTeleport(PlayerTeleportEvent event) {
handleMove(event.getPlayer());
}

private void handleMove(Player player) {
for (NPCBase npc : NPCManager.getAllNPCs()) {
if (!npc.getShown().contains(player.getUniqueId())) {
continue; // NPC was never supposed to be shown to the player.
}

if (!npc.isShown(player) && npc.inRangeOf(player) && npc.inViewOf(player)) {
// The player is in range and can see the NPC, auto-show it.
npc.show(player, true);
} else if (npc.isShown(player) && !npc.inRangeOf(player)) {
// The player is not in range of the NPC anymore, auto-hide it.
npc.hide(player, true);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package net.jitse.npclib.listeners;

import org.bukkit.Location;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent;

public class PlayerMoveEventListener extends HandleMoveBase implements Listener {

@EventHandler
public void onPlayerMove(PlayerMoveEvent event) {
Location from = event.getFrom();
Location to = event.getTo();
// Only check movement when the player moves from one block to another. The event is called often
// as it is also called when the pitch or yaw change. This is worth it from a performance view.
if (to == null || from.getBlockX() != to.getBlockX()
|| from.getBlockY() != to.getBlockY()
|| from.getBlockZ() != to.getBlockZ())
handleMove(event.getPlayer());
}

}

0 comments on commit 3a99792

Please sign in to comment.