[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

    surtic

    Thanks for your Tutorial!

    I get all the Time Null from "Bukkit.getScoreboardManager();" yes it is in onEnable() :/ is there a Problem with the new 1.5.1 R0.2 Beta Build?


    A bit Code of the Plugin
    Code:
        @Override
        public void onEnable() {
     
            try {
                Metrics metrics = new Metrics(this);
                metrics.start();
            } catch (IOException e) {
                // Failed to submit the stats :-(
            }
     
            // Commands
            setupGameCommands();
            if ( getConfig().getBoolean("Settings.Teams.Active") ) {
                setupTeamCommands();
            }
     
            // Listener
            new UHCGListener();
     
            setupRecipes();
     
            // Start ScoreboardTask
            ScoreboardManager scoreboardManager =  Bukkit.getScoreboardManager();
     
     
            if ( scoreboardManager == null ) {
                getLogger().info("is Null");
            }
     
            //getServer().getScheduler().runTaskTimer(this, new UpdateScoreboardTask( scoreboardManager ), 40L, 40L);
     
     
     
     
     
            getLogger().info("enabled");
        }
    Edit: I had found the Problem :) my Plugin is onEnabled before a World is loaded then i add new Populators and some stuff to the World.

    Now it works.
     
  2. Offline

    HackintoshMan

    how did you make it work? I keep getting an NPE when I start the server. After I reload it i don't get the NPE.
     
  3. Offline

    funbob10


    please, take a second to compare your code with the one I sent.

    Yours:
    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 int redScore = 0;
    7. public int blueScore = 0;
    8. public int gameTime;
    9. public boolean isCTF;
    10. public ScoreboardManager manager = Bukkit.getScoreboardManager();
    11. public Scoreboard board = manager.getNewScoreboard();
    12. public Team red = board.registerNewTeam("Red");
    13. public Team blue = board.registerNewTeam("Blue");
    14.  
    15. @Override
    16. public void onEnable() {
    17.  
    18. manager = Bukkit.getScoreboardManager();
    19. board = manager.getNewScoreboard();
    20. red = board.registerNewTeam("Red");
    21. blue = board.registerNewTeam("Blue");
    22.  
    23. red.setAllowFriendlyFire(false);
    24. blue.setAllowFriendlyFire(false);
    25.  
    26. System.out.println("[MCFTF2] Loading config...");
    27. loadConfig();
    28.  
    29. getCommand("kd").setExecutor(new CommandKD(this));
    30. getCommand("setpoint").setExecutor(new CommandSetPoints(this));
    31. getCommand("team").setExecutor(new CommandTeam(this));
    32.  
    33. getServer().getPluginManager().registerEvents(new CaptureTheFlagHandler(this), this);
    34. getServer().getPluginManager().registerEvents(this, this);
    35. }


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


    Now again, here is the problem with yours. If you look at the variables, you are initializing them before the onEnable but instead when the file gets loaded, which means it is before bukkit actually initialized the ScoreboardManager, creating the NPE. Now, to fix this all you have to do is change the variable creations to null, and instead initialize in the onEnable.


    That is because if you look at his, the manager gets not only created but initialized in the onEnable, meaning that it does actually exist in bukkit.

    Ask if you need further clarification, but I honestly do not see what I could clarify further without getting into how Java works...
     
  4. chasechocolate thanks for the great tutorial!

    Just one question remaining, how can I display scoreboards to individual players, so that only the defined player can see the defined stats and not everyone?

    I want to display players their mana and spell cooldowns, but currently it shows them for everybody.

    https://gist.github.com/Silthus/fdd035728cd84ec7f30d

    The method update is called everytime the resource changes (e.g. mana).

    I only have the resource Mana in this example and two other players with the other resources are online.

    http://i.imgur.com/bZtOH5N.jpg
     
  5. Offline

    chasechocolate

    silthus I would create a HashMap<String, Scoreboard> and update each player's board from there.
     
  6. Thanks that works now, but when I now want to display the health above the head in always shows 0 as score.
     
  7. Offline

    chasechocolate

    That sometimes happens, I'm not sure if it is a Minecraft bug or not, but I think the player has to be damaged or regenerate health for the scoreboard to update.
     
  8. Offline

    Ba7marker

    Hi thanks for the tutorial it helped me with the basic idea of scoreboards, however the scoreboard shows fine but i'm wondering how i can add a number to one of my objectives. I just want to make a baisc kill and death scoreboard by adding the current value to 1. This is my current code(im using PlayerDeathEvent for checking if player has died and who killed them):
    Code:
    package me.weecazza7.test;
     
     
    import org.bukkit.Bukkit;
    import org.bukkit.command.defaults.KillCommand;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.entity.PlayerDeathEvent;
    import org.bukkit.event.player.PlayerJoinEvent;
    import org.bukkit.scoreboard.DisplaySlot;
    import org.bukkit.scoreboard.Objective;
    import org.bukkit.scoreboard.Score;
    import org.bukkit.scoreboard.Scoreboard;
    import org.bukkit.scoreboard.ScoreboardManager;
     
    public class OnJoinEventListener implements Listener{
        @EventHandler
        public void onJoin(PlayerJoinEvent event){
            Player p = event.getPlayer();
            showScoreboard(p);
                }
       
        @EventHandler
        public void PlayerDeathEvent(PlayerDeathEvent e){
            Player p = e.getEntity().getPlayer();
            Player k = e.getEntity().getKiller();
            if(p.isDead()){
               
                }
            }
        public void showScoreboard(Player player) {
            ScoreboardManager manager = Bukkit.getScoreboardManager();
            Scoreboard board = manager.getNewScoreboard();
            Objective objective = board.registerNewObjective("test", "dummy");
            objective.setDisplaySlot(DisplaySlot.SIDEBAR);
            objective.setDisplayName(" §bYour Stats ");
           
            Score kills = objective.getScore(Bukkit.getOfflinePlayer("Kills"));
            Score deaths = objective.getScore(Bukkit.getOfflinePlayer("Deaths"));
            player.setScoreboard(board);
            deaths.setScore(1);
            kills.setScore(1);
            deaths.setScore(0);
            kills.setScore(0);
        }
     
        }
     
  9. Offline

    surtic

    I had already a Task for Update the Player Health so run it 20secs later so the World is Loaded.
     
  10. Offline

    chasechocolate

    imjack16 there's two ways you could do this. The first one would be to create multiple HashMap and save a player's kills and deaths there. The second one would be to register a kills objective with the criteria of Minecraft's built-in kill/death counter. Example:
    Code:java
    1. Objective kills = board.registerNewObjective("kills", "playerKillCount");
    2. Objective deaths = board.registerNewObjective("deaths", "deathCount");
     
  11. Offline

    HackintoshMan


    Thank you so much! That makes so much sense now.
     
  12. Offline

    TheE

    Am I wrong, or is the score of a certain scoreboard only visible for players that hold this scoreboard? If so, is there anything I can do so the score is visible for all players, even those that do not hold the corresponding scoreboard?

    I am tracking player's health during arena PvP fights and want to make it visible for viewers too (which was possible in TagAPI that I used until now).
     
  13. Offline

    surtic

    Yes you need to set the Scoreboard also for the Viewers. But you don't need to add a Player to the Scoreboard :)

    Code:
    // Only for the Players in the Arena
    Score score = objective.getScore(player);
    score.setScore( player.getHealth() );
     
     
    // This for your Viewers
    player.setScoreboard( scoreboard );
    
     
  14. chasechocolate

    Is there a nice way to display custom info for each player on the sidebar; eg player stats. And display a team prefix that changes with a player stat change; like player level.

    I can get the custom stats working per player, but when I try to fix the team to something like:
    [lvl 10] Bob
    when the player levels up, nothing happens.

    Been playing around with it for a few days and pretty much banging my head on the desk now :)
     
  15. Offline

    NetFusion

    Hello... i have code a Scoreboard for a snowball plugin. but if the User leave the game, the Screboard doesn´t disable..
    how i must code this...

    MFG Trax
     
  16. Offline

    funbob10

    define in more detail what you want to do. Do you want him to be removed from the scoreboard or completely remove the scoreboard?
     
  17. Offline

    NetFusion

    Hi sorry i want to remove the (display) sidebar when the player leave the fight Arena. also remove the player form the scoreboard, :)
     
  18. Offline

    GWarBand

    Code:
    ScoreboardManager manager = Bukkit.getScoreboardManager();
    Scoreboard board = manager.getNewScoreboard();
    Objective below_name = board.registerNewObjective("title", "dummy");
    below_name.setDisplaySlot(DisplaySlot.BELOW_NAME);
    below_name.setDisplayName(ChatColor.GOLD + "King");
    Hi, how can I change the number before "King" ? (e.g. Level)
    Can I implement my own Criteria? Like this?
    Code:
    package net.minecraft.server.v1_5_R2;
     
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
     
    public interface IScoreboardCriteria {
     
        Map a = new HashMap();
        IScoreboardCriteria b = new ScoreboardBaseCriteria("dummy");
        IScoreboardCriteria c = new ScoreboardBaseCriteria("deathCount");
        IScoreboardCriteria d = new ScoreboardBaseCriteria("playerKillCount");
        IScoreboardCriteria e = new ScoreboardBaseCriteria("totalKillCount");
        IScoreboardCriteria f = new ScoreboardHealthCriteria("health");
        IScoreboardCriteria g = new ScoreboardBaseCriteria("level");
     
        String getName();
     
        int getScoreModifier(List list);
     
        boolean isReadOnly();
     
    }
     
  19. Offline

    Devix

    chasechocolate Do you think it would be possible to display someones health and faction name above someones head? If it's possible, how would I go about doing it?

    Thanks! :)
     
  20. Offline

    chasechocolate

    You can display their health (see my example in the OP), but I'm not sure about the faction name, because you can only add one line. However, you could create a team and make the prefix or suffix have the faction name.
     
  21. Offline

    Devix

  22. Offline

    Quaro

    How to set two updatable scoreboards: SIDEBAR and BELOWNAME in the same time? (Because it dissapears when im trying to use another)

    [Give example please]
     
  23. i am having the same issue
     
  24. Offline

    TheE

    I might miss something, but wouldn't this still create scores for all players that hold the scoreboard, so every player has his health displayed under his name, even if he is not fighting? I was hoping for some way to show a score that is only hold by two players for all players on the server, but this does not seem to be possible(?).
     
  25. Offline

    surtic

    No you only need to make a Score for the Players who are in the Arena. And the Scoreboard you add all Players who need to see the Score.

    I had implemented something similar to yours. I had make a UltraHardcore Plugin where Spectators join the Game and only see the Health of the Players but the Spectators Health is not displayed.

    Here a bit of my Code:
    Code:
    for ( Team team : plugin.getTeams() ) {
      for ( Player player : team.getMembers() ) {
        Score score = objective.getScore(player);
        score.setScore( player.getHealth() );
      }
    }
     
    for ( Player player : plugin.getServer().getOnlinePlayers() ) {
      player.setScoreboard( scoreboard );
    }
    
     
  26. Offline

    TheE

    surtic
    I still cannot get it to work like I would. In my case, players 'in the arena' have the correct score, other players have a score of 0. Could you have a look at the following code to see where I am doing something differently than you?

    Code:java
    1. package me.thee.scoretest;
    2.  
    3. import org.bukkit.Bukkit;
    4. import org.bukkit.ChatColor;
    5. import org.bukkit.command.Command;
    6. import org.bukkit.command.CommandSender;
    7. import org.bukkit.entity.Player;
    8. import org.bukkit.plugin.java.JavaPlugin;
    9. import org.bukkit.scoreboard.DisplaySlot;
    10. import org.bukkit.scoreboard.Objective;
    11. import org.bukkit.scoreboard.Score;
    12. import org.bukkit.scoreboard.Scoreboard;
    13.  
    14. public class ScoreTest extends JavaPlugin {
    15.  
    16. private Scoreboard board = Bukkit.getScoreboardManager().getNewScoreboard();
    17. private Objective objective;
    18.  
    19. @Override
    20. public void onEnable() {
    21. objective = board.registerNewObjective("ScoreTest", "dummy");
    22. objective.setDisplaySlot(DisplaySlot.BELOW_NAME);
    23. objective.setDisplayName(ChatColor.RED + "❤");
    24. }
    25.  
    26. // players specified here should be visible for everyone with the custom score.
    27. // Any other player should not have any score associated with him.
    28.  
    29. @Override
    30. public boolean onCommand(CommandSender sender, Command command,
    31. String commandLabel, String[] args) {
    32. if (!command.getName().equals("score")) {
    33. return false;
    34. }
    35. for (Player player : getServer().getOnlinePlayers()) {
    36. player.setScoreboard(board);
    37. }
    38.  
    39. for (String playerName : args) {
    40. Player player = getServer().getPlayer(playerName);
    41. Score score = objective.getScore(player);
    42. score.setScore(player.getHealth());
    43. }
    44. return true;
    45. }
    46. }
     
  27. Offline

    fkfabian

    Can you send me a example ?
     
  28. How can I display the health below players AND set individual scoreboards for each player?
    My scenario is as follows:

    Each player should have a scoreboard on the side which shows his current mana, currency and so on. Additional to that the health should be displayed below the player names.

    The problem is that I can only get them working one at a time and not at the same time. When I set the health below the players I get the mana and currency of a random player on the side. When I use the currency/mana scoreboard the health below the names is always 0.
     
  29. Offline

    ScottGambler

    Heyho. I don't know if i'm doing it wrong but in my case, it displays below every player-name the wrong PlayerHealth. If I use your code:

    Code:
    ScoreboardManager manager =  Bukkit.getScoreboardManager();
     
    org.bukkit.scoreboard.Scoreboard board = manager.getNewScoreboard();
     
            board.registerNewObjective("showhealth", "health");
     
           
     
            Objective objective = board.getObjective("showhealth");
     
            objective.setDisplaySlot(DisplaySlot.BELOW_NAME);
     
            objective.setDisplayName("/20 §d❤");
     
            for(Player online : Bukkit.getOnlinePlayers()){
     
               
     
              online.setScoreboard(board);
     
     
     
            }
    It displays the player-health as 0. I don't know what's in this code wrong but it won't work. Sometimes, it is just displaying the correct health below the name of one User, but the other user's playerhealth is wrong. I tried it already with a few events and i think there is a little fail in the code.

    Hope anyone can help me :)
     
  30. Offline

    xXSniperzzXx_SD

    Does anyone else have problems getting the sidebar display to work? I can get the player list to work, but i'm unable to get the sidebar to even show...
     
Thread Status:
Not open for further replies.

Share This Page