PocketMine-MP 5.37.4 git-07e225b0bd0d389de8a3d035fbd0ae8730a06053
Loading...
Searching...
No Matches
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
33use function sin;
34use const M_PI;
35
36class Ore{
37 public function __construct(
38 private Random $random,
39 public OreType $type
40 ){}
41
42 public function getType() : OreType{
43 return $this->type;
44 }
45
46 public function canPlaceObject(ChunkManager $world, int $x, int $y, int $z) : bool{
47 return $world->getBlockAt($x, $y, $z)->hasSameTypeId($this->type->replaces);
48 }
49
50 public function placeObject(ChunkManager $world, int $x, int $y, int $z) : void{
51 $clusterSize = $this->type->clusterSize;
52 $angle = $this->random->nextFloat() * M_PI;
53 $offset = VectorMath::getDirection2D($angle)->multiply($clusterSize / 8);
54 $x1 = $x + 8 + $offset->x;
55 $x2 = $x + 8 - $offset->x;
56 $z1 = $z + 8 + $offset->y;
57 $z2 = $z + 8 - $offset->y;
58 $y1 = $y + $this->random->nextBoundedInt(3) + 2;
59 $y2 = $y + $this->random->nextBoundedInt(3) + 2;
60
61 $explorer = new SubChunkExplorer($world);
62
63 $tried = [];
64 $replaceableStateIds = [];
65 $materialStateId = $this->type->material->getStateId();
66 for($count = 0; $count <= $clusterSize; ++$count){
67 $centerX = $x1 + ($x2 - $x1) * $count / $clusterSize;
68 $centerY = $y1 + ($y2 - $y1) * $count / $clusterSize;
69 $centerZ = $z1 + ($z2 - $z1) * $count / $clusterSize;
70 $radius = ((sin($count * (M_PI / $clusterSize)) + 1) * $this->random->nextFloat() * $clusterSize / 16 + 1) / 2;
71
72 $this->placeSphere($world, $explorer, $centerX, $centerY, $centerZ, $radius, $tried, $replaceableStateIds, $materialStateId);
73 }
74 }
75
86 private function placeSphere(
87 ChunkManager $world,
88 SubChunkExplorer $explorer,
89 float $centerX,
90 float $centerY,
91 float $centerZ,
92 float $radius,
93 array &$visited,
94 array &$replaceableStateIds,
95 int $materialStateId
96 ) : void{
97 $startX = (int) ($centerX - $radius);
98 $startY = (int) ($centerY - $radius);
99 $startZ = (int) ($centerZ - $radius);
100 $endX = (int) ($centerX + $radius);
101 $endY = (int) ($centerY + $radius);
102 $endZ = (int) ($centerZ + $radius);
103
104 for($xx = $startX; $xx <= $endX; ++$xx){
105 $sizeX = ($xx + 0.5 - $centerX) / $radius;
106 $sizeX *= $sizeX;
107
108 if($sizeX < 1){
109 for($yy = $startY; $yy <= $endY; ++$yy){
110 $sizeY = ($yy + 0.5 - $centerY) / $radius;
111 $sizeY *= $sizeY;
112
113 if($yy > 0 && ($sizeX + $sizeY) < 1){
114 for($zz = $startZ; $zz <= $endZ; ++$zz){
115 $sizeZ = ($zz + 0.5 - $centerZ) / $radius;
116 $sizeZ *= $sizeZ;
117
118 if(($sizeX + $sizeY + $sizeZ) < 1){
119 $hash = World::blockHash($xx, $yy, $zz);
120 if(isset($visited[$hash])){
121 continue;
122 }
123 $visited[$hash] = true;
124 if($explorer->moveTo($xx, $yy, $zz) === SubChunkExplorerStatus::INVALID || $explorer->currentSubChunk === null){
125 throw new \LogicException("Unavailable chunk at block x=$xx, y=$yy, z=$zz");
126 }
127 $stateId = $explorer->currentSubChunk->getBlockStateId($xx & SubChunk::COORD_MASK, $yy & SubChunk::COORD_MASK, $zz & SubChunk::COORD_MASK);
128 $replaceable = $replaceableStateIds[$stateId] ??= $world->getBlockAt($xx, $yy, $zz)->hasSameTypeId($this->type->replaces);
129 if($replaceable){
130 $explorer->currentSubChunk->setBlockStateId($xx & SubChunk::COORD_MASK, $yy & SubChunk::COORD_MASK, $zz & SubChunk::COORD_MASK, $materialStateId);
131 }
132 }
133 }
134 }
135 }
136 }
137 }
138 }
139}
static blockHash(int $x, int $y, int $z)
Definition World.php:403
getBlockAt(int $x, int $y, int $z)