Browse Source

Merge pull request #39 from RedstoneFuture/EventListenerReworkV3.3

Reworking EventListener v.3c
Daniel 2 years ago
parent
commit
c516d4ee7b

+ 1 - 1
missilewars-plugin/src/main/java/de/butzlabben/missilewars/MissileWars.java

@@ -108,7 +108,7 @@ public class MissileWars extends JavaPlugin {
         GameManager.getInstance().getGames().values().forEach(game -> {
             for (Player player : Bukkit.getOnlinePlayers()) {
                 if (!game.isIn(player.getLocation())) continue;
-                game.addPlayer(player);
+                game.teleportToLobbySpawn(player);
             }
         });
 

+ 201 - 41
missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/Game.java

@@ -27,11 +27,13 @@ import de.butzlabben.missilewars.game.timer.EndTimer;
 import de.butzlabben.missilewars.game.timer.GameTimer;
 import de.butzlabben.missilewars.game.timer.LobbyTimer;
 import de.butzlabben.missilewars.game.timer.Timer;
+import de.butzlabben.missilewars.inventory.OrcItem;
 import de.butzlabben.missilewars.listener.EndListener;
 import de.butzlabben.missilewars.listener.GameBoundListener;
 import de.butzlabben.missilewars.listener.GameListener;
 import de.butzlabben.missilewars.listener.LobbyListener;
 import de.butzlabben.missilewars.util.MotdManager;
+import de.butzlabben.missilewars.util.PlayerDataProvider;
 import de.butzlabben.missilewars.util.ScoreboardManager;
 import de.butzlabben.missilewars.util.serialization.Serializer;
 import de.butzlabben.missilewars.util.version.VersionUtil;
@@ -41,13 +43,13 @@ import de.butzlabben.missilewars.wrapper.abstracts.Lobby;
 import de.butzlabben.missilewars.wrapper.abstracts.MapChooseProcedure;
 import de.butzlabben.missilewars.wrapper.event.GameStartEvent;
 import de.butzlabben.missilewars.wrapper.event.GameStopEvent;
-import de.butzlabben.missilewars.wrapper.event.PlayerArenaJoinEvent;
 import de.butzlabben.missilewars.wrapper.game.MissileGameEquipment;
 import de.butzlabben.missilewars.wrapper.game.SpecialGameEquipment;
 import de.butzlabben.missilewars.wrapper.game.Team;
 import de.butzlabben.missilewars.wrapper.missile.Missile;
 import de.butzlabben.missilewars.wrapper.missile.MissileFacing;
 import de.butzlabben.missilewars.wrapper.player.MWPlayer;
+import de.butzlabben.missilewars.wrapper.signs.MWSign;
 import de.butzlabben.missilewars.wrapper.stats.FightStats;
 import java.util.HashMap;
 import java.util.List;
@@ -65,10 +67,12 @@ import org.bukkit.enchantments.Enchantment;
 import org.bukkit.entity.Fireball;
 import org.bukkit.entity.Player;
 import org.bukkit.event.HandlerList;
+import org.bukkit.event.player.PlayerTeleportEvent;
 import org.bukkit.inventory.ItemStack;
 import org.bukkit.inventory.meta.ItemMeta;
 import org.bukkit.scheduler.BukkitTask;
 import org.bukkit.scoreboard.Scoreboard;
+import org.bukkit.util.Vector;
 
 /**
  * @author Butzlabben
@@ -131,23 +135,14 @@ public class Game {
 
         gameWorld = new GameWorld(this, "");
 
-        players.clear();
-
         team1 = new Team(lobby.getTeam1Name(), lobby.getTeam1Color(), this);
         team2 = new Team(lobby.getTeam2Name(), lobby.getTeam2Color(), this);
-      
+
         team1.createTeamArmor();
         team2.createTeamArmor();
 
         Logger.DEBUG.log("Registering, teleporting, etc. all players");
 
-        for (Player all : Bukkit.getOnlinePlayers()) {
-            if (!isIn(all.getLocation()))
-                continue;
-            Bukkit.getScheduler().runTaskLater(MissileWars.getInstance(),
-                    () -> Bukkit.getPluginManager().callEvent(new PlayerArenaJoinEvent(all, this)), 2);
-        }
-
         // Change MOTD
         if (!Config.isMultipleLobbies()) MotdManager.getInstance().updateMOTD(this);
 
@@ -159,6 +154,8 @@ public class Game {
         bt = Bukkit.getScheduler().runTaskTimer(MissileWars.getInstance(), timer, 0, 20);
         state = GameState.LOBBY;
 
+        Bukkit.getScheduler().runTaskLater(MissileWars.getInstance(), () -> applyForAllPlayers(this::runTeleportEventForPlayer), 2);
+
         if (Config.isSetup()) {
             Logger.WARN.log("Did not fully initialize lobby " + lobby.getName() + " as the plugin is in setup mode");
             return;
@@ -197,11 +194,11 @@ public class Game {
         createGameItems();
     }
 
-    private void updateGameListener(GameBoundListener listener) {
+    private void updateGameListener(GameBoundListener newListener) {
         if (listener != null) HandlerList.unregisterAll(listener);
 
-        Bukkit.getPluginManager().registerEvents(listener, MissileWars.getInstance());
-        this.listener = listener;
+        Bukkit.getPluginManager().registerEvents(newListener, MissileWars.getInstance());
+        this.listener = newListener;
     }
 
     public Scoreboard getScoreboard() {
@@ -244,8 +241,7 @@ public class Game {
     }
 
     public void stopGame() {
-        if (Config.isSetup())
-            return;
+        if (Config.isSetup()) return;
 
         Logger.DEBUG.log("Stopping");
 
@@ -258,8 +254,7 @@ public class Game {
 
             Logger.DEBUG.log("Stopping for: " + player.getName());
             player.setGameMode(GameMode.SPECTATOR);
-            player.teleport(arena.getSpectatorSpawn());
-            player.setHealth(player.getMaxHealth());
+            teleportToArenaSpectatorSpawn(player);
 
         }
 
@@ -300,31 +295,140 @@ public class Game {
     }
 
     public void disableGameOnServerStop() {
-        sendPlayerToFallbackSpawn();
+
+        for (MWPlayer player : players.values()) {
+            playerLeaveFromGame(player);
+        }
+
         gameWorld.unload();
     }
 
-    private void sendPlayerToFallbackSpawn() {
+    /**
+     * This method adds the player to the game.
+     *
+     * @param player the target Player
+     * @param isSpectatorJoin should the player join as spectator or as normal player
+     */
+    public void playerJoinInGame(Player player, boolean isSpectatorJoin) {
 
-        for (Player player : Bukkit.getOnlinePlayers()) {
-            if (!isIn(player.getLocation())) continue;
+        PlayerDataProvider.getInstance().storeInventory(player);
+        MWPlayer mwPlayer = addPlayer(player);
 
-            player.teleport(Config.getFallbackSpawn());
+        if (state == GameState.LOBBY) {
+            assert !isSpectatorJoin : "wrong syntax";
 
+            teleportToLobbySpawn(player);
+            player.setGameMode(GameMode.ADVENTURE);
+        }
+
+        if (isSpectatorJoin) {
+            Bukkit.getScheduler().runTaskLater(MissileWars.getInstance(), () -> teleportToArenaSpectatorSpawn(player), 2);
+            Bukkit.getScheduler().runTaskLater(MissileWars.getInstance(), () -> player.setGameMode(GameMode.SPECTATOR), 35);
+
+            player.sendMessage(MessageConfig.getMessage("spectator"));
+            player.setDisplayName("§7" + player.getName() + "§r");
+
+        } else {
             player.getInventory().clear();
             player.setFoodLevel(20);
             player.setHealth(player.getMaxHealth());
+
+            Team team = getNextTeam();
+            team.addMember(mwPlayer);
+            player.sendMessage(MessageConfig.getMessage("team_assigned").replace("%team%", team.getFullname()));
+
+            broadcast(MessageConfig.getMessage("lobby_joined")
+                    .replace("%max_players%", Integer.toString(getLobby().getMaxSize()))
+                    .replace("%players%", Integer.toString(getPlayers().values().size()))
+                    .replace("%player%", player.getName()));
+        }
+
+        player.setScoreboard(getScoreboard());
+
+        if (state == GameState.LOBBY) {
+
+            // team change menu:
+            if (player.hasPermission("mw.change")) {
+                player.getInventory().setItem(0, VersionUtil.getGlassPlane(team1));
+                player.getInventory().setItem(8, VersionUtil.getGlassPlane(team2));
+            }
+
+            // map choose menu:
+            if (lobby.getMapChooseProcedure() == MapChooseProcedure.MAPVOTING && arena == null) {
+                player.getInventory().setItem(4, new OrcItem(Material.NETHER_STAR, "§3Vote Map").getItemStack());
+            }
+
+        } else if ((state == GameState.INGAME) && (!isSpectatorJoin)) {
+            startForPlayer(player);
+        }
+    }
+
+    /**
+     * This method handles the removal of the player from the game.
+     *
+     * @param mwPlayer the target missilewars player
+     */
+    public void playerLeaveFromGame(MWPlayer mwPlayer) {
+        Player player = mwPlayer.getPlayer();
+        Team team = mwPlayer.getTeam();
+
+        if (state == GameState.INGAME) {
+            BukkitTask task = getPlayerTasks().get(mwPlayer.getUuid());
+            if (task != null) task.cancel();
+
+            if (team != null) {
+                broadcast(MessageConfig.getMessage("player_left")
+                        .replace("%team%", team.getFullname())
+                        .replace("%player%", player.getName()));
+            }
+        }
+
+        PlayerDataProvider.getInstance().loadInventory(player);
+
+        if (team != null) {
+            team.removeMember(mwPlayer);
+            if (state == GameState.INGAME) checkTeamSize(team);
+        }
+
+        player.setScoreboard(Bukkit.getScoreboardManager().getMainScoreboard());
+        removePlayer(mwPlayer);
+    }
+
+    /**
+     * This method executes the PlayerTeleportEvent to run the basic game join process
+     * after the game is restarted.
+     *
+     * @param player target player
+     */
+    private void runTeleportEventForPlayer(Player player) {
+        Bukkit.getPluginManager().callEvent(new PlayerTeleportEvent(player,
+                Config.getFallbackSpawn(), getLobby().getSpawnPoint()));
+    }
+
+    private void checkTeamSize(Team team) {
+        int teamSize = team.getMembers().size();
+        if (teamSize == 0) {
+            Bukkit.getScheduler().runTask(MissileWars.getInstance(), () -> {
+                team.getEnemyTeam().setGameResult(GameResult.WIN);
+                team.setGameResult(GameResult.LOSE);
+                sendGameResult();
+                stopGame();
+            });
+            broadcast(MessageConfig.getMessage("team_offline").replace("%team%", team.getFullname()));
         }
     }
 
     public void resetGame() {
-        if (state == GameState.INGAME) stopGame();
+        if (state == GameState.INGAME) {
+            stopGame();
+            return;
+        }
 
         HandlerList.unregisterAll(listener);
 
         stopTimer();
 
-        applyForAllPlayers(player -> player.teleport(lobby.getAfterGameSpawn()));
+        applyForAllPlayers(this::teleportToAfterGameSpawn);
 
         if (gameWorld != null) {
             gameWorld.sendPlayersBack();
@@ -367,10 +471,25 @@ public class Game {
         return isInLobbyArea(location) || isInGameWorld(location);
     }
 
+    private MWPlayer addPlayer(Player player) {
+        if (players.containsKey(player.getUniqueId())) return players.get(player.getUniqueId());
+        MWPlayer mwPlayer = new MWPlayer(player, this);
+        players.put(player.getUniqueId(), mwPlayer);
+        return mwPlayer;
+    }
+
     public MWPlayer getPlayer(Player player) {
         return players.get(player.getUniqueId());
     }
 
+    /**
+     * This method finally removes the player from the game player array. Besides former
+     * team members, it also affects spectators.
+     */
+    private void removePlayer(MWPlayer mwPlayer) {
+        players.remove(mwPlayer.getUuid());
+    }
+
     public void broadcast(String message) {
         for (MWPlayer player : players.values()) {
             Player p = player.getPlayer();
@@ -392,7 +511,6 @@ public class Game {
 
         playerTasks.put(player.getUniqueId(),
                 Bukkit.getScheduler().runTaskTimer(MissileWars.getInstance(), mwPlayer, 40, 20));
-
     }
 
     /**
@@ -488,7 +606,7 @@ public class Game {
      *
      * @param player the target player
      */
-    public static void autoRespawnPlayer(Player player) {
+    public void autoRespawnPlayer(Player player) {
         Bukkit.getScheduler().runTaskLater(MissileWars.getInstance(), () -> player.spigot().respawn(), 20L);
     }
 
@@ -569,7 +687,7 @@ public class Game {
         if (lobby.getMapChooseProcedure() == MapChooseProcedure.MAPVOTING) {
             this.broadcast(MessageConfig.getMessage("vote.finished").replace("%map%", this.arena.getDisplayName()));
         }
-        applyForAllPlayers(p -> p.getInventory().setItem(4, new ItemStack(Material.AIR)));
+        applyForAllPlayers(player -> player.getInventory().setItem(4, new ItemStack(Material.AIR)));
 
         ready = true;
     }
@@ -581,13 +699,6 @@ public class Game {
         }
     }
 
-    public MWPlayer addPlayer(Player player) {
-        if (players.containsKey(player.getUniqueId())) return players.get(player.getUniqueId());
-        MWPlayer mwPlayer = new MWPlayer(player, this);
-        players.put(player.getUniqueId(), mwPlayer);
-        return mwPlayer;
-    }
-
     /**
      * This method manages the message output of the game result.
      * Each player who is currently in the arena world gets a
@@ -622,7 +733,6 @@ public class Game {
         }
     }
 
-
     /**
      * This method sends the players the title / subtitle of the
      * game result there are not in a team (= spectator).
@@ -648,13 +758,63 @@ public class Game {
         VersionUtil.sendTitle(player, title, subTitle);
     }
 
+    /**
+     * This method updates the MissileWars signs and the scoreboard.
+     */
+    public void updateGameInfo() {
+        MissileWars.getInstance().getSignRepository().getSigns(this).forEach(MWSign::update);
+        getScoreboardManager().resetScoreboard();
+        Logger.DEBUG.log("Updated signs and scoreboard.");
+    }
 
     /**
-     * This method removes players from the game. Besides former
-     * team members, it also affects spectators.
+     * This method returns the next matching team for the next player to
+     * join. It is always the smaller team.
+     *
+     * @return (Team) the matched team to join
      */
-    public void removePlayer(MWPlayer mwPlayer) {
-        if (mwPlayer.getTeam() != null) mwPlayer.getTeam().removeMember(mwPlayer);
-        players.remove(mwPlayer);
+    public Team getNextTeam() {
+        if (team1.getMembers().size() > team2.getMembers().size()) {
+            return team2;
+        } else {
+            return team1;
+        }
+    }
+
+    public boolean isPlayersMax() {
+        int maxSize = getLobby().getMaxSize();
+        int currentSize = team1.getMembers().size() + team2.getMembers().size();
+        return currentSize >= maxSize;
+    }
+
+    public boolean isSpectatorsMax() {
+        int maxSize = getArena().getMaxSpectators();
+
+        if (maxSize == -1) return false;
+
+        int currentSize = players.size();
+        return currentSize >= maxSize;
+    }
+
+    public static void knockbackEffect(Player player, Location from, Location to) {
+        Vector addTo = from.toVector().subtract(to.toVector()).multiply(3);
+        addTo.setY(0);
+        player.teleport(from.add(addTo));
+    }
+
+    public void teleportToFallbackSpawn(Player player) {
+        player.teleport(Config.getFallbackSpawn());
+    }
+
+    public void teleportToLobbySpawn(Player player) {
+        player.teleport(getLobby().getSpawnPoint());
+    }
+
+    public void teleportToArenaSpectatorSpawn(Player player) {
+        player.teleport(getArena().getSpectatorSpawn());
+    }
+
+    public void teleportToAfterGameSpawn(Player player) {
+        player.teleport(getLobby().getAfterGameSpawn());
     }
 }

+ 14 - 10
missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/GameManager.java

@@ -18,7 +18,6 @@
 
 package de.butzlabben.missilewars.game;
 
-import com.google.common.base.Preconditions;
 import de.butzlabben.missilewars.Config;
 import de.butzlabben.missilewars.Logger;
 import de.butzlabben.missilewars.MissileWars;
@@ -105,24 +104,25 @@ public class GameManager {
         }
     }
 
-    public void disableGame(String name) {
-        Preconditions.checkNotNull(name);
-        Game game = getGame(name);
-        if (game == null)
-            return;
+    public void disableGame(String lobbyName) {
+        Game game = getGame(lobbyName);
+        if (game == null) return;
+
         game.resetGame();
-        games.remove(name);
+        games.remove(lobbyName);
+
+        Logger.DEBUG.log("Old Game disabled.");
     }
 
     public void restartGame(Lobby oldLobby) {
-        String name = oldLobby.getName();
-        disableGame(name);
+        String oldLobbyName = oldLobby.getName();
+        disableGame(oldLobbyName);
         try {
             Lobby lobby = Serializer.deserialize(oldLobby.getFile(), Lobby.class);
             lobby.setFile(oldLobby.getFile());
             // Save for possible new values
             Serializer.serialize(oldLobby.getFile(), lobby);
-            games.put(name, new Game(lobby));
+            games.put(oldLobbyName, new Game(lobby));
         } catch (IOException exception) {
             Logger.ERROR.log("Could not load lobby " + oldLobby.getName());
             exception.printStackTrace();
@@ -133,6 +133,10 @@ public class GameManager {
         return games.get(name);
     }
 
+    public int getGameAmount() {
+        return games.size();
+    }
+
     public Game getGame(Location location) {
         for (Game game : GameManager.getInstance().getGames().values()) {
             if (game.isIn(location)) {

+ 3 - 10
missilewars-plugin/src/main/java/de/butzlabben/missilewars/wrapper/game/Team.java

@@ -30,7 +30,6 @@ import lombok.Getter;
 import lombok.RequiredArgsConstructor;
 import lombok.Setter;
 import lombok.ToString;
-import org.bukkit.Bukkit;
 import org.bukkit.Color;
 import org.bukkit.Location;
 import org.bukkit.Material;
@@ -68,7 +67,7 @@ public class Team {
             return game.getTeam2();
         return game.getTeam1();
     }
-    
+
     public void removeMember(MWPlayer player) {
         if (!isMember(player)) return;
 
@@ -80,11 +79,8 @@ public class Team {
         }
 
         members.removeIf(mp -> mp.getUuid().equals(player.getUuid()));
-
-        game.getScoreboardManager().resetScoreboard();
-        p.setScoreboard(Bukkit.getScoreboardManager().getMainScoreboard());
     }
-    
+
     public void addMember(MWPlayer player) {
         if (isMember(player)) return;
 
@@ -103,9 +99,6 @@ public class Team {
         player.setTeam(this);
         p.setDisplayName(getColorCode() + p.getName() + "§r");
         p.getInventory().setArmorContents(getTeamArmor());
-
-        game.getScoreboardManager().updateScoreboard();
-        p.setScoreboard(game.getScoreboard());
     }
 
     public String getFullname() {
@@ -233,7 +226,7 @@ public class Team {
         }
     }
 
-    // TODO Review for necessity (of an alternative), completeness and refactoring
+    // TODO Add new team buffer
     public void updateIntervals(int newInterval) {
         if (newInterval < currentInterval && currentInterval != 0) {
             getGame().broadcast(MessageConfig.getMessage("team_buffed").replace("%team%", getFullname()));