package in.twizmwaz.cardinal.module.modules.scoreboard; import in.twizmwaz.cardinal.GameHandler; import in.twizmwaz.cardinal.event.CycleCompleteEvent; import in.twizmwaz.cardinal.event.MatchEndEvent; import in.twizmwaz.cardinal.event.MatchStartEvent; import in.twizmwaz.cardinal.event.PlayerChangeTeamEvent; import in.twizmwaz.cardinal.event.ScoreUpdateEvent; import in.twizmwaz.cardinal.event.TeamNameChangeEvent; import in.twizmwaz.cardinal.event.TimeLimitChangeEvent; import in.twizmwaz.cardinal.event.objective.ObjectiveCompleteEvent; import in.twizmwaz.cardinal.event.objective.ObjectiveProximityEvent; import in.twizmwaz.cardinal.event.objective.ObjectiveTouchEvent; import in.twizmwaz.cardinal.module.GameObjective; import in.twizmwaz.cardinal.module.Module; import in.twizmwaz.cardinal.module.ModuleCollection; import in.twizmwaz.cardinal.module.modules.blitz.Blitz; import in.twizmwaz.cardinal.module.modules.cores.CoreObjective; import in.twizmwaz.cardinal.module.modules.ctf.FlagObjective; import in.twizmwaz.cardinal.module.modules.destroyable.DestroyableObjective; import in.twizmwaz.cardinal.module.modules.hill.HillObjective; import in.twizmwaz.cardinal.module.modules.score.ScoreModule; import in.twizmwaz.cardinal.module.modules.team.TeamModule; import in.twizmwaz.cardinal.module.modules.timeLimit.TimeLimit; import in.twizmwaz.cardinal.module.modules.wools.WoolObjective; import in.twizmwaz.cardinal.util.Scoreboards; import in.twizmwaz.cardinal.util.Strings; import in.twizmwaz.cardinal.util.Teams; import org.apache.commons.lang.WordUtils; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.HandlerList; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.scoreboard.DisplaySlot; import org.bukkit.scoreboard.Objective; import org.bukkit.scoreboard.Scoreboard; import org.bukkit.scoreboard.Team; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; public class ScoreboardModule implements Module { private TeamModule team, prioritized; private Scoreboard scoreboard; private List<TeamModule> sortedTeams; private Objective objective; private int currentScore, minBlitzScore = -1, minTdmScore = -1; private List<String> used; public ScoreboardModule(final TeamModule team) { this.team = team; this.prioritized = team.isObserver() ? null : team; this.sortedTeams = Teams.getTeams(); this.scoreboard = Bukkit.getScoreboardManager().getNewScoreboard(); for (TeamModule teams : Teams.getTeams()) { Team prefixTeam = scoreboard.registerNewTeam(teams.getId()); prefixTeam.setPrefix(teams.getColor() + ""); prefixTeam.setOption(Team.Option.COLLISION_RULE, Team.OptionStatus.NEVER); if (!teams.isObserver()) { scoreboard.registerNewTeam(teams.getId() + "-t"); } } for (GameObjective objective : GameHandler.getGameHandler().getMatch().getModules().getModules(GameObjective.class)) { scoreboard.registerNewTeam(objective.getScoreboardHandler().getNumber() + "-o"); } if (ScoreModule.matchHasScoring()) { for (ScoreModule score : GameHandler.getGameHandler().getMatch().getModules().getModules(ScoreModule.class)) { scoreboard.registerNewTeam(score.getTeam().getId() + "-s"); } } if (Blitz.matchIsBlitz()) { for (TeamModule teams : Teams.getTeams()) { if (!teams.isObserver()) { scoreboard.registerNewTeam(teams.getId() + "-b"); } } } } public static void add(TeamModule team, Player player) { for (ScoreboardModule scoreboard : GameHandler.getGameHandler().getMatch().getModules().getModules(ScoreboardModule.class)) { scoreboard.getScoreboard().getTeam(team.getId()).addEntry(player.getName()); } } public TeamModule getTeam() { return team; } public Scoreboard getScoreboard() { return scoreboard; } @Override public void unload() { HandlerList.unregisterAll(this); } @EventHandler public void onMatchStartEvent(MatchStartEvent event) { for (TeamModule team : Teams.getTeams()) { Team scoreboardTeam = scoreboard.getTeam(team.getId()); if (!team.isObserver()) scoreboardTeam.setOption(Team.Option.COLLISION_RULE, Team.OptionStatus.NEVER); } } @EventHandler public void onMatchEndEvent(MatchEndEvent event) { for (TeamModule team : Teams.getTeams()) { Team scoreboardTeam = scoreboard.getTeam(team.getId()); if (!team.isObserver()) scoreboardTeam.setOption(Team.Option.COLLISION_RULE, Team.OptionStatus.NEVER); } } @EventHandler(priority = EventPriority.HIGHEST) public void onPlayerChangeTeam(PlayerChangeTeamEvent event) { if (!event.isCancelled()) { if (event.getNewTeam().orNull() == this.team) { event.getPlayer().setScoreboard(this.scoreboard); } if (event.getNewTeam().isPresent()) { add(event.getNewTeam().get(), event.getPlayer()); } if (Blitz.matchIsBlitz()) { updateTeamBlitz(); } } } @EventHandler(priority = EventPriority.MONITOR) public void onPlayerLeave(PlayerQuitEvent event){ updateTeamBlitz(); } @EventHandler public void onCycleComplete(CycleCompleteEvent event) { update(); } @EventHandler public void onObjectiveProximity(ObjectiveProximityEvent event) { if (!this.team.isObserver()) { if ((event.getObjective() instanceof WoolObjective && !(event.getObjective().getTeam() == this.team)) || ((event.getObjective() instanceof CoreObjective || event.getObjective() instanceof DestroyableObjective || event.getObjective() instanceof FlagObjective) && (event.getObjective().getTeam() == this.team))) { return; } } updateObjectivePrefix(event.getObjective()); updateTeamOrder(); } @EventHandler public void onTimeLimitChange(TimeLimitChangeEvent event) { update(); } @EventHandler public void onObjectiveTouch(ObjectiveTouchEvent event) { updateObjectivePrefix(event.getObjective()); updateTeamOrder(); } @EventHandler public void onObjectiveComplete(ObjectiveCompleteEvent event) { updateObjectivePrefix(event.getObjective()); updateTeamOrder(); } @EventHandler public void onTeamNameChange(TeamNameChangeEvent event) { if (event.getTeam().isObserver()) return; updateTeamTitle(event.getTeam()); if (Blitz.matchIsBlitz()) { updateTeamBlitz(); } if (ScoreModule.matchHasScoring()) { updateTeamScore(); } } @EventHandler public void onScoreUpdate(ScoreUpdateEvent event) { updateTeamScore(); } public void updateTeamOrder() { List<TeamModule> newList = TimeLimit.getSortedTeams(); if (sortedTeams != newList){ sortedTeams = newList; update(); } } public void update() { objective = scoreboard.getObjective("scoreboard") == null ? scoreboard.registerNewObjective("scoreboard", "dummy") : scoreboard.getObjective("scoreboard"); objective.setDisplayName(getDisplayTitle()); currentScore = 0; used = new ArrayList<>(); renderObjectives(Scoreboards.getHills()); renderObjectives(Teams.getShownSharedObjectives()); for (TeamModule team : sortedTeams) { if (!team.isObserver() && team != prioritized && Teams.getShownObjectives(team).size() > 0) { if (getSlots() < 16) { renderObjectives(Teams.getShownObjectives(team)); } else { createBlankSlot(); renderCompactObjectives(Teams.getShownObjectives(team)); } renderTeamTitle(team); } } if (prioritized != null && Teams.getShownObjectives(prioritized).size() > 0) { if (getSlots() < 16) { renderObjectives(Teams.getShownObjectives(prioritized)); } else { createBlankSlot(); renderCompactObjectives(Teams.getShownObjectives(prioritized)); } renderTeamTitle(prioritized); } if (ScoreModule.matchHasScoring()) { createBlankSlot(); renderTeamScore(); } if (Blitz.matchIsBlitz()) { createBlankSlot(); renderTeamBlitz(); } if (objective.getDisplaySlot() == null || !objective.getDisplaySlot().equals(DisplaySlot.SIDEBAR)) { objective.setDisplaySlot(DisplaySlot.SIDEBAR); } } public void updateObjectivePrefix(GameObjective objective) { if (!objective.showOnScoreboard()) return; if (getSlots() < 16) { Team team = scoreboard.getTeam(objective.getScoreboardHandler().getNumber() + "-o"); String prefix = objective.getScoreboardHandler().getPrefix(this.team); team.setPrefix(prefix); } else { update(); } } public void updateTeamTitle(TeamModule teamModule) { Team team = scoreboard.getTeam(teamModule.getId() + "-t"); team.setPrefix(teamModule.getColor() + Strings.trimTo(teamModule.getName(), 0, 14)); team.setSuffix(Strings.trimTo(teamModule.getName(), 14, 30)); } public void updateTeamBlitz() { if (minBlitzScore == -1) { update(); } else { renderTeamBlitz(); } } public void updateTeamScore() { if (minTdmScore == -1) { update(); } else { renderTeamScore(); } } private void createBlankSlot() { if (currentScore != 0) { setBlankSlot(currentScore); currentScore++; } } public void setBlankSlot(int score) { String blank = " "; while (used.contains(blank)) { blank += " "; } setScore(objective, blank, score); used.add(blank); } public void setScore(Objective objective, String string, int score) { if (score == 0) { objective.getScore(string).setScore(-1); } objective.getScore(string).setScore(score); } public int getSlots() { int slots = 0; if (Scoreboards.getHills().size() > 0) { slots += Scoreboards.getHills().size(); } if (Teams.getShownSharedObjectives().size() > 0) { if (slots != 0) slots++; slots += Teams.getShownSharedObjectives().size(); } for (TeamModule team : Teams.getTeams()) { if (!team.isObserver() && Teams.getShownObjectives(team).size() > 0) { if (slots != 0) slots++; slots += Teams.getShownObjectives(team).size() + 1; } } if (ScoreModule.matchHasScoring()) { if (slots != 0) slots++; slots += (Teams.getTeams().size() - 1); } if (Blitz.matchIsBlitz()) { if (slots != 0) slots++; slots += (Teams.getTeams().size() - 1); } return slots; } public String getDisplayTitle() { String displayTitle = ""; boolean hasObjectives = false; for (GameObjective obj : GameHandler.getGameHandler().getMatch().getModules().getModules(GameObjective.class)) { if (obj.showOnScoreboard()) { hasObjectives = true; } } Class objective = getSpecificObjective(); if (hasObjectives) { if (objective != null) { if (objective.equals(WoolObjective.class)) { displayTitle = "Wools"; } else if (objective.equals(FlagObjective.class)) { displayTitle = "Flags"; } else if (objective.equals(CoreObjective.class)) { displayTitle = "Cores"; } else if (objective.equals(DestroyableObjective.class)) { displayTitle = "Monuments"; } else if (objective.equals(HillObjective.class)) { displayTitle = "Hills"; } } else { displayTitle = "Objectives"; } } if (ScoreModule.matchHasScoring()) { displayTitle = displayTitle.equals("") || displayTitle.equals("Flags")|| displayTitle.equals("Hills") ? "Scores" : "Objectives"; } if (Blitz.matchIsBlitz()) { String blitzTitle = GameHandler.getGameHandler().getMatch().getModules().getModule(Blitz.class).getTitle(); displayTitle = (blitzTitle.equals("Blitz") || blitzTitle.equals("Blitz: Rage")) ? (displayTitle.equals("") ? blitzTitle : "Players Remaining") : blitzTitle; } if (displayTitle.equals("")) { return ChatColor.RED + "" + ChatColor.BOLD + "Invalid"; } return ChatColor.AQUA + displayTitle; } public Class getSpecificObjective() { Class objective = null; for (GameObjective obj : GameHandler.getGameHandler().getMatch().getModules().getModules(GameObjective.class)) { if (obj.showOnScoreboard()) { if (objective == null) { objective = obj.getClass(); } else if (objective != obj.getClass()) { objective = null; break; } } } return objective; } private void renderObjectives(List<GameObjective> objectives) { Collections.reverse(objectives); if (currentScore != 0 && objectives.size() > 0) createBlankSlot(); for (GameObjective obj : objectives) renderObjective(obj); } public void renderObjective(GameObjective objective) { if (!objective.showOnScoreboard()) return; int score = currentScore; Team team = scoreboard.getTeam(objective.getScoreboardHandler().getNumber() + "-o"); String prefix = objective.getScoreboardHandler().getPrefix(this.team); team.setPrefix(prefix); if (team.getEntries().size() > 0) { setScore(this.objective, new ArrayList<>(team.getEntries()).get(0), score); } else { String raw = (objective instanceof HillObjective ? "" : ChatColor.RESET) + " " + WordUtils.capitalizeFully(objective.getName().replaceAll("_", " ")); while (used.contains(raw)) { raw = raw + ChatColor.RESET; } team.addEntry(raw); setScore(this.objective, raw, score); used.add(raw); } currentScore++; } public void renderCompactObjectives(ModuleCollection<GameObjective> objectives) { int score = currentScore; Team team = scoreboard.getTeam(objectives.get(0).getScoreboardHandler().getNumber() + "-o"); if (team != null) { String compact = ""; for (GameObjective obj : objectives) { compact += obj.getScoreboardHandler().getCompactPrefix(this.team) + " "; } while (compact.length() > 32) { compact = Strings.removeLastWord(compact); } if (compact.length() < 16){ team.setPrefix(Strings.trimTo(compact, 0, 16)); team.setSuffix("r"); } else if (compact.charAt(15) == '\u00A7') { team.setPrefix(Strings.trimTo(compact, 0, 15)); team.setSuffix(Strings.trimTo(compact, 15, 31)); } else { team.setPrefix(Strings.trimTo(compact, 0, 16)); team.setSuffix(Strings.getCurrentChatColor(compact, 16).charAt(1) + Strings.trimTo(compact, 16, 31)); } if (team.getEntries().size() > 0) { setScore(objective, new ArrayList<>(team.getEntries()).get(0), currentScore); } else { String name = "\u00A7"; while (used.contains(name)) { name = ChatColor.RESET + name; } team.addEntry(name); setScore(objective, name, score); used.add(name); } currentScore++; } } public void renderTeamTitle(TeamModule teamModule) { Team team = scoreboard.getTeam(teamModule.getId() + "-t"); team.setPrefix(teamModule.getColor() + Strings.trimTo(teamModule.getName(), 0, 14)); team.setSuffix(Strings.trimTo(teamModule.getName(), 14, 30)); if (team.getEntries().size() > 0) { setScore(objective, new ArrayList<>(team.getEntries()).get(0), currentScore); } else { String name = teamModule.getColor() + ""; while (used.contains(name)) { name = teamModule.getColor() + name; } team.addEntry(name); setScore(objective, name, currentScore); used.add(name); } currentScore++; } public void renderTeamScore() { if (minTdmScore == -1){ minTdmScore = currentScore; } List<String> fullNames = new ArrayList<>(); for (ScoreModule score : GameHandler.getGameHandler().getMatch().getModules().getModules(ScoreModule.class)){ if (score.getMax() != 0){ fullNames.add(score.getScore() + "" + ChatColor.DARK_GRAY + "/" + ChatColor.GRAY + score.getMax() + " " + score.getTeam().getCompleteName()); } else { fullNames.add(score.getScore() + " " + score.getTeam().getCompleteName()); } } java.util.Collections.sort(fullNames, new Comparator<String>(){ public int compare(String str1, String str2){ int int1 = Integer.parseInt((str1.contains("/") ? str1.split("\u00a7",2) : str1.split(" ",2))[0]); int int2 = Integer.parseInt((str2.contains("/") ? str2.split("\u00a7",2) : str2.split(" ",2))[0]); return int1 - int2; } }); for (int i = 0; i < fullNames.size(); i++) { String teamCompleteName = fullNames.get(i).split(" ",2)[1]; Team team = scoreboard.getTeam(Teams.getTeamByName(teamCompleteName.substring(2)).get().getId() + "-s"); team.setPrefix(Strings.trimTo(fullNames.get(i), 0, 16)); team.setSuffix(Strings.trimTo(fullNames.get(i), 16, 32)); if (team.getEntries().size() > 0) { if (objective.getScore(new ArrayList<>(team.getEntries()).get(0)).getScore() != minTdmScore + i) setScore(objective, new ArrayList<>(team.getEntries()).get(0), minTdmScore + i); } else { String color = teamCompleteName.substring(0, 2); String name = color + ""; while (used.contains(name)) { name = color + name; } team.addEntry(name); setScore(objective, name, minTdmScore + i); used.add(name); } currentScore++; } } public void renderTeamBlitz() { if (minBlitzScore == -1){ minBlitzScore = currentScore; } List<String> fullNames = new ArrayList<>(); for (TeamModule team : Teams.getTeams()) { if (!team.isObserver()) { fullNames.add(team.size() + " " + team.getCompleteName()); } } java.util.Collections.sort(fullNames); for (int i = 0; i < fullNames.size(); i++) { String teamCompleteName = fullNames.get(i).split(" ", 2)[1]; Team team = scoreboard.getTeam(Teams.getTeamByName(teamCompleteName.substring(2)).get().getId() + "-b"); team.setPrefix(Strings.trimTo(fullNames.get(i), 0, 16)); team.setSuffix(Strings.trimTo(fullNames.get(i), 16, 32)); if (team.getEntries().size() > 0) { setScore(objective, new ArrayList<>(team.getEntries()).get(0), minBlitzScore + i); } else { String color = teamCompleteName.substring(0, 2); String name = color + ""; while (used.contains(name)) { name = color + name; } team.addEntry(name); setScore(objective, name, minBlitzScore + i); used.add(name); } currentScore++; } } }