1+ <?php
2+
3+ namespace NeiroNetwork \MiniatureWorld \world ;
4+
5+ use pocketmine \event \world \WorldInitEvent ;
6+ use pocketmine \event \world \WorldLoadEvent ;
7+ use pocketmine \player \ChunkSelector ;
8+ use pocketmine \Server ;
9+ use pocketmine \world \format \Chunk ;
10+ use pocketmine \world \World ;
11+ use pocketmine \world \WorldCreationOptions ;
12+ use pocketmine \world \WorldManager ;
13+
14+ final class WorldGenerator{
15+
16+ /**
17+ * @see WorldManager::generateWorld()
18+ */
19+ public static function generate (string $ name , WorldCreationOptions $ options , int $ chunkRadius = 8 , ?\Closure $ onCompletion = null ) : bool {
20+ $ manager = ($ server = Server::getInstance ())->getWorldManager ();
21+
22+ if (trim ($ name ) === "" || $ manager ->isWorldGenerated ($ name )){
23+ return false ;
24+ }
25+
26+ $ providerEntry = $ manager ->getProviderManager ()->getDefault ();
27+
28+ $ path = self ::getWorldPath ($ name );
29+ $ providerEntry ->generate ($ path , $ name , $ options );
30+
31+ $ world = new World ($ server , $ name , $ providerEntry ->fromPath ($ path ), $ server ->getAsyncPool ());
32+ self ::addWorldToManager ($ world );
33+
34+ $ world ->setAutoSave ($ manager ->getAutoSave ());
35+
36+ (new WorldInitEvent ($ world ))->call ();
37+
38+ (new WorldLoadEvent ($ world ))->call ();
39+
40+ $ spawnLocation = $ world ->getSpawnLocation ();
41+ $ centerX = $ spawnLocation ->getFloorX () >> Chunk::COORD_BIT_SIZE ;
42+ $ centerZ = $ spawnLocation ->getFloorZ () >> Chunk::COORD_BIT_SIZE ;
43+
44+ $ selected = iterator_to_array ((new ChunkSelector ())->selectChunks ($ chunkRadius - 1 , $ centerX , $ centerZ ));
45+ $ done = 0 ;
46+ $ total = count ($ selected );
47+ foreach ($ selected as $ index ){
48+ World::getXZ ($ index , $ chunkX , $ chunkZ );
49+ $ world ->orderChunkPopulation ($ chunkX , $ chunkZ , null )->onCompletion (
50+ static function () use (&$ done , $ total , $ onCompletion ) : void {
51+ if (++$ done === $ total ) $ onCompletion ();
52+ },
53+ static function () : void {}
54+ );
55+ }
56+
57+ return true ;
58+ }
59+
60+ /**
61+ * @see WorldManager::getWorldPath()
62+ */
63+ private static function getWorldPath (string $ name ) : string {
64+ $ manager = Server::getInstance ()->getWorldManager ();
65+ $ method = (new \ReflectionClass ($ manager ))->getMethod ("getWorldPath " );
66+ $ method ->setAccessible (true );
67+ return $ method ->invokeArgs ($ manager , [$ name ]);
68+ }
69+
70+ private static function addWorldToManager (World $ world ) : void {
71+ $ manager = Server::getInstance ()->getWorldManager ();
72+
73+ $ property = (new \ReflectionClass ($ manager ))->getProperty ("worlds " );
74+ $ property ->setAccessible (true );
75+
76+ $ worlds = $ property ->getValue ($ manager );
77+ $ worlds [$ world ->getId ()] = $ world ;
78+
79+ $ property ->setValue ($ manager , $ worlds );
80+ }
81+ }
0 commit comments