40 use HorizontalFacingTrait;
42 protected bool $top =
false;
45 $w->horizontalFacing($this->facing);
49 public function isTop() : bool{
54 public function setTop(
bool $top) : self{
59 private function canBeSupportedBy(
Block $block) : bool{
67 if(!$this->top && !$this->canBeSupportedBy($this->getSide(
Facing::DOWN))){
68 $this->position->getWorld()->useBreakOn($this->position);
71 $face = $this->top ? Facing::DOWN : Facing::UP;
72 if(!$this->getSide($face)->hasSameTypeId($this)){
73 $this->position->getWorld()->useBreakOn($this->position);
78 $block = $blockReplace->getSide(
Facing::UP);
79 if($block->getTypeId() !== BlockTypeIds::AIR || !$this->canBeSupportedBy($blockReplace->
getSide(Facing::DOWN))){
83 $this->facing = Facing::opposite($player->getHorizontalFacing());
86 $tx->
addBlock($block->position, VanillaBlocks::SMALL_DRIPLEAF()
87 ->setFacing($this->facing)
90 return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
94 if($item instanceof
Fertilizer && $this->grow($player)){
101 private function canGrowTo(
Position $pos) : bool{
102 $world = $pos->getWorld();
103 if(!$world->isInWorld($pos->getFloorX(), $pos->getFloorY(), $pos->getFloorZ())){
106 $block = $world->getBlock($pos);
107 return $block->hasSameTypeId($this) || $block->getTypeId() === BlockTypeIds::AIR;
110 private function grow(?Player $player) : bool{
111 $bottomBlock = $this->top ? $this->getSide(Facing::DOWN) : $this;
112 if(!$this->hasSameTypeId($bottomBlock)){
115 $world = $this->position->getWorld();
116 $tx =
new BlockTransaction($world);
117 $height = mt_rand(2, 5);
119 for($i = 0; $i < $height; $i++){
120 $pos = $bottomBlock->
getSide(Facing::UP, $i)->position;
121 if(!$this->canGrowTo($pos)){
124 $block = ++$grown < $height && $this->canGrowTo($pos->
getSide(Facing::UP)) ?
125 VanillaBlocks::BIG_DRIPLEAF_STEM() :
126 VanillaBlocks::BIG_DRIPLEAF_HEAD();
127 $tx->addBlock($pos, $block->setFacing($this->facing));
130 $ev =
new StructureGrowEvent($bottomBlock, $tx, $player);
132 if(!$ev->isCancelled()){
141 $other = $this->getSide($this->top ?
Facing::DOWN :
Facing::UP);
142 if($other->hasSameTypeId($this)){
143 return [$this, $other];
145 return parent::getAffectedBlocks();
150 return [$this->asItem()];
164 return SupportType::NONE;
place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player=null)