use of cn.nukkit.level.format.ChunkSection in project Nukkit by Nukkit.
the class Level method tickChunks.
private void tickChunks() {
if (this.chunksPerTicks <= 0 || this.loaders.isEmpty()) {
this.chunkTickList.clear();
return;
}
int chunksPerLoader = Math.min(200, Math.max(1, (int) (((double) (this.chunksPerTicks - this.loaders.size()) / this.loaders.size() + 0.5))));
int randRange = 3 + chunksPerLoader / 30;
randRange = randRange > this.chunkTickRadius ? this.chunkTickRadius : randRange;
ThreadLocalRandom random = ThreadLocalRandom.current();
if (!this.loaders.isEmpty()) {
for (ChunkLoader loader : this.loaders.values()) {
int chunkX = (int) loader.getX() >> 4;
int chunkZ = (int) loader.getZ() >> 4;
long index = Level.chunkHash(chunkX, chunkZ);
int existingLoaders = Math.max(0, this.chunkTickList.getOrDefault(index, 0));
this.chunkTickList.put(index, (Integer) (existingLoaders + 1));
for (int chunk = 0; chunk < chunksPerLoader; ++chunk) {
int dx = random.nextInt(2 * randRange) - randRange;
int dz = random.nextInt(2 * randRange) - randRange;
long hash = Level.chunkHash(dx + chunkX, dz + chunkZ);
if (!this.chunkTickList.containsKey(hash) && provider.isChunkLoaded(hash)) {
this.chunkTickList.put(hash, (Integer) (-1));
}
}
}
}
int blockTest = 0;
if (!chunkTickList.isEmpty()) {
ObjectIterator<Long2ObjectMap.Entry<Integer>> iter = chunkTickList.long2ObjectEntrySet().fastIterator();
while (iter.hasNext()) {
Long2ObjectMap.Entry<Integer> entry = iter.next();
long index = entry.getLongKey();
if (!areNeighboringChunksLoaded(index)) {
iter.remove();
continue;
}
int loaders = entry.getValue();
int chunkX = getHashX(index);
int chunkZ = getHashZ(index);
FullChunk chunk;
if ((chunk = this.getChunk(chunkX, chunkZ, false)) == null) {
iter.remove();
continue;
} else if (loaders <= 0) {
iter.remove();
}
for (Entity entity : chunk.getEntities().values()) {
entity.scheduleUpdate();
}
int tickSpeed = 3;
if (tickSpeed > 0) {
if (this.useSections) {
for (ChunkSection section : ((Chunk) chunk).getSections()) {
if (!(section instanceof EmptyChunkSection)) {
int Y = section.getY();
this.updateLCG = this.updateLCG * 3 + 1013904223;
int k = this.updateLCG >> 2;
for (int i = 0; i < tickSpeed; ++i, k >>= 10) {
int x = k & 0x0f;
int y = k >> 8 & 0x0f;
int z = k >> 16 & 0x0f;
int fullId = section.getFullBlock(x, y, z);
int blockId = fullId >> 4;
if (randomTickBlocks[blockId]) {
Block block = Block.get(fullId, this, chunkX * 16 + x, (Y << 4) + y, chunkZ * 16 + z);
block.onUpdate(BLOCK_UPDATE_RANDOM);
}
}
}
}
} else {
for (int Y = 0; Y < 8 && (Y < 3 || blockTest != 0); ++Y) {
blockTest = 0;
this.updateLCG = this.updateLCG * 3 + 1013904223;
int k = this.updateLCG >> 2;
for (int i = 0; i < tickSpeed; ++i, k >>= 10) {
int x = k & 0x0f;
int y = k >> 8 & 0x0f;
int z = k >> 16 & 0x0f;
int fullId = chunk.getFullBlock(x, y + (Y << 4), z);
int blockId = fullId >> 4;
blockTest |= fullId;
if (this.randomTickBlocks[blockId]) {
Block block = Block.get(fullId, this, x, y + (Y << 4), z);
block.onUpdate(BLOCK_UPDATE_RANDOM);
}
}
}
}
}
}
}
if (this.clearChunksOnTick) {
this.chunkTickList.clear();
}
}
Aggregations