22declare(strict_types=1);
27use pocketmine\block\utils\LeavesType;
28use pocketmine\block\utils\SupportType;
41 private const MAX_LOG_DISTANCE = 4;
43 protected LeavesType $leavesType;
44 protected bool $noDecay =
false;
45 protected bool $checkDecay =
false;
48 parent::__construct($idInfo, $name, $typeInfo);
49 $this->leavesType = $leavesType;
53 $w->bool($this->noDecay);
54 $w->bool($this->checkDecay);
57 public function getLeavesType() : LeavesType{ return $this->leavesType; }
59 public function isNoDecay() : bool{ return $this->noDecay; }
63 $this->noDecay = $noDecay;
67 public function isCheckDecay() : bool{ return $this->checkDecay; }
71 $this->checkDecay = $checkDecay;
84 protected function findLog(
Vector3 $pos, array &$visited = [],
int $distance = 0) : bool{
85 $index =
World::blockHash($pos->x, $pos->y, $pos->z);
86 if(isset($visited[$index])){
89 $visited[$index] =
true;
91 $block = $this->position->getWorld()->
getBlock($pos);
92 if($block instanceof
Wood){
96 if($block instanceof Leaves && $distance <= self::MAX_LOG_DISTANCE){
97 foreach(Facing::ALL as $side){
98 if($this->findLog($pos->
getSide($side), $visited, $distance + 1)){
108 if(!$this->noDecay && !$this->checkDecay){
109 $this->checkDecay =
true;
110 $this->position->getWorld()->setBlock($this->position, $this,
false);
115 return !$this->noDecay && $this->checkDecay;
119 if(!$this->noDecay && $this->checkDecay){
121 if(LeavesDecayEvent::hasHandlers()){
124 $cancelled = $ev->isCancelled();
127 $world = $this->position->getWorld();
128 if($cancelled || $this->findLog($this->position)){
129 $this->checkDecay =
false;
130 $world->setBlock($this->position, $this,
false);
132 $world->useBreakOn($this->position);
138 $this->noDecay = true;
139 return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
143 if(($item->getBlockToolType() &
BlockToolType::SHEARS) !== 0){
144 return parent::getDropsForCompatibleTool($item);
148 if(FortuneDropHelper::bonusChanceDivisor($item, 20, 4)){
150 $sapling = (match($this->leavesType){
151 LeavesType::ACACIA => VanillaBlocks::ACACIA_SAPLING(),
152 LeavesType::BIRCH => VanillaBlocks::BIRCH_SAPLING(),
153 LeavesType::DARK_OAK => VanillaBlocks::DARK_OAK_SAPLING(),
154 LeavesType::JUNGLE => VanillaBlocks::JUNGLE_SAPLING(),
155 LeavesType::OAK => VanillaBlocks::OAK_SAPLING(),
156 LeavesType::SPRUCE => VanillaBlocks::SPRUCE_SAPLING(),
157 LeavesType::MANGROVE,
158 LeavesType::AZALEA, LeavesType::FLOWERING_AZALEA =>
null,
159 LeavesType::CHERRY =>
null,
161 if($sapling !==
null){
166 ($this->leavesType === LeavesType::OAK || $this->leavesType === LeavesType::DARK_OAK) &&
167 FortuneDropHelper::bonusChanceDivisor($item, 200, 20)
169 $drops[] = VanillaItems::APPLE();
171 if(FortuneDropHelper::bonusChanceDivisor($item, 50, 5)){
172 $drops[] = VanillaItems::STICK()->setCount(mt_rand(1, 2));
191 return SupportType::NONE;
findLog(Vector3 $pos, array &$visited=[], int $distance=0)
setNoDecay(bool $noDecay)
describeBlockOnlyState(RuntimeDataDescriber $w)
setCheckDecay(bool $checkDecay)
place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player=null)
getDropsForCompatibleTool(Item $item)
getSupportType(int $facing)
getSide(int $side, int $step=1)
getBlock(Vector3 $pos, bool $cached=true, bool $addToCache=true)