package com.alttd.ctf.game; import com.alttd.ctf.flag.Flag; import com.alttd.ctf.game.phases.ClassSelectionPhase; import com.alttd.ctf.game.phases.CombatPhase; import com.alttd.ctf.game.phases.EndedPhase; import com.alttd.ctf.game.phases.GatheringPhase; import com.alttd.ctf.game_class.creation.FighterCreator; import com.alttd.ctf.team.Team; import com.alttd.ctf.team.TeamPlayer; import com.github.yannicklamprecht.worldborder.api.WorldBorderApi; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import java.time.Duration; import java.util.*; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class GameManager { ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); private final HashMap phases; private RunningGame runningGame; private final HashMap teams = new HashMap<>(); public GameManager(WorldBorderApi worldBorderApi) { phases = new HashMap<>(); phases.put(GamePhase.CLASS_SELECTION, new ClassSelectionPhase(this, FighterCreator::createFighter, worldBorderApi)); phases.put(GamePhase.GATHERING, new GatheringPhase(this, worldBorderApi)); phases.put(GamePhase.COMBAT, new CombatPhase()); phases.put(GamePhase.ENDED, new EndedPhase()); } public Optional getGamePhase() { return runningGame == null ? Optional.empty() : Optional.of(runningGame.getCurrentPhase()); } public void registerPlayer(Team team, Player player) { unregisterPlayer(player); teams.get(team.getId()).addPlayer(player.getUniqueId()); } public void unregisterPlayer(Player player) { teams.values().forEach(team -> team.removePlayer(player.getUniqueId())); } public void registerTeam(Team team) { teams.put(team.getId(), team); } public Collection getTeams() { return teams.values(); } public Optional getTeam(@NotNull UUID uuid) { return getTeams().stream().filter(filterTeam -> filterTeam.getPlayer(uuid).isPresent()).findAny(); } public Optional getTeam(int teamId) { return getTeams().stream().filter(filterTeam -> filterTeam.getId() == teamId).findAny(); } public Optional getTeamPlayer(@NotNull UUID uuid) { return getTeams().stream() .map(team -> team.getPlayer(uuid)) .filter(Optional::isPresent) .findFirst() .orElseGet(Optional::empty); } public void start(Duration duration, Flag flag) { //TODO assign players to teams and if they are discord link give them a team role so they can be in vc with each other if (runningGame != null) { runningGame.end(); executorService.shutdown(); executorService = Executors.newSingleThreadScheduledExecutor(); } runningGame = new RunningGame(this, duration, flag); executorService.scheduleAtFixedRate(runningGame, 0, 1, TimeUnit.SECONDS); } protected GamePhaseExecutor getPhaseExecutor(GamePhase gamePhase) { GamePhaseExecutor gamePhaseExecutor = phases.get(gamePhase); if (gamePhaseExecutor == null) { throw new IllegalArgumentException("No phase executor found for phase " + gamePhase); } return gamePhaseExecutor; } public void clearTeams() { teams.clear(); } public int getMaxTeamId() { return getTeams().stream() .mapToInt(Team::getId) .max() .orElse(0); } }