Solved Per Player Compass Bossbar

Discussion in 'Spigot Plugin Development' started by ytredstone, Nov 7, 2020.

  1. So, I want to have bossbar compass on my server. I almost done it, but here is a problem, it works only for last joined player. How do I create per-player bossbars? (I'm a newbie. I started to learn Java about a week ago)

    Here is the code:
    Code (Java):
    package tl.fc.main;

    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.boss.BarColor;
    import org.bukkit.boss.BarStyle;
    import org.bukkit.boss.BossBar;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.player.PlayerJoinEvent;
    import org.bukkit.event.player.PlayerMoveEvent;
    import org.bukkit.plugin.java.JavaPlugin;

    public class TLFortCompass extends JavaPlugin implements Listener {
        private BossBar compass;
        public void onEnable() {
            Bukkit.getPluginManager().registerEvents(this, this);
        }
        public String getDir(String srawyaw) {
            int n = 5;
            String ret = "ERR";
            int rawyaw = Integer.valueOf(srawyaw);
            if(rawyaw > 360-n || rawyaw < 0+n) {
                ret = " S ";
            } else if (rawyaw >= 45-n && rawyaw < 45+n) {
                ret = "S E";
            } else if (rawyaw >= 90-n && rawyaw < 90+n) {
                ret = " E ";
            } else if (rawyaw >= 135-n && rawyaw < 135+n) {
                ret = "N E";
            } else if (rawyaw >= 180-n && rawyaw < 180+n) {
                ret = " N ";
            } else if (rawyaw >= 225-n && rawyaw < 225+n) {
                ret = "N W";
            } else if (rawyaw >= 270-n && rawyaw < 270+n) {
                ret = " W ";
            } else if (rawyaw >= 315-n && rawyaw < 315+n) {
                ret = "S W";
            } else if (srawyaw.length() == 1){
                ret = " " + srawyaw + " ";
            } else if (srawyaw.length() == 2){
                //ret = " " + srawyaw;
                ret = srawyaw.charAt(0) + " " + srawyaw.charAt(1);
            } else {
                ret = srawyaw;
            }
            return ret;
        }
        public String formatYaw(Float rawyaw) {
            String num = Integer.toString((int)Math.abs(Math.round(rawyaw)));
            String l3 = getDir(Integer.toString((int)Math.round(rawyaw) - 15*3));
            String l2 = getDir(Integer.toString((int)Math.round(rawyaw) - 15*2));
            String l1 = getDir(Integer.toString((int)Math.round(rawyaw) - 15*1));
            String r3 = getDir(Integer.toString((int)Math.round(rawyaw) + 15*3));
            String r2 = getDir(Integer.toString((int)Math.round(rawyaw) + 15*2));
            String r1 = getDir(Integer.toString((int)Math.round(rawyaw) + 15*1));
            String s = ChatColor.GRAY + " ███ " + ChatColor.WHITE;
           
            return l3+s+l2+s+l1+s+ChatColor.RED + "[" + getDir(num) + "]" + ChatColor.WHITE+s+r1+s+r2+s+r3;
        }
        @EventHandler
        public void onJoin(PlayerJoinEvent e) {
            compass = Bukkit.createBossBar(formatYaw(e.getPlayer().getLocation().getYaw()), BarColor.WHITE, BarStyle.SOLID);
            compass.setVisible(true);
            for(Player player : Bukkit.getOnlinePlayers()) compass.removePlayer(player);
            compass.addPlayer(e.getPlayer());
        }
        @EventHandler
        public void onMove(PlayerMoveEvent e) {
            compass.setTitle(formatYaw(e.getPlayer().getLocation().getYaw()));
        }
    }
    P.s. It works fine for me, except that thing(
     
  2. The reason for that is, that you only ever have one instance of your compass.
    You would need to create a compass for every player that joins instead and store / update it with the players.

    A simple way of doing this is by using a (Hash)Map:
    Code (Text):
    private final HashMap<UUID, BossBar> compasses = new HashMap<UUID, BossBar>();
    Where UUID is the UUID of the Player and BossBar is the compass instance you've created for that player.

    Following is how to use the (Hash)Map for your case:
    Code (Java):
    // Adding / putting into the map
    compasses.put(player.getUniqueID(), compass);

    // Getting from the map
    compasses.get(player.getUniqueID());

    // Removing from the map
    compasses.remove(player.getUniqueID());

    // Iterating over the map (to update something for example)
    for (UUID uuid : compasses.keySet()) {
        Player player = Bukkit.getPlayer(uuid);
        if (player == null) { // Player is not online anymore
            compasses.remove(uuid);
            continue;
        }

        BossBar compass = compasses.get(uuid);

       // at this point you have a Player and the compass to your disposal
    }
    I hope this helps you. Feel free to ask for more help if you get stuck :)
     
  3. Thanks A Lot!