PHP: $this->levels = $cfg->get("Levels");//$this->levels = "world" , "world2"foreach ($this->levels as $levelname) { $level = $this->getServer()->getLevelByName("$levelname"); //line 71 } Code: [Server thread/CRITICAL]: "Could not pass event 'pocketmine\event\player\PlayerInteractEvent' to 'Test v1.0.0': Call to a member function getLevelByName() on null on Test\eventmanager [18:52:30] [Server thread/CRITICAL]: Error: "Call to a member function getLevelByName() on null" (EXCEPTION) in "/Test/src/Test/eventmanager" at line 71 Anyone know what did do wrong? =)
First of all, the way you put it, $level will keep being overwritten by the next world in the array. Second, you don't need to put quotes around variables, third, are you executing this code in a class that extends PluginBase? (usually your main class)
Oh it still happen when it is extended to pluginbase and I just wanna tell you that $this->levels is an array PS : the quotes are TYPING ERROR only , it doesn't exist in my file XD
Also, I tried PHP: $this->levels = $cfg->get("Levels");//$this->levels = "world" , "world2"$level = $this->getServer()->getLevelByName($this->levels[0]); //line 71 It still return the level on NULL =(
It's too much work to explain everything, because you really need to understand how it works. I recommend you to learn OOP in this case (Object Orientated Programming)
I assume you're trying to get the levels from an array of level names, in which case use: PHP: $this->levels = $cfg->get("Levels");$this->levelArray = [];foreach ($this->levels as $levelname) { array_push($this->levelArray, $this->getServer()->getLevelByName("$levelname"))} Will return an array of levels, and possibly one or more nulls if one or more levels do not exist.
The error means that $this->getServer() is null, NOT $levelname. If you post the full plugin code on github we might be able to help, otherwise...
I have done var_dump($this->levels) and var_dump($levelname) and var_dump($this->getServer()) none of them return NULL Code: array(2) { [0]=> string(6) "world1" [1]=> string(6) "world2" } string(6) "world1" NULL
As you can see $this->getServer() DOES return null. Again, it's too much to explain in a single post. Try understanding the basics of OOP, especially constructors are important for your case. Also, know that only one file in your plugin should extend PluginBase, unless you know what you're doing. *citation needed*
PHP: class eventmanager extends PluginBase implements Listener { public $queuemanager; private $cfg; private $rooms; public function onInteract(PlayerInteractEvent $event) { $player = $event->getPlayer(); $tile = $event->getPlayer()->getLevel()->getTile($event->getBlock()); if($tile instanceof \pocketmine\tile\Sign) { if($tile->getText()[0] == C::AQUA . mb::mb . C::RESET) { $pos = new Position($this->red["X"] , $this->red["Y"] , $this->red["Z"] , $this->queuemanager->getFreeRoom($this->rooms)); $this->queuemanager->addPlayer($player, $pos , $this->queuemanager->getFreeRoom($this->rooms)); } } }} queuemanger PHP: class queuemanager extends PluginBase { private $queue = []; private $roomlist = []; private $room; public $status; public function getFreeRoom(array $rooms) { $this->roomlist = $rooms; foreach ($rooms as $roomname) { $freeroom = $this->getServer()->getLevelByName($roomname); return $freeroom; } } public function addPlayer(Player $player , $pos) { if(in_array($player, $this->queue)) { return true; } else { array_push($this->queue, $Player); $player->teleport($pos); $player->sendMessage(C::AQUA . mb::mb . C::YELLOW . "You have joined " . $this->room . "!"); } } }
Don't use PluginBase in more than one class. Just make a public variable called plugin, and add it to the constructor and set it. Another problem is that is seems you have not initialized the variable "$this->queuemanager" As the wise PEMapModder once said, " Don't make it extend PluginBase. PluginBase is initialized with its methods from PocketMine core, but you didn't do that. PluginBase actually just means nothing." I cleaned it up a bit, try this. PHP: class EventManager extends PluginBase implements Listener { private $queueManager; private $cfg; private $rooms = []; private $red = []; //never initialized that :P public function onEnable(){ /* * Set the config, register events, do other things you need, etc. */ $this->setQueueManager(); } public function setQueueManager(){ $this->queueManager = new QueueManager($this); } public function getQueueManager(){ return $this->queueManager; } public function onInteract(PlayerInteractEvent $event){ $player = $event->getPlayer(); $tile = $event->getPlayer()->getLevel()->getTile($event->getBlock()); if($tile instanceof \pocketmine\tile\Sign){ //what is mb::mb? Who cares if($tile->getText()[0] == C::AQUA.mb::mb.C::RESET){ $pos = new Position($this->red["X"], $this->red["Y"], $this->red["Z"], $this-.getQueueManager()->getFreeRoom($this->rooms)); $this->getQueueManager()->addPlayer($player, $pos); // You added an unneeded third parameter that was checking for the level AGAIN } } }} PHP: class QueueManager { private $plugin; private $queue = []; private $roomList = []; private $room; public $status; public function __construct(EventManager $plugin){ $this->plugin = $plugin; } public function getPlugin(){ return $this->plugin; } public function getFreeRoom(array $rooms){ $this->roomList = $rooms; foreach($rooms as $roomName){ return $this->getPlugin()->getServer()->getLevelByName($roomName); } return false; } public function addPlayer(Player $player, Position $position){ if(in_array($player, $this->queue)){ return true; } else { array_push($this->queue, $player); $player->teleport($position); $player->sendMessage("Insert whatever message you need here!"); } }}
First, I have already register event in my main class and like this... PHP: $this->getServer()->getPluginManager()->registerEvents(new eventmanager($queuemanager , $this->cfg), $this); Also,if queuemanager doesn't extend PluginBase , how does it get the getLevelByName() function? p.s. : some code like addPlayer(a,b,c) just because I haven't change it after I have written new function Thx for reminding me
As said before, don't extend PluginBase in a class if it's not your main class(the one set in your plugin.yml) To get the function getLevelByName() you'll have to refer to your main class and get the server and then you can access all of the methods afterwards. If QueueManager is your main class, go ahead and have it extend PluginBase, but you should only extend PluginBase in your main class. The only ways to get the instance of a server is through your main class or calling it statically via Server::getInstance()
Note: another way you could get the server, is by adding a server parameter to the getFreeRoom method. such as PHP: public function getFreeRoom(array $rooms, Server $server){ $this->roomList = $rooms; foreach($rooms as $roomName){ return $server->getLevelByName($roomName); } return false; } PHP: $this->queuemanager->addPlayer($player, $pos , $this->queuemanager->getFreeRoom($this->rooms, $player->getServer())); Just another way if you can't figure out anything else.
I fixed it! PHP: //main $queuemanager = new queuemanager($this->getServer()); //bad but still a method XD $this->getServer()->getPluginManager()->registerEvents(new eventmanager($queuemanager , $this , $this->cfg), $this); PHP: //queuemanager public function __construct(Server $server) { $this->server = $server; }public function getFreeRoom(array $rooms) { $this->roomlist = $rooms; foreach ($rooms as $roomname) { $freeroom = $this->server->getLevelByName($roomname); } }public function addPlayer(Player $player , $pos) { if(in_array($player, $this->queue)) { return true; } else { array_push($this->queue, $Player); $player->teleport($pos); $player->sendMessage(C::AQUA . mb::mb . C::YELLOW . "You have joined " . $this->room . "!"); } PHP: //eventmanagerpublic function onInteract(PlayerInteractEvent $event) { $player = $event->getPlayer(); $tile = $event->getPlayer()->getLevel()->getTile($event->getBlock()); if($tile instanceof \pocketmine\tile\Sign) { if($tile->getText()[0] == C::AQUA . mb::mb . C::RESET) { $pos = new Position($this->red["X"] , $this->red["Y"] , $this->red["Z"] , $this->queuemanager->getFreeRoom($this->rooms)); $this->queuemanager->addPlayer($player, $pos , $this->queuemanager->getFreeRoom($this->rooms)); } } }
He never said he is trying to add the levels to an array. Can you please stop making wild guesses? It should not have been crime to post wrong answers, but if you continue to post irrelevant answers like this, I'm afraid I cannot stop myself. WTF... Does quoting PEMapModder really increase the authority of your post?