Avoid unintentionally loading loads of chunks with Location#getChunk
This commit is contained in:
@@ -9,12 +9,14 @@ import net.jitse.npclib.internal.NPCManager;
|
|||||||
import net.jitse.npclib.internal.SimpleNPC;
|
import net.jitse.npclib.internal.SimpleNPC;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
|
import org.bukkit.Location;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.world.ChunkLoadEvent;
|
import org.bukkit.event.world.ChunkLoadEvent;
|
||||||
import org.bukkit.event.world.ChunkUnloadEvent;
|
import org.bukkit.event.world.ChunkUnloadEvent;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -33,11 +35,10 @@ public class ChunkListener implements Listener {
|
|||||||
Chunk chunk = event.getChunk();
|
Chunk chunk = event.getChunk();
|
||||||
|
|
||||||
for (SimpleNPC npc : NPCManager.getAllNPCs()) {
|
for (SimpleNPC npc : NPCManager.getAllNPCs()) {
|
||||||
Chunk npcChunk = npc.getLocation().getChunk();
|
if (!isSameChunk(npc.getLocation(), chunk))
|
||||||
|
continue; // We aren't unloading the chunk with the NPC in it.
|
||||||
if (chunk.equals(npcChunk)) {
|
|
||||||
// Unloaded chunk with NPC in it. Hiding it from all players currently shown to.
|
|
||||||
|
|
||||||
|
// We found an NPC in the chunk being unloaded. Time to hide this NPC from all players.
|
||||||
for (UUID uuid : npc.getShown()) {
|
for (UUID uuid : npc.getShown()) {
|
||||||
// Safety check so it doesn't send packets if the NPC has already
|
// Safety check so it doesn't send packets if the NPC has already
|
||||||
// been automatically despawned by the system.
|
// been automatically despawned by the system.
|
||||||
@@ -49,18 +50,16 @@ public class ChunkListener implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onChunkLoad(ChunkLoadEvent event) {
|
public void onChunkLoad(ChunkLoadEvent event) {
|
||||||
Chunk chunk = event.getChunk();
|
Chunk chunk = event.getChunk();
|
||||||
|
|
||||||
for (SimpleNPC npc : NPCManager.getAllNPCs()) {
|
for (SimpleNPC npc : NPCManager.getAllNPCs()) {
|
||||||
Chunk npcChunk = npc.getLocation().getChunk();
|
if (!isSameChunk(npc.getLocation(), chunk))
|
||||||
|
continue; // The NPC is not in the loaded chunk.
|
||||||
if (chunk.equals(npcChunk)) {
|
|
||||||
// Loaded chunk with NPC in it. Showing it to the players again.
|
|
||||||
|
|
||||||
|
// The chunk being loaded has this NPC in it. Showing it to all the players again.
|
||||||
for (UUID uuid : npc.getShown()) {
|
for (UUID uuid : npc.getShown()) {
|
||||||
// Make sure not to respawn a not-hidden NPC.
|
// Make sure not to respawn a not-hidden NPC.
|
||||||
if (!npc.getAutoHidden().contains(uuid)) {
|
if (!npc.getAutoHidden().contains(uuid)) {
|
||||||
@@ -68,8 +67,10 @@ public class ChunkListener implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Player player = Bukkit.getPlayer(uuid);
|
Player player = Bukkit.getPlayer(uuid);
|
||||||
|
if (player == null)
|
||||||
|
continue; // Couldn't find the player, so skip.
|
||||||
|
|
||||||
if (!npcChunk.getWorld().equals(player.getWorld())) {
|
if (!Objects.equals(npc.getWorld(), player.getWorld())) {
|
||||||
continue; // Player and NPC are not in the same world.
|
continue; // Player and NPC are not in the same world.
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,5 +85,16 @@ public class ChunkListener implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static int getChunkCoordinate(int coordinate) {
|
||||||
|
return coordinate >> 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Using Location#getChunk will load the chunk, which is a pretty hefty task, so we'll want to avoid it.
|
||||||
|
// Using Location#getChunk would effectively mean we'd load every chunk an NPC is located in when any chunk is unloaded.
|
||||||
|
private static boolean isSameChunk(Location loc, Chunk chunk) {
|
||||||
|
return getChunkCoordinate(loc.getBlockX()) == chunk.getX()
|
||||||
|
&& getChunkCoordinate(loc.getBlockZ()) == chunk.getZ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user