Fixed collision bugs caused by not clearing pre-computed outdated AABBs for blocks

take fences as an example: say you have fence1 and fence2 next to each other, like this:
|==|
and they are joined together
then delete the fence on the right
the left fence will then look like this
|
but the server would still think its collision boxes were like this:
|=
so you wouldn't be able to shoot arrows through that space.

This commit clears pre-computed bounding boxes when a block is set using Level->setBlock() (in case the block was previously already set and has pre-calculated outdated AABB). However, because of weird blocks like fences, glass and walls, they must also be cleared on neighbour block update (since connection state isn't shown in the block data).
This commit is contained in:
Dylan K. Taylor 2017-10-14 10:07:17 +01:00
parent cc553a157d
commit fd8a562e02
2 changed files with 15 additions and 1 deletions

View File

@ -557,6 +557,15 @@ class Block extends Position implements BlockIds, Metadatable{
);
}
/**
* Clears any cached precomputed bounding boxes. This is called on block neighbour update and when the block is set
* into the world to remove any outdated precomputed AABBs and force recalculation.
*/
public function clearBoundingBoxes() : void{
$this->boundingBox = null;
$this->collisionBoxes = null;
}
/**
* @param Vector3 $pos1
* @param Vector3 $pos2

View File

@ -709,7 +709,11 @@ class Level implements ChunkManager, Metadatable{
while($this->neighbourBlockUpdateQueue->count() > 0){
$index = $this->neighbourBlockUpdateQueue->dequeue();
Level::getBlockXYZ($index, $x, $y, $z);
$this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlock($this->temporalVector->setComponents($x, $y, $z))));
$block = $this->getBlock($this->temporalVector->setComponents($x, $y, $z));
$block->clearBoundingBoxes(); //this MUST apply to the original block, not the block chosen by a plugin
$this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($block));
if(!$ev->isCancelled()){
$ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL);
}
@ -1482,6 +1486,7 @@ class Level implements ChunkManager, Metadatable{
}
$block->position($pos);
$block->clearBoundingBoxes();
unset($this->blockCache[Level::blockHash($pos->x, $pos->y, $pos->z)]);
$index = Level::chunkHash($pos->x >> 4, $pos->z >> 4);