Cleaned up random-block-ticking registration

This commit is contained in:
Dylan K. Taylor 2017-06-25 19:42:32 +01:00
parent 6553c82320
commit ebda6ec19b
17 changed files with 94 additions and 86 deletions

View File

@ -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

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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){

View File

@ -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)

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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

View File

@ -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){

View File

@ -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){

View File

@ -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);

View File

@ -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()){

View File

@ -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){

View File

@ -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;

View File

@ -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<Block> */
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;