mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-21 08:17:34 +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);
|
||||
|
||||
/**
|
||||
* Gets the level seed
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getSeed() : int;
|
||||
|
||||
/**
|
||||
* Returns the height of the world
|
||||
* @return int
|
||||
|
@ -30,17 +30,14 @@ class SimpleChunkManager implements ChunkManager{
|
||||
/** @var Chunk[] */
|
||||
protected $chunks = [];
|
||||
|
||||
protected $seed;
|
||||
protected $worldHeight;
|
||||
|
||||
/**
|
||||
* SimpleChunkManager constructor.
|
||||
*
|
||||
* @param int $seed
|
||||
* @param int $worldHeight
|
||||
*/
|
||||
public function __construct(int $seed, int $worldHeight = Level::Y_MAX){
|
||||
$this->seed = $seed;
|
||||
public function __construct(int $worldHeight = Level::Y_MAX){
|
||||
$this->worldHeight = $worldHeight;
|
||||
}
|
||||
|
||||
@ -159,15 +156,6 @@ class SimpleChunkManager implements ChunkManager{
|
||||
$this->chunks = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the level seed
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getSeed() : int{
|
||||
return $this->seed;
|
||||
}
|
||||
|
||||
public function getWorldHeight() : int{
|
||||
return $this->worldHeight;
|
||||
}
|
||||
|
@ -45,21 +45,16 @@ class Flat extends Generator{
|
||||
private $floorLevel;
|
||||
/** @var int */
|
||||
private $biome;
|
||||
/** @var mixed[] */
|
||||
private $options;
|
||||
/** @var string */
|
||||
private $preset;
|
||||
|
||||
public function getSettings() : array{
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
public function getName() : string{
|
||||
return "flat";
|
||||
}
|
||||
|
||||
public function __construct(array $options = []){
|
||||
$this->options = $options;
|
||||
public function __construct(ChunkManager $level, int $seed, array $options = []){
|
||||
parent::__construct($level, $seed, $options);
|
||||
|
||||
if(isset($this->options["preset"]) and $this->options["preset"] != ""){
|
||||
$this->preset = $this->options["preset"];
|
||||
}else{
|
||||
@ -83,6 +78,8 @@ class Flat extends Generator{
|
||||
]);
|
||||
$this->populators[] = $ores;
|
||||
}
|
||||
|
||||
$this->generateBaseChunk();
|
||||
}
|
||||
|
||||
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{
|
||||
$chunk = clone $this->chunk;
|
||||
$chunk->setX($chunkX);
|
||||
@ -164,7 +156,7 @@ class Flat extends Generator{
|
||||
}
|
||||
|
||||
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){
|
||||
$populator->populate($this->level, $chunkX, $chunkZ, $this->random);
|
||||
}
|
||||
|
@ -54,22 +54,28 @@ abstract class Generator{
|
||||
|
||||
/** @var ChunkManager */
|
||||
protected $level;
|
||||
/** @var int */
|
||||
protected $seed;
|
||||
/** @var array */
|
||||
protected $options;
|
||||
|
||||
/** @var Random */
|
||||
protected $random;
|
||||
|
||||
abstract public function __construct(array $settings = []);
|
||||
|
||||
|
||||
public function init(ChunkManager $level, Random $random) : void{
|
||||
public function __construct(ChunkManager $level, int $seed, array $options = []){
|
||||
$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 populateChunk(int $chunkX, int $chunkZ) : void;
|
||||
|
||||
abstract public function getSettings() : array;
|
||||
public function getSettings() : array{
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
abstract public function getName() : string;
|
||||
|
||||
|
@ -49,15 +49,14 @@ class GeneratorRegisterTask extends AsyncTask{
|
||||
public function onRun() : void{
|
||||
BlockFactory::init();
|
||||
Biome::init();
|
||||
$manager = new SimpleChunkManager($this->seed, $this->worldHeight);
|
||||
$manager = new SimpleChunkManager($this->worldHeight);
|
||||
$this->saveToThreadStore("generation.level{$this->levelId}.manager", $manager);
|
||||
|
||||
/**
|
||||
* @var Generator $generator
|
||||
* @see Generator::__construct()
|
||||
*/
|
||||
$generator = new $this->generatorClass(unserialize($this->settings));
|
||||
$generator->init($manager, new Random($manager->getSeed()));
|
||||
$generator = new $this->generatorClass($manager, $this->seed, unserialize($this->settings));
|
||||
$this->saveToThreadStore("generation.level{$this->levelId}.generator", $generator);
|
||||
}
|
||||
}
|
||||
|
@ -50,28 +50,16 @@ class Nether extends Generator{
|
||||
/** @var Simplex */
|
||||
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->random->setSeed($this->level->getSeed());
|
||||
$this->random->setSeed($this->seed);
|
||||
|
||||
/*$ores = new Ore();
|
||||
$ores->setOreTypes([
|
||||
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 LapisOre(), 1, 6, 0, 32),
|
||||
new OreType(new GoldOre(), 2, 8, 0, 32),
|
||||
@ -82,8 +70,12 @@ class Nether extends Generator{
|
||||
$this->populators[] = $ores;*/
|
||||
}
|
||||
|
||||
public function getName() : string{
|
||||
return "nether";
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@ -118,7 +110,7 @@ class Nether extends Generator{
|
||||
}
|
||||
|
||||
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){
|
||||
$populator->populate($this->level, $chunkX, $chunkZ, $this->random);
|
||||
}
|
||||
|
@ -56,57 +56,15 @@ class Normal extends Generator{
|
||||
private static $GAUSSIAN_KERNEL = null;
|
||||
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){
|
||||
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->random->setSeed($this->level->getSeed());
|
||||
$this->random->setSeed($this->seed);
|
||||
|
||||
$this->selector = new class($this->random) extends BiomeSelector{
|
||||
protected function lookup(float $temperature, float $rainfall) : int{
|
||||
if($rainfall < 0.25){
|
||||
@ -167,8 +125,44 @@ class Normal extends Generator{
|
||||
$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{
|
||||
$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);
|
||||
|
||||
@ -235,7 +229,7 @@ class Normal extends Generator{
|
||||
}
|
||||
|
||||
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){
|
||||
$populator->populate($this->level, $chunkX, $chunkZ, $this->random);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user