I hold in hand id 355 and how to sendPopup with closest player and meters to him? NAME_OF_PLAYER | NUMBER_OF_METERS
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
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.
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
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}"); } } }}
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?
Fixed Fixed Final code PHP: <?phpnamespace 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.
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)"); } }}
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.
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.
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?!
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)
FYI this should be run on a task triggered when player holds that item, un-triggered once the item is unheld
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.
It's better to foreach loop $player->getViewers() than $player->getLevel()->getPlayers() (performance-wise). Yeah, drawbacks intended.