private function tickChunks()
{
if ($this->chunksPerTick <= 0 or count($this->loaders) === 0) {
$this->chunkTickList = [];
return;
}
$chunksPerLoader = min(200, max(1, (int) (($this->chunksPerTick - count($this->loaders)) / count($this->loaders) + 0.5)));
$randRange = 3 + $chunksPerLoader / 30;
$randRange = (int) ($randRange > $this->chunkTickRadius ? $this->chunkTickRadius : $randRange);
foreach ($this->loaders as $loader) {
$chunkX = $loader->getX() >> 4;
$chunkZ = $loader->getZ() >> 4;
$index = Level::chunkHash($chunkX, $chunkZ);
$existingLoaders = max(0, isset($this->chunkTickList[$index]) ? $this->chunkTickList[$index] : 0);
$this->chunkTickList[$index] = $existingLoaders + 1;
for ($chunk = 0; $chunk < $chunksPerLoader; ++$chunk) {
$dx = mt_rand(-$randRange, $randRange);
$dz = mt_rand(-$randRange, $randRange);
$hash = Level::chunkHash($dx + $chunkX, $dz + $chunkZ);
if (!isset($this->chunkTickList[$hash]) and isset($this->chunks[$hash])) {
$this->chunkTickList[$hash] = -1;
}
}
}
$blockTest = 0;
foreach ($this->chunkTickList as $index => $loaders) {
Level::getXZ($index, $chunkX, $chunkZ);
if (!isset($this->chunks[$index]) or ($chunk = $this->getChunk($chunkX, $chunkZ, false)) === null) {
unset($this->chunkTickList[$index]);
continue;
} elseif ($loaders <= 0) {
unset($this->chunkTickList[$index]);
}
foreach ($chunk->getEntities() as $entity) {
$entity->scheduleUpdate();
}
if ($this->useSections) {
foreach ($chunk->getSections() as $section) {
if (!$section instanceof EmptyChunkSection) {
$Y = $section->getY();
$k = mt_rand(0, 0x7fffffff);
for ($i = 0; $i < 3; ++$i, $k >>= 10) {
$x = $k & 0xf;
$y = $k >> 8 & 0xf;
$z = $k >> 16 & 0xf;
$blockId = $section->getBlockId($x, $y, $z);
if (isset($this->randomTickBlocks[$blockId])) {
$class = $this->randomTickBlocks[$blockId];
/** @var Block $block */
$block = new $class($section->getBlockData($x, $y, $z));
$block->x = $chunkX * 16 + $x;
$block->y = ($Y << 4) + $y;
$block->z = $chunkZ * 16 + $z;
$block->level = $this;
$block->onUpdate(self::BLOCK_UPDATE_RANDOM);
}
}
}
}
} else {
for ($Y = 0; $Y < 8 and ($Y < 3 or $blockTest !== 0); ++$Y) {
$blockTest = 0;
$k = mt_rand(0, 0x7fffffff);
for ($i = 0; $i < 3; ++$i, $k >>= 10) {
$x = $k & 0xf;
$y = $k >> 8 & 0xf;
$z = $k >> 16 & 0xf;
$blockTest |= $blockId = $chunk->getBlockId($x, $y + ($Y << 4), $z);
if (isset($this->randomTickBlocks[$blockId])) {
$class = $this->randomTickBlocks[$blockId];
/** @var Block $block */
$block = new $class($chunk->getBlockData($x, $y + ($Y << 4), $z));
$block->x = $chunkX * 16 + $x;
$block->y = ($Y << 4) + $y;
$block->z = $chunkZ * 16 + $z;
$block->level = $this;
$block->onUpdate(self::BLOCK_UPDATE_RANDOM);
}
}
}
}
}
if ($this->clearChunksOnTick) {
$this->chunkTickList = [];
}
}