ursinn/DeadByDaylightMC

View on GitHub
src/main/java/noahnok/dbdl/files/game/DGameManager.java

Summary

Maintainability
B
5 hrs
Test Coverage
package noahnok.dbdl.files.game;

import noahnok.dbdl.files.DeadByDaylight;
import noahnok.dbdl.files.game.generators.Generator;
import noahnok.dbdl.files.game.levers.DLever;
import noahnok.dbdl.files.player.DPlayer;
import noahnok.dbdl.files.player.PlayerStatus;
import noahnok.dbdl.files.signs.DSign;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;

public class DGameManager {

    private final DeadByDaylight main;
    private final Set<DGame> games = new HashSet<>();
    private int gamesRun = 0;

    public DGameManager(DeadByDaylight main) {
        this.main = main;
    }

    public Set<DGame> getGames() {
        return games;
    }

    public DGame getGamePlayerIsIn(Player p) {
        for (DGame game : games) {
            if (game.getPlayers().contains(main.getDPlayerManager().getPlayer(p.getUniqueId()))) {
                return game;
            }
        }

        return null;
    }

    public void joinPlayerToGame(Player p, DGame game, String playType) {
        DPlayer dPlayer = main.getDPlayerManager().getPlayer(p.getUniqueId());
        game.getPlayers().add(dPlayer);
        if (playType.equalsIgnoreCase("HUNTER")) {
            dPlayer.setStatus(PlayerStatus.HUNTER);
        } else {
            dPlayer.setStatus(PlayerStatus.HUNTED);
        }

        p.teleport(game.getArena().getLobbyLocation());
        game.announceJoin(p);
        p.setGameMode(GameMode.SURVIVAL);
        dPlayer.setCurrentGame(game);
        canGameStart(game, false);
        dPlayer.resetPlayerState();
    }

    public String generateGameID(DGame game) {
        gamesRun++;
        return game.getArena().getId() + "_" + game.getGamemode().getId() + "_" + gamesRun;
    }

    public void removePlayerFromGame(Player p, DGame game) {
        DPlayer dPlayer = game.getPlayer(p.getUniqueId());
        game.getPlayers().remove(dPlayer);
        dPlayer.setStatus(PlayerStatus.OUT_OF_GAME);
        game.announceLeave(p);
        dPlayer.setCurrentGame(null);
        dPlayer.stopSpectating();
        dPlayer.resetPlayerState();
        p.getActivePotionEffects().clear();

        p.teleport(Bukkit.getServer().getWorld("world").getSpawnLocation());

        if (game.totalCurrentPlayers() == 0) {
            if (game.getStatus() == STATUS.WAITING || game.getStatus() == STATUS.STARTING) {
                DSign sign = main.getSignManager().getSign(game);
                if (sign != null) {
                    sign.removeGame();
                    sign.update();
                }
            }
            destroyGame(game);
        }

    }

    public void destroyGame(DGame game) {
        main.getMatchMaking().removeGame(game);
        game.getArena().setInUse(false);
        game.kill();
    }

    public void forceStartGame(DGame game) {
        canGameStart(game, true);
    }

    public void endGame(final DGame game) {
        game.endGameSound();
        game.announce("The game has ended!");
        game.setStatus(STATUS.ENDING);

        game.sendPlayersStats();

        new BukkitRunnable() {
            public void run() {
                game.endGame();
                removeMatchBlocks(game);
                destroyGame(game);
            }
        }.runTaskLater(main, 20 * 10);
    }


    private void canGameStart(DGame game, boolean force) {
        int totalReqPlayers = game.getGamemode().getHunted() + game.getGamemode().getHunters();
        int currentPlayers = game.getPlayers().size();

        if (currentPlayers >= totalReqPlayers || force) {
            //Game can start countdown

            main.getMatchMaking().removeGameFromMatchmaking(game);

            prepareMatchBlocks(game);

            game.setStatus(STATUS.STARTING);
            Countdown cd = new Countdown(10, true, 30, game, main);
            game.setCd(cd);
            cd.start();
        }
    }

    public void canGameEnd(DGame game) {
        for (DPlayer player : game.getHunted()) {
            if (player.isHunter()) {
                continue;
            }

            if (!player.isDead()) {
                return;
            }
        }

        for (DPlayer player : game.getPlayers()) {
            Player actual = player.getPlayer();
            player.stopSpectating();
            actual.setGameMode(GameMode.CREATIVE);
            actual.getInventory().clear();
            actual.setHealth(20D);
            actual.setFoodLevel(20);
            actual.setFlying(true);
            main.getPlayerStateManager().survivorHealed(player, true);
        }

        endGame(game);
    }

    public DGame createNewGame() {
        DArena arena = main.getArenaManager().getRandomArena();
        if (arena == null) {
            return null;
        }

        arena.setInUse(true);
        DGamemode mode = main.getGamemodeManager().getMode("default");
        return new DGame(arena, mode, STATUS.WAITING, main);
    }


    private Location getRandomLocation(Set<Location> locations) {
        if (locations.size() == 1) {
            return locations.iterator().next();
        }
        int rand = ThreadLocalRandom.current().nextInt(1, locations.size()) - 1;
        int i = 0;
        for (Location loc : locations) {
            if (i == rand) {
                return loc;
            }
            i++;
        }
        return null;
    }

    private void spawnGenerators(DGame game, Set<Location> locs, DGamemode mode) {
        Set<Location> temp = new HashSet<>();
        temp.addAll(locs);
        for (int i = 0; i < mode.getMaxgenerators(); i++) {
            Location loc = getRandomLocation(temp);
            temp.remove(loc);
            Generator gen = new Generator(game, loc, main);
            game.getGenerators().add(gen);
            gen.spawn();
        }
        temp.clear();
    }

    private void spawnExitGates(DGame game) {
        for (ExitGate gate : game.getArena().getExitGateLocations()) {
            for (Location loc : gate.getLocs()) {
                loc.getBlock().setType(Material.IRON_FENCE);
            }
            gate.getCenter().getBlock().setType(Material.IRON_BLOCK);
            Location leverFowardLoc = null;
            Location leverBackwardLoc = null;
            if (gate.getFacing().equalsIgnoreCase("EAST")) {
                leverFowardLoc = gate.getCenter().clone().add(1, 0, 0);
                leverBackwardLoc = gate.getCenter().clone().subtract(1, 0, 0);
            }
            if (gate.getFacing().equalsIgnoreCase("NORTH")) {
                leverFowardLoc = gate.getCenter().clone().add(0, 0, 1);
                leverBackwardLoc = gate.getCenter().clone().subtract(0, 0, 1);
            }
            if (leverFowardLoc == null || leverBackwardLoc == null) {
                main.getLogger().severe("Woah! Somethings not quite right with your exit gates LEVERS!" +
                        " Their facing tag is wrong! So we haven't spawned them!");
                continue;
            }
            DLever lever = new DLever(leverFowardLoc, game, gate);
            DLever lever2 = new DLever(leverBackwardLoc, game, gate);

            gate.setLever1(lever);
            gate.setLever2(lever2);

            game.getExitGates().add(gate);
        }
    }


    public void prepareMatchBlocks(DGame game) {
        DArena arena = game.getArena();
        spawnGenerators(game, arena.getPossibleGeneratorLocations(), game.getGamemode());
        spawnExitGates(game);
    }


    public void removeMatchBlocks(DGame game) {
        for (Generator gen : game.getGenerators()) {
            gen.setGame(null);
            gen.despawn();
        }
        game.getGenerators().clear();

        if (game.getArena() != null && game.getArena().getExitGateLocations() != null) {
            for (ExitGate gate : game.getArena().getExitGateLocations()) {
                for (Location loc : gate.getLocs()) {
                    loc.getBlock().setType(Material.AIR);
                }
                gate.getLever1().kill();
                gate.getLever2().kill();
                gate.setLever1(null);
                gate.setLever2(null);

            }
        }
        game.getExitGates().clear();
    }

}