Hello guys Does someone can help me? I just want to learn if its possible to do like per world plugin by doing checking player in a certain world then run the event in that world.. I just want to run EntityDamageEvent/PlayerDeathEvent only in 1 world for custom messages.. i already did custom messages but i want to work that plugin just in 1 world plss help me :<
Events are not fired in channels, they are broadcasted to anyone that listens. But most events (depending on which) hold some kind of reference to levels. So for example PlayerDeathEvent has Player object assigned, and player knows which level he is in. So if player died in LevelA then you broadcast the custom message to anyone who is in that particular level PHP: public function onDeath(PlayerDeathEvent $e) { $player = $event->getPlayer(); $level = $player->getLevel(); foreach($level->getPlayers() as $p) { // Broadcast your message here } // Server::broadcastMessage($message, $level->getPlayers()) // Works aswell // I can't recall how to disable the default death message, but someone will hint that.} You can not fire event in specific level, you can control how event is handled depending on which level it was fired in!
I forgot sorry my bad... sorry im still learning.. actually its a death spectate too with cancelling PlayerDeathEvent.. im so happy that i did it! Also i want that death spectate run only in particular world.. pls can you help me to stop losing my hair? xD i will credit you Mr if i make this properly.. thank you Mr! <3
Yep, Primus is always there first :[ Checking for the level(aka world) when a certain event is executed can make it work at only that specific level. This works with basically every event that PocketMine-MP has. Here's another example using BlockUpdateEvent. PHP: // This function will stop flowing liquid in "world" levelpublic function onBlockUpdate(BlockUpdateEvent $event){ $block = $event->getBlock(); $level = $block->getLevel()->getFolderName(); if ($level === "world") { if ($block->getName() === "Lava" || $block->getName() === "Water"){ $event->setCancelled(); } } } You can also have a check for the world that the player is in when the player is executing a command! The following is a part of my plugin I've made several days ago. PHP: public function execute(CommandSender $sender, array $args): bool { if(!isset($args[0])){ $sender->sendMessage($this->prefix . $this->getUsage()); return false; } if ($sender->getLevel()->getFolderName() === 'pvp') { // Checking for world $sender->sendMessage("§cYou cannot set home in PvP!"); return false; } Hope this can help with your question! Cheers!
Default death message can be edited with PHP: $event->setDeathMessage("BRUH THIS ".$event->getPlayer()->getName()." DIED");
Check for the player's world, like in Primus' example! PHP: $player->getLevel()->getName()// OR$player->getLevel()->getFolderName() // Recommended
Actually its not actually onDeath its like get the last hit or finalDamage clear inv, set back hp to 20 and tp to worldspawn heres the code.. idk if im right because its from someones help public function onDamage(EntityDamageEvent $event){ $player = $event->getEntity(); if($player instanceof Player and $player->getHealth() - $event->getBaseDamage() <= 0) { $player->sendTitle("§l§cYOU DIED"); $player->setHealth(20); $player->setFood(20); $player->getInventory()->clearAll(); $player->getArmorInventory()->clearAll(); $player->getCursorInventory()->clearAll(); $player->removeAllEffects(); $player->setGamemode(3); $this->getScheduler()->scheduleRepeatingTask(new Respawn($this, $player->getName()), 20); $event->setCancelled();
Your code will execute every time when the player is hit. There's PlayerDeathEvent So I recommend using that instead. However, it isn't cancellable so I'm not sure to be honest. I've seen something with getFinalDamage() in EntityDamageByEntity event but I'm not entirely sure how to do that. I'll see what I can find online.
A little update on the situation, I've actually come up with a solution you could use. PHP: public function onDamage(EntityDamageEvent $event) { $victim = $event->getEntity(); if($event->getFinalDamage() >= $victim->getHealth()) { $event->setCancelled(); // Player cannot die $victim->setHealth($victim->getMaxHealth); // Fully heals $player->setFood(20); $player->getInventory()->clearAll(); $player->getArmorInventory()->clearAll(); $player->getCursorInventory()->clearAll(); $player->removeAllEffects(); $player->setGamemode(3); $this->getScheduler()->scheduleRepeatingTask(new Respawn($this, $player->getName()), 20); }} Try using this instead! If you want to have this working in only a specific world, try this code! PHP: public function onDamage(EntityDamageEvent $event) { $victim = $event->getEntity(); if($event->getFinalDamage() >= $victim->getHealth()) { if($victim->getLevel()->getFolderName() === "world") { $event->setCancelled(); // Player cannot die $victim->setHealth($victim->getMaxHealth); // Fully heals $player->setFood(20); $player->getInventory()->clearAll(); $player->getArmorInventory()->clearAll(); $player->getCursorInventory()->clearAll(); $player->removeAllEffects(); $player->setGamemode(3); $this->getScheduler()->scheduleRepeatingTask(new Respawn($this, $player->getName()), 20); } }}
Thats actually a common solution to "faking death" to avoid the death screen. There is however one flaw with it, what if any other plugin would have manipulated victims health after your listener, resulting in player not dying? Or what if it does, resulting having not full health? You should be the last one that gets notified about the event to avoid this problem, you can do that by using php docs and set priority to highest. If the naming of priority confuses you, don't worry just remember it's kinda reversed, but does make somewhat of a sense programmatically PHP: /** * @priority HIGHEST */function someMethod(Event $e) {}