PocketMine-MP  1.4 - API 1.10.0
 All Classes Namespaces Functions Variables Pages
BaseFullChunk.php
1 <?php
2 
3 /*
4  *
5  * ____ _ _ __ __ _ __ __ ____
6  * | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
7  * | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
8  * | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
9  * |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
10  *
11  * This program is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License as published by
13  * the Free Software Foundation, either version 3 of the License, or
14  * (at your option) any later version.
15  *
16  * @author PocketMine Team
17  * @link http://www.pocketmine.net/
18  *
19  *
20 */
21 
22 namespace pocketmine\level\format\generic;
23 
31 
32 abstract class BaseFullChunk implements FullChunk{
33 
35  protected $entities = [];
36 
38  protected $tiles = [];
39 
41  protected $tileList = [];
42 
44  protected $biomeIds;
45 
47  protected $biomeColors;
48 
49  protected $blocks;
50 
51  protected $data;
52 
53  protected $skyLight;
54 
55  protected $blockLight;
56 
57  protected $heightMap;
58 
59  protected $NBTtiles;
60 
61  protected $NBTentities;
62 
64  protected $provider;
65 
66  protected $x;
67  protected $z;
68 
69  protected $hasChanged = false;
70 
85  protected function __construct($provider, $x, $z, $blocks, $data, $skyLight, $blockLight, $biomeIds = null, array $biomeColors = [], array $heightMap = [], array $entities = [], array $tiles = []){
86  $this->provider = $provider;
87  $this->x = (int) $x;
88  $this->z = (int) $z;
89 
90  $this->blocks = $blocks;
91  $this->data = $data;
92  $this->skyLight = $skyLight;
93  $this->blockLight = $blockLight;
94 
95  if(strlen($biomeIds) === 256){
96  $this->biomeIds = $biomeIds;
97  }else{
98  $this->biomeIds = str_repeat("\x01", 256);
99  }
100 
101  if(count($biomeColors) === 256){
102  $this->biomeColors = $biomeColors;
103  }else{
104  $this->biomeColors = array_fill(0, 256, Binary::readInt("\x00\x85\xb2\x4a"));
105  }
106 
107  if(count($heightMap) === 256){
108  $this->heightMap = $heightMap;
109  }else{
110  $this->heightMap = array_fill(0, 256, 127);
111  }
112 
113  $this->NBTtiles = $tiles;
114  $this->NBTentities = $entities;
115  }
116 
117  public function initChunk(){
118  if($this->getProvider() instanceof LevelProvider and $this->NBTentities !== null){
119  $this->getProvider()->getLevel()->timings->syncChunkLoadEntitiesTimer->startTiming();
120  foreach($this->NBTentities as $nbt){
121  if($nbt instanceof Compound){
122  if(!isset($nbt->id)){
123  $this->setChanged();
124  continue;
125  }
126 
127  if(($nbt["Pos"][0] >> 4) !== $this->x or ($nbt["Pos"][2] >> 4) !== $this->z){
128  $this->setChanged();
129  continue; //Fixes entities allocated in wrong chunks.
130  }
131 
132  if(($entity = Entity::createEntity($nbt["id"], $this, $nbt)) instanceof Entity){
133  $entity->spawnToAll();
134  }else{
135  $this->setChanged();
136  continue;
137  }
138  }
139  }
140  $this->getProvider()->getLevel()->timings->syncChunkLoadEntitiesTimer->stopTiming();
141 
142  $this->getProvider()->getLevel()->timings->syncChunkLoadTileEntitiesTimer->startTiming();
143  foreach($this->NBTtiles as $nbt){
144  if($nbt instanceof Compound){
145  if(!isset($nbt->id)){
146  $this->setChanged();
147  continue;
148  }
149 
150  if(($nbt["x"] >> 4) !== $this->x or ($nbt["z"] >> 4) !== $this->z){
151  $this->setChanged();
152  continue; //Fixes tiles allocated in wrong chunks.
153  }
154 
155  if(Tile::createTile($nbt["id"], $this, $nbt) === null){
156  $this->setChanged();
157  continue;
158  }
159  }
160  }
161 
162  $this->getProvider()->getLevel()->timings->syncChunkLoadTileEntitiesTimer->stopTiming();
163 
164  $this->NBTentities = null;
165  $this->NBTtiles = null;
166  $this->hasChanged = false;
167  }
168  }
169 
170  public function getX(){
171  return $this->x;
172  }
173 
174  public function getZ(){
175  return $this->z;
176  }
177 
178  public function setX($x){
179  $this->x = $x;
180  }
181 
182  public function setZ($z){
183  $this->z = $z;
184  }
185 
191  public function getLevel(){
192  return $this->getProvider();
193  }
194 
198  public function getProvider(){
199  return $this->provider;
200  }
201 
202  public function setProvider(LevelProvider $provider){
203  $this->provider = $provider;
204  }
205 
206  public function getBiomeId($x, $z){
207  return ord($this->biomeIds{($z << 4) + $x});
208  }
209 
210  public function setBiomeId($x, $z, $biomeId){
211  $this->hasChanged = true;
212  $this->biomeIds{($z << 4) + $x} = chr($biomeId);
213  }
214 
215  public function getBiomeColor($x, $z){
216  $color = $this->biomeColors[($z << 4) + $x] & 0xFFFFFF;
217 
218  return [$color >> 16, ($color >> 8) & 0xFF, $color & 0xFF];
219  }
220 
221  public function setBiomeColor($x, $z, $R, $G, $B){
222  $this->hasChanged = true;
223  $this->biomeColors[($z << 4) + $x] = 0 | (($R & 0xFF) << 16) | (($G & 0xFF) << 8) | ($B & 0xFF);
224  }
225 
226  public function getHeightMap($x, $z){
227  return $this->heightMap[($z << 4) + $x];
228  }
229 
230  public function setHeightMap($x, $z, $value){
231  $this->heightMap[($z << 4) + $x] = $value;
232  }
233 
234  public function getHighestBlockAt($x, $z){
235  $column = $this->getBlockIdColumn($x, $z);
236  for($y = 127; $y >= 0; --$y){
237  if($column{$y} !== "\x00"){
238  return $y;
239  }
240  }
241 
242  return 0;
243  }
244 
245  public function addEntity(Entity $entity){
246  $this->entities[$entity->getId()] = $entity;
247  $this->hasChanged = true;
248  }
249 
250  public function removeEntity(Entity $entity){
251  unset($this->entities[$entity->getId()]);
252  $this->hasChanged = true;
253  }
254 
255  public function addTile(Tile $tile){
256  $this->tiles[$tile->getId()] = $tile;
257  if(isset($this->tileList[$index = (($tile->z & 0x0f) << 12) | (($tile->x & 0x0f) << 8) | ($tile->y & 0xff)]) and $this->tileList[$index] !== $tile){
258  $this->tileList[$index]->close();
259  }
260  $this->tileList[$index] = $tile;
261  $this->hasChanged = true;
262  }
263 
264  public function removeTile(Tile $tile){
265  unset($this->tiles[$tile->getId()]);
266  unset($this->tileList[(($tile->z & 0x0f) << 12) | (($tile->x & 0x0f) << 8) | ($tile->y & 0xff)]);
267  $this->hasChanged = true;
268  }
269 
270  public function getEntities(){
271  return $this->entities;
272  }
273 
274  public function getTiles(){
275  return $this->tiles;
276  }
277 
278  public function getTile($x, $y, $z){
279  $index = ($z << 12) | ($x << 8) | $y;
280  return isset($this->tileList[$index]) ? $this->tileList[$index] : null;
281  }
282 
283  public function isLoaded(){
284  return $this->getProvider() === null ? false : $this->getProvider()->isChunkLoaded($this->getX(), $this->getZ());
285  }
286 
287  public function load($generate = true){
288  return $this->getProvider() === null ? false : $this->getProvider()->getChunk($this->getX(), $this->getZ(), true) instanceof FullChunk;
289  }
290 
291  public function unload($save = true, $safe = true){
292  $level = $this->getProvider();
293  if($level === null){
294  return true;
295  }
296  if($save === true and $this->hasChanged){
297  $level->saveChunk($this->getX(), $this->getZ());
298  }
299  if($safe === true){
300  foreach($this->getEntities() as $entity){
301  if($entity instanceof Player){
302  return false;
303  }
304  }
305  }
306 
307  foreach($this->getEntities() as $entity){
308  if($entity instanceof Player){
309  continue;
310  }
311  $entity->close();
312  }
313  foreach($this->getTiles() as $tile){
314  $tile->close();
315  }
316  $this->provider = null;
317  return true;
318  }
319 
320  public function getBlockIdArray(){
321  return $this->blocks;
322  }
323 
324  public function getBlockDataArray(){
325  return $this->data;
326  }
327 
328  public function getBlockSkyLightArray(){
329  return $this->skyLight;
330  }
331 
332  public function getBlockLightArray(){
333  return $this->blockLight;
334  }
335 
336  public function getBiomeIdArray(){
337  return $this->biomeIds;
338  }
339 
340  public function getBiomeColorArray(){
341  return $this->biomeColors;
342  }
343 
344  public function getHeightMapArray(){
345  return $this->heightMap;
346  }
347 
348  public function hasChanged(){
349  return $this->hasChanged;
350  }
351 
352  public function setChanged($changed = true){
353  $this->hasChanged = (bool) $changed;
354  }
355 
356 }
__construct($provider, $x, $z, $blocks, $data, $skyLight, $blockLight, $biomeIds=null, array $biomeColors=[], array $heightMap=[], array $entities=[], array $tiles=[])
static createEntity($type, FullChunk $chunk, Compound $nbt,...$args)
Definition: Entity.php:239
static createTile($type, FullChunk $chunk, Compound $nbt,...$args)
Definition: Tile.php:74