Compare commits

...

3 commits

Author SHA1 Message Date
thebigsmileXD
2767113421 Fix legal issues 2017-05-16 12:14:20 +02:00
thebigsmileXD
1f10807c7b Finish loottable generation & chest generation 2017-05-14 11:32:58 +02:00
thebigsmileXD
58b4870fee Add default addon submodule for lootfiles, Reformatting, fix structure command #20, cleanups, Looting file replacement 2017-05-14 07:59:19 +02:00
42 changed files with 1604 additions and 1819 deletions

View file

@ -46,4 +46,14 @@ Welcome user to the home of a new PocketMine World Generator which features 9 ne
### These two biomes now are a bit better by the additions of bushes.
<img src="https://raw.githubusercontent.com/Ad5001/BetterGen/master/imgs/bushes.png" style="width: 500px"></img>
-----
# Notice:
### To generate loot like in vanilla MCPE, you have to put the default behaviour pack contents of the game into the "addon" folder.
### Due to legal issues we are not able to include these directly into the repository.
### You can get them here: https://aka.ms/behaviorpacktemplate or here https://github.com/dktapps/mcpe-default-addon for an optimised version
### The folder has to look like this:
<img src="https://raw.githubusercontent.com/Ad5001/BetterGen/master/imgs/addon_setup.png" style="width: 500px"></img>
All content here is copyrighted (C) Ad5001 2017. Infos about this copyright can be found in the license file.

BIN
imgs/addon_setup.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

View file

@ -10,11 +10,11 @@
# @author Ad5001
# @link https://github.com/Ad5001/BetterGen
name: BetterGen
author: Ad5001
authors: Ad5001, XenialDan
main: Ad5001\BetterGen\Main
version: 1.1
version: 2.0
load: STARTUP
api: [3.0.1, 3.0.0-ALPHA3]
api: [3.0.0-ALPHA3, 3.0.0-ALPHA5]
commands:
createworld:
description: Generates a new world.
@ -24,9 +24,9 @@ commands:
description: Teleports you to an another world
usage: "/worldtp <world name>"
permission: bettergen.cmd.worldtp
temple:
description: Spawns a temple for debugging
usage: "/temple"
structure:
description: Spawns a structure for debugging
usage: "/structure <type>"
permission: bettergen.cmd.debug
permissions:
bettergen.cmd.createworld:

View file

@ -1 +0,0 @@
[]

View file

@ -1,183 +0,0 @@
{
"max": 27,
"rail": {
"percentage": 79,
"minCount": 4,
"maxCount": 8,
"minStacks": 3,
"maxStacks": 3,
"id": 66,
"data": 0
},
"torch": {
"percentage": 66,
"minCount": 1,
"maxCount": 16,
"minStacks": 3,
"maxStacks": 3,
"id": 50,
"data": 0
},
"bread": {
"percentage": 45,
"minCount": 1,
"maxCount": 3,
"minStacks": 2,
"maxStacks": 4,
"id": 297,
"data": 0
},
"name tag": {
"percentage": 42,
"minCount": 1,
"maxCount": 1,
"minStacks": 2,
"maxStacks": 4,
"id": 297,
"data": 0
},
"coal": {
"percentage": 32,
"minCount": 3,
"maxCount": 8,
"minStacks": 2,
"maxStacks": 4,
"id": 263,
"data": 0
},
"beetroot seeds": {
"percentage": 32,
"minCount": 2,
"maxCount": 4,
"minStacks": 2,
"maxStacks": 4,
"id": 458,
"data": 0
},
"melon seeds": {
"percentage": 32,
"minCount": 2,
"maxCount": 4,
"minStacks": 2,
"maxStacks": 4,
"id": 362,
"data": 0
},
"pumpkin seeds": {
"percentage": 32,
"minCount": 2,
"maxCount": 4,
"minStacks": 2,
"maxStacks": 4,
"id": 361,
"data": 0
},
"iron ingot": {
"percentage": 32,
"minCount": 1,
"maxCount": 5,
"minStacks": 2,
"maxStacks": 4,
"id": 365,
"data": 0
},
"golden apple": {
"percentage": 28,
"minCount": 1,
"maxCount": 1,
"minStacks": 1,
"maxStacks": 1,
"id": 322,
"data": 0
},
"activator rail": {
"percentage": 27,
"minCount": 1,
"maxCount": 4,
"minStacks": 3,
"maxStacks": 3,
"id": 126,
"data": 0
},
"detector rail": {
"percentage": 27,
"minCount": 1,
"maxCount": 4,
"minStacks": 3,
"maxStacks": 3,
"id": 28,
"data": 0
},
"powered rail": {
"percentage": 27,
"minCount": 1,
"maxCount": 4,
"minStacks": 3,
"maxStacks": 3,
"id": 27,
"data": 0
},
"lapis lazuli": {
"percentage": 17,
"minCount": 4,
"maxCount": 9,
"minStacks": 2,
"maxStacks": 4,
"id": 351,
"data": 4
},
"redstone": {
"percentage": 17,
"minCount": 4,
"maxCount": 9,
"minStacks": 2,
"maxStacks": 4,
"id": 331,
"data": 0
},
"gold ingot": {
"percentage": 17,
"minCount": 1,
"maxCount": 3,
"minStacks": 2,
"maxStacks": 4,
"id": 366,
"data": 0
},
"enchanted book": {
"percentage": 14,
"minCount": 1,
"maxCount": 1,
"minStacks": 1,
"maxStacks": 1,
"id": 403,
"data": 0
},
"diamond": {
"percentage": 11,
"minCount": 1,
"maxCount": 2,
"minStacks": 2,
"maxStacks": 4,
"id": 264,
"data": 0
},
"iron pickaxe": {
"percentage": 7,
"minCount": 1,
"maxCount": 1,
"minStacks": 1,
"maxStacks": 1,
"id": 257,
"data": 0
},
"enchanted golden apple": {
"percentage": 1,
"minCount": 1,
"maxCount": 1,
"minStacks": 1,
"maxStacks": 1,
"id": 466,
"data": 0
}
}

View file

@ -1,154 +0,0 @@
{
"max": 27,
"bone": {
"percentage": 71,
"minCount": 4,
"maxCount": 6,
"minStacks": 2,
"maxStacks": 4,
"id": 352,
"data": 0
},
"rotten_flesh": {
"percentage": 71,
"minCount": 3,
"maxCount": 7,
"minStacks": 2,
"maxStacks": 4,
"id": 367,
"data": 0
},
"gunpowder": {
"percentage": 59,
"minCount": 1,
"maxCount": 8,
"minStacks": 4,
"maxStacks": 4,
"id": 289,
"data": 0
},
"sand": {
"percentage": 59,
"minCount": 1,
"maxCount": 8,
"minStacks": 4,
"maxStacks": 4,
"id": 12,
"data": 0
},
"string": {
"percentage": 59,
"minCount": 1,
"maxCount": 8,
"minStacks": 4,
"maxStacks": 4,
"id": 287,
"data": 0
},
"spider_eye": {
"percentage": 29,
"minCount": 1,
"maxCount": 3,
"minStacks": 2,
"maxStacks": 4,
"id": 375,
"data": 0
},
"enchanted_book": {
"percentage": 24,
"minCount": 1,
"maxCount": 1,
"id": 403,
"data": 0
},
"saddle": {
"percentage": 24,
"minCount": 1,
"maxCount": 1,
"minStacks": 2,
"maxStacks": 4,
"id": 329,
"data": 0
},
"golden_apple": {
"percentage": 24,
"minCount": 1,
"maxCount": 1,
"minStacks": 1,
"maxStacks": 1,
"id": 322,
"data": 0
},
"gold_ingot": {
"percentage": 18,
"minCount": 2,
"maxCount": 7,
"minStacks": 2,
"maxStacks": 4,
"id": 266,
"data": 0
},
"iron_ingot": {
"percentage": 18,
"minCount": 1,
"maxCount": 5,
"minStacks": 2,
"maxStacks": 4,
"id": 265,
"data": 0
},
"emerald": {
"percentage": 18,
"minCount": 1,
"maxCount": 3,
"minStacks": 2,
"maxStacks": 4,
"id": 388,
"data": 0
},
"iron_horse_armor": {
"percentage": 18,
"minCount": 1,
"maxCount": 1,
"minStacks": 2,
"maxStacks": 4,
"id": 417,
"data": 0
},
"gold_horse_armor": {
"percentage": 12,
"minCount": 1,
"maxCount": 1,
"minStacks": 2,
"maxStacks": 4,
"id": 418,
"data": 0
},
"diamond": {
"percentage": 6,
"minCount": 1,
"maxCount": 3,
"minStacks": 2,
"maxStacks": 4,
"id": 264,
"data": 0
},
"diamond_horse_armor": {
"percentage": 6,
"minCount": 1,
"maxCount": 1,
"minStacks": 2,
"maxStacks": 4,
"id": 419,
"data": 0
},
"enchanted_golden_apple": {
"percentage": 3,
"minCount": 1,
"maxCount": 1,
"minStacks": 2,
"maxStacks": 4,
"id": 466,
"data": 0
}
}

View file

@ -17,62 +17,85 @@ namespace Ad5001\BetterGen;
use Ad5001\BetterGen\biome\BetterForest;
use Ad5001\BetterGen\generator\BetterNormal;
use Ad5001\BetterGen\loot\LootTable;
use Ad5001\BetterGen\structure\FallenTree;
use Ad5001\BetterGen\structure\Igloo;
use Ad5001\BetterGen\structure\SakuraTree;
use Ad5001\BetterGen\structure\Temple;
use Ad5001\BetterGen\structure\Well;
use pocketmine\block\Block;
use pocketmine\block\Chest;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\command\ConsoleCommandSender;
use pocketmine\event\block\BlockBreakEvent;
use pocketmine\event\level\ChunkPopulateEvent;
use pocketmine\event\Listener;
use pocketmine\event\player\PlayerInteractEvent;
use pocketmine\item\Item;
use pocketmine\level\generator\biome\Biome;
use pocketmine\level\generator\Generator;
use pocketmine\level\generator\object\OakTree;
use pocketmine\level\Position;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\ListTag;
use pocketmine\nbt\tag\StringTag;
use pocketmine\Player;
use pocketmine\plugin\PluginBase;
use pocketmine\tile\Chest;
use pocketmine\tile\Chest as TileChest;
use pocketmine\tile\Tile;
use pocketmine\utils\Config;
use pocketmine\utils\Random;
use pocketmine\utils\TextFormat;
class Main extends PluginBase implements Listener {
const PREFIX = "§l§o§b[§r§l§2Better§aGen§o§b]§r§f ";
const SAKURA_FOREST = 100; // Letting some place for future biomes.
private static $instance;
/*
* Called when the plugin enables
/**
* Registers a biome for the normal generator. Normal means(Biome::register) doesn't allow biome to be generated
* @param $id int
* @param $biome Biome
* @return void
*/
public static function registerBiome(int $id, Biome $biome) {
BetterNormal::registerBiome($biome);
}
/*
* Called when the plugin disables
/**
* Places a looting chest block and creates the corresponding tile
* @param Block $block
* @param $lootfile
*/
static public function placeLootChest(Block $block, $lootfile) {
$block->getLevel()->setBlock($block, $block, true);
$nbt = new CompoundTag("", [
new StringTag("id", Tile::CHEST),
new IntTag("x", (int)$block->x),
new IntTag("y", (int)$block->y),
new IntTag("z", (int)$block->z),
new StringTag("generateLoot", $lootfile)
]);
$tile = new TileChest($block->getLevel(), $nbt);
$tile->spawnToAll();
}
/**
* Called when the plugin enables
*/
public function onEnable() {
self::$instance = $this;
$this->getServer()->getPluginManager()->registerEvents($this, $this);
Generator::addGenerator(BetterNormal::class, "betternormal");
if ($this->isOtherNS()) $this->getLogger()->warning("Tesseract detected. Note that Tesseract is not up to date with the generation structure and some generation features may be limited or not working");
@mkdir($this->getDataFolder());
if (!file_exists(LootTable::getPluginFolder() . "processingLoots.json"))
file_put_contents(LootTable::getPluginFolder() . "processingLoots.json", "{}");
@mkdir($this->getDataFolder() . 'addon');
if ((($files = @scandir($this->getDataFolder() . 'addon')) && count($files) <= 2)) $this->getLogger()->alert('The loot files are missing, this means no loot will generate! You can get them here: https://aka.ms/behaviorpacktemplate or here https://github.com/dktapps/mcpe-default-addon for an optimised version');
}
/*
* Called when one of the defined commands of the plugin has been called
* @param $sender \pocketmine\command\CommandSender
* @param $cmd \pocketmine\command\Command
* @param $label mixed
* @param $args array
* return bool
/**
* Check if it's a Tesseract like namespace
* @return bool
*/
public static function isOtherNS() {
try {
return @class_exists("pocketmine\\level\\generator\\normal\\object\\OakTree");
@ -81,24 +104,20 @@ class Main extends PluginBase implements Listener {
}
}
/*
* Registers a forest type.
* @param $name string
* @param $treeClass string
* @params $infos Array(temperature, rainfall)
* @return bool
/**
* Called when the plugin disables
*/
public function onDisable() {
}
/*
* Registers a biome for the normal generator. Normal means(Biome::register) doesn't allow biome to be generated
* @param $id int
* @param $biome Biome
* @return void
/**
* Called when one of the defined commands of the plugin has been called
* @param $sender \pocketmine\command\CommandSender
* @param $cmd \pocketmine\command\Command
* @param $label mixed
* @param $args array
* @return bool
*/
public function onCommand(CommandSender $sender, Command $cmd, $label, array $args): bool {
switch ($cmd->getName()) {
case "createworld": // /createworld <name> [generator = betternormal] [seed = rand()] [options(json)]
@ -179,49 +198,91 @@ class Main extends PluginBase implements Listener {
return true;
break;
case "worldtp":
if(isset($args[0])) {
if(is_null($this->getServer()->getLevelByName($args[0]))) {
if (!$sender instanceof Player) {
$sender->sendMessage(TextFormat::RED . 'You can\'t use this command');
return true;
}
/** @var Player $sender */
if (isset($args[0])) {
if (is_null($this->getServer()->getLevelByName($args[0]))) {
$this->getServer()->loadLevel($args[0]);
if(is_null($this->getServer()->getLevelByName($args[0]))) {
if (is_null($this->getServer()->getLevelByName($args[0]))) {
$sender->sendMessage("Could not find level {$args[0]}.");
return false;
}
}
$sender->teleport(\pocketmine\level\Position::fromObject($player, $this->getServer()->getLevelByName($args[0])));
$sender->teleport(Position::fromObject($sender, $this->getServer()->getLevelByName($args[0])));
$sender->sendMessage("§aTeleporting to {$args[0]}...");
return true;
} else {
return false;
}
break;
case 'temple':{
if($sender instanceof ConsoleCommandSender) return false;
case 'structure': {
if (!$sender instanceof Player) {
$sender->sendMessage(TextFormat::RED . 'You can\'t use this command');
return true;
}
/** @var Player $sender */
$temple = new Temple();
$temple->placeObject($sender->getLevel(), $sender->x, $sender->y, $sender->z, new Random(microtime()));
if (isset($args[0])) {
switch ($args[0]) {
case 'temple': {
$temple = new Temple();
$temple->placeObject($sender->getLevel(), $sender->x, $sender->y, $sender->z, new Random(microtime()));
return true;
}
break;
case 'fallen': {
$temple = new FallenTree(new OakTree());
$temple->placeObject($sender->getLevel(), $sender->x, $sender->y, $sender->z);
return true;
}
break;
case 'igloo': {
$temple = new Igloo();
$temple->placeObject($sender->getLevel(), $sender->x, $sender->y, $sender->z, new Random(microtime()));
return true;
}
break;
case 'well': {
$temple = new Well();
$temple->placeObject($sender->getLevel(), $sender->x, $sender->y, $sender->z, new Random(microtime()));
return true;
}
break;
case 'sakura': {
$temple = new SakuraTree();
$temple->placeObject($sender->getLevel(), $sender->x, $sender->y, $sender->z, new Random(microtime()));
return true;
}
break;
default: {
}
}
}
$sender->sendMessage(implode(', ', ['temple', 'fallen', 'igloo', 'well', 'sakura']));
return true;
}
}
return false;
}
/*
/**
* Generates a(semi) random seed.
* @return int
*/
public function generateRandomSeed(): int {
return (int)round(rand(0, round(time()) / memory_get_usage(true)) * (int)str_shuffle("127469453645108") / (int)str_shuffle("12746945364"));
}
// Listener
/*
* Checks after a chunk populates so we an add tiles and loot tables
* @param $event pocketmine\event\level\ChunkPopulateEvent
* @return int
/**
* Registers a forest type.
* @param $name string
* @param $treeClass string
* @param array $infos
* @return bool
* @params $infos Array(temperature, rainfall)
*/
public function registerForest(string $name, string $treeClass, array $infos): bool {
if (!@class_exists($treeClass))
return false;
@ -232,66 +293,60 @@ class Main extends PluginBase implements Listener {
return BetterForest::registerForest($name, $treeClass, $infos);
}
/*
* Checks when a player interacts with a loot chest to create it.
/**
* Checks when a player attempts to open a loot chest which is not created yet
* @param PlayerInteractEvent $event
*/
public function onChunkPopulate(ChunkPopulateEvent $event) {
$cfg = new Config(LootTable::getPluginFolder() . "processingLoots.json", Config::JSON);
foreach ($cfg->getAll() as $key => $value) {
list($x, $y, $z) = explode(";", $key);
if ($value["saveAs"] == "chest" && $event->getLevel()->getBlockIdAt($x, $y, $z) == Block::AIR) {
$event->getLevel()->setBlockIdAt($x, $y, $z, Block::CHEST);
} else {
$cfg->remove($key);
$cfg->save();
}
}
}
/*
* Checks when a player breaks a loot chest which is not created to create it
*/
public function onInteract(PlayerInteractEvent $event) {
$cfg = new Config(LootTable::getPluginFolder() . "processingLoots.json", Config::JSON);
if ($event->getBlock()->getId() !== Block::CHEST) return;
if (!$cfg->exists($event->getBlock()->getX() . ";" . $event->getBlock()->getY() . ";" . $event->getBlock()->getZ())) return;
$nbt = new CompoundTag("", [
new ListTag("Items", []),
new StringTag("id", Tile::CHEST),
new IntTag("x", $event->getBlock()->x),
new IntTag("y", $event->getBlock()->y),
new IntTag("z", $event->getBlock()->z)
]);
/** @var Chest $chest */
$chest = Tile::createTile(Tile::CHEST, $event->getBlock()->getLevel(), $nbt);
$chest->setName("§k(Fake)§r Minecart chest");
LootTable::fillChest($chest->getInventory(), $event->getBlock());
if (($block = $event->getBlock())->getId() !== Block::CHEST || $event->getAction() !== PlayerInteractEvent::RIGHT_CLICK_BLOCK) return;
$this->generateLootChest($block);
}
/*
* Check if it's a Tesseract like namespace
* @return bool
*/
/**
* Fills a chest with loot
* @param Block $block
* @param Random|null $random
*/
static public function generateLootChest(Block $block, Random $random = null) {
if (!$block instanceof Chest) return;
$tile = $block->getLevel()->getTile($block);
if (is_null($tile)) {
//TODO new tile, but no loot, because we don't know which type of loot chest this is
$nbt = new CompoundTag("", [
new StringTag("id", Tile::CHEST),
new IntTag("x", (int)$block->x),
new IntTag("y", (int)$block->y),
new IntTag("z", (int)$block->z)
]);
$tile = new TileChest($block->getLevel(), $nbt);
$tile->spawnToAll();
return;
}
if (!$tile instanceof TileChest) return;
//Check if lootchest (or already generated loot)
if (!isset($tile->namedtag->generateLoot)) return;
$table = new LootTable($config = new Config(self::getInstance()->getDataFolder() . 'addon\\' . $tile->namedtag->generateLoot . '.json', Config::DETECT, []));
$size = $tile->getInventory()->getSize();
$loot = $table->getRandomLoot($random);
$items = array_pad($loot, $size, Item::get(0));
shuffle($items);
$tile->getInventory()->setContents($items);
unset($tile->namedtag->generateLoot);
}
/**
* @return Main
*/
static public function getInstance() {
return self::$instance;
}
/**
* Checks when a player breaks a loot chest which is not created yet
* @param BlockBreakEvent $event
*/
public function onBlockBreak(BlockBreakEvent $event) {
$cfg = new Config(LootTable::getPluginFolder() . "processingLoots.json", Config::JSON);
if ($event->getBlock()->getId() !== Block::CHEST) return;
if (!$cfg->exists($event->getBlock()->getX() . ";" . $event->getBlock()->getY() . ";" . $event->getBlock()->getZ())) return;
$nbt = new CompoundTag("", [
new ListTag("Items", []),
new StringTag("id", Tile::CHEST),
new IntTag("x", $event->getBlock()->x),
new IntTag("y", $event->getBlock()->y),
new IntTag("z", $event->getBlock()->z)
]);
/** @var Chest $chest */
$chest = Tile::createTile(Tile::CHEST, $event->getBlock()->getLevel(), $nbt);
$chest->setName("§k(Fake)§r Minecart chest");
LootTable::fillChest($chest->getInventory(), $event->getBlock());
// $event->setCancelled(); //i think nope. You want to break it with items
if (($block = $event->getBlock())->getId() !== Block::CHEST) return;
$this->generateLootChest($block);
}
}

View file

@ -11,14 +11,15 @@
* @author Ad5001
* @link https://github.com/Ad5001/BetterGen
*/
namespace Ad5001\BetterGen\biome;
use Ad5001\BetterGen\generator\BetterNormal;
use Ad5001\BetterGen\populator\CactusPopulator;
use Ad5001\BetterGen\populator\DeadbushPopulator;
use Ad5001\BetterGen\populator\SugarCanePopulator;
use Ad5001\BetterGen\populator\TemplePopulator;
use Ad5001\BetterGen\populator\WellPopulator;
use Ad5001\BetterGen\generator\BetterNormal;
use pocketmine\block\Block;
use pocketmine\level\generator\biome\Biome;
use pocketmine\level\generator\normal\biome\SandyBiome;
@ -42,11 +43,11 @@ class BetterDesert extends SandyBiome implements Mountainable {
$well = new WellPopulator ();
if(!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("Cactus", BetterNormal::$options["delStruct"])) $this->addPopulator($cactus);
if(!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("Deadbush", BetterNormal::$options["delStruct"])) $this->addPopulator($deadBush);
if(!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("SugarCane", BetterNormal::$options["delStruct"])) $this->addPopulator($sugarCane);
if(!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("Temples", BetterNormal::$options["delStruct"])) $this->addPopulator($temple);
if(!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("Wells", BetterNormal::$options["delStruct"])) $this->addPopulator($well);
if (!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("Cactus", BetterNormal::$options["delStruct"])) $this->addPopulator($cactus);
if (!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("Deadbush", BetterNormal::$options["delStruct"])) $this->addPopulator($deadBush);
if (!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("SugarCane", BetterNormal::$options["delStruct"])) $this->addPopulator($sugarCane);
if (!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("Temples", BetterNormal::$options["delStruct"])) $this->addPopulator($temple);
if (!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("Wells", BetterNormal::$options["delStruct"])) $this->addPopulator($well);
$this->setElevation(63, 70);
// $this->setElevation(66, 70);
@ -54,30 +55,31 @@ class BetterDesert extends SandyBiome implements Mountainable {
$this->temperature = 0.5;
$this->rainfall = 0;
$this->setGroundCover([
Block::get(Block::SAND, 0),
Block::get(Block::SAND, 0),
Block::get(Block::SAND, 0),
Block::get(Block::SAND, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0)
Block::get(Block::SAND, 0),
Block::get(Block::SAND, 0),
Block::get(Block::SAND, 0),
Block::get(Block::SAND, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0)
]);
}
public function getName(): string {
return "BetterDesert";
}
/*
/**
* Returns biome id
*/
public function getId() {

View file

@ -25,55 +25,46 @@ use pocketmine\level\generator\normal\biome\ForestBiome;
class BetterForest extends ForestBiome implements Mountainable {
static $types = [
"Oak Forest",
"Birch Forest",
"Sakura Forest"
"Oak Forest",
"Birch Forest",
"Sakura Forest"
];
static $ids = [
Biome::FOREST,
Biome::BIRCH_FOREST,
Main::SAKURA_FOREST
Biome::FOREST,
Biome::BIRCH_FOREST,
Main::SAKURA_FOREST
];
public function __construct($type = 0, array $infos = [0.6, 0.5]) {
parent::__construct($type);
$this->clearPopulators ();
$this->clearPopulators();
$this->type = $type;
$bush = new BushPopulator($type);
$bush->setBaseAmount(10);
if(!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("Bushes", BetterNormal::$options["delStruct"])) $this->addPopulator($bush);
if (!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("Bushes", BetterNormal::$options["delStruct"])) $this->addPopulator($bush);
$ft = new FallenTreePopulator($type);
$ft->setBaseAmount(0);
$ft->setRandomAmount(4);
if(!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("FallenTrees", BetterNormal::$options["delStruct"])) $this->addPopulator($ft);
if (!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("FallenTrees", BetterNormal::$options["delStruct"])) $this->addPopulator($ft);
$trees = new TreePopulator($type);
$trees->setBaseAmount((null !== @constant(TreePopulator::$types[$type] . "::maxPerChunk")) ? constant(TreePopulator::$types[$type] . "::maxPerChunk") : 5);
if(!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("Trees", BetterNormal::$options["delStruct"])) $this->addPopulator($trees);
if (!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("Trees", BetterNormal::$options["delStruct"])) $this->addPopulator($trees);
$tallGrass = Main::isOtherNS() ? new \pocketmine\level\generator\normal\populator\TallGrass () : new \pocketmine\level\generator\populator\TallGrass();
$tallGrass->setBaseAmount(3);
if(!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("TallGrass", BetterNormal::$options["delStruct"])) $this->addPopulator($tallGrass);
if (!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("TallGrass", BetterNormal::$options["delStruct"])) $this->addPopulator($tallGrass);
$this->setElevation(63, 69);
$this->temperature = $infos[0];
$this->rainfall = $infos[1];
}
public function getName() {
return str_ireplace(" ", "", self::$types[$this->type]);
}
/**
* Returns the ID relatively.
* @return int
*/
public function getId() {
return self::$ids[$this->type];
}
/**
* @param string $name
* @param string $treeClass
@ -87,4 +78,16 @@ class BetterForest extends ForestBiome implements Mountainable {
Main::register(Main::SAKURA_FOREST + (count(self::$types) - 2), new BetterForest(count(self::$types) - 1, $infos));
return true;
}
public function getName() {
return str_ireplace(" ", "", self::$types[$this->type]);
}
/**
* Returns the ID relatively.
* @return int
*/
public function getId() {
return self::$ids[$this->type];
}
}

View file

@ -22,26 +22,27 @@ use pocketmine\level\generator\normal\biome\SnowyBiome;
class BetterIcePlains extends SnowyBiome implements Mountainable {
public function __construct() {
parent::__construct ();
parent::__construct();
$this->setGroundCover([
Block::get(Block::SNOW, 0),
Block::get(Block::GRASS, 0),
Block::get(Block::DIRT, 0),
Block::get(Block::DIRT, 0),
Block::get(Block::DIRT, 0)
Block::get(Block::SNOW, 0),
Block::get(Block::GRASS, 0),
Block::get(Block::DIRT, 0),
Block::get(Block::DIRT, 0),
Block::get(Block::DIRT, 0)
]);
if(!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("Igloos", BetterNormal::$options["delStruct"])) $this->addPopulator(new IglooPopulator ());
if (!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("Igloos", BetterNormal::$options["delStruct"])) $this->addPopulator(new IglooPopulator ());
$tallGrass = Main::isOtherNS() ? new \pocketmine\level\generator\normal\populator\TallGrass() : new \pocketmine\level\generator\populator\TallGrass();
$tallGrass->setBaseAmount(3);
if(!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("TallGrass", BetterNormal::$options["delStruct"])) $this->addPopulator($tallGrass);
if (!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("TallGrass", BetterNormal::$options["delStruct"])) $this->addPopulator($tallGrass);
$this->setElevation(63, 74);
$this->temperature = 0.05;
$this->rainfall = 0.8;
}
public function getName() {
return "BetterIcePlains";
}

View file

@ -44,13 +44,13 @@ class BetterMesa extends SandyBiome {
$ores = Main::isOtherNS() ? new \pocketmine\level\generator\normal\populator\Ore() : new \pocketmine\level\generator\populator\Ore();
$ores->setOreTypes([
Main::isOtherNS() ? new \pocketmine\level\generator\normal\object\OreType(new GoldOre (), 2, 8, 0, 32) : new \pocketmine\level\generator\object\OreType(new GoldOre (), 2, 8, 0, 32)
Main::isOtherNS() ? new \pocketmine\level\generator\normal\object\OreType(new GoldOre (), 2, 8, 0, 32) : new \pocketmine\level\generator\object\OreType(new GoldOre (), 2, 8, 0, 32)
]);
if(!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("Cactus", BetterNormal::$options["delStruct"])) $this->addPopulator($cactus);
if(!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("DeadBush", BetterNormal::$options["delStruct"])) $this->addPopulator($deadBush);
if(!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("SugarCane", BetterNormal::$options["delStruct"])) $this->addPopulator($sugarCane);
if(!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("Ores", BetterNormal::$options["delStruct"])) $this->addPopulator($ores);
if (!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("Cactus", BetterNormal::$options["delStruct"])) $this->addPopulator($cactus);
if (!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("DeadBush", BetterNormal::$options["delStruct"])) $this->addPopulator($deadBush);
if (!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("SugarCane", BetterNormal::$options["delStruct"])) $this->addPopulator($sugarCane);
if (!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("Ores", BetterNormal::$options["delStruct"])) $this->addPopulator($ores);
$this->setElevation(80, 83);
// $this->setElevation(66, 70);
@ -58,57 +58,58 @@ class BetterMesa extends SandyBiome {
$this->temperature = 0.8;
$this->rainfall = 0;
$this->setGroundCover([
Block::get(Block::DIRT, 0),
Block::get(Block::HARDENED_CLAY, 0),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::HARDENED_CLAY, 0),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 7),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::HARDENED_CLAY, 0),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 12),
Block::get(Block::STAINED_HARDENED_CLAY, 12),
Block::get(Block::STAINED_HARDENED_CLAY, 12),
Block::get(Block::STAINED_HARDENED_CLAY, 14),
Block::get(Block::STAINED_HARDENED_CLAY, 14),
Block::get(Block::STAINED_HARDENED_CLAY, 14),
Block::get(Block::STAINED_HARDENED_CLAY, 4),
Block::get(Block::STAINED_HARDENED_CLAY, 7),
Block::get(Block::STAINED_HARDENED_CLAY, 0),
Block::get(Block::STAINED_HARDENED_CLAY, 7),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::HARDENED_CLAY, 0),
Block::get(Block::HARDENED_CLAY, 0),
Block::get(Block::HARDENED_CLAY, 0),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::RED_SANDSTONE, 0),
Block::get(Block::RED_SANDSTONE, 0),
Block::get(Block::RED_SANDSTONE, 0),
Block::get(Block::RED_SANDSTONE, 0),
Block::get(Block::RED_SANDSTONE, 0),
Block::get(Block::RED_SANDSTONE, 0),
Block::get(Block::RED_SANDSTONE, 0),
Block::get(Block::RED_SANDSTONE, 0)
Block::get(Block::DIRT, 0),
Block::get(Block::HARDENED_CLAY, 0),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::HARDENED_CLAY, 0),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 7),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::HARDENED_CLAY, 0),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 12),
Block::get(Block::STAINED_HARDENED_CLAY, 12),
Block::get(Block::STAINED_HARDENED_CLAY, 12),
Block::get(Block::STAINED_HARDENED_CLAY, 14),
Block::get(Block::STAINED_HARDENED_CLAY, 14),
Block::get(Block::STAINED_HARDENED_CLAY, 14),
Block::get(Block::STAINED_HARDENED_CLAY, 4),
Block::get(Block::STAINED_HARDENED_CLAY, 7),
Block::get(Block::STAINED_HARDENED_CLAY, 0),
Block::get(Block::STAINED_HARDENED_CLAY, 7),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::HARDENED_CLAY, 0),
Block::get(Block::HARDENED_CLAY, 0),
Block::get(Block::HARDENED_CLAY, 0),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::RED_SANDSTONE, 0),
Block::get(Block::RED_SANDSTONE, 0),
Block::get(Block::RED_SANDSTONE, 0),
Block::get(Block::RED_SANDSTONE, 0),
Block::get(Block::RED_SANDSTONE, 0),
Block::get(Block::RED_SANDSTONE, 0),
Block::get(Block::RED_SANDSTONE, 0),
Block::get(Block::RED_SANDSTONE, 0)
]);
}
public function getName(): string {
return "BetterMesa";
}
/*
/**
* Returns biome id
*/
public function getId() {

View file

@ -39,13 +39,13 @@ class BetterMesaPlains extends SandyBiome {
$ores = Main::isOtherNS() ? new \pocketmine\level\generator\normal\populator\Ore() : new \pocketmine\level\generator\populator\Ore();
$ores->setOreTypes([
Main::isOtherNS() ? new \pocketmine\level\generator\normal\object\OreType(new GoldOre (), 2, 8, 0, 32) : new \pocketmine\level\generator\object\OreType(new GoldOre (), 2, 8, 0, 32)
Main::isOtherNS() ? new \pocketmine\level\generator\normal\object\OreType(new GoldOre (), 2, 8, 0, 32) : new \pocketmine\level\generator\object\OreType(new GoldOre (), 2, 8, 0, 32)
]);
if(!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("Cactus", BetterNormal::$options["delStruct"])) $this->addPopulator($cactus);
if(!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("DeadBush", BetterNormal::$options["delStruct"])) $this->addPopulator($deadBush);
if(!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("SugarCane", BetterNormal::$options["delStruct"])) $this->addPopulator($sugarCane);
if(!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("Ores", BetterNormal::$options["delStruct"])) $this->addPopulator($ores);
if (!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("Cactus", BetterNormal::$options["delStruct"])) $this->addPopulator($cactus);
if (!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("DeadBush", BetterNormal::$options["delStruct"])) $this->addPopulator($deadBush);
if (!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("SugarCane", BetterNormal::$options["delStruct"])) $this->addPopulator($sugarCane);
if (!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("Ores", BetterNormal::$options["delStruct"])) $this->addPopulator($ores);
$this->setElevation(62, 67);
// $this->setElevation(66, 70);
@ -53,58 +53,59 @@ class BetterMesaPlains extends SandyBiome {
$this->temperature = 0.6;
$this->rainfall = 0;
$this->setGroundCover([
Block::get(Block::SAND, 1),
Block::get(Block::SAND, 1),
Block::get(Block::HARDENED_CLAY, 0),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::HARDENED_CLAY, 0),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 7),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::HARDENED_CLAY, 0),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 12),
Block::get(Block::STAINED_HARDENED_CLAY, 12),
Block::get(Block::STAINED_HARDENED_CLAY, 12),
Block::get(Block::STAINED_HARDENED_CLAY, 14),
Block::get(Block::STAINED_HARDENED_CLAY, 14),
Block::get(Block::STAINED_HARDENED_CLAY, 14),
Block::get(Block::STAINED_HARDENED_CLAY, 4),
Block::get(Block::STAINED_HARDENED_CLAY, 7),
Block::get(Block::STAINED_HARDENED_CLAY, 0),
Block::get(Block::STAINED_HARDENED_CLAY, 7),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::HARDENED_CLAY, 0),
Block::get(Block::HARDENED_CLAY, 0),
Block::get(Block::HARDENED_CLAY, 0),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::RED_SANDSTONE, 0),
Block::get(Block::RED_SANDSTONE, 0),
Block::get(Block::RED_SANDSTONE, 0),
Block::get(Block::RED_SANDSTONE, 0),
Block::get(Block::RED_SANDSTONE, 0),
Block::get(Block::RED_SANDSTONE, 0),
Block::get(Block::RED_SANDSTONE, 0),
Block::get(Block::RED_SANDSTONE, 0)
Block::get(Block::SAND, 1),
Block::get(Block::SAND, 1),
Block::get(Block::HARDENED_CLAY, 0),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::HARDENED_CLAY, 0),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 7),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::HARDENED_CLAY, 0),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 12),
Block::get(Block::STAINED_HARDENED_CLAY, 12),
Block::get(Block::STAINED_HARDENED_CLAY, 12),
Block::get(Block::STAINED_HARDENED_CLAY, 14),
Block::get(Block::STAINED_HARDENED_CLAY, 14),
Block::get(Block::STAINED_HARDENED_CLAY, 14),
Block::get(Block::STAINED_HARDENED_CLAY, 4),
Block::get(Block::STAINED_HARDENED_CLAY, 7),
Block::get(Block::STAINED_HARDENED_CLAY, 0),
Block::get(Block::STAINED_HARDENED_CLAY, 7),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::HARDENED_CLAY, 0),
Block::get(Block::HARDENED_CLAY, 0),
Block::get(Block::HARDENED_CLAY, 0),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::STAINED_HARDENED_CLAY, 1),
Block::get(Block::RED_SANDSTONE, 0),
Block::get(Block::RED_SANDSTONE, 0),
Block::get(Block::RED_SANDSTONE, 0),
Block::get(Block::RED_SANDSTONE, 0),
Block::get(Block::RED_SANDSTONE, 0),
Block::get(Block::RED_SANDSTONE, 0),
Block::get(Block::RED_SANDSTONE, 0),
Block::get(Block::RED_SANDSTONE, 0)
]);
}
public function getName(): string {
return "BetterMesaPlains";
}
/*
/**
* Returns biome id
*/
public function getId() {

View file

@ -19,20 +19,20 @@ use pocketmine\level\generator\biome\Biome;
class BetterRiver extends Biome {
public function __construct() {
$this->clearPopulators ();
$this->clearPopulators();
$this->setGroundCover([
Block::get(Block::SAND, 0),
Block::get(Block::SAND, 0),
Block::get(Block::SAND, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0)
Block::get(Block::SAND, 0),
Block::get(Block::SAND, 0),
Block::get(Block::SAND, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0),
Block::get(Block::SANDSTONE, 0)
]);
$this->setElevation(60, 60);
@ -40,11 +40,12 @@ class BetterRiver extends Biome {
$this->temperature = 0.5;
$this->rainfall = 0.7;
}
public function getName() {
return "BetterRiver";
}
/*
/**
* Returns the ID relatively.
*/
public function getId() {

View file

@ -10,7 +10,8 @@
* Tomorrow's pocketmine generator.
* @author Ad5001
* @link https://github.com/Ad5001/BetterGen
*/
*/
namespace Ad5001\BetterGen\generator;
use pocketmine\level\generator\biome\Biome;
@ -29,8 +30,9 @@ class BetterBiomeSelector extends BiomeSelector {
private $rainfall;
/** @var Biome[] */
private $biomes = [ ];
private $biomes = [];
private $lookup;
public function __construct(Random $random, callable $lookup, Biome $fallback) {
parent::__construct($random, $lookup, $fallback);
$this->fallback = $fallback;
@ -38,24 +40,20 @@ class BetterBiomeSelector extends BiomeSelector {
$this->temperature = new Simplex($random, 2, 1 / 16, 1 / 512);
$this->rainfall = new Simplex($random, 2, 1 / 16, 1 / 512);
}
public function recalculate() {
} // Using our own system, No need for that
public function addBiome(Biome $biome) {
$this->biomes[$biome->getId ()] = $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;
$this->biomes[$biome->getId()] = $biome;
}
/**
*
* @param
* $x
* $x
* @param
* $z
* $z
*
* @return Biome
*/
@ -67,4 +65,12 @@ class BetterBiomeSelector extends BiomeSelector {
$b = (($biomeId instanceof Biome) ? $biomeId : ($this->biomes[$biomeId] ?? $this->fallback));
return $b;
}
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;
}
}

View file

@ -10,7 +10,7 @@
* Tomorrow's pocketmine generator.
* @author Ad5001
* @link https://github.com/Ad5001/BetterGen
*/
*/
namespace Ad5001\BetterGen\generator;
@ -47,31 +47,23 @@ use pocketmine\utils\Random;
class BetterNormal extends Generator {
const NOT_OVERWRITABLE = [
Block::STONE,
Block::GRAVEL,
Block::BEDROCK,
Block::DIAMOND_ORE,
Block::GOLD_ORE,
Block::LAPIS_ORE,
Block::REDSTONE_ORE,
Block::IRON_ORE,
Block::COAL_ORE,
Block::WATER,
Block::STILL_WATER
Block::STONE,
Block::GRAVEL,
Block::BEDROCK,
Block::DIAMOND_ORE,
Block::GOLD_ORE,
Block::LAPIS_ORE,
Block::REDSTONE_ORE,
Block::IRON_ORE,
Block::COAL_ORE,
Block::WATER,
Block::STILL_WATER
];
/** @var BetterBiomeSelector */
protected $selector;
/** @var Level */
protected $level;
/** @var Random */
protected $random;
protected $populators = [ ];
protected $generationPopulators = [ ];
public static $biomes = [ ];
public static $biomes = [];
/** @var Biome[] */
public static $biomeById = [ ];
public static $levels = [ ];
protected static $GAUSSIAN_KERNEL = null; // From main class
public static $biomeById = [];
public static $levels = [];
protected static $GAUSSIAN_KERNEL = null;
protected static $SMOOTH_SIZE = 2;
protected static $options = [
"delBio" => [
@ -80,17 +72,307 @@ class BetterNormal extends Generator {
"Lakes"
]
];
/** @var BetterBiomeSelector */
protected $selector;
/** @var Level */
protected $level;
/** @var Random */
protected $random; // From main class
protected $populators = [];
protected $generationPopulators = [];
protected $waterHeight = 63;
private $noiseBase;
/*
/**
* Constructs the class
* @param $options array
*/
public function __construct(array $options = []) {
self::$options["preset"] = $options["preset"];
$options = (array)json_decode($options["preset"]);
if (isset($options["delBio"])) {
if (is_string($options["de"])) $options["delBio"] = explode(",", $options["delBio"]);
if (count($options["delBio"]) !== 0) {
self::$options["delBio"] = $options["delBio"];
}
}
if (isset($options["delStruct"])) {
if (is_string($options["delStruct"])) $options["delStruct"] = explode(",", $options["delStruct"]);
if (count($options["delStruct"]) !== 0) {
self::$options["delStruct"] = $options["delStruct"];
}
}
if (self::$GAUSSIAN_KERNEL === null) {
self::generateKernel();
}
}
/**
* Generates the generation kernel based on smooth size (here 2)
*/
private static function generateKernel() {
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);
}
}
}
/**
* Inits the class for the var
* @param ChunkManager $level
* @param Random $random
* @return void
*/
public function init(ChunkManager $level, Random $random) {
$this->level = $level;
$this->random = $random;
self::$levels[] = $level;
$this->random->setSeed($this->level->getSeed());
$this->noiseBase = new Simplex($this->random, 4, 1 / 4, 1 / 32);
$this->random->setSeed($this->level->getSeed());
$this->registerBiome(Biome::getBiome(Biome::OCEAN));
$this->registerBiome(Biome::getBiome(Biome::PLAINS));
$this->registerBiome(new BetterDesert ());
$this->registerBiome(new BetterMesa ());
$this->registerBiome(new BetterMesaPlains ());
$this->registerBiome(Biome::getBiome(Biome::TAIGA));
$this->registerBiome(Biome::getBiome(Biome::SWAMP));
$this->registerBiome(new BetterRiver ());
$this->registerBiome(new BetterIcePlains ());
$this->registerBiome(new BetterForest(0, [
0.6,
0.5
]));
$this->registerBiome(new BetterForest(1, [
0.7,
0.8
]));
$this->registerBiome(new BetterForest(2, [
0.6,
0.4
]));
$this->selector = new BetterBiomeSelector($random, [
self::class,
"getBiome"
], self::getBiome(0, 0));
foreach (self::$biomes as $rain) {
foreach ($rain as $biome) {
$this->selector->addBiome($biome);
}
}
$this->selector->recalculate();
$cover = Main::isOtherNS() ? new \pocketmine\level\generator\normal\populator\GroundCover() : new \pocketmine\level\generator\populator\GroundCover();
$this->generationPopulators[] = $cover;
if (!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("Lakes", self::$options["delStruct"])) {
$lake = new LakePopulator();
$lake->setBaseAmount(0);
$lake->setRandomAmount(1);
$this->generationPopulators[] = $lake;
}
if (!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("Caves", self::$options["delStruct"])) {
$cave = new CavePopulator ();
$cave->setBaseAmount(0);
$cave->setRandomAmount(2);
$this->generationPopulators[] = $cave;
}
if (!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("Ravines", self::$options["delStruct"])) {
$ravine = new RavinePopulator ();
$ravine->setBaseAmount(0);
$ravine->setRandomAmount(51);
$this->generationPopulators[] = $ravine;
}
if (!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("Mineshafts", self::$options["delStruct"])) {
$mineshaft = new MineshaftPopulator ();
$mineshaft->setBaseAmount(0);
$mineshaft->setRandomAmount(102);
$this->populators[] = $mineshaft;
}
if (!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("FloatingIslands", self::$options["delStruct"])) {
$fisl = new FloatingIslandPopulator();
$fisl->setBaseAmount(0);
$fisl->setRandomAmount(132);
$this->populators[] = $fisl;
}
if (!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("Ores", self::$options["delStruct"])) {
$ores = Main::isOtherNS() ? new \pocketmine\level\generator\normal\populator\Ore() : new \pocketmine\level\generator\populator\Ore();
if (Main::isOtherNS()) $ores->setOreTypes([
new OreType2(new CoalOre (), 20, 16, 0, 128),
new OreType2(new IronOre (), 20, 8, 0, 64),
new OreType2(new RedstoneOre (), 8, 7, 0, 16),
new OreType2(new LapisOre (), 1, 6, 0, 32),
new OreType2(new GoldOre (), 2, 8, 0, 32),
new OreType2(new DiamondOre (), 1, 7, 0, 16),
new OreType2(new Dirt (), 20, 32, 0, 128),
new OreType2(new Gravel (), 10, 16, 0, 128)
]);
if (!Main::isOtherNS()) $ores->setOreTypes([
new OreType(new CoalOre (), 20, 16, 0, 128),
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),
new OreType(new DiamondOre (), 1, 7, 0, 16),
new OreType(new Dirt (), 20, 32, 0, 128),
new OreType(new Gravel (), 10, 16, 0, 128)
]);
$this->populators[] = $ores;
}
}
/**
* Adds a biome to the selector. Do not use this method directly use Main::registerBiome which registers it properly
* @param $biome Biome
* @return bool
*/
public static function registerBiome(Biome $biome): bool {
if (\Ad5001\BetterGen\utils\CommonUtils::in_arrayi($biome->getName(), self::$options["delBio"])) {
return false;
}
foreach (self::$levels as $lvl) if (isset($lvl->selector)) $lvl->selector->addBiome($biome); // If no selector created, it would cause errors. These will be added when selectoes
if (!isset(self::$biomes[(string)$biome->getRainfall()])) self::$biomes[( string)$biome->getRainfall()] = [];
self::$biomes[( string)$biome->getRainfall()] [( string)$biome->getTemperature()] = $biome;
ksort(self::$biomes[( string)$biome->getRainfall()]);
ksort(self::$biomes);
self::$biomeById[$biome->getId()] = $biome;
return true;
}
/**
* Returns a biome by temperature
* @param $temperature float
* @param $rainfall float
*/
public static function getBiome($temperature, $rainfall) {
$ret = null;
if (!isset(self::$biomes[( string)round($rainfall, 1)])) {
while (!isset(self::$biomes[( string)round($rainfall, 1)])) {
if (abs($rainfall - round($rainfall, 1)) >= 0.05)
$rainfall += 0.1;
if (abs($rainfall - round($rainfall, 1)) < 0.05)
$rainfall -= 0.1;
if (round($rainfall, 1) < 0)
$rainfall = 0;
if (round($rainfall, 1) >= 0.9)
$rainfall = 0.9;
}
}
$b = self::$biomes[( string)round($rainfall, 1)];
foreach ($b as $t => $biome) {
if ($temperature <= (float)$t) {
$ret = $biome;
break;
}
}
if (is_string($ret)) {
$ret = new $ret ();
}
return $ret;
}
/**
* Generates a chunk.
* Cloning method to make it work with new methods.
* @param $chunkX int
* @param $chunkZ int
*/
public function generateChunk($chunkX, $chunkZ) {
$this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->level->getSeed());
$noise = Generator::getFastNoise3D($this->noiseBase, 16, 128, 16, 4, 8, 4, $chunkX * 16, 0, $chunkZ * 16);
$chunk = $this->level->getChunk($chunkX, $chunkZ);
$biomeCache = [];
for ($x = 0; $x < 16; $x++) {
for ($z = 0; $z < 16; $z++) {
$minSum = 0;
$maxSum = 0;
$weightSum = 0;
$biome = $this->pickBiome($chunkX * 16 + $x, $chunkZ * 16 + $z);
$chunk->setBiomeId($x, $z, $biome->getId());
for ($sx = -self::$SMOOTH_SIZE; $sx <= self::$SMOOTH_SIZE; $sx++) {
for ($sz = -self::$SMOOTH_SIZE; $sz <= self::$SMOOTH_SIZE; $sz++) {
$weight = self::$GAUSSIAN_KERNEL[$sx + self::$SMOOTH_SIZE] [$sz + self::$SMOOTH_SIZE];
if ($sx === 0 and $sz === 0) {
$adjacent = $biome;
} else {
$index = Level::chunkHash($chunkX * 16 + $x + $sx, $chunkZ * 16 + $z + $sz);
if (isset($biomeCache[$index])) {
$adjacent = $biomeCache[$index];
} else {
$biomeCache[$index] = $adjacent = $this->pickBiome($chunkX * 16 + $x + $sx, $chunkZ * 16 + $z + $sz);
}
}
$minSum += ($adjacent->getMinElevation() - 1) * $weight;
$maxSum += $adjacent->getMaxElevation() * $weight;
$weightSum += $weight;
}
}
$minSum /= $weightSum;
$maxSum /= $weightSum;
$smoothHeight = ($maxSum - $minSum) / 2;
for ($y = 0; $y < 128; $y++) {
if ($y < 3 || ($y < 5 && $this->random->nextBoolean())) {
$chunk->setBlockId($x, $y, $z, Block::BEDROCK);
continue;
}
$noiseValue = $noise[$x] [$z] [$y] - 1 / $smoothHeight * ($y - $smoothHeight - $minSum);
if ($noiseValue > 0) {
$chunk->setBlockId($x, $y, $z, Block::STONE);
} elseif ($y <= $this->waterHeight) {
$chunk->setBlockId($x, $y, $z, Block::STILL_WATER);
}
}
}
}
foreach ($this->generationPopulators as $populator) {
$populator->populate($this->level, $chunkX, $chunkZ, $this->random);
}
}
/**
* Picks a biome by X and Z
* @param $x int
* @param $z int
* @param $x int
* @param $z int
* @return Biome
*/
public function pickBiome($x, $z) {
$hash = $x * 2345803 ^ $z * 9236449 ^ $this->level->getSeed ();
$hash = $x * 2345803 ^ $z * 9236449 ^ $this->level->getSeed();
$hash *= $hash + 223;
$xNoise = $hash >> 20 & 3;
$zNoise = $hash >> 22 & 3;
@ -110,268 +392,21 @@ class BetterNormal extends Generator {
}
/**
* Inits the class for the var
* @param ChunkManager $level
* @param Random $random
* @return void
*/
public function init(ChunkManager $level, Random $random) {
$this->level = $level;
$this->random = $random;
self::$levels[] = $level;
$this->random->setSeed($this->level->getSeed ());
$this->noiseBase = new Simplex($this->random, 4, 1 / 4, 1 / 32);
$this->random->setSeed($this->level->getSeed ());
$this->registerBiome(Biome::getBiome(Biome::OCEAN));
$this->registerBiome(Biome::getBiome(Biome::PLAINS));
$this->registerBiome(new BetterDesert ());
$this->registerBiome(new BetterMesa ());
$this->registerBiome(new BetterMesaPlains ());
$this->registerBiome(Biome::getBiome(Biome::TAIGA));
$this->registerBiome(Biome::getBiome(Biome::SWAMP));
$this->registerBiome(new BetterRiver ());
$this->registerBiome(new BetterIcePlains ());
$this->registerBiome(new BetterForest(0, [
0.6,
0.5
]));
$this->registerBiome(new BetterForest(1, [
0.7,
0.8
]));
$this->registerBiome(new BetterForest(2, [
0.6,
0.4
]));
$this->selector = new BetterBiomeSelector($random, [
self::class,
"getBiome"
], self::getBiome(0, 0));
foreach(self::$biomes as $rain) {
foreach($rain as $biome) {
$this->selector->addBiome($biome);
}
}
$this->selector->recalculate ();
$cover = Main::isOtherNS() ? new \pocketmine\level\generator\normal\populator\GroundCover() : new \pocketmine\level\generator\populator\GroundCover();
$this->generationPopulators[] = $cover;
if(!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("Lakes", self::$options["delStruct"])) {
$lake = new LakePopulator();
$lake->setBaseAmount(0);
$lake->setRandomAmount(1);
$this->generationPopulators[] = $lake;
}
if(!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("Caves", self::$options["delStruct"])) {
$cave = new CavePopulator ();
$cave->setBaseAmount(0);
$cave->setRandomAmount(2);
$this->generationPopulators[] = $cave;
}
if(!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("Ravines", self::$options["delStruct"])) {
$ravine = new RavinePopulator ();
$ravine->setBaseAmount(0);
$ravine->setRandomAmount(51);
$this->generationPopulators[] = $ravine;
}
if(!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("Mineshafts", self::$options["delStruct"])) {
$mineshaft = new MineshaftPopulator ();
$mineshaft->setBaseAmount(0);
$mineshaft->setRandomAmount(102);
$this->populators[] = $mineshaft;
}
if(!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("FloatingIslands", self::$options["delStruct"])) {
$fisl = new FloatingIslandPopulator();
$fisl->setBaseAmount(0);
$fisl->setRandomAmount(132);
$this->populators[] = $fisl;
}
if(!\Ad5001\BetterGen\utils\CommonUtils::in_arrayi("Ores", self::$options["delStruct"])) {
$ores = Main::isOtherNS() ? new \pocketmine\level\generator\normal\populator\Ore() : new \pocketmine\level\generator\populator\Ore();
if(Main::isOtherNS()) $ores->setOreTypes([
new OreType2(new CoalOre (), 20, 16, 0, 128),
new OreType2(new IronOre (), 20, 8, 0, 64),
new OreType2(new RedstoneOre (), 8, 7, 0, 16),
new OreType2(new LapisOre (), 1, 6, 0, 32),
new OreType2(new GoldOre (), 2, 8, 0, 32),
new OreType2(new DiamondOre (), 1, 7, 0, 16),
new OreType2(new Dirt (), 20, 32, 0, 128),
new OreType2(new Gravel (), 10, 16, 0, 128)
]);
if(!Main::isOtherNS()) $ores->setOreTypes([
new OreType(new CoalOre (), 20, 16, 0, 128),
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),
new OreType(new DiamondOre (), 1, 7, 0, 16),
new OreType(new Dirt (), 20, 32, 0, 128),
new OreType(new Gravel (), 10, 16, 0, 128)
]);
$this->populators[] = $ores;
}
}
/*
* Adds a biome to the selector. Do not use this method directly use Main::registerBiome which registers it properly
* @param $biome Biome
* @return bool
*/
public static function registerBiome(Biome $biome): bool {
if(\Ad5001\BetterGen\utils\CommonUtils::in_arrayi($biome->getName(), self::$options["delBio"])) {
return false;
}
foreach(self::$levels as $lvl) if(isset($lvl->selector)) $lvl->selector->addBiome($biome); // If no selector created, it would cause errors. These will be added when selectoes
if (! isset(self::$biomes[(string) $biome->getRainfall ()])) self::$biomes[( string) $biome->getRainfall ()] = [ ];
self::$biomes[( string) $biome->getRainfall ()] [( string) $biome->getTemperature ()] = $biome;
ksort(self::$biomes[( string) $biome->getRainfall ()]);
ksort(self::$biomes);
self::$biomeById[$biome->getId()] = $biome;
return true;
}
/*
* Returns a biome by temperature
* @param $temperature float
* @param $rainfall float
*/
public static function getBiome($temperature, $rainfall) {
$ret = null;
if (! isset(self::$biomes[( string) round($rainfall, 1)])) {
while(! isset(self::$biomes[( string) round($rainfall, 1)])) {
if (abs($rainfall - round($rainfall, 1)) >= 0.05)
$rainfall += 0.1;
if (abs($rainfall - round($rainfall, 1)) < 0.05)
$rainfall -= 0.1;
if (round($rainfall, 1) < 0)
$rainfall = 0;
if (round($rainfall, 1) >= 0.9)
$rainfall = 0.9;
}
}
$b = self::$biomes[( string) round($rainfall, 1)];
foreach($b as $t => $biome) {
if ($temperature <=(float) $t) {
$ret = $biome;
break;
}
}
if (is_string($ret)) {
$ret = new $ret ();
}
return $ret;
}
/*
* Returns a biome by its id
* @param $id int
* @return Biome
*/
public function getBiomeById(int $id): Biome {
return self::$biomeById[$id] ?? self::$biomeById[Biome::OCEAN];
}
/*
* Generates a chunk.
* Cloning method to make it work with new methods.
* @param $chunkX int
* @param $chunkZ int
*/
public function generateChunk($chunkX, $chunkZ) {
$this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->level->getSeed ());
$noise = Generator::getFastNoise3D($this->noiseBase, 16, 128, 16, 4, 8, 4, $chunkX * 16, 0, $chunkZ * 16);
$chunk = $this->level->getChunk($chunkX, $chunkZ);
$biomeCache = [ ];
for($x = 0; $x < 16; $x++) {
for($z = 0; $z < 16; $z++) {
$minSum = 0;
$maxSum = 0;
$weightSum = 0;
$biome = $this->pickBiome($chunkX * 16 + $x, $chunkZ * 16 + $z);
$chunk->setBiomeId($x, $z, $biome->getId ());
for($sx = - self::$SMOOTH_SIZE; $sx <= self::$SMOOTH_SIZE; $sx++) {
for($sz = - self::$SMOOTH_SIZE; $sz <= self::$SMOOTH_SIZE; $sz++) {
$weight = self::$GAUSSIAN_KERNEL[$sx + self::$SMOOTH_SIZE] [$sz + self::$SMOOTH_SIZE];
if ($sx === 0 and $sz === 0) {
$adjacent = $biome;
} else {
$index = Level::chunkHash($chunkX * 16 + $x + $sx, $chunkZ * 16 + $z + $sz);
if (isset($biomeCache[$index])) {
$adjacent = $biomeCache[$index];
} else {
$biomeCache[$index] = $adjacent = $this->pickBiome($chunkX * 16 + $x + $sx, $chunkZ * 16 + $z + $sz);
}
}
$minSum += ($adjacent->getMinElevation () - 1) * $weight;
$maxSum += $adjacent->getMaxElevation () * $weight;
$weightSum += $weight;
}
}
$minSum /= $weightSum;
$maxSum /= $weightSum;
$smoothHeight = ($maxSum - $minSum) / 2;
for($y = 0; $y < 128; $y++) {
if ($y < 3 || ($y < 5 && $this->random->nextBoolean ())) {
$chunk->setBlockId($x, $y, $z, Block::BEDROCK);
continue;
}
$noiseValue = $noise[$x] [$z] [$y] - 1 / $smoothHeight * ($y - $smoothHeight - $minSum);
if ($noiseValue > 0) {
$chunk->setBlockId($x, $y, $z, Block::STONE);
} elseif ($y <= $this->waterHeight) {
$chunk->setBlockId($x, $y, $z, Block::STILL_WATER);
}
}
}
}
foreach($this->generationPopulators as $populator) {
$populator->populate($this->level, $chunkX, $chunkZ, $this->random);
}
}
/*
* Populates a chunk.
* @param $chunkX int
* @param $chunk2 int
*/
public function populateChunk($chunkX, $chunkZ) {
$this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->level->getSeed ());
foreach($this->populators as $populator) {
$this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->level->getSeed());
foreach ($this->populators as $populator) {
$populator->populate($this->level, $chunkX, $chunkZ, $this->random);
}
// Filling lava (lakes & rivers underground)...
for($x = $chunkX; $x < $chunkX + 16; $x ++)
for($z = $chunkZ; $z < $chunkZ + 16; $z ++)
for($y = 1; $y < 11; $y ++) {
if (! in_array($this->level->getBlockIdAt($x, $y, $z), self::NOT_OVERWRITABLE))
for ($x = $chunkX; $x < $chunkX + 16; $x++)
for ($z = $chunkZ; $z < $chunkZ + 16; $z++)
for ($y = 1; $y < 11; $y++) {
if (!in_array($this->level->getBlockIdAt($x, $y, $z), self::NOT_OVERWRITABLE))
$this->level->setBlockIdAt($x, $y, $z, Block::LAVA);
}
@ -380,85 +415,52 @@ class BetterNormal extends Generator {
$biome->populateChunk($this->level, $chunkX, $chunkZ, $this->random);
}
/*
* Constructs the class
* @param $options array
/**
* Returns a biome by its id
* @param $id int
* @return Biome
*/
public function __construct(array $options = []) {
self::$options["preset"] = $options["preset"];
$options = (array) json_decode($options["preset"]);
if(isset($options["delBio"])) {
if(is_string($options["de"])) $options["delBio"] = explode(",", $options["delBio"]);
if(count($options["delBio"]) !== 0) {
self::$options["delBio"] = $options["delBio"];
}
}
if(isset($options["delStruct"])) {
if(is_string($options["delStruct"])) $options["delStruct"] = explode(",", $options["delStruct"]);
if(count($options["delStruct"]) !== 0) {
self::$options["delStruct"] = $options["delStruct"];
}
}
if (self::$GAUSSIAN_KERNEL === null) {
self::generateKernel ();
}
}
/*
* Generates the generation kernel based on smooth size (here 2)
*/
private static function generateKernel() {
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 getBiomeById(int $id): Biome {
return self::$biomeById[$id] ?? self::$biomeById[Biome::OCEAN];
}
//  Returns the name of the generator
public function getName() {
return "betternormal";
}
/*
/**
* Gives the generators settings.
* @return array
*/
public function getSettings(): array {
return self::$options;
}
public function getSpawn() {
return new Vector3(127.5, 128, 127.5);
}
/*
/**
* Returns a safe spawn location
*/
public function getSafeSpawn() {
return new Vector3(127.5, $this->getHighestWorkableBlock(127, 127), 127.5);
}
/*
/**
* Gets the top block (y) on an x and z axes
* @param $x int
* @param $z int
*/
protected function getHighestWorkableBlock($x, $z) {
for($y = Level::Y_MAX - 1; $y > 0; -- $y) {
for ($y = Level::Y_MAX - 1; $y > 0; --$y) {
$b = $this->level->getBlockIdAt($x, $y, $z);
if ($b === Block::DIRT or $b === Block::GRASS or $b === Block::PODZOL) {
break;
} elseif ($b !== 0 and $b !== Block::SNOW_LAYER) {
return - 1;
return -1;
}
}

View file

@ -14,116 +14,157 @@
namespace Ad5001\BetterGen\loot;
use pocketmine\inventory\BaseInventory;
use Ad5001\BetterGen\Main;
use pocketmine\item\Item;
use pocketmine\math\Vector3;
use pocketmine\nbt\NBT;
use pocketmine\item\Tool;
use pocketmine\utils\Config;
use pocketmine\utils\Random;
/*
* This class is used for loot setting.
* Please note that they AREN'T as powerful as PC ones due to some implementations limitations.
* Loot table format:
* {
* "max": Max number of loots (storable amount)
* "example": {
* "percentage": Chance of appearing(in percent)
* "minCount": Minimal count
* "maxCount": Maximal count
* "id": Id of the item
* "data": Item damage
* "tags": {"display": {"Name": "Example NBT data"}}. This parameter is optional
* "minStacks": If chosen, the minimum amount of stacks that can be found
* "maxStacks": If chosen the maximum number of stacks that can be chosen
* }
* }
*/
class LootTable {
const LOOT_NAMES = [
"temple",
"igloo",
"mineshaft"
];
const LOOT_SAVE = [
"chest",
"chest",
"chest"
];
const LOOT_DESERT_TEMPLE = 0;
const LOOT_IGLOO = 1;
const LOOT_MINESHAFT = 2;
/*
* Asynchronous loot table choosing
* @param $place pocketmine\math\Vector3
* @param $type int
* @param $random pocketmine\utils\Random
* @return void
/**
* @var null|Config The lootfile (.json) thats used
*/
public static function buildLootTable(Vector3 $place, int $type, Random $random) {
if($place->y < 1) return; // Making sure sometimes that it doesn't write for nothing
$cfg = new Config(self::getPluginFolder() . "processingLoots.json", Config::JSON);
$lootsFromJson = json_decode(file_get_contents(self::getResourcesFolder() . "loots/" . self::LOOT_NAMES[$type] . ".json"), true);
$loots =[];
foreach($lootsFromJson as $loot) {
if(is_array($loot) && $random->nextBoundedInt(101) < $loot["percentage"])
$loots[] = $loot;
}
if($lootsFromJson["max"] < count($loots)) {
while($lootsFromJson["max"] < count($loots))
unset($loots[array_rand($loots)]);
}
$loots["saveAs"] = self::LOOT_SAVE[$type];
$cfg->set($place->x . ";" . $place->y . ";" . $place->z, $loots);
$cfg->save();
private $lootFile = null;
/**
* LootTable constructor.
* @param Config $lootFile
*/
public function __construct(Config $lootFile) {
$this->lootFile = $lootFile;
}
/*
* Synchronous inventory filling with loot table.
* @param $inv pocketmine\inventory\BaseInventory
* @param $pos pocketmine\math\Vector3
* @return void
/**
* Public function to generate loot. A {@link: \pocketmine\utils\Random} can be passed. Serves as file reader + sub-table loader
* Do _NOT_ use this in the source, use LootTable::createLoot instead
* @param Random|null $random
* @return Item[]
*/
public static function fillChest(BaseInventory $inv, Vector3 $pos) {
$cfg = new Config(self::getPluginFolder() . "processingLoots.json", Config::JSON);
if($cfg->exists($pos->x . ";" . $pos->y . ";" . $pos->z)) {
$loots = $cfg->get($pos->x . ";" . $pos->y . ";" . $pos->z);
$items = [];
foreach($loots as $loot) {
if(!is_array($loot)) continue;
$randCount = rand($loot["minStacks"], $loot["maxStacks"]);
for($i = 0; $i <= $randCount; $i++) {
$rand = rand(0, count($loots));
$items[$rand] = Item::get($loot["id"], $loot["data"], rand($loot["minCount"], $loot["maxCount"]));
if(isset($loot["tags"])) $items[$rand]->setCompoundTag(NBT::parseJSON($loot["tags"]));
public function getRandomLoot(Random $random = null) {
if (is_null($random)) $random = new Random();
$items = [];
foreach ($this->lootFile->get("pools") as $rolls) {
if (isset($rolls["rolls"]["min"]) && isset($rolls["rolls"]["max"])) $maxrolls = $random->nextRange($rolls["rolls"]["min"], $rolls["rolls"]["max"]);
else $maxrolls = $rolls["rolls"];//TODO: $rolls["conditions"] //Example: looting swords
while ($maxrolls > 0) {
$array = [];
$maxrolls--;
foreach ($rolls["entries"] as $index => $entries) {
$array[] = $entries["weight"]??1;
}
$val = $rolls["entries"][$this->getRandomWeightedElement($array)];
//typecheck
if ($val["type"] == "loot_table") {
$loottable = new LootTable(new Config(Main::getInstance()->getDataFolder() . 'addon\\' . $val["name"] . ".json", Config::DETECT, []));
$items = array_merge($items, $loottable->getRandomLoot($random));
unset($loottable);
} elseif ($val["type"] == "item") {
//name fix
$val["name"] = self::fixItemName($val["name"]);
$item = Item::fromString($val["name"]);
if (isset($val["functions"])) {
foreach ($val["functions"] as $function) {
switch ($functionname = $function["function"]) {
case "set_damage": {
if ($item instanceof Tool) $item->setDamage($random->nextRange($function["damage"]["min"] * $item->getMaxDurability(), $function["damage"]["max"] * $item->getMaxDurability()));
else $item->setDamage($random->nextRange($function["damage"]["min"], $function["damage"]["max"]));
}
break;
case "set_data": {
//fish fix, blame mojang
if ($item->getId() == Item::RAW_FISH) {
switch ($function["data"]) {
case 1:
$item = Item::get(Item::RAW_SALMON, $item->getDamage(), $item->getCount(), $item->getCompoundTag());
break;
case 2:
$item = Item::get(Item::CLOWN_FISH, $item->getDamage(), $item->getCount(), $item->getCompoundTag());
break;
case 3:
$item = Item::get(Item::PUFFER_FISH, $item->getDamage(), $item->getCount(), $item->getCompoundTag());
break;
default:
break;
}
} else $item->setDamage($function["data"]);
}
break;
case "set_count": {
$item->setCount($random->nextRange($function["count"]["min"], $function["count"]["max"]));
}
break;
case "furnace_smelt": {
/* TODO
Mostly bound to conditions (burning)
"conditions": [
{
"condition": "entity_properties",
"entity": "this",
"properties": {
"on_fire": true
}
}
]
*/
}
break;
case "enchant_randomly": {
//TODO
}
break;
case "enchant_with_levels": {
//TODO
}
break;
case "looting_enchant": {
//TODO
}
break;
default:
assert("Unknown looting table function $functionname, skipping");
}
}
}
$items[] = $item;
}
}
$inv->setContents($items);
$cfg->remove($pos->x . ";" . $pos->y . ";" . $pos->z);
$cfg->save();
}
return $items;
}
/*
* Returns the plugins folder.
* @return string
/**
* TODO: Make Random::class actually useful here.
* @param array $weightedValues
* @return mixed
*/
public static function getPluginFolder(): string {
$dir = explode(DIRECTORY_SEPARATOR, __DIR__);
$c = count($dir);
unset($dir[$c - 1], $dir[$c - 2], $dir[$c - 3], $dir[$c - 4], $dir[$c - 5]);
return str_ireplace("phar://", "", implode(DIRECTORY_SEPARATOR, $dir)) . DIRECTORY_SEPARATOR . "BetterGen" . DIRECTORY_SEPARATOR;
private function getRandomWeightedElement(array $weightedValues) {
$array = array();
foreach ($weightedValues as $key => $weight) {
$array = array_merge(array_fill(0, $weight, $key), $array);
}
return $array[array_rand($array)];
}
/*
* Returns the resources folder.
* @return string
/**
* Fixes the item names because #BlameMojang for not changing the id's from PC -> PE
* @param $name
* @return mixed
*/
public static function getResourcesFolder(): string {
$dir = explode(DIRECTORY_SEPARATOR, __DIR__);
$c = count($dir);
unset($dir[$c - 1], $dir[$c - 2], $dir[$c - 3], $dir[$c - 4]);
return str_ireplace("phar://", "", implode(DIRECTORY_SEPARATOR, $dir)) . DIRECTORY_SEPARATOR . "resources" . DIRECTORY_SEPARATOR;
private static function fixItemName($name) {
switch ($name) {
case 'minecraft:horsearmoriron':
$name = 'minecraft:iron_horse_armor';
break;
case 'minecraft:horsearmorgold':
$name = 'minecraft:gold_horse_armor';
break;
case 'minecraft:horsearmordiamond':
$name = 'minecraft:diamond_horse_armor';
break;
default: {
}
}
return $name;
}
}

View file

@ -21,27 +21,11 @@ abstract class AmountPopulator extends Populator {
protected $baseAmount = 0;
protected $randomAmount = 0;
/*
/**
* Crosssoftware class for random amount
*/
/*
* Sets the random addition amount
* @param $amount int
*/
public function setRandomAmount(int $amount) {
$this->randomAmount = $amount;
}
/*
* Sets the base addition amount
* @param $amount int
*/
public function setBaseAmount(int $amount) {
$this->baseAmount = $amount;
}
/*
/**
* Returns the amount based on random
* @param $random Random
*/
@ -49,7 +33,7 @@ abstract class AmountPopulator extends Populator {
return $this->baseAmount + $random->nextRange(0, $this->randomAmount + 1);
}
/*
/**
* Returns the base amount
* @return int
*/
@ -57,11 +41,27 @@ abstract class AmountPopulator extends Populator {
return $this->baseAmount;
}
/*
/**
* Sets the base addition amount
* @param $amount int
*/
public function setBaseAmount(int $amount) {
$this->baseAmount = $amount;
}
/**
* Returns the random additional amount
* @return int
*/
public function getRandomAmount(): int {
return $this->randomAmount;
}
/**
* Sets the random addition amount
* @param $amount int
*/
public function setRandomAmount(int $amount) {
$this->randomAmount = $amount;
}
}

View file

@ -25,7 +25,7 @@ class BushPopulator extends AmountPopulator {
protected $level;
protected $type;
/*
/**
* Constructs the class
* @param $type int
*/
@ -33,7 +33,7 @@ class BushPopulator extends AmountPopulator {
$this->type = $type;
}
/*
/**
* Populate the chunk
* @param $level pocketmine\level\ChunkManager
* @param $chunkX int
@ -43,7 +43,7 @@ class BushPopulator extends AmountPopulator {
public function populate(ChunkManager $level, $chunkX, $chunkZ, Random $random) {
$this->level = $level;
$amount = $this->getAmount($random);
for($i = 0; $i < $amount; $i++) {
for ($i = 0; $i < $amount; $i++) {
$x = $random->nextRange($chunkX << 4, ($chunkX << 4) + 15);
$z = $random->nextRange($chunkZ << 4, ($chunkZ << 4) + 15);
$y = $this->getHighestWorkableBlock($x, $z);
@ -56,18 +56,18 @@ class BushPopulator extends AmountPopulator {
}
}
/*
/**
* Gets the top block (y) on an x and z axes
* @param $x int
* @param $z int
*/
protected function getHighestWorkableBlock($x, $z) {
for($y = Level::Y_MAX - 1; $y > 0; -- $y) {
for ($y = Level::Y_MAX - 1; $y > 0; --$y) {
$b = $this->level->getBlockIdAt($x, $y, $z);
if ($b === Block::DIRT or $b === Block::GRASS or $b === Block::PODZOL) {
break;
} elseif ($b !== 0 and $b !== Block::SNOW_LAYER) {
return - 1;
return -1;
}
}

View file

@ -24,7 +24,8 @@ use pocketmine\utils\Random;
class CactusPopulator extends AmountPopulator {
/** @var ChunkManager */
protected $level;
/*
/**
* Constructs the class
*/
public function __construct() {
@ -32,7 +33,7 @@ class CactusPopulator extends AmountPopulator {
$this->setRandomAmount(2);
}
/*
/**
* Populate the chunk
* @param $level pocketmine\level\ChunkManager
* @param $chunkX int
@ -43,7 +44,7 @@ class CactusPopulator extends AmountPopulator {
$this->level = $level;
$amount = $this->getAmount($random);
$cactus = new Cactus ();
for($i = 0; $i < $amount; $i++) {
for ($i = 0; $i < $amount; $i++) {
$x = $random->nextRange($chunkX * 16, $chunkX * 16 + 15);
$z = $random->nextRange($chunkZ * 16, $chunkZ * 16 + 15);
$y = $this->getHighestWorkableBlock($x, $z);
@ -53,18 +54,18 @@ class CactusPopulator extends AmountPopulator {
}
}
/*
/**
* Gets the top block (y) on an x and z axes
* @param $x int
* @param $z int
*/
protected function getHighestWorkableBlock($x, $z) {
for($y = Level::Y_MAX - 1; $y >= 0; -- $y) {
for ($y = Level::Y_MAX - 1; $y >= 0; --$y) {
$b = $this->level->getBlockIdAt($x, $y, $z);
if ($b !== Block::AIR and $b !== Block::LEAVES and $b !== Block::LEAVES2) {
break;
}
}
return $y === 0 ? - 1 : ++$y;
return $y === 0 ? -1 : ++$y;
}
}

View file

@ -22,12 +22,12 @@ use pocketmine\math\Vector3;
use pocketmine\utils\Random;
class CavePopulator extends AmountPopulator {
/** @var ChunkManager */
protected $level;
const STOP = false;
const CONTINUE = true;
/** @var ChunkManager */
protected $level;
/*
/**
* Populate the chunk
* @param $level pocketmine\level\ChunkManager
* @param $chunkX int
@ -37,7 +37,7 @@ class CavePopulator extends AmountPopulator {
public function populate(ChunkManager $level, $chunkX, $chunkZ, Random $random) {
$this->level = $level;
$amount = $this->getAmount($random);
for($i = 0; $i < $amount; $i++) {
for ($i = 0; $i < $amount; $i++) {
$x = $random->nextRange($chunkX << 4, ($chunkX << 4) + 15);
$z = $random->nextRange($chunkZ << 4, ($chunkZ << 4) + 15);
$y = $random->nextRange(10, $this->getHighestWorkableBlock($x, $z));
@ -46,12 +46,12 @@ class CavePopulator extends AmountPopulator {
}
// echo "Finished Populating chunk $chunkX, $chunkZ !" . PHP_EOL;
// Filling water & lava sources randomly
for($i = 0; $i < $random->nextBoundedInt(5) + 3; $i ++) {
for ($i = 0; $i < $random->nextBoundedInt(5) + 3; $i++) {
$x = $random->nextRange($chunkX << 4, ($chunkX << 4) + 15);
$z = $random->nextRange($chunkZ << 4, ($chunkZ << 4) + 15);
$y = $random->nextRange(10, $this->getHighestWorkableBlock($x, $z));
if ($level->getBlockIdAt($x, $y, $z) == Block::STONE && ($level->getBlockIdAt($x + 1, $y, $z) == Block::AIR || $level->getBlockIdAt($x - 1, $y, $z) == Block::AIR || $level->getBlockIdAt($x, $y, $z + 1) == Block::AIR || $level->getBlockIdAt($x, $y, $z - 1) == Block::AIR) && $level->getBlockIdAt($x, $y - 1, $z) !== Block::AIR && $level->getBlockIdAt($x, $y + 1, $z) !== Block::AIR) {
if ($y < 40 && $random->nextBoolean ()) {
if ($y < 40 && $random->nextBoolean()) {
$level->setBlockIdAt($x, $y, $z, Block::LAVA);
} else {
$level->setBlockIdAt($x, $y, $z, Block::WATER);
@ -60,25 +60,25 @@ class CavePopulator extends AmountPopulator {
}
}
/*
/**
* Gets the top block (y) on an x and z axes
* @param $x int
* @param $z int
*/
protected function getHighestWorkableBlock($x, $z) {
for($y = Level::Y_MAX - 1; $y > 0; -- $y) {
for ($y = Level::Y_MAX - 1; $y > 0; --$y) {
$b = $this->level->getBlockIdAt($x, $y, $z);
if ($b === Block::DIRT or $b === Block::GRASS or $b === Block::PODZOL or $b === Block::SAND or $b === Block::SNOW_BLOCK or $b === Block::SANDSTONE) {
break;
} elseif ($b !== 0 and $b !== Block::SNOW_LAYER and $b !== Block::WATER) {
return - 1;
return -1;
}
}
return ++$y;
}
/*
/**
* Generates a cave
* @param $x int
* @param $y int
@ -88,8 +88,8 @@ class CavePopulator extends AmountPopulator {
*/
public function generateCave($x, $y, $z, Random $random) {
$generatedBranches = $random->nextBoundedInt(10) + 1;
foreach($gen = $this->generateBranch($x, $y, $z, 5, 3, 5, $random) as $v3) {
$generatedBranches --;
foreach ($gen = $this->generateBranch($x, $y, $z, 5, 3, 5, $random) as $v3) {
$generatedBranches--;
if ($generatedBranches <= 0) {
$gen->send(self::STOP);
} else {
@ -97,7 +97,8 @@ class CavePopulator extends AmountPopulator {
}
}
}
/*
/**
* Generates a cave branch.
* @param $x int
* @param $y int
@ -110,29 +111,29 @@ class CavePopulator extends AmountPopulator {
* @return void
*/
public function generateBranch($x, $y, $z, $length, $height, $depth, Random $random) {
if (! (yield new Vector3($x, $y, $z))) {
for($i = 0; $i <= 4; $i ++) {
if (!(yield new Vector3($x, $y, $z))) {
for ($i = 0; $i <= 4; $i++) {
BuildingUtils::buildRandom($this->level, new Vector3($x, $y, $z), new Vector3($length - $i, $height - $i, $depth - $i), $random, Block::get(Block::AIR));
$x += round(($random->nextBoundedInt(round(30 * ($length / 10)) + 1) / 10 - 2));
$yP = $random->nextRange(-14, 14);
if ($yP > 12) {
$y ++;
} elseif ($yP < - 12) {
$y --;
$y++;
} elseif ($yP < -12) {
$y--;
}
$z += round(($random->nextBoundedInt(round(30 * ($depth / 10)) + 1) / 10 - 1));
return;
}
}
$repeat = $random->nextBoundedInt(25) + 15;
while($repeat-- > 0) {
while ($repeat-- > 0) {
BuildingUtils::buildRandom($this->level, new Vector3($x, $y, $z), new Vector3($length, $height, $depth), $random, Block::get(Block::AIR));
$x += round(($random->nextBoundedInt(round(30 * ($length / 10)) + 1) / 10 - 2));
$yP = $random->nextRange(- 14, 14);
$yP = $random->nextRange(-14, 14);
if ($yP > 12) {
$y ++;
} elseif ($yP < - 12) {
$y --;
$y++;
} elseif ($yP < -12) {
$y--;
}
$z += round(($random->nextBoundedInt(round(30 * ($depth / 10)) + 1) / 10 - 1));
$height += $random->nextBoundedInt(3) - 1;
@ -151,8 +152,8 @@ class CavePopulator extends AmountPopulator {
if ($height < 7)
$height = 7;
if ($random->nextBoundedInt(10) == 0) {
foreach($generator = $this->generateBranch($x, $y, $z, $length, $height, $depth, $random) as $gen) {
if (! (yield $gen))
foreach ($generator = $this->generateBranch($x, $y, $z, $length, $height, $depth, $random) as $gen) {
if (!(yield $gen))
$generator->send(self::STOP);
}
}

View file

@ -14,7 +14,6 @@
namespace Ad5001\BetterGen\populator;
use Ad5001\BetterGen\generator\BetterBiomeSelector;
use pocketmine\block\Block;
use pocketmine\level\ChunkManager;
use pocketmine\level\generator\biome\Biome;
@ -25,7 +24,7 @@ class DeadbushPopulator extends AmountPopulator {
/** @var ChunkManager */
protected $level;
/*
/**
* Populate the chunk
* @param $level pocketmine\level\ChunkManager
* @param $chunkX int
@ -35,10 +34,10 @@ class DeadbushPopulator extends AmountPopulator {
public function populate(ChunkManager $level, $chunkX, $chunkZ, Random $random) {
$this->level = $level;
$amount = $this->getAmount($random);
for($i = 0; $i < $amount; $i++) {
for ($i = 0; $i < $amount; $i++) {
$x = $random->nextRange($chunkX * 16, $chunkX * 16 + 15);
$z = $random->nextRange($chunkZ * 16, $chunkZ * 16 + 15);
if(!in_array($level->getChunk($chunkX, $chunkZ)->getBiomeId(abs($x % 16), ($z % 16)), [40, 39, Biome::DESERT])) continue;
if (!in_array($level->getChunk($chunkX, $chunkZ)->getBiomeId(abs($x % 16), ($z % 16)), [40, 39, Biome::DESERT])) continue;
$y = $this->getHighestWorkableBlock($x, $z);
if ($y !== -1 && $level->getBlockIdAt($x, $y - 1, $z) == Block::SAND) {
$level->setBlockIdAt($x, $y, $z, Block::DEAD_BUSH);
@ -53,12 +52,12 @@ class DeadbushPopulator extends AmountPopulator {
* @param $z
* @return int
*/
private function getHighestWorkableBlock($x, $z){
for($y = Level::Y_MAX - 1; $y > 0; --$y){
private function getHighestWorkableBlock($x, $z) {
for ($y = Level::Y_MAX - 1; $y > 0; --$y) {
$b = $this->level->getBlockIdAt($x, $y, $z);
if($b === Block::DIRT or $b === Block::GRASS or $b === Block::SAND or $b === Block::SANDSTONE or $b === Block::HARDENED_CLAY or $b === Block::STAINED_HARDENED_CLAY){
if ($b === Block::DIRT or $b === Block::GRASS or $b === Block::SAND or $b === Block::SANDSTONE or $b === Block::HARDENED_CLAY or $b === Block::STAINED_HARDENED_CLAY) {
break;
}elseif($b !== Block::AIR){
} elseif ($b !== Block::AIR) {
return -1;
}
}

View file

@ -25,7 +25,8 @@ class FallenTreePopulator extends AmountPopulator {
/** @var ChunkManager */
protected $level;
protected $type;
/*
/**
* Constructs the class
* @param $type int
*/
@ -35,7 +36,7 @@ class FallenTreePopulator extends AmountPopulator {
$this->setRandomAmount(2);
}
/*
/**
* Populate the chunk
* @param $level pocketmine\level\ChunkManager
* @param $chunkX int
@ -45,15 +46,15 @@ class FallenTreePopulator extends AmountPopulator {
public function populate(ChunkManager $level, $chunkX, $chunkZ, Random $random) {
$this->level = $level;
$amount = $this->getAmount($random);
$tree = TreePopulator::$types[$this->type];
$tree = TreePopulator::$types[$this->type];
$fallenTree = new \Ad5001\BetterGen\structure\FallenTree(
new $tree()
);
for($i = 0; $i < $amount; $i++) {
for ($i = 0; $i < $amount; $i++) {
$x = $random->nextRange($chunkX * 16, $chunkX * 16 + 15);
$z = $random->nextRange($chunkZ * 16, $chunkZ * 16 + 15);
$y = $this->getHighestWorkableBlock($x, $z);
if(isset(FallenTree::$overridable[$level->getBlockIdAt($x, $y, $z)])) $y--; // Changing $y if 1 block to high.
if (isset(FallenTree::$overridable[$level->getBlockIdAt($x, $y, $z)])) $y--; // Changing $y if 1 block to high.
if ($y !== -1 and $fallenTree->canPlaceObject($level, $x, $y + 1, $z, $random)) {
$fallenTree->placeObject($level, $x, $y + 1, $z);
}
@ -66,12 +67,12 @@ class FallenTreePopulator extends AmountPopulator {
* @param $z
* @return int
*/
private function getHighestWorkableBlock($x, $z){
for($y = Level::Y_MAX - 1; $y > 0; --$y){
private function getHighestWorkableBlock($x, $z) {
for ($y = Level::Y_MAX - 1; $y > 0; --$y) {
$b = $this->level->getBlockIdAt($x, $y, $z);
if($b === Block::DIRT or $b === Block::GRASS){
if ($b === Block::DIRT or $b === Block::GRASS) {
break;
}elseif($b !== Block::AIR and $b !== Block::SNOW_LAYER){
} elseif ($b !== Block::AIR and $b !== Block::SNOW_LAYER) {
return -1;
}
}

View file

@ -33,19 +33,19 @@ use pocketmine\utils\Random;
class FloatingIslandPopulator extends AmountPopulator {
/*
/**
* Populate the chunk
* @param $level pocketmine\level\ChunkManager
* @param $chunkX int
* @param $chunkZ int
* @param $random pocketmine\utils\Random
* @param $level pocketmine\level\ChunkManager
* @param $chunkX int
* @param $chunkZ int
* @param $random pocketmine\utils\Random
*/
/** @var ChunkManager */
private $level;
public function populate(ChunkManager $level, $chunkX, $chunkZ, Random $random) {
$this->level = $level;
if($this->getAmount($random) > 130) {
if ($this->getAmount($random) > 130) {
$x = $random->nextRange(($chunkX << 4), ($chunkX << 4) + 15);
$z = $random->nextRange(($chunkX << 4), ($chunkX << 4) + 15);
$y = $random->nextRange($this->getHighestWorkableBlock($x, $z) < 96 ? $this->getHighestWorkableBlock($x, $z) + 20 : $this->getHighestWorkableBlock($x, $z), 126);
@ -55,21 +55,20 @@ class FloatingIslandPopulator extends AmountPopulator {
$chunk = $level->getChunk($chunkX, $chunkZ);
$biome = BetterNormal::$biomeById[$chunk->getBiomeId($x % 16, $z % 16)];
$populators = $biome->getPopulators();
foreach($populators as $populator) {
foreach ($populators as $populator) {
$populator->populate($level, $chunkX, $chunkZ, $random);
}
}
}
/*
/**
* Gets the top block (y) on an x and z axes
* @param $x int
* @param $z int
*/
protected function getHighestWorkableBlock($x, $z) {
for($y = Level::Y_MAX - 1; $y > 0; -- $y) {
for ($y = Level::Y_MAX - 1; $y > 0; --$y) {
$b = $this->level->getBlockIdAt($x, $y, $z);
if ($b === Block::DIRT or $b === Block::GRASS or $b === Block::PODZOL or $b === Block::SAND) {
break;
@ -82,34 +81,33 @@ class FloatingIslandPopulator extends AmountPopulator {
}
/*
/**
* Builds a an island shape
* @param $level pocketmine\level\ChunkManager
* @param $pos pocketmine\math\Vector3
* @param $radius int
* @param $random pocketmine\utils\Random
* @return int lowest ore point
* @param $level pocketmine\level\ChunkManager
* @param $pos pocketmine\math\Vector3
* @param $radius int
* @param $random pocketmine\utils\Random
* @return int lowest ore point
*/
public function buildIslandBottomShape(ChunkManager $level, Vector3 $pos, int $radius, Random $random) {
$pos = $pos->round();
$currentLen = 1;
$hBound = 0;
$current = 0;
for($y = $pos->y - 1; $radius > 0; $y--) {
for($x = $pos->x - $radius; $x <= $pos->x + $radius; $x++) {
for($z = $pos->z - $radius; $z <= $pos->z + $radius; $z ++) {
if(abs(abs($x - $pos->x) ** 2) + abs(abs($z - $pos->z) ** 2) == ($radius ** 2) * 0.67) {
for ($y = $pos->y - 1; $radius > 0; $y--) {
for ($x = $pos->x - $radius; $x <= $pos->x + $radius; $x++) {
for ($z = $pos->z - $radius; $z <= $pos->z + $radius; $z++) {
if (abs(abs($x - $pos->x) ** 2) + abs(abs($z - $pos->z) ** 2) == ($radius ** 2) * 0.67) {
$isEdge = true;
} else {
$isEdge = false;
}
if(abs(abs($x - $pos->x) ** 2) + abs(abs($z - $pos->z) ** 2) <= ($radius ** 2) * 0.67 && $y < 128) {
if($chunk = $level->getChunk($x >> 4, $z >> 4)) {
if (abs(abs($x - $pos->x) ** 2) + abs(abs($z - $pos->z) ** 2) <= ($radius ** 2) * 0.67 && $y < 128) {
if ($chunk = $level->getChunk($x >> 4, $z >> 4)) {
$biome = BetterNormal::$biomeById[$chunk->getBiomeId($x % 16, $z % 16)];
$block = $biome->getGroundCover()[$pos->y - $y - 1] ?? Block::get(Block::STONE);
$block = $block->getId();
} elseif($random->nextBoundedInt(5) == 0 && $isEdge) {
} elseif ($random->nextBoundedInt(5) == 0 && $isEdge) {
$block = Block::AIR;
} else {
$block = Block::STONE;
@ -121,8 +119,8 @@ class FloatingIslandPopulator extends AmountPopulator {
$current++;
$oldHB = $hBound;
$hBound = $random->nextFloat();
if($current >= $currentLen + $hBound) {
if($radius == 0) return $pos->y;
if ($current >= $currentLen + $hBound) {
if ($radius == 0) return $pos->y;
$current = 0;
$currentLen += 0.3 * ($random->nextFloat() + 0.5);
$radius--;
@ -132,34 +130,32 @@ class FloatingIslandPopulator extends AmountPopulator {
}
/*
/**
* BPopulate the island with ores
* @param $level pocketmine\level\ChunkManager
* @param $pos pocketmine\math\Vector3
* @param $width int
* @param $height int
* @param $random pocketmine\utils\Random
* @return void
* @param $level pocketmine\level\ChunkManager
* @param $pos pocketmine\math\Vector3
* @param $width int
* @param $height int
* @param $random pocketmine\utils\Random
* @return void
*/
public function populateOres(ChunkManager $level, Vector3 $pos, int $width, int $height, Random $random) {
$ores = Main::isOtherNS() ? new \pocketmine\level\generator\normal\populator\Ore() : new \pocketmine\level\generator\populator\Ore();
if(Main::isOtherNS()) $ores->setOreTypes([
new OreType2(new CoalOre (), 20, 16, $pos->y - $height, $pos->y),
new OreType2(new IronOre (), 20, 8, $pos->y - $height, $pos->y - round($height * 0.75)),
new OreType2(new RedstoneOre (), 8, 7, $pos->y - $height, $pos->y - round($height / 2)),
new OreType2(new LapisOre (), 1, 6, $pos->y - $height, $pos->y - round($height / 2)),
new OreType2(new GoldOre (), 2, 8, $pos->y - $height, $pos->y - round($height / 2)),
new OreType2(new DiamondOre (), 1, 7, $pos->y - $height, $pos->y - round($height / 4))
if (Main::isOtherNS()) $ores->setOreTypes([
new OreType2(new CoalOre (), 20, 16, $pos->y - $height, $pos->y),
new OreType2(new IronOre (), 20, 8, $pos->y - $height, $pos->y - round($height * 0.75)),
new OreType2(new RedstoneOre (), 8, 7, $pos->y - $height, $pos->y - round($height / 2)),
new OreType2(new LapisOre (), 1, 6, $pos->y - $height, $pos->y - round($height / 2)),
new OreType2(new GoldOre (), 2, 8, $pos->y - $height, $pos->y - round($height / 2)),
new OreType2(new DiamondOre (), 1, 7, $pos->y - $height, $pos->y - round($height / 4))
]);
if(!Main::isOtherNS()) $ores->setOreTypes([
new OreType(new CoalOre (), 20, 16, $pos->y - $height, $pos->y),
new OreType(new IronOre (), 20, 8, $pos->y - $height, $pos->y - round($height * 0.75)),
new OreType(new RedstoneOre (), 8, 7, $pos->y - $height, $pos->y - round($height / 2)),
new OreType(new LapisOre (), 1, 6, $pos->y - $height, $pos->y - round($height / 2)),
new OreType(new GoldOre (), 2, 8, $pos->y - $height, $pos->y - round($height / 2)),
new OreType(new DiamondOre (), 1, 7, $pos->y - $height, $pos->y - round($height / 4))
if (!Main::isOtherNS()) $ores->setOreTypes([
new OreType(new CoalOre (), 20, 16, $pos->y - $height, $pos->y),
new OreType(new IronOre (), 20, 8, $pos->y - $height, $pos->y - round($height * 0.75)),
new OreType(new RedstoneOre (), 8, 7, $pos->y - $height, $pos->y - round($height / 2)),
new OreType(new LapisOre (), 1, 6, $pos->y - $height, $pos->y - round($height / 2)),
new OreType(new GoldOre (), 2, 8, $pos->y - $height, $pos->y - round($height / 2)),
new OreType(new DiamondOre (), 1, 7, $pos->y - $height, $pos->y - round($height / 4))
]);
$ores->populate($level, $pos->x >> 4, $pos->z >> 4, $random);//x z undefined
}

View file

@ -24,7 +24,7 @@ class IglooPopulator extends AmountPopulator {
/** @var ChunkManager */
protected $level;
/*
/**
* Populate the chunk
* @param $level pocketmine\level\ChunkManager
* @param $chunkX int
@ -43,18 +43,18 @@ class IglooPopulator extends AmountPopulator {
$igloo->placeObject($level, $x, $y, $z, $random);
}
/*
/**
* Gets the top block (y) on an x and z axes
* @param $x int
* @param $z int
*/
protected function getHighestWorkableBlock($x, $z) {
for($y = Level::Y_MAX - 1; $y > 0; -- $y) {
for ($y = Level::Y_MAX - 1; $y > 0; --$y) {
$b = $this->level->getBlockIdAt($x, $y, $z);
if ($b === Block::DIRT or $b === Block::GRASS or $b === Block::PODZOL) {
break;
} elseif ($b !== 0 and $b !== Block::SNOW_LAYER) {
return - 1;
return -1;
}
}

View file

@ -25,7 +25,7 @@ class LakePopulator extends AmountPopulator {
/** @var ChunkManager */
protected $level;
/*
/**
* Populate the chunk
* @param $level pocketmine\level\ChunkManager
* @param $chunkX int
@ -38,32 +38,32 @@ class LakePopulator extends AmountPopulator {
$z = $random->nextRange($chunkZ << 4, ($chunkZ << 4) + 15);
$ory = $random->nextRange(20, 63); // Water level
$y = $ory;
for($i = 0; $i < 4; $i ++) {
$x += $random->nextRange(- 1, 1);
$y += $random->nextRange(- 1, 1);
$z += $random->nextRange(- 1, 1);
for ($i = 0; $i < 4; $i++) {
$x += $random->nextRange(-1, 1);
$y += $random->nextRange(-1, 1);
$z += $random->nextRange(-1, 1);
if ($level->getBlockIdAt($x, $y, $z) !== Block::AIR)
BuildingUtils::buildRandom($this->level, new Vector3($x, $y, $z), new Vector3(5, 5, 5), $random, Block::get(Block::WATER));
}
for($xx = $x - 8; $xx <= $x + 8; $xx ++)
for($zz = $z - 8; $zz <= $z + 8; $zz ++)
for($yy = $ory + 1; $yy <= $y + 3; $yy ++)
for ($xx = $x - 8; $xx <= $x + 8; $xx++)
for ($zz = $z - 8; $zz <= $z + 8; $zz++)
for ($yy = $ory + 1; $yy <= $y + 3; $yy++)
if ($level->getBlockIdAt($xx, $yy, $zz) == Block::WATER)
$level->setBlockIdAt($xx, $yy, $zz, Block::AIR);
}
/*
/**
* Gets the top block (y) on an x and z axes
* @param $x int
* @param $z int
*/
protected function getHighestWorkableBlock($x, $z) {
for($y = Level::Y_MAX - 1; $y > 0; -- $y) {
for ($y = Level::Y_MAX - 1; $y > 0; --$y) {
$b = $this->level->getBlockIdAt($x, $y, $z);
if ($b === Block::DIRT or $b === Block::GRASS or $b === Block::PODZOL) {
break;
} elseif ($b !== 0 and $b !== Block::SNOW_LAYER) {
return - 1;
return -1;
}
}

View file

@ -22,9 +22,6 @@ use pocketmine\math\Vector3;
use pocketmine\utils\Random;
class MineshaftPopulator extends AmountPopulator {
protected $maxPath;
/** @var ChunkManager */
protected $level;
const DIR_XPLUS = 0;
const DIR_XMIN = 1;
const DIR_ZPLUS = 2;
@ -32,8 +29,11 @@ class MineshaftPopulator extends AmountPopulator {
const TYPE_FORWARD = 0;
const TYPE_CROSSPATH = 1;
const TYPE_STAIRS = 2;
protected $maxPath;
/** @var ChunkManager */
protected $level;
/*
/**
* Populate the chunk
* @param $level pocketmine\level\ChunkManager
* @param $chunkX int
@ -52,7 +52,7 @@ class MineshaftPopulator extends AmountPopulator {
BuildingUtils::fill($level, new Vector3($x - 6, $y, $x - 6), new Vector3($x + 6, $y, $z + 6), Block::get(Block::DIRT));
$startingPath = $random->nextBoundedInt(4);
$this->maxPath = $random->nextBoundedInt(100) + 50;
foreach(array_fill(0, $startingPath, 1) as $hey) {
foreach (array_fill(0, $startingPath, 1) as $hey) {
$dir = $random->nextBoundedInt(4);
switch ($dir) {
case self::DIR_XPLUS :
@ -80,7 +80,7 @@ class MineshaftPopulator extends AmountPopulator {
* @param Random $random
*/
public function generateMineshaftPart(int $x, int $y, int $z, int $dir, Random $random) {
if ($this->maxPath -- < 1)
if ($this->maxPath-- < 1)
return;
$type = $random->nextBoundedInt(3);
$level = $this->level;
@ -114,10 +114,10 @@ class MineshaftPopulator extends AmountPopulator {
$level->setBlockDataAt($x + 1, $y + 2, $z, 2);
// Generating chest
if ($random->nextBoundedInt(30) == 0) {
$direction =(int) $random->nextBoolean ();
$direction = (int)$random->nextBoolean();
if ($direction == 0)
$direction = -1; // Choosing the part of the rail.
$direction2 =(int) $random->nextBoolean ();
$direction2 = (int)$random->nextBoolean();
if ($direction2 == 0)
$direction2 = 2;
if ($direction2 == 1)
@ -155,10 +155,10 @@ class MineshaftPopulator extends AmountPopulator {
$level->setBlockDataAt($x - 1, $y + 2, $z, 1);
// Generating chest
if ($random->nextBoundedInt(30) == 0) {
$direction =(int) $random->nextBoolean ();
$direction = (int)$random->nextBoolean();
if ($direction == 0)
$direction = -1; // Choosing the part of the rail.
$direction2 =(int) $random->nextBoolean ();
$direction2 = (int)$random->nextBoolean();
if ($direction2 == 0)
$direction2 = 2;
if ($direction2 == 1)
@ -196,10 +196,10 @@ class MineshaftPopulator extends AmountPopulator {
$level->setBlockDataAt($x, $y + 2, $z - 1, 4);
// Generating chest
if ($random->nextBoundedInt(30) == 0) {
$direction =(int) $random->nextBoolean ();
$direction = (int)$random->nextBoolean();
if ($direction == 0)
$direction = -1; // Choosing the part of the rail.
$direction2 =(int) $random->nextBoolean ();
$direction2 = (int)$random->nextBoolean();
if ($direction2 == 0)
$direction2 = 2;
if ($direction2 == 1)
@ -237,10 +237,10 @@ class MineshaftPopulator extends AmountPopulator {
$level->setBlockDataAt($x, $y + 2, $z - 1, 3);
// Generating chest
if ($random->nextBoundedInt(30) == 0) {
$direction =(int) $random->nextBoolean ();
$direction = (int)$random->nextBoolean();
if ($direction == 0)
$direction = -1; // Choosing the part of the rail.
$direction2 =(int) $random->nextBoolean ();
$direction2 = (int)$random->nextBoolean();
if ($direction2 == 0)
$direction2 = 2;
if ($direction2 == 1)
@ -253,7 +253,7 @@ class MineshaftPopulator extends AmountPopulator {
}
// Doing cobwebs
$webNum = $random->nextBoundedInt(5) + 2;
for($i = 0; $i < $webNum; $i ++) {
for ($i = 0; $i < $webNum; $i++) {
$xx = $x + $random->nextBoundedInt(5) - 2;
$yy = $y + $random->nextBoundedInt(3);
$zz = $z + $random->nextBoundedInt(5) - 2;
@ -263,26 +263,26 @@ class MineshaftPopulator extends AmountPopulator {
break;
case self::TYPE_CROSSPATH :
$possiblePathes = [
self::DIR_XPLUS,
self::DIR_XMIN,
self::DIR_ZPLUS,
self::DIR_ZMIN
self::DIR_XPLUS,
self::DIR_XMIN,
self::DIR_ZPLUS,
self::DIR_ZMIN
];
switch ($dir) {
case self::DIR_XPLUS :
$x ++;
$x++;
unset($possiblePathes[0]);
break;
case self::DIR_XMIN :
$x --;
$x--;
unset($possiblePathes[1]);
break;
case self::DIR_ZPLUS :
$z ++;
$z++;
unset($possiblePathes[2]);
break;
case self::DIR_ZMIN :
$z --;
$z--;
unset($possiblePathes[3]);
break;
}
@ -299,24 +299,24 @@ class MineshaftPopulator extends AmountPopulator {
BuildingUtils::corners($this->level, new Vector3($x - 1, $y, $z - 1), new Vector3($x + 1, $y + 6, $z + 1), Block::get(Block::PLANK));
$newFloor = $random->nextBoolean ();
$newFloor = $random->nextBoolean();
$numberFloor = $random->nextBoundedInt(4 + ($newFloor ? 5 : 0));
$possiblePathes = [
$possiblePathes,
($newFloor ?[
self::DIR_XPLUS,
self::DIR_XMIN,
self::DIR_ZPLUS,
self::DIR_ZMIN
] : [ ])
$possiblePathes,
($newFloor ? [
self::DIR_XPLUS,
self::DIR_XMIN,
self::DIR_ZPLUS,
self::DIR_ZMIN
] : [])
];
for($i = 7; $i > $newFloor; $i --) {
$chooseNew =(int) $newFloor && $random->nextBoolean ();
for ($i = 7; $i > $newFloor; $i--) {
$chooseNew = (int)$newFloor && $random->nextBoolean();
$choose = $random->nextBoundedInt(4);
unset($possiblePathes[$chooseNew] [$choose]);
}
// Building pathes
foreach($possiblePathes[0] as $path) {
foreach ($possiblePathes[0] as $path) {
switch ($path) {
case self::DIR_XPLUS :
$this->generateMineshaftPart($x + 2, $y, $z, self::DIR_XPLUS, $random);
@ -332,7 +332,7 @@ class MineshaftPopulator extends AmountPopulator {
break;
}
}
foreach($possiblePathes[1] as $path) {
foreach ($possiblePathes[1] as $path) {
switch ($path) {
case self::DIR_XPLUS :
$this->generateMineshaftPart($x + 2, $y + 4, $z, self::DIR_XPLUS, $random);
@ -351,7 +351,7 @@ class MineshaftPopulator extends AmountPopulator {
// Doing cobwebs
$webNum = $random->nextBoundedInt(5) + 2;
for($i = 0; $i < $webNum; $i ++) {
for ($i = 0; $i < $webNum; $i++) {
$xx = $x + $random->nextBoundedInt(3) - 1;
$yy = $y + $random->nextBoundedInt(6);
$zz = $z + $random->nextBoundedInt(3) - 1;
@ -360,12 +360,12 @@ class MineshaftPopulator extends AmountPopulator {
}
break;
case self::TYPE_STAIRS :
if($y <= 5) {
if ($y <= 5) {
$this->generateMineshaftPart($x, $y, $z, $dir, $random);
return;
}
// Building stairs
for($i = 0; $i < 4; $i ++) {
for ($i = 0; $i < 4; $i++) {
switch ($i) {
case self::DIR_XPLUS :
BuildingUtils::fill($this->level, new Vector3($x + $i, $y - $i - 1, $z - 2), new Vector3($x + $i, $y - $i + 3, $z + 2), Block::get(Block::AIR));
@ -420,4 +420,5 @@ class MineshaftPopulator extends AmountPopulator {
}
}
}
?>

View file

@ -21,11 +21,11 @@ use pocketmine\level\Level;
use pocketmine\utils\Random;
class RavinePopulator extends AmountPopulator {
const NOISE = 250;
/** @var ChunkManager */
protected $level;
const NOISE = 250;
/*
/**
* Populate the chunk
* @param $level pocketmine\level\ChunkManager
* @param $chunkX int
@ -44,18 +44,18 @@ class RavinePopulator extends AmountPopulator {
$deffZ = $z;
$height = $random->nextRange(15, 30);
$length = $random->nextRange(5, 12);
for($i = 0; $i < $depth; $i ++) {
for ($i = 0; $i < $depth; $i++) {
$this->buildRavinePart($x, $y, $z, $height, $length, $random);
$diffX = $x - $deffX;
$diffZ = $z - $deffZ;
if ($diffX > $length / 2)
$diffX = $length / 2;
if ($diffX < - $length / 2)
$diffX = - $length / 2;
if ($diffX < -$length / 2)
$diffX = -$length / 2;
if ($diffZ > $length / 2)
$diffZ = $length / 2;
if ($diffZ < - $length / 2)
$diffZ = - $length / 2;
if ($diffZ < -$length / 2)
$diffZ = -$length / 2;
if ($length > 10)
$length = 10;
if ($length < 5)
@ -69,25 +69,25 @@ class RavinePopulator extends AmountPopulator {
}
}
/*
/**
* Gets the top block (y) on an x and z axes
* @param $x int
* @param $z int
*/
protected function getHighestWorkableBlock($x, $z) {
for($y = Level::Y_MAX - 1; $y > 0; -- $y) {
for ($y = Level::Y_MAX - 1; $y > 0; --$y) {
$b = $this->level->getBlockIdAt($x, $y, $z);
if ($b === Block::DIRT or $b === Block::GRASS or $b === Block::PODZOL or $b === Block::SAND or $b === Block::SNOW_BLOCK or $b === Block::SANDSTONE) {
break;
} elseif ($b !== 0 and $b !== Block::SNOW_LAYER and $b !== Block::WATER) {
return - 1;
return -1;
}
}
return ++$y;
}
/*
/**
* Builds a ravine part
* @param $x int
* @param $y int
@ -99,29 +99,29 @@ class RavinePopulator extends AmountPopulator {
protected function buildRavinePart($x, $y, $z, $height, $length, Random $random) {
$xBounded = 0;
$zBounded = 0;
for($xx = $x - $length; $xx <= $x + $length; $xx ++) {
for($yy = $y; $yy <= $y + $height; $yy ++) {
for($zz = $z - $length; $zz <= $z + $length; $zz ++) {
for ($xx = $x - $length; $xx <= $x + $length; $xx++) {
for ($yy = $y; $yy <= $y + $height; $yy++) {
for ($zz = $z - $length; $zz <= $z + $length; $zz++) {
$oldXB = $xBounded;
$xBounded = $random->nextBoundedInt(self::NOISE * 2) - self::NOISE;
$oldZB = $zBounded;
$zBounded = $random->nextBoundedInt(self::NOISE * 2) - self::NOISE;
if ($xBounded > self::NOISE - 2) {
$xBounded = 1;
} elseif ($xBounded < - self::NOISE + 2) {
} elseif ($xBounded < -self::NOISE + 2) {
$xBounded = -1;
} else {
$xBounded = $oldXB;
}
if ($zBounded > self::NOISE - 2) {
$zBounded = 1;
} elseif ($zBounded < - self::NOISE + 2) {
} elseif ($zBounded < -self::NOISE + 2) {
$zBounded = -1;
} else {
$zBounded = $oldZB;
}
if (abs((abs($xx) - abs($x)) ** 2 + (abs($zz) - abs($z)) ** 2) < ((($length / 2 - $xBounded) + ($length / 2 - $zBounded)) / 2) ** 2 && $y > 0 && ! in_array($this->level->getBlockIdAt(( int) round($xx),(int) round($yy),(int) round($zz)), BuildingUtils::TO_NOT_OVERWRITE) && ! in_array($this->level->getBlockIdAt(( int) round($xx),(int) round($yy + 1),(int) round($zz)), BuildingUtils::TO_NOT_OVERWRITE)) {
$this->level->setBlockIdAt(( int) round($xx),(int) round($yy),(int) round($zz), Block::AIR);
if (abs((abs($xx) - abs($x)) ** 2 + (abs($zz) - abs($z)) ** 2) < ((($length / 2 - $xBounded) + ($length / 2 - $zBounded)) / 2) ** 2 && $y > 0 && !in_array($this->level->getBlockIdAt(( int)round($xx), (int)round($yy), (int)round($zz)), BuildingUtils::TO_NOT_OVERWRITE) && !in_array($this->level->getBlockIdAt(( int)round($xx), (int)round($yy + 1), (int)round($zz)), BuildingUtils::TO_NOT_OVERWRITE)) {
$this->level->setBlockIdAt(( int)round($xx), (int)round($yy), (int)round($zz), Block::AIR);
}
}
}

View file

@ -23,7 +23,8 @@ use pocketmine\utils\Random;
class SugarCanePopulator extends AmountPopulator {
/** @var ChunkManager */
protected $level;
/*
/**
* Constructs the class
*/
public function __construct() {
@ -31,7 +32,7 @@ class SugarCanePopulator extends AmountPopulator {
$this->setRandomAmount(2);
}
/*
/**
* Populate the chunk
* @param $level pocketmine\level\ChunkManager
* @param $chunkX int
@ -42,7 +43,7 @@ class SugarCanePopulator extends AmountPopulator {
$this->level = $level;
$amount = $this->getAmount($random);
$sugarcane = new SugarCane ();
for($i = 0; $i < $amount; $i++) {
for ($i = 0; $i < $amount; $i++) {
$x = $random->nextRange($chunkX * 16, $chunkX * 16 + 15);
$z = $random->nextRange($chunkZ * 16, $chunkZ * 16 + 15);
$y = $this->getHighestWorkableBlock($x, $z);
@ -52,18 +53,18 @@ class SugarCanePopulator extends AmountPopulator {
}
}
/*
/**
* Gets the top block (y) on an x and z axes
* @param $x int
* @param $z int
*/
protected function getHighestWorkableBlock($x, $z) {
for($y = Level::Y_MAX - 1; $y >= 0; -- $y) {
for ($y = Level::Y_MAX - 1; $y >= 0; --$y) {
$b = $this->level->getBlockIdAt($x, $y, $z);
if ($b !== Block::AIR and $b !== Block::LEAVES and $b !== Block::LEAVES2) {
break;
}
}
return $y === 0 ? - 1 : ++$y;
return $y === 0 ? -1 : ++$y;
}
}

View file

@ -24,7 +24,7 @@ class TemplePopulator extends AmountPopulator {
/** @var Level */
protected $level;
/*
/**
* Populate the chunk
* @param $level pocketmine\level\ChunkManager
* @param $chunkX int
@ -43,13 +43,13 @@ class TemplePopulator extends AmountPopulator {
$temple->placeObject($level, $x, $y - 1, $z, $random);
}
/*
/**
* Gets the top block (y) on an x and z axes
* @param $x int
* @param $z int
*/
protected function getHighestWorkableBlock($x, $z) {
for($y = Level::Y_MAX - 1; $y > 0; -- $y) {
for ($y = Level::Y_MAX - 1; $y > 0; --$y) {
$b = $this->level->getBlockIdAt($x, $y, $z);
if ($b === Block::SAND) {
break;

View file

@ -25,20 +25,20 @@ use pocketmine\utils\Random;
class TreePopulator extends AmountPopulator {
/** @var Tree[] */
static $types = [
"pocketmine\\level\\generator\\object\\OakTree",
"pocketmine\\level\\generator\\object\\BirchTree",
"Ad5001\\BetterGen\\structure\\SakuraTree"
"pocketmine\\level\\generator\\object\\OakTree",
"pocketmine\\level\\generator\\object\\BirchTree",
"Ad5001\\BetterGen\\structure\\SakuraTree"
];
/** @var ChunkManager */
protected $level;
protected $type;
/*
/**
* Constructs the class
*/
public function __construct($type = 0) {
$this->type = $type;
if(Main::isOtherNS()) {
if (Main::isOtherNS()) {
self::$types = [
"pocketmine\\level\\generator\\normal\\object\\OakTree",
"pocketmine\\level\\generator\\normal\\object\\BirchTree",
@ -47,7 +47,7 @@ class TreePopulator extends AmountPopulator {
}
}
/*
/**
* Populate the chunk
* @param $level pocketmine\level\ChunkManager
* @param $chunkX int
@ -57,7 +57,7 @@ class TreePopulator extends AmountPopulator {
public function populate(ChunkManager $level, $chunkX, $chunkZ, Random $random) {
$this->level = $level;
$amount = $this->getAmount($random);
for($i = 0; $i < $amount; $i++) {
for ($i = 0; $i < $amount; $i++) {
$x = $random->nextRange($chunkX << 4, ($chunkX << 4) + 15);
$z = $random->nextRange($chunkZ << 4, ($chunkZ << 4) + 15);
$y = $this->getHighestWorkableBlock($x, $z);
@ -71,18 +71,18 @@ class TreePopulator extends AmountPopulator {
}
}
/*
/**
* Gets the top block (y) on an x and z axes
* @param $x int
* @param $z int
*/
protected function getHighestWorkableBlock($x, $z) {
for($y = Level::Y_MAX - 1; $y > 0; -- $y) {
for ($y = Level::Y_MAX - 1; $y > 0; --$y) {
$b = $this->level->getBlockIdAt($x, $y, $z);
if ($b === Block::DIRT or $b === Block::GRASS or $b === Block::PODZOL) {
break;
} elseif ($b !== 0 and $b !== Block::SNOW_LAYER) {
return - 1;
return -1;
}
}

View file

@ -24,7 +24,7 @@ class WellPopulator extends AmountPopulator {
/** @var ChunkManager */
protected $level;
/*
/**
* Populate the chunk
* @param $level pocketmine\level\ChunkManager
* @param $chunkX int
@ -43,13 +43,13 @@ class WellPopulator extends AmountPopulator {
$well->placeObject($level, $x, $y, $z, $random);
}
/*
/**
* Gets the top block (y) on an x and z axes
* @param $x int
* @param $z int
*/
protected function getHighestWorkableBlock($x, $z) {
for($y = Level::Y_MAX - 1; $y > 0; -- $y) {
for ($y = Level::Y_MAX - 1; $y > 0; --$y) {
$b = $this->level->getBlockIdAt($x, $y, $z);
if ($b === Block::SAND) {
break;

View file

@ -22,27 +22,27 @@ use pocketmine\utils\Random;
class Bush extends Object {
public $overridable = [
Block::AIR => true,
17 => true,
Block::SNOW_LAYER => true,
Block::LOG2 => true
Block::AIR => true,
17 => true,
Block::SNOW_LAYER => true,
Block::LOG2 => true
];
protected $leaf;
protected $height;
/*
/**
* Constructs the class
* @param $leafId int
* @param $leafData int
*/
public function __construct($leafId = Block::LEAVES, $leafData = 0) {
$this->leaf = [
$leafId,
$leafData
$leafId,
$leafData
];
}
/*
/**
* Places a bush
* @param $level pocketmine\level\ChunkManager
* @param $x int
@ -54,8 +54,8 @@ class Bush extends Object {
$number = $random->nextBoundedInt(6);
$pos = new Vector3($x, $y, $z);
$this->placeLeaf($pos->x, $pos->y, $pos->z, $level);
for($i = 0; $i < $number; $i ++) {
$transfer = $random->nextBoolean ();
for ($i = 0; $i < $number; $i++) {
$transfer = $random->nextBoolean();
$direction = $random->nextBoundedInt(6);
$newPos = $pos->getSide($direction);
if ($transfer)
@ -64,7 +64,7 @@ class Bush extends Object {
}
}
/*
/**
* Places a leaf
* @param $x int
* @param $y int
@ -72,7 +72,7 @@ class Bush extends Object {
* @param $level pocketmine\level\ChunkManager
*/
public function placeLeaf($x, $y, $z, ChunkManager $level) {
if (isset($this->overridable[$level->getBlockIdAt($x, $y, $z)]) && ! isset($this->overridable[$level->getBlockIdAt($x, $y - 1, $z)])) {
if (isset($this->overridable[$level->getBlockIdAt($x, $y, $z)]) && !isset($this->overridable[$level->getBlockIdAt($x, $y - 1, $z)])) {
$level->setBlockIdAt($x, $y, $z, $this->leaf[0]);
$level->setBlockDataAt($x, $y, $z, $this->leaf[1]);
}

View file

@ -21,7 +21,7 @@ use pocketmine\utils\Random;
class Cactus extends Object {
/*
/**
* Checks if a cactus is placeable
* @param $level pocketmine\level\ChunkManager
* @param $x int
@ -34,7 +34,7 @@ class Cactus extends Object {
public function canPlaceObject(ChunkManager $level, int $x, int $y, int $z, Random $random): bool {
$this->totalHeight = 1 + $random->nextBoundedInt(3);
$below = $level->getBlockIdAt($x, $y - 1, $z);
for($yy = $y; $yy <= $y + $this->totalHeight; $yy ++) {
for ($yy = $y; $yy <= $y + $this->totalHeight; $yy++) {
if ($level->getBlockIdAt($x, $yy, $z) !== Block::AIR || ($below !== Block::SAND && $below !== Block::CACTUS) || ($level->getBlockIdAt($x - 1, $yy, $z) !== Block::AIR || $level->getBlockIdAt($x + 1, $yy, $z) !== Block::AIR || $level->getBlockIdAt($x, $yy, $z - 1) !== Block::AIR || $level->getBlockIdAt($x, $yy, $z + 1) !== Block::AIR)) {
return false;
}
@ -42,7 +42,7 @@ class Cactus extends Object {
return true;
}
/*
/**
* Places a cactus
* @param $level pocketmine\level\ChunkManager
* @param $x int
@ -50,7 +50,7 @@ class Cactus extends Object {
* @param $z int
*/
public function placeObject(ChunkManager $level, int $x, int $y, int $z) {
for($yy = 0; $yy < $this->totalHeight; $yy ++) {
for ($yy = 0; $yy < $this->totalHeight; $yy++) {
if ($level->getBlockIdAt($x, $y + $yy, $z) != Block::AIR) {
return;
}

View file

@ -25,32 +25,32 @@ use pocketmine\utils\Random;
class FallenTree extends Object {
public static $overridable = [
Block::AIR => true,
6 => true,
17 => true,
18 => true,
Block::DANDELION => true,
Block::POPPY => true,
Block::SNOW_LAYER => true,
Block::LOG2 => true,
Block::LEAVES2 => true,
Block::CACTUS => true
Block::AIR => true,
6 => true,
17 => true,
18 => true,
Block::DANDELION => true,
Block::POPPY => true,
Block::SNOW_LAYER => true,
Block::LOG2 => true,
Block::LEAVES2 => true,
Block::CACTUS => true
];
protected $tree;
protected $direction;
protected $random;
private $length = 0;
/*
/**
* Constructs the class
* @param $tree ObjectTree
* @throws Exeption
* @param $tree ObjectTree
* @throws Exeption
*/
public function __construct(ObjectTree $tree) {
$this->tree = $tree;
}
/*
/**
* Places a fallen tree
* @param $level pocketmine\level\ChunkManager
* @param $x int
@ -67,43 +67,43 @@ class FallenTree extends Object {
switch ($this->direction) {
case 0:
case 1:// Z+
$return = array_merge(BuildingUtils::fillCallback(new Vector3($x, $y, $z), new Vector3($x, $y, $z + $this->length), function($v3, $level) {
if(!isset(\Ad5001\BetterGen\structure\FallenTree::$overridable[$level->getBlockIdAt($v3->x, $v3->y, $v3->z)])) {
echo "$v3 is not overwritable (" . $level->getBlockIdAt($v3->x, $v3->y, $v3->z) . ").\n";
$return = array_merge(BuildingUtils::fillCallback(new Vector3($x, $y, $z), new Vector3($x, $y, $z + $this->length), function ($v3, $level) {
if (!isset(\Ad5001\BetterGen\structure\FallenTree::$overridable[$level->getBlockIdAt($v3->x, $v3->y, $v3->z)])) {
echo "$v3 is not overwritable (" . $level->getBlockIdAt($v3->x, $v3->y, $v3->z) . ").\n";
return false;
}
}, $level), BuildingUtils::fillCallback(new Vector3($x, $y - 1, $z), new Vector3($x, $y - 1, $z + $this->length), function ($v3, $level) {
if (isset(\Ad5001\BetterGen\structure\FallenTree::$overridable[$level->getBlockIdAt($v3->x, $v3->y, $v3->z)])) {
echo "$v3 is overwritable (" . $level->getBlockIdAt($v3->x, $v3->y, $v3->z) . ").\n";
return false;
}
}, $level));
if (in_array(false, $return, true)) {
return false;
}
}, $level), BuildingUtils::fillCallback(new Vector3($x, $y - 1, $z), new Vector3($x, $y - 1, $z + $this->length), function($v3, $level) {
if(isset(\Ad5001\BetterGen\structure\FallenTree::$overridable[$level->getBlockIdAt($v3->x, $v3->y, $v3->z)])) {
echo "$v3 is overwritable (" . $level->getBlockIdAt($v3->x, $v3->y, $v3->z) . ").\n";
return false;
}
}, $level));
if(in_array(false, $return, true)) {
return false;
}
break;
break;
case 2:
case 3: // X+
$return = array_merge(BuildingUtils::fillCallback(new Vector3($x, $y, $z), new Vector3($x + $this->length, $y, $z), function($v3, $level) {
if(!isset(\Ad5001\BetterGen\structure\FallenTree::$overridable[$level->getBlockIdAt($v3->x, $v3->y, $v3->z)])) {
echo "$v3 is not overwritable (" . $level->getBlockIdAt($v3->x, $v3->y, $v3->z) . ").\n";
$return = array_merge(BuildingUtils::fillCallback(new Vector3($x, $y, $z), new Vector3($x + $this->length, $y, $z), function ($v3, $level) {
if (!isset(\Ad5001\BetterGen\structure\FallenTree::$overridable[$level->getBlockIdAt($v3->x, $v3->y, $v3->z)])) {
echo "$v3 is not overwritable (" . $level->getBlockIdAt($v3->x, $v3->y, $v3->z) . ").\n";
return false;
}
}, $level), BuildingUtils::fillCallback(new Vector3($x, $y - 1, $z), new Vector3($x + $this->length, $y - 1, $z), function ($v3, $level) {
if (isset(\Ad5001\BetterGen\structure\FallenTree::$overridable[$level->getBlockIdAt($v3->x, $v3->y, $v3->z)])) {
echo "$v3 is overwritable (" . $level->getBlockIdAt($v3->x, $v3->y, $v3->z) . ").\n";
return false;
}
}, $level));
if (in_array(false, $return, true)) {
return false;
}
}, $level), BuildingUtils::fillCallback(new Vector3($x, $y - 1, $z), new Vector3($x + $this->length, $y - 1, $z), function($v3, $level) {
if(isset(\Ad5001\BetterGen\structure\FallenTree::$overridable[$level->getBlockIdAt($v3->x, $v3->y, $v3->z)])) {
echo "$v3 is overwritable (" . $level->getBlockIdAt($v3->x, $v3->y, $v3->z) . ").\n";
return false;
}
}, $level));
if(in_array(false, $return, true)) {
return false;
}
break;
break;
}
return true;
}
/*
/**
* Places a fallen tree
* @param $level pocketmine\level\ChunkManager
* @param $x int
@ -147,7 +147,7 @@ class FallenTree extends Object {
}
}
/*
/**
* Places a Block
* @param $x int
* @param $y int
@ -155,7 +155,7 @@ class FallenTree extends Object {
* @param $level pocketmine\level\ChunkManager
*/
public function placeBlock($x, $y, $z, ChunkManager $level) {
if (isset(self::$overridable[$level->getBlockIdAt($x, $y, $z)]) && ! isset(self::$overridable[$level->getBlockIdAt($x, $y - 1, $z)])) {
if (isset(self::$overridable[$level->getBlockIdAt($x, $y, $z)]) && !isset(self::$overridable[$level->getBlockIdAt($x, $y - 1, $z)])) {
$level->setBlockIdAt($x, $y, $z, $this->trunk[0]);
$level->setBlockDataAt($x, $y, $z, $this->trunk[1]);
}

View file

@ -21,83 +21,39 @@ use pocketmine\utils\Random;
class Igloo extends Object {
public $overridable = [
Block::AIR => true,
6 => true,
17 => true,
18 => true,
Block::DANDELION => true,
Block::POPPY => true,
Block::SNOW_LAYER => true,
Block::LOG2 => true,
Block::LEAVES2 => true
Block::AIR => true,
6 => true,
17 => true,
18 => true,
Block::DANDELION => true,
Block::POPPY => true,
Block::SNOW_LAYER => true,
Block::LOG2 => true,
Block::LEAVES2 => true
];
protected $direction;
/*
* Checks if an igloo is placeable
* @param $level pocketmine\level\ChunkManager
* @param $x int
* @param $y int
* @param $z int
* @param $random pocketmine\utils\Random
* @return bool
*/
public function canPlaceObject(ChunkManager $level, $x, $y, $z, Random $random) {
$this->direction = $random->nextBoundedInt(4);
switch ($this->direction) {
case 0 : // Entrance is x+
for($xx = $x - 3; $xx <= $x + 4; $xx ++)
for($yy = $y + 1; $yy <= $y + 4; $yy ++)
for($zz = $z - 3; $zz <= $z + 3; $zz ++)
if (! isset($this->overridable[$level->getBlockIdAt($xx, $yy, $zz)]))
return false;
break;
case 1 : // Entrance is x-
for($xx = $x - 4; $xx <= $x + 3; $xx ++)
for($yy = $y + 1; $yy <= $y + 4; $yy ++)
for($zz = $z - 3; $zz <= $z + 3; $zz ++)
if (! isset($this->overridable[$level->getBlockIdAt($xx, $yy, $zz)]))
return false;
break;
case 2 : // Entrance is z+
for($xx = $x - 3; $xx <= $x + 3; $xx ++)
for($yy = $y + 1; $yy <= $y + 4; $yy ++)
for($zz = $z - 3; $zz <= $z + 4; $zz ++)
if (! isset($this->overridable[$level->getBlockIdAt($xx, $yy, $zz)]))
return false;
break;
case 3 : // Entrance is z-
for($xx = $x - 3; $xx <= $x + 3; $xx ++)
for($yy = $y + 1; $yy <= $y + 4; $yy ++)
for($zz = $z - 4; $zz <= $z + 3; $zz ++)
if (! isset($this->overridable[$level->getBlockIdAt($xx, $yy, $zz)]))
return false;
break;
}
return true;
}
/*
/**
* Places an igloo
* @param $level pocketmine\level\ChunkManager
* @param $x int
* @param $y int
* @param $z int
* @param $random pocketmine\utils\Random
* @param ChunkManager $level
* @param $x
* @param $y
* @param $z
* @param Random $random
* @return bool placed
*/
public function placeObject(ChunkManager $level, $x, $y, $z, Random $random) {
if (! isset($this->direction) && ! $this->canPlaceObject($level, $x, $y, $z, $random))
if (!isset($this->direction) && !$this->canPlaceObject($level, $x, $y, $z, $random))
return false;
switch ($this->direction) {
case 0 : // Entrance is x+
// Ground
for($xx = $x - 3; $xx <= $x + 4; $xx ++)
for($zz = $z - 3; $zz <= $z + 3; $zz ++)
if (! isset($this->overridable[$level->getBlockIdAt($xx, $y, $zz)]))
// Ground
for ($xx = $x - 3; $xx <= $x + 4; $xx++)
for ($zz = $z - 3; $zz <= $z + 3; $zz++)
if (!isset($this->overridable[$level->getBlockIdAt($xx, $y, $zz)]))
$level->setBlockIdAt($xx, $y, $zz, Block::SNOW_BLOCK);
// Entrance
for($i = 0; $i < 2; $i ++) {
for ($i = 0; $i < 2; $i++) {
$level->setBlockIdAt($x + 3 + $i, $y, $z, Block::SNOW_BLOCK);
$level->setBlockIdAt($x + 3 + $i, $y + 3, $z, Block::SNOW_BLOCK);
$level->setBlockIdAt($x + 3 + $i, $y + 1, $z + 1, Block::SNOW_BLOCK);
@ -107,13 +63,13 @@ class Igloo extends Object {
}
// Back
for($zz = $z - 1; $zz <= $z + 1; $zz ++) {
for ($zz = $z - 1; $zz <= $z + 1; $zz++) {
$level->setBlockIdAt($x - 3, $y + 1, $zz, Block::SNOW_BLOCK);
$level->setBlockIdAt($x - 3, $y + 2, $zz, Block::SNOW_BLOCK);
}
// Sides
for($xx = $x - 1; $xx <= $x + 1; $xx ++) {
for ($xx = $x - 1; $xx <= $x + 1; $xx++) {
$level->setBlockIdAt($xx, $y + 1, $z - 3, Block::SNOW_BLOCK);
$level->setBlockIdAt($xx, $y + 2, $z - 3, Block::SNOW_BLOCK);
$level->setBlockIdAt($xx, $y + 1, $z + 3, Block::SNOW_BLOCK);
@ -123,7 +79,7 @@ class Igloo extends Object {
$level->setBlockIdAt($x, $y + 1, $z - 3, Block::ICE);
// Diags
for($i = 1; $i <= 2; $i ++) {
for ($i = 1; $i <= 2; $i++) {
$level->setBlockIdAt($x + 2, $y + $i, $z + 2, Block::SNOW_BLOCK);
$level->setBlockIdAt($x - 2, $y + $i, $z + 2, Block::SNOW_BLOCK);
$level->setBlockIdAt($x - 2, $y + $i, $z - 2, Block::SNOW_BLOCK);
@ -131,7 +87,7 @@ class Igloo extends Object {
}
// 2nd layer
for($i = 0; $i < 3; $i ++) {
for ($i = 0; $i < 3; $i++) {
$level->setBlockIdAt($x - 1 + $i, $y + 3, $z + 2, Block::SNOW_BLOCK);
$level->setBlockIdAt($x - 1 + $i, $y + 3, $z - 2, Block::SNOW_BLOCK);
$level->setBlockIdAt($x + 2, $y + 3, $z - 1 + $i, Block::SNOW_BLOCK);
@ -139,15 +95,15 @@ class Igloo extends Object {
}
// Top
for($xx = $x - 1; $xx <= $x + 1; $xx ++)
for($zz = $z - 1; $zz <= $z + 1; $zz ++) {
for ($xx = $x - 1; $xx <= $x + 1; $xx++)
for ($zz = $z - 1; $zz <= $z + 1; $zz++) {
$level->setBlockIdAt($xx, $y + 4, $zz, Block::SNOW_BLOCK);
$level->setBlockIdAt($xx, $y, $zz, Block::SNOW_BLOCK);
}
// Carpets
for($xx = $x - 2; $xx <= $x + 1; $xx ++)
for($zz = $z - 1; $zz <= $z + 1; $zz ++) {
for ($xx = $x - 2; $xx <= $x + 1; $xx++)
for ($zz = $z - 1; $zz <= $z + 1; $zz++) {
$level->setBlockIdAt($xx, $y + 1, $zz, Block::CARPET);
}
@ -166,13 +122,13 @@ class Igloo extends Object {
// Second direction
case 1 : // Entrance is x-
// Ground
for($xx = $x - 4; $xx <= $x + 3; $xx ++)
for($zz = $z - 3; $zz <= $z + 3; $zz ++)
if (! isset($this->overridable[$level->getBlockIdAt($xx, $y, $zz)]))
// Ground
for ($xx = $x - 4; $xx <= $x + 3; $xx++)
for ($zz = $z - 3; $zz <= $z + 3; $zz++)
if (!isset($this->overridable[$level->getBlockIdAt($xx, $y, $zz)]))
$level->setBlockIdAt($xx, $y, $zz, Block::SNOW_BLOCK);
// Entrance
for($i = 0; $i < 2; $i ++) {
for ($i = 0; $i < 2; $i++) {
$level->setBlockIdAt($x - 3 - $i, $y, $z, Block::SNOW_BLOCK);
$level->setBlockIdAt($x - 3 - $i, $y + 3, $z, Block::SNOW_BLOCK);
$level->setBlockIdAt($x - 3 - $i, $y + 1, $z + 1, Block::SNOW_BLOCK);
@ -182,13 +138,13 @@ class Igloo extends Object {
}
// Back
for($zz = $z - 1; $zz <= $z + 1; $zz ++) {
for ($zz = $z - 1; $zz <= $z + 1; $zz++) {
$level->setBlockIdAt($x + 3, $y + 1, $zz, Block::SNOW_BLOCK);
$level->setBlockIdAt($x + 3, $y + 2, $zz, Block::SNOW_BLOCK);
}
// Sides
for($xx = $x - 1; $xx <= $x + 1; $xx ++) {
for ($xx = $x - 1; $xx <= $x + 1; $xx++) {
$level->setBlockIdAt($xx, $y + 1, $z - 3, Block::SNOW_BLOCK);
$level->setBlockIdAt($xx, $y + 2, $z - 3, Block::SNOW_BLOCK);
$level->setBlockIdAt($xx, $y + 1, $z + 3, Block::SNOW_BLOCK);
@ -198,7 +154,7 @@ class Igloo extends Object {
$level->setBlockIdAt($x, $y + 1, $z - 3, Block::ICE);
// Diags
for($i = 1; $i <= 2; $i ++) {
for ($i = 1; $i <= 2; $i++) {
$level->setBlockIdAt($x + 2, $y + $i, $z + 2, Block::SNOW_BLOCK);
$level->setBlockIdAt($x - 2, $y + $i, $z + 2, Block::SNOW_BLOCK);
$level->setBlockIdAt($x - 2, $y + $i, $z - 2, Block::SNOW_BLOCK);
@ -206,7 +162,7 @@ class Igloo extends Object {
}
// 2nd layer
for($i = 0; $i < 3; $i ++) {
for ($i = 0; $i < 3; $i++) {
$level->setBlockIdAt($x - 1 + $i, $y + 3, $z + 2, Block::SNOW_BLOCK);
$level->setBlockIdAt($x - 1 + $i, $y + 3, $z - 2, Block::SNOW_BLOCK);
$level->setBlockIdAt($x + 2, $y + 3, $z - 1 + $i, Block::SNOW_BLOCK);
@ -214,15 +170,15 @@ class Igloo extends Object {
}
// Top
for($xx = $x - 1; $xx <= $x + 1; $xx ++)
for($zz = $z - 1; $zz <= $z + 1; $zz ++) {
for ($xx = $x - 1; $xx <= $x + 1; $xx++)
for ($zz = $z - 1; $zz <= $z + 1; $zz++) {
$level->setBlockIdAt($xx, $y + 4, $zz, Block::SNOW_BLOCK);
$level->setBlockIdAt($xx, $y, $zz, Block::SNOW_BLOCK);
}
// Carpets
for($xx = $x - 1; $xx <= $x + 2; $xx ++)
for($zz = $z - 1; $zz <= $z + 1; $zz ++) {
for ($xx = $x - 1; $xx <= $x + 2; $xx++)
for ($zz = $z - 1; $zz <= $z + 1; $zz++) {
$level->setBlockIdAt($xx, $y + 1, $zz, Block::CARPET);
}
@ -240,13 +196,13 @@ class Igloo extends Object {
// Third direction
case 2 : // Entrance is z+
// Ground
for($xx = $x - 3; $xx <= $x + 3; $xx ++)
for($zz = $z - 3; $zz <= $z + 4; $zz ++)
if (! isset($this->overridable[$level->getBlockIdAt($xx, $y, $zz)]))
// Ground
for ($xx = $x - 3; $xx <= $x + 3; $xx++)
for ($zz = $z - 3; $zz <= $z + 4; $zz++)
if (!isset($this->overridable[$level->getBlockIdAt($xx, $y, $zz)]))
$level->setBlockIdAt($xx, $y, $zz, Block::SNOW_BLOCK);
// Entrance
for($i = 0; $i < 2; $i ++) {
for ($i = 0; $i < 2; $i++) {
$level->setBlockIdAt($x, $y, $z + 3 + $i, Block::SNOW_BLOCK);
$level->setBlockIdAt($x, $y + 3, $z + 3 + $i, Block::SNOW_BLOCK);
$level->setBlockIdAt($x + 1, $y + 1, $z + 3 + $i, Block::SNOW_BLOCK);
@ -256,13 +212,13 @@ class Igloo extends Object {
}
// Back
for($xx = $x - 1; $xx <= $x + 1; $xx ++) {
for ($xx = $x - 1; $xx <= $x + 1; $xx++) {
$level->setBlockIdAt($xx, $y + 1, $z - 3, Block::SNOW_BLOCK);
$level->setBlockIdAt($xx, $y + 2, $z - 3, Block::SNOW_BLOCK);
}
// Sides
for($zz = $z - 1; $zz <= $z + 1; $zz ++) {
for ($zz = $z - 1; $zz <= $z + 1; $zz++) {
$level->setBlockIdAt($x - 3, $y + 1, $zz, Block::SNOW_BLOCK);
$level->setBlockIdAt($x - 3, $y + 2, $zz, Block::SNOW_BLOCK);
$level->setBlockIdAt($x + 3, $y + 1, $zz, Block::SNOW_BLOCK);
@ -272,7 +228,7 @@ class Igloo extends Object {
$level->setBlockIdAt($x - 3, $y + 1, $z, Block::ICE);
// Diags
for($i = 1; $i <= 2; $i ++) {
for ($i = 1; $i <= 2; $i++) {
$level->setBlockIdAt($x + 2, $y + $i, $z + 2, Block::SNOW_BLOCK);
$level->setBlockIdAt($x - 2, $y + $i, $z + 2, Block::SNOW_BLOCK);
$level->setBlockIdAt($x - 2, $y + $i, $z - 2, Block::SNOW_BLOCK);
@ -280,7 +236,7 @@ class Igloo extends Object {
}
// 2nd layer
for($i = 0; $i < 3; $i ++) {
for ($i = 0; $i < 3; $i++) {
$level->setBlockIdAt($x - 1 + $i, $y + 3, $z + 2, Block::SNOW_BLOCK);
$level->setBlockIdAt($x - 1 + $i, $y + 3, $z - 2, Block::SNOW_BLOCK);
$level->setBlockIdAt($x + 2, $y + 3, $z - 1 + $i, Block::SNOW_BLOCK);
@ -288,15 +244,15 @@ class Igloo extends Object {
}
// Top
for($xx = $x - 1; $xx <= $x + 1; $xx ++)
for($zz = $z - 1; $zz <= $z + 1; $zz ++) {
for ($xx = $x - 1; $xx <= $x + 1; $xx++)
for ($zz = $z - 1; $zz <= $z + 1; $zz++) {
$level->setBlockIdAt($xx, $y + 4, $zz, Block::SNOW_BLOCK);
$level->setBlockIdAt($xx, $y, $zz, Block::SNOW_BLOCK);
}
// Carpets
for($xx = $x - 1; $xx <= $x + 1; $xx ++)
for($zz = $z - 2; $zz <= $z + 1; $zz ++) {
for ($xx = $x - 1; $xx <= $x + 1; $xx++)
for ($zz = $z - 2; $zz <= $z + 1; $zz++) {
$level->setBlockIdAt($xx, $y + 1, $zz, Block::CARPET);
}
@ -314,13 +270,13 @@ class Igloo extends Object {
// Fourth direction
case 3 : // Entrance is z-
// Ground
for($xx = $x - 3; $xx <= $x + 3; $xx ++)
for($zz = $z - 4; $zz <= $z + 3; $zz ++)
if (! isset($this->overridable[$level->getBlockIdAt($xx, $y, $zz)]))
// Ground
for ($xx = $x - 3; $xx <= $x + 3; $xx++)
for ($zz = $z - 4; $zz <= $z + 3; $zz++)
if (!isset($this->overridable[$level->getBlockIdAt($xx, $y, $zz)]))
$level->setBlockIdAt($xx, $y, $zz, Block::SNOW_BLOCK);
// Entrance
for($i = 0; $i < 2; $i ++) {
for ($i = 0; $i < 2; $i++) {
$level->setBlockIdAt($x, $y, $z - 3 - $i, Block::SNOW_BLOCK);
$level->setBlockIdAt($x, $y + 3, $z - 3 - $i, Block::SNOW_BLOCK);
$level->setBlockIdAt($x + 1, $y + 1, $z - 3 - $i, Block::SNOW_BLOCK);
@ -330,13 +286,13 @@ class Igloo extends Object {
}
// Back
for($xx = $x - 1; $xx <= $x + 1; $xx ++) {
for ($xx = $x - 1; $xx <= $x + 1; $xx++) {
$level->setBlockIdAt($xx, $y + 1, $z + 3, Block::SNOW_BLOCK);
$level->setBlockIdAt($xx, $y + 2, $z + 3, Block::SNOW_BLOCK);
}
// Sides
for($zz = $z - 1; $zz <= $z + 1; $zz ++) {
for ($zz = $z - 1; $zz <= $z + 1; $zz++) {
$level->setBlockIdAt($x - 3, $y + 1, $zz, Block::SNOW_BLOCK);
$level->setBlockIdAt($x - 3, $y + 2, $zz, Block::SNOW_BLOCK);
$level->setBlockIdAt($x + 3, $y + 1, $zz, Block::SNOW_BLOCK);
@ -346,7 +302,7 @@ class Igloo extends Object {
$level->setBlockIdAt($x - 3, $y + 1, $z, Block::ICE);
// Diags
for($i = 1; $i <= 2; $i ++) {
for ($i = 1; $i <= 2; $i++) {
$level->setBlockIdAt($x + 2, $y + $i, $z + 2, Block::SNOW_BLOCK);
$level->setBlockIdAt($x - 2, $y + $i, $z + 2, Block::SNOW_BLOCK);
$level->setBlockIdAt($x - 2, $y + $i, $z - 2, Block::SNOW_BLOCK);
@ -354,7 +310,7 @@ class Igloo extends Object {
}
// 2nd layer
for($i = 0; $i < 3; $i ++) {
for ($i = 0; $i < 3; $i++) {
$level->setBlockIdAt($x - 1 + $i, $y + 3, $z + 2, Block::SNOW_BLOCK);
$level->setBlockIdAt($x - 1 + $i, $y + 3, $z - 2, Block::SNOW_BLOCK);
$level->setBlockIdAt($x + 2, $y + 3, $z - 1 + $i, Block::SNOW_BLOCK);
@ -362,15 +318,15 @@ class Igloo extends Object {
}
// Top
for($xx = $x - 1; $xx <= $x + 1; $xx ++)
for($zz = $z - 1; $zz <= $z + 1; $zz ++) {
for ($xx = $x - 1; $xx <= $x + 1; $xx++)
for ($zz = $z - 1; $zz <= $z + 1; $zz++) {
$level->setBlockIdAt($xx, $y + 4, $zz, Block::SNOW_BLOCK);
$level->setBlockIdAt($xx, $y, $zz, Block::SNOW_BLOCK);
}
// Carpets
for($xx = $x - 1; $xx <= $x + 1; $xx ++)
for($zz = $z - 1; $zz <= $z + 2; $zz ++) {
for ($xx = $x - 1; $xx <= $x + 1; $xx++)
for ($zz = $z - 1; $zz <= $z + 2; $zz++) {
$level->setBlockIdAt($xx, $y + 1, $zz, Block::CARPET);
}
@ -388,4 +344,48 @@ class Igloo extends Object {
}
return true;
}
/**
* Checks if an igloo is placeable
* @param ChunkManager $level
* @param $x
* @param $y
* @param $z
* @param Random $random
* @return bool
*/
public function canPlaceObject(ChunkManager $level, $x, $y, $z, Random $random) {
$this->direction = $random->nextBoundedInt(4);
switch ($this->direction) {
case 0 : // Entrance is x+
for ($xx = $x - 3; $xx <= $x + 4; $xx++)
for ($yy = $y + 1; $yy <= $y + 4; $yy++)
for ($zz = $z - 3; $zz <= $z + 3; $zz++)
if (!isset($this->overridable[$level->getBlockIdAt($xx, $yy, $zz)]))
return false;
break;
case 1 : // Entrance is x-
for ($xx = $x - 4; $xx <= $x + 3; $xx++)
for ($yy = $y + 1; $yy <= $y + 4; $yy++)
for ($zz = $z - 3; $zz <= $z + 3; $zz++)
if (!isset($this->overridable[$level->getBlockIdAt($xx, $yy, $zz)]))
return false;
break;
case 2 : // Entrance is z+
for ($xx = $x - 3; $xx <= $x + 3; $xx++)
for ($yy = $y + 1; $yy <= $y + 4; $yy++)
for ($zz = $z - 3; $zz <= $z + 4; $zz++)
if (!isset($this->overridable[$level->getBlockIdAt($xx, $yy, $zz)]))
return false;
break;
case 3 : // Entrance is z-
for ($xx = $x - 3; $xx <= $x + 3; $xx++)
for ($yy = $y + 1; $yy <= $y + 4; $yy++)
for ($zz = $z - 4; $zz <= $z + 3; $zz++)
if (!isset($this->overridable[$level->getBlockIdAt($xx, $yy, $zz)]))
return false;
break;
}
return true;
}
}

View file

@ -445,7 +445,7 @@ class SakuraTree extends Tree {
public $leafType;
public $leaf2Type;
/*
/**
* Constructs the class
*/
public function __construct() {
@ -457,7 +457,7 @@ class SakuraTree extends Tree {
$this->type = Wood::OAK;
}
/*
/**
* Builds the tree.
* @param $level \pocketmine\level\ChunkManager
* @param $x int
@ -656,7 +656,7 @@ class SakuraTree extends Tree {
}
}
/*
/**
* Fills a log at.
* @param $level pocketmine\level\ChunkManager
* @param $x int
@ -668,7 +668,7 @@ class SakuraTree extends Tree {
$level->setBlockDataAt($x, $y, $z, $this->type);
}
/*
/**
* Fills a leave at.
* @param $level pocketmine\level\ChunkManager
* @param $x int

View file

@ -22,7 +22,7 @@ use pocketmine\utils\Random;
class SugarCane extends Object {
/*
/**
* Checks if a cactus is placeable
* @param $level pocketmine\level\ChunkManager
* @param $x int
@ -41,7 +41,7 @@ class SugarCane extends Object {
return false;
}
/*
/**
* Places a cactus
* @param $level pocketmine\level\ChunkManager
* @param $x int
@ -49,7 +49,7 @@ class SugarCane extends Object {
* @param $z int
*/
public function placeObject(ChunkManager $level, int $x, int $y, int $z) {
for($yy = 0; $yy < $this->totalHeight; $yy ++) {
for ($yy = 0; $yy < $this->totalHeight; $yy++) {
if ($level->getBlockIdAt($x, $y + $yy, $z) != Block::AIR) {
return;
}

View file

@ -14,10 +14,12 @@
namespace Ad5001\BetterGen\structure;
use Ad5001\BetterGen\Main;
use Ad5001\BetterGen\utils\BuildingUtils;
use pocketmine\block\Block;
use pocketmine\level\ChunkManager;
use pocketmine\level\generator\object\Object;
use pocketmine\level\Position;
use pocketmine\math\Vector3;
use pocketmine\utils\Random;
@ -111,16 +113,15 @@ class Temple extends Object {
private $level;
private $direction = 0;
/*
/**
* Checks if a temple is placeable
* @param $level pocketmine\level\ChunkManager
* @param $x int
* @param $y int
* @param $z int
* @param $random pocketmine\utils\Random
* @param ChunkManager $level
* @param $x
* @param $y
* @param $z
* @param Random $random
* @return bool
*/
public function canPlaceObject(ChunkManager $level, $x, $y, $z, Random $random) {
$this->level = $level;
$this->direction = $random->nextBoundedInt(4);
@ -132,13 +133,13 @@ class Temple extends Object {
return true;
}
/*
/**
* Places a temple
* @param $level pocketmine\level\ChunkManager
* @param $x int
* @param $y int
* @param $z int
* @param $random pocketmine\utils\Random
* @param ChunkManager $level
* @param $x
* @param $y
* @param $z
* @param Random $random
*/
public function placeObject(ChunkManager $level, $x, $y, $z, Random $random) {
// Clearing space...
@ -216,20 +217,19 @@ class Temple extends Object {
$this->placeBlock($xx, $y - 13, $zz, Block::TNT);
$this->placeBlock($x, $y - 11, $z, Block::STONE_PRESSURE_PLATE);
//TODO TILES
$this->placeBlock($x, $y - 11, $z + 2, Block::CHEST, 4);
$this->placeBlock($x, $y - 11, $z - 2, Block::CHEST, 2);
$this->placeBlock($x + 2, $y - 11, $z, Block::CHEST, 5);
$this->placeBlock($x - 2, $y - 11, $z, Block::CHEST, 3);
$this->placeBlock($x, $y - 10, $z + 2, Block::AIR);
$this->placeBlock($x, $y - 10, $z - 2, Block::AIR);
$this->placeBlock($x + 2, $y - 10, $z, Block::AIR);
$this->placeBlock($x - 2, $y - 10, $z, Block::AIR);
// Chests
/*LootTable::buildLootTable(new Vector3($x, $y - 11, $z + 2), LootTable::LOOT_DESERT_TEMPLE, $random);//TODO: Improve using addon
LootTable::buildLootTable(new Vector3($x, $y - 11, $z - 2), LootTable::LOOT_DESERT_TEMPLE, $random);
LootTable::buildLootTable(new Vector3($x + 2, $y - 11, $z), LootTable::LOOT_DESERT_TEMPLE, $random);
LootTable::buildLootTable(new Vector3($x - 2, $y - 11, $z), LootTable::LOOT_DESERT_TEMPLE, $random);*/
#$this->placeBlock($x, $y - 11, $z + 2, Block::CHEST, 4);
#$this->placeBlock($x, $y - 11, $z - 2, Block::CHEST, 2);
#$this->placeBlock($x + 2, $y - 11, $z, Block::CHEST, 5);
#$this->placeBlock($x - 2, $y - 11, $z, Block::CHEST, 3);
Main::placeLootChest(Block::get(Block::CHEST, 2, new Position($x, $y - 11, $z + 2, $this->level)), 'loot_tables\\chests\\desert_pyramid');
Main::placeLootChest(Block::get(Block::CHEST, 3, new Position($x, $y - 11, $z - 2, $this->level)), 'loot_tables\\chests\\desert_pyramid');
Main::placeLootChest(Block::get(Block::CHEST, 4, new Position($x + 2, $y - 11, $z, $this->level)), 'loot_tables\\chests\\desert_pyramid');
Main::placeLootChest(Block::get(Block::CHEST, 5, new Position($x - 2, $y - 11, $z, $this->level)), 'loot_tables\\chests\\desert_pyramid');
// Entrance is a rectangular parallelepiped
switch ($this->direction) {
@ -896,6 +896,7 @@ class Temple extends Object {
* @param $z int
* @param $id int
* @param $meta int
* @param bool $top
* @return void
*/
protected function placeSlab($x, $y, $z, $id = 44, $meta = 1, $top = false) {

View file

@ -22,40 +22,40 @@ use pocketmine\utils\Random;
class Well extends Object {
public $overridable = [
Block::AIR => true,
6 => true,
17 => true,
18 => true,
Block::DANDELION => true,
Block::POPPY => true,
Block::SNOW_LAYER => true,
Block::LOG2 => true,
Block::LEAVES2 => true,
Block::CACTUS => true
];
/** @var ChunkManager */
protected $level;
public $overridable = [
Block::AIR => true,
6 => true,
17 => true,
18 => true,
Block::DANDELION => true,
Block::POPPY => true,
Block::SNOW_LAYER => true,
Block::LOG2 => true,
Block::LEAVES2 => true,
Block::CACTUS => true
];
protected $directions = [
[
1,
1
],
[
1,
- 1
],
[
- 1,
- 1
],
[
- 1,
1
]
[
1,
1
],
[
1,
-1
],
[
-1,
-1
],
[
-1,
1
]
];
/*
/**
* Checks if a well is placeable
* @param $level ChunkManager
* @param $x int
@ -66,15 +66,15 @@ class Well extends Object {
*/
public function canPlaceObject(ChunkManager $level, $x, $y, $z, Random $random) {
$this->level = $level;
for($xx = $x - 2; $xx <= $x + 2; $xx ++)
for($yy = $y; $yy <= $y + 3; $yy ++)
for($zz = $z - 2; $zz <= $z + 2; $zz ++)
if (! isset($this->overridable[$level->getBlockIdAt($xx, $yy, $zz)]))
for ($xx = $x - 2; $xx <= $x + 2; $xx++)
for ($yy = $y; $yy <= $y + 3; $yy++)
for ($zz = $z - 2; $zz <= $z + 2; $zz++)
if (!isset($this->overridable[$level->getBlockIdAt($xx, $yy, $zz)]))
return false;
return true;
}
/*
/**
* Places a well
* @param $level ChunkManager
* @param $x int
@ -84,9 +84,9 @@ class Well extends Object {
*/
public function placeObject(ChunkManager $level, $x, $y, $z, Random $random) {
$this->level = $level;
foreach($this->directions as $direction) {
foreach ($this->directions as $direction) {
// Building pillars
for($yy = $y; $yy < $y + 3; $yy ++)
for ($yy = $y; $yy < $y + 3; $yy++)
$this->placeBlock($x + $direction [0], $yy, $z + $direction [1], Block::SANDSTONE);
// Building corners
@ -104,14 +104,14 @@ class Well extends Object {
}
// Final things
for($xx = $x - 1; $xx <= $x + 1; $xx ++)
for($zz = $z - 1; $zz <= $z + 1; $zz ++)
for ($xx = $x - 1; $xx <= $x + 1; $xx++)
for ($zz = $z - 1; $zz <= $z + 1; $zz++)
$this->placeBlock($xx, $y + 3, $zz);
$this->placeBlock($x, $y + 3, $z, Block::SANDSTONE, 1);
$this->placeBlock($x, $y, $z, Block::WATER);
}
/*
/**
* Places a slab
* @param $x int
* @param $y int

View file

@ -10,7 +10,7 @@
* Tomorrow's pocketmine generator.
* @author Ad5001
* @link https://github.com/Ad5001/BetterGen
*/
*/
namespace Ad5001\BetterGen\utils;
@ -21,16 +21,16 @@ use pocketmine\utils\Random;
class BuildingUtils {
const TO_NOT_OVERWRITE = [
Block::WATER,
Block::STILL_WATER,
Block::STILL_LAVA,
Block::LAVA,
Block::BEDROCK,
Block::CACTUS,
Block::PLANK
Block::WATER,
Block::STILL_WATER,
Block::STILL_LAVA,
Block::LAVA,
Block::BEDROCK,
Block::CACTUS,
Block::PLANK
];
/*
/**
* Fills an area
* @param $level pocketmine\level\ChunkManager
* @param $pos1 pocketmine\math\Vector3
@ -41,33 +41,47 @@ class BuildingUtils {
public static function fill(ChunkManager $level, Vector3 $pos1, Vector3 $pos2, Block $block = null) {
if ($block == null) $block = Block::get(Block::AIR);
list($pos1, $pos2) = self::minmax($pos1, $pos2);
for($x = $pos1->x; $x >= $pos2->x; $x --) for($y = $pos1->y; $y >= $pos2->y; $y --) for($z = $pos1->z; $z >= $pos2->z; $z --) {
$level->setBlockIdAt($x, $y, $z, $block->getId ());
$level->setBlockDataAt($x, $y, $z, $block->getDamage ());
}
for ($x = $pos1->x; $x >= $pos2->x; $x--) for ($y = $pos1->y; $y >= $pos2->y; $y--) for ($z = $pos1->z; $z >= $pos2->z; $z--) {
$level->setBlockIdAt($x, $y, $z, $block->getId());
$level->setBlockDataAt($x, $y, $z, $block->getDamage());
}
}
/**
* Returns 2 vector3, one with minimal values, one with max values of the provided ones.
* @param $pos1 pocketmine\math\Vector3
* @param $pos2 pocketmine\math\Vector3
* @return array
*/
protected static function minmax(Vector3 $pos1, Vector3 $pos2): array {
$v1 = new Vector3(max($pos1->x, $pos2->x), max($pos1->y, $pos2->y), max($pos1->z, $pos2->z));
$v2 = new Vector3(min($pos1->x, $pos2->x), min($pos1->y, $pos2->y), min($pos1->z, $pos2->z));
return [
$v1,
$v2
];
}
/*
/**
* Fills an area randomly
* @param $level pocketmine\level\ChunkManager
* @param $pos1 pocketmine\math\Vector3
* @param $pos2 pocketmine\math\Vector3
* @param $block pocketmine\block\Block
* @param $random pocketmine\utils
* @param $randMax pocketmine\utils
* @param $level pocketmine\level\ChunkManager
* @param $pos1 pocketmine\math\Vector3
* @param $pos2 pocketmine\math\Vector3
* @param $block pocketmine\block\Block
* @param $random pocketmine\utils
* @param $randMax pocketmine\utils
* @return void
*/
public static function fillRandom(ChunkManager $level, Vector3 $pos1, Vector3 $pos2, Block $block = null, Random $random = null, $randMax = 3) {
if ($block == null) $block = Block::get(Block::AIR);
list($pos1, $pos2) = self::minmax($pos1, $pos2);
for($x = $pos1->x; $x >= $pos2->x; $x --) for($y = $pos1->y; $y >= $pos2->y; $y --) for($z = $pos1->z; $z >= $pos2->z; $z --) if($random !== null ? $random->nextBoundedInt($randMax) == 0 : rand(0, $randMax) == 0) {
$level->setBlockIdAt($x, $y, $z, $block->getId ());
$level->setBlockDataAt($x, $y, $z, $block->getDamage ());
}
for ($x = $pos1->x; $x >= $pos2->x; $x--) for ($y = $pos1->y; $y >= $pos2->y; $y--) for ($z = $pos1->z; $z >= $pos2->z; $z--) if ($random !== null ? $random->nextBoundedInt($randMax) == 0 : rand(0, $randMax) == 0) {
$level->setBlockIdAt($x, $y, $z, $block->getId());
$level->setBlockDataAt($x, $y, $z, $block->getDamage());
}
}
/*
/**
* Fills an area by custom filling
* @param $pos1 pocketmine\math\Vector3
* @param $pos2 pocketmine\math\Vector3
@ -75,16 +89,16 @@ class BuildingUtils {
* @param $params array
* @return array
*/
public static function fillCallback(Vector3 $pos1, Vector3 $pos2, callable $call, ...$params) : array {
public static function fillCallback(Vector3 $pos1, Vector3 $pos2, callable $call, ...$params): array {
list($pos1, $pos2) = self::minmax($pos1, $pos2);
$return = [];
for($x = $pos1->x; $x >= $pos2->x; $x --) for($y = $pos1->y; $y >= $pos2->y; $y --) for($z = $pos1->z; $z >= $pos2->z; $z --) {
$return[] = call_user_func($call, new Vector3($x, $y, $z), ...$params);
}
for ($x = $pos1->x; $x >= $pos2->x; $x--) for ($y = $pos1->y; $y >= $pos2->y; $y--) for ($z = $pos1->z; $z >= $pos2->z; $z--) {
$return[] = call_user_func($call, new Vector3($x, $y, $z), ...$params);
}
return $return;
}
/*
/**
* Creates walls
* @param $level pocketmine\level\ChunkManager
* @param $pos1 pocketmine\math\Vector3
@ -94,23 +108,23 @@ class BuildingUtils {
*/
public static function walls(ChunkManager $level, Vector3 $pos1, Vector3 $pos2, Block $block) {
list($pos1, $pos2) = self::minmax($pos1, $pos2);
for($y = $pos1->y; $y >= $pos2->y; $y --) {
for($x = $pos1->x; $x >= $pos2->x; $x --) {
$level->setBlockIdAt($x, $y, $pos1->z, $block->getId ());
$level->setBlockDataAt($x, $y, $pos1->z, $block->getDamage ());
$level->setBlockIdAt($x, $y, $pos2->z, $block->getId ());
$level->setBlockDataAt($x, $y, $pos2->z, $block->getDamage ());
for ($y = $pos1->y; $y >= $pos2->y; $y--) {
for ($x = $pos1->x; $x >= $pos2->x; $x--) {
$level->setBlockIdAt($x, $y, $pos1->z, $block->getId());
$level->setBlockDataAt($x, $y, $pos1->z, $block->getDamage());
$level->setBlockIdAt($x, $y, $pos2->z, $block->getId());
$level->setBlockDataAt($x, $y, $pos2->z, $block->getDamage());
}
for($z = $pos1->z; $z >= $pos2->z; $z --) {
$level->setBlockIdAt($pos1->x, $y, $z, $block->getId ());
$level->setBlockDataAt($pos1->x, $y, $z, $block->getDamage ());
$level->setBlockIdAt($pos2->x, $y, $z, $block->getId ());
$level->setBlockDataAt($pos2->x, $y, $z, $block->getDamage ());
for ($z = $pos1->z; $z >= $pos2->z; $z--) {
$level->setBlockIdAt($pos1->x, $y, $z, $block->getId());
$level->setBlockDataAt($pos1->x, $y, $z, $block->getDamage());
$level->setBlockIdAt($pos2->x, $y, $z, $block->getId());
$level->setBlockDataAt($pos2->x, $y, $z, $block->getDamage());
}
}
}
/*
/**
* Creates the top of a structure
* @param $level pocketmine\level\ChunkManager
* @param $pos1 pocketmine\math\Vector3
@ -120,14 +134,14 @@ class BuildingUtils {
*/
public static function top(ChunkManager $level, Vector3 $pos1, Vector3 $pos2, Block $block) {
list($pos1, $pos2) = self::minmax($pos1, $pos2);
for($x = $pos1->x; $x >= $pos2->x; $x --)
for($z = $pos1->z; $z >= $pos2->z; $z --) {
$level->setBlockIdAt($x, $pos1->y, $z, $block->getId ());
$level->setBlockDataAt($x, $pos1->y, $z, $block->getDamage ());
for ($x = $pos1->x; $x >= $pos2->x; $x--)
for ($z = $pos1->z; $z >= $pos2->z; $z--) {
$level->setBlockIdAt($x, $pos1->y, $z, $block->getId());
$level->setBlockDataAt($x, $pos1->y, $z, $block->getDamage());
}
}
/*
/**
* Creates all corners from positions. Used for Mineshaft.
* @param $level pocketmine\level\ChunkManager
* @param $pos1 pocketmine\math\Vector3
@ -137,19 +151,19 @@ class BuildingUtils {
*/
public static function corners(ChunkManager $level, Vector3 $pos1, Vector3 $pos2, Block $block) {
list($pos1, $pos2) = self::minmax($pos1, $pos2);
for($y = $pos1->y; $y >= $pos2->y; $y --) {
$level->setBlockIdAt($pos1->x, $y, $pos1->z, $block->getId ());
$level->setBlockDataAt($pos1->x, $y, $pos1->z, $block->getDamage ());
$level->setBlockIdAt($pos2->x, $y, $pos1->z, $block->getId ());
$level->setBlockDataAt($pos2->x, $y, $pos1->z, $block->getDamage ());
$level->setBlockIdAt($pos1->x, $y, $pos2->z, $block->getId ());
$level->setBlockDataAt($pos1->x, $y, $pos2->z, $block->getDamage ());
$level->setBlockIdAt($pos2->x, $y, $pos2->z, $block->getId ());
$level->setBlockDataAt($pos2->x, $y, $pos2->z, $block->getDamage ());
for ($y = $pos1->y; $y >= $pos2->y; $y--) {
$level->setBlockIdAt($pos1->x, $y, $pos1->z, $block->getId());
$level->setBlockDataAt($pos1->x, $y, $pos1->z, $block->getDamage());
$level->setBlockIdAt($pos2->x, $y, $pos1->z, $block->getId());
$level->setBlockDataAt($pos2->x, $y, $pos1->z, $block->getDamage());
$level->setBlockIdAt($pos1->x, $y, $pos2->z, $block->getId());
$level->setBlockDataAt($pos1->x, $y, $pos2->z, $block->getDamage());
$level->setBlockIdAt($pos2->x, $y, $pos2->z, $block->getId());
$level->setBlockDataAt($pos2->x, $y, $pos2->z, $block->getDamage());
}
}
/*
/**
* Creates the bottom of a structure
* @param $level pocketmine\level\ChunkManager
* @param $pos1 pocketmine\math\Vector3
@ -159,14 +173,14 @@ class BuildingUtils {
*/
public static function bottom(ChunkManager $level, Vector3 $pos1, Vector3 $pos2, Block $block) {
list($pos1, $pos2) = self::minmax($pos1, $pos2);
for($x = $pos1->x; $x >= $pos2->x; $x --)
for($z = $pos1->z; $z >= $pos2->z; $z --) {
$level->setBlockIdAt($x, $pos2->y, $z, $block->getId ());
$level->setBlockDataAt($x, $pos2->y, $z, $block->getDamage ());
for ($x = $pos1->x; $x >= $pos2->x; $x--)
for ($z = $pos1->z; $z >= $pos2->z; $z--) {
$level->setBlockIdAt($x, $pos2->y, $z, $block->getId());
$level->setBlockDataAt($x, $pos2->y, $z, $block->getDamage());
}
}
/*
/**
* Builds a random structure depending of length, height, depth and random
* @param $level pocketmine\level\ChunkManager
* @param $pos pocketmine\math\Vector3
@ -179,32 +193,17 @@ class BuildingUtils {
$xBounded = $random->nextBoundedInt(3) - 1;
$yBounded = $random->nextBoundedInt(3) - 1;
$zBounded = $random->nextBoundedInt(3) - 1;
$pos = $pos->round ();
for($x = $pos->x - ($infos->x / 2); $x <= $pos->x + ($infos->x / 2); $x ++) {
for($y = $pos->y - ($infos->y / 2); $y <= $pos->y + ($infos->y / 2); $y ++) {
for($z = $pos->z - ($infos->z / 2); $z <= $pos->z + ($infos->z / 2); $z ++) {
$pos = $pos->round();
for ($x = $pos->x - ($infos->x / 2); $x <= $pos->x + ($infos->x / 2); $x++) {
for ($y = $pos->y - ($infos->y / 2); $y <= $pos->y + ($infos->y / 2); $y++) {
for ($z = $pos->z - ($infos->z / 2); $z <= $pos->z + ($infos->z / 2); $z++) {
// if(abs((abs($x) - abs($pos->x)) ** 2 + ($y - $pos->y) ** 2 + (abs($z) - abs($pos->z)) ** 2) < (abs($infos->x / 2 + $xBounded) + abs($infos->y / 2 + $yBounded) + abs($infos->z / 2 + $zBounded)) ** 2
if (abs((abs($x) - abs($pos->x)) ** 2 + ($y - $pos->y) ** 2 + (abs($z) - abs($pos->z)) ** 2) < ((($infos->x / 2 - $xBounded) + ($infos->y / 2 - $yBounded) + ($infos->z / 2 - $zBounded)) / 3) ** 2 && $y > 0 && ! in_array($level->getBlockIdAt($x, $y, $z), self::TO_NOT_OVERWRITE) && ! in_array($level->getBlockIdAt($x, $y + 1, $z), self::TO_NOT_OVERWRITE)) {
$level->setBlockIdAt($x, $y, $z, $block->getId ());
$level->setBlockDataAt($x, $y, $z, $block->getDamage ());
if (abs((abs($x) - abs($pos->x)) ** 2 + ($y - $pos->y) ** 2 + (abs($z) - abs($pos->z)) ** 2) < ((($infos->x / 2 - $xBounded) + ($infos->y / 2 - $yBounded) + ($infos->z / 2 - $zBounded)) / 3) ** 2 && $y > 0 && !in_array($level->getBlockIdAt($x, $y, $z), self::TO_NOT_OVERWRITE) && !in_array($level->getBlockIdAt($x, $y + 1, $z), self::TO_NOT_OVERWRITE)) {
$level->setBlockIdAt($x, $y, $z, $block->getId());
$level->setBlockDataAt($x, $y, $z, $block->getDamage());
}
}
}
}
}
/*
* Returns 2 vector3, one with minimal values, one with max values of the provided ones.
* @param $pos1 pocketmine\math\Vector3
* @param $pos2 pocketmine\math\Vector3
* @return array
*/
protected static function minmax(Vector3 $pos1, Vector3 $pos2): array {
$v1 = new Vector3(max($pos1->x, $pos2->x), max($pos1->y, $pos2->y), max($pos1->z, $pos2->z));
$v2 = new Vector3(min($pos1->x, $pos2->x), min($pos1->y, $pos2->y), min($pos1->z, $pos2->z));
return [
$v1,
$v2
];
}
}

View file

@ -13,17 +13,17 @@
*/
namespace Ad5001\BetterGen\utils;
# Common utils under no namespace made for a specific usage
# Common utils under no namespace made for a specific usage
class CommonUtils {
/**
* Searches case insensitively array $haystack for $needle.
* src: http://php.net/manual/en/function.in-array.php#89256
* @param mixed $needle
* @param array $haystack
* @return bool
*/
static function in_arrayi($needle, array $haystack) :bool {
return in_array(strtolower($needle), array_map('strtolower', $haystack));
}
/**
* Searches case insensitively array $haystack for $needle.
* src: http://php.net/manual/en/function.in-array.php#89256
* @param mixed $needle
* @param array $haystack
* @return bool
*/
static function in_arrayi($needle, array $haystack): bool {
return in_array(strtolower($needle), array_map('strtolower', $haystack));
}
}