diff --git a/src/main/java/net/citizensnpcs/commands/NPCCommands.java b/src/main/java/net/citizensnpcs/commands/NPCCommands.java index 39576f9fe..4b677a225 100644 --- a/src/main/java/net/citizensnpcs/commands/NPCCommands.java +++ b/src/main/java/net/citizensnpcs/commands/NPCCommands.java @@ -42,6 +42,7 @@ import net.citizensnpcs.trait.CurrentLocation; import net.citizensnpcs.trait.Gravity; import net.citizensnpcs.trait.HorseModifiers; import net.citizensnpcs.trait.LookClose; +import net.citizensnpcs.trait.NPCScoreboard; import net.citizensnpcs.trait.NPCSkeletonType; import net.citizensnpcs.trait.OcelotModifiers; import net.citizensnpcs.trait.Poses; @@ -79,6 +80,7 @@ import org.bukkit.entity.Player; import org.bukkit.entity.Skeleton.SkeletonType; import org.bukkit.entity.Villager.Profession; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; +import org.bukkit.metadata.MetadataValue; import org.bukkit.scoreboard.DisplaySlot; import org.bukkit.scoreboard.Objective; import org.bukkit.scoreboard.Scoreboard; @@ -270,7 +272,7 @@ public class NPCCommands { } CommandSenderCreateNPCEvent event = sender instanceof Player ? new PlayerCreateNPCEvent((Player) sender, copy) - : new CommandSenderCreateNPCEvent(sender, copy); + : new CommandSenderCreateNPCEvent(sender, copy); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) { event.getNPC().destroy(); @@ -346,7 +348,7 @@ public class NPCCommands { spawnLoc = args.getSenderLocation(); } CommandSenderCreateNPCEvent event = sender instanceof Player ? new PlayerCreateNPCEvent((Player) sender, npc) - : new CommandSenderCreateNPCEvent(sender, npc); + : new CommandSenderCreateNPCEvent(sender, npc); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) { npc.destroy(); @@ -1021,7 +1023,7 @@ public class NPCCommands { @Requirements(selected = true, ownership = true, types = { EntityType.CREEPER }) public void power(CommandContext args, CommandSender sender, NPC npc) { Messaging - .sendTr(sender, npc.getTrait(Powered.class).toggle() ? Messages.POWERED_SET : Messages.POWERED_STOPPED); + .sendTr(sender, npc.getTrait(Powered.class).toggle() ? Messages.POWERED_SET : Messages.POWERED_STOPPED); } @Command( @@ -1044,7 +1046,7 @@ public class NPCCommands { } @Command(aliases = { "npc" }, usage = "remove|rem (all|id|name)", desc = "Remove a NPC", modifiers = { "remove", - "rem" }, min = 1, max = 2) + "rem" }, min = 1, max = 2) @Requirements public void remove(final CommandContext args, final CommandSender sender, NPC npc) throws CommandException { if (args.argsLength() == 2) { @@ -1135,16 +1137,22 @@ public class NPCCommands { permission = "citizens.npc.scoreboard") @Requirements(selected = true, ownership = true, types = EntityType.PLAYER) public void scoreboard(CommandContext args, CommandSender sender, NPC npc) { - Scoreboard main = Bukkit.getScoreboardManager().getMainScoreboard(); - String objective = args.getString(1); - String criteria = args.getString(2); + Iterable itr = npc.getEntity().getMetadata("citizens.scoreboard"); + Scoreboard main; + if (!itr.iterator().hasNext()) { + main = Bukkit.getScoreboardManager().getNewScoreboard(); + } else { + main = (Scoreboard) itr.iterator().next().value(); + } + String objective = Colorizer.parseColors(args.getString(1)); + String criteria = Colorizer.parseColors(args.getString(2)); Objective obj = main.getObjective(objective); if (obj == null) { - obj = Bukkit.getScoreboardManager().getMainScoreboard().registerNewObjective(objective, criteria); + obj = main.registerNewObjective(objective, criteria); } Player entity = (Player) npc.getEntity(); if (args.hasValueFlag("team")) { - String team = args.getFlag("team"); + String team = Colorizer.parseColors(args.getFlag("team")); if (main.getPlayerTeam(entity) != null) main.getPlayerTeam(entity).removePlayer(entity); if (main.getTeam(team) == null) @@ -1157,6 +1165,7 @@ public class NPCCommands { if (args.hasValueFlag("score")) { obj.getScore(entity).setScore(args.getFlagInteger("score")); } + npc.getTrait(NPCScoreboard.class).persistObjective(obj); } @Command( diff --git a/src/main/java/net/citizensnpcs/npc/CitizensTraitFactory.java b/src/main/java/net/citizensnpcs/npc/CitizensTraitFactory.java index e548bebf2..11108c30e 100644 --- a/src/main/java/net/citizensnpcs/npc/CitizensTraitFactory.java +++ b/src/main/java/net/citizensnpcs/npc/CitizensTraitFactory.java @@ -24,6 +24,7 @@ import net.citizensnpcs.trait.CurrentLocation; import net.citizensnpcs.trait.Gravity; import net.citizensnpcs.trait.HorseModifiers; import net.citizensnpcs.trait.LookClose; +import net.citizensnpcs.trait.NPCScoreboard; import net.citizensnpcs.trait.NPCSkeletonType; import net.citizensnpcs.trait.OcelotModifiers; import net.citizensnpcs.trait.Poses; @@ -63,6 +64,7 @@ public class CitizensTraitFactory implements TraitFactory { registerTrait(TraitInfo.create(Powered.class).withName("powered")); registerTrait(TraitInfo.create(Saddle.class).withName("saddle")); registerTrait(TraitInfo.create(Sheared.class).withName("sheared")); + registerTrait(TraitInfo.create(NPCScoreboard.class).withName("npcscoreboard")); registerTrait(TraitInfo.create(NPCSkeletonType.class).withName("skeletontype")); registerTrait(TraitInfo.create(SlimeSize.class).withName("slimesize")); registerTrait(TraitInfo.create(Spawned.class).withName("spawned")); diff --git a/src/main/java/net/citizensnpcs/trait/NPCScoreboard.java b/src/main/java/net/citizensnpcs/trait/NPCScoreboard.java new file mode 100644 index 000000000..38d60c1ff --- /dev/null +++ b/src/main/java/net/citizensnpcs/trait/NPCScoreboard.java @@ -0,0 +1,107 @@ +package net.citizensnpcs.trait; + +import java.util.Set; + +import net.citizensnpcs.api.CitizensAPI; +import net.citizensnpcs.api.trait.Trait; +import net.citizensnpcs.api.util.DataKey; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.scoreboard.DisplaySlot; +import org.bukkit.scoreboard.Objective; +import org.bukkit.scoreboard.Scoreboard; +import org.bukkit.scoreboard.Team; + +public class NPCScoreboard extends Trait { + private Set objectives; + private Scoreboard scoreboard; + private String team; + + public NPCScoreboard() { + super("npcscoreboard"); + } + + private void checkScoreboard() { + if (scoreboard == null) { + if (npc.isSpawned() && !npc.getEntity().getMetadata("citizens.scoreboard").isEmpty()) { + scoreboard = (Scoreboard) npc.getEntity().getMetadata("citizens.scoreboard").iterator().next().value(); + } else { + scoreboard = Bukkit.getScoreboardManager().getNewScoreboard(); + } + } + if (npc.getEntity() instanceof Player && npc.getEntity().getMetadata("citizens.scoreboard").isEmpty()) { + npc.getEntity().setMetadata("citizens.scoreboard", + new FixedMetadataValue(CitizensAPI.getPlugin(), scoreboard)); + } + } + + @Override + public void load(DataKey root) { + checkScoreboard(); + if (root.keyExists("team")) { + team = root.getString("team"); + } + if (!root.keyExists("objectives")) + return; + for (DataKey sub : root.getRelative("objectives").getSubKeys()) { + String objName = sub.name(); + Objective objective; + if (scoreboard.getObjective(objName) != null) { + objective = scoreboard.getObjective(objName); + } else { + objective = scoreboard.registerNewObjective(objName, root.getString("criteria")); + } + objective.setDisplaySlot(DisplaySlot.valueOf(sub.getString("display"))); + objectives.add(objective); + if (npc.isSpawned() && npc.getEntity() instanceof Player) { + objective.getScore((Player) npc.getEntity()).setScore(sub.getInt("score")); + } + } + } + + @Override + public void onSpawn() { + if (npc.getEntity() instanceof Player && team != null) { + checkScoreboard(); + scoreboard.getTeam(team).addPlayer((Player) npc.getEntity()); + } + } + + public void persistObjective(Objective objective) { + if (!objectives.contains(objective)) { + objectives.add(objective); + } + Team playerTeam = objectives.iterator().next().getScoreboard().getPlayerTeam((Player) npc.getEntity()); + if (team == null) { + team = playerTeam.getName(); + } + if (scoreboard == null) { + scoreboard = objective.getScoreboard(); + } + } + + @Override + public void save(DataKey root) { + root.removeKey("objectives"); + root.removeKey("team"); + if (objectives.isEmpty()) { + return; + } + for (Objective objective : objectives) { + DataKey key = root.getRelative("objectives." + objective.getName()); + key.setString("criteria", objective.getCriteria()); + key.setString("display", objective.getDisplaySlot().name()); + if (npc.getEntity() instanceof Player) { + key.setInt("score", objective.getScore((Player) npc.getEntity()).getScore()); + } + } + if (npc.getEntity() instanceof Player && team == null) { + team = objectives.iterator().next().getScoreboard().getPlayerTeam((Player) npc.getEntity()).getName(); + } + if (team != null) { + root.setString("team", team); + } + } +} \ No newline at end of file