mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-06 17:59:48 +00:00
Merge pull request #1801 from PocketMine/McRegion
Added multiple level formats support, implemented McRegion
This commit is contained in:
@ -37,9 +37,9 @@ use pocketmine\event\LevelTimings;
|
||||
use pocketmine\event\player\PlayerInteractEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\format\Chunk;
|
||||
use pocketmine\level\format\FullChunk;
|
||||
use pocketmine\level\format\generic\EmptyChunkSection;
|
||||
use pocketmine\level\format\LevelProvider;
|
||||
use pocketmine\level\format\SimpleChunk;
|
||||
use pocketmine\level\generator\Generator;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector2;
|
||||
@ -136,6 +136,9 @@ class Level implements ChunkManager, Metadatable{
|
||||
/** @var BlockMetadataStore */
|
||||
private $blockMetadata;
|
||||
|
||||
private $useSections;
|
||||
private $blockOrder;
|
||||
|
||||
protected $chunkTickRadius;
|
||||
protected $chunkTickList = [];
|
||||
protected $chunksPerTick;
|
||||
@ -199,6 +202,9 @@ class Level implements ChunkManager, Metadatable{
|
||||
$this->levelId = static::$levelIdCounter++;
|
||||
$this->blockMetadata = new BlockMetadataStore($this);
|
||||
$this->server = $server;
|
||||
|
||||
/** @var LevelProvider $provider */
|
||||
|
||||
if(is_subclass_of($provider, "pocketmine\\level\\format\\LevelProvider", true)){
|
||||
$this->provider = new $provider($this, $path);
|
||||
}else{
|
||||
@ -208,6 +214,9 @@ class Level implements ChunkManager, Metadatable{
|
||||
$generator = Generator::getGenerator($this->provider->getGenerator());
|
||||
$this->server->getGenerationManager()->openLevel($this, $generator, $this->provider->getGeneratorOptions());
|
||||
|
||||
$this->blockOrder = $provider::getProviderOrder();
|
||||
$this->useSections = $provider::usesChunkSection();
|
||||
|
||||
$this->folderName = $name;
|
||||
$this->updateQueue = new ReversePriorityQueue();
|
||||
$this->updateQueue->setExtractFlags(\SplPriorityQueue::EXTR_BOTH);
|
||||
@ -220,6 +229,7 @@ class Level implements ChunkManager, Metadatable{
|
||||
$this->chunkTickList = [];
|
||||
$this->clearChunksOnTick = (bool) $this->server->getProperty("chunk-ticking.clear-tick-list", false);
|
||||
$this->timings = new LevelTimings($this);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -509,9 +519,27 @@ class Level implements ChunkManager, Metadatable{
|
||||
$chunk = $this->getChunkAt($chunkX, $chunkZ, true);
|
||||
|
||||
|
||||
foreach($chunk->getSections() as $section){
|
||||
if(!($section instanceof EmptyChunkSection)){
|
||||
$Y = $section->getY();
|
||||
if($this->useSections){
|
||||
foreach($chunk->getSections() as $section){
|
||||
if(!($section instanceof EmptyChunkSection)){
|
||||
$Y = $section->getY();
|
||||
$k = mt_rand(0, PHP_INT_MAX);
|
||||
for($i = 0; $i < 3; ++$i){
|
||||
$j = $k >> 2;
|
||||
$x = $j & 0x0f;
|
||||
$y = ($j >> 8) & 0x0f;
|
||||
$z = ($j >> 16) & 0x0f;
|
||||
$k %= 1073741827;
|
||||
$blockId = $section->getBlockId($x, $y, $z);
|
||||
if(isset($this->randomTickBlocks[$blockId])){
|
||||
$block = Block::get($blockId, $section->getBlockData($x, $y, $z), new Position($chunkX * 16 + $x, ($Y << 4) + $y, $chunkZ * 16 + $z, $this));
|
||||
$block->onUpdate(self::BLOCK_UPDATE_RANDOM);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
for($Y = 0; $Y < 8; ++$Y){
|
||||
$k = mt_rand(0, PHP_INT_MAX);
|
||||
for($i = 0; $i < 3; ++$i){
|
||||
$j = $k >> 2;
|
||||
@ -519,9 +547,9 @@ class Level implements ChunkManager, Metadatable{
|
||||
$y = ($j >> 8) & 0x0f;
|
||||
$z = ($j >> 16) & 0x0f;
|
||||
$k %= 1073741827;
|
||||
$blockId = $section->getBlockId($x, $y, $z);
|
||||
$blockId = $chunk->getBlockId($x, $y + ($Y << 4), $z);
|
||||
if(isset($this->randomTickBlocks[$blockId])){
|
||||
$block = Block::get($blockId, $section->getBlockData($x, $y, $z), new Position($chunkX * 16 + $x, $Y * 16 + $y, $chunkZ * 16 + $z, $this));
|
||||
$block = Block::get($blockId, $chunk->getBlockData($x, $y + ($Y << 4), $z), new Position($chunkX * 16 + $x, ($Y << 4) + $y, $chunkZ * 16 + $z, $this));
|
||||
$block->onUpdate(self::BLOCK_UPDATE_RANDOM);
|
||||
}
|
||||
}
|
||||
@ -1263,45 +1291,17 @@ class Level implements ChunkManager, Metadatable{
|
||||
return isset($this->chunks[$index = "$x:$z"]) ? $this->chunks[$index] : $this->chunks[$index] = $this->provider->getChunk($x, $z, $create);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $x
|
||||
* @param int $z
|
||||
* @param bool $create
|
||||
*
|
||||
* @return SimpleChunk
|
||||
*/
|
||||
public function getChunk($x, $z, $create = false){
|
||||
$chunk = $this->getChunkAt($x, $z, $create);
|
||||
if($chunk === null){
|
||||
return new SimpleChunk($x, $z, 0);
|
||||
}else{
|
||||
$flags = SimpleChunk::FLAG_GENERATED;
|
||||
if($this->isChunkPopulated($x, $z)){
|
||||
$flags |= SimpleChunk::FLAG_POPULATED;
|
||||
}
|
||||
$blockIds = [];
|
||||
$data = [];
|
||||
for($Y = 0; $Y < 8; ++$Y){
|
||||
$section = $chunk->getSection($Y);
|
||||
$blockIds[$Y] = $section->getIdArray();
|
||||
$data[$Y] = $section->getDataArray();
|
||||
}
|
||||
|
||||
return new SimpleChunk($x, $z, $flags, $blockIds, $data);
|
||||
}
|
||||
}
|
||||
|
||||
public function generateChunkCallback($x, $z, SimpleChunk $chunk){
|
||||
public function generateChunkCallback($x, $z, FullChunk $chunk){
|
||||
unset($this->chunkGenerationQueue["$x:$z"]);
|
||||
$this->setChunk($x, $z, $chunk);
|
||||
}
|
||||
|
||||
public function setChunk($x, $z, SimpleChunk $chunk){
|
||||
public function setChunk($x, $z, FullChunk $chunk){
|
||||
$index = Level::chunkHash($x, $z);
|
||||
foreach($this->getUsingChunk($x, $z) as $player){
|
||||
$player->unloadChunk($x, $z);
|
||||
}
|
||||
unset($this->chunks[Level::chunkHash($x, $z)]);
|
||||
unset($this->chunks[$index]);
|
||||
$this->provider->setChunk($x, $z, $chunk);
|
||||
$this->loadChunk($x, $z);
|
||||
}
|
||||
@ -1372,7 +1372,7 @@ class Level implements ChunkManager, Metadatable{
|
||||
$this->server->getPluginManager()->callEvent(new SpawnChangeEvent($this, $previousSpawn));
|
||||
}
|
||||
|
||||
public function requestChunk($x, $z, Player $player){
|
||||
public function requestChunk($x, $z, Player $player, $order = LevelProvider::ORDER_ZXY){
|
||||
$index = Level::chunkHash($x, $z);
|
||||
if(!isset($this->chunkSendQueue[$index])){
|
||||
$this->chunkSendQueue[$index] = [];
|
||||
@ -1399,7 +1399,7 @@ class Level implements ChunkManager, Metadatable{
|
||||
}
|
||||
unset($this->chunkSendQueue[$index]);
|
||||
}else{
|
||||
$task = new ChunkRequestTask($this, $x, $z);
|
||||
$task = $this->provider->requestChunkTask($x, $z);
|
||||
$this->server->getScheduler()->scheduleAsyncTask($task);
|
||||
$this->chunkSendTasks[$index] = true;
|
||||
}
|
||||
@ -1512,13 +1512,13 @@ class Level implements ChunkManager, Metadatable{
|
||||
*/
|
||||
public function loadChunk($x, $z, $generate = true){
|
||||
if($generate === true){
|
||||
return $this->getChunkAt($x, $z, true) instanceof Chunk;
|
||||
return $this->getChunkAt($x, $z, true) instanceof FullChunk;
|
||||
}
|
||||
|
||||
$this->cancelUnloadChunkRequest($x, $z);
|
||||
|
||||
$chunk = $this->provider->getChunk($x, $z, false);
|
||||
if($chunk instanceof Chunk){
|
||||
if($chunk instanceof FullChunk){
|
||||
$this->chunks[Level::chunkHash($x, $z)] = $chunk;
|
||||
return true;
|
||||
}else{
|
||||
@ -1526,7 +1526,7 @@ class Level implements ChunkManager, Metadatable{
|
||||
$this->provider->loadChunk($x, $z);
|
||||
$this->timings->syncChunkLoadTimer->stopTiming();
|
||||
|
||||
if(($chunk = $this->provider->getChunk($x, $z)) instanceof Chunk){
|
||||
if(($chunk = $this->provider->getChunk($x, $z)) instanceof FullChunk){
|
||||
$this->chunks[Level::chunkHash($x, $z)] = $chunk;
|
||||
return true;
|
||||
}
|
||||
@ -1635,9 +1635,10 @@ class Level implements ChunkManager, Metadatable{
|
||||
* Sets the spawnpoint
|
||||
*
|
||||
* @param Vector3 $pos
|
||||
* @deprecated
|
||||
*/
|
||||
public function setSpawn(Vector3 $pos){
|
||||
$this->provider->setSpawn($pos);
|
||||
$this->setSpawnLocation($pos);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user