41 use HorizontalFacingTrait;
43 protected bool $top =
false;
46 $w->horizontalFacing($this->facing);
50 public function isTop() : bool{
55 public function setTop(
bool $top) : self{
60 private function canBeSupportedBy(
Block $block) : bool{
68 if(!$this->top && !$this->canBeSupportedBy($this->getSide(
Facing::DOWN))){
69 $this->position->getWorld()->useBreakOn($this->position);
72 $face = $this->top ? Facing::DOWN : Facing::UP;
73 if(!$this->getSide($face)->hasSameTypeId($this)){
74 $this->position->getWorld()->useBreakOn($this->position);
79 $block = $blockReplace->getSide(
Facing::UP);
80 if($block->getTypeId() !== BlockTypeIds::AIR || !$this->canBeSupportedBy($blockReplace->
getSide(Facing::DOWN))){
84 $this->facing = Facing::opposite($player->getHorizontalFacing());
87 $tx->
addBlock($block->position, VanillaBlocks::SMALL_DRIPLEAF()
88 ->setFacing($this->facing)
91 return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
95 if($item instanceof
Fertilizer && $this->grow($player)){
102 private function canGrowTo(
Position $pos) : bool{
103 $world = $pos->getWorld();
104 if(!$world->isInWorld($pos->getFloorX(), $pos->getFloorY(), $pos->getFloorZ())){
107 $block = $world->getBlock($pos);
108 return $block->hasSameTypeId($this) || $block->getTypeId() === BlockTypeIds::AIR;
111 private function grow(?Player $player) : bool{
112 $bottomBlock = $this->top ? $this->getSide(Facing::DOWN) : $this;
113 if(!$this->hasSameTypeId($bottomBlock)){
116 $world = $this->position->getWorld();
117 $tx =
new BlockTransaction($world);
118 $height = mt_rand(2, 5);
120 for($i = 0; $i < $height; $i++){
121 $pos = $bottomBlock->
getSide(Facing::UP, $i)->position;
122 if(!$this->canGrowTo($pos)){
125 $block = ++$grown < $height && $this->canGrowTo($pos->
getSide(Facing::UP)) ?
126 VanillaBlocks::BIG_DRIPLEAF_STEM() :
127 VanillaBlocks::BIG_DRIPLEAF_HEAD();
128 $tx->addBlock($pos, $block->setFacing($this->facing));
131 $ev =
new StructureGrowEvent($bottomBlock, $tx, $player);
133 if(!$ev->isCancelled()){
142 $other = $this->getSide($this->top ?
Facing::DOWN :
Facing::UP);
143 if($other->hasSameTypeId($this)){
144 return [$this, $other];
146 return parent::getAffectedBlocks();
151 return [$this->asItem()];
165 return SupportType::NONE;
place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player=null)