2017-04-23 14:42:51 +00:00
< ? php
2017-05-10 15:03:04 +00:00
/**
2017-05-12 07:01:46 +00:00
* ____ __ __ ____
* / \ _ `\ /\ \__ /\ \__ /\ _` \
* \ \ \L\ \ __ \ \ , _\\ \ , _\ __ _ __ \ \ \L\_\ __ ___
* \ \ _ < ' /' __ `\\ \ \/ \ \ \/ /'__` \ / \ `'__\\ \ \L_L /'__` \ / ' _ ` \
* \ \ \L\ \ / \ __ / \ \ \_ \ \ \_ / \ __ / \ \ \ / \ \ \ / , \ / \ __ / / \ \ / \ \
2017-05-10 15:03:04 +00:00
* \ \____ / \ \____\ \ \__\ \ \__\\ \____\\ \_\ \ \____ / \ \____\\ \_\ \_\
* \ / ___ / \ / ____ / \ / __ / \ / __ / \ / ____ / \ / _ / \ / ___ / \ / ____ / \ / _ / \ / _ /
2017-05-11 11:29:22 +00:00
* Tomorrow ' s pocketmine generator .
2017-05-10 15:03:04 +00:00
* @ author Ad5001
* @ link https :// github . com / Ad5001 / BetterGen
2017-04-23 14:42:51 +00:00
*/
namespace Ad5001\BetterGen ;
2017-05-11 12:07:26 +00:00
use Ad5001\BetterGen\biome\BetterForest ;
use Ad5001\BetterGen\generator\BetterNormal ;
use Ad5001\BetterGen\loot\LootTable ;
2017-05-12 07:01:46 +00:00
use Ad5001\BetterGen\structure\Temple ;
2017-05-11 12:07:26 +00:00
use pocketmine\block\Block ;
2017-05-11 11:29:22 +00:00
use pocketmine\command\Command ;
use pocketmine\command\CommandSender ;
2017-05-12 07:01:46 +00:00
use pocketmine\command\ConsoleCommandSender ;
2017-05-11 12:07:26 +00:00
use pocketmine\event\block\BlockBreakEvent ;
use pocketmine\event\level\ChunkPopulateEvent ;
2017-05-11 11:29:22 +00:00
use pocketmine\event\Listener ;
2017-05-11 12:07:26 +00:00
use pocketmine\event\player\PlayerInteractEvent ;
2017-04-23 14:42:51 +00:00
use pocketmine\level\generator\biome\Biome ;
use pocketmine\level\generator\Generator ;
use pocketmine\nbt\tag\CompoundTag ;
2017-05-11 12:07:26 +00:00
use pocketmine\nbt\tag\IntTag ;
2017-04-23 14:42:51 +00:00
use pocketmine\nbt\tag\ListTag ;
use pocketmine\nbt\tag\StringTag ;
2017-05-12 07:01:46 +00:00
use pocketmine\Player ;
2017-05-11 12:07:26 +00:00
use pocketmine\plugin\PluginBase ;
use pocketmine\tile\Chest ;
2017-04-23 14:42:51 +00:00
use pocketmine\tile\Tile ;
2017-05-11 12:07:26 +00:00
use pocketmine\utils\Config ;
2017-05-12 07:01:46 +00:00
use pocketmine\utils\Random ;
2017-04-23 14:42:51 +00:00
2017-05-11 11:29:22 +00:00
class Main extends PluginBase implements Listener {
2017-04-23 14:42:51 +00:00
const PREFIX = " §l§o§b[§r§l§2Better§aGen§o§b]§r§f " ;
const SAKURA_FOREST = 100 ; // Letting some place for future biomes.
2017-05-12 07:01:46 +00:00
2017-04-23 14:42:51 +00:00
/*
* Called when the plugin enables
*/
2017-05-12 07:01:46 +00:00
public static function registerBiome ( int $id , Biome $biome ) {
BetterNormal :: registerBiome ( $biome );
2017-04-23 14:42:51 +00:00
}
2017-05-12 07:01:46 +00:00
2017-04-23 14:42:51 +00:00
/*
* Called when the plugin disables
*/
2017-05-12 07:01:46 +00:00
public function onEnable () {
$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 " , " { } " );
2017-04-23 14:42:51 +00:00
}
2017-05-12 07:01:46 +00:00
2017-04-23 14:42:51 +00:00
/*
* 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
*/
2017-05-12 07:01:46 +00:00
public static function isOtherNS () {
try {
return @ class_exists ( " pocketmine \\ level \\ generator \\ normal \\ object \\ OakTree " );
} catch ( \Exception $e ) {
return false ;
}
}
/*
* Registers a forest type .
* @ param $name string
* @ param $treeClass string
* @ params $infos Array ( temperature , rainfall )
* @ return bool
*/
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
*/
2017-05-11 11:29:22 +00:00
public function onCommand ( CommandSender $sender , Command $cmd , $label , array $args ) : bool {
2017-05-12 07:01:46 +00:00
switch ( $cmd -> getName ()) {
2017-04-23 14:42:51 +00:00
case " createworld " : // /createworld <name> [generator = betternormal] [seed = rand()] [options(json)]
2017-05-12 07:01:46 +00:00
switch ( count ( $args )) {
2017-04-23 14:42:51 +00:00
case 0 :
return false ;
break ;
case 1 : // /createworld <name>
$name = $args [ 0 ];
$generator = Generator :: getGenerator ( " betternormal " );
$generatorName = " betternormal " ;
$seed = $this -> generateRandomSeed ();
2017-05-12 07:01:46 +00:00
$options = [];
2017-04-23 14:42:51 +00:00
break ;
case 2 : // /createworld <name> [generator = betternormal]
$name = $args [ 0 ];
$generator = Generator :: getGenerator ( $args [ 1 ]);
2017-05-12 07:01:46 +00:00
if ( Generator :: getGeneratorName ( $generator ) !== strtolower ( $args [ 1 ])) {
2017-04-23 14:42:51 +00:00
$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 ();
2017-05-12 07:01:46 +00:00
$options = [];
2017-04-23 14:42:51 +00:00
break ;
case 3 : // /createworld <name> [generator = betternormal] [seed = rand()]
$name = $args [ 0 ];
$generator = Generator :: getGenerator ( $args [ 1 ]);
2017-05-12 07:01:46 +00:00
if ( Generator :: getGeneratorName ( $generator ) !== strtolower ( $args [ 1 ])) {
2017-04-23 14:42:51 +00:00
$sender -> sendMessage ( self :: PREFIX . " §4Could not find generator { $args [ 1 ] } . Are you sure it is registered? " );
return true ;
}
$generatorName = strtolower ( $args [ 1 ]);
2017-05-12 07:01:46 +00:00
if ( preg_match ( " [^ \ d] " , $args [ 2 ]) !== false ) {
2017-04-23 14:42:51 +00:00
$parts = str_split ( $args [ 2 ]);
2017-05-12 07:01:46 +00:00
foreach ( $parts as $key => $str ) {
2017-04-23 14:42:51 +00:00
$parts [ $key ] = ord ( $str );
}
$seed = implode ( " " , $parts );
} else {
$seed = $args [ 2 ];
}
2017-05-12 07:01:46 +00:00
$options = [];
2017-04-23 14:42:51 +00:00
break ;
default : // /createworld <name> [generator = betternormal] [seed = rand()] [options(json)]
$name = $args [ 0 ];
$generator = Generator :: getGenerator ( $args [ 1 ]);
2017-05-12 07:01:46 +00:00
if ( Generator :: getGeneratorName ( $generator ) !== strtolower ( $args [ 1 ])) {
2017-04-23 14:42:51 +00:00
$sender -> sendMessage ( self :: PREFIX . " §4Could not find generator { $args [ 1 ] } . Are you sure it is registered? " );
return true ;
}
$generatorName = strtolower ( $args [ 1 ]);
2017-05-12 07:01:46 +00:00
if ( $args [ 2 ] == " rand " ) $args [ 2 ] = $this -> generateRandomSeed ();
if ( preg_match ( " [^ \ d] " , $args [ 2 ]) !== false ) {
2017-04-23 14:42:51 +00:00
$parts = str_split ( $args [ 2 ]);
2017-05-12 07:01:46 +00:00
foreach ( $parts as $key => $str ) {
2017-04-23 14:42:51 +00:00
$parts [ $key ] = ord ( $str );
}
$seed = implode ( " " , $parts );
} else {
$seed = $args [ 2 ];
}
unset ( $args [ 0 ], $args [ 1 ], $args [ 2 ]);
$options = json_decode ( $args [ 3 ], true );
2017-05-12 07:01:46 +00:00
if ( ! is_array ( $options )) {
2017-04-23 14:42:51 +00:00
$sender -> sendMessage ( Main :: PREFIX . " §4Invalid JSON for options. " );
return true ;
}
break ;
}
2017-05-10 15:03:04 +00:00
$options [ " preset " ] = json_encode ( $options );
2017-05-12 07:01:46 +00:00
if (( int ) $seed == 0 /*String*/ ) {
2017-05-10 15:03:04 +00:00
$seed = $this -> generateRandomSeed ();
}
2017-04-23 14:42:51 +00:00
$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 ;
2017-05-12 07:01:46 +00:00
case 'temple' : {
if ( $sender instanceof ConsoleCommandSender ) return false ;
/** @var Player $sender */
$temple = new Temple ();
2017-05-12 12:51:21 +00:00
$temple -> placeObject ( $sender -> getLevel (), $sender -> x , $sender -> y , $sender -> z , new Random ( microtime ()));
2017-05-12 07:01:46 +00:00
return true ;
}
2017-04-23 14:42:51 +00:00
}
2017-05-11 11:29:22 +00:00
return false ;
2017-04-23 14:42:51 +00:00
}
2017-05-12 07:01:46 +00:00
2017-04-23 14:42:51 +00:00
/*
* Generates a ( semi ) random seed .
* @ return int
*/
2017-05-12 07:01:46 +00:00
2017-04-23 14:42:51 +00:00
public function generateRandomSeed () : int {
2017-05-12 07:01:46 +00:00
return ( int ) round ( rand ( 0 , round ( time ()) / memory_get_usage ( true )) * ( int ) str_shuffle ( " 127469453645108 " ) / ( int ) str_shuffle ( " 12746945364 " ));
2017-04-23 14:42:51 +00:00
}
2017-05-12 07:01:46 +00:00
2017-04-23 14:42:51 +00:00
// Listener
2017-05-12 07:01:46 +00:00
2017-04-23 14:42:51 +00:00
/*
* Checks after a chunk populates so we an add tiles and loot tables
* @ param $event pocketmine\event\level\ChunkPopulateEvent
* @ return int
*/
2017-05-12 07:01:46 +00:00
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 );
}
/*
* Checks when a player interacts with a loot chest to create it .
*/
2017-04-23 14:42:51 +00:00
public function onChunkPopulate ( ChunkPopulateEvent $event ) {
$cfg = new Config ( LootTable :: getPluginFolder () . " processingLoots.json " , Config :: JSON );
2017-05-12 07:01:46 +00:00
foreach ( $cfg -> getAll () as $key => $value ) {
2017-04-23 14:42:51 +00:00
list ( $x , $y , $z ) = explode ( " ; " , $key );
2017-05-12 07:01:46 +00:00
if ( $value [ " saveAs " ] == " chest " && $event -> getLevel () -> getBlockIdAt ( $x , $y , $z ) == Block :: AIR ) {
2017-04-23 14:42:51 +00:00
$event -> getLevel () -> setBlockIdAt ( $x , $y , $z , Block :: CHEST );
} else {
$cfg -> remove ( $key );
$cfg -> save ();
}
}
}
2017-05-12 07:01:46 +00:00
2017-04-23 14:42:51 +00:00
/*
2017-05-12 07:01:46 +00:00
* Checks when a player breaks a loot chest which is not created to create it
2017-04-23 14:42:51 +00:00
*/
2017-05-12 07:01:46 +00:00
2017-04-23 14:42:51 +00:00
public function onInteract ( PlayerInteractEvent $event ) {
$cfg = new Config ( LootTable :: getPluginFolder () . " processingLoots.json " , Config :: JSON );
2017-05-12 07:01:46 +00:00
if ( $event -> getBlock () -> getId () !== Block :: CHEST ) return ;
if ( ! $cfg -> exists ( $event -> getBlock () -> getX () . " ; " . $event -> getBlock () -> getY () . " ; " . $event -> getBlock () -> getZ ())) return ;
2017-04-23 14:42:51 +00:00
$nbt = new CompoundTag ( " " , [
2017-05-12 07:01:46 +00:00
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 )
2017-04-23 14:42:51 +00:00
]);
2017-05-11 12:07:26 +00:00
/** @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 ());
2017-04-23 14:42:51 +00:00
}
2017-05-12 07:01:46 +00:00
2017-04-23 14:42:51 +00:00
/*
2017-05-12 07:01:46 +00:00
* Check if it ' s a Tesseract like namespace
* @ return bool
*/
2017-04-23 14:42:51 +00:00
public function onBlockBreak ( BlockBreakEvent $event ) {
$cfg = new Config ( LootTable :: getPluginFolder () . " processingLoots.json " , Config :: JSON );
2017-05-12 07:01:46 +00:00
if ( $event -> getBlock () -> getId () !== Block :: CHEST ) return ;
if ( ! $cfg -> exists ( $event -> getBlock () -> getX () . " ; " . $event -> getBlock () -> getY () . " ; " . $event -> getBlock () -> getZ ())) return ;
2017-04-23 14:42:51 +00:00
$nbt = new CompoundTag ( " " , [
2017-05-11 12:07:26 +00:00
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 )
2017-04-23 14:42:51 +00:00
]);
2017-05-11 12:07:26 +00:00
/** @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
2017-04-23 14:42:51 +00:00
}
2017-05-08 13:59:19 +00:00
}