Automate creation of tiles when they are used to store block properties

This commit is contained in:
Dylan K. Taylor 2018-10-29 18:20:05 +00:00
parent 3f3bdaeba5
commit 1170b66fd5
8 changed files with 76 additions and 80 deletions

View File

@ -74,16 +74,24 @@ class Bed extends Transparent{
return 0b1111; return 0b1111;
} }
public function updateState() : void{ public function readStateFromWorld() : void{
parent::updateState(); 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
//TODO: extend this hack to setting block as well so we don't have to deal with tile hacks in the main code
$tile = $this->level->getTile($this); $tile = $this->level->getTile($this);
if($tile instanceof TileBed){ if($tile instanceof TileBed){
$this->color = $tile->getColor(); $this->color = $tile->getColor();
} }
} }
public function writeStateToWorld() : void{
parent::writeStateToWorld();
//extra block properties storage hack
$tile = Tile::createTile(Tile::BED, $this->getLevel(), TileBed::createNBT($this));
if($tile instanceof TileBed){
$tile->setColor($this->color);
}
}
public function getHardness() : float{ public function getHardness() : float{
return 0.2; return 0.2;
} }
@ -186,16 +194,6 @@ class Bed extends Transparent{
$nextState->head = true; $nextState->head = true;
$this->getLevel()->setBlock($next, $nextState); $this->getLevel()->setBlock($next, $nextState);
//TODO: make this happen automatically on block set
$tile1 = Tile::createTile(Tile::BED, $this->getLevel(), TileBed::createNBT($this));
if($tile1 instanceof TileBed){
$tile1->setColor($this->color);
}
$tile2 = Tile::createTile(Tile::BED, $this->getLevel(), TileBed::createNBT($next));
if($tile2 instanceof TileBed){
$tile2->setColor($this->color);
}
return true; return true;
} }
} }

View File

@ -149,6 +149,22 @@ class Block extends Position implements BlockIds, Metadatable{
//NOOP //NOOP
} }
/**
* Called when this block is created, set, or has a neighbouring block update, to re-detect dynamic properties which
* are not saved on the world.
*
* Clears any cached precomputed objects, such as bounding boxes. Remove any outdated precomputed things such as
* AABBs and force recalculation.
*/
public function readStateFromWorld() : void{
$this->boundingBox = null;
$this->collisionBoxes = null;
}
public function writeStateToWorld() : void{
$this->level->getChunkAtPosition($this)->setBlock($this->x & 0xf, $this->y, $this->z & 0xf, $this->getId(), $this->getDamage());
}
/** /**
* Returns a bitmask used to extract state bits from block metadata. * Returns a bitmask used to extract state bits from block metadata.
* *
@ -448,7 +464,7 @@ class Block extends Position implements BlockIds, Metadatable{
$this->y = (int) $v->y; $this->y = (int) $v->y;
$this->z = (int) $v->z; $this->z = (int) $v->z;
$this->level = $v->level; $this->level = $v->level;
$this->updateState(); $this->readStateFromWorld();
} }
/** /**
@ -717,18 +733,6 @@ class Block extends Position implements BlockIds, Metadatable{
return AxisAlignedBB::one(); return AxisAlignedBB::one();
} }
/**
* Called when this block is created, set, or has a neighbouring block update, to re-detect dynamic properties which
* are not saved on the world.
*
* Clears any cached precomputed objects, such as bounding boxes. Remove any outdated precomputed things such as
* AABBs and force recalculation.
*/
public function updateState() : void{
$this->boundingBox = null;
$this->collisionBoxes = null;
}
/** /**
* @param Vector3 $pos1 * @param Vector3 $pos1
* @param Vector3 $pos2 * @param Vector3 $pos2

View File

@ -48,8 +48,8 @@ class CobblestoneWall extends Transparent{
return 2; return 2;
} }
public function updateState() : void{ public function readStateFromWorld() : void{
parent::updateState(); parent::readStateFromWorld();
foreach(Facing::HORIZONTAL as $facing){ foreach(Facing::HORIZONTAL as $facing){
$block = $this->getSide($facing); $block = $this->getSide($facing);

View File

@ -69,8 +69,8 @@ abstract class Door extends Transparent{
return 0b1111; return 0b1111;
} }
public function updateState() : void{ public function readStateFromWorld() : void{
parent::updateState(); parent::readStateFromWorld();
//copy door properties from other half //copy door properties from other half
$other = $this->getSide($this->top ? Facing::DOWN : Facing::UP); $other = $this->getSide($this->top ? Facing::DOWN : Facing::UP);

View File

@ -34,8 +34,8 @@ abstract class Fence extends Transparent{
return 0.25; return 0.25;
} }
public function updateState() : void{ public function readStateFromWorld() : void{
parent::updateState(); parent::readStateFromWorld();
foreach(Facing::HORIZONTAL as $facing){ foreach(Facing::HORIZONTAL as $facing){
$block = $this->getSide($facing); $block = $this->getSide($facing);

View File

@ -118,8 +118,8 @@ abstract class Liquid extends Transparent{
return $block->falling ? 0 : $block->decay; return $block->falling ? 0 : $block->decay;
} }
public function updateState() : void{ public function readStateFromWorld() : void{
parent::updateState(); parent::readStateFromWorld();
$this->flowVector = null; $this->flowVector = null;
} }

View File

@ -59,8 +59,8 @@ class Skull extends Flowable{
return 0b111; return 0b111;
} }
public function updateState() : void{ public function readStateFromWorld() : void{
parent::updateState(); parent::readStateFromWorld();
$tile = $this->level->getTile($this); $tile = $this->level->getTile($this);
if($tile instanceof TileSkull){ if($tile instanceof TileSkull){
$this->type = $tile->getType(); $this->type = $tile->getType();
@ -68,6 +68,15 @@ class Skull extends Flowable{
} }
} }
public function writeStateToWorld() : void{
parent::writeStateToWorld();
$tile = Tile::createTile(Tile::SKULL, $this->getLevel(), TileSkull::createNBT($this));
if($tile instanceof TileSkull){
$tile->setRotation($this->rotation);
$tile->setType($this->type);
}
}
public function getHardness() : float{ public function getHardness() : float{
return 1; return 1;
} }
@ -91,17 +100,7 @@ class Skull extends Flowable{
if($player !== null and $face === Facing::UP){ if($player !== null and $face === Facing::UP){
$this->rotation = ((int) floor(($player->yaw * 16 / 360) + 0.5)) & 0xf; $this->rotation = ((int) floor(($player->yaw * 16 / 360) + 0.5)) & 0xf;
} }
if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player);
//TODO: make this automatic on block set
$tile = Tile::createTile(Tile::SKULL, $this->getLevel(), TileSkull::createNBT($this));
if($tile instanceof TileSkull){
$tile->setRotation($this->rotation);
$tile->setType($this->type);
}
return true;
}
return false;
} }
public function getItem() : Item{ public function getItem() : Item{

View File

@ -762,7 +762,7 @@ class Level implements ChunkManager, Metadatable{
Level::getBlockXYZ($index, $x, $y, $z); Level::getBlockXYZ($index, $x, $y, $z);
$block = $this->getBlockAt($x, $y, $z); $block = $this->getBlockAt($x, $y, $z);
$block->updateState(); //for blocks like fences, force recalculation of connected AABBs $block->readStateFromWorld(); //for blocks like fences, force recalculation of connected AABBs
$ev = new BlockUpdateEvent($block); $ev = new BlockUpdateEvent($block);
$ev->call(); $ev->call();
@ -1372,7 +1372,7 @@ class Level implements ChunkManager, Metadatable{
$block->y = $y; $block->y = $y;
$block->z = $z; $block->z = $z;
$block->level = $this; $block->level = $this;
$block->updateState(); $block->readStateFromWorld();
if($addToCache and $blockHash !== null){ if($addToCache and $blockHash !== null){
$this->blockCache[$chunkHash][$blockHash] = $block; $this->blockCache[$chunkHash][$blockHash] = $block;
@ -1517,7 +1517,6 @@ class Level implements ChunkManager, Metadatable{
$this->timings->setBlock->startTiming(); $this->timings->setBlock->startTiming();
if($this->getChunkAtPosition($pos, true)->setBlock($pos->x & 0x0f, $pos->y, $pos->z & 0x0f, $block->getId(), $block->getDamage())){
if(!($pos instanceof Position)){ if(!($pos instanceof Position)){
$pos = $this->temporalPosition->setComponents($pos->x, $pos->y, $pos->z); $pos = $this->temporalPosition->setComponents($pos->x, $pos->y, $pos->z);
} }
@ -1525,6 +1524,7 @@ class Level implements ChunkManager, Metadatable{
$block = clone $block; $block = clone $block;
$block->position($pos); $block->position($pos);
$block->writeStateToWorld();
$chunkHash = Level::chunkHash($pos->x >> 4, $pos->z >> 4); $chunkHash = Level::chunkHash($pos->x >> 4, $pos->z >> 4);
$blockHash = Level::blockHash($pos->x, $pos->y, $pos->z); $blockHash = Level::blockHash($pos->x, $pos->y, $pos->z);
@ -1559,11 +1559,6 @@ class Level implements ChunkManager, Metadatable{
return true; return true;
} }
$this->timings->setBlock->stopTiming();
return false;
}
/** /**
* @param Vector3 $source * @param Vector3 $source
* @param Item $item * @param Item $item