Add scoreboard features and configuration options. Fixes gh-623, gh-45

With the new warzone configuration property "scoreboard", zone makers can
set the type of scoreboard to be used. This may be "none", "points", or
"lifepool". If the scoreboard type is not "none", then a scoreboard will
be shown on the right side of the screen in the warzone. The shown
scoreboard will display the configured option.

Also, 3-year-old feature request COMPLETED! Use the command
/zone <warzone-name> scoreboard to view a scoreboard from anywhere.
This commit is contained in:
cmastudios 2013-09-10 17:23:34 -05:00
parent b367cc53ad
commit 2738d2e358
7 changed files with 178 additions and 30 deletions

View File

@ -2,20 +2,29 @@ package com.tommytony.war;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.logging.Level;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import org.bukkit.scoreboard.DisplaySlot;
import org.bukkit.scoreboard.Objective;
import org.getspout.spoutapi.SpoutManager;
import org.getspout.spoutapi.player.SpoutPlayer;
import org.kitteh.tag.TagAPI;
import com.tommytony.war.config.InventoryBag;
import com.tommytony.war.config.ScoreboardType;
import com.tommytony.war.config.TeamConfig;
import com.tommytony.war.config.TeamConfigBag;
import com.tommytony.war.config.TeamKind;
@ -26,11 +35,6 @@ import com.tommytony.war.utility.Direction;
import com.tommytony.war.utility.SignHelper;
import com.tommytony.war.volume.BlockInfo;
import com.tommytony.war.volume.Volume;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import org.kitteh.tag.TagAPI;
/**
*
@ -356,6 +360,9 @@ public class Team {
if (War.war.isTagServer()) {
TagAPI.refreshPlayer(player);
}
if (this.warzone.getScoreboard() != null && this.warzone.getScoreboardType() != ScoreboardType.NONE) {
player.setScoreboard(this.warzone.getScoreboard());
}
}
public List<Player> getPlayers() {
@ -441,6 +448,12 @@ public class Team {
public void setRemainingLives(int remainingLives) {
this.remainingLives = remainingLives;
if (this.warzone.getScoreboard() != null && this.warzone.getScoreboardType() == ScoreboardType.LIFEPOOL) {
String teamName = kind.getColor() + name + ChatColor.RESET;
OfflinePlayer teamPlayer = Bukkit.getOfflinePlayer(teamName);
Objective obj = this.warzone.getScoreboard().getObjective("Lifepool");
obj.getScore(teamPlayer).setScore(remainingLives);
}
}
public int getRemainingLifes() {
@ -460,6 +473,11 @@ public class Team {
} else if (!atLeastOnePlayerOnOtherTeam) {
this.teamcast("Can't score until at least one player joins another team.");
}
if (this.warzone.getScoreboardType() == ScoreboardType.POINTS) {
String teamName = kind.getColor() + name + ChatColor.RESET;
this.warzone.getScoreboard().getObjective(DisplaySlot.SIDEBAR)
.getScore(Bukkit.getOfflinePlayer(teamName)).setScore(points);
}
}
public int getPoints() {
@ -488,6 +506,11 @@ public class Team {
public void resetPoints() {
this.points = 0;
if (this.warzone.getScoreboardType() == ScoreboardType.POINTS) {
String teamName = kind.getColor() + name + ChatColor.RESET;
this.warzone.getScoreboard().getObjective(DisplaySlot.SIDEBAR)
.getScore(Bukkit.getOfflinePlayer(teamName)).setScore(points);
}
}
public void setFlagVolume(Volume flagVolume) {

View File

@ -28,6 +28,7 @@ import org.bukkit.plugin.java.JavaPlugin;
import com.tommytony.war.command.WarCommandHandler;
import com.tommytony.war.config.FlagReturn;
import com.tommytony.war.config.InventoryBag;
import com.tommytony.war.config.ScoreboardType;
import com.tommytony.war.config.TeamConfig;
import com.tommytony.war.config.TeamConfigBag;
import com.tommytony.war.config.TeamKind;
@ -188,6 +189,7 @@ public class War extends JavaPlugin {
warzoneDefaultConfig.put(WarzoneConfig.DEATHMESSAGES, true);
warzoneDefaultConfig.put(WarzoneConfig.JOINMIDBATTLE, true);
warzoneDefaultConfig.put(WarzoneConfig.AUTOJOIN, false);
warzoneDefaultConfig.put(WarzoneConfig.SCOREBOARD, ScoreboardType.NONE);
teamDefaultConfig.put(TeamConfig.FLAGMUSTBEHOME, true);
teamDefaultConfig.put(TeamConfig.FLAGPOINTSONLY, false);

View File

@ -24,6 +24,7 @@ import org.getspout.spoutapi.SpoutManager;
import org.getspout.spoutapi.player.SpoutPlayer;
import com.tommytony.war.config.InventoryBag;
import com.tommytony.war.config.ScoreboardType;
import com.tommytony.war.config.TeamConfig;
import com.tommytony.war.config.TeamConfigBag;
import com.tommytony.war.config.TeamKind;
@ -49,6 +50,13 @@ import com.tommytony.war.utility.PotionEffectHelper;
import com.tommytony.war.volume.BlockInfo;
import com.tommytony.war.volume.Volume;
import com.tommytony.war.volume.ZoneVolume;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.scoreboard.DisplaySlot;
import org.bukkit.scoreboard.Objective;
import org.bukkit.scoreboard.Scoreboard;
import org.bukkit.inventory.meta.LeatherArmorMeta;
/**
*
@ -83,6 +91,8 @@ public class Warzone {
private final WarzoneConfigBag warzoneConfig;
private final TeamConfigBag teamDefaultConfig;
private InventoryBag defaultInventories = new InventoryBag();
private Scoreboard scoreboard;
private HubLobbyMaterials lobbyMaterials = null;
private WarzoneMaterials warzoneMaterials = new WarzoneMaterials(49, (byte)0, 85, (byte)0, 89, (byte)0); // default main obsidian, stand ladder, light glowstone
@ -261,6 +271,21 @@ public class Warzone {
public void initializeZone(Player respawnExempted) {
if (this.ready() && this.volume.isSaved()) {
if (this.scoreboard != null) {
for (OfflinePlayer opl : this.scoreboard.getPlayers()) {
this.scoreboard.resetScores(opl);
}
this.scoreboard.clearSlot(DisplaySlot.SIDEBAR);
for (Objective obj : this.scoreboard.getObjectives()) {
obj.unregister();
}
for (Player player : Bukkit.getOnlinePlayers()) {
if (player.getScoreboard() == this.scoreboard) {
player.setScoreboard(Bukkit.getScoreboardManager().getMainScoreboard());
}
}
this.scoreboard = null;
}
// everyone back to team spawn with full health
for (Team team : this.teams) {
for (Player player : team.getPlayers()) {
@ -330,7 +355,26 @@ public class Warzone {
this.bombThieves.clear();
this.cakeThieves.clear();
this.reallyDeadFighters.clear();
if (this.getScoreboardType() != ScoreboardType.NONE) {
this.scoreboard = Bukkit.getScoreboardManager().getNewScoreboard();
scoreboard.registerNewObjective(this.getScoreboardType().getDisplayName(), "dummy");
Objective obj = scoreboard.getObjective(this.getScoreboardType().getDisplayName());
Validate.isTrue(obj.isModifiable(), "Cannot modify players' scores on the " + this.name + " scoreboard.");
for (Team team : this.getTeams()) {
String teamName = team.getKind().getColor() + team.getName() + ChatColor.RESET;
if (this.getScoreboardType() == ScoreboardType.POINTS) {
obj.getScore(Bukkit.getOfflinePlayer(teamName)).setScore(team.getPoints());
} else if (this.getScoreboardType() == ScoreboardType.LIFEPOOL) {
obj.getScore(Bukkit.getOfflinePlayer(teamName)).setScore(team.getRemainingLifes());
}
}
obj.setDisplaySlot(DisplaySlot.SIDEBAR);
for (Team team : this.getTeams()) {
for (Player player : team.getPlayers()) {
player.setScoreboard(scoreboard);
}
}
}
// nom drops
for(Entity entity : (this.getWorld().getEntities())) {
if (!(entity instanceof Item)) {
@ -544,6 +588,7 @@ public class Warzone {
SpoutManager.getPlayer(player).setTitle(originalState.getPlayerTitle());
}
}
player.setScoreboard(Bukkit.getScoreboardManager().getMainScoreboard());
}
private void playerInvFromInventoryStash(PlayerInventory playerInv, PlayerState originalContents) {
@ -1510,4 +1555,12 @@ public class Warzone {
public WarzoneMaterials getWarzoneMaterials() {
return warzoneMaterials;
}
public Scoreboard getScoreboard() {
return scoreboard;
}
public ScoreboardType getScoreboardType() {
return this.getWarzoneConfig().getScoreboardType(WarzoneConfig.SCOREBOARD);
}
}

View File

@ -6,6 +6,7 @@ import org.bukkit.entity.Player;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import org.bukkit.Bukkit;
/**
* Warps the player to the given warzone.
@ -23,28 +24,44 @@ public class WarzoneCommand extends AbstractWarCommand {
this.badMsg("You can't do this if you are not in-game.");
return true;
}
if (this.args.length != 1) {
Player player = (Player) this.getSender();
if (args.length == 1) {
if (War.war.canWarp(player)) {
Warzone warzone = Warzone.getZoneByName(args[0]);
if (warzone != null && warzone.getTeleport() != null) {
Warzone playerWarzone = Warzone.getZoneByPlayerName(player.getName());
if (playerWarzone != null) {
playerWarzone.handlePlayerLeave(player, warzone.getTeleport(), true);
} else {
player.teleport(warzone.getTeleport());
}
} else {
this.badMsg("Warzone " + args[0] + " could not be found.");
}
} else {
this.badMsg("You do not have permission to teleport to the warzone.");
}
return true;
} else if (args.length == 2 && (args[1].equalsIgnoreCase("sb")
|| args[1].equalsIgnoreCase("score")
|| args[1].equalsIgnoreCase("scoreboard"))) {
Warzone warzone = Warzone.getZoneByName(args[0]);
if (warzone != null) {
if (warzone.getScoreboard() != null) {
if (warzone.getScoreboard() == player.getScoreboard()) {
player.setScoreboard(Bukkit.getScoreboardManager().getMainScoreboard());
} else {
player.setScoreboard(warzone.getScoreboard());
}
} else {
this.badMsg("Warzone " + args[0] + " has not enabled a scoreboard.");
}
} else {
this.badMsg("Warzone " + args[0] + " could not be found.");
}
return true;
} else {
return false;
}
Player player = (Player) this.getSender();
if (!War.war.canWarp(player)) {
this.badMsg("Can't warp to zone. You need the 'war.warp' permission.");
} else {
Warzone warzone = Warzone.getZoneByName(this.args[0]);
if (warzone != null && warzone.getTeleport() != null) {
Warzone playerWarzone = Warzone.getZoneByPlayerName(player.getName());
if (playerWarzone != null) {
playerWarzone.handlePlayerLeave(player, warzone.getTeleport(), true);
} else {
player.teleport(warzone.getTeleport());
}
return true;
}
this.badMsg("No such warzone.");
}
return true;
}
}

View File

@ -0,0 +1,32 @@
package com.tommytony.war.config;
public enum ScoreboardType {
NONE(null),
POINTS("Points"),
LIFEPOOL("Lifepool");
private final String displayName;
private ScoreboardType(String displayName) {
this.displayName = displayName;
}
@Override
public String toString() {
return super.toString().toLowerCase();
}
public static ScoreboardType getFromString(String string) {
for (ScoreboardType boardMode : ScoreboardType.values()) {
if (string.toLowerCase().equals(boardMode.toString())) {
return boardMode;
}
}
return ScoreboardType.NONE;
}
public String getDisplayName() {
return displayName;
}
}

View File

@ -21,7 +21,9 @@ public enum WarzoneConfig {
RESETONUNLOAD (Boolean.class),
UNBREAKABLE (Boolean.class),
JOINMIDBATTLE (Boolean.class),
AUTOJOIN (Boolean.class);
AUTOJOIN (Boolean.class),
SCOREBOARD (ScoreboardType.class)
;
private final Class<?> configType;

View File

@ -58,6 +58,15 @@ public class WarzoneConfigBag {
}
}
public ScoreboardType getScoreboardType(WarzoneConfig config) {
if (bag.containsKey(config)) {
return (ScoreboardType)bag.get(config);
} else {
// use War default config
return War.war.getWarzoneDefaultConfig().getScoreboardType(config);
}
}
public void loadFrom(ConfigurationSection warzoneConfigSection) {
for (WarzoneConfig config : WarzoneConfig.values()) {
if (warzoneConfigSection.contains(config.toString())) {
@ -65,6 +74,8 @@ public class WarzoneConfigBag {
this.put(config, warzoneConfigSection.getInt(config.toString()));
} else if (config.getConfigType().equals(Boolean.class)) {
this.put(config, warzoneConfigSection.getBoolean(config.toString()));
} else if (config.getConfigType().equals(ScoreboardType.class)) {
this.put(config, ScoreboardType.getFromString(warzoneConfigSection.getString(config.toString())));
}
}
}
@ -73,7 +84,12 @@ public class WarzoneConfigBag {
public void saveTo(ConfigurationSection warzoneConfigSection) {
for (WarzoneConfig config : WarzoneConfig.values()) {
if (this.bag.containsKey(config)) {
warzoneConfigSection.set(config.toString(), this.bag.get(config));
if (config.getConfigType().equals(Integer.class)
|| config.getConfigType().equals(Boolean.class)) {
warzoneConfigSection.set(config.toString(), this.bag.get(config));
} else {
warzoneConfigSection.set(config.toString(), this.bag.get(config).toString());
}
}
}
}
@ -95,6 +111,9 @@ public class WarzoneConfigBag {
this.warzone.getLobby().setLocation(this.warzone.getTeleport());
this.warzone.getLobby().initialize();
}
} else if (warzoneConfig.getConfigType().equals(ScoreboardType.class)) {
String type = namedParams.get(namedParam);
this.bag.put(warzoneConfig, ScoreboardType.getFromString(type));
}
returnMessage += " " + warzoneConfig.toString() + " set to " + namedParams.get(namedParam);
} else if (namedParam.equals("delete")) {