35 private const MIN_HEIGHT = 5;
37 private ?
Vector3 $mainBranchTip =
null;
38 private ?
Vector3 $secondBranchTip =
null;
40 public function __construct(){
42 VanillaBlocks::ACACIA_LOG(),
43 VanillaBlocks::ACACIA_LEAVES(),
48 protected function generateTrunkHeight(
Random $random) :
int{
53 protected function placeTrunk(
int $x,
int $y,
int $z,
Random $random,
int $trunkHeight,
BlockTransaction $transaction) :
void{
55 $transaction->
addBlockAt($x, $y - 1, $z, VanillaBlocks::DIRT());
57 $firstBranchHeight = $trunkHeight - 1 - $random->
nextRange(0, 3);
59 for($yy = 0; $yy <= $firstBranchHeight; ++$yy){
60 $transaction->
addBlockAt($x, $y + $yy, $z, $this->trunkBlock);
63 $mainBranchFacing = Facing::HORIZONTAL[array_rand(Facing::HORIZONTAL)];
66 $this->mainBranchTip = $this->placeBranch(
68 new Vector3($x, $y + $firstBranchHeight, $z),
71 $trunkHeight - $firstBranchHeight
74 $secondBranchFacing = Facing::HORIZONTAL[array_rand(Facing::HORIZONTAL)];
75 if($secondBranchFacing !== $mainBranchFacing){
76 $secondBranchLength = $random->
nextRange(1, 3);
77 $this->secondBranchTip = $this->placeBranch(
90 $nextBlockPos = $start;
91 for($yy = 0; $yy < $length; $yy++){
92 $nextBlockPos = $nextBlockPos->up();
93 if($diagonalPlaced < $maxDiagonal){
94 $nextBlockPos = $nextBlockPos->getSide($branchFacing);
97 $transaction->
addBlock($nextBlockPos, $this->trunkBlock);
100 return $nextBlockPos;
103 protected function placeCanopyLayer(
BlockTransaction $transaction,
Vector3 $center,
int $radius,
int $maxTaxicabDistance) :
void{
104 $centerX = $center->getFloorX();
105 $centerY = $center->getFloorY();
106 $centerZ = $center->getFloorZ();
108 for($x = $centerX - $radius; $x <= $centerX + $radius; ++$x){
109 for($z = $centerZ - $radius; $z <= $centerZ + $radius; ++$z){
111 abs($x - $centerX) + abs($z - $centerZ) <= $maxTaxicabDistance &&
112 $transaction->
fetchBlockAt($x, $centerY, $z)->canBeReplaced()
114 $transaction->
addBlockAt($x, $centerY, $z, $this->leafBlock);
120 protected function placeCanopy(
int $x,
int $y,
int $z,
Random $random,
BlockTransaction $transaction) :
void{
121 $mainBranchTip = $this->mainBranchTip;
122 if($mainBranchTip !==
null){
123 $this->placeCanopyLayer($transaction, $mainBranchTip, radius: 3, maxTaxicabDistance: 5);
124 $this->placeCanopyLayer($transaction, $mainBranchTip->
up(), radius: 2, maxTaxicabDistance: 2);
126 $secondBranchTip = $this->secondBranchTip;
127 if($secondBranchTip !==
null){
128 $this->placeCanopyLayer($transaction, $secondBranchTip, radius: 2, maxTaxicabDistance: 3);
129 $this->placeCanopyLayer($transaction, $secondBranchTip->
up(), radius: 1, maxTaxicabDistance: 2);