mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-06-08 12:48:32 +00:00
Chunks no longer contain their own coordinates
This commit is contained in:
parent
1f5998d24c
commit
c808095978
@ -32,13 +32,23 @@ use pocketmine\world\World;
|
|||||||
abstract class ChunkEvent extends WorldEvent{
|
abstract class ChunkEvent extends WorldEvent{
|
||||||
/** @var Chunk */
|
/** @var Chunk */
|
||||||
private $chunk;
|
private $chunk;
|
||||||
|
/** @var int */
|
||||||
|
private $chunkX;
|
||||||
|
/** @var int */
|
||||||
|
private $chunkZ;
|
||||||
|
|
||||||
public function __construct(World $world, Chunk $chunk){
|
public function __construct(World $world, int $chunkX, int $chunkZ, Chunk $chunk){
|
||||||
parent::__construct($world);
|
parent::__construct($world);
|
||||||
$this->chunk = $chunk;
|
$this->chunk = $chunk;
|
||||||
|
$this->chunkX = $chunkX;
|
||||||
|
$this->chunkZ = $chunkZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getChunk() : Chunk{
|
public function getChunk() : Chunk{
|
||||||
return $this->chunk;
|
return $this->chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getChunkX() : int{ return $this->chunkX; }
|
||||||
|
|
||||||
|
public function getChunkZ() : int{ return $this->chunkZ; }
|
||||||
}
|
}
|
||||||
|
@ -33,8 +33,8 @@ class ChunkLoadEvent extends ChunkEvent{
|
|||||||
/** @var bool */
|
/** @var bool */
|
||||||
private $newChunk;
|
private $newChunk;
|
||||||
|
|
||||||
public function __construct(World $world, Chunk $chunk, bool $newChunk){
|
public function __construct(World $world, int $chunkX, int $chunkZ, Chunk $chunk, bool $newChunk){
|
||||||
parent::__construct($world, $chunk);
|
parent::__construct($world, $chunkX, $chunkZ, $chunk);
|
||||||
$this->newChunk = $newChunk;
|
$this->newChunk = $newChunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ class ChunkRequestTask extends AsyncTask{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function onRun() : void{
|
public function onRun() : void{
|
||||||
$chunk = FastChunkSerializer::deserialize($this->chunk, $this->chunkX, $this->chunkZ);
|
$chunk = FastChunkSerializer::deserialize($this->chunk);
|
||||||
$subCount = ChunkSerializer::getSubChunkCount($chunk);
|
$subCount = ChunkSerializer::getSubChunkCount($chunk);
|
||||||
$payload = ChunkSerializer::serialize($chunk, RuntimeBlockMapping::getInstance(), $this->tiles);
|
$payload = ChunkSerializer::serialize($chunk, RuntimeBlockMapping::getInstance(), $this->tiles);
|
||||||
$this->setResult($this->compressor->compress(PacketBatch::fromPackets(LevelChunkPacket::withoutCache($this->chunkX, $this->chunkZ, $subCount, $payload))->getBuffer()));
|
$this->setResult($this->compressor->compress(PacketBatch::fromPackets(LevelChunkPacket::withoutCache($this->chunkX, $this->chunkZ, $subCount, $payload))->getBuffer()));
|
||||||
|
10
src/network/mcpe/cache/ChunkCache.php
vendored
10
src/network/mcpe/cache/ChunkCache.php
vendored
@ -183,9 +183,9 @@ class ChunkCache implements ChunkListener{
|
|||||||
/**
|
/**
|
||||||
* @see ChunkListener::onChunkChanged()
|
* @see ChunkListener::onChunkChanged()
|
||||||
*/
|
*/
|
||||||
public function onChunkChanged(Chunk $chunk) : void{
|
public function onChunkChanged(int $chunkX, int $chunkZ, Chunk $chunk) : void{
|
||||||
//FIXME: this gets fired for stuff that doesn't change terrain related things (like lighting updates)
|
//FIXME: this gets fired for stuff that doesn't change terrain related things (like lighting updates)
|
||||||
$this->destroyOrRestart($chunk->getX(), $chunk->getZ());
|
$this->destroyOrRestart($chunkX, $chunkZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -200,9 +200,9 @@ class ChunkCache implements ChunkListener{
|
|||||||
/**
|
/**
|
||||||
* @see ChunkListener::onChunkUnloaded()
|
* @see ChunkListener::onChunkUnloaded()
|
||||||
*/
|
*/
|
||||||
public function onChunkUnloaded(Chunk $chunk) : void{
|
public function onChunkUnloaded(int $chunkX, int $chunkZ, Chunk $chunk) : void{
|
||||||
$this->destroy($chunk->getX(), $chunk->getZ());
|
$this->destroy($chunkX, $chunkZ);
|
||||||
$this->world->unregisterChunkListener($this, $chunk->getX(), $chunk->getZ());
|
$this->world->unregisterChunkListener($this, $chunkX, $chunkZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2358,18 +2358,18 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
|
|||||||
onChunkUnloaded as private;
|
onChunkUnloaded as private;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onChunkChanged(Chunk $chunk) : void{
|
public function onChunkChanged(int $chunkX, int $chunkZ, Chunk $chunk) : void{
|
||||||
$status = $this->usedChunks[$hash = World::chunkHash($chunk->getX(), $chunk->getZ())] ?? null;
|
$status = $this->usedChunks[$hash = World::chunkHash($chunkX, $chunkZ)] ?? null;
|
||||||
if($status !== null && !$status->equals(UsedChunkStatus::NEEDED())){
|
if($status !== null && !$status->equals(UsedChunkStatus::NEEDED())){
|
||||||
$this->usedChunks[$hash] = UsedChunkStatus::NEEDED();
|
$this->usedChunks[$hash] = UsedChunkStatus::NEEDED();
|
||||||
$this->nextChunkOrderRun = 0;
|
$this->nextChunkOrderRun = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onChunkUnloaded(Chunk $chunk) : void{
|
public function onChunkUnloaded(int $chunkX, int $chunkZ, Chunk $chunk) : void{
|
||||||
if($this->isUsingChunk($chunk->getX(), $chunk->getZ())){
|
if($this->isUsingChunk($chunkX, $chunkZ)){
|
||||||
$this->logger->debug("Detected forced unload of chunk " . $chunk->getX() . " " . $chunk->getZ());
|
$this->logger->debug("Detected forced unload of chunk " . $chunkX . " " . $chunkZ);
|
||||||
$this->unloadChunk($chunk->getX(), $chunk->getZ());
|
$this->unloadChunk($chunkX, $chunkZ);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,23 +43,23 @@ interface ChunkListener{
|
|||||||
/**
|
/**
|
||||||
* This method will be called when a Chunk is replaced by a new one
|
* This method will be called when a Chunk is replaced by a new one
|
||||||
*/
|
*/
|
||||||
public function onChunkChanged(Chunk $chunk) : void;
|
public function onChunkChanged(int $chunkX, int $chunkZ, Chunk $chunk) : void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method will be called when a registered chunk is loaded
|
* This method will be called when a registered chunk is loaded
|
||||||
*/
|
*/
|
||||||
public function onChunkLoaded(Chunk $chunk) : void;
|
public function onChunkLoaded(int $chunkX, int $chunkZ, Chunk $chunk) : void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method will be called when a registered chunk is unloaded
|
* This method will be called when a registered chunk is unloaded
|
||||||
*/
|
*/
|
||||||
public function onChunkUnloaded(Chunk $chunk) : void;
|
public function onChunkUnloaded(int $chunkX, int $chunkZ, Chunk $chunk) : void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method will be called when a registered chunk is populated
|
* This method will be called when a registered chunk is populated
|
||||||
* Usually it'll be sent with another call to onChunkChanged()
|
* Usually it'll be sent with another call to onChunkChanged()
|
||||||
*/
|
*/
|
||||||
public function onChunkPopulated(Chunk $chunk) : void;
|
public function onChunkPopulated(int $chunkX, int $chunkZ, Chunk $chunk) : void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method will be called when a block changes in a registered chunk
|
* This method will be called when a block changes in a registered chunk
|
||||||
|
@ -32,19 +32,19 @@ use pocketmine\world\format\Chunk;
|
|||||||
*/
|
*/
|
||||||
trait ChunkListenerNoOpTrait/* implements ChunkListener*/{
|
trait ChunkListenerNoOpTrait/* implements ChunkListener*/{
|
||||||
|
|
||||||
public function onChunkChanged(Chunk $chunk) : void{
|
public function onChunkChanged(int $chunkX, int $chunkZ, Chunk $chunk) : void{
|
||||||
//NOOP
|
//NOOP
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onChunkLoaded(Chunk $chunk) : void{
|
public function onChunkLoaded(int $chunkX, int $chunkZ, Chunk $chunk) : void{
|
||||||
//NOOP
|
//NOOP
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onChunkUnloaded(Chunk $chunk) : void{
|
public function onChunkUnloaded(int $chunkX, int $chunkZ, Chunk $chunk) : void{
|
||||||
//NOOP
|
//NOOP
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onChunkPopulated(Chunk $chunk) : void{
|
public function onChunkPopulated(int $chunkX, int $chunkZ, Chunk $chunk) : void{
|
||||||
//NOOP
|
//NOOP
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -461,8 +461,9 @@ class World implements ChunkManager{
|
|||||||
}
|
}
|
||||||
$this->unloadCallbacks = [];
|
$this->unloadCallbacks = [];
|
||||||
|
|
||||||
foreach($this->chunks as $chunk){
|
foreach($this->chunks as $chunkHash => $chunk){
|
||||||
$this->unloadChunk($chunk->getX(), $chunk->getZ(), false);
|
self::getXZ($chunkHash, $chunkX, $chunkZ);
|
||||||
|
$this->unloadChunk($chunkX, $chunkZ, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->save();
|
$this->save();
|
||||||
@ -796,7 +797,7 @@ class World implements ChunkManager{
|
|||||||
if(count($blocks) > 512){
|
if(count($blocks) > 512){
|
||||||
$chunk = $this->getChunk($chunkX, $chunkZ);
|
$chunk = $this->getChunk($chunkX, $chunkZ);
|
||||||
foreach($this->getChunkPlayers($chunkX, $chunkZ) as $p){
|
foreach($this->getChunkPlayers($chunkX, $chunkZ) as $p){
|
||||||
$p->onChunkChanged($chunk);
|
$p->onChunkChanged($chunkX, $chunkZ, $chunk);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
foreach($this->createBlockUpdatePackets($blocks) as $packet){
|
foreach($this->createBlockUpdatePackets($blocks) as $packet){
|
||||||
@ -946,7 +947,7 @@ class World implements ChunkManager{
|
|||||||
if($lightPopulatedState !== true){
|
if($lightPopulatedState !== true){
|
||||||
if($lightPopulatedState === false){
|
if($lightPopulatedState === false){
|
||||||
$this->chunks[$hash]->setLightPopulated(null);
|
$this->chunks[$hash]->setLightPopulated(null);
|
||||||
$this->workerPool->submitTask(new LightPopulationTask($this, $this->chunks[$hash]));
|
$this->workerPool->submitTask(new LightPopulationTask($this, $dx + $chunkX, $dz + $chunkZ, $this->chunks[$hash]));
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1023,9 +1024,10 @@ class World implements ChunkManager{
|
|||||||
public function saveChunks() : void{
|
public function saveChunks() : void{
|
||||||
$this->timings->syncChunkSaveTimer->startTiming();
|
$this->timings->syncChunkSaveTimer->startTiming();
|
||||||
try{
|
try{
|
||||||
foreach($this->chunks as $chunk){
|
foreach($this->chunks as $chunkHash => $chunk){
|
||||||
if($chunk->isDirty() and $chunk->isGenerated()){
|
if($chunk->isDirty() and $chunk->isGenerated()){
|
||||||
$this->provider->saveChunk($chunk);
|
self::getXZ($chunkHash, $chunkX, $chunkZ);
|
||||||
|
$this->provider->saveChunk($chunkX, $chunkZ, $chunk);
|
||||||
$chunk->clearDirtyFlags();
|
$chunk->clearDirtyFlags();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1979,10 +1981,10 @@ class World implements ChunkManager{
|
|||||||
$oldChunk = $this->loadChunk($x, $z);
|
$oldChunk = $this->loadChunk($x, $z);
|
||||||
$this->setChunk($x, $z, $chunk, false);
|
$this->setChunk($x, $z, $chunk, false);
|
||||||
if(($oldChunk === null or !$oldChunk->isPopulated()) and $chunk->isPopulated()){
|
if(($oldChunk === null or !$oldChunk->isPopulated()) and $chunk->isPopulated()){
|
||||||
(new ChunkPopulateEvent($this, $chunk))->call();
|
(new ChunkPopulateEvent($this, $x, $z, $chunk))->call();
|
||||||
|
|
||||||
foreach($this->getChunkListeners($x, $z) as $listener){
|
foreach($this->getChunkListeners($x, $z) as $listener){
|
||||||
$listener->onChunkPopulated($chunk);
|
$listener->onChunkPopulated($x, $z, $chunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2005,9 +2007,6 @@ class World implements ChunkManager{
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$chunk->setX($chunkX);
|
|
||||||
$chunk->setZ($chunkZ);
|
|
||||||
|
|
||||||
$chunkHash = World::chunkHash($chunkX, $chunkZ);
|
$chunkHash = World::chunkHash($chunkX, $chunkZ);
|
||||||
$oldChunk = $this->loadChunk($chunkX, $chunkZ);
|
$oldChunk = $this->loadChunk($chunkX, $chunkZ);
|
||||||
if($oldChunk !== null and $oldChunk !== $chunk){
|
if($oldChunk !== null and $oldChunk !== $chunk){
|
||||||
@ -2049,14 +2048,14 @@ class World implements ChunkManager{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if($oldChunk === null){
|
if($oldChunk === null){
|
||||||
(new ChunkLoadEvent($this, $chunk, true))->call();
|
(new ChunkLoadEvent($this, $chunkX, $chunkZ, $chunk, true))->call();
|
||||||
|
|
||||||
foreach($this->getChunkListeners($chunkX, $chunkZ) as $listener){
|
foreach($this->getChunkListeners($chunkX, $chunkZ) as $listener){
|
||||||
$listener->onChunkLoaded($chunk);
|
$listener->onChunkLoaded($chunkX, $chunkZ, $chunk);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
foreach($this->getChunkListeners($chunkX, $chunkZ) as $listener){
|
foreach($this->getChunkListeners($chunkX, $chunkZ) as $listener){
|
||||||
$listener->onChunkChanged($chunk);
|
$listener->onChunkChanged($chunkX, $chunkZ, $chunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2233,16 +2232,16 @@ class World implements ChunkManager{
|
|||||||
$this->chunks[$chunkHash] = $chunk;
|
$this->chunks[$chunkHash] = $chunk;
|
||||||
unset($this->blockCache[$chunkHash]);
|
unset($this->blockCache[$chunkHash]);
|
||||||
|
|
||||||
$this->initChunk($chunk);
|
$this->initChunk($x, $z, $chunk);
|
||||||
|
|
||||||
(new ChunkLoadEvent($this, $chunk, false))->call();
|
(new ChunkLoadEvent($this, $x, $z, $chunk, false))->call();
|
||||||
|
|
||||||
if(!$this->isChunkInUse($x, $z)){
|
if(!$this->isChunkInUse($x, $z)){
|
||||||
$this->logger->debug("Newly loaded chunk $x $z has no loaders registered, will be unloaded at next available opportunity");
|
$this->logger->debug("Newly loaded chunk $x $z has no loaders registered, will be unloaded at next available opportunity");
|
||||||
$this->unloadChunkRequest($x, $z);
|
$this->unloadChunkRequest($x, $z);
|
||||||
}
|
}
|
||||||
foreach($this->getChunkListeners($x, $z) as $listener){
|
foreach($this->getChunkListeners($x, $z) as $listener){
|
||||||
$listener->onChunkLoaded($chunk);
|
$listener->onChunkLoaded($x, $z, $chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->timings->syncChunkLoadTimer->stopTiming();
|
$this->timings->syncChunkLoadTimer->stopTiming();
|
||||||
@ -2250,7 +2249,7 @@ class World implements ChunkManager{
|
|||||||
return $chunk;
|
return $chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function initChunk(Chunk $chunk) : void{
|
private function initChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void{
|
||||||
if($chunk->NBTentities !== null){
|
if($chunk->NBTentities !== null){
|
||||||
$this->timings->syncChunkLoadEntitiesTimer->startTiming();
|
$this->timings->syncChunkLoadEntitiesTimer->startTiming();
|
||||||
$entityFactory = EntityFactory::getInstance();
|
$entityFactory = EntityFactory::getInstance();
|
||||||
@ -2265,7 +2264,7 @@ class World implements ChunkManager{
|
|||||||
}elseif($saveIdTag instanceof IntTag){ //legacy MCPE format
|
}elseif($saveIdTag instanceof IntTag){ //legacy MCPE format
|
||||||
$saveId = "legacy(" . $saveIdTag->getValue() . ")";
|
$saveId = "legacy(" . $saveIdTag->getValue() . ")";
|
||||||
}
|
}
|
||||||
$this->getLogger()->warning("Chunk " . $chunk->getX() . " " . $chunk->getZ() . ": Deleted unknown entity type $saveId");
|
$this->getLogger()->warning("Chunk $chunkX $chunkZ: Deleted unknown entity type $saveId");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}catch(\Exception $t){ //TODO: this shouldn't be here
|
}catch(\Exception $t){ //TODO: this shouldn't be here
|
||||||
@ -2285,7 +2284,7 @@ class World implements ChunkManager{
|
|||||||
if(($tile = $tileFactory->createFromData($this, $nbt)) !== null){
|
if(($tile = $tileFactory->createFromData($this, $nbt)) !== null){
|
||||||
$this->addTile($tile);
|
$this->addTile($tile);
|
||||||
}else{
|
}else{
|
||||||
$this->getLogger()->warning("Chunk " . $chunk->getX() . " " . $chunk->getZ() . ": Deleted unknown tile entity type " . $nbt->getString("id", "<unknown>"));
|
$this->getLogger()->warning("Chunk $chunkX $chunkZ: Deleted unknown tile entity type " . $nbt->getString("id", "<unknown>"));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2330,7 +2329,7 @@ class World implements ChunkManager{
|
|||||||
$chunk = $this->chunks[$chunkHash] ?? null;
|
$chunk = $this->chunks[$chunkHash] ?? null;
|
||||||
|
|
||||||
if($chunk !== null){
|
if($chunk !== null){
|
||||||
$ev = new ChunkUnloadEvent($this, $chunk);
|
$ev = new ChunkUnloadEvent($this, $x, $z, $chunk);
|
||||||
$ev->call();
|
$ev->call();
|
||||||
if($ev->isCancelled()){
|
if($ev->isCancelled()){
|
||||||
$this->timings->doChunkUnload->stopTiming();
|
$this->timings->doChunkUnload->stopTiming();
|
||||||
@ -2341,14 +2340,14 @@ class World implements ChunkManager{
|
|||||||
if($trySave and $this->getAutoSave() and $chunk->isGenerated() and $chunk->isDirty()){
|
if($trySave and $this->getAutoSave() and $chunk->isGenerated() and $chunk->isDirty()){
|
||||||
$this->timings->syncChunkSaveTimer->startTiming();
|
$this->timings->syncChunkSaveTimer->startTiming();
|
||||||
try{
|
try{
|
||||||
$this->provider->saveChunk($chunk);
|
$this->provider->saveChunk($x, $z, $chunk);
|
||||||
}finally{
|
}finally{
|
||||||
$this->timings->syncChunkSaveTimer->stopTiming();
|
$this->timings->syncChunkSaveTimer->stopTiming();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($this->getChunkListeners($x, $z) as $listener){
|
foreach($this->getChunkListeners($x, $z) as $listener){
|
||||||
$listener->onChunkUnloaded($chunk);
|
$listener->onChunkUnloaded($x, $z, $chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
$chunk->onUnload();
|
$chunk->onUnload();
|
||||||
@ -2509,7 +2508,7 @@ class World implements ChunkManager{
|
|||||||
|
|
||||||
$chunk = $this->loadChunk($x, $z);
|
$chunk = $this->loadChunk($x, $z);
|
||||||
if($chunk === null){
|
if($chunk === null){
|
||||||
$chunk = new Chunk($x, $z);
|
$chunk = new Chunk();
|
||||||
}
|
}
|
||||||
if(!$chunk->isPopulated()){
|
if(!$chunk->isPopulated()){
|
||||||
Timings::$populationTimer->startTiming();
|
Timings::$populationTimer->startTiming();
|
||||||
@ -2521,7 +2520,7 @@ class World implements ChunkManager{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$task = new PopulationTask($this, $chunk);
|
$task = new PopulationTask($this, $x, $z, $chunk);
|
||||||
$workerId = $this->workerPool->selectWorker();
|
$workerId = $this->workerPool->selectWorker();
|
||||||
if(!isset($this->generatorRegisteredWorkers[$workerId])){
|
if(!isset($this->generatorRegisteredWorkers[$workerId])){
|
||||||
$this->registerGeneratorToWorker($workerId);
|
$this->registerGeneratorToWorker($workerId);
|
||||||
|
@ -45,11 +45,6 @@ class Chunk{
|
|||||||
|
|
||||||
public const MAX_SUBCHUNKS = 16;
|
public const MAX_SUBCHUNKS = 16;
|
||||||
|
|
||||||
/** @var int */
|
|
||||||
protected $x;
|
|
||||||
/** @var int */
|
|
||||||
protected $z;
|
|
||||||
|
|
||||||
/** @var int */
|
/** @var int */
|
||||||
private $dirtyFlags = 0;
|
private $dirtyFlags = 0;
|
||||||
|
|
||||||
@ -89,10 +84,7 @@ class Chunk{
|
|||||||
* @param CompoundTag[] $entities
|
* @param CompoundTag[] $entities
|
||||||
* @param CompoundTag[] $tiles
|
* @param CompoundTag[] $tiles
|
||||||
*/
|
*/
|
||||||
public function __construct(int $chunkX, int $chunkZ, array $subChunks = [], ?array $entities = null, ?array $tiles = null, ?BiomeArray $biomeIds = null, ?HeightArray $heightMap = null){
|
public function __construct(array $subChunks = [], ?array $entities = null, ?array $tiles = null, ?BiomeArray $biomeIds = null, ?HeightArray $heightMap = null){
|
||||||
$this->x = $chunkX;
|
|
||||||
$this->z = $chunkZ;
|
|
||||||
|
|
||||||
$this->subChunks = new \SplFixedArray(Chunk::MAX_SUBCHUNKS);
|
$this->subChunks = new \SplFixedArray(Chunk::MAX_SUBCHUNKS);
|
||||||
|
|
||||||
foreach($this->subChunks as $y => $null){
|
foreach($this->subChunks as $y => $null){
|
||||||
@ -107,22 +99,6 @@ class Chunk{
|
|||||||
$this->NBTentities = $entities;
|
$this->NBTentities = $entities;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getX() : int{
|
|
||||||
return $this->x;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getZ() : int{
|
|
||||||
return $this->z;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setX(int $x) : void{
|
|
||||||
$this->x = $x;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setZ(int $z) : void{
|
|
||||||
$this->z = $z;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the chunk height in count of subchunks.
|
* Returns the chunk height in count of subchunks.
|
||||||
*/
|
*/
|
||||||
|
@ -66,11 +66,11 @@ abstract class BaseWorldProvider implements WorldProvider{
|
|||||||
return $this->readChunk($chunkX, $chunkZ);
|
return $this->readChunk($chunkX, $chunkZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function saveChunk(Chunk $chunk) : void{
|
public function saveChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void{
|
||||||
if(!$chunk->isGenerated()){
|
if(!$chunk->isGenerated()){
|
||||||
throw new \InvalidStateException("Cannot save un-generated chunk");
|
throw new \InvalidStateException("Cannot save un-generated chunk");
|
||||||
}
|
}
|
||||||
$this->writeChunk($chunk);
|
$this->writeChunk($chunkX, $chunkZ, $chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -78,5 +78,5 @@ abstract class BaseWorldProvider implements WorldProvider{
|
|||||||
*/
|
*/
|
||||||
abstract protected function readChunk(int $chunkX, int $chunkZ) : ?Chunk;
|
abstract protected function readChunk(int $chunkX, int $chunkZ) : ?Chunk;
|
||||||
|
|
||||||
abstract protected function writeChunk(Chunk $chunk) : void;
|
abstract protected function writeChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void;
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,7 @@ final class FastChunkSerializer{
|
|||||||
/**
|
/**
|
||||||
* Deserializes a fast-serialized chunk
|
* Deserializes a fast-serialized chunk
|
||||||
*/
|
*/
|
||||||
public static function deserialize(string $data, int $chunkX, int $chunkZ) : Chunk{
|
public static function deserialize(string $data) : Chunk{
|
||||||
$stream = new BinaryStream($data);
|
$stream = new BinaryStream($data);
|
||||||
|
|
||||||
$flags = $stream->getByte();
|
$flags = $stream->getByte();
|
||||||
@ -144,7 +144,7 @@ final class FastChunkSerializer{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$chunk = new Chunk($chunkX, $chunkZ, $subChunks, null, null, $biomeIds, $heightMap);
|
$chunk = new Chunk($subChunks, null, null, $biomeIds, $heightMap);
|
||||||
$chunk->setGenerated($terrainGenerated);
|
$chunk->setGenerated($terrainGenerated);
|
||||||
$chunk->setPopulated($terrainPopulated);
|
$chunk->setPopulated($terrainPopulated);
|
||||||
$chunk->setLightPopulated($lightPopulated);
|
$chunk->setLightPopulated($lightPopulated);
|
||||||
|
@ -138,9 +138,10 @@ class FormatConverter{
|
|||||||
|
|
||||||
$start = microtime(true);
|
$start = microtime(true);
|
||||||
$thisRound = $start;
|
$thisRound = $start;
|
||||||
foreach($this->oldProvider->getAllChunks(true, $this->logger) as $chunk){
|
foreach($this->oldProvider->getAllChunks(true, $this->logger) as $coords => $chunk){
|
||||||
|
[$chunkX, $chunkZ] = $coords;
|
||||||
$chunk->setDirty();
|
$chunk->setDirty();
|
||||||
$new->saveChunk($chunk);
|
$new->saveChunk($chunkX, $chunkZ, $chunk);
|
||||||
$counter++;
|
$counter++;
|
||||||
if(($counter % $this->chunksPerProgressUpdate) === 0){
|
if(($counter % $this->chunksPerProgressUpdate) === 0){
|
||||||
$time = microtime(true);
|
$time = microtime(true);
|
||||||
|
@ -75,6 +75,7 @@ interface WorldProvider{
|
|||||||
* Returns a generator which yields all the chunks in this world.
|
* Returns a generator which yields all the chunks in this world.
|
||||||
*
|
*
|
||||||
* @return \Generator|Chunk[]
|
* @return \Generator|Chunk[]
|
||||||
|
* @phpstan-return \Generator<array{int, int}, Chunk, void, void>
|
||||||
* @throws CorruptedChunkException
|
* @throws CorruptedChunkException
|
||||||
*/
|
*/
|
||||||
public function getAllChunks(bool $skipCorrupted = false, ?\Logger $logger = null) : \Generator;
|
public function getAllChunks(bool $skipCorrupted = false, ?\Logger $logger = null) : \Generator;
|
||||||
|
@ -39,5 +39,5 @@ interface WritableWorldProvider extends WorldProvider{
|
|||||||
/**
|
/**
|
||||||
* Saves a chunk (usually to disk).
|
* Saves a chunk (usually to disk).
|
||||||
*/
|
*/
|
||||||
public function saveChunk(Chunk $chunk) : void;
|
public function saveChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void;
|
||||||
}
|
}
|
||||||
|
@ -398,8 +398,6 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{
|
|||||||
}
|
}
|
||||||
|
|
||||||
$chunk = new Chunk(
|
$chunk = new Chunk(
|
||||||
$chunkX,
|
|
||||||
$chunkZ,
|
|
||||||
$subChunks,
|
$subChunks,
|
||||||
$entities,
|
$entities,
|
||||||
$tiles,
|
$tiles,
|
||||||
@ -417,9 +415,9 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{
|
|||||||
return $chunk;
|
return $chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function writeChunk(Chunk $chunk) : void{
|
protected function writeChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void{
|
||||||
$idMap = LegacyBlockIdToStringIdMap::getInstance();
|
$idMap = LegacyBlockIdToStringIdMap::getInstance();
|
||||||
$index = LevelDB::chunkIndex($chunk->getX(), $chunk->getZ());
|
$index = LevelDB::chunkIndex($chunkX, $chunkZ);
|
||||||
|
|
||||||
$write = new \LevelDBWriteBatch();
|
$write = new \LevelDBWriteBatch();
|
||||||
$write->put($index . self::TAG_VERSION, chr(self::CURRENT_LEVEL_CHUNK_VERSION));
|
$write->put($index . self::TAG_VERSION, chr(self::CURRENT_LEVEL_CHUNK_VERSION));
|
||||||
@ -509,7 +507,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{
|
|||||||
$chunkZ = Binary::readLInt(substr($key, 4, 4));
|
$chunkZ = Binary::readLInt(substr($key, 4, 4));
|
||||||
try{
|
try{
|
||||||
if(($chunk = $this->loadChunk($chunkX, $chunkZ)) !== null){
|
if(($chunk = $this->loadChunk($chunkX, $chunkZ)) !== null){
|
||||||
yield $chunk;
|
yield [$chunkX, $chunkZ] => $chunk;
|
||||||
}
|
}
|
||||||
}catch(CorruptedChunkException $e){
|
}catch(CorruptedChunkException $e){
|
||||||
if(!$skipCorrupted){
|
if(!$skipCorrupted){
|
||||||
|
@ -93,8 +93,6 @@ trait LegacyAnvilChunkTrait{
|
|||||||
}
|
}
|
||||||
|
|
||||||
$result = new Chunk(
|
$result = new Chunk(
|
||||||
$chunk->getInt("xPos"),
|
|
||||||
$chunk->getInt("zPos"),
|
|
||||||
$subChunks,
|
$subChunks,
|
||||||
($entitiesTag = $chunk->getTag("Entities")) instanceof ListTag ? self::getCompoundList("Entities", $entitiesTag) : [],
|
($entitiesTag = $chunk->getTag("Entities")) instanceof ListTag ? self::getCompoundList("Entities", $entitiesTag) : [],
|
||||||
($tilesTag = $chunk->getTag("TileEntities")) instanceof ListTag ? self::getCompoundList("TileEntities", $tilesTag) : [],
|
($tilesTag = $chunk->getTag("TileEntities")) instanceof ListTag ? self::getCompoundList("TileEntities", $tilesTag) : [],
|
||||||
|
@ -89,8 +89,6 @@ class McRegion extends RegionWorldProvider{
|
|||||||
}
|
}
|
||||||
|
|
||||||
$result = new Chunk(
|
$result = new Chunk(
|
||||||
$chunk->getInt("xPos"),
|
|
||||||
$chunk->getInt("zPos"),
|
|
||||||
$subChunks,
|
$subChunks,
|
||||||
($entitiesTag = $chunk->getTag("Entities")) instanceof ListTag ? self::getCompoundList("Entities", $entitiesTag) : [],
|
($entitiesTag = $chunk->getTag("Entities")) instanceof ListTag ? self::getCompoundList("Entities", $entitiesTag) : [],
|
||||||
($tilesTag = $chunk->getTag("TileEntities")) instanceof ListTag ? self::getCompoundList("TileEntities", $tilesTag) : [],
|
($tilesTag = $chunk->getTag("TileEntities")) instanceof ListTag ? self::getCompoundList("TileEntities", $tilesTag) : [],
|
||||||
|
@ -228,10 +228,7 @@ abstract class RegionWorldProvider extends BaseWorldProvider{
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function writeChunk(Chunk $chunk) : void{
|
protected function writeChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void{
|
||||||
$chunkX = $chunk->getX();
|
|
||||||
$chunkZ = $chunk->getZ();
|
|
||||||
|
|
||||||
self::getRegionIndex($chunkX, $chunkZ, $regionX, $regionZ);
|
self::getRegionIndex($chunkX, $chunkZ, $regionX, $regionZ);
|
||||||
$this->loadRegion($regionX, $regionZ);
|
$this->loadRegion($regionX, $regionZ);
|
||||||
|
|
||||||
@ -263,7 +260,7 @@ abstract class RegionWorldProvider extends BaseWorldProvider{
|
|||||||
try{
|
try{
|
||||||
$chunk = $this->loadChunk($chunkX, $chunkZ);
|
$chunk = $this->loadChunk($chunkX, $chunkZ);
|
||||||
if($chunk !== null){
|
if($chunk !== null){
|
||||||
yield $chunk;
|
yield [$chunkX, $chunkZ] => $chunk;
|
||||||
}
|
}
|
||||||
}catch(CorruptedChunkException $e){
|
}catch(CorruptedChunkException $e){
|
||||||
if(!$skipCorrupted){
|
if(!$skipCorrupted){
|
||||||
|
@ -145,7 +145,7 @@ class Flat extends Generator{
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected function generateBaseChunk() : void{
|
protected function generateBaseChunk() : void{
|
||||||
$this->chunk = new Chunk(0, 0);
|
$this->chunk = new Chunk();
|
||||||
$this->chunk->setGenerated();
|
$this->chunk->setGenerated();
|
||||||
|
|
||||||
for($Z = 0; $Z < 16; ++$Z){
|
for($Z = 0; $Z < 16; ++$Z){
|
||||||
@ -170,10 +170,7 @@ class Flat extends Generator{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function generateChunk(ChunkManager $world, int $chunkX, int $chunkZ) : void{
|
public function generateChunk(ChunkManager $world, int $chunkX, int $chunkZ) : void{
|
||||||
$chunk = clone $this->chunk;
|
$world->setChunk($chunkX, $chunkZ, clone $this->chunk);
|
||||||
$chunk->setX($chunkX);
|
|
||||||
$chunk->setZ($chunkZ);
|
|
||||||
$world->setChunk($chunkX, $chunkZ, $chunk);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function populateChunk(ChunkManager $world, int $chunkX, int $chunkZ) : void{
|
public function populateChunk(ChunkManager $world, int $chunkX, int $chunkZ) : void{
|
||||||
|
@ -65,14 +65,14 @@ class PopulationTask extends AsyncTask{
|
|||||||
/** @var string */
|
/** @var string */
|
||||||
public $chunk8;
|
public $chunk8;
|
||||||
|
|
||||||
public function __construct(World $world, Chunk $chunk){
|
public function __construct(World $world, int $chunkX, int $chunkZ, Chunk $chunk){
|
||||||
$this->state = true;
|
$this->state = true;
|
||||||
$this->worldId = $world->getId();
|
$this->worldId = $world->getId();
|
||||||
$this->chunkX = $chunk->getX();
|
$this->chunkX = $chunkX;
|
||||||
$this->chunkZ = $chunk->getZ();
|
$this->chunkZ = $chunkZ;
|
||||||
$this->chunk = FastChunkSerializer::serializeWithoutLight($chunk);
|
$this->chunk = FastChunkSerializer::serializeWithoutLight($chunk);
|
||||||
|
|
||||||
foreach($world->getAdjacentChunks($chunk->getX(), $chunk->getZ()) as $i => $c){
|
foreach($world->getAdjacentChunks($chunkX, $chunkZ) as $i => $c){
|
||||||
$this->{"chunk$i"} = $c !== null ? FastChunkSerializer::serializeWithoutLight($c) : null;
|
$this->{"chunk$i"} = $c !== null ? FastChunkSerializer::serializeWithoutLight($c) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,40 +91,40 @@ class PopulationTask extends AsyncTask{
|
|||||||
/** @var Chunk[] $chunks */
|
/** @var Chunk[] $chunks */
|
||||||
$chunks = [];
|
$chunks = [];
|
||||||
|
|
||||||
$chunk = FastChunkSerializer::deserialize($this->chunk, $this->chunkX, $this->chunkZ);
|
$chunk = FastChunkSerializer::deserialize($this->chunk);
|
||||||
|
|
||||||
for($i = 0; $i < 9; ++$i){
|
for($i = 0; $i < 9; ++$i){
|
||||||
if($i === 4){
|
if($i === 4){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$xx = -1 + $i % 3;
|
|
||||||
$zz = -1 + (int) ($i / 3);
|
|
||||||
$ck = $this->{"chunk$i"};
|
$ck = $this->{"chunk$i"};
|
||||||
if($ck === null){
|
if($ck === null){
|
||||||
$chunks[$i] = new Chunk($this->chunkX + $xx, $this->chunkZ + $zz);
|
$chunks[$i] = new Chunk();
|
||||||
}else{
|
}else{
|
||||||
$chunks[$i] = FastChunkSerializer::deserialize($ck, $this->chunkX + $xx, $this->chunkZ + $zz);
|
$chunks[$i] = FastChunkSerializer::deserialize($ck);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$manager->setChunk($chunk->getX(), $chunk->getZ(), $chunk);
|
$manager->setChunk($this->chunkX, $this->chunkZ, $chunk);
|
||||||
if(!$chunk->isGenerated()){
|
if(!$chunk->isGenerated()){
|
||||||
$generator->generateChunk($manager, $chunk->getX(), $chunk->getZ());
|
$generator->generateChunk($manager, $this->chunkX, $this->chunkZ);
|
||||||
$chunk = $manager->getChunk($chunk->getX(), $chunk->getZ());
|
$chunk = $manager->getChunk($this->chunkX, $this->chunkZ);
|
||||||
$chunk->setGenerated();
|
$chunk->setGenerated();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($chunks as $i => $c){
|
foreach($chunks as $i => $c){
|
||||||
$manager->setChunk($c->getX(), $c->getZ(), $c);
|
$cX = (-1 + $i % 3) + $this->chunkX;
|
||||||
|
$cZ = (-1 + intdiv($i, 3)) + $this->chunkZ;
|
||||||
|
$manager->setChunk($cX, $cZ, $c);
|
||||||
if(!$c->isGenerated()){
|
if(!$c->isGenerated()){
|
||||||
$generator->generateChunk($manager, $c->getX(), $c->getZ());
|
$generator->generateChunk($manager, $cX, $cZ);
|
||||||
$chunks[$i] = $manager->getChunk($c->getX(), $c->getZ());
|
$chunks[$i] = $manager->getChunk($cX, $cZ);
|
||||||
$chunks[$i]->setGenerated();
|
$chunks[$i]->setGenerated();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$generator->populateChunk($manager, $chunk->getX(), $chunk->getZ());
|
$generator->populateChunk($manager, $this->chunkX, $this->chunkZ);
|
||||||
$chunk = $manager->getChunk($chunk->getX(), $chunk->getZ());
|
$chunk = $manager->getChunk($this->chunkX, $this->chunkZ);
|
||||||
$chunk->setPopulated();
|
$chunk->setPopulated();
|
||||||
|
|
||||||
$this->chunk = FastChunkSerializer::serializeWithoutLight($chunk);
|
$this->chunk = FastChunkSerializer::serializeWithoutLight($chunk);
|
||||||
@ -142,7 +142,7 @@ class PopulationTask extends AsyncTask{
|
|||||||
$world->registerGeneratorToWorker($this->worker->getAsyncWorkerId());
|
$world->registerGeneratorToWorker($this->worker->getAsyncWorkerId());
|
||||||
}
|
}
|
||||||
|
|
||||||
$chunk = FastChunkSerializer::deserialize($this->chunk, $this->chunkX, $this->chunkZ);
|
$chunk = FastChunkSerializer::deserialize($this->chunk);
|
||||||
|
|
||||||
for($i = 0; $i < 9; ++$i){
|
for($i = 0; $i < 9; ++$i){
|
||||||
if($i === 4){
|
if($i === 4){
|
||||||
@ -153,7 +153,7 @@ class PopulationTask extends AsyncTask{
|
|||||||
$xx = -1 + $i % 3;
|
$xx = -1 + $i % 3;
|
||||||
$zz = -1 + intdiv($i, 3);
|
$zz = -1 + intdiv($i, 3);
|
||||||
|
|
||||||
$c = FastChunkSerializer::deserialize($c, $this->chunkX + $xx, $this->chunkZ + $zz);
|
$c = FastChunkSerializer::deserialize($c);
|
||||||
$world->generateChunkCallback($this->chunkX + $xx, $this->chunkZ + $zz, $this->state ? $c : null);
|
$world->generateChunkCallback($this->chunkX + $xx, $this->chunkZ + $zz, $this->state ? $c : null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,15 +52,15 @@ class LightPopulationTask extends AsyncTask{
|
|||||||
/** @var string */
|
/** @var string */
|
||||||
private $resultBlockLightArrays;
|
private $resultBlockLightArrays;
|
||||||
|
|
||||||
public function __construct(World $world, Chunk $chunk){
|
public function __construct(World $world, int $chunkX, int $chunkZ, Chunk $chunk){
|
||||||
$this->storeLocal(self::TLS_KEY_WORLD, $world);
|
$this->storeLocal(self::TLS_KEY_WORLD, $world);
|
||||||
[$this->chunkX, $this->chunkZ] = [$chunk->getX(), $chunk->getZ()];
|
[$this->chunkX, $this->chunkZ] = [$chunkX, $chunkZ];
|
||||||
$chunk->setLightPopulated(null);
|
$chunk->setLightPopulated(null);
|
||||||
$this->chunk = FastChunkSerializer::serialize($chunk);
|
$this->chunk = FastChunkSerializer::serialize($chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onRun() : void{
|
public function onRun() : void{
|
||||||
$chunk = FastChunkSerializer::deserialize($this->chunk, $this->chunkX, $this->chunkZ);
|
$chunk = FastChunkSerializer::deserialize($this->chunk);
|
||||||
|
|
||||||
$manager = new SimpleChunkManager();
|
$manager = new SimpleChunkManager();
|
||||||
$manager->setChunk($this->chunkX, $this->chunkZ, $chunk);
|
$manager->setChunk($this->chunkX, $this->chunkZ, $chunk);
|
||||||
|
@ -526,7 +526,7 @@ parameters:
|
|||||||
path: ../../../src/world/Explosion.php
|
path: ../../../src/world/Explosion.php
|
||||||
|
|
||||||
-
|
-
|
||||||
message: "#^Parameter \\#1 \\$chunk of method pocketmine\\\\player\\\\Player\\:\\:onChunkChanged\\(\\) expects pocketmine\\\\world\\\\format\\\\Chunk, pocketmine\\\\world\\\\format\\\\Chunk\\|null given\\.$#"
|
message: "#^Parameter \\#3 \\$chunk of method pocketmine\\\\player\\\\Player\\:\\:onChunkChanged\\(\\) expects pocketmine\\\\world\\\\format\\\\Chunk, pocketmine\\\\world\\\\format\\\\Chunk\\|null given\\.$#"
|
||||||
count: 1
|
count: 1
|
||||||
path: ../../../src/world/World.php
|
path: ../../../src/world/World.php
|
||||||
|
|
||||||
@ -595,16 +595,6 @@ parameters:
|
|||||||
count: 2
|
count: 2
|
||||||
path: ../../../src/world/generator/PopulationTask.php
|
path: ../../../src/world/generator/PopulationTask.php
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Cannot call method getX\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#"
|
|
||||||
count: 5
|
|
||||||
path: ../../../src/world/generator/PopulationTask.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Cannot call method getZ\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#"
|
|
||||||
count: 5
|
|
||||||
path: ../../../src/world/generator/PopulationTask.php
|
|
||||||
|
|
||||||
-
|
-
|
||||||
message: "#^Cannot call method isGenerated\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#"
|
message: "#^Cannot call method isGenerated\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#"
|
||||||
count: 1
|
count: 1
|
||||||
|
@ -28,7 +28,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
class ChunkTest extends TestCase{
|
class ChunkTest extends TestCase{
|
||||||
|
|
||||||
public function testClone() : void{
|
public function testClone() : void{
|
||||||
$chunk = new Chunk(0, 0);
|
$chunk = new Chunk();
|
||||||
$chunk->setFullBlock(0, 0, 0, 1);
|
$chunk->setFullBlock(0, 0, 0, 1);
|
||||||
$chunk->setBiomeId(0, 0, 1);
|
$chunk->setBiomeId(0, 0, 1);
|
||||||
$chunk->setHeightMap(0, 0, 1);
|
$chunk->setHeightMap(0, 0, 1);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user