PageRenderTime 50ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/src/pocketmine/level/format/generic/BaseChunk.php

https://gitlab.com/kennethgomad01/genisys
PHP | 267 lines | 189 code | 44 blank | 34 comment | 15 complexity | fa67c7b5e4237bad8035a2a525ef45dc MD5 | raw file
  1. <?php
  2. /*
  3. *
  4. * ____ _ _ __ __ _ __ __ ____
  5. * | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
  6. * | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
  7. * | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
  8. * |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
  9. *
  10. * This program is free software: you can redistribute it and/or modify
  11. * it under the terms of the GNU Lesser General Public License as published by
  12. * the Free Software Foundation, either version 3 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * @author PocketMine Team
  16. * @link http://www.pocketmine.net/
  17. *
  18. *
  19. */
  20. namespace pocketmine\level\format\generic;
  21. use pocketmine\level\format\Chunk;
  22. use pocketmine\level\format\ChunkSection;
  23. use pocketmine\level\format\LevelProvider;
  24. use pocketmine\nbt\tag\CompoundTag;
  25. use pocketmine\utils\Binary;
  26. use pocketmine\utils\ChunkException;
  27. abstract class BaseChunk extends BaseFullChunk implements Chunk{
  28. /** @var ChunkSection[] */
  29. protected $sections = [];
  30. /**
  31. * @param LevelProvider $provider
  32. * @param int $x
  33. * @param int $z
  34. * @param ChunkSection[] $sections
  35. * @param int[] $biomeColors
  36. * @param int[] $heightMap
  37. * @param CompoundTag[] $entities
  38. * @param CompoundTag[] $tiles
  39. *
  40. * @throws ChunkException
  41. */
  42. protected function __construct($provider, $x, $z, array $sections, array $biomeColors = [], array $heightMap = [], array $entities = [], array $tiles = []){
  43. $this->provider = $provider;
  44. $this->x = (int) $x;
  45. $this->z = (int) $z;
  46. foreach($sections as $Y => $section){
  47. if($section instanceof ChunkSection){
  48. $this->sections[$Y] = $section;
  49. }else{
  50. throw new ChunkException("Received invalid ChunkSection instance");
  51. }
  52. if($Y >= self::SECTION_COUNT){
  53. throw new ChunkException("Invalid amount of chunks");
  54. }
  55. }
  56. if(count($biomeColors) === 256){
  57. $this->biomeColors = $biomeColors;
  58. }else{
  59. $this->biomeColors = array_fill(0, 256, Binary::readInt("\xff\x00\x00\x00"));
  60. }
  61. if(count($heightMap) === 256){
  62. $this->heightMap = $heightMap;
  63. }else{
  64. $this->heightMap = array_fill(0, 256, 127);
  65. }
  66. $this->NBTtiles = $tiles;
  67. $this->NBTentities = $entities;
  68. }
  69. public function getBlock($x, $y, $z, &$blockId, &$meta = null){
  70. $full = $this->sections[$y >> 4]->getFullBlock($x, $y & 0x0f, $z);
  71. $blockId = $full >> 4;
  72. $meta = $full & 0x0f;
  73. }
  74. public function getFullBlock($x, $y, $z){
  75. return isset($this->sections[$y >> 4]) ? $this->sections[$y >> 4]->getFullBlock($x, $y & 0x0f, $z) : 0;
  76. }
  77. public function setBlock($x, $y, $z, $blockId = null, $meta = null){
  78. try{
  79. $this->hasChanged = true;
  80. return $this->sections[$y >> 4]->setBlock($x, $y & 0x0f, $z, $blockId & 0xff, $meta & 0x0f);
  81. }catch(ChunkException $e){
  82. $level = $this->getProvider();
  83. $this->setInternalSection($Y = $y >> 4, $level::createChunkSection($Y));
  84. return $this->sections[$y >> 4]->setBlock($x, $y & 0x0f, $z, $blockId & 0xff, $meta & 0x0f);
  85. }
  86. }
  87. public function getBlockId($x, $y, $z){
  88. if(isset($this->sections[$y >> 4])) return $this->sections[$y >> 4]->getBlockId($x, $y & 0x0f, $z);
  89. else return 0;
  90. }
  91. public function setBlockId($x, $y, $z, $id){
  92. try{
  93. $this->sections[$y >> 4]->setBlockId($x, $y & 0x0f, $z, $id);
  94. $this->hasChanged = true;
  95. }catch(ChunkException $e){
  96. $level = $this->getProvider();
  97. $this->setInternalSection($Y = $y >> 4, $level::createChunkSection($Y));
  98. $this->setBlockId($x, $y, $z, $id);
  99. }
  100. }
  101. public function getBlockData($x, $y, $z){
  102. return $this->sections[$y >> 4]->getBlockData($x, $y & 0x0f, $z);
  103. }
  104. public function setBlockData($x, $y, $z, $data){
  105. try{
  106. $this->sections[$y >> 4]->setBlockData($x, $y & 0x0f, $z, $data);
  107. $this->hasChanged = true;
  108. }catch(ChunkException $e){
  109. $level = $this->getProvider();
  110. $this->setInternalSection($Y = $y >> 4, $level::createChunkSection($Y));
  111. $this->setBlockData($x, $y, $z, $data);
  112. }
  113. }
  114. public function getBlockSkyLight($x, $y, $z){
  115. return $this->sections[$y >> 4]->getBlockSkyLight($x, $y & 0x0f, $z);
  116. }
  117. public function setBlockSkyLight($x, $y, $z, $data){
  118. try{
  119. $this->sections[$y >> 4]->setBlockSkyLight($x, $y & 0x0f, $z, $data);
  120. $this->hasChanged = true;
  121. }catch(ChunkException $e){
  122. $level = $this->getProvider();
  123. $this->setInternalSection($Y = $y >> 4, $level::createChunkSection($Y));
  124. $this->setBlockSkyLight($x, $y, $z, $data);
  125. }
  126. }
  127. public function getBlockLight($x, $y, $z){
  128. return $this->sections[$y >> 4]->getBlockLight($x, $y & 0x0f, $z);
  129. }
  130. public function setBlockLight($x, $y, $z, $data){
  131. try{
  132. $this->sections[$y >> 4]->setBlockLight($x, $y & 0x0f, $z, $data);
  133. $this->hasChanged = true;
  134. }catch(ChunkException $e){
  135. $level = $this->getProvider();
  136. $this->setInternalSection($Y = $y >> 4, $level::createChunkSection($Y));
  137. $this->setBlockLight($x, $y, $z, $data);
  138. }
  139. }
  140. public function getBlockIdColumn($x, $z){
  141. $column = "";
  142. for($y = 0; $y < Chunk::SECTION_COUNT; ++$y){
  143. $column .= $this->sections[$y]->getBlockIdColumn($x, $z);
  144. }
  145. return $column;
  146. }
  147. public function getBlockDataColumn($x, $z){
  148. $column = "";
  149. for($y = 0; $y < Chunk::SECTION_COUNT; ++$y){
  150. $column .= $this->sections[$y]->getBlockDataColumn($x, $z);
  151. }
  152. return $column;
  153. }
  154. public function getBlockSkyLightColumn($x, $z){
  155. $column = "";
  156. for($y = 0; $y < Chunk::SECTION_COUNT; ++$y){
  157. $column .= $this->sections[$y]->getBlockSkyLightColumn($x, $z);
  158. }
  159. return $column;
  160. }
  161. public function getBlockLightColumn($x, $z){
  162. $column = "";
  163. for($y = 0; $y < Chunk::SECTION_COUNT; ++$y){
  164. $column .= $this->sections[$y]->getBlockLightColumn($x, $z);
  165. }
  166. return $column;
  167. }
  168. public function isSectionEmpty($fY){
  169. return $this->sections[(int) $fY] instanceof EmptyChunkSection;
  170. }
  171. public function getSection($fY){
  172. return $this->sections[(int) $fY];
  173. }
  174. public function setSection($fY, ChunkSection $section){
  175. if(substr_count($section->getIdArray(), "\x00") === 4096 and substr_count($section->getDataArray(), "\x00") === 2048){
  176. $this->sections[(int) $fY] = new EmptyChunkSection($fY);
  177. }else{
  178. $this->sections[(int) $fY] = $section;
  179. }
  180. $this->hasChanged = true;
  181. }
  182. private function setInternalSection($fY, ChunkSection $section){
  183. $this->sections[(int) $fY] = $section;
  184. $this->hasChanged = true;
  185. }
  186. public function load($generate = true){
  187. return $this->getProvider() === null ? false : $this->getProvider()->getChunk($this->getX(), $this->getZ(), true) instanceof Chunk;
  188. }
  189. public function getBlockIdArray(){
  190. $blocks = "";
  191. for($y = 0; $y < Chunk::SECTION_COUNT; ++$y){
  192. $blocks .= $this->sections[$y]->getIdArray();
  193. }
  194. return $blocks;
  195. }
  196. public function getBlockDataArray(){
  197. $data = "";
  198. for($y = 0; $y < Chunk::SECTION_COUNT; ++$y){
  199. $data .= $this->sections[$y]->getDataArray();
  200. }
  201. return $data;
  202. }
  203. public function getBlockSkyLightArray(){
  204. $skyLight = "";
  205. for($y = 0; $y < Chunk::SECTION_COUNT; ++$y){
  206. $skyLight .= $this->sections[$y]->getSkyLightArray();
  207. }
  208. return $skyLight;
  209. }
  210. public function getBlockLightArray(){
  211. $blockLight = "";
  212. for($y = 0; $y < Chunk::SECTION_COUNT; ++$y){
  213. $blockLight .= $this->sections[$y]->getLightArray();
  214. }
  215. return $blockLight;
  216. }
  217. /**
  218. * @return ChunkSection[]
  219. */
  220. public function getSections(){
  221. return $this->sections;
  222. }
  223. }