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); parent::__construct($idInfo, $name, $breakInfo);
} }
public function readStateFromWorld() : void{ public function readStateFromWorld() : Block{
parent::readStateFromWorld(); parent::readStateFromWorld();
$tile = $this->position->getWorld()->getTile($this->position); $tile = $this->position->getWorld()->getTile($this->position);
if($tile instanceof TileBanner){ if($tile instanceof TileBanner){
$this->color = $tile->getBaseColor(); $this->color = $tile->getBaseColor();
$this->setPatterns($tile->getPatterns()); $this->setPatterns($tile->getPatterns());
} }
return $this;
} }
public function writeStateToWorld() : void{ public function writeStateToWorld() : void{

View File

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

View File

@ -68,13 +68,15 @@ class Bed extends Transparent{
$w->writeBool($this->head); $w->writeBool($this->head);
} }
public function readStateFromWorld() : void{ public function readStateFromWorld() : Block{
parent::readStateFromWorld(); parent::readStateFromWorld();
//read extra state information from the tile - this is an ugly hack //read extra state information from the tile - this is an ugly hack
$tile = $this->position->getWorld()->getTile($this->position); $tile = $this->position->getWorld()->getTile($this->position);
if($tile instanceof TileBed){ if($tile instanceof TileBed){
$this->color = $tile->getColor(); $this->color = $tile->getColor();
} }
return $this;
} }
public function writeStateToWorld() : void{ 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 * Clears any cached precomputed objects, such as bounding boxes. Remove any outdated precomputed things such as
* AABBs and force recalculation. * 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; $this->collisionBoxes = null;
return $this;
} }
public function writeStateToWorld() : void{ public function writeStateToWorld() : void{

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -824,7 +824,11 @@ class World implements ChunkManager{
} }
$block = $this->getBlockAt($x, $y, $z); $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 = new BlockUpdateEvent($block);
$ev->call(); $ev->call();
@ -1548,7 +1552,11 @@ class World implements ChunkManager{
$addToCache = false; $addToCache = false;
}else{ }else{
$dynamicStateRead = true; $dynamicStateRead = true;
$block->readStateFromWorld(); $replacement = $block->readStateFromWorld();
if($replacement !== $block){
$replacement->position($this, $x, $y, $z);
$block = $replacement;
}
$dynamicStateRead = false; $dynamicStateRead = false;
} }