Individual Scoreboard for Different Players?

Discussion in 'Plugin Development' started by The__Master_Coder, May 3, 2014.

Thread Status:
Not open for further replies.
  1. Hello everyone, this is a continuation of another one of threads that is not being answered very well.
    Basically, I am trying to set a Player's scoreboard. On the scoreboard that I am creating, I am not using the scores to display the information, but, I am using the objectives. For example, what im trying to accomplish is: On the scoreboard an objective will say "Crystals" (my currency), then that score will be set to 2 for that objective. Under that objective there will be a new objective and it will say their amount of Crystals. I do this by naming the objective the int from their name in config. This is working almost perfectly except for a important issue. It will have the balance of EVERYBODY's Crystals under the objective "Crystals." I want the scoreboard to be different for each player. Can anybody help me?
    PLEASE NOTE: My actual score for my objectives are 1 and 2, so they can stay in order on the display of the scoreboard.

  2. Offline


    Naw naw naw, You can do it WAY different!
    1. Player.setScoreboard(Crystals);
  3. Offline


    First method that comes to mind is to create a separate scoreboard for every player and update the objectives on each of those individually. Use a Map of UUID or String to Scoreboard to hold the scoreboards.
  4. akabarblake, That is not what im trying to do.. I know how to set a scoreboard.

    coasterman10, How do you mean? Sorry i'm not very educated on UUID and Maps/Hashmaps
  5. Offline


    The__Master_Coder Maps are the traditional way to save data pertaining to individual player. Maps save a collection of objects, each accessible by a unique key. You can use this to have a Map with player UUIDs as keys to Scoreboards as values:
    1. Map<UUID, Scoreboard> scoreboardMap = new HashMap<UUID, Scoreboard>();

    Remember that Map is just an interface, and it needs an implementation (there are many different ways to implement a mapping system). Unless you have a specific reason to use something else, you will almost always be using HashMap. HashMaps use the hashCode() function of your key type to save the values in an array internally, making it also a very fast implementation. There is also a LinkedHashMap which is like a HashMap but uses a linked list instead of an array to store its values. It's slower to get items but stays in order when you loop through all the keys/values, more like a list.

    That aside, we can now store values in this Map. Map.put(K key, V value) (where K is the key type, and V is the value type) is the method you use to set values in a map. Each key can only have one value, so if you put an object under a key that already has a value, it will overwrite the existing object. Map.get(K key) will get the value for a key.

    Since you are using a map of UUIDs to Scoreboards, you can save the scoreboard for a player like so:
    1. Player player; // Some player object
    2. Scoreboard scoreboard; // Some scoreboard object
    4. scoreboardMap.put(player.getUniqueId(), scoreboard);

    Now, if we want to work with the scoreboard associated to a player, we just get the value for their UUID:
    1. Player player; // Some player object
    3. Scoreboard scoreboard = scoreboardMap.get(player.getUniqueId());

    This should be enough for you to start going.
  6. Offline


    Here's a great HashMap tutorial:
    You'd want the key to be the player's unique id (use player.getUniqueUUID() to retrieve), and a scoreboard as the value.
    HashMap<UUIDIntegerscoreboards = new HashMap<>();
    //the stuff between the triangle brackets are known as generics
    Player p //...
    Scoreboard scoreboard //...
    scoreboars.put(p.getUniqueId(), scoreboard);
    Or something of the sort.
  7. Offline


    I don't recommend storing that stuff in a config.yml, I recommend it as a MySQL database if you have a large amount of players, and then an variable of Crystals. (Separate way)
    So each player will get a separate scoreboard, and the code will get their certain amount of 'Crystals';
    MySQL would reach via more servers, A config.yml is separate for each plugin, unless you make a file OUTSIDE of it, like WorldEdit, and that is hard.
  8. coasterman10 Hey, I just can't seem to figure it out.. :( Still having the same issues. When I get more crystals it just adds that new amount to the scoreboard without erasing the old amount. And everyones balance is still on every scoreboard..
    Some of the new code I tried (With UUID) (Variables at top of my Class):

    2. private ScoreboardManager manager = Bukkit.getScoreboardManager();
    3. private Scoreboard board = manager.getNewScoreboard();
    4. private Objective objective = board.registerNewObjective("test", "dummy");
    5. private HashMap<UUID, Scoreboard> boardie = new HashMap<UUID, Scoreboard>();

    Where I used those.. :

    2. boardie.put(p.getUniqueId(), board);
    3. objective.setDisplayName(ChatColor.BOLD +"Welcome to JANK Craft!");
    4. objective.setDisplaySlot(DisplaySlot.SIDEBAR);
    5. Score score = objective.getScore(Bukkit.getOfflinePlayer(ChatColor.GREEN+ "Crystals"));
    6. String pn = p.getName();
    7. String amount = getConfig().getString(pn + ".Crystal");
    8. Score score1 = objective.getScore(Bukkit.getOfflinePlayer(ChatColor.YELLOW + amount));
    9. score1.setScore(1);
    10. score.setScore(2);
    11. p.setScoreboard(boardie.get(p.getUniqueId()));

    Am i doing anything wrong?
    george132222222 likes this.
  9. Offline


    Where are you getting the objective variable? It should be registered to the individual scoreboard you're using. If not, this is why everyone is seeing the same scores everywhere.

    Also there really isn't any need to be using a map to store the scoreboards here since you're just creating a new one each time the score updates anyways. The way it is meant to be used is that you can set up their scoreboard once (for example, when they join), and then when you want to update the score, you can just get their scoreboard from the map, get the objective from the scoreboard, and then set the score accordingly.

    The way this ties in is that you need to reset the score for the fake player tied to the old amount before adding the new one. If, for example, you set the value to "1", but then change it to "2", this will be treated as having a player named "1" and then adding another player named "2" added. To fix this, you need to get the scoreboard for the player whose value you want to update (from the map), and get the set of offline players being tracked. Then iterate over this set, and if the offline player's name doesn't contain "Crystal", reset their scores with Scoberoad.resetScores(). Now, you can go ahead and add the updated score.
Thread Status:
Not open for further replies.

Share This Page