PocketMine-MP 5.36.1 git-eaa7c4834c8fe2f379d24e7f0ee6cc63cfb18ccc
Loading...
Searching...
No Matches
GroundCover.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
25
33use function count;
34use function min;
35
36class GroundCover implements Populator{
37
38 public function populate(ChunkManager $world, int $chunkX, int $chunkZ, Random $random) : void{
39 $chunk = $world->getChunk($chunkX, $chunkZ) ?? throw new \InvalidArgumentException("Chunk $chunkX $chunkZ does not yet exist");
40 $factory = RuntimeBlockStateRegistry::getInstance();
41 $biomeRegistry = BiomeRegistry::getInstance();
42 for($x = 0; $x < Chunk::EDGE_LENGTH; ++$x){
43 for($z = 0; $z < Chunk::EDGE_LENGTH; ++$z){
44 $biome = $biomeRegistry->getBiome($chunk->getBiomeId($x, 0, $z));
45 $cover = $biome->getGroundCover();
46 if(count($cover) > 0){
47 $diffY = 0;
48 if(!$cover[0]->isSolid()){
49 $diffY = 1;
50 }
51
52 $startY = $chunk->getHighestBlockAt($x, $z);
53 if($startY === null){
54 //ground cover is supposed to replace preexisting blocks, nothing to do if there are no blocks
55 continue;
56 }
57 for(; $startY > 0; --$startY){
58 if(!$factory->fromStateId($chunk->getBlockStateId($x, $startY, $z))->isTransparent()){
59 break;
60 }
61 }
62 $startY = min(127, $startY + $diffY);
63 $endY = $startY - count($cover);
64 for($y = $startY; $y > $endY && $y >= 0; --$y){
65 $b = $cover[$startY - $y];
66 $id = $factory->fromStateId($chunk->getBlockStateId($x, $y, $z));
67 if($id->getTypeId() === BlockTypeIds::AIR && $b->isSolid()){
68 break;
69 }
70 if($b->canBeFlowedInto() && $id instanceof Liquid){
71 continue;
72 }
73
74 $chunk->setBlockStateId($x, $y, $z, $b->getStateId());
75 }
76 }
77 }
78 }
79 }
80}