Removed entanglement between chunks and providers. WARNING: BREAKING API CHANGES.

- All entity and tile constructors now require a \pocketmine\level\Level instead of a \pocketmine\level\format\Chunk.
- Chunk->getProvider() and Chunk->setProvider() have been removed.
- Chunk::__construct() has had the $provider parameter removed.
- Chunk->unload() has had the unused $save parameter removed.
- ChunkEvents now take a Level parameter instead of going through the Chunk

API bump to 3.0.0-ALPHA4
This commit is contained in:
Dylan K. Taylor 2017-02-21 17:03:45 +00:00
parent 0a8826b21f
commit c21197ef17
37 changed files with 123 additions and 170 deletions

View File

@ -1726,7 +1726,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$this->server->saveOfflinePlayerData($this->username, $nbt, true); $this->server->saveOfflinePlayerData($this->username, $nbt, true);
} }
parent::__construct($this->level->getChunk($nbt["Pos"][0] >> 4, $nbt["Pos"][2] >> 4, true), $nbt); parent::__construct($this->level, $nbt);
$this->loggedIn = true; $this->loggedIn = true;
$this->server->addOnlinePlayer($this); $this->server->addOnlinePlayer($this);
@ -2115,7 +2115,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
]); ]);
$f = 1.5; $f = 1.5;
$snowball = Entity::createEntity("Snowball", $this->chunk, $nbt, $this); $snowball = Entity::createEntity("Snowball", $this->getLevel(), $nbt, $this);
$snowball->setMotion($snowball->getMotion()->multiply($f)); $snowball->setMotion($snowball->getMotion()->multiply($f));
if($this->isSurvival()){ if($this->isSurvival()){
$item->setCount($item->getCount() - 1); $item->setCount($item->getCount() - 1);
@ -2200,7 +2200,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$diff = ($this->server->getTick() - $this->startAction); $diff = ($this->server->getTick() - $this->startAction);
$p = $diff / 20; $p = $diff / 20;
$f = min((($p ** 2) + $p * 2) / 3, 1) * 2; $f = min((($p ** 2) + $p * 2) / 3, 1) * 2;
$ev = new EntityShootBowEvent($this, $bow, Entity::createEntity("Arrow", $this->chunk, $nbt, $this, $f == 2 ? true : false), $f); $ev = new EntityShootBowEvent($this, $bow, Entity::createEntity("Arrow", $this->getLevel(), $nbt, $this, $f == 2 ? true : false), $f);
if($f < 0.1 or $diff < 5){ if($f < 0.1 or $diff < 5){
$ev->setCancelled(); $ev->setCancelled();

View File

@ -74,7 +74,7 @@ namespace pocketmine {
use raklib\RakLib; use raklib\RakLib;
const VERSION = "1.6.2dev"; const VERSION = "1.6.2dev";
const API_VERSION = "3.0.0-ALPHA3"; const API_VERSION = "3.0.0-ALPHA4";
const CODENAME = "Unleashed"; const CODENAME = "Unleashed";
/* /*

View File

@ -88,7 +88,7 @@ class BurningFurnace extends Solid{
} }
} }
Tile::createTile("Furnace", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt); Tile::createTile("Furnace", $this->getLevel(), $nbt);
return true; return true;
} }
@ -111,7 +111,7 @@ class BurningFurnace extends Solid{
new IntTag("z", $this->z) new IntTag("z", $this->z)
]); ]);
$nbt->Items->setTagType(NBT::TAG_Compound); $nbt->Items->setTagType(NBT::TAG_Compound);
$furnace = Tile::createTile("Furnace", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt); $furnace = Tile::createTile("Furnace", $this->getLevel(), $nbt);
} }
if(isset($furnace->namedtag->Lock) and $furnace->namedtag->Lock instanceof StringTag){ if(isset($furnace->namedtag->Lock) and $furnace->namedtag->Lock instanceof StringTag){

View File

@ -115,7 +115,7 @@ class Chest extends Transparent{
} }
} }
$tile = Tile::createTile("Chest", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt); $tile = Tile::createTile("Chest", $this->getLevel(), $nbt);
if($chest instanceof TileChest and $tile instanceof TileChest){ if($chest instanceof TileChest and $tile instanceof TileChest){
$chest->pairWith($tile); $chest->pairWith($tile);
@ -155,7 +155,7 @@ class Chest extends Transparent{
new IntTag("z", $this->z) new IntTag("z", $this->z)
]); ]);
$nbt->Items->setTagType(NBT::TAG_Compound); $nbt->Items->setTagType(NBT::TAG_Compound);
$chest = Tile::createTile("Chest", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt); $chest = Tile::createTile("Chest", $this->getLevel(), $nbt);
} }
if(isset($chest->namedtag->Lock) and $chest->namedtag->Lock instanceof StringTag){ if(isset($chest->namedtag->Lock) and $chest->namedtag->Lock instanceof StringTag){

View File

@ -57,7 +57,7 @@ class EnchantingTable extends Transparent{
} }
} }
Tile::createTile(Tile::ENCHANT_TABLE, $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt); Tile::createTile(Tile::ENCHANT_TABLE, $this->getLevel(), $nbt);
return true; return true;
} }

View File

@ -37,7 +37,7 @@ abstract class Fallable extends Solid{
if($type === Level::BLOCK_UPDATE_NORMAL){ if($type === Level::BLOCK_UPDATE_NORMAL){
$down = $this->getSide(Vector3::SIDE_DOWN); $down = $this->getSide(Vector3::SIDE_DOWN);
if($down->getId() === self::AIR or ($down instanceof Liquid)){ if($down->getId() === self::AIR or ($down instanceof Liquid)){
$fall = Entity::createEntity("FallingSand", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), new CompoundTag("", [ $fall = Entity::createEntity("FallingSand", $this->getLevel(), new CompoundTag("", [
"Pos" => new ListTag("Pos", [ "Pos" => new ListTag("Pos", [
new DoubleTag("", $this->x + 0.5), new DoubleTag("", $this->x + 0.5),
new DoubleTag("", $this->y), new DoubleTag("", $this->y),

View File

@ -85,7 +85,7 @@ class FlowerPot extends Flowable{
} }
} }
Tile::createTile(Tile::FLOWER_POT, $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt); Tile::createTile(Tile::FLOWER_POT, $this->getLevel(), $nbt);
return true; return true;
} }

View File

@ -56,7 +56,7 @@ class ItemFrame extends Flowable{
new FloatTag("ItemDropChance", 1.0), new FloatTag("ItemDropChance", 1.0),
new ByteTag("ItemRotation", 0) new ByteTag("ItemRotation", 0)
]); ]);
$tile = Tile::createTile(Tile::ITEM_FRAME, $this->level->getChunk($this->x >> 4, $this->z >> 4), $nbt); $tile = Tile::createTile(Tile::ITEM_FRAME, $this->getLevel(), $nbt);
} }
if($tile->hasItem()){ if($tile->hasItem()){
@ -133,7 +133,7 @@ class ItemFrame extends Flowable{
} }
} }
Tile::createTile(Tile::ITEM_FRAME, $this->level->getChunk($this->x >> 4, $this->z >> 4), $nbt); Tile::createTile(Tile::ITEM_FRAME, $this->getLevel(), $nbt);
return true; return true;

View File

@ -81,7 +81,7 @@ class MobHead extends Flowable{
$nbt->CustomName = new StringTag("CustomName", $item->getCustomName()); $nbt->CustomName = new StringTag("CustomName", $item->getCustomName());
} }
/** @var Spawnable $tile */ /** @var Spawnable $tile */
Tile::createTile("Skull", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt); Tile::createTile("Skull", $this->getLevel(), $nbt);
return true; return true;
} }
return false; return false;

View File

@ -87,7 +87,7 @@ class SignPost extends Transparent{
$this->getLevel()->setBlock($block, new WallSign($this->meta), true); $this->getLevel()->setBlock($block, new WallSign($this->meta), true);
} }
Tile::createTile(Tile::SIGN, $this->getLevel()->getChunk($block->x >> 4, $block->z >> 4), $nbt); Tile::createTile(Tile::SIGN, $this->getLevel(), $nbt);
return true; return true;
} }

View File

@ -57,7 +57,7 @@ class TNT extends Solid{
$this->getLevel()->setBlock($this, new Air(), true); $this->getLevel()->setBlock($this, new Air(), true);
$mot = (new Random())->nextSignedFloat() * M_PI * 2; $mot = (new Random())->nextSignedFloat() * M_PI * 2;
$tnt = Entity::createEntity("PrimedTNT", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), new CompoundTag("", [ $tnt = Entity::createEntity("PrimedTNT", $this->getLevel(), new CompoundTag("", [
"Pos" => new ListTag("Pos", [ "Pos" => new ListTag("Pos", [
new DoubleTag("", $this->x + 0.5), new DoubleTag("", $this->x + 0.5),
new DoubleTag("", $this->y), new DoubleTag("", $this->y),

View File

@ -21,7 +21,7 @@
namespace pocketmine\entity; namespace pocketmine\entity;
use pocketmine\level\format\Chunk; use pocketmine\level\Level;
use pocketmine\level\particle\CriticalParticle; use pocketmine\level\particle\CriticalParticle;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\network\protocol\AddEntityPacket; use pocketmine\network\protocol\AddEntityPacket;
@ -41,9 +41,9 @@ class Arrow extends Projectile{
protected $isCritical; protected $isCritical;
public function __construct(Chunk $chunk, CompoundTag $nbt, Entity $shootingEntity = null, $critical = false){ public function __construct(Level $level, CompoundTag $nbt, Entity $shootingEntity = null, $critical = false){
$this->isCritical = (bool) $critical; $this->isCritical = (bool) $critical;
parent::__construct($chunk, $nbt, $shootingEntity); parent::__construct($level, $nbt, $shootingEntity);
} }
public function onUpdate($currentTick){ public function onUpdate($currentTick){

View File

@ -269,10 +269,7 @@ abstract class Entity extends Location implements Metadatable{
protected $isPlayer = false; protected $isPlayer = false;
public function __construct(Chunk $chunk, CompoundTag $nbt){ public function __construct(Level $level, CompoundTag $nbt){
assert($chunk !== null and $chunk->getProvider() !== null);
$this->timings = Timings::getEntityTimings($this); $this->timings = Timings::getEntityTimings($this);
$this->isPlayer = $this instanceof Player; $this->isPlayer = $this instanceof Player;
@ -287,9 +284,10 @@ abstract class Entity extends Location implements Metadatable{
$this->justCreated = true; $this->justCreated = true;
$this->namedtag = $nbt; $this->namedtag = $nbt;
$this->chunk = $chunk; $this->chunk = $level->getChunk($this->namedtag["Pos"][0] >> 4, $this->namedtag["Pos"][2] >> 4);
$this->setLevel($chunk->getProvider()->getLevel()); assert($this->chunk !== null);
$this->server = $chunk->getProvider()->getLevel()->getServer(); $this->setLevel($level);
$this->server = $level->getServer();
$this->boundingBox = new AxisAlignedBB(0, 0, 0, 0, 0, 0); $this->boundingBox = new AxisAlignedBB(0, 0, 0, 0, 0, 0);
$this->setPositionAndRotation( $this->setPositionAndRotation(
@ -301,6 +299,8 @@ abstract class Entity extends Location implements Metadatable{
$this->namedtag->Rotation[0], $this->namedtag->Rotation[0],
$this->namedtag->Rotation[1] $this->namedtag->Rotation[1]
); );
$this->setMotion($this->temporalVector->setComponents($this->namedtag["Motion"][0], $this->namedtag["Motion"][1], $this->namedtag["Motion"][2])); $this->setMotion($this->temporalVector->setComponents($this->namedtag["Motion"][0], $this->namedtag["Motion"][1], $this->namedtag["Motion"][2]));
assert(!is_nan($this->x) and !is_infinite($this->x) and !is_nan($this->y) and !is_infinite($this->y) and !is_nan($this->z) and !is_infinite($this->z)); assert(!is_nan($this->x) and !is_infinite($this->x) and !is_nan($this->y) and !is_infinite($this->y) and !is_nan($this->z) and !is_infinite($this->z));
@ -515,16 +515,16 @@ abstract class Entity extends Location implements Metadatable{
/** /**
* @param int|string $type * @param int|string $type
* @param Chunk $chunk * @param Level $level
* @param CompoundTag $nbt * @param CompoundTag $nbt
* @param $args * @param $args
* *
* @return Entity * @return Entity
*/ */
public static function createEntity($type, Chunk $chunk, CompoundTag $nbt, ...$args){ public static function createEntity($type, Level $level, CompoundTag $nbt, ...$args){
if(isset(self::$knownEntities[$type])){ if(isset(self::$knownEntities[$type])){
$class = self::$knownEntities[$type]; $class = self::$knownEntities[$type];
return new $class($chunk, $nbt, ...$args); return new $class($level, $nbt, ...$args);
} }
return null; return null;

View File

@ -26,7 +26,7 @@ use pocketmine\event\entity\EntityDamageByChildEntityEvent;
use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\event\entity\EntityDamageByEntityEvent;
use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\EntityDamageEvent;
use pocketmine\event\entity\ProjectileHitEvent; use pocketmine\event\entity\ProjectileHitEvent;
use pocketmine\level\format\Chunk; use pocketmine\level\Level;
use pocketmine\level\MovingObjectPosition; use pocketmine\level\MovingObjectPosition;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
@ -42,12 +42,12 @@ abstract class Projectile extends Entity{
public $hadCollision = false; public $hadCollision = false;
public function __construct(Chunk $chunk, CompoundTag $nbt, Entity $shootingEntity = null){ public function __construct(Level $level, CompoundTag $nbt, Entity $shootingEntity = null){
$this->shootingEntity = $shootingEntity; $this->shootingEntity = $shootingEntity;
if($shootingEntity !== null){ if($shootingEntity !== null){
$this->setDataProperty(self::DATA_SHOOTER_ID, self::DATA_TYPE_LONG, $shootingEntity->getId()); $this->setDataProperty(self::DATA_SHOOTER_ID, self::DATA_TYPE_LONG, $shootingEntity->getId());
} }
parent::__construct($chunk, $nbt); parent::__construct($level, $nbt);
} }
public function attack($damage, EntityDamageEvent $source){ public function attack($damage, EntityDamageEvent $source){

View File

@ -21,7 +21,7 @@
namespace pocketmine\entity; namespace pocketmine\entity;
use pocketmine\level\format\Chunk; use pocketmine\level\Level;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\network\protocol\AddEntityPacket; use pocketmine\network\protocol\AddEntityPacket;
use pocketmine\Player; use pocketmine\Player;
@ -36,8 +36,8 @@ class Snowball extends Projectile{
protected $gravity = 0.03; protected $gravity = 0.03;
protected $drag = 0.01; protected $drag = 0.01;
public function __construct(Chunk $chunk, CompoundTag $nbt, Entity $shootingEntity = null){ public function __construct(Level $level, CompoundTag $nbt, Entity $shootingEntity = null){
parent::__construct($chunk, $nbt, $shootingEntity); parent::__construct($level, $nbt, $shootingEntity);
} }
public function onUpdate($currentTick){ public function onUpdate($currentTick){

View File

@ -14,27 +14,30 @@
* (at your option) any later version. * (at your option) any later version.
* *
* @author PocketMine Team * @author PocketMine Team
* @link http://www.pocketmine.net/ * @link http://www.pocketmine.net/
* *
* *
*/ */
/**
* Level related events
*/
namespace pocketmine\event\level; namespace pocketmine\event\level;
use pocketmine\level\Level;
use pocketmine\level\format\Chunk; use pocketmine\level\format\Chunk;
/**
* Chunk-related events
*/
abstract class ChunkEvent extends LevelEvent{ abstract class ChunkEvent extends LevelEvent{
/** @var Chunk */ /** @var Chunk */
private $chunk; private $chunk;
/** /**
* @param Level $level
* @param Chunk $chunk * @param Chunk $chunk
*/ */
public function __construct(Chunk $chunk){ public function __construct(Level $level, Chunk $chunk){
parent::__construct($chunk->getProvider()->getLevel()); parent::__construct($level);
$this->chunk = $chunk; $this->chunk = $chunk;
} }

View File

@ -14,13 +14,15 @@
* (at your option) any later version. * (at your option) any later version.
* *
* @author PocketMine Team * @author PocketMine Team
* @link http://www.pocketmine.net/ * @link http://www.pocketmine.net/
* *
* *
*/ */
namespace pocketmine\event\level; namespace pocketmine\event\level;
use pocketmine\level\Level;
use pocketmine\level\format\Chunk; use pocketmine\level\format\Chunk;
/** /**
@ -31,9 +33,9 @@ class ChunkLoadEvent extends ChunkEvent{
private $newChunk; private $newChunk;
public function __construct(Chunk $chunk, $newChunk){ public function __construct(Level $level, Chunk $chunk, bool $newChunk){
parent::__construct($chunk); parent::__construct($level, $chunk);
$this->newChunk = (bool) $newChunk; $this->newChunk = $newChunk;
} }
/** /**

View File

@ -24,7 +24,6 @@ namespace pocketmine\item;
use pocketmine\block\Block; use pocketmine\block\Block;
use pocketmine\entity\Entity; use pocketmine\entity\Entity;
use pocketmine\level\format\Chunk;
use pocketmine\level\Level; use pocketmine\level\Level;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\DoubleTag; use pocketmine\nbt\tag\DoubleTag;
@ -43,13 +42,6 @@ class SpawnEgg extends Item{
} }
public function onActivate(Level $level, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){ public function onActivate(Level $level, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
$entity = null;
$chunk = $level->getChunk($block->getX() >> 4, $block->getZ() >> 4);
if(!($chunk instanceof Chunk)){
return false;
}
$nbt = new CompoundTag("", [ $nbt = new CompoundTag("", [
"Pos" => new ListTag("Pos", [ "Pos" => new ListTag("Pos", [
new DoubleTag("", $block->getX() + 0.5), new DoubleTag("", $block->getX() + 0.5),
@ -71,7 +63,7 @@ class SpawnEgg extends Item{
$nbt->CustomName = new StringTag("CustomName", $this->getCustomName()); $nbt->CustomName = new StringTag("CustomName", $this->getCustomName());
} }
$entity = Entity::createEntity($this->meta, $chunk, $nbt); $entity = Entity::createEntity($this->meta, $level, $nbt);
if($entity instanceof Entity){ if($entity instanceof Entity){
if($player->isSurvival()){ if($player->isSurvival()){

View File

@ -173,7 +173,7 @@ class Explosion{
foreach($this->affectedBlocks as $block){ foreach($this->affectedBlocks as $block){
if($block->getId() === Block::TNT){ if($block->getId() === Block::TNT){
$mot = (new Random())->nextSignedFloat() * M_PI * 2; $mot = (new Random())->nextSignedFloat() * M_PI * 2;
$tnt = Entity::createEntity("PrimedTNT", $this->level->getChunk($block->x >> 4, $block->z >> 4), new CompoundTag("", [ $tnt = Entity::createEntity("PrimedTNT", $this->level, new CompoundTag("", [
"Pos" => new ListTag("Pos", [ "Pos" => new ListTag("Pos", [
new DoubleTag("", $block->x + 0.5), new DoubleTag("", $block->x + 0.5),
new DoubleTag("", $block->y), new DoubleTag("", $block->y),

View File

@ -1452,7 +1452,7 @@ class Level implements ChunkManager, Metadatable{
$itemTag->setName("Item"); $itemTag->setName("Item");
if($item->getId() > 0 and $item->getCount() > 0){ if($item->getId() > 0 and $item->getCount() > 0){
$itemEntity = Entity::createEntity("Item", $this->getChunk($source->getX() >> 4, $source->getZ() >> 4, true), new CompoundTag("", [ $itemEntity = Entity::createEntity("Item", $this, new CompoundTag("", [
"Pos" => new ListTag("Pos", [ "Pos" => new ListTag("Pos", [
new DoubleTag("", $source->getX()), new DoubleTag("", $source->getX()),
new DoubleTag("", $source->getY()), new DoubleTag("", $source->getY()),
@ -2126,11 +2126,10 @@ class Level implements ChunkManager, Metadatable{
} }
} }
unset($this->chunkPopulationQueue[$index]); unset($this->chunkPopulationQueue[$index]);
$chunk->setProvider($this->provider);
$this->setChunk($x, $z, $chunk, false); $this->setChunk($x, $z, $chunk, false);
$chunk = $this->getChunk($x, $z, false); $chunk = $this->getChunk($x, $z, false);
if($chunk !== null and ($oldChunk === null or $oldChunk->isPopulated() === false) and $chunk->isPopulated() and $chunk->getProvider() !== null){ if($chunk !== null and ($oldChunk === null or $oldChunk->isPopulated() === false) and $chunk->isPopulated()){
$this->server->getPluginManager()->callEvent(new ChunkPopulateEvent($chunk)); $this->server->getPluginManager()->callEvent(new ChunkPopulateEvent($this, $chunk));
foreach($this->getChunkLoaders($x, $z) as $loader){ foreach($this->getChunkLoaders($x, $z) as $loader){
$loader->onChunkPopulated($chunk); $loader->onChunkPopulated($chunk);
@ -2139,10 +2138,8 @@ class Level implements ChunkManager, Metadatable{
}elseif(isset($this->chunkGenerationQueue[$index]) or isset($this->chunkPopulationLock[$index])){ }elseif(isset($this->chunkGenerationQueue[$index]) or isset($this->chunkPopulationLock[$index])){
unset($this->chunkGenerationQueue[$index]); unset($this->chunkGenerationQueue[$index]);
unset($this->chunkPopulationLock[$index]); unset($this->chunkPopulationLock[$index]);
$chunk->setProvider($this->provider);
$this->setChunk($x, $z, $chunk, false); $this->setChunk($x, $z, $chunk, false);
}else{ }else{
$chunk->setProvider($this->provider);
$this->setChunk($x, $z, $chunk, false); $this->setChunk($x, $z, $chunk, false);
} }
Timings::$generationCallbackTimer->stopTiming(); Timings::$generationCallbackTimer->stopTiming();
@ -2435,15 +2432,9 @@ class Level implements ChunkManager, Metadatable{
} }
$this->chunks[$index] = $chunk; $this->chunks[$index] = $chunk;
$chunk->initChunk(); $chunk->initChunk($this);
if($chunk->getProvider() !== null){ $this->server->getPluginManager()->callEvent(new ChunkLoadEvent($this, $chunk, !$chunk->isGenerated()));
$this->server->getPluginManager()->callEvent(new ChunkLoadEvent($chunk, !$chunk->isGenerated()));
}else{
$this->unloadChunk($x, $z, false);
$this->timings->syncChunkLoadTimer->stopTiming();
return false;
}
if(!$chunk->isLightPopulated() and $chunk->isPopulated() and $this->getServer()->getProperty("chunk-ticking.light-updates", false)){ if(!$chunk->isLightPopulated() and $chunk->isPopulated() and $this->getServer()->getProperty("chunk-ticking.light-updates", false)){
$this->getServer()->getScheduler()->scheduleAsyncTask(new LightPopulationTask($this, $chunk)); $this->getServer()->getScheduler()->scheduleAsyncTask(new LightPopulationTask($this, $chunk));
@ -2494,10 +2485,10 @@ class Level implements ChunkManager, Metadatable{
$index = Level::chunkHash($x, $z); $index = Level::chunkHash($x, $z);
$chunk = $this->getChunk($x, $z); $chunk = $this->chunks[$index] ?? null;
if($chunk !== null and $chunk->getProvider() !== null){ if($chunk !== null){
$this->server->getPluginManager()->callEvent($ev = new ChunkUnloadEvent($chunk)); $this->server->getPluginManager()->callEvent($ev = new ChunkUnloadEvent($this, $chunk));
if($ev->isCancelled()){ if($ev->isCancelled()){
$this->timings->doChunkUnload->stopTiming(); $this->timings->doChunkUnload->stopTiming();
return false; return false;

View File

@ -29,7 +29,7 @@ namespace pocketmine\level\format;
use pocketmine\block\Block; use pocketmine\block\Block;
use pocketmine\entity\Entity; use pocketmine\entity\Entity;
use pocketmine\level\format\io\ChunkException; use pocketmine\level\format\io\ChunkException;
use pocketmine\level\format\io\LevelProvider; use pocketmine\level\Level;
use pocketmine\nbt\NBT; use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\Player; use pocketmine\Player;
@ -41,9 +41,6 @@ class Chunk{
const MAX_SUBCHUNKS = 16; const MAX_SUBCHUNKS = 16;
/** @var LevelProvider */
protected $provider;
protected $x; protected $x;
protected $z; protected $z;
@ -85,7 +82,6 @@ class Chunk{
protected $NBTentities = []; protected $NBTentities = [];
/** /**
* @param LevelProvider $provider
* @param int $chunkX * @param int $chunkX
* @param int $chunkZ * @param int $chunkZ
* @param SubChunk[] $subChunks * @param SubChunk[] $subChunks
@ -94,12 +90,11 @@ class Chunk{
* @param string $biomeIds * @param string $biomeIds
* @param int[] $heightMap * @param int[] $heightMap
*/ */
public function __construct($provider, int $chunkX, int $chunkZ, array $subChunks = [], array $entities = [], array $tiles = [], string $biomeIds = "", array $heightMap = []){ public function __construct(int $chunkX, int $chunkZ, array $subChunks = [], array $entities = [], array $tiles = [], string $biomeIds = "", array $heightMap = []){
$this->provider = $provider;
$this->x = $chunkX; $this->x = $chunkX;
$this->z = $chunkZ; $this->z = $chunkZ;
$this->height = $provider !== null ? ($provider->getWorldHeight() >> 4) : 16; $this->height = Chunk::MAX_SUBCHUNKS; //TODO: add a way of changing this
$this->emptySubChunk = new EmptySubChunk(); $this->emptySubChunk = new EmptySubChunk();
@ -164,20 +159,6 @@ class Chunk{
$this->z = $z; $this->z = $z;
} }
/**
* @return LevelProvider|null
*/
public function getProvider(){
return $this->provider;
}
/**
* @param LevelProvider $provider
*/
public function setProvider(LevelProvider $provider){
$this->provider = $provider;
}
/** /**
* Returns the chunk height in count of subchunks. * Returns the chunk height in count of subchunks.
* *
@ -661,20 +642,12 @@ class Chunk{
/** /**
* Unloads the chunk, closing entities and tiles. * Unloads the chunk, closing entities and tiles.
* *
* @param bool $save
* @param bool $safe Whether to check if there are still players using this chunk * @param bool $safe Whether to check if there are still players using this chunk
* *
* @return bool * @return bool
*/ */
public function unload(bool $save = true, bool $safe = true) : bool{ public function unload(bool $safe = true) : bool{
$level = $this->getProvider(); if($safe){
if($level === null){
return true;
}
if($save === true and $this->hasChanged){
$level->saveChunk($this->getX(), $this->getZ());
}
if($safe === true){
foreach($this->getEntities() as $entity){ foreach($this->getEntities() as $entity){
if($entity instanceof Player){ if($entity instanceof Player){
return false; return false;
@ -688,22 +661,24 @@ class Chunk{
} }
$entity->close(); $entity->close();
} }
foreach($this->getTiles() as $tile){ foreach($this->getTiles() as $tile){
$tile->close(); $tile->close();
} }
$this->provider = null;
return true; return true;
} }
/** /**
* Deserializes tiles and entities from NBT * Deserializes tiles and entities from NBT
* TODO: remove this *
* @param Level $level
*/ */
public function initChunk(){ public function initChunk(Level $level){
if($this->getProvider() instanceof LevelProvider and !$this->isInit){ if(!$this->isInit){
$changed = false; $changed = false;
if($this->NBTentities !== null){ if($this->NBTentities !== null){
$this->getProvider()->getLevel()->timings->syncChunkLoadEntitiesTimer->startTiming(); $level->timings->syncChunkLoadEntitiesTimer->startTiming();
foreach($this->NBTentities as $nbt){ foreach($this->NBTentities as $nbt){
if($nbt instanceof CompoundTag){ if($nbt instanceof CompoundTag){
if(!isset($nbt->id)){ if(!isset($nbt->id)){
@ -716,7 +691,7 @@ class Chunk{
continue; //Fixes entities allocated in wrong chunks. continue; //Fixes entities allocated in wrong chunks.
} }
if(($entity = Entity::createEntity($nbt["id"], $this, $nbt)) instanceof Entity){ if(($entity = Entity::createEntity($nbt["id"], $level, $nbt)) instanceof Entity){
$entity->spawnToAll(); $entity->spawnToAll();
}else{ }else{
$changed = true; $changed = true;
@ -724,9 +699,9 @@ class Chunk{
} }
} }
} }
$this->getProvider()->getLevel()->timings->syncChunkLoadEntitiesTimer->stopTiming(); $level->timings->syncChunkLoadEntitiesTimer->stopTiming();
$this->getProvider()->getLevel()->timings->syncChunkLoadTileEntitiesTimer->startTiming(); $level->timings->syncChunkLoadTileEntitiesTimer->startTiming();
foreach($this->NBTtiles as $nbt){ foreach($this->NBTtiles as $nbt){
if($nbt instanceof CompoundTag){ if($nbt instanceof CompoundTag){
if(!isset($nbt->id)){ if(!isset($nbt->id)){
@ -739,14 +714,14 @@ class Chunk{
continue; //Fixes tiles allocated in wrong chunks. continue; //Fixes tiles allocated in wrong chunks.
} }
if(Tile::createTile($nbt["id"], $this, $nbt) === null){ if(Tile::createTile($nbt["id"], $level, $nbt) === null){
$changed = true; $changed = true;
continue; continue;
} }
} }
} }
$this->getProvider()->getLevel()->timings->syncChunkLoadTileEntitiesTimer->stopTiming(); $level->timings->syncChunkLoadTileEntitiesTimer->stopTiming();
$this->NBTentities = null; $this->NBTentities = null;
$this->NBTtiles = null; $this->NBTtiles = null;
@ -954,12 +929,11 @@ class Chunk{
/** /**
* Deserializes a fast-serialized chunk * Deserializes a fast-serialized chunk
* *
* @param string $data * @param string $data
* @param LevelProvider|null $provider
* *
* @return Chunk * @return Chunk
*/ */
public static function fastDeserialize(string $data, LevelProvider $provider = null){ public static function fastDeserialize(string $data){
$stream = new BinaryStream(); $stream = new BinaryStream();
$stream->setBuffer($data); $stream->setBuffer($data);
$data = null; $data = null;
@ -973,7 +947,7 @@ class Chunk{
$heightMap = array_values(unpack("C*", $stream->get(256))); $heightMap = array_values(unpack("C*", $stream->get(256)));
$biomeIds = $stream->get(256); $biomeIds = $stream->get(256);
$chunk = new Chunk($provider, $x, $z, $subChunks, [], [], $biomeIds, $heightMap); $chunk = new Chunk($x, $z, $subChunks, [], [], $biomeIds, $heightMap);
$flags = $stream->getByte(); $flags = $stream->getByte();
$chunk->lightPopulated = (bool) ($flags & 4); $chunk->lightPopulated = (bool) ($flags & 4);
$chunk->terrainPopulated = (bool) ($flags & 2); $chunk->terrainPopulated = (bool) ($flags & 2);
@ -982,8 +956,8 @@ class Chunk{
} }
//TODO: get rid of this //TODO: get rid of this
public static function getEmptyChunk(int $x, int $z, LevelProvider $provider = null) : Chunk{ public static function getEmptyChunk(int $x, int $z) : Chunk{
return new Chunk($provider, $x, $z); return new Chunk($x, $z);
} }
/** /**

View File

@ -258,7 +258,7 @@ class LevelDB extends BaseLevelProvider{
$this->level->timings->syncChunkLoadDataTimer->startTiming(); $this->level->timings->syncChunkLoadDataTimer->startTiming();
$chunk = $this->readChunk($chunkX, $chunkZ); $chunk = $this->readChunk($chunkX, $chunkZ);
if($chunk === null and $create){ if($chunk === null and $create){
$chunk = Chunk::getEmptyChunk($chunkX, $chunkZ, $this); $chunk = Chunk::getEmptyChunk($chunkX, $chunkZ);
} }
$this->level->timings->syncChunkLoadDataTimer->stopTiming(); $this->level->timings->syncChunkLoadDataTimer->stopTiming();
@ -392,7 +392,6 @@ class LevelDB extends BaseLevelProvider{
}*/ //TODO }*/ //TODO
$chunk = new Chunk( $chunk = new Chunk(
$this,
$chunkX, $chunkX,
$chunkZ, $chunkZ,
$subChunks, $subChunks,
@ -469,7 +468,7 @@ class LevelDB extends BaseLevelProvider{
public function unloadChunk(int $x, int $z, bool $safe = true) : bool{ public function unloadChunk(int $x, int $z, bool $safe = true) : bool{
$chunk = $this->chunks[$index = Level::chunkHash($x, $z)] ?? null; $chunk = $this->chunks[$index = Level::chunkHash($x, $z)] ?? null;
if($chunk instanceof Chunk and $chunk->unload(false, $safe)){ if($chunk instanceof Chunk and $chunk->unload($safe)){
unset($this->chunks[$index]); unset($this->chunks[$index]);
return true; return true;
@ -514,8 +513,6 @@ class LevelDB extends BaseLevelProvider{
} }
public function setChunk(int $chunkX, int $chunkZ, Chunk $chunk){ public function setChunk(int $chunkX, int $chunkZ, Chunk $chunk){
$chunk->setProvider($this);
$chunk->setX($chunkX); $chunk->setX($chunkX);
$chunk->setZ($chunkZ); $chunk->setZ($chunkZ);

View File

@ -134,7 +134,6 @@ class Anvil extends McRegion{
} }
$result = new Chunk( $result = new Chunk(
$this,
$chunk["xPos"], $chunk["xPos"],
$chunk["zPos"], $chunk["zPos"],
$subChunks, $subChunks,

View File

@ -188,7 +188,6 @@ class McRegion extends BaseLevelProvider{
} }
$result = new Chunk( $result = new Chunk(
$this,
$chunk["xPos"], $chunk["xPos"],
$chunk["zPos"], $chunk["zPos"],
$subChunks, $subChunks,
@ -294,9 +293,6 @@ class McRegion extends BaseLevelProvider{
} }
public function setChunk(int $chunkX, int $chunkZ, Chunk $chunk){ public function setChunk(int $chunkX, int $chunkZ, Chunk $chunk){
$chunk->setProvider($this);
self::getRegionIndex($chunkX, $chunkZ, $regionX, $regionZ); self::getRegionIndex($chunkX, $chunkZ, $regionX, $regionZ);
$this->loadRegion($regionX, $regionZ); $this->loadRegion($regionX, $regionZ);
@ -354,7 +350,7 @@ class McRegion extends BaseLevelProvider{
public function unloadChunk(int $chunkX, int $chunkZ, bool $safe = true) : bool{ public function unloadChunk(int $chunkX, int $chunkZ, bool $safe = true) : bool{
$chunk = $this->chunks[$index = Level::chunkHash($chunkX, $chunkZ)] ?? null; $chunk = $this->chunks[$index = Level::chunkHash($chunkX, $chunkZ)] ?? null;
if($chunk instanceof Chunk and $chunk->unload(false, $safe)){ if($chunk instanceof Chunk and $chunk->unload($safe)){
unset($this->chunks[$index]); unset($this->chunks[$index]);
return true; return true;
} }
@ -422,7 +418,7 @@ class McRegion extends BaseLevelProvider{
* @return Chunk * @return Chunk
*/ */
public function getEmptyChunk(int $chunkX, int $chunkZ){ public function getEmptyChunk(int $chunkX, int $chunkZ){
return Chunk::getEmptyChunk($chunkX, $chunkZ, $this); return Chunk::getEmptyChunk($chunkX, $chunkZ);
} }
/** /**

View File

@ -129,7 +129,6 @@ class PMAnvil extends Anvil{
} }
$result = new Chunk( $result = new Chunk(
$this,
$chunk["xPos"], $chunk["xPos"],
$chunk["zPos"], $chunk["zPos"],
$subChunks, $subChunks,

View File

@ -75,7 +75,7 @@ class GenerationTask extends AsyncTask{
return; return;
} }
/** @var Chunk $chunk */ /** @var Chunk $chunk */
$chunk = Chunk::fastDeserialize($this->chunk, $level->getProvider()); $chunk = Chunk::fastDeserialize($this->chunk);
if($chunk === null){ if($chunk === null){
//TODO error //TODO error
return; return;

View File

@ -55,7 +55,7 @@ class LightPopulationTask extends AsyncTask{
$level = $server->getLevel($this->levelId); $level = $server->getLevel($this->levelId);
if($level !== null){ if($level !== null){
/** @var Chunk $chunk */ /** @var Chunk $chunk */
$chunk = Chunk::fastDeserialize($this->chunk, $level->getProvider()); $chunk = Chunk::fastDeserialize($this->chunk);
if($chunk === null){ if($chunk === null){
//TODO error //TODO error
return; return;

View File

@ -152,7 +152,7 @@ class PopulationTask extends AsyncTask{
return; return;
} }
$chunk = Chunk::fastDeserialize($this->chunk, $level->getProvider()); $chunk = Chunk::fastDeserialize($this->chunk);
if($chunk === null){ if($chunk === null){
//TODO error //TODO error
@ -165,7 +165,7 @@ class PopulationTask extends AsyncTask{
} }
$c = $this->{"chunk$i"}; $c = $this->{"chunk$i"};
if($c !== null){ if($c !== null){
$c = Chunk::fastDeserialize($c, $level->getProvider()); $c = Chunk::fastDeserialize($c);
$level->generateChunkCallback($c->getX(), $c->getZ(), $c); $level->generateChunkCallback($c->getX(), $c->getZ(), $c);
} }
} }

View File

@ -25,7 +25,7 @@ use pocketmine\inventory\ChestInventory;
use pocketmine\inventory\DoubleChestInventory; use pocketmine\inventory\DoubleChestInventory;
use pocketmine\inventory\InventoryHolder; use pocketmine\inventory\InventoryHolder;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\level\format\Chunk; use pocketmine\level\Level;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\nbt\NBT; use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
@ -40,8 +40,8 @@ class Chest extends Spawnable implements InventoryHolder, Container, Nameable{
/** @var DoubleChestInventory */ /** @var DoubleChestInventory */
protected $doubleInventory = null; protected $doubleInventory = null;
public function __construct(Chunk $chunk, CompoundTag $nbt){ public function __construct(Level $level, CompoundTag $nbt){
parent::__construct($chunk, $nbt); parent::__construct($level, $nbt);
$this->inventory = new ChestInventory($this); $this->inventory = new ChestInventory($this);
if(!isset($this->namedtag->Items) or !($this->namedtag->Items instanceof ListTag)){ if(!isset($this->namedtag->Items) or !($this->namedtag->Items instanceof ListTag)){

View File

@ -22,7 +22,7 @@
namespace pocketmine\tile; namespace pocketmine\tile;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\level\format\Chunk; use pocketmine\level\Level;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\ShortTag; use pocketmine\nbt\tag\ShortTag;
@ -30,14 +30,14 @@ use pocketmine\nbt\tag\StringTag;
class FlowerPot extends Spawnable{ class FlowerPot extends Spawnable{
public function __construct(Chunk $chunk, CompoundTag $nbt){ public function __construct(Level $level, CompoundTag $nbt){
if(!isset($nbt->item)){ if(!isset($nbt->item)){
$nbt->item = new ShortTag("item", 0); $nbt->item = new ShortTag("item", 0);
} }
if(!isset($nbt->mData)){ if(!isset($nbt->mData)){
$nbt->mData = new IntTag("mData", 0); $nbt->mData = new IntTag("mData", 0);
} }
parent::__construct($chunk, $nbt); parent::__construct($level, $nbt);
} }
public function canAddItem(Item $item): bool{ public function canAddItem(Item $item): bool{

View File

@ -28,7 +28,7 @@ use pocketmine\inventory\FurnaceInventory;
use pocketmine\inventory\FurnaceRecipe; use pocketmine\inventory\FurnaceRecipe;
use pocketmine\inventory\InventoryHolder; use pocketmine\inventory\InventoryHolder;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\level\format\Chunk; use pocketmine\level\Level;
use pocketmine\nbt\NBT; use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\IntTag;
@ -41,7 +41,7 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{
/** @var FurnaceInventory */ /** @var FurnaceInventory */
protected $inventory; protected $inventory;
public function __construct(Chunk $chunk, CompoundTag $nbt){ public function __construct(Level $level, CompoundTag $nbt){
if(!isset($nbt->BurnTime) or $nbt["BurnTime"] < 0){ if(!isset($nbt->BurnTime) or $nbt["BurnTime"] < 0){
$nbt->BurnTime = new ShortTag("BurnTime", 0); $nbt->BurnTime = new ShortTag("BurnTime", 0);
} }
@ -53,7 +53,7 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{
$nbt->BurnTicks = new ShortTag("BurnTicks", 0); $nbt->BurnTicks = new ShortTag("BurnTicks", 0);
} }
parent::__construct($chunk, $nbt); parent::__construct($level, $nbt);
$this->inventory = new FurnaceInventory($this); $this->inventory = new FurnaceInventory($this);
if(!isset($this->namedtag->Items) or !($this->namedtag->Items instanceof ListTag)){ if(!isset($this->namedtag->Items) or !($this->namedtag->Items instanceof ListTag)){

View File

@ -22,7 +22,7 @@
namespace pocketmine\tile; namespace pocketmine\tile;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\level\format\Chunk; use pocketmine\level\Level;
use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\ByteTag;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\FloatTag; use pocketmine\nbt\tag\FloatTag;
@ -31,7 +31,7 @@ use pocketmine\nbt\tag\StringTag;
class ItemFrame extends Spawnable{ class ItemFrame extends Spawnable{
public function __construct(Chunk $chunk, CompoundTag $nbt){ public function __construct(Level $level, CompoundTag $nbt){
if(!isset($nbt->ItemRotation)){ if(!isset($nbt->ItemRotation)){
$nbt->ItemRotation = new ByteTag("ItemRotation", 0); $nbt->ItemRotation = new ByteTag("ItemRotation", 0);
} }
@ -40,7 +40,7 @@ class ItemFrame extends Spawnable{
$nbt->ItemDropChance = new FloatTag("ItemDropChance", 1.0); $nbt->ItemDropChance = new FloatTag("ItemDropChance", 1.0);
} }
parent::__construct($chunk, $nbt); parent::__construct($level, $nbt);
} }
public function hasItem() : bool{ public function hasItem() : bool{

View File

@ -22,7 +22,7 @@
namespace pocketmine\tile; namespace pocketmine\tile;
use pocketmine\event\block\SignChangeEvent; use pocketmine\event\block\SignChangeEvent;
use pocketmine\level\format\Chunk; use pocketmine\level\Level;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\StringTag; use pocketmine\nbt\tag\StringTag;
@ -31,7 +31,7 @@ use pocketmine\utils\TextFormat;
class Sign extends Spawnable{ class Sign extends Spawnable{
public function __construct(Chunk $chunk, CompoundTag $nbt){ public function __construct(Level $level, CompoundTag $nbt){
if(!isset($nbt->Text1)){ if(!isset($nbt->Text1)){
$nbt->Text1 = new StringTag("Text1", ""); $nbt->Text1 = new StringTag("Text1", "");
} }
@ -45,7 +45,7 @@ class Sign extends Spawnable{
$nbt->Text4 = new StringTag("Text4", ""); $nbt->Text4 = new StringTag("Text4", "");
} }
parent::__construct($chunk, $nbt); parent::__construct($level, $nbt);
} }
public function saveNBT(){ public function saveNBT(){

View File

@ -21,7 +21,7 @@
namespace pocketmine\tile; namespace pocketmine\tile;
use pocketmine\level\format\Chunk; use pocketmine\level\Level;
use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\ByteTag;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\IntTag;
@ -35,14 +35,14 @@ class Skull extends Spawnable{
const TYPE_CREEPER = 4; const TYPE_CREEPER = 4;
const TYPE_DRAGON = 5; const TYPE_DRAGON = 5;
public function __construct(Chunk $chunk, CompoundTag $nbt){ public function __construct(Level $level, CompoundTag $nbt){
if(!isset($nbt->SkullType)){ if(!isset($nbt->SkullType)){
$nbt->SkullType = new ByteTag("SkullType", 0); $nbt->SkullType = new ByteTag("SkullType", 0);
} }
if(!isset($nbt->Rot)){ if(!isset($nbt->Rot)){
$nbt->Rot = new ByteTag("Rot", 0); $nbt->Rot = new ByteTag("Rot", 0);
} }
parent::__construct($chunk, $nbt); parent::__construct($level, $nbt);
} }
public function setType(int $type){ public function setType(int $type){

View File

@ -21,7 +21,7 @@
namespace pocketmine\tile; namespace pocketmine\tile;
use pocketmine\level\format\Chunk; use pocketmine\level\Level;
use pocketmine\nbt\NBT; use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\network\protocol\BlockEntityDataPacket; use pocketmine\network\protocol\BlockEntityDataPacket;
@ -46,8 +46,8 @@ abstract class Spawnable extends Tile{
return true; return true;
} }
public function __construct(Chunk $chunk, CompoundTag $nbt){ public function __construct(Level $level, CompoundTag $nbt){
parent::__construct($chunk, $nbt); parent::__construct($level, $nbt);
$this->spawnToAll(); $this->spawnToAll();
} }

View File

@ -76,16 +76,16 @@ abstract class Tile extends Position{
/** /**
* @param string $type * @param string $type
* @param Chunk $chunk * @param Level $level
* @param CompoundTag $nbt * @param CompoundTag $nbt
* @param $args * @param $args
* *
* @return Tile * @return Tile
*/ */
public static function createTile($type, Chunk $chunk, CompoundTag $nbt, ...$args){ public static function createTile($type, Level $level, CompoundTag $nbt, ...$args){
if(isset(self::$knownTiles[$type])){ if(isset(self::$knownTiles[$type])){
$class = self::$knownTiles[$type]; $class = self::$knownTiles[$type];
return new $class($chunk, $nbt, ...$args); return new $class($level, $nbt, ...$args);
} }
return null; return null;
@ -116,15 +116,15 @@ abstract class Tile extends Position{
return self::$shortNames[static::class]; return self::$shortNames[static::class];
} }
public function __construct(Chunk $chunk, CompoundTag $nbt){ public function __construct(Level $level, CompoundTag $nbt){
assert($chunk !== null and $chunk->getProvider() !== null);
$this->timings = Timings::getTileEntityTimings($this); $this->timings = Timings::getTileEntityTimings($this);
$this->server = $chunk->getProvider()->getLevel()->getServer();
$this->chunk = $chunk;
$this->setLevel($chunk->getProvider()->getLevel());
$this->namedtag = $nbt; $this->namedtag = $nbt;
$this->server = $level->getServer();
$this->setLevel($level);
$this->chunk = $level->getChunk($this->namedtag["x"] >> 4, $this->namedtag["z"] >> 4, false);
assert($this->chunk !== null);
$this->name = ""; $this->name = "";
$this->lastUpdate = microtime(true); $this->lastUpdate = microtime(true);
$this->id = Tile::$tileCount++; $this->id = Tile::$tileCount++;

@ -1 +1 @@
Subproject commit eb1b7e1c32e440fae216bc46d47ae4f94201de99 Subproject commit db894896ee4932a86f8655ca9f8cabef726787b3