PocketMine-MP 5.18.2 git-00e39821f06a4b6d728d35053c2621dbb19369ff
object/Ore.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
29use function sin;
30use const M_PI;
31
32class Ore{
33 public function __construct(
34 private Random $random,
35 public OreType $type
36 ){}
37
38 public function getType() : OreType{
39 return $this->type;
40 }
41
42 public function canPlaceObject(ChunkManager $world, int $x, int $y, int $z) : bool{
43 return $world->getBlockAt($x, $y, $z)->hasSameTypeId($this->type->replaces);
44 }
45
46 public function placeObject(ChunkManager $world, int $x, int $y, int $z) : void{
47 $clusterSize = $this->type->clusterSize;
48 $angle = $this->random->nextFloat() * M_PI;
49 $offset = VectorMath::getDirection2D($angle)->multiply($clusterSize / 8);
50 $x1 = $x + 8 + $offset->x;
51 $x2 = $x + 8 - $offset->x;
52 $z1 = $z + 8 + $offset->y;
53 $z2 = $z + 8 - $offset->y;
54 $y1 = $y + $this->random->nextBoundedInt(3) + 2;
55 $y2 = $y + $this->random->nextBoundedInt(3) + 2;
56 for($count = 0; $count <= $clusterSize; ++$count){
57 $seedX = $x1 + ($x2 - $x1) * $count / $clusterSize;
58 $seedY = $y1 + ($y2 - $y1) * $count / $clusterSize;
59 $seedZ = $z1 + ($z2 - $z1) * $count / $clusterSize;
60 $size = ((sin($count * (M_PI / $clusterSize)) + 1) * $this->random->nextFloat() * $clusterSize / 16 + 1) / 2;
61
62 $startX = (int) ($seedX - $size);
63 $startY = (int) ($seedY - $size);
64 $startZ = (int) ($seedZ - $size);
65 $endX = (int) ($seedX + $size);
66 $endY = (int) ($seedY + $size);
67 $endZ = (int) ($seedZ + $size);
68
69 for($xx = $startX; $xx <= $endX; ++$xx){
70 $sizeX = ($xx + 0.5 - $seedX) / $size;
71 $sizeX *= $sizeX;
72
73 if($sizeX < 1){
74 for($yy = $startY; $yy <= $endY; ++$yy){
75 $sizeY = ($yy + 0.5 - $seedY) / $size;
76 $sizeY *= $sizeY;
77
78 if($yy > 0 && ($sizeX + $sizeY) < 1){
79 for($zz = $startZ; $zz <= $endZ; ++$zz){
80 $sizeZ = ($zz + 0.5 - $seedZ) / $size;
81 $sizeZ *= $sizeZ;
82
83 if(($sizeX + $sizeY + $sizeZ) < 1 && $world->getBlockAt($xx, $yy, $zz)->hasSameTypeId($this->type->replaces)){
84 $world->setBlockAt($xx, $yy, $zz, $this->type->material);
85 }
86 }
87 }
88 }
89 }
90 }
91 }
92 }
93}
getBlockAt(int $x, int $y, int $z)
setBlockAt(int $x, int $y, int $z, Block $block)