|
|
|
@ -754,7 +754,7 @@ class World implements ChunkManager{
|
|
|
|
|
}
|
|
|
|
|
World::getXZ($index, $chunkX, $chunkZ);
|
|
|
|
|
if(count($blocks) > 512){
|
|
|
|
|
$chunk = $this->getChunk($chunkX, $chunkZ);
|
|
|
|
|
$chunk = $this->getOrLoadChunk($chunkX, $chunkZ);
|
|
|
|
|
foreach($this->getChunkPlayers($chunkX, $chunkZ) as $p){
|
|
|
|
|
$p->onChunkChanged($chunk);
|
|
|
|
|
}
|
|
|
|
@ -1241,7 +1241,7 @@ class World implements ChunkManager{
|
|
|
|
|
* @return int bitmap, (id << 4) | data
|
|
|
|
|
*/
|
|
|
|
|
public function getFullBlock(int $x, int $y, int $z) : int{
|
|
|
|
|
return $this->getChunk($x >> 4, $z >> 4, false)->getFullBlock($x & 0x0f, $y, $z & 0x0f);
|
|
|
|
|
return $this->getOrLoadChunk($x >> 4, $z >> 4, false)->getFullBlock($x & 0x0f, $y, $z & 0x0f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function isInWorld(int $x, int $y, int $z) : bool{
|
|
|
|
@ -1653,7 +1653,7 @@ class World implements ChunkManager{
|
|
|
|
|
if(!$this->isChunkLoaded($x, $z)){
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
foreach($this->getChunk($x, $z)->getEntities() as $ent){
|
|
|
|
|
foreach($this->getOrLoadChunk($x, $z)->getEntities() as $ent){
|
|
|
|
|
/** @var Entity|null $entity */
|
|
|
|
|
if($ent->canBeCollidedWith() and ($entity === null or ($ent !== $entity and $entity->canCollideWith($ent))) and $ent->boundingBox->intersectsWith($bb)){
|
|
|
|
|
$nearby[] = $ent;
|
|
|
|
@ -1684,7 +1684,7 @@ class World implements ChunkManager{
|
|
|
|
|
if(!$this->isChunkLoaded($x, $z)){
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
foreach($this->getChunk($x, $z)->getEntities() as $ent){
|
|
|
|
|
foreach($this->getOrLoadChunk($x, $z)->getEntities() as $ent){
|
|
|
|
|
if($ent !== $entity and $ent->boundingBox->intersectsWith($bb)){
|
|
|
|
|
$nearby[] = $ent;
|
|
|
|
|
}
|
|
|
|
@ -1727,7 +1727,7 @@ class World implements ChunkManager{
|
|
|
|
|
if(!$this->isChunkLoaded($x, $z)){
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
foreach($this->getChunk($x, $z)->getEntities() as $entity){
|
|
|
|
|
foreach($this->getOrLoadChunk($x, $z)->getEntities() as $entity){
|
|
|
|
|
if(!($entity instanceof $entityType) or $entity->isFlaggedForDespawn() or (!$includeDead and !$entity->isAlive())){
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
@ -1773,7 +1773,7 @@ class World implements ChunkManager{
|
|
|
|
|
* Returns the tile at the specified x,y,z coordinates, or null if it does not exist.
|
|
|
|
|
*/
|
|
|
|
|
public function getTileAt(int $x, int $y, int $z) : ?Tile{
|
|
|
|
|
return ($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null ? $chunk->getTile($x & 0x0f, $y, $z & 0x0f) : null;
|
|
|
|
|
return ($chunk = $this->getOrLoadChunk($x >> 4, $z >> 4)) !== null ? $chunk->getTile($x & 0x0f, $y, $z & 0x0f) : null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -1782,7 +1782,7 @@ class World implements ChunkManager{
|
|
|
|
|
* @return int 0-15
|
|
|
|
|
*/
|
|
|
|
|
public function getBlockSkyLightAt(int $x, int $y, int $z) : int{
|
|
|
|
|
return $this->getChunk($x >> 4, $z >> 4, true)->getBlockSkyLight($x & 0x0f, $y, $z & 0x0f);
|
|
|
|
|
return $this->getOrLoadChunk($x >> 4, $z >> 4, true)->getBlockSkyLight($x & 0x0f, $y, $z & 0x0f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -1791,11 +1791,11 @@ class World implements ChunkManager{
|
|
|
|
|
* @return int 0-15
|
|
|
|
|
*/
|
|
|
|
|
public function getBlockLightAt(int $x, int $y, int $z) : int{
|
|
|
|
|
return $this->getChunk($x >> 4, $z >> 4, true)->getBlockLight($x & 0x0f, $y, $z & 0x0f);
|
|
|
|
|
return $this->getOrLoadChunk($x >> 4, $z >> 4, true)->getBlockLight($x & 0x0f, $y, $z & 0x0f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getBiomeId(int $x, int $z) : int{
|
|
|
|
|
return $this->getChunk($x >> 4, $z >> 4, true)->getBiomeId($x & 0x0f, $z & 0x0f);
|
|
|
|
|
return $this->getOrLoadChunk($x >> 4, $z >> 4, true)->getBiomeId($x & 0x0f, $z & 0x0f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getBiome(int $x, int $z) : Biome{
|
|
|
|
@ -1803,7 +1803,7 @@ class World implements ChunkManager{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function setBiomeId(int $x, int $z, int $biomeId) : void{
|
|
|
|
|
$this->getChunk($x >> 4, $z >> 4, true)->setBiomeId($x & 0x0f, $z & 0x0f, $biomeId);
|
|
|
|
|
$this->getOrLoadChunk($x >> 4, $z >> 4, true)->setBiomeId($x & 0x0f, $z & 0x0f, $biomeId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -1819,7 +1819,7 @@ class World implements ChunkManager{
|
|
|
|
|
*
|
|
|
|
|
* @param bool $create Whether to create an empty chunk as a placeholder if the chunk does not exist
|
|
|
|
|
*/
|
|
|
|
|
public function getChunk(int $chunkX, int $chunkZ, bool $create = false) : ?Chunk{
|
|
|
|
|
public function getOrLoadChunk(int $chunkX, int $chunkZ, bool $create = false) : ?Chunk{
|
|
|
|
|
if(isset($this->chunks[$index = World::chunkHash($chunkX, $chunkZ)])){
|
|
|
|
|
return $this->chunks[$index];
|
|
|
|
|
}elseif($this->loadChunk($chunkX, $chunkZ, $create)){
|
|
|
|
@ -1829,11 +1829,19 @@ class World implements ChunkManager{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getChunk(int $chunkX, int $chunkZ, bool $create = false) : ?Chunk{
|
|
|
|
|
$hash = World::chunkHash($chunkX, $chunkZ);
|
|
|
|
|
if(isset($this->chunks[$hash])){
|
|
|
|
|
return $this->chunks[$hash];
|
|
|
|
|
}
|
|
|
|
|
return $create ? ($this->chunks[$hash] = new Chunk($chunkX, $chunkZ)) : null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns the chunk containing the given Vector3 position.
|
|
|
|
|
*/
|
|
|
|
|
public function getChunkAtPosition(Vector3 $pos, bool $create = false) : ?Chunk{
|
|
|
|
|
return $this->getChunk($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4, $create);
|
|
|
|
|
return $this->getOrLoadChunk($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4, $create);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -1849,7 +1857,7 @@ class World implements ChunkManager{
|
|
|
|
|
if($i === 4){
|
|
|
|
|
continue; //center chunk
|
|
|
|
|
}
|
|
|
|
|
$result[$i] = $this->getChunk($x + $xx - 1, $z + $zz - 1, false);
|
|
|
|
|
$result[$i] = $this->getOrLoadChunk($x + $xx - 1, $z + $zz - 1, false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1883,7 +1891,7 @@ class World implements ChunkManager{
|
|
|
|
|
unset($this->chunkPopulationQueue[$index]);
|
|
|
|
|
|
|
|
|
|
if($chunk !== null){
|
|
|
|
|
$oldChunk = $this->getChunk($x, $z, false);
|
|
|
|
|
$oldChunk = $this->getOrLoadChunk($x, $z, false);
|
|
|
|
|
$this->setChunk($x, $z, $chunk, false);
|
|
|
|
|
if(($oldChunk === null or !$oldChunk->isPopulated()) and $chunk->isPopulated()){
|
|
|
|
|
(new ChunkPopulateEvent($this, $chunk))->call();
|
|
|
|
@ -1916,7 +1924,7 @@ class World implements ChunkManager{
|
|
|
|
|
$chunk->setZ($chunkZ);
|
|
|
|
|
|
|
|
|
|
$chunkHash = World::chunkHash($chunkX, $chunkZ);
|
|
|
|
|
$oldChunk = $this->getChunk($chunkX, $chunkZ, false);
|
|
|
|
|
$oldChunk = $this->getOrLoadChunk($chunkX, $chunkZ, false);
|
|
|
|
|
if($oldChunk !== null and $oldChunk !== $chunk){
|
|
|
|
|
if($deleteEntitiesAndTiles){
|
|
|
|
|
foreach($oldChunk->getEntities() as $player){
|
|
|
|
@ -1964,7 +1972,7 @@ class World implements ChunkManager{
|
|
|
|
|
* @return int 0-255
|
|
|
|
|
*/
|
|
|
|
|
public function getHighestBlockAt(int $x, int $z) : int{
|
|
|
|
|
return $this->getChunk($x >> 4, $z >> 4, true)->getHighestBlockAt($x & 0x0f, $z & 0x0f);
|
|
|
|
|
return $this->getOrLoadChunk($x >> 4, $z >> 4, true)->getHighestBlockAt($x & 0x0f, $z & 0x0f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -1979,12 +1987,12 @@ class World implements ChunkManager{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function isChunkGenerated(int $x, int $z) : bool{
|
|
|
|
|
$chunk = $this->getChunk($x, $z);
|
|
|
|
|
$chunk = $this->getOrLoadChunk($x, $z);
|
|
|
|
|
return $chunk !== null ? $chunk->isGenerated() : false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function isChunkPopulated(int $x, int $z) : bool{
|
|
|
|
|
$chunk = $this->getChunk($x, $z);
|
|
|
|
|
$chunk = $this->getOrLoadChunk($x, $z);
|
|
|
|
|
return $chunk !== null ? $chunk->isPopulated() : false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -2360,7 +2368,7 @@ class World implements ChunkManager{
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$chunk = $this->getChunk($x, $z, true);
|
|
|
|
|
$chunk = $this->getOrLoadChunk($x, $z, true);
|
|
|
|
|
if(!$chunk->isPopulated()){
|
|
|
|
|
Timings::$populationTimer->startTiming();
|
|
|
|
|
|
|
|
|
|