getServer()->getPluginManager()->registerEvents($this, $this); Generator::addGenerator(BetterNormal::class, "betternormal"); if($this->isOtherNS()) $this->getLogger()->warning("Tesseract detected. Note that some parts of the generator could not work properly"); @mkdir($this->getDataFolder()); if(! file_exists(LootTable::getPluginFolder(). "processingLoots.json")) file_put_contents(LootTable::getPluginFolder(). "processingLoots.json", "{}"); } /* * Called when the plugin disables */ public function onDisable() { } /* * 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(\pocketmine\command\CommandSender $sender, \pocketmine\command\Command $cmd, $label, array $args): bool { switch($cmd->getName()) { case "createworld" : // /createworld [generator = betternormal] [seed = rand()] [options(json)] switch(count($args)) { case 0 : return false; break; case 1 : // /createworld $name = $args [0]; $generator = Generator::getGenerator("betternormal"); $generatorName = "betternormal"; $seed = $this->generateRandomSeed(); $options = [ ]; break; case 2 : // /createworld [generator = betternormal] $name = $args [0]; $generator = Generator::getGenerator($args [1]); if(Generator::getGeneratorName($generator) !== strtolower($args [1])) { $sender->sendMessage(self::PREFIX . "§4Could not find generator {$args[1]}. Are you sure it is registered?"); return true; } $generatorName = strtolower($args [1]); $seed = $this->generateRandomSeed(); $options = [ ]; break; case 3 : // /createworld [generator = betternormal] [seed = rand()] $name = $args [0]; $generator = Generator::getGenerator($args [1]); if(Generator::getGeneratorName($generator) !== strtolower($args [1])) { $sender->sendMessage(self::PREFIX . "§4Could not find generator {$args[1]}. Are you sure it is registered?"); return true; } $generatorName = strtolower($args [1]); if(preg_match("[^\d]", $args [2]) !== false) { $parts = str_split($args [2]); foreach($parts as $key => $str) { $parts [$key] = ord($str); } $seed = implode("", $parts); } else { $seed = $args [2]; } $options = [ ]; break; default : // /createworld [generator = betternormal] [seed = rand()] [options(json)] $name = $args [0]; $generator = Generator::getGenerator($args [1]); if(Generator::getGeneratorName($generator) !== strtolower($args [1])) { $sender->sendMessage(self::PREFIX . "§4Could not find generator {$args[1]}. Are you sure it is registered?"); return true; } $generatorName = strtolower($args [1]); if(preg_match("[^\d]", $args [2]) !== false) { $parts = str_split($args [2]); foreach($parts as $key => $str) { $parts [$key] = ord($str); } $seed = implode("", $parts); } else { $seed = $args [2]; } unset($args [0], $args [1], $args [2]); $options = json_decode($args [3], true); if(! is_array($json)) { $sender->sendMessage(Main::PREFIX . "§4Invalid JSON for options."); return true; } break; } $this->getServer()->broadcastMessage(Main::PREFIX . "§aGenerating level $name with generator $generatorName and seed $seed.."); $this->getServer()->generateLevel($name, $seed, $generator, $options); $this->getServer()->loadLevel($name); return true; break; } } /* * Registers a forest type. * @param $name string * @param $treeClass string * @params $infos Array(temperature, rainfall) * @return bool */ public function registerForest(string $name, string $treeClass, array $infos): bool { if(! @class_exists($treeClass)) return false; if(! @is_subclass_of($treeClass, "pocketmine\\level\\generator\\normal\\object\\Tree")) return false; if(count($infos) < 2 or ! is_float($infos [0]) or ! is_float($infos [1])) return false; return BetterForest::registerForest($name, $treeClass, $infos); } /* * 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) { $reflection = new \ReflectionClass('pocketmine\\level\\generator\\biome\\Biome'); $register = $reflection->getMethod('register'); $register->setAccessible(true); $register->invoke(null, $id, $biome); BetterNormal::registerBiome($biome); } /* * Generates a(semi) random seed. * @return int */ public function generateRandomSeed(): int { return(int) round(time() * rand(0, time()) / memory_get_usage()); } // Listener /* * Checks after a chunk populates so we an add tiles and loot tables * @param $event pocketmine\event\level\ChunkPopulateEvent * @return int */ 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 interacts with a loot chest 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; echo "Doing {$event->getBlock()}"; $chest = new \pocketmine\block\Chest(0); $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) ]); $chest->setLevel($event->getBlock()->getLevel()); $cItem = Item::get(Item::CHEST, 0); $cItem->setCustomName("§k(Fake)§r Minecart chest"); $chest->place($cItem, $event->getBlock()->getLevel()->getBlock($event->getBlock()), $chest, 0, 0, 0, 0); $inv = $event->getBlock()->getLevel()->getTile($event->getBlock()); LootTable::fillChest($inv->getInventory(), $event->getBlock()); } /* * Checks when a player breaks a loot chest which is not created to create it */ 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; echo "Doing {$event->getBlock()}"; $chest = new \pocketmine\block\Chest(0); $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) ]); $chest->setLevel($event->getBlock()->getLevel()); $cItem = Item::get(Item::CHEST, 0); $cItem->setCustomName("§k(Fake)§r Minecart chest"); $chest->place($cItem, $event->getBlock()->getLevel()->getBlock($event->getBlock()), $chest, 0, 0, 0, 0); $inv = $event->getBlock()->getLevel()->getTile($event->getBlock()); LootTable::fillChest($inv->getInventory(), $event->getBlock()); $event->setCancelled(); } /* * Check if it's a Tesseract like namespace * @return bool */ public static function isOtherNS() { try { return @class_exists("pocketmine\\level\\generator\\normal\\object\\OakTree"); } catch(\Exception $e) { return false; } } }