PocketMine-MP 5.21.1 git-2ff647079265e7c600203af4fd902b15e99d49a4
object/Tree.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\world\generator\object;
25
33use function abs;
34
35abstract class Tree{
36 public function __construct(
37 protected Block $trunkBlock,
38 protected Block $leafBlock,
39 protected int $treeHeight = 7
40 ){}
41
42 public function canPlaceObject(ChunkManager $world, int $x, int $y, int $z, Random $random) : bool{
43 $radiusToCheck = 0;
44 for($yy = 0; $yy < $this->treeHeight + 3; ++$yy){
45 if($yy === 1 || $yy === $this->treeHeight){
46 ++$radiusToCheck;
47 }
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))){
51 return false;
52 }
53 }
54 }
55 }
56
57 return true;
58 }
59
64 public function getBlockTransaction(ChunkManager $world, int $x, int $y, int $z, Random $random) : ?BlockTransaction{
65 if(!$this->canPlaceObject($world, $x, $y, $z, $random)){
66 return null;
67 }
68
69 $transaction = new BlockTransaction($world);
70 $this->placeTrunk($x, $y, $z, $random, $this->generateTrunkHeight($random), $transaction);
71 $this->placeCanopy($x, $y, $z, $random, $transaction);
72
73 return $transaction;
74 }
75
76 protected function generateTrunkHeight(Random $random) : int{
77 return $this->treeHeight - 1;
78 }
79
80 protected function placeTrunk(int $x, int $y, int $z, Random $random, int $trunkHeight, BlockTransaction $transaction) : void{
81 // The base dirt block
82 $transaction->addBlockAt($x, $y - 1, $z, VanillaBlocks::DIRT());
83
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);
87 }
88 }
89 }
90
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)){
100 continue;
101 }
102 if(!$transaction->fetchBlockAt($xx, $yy, $zz)->isSolid()){
103 $transaction->addBlockAt($xx, $yy, $zz, $this->leafBlock);
104 }
105 }
106 }
107 }
108 }
109
110 protected function canOverride(Block $block) : bool{
111 return $block->canBeReplaced() || $block instanceof Sapling || $block instanceof Leaves;
112 }
113}
addBlockAt(int $x, int $y, int $z, Block $state)
fetchBlockAt(int $x, int $y, int $z)
getBlockTransaction(ChunkManager $world, int $x, int $y, int $z, Random $random)
Definition: object/Tree.php:64
getBlockAt(int $x, int $y, int $z)