From 575772302878564dfac9e418ae991e6d10ed180e Mon Sep 17 00:00:00 2001 From: Andreas Troelsen Date: Tue, 9 Apr 2013 19:39:48 +0200 Subject: [PATCH] Implement basic scoreboard support. --- src/com/garbagemule/MobArena/ArenaImpl.java | 17 ++++ .../garbagemule/MobArena/ArenaListener.java | 1 + .../garbagemule/MobArena/MASpawnThread.java | 2 + .../MobArena/ScoreboardManager.java | 92 +++++++++++++++++++ .../garbagemule/MobArena/framework/Arena.java | 3 + 5 files changed, 115 insertions(+) create mode 100644 src/com/garbagemule/MobArena/ScoreboardManager.java diff --git a/src/com/garbagemule/MobArena/ArenaImpl.java b/src/com/garbagemule/MobArena/ArenaImpl.java index 96e3e49..d4f2237 100644 --- a/src/com/garbagemule/MobArena/ArenaImpl.java +++ b/src/com/garbagemule/MobArena/ArenaImpl.java @@ -102,6 +102,9 @@ public class ArenaImpl implements Arena private TimeStrategy timeStrategy; private AutoStartTimer autoStartTimer; + // Scoreboards + private ScoreboardManager scoreboard; + /** * Primary constructor. Requires a name and a world. */ @@ -166,6 +169,9 @@ public class ArenaImpl implements Arena String timeString = settings.getString("player-time-in-arena", "world"); Time time = Enums.getEnumFromString(Time.class, timeString); this.timeStrategy = (time != null ? new TimeStrategyLocked(time) : new TimeStrategyNull()); + + // Scoreboards + this.scoreboard = new ScoreboardManager(this); } @@ -364,6 +370,10 @@ public class ArenaImpl implements Arena return limitManager; } + @Override + public ScoreboardManager getScoreboard() { + return scoreboard; + } @@ -407,6 +417,9 @@ public class ArenaImpl implements Arena return false; } + // Initialize scoreboards + scoreboard.initialize(); + // Teleport players, give full health, initialize map for (Player p : arenaPlayers) { // TODO figure out how people die in lobby and get sent to spectator area early @@ -425,6 +438,8 @@ public class ArenaImpl implements Arena p.setFoodLevel(20); assignClassPermissions(p); arenaPlayerMap.get(p).resetStats(); + + scoreboard.addPlayer(p); } // Start spawning monsters (must happen before 'running = true;') @@ -882,6 +897,8 @@ public class ArenaImpl implements Arena arenaPlayers.remove(p); lobbyPlayers.remove(p); arenaPlayerMap.remove(p); + + scoreboard.removePlayer(p); } private void setHealth(Player p, int health) { diff --git a/src/com/garbagemule/MobArena/ArenaListener.java b/src/com/garbagemule/MobArena/ArenaListener.java index 91c452d..374559f 100644 --- a/src/com/garbagemule/MobArena/ArenaListener.java +++ b/src/com/garbagemule/MobArena/ArenaListener.java @@ -435,6 +435,7 @@ public class ArenaListener ArenaPlayerStatistics stats = ap.getStats(); if (stats != null) { ap.getStats().inc("kills"); + arena.getScoreboard().addKill((Player) damager); } } } diff --git a/src/com/garbagemule/MobArena/MASpawnThread.java b/src/com/garbagemule/MobArena/MASpawnThread.java index 8a9f095..296fe1a 100644 --- a/src/com/garbagemule/MobArena/MASpawnThread.java +++ b/src/com/garbagemule/MobArena/MASpawnThread.java @@ -128,6 +128,8 @@ public class MASpawnThread implements Runnable w.announce(arena, wave); + arena.getScoreboard().updateWave(wave); + // Set the players' level to the wave number if (wavesAsLevel) { for (Player p : arena.getPlayersInArena()) { diff --git a/src/com/garbagemule/MobArena/ScoreboardManager.java b/src/com/garbagemule/MobArena/ScoreboardManager.java new file mode 100644 index 0000000..ae5f42a --- /dev/null +++ b/src/com/garbagemule/MobArena/ScoreboardManager.java @@ -0,0 +1,92 @@ +package com.garbagemule.MobArena; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.scoreboard.DisplaySlot; +import org.bukkit.scoreboard.Objective; +import org.bukkit.scoreboard.Score; +import org.bukkit.scoreboard.Scoreboard; + +import com.garbagemule.MobArena.framework.Arena; + +public class ScoreboardManager { + private Arena arena; + private Scoreboard scoreboard; + private Objective kills; + + /** + * Create a new scoreboard for the given arena. + * @param arena an arena + */ + ScoreboardManager(Arena arena) { + this.arena = arena; + scoreboard = Bukkit.getScoreboardManager().getNewScoreboard(); + } + + /** + * Add a player to the scoreboard by setting the player's scoreboard + * and giving him an initial to-be-reset non-zero score. + * @param player a player + */ + void addPlayer(Player player) { + /* Set the player's scoreboard and give them an initial non-zero + * score. This is necessary due to either Minecraft or Bukkit + * not wanting to show non-zero scores initially. */ + player.setScoreboard(scoreboard); + kills.getScore(player).setScore(8); + } + + /** + * Remove a player from the scoreboard by setting the player's scoreboard + * to the main server scoreboard. + * @param player a player + */ + void removePlayer(Player player) { + player.setScoreboard(Bukkit.getScoreboardManager().getMainScoreboard()); + } + + /** + * Add a kill to the player's score. Called when a player kills a mob. + * @param player a player + */ + void addKill(Player player) { + Score score = kills.getScore(player); + score.setScore(score.getScore() + 1); + } + + /** + * Update the scoreboard to display the given wave number. + * @param wave a wave number + */ + void updateWave(int wave) { + kills.setDisplayName("§aMobArena Kills §bWave " + wave); + } + + /** + * Initialize the scoreboard by resetting the kills objective and + * setting all player scores to 0. + */ + void initialize() { + /* Initialization involves first unregistering the kill counter if + * it was already registered, and then setting it back up. + * It is necessary to delay the reset of the player scores, and the + * reset is necessary because of non-zero crappiness. */ + resetKills(); + arena.scheduleTask(new Runnable() { + public void run() { + for (Player p : arena.getPlayersInArena()) { + kills.getScore(p).setScore(0); + } + } + }, 1); + } + + private void resetKills() { + if (kills != null) { + kills.unregister(); + } + kills = scoreboard.registerNewObjective("kills", "ma-kills"); + kills.setDisplaySlot(DisplaySlot.SIDEBAR); + updateWave(0); + } +} diff --git a/src/com/garbagemule/MobArena/framework/Arena.java b/src/com/garbagemule/MobArena/framework/Arena.java index 55ced6e..5195f68 100644 --- a/src/com/garbagemule/MobArena/framework/Arena.java +++ b/src/com/garbagemule/MobArena/framework/Arena.java @@ -18,6 +18,7 @@ import com.garbagemule.MobArena.MASpawnThread; import com.garbagemule.MobArena.MobArena; import com.garbagemule.MobArena.MonsterManager; import com.garbagemule.MobArena.RewardManager; +import com.garbagemule.MobArena.ScoreboardManager; import com.garbagemule.MobArena.leaderboards.Leaderboard; import com.garbagemule.MobArena.region.ArenaRegion; import com.garbagemule.MobArena.repairable.Repairable; @@ -104,6 +105,8 @@ public interface Arena public void revivePlayer(Player p); + public ScoreboardManager getScoreboard(); +