New chunk ordering algorithm

This commit is contained in:
Shoghi Cervantes 2015-05-29 00:35:40 +02:00
parent 8d4decc548
commit f133154919
No known key found for this signature in database
GPG Key ID: 78464DB0A7837F89

View File

@ -761,59 +761,63 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$this->nextChunkOrderRun = 200; $this->nextChunkOrderRun = 200;
$viewDistance = $this->server->getMemoryManager()->getViewDistance($this->viewDistance); $viewDistance = $this->server->getMemoryManager()->getViewDistance($this->viewDistance);
$radius = ceil(sqrt($viewDistance));
$side = ceil($radius / 2);
$newOrder = []; $newOrder = [];
$lastChunk = $this->usedChunks; $lastChunk = $this->usedChunks;
$currentQueue = [];
$centerX = $this->x >> 4; $centerX = $this->x >> 4;
$centerZ = $this->z >> 4; $centerZ = $this->z >> 4;
for($X = -$side; $X <= $side; ++$X){
for($Z = -$side; $Z <= $side; ++$Z){ $layer = 1;
$chunkX = $X + $centerX; $leg = 0;
$chunkZ = $Z + $centerZ; $x = 0;
$z = 0;
for($i = 0; $i < $viewDistance; ++$i){
$chunkX = $x + $centerX;
$chunkZ = $z + $centerZ;
if(!isset($this->usedChunks[$index = Level::chunkHash($chunkX, $chunkZ)]) or $this->usedChunks[$index] === false){ if(!isset($this->usedChunks[$index = Level::chunkHash($chunkX, $chunkZ)]) or $this->usedChunks[$index] === false){
$newOrder[$index] = abs($X) + abs($Z); $newOrder[$index] = true;
}else{
$currentQueue[$index] = abs($X) + abs($Z);
}
}
}
asort($newOrder);
asort($currentQueue);
$limit = $viewDistance;
foreach($currentQueue as $index => $distance){
if($limit-- <= 0){
break;
} }
unset($lastChunk[$index]); unset($lastChunk[$index]);
switch($leg){
case 0:
++$x;
if($x === $layer){
++$leg;
}
break;
case 1:
++$z;
if($z === $layer){
++$leg;
}
break;
case 2:
--$x;
if(-$x === $layer){
++$leg;
}
break;
case 3:
--$z;
if(-$z === $layer){
$leg = 0;
++$layer;
}
break;
}
} }
foreach($lastChunk as $index => $Yndex){ foreach($lastChunk as $index => $bool){
$X = null;
$Z = null;
Level::getXZ($index, $X, $Z); Level::getXZ($index, $X, $Z);
$this->unloadChunk($X, $Z); $this->unloadChunk($X, $Z);
} }
$loadedChunks = count($this->usedChunks);
if((count($newOrder) + $loadedChunks) > $viewDistance){
$count = $loadedChunks;
$this->loadQueue = [];
foreach($newOrder as $k => $distance){
if(++$count > $viewDistance){
break;
}
$this->loadQueue[$k] = $distance;
}
}else{
$this->loadQueue = $newOrder; $this->loadQueue = $newOrder;
}
return true; return true;
} }