diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 452b998f3..8500567cb 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -616,7 +616,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ $Z = null; Level::getXZ($index, $X, $Z); - if(!$this->level->populateChunk($X, $Z)){ + if(!$this->level->populateChunk($X, $Z, !$this->spawned or count($this->usedChunks) < ($this->viewDistance - 24))){ if($this->spawned){ continue; }else{ diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 84cf4813b..9f3eaf85c 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -583,15 +583,15 @@ class Level implements ChunkManager, Metadatable{ $this->timings->doTickTiles->stopTiming(); if(count($this->changedBlocks) > 0){ - if(count($this->players) > 0){ + if(count($this->players) > 5){ foreach($this->changedBlocks as $index => $blocks){ + Level::getXZ($index, $X, $Z); if(count($blocks) > 512){ - Level::getXZ($index, $X, $Z); foreach($this->getUsingChunk($X, $Z) as $p){ $p->unloadChunk($X, $Z); } }else{ - $this->sendBlocks($this->getUsingChunk($pos->x >> 4, $pos->z >> 4), $blocks); + $this->sendBlocks($this->getUsingChunk($X, $Z), $blocks); } } } @@ -1821,14 +1821,18 @@ class Level implements ChunkManager, Metadatable{ } public function generateChunkCallback($x, $z, FullChunk $chunk){ - $oldChunk = $this->getChunk($x, $z, false); - unset($this->chunkGenerationQueue[Level::chunkHash($x, $z)]); - $chunk->setProvider($this->provider); - $this->setChunk($x, $z, $chunk); - $chunk = $this->getChunk($x, $z, false); - if($chunk !== null and ($oldChunk === null or $oldChunk->isPopulated() === false) and $chunk->isPopulated()){ - $this->server->getPluginManager()->callEvent(new ChunkPopulateEvent($chunk)); + Timings::$generationTimer->startTiming(); + if(isset($this->chunkGenerationQueue[$index = Level::chunkHash($x, $z)])){ + $oldChunk = $this->getChunk($x, $z, false); + unset($this->chunkGenerationQueue[$index = Level::chunkHash($x, $z)]); + $chunk->setProvider($this->provider); + $this->setChunk($x, $z, $chunk); + $chunk = $this->getChunk($x, $z, false); + if($chunk !== null and ($oldChunk === null or $oldChunk->isPopulated() === false) and $chunk->isPopulated() and $chunk->getProvider() !== null){ + $this->server->getPluginManager()->callEvent(new ChunkPopulateEvent($chunk)); + } } + Timings::$generationTimer->stopTiming(); } public function setChunk($x, $z, FullChunk $chunk, $unload = true){ @@ -2079,7 +2083,12 @@ class Level implements ChunkManager, Metadatable{ } } - $this->server->getPluginManager()->callEvent(new ChunkLoadEvent($chunk, !$chunk->isGenerated())); + if($chunk->getProvider() !== null){ + $this->server->getPluginManager()->callEvent(new ChunkLoadEvent($chunk, !$chunk->isGenerated())); + }else{ + $this->unloadChunk($x, $z, false); + return false; + } return true; } @@ -2114,7 +2123,7 @@ class Level implements ChunkManager, Metadatable{ $chunk = $this->getChunk($x, $z); - if($chunk !== null){ + if($chunk !== null and $chunk->getProvider() !== null){ $this->server->getPluginManager()->callEvent($ev = new ChunkUnloadEvent($chunk)); if($ev->isCancelled()){ return false; @@ -2291,24 +2300,30 @@ class Level implements ChunkManager, Metadatable{ } - public function populateChunk($x, $z){ + public function populateChunk($x, $z, $force = false){ if(!$this->isChunkPopulated($x, $z)){ $populate = true; for($xx = -1; $xx <= 1; ++$xx){ for($zz = -1; $zz <= 1; ++$zz){ if(!$this->isChunkGenerated($x + $xx, $z + $zz)){ $populate = false; - $this->generateChunk($x + $xx, $z + $zz); + $this->generateChunk($x + $xx, $z + $zz, $force); } } } if($this->chunksPopulated < $this->chunksPopulatedPerTick and $populate){ + Timings::$generationTimer->startTiming(); $this->generatorInstance->populateChunk($x, $z); $chunk = $this->getChunk($x, $z); $chunk->setPopulated(true); - $this->server->getPluginManager()->callEvent(new ChunkPopulateEvent($chunk)); + if($chunk->getProvider() !== null){ + $this->server->getPluginManager()->callEvent(new ChunkPopulateEvent($chunk)); + }else{ + $this->unloadChunk($x, $z, false); + } ++$this->chunksPopulated; + Timings::$generationTimer->stopTiming(); return true; } @@ -2317,10 +2332,15 @@ class Level implements ChunkManager, Metadatable{ return true; } - public function generateChunk($x, $z){ + public function generateChunk($x, $z, $force = false){ if(!isset($this->chunkGenerationQueue[$index = Level::chunkHash($x, $z)])){ - $this->chunkGenerationQueue[$index] = true; - $this->server->getGenerationManager()->requestChunk($this, $x, $z); + $this->chunkGenerationQueue[$index] = 0; + $this->server->getGenerationManager()->requestChunk($this, $x, $z, $this->getChunk($x, $z, true)); + }elseif($force){ + $value = ++$this->chunkGenerationQueue[$index]; + if($value % 40 === 0){ + $this->server->getGenerationManager()->requestChunk($this, $x, $z); + } } } diff --git a/src/pocketmine/level/generator/GenerationManager.php b/src/pocketmine/level/generator/GenerationManager.php index ad0c21dee..e8eb66a9e 100644 --- a/src/pocketmine/level/generator/GenerationManager.php +++ b/src/pocketmine/level/generator/GenerationManager.php @@ -177,8 +177,9 @@ class GenerationManager{ if($this->needsChunk[$levelID][0] === $chunk->getX() and $this->needsChunk[$levelID][1] === $chunk->getZ()){ $this->needsChunk[$levelID] = $chunk; } + }elseif(isset($this->levels[$levelID])){ + $this->levels[$levelID]->setChunk($chunk->getX(), $chunk->getZ(), $chunk); } - //TODO: set new received chunks } /** diff --git a/src/pocketmine/level/generator/GenerationRequestManager.php b/src/pocketmine/level/generator/GenerationRequestManager.php index bb7fa1499..c73b5990b 100644 --- a/src/pocketmine/level/generator/GenerationRequestManager.php +++ b/src/pocketmine/level/generator/GenerationRequestManager.php @@ -74,9 +74,12 @@ class GenerationRequestManager{ $this->generationThread->pushMainToThreadPacket($buffer); } - public function requestChunk(Level $level, $chunkX, $chunkZ){ + public function requestChunk(Level $level, $chunkX, $chunkZ, FullChunk $chunk = null){ $buffer = chr(GenerationManager::PACKET_REQUEST_CHUNK) . Binary::writeInt($level->getId()) . Binary::writeInt($chunkX) . Binary::writeInt($chunkZ); $this->generationThread->pushMainToThreadPacket($buffer); + if($chunk !== null){ + $this->sendChunk($level->getId(), $chunk); + } } protected function handleRequest($levelID, $chunkX, $chunkZ){ diff --git a/src/pocketmine/level/generator/biome/Biome.php b/src/pocketmine/level/generator/biome/Biome.php index aac148820..e4a1891f4 100644 --- a/src/pocketmine/level/generator/biome/Biome.php +++ b/src/pocketmine/level/generator/biome/Biome.php @@ -23,14 +23,16 @@ namespace pocketmine\level\generator\biome; use pocketmine\block\Block; use pocketmine\level\ChunkManager; -use pocketmine\level\generator\normal\biome\BeachBiome; +use pocketmine\level\generator\normal\biome\SwampBiome; use pocketmine\level\generator\normal\biome\DesertBiome; use pocketmine\level\generator\normal\biome\ForestBiome; +use pocketmine\level\generator\normal\biome\IcePlainsBiome; use pocketmine\level\generator\normal\biome\MountainsBiome; use pocketmine\level\generator\normal\biome\OceanBiome; use pocketmine\level\generator\normal\biome\PlainBiome; use pocketmine\level\generator\normal\biome\RiverBiome; use pocketmine\level\generator\normal\biome\SmallMountainsBiome; +use pocketmine\level\generator\normal\biome\TaigaBiome; use pocketmine\level\generator\populator\Populator; use pocketmine\utils\Random; @@ -41,14 +43,19 @@ abstract class Biome{ const DESERT = 2; const MOUNTAINS = 3; const FOREST = 4; - + const TAIGA = 5; + const SWAMP = 6; const RIVER = 7; - const BEACH = 16; + const ICE_PLAINS = 12; + const SMALL_MOUNTAINS = 20; + const BIRCH_FOREST = 27; + + const MAX_BIOMES = 256; /** @var Biome[] */ @@ -64,6 +71,9 @@ abstract class Biome{ private $groundCover = []; + protected $rainfall = 0.5; + protected $temperature = 0.5; + protected static function register($id, Biome $biome){ self::$biomes[(int) $id] = $biome; $biome->setId((int) $id); @@ -75,12 +85,17 @@ abstract class Biome{ self::register(self::DESERT, new DesertBiome()); self::register(self::MOUNTAINS, new MountainsBiome()); self::register(self::FOREST, new ForestBiome()); + self::register(self::TAIGA, new TaigaBiome()); self::register(self::RIVER, new RiverBiome()); - self::register(self::BEACH, new BeachBiome()); + self::register(self::ICE_PLAINS, new IcePlainsBiome()); + + self::register(self::SWAMP, new SwampBiome()); self::register(self::SMALL_MOUNTAINS, new SmallMountainsBiome()); + + self::register(self::BIRCH_FOREST, new ForestBiome(ForestBiome::TYPE_BIRCH)); } /** @@ -89,7 +104,7 @@ abstract class Biome{ * @return Biome */ public static function getBiome($id){ - return isset(self::$biomes[$id]) ? self::$biomes[$id] : null; + return isset(self::$biomes[$id]) ? self::$biomes[$id] : self::$biomes[self::OCEAN]; } public function clearPopulators(){ @@ -149,4 +164,18 @@ abstract class Biome{ public function setGroundCover(array $covers){ $this->groundCover = $covers; } + + public function getTemperature(){ + return $this->temperature; + } + + public function getRainfall(){ + return $this->rainfall; + } + + + /** + * @return int (randomness|Red|Green|Blue) + */ + abstract public function getColor(); } \ No newline at end of file diff --git a/src/pocketmine/level/generator/biome/BiomeSelector.php b/src/pocketmine/level/generator/biome/BiomeSelector.php index 3219e0027..a60fdd08d 100644 --- a/src/pocketmine/level/generator/biome/BiomeSelector.php +++ b/src/pocketmine/level/generator/biome/BiomeSelector.php @@ -37,17 +37,37 @@ class BiomeSelector{ /** @var Biome[] */ private $biomes = []; - private $select = []; + private $map = []; - public function __construct(Random $random, Biome $fallback){ + private $lookup; + + public function __construct(Random $random, callable $lookup, Biome $fallback){ $this->fallback = $fallback; - $this->temperature = new Simplex($random, 1, 0.004, 0.5, 2); - $this->rainfall = new Simplex($random, 2, 0.004, 0.5, 2); + $this->lookup = $lookup; + $this->temperature = new Simplex($random, 1, 0.001, 1, 1); + $this->rainfall = new Simplex($random, 1, 0.001, 1, 1); } - public function addBiome(Biome $biome, $start, $end){ + public function recalculate(){ + $this->map = new \SplFixedArray(64 * 64); + + for($i = 0; $i < 64; ++$i){ + for($j = 0; $j < 64; ++$j){ + $this->map[$i + ($j << 6)] = call_user_func($this->lookup, $i / 63, $j / 63); + } + } + } + + public function addBiome(Biome $biome){ $this->biomes[$biome->getId()] = $biome; - $this->select[$biome->getId()] = [$biome->getId(), $start, $end]; + } + + public function getTemperature($x, $z){ + return ($this->temperature->noise2D($x, $z, true) + 1) / 2; + } + + public function getRainfall($x, $z){ + return ($this->rainfall->noise2D($x, $z, true) + 1) / 2; } /** @@ -57,27 +77,10 @@ class BiomeSelector{ * @return Biome */ public function pickBiome($x, $z){ + $temperature = (int) ($this->getTemperature($x, $z) * 63); + $rainfall = (int) ($this->getRainfall($x, $z) * 63); - //$temperature = $this->temperature->noise2D($x, $z); - $rainfall = $this->rainfall->noise2D($x, $z); - - if($rainfall > 0.9){ - return Biome::getBiome(Biome::OCEAN); - }elseif($rainfall > 0.7){ - return Biome::getBiome(Biome::RIVER); - }elseif($rainfall > 0.6){ - return Biome::getBiome(Biome::BEACH); - }elseif($rainfall > 0.2){ - return Biome::getBiome(Biome::FOREST); - }elseif($rainfall > -0.3){ - return Biome::getBiome(Biome::PLAINS); - }elseif($rainfall > -0.6){ - return Biome::getBiome(Biome::DESERT); - }elseif($rainfall > -0.7){ - return Biome::getBiome(Biome::BEACH); - }else{ - return Biome::getBiome(Biome::OCEAN); - } - + $biomeId = $this->map[$temperature + ($rainfall << 6)]; + return isset($this->biomes[$biomeId]) ? $this->biomes[$biomeId] : $this->fallback; } } \ No newline at end of file diff --git a/src/pocketmine/level/generator/normal/Normal.php b/src/pocketmine/level/generator/normal/Normal.php index e36c1299e..87a8b16ef 100644 --- a/src/pocketmine/level/generator/normal/Normal.php +++ b/src/pocketmine/level/generator/normal/Normal.php @@ -83,9 +83,7 @@ class Normal extends Generator{ $bellHeight = 2 * self::$SMOOTH_SIZE; for($sx = -self::$SMOOTH_SIZE; $sx <= self::$SMOOTH_SIZE; ++$sx){ for($sz = -self::$SMOOTH_SIZE; $sz <= self::$SMOOTH_SIZE; ++$sz){ - $bx = $bellSize * $sx; - $bz = $bellSize * $sz; - self::$GAUSSIAN_KERNEL[$sx + self::$SMOOTH_SIZE][$sz + self::$SMOOTH_SIZE] = $bellHeight * exp(-($bx * $bx + $bz * $bz) / 2); + self::$GAUSSIAN_KERNEL[$sx + self::$SMOOTH_SIZE][$sz + self::$SMOOTH_SIZE] = 10 / sqrt($sx ** 2 + $sz ** 2 + 0.2); } } } @@ -102,9 +100,54 @@ class Normal extends Generator{ $this->level = $level; $this->random = $random; $this->random->setSeed($this->level->getSeed()); - $this->noiseBase = new Simplex($this->random, 16, 0.012, 0.5, 2); + $this->noiseBase = new Simplex($this->random, 16, 0.02, 0.5, 2); $this->random->setSeed($this->level->getSeed()); - $this->selector = new BiomeSelector($this->random, Biome::getBiome(Biome::OCEAN)); + $this->selector = new BiomeSelector($this->random, function($temperature, $rainfall){ + $rainfall *= $temperature; + if($temperature < 0.10){ + return Biome::ICE_PLAINS; + }elseif($rainfall < 0.20){ + if($temperature < 0.50){ + return Biome::ICE_PLAINS; + }elseif($temperature < 0.95){ + return Biome::SMALL_MOUNTAINS; + }else{ + return Biome::DESERT; + } + }elseif($rainfall > 0.5 and $temperature < 0.7){ + return Biome::SWAMP; + }elseif($temperature < 0.50){ + return Biome::TAIGA; + }elseif($temperature < 0.97){ + if($rainfall < 0.35){ + return Biome::MOUNTAINS; + }else { + return Biome::RIVER; + } + }else{ + if($rainfall < 0.45){ + return Biome::PLAINS; + }elseif($rainfall < 0.90){ + return Biome::FOREST; + }else{ + return Biome::BIRCH_FOREST; + } + } + }, Biome::getBiome(Biome::OCEAN)); + + $this->selector->addBiome(Biome::getBiome(Biome::OCEAN)); + $this->selector->addBiome(Biome::getBiome(Biome::PLAINS)); + $this->selector->addBiome(Biome::getBiome(Biome::DESERT)); + $this->selector->addBiome(Biome::getBiome(Biome::MOUNTAINS)); + $this->selector->addBiome(Biome::getBiome(Biome::FOREST)); + $this->selector->addBiome(Biome::getBiome(Biome::TAIGA)); + $this->selector->addBiome(Biome::getBiome(Biome::SWAMP)); + $this->selector->addBiome(Biome::getBiome(Biome::RIVER)); + $this->selector->addBiome(Biome::getBiome(Biome::ICE_PLAINS)); + $this->selector->addBiome(Biome::getBiome(Biome::SMALL_MOUNTAINS)); + $this->selector->addBiome(Biome::getBiome(Biome::BIRCH_FOREST)); + + $this->selector->recalculate(); $cover = new GroundCover(); $this->generationPopulators[] = $cover; @@ -127,7 +170,7 @@ class Normal extends Generator{ public function generateChunk($chunkX, $chunkZ){ $this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->level->getSeed()); - $noise = Generator::getFastNoise3D($this->noiseBase, 16, 128, 16, 8, 8, 8, $chunkX * 16, 0, $chunkZ * 16); + $noise = Generator::getFastNoise3D($this->noiseBase, 16, 128, 16, 4, 8, 4, $chunkX * 16, 0, $chunkZ * 16); $chunk = $this->level->getChunk($chunkX, $chunkZ); @@ -139,16 +182,16 @@ class Normal extends Generator{ $biome = $this->selector->pickBiome($chunkX * 16 + $x, $chunkZ * 16 + $z); $chunk->setBiomeId($x, $z, $biome->getId()); - $chunk->setBiomeColor($x, $z, 255 - (($biome->getId() * 1377) % 255), 255 - (($biome->getId() * 4096) % 255), 255 - (($biome->getId() * 31337) % 255)); + $color = $biome->getColor(); + $chunk->setBiomeColor($x, $z, $color >> 16, ($color >> 8) & 0xff, $color & 0xff); for($sx = -self::$SMOOTH_SIZE; $sx <= self::$SMOOTH_SIZE; ++$sx){ for($sz = -self::$SMOOTH_SIZE; $sz <= self::$SMOOTH_SIZE; ++$sz){ if($sx === 0 and $sz === 0){ - $adjacent = $biome; + continue; }else{ - $adjacent = $this->selector->pickBiome($chunkX * 16 + $x + $sx * 16, $chunkZ * 16 + $z + $sz * 16); + $adjacent = $this->selector->pickBiome($chunkX * 16 + $x + $sx * 8, $chunkZ * 16 + $z + $sz * 8); } - /** @var NormalBiome $adjacent */ $weight = self::$GAUSSIAN_KERNEL[$sx + self::$SMOOTH_SIZE][$sz + self::$SMOOTH_SIZE]; $minSum += $adjacent->getMinElevation() * $weight; $maxSum += $adjacent->getMaxElevation() * $weight; diff --git a/src/pocketmine/level/generator/normal/biome/DesertBiome.php b/src/pocketmine/level/generator/normal/biome/DesertBiome.php index 424fbbb7c..b0d8399ef 100644 --- a/src/pocketmine/level/generator/normal/biome/DesertBiome.php +++ b/src/pocketmine/level/generator/normal/biome/DesertBiome.php @@ -28,6 +28,9 @@ class DesertBiome extends SandyBiome{ public function __construct(){ parent::__construct(); $this->setElevation(63, 74); + + $this->temperature = 2; + $this->rainfall = 0; } public function getName(){ diff --git a/src/pocketmine/level/generator/normal/biome/ForestBiome.php b/src/pocketmine/level/generator/normal/biome/ForestBiome.php index be18d7498..2291297e9 100644 --- a/src/pocketmine/level/generator/normal/biome/ForestBiome.php +++ b/src/pocketmine/level/generator/normal/biome/ForestBiome.php @@ -21,15 +21,23 @@ namespace pocketmine\level\generator\normal\biome; +use pocketmine\block\Sapling; use pocketmine\level\generator\populator\TallGrass; use pocketmine\level\generator\populator\Tree; class ForestBiome extends GrassyBiome{ - public function __construct(){ + const TYPE_NORMAL = 0; + const TYPE_BIRCH = 1; + + public $type; + + public function __construct($type = self::TYPE_NORMAL){ parent::__construct(); - $trees = new Tree(); + $this->type = $type; + + $trees = new Tree($type === self::TYPE_BIRCH ? Sapling::BIRCH : Sapling::OAK); $trees->setBaseAmount(5); $this->addPopulator($trees); @@ -39,9 +47,21 @@ class ForestBiome extends GrassyBiome{ $this->addPopulator($tallGrass); $this->setElevation(63, 81); + + if($type === self::TYPE_BIRCH){ + $this->temperature = 0.5; + $this->rainfall = 0.5; + }else{ + $this->temperature = 0.7; + $this->temperature = 0.8; + } } public function getName(){ - return "Forest"; + return $this->type === self::TYPE_BIRCH ? "Birch Forest" : "Forest"; + } + + public function getColor(){ + return 0x056621; } } \ No newline at end of file diff --git a/src/pocketmine/level/generator/normal/biome/IcePlainsBiome.php b/src/pocketmine/level/generator/normal/biome/IcePlainsBiome.php new file mode 100644 index 000000000..5bd79fda9 --- /dev/null +++ b/src/pocketmine/level/generator/normal/biome/IcePlainsBiome.php @@ -0,0 +1,49 @@ +setBaseAmount(5); + + $this->addPopulator($tallGrass); + + $this->setElevation(63, 74); + + $this->temperature = 0.05; + $this->rainfall = 0.8; + } + + public function getName(){ + return "Ice Plains"; + } + + public function getColor(){ + return 0x163933; + } +} \ No newline at end of file diff --git a/src/pocketmine/level/generator/normal/biome/MountainsBiome.php b/src/pocketmine/level/generator/normal/biome/MountainsBiome.php index f0854ab1f..20306015f 100644 --- a/src/pocketmine/level/generator/normal/biome/MountainsBiome.php +++ b/src/pocketmine/level/generator/normal/biome/MountainsBiome.php @@ -41,6 +41,9 @@ class MountainsBiome extends GrassyBiome{ //TODO: add emerald $this->setElevation(63, 127); + + $this->temperature = 0.4; + $this->rainfall = 0.5; } public function getName(){ diff --git a/src/pocketmine/level/generator/normal/biome/NormalBiome.php b/src/pocketmine/level/generator/normal/biome/NormalBiome.php index e9d647b61..207f8ae9f 100644 --- a/src/pocketmine/level/generator/normal/biome/NormalBiome.php +++ b/src/pocketmine/level/generator/normal/biome/NormalBiome.php @@ -24,5 +24,7 @@ namespace pocketmine\level\generator\normal\biome; use pocketmine\level\generator\biome\Biome; abstract class NormalBiome extends Biome{ - + public function getColor(){ + return 0xffb360; //Detect wrong biomes + } } diff --git a/src/pocketmine/level/generator/normal/biome/OceanBiome.php b/src/pocketmine/level/generator/normal/biome/OceanBiome.php index 92bb99d2a..8449386b1 100644 --- a/src/pocketmine/level/generator/normal/biome/OceanBiome.php +++ b/src/pocketmine/level/generator/normal/biome/OceanBiome.php @@ -34,9 +34,16 @@ class OceanBiome extends GrassyBiome{ $this->addPopulator($tallGrass); $this->setElevation(46, 58); + + $this->temperature = 0.5; + $this->rainfall = 0.5; } public function getName(){ return "Ocean"; } + + public function getColor(){ + return 0x8da360; + } } \ No newline at end of file diff --git a/src/pocketmine/level/generator/normal/biome/PlainBiome.php b/src/pocketmine/level/generator/normal/biome/PlainBiome.php index e48a6eee8..625646009 100644 --- a/src/pocketmine/level/generator/normal/biome/PlainBiome.php +++ b/src/pocketmine/level/generator/normal/biome/PlainBiome.php @@ -29,14 +29,21 @@ class PlainBiome extends GrassyBiome{ parent::__construct(); $tallGrass = new TallGrass(); - $tallGrass->setBaseAmount(5); + $tallGrass->setBaseAmount(12); $this->addPopulator($tallGrass); $this->setElevation(63, 74); + + $this->temperature = 0.8; + $this->rainfall = 0.4; } public function getName(){ return "Plains"; } + + public function getColor(){ + return 0x8db360; + } } \ No newline at end of file diff --git a/src/pocketmine/level/generator/normal/biome/RiverBiome.php b/src/pocketmine/level/generator/normal/biome/RiverBiome.php index fcedca423..72621b114 100644 --- a/src/pocketmine/level/generator/normal/biome/RiverBiome.php +++ b/src/pocketmine/level/generator/normal/biome/RiverBiome.php @@ -34,9 +34,16 @@ class RiverBiome extends GrassyBiome{ $this->addPopulator($tallGrass); $this->setElevation(58, 62); + + $this->temperature = 0.5; + $this->rainfall = 0.7; } public function getName(){ return "River"; } + + public function getColor(){ + return 0x8dc360; + } } \ No newline at end of file diff --git a/src/pocketmine/level/generator/normal/biome/SnowyBiome.php b/src/pocketmine/level/generator/normal/biome/SnowyBiome.php new file mode 100644 index 000000000..067c031a6 --- /dev/null +++ b/src/pocketmine/level/generator/normal/biome/SnowyBiome.php @@ -0,0 +1,37 @@ +setGroundCover([ + Block::get(Block::SNOW_LAYER, 0), + Block::get(Block::GRASS, 0), + Block::get(Block::DIRT, 0), + Block::get(Block::DIRT, 0), + Block::get(Block::DIRT, 0), + ]); + } +} \ No newline at end of file diff --git a/src/pocketmine/level/generator/normal/biome/BeachBiome.php b/src/pocketmine/level/generator/normal/biome/SwampBiome.php similarity index 81% rename from src/pocketmine/level/generator/normal/biome/BeachBiome.php rename to src/pocketmine/level/generator/normal/biome/SwampBiome.php index 2c67883da..2613ce3da 100644 --- a/src/pocketmine/level/generator/normal/biome/BeachBiome.php +++ b/src/pocketmine/level/generator/normal/biome/SwampBiome.php @@ -21,15 +21,22 @@ namespace pocketmine\level\generator\normal\biome; -class BeachBiome extends GrassyBiome{ +class SwampBiome extends GrassyBiome{ public function __construct(){ parent::__construct(); - $this->setElevation(62, 65); + $this->setElevation(62, 63); + + $this->temperature = 0.8; + $this->rainfall = 0.9; } public function getName(){ - return "Beach"; + return "Swamp"; + } + + public function getColor(){ + return 0x07f9b2; } } \ No newline at end of file diff --git a/src/pocketmine/level/generator/normal/biome/TaigaBiome.php b/src/pocketmine/level/generator/normal/biome/TaigaBiome.php new file mode 100644 index 000000000..9bbb5307c --- /dev/null +++ b/src/pocketmine/level/generator/normal/biome/TaigaBiome.php @@ -0,0 +1,55 @@ +setBaseAmount(10); + $this->addPopulator($trees); + + $tallGrass = new TallGrass(); + $tallGrass->setBaseAmount(1); + + $this->addPopulator($tallGrass); + + $this->setElevation(63, 81); + + $this->temperature = 0.05; + $this->rainfall = 0.8; + } + + public function getName(){ + return "Taiga"; + } + + public function getColor(){ + return 0x0b6659; + } +} \ No newline at end of file diff --git a/src/pocketmine/level/generator/object/Tree.php b/src/pocketmine/level/generator/object/Tree.php index 1ec2ee45a..15b6a013e 100644 --- a/src/pocketmine/level/generator/object/Tree.php +++ b/src/pocketmine/level/generator/object/Tree.php @@ -21,6 +21,7 @@ namespace pocketmine\level\generator\object; +use pocketmine\block\Block; use pocketmine\block\Sapling; use pocketmine\level\ChunkManager; use pocketmine\utils\Random; @@ -33,6 +34,9 @@ class Tree{ 6 => true, 17 => true, 18 => true, + Block::SNOW_LAYER => true, + Block::LOG2 => true, + Block::LEAVES2 => true ]; public static function growTree(ChunkManager $level, $x, $y, $z, Random $random, $type = 0){ diff --git a/src/pocketmine/level/generator/populator/GroundCover.php b/src/pocketmine/level/generator/populator/GroundCover.php index e1ba3f55b..dab6dbaae 100644 --- a/src/pocketmine/level/generator/populator/GroundCover.php +++ b/src/pocketmine/level/generator/populator/GroundCover.php @@ -35,16 +35,24 @@ class GroundCover extends Populator{ $biome = Biome::getBiome($chunk->getBiomeId($x, $z)); $cover = $biome->getGroundCover(); if(count($cover) > 0){ + $diffY = 0; + if(!$cover[0]->isSolid()){ + $diffY = 1; + } + $column = $chunk->getBlockIdColumn($x, $z); for($y = 127; $y > 0; --$y){ - if($column{$y} !== "\x00" and Block::get(ord($column{$y}))->isSolid()){ + if($column{$y} !== "\x00" and !Block::get(ord($column{$y}))->isTransparent()){ break; } } - $startY = $y; + $startY = min(127, $y + $diffY); $endY = $startY - count($cover); for($y = $startY; $y > $endY and $y >= 0; --$y){ $b = $cover[$startY - $y]; + if($column{$y} === "\x00" and $b->isSolid()){ + break; + } if($b->getDamage() === 0){ $chunk->setBlockId($x, $y, $z, $b->getId()); }else{ diff --git a/src/pocketmine/level/generator/populator/TallGrass.php b/src/pocketmine/level/generator/populator/TallGrass.php index 2adcd0519..03438b5c7 100644 --- a/src/pocketmine/level/generator/populator/TallGrass.php +++ b/src/pocketmine/level/generator/populator/TallGrass.php @@ -43,37 +43,30 @@ class TallGrass extends Populator{ $this->level = $level; $amount = $random->nextRange(0, $this->randomAmount + 1) + $this->baseAmount; for($i = 0; $i < $amount; ++$i){ - $x = $random->nextRange($chunkX << 4, ($chunkX << 4) + 15); - $z = $random->nextRange($chunkZ << 4, ($chunkZ << 4) + 15); - for($size = 30; $size > 0; --$size){ - $xx = $x - 7 + $random->nextRange(0, 15); - $zz = $z - 7 + $random->nextRange(0, 15); - $yy = $this->getHighestWorkableBlock($xx, $zz); + $x = $random->nextRange($chunkX * 16, $chunkX * 16 + 15); + $z = $random->nextRange($chunkZ * 16, $chunkZ * 16 + 15); + $y = $this->getHighestWorkableBlock($x, $z); - if($yy !== -1 and $this->canTallGrassStay($xx, $yy, $zz)){ - $this->level->setBlockIdAt($xx, $yy, $zz, Block::TALL_GRASS); - $this->level->setBlockDataAt($xx, $yy, $zz, 1); - } + if($y !== -1 and $this->canTallGrassStay($x, $y, $z)){ + $this->level->setBlockIdAt($x, $y, $z, Block::TALL_GRASS); + $this->level->setBlockDataAt($x, $y, $z, 1); } } } private function canTallGrassStay($x, $y, $z){ - return $this->level->getBlockIdAt($x, $y, $z) === Block::AIR and $this->level->getBlockIdAt($x, $y - 1, $z) === Block::GRASS; + $b = $this->level->getBlockIdAt($x, $y, $z); + return ($b === Block::AIR or $b === Block::SNOW_LAYER) and $this->level->getBlockIdAt($x, $y - 1, $z) === Block::GRASS; } private function getHighestWorkableBlock($x, $z){ - for($y = 128; $y > 0; --$y){ + for($y = 127; $y >= 0; --$y){ $b = $this->level->getBlockIdAt($x, $y, $z); - if($b === Block::AIR or $b === Block::LEAVES){ - if(--$y <= 0){ - return -1; - } - }else{ + if($b !== Block::AIR and $b !== Block::LEAVES and $b !== Block::SNOW_LAYER){ break; } } - return ++$y; + return $y === 0 ? -1 : ++$y; } } \ No newline at end of file diff --git a/src/pocketmine/level/generator/populator/Tree.php b/src/pocketmine/level/generator/populator/Tree.php index 27243ef46..792d3f217 100644 --- a/src/pocketmine/level/generator/populator/Tree.php +++ b/src/pocketmine/level/generator/populator/Tree.php @@ -33,6 +33,12 @@ class Tree extends Populator{ private $randomAmount; private $baseAmount; + private $type; + + public function __construct($type = Sapling::OAK){ + $this->type = $type; + } + public function setRandomAmount($amount){ $this->randomAmount = $amount; } @@ -51,24 +57,17 @@ class Tree extends Populator{ if($y === -1){ continue; } - if($random->nextFloat() > 0.75){ - $meta = Sapling::BIRCH; - }else{ - $meta = Sapling::OAK; - } - ObjectTree::growTree($this->level, $x, $y, $z, $random, $meta); + ObjectTree::growTree($this->level, $x, $y, $z, $random, $this->type); } } private function getHighestWorkableBlock($x, $z){ - for($y = 128; $y > 0; --$y){ + for($y = 127; $y > 0; --$y){ $b = $this->level->getBlockIdAt($x, $y, $z); - if($b !== Block::DIRT and $b !== Block::GRASS){ - if(--$y <= 0){ - return -1; - } - }else{ + if($b === Block::DIRT or $b === Block::GRASS){ break; + }elseif($b !== 0 and $b !== Block::SNOW_LAYER){ + return -1; } } diff --git a/src/spl b/src/spl index 5ad5b3535..3db41e126 160000 --- a/src/spl +++ b/src/spl @@ -1 +1 @@ -Subproject commit 5ad5b3535c9519b2e013a61a2d55fccae014e037 +Subproject commit 3db41e1266811b20c3f52f749265f6c9d416c1bb