Block::readStateFromWorld() now returns the block object that should be used for the target position

this enables changing the block type completely if the situation calls for it.
This commit is contained in:
Dylan K. Taylor 2022-07-16 00:37:32 +01:00
parent b3f8b5ff37
commit 4f2f9b4352
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D
19 changed files with 67 additions and 20 deletions

View File

@ -53,13 +53,15 @@ abstract class BaseBanner extends Transparent{
parent::__construct($idInfo, $name, $breakInfo);
}
public function readStateFromWorld() : void{
public function readStateFromWorld() : Block{
parent::readStateFromWorld();
$tile = $this->position->getWorld()->getTile($this->position);
if($tile instanceof TileBanner){
$this->color = $tile->getBaseColor();
$this->setPatterns($tile->getPatterns());
}
return $this;
}
public function writeStateToWorld() : void{

View File

@ -58,13 +58,15 @@ abstract class BaseSign extends Transparent{
$this->asItemCallback = $asItemCallback;
}
public function readStateFromWorld() : void{
public function readStateFromWorld() : Block{
parent::readStateFromWorld();
$tile = $this->position->getWorld()->getTile($this->position);
if($tile instanceof TileSign){
$this->text = $tile->getText();
$this->editorEntityRuntimeId = $tile->getEditorEntityRuntimeId();
}
return $this;
}
public function writeStateToWorld() : void{

View File

@ -68,13 +68,15 @@ class Bed extends Transparent{
$w->writeBool($this->head);
}
public function readStateFromWorld() : void{
public function readStateFromWorld() : Block{
parent::readStateFromWorld();
//read extra state information from the tile - this is an ugly hack
$tile = $this->position->getWorld()->getTile($this->position);
if($tile instanceof TileBed){
$this->color = $tile->getColor();
}
return $this;
}
public function writeStateToWorld() : void{

View File

@ -189,9 +189,14 @@ class Block{
*
* Clears any cached precomputed objects, such as bounding boxes. Remove any outdated precomputed things such as
* AABBs and force recalculation.
*
* A replacement block may be returned. This is useful if the block type changed due to reading of world data (e.g.
* data from a block entity).
*/
public function readStateFromWorld() : void{
public function readStateFromWorld() : Block{
$this->collisionBoxes = null;
return $this;
}
public function writeStateToWorld() : void{

View File

@ -58,7 +58,7 @@ class Door extends Transparent{
$w->writeBool($this->open);
}
public function readStateFromWorld() : void{
public function readStateFromWorld() : Block{
parent::readStateFromWorld();
//copy door properties from other half
@ -71,6 +71,8 @@ class Door extends Transparent{
$this->hingeRight = $other->hingeRight;
}
}
return $this;
}
public function isTop() : bool{ return $this->top; }

View File

@ -37,7 +37,7 @@ class Fence extends Transparent{
return 0.25;
}
public function readStateFromWorld() : void{
public function readStateFromWorld() : Block{
parent::readStateFromWorld();
foreach(Facing::HORIZONTAL as $facing){
@ -48,6 +48,8 @@ class Fence extends Transparent{
unset($this->connections[$facing]);
}
}
return $this;
}
/**

View File

@ -36,7 +36,7 @@ class FlowerPot extends Flowable{
protected ?Block $plant = null;
public function readStateFromWorld() : void{
public function readStateFromWorld() : Block{
parent::readStateFromWorld();
$tile = $this->position->getWorld()->getTile($this->position);
if($tile instanceof TileFlowerPot){
@ -44,6 +44,8 @@ class FlowerPot extends Flowable{
}else{
$this->setPlant(null);
}
return $this;
}
public function writeStateToWorld() : void{

View File

@ -71,7 +71,7 @@ class ItemFrame extends Flowable{
$w->writeBool($this->hasMap);
}
public function readStateFromWorld() : void{
public function readStateFromWorld() : Block{
parent::readStateFromWorld();
$tile = $this->position->getWorld()->getTile($this->position);
if($tile instanceof TileItemFrame){
@ -82,6 +82,8 @@ class ItemFrame extends Flowable{
$this->itemRotation = $tile->getItemRotation() % self::ROTATIONS;
$this->itemDropChance = $tile->getItemDropChance();
}
return $this;
}
public function writeStateToWorld() : void{

View File

@ -96,12 +96,14 @@ class Jukebox extends Opaque{
return $drops;
}
public function readStateFromWorld() : void{
public function readStateFromWorld() : Block{
parent::readStateFromWorld();
$jukebox = $this->position->getWorld()->getTile($this->position);
if($jukebox instanceof JukeboxTile){
$this->record = $jukebox->getRecord();
}
return $this;
}
public function writeStateToWorld() : void{

View File

@ -59,13 +59,15 @@ class Lectern extends Transparent{
$w->writeBool($this->producingSignal);
}
public function readStateFromWorld() : void{
public function readStateFromWorld() : Block{
parent::readStateFromWorld();
$tile = $this->position->getWorld()->getTile($this->position);
if($tile instanceof TileLectern){
$this->viewedPage = $tile->getViewedPage();
$this->book = $tile->getBook();
}
return $this;
}
public function writeStateToWorld() : void{

View File

@ -160,9 +160,11 @@ abstract class Liquid extends Transparent{
return $block->falling ? 0 : $block->decay;
}
public function readStateFromWorld() : void{
public function readStateFromWorld() : Block{
parent::readStateFromWorld();
$this->flowVector = null;
return $this;
}
public function getFlowVector() : Vector3{

View File

@ -32,7 +32,7 @@ class Note extends Opaque{
private int $pitch = self::MIN_PITCH;
public function readStateFromWorld() : void{
public function readStateFromWorld() : Block{
parent::readStateFromWorld();
$tile = $this->position->getWorld()->getTile($this->position);
if($tile instanceof TileNote){
@ -40,6 +40,8 @@ class Note extends Opaque{
}else{
$this->pitch = self::MIN_PITCH;
}
return $this;
}
public function writeStateToWorld() : void{

View File

@ -60,12 +60,14 @@ class RedstoneComparator extends Flowable{
$w->writeBool($this->powered);
}
public function readStateFromWorld() : void{
public function readStateFromWorld() : Block{
parent::readStateFromWorld();
$tile = $this->position->getWorld()->getTile($this->position);
if($tile instanceof Comparator){
$this->signalStrength = $tile->getSignalStrength();
}
return $this;
}
public function writeStateToWorld() : void{

View File

@ -41,9 +41,11 @@ class RedstoneWire extends Flowable{
return false;
}
public function readStateFromWorld() : void{
public function readStateFromWorld() : Block{
parent::readStateFromWorld();
//TODO: check connections to nearby redstone components
return $this;
}
public function onNearbyBlockChange() : void{

View File

@ -53,12 +53,14 @@ class ShulkerBox extends Opaque{
}
}
public function readStateFromWorld() : void{
public function readStateFromWorld() : Block{
parent::readStateFromWorld();
$shulker = $this->position->getWorld()->getTile($this->position);
if($shulker instanceof TileShulkerBox){
$this->facing = $shulker->getFacing();
}
return $this;
}
public function getMaxStackSize() : int{

View File

@ -77,13 +77,15 @@ class Skull extends Flowable{
$w->writeFacing($this->facing);
}
public function readStateFromWorld() : void{
public function readStateFromWorld() : Block{
parent::readStateFromWorld();
$tile = $this->position->getWorld()->getTile($this->position);
if($tile instanceof TileSkull){
$this->skullType = $tile->getSkullType();
$this->rotation = $tile->getRotation();
}
return $this;
}
public function writeStateToWorld() : void{

View File

@ -59,7 +59,7 @@ class Stair extends Transparent{
$w->writeBool($this->upsideDown);
}
public function readStateFromWorld() : void{
public function readStateFromWorld() : Block{
parent::readStateFromWorld();
$clockwise = Facing::rotateY($this->facing, true);
@ -70,6 +70,8 @@ class Stair extends Transparent{
}else{
$this->shape = StairShape::STRAIGHT();
}
return $this;
}
public function isUpsideDown() : bool{ return $this->upsideDown; }

View File

@ -33,7 +33,7 @@ class Thin extends Transparent{
/** @var bool[] facing => dummy */
protected array $connections = [];
public function readStateFromWorld() : void{
public function readStateFromWorld() : Block{
parent::readStateFromWorld();
foreach(Facing::HORIZONTAL as $facing){
@ -44,6 +44,8 @@ class Thin extends Transparent{
unset($this->connections[$facing]);
}
}
return $this;
}
protected function recalculateCollisionBoxes() : array{

View File

@ -824,7 +824,11 @@ class World implements ChunkManager{
}
$block = $this->getBlockAt($x, $y, $z);
$block->readStateFromWorld(); //for blocks like fences, force recalculation of connected AABBs
$replacement = $block->readStateFromWorld(); //for blocks like fences, force recalculation of connected AABBs
if($replacement !== $block){
$replacement->position($this, $x, $y, $z);
$block = $replacement;
}
$ev = new BlockUpdateEvent($block);
$ev->call();
@ -1548,7 +1552,11 @@ class World implements ChunkManager{
$addToCache = false;
}else{
$dynamicStateRead = true;
$block->readStateFromWorld();
$replacement = $block->readStateFromWorld();
if($replacement !== $block){
$replacement->position($this, $x, $y, $z);
$block = $replacement;
}
$dynamicStateRead = false;
}