[Tutorial] Scoreboards/Teams with the Bukkit API

Discussion in 'Resources' started by chasechocolate, Apr 5, 2013.

Thread Status:
Not open for further replies.
  1. Offline

    stirante

    You should move it to onEnable method.
     
  2. Offline

    vYN

    I guess there is no way to change the view distance on "DisplaySlot.BELOW_NAME"......(It's set to 10blocks..)
     
  3. Offline

    crushh87

    chasechocolate do you think putting a clock on a scoreboard would cause a lot of lag?
     
  4. Offline

    chasechocolate

    I have actually seen someone do this (before it came out in the Bukkit API, so with packets and NMS code) and it worked fine with no lag. But you may want to test it out and see what you think, because I have never tried it with the new API.
     
  5. Offline

    crushh87

    I will have to see, I test it and get back to ya.
     
  6. Offline

    devilquak

    crushh87

    I made a Turret plugin that shoots arrows and other entities quite rapidly, and I used a scoreboard as an HUD for the ammo count. It updated every shot, of which there were at least 5 per second, perfectly and without lagging, so I don't think a clock should be a problem.
     
  7. Offline

    stuntguy3000

    @chasechocolate

    I started to try and use the code today..nothing appeared to work. I don't think i am doing any of it right. Could you provide a example on how to display numbers from a config? Thanks!
     
  8. Offline

    sablednah

    I'm trying to get a different DisplayName for each players objective (much requested health bars for MobHealth).

    But I've worked out that when you set an scoreboard+objective for a player - that player sees that objective for all other players. In other words on my test - everyone sees their own health above the OTHER players heads!

    Most confusing.. can anyone give me some pointers as to the best way to handle a custom Displayed name above each player?
     
  9. Offline

    CreeperShift

    I've been trying to wrap my head around this:

    I'm working on a clan plugin, it automatically puts the clans name into the prefix, with a certain color based on being hostile, allied or neutral. Now the obvious problem is showing the prefix of the player in red (hostile) to hostile players, green (allied) to allied players and orange (neutral) to neutral players.

    Is there any way this can be done? Could I create multiple scoreboards and have the player be a member of 3 of them and simply displaying the correct one for the player that looks at him?
    Or could I somehow send different players different prefixes?


    EDIT: Nevermind, did it using packets.

    However, for some reason the ScoreBoard doesn't persist through restarts :S I remember when I made Scoreboards via CraftBukkit they would persist :S
     
  10. Offline

    confuserr

    Is there any way to make it so they aren't ordered by ascending score value ? Or is that done client side?
     
  11. Offline

    stuntguy3000

    Anyone?
     
  12. Offline

    PixelatedTNT

    Right, I was the scoreboard tutorial and had a few attempts at it, but there was one thing that I couldn't figure out how to do. I wanted to make a Scoreboard Called "Stats" with 2 fields called "Kills" and "Deaths". Something like this:

    [​IMG]

    That is a scoreboard on a different server, those are my Kills and Deaths stats. So each player has a scoreboard like that shown to them, but have different numbers. Each stat shows "0" when the player first joins the server. I was wondering if you could help me make this, because every attempt I had, I couldn't add 2 fields to one scoreboard.

    Sure It's possible, you just have to create 2 scoreboards, whack in your objectives. The set 1 scoreboard to "DisplaySlot.BELOW_NAME" and the other scoreboard to "DisplaySlot.SIDEBAR".

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Oct 30, 2015
  13. Offline

    Rockslide

    @chasechocolate

    I partially got your health example to work, but for some reason it always says 0 / 20. Even after a player is damaged, it stays at 0. What am I missing?

    My code:
    Code:
            healthBoard = plugin.getServer().getScoreboardManager().getNewScoreboard();
            healthBoard.registerNewObjective("showhealth", "health");
            Objective objective = healthBoard.getObjective("showhealth");
            objective.setDisplaySlot(DisplaySlot.BELOW_NAME);
            objective.setDisplayName("/ 20");
    
    Somewhere else:
    Code:
                player.setScoreboard(battlefield.healthBoard);
    
    Edit: Forgot to mention, it doesn't produce any errors.
     
  14. Offline

    Rprrr

    Has anyone found a proper way to use teams? In my opinion, using this feature is a pain. Using NMS-packets might even be easier.. Team tags are incredibly buggy and it is unclear how one should use them.

    Or they show the wrong tag to the wrong player, or they don't pop up at all, or they don't update, or they even crash your Minecraft client... If anyone knows how to use this properly, chasechocolate perhaps, please post some code.

    I will post my, not working, code here, anyway (this crashes all clients on the server when I try to create a new team and add players to it, and fails to show team prefixes / suffixes):

    Code:
    public static void updateTag(Player p){
         
            ScoreboardManager manager = Bukkit.getScoreboardManager();
         
            Scoreboard board = manager.getMainScoreboard();     
         
            if (!(TeamManager.getTeam(p) > 0)){             
                 
                if (board.getPlayerTeam(p) !=null){             
                    Team playerTeam = board.getPlayerTeam(p);
                 
                    playerTeam.removePlayer(p);
                }
                             
                return;
                         
            } 
         
            int teamID = getTeam(p);
         
            String teamName = getTeamName(teamID);
         
            if (board.getTeam(teamName) !=null){
             
                Team team = board.getTeam(teamName);
             
                if (!team.getPlayers().contains(p)){
                    team.addPlayer(p);
                } 
             
                for (Player onlinePlayer : Bukkit.getOnlinePlayers()){
                    onlinePlayer.setScoreboard(board);
                }
             
                return;
            }
         
             
            Team team = board.registerNewTeam(teamName);
             
            team.setDisplayName(teamName);         
            team.setPrefix(ChatColor.RED + "[" + ChatColor.GRAY + teamName + ChatColor.RED + "]");
            team.setSuffix(ChatColor.RED + "<>");     
            team.setAllowFriendlyFire(false);
         
            team.addPlayer(p);
         
            for (Player onlinePlayer : Bukkit.getOnlinePlayers()){
                onlinePlayer.setScoreboard(board);
            }
         
            return;
             
        }
     
  15. Offline

    PHILLIPS_71

    chasechocolate
    I have got a scoreboard but it will not appear for some reason i'm getting no errors at all i'm so confused.

    Code:
        @EventHandler
        public void onJoin(PlayerJoinEvent event) {
            showScoreboard(event.getPlayer());
        }
     
        public void onEnable() {
            getServer().getPluginManager().registerEvents(this, this);
     
            for(Player current : Bukkit.getOnlinePlayers()) {
                showScoreboard(current);
            }
        }
     
        public void showScoreboard(Player player) {
            ScoreboardManager manager = Bukkit.getScoreboardManager();
            Scoreboard board = manager.getNewScoreboard();
            player.setScoreboard(board);
     
            Objective objective = board.registerNewObjective("test", "totalKillCount");
            objective.setDisplaySlot(DisplaySlot.SIDEBAR);
            objective.setDisplayName("ScoreBoard");
            Score score = objective.getScore(Bukkit.getOfflinePlayer(ChatColor.GREEN + "Kills:"));
            score.setScore(1);
        }
     
  16. Offline

    HackintoshMan

    chasechocolate

    1) Could I use the scoreboard API to just mange teams, but leave the scores alone and not display a scoreboard?

    2) Is it possible to have a scoreboard that shows all of the players on the server along with their kills and deaths?
     
  17. Offline

    finalblade1234

    Hey, how do i set the sidebar to a something.
    like to the side bar equals:
    <>--[FinalCraft]--<>
    - Survival
    - Creative
    - BlaBlaBla..
     
  18. Offline

    HackintoshMan

    I am getting that same error too. (Call me stupid is you wish:( ) I tried to move
    Code:
    Scoreboard board = manager.getNewScoreboard();
    to onEnable() but I didn't do anything…:(
     
  19. Offline

    funbob10

    that is because your manager is null. Put the manager initialization in the onEnable.

    Code:
    public ScoreboardManager manager = null;
    public Scoreboard board = null;
    public void onEnable() {
        try {
            manager = Bukkit.getScoreboardManager();
        } catch (Exception e) {
            e.printStackTrace();
        }
     
        board = manager.getNewScoreboard();
    }
    (I would not trust to directly compile this code, for I wrote it off the top of my head in < four minutes)
     
  20. Offline

    sablednah

    Found a bug via my helpful plugin users :)

    Setting a villager name longer than 32 works until you right click. Looks like the Trading GUI doesn't like it.
    Code:
    Internal exception: java.io.IOException: Received string length longer than maximum allowed (40 > 32)
    I'm filing a bukkit ticket now :)
     
  21. Offline

    funbob10

    I believe that cannot be fixed because the packet size will not carry a string longer than 32 characters, and we wont be able to increase the packet size without the clients not being too happy about it.
     
  22. Offline

    sablednah

    Yeah - i know client can't handle it fullstop. Answer is to trim it before sending - or (and i don't like this option :( ) limit custom mob names to 32 as well...
     
  23. Offline

    HackintoshMan

    I did not work. I get the same error. Here is my new code:

    Code:java
    1.  
    2. public class MCFTF2 extends JavaPlugin implements Listener {
    3.  
    4. public String PREFIX = ChatColor.GREEN + "" + ChatColor.BOLD + "[MCFTF2] "
    5. + ChatColor.AQUA;
    6. public static int redScore = 0;
    7. public static int blueScore = 0;
    8. public static int gameTime;
    9. public boolean isCTF;
    10. public static ScoreboardManager manager = Bukkit.getScoreboardManager();
    11. public static Scoreboard board = manager.getNewScoreboard(); *****(LINE 31)*****
    12. public static Team red = board.registerNewTeam("Red");
    13. public static Team blue = board.registerNewTeam("Blue");
    14.  
    15. @Override
    16. public void onEnable() {
    17.  
    18. try {
    19. manager = Bukkit.getScoreboardManager();
    20. } catch (Exception e) {
    21. e.printStackTrace();
    22. System.out.print("bla");
    23. }
    24.  
    25.  
    26. board = manager.getNewScoreboard();
    27.  
    28. red.setAllowFriendlyFire(false);
    29. blue.setAllowFriendlyFire(false);
    30.  
    31. System.out.println("[MCFTF2] Loading config...");
    32.  
    33. loadConfig();
    34.  


    Here is the error:

    Code:
    21:38:14 [SEVERE] Could not load 'plugins/MCFTF2.jar' in folder 'plugins'
    org.bukkit.plugin.InvalidPluginException: java.lang.ExceptionInInitializerError
        at org.bukkit.plugin.java.JavaPluginLoader.loadPlugin(JavaPluginLoader.java:184)
        at org.bukkit.plugin.SimplePluginManager.loadPlugin(SimplePluginManager.java:305)
        at org.bukkit.plugin.SimplePluginManager.loadPlugins(SimplePluginManager.java:230)
        at org.bukkit.craftbukkit.v1_5_R2.CraftServer.loadPlugins(CraftServer.java:239)
        at org.bukkit.craftbukkit.v1_5_R2.CraftServer.<init>(CraftServer.java:217)
        at net.minecraft.server.v1_5_R2.PlayerList.<init>(PlayerList.java:55)
        at net.minecraft.server.v1_5_R2.DedicatedPlayerList.<init>(SourceFile:11)
        at net.minecraft.server.v1_5_R2.DedicatedServer.init(DedicatedServer.java:105)
        at net.minecraft.server.v1_5_R2.MinecraftServer.run(MinecraftServer.java:381)
        at net.minecraft.server.v1_5_R2.ThreadServerApplication.run(SourceFile:573)
    Caused by: java.lang.ExceptionInInitializerError
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:249)
        at org.bukkit.plugin.java.JavaPluginLoader.loadPlugin(JavaPluginLoader.java:173)
        ... 9 more
    Caused by: java.lang.NullPointerException
        at com.hackintoshman.mcftf2.MCFTF2.<clinit>(MCFTF2.java:31)
        ... 12 more
    
     
  24. Offline

    funbob10

    here, try this instead (still have not took the time to test this code...)
    Also, I removed all the static calls because they are unsafe, and the reason I set ScoreboardManager, Scoreboard, and the Teams to private and gave them a getter is so another plugin wouldnt just hook onto your plugin and alter the teams. Furthermore, if you want to call something from another class statically, I added a static instance var that you can call from other classes like so
    Code:
    // This will get the scoreboard declared on MCFTF2 as long as the MCFTF2 class is imported
    MCFTF2.instance.getScoreboard();
    Code:
    public class MCFTF2 extends JavaPlugin implements Listener {
     
        public static MCFTF2 instance;
     
        public String PREFIX = ChatColor.GREEN + "" + ChatColor.BOLD + "[MCFTF2] " + ChatColor.AQUA;
        public int redScore = 0;
        public int blueScore = 0;
        public int gameTime;
        public boolean isCTF;
     
        private ScoreboardManager manager = null;
        private Scoreboard        board  = null;
        private Team              red    = null;
        private Team              blue    = null;
     
        @Override
        public void onEnable() {
            instance = this;
     
            manager = Bukkit.getScoreboardManager();
            board  = manager.getNewScoreboard();
         
            red  = board.registerNewTeam("Red");
            blue  = board.registerNewTeam("Blue");
         
            red.setAllowFriendlyFire(false);
            blue.setAllowFriendlyFire(false);
         
            System.out.println("[MCFTF2] Loading config...");
            loadConfig();
        }
     
        /**
        *
        * @return returns MCFTF2's ScoreboardManager
        */
        public ScoreboardManager getScoreboardManager() {
            return this.manager;
        }
     
        /**
        *
        * @return returns MCFTF2's generic board
        */
        public Scoreboard getScoreboard() {
            return this.board;
        }
     
        /**
        * Gets the team specified by the teamName paramater.
        */
        public Team getTeam(String teamName) {
            if (teamName.equalsIgnoreCase(this.red.getName()))
                return this.red;
            else if (teamName.equalsIgnoreCase(this.blue.getName()))
                return this.blue;
         
            return null;
        }
        public Team getRedTeam() {
            return this.red;
        }
        public Team getBlueTeam() {
            return this.blue;
        }
    }
     
  25. Offline

    sablednah

    I've done my own little fix for this - in PlayerInteractEntityEvent i look for right clicks on villagers - check if custom name is set and if its over 32 chars - and if so truncate it - and then set a scheduleSyncDelayedTask to put the full name back a tick later.

    Not elegant - but it works.
     
  26. Offline

    armbot1000

    is there a way to change where it says the health like 18/20 to a word?
     
  27. Offline

    chasechocolate

    Not fully sure what you mean, but you can change the objective name, however the value (or score) has to be an integer.
     
  28. Offline

    armbot1000

    like say i want it to say my name for example

    Armbot
    Founder

    above a players head saying there rank

    So if you look at the name above my head it will be white but it will say my rank bellow it

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Oct 30, 2015
  29. Offline

    chasechocolate

    armbot1000 You can, although you will also have to show an integer value (afaik).
    Code:java
    1. ScoreboardManager manager = Bukkit.getScoreboardManager();
    2. Scoreboard board = manager.getNewScoreboard();
    3. board.registerNewObjective("showhealth", "health");
    4.  
    5. Objective objective = board.getObjective("showhealth");
    6. objective.setDisplaySlot(DisplaySlot.BELOW_NAME);
    7. objective.setDisplayName(ChatColor.RED + "Founder");
    8.  
    9. for(Player online : Bukkit.getOnlinePlayers()){
    10. online.setScoreboard(board);
    11. }

    This will show up with "0 Founder" under players names.
     
  30. Offline

    HackintoshMan

    I keep getting an NPE. I cave no idea how to fix it. The other helper tried to help but his method did not work. here is my code.
    Code:java
    1. package com.hackintoshman.mcftf2;
    2.  
    3. import java.io.File;
    4.  
    5. import org.bukkit.Bukkit;
    6. import org.bukkit.ChatColor;
    7. import org.bukkit.entity.Player;
    8. import org.bukkit.event.EventHandler;
    9. import org.bukkit.event.EventPriority;
    10. import org.bukkit.event.Listener;
    11. import org.bukkit.event.entity.PlayerDeathEvent;
    12. import org.bukkit.event.player.PlayerJoinEvent;
    13. import org.bukkit.event.player.PlayerQuitEvent;
    14. import org.bukkit.event.player.PlayerRespawnEvent;
    15. import org.bukkit.inventory.ItemStack;
    16. import org.bukkit.plugin.java.JavaPlugin;
    17. import org.bukkit.scoreboard.Scoreboard;
    18. import org.bukkit.scoreboard.ScoreboardManager;
    19. import org.bukkit.scoreboard.Team;
    20.  
    21. import com.hackintoshman.mcftf2.commands.CommandKD;
    22. import com.hackintoshman.mcftf2.commands.CommandSetPoints;
    23. import com.hackintoshman.mcftf2.commands.CommandTeam;
    24.  
    25. public class MCFTF2 extends JavaPlugin implements Listener {
    26.  
    27. public String PREFIX = ChatColor.GREEN + "" + ChatColor.BOLD + "[MCFTF2] "
    28. + ChatColor.AQUA;
    29. public int redScore = 0;
    30. public int blueScore = 0;
    31. public int gameTime;
    32. public boolean isCTF;
    33. public ScoreboardManager manager = Bukkit.getScoreboardManager();
    34. public Scoreboard board = manager.getNewScoreboard();
    35. public Team red = board.registerNewTeam("Red");
    36. public Team blue = board.registerNewTeam("Blue");
    37.  
    38. @Override
    39. public void onEnable() {
    40.  
    41. manager = Bukkit.getScoreboardManager();
    42. board = manager.getNewScoreboard();
    43. red = board.registerNewTeam("Red");
    44. blue = board.registerNewTeam("Blue");
    45.  
    46. red.setAllowFriendlyFire(false);
    47. blue.setAllowFriendlyFire(false);
    48.  
    49. System.out.println("[MCFTF2] Loading config...");
    50. loadConfig();
    51.  
    52. getCommand("kd").setExecutor(new CommandKD(this));
    53. getCommand("setpoint").setExecutor(new CommandSetPoints(this));
    54. getCommand("team").setExecutor(new CommandTeam(this));
    55.  
    56. getServer().getPluginManager().registerEvents(new CaptureTheFlagHandler(this), this);
    57. getServer().getPluginManager().registerEvents(this, this);
    58. }


    here is my error that I get.

    Code:
    21:51:22 [INFO] This server is running CraftBukkit version git-Bukkit-1.5.1-R0.1-21-g49b0699-b2754jnks (MC: 1.5.1) (Implementing API version 1.5.1-R0.2)
    21:51:22 [SEVERE] Could not load 'plugins/MCFTF2.jar' in folder 'plugins'
    org.bukkit.plugin.InvalidPluginException: java.lang.NullPointerException
    at org.bukkit.plugin.java.JavaPluginLoader.loadPlugin(JavaPluginLoader.java:182)
    at org.bukkit.plugin.SimplePluginManager.loadPlugin(SimplePluginManager.java:305)
    at org.bukkit.plugin.SimplePluginManager.loadPlugins(SimplePluginManager.java:230)
    at org.bukkit.craftbukkit.v1_5_R2.CraftServer.loadPlugins(CraftServer.java:239)
    at org.bukkit.craftbukkit.v1_5_R2.CraftServer.<init>(CraftServer.java:217)
    at net.minecraft.server.v1_5_R2.PlayerList.<init>(PlayerList.java:55)
    at net.minecraft.server.v1_5_R2.DedicatedPlayerList.<init>(SourceFile:11)
    at net.minecraft.server.v1_5_R2.DedicatedServer.init(DedicatedServer.java:105)
    at net.minecraft.server.v1_5_R2.MinecraftServer.run(MinecraftServer.java:381)
    at net.minecraft.server.v1_5_R2.ThreadServerApplication.run(SourceFile:573)
    Caused by: java.lang.NullPointerException
    at com.hackintoshman.mcftf2.MCFTF2.<init>(MCFTF2.java:34)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at org.bukkit.plugin.java.JavaPluginLoader.loadPlugin(JavaPluginLoader.java:178)
    ... 9 more
    
     
Thread Status:
Not open for further replies.

Share This Page