Advertisement
  1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Getting each of the last two players in a world

Comments in 'Plugin Development' started by SpopovabgS, Aug 23, 2016.

  1. SpopovabgS
    Offline

    SpopovabgS New Member

    Joined:
    Oct 4, 2015
    Posts:
    8
    Minecraft User:
    _SKDownBG_
    I've been hitting my head in a wall for 2 days trying to figure this out. Any help would be greatly appreciated :D

    I'm trying to get each of the last two players in a world, i've tried several methods, but none succeeded

    Here are the methods i tried:

    Method 1:
    PHP:
    $lps $level->getPlayers();
    if(
    count($lps) == 2) {
      
    $player1 $lps[0];
      
    $player2 $lps[1];
    }
    Method 2:
    PHP:
    $lps $level->getPlayers();
    if(
    count($lps) == 2) {
      foreach(
    $lps as $key => $lp) {
        
    $player1 $lp[0];
        
    $player2 $lp[1];
      }
    }
    Error: "Cannot use object of type pocketmine\Player as array" (i don't remember on which method this was :p)

    Thank you for any help you can provide!
  2. MyNameIsTriXz
    Offline

    MyNameIsTriXz Notable Member

    Joined:
    Aug 17, 2015
    Posts:
    538
    Minecraft User:
    MyNameIsTriXz
    Level::getPlayers() returns an array with players, it is not a multidimensional array. Here is the code to solve your problem:

    PHP:
    $c 0;
    $player1 null;
    $player2 null;

    if(
    count($level->getPlayers()) == 2){
    foreach(
    $level->getPlayers() as $p){
    $c++;
    if(
    $c == 1$player1 $p; else $player2 $p;
    }}

    I use a counter in foreach to check for the index.
    TxnneriOS likes this.
  3. SpopovabgS
    Offline

    SpopovabgS New Member

    Joined:
    Oct 4, 2015
    Posts:
    8
    Minecraft User:
    _SKDownBG_
    Thank you, but this doesn't seem to get the second player. I want to define them both at the same time

    Here is my code:
    (PS: This is on a task)

    PHP:
    if(count($levelPlayers) == 2) {    
      foreach(
    $levelPlayers as $p) {
        
    $c 0;
        
    $p1 null;
        
    $p2 null;

        
    $c++;
        if(
    $c == 1) {
          
    $p1 $p;
        } else {
          
    $p2 $p;
        }
        
    $name $p1->getName();
        
    $tname $p2->getName();
        
    #more code...
    Error: "getName() on null" in "$tname = $p2->getName()"

    Am i doing something wrong?
  4. EntirelyQuartz
    Offline

    EntirelyQuartz New Member

    Joined:
    Aug 9, 2016
    Posts:
    15
    Minecraft User:
    EntirelyQuartz
    I guess this function should work.

    PHP:
    public function getLastPlayers(Level $level) {
            if(
    count($level->getPlayers()) == 2) {
                
    $lastId null;
                
    $lastPlayers = [];
                foreach(
    $level->getLoaders() as $id => $player) {
                    if(empty(
    $lastId)) {
                        
    $lastPlayers["firstPlayer"] = $player;
                        
    $lastId $id;
                    }
                    else {
                        
    $lastPlayers["secondPlayer"] = $player;
                    }
                }
                return 
    $lastPlayers;
            }
            else {
                return 
    false;
            }
        }
    You can just check if it returns an array, if not, it means that there isn't 2 players online.

    TIP: Instead a task, you can just use EntityLevelChangeEvent.php
    Last edited: Aug 25, 2016
  5. Primus
    Offline

    Primus Notable Member

    Joined:
    Apr 7, 2015
    Posts:
    1,470
    Minecraft User:
    PrimusLV
    $p1 and $p2 might not be defined.

    try using one of these methods
    PHP:
    # 1
    # Before using this method, you have to initialize $p1 and $p2 with null value
    if($p1) {
       
    $name $p1->getName();
    }

    # 2
    if(isset($p1)) {
       
    # ...
    }

    # 3
    if($p1 instanceof Player) {
       
    # ...
    }
    I think that the $c isn't necessary as you can pull $index from foreach(...) statement
    PHP:
    foreach($players as $i => $player) {
       if(!
    $i) {
          
    $p1 $player;
       } else {
          
    $p2 $player;
       }
       if(isset(
    $p2)) break;
    }
  6. SpopovabgS
    Offline

    SpopovabgS New Member

    Joined:
    Oct 4, 2015
    Posts:
    8
    Minecraft User:
    _SKDownBG_
    Thank you, but this also doesn't seem to get the second player
    I keep getting an error for undefined index "p2" in "$tname = $lastPlayers["p2"]->getName();"

    Here is my code:
    PHP:
    public function getLastPlayers(Level $level) : array {
        if(
    count($level->getPlayers()) == 2) {
          
    $lastId null;
          
    $lastPlayers = [];
          foreach(
    $level->getLoaders() as $id => $player) {
            if(empty(
    $lastId)) {
              
    $lastPlayers["p1"] = $player;
              
    $lastId $id;
            } else {
              
    $lastPlayers["p2"] = $player;
            }
            
    $name $lastPlayers["p1"]->getName();
            
    $tname $lastPlayers["p2"]->getName();
            
    $lastPlayers["p1"]->sendMessage("DEBUG: " $name ", " $tname); //This is just to see if it returns the names
          
    }
          return 
    $lastPlayers;
        } else {
          return 
    false;
        }
      }
  7. Primus
    Offline

    Primus Notable Member

    Joined:
    Apr 7, 2015
    Posts:
    1,470
    Minecraft User:
    PrimusLV
    That function is really useless as it returns same values in different array. Also you have to learn how to use scalar type hints (return type declarations) because you declare the function to return an array and you can't return any other value than that!
    PHP:
    return false;
    Ritch likes this.
  8. Primus
    Offline

    Primus Notable Member

    Joined:
    Apr 7, 2015
    Posts:
    1,470
    Minecraft User:
    PrimusLV
    Are you sure there is enough players in the world, at least two? *Common sense
  9. SpopovabgS
    Offline

    SpopovabgS New Member

    Joined:
    Oct 4, 2015
    Posts:
    8
    Minecraft User:
    _SKDownBG_
    Yes. I tested with three too, same result
  10. Primus
    Offline

    Primus Notable Member

    Joined:
    Apr 7, 2015
    Posts:
    1,470
    Minecraft User:
    PrimusLV
    Please learn some basic debugging skills then!
  11. SOFe
    Offline

    SOFe Banned

    Joined:
    May 28, 2016
    Posts:
    386
    Minecraft User:
    Herobrine
    But why are you using getLoaders()?
  12. SOFe
    Offline

    SOFe Banned

    Joined:
    May 28, 2016
    Posts:
    386
    Minecraft User:
    Herobrine
    Why do you use "p1" and "p2" as keys? Why not simply 0 and 1, or just use the []= syntax to push values to the end of the array?
  13. Mat
    Offline

    Mat Active Member Plugin Developer

    Joined:
    Jun 15, 2014
    Posts:
    179
    Plugins:
    1
    Minecraft User:
    matcracker
    I don't under understand what you ask. If you have a level with 4 players called p1, p2, p3, p4, do you want p3 and p4 or what?
  14. SpopovabgS
    Offline

    SpopovabgS New Member

    Joined:
    Oct 4, 2015
    Posts:
    8
    Minecraft User:
    _SKDownBG_
    No, when the count of players in a certain world is two, i want to get each of the players' names
  15. SpopovabgS
    Offline

    SpopovabgS New Member

    Joined:
    Oct 4, 2015
    Posts:
    8
    Minecraft User:
    _SKDownBG_
    Why do i have to push the values to the end of the array?
    Also, this is just my way of naming things
  16. Primus
    Offline

    Primus Notable Member

    Joined:
    Apr 7, 2015
    Posts:
    1,470
    Minecraft User:
    PrimusLV
    [​IMG]
    I know that I'll be hated for this but PLEASE learn PHP :eek:

    PHP:
    /** @var Level $level */
    private $level;
    // Context of PluginTask

    public function onRun($currentTick) {
       if(
    count($this->level->getPlayers())) {
          foreach(
    $this->level->getPlayers() as $i => $player) {
             if(!
    $i$p1 $player;
             else { 
    $p2 $player; break; }
          }
       }

       echo 
    "{$p1->getName()}{$p2->getName()} \n";
    }
    Last edited: Aug 25, 2016
  17. SpopovabgS
    Offline

    SpopovabgS New Member

    Joined:
    Oct 4, 2015
    Posts:
    8
    Minecraft User:
    _SKDownBG_
    This forum is for helping people improve their knowlage, instead of telling me "learn php!!1!1!!!!", you can just help me with what i'm doing wrong
  18. Primus
    Offline

    Primus Notable Member

    Joined:
    Apr 7, 2015
    Posts:
    1,470
    Minecraft User:
    PrimusLV
    When the array is empty, the end of array is at beginning of it.
    PHP:
    $array = []; // Create empty array
    for($i 0$i <= 1$i++) $array[] = "I'm in index $i";
    var_dump($array);
    Code:
    array(5) {
         [0] => string(14) "I'm in index 0"
         [1] => string(14) "I'm in index 1"
    }
    
  19. SOFe
    Offline

    SOFe Banned

    Joined:
    May 28, 2016
    Posts:
    386
    Minecraft User:
    Herobrine
    This is not the problem of which way you like to name hings. The problem is that using integer keys is faster.
    Actually, you could simply use $p1 and $p2. Using $p1 and $array["p1"] has no difference - in both cases, you have to use isset() to check if it exists if you need to check, and they both throw an exception if they aren't defined. In PHP, you don't need to declare them at an upper scope.

    Actually, in the very beginning, we have already confirmed that $level->getPlayers() is an array with 2 Player objects right? The first method in the OP is almost right. The only problem is that the array isn't indexed by incremental integers, but by player entity IDs instead. You can use array_values() to convert the keys into incremental order. So you should instead do this:

    PHP:
    list($player1$player2) = array_values($level->getPlayers());
    See also: http://stackoverflow.com/a/3771228/3990767
    Last edited: Aug 25, 2016

Share This Page

Advertisement