diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 97738ca77f..b627f88eff 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -798,6 +798,12 @@ class Level implements ChunkManager, Metadatable{ if(!$tile->onUpdate()){ unset($this->updateTiles[$blockHash]); } + if(!$tile->isClosed() and $tile instanceof Spawnable and $tile->isDirty()){ + $this->clearChunkCache($tile->getFloorX() >> 4, $tile->getFloorZ() >> 4); + //TODO: merge this with block-updating (it'll send useless data if a full-chunk resend happens) + $this->broadcastPacketToViewers($tile, $tile->createSpawnPacket()); + $tile->setDirty(false); + } } Timings::$tickTileEntityTimer->stopTiming(); $this->timings->tileEntityTick->stopTiming(); @@ -2587,10 +2593,6 @@ class Level implements ChunkManager, Metadatable{ $this->tiles[Level::blockHash($tile->x, $tile->y, $tile->z)] = $tile; $tile->scheduleUpdate(); - if($tile instanceof Spawnable){ - $this->clearChunkCache($chunkX, $chunkZ); - $tile->spawnToAll(); - } } /** diff --git a/src/pocketmine/tile/Sign.php b/src/pocketmine/tile/Sign.php index aea189a4f9..c566fe6511 100644 --- a/src/pocketmine/tile/Sign.php +++ b/src/pocketmine/tile/Sign.php @@ -88,17 +88,14 @@ class Sign extends Spawnable{ /** * @param int $index 0-3 * @param string $line - * @param bool $update */ - public function setLine(int $index, string $line, bool $update = true) : void{ + public function setLine(int $index, string $line) : void{ if($index < 0 or $index > 3){ throw new \InvalidArgumentException("Index must be in the range 0-3!"); } $this->text[$index] = $line; - if($update){ - $this->onChanged(); - } + $this->onChanged(); } /** diff --git a/src/pocketmine/tile/Spawnable.php b/src/pocketmine/tile/Spawnable.php index 3b7f95e576..fe9818d396 100644 --- a/src/pocketmine/tile/Spawnable.php +++ b/src/pocketmine/tile/Spawnable.php @@ -33,6 +33,9 @@ use pocketmine\Player; abstract class Spawnable extends Tile{ /** @var string|null */ private $spawnCompoundCache = null; + /** @var bool */ + private $dirty = true; //default dirty, until it's been spawned appropriately on the level + /** @var NetworkLittleEndianNBTStream|null */ private static $nbtWriter = null; @@ -56,23 +59,30 @@ abstract class Spawnable extends Tile{ return true; } - public function spawnToAll(){ - if($this->closed){ - return; - } - - $this->level->broadcastPacketToViewers($this, $this->createSpawnPacket()); - } - /** - * Performs actions needed when the tile is modified, such as clearing caches and respawning the tile to players. - * WARNING: This MUST be called to clear spawn-compound and chunk caches when the tile's spawn compound has changed! + * Flags the tile as modified, so that updates will be broadcasted at the next available opportunity. + * This MUST be called any time a change is made that players must be able to see. */ protected function onChanged() : void{ $this->spawnCompoundCache = null; - $this->spawnToAll(); + $this->dirty = true; + $this->scheduleUpdate(); + } - $this->level->clearChunkCache($this->getFloorX() >> 4, $this->getFloorZ() >> 4); + /** + * Returns whether the tile needs to be respawned to viewers. + * + * @return bool + */ + public function isDirty() : bool{ + return $this->dirty; + } + + /** + * @param bool $dirty + */ + public function setDirty(bool $dirty = true) : void{ + $this->dirty = $dirty; } /**