mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-06-10 05:34:54 +00:00
Clean up to Generator creation, remove getSeed() from ChunkManager interface
it's the generator's responsibility to know about the seed, not the chunkmanager's. This now reduces the complexity of implementing and using a chunkmanager.
This commit is contained in:
parent
0d152a2139
commit
5ce2d5e072
@ -125,13 +125,6 @@ interface ChunkManager{
|
|||||||
*/
|
*/
|
||||||
public function setChunk(int $chunkX, int $chunkZ, Chunk $chunk = null);
|
public function setChunk(int $chunkX, int $chunkZ, Chunk $chunk = null);
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the level seed
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getSeed() : int;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the height of the world
|
* Returns the height of the world
|
||||||
* @return int
|
* @return int
|
||||||
|
@ -30,17 +30,14 @@ class SimpleChunkManager implements ChunkManager{
|
|||||||
/** @var Chunk[] */
|
/** @var Chunk[] */
|
||||||
protected $chunks = [];
|
protected $chunks = [];
|
||||||
|
|
||||||
protected $seed;
|
|
||||||
protected $worldHeight;
|
protected $worldHeight;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SimpleChunkManager constructor.
|
* SimpleChunkManager constructor.
|
||||||
*
|
*
|
||||||
* @param int $seed
|
|
||||||
* @param int $worldHeight
|
* @param int $worldHeight
|
||||||
*/
|
*/
|
||||||
public function __construct(int $seed, int $worldHeight = Level::Y_MAX){
|
public function __construct(int $worldHeight = Level::Y_MAX){
|
||||||
$this->seed = $seed;
|
|
||||||
$this->worldHeight = $worldHeight;
|
$this->worldHeight = $worldHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,15 +156,6 @@ class SimpleChunkManager implements ChunkManager{
|
|||||||
$this->chunks = [];
|
$this->chunks = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the level seed
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getSeed() : int{
|
|
||||||
return $this->seed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getWorldHeight() : int{
|
public function getWorldHeight() : int{
|
||||||
return $this->worldHeight;
|
return $this->worldHeight;
|
||||||
}
|
}
|
||||||
|
@ -45,21 +45,16 @@ class Flat extends Generator{
|
|||||||
private $floorLevel;
|
private $floorLevel;
|
||||||
/** @var int */
|
/** @var int */
|
||||||
private $biome;
|
private $biome;
|
||||||
/** @var mixed[] */
|
|
||||||
private $options;
|
|
||||||
/** @var string */
|
/** @var string */
|
||||||
private $preset;
|
private $preset;
|
||||||
|
|
||||||
public function getSettings() : array{
|
|
||||||
return $this->options;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getName() : string{
|
public function getName() : string{
|
||||||
return "flat";
|
return "flat";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __construct(array $options = []){
|
public function __construct(ChunkManager $level, int $seed, array $options = []){
|
||||||
$this->options = $options;
|
parent::__construct($level, $seed, $options);
|
||||||
|
|
||||||
if(isset($this->options["preset"]) and $this->options["preset"] != ""){
|
if(isset($this->options["preset"]) and $this->options["preset"] != ""){
|
||||||
$this->preset = $this->options["preset"];
|
$this->preset = $this->options["preset"];
|
||||||
}else{
|
}else{
|
||||||
@ -83,6 +78,8 @@ class Flat extends Generator{
|
|||||||
]);
|
]);
|
||||||
$this->populators[] = $ores;
|
$this->populators[] = $ores;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->generateBaseChunk();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function parseLayers(string $layers) : array{
|
public static function parseLayers(string $layers) : array{
|
||||||
@ -151,11 +148,6 @@ class Flat extends Generator{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function init(ChunkManager $level, Random $random) : void{
|
|
||||||
parent::init($level, $random);
|
|
||||||
$this->generateBaseChunk();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function generateChunk(int $chunkX, int $chunkZ) : void{
|
public function generateChunk(int $chunkX, int $chunkZ) : void{
|
||||||
$chunk = clone $this->chunk;
|
$chunk = clone $this->chunk;
|
||||||
$chunk->setX($chunkX);
|
$chunk->setX($chunkX);
|
||||||
@ -164,7 +156,7 @@ class Flat extends Generator{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function populateChunk(int $chunkX, int $chunkZ) : void{
|
public function populateChunk(int $chunkX, int $chunkZ) : void{
|
||||||
$this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->level->getSeed());
|
$this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->seed);
|
||||||
foreach($this->populators as $populator){
|
foreach($this->populators as $populator){
|
||||||
$populator->populate($this->level, $chunkX, $chunkZ, $this->random);
|
$populator->populate($this->level, $chunkX, $chunkZ, $this->random);
|
||||||
}
|
}
|
||||||
|
@ -54,22 +54,28 @@ abstract class Generator{
|
|||||||
|
|
||||||
/** @var ChunkManager */
|
/** @var ChunkManager */
|
||||||
protected $level;
|
protected $level;
|
||||||
|
/** @var int */
|
||||||
|
protected $seed;
|
||||||
|
/** @var array */
|
||||||
|
protected $options;
|
||||||
|
|
||||||
/** @var Random */
|
/** @var Random */
|
||||||
protected $random;
|
protected $random;
|
||||||
|
|
||||||
abstract public function __construct(array $settings = []);
|
public function __construct(ChunkManager $level, int $seed, array $options = []){
|
||||||
|
|
||||||
|
|
||||||
public function init(ChunkManager $level, Random $random) : void{
|
|
||||||
$this->level = $level;
|
$this->level = $level;
|
||||||
$this->random = $random;
|
$this->seed = $seed;
|
||||||
|
$this->options = $options;
|
||||||
|
$this->random = new Random($seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract public function generateChunk(int $chunkX, int $chunkZ) : void;
|
abstract public function generateChunk(int $chunkX, int $chunkZ) : void;
|
||||||
|
|
||||||
abstract public function populateChunk(int $chunkX, int $chunkZ) : void;
|
abstract public function populateChunk(int $chunkX, int $chunkZ) : void;
|
||||||
|
|
||||||
abstract public function getSettings() : array;
|
public function getSettings() : array{
|
||||||
|
return $this->options;
|
||||||
|
}
|
||||||
|
|
||||||
abstract public function getName() : string;
|
abstract public function getName() : string;
|
||||||
|
|
||||||
|
@ -49,15 +49,14 @@ class GeneratorRegisterTask extends AsyncTask{
|
|||||||
public function onRun() : void{
|
public function onRun() : void{
|
||||||
BlockFactory::init();
|
BlockFactory::init();
|
||||||
Biome::init();
|
Biome::init();
|
||||||
$manager = new SimpleChunkManager($this->seed, $this->worldHeight);
|
$manager = new SimpleChunkManager($this->worldHeight);
|
||||||
$this->saveToThreadStore("generation.level{$this->levelId}.manager", $manager);
|
$this->saveToThreadStore("generation.level{$this->levelId}.manager", $manager);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Generator $generator
|
* @var Generator $generator
|
||||||
* @see Generator::__construct()
|
* @see Generator::__construct()
|
||||||
*/
|
*/
|
||||||
$generator = new $this->generatorClass(unserialize($this->settings));
|
$generator = new $this->generatorClass($manager, $this->seed, unserialize($this->settings));
|
||||||
$generator->init($manager, new Random($manager->getSeed()));
|
|
||||||
$this->saveToThreadStore("generation.level{$this->levelId}.generator", $generator);
|
$this->saveToThreadStore("generation.level{$this->levelId}.generator", $generator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,28 +50,16 @@ class Nether extends Generator{
|
|||||||
/** @var Simplex */
|
/** @var Simplex */
|
||||||
private $noiseBase;
|
private $noiseBase;
|
||||||
|
|
||||||
public function __construct(array $options = []){
|
public function __construct(ChunkManager $level, int $seed, array $options = []){
|
||||||
|
parent::__construct($level, $seed, $options);
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getName() : string{
|
|
||||||
return "nether";
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSettings() : array{
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function init(ChunkManager $level, Random $random) : void{
|
|
||||||
parent::init($level, $random);
|
|
||||||
$this->random->setSeed($this->level->getSeed());
|
|
||||||
$this->noiseBase = new Simplex($this->random, 4, 1 / 4, 1 / 64);
|
$this->noiseBase = new Simplex($this->random, 4, 1 / 4, 1 / 64);
|
||||||
$this->random->setSeed($this->level->getSeed());
|
$this->random->setSeed($this->seed);
|
||||||
|
|
||||||
/*$ores = new Ore();
|
/*$ores = new Ore();
|
||||||
$ores->setOreTypes([
|
$ores->setOreTypes([
|
||||||
new OreType(new CoalOre(), 20, 16, 0, 128),
|
new OreType(new CoalOre(), 20, 16, 0, 128),
|
||||||
new OreType(New IronOre(), 20, 8, 0, 64),
|
new OreType(new IronOre(), 20, 8, 0, 64),
|
||||||
new OreType(new RedstoneOre(), 8, 7, 0, 16),
|
new OreType(new RedstoneOre(), 8, 7, 0, 16),
|
||||||
new OreType(new LapisOre(), 1, 6, 0, 32),
|
new OreType(new LapisOre(), 1, 6, 0, 32),
|
||||||
new OreType(new GoldOre(), 2, 8, 0, 32),
|
new OreType(new GoldOre(), 2, 8, 0, 32),
|
||||||
@ -82,8 +70,12 @@ class Nether extends Generator{
|
|||||||
$this->populators[] = $ores;*/
|
$this->populators[] = $ores;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getName() : string{
|
||||||
|
return "nether";
|
||||||
|
}
|
||||||
|
|
||||||
public function generateChunk(int $chunkX, int $chunkZ) : void{
|
public function generateChunk(int $chunkX, int $chunkZ) : void{
|
||||||
$this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->level->getSeed());
|
$this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->seed);
|
||||||
|
|
||||||
$noise = $this->noiseBase->getFastNoise3D(16, 128, 16, 4, 8, 4, $chunkX * 16, 0, $chunkZ * 16);
|
$noise = $this->noiseBase->getFastNoise3D(16, 128, 16, 4, 8, 4, $chunkX * 16, 0, $chunkZ * 16);
|
||||||
|
|
||||||
@ -118,7 +110,7 @@ class Nether extends Generator{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function populateChunk(int $chunkX, int $chunkZ) : void{
|
public function populateChunk(int $chunkX, int $chunkZ) : void{
|
||||||
$this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->level->getSeed());
|
$this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->seed);
|
||||||
foreach($this->populators as $populator){
|
foreach($this->populators as $populator){
|
||||||
$populator->populate($this->level, $chunkX, $chunkZ, $this->random);
|
$populator->populate($this->level, $chunkX, $chunkZ, $this->random);
|
||||||
}
|
}
|
||||||
|
@ -56,57 +56,15 @@ class Normal extends Generator{
|
|||||||
private static $GAUSSIAN_KERNEL = null;
|
private static $GAUSSIAN_KERNEL = null;
|
||||||
private static $SMOOTH_SIZE = 2;
|
private static $SMOOTH_SIZE = 2;
|
||||||
|
|
||||||
public function __construct(array $options = []){
|
public function __construct(ChunkManager $level, int $seed, array $options = []){
|
||||||
|
parent::__construct($level, $seed, $options);
|
||||||
if(self::$GAUSSIAN_KERNEL === null){
|
if(self::$GAUSSIAN_KERNEL === null){
|
||||||
self::generateKernel();
|
self::generateKernel();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private static function generateKernel() : void{
|
|
||||||
self::$GAUSSIAN_KERNEL = [];
|
|
||||||
|
|
||||||
$bellSize = 1 / self::$SMOOTH_SIZE;
|
|
||||||
$bellHeight = 2 * self::$SMOOTH_SIZE;
|
|
||||||
|
|
||||||
for($sx = -self::$SMOOTH_SIZE; $sx <= self::$SMOOTH_SIZE; ++$sx){
|
|
||||||
self::$GAUSSIAN_KERNEL[$sx + self::$SMOOTH_SIZE] = [];
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getName() : string{
|
|
||||||
return "normal";
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSettings() : array{
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
private function pickBiome(int $x, int $z) : Biome{
|
|
||||||
$hash = $x * 2345803 ^ $z * 9236449 ^ $this->level->getSeed();
|
|
||||||
$hash *= $hash + 223;
|
|
||||||
$xNoise = $hash >> 20 & 3;
|
|
||||||
$zNoise = $hash >> 22 & 3;
|
|
||||||
if($xNoise == 3){
|
|
||||||
$xNoise = 1;
|
|
||||||
}
|
|
||||||
if($zNoise == 3){
|
|
||||||
$zNoise = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->selector->pickBiome($x + $xNoise - 1, $z + $zNoise - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function init(ChunkManager $level, Random $random) : void{
|
|
||||||
parent::init($level, $random);
|
|
||||||
$this->random->setSeed($this->level->getSeed());
|
|
||||||
$this->noiseBase = new Simplex($this->random, 4, 1 / 4, 1 / 32);
|
$this->noiseBase = new Simplex($this->random, 4, 1 / 4, 1 / 32);
|
||||||
$this->random->setSeed($this->level->getSeed());
|
$this->random->setSeed($this->seed);
|
||||||
|
|
||||||
$this->selector = new class($this->random) extends BiomeSelector{
|
$this->selector = new class($this->random) extends BiomeSelector{
|
||||||
protected function lookup(float $temperature, float $rainfall) : int{
|
protected function lookup(float $temperature, float $rainfall) : int{
|
||||||
if($rainfall < 0.25){
|
if($rainfall < 0.25){
|
||||||
@ -167,8 +125,44 @@ class Normal extends Generator{
|
|||||||
$this->populators[] = $ores;
|
$this->populators[] = $ores;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static function generateKernel() : void{
|
||||||
|
self::$GAUSSIAN_KERNEL = [];
|
||||||
|
|
||||||
|
$bellSize = 1 / self::$SMOOTH_SIZE;
|
||||||
|
$bellHeight = 2 * self::$SMOOTH_SIZE;
|
||||||
|
|
||||||
|
for($sx = -self::$SMOOTH_SIZE; $sx <= self::$SMOOTH_SIZE; ++$sx){
|
||||||
|
self::$GAUSSIAN_KERNEL[$sx + self::$SMOOTH_SIZE] = [];
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName() : string{
|
||||||
|
return "normal";
|
||||||
|
}
|
||||||
|
|
||||||
|
private function pickBiome(int $x, int $z) : Biome{
|
||||||
|
$hash = $x * 2345803 ^ $z * 9236449 ^ $this->seed;
|
||||||
|
$hash *= $hash + 223;
|
||||||
|
$xNoise = $hash >> 20 & 3;
|
||||||
|
$zNoise = $hash >> 22 & 3;
|
||||||
|
if($xNoise == 3){
|
||||||
|
$xNoise = 1;
|
||||||
|
}
|
||||||
|
if($zNoise == 3){
|
||||||
|
$zNoise = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->selector->pickBiome($x + $xNoise - 1, $z + $zNoise - 1);
|
||||||
|
}
|
||||||
|
|
||||||
public function generateChunk(int $chunkX, int $chunkZ) : void{
|
public function generateChunk(int $chunkX, int $chunkZ) : void{
|
||||||
$this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->level->getSeed());
|
$this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->seed);
|
||||||
|
|
||||||
$noise = $this->noiseBase->getFastNoise3D(16, 128, 16, 4, 8, 4, $chunkX * 16, 0, $chunkZ * 16);
|
$noise = $this->noiseBase->getFastNoise3D(16, 128, 16, 4, 8, 4, $chunkX * 16, 0, $chunkZ * 16);
|
||||||
|
|
||||||
@ -235,7 +229,7 @@ class Normal extends Generator{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function populateChunk(int $chunkX, int $chunkZ) : void{
|
public function populateChunk(int $chunkX, int $chunkZ) : void{
|
||||||
$this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->level->getSeed());
|
$this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->seed);
|
||||||
foreach($this->populators as $populator){
|
foreach($this->populators as $populator){
|
||||||
$populator->populate($this->level, $chunkX, $chunkZ, $this->random);
|
$populator->populate($this->level, $chunkX, $chunkZ, $this->random);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user