1. The forums will be archived and moved to a read only mode in about 2 weeks (mid march).

The closest player and meters to him

Discussion in 'Development' started by SergeyIvanov, Dec 26, 2016.

  1. SergeyIvanov

    SergeyIvanov Witch

    Messages:
    59
    GitHub:
    sergeyivanov14
    I hold in hand id 355 and how to sendPopup with closest player and meters to him?

    NAME_OF_PLAYER | NUMBER_OF_METERS
     
  2. Thunder33345

    Thunder33345 Moderator Staff Member

    Messages:
    2,137
    GitHub:
    Thunder33345
    on holding item
    get all players and cycle thought which is closest

    example
    Code:
    $name = null;
    $range = null;
    players as player->level->getallplayers
    foreach players as player {
    $distance = currentplayer->vector->dis(player->vector)
    if $range is null or $distance is smaller then $range {
    $name = player's name
    $range = $distance
    }
    }
    echo "$name | $range"
    
    this technically should work, now just convert it back to good old PHP it shouldent be very hard
     
    Primus likes this.
  3. SergeyIvanov

    SergeyIvanov Witch

    Messages:
    59
    GitHub:
    sergeyivanov14
    Hard!!! Can you give me this code in PM API?
     
  4. Awzaw

    Awzaw Zombie Pigman Poggit Admin

    Messages:
    726
    GitHub:
    awzaw
    This forum is to help developers, not provide finished code! @Thunder33345 already gave you the outline... The next step is that you try to write the code and post again when you get stuck, preferably providing the full code to your plugin on github.
     
    imYannic and Primus like this.
  5. Thunder33345

    Thunder33345 Moderator Staff Member

    Messages:
    2,137
    GitHub:
    Thunder33345
    sorry but i am not spoonfeeding you code wise, but i am happy to tell you the idea about it enough for you to write your own code with your pre existing PMMP api and PHP knowledge
    but if you are really clueless, tell me which part you dont get
     
    Sandertv, Primus and Awzaw like this.
  6. Diduhless

    Diduhless Baby Zombie

    Messages:
    199
    GitHub:
    Diduhless
    Not tested ;) Hope it works
    PHP:
    /** Item held */
    const ITEM_HELD "355";

    /** Number of metters */
    const NUMBER_OF_METTERS 8;

    /**
    * @param PlayerItemHeldEvent $event
    */
    public function onHold(PlayerItemHeldEvent $event) {
        
    $player $event->getPlayer();
        if(
    $event->getItem()->getId() == self::ITEM_HELD) {
            
    $playerPosition = new Vector3($player->getX(), $player->getY(), $player->getZ());
            foreach(
    $this->getServer()->getOnlinePlayers() as $play) {
                
    $playPosition = new Vector3($play->getX(), $play->getY(), $play->getZ());
                if(
    $playerPosition->distance($playPosition) <= self::NUMBER_OF_METTERS) {
                    
    $distance intval($playerPosition->distance($playPosition));
                    
    $player->sendMessage("Closest target: {$play->getName()} -- Metters: {$distance}");
                }
            }
        }
    }
     
  7. Thunder33345

    Thunder33345 Moderator Staff Member

    Messages:
    2,137
    GitHub:
    Thunder33345
    i deem this redundant there is a way to obtain player's in from of position class

    What if the server had 2 worlds?

    as for this one, what if there's more then 2 player in range?

    final issue: so do i have to keep swapping my hold item to see who is near me?
     
    Muqsit and Diduhless like this.
  8. Diduhless

    Diduhless Baby Zombie

    Messages:
    199
    GitHub:
    Diduhless
    Fixed
    Fixed

    Final code
    PHP:
    <?php

    namespace Mod;

    use 
    pocketmine\event\Listener;
    use 
    pocketmine\event\player\PlayerItemHeldEvent;
    use 
    pocketmine\math\Vector3;
    use 
    pocketmine\plugin\PluginBase;

    class 
    Base extends PluginBase implements Listener {

        
    /** @var string */
        
    private $arena "world";

        
    /** @var array */
        
    private $array = array();

        
    /** Item held */
        
    const ITEM_HELD "355";

        
    /** Number of metters */
        
    const NUMBER_OF_METTERS 7;

        
    /**
         * Enable the plugin
         */
        
    public function onEnable() {
            
    $this->loadArena();
            
    $this->getServer()->getPluginManager()->registerEvents($this$this);
        }

        
    /**
         * Load the arena
         */
        
    public function loadArena() {
            if(!
    $this->getServer()->isLevelLoaded($this->arena)) {
                
    $this->getServer()->loadLevel($this->arena);
            }
        }

        
    /**
         * @param PlayerItemHeldEvent $event
         */
        
    public function onHold(PlayerItemHeldEvent $event) {
            
    $player $event->getPlayer();
            if(
    in_array($player$this->array)) {
                unset(
    $this->array[array_search($player$this->array)]);
            }
            if(
    $event->getItem()->getId() == self::ITEM_HELD) {
                
    $playerPosition = new Vector3($player->getX(), $player->getY(), $player->getZ());
                foreach(
    $this->getServer()->getLevelByName($this->arena)->getPlayers() as $play) {
                    
    $playPosition = new Vector3($play->getX(), $play->getY(), $play->getZ());
                    if(
    $playerPosition->distance($playPosition) <= self::NUMBER_OF_METTERS) {
                        if(
    $play 1) {
                            
    array_push($this->array$play);
                            
    $closest $this->array[array_rand($this->array)];
                        } else {
                            
    $closest $play;
                        }
                        
    $closestPosition = new Vector3($closest->getX(), $closest->getY(), $closest->getZ());
                        
    $distance intval($playerPosition->distance($closestPosition));
                        
    $player->sendMessage("Closest target: {$play->getName()} -- Metters: {$distance}");
                    }
                }
            }
        }

    }
    Change $arena = "world" to your world name.
     
  9. Aviv

    Aviv Baby Zombie

    Messages:
    156
    maybe?
    PHP:
    public function onHold(PlayerItemHeldEvent $event) {
      
    $player $event->getPlayer();
      foreach(
    $this->getServer()->getOnlinePlayers() as $pl){
        if(
    $pl->getName() !== $player->getName() && $pl->getLevel()->getName() === $player->getLevel()->getName()){
           
    array_push($distance$player->distance($pl));
           
    array_push($players$pl);
        }
      }
      
    $distance min($distance);
      foreach(
    $players as $pl){
        if(
    $distance === $pl->distance($player)){
          
    $player->sendPopup($pl->getName()." (".floor($distance)."m)");
        }
      }
    }
     
  10. Awzaw

    Awzaw Zombie Pigman Poggit Admin

    Messages:
    726
    GitHub:
    awzaw
    This is very wrong in many ways - it's best not to answer with code unless you know what you are doing, or at least ask people what's wrong with your code instead of suggesting it as a solution.
     
    Last edited: Dec 30, 2016
  11. Sandertv

    Sandertv Zombie Pigman Poggit Reviewer

    Messages:
    786
    GitHub:
    Sandertv
    You could easily do this by making an array, getting every player of the world, foreaching it and putting the distance in the array. Then sort the array and get the first value. There you go.
     
    Last edited: Dec 30, 2016
  12. Awzaw

    Awzaw Zombie Pigman Poggit Admin

    Messages:
    726
    GitHub:
    awzaw
    This is not 'final code" by any stretch of the imagination!

    Not sure where to start, but the most obvious mistake is that $play is a Player object so $play > 1 will fail miserably... and what is '$closest = $this->array[array_rand($this->array)];' supposed to do?

    You also put your sendMessage within the foreach loop, so once you sort out all the other issues you'd get a list of all players within the range, not the closest. Did you actually try running this?!
     
    Last edited: Dec 30, 2016
    HimbeersaftLP, Primus and Sandertv like this.
  13. Aviv

    Aviv Baby Zombie

    Messages:
    156
    can you at least tell me what wrong with the code?
    instead of saying im wrong you should tell me why...
    (i know i didnt specify the check to item)
     
  14. Thunder33345

    Thunder33345 Moderator Staff Member

    Messages:
    2,137
    GitHub:
    Thunder33345
    FYI this should be run on a task triggered when player holds that item, un-triggered once the item is unheld
     
  15. Awzaw

    Awzaw Zombie Pigman Poggit Admin

    Messages:
    726
    GitHub:
    awzaw
    I admit it's not as bad as I thought on first glance, but most importantly you are doing 2 foreach loops when one should be enough and you are doing those loops through all players in your level on every single PlayerItemHeldEvent, regardless of the item held. Also it is good practice to define default values since PHP will type cast variables depending on how you use them, and although this is how PHP works... it's not a good habit to get into when you are learning to code, especially things like '$distance = min($distance);' when $distance starts life as an array.
     
  16. Muqsit

    Muqsit Chicken

    Messages:
    1,548
    GitHub:
    muqsit
    It's better to foreach loop $player->getViewers() than $player->getLevel()->getPlayers() (performance-wise).
    Yeah, drawbacks intended.
     
  17. Aviv

    Aviv Baby Zombie

    Messages:
    156
    Thanks! lesson learnt;)
     
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.