Added biomeIds and biomeColors to Anvil format

This commit is contained in:
Shoghi Cervantes 2014-06-13 20:04:07 +02:00
parent 20759dcf07
commit cbaeec54ff
6 changed files with 153 additions and 14 deletions

View File

@ -1055,6 +1055,46 @@ class Level implements ChunkManager, Metadatable{
$this->getChunkAt($x >> 4, $z >> 4)->setBlockLight($x & 0x0f, $y & 0x7f, $z & 0x0f, $level & 0x0f);
}
/**
* @param int $x
* @param int $z
*
* @return int
*/
public function getBiomeId($x, $z){
return $this->getChunkAt($x >> 4, $z >> 4)->getBiomeId($x & 0x0f, $z & 0x0f);
}
/**
* @param int $x
* @param int $z
*
* @return int[]
*/
public function getBiomeColor($x, $z){
return $this->getChunkAt($x >> 4, $z >> 4)->getBiomeColor($x & 0x0f, $z & 0x0f);
}
/**
* @param int $x
* @param int $z
* @param int $biomeId
*/
public function setBiomeId($x, $z, $biomeId){
$this->getChunkAt($x >> 4, $z >> 4)->setBiomeId($x & 0x0f, $z & 0x0f, $biomeId);
}
/**
* @param int $x
* @param int $z
* @param int $R
* @param int $G
* @param int $B
*/
public function setBiomeColor($x, $z, $R, $G, $B){
$this->getChunkAt($x >> 4, $z >> 4)->setBiomeColor($x & 0x0f, $z & 0x0f, $R, $G, $B);
}
/**
* Gets the Chunk object
*
@ -1189,9 +1229,13 @@ class Level implements ChunkManager, Metadatable{
$orderedLight = "";
$flag = chr($Yndex);
$chunk = $this->getChunkAt($X, $Z, true);
$biomeIds = $chunk->getBiomeIdArray();
$biomeColors = implode(array_map("pocketmine\\utils\\Binary::writeInt", $chunk->getBiomeColorArray()));
/** @var \pocketmine\level\format\ChunkSection[] $sections */
$sections = [];
foreach($this->getChunkAt($X, $Z, true)->getSections() as $section){
foreach($chunk->getSections() as $section){
$sections[$section->getY()] = $section;
}
@ -1206,15 +1250,7 @@ class Level implements ChunkManager, Metadatable{
}
}
$biomeIDs = str_repeat("\x04", 256);
if($X % 5 === 0 and $Z % 5 === 0){
$ppm = base64_decode("mpqahISEbW1tZmZmZmZmXl5eXl5eXl5eXl5eXl5eXl5eZmZmZmZmbW1thISEmpqafX19bW1tbW1tS5ubS5qdfbXTSpSbS5ubTJ6cSpWZfbXTSpWZTJ6cbW1tbW1tfX19bW1tbW1tfbXSfbbVSI+dfdL/fbrafbfVSZKefbjYfbjYfbXSSpWZfbTRbW1tbW1tZmZmTKGdSpSbfbrbfbzdfdL/SI+dfbnZfdL/fdL/SZKeSpKYSYyWfbbVS5iaZmZmXl5eS6CiSZmmfdL/fbzeSZCcSpSbfbfVSJKifdL/SpegfbXTfbfWfbXTS5ubXl5eXl5efdL/fdL/fdL/fbrbfbbVSpKYfbTRSpecSpieSZCcfbjYSZCcSpegS52iXl5eXl5eSpegfbnZSZSfSZGafbbVxsYAxsYAxsYAxsYAfbjYfdL/SZikfdL/fdL/Xl5eXl5eSpSbfbjYSpegS5qdfbTRxsYA1tYA1tYAxsYASpegfdL/SZahfbfXSpegXl5eXl5efbfWfdL/AAAAAAAAAAAAxsYA1tYAAAAAxsYAS56gSp2lAAAAfbfVS5iaXl5eXl5efbXSSZWjAAAAfbnZfbjYAAAAxsYAAAAAAAAASZOgAAAAAAAAfbfWSpWZXl5eXl5eTJ6cS56gAAAAAAAAAAAASpegS5ubAAAAfdL/AAAAfdL/AAAASZOgfbfVXl5eXl5eTKKfSp2lAAAAfdL/fdL/Sp2lS56gAAAAfdL/SZamSpyjAAAAfdL/fdL/Xl5eZmZmS6CifdL/AAAASZamSZmmfdL/SZqoAAAAfdL/SJOlfdL/AAAAfbnZSpegZmZmbW1tbW1tfdL/AAAAfbXSSpegfdL/fdL/AAAAfbfXfbrbfdL/AAAAfbbVbW1tbW1tfX19bW1tbW1tAAAAfbTRS5qdSp2lfdL/AAAAS5ubSpSbfbfVAAAAbW1tbW1tfX19mpqahISEbW1tZmZmZmZmXl5eXl5eXl5eXl5eXl5eXl5eZmZmZmZmbW1thISEmpqa");
$grassColor = "\x01" . implode("\x01", str_split($ppm, 3));
}else{
$grassColor = str_repeat("\x01\x85\xb2\x4a", 256);
}
$ordered = zlib_encode(Binary::writeLInt($X) . Binary::writeLInt($Z) . $orderedIds . $orderedData . $orderedSkyLight . $orderedLight . $biomeIDs . $grassColor, ZLIB_ENCODING_DEFLATE, 8);
$ordered = zlib_encode(Binary::writeLInt($X) . Binary::writeLInt($Z) . $orderedIds . $orderedData . $orderedSkyLight . $orderedLight . $biomeIds . $biomeColors, ZLIB_ENCODING_DEFLATE, 8);
if(ADVANCED_CACHE == true and $Yndex === 0xff){
Cache::add($identifier, $ordered, 60);

View File

@ -140,6 +140,38 @@ interface Chunk{
*/
public function getHighestBlockAt($x, $z);
/**
* @param int $x 0-15
* @param int $z 0-15
*
* @return int 0-255
*/
public function getBiomeId($x, $z);
/**
* @param int $x 0-15
* @param int $z 0-15
* @param int $biomeId 0-255
*/
public function setBiomeId($x, $z, $biomeId);
/**
* @param int $x
* @param int $z
*
* @return int[] RGB bytes
*/
public function getBiomeColor($x, $z);
/**
* @param int $x 0-15
* @param int $z 0-15
* @param int $R 0-255
* @param int $G 0-255
* @param int $B 0-255
*/
public function setBiomeColor($x, $z, $R, $G, $B);
/**
* Thread-safe read-only chunk
*
@ -232,4 +264,14 @@ interface Chunk{
*/
public function getSections();
/**
* @return string[]
*/
public function getBiomeIdArray();
/**
* @return int[]
*/
public function getBiomeColorArray();
}

View File

@ -52,8 +52,8 @@ class SimpleChunk{
$this->z = $chunkZ;
$this->flags = $flags;
for($y = 0; $y < self::$HEIGHT; ++$y){
$this->ids[$y] = isset($ids[$y]) ? $ids[$y] : str_repeat("\x00", 4096);
$this->meta[$y] = isset($meta[$y]) ? $meta[$y] : str_repeat("\x00", 2048);
$this->ids[$y] = (isset($ids[$y]) and strlen($ids[$y]) === 4096) ? $ids[$y] : str_repeat("\x00", 4096);
$this->meta[$y] = (isset($meta[$y]) and strlen($meta[$y]) === 2048) ? $meta[$y] : str_repeat("\x00", 2048);
}
}

View File

@ -26,8 +26,12 @@ use pocketmine\level\format\generic\EmptyChunkSection;
use pocketmine\level\format\LevelProvider;
use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\Byte;
use pocketmine\nbt\tag\ByteArray;
use pocketmine\nbt\tag\Compound;
use pocketmine\nbt\tag\Enum;
use pocketmine\nbt\tag\Int;
use pocketmine\nbt\tag\IntArray;
use pocketmine\utils\Binary;
class Chunk extends BaseChunk{
@ -65,6 +69,14 @@ class Chunk extends BaseChunk{
$this->nbt->Sections->setTagType(NBT::TAG_Compound);
}
if(!isset($this->nbt->Biomes) or !($this->nbt->Biomes instanceof ByteArray)){
$this->nbt->Biomes = new ByteArray("Biomes", str_repeat("\x01", 256));
}
if(!isset($this->nbt->BiomeColors) or !($this->nbt->BiomeColors instanceof IntArray)){
$this->nbt->BiomeColors = new IntArray("BiomeColors", array_fill(0, 156, Binary::readInt("\x01\x85\xb2\x4a")));
}
$sections = [];
foreach($this->nbt->Sections as $section){
if($section instanceof Compound){
@ -80,7 +92,7 @@ class Chunk extends BaseChunk{
}
}
parent::__construct($level, $this->nbt["xPos"], $this->nbt["zPos"], $sections, $this->nbt->Entities->getValue(), $this->nbt->TileEntities->getValue());
parent::__construct($level, $this->nbt["xPos"], $this->nbt["zPos"], $sections, $this->nbt->Biomes->getValue(), $this->nbt->BiomeColors->getValue(), $this->nbt->Entities->getValue(), $this->nbt->TileEntities->getValue());
}
/**

View File

@ -194,6 +194,9 @@ class RegionLoader{
]);
}
$nbt->Biomes = new ByteArray("Biomes", $chunk->getBiomeIdArray());
$nbt->BiomeColors = new IntArray("BiomeColors", $chunk->getBiomeColorArray());
$entities = [];
foreach($chunk->getEntities() as $entity){

View File

@ -32,6 +32,7 @@ use pocketmine\tile\Chest;
use pocketmine\tile\Furnace;
use pocketmine\tile\Sign;
use pocketmine\tile\Tile;
use pocketmine\utils\Binary;
abstract class BaseChunk implements Chunk{
@ -44,6 +45,12 @@ abstract class BaseChunk implements Chunk{
/** @var Tile[] */
protected $tiles = [];
/** @var string */
protected $biomeIds;
/** @var int[256] */
protected $biomeColors;
/** @var \WeakRef<LevelProvider> */
protected $level;
@ -55,12 +62,14 @@ abstract class BaseChunk implements Chunk{
* @param int $x
* @param int $z
* @param ChunkSection[] $sections
* @param string $biomeIds
* @param int[] $biomeColors
* @param Compound[] $entities
* @param Compound[] $tiles
*
* @throws \Exception
*/
protected function __construct(LevelProvider $level, $x, $z, array $sections, array $entities = [], array $tiles = []){
protected function __construct(LevelProvider $level, $x, $z, array $sections, $biomeIds = null, array $biomeColors = [], array $entities = [], array $tiles = []){
$this->level = new \WeakRef($level);
$this->x = (int) $x;
$this->z = (int) $z;
@ -77,6 +86,18 @@ abstract class BaseChunk implements Chunk{
}
}
if(strlen($biomeIds) === 256){
$this->biomeIds = $biomeIds;
}else{
$this->biomeIds = str_repeat("\x01", 256);
}
if(count($biomeColors) === 256){
$this->biomeColors = $biomeColors;
}else{
$this->biomeColors = array_fill(0, 256, Binary::readInt("\x01\x85\xb2\x4a"));
}
foreach($entities as $nbt){
if($nbt instanceof Compound){
if(!isset($nbt->id)){
@ -171,6 +192,23 @@ abstract class BaseChunk implements Chunk{
$this->sections[$y >> 4]->getBlockSkyLight($x, $y & 0x0f, $z, $data);
}
public function getBiomeId($x, $z){
return ord($this->biomeIds{($z << 4) + $x});
}
public function setBiomeId($x, $z, $biomeId){
$this->biomeIds{($z << 4) + $x} = chr($biomeId);
}
public function getBiomeColor($x, $z){
$color = $this->biomeColors[($z << 4) + $x] & 0xFFFFFF;
return [$color >> 16, ($color >> 8) & 0xFF, $color & 0xFF];
}
public function setBiomeColor($x, $z, $R, $G, $B){
$this->biomeColors = 0xFF000000 | (($R & 0xFF) << 16) | (($G & 0xFF) << 8) | ($B & 0xFF);
}
public function getHighestBlockAt($x, $z){
for($Y = self::SECTION_COUNT; $Y >= 0; --$Y){
if(!$this->isSectionEmpty($Y)){
@ -255,4 +293,12 @@ abstract class BaseChunk implements Chunk{
return $this->sections;
}
public function getBiomeIdArray(){
return $this->biomeIds;
}
public function getBiomeColorArray(){
return $this->biomeColors;
}
}