36 public function __construct(
37 protected Block $trunkBlock,
38 protected Block $leafBlock,
39 protected int $treeHeight = 7
42 public function canPlaceObject(
ChunkManager $world,
int $x,
int $y,
int $z,
Random $random) :
bool{
44 for($yy = 0; $yy < $this->treeHeight + 3; ++$yy){
45 if($yy === 1 || $yy === $this->treeHeight){
48 for($xx = -$radiusToCheck; $xx < ($radiusToCheck + 1); ++$xx){
49 for($zz = -$radiusToCheck; $zz < ($radiusToCheck + 1); ++$zz){
50 if(!$this->canOverride($world->
getBlockAt($x + $xx, $y + $yy, $z + $zz))){
65 if(!$this->canPlaceObject($world, $x, $y, $z, $random)){
70 $this->placeTrunk($x, $y, $z, $random, $this->generateTrunkHeight($random), $transaction);
71 $this->placeCanopy($x, $y, $z, $random, $transaction);
76 protected function generateTrunkHeight(
Random $random) : int{
77 return $this->treeHeight - 1;
80 protected function placeTrunk(
int $x,
int $y,
int $z, Random $random,
int $trunkHeight,
BlockTransaction $transaction) : void{
82 $transaction->addBlockAt($x, $y - 1, $z,
VanillaBlocks::DIRT());
84 for($yy = 0; $yy < $trunkHeight; ++$yy){
85 if($this->canOverride($transaction->
fetchBlockAt($x, $y + $yy, $z))){
86 $transaction->
addBlockAt($x, $y + $yy, $z, $this->trunkBlock);
91 protected function placeCanopy(
int $x,
int $y,
int $z, Random $random, BlockTransaction $transaction) : void{
92 for($yy = $y - 3 + $this->treeHeight; $yy <= $y + $this->treeHeight; ++$yy){
93 $yOff = $yy - ($y + $this->treeHeight);
94 $mid = (int) (1 - $yOff / 2);
95 for($xx = $x - $mid; $xx <= $x + $mid; ++$xx){
96 $xOff = abs($xx - $x);
97 for($zz = $z - $mid; $zz <= $z + $mid; ++$zz){
98 $zOff = abs($zz - $z);
99 if($xOff === $mid && $zOff === $mid && ($yOff === 0 || $random->nextBoundedInt(2) === 0)){
102 if(!$transaction->fetchBlockAt($xx, $yy, $zz)->isSolid()){
103 $transaction->addBlockAt($xx, $yy, $zz, $this->leafBlock);
110 protected function canOverride(Block $block) : bool{
111 return $block->canBeReplaced() || $block instanceof Sapling || $block instanceof Leaves;