From 0907aedcefbf81b839bcf66d4a4a3fd2a23476d3 Mon Sep 17 00:00:00 2001 From: Shoghi Cervantes Date: Mon, 22 Sep 2014 11:48:39 +0200 Subject: [PATCH] Fixed Entity/Block issues on negative coordinates, closes #2100 --- src/pocketmine/entity/Entity.php | 26 ++++++++++---------------- src/pocketmine/entity/FallingBlock.php | 20 ++++++++++---------- src/pocketmine/level/Level.php | 25 +++++++++++++------------ src/pocketmine/math/Math.php | 4 ++++ src/pocketmine/math/Vector3.php | 2 +- 5 files changed, 38 insertions(+), 39 deletions(-) diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 87062d59d..09805282a 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -39,6 +39,7 @@ use pocketmine\level\format\FullChunk; use pocketmine\level\Level; use pocketmine\level\Position; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Math; use pocketmine\math\Vector3 as Vector3; use pocketmine\metadata\Metadatable; use pocketmine\metadata\MetadataValue; @@ -752,20 +753,13 @@ abstract class Entity extends Position implements Metadatable{ $z = ((($i >> 2) % 2) - 0.5) * $this->width * 0.8; $block = $this->getLevel()->getBlock((new Vector3($this->x + $x, $this->y + $this->getEyeHeight() + $y, $this->z + $z))->floor()); - if($block->isSolid){ + $bb = $block->getBoundingBox(); + + if($bb !== null and $block->isSolid and $bb->intersectsWith($this->getBoundingBox())){ return true; } } return false; - - $block = $this->getLevel()->getBlock($pos = (new Vector3($this->x, $y = ($this->y + $this->getEyeHeight()), $this->z))->floor()); - - if($block instanceof Water){ - $f = ($pos->y + 1) - ($block->getFluidHeightPercent() - 0.1111111); - return $y < $f; - } - - return false; } public function collision(){ @@ -994,12 +988,12 @@ abstract class Entity extends Position implements Metadatable{ } protected function checkBlockCollision(){ - $minX = floor($this->boundingBox->minX - 0.001); - $minY = floor($this->boundingBox->minY - 0.001); - $minZ = floor($this->boundingBox->minZ - 0.001); - $maxX = floor($this->boundingBox->maxX + 0.001); - $maxY = floor($this->boundingBox->maxY + 0.001); - $maxZ = floor($this->boundingBox->maxZ + 0.001); + $minX = Math::floorFloat($this->boundingBox->minX - 0.001); + $minY = Math::floorFloat($this->boundingBox->minY - 0.001); + $minZ = Math::floorFloat($this->boundingBox->minZ - 0.001); + $maxX = Math::floorFloat($this->boundingBox->maxX + 0.001); + $maxY = Math::floorFloat($this->boundingBox->maxY + 0.001); + $maxZ = Math::floorFloat($this->boundingBox->maxZ + 0.001); for($z = $minZ; $z <= $maxZ; ++$z){ for($x = $minX; $x <= $maxX; ++$x){ diff --git a/src/pocketmine/entity/FallingBlock.php b/src/pocketmine/entity/FallingBlock.php index 09c385e6f..875c20ac7 100644 --- a/src/pocketmine/entity/FallingBlock.php +++ b/src/pocketmine/entity/FallingBlock.php @@ -69,6 +69,16 @@ class FallingBlock extends Entity{ return false; } + if($this->ticksLived === 1){ + $block = $this->level->getBlock($this->floor()); + if($block->getID() != $this->blockId){ + $this->kill(); + return true; + } + $this->level->setBlock($this->floor(), Block::get(0, true)); + + } + $this->motionY -= $this->gravity; $this->move($this->motionX, $this->motionY, $this->motionZ); @@ -81,16 +91,6 @@ class FallingBlock extends Entity{ $pos = $this->floor(); - if($this->ticksLived === 1){ - $block = $this->level->getBlock($pos); - if($block->getID() != $this->blockId){ - $this->kill(); - return true; - } - $this->level->setBlock($pos, Block::get(0, true)); - - } - if($this->onGround){ $this->kill(); $block = $this->level->getBlock($pos); diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 9bc1b9274..aaffd6049 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -67,6 +67,7 @@ use pocketmine\level\format\generic\EmptyChunkSection; use pocketmine\level\format\LevelProvider; use pocketmine\level\generator\Generator; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Math; use pocketmine\math\Vector2; use pocketmine\math\Vector3; use pocketmine\metadata\BlockMetadataStore; @@ -700,12 +701,12 @@ class Level implements ChunkManager, Metadatable{ * @return Block[] */ public function getCollisionBlocks(AxisAlignedBB $bb){ - $minX = floor($bb->minX); - $minY = floor($bb->minY); - $minZ = floor($bb->minZ); - $maxX = floor($bb->maxX + 1); - $maxY = floor($bb->maxY + 1); - $maxZ = floor($bb->maxZ + 1); + $minX = Math::floorFloat($bb->minX); + $minY = Math::floorFloat($bb->minY); + $minZ = Math::floorFloat($bb->minZ); + $maxX = Math::floorFloat($bb->maxX + 1); + $maxY = Math::floorFloat($bb->maxY + 1); + $maxZ = Math::floorFloat($bb->maxZ + 1); $collides = []; @@ -738,12 +739,12 @@ class Level implements ChunkManager, Metadatable{ * @return AxisAlignedBB[] */ public function getCollisionCubes(Entity $entity, AxisAlignedBB $bb){ - $minX = floor($bb->minX); - $minY = floor($bb->minY); - $minZ = floor($bb->minZ); - $maxX = floor($bb->maxX + 1); - $maxY = floor($bb->maxY + 1); - $maxZ = floor($bb->maxZ + 1); + $minX = Math::floorFloat($bb->minX); + $minY = Math::floorFloat($bb->minY); + $minZ = Math::floorFloat($bb->minZ); + $maxX = Math::floorFloat($bb->maxX + 1); + $maxY = Math::floorFloat($bb->maxY + 1); + $maxZ = Math::floorFloat($bb->maxZ + 1); $collides = []; diff --git a/src/pocketmine/math/Math.php b/src/pocketmine/math/Math.php index 6d48b77d2..7efdf6070 100644 --- a/src/pocketmine/math/Math.php +++ b/src/pocketmine/math/Math.php @@ -27,4 +27,8 @@ namespace pocketmine\math; abstract class Math{ + public static function floorFloat($n){ + $i = (int) $n; + return $n >= $i ? $i : $i - 1; + } } \ No newline at end of file diff --git a/src/pocketmine/math/Vector3.php b/src/pocketmine/math/Vector3.php index ae118a6ba..bdf341f28 100644 --- a/src/pocketmine/math/Vector3.php +++ b/src/pocketmine/math/Vector3.php @@ -123,7 +123,7 @@ class Vector3{ } public function floor(){ - return new Vector3((int) $this->x, (int) $this->y, (int) $this->z); + return new Vector3(Math::floorFloat($this->x), Math::floorFloat($this->y), Math::floorFloat($this->z)); } public function round(){