PocketMine-MP 5.36.1 git-eaa7c4834c8fe2f379d24e7f0ee6cc63cfb18ccc
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 $seedX = $x1 + ($x2 - $x1) * $count / $clusterSize;
68 $seedY = $y1 + ($y2 - $y1) * $count / $clusterSize;
69 $seedZ = $z1 + ($z2 - $z1) * $count / $clusterSize;
70 $size = ((sin($count * (M_PI / $clusterSize)) + 1) * $this->random->nextFloat() * $clusterSize / 16 + 1) / 2;
71
72 $startX = (int) ($seedX - $size);
73 $startY = (int) ($seedY - $size);
74 $startZ = (int) ($seedZ - $size);
75 $endX = (int) ($seedX + $size);
76 $endY = (int) ($seedY + $size);
77 $endZ = (int) ($seedZ + $size);
78
79 for($xx = $startX; $xx <= $endX; ++$xx){
80 $sizeX = ($xx + 0.5 - $seedX) / $size;
81 $sizeX *= $sizeX;
82
83 if($sizeX < 1){
84 for($yy = $startY; $yy <= $endY; ++$yy){
85 $sizeY = ($yy + 0.5 - $seedY) / $size;
86 $sizeY *= $sizeY;
87
88 if($yy > 0 && ($sizeX + $sizeY) < 1){
89 for($zz = $startZ; $zz <= $endZ; ++$zz){
90 $sizeZ = ($zz + 0.5 - $seedZ) / $size;
91 $sizeZ *= $sizeZ;
92
93 if(($sizeX + $sizeY + $sizeZ) < 1){
94 $hash = World::blockHash($xx, $yy, $zz);
95 if(isset($tried[$hash])){
96 continue;
97 }
98 $tried[$hash] = true;
99 if($explorer->moveTo($xx, $yy, $zz) === SubChunkExplorerStatus::INVALID || $explorer->currentSubChunk === null){
100 throw new \LogicException("Unavailable chunk at block x=$xx, y=$yy, z=$zz");
101 }
102 $stateId = $explorer->currentSubChunk->getBlockStateId($xx & SubChunk::COORD_MASK, $yy & SubChunk::COORD_MASK, $zz & SubChunk::COORD_MASK);
103 $replaceable = $replaceableStateIds[$stateId] ??= $world->getBlockAt($xx, $yy, $zz)->hasSameTypeId($this->type->replaces);
104 if($replaceable){
105 $explorer->currentSubChunk->setBlockStateId($xx & SubChunk::COORD_MASK, $yy & SubChunk::COORD_MASK, $zz & SubChunk::COORD_MASK, $materialStateId);
106 }
107 }
108 }
109 }
110 }
111 }
112 }
113 }
114 }
115}
static blockHash(int $x, int $y, int $z)
Definition World.php:403
getBlockAt(int $x, int $y, int $z)