[Tutorial] Teams - Name color and Wool Hats asigned to Player

Discussion in 'Resources' started by ProFatal, Jun 14, 2012.

Thread Status:
Not open for further replies.
  1. Offline

    ProFatal

    So after looking across the whole of the forums for tutorials and help to create this, I found some ways but they didn't really help the person that was asking for it so I though I would make a tutorial since I was also stuck on this for a few hours.

    <font color="#3366ff"><font color="#00ff00">Test Plugin</font></font>

    Show Spoiler
    <Edit by Moderator: Redacted mediafire url>
    You can do /name NAME
    and it will change your name and skin for everyone else so for instance
    /name Notch
    will make your title above your head Notch and give you his skin

    You can also do /color COLOR
    so if you where to do /color red
    your name above head will become red and if you had changed your name it will also affect that as well.

    <font color="#ff0000">NOTE</font> if you do use /color your skin will change since if can't find the color red and your name skin.



    <font color="#3366ff">Video Tutorial</font>

    Show Spoiler



    <font color="#ff0000">ColorName.java for quick instillation. </font>

    Show Spoiler
    Right people of the bukkit forum I have compacted this code so now it is more user friendly
    <font color="#ff0000">IF you have a good idea on how to improve this then please share and if it is good I will add it to the code</font>.

    <font color="#3366ff">Download : <Edit by Moderator: Redacted mediafire url>
    <font color="#ff9900">or</font>

    Show Spoiler
    Code:
    import net.minecraft.server.EntityPlayer;
    import net.minecraft.server.Packet20NamedEntitySpawn;
     
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.craftbukkit.entity.CraftPlayer;
    import org.bukkit.entity.Player;
     
    public class ColorNames {
     
        private Player player;
     
        public ColorNames(Player player,String color){
            this.player = player;
            for(ChatColor chatc  : ChatColor.values()){
                if(replaceString(chatc).equalsIgnoreCase(color)){
                    setPlayerName(chatc.toString());
                }
            }
        }
     
        private String replaceString(ChatColor color){
            String chatcolorReplace = color.name().replaceAll("_","");
            return chatcolorReplace;
        }
     
        private void setPlayerName(String color){
            String oldName = player.getName();
     
            EntityPlayer changingName = ((CraftPlayer)player).getHandle();
            changingName.name = color+player.getName();
            for(Player playerinworld : Bukkit.getOnlinePlayers()){
                if(playerinworld != player){
                    ((CraftPlayer)playerinworld).getHandle().netServerHandler.sendPacket(new Packet20NamedEntitySpawn(changingName));
                }
            }
            changingName.name = oldName;
        }
    }
    



    After you have created a class for this all you need to do to call it is
    Code:
    new ColorNames(player, COLORYOUWANT);
    so e.g
    Code:
    new ColorNames(player, "red");


    Main File
    So first of all we are going to dive into the main class where you have onEnable()
    Code:
    public void onEnable(){
                this.getCommand("blue").setExecutor(new TeamExecutor(this));
                this.getCommand("red").setExecutor(new TeamExecutor(this));
                this.getCommand("leave").setExecutor(new TeamExecutor(this));
    }
    These are going to call onCommand() functions within out Executor file that will handle out color teams.

    TeamExecutor File
    Right now since we have our commands set in the main file now we need to create the jobs that they will be doing and so forth. <font color="#ff0000">BUT</font> first we need to import the files we need for this to work;

    Code:
    import net.minecraft.server.EntityPlayer;
    import net.minecraft.server.Packet20NamedEntitySpawn;
     
    import org.bukkit.ChatColor;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandExecutor;
    import org.bukkit.command.CommandSender;
    import org.bukkit.craftbukkit.entity.CraftPlayer;
    import org.bukkit.entity.Player;
    After we have imported them into our TeamExecutor.java file we then need to implement the command executor and to do this we just add it to the end of <font color="#3366ff">public class</font> line;
    Code:
    public class TeamExecutor implements CommandExecutor {
    and also don't forget to add this line so we can reference to the plugin later on;
    Code:
    private main plugin;
    <font color="#ff0000">*NOTE* <font color="#000000">the main is your main file where your onEnable code is.</font></font>

    Since I like to be nice and tidy in my code I like to make it so I don't need to keep righting lines out and so I have create <font color="#339966">color</font> references and it makes it more easier to get colors in my opinion;
    Code:
    //        Colour Text
        ChatColor green = ChatColor.GREEN;
        ChatColor yellow = ChatColor.YELLOW;
        ChatColor red = ChatColor.RED;
        ChatColor blue = ChatColor.BLUE;
        ChatColor white = ChatColor.WHITE;
    Now we can reference to these without the need to type ChatColor.COLOR later.

    Now we need to link the plugin value we did before and to do this we add this line of code;
    Code:
    public TeamExecutor(main plugin) {
        this.plugin = plugin;
    }
    Now our plugin variable is set the the main plugin and can be used.

    Now for the onCommand() which I think is the most important since it will be calling other functions later on.
    Code:
    public boolean onCommand(CommandSender sender, Command cmd, String commandLable, String[] arg) {
        Player player = (Player) sender;
        String redName = red+player.getName()+white;
        String blueName = blue+player.getName()+white;
        String defaultName = white+player.getName()+white;
    First we have called the boolean function and set some variables that will be used.
    Player player is converting the sender to a Player and then we just set the different Strings that the name in chat can be <font color="#ff0000">Red</font> <font color="#3366ff">Blue</font> Default

    Now after that we then check if any arguments have been passed (these are paramaters you may have seen like <font color="#3366ff">/i 73 3</font> and so on), and we also are doing a check excluding the case so it can be;
    <font color="#ff0000">red, reD, ReD ect, ect</font>
    Code:
    if(arg.length != 1){
                if(commandLable.equalsIgnoreCase("red")){
                    player.setDisplayName(redName);
                    player.setPlayerListName(red+player.getName());
                    applyTeam(player, "red");
                    player.sendMessage(yellow+"Welcome to the "+red+"RED"+yellow+" team.");
                }else
    As you can see we are setting the player's display name to redName as we defined before. This makes it so when they chat their name is now <<font color="#ff0000">Player</font>> instead of white. After that we are also setting the OnlineList to red so that their name shows up as red in the who is online board. Then we call applyTeam() which we haven't done yet and then send a message to the player saying "<font color="#ffcc00">Welcome to the <font color="#ff0000">RED</font> team.</font>".

    The rest of the onCommand() is just the same for blue and leave commands;
    Code:
    if(commandLable.equalsIgnoreCase("blue")){
                    player.setDisplayName(blueName);
                    player.setPlayerListName(blue+player.getName());
                    applyTeam(player, "blue");
                    player.sendMessage(yellow+"Welcome to the "+blue+"BLUE"+yellow+" team.");
                }else
                if(commandLable.equalsIgnoreCase("leave")){
                    player.setDisplayName(defaultName);
                    player.setPlayerListName(white+player.getName());
                    applyTeam(player, "leave");
                    player.sendMessage(green+"You have left your team.");
                }
                return true;
            }
            return true;
        }
    Now for the part of the code that will change the color of the players name above their head and all the juice stuff. :eek:
    Code:
        private void applyTeam(Player p, String team){
            String oldName = p.getName();
            EntityPlayer changingName = ((CraftPlayer) p).getHandle();
            if(team.equalsIgnoreCase("red")){
                changingName.name = red.toString()+p.getName();
            }else
    From this you can see that the function takes to parameters. The first one is the player who sent the command and the second one is what team its getting put onto.
    Next we store a String of the old players name so it can be changed back and stops the plugin from crashing when they call a command then another one. Then we get the player entity that we will be changing the name of and then call an if statement to see what team was sent to the function. We use red.toString() since the color we are apply isn't ChatColor.
    Here is the rest of the if statements for the other teams;
    Code:
    if(team.equalsIgnoreCase("blue")){
                    changingName.name = blue.toString()+p.getName();
            }else
                if(team.equalsIgnoreCase("leave")){
                    changingName.name = white.toString()+p.getName();
                }
    Now after that we need to send the new players name to the rest of the people on the server and this is when out plugin variable is going to be VERY helpful since we need to get server stuff.:)
    Code:
    for(Player pInWorld : plugin.getServer().getOnlinePlayers()){
                if(pInWorld != p){
                    ((CraftPlayer) pInWorld).getHandle().netServerHandler.sendPacket(new Packet20NamedEntitySpawn(changingName));
                }
            }
            changingName.name = oldName;
    }
    So first we have called an for statement that will get all players in the server who is online. Then we do an if statement to check is the player that has been got isn't equal to the player with the name change. Then we send a new packed (Packet20NamedEntitySpawn). At the end you see that it has
    <font color="#ff0000">changingName.name = oldName; <font color="#000000">This sets the player that has changed color name back to the normal color name but since we haven't pushed the new name to the rest of the server, it is still the color. We have done this so when it comes to p.getName() it will not mess up.</font></font>

    <font color="#000000">HashMap storage</font>
    So since we have added people to a team and we haven't stored any data so that they are on that team. To do this we are going to add a HashMap that will store out Players Name and also the Team they are on.

    Code:
    private final PlayerListener playerListener = new PlayerListener(this);
    final HashMap<String, String> playerTeams = new HashMap<String, String>();
    So the first string we are going to be use is to store PlayerName and the second one is to store the team. We have also added a PlayerListener which is a class we will create soon that will listen to see if a player joins or leaves the server.

    In our TeamExecutor we are going to add a line of code to the end of applyTeam() function;
    Code:
    plugin.playerTeams.put(changingName.name, team);
    This will put new values into out playerTeams HashMap.
    Code:
    for(Player pInWorld : plugin.getServer().getOnlinePlayers()){
                if(pInWorld != p){
                    ((CraftPlayer) pInWorld).getHandle().netServerHandler.sendPacket(new Packet20NamedEntitySpawn(changingName));
                }
            }
            changingName.name = oldName;
            plugin.playerTeams.put(changingName.name, team);
        }
    Since it comes after the changingName.name = oldName its the same as having the oldName entered.


    Now that we have it so it will put the data into out HashMap we now head back over to our main file where we have onEnable() and add this line of code to define a PluginManager and then register an event to it.
    Code:
    PluginManager pm = this.getServer().getPluginManager();
    pm.registerEvents(this.playerListener,this);
    Now just create a new class called <font color="#3366ff">PlayerListener.java</font>
    Code:
    public class PlayerListener implements Listener {
        private main plugin;
     
        public PlayerListener(main plugin){
            this.plugin = plugin;
        }
        
    So first we create our plugin variable like we did in the TeamExecutor file and also we implement listener so it will know that it will listen for stuff.

    Now lets create an onPlayerJoin method.
    Code:
    @EventHandler
        private void onPlayerJoin(PlayerJoinEvent e){
            Player player = e.getPlayer();
            plugin.playerTeams.put(player.getName(), "leave");
            if(plugin.playerTeams.get(player.getName())==null){
                plugin.log.info("An ERROR has occured in the onPlayerJoin function, report this asap.");
            }
        }
    We do @EventHandler because bukkit needs a priority for this and by doing @EventHandler it sets it to NORMAL.
    after that we use the line <font color="#339966">plugin.playerTeams.put(player.getName(), "leave"); </font><font color="#339966"><font color="#000000">to input data of the player that has just joints name and also its team which will be leave since they haven't set a team to join.</font></font>

    For onPlayerQuit its much the same but we are going to be adding a bit more if statements to do some checks to see if the players data is still in the HashMap.
    Code:
    @EventHandler
        private void onPlayerQuit(PlayerQuitEvent e){
            Player player = e.getPlayer();
            if(plugin.playerTeams.get(player.getName())!=null && plugin.playerTeams.get(player.getName())!="leave"){
                plugin.log.info(player.getName()+" was removed from the "+plugin.playerTeams.get(player.getName())+" team [Successful]");
            }else{
                plugin.log.info(player.getName()+" was removed from the internal DataBase [Successful]");
            }
            plugin.playerTeams.remove(player.getName());
            if(plugin.playerTeams.get(player.getName())!=null){
                plugin.log.info("An ERROR has occured in the onPlayerQuit function, report this asap.");
            }
        }
    So the first if statment which has the && symbols we do a check to see if the HashMap has a player in it with the player's name in and if it isn't null (empty) and also the team they are in isn't leave then we log out our team. <font color="#ff0000">"Player was removed from the red team"</font> <font color="#000000">else just log <font color="#339966">"Player was removed from the internal DataBase"</font></font><font color="#000000">.</font> After that we have .remove(player.getName()); which is going to remove the stored data from the HashMap.

    Extra Stuff
    So since we have added our players and given them a color name, we can also go further then that and maybe add some hats to define them. For this we are going to be using wool since it comes in varies colors.

    For this we are going to be editing out <font color="#339966">if statement </font><font color="#339966"><font color="#000000">in the applyTeam() function</font></font>
    Code:
    if(team.equalsIgnoreCase("red")){
                changingName.name = red.toString()+p.getName();
            }else
    So lets give our player a<font color="#ff0000"> red wool</font> block helmet to tell us that he is red team and to do this is just a simple get and then set.
    Code:
    p.getInventory().setHelmet(new ItemStack(Material.WOOL, 1, (short) 14));
    As you can see we have got players inventory and then set the helmet value to Wool:14 which is red wool. Your code should look like this.
    Code:
    if(team.equalsIgnoreCase("red")){
                changingName.name = red.toString()+p.getName();
                p.getInventory().setHelmet(new ItemStack(Material.WOOL, 1, (short) 14));
            }else
    Now you are thinking what about if they do <font color="#339966">/leave</font> ? How do I remove the wool from their head? Well its simple, just do the same method as before but instead of WOOL we set it to air.
    Code:
    p.getInventory().setHelmet(new ItemStack(0));
    Since air doesn't need any extra parameters like damage we just need to use one argument.

    <font color="#ff0000">DON'T forget to tell me if this helped you because it did for me -</font> Fatal, coding the world one line at a time.
     
    Last edited by a moderator: Nov 10, 2016
  2. Good tutorial :)
     
  3. Offline

    RobotA69

    Didn't read it all, but great tutorial! [diamond]
     
  4. Offline

    ProFatal

    Thanks

    I made it with so that even the not so bright people that want to get started can understand it.
     
  5. Offline

    anonym110

    Thank you for this great tutorial. I wanted to add the colored Nameplates to my Snowball plugin so I added some of the code to my plugin and it gave me a bunch of errors.
    So then I isolated the namecolor and now its being called through a command, though the error still exists as soon as the command is called.
    Code:
            String oldName = player.getName();
            ChatColor blue = ChatColor.BLUE;
            EntityPlayer changingName = ((CraftPlayer) player).getHandle();
            changingName.name = blue.toString()+player.getName();
           
            for(Player pInWorld : plugin.getServer().getOnlinePlayers()){
                if(pInWorld != player){
                    ((CraftPlayer) pInWorld).getHandle().netServerHandler.sendPacket(new Packet20NamedEntitySpawn(changingName));
                }
            }
            changingName.name = oldName;
    This is the code I added and I get this error (click me)
     
  6. Offline

    ProFatal

    What libraries are you using?
    Bukkit API or Craftbukkit (server file)
    also what is line (Battlefield.java:56)

    EDIT UPDATE READ
    So I redid my code so it was the same as you code and when I ran it and did the command it applied the name change so it is probably the way you have implemented it.
    Make sure if this is a seperate function and is called when a command is entered then make sure you pass the player and not the sender.
    Player player = (Player) sender;
     
  7. Offline

    anonym110

    Thank you, I got it to work now. I dont know what I did, I just was trying around some things and now it works. I think the error might have been cause because I was calling the main plugin the wrong way. I fixed that and some other stuff and now it works. :)

    EDIT - Stopped working again, no error, but the namecolor doesnt change anymore. I will have to check what changed. I was calling it the wrong way. Sorry
     
  8. Offline

    JxAxVxAx

    ProFatal Edit Your Post At This Part

    Now Just Create A New Class Called PlayerListener.jar

    It Isnt A Jar File But A Class File ------------^^
     
  9. Offline

    anonym110

    Ok I guess I need a little more help, I cant get it to work this way.

    -snip-

    It just doesnt show the name colored, but if I add the color name to a command like /join, etc it works without problems. So maybe its the (Player player : players)?
     
  10. Offline

    ProFatal

    Thanks for pointing that out.

    Ok so since you think its players, is the value for players
    plugin.getServer().getOnlinePlayers()

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 26, 2016
  11. Offline

    anonym110

    I understand all that and my ColorName Function looks like this
    Code:
        public void ColorName(Player p,String value) {
            String oldName = p.getName();
            EntityPlayer changingName = ((CraftPlayer) p).getHandle();
            if (value.equalsIgnoreCase("red"))
                changingName.name = ChatColor.RED.toString()+p.getName();
            else if (value.equalsIgnoreCase("blue"))
                changingName.name = ChatColor.BLUE.toString()+p.getName();
            else
                changingName.name = oldName;       
            for(Player pInWorld : Bukkit.getServer().getOnlinePlayers()){
                if(pInWorld != p){
                    ((CraftPlayer) pInWorld).getHandle().netServerHandler.sendPacket(new Packet20NamedEntitySpawn(changingName));
                }
            }
            changingName.name = oldName;
        }
    so I think that part is right. But I dont know why it isnt working.
     
  12. Offline

    ProFatal

    Are you trying to get it so when players join they get put in a team or something?
     
  13. Offline

    anonym110

    Thank you for your help, I found a way to fix my problem
     
  14. Offline

    ProFatal

    I would recommend using HashMaps instead of ArrayLists but anyway may I ask what you did to fix the problem?
     
  15. Offline

    anonym110

    nvm problem still exists. lol it worked one game and after that it didnt anymore...
     
  16. Offline

    ProFatal

    You say it worked for one game? I am guessing this is because you may have not included a
    Code:
    getServer().getScheduler().scheduleAsyncRepeatingTask(this, new Runnable() {
        @Override
            public void run() {
              //STUFF
            }
          }, 0L, 20L); //20L = 1sec
    This is a repeater so it keeps looping, if this is what you need i would suggest go reading up on them since what it looks like you are doing is like what im doing (team based game plugin) and you might need them a lot.
     
  17. Offline

    anonym110

    Thats not the problem as the game repeats once the first one is over and it calls the name function everytime it runs and ends... It doesnt even run the first time now anymore (without me changing anything) This is really frustrating me. lol
     
  18. Offline

    ProFatal

    Since I dont think I can help you since this is your own code you have do, I would suggest doing mayber
    Code:
    System.out.println(STRING);
    Throughout your code. This will print the string to your console and it may help you find where there problem is because it will not have printed that String.
     
  19. Offline

    anonym110

    Well thanks for your help anyway. I will just have to try around and find the problem that way I guess :)
     
  20. Offline

    ProFatal

    Thats what I do when im stuck and it helps people I think learn from their mistakes.
     
  21. Offline

    anonym110

    Well I normally do the same, just thought I could get a easy way out this time :O but I guess not

    Ok so after some testing I found out that the problem occurs because of teleportation. If I disable the teleport the namecolor changes, it I enable the teleport it doesnt...
    -----------------------
    So I the problem seems to be, that the client reloads the the players entity on teleport so the colored name dissappears as soon as I teleport. But I cant change the name right after the teleport either, because there seems to be a loading period (also all armor dissappears when I change the name. Does that happen normally?)

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 26, 2016
  22. Offline

    ProFatal

    The way I have it set up on my Paintball plugin im working on is that after a peried of time a new game is started;
    1. Then it called initGame() - this initialises the teams and stores them in a HashMap
    2. Then call a function called teleportTeams() -this teleports the teams to their starting area
    3. I then do applyTeam()
    I think this happens because the teleport is updating the entity with the rest of the server so the name gets reverted back.
     
  23. Offline

    anonym110

    Well my problem is even if I set the Update right afterwards it wont work, I have to wait ~3sec before changing the color. If I do it less I get teleported I can even see the other player at the new location with a colored name, but then a moment later it changes back to white with the original skin...
     
  24. Offline

    ProFatal

    I see that you are calling it after the teleport, are you doing this
    Code:
    void teleport(){
      //TELEPORT STUFF
      applyTeam();
    }
    Because thats the way I have it setup and it seems to work instead of
    Code:
    teleport();
    applyteam();
     
  25. Offline

    anonym110

    Well I have it like this
    Code:
    player.teleport(redTeamSpawn);     
    ColorName(player, "red");
     
  26. Offline

    OppositeGamer

    You know what would be nice? If you added the source code because I program plugins and THIS SHIT DOESNT WORK!
     
  27. Offline

    notrodash

    I have a problem where the colored name ALWAYS has a space after it. I tried to do a replace and even a substring but it always leaves a space. Do you know why?
     
  28. Offline

    ProFatal

    I think that happens with mine as well.
    What part doesn't work? If its the change name part then you may need to include Bukkit API and Craftbukkit server to your libs.
     
  29. Offline

    p000ison

    hm this will change the skin doesnt it?
     
  30. Offline

    ProFatal

    Yes
     
Thread Status:
Not open for further replies.

Share This Page