use of org.lanternpowered.server.world.chunk.ChunkLoadingTicket in project LanternServer by LanternPowered.
the class LanternPlayer method pulseChunkChanges.
public void pulseChunkChanges() {
final LanternWorld world = getWorld();
if (world == null) {
return;
}
ChunkLoadingTicket loadingTicket = this.getChunkLoadingTicket();
Vector3d position = this.getPosition();
double xPos = position.getX();
double zPos = position.getZ();
int centralX = ((int) xPos) >> 4;
int centralZ = ((int) zPos) >> 4;
// Fail fast if the player hasn't moved a chunk
if (this.lastChunkPos != null && this.lastChunkPos.getX() == centralX && this.lastChunkPos.getY() == centralZ) {
return;
}
this.lastChunkPos = new Vector2i(centralX, centralZ);
// Get the radius of visible chunks
int radius = world.getProperties().getConfig().getViewDistance();
if (radius == WorldConfig.USE_SERVER_VIEW_DISTANCE) {
radius = Lantern.getGame().getGlobalConfig().getViewDistance();
}
if (this.viewDistance != -1) {
radius = Math.min(radius, this.viewDistance + 1);
}
final Set<Vector2i> previousChunks = new HashSet<>(this.knownChunks);
final List<Vector2i> newChunks = new ArrayList<>();
for (int x = (centralX - radius); x <= (centralX + radius); x++) {
for (int z = (centralZ - radius); z <= (centralZ + radius); z++) {
final Vector2i coords = new Vector2i(x, z);
if (!previousChunks.remove(coords)) {
newChunks.add(coords);
}
}
}
// Early end if there's no changes
if (newChunks.size() == 0 && previousChunks.size() == 0) {
return;
}
// Sort chunks by distance from player - closer chunks sent/forced first
newChunks.sort((a, b) -> {
double dx = 16 * a.getX() + 8 - xPos;
double dz = 16 * a.getY() + 8 - zPos;
double da = dx * dx + dz * dz;
dx = 16 * b.getX() + 8 - xPos;
dz = 16 * b.getY() + 8 - zPos;
double db = dx * dx + dz * dz;
return Double.compare(da, db);
});
ObservedChunkManager observedChunkManager = world.getObservedChunkManager();
// Force all the new chunks to be loaded and track the changes
newChunks.forEach(coords -> {
observedChunkManager.addObserver(coords, this);
loadingTicket.forceChunk(coords);
});
// Unforce old chunks so they can unload and untrack the chunk
previousChunks.forEach(coords -> {
observedChunkManager.removeObserver(coords, this, true);
loadingTicket.unforceChunk(coords);
});
this.knownChunks.removeAll(previousChunks);
this.knownChunks.addAll(newChunks);
}
Aggregations