Search in sources :

Example 1 with ChunkLoadingTicket

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);
}
Also used : Vector3d(com.flowpowered.math.vector.Vector3d) ChunkLoadingTicket(org.lanternpowered.server.world.chunk.ChunkLoadingTicket) ArrayList(java.util.ArrayList) IntArrayList(it.unimi.dsi.fastutil.ints.IntArrayList) LanternWorld(org.lanternpowered.server.world.LanternWorld) Vector2i(com.flowpowered.math.vector.Vector2i) HashSet(java.util.HashSet)

Aggregations

Vector2i (com.flowpowered.math.vector.Vector2i)1 Vector3d (com.flowpowered.math.vector.Vector3d)1 IntArrayList (it.unimi.dsi.fastutil.ints.IntArrayList)1 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 LanternWorld (org.lanternpowered.server.world.LanternWorld)1 ChunkLoadingTicket (org.lanternpowered.server.world.chunk.ChunkLoadingTicket)1