mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-12 16:59:44 +00:00
Automate creation of tiles when they are used to store block properties
This commit is contained in:
parent
3f3bdaeba5
commit
1170b66fd5
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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{
|
||||||
|
@ -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,51 +1517,46 @@ 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);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
$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);
|
||||||
|
|
||||||
unset($this->blockCache[$chunkHash][$blockHash]);
|
unset($this->blockCache[$chunkHash][$blockHash]);
|
||||||
|
|
||||||
if(!isset($this->changedBlocks[$chunkHash])){
|
if(!isset($this->changedBlocks[$chunkHash])){
|
||||||
$this->changedBlocks[$chunkHash] = [];
|
$this->changedBlocks[$chunkHash] = [];
|
||||||
}
|
}
|
||||||
$this->changedBlocks[$chunkHash][$blockHash] = $block;
|
$this->changedBlocks[$chunkHash][$blockHash] = $block;
|
||||||
|
|
||||||
foreach($this->getChunkLoaders($pos->x >> 4, $pos->z >> 4) as $loader){
|
foreach($this->getChunkLoaders($pos->x >> 4, $pos->z >> 4) as $loader){
|
||||||
$loader->onBlockChanged($block);
|
$loader->onBlockChanged($block);
|
||||||
}
|
}
|
||||||
|
|
||||||
if($update){
|
if($update){
|
||||||
$this->updateAllLight($block);
|
$this->updateAllLight($block);
|
||||||
|
|
||||||
$ev = new BlockUpdateEvent($block);
|
$ev = new BlockUpdateEvent($block);
|
||||||
$ev->call();
|
$ev->call();
|
||||||
if(!$ev->isCancelled()){
|
if(!$ev->isCancelled()){
|
||||||
foreach($this->getNearbyEntities(AxisAlignedBB::one()->offset($block->x, $block->y, $block->z)->expand(1, 1, 1)) as $entity){
|
foreach($this->getNearbyEntities(AxisAlignedBB::one()->offset($block->x, $block->y, $block->z)->expand(1, 1, 1)) as $entity){
|
||||||
$entity->onNearbyBlockChange();
|
$entity->onNearbyBlockChange();
|
||||||
}
|
|
||||||
$ev->getBlock()->onNearbyBlockChange();
|
|
||||||
$this->scheduleNeighbourBlockUpdates($pos);
|
|
||||||
}
|
}
|
||||||
|
$ev->getBlock()->onNearbyBlockChange();
|
||||||
|
$this->scheduleNeighbourBlockUpdates($pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->timings->setBlock->stopTiming();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->timings->setBlock->stopTiming();
|
$this->timings->setBlock->stopTiming();
|
||||||
|
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user