diff --git a/src/block/EnderChest.php b/src/block/EnderChest.php index 40ae928a0..0dad1888f 100644 --- a/src/block/EnderChest.php +++ b/src/block/EnderChest.php @@ -74,7 +74,7 @@ class EnderChest extends Transparent{ if($player instanceof Player){ $enderChest = $this->pos->getWorld()->getTile($this->pos); if($enderChest instanceof TileEnderChest and $this->getSide(Facing::UP)->isTransparent()){ - $player->getEnderChestInventory()->setHolderPosition($enderChest); + $player->getEnderChestInventory()->setHolderPosition($this->pos); $player->setCurrentWindow($player->getEnderChestInventory()); } } diff --git a/src/block/tile/BrewingStand.php b/src/block/tile/BrewingStand.php index 21663d69c..535a4180e 100644 --- a/src/block/tile/BrewingStand.php +++ b/src/block/tile/BrewingStand.php @@ -54,9 +54,9 @@ class BrewingStand extends Spawnable implements Container, Nameable{ public function __construct(World $world, Vector3 $pos){ parent::__construct($world, $pos); - $this->inventory = new BrewingStandInventory($this); + $this->inventory = new BrewingStandInventory($this->pos); $this->inventory->addChangeListeners(CallbackInventoryChangeListener::onAnyChange(function(Inventory $unused){ - $this->world->scheduleDelayedBlockUpdate($this->getBlock()->getPos(), 1); + $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, 1); })); } diff --git a/src/block/tile/Chest.php b/src/block/tile/Chest.php index fe77aa979..f05f189e7 100644 --- a/src/block/tile/Chest.php +++ b/src/block/tile/Chest.php @@ -55,7 +55,7 @@ class Chest extends Spawnable implements Container, Nameable{ public function __construct(World $world, Vector3 $pos){ parent::__construct($world, $pos); - $this->inventory = new ChestInventory($this); + $this->inventory = new ChestInventory($this->pos); } public function readSaveData(CompoundTag $nbt) : void{ @@ -63,8 +63,8 @@ class Chest extends Spawnable implements Container, Nameable{ $pairX = $nbt->getInt(self::TAG_PAIRX); $pairZ = $nbt->getInt(self::TAG_PAIRZ); if( - ($this->x === $pairX and abs($this->z - $pairZ) === 1) or - ($this->z === $pairZ and abs($this->x - $pairX) === 1) + ($this->pos->x === $pairX and abs($this->pos->z - $pairZ) === 1) or + ($this->pos->z === $pairZ and abs($this->pos->x - $pairX) === 1) ){ $this->pairX = $pairX; $this->pairZ = $pairZ; @@ -99,7 +99,7 @@ class Chest extends Spawnable implements Container, Nameable{ $this->inventory->removeAllViewers(); if($this->doubleInventory !== null){ - if($this->isPaired() and $this->world->isChunkLoaded($this->pairX >> 4, $this->pairZ >> 4)){ + if($this->isPaired() and $this->pos->getWorld()->isChunkLoaded($this->pairX >> 4, $this->pairZ >> 4)){ $this->doubleInventory->removeAllViewers(); if(($pair = $this->getPair()) !== null){ $pair->doubleInventory = null; @@ -137,7 +137,7 @@ class Chest extends Spawnable implements Container, Nameable{ } protected function checkPairing(){ - if($this->isPaired() and !$this->getWorld()->isInLoadedTerrain(new Vector3($this->pairX, $this->y, $this->pairZ))){ + if($this->isPaired() and !$this->pos->getWorld()->isInLoadedTerrain(new Vector3($this->pairX, $this->pos->y, $this->pairZ))){ //paired to a tile in an unloaded chunk $this->doubleInventory = null; @@ -150,7 +150,7 @@ class Chest extends Spawnable implements Container, Nameable{ if($pair->doubleInventory !== null){ $this->doubleInventory = $pair->doubleInventory; }else{ - if(($pair->x + ($pair->z << 15)) > ($this->x + ($this->z << 15))){ //Order them correctly + if(($pair->getPos()->x + ($pair->getPos()->z << 15)) > ($this->pos->x + ($this->pos->z << 15))){ //Order them correctly $this->doubleInventory = $pair->doubleInventory = new DoubleChestInventory($pair->inventory, $this->inventory); }else{ $this->doubleInventory = $pair->doubleInventory = new DoubleChestInventory($this->inventory, $pair->inventory); @@ -179,7 +179,7 @@ class Chest extends Spawnable implements Container, Nameable{ */ public function getPair() : ?Chest{ if($this->isPaired()){ - $tile = $this->getWorld()->getTileAt($this->pairX, $this->y, $this->pairZ); + $tile = $this->pos->getWorld()->getTileAt($this->pairX, $this->pos->y, $this->pairZ); if($tile instanceof Chest){ return $tile; } @@ -203,11 +203,11 @@ class Chest extends Spawnable implements Container, Nameable{ } private function createPair(Chest $tile){ - $this->pairX = $tile->x; - $this->pairZ = $tile->z; + $this->pairX = $tile->getPos()->x; + $this->pairZ = $tile->getPos()->z; - $tile->pairX = $this->x; - $tile->pairZ = $this->z; + $tile->pairX = $this->getPos()->x; + $tile->pairZ = $this->getPos()->z; } public function unpair(){ diff --git a/src/block/tile/ContainerTrait.php b/src/block/tile/ContainerTrait.php index 00652b5cb..6217b2f70 100644 --- a/src/block/tile/ContainerTrait.php +++ b/src/block/tile/ContainerTrait.php @@ -91,14 +91,14 @@ trait ContainerTrait{ * @see Position::asPosition() * @return Position */ - abstract protected function asPosition() : Position; + abstract protected function getPos() : Position; /** * @see Tile::onBlockDestroyedHook() */ protected function onBlockDestroyedHook() : void{ $inv = $this->getRealInventory(); - $pos = $this->asPosition(); + $pos = $this->getPos(); foreach($inv->getContents() as $k => $item){ $pos->world->dropItem($pos->add(0.5, 0.5, 0.5), $item); diff --git a/src/block/tile/Furnace.php b/src/block/tile/Furnace.php index 0cd82cfaa..2dc9b4fb3 100644 --- a/src/block/tile/Furnace.php +++ b/src/block/tile/Furnace.php @@ -57,10 +57,10 @@ class Furnace extends Spawnable implements Container, Nameable{ public function __construct(World $world, Vector3 $pos){ parent::__construct($world, $pos); - $this->inventory = new FurnaceInventory($this); + $this->inventory = new FurnaceInventory($this->pos); $this->inventory->addChangeListeners(CallbackInventoryChangeListener::onAnyChange( function(Inventory $unused) : void{ - $this->world->scheduleDelayedBlockUpdate($this->asVector3(), 1); + $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, 1); }) ); } @@ -132,7 +132,7 @@ class Furnace extends Spawnable implements Container, Nameable{ $block = $this->getBlock(); if($block instanceof BlockFurnace and !$block->isLit()){ $block->setLit(true); - $this->getWorld()->setBlock($block->getPos(), $block); + $this->pos->getWorld()->setBlock($block->getPos(), $block); } if($this->remainingFuelTime > 0 and $ev->isBurning()){ @@ -158,7 +158,7 @@ class Furnace extends Spawnable implements Container, Nameable{ $fuel = $this->inventory->getFuel(); $raw = $this->inventory->getSmelting(); $product = $this->inventory->getResult(); - $smelt = $this->world->getServer()->getCraftingManager()->matchFurnaceRecipe($raw); + $smelt = $this->pos->getWorld()->getServer()->getCraftingManager()->matchFurnaceRecipe($raw); $canSmelt = ($smelt instanceof FurnaceRecipe and $raw->getCount() > 0 and (($smelt->getResult()->equals($product) and $product->getCount() < $product->getMaxStackSize()) or $product->isNull())); if($this->remainingFuelTime <= 0 and $canSmelt and $fuel->getFuelTime() > 0 and $fuel->getCount() > 0){ @@ -195,7 +195,7 @@ class Furnace extends Spawnable implements Container, Nameable{ $block = $this->getBlock(); if($block instanceof BlockFurnace and $block->isLit()){ $block->setLit(false); - $this->getWorld()->setBlock($block->getPos(), $block); + $this->pos->getWorld()->setBlock($block->getPos(), $block); } $this->remainingFuelTime = $this->cookTime = $this->maxFuelTime = 0; } diff --git a/src/block/tile/Hopper.php b/src/block/tile/Hopper.php index ee620b5c4..838cc2f34 100644 --- a/src/block/tile/Hopper.php +++ b/src/block/tile/Hopper.php @@ -43,7 +43,7 @@ class Hopper extends Spawnable implements Container, Nameable{ public function __construct(World $world, Vector3 $pos){ parent::__construct($world, $pos); - $this->inventory = new HopperInventory($this); + $this->inventory = new HopperInventory($this->pos); } public function readSaveData(CompoundTag $nbt) : void{ diff --git a/src/block/tile/Spawnable.php b/src/block/tile/Spawnable.php index 2e6e772a7..c0d911fbc 100644 --- a/src/block/tile/Spawnable.php +++ b/src/block/tile/Spawnable.php @@ -80,9 +80,9 @@ abstract class Spawnable extends Tile{ final public function getSpawnCompound() : CompoundTag{ $nbt = CompoundTag::create() ->setString(self::TAG_ID, TileFactory::getSaveId(get_class($this))) //TODO: disassociate network ID from save ID - ->setInt(self::TAG_X, $this->x) - ->setInt(self::TAG_Y, $this->y) - ->setInt(self::TAG_Z, $this->z); + ->setInt(self::TAG_X, $this->pos->x) + ->setInt(self::TAG_Y, $this->pos->y) + ->setInt(self::TAG_Z, $this->pos->z); $this->addAdditionalSpawnData($nbt); return $nbt; } diff --git a/src/block/tile/Tile.php b/src/block/tile/Tile.php index 3eaeaaed4..734162544 100644 --- a/src/block/tile/Tile.php +++ b/src/block/tile/Tile.php @@ -37,20 +37,22 @@ use pocketmine\world\Position; use pocketmine\world\World; use function get_class; -abstract class Tile extends Position{ +abstract class Tile{ public const TAG_ID = "id"; public const TAG_X = "x"; public const TAG_Y = "y"; public const TAG_Z = "z"; + /** @var Position */ + protected $pos; /** @var bool */ public $closed = false; /** @var TimingsHandler */ protected $timings; public function __construct(World $world, Vector3 $pos){ - parent::__construct($pos->getFloorX(), $pos->getFloorY(), $pos->getFloorZ(), $world); + $this->pos = Position::fromObject($pos, $world); $this->timings = Timings::getTileEntityTimings($this); } @@ -72,9 +74,9 @@ abstract class Tile extends Position{ public function saveNBT() : CompoundTag{ $nbt = CompoundTag::create() ->setString(self::TAG_ID, TileFactory::getSaveId(get_class($this))) - ->setInt(self::TAG_X, $this->x) - ->setInt(self::TAG_Y, $this->y) - ->setInt(self::TAG_Z, $this->z); + ->setInt(self::TAG_X, $this->pos->getFloorX()) + ->setInt(self::TAG_Y, $this->pos->getFloorY()) + ->setInt(self::TAG_Z, $this->pos->getFloorZ()); $this->writeSaveData($nbt); return $nbt; @@ -102,7 +104,14 @@ abstract class Tile extends Position{ * @return Block */ public function getBlock() : Block{ - return $this->world->getBlockAt($this->x, $this->y, $this->z); + return $this->pos->getWorld()->getBlock($this->pos); + } + + /** + * @return Position + */ + public function getPos() : Position{ + return $this->pos; } public function isClosed() : bool{ @@ -132,9 +141,9 @@ abstract class Tile extends Position{ if(!$this->closed){ $this->closed = true; - if($this->isValid()){ - $this->world->removeTile($this); - $this->setWorld(null); + if($this->pos->isValid()){ + $this->pos->getWorld()->removeTile($this); + $this->pos->setWorld(null); } } } diff --git a/src/world/World.php b/src/world/World.php index fa4ee8257..bca106405 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -901,7 +901,7 @@ class World implements ChunkManager{ $tile = $this->getTileAt($b->x, $b->y, $b->z); if($tile instanceof Spawnable){ - $packets[] = BlockActorDataPacket::create($tile->x, $tile->y, $tile->z, $tile->getSerializedSpawnCompound()); + $packets[] = BlockActorDataPacket::create($b->x, $b->y, $b->z, $tile->getSerializedSpawnCompound()); } } @@ -2348,12 +2348,13 @@ class World implements ChunkManager{ if($tile->isClosed()){ throw new \InvalidArgumentException("Attempted to add a garbage closed Tile to world"); } - if($tile->getWorld() !== $this){ + $pos = $tile->getPos(); + if($pos->getWorld() !== $this){ throw new \InvalidArgumentException("Invalid Tile world"); } - $chunkX = $tile->getFloorX() >> 4; - $chunkZ = $tile->getFloorZ() >> 4; + $chunkX = $pos->getFloorX() >> 4; + $chunkZ = $pos->getFloorZ() >> 4; if(isset($this->chunks[$hash = World::chunkHash($chunkX, $chunkZ)])){ $this->chunks[$hash]->addTile($tile); @@ -2362,7 +2363,7 @@ class World implements ChunkManager{ } //delegate tile ticking to the corresponding block - $this->scheduleDelayedBlockUpdate($tile->asVector3(), 1); + $this->scheduleDelayedBlockUpdate($pos->asVector3(), 1); } /** @@ -2371,18 +2372,19 @@ class World implements ChunkManager{ * @throws \InvalidArgumentException */ public function removeTile(Tile $tile){ - if($tile->getWorld() !== $this){ + $pos = $tile->getPos(); + if($pos->getWorld() !== $this){ throw new \InvalidArgumentException("Invalid Tile world"); } - $chunkX = $tile->getFloorX() >> 4; - $chunkZ = $tile->getFloorZ() >> 4; + $chunkX = $pos->getFloorX() >> 4; + $chunkZ = $pos->getFloorZ() >> 4; if(isset($this->chunks[$hash = World::chunkHash($chunkX, $chunkZ)])){ $this->chunks[$hash]->removeTile($tile); } foreach($this->getChunkListeners($chunkX, $chunkZ) as $listener){ - $listener->onBlockChanged($tile); + $listener->onBlockChanged($pos->asVector3()); } } diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index d083a61e2..138b4d074 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -473,7 +473,8 @@ class Chunk{ throw new \InvalidArgumentException("Attempted to add a garbage closed Tile to a chunk"); } - if(isset($this->tiles[$index = Chunk::blockHash($tile->x, $tile->y, $tile->z)]) and $this->tiles[$index] !== $tile){ + $pos = $tile->getPos(); + if(isset($this->tiles[$index = Chunk::blockHash($pos->x, $pos->y, $pos->z)]) and $this->tiles[$index] !== $tile){ $this->tiles[$index]->close(); } $this->tiles[$index] = $tile; @@ -484,7 +485,8 @@ class Chunk{ * @param Tile $tile */ public function removeTile(Tile $tile) : void{ - unset($this->tiles[Chunk::blockHash($tile->x, $tile->y, $tile->z)]); + $pos = $tile->getPos(); + unset($this->tiles[Chunk::blockHash($pos->x, $pos->y, $pos->z)]); $this->hasChanged = true; }