facingExcept($this->facing, Facing::DOWN); } public function getFacing() : int{ return $this->facing; } /** @return $this */ public function setFacing(int $facing) : self{ if($facing === Facing::DOWN){ throw new \InvalidArgumentException("DOWN is not a valid facing for this block"); } $this->facing = $facing; return $this; } abstract protected function getPlant() : Block; public function onNearbyBlockChange() : void{ if($this->facing !== Facing::UP && !$this->getSide($this->facing)->hasSameTypeId($this->getPlant())){ $this->position->getWorld()->setBlock($this->position, $this->setFacing(Facing::UP)); } parent::onNearbyBlockChange(); } public function onRandomTick() : void{ if($this->facing === Facing::UP && mt_rand(0, 2) === 1){ $world = $this->position->getWorld(); if($this->age < self::MAX_AGE){ $block = clone $this; ++$block->age; BlockEventHelper::grow($this, $block, null); }else{ $grow = $this->getPlant(); foreach(Facing::HORIZONTAL as $side){ if($this->getSide($side)->hasSameTypeId($grow)){ return; } } $facing = Facing::HORIZONTAL[array_rand(Facing::HORIZONTAL)]; $side = $this->getSide($facing); if($side->getTypeId() === BlockTypeIds::AIR && $side->getSide(Facing::DOWN)->hasTypeTag(BlockTypeTags::DIRT)){ BlockEventHelper::grow($side, $grow, null); } } } } public function getDropsForCompatibleTool(Item $item) : array{ return [ $this->asItem()->setCount(mt_rand(0, 2)) ]; } }