I want to make a minigame with teams, and each player will have their name colored to indicate what team they are on. I am talking about the name that players see on top of their heads. I cannot use a Scoreboard, since each player is already assigned their own scoreboard. Edit: I am using Bukkit 1.8.8.
I can't remember which method I used but one of these methods changed the color of the nametag and a heads up I don' think it's possible to change a player's actual name but just the color. I've looked for a very long time and the closest I ever got was changing just the color, here are the methods. Code: private void setPlayerName(Player p, String nick) { EntityPlayer changeName = ((CraftPlayer)p).getHandle(); changeName.displayName = ChatColor.translateAlternateColorCodes('&', nick); for (Player all : Bukkit.getServer().getOnlinePlayers()) { PlayerConnection connection = ((CraftPlayer)all).getHandle().playerConnection; connection.sendPacket(new PacketPlayOutNamedEntitySpawn(changeName)); } } public void changeName(Player p, String newName){ for(Player pl : Bukkit.getOnlinePlayers()){ if(pl == p) continue; //REMOVES THE PLAYER ((CraftPlayer)pl).getHandle().playerConnection.sendPacket(new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.REMOVE_PLAYER, ((CraftPlayer)p).getHandle())); //CHANGES THE PLAYER'S GAME PROFILE GameProfile gp = ((CraftPlayer)p).getProfile(); try { Field nameField = GameProfile.class.getDeclaredField("name"); nameField.setAccessible(true); Field modifiersField = Field.class.getDeclaredField("modifiers"); modifiersField.setAccessible(true); modifiersField.setInt(nameField, nameField.getModifiers() & ~Modifier.FINAL); nameField.set(gp, ChatColor.translateAlternateColorCodes('&', newName)); } catch (IllegalAccessException | NoSuchFieldException ex) { throw new IllegalStateException(ex); } //ADDS THE PLAYER ((CraftPlayer)pl).getHandle().playerConnection.sendPacket(new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.ADD_PLAYER, ((CraftPlayer)p).getHandle())); ((CraftPlayer)pl).getHandle().playerConnection.sendPacket(new PacketPlayOutEntityDestroy(p.getEntityId())); ((CraftPlayer)pl).getHandle().playerConnection.sendPacket(new PacketPlayOutNamedEntitySpawn(((CraftPlayer)p).getHandle())); } }
This unfortunately did not work. I forgot to mention that I am using 1.8. I was thinking if there is a way where I can pass in a singular Team object into each player's scoreboard, so each player's scoreboard references the same Team object. Would I have to use reflection? This is because when I do getTeams from the Scoreboard object, it returns an immutable set. Edit: So, I was working on my code for a couple of hours, and I figured out, that I can create a new class that houses a new Scoreboard object, which then houses 4 teams. Then, I have a method in that class that uses Reflection to get down to NMS Scoreboard to add the teams to the sets. If anyone has a better solution, please tell me. Otherwise, this works, for now. Code: public class WallsScoreboardSharedTeams implements ScoreboardSharedTeams { Scoreboard scoreboard; HashMap<String, Team> teams; /** * Uses Reflection to add a shared bundle of teams to each player's scoreboard. */ public void addTeamsToScoreboard(Scoreboard scoreboard) { for (Team team : teams.values()) { Class teamClass = team.getClass(); Class scoreboardClass = scoreboard.getClass(); try { //Get the nms ScoreboardTeam object Field teamField = teamClass.getDeclaredField("team"); teamField.setAccessible(true); ScoreboardTeam nmsScoreboardTeam = (ScoreboardTeam) teamField.get(team); //Get the nms Scoreboard object Field boardField = scoreboardClass.getDeclaredField("board"); boardField.setAccessible(true); net.minecraft.server.v1_8_R3.Scoreboard nmsScoreboard = (net.minecraft.server.v1_8_R3.Scoreboard) boardField.get(scoreboard); Class nmsScoreBoardClass = nmsScoreboard.getClass().getSuperclass(); Field nmsScoreboardTeamsbyName = nmsScoreBoardClass.getDeclaredField("teamsByName"); nmsScoreboardTeamsbyName.setAccessible(true); HashMap<String, ScoreboardTeam> teams = (HashMap<String, ScoreboardTeam>) nmsScoreboardTeamsbyName.get(nmsScoreboard); teams.put(team.getName(), nmsScoreboardTeam); // Put the nmsScoreboardTeam into the nms Scoreboard } catch (Exception e) { e.printStackTrace(); } } }...