From ebda6ec19bdebe5f58eb1a8cecdb5c1d35a8d2a7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 25 Jun 2017 19:42:32 +0100 Subject: [PATCH] Cleaned up random-block-ticking registration --- src/pocketmine/block/Block.php | 9 +++ src/pocketmine/block/BrownMushroom.php | 35 +----------- src/pocketmine/block/Cactus.php | 4 ++ src/pocketmine/block/Crops.php | 4 ++ src/pocketmine/block/Farmland.php | 13 +++++ src/pocketmine/block/Fire.php | 6 ++ src/pocketmine/block/Grass.php | 4 ++ src/pocketmine/block/Ice.php | 4 +- src/pocketmine/block/Leaves.php | 4 ++ src/pocketmine/block/Mycelium.php | 4 ++ src/pocketmine/block/NetherWartPlant.php | 4 ++ src/pocketmine/block/RedMushroom.php | 3 + src/pocketmine/block/Sapling.php | 3 + src/pocketmine/block/SnowLayer.php | 3 + src/pocketmine/block/Sugarcane.php | 4 ++ src/pocketmine/block/Vine.php | 6 ++ src/pocketmine/level/Level.php | 70 +++++++----------------- 17 files changed, 94 insertions(+), 86 deletions(-) diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 0dc4cd5a5e..0304a4b33c 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -263,6 +263,15 @@ class Block extends Position implements BlockIds, Metadatable{ return false; } + /** + * Returns whether random block updates will be done on this block. + * + * @return bool + */ + public function ticksRandomly() : bool{ + return false; + } + /** * AKA: Block->isPlaceable * @return bool diff --git a/src/pocketmine/block/BrownMushroom.php b/src/pocketmine/block/BrownMushroom.php index 2ca5ce0108..00a43b844a 100644 --- a/src/pocketmine/block/BrownMushroom.php +++ b/src/pocketmine/block/BrownMushroom.php @@ -23,19 +23,10 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\item\Item; -use pocketmine\level\Level; -use pocketmine\math\Vector3; -use pocketmine\Player; - -class BrownMushroom extends Flowable{ +class BrownMushroom extends RedMushroom{ protected $id = self::BROWN_MUSHROOM; - public function __construct(int $meta = 0){ - $this->meta = $meta; - } - public function getName() : string{ return "Brown Mushroom"; } @@ -43,28 +34,4 @@ class BrownMushroom extends Flowable{ public function getLightLevel() : int{ return 1; } - - public function onUpdate(int $type){ - if($type === Level::BLOCK_UPDATE_NORMAL){ - if($this->getSide(Vector3::SIDE_DOWN)->isTransparent() === true){ - $this->getLevel()->useBreakOn($this); - - return Level::BLOCK_UPDATE_NORMAL; - } - } - - return false; - } - - public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{ - $down = $this->getSide(Vector3::SIDE_DOWN); - if($down->isTransparent() === false){ - $this->getLevel()->setBlock($block, $this, true, true); - - return true; - } - - return false; - } - } \ No newline at end of file diff --git a/src/pocketmine/block/Cactus.php b/src/pocketmine/block/Cactus.php index 62da396d83..1dad05c66f 100644 --- a/src/pocketmine/block/Cactus.php +++ b/src/pocketmine/block/Cactus.php @@ -66,6 +66,10 @@ class Cactus extends Transparent{ ); } + public function ticksRandomly() : bool{ + return true; + } + public function onEntityCollide(Entity $entity){ $ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_CONTACT, 1); $entity->attack($ev); diff --git a/src/pocketmine/block/Crops.php b/src/pocketmine/block/Crops.php index b91781d082..1e340c62fd 100644 --- a/src/pocketmine/block/Crops.php +++ b/src/pocketmine/block/Crops.php @@ -65,6 +65,10 @@ abstract class Crops extends Flowable{ return false; } + public function ticksRandomly() : bool{ + return true; + } + public function onUpdate(int $type){ if($type === Level::BLOCK_UPDATE_NORMAL){ if($this->getSide(Vector3::SIDE_DOWN)->getId() !== Block::FARMLAND){ diff --git a/src/pocketmine/block/Farmland.php b/src/pocketmine/block/Farmland.php index 0c42b79375..cbe941fd24 100644 --- a/src/pocketmine/block/Farmland.php +++ b/src/pocketmine/block/Farmland.php @@ -26,6 +26,7 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\item\Tool; +use pocketmine\level\Level; use pocketmine\math\AxisAlignedBB; class Farmland extends Transparent{ @@ -48,6 +49,10 @@ class Farmland extends Transparent{ return Tool::TYPE_SHOVEL; } + public function ticksRandomly() : bool{ + return true; + } + protected function recalculateBoundingBox(){ return new AxisAlignedBB( $this->x, @@ -59,6 +64,14 @@ class Farmland extends Transparent{ ); } + public function onUpdate(int $type){ + if($type === Level::BLOCK_UPDATE_RANDOM){ + //TODO: hydration + } + + return false; + } + public function getDrops(Item $item) : array{ return [ ItemFactory::get(Item::DIRT, 0, 1) diff --git a/src/pocketmine/block/Fire.php b/src/pocketmine/block/Fire.php index 51a872fec1..0b44d54bcc 100644 --- a/src/pocketmine/block/Fire.php +++ b/src/pocketmine/block/Fire.php @@ -61,6 +61,10 @@ class Fire extends Flowable{ return true; } + public function ticksRandomly() : bool{ + return true; + } + public function onEntityCollide(Entity $entity){ $ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_FIRE, 1); $entity->attack($ev); @@ -103,6 +107,8 @@ class Fire extends Flowable{ return Level::BLOCK_UPDATE_NORMAL; } } + + //TODO: fire spread } return false; diff --git a/src/pocketmine/block/Grass.php b/src/pocketmine/block/Grass.php index 338b0864ed..657e174967 100644 --- a/src/pocketmine/block/Grass.php +++ b/src/pocketmine/block/Grass.php @@ -59,6 +59,10 @@ class Grass extends Solid{ ]; } + public function ticksRandomly() : bool{ + return true; + } + public function onUpdate(int $type){ if($type === Level::BLOCK_UPDATE_RANDOM){ $lightAbove = $this->level->getFullLightAt($this->x, $this->y + 1, $this->z); diff --git a/src/pocketmine/block/Ice.php b/src/pocketmine/block/Ice.php index 85b7be2665..3006153cda 100644 --- a/src/pocketmine/block/Ice.php +++ b/src/pocketmine/block/Ice.php @@ -57,8 +57,10 @@ class Ice extends Transparent{ } public function onBreak(Item $item, Player $player = null) : bool{ - $this->getLevel()->setBlock($this, BlockFactory::get(Block::WATER), true); + return $this->getLevel()->setBlock($this, BlockFactory::get(Block::WATER), true); + } + public function ticksRandomly() : bool{ return true; } diff --git a/src/pocketmine/block/Leaves.php b/src/pocketmine/block/Leaves.php index 689deede93..8d2441e7ee 100644 --- a/src/pocketmine/block/Leaves.php +++ b/src/pocketmine/block/Leaves.php @@ -68,6 +68,10 @@ class Leaves extends Transparent{ return true; } + public function ticksRandomly() : bool{ + return true; + } + protected function findLog(Block $pos, array $visited, $distance, &$check, $fromSide = null){ ++$check; $index = $pos->x . "." . $pos->y . "." . $pos->z; diff --git a/src/pocketmine/block/Mycelium.php b/src/pocketmine/block/Mycelium.php index 5d143af045..e4e3dcd2e7 100644 --- a/src/pocketmine/block/Mycelium.php +++ b/src/pocketmine/block/Mycelium.php @@ -57,6 +57,10 @@ class Mycelium extends Solid{ ]; } + public function ticksRandomly() : bool{ + return true; + } + public function onUpdate(int $type){ if($type === Level::BLOCK_UPDATE_RANDOM){ //TODO: light levels diff --git a/src/pocketmine/block/NetherWartPlant.php b/src/pocketmine/block/NetherWartPlant.php index f7c0d11855..f34068a5ab 100644 --- a/src/pocketmine/block/NetherWartPlant.php +++ b/src/pocketmine/block/NetherWartPlant.php @@ -40,6 +40,10 @@ class NetherWartPlant extends Flowable{ $this->meta = $meta; } + public function ticksRandomly() : bool{ + return true; + } + public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{ $down = $this->getSide(Vector3::SIDE_DOWN); if($down->getId() === Block::SOUL_SAND){ diff --git a/src/pocketmine/block/RedMushroom.php b/src/pocketmine/block/RedMushroom.php index de491b2796..3ca78e08b9 100644 --- a/src/pocketmine/block/RedMushroom.php +++ b/src/pocketmine/block/RedMushroom.php @@ -40,6 +40,9 @@ class RedMushroom extends Flowable{ return "Red Mushroom"; } + public function ticksRandomly() : bool{ + return true; + } public function onUpdate(int $type){ if($type === Level::BLOCK_UPDATE_NORMAL){ diff --git a/src/pocketmine/block/Sapling.php b/src/pocketmine/block/Sapling.php index 910c1eb1dc..8601354e90 100644 --- a/src/pocketmine/block/Sapling.php +++ b/src/pocketmine/block/Sapling.php @@ -57,6 +57,9 @@ class Sapling extends Flowable{ return $names[$this->meta & 0x07] ?? "Unknown"; } + public function ticksRandomly() : bool{ + return true; + } public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{ $down = $this->getSide(Vector3::SIDE_DOWN); diff --git a/src/pocketmine/block/SnowLayer.php b/src/pocketmine/block/SnowLayer.php index 565d746f5c..631862724a 100644 --- a/src/pocketmine/block/SnowLayer.php +++ b/src/pocketmine/block/SnowLayer.php @@ -54,6 +54,9 @@ class SnowLayer extends Flowable{ return Tool::TYPE_SHOVEL; } + public function ticksRandomly() : bool{ + return true; + } public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{ if($block->getSide(Vector3::SIDE_DOWN)->isSolid()){ diff --git a/src/pocketmine/block/Sugarcane.php b/src/pocketmine/block/Sugarcane.php index dc51562036..304ea7b93d 100644 --- a/src/pocketmine/block/Sugarcane.php +++ b/src/pocketmine/block/Sugarcane.php @@ -44,6 +44,10 @@ class Sugarcane extends Flowable{ return "Sugarcane"; } + public function ticksRandomly() : bool{ + return true; + } + public function onActivate(Item $item, Player $player = null) : bool{ if($item->getId() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal if($this->getSide(Vector3::SIDE_DOWN)->getId() !== self::SUGARCANE_BLOCK){ diff --git a/src/pocketmine/block/Vine.php b/src/pocketmine/block/Vine.php index 6e64984d61..ebe09985bb 100644 --- a/src/pocketmine/block/Vine.php +++ b/src/pocketmine/block/Vine.php @@ -67,6 +67,10 @@ class Vine extends Transparent{ return true; } + public function ticksRandomly() : bool{ + return true; + } + public function onEntityCollide(Entity $entity){ $entity->resetFallDistance(); } @@ -169,6 +173,8 @@ class Vine extends Transparent{ $this->level->useBreakOn($this); return Level::BLOCK_UPDATE_NORMAL; } + }elseif($type === Level::BLOCK_UPDATE_RANDOM){ + //TODO: vine growth } return false; diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index fc964d9c12..f545a3cf1e 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -26,28 +26,8 @@ declare(strict_types=1); */ namespace pocketmine\level; -use pocketmine\block\Beetroot; use pocketmine\block\Block; use pocketmine\block\BlockFactory; -use pocketmine\block\BrownMushroom; -use pocketmine\block\Cactus; -use pocketmine\block\Carrot; -use pocketmine\block\Farmland; -use pocketmine\block\Fire; -use pocketmine\block\Grass; -use pocketmine\block\Ice; -use pocketmine\block\Leaves; -use pocketmine\block\Leaves2; -use pocketmine\block\MelonStem; -use pocketmine\block\Mycelium; -use pocketmine\block\NetherWartPlant; -use pocketmine\block\Potato; -use pocketmine\block\PumpkinStem; -use pocketmine\block\RedMushroom; -use pocketmine\block\Sapling; -use pocketmine\block\SnowLayer; -use pocketmine\block\Sugarcane; -use pocketmine\block\Wheat; use pocketmine\entity\Arrow; use pocketmine\entity\Effect; use pocketmine\entity\Entity; @@ -229,30 +209,8 @@ class Level implements ChunkManager, Metadatable{ private $chunkTickList = []; private $chunksPerTick; private $clearChunksOnTick; - private $randomTickBlocks = [ - Block::GRASS => Grass::class, - Block::SAPLING => Sapling::class, - Block::LEAVES => Leaves::class, - Block::WHEAT_BLOCK => Wheat::class, - Block::FARMLAND => Farmland::class, - Block::SNOW_LAYER => SnowLayer::class, - Block::ICE => Ice::class, - Block::CACTUS => Cactus::class, - Block::SUGARCANE_BLOCK => Sugarcane::class, - Block::RED_MUSHROOM => RedMushroom::class, - Block::BROWN_MUSHROOM => BrownMushroom::class, - Block::PUMPKIN_STEM => PumpkinStem::class, - Block::MELON_STEM => MelonStem::class, - //Block::VINE => true, - Block::MYCELIUM => Mycelium::class, - //Block::COCOA_BLOCK => true, - Block::CARROT_BLOCK => Carrot::class, - Block::POTATO_BLOCK => Potato::class, - Block::LEAVES2 => Leaves2::class, - Block::FIRE => Fire::class, - Block::BEETROOT_BLOCK => Beetroot::class, - Block::NETHER_WART_PLANT => NetherWartPlant::class - ]; + /** @var \SplFixedArray */ + private $randomTickBlocks = null; /** @var LevelTimings */ public $timings; @@ -346,10 +304,19 @@ class Level implements ChunkManager, Metadatable{ $this->clearChunksOnTick = (bool) $this->server->getProperty("chunk-ticking.clear-tick-list", true); $this->cacheChunks = (bool) $this->server->getProperty("chunk-sending.cache-chunks", false); + $this->randomTickBlocks = \SplFixedArray::fromArray(array_filter(BlockFactory::$list->toArray(), function(Block $block = null){ + return $block !== null and $block->ticksRandomly(); + })); + $this->randomTickBlocks->setSize(256); + $dontTickBlocks = $this->server->getProperty("chunk-ticking.disable-block-ticking", []); foreach($dontTickBlocks as $id){ - if(isset($this->randomTickBlocks[$id])){ - unset($this->randomTickBlocks[$id]); + try{ + if(isset($this->randomTickBlocks[$id])){ + $this->randomTickBlocks[$id] = null; + } + }catch(\RuntimeException $e){ + //index out of bounds } } @@ -916,11 +883,11 @@ class Level implements ChunkManager, Metadatable{ } public function addRandomTickedBlock(int $id){ - $this->randomTickBlocks[$id] = get_class(BlockFactory::$list[$id]); + $this->randomTickBlocks[$id] = BlockFactory::get($id); } public function removeRandomTickedBlock(int $id){ - unset($this->randomTickBlocks[$id]); + $this->randomTickBlocks[$id] = null; } private function tickChunks(){ @@ -975,10 +942,11 @@ class Level implements ChunkManager, Metadatable{ $z = ($k >> 8) & 0x0f; $blockId = $subChunk->getBlockId($x, $y, $z); - if(isset($this->randomTickBlocks[$blockId])){ - $class = $this->randomTickBlocks[$blockId]; + if($this->randomTickBlocks[$blockId] !== null){ /** @var Block $block */ - $block = new $class($subChunk->getBlockData($x, $y, $z)); + $block = clone $this->randomTickBlocks[$blockId]; + $block->setDamage($subChunk->getBlockData($x, $y, $z)); + $block->x = $chunkX * 16 + $x; $block->y = ($Y << 4) + $y; $block->z = $chunkZ * 16 + $z;