diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 4a0f422a2..c87fb9c11 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -650,8 +650,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ $pk->started = $this->level->stopTime == false; $this->dataPacket($pk); - $pos = new Position($this->x, $this->y, $this->z, $this->level); - $pos = $this->level->getSafeSpawn($pos); + $pos = $this->level->getSafeSpawn($this); $this->server->getPluginManager()->callEvent($ev = new PlayerRespawnEvent($this, $pos)); @@ -809,8 +808,8 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ return false; } - $this->sleeping = $pos; - $this->teleport(new Position($pos->x + 0.5, $pos->y + 1, $pos->z + 0.5, $this->level)); + $this->sleeping = clone $pos; + $this->teleport(Position::createPosition($pos->x + 0.5, $pos->y + 1, $pos->z + 0.5, $this->level)); $this->sendMetadata($this->getViewers()); $this->sendMetadata($this); diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 18b76853b..6cb8bfaf6 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -50,6 +50,7 @@ use pocketmine\level\generator\GenerationRequestManager; use pocketmine\level\generator\Generator; use pocketmine\level\generator\Normal; use pocketmine\level\Level; +use pocketmine\level\Position; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Vector3; use pocketmine\metadata\EntityMetadataStore; @@ -917,6 +918,7 @@ class Server{ */ public function unloadLevel(Level $level, $forceUnload = false){ if($level->unload($forceUnload) === true){ + Position::clearPositions(); unset($this->levels[$level->getID()]); return true; @@ -2114,13 +2116,9 @@ class Server{ $this->generationManager->process(); - if(($this->tickCounter % 600) === 0){ - Vector3::clearVectors(); - AxisAlignedBB::clearBoundingBoxes(); - }else{ - Vector3::clearVectorList(); - AxisAlignedBB::clearBoundingBoxPool(); - } + Vector3::clearVectorList(); + Position::clearPositionList(); + AxisAlignedBB::clearBoundingBoxPool(); Timings::$serverTickTimer->stopTiming(); diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 6374fa73a..0cafde47b 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -686,7 +686,7 @@ class Block extends Position implements Metadatable{ $block = new Block($id, $meta); } - if($pos instanceof Position){ + if($pos !== null){ $block->x = $pos->x; $block->y = $pos->y; $block->z = $pos->z; diff --git a/src/pocketmine/block/Cactus.php b/src/pocketmine/block/Cactus.php index 29110b7da..b7e11434e 100644 --- a/src/pocketmine/block/Cactus.php +++ b/src/pocketmine/block/Cactus.php @@ -28,7 +28,7 @@ use pocketmine\event\entity\EntityDamageEvent; use pocketmine\item\Item; use pocketmine\level\Level; use pocketmine\math\AxisAlignedBB; -use pocketmine\math\Vector3 as Vector3; +use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\Server; diff --git a/src/pocketmine/block/Grass.php b/src/pocketmine/block/Grass.php index c36ef51aa..167b8a11a 100644 --- a/src/pocketmine/block/Grass.php +++ b/src/pocketmine/block/Grass.php @@ -56,7 +56,7 @@ class Grass extends Solid{ $z = mt_rand($this->z - 1, $this->z + 1); $block = $this->getLevel()->getBlockIdAt($x, $y, $z); if($block === Block::DIRT){ - $block = Block::get($block, $this->getLevel()->getBlockDataAt($x, $y, $z), new Position($x, $y, $z, $this->getLevel())); + $block = Block::get($block, $this->getLevel()->getBlockDataAt($x, $y, $z), Position::createPosition($x, $y, $z, $this->getLevel())); if($block->getSide(1) instanceof Transparent){ Server::getInstance()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($block, $this, new Grass())); if(!$ev->isCancelled()){ diff --git a/src/pocketmine/block/Mycelium.php b/src/pocketmine/block/Mycelium.php index 433661ade..784d2350d 100644 --- a/src/pocketmine/block/Mycelium.php +++ b/src/pocketmine/block/Mycelium.php @@ -47,7 +47,7 @@ class Mycelium extends Solid{ $z = mt_rand($this->z - 1, $this->z + 1); $block = $this->getLevel()->getBlockIdAt($x, $y, $z); if($block === Block::DIRT){ - $block = Block::get($block, $this->getLevel()->getBlockDataAt($x, $y, $z), new Position($x, $y, $z, $this->getLevel())); + $block = Block::get($block, $this->getLevel()->getBlockDataAt($x, $y, $z), Position::createPosition($x, $y, $z, $this->getLevel())); if($block->getSide(1) instanceof Transparent){ Server::getInstance()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($block, $this, new Mycelium())); if(!$ev->isCancelled()){ diff --git a/src/pocketmine/command/defaults/SpawnpointCommand.php b/src/pocketmine/command/defaults/SpawnpointCommand.php index 2aad6c167..8c05f7f30 100644 --- a/src/pocketmine/command/defaults/SpawnpointCommand.php +++ b/src/pocketmine/command/defaults/SpawnpointCommand.php @@ -70,14 +70,14 @@ class SpawnpointCommand extends VanillaCommand{ $x = (int) $this->getRelativeDouble($pos->x, $sender, $args[1]); $y = $this->getRelativeDouble($pos->y, $sender, $args[2], 0, 128); $z = $this->getRelativeDouble($pos->z, $sender, $args[3]); - $target->setSpawn(new Position($x, $y, $z, $level)); + $target->setSpawn(Position::createPosition($x, $y, $z, $level)); Command::broadcastCommandMessage($sender, "Set " . $target->getDisplayName() . "'s spawnpoint to " . $x . ", " . $y . ", " . $z); return true; } }elseif(count($args) <= 1){ if($sender instanceof Player){ - $pos = new Position((int) $sender->x, (int) $sender->y, (int) $sender->z, $sender->getLevel()); + $pos = Position::createPosition((int) $sender->x, (int) $sender->y, (int) $sender->z, $sender->getLevel()); $target->setSpawn($pos); Command::broadcastCommandMessage($sender, "Set " . $target->getDisplayName() . "'s spawnpoint to " . $pos->x . ", " . $pos->y . ", " . $pos->z); diff --git a/src/pocketmine/command/defaults/TeleportCommand.php b/src/pocketmine/command/defaults/TeleportCommand.php index fa6cf24e6..558648722 100644 --- a/src/pocketmine/command/defaults/TeleportCommand.php +++ b/src/pocketmine/command/defaults/TeleportCommand.php @@ -88,7 +88,7 @@ class TeleportCommand extends VanillaCommand{ } if(count($args) < 3){ - $pos = new Position($target->x, $target->y, $target->z, $target->getLevel()); + $pos = Position::clonePosition($target); $origin->teleport($pos); Command::broadcastCommandMessage($sender, "Teleported " . $origin->getDisplayName() . " to " . $target->getDisplayName()); diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 3c2118f65..6fd22b953 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -40,7 +40,7 @@ use pocketmine\level\Location; use pocketmine\level\Position; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Math; -use pocketmine\math\Vector3 as Vector3; +use pocketmine\math\Vector3; use pocketmine\metadata\Metadatable; use pocketmine\metadata\MetadataValue; use pocketmine\nbt\tag\Byte; @@ -737,7 +737,7 @@ abstract class Entity extends Location implements Metadatable{ } public function getPosition(){ - return new Position($this->x, $this->y, $this->z, $this->level); + return Position::createPosition($this->x, $this->y, $this->z, $this->level); } public function getLocation(){ diff --git a/src/pocketmine/entity/FallingBlock.php b/src/pocketmine/entity/FallingBlock.php index e05a6aa92..b23fa1067 100644 --- a/src/pocketmine/entity/FallingBlock.php +++ b/src/pocketmine/entity/FallingBlock.php @@ -88,7 +88,7 @@ class FallingBlock extends Entity{ if(!$this->dead){ if($this->ticksLived === 1){ - $block = $this->level->getBlock($pos = Vector3::createVector($this->x, $this->y, $this->z)->floor()); + $block = $this->level->getBlock($pos = Vector3::cloneVector($this)->floor()); if($block->getID() != $this->blockId){ $this->kill(); return true; @@ -107,7 +107,7 @@ class FallingBlock extends Entity{ $this->motionY *= 1 - $this->drag; $this->motionZ *= $friction; - $pos = Vector3::createVector($this->x, $this->y, $this->z)->floor(); + $pos = Vector3::cloneVector($this)->floor(); if($this->onGround){ $this->kill(); diff --git a/src/pocketmine/event/entity/EntityMotionEvent.php b/src/pocketmine/event/entity/EntityMotionEvent.php index 4d25620ea..6c0ea6b75 100644 --- a/src/pocketmine/event/entity/EntityMotionEvent.php +++ b/src/pocketmine/event/entity/EntityMotionEvent.php @@ -24,7 +24,7 @@ namespace pocketmine\event\entity; use pocketmine\entity\Entity; use pocketmine\Event; use pocketmine\event\Cancellable; -use pocketmine\math\Vector3 as Vector3; +use pocketmine\math\Vector3; class EntityMotionEvent extends EntityEvent implements Cancellable{ public static $handlerList = null; @@ -36,6 +36,9 @@ class EntityMotionEvent extends EntityEvent implements Cancellable{ $this->mot = $mot; } + /** + * @return Vector3 + */ public function getVector(){ return $this->mot; } diff --git a/src/pocketmine/event/entity/EntityMoveEvent.php b/src/pocketmine/event/entity/EntityMoveEvent.php index 74602a46a..099c9a7a4 100644 --- a/src/pocketmine/event/entity/EntityMoveEvent.php +++ b/src/pocketmine/event/entity/EntityMoveEvent.php @@ -24,7 +24,7 @@ namespace pocketmine\event\entity; use pocketmine\entity\Entity; use pocketmine\Event; use pocketmine\event\Cancellable; -use pocketmine\math\Vector3 as Vector3; +use pocketmine\math\Vector3; /** * @deprecated diff --git a/src/pocketmine/level/Explosion.php b/src/pocketmine/level/Explosion.php index 47ce62703..b4eeaf0e0 100644 --- a/src/pocketmine/level/Explosion.php +++ b/src/pocketmine/level/Explosion.php @@ -33,7 +33,7 @@ use pocketmine\event\entity\EntityExplodeEvent; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Math; -use pocketmine\math\Vector3 as Vector3; +use pocketmine\math\Vector3; use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\Double; diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 5d3154ea8..908465c38 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -910,7 +910,7 @@ class Level implements ChunkManager, Metadatable{ return $this->blockCache[$index] = $air; } - return $this->blockCache[$index] = Block::get($blockId, $meta, new Position($pos->x, $pos->y, $pos->z, $this)); + return $this->blockCache[$index] = Block::get($blockId, $meta, $pos instanceof Position ? $pos : Position::createPosition($pos->x, $pos->y, $pos->z, $this)); } /** @@ -940,7 +940,7 @@ class Level implements ChunkManager, Metadatable{ if($this->getChunk($pos->x >> 4, $pos->z >> 4, true)->setBlock($pos->x & 0x0f, $pos->y & 0x7f, $pos->z & 0x0f, $block->getID(), $block->getDamage())){ if(!($pos instanceof Position)){ - $pos = new Position($pos->x, $pos->y, $pos->z, $this); + $pos = Position::createPosition($pos->x, $pos->y, $pos->z, $this); } $block->position($pos); $index = Level::chunkHash($pos->x >> 4, $pos->z >> 4); @@ -1938,14 +1938,14 @@ class Level implements ChunkManager, Metadatable{ for(; $v->y < 128; ++$v->y){ if($this->getBlock($v->getSide(1)) instanceof Air){ if($this->getBlock($v) instanceof Air){ - return new Position($spawn->x, $v->y === Math::floorFloat($spawn->y) ? $spawn->y : $v->y, $spawn->z, $this); + return Position::createPosition($spawn->x, $v->y === Math::floorFloat($spawn->y) ? $spawn->y : $v->y, $spawn->z, $this); } }else{ ++$v->y; } } - return new Position($spawn->x, $v->y, $spawn->z, $this); + return Position::createPosition($spawn->x, $v->y, $spawn->z, $this); } return false; diff --git a/src/pocketmine/level/Position.php b/src/pocketmine/level/Position.php index 8e5f63af1..a3c12460f 100644 --- a/src/pocketmine/level/Position.php +++ b/src/pocketmine/level/Position.php @@ -21,13 +21,54 @@ namespace pocketmine\level; -use pocketmine\math\Vector3 as Vector3; +use pocketmine\math\Vector3; class Position extends Vector3{ + /** @var Position[] */ + private static $positionList = []; + private static $nextPosition = 0; + /** @var Level */ public $level = null; + public static function clearPositions(){ + self::$nextPosition = 0; + self::$positionList = []; + } + + public static function clearPositionList(){ + if(self::$nextPosition > 65536){ + self::clearVectors(); + }else{ + self::$nextPosition = 0; + } + } + + /** + * @param $x + * @param $y + * @param $z + * @param Level $level + * + * @return Position + */ + public static function createPosition($x, $y, $z, Level $level){ + if(self::$nextPosition >= count(self::$positionList)){ + self::$positionList[] = new Position(0, 0, 0, null); + } + + return self::$positionList[self::$nextPosition++]->setLevel($level)->setComponents($x, $y, $z); + } + + public static function clonePosition(Position $pos){ + if(self::$nextPosition >= count(self::$positionList)){ + self::$positionList[] = new Position(0, 0, 0, null); + } + + return self::$positionList[self::$nextPosition++]->setLevel($pos->level)->setComponents($pos->x, $pos->y, $pos->z); + } + /** * @param int $x * @param int $y @@ -42,7 +83,7 @@ class Position extends Vector3{ } public static function fromObject(Vector3 $pos, Level $level = null){ - return new Position($pos->x, $pos->y, $pos->z, $level); + return self::createPosition($pos->x, $pos->y, $pos->z, $level); } /** @@ -52,8 +93,9 @@ class Position extends Vector3{ return $this->level; } - public function setLevel(Level $level, $strong = false){ + public function setLevel(Level $level){ $this->level = $level; + return $this; } /** diff --git a/src/pocketmine/math/AxisAlignedBB.php b/src/pocketmine/math/AxisAlignedBB.php index e9bc2773e..bb233da62 100644 --- a/src/pocketmine/math/AxisAlignedBB.php +++ b/src/pocketmine/math/AxisAlignedBB.php @@ -51,7 +51,11 @@ class AxisAlignedBB{ } public static function clearBoundingBoxPool(){ - self::$nextBoundingBox = 0; + if(self::$nextBoundingBox > 65536){ + self::clearBoundingBoxes(); + }else{ + self::$nextBoundingBox = 0; + } } /** diff --git a/src/pocketmine/math/Vector3.php b/src/pocketmine/math/Vector3.php index 19bcba46b..1c1abfcd5 100644 --- a/src/pocketmine/math/Vector3.php +++ b/src/pocketmine/math/Vector3.php @@ -54,7 +54,11 @@ class Vector3{ } public static function clearVectorList(){ - self::$nextVector = 0; + if(self::$nextVector > 65536){ + self::clearVectors(); + }else{ + self::$nextVector = 0; + } } /** diff --git a/src/pocketmine/tile/Chest.php b/src/pocketmine/tile/Chest.php index b0ff4f7d8..86b2b9a0f 100644 --- a/src/pocketmine/tile/Chest.php +++ b/src/pocketmine/tile/Chest.php @@ -26,7 +26,7 @@ use pocketmine\inventory\DoubleChestInventory; use pocketmine\inventory\InventoryHolder; use pocketmine\item\Item; use pocketmine\level\format\FullChunk; -use pocketmine\math\Vector3 as Vector3; +use pocketmine\math\Vector3; use pocketmine\nbt\NBT; use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\Compound;