mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-17 11:18:52 +00:00
Automatic population on side loading
This commit is contained in:
parent
5d7198396d
commit
715e51b7c5
@ -145,8 +145,6 @@ class PMFLevel extends PMF{
|
|||||||
$X = $index & 0x0F;
|
$X = $index & 0x0F;
|
||||||
$Z = $index >> 4;
|
$Z = $index >> 4;
|
||||||
|
|
||||||
$this->chunks[$index] = false;
|
|
||||||
$this->chunkChange[$index] = false;
|
|
||||||
$bitflags = Utils::readShort($this->read(2));
|
$bitflags = Utils::readShort($this->read(2));
|
||||||
$oldPath = dirname($this->file)."/chunks/".$Z.".".$X.".pmc";
|
$oldPath = dirname($this->file)."/chunks/".$Z.".".$X.".pmc";
|
||||||
$chunkOld = gzopen($oldPath, "rb");
|
$chunkOld = gzopen($oldPath, "rb");
|
||||||
@ -186,15 +184,36 @@ class PMFLevel extends PMF{
|
|||||||
if(!file_exists(dirname($path))){
|
if(!file_exists(dirname($path))){
|
||||||
@mkdir(dirname($path), 0755);
|
@mkdir(dirname($path), 0755);
|
||||||
}
|
}
|
||||||
++$this->isGenerating;
|
|
||||||
$this->initCleanChunk($X, $Z);
|
$this->initCleanChunk($X, $Z);
|
||||||
$ret = $this->level->generateChunk($X, $Z);
|
$ret = $this->level->generateChunk($X, $Z);
|
||||||
$ret = $ret and $this->level->populateChunk($X, $Z);
|
|
||||||
$this->saveChunk($X, $Z);
|
$this->saveChunk($X, $Z);
|
||||||
--$this->isGenerating;
|
$this->populateChunk($X - 1, $Z);
|
||||||
|
$this->populateChunk($X + 1, $Z);
|
||||||
|
$this->populateChunk($X, $Z - 1);
|
||||||
|
$this->populateChunk($X, $Z + 1);
|
||||||
|
$this->populateChunk($X + 1, $Z + 1);
|
||||||
|
$this->populateChunk($X + 1, $Z - 1);
|
||||||
|
$this->populateChunk($X - 1, $Z - 1);
|
||||||
|
$this->populateChunk($X - 1, $Z + 1);
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function populateChunk($X, $Z){
|
||||||
|
if($this->isGenerating === 0 and
|
||||||
|
!$this->isPopulated($X, $Z) and
|
||||||
|
$this->isGenerated($X - 1, $Z) and
|
||||||
|
$this->isGenerated($X, $Z - 1) and
|
||||||
|
$this->isGenerated($X + 1, $Z) and
|
||||||
|
$this->isGenerated($X, $Z + 1) and
|
||||||
|
$this->isGenerated($X + 1, $Z + 1) and
|
||||||
|
$this->isGenerated($X - 1, $Z - 1) and
|
||||||
|
$this->isGenerated($X + 1, $Z - 1) and
|
||||||
|
$this->isGenerated($X - 1, $Z + 1)){
|
||||||
|
$this->level->populateChunk($X, $Z);
|
||||||
|
$this->saveChunk($X, $Z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function loadChunk($X, $Z){
|
public function loadChunk($X, $Z){
|
||||||
$X = (int) $X;
|
$X = (int) $X;
|
||||||
$Z = (int) $Z;
|
$Z = (int) $Z;
|
||||||
@ -206,16 +225,13 @@ class PMFLevel extends PMF{
|
|||||||
if(!file_exists($path)){
|
if(!file_exists($path)){
|
||||||
if($this->isGenerating > 0){
|
if($this->isGenerating > 0){
|
||||||
$this->level->generateChunk($X, $Z);
|
$this->level->generateChunk($X, $Z);
|
||||||
$this->saveChunk($X, $Z);
|
|
||||||
}elseif($this->generateChunk($X, $Z) === false){
|
}elseif($this->generateChunk($X, $Z) === false){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($this->isGenerating === 0 and !$this->isPopulated($X, $Z)){
|
if($this->isGenerating === 0 and !$this->isPopulated($X, $Z)){
|
||||||
++$this->isGenerating;
|
$this->populateChunk($X, $Z);
|
||||||
$this->level->populateChunk($X, $Z);
|
|
||||||
--$this->isGenerating;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$chunk = @gzopen($path, "rb");
|
$chunk = @gzopen($path, "rb");
|
||||||
@ -262,15 +278,15 @@ class PMFLevel extends PMF{
|
|||||||
|
|
||||||
public function isChunkLoaded($X, $Z){
|
public function isChunkLoaded($X, $Z){
|
||||||
$index = self::getIndex($X, $Z);
|
$index = self::getIndex($X, $Z);
|
||||||
if(!isset($this->chunks[$index]) or $this->chunks[$index] === false){
|
if(!isset($this->chunks[$index])){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function isMiniChunkEmpty($X, $Z, $Y){
|
public function isMiniChunkEmpty($X, $Z, $Y){
|
||||||
$index = self::getIndex($X, $Z);
|
$index = self::getIndex($X, $Z);
|
||||||
if($this->chunks[$index][$Y] !== false){
|
if(isset($this->chunks[$index]) and $this->chunks[$index][$Y] !== false){
|
||||||
if(substr_count($this->chunks[$index][$Y], "\x00") < 8192){
|
if(substr_count($this->chunks[$index][$Y], "\x00") < 8192){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -314,7 +330,17 @@ class PMFLevel extends PMF{
|
|||||||
6 => false,
|
6 => false,
|
||||||
7 => false,
|
7 => false,
|
||||||
);
|
);
|
||||||
$this->chunkChange[$index] = array(-1 => false);
|
$this->chunkChange[$index] = array(
|
||||||
|
-1 => true,
|
||||||
|
0 => 8192,
|
||||||
|
1 => 8192,
|
||||||
|
2 => 8192,
|
||||||
|
3 => 8192,
|
||||||
|
4 => 8192,
|
||||||
|
5 => 8192,
|
||||||
|
6 => 8192,
|
||||||
|
7 => 8192,
|
||||||
|
);
|
||||||
$this->chunkInfo[$index] = array(
|
$this->chunkInfo[$index] = array(
|
||||||
0 => 0,
|
0 => 0,
|
||||||
1 => 0,
|
1 => 0,
|
||||||
@ -347,7 +373,7 @@ class PMFLevel extends PMF{
|
|||||||
$Z = $z >> 4;
|
$Z = $z >> 4;
|
||||||
$Y = $y >> 4;
|
$Y = $y >> 4;
|
||||||
$index = self::getIndex($X, $Z);
|
$index = self::getIndex($X, $Z);
|
||||||
if(!isset($this->chunks[$index]) or $this->chunks[$index] === false){
|
if(!isset($this->chunks[$index])){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
$aX = $x - ($X << 4);
|
$aX = $x - ($X << 4);
|
||||||
@ -366,7 +392,7 @@ class PMFLevel extends PMF{
|
|||||||
$Y = $y >> 4;
|
$Y = $y >> 4;
|
||||||
$block &= 0xFF;
|
$block &= 0xFF;
|
||||||
$index = self::getIndex($X, $Z);
|
$index = self::getIndex($X, $Z);
|
||||||
if(!isset($this->chunks[$index]) or $this->chunks[$index] === false){
|
if(!isset($this->chunks[$index])){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$aX = $x - ($X << 4);
|
$aX = $x - ($X << 4);
|
||||||
@ -390,7 +416,7 @@ class PMFLevel extends PMF{
|
|||||||
$Z = $z >> 4;
|
$Z = $z >> 4;
|
||||||
$Y = $y >> 4;
|
$Y = $y >> 4;
|
||||||
$index = self::getIndex($X, $Z);
|
$index = self::getIndex($X, $Z);
|
||||||
if(!isset($this->chunks[$index]) or $this->chunks[$index] === false){
|
if(!isset($this->chunks[$index])){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
$aX = $x - ($X << 4);
|
$aX = $x - ($X << 4);
|
||||||
@ -414,7 +440,7 @@ class PMFLevel extends PMF{
|
|||||||
$Y = $y >> 4;
|
$Y = $y >> 4;
|
||||||
$damage &= 0x0F;
|
$damage &= 0x0F;
|
||||||
$index = self::getIndex($X, $Z);
|
$index = self::getIndex($X, $Z);
|
||||||
if(!isset($this->chunks[$index]) or $this->chunks[$index] === false){
|
if(!isset($this->chunks[$index])){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$aX = $x - ($X << 4);
|
$aX = $x - ($X << 4);
|
||||||
@ -449,7 +475,7 @@ class PMFLevel extends PMF{
|
|||||||
return array(AIR, 0);
|
return array(AIR, 0);
|
||||||
}
|
}
|
||||||
$index = self::getIndex($X, $Z);
|
$index = self::getIndex($X, $Z);
|
||||||
if(!isset($this->chunks[$index]) or $this->chunks[$index] === false){
|
if(!isset($this->chunks[$index])){
|
||||||
if($this->loadChunk($X, $Z) === false){
|
if($this->loadChunk($X, $Z) === false){
|
||||||
return array(AIR, 0);
|
return array(AIR, 0);
|
||||||
}
|
}
|
||||||
@ -479,7 +505,7 @@ class PMFLevel extends PMF{
|
|||||||
$block &= 0xFF;
|
$block &= 0xFF;
|
||||||
$meta &= 0x0F;
|
$meta &= 0x0F;
|
||||||
$index = self::getIndex($X, $Z);
|
$index = self::getIndex($X, $Z);
|
||||||
if(!isset($this->chunks[$index]) or $this->chunks[$index] === false){
|
if(!isset($this->chunks[$index])){
|
||||||
if($this->loadChunk($X, $Z) === false){
|
if($this->loadChunk($X, $Z) === false){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -552,7 +578,7 @@ class PMFLevel extends PMF{
|
|||||||
}
|
}
|
||||||
$chunk = @gzopen($path, "wb".PMFLevel::DEFLATE_LEVEL);
|
$chunk = @gzopen($path, "wb".PMFLevel::DEFLATE_LEVEL);
|
||||||
gzwrite($chunk, chr($bitmap));
|
gzwrite($chunk, chr($bitmap));
|
||||||
gzwrite($chunk, Utils::writeInt($this->chunkInfo[$index][0]));
|
gzwrite($chunk, Utils::writeInt($this->chunkInfo[$index][1]));
|
||||||
for($Y = 0; $Y < 8; ++$Y){
|
for($Y = 0; $Y < 8; ++$Y){
|
||||||
$t = 1 << $Y;
|
$t = 1 << $Y;
|
||||||
if(($bitmap & $t) === $t){
|
if(($bitmap & $t) === $t){
|
||||||
@ -589,6 +615,10 @@ class PMFLevel extends PMF{
|
|||||||
return ($this->chunkInfo[$index][1] & 0b00000000000000000000000000000001) > 0;
|
return ($this->chunkInfo[$index][1] & 0b00000000000000000000000000000001) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isGenerated($X, $Z){
|
||||||
|
return file_exists($this->getChunkPath($X, $Z));
|
||||||
|
}
|
||||||
|
|
||||||
public function doSaveRound(){
|
public function doSaveRound(){
|
||||||
foreach($this->chunks as $index => $chunk){
|
foreach($this->chunks as $index => $chunk){
|
||||||
self::getXZ($index, $X, $Z);
|
self::getXZ($index, $X, $Z);
|
||||||
|
@ -148,11 +148,14 @@ class Level{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function generateChunk($X, $Z){
|
public function generateChunk($X, $Z){
|
||||||
|
++$this->level->isGenerating;
|
||||||
$this->generator->generateChunk($X, $Z);
|
$this->generator->generateChunk($X, $Z);
|
||||||
|
--$this->level->isGenerating;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function populateChunk($X, $Z){
|
public function populateChunk($X, $Z){
|
||||||
$this->generator->populateChunk($X, $Z);
|
$this->generator->populateChunk($X, $Z);
|
||||||
|
$this->level->setPopulated($X, $Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __destruct(){
|
public function __destruct(){
|
||||||
|
@ -65,9 +65,15 @@ class NormalGenerator implements LevelGenerator{
|
|||||||
new OreType(new GravelBlock(), 10, 16, 0, 128),
|
new OreType(new GravelBlock(), 10, 16, 0, 128),
|
||||||
));
|
));
|
||||||
$this->populators[] = $ores;
|
$this->populators[] = $ores;
|
||||||
|
|
||||||
|
$trees = new TreePopulator();
|
||||||
|
$trees->setBaseAmount(3);
|
||||||
|
$trees->setRandomAmount(0);
|
||||||
|
$this->populators[] = $trees;
|
||||||
|
|
||||||
$tallGrass = new TallGrassPopulator();
|
$tallGrass = new TallGrassPopulator();
|
||||||
$tallGrass->setBaseAmount(5);
|
$tallGrass->setBaseAmount(5);
|
||||||
$tallGrass->setRandomAmount(1);
|
$tallGrass->setRandomAmount(0);
|
||||||
$this->populators[] = $tallGrass;
|
$this->populators[] = $tallGrass;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +126,7 @@ class NormalGenerator implements LevelGenerator{
|
|||||||
}elseif($diff === 0){
|
}elseif($diff === 0){
|
||||||
if($patchesSmall[$i] > 0.3){
|
if($patchesSmall[$i] > 0.3){
|
||||||
$chunk .= "\x0d"; //gravel
|
$chunk .= "\x0d"; //gravel
|
||||||
}elseif($patches[$i] < -0.45){
|
}elseif($patchesSmall[$i] < -0.45){
|
||||||
$chunk .= "\x0c"; //sand
|
$chunk .= "\x0c"; //sand
|
||||||
}else{
|
}else{
|
||||||
$chunk .= "\x03"; //dirt
|
$chunk .= "\x03"; //dirt
|
||||||
@ -149,16 +155,11 @@ class NormalGenerator implements LevelGenerator{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function populateChunk($chunkX, $chunkZ){
|
public function populateChunk($chunkX, $chunkZ){
|
||||||
|
$this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->level->getSeed());
|
||||||
foreach($this->populators as $populator){
|
foreach($this->populators as $populator){
|
||||||
$this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->level->getSeed());
|
$this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->level->getSeed());
|
||||||
$populator->populate($this->level, $chunkX, $chunkZ, $this->random);
|
$populator->populate($this->level, $chunkX, $chunkZ, $this->random);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->level->level->setPopulated($chunkX, $chunkZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function populateLevel(){
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSpawn(){
|
public function getSpawn(){
|
||||||
|
@ -130,11 +130,10 @@ class SuperflatGenerator implements LevelGenerator{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function populateChunk($chunkX, $chunkZ){
|
public function populateChunk($chunkX, $chunkZ){
|
||||||
foreach($this->populators as $populator){
|
|
||||||
$this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->level->getSeed());
|
$this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->level->getSeed());
|
||||||
|
foreach($this->populators as $populator){
|
||||||
$populator->populate($this->level, $chunkX, $chunkZ, $this->random);
|
$populator->populate($this->level, $chunkX, $chunkZ, $this->random);
|
||||||
}
|
}
|
||||||
$this->level->level->setPopulated($chunkX, $chunkZ);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function populateLevel(){
|
public function populateLevel(){
|
||||||
|
@ -46,25 +46,17 @@ class WorldGenerator{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function generate(){
|
public function generate(){
|
||||||
++$this->level->level->isGenerating;
|
|
||||||
$this->generator->init($this->level, $this->random);
|
$this->generator->init($this->level, $this->random);
|
||||||
|
|
||||||
//Generate 4 chunks for spawning players
|
//Generate 4 chunks for spawning players
|
||||||
for($Z = 7; $Z <= 8; ++$Z){
|
for($Z = 7; $Z <= 8; ++$Z){
|
||||||
for($X = 7; $X <= 8; ++$X){
|
for($X = 7; $X <= 8; ++$X){
|
||||||
$this->generator->generateChunk($X, $Z);
|
$this->level->level->generateChunk($X, $Z);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for($Z = 7; $Z <= 8; ++$Z){
|
|
||||||
for($X = 7; $X <= 8; ++$X){
|
|
||||||
$this->generator->populateChunk($X, $Z);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->level->setSpawn($this->generator->getSpawn());
|
$this->level->setSpawn($this->generator->getSpawn());
|
||||||
$this->level->save(true, true);
|
$this->level->save(true, true);
|
||||||
--$this->level->level->isGenerating;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function close(){
|
public function close(){
|
||||||
|
67
src/world/generator/populator/TreePopulator.php
Normal file
67
src/world/generator/populator/TreePopulator.php
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* ____ _ _ __ __ _ __ __ ____
|
||||||
|
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||||
|
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||||
|
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||||
|
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* @author PocketMine Team
|
||||||
|
* @link http://www.pocketmine.net/
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
class TreePopulator extends Populator{
|
||||||
|
private $level;
|
||||||
|
private $randomAmount;
|
||||||
|
private $baseAmount;
|
||||||
|
|
||||||
|
public function setRandomAmount($amount){
|
||||||
|
$this->randomAmount = $amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setBaseAmount($amount){
|
||||||
|
$this->baseAmount = $amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function populate(Level $level, $chunkX, $chunkZ, Random $random){
|
||||||
|
$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);
|
||||||
|
$y = $this->getHighestWorkableBlock($x, $z);
|
||||||
|
if($y === -1){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if($random->nextFloat() > 0.75){
|
||||||
|
$meta = 1;
|
||||||
|
}else{
|
||||||
|
$meta = 0;
|
||||||
|
}
|
||||||
|
TreeObject::growTree($this->level, new Vector3($x, $y, $z), $random, $meta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getHighestWorkableBlock($x, $z){
|
||||||
|
for($y = 128; $y > 0; --$y){
|
||||||
|
$b = $this->level->getBlockRaw(new Vector3($x, $y, $z));
|
||||||
|
if($b->getID() !== DIRT and $b->getID() !== GRASS){
|
||||||
|
if(--$y <= 0){
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ++$y;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user