describeAge($w); } protected function recalculateCollisionBoxes() : array{ if($this->top){ return []; } //the pod exists only in the bottom half of the plant return [ AxisAlignedBB::one() ->trim(Facing::UP, 11 / 16) ->squash(Axis::X, 3 / 16) ->squash(Axis::Z, 3 / 16) ->extend(Facing::DOWN, 1 / 16) //presumably this is to correct for farmland being 15/16 of a block tall ]; } private function grow(?Player $player) : bool{ if($this->age >= self::MAX_AGE){ return false; } $bottom = $this->top ? $this->getSide(Facing::DOWN) : $this; $top = $this->top ? $this : $this->getSide(Facing::UP); if($top->getTypeId() !== BlockTypeIds::AIR && !$top->hasSameTypeId($this)){ return false; } $newState = (clone $this)->setAge($this->age + 1); $tx = new BlockTransaction($this->position->getWorld()); $tx->addBlock($bottom->position, (clone $newState)->setTop(false)); $tx->addBlock($top->position, (clone $newState)->setTop(true)); $ev = new StructureGrowEvent($bottom, $tx, $player); $ev->call(); return !$ev->isCancelled() && $tx->apply(); } public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{ if($item instanceof Fertilizer && $this->grow($player)){ $item->pop(); return true; } return false; } public function ticksRandomly() : bool{ return $this->age < self::MAX_AGE && !$this->top; } public function onRandomTick() : void{ //only the bottom half of the plant can grow randomly if(CropGrowthHelper::canGrow($this) && !$this->top){ $this->grow(null); } } }