PocketMine-MP 5.31.1 git-c65f740ce5006911c3bac72aa5e6c3707846bd6e
Loading...
Searching...
No Matches
SmallDripleaf.php
1<?php
2
3/*
4 *
5 * ____ _ _ __ __ _ __ __ ____
6 * | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
7 * | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
8 * | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
9 * |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
10 *
11 * This program is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * @author PocketMine Team
17 * @link http://www.pocketmine.net/
18 *
19 *
20 */
21
22declare(strict_types=1);
23
24namespace pocketmine\block;
25
27use pocketmine\block\utils\HorizontalFacingTrait;
28use pocketmine\block\utils\SupportType;
38use function mt_rand;
39
41 use HorizontalFacingTrait;
42
43 protected bool $top = false;
44
45 public function describeBlockOnlyState(RuntimeDataDescriber $w) : void{
46 $w->horizontalFacing($this->facing);
47 $w->bool($this->top);
48 }
49
50 public function isTop() : bool{
51 return $this->top;
52 }
53
55 public function setTop(bool $top) : self{
56 $this->top = $top;
57 return $this;
58 }
59
60 private function canBeSupportedBy(Block $block) : bool{
61 //TODO: Moss
62 //TODO: Small Dripleaf also can be placed on dirt, coarse dirt, farmland, grass blocks,
63 // podzol, rooted dirt, mycelium, and mud if these blocks are underwater (needs waterlogging)
64 return $block->getTypeId() === BlockTypeIds::CLAY;
65 }
66
67 public function onNearbyBlockChange() : void{
68 if(!$this->top && !$this->canBeSupportedBy($this->getSide(Facing::DOWN))){
69 $this->position->getWorld()->useBreakOn($this->position);
70 return;
71 }
72 $face = $this->top ? Facing::DOWN : Facing::UP;
73 if(!$this->getSide($face)->hasSameTypeId($this)){
74 $this->position->getWorld()->useBreakOn($this->position);
75 }
76 }
77
78 public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
79 $block = $blockReplace->getSide(Facing::UP);
80 if($block->getTypeId() !== BlockTypeIds::AIR || !$this->canBeSupportedBy($blockReplace->getSide(Facing::DOWN))){
81 return false;
82 }
83 if($player !== null){
84 $this->facing = Facing::opposite($player->getHorizontalFacing());
85 }
86
87 $tx->addBlock($block->position, VanillaBlocks::SMALL_DRIPLEAF()
88 ->setFacing($this->facing)
89 ->setTop(true)
90 );
91 return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
92 }
93
94 public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
95 if($item instanceof Fertilizer && $this->grow($player)){
96 $item->pop();
97 return true;
98 }
99 return false;
100 }
101
102 private function canGrowTo(Position $pos) : bool{
103 $world = $pos->getWorld();
104 if(!$world->isInWorld($pos->getFloorX(), $pos->getFloorY(), $pos->getFloorZ())){
105 return false;
106 }
107 $block = $world->getBlock($pos);
108 return $block->hasSameTypeId($this) || $block->getTypeId() === BlockTypeIds::AIR;
109 }
110
111 private function grow(?Player $player) : bool{
112 $bottomBlock = $this->top ? $this->getSide(Facing::DOWN) : $this;
113 if(!$this->hasSameTypeId($bottomBlock)){
114 return false;
115 }
116 $world = $this->position->getWorld();
117 $tx = new BlockTransaction($world);
118 $height = mt_rand(2, 5);
119 $grown = 0;
120 for($i = 0; $i < $height; $i++){
121 $pos = $bottomBlock->getSide(Facing::UP, $i)->position;
122 if(!$this->canGrowTo($pos)){
123 break;
124 }
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));
129 }
130 if($grown > 1){
131 $ev = new StructureGrowEvent($bottomBlock, $tx, $player);
132 $ev->call();
133 if(!$ev->isCancelled()){
134 return $tx->apply();
135 }
136 }
137
138 return false;
139 }
140
141 public function getAffectedBlocks() : array{
142 $other = $this->getSide($this->top ? Facing::DOWN : Facing::UP);
143 if($other->hasSameTypeId($this)){
144 return [$this, $other];
145 }
146 return parent::getAffectedBlocks();
147 }
148
149 public function getDropsForCompatibleTool(Item $item) : array{
150 if(!$this->top){
151 return [$this->asItem()];
152 }
153 return [];
154 }
155
156 public function getFlameEncouragement() : int{
157 return 15;
158 }
159
160 public function getFlammability() : int{
161 return 100;
162 }
163
164 public function getSupportType(int $facing) : SupportType{
165 return SupportType::NONE;
166 }
167
168 protected function recalculateCollisionBoxes() : array{
169 return [];
170 }
171}
getSide(int $side, int $step=1)
Definition Block.php:773
onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player=null, array &$returnedItems=[])
describeBlockOnlyState(RuntimeDataDescriber $w)
place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player=null)
pop(int $count=1)
Definition Item.php:433
addBlock(Vector3 $pos, Block $state)
getSide(int $side, int $step=1)
Definition Position.php:87