mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-13 17:29:44 +00:00
Tiles now encapsulate positions instead of extending them
This commit is contained in:
parent
d355d5b5b5
commit
4e5b296c8c
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -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(){
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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{
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user