42 use HorizontalFacingTrait;
44 protected bool $top =
false;
47 $w->enum($this->facing);
51 public function isTop() : bool{
56 public function setTop(
bool $top) : self{
61 private function canBeSupportedBy(
Block $block) : bool{
69 if(!$this->top && !$this->canBeSupportedBy($this->getSide(
Facing::DOWN))){
70 $this->position->getWorld()->useBreakOn($this->position);
73 $face = $this->top ? Facing::DOWN : Facing::UP;
74 if(!$this->getSide($face)->hasSameTypeId($this)){
75 $this->position->getWorld()->useBreakOn($this->position);
80 $block = $blockReplace->getSide(
Facing::UP);
81 if($block->getTypeId() !== BlockTypeIds::AIR || !$this->canBeSupportedBy($blockReplace->
getSide(Facing::DOWN))){
85 $this->facing = HorizontalFacingOption::fromFacing(Facing::opposite($player->getHorizontalFacing()));
88 $tx->
addBlock($block->position, VanillaBlocks::SMALL_DRIPLEAF()
89 ->setFacing($this->facing)
92 return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
96 if($item instanceof
Fertilizer && $this->grow($player)){
103 private function canGrowTo(
Position $pos) : bool{
104 $world = $pos->getWorld();
105 if(!$world->isInWorld($pos->getFloorX(), $pos->getFloorY(), $pos->getFloorZ())){
108 $block = $world->getBlock($pos);
109 return $block->hasSameTypeId($this) || $block->getTypeId() === BlockTypeIds::AIR;
112 private function grow(?Player $player) : bool{
113 $bottomBlock = $this->top ? $this->getSide(Facing::DOWN) : $this;
114 if(!$this->hasSameTypeId($bottomBlock)){
117 $world = $this->position->getWorld();
118 $tx =
new BlockTransaction($world);
119 $height = mt_rand(2, 5);
121 for($i = 0; $i < $height; $i++){
122 $pos = $bottomBlock->
getSide(Facing::UP, $i)->position;
123 if(!$this->canGrowTo($pos)){
126 $block = ++$grown < $height && $this->canGrowTo($pos->
getSide(Facing::UP)) ?
127 VanillaBlocks::BIG_DRIPLEAF_STEM() :
128 VanillaBlocks::BIG_DRIPLEAF_HEAD();
129 $tx->addBlock($pos, $block->setFacing($this->facing));
132 $ev =
new StructureGrowEvent($bottomBlock, $tx, $player);
134 if(!$ev->isCancelled()){
143 $other = $this->getSide($this->top ?
Facing::DOWN :
Facing::UP);
144 if($other->hasSameTypeId($this)){
145 return [$this, $other];
147 return parent::getAffectedBlocks();
152 return [$this->asItem()];
166 return SupportType::NONE;
place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, Facing $face, Vector3 $clickVector, ?Player $player=null)