/**
* Generates a new level if it does not exists
*
* @param string $name
* @param int $seed
* @param string $generator Class name that extends pocketmine\level\generator\Generator
* @param array $options
*
* @return bool
*/
public function generateLevel($name, $seed = null, $generator = null, $options = [])
{
if (trim($name) === "" or $this->isLevelGenerated($name)) {
return false;
}
$seed = $seed === null ? PHP_INT_SIZE === 8 ? unpack("N", @Utils::getRandomBytes(4, false))[1] << 32 >> 32 : unpack("N", @Utils::getRandomBytes(4, false))[1] : (int) $seed;
if ($generator !== null and class_exists($generator) and is_subclass_of($generator, Generator::class)) {
$generator = new $generator($options);
} else {
$options["preset"] = $this->getConfigString("generator-settings", "");
$generator = Generator::getGenerator($this->getLevelType());
}
if (($provider = LevelProviderManager::getProviderByName($providerName = $this->getProperty("level-settings.default-format", "mcregion"))) === null) {
$provider = LevelProviderManager::getProviderByName($providerName = "mcregion");
}
try {
$path = $this->getDataPath() . "worlds/" . $name . "/";
/** @var \pocketmine\level\format\LevelProvider $provider */
$provider::generate($path, $name, $seed, $generator, $options);
$level = new Level($this, $name, $path, $provider);
$this->levels[$level->getId()] = $level;
$level->initLevel();
} catch (\Exception $e) {
$this->logger->error("Could not generate level \"" . $name . "\": " . $e->getMessage());
if ($this->logger instanceof MainLogger) {
$this->logger->logException($e);
}
return false;
}
$this->getPluginManager()->callEvent(new LevelInitEvent($level));
$this->getPluginManager()->callEvent(new LevelLoadEvent($level));
$this->getLogger()->notice("Spawn terrain for level \"{$name}\" is being generated in the background");
$centerX = $level->getSpawnLocation()->getX() >> 4;
$centerZ = $level->getSpawnLocation()->getZ() >> 4;
$order = [];
for ($X = -4; $X <= 4; ++$X) {
for ($Z = -4; $Z <= 4; ++$Z) {
$distance = $X ** 2 + $Z ** 2;
$chunkX = $X + $centerX;
$chunkZ = $Z + $centerZ;
$index = PHP_INT_SIZE === 8 ? ($chunkX & 0xffffffff) << 32 | $chunkZ & 0xffffffff : $chunkX . ":" . $chunkZ;
$order[$index] = $distance;
}
}
asort($order);
$chunkX = $chunkZ = null;
foreach ($order as $index => $distance) {
if (PHP_INT_SIZE === 8) {
$chunkX = $index >> 32 << 32 >> 32;
$chunkZ = ($index & 0xffffffff) << 32 >> 32;
} else {
list($chunkX, $chunkZ) = explode(":", $index);
$chunkX = (int) $chunkX;
$chunkZ = (int) $chunkZ;
}
$level->generateChunk($chunkX, $chunkZ, true);
}
return true;
}