Ender_Coder
Ender_Coder

Reputation: 45

Bukkit ScoreBoard Acting Weird

I have a score board like so :

int time = 15;

private ScoreboardManager sbManager;
private Scoreboard scoreBoard; 
private Objective obj;

private Score s0;

public void init(Player player) {
    sbManager = Bukkit.getScoreboardManager();
    scoreBoard = sbManager.getNewScoreboard();

    obj = scoreBoard.registerNewObjective("ScoreBoard", "dummy");

    obj.setDisplaySlot(DisplaySlot.SIDEBAR);
    obj.setDisplayName("Test");

    s0 = obj.getScore(Bukkit.getOfflinePlayer("Time = " + time));

    s0.setScore(6);

    player.setScoreboard(scoreBoard);

    Bukkit.getScheduler().scheduleSyncRepeatingTask(this, new Runnable(){

        public void run() {
            time--;
            updateScoreBoard(player);
            System.out.println(time);
        }

    },20, 20);
}

And whenever I try to update it, it just dosen't work and btw my score board is a "fancy" one, so it should look like : Time = time 6 <- the '6' is the default minecraft score.

Here's an example of my update method:

public void updateScoreBoard(Player p){ 

    s0 = obj.getScore(Bukkit.getOfflinePlayer("Time =" + time));

    s0.setScore(6);

    p.setScoreboard(scoreBoard);
}

Upvotes: 1

Views: 568

Answers (1)

Adrian Sohn
Adrian Sohn

Reputation: 1271

Because you're using scoreboards in an unconventional way, things are bound to get tricky. By "fancy" I assume you mean the scoreboards which display a score's name and value right next to each other on the left side, which is done by placing the actual score value inside the name String of the score (like you have already done).

The problem with your code specifically is that you are not actually changing the value of the existing score entry (since that value is set to 6 to keep the entry in the same row of the display) but creating a new score entry every time you update the display, since score entries are identified by their name and not their score value (this is required so that different score entries can have the same value, for example a player can have a "bank balance" score with a value of 2 and an "amount of deaths" score with a value of 2).

If this weren't the case for example, your new score entry with name "Time = 14" and a score value of 6 would override the previous score entry with name "Time = 15" because of the identical score value, but this is not the case.

When I tested your code snippet, more rows (score entries) were added until the display filled to maximum capacity. I can only assume this is what you meant by your code "acting weird" since you didn't elaborate on the expected and observed results of your code.

You'll want to remove the previous score entry with the outdated value. Because the API is not intended to be used this way, one cannot simply remove a score entry from an objective (resetting the score doesn't remove the entire entry).

You'll therefore need to create a new scoreboard with a new objective etc. every time you want to update a single "fancy" score entry. This also means that all scores displayed in the scoreboard need to be kept track of independently and re-added and re-set to the new scoreboard whenever any other "fancy" score is updated.

These changes to your updateScoreboard method did the trick for me:

public void updateScoreBoard(Player p) {

    scoreBoard = sbManager.getNewScoreboard();
    obj = scoreBoard.registerNewObjective("ScoreBoard", "dummy");

    obj.setDisplaySlot(DisplaySlot.SIDEBAR);
    obj.setDisplayName("Test");

    s0 = obj.getScore(Bukkit.getOfflinePlayer("Time = " + time));

    s0.setScore(6);

    p.setScoreboard(scoreBoard);
}

Note that this method only fixes the immediate issue of more entries being added, if you want more "fancy" and possibly even normal score entries, all of those will need to be handled respectively.

All this extra work and having meaningless numbers/values always on the right of the display seem like a large trade-off just to remove a little whitespace between a score's name and value.

Some other tips: You don't need to update the sbManager variable every time you initiate the scoreboard for a new player, the manager is always the same object, so using Bukkit.getScoreboardManager() once should suffice.

Upvotes: 1

Related Questions