Files
PocketMine-MP/src/world/generator/biome/BiomeSelector.php
2019-07-30 19:14:57 +01:00

91 lines
2.5 KiB
PHP

<?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/
*
*
*/
declare(strict_types=1);
namespace pocketmine\world\generator\biome;
use pocketmine\utils\Random;
use pocketmine\world\biome\Biome;
use pocketmine\world\biome\UnknownBiome;
use pocketmine\world\generator\noise\Simplex;
abstract class BiomeSelector{
/** @var Simplex */
private $temperature;
/** @var Simplex */
private $rainfall;
/** @var Biome[]|\SplFixedArray */
private $map = null;
public function __construct(Random $random){
$this->temperature = new Simplex($random, 2, 1 / 16, 1 / 512);
$this->rainfall = new Simplex($random, 2, 1 / 16, 1 / 512);
}
/**
* Lookup function called by recalculate() to determine the biome to use for this temperature and rainfall.
*
* @param float $temperature
* @param float $rainfall
*
* @return int biome ID 0-255
*/
abstract protected function lookup(float $temperature, float $rainfall) : int;
public function recalculate() : void{
$this->map = new \SplFixedArray(64 * 64);
for($i = 0; $i < 64; ++$i){
for($j = 0; $j < 64; ++$j){
$biome = Biome::getBiome($this->lookup($i / 63, $j / 63));
if($biome instanceof UnknownBiome){
throw new \RuntimeException("Unknown biome returned by selector with ID " . $biome->getId());
}
$this->map[$i + ($j << 6)] = $biome;
}
}
}
public function getTemperature($x, $z){
return ($this->temperature->noise2D($x, $z, true) + 1) / 2;
}
public function getRainfall($x, $z){
return ($this->rainfall->noise2D($x, $z, true) + 1) / 2;
}
/**
* TODO: not sure on types here
* @param int|float $x
* @param int|float $z
*
* @return Biome
*/
public function pickBiome($x, $z) : Biome{
$temperature = (int) ($this->getTemperature($x, $z) * 63);
$rainfall = (int) ($this->getRainfall($x, $z) * 63);
return $this->map[$temperature + ($rainfall << 6)];
}
}