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 */
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
*/
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;
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 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)
new IntTag("x", (int)$block->x),
new IntTag("y", (int)$block->y),
new IntTag("z", (int)$block->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
$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) {
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);
@ -73,11 +74,12 @@ class BetterDesert extends SandyBiome implements Mountainable {
Block::get(Block::SANDSTONE, 0)
]);
}
public function getName(): string {
return "BetterDesert";
}
/*
/**
* Returns biome id
*/
public function getId() {

View file

@ -34,46 +34,37 @@ class BetterForest extends ForestBiome implements Mountainable {
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,7 +22,7 @@ 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),
@ -30,18 +30,19 @@ class BetterIcePlains extends SnowyBiome implements Mountainable {
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

@ -47,10 +47,10 @@ class BetterMesa extends SandyBiome {
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);
@ -104,11 +104,12 @@ class BetterMesa extends SandyBiome {
Block::get(Block::RED_SANDSTONE, 0)
]);
}
public function getName(): string {
return "BetterMesa";
}
/*
/**
* Returns biome id
*/
public function getId() {

View file

@ -42,10 +42,10 @@ class BetterMesaPlains extends SandyBiome {
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);
@ -100,11 +100,12 @@ class BetterMesaPlains extends SandyBiome {
Block::get(Block::RED_SANDSTONE, 0)
]);
}
public function getName(): string {
return "BetterMesaPlains";
}
/*
/**
* Returns biome id
*/
public function getId() {

View file

@ -19,7 +19,7 @@ use pocketmine\level\generator\biome\Biome;
class BetterRiver extends Biome {
public function __construct() {
$this->clearPopulators ();
$this->clearPopulators();
$this->setGroundCover([
Block::get(Block::SAND, 0),
@ -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,16 +40,12 @@ 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;
}
/**
@ -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;
@ -59,19 +59,11 @@ class BetterNormal extends Generator {
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,33 +72,59 @@ 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;
/*
* Picks a biome by X and Z
* @param $x int
* @param $z int
* @return Biome
/**
* Constructs the class
* @param $options array
*/
public function pickBiome($x, $z) {
$hash = $x * 2345803 ^ $z * 9236449 ^ $this->level->getSeed ();
$hash *= $hash + 223;
$xNoise = $hash >> 20 & 3;
$zNoise = $hash >> 22 & 3;
if ($xNoise == 3) {
$xNoise = 1;
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();
}
if ($zNoise == 3) {
$zNoise = 1;
}
$b = $this->selector->pickBiome($x + $xNoise - 1, $z + $zNoise - 1);
if ($b instanceof Mountainable && $this->random->nextBoundedInt(1000) < 3) {
$b = clone $b;
// $b->setElevation($b->getMinElevation () + (50 * $b->getMinElevation () / 100), $b->getMaxElevation () + (50 * $b->getMinElevation () / 100));
/**
* 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);
}
}
return $b;
}
/**
@ -121,9 +139,9 @@ class BetterNormal extends Generator {
self::$levels[] = $level;
$this->random->setSeed($this->level->getSeed ());
$this->random->setSeed($this->level->getSeed());
$this->noiseBase = new Simplex($this->random, 4, 1 / 4, 1 / 32);
$this->random->setSeed($this->level->getSeed ());
$this->random->setSeed($this->level->getSeed());
$this->registerBiome(Biome::getBiome(Biome::OCEAN));
$this->registerBiome(Biome::getBiome(Biome::PLAINS));
@ -152,55 +170,55 @@ class BetterNormal extends Generator {
"getBiome"
], self::getBiome(0, 0));
foreach(self::$biomes as $rain) {
foreach($rain as $biome) {
foreach (self::$biomes as $rain) {
foreach ($rain as $biome) {
$this->selector->addBiome($biome);
}
}
$this->selector->recalculate ();
$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"])) {
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"])) {
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"])) {
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"])) {
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"])) {
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"])) {
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([
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),
@ -210,7 +228,7 @@ class BetterNormal extends Generator {
new OreType2(new Dirt (), 20, 32, 0, 128),
new OreType2(new Gravel (), 10, 16, 0, 128)
]);
if(!Main::isOtherNS()) $ores->setOreTypes([
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),
@ -224,33 +242,33 @@ class BetterNormal extends Generator {
}
}
/*
/**
* 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"])) {
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 ()]);
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 (!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)
@ -261,9 +279,9 @@ class BetterNormal extends Generator {
$rainfall = 0.9;
}
}
$b = self::$biomes[( string) round($rainfall, 1)];
foreach($b as $t => $biome) {
if ($temperature <=(float) $t) {
$b = self::$biomes[( string)round($rainfall, 1)];
foreach ($b as $t => $biome) {
if ($temperature <= (float)$t) {
$ret = $biome;
break;
}
@ -274,16 +292,7 @@ class BetterNormal extends Generator {
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
@ -291,25 +300,25 @@ class BetterNormal extends Generator {
*/
public function generateChunk($chunkX, $chunkZ) {
$this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->level->getSeed ());
$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 = [ ];
$biomeCache = [];
for($x = 0; $x < 16; $x++) {
for($z = 0; $z < 16; $z++) {
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 ());
$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++) {
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];
@ -323,8 +332,8 @@ class BetterNormal extends Generator {
$biomeCache[$index] = $adjacent = $this->pickBiome($chunkX * 16 + $x + $sx, $chunkZ * 16 + $z + $sz);
}
}
$minSum += ($adjacent->getMinElevation () - 1) * $weight;
$maxSum += $adjacent->getMaxElevation () * $weight;
$minSum += ($adjacent->getMinElevation() - 1) * $weight;
$maxSum += $adjacent->getMaxElevation() * $weight;
$weightSum += $weight;
}
@ -335,8 +344,8 @@ class BetterNormal extends Generator {
$smoothHeight = ($maxSum - $minSum) / 2;
for($y = 0; $y < 128; $y++) {
if ($y < 3 || ($y < 5 && $this->random->nextBoolean ())) {
for ($y = 0; $y < 128; $y++) {
if ($y < 3 || ($y < 5 && $this->random->nextBoolean())) {
$chunk->setBlockId($x, $y, $z, Block::BEDROCK);
continue;
}
@ -351,27 +360,53 @@ class BetterNormal extends Generator {
}
}
foreach($this->generationPopulators as $populator) {
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
* @return Biome
*/
public function pickBiome($x, $z) {
$hash = $x * 2345803 ^ $z * 9236449 ^ $this->level->getSeed();
$hash *= $hash + 223;
$xNoise = $hash >> 20 & 3;
$zNoise = $hash >> 22 & 3;
if ($xNoise == 3) {
$xNoise = 1;
}
if ($zNoise == 3) {
$zNoise = 1;
}
$b = $this->selector->pickBiome($x + $xNoise - 1, $z + $zNoise - 1);
if ($b instanceof Mountainable && $this->random->nextBoundedInt(1000) < 3) {
$b = clone $b;
// $b->setElevation($b->getMinElevation () + (50 * $b->getMinElevation () / 100), $b->getMaxElevation () + (50 * $b->getMinElevation () / 100));
}
return $b;
}
/**
* 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);
public function getRandomLoot(Random $random = null) {
if (is_null($random)) $random = new Random();
$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"]));
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
}
}
$inv->setContents($items);
$cfg->remove($pos->x . ";" . $pos->y . ";" . $pos->z);
$cfg->save();
]
*/
}
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;
}
}
}
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
@ -49,11 +50,11 @@ class FallenTreePopulator extends AmountPopulator {
$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,7 +33,7 @@ use pocketmine\utils\Random;
class FloatingIslandPopulator extends AmountPopulator {
/*
/**
* Populate the chunk
* @param $level pocketmine\level\ChunkManager
* @param $chunkX int
@ -45,7 +45,7 @@ class FloatingIslandPopulator extends AmountPopulator {
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,8 +81,7 @@ class FloatingIslandPopulator extends AmountPopulator {
}
/*
/**
* Builds a an island shape
* @param $level pocketmine\level\ChunkManager
* @param $pos pocketmine\math\Vector3
@ -96,20 +94,20 @@ class FloatingIslandPopulator extends AmountPopulator {
$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,9 +130,7 @@ class FloatingIslandPopulator extends AmountPopulator {
}
/*
/**
* BPopulate the island with ores
* @param $level pocketmine\level\ChunkManager
* @param $pos pocketmine\math\Vector3
@ -145,7 +141,7 @@ class FloatingIslandPopulator extends AmountPopulator {
*/
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([
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)),
@ -153,7 +149,7 @@ class FloatingIslandPopulator extends AmountPopulator {
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([
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)),

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;
@ -270,19 +270,19 @@ class MineshaftPopulator extends AmountPopulator {
];
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 ?[
($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

@ -33,12 +33,12 @@ class TreePopulator extends AmountPopulator {
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

@ -30,7 +30,7 @@ class Bush extends Object {
protected $leaf;
protected $height;
/*
/**
* Constructs the class
* @param $leafId int
* @param $leafData int
@ -42,7 +42,7 @@ class Bush extends Object {
];
}
/*
/**
* 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

@ -41,7 +41,7 @@ class FallenTree extends Object {
protected $random;
private $length = 0;
/*
/**
* Constructs the class
* @param $tree ObjectTree
* @throws Exeption
@ -50,7 +50,7 @@ class FallenTree extends Object {
$this->tree = $tree;
}
/*
/**
* Places a fallen tree
* @param $level pocketmine\level\ChunkManager
* @param $x int
@ -67,35 +67,35 @@ 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)])) {
$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)])) {
}, $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)) {
if (in_array(false, $return, true)) {
return false;
}
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)])) {
$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)])) {
}, $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)) {
if (in_array(false, $return, true)) {
return false;
}
break;
@ -103,7 +103,7 @@ class FallenTree extends Object {
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

@ -33,71 +33,27 @@ class Igloo extends Object {
];
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)]))
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);
}
@ -167,12 +123,12 @@ 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)]))
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);
}
@ -241,12 +197,12 @@ 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)]))
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);
}
@ -315,12 +271,12 @@ 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)]))
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,8 +22,6 @@ use pocketmine\utils\Random;
class Well extends Object {
/** @var ChunkManager */
protected $level;
public $overridable = [
Block::AIR => true,
6 => true,
@ -36,6 +34,8 @@ class Well extends Object {
Block::LEAVES2 => true,
Block::CACTUS => true
];
/** @var ChunkManager */
protected $level;
protected $directions = [
[
1,
@ -43,19 +43,19 @@ class Well extends Object {
],
[
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;
@ -30,7 +30,7 @@ class BuildingUtils {
Block::PLANK
];
/*
/**
* Fills an area
* @param $level pocketmine\level\ChunkManager
* @param $pos1 pocketmine\math\Vector3
@ -41,159 +41,13 @@ 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());
}
}
/*
* 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
* @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 ());
}
}
/*
* Fills an area by custom filling
* @param $pos1 pocketmine\math\Vector3
* @param $pos2 pocketmine\math\Vector3
* @param $call callback
* @param $params array
* @return 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);
}
return $return;
}
/*
* Creates walls
* @param $level pocketmine\level\ChunkManager
* @param $pos1 pocketmine\math\Vector3
* @param $pos2 pocketmine\math\Vector3
* @param $block pocketmine\block\Block
* @return void
*/
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($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
* @param $pos2 pocketmine\math\Vector3
* @param $block pocketmine\block\Block
* @return void
*/
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 ());
}
}
/*
* Creates all corners from positions. Used for Mineshaft.
* @param $level pocketmine\level\ChunkManager
* @param $pos1 pocketmine\math\Vector3
* @param $pos2 pocketmine\math\Vector3
* @param $block pocketmine\block\Block
* @return void
*/
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 ());
}
}
/*
* Creates the bottom of a structure
* @param $level pocketmine\level\ChunkManager
* @param $pos1 pocketmine\math\Vector3
* @param $pos2 pocketmine\math\Vector3
* @param $block pocketmine\block\Block
* @return void
*/
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 ());
}
}
/*
* Builds a random structure depending of length, height, depth and random
* @param $level pocketmine\level\ChunkManager
* @param $pos pocketmine\math\Vector3
* @param $infos pocketmine\math\Vector3
* @param $random pocketmine\utils\Random
* @param $block pocketmine\block\Block
* @return void
*/
public static function buildRandom(ChunkManager $level, Vector3 $pos, Vector3 $infos, Random $random, Block $block) {
$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 ++) {
// 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 ());
}
}
}
}
}
/*
/**
* 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
@ -207,4 +61,149 @@ class BuildingUtils {
$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
* @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());
}
}
/**
* Fills an area by custom filling
* @param $pos1 pocketmine\math\Vector3
* @param $pos2 pocketmine\math\Vector3
* @param $call callback
* @param $params array
* @return 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);
}
return $return;
}
/**
* Creates walls
* @param $level pocketmine\level\ChunkManager
* @param $pos1 pocketmine\math\Vector3
* @param $pos2 pocketmine\math\Vector3
* @param $block pocketmine\block\Block
* @return void
*/
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 ($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
* @param $pos2 pocketmine\math\Vector3
* @param $block pocketmine\block\Block
* @return void
*/
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());
}
}
/**
* Creates all corners from positions. Used for Mineshaft.
* @param $level pocketmine\level\ChunkManager
* @param $pos1 pocketmine\math\Vector3
* @param $pos2 pocketmine\math\Vector3
* @param $block pocketmine\block\Block
* @return void
*/
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());
}
}
/**
* Creates the bottom of a structure
* @param $level pocketmine\level\ChunkManager
* @param $pos1 pocketmine\math\Vector3
* @param $pos2 pocketmine\math\Vector3
* @param $block pocketmine\block\Block
* @return void
*/
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());
}
}
/**
* Builds a random structure depending of length, height, depth and random
* @param $level pocketmine\level\ChunkManager
* @param $pos pocketmine\math\Vector3
* @param $infos pocketmine\math\Vector3
* @param $random pocketmine\utils\Random
* @param $block pocketmine\block\Block
* @return void
*/
public static function buildRandom(ChunkManager $level, Vector3 $pos, Vector3 $infos, Random $random, Block $block) {
$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++) {
// 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());
}
}
}
}
}
}

View file

@ -13,7 +13,7 @@
*/
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 {
/**
@ -23,7 +23,7 @@ class CommonUtils {
* @param array $haystack
* @return bool
*/
static function in_arrayi($needle, array $haystack) :bool {
static function in_arrayi($needle, array $haystack): bool {
return in_array(strtolower($needle), array_map('strtolower', $haystack));
}
}