mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-07-03 08:39:53 +00:00
Docs for Chunk
This commit is contained in:
parent
ad0553fbf8
commit
aaf549a469
@ -39,6 +39,8 @@ use pocketmine\utils\ChunkException;
|
|||||||
|
|
||||||
class Chunk{
|
class Chunk{
|
||||||
|
|
||||||
|
const MAX_SUBCHUNKS = 16;
|
||||||
|
|
||||||
/** @var LevelProvider */
|
/** @var LevelProvider */
|
||||||
protected $provider;
|
protected $provider;
|
||||||
|
|
||||||
@ -53,7 +55,7 @@ class Chunk{
|
|||||||
protected $terrainGenerated = false;
|
protected $terrainGenerated = false;
|
||||||
protected $terrainPopulated = false;
|
protected $terrainPopulated = false;
|
||||||
|
|
||||||
protected $height = 16;//Chunk::MAX_SUBCHUNKS;
|
protected $height = Chunk::MAX_SUBCHUNKS;
|
||||||
|
|
||||||
/** @var SubChunk[] */
|
/** @var SubChunk[] */
|
||||||
protected $subChunks = [];
|
protected $subChunks = [];
|
||||||
@ -137,10 +139,16 @@ class Chunk{
|
|||||||
$this->NBTentities = $entities;
|
$this->NBTentities = $entities;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
public function getX() : int{
|
public function getX() : int{
|
||||||
return $this->x;
|
return $this->x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
public function getZ() : int{
|
public function getZ() : int{
|
||||||
return $this->z;
|
return $this->z;
|
||||||
}
|
}
|
||||||
@ -149,26 +157,60 @@ class Chunk{
|
|||||||
$this->x = $x;
|
$this->x = $x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $z
|
||||||
|
*/
|
||||||
public function setZ(int $z){
|
public function setZ(int $z){
|
||||||
$this->z = $z;
|
$this->z = $z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return LevelProvider|null
|
||||||
|
*/
|
||||||
public function getProvider(){
|
public function getProvider(){
|
||||||
return $this->provider;
|
return $this->provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param LevelProvider $provider
|
||||||
|
*/
|
||||||
public function setProvider(LevelProvider $provider){
|
public function setProvider(LevelProvider $provider){
|
||||||
$this->provider = $provider;
|
$this->provider = $provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the chunk height in count of subchunks.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
public function getHeight() : int{
|
public function getHeight() : int{
|
||||||
return $this->height;
|
return $this->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a bitmap of block ID and meta at the specified chunk block coordinates
|
||||||
|
*
|
||||||
|
* @param int $x 0-15
|
||||||
|
* @param int $y
|
||||||
|
* @param int $z 0-15
|
||||||
|
*
|
||||||
|
* @return int bitmap, (id << 4) | meta
|
||||||
|
*/
|
||||||
public function getFullBlock(int $x, int $y, int $z) : int{
|
public function getFullBlock(int $x, int $y, int $z) : int{
|
||||||
return $this->getSubChunk($y >> 4)->getFullBlock($x, $y & 0x0f, $z);
|
return $this->getSubChunk($y >> 4)->getFullBlock($x, $y & 0x0f, $z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets block ID and meta in one call at the specified chunk block coordinates
|
||||||
|
*
|
||||||
|
* @param int $x 0-15
|
||||||
|
* @param int $y
|
||||||
|
* @param int $z 0-15
|
||||||
|
* @param int|null $blockId 0-255 if null, does not change
|
||||||
|
* @param int|null $meta 0-15 if null, does not change
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
public function setBlock(int $x, int $y, int $z, $blockId = null, $meta = null) : bool{
|
public function setBlock(int $x, int $y, int $z, $blockId = null, $meta = null) : bool{
|
||||||
if($this->getSubChunk($y >> 4, true)->setBlock($x, $y & 0x0f, $z, $blockId !== null ? ($blockId & 0xff) : null, $meta !== null ? ($meta & 0x0f) : null)){
|
if($this->getSubChunk($y >> 4, true)->setBlock($x, $y & 0x0f, $z, $blockId !== null ? ($blockId & 0xff) : null, $meta !== null ? ($meta & 0x0f) : null)){
|
||||||
$this->hasChanged = true;
|
$this->hasChanged = true;
|
||||||
@ -177,30 +219,81 @@ class Chunk{
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the block ID at the specified chunk block coordinates
|
||||||
|
*
|
||||||
|
* @param int $x 0-15
|
||||||
|
* @param int $y
|
||||||
|
* @param int $z 0-15
|
||||||
|
*
|
||||||
|
* @return int 0-255
|
||||||
|
*/
|
||||||
public function getBlockId(int $x, int $y, int $z) : int{
|
public function getBlockId(int $x, int $y, int $z) : int{
|
||||||
return $this->getSubChunk($y >> 4)->getBlockId($x, $y & 0x0f, $z);
|
return $this->getSubChunk($y >> 4)->getBlockId($x, $y & 0x0f, $z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the block ID at the specified chunk block coordinates
|
||||||
|
*
|
||||||
|
* @param int $x 0-15
|
||||||
|
* @param int $y
|
||||||
|
* @param int $z 0-15
|
||||||
|
* @param int $id 0-255
|
||||||
|
*/
|
||||||
public function setBlockId(int $x, int $y, int $z, int $id){
|
public function setBlockId(int $x, int $y, int $z, int $id){
|
||||||
if($this->getSubChunk($y >> 4, true)->setBlockId($x, $y & 0x0f, $z, $id)){
|
if($this->getSubChunk($y >> 4, true)->setBlockId($x, $y & 0x0f, $z, $id)){
|
||||||
$this->hasChanged = true;
|
$this->hasChanged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the block meta value at the specified chunk block coordinates
|
||||||
|
*
|
||||||
|
* @param int $x 0-15
|
||||||
|
* @param int $y
|
||||||
|
* @param int $z 0-15
|
||||||
|
*
|
||||||
|
* @return int 0-15
|
||||||
|
*/
|
||||||
public function getBlockData(int $x, int $y, int $z) : int{
|
public function getBlockData(int $x, int $y, int $z) : int{
|
||||||
return $this->getSubChunk($y >> 4)->getBlockData($x, $y & 0x0f, $z);
|
return $this->getSubChunk($y >> 4)->getBlockData($x, $y & 0x0f, $z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the block meta value at the specified chunk block coordinates
|
||||||
|
*
|
||||||
|
* @param int $x 0-15
|
||||||
|
* @param int $y
|
||||||
|
* @param int $z 0-15
|
||||||
|
* @param int $data 0-15
|
||||||
|
*/
|
||||||
public function setBlockData(int $x, int $y, int $z, int $data){
|
public function setBlockData(int $x, int $y, int $z, int $data){
|
||||||
if($this->getSubChunk($y >> 4)->setBlockData($x, $y & 0x0f, $z, $data)){
|
if($this->getSubChunk($y >> 4)->setBlockData($x, $y & 0x0f, $z, $data)){
|
||||||
$this->hasChanged = true;
|
$this->hasChanged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the raw block extra data value at the specified chunk block coordinates, or 0 if no data exists
|
||||||
|
*
|
||||||
|
* @param int $x 0-15
|
||||||
|
* @param int $y
|
||||||
|
* @param int $z 0-15
|
||||||
|
*
|
||||||
|
* @return int bitmap, (meta << 8) | id
|
||||||
|
*/
|
||||||
public function getBlockExtraData(int $x, int $y, int $z) : int{
|
public function getBlockExtraData(int $x, int $y, int $z) : int{
|
||||||
return $this->extraData[Chunk::chunkBlockHash($x, $y, $z)] ?? 0;
|
return $this->extraData[Chunk::chunkBlockHash($x, $y, $z)] ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the raw block extra data value at the specified chunk block coordinates
|
||||||
|
*
|
||||||
|
* @param int $x 0-15
|
||||||
|
* @param int $y
|
||||||
|
* @param int $z 0-15
|
||||||
|
* @param int $data bitmap, (meta << 8) | id
|
||||||
|
*/
|
||||||
public function setBlockExtraData(int $x, int $y, int $z, int $data){
|
public function setBlockExtraData(int $x, int $y, int $z, int $data){
|
||||||
if($data === 0){
|
if($data === 0){
|
||||||
unset($this->extraData[Chunk::chunkBlockHash($x, $y, $z)]);
|
unset($this->extraData[Chunk::chunkBlockHash($x, $y, $z)]);
|
||||||
@ -211,26 +304,69 @@ class Chunk{
|
|||||||
$this->hasChanged = true;
|
$this->hasChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the sky light level at the specified chunk block coordinates
|
||||||
|
*
|
||||||
|
* @param int $x 0-15
|
||||||
|
* @param int $y
|
||||||
|
* @param int $z 0-15
|
||||||
|
*
|
||||||
|
* @return int 0-15
|
||||||
|
*/
|
||||||
public function getBlockSkyLight(int $x, int $y, int $z) : int{
|
public function getBlockSkyLight(int $x, int $y, int $z) : int{
|
||||||
return $this->getSubChunk($y >> 4)->getBlockSkyLight($x, $y & 0x0f, $z);
|
return $this->getSubChunk($y >> 4)->getBlockSkyLight($x, $y & 0x0f, $z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the sky light level at the specified chunk block coordinates
|
||||||
|
*
|
||||||
|
* @param int $x 0-15
|
||||||
|
* @param int $y
|
||||||
|
* @param int $z 0-15
|
||||||
|
* @param int $level 0-15
|
||||||
|
*/
|
||||||
public function setBlockSkyLight(int $x, int $y, int $z, int $level){
|
public function setBlockSkyLight(int $x, int $y, int $z, int $level){
|
||||||
if($this->getSubChunk($y >> 4)->setBlockSkyLight($x, $y & 0x0f, $z, $level)){
|
if($this->getSubChunk($y >> 4)->setBlockSkyLight($x, $y & 0x0f, $z, $level)){
|
||||||
$this->hasChanged = true;
|
$this->hasChanged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the block light level at the specified chunk block coordinates
|
||||||
|
*
|
||||||
|
* @param int $x 0-15
|
||||||
|
* @param int $y 0-15
|
||||||
|
* @param int $z 0-15
|
||||||
|
*
|
||||||
|
* @return int 0-15
|
||||||
|
*/
|
||||||
public function getBlockLight(int $x, int $y, int $z) : int{
|
public function getBlockLight(int $x, int $y, int $z) : int{
|
||||||
return $this->getSubChunk($y >> 4)->getBlockLight($x, $y & 0x0f, $z);
|
return $this->getSubChunk($y >> 4)->getBlockLight($x, $y & 0x0f, $z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the block light level at the specified chunk block coordinates
|
||||||
|
*
|
||||||
|
* @param int $x 0-15
|
||||||
|
* @param int $y 0-15
|
||||||
|
* @param int $z 0-15
|
||||||
|
* @param int $level 0-15
|
||||||
|
*/
|
||||||
public function setBlockLight(int $x, int $y, int $z, int $level){
|
public function setBlockLight(int $x, int $y, int $z, int $level){
|
||||||
if($this->getSubChunk($y >> 4)->setBlockLight($x, $y & 0x0f, $z, $level)){
|
if($this->getSubChunk($y >> 4)->setBlockLight($x, $y & 0x0f, $z, $level)){
|
||||||
$this->hasChanged = true;
|
$this->hasChanged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Y coordinate of the highest non-air block at the specified X/Z chunk block coordinates
|
||||||
|
*
|
||||||
|
* @param int $x 0-15
|
||||||
|
* @param int $z 0-15
|
||||||
|
* @param bool $useHeightMap whether to use pre-calculated heightmap values or not
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
public function getHighestBlockAt(int $x, int $z, bool $useHeightMap = true) : int{
|
public function getHighestBlockAt(int $x, int $z, bool $useHeightMap = true) : int{
|
||||||
if($useHeightMap){
|
if($useHeightMap){
|
||||||
$height = $this->getHeightMap($x, $z);
|
$height = $this->getHeightMap($x, $z);
|
||||||
@ -258,14 +394,31 @@ class Chunk{
|
|||||||
return $height;
|
return $height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the heightmap value at the specified X/Z chunk block coordinates
|
||||||
|
*
|
||||||
|
* @param int $x 0-15
|
||||||
|
* @param int $z 0-15
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
public function getHeightMap(int $x, int $z) : int{
|
public function getHeightMap(int $x, int $z) : int{
|
||||||
return $this->heightMap[($z << 4) | $x];
|
return $this->heightMap[($z << 4) | $x];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the heightmap value at the specified X/Z chunk block coordinates
|
||||||
|
* @param int $x 0-15
|
||||||
|
* @param int $z 0-15
|
||||||
|
* @param int $value
|
||||||
|
*/
|
||||||
public function setHeightMap(int $x, int $z, int $value){
|
public function setHeightMap(int $x, int $z, int $value){
|
||||||
$this->heightMap[($z << 4) | $x] = $value;
|
$this->heightMap[($z << 4) | $x] = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recalculates the heightmap for the whole chunk.
|
||||||
|
*/
|
||||||
public function recalculateHeightMap(){
|
public function recalculateHeightMap(){
|
||||||
for($z = 0; $z < 16; ++$z){
|
for($z = 0; $z < 16; ++$z){
|
||||||
for($x = 0; $x < 16; ++$x){
|
for($x = 0; $x < 16; ++$x){
|
||||||
@ -274,8 +427,12 @@ class Chunk{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs basic sky light population on the chunk.
|
||||||
|
*
|
||||||
|
* TODO: rewrite this, use block light filters and diffusion, actual proper sky light population
|
||||||
|
*/
|
||||||
public function populateSkyLight(){
|
public function populateSkyLight(){
|
||||||
//TODO: rewrite this, use block light filters and diffusion, actual proper sky light population
|
|
||||||
for($x = 0; $x < 16; ++$x){
|
for($x = 0; $x < 16; ++$x){
|
||||||
for($z = 0; $z < 16; ++$z){
|
for($z = 0; $z < 16; ++$z){
|
||||||
$heightMap = $this->getHeightMap($x, $z);
|
$heightMap = $this->getHeightMap($x, $z);
|
||||||
@ -299,15 +456,37 @@ class Chunk{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the biome ID at the specified X/Z chunk block coordinates
|
||||||
|
*
|
||||||
|
* @param int $x 0-15
|
||||||
|
* @param int $z 0-15
|
||||||
|
*
|
||||||
|
* @return int 0-255
|
||||||
|
*/
|
||||||
public function getBiomeId(int $x, int $z) : int{
|
public function getBiomeId(int $x, int $z) : int{
|
||||||
return ord($this->biomeIds{($z << 4) | $x});
|
return ord($this->biomeIds{($z << 4) | $x});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the biome ID at the specified X/Z chunk block coordinates
|
||||||
|
*
|
||||||
|
* @param int $x 0-15
|
||||||
|
* @param int $z 0-15
|
||||||
|
* @param int $biomeId 0-255
|
||||||
|
*/
|
||||||
public function setBiomeId(int $x, int $z, int $biomeId){
|
public function setBiomeId(int $x, int $z, int $biomeId){
|
||||||
$this->hasChanged = true;
|
$this->hasChanged = true;
|
||||||
$this->biomeIds{($z << 4) | $x} = chr($biomeId & 0xff);
|
$this->biomeIds{($z << 4) | $x} = chr($biomeId & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a column of block IDs from bottom to top at the specified X/Z chunk block coordinates.
|
||||||
|
* @param int $x 0-15
|
||||||
|
* @param int $z 0-15
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function getBlockIdColumn(int $x, int $z) : string{
|
public function getBlockIdColumn(int $x, int $z) : string{
|
||||||
$result = "";
|
$result = "";
|
||||||
foreach($this->subChunks as $subChunk){
|
foreach($this->subChunks as $subChunk){
|
||||||
@ -316,6 +495,13 @@ class Chunk{
|
|||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a column of block meta values from bottom to top at the specified X/Z chunk block coordinates.
|
||||||
|
* @param int $x 0-15
|
||||||
|
* @param int $z 0-15
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function getBlockDataColumn(int $x, int $z) : string{
|
public function getBlockDataColumn(int $x, int $z) : string{
|
||||||
$result = "";
|
$result = "";
|
||||||
foreach($this->subChunks as $subChunk){
|
foreach($this->subChunks as $subChunk){
|
||||||
@ -324,6 +510,13 @@ class Chunk{
|
|||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a column of sky light values from bottom to top at the specified X/Z chunk block coordinates.
|
||||||
|
* @param int $x 0-15
|
||||||
|
* @param int $z 0-15
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function getBlockSkyLightColumn(int $x, int $z) : string{
|
public function getBlockSkyLightColumn(int $x, int $z) : string{
|
||||||
$result = "";
|
$result = "";
|
||||||
foreach($this->subChunks as $subChunk){
|
foreach($this->subChunks as $subChunk){
|
||||||
@ -332,6 +525,13 @@ class Chunk{
|
|||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a column of block light values from bottom to top at the specified X/Z chunk block coordinates.
|
||||||
|
* @param int $x 0-15
|
||||||
|
* @param int $z 0-15
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function getBlockLightColumn(int $x, int $z) : string{
|
public function getBlockLightColumn(int $x, int $z) : string{
|
||||||
$result = "";
|
$result = "";
|
||||||
foreach($this->subChunks as $subChunk){
|
foreach($this->subChunks as $subChunk){
|
||||||
@ -340,30 +540,51 @@ class Chunk{
|
|||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
public function isLightPopulated() : bool{
|
public function isLightPopulated() : bool{
|
||||||
return $this->lightPopulated;
|
return $this->lightPopulated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param bool $value
|
||||||
|
*/
|
||||||
public function setLightPopulated(bool $value = true){
|
public function setLightPopulated(bool $value = true){
|
||||||
$this->lightPopulated = $value;
|
$this->lightPopulated = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
public function isPopulated() : bool{
|
public function isPopulated() : bool{
|
||||||
return $this->terrainPopulated;
|
return $this->terrainPopulated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param bool $value
|
||||||
|
*/
|
||||||
public function setPopulated(bool $value = true){
|
public function setPopulated(bool $value = true){
|
||||||
$this->terrainPopulated = $value;
|
$this->terrainPopulated = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
public function isGenerated() : bool{
|
public function isGenerated() : bool{
|
||||||
return $this->terrainGenerated;
|
return $this->terrainGenerated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param bool $value
|
||||||
|
*/
|
||||||
public function setGenerated(bool $value = true){
|
public function setGenerated(bool $value = true){
|
||||||
$this->terrainGenerated = $value;
|
$this->terrainGenerated = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Entity $entity
|
||||||
|
*/
|
||||||
public function addEntity(Entity $entity){
|
public function addEntity(Entity $entity){
|
||||||
$this->entities[$entity->getId()] = $entity;
|
$this->entities[$entity->getId()] = $entity;
|
||||||
if(!($entity instanceof Player) and $this->isInit){
|
if(!($entity instanceof Player) and $this->isInit){
|
||||||
@ -371,6 +592,9 @@ class Chunk{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Entity $entity
|
||||||
|
*/
|
||||||
public function removeEntity(Entity $entity){
|
public function removeEntity(Entity $entity){
|
||||||
unset($this->entities[$entity->getId()]);
|
unset($this->entities[$entity->getId()]);
|
||||||
if(!($entity instanceof Player) and $this->isInit){
|
if(!($entity instanceof Player) and $this->isInit){
|
||||||
@ -378,6 +602,9 @@ class Chunk{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Tile $tile
|
||||||
|
*/
|
||||||
public function addTile(Tile $tile){
|
public function addTile(Tile $tile){
|
||||||
$this->tiles[$tile->getId()] = $tile;
|
$this->tiles[$tile->getId()] = $tile;
|
||||||
if(isset($this->tileList[$index = (($tile->x & 0x0f) << 12) | (($tile->z & 0x0f) << 8) | ($tile->y & 0xff)]) and $this->tileList[$index] !== $tile){
|
if(isset($this->tileList[$index = (($tile->x & 0x0f) << 12) | (($tile->z & 0x0f) << 8) | ($tile->y & 0xff)]) and $this->tileList[$index] !== $tile){
|
||||||
@ -389,6 +616,9 @@ class Chunk{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Tile $tile
|
||||||
|
*/
|
||||||
public function removeTile(Tile $tile){
|
public function removeTile(Tile $tile){
|
||||||
unset($this->tiles[$tile->getId()]);
|
unset($this->tiles[$tile->getId()]);
|
||||||
unset($this->tileList[(($tile->x & 0x0f) << 12) | (($tile->z & 0x0f) << 8) | ($tile->y & 0xff)]);
|
unset($this->tileList[(($tile->x & 0x0f) << 12) | (($tile->z & 0x0f) << 8) | ($tile->y & 0xff)]);
|
||||||
@ -397,27 +627,60 @@ class Chunk{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array of entities currently using this chunk.
|
||||||
|
*
|
||||||
|
* @return Entity[]
|
||||||
|
*/
|
||||||
public function getEntities() : array{
|
public function getEntities() : array{
|
||||||
return $this->entities;
|
return $this->entities;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Tile[]
|
||||||
|
*/
|
||||||
public function getTiles() : array{
|
public function getTiles() : array{
|
||||||
return $this->tiles;
|
return $this->tiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the tile at the specified chunk block coordinates, or null if no tile exists.
|
||||||
|
*
|
||||||
|
* @param int $x 0-15
|
||||||
|
* @param int $y
|
||||||
|
* @param int $z 0-15
|
||||||
|
*
|
||||||
|
* @return Tile|null
|
||||||
|
*/
|
||||||
public function getTile(int $x, int $y, int $z){
|
public function getTile(int $x, int $y, int $z){
|
||||||
$index = ($x << 12) | ($z << 8) | $y;
|
$index = ($x << 12) | ($z << 8) | $y;
|
||||||
return $this->tileList[$index] ?? null;
|
return $this->tileList[$index] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
public function isLoaded() : bool{
|
public function isLoaded() : bool{
|
||||||
return $this->getProvider() === null ? false : $this->getProvider()->isChunkLoaded($this->getX(), $this->getZ());
|
return $this->getProvider() === null ? false : $this->getProvider()->isChunkLoaded($this->getX(), $this->getZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param bool $generate
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
public function load(bool $generate = true) : bool{
|
public function load(bool $generate = true) : bool{
|
||||||
return $this->getProvider() === null ? false : $this->getProvider()->getChunk($this->getX(), $this->getZ(), true) instanceof Chunk;
|
return $this->getProvider() === null ? false : $this->getProvider()->getChunk($this->getX(), $this->getZ(), true) instanceof Chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unloads the chunk, closing entities and tiles.
|
||||||
|
*
|
||||||
|
* @param bool $save
|
||||||
|
* @param bool $safe Whether to check if there are still players using this chunk
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
public function unload(bool $save = true, bool $safe = true) : bool{
|
public function unload(bool $save = true, bool $safe = true) : bool{
|
||||||
$level = $this->getProvider();
|
$level = $this->getProvider();
|
||||||
if($level === null){
|
if($level === null){
|
||||||
@ -447,6 +710,10 @@ class Chunk{
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserializes tiles and entities from NBT
|
||||||
|
* TODO: remove this
|
||||||
|
*/
|
||||||
public function initChunk(){
|
public function initChunk(){
|
||||||
if($this->getProvider() instanceof LevelProvider and !$this->isInit){
|
if($this->getProvider() instanceof LevelProvider and !$this->isInit){
|
||||||
$changed = false;
|
$changed = false;
|
||||||
@ -506,26 +773,49 @@ class Chunk{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function getBiomeIdArray() : string{
|
public function getBiomeIdArray() : string{
|
||||||
return $this->biomeIds;
|
return $this->biomeIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int[]
|
||||||
|
*/
|
||||||
public function getHeightMapArray() : array{
|
public function getHeightMapArray() : array{
|
||||||
return $this->heightMap;
|
return $this->heightMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int[]
|
||||||
|
*/
|
||||||
public function getBlockExtraDataArray() : array{
|
public function getBlockExtraDataArray() : array{
|
||||||
return $this->extraData;
|
return $this->extraData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
public function hasChanged() : bool{
|
public function hasChanged() : bool{
|
||||||
return $this->hasChanged;
|
return $this->hasChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param bool $value
|
||||||
|
*/
|
||||||
public function setChanged(bool $value = true){
|
public function setChanged(bool $value = true){
|
||||||
$this->hasChanged = $value;
|
$this->hasChanged = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the subchunk at the specified subchunk Y coordinate, or an empty, unmodifiable stub if it does not exist or the coordinate is out of range.
|
||||||
|
*
|
||||||
|
* @param int $y
|
||||||
|
* @param bool $generateNew Whether to create a new, modifiable subchunk if there is not one in place
|
||||||
|
*
|
||||||
|
* @return SubChunk|EmptySubChunk
|
||||||
|
*/
|
||||||
public function getSubChunk(int $y, bool $generateNew = false) : SubChunk{
|
public function getSubChunk(int $y, bool $generateNew = false) : SubChunk{
|
||||||
if($y < 0 or $y >= $this->height){
|
if($y < 0 or $y >= $this->height){
|
||||||
return $this->emptySubChunk;
|
return $this->emptySubChunk;
|
||||||
@ -536,6 +826,14 @@ class Chunk{
|
|||||||
return $this->subChunks[$y];
|
return $this->subChunks[$y];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a subchunk in the chunk index
|
||||||
|
* @param int $y
|
||||||
|
* @param SubChunk|null $subChunk
|
||||||
|
* @param bool $allowEmpty Whether to check if the chunk is empty, and if so replace it with an empty stub
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
public function setSubChunk(int $y, SubChunk $subChunk = null, bool $allowEmpty = false) : bool{
|
public function setSubChunk(int $y, SubChunk $subChunk = null, bool $allowEmpty = false) : bool{
|
||||||
if($y < 0 or $y >= $this->height){
|
if($y < 0 or $y >= $this->height){
|
||||||
return false;
|
return false;
|
||||||
@ -549,10 +847,18 @@ class Chunk{
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return SubChunk[]
|
||||||
|
*/
|
||||||
public function getSubChunks() : array{
|
public function getSubChunks() : array{
|
||||||
return $this->subChunks;
|
return $this->subChunks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Y coordinate of the highest non-empty subchunk in this chunk.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
public function getHighestSubChunkIndex() : int{
|
public function getHighestSubChunkIndex() : int{
|
||||||
for($y = count($this->subChunks) - 1; $y >= 0; --$y){
|
for($y = count($this->subChunks) - 1; $y >= 0; --$y){
|
||||||
if($this->subChunks[$y] === null or $this->subChunks[$y] instanceof EmptySubChunk){
|
if($this->subChunks[$y] === null or $this->subChunks[$y] instanceof EmptySubChunk){
|
||||||
@ -565,10 +871,18 @@ class Chunk{
|
|||||||
return $y;
|
return $y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the count of subchunks that need sending to players
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
public function getSubChunkSendCount() : int{
|
public function getSubChunkSendCount() : int{
|
||||||
return $this->getHighestSubChunkIndex() + 1;
|
return $this->getHighestSubChunkIndex() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disposes of empty subchunks
|
||||||
|
*/
|
||||||
public function pruneEmptySubChunks(){
|
public function pruneEmptySubChunks(){
|
||||||
foreach($this->subChunks as $y => $subChunk){
|
foreach($this->subChunks as $y => $subChunk){
|
||||||
if($y < 0 or $y >= $this->height){
|
if($y < 0 or $y >= $this->height){
|
||||||
@ -585,6 +899,11 @@ class Chunk{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes the chunk for sending to players
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function networkSerialize() : string{
|
public function networkSerialize() : string{
|
||||||
$result = "";
|
$result = "";
|
||||||
$subChunkCount = $this->getSubChunkSendCount();
|
$subChunkCount = $this->getSubChunkSendCount();
|
||||||
@ -620,6 +939,12 @@ class Chunk{
|
|||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fast-serializes the chunk for passing between threads
|
||||||
|
* TODO: tiles and entities
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function fastSerialize() : string{
|
public function fastSerialize() : string{
|
||||||
$stream = new BinaryStream();
|
$stream = new BinaryStream();
|
||||||
$stream->putInt($this->x);
|
$stream->putInt($this->x);
|
||||||
@ -638,10 +963,17 @@ class Chunk{
|
|||||||
$stream->put(pack("C*", ...$this->heightMap) .
|
$stream->put(pack("C*", ...$this->heightMap) .
|
||||||
$this->biomeIds .
|
$this->biomeIds .
|
||||||
chr(($this->lightPopulated ? 1 << 2 : 0) | ($this->terrainPopulated ? 1 << 1 : 0) | ($this->terrainGenerated ? 1 : 0)));
|
chr(($this->lightPopulated ? 1 << 2 : 0) | ($this->terrainPopulated ? 1 << 1 : 0) | ($this->terrainGenerated ? 1 : 0)));
|
||||||
//TODO: tiles and entities
|
|
||||||
return $stream->getBuffer();
|
return $stream->getBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserializes a fast-serialized chunk
|
||||||
|
*
|
||||||
|
* @param string $data
|
||||||
|
* @param LevelProvider|null $provider
|
||||||
|
*
|
||||||
|
* @return Chunk
|
||||||
|
*/
|
||||||
public static function fastDeserialize(string $data, LevelProvider $provider = null){
|
public static function fastDeserialize(string $data, LevelProvider $provider = null){
|
||||||
$stream = new BinaryStream();
|
$stream = new BinaryStream();
|
||||||
$stream->setBuffer($data);
|
$stream->setBuffer($data);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user