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:
Dylan K. Taylor 2018-09-10 13:28:15 +01:00
parent 0d152a2139
commit 5ce2d5e072
7 changed files with 73 additions and 109 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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);
}