InfinityGamers / HungerGames-UPDATED

A HungerGames plugin for PocketMine-MP developed by xBeastMode
45 stars 24 forks source link

Teleported to Lobby Just Before Death #49

Closed Haxley closed 7 years ago

Haxley commented 7 years ago

HG tournament players seem to be teleported to the lobby just before they are killed, dying in the lobby, dropping their items in the lobby, which can then be picked up by others.

Haxley commented 7 years ago

Ok I think I have a fix for teleporting to the lobby and dropping all your items at the lobby right before you die. I made a new function in GameManager.php called removePlayerWithoutTeleport() that is the exact same thing as removePlayer() except it doesn't teleport. I implemented this function into the EventListener.php playerDeathEvent() function, replacing the old removePlayer() function with the new removePlayerWithoutTeleport().

Below is a copy of both the original removePlayer() function and my added removePlayerWithoutTeleport() function:

  /**
     * Removes player from game
     *
     * @param Player $p
     * @param bool $message
     */
    public function removePlayer(Player $p, $message = false){
        $this->HGApi->getStorage()->removePlayer($p);
        $p->teleport($this->getGame()->getLobbyPosition());
        foreach($this->HGApi->getScriptManager()->getScripts() as $script){
            if(!$script->isEnabled()) continue;
            $script->onPlayerQuitGame($p, $this->getGame());
        }
        if($message){
            $this->sendGameMessage(Msg::color(str_replace(["%player%", "%game%"], [$p->getName(), $this->getGame()->getName()], Msg::getHGMessage("hg.message.quit"))));
        }
    }

    /**
     * Removes player from game without teleporting them
     *
     * @param Player $p
     * @param bool $message
     */
    public function removePlayerWithoutTeleport(Player $p, $message = false){
        $this->HGApi->getStorage()->removePlayer($p);
        foreach($this->HGApi->getScriptManager()->getScripts() as $script){
            if(!$script->isEnabled()) continue;
            $script->onPlayerQuitGame($p, $this->getGame());
        }
        if($message){
            $this->sendGameMessage(Msg::color(str_replace(["%player%", "%game%"], [$p->getName(), $this->getGame()->getName()], Msg::getHGMessage("hg.message.quit"))));
        }
    }

Once you've added the new removePlayerWithoutTeleport() function to the GameManager.php file, change the playerDeathEvent() function in the EventListener.php file to include removePlayerWithoutTeleport() in place of removePlayer(): Old:

public function playerDeathEvent(PlayerDeathEvent $e){
        $p = $e->getEntity();
        if($this->HGApi->getStorage()->isPlayerSet($p)){
            $game = $this->HGApi->getStorage()->getPlayerGame($p);
            if($game !== null){
                $this->HGApi->getGlobalManager()->getGameManager($game)->removePlayer($p);
            }
            $count = $this->HGApi->getStorage()->getPlayersInGameCount($game);
            if($count > 1){
                $msg = Msg::getHGMessage("hg.message.death");
                $msg = str_replace(["%player%", "%game%", "%left%"], [$p->getName(), $game->getName(), $count], $msg);
                $this->HGApi->getGlobalManager()->getGameManager($game)->sendGameMessage(Msg::color($msg));
            }
        }
    }

New:

public function playerDeathEvent(PlayerDeathEvent $e){
        $p = $e->getEntity();
        if($this->HGApi->getStorage()->isPlayerSet($p)){
            $game = $this->HGApi->getStorage()->getPlayerGame($p);
            if($game !== null){
                $this->HGApi->getGlobalManager()->getGameManager($game)->removePlayerWithoutTeleport($p);
            }
            $count = $this->HGApi->getStorage()->getPlayersInGameCount($game);
            if($count > 1){
                $msg = Msg::getHGMessage("hg.message.death");
                $msg = str_replace(["%player%", "%game%", "%left%"], [$p->getName(), $game->getName(), $count], $msg);
                $this->HGApi->getGlobalManager()->getGameManager($game)->sendGameMessage(Msg::color($msg));
            }
        }
    }

In my testing, this will solve the problem of players teleporting to the lobby right before they die causing them to drop their items in the lobby. It also adds the benefit of dead players dropping their items in the arena, rather than the lobby, so their killer(s) can loot them during a match. There is one catch; you can death glitch. Since the player is never teleported, if they tap "main menu" after dying, then log back in, they will spawn where they died. I think you should be able to prevent this using the AlwaysSpawn plugin, which should force players to the set /spawnpoint when they login. https://poggit.pmmp.io/p/AlwaysSpawn/2.2 Let me know if you think this is a good solution to preventing tournament players from dropping their items at the lobby upon death.

xBeastMode commented 7 years ago

I think it's a good idea. You can make a pull request and I think you should also add it for PlayerQuitEvent because it might be the reason that is freezes when a players quits. Thanks :D

Haxley commented 7 years ago

It doesn't appear that I have permission to make pull requests, it keeps saying "Authentication Failed: You may not have permission to access HungerGames-UPDATED. Check Preferences to make sure you’re still logged in." Maybe I'm doing it wrong.

Regarding adding removePlayerWithoutTeleport() to playerQuitEvent(), it doesn't seem to do anything differently than removePlayer() in my testing. But also in my testing, the game isn't freezing when a player quits the match. Can you elaborate on this?

xBeastMode commented 7 years ago

I believe it was when the match is ticking while waiting to start. If you quit it freezes, might be related to the removePlayer() method.

Haxley commented 7 years ago

Ah, I'll test that later tonight. Any word I why I can't submit pull requests?

xBeastMode commented 7 years ago

Did you commit to the master branch?

Haxley commented 7 years ago
screen shot 2017-04-24 at 11 13 15 am
xBeastMode commented 7 years ago

Hmm, I don't know. I think it's something on your side.

Haxley commented 7 years ago

xBeastMode said, "I believe it was when the match is ticking while waiting to start. If you quit it freezes..."

I still can't seem to reproduce this.